Skip to content

Commit 84121e4

Browse files
cmaloneyclaude
andcommitted
pythongh-87613: Use the AC vectorcall for bytes and bytearray
Neither type had a tp_vectorcall before, so every bytes() and bytearray() call went through _PyObject_MakeTpCall(): an args tuple (plus a kwargs dict for keyword calls) built on the way in to type_call(). Add @vectorcall to bytes.__new__ and bytearray.__init__ and install the generated parsers in the two type objects. bytearray is the first non-test type to use the @vectorcall __init__ path, which allocates through tp_new and then calls the __init__ impl, so bytearray_new() still installs ob_bytes_object. Error messages are unchanged: both types are positional-or-keyword only, so the generated vectorcall handles up to three positional arguments inline and hands everything else (keywords, too many arguments) to the same helper the tp_new/tp_init slot uses. Extend the vectorcall slot-parity test to cover both. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent ab0b393 commit 84121e4

5 files changed

Lines changed: 187 additions & 16 deletions

File tree

‎Lib/test/test_clinic.py‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5592,12 +5592,15 @@ def through_new(cls):
55925592
return cls, partial(cls.__new__, cls)
55935593

55945594
def through_init(cls):
5595-
# Not subclassable, and tp_new is PyType_GenericNew, so reach
5596-
# tp_init through the __init__ slot wrapper on an instance.
5595+
# tp_new is PyType_GenericNew (or does no argument parsing), so
5596+
# reach tp_init through the __init__ slot wrapper on an instance.
55975597
return cls, partial(cls.__init__, cls(1))
55985598

55995599
entry_points = [
5600-
through_new(enumerate), # the only non-test @vectorcall function
5600+
# Non-test @vectorcall functions.
5601+
through_new(enumerate),
5602+
through_new(bytes),
5603+
through_init(bytearray),
56015604
through_new(ac_tester.VcNew),
56025605
through_new(ac_tester.VcNewBase),
56035606
through_new(ac_tester.VcKwOnly),

‎Objects/bytearrayobject.c‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -978,6 +978,7 @@ bytearray_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
978978
}
979979

980980
/*[clinic input]
981+
@vectorcall
981982
bytearray.__init__
982983
983984
source as arg: object = NULL
@@ -989,7 +990,7 @@ bytearray.__init__
989990
static int
990991
bytearray___init___impl(PyByteArrayObject *self, PyObject *arg,
991992
const char *encoding, const char *errors)
992-
/*[clinic end generated code: output=4ce1304649c2f8b3 input=1141a7122eefd7b9]*/
993+
/*[clinic end generated code: output=4ce1304649c2f8b3 input=24ddb84055f432dd]*/
993994
{
994995
Py_ssize_t count;
995996
PyObject *it;
@@ -3015,6 +3016,7 @@ PyTypeObject PyByteArray_Type = {
30153016
PyType_GenericAlloc, /* tp_alloc */
30163017
bytearray_new, /* tp_new */
30173018
PyObject_Free, /* tp_free */
3019+
.tp_vectorcall = bytearray_vectorcall,
30183020
.tp_version_tag = _Py_TYPE_VERSION_BYTEARRAY,
30193021
};
30203022

‎Objects/bytesobject.c‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2879,6 +2879,7 @@ static PyObject *
28792879
bytes_subtype_new(PyTypeObject *, PyObject *);
28802880

28812881
/*[clinic input]
2882+
@vectorcall
28822883
@classmethod
28832884
bytes.__new__ as bytes_new
28842885
@@ -2891,7 +2892,7 @@ bytes.__new__ as bytes_new
28912892
static PyObject *
28922893
bytes_new_impl(PyTypeObject *type, PyObject *x, const char *encoding,
28932894
const char *errors)
2894-
/*[clinic end generated code: output=1e0c471be311a425 input=f0a966d19b7262b4]*/
2895+
/*[clinic end generated code: output=1e0c471be311a425 input=b0248d22e221a095]*/
28952896
{
28962897
PyObject *bytes;
28972898
PyObject *func;
@@ -3277,6 +3278,7 @@ PyTypeObject PyBytes_Type = {
32773278
bytes_alloc, /* tp_alloc */
32783279
bytes_new, /* tp_new */
32793280
PyObject_Free, /* tp_free */
3281+
.tp_vectorcall = bytes_vectorcall,
32803282
.tp_version_tag = _Py_TYPE_VERSION_BYTES,
32813283
._tp_iteritem = bytes_iteritem,
32823284
};

‎Objects/clinic/bytearrayobject.c.h‎

Lines changed: 99 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Objects/clinic/bytesobject.c.h‎

Lines changed: 76 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)