pyo3/conversions/std/
vec.rs

1use crate::conversion::IntoPyObject;
2#[cfg(feature = "experimental-inspect")]
3use crate::inspect::types::TypeInfo;
4use crate::types::list::new_from_iter;
5use crate::{Bound, PyAny, PyErr, PyObject, Python};
6#[allow(deprecated)]
7use crate::{IntoPy, ToPyObject};
8
9#[allow(deprecated)]
10impl<T> ToPyObject for [T]
11where
12    T: ToPyObject,
13{
14    fn to_object(&self, py: Python<'_>) -> PyObject {
15        let mut iter = self.iter().map(|e| e.to_object(py));
16        let list = new_from_iter(py, &mut iter);
17        list.into()
18    }
19}
20
21#[allow(deprecated)]
22impl<T> ToPyObject for Vec<T>
23where
24    T: ToPyObject,
25{
26    fn to_object(&self, py: Python<'_>) -> PyObject {
27        self.as_slice().to_object(py)
28    }
29}
30
31#[allow(deprecated)]
32impl<T> IntoPy<PyObject> for Vec<T>
33where
34    T: IntoPy<PyObject>,
35{
36    fn into_py(self, py: Python<'_>) -> PyObject {
37        let mut iter = self.into_iter().map(|e| e.into_py(py));
38        let list = new_from_iter(py, &mut iter);
39        list.into()
40    }
41}
42
43impl<'py, T> IntoPyObject<'py> for Vec<T>
44where
45    T: IntoPyObject<'py>,
46{
47    type Target = PyAny;
48    type Output = Bound<'py, Self::Target>;
49    type Error = PyErr;
50
51    /// Turns [`Vec<u8>`] into [`PyBytes`], all other `T`s will be turned into a [`PyList`]
52    ///
53    /// [`PyBytes`]: crate::types::PyBytes
54    /// [`PyList`]: crate::types::PyList
55    #[inline]
56    fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
57        T::owned_sequence_into_pyobject(self, py, crate::conversion::private::Token)
58    }
59
60    #[cfg(feature = "experimental-inspect")]
61    fn type_output() -> TypeInfo {
62        TypeInfo::list_of(T::type_output())
63    }
64}
65
66impl<'a, 'py, T> IntoPyObject<'py> for &'a Vec<T>
67where
68    &'a T: IntoPyObject<'py>,
69    T: 'a, // MSRV
70{
71    type Target = PyAny;
72    type Output = Bound<'py, Self::Target>;
73    type Error = PyErr;
74
75    #[inline]
76    fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
77        // NB: we could actually not cast to `PyAny`, which would be nice for
78        // `&Vec<u8>`, but that'd be inconsistent with the `IntoPyObject` impl
79        // above which always returns a `PyAny` for `Vec<T>`.
80        self.as_slice().into_pyobject(py).map(Bound::into_any)
81    }
82
83    #[cfg(feature = "experimental-inspect")]
84    fn type_output() -> TypeInfo {
85        TypeInfo::list_of(<&T>::type_output())
86    }
87}
88
89#[cfg(test)]
90mod tests {
91    use crate::conversion::IntoPyObject;
92    use crate::types::{PyAnyMethods, PyBytes, PyBytesMethods, PyList};
93    use crate::Python;
94
95    #[test]
96    fn test_vec_intopyobject_impl() {
97        Python::with_gil(|py| {
98            let bytes: Vec<u8> = b"foobar".to_vec();
99            let obj = bytes.clone().into_pyobject(py).unwrap();
100            assert!(obj.is_instance_of::<PyBytes>());
101            let obj = obj.downcast_into::<PyBytes>().unwrap();
102            assert_eq!(obj.as_bytes(), &bytes);
103
104            let nums: Vec<u16> = vec![0, 1, 2, 3];
105            let obj = nums.into_pyobject(py).unwrap();
106            assert!(obj.is_instance_of::<PyList>());
107        });
108    }
109
110    #[test]
111    fn test_vec_reference_intopyobject_impl() {
112        Python::with_gil(|py| {
113            let bytes: Vec<u8> = b"foobar".to_vec();
114            let obj = (&bytes).into_pyobject(py).unwrap();
115            assert!(obj.is_instance_of::<PyBytes>());
116            let obj = obj.downcast_into::<PyBytes>().unwrap();
117            assert_eq!(obj.as_bytes(), &bytes);
118
119            let nums: Vec<u16> = vec![0, 1, 2, 3];
120            let obj = (&nums).into_pyobject(py).unwrap();
121            assert!(obj.is_instance_of::<PyList>());
122        });
123    }
124}
⚠️ Internal Docs ⚠️ Not Public API 👉 Official Docs Here