Skip to content

Commit b96805f

Browse files
committed
Rework env check.
1 parent 13eeec8 commit b96805f

File tree

5 files changed

+164
-52
lines changed

5 files changed

+164
-52
lines changed

images/env_check.png

-489 KB
Loading

images/open_env_check_notebook.png

-552 KB
Loading

notebooks/0-check_your_env.ipynb

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@
1717
"name": "stdout",
1818
"output_type": "stream",
1919
"text": [
20-
"Using Python in /Users/stefanie/miniconda3/envs/pandas_workshop:\n",
21-
"\u001b[42m[ OK ]\u001b[0m Python is version 3.10.2 | packaged by conda-forge | (main, Mar 8 2022, 15:57:32) [Clang 11.1.0 ]\n",
22-
"\n",
20+
"\u001b[42m[ OK ]\u001b[0m Python\n",
2321
"\u001b[42m[ OK ]\u001b[0m jupyterlab\n",
2422
"\u001b[42m[ OK ]\u001b[0m matplotlib\n",
2523
"\u001b[42m[ OK ]\u001b[0m numpy\n",
@@ -31,7 +29,7 @@
3129
}
3230
],
3331
"source": [
34-
"from utils import run_env_check\n",
32+
"from check_env import run_env_check\n",
3533
"run_env_check()"
3634
]
3735
},
@@ -59,7 +57,7 @@
5957
"name": "python",
6058
"nbconvert_exporter": "python",
6159
"pygments_lexer": "ipython3",
62-
"version": "3.10.2"
60+
"version": "3.10.8"
6361
}
6462
},
6563
"nbformat": 4,

notebooks/check_env.py

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
"""Check the setup for the workshop."""
2+
3+
from functools import partial
4+
from packaging.version import Version
5+
import importlib
6+
import json
7+
import os
8+
import sys
9+
import yaml
10+
11+
12+
def _print_version_ok(item):
13+
"""
14+
Print an OK message for version check.
15+
16+
Parameters
17+
----------
18+
item : str
19+
The item being inspected (package, tool, etc.).
20+
"""
21+
print('\x1b[42m[ OK ]\x1b[0m', '%s' % item)
22+
23+
def _print_version_failure(item, req_version, version, failures):
24+
"""
25+
Print a failure message for version check.
26+
27+
Parameters
28+
----------
29+
item : str
30+
The item being inspected (package, tool, etc.).
31+
req_version : str
32+
The required version.
33+
version : str
34+
The version currently installed.
35+
failures : list
36+
The list of items currently failing the environment check.
37+
"""
38+
failures.append(item)
39+
if version:
40+
msg = '%s version %s is required, but %s installed.'
41+
values = (item, req_version, version)
42+
else:
43+
msg = '%s is not installed.'
44+
values = item
45+
print('\x1b[41m[FAIL]\x1b[0m', msg % values)
46+
47+
def run_env_check(raise_exc=False):
48+
"""
49+
Check that the packages we need are installed and, if necessary,
50+
whether the Python version is correct.
51+
52+
Parameters
53+
----------
54+
raise_exc : bool, default ``False``
55+
Whether to raise an `Exception` if any of the packages doesn't
56+
match the requirements (used for GitHub Action).
57+
"""
58+
59+
failures = []
60+
_print_failure = partial(_print_version_failure, failures=failures)
61+
62+
# read in the environment file and process versions
63+
with open('../environment.yml', 'r') as file:
64+
env = yaml.safe_load(file)
65+
66+
requirements = {}
67+
for line in env['dependencies']:
68+
try:
69+
if '>=' in line:
70+
pkg, versions = line.split('>=')
71+
if ',<=' in versions:
72+
version = versions.split(',<=')
73+
else:
74+
version = [versions, None]
75+
else:
76+
pkg, version = line.split('=')
77+
except ValueError:
78+
pkg, version = line, None
79+
if '-' in pkg:
80+
continue
81+
requirements[pkg.split('::')[-1]] = version
82+
83+
# check the python version, if provided
84+
try:
85+
required_version = requirements.pop('python')
86+
python_version = sys.version_info
87+
base_python_version = Version(
88+
f'{python_version.major}.{python_version.minor}.{python_version.micro}'
89+
)
90+
if isinstance(required_version, list):
91+
min_version, max_version = (
92+
Version(version_str) for version_str in required_version
93+
)
94+
if (
95+
min_version > base_python_version
96+
or (
97+
max_version and base_python_version > max_version
98+
)
99+
):
100+
print(f'Using Python at {sys.prefix}:\n-> {sys.version}')
101+
_print_failure(
102+
'Python',
103+
f'>= {min_version}{f" and <= {max_version}" if max_version else ""}',
104+
base_python_version
105+
)
106+
else:
107+
_print_version_ok('Python')
108+
else:
109+
for component, value in zip(
110+
['major', 'minor', 'micro'], required_version.split('.')
111+
):
112+
if getattr(python_version, component) != int(value):
113+
print(f'Using Python at {sys.prefix}:\n-> {sys.version}')
114+
_print_failure(
115+
'Python',
116+
required_version,
117+
f'{python_version.major}.{python_version.minor}'
118+
)
119+
break
120+
else:
121+
_print_version_ok('Python')
122+
except KeyError:
123+
pass
124+
125+
for pkg, req_version in requirements.items():
126+
try:
127+
mod = importlib.import_module(pkg)
128+
if req_version:
129+
version = mod.__version__
130+
installed_version = Version(version).base_version
131+
if isinstance(req_version, list):
132+
min_version, max_version = req_version
133+
if (
134+
installed_version < Version(min_version).base_version
135+
or (
136+
max_version and
137+
installed_version > Version(max_version).base_version
138+
)
139+
):
140+
_print_failure(
141+
pkg,
142+
f'>= {min_version}{f" and <= {max_version}" if max_version else ""}',
143+
version
144+
)
145+
continue
146+
elif Version(version).base_version != Version(req_version).base_version:
147+
_print_failure(pkg, req_version, version)
148+
continue
149+
_print_version_ok(pkg)
150+
except ImportError:
151+
_print_failure(pkg, req_version, None)
152+
153+
if failures and raise_exc:
154+
raise Exception(
155+
'Environment failed inspection due to incorrect versions '
156+
f'of {len(failures)} item(s): {", ".join(failures)}.'
157+
)
158+
159+
if __name__ == '__main__':
160+
print(f'Using Python at {sys.prefix}:\n-> {sys.version}')
161+
run_env_check(raise_exc=True)

notebooks/utils.py

Lines changed: 0 additions & 47 deletions
This file was deleted.

0 commit comments

Comments
 (0)