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
« 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__
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
19urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
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')
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}'
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()
38 builder = buildinfo[:40]
39 if '|' in buildinfo:
40 sects = buildinfo.split('|')
41 if len(sects) > 1:
42 builder = sects[1].strip()
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 }
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
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 []
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))
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")
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)
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)
112########
113## for comparing current with remote version
114########
115VERSION_URL='https://raw.githubusercontent.com/xraypy/xraylarch/gh-pages/version.txt'
117VersionStatus = namedtuple('VersionStatus', ('update_available',
118 'local_version',
119 'remote_version',
120 'message'))
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#========================"""
129LATEST_MESSAGE = """Larch version {local_version:s} is up to date."""
131def check_larchversion():
132 "check version, return VersionStatus tuple"
133 local_version = __release_version__
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)