Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

Raise psspy ierr as python exception

As I'm sure you've realized after playing with the API for a while, its pretty easy to never check your ierrs when working with the API. I wrote this decorator which will apply itself to all the psspy functions which generate an ierr and check at each call that ierr is not 0.

If it the function does generate an ierr, it raises a Python exception with detailed debug information related to the ierr gleamed from the docstring.

For example, calling

psspy.case(r"nonexistantFile")

now raises:

Exception: psspy.case generated ierr = 3: error opening SFILE.

Here is the code:

def raisePsspyError(psspyFunc):
    """This decorator raises a python exception whenever a psspy
       function returns an ierr that is not 0. """
    def callPsspyFunc(*args, **kwargs):
        ans = psspyFunc(*args, **kwargs)
        if type(ans) is tuple:
            ierr = ans[0]   # ierr is always first element of tuple
        elif type(ans) is int:
            ierr = ans      # function only returns ierr
        else:
            raise Exception("Unkonwn return type %s." % type(ans))
        if ierr != 0:
            # Find all the errors documented in the doc string
            errDoc = psspyFunc.__doc__[psspyFunc.__doc__.find('IERR = 0'):]
            errs = {}
            for errStr in errDoc.split('\n'):
                try:
                    errNum = errStr.split('=')[1].strip()[0]
                    errDesc = errStr.split('=')[1].strip()[2:]
                    errs[int(errNum)] = errDesc
                except:
                    pass
            msg = "psspy." + psspyFunc.__name__ + " generated ierr = " + \
                str(ierr) + ": " + errs[ierr]
            raise Exception(msg)
        else:
            return ans
    return callPsspyFunc

# Apply our decorator to all psspy function which return an ierr
import types
for k,v in vars(psspy).items():
    if isinstance(v, types.FunctionType):
        if v.__doc__.find('IERR = 0') > 0:
            vars(psspy)[k] = raisePsspyError(v)

if __name__ == '__main__':
    import psspy
    psspy.case(r"nonexistantFile.sav")  # Will raise a python exception instead
                                        #  of just going mairly on its way

(maintained at this gist: https://gist.github.com/jsexauer/6425120 )