Coverage for /Users/Newville/Codes/xraylarch/larch/version.py: 24%

105 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-11-09 10:08 -0600

1#!/usr/bin/env python 

2"""Version information""" 

3__date__ = '2023-Oct-03' 

4__release_version__ = '0.9.72' 

5__authors__ = "M. Newville, M. Koker, M. Rovezzi, B. Ravel, and others" 

6from ._version import __version__, __version_tuple__ 

7 

8import sys 

9from collections import namedtuple 

10from packaging.version import parse as ver_parse 

11import importlib 

12import urllib3 

13import requests 

14import numpy 

15import scipy 

16import matplotlib 

17import lmfit 

18 

19urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 

20 

21# libraries whose versions might be interesting to know 

22LIBS_VERSIONS = ('numpy', 'scipy', 'matplotlib', 'h5py', 'sklearn', 'skimage', 

23 'sqlalchemy', 'fabio', 'pyFAI', 'PIL', 'imageio', 'silx', 

24 'tomopy', 'pymatgen.core', 'numdifftools', 'xraydb', 'lmfit', 

25 'asteval', 'wx', 'wxmplot') 

26 

27def version_data(with_libraries=False): 

28 "get version data" 

29 vinf = sys.version_info 

30 pyvers = f'{vinf.major:d}.{vinf.minor:d}.{vinf.micro:d}' 

31 

32 buildinfo = sys.version 

33 if '\n' in buildinfo: 

34 buildinfo = buildinfo.split('\n', maxsplit=1)[0].strip() 

35 if buildinfo.startswith(pyvers): 

36 buildinfo = buildinfo.replace(pyvers, '').strip() 

37 

38 builder = buildinfo[:40] 

39 if '|' in buildinfo: 

40 sects = buildinfo.split('|') 

41 if len(sects) > 1: 

42 builder = sects[1].strip() 

43 

44 vdat = {'release version': __release_version__, 

45 'release date': __date__, 

46 'development version': __version__, 

47 'authors': __authors__, 

48 'python version': pyvers, 

49 'python builder': builder, 

50 'python sysversion': sys.version, 

51 } 

52 

53 if with_libraries: 

54 for modname in LIBS_VERSIONS: 

55 vers = "not installed" 

56 if modname not in sys.modules: 

57 try: 

58 importlib.import_module(modname) 

59 except: 

60 pass 

61 if modname in sys.modules: 

62 mod = sys.modules[modname] 

63 vers = getattr(mod, '__version__', None) 

64 if vers is None: 

65 vers = getattr(mod, 'version', 

66 'unknown version') 

67 vdat[modname] = vers 

68 return vdat 

69 

70def make_banner(with_libraries=False, show_libraries=None): 

71 "return startup banner" 

72 if show_libraries is None: 

73 show_libraries = LIBS_VERSIONS if with_libraries else [] 

74 

75 vdat = version_data(with_libraries=True) 

76 lines = [f"Larch {vdat['release version']}, released {vdat['release date']}"] 

77 if vdat['development version'] != vdat['release version']: 

78 lines.append(f"development version: {vdat['development version']}") 

79 lines.append(f"Python {vdat['python version']}, {vdat['python builder']}") 

80 libline = [] 

81 for key, val in vdat.items(): 

82 if key in show_libraries: 

83 libline.append(f"{key:s}: {val}") 

84 if len(libline) > 3: 

85 lines.append(', '.join(libline)) 

86 libline = [] 

87 if len(libline) > 0: 

88 lines.append(', '.join(libline)) 

89 

90 if len(show_libraries) < 10: 

91 lines.append('use `print(show_version())` for detailed versions') 

92 try: 

93 from wxmplot.interactive import get_wxapp 

94 app = get_wxapp() 

95 except SystemExit: 

96 lines.append("Warning: cannot get wxApp for plotting, GUI components") 

97 

98 linelen = max([len(line) for line in lines]) 

99 border = '='*min(99, max(linelen, 25)) 

100 lines.insert(0, border) 

101 lines.append(border) 

102 return '\n'.join(lines) 

103 

104def show_version(): 

105 vdat = version_data(with_libraries=True) 

106 out = [] 

107 for key, val in vdat.items(): 

108 out.append(f"{key:20s}: {val}") 

109 return '\n'.join(out) 

110 

111 

112######## 

113## for comparing current with remote version 

114######## 

115VERSION_URL='https://raw.githubusercontent.com/xraypy/xraylarch/gh-pages/version.txt' 

116 

117VersionStatus = namedtuple('VersionStatus', ('update_available', 

118 'local_version', 

119 'remote_version', 

120 'message')) 

121 

122UPDATE_MESSAGE = """#=== Update Available === 

123Larch version {remote_version:s} is available. Your version is currently {local_version:s}. 

124To update the latest version run 

125 larch -u 

126from a Command Window or Terminal. 

127#========================""" 

128 

129LATEST_MESSAGE = """Larch version {local_version:s} is up to date.""" 

130 

131def check_larchversion(): 

132 "check version, return VersionStatus tuple" 

133 local_version = __release_version__ 

134 

135 try: 

136 req = requests.get(VERSION_URL, verify=False, timeout=3.10) 

137 except: 

138 return VersionStatus(False, local_version, 'unknown', 'offline') 

139 remote_version = '0.9.001' 

140 if req.status_code == 200: 

141 try: 

142 for line in req.text.split('\n'): 

143 line = line.strip() 

144 if not line.startswith('#'): 

145 remote_version = line 

146 break 

147 except: 

148 pass 

149 update_available = ver_parse(remote_version) > ver_parse(local_version) 

150 message = UPDATE_MESSAGE if update_available else LATEST_MESSAGE 

151 message = message.format(remote_version=remote_version, 

152 local_version=local_version) 

153 return VersionStatus(update_available,local_version, remote_version, message)