After copyObject(), the object has no attribute

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
xianyu
Posts: 66
Joined: Mon Jun 27, 2022 7:34 am

After copyObject(), the object has no attribute

Post by xianyu »

Hi,
I'm improving a project.When I copy an object, the new object will display this error, but my original object is OK.The "Data-Property" of the new object also displays the "shapetype" attribute. What's the reason?
File "Front_Surface.py", line 66, in onChanged
if obj.shapetype == "Conic":
<class 'AttributeError'>: 'FeaturePython' object has no attribute 'shapetype'

Code: Select all

class FrontSurface:
    def __init__(self):
        doc = FreeCAD.ActiveDocument
        obj= doc.addObject("Part::FeaturePython", "FrontSurface")
        obj.addProperty("App::PropertyEnumeration","shapetype","Shape","specifies type").shapetype=["Conic","Cylinder","Asphere"]
        obj.addProperty("App::PropertyFloat", "curv", "Shape", "central curvature").curv = 0
        obj.addProperty("App::PropertyFloat", "cc", "Shape", "conic constant").cc = 0
        
    def onChanged(self, obj, prop):
        proplist = ["curv", "cc"]
        if prop in proplist:
            if obj.shapetype == "Conic":
                obj.shapeclass.curvature.set_value(obj.curv)
                obj.shapeclass.conic.set_value(obj.cc)
Freecad novice, A Python enthusiast
User avatar
Chris_G
Veteran
Posts: 2594
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: After copyObject(), the object has no attribute

Post by Chris_G »

I suspect it is the same problem as document restoring :
- the new object is created
- the properties are added in alphabetical order
- a value is assigned to the new property, which triggers the onChanged method

So, when the curv and cc properties are created and initialized, the shapetype property is not yet created.

Does the error message appear twice ?
Does the error message appear when you open a document containing such object ?
xianyu
Posts: 66
Joined: Mon Jun 27, 2022 7:34 am

Re: After copyObject(), the object has no attribute

Post by xianyu »

Chris_G wrote: Fri Dec 09, 2022 6:28 am Does the error message appear twice ?
Hi, Chris_G
Yes, the error message appears twice.
Chris_G wrote: Fri Dec 09, 2022 6:28 am Does the error message appear when you open a document containing such object ?
I don't understand what this means
But if I save the file as ". FCStd" and open this file, the same error message will appear



Edit:
Also, this error will occur in copy
File "E:\gitfreecad\build\bin\lib\json\encoder.py", line 257, in iterencode
return _iterencode(o, 0)
File "E:\gitfreecad\build\bin\lib\json\encoder.py", line 179, in default
raise TypeError(f'Object of type {o.__class__.__name__} '
<class 'TypeError'>: Object of type FloatOptimizableVariable is not JSON serializable
Freecad novice, A Python enthusiast
User avatar
Chris_G
Veteran
Posts: 2594
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: After copyObject(), the object has no attribute

Post by Chris_G »

xianyu wrote: Fri Dec 09, 2022 6:45 am Hi, Chris_G
Yes, the error message appears twice.
...
I don't understand what this means
But if I save the file as ". FCStd" and open this file, the same error message will appear
Then you can disable onChanged while the object is being restored with :

Code: Select all

def onChanged( self, obj, prop):
    if "Restore" in obj.State:
        return
    ...
xianyu wrote: Fri Dec 09, 2022 6:45 am Edit:
Also, this error will occur in copy :
<class 'TypeError'>: Object of type FloatOptimizableVariable is not JSON serializable
This means that FC is not able to save the FloatOptimizableVariable object.
So you need to handle the save / restore of this object by yourself with :

Code: Select all

def __getstate__(self):
    # create and return a dict that contains all the data needed to create the FloatOptimizableVariable object

def __setstate__(self, state):
    # create the FloatOptimizableVariable object with the dict "state"
    self.FloatOptimizableVariable = object built from state data
    return
xianyu
Posts: 66
Joined: Mon Jun 27, 2022 7:34 am

Re: After copyObject(), the object has no attribute

Post by xianyu »

Chris_G wrote: Fri Dec 09, 2022 8:34 am ...
Thank you very much. It worked.Solved a big problem for me :D
Freecad novice, A Python enthusiast
xianyu
Posts: 66
Joined: Mon Jun 27, 2022 7:34 am

Re: After copyObject(), the object has no attribute

Post by xianyu »

I found that this error also occurs for some "external" custom attributes. How can I solve this problem?
Were these "external" custom properties not successfully copied?

Code: Select all

#example
class FrontSurface:
    def __init__(self, shapedata, aperturedata, lc):

        doc = FreeCAD.ActiveDocument
        obj= doc.addObject("Part::FeaturePython", "FrontSurface")
        obj.addProperty("App::PropertyPythonObject", "shapeclass", "Shape", "").shapeclass = shapedata
        obj.addProperty("App::PropertyPythonObject", "apertureclass", "Aperture", "").apertureclass = aperturedata
        obj.addProperty("App::PropertyLink", "LocalCoordinatesLink", "Coordinates", "local coordinate system").LocalCoordinatesLink = lc
Freecad novice, A Python enthusiast
User avatar
Chris_G
Veteran
Posts: 2594
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: After copyObject(), the object has no attribute

Post by Chris_G »

I suppose the 3rd property LocalCoordinatesLink is correctly handled by FreeCAD.
For the 2 other, shapeclass and apertureclass, I think you need to make the python objects JSON serializable.
Maybe this can help :
https://pynative.com/make-python-class- ... ializable/
User avatar
Roy_043
Veteran
Posts: 8539
Joined: Thu Dec 27, 2018 12:28 pm

Re: After copyObject(), the object has no attribute

Post by Roy_043 »

Chris_G wrote: Fri Dec 09, 2022 8:34 am Then you can disable onChanged while the object is being restored with :

Code: Select all

def onChanged( self, obj, prop):
    if "Restore" in obj.State:
        return
    ...
Thanks. Is there something similar for ViewObjects?
User avatar
Chris_G
Veteran
Posts: 2594
Joined: Tue Dec 31, 2013 4:10 pm
Location: France
Contact:

Re: After copyObject(), the object has no attribute

Post by Chris_G »

I am afraid no :

Code: Select all

AttributeError: 'Gui.ViewProviderDocumentObject' object has no attribute 'State'
User avatar
Roy_043
Veteran
Posts: 8539
Joined: Thu Dec 27, 2018 12:28 pm

Re: After copyObject(), the object has no attribute

Post by Roy_043 »

Thanks again. In the Draft code we have situations where we have to check for the presence of multiple view properties before we can do something in onChanged. A State property could maybe help in such cases.
Post Reply