Commands in pymel

When you execute “pm.some_command()”, how is it executed?, where is the definition of “some_command”? Trying to dig through the pymel code to see how stuff works, but either I’m missing files, don’t know how to search, or… this whole system is beyond me.

Specifically, trying to look up how polySeperate works (in any language).

According to (one version of) the docs, it is derived from the MEL counterpart:

http://pymel.googlecode.com/svn/docs-epydoc/pymel.core.nodetypes.PolySeparate-class.html

At the bottom -> “Derived from mel command maya.cmds.polySeparate”. PyMEL is usually pretty good at indicating what any particular call inherits from and what it is really calling under the hood.

The actual MEL command is written in C/C++, and Autodesk doesn’t typically make this code public. If you have a maintenance contract with them, they are pretty good at describing how many of these functions work in general terms.

I don’t have a direct answer for you, but you’re welcome to accompany me on this magical voyage of discovery:

First of all, you can take a look at the module itself to get its path:

import pymel.core as pm
print pm

This shows you that both the pymel and maya modules are located in Maya/Python/Lib/site-packages. Looking at the one command in particular:

help(pm.polySeparate)

…you can see that pymel’s polySeparate is contained under pymel.core.modeling. If you open up that file, you’ll find that there’s no definition listed for polySeparate. Since nothing by that name is imported or defined, the only thing that could bring polySeparate into the modeling namespace is that curious line at the bottom.

That line calls the createFunctions function in the pymel.internal.factories module, passing in the value of name (“pymel.core.modeling”). createFunctions uses this name to look up that module, wraps the original maya command in a pymel command by calling an incredibly hairy and horrific-looking function called functionFactory, and then adds the newly created function as an attribute of the original module. pymel.core (in init.py) then imports everything from modeling into its namespace for convenient access.

Of course, that all has to do with the black magic that pymel performs in order to initialize itself when you import it. It doesn’t get you any closer to the details of your specific command.

When you call pymel.core.polySeparate, it calls maya.cmds.polySeparate. If you look at maya.cmds on disk, you’ll see that it’s a dummy module: it’s entirely blank. That must mean that the module is populated at runtime with the appropriate Python function definitions for maya.cmds. I don’t know exactly how this happens (or whether that knowledge is publicly available), but a couple of things are certain:

[ol]
[li]When Maya initializes its Python interpreter (or when you import maya.cmds; I’m not sure which), it generates Python function definitions procedurally from its MEL commands. Similar to how pymel.core wraps maya.cmds, maya.cmds wraps MEL.
[/li][li]When you call pymel.core.polySeparate, and it calls maya.cmds.polySeparate, the maya.cmds version most assuredly calls the corresponding MEL command. As Mr. Tribble has pointed out, the implementations of these commands are not available.
[/li][/ol]
This happens a lot when you’re working with closed-source applications. The best you can do is experiment with the command (i.e., poke it with a stick), read the documentation, or ask the people who maintain the original software very nicely.

Wowzers, thanks for that! Makes a lot of sense.

If there’s one thing that obvious here, it’s that we should all get back to coding in MEL.

It’s called metaprogramming, or a function factory depending on how you approach it.
The TL,DR of awforsythe’s pretty comprehensiver post is:

*When Maya is initialized, or plugins are loaded, each internal maya module and plugin registers a set of MEL commands.
*When maya.cmds is initialized, it creates a list of each of these same commands.

*PyMel is a strange beast in that it encapsulates most if not all MEL procedures, including the convenience functions that aren’t available to cmds. It also has a lot of custom code written, but essentially all it’s doing is:
>>You call a method or function
>>It checks if this is okay to create, if it isn’t it raises an error, if it is, then it initializes the function and returns it back to you.

This is a pretty good read on how it works in a general sense.