summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/object.h4
-rw-r--r--Lib/inspect.py115
-rw-r--r--Lib/test/test_capi.py17
-rw-r--r--Lib/test/test_inspect.py73
-rw-r--r--Misc/NEWS14
-rw-r--r--Modules/_cryptmodule.c6
-rw-r--r--Modules/_datetimemodule.c6
-rw-r--r--Modules/_dbmmodule.c12
-rw-r--r--Modules/_opcode.c6
-rw-r--r--Modules/_sre.c6
-rw-r--r--Modules/_testcapimodule.c27
-rw-r--r--Modules/_weakref.c6
-rw-r--r--Modules/clinic/_bz2module.c.h22
-rw-r--r--Modules/clinic/_lzmamodule.c.h30
-rw-r--r--Modules/clinic/_pickle.c.h68
-rw-r--r--Modules/clinic/audioop.c.h107
-rw-r--r--Modules/clinic/binascii.c.h58
-rw-r--r--Modules/clinic/zlibmodule.c.h52
-rw-r--r--Modules/posixmodule.c19
-rw-r--r--Modules/unicodedata.c6
-rw-r--r--Objects/descrobject.c12
-rw-r--r--Objects/dictobject.c12
-rw-r--r--Objects/methodobject.c4
-rw-r--r--Objects/typeobject.c189
-rw-r--r--Objects/unicodeobject.c6
-rw-r--r--Python/import.c72
-rwxr-xr-xTools/clinic/clinic.py160
-rw-r--r--Tools/clinic/clinic_test.py43
28 files changed, 825 insertions, 327 deletions
diff --git a/Include/object.h b/Include/object.h
index 68ca7b4..7584d4c 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -496,8 +496,8 @@ PyAPI_FUNC(unsigned int) PyType_ClearCache(void);
PyAPI_FUNC(void) PyType_Modified(PyTypeObject *);
#ifndef Py_LIMITED_API
-PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *);
-PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *);
+PyAPI_FUNC(PyObject *) _PyType_GetDocFromInternalDoc(const char *, const char *);
+PyAPI_FUNC(PyObject *) _PyType_GetTextSignatureFromInternalDoc(const char *, const char *);
#endif
/* Generic operations on objects */
diff --git a/Lib/inspect.py b/Lib/inspect.py
index 7a2739f..017a7e8 100644
--- a/Lib/inspect.py
+++ b/Lib/inspect.py
@@ -39,6 +39,7 @@ import os
import re
import sys
import tokenize
+import token
import types
import warnings
import functools
@@ -1648,25 +1649,88 @@ def _signature_get_bound_param(spec):
return spec[2:pos]
+def _signature_strip_non_python_syntax(signature):
+ """
+ Takes a signature in Argument Clinic's extended signature format.
+ Returns a tuple of three things:
+ * that signature re-rendered in standard Python syntax,
+ * the index of the "self" parameter (generally 0), or None if
+ the function does not have a "self" parameter, and
+ * the index of the last "positional only" parameter,
+ or None if the signature has no positional-only parameters.
+ """
+
+ if not signature:
+ return signature, None, None
+
+ self_parameter = None
+ last_positional_only = None
+
+ lines = [l.encode('ascii') for l in signature.split('\n')]
+ generator = iter(lines).__next__
+ token_stream = tokenize.tokenize(generator)
+
+ delayed_comma = False
+ skip_next_comma = False
+ text = []
+ add = text.append
+
+ current_parameter = 0
+ OP = token.OP
+ ERRORTOKEN = token.ERRORTOKEN
+
+ # token stream always starts with ENCODING token, skip it
+ t = next(token_stream)
+ assert t.type == tokenize.ENCODING
+
+ for t in token_stream:
+ type, string = t.type, t.string
+
+ if type == OP:
+ if string == ',':
+ if skip_next_comma:
+ skip_next_comma = False
+ else:
+ assert not delayed_comma
+ delayed_comma = True
+ current_parameter += 1
+ continue
+
+ if string == '/':
+ assert not skip_next_comma
+ assert last_positional_only is None
+ skip_next_comma = True
+ last_positional_only = current_parameter - 1
+ continue
+
+ if (type == ERRORTOKEN) and (string == '$'):
+ assert self_parameter is None
+ self_parameter = current_parameter
+ continue
+
+ if delayed_comma:
+ delayed_comma = False
+ if not ((type == OP) and (string == ')')):
+ add(', ')
+ add(string)
+ if (string == ','):
+ add(' ')
+ clean_signature = ''.join(text)
+ return clean_signature, self_parameter, last_positional_only
+
+
def _signature_fromstr(cls, obj, s):
# Internal helper to parse content of '__text_signature__'
# and return a Signature based on it
Parameter = cls._parameter_cls
- if s.endswith("/)"):
- kind = Parameter.POSITIONAL_ONLY
- s = s[:-2] + ')'
- else:
- kind = Parameter.POSITIONAL_OR_KEYWORD
-
- first_parameter_is_self = s.startswith("($")
- if first_parameter_is_self:
- s = '(' + s[2:]
+ clean_signature, self_parameter, last_positional_only = \
+ _signature_strip_non_python_syntax(s)
- s = "def foo" + s + ": pass"
+ program = "def foo" + clean_signature + ": pass"
try:
- module = ast.parse(s)
+ module = ast.parse(program)
except SyntaxError:
module = None
@@ -1750,8 +1814,14 @@ def _signature_fromstr(cls, obj, s):
args = reversed(f.args.args)
defaults = reversed(f.args.defaults)
iter = itertools.zip_longest(args, defaults, fillvalue=None)
- for name, default in reversed(list(iter)):
+ if last_positional_only is not None:
+ kind = Parameter.POSITIONAL_ONLY
+ else:
+ kind = Parameter.POSITIONAL_OR_KEYWORD
+ for i, (name, default) in enumerate(reversed(list(iter))):
p(name, default)
+ if i == last_positional_only:
+ kind = Parameter.POSITIONAL_OR_KEYWORD
# *args
if f.args.vararg:
@@ -1768,7 +1838,7 @@ def _signature_fromstr(cls, obj, s):
kind = Parameter.VAR_KEYWORD
p(f.args.kwarg, empty)
- if first_parameter_is_self:
+ if self_parameter is not None:
assert parameters
if getattr(obj, '__self__', None):
# strip off self, it's already been bound
@@ -1861,12 +1931,13 @@ def signature(obj):
# At this point we know, that `obj` is a class, with no user-
# defined '__init__', '__new__', or class-level '__call__'
- for base in obj.__mro__:
+ for base in obj.__mro__[:-1]:
# Since '__text_signature__' is implemented as a
# descriptor that extracts text signature from the
# class docstring, if 'obj' is derived from a builtin
# class, its own '__text_signature__' may be 'None'.
- # Therefore, we go through the MRO to find the first
+ # Therefore, we go through the MRO (except the last
+ # class in there, which is 'object') to find the first
# class with non-empty text signature.
try:
text_sig = base.__text_signature__
@@ -1881,13 +1952,7 @@ def signature(obj):
# No '__text_signature__' was found for the 'obj' class.
# Last option is to check if its '__init__' is
# object.__init__ or type.__init__.
- if type in obj.__mro__:
- # 'obj' is a metaclass without user-defined __init__
- # or __new__.
- if obj.__init__ is type.__init__:
- # Return a signature of 'type' builtin.
- return signature(type)
- else:
+ if type not in obj.__mro__:
# We have a class (not metaclass), but no user-defined
# __init__ or __new__ for it
if obj.__init__ is object.__init__:
@@ -1901,7 +1966,11 @@ def signature(obj):
# infinite recursion (and even potential segfault)
call = _signature_get_user_defined_method(type(obj), '__call__')
if call is not None:
- sig = signature(call)
+ try:
+ sig = signature(call)
+ except ValueError as ex:
+ msg = 'no signature found for {!r}'.format(obj)
+ raise ValueError(msg) from ex
if sig is not None:
# For classes and objects we skip the first parameter of their
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py
index 10e8c4e..ba7c38d 100644
--- a/Lib/test/test_capi.py
+++ b/Lib/test/test_capi.py
@@ -126,20 +126,29 @@ class CAPITest(unittest.TestCase):
self.assertEqual(_testcapi.docstring_no_signature.__text_signature__, None)
self.assertEqual(_testcapi.docstring_with_invalid_signature.__doc__,
- "sig= (module, boo)\n"
+ "docstring_with_invalid_signature($module, /, boo)\n"
"\n"
"This docstring has an invalid signature."
)
self.assertEqual(_testcapi.docstring_with_invalid_signature.__text_signature__, None)
+ self.assertEqual(_testcapi.docstring_with_invalid_signature2.__doc__,
+ "docstring_with_invalid_signature2($module, /, boo)\n"
+ "\n"
+ "--\n"
+ "\n"
+ "This docstring also has an invalid signature."
+ )
+ self.assertEqual(_testcapi.docstring_with_invalid_signature2.__text_signature__, None)
+
self.assertEqual(_testcapi.docstring_with_signature.__doc__,
"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_and_extra_newlines.__doc__,
- "This 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__,
- "(module, parameter)")
+ "($module, /, parameter)")
@unittest.skipUnless(threading, 'Threading required for this test.')
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index 862ef82..3f20419 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -1684,7 +1684,6 @@ class TestSignatureObject(unittest.TestCase):
self.assertEqual(p('sys'), sys.maxsize)
self.assertEqual(p('exp'), sys.maxsize - 1)
- test_callable(type)
test_callable(object)
# normal method
@@ -1710,9 +1709,12 @@ class TestSignatureObject(unittest.TestCase):
# support for 'method-wrapper'
test_callable(min.__call__)
- class ThisWorksNow:
- __call__ = type
- test_callable(ThisWorksNow())
+ # This doesn't work now.
+ # (We don't have a valid signature for "type" in 3.4)
+ with self.assertRaisesRegex(ValueError, "no signature found"):
+ class ThisWorksNow:
+ __call__ = type
+ test_callable(ThisWorksNow())
@cpython_only
@unittest.skipIf(MISSING_C_DOCSTRINGS,
@@ -2213,11 +2215,11 @@ class TestSignatureObject(unittest.TestCase):
# Test meta-classes without user-defined __init__ or __new__
class C(type): pass
- self.assertEqual(str(inspect.signature(C)),
- '(object_or_name, bases, dict)')
class D(C): pass
- self.assertEqual(str(inspect.signature(D)),
- '(object_or_name, bases, dict)')
+ with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
+ self.assertEqual(inspect.signature(C), None)
+ with self.assertRaisesRegex(ValueError, "callable.*is not supported"):
+ self.assertEqual(inspect.signature(D), None)
@unittest.skipIf(MISSING_C_DOCSTRINGS,
"Signature information for builtins requires docstrings")
@@ -2768,6 +2770,61 @@ class TestSignaturePrivateHelpers(unittest.TestCase):
self.assertEqual(getter('($self, obj)'), 'self')
self.assertEqual(getter('($cls, /, obj)'), 'cls')
+ def _strip_non_python_syntax(self, input,
+ clean_signature, self_parameter, last_positional_only):
+ computed_clean_signature, \
+ computed_self_parameter, \
+ computed_last_positional_only = \
+ inspect._signature_strip_non_python_syntax(input)
+ self.assertEqual(computed_clean_signature, clean_signature)
+ self.assertEqual(computed_self_parameter, self_parameter)
+ self.assertEqual(computed_last_positional_only, last_positional_only)
+
+ def test_signature_strip_non_python_syntax(self):
+ self._strip_non_python_syntax(
+ "($module, /, path, mode, *, dir_fd=None, " +
+ "effective_ids=False,\n follow_symlinks=True)",
+ "(module, path, mode, *, dir_fd=None, " +
+ "effective_ids=False, follow_symlinks=True)",
+ 0,
+ 0)
+
+ self._strip_non_python_syntax(
+ "($module, word, salt, /)",
+ "(module, word, salt)",
+ 0,
+ 2)
+
+ self._strip_non_python_syntax(
+ "(x, y=None, z=None, /)",
+ "(x, y=None, z=None)",
+ None,
+ 2)
+
+ self._strip_non_python_syntax(
+ "(x, y=None, z=None)",
+ "(x, y=None, z=None)",
+ None,
+ None)
+
+ self._strip_non_python_syntax(
+ "(x,\n y=None,\n z = None )",
+ "(x, y=None, z=None)",
+ None,
+ None)
+
+ self._strip_non_python_syntax(
+ "",
+ "",
+ None,
+ None)
+
+ self._strip_non_python_syntax(
+ None,
+ None,
+ None,
+ None)
+
class TestUnwrap(unittest.TestCase):
diff --git a/Misc/NEWS b/Misc/NEWS
index 9ed7e73..20cf656 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -200,18 +200,24 @@ Tests
Tools/Demos
-----------
-- #Issue 20456: Argument Clinic now observes the C preprocessor conditional
+- Issue #20530: Argument Clinic's signature format has been revised again.
+ The new syntax is highly human readable while still preventing false
+ positives. The syntax also extends Python syntax to denote "self" and
+ positional-only parameters, allowing inspect.Signature objects to be
+ totally accurate for all supported builtins in Python 3.4.
+
+- Issue #20456: Argument Clinic now observes the C preprocessor conditional
compilation statements of the C files it parses. When a Clinic block is
inside a conditional code, it adjusts its output to match, including
automatically generating an empty methoddef macro.
-- #Issue 20456: Cloned functions in Argument Clinic now use the correct
+- Issue #20456: Cloned functions in Argument Clinic now use the correct
name, not the name of the function they were cloned from, for text
strings inside generated code.
-- #Issue 20456: Fixed Argument Clinic's test suite and "--converters" feature.
+- Issue #20456: Fixed Argument Clinic's test suite and "--converters" feature.
-- #Issue 20456: Argument Clinic now allows specifying different names
+- Issue #20456: Argument Clinic now allows specifying different names
for a parameter in Python and C, using "as" on the parameter line.
- Issue #20326: Argument Clinic now uses a simple, unique signature to
diff --git a/Modules/_cryptmodule.c b/Modules/_cryptmodule.c
index 7531c2f..da44ef3 100644
--- a/Modules/_cryptmodule.c
+++ b/Modules/_cryptmodule.c
@@ -30,7 +30,9 @@ results for a given *word*.
[clinic start generated code]*/
PyDoc_STRVAR(crypt_crypt__doc__,
-"sig=($module, word, salt)\n"
+"crypt($module, word, salt, /)\n"
+"--\n"
+"\n"
"Hash a *word* with the given *salt* and return the hashed password.\n"
"\n"
"*word* will usually be a user\'s password. *salt* (either a random 2 or 16\n"
@@ -63,7 +65,7 @@ exit:
static PyObject *
crypt_crypt_impl(PyModuleDef *module, const char *word, const char *salt)
-/*[clinic end generated code: output=c7443257e03fca92 input=4d93b6d0f41fbf58]*/
+/*[clinic end generated code: output=3eaacdf994a6ff23 input=4d93b6d0f41fbf58]*/
{
/* On some platforms (AtheOS) crypt returns NULL for an invalid
salt. Return None in that case. XXX Maybe raise an exception? */
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 80fa497..fce6bbf 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -4159,7 +4159,9 @@ If no tz is specified, uses local timezone.
[clinic start generated code]*/
PyDoc_STRVAR(datetime_datetime_now__doc__,
-"sig=($type, tz=None)\n"
+"now($type, /, tz=None)\n"
+"--\n"
+"\n"
"Returns new datetime object representing current time local to tz.\n"
"\n"
" tz\n"
@@ -4192,7 +4194,7 @@ exit:
static PyObject *
datetime_datetime_now_impl(PyTypeObject *type, PyObject *tz)
-/*[clinic end generated code: output=c8a47308483e579a input=80d09869c5267d00]*/
+/*[clinic end generated code: output=583c5637e3c843fa input=80d09869c5267d00]*/
{
PyObject *self;
diff --git a/Modules/_dbmmodule.c b/Modules/_dbmmodule.c
index abeb799..93ea416 100644
--- a/Modules/_dbmmodule.c
+++ b/Modules/_dbmmodule.c
@@ -278,7 +278,9 @@ Return the value for key if present, otherwise default.
[clinic start generated code]*/
PyDoc_STRVAR(dbm_dbm_get__doc__,
-"sig=($self, key, default=None)\n"
+"get($self, key, default=None, /)\n"
+"--\n"
+"\n"
"Return the value for key if present, otherwise default.");
#define DBM_DBM_GET_METHODDEF \
@@ -307,7 +309,7 @@ exit:
static PyObject *
dbm_dbm_get_impl(dbmobject *dp, const char *key, Py_ssize_clean_t key_length, PyObject *default_value)
-/*[clinic end generated code: output=2bbaf9a187f9b6bf input=aecf5efd2f2b1a3b]*/
+/*[clinic end generated code: output=452ea11394e7e92d input=aecf5efd2f2b1a3b]*/
{
datum dbm_key, val;
@@ -448,7 +450,9 @@ Return a database object.
[clinic start generated code]*/
PyDoc_STRVAR(dbmopen__doc__,
-"sig=($module, filename, flags=\'r\', mode=0o666)\n"
+"open($module, filename, flags=\'r\', mode=0o666, /)\n"
+"--\n"
+"\n"
"Return a database object.\n"
"\n"
" filename\n"
@@ -485,7 +489,7 @@ exit:
static PyObject *
dbmopen_impl(PyModuleDef *module, const char *filename, const char *flags, int mode)
-/*[clinic end generated code: output=a1da6a481d9d332b input=6499ab0fab1333ac]*/
+/*[clinic end generated code: output=9a7b725f9c4dcec2 input=6499ab0fab1333ac]*/
{
int iflags;
diff --git a/Modules/_opcode.c b/Modules/_opcode.c
index 712e6eb..fee388f 100644
--- a/Modules/_opcode.c
+++ b/Modules/_opcode.c
@@ -18,7 +18,9 @@ Compute the stack effect of the opcode.
[clinic start generated code]*/
PyDoc_STRVAR(_opcode_stack_effect__doc__,
-"sig=($module, opcode, oparg=None)\n"
+"stack_effect($module, opcode, oparg=None, /)\n"
+"--\n"
+"\n"
"Compute the stack effect of the opcode.");
#define _OPCODE_STACK_EFFECT_METHODDEF \
@@ -50,7 +52,7 @@ exit:
static int
_opcode_stack_effect_impl(PyModuleDef *module, int opcode, PyObject *oparg)
-/*[clinic end generated code: output=4fe636f5db87c0a9 input=2d0a9ee53c0418f5]*/
+/*[clinic end generated code: output=9e1133f8d587bc67 input=2d0a9ee53c0418f5]*/
{
int effect;
int oparg_int = 0;
diff --git a/Modules/_sre.c b/Modules/_sre.c
index 4dcaec1..d4d1d9d 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -540,7 +540,9 @@ Matches zero or more characters at the beginning of the string.
[clinic start generated code]*/
PyDoc_STRVAR(pattern_match__doc__,
-"sig=($self, pattern, pos=0, endpos=sys.maxsize)\n"
+"match($self, /, pattern, pos=0, endpos=sys.maxsize)\n"
+"--\n"
+"\n"
"Matches zero or more characters at the beginning of the string.");
#define PATTERN_MATCH_METHODDEF \
@@ -570,7 +572,7 @@ exit:
static PyObject *
pattern_match_impl(PatternObject *self, PyObject *pattern, Py_ssize_t pos, Py_ssize_t endpos)
-/*[clinic end generated code: output=9f5b785661677848 input=26f9fd31befe46b9]*/
+/*[clinic end generated code: output=1528eafdb8b025ad input=26f9fd31befe46b9]*/
{
SRE_STATE state;
Py_ssize_t status;
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index 260e53d..9e81787 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -2851,26 +2851,40 @@ PyDoc_STRVAR(docstring_no_signature,
);
PyDoc_STRVAR(docstring_with_invalid_signature,
-"sig= (module, boo)\n"
+"docstring_with_invalid_signature($module, /, boo)\n"
"\n"
"This docstring has an invalid signature."
);
+PyDoc_STRVAR(docstring_with_invalid_signature2,
+"docstring_with_invalid_signature2($module, /, boo)\n"
+"\n"
+"--\n"
+"\n"
+"This docstring also has an invalid signature."
+);
+
PyDoc_STRVAR(docstring_with_signature,
-"sig=(module, sig)\n"
+"docstring_with_signature($module, /, sig)\n"
+"--\n"
+"\n"
"This docstring has a valid signature."
);
PyDoc_STRVAR(docstring_with_signature_and_extra_newlines,
-"sig=(module, parameter)\n"
-"\n"
+"docstring_with_signature_and_extra_newlines($module, /, parameter)\n"
+"--\n"
"\n"
"\n"
"This docstring has a valid signature and some extra newlines."
);
PyDoc_STRVAR(docstring_with_signature_with_defaults,
-"sig=(module, s='avocado', b=b'bytes', d=3.14, i=35, n=None, t=True, f=False, local=the_number_three, sys=sys.maxsize, exp=sys.maxsize - 1)\n"
+"docstring_with_signature_with_defaults(module, s='avocado',\n"
+" b=b'bytes', d=3.14, i=35, n=None, t=True, f=False,\n"
+" local=the_number_three, sys=sys.maxsize,\n"
+" exp=sys.maxsize - 1)\n"
+"--\n"
"\n"
"\n"
"\n"
@@ -3090,6 +3104,9 @@ static PyMethodDef TestMethods[] = {
{"docstring_with_invalid_signature",
(PyCFunction)test_with_docstring, METH_NOARGS,
docstring_with_invalid_signature},
+ {"docstring_with_invalid_signature2",
+ (PyCFunction)test_with_docstring, METH_NOARGS,
+ docstring_with_invalid_signature2},
{"docstring_with_signature",
(PyCFunction)test_with_docstring, METH_NOARGS,
docstring_with_signature},
diff --git a/Modules/_weakref.c b/Modules/_weakref.c
index 6451dba..da58931 100644
--- a/Modules/_weakref.c
+++ b/Modules/_weakref.c
@@ -20,7 +20,9 @@ Return the number of weak references to 'object'.
[clinic start generated code]*/
PyDoc_STRVAR(_weakref_getweakrefcount__doc__,
-"sig=($module, object)\n"
+"getweakrefcount($module, object, /)\n"
+"--\n"
+"\n"
"Return the number of weak references to \'object\'.");
#define _WEAKREF_GETWEAKREFCOUNT_METHODDEF \
@@ -46,7 +48,7 @@ exit:
static Py_ssize_t
_weakref_getweakrefcount_impl(PyModuleDef *module, PyObject *object)
-/*[clinic end generated code: output=ef51baac56180816 input=cedb69711b6a2507]*/
+/*[clinic end generated code: output=032eedbfd7d69e10 input=cedb69711b6a2507]*/
{
PyWeakReference **list;
diff --git a/Modules/clinic/_bz2module.c.h b/Modules/clinic/_bz2module.c.h
index 98f9a1b..8a201a0 100644
--- a/Modules/clinic/_bz2module.c.h
+++ b/Modules/clinic/_bz2module.c.h
@@ -3,7 +3,9 @@ preserve
[clinic start generated code]*/
PyDoc_STRVAR(_bz2_BZ2Compressor_compress__doc__,
-"sig=($self, data)\n"
+"compress($self, data, /)\n"
+"--\n"
+"\n"
"Provide data to the compressor object.\n"
"\n"
"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n"
@@ -38,7 +40,9 @@ exit:
}
PyDoc_STRVAR(_bz2_BZ2Compressor_flush__doc__,
-"sig=($self)\n"
+"flush($self, /)\n"
+"--\n"
+"\n"
"Finish the compression process.\n"
"\n"
"Returns the compressed data left in internal buffers.\n"
@@ -58,7 +62,9 @@ _bz2_BZ2Compressor_flush(BZ2Compressor *self, PyObject *Py_UNUSED(ignored))
}
PyDoc_STRVAR(_bz2_BZ2Compressor___init____doc__,
-"sig=(compresslevel=9)\n"
+"BZ2Compressor(compresslevel=9, /)\n"
+"--\n"
+"\n"
"Create a compressor object for compressing data incrementally.\n"
"\n"
" compresslevel\n"
@@ -89,7 +95,9 @@ exit:
}
PyDoc_STRVAR(_bz2_BZ2Decompressor_decompress__doc__,
-"sig=($self, data)\n"
+"decompress($self, data, /)\n"
+"--\n"
+"\n"
"Provide data to the decompressor object.\n"
"\n"
"Returns a chunk of decompressed data if possible, or b\'\' otherwise.\n"
@@ -125,7 +133,9 @@ exit:
}
PyDoc_STRVAR(_bz2_BZ2Decompressor___init____doc__,
-"sig=()\n"
+"BZ2Decompressor()\n"
+"--\n"
+"\n"
"Create a decompressor object for decompressing data incrementally.\n"
"\n"
"For one-shot decompression, use the decompress() function instead.");
@@ -149,4 +159,4 @@ _bz2_BZ2Decompressor___init__(PyObject *self, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=aca4f6329c1c773a input=a9049054013a1b77]*/
+/*[clinic end generated code: output=21ca4405519a0931 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_lzmamodule.c.h b/Modules/clinic/_lzmamodule.c.h
index 1848891..c1ad882 100644
--- a/Modules/clinic/_lzmamodule.c.h
+++ b/Modules/clinic/_lzmamodule.c.h
@@ -3,7 +3,9 @@ preserve
[clinic start generated code]*/
PyDoc_STRVAR(_lzma_LZMACompressor_compress__doc__,
-"sig=($self, data)\n"
+"compress($self, data, /)\n"
+"--\n"
+"\n"
"Provide data to the compressor object.\n"
"\n"
"Returns a chunk of compressed data if possible, or b\'\' otherwise.\n"
@@ -38,7 +40,9 @@ exit:
}
PyDoc_STRVAR(_lzma_LZMACompressor_flush__doc__,
-"sig=($self)\n"
+"flush($self, /)\n"
+"--\n"
+"\n"
"Finish the compression process.\n"
"\n"
"Returns the compressed data left in internal buffers.\n"
@@ -58,7 +62,9 @@ _lzma_LZMACompressor_flush(Compressor *self, PyObject *Py_UNUSED(ignored))
}
PyDoc_STRVAR(_lzma_LZMADecompressor_decompress__doc__,
-"sig=($self, data)\n"
+"decompress($self, data, /)\n"
+"--\n"
+"\n"
"Provide data to the decompressor object.\n"
"\n"
"Returns a chunk of decompressed data if possible, or b\'\' otherwise.\n"
@@ -94,7 +100,9 @@ exit:
}
PyDoc_STRVAR(_lzma_LZMADecompressor___init____doc__,
-"sig=(format=FORMAT_AUTO, memlimit=None, filters=None)\n"
+"LZMADecompressor(format=FORMAT_AUTO, memlimit=None, filters=None)\n"
+"--\n"
+"\n"
"Create a decompressor object for decompressing data incrementally.\n"
"\n"
" format\n"
@@ -137,7 +145,9 @@ exit:
}
PyDoc_STRVAR(_lzma_is_check_supported__doc__,
-"sig=($module, check_id)\n"
+"is_check_supported($module, check_id, /)\n"
+"--\n"
+"\n"
"Test whether the given integrity check is supported.\n"
"\n"
"Always returns True for CHECK_NONE and CHECK_CRC32.");
@@ -165,7 +175,9 @@ exit:
}
PyDoc_STRVAR(_lzma__encode_filter_properties__doc__,
-"sig=($module, filter)\n"
+"_encode_filter_properties($module, filter, /)\n"
+"--\n"
+"\n"
"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
"\n"
"The result does not include the filter ID itself, only the options.");
@@ -197,7 +209,9 @@ exit:
}
PyDoc_STRVAR(_lzma__decode_filter_properties__doc__,
-"sig=($module, filter_id, encoded_props)\n"
+"_decode_filter_properties($module, filter_id, encoded_props, /)\n"
+"--\n"
+"\n"
"Return a bytes object encoding the options (properties) of the filter specified by *filter* (a dict).\n"
"\n"
"The result does not include the filter ID itself, only the options.");
@@ -228,4 +242,4 @@ exit:
return return_value;
}
-/*[clinic end generated code: output=fe63bc798a5c5c55 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=808fec8216ac712b input=a9049054013a1b77]*/
diff --git a/Modules/clinic/_pickle.c.h b/Modules/clinic/_pickle.c.h
index 9ef469d..a20a61e 100644
--- a/Modules/clinic/_pickle.c.h
+++ b/Modules/clinic/_pickle.c.h
@@ -3,7 +3,9 @@ preserve
[clinic start generated code]*/
PyDoc_STRVAR(_pickle_Pickler_clear_memo__doc__,
-"sig=($self)\n"
+"clear_memo($self, /)\n"
+"--\n"
+"\n"
"Clears the pickler\'s \"memo\".\n"
"\n"
"The memo is the data structure that remembers which objects the\n"
@@ -24,14 +26,18 @@ _pickle_Pickler_clear_memo(PicklerObject *self, PyObject *Py_UNUSED(ignored))
}
PyDoc_STRVAR(_pickle_Pickler_dump__doc__,
-"sig=($self, obj)\n"
+"dump($self, obj, /)\n"
+"--\n"
+"\n"
"Write a pickled representation of the given object to the open file.");
#define _PICKLE_PICKLER_DUMP_METHODDEF \
{"dump", (PyCFunction)_pickle_Pickler_dump, METH_O, _pickle_Pickler_dump__doc__},
PyDoc_STRVAR(_pickle_Pickler___init____doc__,
-"sig=(file, protocol=None, fix_imports=True)\n"
+"Pickler(file, protocol=None, fix_imports=True)\n"
+"--\n"
+"\n"
"This takes a binary file for writing a pickle data stream.\n"
"\n"
"The optional *protocol* argument tells the pickler to use the given\n"
@@ -74,7 +80,9 @@ exit:
}
PyDoc_STRVAR(_pickle_PicklerMemoProxy_clear__doc__,
-"sig=($self)\n"
+"clear($self, /)\n"
+"--\n"
+"\n"
"Remove all items from memo.");
#define _PICKLE_PICKLERMEMOPROXY_CLEAR_METHODDEF \
@@ -90,7 +98,9 @@ _pickle_PicklerMemoProxy_clear(PicklerMemoProxyObject *self, PyObject *Py_UNUSED
}
PyDoc_STRVAR(_pickle_PicklerMemoProxy_copy__doc__,
-"sig=($self)\n"
+"copy($self, /)\n"
+"--\n"
+"\n"
"Copy the memo to a new object.");
#define _PICKLE_PICKLERMEMOPROXY_COPY_METHODDEF \
@@ -106,7 +116,9 @@ _pickle_PicklerMemoProxy_copy(PicklerMemoProxyObject *self, PyObject *Py_UNUSED(
}
PyDoc_STRVAR(_pickle_PicklerMemoProxy___reduce____doc__,
-"sig=($self)\n"
+"__reduce__($self, /)\n"
+"--\n"
+"\n"
"Implement pickle support.");
#define _PICKLE_PICKLERMEMOPROXY___REDUCE___METHODDEF \
@@ -122,7 +134,9 @@ _pickle_PicklerMemoProxy___reduce__(PicklerMemoProxyObject *self, PyObject *Py_U
}
PyDoc_STRVAR(_pickle_Unpickler_load__doc__,
-"sig=($self)\n"
+"load($self, /)\n"
+"--\n"
+"\n"
"Load a pickle.\n"
"\n"
"Read a pickled object representation from the open file object given\n"
@@ -142,7 +156,9 @@ _pickle_Unpickler_load(UnpicklerObject *self, PyObject *Py_UNUSED(ignored))
}
PyDoc_STRVAR(_pickle_Unpickler_find_class__doc__,
-"sig=($self, module_name, global_name)\n"
+"find_class($self, module_name, global_name, /)\n"
+"--\n"
+"\n"
"Return an object from a specified module.\n"
"\n"
"If necessary, the module will be imported. Subclasses may override\n"
@@ -176,7 +192,9 @@ exit:
}
PyDoc_STRVAR(_pickle_Unpickler___init____doc__,
-"sig=(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
+"Unpickler(file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
+"--\n"
+"\n"
"This takes a binary file for reading a pickle data stream.\n"
"\n"
"The protocol version of the pickle is detected automatically, so no\n"
@@ -222,7 +240,9 @@ exit:
}
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_clear__doc__,
-"sig=($self)\n"
+"clear($self, /)\n"
+"--\n"
+"\n"
"Remove all items from memo.");
#define _PICKLE_UNPICKLERMEMOPROXY_CLEAR_METHODDEF \
@@ -238,7 +258,9 @@ _pickle_UnpicklerMemoProxy_clear(UnpicklerMemoProxyObject *self, PyObject *Py_UN
}
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy_copy__doc__,
-"sig=($self)\n"
+"copy($self, /)\n"
+"--\n"
+"\n"
"Copy the memo to a new object.");
#define _PICKLE_UNPICKLERMEMOPROXY_COPY_METHODDEF \
@@ -254,7 +276,9 @@ _pickle_UnpicklerMemoProxy_copy(UnpicklerMemoProxyObject *self, PyObject *Py_UNU
}
PyDoc_STRVAR(_pickle_UnpicklerMemoProxy___reduce____doc__,
-"sig=($self)\n"
+"__reduce__($self, /)\n"
+"--\n"
+"\n"
"Implement pickling support.");
#define _PICKLE_UNPICKLERMEMOPROXY___REDUCE___METHODDEF \
@@ -270,7 +294,9 @@ _pickle_UnpicklerMemoProxy___reduce__(UnpicklerMemoProxyObject *self, PyObject *
}
PyDoc_STRVAR(_pickle_dump__doc__,
-"sig=($module, obj, file, protocol=None, *, fix_imports=True)\n"
+"dump($module, /, obj, file, protocol=None, *, fix_imports=True)\n"
+"--\n"
+"\n"
"Write a pickled representation of obj to the open file object file.\n"
"\n"
"This is equivalent to ``Pickler(file, protocol).dump(obj)``, but may\n"
@@ -320,7 +346,9 @@ exit:
}
PyDoc_STRVAR(_pickle_dumps__doc__,
-"sig=($module, obj, protocol=None, *, fix_imports=True)\n"
+"dumps($module, /, obj, protocol=None, *, fix_imports=True)\n"
+"--\n"
+"\n"
"Return the pickled representation of the object as a bytes object.\n"
"\n"
"The optional *protocol* argument tells the pickler to use the given\n"
@@ -361,7 +389,10 @@ exit:
}
PyDoc_STRVAR(_pickle_load__doc__,
-"sig=($module, file, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
+"load($module, /, file, *, fix_imports=True, encoding=\'ASCII\',\n"
+" errors=\'strict\')\n"
+"--\n"
+"\n"
"Read and return an object from the pickle data stored in a file.\n"
"\n"
"This is equivalent to ``Unpickler(file).load()``, but may be more\n"
@@ -413,7 +444,10 @@ exit:
}
PyDoc_STRVAR(_pickle_loads__doc__,
-"sig=($module, data, *, fix_imports=True, encoding=\'ASCII\', errors=\'strict\')\n"
+"loads($module, /, data, *, fix_imports=True, encoding=\'ASCII\',\n"
+" errors=\'strict\')\n"
+"--\n"
+"\n"
"Read and return an object from the given pickle data.\n"
"\n"
"The protocol version of the pickle is detected automatically, so no\n"
@@ -454,4 +488,4 @@ _pickle_loads(PyModuleDef *module, PyObject *args, PyObject *kwargs)
exit:
return return_value;
}
-/*[clinic end generated code: output=c59d4dafc2646f11 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=f965b6c7018c898d input=a9049054013a1b77]*/
diff --git a/Modules/clinic/audioop.c.h b/Modules/clinic/audioop.c.h
index 92d13b0..40ef5e2 100644
--- a/Modules/clinic/audioop.c.h
+++ b/Modules/clinic/audioop.c.h
@@ -3,7 +3,9 @@ preserve
[clinic start generated code]*/
PyDoc_STRVAR(audioop_getsample__doc__,
-"sig=($module, fragment, width, index)\n"
+"getsample($module, fragment, width, index, /)\n"
+"--\n"
+"\n"
"Return the value of sample index from the fragment.");
#define AUDIOOP_GETSAMPLE_METHODDEF \
@@ -35,7 +37,9 @@ exit:
}
PyDoc_STRVAR(audioop_max__doc__,
-"sig=($module, fragment, width)\n"
+"max($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Return the maximum of the absolute value of all samples in a fragment.");
#define AUDIOOP_MAX_METHODDEF \
@@ -66,7 +70,9 @@ exit:
}
PyDoc_STRVAR(audioop_minmax__doc__,
-"sig=($module, fragment, width)\n"
+"minmax($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Return the minimum and maximum values of all samples in the sound fragment.");
#define AUDIOOP_MINMAX_METHODDEF \
@@ -97,7 +103,9 @@ exit:
}
PyDoc_STRVAR(audioop_avg__doc__,
-"sig=($module, fragment, width)\n"
+"avg($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Return the average over all samples in the fragment.");
#define AUDIOOP_AVG_METHODDEF \
@@ -128,7 +136,9 @@ exit:
}
PyDoc_STRVAR(audioop_rms__doc__,
-"sig=($module, fragment, width)\n"
+"rms($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Return the root-mean-square of the fragment, i.e. sqrt(sum(S_i^2)/n).");
#define AUDIOOP_RMS_METHODDEF \
@@ -159,7 +169,9 @@ exit:
}
PyDoc_STRVAR(audioop_findfit__doc__,
-"sig=($module, fragment, reference)\n"
+"findfit($module, fragment, reference, /)\n"
+"--\n"
+"\n"
"Try to match reference as well as possible to a portion of fragment.");
#define AUDIOOP_FINDFIT_METHODDEF \
@@ -193,7 +205,9 @@ exit:
}
PyDoc_STRVAR(audioop_findfactor__doc__,
-"sig=($module, fragment, reference)\n"
+"findfactor($module, fragment, reference, /)\n"
+"--\n"
+"\n"
"Return a factor F such that rms(add(fragment, mul(reference, -F))) is minimal.");
#define AUDIOOP_FINDFACTOR_METHODDEF \
@@ -227,7 +241,9 @@ exit:
}
PyDoc_STRVAR(audioop_findmax__doc__,
-"sig=($module, fragment, length)\n"
+"findmax($module, fragment, length, /)\n"
+"--\n"
+"\n"
"Search fragment for a slice of specified number of samples with maximum energy.");
#define AUDIOOP_FINDMAX_METHODDEF \
@@ -258,7 +274,9 @@ exit:
}
PyDoc_STRVAR(audioop_avgpp__doc__,
-"sig=($module, fragment, width)\n"
+"avgpp($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Return the average peak-peak value over all samples in the fragment.");
#define AUDIOOP_AVGPP_METHODDEF \
@@ -289,7 +307,9 @@ exit:
}
PyDoc_STRVAR(audioop_maxpp__doc__,
-"sig=($module, fragment, width)\n"
+"maxpp($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Return the maximum peak-peak value in the sound fragment.");
#define AUDIOOP_MAXPP_METHODDEF \
@@ -320,7 +340,9 @@ exit:
}
PyDoc_STRVAR(audioop_cross__doc__,
-"sig=($module, fragment, width)\n"
+"cross($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Return the number of zero crossings in the fragment passed as an argument.");
#define AUDIOOP_CROSS_METHODDEF \
@@ -351,7 +373,9 @@ exit:
}
PyDoc_STRVAR(audioop_mul__doc__,
-"sig=($module, fragment, width, factor)\n"
+"mul($module, fragment, width, factor, /)\n"
+"--\n"
+"\n"
"Return a fragment that has all samples in the original fragment multiplied by the floating-point value factor.");
#define AUDIOOP_MUL_METHODDEF \
@@ -383,7 +407,9 @@ exit:
}
PyDoc_STRVAR(audioop_tomono__doc__,
-"sig=($module, fragment, width, lfactor, rfactor)\n"
+"tomono($module, fragment, width, lfactor, rfactor, /)\n"
+"--\n"
+"\n"
"Convert a stereo fragment to a mono fragment.");
#define AUDIOOP_TOMONO_METHODDEF \
@@ -416,7 +442,9 @@ exit:
}
PyDoc_STRVAR(audioop_tostereo__doc__,
-"sig=($module, fragment, width, lfactor, rfactor)\n"
+"tostereo($module, fragment, width, lfactor, rfactor, /)\n"
+"--\n"
+"\n"
"Generate a stereo fragment from a mono fragment.");
#define AUDIOOP_TOSTEREO_METHODDEF \
@@ -449,7 +477,9 @@ exit:
}
PyDoc_STRVAR(audioop_add__doc__,
-"sig=($module, fragment1, fragment2, width)\n"
+"add($module, fragment1, fragment2, width, /)\n"
+"--\n"
+"\n"
"Return a fragment which is the addition of the two samples passed as parameters.");
#define AUDIOOP_ADD_METHODDEF \
@@ -484,7 +514,9 @@ exit:
}
PyDoc_STRVAR(audioop_bias__doc__,
-"sig=($module, fragment, width, bias)\n"
+"bias($module, fragment, width, bias, /)\n"
+"--\n"
+"\n"
"Return a fragment that is the original fragment with a bias added to each sample.");
#define AUDIOOP_BIAS_METHODDEF \
@@ -516,7 +548,9 @@ exit:
}
PyDoc_STRVAR(audioop_reverse__doc__,
-"sig=($module, fragment, width)\n"
+"reverse($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Reverse the samples in a fragment and returns the modified fragment.");
#define AUDIOOP_REVERSE_METHODDEF \
@@ -547,7 +581,9 @@ exit:
}
PyDoc_STRVAR(audioop_byteswap__doc__,
-"sig=($module, fragment, width)\n"
+"byteswap($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Convert big-endian samples to little-endian and vice versa.");
#define AUDIOOP_BYTESWAP_METHODDEF \
@@ -578,7 +614,9 @@ exit:
}
PyDoc_STRVAR(audioop_lin2lin__doc__,
-"sig=($module, fragment, width, newwidth)\n"
+"lin2lin($module, fragment, width, newwidth, /)\n"
+"--\n"
+"\n"
"Convert samples between 1-, 2-, 3- and 4-byte formats.");
#define AUDIOOP_LIN2LIN_METHODDEF \
@@ -610,7 +648,10 @@ exit:
}
PyDoc_STRVAR(audioop_ratecv__doc__,
-"sig=($module, fragment, width, nchannels, inrate, outrate, state, weightA=1, weightB=0)\n"
+"ratecv($module, fragment, width, nchannels, inrate, outrate, state,\n"
+" weightA=1, weightB=0, /)\n"
+"--\n"
+"\n"
"Convert the frame rate of the input fragment.");
#define AUDIOOP_RATECV_METHODDEF \
@@ -647,7 +688,9 @@ exit:
}
PyDoc_STRVAR(audioop_lin2ulaw__doc__,
-"sig=($module, fragment, width)\n"
+"lin2ulaw($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Convert samples in the audio fragment to u-LAW encoding.");
#define AUDIOOP_LIN2ULAW_METHODDEF \
@@ -678,7 +721,9 @@ exit:
}
PyDoc_STRVAR(audioop_ulaw2lin__doc__,
-"sig=($module, fragment, width)\n"
+"ulaw2lin($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Convert sound fragments in u-LAW encoding to linearly encoded sound fragments.");
#define AUDIOOP_ULAW2LIN_METHODDEF \
@@ -709,7 +754,9 @@ exit:
}
PyDoc_STRVAR(audioop_lin2alaw__doc__,
-"sig=($module, fragment, width)\n"
+"lin2alaw($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Convert samples in the audio fragment to a-LAW encoding.");
#define AUDIOOP_LIN2ALAW_METHODDEF \
@@ -740,7 +787,9 @@ exit:
}
PyDoc_STRVAR(audioop_alaw2lin__doc__,
-"sig=($module, fragment, width)\n"
+"alaw2lin($module, fragment, width, /)\n"
+"--\n"
+"\n"
"Convert sound fragments in a-LAW encoding to linearly encoded sound fragments.");
#define AUDIOOP_ALAW2LIN_METHODDEF \
@@ -771,7 +820,9 @@ exit:
}
PyDoc_STRVAR(audioop_lin2adpcm__doc__,
-"sig=($module, fragment, width, state)\n"
+"lin2adpcm($module, fragment, width, state, /)\n"
+"--\n"
+"\n"
"Convert samples to 4 bit Intel/DVI ADPCM encoding.");
#define AUDIOOP_LIN2ADPCM_METHODDEF \
@@ -803,7 +854,9 @@ exit:
}
PyDoc_STRVAR(audioop_adpcm2lin__doc__,
-"sig=($module, fragment, width, state)\n"
+"adpcm2lin($module, fragment, width, state, /)\n"
+"--\n"
+"\n"
"Decode an Intel/DVI ADPCM coded fragment to a linear fragment.");
#define AUDIOOP_ADPCM2LIN_METHODDEF \
@@ -833,4 +886,4 @@ exit:
return return_value;
}
-/*[clinic end generated code: output=ee7e58cfd3d0d5a6 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=be840bba5d40c2ce input=a9049054013a1b77]*/
diff --git a/Modules/clinic/binascii.c.h b/Modules/clinic/binascii.c.h
index e4ef36c..5247180 100644
--- a/Modules/clinic/binascii.c.h
+++ b/Modules/clinic/binascii.c.h
@@ -3,7 +3,9 @@ preserve
[clinic start generated code]*/
PyDoc_STRVAR(binascii_a2b_uu__doc__,
-"sig=($module, data)\n"
+"a2b_uu($module, data, /)\n"
+"--\n"
+"\n"
"Decode a line of uuencoded data.");
#define BINASCII_A2B_UU_METHODDEF \
@@ -33,7 +35,9 @@ exit:
}
PyDoc_STRVAR(binascii_b2a_uu__doc__,
-"sig=($module, data)\n"
+"b2a_uu($module, data, /)\n"
+"--\n"
+"\n"
"Uuencode line of data.");
#define BINASCII_B2A_UU_METHODDEF \
@@ -63,7 +67,9 @@ exit:
}
PyDoc_STRVAR(binascii_a2b_base64__doc__,
-"sig=($module, data)\n"
+"a2b_base64($module, data, /)\n"
+"--\n"
+"\n"
"Decode a line of base64 data.");
#define BINASCII_A2B_BASE64_METHODDEF \
@@ -93,7 +99,9 @@ exit:
}
PyDoc_STRVAR(binascii_b2a_base64__doc__,
-"sig=($module, data)\n"
+"b2a_base64($module, data, /)\n"
+"--\n"
+"\n"
"Base64-code line of data.");
#define BINASCII_B2A_BASE64_METHODDEF \
@@ -123,7 +131,9 @@ exit:
}
PyDoc_STRVAR(binascii_a2b_hqx__doc__,
-"sig=($module, data)\n"
+"a2b_hqx($module, data, /)\n"
+"--\n"
+"\n"
"Decode .hqx coding.");
#define BINASCII_A2B_HQX_METHODDEF \
@@ -153,7 +163,9 @@ exit:
}
PyDoc_STRVAR(binascii_rlecode_hqx__doc__,
-"sig=($module, data)\n"
+"rlecode_hqx($module, data, /)\n"
+"--\n"
+"\n"
"Binhex RLE-code binary data.");
#define BINASCII_RLECODE_HQX_METHODDEF \
@@ -183,7 +195,9 @@ exit:
}
PyDoc_STRVAR(binascii_b2a_hqx__doc__,
-"sig=($module, data)\n"
+"b2a_hqx($module, data, /)\n"
+"--\n"
+"\n"
"Encode .hqx data.");
#define BINASCII_B2A_HQX_METHODDEF \
@@ -213,7 +227,9 @@ exit:
}
PyDoc_STRVAR(binascii_rledecode_hqx__doc__,
-"sig=($module, data)\n"
+"rledecode_hqx($module, data, /)\n"
+"--\n"
+"\n"
"Decode hexbin RLE-coded string.");
#define BINASCII_RLEDECODE_HQX_METHODDEF \
@@ -243,7 +259,9 @@ exit:
}
PyDoc_STRVAR(binascii_crc_hqx__doc__,
-"sig=($module, data, crc)\n"
+"crc_hqx($module, data, crc, /)\n"
+"--\n"
+"\n"
"Compute hqx CRC incrementally.");
#define BINASCII_CRC_HQX_METHODDEF \
@@ -278,7 +296,9 @@ exit:
}
PyDoc_STRVAR(binascii_crc32__doc__,
-"sig=($module, data, crc=0)\n"
+"crc32($module, data, crc=0, /)\n"
+"--\n"
+"\n"
"Compute CRC-32 incrementally.");
#define BINASCII_CRC32_METHODDEF \
@@ -313,7 +333,9 @@ exit:
}
PyDoc_STRVAR(binascii_b2a_hex__doc__,
-"sig=($module, data)\n"
+"b2a_hex($module, data, /)\n"
+"--\n"
+"\n"
"Hexadecimal representation of binary data.\n"
"\n"
"The return value is a bytes object. This function is also\n"
@@ -346,7 +368,9 @@ exit:
}
PyDoc_STRVAR(binascii_a2b_hex__doc__,
-"sig=($module, hexstr)\n"
+"a2b_hex($module, hexstr, /)\n"
+"--\n"
+"\n"
"Binary data of hexadecimal representation.\n"
"\n"
"hexstr must contain an even number of hex digits (upper or lower case).\n"
@@ -379,7 +403,9 @@ exit:
}
PyDoc_STRVAR(binascii_a2b_qp__doc__,
-"sig=($module, data, header=False)\n"
+"a2b_qp($module, /, data, header=False)\n"
+"--\n"
+"\n"
"Decode a string of qp-encoded data.");
#define BINASCII_A2B_QP_METHODDEF \
@@ -411,7 +437,9 @@ exit:
}
PyDoc_STRVAR(binascii_b2a_qp__doc__,
-"sig=($module, data, quotetabs=False, istext=True, header=False)\n"
+"b2a_qp($module, /, data, quotetabs=False, istext=True, header=False)\n"
+"--\n"
+"\n"
"Encode a string using quoted-printable encoding.\n"
"\n"
"On encoding, when istext is set, newlines are not encoded, and white\n"
@@ -447,4 +475,4 @@ exit:
return return_value;
}
-/*[clinic end generated code: output=831a8ccc9f984001 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=68e2bcc6956b6213 input=a9049054013a1b77]*/
diff --git a/Modules/clinic/zlibmodule.c.h b/Modules/clinic/zlibmodule.c.h
index f810fcf..f54a805 100644
--- a/Modules/clinic/zlibmodule.c.h
+++ b/Modules/clinic/zlibmodule.c.h
@@ -3,7 +3,9 @@ preserve
[clinic start generated code]*/
PyDoc_STRVAR(zlib_compress__doc__,
-"sig=($module, bytes, level=Z_DEFAULT_COMPRESSION)\n"
+"compress($module, bytes, level=Z_DEFAULT_COMPRESSION, /)\n"
+"--\n"
+"\n"
"Returns a bytes object containing compressed data.\n"
"\n"
" bytes\n"
@@ -39,7 +41,9 @@ exit:
}
PyDoc_STRVAR(zlib_decompress__doc__,
-"sig=($module, data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE)\n"
+"decompress($module, data, wbits=MAX_WBITS, bufsize=DEF_BUF_SIZE, /)\n"
+"--\n"
+"\n"
"Returns a bytes object containing the uncompressed data.\n"
"\n"
" data\n"
@@ -78,7 +82,11 @@ exit:
}
PyDoc_STRVAR(zlib_compressobj__doc__,
-"sig=($module, level=Z_DEFAULT_COMPRESSION, method=DEFLATED, wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL, strategy=Z_DEFAULT_STRATEGY, zdict=None)\n"
+"compressobj($module, /, level=Z_DEFAULT_COMPRESSION, method=DEFLATED,\n"
+" wbits=MAX_WBITS, memLevel=DEF_MEM_LEVEL,\n"
+" strategy=Z_DEFAULT_STRATEGY, zdict=None)\n"
+"--\n"
+"\n"
"Return a compressor object.\n"
"\n"
" level\n"
@@ -132,7 +140,9 @@ exit:
}
PyDoc_STRVAR(zlib_decompressobj__doc__,
-"sig=($module, wbits=MAX_WBITS, zdict=b\'\')\n"
+"decompressobj($module, /, wbits=MAX_WBITS, zdict=b\'\')\n"
+"--\n"
+"\n"
"Return a decompressor object.\n"
"\n"
" wbits\n"
@@ -166,7 +176,9 @@ exit:
}
PyDoc_STRVAR(zlib_Compress_compress__doc__,
-"sig=($self, data)\n"
+"compress($self, data, /)\n"
+"--\n"
+"\n"
"Returns a bytes object containing compressed data.\n"
"\n"
" data\n"
@@ -203,7 +215,9 @@ exit:
}
PyDoc_STRVAR(zlib_Decompress_decompress__doc__,
-"sig=($self, data, max_length=0)\n"
+"decompress($self, data, max_length=0, /)\n"
+"--\n"
+"\n"
"Return a bytes object containing the decompressed version of the data.\n"
"\n"
" data\n"
@@ -245,7 +259,9 @@ exit:
}
PyDoc_STRVAR(zlib_Compress_flush__doc__,
-"sig=($self, mode=zlib.Z_FINISH)\n"
+"flush($self, mode=zlib.Z_FINISH, /)\n"
+"--\n"
+"\n"
"Return a bytes object containing any remaining compressed data.\n"
"\n"
" mode\n"
@@ -279,7 +295,9 @@ exit:
#if defined(HAVE_ZLIB_COPY)
PyDoc_STRVAR(zlib_Compress_copy__doc__,
-"sig=($self)\n"
+"copy($self, /)\n"
+"--\n"
+"\n"
"Return a copy of the compression object.");
#define ZLIB_COMPRESS_COPY_METHODDEF \
@@ -303,7 +321,9 @@ zlib_Compress_copy(compobject *self, PyObject *Py_UNUSED(ignored))
#if defined(HAVE_ZLIB_COPY)
PyDoc_STRVAR(zlib_Decompress_copy__doc__,
-"sig=($self)\n"
+"copy($self, /)\n"
+"--\n"
+"\n"
"Return a copy of the decompression object.");
#define ZLIB_DECOMPRESS_COPY_METHODDEF \
@@ -325,7 +345,9 @@ zlib_Decompress_copy(compobject *self, PyObject *Py_UNUSED(ignored))
#endif /* !defined(ZLIB_DECOMPRESS_COPY_METHODDEF) */
PyDoc_STRVAR(zlib_Decompress_flush__doc__,
-"sig=($self, length=zlib.DEF_BUF_SIZE)\n"
+"flush($self, length=zlib.DEF_BUF_SIZE, /)\n"
+"--\n"
+"\n"
"Return a bytes object containing any remaining decompressed data.\n"
"\n"
" length\n"
@@ -354,7 +376,9 @@ exit:
}
PyDoc_STRVAR(zlib_adler32__doc__,
-"sig=($module, data, value=1)\n"
+"adler32($module, data, value=1, /)\n"
+"--\n"
+"\n"
"Compute an Adler-32 checksum of data.\n"
"\n"
" value\n"
@@ -390,7 +414,9 @@ exit:
}
PyDoc_STRVAR(zlib_crc32__doc__,
-"sig=($module, data, value=0)\n"
+"crc32($module, data, value=0, /)\n"
+"--\n"
+"\n"
"Compute a CRC-32 checksum of data.\n"
"\n"
" value\n"
@@ -424,4 +450,4 @@ exit:
return return_value;
}
-/*[clinic end generated code: output=67d3e81eafcfb982 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=bc9473721ca7c962 input=a9049054013a1b77]*/
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
index 0646043f..1428220 100644
--- a/Modules/posixmodule.c
+++ b/Modules/posixmodule.c
@@ -2435,7 +2435,9 @@ It's an error to use dir_fd or follow_symlinks when specifying path as
[clinic start generated code]*/
PyDoc_STRVAR(os_stat__doc__,
-"sig=($module, path, *, dir_fd=None, follow_symlinks=True)\n"
+"stat($module, /, path, *, dir_fd=None, follow_symlinks=True)\n"
+"--\n"
+"\n"
"Perform a stat system call on the given path.\n"
"\n"
" path\n"
@@ -2486,7 +2488,7 @@ exit:
static PyObject *
os_stat_impl(PyModuleDef *module, path_t *path, int dir_fd, int follow_symlinks)
-/*[clinic end generated code: output=33b6ee92cd1b98de input=5ae155bd475fd20a]*/
+/*[clinic end generated code: output=f1dcaa5e24db9882 input=5ae155bd475fd20a]*/
{
return posix_do_stat("stat", path, dir_fd, follow_symlinks);
}
@@ -2567,7 +2569,10 @@ Note that most operations will use the effective uid/gid, therefore this
[clinic start generated code]*/
PyDoc_STRVAR(os_access__doc__,
-"sig=($module, path, mode, *, dir_fd=None, effective_ids=False, follow_symlinks=True)\n"
+"access($module, /, path, mode, *, dir_fd=None, effective_ids=False,\n"
+" follow_symlinks=True)\n"
+"--\n"
+"\n"
"Use the real uid/gid to test for access to a path.\n"
"\n"
" path\n"
@@ -2627,7 +2632,7 @@ exit:
static PyObject *
os_access_impl(PyModuleDef *module, path_t *path, int mode, int dir_fd, int effective_ids, int follow_symlinks)
-/*[clinic end generated code: output=33b3fafc61e778e1 input=2e2e7594371f5b7e]*/
+/*[clinic end generated code: output=a6ed4f151be9df0f input=2e2e7594371f5b7e]*/
{
PyObject *return_value = NULL;
@@ -2723,7 +2728,9 @@ Return the name of the terminal device connected to 'fd'.
[clinic start generated code]*/
PyDoc_STRVAR(os_ttyname__doc__,
-"sig=($module, fd)\n"
+"ttyname($module, fd, /)\n"
+"--\n"
+"\n"
"Return the name of the terminal device connected to \'fd\'.\n"
"\n"
" fd\n"
@@ -2757,7 +2764,7 @@ exit:
static char *
os_ttyname_impl(PyModuleDef *module, int fd)
-/*[clinic end generated code: output=c3083e665d4d11b9 input=5f72ca83e76b3b45]*/
+/*[clinic end generated code: output=cee7bc4cffec01a2 input=5f72ca83e76b3b45]*/
{
char *ret;
diff --git a/Modules/unicodedata.c b/Modules/unicodedata.c
index c6c4ba2..3253db2 100644
--- a/Modules/unicodedata.c
+++ b/Modules/unicodedata.c
@@ -129,7 +129,9 @@ not given, ValueError is raised.
[clinic start generated code]*/
PyDoc_STRVAR(unicodedata_UCD_decimal__doc__,
-"sig=($self, unichr, default=None)\n"
+"decimal($self, unichr, default=None, /)\n"
+"--\n"
+"\n"
"Converts a Unicode character into its equivalent decimal value.\n"
"\n"
"Returns the decimal value assigned to the Unicode character unichr\n"
@@ -161,7 +163,7 @@ exit:
static PyObject *
unicodedata_UCD_decimal_impl(PreviousDBVersion *self, PyUnicodeObject *unichr, PyObject *default_value)
-/*[clinic end generated code: output=a3ad5de9393acb2f input=c25c9d2b4de076b1]*/
+/*[clinic end generated code: output=8689669896d293df input=c25c9d2b4de076b1]*/
{
int have_old = 0;
long rc;
diff --git a/Objects/descrobject.c b/Objects/descrobject.c
index 181cc51..2df5ac5 100644
--- a/Objects/descrobject.c
+++ b/Objects/descrobject.c
@@ -353,13 +353,13 @@ wrapperdescr_call(PyWrapperDescrObject *descr, PyObject *args, PyObject *kwds)
static PyObject *
method_get_doc(PyMethodDescrObject *descr, void *closure)
{
- return _PyType_GetDocFromInternalDoc(descr->d_method->ml_doc);
+ return _PyType_GetDocFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
}
static PyObject *
method_get_text_signature(PyMethodDescrObject *descr, void *closure)
{
- return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_doc);
+ return _PyType_GetTextSignatureFromInternalDoc(descr->d_method->ml_name, descr->d_method->ml_doc);
}
static PyObject *
@@ -466,13 +466,13 @@ static PyGetSetDef getset_getset[] = {
static PyObject *
wrapperdescr_get_doc(PyWrapperDescrObject *descr, void *closure)
{
- return _PyType_GetDocFromInternalDoc(descr->d_base->doc);
+ return _PyType_GetDocFromInternalDoc(descr->d_base->name, descr->d_base->doc);
}
static PyObject *
wrapperdescr_get_text_signature(PyWrapperDescrObject *descr, void *closure)
{
- return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->doc);
+ return _PyType_GetTextSignatureFromInternalDoc(descr->d_base->name, descr->d_base->doc);
}
static PyGetSetDef wrapperdescr_getset[] = {
@@ -1151,13 +1151,13 @@ wrapper_name(wrapperobject *wp)
static PyObject *
wrapper_doc(wrapperobject *wp, void *closure)
{
- return _PyType_GetDocFromInternalDoc(wp->descr->d_base->doc);
+ return _PyType_GetDocFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
}
static PyObject *
wrapper_text_signature(wrapperobject *wp, void *closure)
{
- return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->doc);
+ return _PyType_GetTextSignatureFromInternalDoc(wp->descr->d_base->name, wp->descr->d_base->doc);
}
static PyObject *
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 2673817..1ccea6e 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1702,7 +1702,9 @@ Returns a new dict with keys from iterable and values equal to value.
[clinic start generated code]*/
PyDoc_STRVAR(dict_fromkeys__doc__,
-"sig=($type, iterable, value=None)\n"
+"fromkeys($type, iterable, value=None, /)\n"
+"--\n"
+"\n"
"Returns a new dict with keys from iterable and values equal to value.");
#define DICT_FROMKEYS_METHODDEF \
@@ -1730,7 +1732,7 @@ exit:
static PyObject *
dict_fromkeys_impl(PyTypeObject *type, PyObject *iterable, PyObject *value)
-/*[clinic end generated code: output=aff6e583703dbeba input=b85a667f9bf4669d]*/
+/*[clinic end generated code: output=55f8dc0ffa87406f input=b85a667f9bf4669d]*/
{
PyObject *it; /* iter(seq) */
PyObject *key;
@@ -2209,7 +2211,9 @@ True if D has a key k, else False.
[clinic start generated code]*/
PyDoc_STRVAR(dict___contains____doc__,
-"sig=($self, key)\n"
+"__contains__($self, key, /)\n"
+"--\n"
+"\n"
"True if D has a key k, else False.");
#define DICT___CONTAINS___METHODDEF \
@@ -2217,7 +2221,7 @@ PyDoc_STRVAR(dict___contains____doc__,
static PyObject *
dict___contains__(PyDictObject *self, PyObject *key)
-/*[clinic end generated code: output=c654684a6d880281 input=b852b2a19b51ab24]*/
+/*[clinic end generated code: output=3cf3f8aaf2cc5cc3 input=b852b2a19b51ab24]*/
{
register PyDictObject *mp = self;
Py_hash_t hash;
diff --git a/Objects/methodobject.c b/Objects/methodobject.c
index ead7443..f2616d4 100644
--- a/Objects/methodobject.c
+++ b/Objects/methodobject.c
@@ -182,13 +182,13 @@ static PyMethodDef meth_methods[] = {
static PyObject *
meth_get__text_signature__(PyCFunctionObject *m, void *closure)
{
- return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_doc);
+ return _PyType_GetTextSignatureFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
}
static PyObject *
meth_get__doc__(PyCFunctionObject *m, void *closure)
{
- return _PyType_GetDocFromInternalDoc(m->m_ml->ml_doc);
+ return _PyType_GetDocFromInternalDoc(m->m_ml->ml_name, m->m_ml->ml_doc);
}
static PyObject *
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 23015b2..b9df44c 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -55,51 +55,75 @@ static PyObject *
slot_tp_new(PyTypeObject *type, PyObject *args, PyObject *kwds);
/*
- * finds the docstring's introspection signature.
+ * finds the beginning of the docstring's introspection signature.
* if present, returns a pointer pointing to the first '('.
* otherwise returns NULL.
+ *
+ * doesn't guarantee that the signature is valid, only that it
+ * has a valid prefix. (the signature must also pass skip_signature.)
*/
static const char *
-find_signature(const char *doc)
+find_signature(const char *name, const char *doc)
{
- if (doc && !strncmp(doc, "sig=(", 5))
- return doc + 4;
- return NULL;
+ const char *dot;
+ size_t length;
+
+ if (!doc)
+ return NULL;
+
+ assert(name != NULL);
+
+ /* for dotted names like classes, only use the last component */
+ dot = strrchr(name, '.');
+ if (dot)
+ name = dot + 1;
+
+ length = strlen(name);
+ if (strncmp(doc, name, length))
+ return NULL;
+ doc += length;
+ if (*doc != '(')
+ return NULL;
+ return doc;
}
+#define SIGNATURE_END_MARKER ")\n--\n\n"
+#define SIGNATURE_END_MARKER_LENGTH 6
/*
- * skips to the end of the docstring's instrospection signature.
+ * skips past the end of the docstring's instrospection signature.
+ * (assumes doc starts with a valid signature prefix.)
*/
static const char *
skip_signature(const char *doc)
{
- while (*doc && *doc != '\n')
+ while (*doc) {
+ if ((*doc == *SIGNATURE_END_MARKER) &&
+ !strncmp(doc, SIGNATURE_END_MARKER, SIGNATURE_END_MARKER_LENGTH))
+ return doc + SIGNATURE_END_MARKER_LENGTH;
+ if ((*doc == '\n') && (doc[1] == '\n'))
+ return NULL;
doc++;
- return doc;
-}
-
-static const char *
-skip_eols(const char *trace)
-{
- while (*trace == '\n')
- trace++;
- return trace;
+ }
+ return NULL;
}
static const char *
-_PyType_DocWithoutSignature(const char *internal_doc)
+_PyType_DocWithoutSignature(const char *name, const char *internal_doc)
{
- const char *signature = find_signature(internal_doc);
+ const char *doc = find_signature(name, internal_doc);
- if (signature)
- return skip_eols(skip_signature(signature));
+ if (doc) {
+ doc = skip_signature(doc);
+ if (doc)
+ return doc;
+ }
return internal_doc;
}
PyObject *
-_PyType_GetDocFromInternalDoc(const char *internal_doc)
+_PyType_GetDocFromInternalDoc(const char *name, const char *internal_doc)
{
- const char *doc = _PyType_DocWithoutSignature(internal_doc);
+ const char *doc = _PyType_DocWithoutSignature(name, internal_doc);
if (!doc) {
Py_INCREF(Py_None);
@@ -110,18 +134,26 @@ _PyType_GetDocFromInternalDoc(const char *internal_doc)
}
PyObject *
-_PyType_GetTextSignatureFromInternalDoc(const char *internal_doc)
+_PyType_GetTextSignatureFromInternalDoc(const char *name, const char *internal_doc)
{
- const char *signature = find_signature(internal_doc);
- const char *doc;
+ const char *start = find_signature(name, internal_doc);
+ const char *end;
- if (!signature) {
+ if (start)
+ end = skip_signature(start);
+ else
+ end = NULL;
+ if (!end) {
Py_INCREF(Py_None);
return Py_None;
}
- doc = skip_signature(signature);
- return PyUnicode_FromStringAndSize(signature, doc - signature);
+ /* back "end" up until it points just past the final ')' */
+ end -= SIGNATURE_END_MARKER_LENGTH - 1;
+ assert((end - start) >= 2); /* should be "()" at least */
+ assert(end[-1] == ')');
+ assert(end[0] == '\n');
+ return PyUnicode_FromStringAndSize(start, end - start);
}
unsigned int
@@ -699,7 +731,7 @@ type_get_doc(PyTypeObject *type, void *context)
{
PyObject *result;
if (!(type->tp_flags & Py_TPFLAGS_HEAPTYPE) && type->tp_doc != NULL) {
- return _PyType_GetDocFromInternalDoc(type->tp_doc);
+ return _PyType_GetDocFromInternalDoc(type->tp_name, type->tp_doc);
}
result = _PyDict_GetItemId(type->tp_dict, &PyId___doc__);
if (result == NULL) {
@@ -719,7 +751,7 @@ type_get_doc(PyTypeObject *type, void *context)
static PyObject *
type_get_text_signature(PyTypeObject *type, void *context)
{
- return _PyType_GetTextSignatureFromInternalDoc(type->tp_doc);
+ return _PyType_GetTextSignatureFromInternalDoc(type->tp_name, type->tp_doc);
}
static int
@@ -2597,7 +2629,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
/* need to make a copy of the docstring slot, which usually
points to a static string literal */
if (slot->slot == Py_tp_doc) {
- const char *old_doc = _PyType_DocWithoutSignature(slot->pfunc);
+ const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc);
size_t len = strlen(old_doc)+1;
char *tp_doc = PyObject_MALLOC(len);
if (tp_doc == NULL) {
@@ -3002,7 +3034,7 @@ static PyMethodDef type_methods[] = {
PyDoc_STRVAR(type_doc,
/* this text signature cannot be accurate yet. will fix. --larry */
-"sig=(object_or_name, bases, dict)\n"
+"type(object_or_name, bases, dict)\n"
"type(object) -> the object's type\n"
"type(name, bases, dict) -> a new type");
@@ -4198,7 +4230,7 @@ PyTypeObject PyBaseObject_Type = {
PyObject_GenericSetAttr, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
- PyDoc_STR("sig=()\nThe most base type"), /* tp_doc */
+ PyDoc_STR("object()\n--\n\nThe most base type"), /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
object_richcompare, /* tp_richcompare */
@@ -4665,7 +4697,8 @@ PyType_Ready(PyTypeObject *type)
*/
if (_PyDict_GetItemId(type->tp_dict, &PyId___doc__) == NULL) {
if (type->tp_doc != NULL) {
- const char *old_doc = _PyType_DocWithoutSignature(type->tp_doc);
+ const char *old_doc = _PyType_DocWithoutSignature(type->tp_name,
+ type->tp_doc);
PyObject *doc = PyUnicode_FromString(old_doc);
if (doc == NULL)
goto error;
@@ -5327,7 +5360,7 @@ tp_new_wrapper(PyObject *self, PyObject *args, PyObject *kwds)
static struct PyMethodDef tp_new_methoddef[] = {
{"__new__", (PyCFunction)tp_new_wrapper, METH_VARARGS|METH_KEYWORDS,
- PyDoc_STR("sig=($type, *args, **kwargs)\n"
+ PyDoc_STR("__new__($type, *args, **kwargs)\n--\n\n"
"Create and return a new object. "
"See help(type) for accurate signature.")},
{0}
@@ -6101,22 +6134,22 @@ typedef struct wrapperbase slotdef;
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, DOC)
#define UNSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
- "sig=($self)\n" DOC)
+ NAME "($self)\n--\n\n" DOC)
#define IBSLOT(NAME, SLOT, FUNCTION, WRAPPER, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, WRAPPER, \
- "sig=($self, value)\nReturn self" DOC "value.")
+ NAME "($self, value)\n--\n\nReturn self" DOC "value.")
#define BINSLOT(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
- "sig=($self, value)\nReturn self" DOC "value.")
+ NAME "($self, value)\n--\n\nReturn self" DOC "value.")
#define RBINSLOT(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
- "sig=($self, value)\nReturn value" DOC "self.")
+ NAME "($self, value)\n--\n\nReturn value" DOC "self.")
#define BINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_l, \
- "sig=($self, value)\n" DOC)
+ NAME "($self, value)\n--\n\n" DOC)
#define RBINSLOTNOTINFIX(NAME, SLOT, FUNCTION, DOC) \
ETSLOT(NAME, as_number.SLOT, FUNCTION, wrap_binaryfunc_r, \
- "sig=($self, value)\n" DOC)
+ NAME "($self, value)\n--\n\n" DOC)
static slotdef slotdefs[] = {
TPSLOT("__getattribute__", tp_getattr, NULL, NULL, ""),
@@ -6124,51 +6157,51 @@ static slotdef slotdefs[] = {
TPSLOT("__setattr__", tp_setattr, NULL, NULL, ""),
TPSLOT("__delattr__", tp_setattr, NULL, NULL, ""),
TPSLOT("__repr__", tp_repr, slot_tp_repr, wrap_unaryfunc,
- "sig=($self)\nReturn repr(self)."),
+ "__repr__($self)\n--\n\nReturn repr(self)."),
TPSLOT("__hash__", tp_hash, slot_tp_hash, wrap_hashfunc,
- "sig=($self)\nReturn hash(self)."),
+ "__hash__($self)\n--\n\nReturn hash(self)."),
FLSLOT("__call__", tp_call, slot_tp_call, (wrapperfunc)wrap_call,
- "sig=($self, *args, **kwargs)\nCall self as a function.",
+ "__call__($self, *args, **kwargs)\n--\n\nCall self as a function.",
PyWrapperFlag_KEYWORDS),
TPSLOT("__str__", tp_str, slot_tp_str, wrap_unaryfunc,
- "sig=($self)\nReturn str(self)."),
+ "__str__($self)\n--\n\nReturn str(self)."),
TPSLOT("__getattribute__", tp_getattro, slot_tp_getattr_hook,
wrap_binaryfunc,
- "sig=($self, name)\nReturn getattr(self, name)."),
+ "__getattribute__($self, name)\n--\n\nReturn getattr(self, name)."),
TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook, NULL, ""),
TPSLOT("__setattr__", tp_setattro, slot_tp_setattro, wrap_setattr,
- "sig=($self, name, value)\nImplement setattr(self, name, value)."),
+ "__setattr__($self, name, value)\n--\n\nImplement setattr(self, name, value)."),
TPSLOT("__delattr__", tp_setattro, slot_tp_setattro, wrap_delattr,
- "sig=($self, name)\nImplement delattr(self, name)."),
+ "__delattr__($self, name)\n--\n\nImplement delattr(self, name)."),
TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare, richcmp_lt,
- "sig=($self, value)\nReturn self<value."),
+ "__lt__($self, value)\n--\n\nReturn self<value."),
TPSLOT("__le__", tp_richcompare, slot_tp_richcompare, richcmp_le,
- "sig=($self, value)\nReturn self<=value."),
+ "__le__($self, value)\n--\n\nReturn self<=value."),
TPSLOT("__eq__", tp_richcompare, slot_tp_richcompare, richcmp_eq,
- "sig=($self, value)\nReturn self==value."),
+ "__eq__($self, value)\n--\n\nReturn self==value."),
TPSLOT("__ne__", tp_richcompare, slot_tp_richcompare, richcmp_ne,
- "sig=($self, value)\nReturn self!=value."),
+ "__ne__($self, value)\n--\n\nReturn self!=value."),
TPSLOT("__gt__", tp_richcompare, slot_tp_richcompare, richcmp_gt,
- "sig=($self, value)\nReturn self>value."),
+ "__gt__($self, value)\n--\n\nReturn self>value."),
TPSLOT("__ge__", tp_richcompare, slot_tp_richcompare, richcmp_ge,
- "sig=($self, value)\nReturn self>=value."),
+ "__ge__=($self, value)\n--\n\nReturn self>=value."),
TPSLOT("__iter__", tp_iter, slot_tp_iter, wrap_unaryfunc,
- "sig=($self)\nImplement iter(self)."),
+ "__iter__($self)\n--\n\nImplement iter(self)."),
TPSLOT("__next__", tp_iternext, slot_tp_iternext, wrap_next,
- "sig=($self)\nImplement next(self)."),
+ "__next__($self)\n--\n\nImplement next(self)."),
TPSLOT("__get__", tp_descr_get, slot_tp_descr_get, wrap_descr_get,
- "sig=($self, instance, owner)\nReturn an attribute of instance, which is of type owner."),
+ "__get__($self, instance, owner)\n--\n\nReturn an attribute of instance, which is of type owner."),
TPSLOT("__set__", tp_descr_set, slot_tp_descr_set, wrap_descr_set,
- "sig=($self, instance, value)\nSet an attribute of instance to value."),
+ "__set__($self, instance, value)\n--\n\nSet an attribute of instance to value."),
TPSLOT("__delete__", tp_descr_set, slot_tp_descr_set,
wrap_descr_delete,
- "sig=(instance)\nDelete an attribute of instance."),
+ "__delete__(instance)\n--\n\nDelete an attribute of instance."),
FLSLOT("__init__", tp_init, slot_tp_init, (wrapperfunc)wrap_init,
- "sig=($self, *args, **kwargs)\n"
+ "__init__($self, *args, **kwargs)\n--\n\n"
"Initialize self. See help(type(self)) for accurate signature.",
PyWrapperFlag_KEYWORDS),
TPSLOT("__new__", tp_new, slot_tp_new, NULL,
- "sig=(type, *args, **kwargs)\n"
+ "__new__(type, *args, **kwargs)\n--\n\n"
"Create and return new object. See help(type) for accurate signature."),
TPSLOT("__del__", tp_finalize, slot_tp_finalize, (wrapperfunc)wrap_del, ""),
@@ -6193,9 +6226,9 @@ static slotdef slotdefs[] = {
RBINSLOTNOTINFIX("__rdivmod__", nb_divmod, slot_nb_divmod,
"Return divmod(value, self)."),
NBSLOT("__pow__", nb_power, slot_nb_power, wrap_ternaryfunc,
- "sig=($self, value, mod=None)\nReturn pow(self, value, mod)."),
+ "__pow__($self, value, mod=None)\n--\n\nReturn pow(self, value, mod)."),
NBSLOT("__rpow__", nb_power, slot_nb_power, wrap_ternaryfunc_r,
- "sig=($self, value, mod=None)\nReturn pow(value, self, mod)."),
+ "__rpow__($self, value, mod=None)\n--\n\nReturn pow(value, self, mod)."),
UNSLOT("__neg__", nb_negative, slot_nb_negative, wrap_unaryfunc, "-self"),
UNSLOT("__pos__", nb_positive, slot_nb_positive, wrap_unaryfunc, "+self"),
UNSLOT("__abs__", nb_absolute, slot_nb_absolute, wrap_unaryfunc,
@@ -6246,48 +6279,48 @@ static slotdef slotdefs[] = {
IBSLOT("__itruediv__", nb_inplace_true_divide,
slot_nb_inplace_true_divide, wrap_binaryfunc, "/"),
NBSLOT("__index__", nb_index, slot_nb_index, wrap_unaryfunc,
- "sig=($self)\n"
+ "__index__($self)\n--\n\n"
"Return self converted to an integer, if self is suitable"
"for use as an index into a list."),
MPSLOT("__len__", mp_length, slot_mp_length, wrap_lenfunc,
- "sig=($self)\nReturn len(self)."),
+ "__len__($self)\n--\n\nReturn len(self)."),
MPSLOT("__getitem__", mp_subscript, slot_mp_subscript,
wrap_binaryfunc,
- "sig=($self, key)\nReturn self[key]."),
+ "__getitem__($self, key)\n--\n\nReturn self[key]."),
MPSLOT("__setitem__", mp_ass_subscript, slot_mp_ass_subscript,
wrap_objobjargproc,
- "sig=($self, key, value)\nSet self[key] to value."),
+ "__setitem__($self, key, value)\n--\n\nSet self[key] to value."),
MPSLOT("__delitem__", mp_ass_subscript, slot_mp_ass_subscript,
wrap_delitem,
- "sig=(key)\nDelete self[key]."),
+ "__delitem__(key)\n--\n\nDelete self[key]."),
SQSLOT("__len__", sq_length, slot_sq_length, wrap_lenfunc,
- "sig=($self)\nReturn len(self)."),
+ "__len__($self)\n--\n\nReturn len(self)."),
/* Heap types defining __add__/__mul__ have sq_concat/sq_repeat == NULL.
The logic in abstract.c always falls back to nb_add/nb_multiply in
this case. Defining both the nb_* and the sq_* slots to call the
user-defined methods has unexpected side-effects, as shown by
test_descr.notimplemented() */
SQSLOT("__add__", sq_concat, NULL, wrap_binaryfunc,
- "sig=($self, value)\nReturn self+value."),
+ "__add__($self, value)\n--\n\nReturn self+value."),
SQSLOT("__mul__", sq_repeat, NULL, wrap_indexargfunc,
- "sig=($self, value)\nReturn self*value.n"),
+ "__mul__($self, value)\n--\n\nReturn self*value.n"),
SQSLOT("__rmul__", sq_repeat, NULL, wrap_indexargfunc,
- "sig=($self, value)\nReturn self*value."),
+ "__rmul__($self, value)\n--\n\nReturn self*value."),
SQSLOT("__getitem__", sq_item, slot_sq_item, wrap_sq_item,
- "sig=($self, key)\nReturn self[key]."),
+ "__getitem__($self, key)\n--\n\nReturn self[key]."),
SQSLOT("__setitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_setitem,
- "sig=($self, key, value)\nSet self[key] to value."),
+ "__setitem__($self, key, value)\n--\n\nSet self[key] to value."),
SQSLOT("__delitem__", sq_ass_item, slot_sq_ass_item, wrap_sq_delitem,
- "sig=($self, key)\nDelete self[key]."),
+ "__delitem__($self, key)\n--\n\nDelete self[key]."),
SQSLOT("__contains__", sq_contains, slot_sq_contains, wrap_objobjproc,
- "sig=($self, key)\nReturn key in self."),
+ "__contains__($self, key)\n--\n\nReturn key in self."),
SQSLOT("__iadd__", sq_inplace_concat, NULL,
wrap_binaryfunc,
- "sig=($self, value)\nImplement self+=value."),
+ "__iadd__($self, value)\n--\n\nImplement self+=value."),
SQSLOT("__imul__", sq_inplace_repeat, NULL,
wrap_indexargfunc,
- "sig=($self, value)\nImplement self*=value."),
+ "__imul__($self, value)\n--\n\nImplement self*=value."),
{NULL}
};
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 7a1aa16..eae4bc5 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -12893,7 +12893,9 @@ must be a string, whose characters will be mapped to None in the result.
[clinic start generated code]*/
PyDoc_STRVAR(unicode_maketrans__doc__,
-"sig=(x, y=None, z=None)\n"
+"maketrans(x, y=None, z=None, /)\n"
+"--\n"
+"\n"
"Return a translation table usable for str.translate().\n"
"\n"
"If there is only one argument, it must be a dictionary mapping Unicode\n"
@@ -12930,7 +12932,7 @@ exit:
static PyObject *
unicode_maketrans_impl(PyObject *x, PyObject *y, PyObject *z)
-/*[clinic end generated code: output=ca001ac83ed32269 input=7bfbf529a293c6c5]*/
+/*[clinic end generated code: output=566edf630f77436a input=7bfbf529a293c6c5]*/
{
PyObject *new = NULL, *key, *value;
Py_ssize_t i = 0;
diff --git a/Python/import.c b/Python/import.c
index 5e5355d..001d745 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -232,7 +232,9 @@ On platforms without threads, return False.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_lock_held__doc__,
-"sig=($module)\n"
+"lock_held($module, /)\n"
+"--\n"
+"\n"
"Return True if the import lock is currently held, else False.\n"
"\n"
"On platforms without threads, return False.");
@@ -251,7 +253,7 @@ _imp_lock_held(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject *
_imp_lock_held_impl(PyModuleDef *module)
-/*[clinic end generated code: output=5ce46d12a8e4c469 input=9b088f9b217d9bdf]*/
+/*[clinic end generated code: output=dae65674966baa65 input=9b088f9b217d9bdf]*/
{
#ifdef WITH_THREAD
return PyBool_FromLong(import_lock_thread != -1);
@@ -270,7 +272,9 @@ modules. On platforms without threads, this function does nothing.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_acquire_lock__doc__,
-"sig=($module)\n"
+"acquire_lock($module, /)\n"
+"--\n"
+"\n"
"Acquires the interpreter\'s import lock for the current thread.\n"
"\n"
"This lock should be used by import hooks to ensure thread-safety when importing\n"
@@ -290,7 +294,7 @@ _imp_acquire_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject *
_imp_acquire_lock_impl(PyModuleDef *module)
-/*[clinic end generated code: output=b0dd6a132ad25961 input=4a2d4381866d5fdc]*/
+/*[clinic end generated code: output=478f1fa089fdb9a4 input=4a2d4381866d5fdc]*/
{
#ifdef WITH_THREAD
_PyImport_AcquireLock();
@@ -308,7 +312,9 @@ On platforms without threads, this function does nothing.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_release_lock__doc__,
-"sig=($module)\n"
+"release_lock($module, /)\n"
+"--\n"
+"\n"
"Release the interpreter\'s import lock.\n"
"\n"
"On platforms without threads, this function does nothing.");
@@ -327,7 +333,7 @@ _imp_release_lock(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject *
_imp_release_lock_impl(PyModuleDef *module)
-/*[clinic end generated code: output=b1e6e9d723cf5f89 input=934fb11516dd778b]*/
+/*[clinic end generated code: output=36c77a6832fdafd4 input=934fb11516dd778b]*/
{
#ifdef WITH_THREAD
if (_PyImport_ReleaseLock() < 0) {
@@ -927,7 +933,9 @@ Changes code.co_filename to specify the passed-in file path.
[clinic start generated code]*/
PyDoc_STRVAR(_imp__fix_co_filename__doc__,
-"sig=($module, code, path)\n"
+"_fix_co_filename($module, code, path, /)\n"
+"--\n"
+"\n"
"Changes code.co_filename to specify the passed-in file path.\n"
"\n"
" code\n"
@@ -960,7 +968,7 @@ exit:
static PyObject *
_imp__fix_co_filename_impl(PyModuleDef *module, PyCodeObject *code, PyObject *path)
-/*[clinic end generated code: output=3fe5b5a1b0d497df input=895ba50e78b82f05]*/
+/*[clinic end generated code: output=6b4b1edeb0d55c5d input=895ba50e78b82f05]*/
{
update_compiled_module(code, path);
@@ -1823,7 +1831,9 @@ Returns the list of file suffixes used to identify extension modules.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_extension_suffixes__doc__,
-"sig=($module)\n"
+"extension_suffixes($module, /)\n"
+"--\n"
+"\n"
"Returns the list of file suffixes used to identify extension modules.");
#define _IMP_EXTENSION_SUFFIXES_METHODDEF \
@@ -1840,7 +1850,7 @@ _imp_extension_suffixes(PyModuleDef *module, PyObject *Py_UNUSED(ignored))
static PyObject *
_imp_extension_suffixes_impl(PyModuleDef *module)
-/*[clinic end generated code: output=c1bcfbddabefa00a input=ecdeeecfcb6f839e]*/
+/*[clinic end generated code: output=bb30a2438167798c input=ecdeeecfcb6f839e]*/
{
PyObject *list;
const char *suffix;
@@ -1878,7 +1888,9 @@ Initializes a built-in module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_init_builtin__doc__,
-"sig=($module, name)\n"
+"init_builtin($module, name, /)\n"
+"--\n"
+"\n"
"Initializes a built-in module.");
#define _IMP_INIT_BUILTIN_METHODDEF \
@@ -1905,7 +1917,7 @@ exit:
static PyObject *
_imp_init_builtin_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: output=02437efd4668f53e input=f934d2231ec52a2e]*/
+/*[clinic end generated code: output=a0244948a43f8e26 input=f934d2231ec52a2e]*/
{
int ret;
PyObject *m;
@@ -1932,7 +1944,9 @@ Initializes a frozen module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_init_frozen__doc__,
-"sig=($module, name)\n"
+"init_frozen($module, name, /)\n"
+"--\n"
+"\n"
"Initializes a frozen module.");
#define _IMP_INIT_FROZEN_METHODDEF \
@@ -1959,7 +1973,7 @@ exit:
static PyObject *
_imp_init_frozen_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: output=20cea421af513afe input=13019adfc04f3fb3]*/
+/*[clinic end generated code: output=e4bc2bff296f8f22 input=13019adfc04f3fb3]*/
{
int ret;
PyObject *m;
@@ -1986,7 +2000,9 @@ Create a code object for a frozen module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_get_frozen_object__doc__,
-"sig=($module, name)\n"
+"get_frozen_object($module, name, /)\n"
+"--\n"
+"\n"
"Create a code object for a frozen module.");
#define _IMP_GET_FROZEN_OBJECT_METHODDEF \
@@ -2013,7 +2029,7 @@ exit:
static PyObject *
_imp_get_frozen_object_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: output=f00d01ae30ec842f input=ed689bc05358fdbd]*/
+/*[clinic end generated code: output=4089ec702a9d70c5 input=ed689bc05358fdbd]*/
{
return get_frozen_object(name);
}
@@ -2028,7 +2044,9 @@ Returns True if the module name is of a frozen package.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_is_frozen_package__doc__,
-"sig=($module, name)\n"
+"is_frozen_package($module, name, /)\n"
+"--\n"
+"\n"
"Returns True if the module name is of a frozen package.");
#define _IMP_IS_FROZEN_PACKAGE_METHODDEF \
@@ -2055,7 +2073,7 @@ exit:
static PyObject *
_imp_is_frozen_package_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: output=35c78f2448c6fcff input=81b6cdecd080fbb8]*/
+/*[clinic end generated code: output=86aab14dcd4b959b input=81b6cdecd080fbb8]*/
{
return is_frozen_package(name);
}
@@ -2070,7 +2088,9 @@ Returns True if the module name corresponds to a built-in module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_is_builtin__doc__,
-"sig=($module, name)\n"
+"is_builtin($module, name, /)\n"
+"--\n"
+"\n"
"Returns True if the module name corresponds to a built-in module.");
#define _IMP_IS_BUILTIN_METHODDEF \
@@ -2097,7 +2117,7 @@ exit:
static PyObject *
_imp_is_builtin_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: output=641689f833347f66 input=86befdac021dd1c7]*/
+/*[clinic end generated code: output=d5847f8cac50946e input=86befdac021dd1c7]*/
{
return PyLong_FromLong(is_builtin(name));
}
@@ -2112,7 +2132,9 @@ Returns True if the module name corresponds to a frozen module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_is_frozen__doc__,
-"sig=($module, name)\n"
+"is_frozen($module, name, /)\n"
+"--\n"
+"\n"
"Returns True if the module name corresponds to a frozen module.");
#define _IMP_IS_FROZEN_METHODDEF \
@@ -2139,7 +2161,7 @@ exit:
static PyObject *
_imp_is_frozen_impl(PyModuleDef *module, PyObject *name)
-/*[clinic end generated code: output=0f80c7a3f283a686 input=7301dbca1897d66b]*/
+/*[clinic end generated code: output=6691af884ba4987d input=7301dbca1897d66b]*/
{
const struct _frozen *p;
@@ -2161,7 +2183,9 @@ Loads an extension module.
[clinic start generated code]*/
PyDoc_STRVAR(_imp_load_dynamic__doc__,
-"sig=($module, name, path, file=None)\n"
+"load_dynamic($module, name, path, file=None, /)\n"
+"--\n"
+"\n"
"Loads an extension module.");
#define _IMP_LOAD_DYNAMIC_METHODDEF \
@@ -2190,7 +2214,7 @@ exit:
static PyObject *
_imp_load_dynamic_impl(PyModuleDef *module, PyObject *name, PyObject *path, PyObject *file)
-/*[clinic end generated code: output=8f33f48dc6252948 input=af64f06e4bad3526]*/
+/*[clinic end generated code: output=81d11a1fbd1ea0a8 input=af64f06e4bad3526]*/
{
PyObject *mod;
FILE *fp;
diff --git a/Tools/clinic/clinic.py b/Tools/clinic/clinic.py
index e7e45c5..68a1436 100755
--- a/Tools/clinic/clinic.py
+++ b/Tools/clinic/clinic.py
@@ -1123,10 +1123,12 @@ def OverrideStdioWith(stdout):
sys.stdout = saved_stdout
-def create_regex(before, after, word=True):
+def create_regex(before, after, word=True, whole_line=True):
"""Create an re object for matching marker lines."""
group_re = "\w+" if word else ".+"
- pattern = r'^{}({}){}$'
+ pattern = r'{}({}){}'
+ if whole_line:
+ pattern = '^' + pattern + '$'
pattern = pattern.format(re.escape(before), group_re, re.escape(after))
return re.compile(pattern)
@@ -1218,6 +1220,7 @@ class BlockParser:
self.language = language
before, _, after = language.start_line.partition('{dsl_name}')
assert _ == '{dsl_name}'
+ self.find_start_re = create_regex(before, after, whole_line=False)
self.start_re = create_regex(before, after)
self.verify = verify
self.last_checksum_re = None
@@ -1735,11 +1738,15 @@ def parse_file(filename, *, force=False, verify=True, output=None, encoding='utf
except KeyError:
fail("Can't identify file type for file " + repr(filename))
- clinic = Clinic(language, force=force, verify=verify, filename=filename)
-
with open(filename, 'r', encoding=encoding) as f:
raw = f.read()
+ # exit quickly if there are no clinic markers in the file
+ find_start_re = BlockParser("", language).find_start_re
+ if not find_start_re.search(raw):
+ return
+
+ clinic = Clinic(language, force=force, verify=verify, filename=filename)
cooked = clinic.parse(raw)
if (cooked == raw) and not force:
return
@@ -1897,7 +1904,7 @@ class Function:
full_name=None,
return_converter, return_annotation=_empty,
docstring=None, kind=CALLABLE, coexist=False,
- suppress_signature=False):
+ docstring_only=False):
self.parameters = parameters or collections.OrderedDict()
self.return_annotation = return_annotation
self.name = name
@@ -1911,7 +1918,11 @@ class Function:
self.kind = kind
self.coexist = coexist
self.self_converter = None
- self.suppress_signature = suppress_signature
+ # docstring_only means "don't generate a machine-readable
+ # signature, just a normal docstring". it's True for
+ # functions with optional groups because we can't represent
+ # those accurately with inspect.Signature in 3.4.
+ self.docstring_only = docstring_only
self.rendered_parameters = None
@@ -1951,7 +1962,7 @@ class Function:
'full_name': self.full_name,
'return_converter': self.return_converter, 'return_annotation': self.return_annotation,
'docstring': self.docstring, 'kind': self.kind, 'coexist': self.coexist,
- 'suppress_signature': self.suppress_signature,
+ 'docstring_only': self.docstring_only,
}
kwargs.update(overrides)
f = Function(**kwargs)
@@ -1987,6 +1998,9 @@ class Parameter:
def is_keyword_only(self):
return self.kind == inspect.Parameter.KEYWORD_ONLY
+ def is_positional_only(self):
+ return self.kind == inspect.Parameter.POSITIONAL_ONLY
+
def copy(self, **overrides):
kwargs = {
'name': self.name, 'kind': self.kind, 'default':self.default,
@@ -2929,7 +2943,7 @@ class IndentStack:
Returns the length of the line's margin.
"""
if '\t' in line:
- fail('Tab characters are illegal in the Clinic DSL.')
+ fail('Tab characters are illegal in the Argument Clinic DSL.')
stripped = line.lstrip()
if not len(stripped):
# we can't tell anything from an empty line
@@ -3694,7 +3708,7 @@ class DSLParser:
else:
fail("Function " + self.function.name + " has an unsupported group configuration. (Unexpected state " + str(self.parameter_state) + ".b)")
self.group += 1
- self.function.suppress_signature = True
+ self.function.docstring_only = True
elif symbol == ']':
if not self.group:
fail("Function " + self.function.name + " has a ] without a matching [.")
@@ -3783,21 +3797,20 @@ class DSLParser:
# don't render a docstring at all, no signature, nothing.
return f.docstring
- add, output = text_accumulator()
+ text, add, output = _text_accumulator()
parameters = f.render_parameters
##
## docstring first line
##
- if not f.suppress_signature:
- add('sig=')
+ if new_or_init:
+ # classes get *just* the name of the class
+ # not __new__, not __init__, and not module.classname
+ assert f.cls
+ add(f.cls.name)
else:
- if new_or_init:
- assert f.cls
- add(f.cls.name)
- else:
- add(f.name)
+ add(f.name)
add('(')
# populate "right_bracket_count" field for every parameter
@@ -3834,53 +3847,105 @@ class DSLParser:
right_bracket_count -= 1
return s
+ need_slash = False
+ added_slash = False
+ need_a_trailing_slash = False
+
+ # we only need a trailing slash:
+ # * if this is not a "docstring_only" signature
+ # * and if the last *shown* parameter is
+ # positional only
+ if not f.docstring_only:
+ 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
- add_comma = False
+
+ first_parameter = True
+ last_p = parameters[-1]
+ line_length = len(''.join(text))
+ indent = " " * line_length
+ def add_parameter(text):
+ 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:
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():
+ need_slash = not f.docstring_only
+ 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
- if add_comma:
- add(', ')
- add('*')
- add_comma = True
+ add_parameter('*,')
- name = p.converter.signature_name or p.name
+ p_add, p_output = text_accumulator()
+ p_add(fix_right_bracket_count(p.right_bracket_count))
- a = []
if isinstance(p.converter, self_converter):
- if f.suppress_signature:
- continue
- else:
- # annotate first parameter as being a "self".
- #
- # if inspect.Signature gets this function, and it's already bound,
- # the self parameter will be stripped off.
- #
- # if it's not bound, it should be marked as positional-only.
- a.append('$')
- a.append(name)
- else:
- a.append(name)
+ # annotate first parameter as being a "self".
+ #
+ # if inspect.Signature gets this function,
+ # 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 contruct a new instance.
+ p_add('$')
+
+ name = p.converter.signature_name or p.name
+ p_add(name)
+
if p.converter.is_optional():
- a.append('=')
+ p_add('=')
value = p.converter.py_default
if not value:
value = repr(p.converter.default)
- a.append(value)
- s = fix_right_bracket_count(p.right_bracket_count)
- s += "".join(a)
- if add_comma:
- add(', ')
- add(s)
- add_comma = True
+ 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:
@@ -3896,6 +3961,9 @@ class DSLParser:
# add(' -> ')
# add(f.return_converter.py_default)
+ if not f.docstring_only:
+ add("\n--\n")
+
docstring_first_line = output()
# now fix up the places where the brackets look wrong
diff --git a/Tools/clinic/clinic_test.py b/Tools/clinic/clinic_test.py
index 67b0eb9..cd21000 100644
--- a/Tools/clinic/clinic_test.py
+++ b/Tools/clinic/clinic_test.py
@@ -359,7 +359,9 @@ os.stat as os_stat_fn
Perform a stat system call on the given path.""")
self.assertEqual("""
-sig=($module, path)
+stat($module, /, path)
+--
+
Perform a stat system call on the given path.
path
@@ -379,7 +381,9 @@ This is the documentation for foo.
Okay, we're done here.
""")
self.assertEqual("""
-sig=($module, x, y)
+bar($module, /, x, y)
+--
+
This is the documentation for foo.
x
@@ -395,7 +399,7 @@ os.stat
path: str
This/used to break Clinic!
""")
- self.assertEqual("sig=($module, path)\n\nThis/used to break Clinic!", function.docstring)
+ self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring)
def test_c_name(self):
function = self.parse_function("module os\nos.stat as os_stat_fn")
@@ -504,7 +508,8 @@ curses.imaginary
self.assertEqual(p.kind, inspect.Parameter.POSITIONAL_ONLY)
self.assertEqual(function.docstring.strip(), """
-imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5, attr6]])
+imaginary([[y1, y2,] x1, x2,] ch, [attr1, attr2, attr3, [attr4, attr5,
+ attr6]])
y1
@@ -624,9 +629,23 @@ foo.bar
Docstring
""")
- self.assertEqual("sig=($module)\nDocstring", function.docstring)
+ self.assertEqual("bar($module, /)\n--\n\nDocstring", function.docstring)
self.assertEqual(1, len(function.parameters)) # self!
+ def test_init_with_no_parameters(self):
+ function = self.parse_function("""
+module foo
+class foo.Bar "unused" "notneeded"
+foo.Bar.__init__
+
+Docstring
+
+""", signatures_in_block=3, function_index=2)
+ # self is not in the signature
+ self.assertEqual("Bar()\n--\n\nDocstring", function.docstring)
+ # but it *is* a parameter
+ self.assertEqual(1, len(function.parameters))
+
def test_illegal_module_line(self):
self.parse_function_should_fail("""
module foo
@@ -719,7 +738,9 @@ foo.bar
Not at column 0!
""")
self.assertEqual("""
-sig=($module, x, *, y)
+bar($module, /, x, *, y)
+--
+
Not at column 0!
x
@@ -733,7 +754,7 @@ os.stat
path: str
This/used to break Clinic!
""")
- self.assertEqual("sig=($module, path)\nThis/used to break Clinic!", function.docstring)
+ self.assertEqual("stat($module, /, path)\n--\n\nThis/used to break Clinic!", function.docstring)
def test_directive(self):
c = FakeClinic()
@@ -756,13 +777,13 @@ This/used to break Clinic!
parser.parse(block)
return block
- def parse_function(self, text):
+ def parse_function(self, text, signatures_in_block=2, function_index=1):
block = self.parse(text)
s = block.signatures
- self.assertEqual(len(s), 2)
+ self.assertEqual(len(s), signatures_in_block)
assert isinstance(s[0], clinic.Module)
- assert isinstance(s[1], clinic.Function)
- return s[1]
+ assert isinstance(s[function_index], clinic.Function)
+ return s[function_index]
def test_scaffolding(self):
# test repr on special values