Skip to content

Commit

Permalink
Add Python::with_gil
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Jul 13, 2020
1 parent cfa5b2e commit 785f18c
Show file tree
Hide file tree
Showing 6 changed files with 226 additions and 211 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [Unreleased]
### Added
- Add FFI definitions `Py_FinalizeEx`, `PyOS_getsig`, `PyOS_setsig`. [#1021](https://github.com/PyO3/pyo3/pull/1021)
- Add `Python::with_gil` for executing a closure with the Python GIL. [#1037](https://github.com/PyO3/pyo3/pull/1037)

### Changed
- Correct FFI definitions `Py_SetProgramName` and `Py_SetPythonHome` to take `*const` argument instead of `*mut`. [#1021](https://github.com/PyO3/pyo3/pull/1021)
Expand Down
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,12 @@ use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

fn main() -> Result<(), ()> {
let gil = Python::acquire_gil();
let py = gil.python();
main_(py).map_err(|e| {
// We can't display Python exceptions via std::fmt::Display,
// so print the error here manually.
e.print_and_set_sys_last_vars(py);
Python::with_gil(|py| {
main_(py).map_err(|e| {
// We can't display Python exceptions via std::fmt::Display,
// so print the error here manually.
e.print_and_set_sys_last_vars(py);
})
})
}

Expand Down
78 changes: 40 additions & 38 deletions guide/src/python_from_rust.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ module available in your environment.
use pyo3::prelude::*;

fn main() -> PyResult<()> {
let gil = Python::acquire_gil();
let py = gil.python();
let builtins = PyModule::import(py, "builtins")?;
let total: i32 = builtins.call1("sum", (vec![1, 2, 3],))?.extract()?;
assert_eq!(total, 6);
Ok(())
Python::with_gil(|py| {
let builtins = PyModule::import(py, "builtins")?;
let total: i32 = builtins.call1("sum", (vec![1, 2, 3],))?.extract()?;
assert_eq!(total, 6);
Ok(())
})
}
```

Expand All @@ -33,14 +33,14 @@ use pyo3::prelude::*;
use pyo3::types::IntoPyDict;

fn main() -> Result<(), ()> {
let gil = Python::acquire_gil();
let py = gil.python();
let result = py.eval("[i * 10 for i in range(5)]", None, None).map_err(|e| {
e.print_and_set_sys_last_vars(py);
})?;
let res: Vec<i64> = result.extract().unwrap();
assert_eq!(res, vec![0, 10, 20, 30, 40]);
Ok(())
Python::with_gil(|py| {
let result = py.eval("[i * 10 for i in range(5)]", None, None).map_err(|e| {
e.print_and_set_sys_last_vars(py);
})?;
let res: Vec<i64> = result.extract().unwrap();
assert_eq!(res, vec![0, 10, 20, 30, 40]);
Ok(())
})
}
```

Expand Down Expand Up @@ -76,18 +76,19 @@ impl PyObjectProtocol for UserData {
Ok(format!("User {}(id: {})", self.name, self.id))
}
}
let gil = Python::acquire_gil();
let py = gil.python();
let userdata = UserData {
id: 34,
name: "Yu".to_string(),
};
let userdata = PyCell::new(py, userdata).unwrap();
let userdata_as_tuple = (34, "Yu");
py_run!(py, userdata userdata_as_tuple, r#"

Python::with_gil(|py| {
let userdata = UserData {
id: 34,
name: "Yu".to_string(),
};
let userdata = PyCell::new(py, userdata).unwrap();
let userdata_as_tuple = (34, "Yu");
py_run!(py, userdata userdata_as_tuple, r#"
assert repr(userdata) == "User Yu(id: 34)"
assert userdata.as_tuple() == userdata_as_tuple
"#);
"#);
})
# }
```

Expand All @@ -100,26 +101,27 @@ can be used to generate a Python module which can then be used just as if it was
```rust
use pyo3::{prelude::*, types::{IntoPyDict, PyModule}};
# fn main() -> PyResult<()> {
let gil = Python::acquire_gil();
let py = gil.python();
let activators = PyModule::from_code(py, r#"
Python::with_gil(|py| {
let activators = PyModule::from_code(py, r#"
def relu(x):
"""see https://en.wikipedia.org/wiki/Rectifier_(neural_networks)"""
return max(0.0, x)
def leaky_relu(x, slope=0.01):
return x if x >= 0 else x * slope
"#, "activators.py", "activators")?;

let relu_result: f64 = activators.call1("relu", (-1.0,))?.extract()?;
assert_eq!(relu_result, 0.0);

let kwargs = [("slope", 0.2)].into_py_dict(py);
let lrelu_result: f64 = activators
.call("leaky_relu", (-1.0,), Some(kwargs))?
.extract()?;
assert_eq!(lrelu_result, -0.2);
# Ok(()) }
"#, "activators.py", "activators")?;

let relu_result: f64 = activators.call1("relu", (-1.0,))?.extract()?;
assert_eq!(relu_result, 0.0);

let kwargs = [("slope", 0.2)].into_py_dict(py);
let lrelu_result: f64 = activators
.call("leaky_relu", (-1.0,), Some(kwargs))?
.extract()?;
assert_eq!(lrelu_result, -0.2);
# Ok(())
})
# }
```

[`Python::run`]: https://pyo3.rs/master/doc/pyo3/struct.Python.html#method.run
Expand Down
Loading

0 comments on commit 785f18c

Please sign in to comment.