Home Website Youtube GitHub

I found a bug when trying to rename a component that has no children

Correct me if I’m wrong but I think I found a little bug.

  • mGear version: 4.0.9, Maya version: 2022, OSX: Windows 10

For the sake of learning how to create custom components, I created a completely empty component that serves no purpose but just to be able to be built without any errors. And it works properly, except when I’m trying to edit its name. This is the error:

# Traceback (most recent call last):
#   File "P:\Perforcelocal\[ws00]\PRJ_05\GAME\Tools\MayaTools\external\mGear\scripts\mgear\shifter\guide.py", line 1145, in updateComponentName
#     guide.updateProperties(self.root, newName, newSide, newIndex)
#   File "P:\Perforcelocal\[ws00]\PRJ_05\GAME\Tools\MayaTools\external\mGear\scripts\mgear\shifter\guide.py", line 1005, in updateProperties
#     comp_guide.rename(root, newName, newSide, newIndex)
#   File "P:\Perforcelocal\[ws00]\PRJ_05\GAME\Tools\MayaTools\external\mGear\scripts\mgear\shifter\component\guide.py", line 552, in rename
#     self.parent, oldName, oldSideIndex)
#   File "P:\Perforcelocal\[ws00]\PRJ_05\GAME\Tools\MayaTools\external\mGear\scripts\mgear\core\dag.py", line 250, in findComponentChildren3
#     fullPath=True, type="transform"):
# TypeError: 'NoneType' object is not iterable

Looking at mGear’s code, this is the line that is triggering this error:

for item in cmds.listRelatives(node.name(), allDescendents=True, fullPath=True, type="transform"):

When testing the cmds.listRelatives() function myself I realize that when an object has no children, it doesn’t return an empty list ( [ ] ) , but a null object ( None )
And that’s what is triggering the error.

You can reproduce this bug by creating a control_01 component, deleting its only child (sizeRef), and trying to rename the component in the settings window.

This error will trigger too when trying to change the component’s side or index

Maybe it’s not an important bug because there is no reason to use an empty component that has no purpose, but I wanted to be sure that it is a bug in the mGear code and that I’m not missing something when trying to create custom components.

1 Like

Hi,

Maybe you can check if the list is valid before proceeding to your for loop?

myList = cmds.listRelatives(node.name(), allDescendents=True, fullPath=True, type="transform")
if myList: #this will skip if your list returns None
    for item in myList:
        #do whatever
2 Likes

Yep you’ve found a bug, thanks! That should be fixed.

(This is a known inconsistent implementation on Autodesk’s part.)

The PyMEL version correctly returns an empty list. @rafaelmelo makes a good suggestion. A third workaround is the “or” keyword, which falls back to the next value if None is returned:

for item in cmds.listRelatives(node.name(), allDescendents=True, fullPath=True, type="transform") or []:
    item

(As an unsolicited coding lesson, if your iterator wasn’t a list, but was a proper generator-object / iterator, casting it as myList first would potentially be memory-intensive if the list was huge. Iterators don’t store their entire iteration in memory. They go one-at-at-time. So using “or” would keep it as an iterator/generator, or fall back to the next level if the iterator was empty. In this case it is already a list, so it doesn’t really matter.)

3 Likes

I’m glad it’s easily solved, thank you both! Every piece of information is welcome!

I can never get enough from you, @chrislesage! You can consider those coding lessons to be solicited everytime. :slight_smile:
Cheers!

1 Like

Thanks for the head up! I have taken @chrislesage advice and fixed it with “or” :slight_smile:

2 Likes