Terry J. Reedy <tjre...@udel.edu> added the comment:

(While I wrote the following, Lewis Ball posted some of the same conclusions.)

0. I verified the failure with 3.8.5 and current master.

1. I reduced the failing example to a minimum of 7 chars on 2 lines.
(
else)

1a. Deleting '\n' or any letter of 'else' fixes the problem.
1b. Adding 'else' before '(' fixes the problem.
1a is true for the initial 'else' on line 4 of the original example.
1b is true for 'else' on a new line before the first.

2. I tried multiple variations
2a. Matching also fails when typing ')'.
2b. Replacing '()' with '[]' or '{}' makes no difference.

2c. Replacing 'else' with 'elif', 'while', 'def', or 'class' makes no 
difference.  This include the addition for 1b above.  Replacing 'else' with 
'if', 'for', or 'with' fixes the bug.

Bingo!!!  Matching uses idlelib.hyperparser, which uses idlelib.pyparse, which 
has regex _synchre, which finds "what looks like the start of a popular 
statement".  It matches 'elif', etcetera, but not 'if', etcetera.  I noticed 
previously that these 'popular' line beginners were missing and have planned to 
add them.*  But we need to make matched words not disable fence matching.

* Keyword 'with' was likely added to python after this re was last revised.  
Keywords 'if' and 'for' might have been removed when comprehensions were added. 
If so, 'else' should have been removed when conditional expressions were added 
and 'yield' when yield expressions were added.  These latter two are the only 
keywords matched by _synchre that can properly appear in the middle of a 
statement but at the beginning of a continuation line.

2d. In the original and minimal examples, moving the offending 'else' to the 
end of the previous line fixes the problem.  So I believe that 'else' at the 
beginning of the line is seen marking the beginning of the statememt, and 
matching does not look back further.  If 'else' and 'yield' were left in 
_synchre and 'if' and 'for' were added back, the matcher would have to 
determine whether the line is a continuation or not.  (And I believe that not 
having 'if' and 'for' degrades the use of pyparse at least for other uses.)

2e. The minimal failing example works in the shell.  Why are _synchre keywords 
not poisonous here?  Is it just because the current statement is known to begin 
just after the '>>> ' prompt, so that else beginning the second line is somehow 
not seen as beginning a new statement?  We need to check if and how fence 
matching in shell is different other than the presence of the marker where code 
input begins.


Alexey: in msg371076 of #21756 I claimed that there is no issue with typing 
closers or ^0 on the same line just before the closer.  Thank you for reporting 
this counter-example.  I imagine that you are not the first IDLE user to write 
a conditional expression on 2 or more lines with else at the beginning of a 
line.  Such expressions always need a closer.

----------
nosy: +taleinat -Lewis Ball
stage:  -> test needed
versions: +Python 3.10, Python 3.9

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue41388>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to