virtualshell 1.1.4__tar.gz → 1.1.5__tar.gz

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.
Files changed (62) hide show
  1. {virtualshell-1.1.4 → virtualshell-1.1.5}/PKG-INFO +1 -1
  2. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/src/binder.cpp +1 -1
  3. {virtualshell-1.1.4 → virtualshell-1.1.5}/pyproject.toml +1 -1
  4. virtualshell-1.1.5/src/virtualshell/_version.py +1 -0
  5. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/zero_copy_bridge_shell.py +72 -2
  6. virtualshell-1.1.4/src/virtualshell/_version.py +0 -1
  7. {virtualshell-1.1.4 → virtualshell-1.1.5}/.github/workflows/workflow.yml +0 -0
  8. {virtualshell-1.1.4 → virtualshell-1.1.5}/.gitignore +0 -0
  9. {virtualshell-1.1.4 → virtualshell-1.1.5}/CMakeLists.txt +0 -0
  10. {virtualshell-1.1.4 → virtualshell-1.1.5}/LICENSE +0 -0
  11. {virtualshell-1.1.4 → virtualshell-1.1.5}/README.md +0 -0
  12. {virtualshell-1.1.4 → virtualshell-1.1.5}/bench/bench.csv +0 -0
  13. {virtualshell-1.1.4 → virtualshell-1.1.5}/bench/bench.json +0 -0
  14. {virtualshell-1.1.4 → virtualshell-1.1.5}/bench/vs_bench.py +0 -0
  15. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/cmd_state.hpp +0 -0
  16. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/config.hpp +0 -0
  17. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/dev_debug.hpp +0 -0
  18. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/execution_result.hpp +0 -0
  19. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/helpers.hpp +0 -0
  20. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/io_pump.hpp +0 -0
  21. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/powershell_process.hpp +0 -0
  22. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/process.hpp +0 -0
  23. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/py_bridge.hpp +0 -0
  24. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/py_proxy.hpp +0 -0
  25. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/timeout_watcher.hpp +0 -0
  26. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/include/virtual_shell.hpp +0 -0
  27. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/src/io_pump.cpp +0 -0
  28. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/src/powershell_process.cpp +0 -0
  29. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/src/py_proxy.cpp +0 -0
  30. {virtualshell-1.1.4 → virtualshell-1.1.5}/cpp/src/virtual_shell.cpp +0 -0
  31. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/__init__.py +0 -0
  32. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/errors.py +0 -0
  33. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/generate_psobject.py +0 -0
  34. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/get-session.ps1 +0 -0
  35. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/save-session.ps1 +0 -0
  36. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/shell.py +0 -0
  37. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/win_pwsh.dll +0 -0
  38. {virtualshell-1.1.4 → virtualshell-1.1.5}/src/virtualshell/zero_copy_bridge.ps1 +0 -0
  39. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Getting started/Getting started.md +0 -0
  40. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Getting started/Installation.md +0 -0
  41. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Getting started/Quickstart.md +0 -0
  42. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Help/FAQ.md +0 -0
  43. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Help/Troubleshooting.md +0 -0
  44. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Home.md +0 -0
  45. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Project/Benchmarks.md +0 -0
  46. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Project/Changelog.md +0 -0
  47. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Project/Design & Architecture.md +0 -0
  48. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/API Overview.md +0 -0
  49. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/Asynchronous Execution.md +0 -0
  50. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/Configuration.md +0 -0
  51. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/Error Handling.md +0 -0
  52. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/Performance Tips.md +0 -0
  53. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/Running Scripts.md +0 -0
  54. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/Security Notes.md +0 -0
  55. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/Synchronous Execution.md +0 -0
  56. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/Zero-Copy Bridge.md +0 -0
  57. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/generate_psobject.md +0 -0
  58. {virtualshell-1.1.4 → virtualshell-1.1.5}/wiki/Usage/make_proxy.md +0 -0
  59. {virtualshell-1.1.4 → virtualshell-1.1.5}/win_pwsh_dll/CMakeLists.txt +0 -0
  60. {virtualshell-1.1.4 → virtualshell-1.1.5}/win_pwsh_dll/include/vs_shm.h +0 -0
  61. {virtualshell-1.1.4 → virtualshell-1.1.5}/win_pwsh_dll/src/object_serializer.cpp +0 -0
  62. {virtualshell-1.1.4 → virtualshell-1.1.5}/win_pwsh_dll/src/vs_shm.cpp +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: virtualshell
3
- Version: 1.1.4
3
+ Version: 1.1.5
4
4
  Summary: High-performance PowerShell bridge (C++ pybind11 backend)
5
5
  Keywords: powershell,automation,shell,cpp,pybind11
6
6
  Author: Kim-Andre Myrvold
@@ -276,7 +276,7 @@ PYBIND11_MODULE(_core, m) {
276
276
  }, "Create a new VirtualShell instance", py::arg("config"));
