This PEP describes an extension to Python, adding attributedictionaries to functions and methods. This PEP tracks the statusand ownership of this feature. It contains a description of thefeature and outlines changes necessary to support the feature.This PEP summarizes discussions held in mailing list forums, andprovides URLs for further information, where appropriate. The CVSrevision history of this file contains the definitive historicalrecord.
Functions already have a number of attributes, some of which arewritable, e.g.func_doc, a.k.a.func.__doc__.func_dochas the interesting property that there is special syntax infunction (and method) definitions for implicitly setting theattribute. This convenience has been exploited over and over again,overloading docstrings with additional semantics.
For example, John Aycock has written a system where docstrings areused to define parsing rules.[1] Zope’s ZPublisher ORB[2] usesdocstrings to signal publishable methods, i.e. methods that canbe called through the web.
The problem with this approach is that the overloaded semanticsmay conflict with each other. For example, if we wanted to add adoctest unit test to a Zope method that should not be publishablethrough the web.
This proposal adds a new dictionary to function objects, calledfunc_dict (a.k.a.__dict__). This dictionary can be setand get using ordinary attribute set and get syntax.
Methods also gain getter syntax, and they currently access theattribute through the dictionary of the underlying functionobject. It is not possible to set attributes on bound or unboundmethods, except by doing so explicitly on the underlying functionobject. See theFuture Directions discussion below forapproaches in subsequent versions of Python.
A function object’s__dict__ can also be set, but only to adictionary object. Deleting a function’s__dict__, or settingit to anything other than a concrete dictionary object results in aTypeError. If no function attributes have ever been set, thefunction’s__dict__ will be empty.
Here are some examples of what you can do with this feature.
defa():passa.publish=1a.unittest='''...'''ifa.publish:printa()ifhasattr(a,'unittest'):testframework.execute(a.unittest)classC:defa(self):'just a docstring'a.publish=1c=C()ifc.a.publish:publish(c.a())
Paul Prescod enumerated a bunch of other uses on thepython-dev thread.
Here are a number of future directions to consider. Any adoptionof these ideas would require a new PEP, which referenced this one,and would have to be targeted at a Python version subsequent tothe 2.1 release.
Because method attributes were stored in the underlyingfunction, this caused several potentially surprising results:
classC:defa(self):passc1=C()c2=C()c1.a.publish=1# c2.a.publish would now be == 1 also!
Because a change toa boundc1 also caused a change toa bound toc2, setting of attributes on bound methodswas disallowed. However, even allowing setting of attributes onunbound methods has its ambiguities:
classD(C):passclassE(C):passD.a.publish=1# E.a.publish would now be == 1 also!
For this reason, the current PEP disallows setting attributes oneither bound or unbound methods, but does allow for gettingattributes on either – both return the attribute value on theunderlying function object.
A future PEP might propose to implement setting (bound orunbound) method attributes by setting attributes on the instanceor class, using special naming conventions. I.e.:
classC:defa(self):passC.a.publish=1C.__a_publish__==1# truec=C()c.a.publish=2c.__a_publish__==2# trued=C()d.__a_publish__==1# true
Here, a lookup on the instance would look to the instance’sdictionary first, followed by a lookup on the class’sdictionary, and finally a lookup on the function object’sdictionary.
__doc__ is the only function attribute that currently hassyntactic support for conveniently setting. It may beworthwhile to eventually enhance the language for supportingeasy function attribute setting. Here are some syntaxessuggested by PEP reviewers:[3]defa{'publish':1,'unittest':'''...''',}(args):# ...defa(args):"""The usual docstring."""{'publish':1,'unittest':'''...''',# etc.}defa(args)having(publish=1):# see reference [3]pass
The BDFL is currently against any such special syntactic supportfor setting arbitrary function attributes. Any syntax proposalswould have to be outlined in new PEPs.
When this was discussed on the python-dev mailing list in April2000, a number of dissenting opinions were voiced. Forcompleteness, the discussion thread starts onpython-dev.
The dissenting arguments appear to fall under the followingcategories:
Countering some of these arguments is the observation that withvanilla Python 2.0,__doc__ can in fact be set to any type ofobject, so some semblance of writable function attributes arealready feasible. But that approach is yet another corruption of__doc__.
And while it is of course possible to add mappings to classobjects (or in the case of function attributes, to the function’smodule), it is more difficult and less obvious how to extract theattribute values for inspection.
Finally, it may be desirable to add syntactic support, much thesame way that__doc__ syntactic support exists. This can beconsidered separately from the ability to actually set and getfunction attributes.
This PEP has been accepted and the implementation has beenintegrated into Python 2.1.
This document has been placed in the public domain.
Source:https://github.com/python/peps/blob/main/peps/pep-0232.rst
Last modified:2025-02-01 08:59:27 GMT