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]

Reply via email to