Getting attribute using Maya API in python

Heya,
I’ve been banging my head against the desk trying to check the existence of a custom attribute on a transform node, using API python calls.
Heres what i got so far, but it gives me an Unexpected Internal Failure


dagIt = maya.OpenMaya.MItDag(maya.OpenMaya.MItDag.kDepthFirst, maya.OpenMaya.MFn.kTransform)
	
while not dagIt.isDone():
		
	object = maya.OpenMaya.MObject
	object = dagIt.currentItem()
			
	depNode = maya.OpenMaya.MFnDependencyNode(object)
	print depNode.attributeCount()
	depNode.hasAttribute('myAttributeName')
		
	dagIt.next()

Actually, I’m working with the code now and the error is only thrown when the attribute doesn’t exist. Let me see what I can dig up.

That almost feels like a bug in the maya python API. It doesn’t bug out when an attribute that is default on the objects (like ‘tx’), but custom attrs don’t take. findPlug throws an incompatibility error and just .attribute throws the same error as findAttribute.

Very odd.

Weird eh… Cheers for checking that out!
I basically just need the fastest possible way of checking the existence of a custom attribute (not even the value) on about 200 - 500 transforms.

Commands like ls, objExists and attributeQuery are too slow once you run them that many times

Hmmm… it looks like it’s failing because it cannot find the attribute on a whole bunch of internal nodes that MFnDependencyNode discovers (UniversalManip, CubeCompass, groundPlane_transform etc). If you insert a try and except it should work as it will just continue iterating if it stumbles on a node that doesn’t have the attribute.


import maya.OpenMaya as OpenMaya

dagIt = OpenMaya.MItDag(OpenMaya.MItDag.kDepthFirst, OpenMaya.MFn.kTransform)

while not dagIt.isDone():

	object = OpenMaya.MObject
	object = dagIt.currentItem()

	depNode = OpenMaya.MFnDependencyNode(object)
	try:
		print depNode.attributeCount(),depNode.name()
		depNode.hasAttribute('myAttribute')
	except:
		pass

	dagIt.next()

I was under the impression that the goal of the tool was to discover that very thing. Does it have the attribute or doesn’t it. If it does, return True, if it doesn’t return False. So if it doesn’t just return False, not error out.

The Try Except is definitely a solid enough workaround, but should this be considered a bug?

Hmmm… in a sense you could consider it a bug however it’s giving an expected result in the sense that you’re iterating over every DependencyNode inside of Maya and asking if it has the attribute. If the object has the attribute then it will pass but otherwise it will fail without any direction really given to it.

I’m by no means a Python guru or even an API expert so if you guys feel this is indeed a bug from a user perspective and have a suggestion on the expected result you want to see let me know and I’ll go to our devs about it :):

This should work (thanks to Seth for edumacating me on the if part)


import maya.OpenMaya as OpenMaya

dagIt = OpenMaya.MItDag(OpenMaya.MItDag.kDepthFirst, OpenMaya.MFn.kTransform)

while not dagIt.isDone():

	object = OpenMaya.MObject
	object = dagIt.currentItem()

	depNode = OpenMaya.MFnDependencyNode(object)
	depNodeAttr = depNode.hasAttribute('myAttribute')
	if depNodeAttr:
		print depNode.name(),"has attribute"

	dagIt.next()

Running your code Shawn, my error is this:

Error: (kFailure): Unexpected Internal Failure

Traceback (most recent call last):

hasAttr = depNode.hasAttribute(‘myAttribute’)

File “D:\buildforge\Maya_2011_Win64_Build\build\wrk\optim\runTime\Python\Lib\site-packages\maya\OpenMaya.py”, line 3170, in hasAttribute

RuntimeError: (kFailure): Unexpected Internal Failure

However, you’re right that the try/except does essentially solve the problem in my case. I’d be curious to know the “right” way of accessing a custom attribute (even its value) on an object though.

Cheers for your help!

Hmm… that’s not good you’re getting that error. Let me take another look on my end to see what’s going on there.

hasAttribute is technically the right way to my knowledge it may just be that’s a bit too strict and verbose in how it tries to find the attribute (i.e. return a true if found and a false if not rather than suffering an internal failure).

So just to follow up I’ve logged this one on my end and spoken with a few of our developers about how one could possibly clean this up to make it more Python friendly. You guys can PM me if you like and I’ll give you the bug #, not sure when or if it will be addressed but the if/try/except is the current workaround to avoid the internal failure being returned.

Thanks Shawn, appreciate it greatly!