no0by5
no0by5

Reputation: 632

Is there a way to find out which Python method can raise which Exception or Error

Is there a way to find out which Python method can raise which Exception or Error? I didn't find much about it in the official Python documentation.

Upvotes: 2

Views: 1446

Answers (2)

t.m.adam
t.m.adam

Reputation: 15376

You can find the name of the exception with __name__ , example :

try : 
    some_function()
except Exception as ex : 
    print('function: {0}, exception: {1}'.format(some_function.__name__, type(ex).__name__))

Upvotes: 1

Raymond Hettinger
Raymond Hettinger

Reputation: 226326

In general, the answer is no. Some of the exceptions are documented but most just follow a general pattern that can be learned. SyntaxError is checked first and is raised for syntactically invalid code. NameError arises when a variable is undefined (not assigned yet or misspelled). TypeError is raised for the wrong number of arguments or mismatched data types. ValueError means the type is correct and but the value doesn't make sense for the function (i.e. negative inputs to math.sqrt(). If the value is an index in a sequence lookup, IndexError is raised. If the value is a key for a mapping lookup, KeyError is raised. Another common exception is AttributeError for missing attributes. IOError is for failed I/O. And OSError for operating system errors.

Besides learning the common patterns, it is usually easy to just run a function and see what exception it raises in a given circumstance.

In general a function cannot know or document all the possible errors, because the inputs can raise their own exceptions. Consider this function:

def f(a, b):
    return a + b

It can raise TypeError if the number of arguments are wrong or if a doesn't support the __add__ method. However, the underlying data can raise different exceptions:

>>> f(10)

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    f(10)
TypeError: f() takes exactly 2 arguments (1 given)
>>> f(10, 20)
30
>>> f('hello', 'world')
'helloworld'
>>> f(10, 'world')

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    f(10, 'world')
  File "<pyshell#2>", line 2, in f
    return a + b
TypeError: unsupported operand type(s) for +: 'int' and 'str'
>>> class A:
    def __init__(self, x):
        self.x = x
    def __add__(self, other):
        raise RuntimeError(other)

>>> f(A(5), A(7))

Traceback (most recent call last):
  File "<pyshell#13>", line 1, in <module>
    f(A(5), A(7))
  File "<pyshell#2>", line 2, in f
    return a + b
  File "<pyshell#12>", line 5, in __add__
    raise RuntimeError(other)
RuntimeError: <__main__.A instance at 0x103ce2ab8>

Upvotes: 6

Related Questions