question about sys.exc_type and sys.exc_value

J

John Salerno

Here is an exercise from Learning Python that I wrote myself:

import sys
import traceback

class MyError: pass

def oops():
raise MyError()

def safe(func, *args):
try:
apply(func, args)
except:
traceback.print_exc()
print 'Got', sys.exc_type, sys.exc_value

safe(oops)

And here is the output:

Traceback (most recent call last):
File "C:/Python24/oops.py", line 11, in safe
apply(func, args)
File "C:/Python24/oops.py", line 7, in oops
raise MyError()
MyError: <__main__.MyError instance at 0x00B475A8>
Got Queue.Empty

Why does it show Queue.Empty as the values for sys.exc_type and
sys.exc_value? I guess I can somewhat understand Empty, because the
instance is basically nothing. But why does it say Queue instead of
MyError? The sample in the book shows "Got hello world", because hello
is the error name and world is the extra data. But mine doesn't seem to
work that way. (They are also using a string exception in the book,
instead of a class.)

Thanks.
 
J

John Salerno

John said:
MyError? The sample in the book shows "Got hello world", because hello
is the error name and world is the extra data. But mine doesn't seem to
work that way. (They are also using a string exception in the book,
instead of a class.)

My mistake. In the book the exception is:

MyError = 'hello'

and the extra data is 'world'
 
D

David Wahler

John said:
Here is an exercise from Learning Python that I wrote myself:

import sys
import traceback

class MyError: pass

def oops():
raise MyError()

def safe(func, *args):
try:
apply(func, args)
except:
traceback.print_exc()
print 'Got', sys.exc_type, sys.exc_value

safe(oops)

And here is the output:

Traceback (most recent call last):
File "C:/Python24/oops.py", line 11, in safe
apply(func, args)
File "C:/Python24/oops.py", line 7, in oops
raise MyError()
MyError: <__main__.MyError instance at 0x00B475A8>
Got Queue.Empty

Why does it show Queue.Empty as the values for sys.exc_type and
sys.exc_value? I guess I can somewhat understand Empty, because the
instance is basically nothing. But why does it say Queue instead of
MyError? The sample in the book shows "Got hello world", because hello
is the error name and world is the extra data. But mine doesn't seem to
work that way. (They are also using a string exception in the book,
instead of a class.)

Thanks.

Are you using the first edition of "Learning Python"? According to
<http://www.oreilly.com/catalog/lpython/> that was published in 1999,
which puts it right around the end of Python 1.5. I'd strongly suggest
you find a much more recent tutorial, as a lot of python has been
improved and altered since then (sometimes in incompatible ways).

If you look at the sys module's documentation at
<http://docs.python.org/lib/module-sys.html>, you'll notice that
sys.exc_{type,value,traceback} have been deprecated since version 1.5.
That's because there's really no way to use them safely. The reason is
that as global variables, they hold information on the most recent
exception handled _anywhere_ in the program, possibly in another
thread. You should use sys.exc_info() instead, which only returns the
most recent one in the current thread.

If you do a little experimentation, you should notice that your
anomalous result only occurs when you run the code through IDLE -- it
works fine at the command prompt. Also, if you print exc_type and
exc_value first, at the beginning of the except block, it works fine.
The reason for this behavior is that IDLE runs your code in a separate
thread of the same interpreter instance used to run IDLE itself.
Presumably, some code in IDLE's user interface uses a queue to manage
the display, and that results in a Queue.Empty exception being thrown
and caught internally in another thread whenever a line of output is
printed.

The point is that sys.exc_type, sys.exc_value and sys.exc_traceback are
fundamentally unsafe, which is why they've been deprecated for the last
7 years. Incidentally, string exceptions are also deprecated IIRC, so
it's probably best to steer clear of them as well.

Hope this helps,
-- David
 
J

John Salerno

David said:
Are you using the first edition of "Learning Python"? According to
<http://www.oreilly.com/catalog/lpython/> that was published in 1999,
which puts it right around the end of Python 1.5. I'd strongly suggest
you find a much more recent tutorial, as a lot of python has been
improved and altered since then (sometimes in incompatible ways).

Actually I'm using the second edition, which is updated to 2.2/2.3. But
you are right, I just tried it in the command prompt and it does work,
so my mind can rest tonight. :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,526
Members
44,997
Latest member
mileyka

Latest Threads

Top