mirror of https://github.com/python/cpython
gh-118851: Default ctx arguments to AST constructors to Load() (#118854)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
This commit is contained in:
parent
98ff3f65c0
commit
68fbc00dc8
|
@ -120,7 +120,8 @@ Node classes
|
||||||
|
|
||||||
If a field that is optional in the grammar is omitted from the constructor,
|
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
|
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
|
and the AST node will not have this field. In Python 3.15, this condition will
|
||||||
raise an error.
|
raise an error.
|
||||||
|
|
||||||
|
@ -596,8 +597,7 @@ Expressions
|
||||||
* ``keywords`` holds a list of :class:`.keyword` objects representing
|
* ``keywords`` holds a list of :class:`.keyword` objects representing
|
||||||
arguments passed by keyword.
|
arguments passed by keyword.
|
||||||
|
|
||||||
When creating a ``Call`` node, ``args`` and ``keywords`` are required, but
|
The ``args`` and ``keywords`` arguments are optional and default to empty lists.
|
||||||
they can be empty lists.
|
|
||||||
|
|
||||||
.. doctest::
|
.. doctest::
|
||||||
|
|
||||||
|
|
|
@ -521,8 +521,10 @@ ast
|
||||||
|
|
||||||
If an optional field on an AST node is not included as an argument when
|
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,
|
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.
|
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
|
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.)
|
constructed AST node instance.)
|
||||||
|
|
||||||
If other arguments are omitted, a :exc:`DeprecationWarning` is emitted.
|
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
|
unless the class opts in to the new behavior by setting the attribute
|
||||||
:attr:`ast.AST._field_types`.
|
: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*
|
* :func:`ast.parse` now accepts an optional argument *optimize*
|
||||||
which is passed on to the :func:`compile` built-in. This makes it
|
which is passed on to the :func:`compile` built-in. This makes it
|
||||||
|
|
|
@ -3036,6 +3036,23 @@ class ASTConstructorTests(unittest.TestCase):
|
||||||
self.assertEqual(node.name, 'foo')
|
self.assertEqual(node.name, 'foo')
|
||||||
self.assertEqual(node.decorator_list, [])
|
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):
|
def test_custom_subclass_with_no_fields(self):
|
||||||
class NoInit(ast.AST):
|
class NoInit(ast.AST):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -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.
|
|
@ -1022,6 +1022,13 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
|
||||||
goto set_remaining_cleanup;
|
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 {
|
else {
|
||||||
// simple field (e.g., identifier)
|
// simple field (e.g., identifier)
|
||||||
if (PyErr_WarnFormat(
|
if (PyErr_WarnFormat(
|
||||||
|
|
|
@ -5221,6 +5221,13 @@ ast_type_init(PyObject *self, PyObject *args, PyObject *kw)
|
||||||
goto set_remaining_cleanup;
|
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 {
|
else {
|
||||||
// simple field (e.g., identifier)
|
// simple field (e.g., identifier)
|
||||||
if (PyErr_WarnFormat(
|
if (PyErr_WarnFormat(
|
||||||
|
|
Loading…
Reference in New Issue