Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #57200 > unrolled thread

Re: IDLE being too clever checking nonlocal declarations?

Started byTerry Reedy <tjreedy@udel.edu>
First post2013-10-21 15:51 -0400
Last post2013-10-22 09:20 +0200
Articles 6 — 5 participants

Back to article view | Back to comp.lang.python

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: IDLE being too clever checking nonlocal declarations? Terry Reedy <tjreedy@udel.edu> - 2013-10-21 15:51 -0400
    Re: IDLE being too clever checking nonlocal declarations? Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2013-10-21 23:52 +0000
      Re: IDLE being too clever checking nonlocal declarations? Terry Reedy <tjreedy@udel.edu> - 2013-10-21 23:26 -0400
        Re: IDLE being too clever checking nonlocal declarations? Steven D'Aprano <steve@pearwood.info> - 2013-10-22 05:57 +0000
          Re: IDLE being too clever checking nonlocal declarations? Chris Angelico <rosuav@gmail.com> - 2013-10-22 17:24 +1100
          Newline in bash, was Re: IDLE being too clever checking nonlocal declarations? Peter Otten <__peter__@web.de> - 2013-10-22 09:20 +0200

#57200 — Re: IDLE being too clever checking nonlocal declarations?

FromTerry Reedy <tjreedy@udel.edu>
Date2013-10-21 15:51 -0400
SubjectRe: IDLE being too clever checking nonlocal declarations?
Message-ID<mailman.1316.1382385139.18130.python-list@python.org>
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

[toc] | [next] | [standalone]


#57218

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2013-10-21 23:52 +0000
Message-ID<5265be56$0$29981$c3e8da3$5496439d@news.astraweb.com>
In reply to#57200
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

[toc] | [prev] | [next] | [standalone]


#57226

FromTerry Reedy <tjreedy@udel.edu>
Date2013-10-21 23:26 -0400
Message-ID<mailman.1332.1382412405.18130.python-list@python.org>
In reply to#57218
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 "<string>", line None
SyntaxError: no binding for nonlocal 'c' found

There is a bit more on the tracker.

-- 
Terry Jan Reedy

[toc] | [prev] | [next] | [standalone]


#57237

FromSteven D'Aprano <steve@pearwood.info>
Date2013-10-22 05:57 +0000
Message-ID<526613ae$0$30000$c3e8da3$5496439d@news.astraweb.com>
In reply to#57226
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():^M    nonlocal 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

[toc] | [prev] | [next] | [standalone]


#57239

FromChris Angelico <rosuav@gmail.com>
Date2013-10-22 17:24 +1100
Message-ID<mailman.1338.1382423051.18130.python-list@python.org>
In reply to#57237
On Tue, Oct 22, 2013 at 4:57 PM, Steven D'Aprano <steve@pearwood.info> 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

[toc] | [prev] | [next] | [standalone]


#57241 — Newline in bash, was Re: IDLE being too clever checking nonlocal declarations?

FromPeter Otten <__peter__@web.de>
Date2013-10-22 09:20 +0200
SubjectNewline in bash, was Re: IDLE being too clever checking nonlocal declarations?
Message-ID<mailman.1340.1382426425.18130.python-list@python.org>
In reply to#57237
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():^M    nonlocal 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

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web