From 3ee312492e0bdca55cbdc387ef39069f7ef3c516 Mon Sep 17 00:00:00 2001 From: Lily Foote Date: Fri, 3 Mar 2023 16:58:47 +0000 Subject: [PATCH 1/2] Add tests for deserializing `set` and `frozenset` --- src/de.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/de.rs b/src/de.rs index c6a171f..3e26849 100644 --- a/src/de.rs +++ b/src/de.rs @@ -558,6 +558,22 @@ mod test { test_de(code, &expected, &expected_json); } + #[test] + fn test_tuple_from_pyset() { + let expected = ("foo".to_string(), 5); + let expected_json = json!(["foo", 5]); + let code = "{'foo', 5}"; + test_de(code, &expected, &expected_json); + } + + #[test] + fn test_tuple_from_pyfrozenset() { + let expected = ("foo".to_string(), 5); + let expected_json = json!(["foo", 5]); + let code = "frozenset({'foo', 5})"; + test_de(code, &expected, &expected_json); + } + #[test] fn test_vec() { let expected = vec![3, 2, 1]; From 858a3fbd49511fcc847c2833d3bdbaded0d03aeb Mon Sep 17 00:00:00 2001 From: Lily Foote Date: Fri, 3 Mar 2023 17:01:06 +0000 Subject: [PATCH 2/2] Change PySequenceAccess to work with iterators `set` and `frozenset` don't support the Sequence protocol, but they do support the Iterator protocol, so let's use that instead. --- src/de.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/de.rs b/src/de.rs index 3e26849..a60fa38 100644 --- a/src/de.rs +++ b/src/de.rs @@ -23,7 +23,7 @@ impl<'de> Depythonizer<'de> { } fn sequence_access(&self, expected_len: Option) -> Result> { - let seq: &PySequence = self.input.downcast()?; + let seq: &PyIterator = self.input.iter()?; let len = self.input.len()?; match expected_len { @@ -289,13 +289,13 @@ impl<'a, 'de> de::Deserializer<'de> for &'a mut Depythonizer<'de> { } struct PySequenceAccess<'a> { - seq: &'a PySequence, + seq: &'a PyIterator, index: usize, len: usize, } impl<'a> PySequenceAccess<'a> { - fn new(seq: &'a PySequence, len: usize) -> Self { + fn new(seq: &'a PyIterator, len: usize) -> Self { Self { seq, index: 0, len } } } @@ -308,7 +308,11 @@ impl<'de> de::SeqAccess<'de> for PySequenceAccess<'de> { T: de::DeserializeSeed<'de>, { if self.index < self.len { - let mut item_de = Depythonizer::from_object(self.seq.get_item(self.index)?); + let item = match self.seq.next() { + Some(item) => item?, + None => return Ok(None), + }; + let mut item_de = Depythonizer::from_object(item); self.index += 1; seed.deserialize(&mut item_de).map(Some) } else {