[Python-Dev] Arbitrary attributes on funcs and methods

Guido van Rossum guido@python.org
Mon, 10 Apr 2000 12:02:36 -0400


> A number of people have played FAST and loose with function and method
> docstrings, including John Aycock[1], Zope's ORB[2].  Docstrings are
> handy because they are the one attribute on funcs and methods that are
> easily writable.  But as more people overload the semantics for
> docstrings, we'll get collisions.  I've had a number of discussions
> with folks about adding attribute dictionaries to functions and
> methods so that you can essentially add any attribute.  Namespaces are
> one honking great idea -- let's do more of those!
> 
> Below is a very raw set of patches to add an attribute dictionary to
> funcs and methods.  It's only been minimally tested, but if y'all like
> the idea, I'll clean it up, sanity check the memory management, and
> post the changes to patches@python.org.  Here's some things you can
> do:
> 
> -------------------- snip snip --------------------
> Python 1.6a2 (#10, Apr 10 2000, 11:27:59)  [GCC 2.8.1] on sunos5
> Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam
> >>> def a(): pass
> ... 
> >>> a.publish = 1
> >>> a.publish
> 1
> >>> a.__doc__
> >>> a.__doc__ = 'a doc string'
> >>> a.__doc__
> 'a doc string'
> >>> a.magic_string = a.__doc__
> >>> a.magic_string
> 'a doc string'
> >>> dir(a)
> ['__doc__', '__name__', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name', 'magic_string', 'publish']
> >>> class F:
> ...  def a(self): pass
> ... 
> >>> f = F()
> >>> f.a.publish
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
> AttributeError: publish
> >>> f.a.publish = 1
> >>> f.a.publish
> 1

Here I have a question.  Should this really change F.a, or should it
change the method bound to f only?  You implement the former, but I'm
not sure if those semantics are right -- if I have two instances, f1
and f2, and you change f2.a.spam, I'd be surprised if f1.a.spam got
changed as well (since f1.a and f2.a are *not* the same thing -- they
are not shared.  f1.a.im_func and f2.a.im_func are the same thing, but
f1.a and f2.a are distinct!

I would suggest that you only allow setting attributes via the class
or via a function.  (This means that you must still implement the
pass-through on method objects, but reject it if the method is bound
to an instance.)

--Guido van Rossum (home page: http://www.python.org/~guido/)