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