f



question about sys.exc_type and sys.exc_value

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.
0
johnjsal1 (999)
3/5/2006 1:18:27 AM
comp.lang.python 77058 articles. 4 followers. Post Follow

3 Replies
461 Views

Similar Articles

[PageSpeed] 20

John Salerno wrote:

> 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'
0
johnjsal1 (999)
3/5/2006 1:21:57 AM
John Salerno wrote:
> 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

0
dwahler (89)
3/5/2006 4:04:58 AM
David Wahler wrote:

> 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.  :)
0
johnjsal1 (999)
3/5/2006 5:45:06 AM
Reply: