Skip to content

Commit

Permalink
pythongh-118851: Default ctx arguments to AST constructors to Load() (p…
Browse files Browse the repository at this point in the history
…ython#118854)

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
  • Loading branch information
JelleZijlstra and AlexWaygood committed May 9, 2024
1 parent 98ff3f6 commit 68fbc00
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 6 deletions.
6 changes: 3 additions & 3 deletions Doc/library/ast.rst
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ Node classes

If a field that is optional in the grammar is omitted from the constructor,
it defaults to ``None``. If a list field is omitted, it defaults to the empty
list. If any other field is omitted, a :exc:`DeprecationWarning` is raised
list. If a field of type :class:`!ast.expr_context` is omitted, it defaults to
:class:`Load() <ast.Load>`. If any other field is omitted, a :exc:`DeprecationWarning` is raised
and the AST node will not have this field. In Python 3.15, this condition will
raise an error.

Expand Down Expand Up @@ -596,8 +597,7 @@ Expressions
* ``keywords`` holds a list of :class:`.keyword` objects representing
arguments passed by keyword.

When creating a ``Call`` node, ``args`` and ``keywords`` are required, but
they can be empty lists.
The ``args`` and ``keywords`` arguments are optional and default to empty lists.

.. doctest::

Expand Down
8 changes: 5 additions & 3 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -521,8 +521,10 @@ ast

If an optional field on an AST node is not included as an argument when
constructing an instance, the field will now be set to ``None``. Similarly,
if a list field is omitted, that field will now be set to an empty list.
(Previously, in both cases, the attribute would be missing on the newly
if a list field is omitted, that field will now be set to an empty list,
and if a :class:`!ast.expr_context` field is omitted, it defaults to
:class:`Load() <ast.Load>`.
(Previously, in all cases, the attribute would be missing on the newly
constructed AST node instance.)

If other arguments are omitted, a :exc:`DeprecationWarning` is emitted.
Expand All @@ -534,7 +536,7 @@ ast
unless the class opts in to the new behavior by setting the attribute
:attr:`ast.AST._field_types`.

(Contributed by Jelle Zijlstra in :gh:`105858` and :gh:`117486`.)
(Contributed by Jelle Zijlstra in :gh:`105858`, :gh:`117486`, and :gh:`118851`.)

* :func:`ast.parse` now accepts an optional argument *optimize*
which is passed on to the :func:`compile` built-in. This makes it
Expand Down
17 changes: 17 additions & 0 deletions Lib/test/test_ast.py
Original file line number Diff line number Diff line change
Expand Up @@ -3036,6 +3036,23 @@ def test_FunctionDef(self):
self.assertEqual(node.name, 'foo')
self.assertEqual(node.decorator_list, [])

def test_expr_context(self):
name = ast.Name("x")
self.assertEqual(name.id, "x")
self.assertIsInstance(name.ctx, ast.Load)

name2 = ast.Name("x", ast.Store())
self.assertEqual(name2.id, "x")
self.assertIsInstance(name2.ctx, ast.Store)

name3 = ast.Name("x", ctx=ast.Del())
self.assertEqual(name3.id, "x")
self.assertIsInstance(name3.ctx, ast.Del)

with self.assertWarnsRegex(DeprecationWarning,
r"Name\.__init__ missing 1 required positional argument: 'id'"):
name3 = ast.Name()

def test_custom_subclass_with_no_fields(self):
class NoInit(ast.AST):
pass
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
``ctx`` arguments to the constructors of :mod:`ast` node classes now default
to :class:`ast.Load() <ast.Load>`. Patch by Jelle Zijlstra.
7 changes: 7 additions & 0 deletions Parser/asdl_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -1022,6 +1022,13 @@ def visitModule(self, mod):
goto set_remaining_cleanup;
}
}
else if (type == state->expr_context_type) {
// special case for expr_context: default to Load()
res = PyObject_SetAttr(self, name, state->Load_singleton);
if (res < 0) {
goto set_remaining_cleanup;
}
}
else {
// simple field (e.g., identifier)
if (PyErr_WarnFormat(
Expand Down
7 changes: 7 additions & 0 deletions Python/Python-ast.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 68fbc00

Please sign in to comment.