Skip to main content

A flake8 plugin for managing type-checking imports & forward references

Project description

Package version Code coverage Test status Supported Python versions Checked with mypy

flake8-type-checking

Lets you know which imports to put in type-checking blocks.

For the imports you've already defined inside type-checking blocks, it can also help you manage forward references using PEP 484 or PEP 563 style references.

Codes

Code Description
TC001 Move import into a type-checking block
TC002 Move third-party import into a type-checking block
TC003 Found multiple type checking blocks
TC004 Move import out of type-checking block. Import is used for more than type hinting.
TC005 Empty type-checking block

Forward reference codes

These code ranges are opt-in. They represent two different ways of solving the same problem, so please only choose one.

TC100 and TC101 manage forward references by taking advantage of postponed evaluation of annotations.

Code Description
TC100 Add 'from __future__ import annotations' import
TC101 Annotation does not need to be a string literal

TC200 and TC201 manage forward references using string literals.

Code Description
TC200 Annotation needs to be made into a string literal
TC201 Annotation does not need to be a string literal

To select one of the ranges, just specify the code in your flake8 config:

[flake8]
max-line-length = 80
max-complexity = 12
...
ignore = E501
select = C,E,F,W,..., TC, TC2  # or TC1
# alternatively:
enable-extensions = TC, TC2  # or TC1

Configuration

The plugin currently only has one setting:

  • type-checking-exempt-modules: Specify a list of modules to ignore TC001/TC002 errors from. Could be useful if you, e.g., want to handle big libraries, but prefer not to handle typing imports.

Rationale

Good type hinting requires a lot of imports, which can increase the risk of import cycles in your project. The recommended way of preventing this problem is to use typing.TYPE_CHECKING blocks to guard these types of imports.

Both TC001 and TC002 help alleviate this problem; the reason there are two codes instead of one, is because the import cycles rarely occur from library/third-party imports, so this artificial split provides a way to filter down the total pool of imports for users that want to guard against import cycles, but don't want to manage every import in their projects this strictly.

Once imports are guarded, they will no longer be evaluated during runtime. The consequence of this is that these imports can no longer be treated as if they were imported outside the block. Instead we need to use forward references.

For Python version >= 3.7, there are actually two ways of solving this issue. You can either make your annotations string literals, or you can use a __futures__ import to enable postponed evaluation of annotations. See this excellent stackoverflow answer for a better explanation of the differences.

Installation

pip install flake8-type-checking

Examples

Bad code

models/a.py

from models.b import B

class A(Model):
    def foo(self, b: B): ...

models/b.py

from models.a import A

class B(Model):
    def bar(self, a: A): ...

Will result in these errors

>> a.py: TC002 Move third-party import 'models.b.B' into a type-checking block
>> b.py: TC002 Move third-party import 'models.a.A' into a type-checking block

and consequently trigger these errors if imports are purely moved into type-checking block, without proper forward reference handling

>> a.py: TC100 Add 'from __future__ import annotations' import
>> b.py: TC100 Add 'from __future__ import annotations' import

or

>> a.py: TC200 Annotation 'B' needs to be made into a string literal
>> b.py: TC200 Annotation 'A' needs to be made into a string literal

Good code

models/a.py

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from models.b import B

class A(Model):
    def foo(self, b: 'B'): ...

models/b.py

# TC1
from __future__ import annotations

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from models.a import A

class B(Model):
    def bar(self, a: A): ...

or

# TC2
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from models.a import A

class B(Model):
    def bar(self, a: 'A'): ...

As a pre-commit hook

You can run this flake8 plugin as a pre-commit hook:

- repo: https://github.com/pycqa/flake8
  rev: 3.9.2
  hooks:
    - id: flake8
      additional_dependencies: [ flake8-type-checking ]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flake8-type-checking-1.1.2.tar.gz (14.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flake8_type_checking-1.1.2-py3-none-any.whl (14.0 kB view details)

Uploaded Python 3

File details

Details for the file flake8-type-checking-1.1.2.tar.gz.

File metadata

  • Download URL: flake8-type-checking-1.1.2.tar.gz
  • Upload date:
  • Size: 14.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.12 CPython/3.9.9 Linux/5.11.0-1022-azure

File hashes

Hashes for flake8-type-checking-1.1.2.tar.gz
Algorithm Hash digest
SHA256 6e16673953daa77dbf0fec12410d368c41d2e42dd790cf2e5cbc99cecbc6adc0
MD5 e763cffe8120da506c7104834088f848
BLAKE2b-256 09317491b7a32ec6e127413ee008af4e500a172dbcd87764bad2f2fb80a4f6a5

See more details on using hashes here.

File details

Details for the file flake8_type_checking-1.1.2-py3-none-any.whl.

File metadata

  • Download URL: flake8_type_checking-1.1.2-py3-none-any.whl
  • Upload date:
  • Size: 14.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.12 CPython/3.9.9 Linux/5.11.0-1022-azure

File hashes

Hashes for flake8_type_checking-1.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 9445d18f0178a0bb07dc7c75a1fccdaaf5859b7200947a190fa5f3b0ffbd564d
MD5 daca5dac9de05a1f49236558cf11c5c3
BLAKE2b-256 936143c02ad9e0834ae8f7085fb44903260e952b3f88d46067b3989066337051

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page