traceback not full when passing to next fucntion [closed] - python

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
Basically I have something like this:
import traceback
def function1():
try:
temp = None
temp = int(temp)
except:
pass
Which obviously rises error (due to casting NoneType to int), then there is a second method that is called only if previous one had error:
def function2():
# do something
traceback.print_exc()
Though it doesn't print full traceback as it would do if invoked in the except clause, it just says:
NoneType: None
Where does this change come from? And is there any way to still print a full stack trace?

If you call like this, the error context, the traceback does not longer exists as you went away from it
function1()
function2()
You need to call function2 from the except block, to keep track of the traceback
import traceback
def function1():
try:
temp = None
temp = int(temp)
except:
function2()
def function2():
traceback.print_exc()
if __name__ == '__main__':
function1()
Giving
Traceback (most recent call last):
File "C:\Users\...\test_4.py", line 7, in function1
temp = int(temp)
TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType'

Related

Python unit test - NameError: name 'upper' is not defined [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Using Python 3.x. When running the test case for the following code, I get the error - NameError: name 'upper' is not defined. I am attaching the file to test, the File_P_third file where is the code, and the unit test file test_upper.
File File_P_third:
def upper_text(text):
return text.upper()
File test_upper:
import unittest
import File_P_third
class TestUpper(unittest.TestCase):
"""docstring for ClassName"""
def test_one_word(self):
text = 'hello!'
result = upper.upper_text(text)
self.assertEqual(result, 'HELLO!')
if __name__ == '__main__':
unittest.main()
My cmd`s exit text:
D:\Дохуя программист\Projects>python test_upper.py
E
======================================================================
ERROR: test_one_word (__main__.TestUpper)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_upper.py", line 9, in test_one_word
result = upper.upper_text(text)
NameError: name 'upper' is not defined
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (errors=1)
All files is in one directory and I still cant understand why is doesnt work. Can`t search the same problem in internet((
If you're trying to transform 'hello' to upper case, the function to do so in python is string.upper()
i takes no parameter see below:
test='hello'
up=test.upper()
print(up)
# prints HELLO
Replace import File_P_third with from File_P_third import upper_text. Call your function this way result = upper_text(text). Also make sure, both files File_P_third.py and test_upper.py are in the same directory.
Below you'll find the complete code for your file File_P_third.py:
import unittest
from File_P_third import upper_text
class TestUpper(unittest.TestCase):
"""docstring for ClassName"""
def test_one_word(self):
text = 'hello!'
result = upper_text(text)
self.assertEqual(result, 'HELLO!')
if __name__ == '__main__':
unittest.main()

Pretty new to Python, how to write code for this test?

i'm pretty new to python, and my instructor has a series of unit tests that we had to write code for. I've gotten all of them pretty easy, except for this:
class Tester(unittest.TestCase):
def setUp(self):
pass
def test_failure(self):
l = ListClass()
with self.assertRaises(TypeError) as typ:
l.sortlist("string")
exc = typ.exception
self.assertEqual(exc.error_code, "Input isn't a list")
i've tried many ways to get this to return a successful test, but I can't figure it out. currently my code (which has gone through a ton of changes and probably doesn't make much sense) looks like this:
class ListClass():
def __init__(self):
pass
class TypeError(Exception):
pass
#staticmethod
def sortlist(num_list):
try:
inst = isinstance(num_list, list)
if inst:
num_list.sort()
return num_list
else:
raise TypeError
except TypeError:
print("Input isn't a list")
The error I consistently get while fiddling with my code is:
ERROR: test_failure (__main__.Tester)
----------------------------------------------------------------------
Traceback (most recent call last):
File ---------, line 13, in test_failure
exc = typ.exception
AttributeError: '_AssertRaisesContext' object has no attribute 'exception'
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
Process finished with exit code 1
i'm trying to figure out what this error means. is the '_AssertRaisesContext' object part of a python library?

How to get the stack trace of a nested exeption in python?

If an exception is raised I'd like to analyse the stack trace in python that tells about where exactly the problem is in the source code file.
Of course for that purpose the module traceback exists. And that works fine for regular exceptions. But how do you deal with this situation if nested exceptions occur?
Consider this example:
def test():
try:
a = 0
b = 5 / a
except Exception as ee1:
assert False
test()
This example prints two exceptions:
Traceback (most recent call last):
File "./test4d.py", line 12, in test
b = 5 / a
ZeroDivisionError: division by zero
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "./test4d.py", line 18, in <module>
test()
File "./test4d.py", line 14, in test
assert False
AssertionError
So information about both exceptions is known to the interpreter. I therefore like to retrieve these two pieces of information from Python: The stack trace of the assert statement (used as an example here to cause an exception) and the stack trace of the division by zero exception (used as an example here to cause an exception). How can I do that?
And the second part of the question: How can I do that in a structured way? The module traceback can be used to get more information about an existing exception. But I do not want to print the exception, I want to store it. Therefore I'd like to get the stack trace as a tuple of instances of some class where each instance represents the data within each stack frame. How can I do that?
There is a variable named __context__ associated with an exception. This variable can be used to access nested exceptions. See this example:
import traceback
def test():
try:
a = 0
b = 5 / a
except Exception as ee1:
assert False
try:
test()
except Exception as ee:
print(repr(ee))
stackTraceList = traceback.extract_stack(ee.__traceback__.tb_frame)
del stackTraceList[0]
for frame in stackTraceList:
print("\t", frame)
if ee.__context__:
print(repr(ee.__context__))
stackTraceList = traceback.extract_stack(ee.__context__.__traceback__.tb_frame)
del stackTraceList[0]
for frame in stackTraceList:
print("\t", frame)
This will output the following text:
AssertionError()
ZeroDivisionError('division by zero',)
<FrameSummary file ./example.py, line 8 in test>
That indicates that both exceptions can be identified and their stack traces can be iterated through.
For convenience I implemented a simple helper module to process exceptions and stack traces named jk_exceptionhelper. You can install this module using pip. For details have a look at the GIT repository: https://github.com/jkpubsrc/python-module-jk-exceptionhelper

Exception message best practices [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I've written a small production-level Flask application in Python with standard exception handling. Most of the time I'm just logging the exception message and it looks like this
try:
#Do something
except Exception, e:
logger.error('Exception in LoadValidationDocs in main.py : %s' % str(e.args))
return None
I was wondering if I should keep all such error messages in a separate strings.py file like
standard_exception_message = 'Exception in %s in %s, Exception Args : %s'
and get function and module name at run time like
import inspect
function_name = inspect.stack()[0][3]
file_name = os.path.basename(__file__)
logger.error(strings. standard_exception_message % (function_name, file_name, str(e.args)))
I just want to know whether it's necessary to do that and is it even the correct way of doing it considering my current scenario.
You can use logging.exception instead of logging.error. It will take care of looking for the function, module name etc. for you in a formatted way:
import logging
try:
# Do something that will fail
x = 1 / 0
except Exception as e:
logging.exception("This is my message when an error happens here.")
It gives:
ERROR:root:This is my message when an error happens here.
Traceback (most recent call last):
File "question39724934.py", line 5, in compute
x = 1 / 0
ZeroDivisionError: division by zero

Python handling the name error exception

I wrote a small code and tried to handle the name error exception.
I want to print a custom message even if there is an exception, but it is showing the complete the trace back.
#!/usr/bin/python -tt
import logging
def equaldigits(a, b):
logging.basicConfig(filename='run.log',level=logging.INFO)
try:
c = a - b
logging.info('%s is the difference between both the digits', str(c))
print c
return c
except NameError as e:
c = 'Unable to successfully complete execution'
logging.info(c)
print c
#return c
def main():
print '\n1st call'
equaldigits(10, 10)
print '\n2nd call'
equaldigits(1, 0)
print '\nException call'
equaldigits(a, 0)
# Standard boilerplate to call the main() function.
if __name__ == '__main__':
main()
This is the console output
1st call
0
2nd call
1
Exception call
Traceback (most recent call last):
File "./sut.py", line 28, in <module>
main()
File "./sut.py", line 24, in main
equaldigits(a, 0)
NameError: global name 'a' is not defined
In your attempt to catch an exception, you wrote equaldigits(a, 0). The interpreter sees the a and thinks it is a variable that isn't there, thus throwing the uncaught exception. In order to test your try/catch, you need to pass the letter a, like so
equaldigits('a', 0)
^ ^ note the quotes
The problem isn't happening within your equaldigits function where you have your logging information.
Its happening in your main function when the interpreter tries to pass the value of a to equaldigits. The variable a doesn't exist within the local scope of main, thus Python tries to find a global variable named a. Since it doesn't see one, it throws a NameError.
Your error is caused by the fact that a is not defined when you call equaldigits, the execution doesn't get to the try/except clause inside the function.
when you change
a - b
to
a - d
inside the function you'll see that your try/except works fine

Categories

Resources