[Python-bugs-list] [ python-Bugs-478768 ] type attribute hides member of same name

noreply@sourceforge.net noreply@sourceforge.net
Tue, 06 Nov 2001 09:43:57 -0800


Bugs item #478768, was opened at 2001-11-06 08:53
You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=478768&group_id=5470

>Category: Type/class unification
Group: Python 2.2
Status: Open
Resolution: None
Priority: 5
Submitted By: Michael McLay (mclay)
>Assigned to: Tim Peters (tim_one)
Summary: type attribute hides member of same name

Initial Comment:

Allowing type attributes to replace member descriptors
of the same name removes access to all instance data of
the same name throughout the application. The error
generated is not obvious and may not occur near the
source of the error.  A patch to prevent this is attached. 

The use of __slots__ to define attributes allowed in an
instance of a type eliminates the __dict__ in instance.
Instead the names of the instance attributes are
declared in the __slots__ attribute of the class
definition. The names defined in __slots__ become
member descriptor in the type dict. 

This change has useful advantages, but there is one
side effect that makes the use of __slots__ different
from the semantics of the old style dynamic classes. It
is not possible to have a type attribute and an
instance attribute with the same name.  This eliminates
the idiom of using a class attribute as a default and
then overriding the default value by creating an
instance attribute of the same name. This is no longer
possible because the declaration of a type attribute
name will replace the definition of the member name in
the type dict.  Once this occurs it impossible to
access any instances of the attribute of the same name
as a type attribute because the set and get methods for
accessing the data are held in the member descriptor.

The AttributeError raised in the following example
illustrates the problem with using the names declared
in __slots__ when naming a type attribute.  

>>> class B(object):
...   a = 3
...   __slots__ = ['a']
...
>>> b = B()
>>> b.a = 4
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'B' object attribute 'a' is read-only
>>>

The member descriptor 'a' defined in __slots__ is
inaccessible because the type dict has overwritten the
member descriptor with the type attribute of the same
name. A more descriptive error message can be generated
by checking that no __slots__ names are in the type
dict when the __slots__ are being created by type_new(). 

An instance member defined by __slots__ can also be
hidden by a type attribute following the completion of
the definition of the class by making an assignment to
the type with the same name as the instance member. In
the following example the "B.a = "hiding b.a" replaces
the reference to the member descriptor for instance
member 'a' in the type dict.  This eliminates access to
all instance members of that name throughout the
application.

>>> class B(object):
...   __slots__ = ['a']
...
>>> b = B()
>>> b.a = 4
>>> B.a = "hiding b.a"
>>> b.a
'hiding b.a'
>>> b.a = 5
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'B' object attribute 'a' is read-only
>>>




----------------------------------------------------------------------

>Comment By: Tim Peters (tim_one)
Date: 2001-11-06 09:43

Message:
Logged In: YES 
user_id=31435

Changed category, and assigned to me in Guido's absence.

----------------------------------------------------------------------

You can respond by visiting: 
http://sourceforge.net/tracker/?func=detail&atid=105470&aid=478768&group_id=5470