New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
UserList-subclass Tree slicing changes the original list unexpectedly #83291
Comments
Sorry, it is caused by list(). I will update the issue very soon. |
In the code, each item of ls = [[0], [1], [2],...] has an owner pointing to d, which is a Tree inheriting from collections.UserList. |
Can you give an example? Something simple, showing what you tried, what you expected, and what happened instead. This may help: http://sscce.org/ Your bug.py file doesn't ever use the result of calling list(), so how do you know it changes the value of the parameter? |
Hi, thanks. It did call |
I printed the value of *.owner before and after |
OK, I mean... when I call |
Your problem is with UserList. This is from the implementation: def __getitem__(self, i):
if isinstance(i, slice):
return self.__class__(self.data[i])
else:
return self.data[i] So each slice is creating a new Tree. Then the __setitem__() of that new Tree gets triggered for each item, causing the owner to be set to the new Tree. So that's the cause. Is there a particular reason you are subclassing UserList? Consider subclassing list or collections.abc.MutableSequence instead. Or deal with the slice semantics manually. Also, perhaps you expected that a slice would produce a view into the sequence? I know that's how it works in some programming languages (but not Python, though you could make it do that if you wanted to). Regardless, as far as I can tell everything is working as designed. I recommend closing this. |
(ctarn), if you want to discuss what you are doing further, please try a discussion list, such as python-list. |
Sorry but it is not. See the first time I print ls[4].owner. We get d as expected, not a slice of d, that is, d[0:2]. However the next time we print it after _ = list(d[0:1]), noticed that ls[4] == d[0:1], we get d[0:1], it’s extremely surprising!!! I have to highlight it: we just print *.owner before and after The latest 3 lines show more strange results. By the way, it’s my first time to report bug, and I don’t know what is discussion list, and reopened the issue. Thank you. |
I tried to remove list(), and just use cmd like |
Moreover, it works as expected with Python 3.6 (the owner of each of them is d), and Python 3.8 and Python 3.7 work differently. |
and more... It doesn't happen when Tree directly subclasses list. |
[ctarn]
The change in behaviour is the result of a bug fix that was applied in 3.7 and upwards: see #57378 and bpo-27639. As Eric says, UserList is behaving as intended here. Your problem stems from a design flaw in your code, namely that Nodes have owners. If a node exists both in a Tree and in a slice of that Tree (which slice, since the bpo-27639 fix, is again a Tree), that node can't have both the original Tree and the slice as owner. In this case, what's happening is that accessing
See https://www.python.org/community/lists/, and particularly https://mail.python.org/mailman/listinfo/python-list Closing again here, but feel free to start a discussion or ask questions on the list above. |
GOD... I see. Thank you very much! |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: