Beispiel #1
0
def shell_usbdevice(fd, device):
    # interactive explore
    backend = device.backend
    lib = backend.lib
    ctx = backend.ctx
    dev = device._ctx.handle
    handle = dev.handle
    devid = dev.devid

    # query some information
    dev_desc = backend.get_device_descriptor(dev)
    config_desc = backend.get_configuration_descriptor(dev, 0)

    from IPython.terminal.embed import InteractiveShellEmbed
    from IPython.terminal.ipapp import load_default_config

    InteractiveShellEmbed.clear_instance()
    namespace = {
        "fd": fd,
        "handle": handle,
        "devid": devid,
        "dev": dev,
        "dev_desc": dev_desc,
        "config_desc": config_desc,
        "device": device,
        "libusb1": libusb1,
        "backend": backend,
        "lib": lib,
        "ctx": ctx,
    }
    banner = ("Variables:\n" + "\n".join(
        ["{:>12}: {}".format(k, repr(v))
         for k, v in namespace.items()]) + "\n")
    shell = InteractiveShellEmbed.instance(banner1=banner, user_ns=namespace)
    shell()
Beispiel #2
0
def embed_ipython():
    """
    Taken from `IPython.terminal.embed()`, see documentation there.
    Call this to embed IPython at the current point in your program with config from profile 'debug'.
    """
    config = load_config_for_embed_ipython()
    config.InteractiveShellEmbed = config.TerminalInteractiveShell
    # 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)
    location = f'{frame.f_code.co_filename}:{frame.f_lineno}'
    shell = InteractiveShellEmbed.instance(_init_location_id=location, config=config)
    shell(header=location, stack_depth=2, _call_location_id=location)
    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
Beispiel #3
0
def _ipython(local, banner):
    from IPython.terminal.embed import InteractiveShellEmbed
    from IPython.terminal.ipapp import load_default_config

    InteractiveShellEmbed.clear_instance()
    shell = InteractiveShellEmbed.instance(banner1=banner,
                                           user_ns=local,
                                           config=load_default_config())
    shell()
Beispiel #4
0
 def wrapper(namespace=namespace, banner=''):
     config = load_default_config()
     # Always use .instace() to ensure _instance propagation to all parents
     # this is needed for <TAB> completion works well for new imports
     # and clear the instance to always have the fresh env
     # on repeated breaks like with inspect_response()
     InteractiveShellEmbed.clear_instance()
     shell = InteractiveShellEmbed.instance(
         banner1=banner, user_ns=namespace, config=config)
     shell()
Beispiel #5
0
 def wrapper(namespace=namespace, banner=''):
     config = load_default_config()
     # Always use .instance() to ensure _instance propagation to all parents
     # this is needed for <TAB> completion works well for new imports
     # and clear the instance to always have the fresh env
     # on repeated breaks like with inspect_response()
     InteractiveShellEmbed.clear_instance()
     shell = InteractiveShellEmbed.instance(
         banner1=banner, user_ns=namespace, config=config)
     shell()
Beispiel #6
0
def _ipython(local, banner):
    # noinspection PyUnresolvedReferences
    from IPython.terminal.embed import InteractiveShellEmbed
    # noinspection PyUnresolvedReferences
    from IPython.terminal.ipapp import load_default_config

    InteractiveShellEmbed.clear_instance()
    shell = InteractiveShellEmbed.instance(banner1=banner,
                                           user_ns=local,
                                           config=load_default_config())
    shell()
Beispiel #7
0
def _ipython(local, banner):
    from IPython.terminal.embed import InteractiveShellEmbed
    from IPython.terminal.ipapp import load_default_config

    InteractiveShellEmbed.clear_instance()
    shell = InteractiveShellEmbed.instance(
        banner1=banner,
        user_ns=local,
        config=load_default_config()
    )
    shell()
Beispiel #8
0
def console():
    """Starts an interactive IPython console"""

    import sys
    import builtins
    from IPython.terminal.embed import (load_default_config,
                                        InteractiveShell, InteractiveShellEmbed)

    header = 'Django debug console'
    config = load_default_config()
    config.InteractiveShellEmbed = config.TerminalInteractiveShell

    # 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()

    # Starts shell
    retvalue = None

    def exit(value=None):
        nonlocal retvalue
        retvalue = value

    try:
        builtins.exit = exit
        shell = InteractiveShellEmbed.instance(config=config)
        shell(header=header, stack_depth=2, compile_flags=None)
        InteractiveShellEmbed.clear_instance()
    finally:
        pass

    # 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

    return retvalue
