Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion trio/_channel.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

from ._abc import ReceiveChannel, ReceiveType, SendChannel, SendType, T
from ._core import Abort, RaiseCancelT, Task, enable_ki_protection
from ._util import NoPublicConstructor, generic_function
from ._util import NoPublicConstructor, final, generic_function

if TYPE_CHECKING:
from typing_extensions import Self
Expand Down Expand Up @@ -138,6 +138,7 @@ def statistics(self) -> MemoryChannelStats:
)


@final
@attr.s(eq=False, repr=False)
class MemorySendChannel(SendChannel[SendType], metaclass=NoPublicConstructor):
_state: MemoryChannelState[SendType] = attr.ib()
Expand Down Expand Up @@ -282,6 +283,7 @@ async def aclose(self) -> None:
await trio.lowlevel.checkpoint()


@final
@attr.s(eq=False, repr=False)
class MemoryReceiveChannel(ReceiveChannel[ReceiveType], metaclass=NoPublicConstructor):
_state: MemoryChannelState[ReceiveType] = attr.ib()
Expand Down
3 changes: 2 additions & 1 deletion trio/_core/_entry_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import attr

from .. import _core
from .._util import NoPublicConstructor
from .._util import NoPublicConstructor, final
from ._wakeup_socketpair import WakeupSocketpair

# TODO: Type with TypeVarTuple, at least to an extent where it makes
Expand Down Expand Up @@ -139,6 +139,7 @@ def run_sync_soon(
self.wakeup.wakeup_thread_and_signal_safe()


@final
@attr.s(eq=False, hash=False, slots=True)
class TrioToken(metaclass=NoPublicConstructor):
"""An opaque object representing a single call to :func:`trio.run`.
Expand Down
3 changes: 2 additions & 1 deletion trio/_core/_exceptions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from trio._util import NoPublicConstructor
from trio._util import NoPublicConstructor, final


class TrioInternalError(Exception):
Expand Down Expand Up @@ -26,6 +26,7 @@ class WouldBlock(Exception):
"""Raised by ``X_nowait`` functions if ``X`` would block."""


@final
class Cancelled(BaseException, metaclass=NoPublicConstructor):
"""Raised by blocking calls if the surrounding scope has been cancelled.

Expand Down
10 changes: 6 additions & 4 deletions trio/_core/_local.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
from __future__ import annotations

from typing import Generic, TypeVar, cast, final
from typing import Generic, TypeVar, cast

# Runvar implementations
import attr

from .._util import Final, NoPublicConstructor
from .._util import NoPublicConstructor, final
from . import _run

T = TypeVar("T")


@final
class _NoValue(metaclass=Final):
class _NoValue:
...


@final
@attr.s(eq=False, hash=False, slots=False)
class RunVarToken(Generic[T], metaclass=NoPublicConstructor):
_var: RunVar[T] = attr.ib()
Expand All @@ -27,8 +28,9 @@ def _empty(cls, var: RunVar[T]) -> RunVarToken[T]:
return cls._create(var)


@final
@attr.s(eq=False, hash=False, slots=True, repr=False)
class RunVar(Generic[T], metaclass=Final):
class RunVar(Generic[T]):
"""The run-local variant of a context variable.

:class:`RunVar` objects are similar to context variable objects,
Expand Down
5 changes: 3 additions & 2 deletions trio/_core/_mock_clock.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from .. import _core
from .._abc import Clock
from .._util import Final
from .._util import final
from ._run import GLOBAL_RUN_CONTEXT

################################################################
Expand All @@ -14,7 +14,8 @@
# Prior art:
# https://twistedmatrix.com/documents/current/api/twisted.internet.task.Clock.html
# https://github.com/ztellman/manifold/issues/57
class MockClock(Clock, metaclass=Final):
@final
class MockClock(Clock):
"""A user-controllable clock suitable for writing tests.

Args:
Expand Down
7 changes: 4 additions & 3 deletions trio/_core/_parking_lot.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
import attr

from .. import _core
from .._util import Final
from .._util import final

if TYPE_CHECKING:
from ._run import Task
Expand All @@ -89,7 +89,7 @@
class ParkingLotStatistics:
"""An object containing debugging information for a ParkingLot.

Currently the following fields are defined:
Currently, the following fields are defined:

* ``tasks_waiting`` (int): The number of tasks blocked on this lot's
:meth:`trio.lowlevel.ParkingLot.park` method.
Expand All @@ -99,8 +99,9 @@ class ParkingLotStatistics:
tasks_waiting: int = attr.ib()


@final
@attr.s(eq=False, hash=False, slots=True)
class ParkingLot(metaclass=Final):
class ParkingLot:
"""A fair wait queue with cancellation and requeueing.

This class encapsulates the tricky parts of implementing a wait
Expand Down
23 changes: 10 additions & 13 deletions trio/_core/_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@
from typing import (
TYPE_CHECKING,
Any,
Final,
NoReturn,
Protocol,
TypeVar,
cast,
final,
overload,
)

Expand All @@ -42,7 +42,7 @@

from .. import _core
from .._abc import Clock, Instrument
from .._util import Final, NoPublicConstructor, coroutine_or_error
from .._util import NoPublicConstructor, coroutine_or_error, final
from ._asyncgens import AsyncGenerators
from ._entry_queue import EntryQueue, TrioToken
from ._exceptions import Cancelled, RunFinishedError, TrioInternalError
Expand All @@ -67,15 +67,12 @@
if TYPE_CHECKING:
import contextvars

# An unfortunate name collision here with trio._util.Final
from typing import Final as FinalT

from typing_extensions import Self

DEADLINE_HEAP_MIN_PRUNE_THRESHOLD: FinalT = 1000
DEADLINE_HEAP_MIN_PRUNE_THRESHOLD: Final = 1000

# Passed as a sentinel
_NO_SEND: FinalT = cast("Outcome[Any]", object())
_NO_SEND: Final = cast("Outcome[Any]", object())

FnT = TypeVar("FnT", bound="Callable[..., Any]")
StatusT = TypeVar("StatusT")
Expand All @@ -100,7 +97,7 @@ def _public(fn: FnT) -> FnT:
# variable to True, and registers the Random instance _r for Hypothesis
# to manage for each test case, which together should make Trio's task
# scheduling loop deterministic. We have a test for that, of course.
_ALLOW_DETERMINISTIC_SCHEDULING: FinalT = False
_ALLOW_DETERMINISTIC_SCHEDULING: Final = False
_r = random.Random()


Expand Down Expand Up @@ -145,7 +142,7 @@ def function_with_unique_name_xyzzy() -> NoReturn:
)


