Closed mgorny closed 2 years ago
Sorry, had a thinko — it is pylint, not pydantic.
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.
Is another package monkey patching TracebackException
in this case?
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]
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.
It's likely conflicting with trio's own patching of TracebackException
.
Note that you can disable the monkeypatching by setting EXCEPTIONGROUP_NO_PATCH=1
in the environment.
Thanks but I'd really prefer some solution that would work long-term for everyone.
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.
Yeah, I think I can do that.
Would you mind testing against the code in the PR above?
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.
Can you post the traceback if it differs from the ones above?
Hmm, am I mistaken or this approach won't work if some other package does the patching after exceptiongroup?
What can I even do in such cases?
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".
I made a bunch of fixes that will likely solve this. Let me know how it worked.
Released v1.0.0rc8 with this fix.
Thanks a lot!
When running the test suite of pylint on a system with exceptiongroup package installed, the test suite suddenly crashes with the following traceback:
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: