From 87a6e619b48c2471341aa5164948f76f352c5a7c Mon Sep 17 00:00:00 2001 From: Elizaveta Shashkova Date: Thu, 16 Apr 2015 19:45:43 +0300 Subject: [PATCH] Handle -m option in debugger (PY-15230) Do not leave it as interpreter option, but pass it to debugger as additional parameter --- python/helpers/pydev/pydevd.py | 35 +++++++++++++++++-- .../python/debugger/PyDebugRunner.java | 30 +++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/python/helpers/pydev/pydevd.py b/python/helpers/pydev/pydevd.py index 7b9bdd6dfaaa..a10de2716297 100644 --- a/python/helpers/pydev/pydevd.py +++ b/python/helpers/pydev/pydevd.py @@ -96,6 +96,11 @@ PluginManager = None if SUPPORT_PLUGINS: from pydevd_plugin_utils import PluginManager +if IS_PY3K: + import pkgutil +else: + from _pydev_imps import _pydev_pkgutil_old as pkgutil + threadingEnumerate = threading.enumerate threadingCurrentThread = threading.currentThread @@ -1684,8 +1689,27 @@ class PyDB: from pydev_monkey import patch_thread_modules patch_thread_modules() + def get_fullname(self, mod_name): + try: + loader = pkgutil.get_loader(mod_name) + except: + return None + if loader is not None: + for attr in ("get_filename", "_get_filename"): + meth = getattr(loader, attr, None) + if meth is not None: + return meth(mod_name) + return None + + def run(self, file, globals=None, locals=None, module=False, set_trace=True): + if module: + filename = self.get_fullname(file) + if filename is None: + sys.stderr.write("No module named %s\n" % file) + return + else: + file = filename - def run(self, file, globals=None, locals=None, set_trace=True): if os.path.isdir(file): new_target = os.path.join(file, '__main__.py') if os.path.isfile(new_target): @@ -1773,6 +1797,7 @@ def processCommandLine(argv): setup['save-signatures'] = False setup['print-in-debugger-startup'] = False setup['cmd-line'] = False + setup['module'] = False i = 0 del argv[0] while (i < len(argv)): @@ -1816,6 +1841,9 @@ def processCommandLine(argv): elif (argv[i] == '--cmd-line'): del argv[i] setup['cmd-line'] = True + elif (argv[i] == '--module'): + del argv[i] + setup['module'] = True else: raise ValueError("unexpected option " + argv[i]) return setup @@ -2256,6 +2284,7 @@ if __name__ == '__main__': pass # It's ok not having stackless there... debugger = PyDB() + is_module = setup['module'] if fix_app_engine_debug: sys.stderr.write("pydev debugger: google app engine integration enabled\n") @@ -2270,7 +2299,7 @@ if __name__ == '__main__': sys.argv.insert(4, '--max_module_instances=1') # Run the dev_appserver - debugger.run(setup['file'], None, None, set_trace=False) + debugger.run(setup['file'], None, None, is_module, set_trace=False) else: # as to get here all our imports are already resolved, the psyco module can be # changed and we'll still get the speedups in the debugger, as those functions @@ -2303,7 +2332,7 @@ if __name__ == '__main__': connected = True # Mark that we're connected when started from inside ide. - globals = debugger.run(setup['file'], None, None) + globals = debugger.run(setup['file'], None, None, is_module) if setup['cmd-line']: debugger.wait_for_commands(globals) diff --git a/python/src/com/jetbrains/python/debugger/PyDebugRunner.java b/python/src/com/jetbrains/python/debugger/PyDebugRunner.java index 206916bdf36d..f5f25106982c 100644 --- a/python/src/com/jetbrains/python/debugger/PyDebugRunner.java +++ b/python/src/com/jetbrains/python/debugger/PyDebugRunner.java @@ -66,6 +66,7 @@ public class PyDebugRunner extends GenericProgramRunner { public static final String IDE_PROJECT_ROOTS = "IDE_PROJECT_ROOTS"; @SuppressWarnings("SpellCheckingInspection") public static final String GEVENT_SUPPORT = "GEVENT_SUPPORT"; + public static boolean isModule = false; @Override @NotNull @@ -182,14 +183,37 @@ public class PyDebugRunner extends GenericProgramRunner { final PythonCommandLineState pyState, final int serverLocalPort) { return new CommandLinePatcher() { + + private void patchExeParams(ParametersList parametersList) { + // we should remove '-m' parameter, but notify debugger of it + // but we can't remove one parameter from group, so we create new parameters group + ParamsGroup newExeParams = new ParamsGroup(PythonCommandLineState.GROUP_EXE_OPTIONS); + int exeParamsIndex = parametersList.getParamsGroups().indexOf( + parametersList.getParamsGroup(PythonCommandLineState.GROUP_EXE_OPTIONS)); + ParamsGroup exeParamsOld = parametersList.removeParamsGroup(exeParamsIndex); + isModule = false; + for (String param: exeParamsOld.getParameters()) { + if (!param.equals("-m")) { + newExeParams.addParameter(param); + } else { + isModule = true; + } + } + + parametersList.addParamsGroupAt(exeParamsIndex, newExeParams); + } + + @Override public void patchCommandLine(GeneralCommandLine commandLine) { // script name is the last parameter; all other params are for python interpreter; insert just before name - final ParametersList parametersList = commandLine.getParametersList(); + ParametersList parametersList = commandLine.getParametersList(); @SuppressWarnings("ConstantConditions") @NotNull ParamsGroup debugParams = parametersList.getParamsGroup(PythonCommandLineState.GROUP_DEBUGGER); + patchExeParams(parametersList); + @SuppressWarnings("ConstantConditions") @NotNull ParamsGroup exeParams = parametersList.getParamsGroup(PythonCommandLineState.GROUP_EXE_OPTIONS); @@ -218,6 +242,10 @@ public class PyDebugRunner extends GenericProgramRunner { debugParams.addParameter("--multiproc"); } + if (isModule) { + debugParams.addParameter("--module"); + } + if (ApplicationManager.getApplication().isUnitTestMode()) { debugParams.addParameter("--DEBUG"); }