Newline in bash, was Re: IDLE being too clever checking nonlocal declarations?
Steven D'Aprano wrote: > On Mon, 21 Oct 2013 23:26:28 -0400, Terry Reedy wrote: > >> On 10/21/2013 7:52 PM, Steven D'Aprano wrote: >>> On Mon, 21 Oct 2013 15:51:56 -0400, Terry Reedy wrote: >>> On 10/21/2013 11:06 AM, Chris Angelico wrote: > Try typing this into IDLE: > def a(): > def b(): > nonlocal q > SyntaxError: no binding for nonlocal 'q' found If you submit those three lines to Python from the command line, that is what you see. >>> >>> Arguably, that's also too strict, >> >> As I quoted from the doc, it is an error for a program to contain a >> nonlocal with no referent. The reason is one only needs nonlocal to bind >> and unlike with 'global newname', it would be undefined where to do the >> binding. > > Yep, I got that, but what I'm saying is that it is too strict to raise > the exception at the point where it sees "nonlocal q". The CPython > interpreter allows q to be defined inside function a but after function > b, e.g. this is allowed: > > def a(): > def b(): > nonlocal q > q += 1 > q = 2 # <=== > > > If IDLE and the code.py module requires q to be strictly defined before > function b, then it is too strict. Your analysis of the bug as being in > code.py seems plausible. > > > >>> [steve@ando ~]$ python3.3 -c "def a(): def b(): nonlocal q q = 1 " >> >> What system lets you do that? (See other thread about Windows not >> allowing that, because newline terminates the command even after ".) Is >> '>' a line continuation marker (like '...' in Python)? > > Yes, sorry I should have said. That's bash, under Linux. > > Here's another way: > > > steve@runes:~$ python3.3 -c "def a():^M def b():^Mnonlocal q^M > q=1^Mprint(a() is None)" > True > > > Still bash under Linux (a different machine), the ^M is *not* a pair of > characters ^ followed by M but an actually newline, generated by typing > Ctrl-V Enter (that's the ENTER key, not the letters E n t e r). > > In theory I should be able to get something working with \n escapes > instead of ^M, but I can't get it working. But I'm not an expect at bash's > arcane rules for quoting and escaping special characters. I usually just hit Return... $ python3.3 -c "def a(): > def b(): > nonlocal q > q = 1 > print(a() is None)" True but you prompted me to google: $ python3.3 -c $'def a():\n def b():\n nonlocal q\n q = 1\nprint(a() is None)' True -- https://mail.python.org/mailman/listinfo/python-list
Re: IDLE being too clever checking nonlocal declarations?
On Tue, Oct 22, 2013 at 4:57 PM, Steven D'Aprano wrote: > Yep, I got that, but what I'm saying is that it is too strict to raise > the exception at the point where it sees "nonlocal q". The CPython > interpreter allows q to be defined inside function a but after function > b, e.g. this is allowed: > > def a(): > def b(): > nonlocal q > q += 1 > q = 2 # <=== > > > If IDLE and the code.py module requires q to be strictly defined before > function b, then it is too strict. Your analysis of the bug as being in > code.py seems plausible. Yeah. I came across this as I was knocking together a test for something else, and my work-around was to define the inner function as just "pass", and then go back and edit in the nonlocal declaration after adding the assignment outside. The only problem is that it's syntax-checking something that's only half-entered, and is bombing on it - thus stopping you from typing in the bit that would make it valid. Thanks Terry for the extra info on the tracker issue. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: IDLE being too clever checking nonlocal declarations?
On Mon, 21 Oct 2013 23:26:28 -0400, Terry Reedy wrote: > On 10/21/2013 7:52 PM, Steven D'Aprano wrote: >> On Mon, 21 Oct 2013 15:51:56 -0400, Terry Reedy wrote: >> >>> On 10/21/2013 11:06 AM, Chris Angelico wrote: Try typing this into IDLE: >>> def a(): def b(): nonlocal q SyntaxError: no binding for nonlocal 'q' found >>> >>> If you submit those three lines to Python from the command line, that >>> is what you see. >> >> Arguably, that's also too strict, > > As I quoted from the doc, it is an error for a program to contain a > nonlocal with no referent. The reason is one only needs nonlocal to bind > and unlike with 'global newname', it would be undefined where to do the > binding. Yep, I got that, but what I'm saying is that it is too strict to raise the exception at the point where it sees "nonlocal q". The CPython interpreter allows q to be defined inside function a but after function b, e.g. this is allowed: def a(): def b(): nonlocal q q += 1 q = 2 # <=== If IDLE and the code.py module requires q to be strictly defined before function b, then it is too strict. Your analysis of the bug as being in code.py seems plausible. >> [steve@ando ~]$ python3.3 -c "def a(): >>> def b(): >>> nonlocal q >>> q = 1 >>> " > > What system lets you do that? (See other thread about Windows not > allowing that, because newline terminates the command even after ".) Is > '>' a line continuation marker (like '...' in Python)? Yes, sorry I should have said. That's bash, under Linux. Here's another way: steve@runes:~$ python3.3 -c "def a():^M def b():^Mnonlocal q^M q=1^Mprint(a() is None)" True Still bash under Linux (a different machine), the ^M is *not* a pair of characters ^ followed by M but an actually newline, generated by typing Ctrl-V Enter (that's the ENTER key, not the letters E n t e r). In theory I should be able to get something working with \n escapes instead of ^M, but I can't get it working. But I'm not an expect at bash's arcane rules for quoting and escaping special characters. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: IDLE being too clever checking nonlocal declarations?
On 10/21/2013 7:52 PM, Steven D'Aprano wrote: On Mon, 21 Oct 2013 15:51:56 -0400, Terry Reedy wrote: On 10/21/2013 11:06 AM, Chris Angelico wrote: Try typing this into IDLE: def a(): def b(): nonlocal q SyntaxError: no binding for nonlocal 'q' found If you submit those three lines to Python from the command line, that is what you see. Arguably, that's also too strict, As I quoted from the doc, it is an error for a program to contain a nonlocal with no referent. The reason is one only needs nonlocal to bind and unlike with 'global newname', it would be undefined where to do the binding. def a(): def b(): def c(): nonlocal q; q = 1 Where does q go? Replace nonlocal with global and there is no issue. > but these *four* lines work fine interactively: py> def a(): ... def b(): ... nonlocal q ... q = 1 Chris had something like this. and also from the command line: [steve@ando ~]$ python3.3 -c "def a(): def b(): nonlocal q q = 1 " What system lets you do that? (See other thread about Windows not allowing that, because newline terminates the command even after ".) Is '>' a line continuation marker (like '...' in Python)? so it should also work in IDLE. I agree, and implied such on the tracker issue http://bugs.python.org/issue19335 The question is "what does Idle do differently from the C level interpreter". The answer is that is subclasses the Python-coded code.InteractiveInterpreter. Call this II. II.runsource compiles *cumulative* source ultimately with the Python-coded codeop._maybe_compile, which returns a code object (source complete and valid) or None (source incomplete) or raises (source complete but not valid). The bug is seeing the three line input as 'complete but invalid' rather than as 'incomplete' (as the regular interpreter must). To verify that this is not an Idle bug: C:\Programs\Python33>python -m code Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:06:53) [MSC v.1600 64 bit (AMD64)] on win32 Type "help", "copyright", "credits" or "license" for more information. (InteractiveConsole) >>> def a(): ... def b(): ... nonlocal c File "", line None SyntaxError: no binding for nonlocal 'c' found There is a bit more on the tracker. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: IDLE being too clever checking nonlocal declarations?
On Mon, 21 Oct 2013 15:51:56 -0400, Terry Reedy wrote: > On 10/21/2013 11:06 AM, Chris Angelico wrote: >> Try typing this into IDLE: >> > def a(): >> def b(): >> nonlocal q >> SyntaxError: no binding for nonlocal 'q' found > > If you submit those three lines to Python from the command line, that is > what you see. Arguably, that's also too strict, but these *four* lines work fine interactively: py> def a(): ... def b(): ... nonlocal q ... q = 1 ... and also from the command line: [steve@ando ~]$ python3.3 -c "def a(): > def b(): > nonlocal q > q = 1 > " so it should also work in IDLE. -- Steven -- https://mail.python.org/mailman/listinfo/python-list
Re: IDLE being too clever checking nonlocal declarations?
On 10/21/2013 11:06 AM, Chris Angelico wrote: Try typing this into IDLE: def a(): def b(): nonlocal q SyntaxError: no binding for nonlocal 'q' found If you submit those three lines to Python from the command line, that is what you see. In interactive command-line Python, this doesn't throw an error, it works fine if the name is used later: def a(): def b(): nonlocal q q+=1 I verified that interactive Python also syntax checks each line as entered, even for compound statements. Details should be left to the tracker issue you raised. -- Terry Jan Reedy -- https://mail.python.org/mailman/listinfo/python-list
Re: IDLE being too clever checking nonlocal declarations?
On Tue, Oct 22, 2013 at 3:09 AM, Peter Otten <__pete...@web.de> wrote: > Chris Angelico wrote: >> But typing this into IDLE interactive mode requires some fiddling >> around with the editor. Is it trying to be too clever? Am I doing >> something that makes no sense? > > Yes, but you should still file a bug report ;) Heh. I like doing things that make no sense, sometimes :) >> Tested with 3.3.0 on Windows XP. > > Confirmed on Linux for 3.2.2, 3.3.0, and an outdated built of 3.4. It looks > like all versions of Python 3 are affected. Thanks for the confirmation. http://bugs.python.org/issue19335 created. ChrisA -- https://mail.python.org/mailman/listinfo/python-list
Re: IDLE being too clever checking nonlocal declarations?
Chris Angelico wrote: > Try typing this into IDLE: > def a(): > def b(): > nonlocal q > SyntaxError: no binding for nonlocal 'q' found > > > In interactive command-line Python, this doesn't throw an error, and > it works fine if the name is used later: > def a(): > def b(): > nonlocal q > q+=1 > q=1 > b() > return q > a() > 2 > > But typing this into IDLE interactive mode requires some fiddling > around with the editor. Is it trying to be too clever? Am I doing > something that makes no sense? Yes, but you should still file a bug report ;) > Tested with 3.3.0 on Windows XP. Confirmed on Linux for 3.2.2, 3.3.0, and an outdated built of 3.4. It looks like all versions of Python 3 are affected. -- https://mail.python.org/mailman/listinfo/python-list
IDLE being too clever checking nonlocal declarations?
Try typing this into IDLE: >>> def a(): def b(): nonlocal q SyntaxError: no binding for nonlocal 'q' found In interactive command-line Python, this doesn't throw an error, and it works fine if the name is used later: >>> def a(): def b(): nonlocal q q+=1 q=1 b() return q >>> a() 2 But typing this into IDLE interactive mode requires some fiddling around with the editor. Is it trying to be too clever? Am I doing something that makes no sense? Tested with 3.3.0 on Windows XP. ChrisA -- https://mail.python.org/mailman/listinfo/python-list