Coverage for larch/version.py: 24%

99 statements  

« prev     ^ index     » next       coverage.py v7.6.0, created at 2024-10-16 21:04 +0000

1#!/usr/bin/env python 

2"""Version information""" 

3 

4__release_version__ = '0.9.81' 

5__date__ = '2024-September-20' 

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

7 

8from ._version import __version__, __version_tuple__ 

9 

10import sys 

11from collections import namedtuple 

12from packaging.version import parse as ver_parse 

13import importlib 

14import urllib3 

15import requests 

16import numpy 

17import scipy 

18import matplotlib 

19import lmfit 

20 

21urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) 

22 

23# libraries whose versions might be interesting to know 

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

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

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

27 'asteval', 'wx', 'wxmplot') 

28 

29def version_data(with_libraries=False): 

30 "get version data" 

31 vinf = sys.version_info 

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

33 

34 buildinfo = sys.version 

35 if '\n' in buildinfo: 

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

37 if buildinfo.startswith(pyvers): 

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

39 

40 builder = buildinfo[:40] 

41 if '|' in buildinfo: 

42 sects = buildinfo.split('|') 

43 if len(sects) > 1: 

44 builder = sects[1].strip() 

45 

46 vdat = {'release version': __release_version__, 

47 'release date': __date__, 

48 'development version': __version__, 

49 'authors': __authors__, 

50 'python version': pyvers, 

51 'python builder': builder, 

52 'python sysversion': sys.version, 

53 } 

54 

55 if with_libraries: 

56 for modname in LIBS_VERSIONS: 

57 vers = "not installed" 

58 if modname not in sys.modules: 

59 try: 

60 importlib.import_module(modname) 

61 except: 

62 pass 

63 if modname in sys.modules: 

64 mod = sys.modules[modname] 

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

66 if vers is None: 

67 vers = getattr(mod, 'version', 

68 'unknown version') 

69 vdat[modname] = vers 

70 return vdat 

71 

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

73 "return startup banner" 

74 if show_libraries is None: 

75 show_libraries = LIBS_VERSIONS if with_libraries else [] 

76 

77 vdat = version_data(with_libraries=True) 

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

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

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

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

82 libline = [] 

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

84 if key in show_libraries: 

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

86 if len(libline) > 3: 

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

88 libline = [] 

89 if len(libline) > 0: 

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

91 

92 if len(show_libraries) < 10: 

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

94 

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

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

97 lines.insert(0, border) 

98 lines.append(border) 

99 return '\n'.join(lines) 

100 

101def show_version(): 

102 vdat = version_data(with_libraries=True) 

103 out = [] 

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

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

106 return '\n'.join(out) 

107 

108 

109######## 

110## for comparing current with remote version 

111######## 

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

113 

114VersionStatus = namedtuple('VersionStatus', ('update_available', 

115 'local_version', 

116 'remote_version', 

117 'message')) 

118 

119UPDATE_MESSAGE = """#=== Update Available === 

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

121To update the latest version run 

122 larch -u 

123from a Command Window or Terminal. 

124#========================""" 

125 

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

127 

128def check_larchversion(): 

129 "check version, return VersionStatus tuple" 

130 local_version = __release_version__ 

131 

132 try: 

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

134 except: 

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

136 remote_version = '0.9.001' 

137 if req.status_code == 200: 

138 try: 

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

140 line = line.strip() 

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

142 remote_version = line 

143 break 

144 except: 

145 pass 

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

147 message = UPDATE_MESSAGE if update_available else LATEST_MESSAGE 

148 message = message.format(remote_version=remote_version, 

149 local_version=local_version) 

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