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.