fparser
fparser copied to clipboard
[F2008] F2008 constructs/statements don't work in blocks
While looking at implementing #320, I discovered that F2008-specific features don't work inside blocks. The following two tests demonstrate this for error stop:
def test_functional3(f2008_parser):
'''Test error-stop-stmt is matched in a do loop.'''
tree = f2008_parser(get_reader('''\
do
error stop
end do
'''))
assert walk(tree, Error_Stop_Stmt)
assert 'ERROR STOP' in str(tree)
def test_functional4(f2008_parser):
'''Test error-stop-stmt is matched in an if block.'''
tree = f2008_parser(get_reader('''\
if (.true.) then
error stop
end if
'''))
assert walk(tree, Error_Stop_Stmt)
assert 'ERROR STOP' in str(tree)
Both raising:
E fparser.two.utils.FortranSyntaxError: at line 2
E >>>error stop
src/fparser/two/Fortran2003.py:241: FortranSyntaxError
I think this is because the modified F2003 classes (for example, Action_Stmt here) don't get their subclasses updated. Here's some output from putting a breakpoint() just before https://github.com/stfc/fparser/blob/58f903d011642ea76738074203257d6cda225f75/src/fparser/two/parser.py#L161
(Pdb) p "Error_Stop_Stmt" in dict(f2008_cls_members)["Action_Stmt"].subclass_names
True
(Pdb) p "Error_Stop_Stmt" in dict(f2008_cls_members)["Action_Stmt"].subclasses
False
I think this is related to #297. Adding the tests in my first comment and running them like:
pytest src/fparser/two/tests/fortran2008/test_error_stop_stmt_r856.py::test_functional3
works but
pytest -k test_functional3
fails. This is because the first only finds that one test and runs it, while the second finds all tests and only runs the selected one.
To demonstrate, try the following test:
def test_error_stmt_exists(f2008_create):
assert "Error_Stop_Stmt" in [x.__name__ for x in Base.subclasses["Execution_Part_Construct"]]
and see the difference between
# Passes
pytest src/fparser/two/tests/fortran2008/test_error_stop_stmt_r856.py::test_error_stmt_exists
# Fails
pytest -k test_error_stmt_exists
I suspect the solution requires #191 in order to remove all the global state as creating a parser modifies the class objects themselves, as opposed to instances of them.
@ZedThree We merged the block and critical construct support PR. Can this be closed now?
Yes, looks like this works now