trio icon indicating copy to clipboard operation
trio copied to clipboard

Incompatibility with Python 3.10

Open frenzymadness opened this issue 5 years ago • 4 comments

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

frenzymadness avatar Feb 11 '21 12:02 frenzymadness

Simply passing through compact does not get rid of all the test failures. These appear quite often: AttributeError: 'TracebackException' object has no attribute '__cause__'.

agronholm avatar Feb 25 '21 15:02 agronholm

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 avatar May 25 '21 22:05 nascheme

@nascheme could you please open a PR with this change so we can get results from the CI?

frenzymadness avatar May 27 '21 12:05 frenzymadness

I haven't compared in detail, but I think https://github.com/python-trio/trio/pull/1921 touches on this issue?

altendky avatar May 27 '21 14:05 altendky

I think this has been fixed by the recent change to exceptiongroup, @agronholm can reopen if I'm wrong.

Zac-HD avatar Oct 30 '22 08:10 Zac-HD