Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DotDict isn't JSON-serializable #341

Closed
jlowin opened this issue Nov 13, 2018 · 4 comments
Closed

DotDict isn't JSON-serializable #341

jlowin opened this issue Nov 13, 2018 · 4 comments
Assignees

Comments

@jlowin
Copy link
Member

jlowin commented Nov 13, 2018

DotDicts feel like dicts, until you try to ship them as JSON:

In [1]: import json

In [2]: from prefect.utilities.collections import DotDict

In [3]: json.dumps(DotDict(x=1, y=2))

Results in the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-3-b595d5c6cfdf> in <module>()
----> 1 json.dumps(DotDict(x=1, y=2))

/anaconda3/lib/python3.6/json/__init__.py in dumps(obj, skipkeys, ensure_ascii, check_circular, allow_nan, cls, indent, separators, default, sort_keys, **kw)
    229         cls is None and indent is None and separators is None and
    230         default is None and not sort_keys and not kw):
--> 231         return _default_encoder.encode(obj)
    232     if cls is None:
    233         cls = JSONEncoder

/anaconda3/lib/python3.6/json/encoder.py in encode(self, o)
    197         # exceptions aren't as detailed.  The list call should be roughly
    198         # equivalent to the PySequence_Fast that ''.join() would do.
--> 199         chunks = self.iterencode(o, _one_shot=True)
    200         if not isinstance(chunks, (list, tuple)):
    201             chunks = list(chunks)

/anaconda3/lib/python3.6/json/encoder.py in iterencode(self, o, _one_shot)
    255                 self.key_separator, self.item_separator, self.sort_keys,
    256                 self.skipkeys, _one_shot)
--> 257         return _iterencode(o, 0)
    258
    259 def _make_iterencode(markers, _default, _encoder, _indent, _floatstr,

/anaconda3/lib/python3.6/json/encoder.py in default(self, o)
    178         """
    179         raise TypeError("Object of type '%s' is not JSON serializable" %
--> 180                         o.__class__.__name__)
    181
    182     def encode(self, o):

TypeError: Object of type 'DotDict' is not JSON serializable
@jlowin
Copy link
Member Author

jlowin commented Nov 13, 2018

The tricky thing about messing with JSON by, for example, modifying the default encoder, is that some libraries use their own custom encoders (or reinstantiate the default encoder) and therefore won't pick up the modifications. I guess the wishlist item would be for Python to think of DotDict as being a dict

@cicdw
Copy link
Member

cicdw commented Nov 15, 2018

So the TLDR here is that there is no internal-to-DotDict way of doing this without changing the call to json.dumps(). I tried to hack it to force json to think it was a dict and even that didn't work:

TypeError: Object of type 'dict' is not JSON serializable

@jlowin
Copy link
Member Author

jlowin commented Nov 15, 2018

It makes sense.

Perhaps as a convenience, we could add a to_dict() method that calls as_nested_dict(self, dict)?

@downloadpizza
Copy link

We could also talk with the people from python json to add a __serialize__ magic method thats implementable and is used to serialize non-primitive data

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants