gh-111999: Add signatures and improve docstrings for builtins (GH-112000)

This commit is contained in:
Serhiy Storchaka 2023-11-13 09:13:49 +02:00 committed by GitHub
parent d0058cbd1c
commit 1d75ef6b61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 74 additions and 39 deletions

View File

@ -4734,12 +4734,13 @@ class TestSignatureDefinitions(unittest.TestCase):
needs_null = {"anext"} needs_null = {"anext"}
no_signature |= needs_null no_signature |= needs_null
# These need *args support in Argument Clinic # These need *args support in Argument Clinic
needs_varargs = {"breakpoint", "min", "max", "__build_class__"} needs_varargs = {"min", "max", "__build_class__"}
no_signature |= needs_varargs no_signature |= needs_varargs
# These builtin types are expected to provide introspection info # These builtin types are expected to provide introspection info
types_with_signatures = { types_with_signatures = {
'complex', 'enumerate', 'float', 'list', 'memoryview', 'object', 'bool', 'classmethod', 'complex', 'enumerate', 'filter', 'float',
'property', 'reversed', 'tuple', 'frozenset', 'list', 'map', 'memoryview', 'object', 'property',
'reversed', 'set', 'staticmethod', 'tuple', 'zip'
} }
# Check the signatures we expect to be there # Check the signatures we expect to be there
ns = vars(builtins) ns = vars(builtins)
@ -4753,6 +4754,10 @@ class TestSignatureDefinitions(unittest.TestCase):
if (name in no_signature): if (name in no_signature):
# Not yet converted # Not yet converted
continue continue
if name in {'classmethod', 'staticmethod'}:
# Bug gh-112006: inspect.unwrap() does not work with types
# with the __wrapped__ data descriptor.
continue
with self.subTest(builtin=name): with self.subTest(builtin=name):
self.assertIsNotNone(inspect.signature(obj)) self.assertIsNotNone(inspect.signature(obj))
# Check callables that haven't been converted don't claim a signature # Check callables that haven't been converted don't claim a signature

View File

