From 95b7512136f9228dd3b9e5cba01365c466ba3607 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 6 Nov 2024 15:35:49 -0800 Subject: [PATCH 1/4] accurately represent threading.Lock --- stdlib/_thread.pyi | 40 +++++++++++++++++++++++++++------------- stdlib/threading.pyi | 16 ++++------------ 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/stdlib/_thread.pyi b/stdlib/_thread.pyi index b75e7608fa77..334d2de1d22e 100644 --- a/stdlib/_thread.pyi +++ b/stdlib/_thread.pyi @@ -12,18 +12,6 @@ _Ts = TypeVarTuple("_Ts") error = RuntimeError def _count() -> int: ... -@final -class LockType: - def acquire(self, blocking: bool = True, timeout: float = -1) -> bool: ... - def release(self) -> None: ... - def locked(self) -> bool: ... - def acquire_lock(self, blocking: bool = True, timeout: float = -1) -> bool: ... - def release_lock(self) -> None: ... - def locked_lock(self) -> bool: ... - def __enter__(self) -> bool: ... - def __exit__( - self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None - ) -> None: ... if sys.version_info >= (3, 13): @final @@ -37,7 +25,33 @@ if sys.version_info >= (3, 13): def start_joinable_thread( function: Callable[[], object], handle: _ThreadHandle | None = None, daemon: bool = True ) -> _ThreadHandle: ... - lock = LockType + @final + class lock: + def acquire(self, blocking: bool = True, timeout: float = -1) -> bool: ... + def release(self) -> None: ... + def locked(self) -> bool: ... + def acquire_lock(self, blocking: bool = True, timeout: float = -1) -> bool: ... + def release_lock(self) -> None: ... + def locked_lock(self) -> bool: ... + def __enter__(self) -> bool: ... + def __exit__( + self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None + ) -> None: ... + + LockType = lock +else: + @final + class LockType: + def acquire(self, blocking: bool = True, timeout: float = -1) -> bool: ... + def release(self) -> None: ... + def locked(self) -> bool: ... + def acquire_lock(self, blocking: bool = True, timeout: float = -1) -> bool: ... + def release_lock(self) -> None: ... + def locked_lock(self) -> bool: ... + def __enter__(self) -> bool: ... + def __exit__( + self, type: type[BaseException] | None, value: BaseException | None, traceback: TracebackType | None + ) -> None: ... @overload def start_new_thread(function: Callable[[Unpack[_Ts]], object], args: tuple[Unpack[_Ts]], /) -> int: ... diff --git a/stdlib/threading.pyi b/stdlib/threading.pyi index c441a04681e2..e6fafdb010f8 100644 --- a/stdlib/threading.pyi +++ b/stdlib/threading.pyi @@ -100,18 +100,10 @@ class Thread: class _DummyThread(Thread): def __init__(self) -> None: ... -@final -class Lock: - def __enter__(self) -> bool: ... - def __exit__( - self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None - ) -> None: ... - def acquire(self, blocking: bool = ..., timeout: float = ...) -> bool: ... - def release(self) -> None: ... - def locked(self) -> bool: ... - def acquire_lock(self, blocking: bool = ..., timeout: float = ...) -> bool: ... # undocumented - def release_lock(self) -> None: ... # undocumented - def locked_lock(self) -> bool: ... # undocumented +if sys.version_info >= (3, 13): + Lock = _thread.lock +else: + Lock = _thread.allocate_lock @final class _RLock: From 53ec5cf4f65243023504bf814984eb186fbea1c0 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 6 Nov 2024 15:44:06 -0800 Subject: [PATCH 2/4] okay, threading.Lock propbably needs to remain a valid type on all versions --- stdlib/threading.pyi | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/stdlib/threading.pyi b/stdlib/threading.pyi index e6fafdb010f8..eb09cd25b1ba 100644 --- a/stdlib/threading.pyi +++ b/stdlib/threading.pyi @@ -100,10 +100,8 @@ class Thread: class _DummyThread(Thread): def __init__(self) -> None: ... -if sys.version_info >= (3, 13): - Lock = _thread.lock -else: - Lock = _thread.allocate_lock +# This is actually the function _thread.allocate_lock for <= 3.12 +Lock = _thread.LockType @final class _RLock: From b1bfca3652c6faca386b3bc2e4a53358d5dffae3 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 27 Nov 2024 16:23:16 -0800 Subject: [PATCH 3/4] move RLock to _thread --- stdlib/@tests/stubtest_allowlists/common.txt | 1 - stdlib/_thread.pyi | 6 ++++++ stdlib/threading.pyi | 14 ++++---------- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index 68d9e0ed4442..c888e421961e 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -65,7 +65,6 @@ xml.sax.expatreader # ========== # TODO: Module members that exist at runtime, but are missing from stubs # ========== -_thread.RLock _threading_local._localimpl.localargs _threading_local._localimpl.locallock bz2.BZ2File.peek diff --git a/stdlib/_thread.pyi b/stdlib/_thread.pyi index b94eacfdefe0..378ac2423757 100644 --- a/stdlib/_thread.pyi +++ b/stdlib/_thread.pyi @@ -12,6 +12,12 @@ _Ts = TypeVarTuple("_Ts") error = RuntimeError def _count() -> int: ... +@final +class RLock: + def acquire(self, blocking: bool = True, timeout: float = -1) -> bool: ... + def release(self) -> None: ... + __enter__ = acquire + def __exit__(self, t: type[BaseException] | None, v: BaseException | None, tb: TracebackType | None) -> None: ... if sys.version_info >= (3, 13): @final diff --git a/stdlib/threading.pyi b/stdlib/threading.pyi index eb09cd25b1ba..5eb4ca6f5cd4 100644 --- a/stdlib/threading.pyi +++ b/stdlib/threading.pyi @@ -4,7 +4,7 @@ from _thread import _excepthook, _ExceptHookArgs, get_native_id as get_native_id from _typeshed import ProfileFunction, TraceFunction from collections.abc import Callable, Iterable, Mapping from types import TracebackType -from typing import Any, TypeVar, final +from typing import Any, TypeVar _T = TypeVar("_T") @@ -103,17 +103,11 @@ class _DummyThread(Thread): # This is actually the function _thread.allocate_lock for <= 3.12 Lock = _thread.LockType -@final -class _RLock: - def acquire(self, blocking: bool = True, timeout: float = -1) -> bool: ... - def release(self) -> None: ... - __enter__ = acquire - def __exit__(self, t: type[BaseException] | None, v: BaseException | None, tb: TracebackType | None) -> None: ... - -RLock = _RLock +# Actually a function at runtime. +RLock = _thread.RLock class Condition: - def __init__(self, lock: Lock | _RLock | None = None) -> None: ... + def __init__(self, lock: Lock | RLock | None = None) -> None: ... def __enter__(self) -> bool: ... def __exit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None From b80223cf77f7453487129a6405a22d6369986028 Mon Sep 17 00:00:00 2001 From: Stephen Morton Date: Wed, 27 Nov 2024 16:37:00 -0800 Subject: [PATCH 4/4] add threading._RLock back, since mypy primer shows it being used directly --- stdlib/threading.pyi | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/stdlib/threading.pyi b/stdlib/threading.pyi index 5eb4ca6f5cd4..efeea69d0234 100644 --- a/stdlib/threading.pyi +++ b/stdlib/threading.pyi @@ -4,7 +4,7 @@ from _thread import _excepthook, _ExceptHookArgs, get_native_id as get_native_id from _typeshed import ProfileFunction, TraceFunction from collections.abc import Callable, Iterable, Mapping from types import TracebackType -from typing import Any, TypeVar +from typing import Any, TypeVar, final _T = TypeVar("_T") @@ -103,11 +103,19 @@ class _DummyThread(Thread): # This is actually the function _thread.allocate_lock for <= 3.12 Lock = _thread.LockType -# Actually a function at runtime. -RLock = _thread.RLock +# Python implementation of RLock. +@final +class _RLock: + _count: int + def acquire(self, blocking: bool = True, timeout: float = -1) -> bool: ... + def release(self) -> None: ... + __enter__ = acquire + def __exit__(self, t: type[BaseException] | None, v: BaseException | None, tb: TracebackType | None) -> None: ... + +RLock = _thread.RLock # Actually a function at runtime. class Condition: - def __init__(self, lock: Lock | RLock | None = None) -> None: ... + def __init__(self, lock: Lock | _RLock | RLock | None = None) -> None: ... def __enter__(self) -> bool: ... def __exit__( self, exc_type: type[BaseException] | None, exc_val: BaseException | None, exc_tb: TracebackType | None