samuelcolvin / rtoml

A fast TOML library for python implemented in rust.
https://pypi.org/project/rtoml/
MIT License
323 stars 28 forks source link

Subclass of `dict` is not recognized since 0.9 #57

Open pwwang opened 1 year ago

pwwang commented 1 year ago
Python 3.9.5 (default, Jun  4 2021, 12:28:51) 
Type 'copyright', 'credits' or 'license' for more information
IPython 8.1.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import rtoml                                                

In [2]: rtoml.VERSION                                               
Out[2]: '0.8.0'

In [3]: class MyDict(dict): ...                                     

In [4]: d = MyDict(a=1)                                             

In [5]: rtoml.dumps(d)                                              
Out[5]: 'a = 1\n'
Python 3.9.5 (default, Jun  4 2021, 12:28:51) 
Type 'copyright', 'credits' or 'license' for more information
IPython 8.1.1 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import rtoml                                                                     

In [2]: rtoml.__version__                                                                
Out[2]: '0.9.0'

In [3]: class MyDict(dict): ...                                                          

In [4]: d = MyDict(a=1)                                                                  

In [5]: d                                                                                
Out[5]: {'a': 1}

In [6]: rtoml.dumps(d)                                                                   
---------------------------------------------------------------------------
TomlSerializationError                    Traceback (most recent call last)
Input In [6], in <cell line: 1>()
----> 1 rtoml.dumps(d)

File ~/miniconda3/lib/python3.9/site-packages/rtoml/__init__.py:49, in dumps(obj, pretty)
     46 else:
     47     serialize = _rtoml.serialize
---> 49 return serialize(obj)

TomlSerializationError: {'a': 1} (MyDict) is not serializable to TOML
samuelcolvin commented 1 year ago

Makes sense we need to try the next tp_base like here.

Shouldn't be too hard to fix, would you like to have a try.

pwwang commented 5 months ago

This still prevents me from upgrading rtoml to 0.11 for some of my projects.

Originally comments with the PR:

Can we add something to make it work at the python end?

For example, at dump(obj, ...) or dumps(obj, ...), can we do:

def dump(obj, ...):
    if issubclass(type(obj), dict):
        obj = dict(obj)
    # continue logic
samuelcolvin commented 5 months ago

well the problem is it needs to be recursive.

You could add your own method to do this. By the way, it's better to use use type(x) in a lookup, then work through the __mro__, like we did in pydantic v1.

pwwang commented 5 months ago

well the problem is it needs to be recursive.

That's a good point. Maybe I'll just wrap it myself.

Feel free to close.

samuelcolvin commented 5 months ago

Ultimate solution is https://github.com/pydantic/pydantic-core/issues/1339, I'll leave this open for that.