Re: [Python-Dev] Tangent on class level scoping rules (was Re: PEP 463: Exception-catching expressions)

2014-02-22 Thread Nick Coghlan
On 22 Feb 2014 09:59, "Greg Ewing"  wrote:
>
> Nick Coghlan wrote:
>>
>> As Chris later noted, you likely *could* still implement expression
>> local name binding for an except expression without a full closure, it
>> would just be rather difficult.
>
>
> I'm still not convinced it would be all *that* difficult.
> Seems to me it would be semantically equivalent to
> renaming the inner variable and adding a finally clause
> to unbind it. Is there something I'm missing?

Dealing with references from nested closures is the hard part. It's not
impossible to solve, but would require introducing a new kind of scope not
previously seen in Python, which is a  rather dubious suggestion when the
existing closure semantics can typically do the job. However, we're getting
off topic for python-dev.

Cheers,
Nick.

>
> --
> Greg
>
> ___
> Python-Dev mailing list
> Python-Dev@python.org
> https://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Tangent on class level scoping rules (was Re: PEP 463: Exception-catching expressions)

2014-02-22 Thread Chris Angelico
On Sat, Feb 22, 2014 at 10:01 PM, Greg Ewing
 wrote:
> Chris Angelico wrote:
>>
>> On Sat, Feb 22, 2014 at 10:57 AM, Greg Ewing
>>  wrote:
>>
>>> I'm still not convinced it would be all *that* difficult.
>>> Seems to me it would be semantically equivalent to
>>> renaming the inner variable and adding a finally clause
>>> to unbind it. Is there something I'm missing?
>>
>>
>> An inner scope should shadow rather than unbinding.
>
>
> It would. The name being unbound would be the renamed
> inner one, not the one being shadowed.

If the whole inner scope is disappearing, then there's no need to
unbind in a finally clause. The current behaviour of try/except is
exactly what you're describing, with no subscope:

Python 3.4.0rc1+ (default:9f76adbac8b7, Feb 15 2014, 20:19:30)
[GCC 4.7.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> e = 2.71828
>>> try: 1/0
... except ZeroDivisionError as e: pass
...
>>> e
Traceback (most recent call last):
  File "", line 1, in 
NameError: name 'e' is not defined

It's been unbound from the parent scope. It's not shadowed, it's
actually overwritten.

ChrisA
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Tangent on class level scoping rules (was Re: PEP 463: Exception-catching expressions)

2014-02-22 Thread Greg Ewing

Chris Angelico wrote:

On Sat, Feb 22, 2014 at 10:57 AM, Greg Ewing
 wrote:


I'm still not convinced it would be all *that* difficult.
Seems to me it would be semantically equivalent to
renaming the inner variable and adding a finally clause
to unbind it. Is there something I'm missing?


An inner scope should shadow rather than unbinding.


It would. The name being unbound would be the renamed
inner one, not the one being shadowed.

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Tangent on class level scoping rules (was Re: PEP 463: Exception-catching expressions)

2014-02-22 Thread Chris Angelico
On Sat, Feb 22, 2014 at 10:57 AM, Greg Ewing
 wrote:
> Nick Coghlan wrote:
>>
>> As Chris later noted, you likely *could* still implement expression
>> local name binding for an except expression without a full closure, it
>> would just be rather difficult.
>
>
> I'm still not convinced it would be all *that* difficult.
> Seems to me it would be semantically equivalent to
> renaming the inner variable and adding a finally clause
> to unbind it. Is there something I'm missing?

An inner scope should shadow rather than unbinding. Ideally:

spam = "Initial spam"
try: 1/0
except Exception as spam:
assert isinstance(spam, Exception)
assert [spam for spam in ["List Comp"]][0] == "List Comp"
with open("test","w") as spam:
assert hasattr(spam,"write")
assert (lambda spam: spam)("Function") == "Function"
assert spam == "Initial spam"

Currently, the list comp and lambda work that way. The exception will
unbind the name, not changing the scope at all but preventing refloop
after exit. The 'with... as' works in the same scope and leaves the
name bound, which is a bit surprising in some cases (you usually end
up with a closed file object, or whatever it be, lurking around).

A clean inner-scope concept would solve all of this. The lambda would
still be a closure, because you can pass that around. All the others
would be inner scopes - shadowing cleanly and then disappearing.

ChrisA
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Tangent on class level scoping rules (was Re: PEP 463: Exception-catching expressions)

2014-02-21 Thread Greg Ewing

Nick Coghlan wrote:

As Chris later noted, you likely *could* still implement expression
local name binding for an except expression without a full closure, it
would just be rather difficult.


I'm still not convinced it would be all *that* difficult.
Seems to me it would be semantically equivalent to
renaming the inner variable and adding a finally clause
to unbind it. Is there something I'm missing?

--
Greg
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Tangent on class level scoping rules (was Re: PEP 463: Exception-catching expressions)

2014-02-21 Thread Eric Snow
On Fri, Feb 21, 2014 at 7:42 AM, Nick Coghlan  wrote:
> It's a relatively arcane scoping rule that only matters if you have
> non-trivial logic at class scope. The vast majority of Python
> programmers will never have to care, because they do the typical thing
> and their class bodies consist almost entirely of function definitions
> and relatively simple assignment statements.

That is definitely an esoteric corner.  It's only really bitten me
when I was doing stuff with nested classes [1] and mined too deeply.
Here's a simple example:

class Spam:
class Ham:
A = None
B = None
class Eggs:
class Bacon(Ham):
 A = 3

If I recall correctly, Larry Hastings ran into something similar a while back.

-eric


[1] The nested classes were used just for easy-to-read namespaces,
effectively hijacking the class definition syntax with no intention of
actually using the class as a type.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] Tangent on class level scoping rules (was Re: PEP 463: Exception-catching expressions)

2014-02-21 Thread Nick Coghlan
Sorry folks, that was meant to go to python-ideas, not python-dev.
I've been so used to the PEP 463 threads being on python-ideas, I
missed that this was the python-dev one :)

Cheers,
Nick.
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


[Python-Dev] Tangent on class level scoping rules (was Re: PEP 463: Exception-catching expressions)

2014-02-21 Thread Nick Coghlan
On 22 February 2014 00:22, Rob Cliffe  wrote:
> Thanks for looking into this Nick.
> I confess I don't entirely understand the technical argument (my
> understanding breaks down at "the subexpressions can't see the class level
> variables", but I don't want to waste anybody's time expecting an
> explanation, I can always look into it myself)

It's a relatively arcane scoping rule that only matters if you have
non-trivial logic at class scope. The vast majority of Python
programmers will never have to care, because they do the typical thing
and their class bodies consist almost entirely of function definitions
and relatively simple assignment statements. However, it's something
that expression level name binding proposals need to take into account
if they want to avoid side effects on the containing scope.

Python's scoping rules are deliberately designed so that methods
*can't* see class attributes directly, they have to access them via
their first argument or the magic __class__ variable (Py3 only for the
latter). For example:

>>> class C:
... attr = "Hello"
... def m(self):
... print(self.attr)
... print(attr)
...
>>> C().m()
Hello
Traceback (most recent call last):
  File "", line 1, in 
  File "", line 5, in m
NameError: global name 'attr' is not defined

The trick that makes it relevant here is that the "hidden" iteration
variable in comprehensions is implemented by creating an implicit
closure and then calling it. From the point of view of the scoping
rules, that implicit closure behaves the same way as any other method
definition, so most of the subexpressions can't see the class
variables. The sole exception is the outermost iterator expression,
because that is evaluated in the containing scope and then passed to
the closure as an argument (this is all based on the way generator
expressions work, and those *have* to be a closure, because they need
to run in their own completely independent frame).

As Chris later noted, you likely *could* still implement expression
local name binding for an except expression without a full closure, it
would just be rather difficult.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com