I have a statement like this.
I just want to know which of the two assert statement has thrown the exception.
try:
assert re.search("xyz", statement)
assert re.search("abc", statement)
except AssertionError:
print "AssertionError : Expected Error message not found"
Thanks for the answer.
As mentioned in The assert statement docs, you can give an expression after the assertion test expression; that second expression will be passed in the AssertionError. Here's a simple demo:
for n in (-5, 10, 20):
try:
assert 0 <= n, '%d is too low' % n
assert n <= 10, '%d is too high' % n
print('%d is ok' % n)
except AssertionError as err:
print "AssertionError:", err
output
AssertionError: -5 is too low
10 is ok
AssertionError: 20 is too high
That second expression doesn't have to be a string, it can be anything. Since assertions should only be used to verify program logic, not to validate user data, I generally don't bother passing a nicely-formatted string, I just pass a tuple containing the relevant values, and maybe an identifying string. Eg,
assert (a * b > c), ('Bad product', a, b, c)
You could use functions from the traceback module. For example, extract_tb returns a list of tuples (named tuples in Python 3.5 and newer) representing the stack trace entries. Each tuple contains a line number as well as the source text line (if available).
import traceback
try:
assert 1
assert None
except AssertionError as e:
for x in traceback.extract_tb(e.__traceback__, limit=-1):
print(x.lineno, repr(x.line)) # Prints 5 'assert None'
You are able to print the last raised exception with traceback.print_exc(). An example:
>>> import traceback
>>> try:
... a = 1 / 0
... except:
... traceback.print_exc()
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ZeroDivisionError: integer division or modulo by zero
There is also traceback.format_exc() in case you don't want to print.
Maybe you want to differ the exceptions?Then Getting exception details in Python can help you.
Copying the answer here:
import sys
try:
assert re.search("xyz", statement)
assert re.search("abc", statement)
except AssertionError:
type, value, traceback = sys.exc_info()
Then you can print out the info.
Related
If the number in the line is already wroten, I must print 0 and if it's not, I must print 1.
Got ValueError and tried to catch it, but it fails.
a=int(input())
b=input()
n='1 '
c=b.split()
for i in range(a-1):
l=c[0]
c.remove(l)
d=c.index(l)
try:
a=a
except ValueError as ve:
if d > 0:
c = c.replace(l,'zero')
else:
c=c.replace(l,'one')
for amogus in range(a):
a=a.replace('one',1)
a=a.replace('zero',0)
print(a)
The error tracebacks like so:
Traceback (most recent call last):
File "program.pys3", line 8, in <module>
d=c.index(l)
ValueError: '1' is not in list
The first part of your loop is like this:
for i in range(a-1):
l = c[0]
c.remove(l)
d = c.index(l)
l is set to the first item in the list c. You then remove that item. The last line above then tries to find the index of that item again. This will work if there is another one, but if not will throw the error you report.
Did you mean to put the last line inside the try:?
for i in range(a-1):
l = c[0]
c.remove(l)
try:
d = c.index(l)
except ValueError as ve:
if d > 0:
c = c.replace(l,'zero')
else:
c = c.replace(l,'one')
Now a friendly warning: if this fixes the reported error you will encounter another one.
i had two statements and my friend is claiming to me they are not the same. i believe they are. I was wondering if they are and if they aren't is there an example where the behavior is different.
if (n != p and c/n > 5.15):
if (c/n > 5.15 and n !=p):
They could be different due to the short-circuiting behavior of and. If the first operand of and is false, the second is not evaluated. So if c/n > 5.15 raises an exception (for instance if n is zero), the first if may work (that is, not raise any error) while the second causes an error. Here is an example:
c = 0
n = 0
p = 0
# No error, no output because the condition was not true
>>> if (n != p and c/n > 5.15):
... print "Okay!"
# Raises an error
>>> if (c/n > 5.15 and n !=p):
... print "Okay!"
Traceback (most recent call last):
File "<pyshell#23>", line 1, in <module>
if (c/n > 5.15 and n !=p):
ZeroDivisionError: division by zero
I would like to find a way to get the variables I assigned before an exception is made. E.G if the code is
try:
a=b
c=d
e=f
except:
bla bla
And an exception is generated at "e=f," I still want a=b and c=d
Is it possible? I realize I could make this multiple try statements but is there something I can do in one step?
Yes, it is perfectly possible. Below is a demonstration:
>>> try:
... a = 1
... b = 2
... c = 1/0 # This will raise a ZeroDivisionError
... except ZeroDivisionError:
... print 'an error occurred'
...
an error occurred
>>> a # a still exists
1
>>> b # so does b
2
>>> c # only c is undefined
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'c' is not defined
>>>
try/except is designed to execute the code in the try-block normally until an exception is raised. When that happens, the try-block is immediately exited. This means that only the code after the line that raised the exception is ignored.
The best you can do is to limit the number of expressions inside your try block.
If you need to know where the exception is raised, you are probably better off using multiple try...except's like you mentioned in your queestion, since there is no (practical) way to know where the exception was raised.
If the expressions are of the same type, you may want to put them in lists though, and loop over them, like:
vars = [a, b, c]
values = [1, 2, 0]
for i, (var, value) in enumerate(zip(vars, values)):
try:
var /= value
except ZeroDivisionError:
print 'The exception was raised on the {}. iteration'.format(i)
continue
try:
a = "foo"
c = "bar"
e = unknown_function()
except:
pass
print a, c # prints "foo bar"
Both a and c are set, you can simply use their values after the exception is handled. e is not set to anything as an exception was raised when that line was executed.
If I understand you correctly, this will happen by default. Raising an exception does not magically undo everything that has already happened inside the try block. In your example, if an error occurs on the assignment of e, a and c will still have the values they were assigned.
try:
a = b
c = d
e = f # oh noes! error! Try block skips to the end!
except: pass
print (a) #but a and c are still there
print (c)
This is a straight forward method without much of a hassle . This is the best way out when you cant predict what type of error can occur, or multiple errors can occur .
try :
a=10
except :
print "bla A"
try :
b=20
except:
print "bla B"
try:
c=d
except :
print "bla C"
Is it something like this that you want ?
import sys
code = """
b = 100
d = 200
a=b
c=d
e=10/0
g=e
h = 100
"""
for line in filter(None,code.splitlines()):
print line
try:
exec line
except:
sys.excepthook(sys.exc_info()[0],sys.exc_info()[1],None)
result
b = 100
d = 200
a=b
c=d
e=10/0
ZeroDivisionError: integer division or modulo by zero
g=e
NameError: name 'e' is not defined
h = 100
A colleague of mine mistakenly typed this (simplified) code, and was wondering why his exception wasn't getting caught:
>>> try:
... raise ValueError
... except IndexError or ValueError:
... print 'Caught!'
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
ValueError
Now I know that the correct syntax to catch both types of exception should be except (IndexError, ValueError):, but why is the above considered valid syntax? And how does it work?
For example, the above code will throw a ValueError and it won't get caught. But take this code:
>>> try:
... raise IndexError
... except IndexError or ValueError:
... print 'Caught!'
...
Caught!
The IndexError will get caught. How is the or evaluated, and what is it evaluated to?!
Thanks for any light you can shed!
That's because IndexError or ValueError is evaluated to IndexError.
>>> IndexError or ValueError
<type 'exceptions.IndexError'>
The or operator returns the first expression that evaluates to True (In this case IndexError), or the last expression, if none of them are True.
So, your except statement is actually equivalent to:
except IndexError:
The result of the Boolean operations or and and is always one of the operands, so foo or bar will evaluate to foo if foo is truthy, or bar if foo if falsy.
In this case both IndexError and ValueError are truthy so IndexError or ValueError evaluates to IndexError, and your except statement is equivalent to except IndexError.
I can't understand why this code:
x='aaaa'
try:
self.assertTrue(x==y)
except:
print (x)
generates me this error
AssertionError: False is not True
It should be handle it by
print(x)
EDIT
original code is:
try:
self.assertTrue('aaaa'==self.compare_object_name[1])
except:
print ('aaa')
#Space_C0wb0y I can't give you full code because it is not my code, and I don't have a permission.
You should include the code that defines the assertTrue method. From the output you get, I'd say that it actually does not throw an exception, but deals with it internally (thus the error message being printed, and not your value).
You can use the built-in assert statement of Python, which works as expected:
x = 'aaaa'
y = 'bbb'
try:
assert(x == y)
except:
print (x)
Output:
>>>
aaaa