From 315892a9633a67bc78c27716c2ea7c2c4783051c Mon Sep 17 00:00:00 2001 From: Philipp A Date: Fri, 28 Jul 2023 10:55:22 +0200 Subject: [PATCH] Fix nushell --- src/hatch/env/plugin/interface.py | 3 ++- src/hatch/env/virtual.py | 5 ++++- src/hatch/utils/shells.py | 34 ++++++++++++++++--------------- 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/hatch/env/plugin/interface.py b/src/hatch/env/plugin/interface.py index 0d4ebb713..d6dc0400e 100644 --- a/src/hatch/env/plugin/interface.py +++ b/src/hatch/env/plugin/interface.py @@ -3,6 +3,7 @@ import os import sys from abc import ABC, abstractmethod +from collections.abc import Iterable from contextlib import contextmanager from os.path import isabs @@ -756,7 +757,7 @@ def build_environment_exists(self): """ return False - def enter_shell(self, name, path, args): + def enter_shell(self, name: str, path: str, args: Iterable[str]): """ Spawn a [shell](../../config/hatch.md#shell) within the environment. diff --git a/src/hatch/env/virtual.py b/src/hatch/env/virtual.py index c89139208..b1ce5720a 100644 --- a/src/hatch/env/virtual.py +++ b/src/hatch/env/virtual.py @@ -1,4 +1,7 @@ +from __future__ import annotations + from base64 import urlsafe_b64encode +from collections.abc import Iterable from contextlib import contextmanager, suppress from hashlib import sha256 from os.path import isabs @@ -141,7 +144,7 @@ def command_context(self): with self.safe_activation(): yield - def enter_shell(self, name, path, args): + def enter_shell(self, name: str, path: str, args: Iterable[str]): shell_executor = getattr(self.shells, f'enter_{name}', None) if shell_executor is None: # Manually activate in lieu of an activation script diff --git a/src/hatch/utils/shells.py b/src/hatch/utils/shells.py index 4c0888808..8820020ed 100644 --- a/src/hatch/utils/shells.py +++ b/src/hatch/utils/shells.py @@ -1,9 +1,10 @@ from __future__ import annotations import sys -from typing import TYPE_CHECKING, Callable +from typing import TYPE_CHECKING if TYPE_CHECKING: + from collections.abc import Callable, Iterable from types import FrameType from hatch.env.plugin.interface import EnvironmentInterface @@ -14,10 +15,10 @@ class ShellManager: def __init__(self, environment: EnvironmentInterface) -> None: self.environment = environment - def enter_cmd(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_cmd(self, path: str, args: Iterable[str], exe_dir: Path) -> None: self.environment.platform.exit_with_command([path or 'cmd', '/k', str(exe_dir / 'activate.bat')]) - def enter_powershell(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_powershell(self, path: str, args: Iterable[str], exe_dir: Path) -> None: self.environment.platform.exit_with_command( [ path or 'powershell', @@ -30,10 +31,10 @@ def enter_powershell(self, path: str, args: list[str], exe_dir: Path) -> None: ] ) - def enter_pwsh(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_pwsh(self, path: str, args: Iterable[str], exe_dir: Path) -> None: self.enter_powershell(path or 'pwsh', args, exe_dir) - def enter_xonsh(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_xonsh(self, path: str, args: Iterable[str], exe_dir: Path) -> None: if self.environment.platform.windows: with self.environment: self.environment.platform.exit_with_command( @@ -47,7 +48,7 @@ def enter_xonsh(self, path: str, args: list[str], exe_dir: Path) -> None: callback=lambda terminal: terminal.sendline(f'$PATH.insert(0, {str(exe_dir)!r})'), ) - def enter_bash(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_bash(self, path: str, args: Iterable[str], exe_dir: Path) -> None: if self.environment.platform.windows: self.environment.platform.exit_with_command( [path or 'bash', '--init-file', exe_dir / 'activate', *(args or ['-i'])] @@ -55,16 +56,16 @@ def enter_bash(self, path: str, args: list[str], exe_dir: Path) -> None: else: self.spawn_linux_shell(path or 'bash', args or ['-i'], script=exe_dir / 'activate') - def enter_fish(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_fish(self, path: str, args: Iterable[str], exe_dir: Path) -> None: self.spawn_linux_shell(path or 'fish', args or ['-i'], script=exe_dir / 'activate.fish') - def enter_zsh(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_zsh(self, path: str, args: Iterable[str], exe_dir: Path) -> None: self.spawn_linux_shell(path or 'zsh', args or ['-i'], script=exe_dir / 'activate') - def enter_ash(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_ash(self, path: str, args: Iterable[str], exe_dir: Path) -> None: self.spawn_linux_shell(path or 'ash', args or ['-i'], script=exe_dir / 'activate') - def enter_nu(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_nu(self, path: str, args: Iterable[str], exe_dir: Path) -> None: executable = path or 'nu' activation_script = exe_dir / 'activate.nu' if self.environment.platform.windows: @@ -72,12 +73,12 @@ def enter_nu(self, path: str, args: list[str], exe_dir: Path) -> None: [executable, '-c', f'source "{activation_script}"; "{executable}"'] ) else: - self.spawn_linux_shell(executable, args or None, script=activation_script) + self.spawn_linux_shell(executable, args, script=activation_script) - def enter_tcsh(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_tcsh(self, path: str, args: Iterable[str], exe_dir: Path) -> None: self.spawn_linux_shell(path or 'tcsh', args or ['-i'], script=exe_dir / 'activate.csh') - def enter_csh(self, path: str, args: list[str], exe_dir: Path) -> None: + def enter_csh(self, path: str, args: Iterable[str], exe_dir: Path) -> None: self.spawn_linux_shell(path or 'csh', args or ['-i'], script=exe_dir / 'activate.csh') if sys.platform == 'win32': @@ -85,7 +86,7 @@ def enter_csh(self, path: str, args: list[str], exe_dir: Path) -> None: def spawn_linux_shell( self, path: str, - args: list[str] | None = None, + args: Iterable[str] | None = None, *, script: Path | None = None, callback: Callable | None = None, @@ -97,7 +98,7 @@ def spawn_linux_shell( def spawn_linux_shell( self, path: str, - args: list[str] | None = None, + args: Iterable[str] | None = None, *, script: Path | None = None, callback: Callable | None = None, @@ -108,7 +109,8 @@ def spawn_linux_shell( import pexpect columns, lines = shutil.get_terminal_size() - terminal = pexpect.spawn(path, args=args, dimensions=(lines, columns)) + # pexpect only accepts lists + terminal = pexpect.spawn(path, args=list(args or ()), dimensions=(lines, columns)) def sigwinch_passthrough(sig: int, data: FrameType | None) -> None: new_columns, new_lines = shutil.get_terminal_size()