catching exceptions from fortran

J

john

I wrapped some fortran code using F2PY and need to be able to catch
fortran runtime errors to run the following:

# "grid" is a wrapped fortran module
# no runtime errors incurred when run with the correct inputs for
filetype
#-------------------------------
def readGrid( self, coord='xyz' ):
mg = ( '.FALSE.', '.TRUE.' )
form = ( 'FORMATTED', 'UNFORMATTED' )
success = False
for m in mg:
for f in form:
try:
if coord == 'xyz':
self.grid.readxyz( self.filename, f, m )
success = True
elif coord == 'xyrb':
self.grid.readxyrb( self.filename, f, m )
success = True
else:
import sys
print 'gridtype "' + str(coord) + '" not supported. ' \
+ '<IO.Plot3d.Plot3d.read>'
except:
continue
if not success:
import sys
print 'gridfile "' + str(self.filename) + '" not read in any
recognized format' \
+ ' <IO.Plot3d.Plot3d.read>'
#----------------------------


basically, what i want to happen is to try to run 'something' with the
wrapped fortran code and if that doesn't work (error encountered,
etc.) try something else. is there an easier way to go about doing
this? is there something i'm missing about catching exceptions here?

Thanks in advance!
 
G

Gabriel Genellina

I wrapped some fortran code using F2PY and need to be able to catch
fortran runtime errors to run the following:
[reindented]
# "grid" is a wrapped fortran module
# no runtime errors incurred when run with the correct inputs for
filetype
#-------------------------------
def readGrid( self, coord='xyz' ):
mg = ( '.FALSE.', '.TRUE.' )
form = ( 'FORMATTED', 'UNFORMATTED' )
success = False
for m in mg:
for f in form:
try:
if coord == 'xyz':
self.grid.readxyz( self.filename, f, m )
success = True
elif coord == 'xyrb':
self.grid.readxyrb( self.filename, f, m )
success = True
else:
import sys
print 'gridtype "' + str(coord) + '" not supported. ' \
+ '<IO.Plot3d.Plot3d.read>'
except:
continue
if not success:
import sys
print 'gridfile "' + str(self.filename) + '" not read in any
recognized format' \
+ ' <IO.Plot3d.Plot3d.read>'
#----------------------------

I suppose you want to stop trying other formats after a successful read;
in that case put a break statement just below both success=True.
If coord is unrecognized, the code above prints the same message 4 times.
Instead of printing a message, in those cases usually an exception is
raised, letting a higher layer handle the error. And using string
interpolation is a lot easier than building the message in parts:
raise ValueError('gridtype "%s" not supported. <IO.Plot3d.Plot3d.read>' %
coord)
If you want to catch errors on the Fortran code *only*, the try/except
should be more specific (both in scope and what it catches). The Exception
class is the more generic exception that you should catch.
basically, what i want to happen is to try to run 'something' with the
wrapped fortran code and if that doesn't work (error encountered,
etc.) try something else. is there an easier way to go about doing
this? is there something i'm missing about catching exceptions here?

I'd reorder the code in this way (untested, of course):

def readGrid(self, coord='xyz'):

def try_all_formats(read_function, filename):
mg = ('.FALSE.', '.TRUE.')
form = ('FORMATTED', 'UNFORMATTED')
success = False
for m in mg:
for f in form:
try:
read_function(filename, f, m)
success = True
break
except Exception, e:
# this line only for debugging purposes
print "error %r when using m=%r f=%r" % (e, m, f)
continue
if not success:
raise ValueError('gridfile "%s" not read '
'in any recognized format '
'<IO.Plot3d.Plot3d.read>' % filename)

if coord == 'xyz':
try_all_formats(self.grid.readxyz, self.filename)
elif coord == 'xyrb':
try_all_formats(self.grid.readxyrb, self.filename)
else:
raise ValueError('gridtype "%s" not supported. '
'<IO.Plot3d.Plot3d.read>' % coord)

I don't know about F2PY but the values ('.FALSE.', '.TRUE.') seem
suspicious. AFAIR, .FALSE. and .TRUE. are the Fortran spellings of False
and True in Python - they're not strings, but boolean values. So maybe the
right way is to use
mg = (False, True)

Your code above was catching and ignoring everything, even this error, if
it happened.
 
J

john

En Thu, 11 Sep 2008 10:43:08 -0300, john <[email protected]> escribió:




