Commit c100f5e8 authored by da-woods's avatar da-woods Committed by Stefan Behnel

Remove ".__contains__" -> "PySequence_Contains" slot mappings for known builtin types (GH-4792)

They prevent explicitly calling the base-class __contains__.

Closes https://github.com/cython/cython/issues/4785
parent 4e23f3e4
...@@ -271,12 +271,10 @@ builtin_types_table = [ ...@@ -271,12 +271,10 @@ builtin_types_table = [
]), ]),
("bytearray", "PyByteArray_Type", [ ("bytearray", "PyByteArray_Type", [
]), ]),
("bytes", "PyBytes_Type", [BuiltinMethod("__contains__", "TO", "b", "PySequence_Contains"), ("bytes", "PyBytes_Type", [BuiltinMethod("join", "TO", "O", "__Pyx_PyBytes_Join",
BuiltinMethod("join", "TO", "O", "__Pyx_PyBytes_Join",
utility_code=UtilityCode.load("StringJoin", "StringTools.c")), utility_code=UtilityCode.load("StringJoin", "StringTools.c")),
]), ]),
("str", "PyString_Type", [BuiltinMethod("__contains__", "TO", "b", "PySequence_Contains"), ("str", "PyString_Type", [BuiltinMethod("join", "TO", "O", "__Pyx_PyString_Join",
BuiltinMethod("join", "TO", "O", "__Pyx_PyString_Join",
builtin_return_type='basestring', builtin_return_type='basestring',
utility_code=UtilityCode.load("StringJoin", "StringTools.c")), utility_code=UtilityCode.load("StringJoin", "StringTools.c")),
]), ]),
...@@ -284,11 +282,9 @@ builtin_types_table = [ ...@@ -284,11 +282,9 @@ builtin_types_table = [
BuiltinMethod("join", "TO", "T", "PyUnicode_Join"), BuiltinMethod("join", "TO", "T", "PyUnicode_Join"),
]), ]),
("tuple", "PyTuple_Type", [BuiltinMethod("__contains__", "TO", "b", "PySequence_Contains"), ("tuple", "PyTuple_Type", []),
]),
("list", "PyList_Type", [BuiltinMethod("__contains__", "TO", "b", "PySequence_Contains"), ("list", "PyList_Type", [BuiltinMethod("insert", "TzO", "r", "PyList_Insert"),
BuiltinMethod("insert", "TzO", "r", "PyList_Insert"),
BuiltinMethod("reverse", "T", "r", "PyList_Reverse"), BuiltinMethod("reverse", "T", "r", "PyList_Reverse"),
BuiltinMethod("append", "TO", "r", "__Pyx_PyList_Append", BuiltinMethod("append", "TO", "r", "__Pyx_PyList_Append",
utility_code=UtilityCode.load("ListAppend", "Optimize.c")), utility_code=UtilityCode.load("ListAppend", "Optimize.c")),
...@@ -326,8 +322,7 @@ builtin_types_table = [ ...@@ -326,8 +322,7 @@ builtin_types_table = [
]), ]),
# ("file", "PyFile_Type", []), # not in Py3 # ("file", "PyFile_Type", []), # not in Py3
("set", "PySet_Type", [BuiltinMethod("__contains__", "TO", "b", "PySequence_Contains"), ("set", "PySet_Type", [BuiltinMethod("clear", "T", "r", "PySet_Clear"),
BuiltinMethod("clear", "T", "r", "PySet_Clear"),
# discard() and remove() have a special treatment for unhashable values # discard() and remove() have a special treatment for unhashable values
BuiltinMethod("discard", "TO", "r", "__Pyx_PySet_Discard", BuiltinMethod("discard", "TO", "r", "__Pyx_PySet_Discard",
utility_code=UtilityCode.load("py_set_discard", "Optimize.c")), utility_code=UtilityCode.load("py_set_discard", "Optimize.c")),
......
...@@ -4,7 +4,21 @@ ...@@ -4,7 +4,21 @@
cimport cython cimport cython
# The "contains" tests relate to GH-4785 - replacing the method
# call with PySequence_Contains was causing infinite recursion
# for some classes
cdef class MyList(list): cdef class MyList(list):
"""
>>> l = MyList()
>>> l.__contains__(1)
MyList.__contains__
False
>>> l.append(1)
>>> l.__contains__(1)
MyList.__contains__
True
"""
def test_append(self, x): def test_append(self, x):
""" """
>>> l = MyList() >>> l = MyList()
...@@ -18,7 +32,13 @@ cdef class MyList(list): ...@@ -18,7 +32,13 @@ cdef class MyList(list):
""" """
self.append(x) self.append(x)
def __contains__(self, value):
print "MyList.__contains__"
return list.__contains__(self, value) # probably optimized
cdef class MyDict(dict): cdef class MyDict(dict):
# tests for __contains__ are in the global __doc__ to version-check a PyPy bug
@cython.test_assert_path_exists("//ComprehensionNode//AttributeNode", @cython.test_assert_path_exists("//ComprehensionNode//AttributeNode",
"//ComprehensionNode//AttributeNode[@attribute='items']") "//ComprehensionNode//AttributeNode[@attribute='items']")
@cython.test_fail_if_path_exists("//ComprehensionNode//CMethodSelfCloneNode") @cython.test_fail_if_path_exists("//ComprehensionNode//CMethodSelfCloneNode")
...@@ -40,6 +60,19 @@ cdef class MyDict(dict): ...@@ -40,6 +60,19 @@ cdef class MyDict(dict):
l.sort() l.sort()
return l return l
def __contains__(self, key):
print "MyDict.__contains__"
return dict.__contains__(self, key)
import sys
pypy_version = getattr(sys, 'pypy_version_info', None)
if not (pypy_version and pypy_version < (7, 3, 10)):
__doc__ = """
>>> MyDict(a=1).__contains__("a")
MyDict.__contains__
True
"""
@cython.final @cython.final
cdef class MyDictFinal(dict): cdef class MyDictFinal(dict):
@cython.test_assert_path_exists("//ComprehensionNode//CMethodSelfCloneNode") @cython.test_assert_path_exists("//ComprehensionNode//CMethodSelfCloneNode")
...@@ -155,3 +188,17 @@ cdef class MyDictOverride2(MyDict): ...@@ -155,3 +188,17 @@ cdef class MyDictOverride2(MyDict):
l = [ v for v in self.values() ] l = [ v for v in self.values() ]
l.sort() l.sort()
return l return l
class MyBytes(bytes):
"""
>>> mb = MyBytes(b"abc")
>>> mb.__contains__(b"a")
MyBytes.__contains__
True
>>> mb.__contains__(b"z")
MyBytes.__contains__
False
"""
def __contains__(self, value):
print "MyBytes.__contains__"
return bytes.__contains__(self, value)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment