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

About the development of the FEM module/workbench.

Moderator: bernd

User avatar
bernd
Posts: 10823
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

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

Postby bernd » Wed Mar 18, 2020 11:25 am

great this helps a lot. I will have a look.

Thus on three times saving I get ...

Code: Select all

{'Type': {'Type': {'Type': {'Type': 'Fem::FemMeshRegion'}}}}
:o
wmayer
Site Admin
Posts: 16465
Joined: Thu Feb 19, 2009 10:32 am

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

Postby wmayer » Wed Mar 18, 2020 11:36 am

wmayer wrote:
Wed Mar 18, 2020 11:22 am
So, in some of your __getstate__ methods you return an inappropriate dict.
I quickly looked at the FEM code and in none of your fem objects a method __getstate__ exists. This if course won't work because as explained in the other thread when saving the Python proxy it invokes the __getstate__ method if it exists, if not then it uses the dict of the object.

So, what happens is that on safe time the dict is saved and when restoring it the dict is passed to __setstate__ because this exists. This way the original dict will be assigned to Type, hence you have a {'Type': {'Type': 'Fem::FemMeshRegion'}} and for every further save&load step the dict will be nested by one level.

Important hint: do never offer only __setstate__ or __gestate__ alone. Either implement both or none of them.
In this case if it's important that Type must be serialized then do:

Code: Select all

    def __setstate__(self, state):
        if state:
            self.Type = state
    def __getstate__(self):
            return self.Type
User avatar
bernd
Posts: 10823
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

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

Postby bernd » Wed Mar 18, 2020 11:39 am

wmayer wrote:
Wed Mar 18, 2020 11:22 am
So, in some of your __getstate__ methods you return an inappropriate dict.
the __getstate__ was missiong at all for the python base object. After this
https://forum.freecadweb.org/viewtopic.php?f=18&t=44021 I should have known, but I only added them to the FEM Python base VP not to the normal FEM Python base obj

git commit d0fcbf34b0
User avatar
bernd
Posts: 10823
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

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

Postby bernd » Wed Mar 18, 2020 11:42 am

cross post ...
User avatar
bernd
Posts: 10823
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

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

Postby bernd » Wed Mar 18, 2020 11:43 am

User avatar
bernd
Posts: 10823
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

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

Postby bernd » Wed Mar 18, 2020 11:45 am

wmayer wrote:
Wed Mar 18, 2020 11:36 am
Important hint: do never offer only __setstate__ or __gestate__ alone. Either implement both or none of them.
got this ...

What is this "if state ..." useful for in __setstate__?

Code: Select all

def __setstate__(self, state):
        # a few FEM objects had this attribut assignment before the move to this Python base obj class
        # these objects will give a setAttr failed error on document loading without this assignment
        if state:
            self.Type = state
https://github.com/FreeCAD/FreeCAD/blob ... py#L49-L50
wmayer
Site Admin
Posts: 16465
Joined: Thu Feb 19, 2009 10:32 am

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

Postby wmayer » Wed Mar 18, 2020 12:04 pm

What is this "if state ..." useful for in __setstate__?
I don't think it's really needed.
User avatar
bernd
Posts: 10823
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

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

Postby bernd » Wed Mar 18, 2020 2:04 pm

Another question ...

When should __getstate__ and __setstate__ have a return value?

https://github.com/FreeCAD/FreeCAD/blob ... #L129-L134
wmayer
Site Admin
Posts: 16465
Joined: Thu Feb 19, 2009 10:32 am

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

Postby wmayer » Wed Mar 18, 2020 2:15 pm

When restoring a proxy object its __init__ function won't be executed, i.e.. when you add some additional attributes and you don't want to lose them on save&restore then __getstate__/__setstate__ is a good option.
User avatar
bernd
Posts: 10823
Joined: Sun Sep 08, 2013 8:07 pm
Location: Zürich, Switzerland

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

Postby bernd » Wed Mar 18, 2020 5:16 pm

In the link I posted they return None. Is this needed? If not would it not better to use just pass instead of return None? Or the other way around, should they always return None?