From: Lisandro Dalcin Date: Thu, 22 Apr 2010 15:31:52 +0000 (-0300) Subject: custom from_py converter for Py_UNICODE X-Git-Tag: 0.13.beta0~156 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=33c4695889cfb28b6fcef452b4e6753fe27901f1;p=cython.git custom from_py converter for Py_UNICODE --- diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 20e9fc1e..2a0113f9 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -828,7 +828,7 @@ class CIntType(CNumericType): type_name = type_name.replace("PY_LONG_LONG","long long") SignWord = sign_word.title() TypeName = type_name.title().replace(" ", "") - if "Long" in TypeName: + if self.rank >= list(rank_to_type_name).index('long'): utility_code = c_long_from_py_function else: utility_code = c_int_from_py_function @@ -874,6 +874,7 @@ class CPyUnicodeIntType(CIntType): # 1114111, so PyInt_FromLong() will do just fine here. to_py_function = "PyInt_FromLong" + from_py_function = "__Pyx_PyInt_AsPy_UNICODE" def sign_and_name(self): return "Py_UNICODE" @@ -2491,6 +2492,10 @@ type_conversion_predeclarations = """ static CYTHON_INLINE int __Pyx_PyObject_IsTrue(PyObject*); static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x); +#ifdef Py_USING_UNICODE +static CYTHON_INLINE Py_UNICODE __Pyx_PyInt_AsPy_UNICODE(PyObject*); +#endif + static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject*); static CYTHON_INLINE PyObject * __Pyx_PyInt_FromSize_t(size_t); static CYTHON_INLINE size_t __Pyx_PyInt_AsSize_t(PyObject*); @@ -2555,6 +2560,26 @@ static CYTHON_INLINE PyObject* __Pyx_PyNumber_Int(PyObject* x) { return res; } +#ifdef Py_USING_UNICODE +static CYTHON_INLINE Py_UNICODE __Pyx_PyInt_AsPy_UNICODE(PyObject* x) { + long ival = __Pyx_PyInt_AsLong(x); + static long maxval = 0; + if (unlikely(!maxval)) + maxval = (long)PyUnicode_GetMax(); + if (unlikely(ival < 0)) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to Py_UNICODE"); + return (Py_UNICODE)-1; + } else if (unlikely(ival > maxval)) { + PyErr_SetString(PyExc_OverflowError, + "value too large to convert to Py_UNICODE"); + return (Py_UNICODE)-1; + } + return (Py_UNICODE)ival; +} +#endif + static CYTHON_INLINE Py_ssize_t __Pyx_PyIndex_AsSsize_t(PyObject* b) { Py_ssize_t ival; PyObject* x = PyNumber_Index(b); diff --git a/tests/run/py_unicode_type.pyx b/tests/run/py_unicode_type.pyx index b1bb40e8..41fe97d7 100644 --- a/tests/run/py_unicode_type.pyx +++ b/tests/run/py_unicode_type.pyx @@ -42,3 +42,28 @@ def index_literal(int i): # runtime casts are not currently supported #return (u"12345"[i]) return u"12345"[i] + + +def unicode_cardinal(Py_UNICODE i): + """ + >>> import sys + + >>> unicode_cardinal(0) + 0 + >>> unicode_cardinal(1) + 1 + >>> unicode_cardinal(sys.maxunicode) == sys.maxunicode + True + + + >>> unicode_cardinal(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + + >>> unicode_cardinal(sys.maxunicode+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return i