Skip to content

Commit b81e297

Browse files
committed
Merge remote-tracking branch 'origin/main' into break_the_lot
2 parents cc97cca + 5d9067b commit b81e297

File tree

11 files changed

+61
-33
lines changed

11 files changed

+61
-33
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ repos:
2424
hooks:
2525
- id: black
2626
- repo: https://github.com/astral-sh/ruff-pre-commit
27-
rev: v0.6.7
27+
rev: v0.6.8
2828
hooks:
2929
- id: ruff
3030
types: [file]

docs-requirements.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ beautifulsoup4==4.12.3
1212
# via sphinx-codeautolink
1313
certifi==2024.8.30
1414
# via requests
15-
cffi==1.17.0 ; platform_python_implementation != 'PyPy' or os_name == 'nt'
15+
cffi==1.17.1 ; platform_python_implementation != 'PyPy' or os_name == 'nt'
1616
# via
1717
# -r docs-requirements.in
1818
# cryptography
@@ -24,15 +24,15 @@ colorama==0.4.6 ; sys_platform == 'win32' or platform_system == 'Windows'
2424
# via
2525
# click
2626
# sphinx
27-
cryptography==43.0.0
27+
cryptography==43.0.1
2828
# via pyopenssl
2929
docutils==0.20.1
3030
# via
3131
# sphinx
3232
# sphinx-rtd-theme
3333
exceptiongroup==1.2.2
3434
# via -r docs-requirements.in
35-
idna==3.8
35+
idna==3.10
3636
# via
3737
# -r docs-requirements.in
3838
# requests
@@ -77,7 +77,7 @@ sphinx==7.4.7
7777
# sphinxcontrib-trio
7878
sphinx-codeautolink==0.15.2
7979
# via -r docs-requirements.in
80-
sphinx-hoverxref==1.4.0
80+
sphinx-hoverxref==1.4.1
8181
# via -r docs-requirements.in
8282
sphinx-rtd-theme==2.0.0
8383
# via -r docs-requirements.in
@@ -102,5 +102,5 @@ sphinxcontrib-trio==1.1.2
102102
# via -r docs-requirements.in
103103
towncrier==24.8.0
104104
# via -r docs-requirements.in
105-
urllib3==2.2.2
105+
urllib3==2.2.3
106106
# via requests

docs/source/reference-core.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,8 @@ more features beyond the core channel interface:
12411241
.. autoclass:: MemoryReceiveChannel
12421242
:members:
12431243

1244+
.. autoclass:: MemoryChannelStatistics
1245+
:members:
12441246

12451247
A simple channel example
12461248
++++++++++++++++++++++++

newsfragments/3095.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update :func:`trio.sleep_forever` to be `NoReturn`.

newsfragments/3101.doc.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add docstrings for memory channels' ``statistics()`` and ``aclose`` methods.

src/trio/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
# Submodules imported by default
2626
from . import abc, from_thread, lowlevel, socket, to_thread
2727
from ._channel import (
28+
MemoryChannelStatistics as MemoryChannelStatistics,
2829
MemoryReceiveChannel as MemoryReceiveChannel,
2930
MemorySendChannel as MemorySendChannel,
3031
open_memory_channel as open_memory_channel,

src/trio/_channel.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ def __init__(self, max_buffer_size: int | float): # noqa: PYI041
111111

112112

113113
@attrs.frozen
114-
class MemoryChannelStats:
114+
class MemoryChannelStatistics:
115115
current_buffer_used: int
116116
max_buffer_size: int | float
117117
open_send_channels: int
@@ -132,8 +132,8 @@ class MemoryChannelState(Generic[T]):
132132
# {task: None}
133133
receive_tasks: OrderedDict[Task, None] = attrs.Factory(OrderedDict)
134134

135-
def statistics(self) -> MemoryChannelStats:
136-
return MemoryChannelStats(
135+
def statistics(self) -> MemoryChannelStatistics:
136+
return MemoryChannelStatistics(
137137
current_buffer_used=len(self.data),
138138
max_buffer_size=self.max_buffer_size,
139139
open_send_channels=self.open_send_channels,
@@ -159,7 +159,9 @@ def __attrs_post_init__(self) -> None:
159159
def __repr__(self) -> str:
160160
return f"<send channel at {id(self):#x}, using buffer at {id(self._state):#x}>"
161161

162-
def statistics(self) -> MemoryChannelStats:
162+
def statistics(self) -> MemoryChannelStatistics:
163+
"""Returns a `MemoryChannelStatistics` for the memory channel this is
164+
associated with."""
163165
# XX should we also report statistics specific to this object?
164166
return self._state.statistics()
165167

@@ -282,6 +284,9 @@ def close(self) -> None:
282284

283285
@enable_ki_protection
284286
async def aclose(self) -> None:
287+
"""Close this send channel object asynchronously.
288+
289+
See `MemorySendChannel.close`."""
285290
self.close()
286291
await trio.lowlevel.checkpoint()
287292

@@ -296,7 +301,9 @@ class MemoryReceiveChannel(ReceiveChannel[ReceiveType], metaclass=NoPublicConstr
296301
def __attrs_post_init__(self) -> None:
297302
self._state.open_receive_channels += 1
298303

299-
def statistics(self) -> MemoryChannelStats:
304+
def statistics(self) -> MemoryChannelStatistics:
305+
"""Returns a `MemoryChannelStatistics` for the memory channel this is
306+
associated with."""
300307
return self._state.statistics()
301308

302309
def __repr__(self) -> str:
@@ -430,5 +437,8 @@ def close(self) -> None:
430437

431438
@enable_ki_protection
432439
async def aclose(self) -> None:
440+
"""Close this receive channel object asynchronously.
441+
442+
See `MemoryReceiveChannel.close`."""
433443
self.close()
434444
await trio.lowlevel.checkpoint()

src/trio/_tests/_check_type_completeness.json

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,10 @@
2020
"all": [
2121
"No docstring found for class \"trio.MemoryReceiveChannel\"",
2222
"No docstring found for class \"trio._channel.MemoryReceiveChannel\"",
23-
"No docstring found for function \"trio._channel.MemoryReceiveChannel.statistics\"",
24-
"No docstring found for class \"trio._channel.MemoryChannelStats\"",
25-
"No docstring found for function \"trio._channel.MemoryReceiveChannel.aclose\"",
23+
"No docstring found for class \"trio.MemoryChannelStatistics\"",
24+
"No docstring found for class \"trio._channel.MemoryChannelStatistics\"",
2625
"No docstring found for class \"trio.MemorySendChannel\"",
2726
"No docstring found for class \"trio._channel.MemorySendChannel\"",
28-
"No docstring found for function \"trio._channel.MemorySendChannel.statistics\"",
29-
"No docstring found for function \"trio._channel.MemorySendChannel.aclose\"",
3027
"No docstring found for class \"trio._core._run.Task\"",
3128
"No docstring found for class \"trio._socket.SocketType\"",
3229
"No docstring found for function \"trio._highlevel_socket.SocketStream.send_all\"",

src/trio/_tests/test_timeouts.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,20 @@ async def sleep_3() -> None:
8686
await check_takes_about(sleep_3, TARGET)
8787

8888

89+
async def test_cannot_wake_sleep_forever() -> None:
90+
# Test an error occurs if you manually wake sleep_forever().
91+
task = trio.lowlevel.current_task()
92+
93+
async def wake_task() -> None:
94+
await trio.lowlevel.checkpoint()
95+
trio.lowlevel.reschedule(task, outcome.Value(None))
96+
97+
async with trio.open_nursery() as nursery:
98+
nursery.start_soon(wake_task)
99+
with pytest.raises(RuntimeError):
100+
await trio.sleep_forever()
101+
102+
89103
class TimeoutScope(Protocol):
90104
def __call__(self, seconds: float, *, shield: bool) -> trio.CancelScope: ...
91105

src/trio/_timeouts.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import math
44
import sys
55
from contextlib import contextmanager
6-
from typing import TYPE_CHECKING
6+
from typing import TYPE_CHECKING, NoReturn
77

88
import trio
99

@@ -58,13 +58,14 @@ def move_on_after(
5858
)
5959

6060

61-
async def sleep_forever() -> None:
61+
async def sleep_forever() -> NoReturn:
6262
"""Pause execution of the current task forever (or until cancelled).
6363
6464
Equivalent to calling ``await sleep(math.inf)``.
6565
6666
"""
6767
await trio.lowlevel.wait_task_rescheduled(lambda _: trio.lowlevel.Abort.SUCCEEDED)
68+
raise RuntimeError("Should never have been rescheduled!")
6869

6970

7071
async def sleep_until(deadline: float) -> None:

0 commit comments

Comments
 (0)