[Numpy-svn] r3292 - in trunk/numpy/f2py/lib: . parser

numpy-svn at scipy.org numpy-svn at scipy.org
Sun Oct 8 08:16:24 CDT 2006


Author: pearu
Date: 2006-10-08 08:16:13 -0500 (Sun, 08 Oct 2006)
New Revision: 3292

Added:
   trunk/numpy/f2py/lib/test_derived_scalar.py
Modified:
   trunk/numpy/f2py/lib/main.py
   trunk/numpy/f2py/lib/parser/base_classes.py
   trunk/numpy/f2py/lib/parser/block_statements.py
   trunk/numpy/f2py/lib/parser/statements.py
   trunk/numpy/f2py/lib/parser/typedecl_statements.py
   trunk/numpy/f2py/lib/py_wrap_type.py
   trunk/numpy/f2py/lib/test_scalar_in_out.py
Log:
F2PY G3: added simple test for subroutine with derived type intent(in,out) argument. Fixed bugs.

Modified: trunk/numpy/f2py/lib/main.py
===================================================================
--- trunk/numpy/f2py/lib/main.py	2006-10-08 09:38:12 UTC (rev 3291)
+++ trunk/numpy/f2py/lib/main.py	2006-10-08 13:16:13 UTC (rev 3292)
@@ -44,6 +44,56 @@
   --2d-numeric     Use f2py2e tool with Numeric support.
   --2d-numarray    Use f2py2e tool with Numarray support.
 
