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.
2
8
9
+ See `test_scope.py` for additional related behavioral tests covering
10
+ variable scoping and usage in different contexts.
11
+ """
12
+
13
+ import contextlib
3
14
from test .support import check_syntax_error
4
15
from test .support .warnings_helper import check_warnings
16
+ from types import SimpleNamespace
5
17
import unittest
6
18
import warnings
7
19
@@ -12,40 +24,185 @@ def setUp(self):
12
24
self .enterContext (check_warnings ())
13
25
warnings .filterwarnings ("error" , module = "<test string>" )
14
26
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
22
35
"""
23
- check_syntax_error (self , prog_text_1 , lineno = 4 , offset = 5 )
36
+ check_syntax_error (self , prog_text , lineno = 2 , offset = 5 )
24
37
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
30
43
"""
31
- check_syntax_error (self , prog_text_2 , lineno = 3 , offset = 5 )
44
+ check_syntax_error (self , prog_text , lineno = 3 , offset = 5 )
32
45
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
39
51
"""
40
- check_syntax_error (self , prog_text_3 , lineno = 4 , offset = 5 )
52
+ check_syntax_error (self , prog_text , lineno = 3 , offset = 5 )
41
53
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
46
59
"""
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
49
206
50
207
51
208
def setUpModule ():
0 commit comments