pystand 2.32__tar.gz → 2.34__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pystand-2.32/pystand.egg-info → pystand-2.34}/PKG-INFO +15 -12
- {pystand-2.32 → pystand-2.34}/README.md +13 -10
- {pystand-2.32 → pystand-2.34}/check-dist.py +2 -3
- {pystand-2.32 → pystand-2.34}/pyproject.toml +3 -8
- {pystand-2.32 → pystand-2.34/pystand.egg-info}/PKG-INFO +15 -12
- {pystand-2.32 → pystand-2.34}/pystand.egg-info/SOURCES.txt +2 -0
- {pystand-2.32 → pystand-2.34}/pystand.egg-info/requires.txt +1 -1
- pystand-2.34/pystand.egg-info/scm_file_list.json +10 -0
- pystand-2.34/pystand.egg-info/scm_version.json +8 -0
- {pystand-2.32 → pystand-2.34}/pystand.py +56 -55
- {pystand-2.32 → pystand-2.34}/.gitignore +0 -0
- {pystand-2.32 → pystand-2.34}/justfile +0 -0
- {pystand-2.32 → pystand-2.34}/pystand.egg-info/dependency_links.txt +0 -0
- {pystand-2.32 → pystand-2.34}/pystand.egg-info/entry_points.txt +0 -0
- {pystand-2.32 → pystand-2.34}/pystand.egg-info/top_level.txt +0 -0
- {pystand-2.32 → pystand-2.34}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pystand
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.34
|
|
4
4
|
Summary: Install Python versions from python-build-standalone project
|
|
5
5
|
Author-email: Mark Blakeney <mark.blakeney@bullet-systems.net>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -15,7 +15,7 @@ Requires-Dist: argparse-from-file
|
|
|
15
15
|
Requires-Dist: pygithub
|
|
16
16
|
Requires-Dist: certifi
|
|
17
17
|
Requires-Dist: filelock
|
|
18
|
-
Requires-Dist:
|
|
18
|
+
Requires-Dist: backports.zstd; python_version < "3.14"
|
|
19
19
|
|
|
20
20
|
## PYSTAND - Install Python Versions From The Python-Build-Standalone Project
|
|
21
21
|
[](https://pypi.org/project/pystand/)
|
|
@@ -172,7 +172,7 @@ options:
|
|
|
172
172
|
--purge-days PURGE_DAYS
|
|
173
173
|
cache YYYYMMDD release file lists and downloads for
|
|
174
174
|
this number of days after last version referencing
|
|
175
|
-
that release is removed. Default is
|
|
175
|
+
that release is removed. Default is 30 days.
|
|
176
176
|
--github-access-token GITHUB_ACCESS_TOKEN
|
|
177
177
|
optional Github access token. Can specify to reduce
|
|
178
178
|
rate limiting.
|
|
@@ -215,13 +215,13 @@ usage: pystand install [-h] [-r RELEASE] [-a] [-A] [--skip] [-f] [-s]
|
|
|
215
215
|
Install one, more, or all versions from a python-build-standalone release.
|
|
216
216
|
|
|
217
217
|
positional arguments:
|
|
218
|
-
version version to install. E.g. 3.
|
|
218
|
+
version version to install. E.g. 3.14 or 3.14.1
|
|
219
219
|
|
|
220
220
|
options:
|
|
221
221
|
-h, --help show this help message and exit
|
|
222
222
|
-r, --release RELEASE
|
|
223
223
|
install from specified python-build-standalone
|
|
224
|
-
YYYYMMDD release (e.g.
|
|
224
|
+
YYYYMMDD release (e.g. 20260807), default is latest
|
|
225
225
|
release
|
|
226
226
|
-a, --all install ALL versions from release
|
|
227
227
|
-A, --all-prerelease install ALL versions from release, including pre-
|
|
@@ -238,7 +238,8 @@ aliases: i
|
|
|
238
238
|
### Command `update`
|
|
239
239
|
|
|
240
240
|
```
|
|
241
|
-
usage: pystand update [-h] [-r RELEASE] [-a] [--skip] [-k]
|
|
241
|
+
usage: pystand update [-h] [-r RELEASE] [-a] [--pre-release] [--skip] [-k]
|
|
242
|
+
[version ...]
|
|
242
243
|
|
|
243
244
|
Update one, more, or all versions to another release.
|
|
244
245
|
|
|
@@ -248,9 +249,11 @@ positional arguments:
|
|
|
248
249
|
options:
|
|
249
250
|
-h, --help show this help message and exit
|
|
250
251
|
-r, --release RELEASE
|
|
251
|
-
update to specified YYYMMDD release (e.g.
|
|
252
|
+
update to specified YYYMMDD release (e.g. 20260807),
|
|
252
253
|
default is latest release
|
|
253
254
|
-a, --all update ALL versions
|
|
255
|
+
--pre-release update release version to a later superceding pre-
|
|
256
|
+
release
|
|
254
257
|
--skip skip the specified versions when updating all (only
|
|
255
258
|
can be specified with --all)
|
|
256
259
|
-k, --keep keep old version after updating (but only if different
|
|
@@ -276,7 +279,7 @@ options:
|
|
|
276
279
|
can be specified with --all)
|
|
277
280
|
-r, --release RELEASE
|
|
278
281
|
only remove versions if from specified YYYMMDD release
|
|
279
|
-
(e.g.
|
|
282
|
+
(e.g. 20260807)
|
|
280
283
|
|
|
281
284
|
aliases: r, rm
|
|
282
285
|
```
|
|
@@ -296,7 +299,7 @@ options:
|
|
|
296
299
|
-v, --verbose explicitly report why a version is not eligible for
|
|
297
300
|
update
|
|
298
301
|
-r, --release RELEASE
|
|
299
|
-
use specified YYYYMMDD release (e.g.
|
|
302
|
+
use specified YYYYMMDD release (e.g. 20260807) for
|
|
300
303
|
verbose compare, default is latest release
|
|
301
304
|
|
|
302
305
|
aliases: l
|
|
@@ -320,7 +323,7 @@ options:
|
|
|
320
323
|
-l, --list just list recent releases
|
|
321
324
|
-r, --release RELEASE
|
|
322
325
|
python-build-standalone YYYYMMDD release to show (e.g.
|
|
323
|
-
|
|
326
|
+
20260807), default is latest release
|
|
324
327
|
-a, --all show all available distributions for each version from
|
|
325
328
|
the release
|
|
326
329
|
|
|
@@ -387,7 +390,7 @@ positional arguments:
|
|
|
387
390
|
|
|
388
391
|
options:
|
|
389
392
|
-h, --help show this help message and exit
|
|
390
|
-
-p, --python PYTHON version of python to use, e.g. "3.
|
|
393
|
+
-p, --python PYTHON version of python to use, e.g. "3.14", default is
|
|
391
394
|
latest release version
|
|
392
395
|
```
|
|
393
396
|
|
|
@@ -405,7 +408,7 @@ positional arguments:
|
|
|
405
408
|
|
|
406
409
|
options:
|
|
407
410
|
-h, --help show this help message and exit
|
|
408
|
-
-p, --python PYTHON version of python to use, e.g. "3.
|
|
411
|
+
-p, --python PYTHON version of python to use, e.g. "3.14", default is
|
|
409
412
|
latest release version
|
|
410
413
|
```
|
|
411
414
|
|
|
@@ -153,7 +153,7 @@ options:
|
|
|
153
153
|
--purge-days PURGE_DAYS
|
|
154
154
|
cache YYYYMMDD release file lists and downloads for
|
|
155
155
|
this number of days after last version referencing
|
|
156
|
-
that release is removed. Default is
|
|
156
|
+
that release is removed. Default is 30 days.
|
|
157
157
|
--github-access-token GITHUB_ACCESS_TOKEN
|
|
158
158
|
optional Github access token. Can specify to reduce
|
|
159
159
|
rate limiting.
|
|
@@ -196,13 +196,13 @@ usage: pystand install [-h] [-r RELEASE] [-a] [-A] [--skip] [-f] [-s]
|
|
|
196
196
|
Install one, more, or all versions from a python-build-standalone release.
|
|
197
197
|
|
|
198
198
|
positional arguments:
|
|
199
|
-
version version to install. E.g. 3.
|
|
199
|
+
version version to install. E.g. 3.14 or 3.14.1
|
|
200
200
|
|
|
201
201
|
options:
|
|
202
202
|
-h, --help show this help message and exit
|
|
203
203
|
-r, --release RELEASE
|
|
204
204
|
install from specified python-build-standalone
|
|
205
|
-
YYYYMMDD release (e.g.
|
|
205
|
+
YYYYMMDD release (e.g. 20260807), default is latest
|
|
206
206
|
release
|
|
207
207
|
-a, --all install ALL versions from release
|
|
208
208
|
-A, --all-prerelease install ALL versions from release, including pre-
|
|
@@ -219,7 +219,8 @@ aliases: i
|
|
|
219
219
|
### Command `update`
|
|
220
220
|
|
|
221
221
|
```
|
|
222
|
-
usage: pystand update [-h] [-r RELEASE] [-a] [--skip] [-k]
|
|
222
|
+
usage: pystand update [-h] [-r RELEASE] [-a] [--pre-release] [--skip] [-k]
|
|
223
|
+
[version ...]
|
|
223
224
|
|
|
224
225
|
Update one, more, or all versions to another release.
|
|
225
226
|
|
|
@@ -229,9 +230,11 @@ positional arguments:
|
|
|
229
230
|
options:
|
|
230
231
|
-h, --help show this help message and exit
|
|
231
232
|
-r, --release RELEASE
|
|
232
|
-
update to specified YYYMMDD release (e.g.
|
|
233
|
+
update to specified YYYMMDD release (e.g. 20260807),
|
|
233
234
|
default is latest release
|
|
234
235
|
-a, --all update ALL versions
|
|
236
|
+
--pre-release update release version to a later superceding pre-
|
|
237
|
+
release
|
|
235
238
|
--skip skip the specified versions when updating all (only
|
|
236
239
|
can be specified with --all)
|
|
237
240
|
-k, --keep keep old version after updating (but only if different
|
|
@@ -257,7 +260,7 @@ options:
|
|
|
257
260
|
can be specified with --all)
|
|
258
261
|
-r, --release RELEASE
|
|
259
262
|
only remove versions if from specified YYYMMDD release
|
|
260
|
-
(e.g.
|
|
263
|
+
(e.g. 20260807)
|
|
261
264
|
|
|
262
265
|
aliases: r, rm
|
|
263
266
|
```
|
|
@@ -277,7 +280,7 @@ options:
|
|
|
277
280
|
-v, --verbose explicitly report why a version is not eligible for
|
|
278
281
|
update
|
|
279
282
|
-r, --release RELEASE
|
|
280
|
-
use specified YYYYMMDD release (e.g.
|
|
283
|
+
use specified YYYYMMDD release (e.g. 20260807) for
|
|
281
284
|
verbose compare, default is latest release
|
|
282
285
|
|
|
283
286
|
aliases: l
|
|
@@ -301,7 +304,7 @@ options:
|
|
|
301
304
|
-l, --list just list recent releases
|
|
302
305
|
-r, --release RELEASE
|
|
303
306
|
python-build-standalone YYYYMMDD release to show (e.g.
|
|
304
|
-
|
|
307
|
+
20260807), default is latest release
|
|
305
308
|
-a, --all show all available distributions for each version from
|
|
306
309
|
the release
|
|
307
310
|
|
|
@@ -368,7 +371,7 @@ positional arguments:
|
|
|
368
371
|
|
|
369
372
|
options:
|
|
370
373
|
-h, --help show this help message and exit
|
|
371
|
-
-p, --python PYTHON version of python to use, e.g. "3.
|
|
374
|
+
-p, --python PYTHON version of python to use, e.g. "3.14", default is
|
|
372
375
|
latest release version
|
|
373
376
|
```
|
|
374
377
|
|
|
@@ -386,7 +389,7 @@ positional arguments:
|
|
|
386
389
|
|
|
387
390
|
options:
|
|
388
391
|
-h, --help show this help message and exit
|
|
389
|
-
-p, --python PYTHON version of python to use, e.g. "3.
|
|
392
|
+
-p, --python PYTHON version of python to use, e.g. "3.14", default is
|
|
390
393
|
latest release version
|
|
391
394
|
```
|
|
392
395
|
|
|
@@ -1,13 +1,12 @@
|
|
|
1
|
-
#!/usr/bin/python
|
|
2
1
|
import re
|
|
3
2
|
import subprocess
|
|
4
3
|
import sys
|
|
5
4
|
|
|
6
5
|
import pystand
|
|
7
6
|
|
|
8
|
-
cmd = 'pystand show
|
|
7
|
+
cmd = 'pystand show --all'.split()
|
|
9
8
|
out = subprocess.run(cmd, capture_output=True, text=True).stdout
|
|
10
|
-
alldists =
|
|
9
|
+
alldists = {re.sub(r'.+"(.+)".*', r'\1', ln) for ln in out.splitlines()}
|
|
11
10
|
|
|
12
11
|
error = 0
|
|
13
12
|
for mach, dist in pystand.DISTRIBUTIONS.items():
|
|
@@ -20,7 +20,7 @@ dependencies = [
|
|
|
20
20
|
"pygithub",
|
|
21
21
|
"certifi",
|
|
22
22
|
"filelock",
|
|
23
|
-
"
|
|
23
|
+
"backports.zstd; python_version < '3.14'",
|
|
24
24
|
]
|
|
25
25
|
|
|
26
26
|
[[project.authors]]
|
|
@@ -45,13 +45,8 @@ ignore_missing_imports = true
|
|
|
45
45
|
|
|
46
46
|
[tool.ruff.format]
|
|
47
47
|
quote-style = "single"
|
|
48
|
-
skip-magic-trailing-comma = true
|
|
49
48
|
|
|
50
|
-
[tool.
|
|
51
|
-
|
|
52
|
-
"ruff check",
|
|
53
|
-
"mypy",
|
|
54
|
-
"pyright",
|
|
55
|
-
]
|
|
49
|
+
[tool.ruff.lint]
|
|
50
|
+
ignore = ["SIM115", "SIM905", "BLE001", "PLW1510", "S110"]
|
|
56
51
|
|
|
57
52
|
# vim:se sw=2:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pystand
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.34
|
|
4
4
|
Summary: Install Python versions from python-build-standalone project
|
|
5
5
|
Author-email: Mark Blakeney <mark.blakeney@bullet-systems.net>
|
|
6
6
|
License-Expression: GPL-3.0-or-later
|
|
@@ -15,7 +15,7 @@ Requires-Dist: argparse-from-file
|
|
|
15
15
|
Requires-Dist: pygithub
|
|
16
16
|
Requires-Dist: certifi
|
|
17
17
|
Requires-Dist: filelock
|
|
18
|
-
Requires-Dist:
|
|
18
|
+
Requires-Dist: backports.zstd; python_version < "3.14"
|
|
19
19
|
|
|
20
20
|
## PYSTAND - Install Python Versions From The Python-Build-Standalone Project
|
|
21
21
|
[](https://pypi.org/project/pystand/)
|
|
@@ -172,7 +172,7 @@ options:
|
|
|
172
172
|
--purge-days PURGE_DAYS
|
|
173
173
|
cache YYYYMMDD release file lists and downloads for
|
|
174
174
|
this number of days after last version referencing
|
|
175
|
-
that release is removed. Default is
|
|
175
|
+
that release is removed. Default is 30 days.
|
|
176
176
|
--github-access-token GITHUB_ACCESS_TOKEN
|
|
177
177
|
optional Github access token. Can specify to reduce
|
|
178
178
|
rate limiting.
|
|
@@ -215,13 +215,13 @@ usage: pystand install [-h] [-r RELEASE] [-a] [-A] [--skip] [-f] [-s]
|
|
|
215
215
|
Install one, more, or all versions from a python-build-standalone release.
|
|
216
216
|
|
|
217
217
|
positional arguments:
|
|
218
|
-
version version to install. E.g. 3.
|
|
218
|
+
version version to install. E.g. 3.14 or 3.14.1
|
|
219
219
|
|
|
220
220
|
options:
|
|
221
221
|
-h, --help show this help message and exit
|
|
222
222
|
-r, --release RELEASE
|
|
223
223
|
install from specified python-build-standalone
|
|
224
|
-
YYYYMMDD release (e.g.
|
|
224
|
+
YYYYMMDD release (e.g. 20260807), default is latest
|
|
225
225
|
release
|
|
226
226
|
-a, --all install ALL versions from release
|
|
227
227
|
-A, --all-prerelease install ALL versions from release, including pre-
|
|
@@ -238,7 +238,8 @@ aliases: i
|
|
|
238
238
|
### Command `update`
|
|
239
239
|
|
|
240
240
|
```
|
|
241
|
-
usage: pystand update [-h] [-r RELEASE] [-a] [--skip] [-k]
|
|
241
|
+
usage: pystand update [-h] [-r RELEASE] [-a] [--pre-release] [--skip] [-k]
|
|
242
|
+
[version ...]
|
|
242
243
|
|
|
243
244
|
Update one, more, or all versions to another release.
|
|
244
245
|
|
|
@@ -248,9 +249,11 @@ positional arguments:
|
|
|
248
249
|
options:
|
|
249
250
|
-h, --help show this help message and exit
|
|
250
251
|
-r, --release RELEASE
|
|
251
|
-
update to specified YYYMMDD release (e.g.
|
|
252
|
+
update to specified YYYMMDD release (e.g. 20260807),
|
|
252
253
|
default is latest release
|
|
253
254
|
-a, --all update ALL versions
|
|
255
|
+
--pre-release update release version to a later superceding pre-
|
|
256
|
+
release
|
|
254
257
|
--skip skip the specified versions when updating all (only
|
|
255
258
|
can be specified with --all)
|
|
256
259
|
-k, --keep keep old version after updating (but only if different
|
|
@@ -276,7 +279,7 @@ options:
|
|
|
276
279
|
can be specified with --all)
|
|
277
280
|
-r, --release RELEASE
|
|
278
281
|
only remove versions if from specified YYYMMDD release
|
|
279
|
-
(e.g.
|
|
282
|
+
(e.g. 20260807)
|
|
280
283
|
|
|
281
284
|
aliases: r, rm
|
|
282
285
|
```
|
|
@@ -296,7 +299,7 @@ options:
|
|
|
296
299
|
-v, --verbose explicitly report why a version is not eligible for
|
|
297
300
|
update
|
|
298
301
|
-r, --release RELEASE
|
|
299
|
-
use specified YYYYMMDD release (e.g.
|
|
302
|
+
use specified YYYYMMDD release (e.g. 20260807) for
|
|
300
303
|
verbose compare, default is latest release
|
|
301
304
|
|
|
302
305
|
aliases: l
|
|
@@ -320,7 +323,7 @@ options:
|
|
|
320
323
|
-l, --list just list recent releases
|
|
321
324
|
-r, --release RELEASE
|
|
322
325
|
python-build-standalone YYYYMMDD release to show (e.g.
|
|
323
|
-
|
|
326
|
+
20260807), default is latest release
|
|
324
327
|
-a, --all show all available distributions for each version from
|
|
325
328
|
the release
|
|
326
329
|
|
|
@@ -387,7 +390,7 @@ positional arguments:
|
|
|
387
390
|
|
|
388
391
|
options:
|
|
389
392
|
-h, --help show this help message and exit
|
|
390
|
-
-p, --python PYTHON version of python to use, e.g. "3.
|
|
393
|
+
-p, --python PYTHON version of python to use, e.g. "3.14", default is
|
|
391
394
|
latest release version
|
|
392
395
|
```
|
|
393
396
|
|
|
@@ -405,7 +408,7 @@ positional arguments:
|
|
|
405
408
|
|
|
406
409
|
options:
|
|
407
410
|
-h, --help show this help message and exit
|
|
408
|
-
-p, --python PYTHON version of python to use, e.g. "3.
|
|
411
|
+
-p, --python PYTHON version of python to use, e.g. "3.14", default is
|
|
409
412
|
latest release version
|
|
410
413
|
```
|
|
411
414
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
#!/usr/bin/python3
|
|
2
1
|
"""
|
|
3
2
|
Command line tool to download, install, and update pre-built Python
|
|
4
3
|
versions from the python-build-standalone project at
|
|
@@ -35,11 +34,13 @@ GITHUB_SITE = f'https://github.com/{GITHUB_REPO}'
|
|
|
35
34
|
LATEST_RELEASES = f'{GITHUB_SITE}/releases.atom'
|
|
36
35
|
LATEST_RELEASE_TAG = f'{GITHUB_SITE}/releases/latest'
|
|
37
36
|
DOC = 'https://gregoryszorc.com/docs/python-build-standalone/main/'
|
|
37
|
+
VER = f'{sys.version_info.major}.{sys.version_info.minor}'
|
|
38
38
|
|
|
39
39
|
# Sample release tag for documentation/usage examples
|
|
40
|
-
SAMPL_RELEASE = '
|
|
40
|
+
SAMPL_RELEASE = '20260807'
|
|
41
41
|
|
|
42
42
|
PROG = Path(__file__).stem
|
|
43
|
+
HOME = Path.home()
|
|
43
44
|
|
|
44
45
|
# Default distributions for various platforms
|
|
45
46
|
DISTRIBUTIONS = {
|
|
@@ -114,10 +115,10 @@ class ColorDist(ColorTable):
|
|
|
114
115
|
return text.split('-', 1)[0]
|
|
115
116
|
|
|
116
117
|
|
|
117
|
-
def unexpanduser(path: Path
|
|
118
|
+
def unexpanduser(path: Path) -> Path:
|
|
118
119
|
"Return path name, with $HOME replaced by ~ (opposite of Path.expanduser())"
|
|
119
|
-
if path.parts[: len(
|
|
120
|
-
return Path('~', *path.parts[len(
|
|
120
|
+
if path.parts[: len(HOME.parts)] == HOME.parts:
|
|
121
|
+
return Path('~', *path.parts[len(HOME.parts) :])
|
|
121
122
|
|
|
122
123
|
return path
|
|
123
124
|
|
|
@@ -215,23 +216,6 @@ def rm_path(path: Path) -> bool:
|
|
|
215
216
|
return True
|
|
216
217
|
|
|
217
218
|
|
|
218
|
-
def register_zst() -> None:
|
|
219
|
-
"Register custom zstandard unpacker"
|
|
220
|
-
import tarfile
|
|
221
|
-
|
|
222
|
-
from zstandard import ZstdDecompressor
|
|
223
|
-
|
|
224
|
-
def unpack_zst(filename: str, extract_dir: str) -> None:
|
|
225
|
-
"Unpack a zstandard compressed tar"
|
|
226
|
-
with open(filename, 'rb') as compressed:
|
|
227
|
-
dctx = ZstdDecompressor()
|
|
228
|
-
with dctx.stream_reader(compressed) as reader:
|
|
229
|
-
with tarfile.open(fileobj=reader, mode='r|') as tar:
|
|
230
|
-
tar.extractall(path=extract_dir)
|
|
231
|
-
|
|
232
|
-
shutil.register_unpack_format('zst', ['.zst'], unpack_zst)
|
|
233
|
-
|
|
234
|
-
|
|
235
219
|
def fetch(args: Namespace, release: str, url: str, tdir: Path) -> str | None:
|
|
236
220
|
"Fetch and unpack a release file"
|
|
237
221
|
from urllib.parse import unquote, urlparse
|
|
@@ -256,9 +240,12 @@ def fetch(args: Namespace, release: str, url: str, tdir: Path) -> str | None:
|
|
|
256
240
|
if error:
|
|
257
241
|
rm_path(cache_file)
|
|
258
242
|
else:
|
|
259
|
-
# Register
|
|
260
|
-
|
|
261
|
-
|
|
243
|
+
# Register external zstd handler (only if Python < 3.14 which has
|
|
244
|
+
# built-in support)
|
|
245
|
+
if filename.lower().endswith('.zst') and sys.version_info < (3, 14):
|
|
246
|
+
from backports.zstd import register_shutil # type: ignore
|
|
247
|
+
|
|
248
|
+
register_shutil()
|
|
262
249
|
|
|
263
250
|
try:
|
|
264
251
|
shutil.unpack_archive(cache_file, tmpdir)
|
|
@@ -296,20 +283,26 @@ class VersionMatcher:
|
|
|
296
283
|
def __init__(self, seq: Iterable[str]) -> None:
|
|
297
284
|
self.seq = sorted(seq, key=parse_version, reverse=True)
|
|
298
285
|
|
|
299
|
-
def match(
|
|
286
|
+
def match(
|
|
287
|
+
self,
|
|
288
|
+
version: str | None,
|
|
289
|
+
*,
|
|
290
|
+
upgrade: bool = False,
|
|
291
|
+
allow_prelease: bool = False,
|
|
292
|
+
) -> str | None:
|
|
300
293
|
"Return full version string given a [possibly] part version prefix"
|
|
301
294
|
|
|
302
295
|
# If no version specified, return the latest release version
|
|
303
296
|
if not version:
|
|
304
|
-
for
|
|
305
|
-
if is_release_version(
|
|
306
|
-
return
|
|
297
|
+
for ver in self.seq:
|
|
298
|
+
if is_release_version(ver):
|
|
299
|
+
return ver
|
|
307
300
|
return None
|
|
308
301
|
|
|
309
302
|
if version in self.seq:
|
|
310
303
|
return version
|
|
311
304
|
|
|
312
|
-
is_release = is_release_version(version)
|
|
305
|
+
is_release = not allow_prelease and is_release_version(version)
|
|
313
306
|
major_only = '.' not in version
|
|
314
307
|
|
|
315
308
|
if major_only:
|
|
@@ -323,9 +316,10 @@ class VersionMatcher:
|
|
|
323
316
|
# Only allow upgrade of formal release to another formal
|
|
324
317
|
# release.
|
|
325
318
|
for full_version in self.seq:
|
|
326
|
-
if full_version.startswith(version)
|
|
327
|
-
|
|
328
|
-
|
|
319
|
+
if full_version.startswith(version) and (
|
|
320
|
+
not upgrade or not is_release or is_release_version(full_version)
|
|
321
|
+
):
|
|
322
|
+
return full_version
|
|
329
323
|
|
|
330
324
|
return None
|
|
331
325
|
|
|
@@ -356,7 +350,7 @@ def get_version_names(args: Namespace) -> list[str]:
|
|
|
356
350
|
if not args.version:
|
|
357
351
|
args.parser.error('Must specify at least one version, or --all.')
|
|
358
352
|
|
|
359
|
-
all_names =
|
|
353
|
+
all_names = {f.name for f in iter_versions(args)}
|
|
360
354
|
|
|
361
355
|
# Upconvert all user specified partial version names to full version names
|
|
362
356
|
matcher = VersionMatcher(all_names)
|
|
@@ -486,7 +480,7 @@ def get_release_files(args, tag) -> dict[str, Any]:
|
|
|
486
480
|
try:
|
|
487
481
|
release = gh.get_repo(GITHUB_REPO).get_release(tag)
|
|
488
482
|
except Exception as e:
|
|
489
|
-
print(f'Error: {
|
|
483
|
+
print(f'Error: {e}', file=sys.stderr)
|
|
490
484
|
return {}
|
|
491
485
|
|
|
492
486
|
# Iterate over the release assets and store pertinent files in a
|
|
@@ -521,7 +515,7 @@ def update_version_symlinks(args: Namespace) -> None:
|
|
|
521
515
|
|
|
522
516
|
# Create a map of all the new major version links
|
|
523
517
|
newlinks_all = defaultdict(set)
|
|
524
|
-
pre_releases =
|
|
518
|
+
pre_releases = {v for v in vers if not is_release_version(v)}
|
|
525
519
|
for namevers in vers:
|
|
526
520
|
while '.' in namevers[:-1]:
|
|
527
521
|
namevers_major = namevers.rsplit('.', maxsplit=1)[0]
|
|
@@ -540,7 +534,7 @@ def update_version_symlinks(args: Namespace) -> None:
|
|
|
540
534
|
if ver in pre_releases and (rels := (cands - pre_releases)):
|
|
541
535
|
cands = rels
|
|
542
536
|
|
|
543
|
-
newlinks[ver] =
|
|
537
|
+
newlinks[ver] = max(cands, key=parse_version)
|
|
544
538
|
|
|
545
539
|
# Remove all old or invalid existing links
|
|
546
540
|
for name, tgt in oldlinks.items():
|
|
@@ -595,7 +589,7 @@ def show_list(args: Namespace) -> None:
|
|
|
595
589
|
"Show a list of available releases"
|
|
596
590
|
latest = parse_version(args._release)
|
|
597
591
|
releases = fetch_tags(args)
|
|
598
|
-
cached =
|
|
592
|
+
cached = {p.name for p in args._releases.iterdir()}
|
|
599
593
|
for release in sorted(cached.union(releases)):
|
|
600
594
|
if args.re_match and not re.search(args.re_match, release):
|
|
601
595
|
continue
|
|
@@ -820,7 +814,7 @@ def main() -> str | None:
|
|
|
820
814
|
)
|
|
821
815
|
opt.add_argument(
|
|
822
816
|
'--purge-days',
|
|
823
|
-
default=
|
|
817
|
+
default=30,
|
|
824
818
|
type=int,
|
|
825
819
|
help='cache YYYYMMDD release file lists and downloads for '
|
|
826
820
|
'this number of days after last version referencing that '
|
|
@@ -861,7 +855,7 @@ def main() -> str | None:
|
|
|
861
855
|
else:
|
|
862
856
|
return f'Must define a docstring for command class "{name}".'
|
|
863
857
|
|
|
864
|
-
aliases = cls.aliases if hasattr(cls, 'aliases') else
|
|
858
|
+
aliases = cls.aliases if hasattr(cls, 'aliases') else ()
|
|
865
859
|
title = get_title(desc)
|
|
866
860
|
cmdopt = cmd.add_parser(name, description=desc, help=title, aliases=aliases)
|
|
867
861
|
|
|
@@ -927,7 +921,7 @@ def main() -> str | None:
|
|
|
927
921
|
# COMMAND
|
|
928
922
|
class install_:
|
|
929
923
|
doc = f'Install one, more, or all versions from a {REPO} release.'
|
|
930
|
-
aliases =
|
|
924
|
+
aliases = ('i',)
|
|
931
925
|
|
|
932
926
|
@staticmethod
|
|
933
927
|
def init(parser: ArgumentParser) -> None:
|
|
@@ -966,7 +960,7 @@ class install_:
|
|
|
966
960
|
help='also install source files if available in distribution download',
|
|
967
961
|
)
|
|
968
962
|
parser.add_argument(
|
|
969
|
-
'version', nargs='*', help='version to install. E.g.
|
|
963
|
+
'version', nargs='*', help=f'version to install. E.g. {VER} or {VER}.1'
|
|
970
964
|
)
|
|
971
965
|
|
|
972
966
|
@staticmethod
|
|
@@ -987,7 +981,7 @@ class install_:
|
|
|
987
981
|
'Can not specify versions with --all unless also specifying --skip.'
|
|
988
982
|
)
|
|
989
983
|
|
|
990
|
-
skips =
|
|
984
|
+
skips = {v for ver in args.version if (v := matcher.match(ver))}
|
|
991
985
|
|
|
992
986
|
args.version = [
|
|
993
987
|
v
|
|
@@ -1027,7 +1021,7 @@ class install_:
|
|
|
1027
1021
|
class update_:
|
|
1028
1022
|
"Update one, more, or all versions to another release."
|
|
1029
1023
|
|
|
1030
|
-
aliases =
|
|
1024
|
+
aliases = ('u', 'up')
|
|
1031
1025
|
|
|
1032
1026
|
@staticmethod
|
|
1033
1027
|
def init(parser: ArgumentParser) -> None:
|
|
@@ -1040,6 +1034,11 @@ class update_:
|
|
|
1040
1034
|
parser.add_argument(
|
|
1041
1035
|
'-a', '--all', action='store_true', help='update ALL versions'
|
|
1042
1036
|
)
|
|
1037
|
+
parser.add_argument(
|
|
1038
|
+
'--pre-release',
|
|
1039
|
+
action='store_true',
|
|
1040
|
+
help='update release version to a later superceding pre-release',
|
|
1041
|
+
)
|
|
1043
1042
|
parser.add_argument(
|
|
1044
1043
|
'--skip',
|
|
1045
1044
|
action='store_true',
|
|
@@ -1065,6 +1064,7 @@ class update_:
|
|
|
1065
1064
|
return f'Release "{release_target}" not found.'
|
|
1066
1065
|
|
|
1067
1066
|
matcher = VersionMatcher(files)
|
|
1067
|
+
|
|
1068
1068
|
for version in get_version_names(args):
|
|
1069
1069
|
vdir = args._versions / version
|
|
1070
1070
|
if not (data := get_json(vdir / args._data)):
|
|
@@ -1073,7 +1073,10 @@ class update_:
|
|
|
1073
1073
|
if (release := data.get('release')) == release_target:
|
|
1074
1074
|
continue
|
|
1075
1075
|
|
|
1076
|
-
|
|
1076
|
+
nextver = matcher.match(
|
|
1077
|
+
version, upgrade=True, allow_prelease=args.pre_release
|
|
1078
|
+
)
|
|
1079
|
+
if not nextver:
|
|
1077
1080
|
continue
|
|
1078
1081
|
|
|
1079
1082
|
distribution = data.get('distribution')
|
|
@@ -1114,7 +1117,7 @@ class update_:
|
|
|
1114
1117
|
class remove_:
|
|
1115
1118
|
"Remove/uninstall one, more, or all versions."
|
|
1116
1119
|
|
|
1117
|
-
aliases =
|
|
1120
|
+
aliases = ('r', 'rm')
|
|
1118
1121
|
|
|
1119
1122
|
@staticmethod
|
|
1120
1123
|
def init(parser: ArgumentParser) -> None:
|
|
@@ -1155,7 +1158,7 @@ class remove_:
|
|
|
1155
1158
|
class list_:
|
|
1156
1159
|
"List installed versions and show which have an update available."
|
|
1157
1160
|
|
|
1158
|
-
aliases =
|
|
1161
|
+
aliases = ('l',)
|
|
1159
1162
|
|
|
1160
1163
|
@staticmethod
|
|
1161
1164
|
def init(parser: ArgumentParser) -> None:
|
|
@@ -1245,7 +1248,7 @@ class show_:
|
|
|
1245
1248
|
View available releases and their distributions at
|
|
1246
1249
|
{GITHUB_SITE}/releases.
|
|
1247
1250
|
"""
|
|
1248
|
-
aliases =
|
|
1251
|
+
aliases = ('s',)
|
|
1249
1252
|
|
|
1250
1253
|
@staticmethod
|
|
1251
1254
|
def init(parser: ArgumentParser) -> None:
|
|
@@ -1320,7 +1323,7 @@ class show_:
|
|
|
1320
1323
|
class path_:
|
|
1321
1324
|
"Show path prefix to installed version base directory."
|
|
1322
1325
|
|
|
1323
|
-
aliases =
|
|
1326
|
+
aliases = ('p',)
|
|
1324
1327
|
|
|
1325
1328
|
@staticmethod
|
|
1326
1329
|
def init(parser: ArgumentParser) -> None:
|
|
@@ -1373,7 +1376,7 @@ class path_:
|
|
|
1373
1376
|
class cache_:
|
|
1374
1377
|
"Show size of release download caches."
|
|
1375
1378
|
|
|
1376
|
-
aliases =
|
|
1379
|
+
aliases = ('c',)
|
|
1377
1380
|
|
|
1378
1381
|
@staticmethod
|
|
1379
1382
|
def init(parser: ArgumentParser) -> None:
|
|
@@ -1421,9 +1424,7 @@ class cache_:
|
|
|
1421
1424
|
)
|
|
1422
1425
|
|
|
1423
1426
|
keep = keeplist(args)
|
|
1424
|
-
releases =
|
|
1425
|
-
p.name for p in args._downloads.iterdir() if p.name.isdigit()
|
|
1426
|
-
)
|
|
1427
|
+
releases = {p.name for p in args._downloads.iterdir() if p.name.isdigit()}
|
|
1427
1428
|
releases.update(
|
|
1428
1429
|
p.name for p in args._releases.iterdir() if p.name.isdigit()
|
|
1429
1430
|
)
|
|
@@ -1477,7 +1478,7 @@ class uv_:
|
|
|
1477
1478
|
parser.add_argument(
|
|
1478
1479
|
'-p',
|
|
1479
1480
|
'--python',
|
|
1480
|
-
help='version of python to use, e.g. "
|
|
1481
|
+
help=f'version of python to use, e.g. "{VER}", default is latest release version',
|
|
1481
1482
|
)
|
|
1482
1483
|
|
|
1483
1484
|
parser.add_argument('command', help='uv command to run')
|
|
@@ -1507,7 +1508,7 @@ class uvx_:
|
|
|
1507
1508
|
parser.add_argument(
|
|
1508
1509
|
'-p',
|
|
1509
1510
|
'--python',
|
|
1510
|
-
help='version of python to use, e.g. "
|
|
1511
|
+
help=f'version of python to use, e.g. "{VER}", default is latest release version',
|
|
1511
1512
|
)
|
|
1512
1513
|
|
|
1513
1514
|
parser.add_argument('program', help='uvx program to run')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|