Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions news/137.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Corrected ``asdf`` and ``pyenv`` detection and usage which broke with the release of ``pythonfinder==2.0.0``
65 changes: 56 additions & 9 deletions src/pythonfinder/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
import os
import platform
import sys
import posixpath
import ntpath
import re
import shutil


def is_type_checking():
Expand All @@ -13,16 +17,19 @@ def is_type_checking():
return TYPE_CHECKING


PYENV_INSTALLED = bool(os.environ.get("PYENV_SHELL")) or bool(
os.environ.get("PYENV_ROOT")
)
ASDF_INSTALLED = bool(os.environ.get("ASDF_DIR"))
PYENV_ROOT = os.path.expanduser(
os.path.expandvars(os.environ.get("PYENV_ROOT", "~/.pyenv"))
)
# Check if the path is in Unix-style (Git Bash)
if PYENV_ROOT.startswith('/') and os.name == 'nt':
# Convert to Windows-style path
drive, tail = re.match(r"^/([a-zA-Z])/(.*)", PYENV_ROOT).groups()
PYENV_ROOT = drive.upper() + ":\\" + tail.replace('/', '\\')
PYENV_INSTALLED = shutil.which("pyenv") != None
ASDF_DATA_DIR = os.path.expanduser(
os.path.expandvars(os.environ.get("ASDF_DATA_DIR", "~/.asdf"))
)
ASDF_INSTALLED = shutil.which("asdf") != None
IS_64BIT_OS = None
SYSTEM_ARCH = platform.architecture()[0]

Expand All @@ -41,10 +48,50 @@ def is_type_checking():
"""


def get_shim_paths():
shim_paths = []
def join_path_for_platform(path, path_parts):
# If we're on Unix or Unix-like system
if os.name == 'posix' or sys.platform == 'linux':
return posixpath.join(path, *path_parts)
# If we're on Windows
elif os.name == 'nt' or sys.platform == 'win32':
return ntpath.join(path, *path_parts)
else:
raise Exception("Unknown environment")


def set_asdf_paths():
if ASDF_INSTALLED:
shim_paths.append(os.path.join(ASDF_DATA_DIR, "shims"))
python_versions = join_path_for_platform(ASDF_DATA_DIR, ["installs", "python"])
try:
# Get a list of all files and directories in the given path
all_files_and_dirs = os.listdir(python_versions)
# Filter out files and keep only directories
for name in all_files_and_dirs:
if os.path.isdir(os.path.join(python_versions, name)):
asdf_path = os.path.join(python_versions, name)
asdf_path = os.path.join(asdf_path, "bin")
os.environ['PATH'] = asdf_path + os.pathsep + os.environ['PATH']
except FileNotFoundError:
pass


def set_pyenv_paths():
if PYENV_INSTALLED:
shim_paths.append(os.path.join(PYENV_ROOT, "shims"))
return [os.path.normpath(os.path.normcase(p)) for p in shim_paths]
is_windows = False
if os.name == "nt":
python_versions = join_path_for_platform(PYENV_ROOT, ["pyenv-win", "versions"])
is_windows = True
else:
python_versions = join_path_for_platform(PYENV_ROOT, ["versions"])
try:
# Get a list of all files and directories in the given path
all_files_and_dirs = os.listdir(python_versions)
# Filter out files and keep only directories
for name in all_files_and_dirs:
if os.path.isdir(os.path.join(python_versions, name)):
pyenv_path = os.path.join(python_versions, name)
if not is_windows:
pyenv_path = os.path.join(pyenv_path, "bin")
os.environ['PATH'] = pyenv_path + os.pathsep + os.environ['PATH']
except FileNotFoundError:
pass
9 changes: 0 additions & 9 deletions src/pythonfinder/models/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,13 @@

from pydantic import BaseModel, Field, validator

from ..environment import get_shim_paths
from ..exceptions import InvalidPythonVersion
from ..utils import (
KNOWN_EXTS,
ensure_path,
expand_paths,
filter_pythons,
is_in_path,
looks_like_python,
normalize_path,
path_is_known_executable,
)

Expand Down Expand Up @@ -317,7 +314,6 @@ def _filter_children(self) -> Iterator[Path]:
return children

def _gen_children(self) -> Iterator:
shim_paths = get_shim_paths()
pass_name = self.name != self.path.name
pass_args = {"is_root": False, "only_python": self.only_python}
if pass_name:
Expand All @@ -330,8 +326,6 @@ def _gen_children(self) -> Iterator:
yield (self.path.as_posix(), self)
elif self.is_root:
for child in self._filter_children():
if any(is_in_path(str(child), shim) for shim in shim_paths):
continue
if self.only_python:
try:
entry = PathEntry.create(path=child, **pass_args)
Expand Down Expand Up @@ -372,7 +366,6 @@ def create(
:param str name: Name of the python version, e.g. ``anaconda3-5.3.0``
:return: A new instance of the class.
"""

