f90wrap
f90wrap copied to clipboard
Handling reserved Python words in f90wrap
@jameskermode I'm working with a legacy code that unfortunately has a derived type called "Size" (and for other reasons, I'm not allowed to rename it). Unfortunately, f90wrap does not seem to be able to auto-rename size to size_bn (as suggested by f2py).
I got far enough into f90wrap source to identify what appears to be a bug in f90wrapgen.py, line 785 ish. The dictionary key for self.types in RenameReservedWords still retains the name size, but the extra_uses invocation is
extra_uses[self.types[t.name].mod_name] = [t.name]
The entry t.name is not present in self.types, so I added a try/except to use t.orig_name on if the first one fails; would appreciate some guidance on whether it should also appear on the right hand side? I haven't fully tracked it down..
I tried this fix and it proceeded all the way to invoking f2py, at which point f2py complains that size_bn is being used before it is declared.. any help/pointers would be appreciated! I'm mostly stuck at figuring out where the derived type is renamed in the module before being compiled; I can "see" the individual elements in the derived type being renamed.
I obtained a working solution by having f90wrap's fortran code generator completely ignore the renaming of types with reserved keywords (supposedly handled by f2py) and using .orig_name everywhere; what worked is when I got f90wrap's pywrapgen to implement the renaming of classes. However, I had to manually change source code for pywrapgen.py in the beginning of write_dt_wrappers to be
def write_dt_wrappers(self, node, el, properties):
import numpy
name_map = numpy.f2py.crackfortran.badnames
if ft.strip_type(el.type) in name_map:
cls_name = name_map[ft.strip_type(el.type)]
Then normalize the class name after filtering out reserved keywords
cls_name = normalise_class_name(cls_name, self.class_names)
That looks like an OK solution. Does f90wrap still pass all the regression tests? (make test in examples/) If so we could make that change in master. If you would be willing to make a PR which does this, and also adds a new test that would have shown the problem that would be great!
Sure, I can make the PR after running the tests. Fingers crossed...
Edit: nvm, found that I had to change python to python3 in the Makefile
@jameskermode it seems that some of the tests fail on master: the arrayderivedtype test failed on the master branch (i.e., without any of my changes) with the following error
Traceback (most recent call last):
File "tests.py", line 23, in <module>
import arrayderivedtype
File "/Users/ananthsridharan/codes/f90wrap/examples/arrayderivedtypes/arrayderivedtype.py", line 2, in <module>
import _arrayderivedtype
ImportError: No module named _arrayderivedtype
make[1]: *** [test] Error 1
make: *** [test] Error 2
so all the default tests passed with my changes (good). Added a new test on my fork and making it more complex. Still working out nesting derived types with reserved names and catching/replacing all reserved words in all possible instances. Will post a PR when I'm happy with it
@jameskermode I've submitted a PR with another test. There are edge cases like when a user creates an array of a derived type called size that start introducing ambiguity in the fortran compiler; this is a fortran error and I'm not accounting for those instances.