diff --git a/python/helpers/pydev/_pydev_bundle/pydev_monkey.py b/python/helpers/pydev/_pydev_bundle/pydev_monkey.py index 0e6b8f815fdc..2d9994e20e95 100644 --- a/python/helpers/pydev/_pydev_bundle/pydev_monkey.py +++ b/python/helpers/pydev/_pydev_bundle/pydev_monkey.py @@ -8,6 +8,7 @@ try: except: xrange = range + #=============================================================================== # Things that are dependent on having the pydevd debugger #=============================================================================== @@ -15,10 +16,12 @@ def log_debug(msg): from _pydev_bundle import pydev_log pydev_log.debug(msg) + def log_error_once(msg): from _pydev_bundle import pydev_log pydev_log.error_once(msg) + pydev_src_dir = os.path.dirname(os.path.dirname(__file__)) @@ -34,25 +37,30 @@ def _get_python_c_args(host, port, indC, args, setup): setup, args[indC + 1]) + def _get_host_port(): import pydevd host, port = pydevd.dispatch() return host, port + def _is_managed_arg(arg): if arg.endswith('pydevd.py'): return True return False + def _on_forked_process(): import pydevd pydevd.threadingCurrentThread().__pydevd_main_thread = True pydevd.settrace_forked() + def _on_set_trace_for_new_thread(global_debugger): if global_debugger is not None: global_debugger.SetTrace(global_debugger.trace_dispatch, global_debugger.frame_eval_func, global_debugger.dummy_trace_dispatch) + #=============================================================================== # Things related to monkey-patching #=============================================================================== @@ -93,6 +101,24 @@ def quote_args(args): return args +def get_c_option_index(args): + """ + Get index of "-c" argument and check if it's interpreter's option + :param args: list of arguments + :return: index of "-c" if it's an interpreter's option and -1 if it doesn't exist or program's option + """ + try: + ind_c = args.index('-c') + except ValueError: + return -1 + else: + for i in range(1, ind_c): + if not args[i].startswith('-'): + # there is an arg without "-" before "-c", so it's not an interpreter's option + return -1 + return ind_c + + def patch_args(args): try: log_debug("Patching args: %s"% str(args)) @@ -101,22 +127,18 @@ def patch_args(args): from pydevd import SetupHolder import sys new_args = [] - i = 0 if len(args) == 0: return args if is_python(args[0]): - try: - indC = args.index('-c') - except ValueError: - indC = -1 + ind_c = get_c_option_index(args) - if indC != -1: + if ind_c != -1: host, port = _get_host_port() if port is not None: new_args.extend(args) - new_args[indC + 1] = _get_python_c_args(host, port, indC, args, SetupHolder.setup) + new_args[ind_c + 1] = _get_python_c_args(host, port, ind_c, args, SetupHolder.setup) return quote_args(new_args) else: # Check for Python ZIP Applications and don't patch the args for them. @@ -145,7 +167,6 @@ def patch_args(args): return args i = 1 - # Original args should be something as: # ['X:\\pysrc\\pydevd.py', '--multiprocess', '--print-in-debugger-startup', # '--vm_type', 'python', '--client', '127.0.0.1', '--port', '56352', '--file', 'x:\\snippet1.py'] diff --git a/python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py b/python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py index c4d4b0736daf..328102b75d3d 100644 --- a/python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py +++ b/python/helpers/pydev/tests_pydevd_python/test_pydev_monkey.py @@ -1,6 +1,7 @@ -import sys import os +import sys import unittest + try: from _pydev_bundle import pydev_monkey except: @@ -10,15 +11,14 @@ from pydevd import SetupHolder from _pydev_bundle.pydev_monkey import pydev_src_dir - class TestCase(unittest.TestCase): def test_monkey(self): original = SetupHolder.setup try: - SetupHolder.setup = {'client':'127.0.0.1', 'port': '0'} - check='''C:\\bin\\python.exe -u -c connect(\\"127.0.0.1\\")''' + SetupHolder.setup = {'client': '127.0.0.1', 'port': '0'} + check = '''C:\\bin\\python.exe -u -c connect(\\"127.0.0.1\\")''' debug_command = ( 'import sys; ' 'sys.path.append(r\'%s\'); ' @@ -42,8 +42,8 @@ class TestCase(unittest.TestCase): original = SetupHolder.setup try: - SetupHolder.setup = {'client':'127.0.0.1', 'port': '0'} - check=['C:\\bin\\python.exe', '-u', '-c', 'connect("127.0.0.1")'] + SetupHolder.setup = {'client': '127.0.0.1', 'port': '0'} + check = ['C:\\bin\\python.exe', '-u', '-c', 'connect("127.0.0.1")'] debug_command = ( 'import sys; sys.path.append(r\'%s\'); import pydevd; ' 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True); ' @@ -66,8 +66,8 @@ class TestCase(unittest.TestCase): original = SetupHolder.setup try: - SetupHolder.setup = {'client':'127.0.0.1', 'port': '0', 'multiprocess': True} - check=['C:\\bin\\python.exe', '-m', 'test'] + SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True} + check = ['C:\\bin\\python.exe', '-m', 'test'] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file self.assertEqual(pydev_monkey.patch_args(check), [ 'C:\\bin\\python.exe', @@ -88,8 +88,8 @@ class TestCase(unittest.TestCase): original = SetupHolder.setup try: - SetupHolder.setup = {'client':'127.0.0.1', 'port': '0'} - check=['C:\\bin\\python.exe', 'connect(\\"127.0.0.1\\")'] + SetupHolder.setup = {'client': '127.0.0.1', 'port': '0'} + check = ['C:\\bin\\python.exe', 'connect(\\"127.0.0.1\\")'] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file self.assertEqual(pydev_monkey.patch_args(check), [ 'C:\\bin\\python.exe', @@ -107,8 +107,8 @@ class TestCase(unittest.TestCase): original = SetupHolder.setup try: - SetupHolder.setup = {'client':'127.0.0.1', 'port': '0'} - check=['C:\\bin\\python.exe', 'pydevd.py', 'connect(\\"127.0.0.1\\")', 'bar'] + SetupHolder.setup = {'client': '127.0.0.1', 'port': '0'} + check = ['C:\\bin\\python.exe', 'pydevd.py', 'connect(\\"127.0.0.1\\")', 'bar'] self.assertEqual(pydev_monkey.patch_args(check), [ 'C:\\bin\\python.exe', 'pydevd.py', 'connect(\\"127.0.0.1\\")', 'bar']) @@ -120,8 +120,8 @@ class TestCase(unittest.TestCase): from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file try: - SetupHolder.setup = {'client':'127.0.0.1', 'port': '0'} - check=['C:\\bin\\python.exe', 'target.py', 'connect(\\"127.0.0.1\\")', 'bar'] + SetupHolder.setup = {'client': '127.0.0.1', 'port': '0'} + check = ['C:\\bin\\python.exe', 'target.py', 'connect(\\"127.0.0.1\\")', 'bar'] self.assertEqual(pydev_monkey.patch_args(check), [ 'C:\\bin\\python.exe', @@ -138,5 +138,30 @@ class TestCase(unittest.TestCase): finally: SetupHolder.setup = original + def test_monkey_patch_c_program_arg(self): + original = SetupHolder.setup + from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file + + try: + SetupHolder.setup = {'client': '127.0.0.1', 'port': '0'} + check = ['C:\\bin\\python.exe', '-u', 'target.py', '-c', '-another_arg'] + + self.assertEqual(pydev_monkey.patch_args(check), [ + 'C:\\bin\\python.exe', + '-u', + get_pydevd_file(), + '--port', + '0', + '--client', + '127.0.0.1', + '--file', + 'target.py', + '-c', + '-another_arg' + ]) + finally: + SetupHolder.setup = original + + if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main()