gh-114315: Make `threading.Lock` a real class, not a factory function by sobolevn · Pull Request #114479 · python/cpython · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Doc/library/threading.rst
20 changes: 15 additions & 5 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,21 @@ def test_args_argument(self):
t.start()
t.join()

@cpython_only
def test_disallow_instantiation(self):
# Ensure that the type disallows instantiation (bpo-43916)
lock = threading.Lock()
test.support.check_disallow_instantiation(self, type(lock))
def test_lock_no_args(self):
threading.Lock() # works
self.assertRaises(TypeError, threading.Lock, 1)
self.assertRaises(TypeError, threading.Lock, a=1)
self.assertRaises(TypeError, threading.Lock, 1, 2, a=1, b=2)

def test_lock_no_subclass(self):
# Intentionally disallow subclasses of threading.Lock because they have
# never been allowed, so why start now just because the type is public?
with self.assertRaises(TypeError):
class MyLock(threading.Lock): pass

def test_lock_or_none(self):
import types
self.assertIsInstance(threading.Lock | None, types.UnionType)

# Create a bunch of threads, let each do some work, wait until all are
# done.
Expand Down
4 changes: 2 additions & 2 deletions Lib/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import _thread
import functools
import warnings
import _weakref

from time import monotonic as _time
from _weakrefset import WeakSet
Expand Down Expand Up @@ -37,6 +36,7 @@
_start_joinable_thread = _thread.start_joinable_thread
_daemon_threads_allowed = _thread.daemon_threads_allowed
_allocate_lock = _thread.allocate_lock
_LockType = _thread.LockType
_set_sentinel = _thread._set_sentinel
get_ident = _thread.get_ident
_is_main_interpreter = _thread._is_main_interpreter
Expand Down Expand Up @@ -108,7 +108,7 @@ def gettrace():

# Synchronization classes

Lock = _allocate_lock
Lock = _LockType

def RLock(*args, **kwargs):
"""Factory function that returns a new reentrant lock.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Make :class:`threading.Lock` a real class, not a factory function. Add
``__new__`` to ``_thread.lock`` type.
33 changes: 29 additions & 4 deletions Modules/_threadmodule.c