pyo3/conversions/
bytes.rs1#![cfg(feature = "bytes")]
2
3#![doc = concat!("pyo3 = { version = \"", env!("CARGO_PKG_VERSION"), "\", features = [\"bytes\"] }")]
24use bytes::Bytes;
66
67use crate::conversion::IntoPyObject;
68#[cfg(feature = "experimental-inspect")]
69use crate::inspect::PyStaticExpr;
70use crate::instance::Bound;
71#[allow(unused_imports, reason = "used to build docs")]
72use crate::platform::prelude::*;
73use crate::pybacked::PyBackedBytes;
74use crate::types::PyBytes;
75#[cfg(feature = "experimental-inspect")]
76use crate::PyTypeInfo;
77use crate::{Borrowed, CastError, FromPyObject, PyAny, PyErr, Python};
78
79impl<'a, 'py> FromPyObject<'a, 'py> for Bytes {
80 type Error = CastError<'a, 'py>;
81
82 #[cfg(feature = "experimental-inspect")]
83 const INPUT_TYPE: PyStaticExpr = PyBackedBytes::INPUT_TYPE;
84
85 fn extract(obj: Borrowed<'a, 'py, PyAny>) -> Result<Self, Self::Error> {
86 Ok(Bytes::from_owner(obj.extract::<PyBackedBytes>()?))
87 }
88}
89
90impl<'py> IntoPyObject<'py> for Bytes {
91 type Target = PyBytes;
92 type Output = Bound<'py, Self::Target>;
93 type Error = PyErr;
94
95 #[cfg(feature = "experimental-inspect")]
96 const OUTPUT_TYPE: PyStaticExpr = PyBytes::TYPE_HINT;
97
98 fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
99 Ok(PyBytes::new(py, &self))
100 }
101}
102
103impl<'py> IntoPyObject<'py> for &Bytes {
104 type Target = PyBytes;
105 type Output = Bound<'py, Self::Target>;
106 type Error = PyErr;
107
108 #[cfg(feature = "experimental-inspect")]
109 const OUTPUT_TYPE: PyStaticExpr = PyBytes::TYPE_HINT;
110
111 fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
112 Ok(PyBytes::new(py, self))
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use super::*;
119 use crate::types::{PyAnyMethods, PyByteArray, PyByteArrayMethods, PyBytes};
120 use crate::Python;
121
122 #[test]
123 fn test_bytes() {
124 Python::attach(|py| {
125 let py_bytes = PyBytes::new(py, b"foobar");
126 let bytes: Bytes = py_bytes.extract().unwrap();
127 assert_eq!(&*bytes, b"foobar");
128
129 let bytes = Bytes::from_static(b"foobar").into_pyobject(py).unwrap();
130 assert!(bytes.is_instance_of::<PyBytes>());
131 });
132 }
133
134 #[test]
135 fn test_bytearray() {
136 Python::attach(|py| {
137 let py_bytearray = PyByteArray::new(py, b"foobar");
138 let bytes: Bytes = py_bytearray.extract().unwrap();
139 assert_eq!(&*bytes, b"foobar");
140
141 unsafe { py_bytearray.as_bytes_mut()[0] = b'x' };
145 assert_eq!(&bytes, "foobar");
146 assert_eq!(&py_bytearray.extract::<Vec<u8>>().unwrap(), b"xoobar");
147 });
148 }
149}