470,619 Members | 1,450 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,619 developers. It's quick & easy.

classic and property() version of same attribute - yikes!


I just stumbled upon a bug in some group-written code. We have this sort of
class hierarchy:

class X(object):
...
class A(X):
def __init__(...):
self.attr = 0.0

def GetAttr(self):
return self.attr

def SetAttr(self, a):
self.attr = a
class B(A):
...
class C(B):
def set_attr(self, a):
...

def get_attr(self):
...

attr = property(get_attr, set_attr, None, None)

Each of the four classes is defined in a different module. The author of A
was not aware that it was a new-style class and coded it like a classic
class. The author of C (different person) apparently knew it was new-style
and took advantage of that fact to use property(), but didn't notice there
was already an attribute named "attr" two levels up.

This of course all gets to the Zen bit: "Flat is better than nested", and
I'll use that as an argument for flatter hierarchies in the future.
Nonetheless, what would be the effect of such an attribute stomping? Do I
just have multiple ways to change self.attr, assuming __slots__ hasn't been
declared? This seems like something perhaps pychecker should notice, but
can it?

Thx,

Skip
Jul 18 '05 #1
1 1323
Skip Montanaro <sk**@pobox.com> wrote in message news:<ma*************************************@pyth on.org>...
I just stumbled upon a bug in some group-written code. We have this sort of
class hierarchy:

class X(object):
...
class A(X):
def __init__(...):
self.attr = 0.0

def GetAttr(self):
return self.attr

def SetAttr(self, a):
self.attr = a
class B(A):
...
class C(B):
def set_attr(self, a):
...

def get_attr(self):
...

attr = property(get_attr, set_attr, None, None)

Each of the four classes is defined in a different module. The author of A
was not aware that it was a new-style class and coded it like a classic
class. The author of C (different person) apparently knew it was new-style
and took advantage of that fact to use property(), but didn't notice there
was already an attribute named "attr" two levels up.

This of course all gets to the Zen bit: "Flat is better than nested", and
I'll use that as an argument for flatter hierarchies in the future.
Nonetheless, what would be the effect of such an attribute stomping? Do I
just have multiple ways to change self.attr, assuming __slots__ hasn't been
declared? This seems like something perhaps pychecker should notice, but
can it?

Thx,

Skip


I have run in this kind of troubles when working with Zope. Zope
hierarchies
as the best example of spaghetti-inheritance I have seen till now;
just today I
was looking at the CMF BaseFolder class: it has 33 ancestors (33!)
with definitions scattered in dozen of modules, packages and
subpackages,
and multiple inheritance abused at ridicoulous levels: how in they
hell they believe I can keep track of all the attributes defined in 33
ancestors??

So, I have written a routine to travel the MRO of the any class I
define;
the routine checks that I am not overriding accidentally an already
defined
attribute (which is pretty likely for what I am doing now and has
already bitten me and my coworkers a couple of times). Unfortunately
I cannot use metaclasses, so I can only get the shadowing attribute
warning
after the class creation and not before, and I have to invoke the
checking
function each time I define a new class (i.e. it is not automatic).

But anyway it helps a bit.
Michele Simionato
Jul 18 '05 #2

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

18 posts views Thread by Robin Becker | last post: by
25 posts views Thread by Michal Kwiatkowski | last post: by
5 posts views Thread by Kent.Gallinger | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.