agronholm / exceptiongroup

Backport of PEP 654 (exception groups)
Other
42 stars 20 forks source link

AttributeError: 'TracebackException' object has no attribute '_format_syntax_error' when running the test suite of `pylint` #11

Closed mgorny closed 2 years ago

mgorny commented 2 years ago

When running the test suite of pylint on a system with exceptiongroup package installed, the test suite suddenly crashes with the following traceback:

tests/checkers/unittest_non_ascii_name.py::TestNonAsciiChecker::test_check_import[from_okay_module_import_bad_as_good_and_star] 
INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/main.py", line 268, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/main.py", line 322, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/main.py", line 347, in pytest_runtestloop
INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/flaky/flaky_pytest_plugin.py", line 94, in pytest_runtest_protocol
INTERNALERROR>     self.runner.pytest_runtest_protocol(item, nextitem)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/runner.py", line 111, in pytest_runtest_protocol
INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/runner.py", line 130, in runtestprotocol
INTERNALERROR>     reports.append(call_and_report(item, "call", log))
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/flaky/flaky_pytest_plugin.py", line 141, in call_and_report
INTERNALERROR>     report = hook.pytest_runtest_makereport(item=item, call=call)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 55, in _multicall
INTERNALERROR>     gen.send(outcome)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/skipping.py", line 265, in pytest_runtest_makereport
INTERNALERROR>     rep = outcome.get_result()
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/runner.py", line 365, in pytest_runtest_makereport
INTERNALERROR>     return TestReport.from_item_and_call(item, call)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/reports.py", line 345, in from_item_and_call
INTERNALERROR>     longrepr = item.repr_failure(excinfo)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/python.py", line 1795, in repr_failure
INTERNALERROR>     return self._repr_failure_py(excinfo, style=style)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/nodes.py", line 475, in _repr_failure_py
INTERNALERROR>     return excinfo.getrepr(
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 666, in getrepr
INTERNALERROR>     return fmt.repr_excinfo(self)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 926, in repr_excinfo
INTERNALERROR>     reprtraceback = self.repr_traceback(excinfo_)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 867, in repr_traceback
INTERNALERROR>     reprentry = self.repr_traceback_entry(entry, einfo)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 818, in repr_traceback_entry
INTERNALERROR>     s = self.get_source(source, line_index, excinfo, short=short)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 756, in get_source
INTERNALERROR>     lines.extend(self.get_exconly(excinfo, indent=indent, markall=True))
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 768, in get_exconly
INTERNALERROR>     exlines = excinfo.exconly(tryshort=True).split("\n")
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 585, in exconly
INTERNALERROR>     lines = format_exception_only(self.type, self.value)
INTERNALERROR>   File "/usr/lib/python3.8/traceback.py", line 140, in format_exception_only
INTERNALERROR>     return list(TracebackException(etype, value, None).format_exception_only())
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py", line 149, in traceback_exception_format_exception_only
INTERNALERROR>     yield from self._format_syntax_error(stype)
INTERNALERROR> AttributeError: 'TracebackException' object has no attribute '_format_syntax_error'

Uninstalling exceptiongroup from the system resolves the problem. I wasn't able to make a clear reproducer in a venv yet — I suspect one of the pytest plugins installed on my system may be involved.

The pytest banner is:

platform linux -- Python 3.8.13, pytest-7.1.2, pluggy-1.0.0 -- /tmp/portage/dev-python/pylint-2.14.1/work/pylint-2.14.1-python3_8/install/usr/bin/python3.8
cachedir: .pytest_cache
PySide2 5.15.2 -- Qt runtime 5.15.4 -- Qt compiled 5.15.4
metadata: {'Python': '3.8.13', 'Platform': 'Linux-5.17.12-gentoo-dist-x86_64-AMD_Ryzen_5_3600_6-Core_Processor-with-glibc2.34', 'Packages': {'pytest': '7.1.2', 'py': '1.11.0', 'pluggy': '1.0.0'}, 'Plugins': {'timeout': '2.1.0', 'pytest_param_files': '0.3.4', 'tornasync': '0.6.0.post2', 'nbval': '0.9.6', 'regressions': '2.3.1', 'mock': '3.7.0', 'django': '4.5.2', 'qt': '4.0.2', 'pylama': '8.3.8', 'pyfakefs': '4.5.6', 'console-scripts': '1.3.1', 'xdoctest': '1.0.0', 'metadata': '2.0.1', 'trio': '0.7.0', 'httpbin': '1.0.2', 'freezegun': '0.4.2', 'toolbox': '0.4', 'testinfra': '6.7.0', 'pytest_codeblocks': '0.15.0', 'localserver': '0.6.0', 'xdist': '2.5.0', 'forked': '1.4.0', 'asyncio': '0.18.3', 'aiohttp': '1.0.4', 'flaky': '3.7.0', 'datadir': '1.3.1', 'expect': '1.1.0', 'rerunfailures': '10.2', 'shutil': '1.7.0', 'virtualenv': '1.7.0', 'anyio': '3.6.1', 'skip-markers': '1.3.0', 'lazy-fixture': '0.6.3', 'betamax': '0.8.1', 'kgb': '7.0', 'services': '2.2.1', 'requests-mock': '1.9.3', 'subtesthack': '0.1.2', 'xprocess': '0.19.0', 'helpers-namespace': '2021.12.29', 'pkgcore': '0.12.11', 'typeguard': '2.13.3', 'httpx': '0.21.0', 'subtests': '0.8.0', 'xvfb': '2.0.0', 'hypothesis': '6.46.11', 'shell-utilities': '1.5.0', 'snapshottest': '0.6.0', 'plus': '0.2', 'Faker': '13.12.1'}, 'JAVA_HOME': '/etc/java-config-2/current-system-vm'}
hypothesis profile 'default' -> database=DirectoryBasedExampleDatabase('/tmp/portage/dev-python/pylint-2.14.1/work/pylint-2.14.1/.hypothesis/examples')
rootdir: /tmp/portage/dev-python/pylint-2.14.1/work/pylint-2.14.1, configfile: setup.cfg, testpaths: tests
plugins: timeout-2.1.0, pytest_param_files-0.3.4, tornasync-0.6.0.post2, nbval-0.9.6, regressions-2.3.1, mock-3.7.0, django-4.5.2, qt-4.0.2, pylama-8.3.8, pyfakefs-4.5.6, console-scripts-1.3.1, xdoctest-1.0.0, metadata-2.0.1, trio-0.7.0, httpbin-1.0.2, freezegun-0.4.2, toolbox-0.4, testinfra-6.7.0, pytest_codeblocks-0.15.0, localserver-0.6.0, xdist-2.5.0, forked-1.4.0, asyncio-0.18.3, aiohttp-1.0.4, flaky-3.7.0, datadir-1.3.1, expect-1.1.0, rerunfailures-10.2, shutil-1.7.0, virtualenv-1.7.0, anyio-3.6.1, skip-markers-1.3.0, lazy-fixture-0.6.3, betamax-0.8.1, kgb-7.0, services-2.2.1, requests-mock-1.9.3, subtesthack-0.1.2, xprocess-0.19.0, helpers-namespace-2021.12.29, pkgcore-0.12.11, typeguard-2.13.3, httpx-0.21.0, subtests-0.8.0, xvfb-2.0.0, hypothesis-6.46.11, shell-utilities-1.5.0, snapshottest-0.6.0, plus-0.2, Faker-13.12.1
asyncio: mode=auto
mgorny commented 2 years ago

Sorry, had a thinko — it is pylint, not pydantic.

mgorny commented 2 years ago

Uninstalling flaky makes the exception a little shorter:

INTERNALERROR> Traceback (most recent call last):
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/main.py", line 268, in wrap_session
INTERNALERROR>     session.exitstatus = doit(config, session) or 0
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/main.py", line 322, in _main
INTERNALERROR>     config.hook.pytest_runtestloop(session=session)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/main.py", line 347, in pytest_runtestloop
INTERNALERROR>     item.config.hook.pytest_runtest_protocol(item=item, nextitem=nextitem)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 60, in _multicall
INTERNALERROR>     return outcome.get_result()
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/runner.py", line 111, in pytest_runtest_protocol
INTERNALERROR>     runtestprotocol(item, nextitem=nextitem)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/runner.py", line 130, in runtestprotocol
INTERNALERROR>     reports.append(call_and_report(item, "call", log))
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/runner.py", line 221, in call_and_report
INTERNALERROR>     report: TestReport = hook.pytest_runtest_makereport(item=item, call=call)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_hooks.py", line 265, in __call__
INTERNALERROR>     return self._hookexec(self.name, self.get_hookimpls(), kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_manager.py", line 80, in _hookexec
INTERNALERROR>     return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 55, in _multicall
INTERNALERROR>     gen.send(outcome)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/skipping.py", line 265, in pytest_runtest_makereport
INTERNALERROR>     rep = outcome.get_result()
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_result.py", line 60, in get_result
INTERNALERROR>     raise ex[1].with_traceback(ex[2])
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/pluggy/_callers.py", line 39, in _multicall
INTERNALERROR>     res = hook_impl.function(*args)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/runner.py", line 365, in pytest_runtest_makereport
INTERNALERROR>     return TestReport.from_item_and_call(item, call)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/reports.py", line 345, in from_item_and_call
INTERNALERROR>     longrepr = item.repr_failure(excinfo)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/python.py", line 1795, in repr_failure
INTERNALERROR>     return self._repr_failure_py(excinfo, style=style)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/nodes.py", line 475, in _repr_failure_py
INTERNALERROR>     return excinfo.getrepr(
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 666, in getrepr
INTERNALERROR>     return fmt.repr_excinfo(self)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 926, in repr_excinfo
INTERNALERROR>     reprtraceback = self.repr_traceback(excinfo_)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 867, in repr_traceback
INTERNALERROR>     reprentry = self.repr_traceback_entry(entry, einfo)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 818, in repr_traceback_entry
INTERNALERROR>     s = self.get_source(source, line_index, excinfo, short=short)
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 756, in get_source
INTERNALERROR>     lines.extend(self.get_exconly(excinfo, indent=indent, markall=True))
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 768, in get_exconly
INTERNALERROR>     exlines = excinfo.exconly(tryshort=True).split("\n")
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/_pytest/_code/code.py", line 585, in exconly
INTERNALERROR>     lines = format_exception_only(self.type, self.value)
INTERNALERROR>   File "/usr/lib/python3.8/traceback.py", line 140, in format_exception_only
INTERNALERROR>     return list(TracebackException(etype, value, None).format_exception_only())
INTERNALERROR>   File "/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py", line 149, in traceback_exception_format_exception_only
INTERNALERROR>     yield from self._format_syntax_error(stype)
INTERNALERROR> AttributeError: 'TracebackException' object has no attribute '_format_syntax_error'

I've also tried uninstalling trio, as grep suggested that it can monkey-patch TracebackException but that didn't help either.

agronholm commented 2 years ago

Is another package monkey patching TracebackException in this case?

mgorny commented 2 years ago

Is another package monkey patching TracebackException in this case?

A grep doesn't reveal anything else that would do that. FWICS there are just type stubs, a few uses and exceptiongroup.

$ grep -R TracebackException /usr/lib/python3.8/site-packages/
/usr/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/traceback.pyi:    class TracebackException:
/usr/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/traceback.pyi:        __cause__: TracebackException
/usr/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/traceback.pyi:        __context__: TracebackException
/usr/lib/python3.8/site-packages/jedi/third_party/typeshed/stdlib/2and3/traceback.pyi:        ) -> TracebackException: ...
/usr/lib/python3.8/site-packages/mypy/typeshed/stdlib/traceback.pyi:    "TracebackException",
/usr/lib/python3.8/site-packages/mypy/typeshed/stdlib/traceback.pyi:class TracebackException:
/usr/lib/python3.8/site-packages/mypy/typeshed/stdlib/traceback.pyi:    __cause__: TracebackException
/usr/lib/python3.8/site-packages/mypy/typeshed/stdlib/traceback.pyi:    __context__: TracebackException
grep: /usr/lib/python3.8/site-packages/testtools/__pycache__/content.cpython-38.pyc: binary file matches
grep: /usr/lib/python3.8/site-packages/testtools/__pycache__/content.cpython-38.opt-1.pyc: binary file matches
grep: /usr/lib/python3.8/site-packages/testtools/__pycache__/content.cpython-38.opt-2.pyc: binary file matches
/usr/lib/python3.8/site-packages/testtools/content.py:        stack_lines = list(traceback.TracebackException(exctype, value, tb,
grep: /usr/lib/python3.8/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-38.pyc: binary file matches
grep: /usr/lib/python3.8/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-38.opt-1.pyc: binary file matches
grep: /usr/lib/python3.8/site-packages/werkzeug/debug/__pycache__/tbtools.cpython-38.opt-2.pyc: binary file matches
/usr/lib/python3.8/site-packages/werkzeug/debug/tbtools.py:    te: t.Optional[traceback.TracebackException] = None,
/usr/lib/python3.8/site-packages/werkzeug/debug/tbtools.py:) -> traceback.TracebackException:
/usr/lib/python3.8/site-packages/werkzeug/debug/tbtools.py:        te = traceback.TracebackException.from_exception(exc, lookup_lines=False)
/usr/lib/python3.8/site-packages/werkzeug/debug/tbtools.py:        te: t.Optional[traceback.TracebackException] = None,
/usr/lib/python3.8/site-packages/werkzeug/debug/tbtools.py:    ) -> t.List[t.Tuple[t.Optional[str], traceback.TracebackException]]:
grep: /usr/lib/python3.8/site-packages/starlette/middleware/__pycache__/errors.cpython-38.pyc: binary file matches
grep: /usr/lib/python3.8/site-packages/starlette/middleware/__pycache__/errors.cpython-38.opt-1.pyc: binary file matches
grep: /usr/lib/python3.8/site-packages/starlette/middleware/__pycache__/errors.cpython-38.opt-2.pyc: binary file matches
/usr/lib/python3.8/site-packages/starlette/middleware/errors.py:        traceback_obj = traceback.TracebackException.from_exception(
/usr/lib/python3.8/site-packages/exceptiongroup-1.0.0rc7.dist-info/METADATA:* Patches to the ``TracebackException`` class that properly formats exception groups
/usr/lib/python3.8/site-packages/exceptiongroup-1.0.0rc7.dist-info/METADATA:  ``TracebackException`` (installed on import)
/usr/lib/python3.8/site-packages/exceptiongroup-1.0.0rc7.dist-info/METADATA:exception group classes are used instead, ``TracebackException`` is not monkey patched
/usr/lib/python3.8/site-packages/exceptiongroup-1.0.0rc7.dist-info/METADATA:#. The  ``traceback.TracebackException`` class is monkey patched to store extra
/usr/lib/python3.8/site-packages/exceptiongroup-1.0.0rc7.dist-info/METADATA:   ``traceback.TracebackException`` rather than the built-in rendered.
grep: /usr/lib/python3.8/site-packages/exceptiongroup/__pycache__/_formatting.cpython-38.opt-2.pyc: binary file matches
grep: /usr/lib/python3.8/site-packages/exceptiongroup/__pycache__/_formatting.cpython-38.opt-1.pyc: binary file matches
grep: /usr/lib/python3.8/site-packages/exceptiongroup/__pycache__/_formatting.cpython-38.pyc: binary file matches
/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py:    # Capture the original exception and its cause and context as TracebackExceptions
/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py:                    traceback.TracebackException.from_exception(
/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py:traceback_exception_original_init = traceback.TracebackException.__init__
/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py:traceback.TracebackException.__init__ = (  # type: ignore[assignment]
/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py:traceback_exception_original_format = traceback.TracebackException.format
/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py:traceback.TracebackException.format = (  # type: ignore[assignment]
/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py:    traceback.TracebackException.format_exception_only
/usr/lib/python3.8/site-packages/exceptiongroup/_formatting.py:traceback.TracebackException.format_exception_only = (  # type: ignore[assignment]
mgorny commented 2 years ago

Ok, it's definitely due to some pytest plugin — if I disable plugin autoloading entirely, it doesn't fail.

I've also confirmed that it fails if pytest-trio is installed. However, it is clear that some other package is causing the same problem as well. Should I report a bug to trio as well? To be honest, I'm not sure what to tell them.

agronholm commented 2 years ago

It's likely conflicting with trio's own patching of TracebackException.

agronholm commented 2 years ago

Note that you can disable the monkeypatching by setting EXCEPTIONGROUP_NO_PATCH=1 in the environment.

mgorny commented 2 years ago

Thanks but I'd really prefer some solution that would work long-term for everyone.

agronholm commented 2 years ago

For trio, this is the long term solution.

mgorny commented 2 years ago

Right. Though in this particular case, I was thinking of a solution that would work for all packages. Could it be perhaps possible to check if TracebackException is patched from the code relying on that?

The problem right now is that if people end up having both, say, pytest-trio (in current version) and exceptiongroup installed, random test suites are going to crash. I don't really think setting EXCEPTIONGROUP_NO_PATCH globally on all Gentoo systems is a good solution.

agronholm commented 2 years ago

Yeah, I think I can do that.

agronholm commented 2 years ago

Would you mind testing against the code in the PR above?

mgorny commented 2 years ago

Well, good news is that it seems to fix the problem with trio. Bad news is that it still fails on my test container, and I still can't figure out what's even causing it ;-f.

agronholm commented 2 years ago

Can you post the traceback if it differs from the ones above?

mgorny commented 2 years ago

Hmm, am I mistaken or this approach won't work if some other package does the patching after exceptiongroup?

agronholm commented 2 years ago

What can I even do in such cases?

mgorny commented 2 years ago

Can you post the traceback if it differs from the ones above?

It's the same as https://github.com/agronholm/exceptiongroup/issues/11#issuecomment-1148281700

What can I even do in such cases?

Perhaps check hasattr(self, "_format_syntax_error") in traceback_exception_format_exception_only(), or even some dedicated attribute saying "this is still our patched object".

agronholm commented 2 years ago

I made a bunch of fixes that will likely solve this. Let me know how it worked.

agronholm commented 2 years ago

Released v1.0.0rc8 with this fix.

mgorny commented 2 years ago

Thanks a lot!