Skip to content

Commit bdfb694

Browse files
authored
gh-100357: Convert several functions in bltinsmodule to AC (#100358)
1 parent 0769f95 commit bdfb694

File tree

3 files changed

+305
-99
lines changed

3 files changed

+305
-99
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Convert ``vars``, ``dir``, ``next``, ``getattr``, and ``iter`` to argument
2+
clinic.

Python/bltinmodule.c

+108-98
Original file line numberDiff line numberDiff line change
@@ -837,31 +837,33 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename,
837837
return result;
838838
}
839839

840-
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
840+
/*[clinic input]
841+
dir as builtin_dir
842+
843+
arg: object = NULL
844+
/
845+
846+
Show attributes of an object.
847+
848+
If called without an argument, return the names in the current scope.
849+
Else, return an alphabetized list of names comprising (some of) the attributes
850+
of the given object, and of attributes reachable from it.
851+
If the object supplies a method named __dir__, it will be used; otherwise
852+
the default dir() logic is used and returns:
853+
for a module object: the module's attributes.
854+
for a class object: its attributes, and recursively the attributes
855+
of its bases.
856+
for any other object: its attributes, its class's attributes, and
857+
recursively the attributes of its class's base classes.
858+
[clinic start generated code]*/
859+
841860
static PyObject *
842-
builtin_dir(PyObject *self, PyObject *args)
861+
builtin_dir_impl(PyObject *module, PyObject *arg)
862+
/*[clinic end generated code: output=24f2c7a52c1e3b08 input=ed6d6ccb13d52251]*/
843863
{
844-
PyObject *arg = NULL;
845-
846-
if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg))
847-
return NULL;
848864
return PyObject_Dir(arg);
849865
}
850866

851-
PyDoc_STRVAR(dir_doc,
852-
"dir([object]) -> list of strings\n"
853-
"\n"
854-
"If called without an argument, return the names in the current scope.\n"
855-
"Else, return an alphabetized list of names comprising (some of) the attributes\n"
856-
"of the given object, and of attributes reachable from it.\n"
857-
"If the object supplies a method named __dir__, it will be used; otherwise\n"
858-
"the default dir() logic is used and returns:\n"
859-
" for a module object: the module's attributes.\n"
860-
" for a class object: its attributes, and recursively the attributes\n"
861-
" of its bases.\n"
862-
" for any other object: its attributes, its class's attributes, and\n"
863-
" recursively the attributes of its class's base classes.");
864-
865867
/*[clinic input]
866868
divmod as builtin_divmod
867869
@@ -1109,36 +1111,39 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals,
11091111
}
11101112

11111113

1112-
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
1114+
/*[clinic input]
1115+
getattr as builtin_getattr
1116+
1117+
object: object
1118+
name: object
1119+
default: object = NULL
1120+
/
1121+
1122+
Get a named attribute from an object.
1123+
1124+
getattr(x, 'y') is equivalent to x.y
1125+
When a default argument is given, it is returned when the attribute doesn't
1126+
exist; without it, an exception is raised in that case.
1127+
[clinic start generated code]*/
1128+
11131129
static PyObject *
1114-
builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1130+
builtin_getattr_impl(PyObject *module, PyObject *object, PyObject *name,
1131+
PyObject *default_value)
1132+
/*[clinic end generated code: output=74ad0e225e3f701c input=d7562cd4c3556171]*/
11151133
{
1116-
PyObject *v, *name, *result;
1117-
1118-
if (!_PyArg_CheckPositional("getattr", nargs, 2, 3))
1119-
return NULL;
1134+
PyObject *result;
11201135

1121-
v = args[0];
1122-
name = args[1];
1123-
if (nargs > 2) {
1124-
if (_PyObject_LookupAttr(v, name, &result) == 0) {
1125-
PyObject *dflt = args[2];
1126-
return Py_NewRef(dflt);
1136+
if (default_value != NULL) {
1137+
if (_PyObject_LookupAttr(object, name, &result) == 0) {
1138+
return Py_NewRef(default_value);
11271139
}
11281140
}
11291141
else {
1130-
result = PyObject_GetAttr(v, name);
1142+
result = PyObject_GetAttr(object, name);
11311143
}
11321144
return result;
11331145
}
11341146

1135-
PyDoc_STRVAR(getattr_doc,
1136-
"getattr(object, name[, default]) -> value\n\
1137-
\n\
1138-
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\
1139-
When a default argument is given, it is returned when the attribute doesn't\n\
1140-
exist; without it, an exception is raised in that case.");
1141-
11421147

11431148
/*[clinic input]
11441149
globals as builtin_globals
@@ -1450,34 +1455,43 @@ PyTypeObject PyMap_Type = {
14501455
};
14511456

14521457

1453-
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
1458+
/*[clinic input]
1459+
next as builtin_next
1460+
1461+
iterator: object
1462+
default: object = NULL
1463+
/
1464+
1465+
Return the next item from the iterator.
1466+
1467+
If default is given and the iterator is exhausted,
1468+
it is returned instead of raising StopIteration.
1469+
[clinic start generated code]*/
1470+
14541471
static PyObject *
1455-
builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1472+
builtin_next_impl(PyObject *module, PyObject *iterator,
1473+
PyObject *default_value)
1474+
/*[clinic end generated code: output=a38a94eeb447fef9 input=180f9984f182020f]*/
14561475
{
1457-
PyObject *it, *res;
1458-
1459-
if (!_PyArg_CheckPositional("next", nargs, 1, 2))
1460-
return NULL;
1476+
PyObject *res;
14611477

1462-
it = args[0];
1463-
if (!PyIter_Check(it)) {
1478+
if (!PyIter_Check(iterator)) {
14641479
PyErr_Format(PyExc_TypeError,
14651480
"'%.200s' object is not an iterator",
1466-
Py_TYPE(it)->tp_name);
1481+
Py_TYPE(iterator)->tp_name);
14671482
return NULL;
14681483
}
14691484

1470-
res = (*Py_TYPE(it)->tp_iternext)(it);
1485+
res = (*Py_TYPE(iterator)->tp_iternext)(iterator);
14711486
if (res != NULL) {
14721487
return res;
1473-
} else if (nargs > 1) {
1474-
PyObject *def = args[1];
1488+
} else if (default_value != NULL) {
14751489
if (PyErr_Occurred()) {
14761490
if(!PyErr_ExceptionMatches(PyExc_StopIteration))
14771491
return NULL;
14781492
PyErr_Clear();
14791493
}
1480-
return Py_NewRef(def);
1494+
return Py_NewRef(default_value);
14811495
} else if (PyErr_Occurred()) {
14821496
return NULL;
14831497
} else {
@@ -1486,12 +1500,6 @@ builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
14861500
}
14871501
}
14881502

1489-
PyDoc_STRVAR(next_doc,
1490-
"next(iterator[, default])\n\
1491-
\n\
1492-
Return the next item from the iterator. If default is given and the iterator\n\
1493-
is exhausted, it is returned instead of raising StopIteration.");
1494-
14951503

14961504
/*[clinic input]
14971505
setattr as builtin_setattr
@@ -1584,34 +1592,33 @@ builtin_hex(PyObject *module, PyObject *number)
15841592
}
15851593

15861594

1587-
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
1595+
/*[clinic input]
1596+
iter as builtin_iter
1597+
1598+
object: object
1599+
sentinel: object = NULL
1600+
/
1601+
1602+
Get an iterator from an object.
1603+
1604+
In the first form, the argument must supply its own iterator, or be a sequence.
1605+
In the second form, the callable is called until it returns the sentinel.
1606+
[clinic start generated code]*/
1607+
15881608
static PyObject *
1589-
builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs)
1609+
builtin_iter_impl(PyObject *module, PyObject *object, PyObject *sentinel)
1610+
/*[clinic end generated code: output=12cf64203c195a94 input=a5d64d9d81880ba6]*/
15901611
{
1591-
PyObject *v;
1592-
1593-
if (!_PyArg_CheckPositional("iter", nargs, 1, 2))
1594-
return NULL;
1595-
v = args[0];
1596-
if (nargs == 1)
1597-
return PyObject_GetIter(v);
1598-
if (!PyCallable_Check(v)) {
1612+
if (sentinel == NULL)
1613+
return PyObject_GetIter(object);
1614+
if (!PyCallable_Check(object)) {
15991615
PyErr_SetString(PyExc_TypeError,
1600-
"iter(v, w): v must be callable");
1616+
"iter(object, sentinel): object must be callable");
16011617
return NULL;
16021618
}
1603-
PyObject *sentinel = args[1];
1604-
return PyCallIter_New(v, sentinel);
1619+
return PyCallIter_New(object, sentinel);
16051620
}
16061621

1607-
PyDoc_STRVAR(iter_doc,
1608-
"iter(iterable) -> iterator\n\
1609-
iter(callable, sentinel) -> iterator\n\
1610-
\n\
1611-
Get an iterator from an object. In the first form, the argument must\n\
1612-
supply its own iterator, or be a sequence.\n\
1613-
In the second form, the callable is called until it returns the sentinel.");
1614-
16151622

16161623
/*[clinic input]
16171624
aiter as builtin_aiter
@@ -2390,33 +2397,36 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject
23902397
}
23912398

23922399

2393-
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */
2400+
/*[clinic input]
2401+
vars as builtin_vars
2402+
2403+
object: object = NULL
2404+
/
2405+
2406+
Show vars.
2407+
2408+
Without arguments, equivalent to locals().
2409+
With an argument, equivalent to object.__dict__.
2410+
[clinic start generated code]*/
2411+
23942412
static PyObject *
2395-
builtin_vars(PyObject *self, PyObject *args)
2413+
builtin_vars_impl(PyObject *module, PyObject *object)
2414+
/*[clinic end generated code: output=840a7f64007a3e0a input=80cbdef9182c4ba3]*/
23962415
{
2397-
PyObject *v = NULL;
23982416
PyObject *d;
23992417

2400-
if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v))
2401-
return NULL;
2402-
if (v == NULL) {
2418+
if (object == NULL) {
24032419
d = Py_XNewRef(PyEval_GetLocals());
24042420
}
24052421
else {
2406-
if (_PyObject_LookupAttr(v, &_Py_ID(__dict__), &d) == 0) {
2422+
if (_PyObject_LookupAttr(object, &_Py_ID(__dict__), &d) == 0) {
24072423
PyErr_SetString(PyExc_TypeError,
24082424
"vars() argument must have __dict__ attribute");
24092425
}
24102426
}
24112427
return d;
24122428
}
24132429

2414-
PyDoc_STRVAR(vars_doc,
2415-
"vars([object]) -> dictionary\n\
2416-
\n\
2417-
Without arguments, equivalent to locals().\n\
2418-
With an argument, equivalent to object.__dict__.");
2419-
24202430

24212431
/*[clinic input]
24222432
sum as builtin_sum
@@ -2966,12 +2976,12 @@ static PyMethodDef builtin_methods[] = {
29662976
BUILTIN_CHR_METHODDEF
29672977
BUILTIN_COMPILE_METHODDEF
29682978
BUILTIN_DELATTR_METHODDEF
2969-
{"dir", builtin_dir, METH_VARARGS, dir_doc},
2979+
BUILTIN_DIR_METHODDEF
29702980
BUILTIN_DIVMOD_METHODDEF
29712981
BUILTIN_EVAL_METHODDEF
29722982
BUILTIN_EXEC_METHODDEF
29732983
BUILTIN_FORMAT_METHODDEF
2974-
{"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, getattr_doc},
2984+
BUILTIN_GETATTR_METHODDEF
29752985
BUILTIN_GLOBALS_METHODDEF
29762986
BUILTIN_HASATTR_METHODDEF
29772987
BUILTIN_HASH_METHODDEF
@@ -2980,13 +2990,13 @@ static PyMethodDef builtin_methods[] = {
29802990
BUILTIN_INPUT_METHODDEF
29812991
BUILTIN_ISINSTANCE_METHODDEF
29822992
BUILTIN_ISSUBCLASS_METHODDEF
2983-
{"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, iter_doc},
2993+
BUILTIN_ITER_METHODDEF
29842994
BUILTIN_AITER_METHODDEF
29852995
BUILTIN_LEN_METHODDEF
29862996
BUILTIN_LOCALS_METHODDEF
29872997
{"max", _PyCFunction_CAST(builtin_max), METH_VARARGS | METH_KEYWORDS, max_doc},
29882998
{"min", _PyCFunction_CAST(builtin_min), METH_VARARGS | METH_KEYWORDS, min_doc},
2989-
{"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, next_doc},
2999+
BUILTIN_NEXT_METHODDEF
29903000
BUILTIN_ANEXT_METHODDEF
29913001
BUILTIN_OCT_METHODDEF
29923002
BUILTIN_ORD_METHODDEF
@@ -2997,7 +3007,7 @@ static PyMethodDef builtin_methods[] = {
29973007
BUILTIN_SETATTR_METHODDEF
29983008
BUILTIN_SORTED_METHODDEF
29993009
BUILTIN_SUM_METHODDEF
3000-
{"vars", builtin_vars, METH_VARARGS, vars_doc},
3010+
BUILTIN_VARS_METHODDEF
30013011
{NULL, NULL},
30023012
};
30033013

0 commit comments

Comments
 (0)