Skip to content

Commit 6720e7f

Browse files
[3.10] pythongh-94430: Allow params named module or self with custom C names in Argument Clinic (pythonGH-94431).
(cherry picked from commit 8bbd70b) Co-authored-by: Erlend Egeberg Aasland <[email protected]>
1 parent 663aa6e commit 6720e7f

File tree

3 files changed

+270
-2
lines changed

3 files changed

+270
-2
lines changed

Lib/test/clinic.test

Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3308,3 +3308,264 @@ test_preprocessor_guarded_else(PyObject *module, PyObject *Py_UNUSED(ignored))
33083308
#define TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF
33093309
#endif /* !defined(TEST_PREPROCESSOR_GUARDED_ELSE_METHODDEF) */
33103310
/*[clinic end generated code: output=3804bb18d454038c input=3fc80c9989d2f2e1]*/
3311+
3312+
/*[clinic input]
3313+
test_vararg_and_posonly
3314+
3315+
3316+
a: object
3317+
*args: object
3318+
/
3319+
3320+
[clinic start generated code]*/
3321+
3322+
PyDoc_STRVAR(test_vararg_and_posonly__doc__,
3323+
"test_vararg_and_posonly($module, a, /, *args)\n"
3324+
"--\n"
3325+
"\n");
3326+
3327+
#define TEST_VARARG_AND_POSONLY_METHODDEF \
3328+
{"test_vararg_and_posonly", _PyCFunction_CAST(test_vararg_and_posonly), METH_FASTCALL, test_vararg_and_posonly__doc__},
3329+
3330+
static PyObject *
3331+
test_vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args);
3332+
3333+
static PyObject *
3334+
test_vararg_and_posonly(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
3335+
{
3336+
PyObject *return_value = NULL;
3337+
PyObject *a;
3338+
PyObject *__clinic_args = NULL;
3339+
3340+
if (!_PyArg_CheckPositional("test_vararg_and_posonly", nargs, 1, PY_SSIZE_T_MAX)) {
3341+
goto exit;
3342+
}
3343+
a = args[0];
3344+
__clinic_args = PyTuple_New(nargs - 1);
3345+
for (Py_ssize_t i = 0; i < nargs - 1; ++i) {
3346+
PyTuple_SET_ITEM(__clinic_args, i, args[1 + i]);
3347+
}
3348+
return_value = test_vararg_and_posonly_impl(module, a, __clinic_args);
3349+
3350+
exit:
3351+
Py_XDECREF(__clinic_args);
3352+
return return_value;
3353+
}
3354+
3355+
static PyObject *
3356+
test_vararg_and_posonly_impl(PyObject *module, PyObject *a, PyObject *args)
3357+
/*[clinic end generated code: output=548bca3a127c22c1 input=08dc2bf7afbf1613]*/
3358+
3359+
/*[clinic input]
3360+
test_vararg
3361+
3362+
3363+
a: object
3364+
*args: object
3365+
3366+
[clinic start generated code]*/
3367+
3368+
PyDoc_STRVAR(test_vararg__doc__,
3369+
"test_vararg($module, /, a, *args)\n"
3370+
"--\n"
3371+
"\n");
3372+
3373+
#define TEST_VARARG_METHODDEF \
3374+
{"test_vararg", _PyCFunction_CAST(test_vararg), METH_FASTCALL|METH_KEYWORDS, test_vararg__doc__},
3375+
3376+
static PyObject *
3377+
test_vararg_impl(PyObject *module, PyObject *a, PyObject *args);
3378+
3379+
static PyObject *
3380+
test_vararg(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
3381+
{
3382+
PyObject *return_value = NULL;
3383+
static const char * const _keywords[] = {"a", NULL};
3384+
static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg", 0};
3385+
PyObject *argsbuf[2];
3386+
Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
3387+
PyObject *a;
3388+
PyObject *__clinic_args = NULL;
3389+
3390+
args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf);
3391+
if (!args) {
3392+
goto exit;
3393+
}
3394+
a = args[0];
3395+
__clinic_args = args[1];
3396+
return_value = test_vararg_impl(module, a, __clinic_args);
3397+
3398+
exit:
3399+
Py_XDECREF(__clinic_args);
3400+
return return_value;
3401+
}
3402+
3403+
static PyObject *
3404+
test_vararg_impl(PyObject *module, PyObject *a, PyObject *args)
3405+
/*[clinic end generated code: output=a2baf8c1fade41d2 input=81d33815ad1bae6e]*/
3406+
3407+
/*[clinic input]
3408+
test_vararg_with_default
3409+
3410+
3411+
a: object
3412+
*args: object
3413+
b: bool = False
3414+
3415+
[clinic start generated code]*/
3416+
3417+
PyDoc_STRVAR(test_vararg_with_default__doc__,
3418+
"test_vararg_with_default($module, /, a, *args, b=False)\n"
3419+
"--\n"
3420+
"\n");
3421+
3422+
#define TEST_VARARG_WITH_DEFAULT_METHODDEF \
3423+
{"test_vararg_with_default", _PyCFunction_CAST(test_vararg_with_default), METH_FASTCALL|METH_KEYWORDS, test_vararg_with_default__doc__},
3424+
3425+
static PyObject *
3426+
test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args,
3427+
int b);
3428+
3429+
static PyObject *
3430+
test_vararg_with_default(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
3431+
{
3432+
PyObject *return_value = NULL;
3433+
static const char * const _keywords[] = {"a", "b", NULL};
3434+
static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_default", 0};
3435+
PyObject *argsbuf[3];
3436+
Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
3437+
PyObject *a;
3438+
PyObject *__clinic_args = NULL;
3439+
int b = 0;
3440+
3441+
args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, 1, argsbuf);
3442+
if (!args) {
3443+
goto exit;
3444+
}
3445+
a = args[0];
3446+
__clinic_args = args[1];
3447+
if (!noptargs) {
3448+
goto skip_optional_kwonly;
3449+
}
3450+
b = PyObject_IsTrue(args[2]);
3451+
if (b < 0) {
3452+
goto exit;
3453+
}
3454+
skip_optional_kwonly:
3455+
return_value = test_vararg_with_default_impl(module, a, __clinic_args, b);
3456+
3457+
exit:
3458+
Py_XDECREF(__clinic_args);
3459+
return return_value;
3460+
}
3461+
3462+
static PyObject *
3463+
test_vararg_with_default_impl(PyObject *module, PyObject *a, PyObject *args,
3464+
int b)
3465+
/*[clinic end generated code: output=3821d282c29f8616 input=6e110b54acd9b22d]*/
3466+
3467+
/*[clinic input]
3468+
test_vararg_with_only_defaults
3469+
3470+
3471+
*args: object
3472+
b: bool = False
3473+
c: object = ' '
3474+
3475+
[clinic start generated code]*/
3476+
3477+
PyDoc_STRVAR(test_vararg_with_only_defaults__doc__,
3478+
"test_vararg_with_only_defaults($module, /, *args, b=False, c=\' \')\n"
3479+
"--\n"
3480+
"\n");
3481+
3482+
#define TEST_VARARG_WITH_ONLY_DEFAULTS_METHODDEF \
3483+
{"test_vararg_with_only_defaults", _PyCFunction_CAST(test_vararg_with_only_defaults), METH_FASTCALL|METH_KEYWORDS, test_vararg_with_only_defaults__doc__},
3484+
3485+
static PyObject *
3486+
test_vararg_with_only_defaults_impl(PyObject *module, PyObject *args, int b,
3487+
PyObject *c);
3488+
3489+
static PyObject *
3490+
test_vararg_with_only_defaults(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
3491+
{
3492+
PyObject *return_value = NULL;
3493+
static const char * const _keywords[] = {"b", "c", NULL};
3494+
static _PyArg_Parser _parser = {NULL, _keywords, "test_vararg_with_only_defaults", 0};
3495+
PyObject *argsbuf[3];
3496+
Py_ssize_t noptargs = 0 + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
3497+
PyObject *__clinic_args = NULL;
3498+
int b = 0;
3499+
PyObject *c = " ";
3500+
3501+
args = _PyArg_UnpackKeywordsWithVararg(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, 0, argsbuf);
3502+
if (!args) {
3503+
goto exit;
3504+
}
3505+
__clinic_args = args[0];
3506+
if (!noptargs) {
3507+
goto skip_optional_kwonly;
3508+
}
3509+
if (args[1]) {
3510+
b = PyObject_IsTrue(args[1]);
3511+
if (b < 0) {
3512+
goto exit;
3513+
}
3514+
if (!--noptargs) {
3515+
goto skip_optional_kwonly;
3516+
}
3517+
}
3518+
c = args[2];
3519+
skip_optional_kwonly:
3520+
return_value = test_vararg_with_only_defaults_impl(module, __clinic_args, b, c);
3521+
3522+
exit:
3523+
Py_XDECREF(__clinic_args);
3524+
return return_value;
3525+
}
3526+
3527+
static PyObject *
3528+
test_vararg_with_only_defaults_impl(PyObject *module, PyObject *args, int b,
3529+
PyObject *c)
3530+
/*[clinic end generated code: output=7e393689e6ce61a3 input=fa56a709a035666e]*/
3531+
3532+
/*[clinic input]
3533+
test_paramname_module
3534+
3535+
module as mod: object
3536+
[clinic start generated code]*/
3537+
3538+
PyDoc_STRVAR(test_paramname_module__doc__,
3539+
"test_paramname_module($module, /, module)\n"
3540+
"--\n"
3541+
"\n");
3542+
3543+
#define TEST_PARAMNAME_MODULE_METHODDEF \
3544+
{"test_paramname_module", _PyCFunction_CAST(test_paramname_module), METH_FASTCALL|METH_KEYWORDS, test_paramname_module__doc__},
3545+
3546+
static PyObject *
3547+
test_paramname_module_impl(PyObject *module, PyObject *mod);
3548+
3549+
static PyObject *
3550+
test_paramname_module(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
3551+
{
3552+
PyObject *return_value = NULL;
3553+
static const char * const _keywords[] = {"module", NULL};
3554+
static _PyArg_Parser _parser = {NULL, _keywords, "test_paramname_module", 0};
3555+
PyObject *argsbuf[1];
3556+
PyObject *mod;
3557+
3558+
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
3559+
if (!args) {
3560+
goto exit;
3561+
}
3562+
mod = args[0];
3563+
return_value = test_paramname_module_impl(module, mod);
3564+
3565+
exit:
3566+
return return_value;
3567+
}
3568+
3569+
static PyObject *
3570+
test_paramname_module_impl(PyObject *module, PyObject *mod)
3571+
/*[clinic end generated code: output=23379a7ffa65c514 input=afefe259667f13ba]*/
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Allow parameters named ``module`` and ``self`` with custom C names in Argument
2+
Clinic. Patch by Erlend E. Aasland

Tools/clinic/clinic.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4626,9 +4626,14 @@ def bad_node(self, node):
46264626

46274627
p = Parameter(parameter_name, kind, function=self.function, converter=converter, default=value, group=self.group)
46284628

4629-
if parameter_name in self.function.parameters:
4629+
names = [k.name for k in self.function.parameters.values()]
4630+
if parameter_name in names[1:]:
46304631
fail("You can't have two parameters named " + repr(parameter_name) + "!")
4631-
self.function.parameters[parameter_name] = p
4632+
elif names and parameter_name == names[0] and c_name is None:
4633+
fail(f"Parameter '{parameter_name}' requires a custom C name")
4634+
4635+
key = f"{parameter_name}_as_{c_name}" if c_name else parameter_name
4636+
self.function.parameters[key] = p
46324637

46334638
def parse_converter(self, annotation):
46344639
if (hasattr(ast, 'Constant') and

0 commit comments

Comments
 (0)