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.
This commit is contained in:
Larry Hastings 2014-02-08 22:15:29 -08:00
parent 09f08fe248
commit 2623c8c23c
28 changed files with 825 additions and 327 deletions

View File

@ -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 */

View File

@ -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
clean_signature, self_parameter, last_positional_only = \
_signature_strip_non_python_syntax(s)
first_parameter_is_self = s.startswith("($")
if first_parameter_is_self:
s = '(' + s[2:]
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

View File

@ -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.')

View File

@ -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):

View File

@ -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

View File

@ -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? */

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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},

View File

@ -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;

View File

@ -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]*/

View File

@ -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]*/

View File

@ -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]*/

View File

@ -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]*/

View File

@ -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]*/

View File

@ -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]*/

View File

@ -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;

View File

@ -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;

View File

@ -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 *

View File

@ -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;

View File

@ -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 *

View File

@ -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;
}
return NULL;
}
static const char *
skip_eols(const char *trace)
_PyType_DocWithoutSignature(const char *name, const char *internal_doc)
{
while (*trace == '\n')
trace++;
return trace;
}
const char *doc = find_signature(name, internal_doc);
static const char *
_PyType_DocWithoutSignature(const char *internal_doc)
{
const char *signature = find_signature(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}
};

View File

@ -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;

View File

@ -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;

View File

@ -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('*,')
p_add, p_output = text_accumulator()
p_add(fix_right_bracket_count(p.right_bracket_count))
if isinstance(p.converter, self_converter):
# 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)
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)
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

View File

@ -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