Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find exceptions that can be raised for a particular module in Python?

I would like to know how is the standard way (if there's any) to get the exceptions that a module/function can raised.

Let's take for instance json. Naturally I went to the Documentation but I didn't find a standardized way to know which exceptions can be raised in certain functions (like dump or load). It is not clear to me (at first glance) if just catching TypeError will be enough.

Which are the recommendations to be sure that we're catching everything (and just enough) about a particular module/function?

like image 604
Santi Agüero Avatar asked Jul 16 '13 02:07

Santi Agüero


People also ask

How do I find specific exceptions in Python?

To get exception information from a bare exception handler, you use the exc_info() function from the sys module. The sys. exc_info() function returns a tuple that consists of three values: type is the type of the exception occurred.

Which exception is raised when module requested is not available in Python?

ImportError(StandardError) is raised when Python fails to import a module. EnvironmentError is used as a base class for exceptions that can be caused by the interpreter's environment (that is, they're usually not caused by bugs in the program).

Which exception is raised when module requested is not available?

A subclass of ImportError which is raised by import when a module could not be located. It is also raised when None is found in sys.modules .


2 Answers

I've never been completely satisfied with Python's exception stuff. It works fine in practice, it's the theory that bothers me. :-) In particular, because everything is dynamic, even if you know that evil() only raises ZorgError itself and calls spam() which raises EggsError, so that at most you get those two errors from a call to evil(), someone could patch things behind your back and change this.

That said, some documentation is better than others. For instance os.kill can obviously raise OSError if the kill fails, and TypeError if you call it with something other than two integers, but did you know it can also raise OverflowError?

>>> os.kill(9999999999999, 0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: signed integer is greater than maximum

If you are attempting to write reasonably bullet-proof code that does things like read a pid-file and probe to see if a process is running, it turns out you have to catch this OverflowError in case the pid in the pid-file is an integer, but is out of range. It would be nice if this were in the documentation (I found it through torture-testing instead.)

Simply catching everything (except: or except Exception) is usually not suitable as it usually catches too much (including, e.g., RuntimeError from a stack overflow). So how do you know what to catch? I think it might be nice if leaf functions in standard libraries had an "exceptions I raise directly" attribute or documentation-requirement, but it's just not there.


Edit: I noted in a comment above that the json documentation mentions ValueError explicitly. Not explicitly called out, but found in json's self tests, are UnicodeDecodeError (which is obvious once you think about it) and AttributeError (not so obvious). The documentation also mentions that you can get an OverflowError. Of course, if you use json.dump, which takes a stream on which to write, you can get all of the stream's errors as well. This kind of thing is why a "list of exceptions zorg() raises directly" is not always very useful.

like image 65
torek Avatar answered Sep 22 '22 22:09

torek


Well you can use the global type Exception to catch the Exceptions:

try:
   1 + "2"
except Exception as error:
   print  "Error", error

The output will be something like:

Error unsupported operand type(s) for +: 'int' and 'str'

If you want to know the name of that Exception you can do something like:

try:
   1 + "2"
except Exception as error:
   print  error.__class__.__name__, error

and the output will be something like:

TypeError unsupported operand type(s) for +: 'int' and 'str'
like image 30
Victor Castillo Torres Avatar answered Sep 19 '22 22:09

Victor Castillo Torres