Fix Python 2 builtin tp_hash hashfunc closure regression when using "python:slot"

Closes https://github.com/swig/swig/issues/843
This commit is contained in:
William S Fulton 2016-12-23 23:41:07 +00:00
commit 4963a7f88f
4 changed files with 35 additions and 3 deletions

View file

@ -5,6 +5,11 @@ See the RELEASENOTES file for a summary of changes in each release.
Version 3.0.11 (in progress)
============================
2016-12-23: wsfulton
[Python] Fix builtin "python:slot" feature failing for tp_hash when using
hashfunc closure with a "Wrong type for hash function" for Python 2.
Issue https://github.com/swig/swig/issues/843
2016-12-21: joequamt
Changed generation of functions so that only functions
that end in _set generate accessor functions rather than

View file

@ -12,10 +12,14 @@ if is_python_builtin():
if h != h2:
raise RuntimeError("default tp_hash not working")
# Test 1 for tp_hash
# Test 1a for tp_hash
if hash(SimpleValue(222)) != 222:
raise RuntimeError("tp_hash not working")
# Test 1b for tp_hash
if hash(SimpleValue2(333)) != 333:
raise RuntimeError("tp_hash not working")
# Test 2 for tp_hash
try:
# Was incorrectly raising: SystemError: error return without exception set

View file

@ -27,7 +27,7 @@ struct ValueStruct {
};
%}
// Test 1 for tp_hash
// Test 1a for tp_hash
#if defined(SWIGPYTHON_BUILTIN)
%feature("python:tp_hash") SimpleValue "SimpleValueHashFunction"
#endif
@ -55,6 +55,24 @@ hashfunc test_hashfunc_cast() {
}
%}
// Test 1b for tp_hash
#if defined(SWIGPYTHON_BUILTIN)
%feature("python:slot", "tp_hash", functype="hashfunc") SimpleValue2::HashFunc;
#endif
%inline %{
struct SimpleValue2 {
int value;
SimpleValue2(int value) : value(value) {}
#if PY_VERSION_HEX >= 0x03020000
typedef Py_hash_t HashType;
#else
typedef long HashType;
#endif
HashType HashFunc() { return (HashType)value; }
};
%}
// Test 2 for tp_hash
#if defined(SWIGPYTHON_BUILTIN)
%feature("python:slot", "tp_hash", functype="hashfunc") BadHashFunctionReturnType::bad_hash_function;

View file

@ -13,6 +13,11 @@ SWIGINTERN Py_hash_t
SWIG_PyNumber_AsPyHash(PyObject *obj) {
Py_hash_t result = -1;
#if PY_VERSION_HEX < 0x03020000
#if PY_VERSION_HEX < 0x03000000
if (PyInt_Check(obj))
result = PyInt_AsLong(obj);
else
#endif
if (PyLong_Check(obj))
result = PyLong_AsLong(obj);
#else
@ -21,7 +26,7 @@ SWIG_PyNumber_AsPyHash(PyObject *obj) {
#endif
else
PyErr_Format(PyExc_TypeError, "Wrong type for hash function");
return result;
return PyErr_Occurred() ? -1 : result;
}
SWIGINTERN int