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 \
|
||||
python_abstractbase \
|
||||
python_append \
|
||||
python_builtin \
|
||||
python_destructor_exception \
|
||||
python_director \
|
||||
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; \
|
||||
long result; \
|
||||
pyresult = wrapper(a, NULL); \
|
||||
if (!pyresult || !PyLong_Check(pyresult)) \
|
||||
return -1; \
|
||||
if (!pyresult) \
|
||||
return -1; \
|
||||
result = PyLong_AsLong(pyresult); \
|
||||
if (PyErr_Occurred()) \
|
||||
result = -1; \
|
||||
Py_DECREF(pyresult); \
|
||||
return result; \
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue