Issue 1230540: Add threading.excepthook() to handle uncaught exceptions raised by Thread.run() (original) (raw)

Created on 2005-06-30 19:06 by ellisj, last changed 2022-04-11 14:56 by admin. This issue is now closed.

Messages (42)

msg25694 - (view)

Author: Jonathan Ellis (ellisj)

Date: 2005-06-30 19:06

simple script to reproduce:

import sys, threading

def log_exception(*args): print 'got exception %s' % (args,) sys.excepthook = log_exception

def foo(): a = 1 / 0 threading.Thread(target=foo).start()

Note that a normal traceback is printed instead of "got exception."

msg25695 - (view)

Author: Michael Hudson (mwh) (Python committer)

Date: 2007-06-06 11:11

I've just run into this, and it's very annoying. The stupid part is that threads started with the thread module don't have this problem, it's just a problem with threading.Thread()s trying to be too clever.

I would vote for deleting all the code to do with exception printing in threading.py and letting the C machinery take care of it.

msg25696 - (view)

Author: Jonathan Ellis (ellisj)

Date: 2007-06-15 02:04

Here is a workaround in the meantime:

def install_thread_excepthook(): """ Workaround for sys.excepthook thread bug (https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470). Call once from main before creating any threads. If using psyco, call psycho.cannotcompile(threading.Thread.run) since this replaces a new-style class method. """ import sys run_old = threading.Thread.run def run(*args, **kwargs): try: run_old(*args, **kwargs) except (KeyboardInterrupt, SystemExit): raise except: sys.excepthook(*sys.exc_info()) threading.Thread.run = run

msg62933 - (view)

Author: Tiago Alves (tiagoaoa)

Date: 2008-02-24 20:40

I don't see it as a problem or as the threading module trying to be "clever". It clearly was a design choice to make the module have its own exception treatment in order to make it clear in which thread the exception occurred. IMHO the decision here should be to implement per thread excepthook's.

msg91243 - (view)

Author: Ian Beaver (undercoveridiot)

Date: 2009-08-03 21:59

I found that the workaround suggested doesn't work when you have a subclass of threading.Thread and you want to catch everything in the module that contains the class to a common log.

Say you have a module with a socket server that spawns a thread on accept and you want to log anything that tracebacks in the module. This seems to work:

import sys import logging from functools import wraps

def myExceptHook(type, value, tb): """ Redirect tracebacks to error log """ import traceback rawreport = traceback.format_exception(type, value, tb) report = '\n'.join(rawreport) log.error(report)

sys.excepthook = myExceptHook

def use_my_excepthook(view): """ Redirect any unexpected tracebacks """ @wraps(view) def run(*args, **kwargs): try: return view(*args, **kwargs) except: sys.excepthook(*sys.exc_info()) return run

Then in your thread subclass:

class MyThread(threading.Thread): def init(self, socket_conn): threading.Thread.init(self) self.my_conn = socket_conn

@use_my_excepthook
def run(self):
    """ Do stuff """

msg91244 - (view)

Author: Ian Beaver (undercoveridiot)

Date: 2009-08-03 22:24

Instead of using decorators, this is a slightly simpler modification to the proposed workaround that allows for any subclassed run method to also be caught.

def installThreadExcepthook(): """ Workaround for sys.excepthook thread bug From http://spyced.blogspot.com/2007/06/workaround-for-sysexcepthook-bug.html

(https://sourceforge.net/tracker/?func=detail&atid=105470&aid=1230540&group_id=5470). Call once from main before creating any threads. If using psyco, call psyco.cannotcompile(threading.Thread.run) since this replaces a new-style class method. """ init_old = threading.Thread.init def init(self, *args, **kwargs): init_old(self, *args, **kwargs) run_old = self.run def run_with_except_hook(*args, **kw): try: run_old(*args, **kw) except (KeyboardInterrupt, SystemExit): raise except: sys.excepthook(*sys.exc_info()) self.run = run_with_except_hook threading.Thread.init = init

msg272002 - (view)

Author: Decorater (Decorater) *

Date: 2016-08-05 01:55

I too agree that I hate the thread exceptions being printed in the console I would suggest python was to error log it all to a file instead (so it does not spam up the console). I get it a lot with websocket / opus errors and it is annoying because it does not cleanup ffmpeg for me.

msg272003 - (view)

Author: Decorater (Decorater) *

Date: 2016-08-05 02:04

personally these exceptions in console can be annoying to me as I hate seeing them.

Exception in thread Thread-11: Traceback (most recent call last): File "threading.py", line 914, in _bootstrap_inner File "E:\Users\Elsword\Desktop\DecoraterBot\Async\test\resources\Dependencies\discord\voice_client.py", line 150, in run super().run() File "E:\Users\Elsword\Desktop\DecoraterBot\Async\test\resources\Dependencies\discord\voice_client.py", line 108, in run self.player(data) File "E:\Users\Elsword\Desktop\DecoraterBot\Async\test\resources\Dependencies\discord\voice_client.py", line 669, in play_audio sent = self.socket.sendto(packet, (self.endpoint_ip, self.voice_port)) OSError: [WinError 10055] An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full

Exception in thread Thread-21: Traceback (most recent call last): File "threading.py", line 914, in _bootstrap_inner File "E:\Users\Elsword\Desktop\DecoraterBot\Async\test\resources\Dependencies\discord\voice_client.py", line 150, in run super().run() File "E:\Users\Elsword\Desktop\DecoraterBot\Async\test\resources\Dependencies\discord\voice_client.py", line 108, in run self.player(data) File "E:\Users\Elsword\Desktop\DecoraterBot\Async\test\resources\Dependencies\discord\voice_client.py", line 669, in play_audio sent = self.socket.sendto(packet, (self.endpoint_ip, self.voice_port)) OSError: [WinError 10038] An operation was attempted on something that is not a socket

msg272006 - (view)

Author: Decorater (Decorater) *

Date: 2016-08-05 02:55

Ok, so I just found out you can bypass thread exceptions by wraping the line that actually runs the threads in a try/except block and then using the logging module to log it to a file instead of the console.

msg288513 - (view)

Author: CyberJacob (CyberJacob)

Date: 2017-02-24 09:45

Does this affect threads started with the multiprocessing library as well?

msg288514 - (view)

Author: CyberJacob (CyberJacob)

Date: 2017-02-24 10:33

Just confirmed, this does affect multiprocessing. script to reproduce:

import sys, multiprocessing

def log_exception(*args): print 'got exception %s' % (args,)

sys.excepthook = log_exception

def foo(): a = 1 / 0

multiprocessing.Process(target=foo).start()

again, just a normal traceback instead of "got exception"

msg297221 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2017-06-28 20:17

Apparently the traceback module has been used from the start (since changset 7f5013a9a9678e86bff00c97f98e7a92c515b94d) to print the exception and not sys.excepthook. I presume this is an oversight, as I don't see any reason to prefer traceback here. Tim, any insight?

msg302320 - (view)

Author: Matt Groth (Matt Groth)

Date: 2017-09-16 05:13

Thank you Antoine Pitrou, I was able to disable this behavior by commenting out some lines of code in 'traceback' and replacing them with the appropriate call to 'sys.excepthook'. Note you also have to comment out a few lines in "Modules/_threadmodule.c" to correspond to this change or else that file complains that there wasn't the expected output printed to stderr.

msg302645 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2017-09-20 17:58

Matt, do you want to post your patch here?

msg322892 - (view)

Author: Andrey Vlasovskikh (vlasovskikh) *

Date: 2018-08-01 22:08

I've added a PR with a patch I developed during the EuroPython 2018 sprint.

I've fixed this issue in a way that is more or less consistent with how '_thread' threads interact with sys.excepthook, but I haven't added the log line they print to sys.stderr about an unhandled exception in a thread:

Unhandled exception in thread started by <function <lambda> at 0x108c840d0>

