1#[cfg(feature = "schemars")]
2use std::borrow::Cow;
3use std::{fmt::Debug, num::NonZeroUsize, path::Path, path::PathBuf};
4
5use serde::{Deserialize, Serialize};
6
7use uv_cache_info::CacheKey;
8use uv_configuration::{
9 AddBoundsKind, AnnotationStyle, BuildIsolation, ExcludeDependency, ExcludeNewerPackage,
10 ForkStrategy, IndexStrategy, KeyringProviderType, PackageNameSpecifier, PrereleaseMode,
11 PrereleasePackage, ProxyUrl, Reinstall, RequiredVersion, ResolutionMode, TargetTriple,
12 TrustedHost, TrustedPublishing, Upgrade, serialize_exclude_newer_package_with_spans,
13};
14use uv_distribution_types::{
15 ConfigSettings, ExcludeNewerOverride, ExcludeNewerSpan, ExcludeNewerValue, ExtraBuildVariables,
16 Index, IndexLocations, IndexUrl, IndexUrlError, MinimumLibcVersion, Origin,
17 PackageConfigSettings, PipExtraIndex, PipFindLinks, PipIndex, StaticMetadata,
18};
19use uv_install_wheel::LinkMode;
20use uv_macros::{CombineOptions, DeserializeUntagged, OptionsMetadata};
21use uv_normalize::{ExtraName, PackageName, PipGroupName};
22use uv_pep508::Requirement;
23use uv_preview::{MaybePreviewFeature, Preview};
24use uv_pypi_types::{SupportedEnvironments, VerbatimParsedUrl};
25use uv_python_types::{PythonDownloadMirrors, PythonDownloads, PythonPreference, PythonVersion};
26use uv_redacted::SafeUrl;
27use uv_torch::TorchMode;
28use uv_workspace::pyproject::{
29 BuildConstraintDependency, ExtraBuildDependencies, OverrideDependency,
30};
31
32use crate::{EnvironmentOptions, FilesystemOptions};
33
34#[allow(dead_code)]
36#[derive(Debug, Clone, Default, Deserialize)]
37pub(crate) struct PyProjectToml {
38 pub(crate) tool: Option<Tools>,
39}
40
41#[allow(dead_code)]
43#[derive(Debug, Clone, Default, Deserialize)]
44pub(crate) struct Tools {
45 pub(crate) uv: Option<Options>,
46}
47
48#[derive(Debug, Clone, Default, Deserialize)]
50pub(crate) struct PyProjectRequiredVersionToml {
51 pub(crate) tool: Option<RequiredVersionTools>,
52}
53
54#[derive(Debug, Clone, Default, Deserialize)]
56pub(crate) struct RequiredVersionTools {
57 pub(crate) uv: Option<RequiredVersionOptions>,
58}
59
60#[derive(Debug, Clone, Default, Deserialize)]
62#[serde(rename_all = "kebab-case")]
63pub(crate) struct RequiredVersionOptions {
64 pub(crate) required_version: Option<RequiredVersion>,
65}
66
67#[derive(Debug, Clone, Default, Deserialize)]
69#[serde(rename_all = "kebab-case")]
70pub(crate) struct UvRequiredVersionToml {
71 pub(crate) required_version: Option<RequiredVersion>,
72}
73
74#[allow(dead_code)]
76#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
77#[serde(try_from = "OptionsWire", rename_all = "kebab-case")]
78#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
79#[cfg_attr(feature = "schemars", schemars(!try_from))]
80pub struct Options {
81 #[serde(flatten)]
82 pub globals: GlobalOptions,
83
84 #[serde(flatten)]
85 pub top_level: ResolverInstallerSchema,
86
87 #[serde(flatten)]
88 pub install_mirrors: PythonInstallMirrors,
89
90 #[serde(flatten)]
91 pub publish: PublishOptions,
92
93 #[serde(flatten)]
94 pub add: AddOptions,
95
96 #[option_group]
97 pub audit: Option<AuditOptions>,
98
99 #[option_group]
100 pub pip: Option<PipOptions>,
101
102 #[option(
138 default = r#"[{ file = "pyproject.toml" }, { file = "setup.py" }, { file = "setup.cfg" }]"#,
139 value_type = "list[dict]",
140 example = r#"
141 cache-keys = [{ file = "pyproject.toml" }, { file = "requirements.txt" }, { git = { commit = true } }]
142 "#
143 )]
144 pub cache_keys: Option<Vec<CacheKey>>,
145
146 #[cfg_attr(feature = "schemars", schemars(skip))]
150 pub override_dependencies: Option<Vec<OverrideDependency>>,
151
152 #[cfg_attr(feature = "schemars", schemars(skip))]
153 pub exclude_dependencies: Option<Vec<ExcludeDependency>>,
154
155 #[cfg_attr(feature = "schemars", schemars(skip))]
156 pub constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
157
158 #[cfg_attr(feature = "schemars", schemars(skip))]
159 pub build_constraint_dependencies: Option<Vec<BuildConstraintDependency>>,
160
161 #[cfg_attr(feature = "schemars", schemars(skip))]
162 pub environments: Option<SupportedEnvironments>,
163
164 #[cfg_attr(feature = "schemars", schemars(skip))]
165 pub required_environments: Option<SupportedEnvironments>,
166
167 #[cfg_attr(feature = "schemars", schemars(skip))]
168 pub minimum_libc_version: Option<MinimumLibcVersion>,
169
170 #[cfg_attr(feature = "schemars", schemars(skip))]
174 pub(crate) conflicts: Option<serde::de::IgnoredAny>,
175
176 #[cfg_attr(feature = "schemars", schemars(skip))]
177 pub(crate) workspace: Option<serde::de::IgnoredAny>,
178
179 #[cfg_attr(feature = "schemars", schemars(skip))]
180 pub(crate) sources: Option<serde::de::IgnoredAny>,
181
182 #[cfg_attr(feature = "schemars", schemars(skip))]
183 pub(crate) dev_dependencies: Option<serde::de::IgnoredAny>,
184
185 #[cfg_attr(feature = "schemars", schemars(skip))]
186 pub(crate) default_groups: Option<serde::de::IgnoredAny>,
187
188 #[cfg_attr(feature = "schemars", schemars(skip))]
189 pub(crate) dependency_groups: Option<serde::de::IgnoredAny>,
190
191 #[cfg_attr(feature = "schemars", schemars(skip))]
192 pub(crate) managed: Option<serde::de::IgnoredAny>,
193
194 #[cfg_attr(feature = "schemars", schemars(skip))]
195 pub(crate) r#package: Option<serde::de::IgnoredAny>,
196
197 #[cfg_attr(feature = "schemars", schemars(skip))]
198 pub(crate) build_backend: Option<serde::de::IgnoredAny>,
199}
200
201impl Options {
202 pub fn simple(globals: GlobalOptions, top_level: ResolverInstallerSchema) -> Self {
204 Self {
205 globals,
206 top_level,
207 ..Default::default()
208 }
209 }
210
211 #[must_use]
213 pub(crate) fn with_origin(mut self, origin: Origin) -> Self {
214 if let Some(indexes) = &mut self.top_level.index {
215 for index in indexes {
216 index.origin.get_or_insert(origin);
217 }
218 }
219 if let Some(index_url) = &mut self.top_level.index_url {
220 index_url.try_set_origin(origin);
221 }
222 if let Some(extra_index_urls) = &mut self.top_level.extra_index_url {
223 for index_url in extra_index_urls {
224 index_url.try_set_origin(origin);
225 }
226 }
227 if let Some(pip) = &mut self.pip {
228 if let Some(indexes) = &mut pip.index {
229 for index in indexes {
230 index.origin.get_or_insert(origin);
231 }
232 }
233 if let Some(index_url) = &mut pip.index_url {
234 index_url.try_set_origin(origin);
235 }
236 if let Some(extra_index_urls) = &mut pip.extra_index_url {
237 for index_url in extra_index_urls {
238 index_url.try_set_origin(origin);
239 }
240 }
241 }
242 self
243 }
244
245 pub(crate) fn relative_to(self, root_dir: &Path) -> Result<Self, IndexUrlError> {
247 Ok(Self {
248 top_level: self.top_level.relative_to(root_dir)?,
249 pip: self.pip.map(|pip| pip.relative_to(root_dir)).transpose()?,
250 ..self
251 })
252 }
253}
254
255#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
257#[serde(try_from = "GlobalOptionsWire", rename_all = "kebab-case")]
258#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
259#[cfg_attr(feature = "schemars", schemars(!try_from))]
260pub struct GlobalOptions {
261 #[option(
268 default = "null",
269 value_type = "str",
270 example = r#"
271 required-version = ">=0.5.0"
272 "#
273 )]
274 pub required_version: Option<RequiredVersion>,
275 #[option(
280 default = "false",
281 value_type = "bool",
282 uv_toml_only = true,
283 example = r#"
284 system-certs = true
285 "#
286 )]
287 pub system_certs: Option<bool>,
288 #[deprecated(note = "use `system-certs` instead")]
295 #[option(
296 default = "false",
297 value_type = "bool",
298 uv_toml_only = true,
299 example = r#"
300 native-tls = true
301 "#
302 )]
303 pub native_tls: Option<bool>,
304 #[option(
306 default = "false",
307 value_type = "bool",
308 example = r#"
309 offline = true
310 "#
311 )]
312 pub offline: Option<bool>,
313 #[option(
316 default = "false",
317 value_type = "bool",
318 example = r#"
319 no-cache = true
320 "#
321 )]
322 pub no_cache: Option<bool>,
323 #[option(
328 default = "None",
329 value_type = "str",
330 uv_toml_only = true,
331 example = r#"
332 cache-dir = "./.uv_cache"
333 "#
334 )]
335 pub cache_dir: Option<PathBuf>,
336
337 #[serde(flatten)]
339 pub preview: Option<PreviewOption>,
340
341 #[option(
344 default = "\"managed\"",
345 value_type = "str",
346 example = r#"
347 python-preference = "managed"
348 "#,
349 possible_values = true
350 )]
351 pub python_preference: Option<PythonPreference>,
352 #[option(
354 default = "\"automatic\"",
355 value_type = "str",
356 example = r#"
357 python-downloads = "manual"
358 "#,
359 possible_values = true
360 )]
361 pub python_downloads: Option<PythonDownloads>,
362 #[option(
365 default = "50",
366 value_type = "int",
367 example = r#"
368 concurrent-downloads = 4
369 "#
370 )]
371 pub concurrent_downloads: Option<NonZeroUsize>,
372 #[option(
377 default = "None",
378 value_type = "int",
379 example = r#"
380 concurrent-builds = 4
381 "#
382 )]
383 pub concurrent_builds: Option<NonZeroUsize>,
384 #[option(
388 default = "None",
389 value_type = "int",
390 example = r#"
391 concurrent-installs = 4
392 "#
393 )]
394 pub concurrent_installs: Option<NonZeroUsize>,
395 #[option(
397 default = "None",
398 value_type = "str",
399 uv_toml_only = true,
400 example = r#"
401 http-proxy = "http://proxy.example.com"
402 "#
403 )]
404 pub http_proxy: Option<ProxyUrl>,
405 #[option(
407 default = "None",
408 value_type = "str",
409 uv_toml_only = true,
410 example = r#"
411 https-proxy = "https://proxy.example.com"
412 "#
413 )]
414 pub https_proxy: Option<ProxyUrl>,
415 #[option(
417 default = "None",
418 value_type = "list[str]",
419 uv_toml_only = true,
420 example = r#"
421 no-proxy = ["localhost", "127.0.0.1"]
422 "#
423 )]
424 pub no_proxy: Option<Vec<String>>,
425 #[option(
434 default = "[]",
435 value_type = "list[str]",
436 example = r#"
437 allow-insecure-host = ["localhost:8080"]
438 "#
439 )]
440 pub allow_insecure_host: Option<Vec<TrustedHost>>,
441}
442
443#[derive(Debug, Clone, Default, Deserialize)]
446#[serde(rename_all = "kebab-case")]
447struct GlobalOptionsWire {
448 required_version: Option<RequiredVersion>,
449 system_certs: Option<bool>,
450 native_tls: Option<bool>,
451 offline: Option<bool>,
452 no_cache: Option<bool>,
453 cache_dir: Option<PathBuf>,
454
455 preview: Option<bool>,
456 preview_features: Option<PreviewFeaturesOption>,
457
458 python_preference: Option<PythonPreference>,
459 python_downloads: Option<PythonDownloads>,
460 concurrent_downloads: Option<NonZeroUsize>,
461 concurrent_builds: Option<NonZeroUsize>,
462 concurrent_installs: Option<NonZeroUsize>,
463 http_proxy: Option<ProxyUrl>,
464 https_proxy: Option<ProxyUrl>,
465 no_proxy: Option<Vec<String>>,
466 allow_insecure_host: Option<Vec<TrustedHost>>,
467}
468
469impl TryFrom<GlobalOptionsWire> for GlobalOptions {
470 type Error = &'static str;
471
472 #[allow(deprecated)]
473 fn try_from(value: GlobalOptionsWire) -> Result<Self, Self::Error> {
474 let GlobalOptionsWire {
475 required_version,
476 system_certs,
477 native_tls,
478 offline,
479 no_cache,
480 cache_dir,
481 preview,
482 preview_features,
483 python_preference,
484 python_downloads,
485 concurrent_downloads,
486 concurrent_builds,
487 concurrent_installs,
488 http_proxy,
489 https_proxy,
490 no_proxy,
491 allow_insecure_host,
492 } = value;
493
494 Ok(Self {
495 required_version,
496 system_certs,
497 native_tls,
498 offline,
499 no_cache,
500 cache_dir,
501 preview: PreviewOption::try_from(preview, preview_features)?,
502 python_preference,
503 python_downloads,
504 concurrent_downloads,
505 concurrent_builds,
506 concurrent_installs,
507 http_proxy,
508 https_proxy,
509 no_proxy,
510 allow_insecure_host,
511 })
512 }
513}
514
515fn rebase_indexes(
517 root_dir: &Path,
518 indexes: &mut Option<Vec<Index>>,
519 index_url: &mut Option<PipIndex>,
520 extra_index_urls: &mut Option<Vec<PipExtraIndex>>,
521 find_links: &mut Option<Vec<PipFindLinks>>,
522) -> Result<(), IndexUrlError> {
523 *indexes = indexes
524 .take()
525 .map(|indexes| {
526 indexes
527 .into_iter()
528 .map(|index| index.relative_to(root_dir))
529 .collect::<Result<Vec<_>, _>>()
530 })
531 .transpose()?;
532 *index_url = index_url
533 .take()
534 .map(|index| index.relative_to(root_dir))
535 .transpose()?;
536 *extra_index_urls = extra_index_urls
537 .take()
538 .map(|indexes| {
539 indexes
540 .into_iter()
541 .map(|index| index.relative_to(root_dir))
542 .collect::<Result<Vec<_>, _>>()
543 })
544 .transpose()?;
545 *find_links = find_links
546 .take()
547 .map(|find_links| {
548 find_links
549 .into_iter()
550 .map(|find_link| find_link.relative_to(root_dir))
551 .collect::<Result<Vec<_>, _>>()
552 })
553 .transpose()?;
554
555 Ok(())
556}
557
558#[derive(Debug, Clone, Default, CombineOptions)]
560pub struct InstallerOptions {
561 index: Option<Vec<Index>>,
562 index_url: Option<PipIndex>,
563 extra_index_url: Option<Vec<PipExtraIndex>>,
564 no_index: Option<bool>,
565 find_links: Option<Vec<PipFindLinks>>,
566 index_strategy: Option<IndexStrategy>,
567 keyring_provider: Option<KeyringProviderType>,
568 config_settings: Option<ConfigSettings>,
569 exclude_newer: Option<ExcludeNewerOverride>,
570 link_mode: Option<LinkMode>,
571 compile_bytecode: Option<bool>,
572 reinstall: Option<Reinstall>,
573 build_isolation: Option<BuildIsolation>,
574 no_build: Option<bool>,
575 no_build_package: Option<Vec<PackageName>>,
576 no_binary: Option<bool>,
577 no_binary_package: Option<Vec<PackageName>>,
578 no_sources: Option<bool>,
579 no_sources_package: Option<Vec<PackageName>>,
580}
581
582#[derive(Debug, Clone, Default, CombineOptions)]
584pub struct IndexOptions {
585 pub index: Option<Vec<Index>>,
586 pub index_url: Option<PipIndex>,
587 pub extra_index_url: Option<Vec<PipExtraIndex>>,
588 pub no_index: Option<bool>,
589 pub find_links: Option<Vec<PipFindLinks>>,
590}
591
592impl IndexOptions {
593 pub fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
595 rebase_indexes(
596 root_dir,
597 &mut self.index,
598 &mut self.index_url,
599 &mut self.extra_index_url,
600 &mut self.find_links,
601 )?;
602
603 Ok(self)
604 }
605}
606
607impl From<IndexOptions> for IndexLocations {
608 fn from(value: IndexOptions) -> Self {
609 let IndexOptions {
610 index,
611 index_url,
612 extra_index_url,
613 no_index,
614 find_links,
615 } = value;
616
617 Self::new(
618 index
619 .into_iter()
620 .flatten()
621 .chain(extra_index_url.into_iter().flatten().map(Index::from))
622 .chain(index_url.into_iter().map(Index::from))
623 .collect(),
624 find_links.into_iter().flatten().map(Index::from).collect(),
625 no_index.unwrap_or_default(),
626 )
627 }
628}
629
630impl From<IndexOptions> for PipOptions {
631 fn from(value: IndexOptions) -> Self {
632 let IndexOptions {
633 index,
634 index_url,
635 extra_index_url,
636 no_index,
637 find_links,
638 } = value;
639
640 Self {
641 index,
642 index_url,
643 extra_index_url,
644 no_index,
645 find_links,
646 ..Self::default()
647 }
648 }
649}
650
651#[derive(Debug, Clone, Default, CombineOptions)]
653pub struct ResolverOptions {
654 pub indexes: IndexOptions,
655 pub index_strategy: Option<IndexStrategy>,
656 pub keyring_provider: Option<KeyringProviderType>,
657 pub resolution: Option<ResolutionMode>,
658 pub prerelease: Option<PrereleaseMode>,
659 pub prerelease_package: Option<PrereleasePackage>,
660 pub fork_strategy: Option<ForkStrategy>,
661 pub dependency_metadata: Option<Vec<StaticMetadata>>,
662 pub config_settings: Option<ConfigSettings>,
663 pub config_settings_package: Option<PackageConfigSettings>,
664 pub exclude_newer: Option<ExcludeNewerOverride>,
665 pub exclude_newer_package: Option<ExcludeNewerPackage>,
666 pub link_mode: Option<LinkMode>,
667 pub torch_backend: Option<TorchMode>,
668 pub upgrade: Option<Upgrade>,
669 pub require_build_hashes: Option<bool>,
670 pub build_isolation: Option<BuildIsolation>,
671 pub no_build: Option<bool>,
672 pub no_build_package: Option<Vec<PackageName>>,
673 pub no_binary: Option<bool>,
674 pub no_binary_package: Option<Vec<PackageName>>,
675 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
676 pub extra_build_variables: Option<ExtraBuildVariables>,
677 pub no_sources: Option<bool>,
678 pub no_sources_package: Option<Vec<PackageName>>,
679}
680
681impl ResolverOptions {
682 pub fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
684 self.indexes = self.indexes.relative_to(root_dir)?;
685 Ok(self)
686 }
687}
688
689#[derive(Debug, Clone, Default, CombineOptions)]
692pub struct ResolverInstallerOptions {
693 pub indexes: IndexOptions,
694 pub index_strategy: Option<IndexStrategy>,
695 pub keyring_provider: Option<KeyringProviderType>,
696 pub resolution: Option<ResolutionMode>,
697 pub prerelease: Option<PrereleaseMode>,
698 pub prerelease_package: Option<PrereleasePackage>,
699 pub fork_strategy: Option<ForkStrategy>,
700 pub dependency_metadata: Option<Vec<StaticMetadata>>,
701 pub config_settings: Option<ConfigSettings>,
702 pub config_settings_package: Option<PackageConfigSettings>,
703 pub require_build_hashes: Option<bool>,
704 pub build_isolation: Option<BuildIsolation>,
705 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
706 pub extra_build_variables: Option<ExtraBuildVariables>,
707 pub exclude_newer: Option<ExcludeNewerOverride>,
708 pub exclude_newer_package: Option<ExcludeNewerPackage>,
709 pub link_mode: Option<LinkMode>,
710 pub torch_backend: Option<TorchMode>,
711 pub compile_bytecode: Option<bool>,
712 pub no_sources: Option<bool>,
713 pub no_sources_package: Option<Vec<PackageName>>,
714 pub upgrade: Option<Upgrade>,
715 pub reinstall: Option<Reinstall>,
716 pub no_build: Option<bool>,
717 pub no_build_package: Option<Vec<PackageName>>,
718 pub no_binary: Option<bool>,
719 pub no_binary_package: Option<Vec<PackageName>>,
720}
721
722impl ResolverInstallerOptions {
723 pub fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
725 self.indexes = self.indexes.relative_to(root_dir)?;
726 Ok(self)
727 }
728}
729
730impl From<ResolverInstallerSchema> for ResolverInstallerOptions {
731 fn from(value: ResolverInstallerSchema) -> Self {
732 let ResolverInstallerSchema {
733 index,
734 index_url,
735 extra_index_url,
736 no_index,
737 find_links,
738 index_strategy,
739 keyring_provider,
740 resolution,
741 prerelease,
742 prerelease_package,
743 fork_strategy,
744 dependency_metadata,
745 config_settings,
746 config_settings_package,
747 require_build_hashes,
748 no_build_isolation,
749 no_build_isolation_package,
750 extra_build_dependencies,
751 extra_build_variables,
752 exclude_newer,
753 exclude_newer_package,
754 link_mode,
755 torch_backend,
756 compile_bytecode,
757 no_sources,
758 no_sources_package,
759 upgrade,
760 upgrade_package,
761 reinstall,
762 reinstall_package,
763 no_build,
764 no_build_package,
765 no_binary,
766 no_binary_package,
767 } = value;
768 Self {
769 indexes: IndexOptions {
770 index,
771 index_url,
772 extra_index_url,
773 no_index,
774 find_links,
775 },
776 index_strategy,
777 keyring_provider,
778 resolution,
779 prerelease,
780 prerelease_package,
781 fork_strategy,
782 dependency_metadata,
783 config_settings,
784 config_settings_package,
785 require_build_hashes,
786 build_isolation: BuildIsolation::from_args(
787 no_build_isolation,
788 no_build_isolation_package.into_iter().flatten().collect(),
789 ),
790 extra_build_dependencies,
791 extra_build_variables,
792 exclude_newer,
793 exclude_newer_package,
794 link_mode,
795 torch_backend,
796 compile_bytecode,
797 no_sources,
798 no_sources_package,
799 upgrade: Upgrade::from_args(
800 upgrade,
801 upgrade_package
802 .into_iter()
803 .flatten()
804 .map(Into::into)
805 .collect(),
806 Vec::new(),
807 ),
808 reinstall: Reinstall::from_args(reinstall, reinstall_package.unwrap_or_default()),
809 no_build,
810 no_build_package,
811 no_binary,
812 no_binary_package,
813 }
814 }
815}
816
817impl ResolverInstallerSchema {
818 fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
820 rebase_indexes(
821 root_dir,
822 &mut self.index,
823 &mut self.index_url,
824 &mut self.extra_index_url,
825 &mut self.find_links,
826 )?;
827
828 Ok(self)
829 }
830}
831
832#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
834#[serde(rename_all = "kebab-case")]
835#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
836pub struct ResolverInstallerSchema {
837 #[option(
865 default = "\"[]\"",
866 value_type = "dict",
867 example = r#"
868 [[tool.uv.index]]
869 name = "pytorch"
870 url = "https://download.pytorch.org/whl/cu130"
871 "#
872 )]
873 pub index: Option<Vec<Index>>,
874 #[option(
884 default = "\"https://pypi.org/simple\"",
885 value_type = "str",
886 example = r#"
887 index-url = "https://test.pypi.org/simple"
888 "#
889 )]
890 pub index_url: Option<PipIndex>,
891 #[option(
905 default = "[]",
906 value_type = "list[str]",
907 example = r#"
908 extra-index-url = ["https://download.pytorch.org/whl/cpu"]
909 "#
910 )]
911 pub extra_index_url: Option<Vec<PipExtraIndex>>,
912 #[option(
915 default = "false",
916 value_type = "bool",
917 example = r#"
918 no-index = true
919 "#
920 )]
921 pub no_index: Option<bool>,
922 #[option(
931 default = "[]",
932 value_type = "list[str]",
933 example = r#"
934 find-links = ["https://download.pytorch.org/whl/torch_stable.html"]
935 "#
936 )]
937 pub find_links: Option<Vec<PipFindLinks>>,
938 #[option(
945 default = "\"first-index\"",
946 value_type = "str",
947 example = r#"
948 index-strategy = "unsafe-best-match"
949 "#,
950 possible_values = true
951 )]
952 pub index_strategy: Option<IndexStrategy>,
953 #[option(
958 default = "\"disabled\"",
959 value_type = "str",
960 example = r#"
961 keyring-provider = "subprocess"
962 "#
963 )]
964 pub keyring_provider: Option<KeyringProviderType>,
965 #[option(
970 default = "\"highest\"",
971 value_type = "str",
972 example = r#"
973 resolution = "lowest-direct"
974 "#,
975 possible_values = true
976 )]
977 pub resolution: Option<ResolutionMode>,
978 #[option(
984 default = "\"if-necessary\"",
985 value_type = "str",
986 example = r#"
987 prerelease = "allow"
988 "#,
989 possible_values = true
990 )]
991 pub prerelease: Option<PrereleaseMode>,
992 #[option(
997 default = "{}",
998 value_type = "dict",
999 example = r#"
1000 prerelease-package = { numpy = "allow", scipy = "disallow" }
1001 "#
1002 )]
1003 pub prerelease_package: Option<PrereleasePackage>,
1004 #[option(
1015 default = "\"requires-python\"",
1016 value_type = "str",
1017 example = r#"
1018 fork-strategy = "fewest"
1019 "#,
1020 possible_values = true
1021 )]
1022 pub fork_strategy: Option<ForkStrategy>,
1023 #[option(
1037 default = r#"[]"#,
1038 value_type = "list[dict]",
1039 example = r#"
1040 dependency-metadata = [
1041 { name = "flask", version = "1.0.0", requires-dist = ["werkzeug"], requires-python = ">=3.6" },
1042 ]
1043 "#
1044 )]
1045 pub dependency_metadata: Option<Vec<StaticMetadata>>,
1046 #[option(
1049 default = "{}",
1050 value_type = "dict",
1051 example = r#"
1052 config-settings = { editable_mode = "compat" }
1053 "#
1054 )]
1055 pub config_settings: Option<ConfigSettings>,
1056 #[option(
1061 default = "{}",
1062 value_type = "dict",
1063 example = r#"
1064 config-settings-package = { numpy = { editable_mode = "compat" } }
1065 "#
1066 )]
1067 pub config_settings_package: Option<PackageConfigSettings>,
1068 #[option(
1073 default = "false",
1074 value_type = "bool",
1075 example = r#"
1076 no-build-isolation = true
1077 "#
1078 )]
1079 pub no_build_isolation: Option<bool>,
1080
1081 #[option(
1094 default = "false",
1095 value_type = "bool",
1096 example = "require-build-hashes = true"
1097 )]
1098 pub require_build_hashes: Option<bool>,
1099
1100 #[option(
1105 default = "[]",
1106 value_type = "list[str]",
1107 example = r#"
1108 no-build-isolation-package = ["package1", "package2"]
1109 "#
1110 )]
1111 pub no_build_isolation_package: Option<Vec<PackageName>>,
1112 #[option(
1118 default = "[]",
1119 value_type = "dict",
1120 example = r#"
1121 extra-build-dependencies = { pytest = ["setuptools"] }
1122 "#
1123 )]
1124 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
1125 #[option(
1130 default = r#"{}"#,
1131 value_type = r#"dict[str, dict[str, str]]"#,
1132 example = r#"
1133 extra-build-variables = { flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" } }
1134 "#
1135 )]
1136 pub extra_build_variables: Option<ExtraBuildVariables>,
1137 #[option(
1152 default = "None",
1153 value_type = "str | false",
1154 example = r#"
1155 exclude-newer = "2006-12-02T02:07:43Z"
1156 "#
1157 )]
1158 pub exclude_newer: Option<ExcludeNewerOverride>,
1159 #[option(
1173 default = "None",
1174 value_type = "dict",
1175 example = r#"
1176 exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z", markupsafe = false }
1177 "#
1178 )]
1179 pub exclude_newer_package: Option<ExcludeNewerPackage>,
1180 #[option(
1190 default = "\"clone\" (macOS, Linux) or \"hardlink\" (Windows)",
1191 value_type = "str",
1192 example = r#"
1193 link-mode = "copy"
1194 "#,
1195 possible_values = true
1196 )]
1197 pub link_mode: Option<LinkMode>,
1198 #[option(
1209 default = "false",
1210 value_type = "bool",
1211 example = r#"
1212 compile-bytecode = true
1213 "#
1214 )]
1215 pub compile_bytecode: Option<bool>,
1216 #[option(
1220 default = "false",
1221 value_type = "bool",
1222 example = r#"
1223 no-sources = true
1224 "#
1225 )]
1226 pub no_sources: Option<bool>,
1227 #[option(
1229 default = "[]",
1230 value_type = "list[str]",
1231 example = r#"
1232 no-sources-package = ["ruff"]
1233 "#
1234 )]
1235 pub no_sources_package: Option<Vec<PackageName>>,
1236 #[option(
1238 default = "false",
1239 value_type = "bool",
1240 example = r#"
1241 upgrade = true
1242 "#
1243 )]
1244 pub upgrade: Option<bool>,
1245 #[option(
1250 default = "[]",
1251 value_type = "list[str]",
1252 example = r#"
1253 upgrade-package = ["ruff"]
1254 "#
1255 )]
1256 pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
1257 #[option(
1259 default = "false",
1260 value_type = "bool",
1261 example = r#"
1262 reinstall = true
1263 "#
1264 )]
1265 pub reinstall: Option<bool>,
1266 #[option(
1269 default = "[]",
1270 value_type = "list[str]",
1271 example = r#"
1272 reinstall-package = ["ruff"]
1273 "#
1274 )]
1275 pub reinstall_package: Option<Vec<PackageName>>,
1276 #[option(
1283 default = "false",
1284 value_type = "bool",
1285 example = r#"
1286 no-build = true
1287 "#
1288 )]
1289 pub no_build: Option<bool>,
1290 #[option(
1294 default = "[]",
1295 value_type = "list[str]",
1296 example = r#"
1297 no-build-package = ["ruff"]
1298 "#
1299 )]
1300 pub no_build_package: Option<Vec<PackageName>>,
1301 #[option(
1306 default = "false",
1307 value_type = "bool",
1308 example = r#"
1309 no-binary = true
1310 "#
1311 )]
1312 pub no_binary: Option<bool>,
1313 #[option(
1315 default = "[]",
1316 value_type = "list[str]",
1317 example = r#"
1318 no-binary-package = ["ruff"]
1319 "#
1320 )]
1321 pub no_binary_package: Option<Vec<PackageName>>,
1322 #[option(
1337 default = "null",
1338 value_type = "str",
1339 example = r#"
1340 torch-backend = "auto"
1341 "#
1342 )]
1343 pub torch_backend: Option<TorchMode>,
1344}
1345
1346#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
1348#[serde(rename_all = "kebab-case")]
1349#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1350pub struct PythonInstallMirrors {
1351 #[option(
1359 default = "None",
1360 value_type = "str",
1361 uv_toml_only = true,
1362 example = r#"
1363 python-install-mirror = "https://github.com/astral-sh/python-build-standalone/releases/download"
1364 "#
1365 )]
1366 pub python_install_mirror: Option<String>,
1367 #[option(
1376 default = "None",
1377 value_type = "str",
1378 uv_toml_only = true,
1379 example = r#"
1380 pypy-install-mirror = "https://downloads.python.org/pypy"
1381 "#
1382 )]
1383 pub pypy_install_mirror: Option<String>,
1384 #[option(
1392 default = "None",
1393 value_type = "str",
1394 uv_toml_only = true,
1395 example = r#"
1396 graalpy-install-mirror = "https://github.com/oracle/graalpython/releases/download"
1397 "#
1398 )]
1399 pub graalpy_install_mirror: Option<String>,
1400 #[option(
1408 default = "None",
1409 value_type = "str",
1410 uv_toml_only = true,
1411 example = r#"
1412 pyodide-install-mirror = "https://github.com/pyodide/pyodide/releases/download"
1413 "#
1414 )]
1415 pub pyodide_install_mirror: Option<String>,
1416
1417 #[option(
1419 default = "None",
1420 value_type = "str",
1421 uv_toml_only = true,
1422 example = r#"
1423 python-downloads-json-url = "/etc/uv/python-downloads.json"
1424 "#
1425 )]
1426 pub python_downloads_json_url: Option<String>,
1427}
1428
1429impl PythonInstallMirrors {
1430 pub fn mirrors(&self) -> PythonDownloadMirrors<'_> {
1432 PythonDownloadMirrors {
1433 cpython: self.python_install_mirror.as_deref(),
1434 pypy: self.pypy_install_mirror.as_deref(),
1435 graalpy: self.graalpy_install_mirror.as_deref(),
1436 pyodide: self.pyodide_install_mirror.as_deref(),
1437 }
1438 }
1439
1440 #[must_use]
1441 pub fn combine(self, other: Self) -> Self {
1442 Self {
1443 python_install_mirror: self.python_install_mirror.or(other.python_install_mirror),
1444 pypy_install_mirror: self.pypy_install_mirror.or(other.pypy_install_mirror),
1445 graalpy_install_mirror: self.graalpy_install_mirror.or(other.graalpy_install_mirror),
1446 pyodide_install_mirror: self.pyodide_install_mirror.or(other.pyodide_install_mirror),
1447 python_downloads_json_url: self
1448 .python_downloads_json_url
1449 .or(other.python_downloads_json_url),
1450 }
1451 }
1452}
1453
1454#[derive(Debug, Clone, Default, Deserialize, CombineOptions, OptionsMetadata)]
1459#[serde(deny_unknown_fields, rename_all = "kebab-case")]
1460#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
1461pub struct PipOptions {
1462 #[option(
1475 default = "None",
1476 value_type = "str",
1477 example = r#"
1478 python = "3.10"
1479 "#
1480 )]
1481 pub python: Option<String>,
1482 #[option(
1491 default = "false",
1492 value_type = "bool",
1493 example = r#"
1494 system = true
1495 "#
1496 )]
1497 pub system: Option<bool>,
1498 #[option(
1505 default = "false",
1506 value_type = "bool",
1507 example = r#"
1508 break-system-packages = true
1509 "#
1510 )]
1511 pub break_system_packages: Option<bool>,
1512 #[option(
1515 default = "None",
1516 value_type = "str",
1517 example = r#"
1518 target = "./target"
1519 "#
1520 )]
1521 pub target: Option<PathBuf>,
1522 #[option(
1530 default = "None",
1531 value_type = "str",
1532 example = r#"
1533 prefix = "./prefix"
1534 "#
1535 )]
1536 pub prefix: Option<PathBuf>,
1537 #[serde(skip)]
1538 #[cfg_attr(feature = "schemars", schemars(skip))]
1539 pub index: Option<Vec<Index>>,
1540 #[option(
1548 default = "\"https://pypi.org/simple\"",
1549 value_type = "str",
1550 example = r#"
1551 index-url = "https://test.pypi.org/simple"
1552 "#
1553 )]
1554 pub index_url: Option<PipIndex>,
1555 #[option(
1566 default = "[]",
1567 value_type = "list[str]",
1568 example = r#"
1569 extra-index-url = ["https://download.pytorch.org/whl/cpu"]
1570 "#
1571 )]
1572 pub extra_index_url: Option<Vec<PipExtraIndex>>,
1573 #[option(
1576 default = "false",
1577 value_type = "bool",
1578 example = r#"
1579 no-index = true
1580 "#
1581 )]
1582 pub no_index: Option<bool>,
1583 #[option(
1592 default = "[]",
1593 value_type = "list[str]",
1594 example = r#"
1595 find-links = ["https://download.pytorch.org/whl/torch_stable.html"]
1596 "#
1597 )]
1598 pub find_links: Option<Vec<PipFindLinks>>,
1599 #[option(
1606 default = "\"first-index\"",
1607 value_type = "str",
1608 example = r#"
1609 index-strategy = "unsafe-best-match"
1610 "#,
1611 possible_values = true
1612 )]
1613 pub index_strategy: Option<IndexStrategy>,
1614 #[option(
1619 default = "disabled",
1620 value_type = "str",
1621 example = r#"
1622 keyring-provider = "subprocess"
1623 "#
1624 )]
1625 pub keyring_provider: Option<KeyringProviderType>,
1626 #[option(
1634 default = "false",
1635 value_type = "bool",
1636 example = r#"
1637 no-build = true
1638 "#
1639 )]
1640 pub no_build: Option<bool>,
1641 #[option(
1649 default = "[]",
1650 value_type = "list[str]",
1651 example = r#"
1652 no-binary = ["ruff"]
1653 "#
1654 )]
1655 pub no_binary: Option<Vec<PackageNameSpecifier>>,
1656 #[option(
1666 default = "[]",
1667 value_type = "list[str]",
1668 example = r#"
1669 only-binary = ["ruff"]
1670 "#
1671 )]
1672 pub only_binary: Option<Vec<PackageNameSpecifier>>,
1673 #[option(
1678 default = "false",
1679 value_type = "bool",
1680 example = r#"
1681 no-build-isolation = true
1682 "#
1683 )]
1684 pub no_build_isolation: Option<bool>,
1685 #[option(
1690 default = "false",
1691 value_type = "bool",
1692 example = r#"
1693 require-build-hashes = true
1694 "#
1695 )]
1696 pub require_build_hashes: Option<bool>,
1697 #[option(
1702 default = "[]",
1703 value_type = "list[str]",
1704 example = r#"
1705 no-build-isolation-package = ["package1", "package2"]
1706 "#
1707 )]
1708 pub no_build_isolation_package: Option<Vec<PackageName>>,
1709 #[option(
1715 default = "[]",
1716 value_type = "dict",
1717 example = r#"
1718 extra-build-dependencies = { pytest = ["setuptools"] }
1719 "#
1720 )]
1721 pub extra_build_dependencies: Option<ExtraBuildDependencies>,
1722 #[option(
1727 default = r#"{}"#,
1728 value_type = r#"dict[str, dict[str, str]]"#,
1729 example = r#"
1730 extra-build-variables = { flash-attn = { FLASH_ATTENTION_SKIP_CUDA_BUILD = "TRUE" } }
1731 "#
1732 )]
1733 pub extra_build_variables: Option<ExtraBuildVariables>,
1734 #[option(
1737 default = "false",
1738 value_type = "bool",
1739 example = r#"
1740 strict = true
1741 "#
1742 )]
1743 pub strict: Option<bool>,
1744 #[option(
1748 default = "[]",
1749 value_type = "list[str]",
1750 example = r#"
1751 extra = ["dev", "docs"]
1752 "#
1753 )]
1754 pub extra: Option<Vec<ExtraName>>,
1755 #[option(
1759 default = "false",
1760 value_type = "bool",
1761 example = r#"
1762 all-extras = true
1763 "#
1764 )]
1765 pub all_extras: Option<bool>,
1766 #[option(
1768 default = "[]",
1769 value_type = "list[str]",
1770 example = r#"
1771 all-extras = true
1772 no-extra = ["dev", "docs"]
1773 "#
1774 )]
1775 pub no_extra: Option<Vec<ExtraName>>,
1776 #[option(
1779 default = "false",
1780 value_type = "bool",
1781 example = r#"
1782 no-deps = true
1783 "#
1784 )]
1785 pub no_deps: Option<bool>,
1786 #[option(
1788 default = "None",
1789 value_type = "list[str]",
1790 example = r#"
1791 group = ["dev", "docs"]
1792 "#
1793 )]
1794 pub group: Option<Vec<PipGroupName>>,
1795 #[option(
1798 default = "false",
1799 value_type = "bool",
1800 example = r#"
1801 allow-empty-requirements = true
1802 "#
1803 )]
1804 pub allow_empty_requirements: Option<bool>,
1805 #[option(
1810 default = "\"highest\"",
1811 value_type = "str",
1812 example = r#"
1813 resolution = "lowest-direct"
1814 "#,
1815 possible_values = true
1816 )]
1817 pub resolution: Option<ResolutionMode>,
1818 #[option(
1824 default = "\"if-necessary\"",
1825 value_type = "str",
1826 example = r#"
1827 prerelease = "allow"
1828 "#,
1829 possible_values = true
1830 )]
1831 pub prerelease: Option<PrereleaseMode>,
1832 #[serde(skip)]
1833 #[cfg_attr(feature = "schemars", schemars(skip))]
1834 pub prerelease_package: Option<PrereleasePackage>,
1835 #[option(
1846 default = "\"requires-python\"",
1847 value_type = "str",
1848 example = r#"
1849 fork-strategy = "fewest"
1850 "#,
1851 possible_values = true
1852 )]
1853 pub fork_strategy: Option<ForkStrategy>,
1854 #[option(
1868 default = r#"[]"#,
1869 value_type = "list[dict]",
1870 example = r#"
1871 dependency-metadata = [
1872 { name = "flask", version = "1.0.0", requires-dist = ["werkzeug"], requires-python = ">=3.6" },
1873 ]
1874 "#
1875 )]
1876 pub dependency_metadata: Option<Vec<StaticMetadata>>,
1877 #[option(
1882 default = "None",
1883 value_type = "str",
1884 example = r#"
1885 output-file = "requirements.txt"
1886 "#
1887 )]
1888 pub output_file: Option<PathBuf>,
1889 #[option(
1895 default = "false",
1896 value_type = "bool",
1897 example = r#"
1898 no-strip-extras = true
1899 "#
1900 )]
1901 pub no_strip_extras: Option<bool>,
1902 #[option(
1907 default = "false",
1908 value_type = "bool",
1909 example = r#"
1910 no-strip-markers = true
1911 "#
1912 )]
1913 pub no_strip_markers: Option<bool>,
1914 #[option(
1917 default = "false",
1918 value_type = "bool",
1919 example = r#"
1920 no-annotate = true
1921 "#
1922 )]
1923 pub no_annotate: Option<bool>,
1924 #[option(
1926 default = r#"false"#,
1927 value_type = "bool",
1928 example = r#"
1929 no-header = true
1930 "#
1931 )]
1932 pub no_header: Option<bool>,
1933 #[option(
1937 default = "None",
1938 value_type = "str",
1939 example = r#"
1940 custom-compile-command = "./custom-uv-compile.sh"
1941 "#
1942 )]
1943 pub custom_compile_command: Option<String>,
1944 #[option(
1946 default = "false",
1947 value_type = "bool",
1948 example = r#"
1949 generate-hashes = true
1950 "#
1951 )]
1952 pub generate_hashes: Option<bool>,
1953 #[option(
1956 default = "{}",
1957 value_type = "dict",
1958 example = r#"
1959 config-settings = { editable_mode = "compat" }
1960 "#
1961 )]
1962 pub config_settings: Option<ConfigSettings>,
1963 #[option(
1966 default = "{}",
1967 value_type = "dict",
1968 example = r#"
1969 config-settings-package = { numpy = { editable_mode = "compat" } }
1970 "#
1971 )]
1972 pub config_settings_package: Option<PackageConfigSettings>,
1973 #[option(
1979 default = "None",
1980 value_type = "str",
1981 example = r#"
1982 python-version = "3.8"
1983 "#
1984 )]
1985 pub python_version: Option<PythonVersion>,
1986 #[option(
1992 default = "None",
1993 value_type = "str",
1994 example = r#"
1995 python-platform = "x86_64-unknown-linux-gnu"
1996 "#
1997 )]
1998 pub python_platform: Option<TargetTriple>,
1999 #[option(
2007 default = "false",
2008 value_type = "bool",
2009 example = r#"
2010 universal = true
2011 "#
2012 )]
2013 pub universal: Option<bool>,
2014 #[option(
2029 default = "None",
2030 value_type = "str | false",
2031 example = r#"
2032 exclude-newer = "2006-12-02T02:07:43Z"
2033 "#
2034 )]
2035 pub exclude_newer: Option<ExcludeNewerOverride>,
2036 #[option(
2049 default = "None",
2050 value_type = "dict",
2051 example = r#"
2052 exclude-newer-package = { tqdm = "2022-04-04T00:00:00Z", markupsafe = false }
2053 "#
2054 )]
2055 pub exclude_newer_package: Option<ExcludeNewerPackage>,
2056 #[option(
2059 default = "[]",
2060 value_type = "list[str]",
2061 example = r#"
2062 no-emit-package = ["ruff"]
2063 "#
2064 )]
2065 pub no_emit_package: Option<Vec<PackageName>>,
2066 #[option(
2068 default = "false",
2069 value_type = "bool",
2070 example = r#"
2071 emit-index-url = true
2072 "#
2073 )]
2074 pub emit_index_url: Option<bool>,
2075 #[option(
2077 default = "false",
2078 value_type = "bool",
2079 example = r#"
2080 emit-find-links = true
2081 "#
2082 )]
2083 pub emit_find_links: Option<bool>,
2084 #[option(
2086 default = "false",
2087 value_type = "bool",
2088 example = r#"
2089 emit-build-options = true
2090 "#
2091 )]
2092 pub emit_build_options: Option<bool>,
2093 #[option(
2100 default = "false",
2101 value_type = "bool",
2102 example = r#"
2103 emit-marker-expression = true
2104 "#
2105 )]
2106 pub emit_marker_expression: Option<bool>,
2107 #[option(
2110 default = "false",
2111 value_type = "bool",
2112 example = r#"
2113 emit-index-annotation = true
2114 "#
2115 )]
2116 pub emit_index_annotation: Option<bool>,
2117 #[option(
2120 default = "\"split\"",
2121 value_type = "str",
2122 example = r#"
2123 annotation-style = "line"
2124 "#,
2125 possible_values = true
2126 )]
2127 pub annotation_style: Option<AnnotationStyle>,
2128 #[option(
2138 default = "\"clone\" (macOS, Linux) or \"hardlink\" (Windows)",
2139 value_type = "str",
2140 example = r#"
2141 link-mode = "copy"
2142 "#,
2143 possible_values = true
2144 )]
2145 pub link_mode: Option<LinkMode>,
2146 #[option(
2157 default = "false",
2158 value_type = "bool",
2159 example = r#"
2160 compile-bytecode = true
2161 "#
2162 )]
2163 pub compile_bytecode: Option<bool>,
2164 #[option(
2177 default = "false",
2178 value_type = "bool",
2179 example = r#"
2180 require-hashes = true
2181 "#
2182 )]
2183 pub require_hashes: Option<bool>,
2184 #[option(
2190 default = "true",
2191 value_type = "bool",
2192 example = r#"
2193 verify-hashes = true
2194 "#
2195 )]
2196 pub verify_hashes: Option<bool>,
2197 #[option(
2201 default = "false",
2202 value_type = "bool",
2203 example = r#"
2204 no-sources = true
2205 "#
2206 )]
2207 pub no_sources: Option<bool>,
2208 #[option(
2210 default = "[]",
2211 value_type = "list[str]",
2212 example = r#"
2213 no-sources-package = ["ruff"]
2214 "#
2215 )]
2216 pub no_sources_package: Option<Vec<PackageName>>,
2217 #[option(
2219 default = "false",
2220 value_type = "bool",
2221 example = r#"
2222 upgrade = true
2223 "#
2224 )]
2225 pub upgrade: Option<bool>,
2226 #[option(
2231 default = "[]",
2232 value_type = "list[str]",
2233 example = r#"
2234 upgrade-package = ["ruff"]
2235 "#
2236 )]
2237 pub upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2238 #[option(
2240 default = "false",
2241 value_type = "bool",
2242 example = r#"
2243 reinstall = true
2244 "#
2245 )]
2246 pub reinstall: Option<bool>,
2247 #[option(
2250 default = "[]",
2251 value_type = "list[str]",
2252 example = r#"
2253 reinstall-package = ["ruff"]
2254 "#
2255 )]
2256 pub reinstall_package: Option<Vec<PackageName>>,
2257 #[option(
2272 default = "null",
2273 value_type = "str",
2274 example = r#"
2275 torch-backend = "auto"
2276 "#
2277 )]
2278 pub torch_backend: Option<TorchMode>,
2279}
2280
2281impl PipOptions {
2282 fn relative_to(mut self, root_dir: &Path) -> Result<Self, IndexUrlError> {
2284 rebase_indexes(
2285 root_dir,
2286 &mut self.index,
2287 &mut self.index_url,
2288 &mut self.extra_index_url,
2289 &mut self.find_links,
2290 )?;
2291
2292 Ok(self)
2293 }
2294}
2295
2296impl From<ResolverInstallerSchema> for ResolverOptions {
2297 fn from(value: ResolverInstallerSchema) -> Self {
2298 Self {
2299 indexes: IndexOptions {
2300 index: value.index,
2301 index_url: value.index_url,
2302 extra_index_url: value.extra_index_url,
2303 no_index: value.no_index,
2304 find_links: value.find_links,
2305 },
2306 index_strategy: value.index_strategy,
2307 keyring_provider: value.keyring_provider,
2308 resolution: value.resolution,
2309 prerelease: value.prerelease,
2310 prerelease_package: value.prerelease_package,
2311 fork_strategy: value.fork_strategy,
2312 dependency_metadata: value.dependency_metadata,
2313 config_settings: value.config_settings,
2314 config_settings_package: value.config_settings_package,
2315 require_build_hashes: value.require_build_hashes,
2316 exclude_newer: value.exclude_newer,
2317 exclude_newer_package: value.exclude_newer_package,
2318 link_mode: value.link_mode,
2319 upgrade: Upgrade::from_args(
2320 value.upgrade,
2321 value
2322 .upgrade_package
2323 .into_iter()
2324 .flatten()
2325 .map(Into::into)
2326 .collect(),
2327 Vec::new(),
2328 ),
2329 no_build: value.no_build,
2330 no_build_package: value.no_build_package,
2331 no_binary: value.no_binary,
2332 no_binary_package: value.no_binary_package,
2333 build_isolation: BuildIsolation::from_args(
2334 value.no_build_isolation,
2335 value.no_build_isolation_package.unwrap_or_default(),
2336 ),
2337 extra_build_dependencies: value.extra_build_dependencies,
2338 extra_build_variables: value.extra_build_variables,
2339 no_sources: value.no_sources,
2340 no_sources_package: value.no_sources_package,
2341 torch_backend: value.torch_backend,
2342 }
2343 }
2344}
2345
2346impl From<ResolverInstallerSchema> for InstallerOptions {
2347 fn from(value: ResolverInstallerSchema) -> Self {
2348 Self {
2349 index: value.index,
2350 index_url: value.index_url,
2351 extra_index_url: value.extra_index_url,
2352 no_index: value.no_index,
2353 find_links: value.find_links,
2354 index_strategy: value.index_strategy,
2355 keyring_provider: value.keyring_provider,
2356 config_settings: value.config_settings,
2357 exclude_newer: value.exclude_newer,
2358 link_mode: value.link_mode,
2359 compile_bytecode: value.compile_bytecode,
2360 reinstall: Reinstall::from_args(
2361 value.reinstall,
2362 value.reinstall_package.unwrap_or_default(),
2363 ),
2364 build_isolation: BuildIsolation::from_args(
2365 value.no_build_isolation,
2366 value.no_build_isolation_package.unwrap_or_default(),
2367 ),
2368 no_build: value.no_build,
2369 no_build_package: value.no_build_package,
2370 no_binary: value.no_binary,
2371 no_binary_package: value.no_binary_package,
2372 no_sources: value.no_sources,
2373 no_sources_package: value.no_sources_package,
2374 }
2375 }
2376}
2377
2378#[derive(
2383 Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize, CombineOptions, OptionsMetadata,
2384)]
2385#[serde(deny_unknown_fields, rename_all = "kebab-case")]
2386#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2387pub struct ToolOptions {
2388 index: Option<Vec<Index>>,
2389 index_url: Option<PipIndex>,
2390 extra_index_url: Option<Vec<PipExtraIndex>>,
2391 no_index: Option<bool>,
2392 find_links: Option<Vec<PipFindLinks>>,
2393 index_strategy: Option<IndexStrategy>,
2394 keyring_provider: Option<KeyringProviderType>,
2395 resolution: Option<ResolutionMode>,
2396 prerelease: Option<PrereleaseMode>,
2397 prerelease_package: Option<PrereleasePackage>,
2398 fork_strategy: Option<ForkStrategy>,
2399 dependency_metadata: Option<Vec<StaticMetadata>>,
2400 config_settings: Option<ConfigSettings>,
2401 config_settings_package: Option<PackageConfigSettings>,
2402 build_isolation: Option<BuildIsolation>,
2403 require_build_hashes: Option<bool>,
2404 extra_build_dependencies: Option<ExtraBuildDependencies>,
2405 extra_build_variables: Option<ExtraBuildVariables>,
2406 exclude_newer: Option<ExcludeNewerOverride>,
2407 exclude_newer_package: Option<ExcludeNewerPackage>,
2408 link_mode: Option<LinkMode>,
2409 compile_bytecode: Option<bool>,
2410 no_sources: Option<bool>,
2411 no_sources_package: Option<Vec<PackageName>>,
2412 no_build: Option<bool>,
2413 no_build_package: Option<Vec<PackageName>>,
2414 no_binary: Option<bool>,
2415 no_binary_package: Option<Vec<PackageName>>,
2416 torch_backend: Option<TorchMode>,
2417}
2418
2419#[derive(Debug, Clone, Default, Serialize, Deserialize)]
2421#[serde(deny_unknown_fields, rename_all = "kebab-case")]
2422pub struct ToolOptionsWire {
2423 index: Option<Vec<Index>>,
2424 index_url: Option<PipIndex>,
2425 extra_index_url: Option<Vec<PipExtraIndex>>,
2426 no_index: Option<bool>,
2427 find_links: Option<Vec<PipFindLinks>>,
2428 index_strategy: Option<IndexStrategy>,
2429 keyring_provider: Option<KeyringProviderType>,
2430 resolution: Option<ResolutionMode>,
2431 prerelease: Option<PrereleaseMode>,
2432 prerelease_package: Option<PrereleasePackage>,
2433 fork_strategy: Option<ForkStrategy>,
2434 dependency_metadata: Option<Vec<StaticMetadata>>,
2435 config_settings: Option<ConfigSettings>,
2436 config_settings_package: Option<PackageConfigSettings>,
2437 build_isolation: Option<BuildIsolation>,
2438 require_build_hashes: Option<bool>,
2439 extra_build_dependencies: Option<ExtraBuildDependencies>,
2440 extra_build_variables: Option<ExtraBuildVariables>,
2441 exclude_newer: Option<ExcludeNewerOverride>,
2442 exclude_newer_span: Option<ExcludeNewerSpan>,
2443 #[serde(serialize_with = "serialize_exclude_newer_package_with_spans")]
2444 exclude_newer_package: Option<ExcludeNewerPackage>,
2445 link_mode: Option<LinkMode>,
2446 compile_bytecode: Option<bool>,
2447 no_sources: Option<bool>,
2448 no_sources_package: Option<Vec<PackageName>>,
2449 no_build: Option<bool>,
2450 no_build_package: Option<Vec<PackageName>>,
2451 no_binary: Option<bool>,
2452 no_binary_package: Option<Vec<PackageName>>,
2453 torch_backend: Option<TorchMode>,
2454}
2455
2456impl From<ResolverInstallerOptions> for ToolOptions {
2457 fn from(value: ResolverInstallerOptions) -> Self {
2458 Self {
2459 index: value.indexes.index.map(|indexes| {
2460 indexes
2461 .into_iter()
2462 .map(Index::with_promoted_auth_policy)
2463 .collect()
2464 }),
2465 index_url: value.indexes.index_url,
2466 extra_index_url: value.indexes.extra_index_url,
2467 no_index: value.indexes.no_index,
2468 find_links: value.indexes.find_links,
2469 index_strategy: value.index_strategy,
2470 keyring_provider: value.keyring_provider,
2471 resolution: value.resolution,
2472 prerelease: value.prerelease,
2473 prerelease_package: value.prerelease_package,
2474 fork_strategy: value.fork_strategy,
2475 dependency_metadata: value.dependency_metadata,
2476 config_settings: value.config_settings,
2477 config_settings_package: value.config_settings_package,
2478 build_isolation: value.build_isolation,
2479 require_build_hashes: value.require_build_hashes,
2480 extra_build_dependencies: value.extra_build_dependencies,
2481 extra_build_variables: value.extra_build_variables,
2482 exclude_newer: value.exclude_newer,
2483 exclude_newer_package: value.exclude_newer_package,
2484 link_mode: value.link_mode,
2485 compile_bytecode: value.compile_bytecode,
2486 no_sources: value.no_sources,
2487 no_sources_package: value.no_sources_package,
2488 no_build: value.no_build,
2489 no_build_package: value.no_build_package,
2490 no_binary: value.no_binary,
2491 no_binary_package: value.no_binary_package,
2492 torch_backend: value.torch_backend,
2493 }
2494 }
2495}
2496
2497impl From<ToolOptionsWire> for ToolOptions {
2498 fn from(value: ToolOptionsWire) -> Self {
2499 let exclude_newer = value
2500 .exclude_newer
2501 .map(|exclude_newer| match exclude_newer {
2502 ExcludeNewerOverride::Disabled => ExcludeNewerOverride::Disabled,
2503 ExcludeNewerOverride::Enabled(exclude_newer) => {
2504 let exclude_newer = *exclude_newer;
2505 if let Some(span) = value.exclude_newer_span
2506 && exclude_newer.span().is_none()
2507 {
2508 ExcludeNewerValue::relative(span).into()
2509 } else {
2510 exclude_newer.into()
2511 }
2512 }
2513 });
2514
2515 Self {
2516 index: value.index,
2517 index_url: value.index_url,
2518 extra_index_url: value.extra_index_url,
2519 no_index: value.no_index,
2520 find_links: value.find_links,
2521 index_strategy: value.index_strategy,
2522 keyring_provider: value.keyring_provider,
2523 resolution: value.resolution,
2524 prerelease: value.prerelease,
2525 prerelease_package: value.prerelease_package,
2526 fork_strategy: value.fork_strategy,
2527 dependency_metadata: value.dependency_metadata,
2528 config_settings: value.config_settings,
2529 config_settings_package: value.config_settings_package,
2530 build_isolation: value.build_isolation,
2531 require_build_hashes: value.require_build_hashes,
2532 extra_build_dependencies: value.extra_build_dependencies,
2533 extra_build_variables: value.extra_build_variables,
2534 exclude_newer,
2535 exclude_newer_package: value.exclude_newer_package,
2536 link_mode: value.link_mode,
2537 compile_bytecode: value.compile_bytecode,
2538 no_sources: value.no_sources,
2539 no_sources_package: value.no_sources_package,
2540 no_build: value.no_build,
2541 no_build_package: value.no_build_package,
2542 no_binary: value.no_binary,
2543 no_binary_package: value.no_binary_package,
2544 torch_backend: value.torch_backend,
2545 }
2546 }
2547}
2548
2549impl From<ToolOptions> for ToolOptionsWire {
2550 fn from(value: ToolOptions) -> Self {
2551 let (exclude_newer, exclude_newer_span) = match &value.exclude_newer {
2552 Some(ExcludeNewerOverride::Disabled) => (Some(ExcludeNewerOverride::Disabled), None),
2553 Some(ExcludeNewerOverride::Enabled(value)) => match value.as_ref() {
2554 ExcludeNewerValue::Absolute(_) => {
2555 (Some(ExcludeNewerOverride::Enabled(value.clone())), None)
2556 }
2557 ExcludeNewerValue::Relative(span) => (
2558 Some(ExcludeNewerValue::absolute(value.timestamp()).into()),
2559 Some(*span),
2560 ),
2561 },
2562 None => (None, None),
2563 };
2564
2565 Self {
2566 index: value.index,
2567 index_url: value.index_url,
2568 extra_index_url: value.extra_index_url,
2569 no_index: value.no_index,
2570 find_links: value.find_links,
2571 index_strategy: value.index_strategy,
2572 keyring_provider: value.keyring_provider,
2573 resolution: value.resolution,
2574 prerelease: value.prerelease,
2575 prerelease_package: value.prerelease_package,
2576 fork_strategy: value.fork_strategy,
2577 dependency_metadata: value.dependency_metadata,
2578 config_settings: value.config_settings,
2579 config_settings_package: value.config_settings_package,
2580 build_isolation: value.build_isolation,
2581 require_build_hashes: value.require_build_hashes,
2582 extra_build_dependencies: value.extra_build_dependencies,
2583 extra_build_variables: value.extra_build_variables,
2584 exclude_newer,
2585 exclude_newer_span,
2586 exclude_newer_package: value.exclude_newer_package,
2587 link_mode: value.link_mode,
2588 compile_bytecode: value.compile_bytecode,
2589 no_sources: value.no_sources,
2590 no_sources_package: value.no_sources_package,
2591 no_build: value.no_build,
2592 no_build_package: value.no_build_package,
2593 no_binary: value.no_binary,
2594 no_binary_package: value.no_binary_package,
2595 torch_backend: value.torch_backend,
2596 }
2597 }
2598}
2599
2600impl From<ToolOptions> for ResolverInstallerOptions {
2601 fn from(value: ToolOptions) -> Self {
2602 Self {
2603 indexes: IndexOptions {
2604 index: value.index,
2605 index_url: value.index_url,
2606 extra_index_url: value.extra_index_url,
2607 no_index: value.no_index,
2608 find_links: value.find_links,
2609 },
2610 index_strategy: value.index_strategy,
2611 keyring_provider: value.keyring_provider,
2612 resolution: value.resolution,
2613 prerelease: value.prerelease,
2614 prerelease_package: value.prerelease_package,
2615 fork_strategy: value.fork_strategy,
2616 dependency_metadata: value.dependency_metadata,
2617 config_settings: value.config_settings,
2618 config_settings_package: value.config_settings_package,
2619 build_isolation: value.build_isolation,
2620 require_build_hashes: value.require_build_hashes,
2621 extra_build_dependencies: value.extra_build_dependencies,
2622 extra_build_variables: value.extra_build_variables,
2623 exclude_newer: value.exclude_newer,
2624 exclude_newer_package: value.exclude_newer_package,
2625 link_mode: value.link_mode,
2626 compile_bytecode: value.compile_bytecode,
2627 no_sources: value.no_sources,
2628 no_sources_package: value.no_sources_package,
2629 upgrade: None,
2630 reinstall: None,
2631 no_build: value.no_build,
2632 no_build_package: value.no_build_package,
2633 no_binary: value.no_binary,
2634 no_binary_package: value.no_binary_package,
2635 torch_backend: value.torch_backend,
2636 }
2637 }
2638}
2639
2640#[derive(Debug, Clone, Default, Deserialize)]
2643#[serde(rename_all = "kebab-case", deny_unknown_fields)]
2644struct OptionsWire {
2645 required_version: Option<RequiredVersion>,
2648 system_certs: Option<bool>,
2649 native_tls: Option<bool>,
2650 offline: Option<bool>,
2651 no_cache: Option<bool>,
2652 cache_dir: Option<PathBuf>,
2653 preview: Option<bool>,
2654 preview_features: Option<PreviewFeaturesOption>,
2655 python_preference: Option<PythonPreference>,
2656 python_downloads: Option<PythonDownloads>,
2657 concurrent_downloads: Option<NonZeroUsize>,
2658 concurrent_builds: Option<NonZeroUsize>,
2659 concurrent_installs: Option<NonZeroUsize>,
2660
2661 index: Option<Vec<Index>>,
2664 index_url: Option<PipIndex>,
2665 extra_index_url: Option<Vec<PipExtraIndex>>,
2666 no_index: Option<bool>,
2667 find_links: Option<Vec<PipFindLinks>>,
2668 index_strategy: Option<IndexStrategy>,
2669 keyring_provider: Option<KeyringProviderType>,
2670 http_proxy: Option<ProxyUrl>,
2671 https_proxy: Option<ProxyUrl>,
2672 no_proxy: Option<Vec<String>>,
2673 allow_insecure_host: Option<Vec<TrustedHost>>,
2674 resolution: Option<ResolutionMode>,
2675 prerelease: Option<PrereleaseMode>,
2676 prerelease_package: Option<PrereleasePackage>,
2677 fork_strategy: Option<ForkStrategy>,
2678 dependency_metadata: Option<Vec<StaticMetadata>>,
2679 config_settings: Option<ConfigSettings>,
2680 config_settings_package: Option<PackageConfigSettings>,
2681 no_build_isolation: Option<bool>,
2682 require_build_hashes: Option<bool>,
2683 no_build_isolation_package: Option<Vec<PackageName>>,
2684 extra_build_dependencies: Option<ExtraBuildDependencies>,
2685 extra_build_variables: Option<ExtraBuildVariables>,
2686 exclude_newer: Option<ExcludeNewerOverride>,
2687 exclude_newer_package: Option<ExcludeNewerPackage>,
2688 link_mode: Option<LinkMode>,
2689 compile_bytecode: Option<bool>,
2690 no_sources: Option<bool>,
2691 no_sources_package: Option<Vec<PackageName>>,
2692 upgrade: Option<bool>,
2693 upgrade_package: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2694 reinstall: Option<bool>,
2695 reinstall_package: Option<Vec<PackageName>>,
2696 no_build: Option<bool>,
2697 no_build_package: Option<Vec<PackageName>>,
2698 no_binary: Option<bool>,
2699 no_binary_package: Option<Vec<PackageName>>,
2700 torch_backend: Option<TorchMode>,
2701
2702 python_install_mirror: Option<String>,
2705 pypy_install_mirror: Option<String>,
2706 graalpy_install_mirror: Option<String>,
2707 pyodide_install_mirror: Option<String>,
2708 python_downloads_json_url: Option<String>,
2709
2710 publish_url: Option<SafeUrl>,
2713 trusted_publishing: Option<TrustedPublishing>,
2714 check_url: Option<IndexUrl>,
2715
2716 add_bounds: Option<AddBoundsKind>,
2719
2720 audit: Option<AuditOptions>,
2721 pip: Option<PipOptions>,
2722 cache_keys: Option<Vec<CacheKey>>,
2723
2724 override_dependencies: Option<Vec<OverrideDependency>>,
2728 exclude_dependencies: Option<Vec<ExcludeDependency>>,
2729 constraint_dependencies: Option<Vec<Requirement<VerbatimParsedUrl>>>,
2730 build_constraint_dependencies: Option<Vec<BuildConstraintDependency>>,
2731 environments: Option<SupportedEnvironments>,
2732 required_environments: Option<SupportedEnvironments>,
2733 minimum_libc_version: Option<MinimumLibcVersion>,
2734
2735 conflicts: Option<serde::de::IgnoredAny>,
2739 workspace: Option<serde::de::IgnoredAny>,
2740 sources: Option<serde::de::IgnoredAny>,
2741 managed: Option<serde::de::IgnoredAny>,
2742 r#package: Option<serde::de::IgnoredAny>,
2743 default_groups: Option<serde::de::IgnoredAny>,
2744 dependency_groups: Option<serde::de::IgnoredAny>,
2745 dev_dependencies: Option<serde::de::IgnoredAny>,
2746
2747 build_backend: Option<serde::de::IgnoredAny>,
2749}
2750
2751impl TryFrom<OptionsWire> for Options {
2752 type Error = &'static str;
2753
2754 #[allow(deprecated)]
2755 fn try_from(value: OptionsWire) -> Result<Self, Self::Error> {
2756 let OptionsWire {
2757 required_version,
2758 system_certs,
2759 native_tls,
2760 offline,
2761 no_cache,
2762 cache_dir,
2763 preview,
2764 preview_features,
2765 python_preference,
2766 python_downloads,
2767 python_install_mirror,
2768 pypy_install_mirror,
2769 graalpy_install_mirror,
2770 pyodide_install_mirror,
2771 python_downloads_json_url,
2772 concurrent_downloads,
2773 concurrent_builds,
2774 concurrent_installs,
2775 index,
2776 index_url,
2777 extra_index_url,
2778 no_index,
2779 find_links,
2780 index_strategy,
2781 keyring_provider,
2782 http_proxy,
2783 https_proxy,
2784 no_proxy,
2785 allow_insecure_host,
2786 resolution,
2787 prerelease,
2788 prerelease_package,
2789 fork_strategy,
2790 dependency_metadata,
2791 config_settings,
2792 config_settings_package,
2793 no_build_isolation,
2794 require_build_hashes,
2795 no_build_isolation_package,
2796 exclude_newer,
2797 exclude_newer_package,
2798 link_mode,
2799 compile_bytecode,
2800 no_sources,
2801 no_sources_package,
2802 upgrade,
2803 upgrade_package,
2804 reinstall,
2805 reinstall_package,
2806 no_build,
2807 no_build_package,
2808 no_binary,
2809 no_binary_package,
2810 torch_backend,
2811 audit,
2812 pip,
2813 cache_keys,
2814 override_dependencies,
2815 exclude_dependencies,
2816 constraint_dependencies,
2817 build_constraint_dependencies,
2818 environments,
2819 required_environments,
2820 minimum_libc_version,
2821 conflicts,
2822 publish_url,
2823 trusted_publishing,
2824 check_url,
2825 workspace,
2826 sources,
2827 default_groups,
2828 dependency_groups,
2829 extra_build_dependencies,
2830 extra_build_variables,
2831 dev_dependencies,
2832 managed,
2833 package,
2834 add_bounds: bounds,
2835 build_backend,
2837 } = value;
2838
2839 Ok(Self {
2840 globals: GlobalOptions {
2841 required_version,
2842 system_certs,
2843 native_tls,
2844 offline,
2845 no_cache,
2846 cache_dir,
2847 preview: PreviewOption::try_from(preview, preview_features)?,
2848 python_preference,
2849 python_downloads,
2850 concurrent_downloads,
2851 concurrent_builds,
2852 concurrent_installs,
2853 http_proxy,
2854 https_proxy,
2855 no_proxy,
2856 allow_insecure_host: allow_insecure_host.clone(),
2858 },
2859 top_level: ResolverInstallerSchema {
2860 index,
2861 index_url,
2862 extra_index_url,
2863 no_index,
2864 find_links,
2865 index_strategy,
2866 keyring_provider,
2867 resolution,
2868 prerelease,
2869 prerelease_package,
2870 fork_strategy,
2871 dependency_metadata,
2872 config_settings,
2873 config_settings_package,
2874 no_build_isolation,
2875 require_build_hashes,
2876 no_build_isolation_package,
2877 extra_build_dependencies,
2878 extra_build_variables,
2879 exclude_newer,
2880 exclude_newer_package,
2881 link_mode,
2882 compile_bytecode,
2883 no_sources,
2884 no_sources_package,
2885 upgrade,
2886 upgrade_package,
2887 reinstall,
2888 reinstall_package,
2889 no_build,
2890 no_build_package,
2891 no_binary,
2892 no_binary_package,
2893 torch_backend,
2894 },
2895 pip,
2896 cache_keys,
2897 build_backend,
2898 override_dependencies,
2899 exclude_dependencies,
2900 constraint_dependencies,
2901 build_constraint_dependencies,
2902 environments,
2903 required_environments,
2904 minimum_libc_version,
2905 install_mirrors: PythonInstallMirrors {
2906 python_install_mirror,
2907 pypy_install_mirror,
2908 graalpy_install_mirror,
2909 pyodide_install_mirror,
2910 python_downloads_json_url,
2911 },
2912 conflicts,
2913 publish: PublishOptions {
2914 publish_url,
2915 trusted_publishing,
2916 check_url,
2917 },
2918 add: AddOptions { add_bounds: bounds },
2919 audit,
2920 workspace,
2921 sources,
2922 dev_dependencies,
2923 default_groups,
2924 dependency_groups,
2925 managed,
2926 package,
2927 })
2928 }
2929}
2930
2931#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2932#[serde(rename_all = "kebab-case")]
2933#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2934pub struct PublishOptions {
2935 #[option(
2938 default = "\"https://upload.pypi.org/legacy/\"",
2939 value_type = "str",
2940 example = r#"
2941 publish-url = "https://test.pypi.org/legacy/"
2942 "#
2943 )]
2944 pub publish_url: Option<SafeUrl>,
2945
2946 #[option(
2953 default = "automatic",
2954 value_type = "str",
2955 example = r#"
2956 trusted-publishing = "always"
2957 "#
2958 )]
2959 pub trusted_publishing: Option<TrustedPublishing>,
2960
2961 #[option(
2975 default = "None",
2976 value_type = "str",
2977 example = r#"
2978 check-url = "https://test.pypi.org/simple"
2979 "#
2980 )]
2981 pub check_url: Option<IndexUrl>,
2982}
2983
2984#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
2985#[serde(rename_all = "kebab-case")]
2986#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
2987pub struct AddOptions {
2988 #[option(
2999 default = "\"lower\"",
3000 value_type = "str",
3001 example = r#"
3002 add-bounds = "major"
3003 "#,
3004 possible_values = true
3005 )]
3006 pub add_bounds: Option<AddBoundsKind>,
3007}
3008
3009#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, CombineOptions, OptionsMetadata)]
3010#[serde(rename_all = "kebab-case")]
3011#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
3012pub struct AuditOptions {
3013 #[option(
3015 default = "false",
3016 value_type = "bool",
3017 example = r#"
3018 malware-check = true
3019 "#
3020 )]
3021 pub malware_check: Option<bool>,
3022
3023 #[option(
3025 default = "\"https://api.osv.dev/\"",
3026 value_type = "str",
3027 example = r#"
3028 malware-check-url = "https://example.com"
3029 "#
3030 )]
3031 pub malware_check_url: Option<SafeUrl>,
3032
3033 #[option(
3038 default = "[]",
3039 value_type = "list[str]",
3040 example = r#"
3041 ignore = ["PYSEC-2022-43017", "GHSA-5239-wwwm-4pmq"]
3042 "#
3043 )]
3044 pub ignore: Option<Vec<String>>,
3045
3046 #[option(
3052 default = "[]",
3053 value_type = "list[str]",
3054 example = r#"
3055 ignore-until-fixed = ["PYSEC-2022-43017"]
3056 "#
3057 )]
3058 pub ignore_until_fixed: Option<Vec<String>>,
3059}
3060
3061#[derive(Debug, Clone)]
3062pub struct MalwareCheckSettings {
3063 pub enabled: bool,
3065 pub malware_check_url: Option<SafeUrl>,
3067}
3068
3069impl MalwareCheckSettings {
3070 pub fn resolve(
3071 filesystem: Option<&FilesystemOptions>,
3072 environment: &EnvironmentOptions,
3073 ) -> Self {
3074 let audit = filesystem.and_then(|options| options.audit.as_ref());
3075
3076 Self {
3077 enabled: environment
3078 .malware_check
3079 .value
3080 .or(audit.and_then(|audit| audit.malware_check))
3081 .unwrap_or_default(),
3082 malware_check_url: environment
3083 .malware_check_url
3084 .clone()
3085 .or_else(|| audit.and_then(|audit| audit.malware_check_url.clone())),
3086 }
3087 }
3088}
3089
3090#[derive(Debug, Clone, DeserializeUntagged)]
3092#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
3093#[cfg_attr(feature = "schemars", schemars(untagged))]
3094#[serde(expecting = "a boolean or a list of preview feature names")]
3095pub enum PreviewFeaturesOption {
3096 #[untagged(bool)]
3097 Toggle(bool),
3098 #[untagged(seq)]
3099 Features(Vec<MaybePreviewFeature>),
3100}
3101
3102#[expect(
3103 dead_code,
3104 reason = "Fields are only used by the OptionsMetadata and JsonSchema derives"
3105)]
3106#[derive(OptionsMetadata)]
3107#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
3108#[cfg_attr(feature = "schemars", schemars(rename_all = "kebab-case"))]
3109struct PreviewOptionsDefinition {
3110 #[deprecated(note = "use `preview-features` instead")]
3116 preview: Option<bool>,
3117 #[option(
3121 default = "false",
3122 value_type = "bool | list[str]",
3123 example = r#"
3124 preview-features = true
3125 # or
3126 preview-features = ["json-output"]
3127 "#
3128 )]
3129 preview_features: Option<PreviewFeaturesOption>,
3130}
3131
3132#[derive(Debug, Clone)]
3134pub enum PreviewOption {
3135 Preview(bool),
3137 PreviewFeatures(PreviewFeaturesOption),
3139}
3140
3141impl uv_options_metadata::OptionsMetadata for PreviewOption {
3142 fn record(visit: &mut dyn uv_options_metadata::Visit) {
3143 <PreviewOptionsDefinition as uv_options_metadata::OptionsMetadata>::record(visit);
3144 }
3145}
3146
3147#[cfg(feature = "schemars")]
3148struct ConflictingPreviewOptions;
3149
3150#[cfg(feature = "schemars")]
3151impl schemars::JsonSchema for ConflictingPreviewOptions {
3152 fn schema_name() -> Cow<'static, str> {
3153 Cow::Borrowed("ConflictingPreviewOptions")
3154 }
3155
3156 fn json_schema(_generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
3157 schemars::json_schema!({
3158 "type": "object",
3159 "properties": {
3160 "preview": {},
3161 "preview-features": {},
3162 },
3163 "required": ["preview", "preview-features"],
3164 })
3165 }
3166}
3167
3168#[cfg(feature = "schemars")]
3169impl schemars::JsonSchema for PreviewOption {
3170 fn schema_name() -> Cow<'static, str> {
3171 Cow::Borrowed("PreviewOption")
3172 }
3173
3174 fn json_schema(generator: &mut schemars::SchemaGenerator) -> schemars::Schema {
3175 let mut schema = <PreviewOptionsDefinition as schemars::JsonSchema>::json_schema(generator);
3176 schema.insert(
3179 "not".to_string(),
3180 generator
3181 .subschema_for::<ConflictingPreviewOptions>()
3182 .into(),
3183 );
3184 schema
3185 }
3186}
3187
3188impl PreviewOption {
3189 fn try_from(
3190 preview: Option<bool>,
3191 preview_features: Option<PreviewFeaturesOption>,
3192 ) -> Result<Option<Self>, &'static str> {
3193 match (preview, preview_features) {
3194 (Some(_), Some(_)) => Err("cannot specify both `preview` and `preview-features`"),
3195 (Some(b), None) => Ok(Some(Self::Preview(b))),
3196 (None, Some(features)) => Ok(Some(Self::PreviewFeatures(features))),
3197 (None, None) => Ok(None),
3198 }
3199 }
3200
3201 pub fn resolve(&self) -> Preview {
3203 use PreviewFeaturesOption::{Features, Toggle};
3204
3205 match self {
3206 Self::Preview(false) | Self::PreviewFeatures(Toggle(false)) => Preview::default(),
3207 Self::Preview(true) | Self::PreviewFeatures(Toggle(true)) => Preview::all(),
3208 Self::PreviewFeatures(Features(features)) => Preview::from_feature_names(features),
3209 }
3210 }
3211}