mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 13:41:24 +00:00 
			
		
		
		
	[3.13] gh-118851: Default ctx arguments to AST constructors to Load() (GH-118854) (#118871)
(cherry picked from commit 68fbc00dc8)
Co-authored-by: Jelle Zijlstra <jelle.zijlstra@gmail.com>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
			
			
This commit is contained in:
		
							parent
							
								
									982c73a33e
								
							
						
					
					
						commit
						00ec116883
					
				
					 6 changed files with 41 additions and 6 deletions
				
			
		|  | @ -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 @@ def test_FunctionDef(self): | ||||||
|         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 @@ def visitModule(self, mod): | ||||||
|                     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( | ||||||
|  |  | ||||||
							
								
								
									
										7
									
								
								Python/Python-ast.c
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										7
									
								
								Python/Python-ast.c
									
										
									
										generated
									
									
									
								
							|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Miss Islington (bot)
						Miss Islington (bot)