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