Try function not running correctly - python

try:
left_break = signs_pos[dave - 1]
except IndexError:
left_error = True
try:
right_break = signs_pos[dave + 1]
except IndexError:
right_error = True
if left_error == True:
current_cal = user_input[:right_break]
elif right_error == True:
current_cal = user_input[left_break:]
else:
current_cal = user_input[left_break:right_break]
I've only started looking at try functions and I need some help with this. What I would like to happen is that if when it tries to find left_break and it gives an error it will set left_error to be true. But if it does not give an error left_break will be set properly.
When the code runs and either right or left does not give an error it does not set left_break or right_break properly.
Traceback (most recent call last):
File "C:\Users\Max\Desktop\MaxsCal.py", line 170, in <module>
current_cal = user_input[:right_break]
NameError: name 'right_break' is not defined
This is the error I get without the try function.
Traceback (most recent call last):
File "C:\Users\Max\Desktop\MaxsCal.py", line 157, in <module>
right_break = signs_pos[dave + 1]
IndexError: list index out of range
Both right_error and left_error will not be true.

The reason why this is happening, is that because you are trying to assign something to a variable inside a try/except, it will not actually exist if you raised an exception.
Here is a simple example to clarify this:
try:
x = 6 / 0
except ZeroDivisionError:
print('this failed')
print(x)
>>> print(x)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
Now, to remedy this and you are looking to actually use the variable even if it fails in the try/except, you want to declare it before you are calling the thing that might fail.
x = 0
try:
x = 6 / 0
except ZeroDivisionError:
print('this failed')
print(x)
>>> print(x)
>>> 0
Or even inside your try works, but before what you are calling:
try:
x = 0
x = 6 / 0
except ZeroDivisionError:
print('this failed')
print(x)
>>> print(x)
>>> 0
As mentioned to me in the comments, you could also set a default in your except:
try:
x = 6 / 0
except ZeroDivisionError:
print('this failed')
x = 0
print(x)
>>> print(x)
>>> 0

left_break and right_break are only available within the scope of the try block. You can either define them before the try/except block or add an else block to the exception, as discussed in this thread.

Your error is coming from the fact that the variable is out of scope. Right break is only in scope within the try block, change it to
right_break = None
try:
right_break = signs_pos[dave + 1]
except IndexError:
right_error = True

Related

How to print line number of error that is inside a function using except in Python?

I want to print an error's line number and error message in a nicely displayed way. The follow is my code, which uses linecache:
import linecache
def func():
if xx == 1:
print('ok')
try:
func()
except:
exc_type, exc_obj, tb = sys.exc_info()
f = tb.tb_frame
lineno = tb.tb_lineno
filename = f.f_code.co_filename
linecache.checkcache(filename)
line = linecache.getline(filename, lineno, f.f_globals)
print_('ERROR - (LINE {} "{}"): {}'.format(lineno, line.strip(), exc_obj))
However, this only gives where the func() is called:
ERROR - (LINE 8 ""): name 'xx' is not defined
Is there a way to print the line number where the error actually occured, which should be Line 4? Or even better, can I print Line 8 and then trace back to line 4? For example, if I do not use try - except, the code:
def func():
if xx == 1:
print('ok')
func()
will give me the following error message, which is much better to locate the error:
File "<input>", line 5, in <module>
File "<input>", line 2, in func
NameError: name 'xx' is not defined. Did you mean: 'xxx'?
You can use traceback and sys modules to get advanced traceback output like you are wishing for.
Here is an example:
import traceback
import sys
def func():
zeroDivide = 1 / 0
try:
func()
except Exception:
print(traceback.format_exc()) # This line is for getting traceback.
print(sys.exc_info()[2]) # This line is getting for the error type.
Output will be:
Traceback (most recent call last):
File "b:\abc\1234\pppp\main.py", line 10, in <module>
func()
File "b:\abc\1234\pppp\main.py", line 7, in func
zeroDivide = 1 / 0
ZeroDivisionError: division by zero
You can use the traceback module to get the line number of the error,
import traceback
def function():
try:
# code
except:
tb_list = traceback.extract_tb(sys.exc_info()[2])
line_number = tb_list[-1][1]
print("An error occurred on line:", line_number)
You can use the traceback.extract_tb() function. This function returns a list of traceback objects, each of which contain information about the stack trace. The last element of this list, tb_list[-1], holds information about the line where the exception occurred. To access the line number, you can use the second element of this tuple, tb_list[-1][1]. This value can then be printed using the print() function.
To get the line number as an int you can get the traceback as a list from traceback.extract_tb(). Looking at the last item gives you the line where the exception was raised:
#soPrintLineOfError2
import sys
import traceback
def func():
if xx == 1:
print('ok')
try:
func()
except Exception as e:
tb = sys.exc_info()[2]
ss = traceback.extract_tb(tb)
ss1 = ss[-1]
print(ss1.line)
print(ss1.lineno)
Output:
if xx == 1:
6

