Correct use of PropertyLinkSub - 'NoneType' object is not subscriptable

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
Aleks
Posts: 309
Joined: Sun Mar 08, 2020 5:27 pm
Location: Bonn, Germany
Contact:

Correct use of PropertyLinkSub - 'NoneType' object is not subscriptable

Post by Aleks »

I have created a FeaturePython object and attached a vertex subobj to it with PropertyLinkSub

I get the following error at object creation, but not on object changes.

Code: Select all

15:13:42  Traceback (most recent call last):
  File "C:/Users/Aleksander/AppData/Roaming/FreeCAD/Macro\uselessbox.py", line 27, in execute
    link_sub = obj.LinkSub[0]
<class 'TypeError'>: 'NoneType' object is not subscriptable
This is the object code:

Code: Select all

class UselessBox():

    def __init__(self, obj):
        """
        Default constructor
        """

        self.Type = 'box'

        obj.Proxy = self

        obj.addProperty('App::PropertyString', 'Description', 'Base', 'Box description').Description = "Just a simple box"
        obj.addProperty('App::PropertyLength', 'Length', 'Dimensions', 'Box length').Length = 10.0
        obj.addProperty('App::PropertyLength', 'Width', 'Dimensions', 'Box width').Width = 5.0
        obj.addProperty('App::PropertyLength', 'Height', 'Dimensions', 'Box height').Height = 10.0
        obj.addProperty("App::PropertyLinkSub", "LinkSub", "Subsection", "Description for tooltip").LinkSub = None

    def execute(self, obj):
        """
        Called on document recompute
        """
        # get the parent document object containing the subobject
        link_sub = obj.LinkSub[0]
        # get the list of sub object names from the LinkSub Property
        sub_obj_name_list = obj.LinkSub[1]
        # get the first name in the sub object name list
        sub_obj_name = sub_obj_name_list[0]
        # get the actual sub object by its name
        vertex = link_sub.getSubObject(sub_obj_name)

        vtx_vector = App.Vector(vertex.X - (obj.Length.Value * 0.5), vertex.Y  - (obj.Width.Value * 0.5), vertex.Z  - (obj.Height.Value * 0.5))

        obj.Shape = Part.makeBox(obj.Length, obj.Width, obj.Height, vtx_vector)


def create():
    """
    Object creation method
    """

    obj = App.ActiveDocument.addObject('Part::FeaturePython', 'UselessBox')

    UselessBox(obj)

    obj.ViewObject.Proxy = 0 # just set it to something different from None (this assignment is needed to run an internal notification)

    App.ActiveDocument.recompute()

    return obj
FreeCAD als Maschinenbauer in die Konstruktion und Fertigung integrieren. Schulung buchen: www.alsado.de/freecad-schulungen
User avatar
Aleks
Posts: 309
Joined: Sun Mar 08, 2020 5:27 pm
Location: Bonn, Germany
Contact:

Re: Correct use of PropertyLinkSub - 'NoneType' object is not subscriptable

Post by Aleks »

I suspect its because of this line, when the PropertyLinkSub gets assigned None. The LinkSub property gets assigned a real subobj shape later on.:

Code: Select all

obj.addProperty("App::PropertyLinkSub", "LinkSub", "Subsection", "Description for tooltip").LinkSub = None
But I dont know what to do, so this error does not come up.
FreeCAD als Maschinenbauer in die Konstruktion und Fertigung integrieren. Schulung buchen: www.alsado.de/freecad-schulungen
User avatar
Aleks
Posts: 309
Joined: Sun Mar 08, 2020 5:27 pm
Location: Bonn, Germany
Contact:

Re: Correct use of PropertyLinkSub - 'NoneType' object is not subscriptable

Post by Aleks »

Nevermind, I just passed the values to the custom obj class on object creation.

Code: Select all

class UselessBox():

    def __init__(self, obj, sub_parent_obj, sub_elem_name):
        """
        Default constructor
        """

        self.Type = 'box'

        obj.Proxy = self

        obj.addProperty('App::PropertyString', 'Description', 'Base', 'Box description').Description = "Just a simple box"
        obj.addProperty('App::PropertyLength', 'Length', 'Dimensions', 'Box length').Length = 10.0
        obj.addProperty('App::PropertyLength', 'Width', 'Dimensions', 'Box width').Width = 5.0
        obj.addProperty('App::PropertyLength', 'Height', 'Dimensions', 'Box height').Height = 10.0
        obj.addProperty("App::PropertyLinkSub", "LinkSub", "Subsection", "Description for tooltip").LinkSub = [sub_parent_obj, sub_elem_name]
FreeCAD als Maschinenbauer in die Konstruktion und Fertigung integrieren. Schulung buchen: www.alsado.de/freecad-schulungen
warnerjonn
Posts: 2
Joined: Thu Jun 16, 2022 6:03 am

Re: Correct use of PropertyLinkSub - 'NoneType' object is not subscriptable

Post by warnerjonn »

Aleks wrote: Sun May 15, 2022 1:34 pm <class 'TypeError'>: 'NoneType' object is not subscriptable
The error is self-explanatory. You are trying to subscript an object which you think is a list or dict, but actually is None (i.e: the object has no value). This means that you tried to do:

None[something]

Here you attempted to index an object that doesn’t have that functionality. You might have noticed that the method sort() that only modify the list have no return value printed – they return the default None. This is a design principle for all mutable data structures in Python.

This ‘NoneType’ object is not subscriptable is the one thrown by python when you use the square bracket notation object[key] where an object doesn’t define the getitem method.
User avatar
onekk
Veteran
Posts: 6144
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Correct use of PropertyLinkSub - 'NoneType' object is not subscriptable

Post by onekk »

Aleks wrote: Sun May 15, 2022 1:34 pm

Code: Select all

link_sub = obj.LinkSub[0]

You are assuming that a:

Code: Select all

obj.LinkSub
property exist, that is a list and that is as at least one element.

But sadly when the error is raised:

Code: Select all

obj.LinkSub


is not existing so ti have a NoneType.

probably chceking if:

Code: Select all

obj.LinkSub
is set or maybe setting it to an empty list (if applicable) would do the job.

Such error are very hard to catch when you are coding, as you usually test them "knowing what to do" so probably if you assign a proper value no error is raised.

Sadly these type of errors are usually found by the "end user" after the whole code is perfectly tested and is "running smoothly" :oops:.

I usually assign None only to flags value or usually assign them to False directly.

If the value is a list itvery easy to check it with:

Code: Select all

if len(something) > 0
	do somthing
else:
	 # it depends on the context, possibly something like:
	 return
	 exit
	 break
	 something = [""] # an empty value
	 # raise an error
	 # print a "wrong value message"

Hope it helps.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
Post Reply