diff --git a/crates/uv-cli/src/lib.rs b/crates/uv-cli/src/lib.rs
index f31a8e8499d9..0bf5415478e9 100644
--- a/crates/uv-cli/src/lib.rs
+++ b/crates/uv-cli/src/lib.rs
@@ -1263,9 +1263,12 @@ pub struct PipSyncArgs {
/// Require a matching hash for each requirement.
///
- /// Hash-checking mode is all or nothing. If enabled, _all_ requirements must be provided
- /// with a corresponding hash or set of hashes. Additionally, if enabled, _all_ requirements
- /// must either be pinned to exact versions (e.g., `==1.0.0`), or be specified via direct URL.
+ /// By default, uv will verify any available hashes in the requirements file, but will not
+ /// require that all requirements have an associated hash.
+ ///
+ /// When `--require-hashes` is enabled, _all_ requirements must include a hash or set of hashes,
+ /// and _all_ requirements must either be pinned to exact versions (e.g., `==1.0.0`), or be
+ /// specified via direct URL.
///
/// Hash-checking mode introduces a number of additional constraints:
///
@@ -1284,20 +1287,20 @@ pub struct PipSyncArgs {
#[arg(long, overrides_with("require_hashes"), hide = true)]
pub no_require_hashes: bool,
- /// Validate any hashes provided in the requirements file.
+ #[arg(long, overrides_with("no_verify_hashes"), hide = true)]
+ pub verify_hashes: bool,
+
+ /// Disable validation of hashes in the requirements file.
///
- /// Unlike `--require-hashes`, `--verify-hashes` does not require that all requirements have
- /// hashes; instead, it will limit itself to verifying the hashes of those requirements that do
- /// include them.
+ /// By default, uv will verify any available hashes in the requirements file, but will not
+ /// require that all requirements have an associated hash. To enforce hash validation, use
+ /// `--require-hashes`.
#[arg(
long,
- env = EnvVars::UV_VERIFY_HASHES,
+ env = EnvVars::UV_NO_VERIFY_HASHES,
value_parser = clap::builder::BoolishValueParser::new(),
- overrides_with("no_verify_hashes"),
+ overrides_with("verify_hashes"),
)]
- pub verify_hashes: bool,
-
- #[arg(long, overrides_with("verify_hashes"), hide = true)]
pub no_verify_hashes: bool,
/// The Python interpreter into which packages should be installed.
@@ -1546,9 +1549,12 @@ pub struct PipInstallArgs {
/// Require a matching hash for each requirement.
///
- /// Hash-checking mode is all or nothing. If enabled, _all_ requirements must be provided
- /// with a corresponding hash or set of hashes. Additionally, if enabled, _all_ requirements
- /// must either be pinned to exact versions (e.g., `==1.0.0`), or be specified via direct URL.
+ /// By default, uv will verify any available hashes in the requirements file, but will not
+ /// require that all requirements have an associated hash.
+ ///
+ /// When `--require-hashes` is enabled, _all_ requirements must include a hash or set of hashes,
+ /// and _all_ requirements must either be pinned to exact versions (e.g., `==1.0.0`), or be
+ /// specified via direct URL.
///
/// Hash-checking mode introduces a number of additional constraints:
///
@@ -1567,20 +1573,20 @@ pub struct PipInstallArgs {
#[arg(long, overrides_with("require_hashes"), hide = true)]
pub no_require_hashes: bool,
- /// Validate any hashes provided in the requirements file.
+ #[arg(long, overrides_with("no_verify_hashes"), hide = true)]
+ pub verify_hashes: bool,
+
+ /// Disable validation of hashes in the requirements file.
///
- /// Unlike `--require-hashes`, `--verify-hashes` does not require that all requirements have
- /// hashes; instead, it will limit itself to verifying the hashes of those requirements that do
- /// include them.
+ /// By default, uv will verify any available hashes in the requirements file, but will not
+ /// require that all requirements have an associated hash. To enforce hash validation, use
+ /// `--require-hashes`.
#[arg(
long,
- env = EnvVars::UV_VERIFY_HASHES,
+ env = EnvVars::UV_NO_VERIFY_HASHES,
value_parser = clap::builder::BoolishValueParser::new(),
- overrides_with("no_verify_hashes"),
+ overrides_with("verify_hashes"),
)]
- pub verify_hashes: bool,
-
- #[arg(long, overrides_with("verify_hashes"), hide = true)]
pub no_verify_hashes: bool,
/// The Python interpreter into which packages should be installed.
@@ -2177,12 +2183,14 @@ pub struct BuildArgs {
#[arg(long, short, env = EnvVars::UV_BUILD_CONSTRAINT, value_delimiter = ' ', value_parser = parse_maybe_file_path)]
pub build_constraint: Vec>,
- /// Require a matching hash for each build requirement.
+ /// Require a matching hash for each requirement.
+ ///
+ /// By default, uv will verify any available hashes in the requirements file, but will not
+ /// require that all requirements have an associated hash.
///
- /// Hash-checking mode is all or nothing. If enabled, _all_ build requirements must be provided
- /// with a corresponding hash or set of hashes via the `--build-constraint` argument.
- /// Additionally, if enabled, _all_ requirements must either be pinned to exact versions
- /// (e.g., `==1.0.0`), or be specified via direct URL.
+ /// When `--require-hashes` is enabled, _all_ requirements must include a hash or set of hashes,
+ /// and _all_ requirements must either be pinned to exact versions (e.g., `==1.0.0`), or be
+ /// specified via direct URL.
///
/// Hash-checking mode introduces a number of additional constraints:
///
@@ -2201,20 +2209,20 @@ pub struct BuildArgs {
#[arg(long, overrides_with("require_hashes"), hide = true)]
pub no_require_hashes: bool,
- /// Validate any hashes provided in the build constraints file.
+ #[arg(long, overrides_with("no_verify_hashes"), hide = true)]
+ pub verify_hashes: bool,
+
+ /// Disable validation of hashes in the requirements file.
///
- /// Unlike `--require-hashes`, `--verify-hashes` does not require that all requirements have
- /// hashes; instead, it will limit itself to verifying the hashes of those requirements that do
- /// include them.
+ /// By default, uv will verify any available hashes in the requirements file, but will not
+ /// require that all requirements have an associated hash. To enforce hash validation, use
+ /// `--require-hashes`.
#[arg(
long,
- env = EnvVars::UV_VERIFY_HASHES,
+ env = EnvVars::UV_NO_VERIFY_HASHES,
value_parser = clap::builder::BoolishValueParser::new(),
- overrides_with("no_verify_hashes"),
+ overrides_with("verify_hashes"),
)]
- pub verify_hashes: bool,
-
- #[arg(long, overrides_with("verify_hashes"), hide = true)]
pub no_verify_hashes: bool,
/// The Python interpreter to use for the build environment.
diff --git a/crates/uv-configuration/src/hash.rs b/crates/uv-configuration/src/hash.rs
index 52f6d0a01149..cadebbd1510a 100644
--- a/crates/uv-configuration/src/hash.rs
+++ b/crates/uv-configuration/src/hash.rs
@@ -9,13 +9,26 @@ pub enum HashCheckingMode {
impl HashCheckingMode {
/// Return the [`HashCheckingMode`] from the command-line arguments, if any.
- pub fn from_args(require_hashes: bool, verify_hashes: bool) -> Option {
- if require_hashes {
+ ///
+ /// By default, the hash checking mode is [`HashCheckingMode::Verify`]. If `--require-hashes` is
+ /// passed, the hash checking mode is [`HashCheckingMode::Require`]. If `--no-verify-hashes` is
+ /// passed, then no hash checking is performed.
+ pub fn from_args(require_hashes: Option, verify_hashes: Option) -> Option {
+ if require_hashes == Some(true) {
+ // Given `--require-hashes`, always require hashes, regardless of any other flags.
Some(Self::Require)
- } else if verify_hashes {
+ } else if verify_hashes == Some(true) {
+ // Given `--verify-hashes`, always verify hashes, regardless of any other flags.
Some(Self::Verify)
- } else {
+ } else if verify_hashes == Some(false) {
+ // Given `--no-verify-hashes` (without `--require-hashes`), do not verify hashes.
+ None
+ } else if require_hashes == Some(false) {
+ // Given `--no-require-hashes` (without `--verify-hashes`), do not require hashes.
None
+ } else {
+ // By default, verify hashes.
+ Some(Self::Verify)
}
}
diff --git a/crates/uv-settings/src/settings.rs b/crates/uv-settings/src/settings.rs
index 9b2d261da50e..200e3940df67 100644
--- a/crates/uv-settings/src/settings.rs
+++ b/crates/uv-settings/src/settings.rs
@@ -1348,7 +1348,7 @@ pub struct PipOptions {
/// hashes; instead, it will limit itself to verifying the hashes of those requirements that do
/// include them.
#[option(
- default = "false",
+ default = "true",
value_type = "bool",
example = r#"
verify-hashes = true
diff --git a/crates/uv-static/src/env_vars.rs b/crates/uv-static/src/env_vars.rs
index 63dc454a7117..33c2f2db8f10 100644
--- a/crates/uv-static/src/env_vars.rs
+++ b/crates/uv-static/src/env_vars.rs
@@ -167,8 +167,9 @@ impl EnvVars {
/// Equivalent to the `--token` argument for self update. A GitHub token for authentication.
pub const UV_GITHUB_TOKEN: &'static str = "UV_GITHUB_TOKEN";
- /// Equivalent to the `--verify-hashes` argument. Verifies included hashes.
- pub const UV_VERIFY_HASHES: &'static str = "UV_VERIFY_HASHES";
+ /// Equivalent to the `--no-verify-hashes` argument. Disables hash verification for
+ /// `requirements.txt` files.
+ pub const UV_NO_VERIFY_HASHES: &'static str = "UV_VERIFY_HASHES";
/// Equivalent to the `--allow-insecure-host` argument.
pub const UV_INSECURE_HOST: &'static str = "UV_INSECURE_HOST";
diff --git a/crates/uv/src/settings.rs b/crates/uv/src/settings.rs
index 8b6b44669809..375b00d97d65 100644
--- a/crates/uv/src/settings.rs
+++ b/crates/uv/src/settings.rs
@@ -2003,8 +2003,8 @@ impl BuildSettings {
.filter_map(Maybe::into_option)
.collect(),
hash_checking: HashCheckingMode::from_args(
- flag(require_hashes, no_require_hashes).unwrap_or_default(),
- flag(verify_hashes, no_verify_hashes).unwrap_or_default(),
+ flag(require_hashes, no_require_hashes),
+ flag(verify_hashes, no_verify_hashes),
),
python: python.and_then(Maybe::into_option),
refresh: Refresh::from(refresh),
@@ -2641,12 +2641,8 @@ impl PipSettings {
.unwrap_or_default(),
link_mode: args.link_mode.combine(link_mode).unwrap_or_default(),
hash_checking: HashCheckingMode::from_args(
- args.require_hashes
- .combine(require_hashes)
- .unwrap_or_default(),
- args.verify_hashes
- .combine(verify_hashes)
- .unwrap_or_default(),
+ args.require_hashes.combine(require_hashes),
+ args.verify_hashes.combine(verify_hashes),
),
python: args.python.combine(python),
system: args.system.combine(system).unwrap_or_default(),
diff --git a/crates/uv/tests/it/build.rs b/crates/uv/tests/it/build.rs
index d5404191c942..68e361940833 100644
--- a/crates/uv/tests/it/build.rs
+++ b/crates/uv/tests/it/build.rs
@@ -1447,103 +1447,40 @@ fn sha() -> Result<()> {
project.child("src").child("__init__.py").touch()?;
project.child("README").touch()?;
- // Ignore an incorrect hash, if `--require-hashes` is not provided.
+ // Reject an incorrect hash.
let constraints = project.child("constraints.txt");
constraints.write_str("setuptools==68.2.2 --hash=sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2")?;
uv_snapshot!(&filters, context.build().arg("--build-constraint").arg("constraints.txt").current_dir(&project), @r###"
- success: true
- exit_code: 0
+ success: false
+ exit_code: 2
----- stdout -----
----- stderr -----
Building source distribution...
- running egg_info
- creating src/project.egg-info
- writing src/project.egg-info/PKG-INFO
- writing dependency_links to src/project.egg-info/dependency_links.txt
- writing requirements to src/project.egg-info/requires.txt
- writing top-level names to src/project.egg-info/top_level.txt
- writing manifest file 'src/project.egg-info/SOURCES.txt'
- reading manifest file 'src/project.egg-info/SOURCES.txt'
- writing manifest file 'src/project.egg-info/SOURCES.txt'
- running sdist
- running egg_info
- writing src/project.egg-info/PKG-INFO
- writing dependency_links to src/project.egg-info/dependency_links.txt
- writing requirements to src/project.egg-info/requires.txt
- writing top-level names to src/project.egg-info/top_level.txt
- reading manifest file 'src/project.egg-info/SOURCES.txt'
- writing manifest file 'src/project.egg-info/SOURCES.txt'
- running check
- creating project-0.1.0
- creating project-0.1.0/src
- creating project-0.1.0/src/project.egg-info
- copying files to project-0.1.0...
- copying README -> project-0.1.0
- copying pyproject.toml -> project-0.1.0
- copying src/__init__.py -> project-0.1.0/src
- copying src/project.egg-info/PKG-INFO -> project-0.1.0/src/project.egg-info
- copying src/project.egg-info/SOURCES.txt -> project-0.1.0/src/project.egg-info
- copying src/project.egg-info/dependency_links.txt -> project-0.1.0/src/project.egg-info
- copying src/project.egg-info/requires.txt -> project-0.1.0/src/project.egg-info
- copying src/project.egg-info/top_level.txt -> project-0.1.0/src/project.egg-info
- Writing project-0.1.0/setup.cfg
- Creating tar archive
- removing 'project-0.1.0' (and everything under it)
- Building wheel from source distribution...
- running egg_info
- writing src/project.egg-info/PKG-INFO
- writing dependency_links to src/project.egg-info/dependency_links.txt
- writing requirements to src/project.egg-info/requires.txt
- writing top-level names to src/project.egg-info/top_level.txt
- reading manifest file 'src/project.egg-info/SOURCES.txt'
- writing manifest file 'src/project.egg-info/SOURCES.txt'
- running bdist_wheel
- running build
- running build_py
- creating build
- creating build/lib
- copying src/__init__.py -> build/lib
- running egg_info
- writing src/project.egg-info/PKG-INFO
- writing dependency_links to src/project.egg-info/dependency_links.txt
- writing requirements to src/project.egg-info/requires.txt
- writing top-level names to src/project.egg-info/top_level.txt
- reading manifest file 'src/project.egg-info/SOURCES.txt'
- writing manifest file 'src/project.egg-info/SOURCES.txt'
- installing to build/bdist.linux-x86_64/wheel
- running install
- running install_lib
- creating build/bdist.linux-x86_64
- creating build/bdist.linux-x86_64/wheel
- copying build/lib/__init__.py -> build/bdist.linux-x86_64/wheel
- running install_egg_info
- Copying src/project.egg-info to build/bdist.linux-x86_64/wheel/project-0.1.0-py3.8.egg-info
- running install_scripts
- creating build/bdist.linux-x86_64/wheel/project-0.1.0.dist-info/WHEEL
- creating '[TEMP_DIR]/project/dist/[TMP]/wheel' to it
- adding '__init__.py'
- adding 'project-0.1.0.dist-info/METADATA'
- adding 'project-0.1.0.dist-info/WHEEL'
- adding 'project-0.1.0.dist-info/top_level.txt'
- adding 'project-0.1.0.dist-info/RECORD'
- removing build/bdist.linux-x86_64/wheel
- Successfully built dist/project-0.1.0.tar.gz and dist/project-0.1.0-py3-none-any.whl
+ error: Failed to install requirements from `build-system.requires`
+ Caused by: Failed to download `setuptools==68.2.2`
+ Caused by: Hash mismatch for `setuptools==68.2.2`
+
+ Expected:
+ sha256:a248cb506794bececcddeddb1678bc722f9cfcacf02f98f7c0af6b9ed893caf2
+
+ Computed:
+ sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a
"###);
project
.child("dist")
.child("project-0.1.0.tar.gz")
- .assert(predicate::path::is_file());
+ .assert(predicate::path::missing());
project
.child("dist")
.child("project-0.1.0-py3-none-any.whl")
- .assert(predicate::path::is_file());
+ .assert(predicate::path::missing());
fs_err::remove_dir_all(project.child("dist"))?;
- // Reject an incorrect hash.
+ // Reject an incorrect hash with --requires-hashes.
uv_snapshot!(&filters, context.build().arg("--build-constraint").arg("constraints.txt").arg("--require-hashes").current_dir(&project), @r###"
success: false
exit_code: 2
@@ -1598,6 +1535,8 @@ fn sha() -> Result<()> {
.child("project-0.1.0-py3-none-any.whl")
.assert(predicate::path::missing());
+ fs_err::remove_dir_all(project.child("dist"))?;
+
// Accept a correct hash.
let constraints = project.child("constraints.txt");
constraints.write_str("setuptools==68.2.2 --hash=sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a")?;
@@ -1610,10 +1549,12 @@ fn sha() -> Result<()> {
----- stderr -----
Building source distribution...
running egg_info
+ creating src/project.egg-info
writing src/project.egg-info/PKG-INFO
writing dependency_links to src/project.egg-info/dependency_links.txt
writing requirements to src/project.egg-info/requires.txt
writing top-level names to src/project.egg-info/top_level.txt
+ writing manifest file 'src/project.egg-info/SOURCES.txt'
reading manifest file 'src/project.egg-info/SOURCES.txt'
writing manifest file 'src/project.egg-info/SOURCES.txt'
running sdist
diff --git a/crates/uv/tests/it/pip_install.rs b/crates/uv/tests/it/pip_install.rs
index 1ce62f494b1a..57b30771057c 100644
--- a/crates/uv/tests/it/pip_install.rs
+++ b/crates/uv/tests/it/pip_install.rs
@@ -6241,6 +6241,44 @@ fn verify_hashes_mismatch() -> Result<()> {
"###
);
+ uv_snapshot!(context.pip_install()
+ .arg("-r")
+ .arg("requirements.txt"), @r###"
+ success: false
+ exit_code: 1
+ ----- stdout -----
+
+ ----- stderr -----
+ Resolved 3 packages in [TIME]
+ × Failed to download `anyio==4.0.0`
+ ╰─▶ Hash mismatch for `anyio==4.0.0`
+
+ Expected:
+ sha256:afdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f
+ sha256:a7ed51751b2c2add651e5747c891b47e26d2a21be5d32d9311dfe9692f3e5d7a
+
+ Computed:
+ sha256:cfdb2b588b9fc25ede96d8db56ed50848b0b649dca3dd1df0b11f683bb9e0b5f
+ "###
+ );
+
+ uv_snapshot!(context.pip_install()
+ .arg("-r")
+ .arg("requirements.txt")
+ .arg("--no-verify-hashes"), @r###"
+ success: true
+ exit_code: 0
+ ----- stdout -----
+
+ ----- stderr -----
+ Resolved 3 packages in [TIME]
+ Installed 3 packages in [TIME]
+ + anyio==4.0.0
+ + idna==3.6
+ + sniffio==1.3.1
+ "###
+ );
+
Ok(())
}
diff --git a/crates/uv/tests/it/show_settings.rs b/crates/uv/tests/it/show_settings.rs
index 8083e3639038..2f964484b3c8 100644
--- a/crates/uv/tests/it/show_settings.rs
+++ b/crates/uv/tests/it/show_settings.rs
@@ -176,7 +176,9 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -327,7 +329,9 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -479,7 +483,9 @@ fn resolve_uv_toml() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -663,7 +669,9 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -787,7 +795,9 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -949,7 +959,9 @@ fn resolve_pyproject_toml() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -1153,7 +1165,9 @@ fn resolve_index_url() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -1364,7 +1378,9 @@ fn resolve_index_url() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -1540,7 +1556,9 @@ fn resolve_find_links() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -1686,7 +1704,9 @@ fn resolve_top_level() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -1882,7 +1902,9 @@ fn resolve_top_level() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -2061,7 +2083,9 @@ fn resolve_top_level() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -2207,7 +2231,9 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -2336,7 +2362,9 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -2465,7 +2493,9 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -2596,7 +2626,9 @@ fn resolve_user_configuration() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -2907,7 +2939,9 @@ fn resolve_poetry_toml() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -3093,7 +3127,9 @@ fn resolve_both() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -3367,7 +3403,9 @@ fn resolve_config_file() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -3590,7 +3628,9 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -3722,7 +3762,9 @@ fn resolve_skip_empty() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -3873,7 +3915,9 @@ fn allow_insecure_host() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -4075,7 +4119,9 @@ fn index_priority() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -4256,7 +4302,9 @@ fn index_priority() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -4443,7 +4491,9 @@ fn index_priority() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -4625,7 +4675,9 @@ fn index_priority() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -4814,7 +4866,9 @@ fn index_priority() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
@@ -4996,7 +5050,770 @@ fn index_priority() -> anyhow::Result<()> {
link_mode: Clone,
compile_bytecode: false,
sources: Enabled,
- hash_checking: None,
+ hash_checking: Some(
+ Verify,
+ ),
+ upgrade: None,
+ reinstall: None,
+ },
+ }
+
+ ----- stderr -----
+ "###
+ );
+
+ Ok(())
+}
+
+/// Verify hashes by default.
+#[test]
+#[cfg_attr(
+ windows,
+ ignore = "Configuration tests are not yet supported on Windows"
+)]
+fn verify_hashes() -> anyhow::Result<()> {
+ let context = TestContext::new("3.12");
+
+ let requirements_in = context.temp_dir.child("requirements.in");
+ requirements_in.write_str("anyio>3.0.0")?;
+
+ uv_snapshot!(context.filters(), add_shared_args(context.pip_install())
+ .arg("-r")
+ .arg("requirements.in")
+ .arg("--show-settings"), @r###"
+ success: true
+ exit_code: 0
+ ----- stdout -----
+ GlobalSettings {
+ quiet: false,
+ verbose: 0,
+ color: Auto,
+ native_tls: false,
+ concurrency: Concurrency {
+ downloads: 50,
+ builds: 16,
+ installs: 8,
+ },
+ connectivity: Online,
+ allow_insecure_host: [],
+ show_settings: true,
+ preview: Disabled,
+ python_preference: Managed,
+ python_downloads: Automatic,
+ no_progress: false,
+ }
+ CacheSettings {
+ no_cache: false,
+ cache_dir: Some(
+ "[CACHE_DIR]/",
+ ),
+ }
+ PipInstallSettings {
+ package: [],
+ requirement: [
+ "requirements.in",
+ ],
+ editable: [],
+ constraint: [],
+ override: [],
+ build_constraint: [],
+ dry_run: false,
+ constraints_from_workspace: [],
+ overrides_from_workspace: [],
+ modifications: Sufficient,
+ refresh: None(
+ Timestamp(
+ SystemTime {
+ tv_sec: [TIME],
+ tv_nsec: [TIME],
+ },
+ ),
+ ),
+ settings: PipSettings {
+ index_locations: IndexLocations {
+ indexes: [],
+ flat_index: [],
+ no_index: false,
+ },
+ python: None,
+ install_mirrors: PythonInstallMirrors {
+ python_install_mirror: None,
+ pypy_install_mirror: None,
+ },
+ system: false,
+ extras: None,
+ break_system_packages: false,
+ target: None,
+ prefix: None,
+ index_strategy: FirstIndex,
+ keyring_provider: Disabled,
+ no_build_isolation: false,
+ no_build_isolation_package: [],
+ build_options: BuildOptions {
+ no_binary: None,
+ no_build: None,
+ },
+ allow_empty_requirements: false,
+ strict: false,
+ dependency_mode: Transitive,
+ resolution: Highest,
+ prerelease: IfNecessaryOrExplicit,
+ dependency_metadata: DependencyMetadata(
+ {},
+ ),
+ output_file: None,
+ no_strip_extras: false,
+ no_strip_markers: false,
+ no_annotate: false,
+ no_header: false,
+ custom_compile_command: None,
+ generate_hashes: false,
+ config_setting: ConfigSettings(
+ {},
+ ),
+ python_version: None,
+ python_platform: None,
+ universal: false,
+ exclude_newer: Some(
+ ExcludeNewer(
+ 2024-03-25T00:00:00Z,
+ ),
+ ),
+ no_emit_package: [],
+ emit_index_url: false,
+ emit_find_links: false,
+ emit_build_options: false,
+ emit_marker_expression: false,
+ emit_index_annotation: false,
+ annotation_style: Split,
+ link_mode: Clone,
+ compile_bytecode: false,
+ sources: Enabled,
+ hash_checking: Some(
+ Verify,
+ ),
+ upgrade: None,
+ reinstall: None,
+ },
+ }
+
+ ----- stderr -----
+ "###
+ );
+
+ uv_snapshot!(context.filters(), add_shared_args(context.pip_install())
+ .arg("-r")
+ .arg("requirements.in")
+ .arg("--no-verify-hashes")
+ .arg("--show-settings"), @r###"
+ success: true
+ exit_code: 0
+ ----- stdout -----
+ GlobalSettings {
+ quiet: false,
+ verbose: 0,
+ color: Auto,
+ native_tls: false,
+ concurrency: Concurrency {
+ downloads: 50,
+ builds: 16,
+ installs: 8,
+ },
+ connectivity: Online,
+ allow_insecure_host: [],
+ show_settings: true,
+ preview: Disabled,
+ python_preference: Managed,
+ python_downloads: Automatic,
+ no_progress: false,
+ }
+ CacheSettings {
+ no_cache: false,
+ cache_dir: Some(
+ "[CACHE_DIR]/",
+ ),
+ }
+ PipInstallSettings {
+ package: [],
+ requirement: [
+ "requirements.in",
+ ],
+ editable: [],
+ constraint: [],
+ override: [],
+ build_constraint: [],
+ dry_run: false,
+ constraints_from_workspace: [],
+ overrides_from_workspace: [],
+ modifications: Sufficient,
+ refresh: None(
+ Timestamp(
+ SystemTime {
+ tv_sec: [TIME],
+ tv_nsec: [TIME],
+ },
+ ),
+ ),
+ settings: PipSettings {
+ index_locations: IndexLocations {
+ indexes: [],
+ flat_index: [],
+ no_index: false,
+ },
+ python: None,
+ install_mirrors: PythonInstallMirrors {
+ python_install_mirror: None,
+ pypy_install_mirror: None,
+ },
+ system: false,
+ extras: None,
+ break_system_packages: false,
+ target: None,
+ prefix: None,
+ index_strategy: FirstIndex,
+ keyring_provider: Disabled,
+ no_build_isolation: false,
+ no_build_isolation_package: [],
+ build_options: BuildOptions {
+ no_binary: None,
+ no_build: None,
+ },
+ allow_empty_requirements: false,
+ strict: false,
+ dependency_mode: Transitive,
+ resolution: Highest,
+ prerelease: IfNecessaryOrExplicit,
+ dependency_metadata: DependencyMetadata(
+ {},
+ ),
+ output_file: None,
+ no_strip_extras: false,
+ no_strip_markers: false,
+ no_annotate: false,
+ no_header: false,
+ custom_compile_command: None,
+ generate_hashes: false,
+ config_setting: ConfigSettings(
+ {},
+ ),
+ python_version: None,
+ python_platform: None,
+ universal: false,
+ exclude_newer: Some(
+ ExcludeNewer(
+ 2024-03-25T00:00:00Z,
+ ),
+ ),
+ no_emit_package: [],
+ emit_index_url: false,
+ emit_find_links: false,
+ emit_build_options: false,
+ emit_marker_expression: false,
+ emit_index_annotation: false,
+ annotation_style: Split,
+ link_mode: Clone,
+ compile_bytecode: false,
+ sources: Enabled,
+ hash_checking: None,
+ upgrade: None,
+ reinstall: None,
+ },
+ }
+
+ ----- stderr -----
+ "###
+ );
+
+ uv_snapshot!(context.filters(), add_shared_args(context.pip_install())
+ .arg("-r")
+ .arg("requirements.in")
+ .arg("--require-hashes")
+ .arg("--show-settings"), @r###"
+ success: true
+ exit_code: 0
+ ----- stdout -----
+ GlobalSettings {
+ quiet: false,
+ verbose: 0,
+ color: Auto,
+ native_tls: false,
+ concurrency: Concurrency {
+ downloads: 50,
+ builds: 16,
+ installs: 8,
+ },
+ connectivity: Online,
+ allow_insecure_host: [],
+ show_settings: true,
+ preview: Disabled,
+ python_preference: Managed,
+ python_downloads: Automatic,
+ no_progress: false,
+ }
+ CacheSettings {
+ no_cache: false,
+ cache_dir: Some(
+ "[CACHE_DIR]/",
+ ),
+ }
+ PipInstallSettings {
+ package: [],
+ requirement: [
+ "requirements.in",
+ ],
+ editable: [],
+ constraint: [],
+ override: [],
+ build_constraint: [],
+ dry_run: false,
+ constraints_from_workspace: [],
+ overrides_from_workspace: [],
+ modifications: Sufficient,
+ refresh: None(
+ Timestamp(
+ SystemTime {
+ tv_sec: [TIME],
+ tv_nsec: [TIME],
+ },
+ ),
+ ),
+ settings: PipSettings {
+ index_locations: IndexLocations {
+ indexes: [],
+ flat_index: [],
+ no_index: false,
+ },
+ python: None,
+ install_mirrors: PythonInstallMirrors {
+ python_install_mirror: None,
+ pypy_install_mirror: None,
+ },
+ system: false,
+ extras: None,
+ break_system_packages: false,
+ target: None,
+ prefix: None,
+ index_strategy: FirstIndex,
+ keyring_provider: Disabled,
+ no_build_isolation: false,
+ no_build_isolation_package: [],
+ build_options: BuildOptions {
+ no_binary: None,
+ no_build: None,
+ },
+ allow_empty_requirements: false,
+ strict: false,
+ dependency_mode: Transitive,
+ resolution: Highest,
+ prerelease: IfNecessaryOrExplicit,
+ dependency_metadata: DependencyMetadata(
+ {},
+ ),
+ output_file: None,
+ no_strip_extras: false,
+ no_strip_markers: false,
+ no_annotate: false,
+ no_header: false,
+ custom_compile_command: None,
+ generate_hashes: false,
+ config_setting: ConfigSettings(
+ {},
+ ),
+ python_version: None,
+ python_platform: None,
+ universal: false,
+ exclude_newer: Some(
+ ExcludeNewer(
+ 2024-03-25T00:00:00Z,
+ ),
+ ),
+ no_emit_package: [],
+ emit_index_url: false,
+ emit_find_links: false,
+ emit_build_options: false,
+ emit_marker_expression: false,
+ emit_index_annotation: false,
+ annotation_style: Split,
+ link_mode: Clone,
+ compile_bytecode: false,
+ sources: Enabled,
+ hash_checking: Some(
+ Require,
+ ),
+ upgrade: None,
+ reinstall: None,
+ },
+ }
+
+ ----- stderr -----
+ "###
+ );
+
+ uv_snapshot!(context.filters(), add_shared_args(context.pip_install())
+ .arg("-r")
+ .arg("requirements.in")
+ .arg("--no-require-hashes")
+ .arg("--show-settings"), @r###"
+ success: true
+ exit_code: 0
+ ----- stdout -----
+ GlobalSettings {
+ quiet: false,
+ verbose: 0,
+ color: Auto,
+ native_tls: false,
+ concurrency: Concurrency {
+ downloads: 50,
+ builds: 16,
+ installs: 8,
+ },
+ connectivity: Online,
+ allow_insecure_host: [],
+ show_settings: true,
+ preview: Disabled,
+ python_preference: Managed,
+ python_downloads: Automatic,
+ no_progress: false,
+ }
+ CacheSettings {
+ no_cache: false,
+ cache_dir: Some(
+ "[CACHE_DIR]/",
+ ),
+ }
+ PipInstallSettings {
+ package: [],
+ requirement: [
+ "requirements.in",
+ ],
+ editable: [],
+ constraint: [],
+ override: [],
+ build_constraint: [],
+ dry_run: false,
+ constraints_from_workspace: [],
+ overrides_from_workspace: [],
+ modifications: Sufficient,
+ refresh: None(
+ Timestamp(
+ SystemTime {
+ tv_sec: [TIME],
+ tv_nsec: [TIME],
+ },
+ ),
+ ),
+ settings: PipSettings {
+ index_locations: IndexLocations {
+ indexes: [],
+ flat_index: [],
+ no_index: false,
+ },
+ python: None,
+ install_mirrors: PythonInstallMirrors {
+ python_install_mirror: None,
+ pypy_install_mirror: None,
+ },
+ system: false,
+ extras: None,
+ break_system_packages: false,
+ target: None,
+ prefix: None,
+ index_strategy: FirstIndex,
+ keyring_provider: Disabled,
+ no_build_isolation: false,
+ no_build_isolation_package: [],
+ build_options: BuildOptions {
+ no_binary: None,
+ no_build: None,
+ },
+ allow_empty_requirements: false,
+ strict: false,
+ dependency_mode: Transitive,
+ resolution: Highest,
+ prerelease: IfNecessaryOrExplicit,
+ dependency_metadata: DependencyMetadata(
+ {},
+ ),
+ output_file: None,
+ no_strip_extras: false,
+ no_strip_markers: false,
+ no_annotate: false,
+ no_header: false,
+ custom_compile_command: None,
+ generate_hashes: false,
+ config_setting: ConfigSettings(
+ {},
+ ),
+ python_version: None,
+ python_platform: None,
+ universal: false,
+ exclude_newer: Some(
+ ExcludeNewer(
+ 2024-03-25T00:00:00Z,
+ ),
+ ),
+ no_emit_package: [],
+ emit_index_url: false,
+ emit_find_links: false,
+ emit_build_options: false,
+ emit_marker_expression: false,
+ emit_index_annotation: false,
+ annotation_style: Split,
+ link_mode: Clone,
+ compile_bytecode: false,
+ sources: Enabled,
+ hash_checking: None,
+ upgrade: None,
+ reinstall: None,
+ },
+ }
+
+ ----- stderr -----
+ "###
+ );
+
+ uv_snapshot!(context.filters(), add_shared_args(context.pip_install())
+ .arg("-r")
+ .arg("requirements.in")
+ .env("UV_NO_VERIFY_HASHES", "1")
+ .arg("--show-settings"), @r###"
+ success: true
+ exit_code: 0
+ ----- stdout -----
+ GlobalSettings {
+ quiet: false,
+ verbose: 0,
+ color: Auto,
+ native_tls: false,
+ concurrency: Concurrency {
+ downloads: 50,
+ builds: 16,
+ installs: 8,
+ },
+ connectivity: Online,
+ allow_insecure_host: [],
+ show_settings: true,
+ preview: Disabled,
+ python_preference: Managed,
+ python_downloads: Automatic,
+ no_progress: false,
+ }
+ CacheSettings {
+ no_cache: false,
+ cache_dir: Some(
+ "[CACHE_DIR]/",
+ ),
+ }
+ PipInstallSettings {
+ package: [],
+ requirement: [
+ "requirements.in",
+ ],
+ editable: [],
+ constraint: [],
+ override: [],
+ build_constraint: [],
+ dry_run: false,
+ constraints_from_workspace: [],
+ overrides_from_workspace: [],
+ modifications: Sufficient,
+ refresh: None(
+ Timestamp(
+ SystemTime {
+ tv_sec: [TIME],
+ tv_nsec: [TIME],
+ },
+ ),
+ ),
+ settings: PipSettings {
+ index_locations: IndexLocations {
+ indexes: [],
+ flat_index: [],
+ no_index: false,
+ },
+ python: None,
+ install_mirrors: PythonInstallMirrors {
+ python_install_mirror: None,
+ pypy_install_mirror: None,
+ },
+ system: false,
+ extras: None,
+ break_system_packages: false,
+ target: None,
+ prefix: None,
+ index_strategy: FirstIndex,
+ keyring_provider: Disabled,
+ no_build_isolation: false,
+ no_build_isolation_package: [],
+ build_options: BuildOptions {
+ no_binary: None,
+ no_build: None,
+ },
+ allow_empty_requirements: false,
+ strict: false,
+ dependency_mode: Transitive,
+ resolution: Highest,
+ prerelease: IfNecessaryOrExplicit,
+ dependency_metadata: DependencyMetadata(
+ {},
+ ),
+ output_file: None,
+ no_strip_extras: false,
+ no_strip_markers: false,
+ no_annotate: false,
+ no_header: false,
+ custom_compile_command: None,
+ generate_hashes: false,
+ config_setting: ConfigSettings(
+ {},
+ ),
+ python_version: None,
+ python_platform: None,
+ universal: false,
+ exclude_newer: Some(
+ ExcludeNewer(
+ 2024-03-25T00:00:00Z,
+ ),
+ ),
+ no_emit_package: [],
+ emit_index_url: false,
+ emit_find_links: false,
+ emit_build_options: false,
+ emit_marker_expression: false,
+ emit_index_annotation: false,
+ annotation_style: Split,
+ link_mode: Clone,
+ compile_bytecode: false,
+ sources: Enabled,
+ hash_checking: Some(
+ Verify,
+ ),
+ upgrade: None,
+ reinstall: None,
+ },
+ }
+
+ ----- stderr -----
+ "###
+ );
+
+ uv_snapshot!(context.filters(), add_shared_args(context.pip_install())
+ .arg("-r")
+ .arg("requirements.in")
+ .arg("--verify-hashes")
+ .arg("--no-require-hashes")
+ .arg("--show-settings"), @r###"
+ success: true
+ exit_code: 0
+ ----- stdout -----
+ GlobalSettings {
+ quiet: false,
+ verbose: 0,
+ color: Auto,
+ native_tls: false,
+ concurrency: Concurrency {
+ downloads: 50,
+ builds: 16,
+ installs: 8,
+ },
+ connectivity: Online,
+ allow_insecure_host: [],
+ show_settings: true,
+ preview: Disabled,
+ python_preference: Managed,
+ python_downloads: Automatic,
+ no_progress: false,
+ }
+ CacheSettings {
+ no_cache: false,
+ cache_dir: Some(
+ "[CACHE_DIR]/",
+ ),
+ }
+ PipInstallSettings {
+ package: [],
+ requirement: [
+ "requirements.in",
+ ],
+ editable: [],
+ constraint: [],
+ override: [],
+ build_constraint: [],
+ dry_run: false,
+ constraints_from_workspace: [],
+ overrides_from_workspace: [],
+ modifications: Sufficient,
+ refresh: None(
+ Timestamp(
+ SystemTime {
+ tv_sec: [TIME],
+ tv_nsec: [TIME],
+ },
+ ),
+ ),
+ settings: PipSettings {
+ index_locations: IndexLocations {
+ indexes: [],
+ flat_index: [],
+ no_index: false,
+ },
+ python: None,
+ install_mirrors: PythonInstallMirrors {
+ python_install_mirror: None,
+ pypy_install_mirror: None,
+ },
+ system: false,
+ extras: None,
+ break_system_packages: false,
+ target: None,
+ prefix: None,
+ index_strategy: FirstIndex,
+ keyring_provider: Disabled,
+ no_build_isolation: false,
+ no_build_isolation_package: [],
+ build_options: BuildOptions {
+ no_binary: None,
+ no_build: None,
+ },
+ allow_empty_requirements: false,
+ strict: false,
+ dependency_mode: Transitive,
+ resolution: Highest,
+ prerelease: IfNecessaryOrExplicit,
+ dependency_metadata: DependencyMetadata(
+ {},
+ ),
+ output_file: None,
+ no_strip_extras: false,
+ no_strip_markers: false,
+ no_annotate: false,
+ no_header: false,
+ custom_compile_command: None,
+ generate_hashes: false,
+ config_setting: ConfigSettings(
+ {},
+ ),
+ python_version: None,
+ python_platform: None,
+ universal: false,
+ exclude_newer: Some(
+ ExcludeNewer(
+ 2024-03-25T00:00:00Z,
+ ),
+ ),
+ no_emit_package: [],
+ emit_index_url: false,
+ emit_find_links: false,
+ emit_build_options: false,
+ emit_marker_expression: false,
+ emit_index_annotation: false,
+ annotation_style: Split,
+ link_mode: Clone,
+ compile_bytecode: false,
+ sources: Enabled,
+ hash_checking: Some(
+ Verify,
+ ),
upgrade: None,
reinstall: None,
},
diff --git a/docs/configuration/environment.md b/docs/configuration/environment.md
index b30ac7520dea..3d3f96d5f26c 100644
--- a/docs/configuration/environment.md
+++ b/docs/configuration/environment.md
@@ -188,6 +188,11 @@ Disables all progress output. For example, spinners and progress bars.
Equivalent to the `--no-sync` command-line argument. If set, uv will skip updating
the environment.
+### `UV_NO_VERIFY_HASHES`
+
+Equivalent to the `--no-verify-hashes` argument. Disables hash verification for
+`requirements.txt` files.
+
### `UV_NO_WRAP`
Use to disable line wrapping for diagnostics.
@@ -317,10 +322,6 @@ Specifies the directory where uv stores managed tools.
Used ephemeral environments like CI to install uv to a specific path while preventing
the installer from modifying shell profiles or environment variables.
-### `UV_VERIFY_HASHES`
-
-Equivalent to the `--verify-hashes` argument. Verifies included hashes.
-
## Externally defined variables
diff --git a/docs/reference/cli.md b/docs/reference/cli.md
index d60596633472..16edb5f3e62b 100644
--- a/docs/reference/cli.md
+++ b/docs/reference/cli.md
@@ -5753,6 +5753,11 @@ uv pip sync [OPTIONS] ...
--no-sources
Ignore the tool.uv.sources
table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources
+--no-verify-hashes
Disable validation of hashes in the requirements file.
+
+By default, uv will verify any available hashes in the requirements file, but will not require that all requirements have an associated hash. To enforce hash validation, use --require-hashes
.
+
+May also be set with the UV_VERIFY_HASHES
environment variable.
--offline
Disable network access.
When disabled, uv will only use locally cached data and locally available files.
@@ -5859,7 +5864,9 @@ uv pip sync [OPTIONS] ...
--require-hashes
Require a matching hash for each requirement.
-Hash-checking mode is all or nothing. If enabled, all requirements must be provided with a corresponding hash or set of hashes. Additionally, if enabled, all requirements must either be pinned to exact versions (e.g., ==1.0.0
), or be specified via direct URL.
+By default, uv will verify any available hashes in the requirements file, but will not require that all requirements have an associated hash.
+
+When --require-hashes
is enabled, all requirements must include a hash or set of hashes, and all requirements must either be pinned to exact versions (e.g., ==1.0.0
), or be specified via direct URL.
Hash-checking mode introduces a number of additional constraints:
@@ -5883,11 +5890,6 @@ uv pip sync [OPTIONS] ...
You can configure fine-grained logging using the RUST_LOG
environment variable. (<https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives>)
---verify-hashes
Validate any hashes provided in the requirements file.
-
-Unlike --require-hashes
, --verify-hashes
does not require that all requirements have hashes; instead, it will limit itself to verifying the hashes of those requirements that do include them.
-
-May also be set with the UV_VERIFY_HASHES
environment variable.
--version
, -V
Display the uv version
@@ -6128,6 +6130,11 @@ uv pip install [OPTIONS] |--editable --no-sources
Ignore the tool.uv.sources
table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources
+--no-verify-hashes
Disable validation of hashes in the requirements file.
+
+By default, uv will verify any available hashes in the requirements file, but will not require that all requirements have an associated hash. To enforce hash validation, use --require-hashes
.
+
+May also be set with the UV_VERIFY_HASHES
environment variable.
--offline
Disable network access.
When disabled, uv will only use locally cached data and locally available files.
@@ -6259,7 +6266,9 @@ uv pip install [OPTIONS] |--editable --require-hashes
Require a matching hash for each requirement.
-Hash-checking mode is all or nothing. If enabled, all requirements must be provided with a corresponding hash or set of hashes. Additionally, if enabled, all requirements must either be pinned to exact versions (e.g., ==1.0.0
), or be specified via direct URL.
+By default, uv will verify any available hashes in the requirements file, but will not require that all requirements have an associated hash.
+
+When --require-hashes
is enabled, all requirements must include a hash or set of hashes, and all requirements must either be pinned to exact versions (e.g., ==1.0.0
), or be specified via direct URL.
Hash-checking mode introduces a number of additional constraints:
@@ -6307,11 +6316,6 @@ uv pip install [OPTIONS] |--editable You can configure fine-grained logging using the RUST_LOG
environment variable. (<https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives>)
---verify-hashes
Validate any hashes provided in the requirements file.
-
-Unlike --require-hashes
, --verify-hashes
does not require that all requirements have hashes; instead, it will limit itself to verifying the hashes of those requirements that do include them.
-
-May also be set with the UV_VERIFY_HASHES
environment variable.
--version
, -V
Display the uv version
@@ -7721,6 +7725,11 @@ uv build [OPTIONS] [SRC]
--no-sources
Ignore the tool.uv.sources
table when resolving dependencies. Used to lock against the standards-compliant, publishable package metadata, as opposed to using any local or Git sources
+--no-verify-hashes
Disable validation of hashes in the requirements file.
+
+By default, uv will verify any available hashes in the requirements file, but will not require that all requirements have an associated hash. To enforce hash validation, use --require-hashes
.
+
+May also be set with the UV_VERIFY_HASHES
environment variable.
--offline
Disable network access.
When disabled, uv will only use locally cached data and locally available files.
@@ -7792,9 +7801,11 @@ uv build [OPTIONS] [SRC]
--refresh-package
refresh-packageRefresh cached data for a specific package
---require-hashes
Require a matching hash for each build requirement.
+--require-hashes
Require a matching hash for each requirement.
+
+By default, uv will verify any available hashes in the requirements file, but will not require that all requirements have an associated hash.
-Hash-checking mode is all or nothing. If enabled, all build requirements must be provided with a corresponding hash or set of hashes via the --build-constraint
argument. Additionally, if enabled, all requirements must either be pinned to exact versions (e.g., ==1.0.0
), or be specified via direct URL.
+When --require-hashes
is enabled, all requirements must include a hash or set of hashes, and all requirements must either be pinned to exact versions (e.g., ==1.0.0
), or be specified via direct URL.
Hash-checking mode introduces a number of additional constraints:
@@ -7827,11 +7838,6 @@ uv build [OPTIONS] [SRC]
You can configure fine-grained logging using the RUST_LOG
environment variable. (<https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html#directives>)
---verify-hashes
Validate any hashes provided in the build constraints file.
-
-Unlike --require-hashes
, --verify-hashes
does not require that all requirements have hashes; instead, it will limit itself to verifying the hashes of those requirements that do include them.
-
-May also be set with the UV_VERIFY_HASHES
environment variable.
--version
, -V
Display the uv version
--wheel
Build a binary distribution ("wheel") from the given directory
diff --git a/docs/reference/settings.md b/docs/reference/settings.md
index df8c9a9fd555..02d3aecbcfbc 100644
--- a/docs/reference/settings.md
+++ b/docs/reference/settings.md
@@ -3104,7 +3104,7 @@ Unlike `--require-hashes`, `--verify-hashes` does not require that all requireme
hashes; instead, it will limit itself to verifying the hashes of those requirements that do
include them.
-**Default value**: `false`
+**Default value**: `true`
**Type**: `bool`