1# https://pyrocko.org - GPLv3
2#
3# The Pyrocko Developers, 21st Century
4# ---|P------/S----------~Lg----------
7import sys
8import os.path as op
9from importlib import import_module
10import logging
12logger = logging.getLogger('pyrocko.deps')
15_pyrocko_deps = {
16 'required': [
17 ('python', 'sys', lambda x: '.'.join(map(str, x.version_info[:3]))),
18 ('pyyaml', 'yaml', '__version__'),
19 ('numpy', 'numpy', '__version__'),
20 ('scipy', 'scipy', '__version__'),
21 ('matplotlib', 'matplotlib', '__version__'),
22 ('requests', 'requests', '__version__'),
23 ],
24 'optional': [
25 ('PyQt5', 'PyQt5.Qt', 'PYQT_VERSION_STR'),
26 ('PyQtWebEngine', 'PyQt5.QtWebEngine', 'PYQT_WEBENGINE_VERSION_STR'),
27 ('vtk', 'vtk', 'VTK_VERSION'),
28 ('pyserial', 'serial', '__version__'),
29 ('kite', 'kite', '__version__'),
30 ],
31}
34_module_to_package_name = dict(
35 (module_name, package_name)
36 for (package_name, module_name, _)
37 in _pyrocko_deps['required'] + _pyrocko_deps['optional'])
40def dependencies(group):
42 d = {}
43 for (package_name, module_name, version_attr) in _pyrocko_deps[group]:
44 try:
45 mod = import_module(module_name)
46 d[package_name] = getattr(mod, version_attr) \
47 if isinstance(version_attr, str) \
48 else version_attr(mod)
49 except ImportError:
50 d[package_name] = None
52 return d
55def str_dependencies():
56 lines = []
57 lines.append('dependencies:')
58 for group in ['required', 'optional']:
59 lines.append(' %s:' % group)
61 for package, version in dependencies(group).items():
62 lines.append(' %s: %s' % (
63 package,
64 version or 'N/A'))
66 return '\n'.join(lines)
69def print_dependencies():
70 print(str_dependencies())
73class MissingPyrockoDependency(ImportError):
74 pass
77def require(module_name):
78 try:
79 return import_module(module_name)
80 except ImportError as e:
81 package_name = _module_to_package_name[module_name]
83 raise MissingPyrockoDependency('''
85Missing Pyrocko requirement: %s
87The Python package '%s' is required to run this program, but it doesn't seem to
88be available or an error occured while importing it. Use your package manager
89of choice (apt / yum / conda / pip) to install it. To verify that '%s' is
90available in your Python environment, check that "python -c \'import %s\'"
91exits without error. The original error was:
93 %s
94''' % (
95 package_name,
96 package_name,
97 package_name,
98 module_name,
99 str(e))) from None
102def import_optional(module_name, needed_for):
103 try:
104 return import_module(module_name)
105 except ImportError as e:
106 package_name = _module_to_package_name[module_name]
108 logger.info(
109 'Optional Pyrocko dependency "%s" is not available '
110 '(needed for %s): %s' % (
111 package_name,
112 needed_for,
113 str(e)))
115 return None
118def require_all(group):
119 for (_, module_name, _) in _pyrocko_deps[group]:
120 require(module_name)
123def find_pyrocko_installations():
124 found = []
125 seen = set()
126 orig_sys_path = list(sys.path)
127 while sys.path:
129 try:
130 import pyrocko
131 dpath = op.dirname(op.abspath(pyrocko.__file__))
132 if dpath not in seen:
133 x = (pyrocko.installed_date, dpath,
134 pyrocko.long_version,
135 pyrocko.src_path if hasattr(pyrocko, 'src_path') else '?')
137 found.append(x)
138 seen.add(dpath)
140 del sys.modules['pyrocko']
141 del sys.modules['pyrocko.info']
142 except (ImportError, AttributeError):
143 pass
145 sys.path.pop(0)
147 sys.path = orig_sys_path
148 return found
151def str_installations(found):
152 lines = [
153 'Python library path (sys.path): \n %s\n' % '\n '.join(sys.path)]
155 dates = sorted([xx[0] for xx in found])
156 i = 1
158 for (installed_date, installed_path, long_version, src_path) in found:
159 oldnew = ''
160 if len(dates) >= 2:
161 if installed_date == dates[0]:
162 oldnew = ' (oldest)'
164 if installed_date == dates[-1]:
165 oldnew = ' (newest)'
167 lines.append('''Pyrocko installation #%i %s:
168 date installed: %s%s
169 version: %s
170 path: %s
171 src path: %s
172''' % (
173 i, '(used)' if i == 1 else '(not used)',
174 installed_date,
175 oldnew,
176 long_version,
177 installed_path,
178 src_path))
180 i += 1
182 return '\n'.join(lines)
185def print_installations():
186 found = find_pyrocko_installations()
187 print(str_installations(found))
190if __name__ == '__main__':
191 print_dependencies()
192 print()
193 print_installations()