@@ -13,6 +13,7 @@ use std::collections::{HashMap, HashSet};
13
13
use std:: env;
14
14
use std:: ops:: { Deref , DerefMut } ;
15
15
use std:: path:: PathBuf ;
16
+ use tracing:: debug;
16
17
17
18
// This is used for BridgeModel::Bindings("pyo3-ffi") and BridgeModel::Bindings("pyo3").
18
19
// These should be treated almost identically but must be correctly identified
@@ -218,7 +219,6 @@ impl BuildOptions {
218
219
) -> Result < Vec < PythonInterpreter > > {
219
220
match bridge {
220
221
BridgeModel :: Bindings ( binding_name, _) | BridgeModel :: Bin ( Some ( ( binding_name, _) ) ) => {
221
- let mut native_interpreters = false ;
222
222
let mut interpreters = Vec :: new ( ) ;
223
223
if let Some ( config_file) = env:: var_os ( "PYO3_CONFIG_FILE" ) {
224
224
if !binding_name. starts_with ( "pyo3" ) {
@@ -307,37 +307,20 @@ impl BuildOptions {
307
307
interpreters =
308
308
find_interpreter_in_sysconfig ( interpreter, target, min_python_minor) ?;
309
309
}
310
+ } else if binding_name. starts_with ( "pyo3" ) {
311
+ // Only pyo3/pyo3-ffi bindings supports bundled sysconfig interpreters
312
+ interpreters = find_interpreter ( bridge, interpreter, target, min_python_minor) ?;
310
313
} else {
311
- match find_interpreter_in_host ( bridge, interpreter, target, min_python_minor) {
312
- Ok ( host_interps) => {
313
- interpreters = host_interps;
314
- native_interpreters = true ;
315
- }
316
- Err ( err) => {
317
- if binding_name. starts_with ( "pyo3" ) && target. is_unix ( ) {
318
- interpreters = find_interpreter_in_sysconfig (
319
- interpreter,
320
- target,
321
- min_python_minor,
322
- )
323
- . map_err ( |_| err) ?;
324
- } else {
325
- return Err ( err) ;
326
- }
327
- }
328
- }
314
+ interpreters =
315
+ find_interpreter_in_host ( bridge, interpreter, target, min_python_minor) ?;
329
316
}
330
317
331
318
let interpreters_str = interpreters
332
319
. iter ( )
333
320
. map ( ToString :: to_string)
334
321
. collect :: < Vec < String > > ( )
335
322
. join ( ", " ) ;
336
- if native_interpreters {
337
- println ! ( "🐍 Found {}" , interpreters_str) ;
338
- } else {
339
- println ! ( "🐍 Found cross compiling target {}" , interpreters_str) ;
340
- }
323
+ println ! ( "🐍 Found {}" , interpreters_str) ;
341
324
342
325
Ok ( interpreters)
343
326
}
@@ -994,6 +977,43 @@ fn find_single_python_interpreter(
994
977
Ok ( interpreter)
995
978
}
996
979
980
+ /// Find python interpreters in host machine first,
981
+ /// fallback to bundled sysconfig if not found in host machine
982
+ fn find_interpreter (
983
+ bridge : & BridgeModel ,
984
+ interpreter : & [ PathBuf ] ,
985
+ target : & Target ,
986
+ min_python_minor : Option < usize > ,
987
+ ) -> Result < Vec < PythonInterpreter > > {
988
+ let mut interpreters = Vec :: new ( ) ;
989
+ if !interpreter. is_empty ( ) {
990
+ let mut missing = Vec :: new ( ) ;
991
+ for interp in interpreter {
992
+ match PythonInterpreter :: check_executable ( interp. clone ( ) , target, bridge) {
993
+ Ok ( Some ( interp) ) => interpreters. push ( interp) ,
994
+ _ => missing. push ( interp. clone ( ) ) ,
995
+ }
996
+ }
997
+ if !missing. is_empty ( ) {
998
+ let sysconfig_interps =
999
+ find_interpreter_in_sysconfig ( & missing, target, min_python_minor) ?;
1000
+ interpreters. extend ( sysconfig_interps) ;
1001
+ }
1002
+ } else {
1003
+ interpreters = PythonInterpreter :: find_all ( target, bridge, min_python_minor)
1004
+ . context ( "Finding python interpreters failed" ) ?;
1005
+ } ;
1006
+
1007
+ if interpreters. is_empty ( ) {
1008
+ if let Some ( minor) = min_python_minor {
1009
+ bail ! ( "Couldn't find any python interpreters with version >= 3.{}. Please specify at least one with -i" , minor) ;
1010
+ } else {
1011
+ bail ! ( "Couldn't find any python interpreters. Please specify at least one with -i" ) ;
1012
+ }
1013
+ }
1014
+ Ok ( interpreters)
1015
+ }
1016
+
997
1017
/// Find python interpreters in the host machine
998
1018
fn find_interpreter_in_host (
999
1019
bridge : & BridgeModel ,
@@ -1070,7 +1090,16 @@ fn find_interpreter_in_sysconfig(
1070
1090
python_impl,
1071
1091
( ver_major, ver_minor) ,
1072
1092
)
1073
- . context ( "Failed to find a python interpreter" ) ?;
1093
+ . with_context ( || {
1094
+ format ! (
1095
+ "Failed to find a {} {}.{} interpreter" ,
1096
+ python_impl, ver_major, ver_minor
1097
+ )
1098
+ } ) ?;
1099
+ debug ! (
1100
+ "Found {} {}.{} in bundled sysconfig" ,
1101
+ sysconfig. interpreter_kind, sysconfig. major, sysconfig. minor,
1102
+ ) ;
1074
1103
interpreters. push ( PythonInterpreter :: from_config ( sysconfig. clone ( ) ) ) ;
1075
1104
}
1076
1105
Ok ( interpreters)
0 commit comments