I can add these messages if they are needed.

I'd like to mention the issue I discussed with Victor Stinner at the sprints (adding Victor to the nosy list as he requested). The fix could possibly break the de facto contract that has been there for ages that 'theading' threads don't invoke sys.excepthook on uncaught exceptions.

If the fact that sys.execepthook doesn't work with threading is considered a feature, then an alternative solution could be a new threading-specific hook: threading.excepthook.

msg322895 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2018-08-01 22:12

No, I think this is a bug that deserves fixing, at least in 3.8.

msg322932 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2018-08-02 09:21

Would it be possible to modify the default implementation of sys.excepthook to have a different output when it's not called from the main thread? Mimick the current traceback from threads.

Would it be possible to call threading.current_thread() from the default sys.excepthook? The problem is to get the threading module and to decide how to handle error on getting the current thread.

An alternative would be to introduce a new hook to log exceptions in threads, ex: sys.threadexcepthook. That hoook would take a 4th parameter. But Andrey Vlasovskikh didn't like this idea.

msg323111 - (view)

Author: Andrey Vlasovskikh (vlasovskikh) *

Date: 2018-08-04 15:46

Would it be possible to modify the default implementation of sys.excepthook to have a different output when it's not called from the main thread? Mimick the current traceback from threads.

I agree it's a good idea to mimic what _thread does in case of both handled and unhandled exceptions. Why would you want to do it in sys.excepthook? The code for handling unhandled exceptions in _thread threads is located in _threadmodule.c itself, so there is no dependency from sys to _thread. By following the same logic, the code for handling unhandled exceptions in threading should be located in threading.py, like it does now. So the only thing that's missing in the pull request compared to _thread is the output:

Unhandled exception in thread started by <function at 0x7f6769ca8e18>

for all the exceptions: not caught by the sys.excepthook and caught by the sys.exceptook.

An alternative would be to introduce a new hook to log exceptions in threads, ex: sys.threadexcepthook. That hoook would take a 4th parameter. But Andrey Vlasovskikh didn't like this idea.

I'm overall OK with this idea, but I would prefer to make the existing sys.excepthook API applicable to all the exceptions: for the main thread (works well), for _thread threads (works well) and for threading threads (doesn't work).

msg324422 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2018-08-31 14:22

My concern is more about backward compatibility. Documentation is one thing, but usually users rely on the actual implementation, not on the documentation, to define what is the Python behaviour.

Would you mind to open a thread on python-dev about this change?

I don't want to take the responsibility alone of such change :-) Moreover, I don't really have the bandwidth to work on this specific issue :-(

msg324436 - (view)

Author: Christoph Reiter (lazka) *

Date: 2018-08-31 17:01

To add one more use case for this:

concurrent.futures.Future.add_done_callback() currently ignores exceptions for the callback and just logs them which is easy to miss. I assume because it's not clear when and in which thread it gets called, and there is no "right" way to handle it.

It would be nice if it would call something like sys.excepthook instead.

msg343252 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-22 22:55

See also bpo-36829: I just added sys.unraisablehook().

msg343258 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-23 00:28

I wrote PR 13515 which adds threading.excepthook(). I chose to call threading.excepthook() even when run() raises SystemExit. In this case, threading.excepthook() simply does nothing. The idea is to really give the full control when threading.excepthook() is overriden. For example, log a warning when run() raises SystemExit. By the way, is it really a good idea to call sys.exit() from a thread? It sounds like a bug that should be reported, and not silently ignored, no?

Differences between sys.excepthook() and threading.excepthook():

Thread._stderr was added by bpo-754449:

commit cc4e935ea593cede10cb1316e3faeabd708abca7 Author: Brett Cannon <bcannon@gmail.com> Date: Sat Jul 3 03:52:35 2004 +0000

threading.Thread objects will now print a traceback for an exception raised
during interpreter shutdown instead of masking it with another traceback about
accessing a NoneType when trying to print the exception out in the first place.

Closes bug [#754449](issue754449 "[closed] Exceptions when a thread exits") (using patch [#954922](issue954922 "[closed] Fix for 754449: hiding exc in threading during interp shutdn")).

Note: When sys.stderr is None, threading.excepthook() avoids the traceback module and renders the exception itself. Maybe threading.excepthook() should be reimplemented in C to make it even more reliable and more correct, especially during Python shutdown. Only daemon threads are impacted: Python finalization (Py_Finalize() C function) starts by calling threading._shutdown() which joins all non-daemon threads.

IMHO the threading.Thread semantics is too different than sys.excepthook() to reuse sys.excepthook() to handle threading.Thread.run() exception.

Another explanation is that sadly sys.excepthook() API uses exactly 3 positional-only arguments, and so the API cannot be easily extended to get a thread argument. When I designed sys.unraisablehook(), I chose to pass only one argument which has attributes, to prevent this issue.

I'm not comfortable to attempt to modify sys.excepthook() to make it behave differently if it's called from the main thread or from a different thread. It would have to call threading.current_thread().name to get the name of the current thread.

Let's say that in Python 3.8 threading.Thread now calls sys.execpthook() to handle uncaught run() exception. All applications which override sys.excepthook() on purpose will behave differently: start to log exceptions from threads. But existing code is unlikely to be prepared to implement black magic to check if we are a "thread" or the main thread, to decide if we should display a thread name, and also the "black magic" to get the current thread name.

One of my concern of reusing sys.excepthook to display threading exceptions is that adding more code to handle threads is a risk of raising a new exception while logging a threading exception :-(

IMHO threading.excepthook() is safer since it already has access to the thread.

msg343260 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-23 00:43

I dislike PR 8610: threading.Thread doesn't call sys.excepthook to handle run() exception by default, it only calls sys.excepthook if it's overridden. Moreover, when sys.excepthook is called, the hook doesn't get access to the thread object :-(

msg343261 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-23 00:45

About threading.excepthook() API, maybe we should not reproduce sys.excepthook() API but instead reuse something closer to sys.unraisablehook() API: use a single parameter which has attributes. It would allow to pass more parameters as new attributes in the future, maybe some new "optional" parameters (None by default).

For example, we can imagine calling threading.excepthook() to handle threading.excepthook() failure. We would need an argument to prevent an infine loop :-)

msg343276 - (view)

Author: Christoph Reiter (lazka) *

Date: 2019-05-23 05:44

Let's say that in Python 3.8 threading.Thread now calls sys.execpthook() to handle uncaught run() exception. All applications which override sys.excepthook() on purpose will behave differently: start to log exceptions from threads. But existing code is unlikely to be prepared to implement black magic to check if we are a "thread" or the main thread, to decide if we should display a thread name, and also the "black magic" to get the current thread name.

Note that PyErr_Print() and PyErr_PrintEx() can be called in threads, and CPython itself uses it in some places which can be called in threads and I also use it in thread callbacks in C extensions I work on (PyGObject and pycairo for example). Nothing states currently that it's not allowed to call it in such cases :(

msg343280 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2019-05-23 07:45

Moreover, when sys.excepthook is called, the hook doesn't get access to the thread object

You can get it with threading.current_thread(), no?

msg343293 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-23 12:46

There is a special case. If a thread calls os.fork() and Thread.run() raises an exception, the thread name is still logged even if there is only 1 thread after fork. Try attached fork_thread.py.

Output on Python 3.7:

main thread: spawn fork thread thread: before fork [<_MainThread(MainThread, started 140623217481536)>, <ForkThread(Thread-1, started 140622996952832)>] thread: after fork [<ForkThread(Thread-1, started 140622996952832)>] thread: after fork: raise Exception in thread Thread-1: Traceback (most recent call last): File "/usr/lib64/python3.7/threading.py", line 917, in _bootstrap_inner self.run() File "fork_thread.py", line 17, in run raise Exception("what happens here?") Exception: what happens here?

main thread: done

Moreover, threading.Thread silently ignores SystemExit in run() even if it's the only remaining thread (main thread is gone after fork).

I don't think that we have to change the current behavior. It's just that we have to take it in account if we modify how exceptions are handled.

msg343443 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-25 00:28

I rewrote my PR 13515:

--

First I also added a "stderr" argument to the arguments passed to threading.excepthook(): sys.stderr, or an old copy of sys.stderr if sys.stderr no longer exists or is set to None. But I decided to keep this as an implementation detail instead.

msg343444 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-25 00:30

If you want to reuse sys.excepthook to handle uncaught Thread.run() exception, you can now write:

def hook(args): if args.exc_type == SystemExit: return sys.excepthook(args.exc_type, args.exc_value, args.exc_traceback)

threading.excepthook = hook

Try attached sys_threading_excepthook.py for a full example.

msg343474 - (view)

Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer)

Date: 2019-05-25 12:25

I propose to add the Thead.excepthook() method with the signature compatible with sys.excepthook(). This will allow to set easily per-thread hooks and a global hook.

msg343494 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2019-05-25 17:22

A Thread.excepthook() method does not allow to notify exceptions raised in C-created threads ("dummy threads").

Also, as I said already, you can get the current thread by calling threading.current_thread() in the except hook. There is no need to pass it explicitly to the except hook.

msg343510 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-25 20:53

A Thread.excepthook() method does not allow to notify exceptions raised in C-created threads ("dummy threads").

The main difference between sys.excepthook and threading.excepthook is that the threading hook displays the thread name. Which output do you expect if you don't pass a threading.Thread object (which has a 'name' attribute)? The thread identifier from _thread.get_ident()?

I can easily modify the default hook implementation to support args.thread=None and displays _thread.get_ident() as the name instead.

Also, as I said already, you can get the current thread by calling threading.current_thread() in the except hook. There is no need to pass it explicitly to the except hook.

I understand that your plan is to use sys.excepthook to handle threading.Thread uncaught exception.

My main concern is that sys.excepthook can fail on importing the threading module. One solution would be to import threading when the sys module is created and keep a strong reference to threading.current_thread(). But I dislike this idea.

I already raised my concern, but so far, you didn't explain how you plan to fix this practical issue.

Moreover, the current threading code is quite complex. My guess is that this complexity is needed to display exception very late during Python shutdown, when module attributes are set to None and import no longer works.

I would prefer to not move this complexity into sys.excepthook which has currently a simple implementation.

--

Daemon threads are evil. We should drop this nasty feature... but I would prefer to not block this issue by the removal of daemon threads, since I'm sure that a lot of code rely on them and so it will be really hard to really remove them.

msg343512 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-25 21:09

Serhiy Storchaka:

I propose to add the Thead.excepthook() method with the signature compatible with sys.excepthook(). This will allow to set easily per-thread hooks and a global hook.

I don't see the relationship between the API (signature) and the ability to set a per-thread hook.

I'm not convinced that a per-thread hook is needed. My proposed global threading.excepthook gets a thread parameter which allows a custom hook to implement a different behavior depending on the thread. You can use a different behavior depending on the thread name, depending on a custom Thread attribute, etc.

Would it be acceptable for first add a global hook and see later if a per-thread hook is needed?

msg343515 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2019-05-25 21:11

Sorry, I had overlooked the issue with global variables at shutdown. Though that issue only occurs with daemonic threads, since non-daemonic threads are joined before global variables are cleared.

In any case, I think the namedtuple / structseq solution is elegant, because we can add additional information later (the user must only be careful not to use tuple unpacking).

msg343516 - (view)

Author: Antoine Pitrou (pitrou) * (Python committer)

Date: 2019-05-25 21:19

Le 25/05/2019 à 23:09, STINNER Victor a écrit :

I don't see the relationship between the API (signature) and the ability to set a per-thread hook.

I'm not convinced that a per-thread hook is needed.

Indeed, if you write your own Thread class, you can add a try...except in the Thread.run() method. You don't need a dedicated Thread.excepthook() method.

The only way a per-thread hook could be useful is if you could set it outside of the Thread class (so not as a method), so that one can e.g. catch / report exceptions raised in threads launches by third-party libraries.

msg343522 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-25 23:15

Indeed, if you write your own Thread class, you can add a try...except in the Thread.run() method. You don't need a dedicated Thread.excepthook() method.

Exactly. You can already do you best in your run() method to handle exceptions.

threading.excepthook is only there is everything else already failed.

FYI in my implementation, if threading.excepthook raises a new exception, it's also handled... by sys.excepthook this time ;-)

The only way a per-thread hook could be useful is if you could set it outside of the Thread class (so not as a method), so that one can e.g. catch / report exceptions raised in threads launches by third-party libraries.

I discuss threading excepthook with Pablo and he asked me if it would be possible to have a different behavior depending if the thread is spawn by my application or by "third party code". Using threading.excepthook, you can mark your threads that you spawn directly using a specific name, a special attribute, or you may even track them in a list (maybe using weak references).

If sys.excepthook is used to handle threading exceptions, you call threading.current_thread(), but then we come back to the issue to "dying" Python: exception which occurs late in Python finalization, when most modules are already cleared and import no longer works.

msg343523 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-25 23:40

Antoine Pitrou:

A Thread.excepthook() method does not allow to notify exceptions raised in C-created threads ("dummy threads").

I modified my PR to use the threading identitifer (threading.get_ident()) as the thread name if args.thread is None.

msg343524 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-25 23:44

In any case, I think the namedtuple / structseq solution is elegant, because we can add additional information later

I used the same design for the new sys.unraisablehook in bpo-36829 and I'm already working on adding a new 'err_msg' field to the argument passed to this took: PR 13488 :-)

I was trapped in the past when I had to modify warnings "hooks" (warnings.showwarning and warnings.formatwarning) when I had to add a new 'source' parameter. I had to write wrappers which are fragile, to keep the backward compatibility.

(the user must only be careful not to use tuple unpacking)

threading.excepthook doesn't mention the compatibility with tuple on purpose. It only documents attributes with their names.

msg343692 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-27 22:39

New changeset cd590a7cede156a4244e7cac61e4504e5344d842 by Victor Stinner in branch 'master': bpo-1230540: Add threading.excepthook() (GH-13515) https://github.com/python/cpython/commit/cd590a7cede156a4244e7cac61e4504e5344d842

msg343694 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-27 22:53

It took 14 years, but this issue is now fixed ;-) I close it.

Python 3.8 beta 1 will be released in a few days with threading.excepthook(): please test it to ensure that it works as you expected.

As a follow-up, I created bpo-37069: "regrtest: log unraisable exceptions and uncaught thread exceptions".

msg343748 - (view)

Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer)

Date: 2019-05-28 08:25

If we want to support low-level threads created by start_new_thread() we should call excepthook() from t_bootstrap instead of Thread._bootstrap_inner. Otherwise implementing excepthook() as a Thread method would be more convenient.

msg343758 - (view)

Author: STINNER Victor (vstinner) * (Python committer)

Date: 2019-05-28 10:20

If we want to support low-level threads created by start_new_thread() we should call excepthook() from t_bootstrap instead of Thread._bootstrap_inner. Otherwise implementing excepthook() as a Thread method would be more convenient.

I created bpo-37076: "_thread.start_new_thread(): call sys.unraisablehook() to handle uncaught exceptions".

History

Date

User

Action

Args

2022-04-11 14:56:12

admin

set

github: 42148

2020-09-22 14:48:19

vstinner

link

issue36666 superseder

2019-05-28 10:20:57

vstinner

set

messages: +

2019-05-28 09:11:37

vstinner

set

title: sys.excepthook doesn't work in threads -> Add threading.excepthook() to handle uncaught exceptions raised by Thread.run()

