[Python-ideas] Explicit variable capture list

Victor Stinner victor.stinner at gmail.com
Thu Jan 21 03:48:21 EST 2016


Hi,

Sorry but I'm lost in this long thread. Do you want to extend the
Python language to declare constant in a function? Maybe I'm completly
off-topic, sorry.


2016-01-21 1:10 GMT+01:00 Steven D'Aprano <steve at pearwood.info>:
> (2) If we limit this to only capturing the same name, then we can only
> write (say) "static x", and that does look like a declaration. But maybe
> we want to allow the local name to differ from the global name:
>
>     static x = y

3 months ago, Serhiy Storchaka proposed a "const var = expr" syntax:
https://mail.python.org/pipermail/python-ideas/2015-October/037028.html

With a shortcut "const len" which is like "const len = len".

In the meanwhile, I implemented an optimization in my FAT Python
project: "Copy builtins to constant". It's quite simple: replace the
"LOAD_GLOBAL builtin" instruction with a "LOAD_CONST builtin"
transation and "patch" co_consts constants of a code object at
runtime:

   def hello(): print("hello world")

is replaced with:

   def hello(): "LOAD_GLOBAL print"("hello world")
   hello.__code__ = fat.replace_consts(hello.__code__, {'LOAD_GLOBAL
print': print})

Where fat.replace_consts() is an helper to create a new code object
replacing constants with the specified mapping:
http://fatoptimizer.readthedocs.org/en/latest/fat.html#replace_consts

Replacing print(...) with "LOAD_GLOBAL"(...) is done in the
fatoptimizer (an AST optimpizer):
http://fatoptimizer.readthedocs.org/en/latest/optimizations.html#copy-builtin-functions-to-constants

We have to inject the builtin function at runtime. It cannot be done
when the code object is created by "def ..." because a code object can
only contain objects serializable by marshal (to be able to compile a
.py file to a .pyc file).


> I acknowledge that this goes beyond what the OP asked for, and I think
> that YAGNI is a reasonable response to the static block idea. I'm not
> going to champion it any further unless there's a bunch of interest from
> others. (I'm saving my energy for Eiffel-like require/ensure blocks
> *wink*).

The difference between "def hello(print=print): ..." and Serhiy's
const idea (or my optimization) is that "def hello(print=print): ..."
changes the signature of the function which can be a serious issue in
an API.

Note: The other optimization "local_print = print" in the function is
only useful for loops (when the builtin is loaded multiple times) and
it still loads the builtin once per function call, whereas my
optimization uses a constant and so no lookup is required anymore.

Then guards are used to disable the optimization if builtins are
modified. See the PEP 510 for an explanation on that part.

Victor


More information about the Python-ideas mailing list