Skip to content

Commit 3ed7b8c

Browse files
author
Thierry RAMORASOAVINA
committed
Fix the detection of unhappy installation paths under Windows
- External tools like VSCode can modify for example the case of the path saved in `sys.executable` - As a general rule a pathlib.Path object is always built. Depending on the OS either a PosixPath or a WindowsPath instance is created. This later sees case-insensitive paths.
1 parent a2b0668 commit 3ed7b8c

File tree

2 files changed

+54
-21
lines changed

2 files changed

+54
-21
lines changed

CHANGELOG.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
- (`sklearn`) `n_feature_parts` parameter to the supervised estimators
1313

1414
### Fixed
15-
- (`sklearn`) Default value of `n_features` for the supervised estimators
15+
- (`sklearn`) Default value of `n_features` for the supervised estimators.
16+
- *Internals*:
17+
- Detection of unsupported installation modes on Windows operating systems.
1618

1719
## 11.0.0.2 - 2026-01-26
1820

khiops/core/internals/runner.py

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -542,14 +542,14 @@ def _build_status_message(self):
542542
assert (
543543
os.path.basename(Path(__file__).parents[2]) == "khiops"
544544
), "Please fix the `Path.parents` in this method "
545-
library_root_dir = Path(__file__).parents[2]
545+
library_root_dir_path = Path(__file__).parents[2]
546546

547547
status_msg = "Khiops Python library settings\n"
548548
status_msg += f"version : {khiops.__version__}\n"
549549
status_msg += f"runner class : {self.__class__.__name__}\n"
550550
status_msg += f"root temp dir : {self.root_temp_dir}\n"
551551
status_msg += f"sample datasets dir : {samples_dir_path}\n"
552-
status_msg += f"library root dir : {library_root_dir}\n"
552+
status_msg += f"library root dir : {library_root_dir_path}\n"
553553

554554
error_list = []
555555

@@ -1127,7 +1127,7 @@ def _initialize_khiops_version(self):
11271127
stacklevel=3,
11281128
)
11291129

1130-
def _detect_library_installation_incompatibilities(self, library_root_dir):
1130+
def _detect_library_installation_incompatibilities(self, library_root_dir_path):
11311131
"""Detects known incompatible installations of this library
11321132
in the 3 installation modes see `_infer_khiops_installation_method`
11331133
(binary+pip, conda, conda-based)
@@ -1137,7 +1137,7 @@ def _detect_library_installation_incompatibilities(self, library_root_dir):
11371137
11381138
Parameters
11391139
----------
1140-
library_root_dir : PosixPath
1140+
library_root_dir_path : Path
11411141
path to this current library
11421142
11431143
@@ -1172,10 +1172,15 @@ def _detect_library_installation_incompatibilities(self, library_root_dir):
11721172
)
11731173
warning_list.append(warning)
11741174

1175+
conda_prefix_path = Path(os.environ["CONDA_PREFIX"])
11751176
# the conda environment must match the library installation
1176-
if not str(library_root_dir).startswith(os.environ["CONDA_PREFIX"]):
1177+
if (
1178+
conda_prefix_path.parts
1179+
!= library_root_dir_path.parts[: len(conda_prefix_path.parts)]
1180+
):
11771181
error = (
1178-
f"Khiops Python library installation path '{library_root_dir}' "
1182+
"Khiops Python library installation "
1183+
f"path '{library_root_dir_path}' "
11791184
"does not match the current Conda environment "
11801185
f"'{os.environ['CONDA_PREFIX']}'. "
11811186
"Either deactivate the current Conda environment "
@@ -1184,9 +1189,13 @@ def _detect_library_installation_incompatibilities(self, library_root_dir):
11841189
"Go to https://khiops.org for instructions.\n"
11851190
)
11861191
error_list.append(error)
1192+
khiops_path = Path(self.khiops_path)
11871193
# the khiops executable path must also match the conda environment one
11881194
# meaning khiops core was installed using conda
1189-
if not self.khiops_path.startswith(os.environ["CONDA_PREFIX"]):
1195+
if (
1196+
conda_prefix_path.parts
1197+
!= khiops_path.parts[: len(conda_prefix_path.parts)]
1198+
):
11901199
error = (
11911200
f"Khiops binary path '{self.khiops_path}' "
11921201
"does not match the current Conda environment "
@@ -1226,32 +1235,39 @@ def _detect_library_installation_incompatibilities(self, library_root_dir):
12261235
# no further check cannot be performed)
12271236
base_dir = _infer_base_dir_for_conda_based_or_pip_installations()
12281237
if len(base_dir) > 0:
1238+
# Store in separate variable(s) to abstract over
1239+
# the path casing on Windows
1240+
sys_base_prefix_path = Path(sys.base_prefix)
1241+
sys_prefix_path = Path(sys.prefix)
12291242
# within a virtual env, sys.prefix is set to the virtual env folder
12301243
# whereas sys.base_prefix remains unchanged.
12311244
# Please be aware that if a python executable of a virtual env is used
12321245
# the corresponding virtual env is activated and sys.prefix updated
1233-
if sys.base_prefix != sys.prefix:
1246+
if sys_base_prefix_path != sys_prefix_path:
12341247
# the python executable location
12351248
# (within the virtual env or the conda-based env)
12361249
# must match the library installation
1250+
sys_executable_direct_parent = Path(sys.executable).parents[0]
1251+
sys_executable_grand_parent = Path(sys.executable).parents[1]
1252+
base_dir_path = Path(base_dir)
12371253
if (
12381254
platform.system() == "Windows"
12391255
and
12401256
# Under Windows, there are two cases :
12411257
(
12421258
# for conda-based installations python is inside 'base_dir'
1243-
str(Path(sys.executable).parents[0]) != base_dir
1259+
sys_executable_direct_parent != base_dir_path
12441260
and
12451261
# for 'binary+pip' installations (within a virtual env)
12461262
# python is inside 'base_dir'/Scripts
1247-
str(Path(sys.executable).parents[1]) != base_dir
1263+
sys_executable_grand_parent != base_dir_path
12481264
)
12491265
# Under Linux or MacOS a bin/ folder exists
1250-
or str(Path(sys.executable).parents[1]) != base_dir
1266+
or sys_executable_grand_parent != base_dir_path
12511267
):
12521268
error = (
12531269
"Khiops Python library installation path "
1254-
f"'{library_root_dir}' "
1270+
f"'{library_root_dir_path}' "
12551271
"does not match the current python environment "
12561272
f"('{sys.executable}'). "
12571273
"Go to https://khiops.org for instructions "
@@ -1260,14 +1276,19 @@ def _detect_library_installation_incompatibilities(self, library_root_dir):
12601276
)
12611277
error_list.append(error)
12621278
else:
1279+
sys_executable_path = Path(sys.executable)
1280+
sys_base_prefix_path = Path(sys.base_prefix)
12631281
# the installation is not within a virtual env
12641282
# (sys.base_prefix == sys.prefix)
1265-
if not sys.executable.startswith(sys.base_prefix):
1283+
if (
1284+
sys_base_prefix_path.parts
1285+
!= sys_executable_path.parts[: len(sys_base_prefix_path.parts)]
1286+
):
12661287
# the executable is not the expected one
12671288
# (the system-wide python)
12681289
error = (
12691290
"Khiops Python library installed in "
1270-
f"'{library_root_dir}' "
1291+
f"'{library_root_dir_path}' "
12711292
"is run with an unexpected executable "
12721293
f"'{sys.executable}'. "
12731294
"The system-wide python located in "
@@ -1280,15 +1301,25 @@ def _detect_library_installation_incompatibilities(self, library_root_dir):
12801301
error_list.append(error)
12811302
# fetch the 'User site' site-packages path
12821303
# which is already adapted for each OS (Windows, MacOS, Linux)
1283-
user_site_packages_dir = site.getusersitepackages()
1284-
if not str(library_root_dir).startswith(user_site_packages_dir):
1304+
user_site_packages_path = Path(site.getusersitepackages())
1305+
if (
1306+
user_site_packages_path.parts
1307+
!= library_root_dir_path.parts[
1308+
: len(user_site_packages_path.parts)
1309+
]
1310+
):
12851311
# the library is not installed on the 'User site'
1286-
if not str(library_root_dir).startswith(sys.base_prefix):
1312+
if (
1313+
sys_base_prefix_path.parts
1314+
!= library_root_dir_path.parts[
1315+
: len(sys_base_prefix_path.parts)
1316+
]
1317+
):
12871318
# the library is supposed to be installed system-wide,
12881319
# but it seems that the location is wrong
12891320
error = (
12901321
"Khiops Python library installation path "
1291-
f"'{library_root_dir}' "
1322+
f"'{library_root_dir_path}' "
12921323
"does not match the system-wide Python prefix in "
12931324
f"'{sys.base_prefix}'. "
12941325
"Go to https://khiops.org for instructions "
@@ -1303,10 +1334,10 @@ def _build_status_message(self):
13031334
# Call the parent's method
13041335
status_msg, error_list, warning_list = super()._build_status_message()
13051336

1306-
library_root_dir = Path(__file__).parents[2]
1337+
library_root_dir_path = Path(__file__).parents[2]
13071338

13081339
installation_errors, installation_warnings = (
1309-
self._detect_library_installation_incompatibilities(library_root_dir)
1340+
self._detect_library_installation_incompatibilities(library_root_dir_path)
13101341
)
13111342

13121343
# Build the messages for install type and mpi

0 commit comments

Comments
 (0)