❄️ 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
Unbearably fast O(1) runtime type-checking in pure Python.

Look for the bare necessities, the simple bare necessities. Forget about your worries and your strife. — The Jungle Book.

beartype 1.4k Jan 01, 2023
Enforce the same configuration across multiple projects

Nitpick Flake8 plugin to enforce the same tool configuration (flake8, isort, mypy, Pylint...) across multiple Python projects. Useful if you maintain

Augusto W. Andreoli 315 Dec 25, 2022
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
Optional static typing for Python 3 and 2 (PEP 484)

Mypy: Optional Static Typing for Python Got a question? Join us on Gitter! We don't have a mailing list; but we are always happy to answer questions o

Python 14.4k Jan 08, 2023
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
Flake8 extension to provide force-check option

flake8-force Flake8 extension to provide force-check option. When this option is enabled, flake8 performs all checks even if the target file cannot be

Kenichi Maehashi 9 Oct 29, 2022
Tool to check the completeness of MANIFEST.in for Python packages

check-manifest Are you a Python developer? Have you uploaded packages to the Python Package Index? Have you accidentally uploaded broken packages with

Marius Gedminas 270 Dec 26, 2022
Rust like Option and Result types in Python

Option Rust-like Option and Result types in Python, slotted and fully typed. An Option type represents an optional value, every Option is either Some

45 Dec 13, 2022
Custom Python linting through AST expressions

bellybutton bellybutton is a customizable, easy-to-configure linting engine for Python. What is this good for? Tools like pylint and flake8 provide, o

H. Chase Stevens 249 Dec 31, 2022
❄️ A flake8 plugin to help you write better list/set/dict comprehensions.

flake8-comprehensions A flake8 plugin that helps you write better list/set/dict comprehensions. Requirements Python 3.6 to 3.9 supported. Installation

Adam Johnson 398 Dec 23, 2022
An enhanced version of the Python typing library.

typingplus An enhanced version of the Python typing library that always uses the latest version of typing available, regardless of which version of Py

Contains 6 Mar 26, 2021
Tool for pinpointing circular imports in Python. Find cyclic imports in any project

Pycycle: Find and fix circular imports in python projects Pycycle is an experimental project that aims to help python developers fix their circular de

Vadim Kravcenko 311 Dec 15, 2022
mypy plugin for loguru

loguru-mypy A fancy plugin to boost up your logging with loguru mypy compatibility logoru-mypy should be compatible with mypy=0.770. Currently there

Tomasz Trębski 13 Nov 02, 2022
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
A simple program which checks Python source files for errors

Pyflakes A simple program which checks Python source files for errors. Pyflakes analyzes programs and detects various errors. It works by parsing the

Python Code Quality Authority 1.2k Dec 30, 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
🦆 Better duck-typing with mypy-compatible extensions to Protocol

🦆 Quacks If it walks like a duck and it quacks like a duck, then it must be a duck Thanks to PEP544, Python now has protocols: a way to define duck t

Arie Bovenberg 9 Nov 14, 2022
Flake8 Type Annotation Checking

flake8-annotations flake8-annotations is a plugin for Flake8 that detects the absence of PEP 3107-style function annotations and PEP 484-style type co

S. Co1 118 Jan 05, 2023
Collection of awesome Python types, stubs, plugins, and tools to work with them.

Awesome Python Typing Collection of awesome Python types, stubs, plugins, and tools to work with them. Contents Static type checkers Dynamic type chec

TypedDjango 1.2k Jan 04, 2023
Python classes with types validation at runtime.

typedclasses Python classes with types validation at runtime. (Experimental & Under Development) Installation You can install this library using Pytho

Izhar Ahmad 8 Feb 06, 2022