8000 bpo-37337: Add _PyObject_CallMethodNoArgs() (GH-14267) · python/cpython@762f93f · GitHub
[go: up one dir, main page]

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[] = {

Modules/_io/_iomodule.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
400400

401401
/* buffering */
402402
if (buffering < 0) {
403-
PyObject *res = _PyObject_CallMethodId(raw, &PyId_isatty, NULL);
403+
PyObject *res = _PyObject_CallMethodIdNoArgs(raw, &PyId_isatty);
404404
if (res == NULL)
405405
goto error;
406406
isatty = PyLong_AsLong(res);
@@ -494,7 +494,7 @@ _io_open_impl(PyObject *module, PyObject *file, const char *mode,
494494
if (result != NULL) {
495495
PyObject *exc, *val, *tb, *close_result;
496496
PyErr_Fetch(&exc, &val, &tb);
497-
close_result = _PyObject_CallMethodId(result, &PyId_close, NULL);
497+
close_result = _PyObject_CallMethodIdNoArgs(result, &PyId_close);
498498
_PyErr_ChainExceptions(exc, val, tb);
499499
Py_XDECREF(close_result);
500500
Py_DECREF(result);

Modules/_io/bufferedio.c

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ static PyObject *
461461
buffered_simple_flush(buffered *self, PyObject *args)
462462
{
463463
CHECK_INITIALIZED(self)
464-
return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_flush, NULL);
464+
return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_flush);
465465
}
466466

467467
static int
@@ -513,15 +513,15 @@ buffered_close(buffered *self, PyObject *args)
513513
}
514514
/* flush() will most probably re-take the lock, so drop it first */
515515
LEAVE_BUFFERED(self)
516-
res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
516+
res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
517517
if (!ENTER_BUFFERED(self))
518518
return NULL;
519519
if (res == NULL)
520520
PyErr_Fetch(&exc, &val, &tb);
521521
else
522522
Py_DECREF(res);
523523

524-
res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_close, NULL);
524+
res = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_close);
525525

526526
if (self->buffer) {
527527
PyMem_Free(self->buffer);
@@ -545,7 +545,7 @@ buffered_detach(buffered *self, PyObject *Py_UNUSED(ignored))
545545
{
546546
PyObject *raw, *res;
547547
CHECK_INITIALIZED(self)
548-
res = PyObject_CallMethodObjArgs((PyObject *)self, _PyIO_str_flush, NULL);
548+
res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_flush);
549549
if (res == NULL)
550550
return NULL;
551551
Py_DECREF(res);
@@ -562,21 +562,21 @@ static PyObject *
562562
buffered_seekable(buffered *self, PyObject *Py_UNUSED(ignored))
563563
{
564564
CHECK_INITIALIZED(self)
565-
return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_seekable, NULL);
565+
return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_seekable);
566566
}
567567

568568
static PyObject *
569569
buffered_readable(buffered *self, PyObject *Py_UNUSED(ignored))
570570
{
571571
CHECK_INITIALIZED(self)
572-
return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_readable, NULL);
572+
return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_readable);
573573
}
574574

575575
static PyObject *
576576
buffered_writable(buffered *self, PyObject *Py_UNUSED(ignored))
577577
{
578578
CHECK_INITIALIZED(self)
579-
return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_writable, NULL);
579+
return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_writable);
580580
}
581581

582582
static PyObject *
@@ -599,14 +599,14 @@ static PyObject *
599599
buffered_fileno(buffered *self, PyObject *Py_UNUSED(ignored))
600600
{
601601
CHECK_INITIALIZED(self)
602-
return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_fileno, NULL);
602+
return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_fileno);
603603
}
604604

605605
static PyObject *
606606
buffered_isatty(buffered *self, PyObject *Py_UNUSED(ignored))
607607
{
608608
CHECK_INITIALIZED(self)
609-
return PyObject_CallMethodObjArgs(self->raw, _PyIO_str_isatty, NULL);
609+
return _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_isatty);
610610
}
611611

