virtualshell 1.2.0__cp314-cp314-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ from __future__ import annotations
2
+
3
+
4
+ # start delvewheel patch
5
+ def _delvewheel_patch_1_13_1():
6
+ import os
7
+ if os.path.isdir(libs_dir := os.path.abspath(os.path.join(os.path.dirname(__file__), os.pardir, 'virtualshell.libs'))):
8
+ os.add_dll_directory(libs_dir)
9
+
10
+
11
+ _delvewheel_patch_1_13_1()
12
+ del _delvewheel_patch_1_13_1
13
+ # end delvewheel patch
14
+
15
+ from importlib import import_module
16
+ from typing import TYPE_CHECKING
17
+
18
+ if TYPE_CHECKING:
19
+ from .shell import ExecutionResult, BatchProgress, Shell, ExitCode, Config
20
+ from .zero_copy_bridge_shell import ZeroCopyBridge, PSObject
21
+
22
+ try:
23
+ from ._version import version as __version__
24
+ except Exception:
25
+ __version__ = "0.0.0"
26
+
27
+ from .errors import (
28
+ VirtualShellError,
29
+ PowerShellNotFoundError,
30
+ ExecutionTimeoutError,
31
+ ExecutionError,
32
+ )
33
+
34
+ __all__ = [
35
+ "VirtualShellError", "PowerShellNotFoundError",
36
+ "ExecutionTimeoutError", "ExecutionError",
37
+ "__version__", "Shell", "ExecutionResult", "BatchProgress", "ExitCode", "Config",
38
+ "ZeroCopyBridge", "PSObject",
39
+ ]
40
+
41
+ # Lazy loading of submodules and attributes to avoid importing compiled extension at package import time
42
+ def __getattr__(name: str):
43
+ if name in {"Shell", "ExecutionResult", "BatchProgress", "ExitCode", "Config"}:
44
+ mod = import_module(".shell", __name__)
45
+ obj = getattr(mod, name)
46
+ globals()[name] = obj
47
+ return obj
48
+ if name in {"ZeroCopyBridge", "PSObject"}:
49
+ mod = import_module(".zero_copy_bridge_shell", __name__)
50
+ obj = getattr(mod, name)
51
+ globals()[name] = obj
52
+ return obj
53
+
54
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
55
+
56
+ def __dir__():
57
+ return sorted(__all__)
@@ -0,0 +1,23 @@
1
+ """Guarded import of the compiled pybind11 extension.
2
+
3
+ Importing the extension fails if it was never built, or was built for a
4
+ different Python version or platform. Every import of it is funnelled
5
+ through here so that failure surfaces as a single, actionable ImportError
6
+ instead of a bare ``ModuleNotFoundError``.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import importlib
12
+ from pathlib import Path
13
+ from typing import Any
14
+
15
+ _CORE_MODULE_NAME = f"{__package__}._core"
16
+
17
+ try:
18
+ core: Any = importlib.import_module(_CORE_MODULE_NAME)
19
+ except Exception as e:
20
+ raise ImportError(
21
+ f"Failed to import the compiled extension '{_CORE_MODULE_NAME}'. "
22
+ "Make sure it was built and matches this Python/platform."
23
+ ) from e
Binary file
@@ -0,0 +1,27 @@
1
+ from __future__ import annotations
2
+
3
+ import importlib
4
+ from typing import TYPE_CHECKING
5
+
6
+ _CORE_MODULE_NAME = f"{__package__}._core"
7
+
8
+ try:
9
+ core = importlib.import_module(_CORE_MODULE_NAME)
10
+ except Exception as e:
11
+ raise ImportError(
12
+ f"Failed to import the compiled extension '{_CORE_MODULE_NAME}'. "
13
+ "Make sure it was built and matches this Python/platform."
14
+ ) from e
15
+
16
+ if TYPE_CHECKING:
17
+ from ._protocols import (
18
+ ExecutionResultLike as ExecutionResult,
19
+ BatchProgressLike as BatchProgress,
20
+ ConfigLike as Config,
21
+ VirtualShellLike as VirtualShell,
22
+ )
23
+ else:
24
+ ExecutionResult = core.ExecutionResult
25
+ BatchProgress = core.BatchProgress
26
+ Config = core.Config
27
+ VirtualShell = core.VirtualShell
@@ -0,0 +1,214 @@
1
+ from __future__ import annotations
2
+
3
+ from enum import IntEnum
4
+ import sys
5
+
6
+ from typing import (
7
+ Protocol,
8
+ Any,
9
+ Callable,
10
+ List,
11
+ Dict,
12
+ Self,
13
+ runtime_checkable,
14
+ )
15
+ from concurrent.futures import Future
16
+
17
+ class ExitCode(IntEnum):
18
+ SUCCESS = 0
19
+ GENERAL_ERROR = 1
20
+ TIMEOUT = -1
21
+ RESTARTING = -2 # Internal use; not from PowerShell itself.
22
+ NOT_RUNNING = -3 # Internal use; not from PowerShell itself.
23
+
24
+ @runtime_checkable
25
+ class ExecutionResultLike(Protocol):
26
+ out: Any
27
+ err: Any
28
+ exit_code: ExitCode
29
+ success: bool
30
+ execution_time: float
31
+
32
+ @runtime_checkable
33
+ class BatchProgressLike(Protocol):
34
+ currentCommand: int
35
+ totalCommands: int
36
+ lastResult: ExecutionResultLike
37
+ isComplete: bool
38
+ allResults: List[ExecutionResultLike]
39
+
40
+ @property
41
+ def header_bytes(self) -> int: ...
42
+
43
+ @property
44
+ def frame_bytes(self) -> int: ...
45
+
46
+ def __init__(self) -> None:
47
+ ...
48
+
49
+ @runtime_checkable
50
+ class ConfigLike(Protocol):
51
+ powershell_path: str = "pwsh"
52
+ working_directory: str = ""
53
+ capture_output: bool = True
54
+ capture_error: bool = True
55
+ auto_restart_on_timeout: bool = True
56
+ timeout_seconds: int = 30
57
+ environment: dict[str, str]
58
+ initial_commands: List[str]
59
+ restore_script_path: str = ""
60
+ session_snapshot_path: str = ""
61
+ stdin_buffer_size: int = 64 * 1024
62
+
63
+
64
+ def __init__(self) -> None:
65
+ ...
66
+
67
+
68
+ @runtime_checkable
69
+ class VirtualShellLike(Protocol):
70
+
71
+ # ---------------------------------------------------------
72
+ # Process control
73
+ # ---------------------------------------------------------
74
+ def start(self) -> bool:
75
+ ...
76
+
77
+ def stop(self, force: bool = False) -> None:
78
+ ...
79
+
80
+ def is_alive(self) -> bool:
81
+ ...
82
+
83
+ def is_restarting(self) -> bool:
84
+ ...
85
+
86
+ def get_process_id(self) -> int:
87
+ ...
88
+
89
+ # ---------------------------------------------------------
90
+ # Sync commands
91
+ # ---------------------------------------------------------
92
+ def execute(self, command: str, timeout_seconds: float = 0.0) -> ExecutionResultLike:
93
+ ...
94
+
95
+ def execute_batch(self, commands: List[str], timeout_seconds: float = 0.0) -> List[ExecutionResultLike]:
96
+ ...
97
+
98
+ def execute_script(
99
+ self,
100
+ script_path: str,
101
+ args: List[str] = ...,
102
+ timeout_seconds: float = 0.0,
103
+ dot_source: bool = False,
104
+ raise_on_error: bool = False
105
+ ) -> ExecutionResultLike:
106
+ ...
107
+
108
+ def execute_script_kv(
109
+ self,
110
+ script_path: str,
111
+ named_args: Dict[str, str],
112
+ timeout_seconds: float = 0.0,
113
+ dot_source: bool = False,
114
+ raise_on_error: bool = False
115
+ ) -> ExecutionResultLike:
116
+ ...
117
+
118
+ # ---------------------------------------------------------
119
+ # Async commands
120
+ # ---------------------------------------------------------
121
+ def execute_async(
122
+ self,
123
+ command: str,
124
+ callback: Callable[..., Any] | None = None,
125
+ timeout_seconds: float = 0.0
126
+ ) -> Future[ExecutionResultLike]:
127
+ ...
128
+
129
+ def execute_async_batch(
130
+ self,
131
+ commands: List[str],
132
+ progress_callback: Callable[..., Any] | None = None,
133
+ stop_on_first_error: bool = True,
134
+ per_command_timeout_seconds: float = 0.0
135
+ ) -> Future[List[ExecutionResultLike]]:
136
+ ...
137
+
138
+ def execute_async_script(
139
+ self,
140
+ script_path: str,
141
+ args: List[str] = ...,
142
+ callback: Callable[..., Any] | None = None,
143
+ timeout_seconds: float = 0.0,
144
+ dot_source: bool = False,
145
+ raise_on_error: bool = False
146
+ ) -> Future[ExecutionResultLike]:
147
+ ...
148
+
149
+ def execute_async_script_kv(
150
+ self,
151
+ script_path: str,
152
+ named_args: Dict[str, str],
153
+ timeout_seconds: float = 0.0,
154
+ dot_source: bool = False,
155
+ raise_on_error: bool = False
156
+ ) -> Future[ExecutionResultLike]:
157
+ ...
158
+
159
+ # ---------------------------------------------------------
160
+ # Direct I/O / env / modules
161
+ # ---------------------------------------------------------
162
+ def send_input(self, input: str) -> bool:
163
+ ...
164
+
165
+ def read_output(self, blocking: bool = False) -> str:
166
+ ...
167
+
168
+ def read_error(self, blocking: bool = False) -> str:
169
+ ...
170
+
171
+ def set_working_directory(self, directory: str) -> bool:
172
+ ...
173
+
174
+ def get_working_directory(self) -> str:
175
+ ...
176
+
177
+ def set_environment_variable(self, name: str, value: str) -> bool:
178
+ ...
179
+
180
+ def get_environment_variable(self, name: str) -> str:
181
+ ...
182
+
183
+ def is_module_available(self, module_name: str) -> bool:
184
+ ...
185
+
186
+ def import_module(self, module_name: str) -> bool:
187
+ ...
188
+
189
+ def get_powershell_version(self) -> str:
190
+ ...
191
+
192
+ def get_available_modules(self) -> List[str]:
193
+ ...
194
+
195
+ # ---------------------------------------------------------
196
+ # Configuration and Internals
197
+ # ---------------------------------------------------------
198
+ def get_config(self) -> ConfigLike:
199
+ ...
200
+
201
+ def update_config(self, config: ConfigLike) -> bool:
202
+ ...
203
+
204
+ def get_shared_ptr(self) -> Self:
205
+ ...
206
+
207
+ # ---------------------------------------------------------
208
+ # Context Manager
209
+ # ---------------------------------------------------------
210
+ def __enter__(self) -> "VirtualShellLike":
211
+ ...
212
+
213
+ def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
214
+ ...
@@ -0,0 +1 @@
1
+ version = "1.2.0"
virtualshell/errors.py ADDED
@@ -0,0 +1,4 @@
1
+ class VirtualShellError(RuntimeError): ...
2
+ class PowerShellNotFoundError(VirtualShellError): ...
3
+ class ExecutionTimeoutError(VirtualShellError): ...
4
+ class ExecutionError(VirtualShellError): ...