From 37299e782fb68c160806318af72da028a22f31c3 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Wed, 22 Apr 2026 14:31:40 +0100 Subject: [PATCH 01/10] Fixes max2code and mi2code assuming inputs are real scalars --- doc/user_guide/transformations.rst | 10 ------- .../intrinsics/minormax2code_trans.py | 28 +++++++++++-------- .../intrinsics/max2code_trans_test.py | 4 +-- .../intrinsics/min2code_trans_test.py | 6 ++-- 4 files changed, 22 insertions(+), 26 deletions(-) diff --git a/doc/user_guide/transformations.rst b/doc/user_guide/transformations.rst index 7fd87a0b41..f41f991468 100644 --- a/doc/user_guide/transformations.rst +++ b/doc/user_guide/transformations.rst @@ -344,11 +344,6 @@ can be found in the API-specific sections). :members: apply :no-index: -.. warning:: This transformation assumes that the MAX Intrinsic acts on - PSyIR Real scalar data and does not check that this is - not the case. Once issue #658 is on master then this - limitation can be fixed. - #### .. autoclass:: psyclone.psyir.transformations.Maxval2LoopTrans @@ -361,11 +356,6 @@ can be found in the API-specific sections). :members: apply :no-index: -.. warning:: This transformation assumes that the MIN Intrinsic acts on - PSyIR Real scalar data and does not check that this is - not the case. Once issue #658 is on master then this - limitation can be fixed. - #### .. autoclass:: psyclone.psyir.transformations.Minval2LoopTrans diff --git a/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py b/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py index 73aa14bcd6..511adb6785 100644 --- a/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py +++ b/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py @@ -85,6 +85,19 @@ def __init__(self): super().__init__() self._compare_operator = None + def validate(self, node, options=None): + ''' + Check that it is safe to apply the transformation to the supplied node. + + :param node: the SIGN call to transform. + :type node: :py:class:`psyclone.psyir.nodes.IntrinsicCall` + :param options: any of options for the transformation. + :type options: dict[str, Any] + + ''' + super().validate(node, options=options) + super()._validate_scalar_arg(node) + def apply(self, node, options=None, **kwargs): '''Apply this utility transformation to the specified node. This node must be a MIN or MAX IntrinsicCall. The intrinsic is converted to @@ -132,21 +145,14 @@ def apply(self, node, options=None, **kwargs): symbol_table = node.scope.symbol_table assignment = node.ancestor(Assignment) - # Create a temporary result variable. There is an assumption - # here that the Intrinsic returns a PSyIR real type. This - # might not be what is wanted (e.g. the args might PSyIR - # integers), or there may be errors (arguments are of - # different types) but this can't be checked as we don't have - # appropriate methods to query nodes (see #658). + # Create two temporary variables. + result_type = node.arguments[0].datatype res_var_symbol = symbol_table.new_symbol( f"res_{self._intrinsic.name.lower()}", - symbol_type=DataSymbol, datatype=REAL_TYPE) - # Create a temporary variable. Again there is an - # assumption here about the datatype - please see previous - # comment (associated issue #658). + symbol_type=DataSymbol, datatype=result_type) tmp_var_symbol = symbol_table.new_symbol( f"tmp_{self._intrinsic.name.lower()}", - symbol_type=DataSymbol, datatype=REAL_TYPE) + symbol_type=DataSymbol, datatype=result_type) # Replace intrinsic with a temporary (res_var). node.replace_with(Reference(res_var_symbol)) diff --git a/src/psyclone/tests/psyir/transformations/intrinsics/max2code_trans_test.py b/src/psyclone/tests/psyir/transformations/intrinsics/max2code_trans_test.py index b2dea24fac..38f07a3769 100644 --- a/src/psyclone/tests/psyir/transformations/intrinsics/max2code_trans_test.py +++ b/src/psyclone/tests/psyir/transformations/intrinsics/max2code_trans_test.py @@ -69,8 +69,8 @@ def test_apply(fortran_reader, fortran_writer): integer :: j integer :: k integer :: l - real :: res_max - real :: tmp_max + integer :: res_max + integer :: tmp_max res_max = i tmp_max = j diff --git a/src/psyclone/tests/psyir/transformations/intrinsics/min2code_trans_test.py b/src/psyclone/tests/psyir/transformations/intrinsics/min2code_trans_test.py index 82bd85d7a2..36aad5d17c 100644 --- a/src/psyclone/tests/psyir/transformations/intrinsics/min2code_trans_test.py +++ b/src/psyclone/tests/psyir/transformations/intrinsics/min2code_trans_test.py @@ -1,5 +1,5 @@ # ----------------------------------------------------------------------------- -# BSD 3-Clause License + BSD 3-Clause License # # Copyright (c) 2021-2026, Science and Technology Facilities Council # All rights reserved. @@ -70,8 +70,8 @@ def test_apply(fortran_reader, fortran_writer): integer :: j integer :: k integer :: l - real :: res_min - real :: tmp_min + integer :: res_min + integer :: tmp_min res_min = i tmp_min = j From 638a9d2217724c867055a22ca2770dfab04e3ae4 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Wed, 22 Apr 2026 14:36:14 +0100 Subject: [PATCH 02/10] linting errors --- .../intrinsics/minormax2code_trans.py | 12 +++++++----- .../intrinsics/min2code_trans_test.py | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py b/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py index 511adb6785..af29b9f78b 100644 --- a/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py +++ b/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py @@ -47,11 +47,13 @@ from abc import ABC import warnings -from psyclone.psyir.nodes import BinaryOperation, Assignment, \ - Reference, IfBlock -from psyclone.psyir.symbols import DataSymbol, REAL_TYPE -from psyclone.psyir.transformations.intrinsics.intrinsic2code_trans import \ - Intrinsic2CodeTrans +from psyclone.psyir.nodes import ( + BinaryOperation, Assignment, Reference, IfBlock +) +from psyclone.psyir.symbols import DataSymbol +from psyclone.psyir.transformations.intrinsics.intrinsic2code_trans import ( + Intrinsic2CodeTrans +) from psyclone.utils import transformation_documentation_wrapper diff --git a/src/psyclone/tests/psyir/transformations/intrinsics/min2code_trans_test.py b/src/psyclone/tests/psyir/transformations/intrinsics/min2code_trans_test.py index 36aad5d17c..bfc2fd90e3 100644 --- a/src/psyclone/tests/psyir/transformations/intrinsics/min2code_trans_test.py +++ b/src/psyclone/tests/psyir/transformations/intrinsics/min2code_trans_test.py @@ -1,5 +1,5 @@ # ----------------------------------------------------------------------------- - BSD 3-Clause License +# BSD 3-Clause License # # Copyright (c) 2021-2026, Science and Technology Facilities Council # All rights reserved. From f9689cf5f5569361306e880f805371c97f834f61 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Mon, 27 Apr 2026 09:45:26 +0100 Subject: [PATCH 03/10] Fixed mistake in kwargs and added typehint to minormax2code --- .../transformations/intrinsics/minormax2code_trans.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py b/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py index af29b9f78b..42b1110e1c 100644 --- a/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py +++ b/src/psyclone/psyir/transformations/intrinsics/minormax2code_trans.py @@ -48,7 +48,7 @@ import warnings from psyclone.psyir.nodes import ( - BinaryOperation, Assignment, Reference, IfBlock + BinaryOperation, Assignment, Reference, IfBlock, IntrinsicCall ) from psyclone.psyir.symbols import DataSymbol from psyclone.psyir.transformations.intrinsics.intrinsic2code_trans import ( @@ -87,20 +87,18 @@ def __init__(self): super().__init__() self._compare_operator = None - def validate(self, node, options=None): + def validate(self, node: IntrinsicCall, options=None, **kwargs): ''' Check that it is safe to apply the transformation to the supplied node. :param node: the SIGN call to transform. - :type node: :py:class:`psyclone.psyir.nodes.IntrinsicCall` :param options: any of options for the transformation. - :type options: dict[str, Any] ''' - super().validate(node, options=options) + super().validate(node, options=options, **kwargs) super()._validate_scalar_arg(node) - def apply(self, node, options=None, **kwargs): + def apply(self, node: IntrinsicCall, options=None, **kwargs): '''Apply this utility transformation to the specified node. This node must be a MIN or MAX IntrinsicCall. The intrinsic is converted to equivalent inline code. This is implemented as a PSyIR transform from: @@ -132,7 +130,6 @@ def apply(self, node, options=None, **kwargs): this is not the case. :param node: a MIN or MAX intrinsic. - :type node: :py:class:`psyclone.psyir.nodes.IntrinsicCall` :param options: a dictionary with options for transformations. :type options: Optional[Dict[str, Any]] From dc176da74a1b9a13179f421b800cb76f9e6f8711 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Mon, 27 Apr 2026 11:24:19 +0100 Subject: [PATCH 04/10] Remove extra line break resulting in error in 3.14 tests --- .../tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py index 33705d3033..cf1d620fbf 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py @@ -85,8 +85,7 @@ def test_generate_parse_tree(tmpdir_factory, caplog): assert isinstance(ptree, TSNode) # Invalid code raises a Value error with a relevant error message - invalid_code = """ - program test + invalid_code = """program test syntax error end program test """ From 4563467faa08c998cdd072472a722bc6c3de4f7c Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Mon, 27 Apr 2026 13:05:57 +0100 Subject: [PATCH 05/10] Fixes for treesitter tests --- .../fortran_treesitter_reader/ftr_test.py | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py index cf1d620fbf..cbe1582974 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py @@ -38,6 +38,7 @@ import logging import pytest +import sys from tree_sitter import Node as TSNode @@ -74,6 +75,10 @@ def test_generate_parse_tree(tmpdir_factory, caplog): Test that generate_parse_tree returns treesitter trees or appropriate error messages. ''' + # Skip treesitter tests below 3.10 as they're unsupported by + # treesitter. + if sys.version_info < (3, 10): + return processor = FortranTreeSitterReader() # Valid code returns a treesitter Node @@ -85,13 +90,18 @@ def test_generate_parse_tree(tmpdir_factory, caplog): assert isinstance(ptree, TSNode) # Invalid code raises a Value error with a relevant error message - invalid_code = """program test + invalid_code = """ + program test syntax error end program test """ with pytest.raises(ValueError) as err: _ = processor.generate_parse_tree_from_source(invalid_code) - assert "Syntax Error found at line 2" in str(err.value) + # The result of this test also now seems dependent on Python version + if sys.version_info > (3, 12): + assert "Syntax Error found at line 3" in str(err.value) + else: + assert "Syntax Error found at line 2" in str(err.value) # Test providing a source file filename = str(tmpdir_factory.mktemp('ts_test').join("testfile.f90")) @@ -119,6 +129,10 @@ def test_generate_psyir(): Test that generate_psyir transforms treesitter parse trees to PSyIR nodes. ''' + # Skip treesitter tests below 3.10 as they're unsupported by + # treesitter. + if sys.version_info < (3, 10): + return processor = FortranTreeSitterReader() valid_code = """ @@ -142,6 +156,10 @@ def test_codeblock_generation_and_messages(): Test that NotImplementedErrors are caught and converted to CodeBlocks with the appropriate associated comment ''' + # Skip treesitter tests below 3.10 as they're unsupported by + # treesitter. + if sys.version_info < (3, 10): + return processor = FortranTreeSitterReader() unsupported_code = """ From 727ffad36cdb99c6eb49b09796c4b101e1646fd0 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Mon, 27 Apr 2026 13:33:42 +0100 Subject: [PATCH 06/10] Fixes for other tree sitter related issues --- .../tests/psyir/frontend/fortran_test.py | 6 +++++ .../fortran_treesitter_reader/ftr_test.py | 8 +++---- .../tests/psyir/nodes/codeblock_test.py | 24 +++++++++++++------ 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/psyclone/tests/psyir/frontend/fortran_test.py b/src/psyclone/tests/psyir/frontend/fortran_test.py index 5d873f5e96..150f5d4767 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_test.py @@ -38,6 +38,8 @@ ''' Performs py.test tests on the Fortran PSyIR front-end ''' import pytest +import sys + from psyclone.configuration import Config from psyclone.psyir.frontend.fortran import FortranReader from psyclone.psyir.frontend.fparser2 import Fparser2Reader @@ -97,6 +99,10 @@ def test_fortran_reader_constructor(): # the return value of this function is tested in the following tests freader.psyir_from_source(ONLY_2008_CODE) + # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by + # treesitter. + if sys.version_info < (3, 10): + return # Now repeat the process with treesitter Config.get().frontend = "treesitter" freader = FortranReader() diff --git a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py index cbe1582974..cca850465e 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py @@ -75,7 +75,7 @@ def test_generate_parse_tree(tmpdir_factory, caplog): Test that generate_parse_tree returns treesitter trees or appropriate error messages. ''' - # Skip treesitter tests below 3.10 as they're unsupported by + # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by # treesitter. if sys.version_info < (3, 10): return @@ -98,7 +98,7 @@ def test_generate_parse_tree(tmpdir_factory, caplog): with pytest.raises(ValueError) as err: _ = processor.generate_parse_tree_from_source(invalid_code) # The result of this test also now seems dependent on Python version - if sys.version_info > (3, 12): + if sys.version_info >= (3, 13): assert "Syntax Error found at line 3" in str(err.value) else: assert "Syntax Error found at line 2" in str(err.value) @@ -129,7 +129,7 @@ def test_generate_psyir(): Test that generate_psyir transforms treesitter parse trees to PSyIR nodes. ''' - # Skip treesitter tests below 3.10 as they're unsupported by + # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by # treesitter. if sys.version_info < (3, 10): return @@ -156,7 +156,7 @@ def test_codeblock_generation_and_messages(): Test that NotImplementedErrors are caught and converted to CodeBlocks with the appropriate associated comment ''' - # Skip treesitter tests below 3.10 as they're unsupported by + # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by # treesitter. if sys.version_info < (3, 10): return diff --git a/src/psyclone/tests/psyir/nodes/codeblock_test.py b/src/psyclone/tests/psyir/nodes/codeblock_test.py index a17f022e4a..2d373180c9 100644 --- a/src/psyclone/tests/psyir/nodes/codeblock_test.py +++ b/src/psyclone/tests/psyir/nodes/codeblock_test.py @@ -39,6 +39,8 @@ ''' Performs py.test tests on the CodeBlock PSyIR node. ''' import pytest +import sys + from fparser.common.readfortran import FortranStringReader from psyclone.configuration import Config from psyclone.psyir.frontend.fortran import FortranReader @@ -65,8 +67,19 @@ def test_codeblock_create(): assert isinstance(cb, Fparser2CodeBlock) assert "a => b" in cb.get_fortran_lines() + # Use a different fronted value + Config.get()._frontend = "newfrontend" + with pytest.raises(InternalError) as err: + cb = CodeBlock.create("3 + 3", partial_code="expression") + assert ("The 'newfrontend' frontend does not have an associated CodeBlock " + "subclass" in str(err.value)) + # Use the treesitter frontend (the frontend doesn't support partial # expressions yet, but it gets an appropriate error) + # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by + # treesitter. + if sys.version_info < (3, 10): + return Config.get()._frontend = "treesitter" cb = CodeBlock.create("program test\nend program\n") assert isinstance(cb, TreeSitterCodeBlock) @@ -77,13 +90,6 @@ def test_codeblock_create(): cb = CodeBlock.create("a => b", partial_code="pointer_assignment") assert "Syntax Error found at line 1: a => b" in str(err.value) - # Use a different fronted value - Config.get()._frontend = "newfrontend" - with pytest.raises(InternalError) as err: - cb = CodeBlock.create("3 + 3", partial_code="expression") - assert ("The 'newfrontend' frontend does not have an associated CodeBlock " - "subclass" in str(err.value)) - def test_codeblock_node_str(): ''' Check the node_str method of the Code Block class.''' @@ -184,6 +190,10 @@ def test_codeblock_get_fortran_lines(): assert "subroutine mytest" in block.get_fortran_lines() assert "end subroutine" in block.get_fortran_lines() + # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by + # treesitter. + if sys.version_info < (3, 10): + return tree = FortranTreeSitterReader().generate_parse_tree_from_source(code) block = TreeSitterCodeBlock(tree, CodeBlock.Structure.STATEMENT) assert isinstance(block.get_fortran_lines(), list) From 55932e271ce406d4cce7c0fdaac0dbb86c622710 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Mon, 27 Apr 2026 14:06:58 +0100 Subject: [PATCH 07/10] Update test to work for 3.13 still --- .../tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py index cca850465e..264b37129a 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py @@ -98,7 +98,7 @@ def test_generate_parse_tree(tmpdir_factory, caplog): with pytest.raises(ValueError) as err: _ = processor.generate_parse_tree_from_source(invalid_code) # The result of this test also now seems dependent on Python version - if sys.version_info >= (3, 13): + if sys.version_info >= (3, 14): assert "Syntax Error found at line 3" in str(err.value) else: assert "Syntax Error found at line 2" in str(err.value) From 85cfcc29abfa403a8c557573bd3b00c16a276ddf Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Mon, 27 Apr 2026 14:07:55 +0100 Subject: [PATCH 08/10] Change test to not care about line number --- .../psyir/frontend/fortran_treesitter_reader/ftr_test.py | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py index 264b37129a..5b9ba6ebe6 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py @@ -97,11 +97,7 @@ def test_generate_parse_tree(tmpdir_factory, caplog): """ with pytest.raises(ValueError) as err: _ = processor.generate_parse_tree_from_source(invalid_code) - # The result of this test also now seems dependent on Python version - if sys.version_info >= (3, 14): - assert "Syntax Error found at line 3" in str(err.value) - else: - assert "Syntax Error found at line 2" in str(err.value) + assert "Syntax Error found at line" in str(err.value) # Test providing a source file filename = str(tmpdir_factory.mktemp('ts_test').join("testfile.f90")) From 22a28503af3371eff99652e88c3aab413136da92 Mon Sep 17 00:00:00 2001 From: LonelyCat124 <3043914+LonelyCat124@users.noreply.github.com.> Date: Tue, 28 Apr 2026 15:10:08 +0100 Subject: [PATCH 09/10] Change pre 3.10 skipped tests to use pytest skipif mark --- .../tests/psyir/frontend/fortran_test.py | 9 ++++---- .../fortran_treesitter_reader/ftr_test.py | 23 ++++++++----------- .../tests/psyir/nodes/codeblock_test.py | 16 ++++++------- src/psyclone/tests/utilities.py | 6 +++++ 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/psyclone/tests/psyir/frontend/fortran_test.py b/src/psyclone/tests/psyir/frontend/fortran_test.py index 150f5d4767..ee40595372 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_test.py @@ -38,7 +38,6 @@ ''' Performs py.test tests on the Fortran PSyIR front-end ''' import pytest -import sys from psyclone.configuration import Config from psyclone.psyir.frontend.fortran import FortranReader @@ -51,6 +50,7 @@ from psyclone.psyir.commentable_mixin import CommentableMixin from psyclone.psyir.symbols import ( SymbolTable, DataSymbol, ScalarType, UnresolvedType) +from psyclone.tests.utilities import min_version_3_10 # The 'contiguous' keyword is just valid with Fortran 2008 @@ -89,6 +89,9 @@ ''' +# TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by +# treesitter. +@min_version_3_10 def test_fortran_reader_constructor(): ''' Test that the constructor initialises the _parser and _processor attributes. ''' @@ -99,10 +102,6 @@ def test_fortran_reader_constructor(): # the return value of this function is tested in the following tests freader.psyir_from_source(ONLY_2008_CODE) - # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by - # treesitter. - if sys.version_info < (3, 10): - return # Now repeat the process with treesitter Config.get().frontend = "treesitter" freader = FortranReader() diff --git a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py index 5b9ba6ebe6..a92d6330d0 100644 --- a/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py +++ b/src/psyclone/tests/psyir/frontend/fortran_treesitter_reader/ftr_test.py @@ -38,13 +38,13 @@ import logging import pytest -import sys from tree_sitter import Node as TSNode from psyclone.psyir.frontend.fortran_treesitter_reader import \ FortranTreeSitterReader from psyclone.psyir.nodes import FileContainer, CodeBlock, Container +from psyclone.tests.utilities import min_version_3_10 def test_constructor(): @@ -70,15 +70,14 @@ def test_constructor(): # TODO #3038 Typecheck arguments +# TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by +# treesitter. +@min_version_3_10 def test_generate_parse_tree(tmpdir_factory, caplog): ''' Test that generate_parse_tree returns treesitter trees or appropriate error messages. ''' - # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by - # treesitter. - if sys.version_info < (3, 10): - return processor = FortranTreeSitterReader() # Valid code returns a treesitter Node @@ -120,15 +119,14 @@ def test_generate_parse_tree(tmpdir_factory, caplog): assert isinstance(ptree, TSNode) +# TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by +# treesitter. +@min_version_3_10 def test_generate_psyir(): ''' Test that generate_psyir transforms treesitter parse trees to PSyIR nodes. ''' - # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by - # treesitter. - if sys.version_info < (3, 10): - return processor = FortranTreeSitterReader() valid_code = """ @@ -147,15 +145,14 @@ def test_generate_psyir(): assert isinstance(psyir.children[0].children[0], CodeBlock) +# TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by +# treesitter. +@min_version_3_10 def test_codeblock_generation_and_messages(): ''' Test that NotImplementedErrors are caught and converted to CodeBlocks with the appropriate associated comment ''' - # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by - # treesitter. - if sys.version_info < (3, 10): - return processor = FortranTreeSitterReader() unsupported_code = """ diff --git a/src/psyclone/tests/psyir/nodes/codeblock_test.py b/src/psyclone/tests/psyir/nodes/codeblock_test.py index 2d373180c9..39fb4640aa 100644 --- a/src/psyclone/tests/psyir/nodes/codeblock_test.py +++ b/src/psyclone/tests/psyir/nodes/codeblock_test.py @@ -39,7 +39,6 @@ ''' Performs py.test tests on the CodeBlock PSyIR node. ''' import pytest -import sys from fparser.common.readfortran import FortranStringReader from psyclone.configuration import Config @@ -52,8 +51,12 @@ ) from psyclone.psyir.nodes.node import colored from psyclone.errors import GenerationError, InternalError +from psyclone.tests.utilities import min_version_3_10 +# TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by +# treesitter. +@min_version_3_10 def test_codeblock_create(): ''' Check the create method of the Code Block class.''' @@ -76,10 +79,6 @@ def test_codeblock_create(): # Use the treesitter frontend (the frontend doesn't support partial # expressions yet, but it gets an appropriate error) - # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by - # treesitter. - if sys.version_info < (3, 10): - return Config.get()._frontend = "treesitter" cb = CodeBlock.create("program test\nend program\n") assert isinstance(cb, TreeSitterCodeBlock) @@ -176,6 +175,9 @@ def test_abstract_methods(): assert "Use appropriate CodeBlock subclass" in str(err.value) +# TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by +# treesitter. +@min_version_3_10 def test_codeblock_get_fortran_lines(): ''' Test the get_fortran_lines method for fparser and treesiteer codeblocks. @@ -190,10 +192,6 @@ def test_codeblock_get_fortran_lines(): assert "subroutine mytest" in block.get_fortran_lines() assert "end subroutine" in block.get_fortran_lines() - # TODO #3416: Skip treesitter tests below 3.10 as they're unsupported by - # treesitter. - if sys.version_info < (3, 10): - return tree = FortranTreeSitterReader().generate_parse_tree_from_source(code) block = TreeSitterCodeBlock(tree, CodeBlock.Structure.STATEMENT) assert isinstance(block.get_fortran_lines(), list) diff --git a/src/psyclone/tests/utilities.py b/src/psyclone/tests/utilities.py index 0fb780beac..169441cfed 100644 --- a/src/psyclone/tests/utilities.py +++ b/src/psyclone/tests/utilities.py @@ -663,3 +663,9 @@ def make_external_module(monkeypatch, # that it will be found when the named module is requested. mman = ModuleManager.get() monkeypatch.setitem(mman._modules, mod_name, minfo) + + +# ============================================================================ +min_version_3_10 = pytest.mark.skipif( + sys.version_info < (3, 10), reason="tests require python 3.10 or higher" +) From 0ad4e110fe903a3b1798632eda9be74768bcb1e8 Mon Sep 17 00:00:00 2001 From: Andrew Porter Date: Tue, 28 Apr 2026 16:09:33 +0100 Subject: [PATCH 10/10] #3408 update changelog --- changelog | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/changelog b/changelog index 24a15f5876..56d32e873b 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,7 @@ + 12) PR #3408 for #2812. Updates the Min/Max to code transformations so + that they use the datatype of their arguments rather than assuming real. + Also skips treesitter tests for Python < 3.10. + 11) PR #3414 for #3279. Update the lists of exclusions to improve GPU performance for NEMO.