diff options
author | Pearu Peterson <pearu.peterson@gmail.com> | 2007-08-06 09:51:47 +0000 |
---|---|---|
committer | Pearu Peterson <pearu.peterson@gmail.com> | 2007-08-06 09:51:47 +0000 |
commit | 7a605b4d18a7d5283c5c3eb31b9258150e5755c5 (patch) | |
tree | 509bb4e91c08578eb4ef45db3f219027831d6f82 /numpy/f2py | |
parent | c7f8d0d531e263969c80f861df1b3e41bff6683b (diff) | |
download | numpy-7a605b4d18a7d5283c5c3eb31b9258150e5755c5.tar.gz |
extgen: Impl argument support to all Python types.
Diffstat (limited to 'numpy/f2py')
-rw-r--r-- | numpy/f2py/lib/extgen/base.py | 3 | ||||
-rw-r--r-- | numpy/f2py/lib/extgen/c_type.py | 138 | ||||
-rw-r--r-- | numpy/f2py/lib/extgen/doc.txt | 5 | ||||
-rw-r--r-- | numpy/f2py/lib/extgen/pyc_argument.py | 78 | ||||
-rw-r--r-- | numpy/f2py/lib/extgen/pyc_function.py | 18 |
5 files changed, 172 insertions, 70 deletions
diff --git a/numpy/f2py/lib/extgen/base.py b/numpy/f2py/lib/extgen/base.py index 62367b154..5bef4ba6d 100644 --- a/numpy/f2py/lib/extgen/base.py +++ b/numpy/f2py/lib/extgen/base.py @@ -98,6 +98,9 @@ class Component(object): # XXX: rename Component to Component """ Append component and its target container label to components list. """ + if isinstance(component, tuple) and len(component)==2 and isinstance(component[0], Component): + assert container_label is None, `container_label` + component, container_label = component if not isinstance(component, Component) and self.default_component_class_name!=component.__class__.__name__: clsname = self.default_component_class_name if clsname is not None: diff --git a/numpy/f2py/lib/extgen/c_type.py b/numpy/f2py/lib/extgen/c_type.py index 6d75105f7..aa4c8c4e1 100644 --- a/numpy/f2py/lib/extgen/c_type.py +++ b/numpy/f2py/lib/extgen/c_type.py @@ -4,7 +4,8 @@ C types. """ -__all__ = ['CType', 'CTypeAlias', 'CTypeFuncAlias', 'CTypePtr', 'CTypeStruct', 'CDecl'] +__all__ = ['CType', 'CTypeAlias', 'CTypeFuncAlias', 'CTypePtr', 'CTypeStruct', 'CDecl', + 'CTypePython'] from base import Component @@ -65,6 +66,10 @@ class CType(CTypeBase): """ def initialize(self, name): + if isinstance(name, CTypeBase): + return name + if isinstance(name, type) or name in ['cell', 'generator', 'cobject']: + return CTypePython(name) try: return Component.get(name) except KeyError: @@ -120,6 +125,7 @@ class CTypeFuncAlias(CTypeBase): if components: self.add(components[0], 'RCType') map(self.add, components[1:]) + return self class CTypePtr(CTypeBase): @@ -215,22 +221,139 @@ class CDecl(Component): map(self.add, names) return self -class PyObjectPtr(CType): - name = provides = 'PyObject*' - def initialize(self): return self +class CTypePython(CTypeBase): + + """ CTypePython(<python type object or 'cobject' or 'cell' or 'generator'>) + + >>> from __init__ import * #doctest: +ELLIPSIS + Ignoring... + >>> m = ExtensionModule('test_CTypePython') + >>> f = PyCFunction('func') + >>> f += PyCArgument('i', int, output_intent='return') + >>> f += PyCArgument('l', long, output_intent='return') + >>> f += PyCArgument('f', float, output_intent='return') + >>> f += PyCArgument('c', complex, output_intent='return') + >>> f += PyCArgument('s', str, output_intent='return') + >>> f += PyCArgument('u', unicode, output_intent='return') + >>> f += PyCArgument('t', tuple, output_intent='return') + >>> f += PyCArgument('lst', list, output_intent='return') + >>> f += PyCArgument('d', dict, output_intent='return') + >>> f += PyCArgument('set', set, output_intent='return') + >>> f += PyCArgument('o1', object, output_intent='return') + >>> f += PyCArgument('o2', object, output_intent='return') + >>> m += f + >>> b = m.build() #doctest: +ELLIPSIS + exec_command... + >>> b.func(23, 23l, 1.2, 1+2j, 'hello', u'hei', (2,'a'), [-2], {3:4}, set([1,2]), 2, '15') + (23, 23L, 1.2, (1+2j), 'hello', u'hei', (2, 'a'), [-2], {3: 4}, set([1, 2]), 2, '15') + + #>>> print b.func.__doc__ + + """ + @property + def provides(self): + return self.typeobj_name + def initialize(self, typeobj): + if isinstance(typeobj, type): + self.typeobj_name = typeobj.__name__ + elif isinstance(typeobj, str): + self.typeobj_name = typeobj + else: + raise ValueError('%s: unexpected input type %r' \ + % (self.__class__.__name__, type(typeobj))) + self.ctypeobj = dict(int='PyInt_Type', + long='PyLong_Type', + float='PyFloat_Type', + complex='PyComplex_Type', + str='PyString_Type', + unicode='PyUnicode_Type', + buffer='PyBuffer_Type', + tuple='PyTuple_Type', + list='PyList_Type', + dict='PyDict_Type', + file='PyFile_Type', + instance='PyInstance_Type', + function='PyFunction_Type', + method='PyMethod_Type', + module='PyModule_Type', + iter='PySeqIter_Type', + property='PyProperty_Type', + slice='PySlice_Type', + cell='PyCell_Type', + generator='PyGen_Type', + set='PySet_Type', + frozenset='PyFrozenSet_Type', + type='PyType_Type', + ).get(self.typeobj_name) + pyctypes = dict(int='PyIntObject', + long='PyLongObject', + float='PyFloatObject', + complex='PyComplexObject', + str='PyStringObject', + unicode='PyUnicodeObject', + buffer='PyBufferObject', + tuple='PyTupleObject', + list='PyListObject', + dict='PyDictObject', + file='PyFileObject', + instance='PyObject', + function='PyFunctionObject', + method='PyObject', + module='PyObject', + iter='PyObject', + property='PyObject', + slice='PyObject', + cobject='PyCObject', # XXX: check key + cell='PyCellObject', + type='PyTypeObject', + generator='PyGenObject', + set='PySetObject', + frozenset='PySetObject', + object='PyObject', + ) + try: + self.name = pyctypes[self.typeobj_name] + '*' + except KeyError: + raise NotImplementedError('%s: need %s support' % (self.__class__.__name__, typeobj)) + return self + + def set_titles(self, arg): + if self.typeobj_name == 'object': + tn = 'a python ' + self.typeobj_name + else: + tn = 'a python ' + self.typeobj_name + ' object' + if arg.input_intent!='hide': + r = '' + if arg.input_title: r = ', ' + arg.input_title + arg.input_title = tn + r + if arg.output_intent!='hide': + r = '' + if arg.output_title: r = ', ' + arg.output_title + arg.output_title = tn + r + def set_pyarg_decl(self, arg): if arg.input_intent=='hide': arg += CDecl(self, '%s = Py_None' % (arg.pycvar)) else: arg += CDecl(self, '%s = NULL' % (arg.pycvar)) - def get_pyarg_fmt(self, arg): return 'O' - def get_pyarg_obj(self, arg): return '&' + arg.pycvar + + def get_pyarg_fmt(self, arg): + return dict(object='O', str='S', unicode='U', cobject='O' + ).get(self.typeobj_name, 'O!') # XXX: check cobject + + def get_pyarg_obj(self, arg): + if self.typeobj_name in ['object', 'str', 'unicode', 'cobject']: # XXX: check cobject + return '&' + arg.pycvar + return '&%s, &%s' % (self.ctypeobj, arg.pycvar) + def get_pyret_fmt(self, arg): if arg.input_intent=='hide': return 'O' - return 'N' + # return 'N' if arg is constructed inside PyCFunction + return 'O' def get_pyret_obj(self, arg): return arg.pycvar + class CInt(CType): name = provides = 'int' def initialize(self): return self @@ -244,7 +367,6 @@ class CInt(CType): def register(): Component.register( - PyObjectPtr(), CInt(), ) diff --git a/numpy/f2py/lib/extgen/doc.txt b/numpy/f2py/lib/extgen/doc.txt index 73908caca..9bd777bf4 100644 --- a/numpy/f2py/lib/extgen/doc.txt +++ b/numpy/f2py/lib/extgen/doc.txt @@ -286,6 +286,9 @@ ExtGen package defines the following extension module component classes: - `CDecl(<ctype>, *names)` --- represents `ctype name1, name2, ..;` declaration. Use `.add()` method to add more names. + -`CTypePython(<python type object or 'cell' or 'generator' or 'cobject'>)` + --- represents python type object in C. + Predefined components ===================== @@ -301,5 +304,3 @@ using `Component.get(<provides>)` method: module. - `'int'` - C `int` type support - -- `'PyObject*'` - `PyObject*` type support
\ No newline at end of file diff --git a/numpy/f2py/lib/extgen/pyc_argument.py b/numpy/f2py/lib/extgen/pyc_argument.py index d834e406d..c8667f2d8 100644 --- a/numpy/f2py/lib/extgen/pyc_argument.py +++ b/numpy/f2py/lib/extgen/pyc_argument.py @@ -37,9 +37,12 @@ class PyCArgument(Component): self.pycvar = name + '_pyc' if ctype is None: - ctype = Component.get('PyObject*') + ctype = Component.CTypePython(object) + else: + ctype = Component.CType(ctype) self.ctype = ctype ctype.set_pyarg_decl(self) + ctype.set_titles(self) #self.add(ctype) return self @@ -48,34 +51,7 @@ class PyCArgument(Component): evaluate = self.evaluate ctype = self.ctype - # get containers - ReqArgs = self.container_ReqArgs - OptArgs = self.container_OptArgs - ExtArgs = self.container_ExtArgs - RetArgs = self.container_RetArgs - - ReqArgsDoc = self.container_ReqArgsDoc - OptArgsDoc = self.container_OptArgsDoc - ExtArgsDoc = self.container_ExtArgsDoc - - ReqKWList = self.container_ReqKWList - OptKWList = self.container_OptKWList - ExtKWList = self.container_ExtKWList - - ReqPyArgFmt = self.container_ReqPyArgFmt - OptPyArgFmt = self.container_OptPyArgFmt - ExtPyArgFmt = self.container_ExtPyArgFmt - - ReqPyArgObj = self.container_ReqPyArgObj - OptPyArgObj = self.container_OptPyArgObj - ExtPyArgObj = self.container_ExtPyArgObj - - RetDoc = self.container_RetDoc - RetFmt = self.container_RetFmt - RetObj = self.container_RetObj - # update PyCFunction containers - input_doc_title = '%s - %s' % (self.name, self.input_title) output_doc_title = '%s - %s' % (self.name, self.output_title) if self.input_description is not None: @@ -88,37 +64,37 @@ class PyCArgument(Component): output_doc_descr = None if self.input_intent=='required': - ReqArgs += self.name - ReqKWList += '"' + self.name + '"' - ReqPyArgFmt += ctype.get_pyarg_fmt(self) - ReqPyArgObj += ctype.get_pyarg_obj(self) - ReqArgsDoc += input_doc_title - ReqArgsDoc += input_doc_descr + self.container_ReqArgs += self.name + self.container_ReqKWList += '"' + self.name + '"' + self.container_ReqPyArgFmt += ctype.get_pyarg_fmt(self) + self.container_ReqPyArgObj += ctype.get_pyarg_obj(self) + self.container_ReqArgsDoc += input_doc_title + self.container_ReqArgsDoc += input_doc_descr elif self.input_intent=='optional': - OptArgs += self.name - OptKWList += '"' + self.name + '"' - OptPyArgFmt += ctype.get_pyarg_fmt(self) - OptPyArgObj += ctype.get_pyarg_obj(self) - OptArgsDoc += input_doc_title - OptArgsDoc += input_doc_descr + self.container_OptArgs += self.name + self.container_OptKWList += '"' + self.name + '"' + self.container_OptPyArgFmt += ctype.get_pyarg_fmt(self) + self.container_OptPyArgObj += ctype.get_pyarg_obj(self) + self.container_OptArgsDoc += input_doc_title + self.container_OptArgsDoc += input_doc_descr elif self.input_intent=='extra': - ExtArgs += self.name - ExtKWList += '"' + self.name + '"' - ExtPyArgFmt += ctype.get_pyarg_fmt(self) - ExtPyArgObj += ctype.get_pyarg_obj(self) - ExtArgsDoc += input_doc_title - ExtArgsDoc += input_doc_descr + self.container_ExtArgs += self.name + self.container_ExtKWList += '"' + self.name + '"' + self.container_ExtPyArgFmt += ctype.get_pyarg_fmt(self) + self.container_ExtPyArgObj += ctype.get_pyarg_obj(self) + self.container_ExtArgsDoc += input_doc_title + self.container_ExtArgsDoc += input_doc_descr elif self.input_intent=='hide': pass else: raise NotImplementedError('input_intent=%r' % (self.input_intent)) if self.output_intent=='return': - RetArgs += self.name - RetFmt += ctype.get_pyret_fmt(self) - RetObj += ctype.get_pyret_obj(self) - RetDoc += output_doc_title - RetDoc += output_doc_descr + self.container_RetArgs += self.name + self.container_RetFmt += ctype.get_pyret_fmt(self) + self.container_RetObj += ctype.get_pyret_obj(self) + self.container_RetDoc += output_doc_title + self.container_RetDoc += output_doc_descr elif self.output_intent=='hide': pass else: diff --git a/numpy/f2py/lib/extgen/pyc_function.py b/numpy/f2py/lib/extgen/pyc_function.py index 65e18fc5a..1cdbaeb1a 100644 --- a/numpy/f2py/lib/extgen/pyc_function.py +++ b/numpy/f2py/lib/extgen/pyc_function.py @@ -11,7 +11,7 @@ class PyCFunction(Component): >>> f = PyCFunction('hello', title='A function.', description='\\nFirst line.\\n2nd line.') >>> a1_in_doc = '''First line.\\nSecond line.''' >>> a1_out_doc = '''Single line.''' - >>> f += PyCArgument('a1',output_intent='return', input_title='a Python object', + >>> f += PyCArgument('a1',output_intent='return', input_title='anything', ... input_description=a1_in_doc, output_description=a1_out_doc) >>> f += PyCArgument('c1',input_intent='extra') >>> f += PyCArgument('b1',input_intent='optional') @@ -28,23 +28,23 @@ class PyCFunction(Component): A function. <BLANKLINE> Required arguments: - a1 - a Python object + a1 - a python object, anything First line. Second line. - a2 - None + a2 - a python object <BLANKLINE> Optional arguments: - b1 - None - b2 - None + b1 - a python object + b2 - a python object <BLANKLINE> Extra optional arguments: - c1 - None - c2 - None + c1 - a python object + c2 - a python object <BLANKLINE> Return values: - a1 - None + a1 - a python object Single line. - d2 - None + d2 - a python object <BLANKLINE> Description: <BLANKLINE> |