diff --git a/.editorconfig b/.editorconfig
deleted file mode 100644
index 22ddbb1..0000000
--- a/.editorconfig
+++ /dev/null
@@ -1,17 +0,0 @@
-# http://editorconfig.org
-
-root = true
-
-[*]
-indent_style = space
-indent_size = 2
-trim_trailing_whitespace = true
-insert_final_newline = true
-charset = utf-8
-end_of_line = lf
-
-[*.py]
-indent_size = 4
-
-[Makefile]
-indent_style = tab
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
deleted file mode 100644
index 40f4ac7..0000000
--- a/.github/CODE_OF_CONDUCT.md
+++ /dev/null
@@ -1 +0,0 @@
-This project follows [Django's Code of Conduct](https://www.djangoproject.com/conduct/).
diff --git a/.github/ISSUE_TEMPLATE/feature-request.yml b/.github/ISSUE_TEMPLATE/feature-request.yml
deleted file mode 100644
index 2a7f84f..0000000
--- a/.github/ISSUE_TEMPLATE/feature-request.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: Feature Request
-description: Request an enhancement or new feature.
-body:
-- type: textarea
-  id: description
-  attributes:
-    label: Description
-    description: Please describe your feature request with appropriate detail.
-  validations:
-    required: true
diff --git a/.github/ISSUE_TEMPLATE/issue.yml b/.github/ISSUE_TEMPLATE/issue.yml
deleted file mode 100644
index eb8a28d..0000000
--- a/.github/ISSUE_TEMPLATE/issue.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-name: Issue
-description: File an issue
-body:
-- type: input
-  id: python_version
-  attributes:
-    label: Python Version
-    description: Which version of Python were you using?
-    placeholder: 3.9.0
-  validations:
-    required: false
-- type: input
-  id: flake8_version
-  attributes:
-    label: flake8 Version
-    description: Which version of flake8 were you using?
-    placeholder: 3.9.2
-  validations:
-    required: false
-- type: input
-  id: package_version
-  attributes:
-    label: Package Version
-    description: Which version of this package were you using? If not the latest version, please check this issue has not since been resolved.
-    placeholder: 1.0.0
-  validations:
-    required: false
-- type: textarea
-  id: description
-  attributes:
-    label: Description
-    description: Please describe your issue.
-  validations:
-    required: true
diff --git a/.github/SECURITY.md b/.github/SECURITY.md
deleted file mode 100644
index 205ab9a..0000000
--- a/.github/SECURITY.md
+++ /dev/null
@@ -1 +0,0 @@
-Please report security issues directly over email to me@adamj.eu
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
deleted file mode 100644
index 29b0808..0000000
--- a/.github/workflows/main.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-name: CI
-
-on:
-  push:
-    branches:
-    - main
-  pull_request:
-
-jobs:
-  tests:
-    name: Python ${{ matrix.python-version }}
-    runs-on: ubuntu-20.04
-
-    strategy:
-      matrix:
-        python-version:
-        - 3.7
-        - 3.8
-        - 3.9
-        - '3.10'
-
-    steps:
-    - uses: actions/checkout@v2
-
-    - uses: actions/setup-python@v2
-      with:
-        python-version: ${{ matrix.python-version }}
-        cache: pip
-        cache-dependency-path: 'requirements/*.txt'
-
-    - name: Install dependencies
-      run: |
-        python -m pip install --upgrade pip setuptools wheel
-        python -m pip install --upgrade tox tox-py
-
-    - name: Run tox targets for ${{ matrix.python-version }}
-      run: tox --py current
diff --git a/.gitignore b/.gitignore
deleted file mode 100644
index 36994f8..0000000
--- a/.gitignore
+++ /dev/null
@@ -1,60 +0,0 @@
-# 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/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
deleted file mode 100644
index 3be9fde..0000000
--- a/.pre-commit-config.yaml
+++ /dev/null
@@ -1,52 +0,0 @@
-default_language_version:
-  python: python3.10
-
-repos:
-- repo: https://github.com/pre-commit/pre-commit-hooks
-  rev: v4.1.0
-  hooks:
-  - id: check-added-large-files
-  - id: check-case-conflict
-  - id: check-json
-  - id: check-merge-conflict
-  - id: check-symlinks
-  - id: check-toml
-  - id: end-of-file-fixer
-  - id: trailing-whitespace
-- repo: https://github.com/asottile/pyupgrade
-  rev: v2.31.0
-  hooks:
-  - id: pyupgrade
-    args: [--py37-plus]
-- repo: https://github.com/psf/black
-  rev: 21.12b0
-  hooks:
-  - id: black
-- repo: https://github.com/asottile/blacken-docs
-  rev: v1.12.0
-  hooks:
-  - id: blacken-docs
-    additional_dependencies:
-    - black==21.11b1
-- repo: https://github.com/pycqa/isort
-  rev: 5.10.1
-  hooks:
-  - id: isort
-- repo: https://github.com/PyCQA/flake8
-  rev: 4.0.1
-  hooks:
-  - id: flake8
-    additional_dependencies:
-    - flake8-bugbear
-    - flake8-comprehensions
-    - flake8-tidy-imports
-    - flake8-typing-imports
-- repo: https://github.com/mgedmin/check-manifest
-  rev: "0.47"
-  hooks:
-  - id: check-manifest
-    args: [--no-build-isolation]
-- repo: https://github.com/pre-commit/mirrors-mypy
-  rev: v0.930
-  hooks:
-  - id: mypy
diff --git a/LICENSE b/LICENSE
index c8f54cc..f0a2abf 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2017-2021 Adam Johnson
+Copyright (c) 2017 Adam Johnson
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..1a657dd
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,190 @@
+Metadata-Version: 2.1
+Name: flake8-comprehensions
+Version: 3.8.0
+Summary: A flake8 plugin to help you write better list/set/dict comprehensions.
+Home-page: https://github.com/adamchainz/flake8-comprehensions
+Author: Adam Johnson
+Author-email: me@adamj.eu
+License: MIT
+Project-URL: Changelog, https://github.com/adamchainz/flake8-comprehensions/blob/main/HISTORY.rst
+Project-URL: Twitter, https://twitter.com/adamchainz
+Keywords: flake8,comprehensions,list comprehension,set comprehension,dict comprehension
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Framework :: Flake8
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Natural Language :: English
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+
+=====================
+flake8-comprehensions
+=====================
+
+.. image:: https://img.shields.io/github/workflow/status/adamchainz/flake8-comprehensions/CI/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
+   :target: https://pypi.org/project/flake8-comprehensions/
+
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge
+   :target: https://github.com/psf/black
+
+.. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge
+   :target: https://github.com/pre-commit/pre-commit
+   :alt: pre-commit
+
+A `flake8 <https://flake8.readthedocs.io/en/latest/index.html>`_ plugin that helps you write better list/set/dict comprehensions.
+
+Requirements
+============
+
+Python 3.7 to 3.10 supported.
+
+Installation
+============
+
+First, install with ``pip``:
+
+.. code-block:: sh
+
+     python -m pip install flake8-comprehensions
+
+Second, if you define Flake8’s ``select`` setting, add the ``C4`` prefix to it.
+Otherwise, the plugin should be active by default.
+
+----
+
+**Linting a Django project?**
+Check out my book `Boost Your Django DX <https://adamchainz.gumroad.com/l/byddx>`__ which covers Flake8 and many other code quality tools.
+
+----
+
+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 ``{}``
+
+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]``
+
+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)``
+
+
diff --git a/debian/changelog b/debian/changelog
index 884498b..760cdc0 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,9 @@
+flake8-comprehensions (3.8.0+git20220411.1.da26d5c-1) UNRELEASED; urgency=low
+
+  * New upstream snapshot.
+
+ -- Debian Janitor <janitor@jelmer.uk>  Sat, 16 Apr 2022 20:47:29 -0000
+
 flake8-comprehensions (3.8.0-1) unstable; urgency=medium
 
   * New upstream version 3.8.0
