python: return exception from function - python

suppose I have the following function:
def test():
...
if x['error']:
raise
This would raise an exception regardless if x['error'] is defined or not.
Instead if I try this, it doesn't throw any exception:
def test():
...
try:
if x['error']:
raise
except:
return
How can I test for a specific value and return an exception if it is defined, and to return successfully if it is not defined?

If you want to return error as string:
>>> def test():
try:
if x['error']:raise
except Exception as err:
return err
>>> test()
NameError("name 'x' is not defined",)
If you want to an error to occur:
>>> def test():
try:
if x['error']:raise
except:
raise
>>> test()
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
test()
File "<pyshell#19>", line 3, in test
if x['error']:raise
NameError: name 'x' is not defined

def test():
...
if x.get(‘error’):
raise
You can avoid unintentionally raising an error using the dictionary's built in get function. Get will return None if the value at the specified key does not exist instead of throwing an exception.

try this one
def check_not_exist(d,k):
#if keys exists in dict,raise it
if k in d:
raise
else:
return True

Related

RaiseError from predefined function is getting called when I use it to define another function

I am working on a project for university and I am having trouble with raising errors.
I am supposed to create several functions that will eventually be re-used in even more functions that I am about to create. I am supposed to use Raise ValueError when some specific arguments are being used. Yet, when I use the initial functions to define new functions, the ValueError that gets raised is the initial one and not the new one.
def first_function(arg1):
if isinstance(arg1, tuple):
return True
else:
raise ValueError("This is not a tuple")
def second_function(arg2):
if first_function(arg2):
print("That Is Indeed a Tuple")
else:
raise ValueError("This is really not a tuple")
argument = "(1, 1)"
print(second_function(argument))
# output: ValueError: This is not a tuple
# desired output: ValueError: This is really not a tuple
How can I fix this? I am not supposed to repeat code. I am supposed to keep re-using the functions I build, yet the errors seem to interfere.
So, technically, the "This is not a tuple" error is functioning correctly. The error will stop the code - where the error happens - and report on the stack in that state. This is desirable.
That said, you can use a try/except/finally to catch the first error and pass it back to the second function, which is what I think you're trying to do.
def first_function(arg1):
if isinstance(arg1, tuple):
return True
else:
raise ValueError("This is not a tuple")
def second_function(arg2):
# The try statement wraps the if/then/else
try:
# When you call first_function, it will error
# That error will be recognized and passed to
# second_function's "except" statement
if first_function(arg2):
print("That Is Indeed a Tuple")
# This else is probably not necessary
# Since first_function will either work (return True), or
# raise an error, you will never have a situation where
# "if first_function(arg2):" will ever reach this else
# else:
# raise ValueError("This is not a tuple")
except ValueError:
raise ValueError("This is really not a tuple")
argument = "(1, 1)"
print(second_function(argument))
Traceback (most recent call last):
File "/home/rightmire/eclipse-workspace/junkcode/test.py", line 18, in second_function
if first_function(arg2):
File "/home/rightmire/eclipse-workspace/junkcode/test.py", line 6, in first_function
raise ValueError("This is not a tuple")
ValueError: This is not a tuple
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/rightmire/eclipse-workspace/junkcode/test.py", line 27, in <module>
print(second_function(argument))
File "/home/rightmire/eclipse-workspace/junkcode/test.py", line 23, in second_function
raise ValueError("This is really not a tuple")
ValueError: This is really not a tuple
As an aside...
The functional goal you're usually trying to accomplish with this type of design pattern, is to avoid the need to do checks like you're doing in first_function (where it checks if the arg is a tuple).
This design pattern is usually so you can leave the error checking to the main calling method, and all the called methods can just do their thing - raising errors if bad code is sent.
I.e.
def first_function(arg1):
return arg1.append("I should be a list")
def second_function(arg2):
try:
_list = first_function(arg2)
print("arg2 is, indeed, a list")
except Exception as e:
raise ValueError("You did not pass a list (ORIG ERROR: {}".format(e))
argument = "(1, 1)"
print(second_function(argument))
OUTPUT:
Traceback (most recent call last):
File "/home/rightmire/eclipse-workspace/junkcode/test.py", line 7, in second_function
_list = first_function(arg2)
File "/home/rightmire/eclipse-workspace/junkcode/test.py", line 2, in first_function
arg1.append("I should be a list")
AttributeError: 'str' object has no attribute 'append'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/rightmire/eclipse-workspace/junkcode/test.py", line 13, in <module>
print(second_function(argument))
File "/home/rightmire/eclipse-workspace/junkcode/test.py", line 10, in second_function
raise ValueError("You did not pass a list (ORIG ERROR: {}".format(e))
ValueError: You did not pass a list (ORIG ERROR: 'str' object has no attribute 'append'
Functionally, the try/except/finally is used to silence errors. As an example...
def first_function(_list, arg1):
_list.append(int(arg1))
return _list
def second_function():
_list = []
while True:
arg2 = input("Enter an integer:")
try:
_list = first_function(_list, arg2)
print("a list containing {}".format(_list))
except Exception as e:
print ("You did not pass an integer. Try again")
second_function()
OUTPUT:
Enter an integer:1
a list containing [1]
Enter an integer:2
a list containing [1, 2]
Enter an integer:3
a list containing [1, 2, 3]
Enter an integer:r
You did not pass an integer. Try again
Enter an integer:4
a list containing [1, 2, 3, 4]
Enter an integer:

raising an exception if a parameter is a string

I have seen other posts/videos in order to figure out how to solve this issue I am having but with no success. I am trying to raise an exception if the third parameter(p) is a string datatype but all my attempts in order to achieve this have not been successful and was looking for some help on what I am doing wrong.
class Friends(Ben):
def __init__(self, frank, greg, p):
Ben.__init__(self, frank, greg)
self.p = p
try:
if p == str:
raise TypeError("This is a string!")
except:
print("This not a string")
There are a number of oddities in your piece of code; however, to address the issue of raising an Exception, you use raise to do that, as other answers indicate.
The try/except syntax is used to catch and handle exceptions when they occur. As an example, here is a reworked, standalone version of your code snippet that illustrates this.
class Friends:
def __init__(self, frank, greg, p):
if isinstance(p, str):
raise TypeError(p, "This is a string!")
self.p = p
try:
friends = Friends('Frank', 'Greg', 'dubious_string')
except TypeError as e:
print("Hey, I caught the error!")
# print the exception
print(e)
# raise the exception again
raise e
Output:
Hey, I caught the error!
('dubious_string', 'This is a string!')
Traceback (most recent call last):
File "tmp.py", line 14, in <module>
raise e
File "tmp.py", line 10, in <module>
friends = Friends('Frank', 'Greg', 'dubious_string')
File "tmp.py", line 5, in __init__
raise TypeError(p, "This is a string!")
TypeError: ('dubious_string', 'This is a string!')
I'm not sure what you are trying to do with the class, but I think this is what you are looking for:
#p = 10
p = "some string"
if type(p) == str:
raise Exception("This is a string")
class Ben:
def __init__(self):
pass
class Friends(Ben):
def __init__(self,frank,greg,p):
if isinstance(p, str):
raise TypeError('Why are you giving me strings!')
Ben.__init__(frank,greg)
self.p = p
group = Friends('frank', 'greg', 'evil_string')
Output:
Traceback (most recent call last):
File "C:\Users\StackOverflow\Desktop\temp.py", line 15, in <module>
group = Friends('frank', 'greg', 'evil_string')
File "C:\Users\StackOverflow\Desktop\temp.py", line 10, in __init__
raise TypeError('Why are you giving me strings!')
TypeError: Why are you giving me strings!

How to Assert we have AssertionError in python?

I have a method:
def cargo_add(self, new_cargo):
assert (new_cargo.weight + self.cargo_weight()) \
<= self.cargocapacity, "Not enough Space left"
And i would like to test its functionallyty with someting like:
def _test_cargo_add():
assert cShip.cargo_add(c1) is AssertionError
So i can test the error Handling. But when the first assert is wrong the program stopps.
If your testing framework does not have helpers for that, or you are not using any, you can do this only using builtins by
using try .. except .. else and isinstance:
>>> def f(): # define a function which AssertionErrors.
... assert False
...
>>> f() # as expected, it does
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in f
AssertionError
>>> try: # wrap it
... f()
... except Exception as e: # and assert it really does
... assert isinstance(e, AssertionError)
... else:
... raise AssertionError("There was'nt any Exception, but we expected an AssertionError!")
...
>>>
or just catch the AssertionError explicitly:
>>> try:
... f()
... except AssertionError:
... pass # all good, we got an AssertionError
... except Exception:
... raise AssertionError("There was an Exception, but it wasn't an AssertionError!")
... else:
... raise AssertionError("There was'nt any Exception, but we expected an AssertionError!")
...
If you are testing using unittest you can use assertRaises
with self.assertRaises(AssertionError):
cShip.cargo_add(c1)

Shelve Code gives KeyError

I wanted to use the following code from here:
How can I save all the variables in the current python session?
import shelve
T='Hiya'
val=[1,2,3]
filename='/tmp/shelve.out'
my_shelf = shelve.open(filename,'n') # 'n' for new
for key in dir():
try:
my_shelf[key] = globals()[key]
except TypeError:
#
# __builtins__, my_shelf, and imported modules can not be shelved.
#
print('ERROR shelving: {0}'.format(key))
my_shelf.close()
But it gives the following error:
Traceback (most recent call last):
File "./bingo.py", line 204, in <module>
menu()
File "./bingo.py", line 67, in menu
my_shelf[key] = globals()[key]
KeyError: 'filename'
Can you help me please?
Thanks!
From your traceback, it appears you are trying to run that code from inside a function.
But dir looks up names in the current local scope. So if filename is defined inside the function, it will be in locals() rather than globals().
You probably want something more like this:
import shelve
T = 'Hiya'
val = [1, 2, 3]
def save_variables(globals_=None):
if globals_ is None:
globals_ = globals()
filename = '/tmp/shelve.out'
my_shelf = shelve.open(filename, 'n')
for key, value in globals_.items():
if not key.startswith('__'):
try:
my_shelf[key] = value
except Exception:
print('ERROR shelving: "%s"' % key)
else:
print('shelved: "%s"' % key)
my_shelf.close()
save_variables()
Note that when globals() is called from within the function, it returns the variables from the module where the function is defined, not from where it's called.
So if the save_variables function is imported, and you want the variables from the current module, then do:
save_variables(globals())

Wrapping exceptions in Python

I'm working on a mail-sending library, and I want to be able to catch exceptions produced by the senders (SMTP, Google AppEngine, etc.) and wrap them in easily catchable exceptions specific to my library (ConnectionError, MessageSendError, etc.), with the original traceback intact so it can be debugged. What is the best way to do this in Python 2?
The simplest way would be to reraise with the old trace object. The following example shows this:
import sys
def a():
def b():
raise AssertionError("1")
b()
try:
a()
except AssertionError: # some specific exception you want to wrap
trace = sys.exc_info()[2]
raise Exception("error description"), None, trace
Check the documentation of the raise statement for details of the three parameters. My example would print:
Traceback (most recent call last):
File "C:\...\test.py", line 9, in <module>
a()
File "C:\...\test.py", line 6, in a
b()
File "C:\...\test.py", line 5, in b
raise AssertionError("1")
Exception: error description
For completeness, in Python 3 you'd use the raise MyException(...) from e syntax.
This answer is probably a little bit late, but you can wrap the function in a python decorator.
Here is a simple cheatsheet on how different decorators.
Here is some sample code of how to do this. Just change the decorator to catch different errors in the different ways that you need.
def decorator(wrapped_function):
def _wrapper(*args, **kwargs):
try:
# do something before the function call
result = wrapped_function(*args, **kwargs)
# do something after the function call
except TypeError:
print("TypeError")
except IndexError:
print("IndexError")
# return result
return _wrapper
#decorator
def type_error():
return 1 / 'a'
#decorator
def index_error():
return ['foo', 'bar'][5]
type_error()
index_error()
Use raise_from from the future.utils package.
Relevant example copied below:
from future.utils import raise_from
class FileDatabase:
def __init__(self, filename):
try:
self.file = open(filename)
except IOError as exc:
raise_from(DatabaseError('failed to open'), exc)
Within that package, raise_from is implemented as follows:
def raise_from(exc, cause):
"""
Equivalent to:
raise EXCEPTION from CAUSE
on Python 3. (See PEP 3134).
"""
# Is either arg an exception class (e.g. IndexError) rather than
# instance (e.g. IndexError('my message here')? If so, pass the
# name of the class undisturbed through to "raise ... from ...".
if isinstance(exc, type) and issubclass(exc, Exception):
e = exc()
# exc = exc.__name__
# execstr = "e = " + _repr_strip(exc) + "()"
# myglobals, mylocals = _get_caller_globals_and_locals()
# exec(execstr, myglobals, mylocals)
else:
e = exc
e.__suppress_context__ = False
if isinstance(cause, type) and issubclass(cause, Exception):
e.__cause__ = cause()
e.__suppress_context__ = True
elif cause is None:
e.__cause__ = None
e.__suppress_context__ = True
elif isinstance(cause, BaseException):
e.__cause__ = cause
e.__suppress_context__ = True
else:
raise TypeError("exception causes must derive from BaseException")
e.__context__ = sys.exc_info()[1]
raise e

Categories