diff --git a/docs/source/common_issues.rst b/docs/source/common_issues.rst index fdc603b6d4ba..ba47c90cca7d 100644 --- a/docs/source/common_issues.rst +++ b/docs/source/common_issues.rst @@ -595,6 +595,44 @@ string literal types or :py:data:`~typing.TYPE_CHECKING`: results: 'Queue[int]' = Queue() # OK +If you use a type variable in the type alias that is used as a base class and +implement it in above way, it will give error. Note that type arguments are only +required when using `--disallow-any-generics` (or `--strict`). However, this will +still be a problem even if these options aren't enabled, since we want to make the +subclass generic (otherwise it would be pretty pointless to use a type variable), +and this would result in a runtime error without the suggested trick. + +.. code-block:: python + + from queue import Queue + from typing import TYPE_CHECKING, TypeVar + + _T = TypeVar("_T") + if TYPE_CHECKING: + MyQueueBase = Queue[_T] + else: + MyQueueBase = Queue + + class MyQueue(MyQueueBase): pass # error: Missing type parameters for generic type + +Note here that this error only comes when some configuration options are enabled. +To avoid this problem, we need to create another class in the hierarchy which makes +use of :py:data:`~typing.Generic` when :py:data:`~typing.TYPE_CHECKING` is disabled +and behaves normally when :py:data:`~typing.TYPE_CHECKING` is enabled. + +.. code-block:: python + + from queue import Queue + from typing import TYPE_CHECKING, TypeVar, Generic + + _T = TypeVar("_T") + if TYPE_CHECKING: + class MyQueueBase(Queue[_T]): pass + else: + class MyQueueBase(Generic[_T], Queue): pass + + class MyQueue(MyQueueBase[_T]): pass # OK + If you are running Python 3.7+ you can use ``from __future__ import annotations`` as a (nicer) alternative to string quotes, read more in :pep:`563`. For example: