Skip to content

Commit cf8a748

Browse files
committed
Simplify API.
1 parent d8c2fba commit cf8a748

File tree

2 files changed

+19
-61
lines changed

2 files changed

+19
-61
lines changed

macros/src/error.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use proc_macro::Span;
22
use proc_macro2::TokenStream;
3-
use pyo3::{prelude::*, types::PyTraceback, Bound, PyErr, PyResult, PyTypeInfo, Python, IntoPyObject};
3+
use pyo3::{prelude::*, types::PyTraceback, Bound, IntoPyObject, PyErr, PyResult, PyTypeInfo, Python};
44
use quote::{quote, quote_spanned};
55

66
/// Format a nice error message for a python compilation error.

src/context.rs

+18-60
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::PythonBlock;
33
use pyo3::{
44
prelude::*,
55
types::{PyCFunction, PyDict},
6-
FromPyObject, Py, PyResult, Python, IntoPyObject,
6+
FromPyObject, IntoPyObject, Py, PyResult, Python,
77
};
88

99
/// An execution context for Python code.
@@ -45,21 +45,13 @@ pub struct Context {
4545
impl Context {
4646
/// Create a new context for running Python code.
4747
///
48-
/// This function temporarily acquires the GIL.
49-
/// If you already have the GIL, you can use [`Context::new_with_gil`] instead.
50-
///
5148
/// This function panics if it fails to create the context.
5249
#[allow(clippy::new_without_default)]
5350
pub fn new() -> Self {
5451
Python::with_gil(Self::new_with_gil)
5552
}
5653

57-
/// Create a new context for running Python code.
58-
///
59-
/// You must acquire the GIL to call this function.
60-
///
61-
/// This function panics if it fails to create the context.
62-
pub fn new_with_gil(py: Python) -> Self {
54+
pub(crate) fn new_with_gil(py: Python) -> Self {
6355
match Self::try_new(py) {
6456
Ok(x) => x,
6557
Err(error) => {
@@ -76,25 +68,15 @@ impl Context {
7668
}
7769

7870
/// Get the globals as dictionary.
79-
pub fn globals<'p>(&self, py: Python<'p>) -> &Bound<'p, PyDict> {
80-
self.globals.bind(py)
71+
pub fn globals<'p>(&self) -> &Py<PyDict> {
72+
&self.globals
8173
}
8274

8375
/// Retrieve a global variable from the context.
8476
///
85-
/// This function temporarily acquires the GIL.
86-
/// If you already have the GIL, you can use [`Context::get_with_gil`] instead.
87-
///
8877
/// This function panics if the variable doesn't exist, or the conversion fails.
8978
pub fn get<T: for<'p> FromPyObject<'p>>(&self, name: &str) -> T {
90-
Python::with_gil(|py| self.get_with_gil(py, name))
91-
}
92-
93-
/// Retrieve a global variable from the context.
94-
///
95-
/// This function panics if the variable doesn't exist, or the conversion fails.
96-
pub fn get_with_gil<'p, T: FromPyObject<'p>>(&'p self, py: Python<'p>, name: &str) -> T {
97-
match self.globals(py).get_item(name) {
79+
Python::with_gil(|py| match self.globals.bind(py).get_item(name) {
9880
Err(_) | Ok(None) => panic!("Python context does not contain a variable named `{}`", name),
9981
Ok(Some(value)) => match FromPyObject::extract_bound(&value) {
10082
Ok(value) => value,
@@ -103,30 +85,20 @@ impl Context {
10385
panic!("Unable to convert `{}` to `{}`", name, std::any::type_name::<T>());
10486
}
10587
},
106-
}
88+
})
10789
}
10890

10991
/// Set a global variable in the context.
11092
///
111-
/// This function temporarily acquires the GIL.
112-
/// If you already have the GIL, you can use [`Context::set_with_gil`] instead.
113-
///
11493
/// This function panics if the conversion fails.
11594
pub fn set<T: for<'p> IntoPyObject<'p>>(&self, name: &str, value: T) {
116-
Python::with_gil(|py| self.set_with_gil(py, name, value));
117-
}
118-
119-
/// Set a global variable in the context.
120-
///
121-
/// This function panics if the conversion fails.
122-
pub fn set_with_gil<'p, T: IntoPyObject<'p>>(&self, py: Python<'p>, name: &str, value: T) {
123-
match self.globals(py).set_item(name, value) {
95+
Python::with_gil(|py| match self.globals().bind(py).set_item(name, value) {
12496
Ok(()) => (),
12597
Err(e) => {
12698
e.print(py);
12799
panic!("Unable to set `{}` from a `{}`", name, std::any::type_name::<T>());
128100
}
129-
}
101+
})
130102
}
131103

132104
/// Add a wrapped `#[pyfunction]` or `#[pymodule]` using its own `__name__`.
@@ -152,20 +124,15 @@ impl Context {
152124
/// });
153125
/// }
154126
/// ```
155-
///
156-
/// This function temporarily acquires the GIL.
157-
/// If you already have the GIL, you can use [`Context::add_wrapped_with_gil`] instead.
158127
pub fn add_wrapped(&self, wrapper: &impl Fn(Python) -> PyResult<Bound<'_, PyCFunction>>) {
159-
Python::with_gil(|py| self.add_wrapped_with_gil(py, wrapper));
160-
}
161-
162-
/// Add a wrapped `#[pyfunction]` or `#[pymodule]` using its own `__name__`.
163-
///
164-
/// See [Context::add_wrapped].
165-
pub fn add_wrapped_with_gil<'p>(&self, py: Python<'p>, wrapper: &impl Fn(Python) -> PyResult<Bound<'_, PyCFunction>>) {
166-
let obj = wrapper(py).unwrap();
167-
let name = obj.getattr("__name__").expect("Missing __name__");
168-
self.set_with_gil(py, name.extract().unwrap(), obj);
128+
Python::with_gil(|py| {
129+
let obj = wrapper(py).unwrap();
130+
let name = obj.getattr("__name__").expect("Missing __name__");
131+
if let Err(e) = self.globals().bind(py).set_item(name, obj) {
132+
e.print(py);
133+
panic!("Unable to add wrapped function");
134+
}
135+
})
169136
}
170137

171138
/// Run Python code using this context.
@@ -181,22 +148,13 @@ impl Context {
181148
/// });
182149
/// ```
183150
///
184-
/// This function temporarily acquires the GIL.
185-
/// If you already have the GIL, you can use [`Context::run_with_gil`] instead.
186-
///
187151
/// This function panics if the Python code fails.
188152
pub fn run<F: FnOnce(&Bound<PyDict>)>(&self, code: PythonBlock<F>) {
189153
Python::with_gil(|py| self.run_with_gil(py, code));
190154
}
191155

192-
/// Run Python code using this context.
193-
///
194-
/// This function should be called using the `python!{}` macro, just like
195-
/// [`Context::run`].
196-
///
197-
/// This function panics if the Python code fails.
198-
pub fn run_with_gil<F: FnOnce(&Bound<PyDict>)>(&self, py: Python<'_>, code: PythonBlock<F>) {
199-
(code.set_variables)(self.globals(py));
156+
pub(crate) fn run_with_gil<F: FnOnce(&Bound<PyDict>)>(&self, py: Python<'_>, code: PythonBlock<F>) {
157+
(code.set_variables)(self.globals().bind(py));
200158
match run_python_code(py, self, code.bytecode) {
201159
Ok(_) => (),
202160
Err(e) => {

0 commit comments

Comments
 (0)