Beispiel #9
0
def console():
    """Starts an interactive IPython console"""

    import sys
    import builtins
    from IPython.terminal.embed import (load_default_config, InteractiveShell,
                                        InteractiveShellEmbed)

    header = 'Django debug console'
    config = load_default_config()
    config.InteractiveShellEmbed = config.TerminalInteractiveShell

    # 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()

    # Starts shell
    retvalue = None

    def exit(value=None):
        nonlocal retvalue
        retvalue = value

    try:
        builtins.exit = exit
        shell = InteractiveShellEmbed.instance(config=config)
        shell(header=header, stack_depth=2, compile_flags=None)
        InteractiveShellEmbed.clear_instance()
    finally:
        pass

    # 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

    return retvalue
Beispiel #10
0
def start_python_console(user_ns: dict = None, banner: str = ""):
    """
    Start a python interactive terminal
    :param user_ns:
    :param banner:
    :return:
    """
    config = load_default_config()
    InteractiveShellEmbed.clear_instance()
    python_shell = InteractiveShellEmbed.instance(banner1=banner,
                                                  user_ns=user_ns,
                                                  config=config)

    python_shell()
Beispiel #11
0
    def IPS():

        # let the user know, where this shell is 'waking up'
        # construct frame list
        # this will be printed in the header
        frame_info_list = []
        frame_list = []
        frame = inspect.currentframe()
        while not frame == None:
            frame_list.append(frame)
            info = inspect.getframeinfo(frame)
            frame_info_list.append(info)
            frame = frame.f_back

        frame_info_list.reverse()
        frame_list.reverse()
        frame_info_str_list = [format_frameinfo(fi) for fi in frame_info_list]

        custom_header1 = "----- frame list -----\n\n"
        frame_info_str = "\n--\n".join(frame_info_str_list[:-1])
        custom_header2 = "\n----- end of frame list -----\n"

        custom_header = "{0}{1}{2}".format(custom_header1, frame_info_str,
                                           custom_header2)

        # prevent IPython shell to be launched in IP-Notebook
        test_str = str(frame_info_list[0]) + str(frame_info_list[1])
        #print test_str
        if 'IPython' in test_str and 'zmq' in test_str:
            print("\n- Not entering IPython embedded shell  -\n")
            return

        # copied (and modified) from IPython/terminal/embed.py
        config = load_default_config()
        config.InteractiveShellEmbed = config.TerminalInteractiveShell

        # these two lines prevent problems in related to the initialization
        # of ultratb.FormattedTB below
        InteractiveShellEmbed.clear_instance()
        InteractiveShellEmbed._instance = None

        shell = InteractiveShellEmbed.instance()

        shell(header=custom_header, stack_depth=2)

        custom_excepthook = getattr(sys, 'custom_excepthook', None)
        if custom_excepthook is not None:
            assert callable(custom_excepthook)
            sys.excepthook = custom_excepthook
Beispiel #12
0
 def interact(self, **kwargs):
     from IPython.terminal.embed import InteractiveShellEmbed, load_default_config
     import sys
     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
     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()
Beispiel #13
0
    def IPS():

        # let the user know, where this shell is 'waking up'
        # construct frame list
        # this will be printed in the header
        frame_info_list = []
        frame_list = []
        frame = inspect.currentframe()
        while not frame == None:
            frame_list.append(frame)
            info = inspect.getframeinfo(frame)
            frame_info_list.append(info)
            frame = frame.f_back

        frame_info_list.reverse()
        frame_list.reverse()
        frame_info_str_list = [format_frameinfo(fi) for fi in frame_info_list]

        custom_header1 = "----- frame list -----\n\n"
        frame_info_str = "\n--\n".join(frame_info_str_list[:-1])
        custom_header2 = "\n----- end of frame list -----\n"

        custom_header = "{0}{1}{2}".format(custom_header1, frame_info_str, custom_header2)

        # prevent IPython shell to be launched in IP-Notebook
        test_str = str(frame_info_list[0]) + str(frame_info_list[1])
        # print test_str
        if "IPython" in test_str and "zmq" in test_str:
            print "\n- Not entering IPython embedded shell  -\n"
            return

        # copied (and modified) from IPython/terminal/embed.py
        config = load_default_config()
        config.InteractiveShellEmbed = config.TerminalInteractiveShell

        # these two lines prevent problems in related to the initialization
        # of ultratb.FormattedTB below
        InteractiveShellEmbed.clear_instance()
        InteractiveShellEmbed._instance = None

        shell = InteractiveShellEmbed.instance()

        shell(header=custom_header, stack_depth=2)