+  -m <modulename>  Name of the module; f2py generates a Python/C API
+                   file <modulename>module.c or extension module <modulename>.
+                   For wrapping Fortran 90 modules, f2py will use Fortran
+                   module names.
+
+
+Options effective only with -h
+------------------------------
+
+  -h <filename>    Write signatures of the fortran routines to file <filename>
+                   and exit. You can then edit <filename> and use it instead
+                   of <fortran files> for generating extension module source.
+                   If <filename> is stdout or stderr then the signatures are
+                   printed to the corresponding stream.
+
+  --overwrite-signature  Overwrite existing signature file.
+
+Options effective only with -c
+------------------------------
+
+  -c               Compile fortran sources and build extension module.
+
+  --build-dir <dirname>  All f2py generated files are created in <dirname>.
+                   Default is tempfile.mktemp() and it will be removed after
+                   f2py stops unless <dirname> is specified via --build-dir
+                   option.
+
+numpy.distutils options effective only with -c
+----------------------------------------------
+
+  --fcompiler=<name>      Specify Fortran compiler type by vendor
+
+
+
+Extra options effective only with -c
+------------------------------------
+
+  -L/path/to/lib/ -l<libname>
+  -D<name[=define]> -U<name>
+  -I/path/to/include/
+  <filename>.o <filename>.(so|dynlib|dll) <filename>.a
+
+  Using the following macros may be required with non-gcc Fortran
+  compilers:
+    -DPREPEND_FORTRAN -DNO_APPEND_FORTRAN -DUPPERCASE_FORTRAN
+    -DUNDERSCORE_G77
+
+  -DF2PY_DEBUG_PYOBJ_TOFROM  --- pyobj_(to|from)_<ctype> functions will
+  print debugging messages to stderr.
+
 """
 
 import re
@@ -266,6 +316,7 @@
                                  undef_macros = undef_macros,
                                  include_dirs = include_dirs,
                                  extra_objects = extra_objects,
+                                 language = 'f90',
                                  )
         if external_subprograms:
             wrapper = PythonWrapperModule(modulename)

Modified: trunk/numpy/f2py/lib/parser/base_classes.py
===================================================================
--- trunk/numpy/f2py/lib/parser/base_classes.py	2006-10-08 09:38:12 UTC (rev 3291)
+++ trunk/numpy/f2py/lib/parser/base_classes.py	2006-10-08 13:16:13 UTC (rev 3292)
@@ -426,8 +426,9 @@
             l.append(ttab + 'a=' + self.a.torepr(depth-1,incrtab+'  ').lstrip())
         return '\n'.join(l)
 
-    def get_indent_tab(self,colon=None,deindent=False):
-        if self.reader.isfix:
+    def get_indent_tab(self,colon=None,deindent=False,isfix=None):
+        if isfix is None: isfix = self.reader.isfix
+        if isfix:
             tab = ' '*6
         else:
             tab = ''
@@ -441,19 +442,35 @@
             return tab
         s = self.item.label
         if colon is None:
-            if self.reader.isfix:
+            if isfix:
                 colon = ''
             else:
                 colon = ':'
         if s:
             c = ''
-            if self.reader.isfix:
+            if isfix:
                 c = ' '
             tab = tab[len(c+s)+len(colon):]
             if not tab: tab = ' '
             tab = c + s + colon + tab
         return tab
 
+    def __str__(self):
+        return self.tofortran()
+
+    def asfix(self):
+        lines = []
+        for line in self.tofortran(isfix=True).split('\n'):
+            if len(line)>72 and line[0]==' ':
+                lines.append(line[:72]+'&\n     &')
+                line = line[72:]
+                while len(line)>66:
+                    lines.append(line[:66]+'&\n     &')
+                    line = line[66:]
+                lines.append(line+'\n')
+            else: lines.append(line+'\n')
+        return ''.join(lines).replace('\n     &\n','\n')
+        
     def format_message(self, kind, message):
         if self.item is not None:
             message = self.reader.format_message(kind, message,
@@ -544,11 +561,11 @@
 
     def tostr(self):
         return self.blocktype.upper() + ' '+ self.name
-    
-    def __str__(self):
-        l=[self.get_indent_tab(colon=':') + self.tostr()]
+
+    def tofortran(self, isfix=None):
+        l=[self.get_indent_tab(colon=':', isfix=isfix) + self.tostr()]
         for c in self.content:
-            l.append(str(c))
+            l.append(c.tofortran(isfix=isfix))
         return '\n'.join(l)
 
     def torepr(self, depth=-1, incrtab=''):
@@ -736,10 +753,10 @@
     def analyze(self):
         return
 
-    def get_indent_tab(self,colon=None,deindent=False):
-        return Statement.get_indent_tab(self, colon=colon, deindent=True)
+    def get_indent_tab(self,colon=None,deindent=False,isfix=None):
+        return Statement.get_indent_tab(self, colon=colon, deindent=True,isfix=isfix)
 
-    def __str__(self):
-        return self.get_indent_tab() + 'END %s %s'\
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'END %s %s'\
                % (self.blocktype.upper(),self.name or '')
 

Modified: trunk/numpy/f2py/lib/parser/block_statements.py
===================================================================
--- trunk/numpy/f2py/lib/parser/block_statements.py	2006-10-08 09:38:12 UTC (rev 3291)
+++ trunk/numpy/f2py/lib/parser/block_statements.py	2006-10-08 13:16:13 UTC (rev 3292)
@@ -846,8 +846,8 @@
         assert len(self.content)==1,`self.content`
         return 'IF (%s) %s' % (self.expr, str(self.content[0]).lstrip())
 
-    def __str__(self):
-        return self.get_indent_tab(colon=':') + self.tostr()
+    def tofortran(self,isfix=None):
+        return self.get_indent_tab(colon=':',isfix=isfix) + self.tostr()
 
     def get_classes(self):
         return action_stmt

Modified: trunk/numpy/f2py/lib/parser/statements.py
===================================================================
--- trunk/numpy/f2py/lib/parser/statements.py	2006-10-08 09:38:12 UTC (rev 3291)
+++ trunk/numpy/f2py/lib/parser/statements.py	2006-10-08 13:16:13 UTC (rev 3292)
@@ -56,7 +56,8 @@
                 return
             items.append(item)
         return
-    def __str__(self):
+
+    def tofortran(self,isfix=None):
         if hasattr(self,'stmtname'):
             clsname = self.stmtname.upper()
         else:
@@ -64,7 +65,7 @@
         s = ', '.join(self.items)
         if s:
             s = ' ' + s
-        return self.get_indent_tab() + clsname + s
+        return self.get_indent_tab(isfix=isfix) + clsname + s
 
 # Execution statements
 
@@ -100,8 +101,8 @@
         self.expr = apply_map(m.group('expr'))
         return
 
-    def __str__(self):
-        return self.get_indent_tab() + '%s %s %s' \
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + '%s %s %s' \
                % (self.variable, self.sign, self.expr)
 
     def analyze(self): return
@@ -124,8 +125,8 @@
         assert not self.item.has_map()
         self.items = [line[:i].rstrip(),line[i+2:].lstrip()]
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'ASSIGN %s TO %s' \
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'ASSIGN %s TO %s' \
                % (self.items[0], self.items[1])
     def analyze(self): return
 
@@ -173,8 +174,8 @@
         self.items = items
         return
 
-    def __str__(self):
-        s = self.get_indent_tab() + 'CALL '+str(self.designator)
+    def tofortran(self, isfix=None):
+        s = self.get_indent_tab(isfix=isfix) + 'CALL '+str(self.designator)
         if self.items:
             s += '('+', '.join(map(str,self.items))+ ')'
         return s
@@ -199,8 +200,8 @@
         self.label = self.item.get_line()[2:].lstrip()[2:].lstrip()
         return
 
-    def __str__(self):
-        return self.get_indent_tab() + 'GO TO %s' % (self.label)
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'GO TO %s' % (self.label)
     def analyze(self): return
 
 class ComputedGoto(Statement):
@@ -218,8 +219,8 @@
             line = line[1:].lstrip()
         self.expr = apply_map(line)
         return
-    def __str__(self):
-        return  self.get_indent_tab() + 'GO TO (%s) %s' \
+    def tofortran(self, isfix=None):
+        return  self.get_indent_tab(isfix=isfix) + 'GO TO (%s) %s' \
                % (', '.join(self.items), self.expr)
     def analyze(self): return
 
@@ -242,8 +243,8 @@
         self.items = split_comma(line[i+1:-1], self.item)
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         if self.items:
             return tab + 'GO TO %s (%s)' \
                    % (self.varname, ', '.join(self.items)) 
@@ -260,7 +261,7 @@
         self.label = self.item.label
         return
 
-    def __str__(self):
+    def tofortran(self, isfix=None):
         return self.get_indent_tab(deindent=True) + 'CONTINUE'
 
     def analyze(self): return
@@ -275,8 +276,8 @@
         self.expr = self.item.apply_map(self.item.get_line()[6:].lstrip())
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         if self.expr:
             return tab + 'RETURN %s' % (self.expr)
         return tab + 'RETURN'
@@ -294,8 +295,8 @@
         self.code = self.item.apply_map(self.item.get_line()[4:].lstrip())
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         if self.code:
             return tab + 'STOP %s' % (self.code)
         return tab + 'STOP'
@@ -324,8 +325,8 @@
         self.items = items[1:]
         return
 
-    def __str__(self):
-        return self.get_indent_tab() + 'PRINT %s' \
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'PRINT %s' \
                % (', '.join([self.format]+self.items))
     def analyze(self): return
 
@@ -365,8 +366,8 @@
         self.items = split_comma(line[i+1:], item)
         return
 
-    def __str__(self):
-        s = self.get_indent_tab() + 'READ (%s)' % (', '.join(self.specs))
+    def tofortran(self, isfix=None):
+        s = self.get_indent_tab(isfix=isfix) + 'READ (%s)' % (', '.join(self.specs))
         if self.items:
             return s + ' ' + ', '.join(self.items)
         return s
@@ -381,8 +382,8 @@
         self.items = items[1:]
         return
 
-    def __str__(self):
-        return self.get_indent_tab() + 'READ ' \
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'READ ' \
                + ', '.join([self.format]+self.items)
 
 class Write(Statement):
@@ -399,8 +400,8 @@
         self.items = split_comma(line[i+1:], item)
         return
 
-    def __str__(self):
-        s = self.get_indent_tab() + 'WRITE (%s)' % ', '.join(self.specs)
+    def tofortran(self, isfix=None):
+        s = self.get_indent_tab(isfix=isfix) + 'WRITE (%s)' % ', '.join(self.specs)
         if self.items:
             s += ' ' + ', '.join(self.items)
         return s
@@ -430,8 +431,8 @@
             self.specs = specs_split_comma(line,self.item)
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         return tab + 'FLUSH (%s)' % (', '.join(self.specs))
     def analyze(self): return
 
@@ -452,8 +453,8 @@
         self.specs = specs_split_comma(\
             self.item.get_line()[4:].lstrip()[1:-1], self.item)
         return
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         return tab + 'WAIT (%s)' % (', '.join(self.specs))
     def analyze(self): return
 
@@ -463,7 +464,7 @@
     """
     match = re.compile(r'contains\Z',re.I).match
     def process_item(self): return
