[3.11] gh-86457: Fix signature for code.replace() (GH-23199) (GH-107746)

Also add support of @text_signature in Argument Clinic.
(cherry picked from commit 0e6e32fb84)
This commit is contained in:
Serhiy Storchaka 2023-08-09 09:12:02 +03:00 committed by GitHub
parent 0aa3b9d76c
commit edaa0db93e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 173 additions and 168 deletions

View file

@ -0,0 +1,2 @@
Argument Clinic now supports overriding automatically generated signature by
using directive ``@text_signature``.

View file

@ -157,12 +157,7 @@ exit:
}
PyDoc_STRVAR(code_replace__doc__,
"replace($self, /, *, co_argcount=-1, co_posonlyargcount=-1,\n"
" co_kwonlyargcount=-1, co_nlocals=-1, co_stacksize=-1,\n"
" co_flags=-1, co_firstlineno=-1, co_code=None, co_consts=None,\n"
" co_names=None, co_varnames=None, co_freevars=None,\n"
" co_cellvars=None, co_filename=None, co_name=None,\n"
" co_qualname=None, co_linetable=None, co_exceptiontable=None)\n"
"replace($self, /, **changes)\n"
"--\n"
"\n"
"Return a copy of the code object with new values for the specified fields.");
@ -174,13 +169,12 @@ static PyObject *
code_replace_impl(PyCodeObject *self, int co_argcount,
int co_posonlyargcount, int co_kwonlyargcount,
int co_nlocals, int co_stacksize, int co_flags,
int co_firstlineno, PyBytesObject *co_code,
PyObject *co_consts, PyObject *co_names,
PyObject *co_varnames, PyObject *co_freevars,
PyObject *co_cellvars, PyObject *co_filename,
PyObject *co_name, PyObject *co_qualname,
PyBytesObject *co_linetable,
PyBytesObject *co_exceptiontable);
int co_firstlineno, PyObject *co_code, PyObject *co_consts,
PyObject *co_names, PyObject *co_varnames,
PyObject *co_freevars, PyObject *co_cellvars,
PyObject *co_filename, PyObject *co_name,
PyObject *co_qualname, PyObject *co_linetable,
PyObject *co_exceptiontable);
static PyObject *
code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@ -197,7 +191,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
int co_stacksize = self->co_stacksize;
int co_flags = self->co_flags;
int co_firstlineno = self->co_firstlineno;
PyBytesObject *co_code = NULL;
PyObject *co_code = NULL;
PyObject *co_consts = self->co_consts;
PyObject *co_names = self->co_names;
PyObject *co_varnames = NULL;
@ -206,8 +200,8 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
PyObject *co_filename = self->co_filename;
PyObject *co_name = self->co_name;
PyObject *co_qualname = self->co_qualname;
PyBytesObject *co_linetable = (PyBytesObject *)self->co_linetable;
PyBytesObject *co_exceptiontable = (PyBytesObject *)self->co_exceptiontable;
PyObject *co_linetable = self->co_linetable;
PyObject *co_exceptiontable = self->co_exceptiontable;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf);
if (!args) {
@ -284,7 +278,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
_PyArg_BadArgument("replace", "argument 'co_code'", "bytes", args[7]);
goto exit;
}
co_code = (PyBytesObject *)args[7];
co_code = args[7];
if (!--noptargs) {
goto skip_optional_kwonly;
}
@ -383,7 +377,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
_PyArg_BadArgument("replace", "argument 'co_linetable'", "bytes", args[16]);
goto exit;
}
co_linetable = (PyBytesObject *)args[16];
co_linetable = args[16];
if (!--noptargs) {
goto skip_optional_kwonly;
}
@ -392,7 +386,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
_PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[17]);
goto exit;
}
co_exceptiontable = (PyBytesObject *)args[17];
co_exceptiontable = args[17];
skip_optional_kwonly:
return_value = code_replace_impl(self, co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals, co_stacksize, co_flags, co_firstlineno, co_code, co_consts, co_names, co_varnames, co_freevars, co_cellvars, co_filename, co_name, co_qualname, co_linetable, co_exceptiontable);
@ -436,4 +430,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n
exit:
return return_value;
}
/*[clinic end generated code: output=9c521b6c79f90ff7 input=a9049054013a1b77]*/
/*[clinic end generated code: output=d1bbf51b746ca2d0 input=a9049054013a1b77]*/

View file

@ -1875,27 +1875,28 @@ code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args))
}
/*[clinic input]
@text_signature "($self, /, **changes)"
code.replace
*
co_argcount: int(c_default="self->co_argcount") = -1
co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1
co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1
co_nlocals: int(c_default="self->co_nlocals") = -1
co_stacksize: int(c_default="self->co_stacksize") = -1
co_flags: int(c_default="self->co_flags") = -1
co_firstlineno: int(c_default="self->co_firstlineno") = -1
co_code: PyBytesObject(c_default="NULL") = None
co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None
co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = None
co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
co_filename: unicode(c_default="self->co_filename") = None
co_name: unicode(c_default="self->co_name") = None
co_qualname: unicode(c_default="self->co_qualname") = None
co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None
co_exceptiontable: PyBytesObject(c_default="(PyBytesObject *)self->co_exceptiontable") = None
co_argcount: int(c_default="self->co_argcount") = unchanged
co_posonlyargcount: int(c_default="self->co_posonlyargcount") = unchanged
co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = unchanged
co_nlocals: int(c_default="self->co_nlocals") = unchanged
co_stacksize: int(c_default="self->co_stacksize") = unchanged
co_flags: int(c_default="self->co_flags") = unchanged
co_firstlineno: int(c_default="self->co_firstlineno") = unchanged
co_code: object(subclass_of="&PyBytes_Type", c_default="NULL") = unchanged
co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = unchanged
co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = unchanged
co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
co_filename: unicode(c_default="self->co_filename") = unchanged
co_name: unicode(c_default="self->co_name") = unchanged
co_qualname: unicode(c_default="self->co_qualname") = unchanged
co_linetable: object(subclass_of="&PyBytes_Type", c_default="self->co_linetable") = unchanged
co_exceptiontable: object(subclass_of="&PyBytes_Type", c_default="self->co_exceptiontable") = unchanged
Return a copy of the code object with new values for the specified fields.
[clinic start generated code]*/
@ -1904,14 +1905,13 @@ static PyObject *
code_replace_impl(PyCodeObject *self, int co_argcount,
int co_posonlyargcount, int co_kwonlyargcount,
int co_nlocals, int co_stacksize, int co_flags,
int co_firstlineno, PyBytesObject *co_code,
PyObject *co_consts, PyObject *co_names,
PyObject *co_varnames, PyObject *co_freevars,
PyObject *co_cellvars, PyObject *co_filename,
PyObject *co_name, PyObject *co_qualname,
PyBytesObject *co_linetable,
PyBytesObject *co_exceptiontable)
/*[clinic end generated code: output=b6cd9988391d5711 input=f6f68e03571f8d7c]*/
int co_firstlineno, PyObject *co_code, PyObject *co_consts,
PyObject *co_names, PyObject *co_varnames,
PyObject *co_freevars, PyObject *co_cellvars,
PyObject *co_filename, PyObject *co_name,
PyObject *co_qualname, PyObject *co_linetable,
PyObject *co_exceptiontable)
/*[clinic end generated code: output=e75c48a15def18b9 input=18e280e07846c122]*/
{
#define CHECK_INT_ARG(ARG) \
if (ARG < 0) { \
@ -1936,7 +1936,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount,
if (code == NULL) {
return NULL;
}
co_code = (PyBytesObject *)code;
co_code = code;
}
if (PySys_Audit("code.__new__", "OOOiiiiii",
@ -1975,10 +1975,10 @@ code_replace_impl(PyCodeObject *self, int co_argcount,
co = PyCode_NewWithPosOnlyArgs(
co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
co_stacksize, co_flags, (PyObject*)co_code, co_consts, co_names,
co_stacksize, co_flags, co_code, co_consts, co_names,
co_varnames, co_freevars, co_cellvars, co_filename, co_name,
co_qualname, co_firstlineno,
(PyObject*)co_linetable, (PyObject*)co_exceptiontable);
co_linetable, co_exceptiontable);
error:
Py_XDECREF(code);

View file

@ -4072,6 +4072,7 @@ class DSLParser:
self.indent = IndentStack()
self.kind = CALLABLE
self.coexist = False
self.forced_text_signature: str | None = None
self.parameter_continuation = ''
self.preserve_output = False
@ -4201,6 +4202,11 @@ class DSLParser:
fail("Called @coexist twice!")
self.coexist = True
def at_text_signature(self, text_signature):
if self.forced_text_signature:
fail("Called @text_signature twice!")
self.forced_text_signature = text_signature
def parse(self, block):
self.reset()
self.block = block
@ -4903,6 +4909,9 @@ class DSLParser:
add(f.cls.name)
else:
add(f.name)
if self.forced_text_signature:
add(self.forced_text_signature)
else:
add('(')
# populate "right_bracket_count" field for every parameter