I wrapped some fortran code using F2PY and need to be able to catch
fortran runtime errors to run the following:
[reindented]
# "grid" is a wrapped fortran module
# no runtime errors incurred when run with the correct inputs for
filetype
#-------------------------------
def readGrid( self, coord='xyz' ):
  mg = ( '.FALSE.', '.TRUE.' )
  form = ( 'FORMATTED', 'UNFORMATTED' )
  success = False
  for m in mg:
    for f in form:
      try:
        if coord == 'xyz':
          self.grid.readxyz( self.filename, f, m )
          success = True
        elif coord == 'xyrb':
          self.grid.readxyrb( self.filename, f, m )
          success = True
        else:
          import sys
          print 'gridtype "' + str(coord) + '" not supported. ' \
              + '<IO.Plot3d.Plot3d.read>'
      except:
        continue
  if not success:
    import sys
    print 'gridfile "' + str(self.filename) + '" not read in any  
recognized format' \
        + ' <IO.Plot3d.Plot3d.read>'
#----------------------------

I suppose you want to stop trying other formats after a successful read;  
in that case put a break statement just below both success=True.
If coord is unrecognized, the code above prints the same message 4 times.  
Instead of printing a message, in those cases usually an exception is  
raised, letting a higher layer handle the error. And using string  
interpolation is a lot easier than building the message in parts:
raise ValueError('gridtype "%s" not supported. <IO.Plot3d.Plot3d.read>' %  
coord)
If you want to catch errors on the Fortran code *only*, the try/except  
should be more specific (both in scope and what it catches). The Exception  
class is the more generic exception that you should catch.
basically, what i want to happen is to try to run 'something' with the
wrapped fortran code and if that doesn't work (error encountered,
etc.) try something else.  is there an easier way to go about doing
this?  is there something i'm missing about catching exceptions here?

I'd reorder the code in this way (untested, of course):

def readGrid(self, coord='xyz'):

     def try_all_formats(read_function, filename):
         mg = ('.FALSE.', '.TRUE.')
         form = ('FORMATTED', 'UNFORMATTED')
         success = False
         for m in mg:
             for f in form:
                 try:
                     read_function(filename, f, m)
                     success = True
                     break
                 except Exception, e:
                     # this line only for debugging purposes
                     print "error %r when using m=%r f=%r" % (e, m, f)
                     continue
         if not success:
             raise ValueError('gridfile "%s" not read '
                    'in any recognized format '
                    '<IO.Plot3d.Plot3d.read>' % filename)

     if coord == 'xyz':
         try_all_formats(self.grid.readxyz, self.filename)
     elif coord == 'xyrb':
         try_all_formats(self.grid.readxyrb, self.filename)
     else:
         raise ValueError('gridtype "%s" not supported. '
                 '<IO.Plot3d.Plot3d.read>' % coord)

I don't know about F2PY but the values ('.FALSE.', '.TRUE.') seem  
suspicious. AFAIR, .FALSE. and .TRUE. are the Fortran spellings of False  
and True in Python - they're not strings, but boolean values. So maybe the  
right way is to use
         mg = (False, True)

Your code above was catching and ignoring everything, even this error, if  
it happened.

Gabriel,

i agree with everything you write, but unless i misunderstood
something, this still doesn't address the main problem of the try-
except construct not preventing the program from aborting when the
wrapped fortran code encounters an error. i tried hard-coding all of
the passed variables to the fortran code and ran that code alone--
works. however, when an incorrect fortran read is attempted (ex.
formatted read on unformatted file), the python except still fails to
catch the error and the code aborts with a runtime error...
 
G

Gabriel Genellina

En Mon, 15 Sep 2008 10:04:27 -0300, john <[email protected]> escribió:

[trying to catch exceptions when reading a file in Fortran code using f2py]
i agree with everything you write, but unless i misunderstood
something, this still doesn't address the main problem of the try-
except construct not preventing the program from aborting when the
wrapped fortran code encounters an error. i tried hard-coding all of
the passed variables to the fortran code and ran that code alone--
works. however, when an incorrect fortran read is attempted (ex.
formatted read on unformatted file), the python except still fails to
catch the error and the code aborts with a runtime error...

Looks like the error isn't mapped onto a Python exception, and is handled
directly in the Fortran code; better to find a f2py group to ask then.
Perhaps you have to catch those errors on the Fortran side. I barely
remember doing things like READ(..., IOSTAT=IO)...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,067
Latest member
HunterTere

Latest Threads

Top