-    def __str__(self): return self.get_indent_tab() + 'CONTAINS'
+    def tofortran(self, isfix=None): return self.get_indent_tab(isfix=isfix) + 'CONTAINS'
 
 class Allocate(Statement):
     """
@@ -499,11 +500,11 @@
         self.items = specs_split_comma(line2, item2)
         return
 
-    def __str__(self):
+    def tofortran(self, isfix=None):
         t = ''
         if self.spec:
             t = self.spec.tostr() + ' :: '
-        return self.get_indent_tab() \
+        return self.get_indent_tab(isfix=isfix) \
                + 'ALLOCATE (%s%s)' % (t,', '.join(self.items))
     def analyze(self): return
 
@@ -521,7 +522,7 @@
         line = self.item.get_line()[10:].lstrip()[1:-1].strip()
         self.items = specs_split_comma(line, self.item)
         return
-    def __str__(self): return self.get_indent_tab() \
+    def tofortran(self, isfix=None): return self.get_indent_tab(isfix=isfix) \
         + 'DEALLOCATE (%s)' % (', '.join(self.items))
     def analyze(self): return
     
@@ -542,8 +543,8 @@
         self.items = items
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         return tab + 'MODULE PROCEDURE %s' % (', '.join(self.items))
 
     def analyze(self):
@@ -571,9 +572,9 @@
         self.items = split_comma(line, self.item)
         return
 
-    def __str__(self):
+    def tofortran(self, isfix=None):
         clsname = self.__class__.__name__.upper()
-        tab = self.get_indent_tab()
+        tab = self.get_indent_tab(isfix=isfix)
         if self.items:
             return tab + clsname + ' ' + ', '.join(self.items)
         return tab + clsname
@@ -607,8 +608,8 @@
         line = self.item.get_line()[5:].lstrip()[1:-1].strip()
         self.specs = specs_split_comma(line, self.item)
         return
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         return tab + 'CLOSE (%s)' % (', '.join(self.specs))
     def analyze(self): return
 
@@ -620,10 +621,10 @@
     def process_item(self):
         self.name = self.item.get_line()[5:].lstrip()
         return
-    def __str__(self):
+    def tofortran(self, isfix=None):
         if self.name:
-            return self.get_indent_tab() + 'CYCLE ' + self.name
-        return self.get_indent_tab() + 'CYCLE'
+            return self.get_indent_tab(isfix=isfix) + 'CYCLE ' + self.name
+        return self.get_indent_tab(isfix=isfix) + 'CYCLE'
     def analyze(self): return
 
 class FilePositioningStatement(Statement):
@@ -653,9 +654,9 @@
         self.specs = specs_split_comma(spec, self.item)
         return
 
-    def __str__(self):
+    def tofortran(self, isfix=None):
         clsname = self.__class__.__name__.upper()
-        return self.get_indent_tab() + clsname + ' (%s)' % (', '.join(self.specs))
+        return self.get_indent_tab(isfix=isfix) + clsname + ' (%s)' % (', '.join(self.specs))
     def analyze(self): return
 
 class Backspace(FilePositioningStatement): pass
@@ -676,8 +677,8 @@
         line = self.item.get_line()[4:].lstrip()[1:-1].strip()
         self.specs = specs_split_comma(line, self.item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'OPEN (%s)' % (', '.join(self.specs))
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'OPEN (%s)' % (', '.join(self.specs))
     def analyze(self): return
 
 class Format(Statement):
@@ -715,8 +716,8 @@
         assert line[0]+line[-1]=='()',`line`
         self.specs = split_comma(line[1:-1], item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'FORMAT (%s)' % (', '.join(self.specs))
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'FORMAT (%s)' % (', '.join(self.specs))
     def analyze(self): return
 
 class Save(Statement):
@@ -750,8 +751,8 @@
                 return
         self.items = items
         return
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         if not self.items:
             return tab + 'SAVE'
         return tab + 'SAVE %s' % (', '.join(self.items))
@@ -797,8 +798,8 @@
         self.isvalid = True
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         l = []
         for o,v in self.stmts:
             l.append('%s / %s /' %(', '.join(o),', '.join(v)))
@@ -815,8 +816,8 @@
         line = self.item.get_line()[7:].lstrip()[1:-1].strip()
         self.items = split_comma(line, self.item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'NULLIFY (%s)' % (', '.join(self.items))
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'NULLIFY (%s)' % (', '.join(self.items))
     def analyze(self): return
 
 class Use(Statement):
@@ -857,8 +858,8 @@
             self.items = split_comma(line, self.item)
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         s = 'USE'
         if self.nature:
             s += ' ' + self.nature + ' ::'
@@ -912,10 +913,10 @@
     def process_item(self):
         self.name = self.item.get_line()[4:].lstrip()
         return
-    def __str__(self):
+    def tofortran(self, isfix=None):
         if self.name:
-            return self.get_indent_tab() + 'EXIT ' + self.name
-        return self.get_indent_tab() + 'EXIT'
+            return self.get_indent_tab(isfix=isfix) + 'EXIT ' + self.name
+        return self.get_indent_tab(isfix=isfix) + 'EXIT'
     def analyze(self): return
 
 class Parameter(Statement):
@@ -928,8 +929,8 @@
         line = self.item.get_line()[9:].lstrip()[1:-1].strip()
         self.items = split_comma(line, self.item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'PARAMETER (%s)' % (', '.join(self.items))
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'PARAMETER (%s)' % (', '.join(self.items))
     def analyze(self):
         for item in self.items:
             i = item.find('=')
@@ -957,8 +958,8 @@
             items.append('('+s+')')
         self.items = items
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'EQUIVALENCE %s' % (', '.join(self.items))
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'EQUIVALENCE %s' % (', '.join(self.items))
     def analyze(self): return
 
 class Dimension(Statement):
@@ -973,8 +974,8 @@
             line = line[2:].lstrip()
         self.items = split_comma(line, self.item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'DIMENSION %s' % (', '.join(self.items))
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'DIMENSION %s' % (', '.join(self.items))
     def analyze(self):
         for line in self.items:
             i = line.find('(')
@@ -997,8 +998,8 @@
             line = line[2:].lstrip()
         self.items = split_comma(line, self.item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'TARGET %s' % (', '.join(self.items))
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'TARGET %s' % (', '.join(self.items))
     def analyze(self):
         for line in self.items:
             i = line.find('(')
@@ -1025,8 +1026,8 @@
             line = line[2:].lstrip()
         self.items = split_comma(line, self.item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'POINTER %s' % (', '.join(self.items))
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'POINTER %s' % (', '.join(self.items))
     def analyze(self):
         for line in self.items:
             i = line.find('(')
@@ -1089,8 +1090,8 @@
         self.labels = [l1.strip(),l2.strip(),l3.strip()]
         return
 
-    def __str__(self):
-        return self.get_indent_tab() + 'IF (%s) %s' \
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'IF (%s) %s' \
                % (self.expr,', '.join(self.labels))
     def analyze(self): return
 
@@ -1123,11 +1124,11 @@
         self.specs = specs_split_comma(line[1:i].strip(), self.item)
         self.items = split_comma(line[i+1:].lstrip(), self.item)
         return
-    def __str__(self):
+    def tofortran(self, isfix=None):
         if self.items:
-            return self.get_indent_tab() + 'INQUIRE (%s) %s' \
+            return self.get_indent_tab(isfix=isfix) + 'INQUIRE (%s) %s' \
                    % (', '.join(self.specs), ', '.join(self.items))
-        return self.get_indent_tab() + 'INQUIRE (%s)' \
+        return self.get_indent_tab(isfix=isfix) + 'INQUIRE (%s)' \
                    % (', '.join(self.specs))
     def analyze(self): return
 
@@ -1138,7 +1139,7 @@
     match = re.compile(r'sequence\Z',re.I).match
     def process_item(self):
         return
-    def __str__(self): return self.get_indent_tab() + 'SEQUENCE'
+    def tofortran(self, isfix=None): return self.get_indent_tab(isfix=isfix) + 'SEQUENCE'
     def analyze(self):
         self.parent.update_attributes('SEQUENCE')
         return
@@ -1183,11 +1184,11 @@
         self.items = items
         return
 
-    def __str__(self):
+    def tofortran(self, isfix=None):
         l = []
         for name,s in self.items:
             l.append('%s %s' % (name,s))
-        tab = self.get_indent_tab()
+        tab = self.get_indent_tab(isfix=isfix)
         return tab + 'NAMELIST ' + ', '.join(l)
 
 class Common(Statement):
@@ -1223,7 +1224,7 @@
             line = line[i:].lstrip()
         self.items = items
         return
-    def __str__(self):
+    def tofortran(self, isfix=None):
         l = []
         for name,s in self.items:
             s = ', '.join(s)
@@ -1231,7 +1232,7 @@
                 l.append('/ %s / %s' % (name,s))
             else:
                 l.append(s)
-        tab = self.get_indent_tab()
+        tab = self.get_indent_tab(isfix=isfix)
         return tab + 'COMMON ' + ' '.join(l)
     def analyze(self):
         for cname, items in self.items:
@@ -1285,8 +1286,8 @@
                 self.isvalid = False
                 return
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'INTENT (%s) %s' \
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'INTENT (%s) %s' \
                % (', '.join(self.specs), ', '.join(self.items))
     def analyze(self):
         for name in self.items:
@@ -1326,8 +1327,8 @@
         self.name = name
         self.items = items
         return
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         s = tab + 'ENTRY '+self.name
         if self.items:
             s += ' (%s)' % (', '.join(self.items))
@@ -1392,8 +1393,8 @@
         self.mask = mask
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         l = []
         for index,s1,s2,s3 in self.specs:
             s = '%s = %s : %s' % (index,s1,s2)
@@ -1455,8 +1456,8 @@
             self.name = line[:i].rstrip()
             self.bname = line[i+1:].lstrip()[1:].lstrip()
         return
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         s = 'PROCEDURE '
         if self.iname:
             s += '(' + self.iname + ') '
@@ -1485,8 +1486,8 @@
         self.items = split_comma(line[i+2:].lstrip())
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         s = 'GENERIC'
         if self.aspec:
             s += ', '+self.aspec
@@ -1512,8 +1513,8 @@
             line = line[2:].lstrip()
         self.items = split_comma(line, self.item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'ALLOCATABLE ' + ', '.join(self.items) 
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'ALLOCATABLE ' + ', '.join(self.items) 
     def analyze(self):
         for line in self.items:
             i = line.find('(')
@@ -1562,8 +1563,8 @@
             items.append(item)
         self.items = items
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'BIND (%s) %s' %\
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'BIND (%s) %s' %\
                (', '.join(self.specs), ', '.join(self.items))
 
 # IF construct statements
@@ -1584,7 +1585,7 @@
             self.isvalid = False        
         return
 
-    def __str__(self):
+    def tofortran(self, isfix=None):
         if self.name:
             return self.get_indent_tab(deindent=True) + 'ELSE ' + self.name
         return self.get_indent_tab(deindent=True) + 'ELSE'
@@ -1611,7 +1612,7 @@
             self.isvalid = False        
         return
         
-    def __str__(self):
+    def tofortran(self, isfix=None):
         s = ''
         if self.name:
             s = ' ' + self.name
@@ -1659,8 +1660,8 @@
             self.isvalid = False        
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         s = 'CASE'
         if self.items:
             l = []
@@ -1696,8 +1697,8 @@
         self.isvalid = False
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         return tab + 'WHERE ( %s ) %s' % (self.expr, str(self.content[0]).lstrip())
     def analyze(self): return
 
@@ -1725,8 +1726,8 @@
             self.isvalid = False
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         s = 'ELSE WHERE'
         if self.expr is not None:
             s += ' ( %s )' % (self.expr)
@@ -1749,8 +1750,8 @@
             line = line[2:].lstrip()
         self.items = split_comma(line, self.item)
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'ENUMERATOR ' + ', '.join(self.items)
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'ENUMERATOR ' + ', '.join(self.items)
 
 # F2PY specific statements
 
@@ -1762,8 +1763,8 @@
     def process_item(self):
         self.value = self.item.get_line()[11:].lstrip()
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'FORTRANNAME ' + self.value
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'FORTRANNAME ' + self.value
 
 class Threadsafe(Statement):
     """