@ -110,9 +110,10 @@ bool_xor(PyObject *a, PyObject *b)
/* Doc string */ /* Doc string */
PyDoc_STRVAR(bool_doc, PyDoc_STRVAR(bool_doc,
"bool(x) -> bool\n\ "bool(object=False, /)\n\
--\n\
\n\ \n\
Returns True when the argument x is true, False otherwise.\n\ Returns True when the argument is true, False otherwise.\n\
The builtins True and False are the only two instances of the class bool.\n\ The builtins True and False are the only two instances of the class bool.\n\
The class bool is a subclass of the class int, and cannot be subclassed."); The class bool is a subclass of the class int, and cannot be subclassed.");

View File

@ -1541,6 +1541,9 @@ property_deleter(PyObject *self, PyObject *deleter)
PyDoc_STRVAR(set_name_doc, PyDoc_STRVAR(set_name_doc,
"__set_name__($self, owner, name, /)\n"
"--\n"
"\n"
"Method to set name of a property."); "Method to set name of a property.");
static PyObject * static PyObject *

View File

@ -1164,7 +1164,8 @@ cm_repr(classmethod *cm)
} }
PyDoc_STRVAR(classmethod_doc, PyDoc_STRVAR(classmethod_doc,
"classmethod(function) -> method\n\ "classmethod(function, /)\n\
--\n\
\n\ \n\
Convert a function to be a class method.\n\ Convert a function to be a class method.\n\
\n\ \n\
@ -1359,7 +1360,8 @@ sm_repr(staticmethod *sm)
} }
PyDoc_STRVAR(staticmethod_doc, PyDoc_STRVAR(staticmethod_doc,
"staticmethod(function) -> method\n\ "staticmethod(function, /)\n\
--\n\
\n\ \n\
Convert a function to be a static method.\n\ Convert a function to be a static method.\n\
\n\ \n\

View File

@ -942,7 +942,10 @@ set_update(PySetObject *so, PyObject *args)
} }
PyDoc_STRVAR(update_doc, PyDoc_STRVAR(update_doc,
"Update a set with the union of itself and others."); "update($self, /, *others)\n\
--\n\
\n\
Update the set, adding elements from all others.");
/* XXX Todo: /* XXX Todo:
If aligned memory allocations become available, make the If aligned memory allocations become available, make the
@ -1141,9 +1144,10 @@ set_union(PySetObject *so, PyObject *args)
} }
PyDoc_STRVAR(union_doc, PyDoc_STRVAR(union_doc,
"Return the union of sets as a new set.\n\ "union($self, /, *others)\n\
--\n\
\n\ \n\
(i.e. all elements that are in either set.)"); Return a new set with elements from the set and all others.");
static PyObject * static PyObject *
set_or(PySetObject *so, PyObject *other) set_or(PySetObject *so, PyObject *other)
@ -1281,9 +1285,10 @@ set_intersection_multi(PySetObject *so, PyObject *args)
} }
PyDoc_STRVAR(intersection_doc, PyDoc_STRVAR(intersection_doc,
"Return the intersection of two sets as a new set.\n\ "intersection($self, /, *others)\n\
--\n\
\n\ \n\
(i.e. all elements that are in both sets.)"); Return a new set with elements common to the set and all others.");
static PyObject * static PyObject *
set_intersection_update(PySetObject *so, PyObject *other) set_intersection_update(PySetObject *so, PyObject *other)
@ -1312,7 +1317,10 @@ set_intersection_update_multi(PySetObject *so, PyObject *args)
} }
PyDoc_STRVAR(intersection_update_doc, PyDoc_STRVAR(intersection_update_doc,
"Update a set with the intersection of itself and another."); "intersection_update($self, /, *others)\n\
--\n\
\n\
Update the set, keeping only elements found in it and all others.");
static PyObject * static PyObject *
set_and(PySetObject *so, PyObject *other) set_and(PySetObject *so, PyObject *other)
@ -1470,7 +1478,10 @@ set_difference_update(PySetObject *so, PyObject *args)
} }
PyDoc_STRVAR(difference_update_doc, PyDoc_STRVAR(difference_update_doc,
"Remove all elements of another set from this set."); "difference_update($self, /, *others)\n\
--\n\
\n\
Update the set, removing elements found in others.");
static PyObject * static PyObject *
set_copy_and_difference(PySetObject *so, PyObject *other) set_copy_and_difference(PySetObject *so, PyObject *other)
@ -1587,9 +1598,10 @@ set_difference_multi(PySetObject *so, PyObject *args)
} }
PyDoc_STRVAR(difference_doc, PyDoc_STRVAR(difference_doc,
"Return the difference of two or more sets as a new set.\n\ "difference($self, /, *others)\n\
--\n\
\n\ \n\
(i.e. all elements that are in this set but not the others.)"); Return a new set with elements in the set that are not in the others.");
static PyObject * static PyObject *
set_sub(PySetObject *so, PyObject *other) set_sub(PySetObject *so, PyObject *other)
{ {
@ -1673,7 +1685,10 @@ set_symmetric_difference_update(PySetObject *so, PyObject *other)
} }
PyDoc_STRVAR(symmetric_difference_update_doc, PyDoc_STRVAR(symmetric_difference_update_doc,
"Update a set with the symmetric difference of itself and another."); "symmetric_difference_update($self, other, /)\n\
--\n\
\n\
Update the set, keeping only elements found in either set, but not in both.");
static PyObject * static PyObject *
set_symmetric_difference(PySetObject *so, PyObject *other) set_symmetric_difference(PySetObject *so, PyObject *other)
@ -1694,9 +1709,10 @@ set_symmetric_difference(PySetObject *so, PyObject *other)
} }
PyDoc_STRVAR(symmetric_difference_doc, PyDoc_STRVAR(symmetric_difference_doc,
"Return the symmetric difference of two sets as a new set.\n\ "symmetric_difference($self, other, /)\n\
--\n\
\n\ \n\
(i.e. all elements that are in exactly one of the sets.)"); Return a new set with elements in either the set or other but not both.");
static PyObject * static PyObject *
set_xor(PySetObject *so, PyObject *other) set_xor(PySetObject *so, PyObject *other)
@ -2100,8 +2116,8 @@ static PyNumberMethods set_as_number = {
}; };
PyDoc_STRVAR(set_doc, PyDoc_STRVAR(set_doc,
"set() -> new empty set object\n\ "set(iterable=(), /)\n\
set(iterable) -> new set object\n\ --\n\
\n\ \n\
Build an unordered collection of unique elements."); Build an unordered collection of unique elements.");
@ -2201,8 +2217,8 @@ static PyNumberMethods frozenset_as_number = {
}; };
PyDoc_STRVAR(frozenset_doc, PyDoc_STRVAR(frozenset_doc,
"frozenset() -> empty frozenset object\n\ "frozenset(iterable=(), /)\n\
frozenset(iterable) -> frozenset object\n\ --\n\
\n\ \n\
Build an immutable unordered collection of unique elements."); Build an immutable unordered collection of unique elements.");

View File

@ -5254,8 +5254,10 @@ static PyMethodDef type_methods[] = {
TYPE___SUBCLASSES___METHODDEF TYPE___SUBCLASSES___METHODDEF
{"__prepare__", _PyCFunction_CAST(type_prepare), {"__prepare__", _PyCFunction_CAST(type_prepare),
METH_FASTCALL | METH_KEYWORDS | METH_CLASS, METH_FASTCALL | METH_KEYWORDS | METH_CLASS,
PyDoc_STR("__prepare__() -> dict\n" PyDoc_STR("__prepare__($cls, name, bases, /, **kwds)\n"
"used to create the namespace for the class statement")}, "--\n"
"\n"
"Create the namespace for the class statement")},
TYPE___INSTANCECHECK___METHODDEF TYPE___INSTANCECHECK___METHODDEF
TYPE___SUBCLASSCHECK___METHODDEF TYPE___SUBCLASSCHECK___METHODDEF
TYPE___DIR___METHODDEF TYPE___DIR___METHODDEF

View File

@ -13390,15 +13390,17 @@ _PyUnicodeWriter_Dealloc(_PyUnicodeWriter *writer)
#include "stringlib/unicode_format.h" #include "stringlib/unicode_format.h"
PyDoc_STRVAR(format__doc__, PyDoc_STRVAR(format__doc__,
"S.format(*args, **kwargs) -> str\n\ "format($self, /, *args, **kwargs)\n\
--\n\
\n\ \n\
Return a formatted version of S, using substitutions from args and kwargs.\n\ Return a formatted version of the string, using substitutions from args and kwargs.\n\
The substitutions are identified by braces ('{' and '}')."); The substitutions are identified by braces ('{' and '}').");
PyDoc_STRVAR(format_map__doc__, PyDoc_STRVAR(format_map__doc__,
"S.format_map(mapping) -> str\n\ "format_map($self, /, mapping)\n\
--\n\
\n\ \n\
Return a formatted version of S, using substitutions from mapping.\n\ Return a formatted version of the string, using substitutions from mapping.\n\
The substitutions are identified by braces ('{' and '}')."); The substitutions are identified by braces ('{' and '}').");
/*[clinic input] /*[clinic input]
@ -14696,7 +14698,7 @@ errors is specified, then the object must expose a data buffer\n\
that will be decoded using the given encoding and error handler.\n\ that will be decoded using the given encoding and error handler.\n\
Otherwise, returns the result of object.__str__() (if defined)\n\ Otherwise, returns the result of object.__str__() (if defined)\n\
or repr(object).\n\ or repr(object).\n\
encoding defaults to sys.getdefaultencoding().\n\ encoding defaults to 'utf-8'.\n\
errors defaults to 'strict'."); errors defaults to 'strict'.");
static PyObject *unicode_iter(PyObject *seq); static PyObject *unicode_iter(PyObject *seq);

View File

@ -482,6 +482,7 @@ builtin_breakpoint(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyOb
PyDoc_STRVAR(breakpoint_doc, PyDoc_STRVAR(breakpoint_doc,
"breakpoint(*args, **kws)\n\ "breakpoint(*args, **kws)\n\
--\n\
\n\ \n\
Call sys.breakpointhook(*args, **kws). sys.breakpointhook() must accept\n\ Call sys.breakpointhook(*args, **kws). sys.breakpointhook() must accept\n\
whatever arguments are passed.\n\ whatever arguments are passed.\n\
@ -626,7 +627,8 @@ static PyMethodDef filter_methods[] = {
}; };
PyDoc_STRVAR(filter_doc, PyDoc_STRVAR(filter_doc,
"filter(function or None, iterable) --> filter object\n\ "filter(function, iterable, /)\n\
--\n\
\n\ \n\
Return an iterator yielding those items of iterable for which function(item)\n\ Return an iterator yielding those items of iterable for which function(item)\n\
is true. If function is None, return the items that are true."); is true. If function is None, return the items that are true.");
@ -1449,7 +1451,8 @@ static PyMethodDef map_methods[] = {
PyDoc_STRVAR(map_doc, PyDoc_STRVAR(map_doc,
"map(func, *iterables) --> map object\n\ "map(function, /, *iterables)\n\
--\n\
\n\ \n\
Make an iterator that computes the function using arguments from\n\ Make an iterator that computes the function using arguments from\n\
each of the iterables. Stops when the shortest iterable is exhausted."); each of the iterables. Stops when the shortest iterable is exhausted.");
@ -1888,7 +1891,7 @@ min(arg1, arg2, *args, *[, key=func]) -> value\n\
With a single iterable argument, return its smallest item. The\n\ With a single iterable argument, return its smallest item. The\n\
default keyword-only argument specifies an object to return if\n\ default keyword-only argument specifies an object to return if\n\
the provided iterable is empty.\n\ the provided iterable is empty.\n\
With two or more arguments, return the smallest argument."); With two or more positional arguments, return the smallest argument.");
/* AC: cannot convert yet, waiting for *args support */ /* AC: cannot convert yet, waiting for *args support */
@ -1905,7 +1908,7 @@ max(arg1, arg2, *args, *[, key=func]) -> value\n\
With a single iterable argument, return its biggest item. The\n\ With a single iterable argument, return its biggest item. The\n\
default keyword-only argument specifies an object to return if\n\ default keyword-only argument specifies an object to return if\n\
the provided iterable is empty.\n\ the provided iterable is empty.\n\
With two or more arguments, return the largest argument."); With two or more positional arguments, return the largest argument.");
/*[clinic input] /*[clinic input]
@ -2958,10 +2961,8 @@ static PyMethodDef zip_methods[] = {
}; };
PyDoc_STRVAR(zip_doc, PyDoc_STRVAR(zip_doc,
"zip(*iterables, strict=False) --> Yield tuples until an input is exhausted.\n\ "zip(*iterables, strict=False)\n\
\n\ --\n\
>>> list(zip('abcdefg', range(3), range(4)))\n\
[('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]\n\
\n\ \n\
The zip object yields n-length tuples, where n is the number of iterables\n\ The zip object yields n-length tuples, where n is the number of iterables\n\
passed as positional arguments to zip(). The i-th element in every tuple\n\ passed as positional arguments to zip(). The i-th element in every tuple\n\
@ -2969,7 +2970,10 @@ comes from the i-th iterable argument to zip(). This continues until the\n\
shortest argument is exhausted.\n\ shortest argument is exhausted.\n\
\n\ \n\
If strict is true and one of the arguments is exhausted before the others,\n\ If strict is true and one of the arguments is exhausted before the others,\n\
raise a ValueError."); raise a ValueError.\n\
\n\
>>> list(zip('abcdefg', range(3), range(4)))\n\
[('a', 0, 0), ('b', 1, 1), ('c', 2, 2)]");
PyTypeObject PyZip_Type = { PyTypeObject PyZip_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0) PyVarObject_HEAD_INIT(&PyType_Type, 0)