pystand 2.18__tar.gz → 2.20__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.18/pystand.egg-info → pystand-2.20}/PKG-INFO +9 -5
- {pystand-2.18 → pystand-2.20}/README.md +7 -4
- {pystand-2.18 → pystand-2.20}/pyproject.toml +1 -0
- {pystand-2.18 → pystand-2.20/pystand.egg-info}/PKG-INFO +9 -5
- {pystand-2.18 → pystand-2.20}/pystand.egg-info/requires.txt +1 -0
- {pystand-2.18 → pystand-2.20}/pystand.py +52 -32
- {pystand-2.18 → pystand-2.20}/.gitignore +0 -0
- {pystand-2.18 → pystand-2.20}/Makefile +0 -0
- {pystand-2.18 → pystand-2.20}/pystand.egg-info/SOURCES.txt +0 -0
- {pystand-2.18 → pystand-2.20}/pystand.egg-info/dependency_links.txt +0 -0
- {pystand-2.18 → pystand-2.20}/pystand.egg-info/entry_points.txt +0 -0
- {pystand-2.18 → pystand-2.20}/pystand.egg-info/top_level.txt +0 -0
- {pystand-2.18 → pystand-2.20}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pystand
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.20
|
|
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,6 +15,7 @@ Requires-Dist: platformdirs
|
|
|
15
15
|
Requires-Dist: argparse-from-file
|
|
16
16
|
Requires-Dist: pygithub
|
|
17
17
|
Requires-Dist: certifi
|
|
18
|
+
Requires-Dist: filelock
|
|
18
19
|
Requires-Dist: zstandard; python_version < "3.14"
|
|
19
20
|
|
|
20
21
|
## PYSTAND - Install Python Versions From The Python-Build-Standalone Project
|
|
@@ -145,7 +146,9 @@ options:
|
|
|
145
146
|
python-build-standalone distribution. Default is
|
|
146
147
|
"x86_64_v3-unknown-linux-gnu-install_only_stripped"
|
|
147
148
|
for this host. Run "pystand show -a" to see all
|
|
148
|
-
distributions.
|
|
149
|
+
distributions. See
|
|
150
|
+
https://gregoryszorc.com/docs/python-build-
|
|
151
|
+
standalone/main/
|
|
149
152
|
-P, --prefix-dir PREFIX_DIR
|
|
150
153
|
specify prefix dir for storing versions. Default is
|
|
151
154
|
"$HOME/.local/share/pystand".
|
|
@@ -179,7 +182,7 @@ Commands:
|
|
|
179
182
|
available.
|
|
180
183
|
show Show versions available from a release.
|
|
181
184
|
path Show path prefix to installed version base directory.
|
|
182
|
-
cache Show release
|
|
185
|
+
cache Show size of release download caches.
|
|
183
186
|
|
|
184
187
|
Some commands offer aliases as shown in parentheses above. Note you can set
|
|
185
188
|
default starting global options in $HOME/.config/pystand-flags.conf.
|
|
@@ -317,9 +320,9 @@ options:
|
|
|
317
320
|
### Command `cache`
|
|
318
321
|
|
|
319
322
|
```
|
|
320
|
-
usage: pystand cache [-h] [-T] [-H] [release ...]
|
|
323
|
+
usage: pystand cache [-h] [-T] [-H] [-r] [release ...]
|
|
321
324
|
|
|
322
|
-
Show release
|
|
325
|
+
Show size of release download caches.
|
|
323
326
|
|
|
324
327
|
positional arguments:
|
|
325
328
|
release show cache size for given release[s] only
|
|
@@ -329,6 +332,7 @@ options:
|
|
|
329
332
|
-T, --no-total do not show total cache size
|
|
330
333
|
-H, --no-human-readable
|
|
331
334
|
show sizes in bytes, not human readable format
|
|
335
|
+
-r, --remove remove download cache[s] instead of showing size
|
|
332
336
|
```
|
|
333
337
|
|
|
334
338
|
## Installation and Upgrade
|
|
@@ -126,7 +126,9 @@ options:
|
|
|
126
126
|
python-build-standalone distribution. Default is
|
|
127
127
|
"x86_64_v3-unknown-linux-gnu-install_only_stripped"
|
|
128
128
|
for this host. Run "pystand show -a" to see all
|
|
129
|
-
distributions.
|
|
129
|
+
distributions. See
|
|
130
|
+
https://gregoryszorc.com/docs/python-build-
|
|
131
|
+
standalone/main/
|
|
130
132
|
-P, --prefix-dir PREFIX_DIR
|
|
131
133
|
specify prefix dir for storing versions. Default is
|
|
132
134
|
"$HOME/.local/share/pystand".
|
|
@@ -160,7 +162,7 @@ Commands:
|
|
|
160
162
|
available.
|
|
161
163
|
show Show versions available from a release.
|
|
162
164
|
path Show path prefix to installed version base directory.
|
|
163
|
-
cache Show release
|
|
165
|
+
cache Show size of release download caches.
|
|
164
166
|
|
|
165
167
|
Some commands offer aliases as shown in parentheses above. Note you can set
|
|
166
168
|
default starting global options in $HOME/.config/pystand-flags.conf.
|
|
@@ -298,9 +300,9 @@ options:
|
|
|
298
300
|
### Command `cache`
|
|
299
301
|
|
|
300
302
|
```
|
|
301
|
-
usage: pystand cache [-h] [-T] [-H] [release ...]
|
|
303
|
+
usage: pystand cache [-h] [-T] [-H] [-r] [release ...]
|
|
302
304
|
|
|
303
|
-
Show release
|
|
305
|
+
Show size of release download caches.
|
|
304
306
|
|
|
305
307
|
positional arguments:
|
|
306
308
|
release show cache size for given release[s] only
|
|
@@ -310,6 +312,7 @@ options:
|
|
|
310
312
|
-T, --no-total do not show total cache size
|
|
311
313
|
-H, --no-human-readable
|
|
312
314
|
show sizes in bytes, not human readable format
|
|
315
|
+
-r, --remove remove download cache[s] instead of showing size
|
|
313
316
|
```
|
|
314
317
|
|
|
315
318
|
## Installation and Upgrade
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pystand
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.20
|
|
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,6 +15,7 @@ Requires-Dist: platformdirs
|
|
|
15
15
|
Requires-Dist: argparse-from-file
|
|
16
16
|
Requires-Dist: pygithub
|
|
17
17
|
Requires-Dist: certifi
|
|
18
|
+
Requires-Dist: filelock
|
|
18
19
|
Requires-Dist: zstandard; python_version < "3.14"
|
|
19
20
|
|
|
20
21
|
## PYSTAND - Install Python Versions From The Python-Build-Standalone Project
|
|
@@ -145,7 +146,9 @@ options:
|
|
|
145
146
|
python-build-standalone distribution. Default is
|
|
146
147
|
"x86_64_v3-unknown-linux-gnu-install_only_stripped"
|
|
147
148
|
for this host. Run "pystand show -a" to see all
|
|
148
|
-
distributions.
|
|
149
|
+
distributions. See
|
|
150
|
+
https://gregoryszorc.com/docs/python-build-
|
|
151
|
+
standalone/main/
|
|
149
152
|
-P, --prefix-dir PREFIX_DIR
|
|
150
153
|
specify prefix dir for storing versions. Default is
|
|
151
154
|
"$HOME/.local/share/pystand".
|
|
@@ -179,7 +182,7 @@ Commands:
|
|
|
179
182
|
available.
|
|
180
183
|
show Show versions available from a release.
|
|
181
184
|
path Show path prefix to installed version base directory.
|
|
182
|
-
cache Show release
|
|
185
|
+
cache Show size of release download caches.
|
|
183
186
|
|
|
184
187
|
Some commands offer aliases as shown in parentheses above. Note you can set
|
|
185
188
|
default starting global options in $HOME/.config/pystand-flags.conf.
|
|
@@ -317,9 +320,9 @@ options:
|
|
|
317
320
|
### Command `cache`
|
|
318
321
|
|
|
319
322
|
```
|
|
320
|
-
usage: pystand cache [-h] [-T] [-H] [release ...]
|
|
323
|
+
usage: pystand cache [-h] [-T] [-H] [-r] [release ...]
|
|
321
324
|
|
|
322
|
-
Show release
|
|
325
|
+
Show size of release download caches.
|
|
323
326
|
|
|
324
327
|
positional arguments:
|
|
325
328
|
release show cache size for given release[s] only
|
|
@@ -329,6 +332,7 @@ options:
|
|
|
329
332
|
-T, --no-total do not show total cache size
|
|
330
333
|
-H, --no-human-readable
|
|
331
334
|
show sizes in bytes, not human readable format
|
|
335
|
+
-r, --remove remove download cache[s] instead of showing size
|
|
332
336
|
```
|
|
333
337
|
|
|
334
338
|
## Installation and Upgrade
|
|
@@ -23,8 +23,9 @@ from typing import Any
|
|
|
23
23
|
from urllib.request import urlopen
|
|
24
24
|
|
|
25
25
|
import argcomplete
|
|
26
|
+
import filelock
|
|
26
27
|
import platformdirs
|
|
27
|
-
from argparse_from_file import ArgumentParser, Namespace
|
|
28
|
+
from argparse_from_file import ArgumentParser, Namespace
|
|
28
29
|
from packaging.version import parse as parse_version
|
|
29
30
|
|
|
30
31
|
REPO = 'python-build-standalone'
|
|
@@ -32,6 +33,7 @@ GITHUB_REPO = f'astral-sh/{REPO}'
|
|
|
32
33
|
GITHUB_SITE = f'https://github.com/{GITHUB_REPO}'
|
|
33
34
|
LATEST_RELEASES = f'{GITHUB_SITE}/releases.atom'
|
|
34
35
|
LATEST_RELEASE_TAG = f'{GITHUB_SITE}/releases/latest'
|
|
36
|
+
DOC = 'https://gregoryszorc.com/docs/python-build-standalone/main/'
|
|
35
37
|
|
|
36
38
|
# Sample release tag for documentation/usage examples
|
|
37
39
|
SAMPL_RELEASE = '20240415'
|
|
@@ -144,23 +146,19 @@ def rm_path(path: Path) -> None:
|
|
|
144
146
|
|
|
145
147
|
def register_zst() -> None:
|
|
146
148
|
"Register custom zstandard unpacker"
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
149
|
+
def unpack_zst(filename: str, extract_dir: str) -> None:
|
|
150
|
+
"Unpack a zstandard compressed tar"
|
|
151
|
+
import tarfile
|
|
150
152
|
|
|
151
|
-
|
|
152
|
-
"Unpack a zstandard compressed tar"
|
|
153
|
-
import tarfile
|
|
153
|
+
import zstandard
|
|
154
154
|
|
|
155
|
-
|
|
155
|
+
with open(filename, 'rb') as compressed:
|
|
156
|
+
dctx = zstandard.ZstdDecompressor()
|
|
157
|
+
with dctx.stream_reader(compressed) as reader:
|
|
158
|
+
with tarfile.open(fileobj=reader, mode='r|') as tar:
|
|
159
|
+
tar.extractall(path=extract_dir)
|
|
156
160
|
|
|
157
|
-
|
|
158
|
-
dctx = zstandard.ZstdDecompressor()
|
|
159
|
-
with dctx.stream_reader(compressed) as reader:
|
|
160
|
-
with tarfile.open(fileobj=reader, mode='r|') as tar:
|
|
161
|
-
tar.extractall(path=extract_dir)
|
|
162
|
-
|
|
163
|
-
shutil.register_unpack_format('zst', ['.zst'], unpack_zst)
|
|
161
|
+
shutil.register_unpack_format('zst', ['.zst'], unpack_zst)
|
|
164
162
|
|
|
165
163
|
|
|
166
164
|
def fetch(args: Namespace, release: str, url: str, tdir: Path) -> str | None:
|
|
@@ -187,7 +185,8 @@ def fetch(args: Namespace, release: str, url: str, tdir: Path) -> str | None:
|
|
|
187
185
|
if error:
|
|
188
186
|
rm_path(cache_file)
|
|
189
187
|
else:
|
|
190
|
-
if
|
|
188
|
+
# Register custom zstandard handler (only if Python < 3.14 which has built-in support)
|
|
189
|
+
if filename.endswith('.zst') and sys.version_info < (3, 14):
|
|
191
190
|
register_zst()
|
|
192
191
|
|
|
193
192
|
try:
|
|
@@ -500,9 +499,10 @@ def purge_unused_releases(args: Namespace) -> None:
|
|
|
500
499
|
keep.add(path.name)
|
|
501
500
|
|
|
502
501
|
# Purge any downloads for releases that have expired
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
502
|
+
if args._downloads.is_dir():
|
|
503
|
+
for path in args._downloads.iterdir():
|
|
504
|
+
if path.name not in keep:
|
|
505
|
+
rm_path(path)
|
|
506
506
|
|
|
507
507
|
|
|
508
508
|
def show_list(args: Namespace) -> None:
|
|
@@ -677,7 +677,7 @@ def main() -> str | None:
|
|
|
677
677
|
opt = ArgumentParser(
|
|
678
678
|
description=__doc__,
|
|
679
679
|
epilog='Some commands offer aliases as shown in parentheses above. '
|
|
680
|
-
'Note you can set default starting global options in #FROM_FILE_PATH
|
|
680
|
+
'Note you can set default starting global options in #FROM_FILE_PATH#.',
|
|
681
681
|
)
|
|
682
682
|
|
|
683
683
|
# Set up main/global arguments
|
|
@@ -685,7 +685,7 @@ def main() -> str | None:
|
|
|
685
685
|
'-D',
|
|
686
686
|
'--distribution',
|
|
687
687
|
help=f'{REPO} distribution. Default is "{distro_help}" for this host. '
|
|
688
|
-
f'Run "{PROG} show -a" to see all distributions.',
|
|
688
|
+
f'Run "{PROG} show -a" to see all distributions. See {DOC}',
|
|
689
689
|
)
|
|
690
690
|
opt.add_argument(
|
|
691
691
|
'-P',
|
|
@@ -773,10 +773,7 @@ def main() -> str | None:
|
|
|
773
773
|
|
|
774
774
|
distribution = args.distribution or distro_default
|
|
775
775
|
if not distribution:
|
|
776
|
-
|
|
777
|
-
'Unknown system + machine distribution. Please specify '
|
|
778
|
-
'using -D/--distribution option.'
|
|
779
|
-
)
|
|
776
|
+
return 'Unknown system + machine distribution. Please specify using -D/--distribution option.'
|
|
780
777
|
|
|
781
778
|
# Keep some useful info in the namespace passed to the command
|
|
782
779
|
prefix_dir = Path(args.prefix_dir).expanduser().resolve()
|
|
@@ -788,7 +785,6 @@ def main() -> str | None:
|
|
|
788
785
|
|
|
789
786
|
args._versions = prefix_dir
|
|
790
787
|
args._versions.mkdir(parents=True, exist_ok=True)
|
|
791
|
-
|
|
792
788
|
args._downloads = cache_dir / 'downloads'
|
|
793
789
|
args._downloads.mkdir(parents=True, exist_ok=True)
|
|
794
790
|
args._releases = cache_dir / 'releases'
|
|
@@ -796,9 +792,18 @@ def main() -> str | None:
|
|
|
796
792
|
args._latest_release = cache_dir / 'latest_release'
|
|
797
793
|
args._cert = create_cert(args.cert)
|
|
798
794
|
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
795
|
+
# Only allow one instance of this program to run (to read/write prefix and cache dirs)
|
|
796
|
+
p_lock = filelock.FileLock(prefix_dir / '.lock')
|
|
797
|
+
c_lock = filelock.FileLock(cache_dir / '.lock')
|
|
798
|
+
|
|
799
|
+
try:
|
|
800
|
+
with p_lock.acquire(blocking=False), c_lock.acquire(blocking=False):
|
|
801
|
+
result = args.func(args)
|
|
802
|
+
purge_unused_releases(args)
|
|
803
|
+
update_version_symlinks(args)
|
|
804
|
+
except filelock.Timeout:
|
|
805
|
+
return f'ERROR: Another instance of {PROG} is already running.'
|
|
806
|
+
|
|
802
807
|
return result
|
|
803
808
|
|
|
804
809
|
|
|
@@ -1176,7 +1181,7 @@ class path_:
|
|
|
1176
1181
|
print(args._downloads.parent if args.cache_path else args._versions)
|
|
1177
1182
|
else:
|
|
1178
1183
|
path = args._versions / version
|
|
1179
|
-
if not path.
|
|
1184
|
+
if not path.exists():
|
|
1180
1185
|
return f'Version "{version}" is not installed.'
|
|
1181
1186
|
|
|
1182
1187
|
if args.resolve:
|
|
@@ -1195,7 +1200,7 @@ class path_:
|
|
|
1195
1200
|
|
|
1196
1201
|
# COMMAND
|
|
1197
1202
|
class cache_:
|
|
1198
|
-
"Show release
|
|
1203
|
+
"Show size of release download caches."
|
|
1199
1204
|
|
|
1200
1205
|
@staticmethod
|
|
1201
1206
|
def init(parser: ArgumentParser) -> None:
|
|
@@ -1208,13 +1213,28 @@ class cache_:
|
|
|
1208
1213
|
action='store_true',
|
|
1209
1214
|
help='show sizes in bytes, not human readable format',
|
|
1210
1215
|
)
|
|
1216
|
+
parser.add_argument(
|
|
1217
|
+
'-r',
|
|
1218
|
+
'--remove',
|
|
1219
|
+
action='store_true',
|
|
1220
|
+
help='remove download cache[s] instead of showing size',
|
|
1221
|
+
)
|
|
1211
1222
|
parser.add_argument(
|
|
1212
1223
|
'release', nargs='*', help='show cache size for given release[s] only'
|
|
1213
1224
|
)
|
|
1214
1225
|
|
|
1215
1226
|
@staticmethod
|
|
1216
1227
|
def run(args: Namespace) -> str | None:
|
|
1217
|
-
if args.
|
|
1228
|
+
if args.remove:
|
|
1229
|
+
if args.release:
|
|
1230
|
+
for release in args.release:
|
|
1231
|
+
rm_path(args._downloads / release)
|
|
1232
|
+
else:
|
|
1233
|
+
rm_path(args._downloads)
|
|
1234
|
+
|
|
1235
|
+
print('Cache removed.')
|
|
1236
|
+
|
|
1237
|
+
elif args.release:
|
|
1218
1238
|
for release in args.release:
|
|
1219
1239
|
show_cache_size(args._downloads / release, args)
|
|
1220
1240
|
else:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|