First time here? We are a friendly community of Power Systems Engineers. Check out the FAQ!
1 | initial version |
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 )