Skip to content

Invalid type inferred for attribute initialized to None in class body #4416

Description

@JukkaL

The type inferred for attribute x in the fragment below is unexpected (I was using --strict-optional):

classA:
x=Noney=Nonedef__init__(self): # Note: no annotationself.x=1defg(self) ->None:
self.y=1a=A()
reveal_type(a.x) # None <---- unexpectedreveal_type(a.y) # Union[int, None]ifa.xisnotNone:
1+''# No error, because mypy considers this unreachable

Union[None, Any] would be a better inferred type for A.x. It would work around the false negative. This would be consistent with how global variables work:

x=Nonedeff():
globalxx=1reveal_type(x) # Union[Any, None]

When not using strict optional checking, the type of A.x is currently also None. Any would be a better inferred type in that case.

Another alternative would be to require annotations for both x and y, since inferring a useful (non-None) type requires non-local context. This would be my preference if we didn't have existing code to worry about -- this could require a large number of additional annotations for code that currently type checks cleanly. A final option would be to only require an annotation for y and infer Union[None, Any] for x, since x is initialized in an unannotated method.

[Note that use of non-local context (outside current scope) can make fine-grained incremental checking harder to implement.]

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions