mirror of https://github.com/python/cpython
Issue #20586: Argument Clinic now ensures signatures on functions without docstrings.
This commit is contained in:
parent
a6cc551502
commit
8ef887ce47
|
@ -123,7 +123,7 @@ class CAPITest(unittest.TestCase):
|
||||||
self.assertEqual(_testcapi.no_docstring.__doc__, None)
|
self.assertEqual(_testcapi.no_docstring.__doc__, None)
|
||||||
self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
|
self.assertEqual(_testcapi.no_docstring.__text_signature__, None)
|
||||||
|
|
||||||
self.assertEqual(_testcapi.docstring_empty.__doc__, "")
|
self.assertEqual(_testcapi.docstring_empty.__doc__, None)
|
||||||
self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
|
self.assertEqual(_testcapi.docstring_empty.__text_signature__, None)
|
||||||
|
|
||||||
self.assertEqual(_testcapi.docstring_no_signature.__doc__,
|
self.assertEqual(_testcapi.docstring_no_signature.__doc__,
|
||||||
|
@ -150,6 +150,10 @@ class CAPITest(unittest.TestCase):
|
||||||
"This docstring has a valid signature.")
|
"This docstring has a valid signature.")
|
||||||
self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)")
|
self.assertEqual(_testcapi.docstring_with_signature.__text_signature__, "($module, /, sig)")
|
||||||
|
|
||||||
|
self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__doc__, None)
|
||||||
|
self.assertEqual(_testcapi.docstring_with_signature_but_no_doc.__text_signature__,
|
||||||
|
"($module, /, sig)")
|
||||||
|
|
||||||
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
|
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__doc__,
|
||||||
"\nThis docstring has a valid signature and some extra newlines.")
|
"\nThis docstring has a valid signature and some extra newlines.")
|
||||||
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
|
self.assertEqual(_testcapi.docstring_with_signature_and_extra_newlines.__text_signature__,
|
||||||
|
|
|
@ -1864,6 +1864,9 @@ class TestSignatureObject(unittest.TestCase):
|
||||||
test_unbound_method(dict.__delitem__)
|
test_unbound_method(dict.__delitem__)
|
||||||
test_unbound_method(property.__delete__)
|
test_unbound_method(property.__delete__)
|
||||||
|
|
||||||
|
# Regression test for issue #20586
|
||||||
|
test_callable(_testcapi.docstring_with_signature_but_no_doc)
|
||||||
|
|
||||||
@cpython_only
|
@cpython_only
|
||||||
@unittest.skipIf(MISSING_C_DOCSTRINGS,
|
@unittest.skipIf(MISSING_C_DOCSTRINGS,
|
||||||
"Signature information for builtins requires docstrings")
|
"Signature information for builtins requires docstrings")
|
||||||
|
|
|
@ -156,6 +156,9 @@ Tests
|
||||||
Tools/Demos
|
Tools/Demos
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
|
- Issue #20586: Argument Clinic now ensures that functions without docstrings
|
||||||
|
have signatures.
|
||||||
|
|
||||||
- Issue #23492: Argument Clinic now generates argument parsing code with
|
- Issue #23492: Argument Clinic now generates argument parsing code with
|
||||||
PyArg_Parse instead of PyArg_ParseTuple if possible.
|
PyArg_Parse instead of PyArg_ParseTuple if possible.
|
||||||
|
|
||||||
|
|
|
@ -3083,6 +3083,12 @@ PyDoc_STRVAR(docstring_with_signature,
|
||||||
"This docstring has a valid signature."
|
"This docstring has a valid signature."
|
||||||
);
|
);
|
||||||
|
|
||||||
|
PyDoc_STRVAR(docstring_with_signature_but_no_doc,
|
||||||
|
"docstring_with_signature_but_no_doc($module, /, sig)\n"
|
||||||
|
"--\n"
|
||||||
|
"\n"
|
||||||
|
);
|
||||||
|
|
||||||
PyDoc_STRVAR(docstring_with_signature_and_extra_newlines,
|
PyDoc_STRVAR(docstring_with_signature_and_extra_newlines,
|
||||||
"docstring_with_signature_and_extra_newlines($module, /, parameter)\n"
|
"docstring_with_signature_and_extra_newlines($module, /, parameter)\n"
|
||||||
"--\n"
|
"--\n"
|
||||||
|
@ -3635,6 +3641,9 @@ static PyMethodDef TestMethods[] = {
|
||||||
{"docstring_with_signature",
|
{"docstring_with_signature",
|
||||||
(PyCFunction)test_with_docstring, METH_NOARGS,
|
(PyCFunction)test_with_docstring, METH_NOARGS,
|
||||||
docstring_with_signature},
|
docstring_with_signature},
|
||||||
|
{"docstring_with_signature_but_no_doc",
|
||||||
|
(PyCFunction)test_with_docstring, METH_NOARGS,
|
||||||
|
docstring_with_signature_but_no_doc},
|
||||||
{"docstring_with_signature_and_extra_newlines",
|
{"docstring_with_signature_and_extra_newlines",
|
||||||
(PyCFunction)test_with_docstring, METH_NOARGS,
|
(PyCFunction)test_with_docstring, METH_NOARGS,
|
||||||
docstring_with_signature_and_extra_newlines},
|
docstring_with_signature_and_extra_newlines},
|
||||||
|
|
|
@ -78,7 +78,8 @@ exit:
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_encode__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_encode__doc__,
|
||||||
"encode($self, /, input, final=0)\n"
|
"encode($self, /, input, final=0)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_ENCODE_METHODDEF \
|
||||||
{"encode", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_encode, METH_VARARGS|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalEncoder_encode__doc__},
|
{"encode", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_encode, METH_VARARGS|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalEncoder_encode__doc__},
|
||||||
|
@ -106,7 +107,8 @@ exit:
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_reset__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalEncoder_reset__doc__,
|
||||||
"reset($self, /)\n"
|
"reset($self, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALENCODER_RESET_METHODDEF \
|
||||||
{"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalEncoder_reset__doc__},
|
{"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalEncoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalEncoder_reset__doc__},
|
||||||
|
@ -122,7 +124,8 @@ _multibytecodec_MultibyteIncrementalEncoder_reset(MultibyteIncrementalEncoderObj
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_decode__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_decode__doc__,
|
||||||
"decode($self, /, input, final=0)\n"
|
"decode($self, /, input, final=0)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_DECODE_METHODDEF \
|
||||||
{"decode", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_decode, METH_VARARGS|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalDecoder_decode__doc__},
|
{"decode", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_decode, METH_VARARGS|METH_KEYWORDS, _multibytecodec_MultibyteIncrementalDecoder_decode__doc__},
|
||||||
|
@ -154,7 +157,8 @@ exit:
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_reset__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteIncrementalDecoder_reset__doc__,
|
||||||
"reset($self, /)\n"
|
"reset($self, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTEINCREMENTALDECODER_RESET_METHODDEF \
|
||||||
{"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalDecoder_reset__doc__},
|
{"reset", (PyCFunction)_multibytecodec_MultibyteIncrementalDecoder_reset, METH_NOARGS, _multibytecodec_MultibyteIncrementalDecoder_reset__doc__},
|
||||||
|
@ -170,7 +174,8 @@ _multibytecodec_MultibyteIncrementalDecoder_reset(MultibyteIncrementalDecoderObj
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_read__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_read__doc__,
|
||||||
"read($self, sizeobj=None, /)\n"
|
"read($self, sizeobj=None, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READ_METHODDEF \
|
||||||
{"read", (PyCFunction)_multibytecodec_MultibyteStreamReader_read, METH_VARARGS, _multibytecodec_MultibyteStreamReader_read__doc__},
|
{"read", (PyCFunction)_multibytecodec_MultibyteStreamReader_read, METH_VARARGS, _multibytecodec_MultibyteStreamReader_read__doc__},
|
||||||
|
@ -196,7 +201,8 @@ exit:
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readline__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readline__doc__,
|
||||||
"readline($self, sizeobj=None, /)\n"
|
"readline($self, sizeobj=None, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINE_METHODDEF \
|
||||||
{"readline", (PyCFunction)_multibytecodec_MultibyteStreamReader_readline, METH_VARARGS, _multibytecodec_MultibyteStreamReader_readline__doc__},
|
{"readline", (PyCFunction)_multibytecodec_MultibyteStreamReader_readline, METH_VARARGS, _multibytecodec_MultibyteStreamReader_readline__doc__},
|
||||||
|
@ -222,7 +228,8 @@ exit:
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readlines__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_readlines__doc__,
|
||||||
"readlines($self, sizehintobj=None, /)\n"
|
"readlines($self, sizehintobj=None, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_READLINES_METHODDEF \
|
||||||
{"readlines", (PyCFunction)_multibytecodec_MultibyteStreamReader_readlines, METH_VARARGS, _multibytecodec_MultibyteStreamReader_readlines__doc__},
|
{"readlines", (PyCFunction)_multibytecodec_MultibyteStreamReader_readlines, METH_VARARGS, _multibytecodec_MultibyteStreamReader_readlines__doc__},
|
||||||
|
@ -248,7 +255,8 @@ exit:
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_reset__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteStreamReader_reset__doc__,
|
||||||
"reset($self, /)\n"
|
"reset($self, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTESTREAMREADER_RESET_METHODDEF \
|
||||||
{"reset", (PyCFunction)_multibytecodec_MultibyteStreamReader_reset, METH_NOARGS, _multibytecodec_MultibyteStreamReader_reset__doc__},
|
{"reset", (PyCFunction)_multibytecodec_MultibyteStreamReader_reset, METH_NOARGS, _multibytecodec_MultibyteStreamReader_reset__doc__},
|
||||||
|
@ -264,21 +272,24 @@ _multibytecodec_MultibyteStreamReader_reset(MultibyteStreamReaderObject *self, P
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_write__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_write__doc__,
|
||||||
"write($self, strobj, /)\n"
|
"write($self, strobj, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITE_METHODDEF \
|
||||||
{"write", (PyCFunction)_multibytecodec_MultibyteStreamWriter_write, METH_O, _multibytecodec_MultibyteStreamWriter_write__doc__},
|
{"write", (PyCFunction)_multibytecodec_MultibyteStreamWriter_write, METH_O, _multibytecodec_MultibyteStreamWriter_write__doc__},
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_writelines__doc__,
|
||||||
"writelines($self, lines, /)\n"
|
"writelines($self, lines, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_WRITELINES_METHODDEF \
|
||||||
{"writelines", (PyCFunction)_multibytecodec_MultibyteStreamWriter_writelines, METH_O, _multibytecodec_MultibyteStreamWriter_writelines__doc__},
|
{"writelines", (PyCFunction)_multibytecodec_MultibyteStreamWriter_writelines, METH_O, _multibytecodec_MultibyteStreamWriter_writelines__doc__},
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__,
|
PyDoc_STRVAR(_multibytecodec_MultibyteStreamWriter_reset__doc__,
|
||||||
"reset($self, /)\n"
|
"reset($self, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF \
|
#define _MULTIBYTECODEC_MULTIBYTESTREAMWRITER_RESET_METHODDEF \
|
||||||
{"reset", (PyCFunction)_multibytecodec_MultibyteStreamWriter_reset, METH_NOARGS, _multibytecodec_MultibyteStreamWriter_reset__doc__},
|
{"reset", (PyCFunction)_multibytecodec_MultibyteStreamWriter_reset, METH_NOARGS, _multibytecodec_MultibyteStreamWriter_reset__doc__},
|
||||||
|
@ -294,8 +305,9 @@ _multibytecodec_MultibyteStreamWriter_reset(MultibyteStreamWriterObject *self, P
|
||||||
|
|
||||||
PyDoc_STRVAR(_multibytecodec___create_codec__doc__,
|
PyDoc_STRVAR(_multibytecodec___create_codec__doc__,
|
||||||
"__create_codec($module, arg, /)\n"
|
"__create_codec($module, arg, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \
|
#define _MULTIBYTECODEC___CREATE_CODEC_METHODDEF \
|
||||||
{"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__},
|
{"__create_codec", (PyCFunction)_multibytecodec___create_codec, METH_O, _multibytecodec___create_codec__doc__},
|
||||||
/*[clinic end generated code: output=dff1459dec464796 input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=0ea29cd57f7cbc1a input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -209,7 +209,8 @@ exit:
|
||||||
|
|
||||||
PyDoc_STRVAR(pyexpat_xmlparser___dir____doc__,
|
PyDoc_STRVAR(pyexpat_xmlparser___dir____doc__,
|
||||||
"__dir__($self, /)\n"
|
"__dir__($self, /)\n"
|
||||||
"--");
|
"--\n"
|
||||||
|
"\n");
|
||||||
|
|
||||||
#define PYEXPAT_XMLPARSER___DIR___METHODDEF \
|
#define PYEXPAT_XMLPARSER___DIR___METHODDEF \
|
||||||
{"__dir__", (PyCFunction)pyexpat_xmlparser___dir__, METH_NOARGS, pyexpat_xmlparser___dir____doc__},
|
{"__dir__", (PyCFunction)pyexpat_xmlparser___dir__, METH_NOARGS, pyexpat_xmlparser___dir____doc__},
|
||||||
|
@ -286,4 +287,4 @@ exit:
|
||||||
#ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF
|
#ifndef PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF
|
||||||
#define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF
|
#define PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF
|
||||||
#endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */
|
#endif /* !defined(PYEXPAT_XMLPARSER_USEFOREIGNDTD_METHODDEF) */
|
||||||
/*[clinic end generated code: output=9715b916f2d618fa input=a9049054013a1b77]*/
|
/*[clinic end generated code: output=e5993de4e9dd2236 input=a9049054013a1b77]*/
|
||||||
|
|
|
@ -137,7 +137,7 @@ _PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc)
|
||||||
{
|
{
|
||||||
const char *doc = _PyType_DocWithoutSignature(name, internal_doc);
|
const char *doc = _PyType_DocWithoutSignature(name, internal_doc);
|
||||||
|
|
||||||
if (!doc) {
|
if (!doc || *doc == '\0') {
|
||||||
Py_INCREF(Py_None);
|
Py_INCREF(Py_None);
|
||||||
return Py_None;
|
return Py_None;
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,6 +66,8 @@ class Unknown:
|
||||||
|
|
||||||
unknown = Unknown()
|
unknown = Unknown()
|
||||||
|
|
||||||
|
sig_end_marker = '--'
|
||||||
|
|
||||||
|
|
||||||
_text_accumulator_nt = collections.namedtuple("_text_accumulator", "text append output")
|
_text_accumulator_nt = collections.namedtuple("_text_accumulator", "text append output")
|
||||||
|
|
||||||
|
@ -559,8 +561,13 @@ class CLanguage(Language):
|
||||||
add(quoted_for_c_string(line))
|
add(quoted_for_c_string(line))
|
||||||
add('\\n"\n')
|
add('\\n"\n')
|
||||||
|
|
||||||
text.pop()
|
if text[-2] == sig_end_marker:
|
||||||
add('"')
|
# If we only have a signature, add the blank line that the
|
||||||
|
# __text_signature__ getter expects to be there.
|
||||||
|
add('"\\n"')
|
||||||
|
else:
|
||||||
|
text.pop()
|
||||||
|
add('"')
|
||||||
return ''.join(text)
|
return ''.join(text)
|
||||||
|
|
||||||
def output_templates(self, f):
|
def output_templates(self, f):
|
||||||
|
@ -4015,7 +4022,7 @@ class DSLParser:
|
||||||
# add(f.return_converter.py_default)
|
# add(f.return_converter.py_default)
|
||||||
|
|
||||||
if not f.docstring_only:
|
if not f.docstring_only:
|
||||||
add("\n--\n")
|
add("\n" + sig_end_marker + "\n")
|
||||||
|
|
||||||
docstring_first_line = output()
|
docstring_first_line = output()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue