[Numpy-svn] r3948 - trunk/numpy/f2py/lib/extgen

numpy-svn at scipy.org numpy-svn at scipy.org
Mon Aug 6 05:51:58 EDT 2007


Author: pearu
Date: 2007-08-06 04:51:47 -0500 (Mon, 06 Aug 2007)
New Revision: 3948

Modified:
   trunk/numpy/f2py/lib/extgen/base.py
   trunk/numpy/f2py/lib/extgen/c_type.py
   trunk/numpy/f2py/lib/extgen/doc.txt
   trunk/numpy/f2py/lib/extgen/pyc_argument.py
   trunk/numpy/f2py/lib/extgen/pyc_function.py
Log:
extgen: Impl argument support to all Python types.

Modified: trunk/numpy/f2py/lib/extgen/base.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/base.py	2007-08-05 21:13:49 UTC (rev 3947)
+++ trunk/numpy/f2py/lib/extgen/base.py	2007-08-06 09:51:47 UTC (rev 3948)
@@ -98,6 +98,9 @@
         """
         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:

Modified: trunk/numpy/f2py/lib/extgen/c_type.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/c_type.py	2007-08-05 21:13:49 UTC (rev 3947)
+++ trunk/numpy/f2py/lib/extgen/c_type.py	2007-08-06 09:51:47 UTC (rev 3948)
@@ -4,7 +4,8 @@
 
 """
 
-__all__ = ['CType', 'CTypeAlias', 'CTypeFuncAlias', 'CTypePtr', 'CTypeStruct', 'CDecl']
+__all__ = ['CType', 'CTypeAlias', 'CTypeFuncAlias', 'CTypePtr', 'CTypeStruct', 'CDecl',
+           'CTypePython']
 
 from base import Component
 
@@ -65,6 +66,10 @@
     """
 
     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 @@
         if components:
             self.add(components[0], 'RCType')
         map(self.add, components[1:])
+        return self
 
 class CTypePtr(CTypeBase):
 
@@ -215,22 +221,139 @@
         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 @@
 
 def register():
     Component.register(
-        PyObjectPtr(),
         CInt(),
         )
 

Modified: trunk/numpy/f2py/lib/extgen/doc.txt
===================================================================
--- trunk/numpy/f2py/lib/extgen/doc.txt	2007-08-05 21:13:49 UTC (rev 3947)
+++ trunk/numpy/f2py/lib/extgen/doc.txt	2007-08-06 09:51:47 UTC (rev 3948)
@@ -286,7 +286,10 @@
   - `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 @@
   module.
 
 - `'int'` - C `int` type support
-
-- `'PyObject*'` - `PyObject*` type support
\ No newline at end of file

Modified: trunk/numpy/f2py/lib/extgen/pyc_argument.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/pyc_argument.py	2007-08-05 21:13:49 UTC (rev 3947)
+++ trunk/numpy/f2py/lib/extgen/pyc_argument.py	2007-08-06 09:51:47 UTC (rev 3948)
@@ -37,9 +37,12 @@
         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 @@
         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 @@
             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:

Modified: trunk/numpy/f2py/lib/extgen/pyc_function.py
===================================================================
--- trunk/numpy/f2py/lib/extgen/pyc_function.py	2007-08-05 21:13:49 UTC (rev 3947)
+++ trunk/numpy/f2py/lib/extgen/pyc_function.py	2007-08-06 09:51:47 UTC (rev 3948)
@@ -11,7 +11,7 @@
     >>> 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 @@
     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>




More information about the Numpy-svn mailing list