Beispiel #14
0
def DBG(**kwargs):
    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
        #HORIA
        config.InteractiveShell.confirm_exit = False
        config.TerminalIPythonApp.display_banner = False
        kwargs['banner1'] = '\nDBG>'
        kwargs['config'] = config
        #HORIA
    #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(
        _call_location_id='%s:%s' % (frame.f_code.co_filename, frame.f_lineno),
        **kwargs)
    shell(header=header, stack_depth=2, compile_flags=compile_flags)
    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
    EXIT()
Beispiel #15
0
 def interact(self, **kwargs):
     from IPython.terminal.embed import InteractiveShellEmbed, load_default_config
     import sys
     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
     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()
Beispiel #16
0
def embed2(**kwargs):
    """
    Modified from IPython.terminal.embed.embed so I can mess with stack_depth
    """
    config = kwargs.get('config')
    header = kwargs.pop('header', u'')
    stack_depth = kwargs.pop('stack_depth', 2)
    compile_flags = kwargs.pop('compile_flags', None)
    import IPython
    from IPython.core.interactiveshell import InteractiveShell
    from IPython.terminal.embed import InteractiveShellEmbed
    if config is None:
        config = IPython.terminal.ipapp.load_default_config()
        config.InteractiveShellEmbed = config.TerminalInteractiveShell
        kwargs['config'] = config
    #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()
    shell = InteractiveShellEmbed.instance(**kwargs)
    shell(header=header, stack_depth=stack_depth, compile_flags=compile_flags)
    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
Beispiel #17
0
def embed2(**kwargs):
    """
    Modified from IPython.terminal.embed.embed so I can mess with stack_depth
    """
    config = kwargs.get('config')
    header = kwargs.pop('header', u'')
    stack_depth = kwargs.pop('stack_depth', 2)
    compile_flags = kwargs.pop('compile_flags', None)
    import IPython
    from IPython.core.interactiveshell import InteractiveShell
    from IPython.terminal.embed import InteractiveShellEmbed
    if config is None:
        config = IPython.terminal.ipapp.load_default_config()
        config.InteractiveShellEmbed = config.TerminalInteractiveShell
        kwargs['config'] = config
    #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()
    shell = InteractiveShellEmbed.instance(**kwargs)
    shell(header=header, stack_depth=stack_depth, compile_flags=compile_flags)
    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
Beispiel #18
0
def _run_ips(frame_list, c):
    """
    :param frame_list:  list of frames
    :param c:       Container for arguments
    """

    # copied (and modified) from IPython/terminal/embed.py
    config = load_default_config()
    config.InteractiveShellEmbed = config.TerminalInteractiveShell

    # these two lines prevent problems related to the initialization
    # of ultratb.FormattedTB below
    InteractiveShellEmbed.clear_instance()
    InteractiveShellEmbed._instance = None

    shell = InteractiveShellEmbed.instance()

    # achieve that custom macros are loaded in interactive shell
    shell.magic('load_ext storemagic')
    if config.StoreMagics.autorestore:
        shell.magic('store -r')
        ar_keys = [
            k.split("/")[-1] for k in shell.db.keys()
            if k.startswith("autorestore/")
        ]
    else:
        ar_keys = []

    # adapt the namespaces to prevent missing names inside the shell
    # see: https://github.com/ipython/ipython/issues/62
    # https://github.com/ipython/ipython/issues/10695
    if c.copy_namespaces and len(frame_list) >= 1:
        # callers_frame to IPS()
        # note that frame_list and frame_info_list were reversed above
        f1 = frame_list[-1]
        lns = f1.f_locals
        gns = f1.f_globals

        # insert some IPS-debugging variables
        lns.update(c.ns_extension)

        l_keys = set(lns)
        g_keys = set(gns)
        u_keys = shell.user_ns.keys()

        # those keys which are in local ns but not in global
        safe_keys = l_keys - g_keys
        unsafe_keys = l_keys.intersection(g_keys)

        assert safe_keys.union(unsafe_keys) == l_keys

        gns.update({k: lns[k] for k in safe_keys})

        if unsafe_keys and not c.overwrite_globals:
            c.custom_header += "following local keys have " \
                             "not been copied:\n{}\n".format(unsafe_keys)

        if unsafe_keys and c.overwrite_globals:
            gns.update({k: lns[k] for k in unsafe_keys})
            c.custom_header += "following global keys have " \
                             "been overwritten:\n{}\n".format(unsafe_keys)

        # now update the gns with stuff from the user_ns (if it will not overwrite anything)
        # this could be implemented cleaner
        for k in ar_keys:
            if k not in gns:
                gns[k] = shell.user_ns[k]
            else:
                print("omitting key from user_namespace:", k)

        dummy_module = DummyMod()
        dummy_module.__dict__ = gns

    else:
        # unexpected few frames or no copying desired:
        lns = {}
        dummy_module = None

    # now execute the shell
    shell(header=c.custom_header,
          stack_depth=2,
          local_ns=lns,
          module=dummy_module)

    # if `diff_index` is not None it will be interpreted as index increment for the frame_list in the except hook
    # "__mu" means "move up"
    diff_index = lns.get("__mu")
    if not isinstance(diff_index, int):
        diff_index = None

    return diff_index
