Hi On 8 Aug 2006 00:10:39 -0700 "Michele Simionato" <[EMAIL PROTECTED]> wrote:
> To me, it seems consistent. As said in > http://www-128.ibm.com/developerworks/linux/library/l-pymeta2/ > > """The availability of metaclass attributes is not transitive; in > other words, the attributes of a metaclass are available to its > instances, but not to the instances of the instances. Just this is the > main difference between metaclasses and superclasses.""" Well... I'm not talking about metaclass attributes... that's perfectly consistent, agreed. I'm saying that when the class implements a custom __getattribute__, when you try to access the instance attributes from itself, it uses it. But if the class is a metaclass, instances of its instances have acess to the attribute anyway, but don't use the custom __getattribute__ you implemented. Like the example I mentioned on the previous mail, or (I think in this case it's more obvious): >>> class N(type): ... def __getattribute__(cls, attr): ... print 'using N.__getattribute for "%s"'%(attr) ... return type.__getattribute__(cls, attr) ... >>> class M(type): ... __metaclass__ = N ... >>> class C(object): ... __metaclass__ = M ... >>> M.x = 'foo' >>> M.x using N.__getattribute for "x" 'foo' >>> C.x 'foo' So, in both cases I have access to the class attribute; but in one case it's using the bound M.__getattribute__ implemented at the base metaclass, but not in the other. It was supposed to use it after the bound 'C.__getattribute__' raises AttributeError as expected, but it doesn't... It's inconsistent, but seems a reasonable decision to me since someone can easily mess with descriptors doing with this... but, someone else involved with Python dev I talked about thinks it may be a bug. And, I'm curious anyway... is it possible to customize attribute access in this case in any other way ? What really happens here ? >From the typeobject.c source code, seems like when the metaclass implements __getattribute__, it uses type.__getattribute__ in this case, but I'm not sure. > Since this happens for real attributes, it looks natural that the same > should happen for 'virtual' attributes implemented via '__getattr__' > or '__getattribute__'. Well... as I think it's clear now, the case you mentioned is not exactly what I'm talking about, but it's good you mentioned about 'virtual' attributes, because in this case we have another problem, it's inconsistent too and there's no reason for it... >>> class M(type): ... def __getattr__(cls, attr): ... if attr == 'x': ... return 'foo' ... >>> class C(object): ... __metaclass__ = M ... >>> C.y = 'bar' >>> C.x 'foo' >>> C.y 'bar' >>> o = C() >>> o.x ... AttributeError: 'C' object has no attribute 'x' >>> o.y 'bar' >>> So... both 'x' and 'y' are class attributes, but 'x' is a virtual attribute implemented with M.__getattr__. From the instance I have access to 'y' but not to 'x'. Regards, -- Pedro Werneck -- http://mail.python.org/mailman/listinfo/python-list