question about sys.exc_type and sys.exc_value

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • John Salerno

    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__.MyErr or 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.
  • John Salerno

    #2
    Re: question about sys.exc_type and sys.exc_value

    John Salerno wrote:
    [color=blue]
    > 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.)[/color]

    My mistake. In the book the exception is:

    MyError = 'hello'

    and the extra data is 'world'

    Comment

    • David Wahler

      #3
      Re: question about sys.exc_type and sys.exc_value

      John Salerno wrote:[color=blue]
      > 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__.MyErr or 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.[/color]

      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,v alue,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_traceba ck 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

      Comment

      • John Salerno

        #4
        Re: question about sys.exc_type and sys.exc_value

        David Wahler wrote:
        [color=blue]
        > 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).[/color]

        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. :)

        Comment

        Working...