https://github.com/python/cpython/commit/68fbc00dc870f6a8dcbecd2ec19298e21015867f
commit: 68fbc00dc870f6a8dcbecd2ec19298e21015867f
branch: main
author: Jelle Zijlstra <[email protected]>
committer: JelleZijlstra <[email protected]>
date: 2024-05-09T15:30:14-07:00
summary:

gh-118851: Default ctx arguments to AST constructors to Load() (#118854)

Co-authored-by: Alex Waygood <[email protected]>

files:
A Misc/NEWS.d/next/Library/2024-05-09-08-46-12.gh-issue-118851.aPAoJw.rst
M Doc/library/ast.rst
M Doc/whatsnew/3.13.rst
M Lib/test/test_ast.py
M Parser/asdl_c.py
M Python/Python-ast.c

diff --git a/Doc/library/ast.rst b/Doc/library/ast.rst
index 24c56f17ebb002..d4ccf282a5d00a 100644
--- a/Doc/library/ast.rst
+++ b/Doc/library/ast.rst
@@ -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.
 
@@ -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::
 
diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst
index 44555718184e19..9dab458b210093 100644
--- a/Doc/whatsnew/3.13.rst
+++ b/Doc/whatsnew/3.13.rst
@@ -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.
@@ -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
diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py
index f6e22d44406d9e..5422c861ffb5c0 100644
--- a/Lib/test/test_ast.py
+++ b/Lib/test/test_ast.py
@@ -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
diff --git 
a/Misc/NEWS.d/next/Library/2024-05-09-08-46-12.gh-issue-118851.aPAoJw.rst 
b/Misc/NEWS.d/next/Library/2024-05-09-08-46-12.gh-issue-118851.aPAoJw.rst
new file mode 100644
index 00000000000000..d036d0cda617ef
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-05-09-08-46-12.gh-issue-118851.aPAoJw.rst
@@ -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.
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index 11d59faeb0d42c..9961d23629abc5 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -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(
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index 4956d04f719de9..7aa1c5119d8f28 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -5221,6 +5221,13 @@ ast_type_init(PyObject *self, PyObject *args, PyObject 
*kw)
                     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(

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: [email protected]

Reply via email to