New updates to
Autodesk Character Generator
Learn More!
  • 1/3
You are here: Homepage /  Tutorials & Tips /  Tutorials / Integrating Pylint inside MoBu 2010 Python Editor
Integrating Pylint inside MoBu 2010 Python Editor
 
 
Posted: Sep 23, 2009
Published by: sphaneuf
Homepage: none
Software: Autodesk MotionBuilder
Category: Scripting
Skill: Intermediate
 
Tutorial Steps
1What is Pylint?
2How to install pylint
3How to integrate Pylint in MotionBuilder 2010
 

What is Pylint?

Pylint is a static analyzer. This means it finds mistakes in your python script BEFORE you run the script. It can tell you if you make a mistake in the name of a function, if you have some illegal code, etc. This is especially useful when developing a tool, since tools can have callbacks. When executing a script that creates a tool, the code inside the callback is not executed immediately. The callback has to be triggered. This means if you make an error (calling a non-existing function) inside the callback you will only catch it by activating the UI the callback is connected to. Here is an example of errors pylint can find. I ran the following script with Pylint integration in MoBu:

As you can see in the output of the console, 7 errors were found:

1- At line 6, we are told that the class ToolHolder has no PrintMessage. If we look at the code, we see that the method is called PrintMsg. We would have gotten this error after running the script and after having pressed the button. So pylint saved us a bit of testing time here!

2- At line 8, we have a reminder that the member method of the class should have their first member called self. This is a very important Python requirement and it’s easy to forget :)

3- At line 23 we notice that kFBTextJustifyLef doesn’t exist. The ending “t” was forgotten the real identifier is: kFBTextJustifyLeft.

4- At line 25, we are reminded that BtnCallback doesn’t exist. We should have put self.BtnCallback.

5- At line 27, we are notified that FButton is not a class: FBButton is!

6- At line 30, we are notified that btnCallback is not a member of ToolHolder. It is called BtnCallback (Python is case sensitive).

7- At line 31, variable “t” is not defined. In refactoring my script I renamed that variable tool but forgot that particular reference.

Pylint won’t catch all the errors in your script. You will still have to test it :) but it is as close to static compilation analysis (like java and c++) as we can get in Python.

How to install pylint

There is no real installer for pylint for python 2.6. You will need to download a few scripts and execute them to make it work. IMPORTANT NOTE: All this integration only works for MoBu 32 bits and Python 32 bits since the easy_install program doesn't seem to handle Python 64 bits.

1- Ensure you have a distribution of Python 2.6 on your machine (2.6.1 or 2.6.2).

2- Download the script ez_install.py from: http://peak.telecommunity.com/dist/ez_setup.py.

3- To be able to use easy_install from the command line, add both paths c:Python26 and c:Python26Scripts to your PATH environment variable.

4- Execute the downloaded script from a python 2.6 environment. The easiest way to do this is to start Python2.6 -> IDLE, open the script and execute it (press F5). This will install the program easy_install in your python distribution. This program allows installation of other python utility easily (it downloads and install tools automatically). Alternatively, from the command line you can execute the ez_setup.py script:

Image Attachment Code Listing
# Assuming your current directory is the same as ez_setup.py
>> python ez_install.py

5- ez_install should be installed on your machine. It's startup script file is in the folder c:Python26Scripts (that is why you added this path to your PATH environment variable). Now open a command line console and type the following commands using easy_install to download and install pylint and its 2 dependencies:

Image Attachment Code Listing
>> easy_install logilab-common
>> easy_install logilab-astng
>> easy_install pylint

6- To test that pylint is working correctly, type “pylint” at the command line. You should get the help output of pylint.

How to integrate Pylint in MotionBuilder 2010

For MotionBuilder 2010 you will have to modify some files in MB python core system. Here are the steps you will need to perform:

1- Backup the file binconfigPythonpythonidelib.py. Really, back it up!

2- Now you should really back up: binconfigPythonpythonidelib.py. Now.

3- Download the zip file attach to this tutorial: pylint_integration.zip . It contains 2 files: “pythonidelib_pylint_integration.py” which is my pythonidelib.py file and it shows how to do the plumbing to hook Pylint to a shortcut in the Python Editor. It contains also: “mbpylintrc.txt”: this file specifies a bunch of configuration parameters so the output of Pylint is more relevant to MB. Copy both files in binconfigPython.

3- Open pythonidelib_pylint_integration.py and find the section near the end of the file where it says “Start pylint integration” and "End Pylint integration". Copy this whole section in your binconfigPythonpythonidelib.py. For reference here is the text you should copy:

Image Attachment Code Listing
#################################################################
# Start of Pylint integration: paste the following code into 
# your binconfigPythonpythonidelib.py

import site
site.main()
import sys
def IsVista():
    isVista = False
    if sys.platform == 'win32':
        isVista = sys.getwindowsversion()[0] >= 6
    return isVista
    
def GetBinPath():
    # We will be needing the executable path, so better keep it around...
    execPath = sys.executable[0:sys.executable.rfind(os.path.sep)]
    
    # find the config path
    if IsVista():
        binpath = os.environ['LOCALAPPDATA']
        binpath = os.path.join(binpath, "Autodesk", "MB2010" )
    else:        
        binpath = sys.executable[0:sys.executable.rfind( "bin" ) + 3]
    return binpath

def GetConfigPath():
    return os.path.join(GetBinPath(),"config")

import os
import os.path
PYLINT_CONFIG_FILE= os.path.join(GetConfigPath(),"Python","mbpylintrc.txt")
def Pylint(isFromConsole, editorData, selectedText):
    if isFromConsole:
        return
    # Will statically analyze the script and reports error that
    # can be found BEFORE execution!
    from pylint import lint
    script = os.path.abspath(editorData)
    cmd = ["--errors-only", "--rcfile=%s" %(PYLINT_CONFIG_FILE), editorData]
    try:
        lint.Run(cmd)
    except SystemExit, e:
        if e.code == 0:
            print "No error found in", os.path.basename(editorData)
            
# End of pylint integration: DON'T FORGET TO ADD Pylint in the mapping
# section below!!!
###############################################################            

4- At the end of the file there is a section that maps keyboard shortcut to custom python functions. Ensure you add the Pylint function for one of the shortcut.
For reference the shortcuts dictionary should now look like this (I mapped the Pylint function to action.python.custom3):

Image Attachment Code Listing
# Mapping between shortcut name and their implementation
shortcuts = { 
    # these 3 ids are hardcoded according to the console ui
    'action.python.help' : HelpPyfbsdk
    ,'action.python.toolmanager' : ActivateToolManager
    ,'action.python.debugscript' : Debug
    
    # These id are mapped on keyboard shortcuts
    # they are available for custom user command
    
    ,'action.python.custom1' : Reload
    ,'action.python.custom2' : PyDocHelp
    
    # Pylint integration IMPORTANT: Map the Pylint function to the custom3 shortcut!!!
    ,'action.python.custom3' : Pylint
    
    #,'action.python.custom4' : Custom4
    #,'action.python.custom5' : Custom5
    #,'action.python.custom6' : Custom6
    #,'action.python.custom7' : Custom7
    #,'action.python.custom8' : Custom8
    #,'action.python.custom9' : Custom9
    #,'action.python.custom10' : Custom10    
}

5- Restart MotionBuilder.

6- Open the Window -> Python Editor. Open any script. Press Shift + F3 while the focus is in the Script Editor (bottom half of the Python Editor). You should get some output in the console telling you if there are any errors.

To know more about customizing the Python Editor and binding custom function to shortcut, take a look at my other tutorial in the Area.

Good luck and may the python fu be with you!

In order to post any comments, you must be logged in!