obj.Proxy.Type is a dict, not a string

About the development of the FEM module/workbench.

Moderator: bernd

vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: obj.Proxy.Type is a dict, not a string

Post by vocx »

I'd also love an explanation of these two functions.

This is what the documentation on Scripted objects say.

Code: Select all

    def __getstate__(self):
        '''When saving the document this object gets stored using Python's json module.\
                Since we have some un-serializable parts here -- the Coin stuff -- we must define this method\
                to return a tuple of all serializable objects or None.'''
        return None
 
    def __setstate__(self,state):
        '''When restoring the serialized object from document we have the chance to set some internals here.\
                Since no data were serialized nothing needs to be done here.'''
        return None
Is this information supposed to be correct? Here it talks about a tuple, but Werner mentions a dictionary, so which is which?

There are places talking about "serializing" but this doesn't mean anything to me. Is there somewhere that describes this in detail?

I also remember reading some old documentation that in the past objects where "serialized" using Python's pickle module. I suppose this was changed to json at some point. Or what is the history behind this?

So, this all seems like magic to me, it works, but I don't know why.

In Draft, there are several scripted objects, with various methods but no comments. I don't understand what all those methods do, so for the most part I don't touch them so they keep working like usual.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: obj.Proxy.Type is a dict, not a string

Post by vocx »

bernd wrote: Wed Mar 18, 2020 2:04 pm When should __getstate__ and __setstate__ have a return value?

https://github.com/FreeCAD/FreeCAD/blob ... #L129-L134
I dug further into this.

It seems that these two properties are needed to support the pickle module of Python. This was done in the early days of FreeCAD, under Python 2. Using pickle was common years ago, but that is no longer the case.

Nowadays, Python uses json, but the same __getstate__ and __setstate__ methods are supported.

Essentially, whatever you return in __getstate__ will be saved. The "state" argument of __setstate__ will then receive this information, which you can then manipulate as you want.

Code: Select all

class Something:
    def __init__(self, obj):
        self.Type = "A"
        self.version = 1
        obj.Proxy = self
    def __getstate__(self):
        return self.Type
    def __setstate__(self, state):
        self.Type = state
In __setstate__ the variable "state" will contain the previous value of "self.Type", because this was returned by __getstate__. The return value of __setstate__ doesn't actually matter; what matters is the return value of __getstate__.

You must implement both so the information is passed correctly. You basically have two methods, "method A returns Z", "method B receives Z".

If the methods are not implemented then the default information that is passed is the class's __dict__ variable, which contains all attributes.

Code: Select all

class Something:
    def __init__(self, obj):
        self.Type = "A"
        self.version = 1
        obj.Proxy = self
    def __getstate__(self):
        return self.__dict__
    def __setstate__(self, state):
        self.__dict__ = state
Then if we use the class.

Code: Select all

obj = App.ActiveDocument.addObject(...)
Something(obj)

Code: Select all

>>> print(obj.Proxy.__dict__)
{'Type': 'A', 'version': 1}
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
Post Reply