[Python-ideas] capturing the origin of objects

Eric Snow ericsnowcurrently at gmail.com
Wed Feb 20 06:34:53 CET 2013


With the removal of unbound methods in Python 3, introspecting the
class on which a method was defined is not so simple.  Python 3.3
gives us __qualname__ for classes and functions (see PEP 3155), which
helps somewhat by giving us a string composed at compile-time.
However, I was considering something a little more powerful.

I propose that what would have formerly been an unbound method get a
new attribute, __origin__.  It will be bound to class where the method
is defined.

Motivation
==========

One motivator for this proposal is http://bugs.python.org/issue15582,
allowing inspect.getdoc() to "inherit" docstrings.  Without a concrete
connection between a method and the "origin" class, dynamically
determining the docstring is basically a non-starter.  The __origin__
attribute would help.

Extended Idea
=============

The name, __origin__, is a bit generic to accommodate the possible
extension of the proposal to other objects:

  * f.__origin__ (the module or function (nested) where the function
was defined)
  * cls.__origin__ (the module, class (nested), or function where the
class was defined)
  * code.__origin__ (the function for which the code object was
originally created)
  * module.__origin__ (a.k.a. module.__file__)

For functions and classes defined in a function, __origin__ would be
bound to the function rather than the locals or the code object.  For
modules, __origin__ is more accurate in the cases that the module was
generated from something other than a file.  It would still be a
string, though.  Also, we currently have a convention of setting
__module__ to the name of the module rather than the module itself.
Whether to break with that convention for __origin__ is an open
question which relates to how __origin__ would be used.

Conceivably, each use case for __origin__ could be covered by a name
more specific to the object, e.g. module.__file__.  However, having
the one name would help make the purpose clear and consistent.

Objections
==========

The downside of binding the objects to __origin__ is in memory usage
and, particularly, in ref-counts/reference-cycles.  I expect that this
is where the biggest objections will lie.  However, my understanding
is that this is less of an issue now than it used to be.  If need be,
weakref proxies could address some of the concerns.

The status quo has a gap in the case of "unbound" methods and of code
objects, though __qualname__ does offer an improvement for methods.
The actual use case I have relates strictly to those methods.  Having
something like __origin__ for those methods, at least, would be
helpful.

-eric



More information about the Python-ideas mailing list