From e69df6855fd73c00c21e5f124fdd564acb3fc675 Mon Sep 17 00:00:00 2001 From: Stefan Behnel <stefan_ml@behnel.de> Date: Sat, 11 Oct 2014 08:36:08 +0200 Subject: [PATCH] use normal argument type conversion in cfunc wrapper for types that support it --- Cython/Compiler/PyrexTypes.py | 39 +++++++++++++++++++++------------ Cython/Utility/CFuncConvert.pyx | 2 +- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index 32808c8f2..b67c2f5bb 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -2659,39 +2659,50 @@ class CFuncType(CType): for arg in self.args: if not arg.type.is_pyobject and not arg.type.create_from_py_utility_code(env): return False - if arg.type.is_extension_type or arg.type.is_builtin_type: + if arg.type.is_extension_type: env.use_utility_code(UtilityCode.load_cached("ExtTypeTest", "ObjectHandling.c")) + def declared_type(ix, ctype): + py_arg_type = '' + type_convert = '' + type_name = 'TYPE%s' % ix + type_cname = ctype.declaration_code("") + type_displayname = str(ctype.declaration_code("", for_display=True)) + if ctype.is_builtin_type: + py_arg_type = ctype.name + elif ctype.is_extension_type: + type_convert = '<%s>' % type_name + elif ctype.is_pyobject: + type_convert = '' + elif ctype.is_typedef or ctype.is_struct_or_union: + type_convert = '%s_to_py' % type_name + else: + type_name = py_arg_type = type_displayname + return type_name, type_cname, py_arg_type, type_displayname, type_convert + class Arg(object): def __init__(self, ix, arg): self.ix = ix self.name = arg.name or 'ARG%s' % ix self.type = arg.type - self.type_name = 'TYPE%s' % ix - self.type_cname = self.type.declaration_code("") - self.type_displayname = str(self.type.declaration_code("", for_display=True)) - if self.type.is_extension_type or self.type.is_builtin_type: - self.type_convert = '<%s>' % self.type_name - elif self.type.is_pyobject: - self.type_convert = '' - else: - self.type_convert = '%s_to_py' % self.type_name + self.type_name, self.type_cname, self.py_arg_type, self.type_displayname, self.type_convert = ( + declared_type(ix, self.type)) def declare_type_def(self): - if self.type.is_extension_type or self.type.is_builtin_type or not self.type.is_pyobject: + if self.type.is_extension_type or (not self.type.is_pyobject and not self.py_arg_type): return 'ctypedef void* %s "%s"' % (self.type_name, self.type_cname) def declare_type_convert(self): - if self.type.is_extension_type or self.type.is_builtin_type: + if self.type.is_extension_type: return 'cdef PyTypeObject* %s_TYPE "%s"' % (self.type_name, self.type.typeptr_cname) elif self.type.is_pyobject: return '' - else: + elif not self.py_arg_type: return 'cdef %s %s "%s"(object) except *' % ( self.type_name, self.type_convert, self.type.from_py_function) def check_type(self): - if self.type.is_extension_type or self.type.is_builtin_type: + if self.type.is_extension_type: return '__Pyx_TypeTest(<PyObject*>%s, %s_TYPE)' % (self.name, self.type_name) if self.return_type.is_void: diff --git a/Cython/Utility/CFuncConvert.pyx b/Cython/Utility/CFuncConvert.pyx index 7af465377..73ca28116 100644 --- a/Cython/Utility/CFuncConvert.pyx +++ b/Cython/Utility/CFuncConvert.pyx @@ -13,7 +13,7 @@ cdef extern from *: @cname("{{cname}}") cdef object {{cname}}({{return_type}} (*f)({{ ', '.join(arg.type_name for arg in args) }}) {{except_clause}}): - def wrap({{ ', '.join(arg.name for arg in args) }}): + def wrap({{ ', '.join('{arg.py_arg_type} {arg.name}'.format(arg=arg) for arg in args) }}): """wrap({{', '.join('{arg.name}: {arg.type_displayname!r}'.format(arg=arg) for arg in args)}})""" {{for arg in args}} {{arg.check_type()}} -- 2.30.9