Skip to content

Commit

Permalink
Add a section on memory management for extension
Browse files Browse the repository at this point in the history
Adding a special case of memory management when writing an extension.

This is a documentation of: PyO3#1056 and PyO3#2853
  • Loading branch information
haixuanTao authored Jan 7, 2023
1 parent 94c568d commit 59825f9
Showing 1 changed file with 50 additions and 0 deletions.
50 changes: 50 additions & 0 deletions guide/src/memory.md
Original file line number Diff line number Diff line change
Expand Up @@ -226,3 +226,53 @@ Python::with_gil(|py| {
# Ok(())
# }
```

## On writing extension

Using `#[pyfunction]` and `#[pymethods]` makes `Python::with_gil` a no-op and
the GIL is held for the whole duration that the function is called (from
Python). Any `PyAny` object created within the function will only be freed at the
end of the function call.

```rust
# use pyo3::prelude::*;
# use pyo3::types::PyString;

#[pyfunction]
fn exported_function() -> PyResult<()> {
for _ in 0..10 {
Python::with_gil(|py| -> PyResult<()> {
let hello: &PyString = py.eval("\"Hello World!\"", None, None)?.extract()?;
println!("Python says: {}", hello);
Ok(())
})?;
}
Ok(()) // 10 `hello` will be held in memory until here.
}
```

You will have to use the unsafe method `Python::new_pool` mentioned above to fix this
memory growth.

```rust
# use pyo3::prelude::*;
# use pyo3::types::PyString;

#[pyfunction]
fn exported_function(py: Python) -> PyResult<()> {
for _ in 0..10 {
let pool = unsafe { py.new_pool() };
let py = pool.python();
let hello: &PyString = py.eval("\"Hello World!\"", None, None)?.extract()?;
println!("Python says: {}", hello);
// `hello` memory is released here
}
Ok(())
}
```

For more on this issue: [#1056](https://github.com/PyO3/pyo3/issues/1056)




0 comments on commit 59825f9

Please sign in to comment.