Beispiel #19
0
def embed2(**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.
    """
    ix()  # MYCHANGE
    config = kwargs.get("config")
    header = kwargs.pop("header", "")
    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", "asyncio")  # MYCHANGE
    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
Beispiel #20
0
def IPS(copy_namespaces=True, overwrite_globals=False):
    """Starts IPython embedded shell. This is similar to IPython.embed() but with some
    additional features:

    1. Print a list of the calling frames before entering the prompt
    2. (optionally) copy local name space to global one to prevent certain IPython bug.
    3. while doing so optinally overwrite names in the global namespace

    """

    # let the user know, where this shell is 'waking up'
    # construct frame list
    # this will be printed in the header
    frame_info_list = []
    frame_list = []
    frame = inspect.currentframe()
    while frame is not None:
        frame_list.append(frame)
        info = inspect.getframeinfo(frame)
        frame_info_list.append(info)
        frame = frame.f_back

    frame_info_list.reverse()
    frame_list.reverse()
    frame_info_str_list = [format_frameinfo(fi) for fi in frame_info_list]

    custom_header1 = "----- frame list -----\n\n"
    frame_info_str = "\n--\n".join(frame_info_str_list[:-1])
    custom_header2 = "\n----- end of frame list -----\n"

    custom_header = "{0}{1}{2}".format(custom_header1, frame_info_str, custom_header2)

    # prevent IPython shell to be launched in IP-Notebook
    test_str = str(frame_info_list[0]) + str(frame_info_list[1])
    if 'IPython' in test_str and 'zmq' in test_str:
        print("\n- Not entering IPython embedded shell  -\n")
        return

    # copied (and modified) from IPython/terminal/embed.py
    config = load_default_config()

    config.InteractiveShellEmbed = config.TerminalInteractiveShell

    # these two lines prevent problems related to the initialization
    # of ultratb.FormattedTB below
    InteractiveShellEmbed.clear_instance()
    InteractiveShellEmbed._instance = None

    shell = InteractiveShellEmbed.instance()

    # achieve that custom macros are loade in interactive shell
    shell.magic('load_ext storemagic')
    if config.StoreMagics.autorestore:
        shell.magic('store -r')
        ar_keys = [k.split("/")[-1] for k in shell.db.keys() if k.startswith("autorestore/")]
    else:
        ar_keys = []

    # adapt the namespaces to prevent missing names inside the shell
    # see: https://github.com/ipython/ipython/issues/62
    # https://github.com/ipython/ipython/issues/10695
    if copy_namespaces and len(frame_list) >= 2:
        # callers_frame to IPS()
        # note that frame_list and frame_info_list were reversed above
        f1 = frame_list[-2]
        lns = f1.f_locals
        gns = f1.f_globals

        l_keys = set(lns)
        g_keys = set(gns)
        u_keys = shell.user_ns.keys()

        # those keys which are in local ns but not in global
        safe_keys = l_keys - g_keys
        unsafe_keys = l_keys.intersection(g_keys)

        assert safe_keys.union(unsafe_keys) == l_keys

        gns.update({k:lns[k] for k in safe_keys})

        if unsafe_keys and not overwrite_globals:
            custom_header += "following local keys have " \
                             "not been copied:\n{}\n".format(unsafe_keys)

        if unsafe_keys and overwrite_globals:
            gns.update({k:lns[k] for k in unsafe_keys})
            custom_header += "following global keys have " \
                             "been overwritten:\n{}\n".format(unsafe_keys)

        # now update the gns with stuff from the user_ns (if it will not overwrite anything)
        # this could be implemented cleaner
        for k in ar_keys:
            if k not in gns:
                gns[k] = shell.user_ns[k]
            else:
                print("omitting key from user_namespace:", k)

        dummy_module = DummyMod()
        dummy_module.__dict__ = gns

    else:
        # unexpected few frames or no copying desired:
        lns = None
        dummy_module = None

    # now execute the shell
    shell(header=custom_header, stack_depth=2, local_ns=lns, module=dummy_module)

    custom_excepthook = getattr(sys, 'custom_excepthook', None)
    if custom_excepthook is not None:
        assert callable(custom_excepthook)
        sys.excepthook = custom_excepthook