Storing tracebacks

Discussion in 'Python' started by George Sakkis, May 29, 2007.

  1. I'm reading the docs on sys.exc_info() but I can't tell for sure
    whether I'm using it safely to get a snapshot of an exception and
    reraise it later. The use case is a class which acts like a deferred
    callable, a callable that will be called at some point in the future
    (possibly in a different thread) and whose result or raised exception
    is to be stored as an attribute. This will be available by calling the
    result() method, which returns the original result or reraises the
    exception:

    class JobRequest(object):

    def __init__(self, *args, **kwds):
    self.args = args
    self.kwds = kwds
    self._exc_info = None

    def __call__(self):
    raise NotImplementedError('Abstract method')

    def process(self):
    try:
    self._result = self(*self.args, **self.kwds)
    except:
    self._exc_info = sys.exc_info()
    else:
    self._exc_info = None

    def result(self):
    if self._exc_info is not None:
    type,exception,traceback = self._exc_info
    raise type,exception,traceback
    try: return self._result
    except AttributeError:
    raise UnprocessedRequestError()

    class UnprocessedRequestError(RuntimeError):
    pass


    So far it seems it works as expected but I'd like to know if this is
    error-prone and why.

    George
     
    George Sakkis, May 29, 2007
    #1
    1. Advertising

  2. George Sakkis

    Guest

    On May 28, 10:46 pm, George Sakkis <> wrote:
    > I'm reading the docs on sys.exc_info() but I can't tell for sure
    > whether I'm using it safely to get a snapshot of an exception and
    > reraise it later. The use case is a class which acts like a deferred
    > callable, a callable that will be called at some point in the future
    > (possibly in a different thread) and whose result or raised exception
    > is to be stored as an attribute. This will be available by calling the
    > result() method, which returns the original result or reraises the
    > exception:
    >
    > class JobRequest(object):
    >
    > def __init__(self, *args, **kwds):
    > self.args = args
    > self.kwds = kwds
    > self._exc_info = None
    >
    > def __call__(self):
    > raise NotImplementedError('Abstract method')
    >
    > def process(self):
    > try:
    > self._result = self(*self.args, **self.kwds)
    > except:
    > self._exc_info = sys.exc_info()
    > else:
    > self._exc_info = None
    >
    > def result(self):
    > if self._exc_info is not None:
    > type,exception,traceback = self._exc_info
    > raise type,exception,traceback
    > try: return self._result
    > except AttributeError:
    > raise UnprocessedRequestError()
    >
    > class UnprocessedRequestError(RuntimeError):
    > pass
    >
    > So far it seems it works as expected but I'd like to know if this is
    > error-prone and why.
    >
    > George


    I don't know enough about this method of getting tracebacks, but why
    wouldn't the traceback module work for you? It sounds like it uses the
    sys.exc_info() method you refer to.

    http://python.active-venture.com/lib/module-traceback.html

    Mike
     
    , May 29, 2007
    #2
    1. Advertising

  3. On May 29, 9:46 am, wrote:
    > On May 28, 10:46 pm, George Sakkis <> wrote:
    >
    >
    >
    > > I'm reading the docs on sys.exc_info() but I can't tell for sure
    > > whether I'm using it safely to get a snapshot of an exception and
    > > reraise it later. The use case is a class which acts like a deferred
    > > callable, a callable that will be called at some point in the future
    > > (possibly in a different thread) and whose result or raised exception
    > > is to be stored as an attribute. This will be available by calling the
    > > result() method, which returns the original result or reraises the
    > > exception:

    >
    > > class JobRequest(object):

    >
    > > def __init__(self, *args, **kwds):
    > > self.args = args
    > > self.kwds = kwds
    > > self._exc_info = None

    >
    > > def __call__(self):
    > > raise NotImplementedError('Abstract method')

    >
    > > def process(self):
    > > try:
    > > self._result = self(*self.args, **self.kwds)
    > > except:
    > > self._exc_info = sys.exc_info()
    > > else:
    > > self._exc_info = None

    >
    > > def result(self):
    > > if self._exc_info is not None:
    > > type,exception,traceback = self._exc_info
    > > raise type,exception,traceback
    > > try: return self._result
    > > except AttributeError:
    > > raise UnprocessedRequestError()

    >
    > > class UnprocessedRequestError(RuntimeError):
    > > pass

    >
    > > So far it seems it works as expected but I'd like to know if this is
    > > error-prone and why.

    >
    > > George

    >
    > I don't know enough about this method of getting tracebacks, but why
    > wouldn't the traceback module work for you? It sounds like it uses the
    > sys.exc_info() method you refer to.
    >
    > http://python.active-venture.com/lib/module-traceback.html


    The traceback module is handy if you want a text representation of the
    traceback, not the actual traceback. The reason I want to store the
    actual traceback is to make the exception transparent to the user,
    i.e. not be able to tell whether the exception was thrown in the
    current stack frame or in another thread or even process.
    Unfortunately tracebacks are not pickleable, otherwise I could just
    pickle them in process() and unpickle them in result().

    George
     
    George Sakkis, May 29, 2007
    #3
  4. En Tue, 29 May 2007 13:51:09 -0300, George Sakkis
    <> escribió:

    > The traceback module is handy if you want a text representation of the
    > traceback, not the actual traceback. The reason I want to store the
    > actual traceback is to make the exception transparent to the user,
    > i.e. not be able to tell whether the exception was thrown in the
    > current stack frame or in another thread or even process.
    > Unfortunately tracebacks are not pickleable, otherwise I could just
    > pickle them in process() and unpickle them in result().


    A traceback contains a linked list of frames, each with its own globals
    and locals and lot of context info.
    I'm not sure that moving a traceback across processes has any sense; a
    textual representation should be enough, as t.b. are usually a debugging
    aid and not supposed to reach the final user.

    --
    Gabriel Genellina
     
    Gabriel Genellina, May 29, 2007
    #4
  5. On May 29, 1:21 pm, "Gabriel Genellina" <>
    wrote:
    > En Tue, 29 May 2007 13:51:09 -0300, George Sakkis
    > <> escribió:
    >
    > > The traceback module is handy if you want a text representation of the
    > > traceback, not the actual traceback. The reason I want to store the
    > > actual traceback is to make the exception transparent to the user,
    > > i.e. not be able to tell whether the exception was thrown in the
    > > current stack frame or in another thread or even process.
    > > Unfortunately tracebacks are not pickleable, otherwise I could just
    > > pickle them in process() and unpickle them in result().

    >
    > A traceback contains a linked list of frames, each with its own globals
    > and locals and lot of context info.
    > I'm not sure that moving a traceback across processes has any sense; a
    > textual representation should be enough, as t.b. are usually a debugging
    > aid and not supposed to reach the final user.


    The final user in this case is another programmer that uses a library,
    not some random guy using an application, so he certainly would be
    interested in seeing the traceback. I agree that the traceback is
    useful for debugging and the text representation would be enough if,
    for example, it was stored as an attribute in the Exception object and
    then used automatically by the runtime system (instead of calling
    sys.exc_info()). Of course nobody stops me from sticking
    traceback.format_tb() as an attribute in the Exception object and then
    have the client access it explicitly, something like:

    try: r = job.result()
    except Exception, ex:
    print ex.traceback

    The problem with this is that it's not transparent any more. The
    client must know that the originally raised object has been modified
    (or wrapped), sys.exc_info() doesn't work as expected, etc. It's not a
    show stopper by any means, but it would be convenient if there was a
    standardized optional "traceback" attribute that the runtime looks for
    and treats as the 3rd item of sys.exc_info() (otherwise it falls back
    to the current behavior). Would this be a reasonable feature request ?

    George
     
    George Sakkis, May 29, 2007
    #5
  6. En Tue, 29 May 2007 15:13:33 -0300, George Sakkis
    <> escribió:

    > On May 29, 1:21 pm, "Gabriel Genellina" <>
    > wrote:
    >> A traceback contains a linked list of frames, each with its own globals
    >> and locals and lot of context info.
    >> I'm not sure that moving a traceback across processes has any sense; a
    >> textual representation should be enough, as t.b. are usually a debugging
    >> aid and not supposed to reach the final user.

    >
    > The final user in this case is another programmer that uses a library,
    > not some random guy using an application, so he certainly would be
    > interested in seeing the traceback. I agree that the traceback is
    > useful for debugging and the text representation would be enough if,
    > for example, it was stored as an attribute in the Exception object and
    > then used automatically by the runtime system (instead of calling
    > sys.exc_info()). Of course nobody stops me from sticking
    > traceback.format_tb() as an attribute in the Exception object and then
    > have the client access it explicitly, something like:
    >
    > try: r = job.result()
    > except Exception, ex:
    > print ex.traceback
    >
    > The problem with this is that it's not transparent any more. The
    > client must know that the originally raised object has been modified
    > (or wrapped), sys.exc_info() doesn't work as expected, etc. It's not a
    > show stopper by any means, but it would be convenient if there was a
    > standardized optional "traceback" attribute that the runtime looks for
    > and treats as the 3rd item of sys.exc_info() (otherwise it falls back
    > to the current behavior). Would this be a reasonable feature request ?


    Already requested - see PEP 344 and 3110 for changes on exception handling
    and tracebacks (in Python 3.0 at least; I'm unsure of the PEP344 status on
    the 2.X series)

    --
    Gabriel Genellina
     
    Gabriel Genellina, May 29, 2007
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?ISO-8859-1?Q?Mike_M=FCller?=

    tracebacks in embedded python

    =?ISO-8859-1?Q?Mike_M=FCller?=, Jul 9, 2003, in forum: Python
    Replies:
    1
    Views:
    348
    Thomas Heller
    Jul 9, 2003
  2. Maxwell Hammer

    Help with thread related tracebacks

    Maxwell Hammer, Jun 16, 2005, in forum: Python
    Replies:
    0
    Views:
    320
    Maxwell Hammer
    Jun 16, 2005
  3. Maxwell Hammer
    Replies:
    7
    Views:
    669
    Peter Hansen
    Jun 18, 2005
  4. Michael P. Soulier

    getting tracebacks from traceback objects

    Michael P. Soulier, Jun 24, 2005, in forum: Python
    Replies:
    1
    Views:
    394
    Kent Johnson
    Jun 24, 2005
  5. Timothy Smith

    catching all tracebacks

    Timothy Smith, Oct 6, 2005, in forum: Python
    Replies:
    0
    Views:
    287
    Timothy Smith
    Oct 6, 2005
Loading...

Share This Page