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