This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author terry.reedy
Recipients Alexey Burdin, taleinat, terry.reedy
Date 2020-07-25.02:59:20
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1595645961.3.0.289909592627.issue41388@roundup.psfhosted.org>
In-reply-to
Content
(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.
History
Date User Action Args
2020-07-25 02:59:21terry.reedysetrecipients: + terry.reedy, taleinat, Alexey Burdin
2020-07-25 02:59:21terry.reedysetmessageid: <1595645961.3.0.289909592627.issue41388@roundup.psfhosted.org>
2020-07-25 02:59:21terry.reedylinkissue41388 messages
2020-07-25 02:59:20terry.reedycreate