2019-05-28 08:25:52

serhiy.storchaka

set

messages: +

2019-05-27 22:53:59

vstinner

set

status: open -> closed
resolution: fixed
messages: +

stage: patch review -> resolved

2019-05-27 22:39:54

vstinner

set

messages: +

2019-05-25 23:44:42

vstinner

set

messages: +

2019-05-25 23:40:02

vstinner

set

messages: +

2019-05-25 23:15:19

vstinner

set

messages: +

2019-05-25 21:19:46

pitrou

set

messages: +

2019-05-25 21:11:53

pitrou

set

messages: +

2019-05-25 21:09:43

vstinner

set

messages: +

2019-05-25 20:53:33

vstinner

set

messages: +

2019-05-25 17:22:48

pitrou

set

messages: +

2019-05-25 12:25:21

serhiy.storchaka

set

nosy: + serhiy.storchaka
messages: +

2019-05-25 00:30:51

vstinner

set

files: + sys_threading_excepthook.py

messages: +

2019-05-25 00:28:19

vstinner

set

messages: +

2019-05-23 12:46:26

vstinner

set

files: + fork_thread.py

messages: +

2019-05-23 07:45:35

pitrou

set

messages: +

2019-05-23 05:44:13

lazka

set

messages: +

2019-05-23 00:45:56

