8000 bpo-37194: Add a new public PyObject_CallNoArgs() function by vstinner · Pull Request #13890 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

bpo-37194: Add a new public PyObject_CallNoArgs() function #13890

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 17, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions Doc/c-api/object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,16 @@ Object Protocol
and ``0`` otherwise. This function always succeeds.


.. c:function:: PyObject* PyObject_CallNoArgs(PyObject *callable)

Call a callable Python object *callable* without any arguments.

Returns the result of the call on success, or raise an exception and return
*NULL* on failure.

.. versionadded:: 3.9


.. c:function:: PyObject* PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs)

Call a callable Python object *callable*, with arguments given by the
Expand Down
2 changes: 2 additions & 0 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ Optimizations
Build and C API Changes
=======================

* Add a new public :c:func:`PyObject_CallNoArgs` function to the C API:
call a callable Python object without any arguments.


Deprecated
Expand Down
6 changes: 6 additions & 0 deletions Include/abstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ extern "C" {
#endif


#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x03090000
/* Call a callable Python object without any arguments */
PyAPI_FUNC(PyObject *) PyObject_CallNoArgs(PyObject *func);
#endif


/* Call a callable Python object 'callable' with arguments given by the
tuple 'args' and keywords arguments given by the dictionary 'kwargs'.

Expand Down
4 changes: 3 additions & 1 deletion Include/cpython/abstract.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,9 @@ _PyObject_FastCall(PyObject *func, PyObject *const *args, Py_ssize_t nargs)
return _PyObject_Vectorcall(func, args, (size_t)nargs, NULL);
}

/* Call a callable without any arguments */
/* Call a callable without any arguments
Private static inline function variant of public function
PyObject_CallNoArgs(). */
static inline PyObject *
_PyObject_CallNoArg(PyObject *func) {
return _PyObject_Vectorcall(func, NULL, 0, NULL);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Add a new public :c:func:`PyObject_CallNoArgs` function to the C API: call a
callable Python object without any arguments. It is the most efficient way to
call a callback without any argument. On x86-64, for example,
``PyObject_CallFunctionObjArgs(func, NULL)`` allocates 960 bytes on the stack
per call, whereas ``PyObject_CallNoArgs(func)`` only allocates 624 bytes per
call.
12 changes: 6 additions & 6 deletions Modules/_asynciomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ get_future_loop(PyObject *fut)
return NULL;
}
if (getloop != NULL) {
PyObject *res = _PyObject_CallNoArg(getloop);
PyObject *res = PyObject_CallNoArgs(getloop);
Py_DECREF(getloop);
return res;
}
Expand Down Expand Up @@ -328,7 +328,7 @@ get_event_loop(void)
return loop;
}

policy = _PyObject_CallNoArg(asyncio_get_event_loop_policy);
policy = PyObject_CallNoArgs(asyncio_get_event_loop_policy);
if (policy == NULL) {
return NULL;
}
Expand Down Expand Up @@ -510,7 +510,7 @@ future_init(FutureObj *fut, PyObject *loop)
method, which is called during the interpreter shutdown and the
traceback module is already unloaded.
*/
fut->fut_source_tb = _PyObject_CallNoArg(traceback_extract_stack);
fut->fut_source_tb = PyObject_CallNoArgs(traceback_extract_stack);
if (fut->fut_source_tb == NULL) {
return -1;
}
Expand Down Expand Up @@ -553,7 +553,7 @@ future_set_exception(FutureObj *fut, PyObject *exc)
}

if (PyExceptionClass_Check(exc)) {
exc_val = _PyObject_CallNoArg(exc);
exc_val = PyObject_CallNoArgs(exc);
if (exc_val == NULL) {
return NULL;
}
Expand Down Expand Up @@ -2593,7 +2593,7 @@ task_step_impl(TaskObj *task, PyObject *exc)

if (!exc) {
/* exc was not a CancelledError */
exc = _PyObject_CallNoArg(asyncio_CancelledError);
exc = PyObject_CallNoArgs(asyncio_CancelledError);
if (!exc) {
goto fail;
}
Expand Down Expand Up @@ -3308,7 +3308,7 @@ module_init(void)
PyObject *weak_set;
WITH_MOD("weakref")
GET_MOD_ATTR(weak_set, "WeakSet");
all_tasks = _PyObject_CallNoArg(weak_set);
all_tasks = PyObject_CallNoArgs(weak_set);
Py_CLEAR(weak_set);
if (all_tasks == NULL) {
goto fail;
Expand Down