1# https://pyrocko.org - GPLv3 

2# 

3# The Pyrocko Developers, 21st Century 

4# ---|P------/S----------~Lg---------- 

5 

6 

7import sys 

8import os.path as op 

9from importlib import import_module 

10import logging 

11 

12logger = logging.getLogger('pyrocko.deps') 

13 

14 

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} 

32 

33 

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']) 

38 

39 

40def dependencies(group): 

41 

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 

51 

52 return d 

53 

54 

55def str_dependencies(): 

56 lines = [] 

57 lines.append('dependencies:') 

58 for group in ['required', 'optional']: 

59 lines.append(' %s:' % group) 

60 

61 for package, version in dependencies(group).items(): 

62 lines.append(' %s: %s' % ( 

63 package, 

64 version or 'N/A')) 

65 

66 return '\n'.join(lines) 

67 

68 

69def print_dependencies(): 

70 print(str_dependencies()) 

71 

72 

73class MissingPyrockoDependency(ImportError): 

74 pass 

75 

76 

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] 

82 

83 raise MissingPyrockoDependency(''' 

84 

85Missing Pyrocko requirement: %s 

86 

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: 

92 

93 %s 

94''' % ( 

95 package_name, 

96 package_name, 

97 package_name, 

98 module_name, 

99 str(e))) from None 

100 

101 

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] 

107 

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))) 

114 

115 return None 

116 

117 

118def require_all(group): 

119 for (_, module_name, _) in _pyrocko_deps[group]: 

120 require(module_name) 

121 

122 

123def find_pyrocko_installations(): 

124 found = [] 

125 seen = set() 

126 orig_sys_path = list(sys.path) 

127 while sys.path: 

128 

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 '?') 

136 

137 found.append(x) 

138 seen.add(dpath) 

139 

140 del sys.modules['pyrocko'] 

141 del sys.modules['pyrocko.info'] 

142 except (ImportError, AttributeError): 

143 pass 

144 

145 sys.path.pop(0) 

146 

147 sys.path = orig_sys_path 

148 return found 

149 

150 

151def str_installations(found): 

152 lines = [ 

153 'Python library path (sys.path): \n %s\n' % '\n '.join(sys.path)] 

154 

155 dates = sorted([xx[0] for xx in found]) 

156 i = 1 

157 

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)' 

163 

164 if installed_date == dates[-1]: 

165 oldnew = ' (newest)' 

166 

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)) 

179 

180 i += 1 

181 

182 return '\n'.join(lines) 

183 

184 

185def print_installations(): 

186 found = find_pyrocko_installations() 

187 print(str_installations(found)) 

188 

189 

190if __name__ == '__main__': 

191 print_dependencies() 

192 print() 

193 print_installations()