From bdfffb6b585cc66480c35b6e2d696b6e2ea45e76 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 29 Sep 2024 00:57:40 -0500 Subject: [PATCH 01/13] Enable `flake8-annotations` --- pyproject.toml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index ff4aa3460..781fd8249 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -106,6 +106,7 @@ allowed-confusables = ["–"] select = [ "A", # flake8-builtins + "ANN", # flake8-annotations "ASYNC", # flake8-async "B", # flake8-bugbear "C4", # flake8-comprehensions @@ -132,6 +133,8 @@ select = [ ] extend-ignore = [ 'A002', # builtin-argument-shadowing + 'ANN101', # missing-type-self + 'ANN102', # missing-type-cls 'E402', # module-import-not-at-top-of-file (usually OS-specific) 'E501', # line-too-long 'F403', # undefined-local-with-import-star From acdb7b2c424a2f91f8f98e63010e423b2dc49358 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 29 Sep 2024 00:59:37 -0500 Subject: [PATCH 02/13] Autofix `ANN204` --- notes-to-self/afd-lab.py | 6 ++--- notes-to-self/aio-guest-test.py | 8 +++--- notes-to-self/atomic-local.py | 2 +- notes-to-self/blocking-read-hack.py | 2 +- notes-to-self/estimate-task-size.py | 4 +-- notes-to-self/graceful-shutdown-idea.py | 8 +++--- .../how-does-windows-so-reuseaddr-work.py | 4 +-- notes-to-self/loopy.py | 4 +-- notes-to-self/lots-of-tasks.py | 2 +- notes-to-self/measure-listen-backlog.py | 2 +- notes-to-self/ntp-example.py | 2 +- notes-to-self/print-task-tree.py | 8 +++--- notes-to-self/proxy-benchmarks.py | 26 +++++++++---------- notes-to-self/reopen-pipe.py | 4 +-- notes-to-self/schedule-timing.py | 6 ++--- notes-to-self/socket-scaling.py | 4 +-- .../ssl-close-notify/ssl-close-notify.py | 2 +- notes-to-self/ssl-handshake/ssl-handshake.py | 8 +++--- notes-to-self/thread-closure-bug-demo.py | 2 +- notes-to-self/thread-dispatch-bench.py | 4 +-- notes-to-self/time-wait.py | 4 +-- notes-to-self/trace.py | 26 +++++++++---------- notes-to-self/trivial-err.py | 11 ++++---- notes-to-self/trivial.py | 2 +- notes-to-self/wakeup-fd-racer.py | 6 ++--- notes-to-self/win-waitable-timer.py | 4 +-- src/trio/_channel.py | 2 +- src/trio/_core/_instrumentation.py | 2 +- src/trio/_core/_mock_clock.py | 2 +- src/trio/_core/_run.py | 2 +- src/trio/_dtls.py | 2 +- src/trio/_highlevel_socket.py | 4 +-- src/trio/_repl.py | 2 +- src/trio/_socket.py | 4 +-- src/trio/_sync.py | 6 ++--- src/trio/testing/_check_streams.py | 2 +- src/trio/testing/_fake_net.py | 2 +- src/trio/testing/_memory_streams.py | 8 +++--- src/trio/testing/_raises_group.py | 14 +++++----- 39 files changed, 107 insertions(+), 106 deletions(-) diff --git a/notes-to-self/afd-lab.py b/notes-to-self/afd-lab.py index a95eb8bfd..1a52ff17f 100644 --- a/notes-to-self/afd-lab.py +++ b/notes-to-self/afd-lab.py @@ -99,7 +99,7 @@ class AFDLab: - def __init__(self): + def __init__(self) -> None: self._afd = _afd_helper_handle() trio.lowlevel.register_with_iocp(self._afd) @@ -141,7 +141,7 @@ async def afd_poll(self, sock, flags, *, exclusive=0): return out_flags -def fill_socket(sock): +def fill_socket(sock) -> None: try: while True: sock.send(b"x" * 65536) @@ -149,7 +149,7 @@ def fill_socket(sock): pass -async def main(): +async def main() -> None: afdlab = AFDLab() a, b = socket.socketpair() diff --git a/notes-to-self/aio-guest-test.py b/notes-to-self/aio-guest-test.py index 3c607d028..4995fafec 100644 --- a/notes-to-self/aio-guest-test.py +++ b/notes-to-self/aio-guest-test.py @@ -3,12 +3,12 @@ import trio -async def aio_main(): +async def aio_main() -> None: loop = asyncio.get_running_loop() trio_done_fut = loop.create_future() - def trio_done_callback(main_outcome): + def trio_done_callback(main_outcome) -> None: print(f"trio_main finished: {main_outcome!r}") trio_done_fut.set_result(main_outcome) @@ -21,7 +21,7 @@ def trio_done_callback(main_outcome): (await trio_done_fut).unwrap() -async def trio_main(): +async def trio_main() -> None: print("trio_main!") to_trio, from_aio = trio.open_memory_channel(float("inf")) @@ -40,7 +40,7 @@ async def trio_main(): del _task_ref -async def aio_pingpong(from_trio, to_trio): +async def aio_pingpong(from_trio, to_trio) -> None: print("aio_pingpong!") while True: diff --git a/notes-to-self/atomic-local.py b/notes-to-self/atomic-local.py index 643bc16c6..b0db7ed2b 100644 --- a/notes-to-self/atomic-local.py +++ b/notes-to-self/atomic-local.py @@ -4,7 +4,7 @@ sentinel = "_unique_name" -def f(): +def f() -> None: print(locals()) diff --git a/notes-to-self/blocking-read-hack.py b/notes-to-self/blocking-read-hack.py index 688f10305..a5d486123 100644 --- a/notes-to-self/blocking-read-hack.py +++ b/notes-to-self/blocking-read-hack.py @@ -19,7 +19,7 @@ async def blocking_read_with_timeout( print("reading from fd", fd) cancel_requested = False - async def kill_it_after_timeout(new_fd): + async def kill_it_after_timeout(new_fd) -> None: print("sleeping") await trio.sleep(timeout) print("breaking the fd") diff --git a/notes-to-self/estimate-task-size.py b/notes-to-self/estimate-task-size.py index 0010c7a2b..7a618af7d 100644 --- a/notes-to-self/estimate-task-size.py +++ b/notes-to-self/estimate-task-size.py @@ -9,7 +9,7 @@ HIGH = 10000 -async def tinytask(): +async def tinytask() -> None: await trio.sleep_forever() @@ -22,7 +22,7 @@ async def measure(count): return resource.getrusage(resource.RUSAGE_SELF) -async def main(): +async def main() -> None: low_usage = await measure(LOW) high_usage = await measure(HIGH + LOW) diff --git a/notes-to-self/graceful-shutdown-idea.py b/notes-to-self/graceful-shutdown-idea.py index 9497af972..36e9178ad 100644 --- a/notes-to-self/graceful-shutdown-idea.py +++ b/notes-to-self/graceful-shutdown-idea.py @@ -5,11 +5,11 @@ class GracefulShutdownManager: - def __init__(self): + def __init__(self) -> None: self._shutting_down = False self._cancel_scopes = set() - def start_shutdown(self): + def start_shutdown(self) -> None: self._shutting_down = True for cancel_scope in self._cancel_scopes: cancel_scope.cancel() @@ -32,7 +32,7 @@ def shutting_down(self): # When doing operations that might block for an indefinite about of time and # that should be aborted when a graceful shutdown starts, wrap them in 'with # gsm.cancel_on_graceful_shutdown()'. -async def stream_handler(stream): +async def stream_handler(stream) -> None: while True: with gsm.cancel_on_graceful_shutdown(): data = await stream.receive_some() @@ -42,7 +42,7 @@ async def stream_handler(stream): # To trigger the shutdown: -async def listen_for_shutdown_signals(): +async def listen_for_shutdown_signals() -> None: with trio.open_signal_receiver(signal.SIGINT, signal.SIGTERM) as signal_aiter: async for _sig in signal_aiter: gsm.start_shutdown() diff --git a/notes-to-self/how-does-windows-so-reuseaddr-work.py b/notes-to-self/how-does-windows-so-reuseaddr-work.py index f87e957ad..cb6264844 100644 --- a/notes-to-self/how-does-windows-so-reuseaddr-work.py +++ b/notes-to-self/how-does-windows-so-reuseaddr-work.py @@ -20,7 +20,7 @@ def sock(mode): return s -def bind(sock, bind_type): +def bind(sock, bind_type) -> None: if bind_type == "wildcard": sock.bind(("0.0.0.0", 12345)) elif bind_type == "specific": @@ -29,7 +29,7 @@ def bind(sock, bind_type): raise AssertionError() -def table_entry(mode1, bind_type1, mode2, bind_type2): +def table_entry(mode1, bind_type1, mode2, bind_type2) -> str: with sock(mode1) as sock1: bind(sock1, bind_type1) try: diff --git a/notes-to-self/loopy.py b/notes-to-self/loopy.py index 99f6e050b..e6065bbf7 100644 --- a/notes-to-self/loopy.py +++ b/notes-to-self/loopy.py @@ -3,7 +3,7 @@ import trio -async def loopy(): +async def loopy() -> None: try: while True: # synchronous sleep to avoid maxing out CPU @@ -13,7 +13,7 @@ async def loopy(): print("KI!") -async def main(): +async def main() -> None: async with trio.open_nursery() as nursery: nursery.start_soon(loopy) nursery.start_soon(loopy) diff --git a/notes-to-self/lots-of-tasks.py b/notes-to-self/lots-of-tasks.py index 048c69a7e..d83617552 100644 --- a/notes-to-self/lots-of-tasks.py +++ b/notes-to-self/lots-of-tasks.py @@ -6,7 +6,7 @@ COUNT = int(COUNT_STR) -async def main(): +async def main() -> None: async with trio.open_nursery() as nursery: for _ in range(COUNT): nursery.start_soon(trio.sleep, 1) diff --git a/notes-to-self/measure-listen-backlog.py b/notes-to-self/measure-listen-backlog.py index b7253b86c..7704ee7d4 100644 --- a/notes-to-self/measure-listen-backlog.py +++ b/notes-to-self/measure-listen-backlog.py @@ -1,7 +1,7 @@ import trio -async def run_test(nominal_backlog): +async def run_test(nominal_backlog) -> None: print("--\nnominal:", nominal_backlog) listen_sock = trio.socket.socket() diff --git a/notes-to-self/ntp-example.py b/notes-to-self/ntp-example.py index 2bb9f80fb..79b8cd0a5 100644 --- a/notes-to-self/ntp-example.py +++ b/notes-to-self/ntp-example.py @@ -53,7 +53,7 @@ def extract_transmit_timestamp(ntp_packet): return base_time + offset -async def main(): +async def main() -> None: print("Our clock currently reads (in UTC):", datetime.datetime.utcnow()) # Look up some random NTP servers. diff --git a/notes-to-self/print-task-tree.py b/notes-to-self/print-task-tree.py index 54b97ec01..5f9c535b0 100644 --- a/notes-to-self/print-task-tree.py +++ b/notes-to-self/print-task-tree.py @@ -78,7 +78,7 @@ def task_tree_lines(task=None): return _render_subtree(task.name, rendered_children) -def print_task_tree(task=None): +def print_task_tree(task=None) -> None: for line in task_tree_lines(task): print(line) @@ -86,20 +86,20 @@ def print_task_tree(task=None): ################################################################ -async def child2(): +async def child2() -> None: async with trio.open_nursery() as nursery: nursery.start_soon(trio.sleep_forever) nursery.start_soon(trio.sleep_forever) -async def child1(): +async def child1() -> None: async with trio.open_nursery() as nursery: nursery.start_soon(child2) nursery.start_soon(child2) nursery.start_soon(trio.sleep_forever) -async def main(): +async def main() -> None: async with trio.open_nursery() as nursery0: nursery0.start_soon(child1) async with trio.open_nursery() as nursery1: diff --git a/notes-to-self/proxy-benchmarks.py b/notes-to-self/proxy-benchmarks.py index 830327cf4..85d7db1c0 100644 --- a/notes-to-self/proxy-benchmarks.py +++ b/notes-to-self/proxy-benchmarks.py @@ -8,7 +8,7 @@ class Proxy1: strategy = "__getattr__" works_for = "any attr" - def __init__(self, wrapped): + def __init__(self, wrapped) -> None: self._wrapped = wrapped def __getattr__(self, name): @@ -24,11 +24,11 @@ class Proxy2: strategy = "generated methods (getattr + closure)" works_for = "methods" - def __init__(self, wrapped): + def __init__(self, wrapped) -> None: self._wrapped = wrapped -def add_wrapper(cls, method): +def add_wrapper(cls, method) -> None: def wrapper(self, *args, **kwargs): return getattr(self._wrapped, method)(*args, **kwargs) @@ -45,11 +45,11 @@ class Proxy3: strategy = "generated methods (exec)" works_for = "methods" - def __init__(self, wrapped): + def __init__(self, wrapped) -> None: self._wrapped = wrapped -def add_wrapper(cls, method): +def add_wrapper(cls, method) -> None: code = textwrap.dedent( f""" def wrapper(self, *args, **kwargs): @@ -71,18 +71,18 @@ class Proxy4: strategy = "generated properties (getattr + closure)" works_for = "any attr" - def __init__(self, wrapped): + def __init__(self, wrapped) -> None: self._wrapped = wrapped -def add_wrapper(cls, attr): +def add_wrapper(cls, attr) -> None: def getter(self): return getattr(self._wrapped, attr) - def setter(self, newval): + def setter(self, newval) -> None: setattr(self._wrapped, attr, newval) - def deleter(self): + def deleter(self) -> None: delattr(self._wrapped, attr) setattr(cls, attr, property(getter, setter, deleter)) @@ -98,11 +98,11 @@ class Proxy5: strategy = "generated properties (exec)" works_for = "any attr" - def __init__(self, wrapped): + def __init__(self, wrapped) -> None: self._wrapped = wrapped -def add_wrapper(cls, attr): +def add_wrapper(cls, attr) -> None: code = textwrap.dedent( f""" def getter(self): @@ -131,7 +131,7 @@ class Proxy6: strategy = "copy attrs from wrappee to wrapper" works_for = "methods + constant attrs" - def __init__(self, wrapper): + def __init__(self, wrapper) -> None: self._wrapper = wrapper for method in methods: @@ -143,7 +143,7 @@ def __init__(self, wrapper): classes = [Proxy1, Proxy2, Proxy3, Proxy4, Proxy5, Proxy6] -def check(cls): +def check(cls) -> None: with open("/etc/passwd") as f: p = cls(f) assert p.fileno() == f.fileno() diff --git a/notes-to-self/reopen-pipe.py b/notes-to-self/reopen-pipe.py index dbccd567d..679c854ef 100644 --- a/notes-to-self/reopen-pipe.py +++ b/notes-to-self/reopen-pipe.py @@ -4,7 +4,7 @@ import time -def check_reopen(r1, w): +def check_reopen(r1, w) -> None: try: print("Reopening read end") r2 = os.open(f"/proc/self/fd/{r1}", os.O_RDONLY) @@ -34,7 +34,7 @@ def check_reopen(r1, w): print("r2 definitely seems to be in non-blocking mode") # Check that r1 is really truly still in blocking mode - def sleep_then_write(): + def sleep_then_write() -> None: time.sleep(1) os.write(w, b"c") diff --git a/notes-to-self/schedule-timing.py b/notes-to-self/schedule-timing.py index 11594b7cc..4fa88aeaf 100644 --- a/notes-to-self/schedule-timing.py +++ b/notes-to-self/schedule-timing.py @@ -6,7 +6,7 @@ RUNNING = True -async def reschedule_loop(depth): +async def reschedule_loop(depth) -> None: if depth == 0: global LOOPS while RUNNING: @@ -17,7 +17,7 @@ async def reschedule_loop(depth): await reschedule_loop(depth - 1) -async def report_loop(): +async def report_loop() -> None: global RUNNING try: while True: @@ -33,7 +33,7 @@ async def report_loop(): RUNNING = False -async def main(): +async def main() -> None: async with trio.open_nursery() as nursery: nursery.start_soon(reschedule_loop, 10) nursery.start_soon(report_loop) diff --git a/notes-to-self/socket-scaling.py b/notes-to-self/socket-scaling.py index bd7e32ef7..3d9199440 100644 --- a/notes-to-self/socket-scaling.py +++ b/notes-to-self/socket-scaling.py @@ -24,10 +24,10 @@ import trio.testing -async def main(): +async def main() -> None: for total in [10, 100, 500, 1_000, 10_000, 20_000, 30_000]: - def pt(desc, *, count=total, item="socket"): + def pt(desc, *, count=total, item="socket") -> None: nonlocal last_time now = time.perf_counter() total_ms = (now - last_time) * 1000 diff --git a/notes-to-self/ssl-close-notify/ssl-close-notify.py b/notes-to-self/ssl-close-notify/ssl-close-notify.py index 7a55b8c99..8df8cbb42 100644 --- a/notes-to-self/ssl-close-notify/ssl-close-notify.py +++ b/notes-to-self/ssl-close-notify/ssl-close-notify.py @@ -23,7 +23,7 @@ client_done = threading.Event() -def server_thread_fn(): +def server_thread_fn() -> None: server_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) server_ctx.load_cert_chain("trio-test-1.pem") server = server_ctx.wrap_socket( diff --git a/notes-to-self/ssl-handshake/ssl-handshake.py b/notes-to-self/ssl-handshake/ssl-handshake.py index 1665ce333..6b73339c8 100644 --- a/notes-to-self/ssl-handshake/ssl-handshake.py +++ b/notes-to-self/ssl-handshake/ssl-handshake.py @@ -9,7 +9,7 @@ server_ctx.load_cert_chain("trio-test-1.pem") -def _ssl_echo_serve_sync(sock): +def _ssl_echo_serve_sync(sock) -> None: try: wrapped = server_ctx.wrap_socket(sock, server_side=True) while True: @@ -37,7 +37,7 @@ def echo_server_connection(): class ManuallyWrappedSocket: - def __init__(self, ctx, sock, **kwargs): + def __init__(self, ctx, sock, **kwargs) -> None: self.incoming = ssl.MemoryBIO() self.outgoing = ssl.MemoryBIO() self.obj = ctx.wrap_bio(self.incoming, self.outgoing, **kwargs) @@ -71,13 +71,13 @@ def _retry(self, fn, *args): # then retry if necessary return ret - def do_handshake(self): + def do_handshake(self) -> None: self._retry(self.obj.do_handshake) def recv(self, bufsize): return self._retry(self.obj.read, bufsize) - def sendall(self, data): + def sendall(self, data) -> None: self._retry(self.obj.write, data) def unwrap(self): diff --git a/notes-to-self/thread-closure-bug-demo.py b/notes-to-self/thread-closure-bug-demo.py index b5da68c33..6985534bd 100644 --- a/notes-to-self/thread-closure-bug-demo.py +++ b/notes-to-self/thread-closure-bug-demo.py @@ -23,7 +23,7 @@ def run_with_slow_tracefunc(fn): return fn() -def outer(): +def outer() -> None: x = 0 # We hide the done variable inside a list, because we want to use it to # communicate between the main thread and the looper thread, and the bug diff --git a/notes-to-self/thread-dispatch-bench.py b/notes-to-self/thread-dispatch-bench.py index 70547a600..427cc0a62 100644 --- a/notes-to-self/thread-dispatch-bench.py +++ b/notes-to-self/thread-dispatch-bench.py @@ -11,13 +11,13 @@ COUNT = 10000 -def worker(in_q, out_q): +def worker(in_q, out_q) -> None: while True: job = in_q.get() out_q.put(job()) -def main(): +def main() -> None: in_q = Queue() out_q = Queue() diff --git a/notes-to-self/time-wait.py b/notes-to-self/time-wait.py index edc1b3917..a2a7dd165 100644 --- a/notes-to-self/time-wait.py +++ b/notes-to-self/time-wait.py @@ -40,7 +40,7 @@ class Options: server = None listen2 = None - def set(self, which, sock): + def set(self, which, sock) -> None: value = getattr(self, which) if value is not None: sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, value) @@ -54,7 +54,7 @@ def describe(self): return "Set/unset: {}".format(", ".join(info)) -def time_wait(options): +def time_wait(options) -> None: print(options.describe()) # Find a pristine port (one we can definitely bind to without diff --git a/notes-to-self/trace.py b/notes-to-self/trace.py index 046412d3a..3294ce431 100644 --- a/notes-to-self/trace.py +++ b/notes-to-self/trace.py @@ -32,20 +32,20 @@ class Trace(trio.abc.Instrument): - def __init__(self, out): + def __init__(self, out) -> None: self.out = out self.out.write("[\n") self.ids = count() self._task_metadata(-1, "I/O manager") - def _write(self, **ev): + def _write(self, **ev) -> None: ev.setdefault("pid", os.getpid()) if ev["ph"] != "M": ev.setdefault("ts", trio.current_time() * 1e6) self.out.write(json.dumps(ev)) self.out.write(",\n") - def _task_metadata(self, tid, name): + def _task_metadata(self, tid, name) -> None: self._write( name="thread_name", ph="M", @@ -59,7 +59,7 @@ def _task_metadata(self, tid, name): args={"sort_index": tid}, ) - def task_spawned(self, task): + def task_spawned(self, task) -> None: self._task_metadata(task._counter, task.name) self._write( name="task lifetime", @@ -67,28 +67,28 @@ def task_spawned(self, task): tid=task._counter, ) - def task_exited(self, task): + def task_exited(self, task) -> None: self._write( name="task lifetime", ph="E", tid=task._counter, ) - def before_task_step(self, task): + def before_task_step(self, task) -> None: self._write( name="running", ph="B", tid=task._counter, ) - def after_task_step(self, task): + def after_task_step(self, task) -> None: self._write( name="running", ph="E", tid=task._counter, ) - def task_scheduled(self, task): + def task_scheduled(self, task) -> None: try: waker = trio.lowlevel.current_task() except RuntimeError: @@ -108,14 +108,14 @@ def task_scheduled(self, task): tid=task._counter, ) - def before_io_wait(self, timeout): + def before_io_wait(self, timeout) -> None: self._write( name="I/O wait", ph="B", tid=-1, ) - def after_io_wait(self, timeout): + def after_io_wait(self, timeout) -> None: self._write( name="I/O wait", ph="E", @@ -123,19 +123,19 @@ def after_io_wait(self, timeout): ) -async def child1(): +async def child1() -> None: print(" child1: started! sleeping now...") await trio.sleep(1) print(" child1: exiting!") -async def child2(): +async def child2() -> None: print(" child2: started! sleeping now...") await trio.sleep(1) print(" child2: exiting!") -async def parent(): +async def parent() -> None: print("parent: started!") async with trio.open_nursery() as nursery: print("parent: spawning child1...") diff --git a/notes-to-self/trivial-err.py b/notes-to-self/trivial-err.py index 6c32617c7..1b0b7adde 100644 --- a/notes-to-self/trivial-err.py +++ b/notes-to-self/trivial-err.py @@ -1,29 +1,30 @@ import sys +from typing import NoReturn import trio sys.stderr = sys.stdout -async def child1(): +async def child1() -> NoReturn: raise ValueError -async def child2(): +async def child2() -> None: async with trio.open_nursery() as nursery: nursery.start_soon(grandchild1) nursery.start_soon(grandchild2) -async def grandchild1(): +async def grandchild1() -> NoReturn: raise KeyError -async def grandchild2(): +async def grandchild2() -> NoReturn: raise NameError("Bob") -async def main(): +async def main() -> None: async with trio.open_nursery() as nursery: nursery.start_soon(child1) nursery.start_soon(child2) diff --git a/notes-to-self/trivial.py b/notes-to-self/trivial.py index 405d92daf..f02d5a297 100644 --- a/notes-to-self/trivial.py +++ b/notes-to-self/trivial.py @@ -1,7 +1,7 @@ import trio -async def foo(): +async def foo() -> int: print("in foo!") return 3 diff --git a/notes-to-self/wakeup-fd-racer.py b/notes-to-self/wakeup-fd-racer.py index 97faa0dfd..a48384942 100644 --- a/notes-to-self/wakeup-fd-racer.py +++ b/notes-to-self/wakeup-fd-racer.py @@ -16,13 +16,13 @@ signal_raise = getattr(_lib, "raise") else: - def signal_raise(signum): + def signal_raise(signum) -> None: # Use pthread_kill to make sure we're actually using the wakeup fd on # Unix signal.pthread_kill(threading.get_ident(), signum) -def raise_SIGINT_soon(): +def raise_SIGINT_soon() -> None: time.sleep(1) signal_raise(signal.SIGINT) # Sending 2 signals becomes reliable, as we'd expect (because we need @@ -41,7 +41,7 @@ def drain(sock): return total -def main(): +def main() -> None: writer, reader = socket.socketpair() writer.setblocking(False) reader.setblocking(False) diff --git a/notes-to-self/win-waitable-timer.py b/notes-to-self/win-waitable-timer.py index b8d9af6ca..848f8229e 100644 --- a/notes-to-self/win-waitable-timer.py +++ b/notes-to-self/win-waitable-timer.py @@ -96,7 +96,7 @@ PROCESS_LEAP_SECOND_INFO_FLAG_ENABLE_SIXTY_SECOND = 1 -def set_leap_seconds_enabled(enabled): +def set_leap_seconds_enabled(enabled) -> None: plsi = ffi.new("PROCESS_LEAP_SECOND_INFO*") if enabled: plsi.Flags = PROCESS_LEAP_SECOND_INFO_FLAG_ENABLE_SIXTY_SECOND @@ -160,7 +160,7 @@ def py_datetime_to_win_filetime(dt): return round((dt - FILETIME_EPOCH).total_seconds() * FILETIME_TICKS_PER_SECOND) -async def main(): +async def main() -> None: h = kernel32.CreateWaitableTimerW(ffi.NULL, True, ffi.NULL) if not h: raise_winerror() diff --git a/src/trio/_channel.py b/src/trio/_channel.py index 8a7dba140..91a8c0811 100644 --- a/src/trio/_channel.py +++ b/src/trio/_channel.py @@ -101,7 +101,7 @@ def __new__( # type: ignore[misc] # "must return a subtype" ) -> tuple[MemorySendChannel[T], MemoryReceiveChannel[T]]: return _open_memory_channel(max_buffer_size) - def __init__(self, max_buffer_size: int | float): # noqa: PYI041 + def __init__(self, max_buffer_size: int | float) -> None: # noqa: PYI041 ... else: diff --git a/src/trio/_core/_instrumentation.py b/src/trio/_core/_instrumentation.py index c1063b0e3..9bcc69bc3 100644 --- a/src/trio/_core/_instrumentation.py +++ b/src/trio/_core/_instrumentation.py @@ -29,7 +29,7 @@ class Instruments(Dict[str, Dict[Instrument, None]]): __slots__ = () - def __init__(self, incoming: Sequence[Instrument]): + def __init__(self, incoming: Sequence[Instrument]) -> None: self["_all"] = {} for instrument in incoming: self.add_instrument(instrument) diff --git a/src/trio/_core/_mock_clock.py b/src/trio/_core/_mock_clock.py index 70c4e58a2..7e85df2f7 100644 --- a/src/trio/_core/_mock_clock.py +++ b/src/trio/_core/_mock_clock.py @@ -63,7 +63,7 @@ class MockClock(Clock): """ - def __init__(self, rate: float = 0.0, autojump_threshold: float = inf): + def __init__(self, rate: float = 0.0, autojump_threshold: float = inf) -> None: # when the real clock said 'real_base', the virtual time was # 'virtual_base', and since then it's advanced at 'rate' virtual # seconds per real second. diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index 5de75e8e6..3d8b9b629 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -1128,7 +1128,7 @@ def __init__( parent_task: Task, cancel_scope: CancelScope, strict_exception_groups: bool, - ): + ) -> None: self._parent_task = parent_task self._strict_exception_groups = strict_exception_groups parent_task._child_nurseries.append(self) diff --git a/src/trio/_dtls.py b/src/trio/_dtls.py index 62b01292a..18b228589 100644 --- a/src/trio/_dtls.py +++ b/src/trio/_dtls.py @@ -669,7 +669,7 @@ def challenge_for( class _Queue(Generic[_T]): - def __init__(self, incoming_packets_buffer: int | float): # noqa: PYI041 + def __init__(self, incoming_packets_buffer: int | float) -> None: # noqa: PYI041 self.s, self.r = trio.open_memory_channel[_T](incoming_packets_buffer) diff --git a/src/trio/_highlevel_socket.py b/src/trio/_highlevel_socket.py index 8d9e76807..c04e66e1b 100644 --- a/src/trio/_highlevel_socket.py +++ b/src/trio/_highlevel_socket.py @@ -68,7 +68,7 @@ class SocketStream(HalfCloseableStream): """ - def __init__(self, socket: SocketType): + def __init__(self, socket: SocketType) -> None: if not isinstance(socket, tsocket.SocketType): raise TypeError("SocketStream requires a Trio socket object") if socket.type != tsocket.SOCK_STREAM: @@ -364,7 +364,7 @@ class SocketListener(Listener[SocketStream]): """ - def __init__(self, socket: SocketType): + def __init__(self, socket: SocketType) -> None: if not isinstance(socket, tsocket.SocketType): raise TypeError("SocketListener requires a Trio socket object") if socket.type != tsocket.SOCK_STREAM: diff --git a/src/trio/_repl.py b/src/trio/_repl.py index 73f050140..f9efcc001 100644 --- a/src/trio/_repl.py +++ b/src/trio/_repl.py @@ -22,7 +22,7 @@ class TrioInteractiveConsole(InteractiveConsole): # we make the type more specific on our subclass locals: dict[str, object] - def __init__(self, repl_locals: dict[str, object] | None = None): + def __init__(self, repl_locals: dict[str, object] | None = None) -> None: super().__init__(locals=repl_locals) self.compile.compiler.flags |= ast.PyCF_ALLOW_TOP_LEVEL_AWAIT diff --git a/src/trio/_socket.py b/src/trio/_socket.py index 6dbe9c0c4..42d622951 100644 --- a/src/trio/_socket.py +++ b/src/trio/_socket.py @@ -64,7 +64,7 @@ class _try_sync: def __init__( self, blocking_exc_override: Callable[[BaseException], bool] | None = None, - ): + ) -> None: self._blocking_exc_override = blocking_exc_override def _is_blocking_io_error(self, exc: BaseException) -> bool: @@ -781,7 +781,7 @@ async def sendmsg( class _SocketType(SocketType): - def __init__(self, sock: _stdlib_socket.socket): + def __init__(self, sock: _stdlib_socket.socket) -> None: if type(sock) is not _stdlib_socket.socket: # For example, ssl.SSLSocket subclasses socket.socket, but we # certainly don't want to blindly wrap one of those. diff --git a/src/trio/_sync.py b/src/trio/_sync.py index 698716ea3..60fd18302 100644 --- a/src/trio/_sync.py +++ b/src/trio/_sync.py @@ -213,7 +213,7 @@ class CapacityLimiter(AsyncContextManagerMixin): """ # total_tokens would ideally be int|Literal[math.inf] - but that's not valid typing - def __init__(self, total_tokens: int | float): # noqa: PYI041 + def __init__(self, total_tokens: int | float) -> None: # noqa: PYI041 self._lot = ParkingLot() self._borrowers: set[Task | object] = set() # Maps tasks attempting to acquire -> borrower, to handle on-behalf-of @@ -426,7 +426,7 @@ class Semaphore(AsyncContextManagerMixin): """ - def __init__(self, initial_value: int, *, max_value: int | None = None): + def __init__(self, initial_value: int, *, max_value: int | None = None) -> None: if not isinstance(initial_value, int): raise TypeError("initial_value must be an int") if initial_value < 0: @@ -740,7 +740,7 @@ class Condition(AsyncContextManagerMixin): """ - def __init__(self, lock: Lock | None = None): + def __init__(self, lock: Lock | None = None) -> None: if lock is None: lock = Lock() if type(lock) is not Lock: diff --git a/src/trio/testing/_check_streams.py b/src/trio/testing/_check_streams.py index 335c9c1ea..4339163ee 100644 --- a/src/trio/testing/_check_streams.py +++ b/src/trio/testing/_check_streams.py @@ -314,7 +314,7 @@ async def expect_cancelled( # receive stream causes it to wake up. async with _ForceCloseBoth(await stream_maker()) as (s, r): - async def receive_expecting_closed(): + async def receive_expecting_closed() -> None: with _assert_raises(_core.ClosedResourceError): await r.receive_some(10) diff --git a/src/trio/testing/_fake_net.py b/src/trio/testing/_fake_net.py index ed0f6980f..20265937d 100644 --- a/src/trio/testing/_fake_net.py +++ b/src/trio/testing/_fake_net.py @@ -210,7 +210,7 @@ def __init__( family: AddressFamily, type: SocketKind, proto: int, - ): + ) -> None: self._fake_net = fake_net if not family: # pragma: no cover diff --git a/src/trio/testing/_memory_streams.py b/src/trio/testing/_memory_streams.py index 26ddde856..4183e321f 100644 --- a/src/trio/testing/_memory_streams.py +++ b/src/trio/testing/_memory_streams.py @@ -113,7 +113,7 @@ def __init__( send_all_hook: AsyncHook | None = None, wait_send_all_might_not_block_hook: AsyncHook | None = None, close_hook: SyncHook | None = None, - ): + ) -> None: self._conflict_detector = _util.ConflictDetector( "another task is using this stream", ) @@ -223,7 +223,7 @@ def __init__( self, receive_some_hook: AsyncHook | None = None, close_hook: SyncHook | None = None, - ): + ) -> None: self._conflict_detector = _util.ConflictDetector( "another task is using this stream", ) @@ -548,7 +548,7 @@ async def receive_some(self, max_bytes: int | None = None) -> bytes | bytearray: class _LockstepSendStream(SendStream): - def __init__(self, lbq: _LockstepByteQueue): + def __init__(self, lbq: _LockstepByteQueue) -> None: self._lbq = lbq def close(self) -> None: @@ -566,7 +566,7 @@ async def wait_send_all_might_not_block(self) -> None: class _LockstepReceiveStream(ReceiveStream): - def __init__(self, lbq: _LockstepByteQueue): + def __init__(self, lbq: _LockstepByteQueue) -> None: self._lbq = lbq def close(self) -> None: diff --git a/src/trio/testing/_raises_group.py b/src/trio/testing/_raises_group.py index 627663ffb..8fa308252 100644 --- a/src/trio/testing/_raises_group.py +++ b/src/trio/testing/_raises_group.py @@ -54,7 +54,7 @@ class _ExceptionInfo(Generic[MatchE]): def __init__( self, excinfo: tuple[type[MatchE], MatchE, types.TracebackType] | None, - ): + ) -> None: self._excinfo = excinfo def fill_unfilled( @@ -176,7 +176,7 @@ def __init__( exception_type: type[MatchE], match: str | Pattern[str] = ..., check: Callable[[MatchE], bool] = ..., - ): ... + ) -> None: ... @overload def __init__( @@ -185,10 +185,10 @@ def __init__( match: str | Pattern[str], # If exception_type is not provided, check() must do any typechecks itself. check: Callable[[BaseException], bool] = ..., - ): ... + ) -> None: ... @overload - def __init__(self, *, check: Callable[[BaseException], bool]): ... + def __init__(self, *, check: Callable[[BaseException], bool]) -> None: ... def __init__( self, @@ -351,7 +351,7 @@ def __init__( flatten_subgroups: bool = False, match: None = None, check: None = None, - ): ... + ) -> None: ... # flatten_subgroups = True also requires no nested RaisesGroup @overload @@ -363,7 +363,7 @@ def __init__( flatten_subgroups: Literal[True], match: str | Pattern[str] | None = None, check: Callable[[BaseExceptionGroup[E]], bool] | None = None, - ): ... + ) -> None: ... @overload def __init__( @@ -374,7 +374,7 @@ def __init__( flatten_subgroups: Literal[False] = False, match: str | Pattern[str] | None = None, check: Callable[[BaseExceptionGroup[E]], bool] | None = None, - ): ... + ) -> None: ... def __init__( self, From c05eaa68dee6ef66d974604997862e3c37ea8434 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 29 Sep 2024 02:23:49 -0500 Subject: [PATCH 03/13] Manually fix remaining new issues --- pyproject.toml | 2 + src/trio/_core/_concat_tb.py | 4 +- src/trio/_core/_instrumentation.py | 6 ++- src/trio/_core/_run.py | 4 +- src/trio/_core/_tests/test_guest_mode.py | 11 +++-- src/trio/_core/_traps.py | 10 +++-- src/trio/_dtls.py | 11 ++--- src/trio/_file_io.py | 7 ++- src/trio/_highlevel_open_tcp_stream.py | 4 +- src/trio/_socket.py | 2 +- src/trio/_ssl.py | 4 +- src/trio/_subprocess_platform/__init__.py | 8 ++-- .../test_highlevel_open_tcp_listeners.py | 6 ++- .../_tests/test_highlevel_open_tcp_stream.py | 12 ++++-- src/trio/_tests/test_highlevel_ssl_helpers.py | 7 ++- src/trio/_tests/test_socket.py | 34 +++++++++------ src/trio/_tests/test_ssl.py | 43 ++++++++++++------- src/trio/_tests/test_subprocess.py | 12 ++++-- src/trio/_tests/test_unix_pipes.py | 6 +-- src/trio/_tests/test_util.py | 20 ++++++--- src/trio/_util.py | 2 +- src/trio/testing/_fake_net.py | 2 +- 22 files changed, 143 insertions(+), 74 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 781fd8249..c54cdd490 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -154,6 +154,8 @@ extend-ignore = [ 'src/trio/lowlevel.py' = ['F401'] 'src/trio/socket.py' = ['F401'] 'src/trio/testing/__init__.py' = ['F401'] +# Don't check annotations in notes-to-self +'notes-to-self/*.py' = ['ANN'] [tool.ruff.lint.isort] combine-as-imports = true diff --git a/src/trio/_core/_concat_tb.py b/src/trio/_core/_concat_tb.py index 2ddaf2e8e..919c303e3 100644 --- a/src/trio/_core/_concat_tb.py +++ b/src/trio/_core/_concat_tb.py @@ -86,7 +86,9 @@ def copy_tb(base_tb: TracebackType, tb_next: TracebackType | None) -> TracebackT 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] + def controller( # type: ignore[no-any-unimported] + operation: tputil.ProxyOperation, + ) -> Any | None: # noqa: ANN401 # Using Any # 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 diff --git a/src/trio/_core/_instrumentation.py b/src/trio/_core/_instrumentation.py index 9bcc69bc3..0139b4dea 100644 --- a/src/trio/_core/_instrumentation.py +++ b/src/trio/_core/_instrumentation.py @@ -86,7 +86,11 @@ def remove_instrument(self, instrument: Instrument) -> None: if not instruments: del self[hookname] - def call(self, hookname: str, *args: Any) -> None: + def call( + self, + hookname: str, + *args: Any, # noqa: ANN401 # Using Any + ) -> None: """Call hookname(*args) on each applicable instrument. You must first check whether there are any instruments installed for diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index 3d8b9b629..b81249a70 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -1282,7 +1282,7 @@ async def start( async_fn: Callable[..., Awaitable[object]], *args: object, name: object = None, - ) -> Any: + ) -> Any: # noqa: ANN401 # Using Any r"""Creates and initializes a child task. Like :meth:`start_soon`, but blocks until the new task has @@ -2819,7 +2819,7 @@ class _TaskStatusIgnored(TaskStatus[Any]): def __repr__(self) -> str: return "TASK_STATUS_IGNORED" - def started(self, value: Any = None) -> None: + def started(self, value: Any = None) -> None: # noqa: ANN401 # Using Any pass diff --git a/src/trio/_core/_tests/test_guest_mode.py b/src/trio/_core/_tests/test_guest_mode.py index 1a8b230e7..a6edbb13f 100644 --- a/src/trio/_core/_tests/test_guest_mode.py +++ b/src/trio/_core/_tests/test_guest_mode.py @@ -52,7 +52,7 @@ def trivial_guest_run( trio_fn: Callable[..., Awaitable[T]], *, in_host_after_start: Callable[[], None] | None = None, - **start_guest_run_kwargs: Any, + **start_guest_run_kwargs: Any, # noqa: ANN401 # Using Any, too diverse ) -> T: todo: queue.Queue[tuple[str, Outcome[T] | Callable[..., object]]] = queue.Queue() @@ -436,7 +436,7 @@ def aiotrio_run( trio_fn: Callable[..., Awaitable[T]], *, pass_not_threadsafe: bool = True, - **start_guest_run_kwargs: Any, + **start_guest_run_kwargs: Any, # noqa: ANN401 # Using Any, too diverse ) -> T: loop = asyncio.new_event_loop() @@ -557,11 +557,14 @@ async def crash_in_worker_thread_io(in_host: InHost) -> None: t = threading.current_thread() old_get_events = trio._core._run.TheIOManager.get_events - def bad_get_events(*args: Any) -> object: + def bad_get_events( + self: trio._core._run.TheIOManager, + timeout: float, + ) -> trio._core._run.EventResult: if threading.current_thread() is not t: raise ValueError("oh no!") else: - return old_get_events(*args) + return old_get_events(self, timeout) m.setattr("trio._core._run.TheIOManager.get_events", bad_get_events) diff --git a/src/trio/_core/_traps.py b/src/trio/_core/_traps.py index 27518406c..9222c2f10 100644 --- a/src/trio/_core/_traps.py +++ b/src/trio/_core/_traps.py @@ -25,7 +25,7 @@ # tracking machinery. Since our traps are public APIs, we make them real async # functions, and then this helper takes care of the actual yield: @types.coroutine -def _async_yield(obj: Any) -> Any: # type: ignore[misc] +def _async_yield(obj: Any) -> Any: # type: ignore[misc] # noqa: ANN401 return (yield obj) @@ -77,7 +77,9 @@ class WaitTaskRescheduled: # Should always return the type a Task "expects", unless you willfully reschedule it # with a bad value. -async def wait_task_rescheduled(abort_func: Callable[[RaiseCancelT], Abort]) -> Any: +async def wait_task_rescheduled( + abort_func: Callable[[RaiseCancelT], Abort], +) -> Any: # noqa: ANN401 # Any used """Put the current task to sleep, with cancellation support. This is the lowest-level API for blocking in Trio. Every time a @@ -187,7 +189,7 @@ class PermanentlyDetachCoroutineObject: async def permanently_detach_coroutine_object( final_outcome: outcome.Outcome[Any], -) -> Any: +) -> Any: # noqa: ANN401 # Any used """Permanently detach the current task from the Trio scheduler. Normally, a Trio task doesn't exit until its coroutine object exits. When @@ -220,7 +222,7 @@ async def permanently_detach_coroutine_object( async def temporarily_detach_coroutine_object( abort_func: Callable[[RaiseCancelT], Abort], -) -> Any: +) -> Any: # noqa: ANN401 # Any used """Temporarily detach the current coroutine object from the Trio scheduler. diff --git a/src/trio/_dtls.py b/src/trio/_dtls.py index 18b228589..decf9bd4a 100644 --- a/src/trio/_dtls.py +++ b/src/trio/_dtls.py @@ -43,6 +43,7 @@ from OpenSSL import SSL # noqa: TCH004 from typing_extensions import Self, TypeAlias, TypeVarTuple, Unpack + from trio._socket import AddressFormat from trio.socket import SocketType PosArgsT = TypeVarTuple("PosArgsT") @@ -572,7 +573,7 @@ def _make_cookie( key: bytes, salt: bytes, tick: int, - address: Any, + address: AddressFormat, client_hello_bits: bytes, ) -> bytes: assert len(salt) == SALT_BYTES @@ -593,7 +594,7 @@ def _make_cookie( def valid_cookie( key: bytes, cookie: bytes, - address: Any, + address: AddressFormat, client_hello_bits: bytes, ) -> bool: if len(cookie) > SALT_BYTES: @@ -622,7 +623,7 @@ def valid_cookie( def challenge_for( key: bytes, - address: Any, + address: AddressFormat, epoch_seqno: int, client_hello_bits: bytes, ) -> bytes: @@ -686,7 +687,7 @@ def _read_loop(read_fn: Callable[[int], bytes]) -> bytes: async def handle_client_hello_untrusted( endpoint: DTLSEndpoint, - address: Any, + address: AddressFormat, packet: bytes, ) -> None: # it's trivial to write a simple function that directly calls this to @@ -864,7 +865,7 @@ class DTLSChannel(trio.abc.Channel[bytes], metaclass=NoPublicConstructor): def __init__( self, endpoint: DTLSEndpoint, - peer_address: Any, + peer_address: AddressFormat, ctx: SSL.Context, ) -> None: self.endpoint = endpoint diff --git a/src/trio/_file_io.py b/src/trio/_file_io.py index 8038ff623..f2d07394c 100644 --- a/src/trio/_file_io.py +++ b/src/trio/_file_io.py @@ -32,6 +32,8 @@ ) from typing_extensions import Literal + from ._sync import CapacityLimiter + # This list is also in the docs, make sure to keep them in sync _FILE_SYNC_ATTRS: set[str] = { "closed", @@ -242,7 +244,10 @@ def __getattr__(self, name: str) -> object: meth = getattr(self._wrapped, name) @async_wraps(self.__class__, self._wrapped.__class__, name) - async def wrapper(*args, **kwargs): + async def wrapper( + *args: Callable[..., T], + **kwargs: object | str | bool | CapacityLimiter | None, + ) -> T: func = partial(meth, *args, **kwargs) return await trio.to_thread.run_sync(func) diff --git a/src/trio/_highlevel_open_tcp_stream.py b/src/trio/_highlevel_open_tcp_stream.py index 1e7f4332d..b7c0468e0 100644 --- a/src/trio/_highlevel_open_tcp_stream.py +++ b/src/trio/_highlevel_open_tcp_stream.py @@ -11,6 +11,8 @@ from collections.abc import Generator from socket import AddressFamily, SocketKind + from trio._socket import AddressFormat + if sys.version_info < (3, 11): from exceptiongroup import BaseExceptionGroup, ExceptionGroup @@ -302,7 +304,7 @@ async def open_tcp_stream( # face of crash or cancellation async def attempt_connect( socket_args: tuple[AddressFamily, SocketKind, int], - sockaddr: Any, + sockaddr: AddressFormat, attempt_failed: trio.Event, ) -> None: nonlocal winning_socket diff --git a/src/trio/_socket.py b/src/trio/_socket.py index 42d622951..30e9071ad 100644 --- a/src/trio/_socket.py +++ b/src/trio/_socket.py @@ -476,7 +476,7 @@ async def _resolve_address_nocp( ipv6_v6only: bool | int, address: AddressFormat, local: bool, -) -> Any: +) -> AddressFormat: # Do some pre-checking (or exit early for non-IP sockets) if family == _stdlib_socket.AF_INET: if not isinstance(address, tuple) or not len(address) == 2: diff --git a/src/trio/_ssl.py b/src/trio/_ssl.py index df1cbc37b..d778a5546 100644 --- a/src/trio/_ssl.py +++ b/src/trio/_ssl.py @@ -4,7 +4,7 @@ import operator as _operator import ssl as _stdlib_ssl from enum import Enum as _Enum -from typing import TYPE_CHECKING, Any, ClassVar, Final as TFinal, Generic, TypeVar +from typing import TYPE_CHECKING, ClassVar, Final as TFinal, Generic, TypeVar import trio @@ -413,7 +413,7 @@ def __init__( "version", } - def __getattr__(self, name: str) -> Any: + def __getattr__(self, name: str) -> object: if name in self._forwarded: if name in self._after_handshake and not self._handshook.done: raise NeedHandshakeError(f"call do_handshake() before calling {name!r}") diff --git a/src/trio/_subprocess_platform/__init__.py b/src/trio/_subprocess_platform/__init__.py index d74cd462a..9a5e4d1da 100644 --- a/src/trio/_subprocess_platform/__init__.py +++ b/src/trio/_subprocess_platform/__init__.py @@ -85,11 +85,11 @@ def create_pipe_from_child_output() -> tuple[ClosableReceiveStream, int]: elif os.name == "posix": - def create_pipe_to_child_stdin(): + def create_pipe_to_child_stdin() -> tuple[trio.lowlevel.FdStream, int]: rfd, wfd = os.pipe() return trio.lowlevel.FdStream(wfd), rfd - def create_pipe_from_child_output(): + def create_pipe_from_child_output() -> tuple[trio.lowlevel.FdStream, int]: rfd, wfd = os.pipe() return trio.lowlevel.FdStream(rfd), wfd @@ -106,12 +106,12 @@ def create_pipe_from_child_output(): from .._windows_pipes import PipeReceiveStream, PipeSendStream - def create_pipe_to_child_stdin(): + def create_pipe_to_child_stdin() -> tuple[PipeSendStream, int]: # for stdin, we want the write end (our end) to use overlapped I/O rh, wh = windows_pipe(overlapped=(False, True)) return PipeSendStream(wh), msvcrt.open_osfhandle(rh, os.O_RDONLY) - def create_pipe_from_child_output(): + def create_pipe_from_child_output() -> tuple[PipeReceiveStream, int]: # for stdout/err, it's the read end that's overlapped rh, wh = windows_pipe(overlapped=(True, False)) return PipeReceiveStream(rh), msvcrt.open_osfhandle(wh, 0) diff --git a/src/trio/_tests/test_highlevel_open_tcp_listeners.py b/src/trio/_tests/test_highlevel_open_tcp_listeners.py index 6e2abf112..b041fb4ee 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_listeners.py +++ b/src/trio/_tests/test_highlevel_open_tcp_listeners.py @@ -4,7 +4,7 @@ import socket as stdlib_socket import sys from socket import AddressFamily, SocketKind -from typing import TYPE_CHECKING, Any, Sequence, overload +from typing import TYPE_CHECKING, Sequence, overload import attrs import pytest @@ -28,6 +28,8 @@ if TYPE_CHECKING: from typing_extensions import Buffer + from .._socket import AddressFormat + async def test_open_tcp_listeners_basic() -> None: listeners = await open_tcp_listeners(0) @@ -193,7 +195,7 @@ def setsockopt( ) -> None: pass - async def bind(self, address: Any) -> None: + async def bind(self, address: AddressFormat) -> None: pass def listen(self, /, backlog: int = min(stdlib_socket.SOMAXCONN, 128)) -> None: diff --git a/src/trio/_tests/test_highlevel_open_tcp_stream.py b/src/trio/_tests/test_highlevel_open_tcp_stream.py index 81d2b403b..1f9bd5295 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_stream.py +++ b/src/trio/_tests/test_highlevel_open_tcp_stream.py @@ -3,7 +3,7 @@ import socket import sys from socket import AddressFamily, SocketKind -from typing import TYPE_CHECKING, Any, Sequence +from typing import TYPE_CHECKING import attrs import pytest @@ -19,6 +19,8 @@ from trio.testing import Matcher, RaisesGroup if TYPE_CHECKING: + from collections.abc import Sequence + from trio.testing import MockClock if sys.version_info < (3, 11): @@ -358,7 +360,7 @@ async def run_scenario( # If this is True, we require there to be an exception, and return # (exception, scenario object) expect_error: tuple[type[BaseException], ...] | type[BaseException] = (), - **kwargs: Any, + **kwargs: str | float | None, ) -> tuple[SocketType, Scenario] | tuple[BaseException, Scenario]: supported_families = set() if ipv4_supported: @@ -370,7 +372,11 @@ async def run_scenario( trio.socket.set_custom_socket_factory(scenario) try: - stream = await open_tcp_stream("test.example.com", port, **kwargs) + stream = await open_tcp_stream( + "test.example.com", + port, + **kwargs, # type: ignore[arg-type] + ) assert expect_error == () scenario.check(stream.socket) return (stream.socket, scenario) diff --git a/src/trio/_tests/test_highlevel_ssl_helpers.py b/src/trio/_tests/test_highlevel_ssl_helpers.py index ca23c333c..841232850 100644 --- a/src/trio/_tests/test_highlevel_ssl_helpers.py +++ b/src/trio/_tests/test_highlevel_ssl_helpers.py @@ -1,7 +1,7 @@ from __future__ import annotations from functools import partial -from typing import TYPE_CHECKING, Any, NoReturn +from typing import TYPE_CHECKING, NoReturn import attrs import pytest @@ -66,7 +66,10 @@ async def getaddrinfo( ]: return [(AF_INET, SOCK_STREAM, IPPROTO_TCP, "", self.sockaddr)] - async def getnameinfo(self, *args: Any) -> NoReturn: # pragma: no cover + async def getnameinfo( + self, + *args: tuple[str, int] | tuple[str, int, int, int] | int, + ) -> NoReturn: # pragma: no cover raise NotImplementedError diff --git a/src/trio/_tests/test_socket.py b/src/trio/_tests/test_socket.py index f2c2ee955..a403272b4 100644 --- a/src/trio/_tests/test_socket.py +++ b/src/trio/_tests/test_socket.py @@ -8,17 +8,19 @@ import tempfile from pathlib import Path from socket import AddressFamily, SocketKind -from typing import TYPE_CHECKING, Any, Callable, List, Tuple, Union +from typing import TYPE_CHECKING, Any, List, Tuple, Union import attrs import pytest from .. import _core, socket as tsocket from .._core._tests.tutil import binds_ipv6, creates_ipv6 -from .._socket import _NUMERIC_ONLY, SocketType, _SocketType, _try_sync +from .._socket import _NUMERIC_ONLY, AddressFormat, SocketType, _SocketType, _try_sync from ..testing import assert_checkpoints, wait_all_tasks_blocked if TYPE_CHECKING: + from collections.abc import Callable + from typing_extensions import TypeAlias from .._highlevel_socket import SocketStream @@ -47,7 +49,11 @@ def __init__(self, orig_getaddrinfo: Callable[..., GetAddrInfoResponse]) -> None self.record: list[tuple[Any, ...]] = [] # get a normalized getaddrinfo argument tuple - def _frozenbind(self, *args: Any, **kwargs: Any) -> tuple[Any, ...]: + def _frozenbind( + self, + *args: bytes | str | int | None, + **kwargs: bytes | str | int | None, + ) -> tuple[Any, ...]: sig = inspect.signature(self._orig_getaddrinfo) bound = sig.bind(*args, **kwargs) bound.apply_defaults() @@ -58,12 +64,16 @@ def _frozenbind(self, *args: Any, **kwargs: Any) -> tuple[Any, ...]: def set( self, response: GetAddrInfoResponse | str, - *args: Any, - **kwargs: Any, + *args: bytes | str | int | None, + **kwargs: bytes | str | int | None, ) -> None: self._responses[self._frozenbind(*args, **kwargs)] = response - def getaddrinfo(self, *args: Any, **kwargs: Any) -> GetAddrInfoResponse | str: + def getaddrinfo( + self, + *args: bytes | str | int | None, + **kwargs: bytes | str | int | None, + ) -> GetAddrInfoResponse | str: bound = self._frozenbind(*args, **kwargs) self.record.append(bound) if bound in self._responses: @@ -595,7 +605,7 @@ async def res( | tuple[str, str, int] | tuple[str, str, int, int] ), - ) -> Any: + ) -> AddressFormat: return await sock._resolve_address_nocp( args, local=local, # noqa: B023 # local is not bound in function definition @@ -794,7 +804,7 @@ async def test_SocketType_connect_paths() -> None: # nose -- and then swap it back out again before we hit # wait_socket_writable, which insists on a real socket. class CancelSocket(stdlib_socket.socket): - def connect(self, *args: Any, **kwargs: Any) -> None: + def connect(self, *args: AddressFormat) -> None: # accessing private method only available in _SocketType assert isinstance(sock, _SocketType) @@ -804,7 +814,7 @@ def connect(self, *args: Any, **kwargs: Any) -> None: self.family, self.type, ) - sock._sock.connect(*args, **kwargs) + sock._sock.connect(*args) # If connect *doesn't* raise, then pretend it did raise BlockingIOError # pragma: no cover @@ -851,9 +861,9 @@ async def test_resolve_address_exception_in_connect_closes_socket() -> None: with tsocket.socket() as sock: async def _resolve_address_nocp( - self: Any, - *args: Any, - **kwargs: Any, + self: _SocketType, + *args: AddressFormat, + **kwargs: bool, ) -> None: cancel_scope.cancel() await _core.checkpoint() diff --git a/src/trio/_tests/test_ssl.py b/src/trio/_tests/test_ssl.py index 7197a47cc..575e2a724 100644 --- a/src/trio/_tests/test_ssl.py +++ b/src/trio/_tests/test_ssl.py @@ -11,10 +11,6 @@ from typing import ( TYPE_CHECKING, Any, - AsyncIterator, - Awaitable, - Callable, - Iterator, NoReturn, ) @@ -56,6 +52,13 @@ ) if TYPE_CHECKING: + from collections.abc import ( + AsyncIterator, + Awaitable, + Callable, + Iterator, + ) + from typing_extensions import TypeAlias from trio._core import MockClock @@ -170,8 +173,8 @@ def ssl_echo_serve_sync( # Fixture that gives a raw socket connected to a trio-test-1 echo server # (running in a thread). Useful for testing making connections with different # SSLContexts. -@asynccontextmanager # type: ignore[misc] # decorated contains Any -async def ssl_echo_server_raw(**kwargs: Any) -> AsyncIterator[SocketStream]: +@asynccontextmanager +async def ssl_echo_server_raw(**kwargs: bool) -> AsyncIterator[SocketStream]: a, b = stdlib_socket.socketpair() async with trio.open_nursery() as nursery: # Exiting the 'with a, b' context manager closes the sockets, which @@ -188,10 +191,10 @@ async def ssl_echo_server_raw(**kwargs: Any) -> AsyncIterator[SocketStream]: # Fixture that gives a properly set up SSLStream connected to a trio-test-1 # echo server (running in a thread) -@asynccontextmanager # type: ignore[misc] # decorated contains Any +@asynccontextmanager async def ssl_echo_server( client_ctx: SSLContext, - **kwargs: Any, + **kwargs: bool, ) -> AsyncIterator[SSLStream[Stream]]: async with ssl_echo_server_raw(**kwargs) as sock: yield SSLStream(sock, client_ctx, server_hostname="trio-test-1.example.org") @@ -203,7 +206,10 @@ async def ssl_echo_server( # jakkdl: it seems to implement all the abstract methods (now), so I made it inherit # from Stream for the sake of typechecking. class PyOpenSSLEchoStream(Stream): - def __init__(self, sleeper: None = None) -> None: + def __init__( + self, + sleeper: Callable[[str], Awaitable[None]] | None = None, + ) -> None: ctx = SSL.Context(SSL.SSLv23_METHOD) # TLS 1.3 removes renegotiation support. Which is great for them, but # we still have to support versions before that, and that means we @@ -251,9 +257,10 @@ def __init__(self, sleeper: None = None) -> None: "simultaneous calls to PyOpenSSLEchoStream.receive_some", ) + self.sleeper: Callable[[str], Awaitable[None]] if sleeper is None: - async def no_op_sleeper(_: object) -> None: + async def no_op_sleeper(_: str) -> None: return self.sleeper = no_op_sleeper @@ -386,10 +393,10 @@ async def do_test( await do_test("receive_some", (1,), "receive_some", (1,)) -@contextmanager # type: ignore[misc] # decorated contains Any +@contextmanager def virtual_ssl_echo_server( client_ctx: SSLContext, - **kwargs: Any, + **kwargs: Callable[[str], Awaitable[None]] | None, ) -> Iterator[SSLStream[PyOpenSSLEchoStream]]: fakesock = PyOpenSSLEchoStream(**kwargs) yield SSLStream(fakesock, client_ctx, server_hostname="trio-test-1.example.org") @@ -425,7 +432,10 @@ def ssl_wrap_pair( MemoryStapledStream: TypeAlias = StapledStream[MemorySendStream, MemoryReceiveStream] -def ssl_memory_stream_pair(client_ctx: SSLContext, **kwargs: Any) -> tuple[ +def ssl_memory_stream_pair( + client_ctx: SSLContext, + **kwargs: dict[str, Any] | None, +) -> tuple[ SSLStream[MemoryStapledStream], SSLStream[MemoryStapledStream], ]: @@ -436,7 +446,10 @@ def ssl_memory_stream_pair(client_ctx: SSLContext, **kwargs: Any) -> tuple[ MyStapledStream: TypeAlias = StapledStream[SendStream, ReceiveStream] -def ssl_lockstep_stream_pair(client_ctx: SSLContext, **kwargs: Any) -> tuple[ +def ssl_lockstep_stream_pair( + client_ctx: SSLContext, + **kwargs: dict[str, Any] | None, +) -> tuple[ SSLStream[MyStapledStream], SSLStream[MyStapledStream], ]: @@ -1319,7 +1332,7 @@ async def test_getpeercert(client_ctx: SSLContext) -> None: async def test_SSLListener(client_ctx: SSLContext) -> None: async def setup( - **kwargs: Any, + **kwargs: bool, ) -> tuple[tsocket.SocketType, SSLListener[SocketStream], SSLStream[SocketStream]]: listen_sock = tsocket.socket() await listen_sock.bind(("127.0.0.1", 0)) diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index d65a07614..ba1834d98 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -91,7 +91,10 @@ def got_signal(proc: Process, sig: SignalType) -> bool: @asynccontextmanager # type: ignore[misc] # Any in decorator -async def open_process_then_kill(*args: Any, **kwargs: Any) -> AsyncIterator[Process]: +async def open_process_then_kill( + *args: Any, # noqa: ANN401 # Any used + **kwargs: Any, # noqa: ANN401 +) -> AsyncIterator[Process]: proc = await open_process(*args, **kwargs) try: yield proc @@ -100,8 +103,11 @@ async def open_process_then_kill(*args: Any, **kwargs: Any) -> AsyncIterator[Pro await proc.wait() -@asynccontextmanager # type: ignore[misc] # Any in decorator -async def run_process_in_nursery(*args: Any, **kwargs: Any) -> AsyncIterator[Process]: +@asynccontextmanager +async def run_process_in_nursery( + *args: object, + **kwargs: object, +) -> AsyncIterator[Process]: async with _core.open_nursery() as nursery: kwargs.setdefault("check", False) proc: Process = await nursery.start(partial(run_process, *args, **kwargs)) diff --git a/src/trio/_tests/test_unix_pipes.py b/src/trio/_tests/test_unix_pipes.py index 6f8fa6e02..74914cffa 100644 --- a/src/trio/_tests/test_unix_pipes.py +++ b/src/trio/_tests/test_unix_pipes.py @@ -30,7 +30,7 @@ async def make_pipe() -> tuple[FdStream, FdStream]: return FdStream(w), FdStream(r) -async def make_clogged_pipe(): +async def make_clogged_pipe() -> tuple[FdStream, FdStream]: s, r = await make_pipe() try: while True: @@ -197,7 +197,7 @@ async def expect_closedresourceerror() -> None: orig_wait_readable = _core._run.TheIOManager.wait_readable - async def patched_wait_readable(*args, **kwargs) -> None: + async def patched_wait_readable(*args: object, **kwargs: object) -> None: await orig_wait_readable(*args, **kwargs) await r.aclose() @@ -225,7 +225,7 @@ async def expect_closedresourceerror() -> None: orig_wait_writable = _core._run.TheIOManager.wait_writable - async def patched_wait_writable(*args, **kwargs) -> None: + async def patched_wait_writable(*args: object, **kwargs: object) -> None: await orig_wait_writable(*args, **kwargs) await s.aclose() diff --git a/src/trio/_tests/test_util.py b/src/trio/_tests/test_util.py index 3e62eb622..369acec76 100644 --- a/src/trio/_tests/test_util.py +++ b/src/trio/_tests/test_util.py @@ -1,7 +1,12 @@ +from __future__ import annotations + import signal import sys import types -from typing import Any, TypeVar +from typing import TYPE_CHECKING, TypeVar + +if TYPE_CHECKING: + from collections.abc import AsyncGenerator, Coroutine, Generator import pytest @@ -117,8 +122,10 @@ async def f() -> None: # pragma: no cover if sys.version_info < (3, 11): # not bothering to type this one - @asyncio.coroutine # type: ignore[misc] - def generator_based_coro() -> Any: # pragma: no cover + @asyncio.coroutine + def generator_based_coro() -> ( + Generator[Coroutine[None, None, None], None, None] + ): # pragma: no cover yield from asyncio.sleep(1) with pytest.raises(TypeError) as excinfo: @@ -147,12 +154,13 @@ def generator_based_coro() -> Any: # pragma: no cover assert "appears to be synchronous" in str(excinfo.value) - async def async_gen(_: object) -> Any: # pragma: no cover + async def async_gen( + _: object, + ) -> AsyncGenerator[None, None]: # pragma: no cover yield - # does not give arg-type typing error with pytest.raises(TypeError) as excinfo: - coroutine_or_error(async_gen, [0]) # type: ignore[unused-coroutine] + coroutine_or_error(async_gen, [0]) # type: ignore[arg-type,unused-coroutine] msg = "expected an async function but got an async generator" assert msg in str(excinfo.value) diff --git a/src/trio/_util.py b/src/trio/_util.py index 3af8b5cfd..da44c81c3 100644 --- a/src/trio/_util.py +++ b/src/trio/_util.py @@ -308,7 +308,7 @@ def __init__(self, fn: Callable[..., RetT]) -> None: update_wrapper(self, fn) self._fn = fn - def __call__(self, *args: Any, **kwargs: Any) -> RetT: + def __call__(self, *args: object, **kwargs: object) -> RetT: return self._fn(*args, **kwargs) def __getitem__(self, subscript: object) -> Self: diff --git a/src/trio/testing/_fake_net.py b/src/trio/testing/_fake_net.py index 20265937d..b83ca68da 100644 --- a/src/trio/testing/_fake_net.py +++ b/src/trio/testing/_fake_net.py @@ -313,7 +313,7 @@ async def _sendmsg( buffers: Iterable[Buffer], ancdata: Iterable[tuple[int, int, Buffer]] = (), flags: int = 0, - address: Any | None = None, + address: object | None = None, ) -> int: self._check_closed() From 9a56cb0644852f85d9692e0992d4c38b75f30e56 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 29 Sep 2024 02:36:04 -0500 Subject: [PATCH 04/13] Revert changing `__getattr__` and ignore any usage complaint --- src/trio/_ssl.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trio/_ssl.py b/src/trio/_ssl.py index d778a5546..e5a0cdabd 100644 --- a/src/trio/_ssl.py +++ b/src/trio/_ssl.py @@ -4,7 +4,7 @@ import operator as _operator import ssl as _stdlib_ssl from enum import Enum as _Enum -from typing import TYPE_CHECKING, ClassVar, Final as TFinal, Generic, TypeVar +from typing import TYPE_CHECKING, Any, ClassVar, Final as TFinal, Generic, TypeVar import trio @@ -413,7 +413,7 @@ def __init__( "version", } - def __getattr__(self, name: str) -> object: + def __getattr__(self, name: str) -> Any: # noqa: ANN401 # Any used if name in self._forwarded: if name in self._after_handshake and not self._handshook.done: raise NeedHandshakeError(f"call do_handshake() before calling {name!r}") From a7cdba55c2b1102d7b4b813b3bbdfb15c7bc0b47 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 29 Sep 2024 02:39:44 -0500 Subject: [PATCH 05/13] Use `Any` instead of `object` --- src/trio/_tests/test_subprocess.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index ba1834d98..13d6b4049 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -105,8 +105,8 @@ async def open_process_then_kill( @asynccontextmanager async def run_process_in_nursery( - *args: object, - **kwargs: object, + *args: Any, # noqa: ANN401 # Any used + **kwargs: Any, # noqa: ANN401 ) -> AsyncIterator[Process]: async with _core.open_nursery() as nursery: kwargs.setdefault("check", False) From 3c880fb316d9e8c09a0e681937e6fe4e58c0a20d Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 29 Sep 2024 02:47:38 -0500 Subject: [PATCH 06/13] Restore type ignore for decorated with `Any` --- src/trio/_tests/test_subprocess.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index 13d6b4049..b0742102d 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -90,7 +90,7 @@ def got_signal(proc: Process, sig: SignalType) -> bool: return proc.returncode != 0 -@asynccontextmanager # type: ignore[misc] # Any in decorator +@asynccontextmanager # type: ignore[misc] # Any in decorated async def open_process_then_kill( *args: Any, # noqa: ANN401 # Any used **kwargs: Any, # noqa: ANN401 @@ -103,7 +103,7 @@ async def open_process_then_kill( await proc.wait() -@asynccontextmanager +@asynccontextmanager # type: ignore[misc] # Any in decorated async def run_process_in_nursery( *args: Any, # noqa: ANN401 # Any used **kwargs: Any, # noqa: ANN401 From 76538d8357d94e231c7aa4867b49c7e3a32f3b59 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 29 Sep 2024 03:09:08 -0500 Subject: [PATCH 07/13] Go into even more detail in types after looking at changes --- src/trio/_tests/test_ssl.py | 13 ++++++------- src/trio/_tests/test_subprocess.py | 4 ++-- src/trio/_tests/test_unix_pipes.py | 11 +++++++---- src/trio/testing/_fake_net.py | 4 +++- 4 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/trio/_tests/test_ssl.py b/src/trio/_tests/test_ssl.py index 575e2a724..78a4016a6 100644 --- a/src/trio/_tests/test_ssl.py +++ b/src/trio/_tests/test_ssl.py @@ -10,7 +10,6 @@ from ssl import SSLContext from typing import ( TYPE_CHECKING, - Any, NoReturn, ) @@ -407,8 +406,8 @@ def ssl_wrap_pair( client_transport: T_Stream, server_transport: T_Stream, *, - client_kwargs: dict[str, Any] | None = None, - server_kwargs: dict[str, Any] | None = None, + client_kwargs: dict[str, str | bytes | bool | None] | None = None, + server_kwargs: dict[str, str | bytes | bool | None] | None = None, ) -> tuple[SSLStream[T_Stream], SSLStream[T_Stream]]: if server_kwargs is None: server_kwargs = {} @@ -418,13 +417,13 @@ def ssl_wrap_pair( client_transport, client_ctx, server_hostname="trio-test-1.example.org", - **client_kwargs, + **client_kwargs, # type: ignore[arg-type] ) server_ssl = SSLStream( server_transport, SERVER_CTX, server_side=True, - **server_kwargs, + **server_kwargs, # type: ignore[arg-type] ) return client_ssl, server_ssl @@ -434,7 +433,7 @@ def ssl_wrap_pair( def ssl_memory_stream_pair( client_ctx: SSLContext, - **kwargs: dict[str, Any] | None, + **kwargs: dict[str, str | bytes | bool | None] | None, ) -> tuple[ SSLStream[MemoryStapledStream], SSLStream[MemoryStapledStream], @@ -448,7 +447,7 @@ def ssl_memory_stream_pair( def ssl_lockstep_stream_pair( client_ctx: SSLContext, - **kwargs: dict[str, Any] | None, + **kwargs: dict[str, str | bytes | bool | None] | None, ) -> tuple[ SSLStream[MyStapledStream], SSLStream[MyStapledStream], diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index b0742102d..2908e2294 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -92,7 +92,7 @@ def got_signal(proc: Process, sig: SignalType) -> bool: @asynccontextmanager # type: ignore[misc] # Any in decorated async def open_process_then_kill( - *args: Any, # noqa: ANN401 # Any used + *args: Any, # noqa: ANN401 # Any used, different OS -> different args **kwargs: Any, # noqa: ANN401 ) -> AsyncIterator[Process]: proc = await open_process(*args, **kwargs) @@ -105,7 +105,7 @@ async def open_process_then_kill( @asynccontextmanager # type: ignore[misc] # Any in decorated async def run_process_in_nursery( - *args: Any, # noqa: ANN401 # Any used + *args: Any, # noqa: ANN401 # Any used, different OS -> different args **kwargs: Any, # noqa: ANN401 ) -> AsyncIterator[Process]: async with _core.open_nursery() as nursery: diff --git a/src/trio/_tests/test_unix_pipes.py b/src/trio/_tests/test_unix_pipes.py index 74914cffa..3defdda4e 100644 --- a/src/trio/_tests/test_unix_pipes.py +++ b/src/trio/_tests/test_unix_pipes.py @@ -12,6 +12,9 @@ from .._core._tests.tutil import gc_collect_harder, skip_if_fbsd_pipes_broken from ..testing import check_one_way_stream, wait_all_tasks_blocked +if TYPE_CHECKING: + from .._file_io import _HasFileNo + posix = os.name == "posix" pytestmark = pytest.mark.skipif(not posix, reason="posix only") @@ -197,8 +200,8 @@ async def expect_closedresourceerror() -> None: orig_wait_readable = _core._run.TheIOManager.wait_readable - async def patched_wait_readable(*args: object, **kwargs: object) -> None: - await orig_wait_readable(*args, **kwargs) + async def patched_wait_readable(fd: int | _HasFileNo) -> None: + await orig_wait_readable(fd) await r.aclose() monkeypatch.setattr(_core._run.TheIOManager, "wait_readable", patched_wait_readable) @@ -225,8 +228,8 @@ async def expect_closedresourceerror() -> None: orig_wait_writable = _core._run.TheIOManager.wait_writable - async def patched_wait_writable(*args: object, **kwargs: object) -> None: - await orig_wait_writable(*args, **kwargs) + async def patched_wait_writable(fd: int | _HasFileNo) -> None: + await orig_wait_writable(fd) await s.aclose() monkeypatch.setattr(_core._run.TheIOManager, "wait_writable", patched_wait_writable) diff --git a/src/trio/testing/_fake_net.py b/src/trio/testing/_fake_net.py index b83ca68da..bfe3d0ce3 100644 --- a/src/trio/testing/_fake_net.py +++ b/src/trio/testing/_fake_net.py @@ -36,6 +36,8 @@ from typing_extensions import Buffer, Self, TypeAlias + from trio._socket import AddressFormat + IPAddress: TypeAlias = Union[ipaddress.IPv4Address, ipaddress.IPv6Address] @@ -313,7 +315,7 @@ async def _sendmsg( buffers: Iterable[Buffer], ancdata: Iterable[tuple[int, int, Buffer]] = (), flags: int = 0, - address: object | None = None, + address: AddressFormat | None = None, ) -> int: self._check_closed() From 36ad52236c5168f8ee4c18ef72aaa7ae16b450bb Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Sun, 29 Sep 2024 03:17:48 -0500 Subject: [PATCH 08/13] Patched read and write need to handle `self` argument --- src/trio/_tests/test_unix_pipes.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/trio/_tests/test_unix_pipes.py b/src/trio/_tests/test_unix_pipes.py index 3defdda4e..c850ebefe 100644 --- a/src/trio/_tests/test_unix_pipes.py +++ b/src/trio/_tests/test_unix_pipes.py @@ -200,8 +200,11 @@ async def expect_closedresourceerror() -> None: orig_wait_readable = _core._run.TheIOManager.wait_readable - async def patched_wait_readable(fd: int | _HasFileNo) -> None: - await orig_wait_readable(fd) + async def patched_wait_readable( + self: _core._run.TheIOManager, + fd: int | _HasFileNo, + ) -> None: + await orig_wait_readable(self, fd) await r.aclose() monkeypatch.setattr(_core._run.TheIOManager, "wait_readable", patched_wait_readable) @@ -228,8 +231,11 @@ async def expect_closedresourceerror() -> None: orig_wait_writable = _core._run.TheIOManager.wait_writable - async def patched_wait_writable(fd: int | _HasFileNo) -> None: - await orig_wait_writable(fd) + async def patched_wait_writable( + self: _core._run.TheIOManager, + fd: int | _HasFileNo, + ) -> None: + await orig_wait_writable(self, fd) await s.aclose() monkeypatch.setattr(_core._run.TheIOManager, "wait_writable", patched_wait_writable) From 4be420bd3a341f0dfa2bfb68c8b99d9cefec250a Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Mon, 30 Sep 2024 17:59:51 -0500 Subject: [PATCH 09/13] Remove old comment and specify exactly what issues to ignore in notes-to-self --- pyproject.toml | 2 +- src/trio/_tests/test_util.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index c54cdd490..2db6ab213 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -155,7 +155,7 @@ extend-ignore = [ 'src/trio/socket.py' = ['F401'] 'src/trio/testing/__init__.py' = ['F401'] # Don't check annotations in notes-to-self -'notes-to-self/*.py' = ['ANN'] +'notes-to-self/*.py' = ['ANN001', 'ANN002', 'ANN003', 'ANN201', 'ANN202', 'ANN204'] [tool.ruff.lint.isort] combine-as-imports = true diff --git a/src/trio/_tests/test_util.py b/src/trio/_tests/test_util.py index 369acec76..e48203532 100644 --- a/src/trio/_tests/test_util.py +++ b/src/trio/_tests/test_util.py @@ -121,7 +121,7 @@ async def f() -> None: # pragma: no cover import asyncio if sys.version_info < (3, 11): - # not bothering to type this one + @asyncio.coroutine def generator_based_coro() -> ( Generator[Coroutine[None, None, None], None, None] From c4fccd0250f8d693fd757c04f022ce48e1f0eca2 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Wed, 16 Oct 2024 20:58:09 -0500 Subject: [PATCH 10/13] Address review comments Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com> --- src/trio/_tests/test_highlevel_open_tcp_stream.py | 3 +++ src/trio/_tests/test_ssl.py | 11 ++++++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/trio/_tests/test_highlevel_open_tcp_stream.py b/src/trio/_tests/test_highlevel_open_tcp_stream.py index 1f9bd5295..f05166a28 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_stream.py +++ b/src/trio/_tests/test_highlevel_open_tcp_stream.py @@ -372,6 +372,9 @@ async def run_scenario( trio.socket.set_custom_socket_factory(scenario) try: + # Type ignore is for the fact that there are multiple + # keyword arguments that accept separate types, but + # str | float | None is not the same as str | None and float | None stream = await open_tcp_stream( "test.example.com", port, diff --git a/src/trio/_tests/test_ssl.py b/src/trio/_tests/test_ssl.py index 78a4016a6..3777e8392 100644 --- a/src/trio/_tests/test_ssl.py +++ b/src/trio/_tests/test_ssl.py @@ -10,6 +10,7 @@ from ssl import SSLContext from typing import ( TYPE_CHECKING, + Any, NoReturn, ) @@ -259,7 +260,7 @@ def __init__( self.sleeper: Callable[[str], Awaitable[None]] if sleeper is None: - async def no_op_sleeper(_: str) -> None: + async def no_op_sleeper(_: object) -> None: return self.sleeper = no_op_sleeper @@ -406,8 +407,8 @@ def ssl_wrap_pair( client_transport: T_Stream, server_transport: T_Stream, *, - client_kwargs: dict[str, str | bytes | bool | None] | None = None, - server_kwargs: dict[str, str | bytes | bool | None] | None = None, + client_kwargs: dict[str, Any] | None = None, + server_kwargs: dict[str, Any] | None = None, ) -> tuple[SSLStream[T_Stream], SSLStream[T_Stream]]: if server_kwargs is None: server_kwargs = {} @@ -417,13 +418,13 @@ def ssl_wrap_pair( client_transport, client_ctx, server_hostname="trio-test-1.example.org", - **client_kwargs, # type: ignore[arg-type] + **client_kwargs, ) server_ssl = SSLStream( server_transport, SERVER_CTX, server_side=True, - **server_kwargs, # type: ignore[arg-type] + **server_kwargs, ) return client_ssl, server_ssl From 12fe034374f29d03e4d4f7cd9527242a2ae158eb Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:48:47 -0500 Subject: [PATCH 11/13] Revert `notes-to-self` changes --- notes-to-self/afd-lab.py | 6 ++--- notes-to-self/aio-guest-test.py | 8 +++--- notes-to-self/atomic-local.py | 2 +- notes-to-self/blocking-read-hack.py | 2 +- notes-to-self/estimate-task-size.py | 4 +-- notes-to-self/graceful-shutdown-idea.py | 8 +++--- .../how-does-windows-so-reuseaddr-work.py | 13 ++++++---- notes-to-self/loopy.py | 4 +-- notes-to-self/lots-of-tasks.py | 2 +- notes-to-self/measure-listen-backlog.py | 2 +- notes-to-self/ntp-example.py | 2 +- notes-to-self/print-task-tree.py | 8 +++--- notes-to-self/proxy-benchmarks.py | 26 +++++++++---------- notes-to-self/reopen-pipe.py | 4 +-- notes-to-self/schedule-timing.py | 6 ++--- notes-to-self/socket-scaling.py | 6 ++--- .../ssl-close-notify/ssl-close-notify.py | 2 +- notes-to-self/ssl-handshake/ssl-handshake.py | 8 +++--- notes-to-self/thread-closure-bug-demo.py | 2 +- notes-to-self/thread-dispatch-bench.py | 6 ++--- notes-to-self/time-wait.py | 4 +-- notes-to-self/trace.py | 26 +++++++++---------- notes-to-self/trivial-err.py | 11 ++++---- notes-to-self/trivial.py | 2 +- notes-to-self/wakeup-fd-racer.py | 6 ++--- notes-to-self/win-waitable-timer.py | 4 +-- 26 files changed, 88 insertions(+), 86 deletions(-) diff --git a/notes-to-self/afd-lab.py b/notes-to-self/afd-lab.py index 1a52ff17f..a95eb8bfd 100644 --- a/notes-to-self/afd-lab.py +++ b/notes-to-self/afd-lab.py @@ -99,7 +99,7 @@ class AFDLab: - def __init__(self) -> None: + def __init__(self): self._afd = _afd_helper_handle() trio.lowlevel.register_with_iocp(self._afd) @@ -141,7 +141,7 @@ async def afd_poll(self, sock, flags, *, exclusive=0): return out_flags -def fill_socket(sock) -> None: +def fill_socket(sock): try: while True: sock.send(b"x" * 65536) @@ -149,7 +149,7 @@ def fill_socket(sock) -> None: pass -async def main() -> None: +async def main(): afdlab = AFDLab() a, b = socket.socketpair() diff --git a/notes-to-self/aio-guest-test.py b/notes-to-self/aio-guest-test.py index 4995fafec..3c607d028 100644 --- a/notes-to-self/aio-guest-test.py +++ b/notes-to-self/aio-guest-test.py @@ -3,12 +3,12 @@ import trio -async def aio_main() -> None: +async def aio_main(): loop = asyncio.get_running_loop() trio_done_fut = loop.create_future() - def trio_done_callback(main_outcome) -> None: + def trio_done_callback(main_outcome): print(f"trio_main finished: {main_outcome!r}") trio_done_fut.set_result(main_outcome) @@ -21,7 +21,7 @@ def trio_done_callback(main_outcome) -> None: (await trio_done_fut).unwrap() -async def trio_main() -> None: +async def trio_main(): print("trio_main!") to_trio, from_aio = trio.open_memory_channel(float("inf")) @@ -40,7 +40,7 @@ async def trio_main() -> None: del _task_ref -async def aio_pingpong(from_trio, to_trio) -> None: +async def aio_pingpong(from_trio, to_trio): print("aio_pingpong!") while True: diff --git a/notes-to-self/atomic-local.py b/notes-to-self/atomic-local.py index b0db7ed2b..643bc16c6 100644 --- a/notes-to-self/atomic-local.py +++ b/notes-to-self/atomic-local.py @@ -4,7 +4,7 @@ sentinel = "_unique_name" -def f() -> None: +def f(): print(locals()) diff --git a/notes-to-self/blocking-read-hack.py b/notes-to-self/blocking-read-hack.py index a5d486123..688f10305 100644 --- a/notes-to-self/blocking-read-hack.py +++ b/notes-to-self/blocking-read-hack.py @@ -19,7 +19,7 @@ async def blocking_read_with_timeout( print("reading from fd", fd) cancel_requested = False - async def kill_it_after_timeout(new_fd) -> None: + async def kill_it_after_timeout(new_fd): print("sleeping") await trio.sleep(timeout) print("breaking the fd") diff --git a/notes-to-self/estimate-task-size.py b/notes-to-self/estimate-task-size.py index 7a618af7d..0010c7a2b 100644 --- a/notes-to-self/estimate-task-size.py +++ b/notes-to-self/estimate-task-size.py @@ -9,7 +9,7 @@ HIGH = 10000 -async def tinytask() -> None: +async def tinytask(): await trio.sleep_forever() @@ -22,7 +22,7 @@ async def measure(count): return resource.getrusage(resource.RUSAGE_SELF) -async def main() -> None: +async def main(): low_usage = await measure(LOW) high_usage = await measure(HIGH + LOW) diff --git a/notes-to-self/graceful-shutdown-idea.py b/notes-to-self/graceful-shutdown-idea.py index 36e9178ad..9497af972 100644 --- a/notes-to-self/graceful-shutdown-idea.py +++ b/notes-to-self/graceful-shutdown-idea.py @@ -5,11 +5,11 @@ class GracefulShutdownManager: - def __init__(self) -> None: + def __init__(self): self._shutting_down = False self._cancel_scopes = set() - def start_shutdown(self) -> None: + def start_shutdown(self): self._shutting_down = True for cancel_scope in self._cancel_scopes: cancel_scope.cancel() @@ -32,7 +32,7 @@ def shutting_down(self): # When doing operations that might block for an indefinite about of time and # that should be aborted when a graceful shutdown starts, wrap them in 'with # gsm.cancel_on_graceful_shutdown()'. -async def stream_handler(stream) -> None: +async def stream_handler(stream): while True: with gsm.cancel_on_graceful_shutdown(): data = await stream.receive_some() @@ -42,7 +42,7 @@ async def stream_handler(stream) -> None: # To trigger the shutdown: -async def listen_for_shutdown_signals() -> None: +async def listen_for_shutdown_signals(): with trio.open_signal_receiver(signal.SIGINT, signal.SIGTERM) as signal_aiter: async for _sig in signal_aiter: gsm.start_shutdown() diff --git a/notes-to-self/how-does-windows-so-reuseaddr-work.py b/notes-to-self/how-does-windows-so-reuseaddr-work.py index cb6264844..117b9738e 100644 --- a/notes-to-self/how-does-windows-so-reuseaddr-work.py +++ b/notes-to-self/how-does-windows-so-reuseaddr-work.py @@ -20,7 +20,7 @@ def sock(mode): return s -def bind(sock, bind_type) -> None: +def bind(sock, bind_type): if bind_type == "wildcard": sock.bind(("0.0.0.0", 12345)) elif bind_type == "specific": @@ -29,7 +29,7 @@ def bind(sock, bind_type) -> None: raise AssertionError() -def table_entry(mode1, bind_type1, mode2, bind_type2) -> str: +def table_entry(mode1, bind_type1, mode2, bind_type2): with sock(mode1) as sock1: bind(sock1, bind_type1) try: @@ -49,12 +49,15 @@ def table_entry(mode1, bind_type1, mode2, bind_type2) -> str: """ second bind | """ - + " | ".join(["%-19s" % mode for mode in modes]), + + " | ".join(f"{mode:<19}" for mode in modes), ) print(""" """, end="") for _ in modes: - print(" | " + " | ".join(["%8s" % bind_type for bind_type in bind_types]), end="") + print( + " | " + " | ".join(f"{bind_type:>8}" for bind_type in bind_types), + end="", + ) print( """ @@ -72,5 +75,5 @@ def table_entry(mode1, bind_type1, mode2, bind_type2) -> str: # print(mode1, bind_type1, mode2, bind_type2, entry) print( f"{mode1:>19} | {bind_type1:>8} | " - + " | ".join(["%8s" % entry for entry in row]), + + " | ".join(f"{entry:>8}" for entry in row), ) diff --git a/notes-to-self/loopy.py b/notes-to-self/loopy.py index e6065bbf7..99f6e050b 100644 --- a/notes-to-self/loopy.py +++ b/notes-to-self/loopy.py @@ -3,7 +3,7 @@ import trio -async def loopy() -> None: +async def loopy(): try: while True: # synchronous sleep to avoid maxing out CPU @@ -13,7 +13,7 @@ async def loopy() -> None: print("KI!") -async def main() -> None: +async def main(): async with trio.open_nursery() as nursery: nursery.start_soon(loopy) nursery.start_soon(loopy) diff --git a/notes-to-self/lots-of-tasks.py b/notes-to-self/lots-of-tasks.py index d83617552..048c69a7e 100644 --- a/notes-to-self/lots-of-tasks.py +++ b/notes-to-self/lots-of-tasks.py @@ -6,7 +6,7 @@ COUNT = int(COUNT_STR) -async def main() -> None: +async def main(): async with trio.open_nursery() as nursery: for _ in range(COUNT): nursery.start_soon(trio.sleep, 1) diff --git a/notes-to-self/measure-listen-backlog.py b/notes-to-self/measure-listen-backlog.py index 7704ee7d4..b7253b86c 100644 --- a/notes-to-self/measure-listen-backlog.py +++ b/notes-to-self/measure-listen-backlog.py @@ -1,7 +1,7 @@ import trio -async def run_test(nominal_backlog) -> None: +async def run_test(nominal_backlog): print("--\nnominal:", nominal_backlog) listen_sock = trio.socket.socket() diff --git a/notes-to-self/ntp-example.py b/notes-to-self/ntp-example.py index 79b8cd0a5..2bb9f80fb 100644 --- a/notes-to-self/ntp-example.py +++ b/notes-to-self/ntp-example.py @@ -53,7 +53,7 @@ def extract_transmit_timestamp(ntp_packet): return base_time + offset -async def main() -> None: +async def main(): print("Our clock currently reads (in UTC):", datetime.datetime.utcnow()) # Look up some random NTP servers. diff --git a/notes-to-self/print-task-tree.py b/notes-to-self/print-task-tree.py index 5f9c535b0..54b97ec01 100644 --- a/notes-to-self/print-task-tree.py +++ b/notes-to-self/print-task-tree.py @@ -78,7 +78,7 @@ def task_tree_lines(task=None): return _render_subtree(task.name, rendered_children) -def print_task_tree(task=None) -> None: +def print_task_tree(task=None): for line in task_tree_lines(task): print(line) @@ -86,20 +86,20 @@ def print_task_tree(task=None) -> None: ################################################################ -async def child2() -> None: +async def child2(): async with trio.open_nursery() as nursery: nursery.start_soon(trio.sleep_forever) nursery.start_soon(trio.sleep_forever) -async def child1() -> None: +async def child1(): async with trio.open_nursery() as nursery: nursery.start_soon(child2) nursery.start_soon(child2) nursery.start_soon(trio.sleep_forever) -async def main() -> None: +async def main(): async with trio.open_nursery() as nursery0: nursery0.start_soon(child1) async with trio.open_nursery() as nursery1: diff --git a/notes-to-self/proxy-benchmarks.py b/notes-to-self/proxy-benchmarks.py index 85d7db1c0..830327cf4 100644 --- a/notes-to-self/proxy-benchmarks.py +++ b/notes-to-self/proxy-benchmarks.py @@ -8,7 +8,7 @@ class Proxy1: strategy = "__getattr__" works_for = "any attr" - def __init__(self, wrapped) -> None: + def __init__(self, wrapped): self._wrapped = wrapped def __getattr__(self, name): @@ -24,11 +24,11 @@ class Proxy2: strategy = "generated methods (getattr + closure)" works_for = "methods" - def __init__(self, wrapped) -> None: + def __init__(self, wrapped): self._wrapped = wrapped -def add_wrapper(cls, method) -> None: +def add_wrapper(cls, method): def wrapper(self, *args, **kwargs): return getattr(self._wrapped, method)(*args, **kwargs) @@ -45,11 +45,11 @@ class Proxy3: strategy = "generated methods (exec)" works_for = "methods" - def __init__(self, wrapped) -> None: + def __init__(self, wrapped): self._wrapped = wrapped -def add_wrapper(cls, method) -> None: +def add_wrapper(cls, method): code = textwrap.dedent( f""" def wrapper(self, *args, **kwargs): @@ -71,18 +71,18 @@ class Proxy4: strategy = "generated properties (getattr + closure)" works_for = "any attr" - def __init__(self, wrapped) -> None: + def __init__(self, wrapped): self._wrapped = wrapped -def add_wrapper(cls, attr) -> None: +def add_wrapper(cls, attr): def getter(self): return getattr(self._wrapped, attr) - def setter(self, newval) -> None: + def setter(self, newval): setattr(self._wrapped, attr, newval) - def deleter(self) -> None: + def deleter(self): delattr(self._wrapped, attr) setattr(cls, attr, property(getter, setter, deleter)) @@ -98,11 +98,11 @@ class Proxy5: strategy = "generated properties (exec)" works_for = "any attr" - def __init__(self, wrapped) -> None: + def __init__(self, wrapped): self._wrapped = wrapped -def add_wrapper(cls, attr) -> None: +def add_wrapper(cls, attr): code = textwrap.dedent( f""" def getter(self): @@ -131,7 +131,7 @@ class Proxy6: strategy = "copy attrs from wrappee to wrapper" works_for = "methods + constant attrs" - def __init__(self, wrapper) -> None: + def __init__(self, wrapper): self._wrapper = wrapper for method in methods: @@ -143,7 +143,7 @@ def __init__(self, wrapper) -> None: classes = [Proxy1, Proxy2, Proxy3, Proxy4, Proxy5, Proxy6] -def check(cls) -> None: +def check(cls): with open("/etc/passwd") as f: p = cls(f) assert p.fileno() == f.fileno() diff --git a/notes-to-self/reopen-pipe.py b/notes-to-self/reopen-pipe.py index 679c854ef..dbccd567d 100644 --- a/notes-to-self/reopen-pipe.py +++ b/notes-to-self/reopen-pipe.py @@ -4,7 +4,7 @@ import time -def check_reopen(r1, w) -> None: +def check_reopen(r1, w): try: print("Reopening read end") r2 = os.open(f"/proc/self/fd/{r1}", os.O_RDONLY) @@ -34,7 +34,7 @@ def check_reopen(r1, w) -> None: print("r2 definitely seems to be in non-blocking mode") # Check that r1 is really truly still in blocking mode - def sleep_then_write() -> None: + def sleep_then_write(): time.sleep(1) os.write(w, b"c") diff --git a/notes-to-self/schedule-timing.py b/notes-to-self/schedule-timing.py index 4fa88aeaf..11594b7cc 100644 --- a/notes-to-self/schedule-timing.py +++ b/notes-to-self/schedule-timing.py @@ -6,7 +6,7 @@ RUNNING = True -async def reschedule_loop(depth) -> None: +async def reschedule_loop(depth): if depth == 0: global LOOPS while RUNNING: @@ -17,7 +17,7 @@ async def reschedule_loop(depth) -> None: await reschedule_loop(depth - 1) -async def report_loop() -> None: +async def report_loop(): global RUNNING try: while True: @@ -33,7 +33,7 @@ async def report_loop() -> None: RUNNING = False -async def main() -> None: +async def main(): async with trio.open_nursery() as nursery: nursery.start_soon(reschedule_loop, 10) nursery.start_soon(report_loop) diff --git a/notes-to-self/socket-scaling.py b/notes-to-self/socket-scaling.py index 3d9199440..3bd074836 100644 --- a/notes-to-self/socket-scaling.py +++ b/notes-to-self/socket-scaling.py @@ -24,15 +24,15 @@ import trio.testing -async def main() -> None: +async def main(): for total in [10, 100, 500, 1_000, 10_000, 20_000, 30_000]: - def pt(desc, *, count=total, item="socket") -> None: + def pt(desc, *, count=total, item="socket"): nonlocal last_time now = time.perf_counter() total_ms = (now - last_time) * 1000 per_us = total_ms * 1000 / count - print(f"{desc}: {total_ms:.2f} ms total, {per_us:.2f} µs/{item}") + print(f"{desc}: {total_ms:.2f} ms total, {per_us:.2f} μs/{item}") last_time = now print(f"\n-- {total} sockets --") diff --git a/notes-to-self/ssl-close-notify/ssl-close-notify.py b/notes-to-self/ssl-close-notify/ssl-close-notify.py index 8df8cbb42..7a55b8c99 100644 --- a/notes-to-self/ssl-close-notify/ssl-close-notify.py +++ b/notes-to-self/ssl-close-notify/ssl-close-notify.py @@ -23,7 +23,7 @@ client_done = threading.Event() -def server_thread_fn() -> None: +def server_thread_fn(): server_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH) server_ctx.load_cert_chain("trio-test-1.pem") server = server_ctx.wrap_socket( diff --git a/notes-to-self/ssl-handshake/ssl-handshake.py b/notes-to-self/ssl-handshake/ssl-handshake.py index 6b73339c8..1665ce333 100644 --- a/notes-to-self/ssl-handshake/ssl-handshake.py +++ b/notes-to-self/ssl-handshake/ssl-handshake.py @@ -9,7 +9,7 @@ server_ctx.load_cert_chain("trio-test-1.pem") -def _ssl_echo_serve_sync(sock) -> None: +def _ssl_echo_serve_sync(sock): try: wrapped = server_ctx.wrap_socket(sock, server_side=True) while True: @@ -37,7 +37,7 @@ def echo_server_connection(): class ManuallyWrappedSocket: - def __init__(self, ctx, sock, **kwargs) -> None: + def __init__(self, ctx, sock, **kwargs): self.incoming = ssl.MemoryBIO() self.outgoing = ssl.MemoryBIO() self.obj = ctx.wrap_bio(self.incoming, self.outgoing, **kwargs) @@ -71,13 +71,13 @@ def _retry(self, fn, *args): # then retry if necessary return ret - def do_handshake(self) -> None: + def do_handshake(self): self._retry(self.obj.do_handshake) def recv(self, bufsize): return self._retry(self.obj.read, bufsize) - def sendall(self, data) -> None: + def sendall(self, data): self._retry(self.obj.write, data) def unwrap(self): diff --git a/notes-to-self/thread-closure-bug-demo.py b/notes-to-self/thread-closure-bug-demo.py index 6985534bd..b5da68c33 100644 --- a/notes-to-self/thread-closure-bug-demo.py +++ b/notes-to-self/thread-closure-bug-demo.py @@ -23,7 +23,7 @@ def run_with_slow_tracefunc(fn): return fn() -def outer() -> None: +def outer(): x = 0 # We hide the done variable inside a list, because we want to use it to # communicate between the main thread and the looper thread, and the bug diff --git a/notes-to-self/thread-dispatch-bench.py b/notes-to-self/thread-dispatch-bench.py index 427cc0a62..e752c27e0 100644 --- a/notes-to-self/thread-dispatch-bench.py +++ b/notes-to-self/thread-dispatch-bench.py @@ -11,13 +11,13 @@ COUNT = 10000 -def worker(in_q, out_q) -> None: +def worker(in_q, out_q): while True: job = in_q.get() out_q.put(job()) -def main() -> None: +def main(): in_q = Queue() out_q = Queue() @@ -30,7 +30,7 @@ def main() -> None: in_q.put(lambda: None) out_q.get() end = time.monotonic() - print(f"{(end - start) / COUNT * 1e6:.2f} µs/job") + print(f"{(end - start) / COUNT * 1e6:.2f} μs/job") main() diff --git a/notes-to-self/time-wait.py b/notes-to-self/time-wait.py index a2a7dd165..edc1b3917 100644 --- a/notes-to-self/time-wait.py +++ b/notes-to-self/time-wait.py @@ -40,7 +40,7 @@ class Options: server = None listen2 = None - def set(self, which, sock) -> None: + def set(self, which, sock): value = getattr(self, which) if value is not None: sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, value) @@ -54,7 +54,7 @@ def describe(self): return "Set/unset: {}".format(", ".join(info)) -def time_wait(options) -> None: +def time_wait(options): print(options.describe()) # Find a pristine port (one we can definitely bind to without diff --git a/notes-to-self/trace.py b/notes-to-self/trace.py index 3294ce431..046412d3a 100644 --- a/notes-to-self/trace.py +++ b/notes-to-self/trace.py @@ -32,20 +32,20 @@ class Trace(trio.abc.Instrument): - def __init__(self, out) -> None: + def __init__(self, out): self.out = out self.out.write("[\n") self.ids = count() self._task_metadata(-1, "I/O manager") - def _write(self, **ev) -> None: + def _write(self, **ev): ev.setdefault("pid", os.getpid()) if ev["ph"] != "M": ev.setdefault("ts", trio.current_time() * 1e6) self.out.write(json.dumps(ev)) self.out.write(",\n") - def _task_metadata(self, tid, name) -> None: + def _task_metadata(self, tid, name): self._write( name="thread_name", ph="M", @@ -59,7 +59,7 @@ def _task_metadata(self, tid, name) -> None: args={"sort_index": tid}, ) - def task_spawned(self, task) -> None: + def task_spawned(self, task): self._task_metadata(task._counter, task.name) self._write( name="task lifetime", @@ -67,28 +67,28 @@ def task_spawned(self, task) -> None: tid=task._counter, ) - def task_exited(self, task) -> None: + def task_exited(self, task): self._write( name="task lifetime", ph="E", tid=task._counter, ) - def before_task_step(self, task) -> None: + def before_task_step(self, task): self._write( name="running", ph="B", tid=task._counter, ) - def after_task_step(self, task) -> None: + def after_task_step(self, task): self._write( name="running", ph="E", tid=task._counter, ) - def task_scheduled(self, task) -> None: + def task_scheduled(self, task): try: waker = trio.lowlevel.current_task() except RuntimeError: @@ -108,14 +108,14 @@ def task_scheduled(self, task) -> None: tid=task._counter, ) - def before_io_wait(self, timeout) -> None: + def before_io_wait(self, timeout): self._write( name="I/O wait", ph="B", tid=-1, ) - def after_io_wait(self, timeout) -> None: + def after_io_wait(self, timeout): self._write( name="I/O wait", ph="E", @@ -123,19 +123,19 @@ def after_io_wait(self, timeout) -> None: ) -async def child1() -> None: +async def child1(): print(" child1: started! sleeping now...") await trio.sleep(1) print(" child1: exiting!") -async def child2() -> None: +async def child2(): print(" child2: started! sleeping now...") await trio.sleep(1) print(" child2: exiting!") -async def parent() -> None: +async def parent(): print("parent: started!") async with trio.open_nursery() as nursery: print("parent: spawning child1...") diff --git a/notes-to-self/trivial-err.py b/notes-to-self/trivial-err.py index 1b0b7adde..6c32617c7 100644 --- a/notes-to-self/trivial-err.py +++ b/notes-to-self/trivial-err.py @@ -1,30 +1,29 @@ import sys -from typing import NoReturn import trio sys.stderr = sys.stdout -async def child1() -> NoReturn: +async def child1(): raise ValueError -async def child2() -> None: +async def child2(): async with trio.open_nursery() as nursery: nursery.start_soon(grandchild1) nursery.start_soon(grandchild2) -async def grandchild1() -> NoReturn: +async def grandchild1(): raise KeyError -async def grandchild2() -> NoReturn: +async def grandchild2(): raise NameError("Bob") -async def main() -> None: +async def main(): async with trio.open_nursery() as nursery: nursery.start_soon(child1) nursery.start_soon(child2) diff --git a/notes-to-self/trivial.py b/notes-to-self/trivial.py index f02d5a297..405d92daf 100644 --- a/notes-to-self/trivial.py +++ b/notes-to-self/trivial.py @@ -1,7 +1,7 @@ import trio -async def foo() -> int: +async def foo(): print("in foo!") return 3 diff --git a/notes-to-self/wakeup-fd-racer.py b/notes-to-self/wakeup-fd-racer.py index a48384942..97faa0dfd 100644 --- a/notes-to-self/wakeup-fd-racer.py +++ b/notes-to-self/wakeup-fd-racer.py @@ -16,13 +16,13 @@ signal_raise = getattr(_lib, "raise") else: - def signal_raise(signum) -> None: + def signal_raise(signum): # Use pthread_kill to make sure we're actually using the wakeup fd on # Unix signal.pthread_kill(threading.get_ident(), signum) -def raise_SIGINT_soon() -> None: +def raise_SIGINT_soon(): time.sleep(1) signal_raise(signal.SIGINT) # Sending 2 signals becomes reliable, as we'd expect (because we need @@ -41,7 +41,7 @@ def drain(sock): return total -def main() -> None: +def main(): writer, reader = socket.socketpair() writer.setblocking(False) reader.setblocking(False) diff --git a/notes-to-self/win-waitable-timer.py b/notes-to-self/win-waitable-timer.py index 848f8229e..b8d9af6ca 100644 --- a/notes-to-self/win-waitable-timer.py +++ b/notes-to-self/win-waitable-timer.py @@ -96,7 +96,7 @@ PROCESS_LEAP_SECOND_INFO_FLAG_ENABLE_SIXTY_SECOND = 1 -def set_leap_seconds_enabled(enabled) -> None: +def set_leap_seconds_enabled(enabled): plsi = ffi.new("PROCESS_LEAP_SECOND_INFO*") if enabled: plsi.Flags = PROCESS_LEAP_SECOND_INFO_FLAG_ENABLE_SIXTY_SECOND @@ -160,7 +160,7 @@ def py_datetime_to_win_filetime(dt): return round((dt - FILETIME_EPOCH).total_seconds() * FILETIME_TICKS_PER_SECOND) -async def main() -> None: +async def main(): h = kernel32.CreateWaitableTimerW(ffi.NULL, True, ffi.NULL) if not h: raise_winerror() From 8123b72b3259eba128c7231f7c5db8995221d885 Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:56:18 -0500 Subject: [PATCH 12/13] Disable `ANN401` --- pyproject.toml | 1 + src/trio/_core/_concat_tb.py | 2 +- src/trio/_core/_instrumentation.py | 2 +- src/trio/_core/_run.py | 4 ++-- src/trio/_core/_tests/test_guest_mode.py | 4 ++-- src/trio/_core/_traps.py | 8 ++++---- src/trio/_ssl.py | 2 +- src/trio/_tests/test_subprocess.py | 8 ++++---- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 2db6ab213..a0b66ed42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -142,6 +142,7 @@ extend-ignore = [ 'PERF203', # try-except-in-loop (not always possible to refactor) 'PT012', # multiple statements in pytest.raises block 'SIM117', # multiple-with-statements (messes up lots of context-based stuff and looks bad) + 'ANN401', # any-type (mypy's `disallow_any_explicit` is better) ] [tool.ruff.lint.per-file-ignores] diff --git a/src/trio/_core/_concat_tb.py b/src/trio/_core/_concat_tb.py index 919c303e3..5d84118cd 100644 --- a/src/trio/_core/_concat_tb.py +++ b/src/trio/_core/_concat_tb.py @@ -88,7 +88,7 @@ def copy_tb(base_tb: TracebackType, tb_next: TracebackType | None) -> TracebackT # cpython/pypy in current type checkers. def controller( # type: ignore[no-any-unimported] operation: tputil.ProxyOperation, - ) -> Any | None: # noqa: ANN401 # Using Any + ) -> Any | None: # 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 diff --git a/src/trio/_core/_instrumentation.py b/src/trio/_core/_instrumentation.py index 0139b4dea..d5d6e2c83 100644 --- a/src/trio/_core/_instrumentation.py +++ b/src/trio/_core/_instrumentation.py @@ -89,7 +89,7 @@ def remove_instrument(self, instrument: Instrument) -> None: def call( self, hookname: str, - *args: Any, # noqa: ANN401 # Using Any + *args: Any, ) -> None: """Call hookname(*args) on each applicable instrument. diff --git a/src/trio/_core/_run.py b/src/trio/_core/_run.py index d66fe2e12..882fd17dc 100644 --- a/src/trio/_core/_run.py +++ b/src/trio/_core/_run.py @@ -1283,7 +1283,7 @@ async def start( async_fn: Callable[..., Awaitable[object]], *args: object, name: object = None, - ) -> Any: # noqa: ANN401 # Using Any + ) -> Any: r"""Creates and initializes a child task. Like :meth:`start_soon`, but blocks until the new task has @@ -2826,7 +2826,7 @@ class _TaskStatusIgnored(TaskStatus[Any]): def __repr__(self) -> str: return "TASK_STATUS_IGNORED" - def started(self, value: Any = None) -> None: # noqa: ANN401 # Using Any + def started(self, value: Any = None) -> None: pass diff --git a/src/trio/_core/_tests/test_guest_mode.py b/src/trio/_core/_tests/test_guest_mode.py index a6edbb13f..303c3a229 100644 --- a/src/trio/_core/_tests/test_guest_mode.py +++ b/src/trio/_core/_tests/test_guest_mode.py @@ -52,7 +52,7 @@ def trivial_guest_run( trio_fn: Callable[..., Awaitable[T]], *, in_host_after_start: Callable[[], None] | None = None, - **start_guest_run_kwargs: Any, # noqa: ANN401 # Using Any, too diverse + **start_guest_run_kwargs: Any, ) -> T: todo: queue.Queue[tuple[str, Outcome[T] | Callable[..., object]]] = queue.Queue() @@ -436,7 +436,7 @@ def aiotrio_run( trio_fn: Callable[..., Awaitable[T]], *, pass_not_threadsafe: bool = True, - **start_guest_run_kwargs: Any, # noqa: ANN401 # Using Any, too diverse + **start_guest_run_kwargs: Any, ) -> T: loop = asyncio.new_event_loop() diff --git a/src/trio/_core/_traps.py b/src/trio/_core/_traps.py index 9222c2f10..fc31a182a 100644 --- a/src/trio/_core/_traps.py +++ b/src/trio/_core/_traps.py @@ -25,7 +25,7 @@ # tracking machinery. Since our traps are public APIs, we make them real async # functions, and then this helper takes care of the actual yield: @types.coroutine -def _async_yield(obj: Any) -> Any: # type: ignore[misc] # noqa: ANN401 +def _async_yield(obj: Any) -> Any: # type: ignore[misc] return (yield obj) @@ -79,7 +79,7 @@ class WaitTaskRescheduled: # with a bad value. async def wait_task_rescheduled( abort_func: Callable[[RaiseCancelT], Abort], -) -> Any: # noqa: ANN401 # Any used +) -> Any: """Put the current task to sleep, with cancellation support. This is the lowest-level API for blocking in Trio. Every time a @@ -189,7 +189,7 @@ class PermanentlyDetachCoroutineObject: async def permanently_detach_coroutine_object( final_outcome: outcome.Outcome[Any], -) -> Any: # noqa: ANN401 # Any used +) -> Any: """Permanently detach the current task from the Trio scheduler. Normally, a Trio task doesn't exit until its coroutine object exits. When @@ -222,7 +222,7 @@ async def permanently_detach_coroutine_object( async def temporarily_detach_coroutine_object( abort_func: Callable[[RaiseCancelT], Abort], -) -> Any: # noqa: ANN401 # Any used +) -> Any: """Temporarily detach the current coroutine object from the Trio scheduler. diff --git a/src/trio/_ssl.py b/src/trio/_ssl.py index e5a0cdabd..df1cbc37b 100644 --- a/src/trio/_ssl.py +++ b/src/trio/_ssl.py @@ -413,7 +413,7 @@ def __init__( "version", } - def __getattr__(self, name: str) -> Any: # noqa: ANN401 # Any used + def __getattr__(self, name: str) -> Any: if name in self._forwarded: if name in self._after_handshake and not self._handshook.done: raise NeedHandshakeError(f"call do_handshake() before calling {name!r}") diff --git a/src/trio/_tests/test_subprocess.py b/src/trio/_tests/test_subprocess.py index 2908e2294..3be99b6d3 100644 --- a/src/trio/_tests/test_subprocess.py +++ b/src/trio/_tests/test_subprocess.py @@ -92,8 +92,8 @@ def got_signal(proc: Process, sig: SignalType) -> bool: @asynccontextmanager # type: ignore[misc] # Any in decorated async def open_process_then_kill( - *args: Any, # noqa: ANN401 # Any used, different OS -> different args - **kwargs: Any, # noqa: ANN401 + *args: Any, + **kwargs: Any, ) -> AsyncIterator[Process]: proc = await open_process(*args, **kwargs) try: @@ -105,8 +105,8 @@ async def open_process_then_kill( @asynccontextmanager # type: ignore[misc] # Any in decorated async def run_process_in_nursery( - *args: Any, # noqa: ANN401 # Any used, different OS -> different args - **kwargs: Any, # noqa: ANN401 + *args: Any, + **kwargs: Any, ) -> AsyncIterator[Process]: async with _core.open_nursery() as nursery: kwargs.setdefault("check", False) From 42be7f365dba82634f3ff72d2a30fe528e40c52b Mon Sep 17 00:00:00 2001 From: CoolCat467 <52022020+CoolCat467@users.noreply.github.com> Date: Mon, 21 Oct 2024 11:01:31 -0500 Subject: [PATCH 13/13] Stop using `kwargs` altogether and simply define the parameters Co-authored-by: John Litborn <11260241+jakkdl@users.noreply.github.com> --- pyproject.toml | 2 +- .../_tests/test_highlevel_open_tcp_stream.py | 6 +- src/trio/_tests/test_socket.py | 55 +++++++++++++++---- src/trio/_tests/test_ssl.py | 42 ++++++++++---- 4 files changed, 80 insertions(+), 25 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a0b66ed42..ab2c0dd82 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -135,6 +135,7 @@ extend-ignore = [ 'A002', # builtin-argument-shadowing 'ANN101', # missing-type-self 'ANN102', # missing-type-cls + 'ANN401', # any-type (mypy's `disallow_any_explicit` is better) 'E402', # module-import-not-at-top-of-file (usually OS-specific) 'E501', # line-too-long 'F403', # undefined-local-with-import-star @@ -142,7 +143,6 @@ extend-ignore = [ 'PERF203', # try-except-in-loop (not always possible to refactor) 'PT012', # multiple statements in pytest.raises block 'SIM117', # multiple-with-statements (messes up lots of context-based stuff and looks bad) - 'ANN401', # any-type (mypy's `disallow_any_explicit` is better) ] [tool.ruff.lint.per-file-ignores] diff --git a/src/trio/_tests/test_highlevel_open_tcp_stream.py b/src/trio/_tests/test_highlevel_open_tcp_stream.py index f05166a28..ebe30ef78 100644 --- a/src/trio/_tests/test_highlevel_open_tcp_stream.py +++ b/src/trio/_tests/test_highlevel_open_tcp_stream.py @@ -360,7 +360,8 @@ async def run_scenario( # If this is True, we require there to be an exception, and return # (exception, scenario object) expect_error: tuple[type[BaseException], ...] | type[BaseException] = (), - **kwargs: str | float | None, + happy_eyeballs_delay: float | None = 0.25, + local_address: str | None = None, ) -> tuple[SocketType, Scenario] | tuple[BaseException, Scenario]: supported_families = set() if ipv4_supported: @@ -378,7 +379,8 @@ async def run_scenario( stream = await open_tcp_stream( "test.example.com", port, - **kwargs, # type: ignore[arg-type] + happy_eyeballs_delay=happy_eyeballs_delay, + local_address=local_address, ) assert expect_error == () scenario.check(stream.socket) diff --git a/src/trio/_tests/test_socket.py b/src/trio/_tests/test_socket.py index a403272b4..43c9df239 100644 --- a/src/trio/_tests/test_socket.py +++ b/src/trio/_tests/test_socket.py @@ -51,11 +51,15 @@ def __init__(self, orig_getaddrinfo: Callable[..., GetAddrInfoResponse]) -> None # get a normalized getaddrinfo argument tuple def _frozenbind( self, - *args: bytes | str | int | None, - **kwargs: bytes | str | int | None, + host: bytes | str | None, + port: bytes | str | int | None, + family: int = 0, + type: int = 0, + proto: int = 0, + flags: int = 0, ) -> tuple[Any, ...]: sig = inspect.signature(self._orig_getaddrinfo) - bound = sig.bind(*args, **kwargs) + bound = sig.bind(host, port, family=family, type=type, proto=proto, flags=flags) bound.apply_defaults() frozenbound = bound.args assert not bound.kwargs @@ -64,22 +68,53 @@ def _frozenbind( def set( self, response: GetAddrInfoResponse | str, - *args: bytes | str | int | None, - **kwargs: bytes | str | int | None, + host: bytes | str | None, + port: bytes | str | int | None, + family: int = 0, + type: int = 0, + proto: int = 0, + flags: int = 0, ) -> None: - self._responses[self._frozenbind(*args, **kwargs)] = response + self._responses[ + self._frozenbind( + host, + port, + family=family, + type=type, + proto=proto, + flags=flags, + ) + ] = response def getaddrinfo( self, - *args: bytes | str | int | None, - **kwargs: bytes | str | int | None, + host: bytes | str | None, + port: bytes | str | int | None, + family: int = 0, + type: int = 0, + proto: int = 0, + flags: int = 0, ) -> GetAddrInfoResponse | str: - bound = self._frozenbind(*args, **kwargs) + bound = self._frozenbind( + host, + port, + family=family, + type=type, + proto=proto, + flags=flags, + ) self.record.append(bound) if bound in self._responses: return self._responses[bound] elif bound[-1] & stdlib_socket.AI_NUMERICHOST: - return self._orig_getaddrinfo(*args, **kwargs) + return self._orig_getaddrinfo( + host, + port, + family=family, + type=type, + proto=proto, + flags=flags, + ) else: raise RuntimeError(f"gai called with unexpected arguments {bound}") diff --git a/src/trio/_tests/test_ssl.py b/src/trio/_tests/test_ssl.py index 3777e8392..e732efabb 100644 --- a/src/trio/_tests/test_ssl.py +++ b/src/trio/_tests/test_ssl.py @@ -174,7 +174,7 @@ def ssl_echo_serve_sync( # (running in a thread). Useful for testing making connections with different # SSLContexts. @asynccontextmanager -async def ssl_echo_server_raw(**kwargs: bool) -> AsyncIterator[SocketStream]: +async def ssl_echo_server_raw(expect_fail: bool = False) -> AsyncIterator[SocketStream]: a, b = stdlib_socket.socketpair() async with trio.open_nursery() as nursery: # Exiting the 'with a, b' context manager closes the sockets, which @@ -183,7 +183,7 @@ async def ssl_echo_server_raw(**kwargs: bool) -> AsyncIterator[SocketStream]: with a, b: nursery.start_soon( trio.to_thread.run_sync, - partial(ssl_echo_serve_sync, b, **kwargs), + partial(ssl_echo_serve_sync, b, expect_fail=expect_fail), ) yield SocketStream(tsocket.from_stdlib_socket(a)) @@ -194,9 +194,9 @@ async def ssl_echo_server_raw(**kwargs: bool) -> AsyncIterator[SocketStream]: @asynccontextmanager async def ssl_echo_server( client_ctx: SSLContext, - **kwargs: bool, + expect_fail: bool = False, ) -> AsyncIterator[SSLStream[Stream]]: - async with ssl_echo_server_raw(**kwargs) as sock: + async with ssl_echo_server_raw(expect_fail=expect_fail) as sock: yield SSLStream(sock, client_ctx, server_hostname="trio-test-1.example.org") @@ -396,9 +396,9 @@ async def do_test( @contextmanager def virtual_ssl_echo_server( client_ctx: SSLContext, - **kwargs: Callable[[str], Awaitable[None]] | None, + sleeper: Callable[[str], Awaitable[None]] | None = None, ) -> Iterator[SSLStream[PyOpenSSLEchoStream]]: - fakesock = PyOpenSSLEchoStream(**kwargs) + fakesock = PyOpenSSLEchoStream(sleeper=sleeper) yield SSLStream(fakesock, client_ctx, server_hostname="trio-test-1.example.org") @@ -434,13 +434,20 @@ def ssl_wrap_pair( def ssl_memory_stream_pair( client_ctx: SSLContext, - **kwargs: dict[str, str | bytes | bool | None] | None, + client_kwargs: dict[str, str | bytes | bool | None] | None = None, + server_kwargs: dict[str, str | bytes | bool | None] | None = None, ) -> tuple[ SSLStream[MemoryStapledStream], SSLStream[MemoryStapledStream], ]: client_transport, server_transport = memory_stream_pair() - return ssl_wrap_pair(client_ctx, client_transport, server_transport, **kwargs) + return ssl_wrap_pair( + client_ctx, + client_transport, + server_transport, + client_kwargs=client_kwargs, + server_kwargs=server_kwargs, + ) MyStapledStream: TypeAlias = StapledStream[SendStream, ReceiveStream] @@ -448,13 +455,20 @@ def ssl_memory_stream_pair( def ssl_lockstep_stream_pair( client_ctx: SSLContext, - **kwargs: dict[str, str | bytes | bool | None] | None, + client_kwargs: dict[str, str | bytes | bool | None] | None = None, + server_kwargs: dict[str, str | bytes | bool | None] | None = None, ) -> tuple[ SSLStream[MyStapledStream], SSLStream[MyStapledStream], ]: client_transport, server_transport = lockstep_stream_pair() - return ssl_wrap_pair(client_ctx, client_transport, server_transport, **kwargs) + return ssl_wrap_pair( + client_ctx, + client_transport, + server_transport, + client_kwargs=client_kwargs, + server_kwargs=server_kwargs, + ) # Simple smoke test for handshake/send/receive/shutdown talking to a @@ -1332,13 +1346,17 @@ async def test_getpeercert(client_ctx: SSLContext) -> None: async def test_SSLListener(client_ctx: SSLContext) -> None: async def setup( - **kwargs: bool, + https_compatible: bool = False, ) -> tuple[tsocket.SocketType, SSLListener[SocketStream], SSLStream[SocketStream]]: listen_sock = tsocket.socket() await listen_sock.bind(("127.0.0.1", 0)) listen_sock.listen(1) socket_listener = SocketListener(listen_sock) - ssl_listener = SSLListener(socket_listener, SERVER_CTX, **kwargs) + ssl_listener = SSLListener( + socket_listener, + SERVER_CTX, + https_compatible=https_compatible, + ) transport_client = await open_tcp_stream(*listen_sock.getsockname()) ssl_client = SSLStream(