Skip to content

Commit 2293771

Browse files
authored
Fix pyenv usage for windows and linux. (#137)
* Fix pyenv usage for windows and linux. * Fix asd usage for windows and linux.
1 parent dcee887 commit 2293771

6 files changed

Lines changed: 71 additions & 30 deletions

File tree

news/137.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Corrected ``asdf`` and ``pyenv`` detection and usage which broke with the release of ``pythonfinder==2.0.0``

src/pythonfinder/environment.py

Lines changed: 56 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
import os
44
import platform
55
import sys
6+
import posixpath
7+
import ntpath
8+
import re
9+
import shutil
610

711

812
def is_type_checking():
@@ -13,16 +17,19 @@ def is_type_checking():
1317
return TYPE_CHECKING
1418

1519

16-
PYENV_INSTALLED = bool(os.environ.get("PYENV_SHELL")) or bool(
17-
os.environ.get("PYENV_ROOT")
18-
)
19-
ASDF_INSTALLED = bool(os.environ.get("ASDF_DIR"))
2020
PYENV_ROOT = os.path.expanduser(
2121
os.path.expandvars(os.environ.get("PYENV_ROOT", "~/.pyenv"))
2222
)
23+
# Check if the path is in Unix-style (Git Bash)
24+
if PYENV_ROOT.startswith('/') and os.name == 'nt':
25+
# Convert to Windows-style path
26+
drive, tail = re.match(r"^/([a-zA-Z])/(.*)", PYENV_ROOT).groups()
27+
PYENV_ROOT = drive.upper() + ":\\" + tail.replace('/', '\\')
28+
PYENV_INSTALLED = shutil.which("pyenv") != None
2329
ASDF_DATA_DIR = os.path.expanduser(
2430
os.path.expandvars(os.environ.get("ASDF_DATA_DIR", "~/.asdf"))
2531
)
32+
ASDF_INSTALLED = shutil.which("asdf") != None
2633
IS_64BIT_OS = None
2734
SYSTEM_ARCH = platform.architecture()[0]
2835

@@ -41,10 +48,50 @@ def is_type_checking():
4148
"""
4249

4350

44-
def get_shim_paths():
45-
shim_paths = []
51+
def join_path_for_platform(path, path_parts):
52+
# If we're on Unix or Unix-like system
53+
if os.name == 'posix' or sys.platform == 'linux':
54+
return posixpath.join(path, *path_parts)
55+
# If we're on Windows
56+
elif os.name == 'nt' or sys.platform == 'win32':
57+
return ntpath.join(path, *path_parts)
58+
else:
59+
raise Exception("Unknown environment")
60+
61+
62+
def set_asdf_paths():
4663
if ASDF_INSTALLED:
47-
shim_paths.append(os.path.join(ASDF_DATA_DIR, "shims"))
64+
python_versions = join_path_for_platform(ASDF_DATA_DIR, ["installs", "python"])
65+
try:
66+
# Get a list of all files and directories in the given path
67+
all_files_and_dirs = os.listdir(python_versions)
68+
# Filter out files and keep only directories
69+
for name in all_files_and_dirs:
70+
if os.path.isdir(os.path.join(python_versions, name)):
71+
asdf_path = os.path.join(python_versions, name)
72+
asdf_path = os.path.join(asdf_path, "bin")
73+
os.environ['PATH'] = asdf_path + os.pathsep + os.environ['PATH']
74+
except FileNotFoundError:
75+
pass
76+
77+
78+
def set_pyenv_paths():
4879
if PYENV_INSTALLED:
49-
shim_paths.append(os.path.join(PYENV_ROOT, "shims"))
50-
return [os.path.normpath(os.path.normcase(p)) for p in shim_paths]
80+
is_windows = False
81+
if os.name == "nt":
82+
python_versions = join_path_for_platform(PYENV_ROOT, ["pyenv-win", "versions"])
83+
is_windows = True
84+
else:
85+
python_versions = join_path_for_platform(PYENV_ROOT, ["versions"])
86+
try:
87+
# Get a list of all files and directories in the given path
88+
all_files_and_dirs = os.listdir(python_versions)
89+
# Filter out files and keep only directories
90+
for name in all_files_and_dirs:
91+
if os.path.isdir(os.path.join(python_versions, name)):
92+
pyenv_path = os.path.join(python_versions, name)
93+
if not is_windows:
94+
pyenv_path = os.path.join(pyenv_path, "bin")
95+
os.environ['PATH'] = pyenv_path + os.pathsep + os.environ['PATH']
96+
except FileNotFoundError:
97+
pass

src/pythonfinder/models/mixins.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,16 +14,13 @@
1414

1515
from pydantic import BaseModel, Field, validator
1616

17-
from ..environment import get_shim_paths
1817
from ..exceptions import InvalidPythonVersion
1918
from ..utils import (
2019
KNOWN_EXTS,
2120
ensure_path,
2221
expand_paths,
2322
filter_pythons,
24-
is_in_path,
2523
looks_like_python,
26-
normalize_path,
2724
path_is_known_executable,
2825
)
2926

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

319316
def _gen_children(self) -> Iterator:
320-
shim_paths = get_shim_paths()
321317
pass_name = self.name != self.path.name
322318
pass_args = {"is_root": False, "only_python": self.only_python}
323319
if pass_name:
@@ -330,8 +326,6 @@ def _gen_children(self) -> Iterator:
330326
yield (self.path.as_posix(), self)
331327
elif self.is_root:
332328
for child in self._filter_children():
333-
if any(is_in_path(str(child), shim) for shim in shim_paths):
334-
continue
335329
if self.only_python:
336330
try:
337331
entry = PathEntry.create(path=child, **pass_args)
@@ -372,7 +366,6 @@ def create(
372366
:param str name: Name of the python version, e.g. ``anaconda3-5.3.0``
373367
:return: A new instance of the class.
374368
"""
375-
376369
target = ensure_path(path)
377370
guessed_name = False
378371
if not name:
@@ -393,8 +386,6 @@ def create(
393386
if not guessed_name:
394387
child_creation_args["name"] = _new.name
395388
for pth, python in pythons.items():
396-
if any(shim in normalize_path(str(pth)) for shim in get_shim_paths()):
397-
continue
398389
pth = ensure_path(pth)
399390
children[pth.as_posix()] = PathEntry(
400391
py_version=python, path=pth, **child_creation_args

src/pythonfinder/models/path.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
ASDF_INSTALLED,
2828
PYENV_INSTALLED,
2929
PYENV_ROOT,
30-
get_shim_paths,
3130
)
3231
from ..utils import (
3332
dedup,
@@ -180,10 +179,6 @@ def _run_setup(self) -> SystemPath:
180179
path_instances = [
181180
ensure_path(p.strip('"'))
182181
for p in path_order
183-
if not any(
184-
is_in_path(normalize_path(str(p)), normalize_path(shim))
185-
for shim in get_shim_paths()
186-
)
187182
]
188183
self.paths.update(
189184
{
@@ -249,6 +244,16 @@ def _slice_in_paths(self, start_idx, paths) -> SystemPath:
249244
self.path_order = path_order
250245
return self
251246

247+
def _remove_shims(self):
248+
path_copy = [p for p in self.path_order[:]]
249+
new_order = []
250+
for current_path in path_copy:
251+
if not current_path.endswith("shims"):
252+
normalized = normalize_path(current_path)
253+
new_order.append(normalized)
254+
new_order = [ensure_path(p).as_posix() for p in new_order]
255+
self.path_order = new_order
256+
252257
def _remove_path(self, path) -> SystemPath:
253258
path_copy = [p for p in reversed(self.path_order[:])]
254259
new_order = []
@@ -306,7 +311,6 @@ def _setup_pyenv(self) -> SystemPath:
306311
version_glob_path="versions/*",
307312
ignore_unsupported=self.ignore_unsupported,
308313
)
309-
pyenv_index = None
310314
try:
311315
pyenv_index = self._get_last_instance(PYENV_ROOT)
312316
except ValueError:
@@ -321,7 +325,7 @@ def _setup_pyenv(self) -> SystemPath:
321325
self.paths[pyenv_finder.root] = pyenv_finder
322326
self.paths.update(pyenv_finder.roots)
323327
self.pyenv_finder = pyenv_finder
324-
self._remove_path(os.path.join(PYENV_ROOT, "shims"))
328+
self._remove_shims()
325329
self._register_finder("pyenv", pyenv_finder)
326330
return self
327331

@@ -518,9 +522,6 @@ def create(
518522
}
519523
)
520524
paths = [path, *paths]
521-
paths = [
522-
p for p in paths if not any(is_in_path(p, shim) for shim in get_shim_paths())
523-
]
524525
_path_objects = [ensure_path(p.strip('"')) for p in paths]
525526
path_entries.update(
526527
{

src/pythonfinder/models/python.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,6 @@ class PythonFinder(PathEntry):
5353
roots: Dict = Field(default_factory=lambda: defaultdict())
5454
#: List of paths discovered during search
5555
paths: List = Field(default_factory=lambda: list())
56-
#: shim directory
57-
shim_dir: str = "shims"
5856
#: Versions discovered in the specified paths
5957
_versions: Dict = Field(default_factory=lambda: defaultdict())
6058
pythons_ref: Dict = Field(default_factory=lambda: defaultdict())

src/pythonfinder/pythonfinder.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from .models.common import FinderBaseModel
88
from .models.path import PathEntry, SystemPath
99
from .models.python import PythonVersion
10+
from .environment import set_asdf_paths, set_pyenv_paths
1011
from .utils import Iterable, version_re
1112

1213

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

3435
def create_system_path(self) -> SystemPath:
36+
set_asdf_paths()
37+
set_pyenv_paths()
3538
return SystemPath.create(
3639
path=self.path_prepend,
3740
system=self.system,

0 commit comments

Comments
 (0)