[Python-ideas] Access to function objects

Eric Snow ericsnowcurrently at gmail.com
Sun Aug 7 09:46:08 CEST 2011

On Sat, Aug 6, 2011 at 11:36 PM, Steven D'Aprano <steve at pearwood.info> wrote:
> Eric Snow wrote:
>> Of the three code blocks, functions are the only ones for whom the
> [grammar police]
> "Whom" is for people. You want "which".
> [/grammar police]
> (I don't normally correct people's grammar, but to me, this error broke the
> flow of the sentence like being hit in the face with a sock with half a
> brick in it.)

I aim to please! <wink>

>> resulting object and the execution of the code block are separate.  So
>> a code object could be executing for the original function or a
>> different one that is sharing the code object.
> Fairly unusual, but I grant it could happen. I've done it myself :)
>> Why not bind the called function-object to the frame locals, rather
>> than the one for which the code object was created, perhaps as
>> "__function__"?
> I'm afraid I can't interpret this (which may be my ignorance rather than
> your fault).

No, the fault is likely mine.  But it seems so clear to me. :)

> The only guess I can make is based on what you say later:
> "One new implicit name in locals().
> so I presume you mean that the function should see a local variable (perhaps
> called "me", or "this"?) that is bound to itself.

One called __function__ (or the like).  A "dunder" name is used to
indicate its special nature and limit conflict with existing code.
The function that was called would be bound to that name at function
execution time.  Keep in mind that I am talking about the frame
locals, not anything stored on the code object nor on the function
object.  Not to overdramatize it, but it would happen at the beginning
of every call of every function.  I don't know what that overhead
would be.

> Presumably if a function wants to use that same name as a local, nothing bad
> will happen, since the local assignment will just override the implicit
> assignment. But what about code that expects to see a nonlocal or global
> with the same name?
> What happens when two functions, sharing the same code object, get called
> from two threads at the same time? Are their locals independent?

I'm afraid I don't know.  I expect that each would get executed in
separate execution frames, and so have separate frame locals.

> For most uses, standard recursion via the name is good enough, it's only a
> few corner cases where self-reflection (as I call it) is needed. And I say
> that as somebody who does want a way for functions to know themselves. I
> don't think that use-case is so important that it should be implicitly added
> to every function, on the off-chance it is needed, rather than explicitly on
> demand.

For me the use case involves determining what function called my
function.  Currently you can tell in which execution frame a function
was called, and thereby which code object, but reliably matching that
to a function is not so simple.  I recognize that my case is likely
not a general one.

>> To finish things off, bind to every new code object
>> the function for which it was created, perhaps as "co_func".  That way
>> you will always know what function object was called and which one the
>> code object came from originally.
> What benefit will this give? Have you ever looked at a code object and said,
> "I need a way of knowing which function this is from?" If so, I'd love to
> know what problem you were trying to solve at the time!

You caught me! :)  I don't already have a use case for this part.  I
had only considered that without this you could not determine where a
code object came from, or if a function had borrowed another's code
object.  This is certainly only useful in the case that one function
is using the code object of another, which we have all agreed is not
that common.  However, with a co_func I felt that all the bases would
be covered.

> Code objects don't always get created as part of a function. They can be
> returned by compile. What should co_func be set to then?

None, since there was no function object created along with the code
object.  Same with generator expressions.

> Finally, if the function has a reference to the code object, and the code
> object has a reference to the function, you have a reference cycle. That's
> not the end of the world now as it used to be, in early Python before the
> garbage collector was added, but still, there better be a really good
> use-case to justify it.
> (Perhaps a weak reference might be more appropriate?)

Good point.

Mostly I am trying to look for an angle that works without a lot of
trouble.  Can't fault me for trying in my own incoherent way. :)


> --
> Steven
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> http://mail.python.org/mailman/listinfo/python-ideas

More information about the Python-ideas mailing list