Skip to content

Commit cdce9d5

Browse files
authored
Merge branch 'master' into bump_pyright
2 parents 5acf76f + a10f94b commit cdce9d5

38 files changed

+1430
-1293
lines changed

.pre-commit-config.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,11 @@ repos:
1919
- id: sort-simple-yaml
2020
files: .pre-commit-config.yaml
2121
- repo: https://github.com/psf/black-pre-commit-mirror
22-
rev: 23.12.0
22+
rev: 23.12.1
2323
hooks:
2424
- id: black
2525
- repo: https://github.com/astral-sh/ruff-pre-commit
26-
rev: v0.1.8
26+
rev: v0.1.11
2727
hooks:
2828
- id: ruff
2929
types: [file]

check.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,12 @@ echo "::group::Mypy"
5757
rm -f mypy_annotate.dat
5858
# Pipefail makes these pipelines fail if mypy does, even if mypy_annotate.py succeeds.
5959
set -o pipefail
60-
mypy src/trio --show-error-end --platform linux | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Linux \
60+
mypy --show-error-end --platform linux | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Linux \
6161
|| { echo "* Mypy (Linux) found type errors." >> "$GITHUB_STEP_SUMMARY"; MYPY=1; }
6262
# Darwin tests FreeBSD too
63-
mypy src/trio --show-error-end --platform darwin | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Mac \
63+
mypy --show-error-end --platform darwin | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Mac \
6464
|| { echo "* Mypy (Mac) found type errors." >> "$GITHUB_STEP_SUMMARY"; MYPY=1; }
65-
mypy src/trio --show-error-end --platform win32 | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Windows \
65+
mypy --show-error-end --platform win32 | python ./src/trio/_tools/mypy_annotate.py --dumpfile mypy_annotate.dat --platform Windows \
6666
|| { echo "* Mypy (Windows) found type errors." >> "$GITHUB_STEP_SUMMARY"; MYPY=1; }
6767
set +o pipefail
6868
# Re-display errors using Github's syntax, read out of mypy_annotate.dat

docs-requirements.in

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
# RTD is currently installing 1.5.3, which has a bug in :lineno-match:
2-
sphinx >= 4.0, < 6.2
1+
# RTD is currently installing 1.5.3, which has a bug in :lineno-match: (??)
2+
# sphinx 5.3 doesn't work with our _NoValue workaround
3+
sphinx >= 6.0
34
jinja2
45
sphinx_rtd_theme
56
sphinxcontrib-jquery

docs-requirements.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#
77
alabaster==0.7.13
88
# via sphinx
9-
attrs==23.1.0
9+
attrs==23.2.0
1010
# via
1111
# -r docs-requirements.in
1212
# outcome
@@ -22,7 +22,7 @@ click==8.1.7
2222
# via towncrier
2323
cryptography==41.0.7
2424
# via pyopenssl
25-
docutils==0.19
25+
docutils==0.20.1
2626
# via
2727
# sphinx
2828
# sphinx-rtd-theme
@@ -36,7 +36,7 @@ imagesize==1.4.1
3636
# via sphinx
3737
immutables==0.20
3838
# via -r docs-requirements.in
39-
importlib-metadata==7.0.0
39+
importlib-metadata==7.0.1
4040
# via sphinx
4141
importlib-resources==6.1.1
4242
# via towncrier
@@ -69,7 +69,7 @@ snowballstemmer==2.2.0
6969
# via sphinx
7070
sortedcontainers==2.4.0
7171
# via -r docs-requirements.in
72-
sphinx==6.1.3
72+
sphinx==7.1.2
7373
# via
7474
# -r docs-requirements.in
7575
# sphinx-rtd-theme

docs/source/conf.py

Lines changed: 83 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,16 @@
1616
# add these directories to sys.path here. If the directory is relative to the
1717
# documentation root, use os.path.abspath to make it absolute, like shown here.
1818
#
19+
from __future__ import annotations
20+
21+
import collections.abc
1922
import os
2023
import sys
24+
from typing import TYPE_CHECKING, cast
25+
26+
if TYPE_CHECKING:
27+
from sphinx.application import Sphinx
28+
from sphinx.util.typing import Inventory
2129

