From 552c95072a4aef99628266d6dbbf7f6e6698e702 Mon Sep 17 00:00:00 2001 From: nichmor Date: Tue, 5 Nov 2024 12:44:16 +0200 Subject: [PATCH 01/10] feat: add custom pypi indexes but wip --- .../src/pypi/pypi_requirement.rs | 56 ++++++++++++++++--- .../pixi_uv_conversions/src/requirements.rs | 5 +- src/cli/project/export/conda_environment.rs | 4 +- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/crates/pixi_manifest/src/pypi/pypi_requirement.rs b/crates/pixi_manifest/src/pypi/pypi_requirement.rs index abf069e2d..88ed8e825 100644 --- a/crates/pixi_manifest/src/pypi/pypi_requirement.rs +++ b/crates/pixi_manifest/src/pypi/pypi_requirement.rs @@ -85,6 +85,8 @@ pub enum PyPiRequirement { version: VersionOrStar, #[serde(default)] extras: Vec, + #[serde(default)] + index: Option, }, RawVersion(VersionOrStar), } @@ -138,6 +140,10 @@ struct RawPyPiRequirement { // Git and Url only pub subdirectory: Option, + + // Pinned index + #[serde(default)] + pub index: Option, } impl<'de> Deserialize<'de> for PyPiRequirement { @@ -186,18 +192,24 @@ impl<'de> Deserialize<'de> for PyPiRequirement { ))); } - let req = match (raw_req.url, raw_req.path, raw_req.git, raw_req.extras) { - (Some(url), None, None, extras) => PyPiRequirement::Url { + let req = match ( + raw_req.url, + raw_req.path, + raw_req.git, + raw_req.extras, + raw_req.index, + ) { + (Some(url), None, None, extras, index) => PyPiRequirement::Url { url, extras, subdirectory: raw_req.subdirectory, }, - (None, Some(path), None, extras) => PyPiRequirement::Path { + (None, Some(path), None, extras, index) => PyPiRequirement::Path { path, editable: raw_req.editable, extras, }, - (None, None, Some(git), extras) => PyPiRequirement::Git { + (None, None, Some(git), extras, index) => PyPiRequirement::Git { url: ParsedGitUrl { git, branch: raw_req.branch, @@ -207,13 +219,15 @@ impl<'de> Deserialize<'de> for PyPiRequirement { }, extras, }, - (None, None, None, extras) => PyPiRequirement::Version { + (None, None, None, extras, index) => PyPiRequirement::Version { version: raw_req.version.unwrap_or(VersionOrStar::Star), extras, + index, }, - (_, _, _, extras) if !extras.is_empty() => PyPiRequirement::Version { + (_, _, _, extras, index) if !extras.is_empty() => PyPiRequirement::Version { version: raw_req.version.unwrap_or(VersionOrStar::Star), extras, + index, }, _ => { return Err(serde_untagged::de::Error::custom( @@ -278,17 +292,35 @@ impl From for toml_edit::Value { } } + fn insert_index(table: &mut toml_edit::InlineTable, index: &Option) { + if let Some(index) = index { + table.insert( + "index", + toml_edit::Value::String(toml_edit::Formatted::new(index.to_string())), + ); + } + } + match &val { - PyPiRequirement::Version { version, extras } if extras.is_empty() => { + PyPiRequirement::Version { + version, + extras, + index, + } if extras.is_empty() && index.is_none() => { toml_edit::Value::from(version.to_string()) } - PyPiRequirement::Version { version, extras } => { + PyPiRequirement::Version { + version, + extras, + index, + } => { let mut table = toml_edit::Table::new().into_inline_table(); table.insert( "version", toml_edit::Value::String(toml_edit::Formatted::new(version.to_string())), ); insert_extras(&mut table, extras); + insert_index(&mut table, index); toml_edit::Value::InlineTable(table.to_owned()) } PyPiRequirement::Git { @@ -423,6 +455,7 @@ impl TryFrom for PyPiRequirement { pep508_rs::VersionOrUrl::VersionSpecifier(v) => PyPiRequirement::Version { version: v.into(), extras: req.extras, + index: None, }, pep508_rs::VersionOrUrl::Url(u) => { let url = u.to_url(); @@ -494,6 +527,7 @@ impl TryFrom for PyPiRequirement { PyPiRequirement::Version { version: VersionOrStar::Star, extras: req.extras, + index: None, } } else { PyPiRequirement::RawVersion(VersionOrStar::Star) @@ -538,6 +572,9 @@ impl PyPiRequirement { } } +#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] +pub struct IndexName(String); + #[cfg(test)] mod tests { use std::str::FromStr; @@ -616,6 +653,7 @@ mod tests { &PyPiRequirement::Version { version: ">=3.12".parse().unwrap(), extras: vec![ExtraName::from_str("bar").unwrap()], + index: None, } ); @@ -636,6 +674,7 @@ mod tests { ExtraName::from_str("bar").unwrap(), ExtraName::from_str("foo").unwrap(), ], + index: None, } ); } @@ -659,6 +698,7 @@ mod tests { ExtraName::from_str("feature1").unwrap(), ExtraName::from_str("feature2").unwrap() ], + index: None, } ); } diff --git a/crates/pixi_uv_conversions/src/requirements.rs b/crates/pixi_uv_conversions/src/requirements.rs index 1e9977868..b06b766f7 100644 --- a/crates/pixi_uv_conversions/src/requirements.rs +++ b/crates/pixi_uv_conversions/src/requirements.rs @@ -14,6 +14,7 @@ use uv_distribution_filename::DistExtension; use uv_git::{GitReference, GitSha}; use uv_normalize::{InvalidNameError, PackageName}; use uv_pep440::VersionSpecifiers; +use uv_pep508::Requirement; use uv_pep508::VerbatimUrl; use uv_pypi_types::RequirementSource; @@ -82,11 +83,11 @@ pub fn as_uv_req( ) -> Result { let name = PackageName::new(name.to_owned())?; let source = match req { - PyPiRequirement::Version { version, .. } => { + PyPiRequirement::Version { version, index, .. } => { // TODO: implement index later RequirementSource::Registry { specifier: to_version_specificers(version)?, - index: None, + index: index.clone(), } } PyPiRequirement::Git { diff --git a/src/cli/project/export/conda_environment.rs b/src/cli/project/export/conda_environment.rs index aafb86791..dae0f7623 100644 --- a/src/cli/project/export/conda_environment.rs +++ b/src/cli/project/export/conda_environment.rs @@ -106,7 +106,9 @@ fn format_pip_dependency(name: &PyPiPackageName, requirement: &PyPiRequirement) url_string } - PyPiRequirement::Version { version, extras } => { + PyPiRequirement::Version { + version, extras, .. + } => { format!( "{name}{extras}{version}", name = name.as_normalized(), From 697f2860fc12314314efb41ad3d7a61a41ca26cd Mon Sep 17 00:00:00 2001 From: nichmor Date: Tue, 5 Nov 2024 16:36:08 +0200 Subject: [PATCH 02/10] misc: add index schema --- .../src/pypi/pypi_requirement.rs | 6 +-- schema/examples/valid/full.toml | 1 + schema/model.py | 4 ++ schema/schema.json | 6 +++ tests/integration_rust/add_tests.rs | 1 + tests/integration_rust/common/mod.rs | 24 ++++++++++- tests/integration_rust/pypi_tests.rs | 42 +++++++++++++++++++ 7 files changed, 80 insertions(+), 4 deletions(-) diff --git a/crates/pixi_manifest/src/pypi/pypi_requirement.rs b/crates/pixi_manifest/src/pypi/pypi_requirement.rs index 88ed8e825..4f43751c0 100644 --- a/crates/pixi_manifest/src/pypi/pypi_requirement.rs +++ b/crates/pixi_manifest/src/pypi/pypi_requirement.rs @@ -199,17 +199,17 @@ impl<'de> Deserialize<'de> for PyPiRequirement { raw_req.extras, raw_req.index, ) { - (Some(url), None, None, extras, index) => PyPiRequirement::Url { + (Some(url), None, None, extras, None) => PyPiRequirement::Url { url, extras, subdirectory: raw_req.subdirectory, }, - (None, Some(path), None, extras, index) => PyPiRequirement::Path { + (None, Some(path), None, extras, None) => PyPiRequirement::Path { path, editable: raw_req.editable, extras, }, - (None, None, Some(git), extras, index) => PyPiRequirement::Git { + (None, None, Some(git), extras, None) => PyPiRequirement::Git { url: ParsedGitUrl { git, branch: raw_req.branch, diff --git a/schema/examples/valid/full.toml b/schema/examples/valid/full.toml index 515b953e9..34174227f 100644 --- a/schema/examples/valid/full.toml +++ b/schema/examples/valid/full.toml @@ -48,6 +48,7 @@ requests = { version = ">= 2.8.1, ==2.8.*", extras = [ "security", "tests", ] } # Using the map allows the user to add `extras` +test-pinning-index = { version = "*", index = "https://example.com/test" } testpypi = "*" testpypi1 = "*" diff --git a/schema/model.py b/schema/model.py index 2b0062703..99612ea0f 100644 --- a/schema/model.py +++ b/schema/model.py @@ -241,6 +241,10 @@ class PyPIVersion(_PyPIRequirement): None, description="The version of the package in [PEP 440](https://www.python.org/dev/peps/pep-0440/) format", ) + index: NonEmptyStr | None = Field( + None, + description="The index to fetch the package from", + ) PyPIRequirement = ( diff --git a/schema/schema.json b/schema/schema.json index fb2a0cf31..28ff0a218 100644 --- a/schema/schema.json +++ b/schema/schema.json @@ -1057,6 +1057,12 @@ "minLength": 1 } }, + "index": { + "title": "Index", + "description": "The index to fetch the package from", + "type": "string", + "minLength": 1 + }, "version": { "title": "Version", "description": "The version of the package in [PEP 440](https://www.python.org/dev/peps/pep-0440/) format", diff --git a/tests/integration_rust/add_tests.rs b/tests/integration_rust/add_tests.rs index 618e043c1..2be8ee37f 100644 --- a/tests/integration_rust/add_tests.rs +++ b/tests/integration_rust/add_tests.rs @@ -440,6 +440,7 @@ async fn add_pypi_extra_functionality() { PyPiRequirement::Version { version: VersionOrStar::from_str("==24.8.0").unwrap(), extras: vec![pep508_rs::ExtraName::from_str("cli").unwrap()], + index: None } ); } diff --git a/tests/integration_rust/common/mod.rs b/tests/integration_rust/common/mod.rs index bcf635412..5dc30d7c3 100644 --- a/tests/integration_rust/common/mod.rs +++ b/tests/integration_rust/common/mod.rs @@ -32,7 +32,7 @@ use pixi_consts::consts; use pixi_manifest::{EnvironmentName, FeatureName}; use pixi_progress::global_multi_progress; use rattler_conda_types::{MatchSpec, ParseStrictness::Lenient, Platform}; -use rattler_lock::{LockFile, Package}; +use rattler_lock::{LockFile, Package, UrlOrPath}; use tempfile::TempDir; use thiserror::Error; @@ -101,6 +101,13 @@ pub trait LockFileExt { platform: Platform, package: &str, ) -> Option; + + fn get_pypi_package_url( + &self, + environment: &str, + platform: Platform, + package: &str, + ) -> Option; } impl LockFileExt for LockFile { @@ -179,6 +186,20 @@ impl LockFileExt for LockFile { }) .map(|p| p.version().to_string()) } + + fn get_pypi_package_url( + &self, + environment: &str, + platform: Platform, + package: &str, + ) -> Option { + self.environment(environment) + .and_then(|env| { + env.packages(platform) + .and_then(|mut packages| packages.find(|p| p.name() == package)) + }) + .map(|p| p.url_or_path().into_owned()) + } } impl PixiControl { @@ -194,6 +215,7 @@ impl PixiControl { /// Creates a new PixiControl instance from an existing manifest pub fn from_manifest(manifest: &str) -> miette::Result { let pixi = Self::new()?; + eprintln!("manifest is {}", manifest); std::fs::write(pixi.manifest_path(), manifest) .into_diagnostic() .context("failed to write pixi.toml")?; diff --git a/tests/integration_rust/pypi_tests.rs b/tests/integration_rust/pypi_tests.rs index 293800033..0ae3d16cf 100644 --- a/tests/integration_rust/pypi_tests.rs +++ b/tests/integration_rust/pypi_tests.rs @@ -82,3 +82,45 @@ async fn test_index_strategy() { Some("3.0.0".into()) ); } + +#[tokio::test] +#[cfg_attr(not(feature = "slow_integration_tests"), ignore)] +async fn test_pinning_index() { + let pypi_indexes = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/data/pypi-indexes"); + let pypi_indexes_url = Url::from_directory_path(pypi_indexes.clone()).unwrap(); + + let pixi = PixiControl::from_manifest(&format!( + r#" + [project] + name = "pypi-pinning-index" + platforms = ["{platform}"] + channels = ["conda-forge"] + + [dependencies] + python = "~=3.12.0" + + [pypi-dependencies] + foo = {{ version = "*", index = "{pypi_indexes}multiple-indexes-a/index" }} + + "#, + platform = Platform::current(), + pypi_indexes = pypi_indexes_url, + )); + + let lock_file = pixi.unwrap().update_lock_file().await.unwrap(); + + assert_eq!( + lock_file + .get_pypi_package_url("default", Platform::current(), "foo") + .unwrap() + .as_url() + .unwrap() + .to_file_path() + .unwrap(), + pypi_indexes + .join("multiple-indexes-a/index/foo") + .join("foo-1.0.0-py2.py3-none-any.whl") + ); + + eprintln!("path is {:?}", pypi_indexes); +} From 211d9911485296bcf81449ac3658d5c53f144563 Mon Sep 17 00:00:00 2001 From: nichmor Date: Tue, 5 Nov 2024 16:39:14 +0200 Subject: [PATCH 03/10] misc: remove unused index name --- crates/pixi_manifest/src/pypi/pypi_requirement.rs | 3 --- crates/pixi_uv_conversions/src/requirements.rs | 1 - 2 files changed, 4 deletions(-) diff --git a/crates/pixi_manifest/src/pypi/pypi_requirement.rs b/crates/pixi_manifest/src/pypi/pypi_requirement.rs index 4f43751c0..3e621450a 100644 --- a/crates/pixi_manifest/src/pypi/pypi_requirement.rs +++ b/crates/pixi_manifest/src/pypi/pypi_requirement.rs @@ -572,9 +572,6 @@ impl PyPiRequirement { } } -#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)] -pub struct IndexName(String); - #[cfg(test)] mod tests { use std::str::FromStr; diff --git a/crates/pixi_uv_conversions/src/requirements.rs b/crates/pixi_uv_conversions/src/requirements.rs index b06b766f7..f2ba973a6 100644 --- a/crates/pixi_uv_conversions/src/requirements.rs +++ b/crates/pixi_uv_conversions/src/requirements.rs @@ -14,7 +14,6 @@ use uv_distribution_filename::DistExtension; use uv_git::{GitReference, GitSha}; use uv_normalize::{InvalidNameError, PackageName}; use uv_pep440::VersionSpecifiers; -use uv_pep508::Requirement; use uv_pep508::VerbatimUrl; use uv_pypi_types::RequirementSource; From 2dc2573ec3afdd7c6d604414d151bf7b70b8a649 Mon Sep 17 00:00:00 2001 From: nichmor Date: Tue, 5 Nov 2024 17:19:26 +0200 Subject: [PATCH 04/10] misc: update snapshot --- ...est__pypi__pypi_requirement__tests__deserialize_failing.snap | 2 +- ...__pypi__pypi_requirement__tests__deserialize_succeeding.snap | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/crates/pixi_manifest/src/pypi/snapshots/pixi_manifest__pypi__pypi_requirement__tests__deserialize_failing.snap b/crates/pixi_manifest/src/pypi/snapshots/pixi_manifest__pypi__pypi_requirement__tests__deserialize_failing.snap index 139b6c4d9..fff924ca7 100644 --- a/crates/pixi_manifest/src/pypi/snapshots/pixi_manifest__pypi__pypi_requirement__tests__deserialize_failing.snap +++ b/crates/pixi_manifest/src/pypi/snapshots/pixi_manifest__pypi__pypi_requirement__tests__deserialize_failing.snap @@ -5,7 +5,7 @@ expression: snapshot - input: ver: 1.2.3 result: - error: "ERROR: unknown field `ver`, expected one of `version`, `extras`, `path`, `editable`, `git`, `branch`, `tag`, `rev`, `url`, `subdirectory`" + error: "ERROR: unknown field `ver`, expected one of `version`, `extras`, `path`, `editable`, `git`, `branch`, `tag`, `rev`, `url`, `subdirectory`, `index`" - input: path: foobar version: "==1.2.3" diff --git a/crates/pixi_manifest/src/pypi/snapshots/pixi_manifest__pypi__pypi_requirement__tests__deserialize_succeeding.snap b/crates/pixi_manifest/src/pypi/snapshots/pixi_manifest__pypi__pypi_requirement__tests__deserialize_succeeding.snap index 431b7e49d..00e440f7b 100644 --- a/crates/pixi_manifest/src/pypi/snapshots/pixi_manifest__pypi__pypi_requirement__tests__deserialize_succeeding.snap +++ b/crates/pixi_manifest/src/pypi/snapshots/pixi_manifest__pypi__pypi_requirement__tests__deserialize_succeeding.snap @@ -9,6 +9,7 @@ expression: snapshot result: version: "==1.2.3" extras: [] + index: ~ - input: "*" result: "*" - input: From 17ccc6b2ad5206543f542e1f886cb992074d134d Mon Sep 17 00:00:00 2001 From: nichmor Date: Tue, 5 Nov 2024 17:27:59 +0200 Subject: [PATCH 05/10] misc: add docs for index --- docs/reference/project_configuration.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/docs/reference/project_configuration.md b/docs/reference/project_configuration.md index 1559c77f0..1b5b0a6ab 100644 --- a/docs/reference/project_configuration.md +++ b/docs/reference/project_configuration.md @@ -468,6 +468,19 @@ ruff = "~=1.0.0" pytest = {version = "*", extras = ["dev"]} ``` +##### `index` + +The index parameter allows you to specify the URL of a custom package index for the installation of a specific package. +This feature is useful when you want to ensure that a package is retrieved from a particular source, rather than from the default index. + +For example, you can use either the official Python Package Index (PyPI) at https://pypi.org/simple or an alternative private index like https://example.com/simple. + +Use `index` in combination with `version`: + +```toml +torch = { version = "*", index = "https://download.pytorch.org/whl/cu118" } +``` + ##### `git` A git repository to install from. From 122c0f5bee1e991381ac77def017aa109ccb5115 Mon Sep 17 00:00:00 2001 From: Tim de Jager Date: Mon, 18 Nov 2024 15:41:01 +0100 Subject: [PATCH 06/10] Update tests/integration_rust/common/mod.rs Co-authored-by: Ruben Arts --- tests/integration_rust/common/mod.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration_rust/common/mod.rs b/tests/integration_rust/common/mod.rs index 7b5a4853c..6618d5c7a 100644 --- a/tests/integration_rust/common/mod.rs +++ b/tests/integration_rust/common/mod.rs @@ -220,7 +220,6 @@ impl PixiControl { /// Creates a new PixiControl instance from an existing manifest pub fn from_manifest(manifest: &str) -> miette::Result { let pixi = Self::new()?; - eprintln!("manifest is {}", manifest); std::fs::write(pixi.manifest_path(), manifest) .into_diagnostic() .context("failed to write pixi.toml")?; From 49807180bc20d0f3b4c7bac4714676a9507129e5 Mon Sep 17 00:00:00 2001 From: Tim de Jager Date: Thu, 21 Nov 2024 14:26:12 +0100 Subject: [PATCH 07/10] feat: fix tests --- tests/integration_rust/pypi_tests.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/tests/integration_rust/pypi_tests.rs b/tests/integration_rust/pypi_tests.rs index 2c07ec4db..e8455de0e 100644 --- a/tests/integration_rust/pypi_tests.rs +++ b/tests/integration_rust/pypi_tests.rs @@ -194,14 +194,10 @@ async fn test_pinning_index() { lock_file .get_pypi_package_url("default", Platform::current(), "foo") .unwrap() - .as_url() - .unwrap() - .to_file_path() + .as_path() .unwrap(), pypi_indexes .join("multiple-indexes-a/index/foo") .join("foo-1.0.0-py2.py3-none-any.whl") ); - - eprintln!("path is {:?}", pypi_indexes); } From f91bdc8c0d2bb7fbe8cc1b788661e737a0f922b0 Mon Sep 17 00:00:00 2001 From: Tim de Jager Date: Thu, 21 Nov 2024 14:57:16 +0100 Subject: [PATCH 08/10] feat: add torch-specific test as requested --- tests/integration_rust/pypi_tests.rs | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/tests/integration_rust/pypi_tests.rs b/tests/integration_rust/pypi_tests.rs index e8455de0e..b9064c3d7 100644 --- a/tests/integration_rust/pypi_tests.rs +++ b/tests/integration_rust/pypi_tests.rs @@ -166,6 +166,7 @@ async fn test_index_strategy() { #[tokio::test] #[cfg_attr(not(feature = "slow_integration_tests"), ignore)] +/// This test checks if we can pin a package from a PyPI index, by explicitly specifying the index. async fn test_pinning_index() { let pypi_indexes = Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/data/pypi-indexes"); let pypi_indexes_url = Url::from_directory_path(pypi_indexes.clone()).unwrap(); @@ -201,3 +202,43 @@ async fn test_pinning_index() { .join("foo-1.0.0-py2.py3-none-any.whl") ); } + +#[tokio::test] +#[cfg_attr(not(feature = "slow_integration_tests"), ignore)] +/// This test checks if we can receive torch correctly from the whl/cu124 index. +async fn pin_torch() { + /// Do some platform magic, as the index does not contain wheels for each platform. + let platform = Platform::current(); + let platforms = match platform { + Platform::Linux64 => "\"linux-64\"".to_string(), + _ => format!("\"{platform}\", \"linux-64\"", platform = platform), + }; + + let pixi = PixiControl::from_manifest(&format!( + r#" + [project] + name = "pypi-pinning-index" + platforms = [{platforms}] + channels = ["conda-forge"] + + [dependencies] + python = "~=3.12.0" + + [target.linux-64.pypi-dependencies] + torch = {{ version = "*", index = "https://download.pytorch.org/whl/cu124" }} + "#, + platforms = platforms, + )); + + let lock_file = pixi.unwrap().update_lock_file().await.unwrap(); + // So the check is as follows: + // 1. The PyPI index is the main index-url, so normally torch would be taken from there. + // 2. We manually check if it is taken from the whl/cu124 index instead. + assert!(lock_file + .get_pypi_package_url("default", Platform::Linux64, "torch") + .unwrap() + .as_url() + .unwrap() + .path() + .contains("/whl/cu124")); +} From 3979094d3aaefca18dbf6c71bd8ae8212235699f Mon Sep 17 00:00:00 2001 From: Tim de Jager Date: Thu, 21 Nov 2024 14:57:44 +0100 Subject: [PATCH 09/10] fix: incorrect doc comment --- tests/integration_rust/pypi_tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integration_rust/pypi_tests.rs b/tests/integration_rust/pypi_tests.rs index b9064c3d7..e4f923c6a 100644 --- a/tests/integration_rust/pypi_tests.rs +++ b/tests/integration_rust/pypi_tests.rs @@ -207,7 +207,7 @@ async fn test_pinning_index() { #[cfg_attr(not(feature = "slow_integration_tests"), ignore)] /// This test checks if we can receive torch correctly from the whl/cu124 index. async fn pin_torch() { - /// Do some platform magic, as the index does not contain wheels for each platform. + // Do some platform magic, as the index does not contain wheels for each platform. let platform = Platform::current(); let platforms = match platform { Platform::Linux64 => "\"linux-64\"".to_string(), From bcb1c1cbc142122e7c937213fe045d90f8f194f8 Mon Sep 17 00:00:00 2001 From: Tim de Jager Date: Thu, 21 Nov 2024 16:03:50 +0100 Subject: [PATCH 10/10] doc: updated docs a bit --- docs/reference/project_configuration.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/reference/project_configuration.md b/docs/reference/project_configuration.md index ba4e0db42..4c6aa17a3 100644 --- a/docs/reference/project_configuration.md +++ b/docs/reference/project_configuration.md @@ -474,14 +474,14 @@ pytest = {version = "*", extras = ["dev"]} The index parameter allows you to specify the URL of a custom package index for the installation of a specific package. This feature is useful when you want to ensure that a package is retrieved from a particular source, rather than from the default index. -For example, you can use either the official Python Package Index (PyPI) at https://pypi.org/simple or an alternative private index like https://example.com/simple. - -Use `index` in combination with `version`: +For example, to use some other than the official Python Package Index (PyPI) at https://pypi.org/simple, you can use the `index` parameter: ```toml torch = { version = "*", index = "https://download.pytorch.org/whl/cu118" } ``` +This is useful for PyTorch specifically, as the registries are pinned to different CUDA versions. + ##### `git` A git repository to install from.