Skip to content

How to serialize (JSON) a type reference? #315

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

Open
kkg-else42 opened this issue Oct 24, 2022 · 6 comments
Open

How to serialize (JSON) a type reference? #315

kkg-else42 opened this issue Oct 24, 2022 · 6 comments

Comments

@kkg-else42
Copy link
Contributor

(I know it's not a cattrs issue.)
I'm looking for a way to JSON-serialize a type-ref inside a attrs-class.
But type-refs aren't supported by json-lib.
See a litte example:

import attrs, cattrs, json

@attrs.mutable
class A:
    my_type: type

@attrs.mutable
class B:
    foo: int

a1=A(my_type=B)

a1u=cattrs.unstructure(a1)

a1uj=json.dumps(a1u)
Traceback (most recent call last):
  File "C:\Python310\lib\code.py", line 90, in runcode
    exec(code, self.locals)
  File "<input>", line 1, in <module>
  File "C:\Python310\lib\json\__init__.py", line 231, in dumps
    return _default_encoder.encode(obj)
  File "C:\Python310\lib\json\encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "C:\Python310\lib\json\encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
  File "C:\Python310\lib\json\encoder.py", line 179, in default
    raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type type is not JSON serializable

Are there any ideas on how to achieve my goal?

@Tinche
Copy link
Member

Tinche commented Oct 24, 2022

What json output are you expecting?

@kkg-else42
Copy link
Contributor Author

I want to make the de-serialization as generic as possible for various attrs classes (their instances are sent as JSON messages via MQTT). For this purpose, the respective type information should be contained in the message (in a container). Since this information is needed by cattrs.structure.
My current work-around is to store the type information as str-value.

@Tinche
Copy link
Member

Tinche commented Oct 31, 2022

Do you only want the class name in the JSON payload, or more information?

@kkg-else42
Copy link
Contributor Author

kkg-else42 commented Oct 31, 2022

To rebuild a type object one needs the class name (my_type.__name__) and the module name (my_type.__module__):
my_type: type = getattr(importlib.import_module(<module-name>), <class-name>)

At the moment I store these two values. I'm sure this could be done via hooks, which I haven't looked into yet.

But maybe a general json-lib support for type-object would be the better.

@Tinche
Copy link
Member

Tinche commented Oct 31, 2022

Interesting, ok. We're working on what we're calling tagged union support, this sounds like it. It's un/structuring a union with some metadata attached so it can be recreated on the other end.

Looks like you want the metadata to be a fully-qualified name for a class, and the structuring hook to import it. I'll keep this use case in mind.

@kkg-else42
Copy link
Contributor Author

kkg-else42 commented Oct 31, 2022

Looks like you want the metadata to be a fully-qualified name for a class, and the structuring hook to import it.

Yes, this is what I want.

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

2 participants