LumaPictures / pymel

Python in Maya Done Right
Other
478 stars 130 forks source link

getAttr fails with multi-attributes if indices are not continuous from 0 #450

Open mlfecho opened 2 years ago

mlfecho commented 2 years ago

pymel's getAttr returns a list for multi-attributes. However, the behavior is a bit odd when the multi-attr indices are not continuous from 0. This can arise if someone pokes the trash-can icon in the attribute editor on any element but the last. getAttr always returns a list with the same number of elements as the multi-attr, but it assumes indices are 0 to n-1, leaving out the elements with index >= n, and filling in None for any missing elements. Also, the act of trying to read the non-existent element creates a new, empty element in its place.

I'm not exactly sure what the right answer is, since a list with discontinuous indices isn't a true list. But the current behavior seems not ideal. I'd lean towards either collapsing the existing elements into a true list (and hence with continuous indices), or returning a dictionary with the indices as keys.

(tested using Maya 2022, pymel 1.2.0, and Maya 2020, pymel 1.1.0) to repro:

import maya.cmds as cmds
import pymel.core as pm

pm.sphere(name='mySphere')
node = cmds.ls('mySphere')[0]
pm.addAttr(node, longName='multiAttr', type='string', multi=True)
pm.setAttr(node + '.multiAttr[0]', 'foo')
pm.setAttr(node + '.multiAttr[3]', 'bar')

# run this once, it returns ['foo', None], and creates an empty third element, multiAttr[1]
print(pm.getAttr(node + '.multiAttr'))

# run it again, and it returns ['foo', None, None], adding another empty element, multiAttr[2]
print(pm.getAttr(node + '.multiAttr'))

# run it again, and it returns ['foo', None, None, 'bar']
print(pm.getAttr(node + '.multiAttr'))