277
277
 
278
278
  // Metadata
279
- m.attr("__version__") = "1.1.4";
279
+ m.attr("__version__") = "1.1.5";
280
280
  m.attr("__author__") = "Kim-Andre Myrvold";
281
281
  }
282
282
 
@@ -9,7 +9,7 @@ build-backend = "scikit_build_core.build"
9
9
  [project]
10
10
  name = "virtualshell"
11
11
  description = "High-performance PowerShell bridge (C++ pybind11 backend)"
12
- version = "1.1.4"
12
+ version = "1.1.5"
13
13
  readme = "README.md"
14
14
  license = { file = "LICENSE" }
15
15
  authors = [{ name = "Kim-Andre Myrvold" }]
@@ -0,0 +1 @@
1
+ version = "1.1.5"
@@ -11,13 +11,16 @@ import os
11
11
  import time
12
12
  from concurrent.futures import Future
13
13
  from pathlib import Path
14
- from typing import Any, List, Optional, TYPE_CHECKING, Type
14
+ from typing import Any, List, Optional, TYPE_CHECKING, Type, Dict
15
+ from datetime import datetime
16
+ import base64
17
+ import json
15
18
  from dataclasses import dataclass
16
19
 
17
20
  if TYPE_CHECKING:
18
21
  from .shell import Shell
19
22
 
20
- __all__ = ["ZeroCopyBridge", "find_dll"]
23
+ __all__ = ["ZeroCopyBridge", "find_dll", "PSObject"]
21
24
 
22
25
  _IS_WINDOWS = os.name == "nt"
23
26
 
@@ -567,6 +570,73 @@ class PSObject:
567
570
  # Unknown type - return as string
568
571
  else:
569
572
  return text, str
573
+
574
+ def to_dict(
575
+ self,
576
+ *,
577
+ mode: str = "flat",
578
+ include_none: bool = True,
579
+ bytes_as: str = "base64", # "base64" | "list"
580
+ include_type: bool = False # adds __type per nested PSObject when mode="flat"
581
+ ) -> Dict[str, Any]:
582
+ """
583
+ Convert PSObject to a JSON-friendly dict.
584
+
585
+ modes:
586
+ - "flat": {"Name": "...", "Id": 1, ...}
587
+ - "typed": {"__type": "X.Y.Z", "props": { ... }}
588
+
589
+ bytes_as:
590
+ - "base64" (default): "AAEC..." string
591
+ - "list": [0,1,2,...] (slightly larger JSON)
592
+ """
593
+ def jsonify_scalar(val: Any) -> Any:
594
+ if isinstance(val, PSObject):
595
+ return val.to_dict(
596
+ mode=mode, include_none=include_none,
597
+ bytes_as=bytes_as, include_type=include_type
598
+ )
599
+ if isinstance(val, datetime):
600
+ return val.isoformat()
601
+ if isinstance(val, bytes):
602
+ if bytes_as == "list":
603
+ return list(val)
604
+ return base64.b64encode(val).decode("ascii")
605
+ if isinstance(val, (list, tuple, set)):
606
+ return [jsonify_scalar(v) for v in val]
607
+ if isinstance(val, dict):
608
+ return {str(k): jsonify_scalar(v) for k, v in val.items()}
609
+ # JSON doesn't support NaN/Inf well; convert to string if needed
610
+ if isinstance(val, float) and (val != val or val in (float("inf"), float("-inf"))):
611
+ return str(val)
612
+ # basic JSON types pass through
613
+ return val
614
+
615
+ # Special-case array-like PSObject parsed as {"Items": [...]}
616
+ is_array_like = ("[]" in getattr(self, "type_name", "")) or ("Array" in getattr(self, "type_name", ""))
617
+ if is_array_like and "Items" in self.properties:
618
+ arr = jsonify_scalar(self.properties["Items"].value)
619
+ if mode == "typed":
620
+ return {"__type": self.type_name, "items": arr}
621
+ else:
622
+ # flat mode returns bare list to embed nicely in JSON
623
+ return arr
624
+
625
+ # Regular object: build props dict
626
+ props: Dict[str, Any] = {}
627
+ for name, prop in self.properties.items():
628
+ val = jsonify_scalar(prop.value)
629
+ if val is None and not include_none:
630
+ continue
631
+ props[name] = val
632
+
633
+ if mode == "typed":
634
+ return {"__type": self.type_name, "props": props}
635
+ else:
636
+ if include_type:
637
+ # helpful when you still want a flat dict but keep type info
638
+ props["__type"] = self.type_name
639
+ return props
570
640
 
571
641
  # =============================================================================
572
642
  # INTEGRATED BRIDGE WITH SHELL
@@ -1 +0,0 @@
1
- version = "1.1.4"
File without changes
File without changes
File without changes
File without changes