How does Maya populate its maya.cmds package?

From over on my Mel Wiki:

When using Python in Maya, to access the bulk of the mel commands via Python, you import the mel.cmds package, usually into a namespace, like so:

import maya.cmds as mc
print mc.ls()

But if you browse to that package on disk, you’ll find it empty, only containing an __init__.py file (required for package creation):

C:\Program Files\Autodesk\Maya<VERSION>\Python\Lib\site-packages\maya\cmds

So how are all the ‘mel commands’ added to that package for execution in Python?

There is a Maya startup Python module living here, that works the magic of populating that package:

C:\Program Files\Autodesk\Maya<VERSION>\Python\Lib\site-packages\maya\app\commands.py

It inspects a file called commandList (no extension, but it’s text) living here:

C:\Program Files\Autodesk\Maya<VERSION>\bin\commandList

You can open that file in a text editor, and what you’ll find are two columns: One with a ‘mel’ command name, and one with a .dll where that command ‘lives’. Those .dll’s live in the same dir as the commandList file. Here’s a sample:

TanimLayer AnimSlice.dll
about Shared.dll
addAttr Shared.dll
addDynamic DynSlice.dll
addPP DynSlice.dll
affectedNet Shared.dll
affects Shared.dll
agFormatIn Translators.dll
agFormatOut Translators.dll
aimConstraint AnimSlice.dll
air DynSlice.dll
aliasAttr Shared.dll
align Shared.dll

What commands.py does is parse the commandList file and append each command (via a Python command wrapper function) to maya.cmd‘s ‘__dict__‘ attribute (maya.cmds.__dict__), which is the lookup table users access when calling their favorite mel command via Python (like maya.cmds.ls())  It also passes the name of the .dll to the command wrapper function, so when the user executes the given command, it first loads the parental .dll.

Crack open commands.py for the nitty-gritty details.

If you want to see the end result of all this hard work, you can run this code in Maya. But it prints a *lot* of stuff:

import maya.cmds as mc

for k in sorted(mc.__dict__.keys()):
    print k, mc.__dict__[k]
Pygame Window Info
Updated Pygame Tablet Pressure
  • Trackback are closed
  • Comments (6)
    • Paul
    • September 13th, 2010 11:11am

    I have to disagree with commands.py. You can remove that python file completly with no affect. In fact other then the __init__.py files maya only needs python.py in site-packagesmayaapp from the entire pythonlib directory

  1. Technically you are correct, but Maya is still running either commands.pyc or commands.pyo in its absence. Did you also try removing them? They’re all interrelated. In actuality there’s a good chance Python isn’t even looking to commands.py (since it doesn’t change once installed on your computer) for execution: commands.pyc (bytecode compiled) or commands.pyo (optimized bytecode) would be the one Python actually accesses. Try removing those other modules: When I do, while I can still ‘import maya.cmds’ in Maya, any of the commands I try to execute after that have no effect:

    import maya.cmds as mc
    print mc.ls()
    # nothing, usually a big list…

    So while I didn’t mention commands.pyc or commands.pyo in the above post (since they’re a bit more ‘behind the scenes’ of how Python works), I figured the generic usage of commands.py would be sufficient.

    • Paul
    • September 13th, 2010 12:07pm

    I did test it with .pyc and .pyo files removed with the same results. Because we are removing commands.py code down the line basic.py and gui.py no longer get executed so the stdout no longer runs through maya. You should still be getting output in maya ‘output window’. Also any executable commands like polySphere are visibly working as well.

  2. Interesting: I hadn’t checked the command window, and sure enough, the data does show up in there. So ok, I’ll agree with you now 😉

    So this brings up two questions:
    #1 Why are you monkeying with this start-up stuff? Just a general query 😉
    #2 How DOES maya.cmds get populated then…..?

    Just when you thought you had something figured out…

    • Paul
    • September 13th, 2010 12:25pm

    Just trying to figure it out myself. Have no solution yet.

    • Anthony
    • November 7th, 2012 5:34am

    Hmph, it made me rather curious after reading the post – had a bit of a play and not really much to report aside from the fact that maya.cmds is a fat empty module, but then everything after that (i.e. maya.cmds.polySphere) is a builtin of the module object.. which kinda suggests that there’s some hardlinking going back in maya-land.

    Actually.. more detail, just had a brainwave. No extra use, but more edification:

    Fire up mayapy.exe (i’m on windows right now)

    >>> import maya.cmds
    # works ok
    >>> maya.cmds.polySphere()
    # no go.

    >>>import maya.standalone
    >>>maya.standalone.initialize()
    # startup msgs removed
    >>>maya.cmds.polySphere()
    [u’pSphere’1,u’polySphere1′]

    and of course, maya.standalone is inside the \site-packages\maya\standalone.pyd file which i can’t really crack open, where all the magic appears to occur. The earliest i can patch in would be in maya\app\startup\basic.py at which point, it’s already done with maya.cmds. I suspect the processCommandList() call is just going through and doing proper housekeeping (or patching in esoteric modules which aren’t already loaded.. I’ll bet polySpheres are part of a core set..)

    Ah well. Fun exercise in hunting round though 😀

Comment are closed.