[ python-Bugs-805304 ] super instances don't support item assignment
SourceForge.net
noreply at sourceforge.net
Sat Mar 20 17:56:51 EST 2004
Bugs item #805304, was opened at 2003-09-12 16:10
Message generated for change (Comment added) made by gvanrossum
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=805304&group_id=5470
Category: Python Interpreter Core
Group: None
Status: Open
Resolution: None
>Priority: 5
Submitted By: Fred L. Drake, Jr. (fdrake)
>Assigned to: Raymond Hettinger (rhettinger)
Summary: super instances don't support item assignment
Initial Comment:
This snippet produces a TypeError in Python 2.2.3, 2.3,
and CVS:
class C(object):
def __setitem__(self, name, value):
print (name, value)
class D(C):
def __setitem__(self, name, value):
super(D, self)[name] = value
d = D()
d['foo'] = 'bar'
Here's the traceback:
Traceback (most recent call last):
File "/home/fdrake/tmp/setitem.py", line 10, in ?
d['foo'] = 'bar'
File "/home/fdrake/tmp/setitem.py", line 7, in
__setitem__
super(D, self)[name] = value
TypeError: object does not support item assignment
The problem appears to be that the item assignment
isn't getting mapped to the __setitem__ of the base
class, so this is probably somewhere deep in
Objects/typeobject.c.
----------------------------------------------------------------------
>Comment By: Guido van Rossum (gvanrossum)
Date: 2004-03-20 17:56
Message:
Logged In: YES
user_id=6380
This should be coded as Raymond originally recommended:
super(D, self).__setitem__(name, value).
Raymond, can you update the docs?
----------------------------------------------------------------------
Comment By: Raymond Hettinger (rhettinger)
Date: 2003-09-16 00:48
Message:
Logged In: YES
user_id=80475
Referring to Guido for pronouncement.
I've been thinking that this one could be left alone and just
document that super objects only do their magic upon
explicit attribute lookup.
Otherwise, fixing it completely involves combing Python for
every place that directly calls functions from the slots table,
and then adding a followup call using attribute lookup if the
slot is empty.
When it comes to functions like repr(obj), I think we want
the super object to identify itself rather than forwarding the
call to the target object's __repr__() method.
The downside of leaving it alone is that it breaks the
symmetry between obj[k] and obj.__getitem__[k].
----------------------------------------------------------------------
Comment By: Raymond Hettinger (rhettinger)
Date: 2003-09-13 19:19
Message:
Logged In: YES
user_id=80475
Okay, let's apply the two-step problem solving approach.
First, declare the problem impossible to solve. Then, propose
a solution ;-)
The attached patch is a proof-of-concept. It teaches
PyObject_SetItem to use an attribute lookup for super
objects whenever a direct table lookup fails.
If the approach is approved, the final version of the patch
should also address PyObject_GetItem and other ways that
the attribute lookup mechanism can be bypassed. Also, the
test for super can be improved by adding PySuper_Check()
to the typeobject.c API.
Of course, there is also the question as to whether fixing this
is a bug or a feature. It does enable a whole set of programs
to run under Py2.3.1 and Py2.2.4 that would not run under
Py2.3.0 and Py2.2.3.
----------------------------------------------------------------------
Comment By: Raymond Hettinger (rhettinger)
Date: 2003-09-13 02:50
Message:
Logged In: YES
user_id=80475
This one is tough.
All of super's magic happens with descriptors upon attribute
lookup. The example above will work fine if the call were
written as: "super(D, self).__setitem__(name)".
However, when written as "super(D, self)[name]", ceval.c
triggers a STORE_SUBSCR opcode which calls
PyObject_SetItem which in turns looks directly at the super
object's type table (and finding nothing). Nowhere in this
process is an attribute lookup called or a descriptor invoked.
The current implementation waits until attribute binding time
to search the bases. Hence, at the time the super object is
created, it doesn't know enough information to fill out its
table about which methods will be available. Consequently,
direct table probes will fail.
To make a general purpose fix would be a mess and involves
changing the semantics of super to do its base search at the
time the super object is created and to fillout its table with
the appropriate methods. Unfortunately, any dynamic
changes to the methods in the base object would *not* get
reflected at lookup.
There may be a reasonable special purpose fix. Fill-out the
entire superobject table with custom methods that trigger an
attribute lookup. For instance, fillout the sq_ass_item slot
with a function that calls self.__setitem__ which will trigger
the attribute search. Even this approach has problems
because the super object has no way of knowing in advance
whether sq_ass_item or mp_ass_subscript is the appropriate
method for the object being referred to (is it a mapping or a
sequence?).
I recommend punting on this one and documenting that
direct syntax manipulation of super objects is not defined
and the super().__special_method__ format be used instead.
Perhaps, all of super's unfilled slots can be filled with a
placeholder method that emits an explanatory error message.
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=105470&aid=805304&group_id=5470
More information about the Python-bugs-list
mailing list