Why did someone write this?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Sandra-24

    #1

    Why did someone write this?

    try:
    exc_type, exc_value, exc_traceback = sys.exc_info()
    # Do something
    finally:
    exc_traceback = None

    Why the try/finally with setting exc_traceback to None? The python docs
    didn't give me any clue, and I'm wondering what this person knows that
    I don't.

    Thanks,
    -Sandra

  • skip@pobox.com

    #2
    Re: Why did someone write this?


    Sandra> try:
    Sandra> exc_type, exc_value, exc_traceback = sys.exc_info()
    Sandra> # Do something
    Sandra> finally:
    Sandra> exc_traceback = None

    Sandra> Why the try/finally with setting exc_traceback to None?

    The intent is to decrement the reference count to any objects referenced by
    exc_traceback. Without it, the frame(s) referenced by the traceback remain
    alive until exc_traceback goes out of scope.

    Skip

    Comment

    • Benjamin Niemann

      #3
      Re: Why did someone write this?

      Sandra-24 wrote:
      [color=blue]
      > try:
      > exc_type, exc_value, exc_traceback = sys.exc_info()
      > # Do something
      > finally:
      > exc_traceback = None
      >
      > Why the try/finally with setting exc_traceback to None? The python docs
      > didn't give me any clue, and I'm wondering what this person knows that
      > I don't.[/color]

      You just have not found the right part of the doc:
      This module provides access to some variables used or maintained by the interpreter and to functions that interact strongly with the interpreter. It is always available. Unless explicitly noted oth...


      --
      Benjamin Niemann
      Email: pink at odahoda dot de
      WWW: http://pink.odahoda.de/

      Comment

      • Sandra-24

        #4
        Re: Why did someone write this?

        I can't believe I missed it in the documentation. Maybe it wasn't in
        the offline version I was using, but more likely it was just one of
        those things.

        So the trouble seems to be that the traceback holds a reference to the
        frame where the exception occurred, and as a result a local variable
        that references the traceback in that frame now holds a reference to
        it's own frame (preventing the frame from being recliamed) and can't be
        cleaned up prior to python 2.2 with GC enabled.

        Which means it's fine to hold a reference to the traceback in a frame
        not in the traceback, or (I think) to create a temporary unamed
        reference to it.

        Thanks for your help guys!
        -Sandra

        Comment

        • Donn Cave

          #5
          Re: Why did someone write this?

          In article <1144446670.262 116.315360@j33g 2000cwa.googleg roups.com>,
          "Sandra-24" <sandravandale@ yahoo.com> wrote:
          [color=blue]
          > I can't believe I missed it in the documentation. Maybe it wasn't in
          > the offline version I was using, but more likely it was just one of
          > those things.
          >
          > So the trouble seems to be that the traceback holds a reference to the
          > frame where the exception occurred, and as a result a local variable
          > that references the traceback in that frame now holds a reference to
          > it's own frame (preventing the frame from being recliamed) and can't be
          > cleaned up prior to python 2.2 with GC enabled.
          >
          > Which means it's fine to hold a reference to the traceback in a frame
          > not in the traceback, or (I think) to create a temporary unamed
          > reference to it.[/color]

          I don't think that's exactly it - the problem wasn't exactly
          circularity, and GC wouldn't help. But as I try to write a
          test program that demonstrates, it looks like current versions
          of Python have done something with sys.exc_traceba ck that
          avoids at least some of the problems.

          import sys
          class A:
          def __del__(self):
          print 'A.__del__'

          def f():
          a = A()
          try:
          xyz
          except:
          print 'caught expected error'
          print 'returning from f'
          return sys.exc_traceba ck

          t = f()
          print 'Done'


          In order to get the traceback to preserve "a" past its
          natural lifetime, I had to return it to the caller, because
          today sys.exc_traceba ck disappears when f() returns. But
          it shows the effect on order of execution: 'A.__del__'
          will appear after 'Done', when it should appear before it.

          When I did this (sys.exc_traceb ack = None), the applications
          used a terminal graphics library, like curses, and I often
          depended on finalization (__del__) to run the "close" rendering
          for a graphic element. Worked fine until an exception, so I
          add this precaution to every I/O flush.

          Donn Cave, donn@u.washingt on.edu

          Comment

          Working...