[Python-Dev] Arbitrary attributes on funcs and methods
bwarsaw@python.org
bwarsaw@python.org
Tue, 11 Apr 2000 01:08:49 -0400 (EDT)
>>>>> "GvR" == Guido van Rossum <guido@python.org> writes:
GvR> Here I have a question. Should this really change F.a, or
GvR> should it change the method bound to f only? You implement
GvR> the former, but I'm not sure if those semantics are right --
GvR> if I have two instances, f1 and f2, and you change f2.a.spam,
GvR> I'd be surprised if f1.a.spam got changed as well (since f1.a
GvR> and f2.a are *not* the same thing -- they are not shared.
GvR> f1.a.im_func and f2.a.im_func are the same thing, but f1.a
GvR> and f2.a are distinct!
As are f1.a and f1.a! :)
GvR> I would suggest that you only allow setting attributes via
GvR> the class or via a function. (This means that you must still
GvR> implement the pass-through on method objects, but reject it
GvR> if the method is bound to an instance.)
Given that, Python should probably raise a TypeError if an attempt is
made to set an attribute on a bound method object. However, it should
definitely succeed to /get/ an attribute on a bound method object.
I'm not 100% sure that setting bound-method-attributes should be
illegal, but we can be strict about it now and see if it makes sense
to loosen the restriction later.
Here's a candidate for Lib/test/test_methattr.py which should print a
bunch of `1's. I'll post the revised diffs (taking into account GvR's
and GS's suggestions) tomorrow after I've had a night to sleep on it.
-Barry
-------------------- snip snip --------------------
from test_support import verbose
class F:
def a(self):
pass
def b():
pass
# setting attributes on functions
try:
b.blah
except AttributeError:
pass
else:
print 'did not get expected AttributeError'
b.blah = 1
print b.blah == 1
print 'blah' in dir(b)
# setting attributes on unbound methods
try:
F.a.blah
except AttributeError:
pass
else:
print 'did not get expected AttributeError'
F.a.blah = 1
print F.a.blah == 1
print 'blah' in dir(F.a)
# setting attributes on bound methods is illegal
f1 = F()
try:
f1.a.snerp = 1
except TypeError:
pass
else:
print 'did not get expected TypeError'
# but accessing attributes on bound methods is fine
print f1.a.blah
print 'blah' in dir(f1.a)
f2 = F()
print f1.a.blah == f2.a.blah
F.a.wazoo = F
f1.a.wazoo is f2.a.wazoo
# try setting __dict__ illegally
try:
F.a.__dict__ = (1, 2, 3)
except TypeError:
pass
else:
print 'did not get expected TypeError'
F.a.__dict__ = {'one': 111, 'two': 222, 'three': 333}
print f1.a.two == 222
from UserDict import UserDict
d = UserDict({'four': 444, 'five': 555})
F.a.__dict__ = d
try:
f2.a.two
except AttributeError:
pass
else:
print 'did not get expected AttributeError'
print f2.a.four is f1.a.four is F.a.four