mirror of https://github.com/swig/swig
Py_LIMITED_API support in SwigPyObject_Check for -builtin
Simplify implementation for -builtin, which does not need a fallback to use strcmp as PyType_IsSubtype() 'just works' even when using multiple modules (I think perhaps because SwigPyObject_stype->clientdata->pytype is common across modules due to the implementation in SwigPyObject_Type()). In the non-builtin case SwigPyObject is not a base type and usage is different and when multiple modules are being used, SwigPyObject_Type() returns two implementations of SwigPyObject which is solved in a hacky way by comparing the types as strings when the pointer comparison fails. Add import_callback test - tests %import and %callback to exercise all of SwigPyPacked_Check(). Python only - the main callback example is not widely tested and needs work in most of the other languages.
This commit is contained in:
parent
9ec4c6f1aa
commit
f3672e2d6f
|
@ -0,0 +1,2 @@
|
|||
import_callback_x
|
||||
import_callback_y
|
|
@ -0,0 +1,16 @@
|
|||
class X {
|
||||
int val;
|
||||
public:
|
||||
|
||||
X(int val = 0) : val(val) {}
|
||||
int xmethod(int a) {
|
||||
return -a;
|
||||
}
|
||||
int call_xmethod(int a) {
|
||||
return xmethod(a);
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" int go_for_it_x(int a, X x, int (X::*pf)(int a)) {
|
||||
return (x.*pf)(a) + 11;
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
%module import_callback_x
|
||||
|
||||
%{
|
||||
#include "import_callback_x.h"
|
||||
%}
|
||||
|
||||
%callback("%s_cb_ptr") X::xmethod;
|
||||
|
||||
%import "import_callback_y.i"
|
||||
|
||||
%include "import_callback_x.h"
|
|
@ -0,0 +1,5 @@
|
|||
#include "import_callback_x.h"
|
||||
|
||||
extern "C" int go_for_it_y(int a, X x, int (X::*pf)(int a)) {
|
||||
return (x.*pf)(a) + 111;
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
%module import_callback_y
|
||||
|
||||
%{
|
||||
#include "import_callback_y.h"
|
||||
%}
|
||||
|
||||
%include "import_callback_y.h"
|
|
@ -113,6 +113,7 @@ C_TEST_CASES += \
|
|||
python_varargs_typemap \
|
||||
|
||||
MULTI_CPP_TEST_CASES += \
|
||||
import_callback \
|
||||
python_runtime_data \
|
||||
|
||||
include $(srcdir)/../common.mk
|
||||
|
@ -183,6 +184,7 @@ clean:
|
|||
rm -f imports_a.py imports_b.py mod_a.py mod_b.py multi_import_a.py
|
||||
rm -f multi_import_b.py multi_import_d.py packageoption_a.py packageoption_b.py packageoption_c.py
|
||||
rm -f template_typedef_cplx2.py python_runtime_data_builtin.py python_runtime_data_nobuiltin.py
|
||||
rm -f import_callback_x.py import_callback_y.py
|
||||
|
||||
hugemod_runme = $(SCRIPTPREFIX)hugemod$(SCRIPTSUFFIX)
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
import import_callback_x
|
||||
import import_callback_y
|
||||
|
||||
x = import_callback_x.X()
|
||||
|
||||
# Sanity check
|
||||
aa = x.call_xmethod(5)
|
||||
if aa != -5:
|
||||
raise RuntimeError("Bad aa {}".format(aa))
|
||||
|
||||
# Callback within import_callback_x module
|
||||
res = import_callback_x.go_for_it_x(3, x, import_callback_x.X.xmethod_cb_ptr) - 11
|
||||
if res != x.call_xmethod(3):
|
||||
raise RuntimeError("Bad res {}".format(res))
|
||||
|
||||
# Callback across modules
|
||||
# This uses the fallback string comparison in SwigPyPacked_Check()
|
||||
res = import_callback_y.go_for_it_y(3, x, import_callback_x.X.xmethod_cb_ptr) - 111
|
||||
if res != x.call_xmethod(3):
|
||||
raise RuntimeError("Bad res {}".format(res))
|
|
@ -780,10 +780,10 @@ SwigPyObject_Check(PyObject *op) {
|
|||
PyTypeObject *target_tp = SwigPyObject_Type();
|
||||
PyTypeObject *op_type = Py_TYPE(op);
|
||||
#ifdef SWIGPYTHON_BUILTIN
|
||||
if (PyType_IsSubtype(op_type, target_tp))
|
||||
return 1;
|
||||
return (strcmp(op_type->tp_name, SWIG_RUNTIME_MODULE ".SwigPyObject") == 0);
|
||||
/* Only builtin types have SwigPyObject as a base type */
|
||||
return PyType_IsSubtype(op_type, target_tp);
|
||||
#else
|
||||
/* Check for an exact match to SwigPyObject */
|
||||
# ifdef Py_LIMITED_API
|
||||
int cmp;
|
||||
PyObject *tp_name;
|
||||
|
@ -791,6 +791,7 @@ SwigPyObject_Check(PyObject *op) {
|
|||
if (op_type == target_tp)
|
||||
return 1;
|
||||
# ifdef Py_LIMITED_API
|
||||
/* Fallback for multiple modules */
|
||||
tp_name = PyObject_GetAttrString((PyObject *)op_type, "__name__");
|
||||
if (!tp_name)
|
||||
return 0;
|
||||
|
@ -1184,14 +1185,17 @@ SwigPyPacked_Type(void) {
|
|||
|
||||
SWIGRUNTIMEINLINE int
|
||||
SwigPyPacked_Check(PyObject *op) {
|
||||
PyTypeObject *target_tp = SwigPyPacked_Type();
|
||||
PyTypeObject *op_type = Py_TYPE(op);
|
||||
/* Check for an exact match to SwigPyPacked */
|
||||
#ifdef Py_LIMITED_API
|
||||
int cmp;
|
||||
PyObject *tp_name;
|
||||
#endif
|
||||
PyTypeObject* op_type = Py_TYPE(op);
|
||||
if (op_type == SwigPyPacked_Type())
|
||||
if (op_type == target_tp)
|
||||
return 1;
|
||||
#ifdef Py_LIMITED_API
|
||||
/* Fallback for multiple modules */
|
||||
tp_name = PyObject_GetAttrString((PyObject *)op_type, "__name__");
|
||||
if (!tp_name)
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue