This Engineering Notebook post discusses a mypy complaint that probably should never be eliminated. Feel free to ignore, unless you are Félix :-)
Two Position methods,
p.moveToNthChild and p.moveToParent, set p.v = None if there is no such
position. This is a fundamental feature of all of the p.moveTo* methods! All these methods change p in place. They do not return a new position.
Here is p.moveToNthChild:
def moveToNthChild(self, n: int):
p = self
if p.v and len(p.v.children) > n:
p.stack.append((p.v, p._childIndex))
p.v = p.v.children[n]
p._childIndex = n
else:
# mypy rightly doesn't like setting p.v to None.
# Leo's code must use the test `if p:` as appropriate.
p.v = None # type: ignore
return p
As noted in the comment, the only
valid way to test whether any of the p.moveTo methods yields a
valid position is to test `if p:` or `if not p:`. The p.__bool__
special method enforces this convention:
def __bool__(self):
"""
Return True if a position is valid.
The tests 'if p' or 'if not p' are the _only_ correct ways
to test whether a position p is valid.
Tests like 'if p is None' or 'if p is not None' will not
work properly.
"""
return self.v is not None
To repeat, mypy
rightly complains that assigning None to p.v is a type error. Changing the declaration of p.v in p.__init__ from:
self.v: "VNode" = v
to
self.v: Optional["VNode"] = v
creates a cascade of (valid!) mypy complaints. Rather than attempt a
(possibly heroic) fix, I think it best to leave the two `type:
ignore` statements in place, with comments explaining their
significance.
Summary
Setting p.v to None is a real type error. Imo, it would not be helpful to pretend otherwise. Setting p.v to None works only because:
1. p.__bool__ tests p.v.
2. Leonine scripts must test `if p:` or `if not p:` after calling p.moveTo* methods.
There is no way to change this special case now. It affects all Leonine scripts. Any anyway, I would not likely change this coding convention even if I could.
All comments welcome. I would especially like to know how leojs handles this issue.
Edward