[Python-ideas] PEP 3155 - Qualified name for classes and functions

Antoine Pitrou solipsis at pitrou.net
Sun Oct 30 00:18:01 CEST 2011


I would like to propose the following PEP for discussion and, if
possible, acceptance. I think the proposal shouldn't be too
controversial (I find it quite simple and straightforward myself :-)).

I also have a draft implementation that's quite simple



PEP: 3155
Title: Qualified name for classes and functions
Version: $Revision$
Last-Modified: $Date$
Author: Antoine Pitrou <solipsis at pitrou.net>
Status: Draft
Type: Standards Track
Content-Type: text/x-rst
Created: 2011-10-29
Python-Version: 3.3
Resolution: TBD


Python's introspection facilities have long had poor support for nested
classes.  Given a class object, it is impossible to know whether it was
defined inside another class or at module top-level; and, if the former,
it is also impossible to know in which class it was defined.  While
use of nested classes is often considered poor style, the only reason
for them to have second class introspection support is a lousy pun.

Python 3 adds insult to injury by dropping what was formerly known as
unbound methods.  In Python 2, given the following definition::

    class C:
        def f():

you can then walk up from the ``C.f`` object to its defining class::

    >>> C.f.im_class
    <class '__main__.C'>

This possibility is gone in Python 3::

    >>> C.f.im_class
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'function' object has no attribute 'im_class'
    >>> dir(C.f)
    ['__annotations__', '__call__', '__class__', '__closure__', '__code__',
    '__defaults__', '__delattr__', '__dict__', '__dir__', '__doc__',
    '__eq__', '__format__', '__ge__', '__get__', '__getattribute__',
    '__globals__', '__gt__', '__hash__', '__init__', '__kwdefaults__',
    '__le__', '__lt__', '__module__', '__name__', '__ne__', '__new__',
    '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__',
    '__str__', '__subclasshook__']

This limits again the introspection capabilities available to the user.
It can produce actual issues when porting software to Python 3, for example
Twisted Core where the issue of introspecting method objects came up
several times.  It also limits pickling support [1]_.


This PEP proposes the addition of a ``__qname__`` attribute to functions
and classes.  For top-level functions and classes, the ``__qname__``
attribute is equal to the ``__name__`` attribute.  For nested classed,
methods, and nested functions, the ``__qname__`` attribute contains a
dotted path leading to the object from the module top-level.

The repr() and str() of functions and classes is modified to use ``__qname__``
rather than ``__name__``.

Example with nested classes

>>> class C:
...   def f(): pass
...   class D:
...     def g(): pass
>>> C.__qname__
>>> C.f.__qname__
>>> C.D.__qname__
>>> C.D.g.__qname__

Example with nested functions

>>> def f():
...   def g(): pass
...   return g
>>> f.__qname__
>>> f().__qname__


With nested functions (and classes defined inside functions), the dotted
path will not be walkable programmatically as a function's namespace is not
available from the outside.  It will still be more helpful to the human
reader than the bare ``__name__``.

As the ``__name__`` attribute, the ``__qname__`` attribute is computed
statically and it will not automatically follow rebinding.


.. [1] "pickle should support methods":


This document has been placed in the public domain.

   Local Variables:
   mode: indented-text
   indent-tabs-mode: nil
   sentence-end-double-space: t
   fill-column: 70
   coding: utf-8

More information about the Python-ideas mailing list