generic-not-last-base-class (PYI059)
Derived from the flake8-pyi linter.
Fix is sometimes available.
This rule is unstable and in preview. The --preview
flag is required for use.
What it does
Checks for classes inheriting from typing.Generic[]
where Generic[]
is
not the last base class in the bases tuple.
Why is this bad?
If Generic[]
is not the final class in the bases tuple, unexpected
behaviour can occur at runtime (See this CPython issue for an example).
The rule is also applied to stub files, where it won't cause issues at runtime. This is because type checkers may not be able to infer an accurate MRO for the class, which could lead to unexpected or inaccurate results when they analyze your code.
For example:
class LinkedList(Generic[T], Sized):
def push(self, item: T) -> None:
self._items.append(item)
class MyMapping(
Generic[K, V],
Iterable[Tuple[K, V]],
Container[Tuple[K, V]],
):
...
Use instead:
class LinkedList(Sized, Generic[T]):
def push(self, item: T) -> None:
self._items.append(item)
class MyMapping(
Iterable[Tuple[K, V]],
Container[Tuple[K, V]],
Generic[K, V],
):
...
Fix safety
This rule's fix is always unsafe because reordering base classes can change
the behavior of the code by modifying the class's MRO. The fix will also
delete trailing comments after the Generic
base class in multi-line base
class lists, if any are present.
Fix availability
This rule's fix is only available when there are no *args
present in the base class list.