Skip to content

Commit e9a27e7

Browse files
committed
Update README about magics. Add pyenv helper script.
1 parent 2844f15 commit e9a27e7

File tree

3 files changed

+54
-1
lines changed

3 files changed

+54
-1
lines changed

README.md

+17-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ Mini blog to myself about the technical steps to get a python development enviro
88
- [PyEnv](#pyenv)
99
- [Install / Update](#install--update)
1010
- [Activate on demand](#activate-on-demand)
11+
- [Avoiding magic 🔮](#avoiding-magic-)
1112
- [List Versions you **CAN** install](#list-versions-you-can-install)
1213
- [List Versions that **ARE** installed](#list-versions-that-are-installed)
1314
- [Check and Activate a Version](#check-and-activate-a-version)
@@ -48,11 +49,26 @@ brew install pyenv
4849
4950
## Activate on demand
5051

51-
This causes the least magic 🔮 and you have better control over what is activated and when.
52+
This causes the least magic 🔮* and you have better control over what is activated and when.
5253
```sh
5354
eval "$(pyenv init --path)"
5455
```
5556

57+
### Avoiding magic 🔮
58+
59+
60+
61+
[![The Python environmental protection agency wants to seal it in a cement chamber, with pictorial messages to future civilizations warning them about the danger of using sudo to install random Python packages.](assets/xkcd_1987_python_environment_2x.png)](https://xkcd.com/1987/)
62+
63+
> __*magic 🔮__ --> refers to `pip install poetry` or `pip install awscli` could resolve to installing it into **ANY** of **MANY** different python versions that might exist on your `PATH` and this all depends on the order they resolve.
64+
>
65+
> So when trying to upgrade it can get problematic...
66+
>
67+
> For example you install `awscli` into `homebrew/python3.8` but then `homebrew upgrade python3` and that now resolves to `hombrew/python3.9`.
68+
> `awscli` is still resolving first on `PATH` but `pip install --upgrade awscli` is pointing to `homebrew/python3.9`.
69+
>
70+
> The main way to avoid this completely and over the top is to use the `python3 -m pip install --upgrade awscli` format of the command, but use the absolute path to the version of python you need like ``
71+
5672
## List Versions you **CAN** install
5773

5874
```sh
109 KB
Loading

latest_penv_versions.py

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Standard Library
2+
import subprocess
3+
from itertools import groupby
4+
from pathlib import Path
5+
6+
7+
def update_pyenv():
8+
"""Update with latest information."""
9+
PYENV_HOME = Path.home() / ".pyenv"
10+
subprocess.run("git pull", capture_output=True, shell=True, text=True, cwd=PYENV_HOME)
11+
12+
13+
def tidy_versions():
14+
# Get all available versions
15+
result = subprocess.run("pyenv install --list", capture_output=True, shell=True, text=True)
16+
17+
# Get all python versions that are only X.Y.Z format and only digits. No dev or alpha versions etc
18+
return {
19+
pyversion.strip(): tuple([int(d) for d in pyversion.strip().split(".")])
20+
for pyversion in result.stdout.strip().split("\n")
21+
if pyversion.strip().startswith("3.") and all([d.isdigit() for d in pyversion.strip().split(".")])
22+
}
23+
24+
25+
def max_patched_versions():
26+
# Group tuples by the minor version number
27+
grouped_versions = groupby(tidy_versions().values(), lambda v: v[1])
28+
# Tuple sort to get the largest within each group
29+
return [
30+
".".join([str(n) for n in list(v)]) # Convert tuple back to dot formatted string
31+
for v in sorted([max(g, key=lambda x: x) for k, g in grouped_versions], reverse=True)
32+
]
33+
34+
35+
if __name__ == "__main__":
36+
update_pyenv()
37+
print("\n".join([f"pyenv install {v}" for v in max_patched_versions()[:3]]))

0 commit comments

Comments
 (0)