vstinner

set

messages: +

2019-05-23 00:43:09

vstinner

set

messages: +

2019-05-23 00:28:16

vstinner

set

messages: +

2019-05-23 00:02:02

vstinner

set

pull_requests: + <pull%5Frequest13432>

2019-05-22 22:55:57

vstinner

set

messages: +

2018-08-31 17:01:00

lazka

set

nosy: + lazka
messages: +

2018-08-31 14:22:46

vstinner

set

messages: +

2018-08-04 15:46:54

vlasovskikh

set

messages: +

2018-08-02 09:46:59

nikratio

set

nosy: - nikratio

2018-08-02 09:21:28

vstinner

set

messages: +

2018-08-01 22:12:50

pitrou

set

messages: +
versions: + Python 3.8, - Python 2.7, Python 3.5, Python 3.6, Python 3.7

2018-08-01 22:08:24

vlasovskikh

set

nosy: + vlasovskikh, vstinner
messages: +

2018-08-01 21:56:50

vlasovskikh

set

keywords: + patch
stage: needs patch -> patch review
pull_requests: + <pull%5Frequest8116>

2018-04-09 03:58:07

ncoghlan

set

nosy: + ncoghlan

2017-09-20 17:58:31

pitrou

set

messages: +

2017-09-16 05:13:38

Matt Groth

set

nosy: + Matt Groth
messages: +

2017-06-28 20:17:02

pitrou

set

versions: + Python 3.6, Python 3.7, - Python 3.2
nosy: + pitrou, tim.peters

messages: +

type: behavior
stage: test needed -> needs patch

2017-02-24 10:33:39

CyberJacob

set

messages: +

2017-02-24 09:45:23

CyberJacob

set

nosy: + CyberJacob
messages: +

2016-08-05 02:55:32

Decorater

set

messages: +

2016-08-05 02:04:58

Decorater

set

messages: +
versions: + Python 3.5

2016-08-05 01:55:13

Decorater

set

nosy: + Decorater
messages: +

2011-09-11 18:55:28

nikratio

set

nosy: + nikratio

2010-08-04 04:44:18

terry.reedy

set

stage: test needed
versions: + Python 2.7, Python 3.2, - Python 2.6, Python 2.5

2010-02-23 21:22:52

eric.araujo

set

nosy: + eric.araujo

2009-08-03 22:24:03

undercoveridiot

set

messages: +

2009-08-03 21:59:32

undercoveridiot

set

nosy: + undercoveridiot
messages: +

2008-02-24 20:40:08

tiagoaoa

set

nosy: + tiagoaoa
messages: +

2007-11-23 09:20:55

christian.heimes

set

versions: + Python 2.6, Python 2.5, - Python 2.4

2005-06-30 19:06:10

ellisj

create