Skip to content

Commit ac06e13

Browse files
lengauzanieb
andauthored
Add NO_BINARY and NO_BINARY_PACKAGE environment variables (#11399)
<!-- Thank you for contributing to uv! To help us out with reviewing, please consider the following: - Does this pull request include a summary of the change? (See below.) - Does this pull request include a descriptive title? - Does this pull request include references to any relevant issues? --> ## Summary This adds `NO_BINARY` and `NO_BINARY_PACKAGE` environment variables to the uv CLI, allowing the user to specify packages to build from source using environment variables. Its not a complete fix for #4291 as it does not handle the `pip` subcommand. ## Test Plan This was tested by running `uv sync` with various `UV_NO_BINARY` and `UV_NO_BINARY_PACKAGE` environment variables set and checking that the correct set of packages were compiled rather than taken from pre-built wheels. --------- Co-authored-by: Zanie Blue <contact@zanie.dev>
1 parent 768da20 commit ac06e13

File tree

6 files changed

+177
-2
lines changed

6 files changed

+177
-2
lines changed

crates/uv-cli/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4770,7 +4770,13 @@ pub struct BuildOptionsArgs {
47704770
///
47714771
/// The given packages will be built and installed from source. The resolver will still use
47724772
/// pre-built wheels to extract package metadata, if available.
4773-
#[arg(long, overrides_with("binary"), help_heading = "Build options")]
4773+
#[arg(
4774+
long,
4775+
env = EnvVars::UV_NO_BINARY,
4776+
overrides_with("binary"),
4777+
value_parser = clap::builder::BoolishValueParser::new(),
4778+
help_heading = "Build options"
4779+
)]
47744780
pub no_binary: bool,
47754781

47764782
#[arg(
@@ -4782,7 +4788,7 @@ pub struct BuildOptionsArgs {
47824788
pub binary: bool,
47834789

47844790
/// Don't install pre-built wheels for a specific package.
4785-
#[arg(long, help_heading = "Build options")]
4791+
#[arg(long, help_heading = "Build options", env = EnvVars::UV_NO_BINARY_PACKAGE, value_delimiter = ' ')]
47864792
pub no_binary_package: Vec<PackageName>,
47874793
}
47884794

crates/uv-static/src/env_vars.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,15 @@ impl EnvVars {
142142
/// will compile Python source files to bytecode after installation.
143143
pub const UV_COMPILE_BYTECODE: &'static str = "UV_COMPILE_BYTECODE";
144144

145+
/// Equivalent to the `--no-binary` command-line argument. If set, uv will install
146+
/// all packages from source. The resolver will still use pre-built wheels to
147+
/// extract package metadata, if available.
148+
pub const UV_NO_BINARY: &'static str = "UV_NO_BINARY";
149+
150+
/// Equivalent to the `--no-binary-package` command line argument. If set, uv will
151+
/// not use pre-built wheels for the given space-delimited list of packages.
152+
pub const UV_NO_BINARY_PACKAGE: &'static str = "UV_NO_BINARY_PACKAGE";
153+
145154
/// Equivalent to the `--publish-url` command-line argument. The URL of the upload
146155
/// endpoint of the index to use with `uv publish`.
147156
pub const UV_PUBLISH_URL: &'static str = "UV_PUBLISH_URL";

crates/uv/tests/it/pip_install.rs

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,6 +2279,83 @@ fn install_no_binary_overrides_only_binary_all() {
22792279
context.assert_command("import anyio").success();
22802280
}
22812281

2282+
/// Disable binaries with an environment variable
2283+
/// TODO(zanieb): This is not yet implemented
2284+
#[test]
2285+
fn install_no_binary_env() {
2286+
let context = TestContext::new("3.12");
2287+
2288+
let mut command = context.pip_install();
2289+
command.arg("anyio").env("UV_NO_BINARY", "1");
2290+
uv_snapshot!(
2291+
command,
2292+
@r###"
2293+
success: true
2294+
exit_code: 0
2295+
----- stdout -----
2296+
2297+
----- stderr -----
2298+
Resolved 3 packages in [TIME]
2299+
Prepared 3 packages in [TIME]
2300+
Installed 3 packages in [TIME]
2301+
+ anyio==4.3.0
2302+
+ idna==3.6
2303+
+ sniffio==1.3.1
2304+
"###
2305+
);
2306+
2307+
let mut command = context.pip_install();
2308+
command
2309+
.arg("anyio")
2310+
.arg("--reinstall")
2311+
.env("UV_NO_BINARY", "anyio");
2312+
uv_snapshot!(
2313+
command,
2314+
@r###"
2315+
success: true
2316+
exit_code: 0
2317+
----- stdout -----
2318+
2319+
----- stderr -----
2320+
Resolved 3 packages in [TIME]
2321+
Prepared 3 packages in [TIME]
2322+
Uninstalled 3 packages in [TIME]
2323+
Installed 3 packages in [TIME]
2324+
~ anyio==4.3.0
2325+
~ idna==3.6
2326+
~ sniffio==1.3.1
2327+
"###
2328+
);
2329+
2330+
context.assert_command("import anyio").success();
2331+
2332+
let mut command = context.pip_install();
2333+
command
2334+
.arg("anyio")
2335+
.arg("--reinstall")
2336+
.arg("idna")
2337+
.env("UV_NO_BINARY_PACKAGE", "idna");
2338+
uv_snapshot!(
2339+
command,
2340+
@r###"
2341+
success: true
2342+
exit_code: 0
2343+
----- stdout -----
2344+
2345+
----- stderr -----
2346+
Resolved 3 packages in [TIME]
2347+
Prepared 3 packages in [TIME]
2348+
Uninstalled 3 packages in [TIME]
2349+
Installed 3 packages in [TIME]
2350+
~ anyio==4.3.0
2351+
~ idna==3.6
2352+
~ sniffio==1.3.1
2353+
"###
2354+
);
2355+
2356+
context.assert_command("import idna").success();
2357+
}
2358+
22822359
/// Overlapping usage of `--no-binary` and `--only-binary`
22832360
#[test]
22842361
fn install_only_binary_overrides_no_binary_all() {

crates/uv/tests/it/sync.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3963,6 +3963,56 @@ fn no_binary() -> Result<()> {
39633963

39643964
assert!(context.temp_dir.child("uv.lock").exists());
39653965

3966+
uv_snapshot!(context.filters(), context.sync().arg("--reinstall").arg("--no-binary"), @r###"
3967+
success: true
3968+
exit_code: 0
3969+
----- stdout -----
3970+
3971+
----- stderr -----
3972+
Resolved 2 packages in [TIME]
3973+
Prepared 1 package in [TIME]
3974+
Uninstalled 1 package in [TIME]
3975+
Installed 1 package in [TIME]
3976+
~ iniconfig==2.0.0
3977+
"###);
3978+
3979+
uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY_PACKAGE", "iniconfig"), @r###"
3980+
success: true
3981+
exit_code: 0
3982+
----- stdout -----
3983+
3984+
----- stderr -----
3985+
Resolved 2 packages in [TIME]
3986+
Prepared 1 package in [TIME]
3987+
Uninstalled 1 package in [TIME]
3988+
Installed 1 package in [TIME]
3989+
~ iniconfig==2.0.0
3990+
"###);
3991+
3992+
uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY", "1"), @r###"
3993+
success: true
3994+
exit_code: 0
3995+
----- stdout -----
3996+
3997+
----- stderr -----
3998+
Resolved 2 packages in [TIME]
3999+
Prepared 1 package in [TIME]
4000+
Uninstalled 1 package in [TIME]
4001+
Installed 1 package in [TIME]
4002+
~ iniconfig==2.0.0
4003+
"###);
4004+
4005+
uv_snapshot!(context.filters(), context.sync().arg("--reinstall").env("UV_NO_BINARY", "iniconfig"), @r###"
4006+
success: false
4007+
exit_code: 2
4008+
----- stdout -----
4009+
4010+
----- stderr -----
4011+
error: invalid value 'iniconfig' for '--no-binary': value was not a boolean
4012+
4013+
For more information, try '--help'.
4014+
"###);
4015+
39664016
Ok(())
39674017
}
39684018

docs/configuration/environment.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,17 @@ Equivalent to the `--locked` command-line argument. If set, uv will assert that
178178
Equivalent to the `--native-tls` command-line argument. If set to `true`, uv will
179179
use the system's trust store instead of the bundled `webpki-roots` crate.
180180

181+
### `UV_NO_BINARY`
182+
183+
Equivalent to the `--no-binary` command-line argument. If set, uv will install
184+
all packages from source. The resolver will still use pre-built wheels to
185+
extract package metadata, if available.
186+
187+
### `UV_NO_BINARY_PACKAGE`
188+
189+
Equivalent to the `--no-binary-package` command line argument. If set, uv will
190+
not use pre-built wheels for the given space-delimited list of packages.
191+
181192
### `UV_NO_BUILD_ISOLATION`
182193

183194
Equivalent to the `--no-build-isolation` command-line argument. If set, uv will

docs/reference/cli.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,8 +299,10 @@ uv run [OPTIONS] [COMMAND]
299299

300300
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
301301

302+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
302303
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
303304

305+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
304306
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
305307

306308
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -958,8 +960,10 @@ uv add [OPTIONS] <PACKAGES|--requirements <REQUIREMENTS>>
958960

959961
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
960962

963+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
961964
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
962965

966+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
963967
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
964968

965969
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -1319,8 +1323,10 @@ uv remove [OPTIONS] <PACKAGES>...
13191323

13201324
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
13211325

1326+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
13221327
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
13231328

1329+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
13241330
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
13251331

13261332
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -1692,8 +1698,10 @@ uv sync [OPTIONS]
16921698

16931699
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
16941700

1701+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
16951702
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
16961703

1704+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
16971705
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
16981706

16991707
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -2059,8 +2067,10 @@ uv lock [OPTIONS]
20592067

20602068
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
20612069

2070+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
20622071
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
20632072

2073+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
20642074
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
20652075

20662076
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -2404,8 +2414,10 @@ uv export [OPTIONS]
24042414

24052415
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
24062416

2417+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
24072418
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
24082419

2420+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
24092421
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
24102422

24112423
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -2782,8 +2794,10 @@ uv tree [OPTIONS]
27822794

27832795
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
27842796

2797+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
27852798
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
27862799

2800+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
27872801
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
27882802

27892803
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -3255,8 +3269,10 @@ uv tool run [OPTIONS] [COMMAND]
32553269

32563270
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
32573271

3272+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
32583273
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
32593274

3275+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
32603276
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
32613277

32623278
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -3584,8 +3600,10 @@ uv tool install [OPTIONS] <PACKAGE>
35843600

35853601
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
35863602

3603+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
35873604
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
35883605

3606+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
35893607
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
35903608

35913609
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -3907,8 +3925,10 @@ uv tool upgrade [OPTIONS] <NAME>...
39073925

39083926
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
39093927

3928+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
39103929
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
39113930

3931+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
39123932
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
39133933

39143934
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>
@@ -8349,8 +8369,10 @@ uv build [OPTIONS] [SRC]
83498369

83508370
<p>The given packages will be built and installed from source. The resolver will still use pre-built wheels to extract package metadata, if available.</p>
83518371

8372+
<p>May also be set with the <code>UV_NO_BINARY</code> environment variable.</p>
83528373
</dd><dt><code>--no-binary-package</code> <i>no-binary-package</i></dt><dd><p>Don&#8217;t install pre-built wheels for a specific package</p>
83538374

8375+
<p>May also be set with the <code>UV_NO_BINARY_PACKAGE</code> environment variable.</p>
83548376
</dd><dt><code>--no-build</code></dt><dd><p>Don&#8217;t build source distributions.</p>
83558377

83568378
<p>When enabled, resolving will not run arbitrary Python code. The cached wheels of already-built source distributions will be reused, but operations that require building distributions will exit with an error.</p>

0 commit comments

Comments
 (0)