Title: mishandling of AttributeError in threads
Type: Stage: resolved
Components: Interpreter Core Versions: Python 2.7
Status: closed Resolution: fixed
Dependencies: Superseder:
Assigned To: Nosy List: amaury.forgeotdarc, ossman, python-dev, scoder
Priority: normal Keywords:

Created on 2012-04-02 12:08 by ossman, last changed 2012-04-22 12:56 by scoder. This issue is now closed.

Messages (6)
msg157350 - (view) Author: Pierre Ossman (ossman) Date: 2012-04-02 12:08
These three things do not mix:

 - AttributeError
 - Threads
 - Object methods

An unhandled AttributeError thrown in a thread will not call sys.excepthook if the thread's start function is a class/object method.

Test case:

import sys
import thread

class Dummy:
	def worker(self):
		raise AttributeError

thread.start_new_thread(Dummy().worker, ())


Note that you do not get a traceback here. Throwing any other exception type works fine, as does having worker() be a simple function.

I think I've traced the issue to Objects/classobject.c:instance_repr(). It tries to look up the method, making sure to handle any AttributeError this might cause. But it fails to save and restore and Exception currently already active, effectively clearing out the current exception.
msg157357 - (view) Author: Amaury Forgeot d'Arc (amaury.forgeotdarc) * (Python committer) Date: 2012-04-02 14:36
If Dummy is a new-style class, the traceback is correctly printed.
msg157359 - (view) Author: Pierre Ossman (ossman) Date: 2012-04-02 14:58
Indeed. I assume old style classes are still supported though?
msg157363 - (view) Author: Roundup Robot (python-dev) Date: 2012-04-02 15:15
New changeset 8609d7fcdcc7 by Benjamin Peterson in branch '2.7':
prevent writing to stderr from messing up the exception state (closes #14474)
msg157366 - (view) Author: Roundup Robot (python-dev) Date: 2012-04-02 15:28
New changeset 60ad83716733 by Benjamin Peterson in branch '3.2':
prevent writing to stderr from messing up the exception state (closes #14474)
msg158960 - (view) Author: Stefan Behnel (scoder) * Date: 2012-04-22 12:56
Could the

    while thread._count() > c:

in be changed to this? (as used in other places)

    while thread._count() > c:

It currently hangs in Cython because it doesn't free the GIL during the plain C loop. (While that might be considered a bug in Cython, it's not what this test is supposed to test for.)
Date User Action Args
2012-04-22 12:56:49scodersetnosy: + scoder
messages: + msg158960
2012-04-02 15:28:55python-devsetmessages: + msg157366
2012-04-02 15:15:24python-devsetstatus: open -> closed

nosy: + python-dev
messages: + msg157363

resolution: fixed
stage: resolved
2012-04-02 14:58:51ossmansetmessages: + msg157359
2012-04-02 14:36:31amaury.forgeotdarcsetnosy: + amaury.forgeotdarc
messages: + msg157357
2012-04-02 12:08:19ossmancreate