From a61b33b8bb60e7af5fecd7b00ec22756105be3da Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Sat, 31 Oct 2026 21:31:26 +0100 Subject: [PATCH 1/2] gh-161032: Convert BaseEventLoop._clock_resolution to asyncio.constants.CLOCK_RESOLUTION Co-Authored-By: Claude Opus 5.5 --- Lib/asyncio/base_events.py | 3 +-- Lib/asyncio/constants.py | 4 ++++ Lib/test/test_asyncio/test_events.py | 3 ++- Lib/test/test_asyncio/utils.py | 1 - .../Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst | 2 ++ 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 9eb34c5f29fb551..861210775347ae4 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -432,7 +432,6 @@ def __init__(self): # Identifier of the thread running the event loop, or None if the # event loop is not running self._thread_id = None - self._clock_resolution = time.get_clock_info('monotonic').resolution self._exception_handler = None self.set_debug(coroutines._is_debug_mode()) # The preserved state of async generator hooks. @@ -2057,7 +2056,7 @@ def _run_once(self): now = self.time() # Ensure that `end_time` is strictly increasing # when the clock resolution is too small. - end_time = now + max(self._clock_resolution, math.ulp(now)) + end_time = now + max(constants.CLOCK_RESOLUTION, math.ulp(now)) while self._scheduled: handle = self._scheduled[0] if handle._when >= end_time: diff --git a/Lib/asyncio/constants.py b/Lib/asyncio/constants.py index b60c1e4236af1fa..e0788851e187e7b 100644 --- a/Lib/asyncio/constants.py +++ b/Lib/asyncio/constants.py @@ -3,6 +3,7 @@ # SPDX-FileCopyrightText: Copyright (c) 2015-2021 MagicStack Inc. http://magic.io import enum +import time # After the connection is lost, log warnings after this many write()s. LOG_THRESHOLD_FOR_CONNLOST_WRITES = 5 @@ -33,6 +34,9 @@ # Default timeout for joining the threads in the threadpool THREAD_JOIN_TIMEOUT = 300 +# Resolution of the clock used by the event loop, in seconds. +CLOCK_RESOLUTION = time.get_clock_info('monotonic').resolution + # The enum should be here to break circular dependencies between # base_events and sslproto class _SendfileMode(enum.Enum): diff --git a/Lib/test/test_asyncio/test_events.py b/Lib/test/test_asyncio/test_events.py index 58556cc87409f7f..33444c76290b6bc 100644 --- a/Lib/test/test_asyncio/test_events.py +++ b/Lib/test/test_asyncio/test_events.py @@ -27,6 +27,7 @@ import tty import asyncio +from asyncio import constants from asyncio import coroutines from asyncio import events from asyncio import selector_events @@ -2314,7 +2315,7 @@ async def wait(): # of the clock used by the kernel. Tolerate a few useless calls on # these platforms. self.assertLessEqual(self.loop._run_once_counter, 20, - {'clock_resolution': self.loop._clock_resolution, + {'clock_resolution': constants.CLOCK_RESOLUTION, 'selector': self.loop._selector.__class__.__name__}) def test_remove_fds_after_closing(self): diff --git a/Lib/test/test_asyncio/utils.py b/Lib/test/test_asyncio/utils.py index e86c221d7f70259..86a2e812b6619ea 100644 --- a/Lib/test/test_asyncio/utils.py +++ b/Lib/test/test_asyncio/utils.py @@ -360,7 +360,6 @@ def gen(): self._gen = gen() next(self._gen) self._time = 0 - self._clock_resolution = 1e-9 self._timers = [] self._selector = TestSelector() diff --git a/Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst b/Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst new file mode 100644 index 000000000000000..01f772ada6f2921 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst @@ -0,0 +1,2 @@ +:mod:`asyncio`: The resolution of the monotonic clock is now computed once at +import time instead of in every event loop. From a7520d92523587ad32465b915e6a31941d8dcd5b Mon Sep 17 00:00:00 2001 From: Andrew Svetlov Date: Mon, 2 Nov 2026 19:58:09 +0100 Subject: [PATCH 2/2] Delete Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst --- .../next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst diff --git a/Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst b/Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst deleted file mode 100644 index 01f772ada6f2921..000000000000000 --- a/Misc/NEWS.d/next/Library/2026-10-31-20-41-55.gh-issue-161032.btNexq.rst +++ /dev/null @@ -1,2 +0,0 @@ -:mod:`asyncio`: The resolution of the monotonic clock is now computed once at -import time instead of in every event loop.