diff --git a/CHANGES.current b/CHANGES.current index 5fc95fef7..118f112de 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -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 diff --git a/Examples/test-suite/python/python_builtin_runme.py b/Examples/test-suite/python/python_builtin_runme.py index dc46b63f5..7afab2a39 100644 --- a/Examples/test-suite/python/python_builtin_runme.py +++ b/Examples/test-suite/python/python_builtin_runme.py @@ -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 diff --git a/Examples/test-suite/python_builtin.i b/Examples/test-suite/python_builtin.i index 4108f6753..d4e245dc4 100644 --- a/Examples/test-suite/python_builtin.i +++ b/Examples/test-suite/python_builtin.i @@ -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; diff --git a/Lib/python/builtin.swg b/Lib/python/builtin.swg index 75b131333..4fd19471a 100644 --- a/Lib/python/builtin.swg +++ b/Lib/python/builtin.swg @@ -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