Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use tblib to enable pickleable tracebacks #323

Merged
merged 3 commits into from
Sep 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 3 additions & 0 deletions _trio_parallel_workers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
from pickle import dumps, loads

from outcome import capture, Error
from tblib.pickling_support import install

install()

MAX_TIMEOUT = 24.0 * 60.0 * 60.0
ACK = b"\x06"
Expand Down
7 changes: 7 additions & 0 deletions _trio_parallel_workers/_funcs.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,10 @@ def _monkeypatch_max_timeout():

def _no_trio():
return "trio" not in sys.modules


def _chained_exc():
try:
raise ValueError('test1')
except BaseException as e:
raise TypeError('test2') from e
2 changes: 2 additions & 0 deletions newsfragments/323.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Use ``tblib`` to enable pickling of tracebacks between processes. Mainly, this
preserves context of exceptions including chained exceptions.
4 changes: 2 additions & 2 deletions requirements/build.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ packaging==21.3
# via
# build
# setuptools-scm
pep517==0.12.0
pep517==0.13.0
# via build
pyparsing==3.0.9
# via packaging
Expand All @@ -30,7 +30,7 @@ wheel==0.37.1
# via -r requirements\build.in

# The following packages are considered to be unsafe in a requirements file:
setuptools==63.1.0
setuptools==65.3.0
# via
# -r requirements\build.in
# setuptools-scm
2 changes: 1 addition & 1 deletion requirements/coverage.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#
# pip-compile-multi
#
coverage[toml]==6.4.1
coverage[toml]==6.4.4
# via -r requirements\coverage.in
tomli==2.0.1
# via coverage
16 changes: 8 additions & 8 deletions requirements/docs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ alabaster==0.7.12
# via sphinx
babel==2.10.3
# via sphinx
certifi==2022.6.15
certifi==2022.9.14
# via requests
cffi==1.15.1 ; os_name == "nt" and implementation_name != "pypy"
# via
# -r requirements\install.in
# trio
charset-normalizer==2.1.0
charset-normalizer==2.1.1
# via requests
click==8.1.3
# via
Expand Down Expand Up @@ -44,17 +44,17 @@ markupsafe==2.1.1
# via jinja2
packaging==21.3
# via sphinx
pygments==2.12.0
pygments==2.13.0
# via sphinx
pyparsing==3.0.9
# via packaging
pytz==2022.1
pytz==2022.2.1
# via babel
requests==2.28.1
# via sphinx
snowballstemmer==2.2.0
# via sphinx
sphinx==5.0.2
sphinx==5.1.1
# via
# -r requirements\docs.in
# sphinx-rtd-theme
Expand All @@ -77,11 +77,11 @@ sphinxcontrib-trio==1.1.2
# via -r requirements\docs.in
tomli==2.0.1
# via towncrier
towncrier==21.9.0
towncrier==22.8.0
# via -r requirements\docs.in
urllib3==1.26.10
urllib3==1.26.12
# via requests

# The following packages are considered to be unsafe in a requirements file:
setuptools==63.1.0
setuptools==65.3.0
# via towncrier
3 changes: 2 additions & 1 deletion requirements/install.in
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
trio >= 0.18.0
outcome
attrs >= 17.3.0
cffi; os_name == 'nt' and implementation_name != 'pypy'
cffi; os_name == 'nt' and implementation_name != 'pypy'
tblib
10 changes: 6 additions & 4 deletions requirements/install.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# SHA1:bb6e9a7b5d2a35f9ddeec40f11d7bc137ea27c3e
# SHA1:63e73656a123a857e40bd1da6cce5906958410ed
#
# This file is autogenerated by pip-compile-multi
# To update, run:
Expand All @@ -7,7 +7,7 @@
#
async-generator==1.10
# via trio
attrs==21.4.0
attrs==22.1.0
# via
# -r requirements\install.in
# outcome
Expand All @@ -16,17 +16,19 @@ cffi==1.15.1 ; os_name == "nt" and implementation_name != "pypy"
# via
# -r requirements\install.in
# trio
idna==3.3
idna==3.4
# via trio
outcome==1.2.0
# via
# -r requirements\install.in
# trio
pycparser==2.21
# via cffi
sniffio==1.2.0
sniffio==1.3.0
# via trio
sortedcontainers==2.4.0
# via trio
tblib==1.7.0
# via -r requirements\install.in
trio==0.21.0
# via -r requirements\install.in
12 changes: 6 additions & 6 deletions requirements/lint.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,25 @@
#
# pip-compile-multi
#
black==22.6.0
black==22.8.0
# via -r requirements\lint.in
click==8.1.3
# via black
colorama==0.4.5
# via click
flake8==4.0.1
flake8==5.0.4
# via -r requirements\lint.in
mccabe==0.6.1
mccabe==0.7.0
# via flake8
mypy-extensions==0.4.3
# via black
pathspec==0.9.0
pathspec==0.10.1
# via black
platformdirs==2.5.2
# via black
pycodestyle==2.8.0
pycodestyle==2.9.1
# via flake8
pyflakes==2.4.0
pyflakes==2.5.0
# via flake8
tomli==2.0.1
# via black
6 changes: 2 additions & 4 deletions requirements/test.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,13 @@
# pip-compile-multi
#
-r install.txt
atomicwrites==1.4.1
# via pytest
cffi==1.15.1 ; os_name == "nt" and implementation_name != "pypy"
# via
# -r requirements\install.in
# trio
colorama==0.4.5
# via pytest
coverage[toml]==6.4.1
coverage[toml]==6.4.4
# via
# -r requirements\test.in
# pytest-cov
Expand All @@ -28,7 +26,7 @@ py==1.11.0
# via pytest
pyparsing==3.0.9
# via packaging
pytest==7.1.2
pytest==7.1.3
# via
# -r requirements\test.in
# pytest-cov
Expand Down
1 change: 1 addition & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ install_requires =
outcome
attrs >= 17.3.0
cffi; os_name == 'nt' and implementation_name != 'pypy'
tblib
python_requires = >=3.7

[options.extras_require]
Expand Down
17 changes: 16 additions & 1 deletion trio_parallel/_tests/test_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@
All workers should pass these tests, regardless of implementation
"""
import math
import traceback

import pytest
import trio

from _trio_parallel_workers._funcs import _null_async_fn
from _trio_parallel_workers._funcs import _null_async_fn, _chained_exc
from .._impl import WORKER_MAP


Expand Down Expand Up @@ -68,3 +69,17 @@ async def test_clean_exit_on_shutdown(worker, capfd):
out, err = capfd.readouterr()
assert not out
assert not err


async def test_tracebacks(worker):
await worker.start()
try:
(await worker.run_sync(_chained_exc)).unwrap()
except TypeError as e:
assert str(e) == "test2"
text = "".join(traceback.format_exception(type(e), e, e.__traceback__))
else: # pragma: no cover
assert False, "an error should be raised"

assert "raise ValueError(" in text
assert "raise TypeError(" in text