From 0d91281d9603fd29822df232dd9e442b2230ff3f Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Sun, 10 Nov 2024 15:34:35 +0900 Subject: [PATCH 1/4] fix(windows): add venv path --- crates/erg_common/python_util.rs | 56 ++++++++++++++++++++++++++------ tests/test.rs | 7 +--- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/crates/erg_common/python_util.rs b/crates/erg_common/python_util.rs index 05c898453..ef31ea247 100644 --- a/crates/erg_common/python_util.rs +++ b/crates/erg_common/python_util.rs @@ -609,23 +609,59 @@ fn get_poetry_virtualenv_path() -> Option { .then_some(path.trim().to_string()) } +fn get_uv_python_venv_path() -> Option { + let out = if cfg!(windows) { + Command::new("cmd") + .arg("/C") + .args(&["uv", "python", "find"]) + .output() + .ok()? + } else { + Command::new("sh") + .arg("-c") + .args(&["uv", "python", "find"]) + .output() + .ok()? + }; + String::from_utf8(out.stdout) + .ok() + .map(|s| s.trim().to_string()) +} + pub fn _opt_which_python() -> Result { if let Some(path) = which_python_from_toml() { return Ok(path); } - if Path::new("./.venv/bin/python").is_file() { - let path = canonicalize("./.venv/bin/python").unwrap(); - return Ok(path.to_string_lossy().to_string()); - } else if let Some(path) = get_poetry_virtualenv_path() { + if let Some(path) = get_poetry_virtualenv_path() { return Ok(format!("{path}/bin/python")); + } else if let Some(path) = get_uv_python_venv_path() { + return Ok(path); } - let (cmd, python) = if cfg!(windows) { - ("where", "python") + + let path = if cfg!(windows) { + r".venv\Scripts\python.exe" } else { - ("which", "python3") + ".venv/bin/python" + }; + if Path::new(&path).is_file() { + let path = canonicalize(&path).unwrap(); + return Ok(path.to_string_lossy().to_string()); + } + let out = if cfg!(windows) { + Command::new("cmd") + .arg("/C") + .arg("where") + .arg("python") + .output() + } else { + Command::new("sh") + .arg("-c") + .arg("which") + .arg("python3") + .output() }; - let Ok(out) = Command::new(cmd).arg(python).output() else { - return Err(format!("{}: {python} not found", fn_name_full!())); + let Ok(out) = out else { + return Err(format!("{}: python not found", fn_name_full!())); }; let Ok(res) = String::from_utf8(out.stdout) else { return Err(format!( @@ -635,7 +671,7 @@ pub fn _opt_which_python() -> Result { }; let res = res.split('\n').next().unwrap_or("").replace('\r', ""); if res.is_empty() { - return Err(format!("{}: {python} not found", fn_name_full!())); + return Err(format!("{}: python not found", fn_name_full!())); } else if res.contains("pyenv") && cfg!(windows) { // because pyenv-win does not support `-c` option return Err("cannot use pyenv-win".into()); diff --git a/tests/test.rs b/tests/test.rs index 0d2fef90e..426c1b0d0 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -183,12 +183,7 @@ fn exec_fib() -> Result<(), ()> { #[test] fn exec_helloworld() -> Result<(), ()> { - // HACK: When running the test with Windows, the exit code is 1 (the cause is unknown) - if cfg!(windows) && env_python_version().unwrap().minor >= Some(8) { - expect_end_with("examples/helloworld.er", 0, 1) - } else { - expect_success("examples/helloworld.er", 0) - } + expect_success("examples/helloworld.er", 0) } #[test] From 3952b7469e2eeed797fbc9f2924b020926affe0c Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Sun, 10 Nov 2024 22:50:15 +0900 Subject: [PATCH 2/4] fix: get_uv_python_venv_path if uv isn't installed --- crates/erg_common/python_util.rs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/crates/erg_common/python_util.rs b/crates/erg_common/python_util.rs index ef31ea247..3f71dd0da 100644 --- a/crates/erg_common/python_util.rs +++ b/crates/erg_common/python_util.rs @@ -593,13 +593,13 @@ fn get_poetry_virtualenv_path() -> Option { let out = if cfg!(windows) { Command::new("cmd") .arg("/C") - .arg("poetry env info -p") + .args(["poetry", "env", "info", "-p"]) .output() .ok()? } else { Command::new("sh") .arg("-c") - .arg("poetry env info -p") + .args(["poetry", "env", "info", "-p"]) .output() .ok()? }; @@ -613,19 +613,20 @@ fn get_uv_python_venv_path() -> Option { let out = if cfg!(windows) { Command::new("cmd") .arg("/C") - .args(&["uv", "python", "find"]) + .args(["uv", "python", "find"]) .output() .ok()? } else { Command::new("sh") .arg("-c") - .args(&["uv", "python", "find"]) + .args(["uv", "python", "find"]) .output() .ok()? }; - String::from_utf8(out.stdout) - .ok() - .map(|s| s.trim().to_string()) + let path = String::from_utf8(out.stdout).ok()?; + Path::new(path.trim()) + .exists() + .then_some(path.trim().to_string()) } pub fn _opt_which_python() -> Result { @@ -644,7 +645,7 @@ pub fn _opt_which_python() -> Result { ".venv/bin/python" }; if Path::new(&path).is_file() { - let path = canonicalize(&path).unwrap(); + let path = canonicalize(path).unwrap(); return Ok(path.to_string_lossy().to_string()); } let out = if cfg!(windows) { From c9b803a3012e1e4c59aaf99a59bfcd57012ff2e6 Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Thu, 14 Nov 2024 00:11:59 +0900 Subject: [PATCH 3/4] fix(er): encoding utf8 --- examples/helloworld.er | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/helloworld.er b/examples/helloworld.er index e989381e2..8479786e5 100644 --- a/examples/helloworld.er +++ b/examples/helloworld.er @@ -1,3 +1,6 @@ +sys = pyimport "sys" +sys.stdout.reconfigure!(encoding:="utf-8") + print! "Hello, world!" print! "こんにちは、世界!" print! "Γειά σου Κόσμε!" From 2febb7179904e5e4d1bd3453391ba0466778a95d Mon Sep 17 00:00:00 2001 From: GreasySlug <9619abgoni@gmail.com> Date: Thu, 14 Nov 2024 00:41:18 +0900 Subject: [PATCH 4/4] fix(linux): don't separate arguments --- crates/erg_common/python_util.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/crates/erg_common/python_util.rs b/crates/erg_common/python_util.rs index 3f71dd0da..fe3b0b72b 100644 --- a/crates/erg_common/python_util.rs +++ b/crates/erg_common/python_util.rs @@ -655,11 +655,7 @@ pub fn _opt_which_python() -> Result { .arg("python") .output() } else { - Command::new("sh") - .arg("-c") - .arg("which") - .arg("python3") - .output() + Command::new("sh").arg("-c").arg("which python3").output() }; let Ok(out) = out else { return Err(format!("{}: python not found", fn_name_full!()));