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
Related
def strornum(a):
try:
return(a/1)
except Exception:
return("ERROR")
bob=strornum("W")
print(bob)
This gives me the correct error of "ERROR"
def strornum(a):
try:
return(a/1)
except Exception:
return("ERROR")
bob=strornum(W)
print(bob)
This is not handled and gives me "NameError: name 'W' is not defined"
I need to capture this error
Any ideas?
What you want is not possible.
When you call a function, all the arguments are evaluated before the code in the function is executed. Python doesn't wait until you refer to the parameter variable inside the function (there are some languages that do this, it's called "lazy evaluation").
So the error is raised in the calling code, before entering your try/except block, so it can't catch it there.
Running the failing code gives the traceback message
Traceback (most recent call last):
File "test.py", line 7, in <module>
bob=strornum(W)
NameError: name 'W' is not defined
The error was raised when you tried to call the function, not in the function itself. W is not defined at the point of the call. The solution is to add another exception handler at that level.
def strornum(a):
try:
return(a/1)
except Exception:
return("ERROR")
try:
bob=strornum(W)
print(bob)
except Exception:
print("Outer Error")
obligatory warning: Catching all exceptions is usually not a good idea because it can mask real problems with your code.
I can call functions in my dll from python.
When I call a dll function that does a callback to my python code it fails.
It there some sort of mutex blocking my callback?
from ctypes import *
import _ctypes
#CFUNCTYPE(None)
def Test():
print ("Test here")
return
def SetUpDll():
print ("Setting read / write callback functions...")
windll.ClaRUN.AttachThreadToClarion(1)
MyDll = CDLL('IC2_CommsServer.dll')
SetTestFunc = getattr(MyDll, "SETTESTFUNC#Fl")
SetTestFunc (Test)
CallTestFunc = getattr(MyDll, "CALLTESTFUNC#F")
CallTestFunc()
_ctypes.FreeLibrary(MyDll._handle)
_ctypes.FreeLibrary(windll.ClaRUN._handle)
print ("Done.")
SetUpDll()
C:\Users\Derek\anaconda3_32\python.exe Z:/ps_IC2_dll/ps_IC2_dll.py
Setting read / write callback functions...
Traceback (most recent call last):
File "Z:/ps_IC2_dll/ps_IC2_dll.py", line 48, in <module>
SetUpDll()
File "Z:/ps_IC2_dll/ps_IC2_dll.py", line 40, in SetUpDll
CallTestFunc()
OSError: exception: access violation writing 0x009EF77C
Process finished with exit code 1
First, on Windows, the ctypes uses win32 structured exception handling to prevent crashes from general protection faults when functions are called with invalid argument values.
You have a bad call for this line of code:
CallTestFunc = getattr(MyDll, "CALLTESTFUNC#F")
Try to review your code, then see if the problem is from ps_IC2_dll.py build area.
Thanks to CristiFati who provided half of the answer.
This code now works, note that the clarion dll functions are now prototyped as ,C
A nice side effect is that the function names loose the "#F" suffix and so the code is simpler.
from ctypes import *
import _ctypes
#CFUNCTYPE(None)
def Test():
print ("Test here")
return
def SetUpDll():
print ("Setting read / write callback functions... Ptr=", sizeof(c_void_p), "bytes")
assert sizeof(c_void_p) == 4
ClaRTL = CDLL('./ClaRUN.dll')
MyDll = CDLL('./IC2_CommsServer.dll')
ClaRTL.AttachThreadToClarion.restype = None
ClaRTL.AttachThreadToClarion.argtypes = [c_int32]
ClaRTL.AttachThreadToClarion(1)
MyDll.SETTESTFUNC.restype = None
MyDll.SETTESTFUNC.argtypes = [CFUNCTYPE(None)]
MyDll.SETTESTFUNC (Test)
MyDll.CALLTESTFUNC.restype = None
MyDll.CALLTESTFUNC ()
_ctypes.FreeLibrary(MyDll._handle)
_ctypes.FreeLibrary(ClaRTL._handle)
print ("Done.")
SetUpDll()
Output is now:
C:\Users\Derek\AppData\Local\Programs\Python\Python38-32\python.exe Z:/ps_IC2_dll/ps_IC2_dll.py
Setting read / write callback functions... Ptr= 4 bytes
Test here
Done.
Process finished with exit code 0
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
Before using the value of a return of a function, I want to check if the value is useable. So what I have is more or less the following:
def get_module():
import foo
return foo
def do_something():
try:
module = get_module()
except:
print "error"
module.bar()
Unfortunately, it seems to me that this never raises an exception. In particular, I want to check (a) that the module was transferred correctly and (b) that the module is one of three possible modules.
I know I can check through if-statements, but I feel that exception handing is ought to be the correct way.
If foo cannot be imported, the code below will produce an ImportError exception:
def get_module():
import foo
return foo
def do_something():
try:
module = get_module()
except ImportError:
print "Import Error!"
raise
module.bar()
do_something()
Produces:
Import Error!
Traceback (most recent call last):
...
import foo
ImportError: No module named foo
Note, that you should either reraise the exception via raise in the except block, or make a return, so that you don't get an error on module.bar() line because of undefined module variable.
Hope that helps.
I have been stuck with this error for a couple of hours now. Not sure what is wrong. Below is the piece of code
NameError: global name 'GetText' is not defined
class BaseScreen(object):
def GetTextFromScreen(self, x, y, a, b, noofrows = 0):
count = 0
message = ""
while (count < noofrows):
line = Region(self.screen.x + x, self.screen.y + y + (count * 20), a, b)
message = message + "\n" + line.text()
count += 1
return message
class HomeScreen(BaseScreen):
def GetSearchResults(self):
if self.screen.exists("Noitemsfound.png"):
return 'No Items Found'
else:
return self.GetTextFromScreen(36, 274, 680, 20, 16)
class HomeTests(unittest.TestCase):
def test_001S(self):
Home = HomeScreen()
Home.ResetSearchCriteria()
Home.Search("0009", "Key")
self.assertTrue("0009" in Home.GetSearchResults(), "Key was not returned")
Basescreen class has all the reusable methods applicable across different screens.
Homescreen inherits Basescreen.
In HomeTests test case class, the last step is to Home.GetSearchResults() which in turn calls a base class method and the error.
Note:
I have another screenclass and testcaseclass doing the same which works without issues.
I have checked all the importing statements and is ok
'GetText' in the error message is the name of method initially after which i changed it to GetTextFromScreen
Error message is still pointing to a line 88 in code which is not there any more. Module import/reloading issue?
Try clearing out your *.pyc files (or __pycache__ if using 3+).
You asked:
Error message is still pointing to a line 88 in code which is not there any more. Module import/reloading issue?
Yes. The traceback (error messages) will show the current (newest saved) file, even if you haven't run it yet. You must reload/reimport to get the new file.
The discrepancy comes from the fact that traceback printouts read from the script file (scriptname.py) saved on your drive. However, the program is run either from the module saved in memory, or sometimes from the .pyc file. If you fix an error by changing your script, and save it to your drive, then the same error will still occur if you don't reload it.
If you're running interactively for testing, you can use the reload function:
>>> import mymodule
>>> mymodule.somefunction()
Traceback (most recent call last):
File "mymodule.py", line 3, in somefunction
Here is a broken line
OhNoError: Problem with your file
Now, you fix the error and save mymodule.py, return to your interactive session, but you still get the error, but the traceback shows the fixed line
>>> mymodule.somefunction()
Traceback (most recent call last):
File "mymodule.py", line 3, in somefunction
Here is the fixed line
OhNoError: Problem with your file
So you have to reload the module:
>>> reload(mymodule)
<module 'mymodule' from '/path/to/mymodule.py'>
>>> mymodule.somefunction()
Success!