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