[Python-checkins] bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649)
Batuhan Taskaya
webhook-mailer at python.org
Sat Jun 6 08:44:20 EDT 2020
https://github.com/python/cpython/commit/68874a8502da440a1dc4746cf73262648b870aee
commit: 68874a8502da440a1dc4746cf73262648b870aee
branch: master
author: Batuhan Taskaya <isidentical at gmail.com>
committer: GitHub <noreply at github.com>
date: 2020-06-06T05:44:16-07:00
summary:
bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649)
files:
A Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst
M Lib/test/test_ast.py
M Python/ast.c
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index a3b366ec35da1..78e4a5653d4ef 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -668,6 +668,13 @@ def test_issue40614_feature_version(self):
with self.assertRaises(SyntaxError):
ast.parse('f"{x=}"', feature_version=(3, 7))
+ def test_constant_as_name(self):
+ for constant in "True", "False", "None":
+ expr = ast.Expression(ast.Name(constant, ast.Load()))
+ ast.fix_missing_locations(expr)
+ with self.assertRaisesRegex(ValueError, f"Name node can't be used with '{constant}' constant"):
+ compile(expr, "<test>", "eval")
+
class ASTHelpers_Test(unittest.TestCase):
maxDiff = None
diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst
new file mode 100644
index 0000000000000..8e943a29f337f
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst
@@ -0,0 +1,2 @@
+Raise :exc:`ValueError` when validating custom AST's where the constants
+``True``, ``False`` and ``None`` are used within a :class:`ast.Name` node.
diff --git a/Python/ast.c b/Python/ast.c
index c524b8e34e873..408591f32536f 100644
--- a/Python/ast.c
+++ b/Python/ast.c
@@ -21,6 +21,25 @@ static int validate_nonempty_seq(asdl_seq *, const char *, const char *);
static int validate_stmt(stmt_ty);
static int validate_expr(expr_ty, expr_context_ty);
+static int
+validate_name(PyObject *name)
+{
+ assert(PyUnicode_Check(name));
+ static const char * const forbidden[] = {
+ "None",
+ "True",
+ "False",
+ NULL
+ };
+ for (int i = 0; forbidden[i] != NULL; i++) {
+ if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) {
+ PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]);
+ return 0;
+ }
+ }
+ return 1;
+}
+
static int
validate_comprehension(asdl_seq *gens)
{
@@ -173,6 +192,9 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
actual_ctx = exp->v.Starred.ctx;
break;
case Name_kind:
+ if (!validate_name(exp->v.Name.id)) {
+ return 0;
+ }
actual_ctx = exp->v.Name.ctx;
break;
case List_kind:
More information about the Python-checkins
mailing list