You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
classMyClass:
a_property: int=1defdo_something (
self,
source: Optional['MyClass'] =None
):
is_not_none=sourceisnotNoneifis_not_none:
# My ass even knows that `source` must be a `MyClass` instance here.self.a_property=source.a_property
Expected Behavior
It should pass the test
Actual Behavior
Item "None" of "MyClass | None" has no attribute "a_property" [union-attr]
The only way to avoid this error output is to replace each is_not_none with source is not None. It makes the code silly sometimes, and forces me to revamp the logic just for mypy which is a totally waste of my time.
Your Environment
Mypy version used: 1.15.0
Mypy command-line flags: mypy foo.py
Mypy configuration options from mypy.ini (and other config files): n/a
This feature is formally called "aliased conditional expressions". The first time I saw it implemented was in the TypeScript compiler in 2021. I later implemented it in pyright.
As Jelle said, it's tricky to get this feature right because a static analyzer must prove that there is no statement that can invalidate the condition on any code path between the assignment of the condition variable and its later use for narrowing.
deffunc1(x: int|None):
is_int=xisnotNonefor_inrange(2):
ifis_int: # Safe to narrow x to `int`reveal_type(x) # intdeffunc2(x: int|None):
is_int=xisnotNonefor_inrange(2):
ifis_int: # Not safe to narrow x to `int`reveal_type(x) # int | Nonex=Nonedeffunc3(x: int|None):
is_int=xisnotNonefor_inrange(2):
ifis_int: # Not safe to narrow x to `int`reveal_type(x) # int | Noneis_int=True
Activity
USEONGEE commentedon May 5, 2025
Hello, I want to solve this problem. Can I?
JelleZijlstra commentedon May 5, 2025
PRs are welcome but this is likely a complicated feature to add.
Also this issue is probably a duplicate but I haven't looked.
erictraut commentedon May 5, 2025
I think this is a duplicate of #9229.
This feature is formally called "aliased conditional expressions". The first time I saw it implemented was in the TypeScript compiler in 2021. I later implemented it in pyright.
As Jelle said, it's tricky to get this feature right because a static analyzer must prove that there is no statement that can invalidate the condition on any code path between the assignment of the condition variable and its later use for narrowing.
Consider the following three examples:
is None-check happens in variable assignment #9229USEONGEE commentedon May 5, 2025
Thanks
kaelzhang commentedon May 6, 2025
Thanks