Python builtin hashfunc closure fix
If the wrong return type in the hash function was used, an error: SystemError: error return without exception set was raised Add some tests for testing builtin slots
This commit is contained in:
parent
2740812970
commit
f778ee19df
4 changed files with 105 additions and 2 deletions
|
|
@ -58,6 +58,7 @@ CPP_TEST_CASES += \
|
||||||
primitive_types \
|
primitive_types \
|
||||||
python_abstractbase \
|
python_abstractbase \
|
||||||
python_append \
|
python_append \
|
||||||
|
python_builtin \
|
||||||
python_destructor_exception \
|
python_destructor_exception \
|
||||||
python_director \
|
python_director \
|
||||||
python_docstring \
|
python_docstring \
|
||||||
|
|
|
||||||
26
Examples/test-suite/python/python_builtin_runme.py
Normal file
26
Examples/test-suite/python/python_builtin_runme.py
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
from python_builtin import *
|
||||||
|
|
||||||
|
if is_python_builtin():
|
||||||
|
# Test 1 for tp_hash
|
||||||
|
if hash(SimpleValue(222)) != 222:
|
||||||
|
raise RuntimeError("tp_hash not working")
|
||||||
|
|
||||||
|
# Test 2 for tp_hash
|
||||||
|
try:
|
||||||
|
# Was incorrectly raising: SystemError: error return without exception set
|
||||||
|
h = hash(BadHashFunctionReturnType())
|
||||||
|
raise RuntimeError("Missing TypeError")
|
||||||
|
except TypeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# Test 3 for tp_hash
|
||||||
|
passed = False
|
||||||
|
try:
|
||||||
|
h = hash(ExceptionHashFunction())
|
||||||
|
except RuntimeError, e:
|
||||||
|
passed = str(e).find("oops") != -1
|
||||||
|
pass
|
||||||
|
|
||||||
|
if not passed:
|
||||||
|
raise RuntimeError("did not catch exception in hash()")
|
||||||
|
|
||||||
74
Examples/test-suite/python_builtin.i
Normal file
74
Examples/test-suite/python_builtin.i
Normal file
|
|
@ -0,0 +1,74 @@
|
||||||
|
// Test customizing slots when using the -builtin option
|
||||||
|
|
||||||
|
%module python_builtin
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
#ifdef SWIGPYTHON_BUILTIN
|
||||||
|
bool is_python_builtin() { return true; }
|
||||||
|
#else
|
||||||
|
bool is_python_builtin() { return false; }
|
||||||
|
#endif
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Test 1 for tp_hash
|
||||||
|
#if defined(SWIGPYTHON_BUILTIN)
|
||||||
|
%feature("python:tp_hash") SimpleValue "SimpleValueHashFunction"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct SimpleValue {
|
||||||
|
int value;
|
||||||
|
SimpleValue(int value) : value(value) {}
|
||||||
|
static SimpleValue *inout(SimpleValue *sv) {
|
||||||
|
return sv;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
%{
|
||||||
|
#if PY_VERSION_HEX >= 0x03020000
|
||||||
|
Py_hash_t SimpleValueHashFunction(PyObject *v)
|
||||||
|
#else
|
||||||
|
long SimpleValueHashFunction(PyObject *v)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
SwigPyObject *sobj = (SwigPyObject *) v;
|
||||||
|
SimpleValue *p = (SimpleValue *)sobj->ptr;
|
||||||
|
return p->value;
|
||||||
|
}
|
||||||
|
hashfunc test_hashfunc_cast() {
|
||||||
|
return SimpleValueHashFunction;
|
||||||
|
}
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Test 2 for tp_hash
|
||||||
|
#if defined(SWIGPYTHON_BUILTIN)
|
||||||
|
%feature("python:slot", "tp_hash", functype="hashfunc") BadHashFunctionReturnType::bad_hash_function;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
struct BadHashFunctionReturnType {
|
||||||
|
static const char * bad_hash_function() {
|
||||||
|
return "bad hash function";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
// Test 3 for tp_hash
|
||||||
|
#if defined(SWIGPYTHON_BUILTIN)
|
||||||
|
%feature("python:slot", "tp_hash", functype="hashfunc") ExceptionHashFunction::exception_hash_function;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
%catches(const char *) exception_hash_function;
|
||||||
|
|
||||||
|
%inline %{
|
||||||
|
#if PY_VERSION_HEX < 0x03020000
|
||||||
|
#define Py_hash_t long
|
||||||
|
#endif
|
||||||
|
struct ExceptionHashFunction {
|
||||||
|
static Py_hash_t exception_hash_function() {
|
||||||
|
throw "oops";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
%}
|
||||||
|
|
||||||
|
|
@ -192,9 +192,11 @@ wrapper##_closure(PyObject *a) { \
|
||||||
PyObject *pyresult; \
|
PyObject *pyresult; \
|
||||||
long result; \
|
long result; \
|
||||||
pyresult = wrapper(a, NULL); \
|
pyresult = wrapper(a, NULL); \
|
||||||
if (!pyresult || !PyLong_Check(pyresult)) \
|
if (!pyresult) \
|
||||||
return -1; \
|
return -1; \
|
||||||
result = PyLong_AsLong(pyresult); \
|
result = PyLong_AsLong(pyresult); \
|
||||||
|
if (PyErr_Occurred()) \
|
||||||
|
result = -1; \
|
||||||
Py_DECREF(pyresult); \
|
Py_DECREF(pyresult); \
|
||||||
return result; \
|
return result; \
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue