-
-
Notifications
You must be signed in to change notification settings - Fork 345
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
remove multierror #2891
Merged
Merged
remove multierror #2891
Changes from 24 commits
Commits
Show all changes
25 commits
Select commit
Hold shift + click to select a range
5ff3464
remove multierror
jakkdl 9c23ab0
remove more unused code, fix test_cancel_scope_multierror_filtering i…
jakkdl 4cb329f
fix remaining failing tests, instantly collapse groups in nurseries i…
jakkdl 3822dc1
bump exceptiongroup version to one that has the apport excepthook
jakkdl f52ea57
remove multierror_scripts, rename _core/_multierror.py to _core/_conc…
jakkdl 4d600bc
edit some comments, remove test_ExceptionGroupNotHashable
jakkdl 091e962
Merge branch 'master' into multierror_removal
jakkdl 8246daf
docs: update some references to MultiError, remove section about main…
jakkdl a7a5a71
add newsfragment
jakkdl bfca5a5
Merge remote-tracking branch 'origin/master' into multierror_removal
jakkdl 5dd4b95
update gc comments to my current state of understanding as to what ca…
jakkdl 47ef84a
Merge remote-tracking branch 'origin/master' into multierror_removal
jakkdl 95252ac
Merge remote-tracking branch 'origin/master' into multierror_removal
jakkdl 9c1400c
move 'collapsible' to __notes__, clean up some stray unused-ignores, …
jakkdl 907a2c5
update exceptiongroup message, test for it with a match
jakkdl 3319a01
fix expected message
jakkdl 9941762
fix mypy (this should be checked by pre-commit...)
jakkdl 6977353
add test for loose exceptiongroup collapsing, rename test_multierror
jakkdl bd72a32
fix test
jakkdl 0439e66
Apply suggestions from code review
jakkdl e19f341
update comments after review from a5rocks
jakkdl b0eb6b4
make the note more verbose
jakkdl d4463eb
Merge branch 'master' into multierror_removal
jakkdl f433fdb
fix the test
jakkdl 3e485dc
update comment
jakkdl File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
``MultiError`` has been fully removed, and all relevant trio functions now raise ExceptionGroups instead. This should not affect end users that have transitioned to using ``except*`` or catching ExceptionGroup/BaseExceptionGroup. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
from __future__ import annotations | ||
|
||
from types import TracebackType | ||
from typing import Any, ClassVar, cast | ||
|
||
################################################################ | ||
# concat_tb | ||
################################################################ | ||
|
||
# We need to compute a new traceback that is the concatenation of two existing | ||
# tracebacks. This requires copying the entries in 'head' and then pointing | ||
# the final tb_next to 'tail'. | ||
# | ||
# NB: 'tail' might be None, which requires some special handling in the ctypes | ||
# version. | ||
# | ||
# The complication here is that Python doesn't actually support copying or | ||
# modifying traceback objects, so we have to get creative... | ||
# | ||
# On CPython, we use ctypes. On PyPy, we use "transparent proxies". | ||
# | ||
# Jinja2 is a useful source of inspiration: | ||
# https://github.com/pallets/jinja/blob/main/src/jinja2/debug.py | ||
|
||
try: | ||
import tputil | ||
except ImportError: | ||
# ctypes it is | ||
import ctypes | ||
|
||
# How to handle refcounting? I don't want to use ctypes.py_object because | ||
# I don't understand or trust it, and I don't want to use | ||
# ctypes.pythonapi.Py_{Inc,Dec}Ref because we might clash with user code | ||
# that also tries to use them but with different types. So private _ctypes | ||
# APIs it is! | ||
import _ctypes | ||
|
||
class CTraceback(ctypes.Structure): | ||
_fields_: ClassVar = [ | ||
("PyObject_HEAD", ctypes.c_byte * object().__sizeof__()), | ||
("tb_next", ctypes.c_void_p), | ||
("tb_frame", ctypes.c_void_p), | ||
("tb_lasti", ctypes.c_int), | ||
("tb_lineno", ctypes.c_int), | ||
] | ||
|
||
def copy_tb(base_tb: TracebackType, tb_next: TracebackType | None) -> TracebackType: | ||
# TracebackType has no public constructor, so allocate one the hard way | ||
try: | ||
raise ValueError | ||
except ValueError as exc: | ||
new_tb = exc.__traceback__ | ||
assert new_tb is not None | ||
c_new_tb = CTraceback.from_address(id(new_tb)) | ||
|
||
# At the C level, tb_next either points to the next traceback or is | ||
# NULL. c_void_p and the .tb_next accessor both convert NULL to None, | ||
# but we shouldn't DECREF None just because we assigned to a NULL | ||
# pointer! Here we know that our new traceback has only 1 frame in it, | ||
# so we can assume the tb_next field is NULL. | ||
assert c_new_tb.tb_next is None | ||
# If tb_next is None, then we want to set c_new_tb.tb_next to NULL, | ||
# which it already is, so we're done. Otherwise, we have to actually | ||
# do some work: | ||
if tb_next is not None: | ||
_ctypes.Py_INCREF(tb_next) # type: ignore[attr-defined] | ||
c_new_tb.tb_next = id(tb_next) | ||
|
||
assert c_new_tb.tb_frame is not None | ||
_ctypes.Py_INCREF(base_tb.tb_frame) # type: ignore[attr-defined] | ||
old_tb_frame = new_tb.tb_frame | ||
c_new_tb.tb_frame = id(base_tb.tb_frame) | ||
_ctypes.Py_DECREF(old_tb_frame) # type: ignore[attr-defined] | ||
|
||
c_new_tb.tb_lasti = base_tb.tb_lasti | ||
c_new_tb.tb_lineno = base_tb.tb_lineno | ||
|
||
try: | ||
return new_tb | ||
finally: | ||
# delete references from locals to avoid creating cycles | ||
# see test_cancel_scope_exit_doesnt_create_cyclic_garbage | ||
del new_tb, old_tb_frame | ||
|
||
else: | ||
# http://doc.pypy.org/en/latest/objspace-proxies.html | ||
def copy_tb(base_tb: TracebackType, tb_next: TracebackType | None) -> TracebackType: | ||
# tputil.ProxyOperation is PyPy-only, and there's no way to specify | ||
# cpython/pypy in current type checkers. | ||
def controller(operation: tputil.ProxyOperation) -> Any | None: # type: ignore[no-any-unimported] | ||
# Rationale for pragma: I looked fairly carefully and tried a few | ||
# things, and AFAICT it's not actually possible to get any | ||
# 'opname' that isn't __getattr__ or __getattribute__. So there's | ||
# no missing test we could add, and no value in coverage nagging | ||
# us about adding one. | ||
if ( | ||
operation.opname | ||
in { | ||
"__getattribute__", | ||
"__getattr__", | ||
} | ||
and operation.args[0] == "tb_next" | ||
): # pragma: no cover | ||
return tb_next | ||
return operation.delegate() # Delegate is reverting to original behaviour | ||
|
||
return cast( | ||
TracebackType, tputil.make_proxy(controller, type(base_tb), base_tb) | ||
) # Returns proxy to traceback | ||
|
||
|
||
# this is used for collapsing single-exception ExceptionGroups when using | ||
# `strict_exception_groups=False`. Once that is retired this function and its helper can | ||
# be removed as well. | ||
def concat_tb( | ||
head: TracebackType | None, tail: TracebackType | None | ||
) -> TracebackType | None: | ||
# We have to use an iterative algorithm here, because in the worst case | ||
# this might be a RecursionError stack that is by definition too deep to | ||
# process by recursion! | ||
head_tbs = [] | ||
pointer = head | ||
while pointer is not None: | ||
head_tbs.append(pointer) | ||
pointer = pointer.tb_next | ||
current_head = tail | ||
for head_tb in reversed(head_tbs): | ||
current_head = copy_tb(head_tb, tb_next=current_head) | ||
return current_head |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I guess any release with these should be 0.24.0? Release preparation page says "two months or two releases, whichever is longer") and I assume it means minor releases.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
makes sense to do major (or whatever 0.X releases are called) release on both this and on #2886 since they can break stuff.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't get why Trio doesn't have a 1.0.0 release yet if compatibility guarantees are this stringent anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd be inclined to go 1.0 when we've got this and strict-by-default in; I agree but it seems odd to make that release right before some substantial changes.