2to3 - Automated Python 2 to 3 Code Translation
2to3 is a Python program designed to automatically convert Python 2.x source code into Python 3.x compatible code. It achieves this by applying a series of 'fixers' that address common syntax and API changes between the two major Python versions. The PyPI package `2to3` (version 1.0, last updated September 2018) primarily provides the `2to3` command-line utility, which was historically part of the Python standard library. Its core component, `lib2to3`, has been deprecated since Python 3.11 and is slated for removal in Python 3.13, marking the tool's transition towards obsolescence for active development. As Python 2 reached its End-of-Life in January 2020, the utility's main relevance is for legacy codebase migrations.
Common errors
-
SyntaxError: invalid syntax (often on 'print' statements or 'except Exception, e')
cause Python 3 changed `print` from a statement to a function and modified the `except` syntax. Python 2 code uses the older syntax which is invalid in Python 3.fixRun `2to3` on your Python 2 code. It will automatically convert `print '...'` to `print('...')` and `except Exception, e:` to `except Exception as e:`. -
AttributeError: module 'itertools' has no attribute 'izip' (or 'imap', 'ifilter')
cause In Python 3, built-in functions like `zip`, `map`, and `filter` now behave like their `itertools` 'i' prefixed counterparts (they return iterators). The `itertools` module no longer provides these 'i' prefixed versions.fixUse the built-in `zip()`, `map()`, and `filter()` functions directly instead of `itertools.izip`, `itertools.imap`, `itertools.ifilter`. `2to3` should handle this automatically. -
ModuleNotFoundError: No module named 'urllib2' (or 'urlparse')
cause Several standard library modules, particularly those related to networking like `urllib`, `urllib2`, and `urlparse`, were reorganized and combined into subpackages of `urllib` in Python 3.fixRun `2to3` on your code. It will typically refactor imports like `import urllib2` to `import urllib.request` or similar, depending on the specific functions being used. -
TypeError: a bytes-like object is required, not 'str' (or similar errors related to string/bytes mismatch)
cause Python 3 distinguishes clearly between `str` (Unicode text) and `bytes` (binary data). Python 2's `str` type was ambiguous. `2to3` might not always correctly infer intent, leading to type mismatches when processing text vs. binary data.fixManually inspect and modify the code to explicitly handle `str` and `bytes` types where necessary, using `b''` literals for bytes, `.encode()` to convert str to bytes, and `.decode()` to convert bytes to str. `2to3` often assumes Python 2 strings should become Python 3 strings, which can be incorrect for binary data.
Warnings
- breaking The underlying `lib2to3` library, which powers the `2to3` tool, was officially deprecated in Python 3.11 and is scheduled for removal in Python 3.13 (expected October 2024). This means the `2to3` PyPI package and the standalone tool may cease to function or be actively supported in newer Python environments.
- gotcha `2to3` cannot automatically fix all Python 2 to Python 3 incompatibilities. Significant changes, such as those related to Unicode vs. bytes, reorganized standard library modules (e.g., `urllib`, `urllib2`), and certain semantic shifts, often require manual review and modification after conversion.
- gotcha The `2to3` tool itself, relying on `lib2to3`, is unable to parse Python 3.10+ grammar due to the introduction of the new PEG parser in CPython. This limits its ability to convert Python 2 code if the `2to3` tool itself is being run on a very recent Python 3 interpreter (e.g., 3.10 and above) that it cannot parse.
Install
-
pip install 2to3
Imports
- 2to3 (command-line tool)
This library is primarily used as a command-line tool.
Quickstart
# Save your Python 2 code to a file, e.g., 'my_python2_script.py'
# Example content for my_python2_script.py:
# print 'Hello, world!'
# x = raw_input('Enter your name: ')
# print 'Your name is', x
# To see the changes without modifying the file:
# 2to3 my_python2_script.py
# To apply changes directly to the file (creates a .bak backup):
# 2to3 -w my_python2_script.py
# To convert an entire directory to a new output directory:
# mkdir python3_version
# 2to3 --output-dir=python3_version -W -n python2_codebase/