"""This module includes tests for syntax errors that occur when a name declared as `global` is used in ways that violate the language specification, such as after assignment, usage, or annotation. The tests verify that syntax errors are correctly raised for improper `global` statements following variable use or assignment within functions. Additionally, it tests various name-binding scenarios for global variables to ensure correct behavior. See `test_scope.py` for additional related behavioral tests covering variable scoping and usage in different contexts. """ import contextlib from test.support import check_syntax_error from test.support.warnings_helper import check_warnings from types import SimpleNamespace import unittest import warnings class GlobalTests(unittest.TestCase): def setUp(self): self.enterContext(check_warnings()) warnings.filterwarnings("error", module="") ###################################################### ### Syntax error cases as covered in Python/symtable.c ###################################################### def test_name_param(self): prog_text = """\ def fn(name_param): global name_param """ check_syntax_error(self, prog_text, lineno=2, offset=5) def test_name_after_assign(self): prog_text = """\ def fn(): name_assign = 1 global name_assign """ check_syntax_error(self, prog_text, lineno=3, offset=5) def test_name_after_use(self): prog_text = """\ def fn(): print(name_use) global name_use """ check_syntax_error(self, prog_text, lineno=3, offset=5) def test_name_annot(self): prog_text_3 = """\ def fn(): name_annot: int global name_annot """ check_syntax_error(self, prog_text_3, lineno=3, offset=5) ############################################################# ### Tests for global variables across all name binding cases, ### as described in executionmodel.rst ############################################################# def test_assignment_statement(self): global name_assignment_statement value = object() name_assignment_statement = value self.assertIs(globals()["name_assignment_statement"], value) del name_assignment_statement def test_unpacking_assignment(self): global name_unpacking_assignment value = object() _, name_unpacking_assignment = [None, value] self.assertIs(globals()["name_unpacking_assignment"], value) del name_unpacking_assignment def test_assignment_expression(self): global name_assignment_expression value = object() if name_assignment_expression := value: pass self.assertIs(globals()["name_assignment_expression"], value) del name_assignment_expression def test_iteration_variable(self): global name_iteration_variable value = object() for name_iteration_variable in [value]: pass self.assertIs(globals()["name_iteration_variable"], value) del name_iteration_variable def test_func_def(self): global name_func_def def name_func_def(): pass value = name_func_def self.assertIs(globals()["name_func_def"], value) del name_func_def def test_class_def(self): global name_class_def class name_class_def: pass value = name_class_def self.assertIs(globals()["name_class_def"], value) del name_class_def def test_type_alias(self): global name_type_alias type name_type_alias = tuple[int, int] value = name_type_alias self.assertIs(globals()["name_type_alias"], value) del name_type_alias def test_caught_exception(self): global name_caught_exc try: 1 / 0 except ZeroDivisionError as name_caught_exc: value = name_caught_exc # `name_caught_exc` is cleared automatically after the except block self.assertIs(globals()["name_caught_exc"], value) def test_caught_exception_group(self): global name_caught_exc_group try: try: 1 / 0 except ZeroDivisionError as exc: raise ExceptionGroup("eg", [exc]) except* ZeroDivisionError as name_caught_exc_group: value = name_caught_exc_group # `name_caught_exc` is cleared automatically after the except block self.assertIs(globals()["name_caught_exc_group"], value) def test_enter_result(self): global name_enter_result value = object() with contextlib.nullcontext(value) as name_enter_result: pass self.assertIs(globals()["name_enter_result"], value) del name_enter_result def test_import_result(self): global name_import_result value = contextlib import contextlib as name_import_result self.assertIs(globals()["name_import_result"], value) del name_import_result def test_match(self): global name_match value = object() match value: case name_match: pass self.assertIs(globals()["name_match"], value) del name_match def test_match_as(self): global name_match_as value = object() match value: case _ as name_match_as: pass self.assertIs(globals()["name_match_as"], value) del name_match_as def test_match_seq(self): global name_match_seq value = object() match (None, value): case (_, name_match_seq): pass self.assertIs(globals()["name_match_seq"], value) del name_match_seq def test_match_map(self): global name_match_map value = object() match {"key": value}: case {"key": name_match_map}: pass self.assertIs(globals()["name_match_map"], value) del name_match_map def test_match_attr(self): global name_match_attr value = object() match SimpleNamespace(key=value): case SimpleNamespace(key=name_match_attr): pass self.assertIs(globals()["name_match_attr"], value) del name_match_attr def setUpModule(): unittest.enterModuleContext(warnings.catch_warnings()) warnings.filterwarnings("error", module="") if __name__ == "__main__": unittest.main()