Issue 937700: Slicing changes item-attributes of an instance of a UserList (original) (raw)

Hi, Py!

I got a strange effect on Items of an instance of a UserList-inherited class. In some cases, slicing the list changed the attribute of the items.

I can not see the mistake in my code and I think that the interpreter is not correct here.

ciaou flo

The code - included some output to show the effect - is:

from UserList import UserList

#----------------------------------------------------------------------

The items class

#---------------------------------------------------------------------- class Player: def init(self, name): self.xname = name

def __repr__(self):
    return repr(self.__dict__)

#----------------------------------------------------------------------

The lists class

#---------------------------------------------------------------------- class Team(UserList): def init(self, names=None): if names: UserList.init(self, [Player(name) for name in names]) else: UserList.init()

#----------------------------------------------------------------------

The Test

#---------------------------------------------------------------------- if name == 'main':

tnames = ['Huber','Maier','Mueller'] crew = Team(tnames)

print '\nThis is ok' l = [(i,) for i in crew] for i in l: print i

This is ok

({'xname': 'Huber'},)

({'xname': 'Maier'},)

({'xname': 'Mueller'},)

print '\nThis again is ok' l = [(crew[i],) for i in range(len(crew))] for i in l: print i

This again is ok

({'xname': 'Huber'},)

({'xname': 'Maier'},)

({'xname': 'Mueller'},)

print '\n **** This is w r o n g *******' l = [(i,) for i in crew[:3]] for i in l: print i

**** This is w r o n g *******

({'xname': {'xname': 'Huber'}},)

({'xname': {'xname': 'Maier'}},)

({'xname': {'xname': 'Mueller'}},)

crew = UserList([Player(name) for name in tnames])

print '\n**** Oh! This is ok! *******' l = [(i,) for i in crew[:3]] for i in l: print i

**** Oh! This is ok! *******

({'xname': 'Huber'},)

({'xname': 'Maier'},)

({'xname': 'Mueller'},)

Logged In: YES user_id=2772

The slicing operation calls your class's init to construct the new list. If your init performs some operation on the given items and passes it to UserList.init, that's exactly as expected.

Here's a simpler example---each time the list is sliced, X.init increases all the items in the new list by 1: from UserList import UserList

class X(UserList): . . def init(self, l = []): . . . . UserList.init(self, [i+1 for i in l])

x = X([1,2,3]) print x, x[:], x[:][:]

prints [2, 3, 4] [3, 4, 5] [4, 5, 6]