diff --git a/pyproject.toml b/pyproject.toml
index 3b43eac..2cd8eee 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -7,6 +7,7 @@ target-version = ['py37']
 
 [tool.isort]
 profile = "black"
+add_imports = "from __future__ import annotations"
 
 [tool.mypy]
 check_untyped_defs = true
diff --git a/requirements/compile.py b/requirements/compile.py
deleted file mode 100755
index f15e845..0000000
--- a/requirements/compile.py
+++ /dev/null
@@ -1,37 +0,0 @@
-#!/usr/bin/env python
-import os
-import subprocess
-import sys
-from pathlib import Path
-
-if __name__ == "__main__":
-    os.chdir(Path(__file__).parent)
-    os.environ["CUSTOM_COMPILE_COMMAND"] = "requirements/compile.py"
-    os.environ.pop("PIP_REQUIRE_VIRTUALENV", None)
-    common_args = [
-        "-m",
-        "piptools",
-        "compile",
-        "--generate-hashes",
-        "--allow-unsafe",
-    ] + sys.argv[1:]
-    subprocess.run(
-        ["python3.7", *common_args, "-o", "py37.txt"],
-        check=True,
-        capture_output=True,
-    )
-    subprocess.run(
-        ["python3.8", *common_args, "-o", "py38.txt"],
-        check=True,
-        capture_output=True,
-    )
-    subprocess.run(
-        ["python3.9", *common_args, "-o", "py39.txt"],
-        check=True,
-        capture_output=True,
-    )
-    subprocess.run(
-        ["python3.10", *common_args, "-o", "py310.txt"],
-        check=True,
-        capture_output=True,
-    )
diff --git a/requirements/py310.txt b/requirements/py310.txt
deleted file mode 100644
index 4abe879..0000000
--- a/requirements/py310.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# This file is autogenerated by pip-compile with python 3.10
-# To update, run:
-#
-#    requirements/compile.py
-#
-attrs==21.4.0 \
-    --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4 \
-    --hash=sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd
-    # via pytest
-flake8==4.0.1 \
-    --hash=sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d \
-    --hash=sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d
-    # via pytest-flake8-path
-iniconfig==1.1.1 \
-    --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
-    --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
-    # via pytest
-mccabe==0.6.1 \
-    --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \
-    --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f
-    # via flake8
-packaging==21.3 \
-    --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
-    --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
-    # 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.8.0 \
-    --hash=sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20 \
-    --hash=sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f
-    # via flake8
-pyflakes==2.4.0 \
-    --hash=sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c \
-    --hash=sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e
-    # via flake8
-pyparsing==3.0.6 \
-    --hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \
-    --hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81
-    # via packaging
-pytest==6.2.5 \
-    --hash=sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89 \
-    --hash=sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134
-    # via
-    #   -r requirements.in
-    #   pytest-flake8-path
-    #   pytest-randomly
-pytest-flake8-path==1.1.0 \
-    --hash=sha256:7e55d16c7d26031bebff282283e02326c780e9314a1b4567f04bf0495e4d9a8f \
-    --hash=sha256:d86248a3f7d7be4eb18f28fa27f31a31a43f07ce8d348c30055cfddc7339f58e
-    # via -r requirements.in
-pytest-randomly==3.10.3 \
-    --hash=sha256:22154cdcff7ba44e0599596490e6b75278ca973a33812ea6a54bf14d0b042ef1 \
-    --hash=sha256:b05a7a45f54cae2b5095752c6a10cb559df84448421b0420ae492dd2fb1727ef
-    # via -r requirements.in
-toml==0.10.2 \
-    --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
-    --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
-    # via pytest
diff --git a/requirements/py37.txt b/requirements/py37.txt
deleted file mode 100644
index 694aead..0000000
--- a/requirements/py37.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-#
-# This file is autogenerated by pip-compile with python 3.7
-# To update, run:
-#
-#    requirements/compile.py
-#
-attrs==21.4.0 \
-    --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4 \
-    --hash=sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd
-    # via pytest
-flake8==4.0.1 \
-    --hash=sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d \
-    --hash=sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d
-    # via pytest-flake8-path
-importlib-metadata==4.2.0 ; python_version < "3.8" \
-    --hash=sha256:057e92c15bc8d9e8109738a48db0ccb31b4d9d5cfbee5a8670879a30be66304b \
-    --hash=sha256:b7e52a1f8dec14a75ea73e0891f3060099ca1d8e6a462a4dff11c3e119ea1b31
-    # via
-    #   -r requirements.in
-    #   flake8
-    #   pluggy
-    #   pytest
-    #   pytest-randomly
-iniconfig==1.1.1 \
-    --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
-    --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
-    # via pytest
-mccabe==0.6.1 \
-    --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \
-    --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f
-    # via flake8
-packaging==21.3 \
-    --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
-    --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
-    # 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.8.0 \
-    --hash=sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20 \
-    --hash=sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f
-    # via flake8
-pyflakes==2.4.0 \
-    --hash=sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c \
-    --hash=sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e
-    # via flake8
-pyparsing==3.0.6 \
-    --hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \
-    --hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81
-    # via packaging
-pytest==6.2.5 \
-    --hash=sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89 \
-    --hash=sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134
-    # via
-    #   -r requirements.in
-    #   pytest-flake8-path
-    #   pytest-randomly
-pytest-flake8-path==1.1.0 \
-    --hash=sha256:7e55d16c7d26031bebff282283e02326c780e9314a1b4567f04bf0495e4d9a8f \
-    --hash=sha256:d86248a3f7d7be4eb18f28fa27f31a31a43f07ce8d348c30055cfddc7339f58e
-    # via -r requirements.in
-pytest-randomly==3.10.3 \
-    --hash=sha256:22154cdcff7ba44e0599596490e6b75278ca973a33812ea6a54bf14d0b042ef1 \
-    --hash=sha256:b05a7a45f54cae2b5095752c6a10cb559df84448421b0420ae492dd2fb1727ef
-    # via -r requirements.in
-toml==0.10.2 \
-    --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
-    --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
-    # via pytest
-typing-extensions==4.0.1 \
-    --hash=sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e \
-    --hash=sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b
-    # via importlib-metadata
-zipp==3.7.0 \
-    --hash=sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d \
-    --hash=sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375
-    # via importlib-metadata
diff --git a/requirements/py38.txt b/requirements/py38.txt
deleted file mode 100644
index 81169a5..0000000
--- a/requirements/py38.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# This file is autogenerated by pip-compile with python 3.8
-# To update, run:
-#
-#    requirements/compile.py
-#
-attrs==21.4.0 \
-    --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4 \
-    --hash=sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd
-    # via pytest
-flake8==4.0.1 \
-    --hash=sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d \
-    --hash=sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d
-    # via pytest-flake8-path
-importlib-metadata==4.10.0 \
-    --hash=sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6 \
-    --hash=sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4
-    # via pytest-randomly
-iniconfig==1.1.1 \
-    --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
-    --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
-    # via pytest
-mccabe==0.6.1 \
-    --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \
-    --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f
-    # via flake8
-packaging==21.3 \
-    --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
-    --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
-    # 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.8.0 \
-    --hash=sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20 \
-    --hash=sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f
-    # via flake8
-pyflakes==2.4.0 \
-    --hash=sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c \
-    --hash=sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e
-    # via flake8
-pyparsing==3.0.6 \
-    --hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \
-    --hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81
-    # via packaging
-pytest==6.2.5 \
-    --hash=sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89 \
-    --hash=sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134
-    # via
-    #   -r requirements.in
-    #   pytest-flake8-path
-    #   pytest-randomly
-pytest-flake8-path==1.1.0 \
-    --hash=sha256:7e55d16c7d26031bebff282283e02326c780e9314a1b4567f04bf0495e4d9a8f \
-    --hash=sha256:d86248a3f7d7be4eb18f28fa27f31a31a43f07ce8d348c30055cfddc7339f58e
-    # via -r requirements.in
-pytest-randomly==3.10.3 \
-    --hash=sha256:22154cdcff7ba44e0599596490e6b75278ca973a33812ea6a54bf14d0b042ef1 \
-    --hash=sha256:b05a7a45f54cae2b5095752c6a10cb559df84448421b0420ae492dd2fb1727ef
-    # via -r requirements.in
-toml==0.10.2 \
-    --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
-    --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
-    # via pytest
-zipp==3.7.0 \
-    --hash=sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d \
-    --hash=sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375
-    # via importlib-metadata
diff --git a/requirements/py39.txt b/requirements/py39.txt
deleted file mode 100644
index 710d4c9..0000000
--- a/requirements/py39.txt
+++ /dev/null
@@ -1,73 +0,0 @@
-#
-# This file is autogenerated by pip-compile with python 3.9
-# To update, run:
-#
-#    requirements/compile.py
-#
-attrs==21.4.0 \
-    --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4 \
-    --hash=sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd
-    # via pytest
-flake8==4.0.1 \
-    --hash=sha256:479b1304f72536a55948cb40a32dce8bb0ffe3501e26eaf292c7e60eb5e0428d \
-    --hash=sha256:806e034dda44114815e23c16ef92f95c91e4c71100ff52813adf7132a6ad870d
-    # via pytest-flake8-path
-importlib-metadata==4.10.0 \
-    --hash=sha256:92a8b58ce734b2a4494878e0ecf7d79ccd7a128b5fc6014c401e0b61f006f0f6 \
-    --hash=sha256:b7cf7d3fef75f1e4c80a96ca660efbd51473d7e8f39b5ab9210febc7809012a4
-    # via pytest-randomly
-iniconfig==1.1.1 \
-    --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \
-    --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32
-    # via pytest
-mccabe==0.6.1 \
-    --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \
-    --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f
-    # via flake8
-packaging==21.3 \
-    --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \
-    --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522
-    # 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.8.0 \
-    --hash=sha256:720f8b39dde8b293825e7ff02c475f3077124006db4f440dcbc9a20b76548a20 \
-    --hash=sha256:eddd5847ef438ea1c7870ca7eb78a9d47ce0cdb4851a5523949f2601d0cbbe7f
-    # via flake8
-pyflakes==2.4.0 \
-    --hash=sha256:05a85c2872edf37a4ed30b0cce2f6093e1d0581f8c19d7393122da7e25b2b24c \
-    --hash=sha256:3bb3a3f256f4b7968c9c788781e4ff07dce46bdf12339dcda61053375426ee2e
-    # via flake8
-pyparsing==3.0.6 \
-    --hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \
-    --hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81
-    # via packaging
-pytest==6.2.5 \
-    --hash=sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89 \
-    --hash=sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134
-    # via
-    #   -r requirements.in
-    #   pytest-flake8-path
-    #   pytest-randomly
-pytest-flake8-path==1.1.0 \
-    --hash=sha256:7e55d16c7d26031bebff282283e02326c780e9314a1b4567f04bf0495e4d9a8f \
-    --hash=sha256:d86248a3f7d7be4eb18f28fa27f31a31a43f07ce8d348c30055cfddc7339f58e
-    # via -r requirements.in
-pytest-randomly==3.10.3 \
-    --hash=sha256:22154cdcff7ba44e0599596490e6b75278ca973a33812ea6a54bf14d0b042ef1 \
-    --hash=sha256:b05a7a45f54cae2b5095752c6a10cb559df84448421b0420ae492dd2fb1727ef
-    # via -r requirements.in
-toml==0.10.2 \
-    --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \
-    --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f
-    # via pytest
-zipp==3.7.0 \
-    --hash=sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d \
-    --hash=sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375
-    # via importlib-metadata
diff --git a/requirements/requirements.in b/requirements/requirements.in
deleted file mode 100644
index 97218c5..0000000
--- a/requirements/requirements.in
+++ /dev/null
@@ -1,4 +0,0 @@
-importlib-metadata ; python_version < "3.8"
-pytest
-pytest-flake8-path
-pytest-randomly
diff --git a/setup.cfg b/setup.cfg
index 1c71892..314dc7d 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -7,33 +7,33 @@ long_description_content_type = text/x-rst
 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
