Skip to content

Commit 792fb72

Browse files
committed
Add common issue docs for PEP585 syntax upgrade
As discussed with @AlexWaygood in #14245 (comment) adding a common issue entry for the problem of hitting overshadowing a built-in keyword when upgrading to PEP585 syntax
1 parent b8c03ab commit 792fb72

File tree

1 file changed

+56
-0
lines changed

1 file changed

+56
-0
lines changed

docs/source/common_issues.rst

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -821,3 +821,59 @@ This is best understood via an example:
821821
To get this code to type check, you could assign ``y = x`` after ``x`` has been
822822
narrowed, and use ``y`` in the inner function, or add an assert in the inner
823823
function.
824+
825+
826+
Upgrading to :pep:`585` syntax
827+
------------------------------
828+
829+
Prior to :pep:`585`, instances of builtin types such as ``dict``, ``list``,
830+
``tuple``, and ``type`` were annotated using aliases
831+
from the :py:mod:`typing` module
832+
(``typing.Dict``, ``typing.List``, ``typing.Tuple``, ``typing.Type`` etc.).
833+
834+
When updating a codebase to use modern syntax, you may hit a case such as the following:
835+
836+
.. code-block:: python
837+
838+
from typing import TypeVar
839+
840+
T = TypeVar("T", bound="Foo")
841+
842+
class Foo:
843+
type: str
844+
845+
# Mypy complains that "Foo.type" is "not valid as a type":
846+
@classmethod
847+
def bar(cls: type[T], value: str) -> None:
848+
pass
849+
850+
This occurs due to the fact that the class has an attribute named ``type``
851+
that shadows the built-in function :py:class:`type`.
852+
To illustrate the issue: at runtime in the following example,
853+
the annotation for ``arg`` in the ``ham`` method
854+
is resolved as being the string ``"spam"``
855+
due to the fact that method signatures are executed
856+
in the same scope as class attributes:
857+
858+
.. code-block:: pycon
859+
860+
>>> class Eggs:
861+
... type: str = "spam"
862+
... def ham(self, arg: type) -> None:
863+
... pass
864+
...
865+
>>> import inspect
866+
>>> inspect.signature(Eggs.ham)
867+
<Signature (self, arg: 'spam') -> None>
868+
869+
Mypy follows the same scoping semantics as Python at runtime
870+
when resolving references.
871+
To get this code to type-check, therefore, you have the following options:
872+
873+
- Continue using ``typing.Type[]`` for your annotation.
874+
- Add ``import builtins`` to the top of your module and use ``builtins.type[]``
875+
for your annotation.
876+
- Add ``from builtins import type as Type`` to the top of your module
877+
and use ``Type[]`` for your annotation
878+
879+
The same thing applies for any other built-in name.

0 commit comments

Comments
 (0)