1- """Verify that warnings are issued for global statements following use."""
1+ """This module includes tests for syntax errors that occur when a name
2+ declared as `global` is used in ways that violate the language
3+ specification, such as after assignment, usage, or annotation. The tests
4+ verify that syntax errors are correctly raised for improper `global`
5+ statements following variable use or assignment within functions.
6+ Additionally, it tests various name-binding scenarios for global
7+ variables to ensure correct behavior.
28
9+ See `test_scope.py` for additional related behavioral tests covering
10+ variable scoping and usage in different contexts.
11+ """
12+
13+ import contextlib
314from test .support import check_syntax_error
415from test .support .warnings_helper import check_warnings
16+ from types import SimpleNamespace
517import unittest
618import warnings
719
@@ -12,40 +24,185 @@ def setUp(self):
1224 self .enterContext (check_warnings ())
1325 warnings .filterwarnings ("error" , module = "<test string>" )
1426
15- def test1 (self ):
16- prog_text_1 = """\
17- def wrong1():
18- a = 1
19- b = 2
20- global a
21- global b
27+ ######################################################
28+ ### Syntax error cases as covered in Python/symtable.c
29+ ######################################################
30+
31+ def test_name_param (self ):
32+ prog_text = """\
33+ def fn(name_param):
34+ global name_param
2235"""
23- check_syntax_error (self , prog_text_1 , lineno = 4 , offset = 5 )
36+ check_syntax_error (self , prog_text , lineno = 2 , offset = 5 )
2437
25- def test2 (self ):
26- prog_text_2 = """\
27- def wrong2 ():
28- print(x)
29- global x
38+ def test_name_after_assign (self ):
39+ prog_text = """\
40+ def fn ():
41+ name_assign = 1
42+ global name_assign
3043"""
31- check_syntax_error (self , prog_text_2 , lineno = 3 , offset = 5 )
44+ check_syntax_error (self , prog_text , lineno = 3 , offset = 5 )
3245
33- def test3 (self ):
34- prog_text_3 = """\
35- def wrong3():
36- print(x)
37- x = 2
38- global x
46+ def test_name_after_use (self ):
47+ prog_text = """\
48+ def fn():
49+ print(name_use)
50+ global name_use
3951"""
40- check_syntax_error (self , prog_text_3 , lineno = 4 , offset = 5 )
52+ check_syntax_error (self , prog_text , lineno = 3 , offset = 5 )
4153
42- def test4 (self ):
43- prog_text_4 = """\
44- global x
45- x = 2
54+ def test_name_annot (self ):
55+ prog_text_3 = """\
56+ def fn():
57+ name_annot: int
58+ global name_annot
4659"""
47- # this should work
48- compile (prog_text_4 , "<test string>" , "exec" )
60+ check_syntax_error (self , prog_text_3 , lineno = 3 , offset = 5 )
61+
62+ #############################################################
63+ ### Tests for global variables across all name binding cases,
64+ ### as described in executionmodel.rst
65+ #############################################################
66+
67+ def test_assignment_statement (self ):
68+ global name_assignment_statement
69+ value = object ()
70+ name_assignment_statement = value
71+ self .assertIs (globals ()["name_assignment_statement" ], value )
72+ del name_assignment_statement
73+
74+ def test_unpacking_assignment (self ):
75+ global name_unpacking_assignment
76+ value = object ()
77+ _ , name_unpacking_assignment = [None , value ]
78+ self .assertIs (globals ()["name_unpacking_assignment" ], value )
79+ del name_unpacking_assignment
80+
81+ def test_assignment_expression (self ):
82+ global name_assignment_expression
83+ value = object ()
84+ if name_assignment_expression := value :
85+ pass
86+ self .assertIs (globals ()["name_assignment_expression" ], value )
87+ del name_assignment_expression
88+
89+ def test_iteration_variable (self ):
90+ global name_iteration_variable
91+ value = object ()
92+ for name_iteration_variable in [value ]:
93+ pass
94+ self .assertIs (globals ()["name_iteration_variable" ], value )
95+ del name_iteration_variable
96+
97+ def test_func_def (self ):
98+ global name_func_def
99+
100+ def name_func_def ():
101+ pass
102+
103+ value = name_func_def
104+ self .assertIs (globals ()["name_func_def" ], value )
105+ del name_func_def
106+
107+ def test_class_def (self ):
108+ global name_class_def
109+
110+ class name_class_def :
111+ pass
112+
113+ value = name_class_def
114+ self .assertIs (globals ()["name_class_def" ], value )
115+ del name_class_def
116+
117+ def test_type_alias (self ):
118+ global name_type_alias
119+ type name_type_alias = tuple [int , int ]
120+ value = name_type_alias
121+ self .assertIs (globals ()["name_type_alias" ], value )
122+ del name_type_alias
123+
124+ def test_caught_exception (self ):
125+ global name_caught_exc
126+
127+ try :
128+ 1 / 0
129+ except ZeroDivisionError as name_caught_exc :
130+ value = name_caught_exc
131+ # `name_caught_exc` is cleared automatically after the except block
132+ self .assertIs (globals ()["name_caught_exc" ], value )
133+
134+ def test_caught_exception_group (self ):
135+ global name_caught_exc_group
136+ try :
137+ try :
138+ 1 / 0
139+ except ZeroDivisionError as exc :
140+ raise ExceptionGroup ("eg" , [exc ])
141+ except* ZeroDivisionError as name_caught_exc_group :
142+ value = name_caught_exc_group
143+ # `name_caught_exc` is cleared automatically after the except block
144+ self .assertIs (globals ()["name_caught_exc_group" ], value )
145+
146+ def test_enter_result (self ):
147+ global name_enter_result
148+ value = object ()
149+ with contextlib .nullcontext (value ) as name_enter_result :
150+ pass
151+ self .assertIs (globals ()["name_enter_result" ], value )
152+ del name_enter_result
153+
154+ def test_import_result (self ):
155+ global name_import_result
156+ value = contextlib
157+ import contextlib as name_import_result
158+
159+ self .assertIs (globals ()["name_import_result" ], value )
160+ del name_import_result
161+
162+ def test_match (self ):
163+ global name_match
164+ value = object ()
165+ match value :
166+ case name_match :
167+ pass
168+ self .assertIs (globals ()["name_match" ], value )
169+ del name_match
170+
171+ def test_match_as (self ):
172+ global name_match_as
173+ value = object ()
174+ match value :
175+ case _ as name_match_as :
176+ pass
177+ self .assertIs (globals ()["name_match_as" ], value )
178+ del name_match_as
179+
180+ def test_match_seq (self ):
181+ global name_match_seq
182+ value = object ()
183+ match (None , value ):
184+ case (_, name_match_seq ):
185+ pass
186+ self .assertIs (globals ()["name_match_seq" ], value )
187+ del name_match_seq
188+
189+ def test_match_map (self ):
190+ global name_match_map
191+ value = object ()
192+ match {"key" : value }:
193+ case {"key" : name_match_map }:
194+ pass
195+ self .assertIs (globals ()["name_match_map" ], value )
196+ del name_match_map
197+
198+ def test_match_attr (self ):
199+ global name_match_attr
200+ value = object ()
201+ match SimpleNamespace (key = value ):
202+ case SimpleNamespace (key = name_match_attr ):
203+ pass
204+ self .assertIs (globals ()["name_match_attr" ], value )
205+ del name_match_attr
49206
50207
51208def setUpModule ():
0 commit comments