❄️ A flake8 plugin to help you write better list/set/dict comprehensions.

Overview

flake8-comprehensions

https://img.shields.io/github/workflow/status/adamchainz/flake8-comprehensions/CI/main?style=for-the-badge https://img.shields.io/pypi/v/flake8-comprehensions.svg?style=for-the-badge https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge pre-commit

A flake8 plugin that helps you write better list/set/dict comprehensions.

Requirements

Python 3.6 to 3.9 supported.

Installation

First, install with pip:

python -m pip install flake8-comprehensions

Second, check that flake8 lists the plugin in its version line:

$ flake8 --version
3.7.8 (flake8-comprehensions: 3.0.0, mccabe: 0.6.1, pycodestyle: 2.5.0, pyflakes: 2.1.1) CPython 3.8.0 on Linux

Third, add the C4 prefix to your select list. For example, if you have your configuration in setup.cfg:

[flake8]
select = E,F,W,C4

Linting a Django project? Check out my book Speed Up Your Django Tests which covers loads of best practices so you can write faster, more accurate tests.


Rules

C400-402: Unnecessary generator - rewrite as a <list/set/dict> comprehension.

It's unnecessary to use list, set, or dict around a generator expression, since there are equivalent comprehensions for these types. For example:

  • Rewrite list(f(x) for x in foo) as [f(x) for x in foo]
  • Rewrite set(f(x) for x in foo) as {f(x) for x in foo}
  • Rewrite dict((x, f(x)) for x in foo) as {x: f(x) for x in foo}

C403-404: Unnecessary list comprehension - rewrite as a <set/dict> comprehension.

It's unnecessary to use a list comprehension inside a call to set or dict, since there are equivalent comprehensions for these types. For example:

  • Rewrite set([f(x) for x in foo]) as {f(x) for x in foo}
  • Rewrite dict([(x, f(x)) for x in foo]) as {x: f(x) for x in foo}

C405-406: Unnecessary <list/tuple> literal - rewrite as a <set/dict> literal.

It's unnecessary to use a list or tuple literal within a call to set or dict. For example:

  • Rewrite set([1, 2]) as {1, 2}
  • Rewrite set((1, 2)) as {1, 2}
  • Rewrite set([]) as set()
  • Rewrite dict([(1, 2)]) as {1: 2}
  • Rewrite dict(((1, 2),)) as {1: 2}
  • Rewrite dict([]) as {}

C407: Unnecessary <dict/list> comprehension - <builtin> can take a generator

It's unnecessary to pass a list comprehension to some builtins that can take generators instead. For example:

  • Rewrite sum([x ** 2 for x in range(10)]) as sum(x ** 2 for x in range(10))
  • Rewrite all([foo.bar for foo in foos]) as all(foo.bar for foo in foos)
  • Rewrite filter(lambda x: x % 2 == 0, [x ** 3 for x in range(10)]) as filter(lambda x: x % 2 == 0, (x ** 3 for x in range(10)))

The list of builtins that are checked for are:

  • all
  • any
  • enumerate
  • filter
  • frozenset
  • map
  • max
  • min
  • sorted
  • sum
  • tuple

C408: Unnecessary <dict/list/tuple> call - rewrite as a literal.

It's slower to call e.g. dict() than using the empty literal, because the name dict must be looked up in the global scope in case it has been rebound. Same for the other two basic types here. For example:

  • Rewrite dict() as {}
  • Rewrite dict(a=1, b=2) as {"a": 1, "b": 2}
  • Rewrite list() as []
  • Rewrite tuple() as ()

C409-410: Unnecessary <list/tuple> passed to <list/tuple>() - (remove the outer call to <list/tuple>``()/rewrite as a ``<list/tuple> literal).

It's unnecessary to use a list or tuple literal within a call to list or tuple, since there is literal syntax for these types. For example:

  • Rewrite tuple([1, 2]) as (1, 2)
  • Rewrite tuple((1, 2)) as (1, 2)
  • Rewrite tuple([]) as ()
  • Rewrite list([1, 2]) as [1, 2]
  • Rewrite list((1, 2)) as [1, 2]
  • Rewrite list([]) as []

C411: Unnecessary list call - remove the outer call to list().

It's unnecessary to use a list around a list comprehension, since it is equivalent without it. For example:

  • Rewrite list([f(x) for x in foo]) as [f(x) for x in foo]

C412: Unnecessary <dict/list/set> comprehension - 'in' can take a generator.

It's unnecessary to pass a dict/list/set comprehension to 'in', as it can take a generator instead. For example:

  • Rewrite y in [f(x) for x in foo] as y in (f(x) for x in foo)
  • Rewrite y in {x ** 2 for x in foo} as y in (x ** 2 for x in foo)

C413: Unnecessary <list/reversed> call around sorted().

It's unnecessary to use list() around sorted() as it already returns a list. It is also unnecessary to use reversed() around sorted() as the latter has a reverse argument. For example:

  • Rewrite list(sorted([2, 3, 1])) as sorted([2, 3, 1])
  • Rewrite reversed(sorted([2, 3, 1])) as sorted([2, 3, 1], reverse=True)
  • Rewrite reversed(sorted([2, 3, 1], reverse=True)) as sorted([2, 3, 1])

C414: Unnecessary <list/reversed/set/sorted/tuple> call within <list/set/sorted/tuple>().

It's unnecessary to double-cast or double-process iterables by wrapping the listed functions within list/set/sorted/tuple. For example:

  • Rewrite list(list(iterable)) as list(iterable)
  • Rewrite list(tuple(iterable)) as list(iterable)
  • Rewrite tuple(list(iterable)) as tuple(iterable)
  • Rewrite tuple(tuple(iterable)) as tuple(iterable)
  • Rewrite set(set(iterable)) as set(iterable)
  • Rewrite set(list(iterable)) as set(iterable)
  • Rewrite set(tuple(iterable)) as set(iterable)
  • Rewrite set(sorted(iterable)) as set(iterable)
  • Rewrite set(reversed(iterable)) as set(iterable)
  • Rewrite sorted(list(iterable)) as sorted(iterable)
  • Rewrite sorted(tuple(iterable)) as sorted(iterable)
  • Rewrite sorted(sorted(iterable)) as sorted(iterable)
  • Rewrite sorted(reversed(iterable)) as sorted(iterable)

C415: Unnecessary subscript reversal of iterable within <reversed/set/sorted>().

It's unnecessary to reverse the order of an iterable when passing it into one of the listed functions will change the order again. For example:

  • Rewrite set(iterable[::-1]) as set(iterable)
  • Rewrite sorted(iterable[::-1]) as sorted(iterable, reverse=True)
  • Rewrite reversed(iterable[::-1]) as iterable

C416: Unnecessary <list/set> comprehension - rewrite using <list/set>().

It's unnecessary to use a list comprehension if the elements are unchanged. The iterable should be wrapped in list() or set() instead. For example:

  • Rewrite [x for x in iterable] as list(iterable)
  • Rewrite {x for x in iterable} as set(iterable)
Owner
Adam Johnson
🦄 @django technical board member 🇬🇧 @djangolondon co-organizer ✍ AWS/Django/Python Author and Consultant
Adam Johnson
A plugin for Flake8 that checks pandas code

pandas-vet pandas-vet is a plugin for flake8 that provides opinionated linting for pandas code. It began as a project during the PyCascades 2019 sprin

Jacob Deppen 146 Dec 28, 2022
Flake8 extension for enforcing trailing commas in python

Flake8 Extension to enforce better comma placement. Usage If you are using flake8 it's as easy as: pip install flake8-commas Now you can avoid those a

Python Code Quality Authority 127 Sep 03, 2022
Pylint plugin for improving code analysis for when using Django

pylint-django About pylint-django is a Pylint plugin for improving code analysis when analysing code using Django. It is also used by the Prospector t

Python Code Quality Authority 544 Jan 06, 2023
A plugin for Flake8 that provides specializations for type hinting stub files

flake8-pyi A plugin for Flake8 that provides specializations for type hinting stub files, especially interesting for linting typeshed. Functionality A

Łukasz Langa 58 Jan 04, 2023
Design by contract for Python. Write bug-free code. Add a few decorators, get static analysis and tests for free.

A Python library for design by contract (DbC) and checking values, exceptions, and side-effects. In a nutshell, deal empowers you to write bug-free co

Life4 473 Dec 28, 2022
flake8 plugin to catch useless `assert` statements

flake8-useless-assert flake8 plugin to catch useless assert statements Download or install on the PyPI page Violations Code Description Example ULA001

1 Feb 12, 2022
Static Typing for Python

Python static typing home. Contains the source for typing_extensions and the documentation. Also hosts a user help forum.

Python 1.3k Jan 06, 2023
A python documentation linter which checks that the docstring description matches the definition.

Darglint A functional docstring linter which checks whether a docstring's description matches the actual function/method implementation. Darglint expe

Terrence Reilly 463 Dec 31, 2022
A Python Parser

parso - A Python Parser Parso is a Python parser that supports error recovery and round-trip parsing for different Python versions (in multiple Python

Dave Halter 520 Dec 26, 2022
Type annotations builder for boto3 compatible with VSCode, PyCharm, Emacs, Sublime Text, pyright and mypy.

mypy_boto3_builder Type annotations builder for boto3-stubs project. Compatible with VSCode, PyCharm, Emacs, Sublime Text, mypy, pyright and other too

Vlad Emelianov 2 Dec 05, 2022
Reference implementation of sentinels for the Python stdlib

Sentinels This is a reference implementation of a utility for the definition of sentinel values in Python. This also includes a draft PEP for the incl

Tal Einat 22 Aug 27, 2022
Static type checker for Python

Static type checker for Python Speed Pyright is a fast type checker meant for large Python source bases. It can run in a “watch” mode and performs fas

Microsoft 9.2k Jan 03, 2023
Mypy plugin and stubs for SQLAlchemy

Pythonista Stubs Stubs for the Pythonista iOS API. This allows for better error detection and IDE / editor autocomplete. Installation and Usage pip in

Dropbox 521 Dec 29, 2022
flake8 plugin to run black for checking Python coding style

flake8-black Introduction This is an MIT licensed flake8 plugin for validating Python code style with the command line code formatting tool black. It

Peter Cock 146 Dec 15, 2022
Flake8 extension for checking quotes in python

Flake8 Extension to lint for quotes. Major update in 2.0.0 We automatically encourage avoiding escaping quotes as per PEP 8. To disable this, use --no

Zachary Heller 157 Dec 13, 2022
Stubs with type annotations for ordered-set Python library

ordered-set-stubs - stubs with type annotations for ordered-set Python library Archived - now type annotations are the part of the ordered-set library

Roman Inflianskas 2 Feb 06, 2020
Silence mypy by adding or removing code comments

mypy-silent Automatically add or remove # type: ignore commends to silence mypy. Inspired by pylint-silent Why? Imagine you want to add type check for

Wu Haotian 8 Nov 30, 2022
Mypy stubs for the PyQt5 framework

Mypy stubs for the PyQt5 framework This repository holds the stubs of the PyQt5 framework. It uses the stub files that are produced during compilation

62 Nov 22, 2022
Flake8 plugin for managing type-checking imports & forward references

flake8-type-checking Lets you know which imports to put in type-checking blocks. For the imports you've already defined inside type-checking blocks, i

snok 67 Dec 16, 2022
Tools for improving Python imports

imptools Tools for improving Python imports. Installation pip3 install imptools Overview Detailed docs import_path Import a module from any path on th

Danijar Hafner 7 Aug 07, 2022