+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
-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.7
-    Programming Language :: Python :: 3.8
-    Programming Language :: Python :: 3.9
-    Programming Language :: Python :: 3.10
+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.7
+	Programming Language :: Python :: 3.8
+	Programming Language :: Python :: 3.9
+	Programming Language :: Python :: 3.10
 license_file = LICENSE
 
 [options]
-package_dir=
-    =src
+package_dir = 
+	=src
 packages = find:
 include_package_data = True
-install_requires =
-    flake8>=3.0,!=3.2.0
-    importlib-metadata ; python_version < "3.8"
+install_requires = 
+	flake8>=3.0,!=3.2.0
+	importlib-metadata ; python_version < "3.8"
 python_requires = >=3.7
 zip_safe = False
 
@@ -41,9 +41,14 @@ zip_safe = False
 where = src
 
 [options.entry_points]
-flake8.extension =
-    C4 = flake8_comprehensions:ComprehensionChecker
+flake8.extension = 
+	C4 = flake8_comprehensions:ComprehensionChecker
 
 [flake8]
 max-line-length = 88
 extend-ignore = E203
+
+[egg_info]
+tag_build = 
+tag_date = 0
+
diff --git a/setup.py b/setup.py
index 6068493..a03590f 100644
--- a/setup.py
+++ b/setup.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
 from setuptools import setup
 
 setup()
