1use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
18use std::hash::{BuildHasher, Hash};
19
20use internment::ArcIntern;
21use pyo3::conversion::IntoPy;
22
23use pyo3::types::{
24 PyBool, PyByteArray, PyBytes, PyDict, PyFloat, PyFrozenSet, PyList, PyLong, PySet, PyString,
25};
26
27#[cfg(feature = "time")]
28use pyo3::{
29 exceptions::PyValueError,
30 types::{PyDate, PyDateTime, PyDelta, PyTime, PyTzInfo},
31};
32
33use pyo3::{Py, PyAny, PyResult, Python, ToPyObject};
34
35#[cfg(feature = "complex")]
36mod complex;
38
39#[cfg(feature = "time")]
40use crate::datetime::DateTime;
41#[cfg(feature = "time")]
42use pyo3::types::PyTuple;
43#[cfg(feature = "time")]
44use time::{Date, Duration, OffsetDateTime, PrimitiveDateTime, Time, UtcOffset};
45
46#[cfg(feature = "indexmap")]
47mod indexmap;
49
50pub trait ToPython<P: ToPyObject> {
52 fn to_python(&self, py: Python) -> PyResult<P>;
58}
59
60impl<T, P> ToPython<P> for &Box<T>
61where
62 T: ToPython<P>,
63 P: ToPyObject,
64{
65 fn to_python(&self, py: Python) -> PyResult<P> {
66 T::to_python(self, py)
67 }
68}
69
70impl<T, P> ToPython<P> for &ArcIntern<T>
71where
72 T: ToPython<P> + ?Sized + Eq + Hash + Send + Sync + 'static,
73 P: ToPyObject,
74{
75 fn to_python(&self, py: Python) -> PyResult<P> {
76 T::to_python(self, py)
77 }
78}
79
80impl<T, P> ToPython<P> for Box<T>
81where
82 T: ToPython<P>,
83 P: ToPyObject,
84{
85 fn to_python(&self, py: Python) -> PyResult<P> {
86 T::to_python(self, py)
87 }
88}
89
90impl<T, P> ToPython<P> for ArcIntern<T>
91where
92 T: ToPython<P> + ?Sized + Eq + Hash + Send + Sync + 'static,
93 P: ToPyObject,
94{
95 fn to_python(&self, py: Python) -> PyResult<P> {
96 T::to_python(self, py)
97 }
98}
99
100macro_rules! impl_to_python_for_tuple {
103 ($($idx:tt $t:tt $p:tt),+) => {
104 impl<$($t,)+ $($p,)+> ToPython<($($p,)+)> for ($($t,)+)
105 where
106 $($t: ToPython<$p>, $p: ToPyObject,)+
107
108 {
109 fn to_python(&self, py: Python) -> PyResult<($($p,)+)> {
110 Ok(($(
111 $t :: to_python(&self.$idx, py)?,
112 )+))
113 }
114 }
115 };
116}
117
118impl_to_python_for_tuple!(0 T0 P0);
121impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1);
122impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2);
123impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3);
124impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3, 4 T4 P4);
125impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3, 4 T4 P4, 5 T5 P5);
126impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3, 4 T4 P4, 5 T5 P5, 6 T6 P6);
127impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3, 4 T4 P4, 5 T5 P5, 6 T6 P6, 7 T7 P7);
128impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3, 4 T4 P4, 5 T5 P5, 6 T6 P6, 7 T7 P7, 8 T8 P8);
129impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3, 4 T4 P4, 5 T5 P5, 6 T6 P6, 7 T7 P7, 8 T8 P8, 9 T9 P9);
130impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3, 4 T4 P4, 5 T5 P5, 6 T6 P6, 7 T7 P7, 8 T8 P8, 9 T9 P9, 10 T10 P10);
131impl_to_python_for_tuple!(0 T0 P0, 1 T1 P1, 2 T2 P2, 3 T3 P3, 4 T4 P4, 5 T5 P5, 6 T6 P6, 7 T7 P7, 8 T8 P8, 9 T9 P9, 10 T10 P10, 11 T11 P11);
132
133#[macro_export]
136macro_rules! private_impl_to_python_for {
137 (&$($lt: lifetime)? $self: ident, $py: ident, $rs_type: ty => $py_type: ty $convert: block) => {
138 #[allow(clippy::use_self)]
139 impl$(<$lt>)? $crate::ToPython<$py_type> for $(&$lt)? $rs_type {
140 fn to_python(&$self, $py: $crate::pyo3::Python<'_>) -> $crate::pyo3::PyResult<$py_type> {
141 $convert
142 }
143 }
144 }
145}
146
147#[macro_export]
149macro_rules! private_impl_to_python_with_reference {
150 (&$self: ident, $py: ident, $rs_type: ty => $py_type: ty $convert: block) => {
151 $crate::private_impl_to_python_for!(&$self, $py, $rs_type => $py_type $convert);
152 $crate::private_impl_to_python_for!(&'a $self, $py, $rs_type => $py_type {
153 <$rs_type as $crate::ToPython<$py_type>>::to_python(*$self, $py)
154 });
155 };
156}
157
158#[macro_export]
160macro_rules! private_impl_to_python_pyany {
161 ($rs_type: ty => $py_type: ty) => {
162 $crate::private_impl_to_python_with_reference!(&self, py, $rs_type => $crate::pyo3::Py<$crate::pyo3::PyAny> {
163 $crate::ToPython::<$py_type>::to_python(self, py).map(|item| $crate::pyo3::ToPyObject::to_object(&item, py))
164 });
165 }
166}
167pub(crate) use private_impl_to_python_pyany;
168
169macro_rules! impl_for_primitive {
173 ($rs_type: ty => $py_type: ty) => {
174 private_impl_to_python_with_reference!(&self, py, $rs_type => $py_type {
175 self.into_py(py).extract(py)
177 });
178 };
179}
180
181#[macro_export]
183macro_rules! impl_for_self {
184 ($type: ty) => {
185 $crate::private_impl_to_python_with_reference!(&self, _py, $type => $type {
186 Ok(self.clone())
187 });
188 $crate::private_impl_to_python_pyany!($type => $type);
189 }
190}
191pub(crate) use impl_for_self;
192
193impl_for_self!(bool);
198impl_for_self!(Py<PyBool>);
199
200private_impl_to_python_with_reference!(&self, py, bool => Py<PyBool> {
201 Ok(PyBool::new(py, *self).into_py(py))
202});
203
204impl_for_self!(Py<PyByteArray>);
207
208private_impl_to_python_with_reference!(&self, py, [u8] => Py<PyByteArray> {
209 Ok(PyByteArray::new(py, self).into_py(py))
210});
211
212private_impl_to_python_with_reference!(&self, py, Vec<u8> => Py<PyByteArray> {
213 self.as_slice().to_python(py)
214});
215
216impl_for_self!(Py<PyBytes>);
219
220private_impl_to_python_with_reference!(&self, py, [u8] => Py<PyBytes> {
221 Ok(PyBytes::new(py, self).into_py(py))
222});
223
224private_impl_to_python_with_reference!(&self, py, Vec<u8> => Py<PyBytes> {
225 self.as_slice().to_python(py)
226});
227
228#[cfg(feature = "time")]
231impl_for_self!(Py<PyDate>);
232
233#[cfg(feature = "time")]
234private_impl_to_python_with_reference!(&self, py, Date => Py<PyDate> {
235 let year: i32 = self.year();
236 let month: u8 = self.month().into();
237 let day: u8 = self.day();
238 PyDate::new(py, year, month, day).map(|date| date.into_py(py))
239});
240
241#[cfg(feature = "time")]
242private_impl_to_python_pyany!(Date => Py<PyDate>);
243
244#[cfg(feature = "time")]
247impl_for_self!(Py<PyDateTime>);
248
249#[cfg(feature = "time")]
250private_impl_to_python_with_reference!(&self, py, DateTime => Py<PyDateTime> {
251 match self {
252 Self::Primitive(datetime) => datetime.to_python(py),
253 Self::Offset(datetime) => datetime.to_python(py),
254 }
255});
256
257#[cfg(feature = "time")]
258private_impl_to_python_pyany!(DateTime => Py<PyDateTime>);
259
260#[cfg(feature = "time")]
261private_impl_to_python_with_reference!(&self, py, PrimitiveDateTime => Py<PyDateTime> {
262 let date = self.date();
263 let time = self.time();
264 let year: i32 = date.year();
265 let month: u8 = date.month().into();
266 let day: u8 = date.day();
267 let hour = time.hour();
268 let minute = time.minute();
269 let second = time.second();
270 let microsecond = time.microsecond();
271 PyDateTime::new(py, year, month, day, hour, minute, second, microsecond, None).map(|dt| dt.into_py(py))
272});
273
274#[cfg(feature = "time")]
275private_impl_to_python_pyany!(PrimitiveDateTime => Py<PyDateTime>);
276
277#[cfg(feature = "time")]
278private_impl_to_python_with_reference!(&self, py, OffsetDateTime => Py<PyDateTime> {
279 let date = self.date();
280 let time = self.time();
281 let offset = self.offset();
282 let year: i32 = date.year();
283 let month: u8 = date.month().into();
284 let day: u8 = date.day();
285 let hour = time.hour();
286 let minute = time.minute();
287 let second = time.second();
288 let microsecond = time.microsecond();
289 let tzinfo: Py<PyTzInfo> = offset.to_python(py)?;
290 let tzinfo = tzinfo.as_ref(py);
291 PyDateTime::new(py, year, month, day, hour, minute, second, microsecond, Some(tzinfo)).map(|dt| dt.into_py(py))
292});
293
294#[cfg(feature = "time")]
295private_impl_to_python_pyany!(OffsetDateTime => Py<PyDateTime>);
296
297#[cfg(feature = "time")]
300impl_for_self!(Py<PyDelta>);
301
302#[cfg(feature = "time")]
303private_impl_to_python_with_reference!(&self, py, Duration => Py<PyDelta> {
304 let days: i32 = self.whole_days().try_into().map_err(|_| {
305 PyValueError::new_err(format!("Cannot fit {} days into a 32-bit signed integer", self.whole_days()))
306 })?;
307 let seconds: i32 = self.whole_seconds().try_into().map_err(|_| {
308 PyValueError::new_err(format!("Cannot fit {} seconds into a 32-bit signed integer", self.whole_seconds()))
309 })?;
310 let microseconds:i32 = self.whole_microseconds().try_into().map_err(|_| {
311 PyValueError::new_err(format!("Cannot fit {} microseconds into a 32-bit signed integer", self.whole_microseconds()))
312 })?;
313 PyDelta::new(py, days, seconds, microseconds, true).map(|delta| delta.into_py(py))
314});
315
316#[cfg(feature = "time")]
317private_impl_to_python_pyany!(Duration => Py<PyDelta>);
318
319#[cfg(feature = "time")]
320private_impl_to_python_with_reference!(&self, py, std::time::Duration => Py<PyDelta> {
321 const DAY_FACTOR: u64 = 60 * 60 * 24;
323 let microseconds = self.as_micros() % 1_000_000;
324 let seconds = self.as_secs() % DAY_FACTOR;
325 let days = self.as_secs() / DAY_FACTOR;
326
327 let microseconds: i32 = microseconds.try_into().map_err(|_| {
328 PyValueError::new_err(format!("Cannot fit {microseconds} microseconds into a 32-bit signed integer"))
329 })?;
330
331 let seconds: i32 = seconds.try_into().map_err(|_| {
332 PyValueError::new_err(format!("Cannot fit {seconds} seconds into a 32-bit signed integer"))
333 })?;
334
335 let days: i32 = days.try_into().map_err(|_| {
336 PyValueError::new_err(format!("Cannot fit {days} days into a 32-bit signed integer"))
337 })?;
338
339 PyDelta::new(py, days, seconds, microseconds, true).map(|delta| delta.into_py(py))
340});
341
342#[cfg(feature = "time")]
343private_impl_to_python_pyany!(std::time::Duration => Py<PyDelta>);
344
345impl_for_self!(Py<PyDict>);
348
349impl<K1, K2, V1, V2, Hasher> ToPython<HashMap<K2, V2>> for &HashMap<K1, V1, Hasher>
350where
351 K1: ToPython<K2>,
352 V1: ToPython<V2>,
353 K2: ToPyObject + Eq + Hash,
354 V2: ToPyObject,
355{
356 fn to_python(&self, py: Python) -> PyResult<HashMap<K2, V2>> {
357 self.iter()
358 .map(|(key, val)| {
359 let key = key.to_python(py)?;
360 let val = val.to_python(py)?;
361 Ok((key, val))
362 })
363 .collect::<Result<_, _>>()
364 }
365}
366
367impl<K, V, Hasher> ToPython<Py<PyDict>> for &HashMap<K, V, Hasher>
368where
369 K: ToPython<Py<PyAny>> + std::fmt::Debug,
370 V: ToPython<Py<PyAny>>,
371{
372 fn to_python(&self, py: Python) -> PyResult<Py<PyDict>> {
373 let dict = PyDict::new(py);
374 for (key, val) in *self {
375 let pykey = key.to_python(py)?;
376 let pyval = val.to_python(py)?;
377 dict.set_item(pykey, pyval)?;
378 }
379 Ok(dict.into_py(py))
380 }
381}
382
383impl<K, V, Hasher> ToPython<Py<PyAny>> for &HashMap<K, V, Hasher>
384where
385 K: ToPython<Py<PyAny>> + std::fmt::Debug,
386 V: ToPython<Py<PyAny>>,
387{
388 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
389 <Self as ToPython<Py<PyDict>>>::to_python(self, py).map(|dict| dict.into_py(py))
390 }
391}
392
393impl<K1, K2, V1, V2, Hasher> ToPython<HashMap<K2, V2>> for HashMap<K1, V1, Hasher>
394where
395 K1: ToPython<K2>,
396 V1: ToPython<V2>,
397 K2: ToPyObject + Eq + Hash,
398 V2: ToPyObject,
399{
400 fn to_python(&self, py: Python) -> PyResult<HashMap<K2, V2>> {
401 <&Self as ToPython<HashMap<K2, V2>>>::to_python(&self, py)
402 }
403}
404
405impl<K, V, Hasher> ToPython<Py<PyDict>> for HashMap<K, V, Hasher>
406where
407 K: ToPython<Py<PyAny>> + std::fmt::Debug,
408 V: ToPython<Py<PyAny>>,
409{
410 fn to_python(&self, py: Python) -> PyResult<Py<PyDict>> {
411 <&Self as ToPython<Py<PyDict>>>::to_python(&self, py)
412 }
413}
414
415impl<K, V, Hasher> ToPython<Py<PyAny>> for HashMap<K, V, Hasher>
416where
417 K: ToPython<Py<PyAny>> + std::fmt::Debug,
418 V: ToPython<Py<PyAny>>,
419{
420 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
421 <Self as ToPython<Py<PyDict>>>::to_python(self, py).map(|dict| dict.into_py(py))
422 }
423}
424
425impl<K1, K2, V1, V2> ToPython<BTreeMap<K2, V2>> for &BTreeMap<K1, V1>
426where
427 K1: ToPython<K2> + std::fmt::Debug,
428 V1: ToPython<V2>,
429 K2: ToPyObject + Ord,
430 V2: ToPyObject,
431{
432 fn to_python(&self, py: Python) -> PyResult<BTreeMap<K2, V2>> {
433 let mut map = BTreeMap::new();
434 for (key, val) in *self {
435 let pykey = key.to_python(py)?;
436 let pyval = val.to_python(py)?;
437 map.insert(pykey, pyval);
438 }
439 Ok(map)
440 }
441}
442
443impl<K, V> ToPython<Py<PyDict>> for &BTreeMap<K, V>
444where
445 K: ToPython<Py<PyAny>> + std::fmt::Debug,
446 V: ToPython<Py<PyAny>>,
447{
448 fn to_python(&self, py: Python) -> PyResult<Py<PyDict>> {
449 let dict = PyDict::new(py);
450 for (key, val) in *self {
451 let pykey = key.to_python(py)?;
452 let pyval = val.to_python(py)?;
453 dict.set_item(pykey, pyval)?;
454 }
455 Ok(dict.into_py(py))
456 }
457}
458
459impl<K, V> ToPython<Py<PyAny>> for &BTreeMap<K, V>
460where
461 K: ToPython<Py<PyAny>> + std::fmt::Debug,
462 V: ToPython<Py<PyAny>>,
463{
464 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
465 <Self as ToPython<Py<PyDict>>>::to_python(self, py).map(|dict| dict.into_py(py))
466 }
467}
468
469impl<K1, K2, V1, V2> ToPython<BTreeMap<K2, V2>> for BTreeMap<K1, V1>
470where
471 K1: ToPython<K2> + std::fmt::Debug,
472 V1: ToPython<V2>,
473 K2: ToPyObject + Ord,
474 V2: ToPyObject,
475{
476 fn to_python(&self, py: Python) -> PyResult<BTreeMap<K2, V2>> {
477 <&Self as ToPython<BTreeMap<K2, V2>>>::to_python(&self, py)
478 }
479}
480
481impl<K, V> ToPython<Py<PyDict>> for BTreeMap<K, V>
482where
483 K: ToPython<Py<PyAny>> + std::fmt::Debug,
484 V: ToPython<Py<PyAny>>,
485{
486 fn to_python(&self, py: Python) -> PyResult<Py<PyDict>> {
487 <&Self as ToPython<Py<PyDict>>>::to_python(&self, py)
488 }
489}
490
491impl<K, V> ToPython<Py<PyAny>> for BTreeMap<K, V>
492where
493 K: ToPython<Py<PyAny>> + std::fmt::Debug,
494 V: ToPython<Py<PyAny>>,
495{
496 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
497 <Self as ToPython<Py<PyDict>>>::to_python(self, py).map(|dict| dict.into_py(py))
498 }
499}
500
501impl_for_self!(Py<PyFloat>);
504impl_for_self!(f32);
505impl_for_self!(f64);
506
507impl_for_primitive!(f32 => Py<PyFloat>);
508impl_for_primitive!(f64 => Py<PyFloat>);
509
510impl<T, Hasher> ToPython<Py<PyFrozenSet>> for &HashSet<T, Hasher>
513where
514 T: ToPython<Py<PyAny>> + Clone,
515{
516 fn to_python(&self, py: Python) -> PyResult<Py<PyFrozenSet>> {
517 let elements = self
518 .iter()
519 .map(|item| item.to_python(py))
520 .collect::<PyResult<Vec<_>>>()?;
521 PyFrozenSet::new(py, &elements).map(|set| set.into_py(py))
522 }
523}
524
525impl<T, Hasher> ToPython<Py<PyFrozenSet>> for HashSet<T, Hasher>
526where
527 T: ToPython<Py<PyAny>> + Clone,
528{
529 fn to_python(&self, py: Python) -> PyResult<Py<PyFrozenSet>> {
530 <&Self as ToPython<Py<PyFrozenSet>>>::to_python(&self, py)
531 }
532}
533
534impl<T> ToPython<Py<PyFrozenSet>> for &BTreeSet<T>
535where
536 T: ToPython<Py<PyAny>> + Clone,
537{
538 fn to_python(&self, py: Python) -> PyResult<Py<PyFrozenSet>> {
539 let elements = self
540 .iter()
541 .map(|item| item.to_python(py))
542 .collect::<PyResult<Vec<_>>>()?;
543 PyFrozenSet::new(py, &elements).map(|set| set.into_py(py))
544 }
545}
546
547impl<T> ToPython<Py<PyFrozenSet>> for BTreeSet<T>
548where
549 T: ToPython<Py<PyAny>> + Clone,
550{
551 fn to_python(&self, py: Python) -> PyResult<Py<PyFrozenSet>> {
552 <&Self as ToPython<Py<PyFrozenSet>>>::to_python(&self, py)
553 }
554}
555
556impl_for_self!(Py<PyLong>);
559impl_for_self!(i8);
560impl_for_self!(i16);
561impl_for_self!(i32);
562impl_for_self!(i64);
563impl_for_self!(i128);
564impl_for_self!(isize);
565impl_for_self!(u8);
566impl_for_self!(u16);
567impl_for_self!(u32);
568impl_for_self!(u64);
569impl_for_self!(u128);
570impl_for_self!(usize);
571
572impl_for_primitive!(i8 => Py<PyLong>);
573impl_for_primitive!(i16 => Py<PyLong>);
574impl_for_primitive!(i32 => Py<PyLong>);
575impl_for_primitive!(i64 => Py<PyLong>);
576impl_for_primitive!(i128 => Py<PyLong>);
577impl_for_primitive!(isize => Py<PyLong>);
578impl_for_primitive!(u8 => Py<PyLong>);
579impl_for_primitive!(u16 => Py<PyLong>);
580impl_for_primitive!(u32 => Py<PyLong>);
581impl_for_primitive!(u64 => Py<PyLong>);
582impl_for_primitive!(u128 => Py<PyLong>);
583impl_for_primitive!(usize => Py<PyLong>);
584
585impl<T, P> ToPython<Option<P>> for &Option<T>
588where
589 T: ToPython<P>,
590 P: ToPyObject,
591{
592 fn to_python(&self, py: Python) -> PyResult<Option<P>> {
593 self.as_ref().map(|inner| inner.to_python(py)).transpose()
594 }
595}
596
597impl<T, P> ToPython<Option<P>> for Option<T>
598where
599 T: ToPython<P>,
600 P: ToPyObject,
601{
602 fn to_python(&self, py: Python) -> PyResult<Option<P>> {
603 <&Self as ToPython<Option<P>>>::to_python(&self, py)
604 }
605}
606
607impl_for_self!(Py<PyList>);
610
611impl<T, P> ToPython<Vec<P>> for &[T]
612where
613 T: ToPython<P> + Clone,
614 P: ToPyObject,
615{
616 fn to_python(&self, py: Python) -> PyResult<Vec<P>> {
617 self.iter()
618 .map(|item| item.to_python(py))
619 .collect::<PyResult<Vec<_>>>()
620 }
621}
622
623impl<T> ToPython<Py<PyList>> for &[T]
624where
625 T: ToPython<Py<PyAny>> + Clone,
626{
627 fn to_python(&self, py: Python) -> PyResult<Py<PyList>> {
628 let elements = self
629 .iter()
630 .map(|item| item.to_python(py))
631 .collect::<PyResult<Vec<_>>>()?;
632 Ok(PyList::new(py, elements).into_py(py))
633 }
634}
635
636impl<T> ToPython<Py<PyAny>> for &[T]
637where
638 T: ToPython<Py<PyAny>> + Clone,
639{
640 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
641 <Self as ToPython<Py<PyList>>>::to_python(self, py).map(|item| item.into_py(py))
642 }
643}
644
645impl<T, P> ToPython<Vec<P>> for [T]
646where
647 T: ToPython<P> + Clone,
648 P: ToPyObject,
649{
650 fn to_python(&self, py: Python) -> PyResult<Vec<P>> {
651 <&Self as ToPython<Vec<P>>>::to_python(&self, py)
652 }
653}
654
655impl<T> ToPython<Py<PyList>> for [T]
656where
657 T: ToPython<Py<PyAny>> + Clone,
658{
659 fn to_python(&self, py: Python) -> PyResult<Py<PyList>> {
660 <&Self as ToPython<Py<PyList>>>::to_python(&self, py)
661 }
662}
663
664impl<T> ToPython<Py<PyAny>> for [T]
665where
666 T: ToPython<Py<PyAny>> + Clone,
667{
668 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
669 <&Self as ToPython<Py<PyAny>>>::to_python(&self, py)
670 }
671}
672
673impl<T, P> ToPython<Vec<P>> for Vec<T>
674where
675 T: ToPython<P> + Clone,
676 P: ToPyObject,
677{
678 fn to_python(&self, py: Python) -> PyResult<Vec<P>> {
679 self.as_slice().to_python(py)
680 }
681}
682
683impl<T, P> ToPython<Vec<P>> for &Vec<T>
684where
685 T: ToPython<P> + Clone,
686 P: ToPyObject,
687{
688 fn to_python(&self, py: Python) -> PyResult<Vec<P>> {
689 self.as_slice().to_python(py)
690 }
691}
692
693impl<T> ToPython<Py<PyList>> for Vec<T>
694where
695 T: ToPython<Py<PyAny>> + Clone,
696{
697 fn to_python(&self, py: Python) -> PyResult<Py<PyList>> {
698 self.as_slice().to_python(py)
699 }
700}
701
702impl<T> ToPython<Py<PyList>> for &Vec<T>
703where
704 T: ToPython<Py<PyAny>> + Clone,
705{
706 fn to_python(&self, py: Python) -> PyResult<Py<PyList>> {
707 self.as_slice().to_python(py)
708 }
709}
710
711impl<T> ToPython<Py<PyAny>> for Vec<T>
712where
713 T: ToPython<Py<PyAny>> + Clone,
714{
715 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
716 self.as_slice().to_python(py)
717 }
718}
719
720impl<T> ToPython<Py<PyAny>> for &Vec<T>
721where
722 T: ToPython<Py<PyAny>> + Clone,
723{
724 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
725 self.as_slice().to_python(py)
726 }
727}
728
729impl_for_self!(Py<PySet>);
732
733impl<T, P, Hasher> ToPython<HashSet<P, Hasher>> for &HashSet<T, Hasher>
734where
735 T: ToPython<P> + Clone,
736 P: ToPyObject + Hash + Eq,
737 Hasher: Default + BuildHasher,
738{
739 fn to_python(&self, py: Python) -> PyResult<HashSet<P, Hasher>> {
740 self.iter()
741 .map(|item| item.to_python(py))
742 .collect::<PyResult<_>>()
743 }
744}
745
746impl<T, P, Hasher> ToPython<HashSet<P, Hasher>> for HashSet<T, Hasher>
747where
748 T: ToPython<P> + Clone,
749 P: ToPyObject + Hash + Eq,
750 Hasher: Default + BuildHasher,
751{
752 fn to_python(&self, py: Python) -> PyResult<HashSet<P, Hasher>> {
753 <&Self as ToPython<HashSet<P, Hasher>>>::to_python(&self, py)
754 }
755}
756
757impl<T, Hasher> ToPython<Py<PySet>> for &HashSet<T, Hasher>
758where
759 T: ToPython<Py<PyAny>> + Clone,
760{
761 fn to_python(&self, py: Python) -> PyResult<Py<PySet>> {
762 let set = PySet::empty(py)?;
764 for item in *self {
765 set.add(item.to_python(py)?)?;
766 }
767 Ok(set.into_py(py))
768 }
769}
770
771impl<T, Hasher> ToPython<Py<PySet>> for HashSet<T, Hasher>
772where
773 T: ToPython<Py<PyAny>> + Clone,
774{
775 fn to_python(&self, py: Python) -> PyResult<Py<PySet>> {
776 <&Self as ToPython<Py<PySet>>>::to_python(&self, py)
777 }
778}
779
780impl<T, Hasher> ToPython<Py<PyAny>> for &HashSet<T, Hasher>
781where
782 T: ToPython<Py<PyAny>> + Clone,
783{
784 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
785 <Self as ToPython<Py<PySet>>>::to_python(self, py).map(|item| item.into_py(py))
786 }
787}
788
789impl<T, Hasher> ToPython<Py<PyAny>> for HashSet<T, Hasher>
790where
791 T: ToPython<Py<PyAny>> + Clone,
792{
793 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
794 <&Self as ToPython<Py<PyAny>>>::to_python(&self, py)
795 }
796}
797
798impl<T, P> ToPython<BTreeSet<P>> for &BTreeSet<T>
799where
800 T: ToPython<P> + Clone,
801 P: ToPyObject + Ord + Hash,
803{
804 fn to_python(&self, py: Python) -> PyResult<BTreeSet<P>> {
805 self.iter()
806 .map(|item| item.to_python(py))
807 .collect::<PyResult<_>>()
808 }
809}
810
811impl<T, P> ToPython<BTreeSet<P>> for BTreeSet<T>
812where
813 T: ToPython<P> + Clone,
814 P: ToPyObject + Ord + Hash,
815{
816 fn to_python(&self, py: Python) -> PyResult<BTreeSet<P>> {
817 <&Self as ToPython<BTreeSet<P>>>::to_python(&self, py)
818 }
819}
820
821impl<T> ToPython<Py<PySet>> for &BTreeSet<T>
822where
823 T: ToPython<Py<PyAny>> + Clone,
824{
825 fn to_python(&self, py: Python) -> PyResult<Py<PySet>> {
826 let set = PySet::empty(py)?;
828 for item in *self {
829 set.add(item.to_python(py)?)?;
830 }
831 Ok(set.into_py(py))
832 }
833}
834
835impl<T> ToPython<Py<PySet>> for BTreeSet<T>
836where
837 T: ToPython<Py<PyAny>> + Clone,
838{
839 fn to_python(&self, py: Python) -> PyResult<Py<PySet>> {
840 <&Self as ToPython<Py<PySet>>>::to_python(&self, py)
841 }
842}
843
844impl<T> ToPython<Py<PyAny>> for &BTreeSet<T>
845where
846 T: ToPython<Py<PyAny>> + Clone,
847{
848 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
849 <Self as ToPython<Py<PySet>>>::to_python(self, py).map(|item| item.into_py(py))
850 }
851}
852
853impl<T> ToPython<Py<PyAny>> for BTreeSet<T>
854where
855 T: ToPython<Py<PyAny>> + Clone,
856{
857 fn to_python(&self, py: Python) -> PyResult<Py<PyAny>> {
858 <&Self as ToPython<Py<PyAny>>>::to_python(&self, py)
859 }
860}
861
862impl_for_self!(Py<PyString>);
865impl_for_self!(String);
866
867private_impl_to_python_with_reference!(&self, py, str => Py<PyString> {
868 Ok(PyString::new(py, self).into_py(py))
869});
870
871private_impl_to_python_pyany!(str => Py<PyString>);
872
873private_impl_to_python_with_reference!(&self, py, String => Py<PyString> {
874 self.as_str().to_python(py)
875});
876
877#[cfg(feature = "time")]
880impl_for_self!(Py<PyTime>);
881
882#[cfg(feature = "time")]
883private_impl_to_python_with_reference!(&self, py, (Time, Option<UtcOffset>) => Py<PyTime> {
884 let (time, offset) = self;
885 let hour = time.hour();
886 let minute = time.minute();
887 let second = time.second();
888 let microsecond = time.microsecond();
889 let tzinfo: Option<Py<PyTzInfo>> = offset.map(|offset| {
890 offset.to_python(py)
891 }).transpose()?;
892 let tzinfo = tzinfo.as_ref().map(|tzinfo| tzinfo.as_ref(py));
893 PyTime::new(py, hour, minute, second, microsecond, tzinfo).map(|time| time.into_py(py))
894});
895
896#[cfg(feature = "time")]
897private_impl_to_python_pyany!((Time, Option<UtcOffset>) => Py<PyTime>);
898
899#[cfg(feature = "time")]
902impl_for_self!(Py<PyTzInfo>);
903
904#[cfg(feature = "time")]
905private_impl_to_python_with_reference!(&self, py, UtcOffset => Py<PyTzInfo> {
906 let datetime = py.import("datetime")?;
907 let timezone = datetime.getattr("timezone")?;
908 let (hour, minute, second) = self.as_hms();
909 let seconds = i64::from(second) + 60 * (i64::from(minute) + (60 * i64::from(hour)));
910 let duration = Duration::new(seconds, 0);
911 let delta: Py<PyDelta> = duration.to_python(py)?;
912 let args = (delta,).to_object(py);
913 let args: &PyTuple = args.extract(py)?;
914 let tzinfo = timezone.call1(args)?;
915 tzinfo.extract()
916});
917
918#[cfg(feature = "time")]
919private_impl_to_python_pyany!(UtcOffset => Py<PyTzInfo>);
920
921