target = ensure_path(path)
guessed_name = False
if not name:
Expand All @@ -393,8 +386,6 @@ def create(
if not guessed_name:
child_creation_args["name"] = _new.name
for pth, python in pythons.items():
if any(shim in normalize_path(str(pth)) for shim in get_shim_paths()):
continue
pth = ensure_path(pth)
children[pth.as_posix()] = PathEntry(
py_version=python, path=pth, **child_creation_args
Expand Down
21 changes: 11 additions & 10 deletions src/pythonfinder/models/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
ASDF_INSTALLED,
PYENV_INSTALLED,
PYENV_ROOT,
get_shim_paths,
)
from ..utils import (
dedup,
Expand Down Expand Up @@ -180,10 +179,6 @@ def _run_setup(self) -> SystemPath:
path_instances = [
ensure_path(p.strip('"'))
for p in path_order
if not any(
is_in_path(normalize_path(str(p)), normalize_path(shim))
for shim in get_shim_paths()
)
]
self.paths.update(
{
Expand Down Expand Up @@ -249,6 +244,16 @@ def _slice_in_paths(self, start_idx, paths) -> SystemPath:
self.path_order = path_order
return self

def _remove_shims(self):
path_copy = [p for p in self.path_order[:]]
new_order = []
for current_path in path_copy:
if not current_path.endswith("shims"):
normalized = normalize_path(current_path)
new_order.append(normalized)
new_order = [ensure_path(p).as_posix() for p in new_order]
self.path_order = new_order

def _remove_path(self, path) -> SystemPath:
path_copy = [p for p in reversed(self.path_order[:])]
new_order = []
Expand Down Expand Up @@ -306,7 +311,6 @@ def _setup_pyenv(self) -> SystemPath:
version_glob_path="versions/*",
ignore_unsupported=self.ignore_unsupported,
)
pyenv_index = None
try:
pyenv_index = self._get_last_instance(PYENV_ROOT)
except ValueError:
Expand All @@ -321,7 +325,7 @@ def _setup_pyenv(self) -> SystemPath:
self.paths[pyenv_finder.root] = pyenv_finder
self.paths.update(pyenv_finder.roots)
self.pyenv_finder = pyenv_finder
self._remove_path(os.path.join(PYENV_ROOT, "shims"))
self._remove_shims()
self._register_finder("pyenv", pyenv_finder)
return self

Expand Down Expand Up @@ -518,9 +522,6 @@ def create(
}
)
paths = [path, *paths]
paths = [
p for p in paths if not any(is_in_path(p, shim) for shim in get_shim_paths())
]
_path_objects = [ensure_path(p.strip('"')) for p in paths]
path_entries.update(
{
Expand Down
2 changes: 0 additions & 2 deletions src/pythonfinder/models/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,6 @@ class PythonFinder(PathEntry):
roots: Dict = Field(default_factory=lambda: defaultdict())
#: List of paths discovered during search
paths: List = Field(default_factory=lambda: list())
#: shim directory
shim_dir: str = "shims"
#: Versions discovered in the specified paths
_versions: Dict = Field(default_factory=lambda: defaultdict())
pythons_ref: Dict = Field(default_factory=lambda: defaultdict())
Expand Down
3 changes: 3 additions & 0 deletions src/pythonfinder/pythonfinder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from .models.common import FinderBaseModel
from .models.path import PathEntry, SystemPath
from .models.python import PythonVersion
from .environment import set_asdf_paths, set_pyenv_paths
from .utils import Iterable, version_re


Expand All @@ -32,6 +33,8 @@ def __eq__(self, other) -> bool:
return self.__hash__ == other.__hash__

def create_system_path(self) -> SystemPath:
set_asdf_paths()
set_pyenv_paths()
return SystemPath.create(
path=self.path_prepend,
system=self.system,
Expand Down