diff --git a/crates/pet/tests/ci_test.rs b/crates/pet/tests/ci_test.rs index 7c2a27fa..b5d09ef3 100644 --- a/crates/pet/tests/ci_test.rs +++ b/crates/pet/tests/ci_test.rs @@ -5,7 +5,7 @@ use std::{path::PathBuf, sync::Once}; use common::{does_version_match, resolve_test_path}; use lazy_static::lazy_static; -use log::{error, trace}; +use log::{error, trace, warn}; use pet::{ find::identify_python_executables_using_locators, locators::identify_python_environment_using_locators, resolve::resolve_environment, @@ -321,13 +321,39 @@ fn verify_validity_of_interpreter_info(environment: PythonEnvironment) { } if let Some(version) = environment.clone().version { let expected_version = &interpreter_info.clone().sys_version; - assert!( - does_version_match(&version, expected_version), - "Version mismatch for (expected {:?} to start with {:?}) for {:?}", - expected_version, - version, - environment.clone() - ); + if !does_version_match(&version, expected_version) { + // For pyenv environments, the version may come from the directory name + // which can be out of sync with the binary during CPython version transitions + // (e.g. pyenv installs pre-built binaries without header files). + // Verify at least major.minor matches. + // See https://github.com/microsoft/python-environment-tools/issues/371 + if environment.kind == Some(PythonEnvironmentKind::Pyenv) { + let parts: Vec<&str> = version.splitn(3, '.').collect(); + let major_minor = if parts.len() >= 2 { + format!("{}.{}", parts[0], parts[1]) + } else { + version.clone() + }; + assert!( + expected_version.starts_with(&major_minor), + "Version mismatch (even major.minor differs) for (expected {:?} to start with {:?}) for {:?}", + expected_version, + major_minor, + environment.clone() + ); + warn!( + "Pyenv patch version mismatch: detected={:?}, actual starts with {:?}", + version, expected_version + ); + } else { + panic!( + "Version mismatch for (expected {:?} to start with {:?}) for {:?}", + expected_version, + version, + environment.clone() + ); + } + } } } @@ -462,15 +488,36 @@ fn compare_environments(actual: PythonEnvironment, expected: PythonEnvironment, if let (Some(version), Some(expected_version)) = (expected.clone().version, actual.clone().version) { - assert!( - does_version_match(&version, &expected_version), - "Version mismatch when using {} for (expected {:?} to start with {:?}) for env = {:?} and environment = {:?}", - method, - expected_version, - version, - actual.clone(), - expected.clone() - ); + if !does_version_match(&version, &expected_version) { + // Pyenv directory name can differ from actual binary version at patch level. + // See https://github.com/microsoft/python-environment-tools/issues/371 + if expected.kind == Some(PythonEnvironmentKind::Pyenv) { + let parts: Vec<&str> = version.splitn(3, '.').collect(); + let major_minor = if parts.len() >= 2 { + format!("{}.{}", parts[0], parts[1]) + } else { + version.clone() + }; + assert!( + expected_version.starts_with(&major_minor), + "Version mismatch (even major.minor differs) when using {} for (expected {:?} to start with {:?}) for env = {:?} and environment = {:?}", + method, + expected_version, + major_minor, + actual.clone(), + expected.clone() + ); + } else { + panic!( + "Version mismatch when using {} for (expected {:?} to start with {:?}) for env = {:?} and environment = {:?}", + method, + expected_version, + version, + actual.clone(), + expected.clone() + ); + } + } // if !does_version_match(&version, &expected_version) { // error!("Version mismatch when using {} for (expected {:?} to start with {:?}) for env = {:?} and environment = {:?}", // method,