I'm using Django / DRF. I want to write type-checked Python. I also want linting.
Django's model structure involves creating a manager class for every model, and assigning an instance of the manager class to the model's objects
member.
Since I'm using type annotations, the manager class's methods now also includes a reference to the model. This causes flake8 to report an error in one or the other.
Here is an example:
class UserManager:
def create_user(email: str) -> User:
... ^^^^ [flake8] F821: undefined name 'User'
class User:
objects = UserManager()
And if I flip them around, I get:
class User:
objects = UserManager()
^^^^^^^^^^^ [flake8] F821: undefined name 'UserManager'
class UserManager:
def create_user(email: str) -> User:
...
What do people do to write typed, linted Django code?
In Python 3.7, you can fix this by using from __future__ import annotations
, which will allow type annotations that contain forward references. This is preferred to using string annotations (as suggested by another answer) for simpler code refactoring and linting. Using quotes is simply a workaround for older versions of Python that don’t support forward-reference annotations. In Python 4 (if not sooner) this will be the default behavior.