possibly-undefined false negative for variable annotation
Reported by KotlinIsland in #16609
# mypy: enable-error-code="possibly-undefined"
def foo() -> None:
a: int
print(a)
https://mypy-play.net/?mypy=latest&python=3.12&gist=a044519fd87d51e6028a236f02bcb9cb
I think a distinction between "definition" and "binding" should be made. pyright refers to this as reportUnboundVariable, and this mirrors the runtime exception you would receive:
# pyright / mypy / runtime
def f():
a: int
print(a) # reportUnboundVariable / <nothing> / UnboundLocalError
print(b) # reportUndefinedVariable / name-defined / NameError
I think the discussed problem is not a limitation of possibly-undefined, because If you use --enable-error-code possibly-undefined, mypy generates an error if it cannot verify that a variable will be defined in all execution paths. In the discussed example, a is clearly not defined (or not bound). Such errors should be reported with the name-defined error code (or, eventually, a new name-unbound error code).
Mypy searches for name-defined errors during the semantic analysis step and does the possibly-defined analysis at the end of type checking. The possibly-defined analysis thereby ensures that it does not re-report errors already reported during semantic analysis.
I experimented with extending only the semantic analysis part, but did not open a PR far because I was a little shocked that it caused thousands of tests to fail. But I was only shocked because I had got used to the habit of writing test cases with unbound names:
class C:
x: int
c: C
reveal_type(c.x) # int
So, adding a name-unbound error code (or something similar), as suggested by @KotlinIsland, would be highly practical for this and similar cases, as it would allow turning the new checks off while keeping the old name-defined checks activated.
ais clearly not defined
it's clearly defined as int. perhaps this is an issue with semantics
ais clearly not definedit's clearly defined as
int. perhaps this is an issue with semantics
I agree. I just wanted to say that, if the reported problem is a bug, it is a deficit of name-defined and not of possibly-undefined. If we interpret this issue as a feature request, then we are IMO talking about the two new error codes name-unbound (enabled by default?) and possibly-unbound (optional). And, before experimenting, I was unsure whether adding two new error codes instead of just subsuming definition errors and unbound errors under name-defined (and possibly-defined) is worth it.