From c105629d53b922a95dc7c762b22a536d4b29e2ee Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sat, 3 Aug 2024 17:36:50 -0500 Subject: [PATCH 1/3] Use `unsafe_hash` instead of `hash` to avoid attrs warning `unsafe_hash` is an alias for `hash` as of attrs v22.2.0 --- pyproject.toml | 1 + src/trio/_core/_entry_queue.py | 2 +- src/trio/_core/_io_epoll.py | 2 +- src/trio/_core/_local.py | 4 ++-- src/trio/_core/_parking_lot.py | 2 +- src/trio/_core/_run.py | 8 ++++---- src/trio/_core/_tests/test_instrumentation.py | 2 +- src/trio/_highlevel_generic.py | 2 +- src/trio/_sync.py | 4 ++-- src/trio/_tests/test_highlevel_serve_listeners.py | 2 +- src/trio/testing/_sequencer.py | 2 +- 11 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 0e26fea83a..f9e705fc06 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,6 +41,7 @@ dependencies = [ # attrs 20.1.0 adds @frozen # attrs 21.1.0 adds a dataclass transform for type-checkers # attrs 21.3.0 adds `import addrs` + # attrs 22.2.0 adds `unsafe_hash` "attrs >= 23.2.0", "sortedcontainers", "idna", diff --git a/src/trio/_core/_entry_queue.py b/src/trio/_core/_entry_queue.py index 7f1eea8e29..bb9b86dcc3 100644 --- a/src/trio/_core/_entry_queue.py +++ b/src/trio/_core/_entry_queue.py @@ -146,7 +146,7 @@ def run_sync_soon( @final -@attrs.define(eq=False, hash=False) +@attrs.define(eq=False, unsafe_hash=False) class TrioToken(metaclass=NoPublicConstructor): """An opaque object representing a single call to :func:`trio.run`. diff --git a/src/trio/_core/_io_epoll.py b/src/trio/_core/_io_epoll.py index 1f4ae49f7a..f0ceb0d68c 100644 --- a/src/trio/_core/_io_epoll.py +++ b/src/trio/_core/_io_epoll.py @@ -198,7 +198,7 @@ class _EpollStatistics: # wanted to about how epoll works. -@attrs.define(eq=False, hash=False) +@attrs.define(eq=False, unsafe_hash=False) class EpollIOManager: # Using lambda here because otherwise crash on import with gevent monkey patching # See https://github.com/python-trio/trio/issues/2848 diff --git a/src/trio/_core/_local.py b/src/trio/_core/_local.py index dd20776c54..a49982b538 100644 --- a/src/trio/_core/_local.py +++ b/src/trio/_core/_local.py @@ -16,7 +16,7 @@ class _NoValue: ... @final -@attrs.define(eq=False, hash=False) +@attrs.define(eq=False, unsafe_hash=False) class RunVarToken(Generic[T], metaclass=NoPublicConstructor): _var: RunVar[T] previous_value: T | type[_NoValue] = _NoValue @@ -28,7 +28,7 @@ def _empty(cls, var: RunVar[T]) -> RunVarToken[T]: @final -@attrs.define(eq=False, hash=False, repr=False) +@attrs.define(eq=False, unsafe_hash=False, repr=False) class RunVar(Generic[T]): """The run-local variant of a context variable. diff --git a/src/trio/_core/_parking_lot.py b/src/trio/_core/_parking_lot.py index 340c62508a..58cad7bd44 100644 --- a/src/trio/_core/_parking_lot.py +++ b/src/trio/_core/_parking_lot.py @@ -101,7 +101,7 @@ class ParkingLotStatistics: @final -@attrs.define(eq=False, hash=False) +@attrs.define(eq=False, unsafe_hash=False) class ParkingLot: """A fair wait queue with cancellation and requeueing. diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index 5453c3602e..b141b8f4c2 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -845,7 +845,7 @@ def started(self, value: StatusT_contra | None = None) -> None: # This code needs to be read alongside the code from Nursery.start to make # sense. -@attrs.define(eq=False, hash=False, repr=False, slots=False) +@attrs.define(eq=False, unsafe_hash=False, repr=False, slots=False) class _TaskStatus(TaskStatus[StatusT]): _old_nursery: Nursery _new_nursery: Nursery @@ -1289,7 +1289,7 @@ def __del__(self) -> None: @final -@attrs.define(eq=False, hash=False, repr=False) +@attrs.define(eq=False, unsafe_hash=False, repr=False) class Task(metaclass=NoPublicConstructor): _parent_nursery: Nursery | None coro: Coroutine[Any, Outcome[object], Any] @@ -1532,7 +1532,7 @@ class RunStatistics: # worker thread. -@attrs.define(eq=False, hash=False) +@attrs.define(eq=False, unsafe_hash=False) class GuestState: runner: Runner run_sync_soon_threadsafe: Callable[[Callable[[], object]], object] @@ -1582,7 +1582,7 @@ def in_main_thread() -> None: start_thread_soon(get_events, deliver) -@attrs.define(eq=False, hash=False) +@attrs.define(eq=False, unsafe_hash=False) class Runner: clock: Clock instruments: Instruments diff --git a/src/trio/_core/_tests/test_instrumentation.py b/src/trio/_core/_tests/test_instrumentation.py index 32335ae7fa..0099d98b34 100644 --- a/src/trio/_core/_tests/test_instrumentation.py +++ b/src/trio/_core/_tests/test_instrumentation.py @@ -12,7 +12,7 @@ from ...lowlevel import Task -@attrs.define(eq=False, hash=False, slots=False) +@attrs.define(eq=False, unsafe_hash=False, slots=False) class TaskRecorder(_abc.Instrument): record: list[tuple[str, Task | None]] = attrs.Factory(list) diff --git a/src/trio/_highlevel_generic.py b/src/trio/_highlevel_generic.py index 88a86318a3..ee63459126 100644 --- a/src/trio/_highlevel_generic.py +++ b/src/trio/_highlevel_generic.py @@ -53,7 +53,7 @@ def _is_halfclosable(stream: SendStream) -> TypeGuard[HalfCloseableStream]: @final -@attrs.define(eq=False, hash=False, slots=False) +@attrs.define(eq=False, unsafe_hash=False, slots=False) class StapledStream( HalfCloseableStream, Generic[SendStreamT, ReceiveStreamT], diff --git a/src/trio/_sync.py b/src/trio/_sync.py index 6e62eceeff..e8d7929ccc 100644 --- a/src/trio/_sync.py +++ b/src/trio/_sync.py @@ -33,7 +33,7 @@ class EventStatistics: @final -@attrs.define(repr=False, eq=False, hash=False) +@attrs.define(repr=False, eq=False, unsafe_hash=False) class Event: """A waitable boolean value useful for inter-task synchronization, inspired by :class:`threading.Event`. @@ -538,7 +538,7 @@ class LockStatistics: tasks_waiting: int -@attrs.define(eq=False, hash=False, repr=False, slots=False) +@attrs.define(eq=False, unsafe_hash=False, repr=False, slots=False) class _LockImpl(AsyncContextManagerMixin): _lot: ParkingLot = attrs.field(factory=ParkingLot, init=False) _owner: Task | None = attrs.field(default=None, init=False) diff --git a/src/trio/_tests/test_highlevel_serve_listeners.py b/src/trio/_tests/test_highlevel_serve_listeners.py index 1ce886eddb..d154a9a81a 100644 --- a/src/trio/_tests/test_highlevel_serve_listeners.py +++ b/src/trio/_tests/test_highlevel_serve_listeners.py @@ -29,7 +29,7 @@ StapledMemoryStream = StapledStream[MemorySendStream, MemoryReceiveStream] -@attrs.define(hash=False, eq=False, slots=False) +@attrs.define(unsafe_hash=False, eq=False, slots=False) class MemoryListener(trio.abc.Listener[StapledMemoryStream]): closed: bool = False accepted_streams: list[trio.abc.Stream] = attrs.Factory(list) diff --git a/src/trio/testing/_sequencer.py b/src/trio/testing/_sequencer.py index 2bade1b315..4a2c767e37 100644 --- a/src/trio/testing/_sequencer.py +++ b/src/trio/testing/_sequencer.py @@ -13,7 +13,7 @@ @_util.final -@attrs.define(eq=False, hash=False, slots=False) +@attrs.define(eq=False, unsafe_hash=False, slots=False) class Sequencer: """A convenience class for forcing code in different tasks to run in an explicit linear order. From 1be1df8e128fecd2302e19d2f4885d7a6885908c Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sun, 4 Aug 2024 09:49:58 +0900 Subject: [PATCH 2/3] PR feedback --- newsfragments/3053.bugfix.rst | 1 + pyproject.toml | 3 +-- src/trio/_core/_entry_queue.py | 2 +- src/trio/_core/_io_epoll.py | 2 +- src/trio/_core/_local.py | 4 ++-- src/trio/_core/_parking_lot.py | 2 +- src/trio/_core/_run.py | 8 ++++---- src/trio/_core/_tests/test_instrumentation.py | 2 +- src/trio/_highlevel_generic.py | 2 +- src/trio/_sync.py | 4 ++-- src/trio/_tests/test_highlevel_serve_listeners.py | 2 +- src/trio/testing/_sequencer.py | 2 +- test-requirements.txt | 2 +- 13 files changed, 18 insertions(+), 18 deletions(-) create mode 100644 newsfragments/3053.bugfix.rst diff --git a/newsfragments/3053.bugfix.rst b/newsfragments/3053.bugfix.rst new file mode 100644 index 0000000000..59eca24abe --- /dev/null +++ b/newsfragments/3053.bugfix.rst @@ -0,0 +1 @@ +Switched ``attrs`` usage off of ``hash``, which is now deprecated. \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index f9e705fc06..9bb0919d54 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -40,8 +40,7 @@ dependencies = [ # attrs 19.2.0 adds `eq` option to decorators # attrs 20.1.0 adds @frozen # attrs 21.1.0 adds a dataclass transform for type-checkers - # attrs 21.3.0 adds `import addrs` - # attrs 22.2.0 adds `unsafe_hash` + # attrs 21.3.0 adds `import attrs` "attrs >= 23.2.0", "sortedcontainers", "idna", diff --git a/src/trio/_core/_entry_queue.py b/src/trio/_core/_entry_queue.py index bb9b86dcc3..8305cd1629 100644 --- a/src/trio/_core/_entry_queue.py +++ b/src/trio/_core/_entry_queue.py @@ -146,7 +146,7 @@ def run_sync_soon( @final -@attrs.define(eq=False, unsafe_hash=False) +@attrs.define(eq=False) class TrioToken(metaclass=NoPublicConstructor): """An opaque object representing a single call to :func:`trio.run`. diff --git a/src/trio/_core/_io_epoll.py b/src/trio/_core/_io_epoll.py index f0ceb0d68c..29b378a014 100644 --- a/src/trio/_core/_io_epoll.py +++ b/src/trio/_core/_io_epoll.py @@ -198,7 +198,7 @@ class _EpollStatistics: # wanted to about how epoll works. -@attrs.define(eq=False, unsafe_hash=False) +@attrs.define(eq=False) class EpollIOManager: # Using lambda here because otherwise crash on import with gevent monkey patching # See https://github.com/python-trio/trio/issues/2848 diff --git a/src/trio/_core/_local.py b/src/trio/_core/_local.py index a49982b538..53cbfc135e 100644 --- a/src/trio/_core/_local.py +++ b/src/trio/_core/_local.py @@ -16,7 +16,7 @@ class _NoValue: ... @final -@attrs.define(eq=False, unsafe_hash=False) +@attrs.define(eq=False) class RunVarToken(Generic[T], metaclass=NoPublicConstructor): _var: RunVar[T] previous_value: T | type[_NoValue] = _NoValue @@ -28,7 +28,7 @@ def _empty(cls, var: RunVar[T]) -> RunVarToken[T]: @final -@attrs.define(eq=False, unsafe_hash=False, repr=False) +@attrs.define(eq=False, repr=False) class RunVar(Generic[T]): """The run-local variant of a context variable. diff --git a/src/trio/_core/_parking_lot.py b/src/trio/_core/_parking_lot.py index 58cad7bd44..c01fc2a9d8 100644 --- a/src/trio/_core/_parking_lot.py +++ b/src/trio/_core/_parking_lot.py @@ -101,7 +101,7 @@ class ParkingLotStatistics: @final -@attrs.define(eq=False, unsafe_hash=False) +@attrs.define(eq=False) class ParkingLot: """A fair wait queue with cancellation and requeueing. diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index b141b8f4c2..093d3a202a 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -845,7 +845,7 @@ def started(self, value: StatusT_contra | None = None) -> None: # This code needs to be read alongside the code from Nursery.start to make # sense. -@attrs.define(eq=False, unsafe_hash=False, repr=False, slots=False) +@attrs.define(eq=False, repr=False, slots=False) class _TaskStatus(TaskStatus[StatusT]): _old_nursery: Nursery _new_nursery: Nursery @@ -1289,7 +1289,7 @@ def __del__(self) -> None: @final -@attrs.define(eq=False, unsafe_hash=False, repr=False) +@attrs.define(eq=False, repr=False) class Task(metaclass=NoPublicConstructor): _parent_nursery: Nursery | None coro: Coroutine[Any, Outcome[object], Any] @@ -1532,7 +1532,7 @@ class RunStatistics: # worker thread. -@attrs.define(eq=False, unsafe_hash=False) +@attrs.define(eq=False) class GuestState: runner: Runner run_sync_soon_threadsafe: Callable[[Callable[[], object]], object] @@ -1582,7 +1582,7 @@ def in_main_thread() -> None: start_thread_soon(get_events, deliver) -@attrs.define(eq=False, unsafe_hash=False) +@attrs.define(eq=False) class Runner: clock: Clock instruments: Instruments diff --git a/src/trio/_core/_tests/test_instrumentation.py b/src/trio/_core/_tests/test_instrumentation.py index 0099d98b34..5e6cecae65 100644 --- a/src/trio/_core/_tests/test_instrumentation.py +++ b/src/trio/_core/_tests/test_instrumentation.py @@ -12,7 +12,7 @@ from ...lowlevel import Task -@attrs.define(eq=False, unsafe_hash=False, slots=False) +@attrs.define(eq=False, slots=False) class TaskRecorder(_abc.Instrument): record: list[tuple[str, Task | None]] = attrs.Factory(list) diff --git a/src/trio/_highlevel_generic.py b/src/trio/_highlevel_generic.py index ee63459126..041a684c62 100644 --- a/src/trio/_highlevel_generic.py +++ b/src/trio/_highlevel_generic.py @@ -53,7 +53,7 @@ def _is_halfclosable(stream: SendStream) -> TypeGuard[HalfCloseableStream]: @final -@attrs.define(eq=False, unsafe_hash=False, slots=False) +@attrs.define(eq=False, slots=False) class StapledStream( HalfCloseableStream, Generic[SendStreamT, ReceiveStreamT], diff --git a/src/trio/_sync.py b/src/trio/_sync.py index e8d7929ccc..9f498e82a3 100644 --- a/src/trio/_sync.py +++ b/src/trio/_sync.py @@ -33,7 +33,7 @@ class EventStatistics: @final -@attrs.define(repr=False, eq=False, unsafe_hash=False) +@attrs.define(repr=False, eq=False) class Event: """A waitable boolean value useful for inter-task synchronization, inspired by :class:`threading.Event`. @@ -538,7 +538,7 @@ class LockStatistics: tasks_waiting: int -@attrs.define(eq=False, unsafe_hash=False, repr=False, slots=False) +@attrs.define(eq=False, repr=False, slots=False) class _LockImpl(AsyncContextManagerMixin): _lot: ParkingLot = attrs.field(factory=ParkingLot, init=False) _owner: Task | None = attrs.field(default=None, init=False) diff --git a/src/trio/_tests/test_highlevel_serve_listeners.py b/src/trio/_tests/test_highlevel_serve_listeners.py index d154a9a81a..4909b90d04 100644 --- a/src/trio/_tests/test_highlevel_serve_listeners.py +++ b/src/trio/_tests/test_highlevel_serve_listeners.py @@ -29,7 +29,7 @@ StapledMemoryStream = StapledStream[MemorySendStream, MemoryReceiveStream] -@attrs.define(unsafe_hash=False, eq=False, slots=False) +@attrs.define(eq=False, slots=False) class MemoryListener(trio.abc.Listener[StapledMemoryStream]): closed: bool = False accepted_streams: list[trio.abc.Stream] = attrs.Factory(list) diff --git a/src/trio/testing/_sequencer.py b/src/trio/testing/_sequencer.py index 4a2c767e37..9c01e902f2 100644 --- a/src/trio/testing/_sequencer.py +++ b/src/trio/testing/_sequencer.py @@ -13,7 +13,7 @@ @_util.final -@attrs.define(eq=False, unsafe_hash=False, slots=False) +@attrs.define(eq=False, slots=False) class Sequencer: """A convenience class for forcing code in different tasks to run in an explicit linear order. diff --git a/test-requirements.txt b/test-requirements.txt index 3dec7a570b..4768062864 100644 --- a/test-requirements.txt +++ b/test-requirements.txt @@ -8,7 +8,7 @@ astroid==3.2.2 # via pylint async-generator==1.10 # via -r test-requirements.in -attrs==23.2.0 +attrs==24.1.0 # via # -r test-requirements.in # outcome From ea68af72b8588a2c9d2609035aeaff7b2aff1dc4 Mon Sep 17 00:00:00 2001 From: EXPLOSION Date: Sun, 4 Aug 2024 09:51:01 +0900 Subject: [PATCH 3/3] Address lints --- newsfragments/3053.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/newsfragments/3053.bugfix.rst b/newsfragments/3053.bugfix.rst index 59eca24abe..896d5c9173 100644 --- a/newsfragments/3053.bugfix.rst +++ b/newsfragments/3053.bugfix.rst @@ -1 +1 @@ -Switched ``attrs`` usage off of ``hash``, which is now deprecated. \ No newline at end of file +Switched ``attrs`` usage off of ``hash``, which is now deprecated.