mirror of
https://github.com/python/cpython.git
synced 2025-10-17 20:28:43 +00:00
Add ast.Constant
Issue #26146: Add a new kind of AST node: ast.Constant. It can be used by external AST optimizers, but the compiler does not emit directly such node. An optimizer can replace the following AST nodes with ast.Constant: * ast.NameConstant: None, False, True * ast.Num: int, float, complex * ast.Str: str * ast.Bytes: bytes * ast.Tuple if items are constants too: tuple * frozenset Update code to accept ast.Constant instead of ast.Num and/or ast.Str: * compiler * docstrings * ast.literal_eval() * Tools/parser/unparse.py
This commit is contained in:
parent
0dceb91866
commit
f2c1aa1661
14 changed files with 401 additions and 44 deletions
50
Python/ast.c
50
Python/ast.c
|
@ -131,6 +131,50 @@ validate_arguments(arguments_ty args)
|
|||
return validate_exprs(args->defaults, Load, 0) && validate_exprs(args->kw_defaults, Load, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
validate_constant(PyObject *value)
|
||||
{
|
||||
if (value == Py_None || value == Py_Ellipsis)
|
||||
return 1;
|
||||
|
||||
if (PyLong_CheckExact(value)
|
||||
|| PyFloat_CheckExact(value)
|
||||
|| PyComplex_CheckExact(value)
|
||||
|| PyBool_Check(value)
|
||||
|| PyUnicode_CheckExact(value)
|
||||
|| PyBytes_CheckExact(value))
|
||||
return 1;
|
||||
|
||||
if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
|
||||
PyObject *it;
|
||||
|
||||
it = PyObject_GetIter(value);
|
||||
if (it == NULL)
|
||||
return 0;
|
||||
|
||||
while (1) {
|
||||
PyObject *item = PyIter_Next(it);
|
||||
if (item == NULL) {
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(it);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!validate_constant(item)) {
|
||||
Py_DECREF(it);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Py_DECREF(it);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
validate_expr(expr_ty exp, expr_context_ty ctx)
|
||||
{
|
||||
|
@ -240,6 +284,12 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
|
|||
return validate_expr(exp->v.Call.func, Load) &&
|
||||
validate_exprs(exp->v.Call.args, Load, 0) &&
|
||||
validate_keywords(exp->v.Call.keywords);
|
||||
case Constant_kind:
|
||||
if (!validate_constant(exp->v.Constant.value)) {
|
||||
PyErr_SetString(PyExc_TypeError, "invalid type in Constant");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
case Num_kind: {
|
||||
PyObject *n = exp->v.Num.n;
|
||||
if (!PyLong_CheckExact(n) && !PyFloat_CheckExact(n) &&
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue