After some internal discussions amongst the Pythonlabbers, we've had to make some updates to PEP 232, Function Attributes. Attached is the complete current PEP draft, also available at http://python.sourceforge.net/peps/pep-0232.html The PEP has been moved back to Draft status, but will be Accepted and Finalized for Python 2.1. It will also be propagated forward for Python 2.2 for the next step in implementation. -Barry -------------------- snip snip -------------------- PEP: 232 Title: Function Attributes Version: $Revision: 1.6 $ Author: barry@digicool.com (Barry A. Warsaw) Status: Draft Type: Standards Track Created: 02-Dec-2000 Python-Version: 2.1 / 2.2 Post-History: 20-Feb-2001 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 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. 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. 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 Future Directions - A previous version of this PEP (and the accompanying implementation) 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. Because method attributes were stored in the underlying function, this caused several potentially surprising results: class C: def a(self): pass c1 = C() c2 = C() c1.a.publish = 1 # c2.a.publish would now be == 1 also! 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: class D(C): pass class E(C): pass D.a.publish = 1 # E.a.publish would now be == 1 also! 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. The proposal for Python 2.2 is to implement setting (bound or unbound) method attributes by setting attributes on the instance or class, using special naming conventions. I.e. 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 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. - 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. - __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. 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 This patch has been applied and will become part of Python 2.1. References [1] Aycock, "Compiling Little Languages in Python", http://www.foretec.com/python/workshops/1998-11/proceedings/papers/aycock-li... [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:
Small pedantry (there's another sort?) I note that:
- __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:
[...elided to save space!...]
It isn't currently clear if special syntax is necessary or desirable.
has not been changed since the last version of the PEP. I suggest that it be updated in two ways: 1. Clarify the final statement - I seem to have the impression (sorry, can't find a message to back it up) that either the BDFL or Tim Peters is very against anything other than the "simple" #f.a = 1# sort of thing - unless I'm mischannelling (?) again. 2. Reference the thread/idea a little while back that ended with #def f(a,b) having (publish=1)# - it's certainly no *worse* than the proposals in the PEP! (Michael Hudson got as far as a patch, I think). Tibs -- Tony J Ibbs (Tibs) http://www.tibsnjoan.co.uk/ then-again-i-confuse-easily<wink>-ly y'rs - tim That's true -- I usually feel confused after reading one of your posts. - Aahz My views! Mine! Mine! (Unless Laser-Scan ask nicely to borrow them.)
Small pedantry (there's another sort?)
I note that:
- __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:
[...elided to save space!...]
It isn't currently clear if special syntax is necessary or desirable.
has not been changed since the last version of the PEP. I suggest that it be updated in two ways:
1. Clarify the final statement - I seem to have the impression (sorry, can't find a message to back it up) that either the BDFL or Tim Peters is very against anything other than the "simple" #f.a = 1# sort of thing - unless I'm mischannelling (?) again.
Agreed.
2. Reference the thread/idea a little while back that ended with #def f(a,b) having (publish=1)# - it's certainly no *worse* than the proposals in the PEP! (Michael Hudson got as far as a patch, I think).
Sure, reference it. It will never be added while I'm in charge though. --Guido van Rossum (home page: http://www.python.org/~guido/)
Guido responded to my points thus:
1. Clarify the final statement - I seem to have the impression (sorry, can't find a message to back it up) that either the BDFL or Tim Peters is very against anything other than the "simple" #f.a = 1# sort of thing - unless I'm mischannelling (?) again.
Agreed.
That's a relief - I obviously had "heard" right!
2. Reference the thread/idea a little while back that ended with #def > f(a,b) having (publish=1)# ...
Sure, reference it. It will never be added while I'm in charge though.
Well, I'd kind of assumed that, given my "memory" of the first point. But of the schemes that won't be adopted, that's the one *I* preferred. (my own sense of "locality" means that I would prefer to be placing function attributes near the declaration of the function, especially given my penchant for long docstrings which move the end of the function off-screen. But then I haven't *used* them yet, and I assume this sort of point has been taken into account. And anyway I definitely prefer your sense of language design to mine). Keep on trying not to get run over by buses, and thanks again for the neat language, Tibs -- Tony J Ibbs (Tibs) http://www.tibsnjoan.co.uk/ "Bounce with the bunny. Strut with the duck. Spin with the chickens now - CLUCK CLUCK CLUCK!" BARNYARD DANCE! by Sandra Boynton My views! Mine! Mine! (Unless Laser-Scan ask nicely to borrow them.)
"TJI" == Tony J Ibbs
writes:
TJI> 1. Clarify the final statement - I seem to have the TJI> impression (sorry, can't find a message to back it up) that TJI> either the BDFL or Tim Peters is very against anything other TJI> than the "simple" #f.a = 1# sort of thing - unless I'm TJI> mischannelling (?) again.
participants (3)
-
barry@digicool.com
-
Guido van Rossum
-
Tony J Ibbs (Tibs)