uv_settings/settings.rs
1use std::{fmt::Debug, num::NonZeroUsize, path::Path, path::PathBuf};
2
3use serde::{Deserialize, Serialize};
4
5use uv_cache_info::CacheKey;
6use uv_configuration::{
7 BuildIsolation, IndexStrategy, KeyringProviderType, PackageNameSpecifier, ProxyUrl, Reinstall,
8 RequiredVersion, TargetTriple, TrustedHost, TrustedPublishing, Upgrade,
9};
10use uv_distribution_types::{
11 ConfigSettings, ExtraBuildVariables, Index, IndexUrl, IndexUrlError, Origin,
12 PackageConfigSettings, PipExtraIndex, PipFindLinks, PipIndex, StaticMetadata,
13};
14use uv_install_wheel::LinkMode;
15use uv_macros::{CombineOptions, OptionsMetadata};
16use uv_normalize::{ExtraName, PackageName, PipGroupName};
17use uv_pep508::Requirement;
18use uv_pypi_types::{SupportedEnvironments, VerbatimParsedUrl};
19use uv_python::{PythonDownloads, PythonPreference, PythonVersion};
20use uv_redacted::DisplaySafeUrl;
21use uv_resolver::{
22 AnnotationStyle, ExcludeNewer, ExcludeNewerPackage, ExcludeNewerValue, ForkStrategy,
23 PrereleaseMode, ResolutionMode,
24};
25use uv_torch::TorchMode;
26use uv_workspace::pyproject::ExtraBuildDependencies;
27use uv_workspace::pyproject_mut::AddBoundsKind;
28
29/// A `pyproject.toml` with an (optional) `[tool.uv]` section.
30#[allow(dead_code)]
31#[derive(Debug, Clone, Default, Deserialize)]
32pub(crate) struct PyProjectToml {
33 pub(crate) tool: Option<Tools>,
34}
35
36/// A `[tool]` section.
37#[allow(dead_code)]
38#[derive(Debug, Clone, Default, Deserialize)]
39pub(crate) struct Tools {
40 pub(crate) uv: Option<Options>,
41}
42
43/// A `[tool.uv]` section.
44#[allow(dead_code)]
45#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
46#[serde(from = "OptionsWire", rename_all = "kebab-case")]
47#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
48#[cfg_attr(feature = "schemars", schemars(!from))]
49pub struct Options {
50 #[serde(flatten)]
51 pub globals: GlobalOptions,
52
53 #[serde(flatten)]
54 pub top_level: ResolverInstallerSchema,
55
56 #[serde(flatten)]
57 pub install_mirrors: PythonInstallMirrors,
58
59 #[serde(flatten)]
60 pub publish: PublishOptions,
61
62 #[serde(flatten)]
63 pub add: AddOptions,
64
65 #[option_group]
66 pub pip: Option<PipOptions>,
67
68 /// The keys to consider when caching builds for the project.
69 ///
70 /// Cache keys enable you to specify the files or directories that should trigger a rebuild when
71 /// modified. By default, uv will rebuild a project whenever the `pyproject.toml`, `setup.py`,
72 /// or `setup.cfg` files in the project directory are modified, or if a `src` directory is
73 /// added or removed, i.e.:
74 ///
75 /// ```toml
76 /// cache-keys = [{ file = "pyproject.toml" }, { file = "setup.py" }, { file = "setup.cfg" }, { dir = "src" }]
77 /// ```
78 ///
79 /// As an example: if a project uses dynamic metadata to read its dependencies from a
80 /// `requirements.txt` file, you can specify `cache-keys = [{ file = "requirements.txt" }, { file = "pyproject.toml" }]`
81 /// to ensure that the project is rebuilt whenever the `requirements.txt` file is modified (in
82 /// addition to watching the `pyproject.toml`).
83 ///
84 /// Globs are supported, following the syntax of the [`glob`](https://docs.rs/glob/0.3.1/glob/struct.Pattern.html)
85 /// crate. For example, to invalidate the cache whenever a `.toml` file in the project directory
86 /// or any of its subdirectories is modified, you can specify `cache-keys = [{ file = "**/*.toml" }]`.
87 /// Note that the use of globs can be expensive, as uv may need to walk the filesystem to
88 /// determine whether any files have changed.
89 ///
90 /// Cache keys can also include version control information. For example, if a project uses
91 /// `setuptools_scm` to read its version from a Git commit, you can specify `cache-keys = [{ git = { commit = true }, { file = "pyproject.toml" }]`
92 /// to include the current Git commit hash in the cache key (in addition to the
93 /// `pyproject.toml`). Git tags are also supported via `cache-keys = [{ git = { commit = true, tags = true } }]`.
94 ///
95 /// Cache keys can also include environment variables. For example, if a project relies on
96 /// `MACOSX_DEPLOYMENT_TARGET` or other environment variables to determine its behavior, you can
97 /// specify `cache-keys = [{ env = "MACOSX_DEPLOYMENT_TARGET" }]` to invalidate the cache
98 /// whenever the environment variable changes.
99 ///
100 /// Cache keys only affect the project defined by the `pyproject.toml` in which they're
101 /// specified (as opposed to, e.g., affecting all members in a workspace), and all paths and
102 /// globs are interpreted as relative to the project directory.
103 #[option(
104 default = r#"[{ file = "pyproject.toml" }, { file = "setup.py" }, { file = "setup.cfg" }]"#,
105 value_type = "list[dict]",
106 example = r#"
107 cache-keys = [{ file = "pyproject.toml" }, { file = "requirements.txt" }, { git = { commit = true } }]
108 "#
109 )]
110 pub cache_keys: Option<Vec<CacheKey>>,
111
112 // NOTE(charlie): These fields are shared with `ToolUv` in
113 // `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
114 // They're respected in both `pyproject.toml` and `uv.toml` files.
115 #[cfg_attr(feature = "schemars", schemars(skip))]
116 pub override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
117
118 #[cfg_attr(feature = "schemars", schemars(skip))]
119 pub exclude_dependencies: Option<Vec<uv_normalize::PackageName>>,
120
121 #[cfg_attr(feature = "schemars", schemars(skip))]
122 pub constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
123
124 #[cfg_attr(feature = "schemars", schemars(skip))]
125 pub build_constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
126
127 #[cfg_attr(feature = "schemars", schemars(skip))]
128 pub environments: Option<SupportedEnvironments>,
129
130 #[cfg_attr(feature = "schemars", schemars(skip))]
131 pub required_environments: Option<SupportedEnvironments>,
132
133 // NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
134 // `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
135 // They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
136 #[cfg_attr(feature = "schemars", schemars(skip))]
137 pub conflicts: Option<serde::de::IgnoredAny>,
138
139 #[cfg_attr(feature = "schemars", schemars(skip))]
140 pub workspace: Option<serde::de::IgnoredAny>,
141
142 #[cfg_attr(feature = "schemars", schemars(skip))]
143 pub sources: Option<serde::de::IgnoredAny>,
144
145 #[cfg_attr(feature = "schemars", schemars(skip))]
146 pub dev_dependencies: Option<serde::de::IgnoredAny>,
147
148 #[cfg_attr(feature = "schemars", schemars(skip))]
149 pub default_groups: Option<serde::de::IgnoredAny>,
150
151 #[cfg_attr(feature = "schemars", schemars(skip))]
152 pub dependency_groups: Option<serde::de::IgnoredAny>,
153
154 #[cfg_attr(feature = "schemars", schemars(skip))]
155 pub managed: Option<serde::de::IgnoredAny>,
156
157 #[cfg_attr(feature = "schemars", schemars(skip))]
158 pub r#package: Option<serde::de::IgnoredAny>,
159
160 #[cfg_attr(feature = "schemars", schemars(skip))]
161 pub build_backend: Option<serde::de::IgnoredAny>,
162}
163
164impl Options {
165 /// Construct an [`Options`] with the given global and top-level settings.
166 pub fn simple(globals: GlobalOptions, top_level: ResolverInstallerSchema) -> Self {
167 Self {
168 globals,
169 top_level,
170 ..Default::default()
171 }
172 }
173
174 /// Set the [`Origin`] on all indexes without an existing origin.
175 #[must_use]
176 pub fn with_origin(mut self, origin: Origin) -> Self {
177 if let Some(indexes) = &mut self.top_level.index {
178 for index in indexes {
179 index.origin.get_or_insert(origin);
180 }
181 }
182 if let Some(index_url) = &mut self.top_level.index_url {
183 index_url.try_set_origin(origin);
184 }
185 if let Some(extra_index_urls) = &mut self.top_level.extra_index_url {
186 for index_url in extra_index_urls {
187 index_url.try_set_origin(origin);
188 }
189 }
190 if let Some(pip) = &mut self.pip {
191 if let Some(indexes) = &mut pip.index {
192 for index in indexes {
193 index.origin.get_or_insert(origin);
194 }
195 }
196 if let Some(index_url) = &mut pip.index_url {
197 index_url.try_set_origin(origin);
198 }
199 if let Some(extra_index_urls) = &mut pip.extra_index_url {
200 for index_url in extra_index_urls {
201 index_url.try_set_origin(origin);
202 }
203 }
204 }
205 self
206 }
207
208 /// Resolve the [`Options`] relative to the given root directory.
209 pub fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
210 Ok(Self {
211 top_level: self.top_level.relative_to(root_dir)?,
212 pip: self.pip.map(|pip| pip.relative_to(root_dir)).transpose()?,
213 ..self
214 })
215 }
216}
217
218/// Global settings, relevant to all invocations.
219#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
220#[serde(rename_all = "kebab-case")]
221#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
222pub struct GlobalOptions {
223 /// Enforce a requirement on the version of uv.
224 ///
225 /// If the version of uv does not meet the requirement at runtime, uv will exit
226 /// with an error.
227 ///
228 /// Accepts a [PEP 440](https://peps.python.org/pep-0440/) specifier, like `==0.5.0` or `>=0.5.0`.
229 #[option(
230 default = "null",
231 value_type = "str",
232 example = r#"
233 required-version = ">=0.5.0"
234 "#
235 )]
236 pub required_version: Option<RequiredVersion>,
237 /// Whether to load TLS certificates from the platform's native certificate store.
238 ///
239 /// By default, uv uses bundled Mozilla root certificates. When enabled, this loads
240 /// certificates from the platform's native certificate store instead.
241 #[option(
242 default = "false",
243 value_type = "bool",
244 uv_toml_only = true,
245 example = r#"
246 system-certs = true
247 "#
248 )]
249 pub system_certs: Option<bool>,
250 /// Whether to load TLS certificates from the platform's native certificate store.
251 ///
252 /// By default, uv uses bundled Mozilla root certificates. When enabled, this loads
253 /// certificates from the platform's native certificate store instead.
254 ///
255 /// (Deprecated: use `system-certs` instead.)
256 #[deprecated(note = "use `system-certs` instead")]
257 #[option(
258 default = "false",
259 value_type = "bool",
260 uv_toml_only = true,
261 example = r#"
262 native-tls = true
263 "#
264 )]
265 pub native_tls: Option<bool>,
266 /// Disable network access, relying only on locally cached data and locally available files.
267 #[option(
268 default = "false",
269 value_type = "bool",
270 example = r#"
271 offline = true
272 "#
273 )]
274 pub offline: Option<bool>,
275 /// Avoid reading from or writing to the cache, instead using a temporary directory for the
276 /// duration of the operation.
277 #[option(
278 default = "false",
279 value_type = "bool",
280 example = r#"
281 no-cache = true
282 "#
283 )]
284 pub no_cache: Option<bool>,
285 /// Path to the cache directory.
286 ///
287 /// Defaults to `$XDG_CACHE_HOME/uv` or `$HOME/.cache/uv` on Linux and macOS, and
288 /// `%LOCALAPPDATA%\uv\cache` on Windows.
289 #[option(
290 default = "None",
291 value_type = "str",
292 uv_toml_only = true,
293 example = r#"
294 cache-dir = "./.uv_cache"
295 "#
296 )]
297 pub cache_dir: Option<PathBuf>,
298 /// Whether to enable experimental, preview features.
299 #[option(
300 default = "false",
301 value_type = "bool",
302 example = r#"
303 preview = true
304 "#
305 )]
306 pub preview: Option<bool>,
307 /// Whether to prefer using Python installations that are already present on the system, or
308 /// those that are downloaded and installed by uv.
309 #[option(
310 default = "\"managed\"",
311 value_type = "str",
312 example = r#"
313 python-preference = "managed"
314 "#,
315 possible_values = true
316 )]
317 pub python_preference: Option<PythonPreference>,
318 /// Whether to allow Python downloads.
319 #[option(
320 default = "\"automatic\"",
321 value_type = "str",
322 example = r#"
323 python-downloads = "manual"
324 "#,
325 possible_values = true
326 )]
327 pub python_downloads: Option<PythonDownloads>,
328 /// The maximum number of in-flight concurrent downloads that uv will perform at any given
329 /// time.
330 #[option(
331 default = "50",
332 value_type = "int",
333 example = r#"
334 concurrent-downloads = 4
335 "#
336 )]
337 pub concurrent_downloads: Option<NonZeroUsize>,
338 /// The maximum number of source distributions that uv will build concurrently at any given
339 /// time.
340 ///
341 /// Defaults to the number of available CPU cores.
342 #[option(
343 default = "None",
344 value_type = "int",
345 example = r#"
346 concurrent-builds = 4
347 "#
348 )]
349 pub concurrent_builds: Option<NonZeroUsize>,
350 /// The number of threads used when installing and unzipping packages.
351 ///
352 /// Defaults to the number of available CPU cores.
353 #[option(
354 default = "None",
355 value_type = "int",
356 example = r#"
357 concurrent-installs = 4
358 "#
359 )]
360 pub concurrent_installs: Option<NonZeroUsize>,
361 /// The URL of the HTTP proxy to use.
362 #[option(
363 default = "None",
364 value_type = "str",
365 uv_toml_only = true,
366 example = r#"
367 http-proxy = "http://proxy.example.com"
368 "#
369 )]
370 pub http_proxy: Option<ProxyUrl>,
371 /// The URL of the HTTPS proxy to use.
372 #[option(
373 default = "None",
374 value_type = "str",
375 uv_toml_only = true,
376 example = r#"
377 https-proxy = "https://proxy.example.com"
378 "#
379 )]
380 pub https_proxy: Option<ProxyUrl>,
381 /// A list of hosts to exclude from proxying.
382 #[option(
383 default = "None",
384 value_type = "list[str]",
385 uv_toml_only = true,
386 example = r#"
387 no-proxy = ["localhost", "127.0.0.1"]
388 "#
389 )]
390 pub no_proxy: Option<Vec<String>>,
391 /// Allow insecure connections to host.
392 ///
393 /// Expects to receive either a hostname (e.g., `localhost`), a host-port pair (e.g.,
394 /// `localhost:8080`), or a URL (e.g., `https://localhost`).
395 ///
396 /// WARNING: Hosts included in this list will not be verified against the system's certificate
397 /// store. Only use `--allow-insecure-host` in a secure network with verified sources, as it
398 /// bypasses SSL verification and could expose you to MITM attacks.
399 #[option(
400 default = "[]",
401 value_type = "list[str]",
402 example = r#"
403 allow-insecure-host = ["localhost:8080"]
404 "#
405 )]
406 pub allow_insecure_host: Option<Vec<TrustedHost>>,
407}
408
409/// Settings relevant to all installer operations.
410#[derive(Debug, Clone, Default, CombineOptions)]
411pub struct InstallerOptions {
412 pub index: Option<Vec<Index>>,
413 pub index_url: Option<PipIndex>,
414 pub extra_index_url: Option<Vec<PipExtraIndex>>,
415 pub no_index: Option<bool>,
416 pub find_links: Option<Vec<PipFindLinks>>,
417 pub index_strategy: Option<IndexStrategy>,
418 pub keyring_provider: Option<KeyringProviderType>,
419 pub config_settings: Option<ConfigSettings>,
420 pub exclude_newer: Option<ExcludeNewerValue>,
421 pub link_mode: Option<LinkMode>,
422 pub compile_bytecode: Option<bool>,
423 pub reinstall: Option<Reinstall>,
424 pub build_isolation: Option<BuildIsolation>,
425 pub no_build: Option<bool>,
426 pub no_build_package: Option<Vec<PackageName>>,
427 pub no_binary: Option<bool>,
428 pub no_binary_package: Option<Vec<PackageName>>,
429 pub no_sources: Option<bool>,
430 pub no_sources_package: Option<Vec<PackageName>>,
431}
432
433/// Settings relevant to all resolver operations.
434#[derive(Debug, Clone, Default, CombineOptions)]
435pub struct ResolverOptions {
436 pub index: Option<Vec<Index>>,
437 pub index_url: Option<PipIndex>,
438 pub extra_index_url: Option<Vec<PipExtraIndex>>,
439 pub no_index: Option<bool>,
440 pub find_links: Option<Vec<PipFindLinks>>,
441 pub index_strategy: Option<IndexStrategy>,
442 pub keyring_provider: Option<KeyringProviderType>,
443 pub resolution: Option<ResolutionMode>,
444 pub prerelease: Option<PrereleaseMode>,
445 pub fork_strategy: Option<ForkStrategy>,
446 pub dependency_metadata: Option<Vec<StaticMetadata>>,
447 pub config_settings: Option<ConfigSettings>,
448 pub config_settings_package: Option<PackageConfigSettings>,
449 pub exclude_newer: ExcludeNewer,
450 pub link_mode: Option<LinkMode>,
451 pub torch_backend: Option<TorchMode>,
452 pub upgrade: Option<Upgrade>,
453 pub build_isolation: Option<BuildIsolation>,
454 pub no_build: Option<bool>,
455 pub no_build_package: Option<Vec<PackageName>>,
456 pub no_binary: Option<bool>,
457 pub no_binary_package: Option<Vec<PackageName>>,
458 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
459 pub extra_build_variables: Option<ExtraBuildVariables>,
460 pub no_sources: Option<bool>,
461 pub no_sources_package: Option<Vec<PackageName>>,
462}
463
464/// Shared settings, relevant to all operations that must resolve and install dependencies. The
465/// union of [`InstallerOptions`] and [`ResolverOptions`].
466#[derive(Debug, Clone, Default, CombineOptions)]
467pub struct ResolverInstallerOptions {
468 pub index: Option<Vec<Index>>,
469 pub index_url: Option<PipIndex>,
470 pub extra_index_url: Option<Vec<PipExtraIndex>>,
471 pub no_index: Option<bool>,
472 pub find_links: Option<Vec<PipFindLinks>>,
473 pub index_strategy: Option<IndexStrategy>,
474 pub keyring_provider: Option<KeyringProviderType>,
475 pub resolution: Option<ResolutionMode>,
476 pub prerelease: Option<PrereleaseMode>,
477 pub fork_strategy: Option<ForkStrategy>,
478 pub dependency_metadata: Option<Vec<StaticMetadata>>,
479 pub config_settings: Option<ConfigSettings>,
480 pub config_settings_package: Option<PackageConfigSettings>,
481 pub build_isolation: Option<BuildIsolation>,
482 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
483 pub extra_build_variables: Option<ExtraBuildVariables>,
484 pub exclude_newer: Option<ExcludeNewerValue>,
485 pub exclude_newer_package: Option<ExcludeNewerPackage>,
486 pub link_mode: Option<LinkMode>,
487 pub torch_backend: Option<TorchMode>,
488 pub compile_bytecode: Option<bool>,
489 pub no_sources: Option<bool>,
490 pub no_sources_package: Option<Vec<PackageName>>,
491 pub upgrade: Option<Upgrade>,
492 pub reinstall: Option<Reinstall>,
493 pub no_build: Option<bool>,
494 pub no_build_package: Option<Vec<PackageName>>,
495 pub no_binary: Option<bool>,
496 pub no_binary_package: Option<Vec<PackageName>>,
497}
498
499impl From<ResolverInstallerSchema> for ResolverInstallerOptions {
500 fn from(value: ResolverInstallerSchema) -> Self {
501 let ResolverInstallerSchema {
502 index,
503 index_url,
504 extra_index_url,
505 no_index,
506 find_links,
507 index_strategy,
508 keyring_provider,
509 resolution,
510 prerelease,
511 fork_strategy,
512 dependency_metadata,
513 config_settings,
514 config_settings_package,
515 no_build_isolation,
516 no_build_isolation_package,
517 extra_build_dependencies,
518 extra_build_variables,
519 exclude_newer,
520 exclude_newer_package,
521 link_mode,
522 torch_backend,
523 compile_bytecode,
524 no_sources,
525 no_sources_package,
526 upgrade,
527 upgrade_package,
528 reinstall,
529 reinstall_package,
530 no_build,
531 no_build_package,
532 no_binary,
533 no_binary_package,
534 } = value;
535 Self {
536 index,
537 index_url,
538 extra_index_url,
539 no_index,
540 find_links,
541 index_strategy,
542 keyring_provider,
543 resolution,
544 prerelease,
545 fork_strategy,
546 dependency_metadata,
547 config_settings,
548 config_settings_package,
549 build_isolation: BuildIsolation::from_args(
550 no_build_isolation,
551 no_build_isolation_package.into_iter().flatten().collect(),
552 ),
553 extra_build_dependencies,
554 extra_build_variables,
555 exclude_newer,
556 exclude_newer_package,
557 link_mode,
558 torch_backend,
559 compile_bytecode,
560 no_sources,
561 no_sources_package,
562 upgrade: Upgrade::from_args(
563 upgrade,
564 upgrade_package
565 .into_iter()
566 .flatten()
567 .map(Into::into)
568 .collect(),
569 ),
570 reinstall: Reinstall::from_args(reinstall, reinstall_package.unwrap_or_default()),
571 no_build,
572 no_build_package,
573 no_binary,
574 no_binary_package,
575 }
576 }
577}
578
579impl ResolverInstallerSchema {
580 /// Resolve the [`ResolverInstallerSchema`] relative to the given root directory.
581 pub fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
582 Ok(Self {
583 index: self
584 .index
585 .map(|index| {
586 index
587 .into_iter()
588 .map(|index| index.relative_to(root_dir))
589 .collect::<Result<Vec<_>, _>>()
590 })
591 .transpose()?,
592 index_url: self
593 .index_url
594 .map(|index_url| index_url.relative_to(root_dir))
595 .transpose()?,
596 extra_index_url: self
597 .extra_index_url
598 .map(|extra_index_url| {
599 extra_index_url
600 .into_iter()
601 .map(|extra_index_url| extra_index_url.relative_to(root_dir))
602 .collect::<Result<Vec<_>, _>>()
603 })
604 .transpose()?,
605 find_links: self
606 .find_links
607 .map(|find_links| {
608 find_links
609 .into_iter()
610 .map(|find_link| find_link.relative_to(root_dir))
611 .collect::<Result<Vec<_>, _>>()
612 })
613 .transpose()?,
614 ..self
615 })
616 }
617}
618
619/// The JSON schema for the `[tool.uv]` section of a `pyproject.toml` file.
620#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
621#[serde(rename_all = "kebab-case")]
622#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
623pub struct ResolverInstallerSchema {
624 /// The package indexes to use when resolving dependencies.
625 ///
626 /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
627 /// (the simple repository API), or a local directory laid out in the same format.
628 ///
629 /// Indexes are considered in the order in which they're defined, such that the first-defined
630 /// index has the highest priority. Further, the indexes provided by this setting are given
631 /// higher priority than any indexes specified via [`index_url`](#index-url) or
632 /// [`extra_index_url`](#extra-index-url). uv will only consider the first index that contains
633 /// a given package, unless an alternative [index strategy](#index-strategy) is specified.
634 ///
635 /// If an index is marked as `explicit = true`, it will be used exclusively for those
636 /// dependencies that select it explicitly via `[tool.uv.sources]`, as in:
637 ///
638 /// ```toml
639 /// [[tool.uv.index]]
640 /// name = "pytorch"
641 /// url = "https://download.pytorch.org/whl/cu121"
642 /// explicit = true
643 ///
644 /// [tool.uv.sources]
645 /// torch = { index = "pytorch" }
646 /// ```
647 ///
648 /// If an index is marked as `default = true`, it will be moved to the end of the prioritized list, such that it is
649 /// given the lowest priority when resolving packages. Additionally, marking an index as default will disable the
650 /// PyPI default index.
651 #[option(
652 default = "\"[]\"",
653 value_type = "dict",
654 example = r#"
655 [[tool.uv.index]]
656 name = "pytorch"
657 url = "https://download.pytorch.org/whl/cu121"
658 "#
659 )]
660 pub index: Option<Vec<Index>>,
661 /// The URL of the Python package index (by default: <https://pypi.org/simple>).
662 ///
663 /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
664 /// (the simple repository API), or a local directory laid out in the same format.
665 ///
666 /// The index provided by this setting is given lower priority than any indexes specified via
667 /// [`extra_index_url`](#extra-index-url) or [`index`](#index).
668 ///
669 /// (Deprecated: use `index` instead.)
670 #[option(
671 default = "\"https://pypi.org/simple\"",
672 value_type = "str",
673 example = r#"
674 index-url = "https://test.pypi.org/simple"
675 "#
676 )]
677 pub index_url: Option<PipIndex>,
678 /// Extra URLs of package indexes to use, in addition to `--index-url`.
679 ///
680 /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
681 /// (the simple repository API), or a local directory laid out in the same format.
682 ///
683 /// All indexes provided via this flag take priority over the index specified by
684 /// [`index_url`](#index-url) or [`index`](#index) with `default = true`. When multiple indexes
685 /// are provided, earlier values take priority.
686 ///
687 /// To control uv's resolution strategy when multiple indexes are present, see
688 /// [`index_strategy`](#index-strategy).
689 ///
690 /// (Deprecated: use `index` instead.)
691 #[option(
692 default = "[]",
693 value_type = "list[str]",
694 example = r#"
695 extra-index-url = ["https://download.pytorch.org/whl/cpu"]
696 "#
697 )]
698 pub extra_index_url: Option<Vec<PipExtraIndex>>,
699 /// Ignore all registry indexes (e.g., PyPI), instead relying on direct URL dependencies and
700 /// those provided via `--find-links`.
701 #[option(
702 default = "false",
703 value_type = "bool",
704 example = r#"
705 no-index = true
706 "#
707 )]
708 pub no_index: Option<bool>,
709 /// Locations to search for candidate distributions, in addition to those found in the registry
710 /// indexes.
711 ///
712 /// If a path, the target must be a directory that contains packages as wheel files (`.whl`) or
713 /// source distributions (e.g., `.tar.gz` or `.zip`) at the top level.
714 ///
715 /// If a URL, the page must contain a flat list of links to package files adhering to the
716 /// formats described above.
717 #[option(
718 default = "[]",
719 value_type = "list[str]",
720 example = r#"
721 find-links = ["https://download.pytorch.org/whl/torch_stable.html"]
722 "#
723 )]
724 pub find_links: Option<Vec<PipFindLinks>>,
725 /// The strategy to use when resolving against multiple index URLs.
726 ///
727 /// By default, uv will stop at the first index on which a given package is available, and
728 /// limit resolutions to those present on that first index (`first-index`). This prevents
729 /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the
730 /// same name to an alternate index.
731 #[option(
732 default = "\"first-index\"",
733 value_type = "str",
734 example = r#"
735 index-strategy = "unsafe-best-match"
736 "#,
737 possible_values = true
738 )]
739 pub index_strategy: Option<IndexStrategy>,
740 /// Attempt to use `keyring` for authentication for index URLs.
741 ///
742 /// At present, only `--keyring-provider subprocess` is supported, which configures uv to
743 /// use the `keyring` CLI to handle authentication.
744 #[option(
745 default = "\"disabled\"",
746 value_type = "str",
747 example = r#"
748 keyring-provider = "subprocess"
749 "#
750 )]
751 pub keyring_provider: Option<KeyringProviderType>,
752 /// The strategy to use when selecting between the different compatible versions for a given
753 /// package requirement.
754 ///
755 /// By default, uv will use the latest compatible version of each package (`highest`).
756 #[option(
757 default = "\"highest\"",
758 value_type = "str",
759 example = r#"
760 resolution = "lowest-direct"
761 "#,
762 possible_values = true
763 )]
764 pub resolution: Option<ResolutionMode>,
765 /// The strategy to use when considering pre-release versions.
766 ///
767 /// By default, uv will accept pre-releases for packages that _only_ publish pre-releases,
768 /// along with first-party requirements that contain an explicit pre-release marker in the
769 /// declared specifiers (`if-necessary-or-explicit`).
770 #[option(
771 default = "\"if-necessary-or-explicit\"",
772 value_type = "str",
773 example = r#"
774 prerelease = "allow"
775 "#,
776 possible_values = true
777 )]
778 pub prerelease: Option<PrereleaseMode>,
779 /// The strategy to use when selecting multiple versions of a given package across Python
780 /// versions and platforms.
781 ///
782 /// By default, uv will optimize for selecting the latest version of each package for each
783 /// supported Python version (`requires-python`), while minimizing the number of selected
784 /// versions across platforms.
785 ///
786 /// Under `fewest`, uv will minimize the number of selected versions for each package,
787 /// preferring older versions that are compatible with a wider range of supported Python
788 /// versions or platforms.
789 #[option(
790 default = "\"requires-python\"",
791 value_type = "str",
792 example = r#"
793 fork-strategy = "fewest"
794 "#,
795 possible_values = true
796 )]
797 pub fork_strategy: Option<ForkStrategy>,
798 /// Pre-defined static metadata for dependencies of the project (direct or transitive). When
799 /// provided, enables the resolver to use the specified metadata instead of querying the
800 /// registry or building the relevant package from source.
801 ///
802 /// Metadata should be provided in adherence with the [Metadata 2.3](https://packaging.python.org/en/latest/specifications/core-metadata/)
803 /// standard, though only the following fields are respected:
804 ///
805 /// - `name`: The name of the package.
806 /// - (Optional) `version`: The version of the package. If omitted, the metadata will be applied
807 /// to all versions of the package.
808 /// - (Optional) `requires-dist`: The dependencies of the package (e.g., `werkzeug>=0.14`).
809 /// - (Optional) `requires-python`: The Python version required by the package (e.g., `>=3.10`).
810 /// - (Optional) `provides-extra`: The extras provided by the package.
811 #[option(
812 default = r#"[]"#,
813 value_type = "list[dict]",
814 example = r#"
815 dependency-metadata = [
816 { name = "flask", version = "1.0.0", requires-dist = ["werkzeug"], requires-python = ">=3.6" },
817 ]
818 "#
819 )]
820 pub dependency_metadata: Option<Vec<StaticMetadata>>,
821 /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend,
822 /// specified as `KEY=VALUE` pairs.
823 #[option(
824 default = "{}",
825 value_type = "dict",
826 example = r#"
827 config-settings = { editable_mode = "compat" }
828 "#
829 )]
830 pub config_settings: Option<ConfigSettings>,
831 /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend for specific packages,
832 /// specified as `KEY=VALUE` pairs.
833 ///
834 /// Accepts a map from package names to string key-value pairs.
835 #[option(
836 default = "{}",
837 value_type = "dict",
838 example = r#"
839 config-settings-package = { numpy = { editable_mode = "compat" } }
840 "#
841 )]
842 pub config_settings_package: Option<PackageConfigSettings>,
843 /// Disable isolation when building source distributions.
844 ///
845 /// Assumes that build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
846 /// are already installed.
847 #[option(
848 default = "false",
849 value_type = "bool",
850 example = r#"
851 no-build-isolation = true
852 "#
853 )]
854 pub no_build_isolation: Option<bool>,
855 /// Disable isolation when building source distributions for a specific package.
856 ///
857 /// Assumes that the packages' build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
858 /// are already installed.
859 #[option(
860 default = "[]",
861 value_type = "list[str]",
862 example = r#"
863 no-build-isolation-package = ["package1", "package2"]
864 "#
865 )]
866 pub no_build_isolation_package: Option<Vec<PackageName>>,
867 /// Additional build dependencies for packages.
868 ///
869 /// This allows extending the PEP 517 build environment for the project's dependencies with
870 /// additional packages. This is useful for packages that assume the presence of packages like
871 /// `pip`, and do not declare them as build dependencies.
872 #[option(
873 default = "[]",
874 value_type = "dict",
875 example = r#"
876 extra-build-dependencies = { pytest = ["setuptools"] }
877 "#
878 )]
879 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
880 /// Extra environment variables to set when building certain packages.
881 ///
882 /// Environment variables will be added to the environment when building the
883 /// specified packages.
884 #[option(
885 default = r#"{}"#,
886 value_type = r#"dict[str, dict[str, str]]"#,
887 example = r#"
888 extra-build-variables = { flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" } }
889 "#
890 )]
891 pub extra_build_variables: Option<ExtraBuildVariables>,
892 /// Limit candidate packages to those that were uploaded prior to the given date.
893 ///
894 /// Accepts RFC 3339 timestamps (e.g., `2006-12-02T02:07:43Z`), a "friendly" duration (e.g.,
895 /// `24 hours`, `1 week`, `30 days`), or an ISO 8601 duration (e.g., `PT24H`, `P7D`, `P30D`).
896 ///
897 /// Durations do not respect semantics of the local time zone and are always resolved to a fixed
898 /// number of seconds assuming that a day is 24 hours (e.g., DST transitions are ignored).
899 /// Calendar units such as months and years are not allowed.
900 #[option(
901 default = "None",
902 value_type = "str",
903 example = r#"
904 exclude-newer = "2006-12-02T02:07:43Z"
905 "#
906 )]
907 pub exclude_newer: Option<ExcludeNewerValue>,
908 /// Limit candidate packages for specific packages to those that were uploaded prior to the
909 /// given date.
910 ///
911 /// Accepts a dictionary format of `PACKAGE = "DATE"` pairs, where `DATE` is an RFC 3339
912 /// timestamp (e.g., `2006-12-02T02:07:43Z`), a "friendly" duration (e.g., `24 hours`, `1 week`,
913 /// `30 days`), or a ISO 8601 duration (e.g., `PT24H`, `P7D`, `P30D`).
914 ///
915 /// Durations do not respect semantics of the local time zone and are always resolved to a fixed
916 /// number of seconds assuming that a day is 24 hours (e.g., DST transitions are ignored).
917 /// Calendar units such as months and years are not allowed.
918 #[option(
919 default = "None",
920 value_type = "dict",
921 example = r#"
922 exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z" }
923 "#
924 )]
925 pub exclude_newer_package: Option<ExcludeNewerPackage>,
926 /// The method to use when installing packages from the global cache.
927 ///
928 /// Defaults to `clone` (also known as Copy-on-Write) on macOS and Linux, and `hardlink` on
929 /// Windows.
930 ///
931 /// WARNING: The use of symlink link mode is discouraged, as they create tight coupling between
932 /// the cache and the target environment. For example, clearing the cache (`uv cache clean`)
933 /// will break all installed packages by way of removing the underlying source files. Use
934 /// symlinks with caution.
935 #[option(
936 default = "\"clone\" (macOS, Linux) or \"hardlink\" (Windows)",
937 value_type = "str",
938 example = r#"
939 link-mode = "copy"
940 "#,
941 possible_values = true
942 )]
943 pub link_mode: Option<LinkMode>,
944 /// Compile Python files to bytecode after installation.
945 ///
946 /// By default, uv does not compile Python (`.py`) files to bytecode (`__pycache__/*.pyc`);
947 /// instead, compilation is performed lazily the first time a module is imported. For use-cases
948 /// in which start time is critical, such as CLI applications and Docker containers, this option
949 /// can be enabled to trade longer installation times for faster start times.
950 ///
951 /// When enabled, uv will process the entire site-packages directory (including packages that
952 /// are not being modified by the current operation) for consistency. Like pip, it will also
953 /// ignore errors.
954 #[option(
955 default = "false",
956 value_type = "bool",
957 example = r#"
958 compile-bytecode = true
959 "#
960 )]
961 pub compile_bytecode: Option<bool>,
962 /// Ignore the `tool.uv.sources` table when resolving dependencies. Used to lock against the
963 /// standards-compliant, publishable package metadata, as opposed to using any local or Git
964 /// sources.
965 #[option(
966 default = "false",
967 value_type = "bool",
968 example = r#"
969 no-sources = true
970 "#
971 )]
972 pub no_sources: Option<bool>,
973 /// Ignore `tool.uv.sources` for the specified packages.
974 #[option(
975 default = "[]",
976 value_type = "list[str]",
977 example = r#"
978 no-sources-package = ["ruff"]
979 "#
980 )]
981 pub no_sources_package: Option<Vec<PackageName>>,
982 /// Allow package upgrades, ignoring pinned versions in any existing output file.
983 #[option(
984 default = "false",
985 value_type = "bool",
986 example = r#"
987 upgrade = true
988 "#
989 )]
990 pub upgrade: Option<bool>,
991 /// Allow upgrades for a specific package, ignoring pinned versions in any existing output
992 /// file.
993 ///
994 /// Accepts both standalone package names (`ruff`) and version specifiers (`ruff<0.5.0`).
995 #[option(
996 default = "[]",
997 value_type = "list[str]",
998 example = r#"
999 upgrade-package = ["ruff"]
1000 "#
1001 )]
1002 pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
1003 /// Reinstall all packages, regardless of whether they're already installed. Implies `refresh`.
1004 #[option(
1005 default = "false",
1006 value_type = "bool",
1007 example = r#"
1008 reinstall = true
1009 "#
1010 )]
1011 pub reinstall: Option<bool>,
1012 /// Reinstall a specific package, regardless of whether it's already installed. Implies
1013 /// `refresh-package`.
1014 #[option(
1015 default = "[]",
1016 value_type = "list[str]",
1017 example = r#"
1018 reinstall-package = ["ruff"]
1019 "#
1020 )]
1021 pub reinstall_package: Option<Vec<PackageName>>,
1022 /// Don't build source distributions.
1023 ///
1024 /// When enabled, resolving will not run arbitrary Python code. The cached wheels of
1025 /// already-built source distributions will be reused, but operations that require building
1026 /// distributions will exit with an error.
1027 #[option(
1028 default = "false",
1029 value_type = "bool",
1030 example = r#"
1031 no-build = true
1032 "#
1033 )]
1034 pub no_build: Option<bool>,
1035 /// Don't build source distributions for a specific package.
1036 #[option(
1037 default = "[]",
1038 value_type = "list[str]",
1039 example = r#"
1040 no-build-package = ["ruff"]
1041 "#
1042 )]
1043 pub no_build_package: Option<Vec<PackageName>>,
1044 /// Don't install pre-built wheels.
1045 ///
1046 /// The given packages will be built and installed from source. The resolver will still use
1047 /// pre-built wheels to extract package metadata, if available.
1048 #[option(
1049 default = "false",
1050 value_type = "bool",
1051 example = r#"
1052 no-binary = true
1053 "#
1054 )]
1055 pub no_binary: Option<bool>,
1056 /// Don't install pre-built wheels for a specific package.
1057 #[option(
1058 default = "[]",
1059 value_type = "list[str]",
1060 example = r#"
1061 no-binary-package = ["ruff"]
1062 "#
1063 )]
1064 pub no_binary_package: Option<Vec<PackageName>>,
1065 /// The backend to use when fetching packages in the PyTorch ecosystem.
1066 ///
1067 /// When set, uv will ignore the configured index URLs for packages in the PyTorch ecosystem,
1068 /// and will instead use the defined backend.
1069 ///
1070 /// For example, when set to `cpu`, uv will use the CPU-only PyTorch index; when set to `cu126`,
1071 /// uv will use the PyTorch index for CUDA 12.6.
1072 ///
1073 /// The `auto` mode will attempt to detect the appropriate PyTorch index based on the currently
1074 /// installed CUDA drivers.
1075 ///
1076 /// This setting is only respected by `uv pip` commands.
1077 ///
1078 /// This option is in preview and may change in any future release.
1079 #[option(
1080 default = "null",
1081 value_type = "str",
1082 example = r#"
1083 torch-backend = "auto"
1084 "#
1085 )]
1086 pub torch_backend: Option<TorchMode>,
1087}
1088
1089/// Shared settings, relevant to all operations that might create managed python installations.
1090#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
1091#[serde(rename_all = "kebab-case")]
1092#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1093pub struct PythonInstallMirrors {
1094 /// Mirror URL for downloading managed Python installations.
1095 ///
1096 /// By default, managed Python installations are downloaded from [`python-build-standalone`](https://github.com/astral-sh/python-build-standalone).
1097 /// This variable can be set to a mirror URL to use a different source for Python installations.
1098 /// The provided URL will replace `https://github.com/astral-sh/python-build-standalone/releases/download` in, e.g., `https://github.com/astral-sh/python-build-standalone/releases/download/20240713/cpython-3.12.4%2B20240713-aarch64-apple-darwin-install_only.tar.gz`.
1099 ///
1100 /// Distributions can be read from a local directory by using the `file://` URL scheme.
1101 #[option(
1102 default = "None",
1103 value_type = "str",
1104 uv_toml_only = true,
1105 example = r#"
1106 python-install-mirror = "https://github.com/astral-sh/python-build-standalone/releases/download"
1107 "#
1108 )]
1109 pub python_install_mirror: Option<String>,
1110 /// Mirror URL to use for downloading managed PyPy installations.
1111 ///
1112 /// By default, managed PyPy installations are downloaded from [downloads.python.org](https://downloads.python.org/).
1113 /// This variable can be set to a mirror URL to use a different source for PyPy installations.
1114 /// The provided URL will replace `https://downloads.python.org/pypy` in, e.g., `https://downloads.python.org/pypy/pypy3.8-v7.3.7-osx64.tar.bz2`.
1115 ///
1116 /// Distributions can be read from a
1117 /// local directory by using the `file://` URL scheme.
1118 #[option(
1119 default = "None",
1120 value_type = "str",
1121 uv_toml_only = true,
1122 example = r#"
1123 pypy-install-mirror = "https://downloads.python.org/pypy"
1124 "#
1125 )]
1126 pub pypy_install_mirror: Option<String>,
1127
1128 /// URL pointing to JSON of custom Python installations.
1129 #[option(
1130 default = "None",
1131 value_type = "str",
1132 uv_toml_only = true,
1133 example = r#"
1134 python-downloads-json-url = "/etc/uv/python-downloads.json"
1135 "#
1136 )]
1137 pub python_downloads_json_url: Option<String>,
1138}
1139
1140impl PythonInstallMirrors {
1141 #[must_use]
1142 pub fn combine(self, other: Self) -> Self {
1143 Self {
1144 python_install_mirror: self.python_install_mirror.or(other.python_install_mirror),
1145 pypy_install_mirror: self.pypy_install_mirror.or(other.pypy_install_mirror),
1146 python_downloads_json_url: self
1147 .python_downloads_json_url
1148 .or(other.python_downloads_json_url),
1149 }
1150 }
1151}
1152
1153/// Settings that are specific to the `uv pip` command-line interface.
1154///
1155/// These values will be ignored when running commands outside the `uv pip` namespace (e.g.,
1156/// `uv lock`, `uvx`).
1157#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
1158#[serde(deny_unknown_fields, rename_all = "kebab-case")]
1159#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1160pub struct PipOptions {
1161 /// The Python interpreter into which packages should be installed.
1162 ///
1163 /// By default, uv installs into the virtual environment in the current working directory or
1164 /// any parent directory. The `--python` option allows you to specify a different interpreter,
1165 /// which is intended for use in continuous integration (CI) environments or other automated
1166 /// workflows.
1167 ///
1168 /// Supported formats:
1169 /// - `3.10` looks for an installed Python 3.10 in the registry on Windows (see
1170 /// `py --list-paths`), or `python3.10` on Linux and macOS.
1171 /// - `python3.10` or `python.exe` looks for a binary with the given name in `PATH`.
1172 /// - `/home/ferris/.local/bin/python3.10` uses the exact Python at the given path.
1173 #[option(
1174 default = "None",
1175 value_type = "str",
1176 example = r#"
1177 python = "3.10"
1178 "#
1179 )]
1180 pub python: Option<String>,
1181 /// Install packages into the system Python environment.
1182 ///
1183 /// By default, uv installs into the virtual environment in the current working directory or
1184 /// any parent directory. The `--system` option instructs uv to instead use the first Python
1185 /// found in the system `PATH`.
1186 ///
1187 /// WARNING: `--system` is intended for use in continuous integration (CI) environments and
1188 /// should be used with caution, as it can modify the system Python installation.
1189 #[option(
1190 default = "false",
1191 value_type = "bool",
1192 example = r#"
1193 system = true
1194 "#
1195 )]
1196 pub system: Option<bool>,
1197 /// Allow uv to modify an `EXTERNALLY-MANAGED` Python installation.
1198 ///
1199 /// WARNING: `--break-system-packages` is intended for use in continuous integration (CI)
1200 /// environments, when installing into Python installations that are managed by an external
1201 /// package manager, like `apt`. It should be used with caution, as such Python installations
1202 /// explicitly recommend against modifications by other package managers (like uv or pip).
1203 #[option(
1204 default = "false",
1205 value_type = "bool",
1206 example = r#"
1207 break-system-packages = true
1208 "#
1209 )]
1210 pub break_system_packages: Option<bool>,
1211 /// Install packages into the specified directory, rather than into the virtual or system Python
1212 /// environment. The packages will be installed at the top-level of the directory.
1213 #[option(
1214 default = "None",
1215 value_type = "str",
1216 example = r#"
1217 target = "./target"
1218 "#
1219 )]
1220 pub target: Option<PathBuf>,
1221 /// Install packages into `lib`, `bin`, and other top-level folders under the specified
1222 /// directory, as if a virtual environment were present at that location.
1223 ///
1224 /// In general, prefer the use of `--python` to install into an alternate environment, as
1225 /// scripts and other artifacts installed via `--prefix` will reference the installing
1226 /// interpreter, rather than any interpreter added to the `--prefix` directory, rendering them
1227 /// non-portable.
1228 #[option(
1229 default = "None",
1230 value_type = "str",
1231 example = r#"
1232 prefix = "./prefix"
1233 "#
1234 )]
1235 pub prefix: Option<PathBuf>,
1236 #[serde(skip)]
1237 #[cfg_attr(feature = "schemars", schemars(skip))]
1238 pub index: Option<Vec<Index>>,
1239 /// The URL of the Python package index (by default: <https://pypi.org/simple>).
1240 ///
1241 /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
1242 /// (the simple repository API), or a local directory laid out in the same format.
1243 ///
1244 /// The index provided by this setting is given lower priority than any indexes specified via
1245 /// [`extra_index_url`](#extra-index-url).
1246 #[option(
1247 default = "\"https://pypi.org/simple\"",
1248 value_type = "str",
1249 example = r#"
1250 index-url = "https://test.pypi.org/simple"
1251 "#
1252 )]
1253 pub index_url: Option<PipIndex>,
1254 /// Extra URLs of package indexes to use, in addition to `--index-url`.
1255 ///
1256 /// Accepts either a repository compliant with [PEP 503](https://peps.python.org/pep-0503/)
1257 /// (the simple repository API), or a local directory laid out in the same format.
1258 ///
1259 /// All indexes provided via this flag take priority over the index specified by
1260 /// [`index_url`](#index-url). When multiple indexes are provided, earlier values take priority.
1261 ///
1262 /// To control uv's resolution strategy when multiple indexes are present, see
1263 /// [`index_strategy`](#index-strategy).
1264 #[option(
1265 default = "[]",
1266 value_type = "list[str]",
1267 example = r#"
1268 extra-index-url = ["https://download.pytorch.org/whl/cpu"]
1269 "#
1270 )]
1271 pub extra_index_url: Option<Vec<PipExtraIndex>>,
1272 /// Ignore all registry indexes (e.g., PyPI), instead relying on direct URL dependencies and
1273 /// those provided via `--find-links`.
1274 #[option(
1275 default = "false",
1276 value_type = "bool",
1277 example = r#"
1278 no-index = true
1279 "#
1280 )]
1281 pub no_index: Option<bool>,
1282 /// Locations to search for candidate distributions, in addition to those found in the registry
1283 /// indexes.
1284 ///
1285 /// If a path, the target must be a directory that contains packages as wheel files (`.whl`) or
1286 /// source distributions (e.g., `.tar.gz` or `.zip`) at the top level.
1287 ///
1288 /// If a URL, the page must contain a flat list of links to package files adhering to the
1289 /// formats described above.
1290 #[option(
1291 default = "[]",
1292 value_type = "list[str]",
1293 example = r#"
1294 find-links = ["https://download.pytorch.org/whl/torch_stable.html"]
1295 "#
1296 )]
1297 pub find_links: Option<Vec<PipFindLinks>>,
1298 /// The strategy to use when resolving against multiple index URLs.
1299 ///
1300 /// By default, uv will stop at the first index on which a given package is available, and
1301 /// limit resolutions to those present on that first index (`first-index`). This prevents
1302 /// "dependency confusion" attacks, whereby an attacker can upload a malicious package under the
1303 /// same name to an alternate index.
1304 #[option(
1305 default = "\"first-index\"",
1306 value_type = "str",
1307 example = r#"
1308 index-strategy = "unsafe-best-match"
1309 "#,
1310 possible_values = true
1311 )]
1312 pub index_strategy: Option<IndexStrategy>,
1313 /// Attempt to use `keyring` for authentication for index URLs.
1314 ///
1315 /// At present, only `--keyring-provider subprocess` is supported, which configures uv to
1316 /// use the `keyring` CLI to handle authentication.
1317 #[option(
1318 default = "disabled",
1319 value_type = "str",
1320 example = r#"
1321 keyring-provider = "subprocess"
1322 "#
1323 )]
1324 pub keyring_provider: Option<KeyringProviderType>,
1325 /// Don't build source distributions.
1326 ///
1327 /// When enabled, resolving will not run arbitrary Python code. The cached wheels of
1328 /// already-built source distributions will be reused, but operations that require building
1329 /// distributions will exit with an error.
1330 ///
1331 /// Alias for `--only-binary :all:`.
1332 #[option(
1333 default = "false",
1334 value_type = "bool",
1335 example = r#"
1336 no-build = true
1337 "#
1338 )]
1339 pub no_build: Option<bool>,
1340 /// Don't install pre-built wheels.
1341 ///
1342 /// The given packages will be built and installed from source. The resolver will still use
1343 /// pre-built wheels to extract package metadata, if available.
1344 ///
1345 /// Multiple packages may be provided. Disable binaries for all packages with `:all:`.
1346 /// Clear previously specified packages with `:none:`.
1347 #[option(
1348 default = "[]",
1349 value_type = "list[str]",
1350 example = r#"
1351 no-binary = ["ruff"]
1352 "#
1353 )]
1354 pub no_binary: Option<Vec<PackageNameSpecifier>>,
1355 /// Only use pre-built wheels; don't build source distributions.
1356 ///
1357 /// When enabled, resolving will not run code from the given packages. The cached wheels of already-built
1358 /// source distributions will be reused, but operations that require building distributions will
1359 /// exit with an error.
1360 ///
1361 /// Multiple packages may be provided. Disable binaries for all packages with `:all:`.
1362 /// Clear previously specified packages with `:none:`.
1363 #[option(
1364 default = "[]",
1365 value_type = "list[str]",
1366 example = r#"
1367 only-binary = ["ruff"]
1368 "#
1369 )]
1370 pub only_binary: Option<Vec<PackageNameSpecifier>>,
1371 /// Disable isolation when building source distributions.
1372 ///
1373 /// Assumes that build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
1374 /// are already installed.
1375 #[option(
1376 default = "false",
1377 value_type = "bool",
1378 example = r#"
1379 no-build-isolation = true
1380 "#
1381 )]
1382 pub no_build_isolation: Option<bool>,
1383 /// Disable isolation when building source distributions for a specific package.
1384 ///
1385 /// Assumes that the packages' build dependencies specified by [PEP 518](https://peps.python.org/pep-0518/)
1386 /// are already installed.
1387 #[option(
1388 default = "[]",
1389 value_type = "list[str]",
1390 example = r#"
1391 no-build-isolation-package = ["package1", "package2"]
1392 "#
1393 )]
1394 pub no_build_isolation_package: Option<Vec<PackageName>>,
1395 /// Additional build dependencies for packages.
1396 ///
1397 /// This allows extending the PEP 517 build environment for the project's dependencies with
1398 /// additional packages. This is useful for packages that assume the presence of packages like
1399 /// `pip`, and do not declare them as build dependencies.
1400 #[option(
1401 default = "[]",
1402 value_type = "dict",
1403 example = r#"
1404 extra-build-dependencies = { pytest = ["setuptools"] }
1405 "#
1406 )]
1407 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
1408 /// Extra environment variables to set when building certain packages.
1409 ///
1410 /// Environment variables will be added to the environment when building the
1411 /// specified packages.
1412 #[option(
1413 default = r#"{}"#,
1414 value_type = r#"dict[str, dict[str, str]]"#,
1415 example = r#"
1416 extra-build-variables = { flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" } }
1417 "#
1418 )]
1419 pub extra_build_variables: Option<ExtraBuildVariables>,
1420 /// Validate the Python environment, to detect packages with missing dependencies and other
1421 /// issues.
1422 #[option(
1423 default = "false",
1424 value_type = "bool",
1425 example = r#"
1426 strict = true
1427 "#
1428 )]
1429 pub strict: Option<bool>,
1430 /// Include optional dependencies from the specified extra; may be provided more than once.
1431 ///
1432 /// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources.
1433 #[option(
1434 default = "[]",
1435 value_type = "list[str]",
1436 example = r#"
1437 extra = ["dev", "docs"]
1438 "#
1439 )]
1440 pub extra: Option<Vec<ExtraName>>,
1441 /// Include all optional dependencies.
1442 ///
1443 /// Only applies to `pyproject.toml`, `setup.py`, and `setup.cfg` sources.
1444 #[option(
1445 default = "false",
1446 value_type = "bool",
1447 example = r#"
1448 all-extras = true
1449 "#
1450 )]
1451 pub all_extras: Option<bool>,
1452 /// Exclude the specified optional dependencies if `all-extras` is supplied.
1453 #[option(
1454 default = "[]",
1455 value_type = "list[str]",
1456 example = r#"
1457 all-extras = true
1458 no-extra = ["dev", "docs"]
1459 "#
1460 )]
1461 pub no_extra: Option<Vec<ExtraName>>,
1462 /// Ignore package dependencies, instead only add those packages explicitly listed
1463 /// on the command line to the resulting requirements file.
1464 #[option(
1465 default = "false",
1466 value_type = "bool",
1467 example = r#"
1468 no-deps = true
1469 "#
1470 )]
1471 pub no_deps: Option<bool>,
1472 /// Include the following dependency groups.
1473 #[option(
1474 default = "None",
1475 value_type = "list[str]",
1476 example = r#"
1477 group = ["dev", "docs"]
1478 "#
1479 )]
1480 pub group: Option<Vec<PipGroupName>>,
1481 /// Allow `uv pip sync` with empty requirements, which will clear the environment of all
1482 /// packages.
1483 #[option(
1484 default = "false",
1485 value_type = "bool",
1486 example = r#"
1487 allow-empty-requirements = true
1488 "#
1489 )]
1490 pub allow_empty_requirements: Option<bool>,
1491 /// The strategy to use when selecting between the different compatible versions for a given
1492 /// package requirement.
1493 ///
1494 /// By default, uv will use the latest compatible version of each package (`highest`).
1495 #[option(
1496 default = "\"highest\"",
1497 value_type = "str",
1498 example = r#"
1499 resolution = "lowest-direct"
1500 "#,
1501 possible_values = true
1502 )]
1503 pub resolution: Option<ResolutionMode>,
1504 /// The strategy to use when considering pre-release versions.
1505 ///
1506 /// By default, uv will accept pre-releases for packages that _only_ publish pre-releases,
1507 /// along with first-party requirements that contain an explicit pre-release marker in the
1508 /// declared specifiers (`if-necessary-or-explicit`).
1509 #[option(
1510 default = "\"if-necessary-or-explicit\"",
1511 value_type = "str",
1512 example = r#"
1513 prerelease = "allow"
1514 "#,
1515 possible_values = true
1516 )]
1517 pub prerelease: Option<PrereleaseMode>,
1518 /// The strategy to use when selecting multiple versions of a given package across Python
1519 /// versions and platforms.
1520 ///
1521 /// By default, uv will optimize for selecting the latest version of each package for each
1522 /// supported Python version (`requires-python`), while minimizing the number of selected
1523 /// versions across platforms.
1524 ///
1525 /// Under `fewest`, uv will minimize the number of selected versions for each package,
1526 /// preferring older versions that are compatible with a wider range of supported Python
1527 /// versions or platforms.
1528 #[option(
1529 default = "\"requires-python\"",
1530 value_type = "str",
1531 example = r#"
1532 fork-strategy = "fewest"
1533 "#,
1534 possible_values = true
1535 )]
1536 pub fork_strategy: Option<ForkStrategy>,
1537 /// Pre-defined static metadata for dependencies of the project (direct or transitive). When
1538 /// provided, enables the resolver to use the specified metadata instead of querying the
1539 /// registry or building the relevant package from source.
1540 ///
1541 /// Metadata should be provided in adherence with the [Metadata 2.3](https://packaging.python.org/en/latest/specifications/core-metadata/)
1542 /// standard, though only the following fields are respected:
1543 ///
1544 /// - `name`: The name of the package.
1545 /// - (Optional) `version`: The version of the package. If omitted, the metadata will be applied
1546 /// to all versions of the package.
1547 /// - (Optional) `requires-dist`: The dependencies of the package (e.g., `werkzeug>=0.14`).
1548 /// - (Optional) `requires-python`: The Python version required by the package (e.g., `>=3.10`).
1549 /// - (Optional) `provides-extra`: The extras provided by the package.
1550 #[option(
1551 default = r#"[]"#,
1552 value_type = "list[dict]",
1553 example = r#"
1554 dependency-metadata = [
1555 { name = "flask", version = "1.0.0", requires-dist = ["werkzeug"], requires-python = ">=3.6" },
1556 ]
1557 "#
1558 )]
1559 pub dependency_metadata: Option<Vec<StaticMetadata>>,
1560 /// Write the requirements generated by `uv pip compile` to the given `requirements.txt` file.
1561 ///
1562 /// If the file already exists, the existing versions will be preferred when resolving
1563 /// dependencies, unless `--upgrade` is also specified.
1564 #[option(
1565 default = "None",
1566 value_type = "str",
1567 example = r#"
1568 output-file = "requirements.txt"
1569 "#
1570 )]
1571 pub output_file: Option<PathBuf>,
1572 /// Include extras in the output file.
1573 ///
1574 /// By default, uv strips extras, as any packages pulled in by the extras are already included
1575 /// as dependencies in the output file directly. Further, output files generated with
1576 /// `--no-strip-extras` cannot be used as constraints files in `install` and `sync` invocations.
1577 #[option(
1578 default = "false",
1579 value_type = "bool",
1580 example = r#"
1581 no-strip-extras = true
1582 "#
1583 )]
1584 pub no_strip_extras: Option<bool>,
1585 /// Include environment markers in the output file generated by `uv pip compile`.
1586 ///
1587 /// By default, uv strips environment markers, as the resolution generated by `compile` is
1588 /// only guaranteed to be correct for the target environment.
1589 #[option(
1590 default = "false",
1591 value_type = "bool",
1592 example = r#"
1593 no-strip-markers = true
1594 "#
1595 )]
1596 pub no_strip_markers: Option<bool>,
1597 /// Exclude comment annotations indicating the source of each package from the output file
1598 /// generated by `uv pip compile`.
1599 #[option(
1600 default = "false",
1601 value_type = "bool",
1602 example = r#"
1603 no-annotate = true
1604 "#
1605 )]
1606 pub no_annotate: Option<bool>,
1607 /// Exclude the comment header at the top of output file generated by `uv pip compile`.
1608 #[option(
1609 default = r#"false"#,
1610 value_type = "bool",
1611 example = r#"
1612 no-header = true
1613 "#
1614 )]
1615 pub no_header: Option<bool>,
1616 /// The header comment to include at the top of the output file generated by `uv pip compile`.
1617 ///
1618 /// Used to reflect custom build scripts and commands that wrap `uv pip compile`.
1619 #[option(
1620 default = "None",
1621 value_type = "str",
1622 example = r#"
1623 custom-compile-command = "./custom-uv-compile.sh"
1624 "#
1625 )]
1626 pub custom_compile_command: Option<String>,
1627 /// Include distribution hashes in the output file.
1628 #[option(
1629 default = "false",
1630 value_type = "bool",
1631 example = r#"
1632 generate-hashes = true
1633 "#
1634 )]
1635 pub generate_hashes: Option<bool>,
1636 /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend,
1637 /// specified as `KEY=VALUE` pairs.
1638 #[option(
1639 default = "{}",
1640 value_type = "dict",
1641 example = r#"
1642 config-settings = { editable_mode = "compat" }
1643 "#
1644 )]
1645 pub config_settings: Option<ConfigSettings>,
1646 /// Settings to pass to the [PEP 517](https://peps.python.org/pep-0517/) build backend for specific packages,
1647 /// specified as `KEY=VALUE` pairs.
1648 #[option(
1649 default = "{}",
1650 value_type = "dict",
1651 example = r#"
1652 config-settings-package = { numpy = { editable_mode = "compat" } }
1653 "#
1654 )]
1655 pub config_settings_package: Option<PackageConfigSettings>,
1656 /// The minimum Python version that should be supported by the resolved requirements (e.g.,
1657 /// `3.8` or `3.8.17`).
1658 ///
1659 /// If a patch version is omitted, the minimum patch version is assumed. For example, `3.8` is
1660 /// mapped to `3.8.0`.
1661 #[option(
1662 default = "None",
1663 value_type = "str",
1664 example = r#"
1665 python-version = "3.8"
1666 "#
1667 )]
1668 pub python_version: Option<PythonVersion>,
1669 /// The platform for which requirements should be resolved.
1670 ///
1671 /// Represented as a "target triple", a string that describes the target platform in terms of
1672 /// its CPU, vendor, and operating system name, like `x86_64-unknown-linux-gnu` or
1673 /// `aarch64-apple-darwin`.
1674 #[option(
1675 default = "None",
1676 value_type = "str",
1677 example = r#"
1678 python-platform = "x86_64-unknown-linux-gnu"
1679 "#
1680 )]
1681 pub python_platform: Option<TargetTriple>,
1682 /// Perform a universal resolution, attempting to generate a single `requirements.txt` output
1683 /// file that is compatible with all operating systems, architectures, and Python
1684 /// implementations.
1685 ///
1686 /// In universal mode, the current Python version (or user-provided `--python-version`) will be
1687 /// treated as a lower bound. For example, `--universal --python-version 3.7` would produce a
1688 /// universal resolution for Python 3.7 and later.
1689 #[option(
1690 default = "false",
1691 value_type = "bool",
1692 example = r#"
1693 universal = true
1694 "#
1695 )]
1696 pub universal: Option<bool>,
1697 /// Limit candidate packages to those that were uploaded prior to a given point in time.
1698 ///
1699 /// Accepts a superset of [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339.html) (e.g.,
1700 /// `2006-12-02T02:07:43Z`). A full timestamp is required to ensure that the resolver will
1701 /// behave consistently across timezones.
1702 #[option(
1703 default = "None",
1704 value_type = "str",
1705 example = r#"
1706 exclude-newer = "2006-12-02T02:07:43Z"
1707 "#
1708 )]
1709 pub exclude_newer: Option<ExcludeNewerValue>,
1710 /// Limit candidate packages for specific packages to those that were uploaded prior to the given date.
1711 ///
1712 /// Accepts package-date pairs in a dictionary format.
1713 #[option(
1714 default = "None",
1715 value_type = "dict",
1716 example = r#"
1717 exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z" }
1718 "#
1719 )]
1720 pub exclude_newer_package: Option<ExcludeNewerPackage>,
1721 /// Specify a package to omit from the output resolution. Its dependencies will still be
1722 /// included in the resolution. Equivalent to pip-compile's `--unsafe-package` option.
1723 #[option(
1724 default = "[]",
1725 value_type = "list[str]",
1726 example = r#"
1727 no-emit-package = ["ruff"]
1728 "#
1729 )]
1730 pub no_emit_package: Option<Vec<PackageName>>,
1731 /// Include `--index-url` and `--extra-index-url` entries in the output file generated by `uv pip compile`.
1732 #[option(
1733 default = "false",
1734 value_type = "bool",
1735 example = r#"
1736 emit-index-url = true
1737 "#
1738 )]
1739 pub emit_index_url: Option<bool>,
1740 /// Include `--find-links` entries in the output file generated by `uv pip compile`.
1741 #[option(
1742 default = "false",
1743 value_type = "bool",
1744 example = r#"
1745 emit-find-links = true
1746 "#
1747 )]
1748 pub emit_find_links: Option<bool>,
1749 /// Include `--no-binary` and `--only-binary` entries in the output file generated by `uv pip compile`.
1750 #[option(
1751 default = "false",
1752 value_type = "bool",
1753 example = r#"
1754 emit-build-options = true
1755 "#
1756 )]
1757 pub emit_build_options: Option<bool>,
1758 /// Whether to emit a marker string indicating the conditions under which the set of pinned
1759 /// dependencies is valid.
1760 ///
1761 /// The pinned dependencies may be valid even when the marker expression is
1762 /// false, but when the expression is true, the requirements are known to
1763 /// be correct.
1764 #[option(
1765 default = "false",
1766 value_type = "bool",
1767 example = r#"
1768 emit-marker-expression = true
1769 "#
1770 )]
1771 pub emit_marker_expression: Option<bool>,
1772 /// Include comment annotations indicating the index used to resolve each package (e.g.,
1773 /// `# from https://pypi.org/simple`).
1774 #[option(
1775 default = "false",
1776 value_type = "bool",
1777 example = r#"
1778 emit-index-annotation = true
1779 "#
1780 )]
1781 pub emit_index_annotation: Option<bool>,
1782 /// The style of the annotation comments included in the output file, used to indicate the
1783 /// source of each package.
1784 #[option(
1785 default = "\"split\"",
1786 value_type = "str",
1787 example = r#"
1788 annotation-style = "line"
1789 "#,
1790 possible_values = true
1791 )]
1792 pub annotation_style: Option<AnnotationStyle>,
1793 /// The method to use when installing packages from the global cache.
1794 ///
1795 /// Defaults to `clone` (also known as Copy-on-Write) on macOS and Linux, and `hardlink` on
1796 /// Windows.
1797 ///
1798 /// WARNING: The use of symlink link mode is discouraged, as they create tight coupling between
1799 /// the cache and the target environment. For example, clearing the cache (`uv cache clean`)
1800 /// will break all installed packages by way of removing the underlying source files. Use
1801 /// symlinks with caution.
1802 #[option(
1803 default = "\"clone\" (macOS, Linux) or \"hardlink\" (Windows)",
1804 value_type = "str",
1805 example = r#"
1806 link-mode = "copy"
1807 "#,
1808 possible_values = true
1809 )]
1810 pub link_mode: Option<LinkMode>,
1811 /// Compile Python files to bytecode after installation.
1812 ///
1813 /// By default, uv does not compile Python (`.py`) files to bytecode (`__pycache__/*.pyc`);
1814 /// instead, compilation is performed lazily the first time a module is imported. For use-cases
1815 /// in which start time is critical, such as CLI applications and Docker containers, this option
1816 /// can be enabled to trade longer installation times for faster start times.
1817 ///
1818 /// When enabled, uv will process the entire site-packages directory (including packages that
1819 /// are not being modified by the current operation) for consistency. Like pip, it will also
1820 /// ignore errors.
1821 #[option(
1822 default = "false",
1823 value_type = "bool",
1824 example = r#"
1825 compile-bytecode = true
1826 "#
1827 )]
1828 pub compile_bytecode: Option<bool>,
1829 /// Require a matching hash for each requirement.
1830 ///
1831 /// Hash-checking mode is all or nothing. If enabled, _all_ requirements must be provided
1832 /// with a corresponding hash or set of hashes. Additionally, if enabled, _all_ requirements
1833 /// must either be pinned to exact versions (e.g., `==1.0.0`), or be specified via direct URL.
1834 ///
1835 /// Hash-checking mode introduces a number of additional constraints:
1836 ///
1837 /// - Git dependencies are not supported.
1838 /// - Editable installations are not supported.
1839 /// - Local dependencies are not supported, unless they point to a specific wheel (`.whl`) or
1840 /// source archive (`.zip`, `.tar.gz`), as opposed to a directory.
1841 #[option(
1842 default = "false",
1843 value_type = "bool",
1844 example = r#"
1845 require-hashes = true
1846 "#
1847 )]
1848 pub require_hashes: Option<bool>,
1849 /// Validate any hashes provided in the requirements file.
1850 ///
1851 /// Unlike `--require-hashes`, `--verify-hashes` does not require that all requirements have
1852 /// hashes; instead, it will limit itself to verifying the hashes of those requirements that do
1853 /// include them.
1854 #[option(
1855 default = "true",
1856 value_type = "bool",
1857 example = r#"
1858 verify-hashes = true
1859 "#
1860 )]
1861 pub verify_hashes: Option<bool>,
1862 /// Ignore the `tool.uv.sources` table when resolving dependencies. Used to lock against the
1863 /// standards-compliant, publishable package metadata, as opposed to using any local or Git
1864 /// sources.
1865 #[option(
1866 default = "false",
1867 value_type = "bool",
1868 example = r#"
1869 no-sources = true
1870 "#
1871 )]
1872 pub no_sources: Option<bool>,
1873 /// Ignore `tool.uv.sources` for the specified packages.
1874 #[option(
1875 default = "[]",
1876 value_type = "list[str]",
1877 example = r#"
1878 no-sources-package = ["ruff"]
1879 "#
1880 )]
1881 pub no_sources_package: Option<Vec<PackageName>>,
1882 /// Allow package upgrades, ignoring pinned versions in any existing output file.
1883 #[option(
1884 default = "false",
1885 value_type = "bool",
1886 example = r#"
1887 upgrade = true
1888 "#
1889 )]
1890 pub upgrade: Option<bool>,
1891 /// Allow upgrades for a specific package, ignoring pinned versions in any existing output
1892 /// file.
1893 ///
1894 /// Accepts both standalone package names (`ruff`) and version specifiers (`ruff<0.5.0`).
1895 #[option(
1896 default = "[]",
1897 value_type = "list[str]",
1898 example = r#"
1899 upgrade-package = ["ruff"]
1900 "#
1901 )]
1902 pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
1903 /// Reinstall all packages, regardless of whether they're already installed. Implies `refresh`.
1904 #[option(
1905 default = "false",
1906 value_type = "bool",
1907 example = r#"
1908 reinstall = true
1909 "#
1910 )]
1911 pub reinstall: Option<bool>,
1912 /// Reinstall a specific package, regardless of whether it's already installed. Implies
1913 /// `refresh-package`.
1914 #[option(
1915 default = "[]",
1916 value_type = "list[str]",
1917 example = r#"
1918 reinstall-package = ["ruff"]
1919 "#
1920 )]
1921 pub reinstall_package: Option<Vec<PackageName>>,
1922 /// The backend to use when fetching packages in the PyTorch ecosystem.
1923 ///
1924 /// When set, uv will ignore the configured index URLs for packages in the PyTorch ecosystem,
1925 /// and will instead use the defined backend.
1926 ///
1927 /// For example, when set to `cpu`, uv will use the CPU-only PyTorch index; when set to `cu126`,
1928 /// uv will use the PyTorch index for CUDA 12.6.
1929 ///
1930 /// The `auto` mode will attempt to detect the appropriate PyTorch index based on the currently
1931 /// installed CUDA drivers.
1932 ///
1933 /// This setting is only respected by `uv pip` commands.
1934 ///
1935 /// This option is in preview and may change in any future release.
1936 #[option(
1937 default = "null",
1938 value_type = "str",
1939 example = r#"
1940 torch-backend = "auto"
1941 "#
1942 )]
1943 pub torch_backend: Option<TorchMode>,
1944}
1945
1946impl PipOptions {
1947 /// Resolve the [`PipOptions`] relative to the given root directory.
1948 pub fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
1949 Ok(Self {
1950 index: self
1951 .index
1952 .map(|index| {
1953 index
1954 .into_iter()
1955 .map(|index| index.relative_to(root_dir))
1956 .collect::<Result<Vec<_>, _>>()
1957 })
1958 .transpose()?,
1959 index_url: self
1960 .index_url
1961 .map(|index_url| index_url.relative_to(root_dir))
1962 .transpose()?,
1963 extra_index_url: self
1964 .extra_index_url
1965 .map(|extra_index_url| {
1966 extra_index_url
1967 .into_iter()
1968 .map(|extra_index_url| extra_index_url.relative_to(root_dir))
1969 .collect::<Result<Vec<_>, _>>()
1970 })
1971 .transpose()?,
1972 find_links: self
1973 .find_links
1974 .map(|find_links| {
1975 find_links
1976 .into_iter()
1977 .map(|find_link| find_link.relative_to(root_dir))
1978 .collect::<Result<Vec<_>, _>>()
1979 })
1980 .transpose()?,
1981 ..self
1982 })
1983 }
1984}
1985
1986impl From<ResolverInstallerSchema> for ResolverOptions {
1987 fn from(value: ResolverInstallerSchema) -> Self {
1988 Self {
1989 index: value.index,
1990 index_url: value.index_url,
1991 extra_index_url: value.extra_index_url,
1992 no_index: value.no_index,
1993 find_links: value.find_links,
1994 index_strategy: value.index_strategy,
1995 keyring_provider: value.keyring_provider,
1996 resolution: value.resolution,
1997 prerelease: value.prerelease,
1998 fork_strategy: value.fork_strategy,
1999 dependency_metadata: value.dependency_metadata,
2000 config_settings: value.config_settings,
2001 config_settings_package: value.config_settings_package,
2002 exclude_newer: ExcludeNewer::from_args(
2003 value.exclude_newer,
2004 value
2005 .exclude_newer_package
2006 .unwrap_or_default()
2007 .into_iter()
2008 .map(Into::into)
2009 .collect(),
2010 ),
2011 link_mode: value.link_mode,
2012 upgrade: Upgrade::from_args(
2013 value.upgrade,
2014 value
2015 .upgrade_package
2016 .into_iter()
2017 .flatten()
2018 .map(Into::into)
2019 .collect(),
2020 ),
2021 no_build: value.no_build,
2022 no_build_package: value.no_build_package,
2023 no_binary: value.no_binary,
2024 no_binary_package: value.no_binary_package,
2025 build_isolation: BuildIsolation::from_args(
2026 value.no_build_isolation,
2027 value.no_build_isolation_package.unwrap_or_default(),
2028 ),
2029 extra_build_dependencies: value.extra_build_dependencies,
2030 extra_build_variables: value.extra_build_variables,
2031 no_sources: value.no_sources,
2032 no_sources_package: value.no_sources_package,
2033 torch_backend: value.torch_backend,
2034 }
2035 }
2036}
2037
2038impl From<ResolverInstallerSchema> for InstallerOptions {
2039 fn from(value: ResolverInstallerSchema) -> Self {
2040 Self {
2041 index: value.index,
2042 index_url: value.index_url,
2043 extra_index_url: value.extra_index_url,
2044 no_index: value.no_index,
2045 find_links: value.find_links,
2046 index_strategy: value.index_strategy,
2047 keyring_provider: value.keyring_provider,
2048 config_settings: value.config_settings,
2049 exclude_newer: ExcludeNewer::from_args(
2050 value.exclude_newer,
2051 value
2052 .exclude_newer_package
2053 .unwrap_or_default()
2054 .into_iter()
2055 .map(Into::into)
2056 .collect(),
2057 )
2058 .global,
2059 link_mode: value.link_mode,
2060 compile_bytecode: value.compile_bytecode,
2061 reinstall: Reinstall::from_args(
2062 value.reinstall,
2063 value.reinstall_package.unwrap_or_default(),
2064 ),
2065 build_isolation: BuildIsolation::from_args(
2066 value.no_build_isolation,
2067 value.no_build_isolation_package.unwrap_or_default(),
2068 ),
2069 no_build: value.no_build,
2070 no_build_package: value.no_build_package,
2071 no_binary: value.no_binary,
2072 no_binary_package: value.no_binary_package,
2073 no_sources: value.no_sources,
2074 no_sources_package: value.no_sources_package,
2075 }
2076 }
2077}
2078
2079/// The options persisted alongside an installed tool.
2080///
2081/// A mirror of [`ResolverInstallerSchema`], without upgrades and reinstalls, which shouldn't be
2082/// persisted in a tool receipt.
2083#[derive(
2084 Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, CombineOptions, OptionsMetadata,
2085)]
2086#[serde(deny_unknown_fields, rename_all = "kebab-case")]
2087#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2088pub struct ToolOptions {
2089 pub index: Option<Vec<Index>>,
2090 pub index_url: Option<PipIndex>,
2091 pub extra_index_url: Option<Vec<PipExtraIndex>>,
2092 pub no_index: Option<bool>,
2093 pub find_links: Option<Vec<PipFindLinks>>,
2094 pub index_strategy: Option<IndexStrategy>,
2095 pub keyring_provider: Option<KeyringProviderType>,
2096 pub resolution: Option<ResolutionMode>,
2097 pub prerelease: Option<PrereleaseMode>,
2098 pub fork_strategy: Option<ForkStrategy>,
2099 pub dependency_metadata: Option<Vec<StaticMetadata>>,
2100 pub config_settings: Option<ConfigSettings>,
2101 pub config_settings_package: Option<PackageConfigSettings>,
2102 pub build_isolation: Option<BuildIsolation>,
2103 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
2104 pub extra_build_variables: Option<ExtraBuildVariables>,
2105 pub exclude_newer: Option<ExcludeNewerValue>,
2106 pub exclude_newer_package: Option<ExcludeNewerPackage>,
2107 pub link_mode: Option<LinkMode>,
2108 pub compile_bytecode: Option<bool>,
2109 pub no_sources: Option<bool>,
2110 pub no_sources_package: Option<Vec<PackageName>>,
2111 pub no_build: Option<bool>,
2112 pub no_build_package: Option<Vec<PackageName>>,
2113 pub no_binary: Option<bool>,
2114 pub no_binary_package: Option<Vec<PackageName>>,
2115 pub torch_backend: Option<TorchMode>,
2116}
2117
2118impl From<ResolverInstallerOptions> for ToolOptions {
2119 fn from(value: ResolverInstallerOptions) -> Self {
2120 Self {
2121 index: value.index.map(|indexes| {
2122 indexes
2123 .into_iter()
2124 .map(Index::with_promoted_auth_policy)
2125 .collect()
2126 }),
2127 index_url: value.index_url,
2128 extra_index_url: value.extra_index_url,
2129 no_index: value.no_index,
2130 find_links: value.find_links,
2131 index_strategy: value.index_strategy,
2132 keyring_provider: value.keyring_provider,
2133 resolution: value.resolution,
2134 prerelease: value.prerelease,
2135 fork_strategy: value.fork_strategy,
2136 dependency_metadata: value.dependency_metadata,
2137 config_settings: value.config_settings,
2138 config_settings_package: value.config_settings_package,
2139 build_isolation: value.build_isolation,
2140 extra_build_dependencies: value.extra_build_dependencies,
2141 extra_build_variables: value.extra_build_variables,
2142 exclude_newer: value.exclude_newer,
2143 exclude_newer_package: value.exclude_newer_package,
2144 link_mode: value.link_mode,
2145 compile_bytecode: value.compile_bytecode,
2146 no_sources: value.no_sources,
2147 no_sources_package: value.no_sources_package,
2148 no_build: value.no_build,
2149 no_build_package: value.no_build_package,
2150 no_binary: value.no_binary,
2151 no_binary_package: value.no_binary_package,
2152 torch_backend: value.torch_backend,
2153 }
2154 }
2155}
2156
2157impl From<ToolOptions> for ResolverInstallerOptions {
2158 fn from(value: ToolOptions) -> Self {
2159 Self {
2160 index: value.index,
2161 index_url: value.index_url,
2162 extra_index_url: value.extra_index_url,
2163 no_index: value.no_index,
2164 find_links: value.find_links,
2165 index_strategy: value.index_strategy,
2166 keyring_provider: value.keyring_provider,
2167 resolution: value.resolution,
2168 prerelease: value.prerelease,
2169 fork_strategy: value.fork_strategy,
2170 dependency_metadata: value.dependency_metadata,
2171 config_settings: value.config_settings,
2172 config_settings_package: value.config_settings_package,
2173 build_isolation: value.build_isolation,
2174 extra_build_dependencies: value.extra_build_dependencies,
2175 extra_build_variables: value.extra_build_variables,
2176 exclude_newer: value.exclude_newer,
2177 exclude_newer_package: value.exclude_newer_package,
2178 link_mode: value.link_mode,
2179 compile_bytecode: value.compile_bytecode,
2180 no_sources: value.no_sources,
2181 no_sources_package: value.no_sources_package,
2182 upgrade: None,
2183 reinstall: None,
2184 no_build: value.no_build,
2185 no_build_package: value.no_build_package,
2186 no_binary: value.no_binary,
2187 no_binary_package: value.no_binary_package,
2188 torch_backend: value.torch_backend,
2189 }
2190 }
2191}
2192
2193/// Like [`Options]`, but with any `#[serde(flatten)]` fields inlined. This leads to far, far
2194/// better error messages when deserializing.
2195#[derive(Debug, Clone, Default, Deserialize)]
2196#[serde(rename_all = "kebab-case", deny_unknown_fields)]
2197pub struct OptionsWire {
2198 // #[serde(flatten)]
2199 // globals: GlobalOptions
2200 required_version: Option<RequiredVersion>,
2201 system_certs: Option<bool>,
2202 native_tls: Option<bool>,
2203 offline: Option<bool>,
2204 no_cache: Option<bool>,
2205 cache_dir: Option<PathBuf>,
2206 preview: Option<bool>,
2207 python_preference: Option<PythonPreference>,
2208 python_downloads: Option<PythonDownloads>,
2209 concurrent_downloads: Option<NonZeroUsize>,
2210 concurrent_builds: Option<NonZeroUsize>,
2211 concurrent_installs: Option<NonZeroUsize>,
2212
2213 // #[serde(flatten)]
2214 // top_level: ResolverInstallerOptions
2215 index: Option<Vec<Index>>,
2216 index_url: Option<PipIndex>,
2217 extra_index_url: Option<Vec<PipExtraIndex>>,
2218 no_index: Option<bool>,
2219 find_links: Option<Vec<PipFindLinks>>,
2220 index_strategy: Option<IndexStrategy>,
2221 keyring_provider: Option<KeyringProviderType>,
2222 http_proxy: Option<ProxyUrl>,
2223 https_proxy: Option<ProxyUrl>,
2224 no_proxy: Option<Vec<String>>,
2225 allow_insecure_host: Option<Vec<TrustedHost>>,
2226 resolution: Option<ResolutionMode>,
2227 prerelease: Option<PrereleaseMode>,
2228 fork_strategy: Option<ForkStrategy>,
2229 dependency_metadata: Option<Vec<StaticMetadata>>,
2230 config_settings: Option<ConfigSettings>,
2231 config_settings_package: Option<PackageConfigSettings>,
2232 no_build_isolation: Option<bool>,
2233 no_build_isolation_package: Option<Vec<PackageName>>,
2234 extra_build_dependencies: Option<ExtraBuildDependencies>,
2235 extra_build_variables: Option<ExtraBuildVariables>,
2236 exclude_newer: Option<ExcludeNewerValue>,
2237 exclude_newer_package: Option<ExcludeNewerPackage>,
2238 link_mode: Option<LinkMode>,
2239 compile_bytecode: Option<bool>,
2240 no_sources: Option<bool>,
2241 no_sources_package: Option<Vec<PackageName>>,
2242 upgrade: Option<bool>,
2243 upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2244 reinstall: Option<bool>,
2245 reinstall_package: Option<Vec<PackageName>>,
2246 no_build: Option<bool>,
2247 no_build_package: Option<Vec<PackageName>>,
2248 no_binary: Option<bool>,
2249 no_binary_package: Option<Vec<PackageName>>,
2250 torch_backend: Option<TorchMode>,
2251
2252 // #[serde(flatten)]
2253 // install_mirror: PythonInstallMirrors,
2254 python_install_mirror: Option<String>,
2255 pypy_install_mirror: Option<String>,
2256 python_downloads_json_url: Option<String>,
2257
2258 // #[serde(flatten)]
2259 // publish: PublishOptions
2260 publish_url: Option<DisplaySafeUrl>,
2261 trusted_publishing: Option<TrustedPublishing>,
2262 check_url: Option<IndexUrl>,
2263
2264 // #[serde(flatten)]
2265 // add: AddOptions
2266 add_bounds: Option<AddBoundsKind>,
2267
2268 pip: Option<PipOptions>,
2269 cache_keys: Option<Vec<CacheKey>>,
2270
2271 // NOTE(charlie): These fields are shared with `ToolUv` in
2272 // `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
2273 // They're respected in both `pyproject.toml` and `uv.toml` files.
2274 override_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2275 exclude_dependencies: Option<Vec<PackageName>>,
2276 constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2277 build_constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2278 environments: Option<SupportedEnvironments>,
2279 required_environments: Option<SupportedEnvironments>,
2280
2281 // NOTE(charlie): These fields should be kept in-sync with `ToolUv` in
2282 // `crates/uv-workspace/src/pyproject.rs`. The documentation lives on that struct.
2283 // They're only respected in `pyproject.toml` files, and should be rejected in `uv.toml` files.
2284 conflicts: Option<serde::de::IgnoredAny>,
2285 workspace: Option<serde::de::IgnoredAny>,
2286 sources: Option<serde::de::IgnoredAny>,
2287 managed: Option<serde::de::IgnoredAny>,
2288 r#package: Option<serde::de::IgnoredAny>,
2289 default_groups: Option<serde::de::IgnoredAny>,
2290 dependency_groups: Option<serde::de::IgnoredAny>,
2291 dev_dependencies: Option<serde::de::IgnoredAny>,
2292
2293 // Build backend
2294 build_backend: Option<serde::de::IgnoredAny>,
2295}
2296
2297impl From<OptionsWire> for Options {
2298 #[allow(deprecated)]
2299 fn from(value: OptionsWire) -> Self {
2300 let OptionsWire {
2301 required_version,
2302 system_certs,
2303 native_tls,
2304 offline,
2305 no_cache,
2306 cache_dir,
2307 preview,
2308 python_preference,
2309 python_downloads,
2310 python_install_mirror,
2311 pypy_install_mirror,
2312 python_downloads_json_url,
2313 concurrent_downloads,
2314 concurrent_builds,
2315 concurrent_installs,
2316 index,
2317 index_url,
2318 extra_index_url,
2319 no_index,
2320 find_links,
2321 index_strategy,
2322 keyring_provider,
2323 http_proxy,
2324 https_proxy,
2325 no_proxy,
2326 allow_insecure_host,
2327 resolution,
2328 prerelease,
2329 fork_strategy,
2330 dependency_metadata,
2331 config_settings,
2332 config_settings_package,
2333 no_build_isolation,
2334 no_build_isolation_package,
2335 exclude_newer,
2336 exclude_newer_package,
2337 link_mode,
2338 compile_bytecode,
2339 no_sources,
2340 no_sources_package,
2341 upgrade,
2342 upgrade_package,
2343 reinstall,
2344 reinstall_package,
2345 no_build,
2346 no_build_package,
2347 no_binary,
2348 no_binary_package,
2349 torch_backend,
2350 pip,
2351 cache_keys,
2352 override_dependencies,
2353 exclude_dependencies,
2354 constraint_dependencies,
2355 build_constraint_dependencies,
2356 environments,
2357 required_environments,
2358 conflicts,
2359 publish_url,
2360 trusted_publishing,
2361 check_url,
2362 workspace,
2363 sources,
2364 default_groups,
2365 dependency_groups,
2366 extra_build_dependencies,
2367 extra_build_variables,
2368 dev_dependencies,
2369 managed,
2370 package,
2371 add_bounds: bounds,
2372 // Used by the build backend
2373 build_backend,
2374 } = value;
2375
2376 Self {
2377 globals: GlobalOptions {
2378 required_version,
2379 system_certs,
2380 native_tls,
2381 offline,
2382 no_cache,
2383 cache_dir,
2384 preview,
2385 python_preference,
2386 python_downloads,
2387 concurrent_downloads,
2388 concurrent_builds,
2389 concurrent_installs,
2390 http_proxy,
2391 https_proxy,
2392 no_proxy,
2393 // Used twice for backwards compatibility
2394 allow_insecure_host: allow_insecure_host.clone(),
2395 },
2396 top_level: ResolverInstallerSchema {
2397 index,
2398 index_url,
2399 extra_index_url,
2400 no_index,
2401 find_links,
2402 index_strategy,
2403 keyring_provider,
2404 resolution,
2405 prerelease,
2406 fork_strategy,
2407 dependency_metadata,
2408 config_settings,
2409 config_settings_package,
2410 no_build_isolation,
2411 no_build_isolation_package,
2412 extra_build_dependencies,
2413 extra_build_variables,
2414 exclude_newer,
2415 exclude_newer_package,
2416 link_mode,
2417 compile_bytecode,
2418 no_sources,
2419 no_sources_package,
2420 upgrade,
2421 upgrade_package,
2422 reinstall,
2423 reinstall_package,
2424 no_build,
2425 no_build_package,
2426 no_binary,
2427 no_binary_package,
2428 torch_backend,
2429 },
2430 pip,
2431 cache_keys,
2432 build_backend,
2433 override_dependencies,
2434 exclude_dependencies,
2435 constraint_dependencies,
2436 build_constraint_dependencies,
2437 environments,
2438 required_environments,
2439 install_mirrors: PythonInstallMirrors {
2440 python_install_mirror,
2441 pypy_install_mirror,
2442 python_downloads_json_url,
2443 },
2444 conflicts,
2445 publish: PublishOptions {
2446 publish_url,
2447 trusted_publishing,
2448 check_url,
2449 },
2450 add: AddOptions { add_bounds: bounds },
2451 workspace,
2452 sources,
2453 dev_dependencies,
2454 default_groups,
2455 dependency_groups,
2456 managed,
2457 package,
2458 }
2459 }
2460}
2461
2462#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2463#[serde(rename_all = "kebab-case")]
2464#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2465pub struct PublishOptions {
2466 /// The URL for publishing packages to the Python package index (by default:
2467 /// <https://upload.pypi.org/legacy/>).
2468 #[option(
2469 default = "\"https://upload.pypi.org/legacy/\"",
2470 value_type = "str",
2471 example = r#"
2472 publish-url = "https://test.pypi.org/legacy/"
2473 "#
2474 )]
2475 pub publish_url: Option<DisplaySafeUrl>,
2476
2477 /// Configure trusted publishing.
2478 ///
2479 /// By default, uv checks for trusted publishing when running in a supported environment, but
2480 /// ignores it if it isn't configured.
2481 ///
2482 /// uv's supported environments for trusted publishing include GitHub Actions and GitLab CI/CD.
2483 #[option(
2484 default = "automatic",
2485 value_type = "str",
2486 example = r#"
2487 trusted-publishing = "always"
2488 "#
2489 )]
2490 pub trusted_publishing: Option<TrustedPublishing>,
2491
2492 /// Check an index URL for existing files to skip duplicate uploads.
2493 ///
2494 /// This option allows retrying publishing that failed after only some, but not all files have
2495 /// been uploaded, and handles error due to parallel uploads of the same file.
2496 ///
2497 /// Before uploading, the index is checked. If the exact same file already exists in the index,
2498 /// the file will not be uploaded. If an error occurred during the upload, the index is checked
2499 /// again, to handle cases where the identical file was uploaded twice in parallel.
2500 ///
2501 /// The exact behavior will vary based on the index. When uploading to PyPI, uploading the same
2502 /// file succeeds even without `--check-url`, while most other indexes error.
2503 ///
2504 /// The index must provide one of the supported hashes (SHA-256, SHA-384, or SHA-512).
2505 #[option(
2506 default = "None",
2507 value_type = "str",
2508 example = r#"
2509 check-url = "https://test.pypi.org/simple"
2510 "#
2511 )]
2512 pub check_url: Option<IndexUrl>,
2513}
2514
2515#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2516#[serde(rename_all = "kebab-case")]
2517#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2518pub struct AddOptions {
2519 /// The default version specifier when adding a dependency.
2520 ///
2521 /// When adding a dependency to the project, if no constraint or URL is provided, a constraint
2522 /// is added based on the latest compatible version of the package. By default, a lower bound
2523 /// constraint is used, e.g., `>=1.2.3`.
2524 ///
2525 /// When `--frozen` is provided, no resolution is performed, and dependencies are always added
2526 /// without constraints.
2527 ///
2528 /// This option is in preview and may change in any future release.
2529 #[option(
2530 default = "\"lower\"",
2531 value_type = "str",
2532 example = r#"
2533 add-bounds = "major"
2534 "#,
2535 possible_values = true
2536 )]
2537 pub add_bounds: Option<AddBoundsKind>,
2538}