Skip to content
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

irregular behavior within class using __setitem__ #42461

Closed
capnstabn mannequin opened this issue Oct 8, 2005 · 6 comments
Closed

irregular behavior within class using __setitem__ #42461

capnstabn mannequin opened this issue Oct 8, 2005 · 6 comments
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs)

Comments

@capnstabn
Copy link
Mannequin

capnstabn mannequin commented Oct 8, 2005

BPO 1317376
Nosy @ncoghlan

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:

assignee = None
closed_at = <Date 2005-10-08.09:44:35.000>
created_at = <Date 2005-10-08.07:27:33.000>
labels = ['interpreter-core', 'invalid']
title = 'irregular behavior within class using __setitem__'
updated_at = <Date 2005-10-08.09:44:35.000>
user = 'https://bugs.python.org/capnstabn'

bugs.python.org fields:

activity = <Date 2005-10-08.09:44:35.000>
actor = 'capnstabn'
assignee = 'none'
closed = True
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2005-10-08.07:27:33.000>
creator = 'capnstabn'
dependencies = []
files = []
hgrepos = []
issue_num = 1317376
keywords = []
message_count = 6.0
messages = ['26536', '26537', '26538', '26539', '26540', '26541']
nosy_count = 2.0
nosy_names = ['ncoghlan', 'capnstabn']
pr_nums = []
priority = 'normal'
resolution = 'not a bug'
stage = None
status = 'closed'
superseder = None
type = None
url = 'https://bugs.python.org/issue1317376'
versions = ['Python 2.3']

@capnstabn
Copy link
Mannequin Author

capnstabn mannequin commented Oct 8, 2005

i found two bugs vaguely similar to this posted but i
think they were different bugs in theory, and both were
deemed 'features' anyway so ... :p

basically the class is a modified list, being used as a
queue

what happens is, when hotswapping the __setitem__
functionality, unless explicitly calling __setitem__, the
old __setitem__ continues to be called

this is very odd and as far as i can tell the behavior is
undocumented

class Queue(list):
def __setitem__(self, a, v):
print "old setitem"
def mysetitem(self, i, v):
print "new setitem"
def use_mysetitem(self):
self.__setitem__ = self.mysetitem

x = Queue()

x[1] = 2

x.__setitem__(2, 3)

x.use_mysetitem()
x[3] = 4

x.__setitem__(4, 5)

@capnstabn capnstabn mannequin closed this as completed Oct 8, 2005
@capnstabn capnstabn mannequin added invalid interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Oct 8, 2005
@capnstabn capnstabn mannequin closed this as completed Oct 8, 2005
@capnstabn capnstabn mannequin added invalid interpreter-core (Objects, Python, Grammar, and Parser dirs) labels Oct 8, 2005
@ncoghlan
Copy link
Contributor

ncoghlan commented Oct 8, 2005

Logged In: YES
user_id=1038590

This problem doesn't exist in Python 2.4:

Py> class Queue(list):
... def __setitem__(self, a, v):
... print "old setitem"
... def mysetitem(self, i, v):
... print "new setitem"
... def use_mysetitem(self):
... self.__setitem__ = self.mysetitem
...
Py> x = Queue()
Py>
Py> x[1] = 2
old setitem
Py>
Py> x.__setitem__(2, 3)
old setitem
Py>
Py> x.use_mysetitem()
Py> x[3] = 4
old setitem
Py>
Py> x.__setitem__(4, 5)
new setitem

@capnstabn
Copy link
Mannequin Author

capnstabn mannequin commented Oct 8, 2005

Logged In: YES
user_id=1126596

err, yeh it does 8)
the last TWO prints should display new setitem

@ncoghlan
Copy link
Contributor

ncoghlan commented Oct 8, 2005

Logged In: YES
user_id=1038590

Ah, sorry. I was looking at the wrong part of the printout.

@ncoghlan
Copy link
Contributor

ncoghlan commented Oct 8, 2005

Logged In: YES
user_id=1038590

And now that I've read the bug report properly, I'm closing
it as "Not a bug" :)

To affect the operators you need to alter the slot on the
*class*, not on the instance, but your "use_mysetitem"
method only affects the current instance - it shadows the
slot in the instance dictionary, but the interpreter is only
interested in the slots in the class itself.

To make the method work, it needs to be a class method:

  def use_mysetitem(cls):
    cls.__setitem__ = cls.mysetitem
  use_mysetitem = classmethod(use_mysetitem)

Of course, it will then affect *all* instances of the class
once the change is made.

You can get per-instance swapping by writing the slot method
in such a way that it delegates to a normal method, which
you can then alter on a per-instance basis. The wisdom of
actually *doing* that is debatable though ;)

@capnstabn
Copy link
Mannequin Author

capnstabn mannequin commented Oct 8, 2005

Logged In: YES
user_id=1126596

omg! you're lucky people on freenode spared you a half hour
of explaining that lol!

and after almost 4 hours of completely going around the world
just to take one step backwards...

[05:38] <squ1g3e> what if i want to change the class within
an instance method
[05:38] <squ1g3e> coz the whole method isnt a class method
[05:38] <TFK> Then you can use self.__class__

haha thanks!

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
interpreter-core (Objects, Python, Grammar, and Parser dirs)
Projects
None yet
Development

No branches or pull requests

1 participant