Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd6dc33e

Browse files
authored
gh-134087: enforce signature ofthreading.RLock (#134178)
- Reject positional and keyword arguments in `_thread.RLock.__new__`.- Convert `_thread.lock.__new__` to AC.
1 parent9983c7d commitd6dc33e

File tree

7 files changed

+115
-53
lines changed

7 files changed

+115
-53
lines changed

‎Doc/whatsnew/3.15.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,15 @@ sysconfig
145145
(Contributed by Filipe Laíns in:gh:`92897`.)
146146

147147

148+
threading
149+
---------
150+
151+
* Remove support for arbitrary positional or keyword arguments in the C
152+
implementation of:class:`~threading.RLock` objects. This was deprecated
153+
in Python 3.14.
154+
(Contributed by Bénédikt Tran in:gh:`134087`.)
155+
156+
148157
typing
149158
------
150159

‎Lib/test/lock_tests.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,11 @@ def test_constructor(self):
124124
lock=self.locktype()
125125
dellock
126126

127+
deftest_constructor_noargs(self):
128+
self.assertRaises(TypeError,self.locktype,1)
129+
self.assertRaises(TypeError,self.locktype,x=1)
130+
self.assertRaises(TypeError,self.locktype,1,x=2)
131+
127132
deftest_repr(self):
128133
lock=self.locktype()
129134
self.assertRegex(repr(lock),"<unlocked .* object (.*)?at .*>")

‎Lib/test/test_threading.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2137,8 +2137,7 @@ def test_signature(self): # gh-102029
21372137
]
21382138
forargs,kwargsinarg_types:
21392139
withself.subTest(args=args,kwargs=kwargs):
2140-
withself.assertWarns(DeprecationWarning):
2141-
threading.RLock(*args,**kwargs)
2140+
self.assertRaises(TypeError,threading.RLock,*args,**kwargs)
21422141

21432142
# Subtypes with custom `__init__` are allowed (but, not recommended):
21442143
classCustomRLock(self.locktype):
@@ -2156,6 +2155,9 @@ class ConditionAsRLockTests(lock_tests.RLockTests):
21562155
# Condition uses an RLock by default and exports its API.
21572156
locktype=staticmethod(threading.Condition)
21582157

2158+
deftest_constructor_noargs(self):
2159+
self.skipTest("Condition allows positional arguments")
2160+
21592161
deftest_recursion_count(self):
21602162
self.skipTest("Condition does not expose _recursion_count()")
21612163

‎Lib/threading.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ def gettrace():
123123

124124
Lock=_LockType
125125

126-
defRLock(*args,**kwargs):
126+
defRLock():
127127
"""Factory function that returns a new reentrant lock.
128128
129129
A reentrant lock must be released by the thread that acquired it. Once a
@@ -132,16 +132,9 @@ def RLock(*args, **kwargs):
132132
acquired it.
133133
134134
"""
135-
ifargsorkwargs:
136-
importwarnings
137-
warnings.warn(
138-
'Passing arguments to RLock is deprecated and will be removed in 3.15',
139-
DeprecationWarning,
140-
stacklevel=2,
141-
)
142135
if_CRLockisNone:
143-
return_PyRLock(*args,**kwargs)
144-
return_CRLock(*args,**kwargs)
136+
return_PyRLock()
137+
return_CRLock()
145138

146139
class_RLock:
147140
"""This class implements reentrant lock objects.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Remove support for arbitrary positional or keyword arguments in the C
2+
implementation of:class:`threading.RLock` objects. This was deprecated
3+
since Python 3.14. Patch by Bénédikt Tran.

‎Modules/_threadmodule.c

Lines changed: 43 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
# include<signal.h>// SIGINT
2020
#endif
2121

22-
#include"clinic/_threadmodule.c.h"
23-
2422
// ThreadError is just an alias to PyExc_RuntimeError
2523
#defineThreadError PyExc_RuntimeError
2624

@@ -31,6 +29,7 @@ static struct PyModuleDef thread_module;
3129
typedefstruct {
3230
PyTypeObject*excepthook_type;
3331
PyTypeObject*lock_type;
32+
PyTypeObject*rlock_type;
3433
PyTypeObject*local_type;
3534
PyTypeObject*local_dummy_type;
3635
PyTypeObject*thread_handle_type;
@@ -48,6 +47,17 @@ get_thread_state(PyObject *module)
4847
return (thread_module_state*)state;
4948
}
5049

50+
staticinlinethread_module_state*
51+
get_thread_state_by_cls(PyTypeObject*cls)
52+
{
53+
// Use PyType_GetModuleByDef() to handle (R)Lock subclasses.
54+
PyObject*module=PyType_GetModuleByDef(cls,&thread_module);
55+
if (module==NULL) {
56+
returnNULL;
57+
}
58+
returnget_thread_state(module);
59+
}
60+
5161

5262
#ifdefMS_WINDOWS
5363
typedefHRESULT (WINAPI*PF_GET_THREAD_DESCRIPTION)(HANDLE,PCWSTR*);
@@ -59,9 +69,14 @@ static PF_SET_THREAD_DESCRIPTION pSetThreadDescription = NULL;
5969

6070
/*[clinic input]
6171
module _thread
72+
class _thread.lock "lockobject *" "clinic_state()->lock_type"
73+
class _thread.RLock "rlockobject *" "clinic_state()->rlock_type"
6274
[clinic start generated code]*/
63-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=be8dbe5cc4b16df7]*/
75+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=c5a0f8c492a0c263]*/
6476

77+
#defineclinic_state() get_thread_state_by_cls(type)
78+
#include"clinic/_threadmodule.c.h"
79+
#undef clinic_state
6580

6681
// _ThreadHandle type
6782

@@ -916,25 +931,21 @@ lock__at_fork_reinit(PyObject *op, PyObject *Py_UNUSED(dummy))
916931
}
917932
#endif/* HAVE_FORK */
918933

919-
staticlockobject*newlockobject(PyObject*module);
934+
/*[clinic input]
935+
@classmethod
936+
_thread.lock.__new__ as lock_new
937+
[clinic start generated code]*/
920938

921939
staticPyObject*
922-
lock_new(PyTypeObject*type,PyObject*args,PyObject*kwargs)
940+
lock_new_impl(PyTypeObject*type)
941+
/*[clinic end generated code: output=eab660d5a4c05c8a input=260208a4e277d250]*/
923942
{
924-
// convert to AC?
925-
if (!_PyArg_NoKeywords("lock",kwargs)) {
926-
gotoerror;
927-
}
928-
if (!_PyArg_CheckPositional("lock",PyTuple_GET_SIZE(args),0,0)) {
929-
gotoerror;
943+
lockobject*self= (lockobject*)type->tp_alloc(type,0);
944+
if (self==NULL) {
945+
returnNULL;
930946
}
931-
932-
PyObject*module=PyType_GetModuleByDef(type,&thread_module);
933-
assert(module!=NULL);
934-
return (PyObject*)newlockobject(module);
935-
936-
error:
937-
returnNULL;
947+
self->lock= (PyMutex){0};
948+
return (PyObject*)self;
938949
}
939950

940951

@@ -1186,8 +1197,14 @@ PyDoc_STRVAR(rlock_is_owned_doc,
11861197
\n\
11871198
For internal use by `threading.Condition`.");
11881199

1200+
/*[clinic input]
1201+
@classmethod
1202+
_thread.RLock.__new__ as rlock_new
1203+
[clinic start generated code]*/
1204+
11891205
staticPyObject*
1190-
rlock_new(PyTypeObject*type,PyObject*args,PyObject*kwds)
1206+
rlock_new_impl(PyTypeObject*type)
1207+
/*[clinic end generated code: output=bb4fb1edf6818df5 input=013591361bf1ac6e]*/
11911208
{
11921209
rlockobject*self= (rlockobject*)type->tp_alloc(type,0);
11931210
if (self==NULL) {
@@ -1267,20 +1284,6 @@ static PyType_Spec rlock_type_spec = {
12671284
.slots=rlock_type_slots,
12681285
};
12691286

1270-
staticlockobject*
1271-
newlockobject(PyObject*module)
1272-
{
1273-
thread_module_state*state=get_thread_state(module);
1274-
1275-
PyTypeObject*type=state->lock_type;
1276-
lockobject*self= (lockobject*)type->tp_alloc(type,0);
1277-
if (self==NULL) {
1278-
returnNULL;
1279-
}
1280-
self->lock= (PyMutex){0};
1281-
returnself;
1282-
}
1283-
12841287
/* Thread-local objects */
12851288

12861289
/* Quick overview:
@@ -2035,7 +2038,8 @@ Note: the default signal handler for SIGINT raises ``KeyboardInterrupt``."
20352038
staticPyObject*
20362039
thread_PyThread_allocate_lock(PyObject*module,PyObject*Py_UNUSED(ignored))
20372040
{
2038-
return (PyObject*)newlockobject(module);
2041+
thread_module_state*state=get_thread_state(module);
2042+
returnlock_new_impl(state->lock_type);
20392043
}
20402044

20412045
PyDoc_STRVAR(allocate_lock_doc,
@@ -2645,15 +2649,13 @@ thread_module_exec(PyObject *module)
26452649
}
26462650

26472651
// RLock
2648-
PyTypeObject*rlock_type= (PyTypeObject*)PyType_FromSpec(&rlock_type_spec);
2649-
if (rlock_type==NULL) {
2652+
state->rlock_type= (PyTypeObject*)PyType_FromModuleAndSpec(module,&rlock_type_spec,NULL);
2653+
if (state->rlock_type==NULL) {
26502654
return-1;
26512655
}
2652-
if (PyModule_AddType(module,rlock_type)<0) {
2653-
Py_DECREF(rlock_type);
2656+
if (PyModule_AddType(module,state->rlock_type)<0) {
26542657
return-1;
26552658
}
2656-
Py_DECREF(rlock_type);
26572659

26582660
// Local dummy
26592661
state->local_dummy_type= (PyTypeObject*)PyType_FromSpec(&local_dummy_type_spec);
@@ -2740,6 +2742,7 @@ thread_module_traverse(PyObject *module, visitproc visit, void *arg)
27402742
thread_module_state*state=get_thread_state(module);
27412743
Py_VISIT(state->excepthook_type);
27422744
Py_VISIT(state->lock_type);
2745+
Py_VISIT(state->rlock_type);
27432746
Py_VISIT(state->local_type);
27442747
Py_VISIT(state->local_dummy_type);
27452748
Py_VISIT(state->thread_handle_type);
@@ -2752,6 +2755,7 @@ thread_module_clear(PyObject *module)
27522755
thread_module_state*state=get_thread_state(module);
27532756
Py_CLEAR(state->excepthook_type);
27542757
Py_CLEAR(state->lock_type);
2758+
Py_CLEAR(state->rlock_type);
27552759
Py_CLEAR(state->local_type);
27562760
Py_CLEAR(state->local_dummy_type);
27572761
Py_CLEAR(state->thread_handle_type);

‎Modules/clinic/_threadmodule.c.h

Lines changed: 48 additions & 2 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp