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
This repository was archived by the owner on Feb 13, 2025. It is now read-only.

Commit 1f4aaa3

Browse files
author
Anselm Kruis
committed
Merge branch main into main-slp
Header slp_exttype.h was recreated.
2 parents 37b6a87 + fb9423f commit 1f4aaa3

File tree

5 files changed

+52
-17
lines changed

5 files changed

+52
-17
lines changed

‎Include/cpython/slp_exttype.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ typedef struct _slp_methodflags {
6161
signed char bf_releasebuffer;
6262
signed char tp_dealloc;
6363
signed char tp_repr;
64+
signed char tp_vectorcall_offset;
6465
signed char tp_call;
6566
signed char tp_str;
6667
signed char tp_iter;

‎Lib/test/test_capi.py

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -515,9 +515,10 @@ def test_vectorcall_override(self):
515515

516516
def test_vectorcall(self):
517517
# Test a bunch of different ways to call objects:
518-
# 1. normal call
519-
# 2. vectorcall using _PyObject_Vectorcall()
520-
# 3. vectorcall using PyVectorcall_Call()
518+
# 1. vectorcall using PyVectorcall_Call()
519+
# (only for objects that support vectorcall directly)
520+
# 2. normal call
521+
# 3. vectorcall using _PyObject_Vectorcall()
521522
# 4. call as bound method
522523
# 5. call using functools.partial
523524

@@ -541,6 +542,27 @@ def vectorcall(func, args, kwargs):
541542
kwnames = tuple(kwargs)
542543
return pyobject_vectorcall(func, args, kwnames)
543544

545+
for (func, args, kwargs, expected) in calls:
546+
with self.subTest(str(func)):
547+
if not kwargs:
548+
self.assertEqual(expected, pyvectorcall_call(func, args))
549+
self.assertEqual(expected, pyvectorcall_call(func, args, kwargs))
550+
551+
# Add derived classes (which do not support vectorcall directly,
552+
# but do support all other ways of calling).
553+
554+
class MethodDescriptorHeap(_testcapi.MethodDescriptorBase):
555+
pass
556+
557+
class MethodDescriptorOverridden(_testcapi.MethodDescriptorBase):
558+
def __call__(self, n):
559+
return 'new'
560+
561+
calls += [
562+
(MethodDescriptorHeap(), (0,), {}, True),
563+
(MethodDescriptorOverridden(), (0,), {}, 'new'),
564+
]
565+
544566
for (func, args, kwargs, expected) in calls:
545567
with self.subTest(str(func)):
546568
args1 = args[1:]
@@ -549,12 +571,10 @@ def vectorcall(func, args, kwargs):
549571
if not kwargs:
550572
self.assertEqual(expected, func(*args))
551573
self.assertEqual(expected, pyobject_vectorcall(func, args, None))
552-
self.assertEqual(expected, pyvectorcall_call(func, args))
553574
self.assertEqual(expected, meth(*args1))
554575
self.assertEqual(expected, wrapped(*args))
555576
self.assertEqual(expected, func(*args, **kwargs))
556577
self.assertEqual(expected, vectorcall(func, args, kwargs))
557-
self.assertEqual(expected, pyvectorcall_call(func, args, kwargs))
558578
self.assertEqual(expected, meth(*args1, **kwargs))
559579
self.assertEqual(expected, wrapped(*args, **kwargs))
560580

‎Modules/_testcapimodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5854,7 +5854,7 @@ MethodDescriptor_vectorcall(PyObject *callable, PyObject *const *args,
58545854
static PyObject *
58555855
MethodDescriptor_new(PyTypeObject* type, PyObject* args, PyObject *kw)
58565856
{
5857-
MethodDescriptorObject *op = PyObject_New(MethodDescriptorObject, type);
5857+
MethodDescriptorObject *op = type->tp_alloc(type, 0);
58585858
op->vectorcall = MethodDescriptor_vectorcall;
58595859
return (PyObject *)op;
58605860
}

‎Objects/call.c

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,22 @@ PyObject *
185185
PyVectorcall_Call(PyObject *callable, PyObject *tuple, PyObject *kwargs)
186186
{
187187
STACKLESS_GETARG();
188-
vectorcallfunc func = _PyVectorcall_Function(callable);
188+
/* get vectorcallfunc as in _PyVectorcall_Function, but without
189+
* the _Py_TPFLAGS_HAVE_VECTORCALL check */
190+
Py_ssize_t offset = Py_TYPE(callable)->tp_vectorcall_offset;
191+
if ((offset <= 0) || (!Py_TYPE(callable)->tp_call)) {
192+
PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall",
193+
Py_TYPE(callable)->tp_name);
194+
return NULL;
195+
}
196+
vectorcallfunc func = *(vectorcallfunc *)(((char *)callable) + offset);
189197
if (func == NULL) {
190198
PyErr_Format(PyExc_TypeError, "'%.200s' object does not support vectorcall",
191199
Py_TYPE(callable)->tp_name);
192200
return NULL;
193201
}
202+
203+
/* Convert arguments & call */
194204
PyObject *const *args;
195205
Py_ssize_t nargs = PyTuple_GET_SIZE(tuple);
196206
PyObject *kwnames;

‎Objects/typeobject.c

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5237,17 +5237,21 @@ inherit_slots(PyTypeObject *type, PyTypeObject *base)
52375237
}
52385238
COPYSLOT(tp_repr);
52395239
/* tp_hash see tp_richcompare */
5240-
COPYSLOT(tp_call);
5241-
/* Inherit tp_vectorcall_offset and _Py_TPFLAGS_HAVE_VECTORCALL if tp_call
5242-
* was inherited, but only for extension types */
5243-
if ((base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
5244-
!(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
5245-
!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) &&
5246-
base->tp_call &&
5247-
type->tp_call == base->tp_call)
52485240
{
5249-
type->tp_vectorcall_offset = base->tp_vectorcall_offset;
5250-
type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL;
5241+
/* Inherit tp_vectorcall_offset only if tp_call is not overridden */
5242+
if (!type->tp_call) {
5243+
COPYSLOT(tp_vectorcall_offset);
5244+
}
5245+
/* Inherit_Py_TPFLAGS_HAVE_VECTORCALL for non-heap types
5246+
* if tp_call is not overridden */
5247+
if (!type->tp_call &&
5248+
(base->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
5249+
!(type->tp_flags & _Py_TPFLAGS_HAVE_VECTORCALL) &&
5250+
!(type->tp_flags & Py_TPFLAGS_HEAPTYPE))
5251+
{
5252+
type->tp_flags |= _Py_TPFLAGS_HAVE_VECTORCALL;
5253+
}
5254+
COPYSLOT(tp_call);
52515255
}
52525256
COPYSLOT(tp_str);
52535257
{

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /