Incompatibility with Python 3.10
We are trying to build and test trio with the latest Python 3.10a5 but there seems to be an incompatibility:
Error in sys.excepthook:
Traceback (most recent call last):
File "/builddir/build/BUILD/trio-0.16.0/trio/_core/_multierror.py", line 434, in trio_excepthook
for chunk in traceback.format_exception(etype, value, tb):
File "/usr/lib64/python3.10/traceback.py", line 129, in format_exception
te = TracebackException(type(value), value, tb, limit=limit, compact=True)
TypeError: traceback_exception_init() got an unexpected keyword argument 'compact'
In Python 3.10.0a5, TracebackException now has this keyword argument but traceback_exception_init from trio cannot process it.
From https://docs.python.org/3.10/whatsnew/changelog.html
bpo-42877: Added the compact parameter to the constructor of traceback.TracebackException to reduce time and memory for use cases that only need to call TracebackException.format() and TracebackException.format_exception_only().
https://bugs.python.org/issue42877
Simply passing through compact does not get rid of all the test failures. These appear quite often: AttributeError: 'TracebackException' object has no attribute '__cause__'.
I think the following fix might work. I believe the problem with the __cause__ attribute error is because None is treated as a special value for _seen. If we pass the empty set, __context__ and __cause__ are not properly set. I didn't test this much and also not with old versions of trio and Python.
diff --git a/trio/_core/_multierror.py b/trio/_core/_multierror.py
index 54295e71..93e2a7b8 100644
--- a/trio/_core/_multierror.py
+++ b/trio/_core/_multierror.py
@@ -384,9 +384,6 @@ def traceback_exception_init(
compact=False,
_seen=None,
):
- if _seen is None:
- _seen = set()
-
if sys.version_info >= (3, 10):
kwargs = {"compact": compact}
else:
@@ -409,16 +406,17 @@ def traceback_exception_init(
if isinstance(exc_value, MultiError):
embedded = []
for exc in exc_value.exceptions:
- if exc_key(exc) not in _seen:
+ if _seen is None or exc_key(exc) not in _seen:
+ # copy the set of _seen exceptions so that duplicates shared
+ # between sub-exceptions are not omitted
+ seen_copy = None if _seen is None else set(_seen)
embedded.append(
traceback.TracebackException.from_exception(
exc,
limit=limit,
lookup_lines=lookup_lines,
capture_locals=capture_locals,
- # copy the set of _seen exceptions so that duplicates
- # shared between sub-exceptions are not omitted
- _seen=set(_seen),
+ _seen=seen_copy,
)
)
self.embedded = embedded
@nascheme could you please open a PR with this change so we can get results from the CI?
I haven't compared in detail, but I think https://github.com/python-trio/trio/pull/1921 touches on this issue?
I think this has been fixed by the recent change to exceptiongroup, @agronholm can reopen if I'm wrong.