mirror of https://github.com/python/cpython
gh-90370: Argument Clinic: avoid temporary tuple creation for varargs (#126064)
Avoid temporary tuple creation when all arguments either positional-only or vararg. Objects/setobject.c and Modules/gcmodule.c adapted. This fixes slight performance regression for set methods, introduced by gh-115112.
This commit is contained in:
parent
d07dcce693
commit
8c22eba877
|
@ -4148,36 +4148,32 @@ PyDoc_STRVAR(test_vararg_and_posonly__doc__,
|
||||||
{"test_vararg_and_posonly", _PyCFunction_CAST(test_vararg_and_posonly), METH_FASTCALL, test_vararg_and_posonly__doc__},
|
{"test_vararg_and_posonly", _PyCFunction_CAST(test_vararg_and_posonly), METH_FASTCALL, test_vararg_and_posonly__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
test_vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args);
|
test_vararg_and_posonly_impl(PyObject *module, PyObject *a, Py_ssize_t nargs,
|
||||||
|
PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
test_vararg_and_posonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
test_vararg_and_posonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
|
Py_ssize_t nvararg = nargs - 1;
|
||||||
PyObject *a;
|
PyObject *a;
|
||||||
PyObject *__clinic_args = NULL;
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("test_vararg_and_posonly", nargs, 1, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("test_vararg_and_posonly", nargs, 1, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
a = args[0];
|
a = args[0];
|
||||||
__clinic_args = PyTuple_New(nargs - 1);
|
__clinic_args = args + 1;
|
||||||
if (!__clinic_args) {
|
return_value = test_vararg_and_posonly_impl(module, a, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 1; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[1 + i]));
|
|
||||||
}
|
|
||||||
return_value = test_vararg_and_posonly_impl(module, a, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
test_vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args)
|
test_vararg_and_posonly_impl(PyObject *module, PyObject *a, Py_ssize_t nargs,
|
||||||
/*[clinic end generated code: output=79b75dc07decc8d6 input=9cfa748bbff09877]*/
|
PyObject *const *args)
|
||||||
|
/*[clinic end generated code: output=dc2dd9483cc0459e input=9cfa748bbff09877]*/
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
test_vararg
|
test_vararg
|
||||||
|
@ -4931,14 +4927,14 @@ PyDoc_STRVAR(Test___init____doc__,
|
||||||
"Varargs init method. For example, nargs is translated to PyTuple_GET_SIZE.");
|
"Varargs init method. For example, nargs is translated to PyTuple_GET_SIZE.");
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Test___init___impl(TestObj *self, PyObject *args);
|
Test___init___impl(TestObj *self, Py_ssize_t nargs, PyObject *const *args);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Test___init__(PyObject *self, PyObject *args, PyObject *kwargs)
|
Test___init__(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
int return_value = -1;
|
int return_value = -1;
|
||||||
PyTypeObject *base_tp = TestType;
|
PyTypeObject *base_tp = TestType;
|
||||||
PyObject *__clinic_args = NULL;
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if ((Py_IS_TYPE(self, base_tp) ||
|
if ((Py_IS_TYPE(self, base_tp) ||
|
||||||
Py_TYPE(self)->tp_new == base_tp->tp_new) &&
|
Py_TYPE(self)->tp_new == base_tp->tp_new) &&
|
||||||
|
@ -4948,17 +4944,16 @@ Test___init__(PyObject *self, PyObject *args, PyObject *kwargs)
|
||||||
if (!_PyArg_CheckPositional("Test", PyTuple_GET_SIZE(args), 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("Test", PyTuple_GET_SIZE(args), 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_GetSlice(0, -1);
|
__clinic_args = _PyTuple_CAST(args)->ob_item;
|
||||||
return_value = Test___init___impl((TestObj *)self, __clinic_args);
|
return_value = Test___init___impl((TestObj *)self, nvararg, __clinic_args);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
Test___init___impl(TestObj *self, PyObject *args)
|
Test___init___impl(TestObj *self, Py_ssize_t nargs, PyObject *const *args)
|
||||||
/*[clinic end generated code: output=0ed1009fe0dcf98d input=2a8bd0033c9ac772]*/
|
/*[clinic end generated code: output=6a64b417c9080a73 input=2a8bd0033c9ac772]*/
|
||||||
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
@ -4976,14 +4971,14 @@ PyDoc_STRVAR(Test__doc__,
|
||||||
"Varargs new method. For example, nargs is translated to PyTuple_GET_SIZE.");
|
"Varargs new method. For example, nargs is translated to PyTuple_GET_SIZE.");
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Test_impl(PyTypeObject *type, PyObject *args);
|
Test_impl(PyTypeObject *type, Py_ssize_t nargs, PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Test(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
Test(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyTypeObject *base_tp = TestType;
|
PyTypeObject *base_tp = TestType;
|
||||||
PyObject *__clinic_args = NULL;
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
|
if ((type == base_tp || type->tp_init == base_tp->tp_init) &&
|
||||||
!_PyArg_NoKeywords("Test", kwargs)) {
|
!_PyArg_NoKeywords("Test", kwargs)) {
|
||||||
|
@ -4992,17 +4987,16 @@ Test(PyTypeObject *type, PyObject *args, PyObject *kwargs)
|
||||||
if (!_PyArg_CheckPositional("Test", PyTuple_GET_SIZE(args), 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("Test", PyTuple_GET_SIZE(args), 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_GetSlice(0, -1);
|
__clinic_args = _PyTuple_CAST(args)->ob_item;
|
||||||
return_value = Test_impl(type, __clinic_args);
|
return_value = Test_impl(type, nvararg, __clinic_args);
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
Test_impl(PyTypeObject *type, PyObject *args)
|
Test_impl(PyTypeObject *type, Py_ssize_t nargs, PyObject *const *args)
|
||||||
/*[clinic end generated code: output=8b219f6633e2a2e9 input=70ad829df3dd9b84]*/
|
/*[clinic end generated code: output=bf22f942407383a5 input=70ad829df3dd9b84]*/
|
||||||
|
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
|
|
@ -3381,8 +3381,8 @@ class ClinicFunctionalTest(unittest.TestCase):
|
||||||
def test_varpos(self):
|
def test_varpos(self):
|
||||||
# fn(*args)
|
# fn(*args)
|
||||||
fn = ac_tester.varpos
|
fn = ac_tester.varpos
|
||||||
self.assertEqual(fn(), ())
|
self.assertEqual(fn(), ((),))
|
||||||
self.assertEqual(fn(1, 2), (1, 2))
|
self.assertEqual(fn(1, 2), ((1, 2),))
|
||||||
|
|
||||||
def test_posonly_varpos(self):
|
def test_posonly_varpos(self):
|
||||||
# fn(a, b, /, *args)
|
# fn(a, b, /, *args)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Avoid temporary tuple creation for vararg in argument passing with Argument
|
||||||
|
Clinic generated code (if arguments either vararg or positional-only).
|
|
@ -58,6 +58,20 @@ pack_arguments_newref(int argc, ...)
|
||||||
return tuple;
|
return tuple;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *
|
||||||
|
pack_varargs_to_tuple(Py_ssize_t varargssize, PyObject *const *args)
|
||||||
|
{
|
||||||
|
assert(!PyErr_Occurred());
|
||||||
|
PyObject *tuple = PyTuple_New(varargssize);
|
||||||
|
if (!tuple) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
for (Py_ssize_t i = 0; i < varargssize; i++) {
|
||||||
|
PyTuple_SET_ITEM(tuple, i, Py_NewRef(args[i]));
|
||||||
|
}
|
||||||
|
return tuple;
|
||||||
|
}
|
||||||
|
|
||||||
/* Pack arguments to a tuple.
|
/* Pack arguments to a tuple.
|
||||||
* `wrapper` is function which converts primitive type to PyObject.
|
* `wrapper` is function which converts primitive type to PyObject.
|
||||||
* `arg_type` is type that arguments should be converted to before wrapped. */
|
* `arg_type` is type that arguments should be converted to before wrapped. */
|
||||||
|
@ -970,10 +984,16 @@ varpos
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
varpos_impl(PyObject *module, PyObject *args)
|
varpos_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args)
|
||||||
/*[clinic end generated code: output=7b0b9545872bdca4 input=f87cd674145d394c]*/
|
/*[clinic end generated code: output=b65096f423fb5dcc input=f87cd674145d394c]*/
|
||||||
{
|
{
|
||||||
return Py_NewRef(args);
|
PyObject *vararg_tuple = pack_varargs_to_tuple(nargs, args);
|
||||||
|
if (!vararg_tuple) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyObject *result = pack_arguments_newref(1, vararg_tuple);
|
||||||
|
Py_DECREF(vararg_tuple);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -989,10 +1009,16 @@ posonly_varpos
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posonly_varpos_impl(PyObject *module, PyObject *a, PyObject *b,
|
posonly_varpos_impl(PyObject *module, PyObject *a, PyObject *b,
|
||||||
PyObject *args)
|
Py_ssize_t nargs, PyObject *const *args)
|
||||||
/*[clinic end generated code: output=5dae5eb2a0d623cd input=c9fd7895cfbaabba]*/
|
/*[clinic end generated code: output=d10d43d86d117ab3 input=c9fd7895cfbaabba]*/
|
||||||
{
|
{
|
||||||
return pack_arguments_newref(3, a, b, args);
|
PyObject *vararg_tuple = pack_varargs_to_tuple(nargs, args);
|
||||||
|
if (!vararg_tuple) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
PyObject *result = pack_arguments_newref(3, a, b, vararg_tuple);
|
||||||
|
Py_DECREF(vararg_tuple);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1157,8 +1183,9 @@ Proof-of-concept of GH-99233 refcount error bug.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gh_99233_refcount_impl(PyObject *module, PyObject *args)
|
gh_99233_refcount_impl(PyObject *module, Py_ssize_t nargs,
|
||||||
/*[clinic end generated code: output=585855abfbca9a7f input=eecfdc2092d90dc3]*/
|
PyObject *const *args)
|
||||||
|
/*[clinic end generated code: output=b570007e61e5c670 input=eecfdc2092d90dc3]*/
|
||||||
{
|
{
|
||||||
Py_RETURN_NONE;
|
Py_RETURN_NONE;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2530,28 +2530,22 @@ PyDoc_STRVAR(varpos__doc__,
|
||||||
{"varpos", _PyCFunction_CAST(varpos), METH_FASTCALL, varpos__doc__},
|
{"varpos", _PyCFunction_CAST(varpos), METH_FASTCALL, varpos__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
varpos_impl(PyObject *module, PyObject *args);
|
varpos_impl(PyObject *module, Py_ssize_t nargs, PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
varpos(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
varpos(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("varpos", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("varpos", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = varpos_impl(module, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = varpos_impl(module, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2565,32 +2559,26 @@ PyDoc_STRVAR(posonly_varpos__doc__,
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posonly_varpos_impl(PyObject *module, PyObject *a, PyObject *b,
|
posonly_varpos_impl(PyObject *module, PyObject *a, PyObject *b,
|
||||||
PyObject *args);
|
Py_ssize_t nargs, PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
posonly_varpos(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
posonly_varpos(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
|
Py_ssize_t nvararg = nargs - 2;
|
||||||
PyObject *a;
|
PyObject *a;
|
||||||
PyObject *b;
|
PyObject *b;
|
||||||
PyObject *__clinic_args = NULL;
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("posonly_varpos", nargs, 2, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("posonly_varpos", nargs, 2, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
a = args[0];
|
a = args[0];
|
||||||
b = args[1];
|
b = args[1];
|
||||||
__clinic_args = PyTuple_New(nargs - 2);
|
__clinic_args = args + 2;
|
||||||
if (!__clinic_args) {
|
return_value = posonly_varpos_impl(module, a, b, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 2; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[2 + i]));
|
|
||||||
}
|
|
||||||
return_value = posonly_varpos_impl(module, a, b, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3136,28 +3124,23 @@ PyDoc_STRVAR(gh_99233_refcount__doc__,
|
||||||
{"gh_99233_refcount", _PyCFunction_CAST(gh_99233_refcount), METH_FASTCALL, gh_99233_refcount__doc__},
|
{"gh_99233_refcount", _PyCFunction_CAST(gh_99233_refcount), METH_FASTCALL, gh_99233_refcount__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gh_99233_refcount_impl(PyObject *module, PyObject *args);
|
gh_99233_refcount_impl(PyObject *module, Py_ssize_t nargs,
|
||||||
|
PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gh_99233_refcount(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
gh_99233_refcount(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("gh_99233_refcount", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("gh_99233_refcount", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = gh_99233_refcount_impl(module, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = gh_99233_refcount_impl(module, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3693,4 +3676,4 @@ exit:
|
||||||
Py_XDECREF(__clinic_args);
|
Py_XDECREF(__clinic_args);
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=76ecbb38c632bde8 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=7662d07e7d29cbeb input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -312,28 +312,23 @@ PyDoc_STRVAR(gc_get_referrers__doc__,
|
||||||
{"get_referrers", _PyCFunction_CAST(gc_get_referrers), METH_FASTCALL, gc_get_referrers__doc__},
|
{"get_referrers", _PyCFunction_CAST(gc_get_referrers), METH_FASTCALL, gc_get_referrers__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gc_get_referrers_impl(PyObject *module, PyObject *args);
|
gc_get_referrers_impl(PyObject *module, Py_ssize_t nargs,
|
||||||
|
PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gc_get_referrers(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
gc_get_referrers(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("get_referrers", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("get_referrers", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = gc_get_referrers_impl(module, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = gc_get_referrers_impl(module, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,28 +342,23 @@ PyDoc_STRVAR(gc_get_referents__doc__,
|
||||||
{"get_referents", _PyCFunction_CAST(gc_get_referents), METH_FASTCALL, gc_get_referents__doc__},
|
{"get_referents", _PyCFunction_CAST(gc_get_referents), METH_FASTCALL, gc_get_referents__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gc_get_referents_impl(PyObject *module, PyObject *args);
|
gc_get_referents_impl(PyObject *module, Py_ssize_t nargs,
|
||||||
|
PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gc_get_referents(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
gc_get_referents(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("get_referents", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("get_referents", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = gc_get_referents_impl(module, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = gc_get_referents_impl(module, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,4 +575,4 @@ gc_get_freeze_count(PyObject *module, PyObject *Py_UNUSED(ignored))
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=0a7e91917adcb937 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=f488a0d4d6bd3687 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "pycore_gc.h"
|
#include "pycore_gc.h"
|
||||||
#include "pycore_object.h" // _PyObject_IS_GC()
|
#include "pycore_object.h" // _PyObject_IS_GC()
|
||||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||||
|
#include "pycore_tuple.h" // _PyTuple_FromArray()
|
||||||
|
|
||||||
typedef struct _gc_runtime_state GCState;
|
typedef struct _gc_runtime_state GCState;
|
||||||
|
|
||||||
|
@ -221,15 +222,25 @@ Return the list of objects that directly refer to any of 'objs'.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gc_get_referrers_impl(PyObject *module, PyObject *args)
|
gc_get_referrers_impl(PyObject *module, Py_ssize_t nargs,
|
||||||
/*[clinic end generated code: output=296a09587f6a86b5 input=bae96961b14a0922]*/
|
PyObject *const *args)
|
||||||
|
/*[clinic end generated code: output=1d44a7695ea25c40 input=bae96961b14a0922]*/
|
||||||
{
|
{
|
||||||
if (PySys_Audit("gc.get_referrers", "(O)", args) < 0) {
|
PyObject *varargs = _PyTuple_FromArray(args, nargs);
|
||||||
|
|
||||||
|
if (!varargs) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (PySys_Audit("gc.get_referrers", "(O)", varargs) < 0) {
|
||||||
|
Py_DECREF(varargs);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
return _PyGC_GetReferrers(interp, args);
|
PyObject *result = _PyGC_GetReferrers(interp, varargs);
|
||||||
|
|
||||||
|
Py_DECREF(varargs);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Append obj to list; return true if error (out of memory), false if OK. */
|
/* Append obj to list; return true if error (out of memory), false if OK. */
|
||||||
|
@ -269,27 +280,37 @@ Return the list of objects that are directly referred to by 'objs'.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
gc_get_referents_impl(PyObject *module, PyObject *args)
|
gc_get_referents_impl(PyObject *module, Py_ssize_t nargs,
|
||||||
/*[clinic end generated code: output=d47dc02cefd06fe8 input=b3ceab0c34038cbf]*/
|
PyObject *const *args)
|
||||||
|
/*[clinic end generated code: output=e459f3e8c0d19311 input=b3ceab0c34038cbf]*/
|
||||||
{
|
{
|
||||||
if (PySys_Audit("gc.get_referents", "(O)", args) < 0) {
|
PyObject *varargs = _PyTuple_FromArray(args, nargs);
|
||||||
|
|
||||||
|
if (!varargs) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (PySys_Audit("gc.get_referents", "(O)", varargs) < 0) {
|
||||||
|
Py_DECREF(varargs);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
PyInterpreterState *interp = _PyInterpreterState_GET();
|
PyInterpreterState *interp = _PyInterpreterState_GET();
|
||||||
PyObject *result = PyList_New(0);
|
PyObject *result = PyList_New(0);
|
||||||
|
|
||||||
if (result == NULL)
|
if (result == NULL) {
|
||||||
|
Py_DECREF(varargs);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: stop the world is a no-op in default build
|
// NOTE: stop the world is a no-op in default build
|
||||||
_PyEval_StopTheWorld(interp);
|
_PyEval_StopTheWorld(interp);
|
||||||
int err = append_referrents(result, args);
|
int err = append_referrents(result, varargs);
|
||||||
_PyEval_StartTheWorld(interp);
|
_PyEval_StartTheWorld(interp);
|
||||||
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
Py_CLEAR(result);
|
Py_CLEAR(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Py_DECREF(varargs);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,28 +41,22 @@ PyDoc_STRVAR(set_update__doc__,
|
||||||
{"update", _PyCFunction_CAST(set_update), METH_FASTCALL, set_update__doc__},
|
{"update", _PyCFunction_CAST(set_update), METH_FASTCALL, set_update__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_update_impl(PySetObject *so, PyObject *args);
|
set_update_impl(PySetObject *so, Py_ssize_t nargs, PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_update(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
set_update(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("update", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("update", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = set_update_impl(so, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = set_update_impl(so, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,28 +142,22 @@ PyDoc_STRVAR(set_union__doc__,
|
||||||
{"union", _PyCFunction_CAST(set_union), METH_FASTCALL, set_union__doc__},
|
{"union", _PyCFunction_CAST(set_union), METH_FASTCALL, set_union__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_union_impl(PySetObject *so, PyObject *args);
|
set_union_impl(PySetObject *so, Py_ssize_t nargs, PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_union(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
set_union(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("union", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("union", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = set_union_impl(so, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = set_union_impl(so, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,28 +171,23 @@ PyDoc_STRVAR(set_intersection_multi__doc__,
|
||||||
{"intersection", _PyCFunction_CAST(set_intersection_multi), METH_FASTCALL, set_intersection_multi__doc__},
|
{"intersection", _PyCFunction_CAST(set_intersection_multi), METH_FASTCALL, set_intersection_multi__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_intersection_multi_impl(PySetObject *so, PyObject *args);
|
set_intersection_multi_impl(PySetObject *so, Py_ssize_t nargs,
|
||||||
|
PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_intersection_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
set_intersection_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("intersection", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("intersection", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = set_intersection_multi_impl(so, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = set_intersection_multi_impl(so, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,28 +201,23 @@ PyDoc_STRVAR(set_intersection_update_multi__doc__,
|
||||||
{"intersection_update", _PyCFunction_CAST(set_intersection_update_multi), METH_FASTCALL, set_intersection_update_multi__doc__},
|
{"intersection_update", _PyCFunction_CAST(set_intersection_update_multi), METH_FASTCALL, set_intersection_update_multi__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_intersection_update_multi_impl(PySetObject *so, PyObject *args);
|
set_intersection_update_multi_impl(PySetObject *so, Py_ssize_t nargs,
|
||||||
|
PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_intersection_update_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
set_intersection_update_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("intersection_update", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("intersection_update", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = set_intersection_update_multi_impl(so, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = set_intersection_update_multi_impl(so, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,28 +255,23 @@ PyDoc_STRVAR(set_difference_update__doc__,
|
||||||
{"difference_update", _PyCFunction_CAST(set_difference_update), METH_FASTCALL, set_difference_update__doc__},
|
{"difference_update", _PyCFunction_CAST(set_difference_update), METH_FASTCALL, set_difference_update__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_difference_update_impl(PySetObject *so, PyObject *args);
|
set_difference_update_impl(PySetObject *so, Py_ssize_t nargs,
|
||||||
|
PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_difference_update(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
set_difference_update(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("difference_update", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("difference_update", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = set_difference_update_impl(so, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = set_difference_update_impl(so, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,28 +285,23 @@ PyDoc_STRVAR(set_difference_multi__doc__,
|
||||||
{"difference", _PyCFunction_CAST(set_difference_multi), METH_FASTCALL, set_difference_multi__doc__},
|
{"difference", _PyCFunction_CAST(set_difference_multi), METH_FASTCALL, set_difference_multi__doc__},
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_difference_multi_impl(PySetObject *so, PyObject *args);
|
set_difference_multi_impl(PySetObject *so, Py_ssize_t nargs,
|
||||||
|
PyObject *const *args);
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_difference_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
set_difference_multi(PySetObject *so, PyObject *const *args, Py_ssize_t nargs)
|
||||||
{
|
{
|
||||||
PyObject *return_value = NULL;
|
PyObject *return_value = NULL;
|
||||||
PyObject *__clinic_args = NULL;
|
Py_ssize_t nvararg = nargs - 0;
|
||||||
|
PyObject *const *__clinic_args = NULL;
|
||||||
|
|
||||||
if (!_PyArg_CheckPositional("difference", nargs, 0, PY_SSIZE_T_MAX)) {
|
if (!_PyArg_CheckPositional("difference", nargs, 0, PY_SSIZE_T_MAX)) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
__clinic_args = PyTuple_New(nargs - 0);
|
__clinic_args = args + 0;
|
||||||
if (!__clinic_args) {
|
return_value = set_difference_multi_impl(so, nvararg, __clinic_args);
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
for (Py_ssize_t i = 0; i < nargs - 0; ++i) {
|
|
||||||
PyTuple_SET_ITEM(__clinic_args, i, Py_NewRef(args[0 + i]));
|
|
||||||
}
|
|
||||||
return_value = set_difference_multi_impl(so, __clinic_args);
|
|
||||||
|
|
||||||
exit:
|
exit:
|
||||||
Py_XDECREF(__clinic_args);
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -568,4 +536,4 @@ set___sizeof__(PySetObject *so, PyObject *Py_UNUSED(ignored))
|
||||||
|
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=de4ee725bd29f758 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=9d4b41191b2c602f input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -1060,13 +1060,13 @@ Update the set, adding elements from all others.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_update_impl(PySetObject *so, PyObject *args)
|
set_update_impl(PySetObject *so, Py_ssize_t nargs, PyObject *const *args)
|
||||||
/*[clinic end generated code: output=34f6371704974c8a input=df4fe486e38cd337]*/
|
/*[clinic end generated code: output=050e2a21f8d7d16a input=df4fe486e38cd337]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
|
for (i = 0; i < nargs; i++) {
|
||||||
PyObject *other = PyTuple_GET_ITEM(args, i);
|
PyObject *other = args[i];
|
||||||
if (set_update_internal(so, other))
|
if (set_update_internal(so, other))
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1289,8 +1289,8 @@ Return a new set with elements from the set and all others.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_union_impl(PySetObject *so, PyObject *args)
|
set_union_impl(PySetObject *so, Py_ssize_t nargs, PyObject *const *args)
|
||||||
/*[clinic end generated code: output=2c83d05a446a1477 input=ddf088706e9577b2]*/
|
/*[clinic end generated code: output=f68ec24d5c19d404 input=ddf088706e9577b2]*/
|
||||||
{
|
{
|
||||||
PySetObject *result;
|
PySetObject *result;
|
||||||
PyObject *other;
|
PyObject *other;
|
||||||
|
@ -1300,8 +1300,8 @@ set_union_impl(PySetObject *so, PyObject *args)
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
|
for (i = 0; i < nargs; i++) {
|
||||||
other = PyTuple_GET_ITEM(args, i);
|
other = args[i];
|
||||||
if ((PyObject *)so == other)
|
if ((PyObject *)so == other)
|
||||||
continue;
|
continue;
|
||||||
if (set_update_local(result, other)) {
|
if (set_update_local(result, other)) {
|
||||||
|
@ -1440,18 +1440,19 @@ Return a new set with elements common to the set and all others.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_intersection_multi_impl(PySetObject *so, PyObject *args)
|
set_intersection_multi_impl(PySetObject *so, Py_ssize_t nargs,
|
||||||
/*[clinic end generated code: output=2406ef3387adbe2f input=0d9f3805ccbba6a4]*/
|
PyObject *const *args)
|
||||||
|
/*[clinic end generated code: output=ef0756ddb5f2dee9 input=0d9f3805ccbba6a4]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
if (PyTuple_GET_SIZE(args) == 0) {
|
if (nargs == 0) {
|
||||||
return set_copy(so, NULL);
|
return set_copy(so, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
PyObject *result = Py_NewRef(so);
|
PyObject *result = Py_NewRef(so);
|
||||||
for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
|
for (i = 0; i < nargs; i++) {
|
||||||
PyObject *other = PyTuple_GET_ITEM(args, i);
|
PyObject *other = args[i];
|
||||||
PyObject *newresult;
|
PyObject *newresult;
|
||||||
Py_BEGIN_CRITICAL_SECTION2(result, other);
|
Py_BEGIN_CRITICAL_SECTION2(result, other);
|
||||||
newresult = set_intersection((PySetObject *)result, other);
|
newresult = set_intersection((PySetObject *)result, other);
|
||||||
|
@ -1487,12 +1488,13 @@ Update the set, keeping only elements found in it and all others.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_intersection_update_multi_impl(PySetObject *so, PyObject *args)
|
set_intersection_update_multi_impl(PySetObject *so, Py_ssize_t nargs,
|
||||||
/*[clinic end generated code: output=251c1f729063609d input=223c1e086aa669a9]*/
|
PyObject *const *args)
|
||||||
|
/*[clinic end generated code: output=808d7ad1935b1dfe input=223c1e086aa669a9]*/
|
||||||
{
|
{
|
||||||
PyObject *tmp;
|
PyObject *tmp;
|
||||||
|
|
||||||
tmp = set_intersection_multi_impl(so, args);
|
tmp = set_intersection_multi_impl(so, nargs, args);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
Py_BEGIN_CRITICAL_SECTION(so);
|
Py_BEGIN_CRITICAL_SECTION(so);
|
||||||
|
@ -1676,13 +1678,14 @@ Update the set, removing elements found in others.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_difference_update_impl(PySetObject *so, PyObject *args)
|
set_difference_update_impl(PySetObject *so, Py_ssize_t nargs,
|
||||||
/*[clinic end generated code: output=28685b2fc63e41c4 input=024e6baa6fbcbb3d]*/
|
PyObject *const *args)
|
||||||
|
/*[clinic end generated code: output=55f850c27748d312 input=024e6baa6fbcbb3d]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
|
|
||||||
for (i=0 ; i<PyTuple_GET_SIZE(args) ; i++) {
|
for (i = 0; i < nargs; i++) {
|
||||||
PyObject *other = PyTuple_GET_ITEM(args, i);
|
PyObject *other = args[i];
|
||||||
int rv;
|
int rv;
|
||||||
Py_BEGIN_CRITICAL_SECTION2(so, other);
|
Py_BEGIN_CRITICAL_SECTION2(so, other);
|
||||||
rv = set_difference_update_internal(so, other);
|
rv = set_difference_update_internal(so, other);
|
||||||
|
@ -1793,25 +1796,26 @@ Return a new set with elements in the set that are not in the others.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
set_difference_multi_impl(PySetObject *so, PyObject *args)
|
set_difference_multi_impl(PySetObject *so, Py_ssize_t nargs,
|
||||||
/*[clinic end generated code: output=3130c3bb3cac873d input=ba78ea5f099e58df]*/
|
PyObject *const *args)
|
||||||
|
/*[clinic end generated code: output=8150d008c00523f3 input=ba78ea5f099e58df]*/
|
||||||
{
|
{
|
||||||
Py_ssize_t i;
|
Py_ssize_t i;
|
||||||
PyObject *result, *other;
|
PyObject *result, *other;
|
||||||
|
|
||||||
if (PyTuple_GET_SIZE(args) == 0) {
|
if (nargs == 0) {
|
||||||
return set_copy(so, NULL);
|
return set_copy(so, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
other = PyTuple_GET_ITEM(args, 0);
|
other = args[0];
|
||||||
Py_BEGIN_CRITICAL_SECTION2(so, other);
|
Py_BEGIN_CRITICAL_SECTION2(so, other);
|
||||||
result = set_difference(so, other);
|
result = set_difference(so, other);
|
||||||
Py_END_CRITICAL_SECTION2();
|
Py_END_CRITICAL_SECTION2();
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i=1 ; i<PyTuple_GET_SIZE(args) ; i++) {
|
for (i = 1; i < nargs; i++) {
|
||||||
other = PyTuple_GET_ITEM(args, i);
|
other = args[i];
|
||||||
int rv;
|
int rv;
|
||||||
Py_BEGIN_CRITICAL_SECTION(other);
|
Py_BEGIN_CRITICAL_SECTION(other);
|
||||||
rv = set_difference_update_internal((PySetObject *)result, other);
|
rv = set_difference_update_internal((PySetObject *)result, other);
|
||||||
|
|
|
@ -15,7 +15,7 @@ from libclinic.function import (
|
||||||
Module, Class, Function, Parameter,
|
Module, Class, Function, Parameter,
|
||||||
permute_optional_groups,
|
permute_optional_groups,
|
||||||
GETTER, SETTER, METHOD_INIT)
|
GETTER, SETTER, METHOD_INIT)
|
||||||
from libclinic.converters import self_converter
|
from libclinic.converters import defining_class_converter, self_converter
|
||||||
from libclinic.parse_args import ParseArgsCodeGen
|
from libclinic.parse_args import ParseArgsCodeGen
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from libclinic.app import Clinic
|
from libclinic.app import Clinic
|
||||||
|
@ -396,6 +396,12 @@ class CLanguage(Language):
|
||||||
first_optional = len(selfless)
|
first_optional = len(selfless)
|
||||||
positional = selfless and selfless[-1].is_positional_only()
|
positional = selfless and selfless[-1].is_positional_only()
|
||||||
has_option_groups = False
|
has_option_groups = False
|
||||||
|
requires_defining_class = (len(selfless)
|
||||||
|
and isinstance(selfless[0].converter,
|
||||||
|
defining_class_converter))
|
||||||
|
pass_vararg_directly = (all(p.is_positional_only() or p.is_vararg()
|
||||||
|
for p in selfless)
|
||||||
|
and not requires_defining_class)
|
||||||
|
|
||||||
# offset i by -1 because first_optional needs to ignore self
|
# offset i by -1 because first_optional needs to ignore self
|
||||||
for i, p in enumerate(parameters, -1):
|
for i, p in enumerate(parameters, -1):
|
||||||
|
@ -404,7 +410,7 @@ class CLanguage(Language):
|
||||||
if (i != -1) and (p.default is not unspecified):
|
if (i != -1) and (p.default is not unspecified):
|
||||||
first_optional = min(first_optional, i)
|
first_optional = min(first_optional, i)
|
||||||
|
|
||||||
if p.is_vararg():
|
if p.is_vararg() and not pass_vararg_directly:
|
||||||
data.cleanup.append(f"Py_XDECREF({c.parser_name});")
|
data.cleanup.append(f"Py_XDECREF({c.parser_name});")
|
||||||
|
|
||||||
# insert group variable
|
# insert group variable
|
||||||
|
@ -418,6 +424,11 @@ class CLanguage(Language):
|
||||||
data.impl_parameters.append("int " + group_name)
|
data.impl_parameters.append("int " + group_name)
|
||||||
has_option_groups = True
|
has_option_groups = True
|
||||||
|
|
||||||
|
if p.is_vararg() and pass_vararg_directly:
|
||||||
|
data.impl_arguments.append('nvararg')
|
||||||
|
data.impl_parameters.append('Py_ssize_t nargs')
|
||||||
|
p.converter.type = 'PyObject *const *'
|
||||||
|
|
||||||
c.render(p, data)
|
c.render(p, data)
|
||||||
|
|
||||||
if has_option_groups and (not positional):
|
if has_option_groups and (not positional):
|
||||||
|
|
|
@ -469,7 +469,11 @@ class ParseArgsCodeGen:
|
||||||
nargs = 'PyTuple_GET_SIZE(args)'
|
nargs = 'PyTuple_GET_SIZE(args)'
|
||||||
argname_fmt = 'PyTuple_GET_ITEM(args, %d)'
|
argname_fmt = 'PyTuple_GET_ITEM(args, %d)'
|
||||||
|
|
||||||
left_args = f"{nargs} - {self.max_pos}"
|
if self.vararg != NO_VARARG:
|
||||||
|
self.declarations = f"Py_ssize_t nvararg = {nargs} - {self.max_pos};"
|
||||||
|
else:
|
||||||
|
self.declarations = ""
|
||||||
|
|
||||||
max_args = NO_VARARG if (self.vararg != NO_VARARG) else self.max_pos
|
max_args = NO_VARARG if (self.vararg != NO_VARARG) else self.max_pos
|
||||||
if self.limited_capi:
|
if self.limited_capi:
|
||||||
parser_code = []
|
parser_code = []
|
||||||
|
@ -518,30 +522,13 @@ class ParseArgsCodeGen:
|
||||||
use_parser_code = True
|
use_parser_code = True
|
||||||
for i, p in enumerate(self.parameters):
|
for i, p in enumerate(self.parameters):
|
||||||
if p.is_vararg():
|
if p.is_vararg():
|
||||||
|
var = p.converter.parser_name
|
||||||
if self.fastcall:
|
if self.fastcall:
|
||||||
parser_code.append(libclinic.normalize_snippet("""
|
code = f"{var} = args + {self.vararg};"
|
||||||
%s = PyTuple_New(%s);
|
|
||||||
if (!%s) {{
|
|
||||||
goto exit;
|
|
||||||
}}
|
|
||||||
for (Py_ssize_t i = 0; i < %s; ++i) {{
|
|
||||||
PyTuple_SET_ITEM(%s, i, Py_NewRef(args[%d + i]));
|
|
||||||
}}
|
|
||||||
""" % (
|
|
||||||
p.converter.parser_name,
|
|
||||||
left_args,
|
|
||||||
p.converter.parser_name,
|
|
||||||
left_args,
|
|
||||||
p.converter.parser_name,
|
|
||||||
self.max_pos
|
|
||||||
), indent=4))
|
|
||||||
else:
|
else:
|
||||||
parser_code.append(libclinic.normalize_snippet("""
|
code = f"{var} = _PyTuple_CAST(args)->ob_item;"
|
||||||
%s = PyTuple_GetSlice(%d, -1);
|
formatted_code = libclinic.normalize_snippet(code, indent=4)
|
||||||
""" % (
|
parser_code.append(formatted_code)
|
||||||
p.converter.parser_name,
|
|
||||||
self.max_pos
|
|
||||||
), indent=4))
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
displayname = p.get_displayname(i+1)
|
displayname = p.get_displayname(i+1)
|
||||||
|
@ -588,7 +575,7 @@ class ParseArgsCodeGen:
|
||||||
goto exit;
|
goto exit;
|
||||||
}}
|
}}
|
||||||
""", indent=4)]
|
""", indent=4)]
|
||||||
self.parser_body(*parser_code)
|
self.parser_body(*parser_code, declarations=self.declarations)
|
||||||
|
|
||||||
def parse_general(self, clang: CLanguage) -> None:
|
def parse_general(self, clang: CLanguage) -> None:
|
||||||
parsearg: str | None
|
parsearg: str | None
|
||||||
|
|
Loading…
Reference in New Issue