diff --git a/crates/pixi/tests/integration_rust/pypi_tests.rs b/crates/pixi/tests/integration_rust/pypi_tests.rs index e26251729b..d601ca6b3d 100644 --- a/crates/pixi/tests/integration_rust/pypi_tests.rs +++ b/crates/pixi/tests/integration_rust/pypi_tests.rs @@ -1,4 +1,11 @@ -use std::{fs::File, io::Write, str::FromStr}; +use std::{ + collections::HashMap, + fs::File, + io::Write, + path::{Path, PathBuf}, + str::FromStr, + time::SystemTime, +}; use pep508_rs::Requirement; use rattler_conda_types::Platform; @@ -1150,6 +1157,271 @@ async fn test_prerelease_mode_disallow() { ); } +/// Test that PyPI sdist with static metadata (all in pyproject.toml) can be resolved. +/// This tests the satisfiability check extracts metadata without running setup.py. +#[tokio::test] +#[cfg_attr( + any(not(feature = "online_tests"), not(feature = "slow_integration_tests")), + ignore +)] +async fn test_pypi_sdist_static_metadata_extraction() { + setup_tracing(); + + let platform = Platform::current(); + + // Create a pyproject.toml with all static metadata (hatchling build backend) + let pyproject = format!( + r#" +[project] +name = "test-static-pkg" +version = "1.2.3" +description = "Test package with static metadata" +requires-python = ">=3.10" +dependencies = [] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build] +include = ["src"] +targets.wheel.strict-naming = false +targets.wheel.packages = ["src/test_static_pkg"] +targets.sdist.strict-naming = false +targets.sdist.packages = ["src/test_static_pkg"] + +[tool.pixi.workspace] +channels = ["https://prefix.dev/conda-forge"] +platforms = ["{platform}"] + +[tool.pixi.dependencies] +python = "~=3.12.0" + +[tool.pixi.pypi-dependencies] +test-static-pkg = {{ path = ".", editable = true }} +"#, + ); + + let pixi = PixiControl::from_pyproject_manifest(&pyproject).unwrap(); + + // Create the package source files + let src_dir = pixi.workspace_path().join("src").join("test_static_pkg"); + fs_err::create_dir_all(&src_dir).unwrap(); + fs_err::write(src_dir.join("__init__.py"), "__version__ = '1.2.3'\n").unwrap(); + + // Resolve the lock file + let lock_file = pixi.update_lock_file().await.unwrap(); + + // Verify the package is in the lock file with correct version + let locked_version = lock_file + .get_pypi_package_version("default", platform, "test-static-pkg") + .expect("test-static-pkg should be in lock file"); + + assert_eq!( + locked_version.to_string(), + "1.2.3", + "Static metadata version should be correctly extracted" + ); +} + +/// Test that PyPI sdist with dynamic metadata (version from setup.py) can be resolved. +/// This tests the satisfiability check runs the build backend to extract metadata. +#[tokio::test] +#[cfg_attr( + any(not(feature = "online_tests"), not(feature = "slow_integration_tests")), + ignore +)] +async fn test_pypi_sdist_dynamic_metadata_extraction() { + setup_tracing(); + + let platform = Platform::current(); + + // Create a pyproject.toml with dynamic version (setuptools) + let pyproject = format!( + r#" +[project] +name = "test-dynamic-pkg" +dynamic = ["version"] +requires-python = ">=3.10" +dependencies = [] + +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.dynamic] +version = {{attr = "test_dynamic_pkg.__version__"}} + +[tool.pixi.workspace] +channels = ["https://prefix.dev/conda-forge"] +platforms = ["{platform}"] + +[tool.pixi.dependencies] +python = "~=3.12.0" + +[tool.pixi.pypi-dependencies] +test-dynamic-pkg = {{ path = ".", editable = true }} +"#, + ); + + let pixi = PixiControl::from_pyproject_manifest(&pyproject).unwrap(); + + // Create the package source files with version defined in __init__.py + let pkg_dir = pixi.workspace_path().join("test_dynamic_pkg"); + fs_err::create_dir_all(&pkg_dir).unwrap(); + fs_err::write(pkg_dir.join("__init__.py"), "__version__ = '2.5.0'\n").unwrap(); + + // Resolve the lock file + let lock_file = pixi.update_lock_file().await.unwrap(); + + // Verify the package is in the lock file with dynamically extracted version + let locked_version = lock_file + .get_pypi_package_version("default", platform, "test-dynamic-pkg") + .expect("test-dynamic-pkg should be in lock file"); + + assert_eq!( + locked_version.to_string(), + "2.5.0", + "Dynamic metadata version should be correctly extracted" + ); +} + +/// Find all sdist cache directories under uv-cache/sdists-v*/path/ +fn find_sdist_cache_dirs(cache_dir: &Path) -> Vec { + let mut result = Vec::new(); + let uv_cache = cache_dir.join("uv-cache"); + if !uv_cache.exists() { + return result; + } + + // Look for sdists-v* directories (e.g., sdists-v9) + if let Ok(entries) = fs_err::read_dir(&uv_cache) { + for entry in entries.filter_map(|e| e.ok()) { + let path = entry.path(); + if path.is_dir() { + let name = path.file_name().and_then(|n| n.to_str()).unwrap_or(""); + if name.starts_with("sdists-v") { + let path_dir = path.join("path"); + if path_dir.exists() + && let Ok(hash_dirs) = fs_err::read_dir(&path_dir) + { + for hash_entry in hash_dirs.filter_map(|e| e.ok()) { + let hash_path = hash_entry.path(); + if hash_path.is_dir() { + result.push(hash_path); + } + } + } + } + } + } + } + result +} + +/// Test that PyPI sdist builds are cached and reused on subsequent installs. +/// Uses file modification time verification to check no rebuild occurred. +#[tokio::test] +#[cfg_attr( + any(not(feature = "online_tests"), not(feature = "slow_integration_tests")), + ignore +)] +async fn test_pypi_sdist_cache_reuse() { + setup_tracing(); + + let platform = Platform::current(); + + let pyproject = format!( + r#" +[project] +name = "test-cache-pkg" +version = "1.0.0" +requires-python = ">=3.10" +dependencies = [] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build] +include = ["src"] +targets.wheel.strict-naming = false +targets.wheel.packages = ["src/test_cache_pkg"] +targets.sdist.strict-naming = false +targets.sdist.packages = ["src/test_cache_pkg"] + +[tool.pixi.workspace] +channels = ["https://prefix.dev/conda-forge"] +platforms = ["{platform}"] + +[tool.pixi.dependencies] +python = "~=3.12.0" + +[tool.pixi.pypi-dependencies] +test-cache-pkg = {{ path = "." }} +"#, + ); + + let pixi = PixiControl::from_pyproject_manifest(&pyproject).unwrap(); + + // Create the package source files + let src_dir = pixi.workspace_path().join("src").join("test_cache_pkg"); + fs_err::create_dir_all(&src_dir).unwrap(); + fs_err::write(src_dir.join("__init__.py"), "__version__ = '1.0.0'\n").unwrap(); + + // First install - builds and caches the wheel + let tmp_dir = tempdir().unwrap(); + let cache_dir = tmp_dir.path().to_path_buf(); + + temp_env::async_with_vars( + [("PIXI_CACHE_DIR", Some(tmp_dir.path().to_str().unwrap()))], + async { + pixi.install().await.unwrap(); + }, + ) + .await; + + // Find the sdist cache directory for our package + let sdist_dirs = find_sdist_cache_dirs(&cache_dir); + assert!( + !sdist_dirs.is_empty(), + "Expected sdist cache directory to exist after first install" + ); + + // Record mtimes of all sdist cache directories + let mtimes_first: HashMap = sdist_dirs + .iter() + .filter_map(|p| { + fs_err::metadata(p) + .ok() + .and_then(|m| m.modified().ok()) + .map(|t| (p.clone(), t)) + }) + .collect(); + + // Second install - should reuse cache without rebuilding + temp_env::async_with_vars( + [("PIXI_CACHE_DIR", Some(tmp_dir.path().to_str().unwrap()))], + async { + pixi.install().await.unwrap(); + }, + ) + .await; + + // Verify sdist cache directories were not modified (no rebuild occurred) + for (path, mtime_first) in &mtimes_first { + let mtime_second = fs_err::metadata(path) + .and_then(|m| m.modified()) + .unwrap_or_else(|_| panic!("Cache directory disappeared: {}", path.display())); + assert_eq!( + *mtime_first, + mtime_second, + "Sdist cache was modified (rebuilt): {}", + path.display() + ); + } +} + /// Test for issue #5205: Specifying a python sub-version (patch) should work correctly /// Before the fix, using python 3.10.6 would create a specifier "==3.10.*" which conflicts /// with requires-python = "==3.10.6". The fix uses the full version string. diff --git a/crates/pixi_core/src/lock_file/outdated.rs b/crates/pixi_core/src/lock_file/outdated.rs index c119c15177..19e206fe20 100644 --- a/crates/pixi_core/src/lock_file/outdated.rs +++ b/crates/pixi_core/src/lock_file/outdated.rs @@ -1,6 +1,15 @@ -use std::collections::{HashMap, HashSet}; +use std::{ + collections::{HashMap, HashSet}, + path::PathBuf, + sync::Arc, +}; -use super::{verify_environment_satisfiability, verify_platform_satisfiability}; +use super::{ + CondaPrefixUpdater, + resolve::build_dispatch::LazyBuildDispatchDependencies, + satisfiability::{VerifySatisfiabilityContext, pypi_metadata}, + verify_environment_satisfiability, verify_platform_satisfiability, +}; use crate::{ Workspace, lock_file::satisfiability::{EnvironmentUnsat, verify_solve_group_satisfiability}, @@ -8,18 +17,45 @@ use crate::{ }; use fancy_display::FancyDisplay; use itertools::Itertools; +use once_cell::sync::OnceCell; use pixi_command_dispatcher::CommandDispatcher; use pixi_consts::consts; -use pixi_manifest::FeaturesExt; +use pixi_manifest::{EnvironmentName, FeaturesExt}; +use pixi_uv_context::UvResolutionContext; use rattler_conda_types::Platform; use rattler_lock::{LockFile, LockedPackageRef}; +/// Cache for build-related resources that can be shared between +/// satisfiability checking and PyPI resolution. +#[derive(Default)] +pub struct PypiEnvironmentBuildCache { + /// Lazily initialized build dispatch dependencies (interpreter, env, etc.) + pub lazy_build_dispatch_deps: LazyBuildDispatchDependencies, + /// Optional conda prefix updater (created during satisfiability checking) + pub conda_prefix_updater: OnceCell, +} + +/// Key for the build cache, combining environment name and platform. +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub struct BuildCacheKey { + pub environment: EnvironmentName, + pub platform: Platform, +} + +impl BuildCacheKey { + pub fn new(environment: EnvironmentName, platform: Platform) -> Self { + Self { + environment, + platform, + } + } +} + /// A struct that contains information about specific outdated environments. /// /// Use the [`OutdatedEnvironments::from_project_and_lock_file`] to create an /// instance of this struct by examining the project and lock-file and finding /// any mismatches. -#[derive(Debug)] pub struct OutdatedEnvironments<'p> { /// The conda environments that are considered out of date with the /// lock-file. @@ -33,6 +69,18 @@ pub struct OutdatedEnvironments<'p> { /// discarded. This is the case for instance when the order of the /// channels changed. pub disregard_locked_content: DisregardLockedContent<'p>, + + /// Lazily initialized UV context for building dynamic metadata. + /// This is shared between satisfiability checking and pypi resolution. + pub uv_context: OnceCell, + + /// Per-environment-platform build caches for sharing resources between + /// satisfiability checking and PyPI resolution. + pub build_caches: HashMap>, + + /// Cache for static metadata extracted from pyproject.toml files. + /// This is shared across platforms since static metadata is platform-independent. + pub static_metadata_cache: HashMap, } /// A struct that stores whether the locked content of certain environments @@ -66,11 +114,16 @@ impl<'p> OutdatedEnvironments<'p> { lock_file: &LockFile, ) -> Self { // Find all targets that are not satisfied by the lock-file - let UnsatisfiableTargets { - mut outdated_conda, - mut outdated_pypi, - disregard_locked_content, - } = find_unsatisfiable_targets(workspace, command_dispatcher, lock_file).await; + let ( + UnsatisfiableTargets { + mut outdated_conda, + mut outdated_pypi, + disregard_locked_content, + }, + uv_context, + build_caches, + static_metadata_cache, + ) = find_unsatisfiable_targets(workspace, command_dispatcher, lock_file).await; // Extend the outdated targets to include the solve groups let (mut conda_solve_groups_out_of_date, mut pypi_solve_groups_out_of_date) = @@ -118,6 +171,9 @@ impl<'p> OutdatedEnvironments<'p> { conda: outdated_conda, pypi: outdated_pypi, disregard_locked_content, + uv_context, + build_caches, + static_metadata_cache, } } @@ -137,13 +193,35 @@ struct UnsatisfiableTargets<'p> { /// Find all targets (combination of environment and platform) who's /// requirements in the `project` are not satisfied by the `lock_file`. +/// +/// Returns the unsatisfiable targets, the lazily-initialized UV context +/// (which may have been initialized during satisfiability checking), +/// build caches for each environment, and the static metadata cache. async fn find_unsatisfiable_targets<'p>( project: &'p Workspace, command_dispatcher: CommandDispatcher, lock_file: &LockFile, -) -> UnsatisfiableTargets<'p> { +) -> ( + UnsatisfiableTargets<'p>, + OnceCell, + HashMap>, + HashMap, +) { let mut verified_environments = HashMap::new(); let mut unsatisfiable_targets = UnsatisfiableTargets::default(); + + // Create UV context lazily for building dynamic metadata + let uv_context: OnceCell = OnceCell::new(); + + // Create build caches for sharing between satisfiability and resolution + let mut build_caches: HashMap> = HashMap::new(); + + // Create static metadata cache for sharing across platforms + let mut static_metadata_cache: HashMap = + HashMap::new(); + + let project_config = project.config(); + for environment in project.environments() { let platforms = environment.platforms(); @@ -227,15 +305,18 @@ async fn find_unsatisfiable_targets<'p>( // Verify each individual platform for platform in platforms { - match verify_platform_satisfiability( - &environment, - command_dispatcher.clone(), - locked_environment, + let mut ctx = VerifySatisfiabilityContext { + environment: &environment, + command_dispatcher: command_dispatcher.clone(), platform, - project.root(), - ) - .await - { + project_root: project.root(), + uv_context: &uv_context, + config: project_config, + project_env_vars: project.env_vars().clone(), + build_caches: &mut build_caches, + static_metadata_cache: &mut static_metadata_cache, + }; + match verify_platform_satisfiability(&mut ctx, locked_environment).await { Ok(verified_env) => { verified_environments.insert((environment.clone(), platform), verified_env); } @@ -317,7 +398,12 @@ async fn find_unsatisfiable_targets<'p>( .insert(platform); } - unsatisfiable_targets + ( + unsatisfiable_targets, + uv_context, + build_caches, + static_metadata_cache, + ) } /// Given a mapping of outdated targets, construct a new mapping of all the diff --git a/crates/pixi_core/src/lock_file/resolve/build_dispatch.rs b/crates/pixi_core/src/lock_file/resolve/build_dispatch.rs index c9ec5a4596..dd0ca10026 100644 --- a/crates/pixi_core/src/lock_file/resolve/build_dispatch.rs +++ b/crates/pixi_core/src/lock_file/resolve/build_dispatch.rs @@ -221,11 +221,14 @@ pub struct LazyBuildDispatch<'a> { } /// These are resources for the [`BuildDispatch`] that need to be lazily -/// initialized. along with the build dispatch. +/// initialized along with the build dispatch. /// -/// This needs to be passed in externally or there will be problems with the -/// borrows being shorter than the lifetime of the `BuildDispatch`, and we are -/// returning the references. +/// Fields are stored here for two reasons: +/// 1. **Expensive operations**: `interpreter` requires disk I/O +/// 2. **Lifetime requirements**: `BuildDispatch<'a>` needs references with lifetime `'a`, +/// so values must be stored in a struct with that lifetime (not borrowed from `&self`) +/// +/// The `last_error` field is for panic recovery during build dispatch initialization. #[derive(Default)] pub struct LazyBuildDispatchDependencies { /// The initialized python interpreter @@ -233,6 +236,8 @@ pub struct LazyBuildDispatchDependencies { /// The non isolated packages non_isolated_packages: OnceCell, /// The python environment + /// needed to be together with the interpreter + /// for passing correctly the lifetime of BuildDispatch<'a> python_env: OnceCell, /// The constraints for dependency resolution constraints: OnceCell, diff --git a/crates/pixi_core/src/lock_file/resolve/pypi.rs b/crates/pixi_core/src/lock_file/resolve/pypi.rs index 991412bf62..ac0a37f56e 100644 --- a/crates/pixi_core/src/lock_file/resolve/pypi.rs +++ b/crates/pixi_core/src/lock_file/resolve/pypi.rs @@ -36,9 +36,7 @@ use pypi_modifiers::{ pypi_tags::{get_pypi_tags, is_python_record}, }; use rattler_digest::{Md5, Sha256, parse_digest_from_hex}; -use rattler_lock::{ - PackageHashes, PypiPackageData, PypiPackageEnvironmentData, PypiSourceTreeHashable, UrlOrPath, -}; +use rattler_lock::{PackageHashes, PypiPackageData, PypiPackageEnvironmentData, UrlOrPath}; use typed_path::Utf8TypedPathBuf; use url::Url; use uv_client::{ @@ -68,17 +66,18 @@ use crate::{ lock_file::{ CondaPrefixUpdater, LockedPypiPackages, PixiRecordsByName, PypiPackageIdentifier, PypiRecord, + outdated::PypiEnvironmentBuildCache, records_by_name::HasNameVersion, resolve::{ - build_dispatch::{ - LazyBuildDispatch, LazyBuildDispatchDependencies, UvBuildDispatchParams, - }, + build_dispatch::{LazyBuildDispatch, UvBuildDispatchParams}, resolver_provider::CondaResolverProvider, }, }, - workspace::{Environment, EnvironmentVars}, + workspace::{Environment, EnvironmentVars, grouped_environment::GroupedEnvironment}, }; +use pixi_command_dispatcher::CommandDispatcher; use pixi_uv_context::UvResolutionContext; +use rattler_conda_types::GenericVirtualPackage; #[derive(Debug, thiserror::Error)] #[error("Invalid hash: {0} type: {1}")] @@ -289,13 +288,14 @@ pub async fn resolve_pypi( platform: rattler_conda_types::Platform, pb: &ProgressBar, project_root: &Path, - prefix_updater: CondaPrefixUpdater, + command_dispatcher: CommandDispatcher, repodata_building_records: miette::Result>, project_env_vars: HashMap, - environment_name: Environment<'_>, + environment: Environment<'_>, disallow_install_conda_prefix: bool, exclude_newer: Option>, solve_strategy: SolveStrategy, + build_cache: Arc, ) -> miette::Result<(LockedPypiPackages, Option)> { // Solve python packages pb.set_message("resolving pypi dependencies"); @@ -386,6 +386,7 @@ pub async fn resolve_pypi( ) .into_diagnostic() .context("error creating version specifier for python version")?; + let requires_python = RequiresPython::from_specifiers(&uv_pep440::VersionSpecifiers::from(python_specifier)); tracing::debug!( @@ -393,11 +394,17 @@ pub async fn resolve_pypi( requires_python ); + let index_strategy = to_index_strategy(pypi_options.index_strategy.as_ref()); + let index_locations = pypi_options_to_index_locations(pypi_options, project_root).into_diagnostic()?; - // TODO: create a cached registry client per index_url set? - let index_strategy = to_index_strategy(pypi_options.index_strategy.as_ref()); + // Create build options + let build_options = pypi_options_to_build_options( + &pypi_options.no_build.clone().unwrap_or_default(), + &pypi_options.no_binary.clone().unwrap_or_default(), + ) + .into_diagnostic()?; // Configure insecure hosts for TLS verification bypass let allow_insecure_hosts = configure_insecure_hosts_for_tls_bypass( @@ -406,30 +413,26 @@ pub async fn resolve_pypi( &index_locations, ); - let base_client_builder = BaseClientBuilder::default() - .allow_insecure_host(allow_insecure_hosts) - .markers(&marker_environment) - .keyring(context.keyring_provider) - .connectivity(Connectivity::Online) - .native_tls(context.use_native_tls) - .extra_middleware(context.extra_middleware.clone()); - - let mut uv_client_builder = - RegistryClientBuilder::new(base_client_builder, context.cache.clone()) - .index_locations(index_locations.clone()) - .index_strategy(index_strategy); - - for p in &context.proxies { - uv_client_builder = uv_client_builder.proxy(p.clone()) - } - - let registry_client = Arc::new(uv_client_builder.build()); + let registry_client = { + let base_client_builder = BaseClientBuilder::default() + .allow_insecure_host(allow_insecure_hosts) + .markers(&marker_environment) + .keyring(context.keyring_provider) + .connectivity(Connectivity::Online) + .native_tls(context.use_native_tls) + .extra_middleware(context.extra_middleware.clone()); + + let mut uv_client_builder = + RegistryClientBuilder::new(base_client_builder, context.cache.clone()) + .index_locations(index_locations.clone()) + .index_strategy(index_strategy); + + for p in &context.proxies { + uv_client_builder = uv_client_builder.proxy(p.clone()) + } - let build_options = pypi_options_to_build_options( - &pypi_options.no_build.clone().unwrap_or_default(), - &pypi_options.no_binary.clone().unwrap_or_default(), - ) - .into_diagnostic()?; + Arc::new(uv_client_builder.build()) + }; let dependency_overrides = pypi_options.dependency_overrides.as_ref().map(|overrides|->Result, _> { overrides @@ -448,27 +451,27 @@ pub async fn resolve_pypi( .collect::, _>>() }).transpose()?.unwrap_or_default(); - // Resolve the flat indexes from `--find-links`. - // In UV 0.7.8, we need to fetch flat index entries from the index locations - let flat_index_client = FlatIndexClient::new( - registry_client.cached_client(), - Connectivity::Online, - &context.cache, - ); - let flat_index_urls: Vec<&IndexUrl> = index_locations - .flat_indexes() - .map(|index| index.url()) - .collect(); - let flat_index_entries = flat_index_client - .fetch_all(flat_index_urls.into_iter()) - .await - .into_diagnostic()?; - let flat_index = FlatIndex::from_entries( - flat_index_entries, - Some(&tags), - &context.hash_strategy, - &build_options, - ); + let flat_index = { + let flat_index_client = FlatIndexClient::new( + registry_client.cached_client(), + Connectivity::Online, + &context.cache, + ); + let flat_index_urls: Vec<&IndexUrl> = index_locations + .flat_indexes() + .map(|index| index.url()) + .collect(); + let flat_index_entries = flat_index_client + .fetch_all(flat_index_urls.into_iter()) + .await + .into_diagnostic()?; + FlatIndex::from_entries( + flat_index_entries, + Some(&tags), + &context.hash_strategy, + &build_options, + ) + }; let resolution_mode = match solve_strategy { SolveStrategy::Highest => ResolutionMode::Highest, @@ -491,8 +494,9 @@ pub async fn resolve_pypi( ..Options::default() }; - let config_settings = ConfigSettings::default(); let dependency_metadata = DependencyMetadata::default(); + + let config_settings = ConfigSettings::default(); let build_params = UvBuildDispatchParams::new( ®istry_client, &context.cache, @@ -518,15 +522,39 @@ pub async fn resolve_pypi( .with_source_strategy(context.source_strategy) .with_concurrency(context.concurrency); - let lazy_build_dispatch_dependencies = LazyBuildDispatchDependencies::default(); + // Use cached build dispatch dependencies + let lazy_build_dispatch_deps = &build_cache.lazy_build_dispatch_deps; + + // Use cached conda_prefix_updater if available, otherwise create new + let conda_prefix_updater = build_cache + .conda_prefix_updater + .get_or_try_init(|| { + // Create a new conda prefix updater using best_platform (host platform) + let prefix_platform = environment.best_platform(); + let group = GroupedEnvironment::Environment(environment.clone()); + let virtual_packages = environment.virtual_packages(prefix_platform); + + CondaPrefixUpdater::builder( + group, + prefix_platform, + virtual_packages + .into_iter() + .map(GenericVirtualPackage::from) + .collect(), + command_dispatcher, + ) + .finish() + })? + .clone(); + let lazy_build_dispatch = LazyBuildDispatch::new( build_params, - prefix_updater, + conda_prefix_updater, project_env_vars, - environment_name, + environment, repodata_building_records.map(|r| r.records.clone()), pypi_options.no_build_isolation.clone(), - &lazy_build_dispatch_dependencies, + lazy_build_dispatch_deps, None, disallow_install_conda_prefix, ); @@ -1073,17 +1101,9 @@ async fn lock_pypi_packages( ) } SourceDist::Path(path) => { - // Compute the hash of the package based on the source tree. - let hash = if path.install_path.is_dir() { - Some( - PypiSourceTreeHashable::from_directory(&path.install_path) - .into_diagnostic() - .context("failed to compute hash of pypi source tree")? - .hash(), - ) - } else { - None - }; + // No hash for directory-based packages. + // Satisfiability check uses metadata comparison instead. + let hash = None; // process the path or url that we get back from uv let install_path = process_uv_path_url( @@ -1100,17 +1120,7 @@ async fn lock_pypi_packages( (url_or_path, hash, false) } SourceDist::Directory(dir) => { - // Compute the hash of the package based on the source tree. - let hash = if dir.install_path.is_dir() { - Some( - PypiSourceTreeHashable::from_directory(&dir.install_path) - .into_diagnostic() - .context("failed to compute hash of pypi source tree")? - .hash(), - ) - } else { - None - }; + let hash = None; // process the path or url that we get back from uv let install_path = diff --git a/crates/pixi_core/src/lock_file/satisfiability/mod.rs b/crates/pixi_core/src/lock_file/satisfiability/mod.rs index b9afeb6774..09200d3cb4 100644 --- a/crates/pixi_core/src/lock_file/satisfiability/mod.rs +++ b/crates/pixi_core/src/lock_file/satisfiability/mod.rs @@ -1,3 +1,5 @@ +pub mod pypi_metadata; + use std::{ borrow::Cow, collections::{HashMap, HashSet}, @@ -5,11 +7,13 @@ use std::{ hash::Hash, path::{Path, PathBuf}, str::FromStr, + sync::LazyLock, }; use futures::stream::{FuturesUnordered, StreamExt}; use itertools::{Either, Itertools}; use miette::Diagnostic; +use once_cell::sync::OnceCell; use pep440_rs::VersionSpecifiers; use pixi_build_discovery::EnabledProtocols; use pixi_command_dispatcher::{ @@ -17,6 +21,7 @@ use pixi_command_dispatcher::{ DevSourceMetadataError, DevSourceMetadataSpec, SourceCheckoutError, SourceMetadataError, SourceMetadataSpec, }; +use pixi_config::Config; use pixi_git::url::RepositoryUrl; use pixi_manifest::{ FeaturesExt, @@ -37,24 +42,41 @@ use rattler_conda_types::{ ChannelUrl, GenericVirtualPackage, MatchSpec, Matches, NamedChannelOrUrl, PackageName, PackageRecord, ParseChannelError, ParseMatchSpecError, ParseStrictness::Lenient, Platform, }; -use rattler_lock::{ - LockedPackageRef, PackageHashes, PypiIndexes, PypiPackageData, PypiSourceTreeHashable, - UrlOrPath, -}; +use rattler_lock::{LockedPackageRef, PackageHashes, PypiIndexes, PypiPackageData, UrlOrPath}; use thiserror::Error; use typed_path::Utf8TypedPathBuf; use url::Url; +use uv_configuration::RAYON_INITIALIZE; use uv_distribution_filename::{DistExtension, ExtensionError, SourceDistExtension}; use uv_distribution_types::{RequirementSource, RequiresPython}; use uv_git_types::GitReference; -use uv_pypi_types::ParsedUrlError; +use uv_pypi_types::{ParsedUrlError, PyProjectToml}; use super::{ - PixiRecordsByName, PypiRecord, PypiRecordsByName, package_identifier::ConversionError, + CondaPrefixUpdater, PixiRecordsByName, PypiRecord, PypiRecordsByName, + outdated::{BuildCacheKey, PypiEnvironmentBuildCache}, + package_identifier::ConversionError, + resolve::build_dispatch::{LazyBuildDispatch, UvBuildDispatchParams}, }; use crate::workspace::{ - Environment, HasWorkspaceRef, errors::VariantsError, grouped_environment::GroupedEnvironment, + Environment, EnvironmentVars, HasWorkspaceRef, errors::VariantsError, + grouped_environment::GroupedEnvironment, +}; +use pixi_manifest::EnvironmentName; +use pixi_uv_context::UvResolutionContext; +use pixi_uv_conversions::{ + configure_insecure_hosts_for_tls_bypass, pypi_options_to_build_options, + pypi_options_to_index_locations, to_index_strategy, +}; +use pypi_modifiers::pypi_tags::{get_pypi_tags, is_python_record}; +use std::sync::Arc; +use uv_client::{BaseClientBuilder, Connectivity, FlatIndexClient, RegistryClientBuilder}; +use uv_distribution::DistributionDatabase; +use uv_distribution_types::{ + ConfigSettings, DependencyMetadata, DirectorySourceDist, Dist, HashPolicy, IndexUrl, SourceDist, }; +use uv_pep508; +use uv_resolver::FlatIndex; #[derive(Debug, Error, Diagnostic)] pub enum EnvironmentUnsat { @@ -222,6 +244,63 @@ impl Display for SourceTreeHashMismatch { } } +/// Describes what metadata changed for a local package. +#[derive(Debug, Error)] +pub enum LocalMetadataMismatch { + #[error("dependencies changed - added: [{added}], removed: [{removed}]", + added = format_requirements(added), + removed = format_requirements(removed))] + RequiresDist { + added: Vec, + removed: Vec, + }, + #[error("version changed from {locked} to {current}")] + Version { + locked: pep440_rs::Version, + current: pep440_rs::Version, + }, + #[error("requires-python changed from {locked:?} to {current:?}")] + RequiresPython { + locked: Option, + current: Option, + }, +} + +/// Formats a list of requirements, showing only the first 3 names. +fn format_requirements(reqs: &[pep508_rs::Requirement]) -> String { + const MAX_DISPLAY: usize = 3; + let names: Vec<_> = reqs + .iter() + .take(MAX_DISPLAY) + .map(|r| r.name.to_string()) + .collect(); + let formatted = names.join(", "); + if reqs.len() > MAX_DISPLAY { + format!("{}, ... and {} more", formatted, reqs.len() - MAX_DISPLAY) + } else { + formatted + } +} + +impl From for LocalMetadataMismatch { + fn from(mismatch: pypi_metadata::MetadataMismatch) -> Self { + match mismatch { + pypi_metadata::MetadataMismatch::RequiresDist(diff) => { + LocalMetadataMismatch::RequiresDist { + added: diff.added, + removed: diff.removed, + } + } + pypi_metadata::MetadataMismatch::Version { locked, current } => { + LocalMetadataMismatch::Version { locked, current } + } + pypi_metadata::MetadataMismatch::RequiresPython { locked, current } => { + LocalMetadataMismatch::RequiresPython { locked, current } + } + } + } +} + #[derive(Debug, Error, Diagnostic)] pub enum PlatformUnsat { #[error("the requirement '{0}' could not be satisfied (required by '{1}')")] @@ -320,6 +399,23 @@ pub enum PlatformUnsat { #[error("source tree hash for {0} does not match the hash in the lock-file")] SourceTreeHashMismatch(pep508_rs::PackageName, #[source] SourceTreeHashMismatch), + #[error("metadata for local package '{0}' has changed: {1}")] + LocalPackageMetadataMismatch(pep508_rs::PackageName, LocalMetadataMismatch), + + #[error("failed to read metadata for local package '{0}': {1}")] + FailedToReadLocalMetadata(pep508_rs::PackageName, String), + + #[error("failed to build metadata for local package '{0}': {1}")] + FailedToBuildLocalMetadata(pep508_rs::PackageName, String), + + #[error("local package '{0}' has dynamic {1} metadata that requires re-resolution")] + LocalPackageHasDynamicMetadata(pep508_rs::PackageName, &'static str), + + #[error( + "path-based package '{0}' has a hash in the lock-file, but hashes are no longer used for path packages" + )] + PathPackageHasUnexpectedHash(pep508_rs::PackageName), + #[error("the path '{0}, cannot be canonicalized")] FailedToCanonicalizePath(PathBuf, #[source] std::io::Error), @@ -475,7 +571,10 @@ impl PlatformUnsat { | PlatformUnsat::AsPep508Error(_, _) | PlatformUnsat::FailedToDetermineSourceTreeHash(_, _) | PlatformUnsat::PythonVersionMismatch(_, _, _) - | PlatformUnsat::SourceTreeHashMismatch(..), + | PlatformUnsat::SourceTreeHashMismatch(..) + | PlatformUnsat::LocalPackageMetadataMismatch(_, _) + | PlatformUnsat::FailedToReadLocalMetadata(_, _) + | PlatformUnsat::PathPackageHasUnexpectedHash(_), ) } } @@ -726,6 +825,21 @@ fn verify_pypi_indexes( Ok(()) } +/// Context for verifying platform satisfiability. +pub struct VerifySatisfiabilityContext<'a> { + pub environment: &'a Environment<'a>, + pub command_dispatcher: CommandDispatcher, + pub platform: Platform, + pub project_root: &'a Path, + pub uv_context: &'a OnceCell, + pub config: &'a Config, + pub project_env_vars: HashMap, + pub build_caches: &'a mut HashMap>, + /// Cache for static metadata extracted from pyproject.toml files. + /// This is shared across platforms since static metadata is platform-independent. + pub static_metadata_cache: &'a mut HashMap, +} + /// Verifies that the package requirements of the specified `environment` can be /// satisfied with the packages present in the lock-file. /// @@ -737,22 +851,24 @@ fn verify_pypi_indexes( /// This function returns a [`PlatformUnsat`] error if a verification issue /// occurred. The [`PlatformUnsat`] error should contain enough information for /// the user and developer to figure out what went wrong. +/// pub async fn verify_platform_satisfiability( - environment: &Environment<'_>, - command_dispatcher: CommandDispatcher, + ctx: &mut VerifySatisfiabilityContext<'_>, locked_environment: rattler_lock::Environment<'_>, - platform: Platform, - project_root: &Path, ) -> Result> { // Convert the lock file into a list of conda and pypi packages let mut pixi_records: Vec = Vec::new(); let mut pypi_packages: Vec = Vec::new(); - for package in locked_environment.packages(platform).into_iter().flatten() { + for package in locked_environment + .packages(ctx.platform) + .into_iter() + .flatten() + { match package { LockedPackageRef::Conda(conda) => { let url = conda.location().clone(); pixi_records.push( - PixiRecord::from_conda_package_data(conda.clone(), project_root) + PixiRecord::from_conda_package_data(conda.clone(), ctx.project_root) .map_err(|e| PlatformUnsat::CorruptedEntry(url.to_string(), e))?, ); } @@ -765,7 +881,7 @@ pub async fn verify_platform_satisfiability( // to reflect new purls for pypi packages // we need to invalidate the locked environment // if all conda packages have empty purls - if environment.has_pypi_dependencies() + if ctx.environment.has_pypi_dependencies() && pypi_packages.is_empty() && pixi_records .iter() @@ -779,7 +895,7 @@ pub async fn verify_platform_satisfiability( // Create a lookup table from package name to package record. Returns an error // if we find a duplicate entry for a record - let pixi_records_by_name = match PixiRecordsByName::from_unique_iter(pixi_records) { + let pixi_records_by_name = match PixiRecordsByName::from_unique_iter(pixi_records.clone()) { Ok(pixi_records) => pixi_records, Err(duplicate) => { return Err(Box::new(PlatformUnsat::DuplicateEntry( @@ -799,13 +915,39 @@ pub async fn verify_platform_satisfiability( } }; + // Get host platform records for building (we can only run Python on the host platform) + let best_platform = ctx.environment.best_platform(); + let building_pixi_records = if ctx.platform == best_platform { + // Same platform, reuse the records + Ok(pixi_records_by_name.clone()) + } else { + // Different platform - extract host platform records for building + let mut host_pixi_records: Vec = Vec::new(); + for package in locked_environment + .packages(best_platform) + .into_iter() + .flatten() + { + if let LockedPackageRef::Conda(conda) = package { + let url = conda.location().clone(); + host_pixi_records.push( + PixiRecord::from_conda_package_data(conda.clone(), ctx.project_root) + .map_err(|e| PlatformUnsat::CorruptedEntry(url.to_string(), e))?, + ); + } + } + PixiRecordsByName::from_unique_iter(host_pixi_records).map_err(|duplicate| { + PlatformUnsat::DuplicateEntry(duplicate.package_record().name.as_source().to_string()) + }) + }; + + // Run satisfiability check - for local packages with dynamic metadata, + // we use UV infrastructure to build metadata if available. verify_package_platform_satisfiability( - environment, - command_dispatcher, + ctx, &pixi_records_by_name, &pypi_records_by_name, - platform, - project_root, + building_pixi_records, ) .await } @@ -1468,35 +1610,36 @@ async fn resolve_single_dev_dependency( } pub(crate) async fn verify_package_platform_satisfiability( - environment: &Environment<'_>, - command_dispatcher: CommandDispatcher, + ctx: &mut VerifySatisfiabilityContext<'_>, locked_pixi_records: &PixiRecordsByName, locked_pypi_environment: &PypiRecordsByName, - platform: Platform, - project_root: &Path, + building_pixi_records: Result, ) -> Result> { // Determine the dependencies requested by the environment - let environment_dependencies = environment - .combined_dependencies(Some(platform)) + let environment_dependencies = ctx + .environment + .combined_dependencies(Some(ctx.platform)) .into_specs() .map(|(package_name, spec)| Dependency::Input(package_name, spec, "".into())) .collect_vec(); // Get the dev dependencies for this platform - let dev_dependencies = environment - .combined_dev_dependencies(Some(platform)) + let dev_dependencies = ctx + .environment + .combined_dev_dependencies(Some(ctx.platform)) .into_specs() .collect_vec(); // retrieve dependency-overrides // map it to (name => requirement) for later matching - let dependency_overrides = environment + let dependency_overrides = ctx + .environment .pypi_options() .dependency_overrides .unwrap_or_default() .into_iter() .map(|(name, req)| -> Result<_, Box> { - let uv_req = as_uv_req(&req, name.as_source(), project_root).map_err(|e| { + let uv_req = as_uv_req(&req, name.as_source(), ctx.project_root).map_err(|e| { Box::new(PlatformUnsat::AsPep508Error( name.as_normalized().clone(), e, @@ -1507,8 +1650,10 @@ pub(crate) async fn verify_package_platform_satisfiability( .collect::, _>>()?; // Transform from PyPiPackage name into UV Requirement type - let pypi_requirements = environment - .pypi_dependencies(Some(platform)) + let project_root = ctx.project_root; + let pypi_requirements = ctx + .environment + .pypi_dependencies(Some(ctx.platform)) .iter() .flat_map(|(name, reqs)| { reqs.iter().map(move |req| { @@ -1532,18 +1677,24 @@ pub(crate) async fn verify_package_platform_satisfiability( } // Create a list of virtual packages by name - let virtual_packages = environment - .virtual_packages(platform) + let virtual_packages = ctx + .environment + .virtual_packages(ctx.platform) .into_iter() .map(GenericVirtualPackage::from) .map(|vpkg| (vpkg.name.clone(), vpkg)) .collect::>(); // The list of channels and platforms we need for this task - let channels = environment.channels().into_iter().cloned().collect_vec(); + let channels = ctx + .environment + .channels() + .into_iter() + .cloned() + .collect_vec(); // Get the channel configuration - let channel_config = environment.workspace().channel_config(); + let channel_config = ctx.environment.workspace().channel_config(); // Resolve the channel URLs for the channels we need. let channels = channels @@ -1556,13 +1707,14 @@ pub(crate) async fn verify_package_platform_satisfiability( let VariantConfig { variant_configuration, variant_files, - } = environment + } = ctx + .environment .workspace() - .variants(platform) + .variants(ctx.platform) .map_err(|e| Box::new(PlatformUnsat::Variants(e)))?; let build_environment = - BuildEnvironment::simple(platform, virtual_packages.values().cloned().collect()); + BuildEnvironment::simple(ctx.platform, virtual_packages.values().cloned().collect()); // Get all source records from the lock file for metadata verification let source_records: Vec<_> = locked_pixi_records @@ -1574,7 +1726,7 @@ pub(crate) async fn verify_package_platform_satisfiability( // Resolve dev dependencies and verify source metadata in parallel let dev_deps_future = resolve_dev_dependencies( dev_dependencies, - &command_dispatcher, + &ctx.command_dispatcher, &channel_config, &channels, &build_environment, @@ -1584,13 +1736,13 @@ pub(crate) async fn verify_package_platform_satisfiability( let source_metadata_future = verify_source_metadata( source_records, - command_dispatcher.clone(), + ctx.command_dispatcher.clone(), channel_config.clone(), channels.clone(), variant_configuration.clone(), variant_files.clone(), virtual_packages.values().cloned().collect(), - platform, + ctx.platform, ); let (resolved_dev_dependencies, source_metadata_result) = @@ -1613,7 +1765,7 @@ pub(crate) async fn verify_package_platform_satisfiability( // Determine the marker environment from the python interpreter package. let marker_environment = python_interpreter_record - .map(|interpreter| determine_marker_environment(platform, &interpreter.package_record)) + .map(|interpreter| determine_marker_environment(ctx.platform, &interpreter.package_record)) .transpose() .map_err(|err| { Box::new(PlatformUnsat::FailedToDetermineMarkerEnvironment( @@ -1802,9 +1954,11 @@ pub(crate) async fn verify_package_platform_satisfiability( .unwrap_or(requirement); if requirement.is_editable() { - if let Err(err) = - pypi_satifisfies_editable(&requirement, &record.0, project_root) - { + if let Err(err) = pypi_satifisfies_editable( + &requirement, + &record.0, + ctx.project_root, + ) { delayed_pypi_error.get_or_insert(err); } @@ -1813,7 +1967,7 @@ pub(crate) async fn verify_package_platform_satisfiability( if let Err(err) = pypi_satifisfies_requirement( &requirement, &record.0, - project_root, + ctx.project_root, ) { delayed_pypi_error.get_or_insert(err); } @@ -1916,30 +2070,90 @@ pub(crate) async fn verify_package_platform_satisfiability( let absolute_path = if path.is_absolute() { Cow::Borrowed(Path::new(path.as_str())) } else { - Cow::Owned(project_root.join(Path::new(path.as_str()))) + Cow::Owned(ctx.project_root.join(Path::new(path.as_str()))) }; if absolute_path.is_dir() { - match PypiSourceTreeHashable::from_directory(&absolute_path) - .map(|hashable| hashable.hash()) + // If a hash is present (from an older lock file), trigger re-resolution to remove it. + if record.0.hash.is_some() { + delayed_pypi_error.get_or_insert_with(|| { + Box::new(PlatformUnsat::PathPackageHasUnexpectedHash( + record.0.name.clone(), + )) + }); + } + // Read metadata using UV's DistributionDatabase. + // This first tries database.requires_dist() for static extraction, + // then falls back to building the wheel if needed. + let uv_ctx = ctx + .uv_context + .get_or_try_init(|| UvResolutionContext::from_config(ctx.config)) + .map_err(|e| { + Box::new(PlatformUnsat::FailedToReadLocalMetadata( + record.0.name.clone(), + format!("failed to initialize UV context: {e}"), + )) + })?; + + let mut build_ctx = BuildMetadataContext { + environment: ctx.environment, + locked_pixi_records, + platform: ctx.platform, + project_root: ctx.project_root, + uv_context: uv_ctx, + project_env_vars: &ctx.project_env_vars, + command_dispatcher: ctx.command_dispatcher.clone(), + build_caches: ctx.build_caches, + building_pixi_records: &building_pixi_records, + static_metadata_cache: ctx.static_metadata_cache, + }; + + match read_local_package_metadata( + &absolute_path, + &record.0.name, + record.0.editable, + &mut build_ctx, + ) + .await { - Ok(hashable) if Some(&hashable) != record.0.hash.as_ref() => { - delayed_pypi_error.get_or_insert_with(|| { - Box::new(PlatformUnsat::SourceTreeHashMismatch( - record.0.name.clone(), - SourceTreeHashMismatch { - computed: hashable, - locked: record.0.hash.clone(), + Ok(current_metadata) => { + // Compare metadata with locked metadata + if let Some(mismatch) = pypi_metadata::compare_metadata( + &record.0, + ¤t_metadata, + ) { + let local_mismatch = match mismatch { + pypi_metadata::MetadataMismatch::RequiresDist(diff) => { + LocalMetadataMismatch::RequiresDist { + added: diff.added, + removed: diff.removed, + } + } + pypi_metadata::MetadataMismatch::Version { + locked, + current, + } => LocalMetadataMismatch::Version { locked, current }, + pypi_metadata::MetadataMismatch::RequiresPython { + locked, + current, + } => LocalMetadataMismatch::RequiresPython { + locked, + current, }, - )) - }); + }; + delayed_pypi_error.get_or_insert_with(|| { + Box::new(PlatformUnsat::LocalPackageMetadataMismatch( + record.0.name.clone(), + local_mismatch, + )) + }); + } } - Ok(_) => {} - Err(err) => { + Err(e) => { delayed_pypi_error.get_or_insert_with(|| { - Box::new(PlatformUnsat::FailedToDetermineSourceTreeHash( + Box::new(PlatformUnsat::FailedToReadLocalMetadata( record.0.name.clone(), - err, + format!("failed to read metadata: {e}"), )) }); } @@ -2068,7 +2282,7 @@ pub(crate) async fn verify_package_platform_satisfiability( // the same path-based package. // Verify the pixi build package's package_build_source matches the manifest. - verify_build_source_matches_manifest(environment, locked_pixi_records)?; + verify_build_source_matches_manifest(ctx.environment, locked_pixi_records)?; Ok(VerifiedIndividualEnvironment { expected_conda_packages, @@ -2091,6 +2305,373 @@ pub struct CondaPackageIdx(usize); #[repr(transparent)] pub struct PypiPackageIdx(usize); +/// Context for building dynamic metadata for local packages. +struct BuildMetadataContext<'a> { + environment: &'a Environment<'a>, + locked_pixi_records: &'a PixiRecordsByName, + platform: Platform, + project_root: &'a Path, + uv_context: &'a UvResolutionContext, + project_env_vars: &'a HashMap, + command_dispatcher: CommandDispatcher, + build_caches: &'a mut HashMap>, + building_pixi_records: &'a Result, + static_metadata_cache: &'a mut HashMap, +} + +/// Read metadata for a local directory package using UV's DistributionDatabase. +/// +/// This first tries to extract metadata statically via `database.requires_dist()`, +/// which parses the pyproject.toml without building. If static extraction fails +/// (e.g., dynamic dependencies), it falls back to building the wheel metadata. +/// +/// Static metadata is cached across platforms since it doesn't depend on the platform. +async fn read_local_package_metadata( + directory: &Path, + package_name: &pep508_rs::PackageName, + editable: bool, + ctx: &mut BuildMetadataContext<'_>, +) -> Result { + // Check if we already have static metadata cached for this directory + if let Some(cached_metadata) = ctx.static_metadata_cache.get(directory) { + tracing::debug!("Package {} - using cached static metadata", package_name); + return Ok(cached_metadata.clone()); + } + + let pypi_options = ctx.environment.pypi_options(); + + // Find the Python interpreter from locked records + let python_record = ctx + .locked_pixi_records + .records + .iter() + .find(|r| is_python_record(r)) + .ok_or_else(|| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + "No Python interpreter found in locked packages".to_string(), + ) + })?; + + // Create marker environment for the target platform + let marker_environment = determine_marker_environment(ctx.platform, python_record.as_ref()) + .map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to determine marker environment: {e}"), + ) + })?; + + let index_strategy = to_index_strategy(pypi_options.index_strategy.as_ref()); + + // Get or create cache entry for this environment and host platform + // We use best_platform() since the build prefix is shared across all target platforms + let best_platform = ctx.environment.best_platform(); + let cache_key = BuildCacheKey::new(ctx.environment.name().clone(), best_platform); + let cache = ctx.build_caches.entry(cache_key).or_default(); + + let index_locations = pypi_options_to_index_locations(&pypi_options, ctx.project_root) + .map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to setup index locations: {e}"), + ) + })?; + + let build_options = pypi_options_to_build_options( + &pypi_options.no_build.clone().unwrap_or_default(), + &pypi_options.no_binary.clone().unwrap_or_default(), + ) + .map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to create build options: {e}"), + ) + })?; + + let dependency_metadata = DependencyMetadata::default(); + + // Configure insecure hosts + let allow_insecure_hosts = configure_insecure_hosts_for_tls_bypass( + ctx.uv_context.allow_insecure_host.clone(), + ctx.uv_context.tls_no_verify, + &index_locations, + ); + + let registry_client = { + let base_client_builder = BaseClientBuilder::default() + .allow_insecure_host(allow_insecure_hosts.clone()) + .markers(&marker_environment) + .keyring(ctx.uv_context.keyring_provider) + .connectivity(Connectivity::Online) + .native_tls(ctx.uv_context.use_native_tls) + .extra_middleware(ctx.uv_context.extra_middleware.clone()); + + let mut uv_client_builder = + RegistryClientBuilder::new(base_client_builder, ctx.uv_context.cache.clone()) + .index_locations(index_locations.clone()) + .index_strategy(index_strategy); + + for p in &ctx.uv_context.proxies { + uv_client_builder = uv_client_builder.proxy(p.clone()) + } + + Arc::new(uv_client_builder.build()) + }; + + // Get tags for this platform (needed for FlatIndex) + let system_requirements = ctx.environment.system_requirements(); + let tags = + get_pypi_tags(ctx.platform, &system_requirements, python_record.as_ref()).map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to determine pypi tags: {e}"), + ) + })?; + + let flat_index = { + let flat_index_client = FlatIndexClient::new( + registry_client.cached_client(), + Connectivity::Online, + &ctx.uv_context.cache, + ); + let flat_index_urls: Vec<&IndexUrl> = index_locations + .flat_indexes() + .map(|index| index.url()) + .collect(); + let flat_index_entries = flat_index_client + .fetch_all(flat_index_urls.into_iter()) + .await + .map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to fetch flat index entries: {e}"), + ) + })?; + FlatIndex::from_entries( + flat_index_entries, + Some(&tags), + &ctx.uv_context.hash_strategy, + &build_options, + ) + }; + + // Create build dispatch parameters + let config_settings = ConfigSettings::default(); + let build_params = UvBuildDispatchParams::new( + ®istry_client, + &ctx.uv_context.cache, + &index_locations, + &flat_index, + &dependency_metadata, + &config_settings, + &build_options, + &ctx.uv_context.hash_strategy, + ) + .with_index_strategy(index_strategy) + .with_workspace_cache(ctx.uv_context.workspace_cache.clone()) + .with_shared_state(ctx.uv_context.shared_state.fork()) + .with_source_strategy(ctx.uv_context.source_strategy) + .with_concurrency(ctx.uv_context.concurrency); + + // Get or create conda prefix updater for the environment + // Use best_platform() because we can only install/run Python on the host platform + let conda_prefix_updater = cache + .conda_prefix_updater + .get_or_try_init(|| { + let prefix_platform = ctx.environment.best_platform(); + let group = GroupedEnvironment::Environment(ctx.environment.clone()); + let virtual_packages = ctx.environment.virtual_packages(prefix_platform); + + // Force the initialization of the rayon thread pool to avoid implicit creation + // by the uv. + LazyLock::force(&RAYON_INITIALIZE); + + CondaPrefixUpdater::builder( + group, + prefix_platform, + virtual_packages + .into_iter() + .map(GenericVirtualPackage::from) + .collect(), + ctx.command_dispatcher.clone(), + ) + .finish() + .map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to create conda prefix updater: {e}"), + ) + }) + })? + .clone(); + + // Use cached lazy build dispatch dependencies + // Use building_pixi_records (host platform) for installing Python and building, + // since we can only run binaries on the host platform + let building_records: miette::Result> = ctx + .building_pixi_records + .as_ref() + .map(|r| r.records.clone()) + .map_err(|e| miette::miette!("{}", e)); + let lazy_build_dispatch = LazyBuildDispatch::new( + build_params, + conda_prefix_updater, + ctx.project_env_vars.clone(), + ctx.environment.clone(), + building_records, + pypi_options.no_build_isolation.clone(), + &cache.lazy_build_dispatch_deps, + None, + false, + ); + + // Create distribution database + let database = DistributionDatabase::new( + ®istry_client, + &lazy_build_dispatch, + ctx.uv_context.concurrency.downloads, + ); + + // Try to read pyproject.toml and use requires_dist() first + let pyproject_path = directory.join("pyproject.toml"); + if let Ok(contents) = fs_err::read_to_string(&pyproject_path) { + // Parse with toml_edit for version/requires_python + if let Ok(toml) = contents.parse::() { + let version = toml + .get("project") + .and_then(|p| p.get("version")) + .and_then(|v| v.as_str()) + .and_then(|v| v.parse::().ok()); + + let requires_python = toml + .get("project") + .and_then(|p| p.get("requires-python")) + .and_then(|v| v.as_str()) + .and_then(|rp| rp.parse::().ok()); + + // Parse pyproject.toml with UV's parser for requires_dist + if let Ok(pyproject_toml) = PyProjectToml::from_toml(&contents) { + // Try to extract requires_dist statically using UV's database + match ( + database.requires_dist(directory, &pyproject_toml).await, + version, + ) { + (Ok(Some(requires_dist)), Some(version)) if !requires_dist.dynamic => { + tracing::debug!( + "Package {} - extracted requires_dist using database.requires_dist(). Dynamic: {}", + package_name, + requires_dist.dynamic + ); + + // Convert uv requirements to pep508_rs requirements + let requires_dist_converted: Result, _> = + requires_dist + .requires_dist + .iter() + .map(|req| { + let req_str = req.to_string(); + req_str.parse::().map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Invalid requirement: {e}"), + ) + }) + }) + .collect(); + + if let Ok(requires_dist_vec) = requires_dist_converted { + let metadata = pypi_metadata::LocalPackageMetadata { + version, + requires_dist: requires_dist_vec, + requires_python, + }; + // Cache the static metadata for reuse on other platforms + ctx.static_metadata_cache + .insert(directory.to_path_buf(), metadata.clone()); + return Ok(metadata); + } + } + (Ok(Some(requires_dist)), _) => { + // Dynamic dependencies or missing/dynamic version - need to build wheel for accurate metadata + tracing::debug!( + "Package {} - requires_dist is dynamic (dynamic={}) or version is missing/dynamic, falling back to wheel build", + package_name, + requires_dist.dynamic, + ); + } + (Ok(None), _) => { + tracing::debug!( + "Package {} - requires_dist() returned None, falling back to build", + package_name + ); + } + (Err(e), _) => { + tracing::debug!( + "Package {} - requires_dist() failed: {}, falling back to build", + package_name, + e + ); + } + } + } + } + } + + // Fall back to building the wheel metadata + tracing::debug!( + "Package {} - building wheel metadata with get_or_build_wheel_metadata()", + package_name + ); + + // Create the directory source dist + let uv_package_name = + uv_normalize::PackageName::from_str(package_name.as_ref()).map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Invalid package name: {e}"), + ) + })?; + + let install_path = directory.to_path_buf(); + let file_url = url::Url::from_file_path(&install_path).map_err(|_| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to convert path to URL: {}", install_path.display()), + ) + })?; + let verbatim_url = uv_pep508::VerbatimUrl::from_url(file_url.into()); + let source_dist = DirectorySourceDist { + name: uv_package_name, + install_path: install_path.into_boxed_path(), + editable: Some(editable), + r#virtual: Some(false), + url: verbatim_url, + }; + + // Build the metadata + let metadata_response = database + .get_or_build_wheel_metadata( + &Dist::Source(SourceDist::Directory(source_dist)), + HashPolicy::None, + ) + .await + .map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to build metadata: {e}"), + ) + })?; + + // Convert UV metadata to our format + pypi_metadata::from_uv_metadata(&metadata_response.metadata).map_err(|e| { + PlatformUnsat::FailedToReadLocalMetadata( + package_name.clone(), + format!("Failed to convert metadata: {e}"), + ) + }) +} + fn find_matching_package( locked_pixi_records: &PixiRecordsByName, virtual_packages: &HashMap, @@ -2391,6 +2972,17 @@ mod tests { command_dispatcher.finish() }; + // Create UV context lazily for building dynamic metadata + let uv_context: OnceCell = OnceCell::new(); + + // Create build caches for sharing between satisfiability and resolution + let mut build_caches: HashMap> = + HashMap::new(); + + // Create static metadata cache for sharing across platforms + let mut static_metadata_cache: HashMap = + HashMap::new(); + // Verify individual environment satisfiability for env in project.environments() { let locked_env = lock_file @@ -2400,15 +2992,22 @@ mod tests { .map_err(|e| LockfileUnsat::Environment(env.name().to_string(), e))?; for platform in env.platforms() { - let verified_env = verify_platform_satisfiability( - &env, - command_dispatcher.clone(), - locked_env, + let mut ctx = VerifySatisfiabilityContext { + environment: &env, + command_dispatcher: command_dispatcher.clone(), platform, - project.root(), - ) - .await - .map_err(|e| LockfileUnsat::PlatformUnsat(env.name().to_string(), platform, *e))?; + project_root: project.root(), + uv_context: &uv_context, + config: project.config(), + project_env_vars: project.env_vars().clone(), + build_caches: &mut build_caches, + static_metadata_cache: &mut static_metadata_cache, + }; + let verified_env = verify_platform_satisfiability(&mut ctx, locked_env) + .await + .map_err(|e| { + LockfileUnsat::PlatformUnsat(env.name().to_string(), platform, *e) + })?; individual_verified_envs.insert((env.name(), platform), verified_env); } @@ -2479,9 +3078,7 @@ mod tests { #[rstest] #[tokio::test] #[traced_test] - async fn test_example_satisfiability( - #[files("../../examples/**/p*.toml")] manifest_path: PathBuf, - ) { + async fn q(#[files("../../examples/**/p*.toml")] manifest_path: PathBuf) { // If a pyproject.toml is present check for `tool.pixi` in the file to avoid // testing of non-pixi files if manifest_path.file_name().unwrap() == "pyproject.toml" { diff --git a/crates/pixi_core/src/lock_file/satisfiability/pypi_metadata.rs b/crates/pixi_core/src/lock_file/satisfiability/pypi_metadata.rs new file mode 100644 index 0000000000..43fc63734d --- /dev/null +++ b/crates/pixi_core/src/lock_file/satisfiability/pypi_metadata.rs @@ -0,0 +1,228 @@ +//! Module for reading and comparing PyPI package metadata from local source trees. +//! +//! This module provides functionality to: +//! 1. Read metadata from local pyproject.toml files +//! 2. Compare locked metadata against current source tree metadata +use std::collections::BTreeSet; +use std::str::FromStr; + +use pep440_rs::{Version, VersionSpecifiers}; +use pep508_rs::Requirement; +use rattler_lock::PypiPackageData; +use thiserror::Error; + +/// Metadata extracted from a local package source tree. +#[derive(Debug, Clone)] +pub struct LocalPackageMetadata { + /// The version of the package. + pub version: Version, + /// The package dependencies. + pub requires_dist: Vec, + /// The Python version requirement. + pub requires_python: Option, +} + +/// Error that can occur when reading metadata from a source tree. +#[derive(Debug, Error)] +pub enum MetadataReadError { + /// Failed to parse the pyproject.toml file. + #[error("failed to parse pyproject.toml: {0}")] + ParseError(String), +} + +/// The result of comparing locked metadata against current metadata. +#[derive(Debug)] +pub enum MetadataMismatch { + /// The requires_dist (dependencies) have changed. + RequiresDist(RequiresDistDiff), + /// The version has changed. + Version { locked: Version, current: Version }, + /// The requires_python has changed. + RequiresPython { + locked: Option, + current: Option, + }, +} + +/// Describes the difference in requires_dist between locked and current metadata. +#[derive(Debug)] +pub struct RequiresDistDiff { + /// Dependencies that were added. + pub added: Vec, + /// Dependencies that were removed. + pub removed: Vec, +} + +/// Compare locked metadata against current metadata from the source tree. +/// +/// Returns `None` if the metadata matches, or `Some(MetadataMismatch)` describing +/// what changed. +pub fn compare_metadata( + locked: &PypiPackageData, + current: &LocalPackageMetadata, +) -> Option { + // Compare requires_dist (as normalized sets) + let locked_deps: BTreeSet = locked + .requires_dist + .iter() + .map(normalize_requirement) + .collect(); + + let current_deps: BTreeSet = current + .requires_dist + .iter() + .map(normalize_requirement) + .collect(); + + if locked_deps != current_deps { + // Calculate the diff + let added: Vec = current + .requires_dist + .iter() + .filter(|r| !locked_deps.contains(&normalize_requirement(r))) + .cloned() + .collect(); + + let removed: Vec = locked + .requires_dist + .iter() + .filter(|r| !current_deps.contains(&normalize_requirement(r))) + .cloned() + .collect(); + + return Some(MetadataMismatch::RequiresDist(RequiresDistDiff { + added, + removed, + })); + } + + // Compare version + if locked.version != current.version { + return Some(MetadataMismatch::Version { + locked: locked.version.clone(), + current: current.version.clone(), + }); + } + + // Compare requires_python + if locked.requires_python != current.requires_python { + return Some(MetadataMismatch::RequiresPython { + locked: locked.requires_python.clone(), + current: current.requires_python.clone(), + }); + } + + None +} + +/// Normalize a requirement for comparison purposes. +/// +/// This ensures that semantically equivalent requirements compare equal, +/// regardless of formatting differences (e.g., whitespace, order of extras). +fn normalize_requirement(req: &Requirement) -> String { + // Use the canonical string representation + // The pep508_rs library already normalizes package names and versions + req.to_string() +} + +/// Convert UV metadata to LocalPackageMetadata for comparison. +/// +/// This is used when we build metadata using UV's DistributionDatabase +/// for packages with dynamic metadata. +pub fn from_uv_metadata( + metadata: &uv_distribution::Metadata, +) -> Result { + // Convert version + let version = pep440_rs::Version::from_str(&metadata.version.to_string()) + .map_err(|e| MetadataReadError::ParseError(format!("invalid version: {e}")))?; + + // Convert requires_dist + let requires_dist: Vec = metadata + .requires_dist + .iter() + .map(|req| { + let req_str = req.to_string(); + req_str + .parse::() + .map_err(|e| MetadataReadError::ParseError(format!("invalid requirement: {e}"))) + }) + .collect::, _>>()?; + + // Convert requires_python + let requires_python = metadata + .requires_python + .as_ref() + .map(|rp| { + pep440_rs::VersionSpecifiers::from_str(&rp.to_string()) + .map_err(|e| MetadataReadError::ParseError(format!("invalid requires-python: {e}"))) + }) + .transpose()?; + + Ok(LocalPackageMetadata { + version, + requires_dist, + requires_python, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use std::str::FromStr; + + #[test] + fn test_normalize_requirement() { + let req1: Requirement = "numpy>=1.0".parse().unwrap(); + let req2: Requirement = "numpy >= 1.0".parse().unwrap(); + // Note: These may or may not be equal depending on pep508_rs normalization + // The important thing is we consistently compare them + assert_eq!(normalize_requirement(&req1), normalize_requirement(&req1)); + let _ = req2; // silence unused warning + } + + #[test] + fn test_compare_metadata_same() { + let locked = PypiPackageData { + name: "test-package".parse().unwrap(), + version: Version::from_str("1.0.0").unwrap(), + requires_dist: vec!["numpy>=1.0".parse().unwrap()], + requires_python: Some(VersionSpecifiers::from_str(">=3.8").unwrap()), + location: rattler_lock::UrlOrPath::Url(url::Url::parse("file:///test").unwrap()), + hash: None, + editable: false, + }; + + let current = LocalPackageMetadata { + version: Version::from_str("1.0.0").unwrap(), + requires_dist: vec!["numpy>=1.0".parse().unwrap()], + requires_python: Some(VersionSpecifiers::from_str(">=3.8").unwrap()), + }; + + assert!(compare_metadata(&locked, ¤t).is_none()); + } + + #[test] + fn test_compare_metadata_different_deps() { + let locked = PypiPackageData { + name: "test-package".parse().unwrap(), + version: Version::from_str("1.0.0").unwrap(), + requires_dist: vec!["numpy>=1.0".parse().unwrap()], + requires_python: None, + location: rattler_lock::UrlOrPath::Url(url::Url::parse("file:///test").unwrap()), + hash: None, + editable: false, + }; + + let current = LocalPackageMetadata { + version: Version::from_str("1.0.0").unwrap(), + requires_dist: vec![ + "numpy>=1.0".parse().unwrap(), + "pandas>=2.0".parse().unwrap(), // Added + ], + requires_python: None, + }; + + let mismatch = compare_metadata(&locked, ¤t); + assert!(matches!(mismatch, Some(MetadataMismatch::RequiresDist(_)))); + } +} diff --git a/crates/pixi_core/src/lock_file/update.rs b/crates/pixi_core/src/lock_file/update.rs index d11598b122..3b29c07403 100644 --- a/crates/pixi_core/src/lock_file/update.rs +++ b/crates/pixi_core/src/lock_file/update.rs @@ -1,6 +1,6 @@ use std::{ cmp::PartialEq, - collections::{BTreeMap, HashMap, HashSet, hash_map::Entry}, + collections::{BTreeMap, HashMap, HashSet}, future::{Future, ready}, iter, path::PathBuf, @@ -289,6 +289,7 @@ impl Workspace { io_concurrency_limit: IoConcurrencyLimit::default(), command_dispatcher, glob_hash_cache, + build_caches: Default::default(), }, false, )); @@ -305,6 +306,7 @@ impl Workspace { tracing::info!("the lock-file is up-to-date"); // If no-environment is outdated we can return early. + // Pass the build_caches even if empty, in case conda_prefix needs them return Ok(( LockFileDerivedData { workspace: self, @@ -312,10 +314,11 @@ impl Workspace { package_cache, updated_conda_prefixes: Default::default(), updated_pypi_prefixes: Default::default(), - uv_context: Default::default(), + uv_context: outdated.uv_context, io_concurrency_limit: IoConcurrencyLimit::default(), command_dispatcher, glob_hash_cache, + build_caches: outdated.build_caches, }, false, )); @@ -485,6 +488,12 @@ pub struct LockFileDerivedData<'p> { /// An object that caches input hashes pub glob_hash_cache: GlobHashCache, + + /// Per-environment-platform build caches for sharing resources (CondaPrefixUpdater, etc.) + pub build_caches: HashMap< + lock_file::outdated::BuildCacheKey, + Arc, + >, } /// The mode to use when updating a prefix. @@ -851,18 +860,31 @@ impl<'p> LockFileDerivedData<'p> { // Create object to update the prefix let group = GroupedEnvironment::Environment(environment.clone()); let platform = environment.best_platform(); - let virtual_packages = environment.virtual_packages(platform); - let conda_prefix_updater = CondaPrefixUpdater::builder( - group, - platform, - virtual_packages - .into_iter() - .map(GenericVirtualPackage::from) - .collect(), - self.command_dispatcher.clone(), - ) - .finish()?; + // Use cached conda_prefix_updater if available, otherwise create new + let cache_key = + lock_file::outdated::BuildCacheKey::new(environment.name().clone(), platform); + let conda_prefix_updater = match self + .build_caches + .get(&cache_key) + .and_then(|c| c.conda_prefix_updater.get().cloned()) + { + Some(updater) => updater, + None => { + let virtual_packages = environment.virtual_packages(platform); + + CondaPrefixUpdater::builder( + group, + platform, + virtual_packages + .into_iter() + .map(GenericVirtualPackage::from) + .collect(), + self.command_dispatcher.clone(), + ) + .finish()? + } + }; // Get the locked environment from the lock-file. let locked_env = self.locked_env(environment)?; @@ -1666,8 +1688,6 @@ impl<'p> UpdateContext<'p> { } // Spawn tasks to update the pypi packages. - let uv_context = once_cell::sync::OnceCell::new(); - let mut pypi_conda_prefix_updaters = HashMap::new(); for (environment, platform) in self.outdated_envs .pypi @@ -1711,29 +1731,9 @@ impl<'p> UpdateContext<'p> { .get_latest_group_repodata_records(&group, environment.best_platform()) .ok_or_else(|| make_unsupported_pypi_platform_error(environment, false)); - // Creates an object to initiate an update at a later point. Make sure to only - // create a single entry if we are solving for multiple platforms. - let conda_prefix_updater = - match pypi_conda_prefix_updaters.entry(environment.name().clone()) { - Entry::Vacant(entry) => { - let prefix_platform = environment.best_platform(); - let conda_prefix_updater = CondaPrefixUpdater::builder( - group.clone(), - prefix_platform, - environment - .virtual_packages(prefix_platform) - .into_iter() - .map(GenericVirtualPackage::from) - .collect(), - self.command_dispatcher.clone(), - ) - .finish()?; - entry.insert(conda_prefix_updater).clone() - } - Entry::Occupied(entry) => entry.get().clone(), - }; - - let uv_context = uv_context + let uv_context = self + .outdated_envs + .uv_context .get_or_try_init(|| UvResolutionContext::from_config(project.config()))? .clone(); @@ -1745,6 +1745,16 @@ impl<'p> UpdateContext<'p> { .unwrap_or_default(); // Spawn a task to solve the pypi environment + let cache_key = + lock_file::outdated::BuildCacheKey::new(environment.name().clone(), platform); + + let build_cache = self + .outdated_envs + .build_caches + .get(&cache_key) + .cloned() + .unwrap_or_default(); + let pypi_solve_future = spawn_solve_pypi_task( uv_context, group.clone(), @@ -1753,11 +1763,12 @@ impl<'p> UpdateContext<'p> { platform, repodata_solve_platform_future, repodata_building_env, - conda_prefix_updater, + self.command_dispatcher.clone(), self.pypi_solve_semaphore.clone(), project.root().to_path_buf(), locked_group_records, self.no_install, + build_cache, ); pending_futures.push(pypi_solve_future.boxed_local()); @@ -2066,10 +2077,11 @@ impl<'p> UpdateContext<'p> { .collect(), package_cache: self.package_cache, updated_pypi_prefixes: Default::default(), - uv_context, + uv_context: self.outdated_envs.uv_context, io_concurrency_limit: self.io_concurrency_limit, command_dispatcher: self.command_dispatcher, glob_hash_cache: self.glob_hash_cache, + build_caches: self.outdated_envs.build_caches, }) } } @@ -2531,11 +2543,12 @@ async fn spawn_solve_pypi_task<'p>( platform: Platform, repodata_solve_records: impl Future>, repodata_building_records: miette::Result>>, - prefix_task: CondaPrefixUpdater, + command_dispatcher: CommandDispatcher, semaphore: Arc, project_root: PathBuf, locked_pypi_packages: Arc, disallow_install_conda_prefix: bool, + build_cache: Arc, ) -> miette::Result { // Get the Pypi dependencies for this environment let dependencies = grouped_environment.pypi_dependencies(Some(platform)); @@ -2606,13 +2619,14 @@ async fn spawn_solve_pypi_task<'p>( platform, &pb.pb, &project_root, - prefix_task, + command_dispatcher, repodata_building_records, project_variables, environment, disallow_install_conda_prefix, exclude_newer, solve_strategy, + build_cache, ) .await .with_context(|| { diff --git a/crates/pixi_core/src/workspace/workspace_mut.rs b/crates/pixi_core/src/workspace/workspace_mut.rs index ae876ec375..410d78bc60 100644 --- a/crates/pixi_core/src/workspace/workspace_mut.rs +++ b/crates/pixi_core/src/workspace/workspace_mut.rs @@ -371,6 +371,7 @@ impl WorkspaceMut { command_dispatcher, glob_hash_cache, io_concurrency_limit, + build_caches, } = UpdateContext::builder(self.workspace(), None)? .with_lock_file(unlocked_lock_file) .with_no_install(no_install || dry_run) @@ -436,6 +437,7 @@ impl WorkspaceMut { io_concurrency_limit, command_dispatcher, glob_hash_cache, + build_caches, }; if !dry_run { updated_lock_file.write_to_disk()?; diff --git a/examples/pypi-source-deps/pixi.lock b/examples/pypi-source-deps/pixi.lock index eeee35a13c..03ac132935 100644 --- a/examples/pypi-source-deps/pixi.lock +++ b/examples/pypi-source-deps/pixi.lock @@ -5,172 +5,176 @@ environments: - url: https://conda.anaconda.org/conda-forge/ indexes: - https://pypi.org/simple + options: + pypi-prerelease-mode: if-necessary-or-explicit packages: linux-64: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.12.14-hbcca054_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.4-h5888daf_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h77fa898_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h77fa898_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.6.3-hb9d3cd8_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.48.0-hee588c1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.1-ha99a958_105_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.13-5_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl + - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl - pypi: direct+https://github.com/pallets/click/releases/download/8.1.7/click-8.1.7-py3-none-any.whl - - pypi: git+https://github.com/pallets/flask#f61172b8dd3f962d33f25c50b2f5405e90ceffa5 - - pypi: https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl + - pypi: git+https://github.com/pallets/flask#2579ce9f18e67ec3213c6eceb5240310ccd46af8 + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: git+https://github.com/encode/httpx.git?rev=c7c13f18a5af4c64c649881b2fe8dbd72a519c32#c7c13f18a5af4c64c649881b2fe8dbd72a519c32 - - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl - - pypi: git+https://github.com/pytest-dev/pytest.git#252cf3bf8f568e5a7a8b97e7cf1c2b98824c64bb + - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: git+https://github.com/pytest-dev/pytest.git#0e9db5fa5a8de151ab43e5d71e0e8192e0456b9d - pypi: https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/f9/9e082990c2585c744734f85bec79b5dae5df9c974ffee58fe421652c8e91/werkzeug-3.1.4-py3-none-any.whl - pypi: ./minimal-project osx-64: - - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.12.14-h8857fd0_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.6.4-h240833e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.6.3-hd471939_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hfdf4475_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.48.0-hdb6dae5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.1-h14c5de8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.1-hd09e2f1_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-hd23fc13_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.4.0-hc426f3f_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.1-h2334245_105_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/python_abi-3.13-5_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl + - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.2-hf88997e_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl - pypi: direct+https://github.com/pallets/click/releases/download/8.1.7/click-8.1.7-py3-none-any.whl - - pypi: git+https://github.com/pallets/flask#f61172b8dd3f962d33f25c50b2f5405e90ceffa5 - - pypi: https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl + - pypi: git+https://github.com/pallets/flask#2579ce9f18e67ec3213c6eceb5240310ccd46af8 + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: git+https://github.com/encode/httpx.git?rev=c7c13f18a5af4c64c649881b2fe8dbd72a519c32#c7c13f18a5af4c64c649881b2fe8dbd72a519c32 - - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl - - pypi: git+https://github.com/pytest-dev/pytest.git#252cf3bf8f568e5a7a8b97e7cf1c2b98824c64bb + - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: git+https://github.com/pytest-dev/pytest.git#0e9db5fa5a8de151ab43e5d71e0e8192e0456b9d - pypi: https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/f9/9e082990c2585c744734f85bec79b5dae5df9c974ffee58fe421652c8e91/werkzeug-3.1.4-py3-none-any.whl - pypi: ./minimal-project osx-arm64: - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.12.14-hf0a4a13_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.4-h286801f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.6.3-h39f12f2_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h99b78c6_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.48.0-h3f77e49_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.1-h1b79a29_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-h8359307_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.1-h4f43103_105_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda - - pypi: https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.2-h40d2674_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl - pypi: direct+https://github.com/pallets/click/releases/download/8.1.7/click-8.1.7-py3-none-any.whl - - pypi: git+https://github.com/pallets/flask#f61172b8dd3f962d33f25c50b2f5405e90ceffa5 - - pypi: https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl + - pypi: git+https://github.com/pallets/flask#2579ce9f18e67ec3213c6eceb5240310ccd46af8 + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: git+https://github.com/encode/httpx.git?rev=c7c13f18a5af4c64c649881b2fe8dbd72a519c32#c7c13f18a5af4c64c649881b2fe8dbd72a519c32 - - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl - - pypi: git+https://github.com/pytest-dev/pytest.git#252cf3bf8f568e5a7a8b97e7cf1c2b98824c64bb + - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: git+https://github.com/pytest-dev/pytest.git#0e9db5fa5a8de151ab43e5d71e0e8192e0456b9d - pypi: https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/f9/9e082990c2585c744734f85bec79b5dae5df9c974ffee58fe421652c8e91/werkzeug-3.1.4-py3-none-any.whl - pypi: ./minimal-project win-64: - - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.12.14-h56e8100_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.4-he0c23c2_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.6.3-h2466b09_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-h4c7d964_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.48.0-h67fdade_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.1-hf5d6505_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.1-h071d269_105_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/python_abi-3.13-5_cp313.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda - - pypi: https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.2-h4b44e0e_100_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + - pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl - pypi: direct+https://github.com/pallets/click/releases/download/8.1.7/click-8.1.7-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl - - pypi: git+https://github.com/pallets/flask#f61172b8dd3f962d33f25c50b2f5405e90ceffa5 - - pypi: https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl + - pypi: git+https://github.com/pallets/flask#2579ce9f18e67ec3213c6eceb5240310ccd46af8 + - pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl - pypi: git+https://github.com/encode/httpx.git?rev=c7c13f18a5af4c64c649881b2fe8dbd72a519c32#c7c13f18a5af4c64c649881b2fe8dbd72a519c32 - - pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl - pypi: https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl + - pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl - - pypi: git+https://github.com/pytest-dev/pytest.git#252cf3bf8f568e5a7a8b97e7cf1c2b98824c64bb + - pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl + - pypi: git+https://github.com/pytest-dev/pytest.git#0e9db5fa5a8de151ab43e5d71e0e8192e0456b9d - pypi: https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - - pypi: https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl + - pypi: https://files.pythonhosted.org/packages/2f/f9/9e082990c2585c744734f85bec79b5dae5df9c974ffee58fe421652c8e91/werkzeug-3.1.4-py3-none-any.whl - pypi: ./minimal-project packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 @@ -194,112 +198,88 @@ packages: purls: [] size: 23621 timestamp: 1650670423406 -- pypi: https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/38/0e/27be9fdef66e72d64c0cdc3cc2823101b80585f8119b5c112c2e8f5f7dab/anyio-4.12.1-py3-none-any.whl name: anyio - version: 4.9.0 - sha256: 9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c + version: 4.12.1 + sha256: d405828884fc140aa80a3c667b8beed277f1dfedec42ba031bd6ac3db606ab6c requires_dist: - exceptiongroup>=1.0.2 ; python_full_version < '3.11' - idna>=2.8 - - sniffio>=1.1 - typing-extensions>=4.5 ; python_full_version < '3.13' - - trio>=0.26.1 ; extra == 'trio' - - anyio[trio] ; extra == 'test' - - blockbuster>=1.5.23 ; extra == 'test' - - coverage[toml]>=7 ; extra == 'test' - - exceptiongroup>=1.2.0 ; extra == 'test' - - hypothesis>=4.0 ; extra == 'test' - - psutil>=5.9 ; extra == 'test' - - pytest>=7.0 ; extra == 'test' - - trustme ; extra == 'test' - - truststore>=0.9.1 ; python_full_version >= '3.10' and extra == 'test' - - uvloop>=0.21 ; python_full_version < '3.14' and platform_python_implementation == 'CPython' and sys_platform != 'win32' and extra == 'test' - - packaging ; extra == 'doc' - - sphinx~=8.2 ; extra == 'doc' - - sphinx-rtd-theme ; extra == 'doc' - - sphinx-autodoc-typehints>=1.2.0 ; extra == 'doc' + - trio>=0.32.0 ; python_full_version >= '3.10' and extra == 'trio' + - trio>=0.31.0 ; python_full_version < '3.10' and extra == 'trio' requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/10/cb/f2ad4230dc2eb1a74edf38f1a38b9b52277f75bef262d8908e60d957e13c/blinker-1.9.0-py3-none-any.whl name: blinker version: 1.9.0 sha256: ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-h4bc722e_7.conda - sha256: 5ced96500d945fb286c9c838e54fa759aa04a7129c59800f0846b4335cee770d - md5: 62ee74e96c5ebb0af99386de58cf9553 +- conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_8.conda + sha256: c30daba32ddebbb7ded490f0e371eae90f51e72db620554089103b4a6934b0d5 + md5: 51a19bba1b8ebfb60df25cde030b7ebc depends: - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 + - libgcc >=14 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 252783 - timestamp: 1720974456583 -- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-hfdf4475_7.conda - sha256: cad153608b81fb24fc8c509357daa9ae4e49dfc535b2cb49b91e23dbd68fc3c5 - md5: 7ed4301d437b59045be7e051a0308211 + size: 260341 + timestamp: 1757437258798 +- conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h500dc9f_8.conda + sha256: 8f50b58efb29c710f3cecf2027a8d7325ba769ab10c746eff75cea3ac050b10c + md5: 97c4b3bd8a90722104798175a1bdddbf depends: - __osx >=10.13 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 134188 - timestamp: 1720974491916 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h99b78c6_7.conda - sha256: adfa71f158cbd872a36394c56c3568e6034aa55c623634b37a4836bd036e6b91 - md5: fc6948412dbbbe9a4c9ddbbcfe0a79ab + size: 132607 + timestamp: 1757437730085 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_8.conda + sha256: b456200636bd5fecb2bec63f7e0985ad2097cf1b83d60ce0b6968dffa6d02aa1 + md5: 58fd217444c2a5701a44244faf518206 depends: - __osx >=11.0 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 122909 - timestamp: 1720974522888 -- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h2466b09_7.conda - sha256: 35a5dad92e88fdd7fc405e864ec239486f4f31eec229e31686e61a140a8e573b - md5: 276e7ffe9ffe39688abc665ef0f45596 + size: 125061 + timestamp: 1757437486465 +- conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-h0ad9c76_8.conda + sha256: d882712855624641f48aa9dc3f5feea2ed6b4e6004585d3616386a18186fe692 + md5: 1077e9333c41ff0be8edd1a5ec0ddace depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: bzip2-1.0.6 license_family: BSD purls: [] - size: 54927 - timestamp: 1720974860185 -- conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.12.14-hbcca054_0.conda - sha256: 1afd7274cbc9a334d6d0bc62fa760acc7afdaceb0b91a8df370ec01fd75dc7dd - md5: 720523eb0d6a9b0f6120c16b2aa4e7de - license: ISC - purls: [] - size: 157088 - timestamp: 1734208393264 -- conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.12.14-h8857fd0_0.conda - sha256: ddaafdcd1b8ace6ffeea22b6824ca9db8a64cf0a2652a11d7554ece54935fa06 - md5: b7b887091c99ed2e74845e75e9128410 - license: ISC - purls: [] - size: 156925 - timestamp: 1734208413176 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.12.14-hf0a4a13_0.conda - sha256: 256be633fd0882ccc1a7a32bc278547e1703f85082c0789a87a603ee3ab8fb82 - md5: 7cb381a6783d91902638e4ed1ebd478e + size: 55977 + timestamp: 1757437738856 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-h4c7d964_0.conda + sha256: 4ddcb01be03f85d3db9d881407fb13a673372f1b9fac9c836ea441893390e049 + md5: 84d389c9eee640dda3d26fc5335c67d8 + depends: + - __win license: ISC purls: [] - size: 157091 - timestamp: 1734208344343 -- conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.12.14-h56e8100_0.conda - sha256: 424d82db36cd26234bc4772426170efd60e888c2aed0099a257a95e131683a5e - md5: cb2eaeb88549ddb27af533eccf9a45c1 + size: 147139 + timestamp: 1767500904211 +- conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.1.4-hbd8a1cb_0.conda + sha256: b5974ec9b50e3c514a382335efa81ed02b05906849827a34061c496f4defa0b2 + md5: bddacf101bb4dd0e51811cb69c7790e2 + depends: + - __unix license: ISC purls: [] - size: 157422 - timestamp: 1734208404685 -- pypi: https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl + size: 146519 + timestamp: 1767500828366 +- pypi: https://files.pythonhosted.org/packages/e6/ad/3cc14f097111b4de0040c83a525973216457bbeeb63739ef1ed275c1c021/certifi-2026.1.4-py3-none-any.whl name: certifi - version: 2024.12.14 - sha256: 1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56 - requires_python: '>=3.6' + version: 2026.1.4 + sha256: 9943707519e4add1115f44c2bc244f782c0249876bf51b6599fee1ffbedd685c + requires_python: '>=3.7' - pypi: direct+https://github.com/pallets/click/releases/download/8.1.7/click-8.1.7-py3-none-any.whl name: click version: 8.1.7 @@ -312,33 +292,31 @@ packages: version: 0.4.6 sha256: 4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6 requires_python: '>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*' -- pypi: git+https://github.com/pallets/flask#f61172b8dd3f962d33f25c50b2f5405e90ceffa5 +- pypi: git+https://github.com/pallets/flask#2579ce9f18e67ec3213c6eceb5240310ccd46af8 name: flask version: 3.2.0.dev0 requires_dist: - - werkzeug>=3.1 - - jinja2>=3.1.2 - - itsdangerous>=2.2 + - blinker>=1.9.0 - click>=8.1.3 - - blinker>=1.9 - - importlib-metadata>=3.6 ; python_full_version < '3.10' + - itsdangerous>=2.2.0 + - jinja2>=3.1.2 + - markupsafe>=2.1.1 + - werkzeug>=3.1.0 - asgiref>=3.2 ; extra == 'async' - python-dotenv ; extra == 'dotenv' - requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl name: h11 - version: 0.14.0 - sha256: e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761 - requires_dist: - - typing-extensions ; python_full_version < '3.8' - requires_python: '>=3.7' -- pypi: https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl + version: 0.16.0 + sha256: 63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86 + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl name: httpcore - version: 1.0.7 - sha256: a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd + version: 1.0.9 + sha256: 2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55 requires_dist: - certifi - - h11>=0.13,<0.15 + - h11>=0.16 - anyio>=4.0,<5.0 ; extra == 'asyncio' - h2>=3,<5 ; extra == 'http2' - socksio==1.* ; extra == 'socks' @@ -361,238 +339,265 @@ packages: - socksio==1.* ; extra == 'socks' - zstandard>=0.18.0 ; extra == 'zstd' requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl +- conda: https://conda.anaconda.org/conda-forge/linux-64/icu-78.1-h33c6efd_0.conda + sha256: 7d6463d0be5092b2ae8f2fad34dc84de83eab8bd44cc0d4be8931881c973c48f + md5: 518e9bbbc3e3486d6a4519192ba690f8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - libstdcxx >=14 + license: MIT + license_family: MIT + purls: [] + size: 12722920 + timestamp: 1766299101259 +- conda: https://conda.anaconda.org/conda-forge/osx-64/icu-78.1-h14c5de8_0.conda + sha256: 256df2229f930d7c83d8e2d36fdfce1f78980272558095ce741a9fccc5ed8998 + md5: 1e648e0c6657a29dc44102d6e3b10ebc + depends: + - __osx >=10.13 + license: MIT + license_family: MIT + purls: [] + size: 12273114 + timestamp: 1766299263503 +- pypi: https://files.pythonhosted.org/packages/0e/61/66938bbb5fc52dbdf84594873d5b51fb1f7c7794e9c0f5bd885f30bc507b/idna-3.11-py3-none-any.whl name: idna - version: '3.10' - sha256: 946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3 + version: '3.11' + sha256: 771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea requires_dist: - ruff>=0.6.2 ; extra == 'all' - mypy>=1.11.2 ; extra == 'all' - pytest>=8.3.2 ; extra == 'all' - flake8>=7.1.1 ; extra == 'all' - requires_python: '>=3.6' -- pypi: https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl + requires_python: '>=3.8' +- pypi: https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl name: iniconfig - version: 2.0.0 - sha256: b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374 - requires_python: '>=3.7' + version: 2.3.0 + sha256: f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12 + requires_python: '>=3.10' - pypi: https://files.pythonhosted.org/packages/04/96/92447566d16df59b2a776c0fb82dbc4d9e07cd95062562af01e408583fc4/itsdangerous-2.2.0-py3-none-any.whl name: itsdangerous version: 2.2.0 sha256: c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl name: jinja2 - version: 3.1.5 - sha256: aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb + version: 3.1.6 + sha256: 85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67 requires_dist: - markupsafe>=2.0 - babel>=2.7 ; extra == 'i18n' requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.43-h712a8e2_2.conda - sha256: 7c91cea91b13f4314d125d1bedb9d03a29ebbd5080ccdea70260363424646dbe - md5: 048b02e3962f066da18efe3a21b77672 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45-default_hbd61a6d_105.conda + sha256: 1027bd8aa0d5144e954e426ab6218fd5c14e54a98f571985675468b339c808ca + md5: 3ec0aa5037d39b06554109a01e6fb0c6 depends: - __glibc >=2.17,<3.0.a0 + - zstd >=1.5.7,<1.6.0a0 constrains: - - binutils_impl_linux-64 2.43 + - binutils_impl_linux-64 2.45 license: GPL-3.0-only license_family: GPL purls: [] - size: 669211 - timestamp: 1729655358674 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.4-h5888daf_0.conda - sha256: 56541b98447b58e52d824bd59d6382d609e11de1f8adf20b23143e353d2b8d26 - md5: db833e03127376d461e1e13e76f09b6c + size: 730831 + timestamp: 1766513089214 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.7.3-hecca717_0.conda + sha256: 1e1b08f6211629cbc2efe7a5bca5953f8f6b3cae0eeb04ca4dacee1bd4e2db2f + md5: 8b09ae86839581147ef2e5c5e229d164 depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - libgcc >=14 constrains: - - expat 2.6.4.* + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 73304 - timestamp: 1730967041968 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.6.4-h240833e_0.conda - sha256: d10f43d0c5df6c8cf55259bce0fe14d2377eed625956cddce06f58827d288c59 - md5: 20307f4049a735a78a29073be1be2626 + size: 76643 + timestamp: 1763549731408 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.7.3-heffb93a_0.conda + sha256: d11b3a6ce5b2e832f430fd112084533a01220597221bee16d6c7dc3947dffba6 + md5: 222e0732a1d0780a622926265bee14ef depends: - __osx >=10.13 constrains: - - expat 2.6.4.* + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 70758 - timestamp: 1730967204736 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.4-h286801f_0.conda - sha256: e42ab5ace927ee7c84e3f0f7d813671e1cf3529f5f06ee5899606630498c2745 - md5: 38d2656dd914feb0cab8c629370768bf + size: 74058 + timestamp: 1763549886493 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.7.3-haf25636_0.conda + sha256: fce22610ecc95e6d149e42a42fbc3cc9d9179bd4eb6232639a60f06e080eec98 + md5: b79875dbb5b1db9a4a22a4520f918e1a depends: - __osx >=11.0 constrains: - - expat 2.6.4.* + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 64693 - timestamp: 1730967175868 -- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.4-he0c23c2_0.conda - sha256: 0c0447bf20d1013d5603499de93a16b6faa92d7ead870d96305c0f065b6a5a12 - md5: eb383771c680aa792feb529eaf9df82f + size: 67800 + timestamp: 1763549994166 +- conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.7.3-hac47afa_0.conda + sha256: 844ab708594bdfbd7b35e1a67c379861bcd180d6efe57b654f482ae2f7f5c21e + md5: 8c9e4f1a0e688eef2e95711178061a0f depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 constrains: - - expat 2.6.4.* + - expat 2.7.3.* license: MIT license_family: MIT purls: [] - size: 139068 - timestamp: 1730967442102 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - sha256: ab6e9856c21709b7b517e940ae7028ae0737546122f83c2aa5d692860c3b149e - md5: d645c6d2ac96843a2bfaccd2d62b3ac3 + size: 70137 + timestamp: 1763550049107 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h9ec8514_0.conda + sha256: 25cbdfa65580cfab1b8d15ee90b4c9f1e0d72128f1661449c9a999d341377d54 + md5: 35f29eec58405aaf55e01cb470d8c26a depends: - - libgcc-ng >=9.4.0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 license: MIT license_family: MIT purls: [] - size: 58292 - timestamp: 1636488182923 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2 - sha256: 7a2d27a936ceee6942ea4d397f9c7d136f12549d86f7617e8b6bad51e01a941f - md5: ccb34fb14960ad8b125962d3d79b31a9 + size: 57821 + timestamp: 1760295480630 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.5.2-h750e83c_0.conda + sha256: 277dc89950f5d97f1683f26e362d6dca3c2efa16cb2f6fdb73d109effa1cd3d0 + md5: d214916b24c625bcc459b245d509f22e + depends: + - __osx >=10.13 license: MIT license_family: MIT purls: [] - size: 51348 - timestamp: 1636488394370 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - sha256: 41b3d13efb775e340e4dba549ab5c029611ea6918703096b2eaa9c015c0750ca - md5: 086914b672be056eb70fd4285b6783b6 + size: 52573 + timestamp: 1760295626449 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-he5f378a_0.conda + sha256: 9b8acdf42df61b7bfe8bdc545c016c29e61985e79748c64ad66df47dbc2e295f + md5: 411ff7cd5d1472bba0f55c0faf04453b + depends: + - __osx >=11.0 license: MIT license_family: MIT purls: [] - size: 39020 - timestamp: 1636488587153 -- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - sha256: 1951ab740f80660e9bc07d2ed3aefb874d78c107264fd810f24a1a6211d4b1a5 - md5: 2c96d1b6915b408893f9472569dee135 + size: 40251 + timestamp: 1760295839166 +- conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.5.2-h52bdfb6_0.conda + sha256: ddff25aaa4f0aa535413f5d831b04073789522890a4d8626366e43ecde1534a3 + md5: ba4ad812d2afc22b9a34ce8327a0930f depends: - - vc >=14.1,<15.0a0 - - vs2015_runtime >=14.16.27012 + - ucrt >=10.0.20348.0 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: MIT license_family: MIT purls: [] - size: 42063 - timestamp: 1636489106777 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-14.2.0-h77fa898_1.conda - sha256: 53eb8a79365e58849e7b1a068d31f4f9e718dc938d6f2c03e960345739a03569 - md5: 3cb76c3f10d3bc7f1105b2fc9db984df + size: 44866 + timestamp: 1760295760649 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_16.conda + sha256: 6eed58051c2e12b804d53ceff5994a350c61baf117ec83f5f10c953a3f311451 + md5: 6d0363467e6ed84f11435eb309f2ff06 depends: - - _libgcc_mutex 0.1 conda_forge + - __glibc >=2.17,<3.0.a0 - _openmp_mutex >=4.5 constrains: - - libgomp 14.2.0 h77fa898_1 - - libgcc-ng ==14.2.0=*_1 - license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - purls: [] - size: 848745 - timestamp: 1729027721139 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-14.2.0-h69a702a_1.conda - sha256: 3a76969c80e9af8b6e7a55090088bc41da4cffcde9e2c71b17f44d37b7cb87f7 - md5: e39480b9ca41323497b05492a63bc35b - depends: - - libgcc 14.2.0 h77fa898_1 + - libgcc-ng ==15.2.0=*_16 + - libgomp 15.2.0 he0feb66_16 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 54142 - timestamp: 1729027726517 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-14.2.0-h77fa898_1.conda - sha256: 1911c29975ec99b6b906904040c855772ccb265a1c79d5d75c8ceec4ed89cd63 - md5: cc3573974587f12dda90d96e3e55a702 + size: 1042798 + timestamp: 1765256792743 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_16.conda + sha256: 5b3e5e4e9270ecfcd48f47e3a68f037f5ab0f529ccb223e8e5d5ac75a58fc687 + md5: 26c46f90d0e727e95c6c9498a33a09f3 depends: - - _libgcc_mutex 0.1 conda_forge + - __glibc >=2.17,<3.0.a0 license: GPL-3.0-only WITH GCC-exception-3.1 license_family: GPL purls: [] - size: 460992 - timestamp: 1729027639220 -- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.6.3-hb9d3cd8_1.conda - sha256: e6e425252f3839e2756e4af1ea2074dffd3396c161bf460629f9dfd6a65f15c6 - md5: 2ecf2f1c7e4e21fcfe6423a51a992d84 + size: 603284 + timestamp: 1765256703881 +- conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.1-hb9d3cd8_2.conda + sha256: f2591c0069447bbe28d4d696b7fcb0c5bd0b4ac582769b89addbcf26fb3430d8 + md5: 1a580f7796c7bf6393fddb8bbbde58dc depends: - __glibc >=2.17,<3.0.a0 - libgcc >=13 + constrains: + - xz 5.8.1.* license: 0BSD purls: [] - size: 111132 - timestamp: 1733407410083 -- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.6.3-hd471939_1.conda - sha256: c70639ff3cb034a8e31cb081c907879b6a639bb12b0e090069a68eb69125b10e - md5: f9e9205fed9c664421c1c09f0b90ce6d + size: 112894 + timestamp: 1749230047870 +- conda: https://conda.anaconda.org/conda-forge/osx-64/liblzma-5.8.1-hd471939_2.conda + sha256: 7e22fd1bdb8bf4c2be93de2d4e718db5c548aa082af47a7430eb23192de6bb36 + md5: 8468beea04b9065b9807fc8b9cdc5894 depends: - __osx >=10.13 + constrains: + - xz 5.8.1.* license: 0BSD purls: [] - size: 103745 - timestamp: 1733407504892 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.6.3-h39f12f2_1.conda - sha256: d863b8257406918ffdc50ae65502f2b2d6cede29404d09a094f59509d6a0aaf1 - md5: b2553114a7f5e20ccd02378a77d836aa + size: 104826 + timestamp: 1749230155443 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.1-h39f12f2_2.conda + sha256: 0cb92a9e026e7bd4842f410a5c5c665c89b2eb97794ffddba519a626b8ce7285 + md5: d6df911d4564d77c4374b02552cb17d1 depends: - __osx >=11.0 + constrains: + - xz 5.8.1.* license: 0BSD purls: [] - size: 99129 - timestamp: 1733407496073 -- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.6.3-h2466b09_1.conda - sha256: 24d04bd55adfa44c421c99ce169df38cb1ad2bba5f43151bc847fc802496a1fa - md5: 015b9c0bd1eef60729ab577a38aaf0b5 + size: 92286 + timestamp: 1749230283517 +- conda: https://conda.anaconda.org/conda-forge/win-64/liblzma-5.8.1-h2466b09_2.conda + sha256: 55764956eb9179b98de7cc0e55696f2eff8f7b83fc3ebff5e696ca358bca28cc + md5: c15148b2e18da456f5108ccb5e411446 depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 + constrains: + - xz 5.8.1.* license: 0BSD purls: [] - size: 104332 - timestamp: 1733407872569 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-h4bc722e_0.conda - sha256: d02d1d3304ecaf5c728e515eb7416517a0b118200cd5eacbe829c432d1664070 - md5: aeb98fdeb2e8f25d43ef71fbacbeec80 + size: 104935 + timestamp: 1749230611612 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb9d3cd8_0.conda + sha256: 3aa92d4074d4063f2a162cd8ecb45dccac93e543e565c01a787e16a43501f7ee + md5: c7e925f37e3b40d893459e625f6a53f1 depends: - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 + - libgcc >=13 license: BSD-2-Clause license_family: BSD purls: [] - size: 89991 - timestamp: 1723817448345 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-hfdf4475_0.conda - sha256: 791be3d30d8e37ec49bcc23eb8f1e1415d911a7c023fa93685f2ea485179e258 - md5: ed625b2e59dff82859c23dd24774156b + size: 91183 + timestamp: 1748393666725 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libmpdec-4.0.0-h6e16a3a_0.conda + sha256: 98299c73c7a93cd4f5ff8bb7f43cd80389f08b5a27a296d806bdef7841cc9b9e + md5: 18b81186a6adb43f000ad19ed7b70381 depends: - __osx >=10.13 license: BSD-2-Clause license_family: BSD purls: [] - size: 76561 - timestamp: 1723817691512 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h99b78c6_0.conda - sha256: f7917de9117d3a5fe12a39e185c7ce424f8d5010a6f97b4333e8a1dcb2889d16 - md5: 7476305c35dd9acef48da8f754eedb40 + size: 77667 + timestamp: 1748393757154 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h5505292_0.conda + sha256: 0a1875fc1642324ebd6c4ac864604f3f18f57fbcf558a8264f6ced028a3c75b2 + md5: 85ccccb47823dd9f7a99d2c7f530342f depends: - __osx >=11.0 license: BSD-2-Clause license_family: BSD purls: [] - size: 69263 - timestamp: 1723817629767 + size: 71829 + timestamp: 1748393749336 - conda: https://conda.anaconda.org/conda-forge/win-64/libmpdec-4.0.0-h2466b09_0.conda sha256: fc529fc82c7caf51202cc5cec5bb1c2e8d90edbac6d0a4602c966366efe3c7bf md5: 74860100b2029e2523cf480804c76b9b @@ -605,58 +610,74 @@ packages: purls: [] size: 88657 timestamp: 1723861474602 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.48.0-hee588c1_0.conda - sha256: 7bb84f44e1bd756da4a3d0d43308324a5533e6ba9f4772475884bce44d405064 - md5: 84bd1c9a82b455e7a2f390375fb38f90 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.51.1-hf4e2dac_1.conda + sha256: d614540c55f22ad555633f75e174089018ddfc65c49f447f7bbdbc3c3013bec1 + md5: b1f35e70f047918b49fb4b181e40300e depends: - __glibc >=2.17,<3.0.a0 - - libgcc >=13 + - icu >=78.1,<79.0a0 + - libgcc >=14 - libzlib >=1.3.1,<2.0a0 - license: Unlicense + license: blessing purls: [] - size: 876582 - timestamp: 1737123945341 -- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.48.0-hdb6dae5_0.conda - sha256: 92b391120bf47091490cd7c36b0a60b82f848b6c4ad289713e518402cb5077ff - md5: bddb50cc09176da1659c53ebb8dfbba0 + size: 943451 + timestamp: 1766319676469 +- conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.51.1-hd09e2f1_1.conda + sha256: 497b0a698ae87e024d24e242f93c56303731844d10861e1448f6d0a3d69c9ea7 + md5: 75ba9aba95c277f12e23cdb0856fd9cd depends: - __osx >=10.13 + - icu >=78.1,<79.0a0 - libzlib >=1.3.1,<2.0a0 - license: Unlicense + license: blessing purls: [] - size: 925027 - timestamp: 1737124026531 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.48.0-h3f77e49_0.conda - sha256: b31169cf0ca7b6835baca4ab92d6cf2eee83b1a12a11b72f39521e8baf4d6acb - md5: 714719df4f49e30f9728956f240846ca + size: 991497 + timestamp: 1766319979749 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.51.1-h1b79a29_1.conda + sha256: f2c3cbf2ca7d697098964a748fbf19d6e4adcefa23844ec49f0166f1d36af83c + md5: 8c3951797658e10b610929c3e57e9ad9 depends: - __osx >=11.0 - libzlib >=1.3.1,<2.0a0 - license: Unlicense + license: blessing purls: [] - size: 853163 - timestamp: 1737124192432 -- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.48.0-h67fdade_0.conda - sha256: 2868c0df07b6d0682c9f3709523b6f3f3577f18e0d6f0e31022b48e6d0059f74 - md5: f4268a291ae1f885d4b96add05865cc8 + size: 905861 + timestamp: 1766319901587 +- conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.51.1-hf5d6505_1.conda + sha256: d6d86715a1afe11f626b7509935e9d2e14a4946632c0ac474526e20fc6c55f99 + md5: be65be5f758709fc01b01626152e96b0 depends: - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Unlicense + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + license: blessing + purls: [] + size: 1292859 + timestamp: 1766319616777 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_16.conda + sha256: 813427918316a00c904723f1dfc3da1bbc1974c5cfe1ed1e704c6f4e0798cbc6 + md5: 68f68355000ec3f1d6f26ea13e8f525f + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc 15.2.0 he0feb66_16 + constrains: + - libstdcxx-ng ==15.2.0=*_16 + license: GPL-3.0-only WITH GCC-exception-3.1 + license_family: GPL purls: [] - size: 897200 - timestamp: 1737124291192 -- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - sha256: 787eb542f055a2b3de553614b25f09eefb0a0931b0c87dbcce6efdfd92f04f18 - md5: 40b61aab5c7ba9ff276c41cfffe6b80b + size: 5856456 + timestamp: 1765256838573 +- conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.41.3-h5347b49_0.conda + sha256: 1a7539cfa7df00714e8943e18de0b06cceef6778e420a5ee3a2a145773758aee + md5: db409b7c1720428638e7c0d509d3e1b5 depends: - - libgcc-ng >=12 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 license: BSD-3-Clause license_family: BSD purls: [] - size: 33601 - timestamp: 1680112270483 + size: 40311 + timestamp: 1766271528534 - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-hb9d3cd8_2.conda sha256: d4bfe88d7cb447768e31650f06257995601f89076080e76df55e3112d4e47dc4 md5: edb0dca6bc32e4f4789199455a1dbeb8 @@ -708,56 +729,58 @@ packages: purls: [] size: 55476 timestamp: 1727963768015 -- pypi: https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/94/54/e7d793b573f298e1c9013b8c4dade17d481164aa517d1d7148619c2cedbf/markdown_it_py-4.0.0-py3-none-any.whl name: markdown-it-py - version: 3.0.0 - sha256: 355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1 + version: 4.0.0 + sha256: 87327c59b172c5011896038353a81343b6754500a08cd7a4973bb48c6d578147 requires_dist: - mdurl~=0.1 - psutil ; extra == 'benchmarking' - pytest ; extra == 'benchmarking' - pytest-benchmark ; extra == 'benchmarking' - - pre-commit~=3.0 ; extra == 'code-style' - commonmark~=0.9 ; extra == 'compare' - markdown~=3.4 ; extra == 'compare' - mistletoe~=1.0 ; extra == 'compare' - - mistune~=2.0 ; extra == 'compare' + - mistune~=3.0 ; extra == 'compare' - panflute~=2.3 ; extra == 'compare' + - markdown-it-pyrs ; extra == 'compare' - linkify-it-py>=1,<3 ; extra == 'linkify' - - mdit-py-plugins ; extra == 'plugins' + - mdit-py-plugins>=0.5.0 ; extra == 'plugins' - gprof2dot ; extra == 'profiling' - - mdit-py-plugins ; extra == 'rtd' + - mdit-py-plugins>=0.5.0 ; extra == 'rtd' - myst-parser ; extra == 'rtd' - pyyaml ; extra == 'rtd' - sphinx ; extra == 'rtd' - sphinx-copybutton ; extra == 'rtd' - sphinx-design ; extra == 'rtd' - - sphinx-book-theme ; extra == 'rtd' + - sphinx-book-theme~=1.0 ; extra == 'rtd' - jupyter-sphinx ; extra == 'rtd' + - ipykernel ; extra == 'rtd' - coverage ; extra == 'testing' - pytest ; extra == 'testing' - pytest-cov ; extra == 'testing' - pytest-regressions ; extra == 'testing' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl + - requests ; extra == 'testing' + requires_python: '>=3.10' +- pypi: https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl name: markupsafe - version: 3.0.2 - sha256: 15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396 + version: 3.0.3 + sha256: bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl +- pypi: https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl name: markupsafe - version: 3.0.2 - sha256: e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f + version: 3.0.3 + sha256: eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl +- pypi: https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl name: markupsafe - version: 3.0.2 - sha256: f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430 + version: 3.0.3 + sha256: 457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97 requires_python: '>=3.9' -- pypi: https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl +- pypi: https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl name: markupsafe - version: 3.0.2 - sha256: ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd + version: 3.0.3 + sha256: c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026 requires_python: '>=3.9' - pypi: https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl name: mdurl @@ -767,113 +790,112 @@ packages: - pypi: ./minimal-project name: minimal-project version: '0.1' - sha256: 590cda021c427ceaff15b4aa13245e6fd493b6ffb759c0a017f5d1b485b75c57 - editable: true -- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_2.conda - sha256: 17fe6afd8a00446010220d52256bd222b1e4fcb93bd587e7784b03219f3dc358 - md5: 04b34b9a40cdc48cfdab261ab176ff74 +- conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h2d0b736_3.conda + sha256: 3fde293232fa3fca98635e1167de6b7c7fda83caf24b9d6c91ec9eefb4f4d586 + md5: 47e340acb35de30501a76c7c799c41d7 depends: - __glibc >=2.17,<3.0.a0 - libgcc >=13 license: X11 AND BSD-3-Clause purls: [] - size: 894452 - timestamp: 1736683239706 -- conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_2.conda - sha256: 507456591054ff83a0179c6b3804dbf6ea7874ac07b68bdf6ab5f23f2065e067 - md5: 7eb0c4be5e4287a3d6bfef015669a545 + size: 891641 + timestamp: 1738195959188 +- conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h0622a9a_3.conda + sha256: ea4a5d27ded18443749aefa49dc79f6356da8506d508b5296f60b8d51e0c4bd9 + md5: ced34dd9929f491ca6dab6a2927aff25 depends: - __osx >=10.13 license: X11 AND BSD-3-Clause purls: [] - size: 822835 - timestamp: 1736683439206 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_2.conda - sha256: b45c73348ec9841d5c893acc2e97adff24127548fe8c786109d03c41ed564e91 - md5: f6f7c5b7d0983be186c46c4f6f8f9af8 + size: 822259 + timestamp: 1738196181298 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-h5e97a16_3.conda + sha256: 2827ada40e8d9ca69a153a45f7fd14f32b2ead7045d3bbb5d10964898fe65733 + md5: 068d497125e4bf8a66bf707254fff5ae depends: - __osx >=11.0 license: X11 AND BSD-3-Clause purls: [] - size: 796754 - timestamp: 1736683572099 -- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.4.0-h7b32b05_1.conda - sha256: f62f6bca4a33ca5109b6d571b052a394d836956d21b25b7ffd03376abf7a481f - md5: 4ce6875f75469b2757a65e10a5d05e31 + size: 797030 + timestamp: 1738196177597 +- conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.0-h26f9b46_0.conda + sha256: a47271202f4518a484956968335b2521409c8173e123ab381e775c358c67fe6d + md5: 9ee58d5c534af06558933af3c845a780 depends: - __glibc >=2.17,<3.0.a0 - ca-certificates - - libgcc >=13 + - libgcc >=14 license: Apache-2.0 license_family: Apache purls: [] - size: 2937158 - timestamp: 1736086387286 -- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.4.0-hc426f3f_1.conda - sha256: 879a960d586cf8a64131ac0c060ef575cfb8aa9f6813093cba92042a86ee867c - md5: eaae23dbfc9ec84775097898526c72ea + size: 3165399 + timestamp: 1762839186699 +- conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.6.0-h230baf5_0.conda + sha256: 36fe9fb316be22fcfb46d5fa3e2e85eec5ef84f908b7745f68f768917235b2d5 + md5: 3f50cdf9a97d0280655758b735781096 depends: - __osx >=10.13 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 2590210 - timestamp: 1736086530077 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.4.0-h81ee809_1.conda - sha256: 97772762abc70b3a537683ca9fc3ff3d6099eb64e4aba3b9c99e6fce48422d21 - md5: 22f971393637480bda8c679f374d8861 + size: 2778996 + timestamp: 1762840724922 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.0-h5503f6c_0.conda + sha256: ebe93dafcc09e099782fe3907485d4e1671296bc14f8c383cb6f3dfebb773988 + md5: b34dc4172653c13dcf453862f251af2b depends: - __osx >=11.0 - ca-certificates license: Apache-2.0 license_family: Apache purls: [] - size: 2936415 - timestamp: 1736086108693 -- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.4.0-ha4e3fda_1.conda - sha256: 519a06eaab7c878fbebb8cab98ea4a4465eafb1e9ed8c6ce67226068a80a92f0 - md5: fb45308ba8bfe1abf1f4a27bad24a743 + size: 3108371 + timestamp: 1762839712322 +- conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.6.0-h725018a_0.conda + sha256: 6d72d6f766293d4f2aa60c28c244c8efed6946c430814175f959ffe8cab899b3 + md5: 84f8fb4afd1157f59098f618cd2437e4 depends: - ca-certificates - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 license: Apache-2.0 license_family: Apache purls: [] - size: 8462960 - timestamp: 1736088436984 -- pypi: https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl + size: 9440812 + timestamp: 1762841722179 +- pypi: https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl name: packaging - version: '24.2' - sha256: 09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759 + version: '25.0' + sha256: 29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484 requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl +- pypi: https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl name: pluggy - version: 1.5.0 - sha256: 44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669 + version: 1.6.0 + sha256: e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746 requires_dist: - pre-commit ; extra == 'dev' - tox ; extra == 'dev' - pytest ; extra == 'testing' - pytest-benchmark ; extra == 'testing' - requires_python: '>=3.8' -- pypi: https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl + - coverage ; extra == 'testing' + requires_python: '>=3.9' +- pypi: https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl name: pygments - version: 2.19.1 - sha256: 9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c + version: 2.19.2 + sha256: 86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b requires_dist: - colorama>=0.4.6 ; extra == 'windows-terminal' requires_python: '>=3.8' -- pypi: git+https://github.com/pytest-dev/pytest.git#252cf3bf8f568e5a7a8b97e7cf1c2b98824c64bb +- pypi: git+https://github.com/pytest-dev/pytest.git#0e9db5fa5a8de151ab43e5d71e0e8192e0456b9d name: pytest - version: 8.4.0.dev435+g252cf3bf8 + version: 9.1.0.dev148+g0e9db5fa5 requires_dist: - colorama>=0.4 ; sys_platform == 'win32' - exceptiongroup>=1 ; python_full_version < '3.11' - - iniconfig>=1 - - packaging>=20 + - iniconfig>=1.0.1 + - packaging>=22 - pluggy>=1.5,<2 - pygments>=2.7.2 - tomli>=1 ; python_full_version < '3.11' @@ -884,181 +906,155 @@ packages: - requests ; extra == 'dev' - setuptools ; extra == 'dev' - xmlschema ; extra == 'dev' - requires_python: '>=3.9' -- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.13.1-ha99a958_105_cp313.conda - build_number: 105 - sha256: d3eb7d0820cf0189103bba1e60e242ffc15fd2f727640ac3a10394b27adf3cca - md5: 34945787453ee52a8f8271c1d19af1e8 + requires_python: '>=3.10' +- conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.2-h32b2ec7_100_cp314.conda + build_number: 100 + sha256: a120fb2da4e4d51dd32918c149b04a08815fd2bd52099dad1334647984bb07f1 + md5: 1cef1236a05c3a98f68c33ae9425f656 depends: - __glibc >=2.17,<3.0.a0 - bzip2 >=1.0.8,<2.0a0 - ld_impl_linux-64 >=2.36.1 - - libexpat >=2.6.4,<3.0a0 - - libffi >=3.4,<4.0a0 - - libgcc >=13 - - liblzma >=5.6.3,<6.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - libgcc >=14 + - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.47.2,<4.0a0 - - libuuid >=2.38.1,<3.0a0 + - libsqlite >=3.51.1,<4.0a0 + - libuuid >=2.41.2,<3.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.4.0,<4.0a0 - - python_abi 3.13.* *_cp313 + - openssl >=3.5.4,<4.0a0 + - python_abi 3.14.* *_cp314 - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata + - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 purls: [] - size: 33169840 - timestamp: 1736763984540 - python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.13.1-h2334245_105_cp313.conda - build_number: 105 - sha256: a9d224fa69c8b58c8112997f03988de569504c36ba619a08144c47512219e5ad - md5: c3318c58d14fefd755852e989c991556 + size: 36790521 + timestamp: 1765021515427 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.14.2-hf88997e_100_cp314.conda + build_number: 100 + sha256: cd9d41368cb7c531e82fbfdb01e274efbb176c464b59ec619538dd2580602191 + md5: 48921d5efb314c3e628089fc6e27e54a depends: - __osx >=10.13 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.6.4,<3.0a0 - - libffi >=3.4,<4.0a0 - - liblzma >=5.6.3,<6.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.47.2,<4.0a0 + - libsqlite >=3.51.1,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.4.0,<4.0a0 - - python_abi 3.13.* *_cp313 + - openssl >=3.5.4,<4.0a0 + - python_abi 3.14.* *_cp314 - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata + - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 purls: [] - size: 13893157 - timestamp: 1736762934457 - python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.13.1-h4f43103_105_cp313.conda - build_number: 105 - sha256: 7d27cc8ef214abbdf7dd8a5d473e744f4bd9beb7293214a73c58e4895c2830b8 - md5: 11d916b508764b7d881dd5c75d222d6e + size: 14323056 + timestamp: 1765026108189 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.2-h40d2674_100_cp314.conda + build_number: 100 + sha256: 1a93782e90b53e04c2b1a50a0f8bf0887936649d19dba6a05b05c4b44dae96b7 + md5: 14f15ab0d31a2ee5635aa56e77132594 depends: - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.6.4,<3.0a0 - - libffi >=3.4,<4.0a0 - - liblzma >=5.6.3,<6.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.47.2,<4.0a0 + - libsqlite >=3.51.1,<4.0a0 - libzlib >=1.3.1,<2.0a0 - ncurses >=6.5,<7.0a0 - - openssl >=3.4.0,<4.0a0 - - python_abi 3.13.* *_cp313 + - openssl >=3.5.4,<4.0a0 + - python_abi 3.14.* *_cp314 - readline >=8.2,<9.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata + - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 purls: [] - size: 12919840 - timestamp: 1736761931666 - python_site_packages_path: lib/python3.13/site-packages -- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.13.1-h071d269_105_cp313.conda - build_number: 105 - sha256: de3bb832ff3982c993c6af15e6c45bb647159f25329caceed6f73fd4769c7628 - md5: 3ddb0531ecfb2e7274d471203e053d78 + size: 13575758 + timestamp: 1765021280625 + python_site_packages_path: lib/python3.14/site-packages +- conda: https://conda.anaconda.org/conda-forge/win-64/python-3.14.2-h4b44e0e_100_cp314.conda + build_number: 100 + sha256: 6857d7c97cc71fe9ba298dcb1d3b66cc7df425132ab801babd655faa3df48f32 + md5: c3c73414d5ae3f543c531c978d9cc8b8 depends: - bzip2 >=1.0.8,<2.0a0 - - libexpat >=2.6.4,<3.0a0 - - libffi >=3.4,<4.0a0 - - liblzma >=5.6.3,<6.0a0 + - libexpat >=2.7.3,<3.0a0 + - libffi >=3.5.2,<3.6.0a0 + - liblzma >=5.8.1,<6.0a0 - libmpdec >=4.0.0,<5.0a0 - - libsqlite >=3.47.2,<4.0a0 + - libsqlite >=3.51.1,<4.0a0 - libzlib >=1.3.1,<2.0a0 - - openssl >=3.4.0,<4.0a0 - - python_abi 3.13.* *_cp313 + - openssl >=3.5.4,<4.0a0 + - python_abi 3.14.* *_cp314 - tk >=8.6.13,<8.7.0a0 - tzdata - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - zstd >=1.5.7,<1.6.0a0 license: Python-2.0 purls: [] - size: 16778758 - timestamp: 1736761341620 + size: 16833248 + timestamp: 1765020224759 python_site_packages_path: Lib/site-packages -- conda: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.13-5_cp313.conda - build_number: 5 - sha256: 438225b241c5f9bddae6f0178a97f5870a89ecf927dfca54753e689907331442 - md5: 381bbd2a92c863f640a55b6ff3c35161 - constrains: - - python 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 6217 - timestamp: 1723823393322 -- conda: https://conda.anaconda.org/conda-forge/osx-64/python_abi-3.13-5_cp313.conda - build_number: 5 - sha256: 075ad768648e88b78d2a94099563b43d3082e7c35979f457164f26d1079b7b5c - md5: 927a2186f1f997ac018d67c4eece90a6 - constrains: - - python 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 6291 - timestamp: 1723823083064 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/python_abi-3.13-5_cp313.conda - build_number: 5 - sha256: 4437198eae80310f40b23ae2f8a9e0a7e5c2b9ae411a8621eb03d87273666199 - md5: b8e82d0a5c1664638f87f63cc5d241fb - constrains: - - python 3.13.* *_cp313 - license: BSD-3-Clause - license_family: BSD - purls: [] - size: 6322 - timestamp: 1723823058879 -- conda: https://conda.anaconda.org/conda-forge/win-64/python_abi-3.13-5_cp313.conda - build_number: 5 - sha256: 0c12cc1b84962444002c699ed21e815fb9f686f950d734332a1b74d07db97756 - md5: 44b4fe6f22b57103afb2299935c8b68e +- conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda + build_number: 8 + sha256: ad6d2e9ac39751cc0529dd1566a26751a0bf2542adb0c232533d32e176e21db5 + md5: 0539938c55b6b1a59b560e843ad864a4 constrains: - - python 3.13.* *_cp313 + - python 3.14.* *_cp314 license: BSD-3-Clause license_family: BSD purls: [] - size: 6716 - timestamp: 1723823166911 -- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - sha256: 5435cf39d039387fbdc977b0a762357ea909a7694d9528ab40f005e9208744d7 - md5: 47d31b792659ce70f470b5c82fdfb7a4 + size: 6989 + timestamp: 1752805904792 +- conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda + sha256: 12ffde5a6f958e285aa22c191ca01bbd3d6e710aa852e00618fa6ddc59149002 + md5: d7d95fc8287ea7bf33e0e7116d2b95ec depends: - - libgcc-ng >=12 - - ncurses >=6.3,<7.0a0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=14 + - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 281456 - timestamp: 1679532220005 -- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - sha256: 41e7d30a097d9b060037f0c6a2b1d4c4ae7e942c06c943d23f9d481548478568 - md5: f17f77f2acf4d344734bda76829ce14e + size: 345073 + timestamp: 1765813471974 +- conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.3-h68b038d_0.conda + sha256: 4614af680aa0920e82b953fece85a03007e0719c3399f13d7de64176874b80d5 + md5: eefd65452dfe7cce476a519bece46704 depends: - - ncurses >=6.3,<7.0a0 + - __osx >=10.13 + - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 255870 - timestamp: 1679532707590 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - sha256: a1dfa679ac3f6007362386576a704ad2d0d7a02e98f5d0b115f207a2da63e884 - md5: 8cbb776a2f641b943d413b3e19df71f4 + size: 317819 + timestamp: 1765813692798 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda + sha256: a77010528efb4b548ac2a4484eaf7e1c3907f2aec86123ed9c5212ae44502477 + md5: f8381319127120ce51e081dce4865cf4 depends: - - ncurses >=6.3,<7.0a0 + - __osx >=11.0 + - ncurses >=6.5,<7.0a0 license: GPL-3.0-only license_family: GPL purls: [] - size: 250351 - timestamp: 1679532511311 + size: 313930 + timestamp: 1765813902568 - pypi: https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl name: rich version: 13.9.4 @@ -1069,45 +1065,45 @@ packages: - pygments>=2.13.0,<3.0.0 - typing-extensions>=4.0.0,<5.0 ; python_full_version < '3.11' requires_python: '>=3.8.0' -- pypi: https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl - name: sniffio - version: 1.3.1 - sha256: 2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2 - requires_python: '>=3.7' -- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - sha256: e0569c9caa68bf476bead1bed3d79650bb080b532c64a4af7d8ca286c08dea4e - md5: d453b98d9c83e71da0741bb0ff4d76bc +- conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_ha0e22de_103.conda + sha256: 1544760538a40bcd8ace2b1d8ebe3eb5807ac268641f8acdc18c69c5ebfeaf64 + md5: 86bc20552bf46075e3d92b67f089172d depends: - - libgcc-ng >=12 - - libzlib >=1.2.13,<2.0.0a0 + - __glibc >=2.17,<3.0.a0 + - libgcc >=13 + - libzlib >=1.3.1,<2.0a0 + constrains: + - xorg-libx11 >=1.8.12,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3318875 - timestamp: 1699202167581 -- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda - sha256: 30412b2e9de4ff82d8c2a7e5d06a15f4f4fef1809a72138b6ccb53a33b26faf5 - md5: bf830ba5afc507c6232d4ef0fb1a882d + size: 3284905 + timestamp: 1763054914403 +- conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-hf689a15_3.conda + sha256: 0d0b6cef83fec41bc0eb4f3b761c4621b7adfb14378051a8177bd9bb73d26779 + md5: bd9f1de651dbd80b51281c694827f78f depends: - - libzlib >=1.2.13,<2.0.0a0 + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3270220 - timestamp: 1699202389792 -- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - sha256: 72457ad031b4c048e5891f3f6cb27a53cb479db68a52d965f796910e71a403a8 - md5: b50a57ba89c32b62428b71a875291c9b + size: 3262702 + timestamp: 1763055085507 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h892fb3f_3.conda + sha256: ad0c67cb03c163a109820dc9ecf77faf6ec7150e942d1e8bb13e5d39dc058ab7 + md5: a73d54a5abba6543cb2f0af1bfbd6851 depends: - - libzlib >=1.2.13,<2.0.0a0 + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 license: TCL license_family: BSD purls: [] - size: 3145523 - timestamp: 1699202432999 -- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - sha256: 2c4e914f521ccb2718946645108c9bd3fc3216ba69aea20c2c3cedbd8db32bb1 - md5: fc048363eb8f03cd1737600a5d08aafe + size: 3125484 + timestamp: 1763055028377 +- conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h2c6b04d_3.conda + sha256: 4581f4ffb432fefa1ac4f85c5682cc27014bcd66e7beaa0ee330e927a7858790 + md5: 7cb36e506a7dba4817970f8adb6396f9 depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 @@ -1115,63 +1111,113 @@ packages: license: TCL license_family: BSD purls: [] - size: 3503410 - timestamp: 1699202577803 -- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025a-h78e105d_0.conda - sha256: c4b1ae8a2931fe9b274c44af29c5475a85b37693999f8c792dad0f8c6734b1de - md5: dbcace4706afdfb7eb891f7b37d07c04 + size: 3472313 + timestamp: 1763055164278 +- conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda + sha256: 1d30098909076af33a35017eed6f2953af1c769e273a0626a04722ac4acaba3c + md5: ad659d0a2b3e47e38d829aa8cad2d610 license: LicenseRef-Public-Domain purls: [] - size: 122921 - timestamp: 1737119101255 -- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_1.conda - sha256: db8dead3dd30fb1a032737554ce91e2819b43496a0db09927edf01c32b577450 - md5: 6797b005cd0f439c4c5c9ac565783700 + size: 119135 + timestamp: 1767016325805 +- conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.26100.0-h57928b3_0.conda + sha256: 3005729dce6f3d3f5ec91dfc49fc75a0095f9cd23bab49efb899657297ac91a5 + md5: 71b24316859acd00bdb8b38f5e2ce328 constrains: + - vc14_runtime >=14.29.30037 - vs2015_runtime >=14.29.30037 license: LicenseRef-MicrosoftWindowsSDK10 purls: [] - size: 559710 - timestamp: 1728377334097 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_23.conda - sha256: 986ddaf8feec2904eac9535a7ddb7acda1a1dfb9482088fdb8129f1595181663 - md5: 7c10ec3158d1eb4ddff7007c9101adb0 + size: 694692 + timestamp: 1756385147981 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h41ae7f8_34.conda + sha256: 9dc40c2610a6e6727d635c62cced5ef30b7b30123f5ef67d6139e23d21744b3a + md5: 1e610f2416b6acdd231c5f573d754a0f depends: - - vc14_runtime >=14.38.33135 + - vc14_runtime >=14.44.35208 track_features: - vc14 license: BSD-3-Clause license_family: BSD purls: [] - size: 17479 - timestamp: 1731710827215 -- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.42.34433-he29a5d6_23.conda - sha256: c483b090c4251a260aba6ff3e83a307bcfb5fb24ad7ced872ab5d02971bd3a49 - md5: 32b37d0cfa80da34548501cdc913a832 + size: 19356 + timestamp: 1767320221521 +- conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.44.35208-h818238b_34.conda + sha256: 02732f953292cce179de9b633e74928037fa3741eb5ef91c3f8bae4f761d32a5 + md5: 37eb311485d2d8b2c419449582046a42 depends: - ucrt >=10.0.20348.0 + - vcomp14 14.44.35208 h818238b_34 constrains: - - vs2015_runtime 14.42.34433.* *_23 + - vs2015_runtime 14.44.35208.* *_34 license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime license_family: Proprietary purls: [] - size: 754247 - timestamp: 1731710681163 -- conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.42.34433-hdffcdeb_23.conda - sha256: 568ce8151eaae256f1cef752fc78651ad7a86ff05153cc7a4740b52ae6536118 - md5: 5c176975ca2b8366abad3c97b3cd1e83 + size: 683233 + timestamp: 1767320219644 +- conda: https://conda.anaconda.org/conda-forge/win-64/vcomp14-14.44.35208-h818238b_34.conda + sha256: 878d5d10318b119bd98ed3ed874bd467acbe21996e1d81597a1dbf8030ea0ce6 + md5: 242d9f25d2ae60c76b38a5e42858e51d depends: - - vc14_runtime >=14.42.34433 - license: BSD-3-Clause - license_family: BSD + - ucrt >=10.0.20348.0 + constrains: + - vs2015_runtime 14.44.35208.* *_34 + license: LicenseRef-MicrosoftVisualCpp2015-2022Runtime + license_family: Proprietary purls: [] - size: 17572 - timestamp: 1731710685291 -- pypi: https://files.pythonhosted.org/packages/52/24/ab44c871b0f07f491e5d2ad12c9bd7358e527510618cb1b803a88e986db1/werkzeug-3.1.3-py3-none-any.whl + size: 115235 + timestamp: 1767320173250 +- pypi: https://files.pythonhosted.org/packages/2f/f9/9e082990c2585c744734f85bec79b5dae5df9c974ffee58fe421652c8e91/werkzeug-3.1.4-py3-none-any.whl name: werkzeug - version: 3.1.3 - sha256: 54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e + version: 3.1.4 + sha256: 2ad50fb9ed09cc3af22c54698351027ace879a0b60a3b5edf5730b2f7d876905 requires_dist: - markupsafe>=2.1.1 - watchdog>=2.3 ; extra == 'watchdog' requires_python: '>=3.9' +- conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda + sha256: 68f0206ca6e98fea941e5717cec780ed2873ffabc0e1ed34428c061e2c6268c7 + md5: 4a13eeac0b5c8e5b8ab496e6c4ddd829 + depends: + - __glibc >=2.17,<3.0.a0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 601375 + timestamp: 1764777111296 +- conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.7-h3eecb57_6.conda + sha256: 47101a4055a70a4876ffc87b750ab2287b67eca793f21c8224be5e1ee6394d3f + md5: 727109b184d680772e3122f40136d5ca + depends: + - __osx >=10.13 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 528148 + timestamp: 1764777156963 +- conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda + sha256: 9485ba49e8f47d2b597dd399e88f4802e100851b27c21d7525625b0b4025a5d9 + md5: ab136e4c34e97f34fb621d2592a393d8 + depends: + - __osx >=11.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 433413 + timestamp: 1764777166076 +- conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.7-h534d264_6.conda + sha256: 368d8628424966fd8f9c8018326a9c779e06913dd39e646cf331226acc90e5b2 + md5: 053b84beec00b71ea8ff7a4f84b55207 + depends: + - vc >=14.3,<15 + - vc14_runtime >=14.44.35208 + - ucrt >=10.0.20348.0 + - libzlib >=1.3.1,<2.0a0 + license: BSD-3-Clause + license_family: BSD + purls: [] + size: 388453 + timestamp: 1764777142545 diff --git a/pyproject.toml b/pyproject.toml index 703ed2b3fc..7e276e11e8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -5,7 +5,13 @@ format-command = "pixi run -e lint ruff format --stdin-filename {filename}" [tool.basedpyright] -ignore = ["**/*.ipynb", "**/docs_hooks.py", "scripts/test_native_certs.py"] +ignore = [ + "**/*.ipynb", + "**/docs_hooks.py", + "scripts/test_native_certs.py", + "examples/dynamic-source-deps/minimal-project/hatch_build.py", + "/Users/graf/oss/pixi/examples/dynamic-source-deps/setup-project/setup.py", +] pythonPlatform = "All" pythonVersion = "3.13" typeCheckingMode = "all"