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.