Python -builtin __contains__ fix for map and set like containers.
Fix when using -builtin and wrapping std::map, std::set, std::unordered_map or std::unordered_set to ensure __contains__ is called. This is a wrapper for the STL container's find method. Without it, Python will do its own slower sequence search.
This commit is contained in:
parent
333209595d
commit
4715a4e72c
8 changed files with 76 additions and 2 deletions
|
|
@ -7,6 +7,11 @@ the issue number to the end of the URL: https://github.com/swig/swig/issues/
|
||||||
Version 4.0.0 (in progress)
|
Version 4.0.0 (in progress)
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
|
2018-09-21: wsfulton
|
||||||
|
[Python] Fix when using -builtin and wrapping std::map, std::set, std::unordered_map or
|
||||||
|
std::unordered_set to ensure __contains__ is called. This is a wrapper for the STL
|
||||||
|
container's find method. Without it, Python will do its own slower sequence search.
|
||||||
|
|
||||||
2018-09-19: wsfulton
|
2018-09-19: wsfulton
|
||||||
[Python] Fix functors (wrapped as __call__) when using -builtin -modern -fastunpack.
|
[Python] Fix functors (wrapped as __call__) when using -builtin -modern -fastunpack.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,15 @@ for k in map:
|
||||||
if map[k] != imap[k]:
|
if map[k] != imap[k]:
|
||||||
raise RuntimeError, "bad map"
|
raise RuntimeError, "bad map"
|
||||||
|
|
||||||
|
# Test __contains__ (required for 'x in y' to work)
|
||||||
|
if not imap.__contains__('hello'):
|
||||||
|
raise RuntimeError("hello imap.__contains__")
|
||||||
|
if 'hello' not in imap:
|
||||||
|
raise RuntimeError("hello not in imap")
|
||||||
|
if imap.__contains__('oops'):
|
||||||
|
raise RuntimeError("oops imap.__contains__")
|
||||||
|
if 'oops' in imap:
|
||||||
|
raise RuntimeError("oops in imap")
|
||||||
|
|
||||||
mapc = {}
|
mapc = {}
|
||||||
c1 = std_containers.C()
|
c1 = std_containers.C()
|
||||||
|
|
@ -114,3 +123,14 @@ for i in s:
|
||||||
if i != j:
|
if i != j:
|
||||||
raise RuntimeError
|
raise RuntimeError
|
||||||
j = j + 1
|
j = j + 1
|
||||||
|
|
||||||
|
# Test __contains__ (required for 'x in y' to work)
|
||||||
|
if not s.__contains__(3):
|
||||||
|
raise RuntimeError("3 s.__contains__")
|
||||||
|
if 3 not in s:
|
||||||
|
raise RuntimeError("3 not in s")
|
||||||
|
if s.__contains__(-1):
|
||||||
|
raise RuntimeError("-1 s.__contains__")
|
||||||
|
if -1 in s:
|
||||||
|
raise RuntimeError("-1 in s")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -635,6 +635,42 @@ SwigPyBuiltin_ssizeobjargproc_closure(SwigPyWrapperFunction wrapper, PyObject *a
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SWIGPY_OBJOBJPROC_CLOSURE(wrapper) \
|
||||||
|
SWIGINTERN int \
|
||||||
|
wrapper##_objobjproc_closure(PyObject *a, PyObject *b) { \
|
||||||
|
return SwigPyBuiltin_objobjproc_closure(wrapper, a, b); \
|
||||||
|
}
|
||||||
|
SWIGINTERN int
|
||||||
|
SwigPyBuiltin_objobjproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) {
|
||||||
|
int result;
|
||||||
|
PyObject *pyresult;
|
||||||
|
PyObject *tuple;
|
||||||
|
tuple = PyTuple_New(1);
|
||||||
|
assert(tuple);
|
||||||
|
PyTuple_SET_ITEM(tuple, 0, b);
|
||||||
|
Py_XINCREF(b);
|
||||||
|
pyresult = wrapper(a, tuple);
|
||||||
|
result = pyresult ? (PyObject_IsTrue(pyresult) ? 1 : 0) : -1;
|
||||||
|
Py_XDECREF(pyresult);
|
||||||
|
Py_DECREF(tuple);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SWIGPY_FUNPACK_OBJOBJPROC_CLOSURE(wrapper) \
|
||||||
|
SWIGINTERN int \
|
||||||
|
wrapper##_objobjproc_closure(PyObject *a, PyObject *b) { \
|
||||||
|
return SwigPyBuiltin_funpack_objobjproc_closure(wrapper, a, b); \
|
||||||
|
}
|
||||||
|
SWIGINTERN int
|
||||||
|
SwigPyBuiltin_funpack_objobjproc_closure(SwigPyWrapperFunction wrapper, PyObject *a, PyObject *b) {
|
||||||
|
int result;
|
||||||
|
PyObject *pyresult;
|
||||||
|
pyresult = wrapper(a, b);
|
||||||
|
result = pyresult ? (PyObject_IsTrue(pyresult) ? 1 : 0) : -1;
|
||||||
|
Py_XDECREF(pyresult);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
#define SWIGPY_OBJOBJARGPROC_CLOSURE(wrapper) \
|
#define SWIGPY_OBJOBJARGPROC_CLOSURE(wrapper) \
|
||||||
SWIGINTERN int \
|
SWIGINTERN int \
|
||||||
wrapper##_objobjargproc_closure(PyObject *a, PyObject *b, PyObject *c) { \
|
wrapper##_objobjargproc_closure(PyObject *a, PyObject *b, PyObject *c) { \
|
||||||
|
|
|
||||||
|
|
@ -156,6 +156,7 @@
|
||||||
%feature("python:slot", "mp_length", functype="lenfunc") __len__;
|
%feature("python:slot", "mp_length", functype="lenfunc") __len__;
|
||||||
%feature("python:slot", "mp_subscript", functype="binaryfunc") __getitem__;
|
%feature("python:slot", "mp_subscript", functype="binaryfunc") __getitem__;
|
||||||
%feature("python:slot", "tp_iter", functype="getiterfunc") key_iterator;
|
%feature("python:slot", "tp_iter", functype="getiterfunc") key_iterator;
|
||||||
|
%feature("python:slot", "sq_contains", functype="objobjproc") __contains__;
|
||||||
|
|
||||||
%extend {
|
%extend {
|
||||||
%newobject iterkeys(PyObject **PYTHON_SELF);
|
%newobject iterkeys(PyObject **PYTHON_SELF);
|
||||||
|
|
@ -263,7 +264,6 @@
|
||||||
return itemList;
|
return itemList;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Python 2.2 methods
|
|
||||||
bool __contains__(const key_type& key) {
|
bool __contains__(const key_type& key) {
|
||||||
return self->find(key) != self->end();
|
return self->find(key) != self->end();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@
|
||||||
%swig_sequence_iterator(set);
|
%swig_sequence_iterator(set);
|
||||||
%swig_container_methods(set);
|
%swig_container_methods(set);
|
||||||
|
|
||||||
|
#if defined(SWIGPYTHON_BUILTIN)
|
||||||
|
%feature("python:slot", "sq_contains", functype="objobjproc") __contains__;
|
||||||
|
#endif
|
||||||
|
|
||||||
%extend {
|
%extend {
|
||||||
void append(value_type x) {
|
void append(value_type x) {
|
||||||
self->insert(x);
|
self->insert(x);
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,10 @@
|
||||||
%swig_sequence_forward_iterator(Map);
|
%swig_sequence_forward_iterator(Map);
|
||||||
%swig_container_methods(Map)
|
%swig_container_methods(Map)
|
||||||
|
|
||||||
|
#if defined(SWIGPYTHON_BUILTIN)
|
||||||
|
%feature("python:slot", "sq_contains", functype="objobjproc") __contains__;
|
||||||
|
#endif
|
||||||
|
|
||||||
%extend {
|
%extend {
|
||||||
mapped_type __getitem__(const key_type& key) const throw (std::out_of_range) {
|
mapped_type __getitem__(const key_type& key) const throw (std::out_of_range) {
|
||||||
Map::const_iterator i = self->find(key);
|
Map::const_iterator i = self->find(key);
|
||||||
|
|
@ -204,7 +208,6 @@
|
||||||
return itemList;
|
return itemList;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Python 2.2 methods
|
|
||||||
bool __contains__(const key_type& key) {
|
bool __contains__(const key_type& key) {
|
||||||
return self->find(key) != self->end();
|
return self->find(key) != self->end();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,10 @@
|
||||||
%swig_sequence_forward_iterator(unordered_set);
|
%swig_sequence_forward_iterator(unordered_set);
|
||||||
%swig_container_methods(unordered_set);
|
%swig_container_methods(unordered_set);
|
||||||
|
|
||||||
|
#if defined(SWIGPYTHON_BUILTIN)
|
||||||
|
%feature("python:slot", "sq_contains", functype="objobjproc") __contains__;
|
||||||
|
#endif
|
||||||
|
|
||||||
%extend {
|
%extend {
|
||||||
void append(value_type x) {
|
void append(value_type x) {
|
||||||
self->insert(x);
|
self->insert(x);
|
||||||
|
|
|
||||||
|
|
@ -210,6 +210,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) {
|
||||||
"ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
|
"ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
|
||||||
"ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
|
"ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
|
||||||
"ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
|
"ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
|
||||||
|
"objobjproc", "SWIGPY_OBJOBJPROC_CLOSURE",
|
||||||
"objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
|
"objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
|
||||||
"reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
|
"reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
|
||||||
"hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
|
"hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
|
||||||
|
|
@ -229,6 +230,7 @@ static String *getClosure(String *functype, String *wrapper, int funpack = 0) {
|
||||||
"ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
|
"ssizessizeargfunc", "SWIGPY_SSIZESSIZEARGFUNC_CLOSURE",
|
||||||
"ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
|
"ssizeobjargproc", "SWIGPY_SSIZEOBJARGPROC_CLOSURE",
|
||||||
"ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
|
"ssizessizeobjargproc", "SWIGPY_SSIZESSIZEOBJARGPROC_CLOSURE",
|
||||||
|
"objobjproc", "SWIGPY_FUNPACK_OBJOBJPROC_CLOSURE",
|
||||||
"objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
|
"objobjargproc", "SWIGPY_OBJOBJARGPROC_CLOSURE",
|
||||||
"reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
|
"reprfunc", "SWIGPY_REPRFUNC_CLOSURE",
|
||||||
"hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
|
"hashfunc", "SWIGPY_HASHFUNC_CLOSURE",
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue