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