From 021488a5a1e0116188fe38c857387a838c967066 Mon Sep 17 00:00:00 2001 From: Lisandro Dalcin Date: Thu, 10 Sep 2009 10:50:11 -0300 Subject: [PATCH] extern ctypedef integral <-> python object conversion (ticket #333) --- Cython/Compiler/ExprNodes.py | 5 +- Cython/Compiler/Nodes.py | 5 +- Cython/Compiler/PyrexTypes.py | 182 ++++-- tests/run/ctypedef_int_types_T333.pyx | 674 +++++++++++++++++++++ tests/run/ctypedef_int_types_chdr_T333.h | 10 + tests/run/ctypedef_int_types_defs_T333.pxd | 15 + 6 files changed, 845 insertions(+), 46 deletions(-) create mode 100644 tests/run/ctypedef_int_types_T333.pyx create mode 100644 tests/run/ctypedef_int_types_chdr_T333.h create mode 100644 tests/run/ctypedef_int_types_defs_T333.pxd diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py index af94ed03..abf575ab 100644 --- a/Cython/Compiler/ExprNodes.py +++ b/Cython/Compiler/ExprNodes.py @@ -3933,8 +3933,7 @@ class TypecastNode(NewTempExprNode): if from_py and not to_py and self.operand.is_ephemeral() and not self.type.is_numeric: error(self.pos, "Casting temporary Python object to non-numeric non-Python type") if to_py and not from_py: - if (self.operand.type.to_py_function and - self.operand.type.create_to_py_utility_code(env)): + if self.operand.type.create_to_py_utility_code(env): self.result_ctype = py_object_type self.operand = self.operand.coerce_to_pyobject(env) else: @@ -3942,7 +3941,7 @@ class TypecastNode(NewTempExprNode): warning(self.pos, "No conversion from %s to %s, python object pointer used." % (self.operand.type, self.type)) self.operand = self.operand.coerce_to_simple(env) elif from_py and not to_py: - if self.type.from_py_function: + if self.type.create_from_py_utility_code(env): self.operand = self.operand.coerce_to(self.type, env) elif self.type.is_ptr and not (self.type.base_type.is_void or self.type.base_type.is_struct): error(self.pos, "Python objects cannot be casted to pointers of primitive types") diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index a1efb255..e1b4524f 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1964,8 +1964,9 @@ class DefNode(FuncDefNode): or self.starstar_arg is not None or has_kwonly_args for arg in self.args: - if not arg.type.is_pyobject and arg.type.from_py_function is None: - arg.type.create_from_py_utility_code(env) + if not arg.type.is_pyobject: + done = arg.type.create_from_py_utility_code(env) + if not done: pass # will fail later if not self.signature_has_generic_args(): if has_star_or_kw_args: diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 3048d36d..2c393992 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -163,12 +163,15 @@ class CTypedefType(BaseType): is_typedef = 1 typedef_is_external = 0 + + to_py_utility_code = None + from_py_utility_code = None + def __init__(self, cname, base_type, is_external=0): self.typedef_cname = cname self.typedef_base_type = base_type self.typedef_is_external = is_external - # Make typecodes in external typedefs use typesize-neutral macros if is_external: typecode = None @@ -206,13 +209,70 @@ class CTypedefType(BaseType): return self.typedef_base_type.cast_code(expr_code) else: return BaseType.cast_code(self, expr_code) - + def __repr__(self): return "" % self.typedef_cname def __str__(self): return self.declaration_name(for_display = 1) - + + def _create_utility_code(self, template_utility_code, + template_function_name): + type_name = self.typedef_cname.replace(" ","_") + utility_code = template_utility_code.specialize( + type = self.typedef_cname, + TypeName = type_name) + function_name = template_function_name % type_name + return utility_code, function_name + + def create_to_py_utility_code(self, env): + if self.typedef_is_external: + if not self.to_py_utility_code: + base_type = self.typedef_base_type + if base_type.is_int: + self.to_py_utility_code, self.to_py_function = \ + self._create_utility_code(c_typedef_int_to_py_function, + '__Pyx_PyInt_to_py_%s') + elif base_type.is_float: + pass # XXX implement! + elif base_type.is_complex: + pass # XXX implement! + pass + if self.to_py_utility_code: + env.use_utility_code(self.to_py_utility_code) + return True + # delegation + return self.typedef_base_type.create_to_py_utility_code(env) + + def create_from_py_utility_code(self, env): + if self.typedef_is_external: + if not self.from_py_utility_code: + base_type = self.typedef_base_type + if base_type.is_int: + self.from_py_utility_code, self.from_py_function = \ + self._create_utility_code(c_typedef_int_from_py_function, + '__Pyx_PyInt_from_py_%s') + elif base_type.is_float: + pass # XXX implement! + elif base_type.is_complex: + pass # XXX implement! + if self.from_py_utility_code: + env.use_utility_code(self.from_py_utility_code) + return True + # delegation + return self.typedef_base_type.create_from_py_utility_code(env) + + def error_condition(self, result_code): + if self.typedef_is_external: + if self.exception_value: + condition = "(%s == (%s)%s)" % ( + result_code, self.typedef_cname, self.exception_value) + if self.exception_check: + condition += " && PyErr_Occurred()" + return condition + # delegation + return self.typedef_base_type.error_condition(result_code) + def __getattr__(self, name): return getattr(self.typedef_base_type, name) @@ -540,9 +600,12 @@ static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) { long val = __Pyx_PyInt_AsLong(x); if (unlikely(val != (long)(%(type)s)val)) { if (unlikely(val == -1 && PyErr_Occurred())) - return (%(type)s)-1;""" + \ - "%(IntValSignTest)s" + \ -""" + return (%(type)s)-1; + if (((%(type)s)-1) > ((%(type)s)0) && unlikely(val < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to %(type)s"); + return (%(type)s)-1; + } PyErr_SetString(PyExc_OverflowError, "value too large to convert to %(type)s"); return (%(type)s)-1; @@ -552,12 +615,6 @@ static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) { return (%(type)s)__Pyx_PyInt_As%(SignWord)sLong(x); } """) -intval_signtest = """ - if (unlikely(%(var)s < 0)) { - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to %(type)s"); - return (%(type)s)-1; - }""" c_long_from_py_function = UtilityCode( proto=""" @@ -566,17 +623,25 @@ static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject *); impl=""" static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) { #if PY_VERSION_HEX < 0x03000000 - if (likely(PyInt_CheckExact(x) || PyInt_Check(x))) { - long val = PyInt_AS_LONG(x);""" + \ - "%(IntValSignTest)s" + \ -""" + if (likely(PyInt_Check(x))) { + long val = PyInt_AS_LONG(x); + if (((%(type)s)-1) > ((%(type)s)0) && unlikely(val < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to %(type)s"); + return (%(type)s)-1; + } return (%(type)s)val; } else #endif - if (likely(PyLong_CheckExact(x) || PyLong_Check(x))) {""" +\ - "%(PyLongSignTest)s" + \ -""" - return %(PyLongConvert)s(x); + if (likely(PyLong_Check(x))) { + if (((%(type)s)-1) > ((%(type)s)0) && unlikely(Py_SIZE(x) < 0)) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to %(type)s"); + return (%(type)s)-1; + } + return (((%(type)s)-1) < ((%(type)s)0)) ? + PyLong_As%(TypeName)s(x) : + PyLong_AsUnsigned%(TypeName)s(x); } else { %(type)s val; PyObject *tmp = __Pyx_PyNumber_Int(x); @@ -587,14 +652,63 @@ static INLINE %(type)s __Pyx_PyInt_As%(SignWord)s%(TypeName)s(PyObject* x) { } } """) -pylong_signtest = """ - if (unlikely(Py_SIZE(%(var)s) < 0)) { - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to %(type)s"); - return (%(type)s)-1; - }""" +c_typedef_int_from_py_function = UtilityCode( +proto=""" +static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject *); +""", +impl=""" +static INLINE %(type)s __Pyx_PyInt_from_py_%(TypeName)s(PyObject* x) { + /**/ if (sizeof(%(type)s) == sizeof(char)) + return (((%(type)s)-1) < ((%(type)s)0)) ? + (%(type)s)__Pyx_PyInt_AsSignedChar(x) : + (%(type)s)__Pyx_PyInt_AsUnsignedChar(x); + else if (sizeof(%(type)s) == sizeof(short)) + return (((%(type)s)-1) < ((%(type)s)0)) ? + (%(type)s)__Pyx_PyInt_AsSignedShort(x) : + (%(type)s)__Pyx_PyInt_AsUnsignedShort(x); + else if (sizeof(%(type)s) == sizeof(int)) + return (((%(type)s)-1) < ((%(type)s)0)) ? + (%(type)s)__Pyx_PyInt_AsSignedInt(x) : + (%(type)s)__Pyx_PyInt_AsUnsignedInt(x); + else if (sizeof(%(type)s) == sizeof(long)) + return (((%(type)s)-1) < ((%(type)s)0)) ? + (%(type)s)__Pyx_PyInt_AsSignedLong(x) : + (%(type)s)__Pyx_PyInt_AsUnsignedLong(x); + else if (sizeof(%(type)s) == sizeof(PY_LONG_LONG)) + return (((%(type)s)-1) < ((%(type)s)0)) ? + (%(type)s)__Pyx_PyInt_AsSignedLongLong(x) : + (%(type)s)__Pyx_PyInt_AsUnsignedLongLong(x); +#if 0 + else if (sizeof(%(type)s) > sizeof(short) && + sizeof(%(type)s) < sizeof(int)) /* __int32 ILP64 ? */ + return (((%(type)s)-1) < ((%(type)s)0)) ? + (%(type)s)__Pyx_PyInt_AsSignedInt(x) : + (%(type)s)__Pyx_PyInt_AsUnsignedInt(x); +#endif + PyErr_SetString(PyExc_TypeError, "%(TypeName)s"); + return (%(type)s)-1; +} +""") +c_typedef_int_to_py_function = UtilityCode( +proto=""" +static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s); +""", +impl=""" +static INLINE PyObject *__Pyx_PyInt_to_py_%(TypeName)s(%(type)s val) { + /**/ if (sizeof(%(type)s) < sizeof(long)) + return PyInt_FromLong((long)val); + else if (sizeof(%(type)s) == sizeof(long)) + return (((%(type)s)-1) < ((%(type)s)0)) ? + PyInt_FromLong((long)val) : + PyLong_FromUnsignedLong((unsigned long)val); + else /* (sizeof(%(type)s) > sizeof(long)) */ + return (((%(type)s)-1) < ((%(type)s)0)) ? + PyLong_FromLongLong((PY_LONG_LONG)val) : + PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)val); +} +""") class CIntType(CNumericType): @@ -620,27 +734,13 @@ class CIntType(CNumericType): type_name = type_name.replace("PY_LONG_LONG","long long") SignWord = sign_word.title() TypeName = type_name.title().replace(" ", "") - data = {'IntValSignTest' : "", - 'PyLongSignTest' : "", - 'PyLongConvert' : "", - } - if not self.signed: - data['IntValSignTest'] = intval_signtest % {'var':"val", 'type':ctype} - data['PyLongSignTest'] = pylong_signtest % {'var':"x", 'type':ctype} if "Long" in TypeName: - data['PyLongConvert'] = \ - "PyLong_As" + SignWord.replace("Signed", "") + TypeName - # the replaces below are just for generating well indented C code - data['IntValSignTest'] = "\n".join( - [ln.replace(" "*4, "", 1) for ln in data['IntValSignTest'].split('\n')] - ) utility_code = c_long_from_py_function else: utility_code = c_int_from_py_function utility_code.specialize(self, SignWord=SignWord, - TypeName=TypeName, - **data) + TypeName=TypeName) func_name = "__Pyx_PyInt_As%s%s" % (SignWord, TypeName) return func_name diff --git a/tests/run/ctypedef_int_types_T333.pyx b/tests/run/ctypedef_int_types_T333.pyx new file mode 100644 index 00000000..5d9371b7 --- /dev/null +++ b/tests/run/ctypedef_int_types_T333.pyx @@ -0,0 +1,674 @@ +__doc__ = u"" + +# ------------------------------------------------------------------- + +cdef extern from "ctypedef_int_types_chdr_T333.h": + ctypedef int SChar ## "signed char" + ctypedef int UChar ## "unsigned char" + ctypedef int SShort ## "signed short" + ctypedef int UShort ## "unsigned short" + ctypedef int SInt ## "signed int" + ctypedef int UInt ## "unsigned int" + ctypedef int SLong ## "signed long" + ctypedef int ULong ## "unsigned long" + ctypedef int SLongLong ## "signed PY_LONG_LONG" + ctypedef int ULongLong ## "unsigned PY_LONG_LONG" + +# ------------------------------------------------------------------- + +SCHAR_MAX = ((-1)>>1) +SCHAR_MIN = (-SCHAR_MAX-1) + +def test_schar(SChar x): + u""" + >>> test_schar(-129) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_schar(-128) + -128 + >>> test_schar(0) + 0 + >>> test_schar(127) + 127 + >>> test_schar(128) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_schar(x, y): + u""" + >>> test_add_schar(SCHAR_MIN, -1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_add_schar(SCHAR_MIN, 0) == SCHAR_MIN + True + >>> test_add_schar(SCHAR_MIN, 1) == SCHAR_MIN+1 + True + >>> test_add_schar(SCHAR_MAX, -1) == SCHAR_MAX-1 + True + >>> test_add_schar(SCHAR_MAX, 0) == SCHAR_MAX + True + >>> test_add_schar(SCHAR_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef SChar r = x + y + return r + +UCHAR_MAX = ((-1)) + +def test_uchar(UChar x): + u""" + >>> test_uchar(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_uchar(0) + 0 + >>> test_uchar(1) + 1 + >>> test_uchar(UCHAR_MAX) == UCHAR_MAX + True + >>> test_uchar(UCHAR_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_uchar(x, y): + u""" + >>> test_add_uchar(UCHAR_MAX, 0) == UCHAR_MAX + True + >>> test_add_uchar(UCHAR_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef UChar r = x + y + return r + +# ------------------------------------------------------------------- + +SSHORT_MAX = ((-1)>>1) +SSHORT_MIN = (-SSHORT_MAX-1) + +def test_sshort(short x): + u""" + >>> test_sshort(SSHORT_MIN-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_sshort(SSHORT_MIN) == SSHORT_MIN + True + >>> test_sshort(-1) + -1 + >>> test_sshort(0) + 0 + >>> test_sshort(1) + 1 + >>> test_sshort(SSHORT_MAX) == SSHORT_MAX + True + >>> test_sshort(SSHORT_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_sshort(x, y): + u""" + >>> test_add_sshort(SSHORT_MIN, -1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_add_sshort(SSHORT_MIN, 0) == SSHORT_MIN + True + >>> test_add_sshort(SSHORT_MIN, 1) == SSHORT_MIN+1 + True + >>> test_add_sshort(SSHORT_MAX, -1) == SSHORT_MAX-1 + True + >>> test_add_sshort(SSHORT_MAX, 0) == SSHORT_MAX + True + >>> test_add_sshort(SSHORT_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef SShort r = x + y + return r + +USHORT_MAX = ((-1)) + +def test_ushort(UShort x): + u""" + >>> test_ushort(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_ushort(0) + 0 + >>> test_ushort(1) + 1 + >>> test_ushort(USHORT_MAX) == USHORT_MAX + True + >>> test_ushort(USHORT_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_ushort(x, y): + u""" + >>> test_add_ushort(USHORT_MAX, 0) == USHORT_MAX + True + >>> test_add_ushort(USHORT_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef UShort r = x + y + return r + +# ------------------------------------------------------------------- + +SINT_MAX = ((-1)>>1) +SINT_MIN = (-SINT_MAX-1) + +def test_sint(int x): + u""" + >>> test_sint(SINT_MIN-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_sint(SINT_MIN) == SINT_MIN + True + >>> test_sint(-1) + -1 + >>> test_sint(0) + 0 + >>> test_sint(1) + 1 + >>> test_sint(SINT_MAX) == SINT_MAX + True + >>> test_sint(SINT_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_sint(x, y): + u""" + >>> test_add_sint(SINT_MIN, -1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_add_sint(SINT_MIN, 0) == SINT_MIN + True + >>> test_add_sint(SINT_MIN, 1) == SINT_MIN+1 + True + >>> test_add_sint(SINT_MAX, -1) == SINT_MAX-1 + True + >>> test_add_sint(SINT_MAX, 0) == SINT_MAX + True + >>> test_add_sint(SINT_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef SInt r = x + y + return r + +UINT_MAX = (-1) + +def test_uint(UInt x): + u""" + >>> test_uint(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> print(test_uint(0)) + 0 + >>> print(test_uint(1)) + 1 + >>> test_uint(UINT_MAX) == UINT_MAX + True + >>> test_uint(UINT_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_uint(x, y): + u""" + >>> test_add_uint(UINT_MAX, 0) == UINT_MAX + True + >>> test_add_uint(UINT_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef UInt r = x + y + return r + +# ------------------------------------------------------------------- + +SLONG_MAX = ((-1)>>1) +SLONG_MIN = (-SLONG_MAX-1) + +def test_slong(long x): + u""" + >>> test_slong(SLONG_MIN-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_slong(SLONG_MIN) == SLONG_MIN + True + >>> test_slong(-1) + -1 + >>> test_slong(0) + 0 + >>> test_slong(1) + 1 + >>> test_slong(SLONG_MAX) == SLONG_MAX + True + >>> test_slong(SLONG_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_slong(x, y): + u""" + >>> test_add_slong(SLONG_MIN, -1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_add_slong(SLONG_MIN, 0) == SLONG_MIN + True + >>> test_add_slong(SLONG_MIN, 1) == SLONG_MIN+1 + True + >>> test_add_slong(SLONG_MAX, -1) == SLONG_MAX-1 + True + >>> test_add_slong(SLONG_MAX, 0) == SLONG_MAX + True + >>> test_add_slong(SLONG_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef SLong r = x + y + return r + +ULONG_MAX = (-1) + +def test_ulong(ULong x): + u""" + >>> test_ulong(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> print(test_ulong(0)) + 0 + >>> print(test_ulong(1)) + 1 + >>> test_ulong(ULONG_MAX) == ULONG_MAX + True + >>> test_ulong(ULONG_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_ulong(x, y): + u""" + >>> test_add_ulong(ULONG_MAX, 0) == ULONG_MAX + True + >>> test_add_ulong(ULONG_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef ULong r = x + y + return r + +# ------------------------------------------------------------------- + +SLONGLONG_MAX = ((-1)>>1) +SLONGLONG_MIN = (-SLONGLONG_MAX-1) + +def test_slonglong(long long x): + u""" + >>> test_slonglong(SLONGLONG_MIN-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_slonglong(SLONGLONG_MIN) == SLONGLONG_MIN + True + >>> print(test_slonglong(-1)) + -1 + >>> print(test_slonglong(0)) + 0 + >>> print(test_slonglong(1)) + 1 + >>> test_slonglong(SLONGLONG_MAX) == SLONGLONG_MAX + True + >>> test_slonglong(SLONGLONG_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_slonglong(x, y): + u""" + >>> test_add_slonglong(SLONGLONG_MIN, -1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_add_slonglong(SLONGLONG_MIN, 0) == SLONGLONG_MIN + True + >>> test_add_slonglong(SLONGLONG_MIN, 1) == SLONGLONG_MIN+1 + True + >>> test_add_slonglong(SLONGLONG_MAX, -1) == SLONGLONG_MAX-1 + True + >>> test_add_slonglong(SLONGLONG_MAX, 0) == SLONGLONG_MAX + True + >>> test_add_slonglong(SLONGLONG_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef SLongLong r = x + y + return r + +ULONGLONG_MAX = (-1) + +def test_ulonglong(ULongLong x): + u""" + >>> test_ulonglong(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> print(test_ulonglong(0)) + 0 + >>> print(test_ulonglong(1)) + 1 + >>> test_ulonglong(ULONGLONG_MAX) == ULONGLONG_MAX + True + >>> test_ulonglong(ULONGLONG_MAX+1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + return x + +def test_add_ulonglong(x, y): + u""" + >>> test_add_ulonglong(ULONGLONG_MAX, 0) == ULONGLONG_MAX + True + >>> test_add_ulonglong(ULONGLONG_MAX, 1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + """ + cdef ULongLong r = x + y + return r + +# ------------------------------------------------------------------- + +cdef class MyClass: + """ + >>> a = MyClass() + + >>> vals = (SCHAR_MIN, UCHAR_MAX, + ... SSHORT_MIN, USHORT_MAX, + ... SINT_MIN, UINT_MAX, + ... SLONG_MIN, ULONG_MAX, + ... SLONGLONG_MIN, ULONGLONG_MAX) + >>> a.setvalues(*vals) + >>> a.getvalues() == vals + True + + >>> vals = (SCHAR_MAX, UCHAR_MAX, + ... SSHORT_MAX, USHORT_MAX, + ... SINT_MAX, UINT_MAX, + ... SLONG_MAX, ULONG_MAX, + ... SLONGLONG_MAX, ULONGLONG_MAX) + >>> a.setvalues(*vals) + >>> a.getvalues() == vals + True + + >>> vals = (0,) * 10 + >>> a.setvalues(*vals) + >>> a.getvalues() == vals + True + + + """ + cdef: + SChar attr_schar + UChar attr_uchar + SShort attr_sshort + UShort attr_ushort + SInt attr_sint + UInt attr_uint + SLong attr_slong + ULong attr_ulong + SLongLong attr_slonglong + ULongLong attr_ulonglong + + cpdef setvalues(self, + SChar arg_schar , + UChar arg_uchar , + SShort arg_sshort , + UShort arg_ushort , + SInt arg_sint , + UInt arg_uint , + SLong arg_slong , + ULong arg_ulong , + SLongLong arg_slonglong , + ULongLong arg_ulonglong ): + self.attr_schar = arg_schar + self.attr_uchar = arg_uchar + self.attr_sshort = arg_sshort + self.attr_ushort = arg_ushort + self.attr_sint = arg_sint + self.attr_uint = arg_uint + self.attr_slong = arg_slong + self.attr_ulong = arg_ulong + self.attr_slonglong = arg_slonglong + self.attr_ulonglong = arg_ulonglong + + cpdef getvalues(self): + return (self.attr_schar , + self.attr_uchar , + self.attr_sshort , + self.attr_ushort , + self.attr_sint , + self.attr_uint , + self.attr_slong , + self.attr_ulong , + self.attr_slonglong , + self.attr_ulonglong ) + + +# ------------------------------------------------------------------- + +cdef extern from *: + ctypedef signed MySInt1 "signed short" + ctypedef unsigned MyUInt1 "unsigned short" + +def test_MySInt1(MySInt1 x): + u""" + >>> test_MySInt1(-1) + -1 + >>> test_MySInt1(0) + 0 + >>> test_MySInt1(1) + 1 + """ + return x + +def test_MyUInt1(MyUInt1 x): + u""" + >>> test_MyUInt1(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_MyUInt1(0) + 0 + >>> test_MyUInt1(1) + 1 + """ + return x + +cdef extern from *: + ctypedef signed MySInt2 "signed short" + ctypedef unsigned MyUInt2 "unsigned short" + +def test_MySInt2(MySInt2 x): + u""" + >>> test_MySInt2(-1) + -1 + >>> test_MySInt2(0) + 0 + >>> test_MySInt2(1) + 1 + """ + return x + +def test_MyUInt2(MyUInt2 x): + u""" + >>> test_MyUInt2(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_MyUInt2(0) + 0 + >>> test_MyUInt2(1) + 1 + """ + return x + +# ------------------------------------------------------------------- + +cimport ctypedef_int_types_defs_T333 as defs + +def test_DefSInt(defs.SInt x): + u""" + >>> test_DeftSInt(-1) + -1 + >>> test_DefSInt(0) + 0 + >>> test_DefSInt(1) + 1 + """ + return x + +def test_DefUInt(defs.UInt x): + u""" + >>> test_DefUInt(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_DefUInt(0) + 0 + >>> test_DefUInt(1) + 1 + """ + return x + +def test_ExtSInt(defs.ExtSInt x): + u""" + >>> test_ExtSInt(-1) + -1 + >>> test_ExtSInt(0) + 0 + >>> test_ExtSInt(1) + 1 + """ + return x + +def test_ExtUInt(defs.ExtUInt x): + u""" + >>> test_ExtUInt(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_ExtUInt(0) + 0 + >>> test_ExtUInt(1) + 1 + """ + return x + + +ctypedef defs.SShort LocSInt +ctypedef defs.UShort LocUInt + +def test_LocSInt(LocSInt x): + u""" + >>> test_LocSInt(-1) + -1 + >>> test_LocSInt(0) + 0 + >>> test_LocSInt(1) + 1 + """ + return x + +def test_LocUInt(LocUInt x): + u""" + >>> test_LocUInt(-1) #doctest: +ELLIPSIS + Traceback (most recent call last): + ... + OverflowError: ... + >>> test_LocUInt(0) + 0 + >>> test_LocUInt(1) + 1 + """ + return x + +# ------------------------------------------------------------------- + +__doc__ = u"".join([ + f.__doc__ for f in ( + # + test_schar, test_add_schar, + test_uchar, test_add_uchar, + # + test_sshort, test_add_sshort, + test_ushort, test_add_ushort, + # + test_sint, test_add_sint, + test_uint, test_add_uint, + # + test_slong, test_add_slong, + test_ulong, test_add_ulong, + # + test_slonglong, test_add_slonglong, + test_ulonglong, test_add_ulonglong, + # + MyClass, + # + test_MySInt1, test_MyUInt1, + test_MySInt2, test_MyUInt2, + # + test_ExtSInt, test_ExtUInt, + test_LocSInt, test_LocUInt, + ) + ]) + +# ------------------------------------------------------------------- diff --git a/tests/run/ctypedef_int_types_chdr_T333.h b/tests/run/ctypedef_int_types_chdr_T333.h new file mode 100644 index 00000000..66b6158c --- /dev/null +++ b/tests/run/ctypedef_int_types_chdr_T333.h @@ -0,0 +1,10 @@ +typedef signed char SChar; +typedef unsigned char UChar; +typedef signed short SShort; +typedef unsigned short UShort; +typedef signed int SInt; +typedef unsigned int UInt; +typedef signed long SLong; +typedef unsigned long ULong; +typedef signed long long SLongLong; +typedef unsigned long long ULongLong; diff --git a/tests/run/ctypedef_int_types_defs_T333.pxd b/tests/run/ctypedef_int_types_defs_T333.pxd new file mode 100644 index 00000000..8fbe0f51 --- /dev/null +++ b/tests/run/ctypedef_int_types_defs_T333.pxd @@ -0,0 +1,15 @@ +cdef extern from "ctypedef_int_types_chdr_T333.h": + ctypedef int SChar ## "signed char" + ctypedef int UChar ## "unsigned char" + ctypedef int SShort ## "signed short" + ctypedef int UShort ## "unsigned short" + ctypedef int SInt ## "signed int" + ctypedef int UInt ## "unsigned int" + ctypedef int SLong ## "signed long" + ctypedef int ULong ## "unsigned long" + ctypedef int SLongLong ## "signed PY_LONG_LONG" + ctypedef int ULongLong ## "unsigned PY_LONG_LONG" + +cdef extern from *: + ctypedef int ExtSInt "signed short" + ctypedef int ExtUInt "unsigned short" -- 2.26.2