Author ncoghlan
Recipients Esa.Peuha, Mark.Shannon, Rosuav, ncoghlan, terry.reedy
Date 2013-10-22.12:32:13
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1382445134.29.0.0648935340026.issue19335@psf.upfronthosting.co.za>
In-reply-to
Content
The comment at the top of codeop explains the problem (and why Terry is interested in what the C code is doing, since it's clearly different):

===============
Compile three times: as is, with \n, and with \n\n appended.  If it
compiles as is, it's complete.  If it compiles with one \n appended,
we expect more.  If it doesn't compile either way, we compare the
error we get when compiling with \n or \n\n appended.  If the errors
are the same, the code is broken.  But if the errors are different, we
expect more.  Not intuitive; not even guaranteed to hold in future
releases; but this matches the compiler's behavior from Python 1.4
through 2.2, at least.
===============

Unfortunately, the way the main interactive loop works isn't useful to codeop: the C level loop simply blocks on stdin, waiting until the parser spits out a complete AST. By contrast, codeop is handed complete strings, and has to decide whether they're a potentially incomplete or not.

"nonlocal c" is unique in that it's a name lookup that is *checked by the compiler*, so it triggers the *same* exception in all 3 cases that codeop._maybe_compile tries:

>>> src = "def a():\n   def b():\n    nonlocal c"
>>> compile(src, "", "single")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "", line 3
SyntaxError: no binding for nonlocal 'c' found
>>> compile(src + "\n", "", "single")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "", line 3
SyntaxError: no binding for nonlocal 'c' found
>>> compile(src + "\n\n", "", "single")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "", line 3
SyntaxError: no binding for nonlocal 'c' found

So it's a SyntaxError that *could be fixed* by later code, but that code never gets a chance to run, because codeop assumes that getting the same error in the last two cases means it will never pass.
History
Date User Action Args
2013-10-22 12:32:14ncoghlansetrecipients: + ncoghlan, terry.reedy, Mark.Shannon, Rosuav, Esa.Peuha
2013-10-22 12:32:14ncoghlansetmessageid: <1382445134.29.0.0648935340026.issue19335@psf.upfronthosting.co.za>
2013-10-22 12:32:14ncoghlanlinkissue19335 messages
2013-10-22 12:32:13ncoghlancreate