Skip to content

Commit b324e3a

Browse files
committed
make IntoPyDict::into_py_dict fallible
1 parent 50e4b38 commit b324e3a

33 files changed

+129
-83
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ fn main() -> PyResult<()> {
156156
let sys = py.import("sys")?;
157157
let version: String = sys.getattr("version")?.extract()?;
158158

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

guide/src/exception.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,18 @@ use pyo3::exceptions::PyException;
2323

2424
create_exception!(mymodule, CustomError, PyException);
2525

26+
# fn main() -> PyResult<()> {
2627
Python::with_gil(|py| {
27-
let ctx = [("CustomError", py.get_type::<CustomError>())].into_py_dict(py);
28+
let ctx = [("CustomError", py.get_type::<CustomError>())].into_py_dict(py)?;
2829
pyo3::py_run!(
2930
py,
3031
*ctx,
3132
"assert str(CustomError) == \"<class 'mymodule.CustomError'>\""
3233
);
3334
pyo3::py_run!(py, *ctx, "assert CustomError('oops').args == ('oops',)");
34-
});
35+
# Ok(())
36+
})
37+
# }
3538
```
3639

3740
When using PyO3 to create an extension module, you can add the new exception to

guide/src/module.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ fn func() -> String {
9090
# use pyo3::types::IntoPyDict;
9191
# use pyo3::ffi::c_str;
9292
# let parent_module = wrap_pymodule!(parent_module)(py);
93-
# let ctx = [("parent_module", parent_module)].into_py_dict(py);
93+
# let ctx = [("parent_module", parent_module)].into_py_dict(py).unwrap();
9494
#
9595
# py.run(c_str!("assert parent_module.child_module.func() == 'func'"), None, Some(&ctx)).unwrap();
9696
# })

guide/src/python-from-rust/calling-existing-code.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ def leaky_relu(x, slope=0.01):
131131
let relu_result: f64 = activators.getattr("relu")?.call1((-1.0,))?.extract()?;
132132
assert_eq!(relu_result, 0.0);
133133

134-
let kwargs = [("slope", 0.2)].into_py_dict(py);
134+
let kwargs = [("slope", 0.2)].into_py_dict(py)?;
135135
let lrelu_result: f64 = activators
136136
.getattr("leaky_relu")?
137137
.call((-1.0,), Some(&kwargs))?

guide/src/python-from-rust/function-calls.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,17 +90,17 @@ fn main() -> PyResult<()> {
9090
.into();
9191

9292
// call object with PyDict
93-
let kwargs = [(key1, val1)].into_py_dict(py);
93+
let kwargs = [(key1, val1)].into_py_dict(py)?;
9494
fun.call(py, (), Some(&kwargs))?;
9595

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

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

105105
Ok(())
106106
})

src/conversions/anyhow.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ mod test_anyhow {
145145
let pyerr = PyErr::from(err);
146146

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

166166
Python::with_gil(|py| {
167-
let locals = [("err", pyerr)].into_py_dict(py);
167+
let locals = [("err", pyerr)].into_py_dict(py).unwrap();
168168
let pyerr = py
169169
.run(ffi::c_str!("raise err"), None, Some(&locals))
170170
.unwrap_err();

src/conversions/chrono.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1365,7 +1365,7 @@ mod tests {
13651365
fn test_pyo3_offset_fixed_frompyobject_created_in_python(timestamp in 0..(i32::MAX as i64), timedelta in -86399i32..=86399i32) {
13661366
Python::with_gil(|py| {
13671367

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

src/conversions/eyre.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ mod tests {
151151
let pyerr = PyErr::from(err);
152152

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

172172
Python::with_gil(|py| {
173-
let locals = [("err", pyerr)].into_py_dict(py);
173+
let locals = [("err", pyerr)].into_py_dict(py).unwrap();
174174
let pyerr = py
175175
.run(ffi::c_str!("raise err"), None, Some(&locals))
176176
.unwrap_err();

src/conversions/hashbrown.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ use crate::{
2525
set::{new_from_iter, try_new_from_iter, PySetMethods},
2626
PyDict, PyFrozenSet, PySet,
2727
},
28-
Bound, BoundObject, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
28+
Bound, FromPyObject, IntoPy, PyAny, PyErr, PyObject, PyResult, Python, ToPyObject,
2929
};
3030
use std::{cmp, hash};
3131

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

241-
let py_map = map.into_py_dict(py);
241+
let py_map = map.into_py_dict(py).unwrap();
242242

243243
assert_eq!(py_map.len(), 1);
244244
assert_eq!(

src/conversions/indexmap.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,7 @@ mod test_indexmap {
236236
let mut map = indexmap::IndexMap::<i32, i32>::new();
237237
map.insert(1, 1);
238238

239-
let py_map = map.into_py_dict(py);
239+
let py_map = map.into_py_dict(py).unwrap();
240240

241241
assert_eq!(py_map.len(), 1);
242242
assert_eq!(
@@ -265,7 +265,7 @@ mod test_indexmap {
265265
}
266266
}
267267

268-
let py_map = map.clone().into_py_dict(py);
268+
let py_map = map.clone().into_py_dict(py).unwrap();
269269

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

src/exceptions.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,13 @@ macro_rules! impl_exception_boilerplate_bound {
6161
///
6262
/// import_exception!(socket, gaierror);
6363
///
64+
/// # fn main() -> pyo3::PyResult<()> {
6465
/// Python::with_gil(|py| {
65-
/// let ctx = [("gaierror", py.get_type::<gaierror>())].into_py_dict(py);
66+
/// let ctx = [("gaierror", py.get_type::<gaierror>())].into_py_dict(py)?;
6667
/// pyo3::py_run!(py, *ctx, "import socket; assert gaierror is socket.gaierror");
67-
/// });
68+
/// # Ok(())
69+
/// })
70+
/// # }
6871
///
6972
/// ```
7073
#[macro_export]
@@ -905,7 +908,7 @@ mod tests {
905908

906909
Python::with_gil(|py| {
907910
let error_type = py.get_type::<CustomError>();
908-
let ctx = [("CustomError", error_type)].into_py_dict(py);
911+
let ctx = [("CustomError", error_type)].into_py_dict(py).unwrap();
909912
let type_description: String = py
910913
.eval(ffi::c_str!("str(CustomError)"), None, Some(&ctx))
911914
.unwrap()
@@ -932,7 +935,7 @@ mod tests {
932935
create_exception!(mymodule.exceptions, CustomError, PyException);
933936
Python::with_gil(|py| {
934937
let error_type = py.get_type::<CustomError>();
935-
let ctx = [("CustomError", error_type)].into_py_dict(py);
938+
let ctx = [("CustomError", error_type)].into_py_dict(py).unwrap();
936939
let type_description: String = py
937940
.eval(ffi::c_str!("str(CustomError)"), None, Some(&ctx))
938941
.unwrap()
@@ -951,7 +954,7 @@ mod tests {
951954

952955
Python::with_gil(|py| {
953956
let error_type = py.get_type::<CustomError>();
954-
let ctx = [("CustomError", error_type)].into_py_dict(py);
957+
let ctx = [("CustomError", error_type)].into_py_dict(py).unwrap();
955958
let type_description: String = py
956959
.eval(ffi::c_str!("str(CustomError)"), None, Some(&ctx))
957960
.unwrap()
@@ -984,7 +987,7 @@ mod tests {
984987

985988
Python::with_gil(|py| {
986989
let error_type = py.get_type::<CustomError>();
987-
let ctx = [("CustomError", error_type)].into_py_dict(py);
990+
let ctx = [("CustomError", error_type)].into_py_dict(py).unwrap();
988991
let type_description: String = py
989992
.eval(ffi::c_str!("str(CustomError)"), None, Some(&ctx))
990993
.unwrap()

src/impl_/extract_argument.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,7 +802,7 @@ mod tests {
802802

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

834834
Python::with_gil(|py| {
835835
let args = PyTuple::empty(py);
836-
let kwargs = [(1u8, 1u8)].into_py_dict(py);
836+
let kwargs = [(1u8, 1u8)].into_py_dict(py).unwrap();
837837
let err = unsafe {
838838
function_description
839839
.extract_arguments_tuple_dict::<NoVarargs, NoVarkeywords>(

src/instance.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1960,7 +1960,7 @@ mod tests {
19601960

19611961
assert_repr(obj.call1(py, ((('x', 1),),)).unwrap().bind(py), "{'x': 1}");
19621962
assert_repr(
1963-
obj.call(py, (), Some(&[('x', 1)].into_py_dict(py)))
1963+
obj.call(py, (), Some(&[('x', 1)].into_py_dict(py).unwrap()))
19641964
.unwrap()
19651965
.bind(py),
19661966
"{'x': 1}",

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@
242242
//! let sys = py.import("sys")?;
243243
//! let version: String = sys.getattr("version")?.extract()?;
244244
//!
245-
//! let locals = [("os", py.import("os")?)].into_py_dict(py);
245+
//! let locals = [("os", py.import("os")?)].into_py_dict(py)?;
246246
//! let code = c_str!("os.getenv('USER') or os.getenv('USERNAME') or 'Unknown'");
247247
//! let user: String = py.eval(code, None, Some(&locals))?.extract()?;
248248
//!

src/macros.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,13 @@
7575
/// }
7676
/// }
7777
///
78+
/// # fn main() -> PyResult<()> {
7879
/// Python::with_gil(|py| {
79-
/// let locals = [("C", py.get_type::<MyClass>())].into_py_dict(py);
80+
/// let locals = [("C", py.get_type::<MyClass>())].into_py_dict(py)?;
8081
/// pyo3::py_run!(py, *locals, "c = C()");
81-
/// });
82+
/// # Ok(())
83+
/// })
84+
/// # }
8285
/// ```
8386
#[macro_export]
8487
macro_rules! py_run {
@@ -102,7 +105,7 @@ macro_rules! py_run_impl {
102105
($py:expr, $($val:ident)+, $code:expr) => {{
103106
use $crate::types::IntoPyDict;
104107
use $crate::ToPyObject;
105-
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py);
108+
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py).unwrap();
106109
$crate::py_run_impl!($py, *d, $code)
107110
}};
108111
($py:expr, *$dict:expr, $code:expr) => {{

src/marker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -872,7 +872,7 @@ mod tests {
872872
.unwrap();
873873
assert_eq!(v, 1);
874874

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

877877
// Inject our own global namespace
878878
let v: i32 = py

src/tests/common.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ mod inner {
4040
// Case1: idents & no err_msg
4141
($py:expr, $($val:ident)+, $code:expr, $err:ident) => {{
4242
use pyo3::types::IntoPyDict;
43-
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py);
43+
let d = [$((stringify!($val), $val.to_object($py)),)+].into_py_dict($py).unwrap();
4444
py_expect_exception!($py, *d, $code, $err)
4545
}};
4646
// Case2: dict & no err_msg
@@ -126,7 +126,7 @@ mod inner {
126126
f: impl FnOnce(&Bound<'py, PyList>) -> PyResult<R>,
127127
) -> PyResult<R> {
128128
let warnings = py.import("warnings")?;
129-
let kwargs = [("record", true)].into_py_dict(py);
129+
let kwargs = [("record", true)].into_py_dict(py)?;
130130
let catch_warnings = warnings
131131
.getattr("catch_warnings")?
132132
.call((), Some(&kwargs))?;

src/types/any.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1701,7 +1701,7 @@ class NonHeapNonDescriptorInt:
17011701
fn test_call_with_kwargs() {
17021702
Python::with_gil(|py| {
17031703
let list = vec![3, 6, 5, 4, 7].to_object(py);
1704-
let dict = vec![("reverse", true)].into_py_dict(py);
1704+
let dict = vec![("reverse", true)].into_py_dict(py).unwrap();
17051705
list.call_method(py, "sort", (), Some(&dict)).unwrap();
17061706
assert_eq!(list.extract::<Vec<i32>>(py).unwrap(), vec![7, 6, 5, 4, 3]);
17071707
});

0 commit comments

Comments
 (0)