f90nml icon indicating copy to clipboard operation
f90nml copied to clipboard

Parsing error using array assignment in namelist

Open Cory-Kramer opened this issue 3 years ago • 4 comments

One of the namelists I am trying to parse using f90nml contains an array assignment of the following syntax

&example
  arr(1:2)%foo =   1.0,   2.0
  arr(1:2)%bar =   3.0,   4.0
/

If I try to read/parse this namelist

import f90nml
f90nml.reads('''
&example
  arr(1:2)%foo =   1.0,   2.0
  arr(1:2)%bar =   3.0,   4.0
/
''')

I will get the following error

Traceback (most recent call last):
  File "<pyshell#1>", line 5, in <module>
    ''')
  File "C:\Python\Python37-64\lib\site-packages\f90nml\__init__.py", line 47, in reads
    return parser.reads(nml_string)
  File "C:\Python\Python37-64\lib\site-packages\f90nml\parser.py", line 280, in reads
    return self._readstream(iter(nml_string.splitlines()))
  File "C:\Python\Python37-64\lib\site-packages\f90nml\parser.py", line 359, in _readstream
    patch_nml=grp_patch
  File "C:\Python\Python37-64\lib\site-packages\f90nml\parser.py", line 459, in _parse_variable
    assert v_idx_bounds[0][1] - v_idx_bounds[0][0] == 1
AssertionError

Cory-Kramer avatar Mar 31 '21 17:03 Cory-Kramer

Looks like broadcasting to fields of arrays of derived types is not currently working.

This does work:

&example
    arr(1)%foo = 1.0, 2.0
    arr(1)%bar = 3.0, 4.0
    arr(2)%foo = 1.0, 2.0
    arr(2)%bar = 3.0, 4.0
/

but your example does not.

I will have a look, thanks for reporting it.

marshallward avatar Mar 31 '21 17:03 marshallward

I realize I was unclear on what your example was supposed to produce. This is probably closer to what you were expecting:

&example
    arr(1)%foo = 1.0
    arr(1)%bar = 3.0
    arr(2)%foo = 2.0
    arr(2)%bar = 4.0
/

At first I thought there may be some ambiguity about whether foo and bar are arrays or scalars, but it seems GFortran rejects namelist records of arrays in arrays. Attempting to read your example into an array of arr containing foo and bar arrays gives this error:

Fortran runtime error: Multiple sub-objects with non-zero rank in namelist object arr%foo

Intel gives a more vague error, but otherwise also objects to reading such a record.

Also just to clarify: there is no issue with arrays of derived types containing arrays. This seems to have more to do with limitations of the namelist record syntax.

I can't find where this is explained in the language standard, but I'm guessing that interpretation in my previous comment is wrong, and the one in this comment is correct: if the derived type is an array, then we can assume its fields to be scalars.

marshallward avatar Apr 05 '21 20:04 marshallward

In the real/production code that I modified to create the above example foo and bar are both scalar types, specifically integer.

Cory-Kramer avatar Apr 06 '21 14:04 Cory-Kramer

It looks like I made an absolute mess of derived type array handling, so I don't know if there's a quick fix here. Aside from the usual problems, there's a very strong preference to handling foo as an array, rather than scattering the values across elements of arr(:).

I'll try to find a bit of time to get it working, but no idea when it will get done. Apologies if you're working under some kind of time limit here.

marshallward avatar Apr 06 '21 15:04 marshallward