summaryrefslogtreecommitdiff
path: root/cmd2
diff options
context:
space:
mode:
authorKevin Van Brunt <kmvanbrunt@gmail.com>2021-03-24 13:39:54 -0400
committerKevin Van Brunt <kmvanbrunt@gmail.com>2021-03-24 16:33:27 -0400
commitfc3c9b9e17e3cb89f771cc618517ebd968730938 (patch)
treefabbd6858c6090c78e80a037b3fbfdfd13f02123 /cmd2
parentae03c59de609878e068920380667c5fd45f26650 (diff)
downloadcmd2-git-fc3c9b9e17e3cb89f771cc618517ebd968730938.tar.gz
Removed ipy's access to the CLI's globals() dictionary
Diffstat (limited to 'cmd2')
-rw-r--r--cmd2/cmd2.py55
1 files changed, 29 insertions, 26 deletions
diff --git a/cmd2/cmd2.py b/cmd2/cmd2.py
index b6c44eb3..b04b7771 100644
--- a/cmd2/cmd2.py
+++ b/cmd2/cmd2.py
@@ -168,7 +168,7 @@ ipython_available = True
try:
# noinspection PyUnresolvedReferences,PyPackageRequirements
from IPython import ( # type: ignore[import]
- embed,
+ start_ipython,
)
except ImportError: # pragma: no cover
ipython_available = False
@@ -4197,34 +4197,21 @@ class Cmd(cmd.Cmd):
:return: True if running of commands should stop
"""
+ # noinspection PyPackageRequirements
+ from IPython.terminal.interactiveshell import (
+ TerminalInteractiveShell,
+ )
+ from IPython.terminal.ipapp import (
+ TerminalIPythonApp,
+ )
+ from traitlets.config.loader import (
+ Config as TraitletsConfig,
+ )
+
from .py_bridge import (
PyBridge,
)
- def load_ipy(ipy_locals: Dict[str, Any]) -> None:
- """
- Embed an IPython shell in an environment that is restricted to only the variables in this function
-
- :param ipy_locals: locals dictionary for the IPython environment
- """
- # Copy ipy_locals into this function's locals
- for key, val in ipy_locals.items():
- locals()[key] = val
-
- # Delete these names from the environment so IPython won't see them
- del key
- del val
- del ipy_locals
-
- # Start ipy shell
- embed(
- banner1=(
- 'Entering an embedded IPython shell. Type quit or <Ctrl>-d to exit.\n'
- 'Run Python code from external files with: run filename.py\n'
- ),
- exit_msg='Leaving IPython, back to {}'.format(sys.argv[0]),
- )
-
if self.in_pyscript():
self.perror("Recursively entering interactive Python shells is not allowed")
return
@@ -4241,7 +4228,23 @@ class Cmd(cmd.Cmd):
if self.self_in_py:
local_vars['self'] = self
- load_ipy(local_vars)
+ # Configure IPython
+ config = TraitletsConfig()
+ config.InteractiveShell.banner2 = (
+ 'Entering an embedded IPython shell. Type quit or <Ctrl>-d to exit.\n'
+ 'Run Python code from external files with: run filename.py\n'
+ )
+
+ # Start IPython
+ start_ipython(config=config, argv=[], user_ns=local_vars)
+
+ # The IPython application is a singleton and won't be recreated next time
+ # this function runs. That's a problem since the contents of local_vars
+ # may need to be changed. Therefore we must destroy all instances of the
+ # relevant classes.
+ TerminalIPythonApp.clear_instance()
+ TerminalInteractiveShell.clear_instance()
+
return py_bridge.stop
finally:
self._in_py = False