diff --git a/contrib/debugshell.py b/contrib/debugshell.py index a232522d377076537ae60536fe868b1623e9515d_Y29udHJpYi9kZWJ1Z3NoZWxsLnB5..c7a4fb11acacc134967b1b7861d30fe4ef3beb45_Y29udHJpYi9kZWJ1Z3NoZWxsLnB5 100644 --- a/contrib/debugshell.py +++ b/contrib/debugshell.py @@ -1,30 +1,2 @@ -# debugshell extension -"""a python shell with repo, changelog & manifest objects""" - -import code -import mercurial -import sys -from mercurial import ( - demandimport, - pycompat, - registrar, -) - -cmdtable = {} -command = registrar.command(cmdtable) - - -def pdb(ui, repo, msg, **opts): - objects = { - 'mercurial': mercurial, - 'repo': repo, - 'cl': repo.changelog, - 'mf': repo.manifestlog, - } - - code.interact(msg, local=objects) - - -def ipdb(ui, repo, msg, **opts): - import IPython +"""a python shell with repo, changelog & manifest objects (DEPRECATED) @@ -30,35 +2,4 @@ - cl = repo.changelog - mf = repo.manifestlog - cl, mf # use variables to appease pyflakes - - IPython.embed() - - -@command(b'debugshell|dbsh', []) -def debugshell(ui, repo, **opts): - bannermsg = "loaded repo : %s\n" "using source: %s" % ( - pycompat.sysstr(repo.root), - mercurial.__path__[0], - ) - - pdbmap = {'pdb': 'code', 'ipdb': 'IPython'} - - debugger = ui.config(b"ui", b"debugger") - if not debugger: - debugger = 'pdb' - else: - debugger = pycompat.sysstr(debugger) - - # if IPython doesn't exist, fallback to code.interact - try: - with demandimport.deactivated(): - __import__(pdbmap[debugger]) - except ImportError: - ui.warnnoi18n( - b"%s debugger specified but %s module was not found\n" - % (debugger, pdbmap[debugger]) - ) - debugger = b'pdb' - - getattr(sys.modules[__name__], debugger)(ui, repo, bannermsg, **opts) +The functionality of this extension has been included in core Mercurial since +version 7.1. Please use the core :hg:`debugshell` command instead. +""" diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py index a232522d377076537ae60536fe868b1623e9515d_bWVyY3VyaWFsL2RlYnVnY29tbWFuZHMucHk=..c7a4fb11acacc134967b1b7861d30fe4ef3beb45_bWVyY3VyaWFsL2RlYnVnY29tbWFuZHMucHk= 100644 --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -42,6 +42,7 @@ context, copies, dagparser, + demandimport, dirstateutils, encoding, error, @@ -3803,7 +3804,7 @@ @command( - b'debugshell', + b'debugshell|dbsh', [ ( b'c', @@ -3819,10 +3820,11 @@ def debugshell(ui, repo, **opts): """run an interactive Python interpreter - The local namespace is provided with a reference to the ui and - the repo instance (if available). + The local namespace is provided with a reference to the ui and the repo + instance (if available). If `ui.debugger` is configured to be `ipdb`, an + IPython shell will be used instead of the standard Python shell. """ import code imported_objects = { 'ui': ui, @@ -3824,8 +3826,10 @@ """ import code imported_objects = { 'ui': ui, - 'repo': repo, + # Import some useful utilities. + 'hex': hex, + 'bin': bin, } @@ -3830,5 +3834,40 @@ } + if repo: + imported_objects.update( + { + 'repo': repo, + 'cl': repo.changelog, + 'mf': repo.manifestlog, + } + ) + + # Import the `mercurial` module. + srcpath = "(unknown)" + if __package__: + mercurial = __import__(__package__) + imported_objects['m'] = mercurial + if mercurial.__path__: + srcpath = mercurial.__path__[0] + + # Import native extensions (if available). + try: + from . import cext + + imported_objects['cext'] = cext + except ImportError: + cext = None + try: + from . import pyo3_rustext as rustext + + imported_objects['rustext'] = rustext + except ImportError: + rustext = None + + # Import a few handy standard library modules. + for name in ['os', 'sys', 'subprocess', 're']: + imported_objects[name] = __import__(name) + # py2exe disables initialization of the site module, which is responsible # for arranging for ``quit()`` to exit the interpreter. Manually initialize # the stuff that site normally does here, so that the interpreter can be @@ -3850,7 +3889,48 @@ code.InteractiveInterpreter(locals=imported_objects).runcode(compiled) return - code.interact(local=imported_objects) + reporoot = ( + encoding.strfromlocal(repo.root) if repo and repo.root else "(none)" + ) + bannermsg = ( + f"Loaded repo: {reporoot}\n" + f"Using source: {srcpath}\n" + "\nModules:\n" + " m: the mercurial module\n" + ) + if cext: + bannermsg += " cext: native C extensions\n" + if rustext: + bannermsg += " rustext: native Rust extensions\n" + bannermsg += "\nObjects:\n ui: the ui object\n" + if repo: + bannermsg += ( + " repo: the repo object\n" + " cl: repo.changelog\n" + " mf: repo.manifestlog\n" + ) + bannermsg += ( + "\nUtilities:\n" + " hex: binascii.hexlify\n" + " bin: binascii.unhexlify\n" + ) + + if ui.config(b"ui", b"debugger") == b"ipdb": + try: + # IPython is incompatible with demandimport. + with demandimport.deactivated(): + import IPython + + globals().update(imported_objects) + IPython.embed(header=bannermsg) + return + except ImportError: + ui.warnnoi18n( + b"IPython module not found, " + b"falling back to standard Python shell\n\n" + ) + + code.interact(bannermsg, local=imported_objects) @command(