pyfig 0.3.1 → 0.5.0
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.
- package/README.md +116 -123
- package/SECURITY.md +2 -2
- package/dist/cjs/index.js +525 -888
- package/dist/cjs/index.js.map +15 -15
- package/dist/cjs/sync-resolver.js +482 -676
- package/dist/cjs/sync-resolver.js.map +13 -12
- package/dist/cli.js +7 -10
- package/dist/cli.js.map +1 -1
- package/dist/client.d.ts +3 -8
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +13 -11
- package/dist/client.js.map +1 -1
- package/dist/config.d.ts +9 -18
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +22 -59
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +5 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -4
- package/dist/index.js.map +1 -1
- package/dist/package-target.d.ts +7 -11
- package/dist/package-target.d.ts.map +1 -1
- package/dist/package-target.js +41 -57
- package/dist/package-target.js.map +1 -1
- package/dist/probes.d.ts +1 -19
- package/dist/probes.d.ts.map +1 -1
- package/dist/probes.js +13 -74
- package/dist/probes.js.map +1 -1
- package/dist/process.d.ts +1 -1
- package/dist/process.d.ts.map +1 -1
- package/dist/process.js +2 -1
- package/dist/process.js.map +1 -1
- package/dist/project-root.d.ts +1 -1
- package/dist/project-root.d.ts.map +1 -1
- package/dist/project-root.js +3 -64
- package/dist/project-root.js.map +1 -1
- package/dist/provision-lock.d.ts +10 -0
- package/dist/provision-lock.d.ts.map +1 -0
- package/dist/provision-lock.js +24 -0
- package/dist/provision-lock.js.map +1 -0
- package/dist/provision.d.ts +18 -6
- package/dist/provision.d.ts.map +1 -1
- package/dist/provision.js +297 -235
- package/dist/provision.js.map +1 -1
- package/dist/python-version.d.ts +10 -0
- package/dist/python-version.d.ts.map +1 -0
- package/dist/python-version.js +17 -0
- package/dist/python-version.js.map +1 -0
- package/dist/runners.d.ts +3 -7
- package/dist/runners.d.ts.map +1 -1
- package/dist/runners.js +35 -115
- package/dist/runners.js.map +1 -1
- package/dist/sync-resolver.js +4 -13
- package/dist/sync-resolver.js.map +1 -1
- package/dist/virtual-environment.d.ts +3 -1
- package/dist/virtual-environment.d.ts.map +1 -1
- package/dist/virtual-environment.js +8 -1
- package/dist/virtual-environment.js.map +1 -1
- package/package.json +9 -10
- package/dist/coordination.d.ts +0 -25
- package/dist/coordination.d.ts.map +0 -1
- package/dist/coordination.js +0 -187
- package/dist/coordination.js.map +0 -1
- package/dist/state.d.ts +0 -10
- package/dist/state.d.ts.map +0 -1
- package/dist/state.js +0 -62
- package/dist/state.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# pyfig
|
|
2
2
|
|
|
3
|
-
`pyfig`
|
|
3
|
+
`pyfig` prepares uv and a compatible Python virtual environment from Bun or Node.js. It prefers a valid uv already on the system, reuses a compatible venv, and searches system Python with downloads disabled before considering any managed Python download.
|
|
4
|
+
|
|
5
|
+
Pyfig never invokes standalone `pip`, never writes `pyproject.toml` or requirements files, and never creates a project-root `.venv`. When no compatible venv exists, its private environment is `<project-root>/node_modules/.pyfig/venv`.
|
|
4
6
|
|
|
5
7
|
## Install
|
|
6
8
|
|
|
@@ -8,156 +10,146 @@
|
|
|
8
10
|
bun add pyfig
|
|
9
11
|
```
|
|
10
12
|
|
|
11
|
-
##
|
|
13
|
+
## Use
|
|
12
14
|
|
|
13
15
|
```ts
|
|
14
16
|
import { createPyfig } from 'pyfig';
|
|
15
17
|
|
|
16
18
|
const pyfig = createPyfig({
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
requireGil: true, // reject free-threaded CPython ABIs
|
|
19
|
+
requiresPython: '>=3.11,<4',
|
|
20
|
+
requireEmbedding: true,
|
|
21
|
+
requireGil: true,
|
|
21
22
|
});
|
|
22
|
-
const environment = await pyfig.prepare();
|
|
23
23
|
|
|
24
|
+
const environment = await pyfig.prepare(
|
|
25
|
+
['requests>=2.32'],
|
|
26
|
+
{ extras: ['database'] },
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
console.log(environment.uv);
|
|
24
30
|
console.log(environment.python);
|
|
25
|
-
console.log(environment.
|
|
31
|
+
console.log(environment.managed);
|
|
32
|
+
|
|
33
|
+
await pyfig.uv(
|
|
34
|
+
['run', '--', 'python', 'script.py'],
|
|
35
|
+
{ stdio: 'inherit' },
|
|
36
|
+
);
|
|
26
37
|
```
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
`prepare()` accepts PEP 508 dependency specifiers plus optional `extras`, `groups`, or `allExtras`. If the project has a `pyproject.toml`, uv resolves that read-only input together with a temporary dependency file. Pyfig installs the resolved result with `uv pip install -r`, which preserves unrelated packages. Temporary inputs are created outside the repository and removed afterward.
|
|
40
|
+
|
|
41
|
+
The same uv-only surface handles direct commands:
|
|
29
42
|
|
|
30
43
|
```ts
|
|
31
|
-
import {
|
|
32
|
-
pipSpawn,
|
|
33
|
-
pipSpawnSync,
|
|
34
|
-
pythonSpawn,
|
|
35
|
-
pythonSpawnSync,
|
|
36
|
-
uvSpawn,
|
|
37
|
-
uvSpawnSync,
|
|
38
|
-
} from 'pyfig';
|
|
39
|
-
|
|
40
|
-
const python = await pythonSpawn(['script.py', '--verbose'], { stdio: 'inherit' });
|
|
41
|
-
const pythonVersion = pythonSpawnSync(['--version'], { encoding: 'utf8' });
|
|
42
|
-
|
|
43
|
-
const pip = await pipSpawn(['install', 'ruff'], { stdio: 'inherit' });
|
|
44
|
-
const installed = pipSpawnSync(['list', '--format', 'json'], { encoding: 'utf8' });
|
|
45
|
-
|
|
46
|
-
const uv = await uvSpawn(['python', 'list'], { stdio: 'inherit' });
|
|
47
|
-
const uvVersion = uvSpawnSync(['--version'], { encoding: 'utf8' });
|
|
48
|
-
```
|
|
44
|
+
import { uvSpawn, uvSpawnSync } from 'pyfig';
|
|
49
45
|
|
|
50
|
-
|
|
46
|
+
await uvSpawn(['pip', 'list'], { stdio: 'inherit' });
|
|
51
47
|
|
|
52
|
-
|
|
48
|
+
const result = uvSpawnSync(
|
|
49
|
+
['run', '--', 'python', '-c', 'import sys; print(sys.executable)'],
|
|
50
|
+
{ encoding: 'utf8' },
|
|
51
|
+
);
|
|
52
|
+
```
|
|
53
53
|
|
|
54
|
-
Pyfig
|
|
54
|
+
For `uv pip` and `uv run`, Pyfig selects the venv and injects its exact interpreter. Caller-supplied target overrides such as `--python`, `--system`, `--target`, `--prefix`, and `--user` are rejected. Inherited target-changing environment variables are removed. Other uv commands run with Pyfig's cache and system-Python preference but are otherwise unchanged.
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
The async spawn helper returns `Promise<ChildProcess>` because uv or environment setup may happen before spawning. The synchronous helper performs setup through `process.execPath`, so a Bun process remains Bun and does not assume a `node` command exists.
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
## Selection policy
|
|
59
59
|
|
|
60
|
-
|
|
60
|
+
Pyfig uses this order:
|
|
61
61
|
|
|
62
|
-
|
|
62
|
+
1. A compatible configured or `PATH` uv.
|
|
63
|
+
2. Pyfig's cached, checksum-verified uv.
|
|
64
|
+
3. A compatible explicitly configured venv, active `VIRTUAL_ENV`, root `.venv`, or Pyfig-owned venv.
|
|
65
|
+
4. Every installed system Python reported by uv, with downloads disabled, until one passes all capability checks.
|
|
66
|
+
5. An already-cached uv-managed Python that passes the same checks.
|
|
67
|
+
6. A managed Python download, only when installation policy allows it.
|
|
63
68
|
|
|
64
|
-
|
|
69
|
+
An explicit `python` option is strict: an unavailable or incompatible interpreter is an error. Incompatible external venvs are preserved and skipped. Only an incompatible environment under `node_modules/.pyfig/venv` may be rebuilt.
|
|
65
70
|
|
|
66
|
-
|
|
71
|
+

|
|
67
72
|
|
|
68
|
-
|
|
73
|
+
[Mermaid source](docs/diagrams/python-selection.mmd)
|
|
69
74
|
|
|
70
|
-
|
|
71
|
-
graph TD;
|
|
72
|
-
A[Ensure environment] --> V{Repository virtual environment usable};
|
|
73
|
-
V -->|Yes| Q{Compatible uv available};
|
|
74
|
-
V -->|No| B{Configured Python supplied};
|
|
75
|
-
B -->|Valid| P[Select base Python];
|
|
76
|
-
B -->|Invalid| X[Fail explicit configuration];
|
|
77
|
-
B -->|No| C{Managed uv Python compatible};
|
|
78
|
-
C -->|Yes| P;
|
|
79
|
-
C -->|No| D{System Python compatible};
|
|
80
|
-
D -->|Yes| P;
|
|
81
|
-
D -->|No| E{Python installation allowed};
|
|
82
|
-
E -->|No| X2[Fail without changes];
|
|
83
|
-
E -->|Yes| U[Install pinned uv];
|
|
84
|
-
U --> M[Install managed Python];
|
|
85
|
-
M --> P;
|
|
75
|
+
Native consumers can set `requireEmbedding: true` to require CPython, `Python.h`, a linkable embedding library, and architecture/pointer-width compatibility with the JavaScript runtime. Set `requireGil: true` when the native addon requires the standard GIL-enabled ABI. These checks apply to system, existing-venv, cached, and downloaded interpreters alike.
|
|
86
76
|
|
|
87
|
-
|
|
88
|
-
W -->|Yes| UVV[Create virtual environment with uv];
|
|
89
|
-
W -->|No| SV[Create virtual environment with Python];
|
|
90
|
-
UVV --> Q;
|
|
91
|
-
SV --> Q;
|
|
77
|
+
## Runtime dependency resolution
|
|
92
78
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
79
|
+
```ts
|
|
80
|
+
await pyfig.prepare(
|
|
81
|
+
['orjson>=3.10', 'httpx[http2]'],
|
|
82
|
+
{
|
|
83
|
+
extras: ['postgres'],
|
|
84
|
+
groups: ['runtime'],
|
|
85
|
+
},
|
|
86
|
+
);
|
|
97
87
|
```
|
|
98
88
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
```mermaid
|
|
102
|
-
graph TD;
|
|
103
|
-
A[Start uv helper] --> B{Compatible uv available};
|
|
104
|
-
B -->|Yes| H[Spawn uv with pyfig cache environment];
|
|
105
|
-
B -->|No| C{Automatic setup enabled};
|
|
106
|
-
C -->|No| F[Fail without installing];
|
|
107
|
-
C -->|Yes| I[Download verified platform uv archive];
|
|
108
|
-
I --> J{Installed uv validates};
|
|
109
|
-
J -->|No| K[Fail installation];
|
|
110
|
-
J -->|Yes| H;
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
## CLI
|
|
89
|
+
Resolution follows the equivalent of:
|
|
114
90
|
|
|
115
91
|
```sh
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
92
|
+
uv pip compile pyproject.toml /temporary/runtime-dependencies.txt \
|
|
93
|
+
--extra postgres --group runtime \
|
|
94
|
+
--python /selected/venv/python \
|
|
95
|
+
--output-file /temporary/resolved-dependencies.txt
|
|
96
|
+
|
|
97
|
+
uv pip install \
|
|
98
|
+
--python /selected/venv/python \
|
|
99
|
+
-r /temporary/resolved-dependencies.txt
|
|
122
100
|
```
|
|
123
101
|
|
|
124
|
-
|
|
102
|
+
When no `pyproject.toml` exists, only the temporary dependency input is compiled. Extras and dependency groups require an existing `pyproject.toml`. Pyfig does not use `uv add` or `uv pip sync`: the former would edit project metadata, while the latter could remove unrelated packages from the venv.
|
|
103
|
+
|
|
104
|
+

|
|
105
|
+
|
|
106
|
+
[Mermaid source](docs/diagrams/runtime-dependencies.mmd)
|
|
125
107
|
|
|
126
|
-
|
|
108
|
+
## Project root
|
|
109
|
+
|
|
110
|
+
Pyfig does not interpret `package.json`, workspace metadata, `pyproject.toml`, or lockfiles to choose ownership. Root precedence is:
|
|
111
|
+
|
|
112
|
+
1. `projectRoot`
|
|
113
|
+
2. `PYFIG_PROJECT_ROOT`
|
|
114
|
+
3. nearest Git worktree marker above `INIT_CWD`, when set, otherwise the current directory
|
|
115
|
+
4. that starting directory when no Git marker exists
|
|
116
|
+
|
|
117
|
+
Set `projectRoot` explicitly in reusable libraries and unusual workspace layouts.
|
|
127
118
|
|
|
128
119
|
## Public API
|
|
129
120
|
|
|
130
121
|
| Export | Responsibility |
|
|
131
122
|
| --- | --- |
|
|
132
|
-
| `createPyfig(options)` |
|
|
133
|
-
| `
|
|
134
|
-
| `
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
137
|
-
| `
|
|
138
|
-
| `
|
|
139
|
-
| `
|
|
140
|
-
| `
|
|
141
|
-
|
|
142
|
-
The
|
|
123
|
+
| `createPyfig(options)` | Create a scoped client with memoized base preparation. |
|
|
124
|
+
| `client.prepare(dependencies?, options?)` | Select a venv and optionally resolve/install runtime dependencies. |
|
|
125
|
+
| `client.pythonInfo()` | Return the selected interpreter and embedding metadata. |
|
|
126
|
+
| `client.uvInfo()` | Return the selected uv executable and version. |
|
|
127
|
+
| `client.uv()` / `client.uvSync()` | Spawn uv and pin pip/run commands to the selected venv. |
|
|
128
|
+
| `ensureEnvironment(options?, dependencies?, dependencyOptions?)` | Standalone preparation API. |
|
|
129
|
+
| `ensureUv(options?)` | Prefer existing uv, otherwise bootstrap verified uv when allowed. |
|
|
130
|
+
| `uvSpawn()` / `uvSpawnSync()` | Standalone uv spawn API. |
|
|
131
|
+
| `resolveProjectRoot(start?)` | Resolve the nearest Git root without reading manifests. |
|
|
132
|
+
|
|
133
|
+
The package exposes matching ESM and CommonJS entry points. Probe, download, lock, and command-policy internals are not exported.
|
|
143
134
|
|
|
144
135
|
## Configuration
|
|
145
136
|
|
|
146
|
-
Precedence is API
|
|
137
|
+
Precedence is API or CLI option, environment variable, then default.
|
|
138
|
+
|
|
139
|
+
`requiresPython` uses the same PEP 440 specifier syntax as `[project].requires-python` in `pyproject.toml`. Comma-separated clauses, compatible releases (`~=`), exclusions (`!=`), wildcard equality (`==3.12.*`), arbitrary equality (`===`), and pre-release versions are supported. For example: `>=3.10,!=3.12.*,<4`.
|
|
147
140
|
|
|
148
141
|
| API option | Environment variable | Default |
|
|
149
142
|
| --- | --- | --- |
|
|
150
|
-
| `python` | `PYFIG_PYTHON` |
|
|
151
|
-
| `
|
|
152
|
-
| `pipRange` | `PYFIG_PIP_RANGE` | `>=20.3.0` |
|
|
143
|
+
| `python` | `PYFIG_PYTHON` | uv discovery |
|
|
144
|
+
| `requiresPython` | `PYFIG_REQUIRES_PYTHON` | `>=3.10,<4` |
|
|
153
145
|
| `managedPython` | `PYFIG_MANAGED_PYTHON` | `3.12` |
|
|
154
146
|
| `uvVersion` | `PYFIG_UV_VERSION` | `0.13.6` |
|
|
155
|
-
| `uvRange` | `PYFIG_UV_RANGE` | `>=0.
|
|
147
|
+
| `uvRange` | `PYFIG_UV_RANGE` | `>=0.10.0 <1.0.0` |
|
|
156
148
|
| `cacheDir` | `PYFIG_HOME` | OS cache directory |
|
|
157
|
-
| `projectRoot` | `PYFIG_PROJECT_ROOT` |
|
|
149
|
+
| `projectRoot` | `PYFIG_PROJECT_ROOT` | `INIT_CWD`, Git root, or current directory |
|
|
158
150
|
| `requireEmbedding` | `PYFIG_REQUIRE_EMBEDDING` | `false` |
|
|
159
151
|
| `requireGil` | `PYFIG_REQUIRE_GIL` | `false` |
|
|
160
|
-
| `autoInstall` | `PYFIG_AUTO_INSTALL` | `true`
|
|
152
|
+
| `autoInstall` | `PYFIG_AUTO_INSTALL` | `true` |
|
|
161
153
|
| `installPython` | `PYFIG_INSTALL_PYTHON` | `autoInstall` |
|
|
162
154
|
| `installUv` | `PYFIG_INSTALL_UV` | `autoInstall` |
|
|
163
155
|
| `createVirtualEnvironment` | `PYFIG_CREATE_VIRTUAL_ENVIRONMENT` | `autoInstall` |
|
|
@@ -165,43 +157,44 @@ Precedence is API/CLI option, environment variable, then default.
|
|
|
165
157
|
| `installTimeoutMs` | `PYFIG_INSTALL_TIMEOUT_MS` | `600000` |
|
|
166
158
|
| `downloadTimeoutMs` | `PYFIG_DOWNLOAD_TIMEOUT_MS` | `300000` |
|
|
167
159
|
| `coordinationTimeoutMs` | `PYFIG_COORDINATION_TIMEOUT_MS` | install + download + 60 seconds |
|
|
168
|
-
| `cacheTtlMs` | `PYFIG_CACHE_TTL_MS` | `30000` (`0` disables completed-result caching) |
|
|
169
160
|
|
|
170
|
-
Set `PYFIG_UV` to
|
|
161
|
+
Set `PYFIG_UV` to choose an explicit uv executable. Set `PYFIG_AUTO_INSTALL=0` or use the CLI's `--check` flag on hosts where downloads and environment creation are prohibited.
|
|
171
162
|
|
|
172
|
-
##
|
|
163
|
+
## CLI
|
|
173
164
|
|
|
174
|
-
|
|
165
|
+
```sh
|
|
166
|
+
bunx --bun pyfig
|
|
167
|
+
bunx --bun pyfig --check
|
|
168
|
+
bunx --bun pyfig --requires-python '>=3.12,<3.14'
|
|
169
|
+
bunx --bun pyfig --require-embedding --require-gil
|
|
170
|
+
bunx --bun pyfig --project-root /path/to/repository
|
|
171
|
+
bunx --bun pyfig --json
|
|
172
|
+
```
|
|
175
173
|
|
|
176
|
-
|
|
174
|
+
`bunx --bun` runs the CLI with Bun and does not require a separate Node.js executable.
|
|
177
175
|
|
|
178
|
-
##
|
|
176
|
+
## Concurrency and installation safety
|
|
179
177
|
|
|
180
|
-
Pyfig downloads
|
|
178
|
+
Pyfig downloads an exact uv release archive over HTTPS, verifies its adjacent SHA-256 checksum, validates the staged executable version, and atomically publishes it in Pyfig's cache. It does not execute installer scripts or modify shell profiles.
|
|
181
179
|
|
|
182
|
-
|
|
180
|
+
Provisioning mutations use Loqkit's layered in-memory, worker, native-file-lock-when-available, and portable-file coordination with capability checks before and after acquisition. uv supplies its own target-environment lock for installs. Base client preparation is memoized; dependency preparation is intentionally rerun so uv can cheaply verify current inputs through its shared cache.
|
|
183
181
|
|
|
184
|
-
|
|
185
|
-
2. Queue behind the current JavaScript realm's mutex.
|
|
186
|
-
3. Use Node's cross-worker `LockManager` when the runtime provides it.
|
|
187
|
-
4. Use the system `flock` command when it is available and functional.
|
|
188
|
-
5. Acquire the portable heartbeat-based filesystem lease used by every runtime.
|
|
189
|
-
6. Check again and install only when the resource is still absent.
|
|
182
|
+
## Platform support
|
|
190
183
|
|
|
191
|
-
|
|
184
|
+
Pyfig bootstraps uv on x64 and arm64 Windows, macOS, and Linux. Linux uses Astral's static musl artifact, which also runs on glibc. Node.js 22.11+ on the 22.x line, Node.js 24.10 through 26.x, and Bun 1.2+ are supported. Other JavaScript runtimes may work when they provide compatible Node built-ins and process semantics.
|
|
192
185
|
|
|
193
186
|
## Publishing
|
|
194
187
|
|
|
195
|
-
Pyfig publishes
|
|
188
|
+
Pyfig publishes from a `v<package-version>` Git tag through `.github/workflows/publish.yml`. The trusted-publishing workflow validates the tag, rejects an existing registry version, builds and audits one archive, and publishes that archive with provenance.
|
|
196
189
|
|
|
197
|
-
|
|
190
|
+
From a clean, synchronized `main` branch:
|
|
198
191
|
|
|
199
192
|
```sh
|
|
200
|
-
bun
|
|
201
|
-
bun run verify
|
|
202
|
-
bun run release:check -- v0.3.0
|
|
193
|
+
bun run release
|
|
203
194
|
```
|
|
204
195
|
|
|
196
|
+
The local gate derives the next version from remote GitHub tags, verifies locally, audits the package, commits, tags, and atomically pushes. Use `bun run release -- minor`, `bun run release -- major`, or `bun run release -- --dry-run` as needed. Tag publishing intentionally does not repeat the local test suite.
|
|
197
|
+
|
|
205
198
|
## Development
|
|
206
199
|
|
|
207
200
|
```sh
|
package/SECURITY.md
CHANGED
|
@@ -4,6 +4,6 @@ Pyfig can download Astral uv release archives and can ask uv to download Python
|
|
|
4
4
|
|
|
5
5
|
The uv release URL is pinned to an exact validated version and fetched over HTTPS with bounded redirects and timeouts. Pyfig verifies the adjacent SHA-256 checksum, validates the staged executable's reported version, and atomically publishes it into its cache. It never executes an installer script or modifies shell profiles or the host `PATH`. Proxy variables are honored through a per-request dispatcher without logging proxy credentials.
|
|
6
6
|
|
|
7
|
-
Provisioning uses
|
|
7
|
+
Provisioning uses in-process, worker, optional native advisory, and portable filesystem coordination followed by a post-lock capability check. Runtime dependency mutation uses uv's target-environment lock. Pyfig pins uv commands to the selected venv and removes configuration values that could redirect them. It reads an existing `pyproject.toml` only as a resolver input and never writes project manifests or requirements files.
|
|
8
8
|
|
|
9
|
-
Executable paths, project roots, version
|
|
9
|
+
Executable paths, project roots, version specifiers, package specifications, indexes, and proxy settings remain trusted configuration. Do not let an untrusted user choose `python`, `PYFIG_UV`, `cacheDir`, package arguments, or related environment variables in a privileged process. A checksum fetched from the same release protects transfer integrity, not a compromised upstream publisher.
|