CONTEXT_RUN_TB_FRAMES: FinalT = _count_context_run_tb_frames()
CONTEXT_RUN_TB_FRAMES: Final = _count_context_run_tb_frames()


@attr.s(frozen=True, slots=True)
Expand Down Expand Up @@ -473,7 +470,7 @@ def effective_deadline(self) -> float:

@final
@attr.s(eq=False, repr=False, slots=True)
class CancelScope(metaclass=Final):
class CancelScope:
"""A *cancellation scope*: the link between a unit of cancellable
work and Trio's cancellation system.

Expand Down Expand Up @@ -1428,7 +1425,7 @@ class RunContext(threading.local):
task: Task


GLOBAL_RUN_CONTEXT: FinalT = RunContext()
GLOBAL_RUN_CONTEXT: Final = RunContext()


@attr.frozen
Expand Down Expand Up @@ -2398,7 +2395,7 @@ def my_done_callback(run_outcome):

# 24 hours is arbitrary, but it avoids issues like people setting timeouts of
# 10**20 and then getting integer overflows in the underlying system calls.
_MAX_TIMEOUT: FinalT = 24 * 60 * 60
_MAX_TIMEOUT: Final = 24 * 60 * 60


# Weird quirk: this is written as a generator in order to support "guest
Expand Down Expand Up @@ -2656,7 +2653,7 @@ def started(self, value: Any = None) -> None:
pass


TASK_STATUS_IGNORED: FinalT[TaskStatus[Any]] = _TaskStatusIgnored()
TASK_STATUS_IGNORED: Final[TaskStatus[Any]] = _TaskStatusIgnored()


def current_task() -> Task:
Expand Down
7 changes: 4 additions & 3 deletions trio/_core/_unbounded_queue.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from .. import _core
from .._deprecate import deprecated
from .._util import Final
from .._util import final

T = TypeVar("T")

Expand All @@ -18,7 +18,7 @@
class UnboundedQueueStatistics:
"""An object containing debugging information.

Currently the following fields are defined:
Currently, the following fields are defined:

* ``qsize``: The number of items currently in the queue.
* ``tasks_waiting``: The number of tasks blocked on this queue's
Expand All @@ -30,7 +30,8 @@ class UnboundedQueueStatistics:
tasks_waiting: int = attr.ib()


class UnboundedQueue(Generic[T], metaclass=Final):
@final
class UnboundedQueue(Generic[T]):
"""An unbounded queue suitable for certain unusual forms of inter-task
communication.

Expand Down
6 changes: 4 additions & 2 deletions trio/_dtls.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

import trio

from ._util import Final, NoPublicConstructor
from ._util import NoPublicConstructor, final

if TYPE_CHECKING:
from types import TracebackType
Expand Down Expand Up @@ -812,6 +812,7 @@ class DTLSChannelStatistics:
incoming_packets_dropped_in_trio: int


@final
class DTLSChannel(trio.abc.Channel[bytes], metaclass=NoPublicConstructor):
"""A DTLS connection.

Expand Down Expand Up @@ -1154,7 +1155,8 @@ def statistics(self) -> DTLSChannelStatistics:
return DTLSChannelStatistics(self._packets_dropped_in_trio)


class DTLSEndpoint(metaclass=Final):
@final
class DTLSEndpoint:
"""A DTLS endpoint.

A single UDP socket can handle arbitrarily many DTLS connections simultaneously,
Expand Down
4 changes: 2 additions & 2 deletions trio/_highlevel_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import attr

import trio
from trio._util import Final
from trio._util import final

from .abc import AsyncResource, HalfCloseableStream, ReceiveStream, SendStream

Expand Down Expand Up @@ -52,11 +52,11 @@ def _is_halfclosable(stream: SendStream) -> TypeGuard[HalfCloseableStream]:
return hasattr(stream, "send_eof")


@final
@attr.s(eq=False, hash=False)
class StapledStream(
HalfCloseableStream,
Generic[SendStreamT, ReceiveStreamT],
metaclass=Final,
):
"""This class `staples <https://en.wikipedia.org/wiki/Staple_(fastener)>`__
together two unidirectional streams to make single bidirectional stream.
Expand Down
8 changes: 5 additions & 3 deletions trio/_highlevel_socket.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import trio

from . import socket as tsocket
from ._util import ConflictDetector, Final
from ._util import ConflictDetector, final
from .abc import HalfCloseableStream, Listener

if TYPE_CHECKING:
Expand Down Expand Up @@ -42,7 +42,8 @@ def _translate_socket_errors_to_stream_errors() -> Generator[None, None, None]:
raise trio.BrokenResourceError(f"socket connection broken: {exc}") from exc


class SocketStream(HalfCloseableStream, metaclass=Final):
@final
class SocketStream(HalfCloseableStream):
"""An implementation of the :class:`trio.abc.HalfCloseableStream`
interface based on a raw network socket.

Expand Down Expand Up @@ -354,7 +355,8 @@ def getsockopt(self, level: int, option: int, buffersize: int = 0) -> int | byte
pass


class SocketListener(Listener[SocketStream], metaclass=Final):
@final
class SocketListener(Listener[SocketStream]):
"""A :class:`~trio.abc.Listener` that uses a listening socket to accept
incoming connections as :class:`SocketStream` objects.

Expand Down
5 changes: 3 additions & 2 deletions trio/_path.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@

import trio
from trio._file_io import AsyncIOWrapper as _AsyncIOWrapper
from trio._util import Final, async_wraps
from trio._util import async_wraps, final

if TYPE_CHECKING:
from _typeshed import (
Expand Down Expand Up @@ -129,7 +129,7 @@ async def wrapper(cls: type[Path], *args: Any, **kwargs: Any) -> Path: # type:
return classmethod(wrapper)


class AsyncAutoWrapperType(Final):
class AsyncAutoWrapperType(type):
_forwards: type
_wraps: type
_forward_magic: list[str]
Expand Down Expand Up @@ -197,6 +197,7 @@ def generate_iter(cls, attrs: dict[str, object]) -> None:
setattr(cls, attr_name, wrapper)


@final
class Path(metaclass=AsyncAutoWrapperType):
"""A :class:`pathlib.Path` wrapper that executes blocking methods in
:meth:`trio.to_thread.run_sync`.
Expand Down
8 changes: 5 additions & 3 deletions trio/_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from . import _sync
from ._highlevel_generic import aclose_forcefully
from ._util import ConflictDetector, Final
from ._util import ConflictDetector, final
from .abc import Listener, Stream

# General theory of operation:
Expand Down Expand Up @@ -240,7 +240,8 @@ def done(self) -> bool:
_State = _Enum("_State", ["OK", "BROKEN", "CLOSED"])


class SSLStream(Stream, metaclass=Final):
@final
class SSLStream(Stream):
r"""Encrypted communication using SSL/TLS.

:class:`SSLStream` wraps an arbitrary :class:`~trio.abc.Stream`, and
Expand Down Expand Up @@ -888,7 +889,8 @@ async def wait_send_all_might_not_block(self) -> None:
await self.transport_stream.wait_send_all_might_not_block()


class SSLListener(Listener[SSLStream], metaclass=Final):
@final
class SSLListener(Listener[SSLStream]):
"""A :class:`~trio.abc.Listener` for SSL/TLS-encrypted servers.

:class:`SSLListener` wraps around another Listener, and converts
Expand Down
Loading