Page MenuHomePhabricator

[ORES] Make setup.py only work when using Python 3+
Closed, ResolvedPublic

Description

Currently, ORES supports strictly Python 3 and no Python 2 backwards compatibility is planned (nor IMO should there be), so to prevent Python 2 users from being able to use setup.py to setup ORES (and then finding out that Python 2 isnt supported) would be ideal. @awight and I have looked at ways to do this, its currently possible but would require us to force a new minimum version for Setup tools (24.2.0) and PIP (9.0.0). See this link for further information on what is required to force Python 3.

Event Timeline

Restricted Application added a subscriber: Aklapper. · View Herald Transcript

I think we should use a multifaceted strategy. There's a few different install pathways.

  1. The wheel in pypi (pip install ores)
  2. A tar.gz from something like pypi (pip install ores-<version>.tar.gz)
  3. Directly running setup.py (python setup.py install)

Option 2 and 3 both run setup.py. Option 1 does not. If you have an old version of pip, you can install the wheel in python 2.x without running setup.py. Here's what I propose we do:

For setup.py

import platform
import sys
if sys.version_info <= (3, 0):
    print("ores requires Python '>=3' but the running Python is " + platform.python_version())
    sys.exit(1)

setup(
    ...
    python_requires=">=3"
)

For the main __init__.py

import platform
import sys
if sys.version_info <= (3, 0):
    from pkg_resources import VersionConflict
    raise VersionConflict("ores requires Python '>=3' but the running Python is " + platform.python_version())

...

By including "python_requires" in the setup.py, we catch version mismatches ASAP for people with up-to-date pip (1). By including the version check code in setup.py, we catch version issues during install via pip (2). By including the version check in __init__.py we catch any import of any module within the project(3). This will allow scripts to crash gracefully.

To make sure that even submodule imports were caught by one check in the top __init__.py, I made a test package to prove it:

$ python
Python 2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from py3only import module
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "py3only/__init__.py", line 5, in <module>
    raise VersionConflict("py3only requires Python '>=3' but the running Python is " + platform.python_version())
pkg_resources.VersionConflict: py3only requires Python '>=3' but the running Python is 2.7.12