| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327 | 
							- # Copyright (c) 2011-2016 Godefroid Chapelle and ipdb development team
 
- #
 
- # This file is part of ipdb.
 
- # Redistributable under the revised BSD license
 
- # https://opensource.org/licenses/BSD-3-Clause
 
- from __future__ import print_function
 
- import os
 
- import sys
 
- from decorator import contextmanager
 
- __version__ = '0.13.9'
 
- from IPython import get_ipython
 
- from IPython.core.debugger import BdbQuit_excepthook
 
- from IPython.terminal.ipapp import TerminalIPythonApp
 
- from IPython.terminal.embed import InteractiveShellEmbed
 
- try:
 
-     import configparser
 
- except:
 
-     import ConfigParser as configparser
 
- def _get_debugger_cls():
 
-     shell = get_ipython()
 
-     if shell is None:
 
-         # Not inside IPython
 
-         # Build a terminal app in order to force ipython to load the
 
-         # configuration
 
-         ipapp = TerminalIPythonApp()
 
-         # Avoid output (banner, prints)
 
-         ipapp.interact = False
 
-         ipapp.initialize(["--no-term-title"])
 
-         shell = ipapp.shell
 
-     else:
 
-         # Running inside IPython
 
-         # Detect if embed shell or not and display a message
 
-         if isinstance(shell, InteractiveShellEmbed):
 
-             sys.stderr.write(
 
-                 "\nYou are currently into an embedded ipython shell,\n"
 
-                 "the configuration will not be loaded.\n\n"
 
-             )
 
-     # Let IPython decide about which debugger class to use
 
-     # This is especially important for tools that fiddle with stdout
 
-     return shell.debugger_cls
 
- def _init_pdb(context=None, commands=[]):
 
-     if context is None:
 
-         context = os.getenv("IPDB_CONTEXT_SIZE", get_context_from_config())
 
-     debugger_cls = _get_debugger_cls()
 
-     try:
 
-         p = debugger_cls(context=context)
 
-     except TypeError:
 
-         p = debugger_cls()
 
-     p.rcLines.extend(commands)
 
-     return p
 
- def wrap_sys_excepthook():
 
-     # make sure we wrap it only once or we would end up with a cycle
 
-     #  BdbQuit_excepthook.excepthook_ori == BdbQuit_excepthook
 
-     if sys.excepthook != BdbQuit_excepthook:
 
-         BdbQuit_excepthook.excepthook_ori = sys.excepthook
 
-         sys.excepthook = BdbQuit_excepthook
 
- def set_trace(frame=None, context=None, cond=True):
 
-     if not cond:
 
-         return
 
-     wrap_sys_excepthook()
 
-     if frame is None:
 
-         frame = sys._getframe().f_back
 
-     p = _init_pdb(context).set_trace(frame)
 
-     if p and hasattr(p, 'shell'):
 
-         p.shell.restore_sys_module_state()
 
- def get_context_from_config():
 
-     try:
 
-         parser = get_config()
 
-         return parser.getint("ipdb", "context")
 
-     except (configparser.NoSectionError, configparser.NoOptionError):
 
-         return 3
 
-     except ValueError:
 
-         value = parser.get("ipdb", "context")
 
-         raise ValueError(
 
-             "In %s,  context value [%s] cannot be converted into an integer."
 
-             % (parser.filepath, value)
 
-         )
 
- class ConfigFile(object):
 
-     """
 
-     Filehandle wrapper that adds a "[ipdb]" section to the start of a config
 
-     file so that users don't actually have to manually add a [ipdb] section.
 
-     Works with configparser versions from both Python 2 and 3
 
-     """
 
-     def __init__(self, filepath):
 
-         self.first = True
 
-         with open(filepath) as f:
 
-             self.lines = f.readlines()
 
-     # Python 2.7 (Older dot versions)
 
-     def readline(self):
 
-         try:
 
-             return self.__next__()
 
-         except StopIteration:
 
-             return ''
 
-     # Python 2.7 (Newer dot versions)
 
-     def next(self):
 
-         return self.__next__()
 
-     # Python 3
 
-     def __iter__(self):
 
-         return self
 
-     def __next__(self):
 
-         if self.first:
 
-             self.first = False
 
-             return "[ipdb]\n"
 
-         if self.lines:
 
-             return self.lines.pop(0)
 
-         raise StopIteration
 
- def get_config():
 
-     """
 
-     Get ipdb config file settings.
 
-     All available config files are read.  If settings are in multiple configs,
 
-     the last value encountered wins.  Values specified on the command-line take
 
-     precedence over all config file settings.
 
-     Returns: A ConfigParser object.
 
-     """
 
-     parser = configparser.ConfigParser()
 
-     filepaths = []
 
-     # Low priority goes first in the list
 
-     for cfg_file in ("setup.cfg", ".ipdb", "pyproject.toml"):
 
-         cwd_filepath = os.path.join(os.getcwd(), cfg_file)
 
-         if os.path.isfile(cwd_filepath):
 
-             filepaths.append(cwd_filepath)
 
-     # Medium priority (whenever user wants to set a specific path to config file)
 
-     home = os.getenv("HOME")
 
-     if home:
 
-         default_filepath = os.path.join(home, ".ipdb")
 
-         if os.path.isfile(default_filepath):
 
-             filepaths.append(default_filepath)
 
-     # High priority (default files)
 
-     env_filepath = os.getenv("IPDB_CONFIG")
 
-     if env_filepath and os.path.isfile(env_filepath):
 
-         filepaths.append(env_filepath)
 
-     if filepaths:
 
-         # Python 3 has parser.read_file(iterator) while Python2 has
 
-         # parser.readfp(obj_with_readline)
 
-         try:
 
-             read_func = parser.read_file
 
-         except AttributeError:
 
-             read_func = parser.readfp
 
-         for filepath in filepaths:
 
-             parser.filepath = filepath
 
-             # Users are expected to put an [ipdb] section
 
-             # only if they use setup.cfg
 
-             if filepath.endswith('setup.cfg'):
 
-                 with open(filepath) as f:
 
-                     parser.remove_section("ipdb")
 
-                     read_func(f)
 
-             # To use on pyproject.toml, put [tool.ipdb] section
 
-             elif filepath.endswith('pyproject.toml'):
 
-                 import toml
 
-                 toml_file = toml.load(filepath)
 
-                 if "tool" in toml_file and "ipdb" in toml_file["tool"]:
 
-                     if not parser.has_section("ipdb"):
 
-                         parser.add_section("ipdb")
 
-                     for key, value in toml_file["tool"]["ipdb"].items():
 
-                         parser.set("ipdb", key, str(value))
 
-             else:
 
-                 read_func(ConfigFile(filepath))
 
-     return parser
 
- def post_mortem(tb=None):
 
-     wrap_sys_excepthook()
 
-     p = _init_pdb()
 
-     p.reset()
 
-     if tb is None:
 
-         # sys.exc_info() returns (type, value, traceback) if an exception is
 
-         # being handled, otherwise it returns None
 
-         tb = sys.exc_info()[2]
 
-     if tb:
 
-         p.interaction(None, tb)
 
- def pm():
 
-     post_mortem(sys.last_traceback)
 
- def run(statement, globals=None, locals=None):
 
-     _init_pdb().run(statement, globals, locals)
 
- def runcall(*args, **kwargs):
 
-     return _init_pdb().runcall(*args, **kwargs)
 
- def runeval(expression, globals=None, locals=None):
 
-     return _init_pdb().runeval(expression, globals, locals)
 
- @contextmanager
 
- def launch_ipdb_on_exception():
 
-     try:
 
-         yield
 
-     except Exception:
 
-         e, m, tb = sys.exc_info()
 
-         print(m.__repr__(), file=sys.stderr)
 
-         post_mortem(tb)
 
-     finally:
 
-         pass
 
- # iex is a concise alias
 
- iex = launch_ipdb_on_exception()
 
- _usage = """\
 
- usage: python -m ipdb [-m] [-c command] ... pyfile [arg] ...
 
- Debug the Python program given by pyfile.
 
- Initial commands are read from .pdbrc files in your home directory
 
- and in the current directory, if they exist.  Commands supplied with
 
- -c are executed after commands from .pdbrc files.
 
- To let the script run until an exception occurs, use "-c continue".
 
- To let the script run up to a given line X in the debugged file, use
 
- "-c 'until X'"
 
- Option -m is available only in Python 3.7 and later.
 
- ipdb version %s.""" % __version__
 
- def main():
 
-     import traceback
 
-     import sys
 
-     import getopt
 
-     try:
 
-         from pdb import Restart
 
-     except ImportError:
 
-         class Restart(Exception):
 
-             pass
 
-     if sys.version_info >= (3, 7):
 
-         opts, args = getopt.getopt(sys.argv[1:], 'mhc:', ['help', 'command='])
 
-     else:
 
-         opts, args = getopt.getopt(sys.argv[1:], 'hc:', ['help', 'command='])
 
-     commands = []
 
-     run_as_module = False
 
-     for opt, optarg in opts:
 
-         if opt in ['-h', '--help']:
 
-             print(_usage)
 
-             sys.exit()
 
-         elif opt in ['-c', '--command']:
 
-             commands.append(optarg)
 
-         elif opt in ['-m']:
 
-             run_as_module = True
 
-     if not args:
 
-         print(_usage)
 
-         sys.exit(2)
 
-     mainpyfile = args[0]     # Get script filename
 
-     if not run_as_module and not os.path.exists(mainpyfile):
 
-         print('Error:', mainpyfile, 'does not exist')
 
-         sys.exit(1)
 
-     sys.argv = args     # Hide "pdb.py" from argument list
 
-     # Replace pdb's dir with script's dir in front of module search path.
 
-     if not run_as_module:
 
-         sys.path[0] = os.path.dirname(mainpyfile)
 
-     # Note on saving/restoring sys.argv: it's a good idea when sys.argv was
 
-     # modified by the script being debugged. It's a bad idea when it was
 
-     # changed by the user from the command line. There is a "restart" command
 
-     # which allows explicit specification of command line arguments.
 
-     pdb = _init_pdb(commands=commands)
 
-     while 1:
 
-         try:
 
-             if run_as_module:
 
-                 pdb._runmodule(mainpyfile)
 
-             else:
 
-                 pdb._runscript(mainpyfile)
 
-             if pdb._user_requested_quit:
 
-                 break
 
-             print("The program finished and will be restarted")
 
-         except Restart:
 
-             print("Restarting", mainpyfile, "with arguments:")
 
-             print("\t" + " ".join(sys.argv[1:]))
 
-         except SystemExit:
 
-             # In most cases SystemExit does not warrant a post-mortem session.
 
-             print("The program exited via sys.exit(). Exit status: ", end='')
 
-             print(sys.exc_info()[1])
 
-         except:
 
-             traceback.print_exc()
 
-             print("Uncaught exception. Entering post mortem debugging")
 
-             print("Running 'cont' or 'step' will restart the program")
 
-             t = sys.exc_info()[2]
 
-             pdb.interaction(None, t)
 
-             print("Post mortem debugger finished. The " + mainpyfile +
 
-                   " will be restarted")
 
- if __name__ == '__main__':
 
-     main()
 
 
  |