-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
gh-100357: Convert several functions in bltinsmodule
to AC
#100358
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Convert ``vars``, ``dir``, ``next``, ``getattr``, and ``iter`` to argument | ||
clinic. |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -837,31 +837,33 @@ builtin_compile_impl(PyObject *module, PyObject *source, PyObject *filename, | |||||
return result; | ||||||
} | ||||||
|
||||||
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | ||||||
/*[clinic input] | ||||||
dir as builtin_dir | ||||||
|
||||||
arg: object = NULL | ||||||
/ | ||||||
|
||||||
Show attributes of an object. | ||||||
|
||||||
If called without an argument, return the names in the current scope. | ||||||
Else, return an alphabetized list of names comprising (some of) the attributes | ||||||
of the given object, and of attributes reachable from it. | ||||||
If the object supplies a method named __dir__, it will be used; otherwise | ||||||
the default dir() logic is used and returns: | ||||||
for a module object: the module's attributes. | ||||||
for a class object: its attributes, and recursively the attributes | ||||||
of its bases. | ||||||
for any other object: its attributes, its class's attributes, and | ||||||
recursively the attributes of its class's base classes. | ||||||
[clinic start generated code]*/ | ||||||
|
||||||
static PyObject * | ||||||
builtin_dir(PyObject *self, PyObject *args) | ||||||
builtin_dir_impl(PyObject *module, PyObject *arg) | ||||||
/*[clinic end generated code: output=24f2c7a52c1e3b08 input=ed6d6ccb13d52251]*/ | ||||||
{ | ||||||
PyObject *arg = NULL; | ||||||
|
||||||
if (!PyArg_UnpackTuple(args, "dir", 0, 1, &arg)) | ||||||
return NULL; | ||||||
return PyObject_Dir(arg); | ||||||
} | ||||||
|
||||||
PyDoc_STRVAR(dir_doc, | ||||||
"dir([object]) -> list of strings\n" | ||||||
"\n" | ||||||
"If called without an argument, return the names in the current scope.\n" | ||||||
"Else, return an alphabetized list of names comprising (some of) the attributes\n" | ||||||
"of the given object, and of attributes reachable from it.\n" | ||||||
"If the object supplies a method named __dir__, it will be used; otherwise\n" | ||||||
"the default dir() logic is used and returns:\n" | ||||||
" for a module object: the module's attributes.\n" | ||||||
" for a class object: its attributes, and recursively the attributes\n" | ||||||
" of its bases.\n" | ||||||
" for any other object: its attributes, its class's attributes, and\n" | ||||||
" recursively the attributes of its class's base classes."); | ||||||
|
||||||
/*[clinic input] | ||||||
divmod as builtin_divmod | ||||||
|
||||||
|
@@ -1109,20 +1111,30 @@ builtin_exec_impl(PyObject *module, PyObject *source, PyObject *globals, | |||||
} | ||||||
|
||||||
|
||||||
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | ||||||
/*[clinic input] | ||||||
getattr as builtin_getattr | ||||||
|
||||||
v: object | ||||||
name: object | ||||||
dflt: object = NULL | ||||||
/ | ||||||
|
||||||
Get a named attribute from an object. | ||||||
|
||||||
getattr(x, 'y') is equivalent to x.y | ||||||
When a default argument is given, it is returned when the attribute doesn't | ||||||
exist; without it, an exception is raised in that case. | ||||||
[clinic start generated code]*/ | ||||||
|
||||||
static PyObject * | ||||||
builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | ||||||
builtin_getattr_impl(PyObject *module, PyObject *v, PyObject *name, | ||||||
PyObject *dflt) | ||||||
/*[clinic end generated code: output=dd719f3bee023bc8 input=c89dfe401b53e36c]*/ | ||||||
{ | ||||||
PyObject *v, *name, *result; | ||||||
|
||||||
if (!_PyArg_CheckPositional("getattr", nargs, 2, 3)) | ||||||
return NULL; | ||||||
PyObject *result; | ||||||
|
||||||
v = args[0]; | ||||||
name = args[1]; | ||||||
if (nargs > 2) { | ||||||
if (dflt != NULL) { | ||||||
if (_PyObject_LookupAttr(v, name, &result) == 0) { | ||||||
PyObject *dflt = args[2]; | ||||||
return Py_NewRef(dflt); | ||||||
} | ||||||
} | ||||||
|
@@ -1132,13 +1144,6 @@ builtin_getattr(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | |||||
return result; | ||||||
} | ||||||
|
||||||
PyDoc_STRVAR(getattr_doc, | ||||||
"getattr(object, name[, default]) -> value\n\ | ||||||
\n\ | ||||||
Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.\n\ | ||||||
When a default argument is given, it is returned when the attribute doesn't\n\ | ||||||
exist; without it, an exception is raised in that case."); | ||||||
|
||||||
|
||||||
/*[clinic input] | ||||||
globals as builtin_globals | ||||||
|
@@ -1450,16 +1455,25 @@ PyTypeObject PyMap_Type = { | |||||
}; | ||||||
|
||||||
|
||||||
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | ||||||
/*[clinic input] | ||||||
next as builtin_next | ||||||
|
||||||
it: object | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
default: object = NULL | ||||||
/ | ||||||
|
||||||
Return the next item from the iterator. | ||||||
|
||||||
If default is given and the iterator is exhausted, | ||||||
it is returned instead of raising StopIteration. | ||||||
[clinic start generated code]*/ | ||||||
|
||||||
static PyObject * | ||||||
builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | ||||||
builtin_next_impl(PyObject *module, PyObject *it, PyObject *default_value) | ||||||
/*[clinic end generated code: output=46a69959fd15f36c input=812f1b6154c81014]*/ | ||||||
{ | ||||||
PyObject *it, *res; | ||||||
|
||||||
if (!_PyArg_CheckPositional("next", nargs, 1, 2)) | ||||||
return NULL; | ||||||
PyObject *res; | ||||||
|
||||||
it = args[0]; | ||||||
if (!PyIter_Check(it)) { | ||||||
PyErr_Format(PyExc_TypeError, | ||||||
"'%.200s' object is not an iterator", | ||||||
|
@@ -1470,14 +1484,13 @@ builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | |||||
res = (*Py_TYPE(it)->tp_iternext)(it); | ||||||
if (res != NULL) { | ||||||
return res; | ||||||
} else if (nargs > 1) { | ||||||
PyObject *def = args[1]; | ||||||
} else if (default_value != NULL) { | ||||||
if (PyErr_Occurred()) { | ||||||
if(!PyErr_ExceptionMatches(PyExc_StopIteration)) | ||||||
return NULL; | ||||||
PyErr_Clear(); | ||||||
} | ||||||
return Py_NewRef(def); | ||||||
return Py_NewRef(default_value); | ||||||
} else if (PyErr_Occurred()) { | ||||||
return NULL; | ||||||
} else { | ||||||
|
@@ -1486,12 +1499,6 @@ builtin_next(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | |||||
} | ||||||
} | ||||||
|
||||||
PyDoc_STRVAR(next_doc, | ||||||
"next(iterator[, default])\n\ | ||||||
\n\ | ||||||
Return the next item from the iterator. If default is given and the iterator\n\ | ||||||
is exhausted, it is returned instead of raising StopIteration."); | ||||||
|
||||||
|
||||||
/*[clinic input] | ||||||
setattr as builtin_setattr | ||||||
|
@@ -1584,34 +1591,33 @@ builtin_hex(PyObject *module, PyObject *number) | |||||
} | ||||||
|
||||||
|
||||||
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | ||||||
/*[clinic input] | ||||||
iter as builtin_iter | ||||||
|
||||||
v: object | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a fan of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the docs it is
|
||||||
sentinel: object = NULL | ||||||
/ | ||||||
|
||||||
Get an iterator from an object. | ||||||
|
||||||
In the first form, the argument must supply its own iterator, or be a sequence. | ||||||
In the second form, the callable is called until it returns the sentinel. | ||||||
[clinic start generated code]*/ | ||||||
|
||||||
static PyObject * | ||||||
builtin_iter(PyObject *self, PyObject *const *args, Py_ssize_t nargs) | ||||||
builtin_iter_impl(PyObject *module, PyObject *v, PyObject *sentinel) | ||||||
/*[clinic end generated code: output=e44e927b4b674002 input=7ae9b0166003fe37]*/ | ||||||
{ | ||||||
PyObject *v; | ||||||
|
||||||
if (!_PyArg_CheckPositional("iter", nargs, 1, 2)) | ||||||
return NULL; | ||||||
v = args[0]; | ||||||
if (nargs == 1) | ||||||
if (sentinel == NULL) | ||||||
return PyObject_GetIter(v); | ||||||
if (!PyCallable_Check(v)) { | ||||||
PyErr_SetString(PyExc_TypeError, | ||||||
"iter(v, w): v must be callable"); | ||||||
return NULL; | ||||||
} | ||||||
PyObject *sentinel = args[1]; | ||||||
return PyCallIter_New(v, sentinel); | ||||||
} | ||||||
|
||||||
PyDoc_STRVAR(iter_doc, | ||||||
"iter(iterable) -> iterator\n\ | ||||||
iter(callable, sentinel) -> iterator\n\ | ||||||
\n\ | ||||||
Get an iterator from an object. In the first form, the argument must\n\ | ||||||
supply its own iterator, or be a sequence.\n\ | ||||||
In the second form, the callable is called until it returns the sentinel."); | ||||||
|
||||||
|
||||||
/*[clinic input] | ||||||
aiter as builtin_aiter | ||||||
|
@@ -2390,15 +2396,24 @@ builtin_sorted(PyObject *self, PyObject *const *args, Py_ssize_t nargs, PyObject | |||||
} | ||||||
|
||||||
|
||||||
/* AC: cannot convert yet, as needs PEP 457 group support in inspect */ | ||||||
/*[clinic input] | ||||||
vars as builtin_vars | ||||||
|
||||||
v: object = NULL | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Or maybe |
||||||
/ | ||||||
|
||||||
Show vars. | ||||||
|
||||||
Without arguments, equivalent to locals(). | ||||||
With an argument, equivalent to object.__dict__. | ||||||
[clinic start generated code]*/ | ||||||
|
||||||
static PyObject * | ||||||
builtin_vars(PyObject *self, PyObject *args) | ||||||
builtin_vars_impl(PyObject *module, PyObject *v) | ||||||
/*[clinic end generated code: output=a64017e4a4dc53fc input=4a426fb03c9b2781]*/ | ||||||
{ | ||||||
PyObject *v = NULL; | ||||||
PyObject *d; | ||||||
|
||||||
if (!PyArg_UnpackTuple(args, "vars", 0, 1, &v)) | ||||||
return NULL; | ||||||
if (v == NULL) { | ||||||
d = Py_XNewRef(PyEval_GetLocals()); | ||||||
} | ||||||
|
@@ -2411,12 +2426,6 @@ builtin_vars(PyObject *self, PyObject *args) | |||||
return d; | ||||||
} | ||||||
|
||||||
PyDoc_STRVAR(vars_doc, | ||||||
"vars([object]) -> dictionary\n\ | ||||||
\n\ | ||||||
Without arguments, equivalent to locals().\n\ | ||||||
With an argument, equivalent to object.__dict__."); | ||||||
|
||||||
|
||||||
/*[clinic input] | ||||||
sum as builtin_sum | ||||||
|
@@ -2947,12 +2956,12 @@ static PyMethodDef builtin_methods[] = { | |||||
BUILTIN_CHR_METHODDEF | ||||||
BUILTIN_COMPILE_METHODDEF | ||||||
BUILTIN_DELATTR_METHODDEF | ||||||
{"dir", builtin_dir, METH_VARARGS, dir_doc}, | ||||||
BUILTIN_DIR_METHODDEF | ||||||
BUILTIN_DIVMOD_METHODDEF | ||||||
BUILTIN_EVAL_METHODDEF | ||||||
BUILTIN_EXEC_METHODDEF | ||||||
BUILTIN_FORMAT_METHODDEF | ||||||
{"getattr", _PyCFunction_CAST(builtin_getattr), METH_FASTCALL, getattr_doc}, | ||||||
BUILTIN_GETATTR_METHODDEF | ||||||
BUILTIN_GLOBALS_METHODDEF | ||||||
BUILTIN_HASATTR_METHODDEF | ||||||
BUILTIN_HASH_METHODDEF | ||||||
|
@@ -2961,13 +2970,13 @@ static PyMethodDef builtin_methods[] = { | |||||
BUILTIN_INPUT_METHODDEF | ||||||
BUILTIN_ISINSTANCE_METHODDEF | ||||||
BUILTIN_ISSUBCLASS_METHODDEF | ||||||
{"iter", _PyCFunction_CAST(builtin_iter), METH_FASTCALL, iter_doc}, | ||||||
BUILTIN_ITER_METHODDEF | ||||||
BUILTIN_AITER_METHODDEF | ||||||
BUILTIN_LEN_METHODDEF | ||||||
BUILTIN_LOCALS_METHODDEF | ||||||
{"max", _PyCFunction_CAST(builtin_max), METH_VARARGS | METH_KEYWORDS, max_doc}, | ||||||
{"min", _PyCFunction_CAST(builtin_min), METH_VARARGS | METH_KEYWORDS, min_doc}, | ||||||
{"next", _PyCFunction_CAST(builtin_next), METH_FASTCALL, next_doc}, | ||||||
BUILTIN_NEXT_METHODDEF | ||||||
BUILTIN_ANEXT_METHODDEF | ||||||
BUILTIN_OCT_METHODDEF | ||||||
BUILTIN_ORD_METHODDEF | ||||||
|
@@ -2978,7 +2987,7 @@ static PyMethodDef builtin_methods[] = { | |||||
BUILTIN_SETATTR_METHODDEF | ||||||
BUILTIN_SORTED_METHODDEF | ||||||
BUILTIN_SUM_METHODDEF | ||||||
{"vars", builtin_vars, METH_VARARGS, vars_doc}, | ||||||
BUILTIN_VARS_METHODDEF | ||||||
{NULL, NULL}, | ||||||
}; | ||||||
|
||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I feel like we should use the param names used in the old docstring and in the docs (https://docs.python.org/3.10/library/functions.html#getattr): object, name, default.
v
is meaningless. If there's a technical problem with usingobject
, let's useobj
instead.