New Upstream Release - flake8-comprehensions
Ready changes
Summary
Merged new upstream version: 3.12.0 (was: 3.10.1).
Resulting package
Built on 2023-06-06T04:15 (took 6m52s)
The resulting binary packages can be installed (if you have the apt repository enabled) by running one of:
apt install -t fresh-releases python3-flake8-comprehensions
Lintian Result
Diff
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index 4afa269..046ab3a 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -36,7 +36,7 @@ jobs:
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
- python -m pip install --upgrade tox tox-py
+ python -m pip install --upgrade 'tox>=4.0.0rc3'
- name: Run tox targets for ${{ matrix.python-version }}
- run: tox --py current
+ run: tox run -f py$(echo ${{ matrix.python-version }} | tr -d .)
diff --git a/.gitignore b/.gitignore
index 36994f8..93acb63 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,60 +1,7 @@
-# Byte-compiled / optimized / DLL files
-__pycache__/
-*.py[cod]
-*$py.class
-
-# C extensions
-*.so
-
-# Distribution / packaging
-.Python
-env/
-build/
-develop-eggs/
-dist/
-downloads/
-eggs/
-.eggs/
-lib/
-lib64/
-parts/
-sdist/
-var/
*.egg-info/
-.installed.cfg
-*.egg
-
-# PyInstaller
-# Usually these files are written by a python script from a template
-# before PyInstaller builds the exe, so as to inject date/other infos into it.
-*.manifest
-*.spec
-
-# Installer logs
-pip-log.txt
-pip-delete-this-directory.txt
-
-# Unit test / coverage reports
-htmlcov/
-.tox/
-.coverage
-.coverage.*
-.cache
-nosetests.xml
-coverage.xml
-*,cover
-.hypothesis/
-.pytest_cache
-
-# Translations
-*.mo
-*.pot
-
-# Django stuff:
-*.log
-
-# Sphinx documentation
-docs/_build/
-
-# PyBuilder
-target/
+*.pyc
+/.coverage
+/.coverage.*
+/.tox
+/build/
+/dist/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index fbf0fc3..51a9121 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,9 +1,9 @@
default_language_version:
- python: python3.10
+ python: python3.11
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.3.0
+ rev: v4.4.0
hooks:
- id: check-added-large-files
- id: check-case-conflict
@@ -13,27 +13,53 @@ repos:
- id: check-toml
- id: end-of-file-fixer
- id: trailing-whitespace
+- repo: https://github.com/tox-dev/pyproject-fmt
+ rev: 0.9.2
+ hooks:
+ - id: pyproject-fmt
+- repo: https://github.com/asottile/setup-cfg-fmt
+ rev: v2.2.0
+ hooks:
+ - id: setup-cfg-fmt
+ args:
+ - --include-version-classifiers
+- repo: https://github.com/tox-dev/tox-ini-fmt
+ rev: 1.3.0
+ hooks:
+ - id: tox-ini-fmt
+- repo: https://github.com/rstcheck/rstcheck
+ rev: v6.1.2
+ hooks:
+ - id: rstcheck
+ additional_dependencies:
+ - tomli==2.0.1
- repo: https://github.com/asottile/pyupgrade
- rev: v3.1.0
+ rev: v3.3.1
hooks:
- id: pyupgrade
args: [--py37-plus]
- repo: https://github.com/psf/black
- rev: 22.10.0
+ rev: 23.3.0
hooks:
- id: black
-- repo: https://github.com/asottile/blacken-docs
- rev: v1.12.1
+- repo: https://github.com/adamchainz/blacken-docs
+ rev: 1.13.0
hooks:
- id: blacken-docs
additional_dependencies:
- - black==22.1.0
-- repo: https://github.com/pycqa/isort
- rev: 5.10.1
+ - black==23.1.0
+- repo: https://github.com/asottile/reorder_python_imports
+ rev: v3.9.0
hooks:
- - id: isort
+ - id: reorder-python-imports
+ args:
+ - --py37-plus
+ - --application-directories
+ - .:example:src
+ - --add-import
+ - 'from __future__ import annotations'
- repo: https://github.com/PyCQA/flake8
- rev: 5.0.4
+ rev: 6.0.0
hooks:
- id: flake8
additional_dependencies:
@@ -42,6 +68,6 @@ repos:
- flake8-tidy-imports
- flake8-typing-imports
- repo: https://github.com/pre-commit/mirrors-mypy
- rev: v0.982
+ rev: v1.2.0
hooks:
- id: mypy
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
new file mode 100644
index 0000000..52f0a20
--- /dev/null
+++ b/CHANGELOG.rst
@@ -0,0 +1,268 @@
+=========
+Changelog
+=========
+
+3.12.0 (2023-04-13)
+-------------------
+
+* Add rule C418 to check for calls passing a dict literal or dict comprehension to ``dict()``.
+
+* Add rule C419 to check for calls passing a list comprehension to ``any()``/``all()``.
+
+3.11.1 (2023-03-21)
+-------------------
+
+* Fix false positives in C406 “unnecessary dict literal”.
+
+ Fixes `Issue #260 <https://github.com/adamchainz/flake8-comprehensions/issues/260>`__.
+
+3.11.0 (2023-03-18)
+-------------------
+
+* Expand C416 to ``dict`` comprehensions.
+
+ Thanks to Aaron Gokaslan in `PR #490 <https://github.com/adamchainz/flake8-comprehensions/pull/490>`__.
+
+3.10.1 (2022-10-29)
+-------------------
+
+* Fix false positive in rules C402 and C404 for ``dict()`` calls with keyword arguments.
+
+ Thanks to Anders Kaseorg for the report in `Issue #457 <https://github.com/adamchainz/flake8-comprehensions/issues/457>`__.
+
+3.10.0 (2022-05-19)
+-------------------
+
+* Add rule C417 which recommends rewriting use of ``map()`` with ``lambda`` to an equivalent generator expression or comprehension.
+
+ Thanks to Tushar Sadhwani in `PR #409 <https://github.com/adamchainz/flake8-comprehensions/pull/409>`__.
+
+3.9.0 (2022-05-11)
+------------------
+
+* Support Python 3.11.
+
+3.8.0 (2022-01-10)
+------------------
+
+* Drop Python 3.6 support.
+
+* Remove upper bound on Flake8 version.
+
+3.7.0 (2021-10-11)
+------------------
+
+* Support Flake8 4.
+
+3.6.1 (2021-08-16)
+------------------
+
+* Fix type hint for ``tree`` argument.
+
+ Thanks to kasium for the report in `Issue #352
+ <https://github.com/adamchainz/flake8-comprehensions/issues/352>`__.
+
+3.6.0 (2021-08-13)
+------------------
+
+* Add type hints.
+
+3.5.0 (2021-05-10)
+------------------
+
+* Support Python 3.10.
+
+* Stop distributing tests to reduce package size. Tests are not intended to be
+ run outside of the tox setup in the repository. Repackagers can use GitHub's
+ tarballs per tag.
+
+3.4.0 (2021-03-18)
+------------------
+
+* Remove rules C407 (Unnecessary ``<dict/list>`` comprehension - ``<builtin>``
+ can take a generator) and C412 (Unnecessary ``<dict/list/set>`` comprehension
+ - 'in' can take a generator). Both rules recommended increasing laziness,
+ which is not always desirable and can lead to subtle bugs. Also, a fully
+ exhausted generator is slower than an equivalent comprehension, so the advice
+ did not always improve performance.
+
+ Thanks to David Smith, Dylan Young, and Leonidas Loucas for the report in
+ `Issue #247
+ <https://github.com/adamchainz/flake8-comprehensions/issues/247>`__.
+
+3.3.1 (2020-12-19)
+------------------
+
+* Drop Python 3.5 support.
+* Improved installation instructions in README.
+
+3.3.0 (2020-10-23)
+------------------
+
+* Support Python 3.9.
+* Move license from ISC to MIT License.
+* Partially reverted the change to ``C408`` to make it apply again to when
+ ``dict`` is called with keyword arguments, e.g. ``dict(a=1, b=2)`` will be
+ flagged to be rewritten in the literal form ``{"a": 1, "b": 2}``
+
+3.2.3 (2020-06-06)
+------------------
+
+* Made ``C408`` only apply when no arguments are passed to
+ ``dict``/``list``/``tuple``.
+
+3.2.2 (2020-01-20)
+------------------
+
+* Remove check for dict comprehensions in rule C407 as it would also change the
+ results for certain builtins such as ``sum()``.
+
+3.2.1 (2020-01-20)
+------------------
+
+* Remove check for set comprehensions in rule C407 as it would change the
+ results for certain builtins such as ``sum()``.
+
+3.2.0 (2020-01-20)
+------------------
+
+* Add ``filter`` and ``map`` to rule C407.
+* Check for dict and set comprehensions in rules C407 and C412.
+
+3.1.4 (2019-11-20)
+------------------
+
+* Remove the tuple/unpacking check from C416 to prevent false positives where
+ the type of the iterable is changed from some iterable to a tuple.
+
+3.1.3 (2019-11-19)
+------------------
+
+* Ensure the fix for false positives in ``C416`` rule for asynchronous
+ comprehensions runs on Python 3.6 too.
+
+3.1.2 (2019-11-18)
+------------------
+
+* Fix false positives in ``C416`` rule for list comprehensions returning
+ tuples.
+
+3.1.1 (2019-11-16)
+------------------
+
+* Fix false positives in ``C416`` rule for asynchronous comprehensions.
+
+3.1.0 (2019-11-15)
+------------------
+
+* Update Python support to 3.5-3.8.
+* Fix false positives for C404 for list comprehensions not directly creating
+ tuples.
+* Add ``C413`` rule that checks for unnecessary use of ``list()`` or
+ ``reversed()`` around ``sorted()``.
+* Add ``C414`` rule that checks for unnecessary use of the following:
+ * ``list()``, ``reversed()``, ``sorted()``, or ``tuple()`` within ``set``
+ or ``sorted()``
+ * ``list()`` or ``tuple()`` within ``list()`` or ``tuple()``
+ * ``set()`` within ``set``
+* Add ``C415`` rule that checks for unnecessary reversal of an iterable via
+ subscript within ``reversed()``, ``set()``, or ``sorted()``.
+* Add ``C416`` rule that checks for unnecessary list or set comprehensions that
+ can be rewritten using ``list()`` or ``set()``.
+
+3.0.1 (2019-10-28)
+------------------
+
+* Fix version display on ``flake8 --version`` (removing dependency on
+ ``cached-property``). Thanks to Jon Dufresne.
+
+3.0.0 (2019-10-25)
+------------------
+
+* Update Flake8 support to 3.0+ only. 3.0.0 was released in 2016 and the plugin
+ hasn't been tested with it since.
+
+2.3.0 (2019-10-25)
+------------------
+
+* Converted setuptools metadata to configuration file. This meant removing the
+ ``__version__`` attribute from the package. If you want to inspect the
+ installed version, use
+ ``importlib.metadata.version("flake8-comprehensions")``
+ (`docs <https://docs.python.org/3.8/library/importlib.metadata.html#distribution-versions>`__ /
+ `backport <https://pypi.org/project/importlib-metadata/>`__).
+* Add dependencies on ``cached-property`` and ``importlib-metadata``.
+* Fix false negatives in ``C407`` for cases when ``enumerate`` and ``sum()``
+ are passed more than one argument.
+
+2.2.0 (2019-08-12)
+------------------
+
+* Update Python support to 3.5-3.7, as 3.4 has reached its end of life.
+* ``C412`` rule that complains about using list comprehension with ``in``.
+
+2.1.0 (2019-03-01)
+------------------
+
+* Add missing builtin ``enumerate`` to ``C407``.
+
+2.0.0 (2019-02-02)
+------------------
+
+* Drop Python 2 support, only Python 3.4+ is supported now.
+
+1.4.1 (2017-05-17)
+------------------
+
+* Fix false positives in ``C408`` for calls using ``*args`` or ``**kwargs``.
+
+1.4.0 (2017-05-14)
+------------------
+
+* Plugin now reserves the full ``C4XX`` code space rather than just ``C40X``
+* ``C408`` rule that complains about using ``tuple()``, ``list()``, or
+ ``dict()`` instead of a literal.
+* ``C409`` and ``C410`` rules that complain about an unnecessary list or tuple
+ that could be rewritten as a literal.
+* ``C411`` rule that complains about using list comprehension inside a
+ ``list()`` call.
+
+1.3.0 (2017-05-01)
+------------------
+
+* Don't allow installation with Flake8 3.2.0 which doesn't enable the plugin.
+ This bug was fixed in Flake8 3.2.1.
+* Prevent false positives of ``C402`` from generators of expressions that
+ aren't two-tuples.
+* ``C405`` and ``C406`` now also complain about unnecessary tuple literals.
+
+1.2.1 (2016-06-27)
+------------------
+
+* ``C407`` rule that complains about unnecessary list comprehensions inside
+ builtins that can work on generators.
+
+1.2.0 (2016-07-11)
+------------------
+
+* Split all rule codes by type. This allows granular selection of the rules in
+ flake8 configuration.
+
+1.1.1 (2016-04-06)
+------------------
+
+* Fix crash on method calls
+
+1.1.0 (2016-04-06)
+------------------
+
+* ``C401`` rule that complains about unnecessary list comprehensions inside
+ calls to ``set()`` or ``dict()``.
+* ``C402`` rule that complains about unnecessary list literals inside calls to
+ ``set()`` or ``dict()``.
+
+1.0.0 (2016-04-05)
+------------------
+
+* ``C400`` rule that complains about an unnecessary usage of a generator when a
+ list/set/dict comprehension would do.
diff --git a/HISTORY.rst b/HISTORY.rst
index 509740b..27beaea 100644
--- a/HISTORY.rst
+++ b/HISTORY.rst
@@ -1,247 +1 @@
-=======
-History
-=======
-
-3.10.1 (2022-10-29)
--------------------
-
-* Fix false positive in rules C402 and C404 for ``dict()`` calls with keyword arguments.
-
- Thanks to Anders Kaseorg for the report in `Issue #457 <https://github.com/adamchainz/flake8-comprehensions/issues/457>`__.
-
-3.10.0 (2022-05-19)
--------------------
-
-* Add rule C417 which recommends rewriting use of ``map()`` with ``lambda`` to an equivalent generator expression or comprehension.
-
- Thanks to Tushar Sadhwani in `PR #409 <https://github.com/adamchainz/flake8-comprehensions/pull/409>`__.
-
-3.9.0 (2022-05-11)
-------------------
-
-* Support Python 3.11.
-
-3.8.0 (2022-01-10)
-------------------
-
-* Drop Python 3.6 support.
-
-* Remove upper bound on Flake8 version.
-
-3.7.0 (2021-10-11)
-------------------
-
-* Support Flake8 4.
-
-3.6.1 (2021-08-16)
-------------------
-
-* Fix type hint for ``tree`` argument.
-
- Thanks to kasium for the report in `Issue #352
- <https://github.com/adamchainz/flake8-comprehensions/issues/352>`__.
-
-3.6.0 (2021-08-13)
-------------------
-
-* Add type hints.
-
-3.5.0 (2021-05-10)
-------------------
-
-* Support Python 3.10.
-
-* Stop distributing tests to reduce package size. Tests are not intended to be
- run outside of the tox setup in the repository. Repackagers can use GitHub's
- tarballs per tag.
-
-3.4.0 (2021-03-18)
-------------------
-
-* Remove rules C407 (Unnecessary ``<dict/list>`` comprehension - ``<builtin>``
- can take a generator) and C412 (Unnecessary ``<dict/list/set>`` comprehension
- - 'in' can take a generator). Both rules recommended increasing laziness,
- which is not always desirable and can lead to subtle bugs. Also, a fully
- exhausted generator is slower than an equivalent comprehension, so the advice
- did not always improve performance.
-
- Thanks to David Smith, Dylan Young, and Leonidas Loucas for the report in
- `Issue #247
- <https://github.com/adamchainz/flake8-comprehensions/issues/247>`__.
-
-3.3.1 (2020-12-19)
-------------------
-
-* Drop Python 3.5 support.
-* Improved installation instructions in README.
-
-3.3.0 (2020-10-23)
-------------------
-
-* Support Python 3.9.
-* Move license from ISC to MIT License.
-* Partially reverted the change to ``C408`` to make it apply again to when
- ``dict`` is called with keyword arguments, e.g. ``dict(a=1, b=2)`` will be
- flagged to be rewritten in the literal form ``{"a": 1, "b": 2}``
-
-3.2.3 (2020-06-06)
-------------------
-
-* Made ``C408`` only apply when no arguments are passed to
- ``dict``/``list``/``tuple``.
-
-3.2.2 (2020-01-20)
-------------------
-
-* Remove check for dict comprehensions in rule C407 as it would also change the
- results for certain builtins such as ``sum()``.
-
-3.2.1 (2020-01-20)
-------------------
-
-* Remove check for set comprehensions in rule C407 as it would change the
- results for certain builtins such as ``sum()``.
-
-3.2.0 (2020-01-20)
-------------------
-
-* Add ``filter`` and ``map`` to rule C407.
-* Check for dict and set comprehensions in rules C407 and C412.
-
-3.1.4 (2019-11-20)
-------------------
-
-* Remove the tuple/unpacking check from C416 to prevent false positives where
- the type of the iterable is changed from some iterable to a tuple.
-
-3.1.3 (2019-11-19)
-------------------
-
-* Ensure the fix for false positives in ``C416`` rule for asynchronous
- comprehensions runs on Python 3.6 too.
-
-3.1.2 (2019-11-18)
-------------------
-
-* Fix false positives in ``C416`` rule for list comprehensions returning
- tuples.
-
-3.1.1 (2019-11-16)
-------------------
-
-* Fix false positives in ``C416`` rule for asynchronous comprehensions.
-
-3.1.0 (2019-11-15)
-------------------
-
-* Update Python support to 3.5-3.8.
-* Fix false positives for C404 for list comprehensions not directly creating
- tuples.
-* Add ``C413`` rule that checks for unnecessary use of ``list()`` or
- ``reversed()`` around ``sorted()``.
-* Add ``C414`` rule that checks for unnecessary use of the following:
- * ``list()``, ``reversed()``, ``sorted()``, or ``tuple()`` within ``set``
- or ``sorted()``
- * ``list()`` or ``tuple()`` within ``list()`` or ``tuple()``
- * ``set()`` within ``set``
-* Add ``C415`` rule that checks for unnecessary reversal of an iterable via
- subscript within ``reversed()``, ``set()``, or ``sorted()``.
-* Add ``C416`` rule that checks for unnecessary list or set comprehensions that
- can be rewritten using ``list()`` or ``set()``.
-
-3.0.1 (2019-10-28)
-------------------
-
-* Fix version display on ``flake8 --version`` (removing dependency on
- ``cached-property``). Thanks to Jon Dufresne.
-
-3.0.0 (2019-10-25)
-------------------
-
-* Update Flake8 support to 3.0+ only. 3.0.0 was released in 2016 and the plugin
- hasn't been tested with it since.
-
-2.3.0 (2019-10-25)
-------------------
-
-* Converted setuptools metadata to configuration file. This meant removing the
- ``__version__`` attribute from the package. If you want to inspect the
- installed version, use
- ``importlib.metadata.version("flake8-comprehensions")``
- (`docs <https://docs.python.org/3.8/library/importlib.metadata.html#distribution-versions>`__ /
- `backport <https://pypi.org/project/importlib-metadata/>`__).
-* Add dependencies on ``cached-property`` and ``importlib-metadata``.
-* Fix false negatives in ``C407`` for cases when ``enumerate`` and ``sum()``
- are passed more than one argument.
-
-2.2.0 (2019-08-12)
-------------------
-
-* Update Python support to 3.5-3.7, as 3.4 has reached its end of life.
-* ``C412`` rule that complains about using list comprehension with ``in``.
-
-2.1.0 (2019-03-01)
-------------------
-
-* Add missing builtin ``enumerate`` to ``C407``.
-
-2.0.0 (2019-02-02)
-------------------
-
-* Drop Python 2 support, only Python 3.4+ is supported now.
-
-1.4.1 (2017-05-17)
-------------------
-
-* Fix false positives in ``C408`` for calls using ``*args`` or ``**kwargs``.
-
-1.4.0 (2017-05-14)
-------------------
-
-* Plugin now reserves the full ``C4XX`` code space rather than just ``C40X``
-* ``C408`` rule that complains about using ``tuple()``, ``list()``, or
- ``dict()`` instead of a literal.
-* ``C409`` and ``C410`` rules that complain about an unnecessary list or tuple
- that could be rewritten as a literal.
-* ``C411`` rule that complains about using list comprehension inside a
- ``list()`` call.
-
-1.3.0 (2017-05-01)
-------------------
-
-* Don't allow installation with Flake8 3.2.0 which doesn't enable the plugin.
- This bug was fixed in Flake8 3.2.1.
-* Prevent false positives of ``C402`` from generators of expressions that
- aren't two-tuples.
-* ``C405`` and ``C406`` now also complain about unnecessary tuple literals.
-
-1.2.1 (2016-06-27)
-------------------
-
-* ``C407`` rule that complains about unnecessary list comprehensions inside
- builtins that can work on generators.
-
-1.2.0 (2016-07-11)
-------------------
-
-* Split all rule codes by type. This allows granular selection of the rules in
- flake8 configuration.
-
-1.1.1 (2016-04-06)
-------------------
-
-* Fix crash on method calls
-
-1.1.0 (2016-04-06)
-------------------
-
-* ``C401`` rule that complains about unnecessary list comprehensions inside
- calls to ``set()`` or ``dict()``.
-* ``C402`` rule that complains about unnecessary list literals inside calls to
- ``set()`` or ``dict()``.
-
-1.0.0 (2016-04-05)
-------------------
-
-* ``C400`` rule that complains about an unnecessary usage of a generator when a
- list/set/dict comprehension would do.
+See https://github.com/adamchainz/flake8-comprehensions/blob/main/CHANGELOG.rst
diff --git a/MANIFEST.in b/MANIFEST.in
index 4556868..f7ed108 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -1,4 +1,4 @@
-include HISTORY.rst
+include CHANGELOG.rst
include LICENSE
include pyproject.toml
include README.rst
diff --git a/README.rst b/README.rst
index cb34478..51d1970 100644
--- a/README.rst
+++ b/README.rst
@@ -2,7 +2,7 @@
flake8-comprehensions
=====================
-.. image:: https://img.shields.io/github/workflow/status/adamchainz/flake8-comprehensions/CI/main?style=for-the-badge
+.. image:: https://img.shields.io/github/actions/workflow/status/adamchainz/flake8-comprehensions/main.yml?branch=main&style=for-the-badge
:target: https://github.com/adamchainz/flake8-comprehensions/actions?workflow=CI
.. image:: https://img.shields.io/pypi/v/flake8-comprehensions.svg?style=for-the-badge
@@ -47,6 +47,12 @@ Rules
C400-402: Unnecessary generator - rewrite as a ``<list/set/dict>`` comprehension.
---------------------------------------------------------------------------------
+Rules:
+
+* C400 Unnecessary generator - rewrite as a list comprehension.
+* C401 Unnecessary generator - rewrite as a set comprehension.
+* C402 Unnecessary generator - rewrite as a 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:
@@ -57,6 +63,11 @@ For example:
C403-404: Unnecessary list comprehension - rewrite as a ``<set/dict>`` comprehension.
-------------------------------------------------------------------------------------
+Rules:
+
+* C403 Unnecessary list comprehension - rewrite as a set comprehension.
+* C404 Unnecessary list comprehension - rewrite as a 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:
@@ -66,6 +77,9 @@ For example:
C405-406: Unnecessary ``<list/tuple>`` literal - rewrite as a ``<set/dict>`` literal.
-------------------------------------------------------------------------------------
+* C405 Unnecessary ``<list/tuple>`` literal - rewrite as a set literal.
+* C406 Unnecessary ``<list/tuple>`` literal - rewrite as a dict literal.
+
It's unnecessary to use a list or tuple literal within a call to ``set`` or ``dict``.
For example:
@@ -76,6 +90,11 @@ For example:
* Rewrite ``dict(((1, 2),))`` as ``{1: 2}``
* Rewrite ``dict([])`` as ``{}``
+C407: Unnecessary ``<dict/list>`` comprehension - ``<builtin>`` can take a generator
+------------------------------------------------------------------------------------
+
+This rule was dropped in version 3.4.0, because it promoted an increase in laziness which could lead to bugs.
+
C408: Unnecessary ``<dict/list/tuple>`` call - rewrite as a literal.
--------------------------------------------------------------------
@@ -88,8 +107,18 @@ For example:
* 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).
------------------------------------------------------------------------------------------------------------------------------------------------------------
+C409-410: Unnecessary ``<list/tuple>`` passed to ``<list/tuple>``\() - ``<advice>``.
+------------------------------------------------------------------------------------
+
+Rules:
+
+* C409 Unnecessary ``<list/tuple>`` passed to tuple() - ``<advice>``.
+* C410 Unnecessary list passed to list() - ``<advice>``.
+
+Where ``<advice>`` is either:
+
+* 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:
@@ -109,6 +138,11 @@ 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.
+--------------------------------------------------------------------------------
+
+This rule was dropped in version 3.4.0, because it promoted an increase in laziness which could lead to bugs.
+
C413: Unnecessary ``<list/reversed>`` call around sorted().
-----------------------------------------------------------
@@ -150,13 +184,14 @@ For example:
* Rewrite ``sorted(iterable)[::-1]`` as ``sorted(iterable, reverse=True)``
* Rewrite ``reversed(iterable[::-1])`` as ``iterable``
-C416: Unnecessary ``<list/set>`` comprehension - rewrite using ``<list/set>``\().
----------------------------------------------------------------------------------
+C416: Unnecessary ``<dict/list/set>`` comprehension - rewrite using ``<dict/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.
+It's unnecessary to use a dict/list/set comprehension to build a data structure if the elements are unchanged.
+Wrap the iterable with ``dict()``, ``list()``, or ``set()`` instead.
For example:
+* Rewrite ``{a: b for a, b in iterable}`` as ``dict(iterable)``
* Rewrite ``[x for x in iterable]`` as ``list(iterable)``
* Rewrite ``{x for x in iterable}`` as ``set(iterable)``
@@ -172,3 +207,23 @@ For example:
* Rewrite ``list(map(lambda num: num * 2, nums))`` to ``[num * 2 for num in nums]``
* Rewrite ``set(map(lambda num: num % 2 == 0, nums))`` to ``{num % 2 == 0 for num in nums}``
* Rewrite ``dict(map(lambda v: (v, v ** 2), values))`` to ``{v : v ** 2 for v in values}``
+
+C418: Unnecessary ``<dict/dict comprehension>`` passed to dict() - remove the outer call to dict()
+--------------------------------------------------------------------------------------------------
+
+It's unnecessary to use a ``dict`` around a dict literal or dict comprehension, since either syntax already constructs a dict.
+For example:
+
+* Rewrite ``dict({})`` as ``{}``
+* Rewrite ``dict({"a": 1})`` as ``{"a": 1}``
+
+C419 Unnecessary list comprehension in ``<any/all>``\() prevents short-circuiting - rewrite as a generator.
+-----------------------------------------------------------------------------------------------------------
+
+Using a list comprehension inside a call to ``any()``/``all()`` prevents short-circuiting when a ``True`` / ``False`` value is found.
+The whole list will be constructed before calling ``any()``/``all()``, potentially wasting work.part-way.
+Rewrite to use a generator expression, which can stop part way.
+For example:
+
+* Rewrite ``all([condition(x) for x in iterable])`` as ``all(condition(x) for x in iterable)``
+* Rewrite ``any([condition(x) for x in iterable])`` as ``any(condition(x) for x in iterable)``
diff --git a/debian/changelog b/debian/changelog
index 80a6c16..eca5df6 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+flake8-comprehensions (3.12.0-1) UNRELEASED; urgency=low
+
+ * New upstream release.
+
+ -- Debian Janitor <janitor@jelmer.uk> Tue, 06 Jun 2023 04:08:42 -0000
+
flake8-comprehensions (3.10.1-2) unstable; urgency=medium
* Team upload.
diff --git a/pyproject.toml b/pyproject.toml
index c9f9f88..f15f73a 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,16 +1,21 @@
[build-system]
-requires = ["setuptools"]
build-backend = "setuptools.build_meta"
+requires = [
+ "setuptools",
+]
[tool.black]
target-version = ['py37']
-[tool.isort]
-profile = "black"
-add_imports = "from __future__ import annotations"
+[tool.pytest.ini_options]
+addopts = """\
+ --strict-config
+ --strict-markers
+ """
[tool.mypy]
mypy_path = "src/"
+namespace_packages = false
show_error_codes = true
strict = true
warn_unreachable = true
@@ -19,8 +24,5 @@ warn_unreachable = true
module = "tests.*"
allow_untyped_defs = true
-[tool.pytest.ini_options]
-addopts = """\
- --strict-config
- --strict-markers
- """
+[tool.rstcheck]
+report_level = "ERROR"
diff --git a/requirements/py310.txt b/requirements/py310.txt
index 2373b34..bb7c4b1 100644
--- a/requirements/py310.txt
+++ b/requirements/py310.txt
@@ -1,52 +1,48 @@
#
-# This file is autogenerated by pip-compile with python 3.10
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.10
+# by the following command:
#
# requirements/compile.py
#
-attrs==22.1.0 \
- --hash=sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6 \
- --hash=sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c
+attrs==22.2.0 \
+ --hash=sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836 \
+ --hash=sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99
# via pytest
-flake8==5.0.4 \
- --hash=sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db \
- --hash=sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248
+exceptiongroup==1.1.1 \
+ --hash=sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e \
+ --hash=sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785
+ # via pytest
+flake8==6.0.0 \
+ --hash=sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7 \
+ --hash=sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181
# via pytest-flake8-path
-iniconfig==1.1.1 \
- --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
- --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
+iniconfig==2.0.0 \
+ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
+ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
# via pytest
mccabe==0.7.0 \
--hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
--hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
# via flake8
-packaging==21.3 \
- --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
- --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
+packaging==23.0 \
+ --hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 \
+ --hash=sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97
# via pytest
pluggy==1.0.0 \
--hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \
--hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3
# via pytest
-py==1.11.0 \
- --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \
- --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378
- # via pytest
-pycodestyle==2.9.1 \
- --hash=sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785 \
- --hash=sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b
+pycodestyle==2.10.0 \
+ --hash=sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053 \
+ --hash=sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610
# via flake8
-pyflakes==2.5.0 \
- --hash=sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2 \
- --hash=sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3
+pyflakes==3.0.1 \
+ --hash=sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf \
+ --hash=sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd
# via flake8
-pyparsing==3.0.9 \
- --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \
- --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc
- # via packaging
-pytest==7.1.3 \
- --hash=sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7 \
- --hash=sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39
+pytest==7.2.2 \
+ --hash=sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e \
+ --hash=sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4
# via
# -r requirements.in
# pytest-flake8-path
diff --git a/requirements/py311.txt b/requirements/py311.txt
index a707301..afc43ca 100644
--- a/requirements/py311.txt
+++ b/requirements/py311.txt
@@ -1,52 +1,44 @@
#
-# This file is autogenerated by pip-compile with python 3.11
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.11
+# by the following command:
#
# requirements/compile.py
#
-attrs==22.1.0 \
- --hash=sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6 \
- --hash=sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c
+attrs==22.2.0 \
+ --hash=sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836 \
+ --hash=sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99
# via pytest
-flake8==5.0.4 \
- --hash=sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db \
- --hash=sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248
+flake8==6.0.0 \
+ --hash=sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7 \
+ --hash=sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181
# via pytest-flake8-path
-iniconfig==1.1.1 \
- --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
- --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
+iniconfig==2.0.0 \
+ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
+ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
# via pytest
mccabe==0.7.0 \
--hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
--hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
# via flake8
-packaging==21.3 \
- --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
- --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
+packaging==23.0 \
+ --hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 \
+ --hash=sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97
# via pytest
pluggy==1.0.0 \
--hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \
--hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3
# via pytest
-py==1.11.0 \
- --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \
- --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378
- # via pytest
-pycodestyle==2.9.1 \
- --hash=sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785 \
- --hash=sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b
+pycodestyle==2.10.0 \
+ --hash=sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053 \
+ --hash=sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610
# via flake8
-pyflakes==2.5.0 \
- --hash=sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2 \
- --hash=sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3
+pyflakes==3.0.1 \
+ --hash=sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf \
+ --hash=sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd
# via flake8
-pyparsing==3.0.9 \
- --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \
- --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc
- # via packaging
-pytest==7.1.3 \
- --hash=sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7 \
- --hash=sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39
+pytest==7.2.2 \
+ --hash=sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e \
+ --hash=sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4
# via
# -r requirements.in
# pytest-flake8-path
@@ -59,7 +51,3 @@ pytest-randomly==3.12.0 \
--hash=sha256:d60c2db71ac319aee0fc6c4110a7597d611a8b94a5590918bfa8583f00caccb2 \
--hash=sha256:f4f2e803daf5d1ba036cc22bf4fe9dbbf99389ec56b00e5cba732fb5c1d07fdd
# via -r requirements.in
-tomli==2.0.1 \
- --hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
- --hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
- # via pytest
diff --git a/requirements/py37.txt b/requirements/py37.txt
index a6084d2..1176245 100644
--- a/requirements/py37.txt
+++ b/requirements/py37.txt
@@ -1,12 +1,16 @@
#
-# This file is autogenerated by pip-compile with python 3.7
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.7
+# by the following command:
#
# requirements/compile.py
#
-attrs==22.1.0 \
- --hash=sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6 \
- --hash=sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c
+attrs==22.2.0 \
+ --hash=sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836 \
+ --hash=sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99
+ # via pytest
+exceptiongroup==1.1.1 \
+ --hash=sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e \
+ --hash=sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785
# via pytest
flake8==5.0.4 \
--hash=sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db \
@@ -21,26 +25,22 @@ importlib-metadata==4.2.0 ; python_version < "3.8" \
# pluggy
# pytest
# pytest-randomly
-iniconfig==1.1.1 \
- --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
- --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
+iniconfig==2.0.0 \
+ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
+ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
# via pytest
mccabe==0.7.0 \
--hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
--hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
# via flake8
-packaging==21.3 \
- --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
- --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
+packaging==23.0 \
+ --hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 \
+ --hash=sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97
# via pytest
pluggy==1.0.0 \
--hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \
--hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3
# via pytest
-py==1.11.0 \
- --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \
- --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378
- # via pytest
pycodestyle==2.9.1 \
--hash=sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785 \
--hash=sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b
@@ -49,13 +49,9 @@ pyflakes==2.5.0 \
--hash=sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2 \
--hash=sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3
# via flake8
-pyparsing==3.0.9 \
- --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \
- --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc
- # via packaging
-pytest==7.1.3 \
- --hash=sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7 \
- --hash=sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39
+pytest==7.2.2 \
+ --hash=sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e \
+ --hash=sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4
# via
# -r requirements.in
# pytest-flake8-path
@@ -72,11 +68,11 @@ tomli==2.0.1 \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
--hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
# via pytest
-typing-extensions==4.4.0 \
- --hash=sha256:1511434bb92bf8dd198c12b1cc812e800d4181cfcb867674e0f8279cc93087aa \
- --hash=sha256:16fa4864408f655d35ec496218b85f79b3437c829e93320c7c9215ccfd92489e
+typing-extensions==4.5.0 \
+ --hash=sha256:5cb5f4a79139d699607b3ef622a1dedafa84e115ab0024e0d9c044a9479ca7cb \
+ --hash=sha256:fb33085c39dd998ac16d1431ebc293a8b3eedd00fd4a32de0ff79002c19511b4
# via importlib-metadata
-zipp==3.9.0 \
- --hash=sha256:3a7af91c3db40ec72dd9d154ae18e008c69efe8ca88dde4f9a731bb82fe2f9eb \
- --hash=sha256:972cfa31bc2fedd3fa838a51e9bc7e64b7fb725a8c00e7431554311f180e9980
+zipp==3.15.0 \
+ --hash=sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b \
+ --hash=sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556
# via importlib-metadata
diff --git a/requirements/py38.txt b/requirements/py38.txt
index 8eb3715..a6e9891 100644
--- a/requirements/py38.txt
+++ b/requirements/py38.txt
@@ -1,56 +1,52 @@
#
-# This file is autogenerated by pip-compile with python 3.8
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.8
+# by the following command:
#
# requirements/compile.py
#
-attrs==22.1.0 \
- --hash=sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6 \
- --hash=sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c
+attrs==22.2.0 \
+ --hash=sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836 \
+ --hash=sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99
# via pytest
-flake8==5.0.4 \
- --hash=sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db \
- --hash=sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248
+exceptiongroup==1.1.1 \
+ --hash=sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e \
+ --hash=sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785
+ # via pytest
+flake8==6.0.0 \
+ --hash=sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7 \
+ --hash=sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181
# via pytest-flake8-path
-importlib-metadata==5.0.0 \
- --hash=sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab \
- --hash=sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43
+importlib-metadata==6.2.0 \
+ --hash=sha256:8388b74023a138c605fddd0d47cb81dd706232569f56c9aca7d9c7fdb54caeba \
+ --hash=sha256:9127aad2f49d7203e7112098c12b92e4fd1061ccd18548cdfdc49171a8c073cc
# via pytest-randomly
-iniconfig==1.1.1 \
- --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
- --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
+iniconfig==2.0.0 \
+ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
+ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
# via pytest
mccabe==0.7.0 \
--hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
--hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
# via flake8
-packaging==21.3 \
- --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
- --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
+packaging==23.0 \
+ --hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 \
+ --hash=sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97
# via pytest
pluggy==1.0.0 \
--hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \
--hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3
# via pytest
-py==1.11.0 \
- --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \
- --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378
- # via pytest
-pycodestyle==2.9.1 \
- --hash=sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785 \
- --hash=sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b
+pycodestyle==2.10.0 \
+ --hash=sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053 \
+ --hash=sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610
# via flake8
-pyflakes==2.5.0 \
- --hash=sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2 \
- --hash=sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3
+pyflakes==3.0.1 \
+ --hash=sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf \
+ --hash=sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd
# via flake8
-pyparsing==3.0.9 \
- --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \
- --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc
- # via packaging
-pytest==7.1.3 \
- --hash=sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7 \
- --hash=sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39
+pytest==7.2.2 \
+ --hash=sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e \
+ --hash=sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4
# via
# -r requirements.in
# pytest-flake8-path
@@ -67,7 +63,7 @@ tomli==2.0.1 \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
--hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
# via pytest
-zipp==3.9.0 \
- --hash=sha256:3a7af91c3db40ec72dd9d154ae18e008c69efe8ca88dde4f9a731bb82fe2f9eb \
- --hash=sha256:972cfa31bc2fedd3fa838a51e9bc7e64b7fb725a8c00e7431554311f180e9980
+zipp==3.15.0 \
+ --hash=sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b \
+ --hash=sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556
# via importlib-metadata
diff --git a/requirements/py39.txt b/requirements/py39.txt
index 80f593b..f1f9f30 100644
--- a/requirements/py39.txt
+++ b/requirements/py39.txt
@@ -1,56 +1,52 @@
#
-# This file is autogenerated by pip-compile with python 3.9
-# To update, run:
+# This file is autogenerated by pip-compile with Python 3.9
+# by the following command:
#
# requirements/compile.py
#
-attrs==22.1.0 \
- --hash=sha256:29adc2665447e5191d0e7c568fde78b21f9672d344281d0c6e1ab085429b22b6 \
- --hash=sha256:86efa402f67bf2df34f51a335487cf46b1ec130d02b8d39fd248abfd30da551c
+attrs==22.2.0 \
+ --hash=sha256:29e95c7f6778868dbd49170f98f8818f78f3dc5e0e37c0b1f474e3561b240836 \
+ --hash=sha256:c9227bfc2f01993c03f68db37d1d15c9690188323c067c641f1a35ca58185f99
# via pytest
-flake8==5.0.4 \
- --hash=sha256:6fbe320aad8d6b95cec8b8e47bc933004678dc63095be98528b7bdd2a9f510db \
- --hash=sha256:7a1cf6b73744f5806ab95e526f6f0d8c01c66d7bbe349562d22dfca20610b248
+exceptiongroup==1.1.1 \
+ --hash=sha256:232c37c63e4f682982c8b6459f33a8981039e5fb8756b2074364e5055c498c9e \
+ --hash=sha256:d484c3090ba2889ae2928419117447a14daf3c1231d5e30d0aae34f354f01785
+ # via pytest
+flake8==6.0.0 \
+ --hash=sha256:3833794e27ff64ea4e9cf5d410082a8b97ff1a06c16aa3d2027339cd0f1195c7 \
+ --hash=sha256:c61007e76655af75e6785a931f452915b371dc48f56efd765247c8fe68f2b181
# via pytest-flake8-path
-importlib-metadata==5.0.0 \
- --hash=sha256:da31db32b304314d044d3c12c79bd59e307889b287ad12ff387b3500835fc2ab \
- --hash=sha256:ddb0e35065e8938f867ed4928d0ae5bf2a53b7773871bfe6bcc7e4fcdc7dea43
+importlib-metadata==6.2.0 \
+ --hash=sha256:8388b74023a138c605fddd0d47cb81dd706232569f56c9aca7d9c7fdb54caeba \
+ --hash=sha256:9127aad2f49d7203e7112098c12b92e4fd1061ccd18548cdfdc49171a8c073cc
# via pytest-randomly
-iniconfig==1.1.1 \
- --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
- --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
+iniconfig==2.0.0 \
+ --hash=sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3 \
+ --hash=sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374
# via pytest
mccabe==0.7.0 \
--hash=sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325 \
--hash=sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e
# via flake8
-packaging==21.3 \
- --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
- --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
+packaging==23.0 \
+ --hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 \
+ --hash=sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97
# via pytest
pluggy==1.0.0 \
--hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \
--hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3
# via pytest
-py==1.11.0 \
- --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \
- --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378
- # via pytest
-pycodestyle==2.9.1 \
- --hash=sha256:2c9607871d58c76354b697b42f5d57e1ada7d261c261efac224b664affdc5785 \
- --hash=sha256:d1735fc58b418fd7c5f658d28d943854f8a849b01a5d0a1e6f3f3fdd0166804b
+pycodestyle==2.10.0 \
+ --hash=sha256:347187bdb476329d98f695c213d7295a846d1152ff4fe9bacb8a9590b8ee7053 \
+ --hash=sha256:8a4eaf0d0495c7395bdab3589ac2db602797d76207242c17d470186815706610
# via flake8
-pyflakes==2.5.0 \
- --hash=sha256:4579f67d887f804e67edb544428f264b7b24f435b263c4614f384135cea553d2 \
- --hash=sha256:491feb020dca48ccc562a8c0cbe8df07ee13078df59813b83959cbdada312ea3
+pyflakes==3.0.1 \
+ --hash=sha256:ec55bf7fe21fff7f1ad2f7da62363d749e2a470500eab1b555334b67aa1ef8cf \
+ --hash=sha256:ec8b276a6b60bd80defed25add7e439881c19e64850afd9b346283d4165fd0fd
# via flake8
-pyparsing==3.0.9 \
- --hash=sha256:2b020ecf7d21b687f219b71ecad3631f644a47f01403fa1d1036b0c6416d70fb \
- --hash=sha256:5026bae9a10eeaefb61dab2f09052b9f4307d44aee4eda64b309723d8d206bbc
- # via packaging
-pytest==7.1.3 \
- --hash=sha256:1377bda3466d70b55e3f5cecfa55bb7cfcf219c7964629b967c37cf0bda818b7 \
- --hash=sha256:4f365fec2dff9c1162f834d9f18af1ba13062db0c708bf7b946f8a5c76180c39
+pytest==7.2.2 \
+ --hash=sha256:130328f552dcfac0b1cec75c12e3f005619dc5f874f0a06e8ff7263f0ee6225e \
+ --hash=sha256:c99ab0c73aceb050f68929bc93af19ab6db0558791c6a0715723abe9d0ade9d4
# via
# -r requirements.in
# pytest-flake8-path
@@ -67,7 +63,7 @@ tomli==2.0.1 \
--hash=sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc \
--hash=sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f
# via pytest
-zipp==3.9.0 \
- --hash=sha256:3a7af91c3db40ec72dd9d154ae18e008c69efe8ca88dde4f9a731bb82fe2f9eb \
- --hash=sha256:972cfa31bc2fedd3fa838a51e9bc7e64b7fb725a8c00e7431554311f180e9980
+zipp==3.15.0 \
+ --hash=sha256:112929ad649da941c23de50f356a2b5570c954b65150642bccdd66bf194d224b \
+ --hash=sha256:48904fc76a60e542af151aded95726c1a5c34ed43ab4134b597665c86d7ad556
# via importlib-metadata
diff --git a/setup.cfg b/setup.cfg
index 8a2bb8c..8d58990 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,41 +1,43 @@
[metadata]
-name = flake8-comprehensions
-version = 3.10.1
+name = flake8_comprehensions
+version = 3.12.0
description = A flake8 plugin to help you write better list/set/dict comprehensions.
long_description = file: README.rst
long_description_content_type = text/x-rst
+url = https://github.com/adamchainz/flake8-comprehensions
author = Adam Johnson
author_email = me@adamj.eu
-url = https://github.com/adamchainz/flake8-comprehensions
-project_urls =
- Changelog = https://github.com/adamchainz/flake8-comprehensions/blob/main/HISTORY.rst
- Twitter = https://twitter.com/adamchainz
license = MIT
-keywords = flake8, comprehensions, list comprehension, set comprehension, dict comprehension
+license_file = LICENSE
classifiers =
Development Status :: 5 - Production/Stable
Framework :: Flake8
Intended Audience :: Developers
License :: OSI Approved :: MIT License
Natural Language :: English
- Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3
+ Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Typing :: Typed
+keywords = flake8, comprehensions, list comprehension, set comprehension, dict comprehension
+project_urls =
+ Changelog = https://github.com/adamchainz/flake8-comprehensions/blob/main/CHANGELOG.rst
+ Mastodon = https://fosstodon.org/@adamchainz
+ Twitter = https://twitter.com/adamchainz
[options]
-package_dir=
- =src
packages = find:
-include_package_data = True
install_requires =
- flake8>=3.0,!=3.2.0
- importlib-metadata ; python_version < "3.8"
+ flake8!=3.2.0,>=3.0
+ importlib-metadata;python_version < "3.8"
python_requires = >=3.7
+include_package_data = True
+package_dir =
+ =src
zip_safe = False
[options.packages.find]
diff --git a/src/flake8_comprehensions/__init__.py b/src/flake8_comprehensions/__init__.py
index 27f519b..b18a8ba 100644
--- a/src/flake8_comprehensions/__init__.py
+++ b/src/flake8_comprehensions/__init__.py
@@ -2,7 +2,8 @@ from __future__ import annotations
import ast
import sys
-from typing import Any, Generator
+from typing import Any
+from typing import Generator
if sys.version_info >= (3, 8):
from importlib.metadata import version
@@ -42,6 +43,14 @@ class ComprehensionChecker:
"C415": "C415 Unnecessary subscript reversal of iterable within {func}().",
"C416": "C416 Unnecessary {type} comprehension - rewrite using {type}().",
"C417": "C417 Unnecessary use of map - use a {comp} instead.",
+ "C418": (
+ "C418 Unnecessary {type} passed to dict() - "
+ + "remove the outer call to dict()."
+ ),
+ "C419": (
+ "C419 Unnecessary list comprehension passed to {func}() prevents "
+ + "short-circuiting - rewrite as a generator."
+ ),
}
def run(self) -> Generator[tuple[int, int, str, type[Any]], None, None]:
@@ -88,13 +97,19 @@ class ComprehensionChecker:
elif (
num_positional_args == 1
and isinstance(node.args[0], ast.ListComp)
- and node.func.id in ("list", "set")
+ and node.func.id in ("list", "set", "any", "all")
):
- msg_key = {"list": "C411", "set": "C403"}[node.func.id]
+ msg_key = {
+ "list": "C411",
+ "set": "C403",
+ "any": "C419",
+ "all": "C419",
+ }[node.func.id]
+ msg = self.messages[msg_key].format(func=node.func.id)
yield (
node.lineno,
node.col_offset,
- self.messages[msg_key],
+ msg,
type(self),
)
@@ -116,10 +131,36 @@ class ComprehensionChecker:
type(self),
)
+ elif (
+ num_positional_args == 1
+ and num_keyword_args == 0
+ and isinstance(node.args[0], (ast.Dict, ast.DictComp))
+ and node.func.id == "dict"
+ ):
+ if isinstance(node.args[0], ast.Dict):
+ type_ = "dict"
+ else:
+ type_ = "dict comprehension"
+ yield (
+ node.lineno,
+ node.col_offset,
+ self.messages["C418"].format(type=type_),
+ type(self),
+ )
+
elif (
num_positional_args == 1
and isinstance(node.args[0], (ast.Tuple, ast.List))
- and node.func.id in ("tuple", "list", "set", "dict")
+ and (
+ node.func.id in ("tuple", "list", "set")
+ or (
+ node.func.id == "dict"
+ and all(
+ isinstance(i, ast.Tuple) and len(i.elts) == 2
+ for i in node.args[0].elts
+ )
+ )
+ )
):
suffix = "rewrite as a {func} literal."
msg_key = {
@@ -294,18 +335,31 @@ class ComprehensionChecker:
type(self),
)
- elif isinstance(node, (ast.ListComp, ast.SetComp)):
+ elif isinstance(node, (ast.DictComp, ast.ListComp, ast.SetComp)):
if (
len(node.generators) == 1
and not node.generators[0].ifs
and not node.generators[0].is_async
and (
- isinstance(node.elt, ast.Name)
- and isinstance(node.generators[0].target, ast.Name)
- and node.elt.id == node.generators[0].target.id
+ (
+ isinstance(node, (ast.ListComp, ast.SetComp))
+ and isinstance(node.elt, ast.Name)
+ and isinstance(node.generators[0].target, ast.Name)
+ and node.elt.id == node.generators[0].target.id
+ )
+ or (
+ isinstance(node, ast.DictComp)
+ and isinstance(node.key, ast.Name)
+ and isinstance(node.value, ast.Name)
+ and isinstance(node.generators[0].target, ast.Tuple)
+ and len(node.generators[0].target.elts) == 2
+ and isinstance(node.generators[0].target.elts[0], ast.Name)
+ and node.generators[0].target.elts[0].id == node.key.id
+ and isinstance(node.generators[0].target.elts[1], ast.Name)
+ and node.generators[0].target.elts[1].id == node.value.id
+ )
)
):
-
yield (
node.lineno,
node.col_offset,
diff --git a/tests/test_flake8_comprehensions.py b/tests/test_flake8_comprehensions.py
index 5e9626a..5537cb8 100644
--- a/tests/test_flake8_comprehensions.py
+++ b/tests/test_flake8_comprehensions.py
@@ -289,6 +289,8 @@ def test_C405_fail(code, failures, flake8_path):
"code",
[
"foo = dict(range)",
+ "something = (1, 2); dict([something])",
+ "dict([(1,)])",
],
)
def test_C406_pass(code, flake8_path):
@@ -757,6 +759,10 @@ def test_C415_fail(code, failures, flake8_path):
@pytest.mark.parametrize(
"code",
[
+ "{x, y for x, y, z in zip('abc', '123', 'def')}",
+ "{y: x for x, y in zip('abc', '123')}",
+ "{x: y for x, (y,) in zip('a', ('1',))}",
+ "{x: z for x, (y,), z in zip('a', ('1',), 'b')}",
"[str(x) for x in range(5)]",
"[x + 1 for x in range(5)]",
"[x for x in range(5) if x % 2]",
@@ -796,6 +802,20 @@ else:
@pytest.mark.parametrize(
"code,failures",
[
+ (
+ "{x: y for x, y in zip(range(5), range(5))}",
+ [
+ "./example.py:1:1: C416 Unnecessary dict comprehension - "
+ + "rewrite using dict().",
+ ],
+ ),
+ (
+ "{x: y for (x, y) in zip(range(5), range(5))}",
+ [
+ "./example.py:1:1: C416 Unnecessary dict comprehension - "
+ + "rewrite using dict().",
+ ],
+ ),
(
"[x for x in range(5)]",
[
@@ -873,3 +893,86 @@ def test_C417_fail(code, failures, flake8_path):
(flake8_path / "example.py").write_text(dedent(code))
result = flake8_path.run_flake8()
assert result.out_lines == failures
+
+
+@pytest.mark.parametrize(
+ "code",
+ [
+ "dict({}, a=1)",
+ "dict({x: 1 for x in range(1)}, a=1)",
+ ],
+)
+def test_C418_pass(code, flake8_path):
+ (flake8_path / "example.py").write_text(dedent(code))
+ result = flake8_path.run_flake8()
+ assert result.out_lines == []
+
+
+@pytest.mark.parametrize(
+ "code,failures",
+ [
+ (
+ "dict({})",
+ [
+ "./example.py:1:1: C418 Unnecessary dict passed to dict() - "
+ + "remove the outer call to dict()."
+ ],
+ ),
+ (
+ "dict({'a': 1})",
+ [
+ "./example.py:1:1: C418 Unnecessary dict passed to dict() - "
+ + "remove the outer call to dict()."
+ ],
+ ),
+ (
+ "dict({'x': 1 for x in range(10)})",
+ [
+ "./example.py:1:1: C418 Unnecessary dict comprehension passed "
+ + "to dict() - remove the outer call to dict()."
+ ],
+ ),
+ ],
+)
+def test_C418_fail(code, failures, flake8_path):
+ (flake8_path / "example.py").write_text(dedent(code))
+ result = flake8_path.run_flake8()
+ assert result.out_lines == failures
+
+
+@pytest.mark.parametrize(
+ "code",
+ [
+ "any(num == 3 for num in range(5))",
+ "all(num == 3 for num in range(5))",
+ ],
+)
+def test_C419_pass(code, flake8_path):
+ (flake8_path / "example.py").write_text(dedent(code))
+ result = flake8_path.run_flake8()
+ assert result.out_lines == []
+
+
+@pytest.mark.parametrize(
+ "code,failures",
+ [
+ (
+ "any([num == 3 for num in range(5)])",
+ [
+ "./example.py:1:1: C419 Unnecessary list comprehension passed "
+ + "to any() prevents short-circuiting - rewrite as a generator."
+ ],
+ ),
+ (
+ "all([num == 3 for num in range(5)])",
+ [
+ "./example.py:1:1: C419 Unnecessary list comprehension passed "
+ + "to all() prevents short-circuiting - rewrite as a generator."
+ ],
+ ),
+ ],
+)
+def test_C419_fail(code, failures, flake8_path):
+ (flake8_path / "example.py").write_text(dedent(code))
+ result = flake8_path.run_flake8()
+ assert result.out_lines == failures
diff --git a/tox.ini b/tox.ini
index 1d2ebc3..bb88516 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,15 +1,17 @@
[tox]
-isolated_build = True
-envlist =
- py{37,38,39,310,311}
+requires =
+ tox>=4.2
+env_list =
+ py{311, 310, 39, 38, 37}
[testenv]
+deps =
+ -r requirements/{envname}.txt
+set_env =
+ PYTHONDEVMODE = 1
commands =
- python \
- -W error::ResourceWarning \
- -W error::DeprecationWarning \
- -W error::PendingDeprecationWarning \
- -m pytest {posargs:tests}
-deps = -r requirements/{envname}.txt
-setenv =
- PYTHONDEVMODE=1
+ python \
+ -W error::ResourceWarning \
+ -W error::DeprecationWarning \
+ -W error::PendingDeprecationWarning \
+ -m pytest {posargs:tests}
Debdiff
[The following lists of changes regard files as different if they have different names, permissions or owners.]
Files in second set of .debs but not in first
-rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.12.0.dist-info/METADATA -rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.12.0.dist-info/RECORD -rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.12.0.dist-info/WHEEL -rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.12.0.dist-info/entry_points.txt -rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.12.0.dist-info/top_level.txt
Files in first set of .debs but not in second
-rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.10.1.dist-info/METADATA -rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.10.1.dist-info/RECORD -rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.10.1.dist-info/WHEEL -rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.10.1.dist-info/entry_points.txt -rw-r--r-- root/root /usr/lib/python3/dist-packages/flake8_comprehensions-3.10.1.dist-info/top_level.txt
No differences were encountered in the control files