612612
/* Forward decls */
@@ -670,7 +670,7 @@ _buffered_raw_tell(buffered *self)
670670
{
671671
Py_off_t n;
672672
PyObject *res;
673-
res = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_tell, NULL);
673+
res = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_tell);
674674
if (res == NULL)
675675
return -1;
676676
n = PyNumber_AsOff_t(res, PyExc_ValueError);
@@ -1350,8 +1350,8 @@ buffered_iternext(buffered *self)
13501350
line = _buffered_readline(self, -1);
13511351
}
13521352
else {
1353-
line = PyObject_CallMethodObjArgs((PyObject *)self,
1354-
_PyIO_str_readline, NULL);
1353+
line = _PyObject_CallMethodNoArgs((PyObject *)self,
1354+
_PyIO_str_readline);
13551355
if (line && !PyBytes_Check(line)) {
13561356
PyErr_Format(PyExc_OSError,
13571357
"readline() should have returned a bytes object, "
@@ -1566,7 +1566,7 @@ _bufferedreader_read_all(buffered *self)
15661566
}
15671567

15681568
/* Read until EOF or until read() would block. */
1569-
data = PyObject_CallMethodObjArgs(self->raw, _PyIO_str_read, NULL);
1569+
data = _PyObject_CallMethodNoArgs(self->raw, _PyIO_str_read);
15701570
if (data == NULL)
15711571
goto cleanup;
15721572
if (data != Py_None && !PyBytes_Check(data)) {

Modules/_io/iobase.c

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ _io__IOBase_close_impl(PyObject *self)
235235
Py_RETURN_NONE;
236236
}
237237

238-
res = PyObject_CallMethodObjArgs(self, _PyIO_str_flush, NULL);
238+
res = _PyObject_CallMethodNoArgs(self, _PyIO_str_flush);
239239

240240
PyErr_Fetch(&exc, &val, &tb);
241241
rc = _PyObject_SetAttrId(self, &PyId___IOBase_closed, Py_True);
@@ -281,8 +281,7 @@ iobase_finalize(PyObject *self)
281281
finalization process. */
282282
if (_PyObject_SetAttrId(self, &PyId__finalizing, Py_True))
283283
PyErr_Clear();
284-
res = PyObject_CallMethodObjArgs((PyObject *) self, _PyIO_str_close,
285-
NULL);
284+
res = _PyObject_CallMethodNoArgs((PyObject *)self, _PyIO_str_close);
286285
/* Silencing I/O errors is bad, but printing spurious tracebacks is
287286
equally as bad, and potentially more frequent (because of
288287
shutdown issues). */
@@ -383,7 +382,7 @@ _io__IOBase_seekable_impl(PyObject *self)
383382
PyObject *
384383
_PyIOBase_check_seekable(PyObject *self, PyObject *args)
385384
{
386-
PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_seekable, NULL);
385+
PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_seekable);
387386
if (res == NULL)
388387
return NULL;
389388
if (res != Py_True) {
@@ -416,7 +415,7 @@ _io__IOBase_readable_impl(PyObject *self)
416415
PyObject *
417416
_PyIOBase_check_readable(PyObject *self, PyObject *args)
418417
{
419-
PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_readable, NULL);
418+
PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_readable);
420419
if (res == NULL)
421420
return NULL;
422421
if (res != Py_True) {
@@ -449,7 +448,7 @@ _io__IOBase_writable_impl(PyObject *self)
449448
PyObject *
450449
_PyIOBase_check_writable(PyObject *self, PyObject *args)
451450
{
452-
PyObject *res = PyObject_CallMethodObjArgs(self, _PyIO_str_writable, NULL);
451+
PyObject *res = _PyObject_CallMethodNoArgs(self, _PyIO_str_writable);
453452
if (res == NULL)
454453
return NULL;
455454
if (res != Py_True) {
@@ -478,7 +477,7 @@ iobase_enter(PyObject *self, PyObject *args)
478477
static PyObject *
479478
iobase_exit(PyObject *self, PyObject *args)
480479
{
481-
return PyObject_CallMethodObjArgs(self, _PyIO_str_close, NULL);
480+
return _PyObject_CallMethodNoArgs(self, _PyIO_str_close);
482481
}
483482

484483
/* Lower-level APIs */
@@ -656,7 +655,7 @@ iobase_iter(PyObject *self)
656655
static PyObject *
657656
iobase_iternext(PyObject *self)
658657
{
659-
PyObject *line = PyObject_CallMethodObjArgs(self, _PyIO_str_readline, NULL);
658+
PyObject *line = _PyObject_CallMethodNoArgs(self, _PyIO_str_readline);
660659

661660
if (line == NULL)
662661
return NULL;
@@ -921,7 +920,7 @@ _io__RawIOBase_read_impl(PyObject *self, Py_ssize_t n)
921920
if (n < 0) {
922921
_Py_IDENTIFIER(readall);
923922

924-
return _PyObject_CallMethodId(self, &PyId_readall, NULL);
923+
return _PyObject_CallMethodIdNoArgs(self, &PyId_readall);
925924
}
926925

927926
/* TODO: allocate a bytes object directly instead and manually construct

0 commit comments

Comments
 (0)
0