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
On Python 3.10.5+cinder, Cinder commit 1aeff3259dc
Example program:
class Node:
def __init__(self) -> None:
self.wins: int = 0
self.losses: int = 0
self.parent: None | Node = None
def score1(self) -> int:
n = 0
if self.parent is not None:
n += self.parent.wins
if self.parent is not None:
n += self.parent.losses
return n
def score2(self) -> int:
n = 0
if self.parent is not None:
n += self.parent.losses
n += self.parent.wins # type error !?
return n
Expected no type error.
But got a type error inside score2 accessing self.parent.wins:
File "foo.py", line 20
n += self.parent.wins
^
cinderx.compiler.errors.TypedSyntaxError: Optional[__main__.Node]: 'NoneType' object has no attribute 'wins'
If you swap that line and the previous one, the error is on self.parent.losses instead!
The text was updated successfully, but these errors were encountered:
I think this is Static Python reflecting the idea that losses could be a dynamic property which could execute arbitrary code. So once you've accessed it, any guarantees from the narrowing go out the window. That explains the seemingly odd "second access is an error" behavior.
It might be possible for SP to know that this isn't actually the case for an attribute of a given static type, though, since we can see the definition of the type. The trick here is subclassing, though -- it depends what our rules are on subclasses overriding a normal attribute with a dynamic property.
Respecting if x (and not just if x is not None) as eliminating the possibility of None in an optional type should definitely be possible, I think it just hasn't been implemented.
On Python 3.10.5+cinder, Cinder commit
1aeff3259dc
Example program:
Expected no type error.
But got a type error inside
score2
accessingself.parent.wins
:If you swap that line and the previous one, the error is on
self.parent.losses
instead!The text was updated successfully, but these errors were encountered: