pymel.tools.mel2py

Convert mel scripts into python scripts.

Mel To Python Translator

Known Limitations

array index assignment

In mel, you can directly assign the value of any element in an array, and all intermediate elements will be automatically filled. This is not the case in python: if the list index is out of range an IndexError will be raised. I’ve added fixes for several common array assignment conventions:

append new element

MEL

Python

>>> strArray = []                
>>> strArray.append("foo")       
assignment relative to end of array

MEL

Python

>>> strArray[-3] = "foo"        

However, since the translator does not track values of variables, it does not know if any given index is out of range or not. so, the following would raise a ‘list assignment index out of range’ error when converted to python and would need to be manually fixed:

for(init; condition; update)

the closest equivalent to this in python is something akin to:

>>> for i in range(start, end):    

in order for this type of for loop to be translated into a python for loop it must meet several requirements:

  1. the initialization, condition, and update expressions must not be empty.

    not translatable:

  2. there can be only one conditional expression.

    not translatable:

  3. the variable which is being updated and tested in the condition (aka, the iterator) must exist alone on one

    side of the conditional expression. this one is easy enough to fix, just do some algebra:

    not translatable:

    translatable:

  4. the iterator can appear only once in the update expression:

    not translatable:

if these conditions are not met, the for loop will be converted into a while loop:

>>> i=0
>>> while 1:                        
...     if not ( (i - 2)<10 ):
...         break
...     print i
...     i+=1

Inconveniences

Switch Statements

Alas, switch statements are not supported by python. the translator will convert them into an if/elif/else statement.

Global Variables

Global variables are not shared between mel and python. two functions have been added to pymel for this purpose: getMelGlobal and setMelGlobal. by default, the translator will convert mel global variables into python global variables AND intialize them to the value of their corresponding mel global variable using getMelGlobal(). if your python global variable does not need to be shared with other mel scripts, you can remove the get- and setMelGlobals lines (for how to filter global variables, see below). however, if it does need to be shared, it is very important that you manually add setMelGlobal() to update the variable in the mel environment before calling any mel procedures that will use the global variable.

In order to hone the accuracy of the translation of global variables, you will find two dictionary parameters below – global_var_include_regex and global_var_exclude_regex – which you can use to set a regular expression string to tell the translator which global variables to share with the mel environment (i.e. which will use the get and set methods described above) and which to not. for instance, in my case, it is desirable for all of maya’s global variables to be initialized from their mel value but for our in-house variables not to be, since the latter are often used to pass values within a single script. see below for the actual regular expressions used to accomplish this.

Comments

Rules on where comments may be placed is more strict in python, so expect your comments to be shifted around a bit after translation.

Formatting

Much of the formatting of your original script will be lost. I apologize for this, but python is much more strict about formatting than mel, so the conversion is infinitely simpler when the formatting is largely discarded and reconstructed based on pythonic rules.

Solutions and Caveats

catch and catchQuiet

There is no direct equivalent in python to the catch and catchQuiet command and it does not exist in maya.cmds so i wrote two python commands of the same name and put them into pymel. these are provided primarily for compatibility with automatically translated scripts. try/except statements should be used instead of catch or catchQuiet if coding from scratch.

for( $elem in $list )

This variety of for loop has a direct syntactical equivalent in python. the only catch here is that maya.cmds functions which are supposed to return lists, return None when there are no matches. life would be much simpler if they returned empty lists instead. the solution currently lies in pymel, where i have begun correcting all of these command to return proper results. i’ve started with the obvious ones, but there are many more that i need to fix. you’ll know you hit the problem when you get this error: ‘TypeError: iteration over non-sequence’. just email me with commands that are giving you problems and i’ll fix them as quickly as i can.

Functions

fileOnMelPath Return True if this file is on the mel path.
findMelOnlyCommands Using maya’s documentation, find commands which were not ported to python.
mel2py Batch convert an entire directory
mel2pyStr convert a string representing mel code into a string representing python code
melInfo Get information about procedures in a mel file.
resolvePath if passed a directory, get all mel files in the directory

Exceptions

LexError(message, s)