Skip to content

Commit dc59006

Browse files
gh-155496: Use Argument Clinic for more functions and methods (GH-158134)
Convert to Argument Clinic: * builtins dir() and vars() * property.__set_name__() * memoryview.__exit__() * structseq __replace__() * types.SimpleNamespace.__replace__() * re.Match.group() * sys.getsizeof() and sys.set_asyncgen_hooks() * atexit.register() * os.scandir() iterator __exit__() * _dbm, _gdbm and _decimal context manager __exit__() * _functools lru_cache __copy__() and __deepcopy__() * _elementtree.SubElement() * _interpreters.new_config() * _tkinter call() and wantobjects() * zoneinfo.ZoneInfo.__init_subclass__() * internal hamt and stdprinter methods
1 parent 93142c9 commit dc59006

44 files changed

Lines changed: 1363 additions & 335 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎Include/internal/pycore_global_objects_fini_generated.h‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Include/internal/pycore_global_strings.h‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,7 +500,9 @@ struct _Py_global_strings {
500500
STRUCT_FOR_ID(filter)
501501
STRUCT_FOR_ID(filters)
502502
STRUCT_FOR_ID(final)
503+
STRUCT_FOR_ID(finalizer)
503504
STRUCT_FOR_ID(find_class)
505+
STRUCT_FOR_ID(firstiter)
504506
STRUCT_FOR_ID(fix_imports)
505507
STRUCT_FOR_ID(flags)
506508
STRUCT_FOR_ID(flush)

‎Include/internal/pycore_runtime_init_generated.h‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Include/internal/pycore_unicodeobject_generated.h‎

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Lib/test/test_inspect/test_inspect.py‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6170,11 +6170,10 @@ def test_builtins_have_signatures(self):
61706170
no_signature = {'type', 'super', 'bytearray', 'bytes',
61716171
'dict', 'frozendict', 'int', 'str'}
61726172
# These need PEP 457 groups
6173-
needs_groups = {"range", "slice", "dir", "getattr",
6174-
"next", "vars"}
6173+
needs_groups = {"range", "slice", "getattr", "next"}
61756174
no_signature |= needs_groups
61766175
# These have unrepresentable parameter default values of NULL
6177-
unsupported_signature = {"aiter", "iter"}
6176+
unsupported_signature = {"aiter", "iter", "dir", "vars"}
61786177
# These need *args support in Argument Clinic
61796178
needs_varargs = {"min", "max", "__build_class__"}
61806179
no_signature |= needs_varargs
@@ -6207,10 +6206,12 @@ def test_types_module_has_signatures(self):
62076206
methods_no_signature=methods_no_signature)
62086207

62096208
def test_sys_module_has_signatures(self):
6210-
no_signature = {'getsizeof', 'set_asyncgen_hooks'}
6211-
no_signature |= {name for name in ['getobjects']
6212-
if hasattr(sys, name)}
6213-
self._test_module_has_signatures(sys, no_signature)
6209+
no_signature = {name for name in ['getobjects']
6210+
if hasattr(sys, name)}
6211+
# The C default is NULL and None has other meaning
6212+
unsupported_signature = {'getsizeof', 'set_asyncgen_hooks'}
6213+
self._test_module_has_signatures(sys, no_signature,
6214+
unsupported_signature)
62146215

62156216
def test_abc_module_has_signatures(self):
62166217
import abc
@@ -6313,7 +6314,6 @@ def test_pwd_module_has_signatures(self):
63136314
def test_re_module_has_signatures(self):
63146315
import re
63156316
methods_no_signature = {
6316-
'Match': {'group'},
63176317
'Pattern': {'match'}, # It is now an alias for prefixmatch
63186318
}
63196319
self._test_module_has_signatures(re,

‎Lib/test/test_property.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ def test_property_set_name_incorrect_args(self):
260260
for i in (0, 1, 3):
261261
with self.assertRaisesRegex(
262262
TypeError,
263-
fr'^__set_name__\(\) takes 2 positional arguments but {i} were given$'
263+
fr'^__set_name__ expected 2 arguments?, got {i}$'
264264
):
265265
p.__set_name__(*([0] * i))
266266

‎Modules/_dbmmodule.c‎

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -513,15 +513,21 @@ dbm__enter__(PyObject *self, PyObject *Py_UNUSED(dummy))
513513
return Py_NewRef(self);
514514
}
515515

