mirror of
https://github.com/python/cpython.git
synced 2025-07-07 19:35:27 +00:00
gh-106084: Remove _PyObject_CallMethod() function (#106159)
Remove the following private functions from the public C API: * _Py_CheckFunctionResult() * _PyObject_CallMethod() * _PyObject_CallMethodId() * _PyObject_CallMethodIdNoArgs() * _PyObject_CallMethodIdObjArgs() * _PyObject_CallMethodIdOneArg() * _PyObject_MakeTpCall() * _PyObject_VectorcallMethodId() * _PyStack_AsDict() Move these functions to the internal C API (pycore_call.h). No longer export the following functions: * _PyObject_Call() * _PyObject_CallMethod() * _PyObject_CallMethodId() * _PyObject_CallMethodIdObjArgs() * _PyObject_Call_Prepend() * _PyObject_FastCallDictTstate() * _PyStack_AsDict() The following functions are still exported for stdlib shared extensions: * _Py_CheckFunctionResult() * _PyObject_MakeTpCall() Mark the following internal functions as extern: * _PyStack_UnpackDict() * _PyStack_UnpackDict_Free() * _PyStack_UnpackDict_FreeNoDecRef()
This commit is contained in:
parent
6b5166fb12
commit
84caa3324a
9 changed files with 111 additions and 85 deletions
|
@ -4,20 +4,6 @@
|
|||
|
||||
/* === Object Protocol ================================================== */
|
||||
|
||||
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
|
||||
format to a Python dictionary ("kwargs" dict).
|
||||
|
||||
The type of kwnames keys is not checked. The final function getting
|
||||
arguments is responsible to check if all keys are strings, for example using
|
||||
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
|
||||
|
||||
Duplicate keys are merged using the last value. If duplicate keys must raise
|
||||
an exception, the caller is responsible to implement an explicit keys on
|
||||
kwnames. */
|
||||
PyAPI_FUNC(PyObject *) _PyStack_AsDict(
|
||||
PyObject *const *values,
|
||||
PyObject *kwnames);
|
||||
|
||||
/* Suggested size (number of positional arguments) for arrays of PyObject*
|
||||
allocated on a C stack to avoid allocating memory on the heap memory. Such
|
||||
array is used to pass positional arguments to call functions of the
|
||||
|
@ -29,32 +15,17 @@ PyAPI_FUNC(PyObject *) _PyStack_AsDict(
|
|||
40 bytes on the stack. */
|
||||
#define _PY_FASTCALL_SMALL_STACK 5
|
||||
|
||||
PyAPI_FUNC(PyObject *) _Py_CheckFunctionResult(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *result,
|
||||
const char *where);
|
||||
|
||||
/* === Vectorcall protocol (PEP 590) ============================= */
|
||||
|
||||
/* Call callable using tp_call. Arguments are like PyObject_Vectorcall()
|
||||
or PyObject_FastCallDict() (both forms are supported),
|
||||
except that nargs is plainly the number of arguments without flags. */
|
||||
PyAPI_FUNC(PyObject *) _PyObject_MakeTpCall(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *const *args, Py_ssize_t nargs,
|
||||
PyObject *keywords);
|
||||
|
||||
// PyVectorcall_NARGS() is exported as a function for the stable ABI.
|
||||
// Here (when we are not using the stable ABI), the name is overridden to
|
||||
// call a static inline function for best performance.
|
||||
#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n)
|
||||
static inline Py_ssize_t
|
||||
_PyVectorcall_NARGS(size_t n)
|
||||
{
|
||||
return n & ~PY_VECTORCALL_ARGUMENTS_OFFSET;
|
||||
}
|
||||
#define PyVectorcall_NARGS(n) _PyVectorcall_NARGS(n)
|
||||
|
||||
PyAPI_FUNC(vectorcallfunc) PyVectorcall_Function(PyObject *callable);
|
||||
|
||||
|
@ -90,49 +61,6 @@ PyObject_CallMethodOneArg(PyObject *self, PyObject *name, PyObject *arg)
|
|||
return PyObject_VectorcallMethod(name, args, nargsf, _Py_NULL);
|
||||
}
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethod(PyObject *obj,
|
||||
PyObject *name,
|
||||
const char *format, ...);
|
||||
|
||||
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
|
||||
as the method name. */
|
||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethodId(PyObject *obj,
|
||||
_Py_Identifier *name,
|
||||
const char *format, ...);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_CallMethodIdObjArgs(
|
||||
PyObject *obj,
|
||||
_Py_Identifier *name,
|
||||
...);
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_VectorcallMethodId(
|
||||
_Py_Identifier *name, PyObject *const *args,
|
||||
size_t nargsf, PyObject *kwnames)
|
||||
{
|
||||
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
|
||||
if (!oname) {
|
||||
return _Py_NULL;
|
||||
}
|
||||
return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
|
||||
{
|
||||
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
||||
return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
|
||||
{
|
||||
PyObject *args[2] = {self, arg};
|
||||
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
||||
assert(arg != NULL);
|
||||
return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
|
||||
}
|
||||
|
||||
/* Guess the size of object 'o' using len(o) or o.__length_hint__().
|
||||
If neither of those return a non-negative value, then return the default
|
||||
value. If one of the calls fails, this function returns -1. */
|
||||
|
|
|
@ -10,29 +10,112 @@ extern "C" {
|
|||
|
||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_Call_Prepend(
|
||||
// Export for shared stdlib extensions like the math extension,
|
||||
// function used via inlined _PyObject_VectorcallTstate() function.
|
||||
PyAPI_FUNC(PyObject*) _Py_CheckFunctionResult(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *result,
|
||||
const char *where);
|
||||
|
||||
/* Convert keyword arguments from the FASTCALL (stack: C array, kwnames: tuple)
|
||||
format to a Python dictionary ("kwargs" dict).
|
||||
|
||||
The type of kwnames keys is not checked. The final function getting
|
||||
arguments is responsible to check if all keys are strings, for example using
|
||||
PyArg_ParseTupleAndKeywords() or PyArg_ValidateKeywordArguments().
|
||||
|
||||
Duplicate keys are merged using the last value. If duplicate keys must raise
|
||||
an exception, the caller is responsible to implement an explicit keys on
|
||||
kwnames. */
|
||||
extern PyObject* _PyStack_AsDict(PyObject *const *values, PyObject *kwnames);
|
||||
|
||||
extern PyObject* _PyObject_Call_Prepend(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *obj,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_FastCallDictTstate(
|
||||
extern PyObject* _PyObject_FastCallDictTstate(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *const *args,
|
||||
size_t nargsf,
|
||||
PyObject *kwargs);
|
||||
|
||||
PyAPI_FUNC(PyObject *) _PyObject_Call(
|
||||
extern PyObject* _PyObject_Call(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *args,
|
||||
PyObject *kwargs);
|
||||
|
||||
extern PyObject * _PyObject_CallMethodFormat(
|
||||
PyThreadState *tstate, PyObject *callable, const char *format, ...);
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
const char *format,
|
||||
...);
|
||||
|
||||
// Export for shared stdlib extensions like the array extension
|
||||
PyAPI_FUNC(PyObject*) _PyObject_CallMethod(
|
||||
PyObject *obj,
|
||||
PyObject *name,
|
||||
const char *format, ...);
|
||||
|
||||
/* Like PyObject_CallMethod(), but expect a _Py_Identifier*
|
||||
as the method name. */
|
||||
extern PyObject* _PyObject_CallMethodId(
|
||||
PyObject *obj,
|
||||
_Py_Identifier *name,
|
||||
const char *format, ...);
|
||||
|
||||
extern PyObject* _PyObject_CallMethodIdObjArgs(
|
||||
PyObject *obj,
|
||||
_Py_Identifier *name,
|
||||
...);
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_VectorcallMethodId(
|
||||
_Py_Identifier *name, PyObject *const *args,
|
||||
size_t nargsf, PyObject *kwnames)
|
||||
{
|
||||
PyObject *oname = _PyUnicode_FromId(name); /* borrowed */
|
||||
if (!oname) {
|
||||
return _Py_NULL;
|
||||
}
|
||||
return PyObject_VectorcallMethod(oname, args, nargsf, kwnames);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallMethodIdNoArgs(PyObject *self, _Py_Identifier *name)
|
||||
{
|
||||
size_t nargsf = 1 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
||||
return _PyObject_VectorcallMethodId(name, &self, nargsf, _Py_NULL);
|
||||
}
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_CallMethodIdOneArg(PyObject *self, _Py_Identifier *name, PyObject *arg)
|
||||
{
|
||||
PyObject *args[2] = {self, arg};
|
||||
size_t nargsf = 2 | PY_VECTORCALL_ARGUMENTS_OFFSET;
|
||||
assert(arg != NULL);
|
||||
return _PyObject_VectorcallMethodId(name, args, nargsf, _Py_NULL);
|
||||
}
|
||||
|
||||
|
||||
/* === Vectorcall protocol (PEP 590) ============================= */
|
||||
|
||||
// Call callable using tp_call. Arguments are like PyObject_Vectorcall()
|
||||
// or PyObject_FastCallDict() (both forms are supported),
|
||||
// except that nargs is plainly the number of arguments without flags.
|
||||
//
|
||||
// Export for shared stdlib extensions like the math extension,
|
||||
// function used via inlined _PyObject_VectorcallTstate() function.
|
||||
PyAPI_FUNC(PyObject*) _PyObject_MakeTpCall(
|
||||
PyThreadState *tstate,
|
||||
PyObject *callable,
|
||||
PyObject *const *args, Py_ssize_t nargs,
|
||||
PyObject *keywords);
|
||||
|
||||
// Static inline variant of public PyVectorcall_Function().
|
||||
static inline vectorcallfunc
|
||||
|
@ -110,22 +193,26 @@ _PyObject_CallNoArgs(PyObject *func) {
|
|||
|
||||
|
||||
static inline PyObject *
|
||||
_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func, PyObject *const *args, Py_ssize_t nargs)
|
||||
_PyObject_FastCallTstate(PyThreadState *tstate, PyObject *func,
|
||||
PyObject *const *args, Py_ssize_t nargs)
|
||||
{
|
||||
EVAL_CALL_STAT_INC_IF_FUNCTION(EVAL_CALL_API, func);
|
||||
return _PyObject_VectorcallTstate(tstate, func, args, (size_t)nargs, NULL);
|
||||
}
|
||||
|
||||
PyObject *const *
|
||||
extern PyObject *const *
|
||||
_PyStack_UnpackDict(PyThreadState *tstate,
|
||||
PyObject *const *args, Py_ssize_t nargs,
|
||||
PyObject *kwargs, PyObject **p_kwnames);
|
||||
|
||||
void
|
||||
_PyStack_UnpackDict_Free(PyObject *const *stack, Py_ssize_t nargs,
|
||||
extern void _PyStack_UnpackDict_Free(
|
||||
PyObject *const *stack,
|
||||
Py_ssize_t nargs,
|
||||
PyObject *kwnames);
|
||||
|
||||
void _PyStack_UnpackDict_FreeNoDecRef(PyObject *const *stack, PyObject *kwnames);
|
||||
extern void _PyStack_UnpackDict_FreeNoDecRef(
|
||||
PyObject *const *stack,
|
||||
PyObject *kwnames);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -3,8 +3,13 @@
|
|||
Converted to C by Dmitry Vasiliev (dima at hlabs.spb.ru).
|
||||
*/
|
||||
|
||||
#ifndef Py_BUILD_CORE_BUILTIN
|
||||
# define Py_BUILD_CORE_MODULE 1
|
||||
#endif
|
||||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "pycore_call.h" // _PyObject_CallMethod()
|
||||
|
||||
/*[clinic input]
|
||||
module _bisect
|
||||
|
|
|
@ -10,8 +10,9 @@
|
|||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "pycore_call.h" // _PyObject_CallMethod()
|
||||
#include "pycore_long.h" // _PyLong_GetOne()
|
||||
#include "pycore_object.h"
|
||||
#include "pycore_object.h" // _PyType_HasFeature()
|
||||
#include <stddef.h> // offsetof()
|
||||
#include "_iomodule.h"
|
||||
|
||||
|
|
|
@ -8,10 +8,11 @@
|
|||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "pycore_call.h" // _PyObject_CallMethod()
|
||||
#include "pycore_interp.h" // PyInterpreterState.fs_codec
|
||||
#include "pycore_long.h" // _PyLong_GetZero()
|
||||
#include "pycore_fileutils.h" // _Py_GetLocaleEncoding()
|
||||
#include "pycore_object.h"
|
||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||
#include "structmember.h" // PyMemberDef
|
||||
#include "_iomodule.h"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "Python.h"
|
||||
#include "pycore_call.h" // _PyObject_CallMethod()
|
||||
#include "pycore_moduleobject.h" // _PyModule_GetState()
|
||||
#include "pycore_bytesobject.h" // _PyBytes_Repeat
|
||||
#include "structmember.h" // PyMemberDef
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include "Python.h"
|
||||
#include "pycore_abstract.h" // _PyObject_RealIsSubclass()
|
||||
#include "pycore_call.h" // _PyStack_AsDict()
|
||||
#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
|
||||
#include "pycore_object.h" // _PyObject_GC_UNTRACK()
|
||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
/* Method object implementation */
|
||||
|
||||
#include "Python.h"
|
||||
#include "pycore_call.h" // _Py_CheckFunctionResult()
|
||||
#include "pycore_ceval.h" // _Py_EnterRecursiveCallTstate()
|
||||
#include "pycore_object.h"
|
||||
#include "pycore_pyerrors.h"
|
||||
|
|
|
@ -2,10 +2,11 @@
|
|||
|
||||
#include "Python.h"
|
||||
|
||||
#include "pycore_call.h" // _PyObject_CallMethod()
|
||||
#include "pycore_ceval.h" // _PyEval_FiniGIL()
|
||||
#include "pycore_context.h" // _PyContext_Init()
|
||||
#include "pycore_exceptions.h" // _PyExc_InitTypes()
|
||||
#include "pycore_dict.h" // _PyDict_Fini()
|
||||
#include "pycore_exceptions.h" // _PyExc_InitTypes()
|
||||
#include "pycore_fileutils.h" // _Py_ResetForceASCII()
|
||||
#include "pycore_floatobject.h" // _PyFloat_InitTypes()
|
||||
#include "pycore_genobject.h" // _PyAsyncGen_Fini()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue