Can't include relative module within an IFO package's __init__.py
(Python 3 only)
I'm trying to define an IFO in a separate directory to pygwinc, but run it using pygwinc's __main__.py. My IFO is defined in a package within a directory called mydir. The structure looks like this:
$> tree mydir
mydir/
├── __init__.py
├── __main__.py
└── tmp
├── ifo.yaml
├── __init__.py
└── thing.py
__main__.py contains just a simple wrapper around pygwinc's __main__.py:
from gwinc.__main__ import main
if __name__ == "__main__":
main()
/tmp/__init__.py is the noise budget definition:
from .thing import test
from gwinc.ifo.noises import *
class MyIFO(nb.Budget):
name = 'My IFO'
noises = [
QuantumVacuum,
Seismic,
Newtonian,
SuspensionThermal,
CoatingBrownian,
CoatingThermoOptic,
SubstrateBrownian,
SubstrateThermoElastic,
ExcessGas,
]
/tmp/thing.py is just a module I want to define some useful functions in:
def test():
pass
/tmp/ifo.yaml is the YAML parameter file (can just copy aLIGO's for testing):
...
Including relative modules from within an IFO's __init__.py seems to cause an error:
$> cd /path/to/directory/containing/mydir
$> python -m mydir mydir/tmp
loading module path mydir/tmp...
Traceback (most recent call last):
File "/home/sean/Workspace/anaconda/envs/gwinc/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/home/sean/Workspace/anaconda/envs/gwinc/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/home/sean/Workspace/Repositories/pt-modelling/mydir/__main__.py", line 11, in <module>
main()
File "/home/sean/Workspace/Repositories/pygwinc/gwinc/__main__.py", line 100, in main
Budget, ifo, freq, plot_style = load_ifo(args.IFO)
File "/home/sean/Workspace/Repositories/pygwinc/gwinc/ifo/__init__.py", line 66, in load_ifo
mod, modpath = load_module(modname)
File "/home/sean/Workspace/Repositories/pygwinc/gwinc/util.py", line 32, in load_module
spec.loader.exec_module(mod)
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "mydir/tmp/__init__.py", line 1, in <module>
from .thing import test
ModuleNotFoundError: No module named 'tmp'
My workaround is to put everything in the IFO's __init__.py file, but this isn't very nice and kind of defeats the point of putting the IFO into a package and not just a module on the top level.
I guess this is caused by the way the module mydir/tmp is included by gwinc.util.load_module (via gwinc.ifo.load_ifo). Maybe this way of loading a module does not allow relative imports. Perhaps first adding the module to the $PATH would fix this.