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