@@ -1772,8 +1773,8 @@
     match = re.compile(r'threadsafe\Z',re.I).match
     def process_item(self):
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'THREADSAFE'
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'THREADSAFE'
 
 class Depend(Statement):
     """
@@ -1791,8 +1792,8 @@
         self.items = split_comma(line)
         return
 
-    def __str__(self):
-        return self.get_indent_tab() + 'DEPEND ( %s ) %s' \
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'DEPEND ( %s ) %s' \
                % (', '.join(self.depends), ', '.join(self.items))
 
 class Check(Statement):
@@ -1811,8 +1812,8 @@
             line = line[2:].lstrip()
         self.value = line
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'CHECK ( %s ) %s' \
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'CHECK ( %s ) %s' \
                % (self.expr, self.value)
 
 class CallStatement(Statement):
@@ -1823,8 +1824,8 @@
     def process_item(self):
         self.expr = self.item.apply_map(self.item.get_line()[13:].lstrip())
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'CALLSTATEMENT ' + self.expr
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'CALLSTATEMENT ' + self.expr
 
 class CallProtoArgument(Statement):
     """
@@ -1834,8 +1835,8 @@
     def process_item(self):
         self.specs = self.item.apply_map(self.item.get_line()[17:].lstrip())
         return
-    def __str__(self):
-        return self.get_indent_tab() + 'CALLPROTOARGUMENT ' + self.specs
+    def tofortran(self, isfix=None):
+        return self.get_indent_tab(isfix=isfix) + 'CALLPROTOARGUMENT ' + self.specs
 
 # Non-standard statements
 
