Skip to content

Commit 762f93f

Browse files
jdemeyermethane
authored andcommitted
bpo-37337: Add _PyObject_CallMethodNoArgs() (GH-14267)
1 parent 38f44b4 commit 762f93f

37 files changed

+154
-132
lines changed

Doc/c-api/object.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,17 @@ Object Protocol
364364
*NULL* on failure.
365365
366366
367+
.. c:function:: PyObject* _PyObject_CallMethodNoArgs(PyObject *obj, PyObject *name)
368+
369+
Call a method of the Python object *obj* without arguments,
370+
where the name of the method is given as a Python string object in *name*.
371+
372+
Return the result of the call on success, or raise an exception and return
373+
*NULL* on failure.
374+
375+
.. versionadded:: 3.9
376+
377+
367378
.. c:function:: PyObject* _PyObject_Vectorcall(PyObject *callable, PyObject *const *args, size_t nargsf, PyObject *kwnames)
368379
369380
Call a callable Python object *callable*, using

Include/cpython/abstract.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,13 @@ PyAPI_FUNC(PyObject *) _PyObject_VectorcallMethod(
156156
PyObject *name, PyObject *const *args,
157157
size_t nargsf, PyObject *kwnames);
158158

159+
static inline PyObject *
160+
_PyObject_CallMethodNoArgs(PyObject *self, PyObject *name)
161+
{
162+
return _PyObject_VectorcallMethod(name, &self,
163+
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
164+
}
165+
159166
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
160167
as the method name. */
161168
PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
@@ -184,6 +191,13 @@ _PyObject_VectorcallMethodId(
184191
return _PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
185192
}
186193

194+
static inline PyObject *
195+
_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
196+
{
197+
return _PyObject_VectorcallMethodId(name, &self,
198+
1 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
199+
}
200+
187201
PyAPI_FUNC(int) _PyObject_HasLen(PyObject *o);
188202

189203
/* Guess the size of object 'o' using len(o) or o.__length_hint__().
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
Add :c:func:`_PyObject_VectorcallMethod` for fast calling of methods.
1+
Add fast functions for calling methods: :c:func:`_PyObject_VectorcallMethod`
2+
and :c:func:`_PyObject_CallMethodNoArgs`

Modules/_asynciomodule.c

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ get_event_loop(void)
332332
return NULL;
333333
}
334334

335-
loop = _PyObject_CallMethodId(policy, &PyId_get_event_loop, NULL);
335+
loop = _PyObject_CallMethodIdNoArgs(policy, &PyId_get_event_loop);
336336
Py_DECREF(policy);
337337
return loop;
338338
}
@@ -493,7 +493,7 @@ future_init(FutureObj *fut, PyObject *loop)
493493
}
494494
fut->fut_loop = loop;
495495

496-
res = _PyObject_CallMethodId(fut->fut_loop, &PyId_get_debug, NULL);
496+
res = _PyObject_CallMethodIdNoArgs(fut->fut_loop, &PyId_get_debug);
497497
if (res == NULL) {
498498
return -1;
499499
}
@@ -1295,9 +1295,8 @@ FutureObj_repr(FutureObj *fut)
12951295

12961296
ENSURE_FUTURE_ALIVE(fut)
12971297

1298-
PyObject *rinfo = _PyObject_CallMethodIdObjArgs((PyObject*)fut,
1299-
&PyId__repr_info,
1300-
NULL);
1298+
PyObject *rinfo = _PyObject_CallMethodIdNoArgs((PyObject*)fut,
1299+
&PyId__repr_info);
13011300
if (rinfo == NULL) {
13021301
return NULL;
13031302
}
@@ -2197,8 +2196,7 @@ _asyncio_Task_cancel_impl(TaskObj *self)
21972196
PyObject *res;
21982197
int is_true;
21992198

2200-
res = _PyObject_CallMethodId(
2201-
self->task_fut_waiter, &PyId_cancel, NULL);
2199+
res = _PyObject_CallMethodIdNoArgs(self->task_fut_waiter, &PyId_cancel);
22022200
if (res == NULL) {
22032201
return NULL;
22042202
}
@@ -2735,7 +2733,7 @@ task_step_impl(TaskObj *task, PyObject *exc)
27352733
if (task->task_must_cancel) {
27362734
PyObject *r;
27372735
int is_true;
2738-
r = _PyObject_CallMethodId(result, &PyId_cancel, NULL);
2736+
r = _PyObject_CallMethodIdNoArgs(result, &PyId_cancel);
27392737
if (r == NULL) {
27402738
return NULL;
27412739
}
@@ -2826,7 +2824,7 @@ task_step_impl(TaskObj *task, PyObject *exc)
28262824
if (task->task_must_cancel) {
28272825
PyObject *r;
28282826
int is_true;
2829-
r = _PyObject_CallMethodId(result, &PyId_cancel, NULL);
2827+
r = _PyObject_CallMethodIdNoArgs(result, &PyId_cancel);
28302828
if (r == NULL) {
28312829
return NULL;
28322830
}

Modules/_collectionsmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2039,7 +2039,7 @@ defdict_reduce(defdictobject *dd, PyObject *Py_UNUSED(ignored))
20392039
args = PyTuple_Pack(1, dd->default_factory);
20402040
if (args == NULL)
20412041
return NULL;
2042-
items = _PyObject_CallMethodId((PyObject *)dd, &PyId_items, NULL);
2042+
items = _PyObject_CallMethodIdNoArgs((PyObject *)dd, &PyId_items);
20432043
if (items == NULL) {
20442044
Py_DECREF(args);
20452045
return NULL;

Modules/_ctypes/_ctypes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3974,7 +3974,7 @@ _build_result(PyObject *result, PyObject *callargs,
39743974
_Py_IDENTIFIER(__ctypes_from_outparam__);
39753975

39763976
v = PyTuple_GET_ITEM(callargs, i);
3977-
v = _PyObject_CallMethodId(v, &PyId___ctypes_from_outparam__, NULL);
3977+
v = _PyObject_CallMethodIdNoArgs(v, &PyId___ctypes_from_outparam__);
39783978
if (v == NULL || numretvals == 1) {
39793979
Py_DECREF(callargs);
39803980
return v;

Modules/_cursesmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2906,7 +2906,7 @@ _curses_getwin(PyObject *module, PyObject *file)
29062906
if (_Py_set_inheritable(fileno(fp), 0, NULL) < 0)
29072907
goto error;
29082908

2909-
data = _PyObject_CallMethodId(file, &PyId_read, NULL);
2909+
data = _PyObject_CallMethodIdNoArgs(file, &PyId_read);
29102910
if (data == NULL)
29112911
goto error;
29122912
if (!PyBytes_Check(data)) {

Modules/_datetimemodule.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,7 +1659,7 @@ time_time(void)
16591659
if (time != NULL) {
16601660
_Py_IDENTIFIER(time);
16611661

1662-
result = _PyObject_CallMethodId(time, &PyId_time, NULL);
1662+
result = _PyObject_CallMethodIdNoArgs(time, &PyId_time);
16631663
Py_DECREF(time);
16641664
}
16651665
return result;
@@ -1918,7 +1918,7 @@ get_float_as_integer_ratio(PyObject *floatobj)
19181918
PyObject *ratio;
19191919

19201920
assert(floatobj && PyFloat_Check(floatobj));
1921-
ratio = _PyObject_CallMethodId(floatobj, &PyId_as_integer_ratio, NULL);
1921+
ratio = _PyObject_CallMethodIdNoArgs(floatobj, &PyId_as_integer_ratio);
19221922
if (ratio == NULL) {
19231923
return NULL;
19241924
}
@@ -3162,7 +3162,7 @@ date_isoformat(PyDateTime_Date *self, PyObject *Py_UNUSED(ignored))
31623162
static PyObject *
31633163
date_str(PyDateTime_Date *self)
31643164
{
3165-
return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
3165+
return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
31663166
}
31673167

31683168

@@ -3188,7 +3188,7 @@ date_strftime(PyDateTime_Date *self, PyObject *args, PyObject *kw)
31883188
&format))
31893189
return NULL;
31903190

3191-
tuple = _PyObject_CallMethodId((PyObject *)self, &PyId_timetuple, NULL);
3191+
tuple = _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_timetuple);
31923192
if (tuple == NULL)
31933193
return NULL;
31943194
result = wrap_strftime((PyObject *)self, format, tuple,
@@ -4175,7 +4175,7 @@ time_repr(PyDateTime_Time *self)
41754175
static PyObject *
41764176
time_str(PyDateTime_Time *self)
41774177
{
4178-
return _PyObject_CallMethodId((PyObject *)self, &PyId_isoformat, NULL);
4178+
return _PyObject_CallMethodIdNoArgs((PyObject *)self, &PyId_isoformat);
41794179
}
41804180

41814181
static PyObject *

Modules/_dbmmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,7 @@ static PyObject *
370370
dbm__exit__(PyObject *self, PyObject *args)
371371
{
372372
_Py_IDENTIFIER(close);
373-
return _PyObject_CallMethodId(self, &PyId_close, NULL);
373+
return _PyObject_CallMethodIdNoArgs(self, &PyId_close);
374374
}
375375

376376

Modules/_gdbmmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ static PyObject *
497497
dbm__exit__(PyObject *self, PyObject *args)
498498
{
499499
_Py_IDENTIFIER(close);
500-
return _PyObject_CallMethodId(self, &PyId_close, NULL);
500+
return _PyObject_CallMethodIdNoArgs(self, &PyId_close);
501501
}
502502

503503
static PyMethodDef dbm_methods[] = {

0 commit comments

Comments
 (0)