Handle KeyError exception and get dictionary name which caused the trouble

KeyError exception object contains args attribute. This is a list and it contains a key name which user tries to access within a dictionary.
Is it possible to figure out dictionary name which does not contain that key and which caused an exception while trying to access the key within it?
Example
data = {"my_key": "my_value"}
try:
data["unknown_key"] except KeyError as e:
print("key name: ", e.args[0])
print("dictionary name: ", e.???) # Here I would need to know the the name of a variable which stores the dictionary is "data"
You can kinda hack this with Python 3.11+, since the traceback contains fine-grained information about where the error happened.
import ast
import linecache
import traceback
data = {"my_key": "my_value"}
flurk = data
try:
data["flep"] = data["my_key"] + flurk["unknown_key"]
except KeyError as e:
# Find the last frame where the exception occurred, formatted as a FrameSummary
err_frame = traceback.TracebackException.from_exception(e).stack[-1]
if err_frame.lineno == getattr(err_frame, "end_lineno", -1): # If we can reliably find the line,
# ... read the line,
line = linecache.getline(err_frame.filename, err_frame.lineno)
# find the "marked segment" in it,
fragment = line[err_frame.colno:err_frame.end_colno]
# ... and parse it as an expression.
expr: ast.Expression = ast.parse(fragment, mode='eval')
# Check we're dealing with a subscript (index) node...
assert isinstance(expr.body, ast.Subscript)
# ... and extract the main parts of the expression.
subscriptee = ast.unparse(expr.body.value)
subscript = ast.unparse(expr.body.slice)
else:
subscriptee = None # No idea
subscript = e.args[0] # Just use the exception message
raise RuntimeError(f"KeyError with {subscriptee=!r}, {subscript=!r}") from e
prints out
Traceback (most recent call last):
File "scratch_679.py", line 8, in <module>
data["flep"] = data["my_key"] + flurk["unknown_key"]
~~~~~^^^^^^^^^^^^^^^
KeyError: 'unknown_key'
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "scratch_679.py", line 27, in <module>
raise RuntimeError(f"KeyError with {subscriptee=!r}, {subscript=!r}") from e
RuntimeError: KeyError with subscriptee='flurk', subscript="'unknown_key'"
so you can see the subscriptee name is flurk.

Handling key error in python

The below function parses the cisco command output,stores the output in dictionary and returns the value for a given key. This function works as expected when the dictionary contains the output. However, if the command returns no output at all the length of dictionary is 0 and the function returns a key error . I have used exception KeyError: But this doesn't seem to work.
from qa.ssh import Ssh
import re
class crypto:
def __init__(self, username, ip, password, machinetype):
self.user_name = username
self.ip_address = ip
self.pass_word = password
self.machine_type = machinetype
self.router_ssh = Ssh(ip=self.ip_address,
user=self.user_name,
password=self.pass_word,
machine_type=self.machine_type
)
def session_status(self, interface):
command = 'show crypto session interface '+interface
result = self.router_ssh.cmd(command)
try:
resultDict = dict(map(str.strip, line.split(':', 1))
for line in result.split('\n') if ':' in line)
return resultDict
except KeyError:
return False
test script :
obj = crypto('uname', 'ipaddr', 'password', 'router')
out = obj.session_status('tunnel0')
status = out['Peer']
print(status)
Error
Traceback (most recent call last):
File "./test_parser.py", line 16, in <module>
status = out['Peer']
KeyError: 'Peer'
The KeyError did not happend in the function session_status,it is happend in your script at status = out['Peer'].So your try and except in session_status will not work.you should make a try and except for status = out['Peer']:
try:
status = out['Peer']
except KeyError:
print 'no Peer'
or :
status = out.get('Peer', None)
Your exception is not in the right place. As you said you just return an empty dictionary with your function. The exception is trying to lookup the key on empty dictionary object that is returned status = outertunnel['Peer']. It might be easier to check it with the dict get function. status = outertunnel.get('Peer',False) or improve the test within the function session_status, like testing the length to decide what to return False if len(resultDict) == 0
This explains the problem you're seeing.
The exception happens when you reference out['Peer'] because out is an empty dict. To see where the KeyError exception can come into play, this is how it operates on an empty dict:
out = {}
status = out['Peer']
Throws the error you're seeing. The following shows how to deal with an unfound key in out:
out = {}
try:
status = out['Peer']
except KeyError:
status = False
print('The key you asked for is not here status has been set to False')
Even if the returned object was False, out['Peer'] still fails:
>>> out = False
>>> out['Peer']
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
out['Peer']
TypeError: 'bool' object is not subscriptable
I'm not sure how you should proceed, but dealing with the result of session_status not having the values you need is the way forward, and the try: except: block inside the session_status function isn't doing anything at the moment.

Condition not being evaluated as expected

I have a piece of code that acts as a listener of a button and evaluates whether some fields above this button are filled in:
def goListener(self):
if all( [self.nme.get() != "", self.dsc.get() != "", self.imp.get != ""] ):
name = self.nme.get()
desc = self.dsc.get()
while True:
try:
imp = int(self.imp.get())
break
except:
imp = int(self.imp.get())
When I run this program with different fields filled in or otherwise, it gets it right and produces the error message I ask it to with every combination except where nme and dsc are filled in but imp isn't, this produces the error message:
Traceback (most recent call last):
File "C:\Python33\lib\tkinter\__init__.py", line 1442, in __call__
return self.func(*args)
File "C:\Python33\todo.py", line 68, in goListener
imp = int(self.imp.get())
ValueError: invalid literal for int() with base 10: ''
This is running the except block by the way, which it shouldn't. Is this a problem with the evaluation, or am I missing something here?
You have:
self.imp.get != ""
You are failing to invoke the .get() method. Try:
self.imp.get() != ""
If imp = int(self.imp.get()) throws an error, calling it again outside of a try block will throw the same error.
The except block is for code that should run when there is an exception:
try:
imp = int(self.imp.get())
break
except:
print "Something bad happened"

Python:winreg module :Windows 7:None is not valid HKEY error

I ran into issues while reading registry value for windows 7 winth winreg module .Any pointers to resolve the same?
Code :
try:
ParentKey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall")
i = 0
while 1:
name, value, type = _winreg.EnumValue(ParentKey, i)
print repr(name),
i += 1
except Exception as e:
print(Exception(e))
ParentKey =_winreg.DisableReflectionKey(ParentKey)
temp = _winreg.QueryValueEx(ParentKey, 'DisplayName')
temp1 = _winreg.QueryValueEx(ParentKey, 'DisplayVersion')
temp2 = _winreg.QueryValueEx(ParentKey, 'Publisher')
temp3 = _winreg.QueryValueEx(ParentKey, 'InstallLocation')
display = str(temp[0])
display_ver=str(temp1[0])
display_p=str(temp2[0])
display_loc=str(temp3)
print ('Display Name: ' + display + '\nDisplay version: ' + display_ver + '\nVendor/Publisher: ' + display_p +'\nRegkey: ' + display_loc +'\nInstall Location: ' )
Output:
[Error 259] No more data is available
Traceback (most recent call last):
File "C:\Users\Test\workspace\Pythontests\src\test.py", line 24, in <module>
temp = _winreg.QueryValueEx(ParentKey, 'DisplayName')
TypeError: None is not a valid HKEY in this context
**strong text**
This line:
ParentKey = _winreg.DisableReflectionKey(ParentKey)
will return None. The function DisableReflectionKey is not documented as returning anything (success or failure is indicated by whether or not an exception is raised). Such a function that does not return anything returns None implicitly. Since you bind the returned value to ParentKey, that variable will holds None from that point on.
So, of course the subsequent call,
_winreg.QueryValueEx(ParentKey, 'DisplayName')
will fail since QueryValueEx requires a defined key (not None) to work.

Categories

Resources