A flake8 plugin for managing type-checking imports & forward references
Project description
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. |
Forward reference codes
These code ranges are opt-in. They represent two different ways of solving the same problem, so please only choose one.
TCH100
and TCH101
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 |
TCH200
and TCH201
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 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
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
# TCH1
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://gitlab.com/pycqa/flake8
rev: 3.7.8
hooks:
- id: flake8
additional_dependencies: [ flake8-type-checking ]
Supporting the project
Contributions are always welcome, and leaving a ⭐️ is always useful as it helps raise the profile of the repo 🚀
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file flake8-type-checking-1.0.2.tar.gz
.
File metadata
- Download URL: flake8-type-checking-1.0.2.tar.gz
- Upload date:
- Size: 13.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.5 CPython/3.9.4 Linux/5.4.0-1046-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 8c329d9dc8138e6dda6c737b1dc7101b86d88e15099f665a8d1a03251e87bdeb |
|
MD5 | 0b07e8328b0a29890c3d0b3958c8c324 |
|
BLAKE2b-256 | d4b0ad79dbc1ce94c3bbf3cdca21c72f9064431a7acf53a3f4221e45b5da0344 |
File details
Details for the file flake8_type_checking-1.0.2-py3-none-any.whl
.
File metadata
- Download URL: flake8_type_checking-1.0.2-py3-none-any.whl
- Upload date:
- Size: 12.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.1.5 CPython/3.9.4 Linux/5.4.0-1046-azure
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | a0cd7beb836ddbd536125e2668e604720bf22f4dfb2513ad6e385e337531c662 |
|
MD5 | d3bb7c7755a6b69cd383a169c462724d |
|
BLAKE2b-256 | af853d1ddaedefe9ac23d90a52725d13aeaf181304a37dde984aaeeeaa922cf3 |