516+
/*[clinic input]
517+
@critical_section
518+
_dbm.dbm.__exit__
519+
520+
*exc_info: array
521+
522+
Close the database.
523+
[clinic start generated code]*/
524+
516525
static PyObject *
517-
dbm__exit__(PyObject *self, PyObject *Py_UNUSED(args))
526+
_dbm_dbm___exit___impl(dbmobject *self, PyObject * const *exc_info,
527+
Py_ssize_t exc_info_length)
528+
/*[clinic end generated code: output=f9549bf513b3285d input=340d8190b6fb0f15]*/
518529
{
519-
PyObject *result;
520-
dbmobject *dp = dbmobject_CAST(self);
521-
Py_BEGIN_CRITICAL_SECTION(self);
522-
result = _dbm_dbm_close_impl(dp);
523-
Py_END_CRITICAL_SECTION();
524-
return result;
530+
return _dbm_dbm_close_impl(self);
525531
}
526532

527533
static PyMethodDef dbm_methods[] = {
@@ -531,7 +537,7 @@ static PyMethodDef dbm_methods[] = {
531537
_DBM_DBM_SETDEFAULT_METHODDEF
532538
_DBM_DBM_CLEAR_METHODDEF
533539
{"__enter__", dbm__enter__, METH_NOARGS, NULL},
534-
{"__exit__", dbm__exit__, METH_VARARGS, NULL},
540+
_DBM_DBM___EXIT___METHODDEF
535541
{NULL, NULL} /* sentinel */
536542
};
537543

‎Modules/_decimal/_decimal.c‎

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,6 @@
5757
#define _PY_DEC_ROUND_GUARD (MPD_ROUND_GUARD-1)
5858
#endif
5959

60-
#include "clinic/_decimal.c.h"
6160

6261
#define MPD_SPEC_VERSION "1.70" // Highest version of the spec this complies with
6362
// See https://speleotrove.com/decimal/decarith.html
@@ -66,8 +65,9 @@
6665
module _decimal
6766
class _decimal.Decimal "PyObject *" "&dec_spec"
6867
class _decimal.Context "PyObject *" "&context_spec"
68+
class _decimal.ContextManager "PyDecContextManagerObject *" "&ctxmanager_spec"
6969
[clinic start generated code]*/
70-
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=a6a6c0bdf4e576ef]*/
70+
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=52b8c97cabc5bf05]*/
7171

7272
struct PyDecContextObject;
7373
struct DecCondMap;
@@ -234,6 +234,8 @@ typedef struct {
234234
PyObject *global;
235235
} PyDecContextManagerObject;
236236

237+
#include "clinic/_decimal.c.h"
238+
237239
#define _PyDecContextManagerObject_CAST(op) ((PyDecContextManagerObject *)(op))
238240

239241
#undef MPD
@@ -2209,11 +2211,21 @@ ctxmanager_set_local(PyObject *op, PyObject *Py_UNUSED(dummy))
22092211
return Py_NewRef(self->local);
22102212
}
22112213

2214+
/*[clinic input]
2215+
_decimal.ContextManager.__exit__
2216+
2217+
*exc_info: array
2218+
2219+
Restore the global context.
2220+
[clinic start generated code]*/
2221+
22122222
static PyObject *
2213-
ctxmanager_restore_global(PyObject *op, PyObject *Py_UNUSED(args))
2223+
_decimal_ContextManager___exit___impl(PyDecContextManagerObject *self,
2224+
PyObject * const *exc_info,
2225+
Py_ssize_t exc_info_length)
2226+
/*[clinic end generated code: output=744a645b0145842d input=a86ec9080e28dff3]*/
22142227
{
22152228
PyObject *ret;
2216-
PyDecContextManagerObject *self = _PyDecContextManagerObject_CAST(op);
22172229
ret = PyDec_SetCurrentContext(PyType_GetModule(Py_TYPE(self)), self->global);
22182230
if (ret == NULL) {
22192231
return NULL;
@@ -2226,7 +2238,7 @@ ctxmanager_restore_global(PyObject *op, PyObject *Py_UNUSED(args))
22262238

22272239
static PyMethodDef ctxmanager_methods[] = {
22282240
{"__enter__", ctxmanager_set_local, METH_NOARGS, NULL},
2229-
{"__exit__", ctxmanager_restore_global, METH_VARARGS, NULL},
2241+
_DECIMAL_CONTEXTMANAGER___EXIT___METHODDEF
22302242
{NULL, NULL}
22312243
};
22322244

‎Modules/_decimal/clinic/_decimal.c.h‎

Lines changed: 29 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Modules/_elementtree.c‎

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -612,33 +612,41 @@ element_get_tail(ElementObject* self)
612612
return Py_NewRef(res);
613613
}
614614

615-
static PyObject*
616-
subelement(PyObject *self, PyObject *args, PyObject *kwds)
615+
/*[clinic input]
616+
_elementtree.SubElement
617+
618+
parent: object(subclass_of='get_elementtree_state(module)->Element_Type')
619+
tag: object
620+
attrib: object(subclass_of='&PyDict_Type', c_default='NULL') = {}
621+
/
622+
**extra: dict
623+
624+
Create a new subelement of the parent element.
625+
[clinic start generated code]*/
626+
627+
static PyObject *
628+
_elementtree_SubElement_impl(PyObject *module, PyObject *parent,
629+
PyObject *tag, PyObject *attrib,
630+
PyObject *extra)
631+
/*[clinic end generated code: output=42e8a4ebc5db08aa input=8588fc68283cdaa0]*/
617632
{
618633
PyObject* elem;
619634

620-
elementtreestate *st = get_elementtree_state(self);
621-
ElementObject* parent;
622-
PyObject* tag;
623-
PyObject* attrib = NULL;
624-
if (!PyArg_ParseTuple(args, "O!O|O!:SubElement",
625-
st->Element_Type, &parent, &tag,
626-
&PyDict_Type, &attrib)) {
627-
return NULL;
628-
}
635+
elementtreestate *st = get_elementtree_state(module);
636+
ElementObject* parent_elem = (ElementObject *)parent;
629637

630638
if (attrib) {
631639
/* attrib passed as positional arg */
632640
attrib = PyDict_Copy(attrib);
633641
if (!attrib)
634642
return NULL;
635-
if (kwds != NULL && PyDict_Update(attrib, kwds) < 0) {
643+
if (PyDict_Update(attrib, extra) < 0) {
636644
Py_DECREF(attrib);
637645
return NULL;
638646
}
639-
} else if (kwds) {
647+
} else if (PyDict_GET_SIZE(extra)) {
640648
/* have keyword args */
641-
attrib = get_attrib_from_keywords(kwds);
649+
attrib = get_attrib_from_keywords(extra);
642650
if (!attrib)
643651
return NULL;
644652
} else {
@@ -650,7 +658,7 @@ subelement(PyObject *self, PyObject *args, PyObject *kwds)
650658
if (elem == NULL)
651659
return NULL;
652660

653-
if (element_add_subelement(st, parent, elem) < 0) {
661+
if (element_add_subelement(st, parent_elem, elem) < 0) {
654662
Py_DECREF(elem);
655663
return NULL;
656664
}
@@ -4547,7 +4555,7 @@ static PyType_Spec xmlparser_spec = {
45474555
/* python module interface */
45484556

45494557
static PyMethodDef _functions[] = {
4550-
{"SubElement", _PyCFunction_CAST(subelement), METH_VARARGS | METH_KEYWORDS},
4558+
_ELEMENTTREE_SUBELEMENT_METHODDEF
45514559
_ELEMENTTREE__SET_FACTORIES_METHODDEF
45524560
{NULL, NULL}
45534561
};

0 commit comments

Comments
 (0)