diff --git a/test/test_bind_names_namedexpr.py b/test/test_bind_names_namedexpr.py new file mode 100644 index 0000000..a0e4ccb --- /dev/null +++ b/test/test_bind_names_namedexpr.py @@ -0,0 +1,259 @@ +import sys + +import pytest + +from helpers import assert_namespace_tree + +def test_namedexpr_in_module(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +(a := 1) +''' + + expected_namespaces = ''' ++ Module + - NameBinding(name='a', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + +def test_namedexpr_in_function(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +def test(): + (a := 1) +lambda x: (x := 1) +''' + + expected_namespaces = ''' ++ Module + - NameBinding(name='test', allow_rename=True) + + Function test + - NameBinding(name='a', allow_rename=True) + + Lambda + - NameBinding(name='x', allow_rename=False) +''' + + assert_namespace_tree(source, expected_namespaces) + +def test_namedexpr_in_listcomp_if_nonlocal(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +def f(arg, /): + nonlocal x + print([x for y in range(10) if (x := y // 2) & 1]) + print(arg, arg) +''' + + expected_namespaces = ''' ++ Module + - NameBinding(name='f', allow_rename=True) + - BuiltinBinding(name='print', allow_rename=True) + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='x', allow_rename=False) + + Function f + - nonlocal x + - NameBinding(name='arg', allow_rename=True) + + ListComp + - NameBinding(name='y', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + + +def test_namedexpr_in_listcomp_if_global(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +def f2(): + def f(arg, /): + global x + print([x for y in range(10) if (x := y // 2) & 1]) + print(arg, arg) +''' + + expected_namespaces = ''' ++ Module + - NameBinding(name='f2', allow_rename=True) + - BuiltinBinding(name='print', allow_rename=True) + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + Function f2 + - NameBinding(name='f', allow_rename=True) + + Function f + - global x + - NameBinding(name='arg', allow_rename=True) + + ListComp + - NameBinding(name='y', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + + +def test_namedexpr_in_listcomp_if(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +def f(arg, /): + print([x for y in range(10) if (x := y // 2) & 1]) + print(arg, arg) +''' + + expected_namespaces = ''' ++ Module + - NameBinding(name='f', allow_rename=True) + - BuiltinBinding(name='print', allow_rename=True) + - BuiltinBinding(name='range', allow_rename=True) + + Function f + - NameBinding(name='arg', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + ListComp + - NameBinding(name='y', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + + +def test_namedexpr_in_listcomp_body(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +def f(arg, /): + print([(x := y // 2) for _ in range(x)]) + print(arg, arg) +''' + + expected_namespaces = ''' ++ Module + - NameBinding(name='f', allow_rename=True) + - BuiltinBinding(name='print', allow_rename=True) + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='y', allow_rename=False) + + Function f + - NameBinding(name='arg', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + ListComp + - NameBinding(name='_', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + +def test_namedexpr_in_dictcomp_body(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +{i: (x := i // 2) for i in range(1)} +''' + + expected_namespaces = ''' ++ Module + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + DictComp + - NameBinding(name='i', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + + +def test_namedexpr_in_dictcomp_if(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +{x: y for y in range(1) if (x := y // 2)} +''' + + expected_namespaces = ''' ++ Module + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + DictComp + - NameBinding(name='y', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + +def test_namedexpr_in_setcomp_body(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +{(x := y // 2) for y in range(1)} +''' + + expected_namespaces = ''' ++ Module + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + SetComp + - NameBinding(name='y', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + + +def test_namedexpr_in_setcomp_if(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +{x for y in range(1) if (x := y // 2)} +''' + + expected_namespaces = ''' ++ Module + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + SetComp + - NameBinding(name='y', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + +def test_namedexpr_in_generatorexp_body(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +((x := y // 2) for y in range(1)) +''' + + expected_namespaces = ''' ++ Module + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + GeneratorExp + - NameBinding(name='y', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) + + +def test_namedexpr_in_generatorexp_if(): + if sys.version_info < (3, 8): + pytest.skip('Test is for >= python3.8 only') + + source = ''' +(x for y in range(1) if (x := y // 2)) +''' + + expected_namespaces = ''' ++ Module + - BuiltinBinding(name='range', allow_rename=True) + - NameBinding(name='x', allow_rename=True) + + GeneratorExp + - NameBinding(name='y', allow_rename=True) +''' + + assert_namespace_tree(source, expected_namespaces) diff --git a/test/test_bind_names_python312.py b/test/test_bind_names_python312.py index 43f5c08..c751c7b 100644 --- a/test/test_bind_names_python312.py +++ b/test/test_bind_names_python312.py @@ -165,63 +165,3 @@ def test_alias_paramspec_default(): ''' assert_namespace_tree(source, expected_namespaces) - -def test_namedexpr_in_module(): - if sys.version_info < (3, 8): - pytest.skip('Test is for > python3.8 only') - - source = ''' -(a := 1) -''' - - expected_namespaces = ''' -+ Module - - NameBinding(name='a', allow_rename=True) -''' - - assert_namespace_tree(source, expected_namespaces) - -def test_namedexpr_in_function(): - if sys.version_info < (3, 8): - pytest.skip('Test is for > python3.8 only') - - source = ''' -def test(): - (a := 1) -lambda x: (x := 1) -''' - - expected_namespaces = ''' -+ Module - - NameBinding(name='test', allow_rename=True) - + Function test - - NameBinding(name='a', allow_rename=True) - + Lambda - - NameBinding(name='x', allow_rename=False) -''' - - assert_namespace_tree(source, expected_namespaces) - -def test_namedexpr(): - if sys.version_info < (3, 8): - pytest.skip('Test is for > python3.8 only') - - source = ''' -def f(arg, /): - print([x for y in range(10) if (x := y // 2) & 1]) - print(arg, arg) -''' - - expected_namespaces = ''' -+ Module - - NameBinding(name='f', allow_rename=True) - - BuiltinBinding(name='print', allow_rename=True) - - BuiltinBinding(name='range', allow_rename=True) - + Function f - - NameBinding(name='arg', allow_rename=True) - - NameBinding(name='x', allow_rename=True) - + ListComp - - NameBinding(name='y', allow_rename=True) -''' - - assert_namespace_tree(source, expected_namespaces)