From a475749aaf1838ac7fe2adb027f286369cfb3b92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Pich=C3=A9?= Date: Mon, 13 Jan 2020 09:00:39 -0500 Subject: [PATCH 1/6] get-poetry.py fallback to standard executables --- get-poetry.py | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/get-poetry.py b/get-poetry.py index 7a2b18d3997..25be35dcb67 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -197,8 +197,7 @@ def expanduser(path): POETRY_LIB_BACKUP = os.path.join(POETRY_HOME, "lib-backup") -BIN = """#!/usr/bin/env python -# -*- coding: utf-8 -*- +BIN = """# -*- coding: utf-8 -*- import glob import sys import os @@ -213,7 +212,7 @@ def expanduser(path): main() """ -BAT = u('@echo off\r\npython "{poetry_bin}" %*\r\n') +BAT = u('@echo off\r\n{python_executable} "{poetry_bin}" %*\r\n') PRE_MESSAGE = """# Welcome to {poetry}! @@ -585,23 +584,46 @@ def _make_lib(self, version): finally: gz.close() + def _which_python(self): + allowed_executables = ["python", "python3"] + if WINDOWS: + allowed_executables += ["py.exe -3", "py.exe -2"] + + for executable in allowed_executables: + try: + subprocess.check_call(executable + "--version", shell=True) + except subprocess.CalledProcessError: + continue + + return executable + + raise RuntimeError( + "No python executable found in shell environment. Tried: " + + str(allowed_executables) + ) + def make_bin(self): if not os.path.exists(POETRY_BIN): os.mkdir(POETRY_BIN, 0o755) + python_executable = self._which_python() + if WINDOWS: with open(os.path.join(POETRY_BIN, "poetry.bat"), "w") as f: f.write( u( BAT.format( + python_executable=python_executable, poetry_bin=os.path.join(POETRY_BIN, "poetry").replace( os.environ["USERPROFILE"], "%USERPROFILE%" - ) + ), ) ) ) with open(os.path.join(POETRY_BIN, "poetry"), "w", encoding="utf-8") as f: + if not WINDOWS: + f.write(u("#!/usr/bin/env {}\n".format(python_executable))) f.write(u(BIN)) if not WINDOWS: From 49343b166182aded67e44c61fb961977755105b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Pich=C3=A9?= Date: Mon, 13 Jan 2020 09:17:17 -0500 Subject: [PATCH 2/6] documentation update --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index cf8317294a2..7d26253f711 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,13 @@ curl -sSL https://raw.githubusercontent.com/python-poetry/poetry/master/get-poet Alternatively, you can download the `get-poetry.py` file and execute it separately. +The setup script must be able to find one of following executables in your shell's path environment: + +- `python` (which can be a py3 or py2 interpreter) +- `python3` +- `py.exe -3` (Windows) +- `py.exe -2` (Windows) + If you want to install prerelease versions, you can do so by passing `--preview` to `get-poetry.py`: ```bash From da3bb0345308fbd69458be6bb3758082d537b537 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Pich=C3=A9?= Date: Mon, 13 Jan 2020 09:32:50 -0500 Subject: [PATCH 3/6] fix typo due to cleanup --- get-poetry.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/get-poetry.py b/get-poetry.py index 25be35dcb67..9537da918a8 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -591,7 +591,7 @@ def _which_python(self): for executable in allowed_executables: try: - subprocess.check_call(executable + "--version", shell=True) + subprocess.check_call(executable + " --version", shell=True) except subprocess.CalledProcessError: continue From 33b101360774928ffb054494b2770c424e568594 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Pich=C3=A9?= Date: Tue, 21 Jan 2020 08:29:42 -0500 Subject: [PATCH 4/6] favor python3 over python2 when creating launcher --- get-poetry.py | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/get-poetry.py b/get-poetry.py index 9537da918a8..b88baf9fbf7 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -585,22 +585,35 @@ def _make_lib(self, version): gz.close() def _which_python(self): + """Decides which python executable we'll embed in the launcher script.""" allowed_executables = ["python", "python3"] if WINDOWS: allowed_executables += ["py.exe -3", "py.exe -2"] + version_matcher = re.compile(r"^Python (?P\d+)\.(?P\d+)\..+$") + fallback = None for executable in allowed_executables: try: - subprocess.check_call(executable + " --version", shell=True) + raw_version = subprocess.check_output( + executable + " --version", stderr=subprocess.STDOUT, shell=True + ).decode("utf-8") except subprocess.CalledProcessError: continue - return executable + match = version_matcher.match(raw_version.strip()) + if match and int(match.groupdict()["major"]) >= 3: + return executable + if fallback is None: + # keep this one as the fallback; it was the first valid exec we found. + fallback = executable + + if fallback is None: + raise RuntimeError( + "No python executable found in shell environment. Tried: " + + str(allowed_executables) + ) - raise RuntimeError( - "No python executable found in shell environment. Tried: " - + str(allowed_executables) - ) + return fallback def make_bin(self): if not os.path.exists(POETRY_BIN): From 5074e5fba52f0f059000b6ceb1942e29cba6f088 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Pich=C3=A9?= Date: Wed, 22 Jan 2020 11:05:49 -0500 Subject: [PATCH 5/6] launcher favors 3.5 and up, else the first valid one it finds. --- get-poetry.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/get-poetry.py b/get-poetry.py index b88baf9fbf7..231d3174587 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -590,6 +590,7 @@ def _which_python(self): if WINDOWS: allowed_executables += ["py.exe -3", "py.exe -2"] + # \d in regex ensures we can convert to int later version_matcher = re.compile(r"^Python (?P\d+)\.(?P\d+)\..+$") fallback = None for executable in allowed_executables: @@ -601,10 +602,11 @@ def _which_python(self): continue match = version_matcher.match(raw_version.strip()) - if match and int(match.groupdict()["major"]) >= 3: + if match and tuple(map(int, match.groups())) >= (3, 5): + # favor the first py3.5+ executable we can find. return executable if fallback is None: - # keep this one as the fallback; it was the first valid exec we found. + # keep this one as the fallback; it was the first valid executable we found. fallback = executable if fallback is None: From 442d025a8a02aa94bfa16251d64576c0b0eedc9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Pich=C3=A9?= Date: Thu, 23 Jan 2020 07:56:33 -0500 Subject: [PATCH 6/6] favor any py3 over py2, not just 3.5+ --- get-poetry.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/get-poetry.py b/get-poetry.py index 231d3174587..9760971eb06 100644 --- a/get-poetry.py +++ b/get-poetry.py @@ -602,8 +602,8 @@ def _which_python(self): continue match = version_matcher.match(raw_version.strip()) - if match and tuple(map(int, match.groups())) >= (3, 5): - # favor the first py3.5+ executable we can find. + if match and tuple(map(int, match.groups())) >= (3, 0): + # favor the first py3 executable we can find. return executable if fallback is None: # keep this one as the fallback; it was the first valid executable we found.