How to Convert Maya Python 2 Code to Python 3
Python 3 is finally here in Maya 2022! If you haven’t converted your scripts to Python 3, I’ll go over how you can automatically convert your Python 2 scripts and modules to Python 3. There are A LOT of changes between Python 2 and Python 3 and Python 3 code is not designed to be backwards-compatible with Python 2. You may only be using a subset of affected libraries and features in your Maya scripts, but you’re probably still going to want to avoid making the updates manually.
Python 3 includes a script called, 2to3.py, which handles automatically converting your code for a lot of the changes that occurred between Python 2 and Python 3. Take a look at the 2to3.py documentation which lists the fixes that it applies to get an idea of how big of a difference there is between Python 2 and Python 3.
My goal with this blog post is to help you convert your code as fast a possible with the least amount of fuss while also showing you some options for maintaining backwards-compatibility with Python 2. You can achieve cleaner results with manual conversion, but I know that may not always be desired or practical. You can always go back and clean up your code as time allows and especially as you drop support for Python 2. I really recommend reading this blog post in its entirety before getting started to understand what changes are being made and there are a few scenarios that you’ll want to consider.
Should I use 2to3, futurize, or modernize?#
As mentioned, Python 3 comes with a library called lib2to3 which as the name suggests converts Python 2 code to Python 3. 2to3 focuses on porting your code to Python 3, but it does not attempt to make it backwards-compatible.
On the other hand, Maya 2022 also comes with the python-future library installed which uses 2to3 under the hood, but it can convert your code and make it backwards compatible with Python 2 with the futurize script. This sounds wonderful, but the catch is that to use it as intended your end-user needs to have the future python package installed in their older Maya installations or you need to provide the future package with your code.
Lastly, the python-modernize library will also give you backwards-compatibility and only relies on the built-in six library as the compatibility layer, but you’ll need to install python-modernize to get access to the conversion script.
I’m going to show you how to use the conversion scripts for these three methods and cover more in-depth the pros and cons for each. Note that none of these libraries is a complete solution, but if you’re lucky, they’ll get the job done or get you most of the way there.
Backup#
Make sure you have a backup of the code you’ll be converting. The way I’m showing you how to use the conversion scripts will also create a backup in the process, but just the be on the safe side, it’s not bad to keep another copy.
2to3#
Summary#
- Use this if you want to move to Python 3 and not look back or if you intend to maintain separate Python 2 and Python 3 branches.
- No external dependencies. You’re converting to vanilla Python 3 code.
- You may introduce bugs from the conversion.
- e.g. If you’re using the division operator in 2.7 and your code expected an integer result, in Python 3 you’ll get a float result which may cause issues.
How-To#
We’re looking at 2to3 first since it’s at the core of futurize and modernize and the other tools adopt a similar script interface to run the conversion. As I mentioned, 2to3 does not attempt to keep any backwards-compatibility so there’s no additional compatibility layer like the other conversion tools. It just outputs pure Python 3. I mention this approach only because some people may be fortunate enough to move to Maya 2022/Python 3 and never look back or may prefer to maintain a copy of legacy Python 2 code and a separate branch with clean Python 3 code. Here’s what the conversion command looks like:
# For a single file or list of files
"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m lib2to3 --nofix=long -w my_script.py
# To convert all files recursively in a folder
"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m lib2to3 --nofix=long -w my_directory/
This will edit your “.py” files to apply the fixes, but it will backup the files first as “.py.bak”. It won’t touch or backup “.py” files that it finds don’t need any fixes. I also added to skip the “long” function because that interferes with maya.cmds
like maya.cmds.ls(long=True)
. I find that I use the ls command in that way a lot more than using the long data type.
2to3 also outputs to the terminal the changes that it’s making. Lines with “minus” at the beginning is what you had before and lines with “plus” is what it changed the code to. This is a good way to start learning to write Python 3 compatible code. You can run without the “-w” flag to just inspect what changes it would make without writing out anything.
futurize#
Summary#
- Use this if you are only targeting Maya 2022+ or can guarantee your users will have the future package installed for older versions of Maya.
- Converts your code to be compatible with Python 2 and Python 3
- Maya 2022 includes python-future package to perform the conversion
- Your converted code will depend on the future python package
- This is included with Maya 2022
- You would need to “pip install” it into older versions of Maya
- Will work with Maya 2022 out of the box and <2022 with some modifications to older Mayas.
How-To#
Maya 2022 comes with the python-future library installed and is available in both Python 2 and Python 3 modes. Autodesk is likely using this and encouraging it. The python-future library comes with a script called, futurize-script.py, that we’ll be using to apply the conversion, but it also comes with a collection of modules that serve as a compatibility layer between Python 2 and Python 3. Let’s look at the conversion command and then talk more about cross-compatibility. Here’s what the conversion command looks like:
# For a single file or list of files
"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" "C:\Program Files\Autodesk\Maya2022\Python37\Scripts\futurize-script.py" --nofix=lib2to3.fixes.fix_long -w my_script.py
# To convert all files recursively in a folder
"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" "C:\Program Files\Autodesk\Maya2022\Python37\Scripts\futurize-script.py" --nofix=lib2to3.fixes.fix_long -w my_dir/
from __future__ import division
from __future__ import print_function
from future import standard_library
standard_library.install_aliases()
from builtins import zip
from builtins import range
from past.utils import old_div
from builtins import object
modernize#
Summary#
- Use this for best compatibility with all newer versions of Maya.
- Converts your code to be compatible with Python 2 and Python 3
- You need to
pip install python-modernize
to get the conversion script. - Your converted code will depend on the six python package, but that’s included with Python 2 and Python 3.
- Will work with all newer versions of Maya.
How-To#
The python-modernize library tries to achieve cross-compatibility like python-future, but it doesn’t depend on an external compatibility layer. Instead, it uses the six module as its compatibility layer which comes built-in with the latest versions of Python 2 and with Python 3. You just need to install modernize to get access to the conversion script. You could install modernize into any Python interpreter. It doesn’t need to be installed in Maya’s Python interpreter, but if that’s all you’ve got, here’s how to do it:
"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m pip install modernize
# For a single file or list of files
"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m modernize -x fissix.fixes.fix_long -w my_script.py
# To convert all files recursively in a folder
"C:\Program Files\Autodesk\Maya2022\bin\mayapy.exe" -m modernize -x fissix.fixes.fix_long -w my_dir/
modernize will apply fixes just like the other tools, but mostly you’ll just notice that the compatibility imports will be different.
from six.moves import range
from six.moves import zip
Final Thoughts#
Whichever route you take, try running the conversion and testing your code. As I mentioned, none of these will fix everything, but they will reduce the amount of time and energy you’ll need to devote to it. Test your code and fix the remaining issues manually.
Start writing modernized Python 2 and eventually Python 3 code. This is something that you’ll need to keep working on with new code you write. Test new code in Python 3 first to get in the habit of writing modern Python 2.
Hope this helps you get started migrating over to Python 3. Let me know if you run into any issues when converting or find any particularly tricky code that doesn’t auto-convert.