diff --git a/src/flake8_comprehensions.egg-info/PKG-INFO b/src/flake8_comprehensions.egg-info/PKG-INFO
new file mode 100644
index 0000000..1a657dd
--- /dev/null
+++ b/src/flake8_comprehensions.egg-info/PKG-INFO
@@ -0,0 +1,190 @@
+Metadata-Version: 2.1
+Name: flake8-comprehensions
+Version: 3.8.0
+Summary: A flake8 plugin to help you write better list/set/dict comprehensions.
+Home-page: https://github.com/adamchainz/flake8-comprehensions
+Author: Adam Johnson
+Author-email: me@adamj.eu
+License: MIT
+Project-URL: Changelog, https://github.com/adamchainz/flake8-comprehensions/blob/main/HISTORY.rst
+Project-URL: Twitter, https://twitter.com/adamchainz
+Keywords: flake8,comprehensions,list comprehension,set comprehension,dict comprehension
+Platform: UNKNOWN
+Classifier: Development Status :: 5 - Production/Stable
+Classifier: Framework :: Flake8
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: MIT License
+Classifier: Natural Language :: English
+Classifier: Programming Language :: Python :: 3 :: Only
+Classifier: Programming Language :: Python :: 3
+Classifier: Programming Language :: Python :: 3.7
+Classifier: Programming Language :: Python :: 3.8
+Classifier: Programming Language :: Python :: 3.9
+Classifier: Programming Language :: Python :: 3.10
+Requires-Python: >=3.7
+Description-Content-Type: text/x-rst
+License-File: LICENSE
+
+=====================
+flake8-comprehensions
+=====================
+
+.. image:: https://img.shields.io/github/workflow/status/adamchainz/flake8-comprehensions/CI/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
+   :target: https://pypi.org/project/flake8-comprehensions/
+
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg?style=for-the-badge
+   :target: https://github.com/psf/black
+
+.. image:: https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white&style=for-the-badge
+   :target: https://github.com/pre-commit/pre-commit
+   :alt: pre-commit
+
+A `flake8 <https://flake8.readthedocs.io/en/latest/index.html>`_ plugin that helps you write better list/set/dict comprehensions.
+
+Requirements
+============
+
+Python 3.7 to 3.10 supported.
+
+Installation
+============
+
+First, install with ``pip``:
+
+.. code-block:: sh
+
+     python -m pip install flake8-comprehensions
+
+Second, if you define Flake8’s ``select`` setting, add the ``C4`` prefix to it.
+Otherwise, the plugin should be active by default.
+
+----
+
+**Linting a Django project?**
+Check out my book `Boost Your Django DX <https://adamchainz.gumroad.com/l/byddx>`__ which covers Flake8 and many other code quality tools.
+
+----
+
+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 ``{}``
+
+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]``
+
+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)``
+
+
diff --git a/src/flake8_comprehensions.egg-info/SOURCES.txt b/src/flake8_comprehensions.egg-info/SOURCES.txt
new file mode 100644
index 0000000..4a1178f
--- /dev/null
+++ b/src/flake8_comprehensions.egg-info/SOURCES.txt
@@ -0,0 +1,16 @@
+HISTORY.rst
+LICENSE
+MANIFEST.in
+README.rst
+pyproject.toml
+setup.cfg
+setup.py
+src/flake8_comprehensions/__init__.py
+src/flake8_comprehensions/py.typed
+src/flake8_comprehensions.egg-info/PKG-INFO
+src/flake8_comprehensions.egg-info/SOURCES.txt
+src/flake8_comprehensions.egg-info/dependency_links.txt
+src/flake8_comprehensions.egg-info/entry_points.txt
+src/flake8_comprehensions.egg-info/not-zip-safe
+src/flake8_comprehensions.egg-info/requires.txt
+src/flake8_comprehensions.egg-info/top_level.txt
\ No newline at end of file
diff --git a/src/flake8_comprehensions.egg-info/dependency_links.txt b/src/flake8_comprehensions.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/flake8_comprehensions.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/src/flake8_comprehensions.egg-info/entry_points.txt b/src/flake8_comprehensions.egg-info/entry_points.txt
new file mode 100644
index 0000000..00a0f77
--- /dev/null
+++ b/src/flake8_comprehensions.egg-info/entry_points.txt
@@ -0,0 +1,3 @@
+[flake8.extension]
+C4 = flake8_comprehensions:ComprehensionChecker
+
diff --git a/src/flake8_comprehensions.egg-info/not-zip-safe b/src/flake8_comprehensions.egg-info/not-zip-safe
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/src/flake8_comprehensions.egg-info/not-zip-safe
@@ -0,0 +1 @@
+
diff --git a/src/flake8_comprehensions.egg-info/requires.txt b/src/flake8_comprehensions.egg-info/requires.txt
new file mode 100644
index 0000000..a10bb66
--- /dev/null
+++ b/src/flake8_comprehensions.egg-info/requires.txt
@@ -0,0 +1,4 @@
+flake8!=3.2.0,>=3.0
+
+[:python_version < "3.8"]
+importlib-metadata
diff --git a/src/flake8_comprehensions.egg-info/top_level.txt b/src/flake8_comprehensions.egg-info/top_level.txt
new file mode 100644
index 0000000..1b8ddbe
--- /dev/null
+++ b/src/flake8_comprehensions.egg-info/top_level.txt
@@ -0,0 +1 @@
+flake8_comprehensions
diff --git a/src/flake8_comprehensions/__init__.py b/src/flake8_comprehensions/__init__.py
index 6448ec0..ea9b768 100644
--- a/src/flake8_comprehensions/__init__.py
+++ b/src/flake8_comprehensions/__init__.py
@@ -1,6 +1,8 @@
+from __future__ import annotations
+
 import ast
 import sys
