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

Tim Peters tim.peters at gmail.com
Tue May 1 14:33:05 EDT 2018


[MRAB]
> By "inject" I mean putting a name into a namespace:
>
>     import my_module
>     my_module.foo = 'FOO'
>
> You can't insert a name into a function's body to make a new local variable.

So you do mean at runtime, I think.  Then as before, you can do that
with module and the builtin namespaces now, but all function locals
need to be identifiable at compile time now.  People often get
confused about that when they read that "it's a binding" that makes a
name local to a scope, but it's not "_doing_ a binding" that makes it
local, merely that the name _syntactically_ appears as a target in a
binding construct.  That analysis is entirely done at compile time.

In Python's very early days, all namespaces could be dynamically
altered at any time in any way.  As time went on, more & more
restrictions were placed on runtime alteration of local scopes.  I
don't believe that, in current Python 3, dynamic alteration of local
scopes is supported in any case anymore.  Perhaps the last to go was
runtime alteration of locals via `exec`.  This still works in Python
2:

>>> def f():
...         exec 'i = 1+2'
...         print i
>>> f()
3
>>> i  # showing that it was function-local `i`, not global
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'i' is not defined

`exec` was a statement type in Python 2, so the compiler could
recognize that and generate radically different name-lookup code in a
scope containing an `exec` statement.  But in Python 3, `exec` is just
another builtin function, and the compiler knows nothing about what it
does.  Similar code run in Python 3 has no effect on f's locals.


More information about the Python-ideas mailing list