ForkAnthropicAnthropicpublished Oct 5, 2023seen 6d

anthropics/python-tblib

forked from ionelmc/python-tblib

Open original ↗

Captured source

source ↗
published Oct 5, 2023seen 6dcaptured 9hhttp 200method plain

anthropics/python-tblib

Description: Serialization library for Exceptions and Tracebacks.

Language: Python

License: BSD-2-Clause

Stars: 12

Forks: 4

Open issues: 0

Created: 2023-10-05T21:16:30Z

Pushed: 2023-10-06T19:31:24Z

Default branch: master

Fork: yes

Parent repository: ionelmc/python-tblib

Archived: no

README: ======== Overview ========

.. start-badges

.. list-table:: :stub-columns: 1

  • - docs
  • |docs|
  • - tests
  • | |github-actions| |requires|

| |codecov|

  • - package
  • | |version| |wheel| |supported-versions| |supported-implementations|

| |commits-since| .. |docs| image:: https://readthedocs.org/projects/python-tblib/badge/?style=flat :target: https://python-tblib.readthedocs.io/ :alt: Documentation Status

.. |github-actions| image:: https://github.com/ionelmc/python-tblib/actions/workflows/github-actions.yml/badge.svg :alt: GitHub Actions Build Status :target: https://github.com/ionelmc/python-tblib/actions

.. |codecov| image:: https://codecov.io/gh/ionelmc/python-tblib/branch/master/graphs/badge.svg?branch=master :alt: Coverage Status :target: https://app.codecov.io/github/ionelmc/python-tblib

:alt: PyPI Package latest release :target: https://pypi.org/project/tblib

:alt: PyPI Wheel :target: https://pypi.org/project/tblib

:alt: Supported versions :target: https://pypi.org/project/tblib

:alt: Supported implementations :target: https://pypi.org/project/tblib

:alt: Commits since latest release :target: https://github.com/ionelmc/python-tblib/compare/v2.0.0...master

.. end-badges

Serialization library for Exceptions and Tracebacks.

  • Free software: BSD license

It allows you to:

  • Pickle _ tracebacks and raise exceptions

with pickled tracebacks in different processes. This allows better error handling when running code over multiple processes (imagine multiprocessing, billiard, futures, celery etc).

  • Create traceback objects from strings (the `from_string` method). *No pickling is used*.
  • Serialize tracebacks to/from plain dicts (the `from_dict and to_dict` methods). *No pickling is used*.
  • Raise the tracebacks created from the aforementioned sources.
  • Pickle an Exception together with its traceback and exception chain

(`raise ... from ...`) *(Python 3 only)*

Again, note that using the pickle support is completely optional. You are solely responsible for security problems should you decide to use the pickle support.

Installation ============

::

pip install tblib

Documentation =============

.. contents:: :local:

Pickling tracebacks ~~~~~~~~~~~~~~~~~~~

Note: The traceback objects that come out are stripped of some attributes (like variables). But you'll be able to raise exceptions with those tracebacks or print them - that should cover 99% of the usecases.

::

>>> from tblib import pickling_support >>> pickling_support.install() >>> import pickle, sys >>> def inner_0(): ... raise Exception('fail') ... >>> def inner_1(): ... inner_0() ... >>> def inner_2(): ... inner_1() ... >>> try: ... inner_2() ... except: ... s1 = pickle.dumps(sys.exc_info()) ... >>> len(s1) > 1 True >>> try: ... inner_2() ... except: ... s2 = pickle.dumps(sys.exc_info(), protocol=pickle.HIGHEST_PROTOCOL) ... >>> len(s2) > 1 True

>>> try: ... import cPickle ... except ImportError: ... import pickle as cPickle >>> try: ... inner_2() ... except: ... s3 = cPickle.dumps(sys.exc_info(), protocol=pickle.HIGHEST_PROTOCOL) ... >>> len(s3) > 1 True

Unpickling tracebacks ~~~~~~~~~~~~~~~~~~~~~

::

>>> pickle.loads(s1) (, Exception('fail'...), )

>>> pickle.loads(s2) (, Exception('fail'...), )

>>> pickle.loads(s3) (, Exception('fail'...), )

Raising ~~~~~~~

::

>>> from six import reraise >>> reraise(*pickle.loads(s1)) Traceback (most recent call last): ... File "", line 1, in reraise(*pickle.loads(s2)) File "", line 2, in inner_2() File "", line 2, in inner_2 inner_1() File "", line 2, in inner_1 inner_0() File "", line 2, in inner_0 raise Exception('fail') Exception: fail >>> reraise(*pickle.loads(s2)) Traceback (most recent call last): ... File "", line 1, in reraise(*pickle.loads(s2)) File "", line 2, in inner_2() File "", line 2, in inner_2 inner_1() File "", line 2, in inner_1 inner_0() File "", line 2, in inner_0 raise Exception('fail') Exception: fail >>> reraise(*pickle.loads(s3)) Traceback (most recent call last): ... File "", line 1, in reraise(*pickle.loads(s2)) File "", line 2, in inner_2() File "", line 2, in inner_2 inner_1() File "", line 2, in inner_1 inner_0() File "", line 2, in inner_0 raise Exception('fail') Exception: fail

Pickling Exceptions together with their traceback and chain (Python 3 only) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

>>> try: # doctest: +SKIP ... try: ... 1 / 0 ... except Exception as e: ... raise Exception("foo") from e ... except Exception as e: ... s = pickle.dumps(e) >>> raise pickle.loads(s) # doctest: +SKIP Traceback (most recent call last): File "", line 3, in 1 / 0 ZeroDivisionError: division by zero

The above exception was the direct cause of the following exception:

Traceback (most recent call last): File "", line 1, in raise pickle.loads(s) File "", line 5, in raise Exception("foo") from e Exception: foo

BaseException subclasses defined after calling `pickling_support.install()` will not retain their traceback and exception chain pickling. To cover custom Exceptions, there are three options:

1. Use `@pickling_support.install` as a decorator for each custom Exception

.. code-block:: python

>>> from tblib import pickling_support >>> # Declare all imports of your package's dependencies >>> import numpy # doctest: +SKIP

>>> pickling_support.install() # install for all modules imported so far

>>> @pickling_support.install ... class CustomError(Exception): ... pass

Eventual subclasses of `CustomError` will need to be decorated again.

2. Invoke `pickling_support.install()` after all modules have been imported and all Exception subclasses have been declared

.. code-block:: python

>>> # Declare all imports of your package's dependencies >>> import numpy # doctest: +SKIP >>> from tblib import pickling_support

>>> # Declare your own custom Exceptions >>> class CustomError(Exception): ... pass

>>> # Finally, install tblib >>> pickling_support.install()

3. Selectively install tblib for Exception instances just before they are pickled

.. code-block:: python

pickling_support.install(, [Exception instance], ...)

The above will install tblib…

Excerpt shown — open the source for the full document.