Skip to content

Commit

Permalink
make IntoPyDict::into_py_dict fallible
Browse files Browse the repository at this point in the history
  • Loading branch information
Icxolu committed Oct 1, 2024
1 parent 50e4b38 commit b324e3a
Show file tree
Hide file tree
Showing 33 changed files with 129 additions and 83 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ fn main() -> PyResult<()> {
let sys = py.import("sys")?;
let version: String = sys.getattr("version")?.extract()?;

let locals = [("os", py.import("os")?)].into_py_dict(py);
let locals = [("os", py.import("os")?)].into_py_dict(py)?;
let code = c_str!("os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'");
let user: String = py.eval(code, None, Some(&locals))?.extract()?;

Expand Down
7 changes: 5 additions & 2 deletions guide/src/exception.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,18 @@ use pyo3::exceptions::PyException;

create_exception!(mymodule, CustomError, PyException);

# fn main() -> PyResult<()> {
Python::with_gil(|py| {
let ctx = [("CustomError", py.get_type::<CustomError>())].into_py_dict(py);
let ctx = [("CustomError", py.get_type::<CustomError>())].into_py_dict(py)?;
pyo3::py_run!(
py,
*ctx,
"assert str(CustomError) == \"<class 'mymodule.CustomError'>\""
);
pyo3::py_run!(py, *ctx, "assert CustomError('oops').args == ('oops',)");
});
# Ok(())
})
# }
```

When using PyO3 to create an extension module, you can add the new exception to
Expand Down
2 changes: 1 addition & 1 deletion guide/src/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ fn func() -> String {
# use pyo3::types::IntoPyDict;
# use pyo3::ffi::c_str;
# let parent_module = wrap_pymodule!(parent_module)(py);
# let ctx = [("parent_module", parent_module)].into_py_dict(py);
# let ctx = [("parent_module", parent_module)].into_py_dict(py).unwrap();
#
# py.run(c_str!("assert parent_module.child_module.func() == 'func'"), None, Some(&ctx)).unwrap();
# })
Expand Down
2 changes: 1 addition & 1 deletion guide/src/python-from-rust/calling-existing-code.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def leaky_relu(x, slope=0.01):
let relu_result: f64 = activators.getattr("relu")?.call1((-1.0,))?.extract()?;
assert_eq!(relu_result, 0.0);

let kwargs = [("slope", 0.2)].into_py_dict(py);
let kwargs = [("slope", 0.2)].into_py_dict(py)?;
let lrelu_result: f64 = activators
.getattr("leaky_relu")?
.call((-1.0,), Some(&kwargs))?
Expand Down
6 changes: 3 additions & 3 deletions guide/src/python-from-rust/function-calls.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,17 +90,17 @@ fn main() -> PyResult<()> {
.into();

// call object with PyDict
let kwargs = [(key1, val1)].into_py_dict(py);
let kwargs = [(key1, val1)].into_py_dict(py)?;
fun.call(py, (), Some(&kwargs))?;

// pass arguments as Vec
let kwargs = vec![(key1, val1), (key2, val2)];
fun.call(py, (), Some(&kwargs.into_py_dict(py)))?;
fun.call(py, (), Some(&kwargs.into_py_dict(py)?))?;

// pass arguments as HashMap
let mut kwargs = HashMap::<&str, i32>::new();
kwargs.insert(key1, 1);
fun.call(py, (), Some(&kwargs.into_py_dict(py)))?;
fun.call(py, (), Some(&kwargs.into_py_dict(py)?))?;

Ok(())
})
Expand Down
4 changes: 2 additions & 2 deletions src/conversions/anyhow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ mod test_anyhow {
let pyerr = PyErr::from(err);

Python::with_gil(|py| {
let locals = [("err", pyerr)].into_py_dict(py);
let locals = [("err", pyerr)].into_py_dict(py).unwrap();
let pyerr = py
.run(ffi::c_str!("raise err"), None, Some(&locals))
.unwrap_err();
Expand All @@ -164,7 +164,7 @@ mod test_anyhow {
let pyerr = PyErr::from(err);

Python::with_gil(|py| {
let locals = [("err", pyerr)].into_py_dict(py);
let locals = [("err", pyerr)].into_py_dict(py).unwrap();
let pyerr = py
.run(ffi::c_str!("raise err"), None, Some(&locals))
.unwrap_err();
Expand Down
2 changes: 1 addition & 1 deletion src/conversions/chrono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1365,7 +1365,7 @@ mod tests {
fn test_pyo3_offset_fixed_frompyobject_created_in_python(timestamp in 0..(i32::MAX as i64), timedelta in -86399i32..=86399i32) {
Python::with_gil(|py| {

let globals = [("datetime", py.import("datetime").unwrap())].into_py_dict(py);
let globals = [("datetime", py.import("datetime").unwrap())].into_py_dict(py).unwrap();
let code = format!("datetime.datetime.fromtimestamp({}).replace(tzinfo=datetime.timezone(datetime.timedelta(seconds={})))", timestamp, timedelta);
let t = py.eval(&CString::new(code).unwrap(), Some(&globals), None).unwrap();

Expand Down
4 changes: 2 additions & 2 deletions src/conversions/eyre.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ mod tests {
let pyerr = PyErr::from(err);

Python::with_gil(|py| {
let locals = [("err", pyerr)].into_py_dict(py);
let locals = [("err", pyerr)].into_py_dict(py).unwrap();
let pyerr = py
.run(ffi::c_str!("raise err"), None, Some(&locals))
.unwrap_err();
Expand All @@ -170,7 +170,7 @@ mod tests {
let pyerr = PyErr::from(err);

Python::with_gil(|py| {
let locals = [("err", pyerr)].into_py_dict(py);
let locals = [("err", pyerr)].into_py_dict(py).unwrap();
let pyerr = py
.run(ffi::c_str!("raise err"), None, Some(&locals))
.unwrap_err();
Expand Down
4 changes: 2 additions & 2 deletions src/conversions/hashbrown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use crate::{
set::{new_from_iter, try_new_from_iter, PySetMethods},
PyDict, PyFrozenSet, PySet,
},
Bound, BoundObject, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
Bound, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
};
use std::{cmp, hash};

Expand Down Expand Up @@ -238,7 +238,7 @@ mod tests {
let mut map = hashbrown::HashMap::<i32, i32>::new();
map.insert(1, 1);

let py_map = map.into_py_dict(py);
let py_map = map.into_py_dict(py).unwrap();

assert_eq!(py_map.len(), 1);
assert_eq!(
Expand Down
4 changes: 2 additions & 2 deletions src/conversions/indexmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@ mod test_indexmap {
let mut map = indexmap::IndexMap::<i32, i32>::new();
map.insert(1, 1);

let py_map = map.into_py_dict(py);
let py_map = map.into_py_dict(py).unwrap();

assert_eq!(py_map.len(), 1);
assert_eq!(
Expand Down Expand Up @@ -265,7 +265,7 @@ mod test_indexmap {
}
}

let py_map = map.clone().into_py_dict(py);
let py_map = map.clone().into_py_dict(py).unwrap();

let trip_map = py_map.extract::<indexmap::IndexMap<i32, i32>>().unwrap();

Expand Down
15 changes: 9 additions & 6 deletions src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,13 @@ macro_rules! impl_exception_boilerplate_bound {
///
/// import_exception!(socket, gaierror);
///
/// # fn main() -> pyo3::PyResult<()> {
/// Python::with_gil(|py| {
/// let ctx = [("gaierror", py.get_type::<gaierror>())].into_py_dict(py);
/// let ctx = [("gaierror", py.get_type::<gaierror>())].into_py_dict(py)?;
/// pyo3::py_run!(py, *ctx, "import socket; assert gaierror is socket.gaierror");
/// });
/// # Ok(())
/// })
/// # }
///
/// ```
#[macro_export]
Expand Down Expand Up @@ -905,7 +908,7 @@ mod tests {

Python::with_gil(|py| {
let error_type = py.get_type::<CustomError>();
let ctx = [("CustomError", error_type)].into_py_dict(py);
let ctx = [("CustomError", error_type)].into_py_dict(py).unwrap();
let type_description: String = py
.eval(ffi::c_str!("str(CustomError)"), None, Some(&ctx))
.unwrap()
Expand All @@ -932,7 +935,7 @@ mod tests {
create_exception!(mymodule.exceptions, CustomError, PyException);
Python::with_gil(|py| {
let error_type = py.get_type::<CustomError>();
let ctx = [("CustomError", error_type)].into_py_dict(py);
let ctx = [("CustomError", error_type)].into_py_dict(py).unwrap();
let type_description: String = py
.eval(ffi::c_str!("str(CustomError)"), None, Some(&ctx))
.unwrap()
Expand All @@ -951,7 +954,7 @@ mod tests {

Python::with_gil(|py| {
let error_type = py.get_type::<CustomError>();
let ctx = [("CustomError", error_type)].into_py_dict(py);
let ctx = [("CustomError", error_type)].into_py_dict(py).unwrap();
let type_description: String = py
.eval(ffi::c_str!("str(CustomError)"), None, Some(&ctx))
.unwrap()
Expand Down Expand Up @@ -984,7 +987,7 @@ mod tests {

Python::with_gil(|py| {
let error_type = py.get_type::<CustomError>();
let ctx = [("CustomError", error_type)].into_py_dict(py);
let ctx = [("CustomError", error_type)].into_py_dict(py).unwrap();
let type_description: String = py
.eval(ffi::c_str!("str(CustomError)"), None, Some(&ctx))
.unwrap()
Expand Down
4 changes: 2 additions & 2 deletions src/impl_/extract_argument.rs
Original file line number Diff line number Diff line change
Expand Up @@ -802,7 +802,7 @@ mod tests {

Python::with_gil(|py| {
let args = PyTuple::empty(py);
let kwargs = [("foo", 0u8)].into_py_dict(py);
let kwargs = [("foo", 0u8)].into_py_dict(py).unwrap();
let err = unsafe {
function_description
.extract_arguments_tuple_dict::<NoVarargs, NoVarkeywords>(
Expand Down Expand Up @@ -833,7 +833,7 @@ mod tests {

Python::with_gil(|py| {
let args = PyTuple::empty(py);
let kwargs = [(1u8, 1u8)].into_py_dict(py);
let kwargs = [(1u8, 1u8)].into_py_dict(py).unwrap();
let err = unsafe {
function_description
.extract_arguments_tuple_dict::<NoVarargs, NoVarkeywords>(
Expand Down
2 changes: 1 addition & 1 deletion src/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1960,7 +1960,7 @@ mod tests {

assert_repr(obj.call1(py, ((('x', 1),),)).unwrap().bind(py), "{'x': 1}");
assert_repr(
obj.call(py, (), Some(&[('x', 1)].into_py_dict(py)))
obj.call(py, (), Some(&[('x', 1)].into_py_dict(py).unwrap()))
.unwrap()
.bind(py),
"{'x': 1}",
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@
//! let sys = py.import("sys")?;
//! let version: String = sys.getattr("version")?.extract()?;
//!
//! let locals = [("os", py.import("os")?)].into_py_dict(py);
//! let locals = [("os", py.import("os")?)].into_py_dict(py)?;
//! let code = c_str!("os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'");
//! let user: String = py.eval(code, None, Some(&locals))?.extract()?;
//!
Expand Down
9 changes: 6 additions & 3 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,13 @@
/// }
/// }
///
/// # fn main() -> PyResult<()> {
/// Python::with_gil(|py| {
/// let locals = [("C", py.get_type::<MyClass>())].into_py_dict(py);
/// let locals = [("C", py.get_type::<MyClass>())].into_py_dict(py)?;
/// pyo3::py_run!(py, *locals, "c = C()");
/// });
/// # Ok(())
/// })
/// # }
/// ```
#[macro_export]
macro_rules! py_run {
Expand All @@ -102,7 +105,7 @@ macro_rules! py_run_impl {
($py:expr, $($val:ident)+, $code:expr) => {{
use $crate::types::IntoPyDict;
use $crate::ToPyObject;
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py);
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py).unwrap();
$crate::py_run_impl!($py, *d, $code)
}};
($py:expr, *$dict:expr, $code:expr) => {{
Expand Down
2 changes: 1 addition & 1 deletion src/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -872,7 +872,7 @@ mod tests {
.unwrap();
assert_eq!(v, 1);

let d = [("foo", 13)].into_py_dict(py);
let d = [("foo", 13)].into_py_dict(py).unwrap();

// Inject our own global namespace
let v: i32 = py
Expand Down
4 changes: 2 additions & 2 deletions src/tests/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ mod inner {
// Case1: idents & no err_msg
($py:expr, $($val:ident)+, $code:expr, $err:ident) => {{
use pyo3::types::IntoPyDict;
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py);
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py).unwrap();
py_expect_exception!($py, *d, $code, $err)
}};
// Case2: dict & no err_msg
Expand Down Expand Up @@ -126,7 +126,7 @@ mod inner {
f: impl FnOnce(&Bound<'py, PyList>) -> PyResult<R>,
) -> PyResult<R> {
let warnings = py.import("warnings")?;
let kwargs = [("record", true)].into_py_dict(py);
let kwargs = [("record", true)].into_py_dict(py)?;
let catch_warnings = warnings
.getattr("catch_warnings")?
.call((), Some(&kwargs))?;
Expand Down
2 changes: 1 addition & 1 deletion src/types/any.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1701,7 +1701,7 @@ class NonHeapNonDescriptorInt:
fn test_call_with_kwargs() {
Python::with_gil(|py| {
let list = vec![3, 6, 5, 4, 7].to_object(py);
let dict = vec![("reverse", true)].into_py_dict(py);
let dict = vec![("reverse", true)].into_py_dict(py).unwrap();
list.call_method(py, "sort", (), Some(&dict)).unwrap();
assert_eq!(list.extract::<Vec<i32>>(py).unwrap(), vec![7, 6, 5, 4, 3]);
});
Expand Down
Loading

0 comments on commit b324e3a

Please sign in to comment.