-
-
Notifications
You must be signed in to change notification settings - Fork 628
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add runtime check for valid Python interpreter (#7365)
### Problem Now that we'll soon allow running Pants with more than Python 2.7 for every day users, we should eagerly ensure that they are using a supported Python version. This is necessary because Pants is typically ran as a script, rather than as a library, and the script may be ran with whichever interpreter the user chooses. Even though the setup repo is supposed to ensure people use a valid interpreter, it is easy to get around this with `PYTHON=3.5 ./pants` or with putting `pants_engine_python_version: 3.5` in their `pants.ini`. Both these scenarios are totally valid to do, and we should not teach the setup repo or `--pants-engine-python-version` what are valid options, because the former is easy to fall out of sync with users and the latter is easy to circumvent. While Pants _might_ work with something like 3.5, we should at least warn users they're treading into dangerous waters. If they want to proceed by setting an env var bypass, all power to them. But for the sake of UX we should at least give the warning, rather than relying on strange bugs and `SyntaxError`s to enforce using the correct version. ### Solution Add a runtime check to `pants_loader.py` with a human readable error message. Allow skipping the check with `PANTS_IGNORE_UNSUPPORTED_PYTHON_INTERPRETER`. Add unit tests for this all. ### Result When running with anything other than 2.7 or 3.6+, Pants will error out. Once we drop Py2, we can change this check to 3.6+.
- Loading branch information
1 parent
b3ab38c
commit 5879cf1
Showing
4 changed files
with
79 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# coding=utf-8 | ||
# Copyright 2019 Pants project contributors (see CONTRIBUTORS.md). | ||
# Licensed under the Apache License, Version 2.0 (see LICENSE). | ||
|
||
from __future__ import absolute_import, division, print_function, unicode_literals | ||
|
||
import os | ||
import sys | ||
import unittest | ||
from builtins import map, str | ||
|
||
import mock | ||
|
||
from pants.bin.pants_loader import PantsLoader | ||
|
||
|
||
class LoaderTest(unittest.TestCase): | ||
|
||
def test_is_supported_interpreter(self): | ||
unsupported_versions = {(2, 6), (3, 3), (3, 4), (3, 5), (4, 0)} | ||
supported_versions = {(2, 7), (3, 6), (3, 7), (3, 8)} | ||
self.assertTrue(all(not PantsLoader.is_supported_interpreter(major, minor) for major, minor in unsupported_versions)) | ||
self.assertTrue(all(PantsLoader.is_supported_interpreter(major, minor) for major, minor in supported_versions)) | ||
|
||
def test_ensure_valid_interpreter(self): | ||
current_interpreter_version = '.'.join(map(str, sys.version_info[0:2])) | ||
bypass_env = PantsLoader.INTERPRETER_IGNORE_ENV_VAR | ||
with mock.patch.object(PantsLoader, 'is_supported_interpreter', return_value=False): | ||
with self.assertRaises(PantsLoader.InvalidInterpreter) as e: | ||
PantsLoader.ensure_valid_interpreter() | ||
self.assertIn(current_interpreter_version, str(e.exception)) | ||
self.assertIn(bypass_env, str(e.exception)) | ||
with mock.patch.dict(os.environ, {bypass_env: "1"}): | ||
PantsLoader.ensure_valid_interpreter() |