Python in Maya Done Right
=========================
PyMEL makes python scripting with Maya work the way it should.
Maya's command module is a direct translation of mel commands into python commands. The result is a very awkward and unpythonic syntax which does not take advantage of python's strengths -- particulary, a flexible, object-oriented design. PyMEL builds on the `maya.cmds` module by organizing its commands into a class hierarchy, and by customizing them to operate in a more succinct and intuitive way.
Project Goals
-------------
- Create an open-source python module for Maya that is intuitive to MEL users and python users alike
- Fix bugs and design limitations in Maya's python modues, maya.cmds and maya.mel
- Keep code concise and readable
- Add organization through class hierarchy and sub-modules
- Provide documentation accessible via html and the builtin `help() function
- Make it "just work"
Supported Maya Versions
-----------------------
PyMEL supports four major versions of Maya:
- 2022
- 2023
- 2024
- 2025
See the full [changelog](https://github.com/LumaPictures/pymel/blob/master/CHANGELOG.rst).
Production Proven
-----------------
Since its release in 2008, PyMEL has accumulated an impressive resume in both feature films and games, and is now bundled with every release of Maya.
Here's what Seth Gibson of Bungie Studios, makers of *Halo*, has to say:
> Having done production python code myself for many years, wrapping my head around Maya's native implementation took a little bit of time. With PyMel, I can think and write the python code and syntax I'm already used to, which speeds up my development time considerably. It's also going to help our other Technical Artists with their Python learning curve, since PyMEL's syntax is consistent with most other python packages. Kudos to the PyMel team for such a well thought out project!
BSD License
-----------
PyMEL is released under the BSD license, which is as open as open source gets. Your studio can freely use, contribute to, and modify this module with no strings attached.
Features
--------
### API Hybridization
PyMEL harnesses the API to create a name-independent representation of your object. This means that the annoying inconsistencies of string comparisons are over: no more worrying about short names versus long names, DAG paths, unique paths, instance paths... it's all handled intelligently for you. And what's more, if anything causes the name of your object to change it will automatically be reflected in your python object.
PyMEL node classes now include hundreds of new methods derived from the API, but with the same intuitive and unified design as before. With PyMEL you get the benefits of API speed and versatility without the advanced learning curve.
### Improved Batch / Standalone Support
Ever wonder why python scripts that work in the Maya UI or in Maya batch don't work in Maya's python interpreter? Here's a possible explanation: in both GUI and batch modes Maya sources all of its lowest-level MEL scripts, like those that load user plugins, whereas mayapy and `maya.initialize` does not.
PyMEL ensures that Maya is properly initialized when used from Maya's python interpreter, which makes runtime environments more consistent and your scripts more portable, which adds up to fewer bugs.
### Tighter MEL Integration
Executing a MEL script with arguments can be an unsightly mess when done the default way:
**default**
```python
values = ['one', 'two', 'three', 'four']
maya.mel.eval('stringArrayRemoveDuplicates({"'+'","'.join(values)+'"})')
```
So PyMEL provides a handy interface which makes calling MEL procedures just like calling a python function:
**PyMEL**
```python
values = ['one', 'two', 'three', 'four']
pm.mel.stringArrayRemoveDuplicates(values)
```
Also, unlike `maya.mel.eval`, PyMEL will give you the specific MEL error message in a python traceback, along with line numbers:
```python
>>> mel.myScript('foo', [])
Traceback (most recent call last):
...
MelConversionError: Error occurred during execution of MEL script: line 2: Cannot convert data of type string[] to type float.
```
Also, getting and setting MEL global variables is as easy as working with a dictionary:
```python
print(pm.melGlobals['gMainFileMenu'])
pm.melGlobals['gGridDisplayGridLinesDefault'] = 2
```
### Powerful Classes
#### Nodes
```python
camTrans, cam = pm.camera() # create a new camera
cam.setFocalLength(100)
fov = cam.getHorizontalFieldOfView()
cam.dolly(-3)
cam.track(left=10)
cam.addBookmark('new')
```
#### Attributes
```python
s = pm.polySphere()[0]
if s.visibility.isKeyable() and not s.visibility.isLocked():
s.visibility.set(True)
s.visibility.lock()
print(s.visibility.type())
```
#### File paths
backup all mb files in the current scene's directory
```python
basedir = pm.sceneName().parent
backupDir = basedir / "backup" #slash op joins paths
if not backupDir.exists:
backupDir.mkdir()
for path in basedir.files('*.mb'):
print("backing up: ", path.name)
path.copy(backupDir / (path.namebase + ".old"))
```
#### Shape components and vectors/matrices
select all faces that point up in world space
```python
s = pm.polySphere()[0]
for face in s.faces:
if face.getNormal('world').y > 0.0:
pm.select(face, add=1)
```
#### optionVars dictionary
```python
if 'numbers' not in pm.optionVar:
pm.optionVar['numbers'] = [1, 24, 47]
pm.optionVar['numbers'].append(9)
numArray = pm.optionVar.pop('numbers')
```
Who is PyMEL for?
-----------------
### For the Novice
Object-oriented programming, like that provided by PyMEL, is more intuitive to learn because the functionality of an object is directly associated with the object itself.
For an artist starting to program in Maya, the first question you might ask is "what can I do with this node?" Using a procedural approach, like that offered by MEL or maya.cmds, you'll have to dig through the thousands of MEL commands looking for the one that you want. For a camera node, the `camera` MEL command is easy to find, but did you find `orbit`, `track`, `dolly`, and `tumble`, which also work on cameras? What about the API methods?
In PyMEL, all you have to do is type `help(nt.Camera)` in the python script editor to find out all the things a camera node can do, or just look up the Camera class in the PyMEL docs.
### For the MEL Scripter
When we say PyMEL is concise and easy to read, we mean it.
***MEL***
```mel
string $sel[] = `ls -sl`;
string $shapes[] = `listRelatives -s $sel[0]`;
string $conn[] = `listConnections -s 1 -d 0 $shapes[0]`;
setAttr ( $conn[0] + ".radius") 3;
```
***PyMEL***
```python
pm.selected()[0].getShape().inputs()[0].radius.set(3)
```
### For the Technical Director
For those looking to master python in a production environment, PyMEL is more than a module for Maya scripting, it is a repository of example python code -- a self-contained pipeline demonstrating advanced python concepts like function factories, metaclasses, and decorators, as well as essential production practices such as parsing, pickling, logging, and unit testing.
For those who are already masters of python and who naturally expect more out of a python package, PyMEL is for you, too. It was written for use in production by experienced programmers with a vision for how to add object-oriented design to Maya.
Code Comparison
---------------
**with Mel**
```mel
string $objs[] = `ls -type transform`;
for ($x in $objs) {
print (longNameOf($x)); print "\n";
// make and break some connections
connectAttr( $x + ".sx") ($x + ".sy");
connectAttr( $x + ".sx") ($x + ".sz");
// disconnect all connections to .sx
string $conn[] = `listConnections -s 0 -d 1 -p 1 ($x + ".sx")`;
for ($inputPlug in $conn)
disconnectAttr ($x + ".sx") $inputPlug;
// add and set a string array attribute with the history of this transform's shape
if ( !`attributeExists "newAt" $x`)
addAttr -ln newAt -dataType stringArray $x;
string $shape[] = `listRelatives -s $x`;
string $history[] = `listHistory $shape[0]`;
string $elements = "";
for ($elem in $history)
$elements += """ + $elem + "" ";
eval ("setAttr -type stringArray " + $x + ".newAt " + `size $history` + $elements);
print `getAttr ( $x + ".newAt" )`;
// get and set some attributes
setAttr ($x + ".rotate") 1 1 1;
float $trans[] = `getAttr ($x + ".translate")`;
float $scale[] = `getAttr ($x + ".scale")`;
$trans[0] *= $scale[0];
$trans[1] *= $scale[1];
$trans[2] *= $scale[2];
setAttr ($x + ".scale") $trans[0] $trans[1] $trans[2];
// call a mel procedure
myMelScript( `nodeType $x`, $trans );
}
```
**with default Python**
```python
import maya.cmds as cmds
objs = cmds.ls(type='transform')
# returns None when it finds no matches
if objs is not None:
for x in objs:
print(mm.eval('longNameOf("%s")' % x))
# make and break some connections
cmds.connectAttr('%s.sx' % x, '%s.sy' % x)
cmds.connectAttr('%s.sx' % x, '%s.sz' % x)
# disconnect all connections to .sx
conn = cmds.listConnections(x + ".sx", s=0, d=1, p=1)
# returns None when it finds no match:
if conn is not None:
for inputPlug in conn:
cmds.disconnectAttr(x + ".sx", inputPlug)
# add and set a string array attribute with the history of this transform's shape
if not mm.eval('attributeExists "newAt" "%s"' % x):
cmds.addAttr(x, ln='newAt', dataType='stringArray')
shape = cmds.listRelatives(x, s=1 )
if shape is not None:
history = cmds.listHistory( shape[0] )
else:
history = []
args = tuple(['%s.newAt' % x, len(history)] + history)
cmds.setAttr(*args, type='stringArray' )
# get and set some attributes
cmds.setAttr('%s.rotate' % x, 1, 1, 1)
scale = cmds.getAttr('%s.scale' % x)
# maya packs the previous result in a list for no apparent reason:
scale = scale[0]
# the tuple must be converted to a list for item assignment:
trans = list(cmds.getAttr('%s.translate' % x )[0])
trans[0] *= scale[0]
trans[1] *= scale[1]
trans[2] *= scale[2]
cmds.setAttr('%s.scale' % x, trans[0], trans[1], trans[2])
# call a mel procedure
mm.eval('myMelScript("%s",{%s,%s,%s})' % (cmds.nodeType(x), trans[0], trans[1], trans[2]))
```
**with Pymel**
```python
# safe to import into main namespace (but only recommended when scripting interactively)
from pymel import *
for x in ls(type='transform'):
# object oriented design
print(x.longName())
# make and break some connections
x.sx.connect(x.sy)
x.sx.connect(x.sz)
# disconnect all connections to .sx
x.sx.disconnect()
# add and set a string array attribute with the history of this transform's shape
x.setAttr('newAt', x.getShape().history(), force=1)
# get and set some attributes
x.rotate.set([1, 1, 1])
trans = x.translate.get()
# vector math:
trans *= x.scale.get()
# ability to pass list/vector args
x.translate.set(trans)
# call a mel procedure
mel.myMelScript(x.type(), trans)
```
With PyMEL, python and maya play well together.
Installation
------------
To install, use `pip` with the `mayapy` interpreter.
### Installing into Maya's site-packages directory
The following commands will install PyMEL into the site-packages of the Maya application directory:
#### On MacOS:
```
/Applications/Autodesk/maya<Version>/Maya.app/Contents/bin/mayapy -m pip install pymel
```
#### On Linux:
```
sudo /usr/autodesk/maya<Version>/bin/mayapy -m pip install pymel
```
#### On Windows:
(from a command window running as Administrator)
```
/Applications/Autodesk/maya<Version>/Maya.app/Contents/bin/mayapy -m pip install pymel
```
### Installing into your user's site-packages directory
If you do not have permissions to install into Maya's site-packages, you can
install into your user site-packages by adding the `--user` flag, e.g.
```
/usr/autodesk/maya<Version>/bin/mayapy -m pip install pymel --user
```
To see where `pymel` was installed you can run:
```
mayapy -c "import pymel;print(pymel.__file__)"
```
### Caveats
Older versions of Maya (2021 and earlier) may require installing `pip` before running `pip install`:
On Linux and Mac:
```
curl https://bootstrap.pypa.io/get-pip.py | /usr/autodesk/maya2021/bin/mayapy
```
---
PyMEL is developed and maintained by [Luma Pictures](http://www.lumapictures.com).
Raw data
{
"_id": null,
"home_page": "https://github.com/Lumapictures/pymel",
"name": "pymel",
"maintainer": null,
"docs_url": null,
"requires_python": "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7",
"maintainer_email": null,
"keywords": "maya, mel, 3d, graphics, games, VFX, CG, animation",
"author": "Chad Dombrova",
"author_email": null,
"download_url": null,
"platform": null,
"description": "\nPython in Maya Done Right\n=========================\n\nPyMEL makes python scripting with Maya work the way it should.\n\nMaya's command module is a direct translation of mel commands into python commands. The result is a very awkward and unpythonic syntax which does not take advantage of python's strengths -- particulary, a flexible, object-oriented design. PyMEL builds on the `maya.cmds` module by organizing its commands into a class hierarchy, and by customizing them to operate in a more succinct and intuitive way.\n\nProject Goals\n-------------\n\n- Create an open-source python module for Maya that is intuitive to MEL users and python users alike\n- Fix bugs and design limitations in Maya's python modues, maya.cmds and maya.mel\n- Keep code concise and readable\n- Add organization through class hierarchy and sub-modules\n- Provide documentation accessible via html and the builtin `help() function\n- Make it \"just work\"\n\nSupported Maya Versions\n-----------------------\n\nPyMEL supports four major versions of Maya:\n\n- 2022\n- 2023\n- 2024\n- 2025\n\nSee the full [changelog](https://github.com/LumaPictures/pymel/blob/master/CHANGELOG.rst).\n\nProduction Proven\n-----------------\n\nSince its release in 2008, PyMEL has accumulated an impressive resume in both feature films and games, and is now bundled with every release of Maya.\n\nHere's what Seth Gibson of Bungie Studios, makers of *Halo*, has to say:\n\n> Having done production python code myself for many years, wrapping my head around Maya's native implementation took a little bit of time. With PyMel, I can think and write the python code and syntax I'm already used to, which speeds up my development time considerably. It's also going to help our other Technical Artists with their Python learning curve, since PyMEL's syntax is consistent with most other python packages. Kudos to the PyMel team for such a well thought out project!\n\nBSD License\n-----------\n\nPyMEL is released under the BSD license, which is as open as open source gets. Your studio can freely use, contribute to, and modify this module with no strings attached.\n\nFeatures\n--------\n\n### API Hybridization\n\nPyMEL harnesses the API to create a name-independent representation of your object. This means that the annoying inconsistencies of string comparisons are over: no more worrying about short names versus long names, DAG paths, unique paths, instance paths... it's all handled intelligently for you. And what's more, if anything causes the name of your object to change it will automatically be reflected in your python object.\n\nPyMEL node classes now include hundreds of new methods derived from the API, but with the same intuitive and unified design as before. With PyMEL you get the benefits of API speed and versatility without the advanced learning curve.\n\n### Improved Batch / Standalone Support\n\nEver wonder why python scripts that work in the Maya UI or in Maya batch don't work in Maya's python interpreter? Here's a possible explanation: in both GUI and batch modes Maya sources all of its lowest-level MEL scripts, like those that load user plugins, whereas mayapy and `maya.initialize` does not.\n\nPyMEL ensures that Maya is properly initialized when used from Maya's python interpreter, which makes runtime environments more consistent and your scripts more portable, which adds up to fewer bugs.\n\n### Tighter MEL Integration\n\nExecuting a MEL script with arguments can be an unsightly mess when done the default way:\n\n**default**\n```python\nvalues = ['one', 'two', 'three', 'four']\nmaya.mel.eval('stringArrayRemoveDuplicates({\"'+'\",\"'.join(values)+'\"})')\n```\n\nSo PyMEL provides a handy interface which makes calling MEL procedures just like calling a python function:\n\n**PyMEL**\n```python\nvalues = ['one', 'two', 'three', 'four']\npm.mel.stringArrayRemoveDuplicates(values)\n```\n\nAlso, unlike `maya.mel.eval`, PyMEL will give you the specific MEL error message in a python traceback, along with line numbers:\n\n```python\n>>> mel.myScript('foo', [])\nTraceback (most recent call last):\n ...\nMelConversionError: Error occurred during execution of MEL script: line 2: Cannot convert data of type string[] to type float.\n```\n\nAlso, getting and setting MEL global variables is as easy as working with a dictionary:\n\n```python\nprint(pm.melGlobals['gMainFileMenu'])\npm.melGlobals['gGridDisplayGridLinesDefault'] = 2\n```\n\n### Powerful Classes\n\n#### Nodes\n\n```python\ncamTrans, cam = pm.camera() # create a new camera\ncam.setFocalLength(100)\nfov = cam.getHorizontalFieldOfView()\ncam.dolly(-3)\ncam.track(left=10)\ncam.addBookmark('new')\n```\n\n#### Attributes\n\n```python\ns = pm.polySphere()[0]\nif s.visibility.isKeyable() and not s.visibility.isLocked():\n s.visibility.set(True)\n s.visibility.lock()\n print(s.visibility.type())\n```\n\n#### File paths\n\nbackup all mb files in the current scene's directory\n\n```python\nbasedir = pm.sceneName().parent\nbackupDir = basedir / \"backup\" #slash op joins paths\nif not backupDir.exists:\n backupDir.mkdir()\nfor path in basedir.files('*.mb'):\n print(\"backing up: \", path.name)\n path.copy(backupDir / (path.namebase + \".old\"))\n```\n\n#### Shape components and vectors/matrices\n\nselect all faces that point up in world space\n\n```python\ns = pm.polySphere()[0]\nfor face in s.faces:\n if face.getNormal('world').y > 0.0:\n pm.select(face, add=1)\n```\n\n#### optionVars dictionary\n\n```python\nif 'numbers' not in pm.optionVar:\n pm.optionVar['numbers'] = [1, 24, 47]\npm.optionVar['numbers'].append(9)\nnumArray = pm.optionVar.pop('numbers')\n```\n\nWho is PyMEL for?\n-----------------\n\n### For the Novice\n\nObject-oriented programming, like that provided by PyMEL, is more intuitive to learn because the functionality of an object is directly associated with the object itself.\n\nFor an artist starting to program in Maya, the first question you might ask is \"what can I do with this node?\" Using a procedural approach, like that offered by MEL or maya.cmds, you'll have to dig through the thousands of MEL commands looking for the one that you want. For a camera node, the `camera` MEL command is easy to find, but did you find `orbit`, `track`, `dolly`, and `tumble`, which also work on cameras? What about the API methods?\n\nIn PyMEL, all you have to do is type `help(nt.Camera)` in the python script editor to find out all the things a camera node can do, or just look up the Camera class in the PyMEL docs.\n\n### For the MEL Scripter\n\nWhen we say PyMEL is concise and easy to read, we mean it.\n\n***MEL***\n\n```mel\nstring $sel[] = `ls -sl`;\nstring $shapes[] = `listRelatives -s $sel[0]`;\nstring $conn[] = `listConnections -s 1 -d 0 $shapes[0]`;\nsetAttr ( $conn[0] + \".radius\") 3;\n```\n\n***PyMEL***\n\n```python\npm.selected()[0].getShape().inputs()[0].radius.set(3)\n```\n\n### For the Technical Director\n\nFor those looking to master python in a production environment, PyMEL is more than a module for Maya scripting, it is a repository of example python code -- a self-contained pipeline demonstrating advanced python concepts like function factories, metaclasses, and decorators, as well as essential production practices such as parsing, pickling, logging, and unit testing.\n\nFor those who are already masters of python and who naturally expect more out of a python package, PyMEL is for you, too. It was written for use in production by experienced programmers with a vision for how to add object-oriented design to Maya.\n\nCode Comparison\n---------------\n\n**with Mel**\n\n```mel\nstring $objs[] = `ls -type transform`;\nfor ($x in $objs) {\n print (longNameOf($x)); print \"\\n\";\n\n // make and break some connections\n connectAttr( $x + \".sx\") ($x + \".sy\");\n connectAttr( $x + \".sx\") ($x + \".sz\");\n\n // disconnect all connections to .sx\n string $conn[] = `listConnections -s 0 -d 1 -p 1 ($x + \".sx\")`;\n for ($inputPlug in $conn)\n disconnectAttr ($x + \".sx\") $inputPlug;\n\n // add and set a string array attribute with the history of this transform's shape\n if ( !`attributeExists \"newAt\" $x`)\n addAttr -ln newAt -dataType stringArray $x;\n string $shape[] = `listRelatives -s $x`;\n string $history[] = `listHistory $shape[0]`;\n string $elements = \"\";\n for ($elem in $history)\n $elements += \"\"\" + $elem + \"\" \";\n eval (\"setAttr -type stringArray \" + $x + \".newAt \" + `size $history` + $elements);\n print `getAttr ( $x + \".newAt\" )`;\n\n // get and set some attributes\n setAttr ($x + \".rotate\") 1 1 1;\n float $trans[] = `getAttr ($x + \".translate\")`;\n float $scale[] = `getAttr ($x + \".scale\")`;\n $trans[0] *= $scale[0];\n $trans[1] *= $scale[1];\n $trans[2] *= $scale[2];\n setAttr ($x + \".scale\") $trans[0] $trans[1] $trans[2];\n\n // call a mel procedure\n myMelScript( `nodeType $x`, $trans );\n}\n```\n\n**with default Python**\n\n```python\nimport maya.cmds as cmds\nobjs = cmds.ls(type='transform')\n# returns None when it finds no matches\nif objs is not None:\n for x in objs:\n print(mm.eval('longNameOf(\"%s\")' % x))\n\n # make and break some connections\n cmds.connectAttr('%s.sx' % x, '%s.sy' % x)\n cmds.connectAttr('%s.sx' % x, '%s.sz' % x)\n\n # disconnect all connections to .sx\n conn = cmds.listConnections(x + \".sx\", s=0, d=1, p=1)\n # returns None when it finds no match:\n if conn is not None:\n for inputPlug in conn:\n cmds.disconnectAttr(x + \".sx\", inputPlug)\n\n # add and set a string array attribute with the history of this transform's shape\n if not mm.eval('attributeExists \"newAt\" \"%s\"' % x):\n cmds.addAttr(x, ln='newAt', dataType='stringArray')\n shape = cmds.listRelatives(x, s=1 )\n if shape is not None:\n history = cmds.listHistory( shape[0] )\n else:\n history = []\n args = tuple(['%s.newAt' % x, len(history)] + history)\n cmds.setAttr(*args, type='stringArray' )\n\n # get and set some attributes\n cmds.setAttr('%s.rotate' % x, 1, 1, 1)\n scale = cmds.getAttr('%s.scale' % x)\n # maya packs the previous result in a list for no apparent reason:\n scale = scale[0]\n # the tuple must be converted to a list for item assignment:\n trans = list(cmds.getAttr('%s.translate' % x )[0]) \n trans[0] *= scale[0]\n trans[1] *= scale[1]\n trans[2] *= scale[2]\n cmds.setAttr('%s.scale' % x, trans[0], trans[1], trans[2])\n # call a mel procedure\n mm.eval('myMelScript(\"%s\",{%s,%s,%s})' % (cmds.nodeType(x), trans[0], trans[1], trans[2]))\n```\n\n**with Pymel**\n\n```python\n# safe to import into main namespace (but only recommended when scripting interactively)\nfrom pymel import *\nfor x in ls(type='transform'):\n # object oriented design\n print(x.longName())\n\n # make and break some connections\n x.sx.connect(x.sy)\n x.sx.connect(x.sz)\n # disconnect all connections to .sx\n x.sx.disconnect()\n\n # add and set a string array attribute with the history of this transform's shape\n x.setAttr('newAt', x.getShape().history(), force=1)\n\n # get and set some attributes\n x.rotate.set([1, 1, 1])\n trans = x.translate.get()\n # vector math:\n trans *= x.scale.get()\n # ability to pass list/vector args\n x.translate.set(trans)\n # call a mel procedure\n mel.myMelScript(x.type(), trans)\n```\n\nWith PyMEL, python and maya play well together.\n\nInstallation\n------------\n\nTo install, use `pip` with the `mayapy` interpreter.\n\n### Installing into Maya's site-packages directory\n\nThe following commands will install PyMEL into the site-packages of the Maya application directory:\n\n#### On MacOS:\n\n```\n/Applications/Autodesk/maya<Version>/Maya.app/Contents/bin/mayapy -m pip install pymel\n```\n\n#### On Linux:\n```\nsudo /usr/autodesk/maya<Version>/bin/mayapy -m pip install pymel\n```\n\n#### On Windows:\n\n(from a command window running as Administrator)\n\n```\n/Applications/Autodesk/maya<Version>/Maya.app/Contents/bin/mayapy -m pip install pymel\n```\n\n### Installing into your user's site-packages directory\n\nIf you do not have permissions to install into Maya's site-packages, you can\ninstall into your user site-packages by adding the `--user` flag, e.g.\n\n```\n/usr/autodesk/maya<Version>/bin/mayapy -m pip install pymel --user\n```\n\nTo see where `pymel` was installed you can run:\n\n```\nmayapy -c \"import pymel;print(pymel.__file__)\"\n```\n\n### Caveats\n\nOlder versions of Maya (2021 and earlier) may require installing `pip` before running `pip install`:\n\nOn Linux and Mac:\n```\ncurl https://bootstrap.pypa.io/get-pip.py | /usr/autodesk/maya2021/bin/mayapy\n```\n\n---\n\nPyMEL is developed and maintained by [Luma Pictures](http://www.lumapictures.com).\n",
"bugtrack_url": null,
"license": "BSD",
"summary": "Python in Maya Done Right",
"version": "1.5.0",
"project_urls": {
"Homepage": "https://github.com/Lumapictures/pymel",
"Repository": "https://github.com/Lumapictures/pymel"
},
"split_keywords": [
"maya",
" mel",
" 3d",
" graphics",
" games",
" vfx",
" cg",
" animation"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "e4d88db666ebbe3cd6fb643b609483bf359d0b513a94e5cd46e903367fb394fe",
"md5": "8d136b8af0a2b9ad94c2534537bb7e46",
"sha256": "2f779e28eef37af580433c2df1798905f32f055b62bbbffa0ad1eab32c59040d"
},
"downloads": -1,
"filename": "pymel-1.5.0-py2.py3-none-any.whl",
"has_sig": false,
"md5_digest": "8d136b8af0a2b9ad94c2534537bb7e46",
"packagetype": "bdist_wheel",
"python_version": "py2.py3",
"requires_python": "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7",
"size": 9906247,
"upload_time": "2024-10-28T05:09:20",
"upload_time_iso_8601": "2024-10-28T05:09:20.822320Z",
"url": "https://files.pythonhosted.org/packages/e4/d8/8db666ebbe3cd6fb643b609483bf359d0b513a94e5cd46e903367fb394fe/pymel-1.5.0-py2.py3-none-any.whl",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-10-28 05:09:20",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "Lumapictures",
"github_project": "pymel",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pymel"
}