Skip to content

Commit

Permalink
Clear error indicator when the exception is handled on the Rust side
Browse files Browse the repository at this point in the history
Leaving Python's global exception state is misleading, e.g. subsequent
calls of `py.eval` will fail.
  • Loading branch information
Alexander-N committed Jan 10, 2020
1 parent 41e3b25 commit 1f675dc
Show file tree
Hide file tree
Showing 4 changed files with 17 additions and 1 deletion.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

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

### Fixed

* Clear error indicator when the exception is handled on the Rust side. [#719](https://github.com/PyO3/pyo3/pull/719)

## [0.8.5]

* Support for `#[name = "foo"]` attribute for `#[pyfunction]` and in `#[pymethods]`. [#692](https://github.com/PyO3/pyo3/pull/692)
Expand Down
1 change: 1 addition & 0 deletions src/types/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl<'p> PyIterator<'p> {
let ptr = ffi::PyObject_GetIter(obj.as_ptr());
// Returns NULL if an object cannot be iterated.
if ptr.is_null() {
PyErr::fetch(py);
return Err(PyDowncastError);
}

Expand Down
10 changes: 9 additions & 1 deletion src/types/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,12 @@ impl PySet {

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

/// Returns an iterator of values in this set.
Expand Down Expand Up @@ -324,6 +329,9 @@ mod test {
assert!(val.is_some());
let val2 = set.pop();
assert!(val2.is_none());
assert!(py
.eval("print('Exception state should not be set.')", None, None)
.is_ok());
}

#[test]
Expand Down
3 changes: 3 additions & 0 deletions tests/test_various.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,7 @@ fn incorrect_iter() {
let int_ref = int.as_ref(py);
// Should not segfault.
assert!(int_ref.iter().is_err());
assert!(py
.eval("print('Exception state should not be set.')", None, None)
.is_ok());
}

0 comments on commit 1f675dc

Please sign in to comment.