Skip to content

Commit 1f675dc

Browse files
committed
Clear error indicator when the exception is handled on the Rust side
Leaving Python's global exception state is misleading, e.g. subsequent calls of `py.eval` will fail.
1 parent 41e3b25 commit 1f675dc

File tree

4 files changed

+17
-1
lines changed

4 files changed

+17
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1616

1717
* Implemented `IntoIterator` for `PySet` and `PyFrozenSet`. [#716](https://github.com/PyO3/pyo3/pull/716)
1818

19+
### Fixed
20+
21+
* Clear error indicator when the exception is handled on the Rust side. [#719](https://github.com/PyO3/pyo3/pull/719)
22+
1923
## [0.8.5]
2024

2125
* Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692)

src/types/iterator.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ impl<'p> PyIterator<'p> {
4242
let ptr = ffi::PyObject_GetIter(obj.as_ptr());
4343
// Returns NULL if an object cannot be iterated.
4444
if ptr.is_null() {
45+
PyErr::fetch(py);
4546
return Err(PyDowncastError);
4647
}
4748

src/types/set.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,12 @@ impl PySet {
9393

9494
/// Remove and return an arbitrary element from the set
9595
pub fn pop(&self) -> Option<PyObject> {
96-
unsafe { PyObject::from_owned_ptr_or_opt(self.py(), ffi::PySet_Pop(self.as_ptr())) }
96+
let element =
97+
unsafe { PyObject::from_owned_ptr_or_err(self.py(), ffi::PySet_Pop(self.as_ptr())) };
98+
match element {
99+
Ok(e) => Some(e),
100+
Err(_) => None,
101+
}
97102
}
98103

99104
/// Returns an iterator of values in this set.
@@ -324,6 +329,9 @@ mod test {
324329
assert!(val.is_some());
325330
let val2 = set.pop();
326331
assert!(val2.is_none());
332+
assert!(py
333+
.eval("print('Exception state should not be set.')", None, None)
334+
.is_ok());
327335
}
328336

329337
#[test]

tests/test_various.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,7 @@ fn incorrect_iter() {
179179
let int_ref = int.as_ref(py);
180180
// Should not segfault.
181181
assert!(int_ref.iter().is_err());
182+
assert!(py
183+
.eval("print('Exception state should not be set.')", None, None)
184+
.is_ok());
182185
}

0 commit comments

Comments
 (0)