mirror of https://github.com/python/cpython
gh-86457: Fix signature for code.replace() (GH-23199)
Also add support of @text_signature in Argument Clinic.
This commit is contained in:
parent
bea5f93196
commit
0e6e32fb84
|
@ -0,0 +1,2 @@
|
||||||
|
Argument Clinic now supports overriding automatically generated signature by
|
||||||
|
using directive `@text_signature`.
|
|
@ -154,12 +154,7 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
PyDoc_STRVAR(code_replace__doc__,
|
PyDoc_STRVAR(code_replace__doc__,
|
||||||
"replace($self, /, *, co_argcount=-1, co_posonlyargcount=-1,\n"
|
"replace($self, /, **changes)\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"
|
|
||||||
"--\n"
|
"--\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Return a copy of the code object with new values for the specified fields.");
|
"Return a copy of the code object with new values for the specified fields.");
|
||||||
|
@ -171,13 +166,12 @@ static PyObject *
|
||||||
code_replace_impl(PyCodeObject *self, int co_argcount,
|
code_replace_impl(PyCodeObject *self, int co_argcount,
|
||||||
int co_posonlyargcount, int co_kwonlyargcount,
|
int co_posonlyargcount, int co_kwonlyargcount,
|
||||||
int co_nlocals, int co_stacksize, int co_flags,
|
int co_nlocals, int co_stacksize, int co_flags,
|
||||||
int co_firstlineno, PyBytesObject *co_code,
|
int co_firstlineno, PyObject *co_code, PyObject *co_consts,
|
||||||
PyObject *co_consts, PyObject *co_names,
|
PyObject *co_names, PyObject *co_varnames,
|
||||||
PyObject *co_varnames, PyObject *co_freevars,
|
PyObject *co_freevars, PyObject *co_cellvars,
|
||||||
PyObject *co_cellvars, PyObject *co_filename,
|
PyObject *co_filename, PyObject *co_name,
|
||||||
PyObject *co_name, PyObject *co_qualname,
|
PyObject *co_qualname, PyObject *co_linetable,
|
||||||
PyBytesObject *co_linetable,
|
PyObject *co_exceptiontable);
|
||||||
PyBytesObject *co_exceptiontable);
|
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
|
||||||
|
@ -217,7 +211,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
|
||||||
int co_stacksize = self->co_stacksize;
|
int co_stacksize = self->co_stacksize;
|
||||||
int co_flags = self->co_flags;
|
int co_flags = self->co_flags;
|
||||||
int co_firstlineno = self->co_firstlineno;
|
int co_firstlineno = self->co_firstlineno;
|
||||||
PyBytesObject *co_code = NULL;
|
PyObject *co_code = NULL;
|
||||||
PyObject *co_consts = self->co_consts;
|
PyObject *co_consts = self->co_consts;
|
||||||
PyObject *co_names = self->co_names;
|
PyObject *co_names = self->co_names;
|
||||||
PyObject *co_varnames = NULL;
|
PyObject *co_varnames = NULL;
|
||||||
|
@ -226,8 +220,8 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
|
||||||
PyObject *co_filename = self->co_filename;
|
PyObject *co_filename = self->co_filename;
|
||||||
PyObject *co_name = self->co_name;
|
PyObject *co_name = self->co_name;
|
||||||
PyObject *co_qualname = self->co_qualname;
|
PyObject *co_qualname = self->co_qualname;
|
||||||
PyBytesObject *co_linetable = (PyBytesObject *)self->co_linetable;
|
PyObject *co_linetable = self->co_linetable;
|
||||||
PyBytesObject *co_exceptiontable = (PyBytesObject *)self->co_exceptiontable;
|
PyObject *co_exceptiontable = self->co_exceptiontable;
|
||||||
|
|
||||||
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf);
|
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 0, 0, argsbuf);
|
||||||
if (!args) {
|
if (!args) {
|
||||||
|
@ -304,7 +298,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
|
||||||
_PyArg_BadArgument("replace", "argument 'co_code'", "bytes", args[7]);
|
_PyArg_BadArgument("replace", "argument 'co_code'", "bytes", args[7]);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
co_code = (PyBytesObject *)args[7];
|
co_code = args[7];
|
||||||
if (!--noptargs) {
|
if (!--noptargs) {
|
||||||
goto skip_optional_kwonly;
|
goto skip_optional_kwonly;
|
||||||
}
|
}
|
||||||
|
@ -394,7 +388,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
|
||||||
_PyArg_BadArgument("replace", "argument 'co_linetable'", "bytes", args[16]);
|
_PyArg_BadArgument("replace", "argument 'co_linetable'", "bytes", args[16]);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
co_linetable = (PyBytesObject *)args[16];
|
co_linetable = args[16];
|
||||||
if (!--noptargs) {
|
if (!--noptargs) {
|
||||||
goto skip_optional_kwonly;
|
goto skip_optional_kwonly;
|
||||||
}
|
}
|
||||||
|
@ -403,7 +397,7 @@ code_replace(PyCodeObject *self, PyObject *const *args, Py_ssize_t nargs, PyObje
|
||||||
_PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[17]);
|
_PyArg_BadArgument("replace", "argument 'co_exceptiontable'", "bytes", args[17]);
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
co_exceptiontable = (PyBytesObject *)args[17];
|
co_exceptiontable = args[17];
|
||||||
skip_optional_kwonly:
|
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);
|
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);
|
||||||
|
|
||||||
|
@ -470,4 +464,4 @@ code__varname_from_oparg(PyCodeObject *self, PyObject *const *args, Py_ssize_t n
|
||||||
exit:
|
exit:
|
||||||
return return_value;
|
return return_value;
|
||||||
}
|
}
|
||||||
/*[clinic end generated code: output=4ca4c0c403dbfa71 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=16c95266bbc4bc03 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -1968,27 +1968,28 @@ code_linesiterator(PyCodeObject *code, PyObject *Py_UNUSED(args))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*[clinic input]
|
/*[clinic input]
|
||||||
|
@text_signature "($self, /, **changes)"
|
||||||
code.replace
|
code.replace
|
||||||
|
|
||||||
*
|
*
|
||||||
co_argcount: int(c_default="self->co_argcount") = -1
|
co_argcount: int(c_default="self->co_argcount") = unchanged
|
||||||
co_posonlyargcount: int(c_default="self->co_posonlyargcount") = -1
|
co_posonlyargcount: int(c_default="self->co_posonlyargcount") = unchanged
|
||||||
co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = -1
|
co_kwonlyargcount: int(c_default="self->co_kwonlyargcount") = unchanged
|
||||||
co_nlocals: int(c_default="self->co_nlocals") = -1
|
co_nlocals: int(c_default="self->co_nlocals") = unchanged
|
||||||
co_stacksize: int(c_default="self->co_stacksize") = -1
|
co_stacksize: int(c_default="self->co_stacksize") = unchanged
|
||||||
co_flags: int(c_default="self->co_flags") = -1
|
co_flags: int(c_default="self->co_flags") = unchanged
|
||||||
co_firstlineno: int(c_default="self->co_firstlineno") = -1
|
co_firstlineno: int(c_default="self->co_firstlineno") = unchanged
|
||||||
co_code: PyBytesObject(c_default="NULL") = None
|
co_code: object(subclass_of="&PyBytes_Type", c_default="NULL") = unchanged
|
||||||
co_consts: object(subclass_of="&PyTuple_Type", c_default="self->co_consts") = None
|
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") = None
|
co_names: object(subclass_of="&PyTuple_Type", c_default="self->co_names") = unchanged
|
||||||
co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
|
co_varnames: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
|
||||||
co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
|
co_freevars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
|
||||||
co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = None
|
co_cellvars: object(subclass_of="&PyTuple_Type", c_default="NULL") = unchanged
|
||||||
co_filename: unicode(c_default="self->co_filename") = None
|
co_filename: unicode(c_default="self->co_filename") = unchanged
|
||||||
co_name: unicode(c_default="self->co_name") = None
|
co_name: unicode(c_default="self->co_name") = unchanged
|
||||||
co_qualname: unicode(c_default="self->co_qualname") = None
|
co_qualname: unicode(c_default="self->co_qualname") = unchanged
|
||||||
co_linetable: PyBytesObject(c_default="(PyBytesObject *)self->co_linetable") = None
|
co_linetable: object(subclass_of="&PyBytes_Type", c_default="self->co_linetable") = unchanged
|
||||||
co_exceptiontable: PyBytesObject(c_default="(PyBytesObject *)self->co_exceptiontable") = None
|
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.
|
Return a copy of the code object with new values for the specified fields.
|
||||||
[clinic start generated code]*/
|
[clinic start generated code]*/
|
||||||
|
@ -1997,14 +1998,13 @@ static PyObject *
|
||||||
code_replace_impl(PyCodeObject *self, int co_argcount,
|
code_replace_impl(PyCodeObject *self, int co_argcount,
|
||||||
int co_posonlyargcount, int co_kwonlyargcount,
|
int co_posonlyargcount, int co_kwonlyargcount,
|
||||||
int co_nlocals, int co_stacksize, int co_flags,
|
int co_nlocals, int co_stacksize, int co_flags,
|
||||||
int co_firstlineno, PyBytesObject *co_code,
|
int co_firstlineno, PyObject *co_code, PyObject *co_consts,
|
||||||
PyObject *co_consts, PyObject *co_names,
|
PyObject *co_names, PyObject *co_varnames,
|
||||||
PyObject *co_varnames, PyObject *co_freevars,
|
PyObject *co_freevars, PyObject *co_cellvars,
|
||||||
PyObject *co_cellvars, PyObject *co_filename,
|
PyObject *co_filename, PyObject *co_name,
|
||||||
PyObject *co_name, PyObject *co_qualname,
|
PyObject *co_qualname, PyObject *co_linetable,
|
||||||
PyBytesObject *co_linetable,
|
PyObject *co_exceptiontable)
|
||||||
PyBytesObject *co_exceptiontable)
|
/*[clinic end generated code: output=e75c48a15def18b9 input=18e280e07846c122]*/
|
||||||
/*[clinic end generated code: output=b6cd9988391d5711 input=f6f68e03571f8d7c]*/
|
|
||||||
{
|
{
|
||||||
#define CHECK_INT_ARG(ARG) \
|
#define CHECK_INT_ARG(ARG) \
|
||||||
if (ARG < 0) { \
|
if (ARG < 0) { \
|
||||||
|
@ -2029,7 +2029,7 @@ code_replace_impl(PyCodeObject *self, int co_argcount,
|
||||||
if (code == NULL) {
|
if (code == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
co_code = (PyBytesObject *)code;
|
co_code = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PySys_Audit("code.__new__", "OOOiiiiii",
|
if (PySys_Audit("code.__new__", "OOOiiiiii",
|
||||||
|
@ -2068,10 +2068,10 @@ code_replace_impl(PyCodeObject *self, int co_argcount,
|
||||||
|
|
||||||
co = PyCode_NewWithPosOnlyArgs(
|
co = PyCode_NewWithPosOnlyArgs(
|
||||||
co_argcount, co_posonlyargcount, co_kwonlyargcount, co_nlocals,
|
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_varnames, co_freevars, co_cellvars, co_filename, co_name,
|
||||||
co_qualname, co_firstlineno,
|
co_qualname, co_firstlineno,
|
||||||
(PyObject*)co_linetable, (PyObject*)co_exceptiontable);
|
co_linetable, co_exceptiontable);
|
||||||
|
|
||||||
error:
|
error:
|
||||||
Py_XDECREF(code);
|
Py_XDECREF(code);
|
||||||
|
|
|
@ -4595,6 +4595,7 @@ class DSLParser:
|
||||||
self.indent = IndentStack()
|
self.indent = IndentStack()
|
||||||
self.kind = CALLABLE
|
self.kind = CALLABLE
|
||||||
self.coexist = False
|
self.coexist = False
|
||||||
|
self.forced_text_signature: str | None = None
|
||||||
self.parameter_continuation = ''
|
self.parameter_continuation = ''
|
||||||
self.preserve_output = False
|
self.preserve_output = False
|
||||||
|
|
||||||
|
@ -4735,6 +4736,11 @@ class DSLParser:
|
||||||
fail("Called @coexist twice!")
|
fail("Called @coexist twice!")
|
||||||
self.coexist = True
|
self.coexist = True
|
||||||
|
|
||||||
|
def at_text_signature(self, text_signature: str) -> None:
|
||||||
|
if self.forced_text_signature:
|
||||||
|
fail("Called @text_signature twice!")
|
||||||
|
self.forced_text_signature = text_signature
|
||||||
|
|
||||||
def parse(self, block: Block) -> None:
|
def parse(self, block: Block) -> None:
|
||||||
self.reset()
|
self.reset()
|
||||||
self.block = block
|
self.block = block
|
||||||
|
@ -5515,142 +5521,145 @@ class DSLParser:
|
||||||
add(f.cls.name)
|
add(f.cls.name)
|
||||||
else:
|
else:
|
||||||
add(f.name)
|
add(f.name)
|
||||||
add('(')
|
if self.forced_text_signature:
|
||||||
|
add(self.forced_text_signature)
|
||||||
|
else:
|
||||||
|
add('(')
|
||||||
|
|
||||||
# populate "right_bracket_count" field for every parameter
|
# populate "right_bracket_count" field for every parameter
|
||||||
assert parameters, "We should always have a self parameter. " + repr(f)
|
assert parameters, "We should always have a self parameter. " + repr(f)
|
||||||
assert isinstance(parameters[0].converter, self_converter)
|
assert isinstance(parameters[0].converter, self_converter)
|
||||||
# self is always positional-only.
|
# self is always positional-only.
|
||||||
assert parameters[0].is_positional_only()
|
assert parameters[0].is_positional_only()
|
||||||
assert parameters[0].right_bracket_count == 0
|
assert parameters[0].right_bracket_count == 0
|
||||||
positional_only = True
|
positional_only = True
|
||||||
for p in parameters[1:]:
|
for p in parameters[1:]:
|
||||||
if not p.is_positional_only():
|
if not p.is_positional_only():
|
||||||
positional_only = False
|
positional_only = False
|
||||||
else:
|
else:
|
||||||
assert positional_only
|
assert positional_only
|
||||||
if positional_only:
|
if positional_only:
|
||||||
p.right_bracket_count = abs(p.group)
|
p.right_bracket_count = abs(p.group)
|
||||||
else:
|
else:
|
||||||
# don't put any right brackets around non-positional-only parameters, ever.
|
# don't put any right brackets around non-positional-only parameters, ever.
|
||||||
p.right_bracket_count = 0
|
p.right_bracket_count = 0
|
||||||
|
|
||||||
right_bracket_count = 0
|
right_bracket_count = 0
|
||||||
|
|
||||||
def fix_right_bracket_count(desired: int) -> str:
|
def fix_right_bracket_count(desired: int) -> str:
|
||||||
nonlocal right_bracket_count
|
nonlocal right_bracket_count
|
||||||
s = ''
|
s = ''
|
||||||
while right_bracket_count < desired:
|
while right_bracket_count < desired:
|
||||||
s += '['
|
s += '['
|
||||||
right_bracket_count += 1
|
right_bracket_count += 1
|
||||||
while right_bracket_count > desired:
|
while right_bracket_count > desired:
|
||||||
s += ']'
|
s += ']'
|
||||||
right_bracket_count -= 1
|
right_bracket_count -= 1
|
||||||
return s
|
return s
|
||||||
|
|
||||||
need_slash = False
|
need_slash = False
|
||||||
added_slash = False
|
added_slash = False
|
||||||
need_a_trailing_slash = False
|
need_a_trailing_slash = False
|
||||||
|
|
||||||
# we only need a trailing slash:
|
# we only need a trailing slash:
|
||||||
# * if this is not a "docstring_only" signature
|
# * if this is not a "docstring_only" signature
|
||||||
# * and if the last *shown* parameter is
|
# * and if the last *shown* parameter is
|
||||||
# positional only
|
# positional only
|
||||||
if not f.docstring_only:
|
if not f.docstring_only:
|
||||||
for p in reversed(parameters):
|
for p in reversed(parameters):
|
||||||
|
if not p.converter.show_in_signature:
|
||||||
|
continue
|
||||||
|
if p.is_positional_only():
|
||||||
|
need_a_trailing_slash = True
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
added_star = False
|
||||||
|
|
||||||
|
first_parameter = True
|
||||||
|
last_p = parameters[-1]
|
||||||
|
line_length = len(''.join(text))
|
||||||
|
indent = " " * line_length
|
||||||
|
def add_parameter(text: str) -> None:
|
||||||
|
nonlocal line_length
|
||||||
|
nonlocal first_parameter
|
||||||
|
if first_parameter:
|
||||||
|
s = text
|
||||||
|
first_parameter = False
|
||||||
|
else:
|
||||||
|
s = ' ' + text
|
||||||
|
if line_length + len(s) >= 72:
|
||||||
|
add('\n')
|
||||||
|
add(indent)
|
||||||
|
line_length = len(indent)
|
||||||
|
s = text
|
||||||
|
line_length += len(s)
|
||||||
|
add(s)
|
||||||
|
|
||||||
|
for p in parameters:
|
||||||
if not p.converter.show_in_signature:
|
if not p.converter.show_in_signature:
|
||||||
continue
|
continue
|
||||||
|
assert p.name
|
||||||
|
|
||||||
|
is_self = isinstance(p.converter, self_converter)
|
||||||
|
if is_self and f.docstring_only:
|
||||||
|
# this isn't a real machine-parsable signature,
|
||||||
|
# so let's not print the "self" parameter
|
||||||
|
continue
|
||||||
|
|
||||||
if p.is_positional_only():
|
if p.is_positional_only():
|
||||||
need_a_trailing_slash = True
|
need_slash = not f.docstring_only
|
||||||
break
|
elif need_slash and not (added_slash or p.is_positional_only()):
|
||||||
|
added_slash = True
|
||||||
|
add_parameter('/,')
|
||||||
|
|
||||||
|
if p.is_keyword_only() and not added_star:
|
||||||
|
added_star = True
|
||||||
|
add_parameter('*,')
|
||||||
|
|
||||||
added_star = False
|
p_add, p_output = text_accumulator()
|
||||||
|
p_add(fix_right_bracket_count(p.right_bracket_count))
|
||||||
|
|
||||||
first_parameter = True
|
if isinstance(p.converter, self_converter):
|
||||||
last_p = parameters[-1]
|
# annotate first parameter as being a "self".
|
||||||
line_length = len(''.join(text))
|
#
|
||||||
indent = " " * line_length
|
# if inspect.Signature gets this function,
|
||||||
def add_parameter(text: str) -> None:
|
# and it's already bound, the self parameter
|
||||||
nonlocal line_length
|
# will be stripped off.
|
||||||
nonlocal first_parameter
|
#
|
||||||
if first_parameter:
|
# if it's not bound, it should be marked
|
||||||
s = text
|
# as positional-only.
|
||||||
first_parameter = False
|
#
|
||||||
else:
|
# note: we don't print "self" for __init__,
|
||||||
s = ' ' + text
|
# because this isn't actually the signature
|
||||||
if line_length + len(s) >= 72:
|
# for __init__. (it can't be, __init__ doesn't
|
||||||
add('\n')
|
# have a docstring.) if this is an __init__
|
||||||
add(indent)
|
# (or __new__), then this signature is for
|
||||||
line_length = len(indent)
|
# calling the class to construct a new instance.
|
||||||
s = text
|
p_add('$')
|
||||||
line_length += len(s)
|
|
||||||
add(s)
|
|
||||||
|
|
||||||
for p in parameters:
|
if p.is_vararg():
|
||||||
if not p.converter.show_in_signature:
|
p_add("*")
|
||||||
continue
|
|
||||||
assert p.name
|
|
||||||
|
|
||||||
is_self = isinstance(p.converter, self_converter)
|
name = p.converter.signature_name or p.name
|
||||||
if is_self and f.docstring_only:
|
p_add(name)
|
||||||
# this isn't a real machine-parsable signature,
|
|
||||||
# so let's not print the "self" parameter
|
|
||||||
continue
|
|
||||||
|
|
||||||
if p.is_positional_only():
|
if not p.is_vararg() and p.converter.is_optional():
|
||||||
need_slash = not f.docstring_only
|
p_add('=')
|
||||||
elif need_slash and not (added_slash or p.is_positional_only()):
|
value = p.converter.py_default
|
||||||
added_slash = True
|
if not value:
|
||||||
add_parameter('/,')
|
value = repr(p.converter.default)
|
||||||
|
p_add(value)
|
||||||
|
|
||||||
if p.is_keyword_only() and not added_star:
|
if (p != last_p) or need_a_trailing_slash:
|
||||||
added_star = True
|
p_add(',')
|
||||||
add_parameter('*,')
|
|
||||||
|
|
||||||
p_add, p_output = text_accumulator()
|
add_parameter(p_output())
|
||||||
p_add(fix_right_bracket_count(p.right_bracket_count))
|
|
||||||
|
|
||||||
if isinstance(p.converter, self_converter):
|
add(fix_right_bracket_count(0))
|
||||||
# annotate first parameter as being a "self".
|
if need_a_trailing_slash:
|
||||||
#
|
add_parameter('/')
|
||||||
# if inspect.Signature gets this function,
|
add(')')
|
||||||
# and it's already bound, the self parameter
|
|
||||||
# will be stripped off.
|
|
||||||
#
|
|
||||||
# if it's not bound, it should be marked
|
|
||||||
# as positional-only.
|
|
||||||
#
|
|
||||||
# note: we don't print "self" for __init__,
|
|
||||||
# because this isn't actually the signature
|
|
||||||
# for __init__. (it can't be, __init__ doesn't
|
|
||||||
# have a docstring.) if this is an __init__
|
|
||||||
# (or __new__), then this signature is for
|
|
||||||
# calling the class to construct a new instance.
|
|
||||||
p_add('$')
|
|
||||||
|
|
||||||
if p.is_vararg():
|
|
||||||
p_add("*")
|
|
||||||
|
|
||||||
name = p.converter.signature_name or p.name
|
|
||||||
p_add(name)
|
|
||||||
|
|
||||||
if not p.is_vararg() and p.converter.is_optional():
|
|
||||||
p_add('=')
|
|
||||||
value = p.converter.py_default
|
|
||||||
if not value:
|
|
||||||
value = repr(p.converter.default)
|
|
||||||
p_add(value)
|
|
||||||
|
|
||||||
if (p != last_p) or need_a_trailing_slash:
|
|
||||||
p_add(',')
|
|
||||||
|
|
||||||
add_parameter(p_output())
|
|
||||||
|
|
||||||
add(fix_right_bracket_count(0))
|
|
||||||
if need_a_trailing_slash:
|
|
||||||
add_parameter('/')
|
|
||||||
add(')')
|
|
||||||
|
|
||||||
# PEP 8 says:
|
# PEP 8 says:
|
||||||
#
|
#
|
||||||
|
|
Loading…
Reference in New Issue