2to3 - Automated Python 2 to 3 Code Translation

raw JSON →
1.0 verified Thu Apr 16 auth: no python deprecated

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.

pip install 2to3
error 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.
fix
Run 2to3 on your Python 2 code. It will automatically convert print '...' to print('...') and except Exception, e: to except Exception as e:.
error 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.
fix
Use the built-in zip(), map(), and filter() functions directly instead of itertools.izip, itertools.imap, itertools.ifilter. 2to3 should handle this automatically.
error 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.
fix
Run 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.
error 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.
fix
Manually 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.
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.
fix For new projects, avoid Python 2 entirely. For existing Python 2 codebases, migrate to Python 3 as soon as possible and manually address any remaining incompatibilities if `2to3` is no longer viable with your target Python 3 version. Consider alternatives like `python-modernize` for dual Python 2/3 compatibility if needed for a transition period, though Python 2 is EOL.
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.
fix Always thoroughly review the diffs generated by `2to3` and extensively test the converted Python 3 code. Be prepared to manually refactor code, especially for string/bytes handling, exception syntax (`except Exception as e`), and relocated standard library modules.
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.
fix Run `2to3` using an older Python 3 interpreter (e.g., Python 3.9 or earlier) if encountering parsing issues with newer Python versions, or manually port the code. Given Python 2 is EOL, a full manual port for problematic sections might be more robust.

The `2to3` tool is executed from the command line, pointing it to Python 2.x source files or directories. The `-w` flag writes the changes back to the original files, creating a `.bak` backup. The `--output-dir` option allows writing converted files to a new location, often used with `-n` to prevent backup files and `-W` to write all files, even if unchanged.

# 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/