Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
399
venv/Lib/site-packages/IPython/terminal/embed.py
Normal file
399
venv/Lib/site-packages/IPython/terminal/embed.py
Normal file
|
@ -0,0 +1,399 @@
|
|||
# encoding: utf-8
|
||||
"""
|
||||
An embedded IPython shell.
|
||||
"""
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
from IPython.core import ultratb, compilerop
|
||||
from IPython.core import magic_arguments
|
||||
from IPython.core.magic import Magics, magics_class, line_magic
|
||||
from IPython.core.interactiveshell import DummyMod, InteractiveShell
|
||||
from IPython.terminal.interactiveshell import TerminalInteractiveShell
|
||||
from IPython.terminal.ipapp import load_default_config
|
||||
|
||||
from traitlets import Bool, CBool, Unicode
|
||||
from IPython.utils.io import ask_yes_no
|
||||
|
||||
class KillEmbedded(Exception):pass
|
||||
|
||||
# kept for backward compatibility as IPython 6 was released with
|
||||
# the typo. See https://github.com/ipython/ipython/pull/10706
|
||||
KillEmbeded = KillEmbedded
|
||||
|
||||
# This is an additional magic that is exposed in embedded shells.
|
||||
@magics_class
|
||||
class EmbeddedMagics(Magics):
|
||||
|
||||
@line_magic
|
||||
@magic_arguments.magic_arguments()
|
||||
@magic_arguments.argument('-i', '--instance', action='store_true',
|
||||
help='Kill instance instead of call location')
|
||||
@magic_arguments.argument('-x', '--exit', action='store_true',
|
||||
help='Also exit the current session')
|
||||
@magic_arguments.argument('-y', '--yes', action='store_true',
|
||||
help='Do not ask confirmation')
|
||||
def kill_embedded(self, parameter_s=''):
|
||||
"""%kill_embedded : deactivate for good the current embedded IPython
|
||||
|
||||
This function (after asking for confirmation) sets an internal flag so
|
||||
that an embedded IPython will never activate again for the given call
|
||||
location. This is useful to permanently disable a shell that is being
|
||||
called inside a loop: once you've figured out what you needed from it,
|
||||
you may then kill it and the program will then continue to run without
|
||||
the interactive shell interfering again.
|
||||
|
||||
|
||||
Kill Instance Option:
|
||||
|
||||
If for some reasons you need to kill the location where the instance
|
||||
is created and not called, for example if you create a single
|
||||
instance in one place and debug in many locations, you can use the
|
||||
``--instance`` option to kill this specific instance. Like for the
|
||||
``call location`` killing an "instance" should work even if it is
|
||||
recreated within a loop.
|
||||
|
||||
.. note::
|
||||
|
||||
This was the default behavior before IPython 5.2
|
||||
|
||||
"""
|
||||
|
||||
args = magic_arguments.parse_argstring(self.kill_embedded, parameter_s)
|
||||
print(args)
|
||||
if args.instance:
|
||||
# let no ask
|
||||
if not args.yes:
|
||||
kill = ask_yes_no(
|
||||
"Are you sure you want to kill this embedded instance? [y/N] ", 'n')
|
||||
else:
|
||||
kill = True
|
||||
if kill:
|
||||
self.shell._disable_init_location()
|
||||
print("This embedded IPython instance will not reactivate anymore "
|
||||
"once you exit.")
|
||||
else:
|
||||
if not args.yes:
|
||||
kill = ask_yes_no(
|
||||
"Are you sure you want to kill this embedded call_location? [y/N] ", 'n')
|
||||
else:
|
||||
kill = True
|
||||
if kill:
|
||||
self.shell.embedded_active = False
|
||||
print("This embedded IPython call location will not reactivate anymore "
|
||||
"once you exit.")
|
||||
|
||||
if args.exit:
|
||||
# Ask-exit does not really ask, it just set internals flags to exit
|
||||
# on next loop.
|
||||
self.shell.ask_exit()
|
||||
|
||||
|
||||
@line_magic
|
||||
def exit_raise(self, parameter_s=''):
|
||||
"""%exit_raise Make the current embedded kernel exit and raise and exception.
|
||||
|
||||
This function sets an internal flag so that an embedded IPython will
|
||||
raise a `IPython.terminal.embed.KillEmbedded` Exception on exit, and then exit the current I. This is
|
||||
useful to permanently exit a loop that create IPython embed instance.
|
||||
"""
|
||||
|
||||
self.shell.should_raise = True
|
||||
self.shell.ask_exit()
|
||||
|
||||
|
||||
|
||||
class InteractiveShellEmbed(TerminalInteractiveShell):
|
||||
|
||||
dummy_mode = Bool(False)
|
||||
exit_msg = Unicode('')
|
||||
embedded = CBool(True)
|
||||
should_raise = CBool(False)
|
||||
# Like the base class display_banner is not configurable, but here it
|
||||
# is True by default.
|
||||
display_banner = CBool(True)
|
||||
exit_msg = Unicode()
|
||||
|
||||
# When embedding, by default we don't change the terminal title
|
||||
term_title = Bool(False,
|
||||
help="Automatically set the terminal title"
|
||||
).tag(config=True)
|
||||
|
||||
_inactive_locations = set()
|
||||
|
||||
@property
|
||||
def embedded_active(self):
|
||||
return (self._call_location_id not in InteractiveShellEmbed._inactive_locations)\
|
||||
and (self._init_location_id not in InteractiveShellEmbed._inactive_locations)
|
||||
|
||||
def _disable_init_location(self):
|
||||
"""Disable the current Instance creation location"""
|
||||
InteractiveShellEmbed._inactive_locations.add(self._init_location_id)
|
||||
|
||||
@embedded_active.setter
|
||||
def embedded_active(self, value):
|
||||
if value:
|
||||
InteractiveShellEmbed._inactive_locations.discard(
|
||||
self._call_location_id)
|
||||
InteractiveShellEmbed._inactive_locations.discard(
|
||||
self._init_location_id)
|
||||
else:
|
||||
InteractiveShellEmbed._inactive_locations.add(
|
||||
self._call_location_id)
|
||||
|
||||
def __init__(self, **kw):
|
||||
if kw.get('user_global_ns', None) is not None:
|
||||
raise DeprecationWarning(
|
||||
"Key word argument `user_global_ns` has been replaced by `user_module` since IPython 4.0.")
|
||||
|
||||
clid = kw.pop('_init_location_id', None)
|
||||
if not clid:
|
||||
frame = sys._getframe(1)
|
||||
clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
|
||||
self._init_location_id = clid
|
||||
|
||||
super(InteractiveShellEmbed,self).__init__(**kw)
|
||||
|
||||
# don't use the ipython crash handler so that user exceptions aren't
|
||||
# trapped
|
||||
sys.excepthook = ultratb.FormattedTB(color_scheme=self.colors,
|
||||
mode=self.xmode,
|
||||
call_pdb=self.pdb)
|
||||
|
||||
def init_sys_modules(self):
|
||||
"""
|
||||
Explicitly overwrite :mod:`IPython.core.interactiveshell` to do nothing.
|
||||
"""
|
||||
pass
|
||||
|
||||
def init_magics(self):
|
||||
super(InteractiveShellEmbed, self).init_magics()
|
||||
self.register_magics(EmbeddedMagics)
|
||||
|
||||
def __call__(self, header='', local_ns=None, module=None, dummy=None,
|
||||
stack_depth=1, global_ns=None, compile_flags=None, **kw):
|
||||
"""Activate the interactive interpreter.
|
||||
|
||||
__call__(self,header='',local_ns=None,module=None,dummy=None) -> Start
|
||||
the interpreter shell with the given local and global namespaces, and
|
||||
optionally print a header string at startup.
|
||||
|
||||
The shell can be globally activated/deactivated using the
|
||||
dummy_mode attribute. This allows you to turn off a shell used
|
||||
for debugging globally.
|
||||
|
||||
However, *each* time you call the shell you can override the current
|
||||
state of dummy_mode with the optional keyword parameter 'dummy'. For
|
||||
example, if you set dummy mode on with IPShell.dummy_mode = True, you
|
||||
can still have a specific call work by making it as IPShell(dummy=False).
|
||||
"""
|
||||
|
||||
# we are called, set the underlying interactiveshell not to exit.
|
||||
self.keep_running = True
|
||||
|
||||
# If the user has turned it off, go away
|
||||
clid = kw.pop('_call_location_id', None)
|
||||
if not clid:
|
||||
frame = sys._getframe(1)
|
||||
clid = '%s:%s' % (frame.f_code.co_filename, frame.f_lineno)
|
||||
self._call_location_id = clid
|
||||
|
||||
if not self.embedded_active:
|
||||
return
|
||||
|
||||
# Normal exits from interactive mode set this flag, so the shell can't
|
||||
# re-enter (it checks this variable at the start of interactive mode).
|
||||
self.exit_now = False
|
||||
|
||||
# Allow the dummy parameter to override the global __dummy_mode
|
||||
if dummy or (dummy != 0 and self.dummy_mode):
|
||||
return
|
||||
|
||||
# self.banner is auto computed
|
||||
if header:
|
||||
self.old_banner2 = self.banner2
|
||||
self.banner2 = self.banner2 + '\n' + header + '\n'
|
||||
else:
|
||||
self.old_banner2 = ''
|
||||
|
||||
if self.display_banner:
|
||||
self.show_banner()
|
||||
|
||||
# Call the embedding code with a stack depth of 1 so it can skip over
|
||||
# our call and get the original caller's namespaces.
|
||||
self.mainloop(local_ns, module, stack_depth=stack_depth,
|
||||
global_ns=global_ns, compile_flags=compile_flags)
|
||||
|
||||
self.banner2 = self.old_banner2
|
||||
|
||||
if self.exit_msg is not None:
|
||||
print(self.exit_msg)
|
||||
|
||||
if self.should_raise:
|
||||
raise KillEmbedded('Embedded IPython raising error, as user requested.')
|
||||
|
||||
|
||||
def mainloop(self, local_ns=None, module=None, stack_depth=0,
|
||||
display_banner=None, global_ns=None, compile_flags=None):
|
||||
"""Embeds IPython into a running python program.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
||||
local_ns, module
|
||||
Working local namespace (a dict) and module (a module or similar
|
||||
object). If given as None, they are automatically taken from the scope
|
||||
where the shell was called, so that program variables become visible.
|
||||
|
||||
stack_depth : int
|
||||
How many levels in the stack to go to looking for namespaces (when
|
||||
local_ns or module is None). This allows an intermediate caller to
|
||||
make sure that this function gets the namespace from the intended
|
||||
level in the stack. By default (0) it will get its locals and globals
|
||||
from the immediate caller.
|
||||
|
||||
compile_flags
|
||||
A bit field identifying the __future__ features
|
||||
that are enabled, as passed to the builtin :func:`compile` function.
|
||||
If given as None, they are automatically taken from the scope where
|
||||
the shell was called.
|
||||
|
||||
"""
|
||||
|
||||
if (global_ns is not None) and (module is None):
|
||||
raise DeprecationWarning("'global_ns' keyword argument is deprecated, and has been removed in IPython 5.0 use `module` keyword argument instead.")
|
||||
|
||||
if (display_banner is not None):
|
||||
warnings.warn("The display_banner parameter is deprecated since IPython 4.0", DeprecationWarning)
|
||||
|
||||
# Get locals and globals from caller
|
||||
if ((local_ns is None or module is None or compile_flags is None)
|
||||
and self.default_user_namespaces):
|
||||
call_frame = sys._getframe(stack_depth).f_back
|
||||
|
||||
if local_ns is None:
|
||||
local_ns = call_frame.f_locals
|
||||
if module is None:
|
||||
global_ns = call_frame.f_globals
|
||||
try:
|
||||
module = sys.modules[global_ns['__name__']]
|
||||
except KeyError:
|
||||
warnings.warn("Failed to get module %s" % \
|
||||
global_ns.get('__name__', 'unknown module')
|
||||
)
|
||||
module = DummyMod()
|
||||
module.__dict__ = global_ns
|
||||
if compile_flags is None:
|
||||
compile_flags = (call_frame.f_code.co_flags &
|
||||
compilerop.PyCF_MASK)
|
||||
|
||||
# Save original namespace and module so we can restore them after
|
||||
# embedding; otherwise the shell doesn't shut down correctly.
|
||||
orig_user_module = self.user_module
|
||||
orig_user_ns = self.user_ns
|
||||
orig_compile_flags = self.compile.flags
|
||||
|
||||
# Update namespaces and fire up interpreter
|
||||
|
||||
# The global one is easy, we can just throw it in
|
||||
if module is not None:
|
||||
self.user_module = module
|
||||
|
||||
# But the user/local one is tricky: ipython needs it to store internal
|
||||
# data, but we also need the locals. We'll throw our hidden variables
|
||||
# like _ih and get_ipython() into the local namespace, but delete them
|
||||
# later.
|
||||
if local_ns is not None:
|
||||
reentrant_local_ns = {k: v for (k, v) in local_ns.items() if k not in self.user_ns_hidden.keys()}
|
||||
self.user_ns = reentrant_local_ns
|
||||
self.init_user_ns()
|
||||
|
||||
# Compiler flags
|
||||
if compile_flags is not None:
|
||||
self.compile.flags = compile_flags
|
||||
|
||||
# make sure the tab-completer has the correct frame information, so it
|
||||
# actually completes using the frame's locals/globals
|
||||
self.set_completer_frame()
|
||||
|
||||
with self.builtin_trap, self.display_trap:
|
||||
self.interact()
|
||||
|
||||
# now, purge out the local namespace of IPython's hidden variables.
|
||||
if local_ns is not None:
|
||||
local_ns.update({k: v for (k, v) in self.user_ns.items() if k not in self.user_ns_hidden.keys()})
|
||||
|
||||
|
||||
# Restore original namespace so shell can shut down when we exit.
|
||||
self.user_module = orig_user_module
|
||||
self.user_ns = orig_user_ns
|
||||
self.compile.flags = orig_compile_flags
|
||||
|
||||
|
||||
def embed(**kwargs):
|
||||
"""Call this to embed IPython at the current point in your program.
|
||||
|
||||
The first invocation of this will create an :class:`InteractiveShellEmbed`
|
||||
instance and then call it. Consecutive calls just call the already
|
||||
created instance.
|
||||
|
||||
If you don't want the kernel to initialize the namespace
|
||||
from the scope of the surrounding function,
|
||||
and/or you want to load full IPython configuration,
|
||||
you probably want `IPython.start_ipython()` instead.
|
||||
|
||||
Here is a simple example::
|
||||
|
||||
from IPython import embed
|
||||
a = 10
|
||||
b = 20
|
||||
embed(header='First time')
|
||||
c = 30
|
||||
d = 40
|
||||
embed()
|
||||
|
||||
Full customization can be done by passing a :class:`Config` in as the
|
||||
config argument.
|
||||
"""
|
||||
config = kwargs.get('config')
|
||||
header = kwargs.pop('header', u'')
|
||||
compile_flags = kwargs.pop('compile_flags', None)
|
||||
if config is None:
|
||||
config = load_default_config()
|
||||
config.InteractiveShellEmbed = config.TerminalInteractiveShell
|
||||
kwargs['config'] = config
|
||||
using = kwargs.get('using', 'sync')
|
||||
if using :
|
||||
kwargs['config'].update({'TerminalInteractiveShell':{'loop_runner':using, 'colors':'NoColor', 'autoawait': using!='sync'}})
|
||||
#save ps1/ps2 if defined
|
||||
ps1 = None
|
||||
ps2 = None
|
||||
try:
|
||||
ps1 = sys.ps1
|
||||
ps2 = sys.ps2
|
||||
except AttributeError:
|
||||
pass
|
||||
#save previous instance
|
||||
saved_shell_instance = InteractiveShell._instance
|
||||
if saved_shell_instance is not None:
|
||||
cls = type(saved_shell_instance)
|
||||
cls.clear_instance()
|
||||
frame = sys._getframe(1)
|
||||
shell = InteractiveShellEmbed.instance(_init_location_id='%s:%s' % (
|
||||
frame.f_code.co_filename, frame.f_lineno), **kwargs)
|
||||
shell(header=header, stack_depth=2, compile_flags=compile_flags,
|
||||
_call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno))
|
||||
InteractiveShellEmbed.clear_instance()
|
||||
#restore previous instance
|
||||
if saved_shell_instance is not None:
|
||||
cls = type(saved_shell_instance)
|
||||
cls.clear_instance()
|
||||
for subclass in cls._walk_mro():
|
||||
subclass._instance = saved_shell_instance
|
||||
if ps1 is not None:
|
||||
sys.ps1 = ps1
|
||||
sys.ps2 = ps2
|
Loading…
Add table
Add a link
Reference in a new issue