2000-12-12 21:11:58 -05:00
|
|
|
PEP: 232
|
|
|
|
Title: Function Attributes
|
|
|
|
Version: $Revision$
|
2006-03-23 15:13:19 -05:00
|
|
|
Last-Modified: $Date$
|
2016-12-31 20:04:52 -05:00
|
|
|
Author: Barry Warsaw <barry@python.org>
|
2001-03-28 15:24:34 -05:00
|
|
|
Status: Final
|
2000-12-12 21:11:58 -05:00
|
|
|
Type: Standards Track
|
2016-12-31 20:04:52 -05:00
|
|
|
Content-Type: text/x-rst
|
2000-12-12 21:11:58 -05:00
|
|
|
Created: 02-Dec-2000
|
2001-03-28 15:24:34 -05:00
|
|
|
Python-Version: 2.1
|
2001-02-20 15:11:04 -05:00
|
|
|
Post-History: 20-Feb-2001
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
Introduction
|
2016-12-31 20:04:52 -05:00
|
|
|
============
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
This PEP describes an extension to Python, adding attribute
|
|
|
|
dictionaries to functions and methods. This PEP tracks the status
|
|
|
|
and ownership of this feature. It contains a description of the
|
|
|
|
feature and outlines changes necessary to support the feature.
|
|
|
|
This PEP summarizes discussions held in mailing list forums, and
|
|
|
|
provides URLs for further information, where appropriate. The CVS
|
|
|
|
revision history of this file contains the definitive historical
|
|
|
|
record.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
Background
|
2016-12-31 20:04:52 -05:00
|
|
|
==========
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Functions already have a number of attributes, some of which are
|
|
|
|
writable, e.g. ``func_doc``, a.k.a. ``func.__doc__``. ``func_doc``
|
|
|
|
has the interesting property that there is special syntax in
|
|
|
|
function (and method) definitions for implicitly setting the
|
|
|
|
attribute. This convenience has been exploited over and over again,
|
|
|
|
overloading docstrings with additional semantics.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
For example, John Aycock has written a system where docstrings are
|
|
|
|
used to define parsing rules. [1]_ Zope's ZPublisher ORB [2]_ uses
|
|
|
|
docstrings to signal publishable methods, i.e. methods that can
|
|
|
|
be called through the web.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
The problem with this approach is that the overloaded semantics
|
|
|
|
may conflict with each other. For example, if we wanted to add a
|
|
|
|
doctest unit test to a Zope method that should not be publishable
|
|
|
|
through the web.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
Proposal
|
2016-12-31 20:04:52 -05:00
|
|
|
========
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
This proposal adds a new dictionary to function objects, called
|
|
|
|
``func_dict`` (a.k.a. ``__dict__``). This dictionary can be set
|
|
|
|
and get using ordinary attribute set and get syntax.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Methods also gain getter syntax, and they currently access the
|
|
|
|
attribute through the dictionary of the underlying function
|
|
|
|
object. It is not possible to set attributes on bound or unbound
|
|
|
|
methods, except by doing so explicitly on the underlying function
|
|
|
|
object. See the `Future Directions`_ discussion below for
|
|
|
|
approaches in subsequent versions of Python.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
A function object's ``__dict__`` can also be set, but only to a
|
|
|
|
dictionary object. Deleting a function's ``__dict__``, or setting
|
|
|
|
it to anything other than a concrete dictionary object results in a
|
|
|
|
``TypeError``. If no function attributes have ever been set, the
|
|
|
|
function's ``__dict__`` will be empty.
|
2001-01-06 02:03:11 -05:00
|
|
|
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
Examples
|
2016-12-31 20:04:52 -05:00
|
|
|
========
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Here are some examples of what you can do with this feature.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
::
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
def a():
|
|
|
|
pass
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
a.publish = 1
|
|
|
|
a.unittest = '''...'''
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
if a.publish:
|
|
|
|
print a()
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
if hasattr(a, 'unittest'):
|
|
|
|
testframework.execute(a.unittest)
|
|
|
|
|
|
|
|
class C:
|
|
|
|
def a(self):
|
|
|
|
'just a docstring'
|
2001-01-06 02:03:11 -05:00
|
|
|
a.publish = 1
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
c = C()
|
|
|
|
if c.a.publish:
|
|
|
|
publish(c.a())
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
Other Uses
|
2016-12-31 20:04:52 -05:00
|
|
|
----------
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Paul Prescod enumerated a bunch of other uses on the `python-dev thread`_.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2017-06-11 15:02:39 -04:00
|
|
|
.. _python-dev thread: https://mail.python.org/pipermail/python-dev/2000-April/003364.html
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
|
2001-01-15 15:47:14 -05:00
|
|
|
Future Directions
|
2016-12-31 20:04:52 -05:00
|
|
|
=================
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Here are a number of future directions to consider. Any adoption
|
|
|
|
of these ideas would require a new PEP, which referenced this one,
|
|
|
|
and would have to be targeted at a Python version subsequent to
|
|
|
|
the 2.1 release.
|
2001-03-28 15:24:34 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
- A previous version of this PEP allowed for both setter and
|
|
|
|
getter of attributes on unbound methods, and only getter on
|
|
|
|
bound methods. A number of problems were discovered with this
|
|
|
|
policy.
|
2001-02-20 15:11:04 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Because method attributes were stored in the underlying
|
|
|
|
function, this caused several potentially surprising results::
|
2001-02-20 15:11:04 -05:00
|
|
|
|
|
|
|
class C:
|
|
|
|
def a(self): pass
|
|
|
|
|
|
|
|
c1 = C()
|
|
|
|
c2 = C()
|
|
|
|
c1.a.publish = 1
|
|
|
|
# c2.a.publish would now be == 1 also!
|
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Because a change to ``a`` bound ``c1`` also caused a change to
|
|
|
|
``a`` bound to ``c2``, setting of attributes on bound methods
|
|
|
|
was disallowed. However, even allowing setting of attributes on
|
|
|
|
unbound methods has its ambiguities::
|
2001-02-20 15:11:04 -05:00
|
|
|
|
|
|
|
class D(C): pass
|
|
|
|
class E(C): pass
|
|
|
|
|
|
|
|
D.a.publish = 1
|
|
|
|
# E.a.publish would now be == 1 also!
|
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
For this reason, the current PEP disallows setting attributes on
|
|
|
|
either bound or unbound methods, but does allow for getting
|
|
|
|
attributes on either -- both return the attribute value on the
|
|
|
|
underlying function object.
|
2001-02-20 15:11:04 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
A future PEP might propose to implement setting (bound or
|
|
|
|
unbound) method attributes by setting attributes on the instance
|
|
|
|
or class, using special naming conventions. I.e.::
|
2001-02-20 15:11:04 -05:00
|
|
|
|
|
|
|
class C:
|
|
|
|
def a(self): pass
|
|
|
|
|
|
|
|
C.a.publish = 1
|
|
|
|
C.__a_publish__ == 1 # true
|
|
|
|
|
|
|
|
c = C()
|
|
|
|
c.a.publish = 2
|
|
|
|
c.__a_publish__ == 2 # true
|
|
|
|
|
|
|
|
d = C()
|
|
|
|
d.__a_publish__ == 1 # true
|
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Here, a lookup on the instance would look to the instance's
|
|
|
|
dictionary first, followed by a lookup on the class's
|
|
|
|
dictionary, and finally a lookup on the function object's
|
|
|
|
dictionary.
|
2001-02-20 15:11:04 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
- Currently, Python supports function attributes only on Python
|
|
|
|
functions (i.e. those that are written in Python, not those that
|
|
|
|
are built-in). Should it be worthwhile, a separate patch can be
|
|
|
|
crafted that will add function attributes to built-ins.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
- ``__doc__`` is the only function attribute that currently has
|
|
|
|
syntactic support for conveniently setting. It may be
|
|
|
|
worthwhile to eventually enhance the language for supporting
|
|
|
|
easy function attribute setting. Here are some syntaxes
|
2023-08-01 19:02:36 -04:00
|
|
|
suggested by PEP reviewers: [3]_
|
|
|
|
|
|
|
|
.. code:: python
|
2001-01-06 02:03:11 -05:00
|
|
|
|
2001-01-15 15:47:14 -05:00
|
|
|
def a {
|
|
|
|
'publish' : 1,
|
|
|
|
'unittest': '''...''',
|
|
|
|
}
|
|
|
|
(args):
|
|
|
|
# ...
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2001-01-15 15:47:14 -05:00
|
|
|
def a(args):
|
|
|
|
"""The usual docstring."""
|
|
|
|
{'publish' : 1,
|
2000-12-12 21:11:58 -05:00
|
|
|
'unittest': '''...''',
|
2001-01-15 15:47:14 -05:00
|
|
|
# etc.
|
2000-12-12 21:11:58 -05:00
|
|
|
}
|
|
|
|
|
2001-02-26 13:13:05 -05:00
|
|
|
def a(args) having (publish = 1):
|
|
|
|
# see reference [3]
|
|
|
|
pass
|
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
The BDFL is currently against any such special syntactic support
|
|
|
|
for setting arbitrary function attributes. Any syntax proposals
|
|
|
|
would have to be outlined in new PEPs.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
Dissenting Opinion
|
2016-12-31 20:04:52 -05:00
|
|
|
==================
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
When this was discussed on the python-dev mailing list in April
|
|
|
|
2000, a number of dissenting opinions were voiced. For
|
|
|
|
completeness, the discussion thread starts on `python-dev`_.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2017-06-11 15:02:39 -04:00
|
|
|
.. _python-dev: https://mail.python.org/pipermail/python-dev/2000-April/003361.html
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
The dissenting arguments appear to fall under the following
|
|
|
|
categories:
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
- no clear purpose (what does it buy you?)
|
|
|
|
- other ways to do it (e.g. mappings as class attributes)
|
|
|
|
- useless until syntactic support is included
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Countering some of these arguments is the observation that with
|
|
|
|
vanilla Python 2.0, ``__doc__`` can in fact be set to any type of
|
|
|
|
object, so some semblance of writable function attributes are
|
|
|
|
already feasible. But that approach is yet another corruption of
|
|
|
|
``__doc__``.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
And while it is of course possible to add mappings to class
|
|
|
|
objects (or in the case of function attributes, to the function's
|
|
|
|
module), it is more difficult and less obvious how to extract the
|
|
|
|
attribute values for inspection.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
Finally, it may be desirable to add syntactic support, much the
|
|
|
|
same way that ``__doc__`` syntactic support exists. This can be
|
|
|
|
considered separately from the ability to actually set and get
|
|
|
|
function attributes.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
Reference Implementation
|
2016-12-31 20:04:52 -05:00
|
|
|
========================
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
This PEP has been accepted and the implementation has been
|
|
|
|
integrated into Python 2.1.
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
|
|
|
|
References
|
2016-12-31 20:04:52 -05:00
|
|
|
==========
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
.. [1] Aycock, "Compiling Little Languages in Python",
|
2023-08-01 19:02:36 -04:00
|
|
|
https://legacy.python.org/workshops/1998-11/proceedings/papers/aycock-little/aycock-little.html
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2023-08-01 19:02:36 -04:00
|
|
|
.. [2] https://web.archive.org/web/20010307022153/http://classic.zope.org:8080/Documentation/Reference/ORB
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
.. [3] Hudson, Michael, SourceForge patch implementing this syntax,
|
2023-08-01 19:02:36 -04:00
|
|
|
https://web.archive.org/web/20010901050535/http://sourceforge.net/tracker/index.php?func=detail&aid=403441&group_id=5470&atid=305470
|
2001-02-26 13:13:05 -05:00
|
|
|
|
2000-12-12 21:11:58 -05:00
|
|
|
|
|
|
|
Copyright
|
2016-12-31 20:04:52 -05:00
|
|
|
=========
|
2000-12-12 21:11:58 -05:00
|
|
|
|
2016-12-31 20:04:52 -05:00
|
|
|
This document has been placed in the public domain.
|