Oops, I see that I should ave written about a special value for p.v, not 
for p.  For example, leo.core.leoNodes.VNode could have an "invalid" flag 
that would be tested for in p.__bool__.  Would that make it more feasible?

OTOH, this is legacy code, so probably your solution of having mypy ignore 
the type mismatch is perfectly fine as you said.

On Wednesday, March 3, 2021 at 1:22:44 PM UTC-5 Edward K. Ream wrote:

> On Wednesday, March 3, 2021 at 10:37:01 AM UTC-6 tbp1...@gmail.com wrote:
>
> Thanks for these comments. They inspired me to dig a little deeper into 
> what is going on.
>
> There could be a special instance of p that plays the role of null, in 
>> that it returns None when tested.  Call it p_none.  mypy would recognize it 
>> as the same type as type(p) so it would be type safe, and p.__bool__ would 
>> return False when tested if p were p_none.  There would only need to be one 
>> p_none instance.
>>
>
> This won't work. Recall that p.moveTo* methods change p in place. They 
> don't return a value, and there is no way in python to alter references to 
> p in the caller.
>
> I'm not sure how many different places in the codebase that p is set to 
>> None.  If it's only a few, changing them all to set p to p_none instead 
>> shouldn't be hard or dangerous. 
>>
>
> There are only two methods, but several other position methods call those 
> two methods, so all told there are about a dozen. In any case, setting p to 
> p_none is simply impossible.
>
> mypy gives 27 errors when I annotate p.v to be Optional["VNode"] . These 
> errors basically all say that p.v.any is invalid if p.v is None. This is 
> perfectly proper on mypy's part. As I said earlier, Leo's scripting api 
> works because all scripts, including Leo's core, are supposed to test p 
> after any of the p.moveTo* methods. In practice, these tests happen 
> naturally. The typical patterns are:
>
> for p in c.all_positions():
>     whatever
>
> or
>
> while p:
>    whatever
>    p.moveToThreadNext()
>
> In the first example, the test happens behind the scenes. In the second 
> example, the test is part of the loop.
>
> One could imagine removing the 27 errors by using guards, but nothing 
> would be gained by doing so.  Suppose the guard fails.  Now what? I'm not 
> going to pollute code with error returns, so the only choice is to raise a 
> Leo-specific exception, say, ScriptingError. But Leo's main loop already 
> catches all exceptions, so there is no real benefit.
>
> Edward
>

-- 
You received this message because you are subscribed to the Google Groups 
"leo-editor" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to leo-editor+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/leo-editor/89723e68-b155-44cd-9574-a2f31d7d199en%40googlegroups.com.

Reply via email to