Painful details of variable scope mixed with classes

If a parameter to an outer function is used in a closure, does that basically mark it off as not being available for fast locals? I have something like this:

def maker(p):
  def made(x):
    return p + x
m = maker(1)

Previously, I’d just take all the parameters into maker and set them up as fasts, but it looks like p inside of maker is an enclosed cell variable.

I am pretty sure this is how it goes. I’m just annoyed. My new code even does this, but having to rearrange the furniture on my much older code is going to be fun.

The second goofy I discovered disassembling that was LOAD_CLOSURE, the construction of the closure tuple, and the exotic opcode to MAKE_FUNCTION. I was just kind of building that stuff in the MAKE_FUNCTION opcode implementation. Is there any particular reason to not do that? Can the construction of that closure tuple be more exotic in some way that requires flexibility from code generation?

Like any optimized local in CPython, if a parameter is referenced by an enclosed scope, then it has to be stored in a cell. Accessing the contents of a cell is still fast and efficient, however. CPython uses the inline functions PyCell_GET() and PyCell_SET() to directly access cell->ob_ref.

Instantiating a function requires a code object (__code__) and may also require a tuple of parameter defaults (__defaults__), a dict of keyword-only defaults (__kwdefaults__), a tuple of annotations (__annotations__, converted to a dict), and a tuple cells for a closure (__closure__). The latter is the subset of the current frame’s cell objects that are referenced in the function as well as any of its inner functions, comprehensions, generators, and class bodies. It’s not necessarily all of the cell objects in the current frame.

If you wanted to see the end result of all this discussion, I was doing a lot of work on a branch that got feature-complete-enough for what I needed, squashed, and slapped on to the master of my project here:

https://github.com/rockobonaparte/cloaca/commit/6cdef922a575acfd738b04b828b760173254c3ca

My cell objects aren’t really to-spec but I’m casually dismissing that right now. I have a personal game project consuming all this that I’m busy re-integrating (because I’ve done quite a bit of changes) before I even think about refining any of this any further.

Anyways, thank you for all the help on this. I can keep tweaking on stuff and if I should be paying it forward in some way, let me know and I’ll see what I can do.

1 Like