indygreg / PyOxidizer

A modern Python application packaging and distribution tool
Mozilla Public License 2.0
5.5k stars 239 forks source link

Very strange python behavior #734

Open jafioti opened 9 months ago

jafioti commented 9 months ago

I have some python code which is valid python syntax, but fails to run:

a = [1, 2, 3]
b = [3, 2, 1]
c = [a[i] * b[i] for i in range(len(a))]
print(c)

Which produces the following error: Error: NameError: name 'a' is not defined This code runs fine on my local python interpreter, but not when I run it through this function:

pub fn run_python_code(code: &str, inputs: &[(String, String)]) -> String {
    let mut config = pyembed::OxidizedPythonInterpreterConfig::default();
    config.interpreter_config.filesystem_encoding = Some("utf-8".to_string());
    config.set_missing_path_configuration = false;
    config.argv = Some(vec!["python".into()]);
    config.interpreter_config.executable = Some("python".into());

    pyembed::MainPythonInterpreter::new(config)
        .unwrap()
        .with_gil(|py| {
            println!("{}", py.version());
            py.run(
                "import sys; from io import StringIO; sys.stdout = _stdout = StringIO()",
                None,
                None,
            )
            .unwrap();
            let error = if let Err(e) = py.run(code, None, Some(inputs.to_vec().into_py_dict(py))) {
                format!("Error: {}", e.to_string())
            } else {
                "".to_string()
            };
            let output: String = py
                .eval("sys.stdout.getvalue()", None, None)
                .unwrap()
                .extract()
                .unwrap_or_default();

            py.run("sys.stdout = sys.__stdout__", None, None).unwrap();
            let output = output.trim().to_string().replace("None", "");
            if error.is_empty() {
                output
            } else {
                error
            }
        })
}

Notably this runs through that function fine:

a = [1, 2, 3]
b = [3, 2, 1]
c = [a * b for a, b in zip(a, b)]
print(c)

which should be logically equivalent code Am I setting up the interpreter wrong or something?