At the moment, I heavily rely on traceback to check python errors (on my console). However, the traceback is not output on the console when the error happens in a thread different from the main one:
def test(n):
time.sleep(10-n)
print(n)
assert False
#assert False #if uncommented the console correctly show the traceback
with futures.ThreadPoolExecutor(4) as executor:
res=executor.map(test,range(10))
print("DONE finally")
If I uncomment the "assert false" the traceback returned is the following one:
Traceback (most recent call last):
File "C:/Users/massimo.bono/Documents/PythonWorkspace/AntaresPythonUtils/AntaresUtils/thread_try.py", line 14, in
assert False
AssertionError
If leave the comment, the output of the console is the following:
3
2
1
0
4
6
5
7
9
8
DONE finally
Process finished with exit code 0
Other infos useful to help me:
I'm using python 3.4.3;
my python console is the one embedded in PyCharm Community Edition 4.5.2
I'm on windows 8.1 64bit;
I tried to run the same python file from the windows powershell by entering in the python console, but the traceback was not displayed.
For what I understood it seems that the traceback of the threads still existed in the python runtime: they weren't simply printed on the stderr.
You can solve the issue by catching any exception in the method called by the executor, like this:
#this will be executed in a different thread. If any exception is caught
#it will be printed on the console
def thread_safe(n):
try:
test(n)
except Exception as e:
traceback.print_exc()
with futures.ThreadPoolExecutor(4) as executor:
res=executor.map(thread_safe,range(10))
print("DONE finally")
Related
kochat is a Korean chatbot, and I ran into a problem while practicing it.
github imformation : https://github.com/hyunwoongko/kochat
It is environment setting
python3.8
pip install kochat
JPype is reinstalled ues JPype1-1.2.0-cp38-cp38-win_amd64.whl <-download
pytorch is same ver with cuda 11.1
start code
### from kochat.proc import DistanceClassifier ###
from kochat.data import Dataset
from kochat.proc import GensimEmbedder, DistanceClassifier
from kochat.model import intent, embed
from kochat.loss import CenterLoss
dataset = Dataset(ood=True)
emb = GensimEmbedder(model=embed.Word2Vec())
# 프로세서 생성
clf = DistanceClassifier(
model=intent.CNN(dataset.intent_dict),
loss=CenterLoss(dataset.intent_dict)
)
# 되도록이면 DistanceClassifier는 Margin 기반의 Loss 함수를 이용해주세요
# 현재는 CenterLoss, COCOLoss, Cosface, GausianMixture 등의
# 거리기반 Metric Learning 전용 Loss함수를 지원합니다.
# 모델 학습
clf.fit(dataset.load_intent(emb))
# 모델 추론 (인텐트 분류)
clf.predict(dataset.load_predict("오늘 서울 날씨 어떨까", emb))
error message
C:\projectkyc\kochat3.8\Scripts\python.exe "C:/projectkyc/kochat3.8/test3.8/!from kochat.proc import DistanceClassifier.py"`enter code here`
Exception ignored in: <function Image.__del__ at 0x000001E7E1566D30>
Traceback (most recent call last):
File "c:\users\user\appdata\local\programs\python\python38\lib\tkinter\__init__.py", line 4014, in __del__
Exception ignored in: <function Variable.__del__ at 0x000001E7E154B430>
Traceback (most recent call last):
File "c:\users\user\appdata\local\programs\python\python38\lib\tkinter\__init__.py", line 351, in __del__
if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <function Image.__del__ at 0x000001E7E1566D30>
Traceback (most recent call last):
File "c:\users\user\appdata\local\programs\python\python38\lib\tkinter\__init__.py", line 4014, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (os_windows_x86.cpp:144), pid=11208, tid=0x00000000000037f4
# guarantee(result == EXCEPTION_CONTINUE_EXECUTION) failed: Unexpected result from topLevelExceptionFilter
#
# JRE version: Java(TM) SE Runtime Environment (8.0_281-b09) (build 1.8.0_281-b09)
# Java VM: Java HotSpot(TM) 64-Bit Server VM (25.281-b09 mixed mode windows-amd64 compressed oops)
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# An error report file with more information is saved as:
# C:\projectkyc\kochat3.8\test3.8\hs_err_pid11208.log
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#
Exception ignored in: <function Image.__del__ at 0x000001E7E1566D30>
Traceback (most recent call last):
File "c:\users\user\appdata\local\programs\python\python38\lib\tkinter\__init__.py", line 4014, in __del__
self.tk.call('image', 'delete', self.name)
RuntimeError: main thread is not in main loop
Tcl_AsyncDelete: async handler deleted by the wrong thread
Process finished with exit code 1
If I haven't posted it or if I have the information I need, I will add it immediately upon confirmation if requested.
This is such an annoying issue and to me setting matplotlib.use('Agg') does not cut it. I dont want to comprise on this.
The only thing that seems to do it somewhat consistently is having to close the figure before creating a new plot via plt.close(). This is annoying and if i forget it does this.
this error
Matplotlib - Tcl_AsyncDelete: async handler deleted by the wrong thread?
same Question But did not know where to apply
The places to apply are kochat\utils\visualizer.py and kochat\proc\utils\visualizer.py
to be. In the
from matplotlib import pyplot as plt
part of these two places,
import matplotlib
matplotlib.use('Agg')
from matplotlib import pyplot as plt
The problem is solved.
Consider the following code snippets and the resulting printouts from the console:
Snippet 1
Behaves just fine. Everything is hunkydory.
Code
try:
raise ValueError()
finally:
print(3)
Console Output
Traceback (most recent call last):
File "D:/FILE_MGMT_PYTHON/fbzdfbhedrh.py", line 5, in <module>
raise ValueError()
ValueError
3
Snippet 2
Also behaves just fine. Everything is hunkydory.
Code
try:
raise ValueError()
except type("", (Exception,), dict()):
print("this is not supposed to print")
finally:
print(3)
Console Output
3
Traceback (most recent call last):
File "D:/FILE_MGMT_PYTHON/fbzdfbhedrh.py", line 14, in <module>
raise ValueError()
ValueError
Snippet 3
I don't understand why the following does not result in an unhandled exception being printed to the console:
Code
def e():
try:
raise ValueError()
x = y + z
L = [1, 2, 3]
print(L[9999999999999999999999999999])
except type("", (Exception,), dict()) as exc:
print("this is not supposed to print")
return "strawberries " + src(exc)
finally:
return "finally"
print(e())
Console Output
finally
Process finished with exit code 0
Build:
------------------
System Information
------------------
Time of this report: 10/25/2019, 07:22:01
Machine name: DESKTOP-U5M46TJ
Machine Id: {403D9006-3BF1-4C4B-AAF5-2AD795E00738}
Operating System: Windows 10 Pro 64-bit (10.0, Build 18362) (18362.19h1_release.190318-1202)
Language: English (Regional Setting: English)
System Manufacturer: System manufacturer
System Model: System Product Name
BIOS: BIOS Date: 10/31/12 20:41:07 Ver: 36.02 (type: BIOS)
Processor: Intel(R) Core(TM) i5-2500K CPU # 3.30GHz (4 CPUs), ~3.3GHz
Memory: 4096MB RAM
Available OS Memory: 4064MB RAM
Page File: 12606MB used, 3744MB available
Windows Dir: C:\Windows
DirectX Version: DirectX 12
DX Setup Parameters: Not found
User DPI Setting: 96 DPI (100 percent)
System DPI Setting: 144 DPI (150 percent)
DWM DPI Scaling: UnKnown
Miracast: Available, with HDCP
Microsoft Graphics Hybrid: Not Supported
DirectX Database Version: Unknown
DxDiag Version: 10.00.18362.0387 64bit Unicode
------------------
IDE Information
------------------
PyCharm 2019.1.3 (Community Edition)
Build #PC-191.7479.30, built on May 29, 2019
JRE: 11.0.2+9-b159.60 amd64
JVM: OpenJDK 64-Bit Server VM by JetBrains s.r.o
Windows 10 10.0
------------------
Python Information
------------------
print(sys.version)
print(sys.version_info)
print(sys.hexversion)
3.8.0 (tags/v3.8.0:fa919fd, Oct 14 2019, 19:21:23) [MSC v.1916 32 bit (Intel)]
sys.version_info(major=3, minor=8, micro=0, releaselevel='final', serial=0)
50856176
Returning from a finally block discards the exception. The function can't return and raise the exception, and you're telling it that you want it to return.
The exception is going to be thrown, but before the try statement can be exited, the finally block needs to be run. Your finally block says "regardless of whatever you thought you were doing, I want to return". So the exception is discarded.
Similary, if you were returning from a try block, and the finally block raised an exception, the return value would be discarded.
See Defining Clean-up Actions in the Python docs:
If an exception occurs during execution of the try clause, the exception may be handled by an except clause. If the exception is not handled by an except clause, the exception is re-raised after the finally clause has been executed.
...
If a finally clause includes a return statement, the finally clause’s return statement will execute before, and instead of, the return statement in a try clause.
The reason is your except statement.
>>> type("", (Exception,), dict())
<class '__main__.'>
And since a "ValueError" is not an exception of that type it won't catch the exception and will only go into the finally statement.
Change the except statement to:
except ValueError as e:
pass
# or this:
except Exception as e:
pass
Is there any way to set exit code in the function registered in atexit module and called on exit? The call to sys.exit(code) produces an error and does not set exit code to the desired value.
d:\>python atexit_test.py
Error in atexit._run_exitfuncs:
Traceback (most recent call last):
File "atexit_test.py", line 3, in myexit
sys.exit(2)
SystemExit: 2
d:\>echo %ERRORLEVEL%
0
The contents of atexit_test.py:
def myexit():
import sys
sys.exit(2)
import atexit
atexit.register(myexit)
I can prove the test code works in Python 2.7.x (2.7.6 in my case), as reported by #Łukasz Rogalski. So I’ve assumed this to be a bug of Python 3.x and filed a bug report.
In my code I am having a TypeError exception that is crashing my code. In this one particular program (I created a test file to reproduce the error and couldn't) the traceback only says TypeError: 'int' object is unsubscriptable with no information about where it was occuring. I tried creating my own exception before the function call that this must be happening in by 1[0] and got the same problem. When I try causing a different kind of exception by foo_that_doesn't_exist() I get a proper traceback with where the error occurred. I'm running the IronPython interpreter and because of some dependencies on C# code I can't test with CPython.
EDIT: I tracked down the problem in my own code, and then found a way to reproduce it. The problem can be recreated with:
import traceback
import sys
try:
try:
1[0]
except:
raise
except:
traceback.print_tb(sys.exc_info()[2])
Which returns nothing while:
import traceback
import sys
try:
1[0]
except:
traceback.print_tb(sys.exc_info()[2])
returns
File "a.py", line 6, in <module>
1[0]
I know that print(e) (where e is an Exception) prints the occurred exception
but, I was trying to find the python equivalent of Java's e.printStackTrace() that exactly traces the exception to what line it occurred and prints the entire trace of it.
Could anyone please tell me the equivalent of e.printStackTrace() in Python?
import traceback
traceback.print_exc()
When doing this inside an except ...: block it will automatically use the current exception. See http://docs.python.org/library/traceback.html for more information.
There is also logging.exception.
import logging
...
try:
g()
except Exception as ex:
logging.exception("Something awful happened!")
# will print this message followed by traceback
Output:
ERROR 2007-09-18 23:30:19,913 error 1294 Something awful happened!
Traceback (most recent call last):
File "b.py", line 22, in f
g()
File "b.py", line 14, in g
1/0
ZeroDivisionError: integer division or modulo by zero
(From http://blog.tplus1.com/index.php/2007/09/28/the-python-logging-module-is-much-better-than-print-statements/ via How to print the full traceback without halting the program?)
e.printStackTrace equivalent in python
In Java, this does the following (docs):
public void printStackTrace()
Prints this throwable and its backtrace to the standard error stream...
This is used like this:
try
{
// code that may raise an error
}
catch (IOException e)
{
// exception handling
e.printStackTrace();
}
In Java, the Standard Error stream is unbuffered so that output arrives immediately.
The same semantics in Python 2 are:
import traceback
import sys
try: # code that may raise an error
pass
except IOError as e: # exception handling
# in Python 2, stderr is also unbuffered
print >> sys.stderr, traceback.format_exc()
# in Python 2, you can also from __future__ import print_function
print(traceback.format_exc(), file=sys.stderr)
# or as the top answer here demonstrates, use:
traceback.print_exc()
# which also uses stderr.
Python 3
In Python 3, we can get the traceback directly from the exception object (which likely behaves better for threaded code).
Also, stderr is line-buffered, but the print function gets
a flush argument, so this would be immediately printed to stderr:
print(traceback.format_exception(None, # <- type(e) by docs, but ignored
e, e.__traceback__),
file=sys.stderr, flush=True)
Conclusion:
In Python 3, therefore, traceback.print_exc(), although it uses sys.stderr by default, would buffer the output, and you may possibly lose it. So to get as equivalent semantics as possible, in Python 3, use print with flush=True.
Adding to the other great answers, we can use the Python logging library's debug(), info(), warning(), error(), and critical() methods. Quoting from the docs for Python 3.7.4,
There are three keyword arguments in kwargs which are inspected: exc_info which, if it does not evaluate as false, causes exception information to be added to the logging message.
What this means is, you can use the Python logging library to output a debug(), or other type of message, and the logging library will include the stack trace in its output. With this in mind, we can do the following:
import logging
logger = logging.getLogger()
logger.setLevel(logging.DEBUG)
def f():
a = { 'foo': None }
# the following line will raise KeyError
b = a['bar']
def g():
f()
try:
g()
except Exception as e:
logger.error(str(e), exc_info=True)
And it will output:
'bar'
Traceback (most recent call last):
File "<ipython-input-2-8ae09e08766b>", line 18, in <module>
g()
File "<ipython-input-2-8ae09e08766b>", line 14, in g
f()
File "<ipython-input-2-8ae09e08766b>", line 10, in f
b = a['bar']
KeyError: 'bar'