I want to officially drop python 2 support for a program I maintain and take full advantage of python 3 features. Instead of having a program that more-or-less works under python 2 but fails with weird behavior in corner cases, I'd like to officially break my program for python 2 with a clear "please use python 3 instead" error message. What's the most reasonable way to fail with errors for unsupported python versions?
For instance, I'd like importing the code in python 2 (at least the top-level package) to trigger an error and for my distutils setup.py script to error out when attempting to install or build it for python 2 (even when invoked via python 3 like python3 setup.py sdist_dsc --with-python2
). I'd also like to include any relevant metadata to officially declare which python versions I support. There's a Requires-Python field in PEP 345 but I don't think that matters if I'm not using distutils2.
As of setuptools 24.2.0 (2016-07-20) and pip 9.0.0 (2016-11-02), the python_requires
argument to setup()
in setup.py
will tell packaging tools not to install a package that doesn't match the specifier. For example, to only support Python 3.6+:
setup(
...
python_requires=">=3.6",
...
)
To only support Python 2.7 and 3.4+:
setup(
...
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*",
...
)
Given the built-in support, the following methods in this answer should no longer be used.
To prevent importing, put this at the top of the module:
import sys
if sys.version_info[0] < 3:
raise ImportError('Python < 3 is unsupported.')
To prevent installing, put this at the top of setup.py
:
import sys
if sys.version_info[0] < 3:
sys.exit('Python < 3 is unsupported.')
This will also fail before the check if you use syntax that is incompatible with Python 2, as the module will be parsed before running. Detecting that might be overkill for supporting "not supporting Python 2".
But I haven't actually seen this done in practice. Most maintainers just say what's supported and don't bother checking.
The standard way is to set the classifiers
in setup.py
:
if sys.version_info < (3, 3):
sys.exit("error: this script requires Python 3.3 or greater.")
setup(...,
classifiers=[
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
# ... other non-version info
],
...)
For example, tulip
project (asyncio
) supports only Python 3.3.
You could also add in your package __init__.py
:
if sys.version_info < (3, 3):
raise ImportError("Python 3.3 or greater is required")
I would go with this answer but instead I would raise an exception:
import sys
if sys.version_info[0] < 3:
raise ImportError('Only Python 3 is supported.')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With