virtualenv update
This commit is contained in:
parent
03ac6f2277
commit
28ed7e2e42
@ -4,11 +4,12 @@ import logging
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
from virtualenv.discovery.builtin import Builtin
|
from virtualenv.discovery.builtin import Builtin
|
||||||
from virtualenv.discovery.builtin import check_path
|
from virtualenv.discovery.builtin import fs_path_id
|
||||||
from virtualenv.discovery.builtin import get_paths
|
from virtualenv.discovery.builtin import get_paths
|
||||||
|
from virtualenv.discovery.builtin import IS_WIN
|
||||||
from virtualenv.discovery.builtin import LazyPathDump
|
from virtualenv.discovery.builtin import LazyPathDump
|
||||||
|
from virtualenv.discovery.builtin import path_exe_finder
|
||||||
from virtualenv.discovery.builtin import PathPythonInfo
|
from virtualenv.discovery.builtin import PathPythonInfo
|
||||||
from virtualenv.discovery.builtin import possible_specs
|
|
||||||
from virtualenv.discovery.py_info import PythonInfo
|
from virtualenv.discovery.py_info import PythonInfo
|
||||||
from virtualenv.discovery.py_spec import PythonSpec
|
from virtualenv.discovery.py_spec import PythonSpec
|
||||||
|
|
||||||
@ -43,43 +44,67 @@ def get_interpreter(key, try_first_with, app_data=None, env=None):
|
|||||||
# Current interpreter is removed
|
# Current interpreter is removed
|
||||||
|
|
||||||
|
|
||||||
def propose_interpreters(spec, try_first_with, app_data, env=None):
|
def propose_interpreters( # noqa: C901, PLR0912, PLR0915
|
||||||
|
spec: PythonSpec,
|
||||||
|
try_first_with,
|
||||||
|
app_data=None,
|
||||||
|
env=None,
|
||||||
|
):
|
||||||
# 0. try with first
|
# 0. try with first
|
||||||
env = os.environ if env is None else env
|
env = os.environ if env is None else env
|
||||||
|
tested_exes: set[str] = set()
|
||||||
for py_exe in try_first_with:
|
for py_exe in try_first_with:
|
||||||
path = os.path.abspath(py_exe)
|
path = os.path.abspath(py_exe)
|
||||||
try:
|
try:
|
||||||
# Windows Store Python does not work with os.path.exists, but does for os.lstat
|
os.lstat(path) # Windows Store Python does not work with os.path.exists, but does for os.lstat
|
||||||
os.lstat(path)
|
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
yield PythonInfo.from_exe(os.path.abspath(path), app_data, env=env), True
|
exe_raw = os.path.abspath(path)
|
||||||
|
exe_id = fs_path_id(exe_raw)
|
||||||
|
if exe_id in tested_exes:
|
||||||
|
continue
|
||||||
|
tested_exes.add(exe_id)
|
||||||
|
yield PythonInfo.from_exe(exe_raw, app_data, env=env), True
|
||||||
|
|
||||||
# 1. if it's a path and exists
|
# 1. if it's a path and exists
|
||||||
if spec.path is not None:
|
if spec.path is not None:
|
||||||
try:
|
try:
|
||||||
# Windows Store Python does not work with os.path.exists, but does for os.lstat
|
os.lstat(spec.path) # Windows Store Python does not work with os.path.exists, but does for os.lstat
|
||||||
os.lstat(spec.path)
|
|
||||||
except OSError:
|
except OSError:
|
||||||
if spec.is_abs:
|
if spec.is_abs:
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
yield PythonInfo.from_exe(os.path.abspath(spec.path), app_data, env=env), True
|
exe_raw = os.path.abspath(spec.path)
|
||||||
|
exe_id = fs_path_id(exe_raw)
|
||||||
|
if exe_id not in tested_exes:
|
||||||
|
tested_exes.add(exe_id)
|
||||||
|
yield PythonInfo.from_exe(exe_raw, app_data, env=env), True
|
||||||
if spec.is_abs:
|
if spec.is_abs:
|
||||||
return
|
return
|
||||||
|
else:
|
||||||
|
|
||||||
|
# 3. otherwise fallback to platform default logic
|
||||||
|
if IS_WIN:
|
||||||
|
from .windows import propose_interpreters # noqa: PLC0415
|
||||||
|
|
||||||
|
for interpreter in propose_interpreters(spec, app_data, env):
|
||||||
|
exe_raw = str(interpreter.executable)
|
||||||
|
exe_id = fs_path_id(exe_raw)
|
||||||
|
if exe_id in tested_exes:
|
||||||
|
continue
|
||||||
|
tested_exes.add(exe_id)
|
||||||
|
yield interpreter, True
|
||||||
# finally just find on path, the path order matters (as the candidates are less easy to control by end user)
|
# finally just find on path, the path order matters (as the candidates are less easy to control by end user)
|
||||||
paths = get_paths(env)
|
find_candidates = path_exe_finder(spec)
|
||||||
tested_exes = set()
|
for pos, path in enumerate(get_paths(env)):
|
||||||
for pos, path in enumerate(paths):
|
logging.debug(LazyPathDump(pos, path, env))
|
||||||
path_str = str(path)
|
for exe, impl_must_match in find_candidates(path):
|
||||||
logging.debug(LazyPathDump(pos, path_str, env))
|
exe_raw = str(exe)
|
||||||
for candidate, match in possible_specs(spec):
|
exe_id = fs_path_id(exe_raw)
|
||||||
found = check_path(candidate, path_str)
|
if exe_id in tested_exes:
|
||||||
if found is not None:
|
continue
|
||||||
exe = os.path.abspath(found)
|
tested_exes.add(exe_id)
|
||||||
if exe not in tested_exes:
|
interpreter = PathPythonInfo.from_exe(exe_raw, app_data, raise_on_error=False, env=env)
|
||||||
tested_exes.add(exe)
|
|
||||||
interpreter = PathPythonInfo.from_exe(exe, app_data, raise_on_error=False, env=env)
|
|
||||||
if interpreter is not None:
|
if interpreter is not None:
|
||||||
yield interpreter, match
|
yield interpreter, impl_must_match
|
||||||
|
Loading…
Reference in New Issue
Block a user