# Adopted from https://github.com/python-poetry/install.python-poetry.org/blob/main/install-poetry.py import sys # Eager version check so we fail nicely before possible syntax errors if sys.version_info < (3, 6): # noqa: UP036 sys.stdout.write("Poetry installer requires Python 3.6 or newer to run!\n") sys.exit(1) import argparse import json import os import re import shutil import subprocess import sysconfig import tempfile from contextlib import closing from contextlib import contextmanager from functools import cmp_to_key from io import UnsupportedOperation from pathlib import Path from typing import Optional from urllib.request import Request from urllib.request import urlopen SHELL = os.getenv("SHELL", "") WINDOWS = sys.platform.startswith("win") or (sys.platform == "cli" and os.name == "nt") MINGW = sysconfig.get_platform().startswith("mingw") MACOS = sys.platform == "darwin" FOREGROUND_COLORS = { "black": 30, "red": 31, "green": 32, "yellow": 33, "blue": 34, "magenta": 35, "cyan": 36, "white": 37, } BACKGROUND_COLORS = { "black": 40, "red": 41, "green": 42, "yellow": 43, "blue": 44, "magenta": 45, "cyan": 46, "white": 47, } OPTIONS = {"bold": 1, "underscore": 4, "blink": 5, "reverse": 7, "conceal": 8} def style(fg, bg, options): codes = [] if fg: codes.append(FOREGROUND_COLORS[fg]) if bg: codes.append(BACKGROUND_COLORS[bg]) if options: if not isinstance(options, (list, tuple)): options = [options] for option in options: codes.append(OPTIONS[option]) return "\033[{}m".format(";".join(map(str, codes))) STYLES = { "info": style("cyan", None, None), "comment": style("yellow", None, None), "success": style("green", None, None), "error": style("red", None, None), "warning": style("yellow", None, None), "b": style(None, None, ("bold",)), } def is_decorated(): if WINDOWS: return ( os.getenv("ANSICON") is not None or os.getenv("ConEmuANSI") == "ON" # noqa: SIM112 or os.getenv("Term") == "xterm" # noqa: SIM112 ) if not hasattr(sys.stdout, "fileno"): return False try: return os.isatty(sys.stdout.fileno()) except UnsupportedOperation: return False def is_interactive(): if not hasattr(sys.stdin, "fileno"): return False try: return os.isatty(sys.stdin.fileno()) except UnsupportedOperation: return False def colorize(style, text): if not is_decorated(): return text return f"{STYLES[style]}{text}\033[0m" def string_to_bool(value): value = value.lower() return value in {"true", "1", "y", "yes"} def data_dir() -> Path: if os.getenv("POETRY_HOME"): return Path(os.getenv("POETRY_HOME")).expanduser() if WINDOWS: base_dir = Path(_get_win_folder("CSIDL_APPDATA")) elif MACOS: base_dir = Path("~/Library/Application Support").expanduser() else: base_dir = Path(os.getenv("XDG_DATA_HOME", "~/.local/share")).expanduser() base_dir = base_dir.resolve() return base_dir / "pypoetry" def bin_dir() -> Path: if os.getenv("POETRY_HOME"): return Path(os.getenv("POETRY_HOME")).expanduser() / "bin" if WINDOWS and not MINGW: return Path(_get_win_folder("CSIDL_APPDATA")) / "Python/Scripts" else: return Path("~/.local/bin").expanduser() def _get_win_folder_from_registry(csidl_name): import winreg as _winreg shell_folder_name = { "CSIDL_APPDATA": "AppData", "CSIDL_COMMON_APPDATA": "Common AppData", "CSIDL_LOCAL_APPDATA": "Local AppData", }[csidl_name] key = _winreg.OpenKey( _winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders", ) path, _ = _winreg.QueryValueEx(key, shell_folder_name) return path def _get_win_folder_with_ctypes(csidl_name): import ctypes csidl_const = { "CSIDL_APPDATA": 26, "CSIDL_COMMON_APPDATA": 35, "CSIDL_LOCAL_APPDATA": 28, }[csidl_name] buf = ctypes.create_unicode_buffer(1024) ctypes.windll.shell32.SHGetFolderPathW(None, csidl_const, None, 0, buf) # Downgrade to short path name if have highbit chars. See # . has_high_char = False for c in buf: if ord(c) > 255: has_high_char = True break if has_high_char: buf2 = ctypes.create_unicode_buffer(1024) if ctypes.windll.kernel32.GetShortPathNameW(buf.value, buf2, 1024): buf = buf2 return buf.value if WINDOWS: try: from ctypes import windll # noqa: F401 _get_win_folder = _get_win_folder_with_ctypes except ImportError: _get_win_folder = _get_win_folder_from_registry