1use uv_configuration::{
2 BuildIsolation, BuildOptions, ExcludeNewer, ForkStrategy, IndexStrategy, KeyringProviderType,
3 NoBinary, NoBuild, NoSources, Prerelease, PrereleaseMode, PrereleasePackage, Reinstall,
4 ResolutionMode, Upgrade,
5};
6use uv_distribution_types::{
7 ConfigSettings, DependencyMetadata, ExtraBuildVariables, IndexLocations, PackageConfigSettings,
8};
9use uv_install_wheel::LinkMode;
10use uv_pep440::Version;
11use uv_torch::{AmdGpuArchitecture, TorchMode};
12use uv_warnings::warn_user_once;
13use uv_workspace::pyproject::ExtraBuildDependencies;
14
15use crate::{ResolverInstallerOptions, ResolverOptions};
16
17#[derive(Debug, Clone, Copy)]
19pub enum LockedFlag {
20 Locked,
21 Check,
22}
23
24impl LockedFlag {
25 pub fn name(self) -> &'static str {
27 match self {
28 Self::Locked => "locked",
29 Self::Check => "check",
30 }
31 }
32}
33
34impl std::fmt::Display for LockedFlag {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 write!(f, "--{}", self.name())
37 }
38}
39
40#[derive(Debug, Clone, Copy)]
42pub enum LockedSource {
43 Cli(LockedFlag),
45 Env,
47}
48
49impl std::fmt::Display for LockedSource {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 match self {
52 Self::Cli(flag) => flag.fmt(f),
53 Self::Env => write!(f, "UV_LOCKED=1"),
54 }
55 }
56}
57
58#[derive(Debug, Clone, Copy)]
60pub enum LockCheck {
61 Enabled(LockedSource),
63 Disabled,
65}
66
67#[derive(Debug, Clone, Copy)]
69pub enum FrozenFlag {
70 Frozen,
71 CheckExists,
72}
73
74impl FrozenFlag {
75 pub fn name(self) -> &'static str {
77 match self {
78 Self::Frozen => "frozen",
79 Self::CheckExists => "check-exists",
80 }
81 }
82}
83
84impl std::fmt::Display for FrozenFlag {
85 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86 write!(f, "--{}", self.name())
87 }
88}
89
90#[derive(Debug, Clone, Copy)]
92pub enum FrozenSource {
93 Cli(FrozenFlag),
95 Env,
97}
98
99impl std::fmt::Display for FrozenSource {
100 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101 match self {
102 Self::Cli(flag) => flag.fmt(f),
103 Self::Env => write!(f, "UV_FROZEN=1"),
104 }
105 }
106}
107
108#[derive(Debug, Clone, Default)]
110pub enum PythonListKinds {
111 #[default]
113 Default,
114 Downloads,
116 Installed,
118}
119
120#[derive(Debug, Clone)]
124pub struct InstallerSettingsRef<'a> {
125 pub index_locations: &'a IndexLocations,
126 pub index_strategy: IndexStrategy,
127 pub keyring_provider: KeyringProviderType,
128 pub dependency_metadata: &'a DependencyMetadata,
129 pub config_setting: &'a ConfigSettings,
130 pub config_settings_package: &'a PackageConfigSettings,
131 pub build_isolation: &'a BuildIsolation,
132 pub extra_build_dependencies: &'a ExtraBuildDependencies,
133 pub extra_build_variables: &'a ExtraBuildVariables,
134 pub exclude_newer: &'a ExcludeNewer,
135 pub link_mode: LinkMode,
136 pub compile_bytecode: bool,
137 pub reinstall: &'a Reinstall,
138 pub build_options: &'a BuildOptions,
139 pub sources: NoSources,
140}
141
142#[derive(Debug, Clone, Default)]
146pub struct ResolverSettings {
147 pub build_options: BuildOptions,
148 pub config_setting: ConfigSettings,
149 pub config_settings_package: PackageConfigSettings,
150 pub dependency_metadata: DependencyMetadata,
151 pub exclude_newer: ExcludeNewer,
152 pub fork_strategy: ForkStrategy,
153 pub index_locations: IndexLocations,
154 pub index_strategy: IndexStrategy,
155 pub keyring_provider: KeyringProviderType,
156 pub link_mode: LinkMode,
157 pub build_isolation: BuildIsolation,
158 pub extra_build_dependencies: ExtraBuildDependencies,
159 pub extra_build_variables: ExtraBuildVariables,
160 pub prerelease: Prerelease,
161 pub resolution: ResolutionMode,
162 pub sources: NoSources,
163 pub torch_backend: Option<TorchMode>,
164 pub cuda_driver_version: Option<Version>,
165 pub amd_gpu_architecture: Option<AmdGpuArchitecture>,
166 pub upgrade: Upgrade,
167}
168
169#[expect(deprecated)]
171fn warn_if_deprecated_prerelease_mode(prerelease: PrereleaseMode) -> PrereleaseMode {
172 if matches!(prerelease, PrereleaseMode::IfNecessaryOrExplicit) {
173 warn_user_once!(
174 "The `if-necessary-or-explicit` pre-release mode is deprecated and will be removed in a future release. Use `if-necessary` instead."
175 );
176 PrereleaseMode::IfNecessary
177 } else {
178 prerelease
179 }
180}
181
182pub fn resolve_prerelease(global: PrereleaseMode, mut package: PrereleasePackage) -> Prerelease {
184 for mode in package.values_mut() {
185 *mode = warn_if_deprecated_prerelease_mode(*mode);
186 }
187
188 Prerelease {
189 global: warn_if_deprecated_prerelease_mode(global),
190 package,
191 }
192}
193
194impl From<ResolverOptions> for ResolverSettings {
195 fn from(value: ResolverOptions) -> Self {
196 Self {
197 index_locations: value.indexes.into(),
198 resolution: value.resolution.unwrap_or_default(),
199 prerelease: resolve_prerelease(
200 value.prerelease.unwrap_or_default(),
201 value.prerelease_package.unwrap_or_default(),
202 ),
203 fork_strategy: value.fork_strategy.unwrap_or_default(),
204 dependency_metadata: DependencyMetadata::from_entries(
205 value.dependency_metadata.into_iter().flatten(),
206 ),
207 index_strategy: value.index_strategy.unwrap_or_default(),
208 keyring_provider: value.keyring_provider.unwrap_or_default(),
209 config_setting: value.config_settings.unwrap_or_default(),
210 config_settings_package: value.config_settings_package.unwrap_or_default(),
211 build_isolation: value.build_isolation.unwrap_or_default(),
212 extra_build_dependencies: value.extra_build_dependencies.unwrap_or_default(),
213 extra_build_variables: value.extra_build_variables.unwrap_or_default(),
214 exclude_newer: ExcludeNewer::from_args(
215 value.exclude_newer,
216 value
217 .exclude_newer_package
218 .unwrap_or_default()
219 .into_iter()
220 .map(Into::into)
221 .collect(),
222 ),
223 link_mode: value.link_mode.unwrap_or_default(),
224 torch_backend: value.torch_backend,
225 cuda_driver_version: None,
226 amd_gpu_architecture: None,
227 sources: NoSources::from_args(
228 value.no_sources,
229 value.no_sources_package.unwrap_or_default(),
230 ),
231 upgrade: value.upgrade.unwrap_or_default(),
232 build_options: BuildOptions::new(
233 NoBinary::from_args(value.no_binary, value.no_binary_package.unwrap_or_default()),
234 NoBuild::from_args(value.no_build, value.no_build_package.unwrap_or_default()),
235 ),
236 }
237 }
238}
239
240#[derive(Debug, Clone, Default)]
246pub struct ResolverInstallerSettings {
247 pub resolver: ResolverSettings,
248 pub compile_bytecode: bool,
249 pub reinstall: Reinstall,
250}
251
252impl From<ResolverInstallerOptions> for ResolverInstallerSettings {
253 fn from(value: ResolverInstallerOptions) -> Self {
254 let index_locations = value.indexes.into();
255 Self {
256 resolver: ResolverSettings {
257 build_options: BuildOptions::new(
258 NoBinary::from_args(
259 value.no_binary,
260 value.no_binary_package.unwrap_or_default(),
261 ),
262 NoBuild::from_args(value.no_build, value.no_build_package.unwrap_or_default()),
263 ),
264 config_setting: value.config_settings.unwrap_or_default(),
265 config_settings_package: value.config_settings_package.unwrap_or_default(),
266 dependency_metadata: DependencyMetadata::from_entries(
267 value.dependency_metadata.into_iter().flatten(),
268 ),
269 exclude_newer: ExcludeNewer::from_args(
270 value.exclude_newer,
271 value
272 .exclude_newer_package
273 .unwrap_or_default()
274 .into_iter()
275 .map(Into::into)
276 .collect(),
277 ),
278 fork_strategy: value.fork_strategy.unwrap_or_default(),
279 index_locations,
280 index_strategy: value.index_strategy.unwrap_or_default(),
281 keyring_provider: value.keyring_provider.unwrap_or_default(),
282 link_mode: value.link_mode.unwrap_or_default(),
283 build_isolation: value.build_isolation.unwrap_or_default(),
284 extra_build_dependencies: value.extra_build_dependencies.unwrap_or_default(),
285 extra_build_variables: value.extra_build_variables.unwrap_or_default(),
286 prerelease: resolve_prerelease(
287 value.prerelease.unwrap_or_default(),
288 value.prerelease_package.unwrap_or_default(),
289 ),
290 resolution: value.resolution.unwrap_or_default(),
291 sources: NoSources::from_args(
292 value.no_sources,
293 value.no_sources_package.unwrap_or_default(),
294 ),
295 torch_backend: value.torch_backend,
296 cuda_driver_version: None,
297 amd_gpu_architecture: None,
298 upgrade: value.upgrade.unwrap_or_default(),
299 },
300 compile_bytecode: value.compile_bytecode.unwrap_or_default(),
301 reinstall: value.reinstall.unwrap_or_default(),
302 }
303 }
304}
305
306impl<'a> From<&'a ResolverInstallerSettings> for InstallerSettingsRef<'a> {
307 fn from(settings: &'a ResolverInstallerSettings) -> Self {
308 Self {
309 index_locations: &settings.resolver.index_locations,
310 index_strategy: settings.resolver.index_strategy,
311 keyring_provider: settings.resolver.keyring_provider,
312 dependency_metadata: &settings.resolver.dependency_metadata,
313 config_setting: &settings.resolver.config_setting,
314 config_settings_package: &settings.resolver.config_settings_package,
315 build_isolation: &settings.resolver.build_isolation,
316 extra_build_dependencies: &settings.resolver.extra_build_dependencies,
317 extra_build_variables: &settings.resolver.extra_build_variables,
318 exclude_newer: &settings.resolver.exclude_newer,
319 link_mode: settings.resolver.link_mode,
320 compile_bytecode: settings.compile_bytecode,
321 reinstall: &settings.reinstall,
322 build_options: &settings.resolver.build_options,
323 sources: settings.resolver.sources.clone(),
324 }
325 }
326}