Commit 100a53ff authored by Robert Bradshaw's avatar Robert Bradshaw Committed by Stefan Behnel

Non-int conversion to Py_hash_t.

Still requires the more conservative __index__ here rather than a possibly
truncating __int__ because this is used in a context where floating point
values should probably be treated specially.

This fixes Github issue #2752.
parent 8235d1c9
...@@ -675,10 +675,10 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) { ...@@ -675,10 +675,10 @@ static CYTHON_INLINE void * PyThread_tss_get(Py_tss_t *key) {
#if PY_VERSION_HEX < 0x030200A4 #if PY_VERSION_HEX < 0x030200A4
typedef long Py_hash_t; typedef long Py_hash_t;
#define __Pyx_PyInt_FromHash_t PyInt_FromLong #define __Pyx_PyInt_FromHash_t PyInt_FromLong
#define __Pyx_PyInt_AsHash_t PyInt_AsLong #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsHash_t
#else #else
#define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t #define __Pyx_PyInt_FromHash_t PyInt_FromSsize_t
#define __Pyx_PyInt_AsHash_t PyInt_AsSsize_t #define __Pyx_PyInt_AsHash_t __Pyx_PyIndex_AsSsize_t
#endif #endif
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
......
...@@ -102,6 +102,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x); ...@@ -102,6 +102,7 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_IntOrLong(PyObject* x);
static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*);
static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t);
static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject*);
#if CYTHON_ASSUME_SAFE_MACROS #if CYTHON_ASSUME_SAFE_MACROS
#define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x)) #define __pyx_PyFloat_AsDouble(x) (PyFloat_CheckExact(x) ? PyFloat_AS_DOUBLE(x) : PyFloat_AsDouble(x))
...@@ -420,6 +421,25 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { ...@@ -420,6 +421,25 @@ static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) {
} }
static CYTHON_INLINE Py_hash_t __Pyx_PyIndex_AsHash_t(PyObject* o) {
if (sizeof(Py_hash_t) == sizeof(Py_ssize_t)) {
return __Pyx_PyIndex_AsSsize_t(o);
#if PY_MAJOR_VERSION < 3
} else if (likely(PyInt_CheckExact(o))) {
return PyInt_AS_LONG(o);
#endif
} else {
Py_ssize_t ival;
PyObject *x;
x = PyNumber_Index(o);
if (!x) return -1;
ival = PyInt_AsLong(x);
Py_DECREF(x);
return ival;
}
}
static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) { static CYTHON_INLINE PyObject * __Pyx_PyBool_FromLong(long b) {
return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False); return b ? __Pyx_NewRef(Py_True) : __Pyx_NewRef(Py_False);
} }
......
...@@ -2,12 +2,30 @@ ...@@ -2,12 +2,30 @@
cimport cython cimport cython
class IntLike(object):
def __init__(self, value):
self.value = value
def __index__(self):
return self.value
def assign_py_hash_t(x): def assign_py_hash_t(x):
""" """
>>> assign_py_hash_t(12) >>> assign_py_hash_t(12)
12 12
>>> assign_py_hash_t(-12) >>> assign_py_hash_t(-12)
-12 -12
>>> assign_py_hash_t(IntLike(-3))
-3
>>> assign_py_hash_t(IntLike(1 << 100)) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
OverflowError: ...
>>> assign_py_hash_t(IntLike(1.5)) # doctest: +ELLIPSIS
Traceback (most recent call last):
...
TypeError: __index__ ... (type float)
""" """
cdef Py_hash_t h = x cdef Py_hash_t h = x
return h return h
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment