Skip to content

Mypy misunderstands class-level namespace (spurious Variable "module.Class.attribute" is not valid as a type)Β #12570

Open
@gwk

Description

@gwk

Consider the following:

from typing import Any

@dataclass
class C:
  dict:object # This attribute name shadows `dict` type, but it should not shadow the name inside of the `class` lexical scope; that's not how python works.
  d:dict # This attribute is annotated as `dict`. The interpreter does not pick up the previous shadowed attribute, but mypy does.

c = C(dict={'a':1}, d={'b':2})
print(c.__annotations__)
assert c.__annotations__['d'] is dict # This proves that mypy is misunderstanding the name `dict`.

mypy 0.942 output:

$ mypy property_name_shadows_type.py
property_name_shadows_type.py:11: error: Variable "property_name_shadows_type.C.dict" is not valid as a type
property_name_shadows_type.py:11: note: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
Found 1 error in 1 file (checked 1 source file)

Ill-advised as this naming may seem, mypy is making a semantic mistake here. The dict:object line should not alter the namespace in which d:dict is evaluated (I hope that's the correct terminology!). I ran across this case when a machine-generated dataclass used a builtin type name for an attribute name.

Some notes:

  • This is not specific to dict; it happens for all builtin type names as well as imported type names.
  • If you change the first declaration to dict:Any, then the problem goes away. This seems indicative of a deeper problem in mypy.
  • Whether or not the class is decorated as dataclass seems irrelevant; it's just here for ease of constructing the example instance.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions