Python exceptions: is there a way to find the exception attributes?
Pierre Rouleau
pieroul at attglobal.net
Sun Dec 1 15:27:00 EST 2002
Bengt Richter wrote:
> On Sat, 30 Nov 2002 22:16:22 -0500, Pierre Rouleau <pieroul at attglobal.net> wrote:
>
>
>>
>>John Hunter wrote:
>>
>>>>>>>>"Pierre" == Pierre Rouleau <pieroul at attglobal.net> writes:
>>>>>>>
>>>
>>> Pierre> I was looking for a quick way to look at exception
>>> Pierre> attributes from within my programming environment when i
>>> Pierre> have to decide what exception i should catch or which one
>>> Pierre> i should raise and then what information i should pass
>>> Pierre> inside the exception object.
>>>
>>>Within recent interactive python shells (which include pydoc.help by
>>>default), you can do, for example:
>>>
>>> help(Exception)
>>> help(StandardError)
>>> help(IOError)
>>> help(StandardError)
>>> help(AttributeError)
>>> help(KeyError)
>>>
>>>With some shells (eg, ipython) you can drop the parentheses. Is this
>>>what you are looking for?
>>>
>>>
>>
>>Not really. I would like to be able to know what my code can retreive
>
>>from a given exception object (its attributes) without having to look
>
>>into the code. Exceptions are different than other objects in the sense
>>that I can't simply create one and list its attributes.
>>
>>For example, on Python 2.2, if you run help(IOError) you get:
>>
>>
>>Help on class IOError in module exceptions:
>>
>>class IOError(EnvironmentError)
>> | I/O operation failed.
>> |
>> | Method resolution order:
>> | IOError
>> | EnvironmentError
>> | StandardError
>> | Exception
>> |
>> | Data and non-method functions defined here:
>> |
>> | __doc__ = 'I/O operation failed.'
>> |
>> | __module__ = 'exceptions'
>> |
>> | ----------------------------------------------------------------------
>> | Methods inherited from EnvironmentError:
>> |
>> | __init__(...)
>> |
>> | __str__(...)
>> |
>> | ----------------------------------------------------------------------
>> | Methods inherited from Exception:
>> |
>> | __getitem__(...)
>>
>>
>>There is nothing in that information to tell anyone that IOError
>>exceptions have 3 attributes: errno, filename and strerror.
>>
>>In my question, I show a way to find out the list of attributes. The
>>code is generating the exception, cathing the exception object and use
>>dir() on the exception object instance to list its attributes. By
>>visual inspection it becomes easy to find their names:
>>
>>
>>>>>try:
>>>>
>>... f=open("/invalid/invalid.oops")
>>... except IOError, e:
>>... print dir(e)
>>...
>>['__doc__', '__getitem__', '__init__', '__module__', '__str__', 'args',
>>'errno', 'filename', 'strerror']
>>
>>But lets assume i did not know how to generate an IOError exception. I
>>would have to look into the documentation to find out what it is (or its
>>source code if it is available). If it is a builtin exception I would
>>have to find out how to generate the exception before I could write a
>>small code snippet (like the one above) to be able to get one object for
>>the type of exception I am interested in.
>>
>>I am just trying to find out if there is a faster way than that. A
>>method that does not involve all of this cogitation. This way, if one
>>day, with a new release of Python i want to quickly know what are the
>>attributes to this new exception, I would quickly find out.
>>
>>
>
> You could just mechanize your code snippet for all the official exceptions:
>
> >>> import exceptions
> >>> for xname in [x for x in dir(exceptions) if not x.startswith('_')]:
> ... x = exceptions.__dict__.get(xname)
> ... if x is None: print 'Nothing for %s' % x
> ... try:
> ... raise x
> ... except x, e:
> ... print '%s:\n %s' %(x.__name__,[a for a in dir(e) if not a.startswith('_')])
> ...
>
That's it! I should have known that i could just raise the exception and get the attributes from
it. Oh well...
I wrote the following utilities to mechanize that work in the future, based on your code above. Thanks!
The main function is exception_info(). It uses printIndented() to print a paragraph of text with a
left margin. execption_info() accepts different types of arguments and can be used to get a list of
arguments or simply print them.
def printIndented(indentSize,text,noIndentOn=0) :
"""Print all lines of text indented by specified amount.
Arguments:
text : The single or multi-line string to print.
indentSize : A string or number representing the size of the left margin.
If a string is passed, its size is used for the margin.
noIndentOn : Number of lines not indented starting from the first one.
"""
if type(indentSize) in types.StringTypes:
marginText = " " * len(indentSize)
elif type(indentSize) is types.IntType:
marginText = " " * indentSize
else:
marginText = ""
for line in text.split('\n'):
if (noIndentOn <= 0):
print "%s%s" % (marginText,line)
else:
print line
noIndentOn -= 1
def exception_info(excClass=None) :
"""Print information about specific builtin exception class (or all of them).
Arguments:
excClass : a builtin exception class name
or a string for a builtin exception class.
By default none is specified: print information for all
builtin exceptions.
Returns:
- For a specific exception: a 2-tuple: (docstring, [argument list])
- For a report for all exceptions: None
- On error : None
Example:
>>> exception_info(IOError)
Exception class: IOError
Documentation: I/O operation failed.
Arguments : ['args', 'errno', 'filename', 'strerror']
('I/O operation failed.', ['args', 'errno', 'filename', 'strerror'])
>>> exception_info('UnicodeError')
Exception class: UnicodeError
Documentation: Unicode related error.
Arguments : ['args']
('Unicode related error.', ['args'])
"""
#
def showInfoFor(anExcptClass):
try:
raise anExcptClass
except anExcptClass, exp:
print "Exception class: %s" % anExcptClass.__name__
print " Documentation: ",
printIndented(" Documentation: ", anExcptClass.__doc__ ,noIndentOn=1)
argList = [arg for arg in dir(exp) if not arg.startswith('_')]
print " Arguments : %s" % argList
return argList
#
def getInfoFor(anExcptClass):
try:
return (anExcptClass.__doc__, showInfoFor(anExcptClass))
except :
print "Unknown exception %s" % anExcptClass
#
if isinstance(excClass, types.ClassType):
return getInfoFor(excClass)
else:
if type(excClass) in types.StringTypes:
return getInfoFor(exceptions.__dict__.get(excClass))
elif excClass is None:
for xname in [x for x in dir(exceptions) if not x.startswith('_')]:
excpt = exceptions.__dict__.get(xname)
if excpt is not None:
showInfoFor(excpt)
else:
print "Invalid argument: pass name of builtin exception"
print " not a %s" % type(excClass)
> but I agree that there ought to be some visibility in documentation somewhere. Maybe there is?
>
If there is I did not see it. If anyone knows where it is let me know!
Thanks again!
--
Pierre Rouleau, ing.
More information about the Python-list
mailing list