From 10c285b28312796857f3f6d255bffb006d8689bf Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Wed, 6 Apr 2022 14:23:06 +0200 Subject: [PATCH] Add PyDowncastErrorArguments to delay formatting downcast errors. --- CHANGELOG.md | 1 + src/err/mod.rs | 26 +++++++++++++++++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bd41b4c..937f9926 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Default to "m" ABI tag when choosing `libpython` link name for CPython 3.7 on Unix. [#2288](https://github.com/PyO3/pyo3/pull/2288) +- Improved performance of failing calls to `FromPyObject::extract` which is common when functions accept multiple distinct types. [#2279](https://github.com/PyO3/pyo3/pull/2279) ## [0.16.3] - 2022-04-05 diff --git a/src/err/mod.rs b/src/err/mod.rs index 869ff20a..eed6798a 100644 --- a/src/err/mod.rs +++ b/src/err/mod.rs @@ -663,10 +663,34 @@ impl<'a> IntoPy for &'a PyErr { } } +struct PyDowncastErrorArguments { + from: Py, + to: Cow<'static, str>, +} + +impl PyErrArguments for PyDowncastErrorArguments { + fn arguments(self, py: Python<'_>) -> PyObject { + format!( + "'{}' object cannot be converted to '{}'", + self.from + .as_ref(py) + .name() + .unwrap_or(""), + self.to + ) + .to_object(py) + } +} + /// Convert `PyDowncastError` to Python `TypeError`. impl<'a> std::convert::From> for PyErr { fn from(err: PyDowncastError<'_>) -> PyErr { - exceptions::PyTypeError::new_err(err.to_string()) + let args = PyDowncastErrorArguments { + from: err.from.get_type().into(), + to: err.to, + }; + + exceptions::PyTypeError::new_err(args) } }