https://github.com/python/cpython/commit/fe70b069174e7dc83da14c37f0a45b424630fbb5
commit: fe70b069174e7dc83da14c37f0a45b424630fbb5
branch: main
author: Peter Bierma <[email protected]>
committer: ZeroIntensity <[email protected]>
date: 2026-10-21T20:17:22Z
summary:
gh-114258: Use Argument Clinic for `__mul__`/`__imul__` (GH-160049)
files:
M Modules/_collectionsmodule.c
M Modules/clinic/_collectionsmodule.c.h
M Objects/bytearrayobject.c
M Objects/clinic/bytearrayobject.c.h
M Objects/clinic/listobject.c.h
M Objects/listobject.c
M Tools/clinic/libclinic/dsl_parser.py
M Tools/clinic/libclinic/slots.py
diff --git a/Modules/_collectionsmodule.c b/Modules/_collectionsmodule.c
index 5a68a9ede44a6a..64f8fa9ab4041f 100644
--- a/Modules/_collectionsmodule.c
+++ b/Modules/_collectionsmodule.c
@@ -819,8 +819,18 @@ deque_clearmethod_impl(dequeobject *deque)
Py_RETURN_NONE;
}
+/*[clinic input]
+@critical_section
+_collections.deque.__imul__ as deque_inplace_repeat
+
+ deque: dequeobject
+ n: Py_ssize_t
+ /
+[clinic start generated code]*/
+
static PyObject *
-deque_inplace_repeat_lock_held(dequeobject *deque, Py_ssize_t n)
+deque_inplace_repeat_impl(dequeobject *deque, Py_ssize_t n)
+/*[clinic end generated code: output=e9052495a8eb46f9 input=0ebbaedad03b8abf]*/
{
Py_ssize_t i, m, size;
PyObject *seq;
@@ -896,17 +906,6 @@ deque_inplace_repeat_lock_held(dequeobject *deque,
Py_ssize_t n)
return (PyObject *)deque;
}
-static PyObject *
-deque_inplace_repeat(PyObject *self, Py_ssize_t n)
-{
- dequeobject *deque = dequeobject_CAST(self);
- PyObject *result;
- Py_BEGIN_CRITICAL_SECTION(deque);
- result = deque_inplace_repeat_lock_held(deque, n);
- Py_END_CRITICAL_SECTION();
- return result;
-}
-
static PyObject *
deque_repeat(PyObject *self, Py_ssize_t n)
{
@@ -921,7 +920,7 @@ deque_repeat(PyObject *self, Py_ssize_t n)
return NULL;
// It's safe to not acquire the per-object lock for new_deque; it's
// invisible to other threads.
- rv = deque_inplace_repeat_lock_held(new_deque, n);
+ rv = deque_inplace_repeat_impl(new_deque, n);
Py_DECREF(new_deque);
return rv;
}
diff --git a/Modules/clinic/_collectionsmodule.c.h
b/Modules/clinic/_collectionsmodule.c.h
index b179555f987361..cef17347078fe4 100644
--- a/Modules/clinic/_collectionsmodule.c.h
+++ b/Modules/clinic/_collectionsmodule.c.h
@@ -226,6 +226,21 @@ deque_clearmethod(PyObject *deque, PyObject
*Py_UNUSED(ignored))
return return_value;
}
+static PyObject *
+deque_inplace_repeat_impl(dequeobject *deque, Py_ssize_t n);
+
+static PyObject *
+deque_inplace_repeat(PyObject *deque, Py_ssize_t n)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(deque);
+ return_value = deque_inplace_repeat_impl((dequeobject *)deque, n);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
PyDoc_STRVAR(deque_rotate__doc__,
"rotate($self, n=1, /)\n"
"--\n"
@@ -647,4 +662,4 @@ tuplegetter_new(PyTypeObject *type, PyObject *args,
PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=1bdec9485a9d40fb input=a9049054013a1b77]*/
+/*[clinic end generated code: output=fe575846d0131efd input=a9049054013a1b77]*/
diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c
index 61077866872bcd..5abd0fd235f030 100644
--- a/Objects/bytearrayobject.c
+++ b/Objects/bytearrayobject.c
@@ -442,11 +442,19 @@ bytearray_iconcat(PyObject *op, PyObject *other)
return ret;
}
+/*[clinic input]
+@critical_section
+bytearray.__mul__ as bytearray_repeat
+
+ count: Py_ssize_t
+ /
+[clinic start generated code]*/
+
static PyObject *
-bytearray_repeat_lock_held(PyObject *op, Py_ssize_t count)
+bytearray_repeat_impl(PyByteArrayObject *self, Py_ssize_t count)
+/*[clinic end generated code: output=0889e9ebbe61890a input=3363528e6db1f39b]*/
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
- PyByteArrayObject *self = _PyByteArray_CAST(op);
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
if (count < 0) {
count = 0;
}
@@ -464,21 +472,19 @@ bytearray_repeat_lock_held(PyObject *op, Py_ssize_t count)
return (PyObject *)result;
}
-static PyObject *
-bytearray_repeat(PyObject *op, Py_ssize_t count)
-{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = bytearray_repeat_lock_held(op, count);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
+/*[clinic input]
+@critical_section
+bytearray.__imul__ as bytearray_irepeat
+
+ count: Py_ssize_t
+ /
+[clinic start generated code]*/
static PyObject *
-bytearray_irepeat_lock_held(PyObject *op, Py_ssize_t count)
+bytearray_irepeat_impl(PyByteArrayObject *self, Py_ssize_t count)
+/*[clinic end generated code: output=4cfee919b3489219 input=e12991c89153490b]*/
{
- _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
- PyByteArrayObject *self = _PyByteArray_CAST(op);
+ _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
if (count < 0) {
count = 0;
}
@@ -501,16 +507,6 @@ bytearray_irepeat_lock_held(PyObject *op, Py_ssize_t count)
return Py_NewRef(self);
}
-static PyObject *
-bytearray_irepeat(PyObject *op, Py_ssize_t count)
-{
- PyObject *ret;
- Py_BEGIN_CRITICAL_SECTION(op);
- ret = bytearray_irepeat_lock_held(op, count);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
-
static PyObject *
bytearray_getitem_lock_held(PyObject *op, Py_ssize_t i)
{
diff --git a/Objects/clinic/bytearrayobject.c.h
b/Objects/clinic/bytearrayobject.c.h
index 451308d99112a1..a41866b40f8055 100644
--- a/Objects/clinic/bytearrayobject.c.h
+++ b/Objects/clinic/bytearrayobject.c.h
@@ -11,6 +11,36 @@ preserve
#include "pycore_runtime.h" // _Py_SINGLETON()
#include "pycore_unicodeobject.h" // _PyUnicode_AsUTF8NoNUL()
+static PyObject *
+bytearray_repeat_impl(PyByteArrayObject *self, Py_ssize_t count);
+
+static PyObject *
+bytearray_repeat(PyObject *self, Py_ssize_t count)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_repeat_impl((PyByteArrayObject *)self, count);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+static PyObject *
+bytearray_irepeat_impl(PyByteArrayObject *self, Py_ssize_t count);
+
+static PyObject *
+bytearray_irepeat(PyObject *self, Py_ssize_t count)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = bytearray_irepeat_impl((PyByteArrayObject *)self, count);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
static int
bytearray_setitem_impl(PyByteArrayObject *self, Py_ssize_t i,
PyObject *value);
@@ -1977,4 +2007,4 @@ bytearray_sizeof(PyObject *self, PyObject
*Py_UNUSED(ignored))
{
return bytearray_sizeof_impl((PyByteArrayObject *)self);
}
-/*[clinic end generated code: output=5cfb062cb3307f31 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=a1a91ef777ab985f input=a9049054013a1b77]*/
diff --git a/Objects/clinic/listobject.c.h b/Objects/clinic/listobject.c.h
index 787f575a1ac272..359b9c20269447 100644
--- a/Objects/clinic/listobject.c.h
+++ b/Objects/clinic/listobject.c.h
@@ -25,6 +25,36 @@ list_repr(PyObject *v)
return return_value;
}
+static PyObject *
+list_repeat_impl(PyListObject *a, Py_ssize_t n);
+
+static PyObject *
+list_repeat(PyObject *a, Py_ssize_t n)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(a);
+ return_value = list_repeat_impl((PyListObject *)a, n);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
+static PyObject *
+list_inplace_repeat_impl(PyListObject *self, Py_ssize_t n);
+
+static PyObject *
+list_inplace_repeat(PyObject *self, Py_ssize_t n)
+{
+ PyObject *return_value = NULL;
+
+ Py_BEGIN_CRITICAL_SECTION(self);
+ return_value = list_inplace_repeat_impl((PyListObject *)self, n);
+ Py_END_CRITICAL_SECTION();
+
+ return return_value;
+}
+
static int
list_ass_item_impl(PyListObject *a, Py_ssize_t i, PyObject *v);
@@ -498,4 +528,4 @@ list___reversed__(PyObject *self, PyObject
*Py_UNUSED(ignored))
{
return list___reversed___impl((PyListObject *)self);
}
-/*[clinic end generated code: output=c7ed86d2a453ec78 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=9eab9551fc4cea1c input=a9049054013a1b77]*/
diff --git a/Objects/listobject.c b/Objects/listobject.c
index fa251923dfd495..5ca8cdf09d3160 100644
--- a/Objects/listobject.c
+++ b/Objects/listobject.c
@@ -869,8 +869,18 @@ _PyList_Concat(PyObject *aa, PyObject *bb)
return ret;
}
+/*[clinic input]
+@critical_section
+list.__mul__ as list_repeat
+
+ a: self(type="PyListObject *")
+ n: Py_ssize_t
+ /
+[clinic start generated code]*/
+
static PyObject *
-list_repeat_lock_held(PyListObject *a, Py_ssize_t n)
+list_repeat_impl(PyListObject *a, Py_ssize_t n)
+/*[clinic end generated code: output=65bb40ed76d3e733 input=dfef16e067b2abb6]*/
{
const Py_ssize_t input_size = Py_SIZE(a);
if (input_size == 0 || n <= 0)
@@ -911,17 +921,6 @@ list_repeat_lock_held(PyListObject *a, Py_ssize_t n)
return (PyObject *) np;
}
-static PyObject *
-list_repeat(PyObject *aa, Py_ssize_t n)
-{
- PyObject *ret;
- PyListObject *a = (PyListObject *)aa;
- Py_BEGIN_CRITICAL_SECTION(a);
- ret = list_repeat_lock_held(a, n);
- Py_END_CRITICAL_SECTION();
- return ret;
-}
-
static void
list_clear_impl(PyListObject *a, bool is_resize)
{
@@ -1171,20 +1170,22 @@ list_inplace_repeat_lock_held(PyListObject *self,
Py_ssize_t n)
return 0;
}
+/*[clinic input]
+@critical_section
+list.__imul__ as list_inplace_repeat
+
+ n: Py_ssize_t
+ /
+[clinic start generated code]*/
+
static PyObject *
-list_inplace_repeat(PyObject *_self, Py_ssize_t n)
+list_inplace_repeat_impl(PyListObject *self, Py_ssize_t n)
+/*[clinic end generated code: output=d318a9f047b4fcaf input=530d74de0e4a61f0]*/
{
- PyObject *ret;
- PyListObject *self = (PyListObject *) _self;
- Py_BEGIN_CRITICAL_SECTION(self);
if (list_inplace_repeat_lock_held(self, n) < 0) {
- ret = NULL;
- }
- else {
- ret = Py_NewRef(self);
+ return NULL;
}
- Py_END_CRITICAL_SECTION();
- return ret;
+ return Py_NewRef(self);
}
/*[clinic input]
diff --git a/Tools/clinic/libclinic/dsl_parser.py
b/Tools/clinic/libclinic/dsl_parser.py
index a52cd92ed7f78f..f40b17408ba1eb 100644
--- a/Tools/clinic/libclinic/dsl_parser.py
+++ b/Tools/clinic/libclinic/dsl_parser.py
@@ -60,7 +60,6 @@
__ilshift__
__imatmul__
__imod__
-__imul__
__index__
__int__
__invert__
@@ -76,7 +75,6 @@
__lt__
__matmul__
__mod__
-__mul__
__neg__
__or__
__pos__
diff --git a/Tools/clinic/libclinic/slots.py b/Tools/clinic/libclinic/slots.py
index 0e2a04f9812634..4c14959d3598f0 100644
--- a/Tools/clinic/libclinic/slots.py
+++ b/Tools/clinic/libclinic/slots.py
@@ -40,6 +40,8 @@ def make_return_converter(self) -> CReturnConverter:
SLOTS: Final[dict[str, SlotSpec]] = {
'__next__': SlotSpec(return_converter='object'),
'__len__': SlotSpec(return_converter='Py_ssize_t'),
+ '__mul__': SlotSpec(return_converter='object'),
+ '__imul__': SlotSpec(return_converter='object'),
'__repr__': SlotSpec(return_converter='object'),
'__setitem__': SlotSpec(return_converter='int'),
}
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]