xmyshell 0.2.8__tar.gz → 0.2.10__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 (25) hide show
  1. {xmyshell-0.2.8/xmyshell.egg-info → xmyshell-0.2.10}/PKG-INFO +1 -1
  2. {xmyshell-0.2.8 → xmyshell-0.2.10}/pyproject.toml +1 -1
  3. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/kernel.py +27 -3
  4. {xmyshell-0.2.8 → xmyshell-0.2.10/xmyshell.egg-info}/PKG-INFO +1 -1
  5. {xmyshell-0.2.8 → xmyshell-0.2.10}/LICENSE +0 -0
  6. {xmyshell-0.2.8 → xmyshell-0.2.10}/README.md +0 -0
  7. {xmyshell-0.2.8 → xmyshell-0.2.10}/setup.cfg +0 -0
  8. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/__init__.py +0 -0
  9. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/__main__.py +0 -0
  10. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/completer.py +0 -0
  11. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/data/commands.json +0 -0
  12. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/environment.py +0 -0
  13. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/init.py +0 -0
  14. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/keybindings.py +0 -0
  15. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/lexer.py +0 -0
  16. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/main.py +0 -0
  17. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/meta.py +0 -0
  18. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/themes.py +0 -0
  19. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/update.py +0 -0
  20. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell/utils.py +0 -0
  21. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell.egg-info/SOURCES.txt +0 -0
  22. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell.egg-info/dependency_links.txt +0 -0
  23. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell.egg-info/entry_points.txt +0 -0
  24. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell.egg-info/requires.txt +0 -0
  25. {xmyshell-0.2.8 → xmyshell-0.2.10}/xmyshell.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xmyshell
3
- Version: 0.2.8
3
+ Version: 0.2.10
4
4
  Summary: XmyShell is a shell-like tool built on top of prompt_toolkit which provides a persistent Python runtime.
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "xmyshell"
3
- version = "0.2.8"
3
+ version = "0.2.10"
4
4
  description = "XmyShell is a shell-like tool built on top of prompt_toolkit which provides a persistent Python runtime."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -3,6 +3,7 @@ import os
3
3
  import sys
4
4
  import runpy
5
5
  import subprocess
6
+ import signal
6
7
  import shlex
7
8
  from .environment import namespace, aliases, xmyshell_alias, xmyshell_unalias
8
9
  from .utils import pywarning, pyerror, getcwd
@@ -14,6 +15,29 @@ def _reload() -> None:
14
15
  xmyshell_reload()
15
16
 
16
17
 
18
+ def _run(*args, **kwargs) -> subprocess.CompletedProcess:
19
+ # Block SIGINT in the parent while the child runs, so that a Ctrl-C
20
+ # delivered to the console/process group is handled solely by the child.
21
+ #
22
+ # Without this, subprocess.run() would catch the KeyboardInterrupt
23
+ # raised in the parent, wait briefly, and then send SIGKILL to the
24
+ # child -- which is not what a shell should do. Here the parent stays
25
+ # silent, the child receives SIGINT as usual, and the caller's
26
+ # KeyboardInterrupt handler only fires for Ctrl-C at the prompt.
27
+ #
28
+ # Must run on the main thread: signal.signal() is not allowed elsewhere.
29
+ kwargs_preexec = {}
30
+ if os.name == "posix":
31
+ def _reset_sigint():
32
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
33
+ kwargs_preexec["preexec_fn"] = _reset_sigint
34
+ old = signal.signal(signal.SIGINT, signal.SIG_IGN)
35
+ try:
36
+ return subprocess.run(*args, **kwargs_preexec, **kwargs)
37
+ finally:
38
+ signal.signal(signal.SIGINT, old)
39
+
40
+
17
41
  def xmyshell_source(path: str) -> None:
18
42
  _updated = runpy.run_path(
19
43
  path_name=os.path.expanduser(path),
@@ -162,7 +186,7 @@ def xmyshell_raw_command(cmd_line: str) -> int | None:
162
186
  return 0
163
187
 
164
188
  case "update":
165
- returncode = subprocess.run(
189
+ returncode = _run(
166
190
  [sys.executable, "-m", "xmyshell.update"]
167
191
  + (args[1:] if len(args) > 1 else [])
168
192
  ).returncode
@@ -312,11 +336,11 @@ def xmyshell(cmd_line: str) -> int:
312
336
  if os.name == "nt":
313
337
  cmd_line = _fix_first_word(cmd_line)
314
338
  if target_var:
315
- result = subprocess.run(
339
+ result = _run(
316
340
  cmd_line, shell=True, env=os.environ, capture_output=True, text=True
317
341
  )
318
342
  namespace[target_var] = result.stdout
319
343
  else:
320
- result = subprocess.run(cmd_line, shell=True, env=os.environ)
344
+ result = _run(cmd_line, shell=True, env=os.environ)
321
345
 
322
346
  return result.returncode
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: xmyshell
3
- Version: 0.2.8
3
+ Version: 0.2.10
4
4
  Summary: XmyShell is a shell-like tool built on top of prompt_toolkit which provides a persistent Python runtime.
5
5
  Requires-Python: >=3.12
6
6
  Description-Content-Type: text/markdown
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes