PEP: 232 Title: Function Attributes Version: $Revision$ Author: barry@digicool.com (Barry A. Warsaw) Status: Draft Type: Standards Track Created: 02-Dec-2000 Python-Version: 2.1 Post-History: Introduction 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. Background Functions and methods 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. 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. And Tim Peters has developed a system called doctest[3], where docstrings actually contain unit tests. 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. Proposal 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. Unbound methods also gain set and get attribute syntax, but they modify the dictionary of the underlying function object. When accessed through bound methods, attributes can only be gotten; attempting to set an attribute on a bound method raises TypeError. This is because while function attributes appear to be unique to the bound method, they are really shared by all bound methods, via the underlying function object. A function object's __dict__ can also be set, but only to a dictionary object (i.e. setting __dict__ to UserDict raises a TypeError). Examples Here are some examples of what you can do with this feature. def a(): pass a.publish = 1 a.unittest = '''...''' if a.publish: print a() if hasattr(a, 'unittest'): testframework.execute(a.unittest) class C: def a(self): 'just a docstring' a.publish = 1 c = C() if c.a.publish: publish(c.a()) Other Uses Paul Prescod enumerated a bunch of other uses: http://mail.python.org/pipermail/python-dev/2000-April/003364.html Open Issues 1) Should function attributes be settable or gettable when in restricted execution mode? What about __dict__/func_dict? 2) Should built-in functions have writable attributes? The current patch only supports attributes on user defined (i.e. Python) functions and methods. Adding support to built-in functions isn't difficult -- it would essentially mirror the implementation for user defined functions (i.e. we add a PyObject* to the PyCFunctionObject struct and write getattro and setattro functions to read and write them). 3) __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 suggested by PEP reviewers: def a { 'publish' : 1, 'unittest': '''...''', } (args): # ... def a(args): """The usual docstring.""" {'publish' : 1, 'unittest': '''...''', # etc. } It isn't currently clear if special syntax is necessary or desirable. It would be sufficient to postpone syntactic support for some future PEP. Dissenting Opinion 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 here: http://mail.python.org/pipermail/python-dev/2000-April/003361.html The dissenting arguments appear to fall under the following categories: - 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 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__. 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. 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. Reference Implementation The reference implementation is available on SourceForge as a patch against the Python CVS tree (patch #103123). This patch doesn't include the regrtest module and output file. Those are available upon request. http://sourceforge.net/patch/?func=detailpatch&patch_id=103123&group_id=5470 References [1] Aycock, "Compiling Little Languages in Python", http://www.foretec.com/python/workshops/1998-11/proceedings/papers/aycock-little/aycock-little.html [2] http://classic.zope.org:8080/Documentation/Reference/ORB [3] ftp://ftp.python.org/pub/python/contrib-09-Dec-1999/System/doctest.py Copyright This document has been placed in the Public Domain. Local Variables: mode: indented-text indent-tabs-mode: nil End: