ramonhagenaars / jsons

🐍 A Python lib for (de)serializing Python objects to/from JSON
https://jsons.readthedocs.io
MIT License
288 stars 40 forks source link

How to ignore or disable serialization of super classes #109

Open javiruiz opened 4 years ago

javiruiz commented 4 years ago

Hi Ramon, I am trying to leverage the power of your package in a CDN system where a test component is itself composed of several components, all inheriting from a common class that I can't (and I shouldn't) touch. Unfortunately, jsons.dumps is giving a stackoverflow error (Reason: maximum recursion depth exceeded while calling a Python object. Ignoring the attribute.)

Is there a way to avoid the serialization of a super class?

ramonhagenaars commented 4 years ago

Hi Javier,

If I understand it right, that base class is causing you trouble when serializing? If that's the case, then you could dump your object while providing a target class:

@dataclass
class Parent:
    x: int

@dataclass
class Child(Parent):
    y: int

jsons.dumps(Child(1, 2), cls=Child)  # <-- By dumping as a Child, all of Parent's attribute are omitted.

Or, if you know which attributes of that base class are causing the headache, you could choose to omit just those:

jsons.dumps(Child(1, 2), strip_attr='x')  # <-- You can also provide several attributes e.g. strip_attr=('x', 'y').

Hope that helps, let me know!

javiruiz commented 4 years ago

Hello Ramon, Thanks for your prompt response! Indeed your understanding of the issue is perfect. After I posted the question, I was investigating further and I used: Myclass(MyBaseClass, jsons.JsonSerializable.with_dump(strip_attr=('log', 'logger','suite_log_file'))):

So that solved some of the problems I was having. Then I was toying around setting the serializer of the base class: jsons.set_serializer(lambda my_base_class, **_: "This is my Base Class serialized!", MyBaseClass)

Of course your solution seems much more simple and I am going to try it next. jsons is a magnificent library, very easy to use, and full of nice features!

ramonhagenaars commented 4 years ago

Hi javiruiz,

Cool to see that you found other solutions that work as well and that you appreciate jsons so much. You just made my day! 😃

Let me know if there's anything else!

javiruiz commented 4 years ago

Hi again, sorry to bother you with this but I tried:

from dataclasses import dataclass

import jsons

@dataclass
class Parent:
    x: int

@dataclass
class Child(Parent):
    y: int

print("Parent and Child attributes")
print(jsons.dumps(Child(1, 2)))
print("Child attributes only")
print(jsons.dumps(Child(1, 2), cls=Child)

And I obtain the same output both times:

(venv) MacBook-Pro:jsons_test jarvierziu$ python jsons_test.py 
Parent and Child attributes
{"x": 1, "y": 2}
Child attributes only
{"x": 1, "y": 2}

I wonder what I am doing wrong.

ramonhagenaars commented 4 years ago

hmm, the feature seems to be broken. I'll report this as a bug to be fixed in a next release. The strip_attr still works though, have you tried that?

javiruiz commented 4 years ago

Thank you for getting back to me. Yes, the strip_attr feature works great. I am using it with the class jsons.JsonSerializable and the with_dump class method.