"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