Open bennn opened 1 month ago
Also, it's strange that the test must be self.parent is not None
. I'd rather write self.parent
by itself.
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.
ah, that makes sense, thanks!
This seems like a related issue: if self.parent
is optional, then I can't call a method on it (after a guard) because SP thinks I'm passing an optional value as the self argument to the method call:
import __static__
from typing import Optional
class Node:
def __init__(self, val: int):
self.parent: Optional[Node] = None
self.val: int = val
def add(self, pp: Node):
self.parent = pp
def getval(self):
return self.val
def pval(self):
if self.parent is not None:
self.parent.getval() # ERROR
# it's fine if I define `pp = self.parent` and do the call on `pp`
def main():
n0: Node = Node(0)
n1: Node = Node(1)
n0.add(n1)
n0.pval()
return
main()
....
raise exception
File "test.py", line 18
self.parent.getval()
cinderx.compiler.errors.TypedSyntaxError: type mismatch: Optional[__main__.Node] received for positional arg 'self', expected __main__.Node
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!