jcrist / msgspec

A fast serialization and validation library, with builtin support for JSON, MessagePack, YAML, and TOML
https://jcristharif.com/msgspec/
BSD 3-Clause "New" or "Revised" License
2.01k stars 59 forks source link

Unable to encode `lxml.etree._ElementUnicodeResult` #690

Open umarbutler opened 1 month ago

umarbutler commented 1 month ago

Hi, First off, thank you for creating this library, I have found it immensely useful and it has saved me a lot of time spent serialising and deserialising objects.

I was using msgspec to encode a Struct that, unbeknowest to me, contained a lxml.etree._ElementUnicodeResult instance. The attribute in which the instance was stored was type hinted as a string. When creating the Struct, no errors were raised. However, when attempting to encode the Struct, an encoding error was raised.

There are two alternative solutions I would suggest implementing: a) Raise an exception if lxml.etree._ElementUnicodeResult is passed as the value for an attribute type hinted as a string; or b) Serialise lxml.etree._ElementUnicodeResult instances as if they were strings.

The latter approach is what orjson does, although I am not sure if that it is intentional.

I only picked up on this because I switched from orjson to msgspec.

lxml.etree._ElementUnicodeResult behaves pretty much like a string so I personally would prefer option (b).

In terms of reproducing the error, you may do so using the below code:

import msgspec
import lxml.etree

class DummyStruct(msgspec.Struct):
    i_am_a_string: str

element_unicode_result = lxml.etree._ElementUnicodeResult('I am a pseudo-string.')
dummy_struct = DummyStruct(i_am_a_string=element_unicode_result) # No `TypeError`!
msgspec.json.encode(dummy_struct) # `TypeError`?!

And this code snippet demonstrates what orjson does when passed with lxml.etree._ElementUnicodeResult:

import orjson

element_unicode_result = lxml.etree._ElementUnicodeResult('I am a pseudo-string.')
orjson.dumps(element_unicode_result) # No `TypeError`!

Thanks again for your great work!