Hello everyone,

I've found an ugly bug in maya api python bindings and want to share with you. Every method which returns an api object, and can raise exception will leak objects on exception. I've tried following script with maya 2012 on linux and 2014 on mac, both leaked. Objects you get from gc.get_objects() are top level objects not living inside any other, they have non zero reference
count and are uncollectable.
It seems that maya swig bindings raise RuntimeError on any non success MStatus, without
Py_DECREF on temporary reference.

In case of MFnDependencyNode findPlug() and attribute() you can avoid leaks by first checking depFn.hasAttribute('foo') first. But there are methods which have no alternative. For example MFnAttribute provides only one way to check if attribute is child of some other, parent() which either returns MObject, or raises exception. You can avoid it also by converting
attribute to plug and using isChild() method.

It does not leak (or gc does not know, it does not track primitive types, like string) on methods
returning primitive types like MPlug.asString().

Try to avoid methods returning wrapped api objects which can raise exceptions.

You can check it with following script.
import maya.OpenMaya as om
import gc

def count_leaked(typ):
    return len ([x for x in gc.get_objects() if isinstance(x, typ)])


slist = om.MSelectionList()
slist.add('persp')
obj = om.MObject()
slist.getDependNode(0, obj)
depFn = om.MFnDependencyNode(obj)
def leak_plug():
    try:
        plug = depFn.findPlug('foo')
    except RuntimeError:
        pass

prev_cnt = count_leaked(om.MPlug)
print prev_cnt
for i in xrange(1000):
    leak_plug()

new_cnt = count_leaked(om.MPlug)
print prev_cnt, new_cnt
#also works with MObject
def leak_mobject():
    try:
        obj = depFn.attribute('foo')
    except RuntimeError:
        pass

prev_cnt = count_leaked(om.MObject)
for i in xrange(1000):
    leak_mobject()
new_cnt = count_leaked(om.MObject)
print  prev_cnt, new_cnt

Leonid.

--
You received this message because you are subscribed to the Google Groups "Python 
Programming for Autodesk Maya" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to