Skip to content

Commit 336e422

Browse files
authored
Merge pull request #186 from rjleveque/fullpath_import
new clawutil.util module containing fullpath_import
2 parents 2f660f7 + c3be67e commit 336e422

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

src/python/clawutil/util.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
r"""
2+
clawutil.util Module `$CLAW/clawutil/src/python/clawutil/util.py`
3+
4+
Provides general utility functions.
5+
6+
:Functions:
7+
8+
- fullpath_import: import a module using its full path
9+
10+
"""
11+
12+
import os, sys, importlib
13+
from pathlib import Path
14+
15+
16+
def fullpath_import(fullpath, verbose=False):
17+
"""
18+
Return a module imported from a full path name, e.g. if you have
19+
a personal enhanced version of the geoclaw topotools module at
20+
/full/path/to/topotools.py then instead of:
21+
22+
from clawpack.geoclaw import topotools
23+
24+
use:
25+
26+
from clawpack.clawutil.util import fullpath_import
27+
topotools = fullpath_import('/full/path/to/topotools.py')
28+
29+
Relative imports also work, e.g.
30+
31+
topotools = fullpath_import('../topotools.py')
32+
33+
To reload the module if you make changes to it, use this function again
34+
(rather than using importlib.reload).
35+
36+
Input `fullpath` can also be a `pathlib.Path` object instead of a string.
37+
38+
If `fullpath` is a string that starts with `$`, then the path is assumed
39+
to start with an environment variable and this is resolved, if possible,
40+
from `os.environ`. For example, this works:
41+
42+
setrun_file = '$CLAW/amrclaw/examples/advection_2d_swirl/setrun.py'
43+
setrun = util.fullpath_import(setrun_file)
44+
45+
It also expands `~` and `~user` constructs and resolves symlinks.
46+
"""
47+
48+
# expand any environment variables:
49+
fullpath = os.path.expandvars(fullpath)
50+
51+
# convert to a Path object if necessary, expand user prefix `~`,
52+
# and convert to absolute path, resolving any symlinks:
53+
fullPath = Path(fullpath).expanduser().resolve()
54+
55+
assert fullPath.suffix == '.py', '*** Expecting path to .py file'
56+
57+
fname = fullPath.name # should be modname.py
58+
modname = fullPath.stem # without extension
59+
60+
spec = importlib.util.spec_from_file_location(modname, fullPath)
61+
module = importlib.util.module_from_spec(spec)
62+
spec.loader.exec_module(module)
63+
sys.modules[modname] = module
64+
if verbose:
65+
print('loaded module from file: ',module.__file__)
66+
return module

0 commit comments

Comments
 (0)