def testProcessCommandLine(self): from _pydevd_bundle.pydevd_command_line_handling import process_command_line, setup_to_argv setup = process_command_line(['pydevd.py', '--port', '1', '--save-threading']) assert setup['save-threading'] assert setup['port'] == 1 assert not setup['qt-support'] argv = setup_to_argv(setup) assert argv[0].endswith('pydevd.py') argv = argv[1:] assert argv == ['--port', '1', '--save-threading']
def patch_args(args): try: log_debug("Patching args: %s"% str(args)) args = remove_quotes_from_args(args) from pydevd import SetupHolder new_args = [] if len(args) == 0: return args if is_python(args[0]): ind_c = get_c_option_index(args) if ind_c != -1: host, port = _get_host_port() if port is not None: new_args.extend(args) 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. # Assumes the first non `-<flag>` argument is what we need to check. # There's probably a better way to determine this but it works for most cases. continue_next = False for i in range(1, len(args)): if continue_next: continue_next = False continue arg = args[i] if arg.startswith('-'): # Skip the next arg too if this flag expects a value. continue_next = arg in ['-m', '-W', '-X'] continue if arg.rsplit('.')[-1] in ['zip', 'pyz', 'pyzw']: log_debug('Executing a PyZip, returning') return args break new_args.append(args[0]) else: log_debug("Process is not python, returning.") 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'] from _pydevd_bundle.pydevd_command_line_handling import setup_to_argv original = setup_to_argv(SetupHolder.setup) + ['--file'] while i < len(args): if args[i] == '-m': # Always insert at pos == 1 (i.e.: pydevd "--module" --multiprocess ...) original.insert(1, '--module') else: if args[i].startswith('-'): new_args.append(args[i]) else: break i += 1 # Note: undoing https://github.com/Elizaveta239/PyDev.Debugger/commit/053c9d6b1b455530bca267e7419a9f63bf51cddf # (i >= len(args) instead of i < len(args)) # in practice it'd raise an exception here and would return original args, which is not what we want... providing # a proper fix for https://youtrack.jetbrains.com/issue/PY-9767 elsewhere. if i < len(args) and _is_managed_arg(args[i]): # no need to add pydevd twice return args for x in original: new_args.append(x) if x == '--file': break while i < len(args): new_args.append(args[i]) i += 1 return quote_args(new_args) except: traceback.print_exc() return args
def patch_args(args): try: log_debug("Patching args: %s" % str(args)) if _is_py3_and_has_bytes_args(args): warn_bytes_args() return args args = remove_quotes_from_args(args) from pydevd import SetupHolder new_args = [] if len(args) == 0: return args if is_python(args[0]): for name in PYTHON_NAMES: if args[0].find(name) != -1: break else: # Executable file with Python shebang. args.insert(0, sys.executable) ind_c = get_c_option_index(args) if ind_c != -1: if _is_already_patched(args): return args host, port = _get_host_port() if port is not None: new_args.extend(args) 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. # Assumes the first non `-<flag>` argument is what we need to check. # There's probably a better way to determine this but it works for most cases. continue_next = False for i in range(1, len(args)): if continue_next: continue_next = False continue arg = args[i] if arg.startswith('-'): # Skip the next arg too if this flag expects a value. continue_next = arg in ['-m', '-W', '-X'] continue if arg.rsplit('.')[-1] in ['zip', 'pyz', 'pyzw']: log_debug('Executing a PyZip, returning') return args break new_args.append(args[0]) else: log_debug("Process is not python, returning.") 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'] from _pydevd_bundle.pydevd_command_line_handling import setup_to_argv SetupHolder.setup[ 'module'] = False # clean module param from parent process original = setup_to_argv(SetupHolder.setup) + ['--file'] while i < len(args): if args[i] == '-m': # Always insert at pos == 1 (i.e.: pydevd "--module" --multiprocess ...) original.insert(1, '--module') else: if args[i] == '-': # this is the marker that input is going to be from stdin for Python # for now we just disable the debugging here, don't crash but is not supported return args elif args[i].startswith('-'): new_args.append(args[i]) else: break i += 1 # Note: undoing https://github.com/Elizaveta239/PyDev.Debugger/commit/053c9d6b1b455530bca267e7419a9f63bf51cddf # (i >= len(args) instead of i < len(args)) # in practice it'd raise an exception here and would return original args, which is not what we want... providing # a proper fix for https://youtrack.jetbrains.com/issue/PY-9767 elsewhere. if i >= len(args) or _is_managed_arg( args[i]): # no need to add pydevd twice return args for x in original: new_args.append(x) if x == '--file': break while i < len(args): new_args.append(args[i]) i += 1 return quote_args(new_args) except: traceback.print_exc() return args
def patch_args(args, is_exec=False): ''' :param list args: Arguments to patch. :param bool is_exec: If it's an exec, the current process will be replaced (this means we have to keep the same ppid). ''' try: pydev_log.debug("Patching args: %s", args) original_args = args unquoted_args = remove_quotes_from_args(args) # Internally we should reference original_args (if we want to return them) or unquoted_args # to add to the list which will be then quoted in the end. del args from pydevd import SetupHolder if not unquoted_args: return original_args if not is_python(unquoted_args[0]): pydev_log.debug("Process is not python, returning.") return original_args # Note: we create a copy as string to help with analyzing the arguments, but # the final list should have items from the unquoted_args as they were initially. args_as_str = _get_str_type_compatible('', unquoted_args) params_with_value_in_separate_arg = ( '--check-hash-based-pycs', '--jit' # pypy option ) # All short switches may be combined together. The ones below require a value and the # value itself may be embedded in the arg. # # i.e.: Python accepts things as: # # python -OQold -qmtest # # Which is the same as: # # python -O -Q old -q -m test # # or even: # # python -OQold "-vcimport sys;print(sys)" # # Which is the same as: # # python -O -Q old -v -c "import sys;print(sys)" params_with_combinable_arg = set(('W', 'X', 'Q', 'c', 'm')) module_name = None before_module_flag = '' module_name_i_start = -1 module_name_i_end = -1 code = None code_i = -1 code_i_end = -1 code_flag = '' filename = None filename_i = -1 ignore_next = True # start ignoring the first (the first entry is the python executable) for i, arg_as_str in enumerate(args_as_str): if ignore_next: ignore_next = False continue if arg_as_str.startswith('-'): if arg_as_str == '-': # Contents will be read from the stdin. This is not currently handled. pydev_log.debug( 'Unable to fix arguments to attach debugger on subprocess when reading from stdin ("python ... -").' ) return original_args if arg_as_str.startswith(params_with_value_in_separate_arg): if arg_as_str in params_with_value_in_separate_arg: ignore_next = True continue break_out = False for j, c in enumerate(arg_as_str): # i.e.: Python supports -X faulthandler as well as -Xfaulthandler # (in one case we have to ignore the next and in the other we don't # have to ignore it). if c in params_with_combinable_arg: remainder = arg_as_str[j + 1:] if not remainder: ignore_next = True if c == 'm': # i.e.: Something as # python -qm test # python -m test # python -qmtest before_module_flag = arg_as_str[: j] # before_module_flag would then be "-q" if before_module_flag == '-': before_module_flag = '' module_name_i_start = i if not remainder: module_name = unquoted_args[i + 1] module_name_i_end = i + 1 else: # i.e.: python -qmtest should provide 'test' as the module_name module_name = unquoted_args[i][j + 1:] module_name_i_end = module_name_i_start break_out = True break elif c == 'c': # i.e.: Something as # python -qc "import sys" # python -c "import sys" # python "-qcimport sys" code_flag = arg_as_str[:j + 1] # code_flag would then be "-qc" if not remainder: # arg_as_str is something as "-qc", "import sys" code = unquoted_args[i + 1] code_i_end = i + 2 else: # if arg_as_str is something as "-qcimport sys" code = remainder # code would be "import sys" code_i_end = i + 1 code_i = i break_out = True break else: break if break_out: break else: # It doesn't start with '-' and we didn't ignore this entry: # this means that this is the file to be executed. filename = unquoted_args[i] filename_i = i # When executing .zip applications, don't attach the debugger. extensions = _get_str_type_compatible( filename, ['.zip', '.pyz', '.pyzw']) for ext in extensions: if filename.endswith(ext): pydev_log.debug( 'Executing a PyZip (debugger will not be attached to subprocess).' ) return original_args if _is_managed_arg(filename): # no need to add pydevd twice pydev_log.debug( 'Skipped monkey-patching as pydevd.py is in args already.' ) return original_args break else: # We didn't find the filename (something is unexpected). pydev_log.debug( 'Unable to fix arguments to attach debugger on subprocess (filename not found).' ) return original_args if code_i != -1: host, port = _get_host_port() if port is not None: new_args = [] new_args.extend(unquoted_args[:code_i]) new_args.append(code_flag) new_args.append( _get_python_c_args(host, port, code, unquoted_args, SetupHolder.setup)) new_args.extend(unquoted_args[code_i_end:]) return quote_args(new_args) first_non_vm_index = max(filename_i, module_name_i_start) if first_non_vm_index == -1: pydev_log.debug( 'Unable to fix arguments to attach debugger on subprocess (could not resolve filename nor module name).' ) return original_args # 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'] from _pydevd_bundle.pydevd_command_line_handling import setup_to_argv new_args = [] new_args.extend(unquoted_args[:first_non_vm_index]) if before_module_flag: new_args.append(before_module_flag) new_args.extend( setup_to_argv( _get_setup_updated_with_protocol_and_ppid(SetupHolder.setup, is_exec=is_exec))) new_args.append('--file') if module_name is not None: assert module_name_i_start != -1 assert module_name_i_end != -1 # Always after 'pydevd' (i.e.: pydevd "--module" --multiprocess ...) new_args.insert(2 if not before_module_flag else 3, '--module') new_args.append(module_name) new_args.extend(unquoted_args[module_name_i_end + 1:]) elif filename is not None: assert filename_i != -1 new_args.append(filename) new_args.extend(unquoted_args[filename_i + 1:]) else: raise AssertionError('Internal error (unexpected condition)') return quote_args(new_args) except: pydev_log.exception( 'Error patching args (debugger not attached to subprocess).') return original_args
def patch_args(args): try: pydev_log.debug("Patching args: %s", args) args = remove_quotes_from_args(args) from pydevd import SetupHolder new_args = [] if len(args) == 0: return args if is_python(args[0]): ind_c = get_c_option_index(args) if ind_c != -1: host, port = _get_host_port() if port is not None: new_args.extend(args) 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. # Assumes the first non `-<flag>` argument is what we need to check. # There's probably a better way to determine this but it works for most cases. continue_next = False for i in range(1, len(args)): if continue_next: continue_next = False continue arg = args[i] if arg.startswith(_get_str_type_compatible(arg, '-')): # Skip the next arg too if this flag expects a value. continue_next = arg in _get_str_type_compatible(arg, ['-m', '-W', '-X']) continue dot = _get_str_type_compatible(arg, '.') extensions = _get_str_type_compatible(arg, ['zip', 'pyz', 'pyzw']) if arg.rsplit(dot)[-1] in extensions: pydev_log.debug('Executing a PyZip, returning') return args break new_args.append(args[0]) else: pydev_log.debug("Process is not python, returning.") 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'] from _pydevd_bundle.pydevd_command_line_handling import setup_to_argv original = setup_to_argv(_get_setup_updated_with_protocol(SetupHolder.setup)) + ['--file'] module_name = None m_flag = _get_str_type_compatible(args[i], '-m') while i < len(args): if args[i] == m_flag: # Always insert at pos == 1 (i.e.: pydevd "--module" --multiprocess ...) original.insert(1, '--module') elif args[i].startswith(m_flag): # Case where the user does: python -mmodule_name (using a single parameter). original.insert(1, '--module') module_name = args[i][2:] else: if args[i].startswith(_get_str_type_compatible(args[i], '-')): new_args.append(args[i]) else: break i += 1 # Note: undoing https://github.com/Elizaveta239/PyDev.Debugger/commit/053c9d6b1b455530bca267e7419a9f63bf51cddf # (i >= len(args) instead of i < len(args)) # in practice it'd raise an exception here and would return original args, which is not what we want... providing # a proper fix for https://youtrack.jetbrains.com/issue/PY-9767 elsewhere. if i < len(args) and _is_managed_arg(args[i]): # no need to add pydevd twice return args for x in original: new_args.append(x) if x == _get_str_type_compatible(x, '--file'): break if module_name is not None: new_args.append(module_name) while i < len(args): new_args.append(args[i]) i += 1 return quote_args(new_args) except: pydev_log.exception('Error patching args') return args