Posts Tagged ‘ variable

Casting variable data from Python to Maya

I’ve recently ran across a nasty… bug, in the Maya-Python integration.  It appears, that if you have a Python module return a list, Maya will convert it to an array. That’s as expected.  However, if the Python list is empty, Maya converts it to a string with two brackets inside of it: “[]”, rather than converting it to an empty array.

I should note, as an update, that this initial presumption (that this is a ‘bug’) is wrong:  Maya variables are always typed (string $foo = “word”;), while Python’s aren’t, they’re just pointers (foo = “word”).  Maya has to auto-detect what type of data (string, float, etc) exists in the passed-in Python object and make a determination for what the conversion should be.  If it just gets an ’empty list’, it really has no idea what type of Maya array (float, string, int, vector) it should be.

Obviously, this can cause some real headaches if you’re trying to capture expected data from Python in Maya.

I found a fix, that I’m… not…. very… happy with.  Explained below the example.

Example:  First, a Python module that will return different types of data, based on the passed in arg:

# Python code
def variableReturn(varType):
    if varType == "str":
        return "string"
    if varType == "listSingle":
        return ["value1"]
    if varType == "listMult":
        return ["value1", "value2"]
    if varType == "listNone":
        return [None]
    if varType == "listEmpty":
        return []

Now, some mel code to capture that data.  I’ve already setup the Maya variable types to be the correct ones based on what the Python module spits out… but you can see that one of them is clearly wrong:

// Mel code:
string $str = python("variableReturn('str')");
string $lstSingle[] = python("variableReturn('listSingle')");
string $listMult[] = python("variableReturn('listMult')");
string $listNone[] = python("variableReturn('listNone')");
string $listEmpty = python("variableReturn('listEmpty')");

print ("Type of 'str' : " + `whatIs "$str"` + "n");
print ("Type of 'listSingle' : " + `whatIs "$lstSingle"` + "n");
print ("Type or 'listMult' : " + `whatIs "$listMult"` + "n");
print ("Type of 'listNone' : " + `whatIs "$listNone"` +"n");
print ("Type of 'listEmpty' : " + `whatIs "$listEmpty"` + "  <--- aaaagh!!!n");

Prints:

Type of 'str' : string variable
Type of 'listSingle' : string[] variable
Type or 'listMult' : string[] variable
Type of 'listNone' : string[] variable
Type of 'listEmpty' : string variable  <--- aaaagh!!!

As you can see, the workaround is to have your Python code return a list with a ‘None’ object in it:

# Python
return [None]

Presumably, you’d do some sort of test before hand in your Python code to know to return things this way:

# Python
if len(myVal) == 0:
    myVal = [None]
return myVal

Of course, in Maya you’d then have to detect if the first item of the list was empty, if it’s size was 1:

// mel
string $result[] = python("myPyFunc()");
if(size($result) && $result[0] != ""){
    // start doing something...
}

Update #1:

After reading through the Maya docs on Python integration, this may make a bit of sense:

Python Return Value MEL Conversion
string string
unicode string
int int
float float
list containing numbers, including at least one float float[]
list containing only integers or longs int[]
list containing a non-number string[]
anything else string

I’m guessing an ’empty list’ falls into the ‘anything else’ category, and thus converts it to a “string”. Even though our above example returns an empty list, and we presume to have string data, it could actually contain float data, int data, etc. But how is Maya to know this if all it gets is an un-typed empty list? It doesn’t, so it turns it into a string.

Update #2:

Looks like (based on comment below) later version of Maya have fixed this issue:  The docs (in 2010) now append this new information:

| empty Python list | empty string array (string $array[]) |