2230
# For our local_customization module
2331
sys.path.insert(0, os.path.abspath("."))
@@ -41,6 +49,21 @@
4149
check=True,
4250
)
4351

52+
# Sphinx is very finicky, and somewhat buggy, so we have several different
53+
# methods to help it resolve links.
54+
# 1. The ones that are not possible to fix are added to `nitpick_ignore`
55+
# 2. some can be resolved with a simple alias in `autodoc_type_aliases`,
56+
# even if that is primarily meant for TypeAliases
57+
# 3. autodoc_process_signature is hooked up to an event, and we use it for
58+
# whole-sale replacing types in signatures where internal details are not
59+
# relevant or hard to read.
60+
# 4. add_intersphinx manually modifies the intersphinx mappings after
61+
# objects.inv has been parsed, to resolve bugs and version differences
62+
# that causes some objects to be looked up incorrectly.
63+
# 5. docs/source/typevars.py handles redirecting `typing_extensions` objects to `typing`, and linking `TypeVar`s to `typing.TypeVar` instead of sphinx wanting to link them to their individual definitions.
64+
# It's possible there's better methods for resolving some of the above
65+
# problems, but this works for now:tm:
66+
4467
# Warn about all references to unknown targets
4568
nitpicky = True
4669
# Except for these ones, which we expect to point to unknown targets:
@@ -51,36 +74,37 @@
5174
("py:class", "trio.lowlevel.RunLocal"),
5275
# trio.abc is documented at random places scattered throughout the docs
5376
("py:mod", "trio.abc"),
54-
("py:class", "math.inf"),
5577
("py:exc", "Anything else"),
5678
("py:class", "async function"),
5779
("py:class", "sync function"),
58-
# why aren't these found in stdlib?
59-
("py:class", "types.FrameType"),
60-
# these are not defined in https://docs.python.org/3/objects.inv
80+
# these do not have documentation on python.org
81+
# nor entries in objects.inv
6182
("py:class", "socket.AddressFamily"),
6283
("py:class", "socket.SocketKind"),
63-
("py:class", "Buffer"), # collections.abc.Buffer, in 3.12
6484
]
6585
autodoc_inherit_docstrings = False
6686
default_role = "obj"
6787

68-
# These have incorrect __module__ set in stdlib and give the error
69-
# `py:class reference target not found`
70-
# Some of the nitpick_ignore's above can probably be fixed with this.
71-
# See https://github.com/sphinx-doc/sphinx/issues/8315#issuecomment-751335798
88+
89+
# A dictionary for users defined type aliases that maps a type name to the full-qualified object name. It is used to keep type aliases not evaluated in the document.
90+
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#confval-autodoc_type_aliases
91+
# but it can also be used to help resolve various linking problems
7292
autodoc_type_aliases = {
73-
# aliasing doesn't actually fix the warning for types.FrameType, but displaying
74-
# "types.FrameType" is more helpful than just "frame"
75-
"FrameType": "types.FrameType",
7693
# SSLListener.accept's return type is seen as trio._ssl.SSLStream
7794
"SSLStream": "trio.SSLStream",
7895
}
7996

8097

98+
# https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html#event-autodoc-process-signature
8199
def autodoc_process_signature(
82-
app, what, name, obj, options, signature, return_annotation
83-
):
100+
app: Sphinx,
101+
what: object,
102+
name: str,
103+
obj: object,
104+
options: object,
105+
signature: str,
106+
return_annotation: str,
107+
) -> tuple[str, str]:
84108
"""Modify found signatures to fix various issues."""
85109
if signature is not None:
86110
signature = signature.replace("~_contextvars.Context", "~contextvars.Context")
@@ -103,7 +127,7 @@ def autodoc_process_signature(
103127
# is shipped (should be in the release after 0.2.4)
104128
# ...note that this has since grown to contain a bunch of other CSS hacks too
105129
# though.
106-
def setup(app):
130+
def setup(app: Sphinx) -> None:
107131
app.add_css_file("hackrtd.css")
108132
app.connect("autodoc-process-signature", autodoc_process_signature)
109133
# After Intersphinx runs, add additional mappings.
@@ -138,15 +162,49 @@ def setup(app):
138162
}
139163

140164

141-
def add_intersphinx(app) -> None:
142-
"""Add some specific intersphinx mappings."""
165+
def add_intersphinx(app: Sphinx) -> None:
166+
"""Add some specific intersphinx mappings.
167+
168+
Hooked up to builder-inited. app.builder.env.interpshinx_inventory is not an official API, so this may break on new sphinx versions.
169+
"""
170+
171+
def add_mapping(
172+
reftype: str,
173+
library: str,
174+
obj: str,
175+
version: str = "3.12",
176+
target: str | None = None,
177+
) -> None:
178+
"""helper function"""
179+
url_version = "3" if version == "3.12" else version
180+
if target is None:
181+
target = f"{library}.{obj}"
182+
183+
# sphinx doing fancy caching stuff makes this attribute invisible
184+
# to type checkers
185+
inventory = app.builder.env.intersphinx_inventory # type: ignore[attr-defined]
186+
assert isinstance(inventory, dict)
187+
inventory = cast("Inventory", inventory)
188+
189+
inventory[f"py:{reftype}"][f"{target}"] = (
190+
"Python",
191+
version,
192+
f"https://docs.python.org/{url_version}/library/{library}.html/{obj}",
193+
"-",
194+
)
195+
143196
# This has been removed in Py3.12, so add a link to the 3.11 version with deprecation warnings.
144-
app.builder.env.intersphinx_inventory["py:method"]["pathlib.Path.link_to"] = (
145-
"Python",
146-
"3.11",
147-
"https://docs.python.org/3.11/library/pathlib.html#pathlib.Path.link_to",
148-
"-",
149-
)
197+
add_mapping("method", "pathlib", "Path.link_to", "3.11")
198+
# defined in py:data in objects.inv, but sphinx looks for a py:class
199+
add_mapping("class", "math", "inf")
200+
# `types.FrameType.__module__` is "builtins", so sphinx looks for
201+
# builtins.FrameType.
202+
# See https://github.com/sphinx-doc/sphinx/issues/11802
203+
add_mapping("class", "types", "FrameType")
204+
# new in py3.12, and need target because sphinx is unable to look up
205+
# the module of the object if compiling on <3.12
206+
if not hasattr(collections.abc, "Buffer"):
207+
add_mapping("class", "collections.abc", "Buffer", target="Buffer")
150208

151209

152210
autodoc_member_order = "bysource"
@@ -193,7 +251,7 @@ def add_intersphinx(app) -> None:
193251
# List of patterns, relative to source directory, that match files and
194252
# directories to ignore when looking for source files.
195253
# This patterns also effect to html_static_path and html_extra_path
196-
exclude_patterns = []
254+
exclude_patterns: list[str] = []
197255

198256
# The name of the Pygments (syntax highlighting) style to use.
199257
pygments_style = "default"
@@ -252,7 +310,7 @@ def add_intersphinx(app) -> None:
252310

253311
# -- Options for LaTeX output ---------------------------------------------
254312

255-
latex_elements = {
313+
latex_elements: dict[str, object] = {
256314
# The paper size ('letterpaper' or 'a4paper').
257315
#
258316
# 'papersize': 'letterpaper',

docs/source/local_customization.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
15
from docutils.parsers.rst import directives as directives
26
from sphinx import addnodes
37
from sphinx.domains.python import PyClasslike
@@ -8,6 +12,10 @@
812
Options as Options,
913
)
1014

15+
if TYPE_CHECKING:
16+
from sphinx.addnodes import desc_signature
17+
from sphinx.application import Sphinx
18+
1119
"""
1220
1321
.. interface:: The nursery interface
@@ -18,13 +26,13 @@
1826

1927

2028
class Interface(PyClasslike):
21-
def handle_signature(self, sig, signode):
29+
def handle_signature(self, sig: str, signode: desc_signature) -> tuple[str, str]:
2230
signode += addnodes.desc_name(sig, sig)
2331
return sig, ""
2432

25-
def get_index_text(self, modname, name_cls):
33+
def get_index_text(self, modname: str, name_cls: tuple[str, str]) -> str:
2634
return f"{name_cls[0]} (interface in {modname})"
2735

2836

29-
def setup(app):
37+
def setup(app: Sphinx) -> None:
3038
app.add_directive_to_domain("py", "interface", Interface)

docs/source/reference-core.rst

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -768,12 +768,6 @@ inside the handler function(s) with the ``nonlocal`` keyword::
768768
async with trio.open_nursery() as nursery:
769769
nursery.start_soon(broken1)
770770

771-
For reasons of backwards compatibility, nurseries raise ``trio.MultiError`` and
772-
``trio.NonBaseMultiError`` which inherit from :exc:`BaseExceptionGroup` and
773-
:exc:`ExceptionGroup`, respectively. Users should refrain from attempting to raise or
774-
catch the Trio specific exceptions themselves, and treat them as if they were standard
775-
:exc:`BaseExceptionGroup` or :exc:`ExceptionGroup` instances instead.
776-
777771
"Strict" versus "loose" ExceptionGroup semantics
778772
++++++++++++++++++++++++++++++++++++++++++++++++
779773

docs/source/reference-testing.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,16 @@ Testing checkpoints
219219

220220
.. autofunction:: assert_no_checkpoints
221221
:with:
222+
223+
224+
ExceptionGroup helpers
225+
----------------------
226+
227+
.. autoclass:: RaisesGroup
228+
:members:
229+
230+
.. autoclass:: Matcher
231+
:members:
232+
233+
.. autoclass:: trio.testing._raises_group._ExceptionInfo
234+
:members:

docs/source/tutorial.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,7 @@ TODO: maybe a brief discussion of :exc:`KeyboardInterrupt` handling?
11681168
you can stick anything inside a timeout block, even child tasks
11691169

11701170
[show something like the first example but with a timeout – they
1171-
both get cancelled, the cancelleds get packed into a multierror, and
1171+
both get cancelled, the cancelleds get packed into an ExceptionGroup, and
11721172
then the timeout block catches the cancelled]
11731173

11741174
brief discussion of KI?

docs/source/typevars.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def lookup_reference(
6060
new_node["reftarget"] = f"typing.{target[18:]}"
6161
# This fires off this same event, with our new modified node in order to fetch the right
6262
# URL to use.
63-
return app.emit_firstresult(
63+
return app.emit_firstresult( # type: ignore[no-any-return]
6464
"missing-reference",
6565
env,
6666
new_node,

newsfragments/2785.feature.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
New helper classes: :class:`~.testing.RaisesGroup` and :class:`~.testing.Matcher`.
2+
3+
In preparation for changing the default of ``strict_exception_groups`` to `True`, we're introducing a set of helper classes that can be used in place of `pytest.raises <https://docs.pytest.org/en/stable/reference/reference.html#pytest.raises>`_ in tests, to check for an expected `ExceptionGroup`.
4+
These are provisional, and only planned to be supplied until there's a good solution in ``pytest``. See https://github.com/pytest-dev/pytest/issues/11538

newsfragments/2891.deprecated.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
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.

pyproject.toml

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,6 @@ extend-exclude = [
123123
[tool.ruff.per-file-ignores]
124124
'src/trio/__init__.py' = ['F401']
125125
'src/trio/_core/__init__.py' = ['F401']
126-
'src/trio/_core/_tests/test_multierror_scripts/*' = ['F401']
127126
'src/trio/abc.py' = ['F401']
128127
'src/trio/lowlevel.py' = ['F401']
129128
'src/trio/socket.py' = ['F401']
@@ -137,6 +136,7 @@ fixture-parentheses = false
137136

138137
[tool.mypy]
139138
python_version = "3.8"
139+
files = ["src/trio/", "docs/source/*.py"]
140140

141141
# Be flexible about dependencies that don't have stubs yet (like pytest)
142142
ignore_missing_imports = true
@@ -236,9 +236,6 @@ showcontent = true
236236
branch = true
237237
source_pkgs = ["trio"]
238238
omit = [
239-
# These are run in subprocesses, but still don't work. We follow
240-
# coverage's documentation to no avail.
241-
"*/trio/_core/_tests/test_multierror_scripts/*",
242239
# Omit the generated files in trio/_core starting with _generated_
243240
"*/trio/_core/_generated_*",
244241
# Type tests aren't intended to be run, just passed to type checkers.

0 commit comments

Comments
 (0)