Relax input requirements in deserialize_str - #40
Conversation
Instead of attempting to downcast the input to a PyString, rely on the fact that for str objects, calling __str__ is a no-op, while for other objects it may allow us to support neat use cases. An example of one such use case is turning Python's uuid.UUID into Rust's uuid::Uuid. If you call Uuid::depythonize you end up in <Uuid as Deserialize>::deserialize (if you enabled its serde feature). Since Depythonizer doesn't override Deserialize::is_human_readable, the implementation tries to deserialize with deserialize_str. At that point, the Deserializer has a value of type uuid.UUID (actually PyAny, but it really is uuid.UUID), and the visitor expects a value of type &str. We can make that happen by using __str__.
ShaneMurphy2
commented
Mar 22, 2023
Opened this PR but I'm not sure this is the right way to do this, or if it's even broadly useful. Wanted to get some feedback. Generally, I think this approach is sound, as it mirrors the way An alternate idea I had would be to maintain a list of "known types" that we want to stringify, but that could get expensive. |
I just realized there's no way to implement the serialization half of this, since there is nothing in the serde data model that tells us the original Rust type was a Uuid. This might still be a good change, but I'll wait for feedback. |
davidhewitt
commented
Mar 23, 2023
Hello, thanks for the PR! So I think this use-case is reasonable but I'm a bit nervous about introducing this coercion globally. Instead would you be prepared to amend this PR to add a The |
ShaneMurphy2
commented
Mar 23, 2023
:)
Totally, I was considering feature flags/custom for this.
The docs say "This is equivalent to the Python expression |
davidhewitt
commented
Mar 23, 2023
Right you are; I had peeked at the implementation and mixed up |
ShaneMurphy2
commented
Mar 23, 2023
I did some further pondering about the usefulness of this change with regards to UUIDs. I got wrapped around the axle with serde, pythonize, and {To/From}PyObject. Preserving non serde data model types through serialization isn't really in scope for pythonize I think. Really what I was looking for was a custom implementation of FromPyObject. That being said, I think that being more permissive with what is considered a |
Instead of attempting to downcast the input to a PyString, rely on the fact that for str objects, calling __str__ is a no-op, while for other objects it may allow us to support neat use cases.
An example of one such use case is turning Python's uuid.UUID into Rust's uuid::Uuid. If you call Uuid::depythonize you end up in <Uuid as Deserialize>::deserialize (if you enabled its serde feature). Since Depythonizer doesn't override Deserialize::is_human_readable, the implementation tries to deserialize with deserialize_str. At that point, the Deserializer has a value of type uuid.UUID (actually PyAny, but it really is uuid.UUID), and the visitor expects a value of type &str. We can make that happen by using str.