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

overriding __getitem__ seems to have no effect #33

Open
xcsp3team opened this issue Jul 31, 2019 · 1 comment
Open

overriding __getitem__ seems to have no effect #33

xcsp3team opened this issue Jul 31, 2019 · 1 comment

Comments

@xcsp3team
Copy link

xcsp3team commented Jul 31, 2019

Hi,

Thank you for your useful module.

In my case, I would like to override __getitem__, but that does not seems to be working.
I have installed forbiddenfruit 0.1.3 and I run python 3.5.2.

For the following piece of code (test.py):

from forbiddenfruit import *

def my_getitem(self, key):
    print("my_getitem : self ", self)
    print("my_getitem : key ", key)
    return self.__getitem__(key)


curse(list, "__getitem__", my_getitem)

def my_contains(self, other):
    print("my_contains : self ", self)
    print("my_contains : other ", other)
    return self.__contains__(other)

curse(list, "__contains__", my_contains)

l = [1, 2, 3, 4]

print("l:", l)
print(l[0])
print(2 in l)
print(l.__getitem__(2))

I obtain (python3 test.py):

l: [1, 2, 3, 4]
1
my_contains : self  [1, 2, 3, 4]
my_contains : other  2
True
3

So, while __contains__ is well intercepted, this is not the case for __getitem__.
I wonder if this is something that is missing in forbiddenfruit or if this is something related to the language.
Best,
christophe

@Jongy
Copy link
Contributor

Jongy commented Dec 25, 2020

This is related to the language - in many areas of the CPython codebase, "shortcuts" are being made if strict type checks match.

For example, this is the implementation of BINARY_SUBSCR - the opcode implementing x[y] - for CPython v2.7.18. You can clearly see that it has special treatment for lists - objects that match PyList_CheckExact(o), which is equivalent to type(o) is list. COMPARE_OP (in) which implements x in y does not have shortcuts for lists, therefore "it works" for you.

In recent CPython versions I don't see the code in ceval.c implementing the shortcut for subscripting, so it might have been moved somewhere else down the call chain, or removed completely. Generally, while forbiddenfruit allows for it, depending on overriding of basic operators of builtin types is not consistent across CPython versions. AFAIK, these things can change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants