Skip to content

Commit

Permalink
reintroduce PyUnicodeDecodeError constructors
Browse files Browse the repository at this point in the history
  • Loading branch information
Icxolu committed Aug 30, 2024
1 parent c77b853 commit 810e87f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 13 deletions.
44 changes: 34 additions & 10 deletions src/exceptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -624,13 +624,13 @@ impl_windows_native_exception!(

impl PyUnicodeDecodeError {
/// Creates a Python `UnicodeDecodeError`.
pub fn new_bound<'p>(
py: Python<'p>,
pub fn new<'py>(
py: Python<'py>,
encoding: &CStr,
input: &[u8],
range: ops::Range<usize>,
reason: &CStr,
) -> PyResult<Bound<'p, PyUnicodeDecodeError>> {
) -> PyResult<Bound<'py, PyUnicodeDecodeError>> {
use crate::ffi_ptr_ext::FfiPtrExt;
use crate::py_result_ext::PyResultExt;
unsafe {
Expand All @@ -647,6 +647,19 @@ impl PyUnicodeDecodeError {
.downcast_into()
}

/// Deprecated name for [`PyUnicodeDecodeError::new`].
#[deprecated(since = "0.23.0", note = "renamed to `PyUnicodeDecodeError::new`")]
#[inline]
pub fn new_bound<'py>(
py: Python<'py>,
encoding: &CStr,
input: &[u8],
range: ops::Range<usize>,
reason: &CStr,
) -> PyResult<Bound<'py, PyUnicodeDecodeError>> {
Self::new(py, encoding, input, range, reason)
}

/// Creates a Python `UnicodeDecodeError` from a Rust UTF-8 decoding error.
///
/// # Examples
Expand All @@ -660,28 +673,39 @@ impl PyUnicodeDecodeError {
/// Python::with_gil(|py| {
/// let invalid_utf8 = b"fo\xd8o";
/// let err = std::str::from_utf8(invalid_utf8).expect_err("should be invalid utf8");
/// let decode_err = PyUnicodeDecodeError::new_utf8_bound(py, invalid_utf8, err)?;
/// let decode_err = PyUnicodeDecodeError::new_utf8(py, invalid_utf8, err)?;
/// assert_eq!(
/// decode_err.to_string(),
/// "'utf-8' codec can't decode byte 0xd8 in position 2: invalid utf-8"
/// );
/// Ok(())
/// })
/// # }
pub fn new_utf8_bound<'p>(
py: Python<'p>,
pub fn new_utf8<'py>(
py: Python<'py>,
input: &[u8],
err: std::str::Utf8Error,
) -> PyResult<Bound<'p, PyUnicodeDecodeError>> {
) -> PyResult<Bound<'py, PyUnicodeDecodeError>> {
let pos = err.valid_up_to();
PyUnicodeDecodeError::new_bound(
PyUnicodeDecodeError::new(
py,
ffi::c_str!("utf-8"),
input,
pos..(pos + 1),
ffi::c_str!("invalid utf-8"),
)
}

/// Deprecated name for [`PyUnicodeDecodeError::new_utf8`].
#[deprecated(since = "0.23.0", note = "renamed to `PyUnicodeDecodeError::new_utf8`")]
#[inline]
pub fn new_utf8_bound<'py>(
py: Python<'py>,
input: &[u8],
err: std::str::Utf8Error,
) -> PyResult<Bound<'py, PyUnicodeDecodeError>> {
Self::new_utf8(py, input, err)
}
}

impl_native_exception!(PyWarning, PyExc_Warning, native_doc!("Warning"));
Expand Down Expand Up @@ -1017,7 +1041,7 @@ mod tests {
#[cfg_attr(invalid_from_utf8_lint, allow(invalid_from_utf8))]
let err = std::str::from_utf8(invalid_utf8).expect_err("should be invalid utf8");
Python::with_gil(|py| {
let decode_err = PyUnicodeDecodeError::new_utf8_bound(py, invalid_utf8, err).unwrap();
let decode_err = PyUnicodeDecodeError::new_utf8(py, invalid_utf8, err).unwrap();
assert_eq!(
format!("{:?}", decode_err),
"UnicodeDecodeError('utf-8', b'fo\\xd8o', 2, 3, 'invalid utf-8')"
Expand Down Expand Up @@ -1074,7 +1098,7 @@ mod tests {
#[cfg_attr(invalid_from_utf8_lint, allow(invalid_from_utf8))]
let err = std::str::from_utf8(invalid_utf8).expect_err("should be invalid utf8");
PyErr::from_value(
PyUnicodeDecodeError::new_utf8_bound(py, invalid_utf8, err)
PyUnicodeDecodeError::new_utf8(py, invalid_utf8, err)
.unwrap()
.into_any(),
)
Expand Down
6 changes: 3 additions & 3 deletions src/types/string.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ impl<'a> PyStringData<'a> {
match self {
Self::Ucs1(data) => match str::from_utf8(data) {
Ok(s) => Ok(Cow::Borrowed(s)),
Err(e) => Err(PyUnicodeDecodeError::new_utf8_bound(py, data, e)?.into()),
Err(e) => Err(PyUnicodeDecodeError::new_utf8(py, data, e)?.into()),
},
Self::Ucs2(data) => match String::from_utf16(data) {
Ok(s) => Ok(Cow::Owned(s)),
Err(e) => {
let mut message = e.to_string().as_bytes().to_vec();
message.push(0);

Err(PyUnicodeDecodeError::new_bound(
Err(PyUnicodeDecodeError::new(
py,
ffi::c_str!("utf-16"),
self.as_bytes(),
Expand All @@ -90,7 +90,7 @@ impl<'a> PyStringData<'a> {
},
Self::Ucs4(data) => match data.iter().map(|&c| std::char::from_u32(c)).collect() {
Some(s) => Ok(Cow::Owned(s)),
None => Err(PyUnicodeDecodeError::new_bound(
None => Err(PyUnicodeDecodeError::new(
py,
ffi::c_str!("utf-32"),
self.as_bytes(),
Expand Down

0 comments on commit 810e87f

Please sign in to comment.