From 867ac47a156fa632a75307102ba50a6adb0856d6 Mon Sep 17 00:00:00 2001 From: Lisandro Dalcin Date: Wed, 21 Apr 2010 21:47:54 -0300 Subject: [PATCH] Let ssize_t be a native type (ticket #399) --- Cython/Compiler/Parsing.py | 1 + Cython/Compiler/PyrexTypes.py | 45 +++++++++++++++-------- tests/run/ssize_t_T399.pyx | 69 +++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 16 deletions(-) create mode 100644 tests/run/ssize_t_T399.pyx diff --git a/Cython/Compiler/Parsing.py b/Cython/Compiler/Parsing.py index 3397d771..ebee3bf7 100644 --- a/Cython/Compiler/Parsing.py +++ b/Cython/Compiler/Parsing.py @@ -1853,6 +1853,7 @@ special_basic_c_types = { # name : (signed, longness) "Py_UNICODE" : (0, 0), "Py_ssize_t" : (2, 0), + "ssize_t" : (2, 0), "size_t" : (0, 0), } diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 0b11afaf..6837621c 100755 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -844,16 +844,6 @@ class CIntType(CNumericType): return src_type.is_int or src_type.is_enum or src_type is error_type -class CBIntType(CIntType): - - to_py_function = "__Pyx_PyBool_FromLong" - from_py_function = "__Pyx_PyObject_IsTrue" - exception_check = 0 - - def __repr__(self): - return "" - - class CAnonEnumType(CIntType): is_enum = 1 @@ -866,6 +856,17 @@ class CReturnCodeType(CIntType): is_returncode = 1 + +class CBIntType(CIntType): + + to_py_function = "__Pyx_PyBool_FromLong" + from_py_function = "__Pyx_PyObject_IsTrue" + exception_check = 0 + + def __repr__(self): + return "" + + class CPyUnicodeIntType(CIntType): # Py_UNICODE @@ -888,6 +889,13 @@ class CPySSizeTType(CIntType): def sign_and_name(self): return "Py_ssize_t" +class CSSizeTType(CIntType): + + to_py_function = "PyInt_FromSsize_t" + from_py_function = "PyInt_AsSsize_t" + + def sign_and_name(self): + return "ssize_t" class CSizeTType(CIntType): @@ -2111,7 +2119,6 @@ c_void_ptr_ptr_type = CPtrType(c_void_ptr_type) c_uchar_type = CIntType(0, 0) c_ushort_type = CIntType(1, 0) -c_py_unicode_type = CPyUnicodeIntType(2, 0) c_uint_type = CIntType(3, 0) c_ulong_type = CIntType(4, 0) c_ulonglong_type = CIntType(7, 0) @@ -2129,7 +2136,9 @@ c_slong_type = CIntType(4, 2) c_slonglong_type = CIntType(7, 2) c_bint_type = CBIntType(3, 1) +c_py_unicode_type = CPyUnicodeIntType(2, 0) c_py_ssize_t_type = CPySSizeTType(5, 2) +c_ssize_t_type = CSSizeTType(5, 2) c_size_t_type = CSizeTType(6, 0) c_float_type = CFloatType(8, math_h_modifier='f') @@ -2148,6 +2157,7 @@ c_utf8_char_array_type = CUTF8CharArrayType(None) c_char_ptr_ptr_type = CPtrType(c_char_ptr_type) c_int_ptr_type = CPtrType(c_int_type) c_py_ssize_t_ptr_type = CPtrType(c_py_ssize_t_type) +c_ssize_t_ptr_type = CPtrType(c_ssize_t_type) c_size_t_ptr_type = CPtrType(c_size_t_type) c_returncode_type = CReturnCodeType(3, 1) @@ -2182,9 +2192,10 @@ modifiers_and_name_to_type = { (2, 2, "int"): c_slonglong_type, (1, 0, "bint"): c_bint_type, - (0, 0, "size_t") : c_size_t_type, - (2, 0, "Py_ssize_t"): c_py_ssize_t_type, (0, 0, "Py_UNICODE"): c_py_unicode_type, + (2, 0, "Py_ssize_t"): c_py_ssize_t_type, + (2, 0, "ssize_t") : c_ssize_t_type, + (0, 0, "size_t") : c_size_t_type, (1, 0, "float"): c_float_type, (1, 0, "double"): c_double_type, @@ -2399,12 +2410,14 @@ def parse_basic_type(name): # signed = 1 longness = 0 - if name == 'Py_ssize_t': + if name == 'Py_UNICODE': + signed = 0 + elif name == 'Py_ssize_t': + signed = 2 + elif name == 'ssize_t': signed = 2 elif name == 'size_t': signed = 0 - elif name == 'Py_UNICODE': - signed = 0 else: if name.startswith('u'): name = name[1:] diff --git a/tests/run/ssize_t_T399.pyx b/tests/run/ssize_t_T399.pyx new file mode 100644 index 00000000..f6eafd32 --- /dev/null +++ b/tests/run/ssize_t_T399.pyx @@ -0,0 +1,69 @@ +__doc__ = u""" +>>> test(-2) +-2 +>>> test(-1) +-1 +>>> test(0) +0 +>>> test(1) +1 +>>> test(2) +2 + +>>> test(SSIZE_T_MAX) == SSIZE_T_MAX +True +>>> test(SSIZE_T_MIN) == SSIZE_T_MIN +True + +>>> test(SSIZE_T_MAX+1) #doctest: +ELLIPSIS +Traceback (most recent call last): + ... +OverflowError: ... +>>> test(SSIZE_T_MIN-1) #doctest: +ELLIPSIS +Traceback (most recent call last): + ... +OverflowError: ... + +>>> test(1<<128) #doctest: +ELLIPSIS +Traceback (most recent call last): + ... +OverflowError: ... +>>> test(-(1<<128)) #doctest: +ELLIPSIS +Traceback (most recent call last): + ... +OverflowError: ... + +>>> a = A(1,2) +>>> a.a == 1 +True +>>> a.b == 2 +True +>>> a.foo(5) +5 +>>> a.foo(1 << 180) #doctest: +ELLIPSIS +Traceback (most recent call last): + ... +OverflowError: ... +""" + +# XXX This should generate a warning !!! +cdef extern from *: + ctypedef long ssize_t + +SSIZE_T_MAX = ((-1)>>1) +SSIZE_T_MIN = (-SSIZE_T_MAX-1) + +def test(ssize_t i): + return i + +cdef class A: + cdef public ssize_t a + cdef readonly ssize_t b + + def __init__(self, ssize_t a, object b): + self.a = a + self.b = b + + cpdef ssize_t foo(self, ssize_t x): + cdef object o = x + return o -- 2.26.2