Skip to content

Commit

Permalink
Filter Python interpreters by target pointer width on Windows
Browse files Browse the repository at this point in the history
  • Loading branch information
messense committed Jun 5, 2022
1 parent a95e7c8 commit a074b33
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 47 deletions.
3 changes: 3 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

* Fix Windows Store install detection in [#949](https://github.com/PyO3/maturin/pull/949)
* Filter Python interpreters by target pointer width on Windows in [#950](https://github.com/PyO3/maturin/pull/950)

## [0.12.18] - 2022-05-29

* Add support for building bin bindings wheels with multiple platform tags in [#928](https://github.com/PyO3/maturin/pull/928)
Expand Down
118 changes: 71 additions & 47 deletions src/python_interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,60 +182,39 @@ fn find_all_windows(target: &Target, min_python_minor: usize) -> Result<Vec<Stri
} else {
Path::new(&path).join("python")
};
let python_info = Command::new(&executable)
.arg("-c")
.arg("import sys; print(sys.version)")
.output();

let python_info = match python_info {
Ok(python_info) => python_info,
Err(err) => {
if err.kind() == io::ErrorKind::NotFound {
// This conda env doesn't have python installed
continue;
} else {
bail!(
"Error getting Python version info from conda env at {}",
path
);
}
}
};

let version_info = str::from_utf8(&python_info.stdout).unwrap();
let expr = Regex::new(r"(\d).(\d).(\d+)").unwrap();
if let Some(capture) = expr.captures(version_info) {
let major = capture.get(1).unwrap().as_str().parse::<usize>().unwrap();
let minor = capture.get(2).unwrap().as_str().parse::<usize>().unwrap();
if !versions_found.contains(&(major, minor)) {
let pointer_width = if version_info.contains("64 bit (AMD64)") {
64_usize
} else {
32_usize
};

if windows_interpreter_no_build(
major,
minor,
target.pointer_width(),
pointer_width,
min_python_minor,
) {
continue;
}

interpreter.push(String::from(executable.to_str().unwrap()));
versions_found.insert((major, minor));
if let Some(python_info) = windows_python_info(&executable)? {
if windows_interpreter_no_build(
python_info.major,
python_info.minor,
target.pointer_width(),
python_info.pointer_width.unwrap(),
min_python_minor,
) {
continue;
}
interpreter.push(String::from(executable.to_str().unwrap()));
versions_found.insert((python_info.major, python_info.minor));
}
}
}

// Fallback to pythonX.Y for Microsoft Store versions
for minor in min_python_minor..MAXIMUM_PYTHON_MINOR {
if !versions_found.contains(&(3, minor)) {
interpreter.push(format!("python3.{}.exe", minor));
versions_found.insert((3, minor));
let executable = format!("python3.{}.exe", minor);
if let Some(python_info) = windows_python_info(Path::new(&executable))? {
if windows_interpreter_no_build(
python_info.major,
python_info.minor,
target.pointer_width(),
python_info.pointer_width.unwrap(),
min_python_minor,
) {
continue;
}
interpreter.push(executable);
versions_found.insert((3, minor));
}
}
}

Expand All @@ -247,6 +226,51 @@ fn find_all_windows(target: &Target, min_python_minor: usize) -> Result<Vec<Stri
Ok(interpreter)
}

fn windows_python_info(executable: &Path) -> Result<Option<InterpreterConfig>> {
let python_info = Command::new(&executable)
.arg("-c")
.arg("import sys; print(sys.version)")
.output();

let python_info = match python_info {
Ok(python_info) => python_info,
Err(err) => {
if err.kind() == io::ErrorKind::NotFound {
// python executable not found
return Ok(None);
} else {
bail!(
"Error getting Python version info from {}",
executable.display()
);
}
}
};

let version_info = str::from_utf8(&python_info.stdout).unwrap();
let expr = Regex::new(r"(\d).(\d).(\d+)").unwrap();
if let Some(capture) = expr.captures(version_info) {
let major = capture.get(1).unwrap().as_str().parse::<usize>().unwrap();
let minor = capture.get(2).unwrap().as_str().parse::<usize>().unwrap();
let pointer_width = if version_info.contains("64 bit (AMD64)") {
64
} else {
32
};
Ok(Some(InterpreterConfig {
major,
minor,
interpreter_kind: InterpreterKind::CPython,
abiflags: String::new(),
ext_suffix: String::new(),
abi_tag: None,
pointer_width: Some(pointer_width),
}))
} else {
Ok(None)
}
}

#[derive(Debug, Clone, Copy, Eq, PartialEq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum InterpreterKind {
Expand Down Expand Up @@ -512,7 +536,7 @@ impl PythonInterpreter {
};
// Try py -x.y on Windows
let output = Command::new("py")
.arg(format!("-{}", ver))
.arg(format!("-{}-{}", ver, target.pointer_width()))
.args(&["-c", GET_INTERPRETER_METADATA])
.output();
match output {
Expand Down

0 comments on commit a074b33

Please sign in to comment.