From 6849c59d70aac995c6122374bbe3d59ed41d37aa Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Thu, 8 May 2025 20:45:30 +0200 Subject: [PATCH 1/3] [ci] Start testing on python 3.14-beta --- .github/workflows/ci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 218a7afe1..6ed5faaf6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -81,7 +81,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.9, "3.10", "3.11", "3.12", "3.13"] + python-version: [3.9, "3.10", "3.11", "3.12", "3.13", "3.14-dev"] outputs: python-key: ${{ steps.generate-python-key.outputs.key }} steps: @@ -139,7 +139,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: [3.9, "3.10", "3.11", "3.12", "3.13"] + python-version: [3.9, "3.10", "3.11", "3.12", "3.13", "3.14-dev"] steps: - name: Set temp directory run: echo "TEMP=$env:USERPROFILE\AppData\Local\Temp" >> $env:GITHUB_ENV From da7efb0fb16b1a0ebc59b9ae30f49ab825df0106 Mon Sep 17 00:00:00 2001 From: Pierre Sassoulas Date: Fri, 9 May 2025 20:51:12 +0200 Subject: [PATCH 2/3] Remove syntax error from shared code --- tests/test_nodes.py | 24 +++++- tests/testdata/python3/data/module.py | 6 +- tests/testdata/python3/data/module3.14.py | 91 +++++++++++++++++++++++ 3 files changed, 116 insertions(+), 5 deletions(-) create mode 100644 tests/testdata/python3/data/module3.14.py diff --git a/tests/test_nodes.py b/tests/test_nodes.py index faab9b675..8b17b5a22 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -28,7 +28,14 @@ transforms, util, ) -from astroid.const import IS_PYPY, PY310_PLUS, PY311_PLUS, PY312_PLUS, Context +from astroid.const import ( + IS_PYPY, + PY310_PLUS, + PY311_PLUS, + PY312_PLUS, + PY314_PLUS, + Context, +) from astroid.context import InferenceContext from astroid.exceptions import ( AstroidBuildingError, @@ -115,12 +122,23 @@ def test_varargs_kwargs_as_string(self) -> None: ast = abuilder.string_build("raise_string(*args, **kwargs)").body[0] self.assertEqual(ast.as_string(), "raise_string(*args, **kwargs)") - def test_module_as_string(self) -> None: - """Check as_string on a whole module prepared to be returned identically.""" + @pytest.mark.skipif(PY314_PLUS, reason="return in finally is now a syntax error") + def test_module_as_string_pre_3_14(self) -> None: + """Check as_string on a whole module prepared to be returned identically for py < 3.14.""" + self.maxDiff = None module = resources.build_file("data/module.py", "data.module") with open(resources.find("data/module.py"), encoding="utf-8") as fobj: self.assertMultiLineEqual(module.as_string(), fobj.read()) + @pytest.mark.skipif( + not PY314_PLUS, reason="return in finally is now a syntax error" + ) + def test_module_as_string(self) -> None: + """Check as_string on a whole module prepared to be returned identically for py > 3.14.""" + module = resources.build_file("data/module3.14.py", "data.module3.14") + with open(resources.find("data/module3.14.py"), encoding="utf-8") as fobj: + self.assertMultiLineEqual(module.as_string(), fobj.read()) + def test_module2_as_string(self) -> None: """Check as_string on a whole module prepared to be returned identically.""" module2 = resources.build_file("data/module2.py", "data.module2") diff --git a/tests/testdata/python3/data/module.py b/tests/testdata/python3/data/module.py index af4a75f7d..056fb3eb7 100644 --- a/tests/testdata/python3/data/module.py +++ b/tests/testdata/python3/data/module.py @@ -59,8 +59,10 @@ def method(self): return 'hehe' global_access(local, val=autre) finally: - return local - + # return in finally was previousely tested here but became a syntax error + # in 3.14 and this file is used in 188/1464 tests + a = local + def static_method(): """static method test""" assert MY_DICT, '???' diff --git a/tests/testdata/python3/data/module3.14.py b/tests/testdata/python3/data/module3.14.py new file mode 100644 index 000000000..33643b4ce --- /dev/null +++ b/tests/testdata/python3/data/module3.14.py @@ -0,0 +1,91 @@ +"""test module for astroid +""" + +__revision__ = '$Id: module.py,v 1.2 2005-11-02 11:56:54 syt Exp $' +from astroid.nodes.node_classes import Name as NameNode +from astroid import modutils +from astroid.utils import * +import os.path +MY_DICT = {} + +def global_access(key, val): + """function test""" + local = 1 + MY_DICT[key] = val + for i in val: + if i: + del MY_DICT[i] + continue + else: + break + else: + return + + +class YO: + """hehe + haha""" + a = 1 + + def __init__(self): + try: + self.yo = 1 + except ValueError as ex: + pass + except (NameError, TypeError): + raise XXXError() + except: + raise + + + +class YOUPI(YO): + class_attr = None + + def __init__(self): + self.member = None + + def method(self): + """method + test""" + global MY_DICT + try: + MY_DICT = {} + local = None + autre = [a for (a, b) in MY_DICT if b] + if b in autre: + return + elif a in autre: + return 'hehe' + global_access(local, val=autre) + finally: + # return in finally was previousely tested here but became a syntax error + # in 3.14 and is used in 188/1464 tests + print(local) + + def static_method(): + """static method test""" + assert MY_DICT, '???' + static_method = staticmethod(static_method) + + def class_method(cls): + """class method test""" + exec(a, b) + class_method = classmethod(class_method) + + +def four_args(a, b, c, d): + """four arguments (was nested_args)""" + while 1: + if a: + break + a += +1 + else: + b += -2 + if c: + d = a and (b or c) + else: + c = a and b or d + list(map(lambda x, y: (y, x), a)) +redirect = four_args + From b19868de244af1aea99065deeb4fa3bfad8e123c Mon Sep 17 00:00:00 2001 From: Marc Mueller <30130371+cdce8p@users.noreply.github.com> Date: Fri, 16 May 2025 17:35:35 +0200 Subject: [PATCH 3/3] Fix failing tests --- tests/test_builder.py | 2 +- tests/test_nodes.py | 13 +++++++++++-- tests/testdata/python3/data/module.py | 4 ++-- tests/testdata/python3/data/module3.14.py | 4 ++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/tests/test_builder.py b/tests/test_builder.py index b4bc3e9e0..175f75408 100644 --- a/tests/test_builder.py +++ b/tests/test_builder.py @@ -850,7 +850,7 @@ def test_method_locals(self) -> None: """Test the 'locals' dictionary of an astroid method.""" method = self.module["YOUPI"]["method"] # ListComp variables are not accessible outside - self.assertEqual(sorted(method.locals), ["autre", "local", "self"]) + self.assertEqual(sorted(method.locals), ["a", "autre", "local", "self"]) def test_unknown_encoding(self) -> None: with self.assertRaises(AstroidSyntaxError): diff --git a/tests/test_nodes.py b/tests/test_nodes.py index 8b17b5a22..7006bdb1b 100644 --- a/tests/test_nodes.py +++ b/tests/test_nodes.py @@ -128,16 +128,25 @@ def test_module_as_string_pre_3_14(self) -> None: self.maxDiff = None module = resources.build_file("data/module.py", "data.module") with open(resources.find("data/module.py"), encoding="utf-8") as fobj: - self.assertMultiLineEqual(module.as_string(), fobj.read()) + # Ignore comments in python file + data_str = "\n".join( + [s for s in fobj.read().split("\n") if not s.lstrip().startswith("# ")] + ) + self.assertMultiLineEqual(module.as_string(), data_str) @pytest.mark.skipif( not PY314_PLUS, reason="return in finally is now a syntax error" ) def test_module_as_string(self) -> None: """Check as_string on a whole module prepared to be returned identically for py > 3.14.""" + self.maxDiff = None module = resources.build_file("data/module3.14.py", "data.module3.14") with open(resources.find("data/module3.14.py"), encoding="utf-8") as fobj: - self.assertMultiLineEqual(module.as_string(), fobj.read()) + # Ignore comments in python file + data_str = "\n".join( + [s for s in fobj.read().split("\n") if not s.lstrip().startswith("# ")] + ) + self.assertMultiLineEqual(module.as_string(), data_str) def test_module2_as_string(self) -> None: """Check as_string on a whole module prepared to be returned identically.""" diff --git a/tests/testdata/python3/data/module.py b/tests/testdata/python3/data/module.py index 056fb3eb7..fba4c9c77 100644 --- a/tests/testdata/python3/data/module.py +++ b/tests/testdata/python3/data/module.py @@ -59,10 +59,10 @@ def method(self): return 'hehe' global_access(local, val=autre) finally: - # return in finally was previousely tested here but became a syntax error + # return in finally was previously tested here but became a syntax error # in 3.14 and this file is used in 188/1464 tests a = local - + def static_method(): """static method test""" assert MY_DICT, '???' diff --git a/tests/testdata/python3/data/module3.14.py b/tests/testdata/python3/data/module3.14.py index 33643b4ce..a29b14d89 100644 --- a/tests/testdata/python3/data/module3.14.py +++ b/tests/testdata/python3/data/module3.14.py @@ -59,10 +59,10 @@ def method(self): return 'hehe' global_access(local, val=autre) finally: - # return in finally was previousely tested here but became a syntax error + # return in finally was previously tested here but became a syntax error # in 3.14 and is used in 188/1464 tests print(local) - + def static_method(): """static method test""" assert MY_DICT, '???'