summaryrefslogtreecommitdiffstats
path: root/Python/ast.c
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2016-01-25 23:40:57 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2016-01-25 23:40:57 (GMT)
commitf2c1aa1661edb3e14ff8b7b9995f93e303c8acbb (patch)
tree2b05f347dd55b86059d70197ce3d21210a668f91 /Python/ast.c
parent0dceb918668399bdcbe27d1c59d01c4c9228c1a6 (diff)
downloadcpython-f2c1aa1661edb3e14ff8b7b9995f93e303c8acbb.zip
cpython-f2c1aa1661edb3e14ff8b7b9995f93e303c8acbb.tar.gz
cpython-f2c1aa1661edb3e14ff8b7b9995f93e303c8acbb.tar.bz2
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
Diffstat (limited to 'Python/ast.c')
-rw-r--r--Python/ast.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/Python/ast.c b/Python/ast.c
index a5d8dba..5422e9c 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -132,6 +132,50 @@ validate_arguments(arguments_ty args)
}
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)
{
int check_ctx = 1;
@@ -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) &&