Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve Windows support #171

Merged
Merged
14 changes: 14 additions & 0 deletions .changelog/_unreleased.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,20 @@ type = "feature"
description = "Make Rust builds respect Cargo.lock when present"
author = "[email protected]"

[[entries]]
id = "ebe30d77-1206-4437-8aa2-7373e9335926"
type = "improvement"
description = "Improve Windows support in `krakenw` by supporting the `PYENV` env-var and using the right `pyhon.exe` path on Windows"
author = "@NiklasRosenstein"
component = "kraken-wrapper"

[[entries]]
id = "a8200c89-b05a-46ce-895c-c4a4f5a736a6"
type = "fix"
description = "Do not use `dmypy` on Windows"
author = "@NiklasRosenstein"
component = "kraken-build"

[[entries]]
id = "db65bd12-a9d1-472c-a38b-6f889cdda683"
type = "improvement"
Expand Down
23 changes: 18 additions & 5 deletions kraken-build/src/kraken/common/findpython.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,25 @@ def get_candidates(
if match:
yield {"path": str(command), "exact_version": match.group(1)}

# pyenv
pyenv_versions = Path("~/.pyenv/versions").expanduser()
if check_pyenv and pyenv_versions.is_dir():
# pyenv (+Windows)
if check_pyenv:
pyenv_versions = Path("~/.pyenv/versions").expanduser()
if not pyenv_versions.is_dir():
pyenv = os.getenv("PYENV")
if pyenv:
pyenv_versions = Path(pyenv).expanduser().joinpath("versions")
elif os.name == "nt":
pyenv_versions = Path("~/.pyenv/pyenv-win/versions").expanduser()
else:
pyenv_versions = None

if pyenv_versions and pyenv_versions.is_dir():
for item in pyenv_versions.iterdir():
if re.match(r"\d+\.\d+\.\d+$", item.name) and item.is_dir():
yield {"path": str(item / "bin" / "python"), "exact_version": item.name}
if os.name == "nt":
yield {"path": str(item / "python.exe"), "exact_version": item.name}
else:
yield {"path": str(item / "bin" / "python"), "exact_version": item.name}

yield {"path": sys.executable, "exact_version": ".".join(map(str, sys.version_info[:3]))}

Expand Down Expand Up @@ -192,7 +205,7 @@ def evaluate_candidates(
if version is None:
try:
version = get_python_interpreter_version(str(path))
except (subprocess.CalledProcessError, RuntimeError):
except (subprocess.CalledProcessError, RuntimeError, FileNotFoundError):
logger.debug("Failed to get version for Python interpreter %s", path, exc_info=True)
continue
if cache:
Expand Down
4 changes: 3 additions & 1 deletion kraken-build/src/kraken/std/python/tasks/base_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import shutil
import subprocess as sp
import sys
from collections.abc import Iterable, MutableMapping

from deprecated import deprecated
Expand Down Expand Up @@ -77,5 +78,6 @@ def execute(self) -> TaskStatus:
logger.warning('%s = "*"', dep)
return TaskStatus.failed("The %s dependencies are missing" % self.python_dependencies)
logger.info("%s", command)
result = sp.call(command, cwd=self.project.directory, env=env)
shell = sys.platform.startswith("win32") # Windows requires shell to find executable in path
result = sp.call(command, cwd=self.project.directory, env=env, shell=shell)
return self.handle_exit_code(result)
13 changes: 11 additions & 2 deletions kraken-build/src/kraken/std/python/tasks/mypy_task.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from __future__ import annotations

import logging
import sys
from collections.abc import MutableMapping, Sequence
from pathlib import Path

Expand All @@ -9,6 +11,8 @@

from .base_task import EnvironmentAwareDispatchTask

logger = logging.getLogger(__name__)


class MypyTask(EnvironmentAwareDispatchTask):
description = "Static type checking for Python code using Mypy."
Expand All @@ -24,7 +28,12 @@ class MypyTask(EnvironmentAwareDispatchTask):
# EnvironmentAwareDispatchTask

def get_execute_command_v2(self, env: MutableMapping[str, str]) -> list[str]:
entry_point = "dmypy" if self.use_daemon.get() else "mypy"
use_daemon = self.use_daemon.get()
if use_daemon and sys.platform.startswith("win32"):
use_daemon = False
logger.warning("Disable use of mypy daemon due to error in exit code on Windows")

entry_point = "dmypy" if use_daemon else "mypy"

if mypy_pex_bin := self.mypy_pex_bin.get():
# See https://pex.readthedocs.io/en/latest/api/vars.html
Expand All @@ -38,7 +47,7 @@ def get_execute_command_v2(self, env: MutableMapping[str, str]) -> list[str]:
# happens regularly but is hard to detect automatically).

status_file = (self.project.directory / ".dmypy.json").absolute()
if self.use_daemon.get():
if use_daemon:
command += ["--status-file", str(status_file), "run", "--"]
if mypy_pex_bin:
# Have mypy pick up the Python executable from the virtual environment that is activated automatically
Expand Down
Loading