@@ -1847,9 +1848,9 @@
     def process_item(self):
         self.value = self.item.apply_map(self.item.get_line()[5:].lstrip())
         return
-    def __str__(self):
+    def tofortran(self, isfix=None):
         if self.value:
-            return self.get_indent_tab() + 'PAUSE ' + self.value
-        return self.get_indent_tab() + 'PAUSE'
+            return self.get_indent_tab(isfix=isfix) + 'PAUSE ' + self.value
+        return self.get_indent_tab(isfix=isfix) + 'PAUSE'
     def analyze(self): return
 

Modified: trunk/numpy/f2py/lib/parser/typedecl_statements.py
===================================================================
--- trunk/numpy/f2py/lib/parser/typedecl_statements.py	2006-10-08 09:38:12 UTC (rev 3291)
+++ trunk/numpy/f2py/lib/parser/typedecl_statements.py	2006-10-08 13:16:13 UTC (rev 3292)
@@ -260,8 +260,8 @@
                 
         return clsname + s
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self,isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         s = self.tostr()
         if self.attrspec:
             s += ', ' + ', '.join(self.attrspec)
@@ -270,6 +270,9 @@
         if self.entity_decls:
             s += ' ' + ', '.join(self.entity_decls)
         return tab + s
+    
+    def __str__(self):
+        return self.tofortran()
 
     def __eq__(self, other):
         if self.__class__ is not other.__class__:
@@ -538,8 +541,8 @@
         self.items = items
         return
 
-    def __str__(self):
-        tab = self.get_indent_tab()
+    def tofortran(self, isfix=None):
+        tab = self.get_indent_tab(isfix=isfix)
         if not self.items:
             return tab + 'IMPLICIT NONE'
         l = []

Modified: trunk/numpy/f2py/lib/py_wrap_type.py
===================================================================
--- trunk/numpy/f2py/lib/py_wrap_type.py	2006-10-08 09:38:12 UTC (rev 3291)
+++ trunk/numpy/f2py/lib/py_wrap_type.py	2006-10-08 13:16:13 UTC (rev 3292)
@@ -2,7 +2,8 @@
 __all__ = ['PythonCAPIType']
 
 from wrapper_base import *
-from parser.api import CHAR_BIT, Module, declaration_type_spec, TypeDecl
+from parser.api import CHAR_BIT, Module, declaration_type_spec, \
+     TypeDecl, TypeStmt, Subroutine, Function
 
 class PythonCAPIType(WrapperBase):
     """
@@ -11,7 +12,11 @@
     def __init__(self, parent, typedecl):
         WrapperBase.__init__(self)
         if isinstance(typedecl, tuple(declaration_type_spec)):
-            PythonCAPIIntrinsicType(parent, typedecl)
+            if isinstance(typedecl, TypeStmt):
+                type_decl = typedecl.get_type_decl(typedecl.name)
+                PythonCAPIDerivedType(parent, type_decl)
+            else:
+                PythonCAPIIntrinsicType(parent, typedecl)
         elif isinstance(typedecl, TypeDecl):
             PythonCAPIDerivedType(parent, typedecl)
         else:
@@ -516,6 +521,7 @@
     fortran_code_template = '''\
       subroutine %(init_func)s(init_func_c, self, obj)
       %(use_stmt_list)s
+      %(type_decl_list)s
       external init_func_c
 !     self is %(oname)sObject
       external self
@@ -557,7 +563,7 @@
         for n in typedecl.a.component_names:
             v = typedecl.a.components[n]
             t = v.get_typedecl()
-            PythonCAPIType(t)
+            PythonCAPIType(parent, t)
             ct = t.get_c_type()
             on = 'f2py_' + t.name
             parent.add(t)
@@ -605,8 +611,12 @@
         self.cname = typedecl.get_c_name()
 
         self.use_stmt_list = []
+        self.type_decl_list = []
         if isinstance(typedecl.parent, Module):
             self.use_stmt_list.append('use %s' % (typedecl.parent.name))
-
+        elif isinstance(typedecl.parent, (Subroutine, Function)):
+            self.type_decl_list.append(typedecl.asfix())
+        else:
+            raise NotImplementedError,'types declared in '+typedecl.parent.__class__.__name__
         parent.apply_templates(self)
         return

Added: trunk/numpy/f2py/lib/test_derived_scalar.py
===================================================================
--- trunk/numpy/f2py/lib/test_derived_scalar.py	2006-10-08 09:38:12 UTC (rev 3291)
+++ trunk/numpy/f2py/lib/test_derived_scalar.py	2006-10-08 13:16:13 UTC (rev 3292)
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+"""
+Tests for intent(in,out) derived type arguments in Fortran subroutine's.
+
+-----
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License. See http://scipy.org.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+Author: Pearu Peterson <pearu at cens.ioc.ee>
+Created: Oct 2006
+-----
+"""
+
+import os
+import sys
+from numpy.testing import *
+
+def build(fortran_code, rebuild=True):
+    modulename = os.path.splitext(os.path.basename(__file__))[0]+'_ext'
+    try:
+        exec ('import %s as m' % (modulename))
+        if rebuild and os.stat(m.__file__)[8] < os.stat(__file__)[8]:
+            del sys.modules[m.__name__] # soft unload extension module
+            os.remove(m.__file__)
+            raise ImportError,'%s is newer than %s' % (__file__, m.__file__)
+    except ImportError,msg:
+        print msg, ', recompiling %s.' % (modulename)
+        import tempfile
+        fname = tempfile.mktemp() + '.f90'
+        f = open(fname,'w')
+        f.write(fortran_code)
+        f.close()
+        sys_argv = []
+        sys_argv.extend(['--build-dir','dsctmp'])
+        #sys_argv.extend(['-DF2PY_DEBUG_PYOBJ_TOFROM'])
+        from main import build_extension
+        sys_argv.extend(['-m',modulename, fname])
+        build_extension(sys_argv)
+        os.remove(fname)
+        os.system(' '.join([sys.executable] + sys.argv))
+        sys.exit(0)
+    return m
+
+fortran_code = '''
+subroutine foo(a)
+  type myt
+    integer flag
+  end type myt
+  type(myt) a
+!f2py intent(in,out) a
+  a % flag = a % flag + 1
+end
+'''
+
+# tester note: set rebuild=True when changing fortan_code and for SVN
+m = build(fortran_code, rebuild=True)
+
+from numpy import *
+
+class test_m(NumpyTestCase):
+
+    def check_foo_simple(self, level=1):
+        a = m.myt(2)
+        assert_equal(a.flag,2)
+        assert isinstance(a,m.myt),`a`
+        r = m.foo(a)
+        assert isinstance(r,m.myt),`r`
+        assert_equal(r.flag,3)
+        assert_equal(a.flag,2)
+        
+if __name__ == "__main__":
+    NumpyTest().run()

Modified: trunk/numpy/f2py/lib/test_scalar_in_out.py
===================================================================
--- trunk/numpy/f2py/lib/test_scalar_in_out.py	2006-10-08 09:38:12 UTC (rev 3291)
+++ trunk/numpy/f2py/lib/test_scalar_in_out.py	2006-10-08 13:16:13 UTC (rev 3292)
@@ -1,6 +1,15 @@
 #!/usr/bin/env python
 """
+Tests for intent(in,out) arguments in Fortran subroutine's.
 
+-----
+Permission to use, modify, and distribute this software is given under the
+terms of the NumPy License. See http://scipy.org.
+
+NO WARRANTY IS EXPRESSED OR IMPLIED.  USE AT YOUR OWN RISK.
+Author: Pearu Peterson <pearu at cens.ioc.ee>
+Created: Oct 2006
+-----
 """
 
 import os



More information about the Numpy-svn mailing list