@@ -9,7 +9,7 @@ use std::str::FromStr;
99use std:: sync:: LazyLock ;
1010
1111use anyhow:: bail;
12- use indexmap:: { IndexSet , indexset } ;
12+ use indexmap:: { IndexMap , IndexSet } ;
1313use log:: { debug, warn} ;
1414use pep440_rs:: { Operator , Version , VersionSpecifier , VersionSpecifiers } ;
1515use pep508_rs:: { ExtraName , MarkerTree , PackageName , Requirement , VersionOrUrl } ;
@@ -276,6 +276,11 @@ struct PythonBinarySpec {
276276 suffix : Option < & ' static str > ,
277277}
278278
279+ pub enum VersionSpec {
280+ MajorMinor ( u8 , u8 ) ,
281+ Major ( u8 ) ,
282+ }
283+
279284pub struct InterpreterConstraints ( Vec < InterpreterConstraint > ) ;
280285
281286impl InterpreterConstraints {
@@ -384,9 +389,9 @@ impl InterpreterConstraints {
384389 pub fn calculate_compatible_binary_names (
385390 & self ,
386391 selection_strategy : SelectionStrategy ,
387- ) -> IndexSet < OsString > {
392+ ) -> IndexMap < OsString , Option < VersionSpec > > {
388393 let binary_specs = self . calculate_compatible_binary_specs ( selection_strategy) ;
389- let mut binary_names: IndexSet < OsString > = IndexSet :: new ( ) ;
394+ let mut binary_names: IndexMap < OsString , Option < VersionSpec > > = IndexMap :: new ( ) ;
390395 for binary_spec in & binary_specs {
391396 binary_names. insert (
392397 format ! (
@@ -397,6 +402,10 @@ impl InterpreterConstraints {
397402 suffix = binary_spec. suffix. unwrap_or( "" )
398403 )
399404 . into ( ) ,
405+ Some ( VersionSpec :: MajorMinor (
406+ binary_spec. major ,
407+ binary_spec. minor ,
408+ ) ) ,
400409 ) ;
401410 }
402411 for binary_spec in & binary_specs {
@@ -407,10 +416,11 @@ impl InterpreterConstraints {
407416 major = binary_spec. major
408417 )
409418 . into ( ) ,
419+ Some ( VersionSpec :: Major ( binary_spec. major ) ) ,
410420 ) ;
411421 }
412422 for binary_spec in & binary_specs {
413- binary_names. insert ( binary_spec. name . into ( ) ) ;
423+ binary_names. insert ( binary_spec. name . into ( ) , None ) ;
414424 }
415425 binary_names
416426 }
@@ -422,9 +432,11 @@ impl InterpreterConstraints {
422432 ) -> anyhow:: Result < impl Iterator < Item = PathBuf > > {
423433 let ( python, path, known_paths) = search_path. into_parts ( ) ?;
424434 let binary_names = if let Some ( python) = python {
425- indexset ! { python}
435+ vec ! [ python]
426436 } else {
427437 self . calculate_compatible_binary_names ( selection_strategy)
438+ . into_keys ( )
439+ . collect ( )
428440 } ;
429441 Ok ( PythonExeIter {
430442 known_paths,
@@ -522,6 +534,7 @@ mod tests {
522534 use std:: ffi:: OsStr ;
523535 use std:: str:: FromStr ;
524536
537+ use indexmap:: IndexSet ;
525538 use pep440_rs:: VersionSpecifiers ;
526539
527540 use crate :: constraints:: { InterpreterConstraint , InterpreterImplementation } ;
@@ -602,7 +615,10 @@ mod tests {
602615 #[ test]
603616 fn test_interpreter_constraints_binary_names_all_default_order ( ) {
604617 let ics = InterpreterConstraints :: try_from :: < & str > ( & [ ] ) . unwrap ( ) ;
605- let binary_names = ics. calculate_compatible_binary_names ( SelectionStrategy :: Oldest ) ;
618+ let binary_names = ics
619+ . calculate_compatible_binary_names ( SelectionStrategy :: Oldest )
620+ . into_keys ( )
621+ . collect :: < IndexSet < _ > > ( ) ;
606622
607623 assert_eq ! ( & [ "python2.7" , "pypy2.7" ] , & binary_names[ 0 ..2 ] ) ;
608624
@@ -646,7 +662,10 @@ mod tests {
646662 #[ test]
647663 fn test_interpreter_constraints_binary_names_all_newest_first ( ) {
648664 let ics = InterpreterConstraints :: try_from :: < & str > ( & [ ] ) . unwrap ( ) ;
649- let binary_names = ics. calculate_compatible_binary_names ( SelectionStrategy :: Newest ) ;
665+ let binary_names = ics
666+ . calculate_compatible_binary_names ( SelectionStrategy :: Newest )
667+ . into_keys ( )
668+ . collect :: < IndexSet < _ > > ( ) ;
650669
651670 assert ! (
652671 binary_names. get_index_of( os_str( "python3.15" ) )
@@ -705,6 +724,8 @@ mod tests {
705724 "pypy" ,
706725 ] ,
707726 ics. calculate_compatible_binary_names( SelectionStrategy :: Newest )
727+ . into_keys( )
728+ . collect:: <Vec <_>>( )
708729 . as_slice( )
709730 ) ;
710731 assert_eq ! (
@@ -722,6 +743,8 @@ mod tests {
722743 "python" ,
723744 ] ,
724745 ics. calculate_compatible_binary_names( SelectionStrategy :: Oldest )
746+ . into_keys( )
747+ . collect:: <Vec <_>>( )
725748 . as_slice( )
726749 ) ;
727750 }
0 commit comments