diff options
author | Bernát Gábor <bgabor8@bloomberg.net> | 2021-02-09 09:30:36 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-09 09:30:36 +0000 |
commit | 36cdadba810c20c0b7af89029d7c1f0fa25cc12d (patch) | |
tree | fb1c1f64e0b135b0afccd6e4980f44a801e05273 /src | |
parent | 726271deba8242e76ee4dcacc6cc12190696bf25 (diff) | |
download | tox-git-36cdadba810c20c0b7af89029d7c1f0fa25cc12d.tar.gz |
Support running python 2 targets (#1900)
Diffstat (limited to 'src')
-rw-r--r-- | src/tox/execute/pep517_backend.py | 2 | ||||
-rw-r--r-- | src/tox/tox_env/python/virtual_env/api.py | 3 | ||||
-rw-r--r-- | src/tox/util/pep517/backend.py | 45 | ||||
-rw-r--r-- | src/tox/util/pep517/backend.pyi | 1 |
4 files changed, 38 insertions, 13 deletions
diff --git a/src/tox/execute/pep517_backend.py b/src/tox/execute/pep517_backend.py index a9ccbc08..d865bfaf 100644 --- a/src/tox/execute/pep517_backend.py +++ b/src/tox/execute/pep517_backend.py @@ -1,4 +1,5 @@ """A executor that reuses a single subprocess for all backend calls (saving on python startup/import overhead)""" +import time from pathlib import Path from subprocess import TimeoutExpired from threading import Lock @@ -62,6 +63,7 @@ class LocalSubProcessPep517Executor(Execute): ) self._exc = ToxBackendFailed(failure) raise self._exc + time.sleep(0.01) # wait a short while for the output to populate return self._local_execute @staticmethod diff --git a/src/tox/tox_env/python/virtual_env/api.py b/src/tox/tox_env/python/virtual_env/api.py index f3f8e98e..bdf55a55 100644 --- a/src/tox/tox_env/python/virtual_env/api.py +++ b/src/tox/tox_env/python/virtual_env/api.py @@ -98,7 +98,8 @@ class VirtualEnv(Python, ABC): return cmd def default_install_command(self, conf: Config, env_name: Optional[str]) -> Command: # noqa - cmd = Command(["python", "-I", "-m", "pip", "install", "{opts}", "{packages}"]) + isolated_flag = "-E" if self.base_python.version_info.major == 2 else "-I" + cmd = Command(["python", isolated_flag, "-m", "pip", "install", "{opts}", "{packages}"]) return self.post_process_install_command(cmd) def setup(self) -> None: diff --git a/src/tox/util/pep517/backend.py b/src/tox/util/pep517/backend.py index b17d9c17..a4f2db70 100644 --- a/src/tox/util/pep517/backend.py +++ b/src/tox/util/pep517/backend.py @@ -1,5 +1,8 @@ """Handles communication on the backend side between frontend and backend""" +from __future__ import print_function, unicode_literals + import json +import os import sys import traceback @@ -20,11 +23,11 @@ class BackendProxy: def __call__(self, name, *args, **kwargs): on_object = self if name.startswith("_") else self.backend if not hasattr(on_object, name): - raise MissingCommand(f"{on_object!r} has no attribute {name!r}") + raise MissingCommand("{!r} has no attribute {!r}".format(on_object, name)) return getattr(on_object, name)(*args, **kwargs) def __str__(self): - return f"{self.__class__.__name__}(backend={self.backend})" + return "{}(backend={})".format(self.__class__.__name__, self.backend) def _exit(self): # noqa return 0 @@ -37,27 +40,29 @@ def flush(): def run(argv): reuse_process = argv[0].lower() == "true" + try: backend_proxy = BackendProxy(argv[1], None if len(argv) == 2 else argv[2]) except BaseException: print("failed to start backend", file=sys.stderr) - flush() raise - print(f"started backend {backend_proxy}", file=sys.stdout) + else: + print("started backend {}".format(backend_proxy), file=sys.stdout) + finally: + flush() # pragma: no branch while True: - try: - message = input().strip() - except EOFError: # pragma: no cover # when the stdout is closed without exit - break # pragma: no cover - if not message: + content = read_line() + if not content: continue flush() # flush any output generated before try: - parsed_message = json.loads(message) + if sys.version_info[0] == 2: # pragma: no branch # python 2 does not support loading from bytearray + content = content.decode() # pragma: no cover + parsed_message = json.loads(content) result_file = parsed_message["result"] except Exception: # noqa # ignore messages that are not valid JSON and contain a valid result path - print(f"Backend: incorrect request to backend: {message}", file=sys.stderr) + print("Backend: incorrect request to backend: {}".format(content), file=sys.stderr) flush() else: result = {} @@ -83,12 +88,28 @@ def run(argv): except Exception: # noqa traceback.print_exc() finally: - print(f"Backend: Wrote response {result} to {result_file}") # used as done marker by frontend + # used as done marker by frontend + print("Backend: Wrote response {} to {}".format(result, result_file)) flush() # pragma: no branch if reuse_process is False: # pragma: no branch # no test for reuse process in root test env break return 0 +def read_line(): + # for some reason input() seems to break (hangs forever) so instead we read byte by byte the unbuffered stream + content = bytearray() + while True: + try: + char = os.read(0, 1) + except EOFError: # pragma: no cover # when the stdout is closed without exit + break # pragma: no cover + if char == b"\n": # pragma: no cover + break + if char != b"\r": # pragma: win32 cover + content += char + return content + + if __name__ == "__main__": sys.exit(run(sys.argv[1:])) diff --git a/src/tox/util/pep517/backend.pyi b/src/tox/util/pep517/backend.pyi index df773d4d..315d9afe 100644 --- a/src/tox/util/pep517/backend.pyi +++ b/src/tox/util/pep517/backend.pyi @@ -13,4 +13,5 @@ class BackendProxy: def _exit(self) -> None: ... def run(argv: Sequence[str]) -> int: ... +def read_line() -> bytearray: ... def flush() -> None: ... |