-from typing import Any, Generator, Optional, Tuple, Type
+from typing import Any, Generator
 
 if sys.version_info >= (3, 8):
     from importlib.metadata import version
@@ -41,7 +43,7 @@ class ComprehensionChecker:
         "C416": "C416 Unnecessary {type} comprehension - rewrite using {type}().",
     }
 
-    def run(self) -> Generator[Tuple[int, int, str, Type[Any]], None, None]:
+    def run(self) -> Generator[tuple[int, int, str, type[Any]], None, None]:
         for node in ast.walk(self.tree):
             if isinstance(node, ast.Call) and isinstance(node.func, ast.Name):
                 num_positional_args = len(node.args)
@@ -165,7 +167,7 @@ class ComprehensionChecker:
                 ):
                     remediation = ""
                     if node.func.id == "reversed":
-                        reverse_flag_value: Optional[bool] = False
+                        reverse_flag_value: bool | None = False
                         for keyword in node.args[0].keywords:
                             if keyword.arg != "reverse":
                                 continue
diff --git a/tests/__init__.py b/tests/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/tests/test_flake8_comprehensions.py b/tests/test_flake8_comprehensions.py
deleted file mode 100644
index 6ded2cd..0000000
--- a/tests/test_flake8_comprehensions.py
+++ /dev/null
@@ -1,773 +0,0 @@
-import re
-import sys
-from textwrap import dedent
-
-import pytest
-
-if sys.version_info >= (3, 8):
-    from importlib.metadata import version
-else:
-    from importlib_metadata import version
-
-
-@pytest.fixture
-def flake8_path(flake8_path):
-    (flake8_path / "setup.cfg").write_text(
-        dedent(
-            """\
-            [flake8]
-            select = C4
-            """
-        )
-    )
-    yield flake8_path
-
-
-def test_version(flake8_path):
-    result = flake8_path.run_flake8(["--version"])
-    version_regex = r"flake8-comprehensions:( )*" + version("flake8-comprehensions")
-    unwrapped = "".join(result.out_lines)
-    assert re.search(version_regex, unwrapped)
-
-
-# C400
-
-
-def test_C400_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = [x + 1 for x in range(10)]")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C400_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = list(x + 1 for x in range(10))")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C400 Unnecessary generator - rewrite as a list "
-        + "comprehension."
-    ]
-
-
-def test_C400_fail_2(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foobar = list(
-                str(x)
-                for x
-                in range(10)
-            )
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:10: C400 Unnecessary generator - rewrite as a list "
-        + "comprehension."
-    ]
-
-
-# C401
-
-
-def test_C401_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = {x + 1 for x in range(10)}")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C401_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = set(x + 1 for x in range(10))")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C401 Unnecessary generator - rewrite as a set "
-        + "comprehension."
-    ]
-
-
-def test_C401_fail_2(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foobar = set(
-                str(x) for x
-                in range(10)
-            )
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:10: C401 Unnecessary generator - rewrite as a set "
-        + "comprehension."
-    ]
-
-
-# C402
-
-
-def test_C402_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = {x: str(x) for x in range(10)}")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C402_pass_2(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foo = ['a=1', 'b=2', 'c=3']
-            dict(pair.split('=') for pair in foo)
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C402_pass_3(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foo = [('a', 1), ('b', 2), ('c', 3)]
-            dict(pair for pair in foo if pair[1] % 2 == 0)
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C402_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text(
-        "foo = dict((x, str(x)) for x in range(10))"
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C402 Unnecessary generator - rewrite as a dict "
-        + "comprehension."
-    ]
-
-
-def test_C402_fail_2(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foobar = dict(
-                (x, str(x))
-                for x
-                in range(10)
-            )
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:10: C402 Unnecessary generator - rewrite as a dict "
-        + "comprehension."
-    ]
-
-
-# C403
-
-
-def test_C403_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = {x + 1 for x in range(10)}")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C403_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = set([x + 1 for x in range(10)])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C403 Unnecessary list comprehension - rewrite as a "
-        + "set comprehension."
-    ]
-
-
-# C404
-
-
-def test_C404_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = {x: x for x in range(10)}")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C404_pass_2(flake8_path):
-    # Previously a false positive
-    (flake8_path / "example.py").write_text(
-        "foo = dict([x.split('=') for x in ['a=1', 'b=2']])"
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C404_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = dict([(x, x) for x in range(10)])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C404 Unnecessary list comprehension - rewrite as a "
-        + "dict comprehension."
-    ]
-
-
-# C405
-
-
-def test_C405_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = set(range)")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C405_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = set([])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C405 Unnecessary list literal - rewrite as a set "
-        + "literal."
-    ]
-
-
-def test_C405_fail_2(flake8_path):
-    (flake8_path / "example.py").write_text("foo = set([1])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C405 Unnecessary list literal - rewrite as a set "
-        + "literal."
-    ]
-
-
-def test_C405_fail_3(flake8_path):
-    (flake8_path / "example.py").write_text("foo = set(())")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C405 Unnecessary tuple literal - rewrite as a set "
-        + "literal."
-    ]
-
-
-def test_C405_fail_4(flake8_path):
-    (flake8_path / "example.py").write_text("foo = set((1,))")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C405 Unnecessary tuple literal - rewrite as a set "
-        + "literal."
-    ]
-
-
-# C406
-
-
-def test_C406_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = dict(range)")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C406_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = dict([])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C406 Unnecessary list literal - rewrite as a dict "
-        + "literal."
-    ]
-
-
-def test_C406_fail_2(flake8_path):
-    (flake8_path / "example.py").write_text("foo = dict([(1, 2)])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C406 Unnecessary list literal - rewrite as a dict "
-        + "literal."
-    ]
-
-
-def test_C406_fail_3(flake8_path):
-    (flake8_path / "example.py").write_text("foo = dict(())")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C406 Unnecessary tuple literal - rewrite as a dict "
-        + "literal."
-    ]
-
-
-def test_C406_fail_4(flake8_path):
-    (flake8_path / "example.py").write_text("foo = dict(((1, 2),))")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C406 Unnecessary tuple literal - rewrite as a dict "
-        + "literal."
-    ]
-
-
-# C408
-
-
-def test_C408_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("()")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C408_pass_2(flake8_path):
-    (flake8_path / "example.py").write_text("[]")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C408_pass_3(flake8_path):
-    (flake8_path / "example.py").write_text("{}")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C408_pass_4(flake8_path):
-    (flake8_path / "example.py").write_text("set()")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C408_pass_5(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foo = [('foo', 2)]
-            dict(foo)
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C408_pass_6(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foo = {}
-            dict(bar=1, **foo)
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C408_pass_7(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foo = [1, 2]
-            list(foo)
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C408_pass_8(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            foo = [1, 2]
-            list(*foo)
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C408_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("tuple()")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:1: C408 Unnecessary tuple call - rewrite as a literal."
-    ]
-
-
-def test_C408_fail_2(flake8_path):
-    (flake8_path / "example.py").write_text("list()")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:1: C408 Unnecessary list call - rewrite as a literal."
-    ]
-
-
-def test_C408_fail_3(flake8_path):
-    (flake8_path / "example.py").write_text("dict()")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:1: C408 Unnecessary dict call - rewrite as a literal."
-    ]
-
-
-def test_C408_fail_4(flake8_path):
-    (flake8_path / "example.py").write_text("dict(a=1)")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:1: C408 Unnecessary dict call - rewrite as a literal."
-    ]
-
-
-# C409
-
-
-def test_C409_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = tuple(range)")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C409_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = tuple([])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C409 Unnecessary list passed to tuple() - rewrite as "
-        + "a tuple literal."
-    ]
-
-
-def test_C409_fail_2(flake8_path):
-    (flake8_path / "example.py").write_text("foo = tuple([1, 2])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C409 Unnecessary list passed to tuple() - rewrite as "
-        + "a tuple literal."
-    ]
-
-
-def test_C409_fail_3(flake8_path):
-    (flake8_path / "example.py").write_text("foo = tuple(())")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C409 Unnecessary tuple passed to tuple() - remove "
-        + "the outer call to tuple()."
-    ]
-
-
-def test_C409_fail_4(flake8_path):
-    (flake8_path / "example.py").write_text("foo = tuple((1, 2))")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C409 Unnecessary tuple passed to tuple() - remove "
-        + "the outer call to tuple()."
-    ]
-
-
-# C410
-
-
-def test_C410_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = list(range)")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C410_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("foo = list([])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C410 Unnecessary list passed to list() - remove the "
-        + "outer call to list()."
-    ]
-
-
-def test_C410_fail_2(flake8_path):
-    (flake8_path / "example.py").write_text("foo = list([1, 2])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C410 Unnecessary list passed to list() - remove the "
-        + "outer call to list()."
-    ]
-
-
-def test_C410_fail_3(flake8_path):
-    (flake8_path / "example.py").write_text("foo = list(())")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C410 Unnecessary tuple passed to list() - rewrite as "
-        + "a list literal."
-    ]
-
-
-def test_C410_fail_4(flake8_path):
-    (flake8_path / "example.py").write_text("foo = list((1, 2))")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:7: C410 Unnecessary tuple passed to list() - rewrite as "
-        + "a list literal."
-    ]
-
-
-# C411
-
-
-def test_C411_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text("[x + 1 for x in range(10)]")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C411_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text("list([x + 1 for x in range(10)])")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:1: C411 Unnecessary list call - remove the outer call "
-        + "to list()."
-    ]
-
-
-# C413
-
-
-def test_C413_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            sorted([2, 3, 1])
-            sorted([2, 3, 1], reverse=True)
-            sorted([2, 3, 1], reverse=False)
-            sorted([2, 3, 1], reverse=0)
-            sorted([2, 3, 1], reverse=1)
-            reversed([2, 3, 1])
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C413_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            list(sorted([2, 3, 1]))
-            reversed(sorted([2, 3, 1]))
-            reversed(sorted([2, 3, 1], reverse=False))
-            reversed(sorted([2, 3, 1], reverse=True))
-            reversed(sorted([2, 3, 1], reverse=0))
-            reversed(sorted([2, 3, 1], reverse=1))
-            reversed(sorted([2, 3, 1], reverse=bool()))
-            reversed(sorted([2, 3, 1], reverse=not True))
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:1: C413 Unnecessary list call around sorted().",
-        "./example.py:2:1: C413 Unnecessary reversed call around sorted()"
-        + " - use sorted(..., reverse=True).",
-        "./example.py:3:1: C413 Unnecessary reversed call around sorted()"
-        + " - use sorted(..., reverse=True).",
-        "./example.py:4:1: C413 Unnecessary reversed call around sorted()"
-        + " - use sorted(..., reverse=False).",
-        "./example.py:5:1: C413 Unnecessary reversed call around sorted()"
-        + " - use sorted(..., reverse=True).",
-        "./example.py:6:1: C413 Unnecessary reversed call around sorted()"
-        + " - use sorted(..., reverse=False).",
-        "./example.py:7:1: C413 Unnecessary reversed call around sorted()"
-        + " - toggle reverse argument to sorted().",
-        "./example.py:8:1: C413 Unnecessary reversed call around sorted()"
-        + " - toggle reverse argument to sorted().",
-    ]
-
-
-# C414
-
-
-def test_C414_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            a = [2, 3, 1]
-            list(set(a))
-            tuple(set(a))
-            sorted(set(a))
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C414_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            a = [2, 3, 1]
-            list(list(a))
-            list(tuple(a))
-            tuple(list(a))
-            tuple(tuple(a))
-            set(set(a))
-            set(list(a))
-            set(tuple(a))
-            set(sorted(a))
-            set(sorted(a, reverse=True))
-            set(reversed(a))
-            sorted(list(a))
-            sorted(tuple(a))
-            sorted(sorted(a))
-            sorted(sorted(a), reverse=True)
-            sorted(sorted(a, reverse=True))
-            sorted(sorted(a, reverse=True), reverse=True)
-            sorted(reversed(a))
-            sorted(reversed(a), reverse=True)
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:2:1: C414 Unnecessary list call within list().",
-        "./example.py:3:1: C414 Unnecessary tuple call within list().",
-        "./example.py:4:1: C414 Unnecessary list call within tuple().",
-        "./example.py:5:1: C414 Unnecessary tuple call within tuple().",
-        "./example.py:6:1: C414 Unnecessary set call within set().",
-        "./example.py:7:1: C414 Unnecessary list call within set().",
-        "./example.py:8:1: C414 Unnecessary tuple call within set().",
-        "./example.py:9:1: C414 Unnecessary sorted call within set().",
-        "./example.py:10:1: C414 Unnecessary sorted call within set().",
-        "./example.py:11:1: C414 Unnecessary reversed call within set().",
-        "./example.py:12:1: C414 Unnecessary list call within sorted().",
-        "./example.py:13:1: C414 Unnecessary tuple call within sorted().",
-        "./example.py:14:1: C414 Unnecessary sorted call within sorted().",
-        "./example.py:15:1: C414 Unnecessary sorted call within sorted().",
-        "./example.py:16:1: C414 Unnecessary sorted call within sorted().",
-        "./example.py:17:1: C414 Unnecessary sorted call within sorted().",
-        "./example.py:18:1: C414 Unnecessary reversed call within sorted().",
-        "./example.py:19:1: C414 Unnecessary reversed call within sorted().",
-    ]
-
-
-# C415
-
-
-def test_C415_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            set([2, 3, 1][::1])
-            sorted([2, 3, 1][::1])
-            reversed([2, 3, 1][::1])
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C415_fail_1(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            set([2, 3, 1][::-1])
-            sorted([2, 3, 1][::-1])
-            sorted([2, 3, 1][::-1], reverse=True)
-            reversed([2, 3, 1][::-1])
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:1: C415 Unnecessary subscript reversal of iterable "
-        + "within set().",
-        "./example.py:2:1: C415 Unnecessary subscript reversal of iterable "
-        + "within sorted().",
-        "./example.py:3:1: C415 Unnecessary subscript reversal of iterable "
-        + "within sorted().",
-        "./example.py:4:1: C415 Unnecessary subscript reversal of iterable "
-        + "within reversed().",
-    ]
-
-
-# C416
-
-
-def test_C416_pass_1(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            [str(x) for x in range(5)]
-            [x + 1 for x in range(5)]
-            [x for x in range(5) if x % 2]
-            {str(x) for x in range(5)}
-            {x + 1 for x in range(5)}
-            {x for x in range(5) if x % 2}
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C416_pass_2_async_list(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            async def foo():
-                [x async for x in range(5)]
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C416_pass_3_async_set(flake8_path):
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            async def foo():
-                return {x async for x in range(5)}
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C416_pass_4_tuples(flake8_path):
-    (flake8_path / "example.py").write_text("[(x, y, 1) for x, y in []]")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C416_fail_5_unpacking(flake8_path):
-    # We can't assume unpacking came from tuples, so these examples should pass
-    (flake8_path / "example.py").write_text(
-        dedent(
-            """\
-            [(x, y) for x, y in zip('abc', '123')]
-            [(x, y) for (x, y) in zip('abc', '123')]
-            {(x, y) for x, y in zip('abc', '123')}
-            {(x, y) for (x, y) in zip('abc', '123')}
-            """
-        )
-    )
-    result = flake8_path.run_flake8()
-    assert result.out_lines == []
-
-
-def test_C416_fail_1_list(flake8_path):
-    (flake8_path / "example.py").write_text("[x for x in range(5)]")
-    result = flake8_path.run_flake8()
-    # Column offset for list comprehensions was incorrect in Python < 3.8.
-    # See https://bugs.python.org/issue31241 for details.
-    col_offset = 1 if sys.version_info >= (3, 8) else 2
-    assert result.out_lines == [
-        "./example.py:1:%d: C416 Unnecessary list comprehension - rewrite using list()."
-        % col_offset,
-    ]
-
-
-def test_C416_fail_2_set(flake8_path):
-    (flake8_path / "example.py").write_text("{x for x in range(5)}")
-    result = flake8_path.run_flake8()
-    assert result.out_lines == [
-        "./example.py:1:1: C416 Unnecessary set comprehension - rewrite using set().",
-    ]
diff --git a/tox.ini b/tox.ini
deleted file mode 100644
index ad1d7d4..0000000
--- a/tox.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-[tox]
-isolated_build = True
-envlist =
-    py{36,37,38,39,310}
-
-[testenv]
-commands = python -W error::DeprecationWarning -W error::PendingDeprecationWarning -m pytest {posargs}
-deps = -r requirements/{envname}.txt
-setenv =
-    PYTHONDEVMODE=1