[Python-bugs-list] [ python-Bugs-805304 ] super instances don't support item assignment

SourceForge.net noreply at sourceforge.net
Tue Sep 16 00:48:43 EDT 2003


Bugs item #805304, was opened at 2003-09-12 15:10
Message generated for change (Comment added) made by rhettinger
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: 6
Submitted By: Fred L. Drake, Jr. (fdrake)
>Assigned to: Guido van Rossum (gvanrossum)
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: Raymond Hettinger (rhettinger)
Date: 2003-09-15 23: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 18: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 01: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