Skip to main content

uv_settings/
settings.rs

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