Skip to content

PyErr::new has surprising edge cases #4412

Description

@davidhewitt

Continuing from #4400, where we observed that a tuple was being flattened as part of a call to PyErr::new.

The other special case is that PyErr::new(py.None()) counts as no arguments.

#[pyo3::pymodule]
mod pyo3_scratch {
    use pyo3::prelude::*;

    #[pyfunction]
    fn bug(py: Python<'_>) -> PyResult<()> {
        Err(pyo3::exceptions::PyValueError::new_err(py.None()))
    }
}
>>> try:
...     pyo3_scratch.bug()
... except ValueError as e:
...     print(e.args)
... 
()

Again if we wrap the py.None() in a tuple as (py.None(),) then the final e.args will be (None,).

I'm open to debating whether we should change PyErr::new, because this doesn't match Python users' instincts, where there is no special case:

>>> print(ValueError(None).args)
(None,)
>>> print(ValueError((1,)).args)
((1,),)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions