[Python-ideas] A "local" pseudo-function

Tim Peters tim.peters at gmail.com
Sun Apr 29 23:13:52 EDT 2018


[Tim]
>> ...
>> Worm around that too, then going back to the example at the top, if
>> the manager's
>>
>>         locals().update(_locals)
>>
>> had the intended effect, it would end up restoring `b` to 2 too, yes?
>> The only names that "should be" restored are the names in the `kws`
>> dict.

[David]
> Actually, that wasn't my intention.  As I imagined the semantics, I wanted a
> context manager that restored the "outside" context for anything defined
> "inside" the context.  Allowing keyword arguments was just an extra
> "convenience" that was meant to be equivalent to defining/overwriting
> variables inside the body.  So these would be equivalent:
>
> ## 1
> with sublocal():
>     a = 1
>     b = 2
>     x = a + b
> # a, b now have their old values again

What about x?  I assume that's also restored.

> ## 2
> with sublocal(a=1, b=2):
>     x = a + b
> # a, b now have their old values again
>
> ## 3
> with sublocal(a=1):
>     b = 2
>     x = a + b
> # a, b now have their old values again
>
> I knew I was ignoring nonlocals and nested function scopes.  But just trying
> something really simple that looks like the un-proposal in some cases.
> Maybe there's no way in pure-Python to deal with the edge cases though.

Or even just locals - there doesn't appear to be any supported way in
Python 3 for even `exec` to reliably change locals anymore.

If the intent is to create an "honest-to-Guido new Python scope", then
I expect changing

    BLOCK_OF_CODE

to

    def unique_name():
        BLOCK_OF_CODE
    unique_name()
    del unique_name

gets pretty close?  Any name "created" inside BLOCK_OF_CODE would be
tagged by the compiler as function-local, and vanish when the function
returned.  Anything merely referenced would inherit the enclosing
function's meaning.

I can think of some warts.  E.g., after

    global g

if BLOCK_OF_CODE were

    g += 1

then wrapping that line alone in a function would lead to an
UnboundLocalError when the function was called (because the `global g`
isn't "inherited").

Anyway, since I've never done that in my life, never saw anyone else
do it, and never even thought of it before today, I'm pretty confident
there isn't a hitherto undetected groundswell of demand for a quick
way to create an honest-to-Guido new Python scope ;-)


More information about the Python-ideas mailing list