PEP 3155 - Qualified name for classes and functions
This commit is contained in:
parent
5cc322ca21
commit
f2169e8843
|
@ -0,0 +1,132 @@
|
|||
PEP: 3155
|
||||
Title: Qualified name for classes and functions
|
||||
Version: $Revision$
|
||||
Last-Modified: $Date$
|
||||
Author: Antoine Pitrou <solipsis@pitrou.net>
|
||||
Status: Draft
|
||||
Type: Standards Track
|
||||
Content-Type: text/x-rst
|
||||
Created: 2011-10-29
|
||||
Python-Version: 3.3
|
||||
Post-History:
|
||||
Resolution: TBD
|
||||
|
||||
|
||||
Rationale
|
||||
=========
|
||||
|
||||
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():
|
||||
pass
|
||||
|
||||
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]_.
|
||||
|
||||
|
||||
Proposal
|
||||
========
|
||||
|
||||
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'
|
||||
>>> C.f.__qname__
|
||||
'C.f'
|
||||
>>> C.D.__qname__
|
||||
'C.D'
|
||||
>>> C.D.g.__qname__
|
||||
'C.D.g'
|
||||
|
||||
Example with nested functions
|
||||
-----------------------------
|
||||
|
||||
>>> def f():
|
||||
... def g(): pass
|
||||
... return g
|
||||
...
|
||||
>>> f.__qname__
|
||||
'f'
|
||||
>>> f().__qname__
|
||||
'f.g'
|
||||
|
||||
|
||||
Limitations
|
||||
===========
|
||||
|
||||
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.
|
||||
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
.. [1] "pickle should support methods":
|
||||
http://bugs.python.org/issue9276
|
||||
|
||||
Copyright
|
||||
=========
|
||||
|
||||
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
|
||||
End:
|
Loading…
Reference in New Issue