I've been adding static typechecking to our python project, for example like this:
from typing import List
from something import MyOtherClass
class MyClass:
def __init__(self) -> None:
self.some_var = None # type: List[MyOtherClass]
However, now the linters we use (flake8 and pylint) report for example List
as unused variables, since they are not used in actual code. (pep8 handles it fine, by the way).
So we end up changing the code to this:
from typing import List # noqa # pylint: disable=unused-import
from something import MyOtherClass # noqa # pylint: disable=unused-import
class MyClass:
def __init__(self) -> None:
self.some_var = None # type: List[MyOtherClass]
Is there any better solution to solve this? We don't want to disable all unused import warnings.
Linters are programs that advise about code quality by displaying warnings and errors. They can detect your Python code mistakes, notice invalid code patterns and find elements that do not follow your conventions. Python linters have a number of advantages, such as: Preventing bugs in a project.
Type hints improve IDEs and linters. They make it much easier to statically reason about your code. Type hints help you build and maintain a cleaner architecture. The act of writing type hints forces you to think about the types in your program.
Python will always remain a dynamically typed language. However, PEP 484 introduced type hints, which make it possible to also do static type checking of Python code. Unlike how types work in most other statically typed languages, type hints by themselves don't cause Python to enforce types.
PEP8 is a great starting point for Python. Linters will help you identify problem areas and inconsistencies. You can use linters throughout the development process, even automating them to flag lint-filled code before it gets too far.
Python 3.6 implements PEP 526: Syntax for Variable Annotations, which as the name suggests introduces new syntax for variable annotations, removing the need for type comments.
In the new syntax, your code would be rewritten as:
from typing import List, Optional
from something import MyOtherClass
class MyClass:
def __init__(self) -> None:
self.some_var: Optional[List[MyOtherClass]] = None
... or alternatively:
from typing import List, Optional
from something import MyOtherClass
class MyClass:
some_var: Optional[List[MyOtherClass]]
def __init__(self) -> None:
self.some_var = None
Since List
and MyOtherClass
now appear as actual tokens in the code, rather than comments, linters should have no trouble acknowledging that they are indeed being used.
@Zero Piraeus answer offers the most recent solution to this (i.e use variable annotations, also see: What are variable annotations in Python 3.6?).
Apart from that, you don't even need to import List
when you're using # type:
comments. mypy
doesn't require them to be imported and neither to pyflakes
or pylint
as far as I am aware.
There's no need to import names from typing
unless you require to use their name somewhere that Python actually performs a name look-up (and in comments, this isn't required.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With