diff --git a/_pydev_bundle/_pydev_calltip_util.py b/_pydev_bundle/_pydev_calltip_util.py index aca108fa0..ad9347602 100644 --- a/_pydev_bundle/_pydev_calltip_util.py +++ b/_pydev_bundle/_pydev_calltip_util.py @@ -1,7 +1,7 @@ -''' +""" License: Apache 2.0 Author: Yuli Fitterman -''' +""" import types from _pydevd_bundle.pydevd_constants import IS_JYTHON @@ -9,7 +9,7 @@ try: import inspect except: - import traceback; + import traceback traceback.print_exc() # Ok, no inspect available (search will not work) @@ -18,7 +18,7 @@ def is_bound_method(obj): if isinstance(obj, types.MethodType): - return getattr(obj, '__self__', getattr(obj, 'im_self', None)) is not None + return getattr(obj, "__self__", getattr(obj, "im_self", None)) is not None else: return False @@ -28,7 +28,7 @@ def get_class_name(instance): def get_bound_class_name(obj): - my_self = getattr(obj, '__self__', getattr(obj, 'im_self', None)) + my_self = getattr(obj, "__self__", getattr(obj, "im_self", None)) if my_self is None: return None return get_class_name(my_self) @@ -40,8 +40,8 @@ def get_description(obj): except: ob_call = None - if isinstance(obj, type) or type(obj).__name__ == 'classobj': - fob = getattr(obj, '__init__', lambda: None) + if isinstance(obj, type) or type(obj).__name__ == "classobj": + fob = getattr(obj, "__init__", lambda: None) if not isinstance(fob, (types.FunctionType, types.MethodType)): fob = obj elif is_bound_method(ob_call): @@ -55,16 +55,16 @@ def get_description(obj): if isinstance(fob, (types.FunctionType, types.MethodType)): spec_info = inspect.getfullargspec(fob) argspec = inspect.formatargspec(*spec_info) - fn_name = getattr(fob, '__name__', None) - if isinstance(obj, type) or type(obj).__name__ == 'classobj': + fn_name = getattr(fob, "__name__", None) + if isinstance(obj, type) or type(obj).__name__ == "classobj": fn_name = "__init__" fn_class = getattr(obj, "__name__", "UnknownClass") elif is_bound_method(obj) or is_bound_method(ob_call): fn_class = get_bound_class_name(obj) or "UnknownClass" else: - fn_name = getattr(fob, '__name__', None) - fn_self = getattr(fob, '__self__', None) + fn_name = getattr(fob, "__name__", None) + fn_self = getattr(fob, "__self__", None) if fn_self is not None and not isinstance(fn_self, types.ModuleType): fn_class = get_class_name(fn_self) @@ -77,7 +77,7 @@ def create_method_stub(fn_name, fn_class, argspec, doc_string): doc_string = "" if doc_string is None else doc_string fn_stub = create_function_stub(fn_name, argspec, doc_string, indent=1 if fn_class else 0) if fn_class: - expr = fn_class if fn_name == '__init__' else fn_class + '().' + fn_name + expr = fn_class if fn_name == "__init__" else fn_class + "()." + fn_name return create_class_stub(fn_class, fn_stub) + "\n" + expr else: expr = fn_name @@ -87,10 +87,10 @@ def create_method_stub(fn_name, fn_class, argspec, doc_string): restored_signature, _ = signature_from_docstring(doc_string, fn_name) if restored_signature: return create_method_stub(fn_name, fn_class, restored_signature, doc_string) - return create_function_stub('unknown', '(*args, **kwargs)', doc_string) + '\nunknown' + return create_function_stub("unknown", "(*args, **kwargs)", doc_string) + "\nunknown" else: - return '' + return "" def get_docstring(obj): @@ -105,21 +105,20 @@ def get_docstring(obj): from _pydev_bundle import _pydev_jy_imports_tipper is_method, infos = _pydev_jy_imports_tipper.ismethod(obj) - ret = '' + ret = "" if is_method: for info in infos: ret += info.get_as_doc() return ret else: - doc = inspect.getdoc(obj) if doc is not None: return doc except: pass else: - return '' + return "" try: # if no attempt succeeded, try to return repr()... return repr(obj) @@ -129,7 +128,7 @@ def get_docstring(obj): return str(obj.__class__) except: # if all fails, go to an empty string - return '' + return "" def create_class_stub(class_name, contents): @@ -137,9 +136,8 @@ def create_class_stub(class_name, contents): def create_function_stub(fn_name, fn_argspec, fn_docstring, indent=0): - def shift_right(string, prefix): - return ''.join(prefix + line for line in string.splitlines(True)) + return "".join(prefix + line for line in string.splitlines(True)) fn_docstring = shift_right(inspect.cleandoc(fn_docstring), " " * (indent + 1)) ret = ''' @@ -148,7 +146,7 @@ def %s%s: pass ''' % (fn_name, fn_argspec, fn_docstring) ret = ret[1:] # remove first /n - ret = ret.replace('\t', " ") + ret = ret.replace("\t", " ") if indent: prefix = " " * indent ret = shift_right(ret, prefix) diff --git a/_pydev_bundle/_pydev_completer.py b/_pydev_bundle/_pydev_completer.py index ed0db4ea7..69a2b23f5 100644 --- a/_pydev_bundle/_pydev_completer.py +++ b/_pydev_bundle/_pydev_completer.py @@ -9,6 +9,7 @@ try: import java.lang # @UnusedImport from _pydev_bundle import _pydev_jy_imports_tipper + _pydev_imports_tipper = _pydev_jy_imports_tipper except ImportError: IS_JYTHON = False @@ -17,13 +18,13 @@ dir2 = _pydev_imports_tipper.generate_imports_tip_for_module -#======================================================================================================================= +# ======================================================================================================================= # _StartsWithFilter -#======================================================================================================================= +# ======================================================================================================================= class _StartsWithFilter: - ''' - Used because we can't create a lambda that'll use an outer scope in jython 2.1 - ''' + """ + Used because we can't create a lambda that'll use an outer scope in jython 2.1 + """ def __init__(self, start_with): self.start_with = start_with.lower() @@ -32,13 +33,12 @@ def __call__(self, name): return name.lower().startswith(self.start_with) -#======================================================================================================================= +# ======================================================================================================================= # Completer # # This class was gotten from IPython.completer (dir2 was replaced with the completer already in pydev) -#======================================================================================================================= +# ======================================================================================================================= class Completer: - def __init__(self, namespace=None, global_namespace=None): """Create a new completer for the command line. @@ -82,7 +82,7 @@ def complete(self, text): """ if self.use_main_ns: # In pydev this option should never be used - raise RuntimeError('Namespace must be provided!') + raise RuntimeError("Namespace must be provided!") self.namespace = __main__.__dict__ # @UndefinedVariable if "." in text: @@ -148,7 +148,7 @@ def attr_matches(self, text): def generate_completions(frame, act_tok): - ''' + """ :return list(tuple(method_name, docstring, parameters, completion_type)) method_name: str @@ -156,7 +156,7 @@ def generate_completions(frame, act_tok): parameters: str -- i.e.: "(a, b)" completion_type is an int See: _pydev_bundle._pydev_imports_tipper for TYPE_ constants - ''' + """ if frame is None: return [] @@ -189,21 +189,21 @@ def completions_to_xml(completions): for comp in completions: msg.append('_= \t"))) msg.append('" p1="') - msg.append(valid_xml(quote(comp[1], '/>_= \t'))) + msg.append(valid_xml(quote(comp[1], "/>_= \t"))) msg.append('" p2="') - msg.append(valid_xml(quote(comp[2], '/>_= \t'))) + msg.append(valid_xml(quote(comp[2], "/>_= \t"))) msg.append('" p3="') - msg.append(valid_xml(quote(comp[3], '/>_= \t'))) + msg.append(valid_xml(quote(comp[3], "/>_= \t"))) msg.append('"/>') msg.append("") - return ''.join(msg) + return "".join(msg) -identifier_start = ascii_letters + '_' -identifier_part = ascii_letters + '_' + digits +identifier_start = ascii_letters + "_" +identifier_part = ascii_letters + "_" + digits identifier_start = set(identifier_start) identifier_part = set(identifier_part) @@ -213,18 +213,18 @@ def isidentifier(s): return s.isidentifier() -TokenAndQualifier = namedtuple('TokenAndQualifier', 'token, qualifier') +TokenAndQualifier = namedtuple("TokenAndQualifier", "token, qualifier") def extract_token_and_qualifier(text, line=0, column=0): - ''' + """ Extracts the token a qualifier from the text given the line/colum (see test_extract_token_and_qualifier for examples). :param unicode text: :param int line: 0-based :param int column: 0-based - ''' + """ # Note: not using the tokenize module because text should be unicode and # line/column refer to the unicode text (otherwise we'd have to know # those ranges after converted to bytes). @@ -234,32 +234,32 @@ def extract_token_and_qualifier(text, line=0, column=0): column = 0 if isinstance(text, bytes): - text = text.decode('utf-8') + text = text.decode("utf-8") lines = text.splitlines() try: text = lines[line] except IndexError: - return TokenAndQualifier(u'', u'') + return TokenAndQualifier("", "") if column >= len(text): column = len(text) text = text[:column] - token = u'' - qualifier = u'' + token = "" + qualifier = "" temp_token = [] for i in range(column - 1, -1, -1): c = text[i] - if c in identifier_part or isidentifier(c) or c == u'.': + if c in identifier_part or isidentifier(c) or c == ".": temp_token.append(c) else: break - temp_token = u''.join(reversed(temp_token)) - if u'.' in temp_token: - temp_token = temp_token.split(u'.') - token = u'.'.join(temp_token[:-1]) + temp_token = "".join(reversed(temp_token)) + if "." in temp_token: + temp_token = temp_token.split(".") + token = ".".join(temp_token[:-1]) qualifier = temp_token[-1] else: qualifier = temp_token diff --git a/_pydev_bundle/_pydev_execfile.py b/_pydev_bundle/_pydev_execfile.py index 28ae40351..4abdd4b63 100644 --- a/_pydev_bundle/_pydev_execfile.py +++ b/_pydev_bundle/_pydev_execfile.py @@ -2,13 +2,15 @@ def execfile(file, glob=None, loc=None): if glob is None: import sys + glob = sys._getframe().f_back.f_globals if loc is None: loc = glob import tokenize + with tokenize.open(file) as stream: contents = stream.read() # execute the script (note: it's important to compile first to have the filename set in debug mode) - exec(compile(contents + "\n", file, 'exec'), glob, loc) + exec(compile(contents + "\n", file, "exec"), glob, loc) diff --git a/_pydev_bundle/_pydev_filesystem_encoding.py b/_pydev_bundle/_pydev_filesystem_encoding.py index 6264e3dbd..b0a21bfde 100644 --- a/_pydev_bundle/_pydev_filesystem_encoding.py +++ b/_pydev_bundle/_pydev_filesystem_encoding.py @@ -2,40 +2,42 @@ def __getfilesystemencoding(): - ''' + """ Note: there's a copy of this method in interpreterInfo.py - ''' + """ try: ret = sys.getfilesystemencoding() if not ret: - raise RuntimeError('Unable to get encoding.') + raise RuntimeError("Unable to get encoding.") return ret except: try: - #Handle Jython + # Handle Jython from java.lang import System # @UnresolvedImport + env = System.getProperty("os.name").lower() - if env.find('win') != -1: - return 'ISO-8859-1' #mbcs does not work on Jython, so, use a (hopefully) suitable replacement - return 'utf-8' + if env.find("win") != -1: + return "ISO-8859-1" # mbcs does not work on Jython, so, use a (hopefully) suitable replacement + return "utf-8" except: pass - #Only available from 2.3 onwards. - if sys.platform == 'win32': - return 'mbcs' - return 'utf-8' + # Only available from 2.3 onwards. + if sys.platform == "win32": + return "mbcs" + return "utf-8" + def getfilesystemencoding(): try: ret = __getfilesystemencoding() - #Check if the encoding is actually there to be used! - if hasattr('', 'encode'): - ''.encode(ret) - if hasattr('', 'decode'): - ''.decode(ret) + # Check if the encoding is actually there to be used! + if hasattr("", "encode"): + "".encode(ret) + if hasattr("", "decode"): + "".decode(ret) return ret except: - return 'utf-8' + return "utf-8" diff --git a/_pydev_bundle/_pydev_getopt.py b/_pydev_bundle/_pydev_getopt.py index 5548651e3..d8765ca9a 100644 --- a/_pydev_bundle/_pydev_getopt.py +++ b/_pydev_bundle/_pydev_getopt.py @@ -1,11 +1,11 @@ - -#======================================================================================================================= +# ======================================================================================================================= # getopt code copied since gnu_getopt is not available on jython 2.1 -#======================================================================================================================= +# ======================================================================================================================= class GetoptError(Exception): - opt = '' - msg = '' - def __init__(self, msg, opt=''): + opt = "" + msg = "" + + def __init__(self, msg, opt=""): self.msg = msg self.opt = opt Exception.__init__(self, msg, opt) @@ -30,25 +30,25 @@ def gnu_getopt(args, shortopts, longopts=[]): opts = [] prog_args = [] - if type('') == type(longopts): + if type("") == type(longopts): longopts = [longopts] else: longopts = list(longopts) # Allow options after non-option arguments? all_options_first = False - if shortopts.startswith('+'): + if shortopts.startswith("+"): shortopts = shortopts[1:] all_options_first = True while args: - if args[0] == '--': + if args[0] == "--": prog_args += args[1:] break - if args[0][:2] == '--': + if args[0][:2] == "--": opts, args = do_longs(opts, args[0][2:], longopts, args[1:]) - elif args[0][:1] == '-': + elif args[0][:1] == "-": opts, args = do_shorts(opts, args[0][1:], shortopts, args[1:]) else: if all_options_first: @@ -60,71 +60,74 @@ def gnu_getopt(args, shortopts, longopts=[]): return opts, prog_args + def do_longs(opts, opt, longopts, args): try: - i = opt.index('=') + i = opt.index("=") except ValueError: optarg = None else: - opt, optarg = opt[:i], opt[i + 1:] + opt, optarg = opt[:i], opt[i + 1 :] has_arg, opt = long_has_args(opt, longopts) if has_arg: if optarg is None: if not args: - raise GetoptError('option --%s requires argument' % opt, opt) + raise GetoptError("option --%s requires argument" % opt, opt) optarg, args = args[0], args[1:] elif optarg: - raise GetoptError('option --%s must not have an argument' % opt, opt) - opts.append(('--' + opt, optarg or '')) + raise GetoptError("option --%s must not have an argument" % opt, opt) + opts.append(("--" + opt, optarg or "")) return opts, args + # Return: # has_arg? # full option name def long_has_args(opt, longopts): possibilities = [o for o in longopts if o.startswith(opt)] if not possibilities: - raise GetoptError('option --%s not recognized' % opt, opt) + raise GetoptError("option --%s not recognized" % opt, opt) # Is there an exact match? if opt in possibilities: return False, opt - elif opt + '=' in possibilities: + elif opt + "=" in possibilities: return True, opt # No exact match, so better be unique. if len(possibilities) > 1: # XXX since possibilities contains all valid continuations, might be # nice to work them into the error msg - raise GetoptError('option --%s not a unique prefix' % opt, opt) + raise GetoptError("option --%s not a unique prefix" % opt, opt) assert len(possibilities) == 1 unique_match = possibilities[0] - has_arg = unique_match.endswith('=') + has_arg = unique_match.endswith("=") if has_arg: unique_match = unique_match[:-1] return has_arg, unique_match + def do_shorts(opts, optstring, shortopts, args): - while optstring != '': + while optstring != "": opt, optstring = optstring[0], optstring[1:] if short_has_arg(opt, shortopts): - if optstring == '': + if optstring == "": if not args: - raise GetoptError('option -%s requires argument' % opt, - opt) + raise GetoptError("option -%s requires argument" % opt, opt) optstring, args = args[0], args[1:] - optarg, optstring = optstring, '' + optarg, optstring = optstring, "" else: - optarg = '' - opts.append(('-' + opt, optarg)) + optarg = "" + opts.append(("-" + opt, optarg)) return opts, args + def short_has_arg(opt, shortopts): for i in range(len(shortopts)): - if opt == shortopts[i] != ':': - return shortopts.startswith(':', i + 1) - raise GetoptError('option -%s not recognized' % opt, opt) + if opt == shortopts[i] != ":": + return shortopts.startswith(":", i + 1) + raise GetoptError("option -%s not recognized" % opt, opt) -#======================================================================================================================= +# ======================================================================================================================= # End getopt code -#======================================================================================================================= +# ======================================================================================================================= diff --git a/_pydev_bundle/_pydev_imports_tipper.py b/_pydev_bundle/_pydev_imports_tipper.py index 7f89c750d..b8f0abc1e 100644 --- a/_pydev_bundle/_pydev_imports_tipper.py +++ b/_pydev_bundle/_pydev_imports_tipper.py @@ -14,28 +14,28 @@ def getargspec(*args, **kwargs): # completion types. -TYPE_IMPORT = '0' -TYPE_CLASS = '1' -TYPE_FUNCTION = '2' -TYPE_ATTR = '3' -TYPE_BUILTIN = '4' -TYPE_PARAM = '5' +TYPE_IMPORT = "0" +TYPE_CLASS = "1" +TYPE_FUNCTION = "2" +TYPE_ATTR = "3" +TYPE_BUILTIN = "4" +TYPE_PARAM = "5" def _imp(name, log=None): try: return __import__(name) except: - if '.' in name: - sub = name[0:name.rfind('.')] + if "." in name: + sub = name[0 : name.rfind(".")] if log is not None: - log.add_content('Unable to import', name, 'trying with', sub) + log.add_content("Unable to import", name, "trying with", sub) log.add_exception() return _imp(sub, log) else: - s = 'Unable to import module: %s - sys.path: %s' % (str(name), sys.path) + s = "Unable to import module: %s - sys.path: %s" % (str(name), sys.path) if log is not None: log.add_content(s) log.add_exception() @@ -44,20 +44,21 @@ def _imp(name, log=None): IS_IPY = False -if sys.platform == 'cli': +if sys.platform == "cli": IS_IPY = True _old_imp = _imp def _imp(name, log=None): # We must add a reference in clr for .Net import clr # @UnresolvedImport + initial_name = name - while '.' in name: + while "." in name: try: clr.AddReference(name) break # If it worked, that's OK. except: - name = name[0:name.rfind('.')] + name = name[0 : name.rfind(".")] else: try: clr.AddReference(name) @@ -73,11 +74,11 @@ def get_file(mod): f = inspect.getsourcefile(mod) or inspect.getfile(mod) except: try: - f = getattr(mod, '__file__', None) + f = getattr(mod, "__file__", None) except: f = None - if f and f.lower(f[-4:]) in ['.pyc', '.pyo']: - filename = f[:-4] + '.py' + if f and f.lower(f[-4:]) in [".pyc", ".pyo"]: + filename = f[:-4] + ".py" if os.path.exists(filename): f = filename @@ -89,12 +90,12 @@ def Find(name, log=None): mod = _imp(name, log) parent = mod - foundAs = '' + foundAs = "" if inspect.ismodule(mod): f = get_file(mod) - components = name.split('.') + components = name.split(".") old_comp = None for comp in components[1:]: @@ -111,7 +112,7 @@ def Find(name, log=None): f = get_file(mod) else: if len(foundAs) > 0: - foundAs = foundAs + '.' + foundAs = foundAs + "." foundAs = foundAs + comp old_comp = comp @@ -120,12 +121,11 @@ def Find(name, log=None): def search_definition(data): - '''@return file, line, col - ''' + """@return file, line, col""" - data = data.replace('\n', '') - if data.endswith('.'): - data = data.rstrip('.') + data = data.replace("\n", "") + if data.endswith("."): + data = data.rstrip(".") f, mod, parent, foundAs = Find(data) try: return do_find(f, mod), foundAs @@ -134,9 +134,9 @@ def search_definition(data): def generate_tip(data, log=None): - data = data.replace('\n', '') - if data.endswith('.'): - data = data.rstrip('.') + data = data.replace("\n", "") + if data.endswith("."): + data = data.rstrip(".") f, mod, parent, foundAs = Find(data, log) # print_ >> open('temp.txt', 'w'), f @@ -145,31 +145,31 @@ def generate_tip(data, log=None): def check_char(c): - if c == '-' or c == '.': - return '_' + if c == "-" or c == ".": + return "_" return c _SENTINEL = object() -def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=getattr, filter=lambda name:True): - ''' - @param obj_to_complete: the object from where we should get the completions - @param dir_comps: if passed, we should not 'dir' the object and should just iterate those passed as kwonly_arg parameter - @param getattr: the way to get kwonly_arg given object from the obj_to_complete (used for the completer) - @param filter: kwonly_arg callable that receives the name and decides if it should be appended or not to the results - @return: list of tuples, so that each tuple represents kwonly_arg completion with: - name, doc, args, type (from the TYPE_* constants) - ''' +def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=getattr, filter=lambda name: True): + """ + @param obj_to_complete: the object from where we should get the completions + @param dir_comps: if passed, we should not 'dir' the object and should just iterate those passed as kwonly_arg parameter + @param getattr: the way to get kwonly_arg given object from the obj_to_complete (used for the completer) + @param filter: kwonly_arg callable that receives the name and decides if it should be appended or not to the results + @return: list of tuples, so that each tuple represents kwonly_arg completion with: + name, doc, args, type (from the TYPE_* constants) + """ ret = [] if dir_comps is None: dir_comps = dir_checked(obj_to_complete) - if hasattr_checked(obj_to_complete, '__dict__'): - dir_comps.append('__dict__') - if hasattr_checked(obj_to_complete, '__class__'): - dir_comps.append('__class__') + if hasattr_checked(obj_to_complete, "__dict__"): + dir_comps.append("__dict__") + if hasattr_checked(obj_to_complete, "__class__"): + dir_comps.append("__class__") get_complete_info = True @@ -182,31 +182,31 @@ def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=get dontGetDocsOn = (float, int, str, tuple, list, dict) dontGetattrOn = (dict, list, set, tuple) for d in dir_comps: - if d is None: continue if not filter(d): continue - args = '' + args = "" try: try: if isinstance(obj_to_complete, dontGetattrOn): - raise Exception('Since python 3.9, e.g. "dict[str]" will return' - " a dict that's only supposed to take strings. " - 'Interestingly, e.g. dict["val"] is also valid ' - 'and presumably represents a dict that only takes ' - 'keys that are "val". This breaks our check for ' - 'class attributes.') + raise Exception( + 'Since python 3.9, e.g. "dict[str]" will return' + " a dict that's only supposed to take strings. " + 'Interestingly, e.g. dict["val"] is also valid ' + "and presumably represents a dict that only takes " + 'keys that are "val". This breaks our check for ' + "class attributes." + ) obj = getattr(obj_to_complete.__class__, d) except: obj = getattr(obj_to_complete, d) except: # just ignore and get it without additional info - ret.append((d, '', args, TYPE_BUILTIN)) + ret.append((d, "", args, TYPE_BUILTIN)) else: - if get_complete_info: try: retType = TYPE_BUILTIN @@ -214,21 +214,20 @@ def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=get # check if we have to get docs getDoc = True for class_ in dontGetDocsOn: - if isinstance(obj, class_): getDoc = False break - doc = '' + doc = "" if getDoc: # no need to get this info... too many constants are defined and # makes things much slower (passing all that through sockets takes quite some time) try: doc = inspect.getdoc(obj) if doc is None: - doc = '' + doc = "" except: # may happen on jython when checking java classes (so, just ignore it) - doc = '' + doc = "" if inspect.ismethod(obj) or inspect.isbuiltin(obj) or inspect.isfunction(obj) or inspect.isroutine(obj): try: @@ -239,14 +238,14 @@ def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=get for kwonly_arg in kwonly_args: default = kwonly_defaults.get(kwonly_arg, _SENTINEL) if default is not _SENTINEL: - args.append('%s=%s' % (kwonly_arg, default)) + args.append("%s=%s" % (kwonly_arg, default)) else: args.append(str(kwonly_arg)) - args = '(%s)' % (', '.join(args)) + args = "(%s)" % (", ".join(args)) except TypeError: # ok, let's see if we can get the arguments from the doc - args, doc = signature_from_docstring(doc, getattr(obj, '__name__', None)) + args, doc = signature_from_docstring(doc, getattr(obj, "__name__", None)) retType = TYPE_FUNCTION @@ -263,7 +262,7 @@ def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=get ret.append((d, doc, args, retType)) except: # just ignore and get it without aditional info - ret.append((d, '', args, TYPE_BUILTIN)) + ret.append((d, "", args, TYPE_BUILTIN)) else: # get_complete_info == False if inspect.ismethod(obj) or inspect.isbuiltin(obj) or inspect.isfunction(obj) or inspect.isroutine(obj): @@ -279,13 +278,13 @@ def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=get retType = TYPE_ATTR # ok, no complete info, let's try to do this as fast and clean as possible # so, no docs for this kind of information, only the signatures - ret.append((d, '', str(args), retType)) + ret.append((d, "", str(args), retType)) return ret def signature_from_docstring(doc, obj_name): - args = '()' + args = "()" try: found = False if len(doc) > 0: @@ -301,50 +300,50 @@ def signature_from_docstring(doc, obj_name): # sort(self: list) # sort(self: list, cmp: object) if obj_name: - name = obj_name + '(' + name = obj_name + "(" # Fix issue where it was appearing sort(aa)sort(bb)sort(cc) in the same line. lines = doc.splitlines() if len(lines) == 1: c = doc.count(name) if c > 1: - doc = ('\n' + name).join(doc.split(name)) + doc = ("\n" + name).join(doc.split(name)) - major = '' + major = "" for line in doc.splitlines(): - if line.startswith(name) and line.endswith(')'): + if line.startswith(name) and line.endswith(")"): if len(line) > len(major): major = line if major: - args = major[major.index('('):] + args = major[major.index("(") :] found = True if not found: - i = doc.find('->') + i = doc.find("->") if i < 0: - i = doc.find('--') + i = doc.find("--") if i < 0: - i = doc.find('\n') + i = doc.find("\n") if i < 0: - i = doc.find('\r') + i = doc.find("\r") if i > 0: s = doc[0:i] s = s.strip() # let's see if we have a docstring in the first line - if s[-1] == ')': - start = s.find('(') + if s[-1] == ")": + start = s.find("(") if start >= 0: - end = s.find('[') + end = s.find("[") if end <= 0: - end = s.find(')') + end = s.find(")") if end <= 0: end = len(s) args = s[start:end] - if not args[-1] == ')': - args = args + ')' + if not args[-1] == ")": + args = args + ")" # now, get rid of unwanted chars l = len(args) - 1 @@ -355,18 +354,18 @@ def signature_from_docstring(doc, obj_name): else: r.append(check_char(args[i])) - args = ''.join(r) + args = "".join(r) if IS_IPY: - if args.startswith('(self:'): - i = args.find(',') + if args.startswith("(self:"): + i = args.find(",") if i >= 0: - args = '(self' + args[i:] + args = "(self" + args[i:] else: - args = '(self)' - i = args.find(')') + args = "(self)" + i = args.find(")") if i > 0: - args = args[:i + 1] + args = args[: i + 1] except: pass diff --git a/_pydev_bundle/_pydev_jy_imports_tipper.py b/_pydev_bundle/_pydev_jy_imports_tipper.py index a30c4d35e..d1265de83 100644 --- a/_pydev_bundle/_pydev_jy_imports_tipper.py +++ b/_pydev_bundle/_pydev_jy_imports_tipper.py @@ -12,48 +12,49 @@ from org.python.core import PyClass # @UnresolvedImport # completion types. -TYPE_IMPORT = '0' -TYPE_CLASS = '1' -TYPE_FUNCTION = '2' -TYPE_ATTR = '3' -TYPE_BUILTIN = '4' -TYPE_PARAM = '5' +TYPE_IMPORT = "0" +TYPE_CLASS = "1" +TYPE_FUNCTION = "2" +TYPE_ATTR = "3" +TYPE_BUILTIN = "4" +TYPE_PARAM = "5" def _imp(name): try: return __import__(name) except: - if '.' in name: - sub = name[0:name.rfind('.')] + if "." in name: + sub = name[0 : name.rfind(".")] return _imp(sub) else: - s = 'Unable to import module: %s - sys.path: %s' % (str(name), sys.path) + s = "Unable to import module: %s - sys.path: %s" % (str(name), sys.path) raise RuntimeError(s) import java.util -_java_rt_file = getattr(java.util, '__file__', None) + +_java_rt_file = getattr(java.util, "__file__", None) def Find(name): f = None - if name.startswith('__builtin__'): - if name == '__builtin__.str': - name = 'org.python.core.PyString' - elif name == '__builtin__.dict': - name = 'org.python.core.PyDictionary' + if name.startswith("__builtin__"): + if name == "__builtin__.str": + name = "org.python.core.PyString" + elif name == "__builtin__.dict": + name = "org.python.core.PyDictionary" mod = _imp(name) parent = mod - foundAs = '' + foundAs = "" try: - f = getattr(mod, '__file__', None) + f = getattr(mod, "__file__", None) except: f = None - components = name.split('.') + components = name.split(".") old_comp = None for comp in components[1:]: try: @@ -65,98 +66,95 @@ def Find(name): if old_comp != comp: raise - if hasattr(mod, '__file__'): + if hasattr(mod, "__file__"): f = mod.__file__ else: if len(foundAs) > 0: - foundAs = foundAs + '.' + foundAs = foundAs + "." foundAs = foundAs + comp old_comp = comp - if f is None and name.startswith('java.lang'): + if f is None and name.startswith("java.lang"): # Hack: java.lang.__file__ is None on Jython 2.7 (whereas it pointed to rt.jar on Jython 2.5). f = _java_rt_file if f is not None: - if f.endswith('.pyc'): + if f.endswith(".pyc"): f = f[:-1] - elif f.endswith('$py.class'): - f = f[:-len('$py.class')] + '.py' + elif f.endswith("$py.class"): + f = f[: -len("$py.class")] + ".py" return f, mod, parent, foundAs def format_param_class_name(paramClassName): - if paramClassName.startswith(''): - paramClassName = paramClassName[len('"): + paramClassName = paramClassName[len(" - paramClassName = paramClassName.split('\'')[1] + paramClassName = paramClassName.split("'")[1] except: paramClassName = repr(paramTypesClass) # just in case something else happens... it will at least be visible # if the parameter equals [C, it means it it a char array, so, let's change it @@ -281,16 +280,15 @@ def getargs(func_code): except Exception: s = StringIO() traceback.print_exc(file=s) - return 1, [Info(str('ERROR'), doc=s.getvalue())] + return 1, [Info(str("ERROR"), doc=s.getvalue())] return 0, None def ismodule(mod): # java modules... do we have other way to know that? - if not hasattr(mod, 'getClass') and not hasattr(mod, '__class__') \ - and hasattr(mod, '__name__'): - return 1 + if not hasattr(mod, "getClass") and not hasattr(mod, "__class__") and hasattr(mod, "__name__"): + return 1 return isinstance(mod, core.PyModule) @@ -299,9 +297,8 @@ def dir_obj(obj): ret = [] found = java.util.HashMap() original = obj - if hasattr(obj, '__class__'): + if hasattr(obj, "__class__"): if obj.__class__ == java.lang.Class: - # get info about superclasses classes = [] classes.append(obj) @@ -364,16 +361,15 @@ def dir_obj(obj): def format_arg(arg): - '''formats an argument to be shown - ''' + """formats an argument to be shown""" s = str(arg) - dot = s.rfind('.') + dot = s.rfind(".") if dot >= 0: - s = s[dot + 1:] + s = s[dot + 1 :] - s = s.replace(';', '') - s = s.replace('[]', 'Array') + s = s.replace(";", "") + s = s.replace("[]", "Array") if len(s) > 0: c = s[0].lower() s = c + s[1:] @@ -382,12 +378,11 @@ def format_arg(arg): def search_definition(data): - '''@return file, line, col - ''' + """@return file, line, col""" - data = data.replace('\n', '') - if data.endswith('.'): - data = data.rstrip('.') + data = data.replace("\n", "") + if data.endswith("."): + data = data.rstrip(".") f, mod, parent, foundAs = Find(data) try: return do_find(f, mod), foundAs @@ -395,30 +390,29 @@ def search_definition(data): return do_find(f, parent), foundAs -def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=getattr, filter=lambda name:True): - ''' - @param obj_to_complete: the object from where we should get the completions - @param dir_comps: if passed, we should not 'dir' the object and should just iterate those passed as a parameter - @param getattr: the way to get a given object from the obj_to_complete (used for the completer) - @param filter: a callable that receives the name and decides if it should be appended or not to the results - @return: list of tuples, so that each tuple represents a completion with: - name, doc, args, type (from the TYPE_* constants) - ''' +def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=getattr, filter=lambda name: True): + """ + @param obj_to_complete: the object from where we should get the completions + @param dir_comps: if passed, we should not 'dir' the object and should just iterate those passed as a parameter + @param getattr: the way to get a given object from the obj_to_complete (used for the completer) + @param filter: a callable that receives the name and decides if it should be appended or not to the results + @return: list of tuples, so that each tuple represents a completion with: + name, doc, args, type (from the TYPE_* constants) + """ ret = [] if dir_comps is None: dir_comps = dir_obj(obj_to_complete) for d in dir_comps: - if d is None: continue if not filter(d): continue - args = '' - doc = '' + args = "" + doc = "" retType = TYPE_BUILTIN try: @@ -452,26 +446,25 @@ def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=get # # whereas if we had added the jar to the classpath before, everything would be fine by now... - ret.append((d, '', '', retType)) + ret.append((d, "", "", retType)) # that's ok, private things cannot be gotten... continue else: - isMet = ismethod(obj) if isMet[0] and isMet[1]: info = isMet[1][0] try: args, vargs, kwargs = info.args, info.varargs, info.kwargs doc = info.get_as_doc() - r = '' - for a in (args): + r = "" + for a in args: if len(r) > 0: - r += ', ' + r += ", " r += format_arg(a) - args = '(%s)' % (r) + args = "(%s)" % (r) except TypeError: traceback.print_exc() - args = '()' + args = "()" retType = TYPE_FUNCTION @@ -488,5 +481,5 @@ def generate_imports_tip_for_module(obj_to_complete, dir_comps=None, getattr=get if __name__ == "__main__": - sys.path.append(r'D:\dev_programs\eclipse_3\310\eclipse\plugins\org.junit_3.8.1\junit.jar') - sys.stdout.write('%s\n' % Find('junit.framework.TestCase')) + sys.path.append(r"D:\dev_programs\eclipse_3\310\eclipse\plugins\org.junit_3.8.1\junit.jar") + sys.stdout.write("%s\n" % Find("junit.framework.TestCase")) diff --git a/_pydev_bundle/_pydev_log.py b/_pydev_bundle/_pydev_log.py index 7328d6213..5c9580fce 100644 --- a/_pydev_bundle/_pydev_log.py +++ b/_pydev_bundle/_pydev_log.py @@ -4,12 +4,11 @@ class Log: - def __init__(self): self._contents = [] def add_content(self, *content): - self._contents.append(' '.join(content)) + self._contents.append(" ".join(content)) def add_exception(self): s = StringIO() @@ -18,7 +17,7 @@ def add_exception(self): self._contents.append(s.getvalue()) def get_contents(self): - return '\n'.join(self._contents) + return "\n".join(self._contents) def clear_log(self): del self._contents[:] diff --git a/_pydev_bundle/_pydev_saved_modules.py b/_pydev_bundle/_pydev_saved_modules.py index bdc19e467..f1ba03766 100644 --- a/_pydev_bundle/_pydev_saved_modules.py +++ b/_pydev_bundle/_pydev_saved_modules.py @@ -10,10 +10,10 @@ def find_in_pythonpath(module_name): # this should be rare in general). found_at = [] - parts = module_name.split('.') # split because we need to convert mod.name to mod/name + parts = module_name.split(".") # split because we need to convert mod.name to mod/name for path in sys.path: target = os.path.join(path, *parts) - target_py = target + '.py' + target_py = target + ".py" if os.path.isdir(target): found_at.append(target) if os.path.exists(target_py): @@ -26,7 +26,6 @@ class DebuggerInitializationError(Exception): class VerifyShadowedImport(object): - def __init__(self, import_name): self.import_name = import_name @@ -53,17 +52,19 @@ def __exit__(self, exc_type, exc_val, exc_tb): raise DebuggerInitializationError(msg) def _generate_shadowed_import_message(self, found_at): - msg = '''It was not possible to initialize the debugger due to a module name conflict. + msg = """It was not possible to initialize the debugger due to a module name conflict. i.e.: the module "%(import_name)s" could not be imported because it is shadowed by: %(found_at)s -Please rename this file/folder so that the original module from the standard library can be imported.''' % { - 'import_name': self.import_name, 'found_at': found_at[0]} +Please rename this file/folder so that the original module from the standard library can be imported.""" % { + "import_name": self.import_name, + "found_at": found_at[0], + } return msg def check(self, module, expected_attributes): - msg = '' + msg = "" for expected_attribute in expected_attributes: try: getattr(module, expected_attribute) @@ -75,38 +76,58 @@ def check(self, module, expected_attributes): raise DebuggerInitializationError(msg) -with VerifyShadowedImport('threading') as verify_shadowed: - import threading; verify_shadowed.check(threading, ['Thread', 'settrace', 'setprofile', 'Lock', 'RLock', 'current_thread']) +with VerifyShadowedImport("threading") as verify_shadowed: + import threading + + verify_shadowed.check(threading, ["Thread", "settrace", "setprofile", "Lock", "RLock", "current_thread"]) ThreadingEvent = threading.Event ThreadingLock = threading.Lock threading_current_thread = threading.current_thread -with VerifyShadowedImport('time') as verify_shadowed: - import time; verify_shadowed.check(time, ['sleep', 'time', 'mktime']) +with VerifyShadowedImport("time") as verify_shadowed: + import time + + verify_shadowed.check(time, ["sleep", "time", "mktime"]) + +with VerifyShadowedImport("socket") as verify_shadowed: + import socket + + verify_shadowed.check(socket, ["socket", "gethostname", "getaddrinfo"]) + +with VerifyShadowedImport("select") as verify_shadowed: + import select + + verify_shadowed.check(select, ["select"]) + +with VerifyShadowedImport("code") as verify_shadowed: + import code as _code + + verify_shadowed.check(_code, ["compile_command", "InteractiveInterpreter"]) + +with VerifyShadowedImport("_thread") as verify_shadowed: + import _thread as thread + + verify_shadowed.check(thread, ["start_new_thread", "start_new", "allocate_lock"]) -with VerifyShadowedImport('socket') as verify_shadowed: - import socket; verify_shadowed.check(socket, ['socket', 'gethostname', 'getaddrinfo']) +with VerifyShadowedImport("queue") as verify_shadowed: + import queue as _queue -with VerifyShadowedImport('select') as verify_shadowed: - import select; verify_shadowed.check(select, ['select']) + verify_shadowed.check(_queue, ["Queue", "LifoQueue", "Empty", "Full", "deque"]) -with VerifyShadowedImport('code') as verify_shadowed: - import code as _code; verify_shadowed.check(_code, ['compile_command', 'InteractiveInterpreter']) +with VerifyShadowedImport("xmlrpclib") as verify_shadowed: + import xmlrpc.client as xmlrpclib -with VerifyShadowedImport('_thread') as verify_shadowed: - import _thread as thread; verify_shadowed.check(thread, ['start_new_thread', 'start_new', 'allocate_lock']) + verify_shadowed.check(xmlrpclib, ["ServerProxy", "Marshaller", "Server"]) -with VerifyShadowedImport('queue') as verify_shadowed: - import queue as _queue; verify_shadowed.check(_queue, ['Queue', 'LifoQueue', 'Empty', 'Full', 'deque']) +with VerifyShadowedImport("xmlrpc.server") as verify_shadowed: + import xmlrpc.server as xmlrpcserver -with VerifyShadowedImport('xmlrpclib') as verify_shadowed: - import xmlrpc.client as xmlrpclib; verify_shadowed.check(xmlrpclib, ['ServerProxy', 'Marshaller', 'Server']) + verify_shadowed.check(xmlrpcserver, ["SimpleXMLRPCServer"]) -with VerifyShadowedImport('xmlrpc.server') as verify_shadowed: - import xmlrpc.server as xmlrpcserver; verify_shadowed.check(xmlrpcserver, ['SimpleXMLRPCServer']) +with VerifyShadowedImport("http.server") as verify_shadowed: + import http.server as BaseHTTPServer -with VerifyShadowedImport('http.server') as verify_shadowed: - import http.server as BaseHTTPServer; verify_shadowed.check(BaseHTTPServer, ['BaseHTTPRequestHandler']) + verify_shadowed.check(BaseHTTPServer, ["BaseHTTPRequestHandler"]) # If set, this is a version of the threading.enumerate that doesn't have the patching to remove the pydevd threads. # Note: as it can't be set during execution, don't import the name (import the module and access it through its name). diff --git a/_pydev_bundle/_pydev_sys_patch.py b/_pydev_bundle/_pydev_sys_patch.py index fdaa967a1..23e7d4f54 100644 --- a/_pydev_bundle/_pydev_sys_patch.py +++ b/_pydev_bundle/_pydev_sys_patch.py @@ -2,9 +2,7 @@ def patch_sys_module(): - def patched_exc_info(fun): - def pydev_debugger_exc_info(): type, value, traceback = fun() if type == ImportError: @@ -22,7 +20,6 @@ def pydev_debugger_exc_info(): def patched_reload(orig_reload): - def pydev_debugger_reload(module): orig_reload(module) if module.__name__ == "sys": @@ -40,6 +37,7 @@ def patch_reload(): builtins.reload = patched_reload(sys.builtin_orig_reload) # @UndefinedVariable try: import imp + sys.imp_orig_reload = imp.reload imp.reload = patched_reload(sys.imp_orig_reload) # @UndefinedVariable except ImportError: @@ -47,6 +45,7 @@ def patch_reload(): else: try: import importlib + sys.importlib_orig_reload = importlib.reload # @UndefinedVariable importlib.reload = patched_reload(sys.importlib_orig_reload) # @UndefinedVariable except: @@ -65,12 +64,14 @@ def cancel_patches_in_sys_module(): if hasattr(sys, "imp_orig_reload"): try: import imp + imp.reload = sys.imp_orig_reload except ImportError: pass # Ok, imp not available in Python 3.12. if hasattr(sys, "importlib_orig_reload"): import importlib + importlib.reload = sys.importlib_orig_reload del builtins diff --git a/_pydev_bundle/_pydev_tipper_common.py b/_pydev_bundle/_pydev_tipper_common.py index d97e95d1f..25c0f6fdb 100644 --- a/_pydev_bundle/_pydev_tipper_common.py +++ b/_pydev_bundle/_pydev_tipper_common.py @@ -4,6 +4,7 @@ def do_find(f, mod): import linecache + if inspect.ismodule(mod): return f, 0, 0 @@ -11,7 +12,7 @@ def do_find(f, mod): if inspect.isclass(mod): name = mod.__name__ - pat = re.compile(r'^\s*class\s*' + name + r'\b') + pat = re.compile(r"^\s*class\s*" + name + r"\b") for i in range(len(lines)): if pat.match(lines[i]): return f, i, 0 @@ -34,14 +35,14 @@ def do_find(f, mod): mod = mod.f_code if inspect.iscode(mod): - if not hasattr(mod, 'co_filename'): + if not hasattr(mod, "co_filename"): return None, 0, 0 - if not hasattr(mod, 'co_firstlineno'): + if not hasattr(mod, "co_firstlineno"): return mod.co_filename, 0, 0 lnum = mod.co_firstlineno - pat = re.compile(r'^(\s*def\s)|(.*(? 0: if pat.match(lines[lnum]): break @@ -49,4 +50,4 @@ def do_find(f, mod): return f, lnum, 0 - raise RuntimeError('Do not know about: ' + f + ' ' + str(mod)) + raise RuntimeError("Do not know about: " + f + " " + str(mod)) diff --git a/_pydev_bundle/fsnotify/__init__.py b/_pydev_bundle/fsnotify/__init__.py index 708e442b1..c661b40b1 100644 --- a/_pydev_bundle/fsnotify/__init__.py +++ b/_pydev_bundle/fsnotify/__init__.py @@ -1,4 +1,4 @@ -''' +""" Sample usage to track changes in a thread. import threading @@ -36,7 +36,7 @@ def start_watching(): # Called from thread Note: changes are only reported for files (added/modified/deleted), not directories. -''' +""" import sys from os.path import basename from _pydev_bundle import pydev_log, _pydev_saved_modules @@ -49,11 +49,12 @@ def start_watching(): # Called from thread class IntEnum(object): pass + import time -__author__ = 'Fabio Zadrozny' -__email__ = 'fabiofz@gmail.com' -__version__ = '0.1.5' # Version here and in setup.py +__author__ = "Fabio Zadrozny" +__email__ = "fabiofz@gmail.com" +__version__ = "0.1.5" # Version here and in setup.py class Change(IntEnum): @@ -63,7 +64,6 @@ class Change(IntEnum): class _SingleVisitInfo(object): - def __init__(self): self.count = 0 self.visited_dirs = set() @@ -72,18 +72,18 @@ def __init__(self): class _PathWatcher(object): - ''' + """ Helper to watch a single path. - ''' + """ - def __init__(self, root_path, accept_directory, accept_file, single_visit_info, max_recursion_level, sleep_time=.0): - ''' + def __init__(self, root_path, accept_directory, accept_file, single_visit_info, max_recursion_level, sleep_time=0.0): + """ :type root_path: str :type accept_directory: Callback[str, bool] :type accept_file: Callback[str, bool] :type max_recursion_level: int :type sleep_time: float - ''' + """ self.accept_directory = accept_directory self.accept_file = accept_file self._max_recursion_level = max_recursion_level @@ -94,7 +94,7 @@ def __init__(self, root_path, accept_directory, accept_file, single_visit_info, # Watcher.target_time_for_single_scan. self.sleep_time = sleep_time - self.sleep_at_elapsed = 1. / 30. + self.sleep_at_elapsed = 1.0 / 30.0 # When created, do the initial snapshot right away! old_file_to_mtime = {} @@ -123,7 +123,7 @@ def _check_dir(self, dir_path, single_visit_info, append_change, old_file_to_mti dir_path = dir_path.decode(sys.getfilesystemencoding()) except UnicodeDecodeError: try: - dir_path = dir_path.decode('utf-8') + dir_path = dir_path.decode("utf-8") except UnicodeDecodeError: return # Ignore if we can't deal with the path. @@ -166,10 +166,9 @@ def _check(self, single_visit_info, append_change, old_file_to_mtime): class Watcher(object): - # By default (if accept_directory is not specified), these will be the # ignored directories. - ignored_dirs = {u'.git', u'__pycache__', u'.idea', u'node_modules', u'.metadata'} + ignored_dirs = {".git", "__pycache__", ".idea", "node_modules", ".metadata"} # By default (if accept_file is not specified), these will be the # accepted files. @@ -194,7 +193,7 @@ class Watcher(object): max_recursion_level = 10 def __init__(self, accept_directory=None, accept_file=None): - ''' + """ :param Callable[str, bool] accept_directory: Callable that returns whether a directory should be watched. Note: if passed it'll override the `ignored_dirs` @@ -202,15 +201,14 @@ def __init__(self, accept_directory=None, accept_file=None): :param Callable[str, bool] accept_file: Callable that returns whether a file should be watched. Note: if passed it'll override the `accepted_file_extensions`. - ''' + """ self._path_watchers = set() self._disposed = _pydev_saved_modules.ThreadingEvent() if accept_directory is None: accept_directory = lambda dir_path: basename(dir_path) not in self.ignored_dirs if accept_file is None: - accept_file = lambda path_name: \ - not self.accepted_file_extensions or path_name.endswith(self.accepted_file_extensions) + accept_file = lambda path_name: not self.accepted_file_extensions or path_name.endswith(self.accepted_file_extensions) self.accept_file = accept_file self.accept_directory = accept_directory self._single_visit_info = _SingleVisitInfo() @@ -252,14 +250,14 @@ def set_tracked_paths(self, paths): # Sort by the path len so that the bigger paths come first (so, # if there's any nesting we want the nested paths to be visited # before the parent paths so that the max_recursion_level is correct). - paths = sorted(set(paths), key=lambda path:-len(path)) + paths = sorted(set(paths), key=lambda path: -len(path)) path_watchers = set() self._single_visit_info = _SingleVisitInfo() initial_time = time.time() for path in paths: - sleep_time = 0. # When collecting the first time, sleep_time should be 0! + sleep_time = 0.0 # When collecting the first time, sleep_time should be 0! path_watcher = _PathWatcher( path, self.accept_directory, @@ -271,22 +269,22 @@ def set_tracked_paths(self, paths): path_watchers.add(path_watcher) - actual_time = (time.time() - initial_time) + actual_time = time.time() - initial_time - pydev_log.debug('Tracking the following paths for changes: %s', paths) - pydev_log.debug('Time to track: %.2fs', actual_time) - pydev_log.debug('Folders found: %s', len(self._single_visit_info.visited_dirs)) - pydev_log.debug('Files found: %s', len(self._single_visit_info.file_to_mtime)) + pydev_log.debug("Tracking the following paths for changes: %s", paths) + pydev_log.debug("Time to track: %.2fs", actual_time) + pydev_log.debug("Folders found: %s", len(self._single_visit_info.visited_dirs)) + pydev_log.debug("Files found: %s", len(self._single_visit_info.file_to_mtime)) self._path_watchers = path_watchers def iter_changes(self): - ''' + """ Continuously provides changes (until dispose() is called). Changes provided are tuples with the Change enum and filesystem path. :rtype: Iterable[Tuple[Change, str]] - ''' + """ while not self._disposed.is_set(): initial_time = time.time() @@ -306,9 +304,9 @@ def iter_changes(self): for change in changes: yield change - actual_time = (time.time() - initial_time) + actual_time = time.time() - initial_time if self.print_poll_time: - print('--- Total poll time: %.3fs' % actual_time) + print("--- Total poll time: %.3fs" % actual_time) if actual_time > 0: if self.target_time_for_single_scan <= 0.0: @@ -321,8 +319,8 @@ def iter_changes(self): # direction). # (to prevent from cases where the user puts the machine on sleep and # values become too skewed). - if perc > 2.: - perc = 2. + if perc > 2.0: + perc = 2.0 elif perc < 0.5: perc = 0.5 @@ -336,7 +334,7 @@ def iter_changes(self): # (to prevent from cases where the user puts the machine on sleep and # values become too skewed). diff_sleep_time = new_sleep_time - path_watcher.sleep_time - path_watcher.sleep_time += (diff_sleep_time / (3.0 * len(self._path_watchers))) + path_watcher.sleep_time += diff_sleep_time / (3.0 * len(self._path_watchers)) if actual_time > 0: self._disposed.wait(actual_time) @@ -347,6 +345,5 @@ def iter_changes(self): # print('new sleep time: %s' % path_watcher.sleep_time) diff = self.target_time_for_notification - actual_time - if diff > 0.: + if diff > 0.0: self._disposed.wait(diff) - diff --git a/_pydev_bundle/pydev_console_utils.py b/_pydev_bundle/pydev_console_utils.py index 5c87ac82a..780ff5e4b 100644 --- a/_pydev_bundle/pydev_console_utils.py +++ b/_pydev_bundle/pydev_console_utils.py @@ -2,11 +2,10 @@ import sys import traceback from _pydev_bundle.pydev_imports import xmlrpclib, _queue, Exec -from _pydev_bundle._pydev_calltip_util import get_description +from _pydev_bundle._pydev_calltip_util import get_description from _pydevd_bundle import pydevd_vars from _pydevd_bundle import pydevd_xml -from _pydevd_bundle.pydevd_constants import (IS_JYTHON, NEXT_VALUE_SEPARATOR, get_global_debugger, - silence_warnings_decorator) +from _pydevd_bundle.pydevd_constants import IS_JYTHON, NEXT_VALUE_SEPARATOR, get_global_debugger, silence_warnings_decorator from contextlib import contextmanager from _pydev_bundle import pydev_log from _pydevd_bundle.pydevd_utils import interrupt_main_thread @@ -18,7 +17,6 @@ # BaseStdIn # ======================================================================================================================= class BaseStdIn: - def __init__(self, original_stdin=sys.stdin, *args, **kwargs): try: self.encoding = sys.stdin.encoding @@ -37,7 +35,7 @@ def readline(self, *args, **kwargs): # sys.stderr.write('Cannot readline out of the console evaluation\n') -- don't show anything # This could happen if the user had done input('enter number).<-- upon entering this, that message would appear, # which is not something we want. - return '\n' + return "\n" def write(self, *args, **kwargs): pass # not available StdIn (but it can be expected to be in the stream interface) @@ -67,9 +65,9 @@ def __getattr__(self, item): # StdIn # ======================================================================================================================= class StdIn(BaseStdIn): - ''' - Object to be added to stdin (to emulate it as non-blocking while the next line arrives) - ''' + """ + Object to be added to stdin (to emulate it as non-blocking while the next line arrives) + """ def __init__(self, interpreter, host, client_port, original_stdin=sys.stdin): BaseStdIn.__init__(self, original_stdin) @@ -80,36 +78,36 @@ def __init__(self, interpreter, host, client_port, original_stdin=sys.stdin): def readline(self, *args, **kwargs): # Ok, callback into the client to get the new input try: - server = xmlrpclib.Server('http://%s:%s' % (self.host, self.client_port)) + server = xmlrpclib.Server("http://%s:%s" % (self.host, self.client_port)) requested_input = server.RequestInput() if not requested_input: - return '\n' # Yes, a readline must return something (otherwise we can get an EOFError on the input() call). + return "\n" # Yes, a readline must return something (otherwise we can get an EOFError on the input() call). else: # readline should end with '\n' (not doing so makes IPython 5 remove the last *valid* character). - requested_input += '\n' + requested_input += "\n" return requested_input except KeyboardInterrupt: raise # Let KeyboardInterrupt go through -- #PyDev-816: Interrupting infinite loop in the Interactive Console except: - return '\n' + return "\n" def close(self, *args, **kwargs): pass # expected in StdIn -#======================================================================================================================= +# ======================================================================================================================= # DebugConsoleStdIn -#======================================================================================================================= +# ======================================================================================================================= class DebugConsoleStdIn(BaseStdIn): - ''' - Object to be added to stdin (to emulate it as non-blocking while the next line arrives) - ''' + """ + Object to be added to stdin (to emulate it as non-blocking while the next line arrives) + """ def __init__(self, py_db, original_stdin): - ''' + """ :param py_db: If None, get_global_debugger() is used. - ''' + """ BaseStdIn.__init__(self, original_stdin) self._py_db = py_db self._in_notification = 0 @@ -150,7 +148,6 @@ def read(self, *args, **kwargs): class CodeFragment: - def __init__(self, text, is_single_line=True): self.text = text self.is_single_line = is_single_line @@ -165,7 +162,6 @@ def append(self, code_fragment): # BaseInterpreterInterface # ======================================================================================================================= class BaseInterpreterInterface: - def __init__(self, mainThread, connect_status_queue=None): self.mainThread = mainThread self.interruptable = False @@ -177,17 +173,18 @@ def __init__(self, mainThread, connect_status_queue=None): self.init_mpl_modules_for_patching() def build_banner(self): - return 'print({0})\n'.format(repr(self.get_greeting_msg())) + return "print({0})\n".format(repr(self.get_greeting_msg())) def get_greeting_msg(self): - return 'PyDev console: starting.\n' + return "PyDev console: starting.\n" def init_mpl_modules_for_patching(self): from pydev_ipython.matplotlibtools import activate_matplotlib, activate_pylab, activate_pyplot + self.mpl_modules_for_patching = { "matplotlib": lambda: activate_matplotlib(self.enableGui), "matplotlib.pyplot": activate_pyplot, - "pylab": activate_pylab + "pylab": activate_pylab, } def need_more_for_code(self, source): @@ -195,10 +192,10 @@ def need_more_for_code(self, source): # Strangely even the IPython console is_complete said it was complete # even with a continuation char at the end. - if source.endswith('\\'): + if source.endswith("\\"): return True - if hasattr(self.interpreter, 'is_complete'): + if hasattr(self.interpreter, "is_complete"): return not self.interpreter.is_complete(source) try: # At this point, it should always be single. @@ -209,8 +206,8 @@ def need_more_for_code(self, source): # (in a single line) don't work. # Note that it won't give an error and code will be None (so, it'll # use execMultipleLines in the next call in this case). - symbol = 'single' - code = self.interpreter.compile(source, '', symbol) + symbol = "single" + code = self.interpreter.compile(source, "", symbol) except (OverflowError, SyntaxError, ValueError): # Case 1 return False @@ -243,13 +240,13 @@ def add_exec(self, code_fragment, debugger=None): original_in = sys.stdin try: help = None - if 'pydoc' in sys.modules: - pydoc = sys.modules['pydoc'] # Don't import it if it still is not there. + if "pydoc" in sys.modules: + pydoc = sys.modules["pydoc"] # Don't import it if it still is not there. - if hasattr(pydoc, 'help'): + if hasattr(pydoc, "help"): # You never know how will the API be changed, so, let's code defensively here help = pydoc.help - if not hasattr(help, 'input'): + if not hasattr(help, "input"): help = None except: # Just ignore any error here @@ -270,18 +267,18 @@ def add_exec(self, code_fragment, debugger=None): help = None if not self._input_error_printed: self._input_error_printed = True - sys.stderr.write('\nError when trying to update pydoc.help.input\n') - sys.stderr.write('(help() may not work -- please report this as a bug in the pydev bugtracker).\n\n') + sys.stderr.write("\nError when trying to update pydoc.help.input\n") + sys.stderr.write("(help() may not work -- please report this as a bug in the pydev bugtracker).\n\n") traceback.print_exc() try: self.start_exec() - if hasattr(self, 'debugger'): + if hasattr(self, "debugger"): self.debugger.enable_tracing() more = self.do_add_exec(code_fragment) - if hasattr(self, 'debugger'): + if hasattr(self, "debugger"): self.debugger.disable_tracing() self.finish_exec(more) @@ -307,19 +304,19 @@ def add_exec(self, code_fragment, debugger=None): return more def do_add_exec(self, codeFragment): - ''' + """ Subclasses should override. @return: more (True if more input is needed to complete the statement and False if the statement is complete). - ''' + """ raise NotImplementedError() def get_namespace(self): - ''' + """ Subclasses should override. @return: dict with namespace. - ''' + """ raise NotImplementedError() def __resolve_reference__(self, text): @@ -328,7 +325,7 @@ def __resolve_reference__(self, text): :type text: str """ obj = None - if '.' not in text: + if "." not in text: try: obj = self.get_namespace()[text] except KeyError: @@ -336,22 +333,22 @@ def __resolve_reference__(self, text): if obj is None: try: - obj = self.get_namespace()['__builtins__'][text] + obj = self.get_namespace()["__builtins__"][text] except: pass if obj is None: try: - obj = getattr(self.get_namespace()['__builtins__'], text, None) + obj = getattr(self.get_namespace()["__builtins__"], text, None) except: pass else: try: - last_dot = text.rindex('.') + last_dot = text.rindex(".") parent_context = text[0:last_dot] res = pydevd_vars.eval_in_context(parent_context, self.get_namespace(), self.get_namespace()) - obj = getattr(res, text[last_dot + 1:]) + obj = getattr(res, text[last_dot + 1 :]) except: pass return obj @@ -360,10 +357,10 @@ def getDescription(self, text): try: obj = self.__resolve_reference__(text) if obj is None: - return '' + return "" return get_description(obj) except: - return '' + return "" def do_exec_code(self, code, is_single_line): try: @@ -385,7 +382,7 @@ def execLine(self, line): def execMultipleLines(self, lines): if IS_JYTHON: more = False - for line in lines.split('\n'): + for line in lines.split("\n"): more = self.do_exec_code(line, True) return more else: @@ -411,8 +408,8 @@ def start_exec(self): self.interruptable = True def get_server(self): - if getattr(self, 'host', None) is not None: - return xmlrpclib.Server('http://%s:%s' % (self.host, self.client_port)) + if getattr(self, "host", None) is not None: + return xmlrpclib.Server("http://%s:%s" % (self.host, self.client_port)) else: return None @@ -485,8 +482,8 @@ def loadFullValue(self, seq, scope_attrs): var_objects = [] vars = scope_attrs.split(NEXT_VALUE_SEPARATOR) for var_attrs in vars: - if '\t' in var_attrs: - name, attrs = var_attrs.split('\t', 1) + if "\t" in var_attrs: + name, attrs = var_attrs.split("\t", 1) else: name = var_attrs @@ -499,38 +496,39 @@ def loadFullValue(self, seq, scope_attrs): var_objects.append((var_object, name)) from _pydevd_bundle.pydevd_comm import GetValueAsyncThreadConsole - py_db = getattr(self, 'debugger', None) + + py_db = getattr(self, "debugger", None) if py_db is None: py_db = get_global_debugger() if py_db is None: from pydevd import PyDB + py_db = PyDB() t = GetValueAsyncThreadConsole(py_db, self.get_server(), seq, var_objects) t.start() def changeVariable(self, attr, value): - def do_change_variable(): - Exec('%s=%s' % (attr, value), self.get_namespace(), self.get_namespace()) + Exec("%s=%s" % (attr, value), self.get_namespace(), self.get_namespace()) # Important: it has to be really enabled in the main thread, so, schedule # it to run in the main thread. self.exec_queue.put(do_change_variable) def connectToDebugger(self, debuggerPort, debugger_options=None): - ''' + """ Used to show console with variables connection. Mainly, monkey-patches things in the debugger structure so that the debugger protocol works. - ''' + """ if debugger_options is None: debugger_options = {} env_key = "PYDEVD_EXTRA_ENVS" if env_key in debugger_options: - for (env_name, value) in debugger_options[env_key].items(): + for env_name, value in debugger_options[env_key].items(): existing_value = os.environ.get(env_name, None) if existing_value: os.environ[env_name] = "%s%c%s" % (existing_value, os.path.pathsep, value) @@ -549,10 +547,11 @@ def do_connect_to_debugger(): except: # This happens on Jython embedded in host eclipse traceback.print_exc() - sys.stderr.write('pydevd is not available, cannot connect\n') + sys.stderr.write("pydevd is not available, cannot connect\n") from _pydevd_bundle.pydevd_constants import set_thread_id from _pydev_bundle import pydev_localhost + set_thread_id(threading.current_thread(), "console_main") VIRTUAL_FRAME_ID = "1" # matches PyStackFrameConsole.java @@ -571,22 +570,23 @@ def do_connect_to_debugger(): self.debugger.disable_tracing() except: traceback.print_exc() - sys.stderr.write('Failed to connect to target debugger.\n') + sys.stderr.write("Failed to connect to target debugger.\n") # Register to process commands when idle self.debugrunning = False try: import pydevconsole + pydevconsole.set_debug_hook(self.debugger.process_internal_commands) except: traceback.print_exc() - sys.stderr.write('Version of Python does not support debuggable Interactive Console.\n') + sys.stderr.write("Version of Python does not support debuggable Interactive Console.\n") # Important: it has to be really enabled in the main thread, so, schedule # it to run in the main thread. self.exec_queue.put(do_connect_to_debugger) - return ('connect complete',) + return ("connect complete",) def handshake(self): if self.connect_status_queue is not None: @@ -601,21 +601,23 @@ def hello(self, input_str): return ("Hello eclipse",) def enableGui(self, guiname): - ''' Enable the GUI specified in guiname (see inputhook for list). - As with IPython, enabling multiple GUIs isn't an error, but - only the last one's main loop runs and it may not work - ''' + """Enable the GUI specified in guiname (see inputhook for list). + As with IPython, enabling multiple GUIs isn't an error, but + only the last one's main loop runs and it may not work + """ def do_enable_gui(): from _pydev_bundle.pydev_versioncheck import versionok_for_gui + if versionok_for_gui(): try: from pydev_ipython.inputhook import enable_gui + enable_gui(guiname) except: sys.stderr.write("Failed to enable GUI event loop integration for '%s'\n" % guiname) traceback.print_exc() - elif guiname not in ['none', '', None]: + elif guiname not in ["none", "", None]: # Only print a warning if the guiname was going to do something sys.stderr.write("PyDev console: Python version does not support GUI event loop integration for '%s'\n" % guiname) # Return value does not matter, so return back what was sent @@ -633,7 +635,7 @@ def get_ipython_hidden_vars_dict(self): # FakeFrame # ======================================================================================================================= class FakeFrame: - ''' + """ Used to show console with variables connection. A class to be used as a mock of a frame. - ''' + """ diff --git a/_pydev_bundle/pydev_import_hook.py b/_pydev_bundle/pydev_import_hook.py index 519d8d762..4dd91368c 100644 --- a/_pydev_bundle/pydev_import_hook.py +++ b/_pydev_bundle/pydev_import_hook.py @@ -1,4 +1,3 @@ - import sys import traceback from types import ModuleType @@ -8,7 +7,6 @@ class ImportHookManager(ModuleType): - def __init__(self, name, system_import): ModuleType.__init__(self, name) self._system_import = system_import @@ -35,6 +33,6 @@ def do_import(self, name, *args, **kwargs): return module -import_hook_manager = ImportHookManager(__name__ + '.import_hook', builtins.__import__) +import_hook_manager = ImportHookManager(__name__ + ".import_hook", builtins.__import__) builtins.__import__ = import_hook_manager.do_import sys.modules[import_hook_manager.__name__] = import_hook_manager diff --git a/_pydev_bundle/pydev_imports.py b/_pydev_bundle/pydev_imports.py index edc242908..4ee2868c4 100644 --- a/_pydev_bundle/pydev_imports.py +++ b/_pydev_bundle/pydev_imports.py @@ -10,4 +10,3 @@ from _pydevd_bundle.pydevd_exec2 import Exec from urllib.parse import quote, quote_plus, unquote_plus # @UnresolvedImport - diff --git a/_pydev_bundle/pydev_ipython_console.py b/_pydev_bundle/pydev_ipython_console.py index a1221f972..72b16791c 100644 --- a/_pydev_bundle/pydev_ipython_console.py +++ b/_pydev_bundle/pydev_ipython_console.py @@ -9,13 +9,13 @@ from _pydev_bundle.pydev_ipython_console_011 import get_pydev_frontend -#======================================================================================================================= +# ======================================================================================================================= # InterpreterInterface -#======================================================================================================================= +# ======================================================================================================================= class InterpreterInterface(BaseInterpreterInterface): - ''' - The methods in this class should be registered in the xml-rpc server. - ''' + """ + The methods in this class should be registered in the xml-rpc server. + """ def __init__(self, host, client_port, main_thread, show_banner=True, connect_status_queue=None): BaseInterpreterInterface.__init__(self, main_thread, connect_status_queue) @@ -37,13 +37,13 @@ def get_greeting_msg(self): def do_add_exec(self, code_fragment): self.notify_about_magic() - if code_fragment.text.rstrip().endswith('??'): - print('IPython-->') + if code_fragment.text.rstrip().endswith("??"): + print("IPython-->") try: res = bool(self.interpreter.add_exec(code_fragment.text)) finally: - if code_fragment.text.rstrip().endswith('??'): - print('<--IPython') + if code_fragment.text.rstrip().endswith("??"): + print("<--IPython") return res @@ -75,23 +75,21 @@ def notify_about_magic(self): def get_ipython_hidden_vars_dict(self): try: - if hasattr(self.interpreter, 'ipython') and hasattr(self.interpreter.ipython, 'user_ns_hidden'): + if hasattr(self.interpreter, "ipython") and hasattr(self.interpreter.ipython, "user_ns_hidden"): user_ns_hidden = self.interpreter.ipython.user_ns_hidden if isinstance(user_ns_hidden, dict): # Since IPython 2 dict `user_ns_hidden` contains hidden variables and values user_hidden_dict = user_ns_hidden.copy() else: # In IPython 1.x `user_ns_hidden` used to be a set with names of hidden variables - user_hidden_dict = dict([(key, val) for key, val in self.interpreter.ipython.user_ns.items() - if key in user_ns_hidden]) + user_hidden_dict = dict([(key, val) for key, val in self.interpreter.ipython.user_ns.items() if key in user_ns_hidden]) # while `_`, `__` and `___` were not initialized, they are not presented in `user_ns_hidden` - user_hidden_dict.setdefault('_', '') - user_hidden_dict.setdefault('__', '') - user_hidden_dict.setdefault('___', '') + user_hidden_dict.setdefault("_", "") + user_hidden_dict.setdefault("__", "") + user_hidden_dict.setdefault("___", "") return user_hidden_dict except: # Getting IPython variables shouldn't break loading frame variables traceback.print_exc() - diff --git a/_pydev_bundle/pydev_ipython_console_011.py b/_pydev_bundle/pydev_ipython_console_011.py index eaf4738ba..dabf1f380 100644 --- a/_pydev_bundle/pydev_ipython_console_011.py +++ b/_pydev_bundle/pydev_ipython_console_011.py @@ -27,6 +27,7 @@ from IPython.utils.strdispatch import StrDispatch import IPython.core.release as IPythonRelease from IPython.terminal.interactiveshell import TerminalInteractiveShell + try: from traitlets import CBool, Unicode except ImportError: @@ -37,24 +38,23 @@ default_pydev_banner_parts = default_banner_parts -default_pydev_banner = ''.join(default_pydev_banner_parts) +default_pydev_banner = "".join(default_pydev_banner_parts) def show_in_pager(self, strng, *args, **kwargs): - """ Run a string through pager """ + """Run a string through pager""" # On PyDev we just output the string, there are scroll bars in the console # to handle "paging". This is the same behaviour as when TERM==dump (see # page.py) # for compatibility with mime-bundle form: if isinstance(strng, dict): - strng = strng.get('text/plain', strng) + strng = strng.get("text/plain", strng) print(strng) def create_editor_hook(pydev_host, pydev_client_port): - def call_editor(filename, line=0, wait=True): - """ Open an editor in PyDev """ + """Open an editor in PyDev""" if line is None: line = 0 @@ -66,7 +66,7 @@ def call_editor(filename, line=0, wait=True): # sys.__stderr__.write('Calling editor at: %s:%s\n' % (pydev_host, pydev_client_port)) # Tell PyDev to open the editor - server = xmlrpclib.Server('http://%s:%s' % (pydev_host, pydev_client_port)) + server = xmlrpclib.Server("http://%s:%s" % (pydev_host, pydev_client_port)) server.IPythonEditor(filename, str(line)) if wait: @@ -76,10 +76,9 @@ def call_editor(filename, line=0, wait=True): class PyDevIPCompleter(IPCompleter): - def __init__(self, *args, **kwargs): - """ Create a Completer that reuses the advanced completion support of PyDev - in addition to the completion support provided by IPython """ + """Create a Completer that reuses the advanced completion support of PyDev + in addition to the completion support provided by IPython""" IPCompleter.__init__(self, *args, **kwargs) # Use PyDev for python matches, see getCompletions below if self.python_matches in self.matchers: @@ -88,10 +87,9 @@ def __init__(self, *args, **kwargs): class PyDevIPCompleter6(IPCompleter): - def __init__(self, *args, **kwargs): - """ Create a Completer that reuses the advanced completion support of PyDev - in addition to the completion support provided by IPython """ + """Create a Completer that reuses the advanced completion support of PyDev + in addition to the completion support provided by IPython""" IPCompleter.__init__(self, *args, **kwargs) @property @@ -112,9 +110,7 @@ def matchers(self, value): class PyDevTerminalInteractiveShell(TerminalInteractiveShell): - banner1 = Unicode(default_pydev_banner, config=True, - help="""The part of the banner to be printed before the profile""" - ) + banner1 = Unicode(default_pydev_banner, config=True, help="""The part of the banner to be printed before the profile""") # TODO term_title: (can PyDev's title be changed???, see terminal.py for where to inject code, in particular set_term_title as used by %cd) # for now, just disable term_title @@ -145,18 +141,18 @@ class PyDevTerminalInteractiveShell(TerminalInteractiveShell): # In the PyDev Console, GUI control is done via hookable XML-RPC server @staticmethod def enable_gui(gui=None, app=None): - """Switch amongst GUI input hooks by name. - """ + """Switch amongst GUI input hooks by name.""" # Deferred import from pydev_ipython.inputhook import enable_gui as real_enable_gui + try: return real_enable_gui(gui, app) except ValueError as e: raise UsageError("%s" % e) - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Things related to hooks - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def init_history(self): # Disable history so that we don't have an additional thread for that @@ -166,11 +162,11 @@ def init_history(self): def init_hooks(self): super(PyDevTerminalInteractiveShell, self).init_hooks() - self.set_hook('show_in_pager', show_in_pager) + self.set_hook("show_in_pager", show_in_pager) - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Things related to exceptions - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def showtraceback(self, exc_tuple=None, *args, **kwargs): # IPython does a lot of clever stuff with Exceptions. However mostly @@ -190,53 +186,50 @@ def showtraceback(self, exc_tuple=None, *args, **kwargs): if tb is not None: traceback.print_exception(etype, value, tb) - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Things related to text completion - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # The way to construct an IPCompleter changed in most versions, # so we have a custom, per version implementation of the construction def _new_completer_100(self): - completer = PyDevIPCompleter(shell=self, - namespace=self.user_ns, - global_namespace=self.user_global_ns, - alias_table=self.alias_manager.alias_table, - use_readline=self.has_readline, - parent=self, - ) + completer = PyDevIPCompleter( + shell=self, + namespace=self.user_ns, + global_namespace=self.user_global_ns, + alias_table=self.alias_manager.alias_table, + use_readline=self.has_readline, + parent=self, + ) return completer def _new_completer_234(self): # correct for IPython versions 2.x, 3.x, 4.x - completer = PyDevIPCompleter(shell=self, - namespace=self.user_ns, - global_namespace=self.user_global_ns, - use_readline=self.has_readline, - parent=self, - ) + completer = PyDevIPCompleter( + shell=self, + namespace=self.user_ns, + global_namespace=self.user_global_ns, + use_readline=self.has_readline, + parent=self, + ) return completer def _new_completer_500(self): - completer = PyDevIPCompleter(shell=self, - namespace=self.user_ns, - global_namespace=self.user_global_ns, - use_readline=False, - parent=self - ) + completer = PyDevIPCompleter( + shell=self, namespace=self.user_ns, global_namespace=self.user_global_ns, use_readline=False, parent=self + ) return completer def _new_completer_600(self): - completer = PyDevIPCompleter6(shell=self, - namespace=self.user_ns, - global_namespace=self.user_global_ns, - use_readline=False, - parent=self - ) + completer = PyDevIPCompleter6( + shell=self, namespace=self.user_ns, global_namespace=self.user_global_ns, use_readline=False, parent=self + ) return completer def add_completer_hooks(self): from IPython.core.completerlib import module_completer, magic_run_completer, cd_completer + try: from IPython.core.completerlib import reset_completer except ImportError: @@ -245,16 +238,16 @@ def add_completer_hooks(self): self.configurables.append(self.Completer) # Add custom completers to the basic ones built into IPCompleter - sdisp = self.strdispatchers.get('complete_command', StrDispatch()) - self.strdispatchers['complete_command'] = sdisp + sdisp = self.strdispatchers.get("complete_command", StrDispatch()) + self.strdispatchers["complete_command"] = sdisp self.Completer.custom_completers = sdisp - self.set_hook('complete_command', module_completer, str_key='import') - self.set_hook('complete_command', module_completer, str_key='from') - self.set_hook('complete_command', magic_run_completer, str_key='%run') - self.set_hook('complete_command', cd_completer, str_key='%cd') + self.set_hook("complete_command", module_completer, str_key="import") + self.set_hook("complete_command", module_completer, str_key="from") + self.set_hook("complete_command", magic_run_completer, str_key="%run") + self.set_hook("complete_command", cd_completer, str_key="%cd") if reset_completer: - self.set_hook('complete_command', reset_completer, str_key='%reset') + self.set_hook("complete_command", reset_completer, str_key="%reset") def init_completer(self): """Initialize the completion machinery. @@ -277,7 +270,7 @@ def init_completer(self): elif IPythonRelease._version_major >= 1: self.Completer = self._new_completer_100() - if hasattr(self.Completer, 'use_jedi'): + if hasattr(self.Completer, "use_jedi"): self.Completer.use_jedi = False self.add_completer_hooks() @@ -289,20 +282,20 @@ def init_completer(self): if self.has_readline: self.set_readline_completer() - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Things related to aliases - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def init_alias(self): # InteractiveShell defines alias's we want, but TerminalInteractiveShell defines # ones we don't. So don't use super and instead go right to InteractiveShell InteractiveShell.init_alias(self) - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Things related to exiting - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def ask_exit(self): - """ Ask the shell to exit. Can be overiden and used as a callback. """ + """Ask the shell to exit. Can be overiden and used as a callback.""" # TODO PyDev's console does not have support from the Python side to exit # the console. If user forces the exit (with sys.exit()) then the console # simply reports errors. e.g.: @@ -323,11 +316,11 @@ def ask_exit(self): # >>> # super(PyDevTerminalInteractiveShell, self).ask_exit() - print('To exit the PyDev Console, terminate the console within IDE.') + print("To exit the PyDev Console, terminate the console within IDE.") - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- # Things related to magics - #------------------------------------------------------------------------- + # ------------------------------------------------------------------------- def init_magics(self): super(PyDevTerminalInteractiveShell, self).init_magics() @@ -337,16 +330,15 @@ def init_magics(self): InteractiveShellABC.register(PyDevTerminalInteractiveShell) # @UndefinedVariable -#======================================================================================================================= +# ======================================================================================================================= # _PyDevFrontEnd -#======================================================================================================================= +# ======================================================================================================================= class _PyDevFrontEnd: - version = release.__version__ def __init__(self): # Create and initialize our IPython instance. - if hasattr(PyDevTerminalInteractiveShell, '_instance') and PyDevTerminalInteractiveShell._instance is not None: + if hasattr(PyDevTerminalInteractiveShell, "_instance") and PyDevTerminalInteractiveShell._instance is not None: self.ipython = PyDevTerminalInteractiveShell._instance else: self.ipython = PyDevTerminalInteractiveShell.instance() @@ -368,7 +360,7 @@ def update(self, globals, locals): self.ipython.user_global_ns.update(globals) self.ipython.user_ns = locals - if hasattr(self.ipython, 'history_manager') and hasattr(self.ipython.history_manager, 'save_thread'): + if hasattr(self.ipython, "history_manager") and hasattr(self.ipython.history_manager, "save_thread"): self.ipython.history_manager.save_thread.pydev_do_not_trace = True # don't trace ipython history saving thread def complete(self, string): @@ -384,7 +376,7 @@ def complete(self, string): def is_complete(self, string): # Based on IPython 0.10.1 - if string in ('', '\n'): + if string in ("", "\n"): # Prefiltering, eg through ipython0, may return an empty # string although some operations have been accomplished. We # thus want to consider an empty string as a complete @@ -396,15 +388,11 @@ def is_complete(self, string): # complete (except if '\' was used). # This should probably be done in a different place (like # maybe 'prefilter_input' method? For now, this works. - clean_string = string.rstrip('\n') - if not clean_string.endswith('\\'): - clean_string += '\n\n' - - is_complete = codeop.compile_command( - clean_string, - "", - "exec" - ) + clean_string = string.rstrip("\n") + if not clean_string.endswith("\\"): + clean_string += "\n\n" + + is_complete = codeop.compile_command(clean_string, "", "exec") except Exception: # XXX: Hack: return True so that the # code gets executed and the error captured. @@ -416,18 +404,18 @@ def getCompletions(self, text, act_tok): # IPython only gives context free list of completions, while PyDev # gives detailed information about completions. try: - TYPE_IPYTHON = '11' - TYPE_IPYTHON_MAGIC = '12' + TYPE_IPYTHON = "11" + TYPE_IPYTHON_MAGIC = "12" _line, ipython_completions = self.complete(text) from _pydev_bundle._pydev_completer import Completer + completer = Completer(self.get_namespace(), None) ret = completer.complete(act_tok) append = ret.append ip = self.ipython pydev_completions = set([f[0] for f in ret]) for ipython_completion in ipython_completions: - # PyCharm was not expecting completions with '%'... # Could be fixed in the backend, but it's probably better # fixing it at PyCharm. @@ -437,17 +425,19 @@ def getCompletions(self, text, act_tok): if ipython_completion not in pydev_completions: pydev_completions.add(ipython_completion) inf = ip.object_inspect(ipython_completion) - if inf['type_name'] == 'Magic function': + if inf["type_name"] == "Magic function": pydev_type = TYPE_IPYTHON_MAGIC else: pydev_type = TYPE_IPYTHON - pydev_doc = inf['docstring'] + pydev_doc = inf["docstring"] if pydev_doc is None: - pydev_doc = '' - append((ipython_completion, pydev_doc, '', pydev_type)) + pydev_doc = "" + append((ipython_completion, pydev_doc, "", pydev_type)) return ret except: - import traceback;traceback.print_exc() + import traceback + + traceback.print_exc() return [] def get_namespace(self): @@ -460,7 +450,7 @@ def add_exec(self, line): if self._curr_exec_lines: self._curr_exec_lines.append(line) - buf = '\n'.join(self._curr_exec_lines) + buf = "\n".join(self._curr_exec_lines) if self.is_complete(buf): self._curr_exec_line += 1 @@ -470,7 +460,6 @@ def add_exec(self, line): return True # needs more else: - if not self.is_complete(line): # Did not execute self._curr_exec_lines.append(line) @@ -488,7 +477,7 @@ def is_automagic(self): return self.ipython.automagic def get_greeting_msg(self): - return 'PyDev console: using IPython %s\n' % self.version + return "PyDev console: using IPython %s\n" % self.version class _PyDevFrontEndContainer: @@ -506,11 +495,10 @@ def get_pydev_frontend(pydev_host, pydev_client_port): # Back channel to PyDev to open editors (in the future other # info may go back this way. This is the same channel that is # used to get stdin, see StdIn in pydev_console_utils) - _PyDevFrontEndContainer._instance.ipython.hooks['editor'] = create_editor_hook(pydev_host, pydev_client_port) + _PyDevFrontEndContainer._instance.ipython.hooks["editor"] = create_editor_hook(pydev_host, pydev_client_port) # Note: setting the callback directly because setting it with set_hook would actually create a chain instead # of ovewriting at each new call). # _PyDevFrontEndContainer._instance.ipython.set_hook('editor', create_editor_hook(pydev_host, pydev_client_port)) return _PyDevFrontEndContainer._instance - diff --git a/_pydev_bundle/pydev_is_thread_alive.py b/_pydev_bundle/pydev_is_thread_alive.py index d949ba256..c1902014e 100644 --- a/_pydev_bundle/pydev_is_thread_alive.py +++ b/_pydev_bundle/pydev_is_thread_alive.py @@ -4,20 +4,20 @@ # circumstances). # It is required to debug threads started by start_new_thread in Python 3.4 _temp = threading.Thread() -if hasattr(_temp, '_is_stopped'): # Python 3.x has this +if hasattr(_temp, "_is_stopped"): # Python 3.x has this def is_thread_alive(t): return not t._is_stopped -elif hasattr(_temp, '_Thread__stopped'): # Python 2.x has this +elif hasattr(_temp, "_Thread__stopped"): # Python 2.x has this def is_thread_alive(t): return not t._Thread__stopped else: - # Jython wraps a native java thread and thus only obeys the public API. def is_thread_alive(t): return t.is_alive() + del _temp diff --git a/_pydev_bundle/pydev_localhost.py b/_pydev_bundle/pydev_localhost.py index 0d2838de5..d25809236 100644 --- a/_pydev_bundle/pydev_localhost.py +++ b/_pydev_bundle/pydev_localhost.py @@ -1,20 +1,20 @@ from _pydev_bundle._pydev_saved_modules import socket import sys -IS_JYTHON = sys.platform.find('java') != -1 +IS_JYTHON = sys.platform.find("java") != -1 _cache = None def get_localhost(): - ''' + """ Should return 127.0.0.1 in ipv4 and ::1 in ipv6 localhost is not used because on windows vista/windows 7, there can be issues where the resolving doesn't work properly and takes a lot of time (had this issue on the pyunit server). Using the IP directly solves the problem. - ''' + """ # TODO: Needs better investigation! global _cache @@ -22,14 +22,14 @@ def get_localhost(): try: for addr_info in socket.getaddrinfo("localhost", 80, 0, 0, socket.SOL_TCP): config = addr_info[4] - if config[0] == '127.0.0.1': - _cache = '127.0.0.1' + if config[0] == "127.0.0.1": + _cache = "127.0.0.1" return _cache except: # Ok, some versions of Python don't have getaddrinfo or SOL_TCP... Just consider it 127.0.0.1 in this case. - _cache = '127.0.0.1' + _cache = "127.0.0.1" else: - _cache = 'localhost' + _cache = "localhost" return _cache @@ -42,6 +42,7 @@ def get_socket_names(n_sockets, close=False): # Although the option which would be pure java *should* work for Jython, the socket being returned is still 0 # (i.e.: it doesn't give the local port bound, only the original port, which was 0). from java.net import ServerSocket + sock = ServerSocket(0) socket_name = get_localhost(), sock.getLocalPort() else: @@ -63,5 +64,5 @@ def get_socket_name(close=False): return get_socket_names(1, close)[0] -if __name__ == '__main__': +if __name__ == "__main__": print(get_socket_name()) diff --git a/_pydev_bundle/pydev_log.py b/_pydev_bundle/pydev_log.py index 715519569..2fb0fc267 100644 --- a/_pydev_bundle/pydev_log.py +++ b/_pydev_bundle/pydev_log.py @@ -1,5 +1,4 @@ -from _pydevd_bundle.pydevd_constants import DebugInfoHolder, SHOW_COMPILE_CYTHON_COMMAND_LINE, NULL, LOG_TIME, \ - ForkSafeLock +from _pydevd_bundle.pydevd_constants import DebugInfoHolder, SHOW_COMPILE_CYTHON_COMMAND_LINE, NULL, LOG_TIME, ForkSafeLock from contextlib import contextmanager import traceback import os @@ -15,12 +14,12 @@ class _LoggingGlobals(object): def initialize_debug_stream(reinitialize=False): - ''' + """ :param bool reinitialize: Reinitialize is used to update the debug stream after a fork (thus, if it wasn't initialized, we don't need to do anything, just wait for the first regular log call to initialize). - ''' + """ if reinitialize: if not _LoggingGlobals._debug_stream_initialized: return @@ -53,7 +52,7 @@ def initialize_debug_stream(reinitialize=False): try: target_file = DebugInfoHolder.PYDEVD_DEBUG_FILE debug_file = _compute_filename_with_pid(target_file) - _LoggingGlobals._debug_stream = open(debug_file, 'w') + _LoggingGlobals._debug_stream = open(debug_file, "w") _LoggingGlobals._debug_stream_filename = debug_file except Exception: _LoggingGlobals._debug_stream = sys.stderr @@ -73,10 +72,10 @@ def _compute_filename_with_pid(target_file, pid=None): name, ext = os.path.splitext(basename) if pid is None: pid = os.getpid() - return os.path.join(dirname, '%s.%s%s' % (name, pid, ext)) + return os.path.join(dirname, "%s.%s%s" % (name, pid, ext)) -def log_to(log_file:str, log_level:int=3) -> None: +def log_to(log_file: str, log_level: int = 3) -> None: with _LoggingGlobals._initialize_lock: # Can be set directly. DebugInfoHolder.DEBUG_TRACE_LEVEL = log_level @@ -107,9 +106,9 @@ def list_log_files(pydevd_debug_file): @contextmanager def log_context(trace_level, stream): - ''' + """ To be used to temporarily change the logging settings. - ''' + """ with _LoggingGlobals._initialize_lock: original_trace_level = DebugInfoHolder.DEBUG_TRACE_LEVEL original_debug_stream = _LoggingGlobals._debug_stream @@ -132,6 +131,7 @@ def log_context(trace_level, stream): import time + _last_log_time = time.time() # Set to True to show pid in each logged message (usually the file has it, but sometimes it's handy). @@ -139,14 +139,14 @@ def log_context(trace_level, stream): def _pydevd_log(level, msg, *args): - ''' + """ Levels are: 0 most serious warnings/errors (always printed) 1 warnings/significant events 2 informational trace 3 verbose mode - ''' + """ if level <= DebugInfoHolder.DEBUG_TRACE_LEVEL: # yes, we can have errors printing if the console of the program has been finished (and we're still trying to print something) try: @@ -154,19 +154,25 @@ def _pydevd_log(level, msg, *args): if args: msg = msg % args except: - msg = '%s - %s' % (msg, args) + msg = "%s - %s" % (msg, args) if LOG_TIME: global _last_log_time new_log_time = time.time() time_diff = new_log_time - _last_log_time _last_log_time = new_log_time - msg = '%.2fs - %s\n' % (time_diff, msg,) + msg = "%.2fs - %s\n" % ( + time_diff, + msg, + ) else: - msg = '%s\n' % (msg,) + msg = "%s\n" % (msg,) if _LOG_PID: - msg = '<%s> - %s\n' % (os.getpid(), msg,) + msg = "<%s> - %s\n" % ( + os.getpid(), + msg, + ) try: try: @@ -175,14 +181,14 @@ def _pydevd_log(level, msg, *args): except TypeError: if isinstance(msg, bytes): # Depending on the StringIO flavor, it may only accept unicode. - msg = msg.decode('utf-8', 'replace') + msg = msg.decode("utf-8", "replace") _LoggingGlobals._debug_stream.write(msg) except UnicodeEncodeError: # When writing to the stream it's possible that the string can't be represented # in the encoding expected (in this case, convert it to the stream encoding # or ascii if we can't find one suitable using a suitable replace). - encoding = getattr(_LoggingGlobals._debug_stream, 'encoding', 'ascii') - msg = msg.encode(encoding, 'backslashreplace') + encoding = getattr(_LoggingGlobals._debug_stream, "encoding", "ascii") + msg = msg.encode(encoding, "backslashreplace") msg = msg.decode(encoding) _LoggingGlobals._debug_stream.write(msg) @@ -192,7 +198,7 @@ def _pydevd_log(level, msg, *args): return True -def _pydevd_log_exception(msg='', *args): +def _pydevd_log_exception(msg="", *args): if msg or args: _pydevd_log(0, msg, *args) try: @@ -225,7 +231,7 @@ def critical(msg, *args): _pydevd_log(0, msg, *args) -def exception(msg='', *args): +def exception(msg="", *args): try: _pydevd_log_exception(msg, *args) except: @@ -242,7 +248,7 @@ def error_once(msg, *args): else: message = str(msg) except: - message = '%s - %s' % (msg, args) + message = "%s - %s" % (msg, args) if message not in _LoggingGlobals._warn_once_map: _LoggingGlobals._warn_once_map[message] = True @@ -256,7 +262,7 @@ def exception_once(msg, *args): else: message = str(msg) except: - message = '%s - %s' % (msg, args) + message = "%s - %s" % (msg, args) if message not in _LoggingGlobals._warn_once_map: _LoggingGlobals._warn_once_map[message] = True @@ -271,6 +277,8 @@ def debug_once(msg, *args): def show_compile_cython_command_line(): if SHOW_COMPILE_CYTHON_COMMAND_LINE: dirname = os.path.dirname(os.path.dirname(__file__)) - error_once("warning: Debugger speedups using cython not found. Run '\"%s\" \"%s\" build_ext --inplace' to build.", - sys.executable, os.path.join(dirname, 'setup_pydevd_cython.py')) - + error_once( + 'warning: Debugger speedups using cython not found. Run \'"%s" "%s" build_ext --inplace\' to build.', + sys.executable, + os.path.join(dirname, "setup_pydevd_cython.py"), + ) diff --git a/_pydev_bundle/pydev_monkey.py b/_pydev_bundle/pydev_monkey.py index 4afbccf67..915891f41 100644 --- a/_pydev_bundle/pydev_monkey.py +++ b/_pydev_bundle/pydev_monkey.py @@ -3,8 +3,16 @@ import re import sys from _pydev_bundle._pydev_saved_modules import threading -from _pydevd_bundle.pydevd_constants import get_global_debugger, IS_WINDOWS, IS_JYTHON, get_current_thread_id, \ - sorted_dict_repr, set_global_debugger, DebugInfoHolder, PYDEVD_USE_SYS_MONITORING +from _pydevd_bundle.pydevd_constants import ( + get_global_debugger, + IS_WINDOWS, + IS_JYTHON, + get_current_thread_id, + sorted_dict_repr, + set_global_debugger, + DebugInfoHolder, + PYDEVD_USE_SYS_MONITORING, +) from _pydev_bundle import pydev_log from contextlib import contextmanager from _pydevd_bundle import pydevd_constants, pydevd_defaults @@ -16,9 +24,9 @@ except ImportError: Path = None -#=============================================================================== +# =============================================================================== # Things that are dependent on having the pydevd debugger -#=============================================================================== +# =============================================================================== pydev_src_dir = os.path.dirname(os.path.dirname(__file__)) @@ -35,7 +43,7 @@ def skip_subprocess_arg_patch(): def _get_apply_arg_patching(): - return getattr(_arg_patch, 'apply_arg_patching', True) + return getattr(_arg_patch, "apply_arg_patching", True) def _get_setup_updated_with_protocol_and_ppid(setup, is_exec=False): @@ -67,32 +75,31 @@ def _get_setup_updated_with_protocol_and_ppid(setup, is_exec=False): setup[pydevd_constants.ARGUMENT_HTTP_PROTOCOL] = True else: - pydev_log.debug('Unexpected protocol: %s', protocol) + pydev_log.debug("Unexpected protocol: %s", protocol) mode = pydevd_defaults.PydevdCustomization.DEBUG_MODE if mode: - setup['debug-mode'] = mode + setup["debug-mode"] = mode preimport = pydevd_defaults.PydevdCustomization.PREIMPORT if preimport: - setup['preimport'] = preimport + setup["preimport"] = preimport if DebugInfoHolder.PYDEVD_DEBUG_FILE: - setup['log-file'] = DebugInfoHolder.PYDEVD_DEBUG_FILE + setup["log-file"] = DebugInfoHolder.PYDEVD_DEBUG_FILE if DebugInfoHolder.DEBUG_TRACE_LEVEL: - setup['log-level'] = DebugInfoHolder.DEBUG_TRACE_LEVEL + setup["log-level"] = DebugInfoHolder.DEBUG_TRACE_LEVEL return setup class _LastFutureImportFinder(ast.NodeVisitor): - def __init__(self): self.last_future_import_found = None def visit_ImportFrom(self, node): - if node.module == '__future__': + if node.module == "__future__": self.last_future_import_found = node @@ -109,7 +116,7 @@ def _get_offset_from_line_col(code, line, col): def _separate_future_imports(code): - ''' + """ :param code: The code from where we want to get the __future__ imports (note that it's possible that there's no such entry). @@ -120,18 +127,18 @@ def _separate_future_imports(code): If the future import is not available a return such as ('', code) is given, otherwise, the future import will end with a ';' (so that it can be put right before the pydevd attach code). - ''' + """ try: - node = ast.parse(code, '', 'exec') + node = ast.parse(code, "", "exec") visitor = _LastFutureImportFinder() visitor.visit(node) if visitor.last_future_import_found is None: - return '', code + return "", code node = visitor.last_future_import_found offset = -1 - if hasattr(node, 'end_lineno') and hasattr(node, 'end_col_offset'): + if hasattr(node, "end_lineno") and hasattr(node, "end_col_offset"): # Python 3.8 onwards has these (so, use when possible). line, col = node.end_lineno, node.end_col_offset offset = _get_offset_from_line_col(code, line - 1, col) # ast lines are 1-based, make it 0-based. @@ -151,7 +158,7 @@ def _separate_future_imports(code): if offset >= 0: for i in range(offset, len(code)): - if code[i] in (' ', '\t', ';', ')', '\n'): + if code[i] in (" ", "\t", ";", ")", "\n"): offset += 1 else: break @@ -162,21 +169,21 @@ def _separate_future_imports(code): # Now, put '\n' lines back into the code remainder (we had to search for # `\n)`, but in case we just got the `\n`, it should be at the remainder, # not at the future import. - while future_import.endswith('\n'): + while future_import.endswith("\n"): future_import = future_import[:-1] - code_remainder = '\n' + code_remainder + code_remainder = "\n" + code_remainder - if not future_import.endswith(';'): - future_import += ';' + if not future_import.endswith(";"): + future_import += ";" return future_import, code_remainder # This shouldn't happen... - pydev_log.info('Unable to find line %s in code:\n%r', line, code) - return '', code + pydev_log.info("Unable to find line %s in code:\n%r", line, code) + return "", code except: - pydev_log.exception('Error getting from __future__ imports from: %r', code) - return '', code + pydev_log.exception("Error getting from __future__ imports from: %r", code) + return "", code def _get_python_c_args(host, port, code, args, setup): @@ -185,36 +192,39 @@ def _get_python_c_args(host, port, code, args, setup): # i.e.: We want to make the repr sorted so that it works in tests. setup_repr = setup if setup is None else (sorted_dict_repr(setup)) - future_imports = '' - if '__future__' in code: + future_imports = "" + if "__future__" in code: # If the code has a __future__ import, we need to be able to strip the __future__ # imports from the code and add them to the start of our code snippet. future_imports, code = _separate_future_imports(code) - return ("%simport sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config(%r, %r); " - "pydevd.settrace(host=%r, port=%s, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=%r, client_access_token=%r, __setup_holder__=%s); " - "%s" - ) % ( - future_imports, - pydev_src_dir, - pydevd_constants.get_protocol(), - PydevdCustomization.DEBUG_MODE, - host, - port, - setup.get('access-token'), - setup.get('client-access-token'), - setup_repr, - code) + return ( + "%simport sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config(%r, %r); " + "pydevd.settrace(host=%r, port=%s, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=%r, client_access_token=%r, __setup_holder__=%s); " + "%s" + ) % ( + future_imports, + pydev_src_dir, + pydevd_constants.get_protocol(), + PydevdCustomization.DEBUG_MODE, + host, + port, + setup.get("access-token"), + setup.get("client-access-token"), + setup_repr, + code, + ) def _get_host_port(): import pydevd + host, port = pydevd.dispatch() return host, port def _is_managed_arg(arg): - pydevd_py = _get_str_type_compatible(arg, 'pydevd.py') + pydevd_py = _get_str_type_compatible(arg, "pydevd.py") if arg.endswith(pydevd_py): return True return False @@ -225,9 +235,10 @@ def _on_forked_process(setup_tracing=True): pydev_log.initialize_debug_stream(reinitialize=True) if setup_tracing: - pydev_log.debug('pydevd on forked process: %s', os.getpid()) + pydev_log.debug("pydevd on forked process: %s", os.getpid()) import pydevd + pydevd.threadingCurrentThread().__pydevd_main_thread = True pydevd.settrace_forked(setup_tracing=setup_tracing) @@ -239,9 +250,9 @@ def _on_set_trace_for_new_thread(global_debugger): def _get_str_type_compatible(s, args): - ''' + """ This method converts `args` to byte/unicode based on the `s' type. - ''' + """ if isinstance(args, (list, tuple)): ret = [] for arg in args: @@ -249,30 +260,30 @@ def _get_str_type_compatible(s, args): ret.append(arg) else: if isinstance(s, bytes): - ret.append(arg.encode('utf-8')) + ret.append(arg.encode("utf-8")) else: - ret.append(arg.decode('utf-8')) + ret.append(arg.decode("utf-8")) return ret else: if type(s) == type(args): return args else: if isinstance(s, bytes): - return args.encode('utf-8') + return args.encode("utf-8") else: - return args.decode('utf-8') + return args.decode("utf-8") -#=============================================================================== +# =============================================================================== # Things related to monkey-patching -#=============================================================================== +# =============================================================================== def is_python(path): single_quote, double_quote = _get_str_type_compatible(path, ["'", '"']) if path.endswith(single_quote) or path.endswith(double_quote): - path = path[1:len(path) - 1] + path = path[1 : len(path) - 1] filename = os.path.basename(path).lower() - for name in _get_str_type_compatible(filename, ['python', 'jython', 'pypy']): + for name in _get_str_type_compatible(filename, ["python", "jython", "pypy"]): if filename.find(name) != -1: return True @@ -343,8 +354,8 @@ def quote_arg_win32(arg): # # N backslashes in any other position remain as is. - arg = re.sub(fix_type(r'(\\*)\"'), fix_type(r'\1\1\\"'), arg) - arg = re.sub(fix_type(r'(\\*)$'), fix_type(r'\1\1'), arg) + arg = re.sub(fix_type(r"(\\*)\""), fix_type(r'\1\1\\"'), arg) + arg = re.sub(fix_type(r"(\\*)$"), fix_type(r"\1\1"), arg) return fix_type('"') + arg + fix_type('"') @@ -356,21 +367,21 @@ def quote_args(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 try: unquoted_args = remove_quotes_from_args(args) except InvalidTypeInArgsException as e: - pydev_log.info('Unable to monkey-patch subprocess arguments because a type found in the args is invalid: %s', e) + pydev_log.info("Unable to monkey-patch subprocess arguments because a type found in the args is invalid: %s", e) return original_args # Internally we should reference original_args (if we want to return them) or unquoted_args @@ -378,6 +389,7 @@ def patch_args(args, is_exec=False): del args from pydevd import SetupHolder + if not unquoted_args: return original_args @@ -387,11 +399,11 @@ def patch_args(args, is_exec=False): # 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) + args_as_str = _get_str_type_compatible("", unquoted_args) params_with_value_in_separate_arg = ( - '--check-hash-based-pycs', - '--jit' # pypy option + "--check-hash-based-pycs", + "--jit", # pypy option ) # All short switches may be combined together. The ones below require a value and the @@ -413,17 +425,17 @@ def patch_args(args, is_exec=False): # # python -O -Q old -v -c "import sys;print(sys)" - params_with_combinable_arg = set(('W', 'X', 'Q', 'c', 'm')) + params_with_combinable_arg = set(("W", "X", "Q", "c", "m")) module_name = None - before_module_flag = '' + before_module_flag = "" module_name_i_start = -1 module_name_i_end = -1 code = None code_i = -1 code_i_end = -1 - code_flag = '' + code_flag = "" filename = None filename_i = -1 @@ -434,8 +446,8 @@ def patch_args(args, is_exec=False): ignore_next = False continue - if arg_as_str.startswith('-'): - if arg_as_str == '-': + 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 @@ -447,40 +459,39 @@ def patch_args(args, is_exec=False): 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:] + remainder = arg_as_str[j + 1 :] if not remainder: ignore_next = True - if c == 'm': + 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 = '' + 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 = unquoted_args[i][j + 1 :] module_name_i_end = module_name_i_start break_out = True break - elif c == 'c': + 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" + 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" @@ -514,13 +525,13 @@ def patch_args(args, is_exec=False): filename_i = i if _is_managed_arg(filename): # no need to add pydevd twice - pydev_log.debug('Skipped monkey-patching as pydevd.py is in args already.') + 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).') + pydev_log.debug("Unable to fix arguments to attach debugger on subprocess (filename not found).") return original_args if code_i != -1: @@ -537,13 +548,14 @@ def patch_args(args, is_exec=False): 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).') + 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: @@ -551,31 +563,32 @@ def patch_args(args, is_exec=False): add_module_at = len(new_args) + 1 - new_args.extend(setup_to_argv( - _get_setup_updated_with_protocol_and_ppid(SetupHolder.setup, is_exec=is_exec), - skip_names=set(('module', 'cmd-line')) - )) - new_args.append('--file') + new_args.extend( + setup_to_argv( + _get_setup_updated_with_protocol_and_ppid(SetupHolder.setup, is_exec=is_exec), skip_names=set(("module", "cmd-line")) + ) + ) + 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(add_module_at, '--module') + new_args.insert(add_module_at, "--module") new_args.append(module_name) - new_args.extend(unquoted_args[module_name_i_end + 1:]) + 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:]) + new_args.extend(unquoted_args[filename_i + 1 :]) else: - raise AssertionError('Internal error (unexpected condition)') + raise AssertionError("Internal error (unexpected condition)") return quote_args(new_args) except: - pydev_log.exception('Error patching args (debugger not attached to subprocess).') + pydev_log.exception("Error patching args (debugger not attached to subprocess).") return original_args @@ -593,21 +606,21 @@ def str_to_args_windows(args): state = DEFAULT backslashes = 0 - buf = '' + buf = "" args_len = len(args) for i in range(args_len): ch = args[i] - if (ch == '\\'): + if ch == "\\": backslashes += 1 continue - elif (backslashes != 0): + elif backslashes != 0: if ch == '"': while backslashes >= 2: backslashes -= 2 - buf += '\\' - if (backslashes == 1): - if (state == DEFAULT): + buf += "\\" + if backslashes == 1: + if state == DEFAULT: state = ARG buf += '"' @@ -616,21 +629,21 @@ def str_to_args_windows(args): # else fall through to switch else: # false alarm, treat passed backslashes literally... - if (state == DEFAULT): + if state == DEFAULT: state = ARG while backslashes > 0: backslashes -= 1 - buf += '\\' + buf += "\\" # fall through to switch - if ch in (' ', '\t'): - if (state == DEFAULT): + if ch in (" ", "\t"): + if state == DEFAULT: # skip continue - elif (state == ARG): + elif state == ARG: state = DEFAULT result.append(buf) - buf = '' + buf = "" continue if state in (DEFAULT, ARG): @@ -642,7 +655,7 @@ def str_to_args_windows(args): elif state == IN_DOUBLE_QUOTE: if ch == '"': - if (i + 1 < args_len and args[i + 1] == '"'): + if i + 1 < args_len and args[i + 1] == '"': # Undocumented feature in Windows: # Two consecutive double quotes inside a double-quoted argument are interpreted as # a single double quote. @@ -654,7 +667,7 @@ def str_to_args_windows(args): buf += ch else: - raise RuntimeError('Illegal condition') + raise RuntimeError("Illegal condition") if len(buf) > 0 or state != DEFAULT: result.append(buf) @@ -667,14 +680,14 @@ def patch_arg_str_win(arg_str): # Fix https://youtrack.jetbrains.com/issue/PY-9767 (args may be empty) if not args or not is_python(args[0]): return arg_str - arg_str = ' '.join(patch_args(args)) + arg_str = " ".join(patch_args(args)) pydev_log.debug("New args: %s", arg_str) return arg_str def monkey_patch_module(module, funcname, create_func): if hasattr(module, funcname): - original_name = 'original_' + funcname + original_name = "original_" + funcname if not hasattr(module, original_name): setattr(module, original_name, getattr(module, funcname)) setattr(module, funcname, create_func(original_name)) @@ -693,7 +706,6 @@ def warn_multiproc(): def create_warn_multiproc(original_name): - def new_warn_multiproc(*args, **kwargs): import os @@ -705,7 +717,6 @@ def new_warn_multiproc(*args, **kwargs): def create_execl(original_name): - def new_execl(path, *args): """ os.execl(path, arg0, arg1, ...) @@ -724,7 +735,6 @@ def new_execl(path, *args): def create_execv(original_name): - def new_execv(path, args): """ os.execv(path, args) @@ -758,7 +768,6 @@ def new_execve(path, args, env): def create_spawnl(original_name): - def new_spawnl(mode, path, *args): """ os.spawnl(mode, path, arg0, arg1, ...) @@ -774,7 +783,6 @@ def new_spawnl(mode, path, *args): def create_spawnv(original_name): - def new_spawnv(mode, path, args): """ os.spawnv(mode, path, args) @@ -827,6 +835,7 @@ def create_fork_exec(original_name): def new_fork_exec(args, *other_args): import _posixsubprocess # @UnresolvedImport + if _get_apply_arg_patching(): args = patch_args(args) send_process_created_message() @@ -844,6 +853,7 @@ def create_warn_fork_exec(original_name): def new_warn_fork_exec(*args): try: import _posixsubprocess + warn_multiproc() return getattr(_posixsubprocess, original_name)(*args) except: @@ -859,6 +869,7 @@ def create_subprocess_fork_exec(original_name): def new_fork_exec(args, *other_args): import subprocess + if _get_apply_arg_patching(): args = patch_args(args) send_process_created_message() @@ -876,6 +887,7 @@ def create_subprocess_warn_fork_exec(original_name): def new_warn_fork_exec(*args): try: import subprocess + warn_multiproc() return getattr(subprocess, original_name)(*args) except: @@ -921,7 +933,6 @@ def new_CreateProcess(*args): def create_fork(original_name): - def new_fork(): # A simple fork will result in a new python process is_new_python_process = True @@ -931,12 +942,12 @@ def new_fork(): is_subprocess_fork = False while frame is not None: - if frame.f_code.co_name == '_execute_child' and 'subprocess' in frame.f_code.co_filename: + if frame.f_code.co_name == "_execute_child" and "subprocess" in frame.f_code.co_filename: is_subprocess_fork = True # If we're actually in subprocess.Popen creating a child, it may # result in something which is not a Python process, (so, we # don't want to connect with it in the forked version). - executable = frame.f_locals.get('executable') + executable = frame.f_locals.get("executable") if executable is not None: is_new_python_process = False if is_python(executable): @@ -986,14 +997,14 @@ def patch_new_process_functions(): # os.execve(path, args, env) # os.execvp(file, args) # os.execvpe(file, args, env) - monkey_patch_os('execl', create_execl) - monkey_patch_os('execle', create_execl) - monkey_patch_os('execlp', create_execl) - monkey_patch_os('execlpe', create_execl) - monkey_patch_os('execv', create_execv) - monkey_patch_os('execve', create_execve) - monkey_patch_os('execvp', create_execv) - monkey_patch_os('execvpe', create_execve) + monkey_patch_os("execl", create_execl) + monkey_patch_os("execle", create_execl) + monkey_patch_os("execlp", create_execl) + monkey_patch_os("execlpe", create_execl) + monkey_patch_os("execv", create_execv) + monkey_patch_os("execve", create_execve) + monkey_patch_os("execvp", create_execv) + monkey_patch_os("execvpe", create_execve) # os.spawnl(mode, path, ...) # os.spawnle(mode, path, ..., env) @@ -1004,28 +1015,30 @@ def patch_new_process_functions(): # os.spawnvp(mode, file, args) # os.spawnvpe(mode, file, args, env) - monkey_patch_os('spawnl', create_spawnl) - monkey_patch_os('spawnle', create_spawnl) - monkey_patch_os('spawnlp', create_spawnl) - monkey_patch_os('spawnlpe', create_spawnl) - monkey_patch_os('spawnv', create_spawnv) - monkey_patch_os('spawnve', create_spawnve) - monkey_patch_os('spawnvp', create_spawnv) - monkey_patch_os('spawnvpe', create_spawnve) - monkey_patch_os('posix_spawn', create_posix_spawn) + monkey_patch_os("spawnl", create_spawnl) + monkey_patch_os("spawnle", create_spawnl) + monkey_patch_os("spawnlp", create_spawnl) + monkey_patch_os("spawnlpe", create_spawnl) + monkey_patch_os("spawnv", create_spawnv) + monkey_patch_os("spawnve", create_spawnve) + monkey_patch_os("spawnvp", create_spawnv) + monkey_patch_os("spawnvpe", create_spawnve) + monkey_patch_os("posix_spawn", create_posix_spawn) if not IS_JYTHON: if not IS_WINDOWS: - monkey_patch_os('fork', create_fork) + monkey_patch_os("fork", create_fork) try: import _posixsubprocess - monkey_patch_module(_posixsubprocess, 'fork_exec', create_fork_exec) + + monkey_patch_module(_posixsubprocess, "fork_exec", create_fork_exec) except ImportError: pass try: import subprocess - monkey_patch_module(subprocess, '_fork_exec', create_subprocess_fork_exec) + + monkey_patch_module(subprocess, "_fork_exec", create_subprocess_fork_exec) except AttributeError: pass else: @@ -1034,40 +1047,42 @@ def patch_new_process_functions(): import _subprocess except ImportError: import _winapi as _subprocess - monkey_patch_module(_subprocess, 'CreateProcess', create_CreateProcess) + monkey_patch_module(_subprocess, "CreateProcess", create_CreateProcess) def patch_new_process_functions_with_warning(): - monkey_patch_os('execl', create_warn_multiproc) - monkey_patch_os('execle', create_warn_multiproc) - monkey_patch_os('execlp', create_warn_multiproc) - monkey_patch_os('execlpe', create_warn_multiproc) - monkey_patch_os('execv', create_warn_multiproc) - monkey_patch_os('execve', create_warn_multiproc) - monkey_patch_os('execvp', create_warn_multiproc) - monkey_patch_os('execvpe', create_warn_multiproc) - monkey_patch_os('spawnl', create_warn_multiproc) - monkey_patch_os('spawnle', create_warn_multiproc) - monkey_patch_os('spawnlp', create_warn_multiproc) - monkey_patch_os('spawnlpe', create_warn_multiproc) - monkey_patch_os('spawnv', create_warn_multiproc) - monkey_patch_os('spawnve', create_warn_multiproc) - monkey_patch_os('spawnvp', create_warn_multiproc) - monkey_patch_os('spawnvpe', create_warn_multiproc) - monkey_patch_os('posix_spawn', create_warn_multiproc) + monkey_patch_os("execl", create_warn_multiproc) + monkey_patch_os("execle", create_warn_multiproc) + monkey_patch_os("execlp", create_warn_multiproc) + monkey_patch_os("execlpe", create_warn_multiproc) + monkey_patch_os("execv", create_warn_multiproc) + monkey_patch_os("execve", create_warn_multiproc) + monkey_patch_os("execvp", create_warn_multiproc) + monkey_patch_os("execvpe", create_warn_multiproc) + monkey_patch_os("spawnl", create_warn_multiproc) + monkey_patch_os("spawnle", create_warn_multiproc) + monkey_patch_os("spawnlp", create_warn_multiproc) + monkey_patch_os("spawnlpe", create_warn_multiproc) + monkey_patch_os("spawnv", create_warn_multiproc) + monkey_patch_os("spawnve", create_warn_multiproc) + monkey_patch_os("spawnvp", create_warn_multiproc) + monkey_patch_os("spawnvpe", create_warn_multiproc) + monkey_patch_os("posix_spawn", create_warn_multiproc) if not IS_JYTHON: if not IS_WINDOWS: - monkey_patch_os('fork', create_warn_multiproc) + monkey_patch_os("fork", create_warn_multiproc) try: import _posixsubprocess - monkey_patch_module(_posixsubprocess, 'fork_exec', create_warn_fork_exec) + + monkey_patch_module(_posixsubprocess, "fork_exec", create_warn_fork_exec) except ImportError: pass try: import subprocess - monkey_patch_module(subprocess, '_fork_exec', create_subprocess_warn_fork_exec) + + monkey_patch_module(subprocess, "_fork_exec", create_subprocess_warn_fork_exec) except AttributeError: pass @@ -1077,11 +1092,10 @@ def patch_new_process_functions_with_warning(): import _subprocess except ImportError: import _winapi as _subprocess - monkey_patch_module(_subprocess, 'CreateProcess', create_CreateProcessWarnMultiproc) + monkey_patch_module(_subprocess, "CreateProcess", create_CreateProcessWarnMultiproc) class _NewThreadStartupWithTrace: - def __init__(self, original_func, args, kwargs): self.original_func = original_func self.args = args @@ -1098,20 +1112,21 @@ def __call__(self): # the start_new_thread internal machinery and thread._bootstrap has not finished), so, the code below needs # to make sure that we use the current thread bound to the original function and not use # threading.current_thread() unless we're sure it's a dummy thread. - t = getattr(self.original_func, '__self__', getattr(self.original_func, 'im_self', None)) + t = getattr(self.original_func, "__self__", getattr(self.original_func, "im_self", None)) if not isinstance(t, threading.Thread): # This is not a threading.Thread but a Dummy thread (so, get it as a dummy thread using # currentThread). t = threading.current_thread() - if not getattr(t, 'is_pydev_daemon_thread', False): + if not getattr(t, "is_pydev_daemon_thread", False): thread_id = get_current_thread_id(t) py_db.notify_thread_created(thread_id, t) _on_set_trace_for_new_thread(py_db) - if getattr(py_db, 'thread_analyser', None) is not None: + if getattr(py_db, "thread_analyser", None) is not None: try: from _pydevd_bundle.pydevd_concurrency_analyser.pydevd_concurrency_logger import log_new_thread + log_new_thread(py_db, t) except: sys.stderr.write("Failed to detect new thread for visualization") @@ -1129,7 +1144,6 @@ def __call__(self): class _NewThreadStartupWithoutTrace: - def __init__(self, original_func, args, kwargs): self.original_func = original_func self.args = args @@ -1159,10 +1173,9 @@ def _get_threading_modules_to_patch(): def patch_thread_module(thread_module): - - if getattr(thread_module, '_original_start_new_thread', None) is None: + if getattr(thread_module, "_original_start_new_thread", None) is None: if thread_module is threading: - if not hasattr(thread_module, '_start_new_thread'): + if not hasattr(thread_module, "_start_new_thread"): return # Jython doesn't have it. _original_start_new_thread = thread_module._original_start_new_thread = thread_module._start_new_thread else: @@ -1171,12 +1184,11 @@ def patch_thread_module(thread_module): _original_start_new_thread = thread_module._original_start_new_thread class ClassWithPydevStartNewThread: - def pydev_start_new_thread(self, function, args=(), kwargs={}): - ''' + """ We need to replace the original thread_module.start_new_thread with this function so that threads started through it and not through the threading module are properly traced. - ''' + """ return _original_start_new_thread(_UseNewThreadStartup(function, args, kwargs), ()) # This is a hack for the situation where the thread_module.start_new_thread is declared inside a class, such as the one below @@ -1225,17 +1237,17 @@ def undo_patch_thread_modules(): def disable_trace_thread_modules(): - ''' + """ Can be used to temporarily stop tracing threads created with thread.start_new_thread. - ''' + """ global _UseNewThreadStartup _UseNewThreadStartup = _NewThreadStartupWithoutTrace def enable_trace_thread_modules(): - ''' + """ Can be used to start tracing threads created with thread.start_new_thread again. - ''' + """ global _UseNewThreadStartup _UseNewThreadStartup = _NewThreadStartupWithTrace diff --git a/_pydev_bundle/pydev_monkey_qt.py b/_pydev_bundle/pydev_monkey_qt.py index e348b842d..5864e3ca8 100644 --- a/_pydev_bundle/pydev_monkey_qt.py +++ b/_pydev_bundle/pydev_monkey_qt.py @@ -7,6 +7,7 @@ def set_trace_in_qt(): from _pydevd_bundle.pydevd_comm import get_global_debugger + py_db = get_global_debugger() if py_db is not None: threading.current_thread() # Create the dummy thread for qt. @@ -17,87 +18,94 @@ def set_trace_in_qt(): def patch_qt(qt_support_mode): - ''' + """ This method patches qt (PySide2, PySide, PyQt4, PyQt5) so that we have hooks to set the tracing for QThread. - ''' + """ if not qt_support_mode: return - if qt_support_mode is True or qt_support_mode == 'True': + if qt_support_mode is True or qt_support_mode == "True": # do not break backward compatibility - qt_support_mode = 'auto' + qt_support_mode = "auto" - if qt_support_mode == 'auto': - qt_support_mode = os.getenv('PYDEVD_PYQT_MODE', 'auto') + if qt_support_mode == "auto": + qt_support_mode = os.getenv("PYDEVD_PYQT_MODE", "auto") # Avoid patching more than once global _patched_qt if _patched_qt: return - pydev_log.debug('Qt support mode: %s', qt_support_mode) + pydev_log.debug("Qt support mode: %s", qt_support_mode) _patched_qt = True - if qt_support_mode == 'auto': - + if qt_support_mode == "auto": patch_qt_on_import = None try: import PySide2 # @UnresolvedImport @UnusedImport - qt_support_mode = 'pyside2' + + qt_support_mode = "pyside2" except: try: import Pyside # @UnresolvedImport @UnusedImport - qt_support_mode = 'pyside' + + qt_support_mode = "pyside" except: try: import PyQt5 # @UnresolvedImport @UnusedImport - qt_support_mode = 'pyqt5' + + qt_support_mode = "pyqt5" except: try: import PyQt4 # @UnresolvedImport @UnusedImport - qt_support_mode = 'pyqt4' + + qt_support_mode = "pyqt4" except: return - if qt_support_mode == 'pyside2': + if qt_support_mode == "pyside2": try: import PySide2.QtCore # @UnresolvedImport + _internal_patch_qt(PySide2.QtCore, qt_support_mode) except: return - elif qt_support_mode == 'pyside': + elif qt_support_mode == "pyside": try: import PySide.QtCore # @UnresolvedImport + _internal_patch_qt(PySide.QtCore, qt_support_mode) except: return - elif qt_support_mode == 'pyqt5': + elif qt_support_mode == "pyqt5": try: import PyQt5.QtCore # @UnresolvedImport + _internal_patch_qt(PyQt5.QtCore) except: return - elif qt_support_mode == 'pyqt4': + elif qt_support_mode == "pyqt4": # Ok, we have an issue here: # PyDev-452: Selecting PyQT API version using sip.setapi fails in debug mode # http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html # Mostly, if the user uses a different API version (i.e.: v2 instead of v1), # that has to be done before importing PyQt4 modules (PySide/PyQt5 don't have this issue # as they only implements v2). - patch_qt_on_import = 'PyQt4' + patch_qt_on_import = "PyQt4" def get_qt_core_module(): import PyQt4.QtCore # @UnresolvedImport + return PyQt4.QtCore _patch_import_to_patch_pyqt_on_import(patch_qt_on_import, get_qt_core_module) else: - raise ValueError('Unexpected qt support mode: %s' % (qt_support_mode,)) + raise ValueError("Unexpected qt support mode: %s" % (qt_support_mode,)) def _patch_import_to_patch_pyqt_on_import(patch_qt_on_import, get_qt_core_module): @@ -106,9 +114,9 @@ def _patch_import_to_patch_pyqt_on_import(patch_qt_on_import, get_qt_core_module # So, our approach is to patch PyQt4 right before the user tries to import it (at which # point he should've set the sip api version properly already anyways). - pydev_log.debug('Setting up Qt post-import monkeypatch.') + pydev_log.debug("Setting up Qt post-import monkeypatch.") - dotted = patch_qt_on_import + '.' + dotted = patch_qt_on_import + "." original_import = __import__ from _pydev_bundle._pydev_sys_patch import patch_sys_module, patch_reload, cancel_patches_in_sys_module @@ -128,15 +136,14 @@ def patched_import(name, *args, **kwargs): builtins.__import__ = patched_import -def _internal_patch_qt(QtCore, qt_support_mode='auto'): - pydev_log.debug('Patching Qt: %s', QtCore) +def _internal_patch_qt(QtCore, qt_support_mode="auto"): + pydev_log.debug("Patching Qt: %s", QtCore) _original_thread_init = QtCore.QThread.__init__ _original_runnable_init = QtCore.QRunnable.__init__ _original_QThread = QtCore.QThread class FuncWrapper: - def __init__(self, original): self._original = original @@ -145,7 +152,6 @@ def __call__(self, *args, **kwargs): return self._original(*args, **kwargs) class StartedSignalWrapper(QtCore.QObject): # Wrapper for the QThread.started signal - try: _signal = QtCore.Signal() # @UndefinedVariable except: @@ -155,14 +161,14 @@ def __init__(self, thread, original_started): QtCore.QObject.__init__(self) self.thread = thread self.original_started = original_started - if qt_support_mode in ('pyside', 'pyside2'): + if qt_support_mode in ("pyside", "pyside2"): self._signal = original_started else: self._signal.connect(self._on_call) self.original_started.connect(self._signal) def connect(self, func, *args, **kwargs): - if qt_support_mode in ('pyside', 'pyside2'): + if qt_support_mode in ("pyside", "pyside2"): return self._signal.connect(FuncWrapper(func), *args, **kwargs) else: return self._signal.connect(func, *args, **kwargs) @@ -177,7 +183,6 @@ def _on_call(self, *args, **kwargs): set_trace_in_qt() class ThreadWrapper(QtCore.QThread): # Wrapper for QThread - def __init__(self, *args, **kwargs): _original_thread_init(self, *args, **kwargs) @@ -201,7 +206,6 @@ def _new_run(self): return self._original_run() class RunnableWrapper(QtCore.QRunnable): # Wrapper for QRunnable - def __init__(self, *args, **kwargs): _original_runnable_init(self, *args, **kwargs) diff --git a/_pydev_bundle/pydev_override.py b/_pydev_bundle/pydev_override.py index d7581d207..ecf377e5e 100644 --- a/_pydev_bundle/pydev_override.py +++ b/_pydev_bundle/pydev_override.py @@ -1,12 +1,13 @@ def overrides(method): - ''' + """ Meant to be used as - + class B: @overrides(A.m1) def m1(self): pass - ''' + """ + def wrapper(func): if func.__name__ != method.__name__: msg = "Wrong @override: %r expected, but overwriting %r." @@ -20,6 +21,7 @@ def wrapper(func): return wrapper + def implements(method): def wrapper(func): if func.__name__ != method.__name__: @@ -32,4 +34,4 @@ def wrapper(func): return func - return wrapper \ No newline at end of file + return wrapper diff --git a/_pydev_bundle/pydev_umd.py b/_pydev_bundle/pydev_umd.py index 134ce4c5d..d83049132 100644 --- a/_pydev_bundle/pydev_umd.py +++ b/_pydev_bundle/pydev_umd.py @@ -56,6 +56,7 @@ def __init__(self, namelist=None, pathlist=None): try: # ignore all files in org.python.pydev/pysrc import pydev_pysrc, inspect + self.pathlist.append(os.path.dirname(pydev_pysrc.__file__)) except: pass @@ -66,7 +67,7 @@ def is_module_ignored(self, modname, modpath): if modpath.startswith(path): return True else: - return set(modname.split('.')) & set(self.namelist) + return set(modname.split(".")) & set(self.namelist) def run(self, verbose=False): """ @@ -79,11 +80,11 @@ def run(self, verbose=False): log = [] modules_copy = dict(sys.modules) for modname, module in modules_copy.items(): - if modname == 'aaaaa': + if modname == "aaaaa": print(modname, module) print(self.previous_modules) if modname not in self.previous_modules: - modpath = getattr(module, '__file__', None) + modpath = getattr(module, "__file__", None) if modpath is None: # *module* is a C module that is statically linked into the # interpreter. There is no way to know its path, so we @@ -93,8 +94,7 @@ def run(self, verbose=False): log.append(modname) del sys.modules[modname] if verbose and log: - print("\x1b[4;33m%s\x1b[24m%s\x1b[0m" % ("UMD has deleted", - ": " + ", ".join(log))) + print("\x1b[4;33m%s\x1b[24m%s\x1b[0m" % ("UMD has deleted", ": " + ", ".join(log))) __umd__ = None @@ -118,11 +118,12 @@ def _get_globals(): try: # The import fails on IronPython import __main__ + namespace = __main__.__dict__ except: namespace - shell = namespace.get('__ipythonshell__') - if shell is not None and hasattr(shell, 'user_ns'): + shell = namespace.get("__ipythonshell__") + if shell is not None and hasattr(shell, "user_ns"): # IPython 0.12+ kernel return shell.user_ns else: @@ -138,8 +139,8 @@ def runfile(filename, args=None, wdir=None, namespace=None): wdir: working directory """ try: - if hasattr(filename, 'decode'): - filename = filename.decode('utf-8') + if hasattr(filename, "decode"): + filename = filename.decode("utf-8") except (UnicodeError, TypeError): pass global __umd__ @@ -147,7 +148,7 @@ def runfile(filename, args=None, wdir=None, namespace=None): if __umd__ is None: namelist = os.environ.get("PYDEV_UMD_NAMELIST", None) if namelist is not None: - namelist = namelist.split(',') + namelist = namelist.split(",") __umd__ = UserModuleDeleter(namelist=namelist) else: verbose = os.environ.get("PYDEV_UMD_VERBOSE", "").lower() == "true" @@ -156,25 +157,25 @@ def runfile(filename, args=None, wdir=None, namespace=None): raise TypeError("expected a character buffer object") if namespace is None: namespace = _get_globals() - if '__file__' in namespace: - old_file = namespace['__file__'] + if "__file__" in namespace: + old_file = namespace["__file__"] else: old_file = None - namespace['__file__'] = filename + namespace["__file__"] = filename sys.argv = [filename] if args is not None: for arg in args.split(): sys.argv.append(arg) if wdir is not None: try: - if hasattr(wdir, 'decode'): - wdir = wdir.decode('utf-8') + if hasattr(wdir, "decode"): + wdir = wdir.decode("utf-8") except (UnicodeError, TypeError): pass os.chdir(wdir) execfile(filename, namespace) - sys.argv = [''] + sys.argv = [""] if old_file is None: - del namespace['__file__'] + del namespace["__file__"] else: - namespace['__file__'] = old_file + namespace["__file__"] = old_file diff --git a/_pydev_bundle/pydev_versioncheck.py b/_pydev_bundle/pydev_versioncheck.py index 70bf765f4..fb7372d6f 100644 --- a/_pydev_bundle/pydev_versioncheck.py +++ b/_pydev_bundle/pydev_versioncheck.py @@ -1,7 +1,8 @@ import sys + def versionok_for_gui(): - ''' Return True if running Python is suitable for GUI Event Integration and deeper IPython integration ''' + """Return True if running Python is suitable for GUI Event Integration and deeper IPython integration""" # We require Python 2.6+ ... if sys.hexversion < 0x02060000: return False @@ -9,8 +10,7 @@ def versionok_for_gui(): if sys.hexversion >= 0x03000000 and sys.hexversion < 0x03020000: return False # Not supported under Jython nor IronPython - if sys.platform.startswith("java") or sys.platform.startswith('cli'): + if sys.platform.startswith("java") or sys.platform.startswith("cli"): return False return True - diff --git a/_pydev_runfiles/pydev_runfiles.py b/_pydev_runfiles/pydev_runfiles.py index 9c199e175..2137efb9d 100644 --- a/_pydev_runfiles/pydev_runfiles.py +++ b/_pydev_runfiles/pydev_runfiles.py @@ -8,21 +8,20 @@ import time -#======================================================================================================================= +# ======================================================================================================================= # Configuration -#======================================================================================================================= +# ======================================================================================================================= class Configuration: - def __init__( self, - files_or_dirs='', + files_or_dirs="", verbosity=2, include_tests=None, tests=None, port=None, files_to_tests=None, jobs=1, - split_jobs='tests', + split_jobs="tests", coverage_output_dir=None, coverage_include=None, coverage_output_file=None, @@ -30,7 +29,7 @@ def __init__( exclude_tests=None, include_files=None, django=False, - ): + ): self.files_or_dirs = files_or_dirs self.verbosity = verbosity self.include_tests = include_tests @@ -59,7 +58,7 @@ def __init__( self.coverage_output_file = coverage_output_file def __str__(self): - return '''Configuration + return """Configuration - files_or_dirs: %s - verbosity: %s - tests: %s @@ -79,32 +78,28 @@ def __str__(self): - coverage_output_file: %s - django: %s -''' % ( - self.files_or_dirs, - self.verbosity, - self.tests, - self.port, - self.files_to_tests, - self.jobs, - self.split_jobs, - - self.include_files, - self.include_tests, - - self.exclude_files, - self.exclude_tests, - - self.coverage_output_dir, - self.coverage_include, - self.coverage_output_file, - - self.django, - ) - - -#======================================================================================================================= +""" % ( + self.files_or_dirs, + self.verbosity, + self.tests, + self.port, + self.files_to_tests, + self.jobs, + self.split_jobs, + self.include_files, + self.include_tests, + self.exclude_files, + self.exclude_tests, + self.coverage_output_dir, + self.coverage_include, + self.coverage_output_file, + self.django, + ) + + +# ======================================================================================================================= # parse_cmdline -#======================================================================================================================= +# ======================================================================================================================= def parse_cmdline(argv=None): """ Parses command line and returns test directories, verbosity, test filter and test suites @@ -132,7 +127,7 @@ def parse_cmdline(argv=None): tests = None port = None jobs = 1 - split_jobs = 'tests' + split_jobs = "tests" files_to_tests = {} coverage_output_dir = None coverage_include = None @@ -142,29 +137,25 @@ def parse_cmdline(argv=None): django = False from _pydev_bundle._pydev_getopt import gnu_getopt + optlist, dirs = gnu_getopt( - argv[1:], "", + argv[1:], + "", [ "verbosity=", "tests=", - "port=", "config_file=", - "jobs=", "split_jobs=", - "include_tests=", "include_files=", - "exclude_files=", "exclude_tests=", - "coverage_output_dir=", "coverage_include=", - - "django=" - ] + "django=", + ], ) for opt, value in optlist: @@ -179,37 +170,43 @@ def parse_cmdline(argv=None): elif opt in ("-s", "--split_jobs"): split_jobs = value - if split_jobs not in ('module', 'tests'): + if split_jobs not in ("module", "tests"): raise AssertionError('Expected split to be either "module" or "tests". Was :%s' % (split_jobs,)) - elif opt in ("-d", "--coverage_output_dir",): + elif opt in ( + "-d", + "--coverage_output_dir", + ): coverage_output_dir = value.strip() - elif opt in ("-i", "--coverage_include",): + elif opt in ( + "-i", + "--coverage_include", + ): coverage_include = value.strip() elif opt in ("-I", "--include_tests"): - include_tests = value.split(',') + include_tests = value.split(",") elif opt in ("-E", "--exclude_files"): - exclude_files = value.split(',') + exclude_files = value.split(",") elif opt in ("-F", "--include_files"): - include_files = value.split(',') + include_files = value.split(",") elif opt in ("-e", "--exclude_tests"): - exclude_tests = value.split(',') + exclude_tests = value.split(",") elif opt in ("-t", "--tests"): - tests = value.split(',') + tests = value.split(",") elif opt in ("--django",): - django = value.strip() in ['true', 'True', '1'] + django = value.strip() in ["true", "True", "1"] elif opt in ("-c", "--config_file"): config_file = value.strip() if os.path.exists(config_file): - f = open(config_file, 'r') + f = open(config_file, "r") try: config_file_contents = f.read() finally: @@ -220,7 +217,7 @@ def parse_cmdline(argv=None): if config_file_contents: for line in config_file_contents.splitlines(): - file_and_test = line.split('|') + file_and_test = line.split("|") if len(file_and_test) == 2: file, test = file_and_test if file in files_to_tests: @@ -229,16 +226,16 @@ def parse_cmdline(argv=None): files_to_tests[file] = [test] else: - sys.stderr.write('Could not find config file: %s\n' % (config_file,)) + sys.stderr.write("Could not find config file: %s\n" % (config_file,)) if type([]) != type(dirs): dirs = [dirs] ret_dirs = [] for d in dirs: - if '|' in d: + if "|" in d: # paths may come from the ide separated by | - ret_dirs.extend(d.split('|')) + ret_dirs.extend(d.split("|")) else: ret_dirs.append(d) @@ -246,7 +243,7 @@ def parse_cmdline(argv=None): if tests: if verbosity > 4: - sys.stdout.write('--tests provided. Ignoring --exclude_files, --exclude_tests and --include_files\n') + sys.stdout.write("--tests provided. Ignoring --exclude_files, --exclude_tests and --include_files\n") exclude_files = exclude_tests = include_files = None config = Configuration( @@ -267,34 +264,30 @@ def parse_cmdline(argv=None): ) if verbosity > 5: - sys.stdout.write(str(config) + '\n') + sys.stdout.write(str(config) + "\n") return config -#======================================================================================================================= +# ======================================================================================================================= # PydevTestRunner -#======================================================================================================================= +# ======================================================================================================================= class PydevTestRunner(object): - """ finds and runs a file or directory of files as a unit test """ + """finds and runs a file or directory of files as a unit test""" __py_extensions = ["*.py", "*.pyw"] __exclude_files = ["__init__.*"] # Just to check that only this attributes will be written to this file __slots__ = [ - 'verbosity', # Always used - - 'files_to_tests', # If this one is given, the ones below are not used - - 'files_or_dirs', # Files or directories received in the command line - 'include_tests', # The filter used to collect the tests - 'tests', # Strings with the tests to be run - - 'jobs', # Integer with the number of jobs that should be used to run the test cases - 'split_jobs', # String with 'tests' or 'module' (how should the jobs be split) - - 'configuration', - 'coverage', + "verbosity", # Always used + "files_to_tests", # If this one is given, the ones below are not used + "files_or_dirs", # Files or directories received in the command line + "include_tests", # The filter used to collect the tests + "tests", # Strings with the tests to be run + "jobs", # Integer with the number of jobs that should be used to run the test cases + "split_jobs", # String with 'tests' or 'module' (how should the jobs be split) + "configuration", + "coverage", ] def __init__(self, configuration): @@ -317,7 +310,7 @@ def __init__(self, configuration): self.__adjust_path() def __adjust_path(self): - """ add the current file or directory to the python path """ + """add the current file or directory to the python path""" path_to_append = None for n in range(len(self.files_or_dirs)): dir_name = self.__unixify(self.files_or_dirs[n]) @@ -329,10 +322,10 @@ def __adjust_path(self): path_to_append = os.path.dirname(dir_name) else: if not os.path.exists(dir_name): - block_line = '*' * 120 - sys.stderr.write('\n%s\n* PyDev test runner error: %s does not exist.\n%s\n' % (block_line, dir_name, block_line)) + block_line = "*" * 120 + sys.stderr.write("\n%s\n* PyDev test runner error: %s does not exist.\n%s\n" % (block_line, dir_name, block_line)) return - msg = ("unknown type. \n%s\nshould be file or a directory.\n" % (dir_name)) + msg = "unknown type. \n%s\nshould be file or a directory.\n" % (dir_name) raise RuntimeError(msg) if path_to_append is not None: # Add it as the last one (so, first things are resolved against the default dirs and @@ -340,8 +333,8 @@ def __adjust_path(self): sys.path.append(path_to_append) def __is_valid_py_file(self, fname): - """ tests that a particular file contains the proper file extension - and is not in the list of files to exclude """ + """tests that a particular file contains the proper file extension + and is not in the list of files to exclude""" is_valid_fname = 0 for invalid_fname in self.__class__.__exclude_files: is_valid_fname += int(not fnmatch.fnmatch(fname, invalid_fname)) @@ -351,16 +344,16 @@ def __is_valid_py_file(self, fname): return is_valid_fname > 0 and if_valid_ext > 0 def __unixify(self, s): - """ stupid windows. converts the backslash to forwardslash for consistency """ + """stupid windows. converts the backslash to forwardslash for consistency""" return os.path.normpath(s).replace(os.sep, "/") def __importify(self, s, dir=False): - """ turns directory separators into dots and removes the ".py*" extension - so the string can be used as import statement """ + """turns directory separators into dots and removes the ".py*" extension + so the string can be used as import statement""" if not dir: dirname, fname = os.path.split(s) - if fname.count('.') > 1: + if fname.count(".") > 1: # if there's a file named xxx.xx.py, it is not a valid module, so, let's not load it... return @@ -375,14 +368,14 @@ def __importify(self, s, dir=False): return s.replace("\\", "/").replace("/", ".") def __add_files(self, pyfiles, root, files): - """ if files match, appends them to pyfiles. used by os.path.walk fcn """ + """if files match, appends them to pyfiles. used by os.path.walk fcn""" for fname in files: if self.__is_valid_py_file(fname): name_without_base_dir = self.__unixify(os.path.join(root, fname)) pyfiles.append(name_without_base_dir) def find_import_files(self): - """ return a list of files to import """ + """return a list of files to import""" if self.files_to_tests: pyfiles = self.files_to_tests.keys() else: @@ -395,8 +388,8 @@ def find_import_files(self): # they don't have __init__.py exclude = {} for d in dirs: - for init in ['__init__.py', '__init__.pyo', '__init__.pyc', '__init__.pyw', '__init__$py.class']: - if os.path.exists(os.path.join(root, d, init).replace('\\', '/')): + for init in ["__init__.py", "__init__.pyo", "__init__.pyc", "__init__.pyw", "__init__$py.class"]: + if os.path.exists(os.path.join(root, d, init).replace("\\", "/")): break else: exclude[d] = 1 @@ -429,23 +422,25 @@ def find_import_files(self): if not add: if self.verbosity > 3: - sys.stdout.write('Skipped file: %s (did not match any include_files pattern: %s)\n' % (f, self.configuration.include_files)) + sys.stdout.write( + "Skipped file: %s (did not match any include_files pattern: %s)\n" % (f, self.configuration.include_files) + ) elif self.configuration.exclude_files: for pat in self.configuration.exclude_files: if fnmatch.fnmatchcase(basename, pat): if self.verbosity > 3: - sys.stdout.write('Skipped file: %s (matched exclude_files pattern: %s)\n' % (f, pat)) + sys.stdout.write("Skipped file: %s (matched exclude_files pattern: %s)\n" % (f, pat)) elif self.verbosity > 2: - sys.stdout.write('Skipped file: %s\n' % (f,)) + sys.stdout.write("Skipped file: %s\n" % (f,)) add = False break if add: if self.verbosity > 3: - sys.stdout.write('Adding file: %s for test discovery.\n' % (f,)) + sys.stdout.write("Adding file: %s for test discovery.\n" % (f,)) ret.append(f) pyfiles = ret @@ -453,29 +448,31 @@ def find_import_files(self): return pyfiles def __get_module_from_str(self, modname, print_exception, pyfile): - """ Import the module in the given import path. - * Returns the "final" module, so importing "coilib40.subject.visu" - returns the "visu" module, not the "coilib40" as returned by __import__ """ + """Import the module in the given import path. + * Returns the "final" module, so importing "coilib40.subject.visu" + returns the "visu" module, not the "coilib40" as returned by __import__""" try: mod = __import__(modname) - for part in modname.split('.')[1:]: + for part in modname.split(".")[1:]: mod = getattr(mod, part) return mod except: if print_exception: from _pydev_runfiles import pydev_runfiles_xml_rpc from _pydevd_bundle import pydevd_io - buf_err = pydevd_io.start_redirect(keep_original_redirection=True, std='stderr') - buf_out = pydevd_io.start_redirect(keep_original_redirection=True, std='stdout') + + buf_err = pydevd_io.start_redirect(keep_original_redirection=True, std="stderr") + buf_out = pydevd_io.start_redirect(keep_original_redirection=True, std="stdout") try: - import traceback;traceback.print_exc() - sys.stderr.write('ERROR: Module: %s could not be imported (file: %s).\n' % (modname, pyfile)) + import traceback + + traceback.print_exc() + sys.stderr.write("ERROR: Module: %s could not be imported (file: %s).\n" % (modname, pyfile)) finally: - pydevd_io.end_redirect('stderr') - pydevd_io.end_redirect('stdout') + pydevd_io.end_redirect("stderr") + pydevd_io.end_redirect("stdout") - pydev_runfiles_xml_rpc.notifyTest( - 'error', buf_out.getvalue(), buf_err.getvalue(), pyfile, modname, 0) + pydev_runfiles_xml_rpc.notifyTest("error", buf_out.getvalue(), buf_err.getvalue(), pyfile, modname, 0) return None @@ -485,7 +482,7 @@ def remove_duplicates_keeping_order(self, seq): return [x for x in seq if not (x in seen or seen_add(x))] def find_modules_from_files(self, pyfiles): - """ returns a list of modules given a list of files """ + """returns a list of modules given a list of files""" # let's make sure that the paths we want are in the pythonpath... imports = [(s, self.__importify(s)) for s in pyfiles] @@ -503,13 +500,13 @@ def find_modules_from_files(self, pyfiles): choices = [] for s in system_paths: if imp.startswith(s): - add = imp[len(s) + 1:] + add = imp[len(s) + 1 :] if add: choices.append(add) # sys.stdout.write(' ' + add + ' ') if not choices: - sys.stdout.write('PYTHONPATH not found for file: %s\n' % imp) + sys.stdout.write("PYTHONPATH not found for file: %s\n" % imp) else: for i, import_str in enumerate(choices): print_exception = i == len(choices) - 1 @@ -520,9 +517,9 @@ def find_modules_from_files(self, pyfiles): return ret - #=================================================================================================================== + # =================================================================================================================== # GetTestCaseNames - #=================================================================================================================== + # =================================================================================================================== class GetTestCaseNames: """Yes, we need a class for that (cannot use outer context on jython 2.1)""" @@ -538,14 +535,14 @@ def __call__(self, testCaseClass): if className in self.accepted_classes: for attrname in dir(testCaseClass): # If a class is chosen, we select all the 'test' methods' - if attrname.startswith('test') and hasattr(getattr(testCaseClass, attrname), '__call__'): + if attrname.startswith("test") and hasattr(getattr(testCaseClass, attrname), "__call__"): testFnNames.append(attrname) else: for attrname in dir(testCaseClass): # If we have the class+method name, we must do a full check and have an exact match. - if className + '.' + attrname in self.accepted_methods: - if hasattr(getattr(testCaseClass, attrname), '__call__'): + if className + "." + attrname in self.accepted_methods: + if hasattr(getattr(testCaseClass, attrname), "__call__"): testFnNames.append(attrname) # sorted() is not available in jython 2.1 @@ -554,6 +551,7 @@ def __call__(self, testCaseClass): def _decorate_test_suite(self, suite, pyfile, module_name): import unittest + if isinstance(suite, unittest.TestSuite): add = False suite.__pydev_pyfile__ = pyfile @@ -574,10 +572,11 @@ def _decorate_test_suite(self, suite, pyfile, module_name): return False def find_tests_from_modules(self, file_and_modules_and_module_name): - """ returns the unittests given a list of modules """ + """returns the unittests given a list of modules""" # Use our own suite! from _pydev_runfiles import pydev_runfiles_unittest import unittest + unittest.TestLoader.suiteClass = pydev_runfiles_unittest.PydevTestSuite loader = unittest.TestLoader() @@ -602,7 +601,7 @@ def find_tests_from_modules(self, file_and_modules_and_module_name): accepted_methods = {} for t in self.tests: - splitted = t.split('.') + splitted = t.split(".") if len(splitted) == 1: accepted_classes[t] = t @@ -619,9 +618,10 @@ def find_tests_from_modules(self, file_and_modules_and_module_name): return ret def filter_tests(self, test_objs, internal_call=False): - """ based on a filter name, only return those tests that have - the test case names that match """ + """based on a filter name, only return those tests that have + the test case names that match""" import unittest + if not internal_call: if not self.configuration.include_tests and not self.tests and not self.configuration.exclude_tests: # No need to filter if we have nothing to filter! @@ -629,17 +629,16 @@ def filter_tests(self, test_objs, internal_call=False): if self.verbosity > 1: if self.configuration.include_tests: - sys.stdout.write('Tests to include: %s\n' % (self.configuration.include_tests,)) + sys.stdout.write("Tests to include: %s\n" % (self.configuration.include_tests,)) if self.tests: - sys.stdout.write('Tests to run: %s\n' % (self.tests,)) + sys.stdout.write("Tests to run: %s\n" % (self.tests,)) if self.configuration.exclude_tests: - sys.stdout.write('Tests to exclude: %s\n' % (self.configuration.exclude_tests,)) + sys.stdout.write("Tests to exclude: %s\n" % (self.configuration.exclude_tests,)) test_suite = [] for test_obj in test_objs: - if isinstance(test_obj, unittest.TestSuite): # Note: keep the suites as they are and just 'fix' the tests (so, don't use the iter_tests). if test_obj._tests: @@ -659,10 +658,10 @@ def filter_tests(self, test_objs, internal_call=False): for pat in self.configuration.exclude_tests: if fnmatch.fnmatchcase(testMethodName, pat): if self.verbosity > 3: - sys.stdout.write('Skipped test: %s (matched exclude_tests pattern: %s)\n' % (testMethodName, pat)) + sys.stdout.write("Skipped test: %s (matched exclude_tests pattern: %s)\n" % (testMethodName, pat)) elif self.verbosity > 2: - sys.stdout.write('Skipped test: %s\n' % (testMethodName,)) + sys.stdout.write("Skipped test: %s\n" % (testMethodName,)) add = False break @@ -680,13 +679,19 @@ def filter_tests(self, test_objs, internal_call=False): test_suite.append(test_obj) else: if self.verbosity > 3: - sys.stdout.write('Skipped test: %s (did not match any include_tests pattern %s)\n' % ( - testMethodName, self.configuration.include_tests,)) + sys.stdout.write( + "Skipped test: %s (did not match any include_tests pattern %s)\n" + % ( + testMethodName, + self.configuration.include_tests, + ) + ) return test_suite def iter_tests(self, test_objs): # Note: not using yield because of Jython 2.1. import unittest + tests = [] for test_obj in test_objs: if isinstance(test_obj, unittest.TestSuite): @@ -712,7 +717,7 @@ def __match_tests(self, tests, test_case, test_method_name): return 1 for t in tests: - class_and_method = t.split('.') + class_and_method = t.split(".") if len(class_and_method) == 1: # only class name if class_and_method[0] == test_case.__class__.__name__: @@ -725,7 +730,7 @@ def __match_tests(self, tests, test_case, test_method_name): return 0 def __match(self, filter_list, name): - """ returns whether a test name matches the test filter """ + """returns whether a test name matches the test filter""" if filter_list is None: return 1 for f in filter_list: @@ -734,13 +739,13 @@ def __match(self, filter_list, name): return 0 def run_tests(self, handle_coverage=True): - """ runs all tests """ + """runs all tests""" sys.stdout.write("Finding files... ") files = self.find_import_files() if self.verbosity > 3: - sys.stdout.write('%s ... done.\n' % (self.files_or_dirs)) + sys.stdout.write("%s ... done.\n" % (self.files_or_dirs)) else: - sys.stdout.write('done.\n') + sys.stdout.write("done.\n") sys.stdout.write("Importing test modules ... ") if handle_coverage: @@ -753,8 +758,10 @@ def run_tests(self, handle_coverage=True): all_tests = self.filter_tests(all_tests) from _pydev_runfiles import pydev_runfiles_unittest + test_suite = pydev_runfiles_unittest.PydevTestSuite(all_tests) from _pydev_runfiles import pydev_runfiles_xml_rpc + pydev_runfiles_xml_rpc.notifyTestsCollected(test_suite.countTestCases()) start_time = time.time() @@ -768,12 +775,13 @@ def run_tests(): # (e.g.: 2 jobs were requested for running 1 test) -- in which case execute_tests_in_parallel will # return False and won't run any tests. executed_in_parallel = pydev_runfiles_parallel.execute_tests_in_parallel( - all_tests, self.jobs, self.split_jobs, self.verbosity, coverage_files, self.configuration.coverage_include) + all_tests, self.jobs, self.split_jobs, self.verbosity, coverage_files, self.configuration.coverage_include + ) if not executed_in_parallel: # If in coverage, we don't need to pass anything here (coverage is already enabled for this execution). runner = pydev_runfiles_unittest.PydevTextTestRunner(stream=sys.stdout, descriptions=1, verbosity=self.verbosity) - sys.stdout.write('\n') + sys.stdout.write("\n") runner.run(test_suite) if self.configuration.django: @@ -785,7 +793,7 @@ def run_tests(): coverage.stop() coverage.save() - total_time = 'Finished in: %.2f secs.' % (time.time() - start_time,) + total_time = "Finished in: %.2f secs." % (time.time() - start_time,) pydev_runfiles_xml_rpc.notifyTestRunFinished(total_time) @@ -802,7 +810,6 @@ def get_django_test_suite_runner(): from django.test.runner import DiscoverRunner class MyDjangoTestSuiteRunner(DiscoverRunner): - def __init__(self, on_run_suite): django.setup() DiscoverRunner.__init__(self) @@ -824,15 +831,15 @@ def run_suite(self, *args, **kwargs): except: class DjangoTestSuiteRunner: - def __init__(self): pass def run_tests(self, *args, **kwargs): - raise AssertionError("Unable to run suite with django.test.runner.DiscoverRunner nor django.test.simple.DjangoTestSuiteRunner because it couldn't be imported.") + raise AssertionError( + "Unable to run suite with django.test.runner.DiscoverRunner nor django.test.simple.DjangoTestSuiteRunner because it couldn't be imported." + ) class MyDjangoTestSuiteRunner(DjangoTestSuiteRunner): - def __init__(self, on_run_suite): DjangoTestSuiteRunner.__init__(self) self.on_run_suite = on_run_suite @@ -850,8 +857,8 @@ def run_suite(self, *args, **kwargs): return DJANGO_TEST_SUITE_RUNNER -#======================================================================================================================= +# ======================================================================================================================= # main -#======================================================================================================================= +# ======================================================================================================================= def main(configuration): PydevTestRunner(configuration).run_tests() diff --git a/_pydev_runfiles/pydev_runfiles_coverage.py b/_pydev_runfiles/pydev_runfiles_coverage.py index a83592500..a088b4249 100644 --- a/_pydev_runfiles/pydev_runfiles_coverage.py +++ b/_pydev_runfiles/pydev_runfiles_coverage.py @@ -3,74 +3,75 @@ from _pydevd_bundle.pydevd_constants import Null -#======================================================================================================================= +# ======================================================================================================================= # get_coverage_files -#======================================================================================================================= +# ======================================================================================================================= def get_coverage_files(coverage_output_dir, number_of_files): base_dir = coverage_output_dir ret = [] i = 0 while len(ret) < number_of_files: while True: - f = os.path.join(base_dir, '.coverage.%s' % i) + f = os.path.join(base_dir, ".coverage.%s" % i) i += 1 if not os.path.exists(f): ret.append(f) - break #Break only inner for. + break # Break only inner for. return ret -#======================================================================================================================= +# ======================================================================================================================= # start_coverage_support -#======================================================================================================================= +# ======================================================================================================================= def start_coverage_support(configuration): return start_coverage_support_from_params( - configuration.coverage_output_dir, - configuration.coverage_output_file, - configuration.jobs, - configuration.coverage_include, + configuration.coverage_output_dir, + configuration.coverage_output_file, + configuration.jobs, + configuration.coverage_include, ) - -#======================================================================================================================= + +# ======================================================================================================================= # start_coverage_support_from_params -#======================================================================================================================= +# ======================================================================================================================= def start_coverage_support_from_params(coverage_output_dir, coverage_output_file, jobs, coverage_include): coverage_files = [] coverage_instance = Null() if coverage_output_dir or coverage_output_file: try: - import coverage #@UnresolvedImport + import coverage # @UnresolvedImport except: - sys.stderr.write('Error: coverage module could not be imported\n') - sys.stderr.write('Please make sure that the coverage module (http://nedbatchelder.com/code/coverage/)\n') - sys.stderr.write('is properly installed in your interpreter: %s\n' % (sys.executable,)) - - import traceback;traceback.print_exc() + sys.stderr.write("Error: coverage module could not be imported\n") + sys.stderr.write("Please make sure that the coverage module (http://nedbatchelder.com/code/coverage/)\n") + sys.stderr.write("is properly installed in your interpreter: %s\n" % (sys.executable,)) + + import traceback + + traceback.print_exc() else: if coverage_output_dir: if not os.path.exists(coverage_output_dir): - sys.stderr.write('Error: directory for coverage output (%s) does not exist.\n' % (coverage_output_dir,)) - + sys.stderr.write("Error: directory for coverage output (%s) does not exist.\n" % (coverage_output_dir,)) + elif not os.path.isdir(coverage_output_dir): - sys.stderr.write('Error: expected (%s) to be a directory.\n' % (coverage_output_dir,)) - + sys.stderr.write("Error: expected (%s) to be a directory.\n" % (coverage_output_dir,)) + else: n = jobs if n <= 0: n += 1 - n += 1 #Add 1 more for the current process (which will do the initial import). + n += 1 # Add 1 more for the current process (which will do the initial import). coverage_files = get_coverage_files(coverage_output_dir, n) - os.environ['COVERAGE_FILE'] = coverage_files.pop(0) - + os.environ["COVERAGE_FILE"] = coverage_files.pop(0) + coverage_instance = coverage.coverage(source=[coverage_include]) coverage_instance.start() - + elif coverage_output_file: - #Client of parallel run. - os.environ['COVERAGE_FILE'] = coverage_output_file + # Client of parallel run. + os.environ["COVERAGE_FILE"] = coverage_output_file coverage_instance = coverage.coverage(source=[coverage_include]) coverage_instance.start() - - return coverage_files, coverage_instance + return coverage_files, coverage_instance diff --git a/_pydev_runfiles/pydev_runfiles_nose.py b/_pydev_runfiles/pydev_runfiles_nose.py index 20ea5b295..13a01b2ee 100644 --- a/_pydev_runfiles/pydev_runfiles_nose.py +++ b/_pydev_runfiles/pydev_runfiles_nose.py @@ -9,11 +9,10 @@ import traceback -#======================================================================================================================= +# ======================================================================================================================= # PydevPlugin -#======================================================================================================================= +# ======================================================================================================================= class PydevPlugin(Plugin): - def __init__(self, configuration): self.configuration = configuration Plugin.__init__(self) @@ -28,13 +27,13 @@ def finalize(self, result): self.coverage.stop() self.coverage.save() - pydev_runfiles_xml_rpc.notifyTestRunFinished('Finished in: %.2f secs.' % (time.time() - self.start_time,)) + pydev_runfiles_xml_rpc.notifyTestRunFinished("Finished in: %.2f secs." % (time.time() - self.start_time,)) - #=================================================================================================================== + # =================================================================================================================== # Methods below are not called with multiprocess (so, we monkey-patch MultiProcessTestRunner.consolidate # so that they're called, but unfortunately we loose some info -- i.e.: the time for each test in this # process). - #=================================================================================================================== + # =================================================================================================================== class Sentinel(object): pass @@ -46,8 +45,8 @@ def _without_user_address(self, test): user_address = self.Sentinel user_class_address = self.Sentinel try: - if 'address' in user_test_instance.__dict__: - user_address = user_test_instance.__dict__.pop('address') + if "address" in user_test_instance.__dict__: + user_address = user_test_instance.__dict__.pop("address") except: # Just ignore anything here. pass @@ -62,14 +61,14 @@ def _without_user_address(self, test): yield finally: if user_address is not self.Sentinel: - user_test_instance.__dict__['address'] = user_address + user_test_instance.__dict__["address"] = user_address if user_class_address is not self.Sentinel: user_test_instance.__class__.address = user_class_address def _get_test_address(self, test): try: - if hasattr(test, 'address'): + if hasattr(test, "address"): with self._without_user_address(test): address = test.address() @@ -86,30 +85,30 @@ def _get_test_address(self, test): except TypeError: # It may be an error at setup, in which case it's not really a test, but a Context object. f = test.context.__file__ - if f.endswith('.pyc'): + if f.endswith(".pyc"): f = f[:-1] - elif f.endswith('$py.class'): - f = f[:-len('$py.class')] + '.py' - address = f, '?' + elif f.endswith("$py.class"): + f = f[: -len("$py.class")] + ".py" + address = f, "?" except: sys.stderr.write("PyDev: Internal pydev error getting test address. Please report at the pydev bug tracker\n") traceback.print_exc() sys.stderr.write("\n\n\n") - address = '?', '?' + address = "?", "?" return address - def report_cond(self, cond, test, captured_output, error=''): - ''' + def report_cond(self, cond, test, captured_output, error=""): + """ @param cond: fail, error, ok - ''' + """ address = self._get_test_address(test) error_contents = self.get_io_from_error(error) try: - time_str = '%.2f' % (time.time() - test._pydev_start_time) + time_str = "%.2f" % (time.time() - test._pydev_start_time) except: - time_str = '?' + time_str = "?" pydev_runfiles_xml_rpc.notifyTest(cond, captured_output, error_contents, address[0], address[1], time_str) @@ -132,13 +131,13 @@ def get_io_from_error(self, err): return err def get_captured_output(self, test): - if hasattr(test, 'capturedOutput') and test.capturedOutput: + if hasattr(test, "capturedOutput") and test.capturedOutput: return test.capturedOutput - return '' + return "" def addError(self, test, err): self.report_cond( - 'error', + "error", test, self.get_captured_output(test), err, @@ -146,7 +145,7 @@ def addError(self, test, err): def addFailure(self, test, err): self.report_cond( - 'fail', + "fail", test, self.get_captured_output(test), err, @@ -154,10 +153,10 @@ def addFailure(self, test, err): def addSuccess(self, test): self.report_cond( - 'ok', + "ok", test, self.get_captured_output(test), - '', + "", ) @@ -173,33 +172,33 @@ def start_pydev_nose_plugin_singleton(configuration): original = MultiProcessTestRunner.consolidate -#======================================================================================================================= +# ======================================================================================================================= # new_consolidate -#======================================================================================================================= +# ======================================================================================================================= def new_consolidate(self, result, batch_result): - ''' + """ Used so that it can work with the multiprocess plugin. Monkeypatched because nose seems a bit unsupported at this time (ideally the plugin would have this support by default). - ''' + """ ret = original(self, result, batch_result) parent_frame = sys._getframe().f_back # addr is something as D:\pytesting1\src\mod1\hello.py:TestCase.testMet4 # so, convert it to what report_cond expects - addr = parent_frame.f_locals['addr'] - i = addr.rindex(':') - addr = [addr[:i], addr[i + 1:]] + addr = parent_frame.f_locals["addr"] + i = addr.rindex(":") + addr = [addr[:i], addr[i + 1 :]] output, testsRun, failures, errors, errorClasses = batch_result if failures or errors: for failure in failures: - PYDEV_NOSE_PLUGIN_SINGLETON.report_cond('fail', addr, output, failure) + PYDEV_NOSE_PLUGIN_SINGLETON.report_cond("fail", addr, output, failure) for error in errors: - PYDEV_NOSE_PLUGIN_SINGLETON.report_cond('error', addr, output, error) + PYDEV_NOSE_PLUGIN_SINGLETON.report_cond("error", addr, output, error) else: - PYDEV_NOSE_PLUGIN_SINGLETON.report_cond('ok', addr, output) + PYDEV_NOSE_PLUGIN_SINGLETON.report_cond("ok", addr, output) return ret diff --git a/_pydev_runfiles/pydev_runfiles_parallel.py b/_pydev_runfiles/pydev_runfiles_parallel.py index b34c45e95..55a213420 100644 --- a/_pydev_runfiles/pydev_runfiles_parallel.py +++ b/_pydev_runfiles/pydev_runfiles_parallel.py @@ -8,9 +8,9 @@ import sys -#======================================================================================================================= +# ======================================================================================================================= # flatten_test_suite -#======================================================================================================================= +# ======================================================================================================================= def flatten_test_suite(test_suite, ret): if isinstance(test_suite, unittest.TestSuite): for t in test_suite._tests: @@ -20,11 +20,11 @@ def flatten_test_suite(test_suite, ret): ret.append(test_suite) -#======================================================================================================================= +# ======================================================================================================================= # execute_tests_in_parallel -#======================================================================================================================= +# ======================================================================================================================= def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, coverage_include): - ''' + """ @param tests: list(PydevTestSuite) A list with the suites to be run @@ -44,9 +44,10 @@ def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, cov run. It may also return False if in debug mode (in which case, multi-processes are not accepted) - ''' + """ try: from _pydevd_bundle.pydevd_comm import get_global_debugger + if get_global_debugger() is not None: return False except: @@ -58,7 +59,7 @@ def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, cov tests_queue = [] queue_elements = [] - if split == 'module': + if split == "module": module_to_tests = {} for test in tests: lst = [] @@ -74,7 +75,7 @@ def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, cov # Don't create jobs we will never use. jobs = len(queue_elements) - elif split == 'tests': + elif split == "tests": for test in tests: lst = [] flatten_test_suite(test, lst) @@ -86,7 +87,7 @@ def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, cov jobs = len(queue_elements) else: - raise AssertionError('Do not know how to handle: %s' % (split,)) + raise AssertionError("Do not know how to handle: %s" % (split,)) for test_cases in queue_elements: test_queue_elements = [] @@ -97,14 +98,14 @@ def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, cov # Support for jython 2.1 (__testMethodName is pseudo-private in the test case) test_name = test_case.__class__.__name__ + "." + test_case._TestCase__testMethodName - test_queue_elements.append(test_case.__pydev_pyfile__ + '|' + test_name) + test_queue_elements.append(test_case.__pydev_pyfile__ + "|" + test_name) tests_queue.append(test_queue_elements) if jobs < 2: return False - sys.stdout.write('Running tests in parallel with: %s jobs.\n' % (jobs,)) + sys.stdout.write("Running tests in parallel with: %s jobs.\n" % (jobs,)) queue = Queue.Queue() for item in tests_queue: @@ -134,7 +135,7 @@ def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, cov # Wait for all the clients to exit. if not client.finished: client_alive = True - time.sleep(.2) + time.sleep(0.2) break for provider in providers: @@ -143,11 +144,10 @@ def execute_tests_in_parallel(tests, jobs, split, verbosity, coverage_files, cov return True -#======================================================================================================================= +# ======================================================================================================================= # CommunicationThread -#======================================================================================================================= +# ======================================================================================================================= class CommunicationThread(threading.Thread): - def __init__(self, tests_queue): threading.Thread.__init__(self) self.daemon = True @@ -166,12 +166,12 @@ def __init__(self, tests_queue): self.server = server def GetTestsToRun(self, job_id): - ''' + """ @param job_id: @return: list(str) Each entry is a string in the format: filename|Test.testName - ''' + """ try: ret = self.queue.get(block=False) return ret @@ -195,13 +195,13 @@ def notifyTest(self, job_id, *args, **kwargs): return True def shutdown(self): - if hasattr(self.server, 'shutdown'): + if hasattr(self.server, "shutdown"): self.server.shutdown() else: self._shutdown = True def run(self): - if hasattr(self.server, 'shutdown'): + if hasattr(self.server, "shutdown"): self.server.serve_forever() else: self._shutdown = False @@ -209,11 +209,10 @@ def run(self): self.server.handle_request() -#======================================================================================================================= +# ======================================================================================================================= # Client -#======================================================================================================================= +# ======================================================================================================================= class ClientThread(threading.Thread): - def __init__(self, job_id, port, verbosity, coverage_output_file=None, coverage_include=None): threading.Thread.__init__(self) self.daemon = True @@ -252,6 +251,7 @@ def run(self): args.append(self.coverage_include) import subprocess + if False: proc = subprocess.Popen(args, env=os.environ, shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -264,4 +264,3 @@ def run(self): finally: self.finished = True - diff --git a/_pydev_runfiles/pydev_runfiles_parallel_client.py b/_pydev_runfiles/pydev_runfiles_parallel_client.py index 3d81dd581..0132b06f5 100644 --- a/_pydev_runfiles/pydev_runfiles_parallel_client.py +++ b/_pydev_runfiles/pydev_runfiles_parallel_client.py @@ -1,4 +1,5 @@ from _pydev_bundle.pydev_imports import xmlrpclib, _queue + Queue = _queue.Queue import traceback import sys @@ -6,11 +7,10 @@ import threading -#======================================================================================================================= +# ======================================================================================================================= # ParallelNotification -#======================================================================================================================= +# ======================================================================================================================= class ParallelNotification(object): - def __init__(self, method, args, kwargs): self.method = method self.args = args @@ -20,25 +20,21 @@ def to_tuple(self): return self.method, self.args, self.kwargs -#======================================================================================================================= +# ======================================================================================================================= # KillServer -#======================================================================================================================= +# ======================================================================================================================= class KillServer(object): pass - -#======================================================================================================================= +# ======================================================================================================================= # ServerComm -#======================================================================================================================= +# ======================================================================================================================= class ServerComm(threading.Thread): - - - def __init__(self, job_id, server): self.notifications_queue = Queue() threading.Thread.__init__(self) - self.setDaemon(False) #Wait for all the notifications to be passed before exiting! + self.setDaemon(False) # Wait for all the notifications to be passed before exiting! assert job_id is not None assert port is not None self.job_id = job_id @@ -46,7 +42,6 @@ def __init__(self, job_id, server): self.finished = False self.server = server - def run(self): while True: kill_found = False @@ -60,19 +55,18 @@ def run(self): try: while True: - command = self.notifications_queue.get(block=False) #No block to create a batch. + command = self.notifications_queue.get(block=False) # No block to create a batch. if isinstance(command, KillServer): kill_found = True else: assert isinstance(command, ParallelNotification) commands.append(command.to_tuple()) except: - pass #That's OK, we're getting it until it becomes empty so that we notify multiple at once. - + pass # That's OK, we're getting it until it becomes empty so that we notify multiple at once. if commands: try: - #Batch notification. + # Batch notification. self.server.lock.acquire() try: self.server.notifyCommands(self.job_id, commands) @@ -86,44 +80,36 @@ def run(self): return - -#======================================================================================================================= +# ======================================================================================================================= # ServerFacade -#======================================================================================================================= +# ======================================================================================================================= class ServerFacade(object): - - def __init__(self, notifications_queue): self.notifications_queue = notifications_queue - def notifyTestsCollected(self, *args, **kwargs): - pass #This notification won't be passed - + pass # This notification won't be passed def notifyTestRunFinished(self, *args, **kwargs): - pass #This notification won't be passed - + pass # This notification won't be passed def notifyStartTest(self, *args, **kwargs): - self.notifications_queue.put_nowait(ParallelNotification('notifyStartTest', args, kwargs)) - + self.notifications_queue.put_nowait(ParallelNotification("notifyStartTest", args, kwargs)) def notifyTest(self, *args, **kwargs): - self.notifications_queue.put_nowait(ParallelNotification('notifyTest', args, kwargs)) - + self.notifications_queue.put_nowait(ParallelNotification("notifyTest", args, kwargs)) -#======================================================================================================================= +# ======================================================================================================================= # run_client -#======================================================================================================================= +# ======================================================================================================================= def run_client(job_id, port, verbosity, coverage_output_file, coverage_include): job_id = int(job_id) from _pydev_bundle import pydev_localhost - server = xmlrpclib.Server('http://%s:%s' % (pydev_localhost.get_localhost(), port)) - server.lock = threading.Lock() + server = xmlrpclib.Server("http://%s:%s" % (pydev_localhost.get_localhost(), port)) + server.lock = threading.Lock() server_comm = ServerComm(job_id, server) server_comm.start() @@ -132,17 +118,18 @@ def run_client(job_id, port, verbosity, coverage_output_file, coverage_include): server_facade = ServerFacade(server_comm.notifications_queue) from _pydev_runfiles import pydev_runfiles from _pydev_runfiles import pydev_runfiles_xml_rpc + pydev_runfiles_xml_rpc.set_server(server_facade) - #Starts None and when the 1st test is gotten, it's started (because a server may be initiated and terminated - #before receiving any test -- which would mean a different process got all the tests to run). + # Starts None and when the 1st test is gotten, it's started (because a server may be initiated and terminated + # before receiving any test -- which would mean a different process got all the tests to run). coverage = None try: tests_to_run = [1] while tests_to_run: - #Investigate: is it dangerous to use the same xmlrpclib server from different threads? - #It seems it should be, as it creates a new connection for each request... + # Investigate: is it dangerous to use the same xmlrpclib server from different threads? + # It seems it should be, as it creates a new connection for each request... server.lock.acquire() try: tests_to_run = server.GetTestsToRun(job_id) @@ -153,27 +140,24 @@ def run_client(job_id, port, verbosity, coverage_output_file, coverage_include): break if coverage is None: - _coverage_files, coverage = start_coverage_support_from_params( - None, coverage_output_file, 1, coverage_include) - + _coverage_files, coverage = start_coverage_support_from_params(None, coverage_output_file, 1, coverage_include) files_to_tests = {} for test in tests_to_run: - filename_and_test = test.split('|') + filename_and_test = test.split("|") if len(filename_and_test) == 2: files_to_tests.setdefault(filename_and_test[0], []).append(filename_and_test[1]) configuration = pydev_runfiles.Configuration( - '', + "", verbosity, None, None, None, files_to_tests, - 1, #Always single job here + 1, # Always single job here None, - - #The coverage is handled in this loop. + # The coverage is handled in this loop. coverage_output_file=None, coverage_include=None, ) @@ -185,30 +169,26 @@ def run_client(job_id, port, verbosity, coverage_output_file, coverage_include): coverage.stop() coverage.save() - except: traceback.print_exc() server_comm.notifications_queue.put_nowait(KillServer()) - -#======================================================================================================================= +# ======================================================================================================================= # main -#======================================================================================================================= -if __name__ == '__main__': - if len(sys.argv) -1 == 3: +# ======================================================================================================================= +if __name__ == "__main__": + if len(sys.argv) - 1 == 3: job_id, port, verbosity = sys.argv[1:] coverage_output_file, coverage_include = None, None - elif len(sys.argv) -1 == 5: + elif len(sys.argv) - 1 == 5: job_id, port, verbosity, coverage_output_file, coverage_include = sys.argv[1:] else: - raise AssertionError('Could not find out how to handle the parameters: '+sys.argv[1:]) + raise AssertionError("Could not find out how to handle the parameters: " + sys.argv[1:]) job_id = int(job_id) port = int(port) verbosity = int(verbosity) run_client(job_id, port, verbosity, coverage_output_file, coverage_include) - - diff --git a/_pydev_runfiles/pydev_runfiles_pytest2.py b/_pydev_runfiles/pydev_runfiles_pytest2.py index 793097da7..3cca7a288 100644 --- a/_pydev_runfiles/pydev_runfiles_pytest2.py +++ b/_pydev_runfiles/pydev_runfiles_pytest2.py @@ -9,19 +9,18 @@ import time from pathlib import Path -#========================================================================= +# ========================================================================= # Load filters with tests we should skip -#========================================================================= +# ========================================================================= py_test_accept_filter = None def _load_filters(): global py_test_accept_filter if py_test_accept_filter is None: - py_test_accept_filter = os.environ.get('PYDEV_PYTEST_SKIP') + py_test_accept_filter = os.environ.get("PYDEV_PYTEST_SKIP") if py_test_accept_filter: - py_test_accept_filter = pickle.loads( - zlib.decompress(base64.b64decode(py_test_accept_filter))) + py_test_accept_filter = pickle.loads(zlib.decompress(base64.b64decode(py_test_accept_filter))) # Newer versions of pytest resolve symlinks, so, we # may need to filter with a resolved path too. @@ -36,7 +35,7 @@ def _load_filters(): def is_in_xdist_node(): - main_pid = os.environ.get('PYDEV_MAIN_PID') + main_pid = os.environ.get("PYDEV_MAIN_PID") if main_pid and main_pid != str(os.getpid()): return True return False @@ -51,10 +50,9 @@ def connect_to_server_for_communication_to_xml_rpc_on_xdist(): return connected = True if is_in_xdist_node(): - port = os.environ.get('PYDEV_PYTEST_SERVER') + port = os.environ.get("PYDEV_PYTEST_SERVER") if not port: - sys.stderr.write( - 'Error: no PYDEV_PYTEST_SERVER environment variable defined.\n') + sys.stderr.write("Error: no PYDEV_PYTEST_SERVER environment variable defined.\n") else: pydev_runfiles_xml_rpc.initialize_server(int(port), daemon=True) @@ -73,14 +71,15 @@ def start_redirect(): if State.buf_out is not None: return from _pydevd_bundle import pydevd_io - State.buf_err = pydevd_io.start_redirect(keep_original_redirection=True, std='stderr') - State.buf_out = pydevd_io.start_redirect(keep_original_redirection=True, std='stdout') + + State.buf_err = pydevd_io.start_redirect(keep_original_redirection=True, std="stderr") + State.buf_out = pydevd_io.start_redirect(keep_original_redirection=True, std="stdout") def get_curr_output(): buf_out = State.buf_out buf_err = State.buf_err - return buf_out.getvalue() if buf_out is not None else '', buf_err.getvalue() if buf_err is not None else '' + return buf_out.getvalue() if buf_out is not None else "", buf_err.getvalue() if buf_err is not None else "" def pytest_unconfigure(): @@ -88,8 +87,7 @@ def pytest_unconfigure(): return # Only report that it finished when on the main node (we don't want to report # the finish on each separate node). - pydev_runfiles_xml_rpc.notifyTestRunFinished( - 'Finished in: %.2f secs.' % (time.time() - State.start_time,)) + pydev_runfiles_xml_rpc.notifyTestRunFinished("Finished in: %.2f secs." % (time.time() - State.start_time,)) def pytest_collection_modifyitems(session, config, items): @@ -112,7 +110,7 @@ def pytest_collection_modifyitems(session, config, items): # print('Skip file: %s' % (f,)) continue # Skip the file - i = name.find('[') + i = name.find("[") name_without_parametrize = None if i > 0: name_without_parametrize = name[:i] @@ -138,11 +136,11 @@ def pytest_collection_modifyitems(session, config, items): break if class_name is not None: - if test == class_name + '.' + name: + if test == class_name + "." + name: new_items.append(item) break - if name_without_parametrize is not None and test == class_name + '.' + name_without_parametrize: + if name_without_parametrize is not None and test == class_name + "." + name_without_parametrize: new_items.append(item) break @@ -176,6 +174,7 @@ def _get_error_contents_from_report(report): stringio = tw.stringio except TypeError: import io + stringio = io.StringIO() tw = TerminalWriter(file=stringio) tw.hasmarkup = False @@ -185,13 +184,13 @@ def _get_error_contents_from_report(report): if s: return s - return '' + return "" def pytest_collectreport(report): error_contents = _get_error_contents_from_report(report) if error_contents: - report_test('fail', '', '', '', error_contents, 0.0) + report_test("fail", "", "", "", error_contents, 0.0) def append_strings(s1, s2): @@ -200,10 +199,10 @@ def append_strings(s1, s2): # Prefer str if isinstance(s1, bytes): - s1 = s1.decode('utf-8', 'replace') + s1 = s1.decode("utf-8", "replace") if isinstance(s2, bytes): - s2 = s2.decode('utf-8', 'replace') + s2 = s2.decode("utf-8", "replace") return s1 + s2 @@ -217,70 +216,69 @@ def pytest_runtest_logreport(report): report_when = report.when report_outcome = report.outcome - if hasattr(report, 'wasxfail'): - if report_outcome != 'skipped': - report_outcome = 'passed' + if hasattr(report, "wasxfail"): + if report_outcome != "skipped": + report_outcome = "passed" - if report_outcome == 'passed': + if report_outcome == "passed": # passed on setup/teardown: no need to report if in setup or teardown # (only on the actual test if it passed). - if report_when in ('setup', 'teardown'): + if report_when in ("setup", "teardown"): return - status = 'ok' + status = "ok" - elif report_outcome == 'skipped': - status = 'skip' + elif report_outcome == "skipped": + status = "skip" else: # It has only passed, skipped and failed (no error), so, let's consider # error if not on call. - if report_when in ('setup', 'teardown'): - status = 'error' + if report_when in ("setup", "teardown"): + status = "error" else: # any error in the call (not in setup or teardown) is considered a # regular failure. - status = 'fail' + status = "fail" # This will work if pytest is not capturing it, if it is, nothing will # come from here... - captured_output, error_contents = getattr(report, 'pydev_captured_output', ''), getattr(report, 'pydev_error_contents', '') + captured_output, error_contents = getattr(report, "pydev_captured_output", ""), getattr(report, "pydev_error_contents", "") for type_section, value in report.sections: if value: - if type_section in ('err', 'stderr', 'Captured stderr call'): + if type_section in ("err", "stderr", "Captured stderr call"): error_contents = append_strings(error_contents, value) else: captured_output = append_strings(error_contents, value) - filename = getattr(report, 'pydev_fspath_strpath', '') + filename = getattr(report, "pydev_fspath_strpath", "") test = report.location[2] - if report_outcome != 'skipped': + if report_outcome != "skipped": # On skipped, we'll have a traceback for the skip, which is not what we # want. exc = _get_error_contents_from_report(report) if exc: if error_contents: - error_contents = append_strings(error_contents, '----------------------------- Exceptions -----------------------------\n') + error_contents = append_strings(error_contents, "----------------------------- Exceptions -----------------------------\n") error_contents = append_strings(error_contents, exc) report_test(status, filename, test, captured_output, error_contents, report_duration) def report_test(status, filename, test, captured_output, error_contents, duration): - ''' + """ @param filename: 'D:\\src\\mod1\\hello.py' @param test: 'TestCase.testMet1' @param status: fail, error, ok - ''' - time_str = '%.2f' % (duration,) - pydev_runfiles_xml_rpc.notifyTest( - status, captured_output, error_contents, filename, test, time_str) + """ + time_str = "%.2f" % (duration,) + pydev_runfiles_xml_rpc.notifyTest(status, captured_output, error_contents, filename, test, time_str) -if not hasattr(pytest, 'hookimpl'): - raise AssertionError('Please upgrade pytest (the current version of pytest: %s is unsupported)' % (pytest.__version__,)) +if not hasattr(pytest, "hookimpl"): + raise AssertionError("Please upgrade pytest (the current version of pytest: %s is unsupported)" % (pytest.__version__,)) @pytest.hookimpl(hookwrapper=True) @@ -293,9 +291,9 @@ def pytest_runtest_makereport(item, call): @pytest.mark.tryfirst def pytest_runtest_setup(item): - ''' + """ Note: with xdist will be on a secondary process. - ''' + """ # We have our own redirection: if xdist does its redirection, we'll have # nothing in our contents (which is OK), but if it does, we'll get nothing # from pytest but will get our own here. diff --git a/_pydev_runfiles/pydev_runfiles_unittest.py b/_pydev_runfiles/pydev_runfiles_unittest.py index fff1ef9c6..67f6a259a 100644 --- a/_pydev_runfiles/pydev_runfiles_unittest.py +++ b/_pydev_runfiles/pydev_runfiles_unittest.py @@ -7,11 +7,10 @@ from io import StringIO -#======================================================================================================================= +# ======================================================================================================================= # PydevTextTestRunner -#======================================================================================================================= +# ======================================================================================================================= class PydevTextTestRunner(python_unittest.TextTestRunner): - def _makeResult(self): return PydevTestResult(self.stream, self.descriptions, self.verbosity) @@ -19,11 +18,10 @@ def _makeResult(self): _PythonTextTestResult = python_unittest.TextTestRunner()._makeResult().__class__ -#======================================================================================================================= +# ======================================================================================================================= # PydevTestResult -#======================================================================================================================= +# ======================================================================================================================= class PydevTestResult(_PythonTextTestResult): - def addSubTest(self, test, subtest, err): """Called at the end of a subtest. 'err' is None if the subtest ended successfully, otherwise it's a @@ -33,11 +31,11 @@ def addSubTest(self, test, subtest, err): if err is not None: subdesc = subtest._subDescription() error = (test, self._exc_info_to_string(err, test)) - self._reportErrors([error], [], '', '%s %s' % (self.get_test_name(test), subdesc)) + self._reportErrors([error], [], "", "%s %s" % (self.get_test_name(test), subdesc)) def startTest(self, test): _PythonTextTestResult.startTest(self, test) - self.buf = pydevd_io.start_redirect(keep_original_redirection=True, std='both') + self.buf = pydevd_io.start_redirect(keep_original_redirection=True, std="both") self.start_time = time.time() self._current_errors_stack = [] self._current_failures_stack = [] @@ -48,8 +46,7 @@ def startTest(self, test): # Support for jython 2.1 (__testMethodName is pseudo-private in the test case) test_name = test.__class__.__name__ + "." + test._TestCase__testMethodName - pydev_runfiles_xml_rpc.notifyStartTest( - test.__pydev_pyfile__, test_name) + pydev_runfiles_xml_rpc.notifyStartTest(test.__pydev_pyfile__, test_name) def get_test_name(self, test): try: @@ -61,40 +58,38 @@ def get_test_name(self, test): test_name = test.__class__.__name__ + "." + test._TestCase__testMethodName # Support for class/module exceptions (test is instance of _ErrorHolder) except: - test_name = test.description.split()[1][1:-1] + ' <' + test.description.split()[0] + '>' + test_name = test.description.split()[1][1:-1] + " <" + test.description.split()[0] + ">" except: traceback.print_exc() - return '' + return "" return test_name def stopTest(self, test): end_time = time.time() - pydevd_io.end_redirect(std='both') + pydevd_io.end_redirect(std="both") _PythonTextTestResult.stopTest(self, test) captured_output = self.buf.getvalue() del self.buf - error_contents = '' + error_contents = "" test_name = self.get_test_name(test) - diff_time = '%.2f' % (end_time - self.start_time) + diff_time = "%.2f" % (end_time - self.start_time) skipped = False - outcome = getattr(test, '_outcome', None) + outcome = getattr(test, "_outcome", None) if outcome is not None: - skipped = bool(getattr(outcome, 'skipped', None)) + skipped = bool(getattr(outcome, "skipped", None)) if skipped: - pydev_runfiles_xml_rpc.notifyTest( - 'skip', captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) + pydev_runfiles_xml_rpc.notifyTest("skip", captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) elif not self._current_errors_stack and not self._current_failures_stack: - pydev_runfiles_xml_rpc.notifyTest( - 'ok', captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) + pydev_runfiles_xml_rpc.notifyTest("ok", captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) else: self._reportErrors(self._current_errors_stack, self._current_failures_stack, captured_output, test_name) - def _reportErrors(self, errors, failures, captured_output, test_name, diff_time=''): + def _reportErrors(self, errors, failures, captured_output, test_name, diff_time=""): error_contents = [] for test, s in errors + failures: if type(s) == type((1,)): # If it's a tuple (for jython 2.1) @@ -103,45 +98,41 @@ def _reportErrors(self, errors, failures, captured_output, test_name, diff_time= s = sio.getvalue() error_contents.append(s) - sep = '\n' + self.separator1 + sep = "\n" + self.separator1 error_contents = sep.join(error_contents) if errors and not failures: try: - pydev_runfiles_xml_rpc.notifyTest( - 'error', captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) + pydev_runfiles_xml_rpc.notifyTest("error", captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) except: file_start = error_contents.find('File "') file_end = error_contents.find('", ', file_start) if file_start != -1 and file_end != -1: - file = error_contents[file_start + 6:file_end] + file = error_contents[file_start + 6 : file_end] else: - file = '' - pydev_runfiles_xml_rpc.notifyTest( - 'error', captured_output, error_contents, file, test_name, diff_time) + file = "" + pydev_runfiles_xml_rpc.notifyTest("error", captured_output, error_contents, file, test_name, diff_time) elif failures and not errors: - pydev_runfiles_xml_rpc.notifyTest( - 'fail', captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) + pydev_runfiles_xml_rpc.notifyTest("fail", captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) else: # Ok, we got both, errors and failures. Let's mark it as an error in the end. - pydev_runfiles_xml_rpc.notifyTest( - 'error', captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) + pydev_runfiles_xml_rpc.notifyTest("error", captured_output, error_contents, test.__pydev_pyfile__, test_name, diff_time) def addError(self, test, err): _PythonTextTestResult.addError(self, test, err) # Support for class/module exceptions (test is instance of _ErrorHolder) - if not hasattr(self, '_current_errors_stack') or test.__class__.__name__ == '_ErrorHolder': + if not hasattr(self, "_current_errors_stack") or test.__class__.__name__ == "_ErrorHolder": # Not in start...end, so, report error now (i.e.: django pre/post-setup) - self._reportErrors([self.errors[-1]], [], '', self.get_test_name(test)) + self._reportErrors([self.errors[-1]], [], "", self.get_test_name(test)) else: self._current_errors_stack.append(self.errors[-1]) def addFailure(self, test, err): _PythonTextTestResult.addFailure(self, test, err) - if not hasattr(self, '_current_failures_stack'): + if not hasattr(self, "_current_failures_stack"): # Not in start...end, so, report error now (i.e.: django pre/post-setup) - self._reportErrors([], [self.failures[-1]], '', self.get_test_name(test)) + self._reportErrors([], [self.failures[-1]], "", self.get_test_name(test)) else: self._current_failures_stack.append(self.failures[-1]) diff --git a/_pydev_runfiles/pydev_runfiles_xml_rpc.py b/_pydev_runfiles/pydev_runfiles_xml_rpc.py index ea44140e2..a34472ee9 100644 --- a/_pydev_runfiles/pydev_runfiles_xml_rpc.py +++ b/_pydev_runfiles/pydev_runfiles_xml_rpc.py @@ -11,34 +11,33 @@ # This may happen in IronPython (in Python it shouldn't happen as there are # 'fast' replacements that are used in xmlrpclib.py) -warnings.filterwarnings( - 'ignore', 'The xmllib module is obsolete.*', DeprecationWarning) +warnings.filterwarnings("ignore", "The xmllib module is obsolete.*", DeprecationWarning) file_system_encoding = getfilesystemencoding() -#======================================================================================================================= +# ======================================================================================================================= # _ServerHolder -#======================================================================================================================= +# ======================================================================================================================= class _ServerHolder: - ''' + """ Helper so that we don't have to use a global here. - ''' + """ + SERVER = None -#======================================================================================================================= +# ======================================================================================================================= # set_server -#======================================================================================================================= +# ======================================================================================================================= def set_server(server): _ServerHolder.SERVER = server -#======================================================================================================================= +# ======================================================================================================================= # ParallelNotification -#======================================================================================================================= +# ======================================================================================================================= class ParallelNotification(object): - def __init__(self, method, args): self.method = method self.args = args @@ -47,46 +46,44 @@ def to_tuple(self): return self.method, self.args -#======================================================================================================================= +# ======================================================================================================================= # KillServer -#======================================================================================================================= +# ======================================================================================================================= class KillServer(object): pass -#======================================================================================================================= +# ======================================================================================================================= # ServerFacade -#======================================================================================================================= +# ======================================================================================================================= class ServerFacade(object): - def __init__(self, notifications_queue): self.notifications_queue = notifications_queue def notifyTestsCollected(self, *args): - self.notifications_queue.put_nowait(ParallelNotification('notifyTestsCollected', args)) + self.notifications_queue.put_nowait(ParallelNotification("notifyTestsCollected", args)) def notifyConnected(self, *args): - self.notifications_queue.put_nowait(ParallelNotification('notifyConnected', args)) + self.notifications_queue.put_nowait(ParallelNotification("notifyConnected", args)) def notifyTestRunFinished(self, *args): - self.notifications_queue.put_nowait(ParallelNotification('notifyTestRunFinished', args)) + self.notifications_queue.put_nowait(ParallelNotification("notifyTestRunFinished", args)) def notifyStartTest(self, *args): - self.notifications_queue.put_nowait(ParallelNotification('notifyStartTest', args)) + self.notifications_queue.put_nowait(ParallelNotification("notifyStartTest", args)) def notifyTest(self, *args): new_args = [] for arg in args: new_args.append(_encode_if_needed(arg)) args = tuple(new_args) - self.notifications_queue.put_nowait(ParallelNotification('notifyTest', args)) + self.notifications_queue.put_nowait(ParallelNotification("notifyTest", args)) -#======================================================================================================================= +# ======================================================================================================================= # ServerComm -#======================================================================================================================= +# ======================================================================================================================= class ServerComm(threading.Thread): - def __init__(self, notifications_queue, port, daemon=False): # If daemon is False, wait for all the notifications to be passed before exiting! threading.Thread.__init__(self, daemon=daemon) @@ -111,8 +108,7 @@ def __init__(self, notifications_queue, port, daemon=False): # ISO-8859-1 is good enough. encoding = "ISO-8859-1" - self.server = xmlrpclib.Server('http://%s:%s' % (pydev_localhost.get_localhost(), port), - encoding=encoding) + self.server = xmlrpclib.Server("http://%s:%s" % (pydev_localhost.get_localhost(), port), encoding=encoding) def run(self): while True: @@ -147,9 +143,9 @@ def run(self): return -#======================================================================================================================= +# ======================================================================================================================= # initialize_server -#======================================================================================================================= +# ======================================================================================================================= def initialize_server(port, daemon=False): if _ServerHolder.SERVER is None: if port is not None: @@ -168,9 +164,9 @@ def initialize_server(port, daemon=False): traceback.print_exc() -#======================================================================================================================= +# ======================================================================================================================= # notifyTest -#======================================================================================================================= +# ======================================================================================================================= def notifyTestsCollected(tests_count): assert tests_count is not None try: @@ -179,17 +175,17 @@ def notifyTestsCollected(tests_count): traceback.print_exc() -#======================================================================================================================= +# ======================================================================================================================= # notifyStartTest -#======================================================================================================================= +# ======================================================================================================================= def notifyStartTest(file, test): - ''' + """ @param file: the tests file (c:/temp/test.py) @param test: the test ran (i.e.: TestCase.test1) - ''' + """ assert file is not None if test is None: - test = '' # Could happen if we have an import error importing module. + test = "" # Could happen if we have an import error importing module. try: _ServerHolder.SERVER.notifyStartTest(file, test) @@ -200,35 +196,35 @@ def notifyStartTest(file, test): def _encode_if_needed(obj): # In the java side we expect strings to be ISO-8859-1 (org.python.pydev.debug.pyunit.PyUnitServer.initializeDispatches().new Dispatch() {...}.getAsStr(Object)) if isinstance(obj, str): # Unicode in py3 - return xmlrpclib.Binary(obj.encode('ISO-8859-1', 'xmlcharrefreplace')) + return xmlrpclib.Binary(obj.encode("ISO-8859-1", "xmlcharrefreplace")) elif isinstance(obj, bytes): try: - return xmlrpclib.Binary(obj.decode(sys.stdin.encoding).encode('ISO-8859-1', 'xmlcharrefreplace')) + return xmlrpclib.Binary(obj.decode(sys.stdin.encoding).encode("ISO-8859-1", "xmlcharrefreplace")) except: return xmlrpclib.Binary(obj) # bytes already return obj -#======================================================================================================================= +# ======================================================================================================================= # notifyTest -#======================================================================================================================= +# ======================================================================================================================= def notifyTest(cond, captured_output, error_contents, file, test, time): - ''' + """ @param cond: ok, fail, error @param captured_output: output captured from stdout @param captured_output: output captured from stderr @param file: the tests file (c:/temp/test.py) @param test: the test ran (i.e.: TestCase.test1) @param time: float with the number of seconds elapsed - ''' + """ assert cond is not None assert captured_output is not None assert error_contents is not None assert file is not None if test is None: - test = '' # Could happen if we have an import error importing module. + test = "" # Could happen if we have an import error importing module. assert time is not None try: captured_output = _encode_if_needed(captured_output) @@ -239,9 +235,9 @@ def notifyTest(cond, captured_output, error_contents, file, test, time): traceback.print_exc() -#======================================================================================================================= +# ======================================================================================================================= # notifyTestRunFinished -#======================================================================================================================= +# ======================================================================================================================= def notifyTestRunFinished(total_time): assert total_time is not None try: @@ -250,8 +246,8 @@ def notifyTestRunFinished(total_time): traceback.print_exc() -#======================================================================================================================= +# ======================================================================================================================= # force_server_kill -#======================================================================================================================= +# ======================================================================================================================= def force_server_kill(): _ServerHolder.SERVER_COMM.notifications_queue.put_nowait(KillServer()) diff --git a/_pydevd_bundle/_debug_adapter/__main__pydevd_gen_debug_adapter_protocol.py b/_pydevd_bundle/_debug_adapter/__main__pydevd_gen_debug_adapter_protocol.py index d24db7520..e2672a3e9 100644 --- a/_pydevd_bundle/_debug_adapter/__main__pydevd_gen_debug_adapter_protocol.py +++ b/_pydevd_bundle/_debug_adapter/__main__pydevd_gen_debug_adapter_protocol.py @@ -1,20 +1,20 @@ -''' +""" Run this module to regenerate the `pydevd_schema.py` file. Note that it'll generate it based on the current debugProtocol.json. Erase it and rerun to download the latest version. -''' +""" def is_variable_to_translate(cls_name, var_name): - if var_name in ('variablesReference', 'frameId', 'threadId'): + if var_name in ("variablesReference", "frameId", "threadId"): return True - if cls_name == 'StackFrame' and var_name == 'id': + if cls_name == "StackFrame" and var_name == "id": # It's frameId everywhere except on StackFrame. return True - if cls_name == 'Thread' and var_name == 'id': + if cls_name == "Thread" and var_name == "id": # It's threadId everywhere except on Thread. return True @@ -22,7 +22,7 @@ def is_variable_to_translate(cls_name, var_name): def _get_noqa_for_var(prop_name): - return ' # noqa (assign to builtin)' if prop_name in ('type', 'format', 'id', 'hex', 'breakpoint', 'filter') else '' + return " # noqa (assign to builtin)" if prop_name in ("type", "format", "id", "hex", "breakpoint", "filter") else "" class _OrderedSet(object): @@ -63,14 +63,13 @@ def __len__(self): def set_repr(self): if len(self) == 0: - return 'set()' + return "set()" lst = [repr(x) for x in self] - return 'set([' + ', '.join(lst) + '])' + return "set([" + ", ".join(lst) + "])" class Ref(object): - def __init__(self, ref, ref_data): self.ref = ref self.ref_data = ref_data @@ -83,15 +82,16 @@ def load_schema_data(): import os.path import json - json_file = os.path.join(os.path.dirname(__file__), 'debugProtocol.json') + json_file = os.path.join(os.path.dirname(__file__), "debugProtocol.json") if not os.path.exists(json_file): import requests - req = requests.get('https://raw.githubusercontent.com/microsoft/debug-adapter-protocol/gh-pages/debugAdapterProtocol.json') + + req = requests.get("https://raw.githubusercontent.com/microsoft/debug-adapter-protocol/gh-pages/debugAdapterProtocol.json") assert req.status_code == 200 - with open(json_file, 'wb') as stream: + with open(json_file, "wb") as stream: stream.write(req.content) - with open(json_file, 'rb') as json_contents: + with open(json_file, "rb") as json_contents: json_schema_data = json.loads(json_contents.read()) return json_schema_data @@ -100,48 +100,48 @@ def load_custom_schema_data(): import os.path import json - json_file = os.path.join(os.path.dirname(__file__), 'debugProtocolCustom.json') + json_file = os.path.join(os.path.dirname(__file__), "debugProtocolCustom.json") - with open(json_file, 'rb') as json_contents: + with open(json_file, "rb") as json_contents: json_schema_data = json.loads(json_contents.read()) return json_schema_data def create_classes_to_generate_structure(json_schema_data): - definitions = json_schema_data['definitions'] + definitions = json_schema_data["definitions"] class_to_generatees = {} for name, definition in definitions.items(): - all_of = definition.get('allOf') - description = definition.get('description') - is_enum = definition.get('type') == 'string' and 'enum' in definition + all_of = definition.get("allOf") + description = definition.get("description") + is_enum = definition.get("type") == "string" and "enum" in definition enum_values = None if is_enum: - enum_values = definition['enum'] + enum_values = definition["enum"] properties = {} - properties.update(definition.get('properties', {})) - required = _OrderedSet(definition.get('required', _OrderedSet())) + properties.update(definition.get("properties", {})) + required = _OrderedSet(definition.get("required", _OrderedSet())) base_definitions = [] if all_of is not None: for definition in all_of: - ref = definition.get('$ref') + ref = definition.get("$ref") if ref is not None: - assert ref.startswith('#/definitions/') - ref = ref[len('#/definitions/'):] + assert ref.startswith("#/definitions/") + ref = ref[len("#/definitions/") :] base_definitions.append(ref) else: if not description: - description = definition.get('description') - properties.update(definition.get('properties', {})) - required.update(_OrderedSet(definition.get('required', _OrderedSet()))) + description = definition.get("description") + properties.update(definition.get("properties", {})) + required.update(_OrderedSet(definition.get("required", _OrderedSet()))) if isinstance(description, (list, tuple)): - description = '\n'.join(description) + description = "\n".join(description) - if name == 'ModulesRequest': # Hack to accept modules request without arguments (ptvsd: 2050). - required.discard('arguments') + if name == "ModulesRequest": # Hack to accept modules request without arguments (ptvsd: 2050). + required.discard("arguments") class_to_generatees[name] = dict( name=name, properties=properties, @@ -149,7 +149,7 @@ def create_classes_to_generate_structure(json_schema_data): description=description, required=required, is_enum=is_enum, - enum_values=enum_values + enum_values=enum_values, ) return class_to_generatees @@ -159,7 +159,7 @@ def collect_bases(curr_class, classes_to_generate, memo=None): if memo is None: memo = {} - base_definitions = curr_class['base_definitions'] + base_definitions = curr_class["base_definitions"] for base_definition in base_definitions: if base_definition not in memo: ret.append(base_definition) @@ -177,86 +177,87 @@ def fill_properties_and_required_from_base(classes_to_generate): for base_definition in reversed(collect_bases(class_to_generate, classes_to_generate)): # Note: go from base to current so that the initial order of the properties has that # same order. - dct.update(classes_to_generate[base_definition].get('properties', {})) - s.update(classes_to_generate[base_definition].get('required', _OrderedSet())) + dct.update(classes_to_generate[base_definition].get("properties", {})) + s.update(classes_to_generate[base_definition].get("required", _OrderedSet())) - dct.update(class_to_generate['properties']) - class_to_generate['properties'] = dct + dct.update(class_to_generate["properties"]) + class_to_generate["properties"] = dct - s.update(class_to_generate['required']) - class_to_generate['required'] = s + s.update(class_to_generate["required"]) + class_to_generate["required"] = s return class_to_generate def update_class_to_generate_description(class_to_generate): import textwrap - description = class_to_generate['description'] + + description = class_to_generate["description"] lines = [] for line in description.splitlines(): wrapped = textwrap.wrap(line.strip(), 100) lines.extend(wrapped) - lines.append('') + lines.append("") - while lines and lines[-1] == '': + while lines and lines[-1] == "": lines = lines[:-1] - class_to_generate['description'] = ' ' + ('\n '.join(lines)) + class_to_generate["description"] = " " + ("\n ".join(lines)) def update_class_to_generate_type(classes_to_generate, class_to_generate): - properties = class_to_generate.get('properties') + properties = class_to_generate.get("properties") for _prop_name, prop_val in properties.items(): - prop_type = prop_val.get('type', '') + prop_type = prop_val.get("type", "") if not prop_type: - prop_type = prop_val.pop('$ref', '') + prop_type = prop_val.pop("$ref", "") if prop_type: - assert prop_type.startswith('#/definitions/') - prop_type = prop_type[len('#/definitions/'):] - prop_val['type'] = Ref(prop_type, classes_to_generate[prop_type]) + assert prop_type.startswith("#/definitions/") + prop_type = prop_type[len("#/definitions/") :] + prop_val["type"] = Ref(prop_type, classes_to_generate[prop_type]) def update_class_to_generate_register_dec(classes_to_generate, class_to_generate): # Default - class_to_generate['register_request'] = '' - class_to_generate['register_dec'] = '@register' + class_to_generate["register_request"] = "" + class_to_generate["register_dec"] = "@register" - properties = class_to_generate.get('properties') - enum_type = properties.get('type', {}).get('enum') + properties = class_to_generate.get("properties") + enum_type = properties.get("type", {}).get("enum") command = None event = None if enum_type and len(enum_type) == 1 and next(iter(enum_type)) in ("request", "response", "event"): msg_type = next(iter(enum_type)) - if msg_type == 'response': + if msg_type == "response": # The actual command is typed in the request - response_name = class_to_generate['name'] - request_name = response_name[:-len('Response')] + 'Request' + response_name = class_to_generate["name"] + request_name = response_name[: -len("Response")] + "Request" if request_name in classes_to_generate: - command = classes_to_generate[request_name]['properties'].get('command') + command = classes_to_generate[request_name]["properties"].get("command") else: - if response_name == 'ErrorResponse': - command = {'enum': ['error']} + if response_name == "ErrorResponse": + command = {"enum": ["error"]} else: - raise AssertionError('Unhandled: %s' % (response_name,)) + raise AssertionError("Unhandled: %s" % (response_name,)) - elif msg_type == 'request': - command = properties.get('command') + elif msg_type == "request": + command = properties.get("command") - elif msg_type == 'event': - command = properties.get('event') + elif msg_type == "event": + command = properties.get("event") else: - raise AssertionError('Unexpected condition.') + raise AssertionError("Unexpected condition.") if command: - enum = command.get('enum') + enum = command.get("enum") if enum and len(enum) == 1: - class_to_generate['register_request'] = '@register_%s(%r)\n' % (msg_type, enum[0]) + class_to_generate["register_request"] = "@register_%s(%r)\n" % (msg_type, enum[0]) def extract_prop_name_and_prop(class_to_generate): - properties = class_to_generate.get('properties') - required = _OrderedSet(class_to_generate.get('required', _OrderedSet())) + properties = class_to_generate.get("properties") + required = _OrderedSet(class_to_generate.get("required", _OrderedSet())) # Sort so that required come first prop_name_and_prop = list(properties.items()) @@ -264,7 +265,7 @@ def extract_prop_name_and_prop(class_to_generate): def compute_sort_key(x): key = x[0] if key in required: - if key == 'seq': + if key == "seq": return 0.5 # seq when required is after the other required keys (to have a default of -1). return 0 return 1 @@ -275,98 +276,104 @@ def compute_sort_key(x): def update_class_to_generate_to_json(class_to_generate): - required = _OrderedSet(class_to_generate.get('required', _OrderedSet())) + required = _OrderedSet(class_to_generate.get("required", _OrderedSet())) prop_name_and_prop = extract_prop_name_and_prop(class_to_generate) - to_dict_body = ['def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused)'] + to_dict_body = ["def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused)"] translate_prop_names = [] for prop_name, prop in prop_name_and_prop: - if is_variable_to_translate(class_to_generate['name'], prop_name): + if is_variable_to_translate(class_to_generate["name"], prop_name): translate_prop_names.append(prop_name) for prop_name, prop in prop_name_and_prop: namespace = dict(prop_name=prop_name, noqa=_get_noqa_for_var(prop_name)) - to_dict_body.append(' %(prop_name)s = self.%(prop_name)s%(noqa)s' % namespace) + to_dict_body.append(" %(prop_name)s = self.%(prop_name)s%(noqa)s" % namespace) - if prop.get('type') == 'array': + if prop.get("type") == "array": to_dict_body.append(' if %(prop_name)s and hasattr(%(prop_name)s[0], "to_dict"):' % namespace) - to_dict_body.append(' %(prop_name)s = [x.to_dict() for x in %(prop_name)s]' % namespace) + to_dict_body.append(" %(prop_name)s = [x.to_dict() for x in %(prop_name)s]" % namespace) if translate_prop_names: - to_dict_body.append(' if update_ids_to_dap:') + to_dict_body.append(" if update_ids_to_dap:") for prop_name in translate_prop_names: namespace = dict(prop_name=prop_name, noqa=_get_noqa_for_var(prop_name)) - to_dict_body.append(' if %(prop_name)s is not None:' % namespace) - to_dict_body.append(' %(prop_name)s = self._translate_id_to_dap(%(prop_name)s)%(noqa)s' % namespace) + to_dict_body.append(" if %(prop_name)s is not None:" % namespace) + to_dict_body.append(" %(prop_name)s = self._translate_id_to_dap(%(prop_name)s)%(noqa)s" % namespace) if not translate_prop_names: update_dict_ids_from_dap_body = [] else: - update_dict_ids_from_dap_body = ['', '', '@classmethod', 'def update_dict_ids_from_dap(cls, dct):'] + update_dict_ids_from_dap_body = ["", "", "@classmethod", "def update_dict_ids_from_dap(cls, dct):"] for prop_name in translate_prop_names: namespace = dict(prop_name=prop_name) - update_dict_ids_from_dap_body.append(' if %(prop_name)r in dct:' % namespace) - update_dict_ids_from_dap_body.append(' dct[%(prop_name)r] = cls._translate_id_from_dap(dct[%(prop_name)r])' % namespace) - update_dict_ids_from_dap_body.append(' return dct') + update_dict_ids_from_dap_body.append(" if %(prop_name)r in dct:" % namespace) + update_dict_ids_from_dap_body.append(" dct[%(prop_name)r] = cls._translate_id_from_dap(dct[%(prop_name)r])" % namespace) + update_dict_ids_from_dap_body.append(" return dct") - class_to_generate['update_dict_ids_from_dap'] = _indent_lines('\n'.join(update_dict_ids_from_dap_body)) + class_to_generate["update_dict_ids_from_dap"] = _indent_lines("\n".join(update_dict_ids_from_dap_body)) - to_dict_body.append(' dct = {') + to_dict_body.append(" dct = {") first_not_required = False for prop_name, prop in prop_name_and_prop: - use_to_dict = prop['type'].__class__ == Ref and not prop['type'].ref_data.get('is_enum', False) - is_array = prop['type'] == 'array' - ref_array_cls_name = '' + use_to_dict = prop["type"].__class__ == Ref and not prop["type"].ref_data.get("is_enum", False) + is_array = prop["type"] == "array" + ref_array_cls_name = "" if is_array: - ref = prop['items'].get('$ref') + ref = prop["items"].get("$ref") if ref is not None: - ref_array_cls_name = ref.split('/')[-1] + ref_array_cls_name = ref.split("/")[-1] namespace = dict(prop_name=prop_name, ref_array_cls_name=ref_array_cls_name) if prop_name in required: if use_to_dict: - to_dict_body.append(' %(prop_name)r: %(prop_name)s.to_dict(update_ids_to_dap=update_ids_to_dap),' % namespace) + to_dict_body.append(" %(prop_name)r: %(prop_name)s.to_dict(update_ids_to_dap=update_ids_to_dap)," % namespace) else: if ref_array_cls_name: - to_dict_body.append(' %(prop_name)r: [%(ref_array_cls_name)s.update_dict_ids_to_dap(o) for o in %(prop_name)s] if (update_ids_to_dap and %(prop_name)s) else %(prop_name)s,' % namespace) + to_dict_body.append( + " %(prop_name)r: [%(ref_array_cls_name)s.update_dict_ids_to_dap(o) for o in %(prop_name)s] if (update_ids_to_dap and %(prop_name)s) else %(prop_name)s," + % namespace + ) else: - to_dict_body.append(' %(prop_name)r: %(prop_name)s,' % namespace) + to_dict_body.append(" %(prop_name)r: %(prop_name)s," % namespace) else: if not first_not_required: first_not_required = True - to_dict_body.append(' }') + to_dict_body.append(" }") - to_dict_body.append(' if %(prop_name)s is not None:' % namespace) + to_dict_body.append(" if %(prop_name)s is not None:" % namespace) if use_to_dict: - to_dict_body.append(' dct[%(prop_name)r] = %(prop_name)s.to_dict(update_ids_to_dap=update_ids_to_dap)' % namespace) + to_dict_body.append(" dct[%(prop_name)r] = %(prop_name)s.to_dict(update_ids_to_dap=update_ids_to_dap)" % namespace) else: if ref_array_cls_name: - to_dict_body.append(' dct[%(prop_name)r] = [%(ref_array_cls_name)s.update_dict_ids_to_dap(o) for o in %(prop_name)s] if (update_ids_to_dap and %(prop_name)s) else %(prop_name)s' % namespace) + to_dict_body.append( + " dct[%(prop_name)r] = [%(ref_array_cls_name)s.update_dict_ids_to_dap(o) for o in %(prop_name)s] if (update_ids_to_dap and %(prop_name)s) else %(prop_name)s" + % namespace + ) else: - to_dict_body.append(' dct[%(prop_name)r] = %(prop_name)s' % namespace) + to_dict_body.append(" dct[%(prop_name)r] = %(prop_name)s" % namespace) if not first_not_required: first_not_required = True - to_dict_body.append(' }') + to_dict_body.append(" }") - to_dict_body.append(' dct.update(self.kwargs)') - to_dict_body.append(' return dct') + to_dict_body.append(" dct.update(self.kwargs)") + to_dict_body.append(" return dct") - class_to_generate['to_dict'] = _indent_lines('\n'.join(to_dict_body)) + class_to_generate["to_dict"] = _indent_lines("\n".join(to_dict_body)) if not translate_prop_names: update_dict_ids_to_dap_body = [] else: - update_dict_ids_to_dap_body = ['', '', '@classmethod', 'def update_dict_ids_to_dap(cls, dct):'] + update_dict_ids_to_dap_body = ["", "", "@classmethod", "def update_dict_ids_to_dap(cls, dct):"] for prop_name in translate_prop_names: namespace = dict(prop_name=prop_name) - update_dict_ids_to_dap_body.append(' if %(prop_name)r in dct:' % namespace) - update_dict_ids_to_dap_body.append(' dct[%(prop_name)r] = cls._translate_id_to_dap(dct[%(prop_name)r])' % namespace) - update_dict_ids_to_dap_body.append(' return dct') + update_dict_ids_to_dap_body.append(" if %(prop_name)r in dct:" % namespace) + update_dict_ids_to_dap_body.append(" dct[%(prop_name)r] = cls._translate_id_to_dap(dct[%(prop_name)r])" % namespace) + update_dict_ids_to_dap_body.append(" return dct") - class_to_generate['update_dict_ids_to_dap'] = _indent_lines('\n'.join(update_dict_ids_to_dap_body)) + class_to_generate["update_dict_ids_to_dap"] = _indent_lines("\n".join(update_dict_ids_to_dap_body)) def update_class_to_generate_init(class_to_generate): @@ -374,82 +381,86 @@ def update_class_to_generate_init(class_to_generate): init_body = [] docstring = [] - required = _OrderedSet(class_to_generate.get('required', _OrderedSet())) + required = _OrderedSet(class_to_generate.get("required", _OrderedSet())) prop_name_and_prop = extract_prop_name_and_prop(class_to_generate) translate_prop_names = [] for prop_name, prop in prop_name_and_prop: - if is_variable_to_translate(class_to_generate['name'], prop_name): + if is_variable_to_translate(class_to_generate["name"], prop_name): translate_prop_names.append(prop_name) - enum = prop.get('enum') + enum = prop.get("enum") if enum and len(enum) == 1: - init_body.append(' self.%(prop_name)s = %(enum)r' % dict(prop_name=prop_name, enum=next(iter(enum)))) + init_body.append(" self.%(prop_name)s = %(enum)r" % dict(prop_name=prop_name, enum=next(iter(enum)))) else: if prop_name in required: - if prop_name == 'seq': - args.append(prop_name + '=-1') + if prop_name == "seq": + args.append(prop_name + "=-1") else: args.append(prop_name) else: - args.append(prop_name + '=None') + args.append(prop_name + "=None") - if prop['type'].__class__ == Ref: - ref = prop['type'] + if prop["type"].__class__ == Ref: + ref = prop["type"] ref_data = ref.ref_data - if ref_data.get('is_enum', False): - init_body.append(' if %s is not None:' % (prop_name,)) - init_body.append(' assert %s in %s.VALID_VALUES' % (prop_name, str(ref))) - init_body.append(' self.%(prop_name)s = %(prop_name)s' % dict( - prop_name=prop_name)) + if ref_data.get("is_enum", False): + init_body.append(" if %s is not None:" % (prop_name,)) + init_body.append(" assert %s in %s.VALID_VALUES" % (prop_name, str(ref))) + init_body.append(" self.%(prop_name)s = %(prop_name)s" % dict(prop_name=prop_name)) else: - namespace = dict( - prop_name=prop_name, - ref_name=str(ref) - ) - init_body.append(' if %(prop_name)s is None:' % namespace) - init_body.append(' self.%(prop_name)s = %(ref_name)s()' % namespace) - init_body.append(' else:') - init_body.append(' self.%(prop_name)s = %(ref_name)s(update_ids_from_dap=update_ids_from_dap, **%(prop_name)s) if %(prop_name)s.__class__ != %(ref_name)s else %(prop_name)s' % namespace + namespace = dict(prop_name=prop_name, ref_name=str(ref)) + init_body.append(" if %(prop_name)s is None:" % namespace) + init_body.append(" self.%(prop_name)s = %(ref_name)s()" % namespace) + init_body.append(" else:") + init_body.append( + " self.%(prop_name)s = %(ref_name)s(update_ids_from_dap=update_ids_from_dap, **%(prop_name)s) if %(prop_name)s.__class__ != %(ref_name)s else %(prop_name)s" + % namespace ) else: - init_body.append(' self.%(prop_name)s = %(prop_name)s' % dict(prop_name=prop_name)) + init_body.append(" self.%(prop_name)s = %(prop_name)s" % dict(prop_name=prop_name)) - if prop['type'] == 'array': - ref = prop['items'].get('$ref') + if prop["type"] == "array": + ref = prop["items"].get("$ref") if ref is not None: - ref_array_cls_name = ref.split('/')[-1] - init_body.append(' if update_ids_from_dap and self.%(prop_name)s:' % dict(prop_name=prop_name)) - init_body.append(' for o in self.%(prop_name)s:' % dict(prop_name=prop_name)) - init_body.append(' %(ref_array_cls_name)s.update_dict_ids_from_dap(o)' % dict(ref_array_cls_name=ref_array_cls_name)) + ref_array_cls_name = ref.split("/")[-1] + init_body.append(" if update_ids_from_dap and self.%(prop_name)s:" % dict(prop_name=prop_name)) + init_body.append(" for o in self.%(prop_name)s:" % dict(prop_name=prop_name)) + init_body.append( + " %(ref_array_cls_name)s.update_dict_ids_from_dap(o)" % dict(ref_array_cls_name=ref_array_cls_name) + ) - prop_type = prop['type'] - prop_description = prop.get('description', '') + prop_type = prop["type"] + prop_description = prop.get("description", "") if isinstance(prop_description, (list, tuple)): - prop_description = '\n '.join(prop_description) + prop_description = "\n ".join(prop_description) - docstring.append(':param %(prop_type)s %(prop_name)s: %(prop_description)s' % dict( - prop_type=prop_type, prop_name=prop_name, prop_description=prop_description)) + docstring.append( + ":param %(prop_type)s %(prop_name)s: %(prop_description)s" + % dict(prop_type=prop_type, prop_name=prop_name, prop_description=prop_description) + ) if translate_prop_names: - init_body.append(' if update_ids_from_dap:') + init_body.append(" if update_ids_from_dap:") for prop_name in translate_prop_names: - init_body.append(' self.%(prop_name)s = self._translate_id_from_dap(self.%(prop_name)s)' % dict(prop_name=prop_name)) + init_body.append(" self.%(prop_name)s = self._translate_id_from_dap(self.%(prop_name)s)" % dict(prop_name=prop_name)) - docstring = _indent_lines('\n'.join(docstring)) - init_body = '\n'.join(init_body) + docstring = _indent_lines("\n".join(docstring)) + init_body = "\n".join(init_body) # Actually bundle the whole __init__ from the parts. - args = ', '.join(args) + args = ", ".join(args) if args: - args = ', ' + args + args = ", " + args # Note: added kwargs because some messages are expected to be extended by the user (so, we'll actually # make all extendable so that we don't have to worry about which ones -- we loose a little on typing, # but may be better than doing a allow list based on something only pointed out in the documentation). - class_to_generate['init'] = '''def __init__(self%(args)s, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + class_to_generate[ + "init" + ] = '''def __init__(self%(args)s, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ %(docstring)s """ @@ -457,7 +468,7 @@ def update_class_to_generate_init(class_to_generate): self.kwargs = kwargs ''' % dict(args=args, init_body=init_body, docstring=docstring) - class_to_generate['init'] = _indent_lines(class_to_generate['init']) + class_to_generate["init"] = _indent_lines(class_to_generate["init"]) def update_class_to_generate_props(class_to_generate): @@ -466,48 +477,52 @@ def update_class_to_generate_props(class_to_generate): def default(o): if isinstance(o, Ref): return o.ref - raise AssertionError('Unhandled: %s' % (o,)) + raise AssertionError("Unhandled: %s" % (o,)) - properties = class_to_generate['properties'] - class_to_generate['props'] = ' __props__ = %s' % _indent_lines( - json.dumps(properties, indent=4, default=default).replace('true', 'True')).strip() + properties = class_to_generate["properties"] + class_to_generate["props"] = ( + " __props__ = %s" % _indent_lines(json.dumps(properties, indent=4, default=default).replace("true", "True")).strip() + ) def update_class_to_generate_refs(class_to_generate): - properties = class_to_generate['properties'] - class_to_generate['refs'] = ' __refs__ = %s' % _OrderedSet( - key for (key, val) in properties.items() if val['type'].__class__ == Ref).set_repr() + properties = class_to_generate["properties"] + class_to_generate["refs"] = ( + " __refs__ = %s" % _OrderedSet(key for (key, val) in properties.items() if val["type"].__class__ == Ref).set_repr() + ) def update_class_to_generate_enums(class_to_generate): - class_to_generate['enums'] = '' - if class_to_generate.get('is_enum', False): - enums = '' - for enum in class_to_generate['enum_values']: - enums += ' %s = %r\n' % (enum.upper(), enum) - enums += '\n' - enums += ' VALID_VALUES = %s\n\n' % _OrderedSet(class_to_generate['enum_values']).set_repr() - class_to_generate['enums'] = enums + class_to_generate["enums"] = "" + if class_to_generate.get("is_enum", False): + enums = "" + for enum in class_to_generate["enum_values"]: + enums += " %s = %r\n" % (enum.upper(), enum) + enums += "\n" + enums += " VALID_VALUES = %s\n\n" % _OrderedSet(class_to_generate["enum_values"]).set_repr() + class_to_generate["enums"] = enums def update_class_to_generate_objects(classes_to_generate, class_to_generate): - properties = class_to_generate['properties'] + properties = class_to_generate["properties"] for key, val in properties.items(): - if 'type' not in val: - val['type'] = 'TypeNA' + if "type" not in val: + val["type"] = "TypeNA" continue - if val['type'] == 'object': + if val["type"] == "object": create_new = val.copy() - create_new.update({ - 'name': '%s%s' % (class_to_generate['name'], key.title()), - 'description': ' "%s" of %s' % (key, class_to_generate['name']) - }) - if 'properties' not in create_new: - create_new['properties'] = {} - - assert create_new['name'] not in classes_to_generate - classes_to_generate[create_new['name']] = create_new + create_new.update( + { + "name": "%s%s" % (class_to_generate["name"], key.title()), + "description": ' "%s" of %s' % (key, class_to_generate["name"]), + } + ) + if "properties" not in create_new: + create_new["properties"] = {} + + assert create_new["name"] not in classes_to_generate + classes_to_generate[create_new["name"]] = create_new update_class_to_generate_type(classes_to_generate, create_new) update_class_to_generate_props(create_new) @@ -515,8 +530,8 @@ def update_class_to_generate_objects(classes_to_generate, class_to_generate): # Update nested object types update_class_to_generate_objects(classes_to_generate, create_new) - val['type'] = Ref(create_new['name'], classes_to_generate[create_new['name']]) - val.pop('properties', None) + val["type"] = Ref(create_new["name"], classes_to_generate[create_new["name"]]) + val.pop("properties", None) def gen_debugger_protocol(): @@ -524,7 +539,7 @@ def gen_debugger_protocol(): import sys if sys.version_info[:2] < (3, 6): - raise AssertionError('Must be run with Python 3.6 onwards (to keep dict order).') + raise AssertionError("Must be run with Python 3.6 onwards (to keep dict order).") classes_to_generate = create_classes_to_generate_structure(load_schema_data()) classes_to_generate.update(create_classes_to_generate_structure(load_custom_schema_data())) @@ -564,29 +579,28 @@ class %(name)s(BaseSchema): ''' contents = [] - contents.append('# coding: utf-8') - contents.append('# Automatically generated code.') - contents.append('# Do not edit manually.') - contents.append('# Generated by running: %s' % os.path.basename(__file__)) - contents.append('from .pydevd_base_schema import BaseSchema, register, register_request, register_response, register_event') - contents.append('') + contents.append("# coding: utf-8") + contents.append("# Automatically generated code.") + contents.append("# Do not edit manually.") + contents.append("# Generated by running: %s" % os.path.basename(__file__)) + contents.append("from .pydevd_base_schema import BaseSchema, register, register_request, register_response, register_event") + contents.append("") for class_to_generate in classes_to_generate.values(): contents.append(class_template % class_to_generate) parent_dir = os.path.dirname(__file__) - schema = os.path.join(parent_dir, 'pydevd_schema.py') - with open(schema, 'w', encoding='utf-8') as stream: - stream.write('\n'.join(contents)) + schema = os.path.join(parent_dir, "pydevd_schema.py") + with open(schema, "w", encoding="utf-8") as stream: + stream.write("\n".join(contents)) -def _indent_lines(lines, indent=' '): +def _indent_lines(lines, indent=" "): out_lines = [] for line in lines.splitlines(keepends=True): out_lines.append(indent + line) - return ''.join(out_lines) - + return "".join(out_lines) -if __name__ == '__main__': +if __name__ == "__main__": gen_debugger_protocol() diff --git a/_pydevd_bundle/_debug_adapter/pydevd_base_schema.py b/_pydevd_bundle/_debug_adapter/pydevd_base_schema.py index 0cbb3f5b3..e5078f0e4 100644 --- a/_pydevd_bundle/_debug_adapter/pydevd_base_schema.py +++ b/_pydevd_bundle/_debug_adapter/pydevd_base_schema.py @@ -5,11 +5,10 @@ class BaseSchema(object): - @staticmethod def initialize_ids_translation(): - BaseSchema._dap_id_to_obj_id = {0:0, None:None} - BaseSchema._obj_id_to_dap_id = {0:0, None:None} + BaseSchema._dap_id_to_obj_id = {0: 0, None: None} + BaseSchema._obj_id_to_dap_id = {0: 0, None: None} BaseSchema._next_dap_id = partial(next, itertools.count(1)) def to_json(self): @@ -17,8 +16,8 @@ def to_json(self): @staticmethod def _translate_id_to_dap(obj_id): - if obj_id == '*': - return '*' + if obj_id == "*": + return "*" # Note: we don't invalidate ids, so, if some object starts using the same id # of another object, the same id will be used. dap_id = BaseSchema._obj_id_to_dap_id.get(obj_id) @@ -29,12 +28,12 @@ def _translate_id_to_dap(obj_id): @staticmethod def _translate_id_from_dap(dap_id): - if dap_id == '*': - return '*' + if dap_id == "*": + return "*" try: return BaseSchema._dap_id_to_obj_id[dap_id] except: - raise KeyError('Wrong ID sent from the client: %s' % (dap_id,)) + raise KeyError("Wrong ID sent from the client: %s" % (dap_id,)) @staticmethod def update_dict_ids_to_dap(dct): @@ -59,7 +58,6 @@ def register(cls): def register_request(command): - def do_register(cls): _requests_to_types[command] = cls return cls @@ -68,7 +66,6 @@ def do_register(cls): def register_response(command): - def do_register(cls): _responses_to_types[command] = cls return cls @@ -77,7 +74,6 @@ def do_register(cls): def register_event(event): - def do_register(cls): _event_to_types[event] = cls return cls @@ -86,45 +82,45 @@ def do_register(cls): def from_dict(dct, update_ids_from_dap=False): - msg_type = dct.get('type') + msg_type = dct.get("type") if msg_type is None: - raise ValueError('Unable to make sense of message: %s' % (dct,)) + raise ValueError("Unable to make sense of message: %s" % (dct,)) - if msg_type == 'request': + if msg_type == "request": to_type = _requests_to_types - use = dct['command'] + use = dct["command"] - elif msg_type == 'response': + elif msg_type == "response": to_type = _responses_to_types - use = dct['command'] + use = dct["command"] else: to_type = _event_to_types - use = dct['event'] + use = dct["event"] cls = to_type.get(use) if cls is None: - raise ValueError('Unable to create message from dict: %s. %s not in %s' % (dct, use, sorted(to_type.keys()))) + raise ValueError("Unable to create message from dict: %s. %s not in %s" % (dct, use, sorted(to_type.keys()))) try: return cls(update_ids_from_dap=update_ids_from_dap, **dct) except: - msg = 'Error creating %s from %s' % (cls, dct) + msg = "Error creating %s from %s" % (cls, dct) debug_exception(msg) raise -def from_json(json_msg, update_ids_from_dap=False, on_dict_loaded=lambda dct:None): +def from_json(json_msg, update_ids_from_dap=False, on_dict_loaded=lambda dct: None): if isinstance(json_msg, bytes): - json_msg = json_msg.decode('utf-8') + json_msg = json_msg.decode("utf-8") as_dict = json.loads(json_msg) on_dict_loaded(as_dict) try: return from_dict(as_dict, update_ids_from_dap=update_ids_from_dap) except: - if as_dict.get('type') == 'response' and not as_dict.get('success'): + if as_dict.get("type") == "response" and not as_dict.get("success"): # Error messages may not have required body (return as a generic Response). - Response = _all_messages['Response'] + Response = _all_messages["Response"] return Response(**as_dict) else: raise @@ -132,16 +128,16 @@ def from_json(json_msg, update_ids_from_dap=False, on_dict_loaded=lambda dct:Non def get_response_class(request): if request.__class__ == dict: - return _responses_to_types[request['command']] + return _responses_to_types[request["command"]] return _responses_to_types[request.command] def build_response(request, kwargs=None): if kwargs is None: - kwargs = {'success':True} + kwargs = {"success": True} else: - if 'success' not in kwargs: - kwargs['success'] = True + if "success" not in kwargs: + kwargs["success"] = True response_class = _responses_to_types[request.command] - kwargs.setdefault('seq', -1) # To be overwritten before sending + kwargs.setdefault("seq", -1) # To be overwritten before sending return response_class(command=request.command, request_seq=request.seq, **kwargs) diff --git a/_pydevd_bundle/_debug_adapter/pydevd_schema.py b/_pydevd_bundle/_debug_adapter/pydevd_schema.py index 12d2ddd58..bdb66e121 100644 --- a/_pydevd_bundle/_debug_adapter/pydevd_schema.py +++ b/_pydevd_bundle/_debug_adapter/pydevd_schema.py @@ -16,21 +16,13 @@ class ProtocolMessage(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "type": { - "type": "string", - "description": "Message type.", - "_enum": [ - "request", - "response", - "event" - ] - } + "type": {"type": "string", "description": "Message type.", "_enum": ["request", "response", "event"]}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, type, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -41,13 +33,12 @@ def __init__(self, type, seq=-1, update_ids_from_dap=False, **kwargs): # noqa ( self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) seq = self.seq dct = { - 'type': type, - 'seq': seq, + "type": type, + "seq": seq, } dct.update(self.kwargs) return dct @@ -64,61 +55,44 @@ class Request(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "description": "The command to execute." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "description": "The command to execute."}, "arguments": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Object containing arguments for the command." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Object containing arguments for the command.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, command, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param string command: The command to execute. :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] arguments: Object containing arguments for the command. """ - self.type = 'request' + self.type = "request" self.command = command self.seq = seq self.arguments = arguments self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments + dct["arguments"] = arguments dct.update(self.kwargs) return dct @@ -134,61 +108,44 @@ class Event(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "description": "Type of event." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "description": "Type of event."}, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Event-specific information." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Event-specific information.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, event, seq=-1, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param string event: Type of event. :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Event-specific information. """ - self.type = 'event' + self.type = "event" self.event = event self.seq = seq self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event seq = self.seq body = self.body dct = { - 'type': type, - 'event': event, - 'seq': seq, + "type": type, + "event": event, + "seq": seq, } if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct @@ -204,58 +161,33 @@ class Response(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -267,7 +199,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -276,7 +208,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -286,21 +217,21 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_response('error') +@register_response("error") @register class ErrorResponse(BaseSchema): """ @@ -312,79 +243,56 @@ class ErrorResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", - "properties": { - "error": { - "$ref": "#/definitions/Message", - "description": "A structured error message." - } - } - } + "properties": {"error": {"$ref": "#/definitions/Message", "description": "A structured error message."}}, + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param ErrorResponseBody body: + :param ErrorResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = ErrorResponseBody() else: - self.body = ErrorResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ErrorResponseBody else body + self.body = ErrorResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ErrorResponseBody else body self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -394,48 +302,48 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('cancel') +@register_request("cancel") @register class CancelRequest(BaseSchema): """ The `cancel` request is used by the client in two situations: - + - to indicate that it is no longer interested in the result produced by a specific request issued earlier - + - to cancel a progress sequence. - + Clients should only call this request if the corresponding capability `supportsCancelRequest` is true. - + This request has a hint characteristic: a debug adapter can only be expected to make a 'best effort' in honoring this request but there are no guarantees. - + The `cancel` request may return an error if it could not cancel an operation but a client should refrain from presenting this error to end users. - + The request that got cancelled still needs to send a response back. This can either be a normal result (`success` attribute true) or an error response (`success` attribute false and the `message` set to `cancelled`). - + Returning partial results from a cancelled request is possible but please note that a client has no generic way for detecting that a response is partial or not. - + The progress that got cancelled still needs to send a `progressEnd` event back. - + A client should not assume that progress just got cancelled after sending the `cancel` request. Note: automatically generated code. Do not edit manually. @@ -444,57 +352,48 @@ class CancelRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "cancel" - ] - }, - "arguments": { - "type": "CancelArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["cancel"]}, + "arguments": {"type": "CancelArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param CancelArguments arguments: + :param CancelArguments arguments: """ - self.type = 'request' - self.command = 'cancel' + self.type = "request" + self.command = "cancel" self.seq = seq if arguments is None: self.arguments = CancelArguments() else: - self.arguments = CancelArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != CancelArguments else arguments + self.arguments = ( + CancelArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != CancelArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -510,16 +409,16 @@ class CancelArguments(BaseSchema): __props__ = { "requestId": { "type": "integer", - "description": "The ID (attribute `seq`) of the request to cancel. If missing no request is cancelled.\nBoth a `requestId` and a `progressId` can be specified in one request." + "description": "The ID (attribute `seq`) of the request to cancel. If missing no request is cancelled.\nBoth a `requestId` and a `progressId` can be specified in one request.", }, "progressId": { "type": "string", - "description": "The ID (attribute `progressId`) of the progress to cancel. If missing no progress is cancelled.\nBoth a `requestId` and a `progressId` can be specified in one request." - } + "description": "The ID (attribute `progressId`) of the progress to cancel. If missing no progress is cancelled.\nBoth a `requestId` and a `progressId` can be specified in one request.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, requestId=None, progressId=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -532,21 +431,19 @@ def __init__(self, requestId=None, progressId=None, update_ids_from_dap=False, * self.progressId = progressId self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) requestId = self.requestId progressId = self.progressId - dct = { - } + dct = {} if requestId is not None: - dct['requestId'] = requestId + dct["requestId"] = requestId if progressId is not None: - dct['progressId'] = progressId + dct["progressId"] = progressId dct.update(self.kwargs) return dct -@register_response('cancel') +@register_response("cancel") @register class CancelResponse(BaseSchema): """ @@ -558,58 +455,33 @@ class CancelResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -621,7 +493,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -630,7 +502,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -640,44 +511,44 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_event('initialized') +@register_event("initialized") @register class InitializedEvent(BaseSchema): """ This event indicates that the debug adapter is ready to accept configuration requests (e.g. `setBreakpoints`, `setExceptionBreakpoints`). - + A debug adapter is expected to send this event when it is ready to accept configuration requests (but not before the `initialize` request has finished). - + The sequence of events/requests is as follows: - + - adapters sends `initialized` event (after the `initialize` request has returned) - + - client sends zero or more `setBreakpoints` requests - + - client sends one `setFunctionBreakpoints` request (if corresponding capability `supportsFunctionBreakpoints` is true) - + - client sends a `setExceptionBreakpoints` request if one or more `exceptionBreakpointFilters` have been defined (or if `supportsConfigurationDoneRequest` is not true) - + - client sends other future configuration requests - + - client sends one `configurationDone` request to indicate the end of the configuration. Note: automatically generated code. Do not edit manually. @@ -686,73 +557,54 @@ class InitializedEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "initialized" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["initialized"]}, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Event-specific information." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Event-specific information.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: + :param string type: + :param string event: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Event-specific information. """ - self.type = 'event' - self.event = 'initialized' + self.type = "event" + self.event = "initialized" self.seq = seq self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event seq = self.seq body = self.body dct = { - 'type': type, - 'event': event, - 'seq': seq, + "type": type, + "event": event, + "seq": seq, } if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_event('stopped') +@register_event("stopped") @register class StoppedEvent(BaseSchema): """ The event indicates that the execution of the debuggee has stopped due to some condition. - + This can be caused by a breakpoint previously set, a stepping request has completed, by executing a debugger statement etc. @@ -762,20 +614,10 @@ class StoppedEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "stopped" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["stopped"]}, "body": { "type": "object", "properties": { @@ -791,87 +633,79 @@ class StoppedEvent(BaseSchema): "goto", "function breakpoint", "data breakpoint", - "instruction breakpoint" - ] + "instruction breakpoint", + ], }, "description": { "type": "string", - "description": "The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is and can be translated." - }, - "threadId": { - "type": "integer", - "description": "The thread which was stopped." + "description": "The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is and can be translated.", }, + "threadId": {"type": "integer", "description": "The thread which was stopped."}, "preserveFocusHint": { "type": "boolean", - "description": "A value of True hints to the client that this event should not change the focus." + "description": "A value of True hints to the client that this event should not change the focus.", }, "text": { "type": "string", - "description": "Additional information. E.g. if reason is `exception`, text contains the exception name. This string is shown in the UI." + "description": "Additional information. E.g. if reason is `exception`, text contains the exception name. This string is shown in the UI.", }, "allThreadsStopped": { "type": "boolean", - "description": "If `allThreadsStopped` is True, a debug adapter can announce that all threads have stopped.\n- The client should use this information to enable that all threads can be expanded to access their stacktraces.\n- If the attribute is missing or false, only the thread with the given `threadId` can be expanded." + "description": "If `allThreadsStopped` is True, a debug adapter can announce that all threads have stopped.\n- The client should use this information to enable that all threads can be expanded to access their stacktraces.\n- If the attribute is missing or false, only the thread with the given `threadId` can be expanded.", }, "hitBreakpointIds": { "type": "array", - "items": { - "type": "integer" - }, - "description": "Ids of the breakpoints that triggered the event. In most cases there is only a single breakpoint but here are some examples for multiple breakpoints:\n- Different types of breakpoints map to the same location.\n- Multiple source breakpoints get collapsed to the same instruction by the compiler/runtime.\n- Multiple function breakpoints with different function names map to the same location." - } + "items": {"type": "integer"}, + "description": "Ids of the breakpoints that triggered the event. In most cases there is only a single breakpoint but here are some examples for multiple breakpoints:\n- Different types of breakpoints map to the same location.\n- Multiple source breakpoints get collapsed to the same instruction by the compiler/runtime.\n- Multiple function breakpoints with different function names map to the same location.", + }, }, - "required": [ - "reason" - ] - } + "required": ["reason"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param StoppedEventBody body: + :param string type: + :param string event: + :param StoppedEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'stopped' + self.type = "event" + self.event = "stopped" if body is None: self.body = StoppedEventBody() else: - self.body = StoppedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != StoppedEventBody else body + self.body = StoppedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != StoppedEventBody else body self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('continued') +@register_event("continued") @register class ContinuedEvent(BaseSchema): """ The event indicates that the execution of the debuggee has continued. - + Please note: a debug adapter is not expected to send this event in response to a request that implies that execution continues, e.g. `launch` or `continue`. - + It is only necessary to send a `continued` event if there was no previous request that implied this. Note: automatically generated code. Do not edit manually. @@ -880,74 +714,60 @@ class ContinuedEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "continued" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["continued"]}, "body": { "type": "object", "properties": { - "threadId": { - "type": "integer", - "description": "The thread which was continued." - }, + "threadId": {"type": "integer", "description": "The thread which was continued."}, "allThreadsContinued": { "type": "boolean", - "description": "If `allThreadsContinued` is True, a debug adapter can announce that all threads have continued." - } + "description": "If `allThreadsContinued` is True, a debug adapter can announce that all threads have continued.", + }, }, - "required": [ - "threadId" - ] - } + "required": ["threadId"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param ContinuedEventBody body: + :param string type: + :param string event: + :param ContinuedEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'continued' + self.type = "event" + self.event = "continued" if body is None: self.body = ContinuedEventBody() else: - self.body = ContinuedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ContinuedEventBody else body + self.body = ( + ContinuedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ContinuedEventBody else body + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('exited') +@register_event("exited") @register class ExitedEvent(BaseSchema): """ @@ -959,70 +779,52 @@ class ExitedEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "exited" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["exited"]}, "body": { "type": "object", - "properties": { - "exitCode": { - "type": "integer", - "description": "The exit code returned from the debuggee." - } - }, - "required": [ - "exitCode" - ] - } + "properties": {"exitCode": {"type": "integer", "description": "The exit code returned from the debuggee."}}, + "required": ["exitCode"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param ExitedEventBody body: + :param string type: + :param string event: + :param ExitedEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'exited' + self.type = "event" + self.event = "exited" if body is None: self.body = ExitedEventBody() else: - self.body = ExitedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ExitedEventBody else body + self.body = ExitedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ExitedEventBody else body self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('terminated') +@register_event("terminated") @register class TerminatedEvent(BaseSchema): """ @@ -1035,76 +837,59 @@ class TerminatedEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "terminated" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["terminated"]}, "body": { "type": "object", "properties": { "restart": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "A debug adapter may set `restart` to True (or to an arbitrary object) to request that the client restarts the session.\nThe value is not interpreted by the client and passed unmodified as an attribute `__restart` to the `launch` and `attach` requests." + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "A debug adapter may set `restart` to True (or to an arbitrary object) to request that the client restarts the session.\nThe value is not interpreted by the client and passed unmodified as an attribute `__restart` to the `launch` and `attach` requests.", } - } - } + }, + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: + :param string type: + :param string event: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param TerminatedEventBody body: + :param TerminatedEventBody body: """ - self.type = 'event' - self.event = 'terminated' + self.type = "event" + self.event = "terminated" self.seq = seq if body is None: self.body = TerminatedEventBody() else: - self.body = TerminatedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != TerminatedEventBody else body + self.body = ( + TerminatedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != TerminatedEventBody else body + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event seq = self.seq body = self.body dct = { - 'type': type, - 'event': event, - 'seq': seq, + "type": type, + "event": event, + "seq": seq, } if body is not None: - dct['body'] = body.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["body"] = body.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct -@register_event('thread') +@register_event("thread") @register class ThreadEvent(BaseSchema): """ @@ -1116,79 +901,55 @@ class ThreadEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "thread" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["thread"]}, "body": { "type": "object", "properties": { - "reason": { - "type": "string", - "description": "The reason for the event.", - "_enum": [ - "started", - "exited" - ] - }, - "threadId": { - "type": "integer", - "description": "The identifier of the thread." - } + "reason": {"type": "string", "description": "The reason for the event.", "_enum": ["started", "exited"]}, + "threadId": {"type": "integer", "description": "The identifier of the thread."}, }, - "required": [ - "reason", - "threadId" - ] - } + "required": ["reason", "threadId"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param ThreadEventBody body: + :param string type: + :param string event: + :param ThreadEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'thread' + self.type = "event" + self.event = "thread" if body is None: self.body = ThreadEventBody() else: - self.body = ThreadEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ThreadEventBody else body + self.body = ThreadEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ThreadEventBody else body self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('output') +@register_event("output") @register class OutputEvent(BaseSchema): """ @@ -1200,130 +961,90 @@ class OutputEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "output" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["output"]}, "body": { "type": "object", "properties": { "category": { "type": "string", "description": "The output category. If not specified or if the category is not understood by the client, `console` is assumed.", - "_enum": [ - "console", - "important", - "stdout", - "stderr", - "telemetry" - ], + "_enum": ["console", "important", "stdout", "stderr", "telemetry"], "enumDescriptions": [ "Show the output in the client's default message UI, e.g. a 'debug console'. This category should only be used for informational output from the debugger (as opposed to the debuggee).", "A hint for the client to show the output in the client's UI for important and highly visible information, e.g. as a popup notification. This category should only be used for important messages from the debugger (as opposed to the debuggee). Since this category value is a hint, clients might ignore the hint and assume the `console` category.", "Show the output as normal program output from the debuggee.", "Show the output as error program output from the debuggee.", - "Send the output to telemetry instead of showing it to the user." - ] - }, - "output": { - "type": "string", - "description": "The output to report." + "Send the output to telemetry instead of showing it to the user.", + ], }, + "output": {"type": "string", "description": "The output to report."}, "group": { "type": "string", "description": "Support for keeping an output log organized by grouping related messages.", - "enum": [ - "start", - "startCollapsed", - "end" - ], + "enum": ["start", "startCollapsed", "end"], "enumDescriptions": [ "Start a new group in expanded mode. Subsequent output events are members of the group and should be shown indented.\nThe `output` attribute becomes the name of the group and is not indented.", "Start a new group in collapsed mode. Subsequent output events are members of the group and should be shown indented (as soon as the group is expanded).\nThe `output` attribute becomes the name of the group and is not indented.", - "End the current group and decrease the indentation of subsequent output events.\nA non-empty `output` attribute is shown as the unindented end of the group." - ] + "End the current group and decrease the indentation of subsequent output events.\nA non-empty `output` attribute is shown as the unindented end of the group.", + ], }, "variablesReference": { "type": "integer", - "description": "If an attribute `variablesReference` exists and its value is > 0, the output contains objects which can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." - }, - "source": { - "$ref": "#/definitions/Source", - "description": "The source location where the output was produced." - }, - "line": { - "type": "integer", - "description": "The source location's line where the output was produced." + "description": "If an attribute `variablesReference` exists and its value is > 0, the output contains objects which can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, + "source": {"$ref": "#/definitions/Source", "description": "The source location where the output was produced."}, + "line": {"type": "integer", "description": "The source location's line where the output was produced."}, "column": { "type": "integer", - "description": "The position in `line` where the output was produced. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." + "description": "The position in `line` where the output was produced. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, "data": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Additional data to report. For the `telemetry` category the data is sent to telemetry, for the other categories the data is shown in JSON format." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Additional data to report. For the `telemetry` category the data is sent to telemetry, for the other categories the data is shown in JSON format.", + }, }, - "required": [ - "output" - ] - } + "required": ["output"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param OutputEventBody body: + :param string type: + :param string event: + :param OutputEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'output' + self.type = "event" + self.event = "output" if body is None: self.body = OutputEventBody() else: - self.body = OutputEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != OutputEventBody else body + self.body = OutputEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != OutputEventBody else body self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('breakpoint') +@register_event("breakpoint") @register class BreakpointEvent(BaseSchema): """ @@ -1335,80 +1056,60 @@ class BreakpointEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "breakpoint" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["breakpoint"]}, "body": { "type": "object", "properties": { - "reason": { - "type": "string", - "description": "The reason for the event.", - "_enum": [ - "changed", - "new", - "removed" - ] - }, + "reason": {"type": "string", "description": "The reason for the event.", "_enum": ["changed", "new", "removed"]}, "breakpoint": { "$ref": "#/definitions/Breakpoint", - "description": "The `id` attribute is used to find the target breakpoint, the other attributes are used as the new values." - } + "description": "The `id` attribute is used to find the target breakpoint, the other attributes are used as the new values.", + }, }, - "required": [ - "reason", - "breakpoint" - ] - } + "required": ["reason", "breakpoint"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param BreakpointEventBody body: + :param string type: + :param string event: + :param BreakpointEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'breakpoint' + self.type = "event" + self.event = "breakpoint" if body is None: self.body = BreakpointEventBody() else: - self.body = BreakpointEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != BreakpointEventBody else body + self.body = ( + BreakpointEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != BreakpointEventBody else body + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('module') +@register_event("module") @register class ModuleEvent(BaseSchema): """ @@ -1420,80 +1121,58 @@ class ModuleEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "module" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["module"]}, "body": { "type": "object", "properties": { - "reason": { - "type": "string", - "description": "The reason for the event.", - "enum": [ - "new", - "changed", - "removed" - ] - }, + "reason": {"type": "string", "description": "The reason for the event.", "enum": ["new", "changed", "removed"]}, "module": { "$ref": "#/definitions/Module", - "description": "The new, changed, or removed module. In case of `removed` only the module id is used." - } + "description": "The new, changed, or removed module. In case of `removed` only the module id is used.", + }, }, - "required": [ - "reason", - "module" - ] - } + "required": ["reason", "module"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param ModuleEventBody body: + :param string type: + :param string event: + :param ModuleEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'module' + self.type = "event" + self.event = "module" if body is None: self.body = ModuleEventBody() else: - self.body = ModuleEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ModuleEventBody else body + self.body = ModuleEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ModuleEventBody else body self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('loadedSource') +@register_event("loadedSource") @register class LoadedSourceEvent(BaseSchema): """ @@ -1506,80 +1185,57 @@ class LoadedSourceEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "loadedSource" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["loadedSource"]}, "body": { "type": "object", "properties": { - "reason": { - "type": "string", - "description": "The reason for the event.", - "enum": [ - "new", - "changed", - "removed" - ] - }, - "source": { - "$ref": "#/definitions/Source", - "description": "The new, changed, or removed source." - } + "reason": {"type": "string", "description": "The reason for the event.", "enum": ["new", "changed", "removed"]}, + "source": {"$ref": "#/definitions/Source", "description": "The new, changed, or removed source."}, }, - "required": [ - "reason", - "source" - ] - } + "required": ["reason", "source"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param LoadedSourceEventBody body: + :param string type: + :param string event: + :param LoadedSourceEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'loadedSource' + self.type = "event" + self.event = "loadedSource" if body is None: self.body = LoadedSourceEventBody() else: - self.body = LoadedSourceEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != LoadedSourceEventBody else body + self.body = ( + LoadedSourceEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != LoadedSourceEventBody else body + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('process') +@register_event("process") @register class ProcessEvent(BaseSchema): """ @@ -1592,107 +1248,90 @@ class ProcessEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "process" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["process"]}, "body": { "type": "object", "properties": { "name": { "type": "string", - "description": "The logical name of the process. This is usually the full path to process's executable file. Example: /home/example/myproj/program.js." + "description": "The logical name of the process. This is usually the full path to process's executable file. Example: /home/example/myproj/program.js.", }, "systemProcessId": { "type": "integer", - "description": "The system process id of the debugged process. This property is missing for non-system processes." + "description": "The system process id of the debugged process. This property is missing for non-system processes.", }, "isLocalProcess": { "type": "boolean", - "description": "If True, the process is running on the same computer as the debug adapter." + "description": "If True, the process is running on the same computer as the debug adapter.", }, "startMethod": { "type": "string", - "enum": [ - "launch", - "attach", - "attachForSuspendedLaunch" - ], + "enum": ["launch", "attach", "attachForSuspendedLaunch"], "description": "Describes how the debug engine started debugging this process.", "enumDescriptions": [ "Process was launched under the debugger.", "Debugger attached to an existing process.", - "A project launcher component has launched a new process in a suspended state and then asked the debugger to attach." - ] + "A project launcher component has launched a new process in a suspended state and then asked the debugger to attach.", + ], }, "pointerSize": { "type": "integer", - "description": "The size of a pointer or address for this process, in bits. This value may be used by clients when formatting addresses for display." - } + "description": "The size of a pointer or address for this process, in bits. This value may be used by clients when formatting addresses for display.", + }, }, - "required": [ - "name" - ] - } + "required": ["name"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param ProcessEventBody body: + :param string type: + :param string event: + :param ProcessEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'process' + self.type = "event" + self.event = "process" if body is None: self.body = ProcessEventBody() else: - self.body = ProcessEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ProcessEventBody else body + self.body = ProcessEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ProcessEventBody else body self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('capabilities') +@register_event("capabilities") @register class CapabilitiesEvent(BaseSchema): """ The event indicates that one or more capabilities have changed. - + Since the capabilities are dependent on the client and its UI, it might not be possible to change that at random times (or too late). - + Consequently this event has a hint characteristic: a client can only be expected to make a 'best effort' in honoring individual capabilities but there are no guarantees. - + Only changed capabilities need to be included, all other capabilities keep their values. Note: automatically generated code. Do not edit manually. @@ -1701,78 +1340,62 @@ class CapabilitiesEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "capabilities" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["capabilities"]}, "body": { "type": "object", - "properties": { - "capabilities": { - "$ref": "#/definitions/Capabilities", - "description": "The set of updated capabilities." - } - }, - "required": [ - "capabilities" - ] - } + "properties": {"capabilities": {"$ref": "#/definitions/Capabilities", "description": "The set of updated capabilities."}}, + "required": ["capabilities"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param CapabilitiesEventBody body: + :param string type: + :param string event: + :param CapabilitiesEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'capabilities' + self.type = "event" + self.event = "capabilities" if body is None: self.body = CapabilitiesEventBody() else: - self.body = CapabilitiesEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != CapabilitiesEventBody else body + self.body = ( + CapabilitiesEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != CapabilitiesEventBody else body + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('progressStart') +@register_event("progressStart") @register class ProgressStartEvent(BaseSchema): """ The event signals that a long running operation is about to start and provides additional information for the client to set up a corresponding progress and cancellation UI. - + The client is free to delay the showing of the UI in order to reduce flicker. - + This event should only be sent if the corresponding capability `supportsProgressReporting` is true. Note: automatically generated code. Do not edit manually. @@ -1781,100 +1404,87 @@ class ProgressStartEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "progressStart" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["progressStart"]}, "body": { "type": "object", "properties": { "progressId": { "type": "string", - "description": "An ID that can be used in subsequent `progressUpdate` and `progressEnd` events to make them refer to the same progress reporting.\nIDs must be unique within a debug session." + "description": "An ID that can be used in subsequent `progressUpdate` and `progressEnd` events to make them refer to the same progress reporting.\nIDs must be unique within a debug session.", }, "title": { "type": "string", - "description": "Short title of the progress reporting. Shown in the UI to describe the long running operation." + "description": "Short title of the progress reporting. Shown in the UI to describe the long running operation.", }, "requestId": { "type": "integer", - "description": "The request ID that this progress report is related to. If specified a debug adapter is expected to emit progress events for the long running request until the request has been either completed or cancelled.\nIf the request ID is omitted, the progress report is assumed to be related to some general activity of the debug adapter." + "description": "The request ID that this progress report is related to. If specified a debug adapter is expected to emit progress events for the long running request until the request has been either completed or cancelled.\nIf the request ID is omitted, the progress report is assumed to be related to some general activity of the debug adapter.", }, "cancellable": { "type": "boolean", - "description": "If True, the request that reports progress may be cancelled with a `cancel` request.\nSo this property basically controls whether the client should use UX that supports cancellation.\nClients that don't support cancellation are allowed to ignore the setting." - }, - "message": { - "type": "string", - "description": "More detailed progress message." + "description": "If True, the request that reports progress may be cancelled with a `cancel` request.\nSo this property basically controls whether the client should use UX that supports cancellation.\nClients that don't support cancellation are allowed to ignore the setting.", }, + "message": {"type": "string", "description": "More detailed progress message."}, "percentage": { "type": "number", - "description": "Progress percentage to display (value range: 0 to 100). If omitted no percentage is shown." - } + "description": "Progress percentage to display (value range: 0 to 100). If omitted no percentage is shown.", + }, }, - "required": [ - "progressId", - "title" - ] - } + "required": ["progressId", "title"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param ProgressStartEventBody body: + :param string type: + :param string event: + :param ProgressStartEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'progressStart' + self.type = "event" + self.event = "progressStart" if body is None: self.body = ProgressStartEventBody() else: - self.body = ProgressStartEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ProgressStartEventBody else body + self.body = ( + ProgressStartEventBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != ProgressStartEventBody + else body + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('progressUpdate') +@register_event("progressUpdate") @register class ProgressUpdateEvent(BaseSchema): """ The event signals that the progress reporting needs to be updated with a new message and/or percentage. - + The client does not have to update the UI immediately, but the clients needs to keep track of the message and/or percentage values. - + This event should only be sent if the corresponding capability `supportsProgressReporting` is true. Note: automatically generated code. Do not edit manually. @@ -1883,83 +1493,71 @@ class ProgressUpdateEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "progressUpdate" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["progressUpdate"]}, "body": { "type": "object", - "properties": { - "progressId": { - "type": "string", - "description": "The ID that was introduced in the initial `progressStart` event." - }, + "properties": { + "progressId": {"type": "string", "description": "The ID that was introduced in the initial `progressStart` event."}, "message": { "type": "string", - "description": "More detailed progress message. If omitted, the previous message (if any) is used." + "description": "More detailed progress message. If omitted, the previous message (if any) is used.", }, "percentage": { "type": "number", - "description": "Progress percentage to display (value range: 0 to 100). If omitted no percentage is shown." - } + "description": "Progress percentage to display (value range: 0 to 100). If omitted no percentage is shown.", + }, }, - "required": [ - "progressId" - ] - } + "required": ["progressId"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param ProgressUpdateEventBody body: + :param string type: + :param string event: + :param ProgressUpdateEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'progressUpdate' + self.type = "event" + self.event = "progressUpdate" if body is None: self.body = ProgressUpdateEventBody() else: - self.body = ProgressUpdateEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ProgressUpdateEventBody else body + self.body = ( + ProgressUpdateEventBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != ProgressUpdateEventBody + else body + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('progressEnd') +@register_event("progressEnd") @register class ProgressEndEvent(BaseSchema): """ The event signals the end of the progress reporting with a final message. - + This event should only be sent if the corresponding capability `supportsProgressReporting` is true. Note: automatically generated code. Do not edit manually. @@ -1968,84 +1566,70 @@ class ProgressEndEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "progressEnd" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["progressEnd"]}, "body": { "type": "object", "properties": { - "progressId": { - "type": "string", - "description": "The ID that was introduced in the initial `ProgressStartEvent`." - }, + "progressId": {"type": "string", "description": "The ID that was introduced in the initial `ProgressStartEvent`."}, "message": { "type": "string", - "description": "More detailed progress message. If omitted, the previous message (if any) is used." - } + "description": "More detailed progress message. If omitted, the previous message (if any) is used.", + }, }, - "required": [ - "progressId" - ] - } + "required": ["progressId"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param ProgressEndEventBody body: + :param string type: + :param string event: + :param ProgressEndEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'progressEnd' + self.type = "event" + self.event = "progressEnd" if body is None: self.body = ProgressEndEventBody() else: - self.body = ProgressEndEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ProgressEndEventBody else body + self.body = ( + ProgressEndEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ProgressEndEventBody else body + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('invalidated') +@register_event("invalidated") @register class InvalidatedEvent(BaseSchema): """ This event signals that some state in the debug adapter has changed and requires that the client needs to re-render the data snapshot previously requested. - + Debug adapters do not have to emit this event for runtime changes like stopped or thread events because in that case the client refetches the new state anyway. But the event can be used for example to refresh the UI after rendering formatting has changed in the debug adapter. - + This event should only be sent if the corresponding capability `supportsInvalidatedEvent` is true. Note: automatically generated code. Do not edit manually. @@ -2054,89 +1638,78 @@ class InvalidatedEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "invalidated" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["invalidated"]}, "body": { "type": "object", "properties": { "areas": { "type": "array", "description": "Set of logical areas that got invalidated. This property has a hint characteristic: a client can only be expected to make a 'best effort' in honoring the areas but there are no guarantees. If this property is missing, empty, or if values are not understood, the client should assume a single value `all`.", - "items": { - "$ref": "#/definitions/InvalidatedAreas" - } + "items": {"$ref": "#/definitions/InvalidatedAreas"}, }, "threadId": { "type": "integer", - "description": "If specified, the client only needs to refetch data related to this thread." + "description": "If specified, the client only needs to refetch data related to this thread.", }, "stackFrameId": { "type": "integer", - "description": "If specified, the client only needs to refetch data related to this stack frame (and the `threadId` is ignored)." - } - } - } + "description": "If specified, the client only needs to refetch data related to this stack frame (and the `threadId` is ignored).", + }, + }, + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param InvalidatedEventBody body: + :param string type: + :param string event: + :param InvalidatedEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'invalidated' + self.type = "event" + self.event = "invalidated" if body is None: self.body = InvalidatedEventBody() else: - self.body = InvalidatedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != InvalidatedEventBody else body + self.body = ( + InvalidatedEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != InvalidatedEventBody else body + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_event('memory') +@register_event("memory") @register class MemoryEvent(BaseSchema): """ This event indicates that some memory range has been updated. It should only be sent if the corresponding capability `supportsMemoryEvent` is true. - + Clients typically react to the event by re-issuing a `readMemory` request if they show the memory identified by the `memoryReference` and if the updated memory range overlaps the displayed range. Clients should not make assumptions how individual memory references relate to each other, so they should not assume that they are part of a single continuous address range and might overlap. - + Debug adapters can use this event to indicate that the contents of a memory range has changed due to some other request like `setVariable` or `setExpression`. Debug adapters are not expected to emit this event for each and every memory change of a running program, because that information is @@ -2148,96 +1721,72 @@ class MemoryEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "memory" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["memory"]}, "body": { "type": "object", "properties": { - "memoryReference": { - "type": "string", - "description": "Memory reference of a memory range that has been updated." - }, - "offset": { - "type": "integer", - "description": "Starting offset in bytes where memory has been updated. Can be negative." - }, - "count": { - "type": "integer", - "description": "Number of bytes updated." - } + "memoryReference": {"type": "string", "description": "Memory reference of a memory range that has been updated."}, + "offset": {"type": "integer", "description": "Starting offset in bytes where memory has been updated. Can be negative."}, + "count": {"type": "integer", "description": "Number of bytes updated."}, }, - "required": [ - "memoryReference", - "offset", - "count" - ] - } + "required": ["memoryReference", "offset", "count"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, body, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: - :param MemoryEventBody body: + :param string type: + :param string event: + :param MemoryEventBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'event' - self.event = 'memory' + self.type = "event" + self.event = "memory" if body is None: self.body = MemoryEventBody() else: - self.body = MemoryEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != MemoryEventBody else body + self.body = MemoryEventBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != MemoryEventBody else body self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event body = self.body seq = self.seq dct = { - 'type': type, - 'event': event, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "event": event, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct -@register_request('runInTerminal') +@register_request("runInTerminal") @register class RunInTerminalRequest(BaseSchema): """ This request is sent from the debug adapter to the client to run a command in a terminal. - + This is typically used to launch the debuggee in a terminal provided by the client. - + This request should only be called if the corresponding client capability `supportsRunInTerminalRequest` is true. - + Client implementations of `runInTerminal` are free to run the command however they choose including issuing the command to a command line interpreter (aka 'shell'). Argument strings passed to the `runInTerminal` request must arrive verbatim in the command to be run. As a consequence, clients which use a shell are responsible for escaping any special shell characters in the argument strings to prevent them from being interpreted (and modified) by the shell. - + Some users may wish to take advantage of shell processing in the argument strings. For clients which implement `runInTerminal` using an intermediary shell, the `argsCanBeInterpretedByShell` property can be set to true. In this case the client is requested not to escape any special shell characters @@ -2249,55 +1798,46 @@ class RunInTerminalRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "runInTerminal" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "RunInTerminalRequestArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["runInTerminal"]}, + "arguments": {"type": "RunInTerminalRequestArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param RunInTerminalRequestArguments arguments: + :param string type: + :param string command: + :param RunInTerminalRequestArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'runInTerminal' + self.type = "request" + self.command = "runInTerminal" if arguments is None: self.arguments = RunInTerminalRequestArguments() else: - self.arguments = RunInTerminalRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != RunInTerminalRequestArguments else arguments + self.arguments = ( + RunInTerminalRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != RunInTerminalRequestArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -2314,46 +1854,35 @@ class RunInTerminalRequestArguments(BaseSchema): __props__ = { "kind": { "type": "string", - "enum": [ - "integrated", - "external" - ], - "description": "What kind of terminal to launch. Defaults to `integrated` if not specified." - }, - "title": { - "type": "string", - "description": "Title of the terminal." + "enum": ["integrated", "external"], + "description": "What kind of terminal to launch. Defaults to `integrated` if not specified.", }, + "title": {"type": "string", "description": "Title of the terminal."}, "cwd": { "type": "string", - "description": "Working directory for the command. For non-empty, valid paths this typically results in execution of a change directory command." + "description": "Working directory for the command. For non-empty, valid paths this typically results in execution of a change directory command.", }, "args": { "type": "array", - "items": { - "type": "string" - }, - "description": "List of arguments. The first argument is the command to run." + "items": {"type": "string"}, + "description": "List of arguments. The first argument is the command to run.", }, "env": { "type": "object", "description": "Environment key-value pairs that are added to or removed from the default environment.", "additionalProperties": { - "type": [ - "string", - "null" - ], - "description": "A string is a proper value for an environment variable. The value `null` removes the variable from the environment." - } + "type": ["string", "null"], + "description": "A string is a proper value for an environment variable. The value `null` removes the variable from the environment.", + }, }, "argsCanBeInterpretedByShell": { "type": "boolean", - "description": "This property should only be set if the corresponding capability `supportsArgsCanBeInterpretedByShell` is True. If the client uses an intermediary shell to launch the application, then the client must not attempt to escape characters with special meanings for the shell. The user is fully responsible for escaping as needed and that arguments using special characters may not be portable across shells." - } + "description": "This property should only be set if the corresponding capability `supportsArgsCanBeInterpretedByShell` is True. If the client uses an intermediary shell to launch the application, then the client must not attempt to escape characters with special meanings for the shell. The user is fully responsible for escaping as needed and that arguments using special characters may not be portable across shells.", + }, } - __refs__ = set(['env']) + __refs__ = set(["env"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, cwd, args, kind=None, title=None, env=None, argsCanBeInterpretedByShell=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -2371,11 +1900,14 @@ def __init__(self, cwd, args, kind=None, title=None, env=None, argsCanBeInterpre if env is None: self.env = RunInTerminalRequestArgumentsEnv() else: - self.env = RunInTerminalRequestArgumentsEnv(update_ids_from_dap=update_ids_from_dap, **env) if env.__class__ != RunInTerminalRequestArgumentsEnv else env + self.env = ( + RunInTerminalRequestArgumentsEnv(update_ids_from_dap=update_ids_from_dap, **env) + if env.__class__ != RunInTerminalRequestArgumentsEnv + else env + ) self.argsCanBeInterpretedByShell = argsCanBeInterpretedByShell self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) cwd = self.cwd args = self.args @@ -2386,22 +1918,22 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un env = self.env argsCanBeInterpretedByShell = self.argsCanBeInterpretedByShell dct = { - 'cwd': cwd, - 'args': args, + "cwd": cwd, + "args": args, } if kind is not None: - dct['kind'] = kind + dct["kind"] = kind if title is not None: - dct['title'] = title + dct["title"] = title if env is not None: - dct['env'] = env.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["env"] = env.to_dict(update_ids_to_dap=update_ids_to_dap) if argsCanBeInterpretedByShell is not None: - dct['argsCanBeInterpretedByShell'] = argsCanBeInterpretedByShell + dct["argsCanBeInterpretedByShell"] = argsCanBeInterpretedByShell dct.update(self.kwargs) return dct -@register_response('runInTerminal') +@register_response("runInTerminal") @register class RunInTerminalResponse(BaseSchema): """ @@ -2413,83 +1945,69 @@ class RunInTerminalResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "processId": { "type": "integer", - "description": "The process ID. The value should be less than or equal to 2147483647 (2^31-1)." + "description": "The process ID. The value should be less than or equal to 2147483647 (2^31-1).", }, "shellProcessId": { "type": "integer", - "description": "The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31-1)." - } - } - } + "description": "The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31-1).", + }, + }, + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param RunInTerminalResponseBody body: + :param RunInTerminalResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = RunInTerminalResponseBody() else: - self.body = RunInTerminalResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != RunInTerminalResponseBody else body + self.body = ( + RunInTerminalResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != RunInTerminalResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -2499,29 +2017,29 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('startDebugging') +@register_request("startDebugging") @register class StartDebuggingRequest(BaseSchema): """ This request is sent from the debug adapter to the client to start a new debug session of the same type as the caller. - + This request should only be sent if the corresponding client capability `supportsStartDebuggingRequest` is true. - + A client implementation of `startDebugging` should start a new debug session (of the same type as the caller) in the same way that the caller's session was started. If the client supports hierarchical debug sessions, the newly created session can be treated as a child of the caller @@ -2533,55 +2051,46 @@ class StartDebuggingRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "startDebugging" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "StartDebuggingRequestArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["startDebugging"]}, + "arguments": {"type": "StartDebuggingRequestArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param StartDebuggingRequestArguments arguments: + :param string type: + :param string command: + :param StartDebuggingRequestArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'startDebugging' + self.type = "request" + self.command = "startDebugging" if arguments is None: self.arguments = StartDebuggingRequestArguments() else: - self.arguments = StartDebuggingRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != StartDebuggingRequestArguments else arguments + self.arguments = ( + StartDebuggingRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != StartDebuggingRequestArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -2599,20 +2108,17 @@ class StartDebuggingRequestArguments(BaseSchema): "configuration": { "type": "object", "additionalProperties": True, - "description": "Arguments passed to the new debug session. The arguments must only contain properties understood by the `launch` or `attach` requests of the debug adapter and they must not contain any client-specific properties (e.g. `type`) or client-specific features (e.g. substitutable 'variables')." + "description": "Arguments passed to the new debug session. The arguments must only contain properties understood by the `launch` or `attach` requests of the debug adapter and they must not contain any client-specific properties (e.g. `type`) or client-specific features (e.g. substitutable 'variables').", }, "request": { "type": "string", - "enum": [ - "launch", - "attach" - ], - "description": "Indicates whether the new debug session should be started with a `launch` or `attach` request." - } + "enum": ["launch", "attach"], + "description": "Indicates whether the new debug session should be started with a `launch` or `attach` request.", + }, } - __refs__ = set(['configuration']) + __refs__ = set(["configuration"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, configuration, request, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -2622,23 +2128,26 @@ def __init__(self, configuration, request, update_ids_from_dap=False, **kwargs): if configuration is None: self.configuration = StartDebuggingRequestArgumentsConfiguration() else: - self.configuration = StartDebuggingRequestArgumentsConfiguration(update_ids_from_dap=update_ids_from_dap, **configuration) if configuration.__class__ != StartDebuggingRequestArgumentsConfiguration else configuration + self.configuration = ( + StartDebuggingRequestArgumentsConfiguration(update_ids_from_dap=update_ids_from_dap, **configuration) + if configuration.__class__ != StartDebuggingRequestArgumentsConfiguration + else configuration + ) self.request = request self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) configuration = self.configuration request = self.request dct = { - 'configuration': configuration.to_dict(update_ids_to_dap=update_ids_to_dap), - 'request': request, + "configuration": configuration.to_dict(update_ids_to_dap=update_ids_to_dap), + "request": request, } dct.update(self.kwargs) return dct -@register_response('startDebugging') +@register_response("startDebugging") @register class StartDebuggingResponse(BaseSchema): """ @@ -2650,58 +2159,33 @@ class StartDebuggingResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -2713,7 +2197,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -2722,7 +2206,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -2732,33 +2215,33 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('initialize') +@register_request("initialize") @register class InitializeRequest(BaseSchema): """ The `initialize` request is sent as the first request from the client to the debug adapter in order to configure it with client capabilities and to retrieve capabilities from the debug adapter. - + Until the debug adapter has responded with an `initialize` response, the client must not send any additional requests or events to the debug adapter. - + In addition the debug adapter is not allowed to send any requests or events to the client until it has responded with an `initialize` response. - + The `initialize` request may only be sent once. Note: automatically generated code. Do not edit manually. @@ -2767,55 +2250,46 @@ class InitializeRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "initialize" - ] - }, - "arguments": { - "type": "InitializeRequestArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["initialize"]}, + "arguments": {"type": "InitializeRequestArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param InitializeRequestArguments arguments: + :param string type: + :param string command: + :param InitializeRequestArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'initialize' + self.type = "request" + self.command = "initialize" if arguments is None: self.arguments = InitializeRequestArguments() else: - self.arguments = InitializeRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != InitializeRequestArguments else arguments + self.arguments = ( + InitializeRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != InitializeRequestArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -2830,80 +2304,55 @@ class InitializeRequestArguments(BaseSchema): """ __props__ = { - "clientID": { - "type": "string", - "description": "The ID of the client using this adapter." - }, - "clientName": { - "type": "string", - "description": "The human-readable name of the client using this adapter." - }, - "adapterID": { - "type": "string", - "description": "The ID of the debug adapter." - }, - "locale": { - "type": "string", - "description": "The ISO-639 locale of the client using this adapter, e.g. en-US or de-CH." - }, - "linesStartAt1": { - "type": "boolean", - "description": "If True all line numbers are 1-based (default)." - }, - "columnsStartAt1": { - "type": "boolean", - "description": "If True all column numbers are 1-based (default)." - }, + "clientID": {"type": "string", "description": "The ID of the client using this adapter."}, + "clientName": {"type": "string", "description": "The human-readable name of the client using this adapter."}, + "adapterID": {"type": "string", "description": "The ID of the debug adapter."}, + "locale": {"type": "string", "description": "The ISO-639 locale of the client using this adapter, e.g. en-US or de-CH."}, + "linesStartAt1": {"type": "boolean", "description": "If True all line numbers are 1-based (default)."}, + "columnsStartAt1": {"type": "boolean", "description": "If True all column numbers are 1-based (default)."}, "pathFormat": { "type": "string", - "_enum": [ - "path", - "uri" - ], - "description": "Determines in what format paths are specified. The default is `path`, which is the native format." - }, - "supportsVariableType": { - "type": "boolean", - "description": "Client supports the `type` attribute for variables." - }, - "supportsVariablePaging": { - "type": "boolean", - "description": "Client supports the paging of variables." - }, - "supportsRunInTerminalRequest": { - "type": "boolean", - "description": "Client supports the `runInTerminal` request." - }, - "supportsMemoryReferences": { - "type": "boolean", - "description": "Client supports memory references." - }, - "supportsProgressReporting": { - "type": "boolean", - "description": "Client supports progress reporting." - }, - "supportsInvalidatedEvent": { - "type": "boolean", - "description": "Client supports the `invalidated` event." - }, - "supportsMemoryEvent": { - "type": "boolean", - "description": "Client supports the `memory` event." + "_enum": ["path", "uri"], + "description": "Determines in what format paths are specified. The default is `path`, which is the native format.", }, + "supportsVariableType": {"type": "boolean", "description": "Client supports the `type` attribute for variables."}, + "supportsVariablePaging": {"type": "boolean", "description": "Client supports the paging of variables."}, + "supportsRunInTerminalRequest": {"type": "boolean", "description": "Client supports the `runInTerminal` request."}, + "supportsMemoryReferences": {"type": "boolean", "description": "Client supports memory references."}, + "supportsProgressReporting": {"type": "boolean", "description": "Client supports progress reporting."}, + "supportsInvalidatedEvent": {"type": "boolean", "description": "Client supports the `invalidated` event."}, + "supportsMemoryEvent": {"type": "boolean", "description": "Client supports the `memory` event."}, "supportsArgsCanBeInterpretedByShell": { "type": "boolean", - "description": "Client supports the `argsCanBeInterpretedByShell` attribute on the `runInTerminal` request." + "description": "Client supports the `argsCanBeInterpretedByShell` attribute on the `runInTerminal` request.", }, - "supportsStartDebuggingRequest": { - "type": "boolean", - "description": "Client supports the `startDebugging` request." - } + "supportsStartDebuggingRequest": {"type": "boolean", "description": "Client supports the `startDebugging` request."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, adapterID, clientID=None, clientName=None, locale=None, linesStartAt1=None, columnsStartAt1=None, pathFormat=None, supportsVariableType=None, supportsVariablePaging=None, supportsRunInTerminalRequest=None, supportsMemoryReferences=None, supportsProgressReporting=None, supportsInvalidatedEvent=None, supportsMemoryEvent=None, supportsArgsCanBeInterpretedByShell=None, supportsStartDebuggingRequest=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + adapterID, + clientID=None, + clientName=None, + locale=None, + linesStartAt1=None, + columnsStartAt1=None, + pathFormat=None, + supportsVariableType=None, + supportsVariablePaging=None, + supportsRunInTerminalRequest=None, + supportsMemoryReferences=None, + supportsProgressReporting=None, + supportsInvalidatedEvent=None, + supportsMemoryEvent=None, + supportsArgsCanBeInterpretedByShell=None, + supportsStartDebuggingRequest=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string adapterID: The ID of the debug adapter. :param string clientID: The ID of the client using this adapter. @@ -2940,7 +2389,6 @@ def __init__(self, adapterID, clientID=None, clientName=None, locale=None, lines self.supportsStartDebuggingRequest = supportsStartDebuggingRequest self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) adapterID = self.adapterID clientID = self.clientID @@ -2959,43 +2407,43 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un supportsArgsCanBeInterpretedByShell = self.supportsArgsCanBeInterpretedByShell supportsStartDebuggingRequest = self.supportsStartDebuggingRequest dct = { - 'adapterID': adapterID, + "adapterID": adapterID, } if clientID is not None: - dct['clientID'] = clientID + dct["clientID"] = clientID if clientName is not None: - dct['clientName'] = clientName + dct["clientName"] = clientName if locale is not None: - dct['locale'] = locale + dct["locale"] = locale if linesStartAt1 is not None: - dct['linesStartAt1'] = linesStartAt1 + dct["linesStartAt1"] = linesStartAt1 if columnsStartAt1 is not None: - dct['columnsStartAt1'] = columnsStartAt1 + dct["columnsStartAt1"] = columnsStartAt1 if pathFormat is not None: - dct['pathFormat'] = pathFormat + dct["pathFormat"] = pathFormat if supportsVariableType is not None: - dct['supportsVariableType'] = supportsVariableType + dct["supportsVariableType"] = supportsVariableType if supportsVariablePaging is not None: - dct['supportsVariablePaging'] = supportsVariablePaging + dct["supportsVariablePaging"] = supportsVariablePaging if supportsRunInTerminalRequest is not None: - dct['supportsRunInTerminalRequest'] = supportsRunInTerminalRequest + dct["supportsRunInTerminalRequest"] = supportsRunInTerminalRequest if supportsMemoryReferences is not None: - dct['supportsMemoryReferences'] = supportsMemoryReferences + dct["supportsMemoryReferences"] = supportsMemoryReferences if supportsProgressReporting is not None: - dct['supportsProgressReporting'] = supportsProgressReporting + dct["supportsProgressReporting"] = supportsProgressReporting if supportsInvalidatedEvent is not None: - dct['supportsInvalidatedEvent'] = supportsInvalidatedEvent + dct["supportsInvalidatedEvent"] = supportsInvalidatedEvent if supportsMemoryEvent is not None: - dct['supportsMemoryEvent'] = supportsMemoryEvent + dct["supportsMemoryEvent"] = supportsMemoryEvent if supportsArgsCanBeInterpretedByShell is not None: - dct['supportsArgsCanBeInterpretedByShell'] = supportsArgsCanBeInterpretedByShell + dct["supportsArgsCanBeInterpretedByShell"] = supportsArgsCanBeInterpretedByShell if supportsStartDebuggingRequest is not None: - dct['supportsStartDebuggingRequest'] = supportsStartDebuggingRequest + dct["supportsStartDebuggingRequest"] = supportsStartDebuggingRequest dct.update(self.kwargs) return dct -@register_response('initialize') +@register_response("initialize") @register class InitializeResponse(BaseSchema): """ @@ -3007,50 +2455,30 @@ class InitializeResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, - "body": { - "description": "The capabilities of this debug adapter.", - "type": "Capabilities" - } + "body": {"description": "The capabilities of this debug adapter.", "type": "Capabilities"}, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -3062,7 +2490,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param Capabilities body: The capabilities of this debug adapter. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -3071,10 +2499,9 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non if body is None: self.body = Capabilities() else: - self.body = Capabilities(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != Capabilities else body + self.body = Capabilities(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != Capabilities else body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -3084,29 +2511,29 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["body"] = body.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct -@register_request('configurationDone') +@register_request("configurationDone") @register class ConfigurationDoneRequest(BaseSchema): """ This request indicates that the client has finished initialization of the debug adapter. - + So it is the last request in the sequence of configuration requests (which was started by the `initialized` event). - + Clients should only call this request if the corresponding capability `supportsConfigurationDoneRequest` is true. @@ -3116,57 +2543,48 @@ class ConfigurationDoneRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "configurationDone" - ] - }, - "arguments": { - "type": "ConfigurationDoneArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["configurationDone"]}, + "arguments": {"type": "ConfigurationDoneArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param ConfigurationDoneArguments arguments: + :param ConfigurationDoneArguments arguments: """ - self.type = 'request' - self.command = 'configurationDone' + self.type = "request" + self.command = "configurationDone" self.seq = seq if arguments is None: self.arguments = ConfigurationDoneArguments() else: - self.arguments = ConfigurationDoneArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != ConfigurationDoneArguments else arguments + self.arguments = ( + ConfigurationDoneArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != ConfigurationDoneArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -3182,24 +2600,20 @@ class ConfigurationDoneArguments(BaseSchema): __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct -@register_response('configurationDone') +@register_response("configurationDone") @register class ConfigurationDoneResponse(BaseSchema): """ @@ -3212,58 +2626,33 @@ class ConfigurationDoneResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -3275,7 +2664,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -3284,7 +2673,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -3294,27 +2682,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('launch') +@register_request("launch") @register class LaunchRequest(BaseSchema): """ This launch request is sent from the client to the debug adapter to start the debuggee with or without debugging (if `noDebug` is true). - + Since launching is debugger/runtime specific, the arguments for this request are not part of this specification. @@ -3324,55 +2712,46 @@ class LaunchRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "launch" - ] - }, - "arguments": { - "type": "LaunchRequestArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["launch"]}, + "arguments": {"type": "LaunchRequestArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param LaunchRequestArguments arguments: + :param string type: + :param string command: + :param LaunchRequestArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'launch' + self.type = "request" + self.command = "launch" if arguments is None: self.arguments = LaunchRequestArguments() else: - self.arguments = LaunchRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != LaunchRequestArguments else arguments + self.arguments = ( + LaunchRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != LaunchRequestArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -3387,26 +2766,15 @@ class LaunchRequestArguments(BaseSchema): """ __props__ = { - "noDebug": { - "type": "boolean", - "description": "If True, the launch request should launch the program without enabling debugging." - }, + "noDebug": {"type": "boolean", "description": "If True, the launch request should launch the program without enabling debugging."}, "__restart": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Arbitrary data from the previous, restarted session.\nThe data is sent as the `restart` attribute of the `terminated` event.\nThe client should leave the data intact." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Arbitrary data from the previous, restarted session.\nThe data is sent as the `restart` attribute of the `terminated` event.\nThe client should leave the data intact.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, noDebug=None, __restart=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -3419,21 +2787,19 @@ def __init__(self, noDebug=None, __restart=None, update_ids_from_dap=False, **kw self.__restart = __restart self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) noDebug = self.noDebug __restart = self.__restart - dct = { - } + dct = {} if noDebug is not None: - dct['noDebug'] = noDebug + dct["noDebug"] = noDebug if __restart is not None: - dct['__restart'] = __restart + dct["__restart"] = __restart dct.update(self.kwargs) return dct -@register_response('launch') +@register_response("launch") @register class LaunchResponse(BaseSchema): """ @@ -3445,58 +2811,33 @@ class LaunchResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -3508,7 +2849,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -3517,7 +2858,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -3527,27 +2867,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('attach') +@register_request("attach") @register class AttachRequest(BaseSchema): """ The `attach` request is sent from the client to the debug adapter to attach to a debuggee that is already running. - + Since attaching is debugger/runtime specific, the arguments for this request are not part of this specification. @@ -3557,55 +2897,46 @@ class AttachRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "attach" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "AttachRequestArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["attach"]}, + "arguments": {"type": "AttachRequestArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param AttachRequestArguments arguments: + :param string type: + :param string command: + :param AttachRequestArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'attach' + self.type = "request" + self.command = "attach" if arguments is None: self.arguments = AttachRequestArguments() else: - self.arguments = AttachRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != AttachRequestArguments else arguments + self.arguments = ( + AttachRequestArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != AttachRequestArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -3621,21 +2952,13 @@ class AttachRequestArguments(BaseSchema): __props__ = { "__restart": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Arbitrary data from the previous, restarted session.\nThe data is sent as the `restart` attribute of the `terminated` event.\nThe client should leave the data intact." + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Arbitrary data from the previous, restarted session.\nThe data is sent as the `restart` attribute of the `terminated` event.\nThe client should leave the data intact.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, __restart=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -3646,18 +2969,16 @@ def __init__(self, __restart=None, update_ids_from_dap=False, **kwargs): # noqa self.__restart = __restart self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) __restart = self.__restart - dct = { - } + dct = {} if __restart is not None: - dct['__restart'] = __restart + dct["__restart"] = __restart dct.update(self.kwargs) return dct -@register_response('attach') +@register_response("attach") @register class AttachResponse(BaseSchema): """ @@ -3665,62 +2986,37 @@ class AttachResponse(BaseSchema): Note: automatically generated code. Do not edit manually. """ - - __props__ = { - "seq": { - "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { + + __props__ = { + "seq": { "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -3732,7 +3028,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -3741,7 +3037,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -3751,27 +3046,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('restart') +@register_request("restart") @register class RestartRequest(BaseSchema): """ Restarts a debug session. Clients should only call this request if the corresponding capability `supportsRestartRequest` is true. - + If the capability is missing or has the value false, a typical client emulates `restart` by terminating the debug adapter first and then launching it anew. @@ -3781,57 +3076,48 @@ class RestartRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "restart" - ] - }, - "arguments": { - "type": "RestartArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["restart"]}, + "arguments": {"type": "RestartArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param RestartArguments arguments: + :param RestartArguments arguments: """ - self.type = 'request' - self.command = 'restart' + self.type = "request" + self.command = "restart" self.seq = seq if arguments is None: self.arguments = RestartArguments() else: - self.arguments = RestartArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != RestartArguments else arguments + self.arguments = ( + RestartArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != RestartArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -3846,20 +3132,13 @@ class RestartArguments(BaseSchema): __props__ = { "arguments": { - "oneOf": [ - { - "$ref": "#/definitions/LaunchRequestArguments" - }, - { - "$ref": "#/definitions/AttachRequestArguments" - } - ], - "description": "The latest version of the `launch` or `attach` configuration." + "oneOf": [{"$ref": "#/definitions/LaunchRequestArguments"}, {"$ref": "#/definitions/AttachRequestArguments"}], + "description": "The latest version of the `launch` or `attach` configuration.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -3868,18 +3147,16 @@ def __init__(self, arguments=None, update_ids_from_dap=False, **kwargs): # noqa self.arguments = arguments self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) arguments = self.arguments - dct = { - } + dct = {} if arguments is not None: - dct['arguments'] = arguments + dct["arguments"] = arguments dct.update(self.kwargs) return dct -@register_response('restart') +@register_response("restart") @register class RestartResponse(BaseSchema): """ @@ -3891,58 +3168,33 @@ class RestartResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -3954,7 +3206,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -3963,7 +3215,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -3973,31 +3224,31 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('disconnect') +@register_request("disconnect") @register class DisconnectRequest(BaseSchema): """ The `disconnect` request asks the debug adapter to disconnect from the debuggee (thus ending the debug session) and then to shut down itself (the debug adapter). - + In addition, the debug adapter must terminate the debuggee if it was started with the `launch` request. If an `attach` request was used to connect to the debuggee, then the debug adapter must not terminate the debuggee. - + This implicit behavior of when to terminate the debuggee can be overridden with the `terminateDebuggee` argument (which is only supported by a debug adapter if the corresponding capability `supportTerminateDebuggee` is true). @@ -4008,57 +3259,48 @@ class DisconnectRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "disconnect" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "DisconnectArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["disconnect"]}, + "arguments": {"type": "DisconnectArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param DisconnectArguments arguments: + :param DisconnectArguments arguments: """ - self.type = 'request' - self.command = 'disconnect' + self.type = "request" + self.command = "disconnect" self.seq = seq if arguments is None: self.arguments = DisconnectArguments() else: - self.arguments = DisconnectArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != DisconnectArguments else arguments + self.arguments = ( + DisconnectArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != DisconnectArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -4074,20 +3316,20 @@ class DisconnectArguments(BaseSchema): __props__ = { "restart": { "type": "boolean", - "description": "A value of True indicates that this `disconnect` request is part of a restart sequence." + "description": "A value of True indicates that this `disconnect` request is part of a restart sequence.", }, "terminateDebuggee": { "type": "boolean", - "description": "Indicates whether the debuggee should be terminated when the debugger is disconnected.\nIf unspecified, the debug adapter is free to do whatever it thinks is best.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportTerminateDebuggee` is True." + "description": "Indicates whether the debuggee should be terminated when the debugger is disconnected.\nIf unspecified, the debug adapter is free to do whatever it thinks is best.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportTerminateDebuggee` is True.", }, "suspendDebuggee": { "type": "boolean", - "description": "Indicates whether the debuggee should stay suspended when the debugger is disconnected.\nIf unspecified, the debuggee should resume execution.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportSuspendDebuggee` is True." - } + "description": "Indicates whether the debuggee should stay suspended when the debugger is disconnected.\nIf unspecified, the debuggee should resume execution.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportSuspendDebuggee` is True.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, restart=None, terminateDebuggee=None, suspendDebuggee=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -4104,24 +3346,22 @@ def __init__(self, restart=None, terminateDebuggee=None, suspendDebuggee=None, u self.suspendDebuggee = suspendDebuggee self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) restart = self.restart terminateDebuggee = self.terminateDebuggee suspendDebuggee = self.suspendDebuggee - dct = { - } + dct = {} if restart is not None: - dct['restart'] = restart + dct["restart"] = restart if terminateDebuggee is not None: - dct['terminateDebuggee'] = terminateDebuggee + dct["terminateDebuggee"] = terminateDebuggee if suspendDebuggee is not None: - dct['suspendDebuggee'] = suspendDebuggee + dct["suspendDebuggee"] = suspendDebuggee dct.update(self.kwargs) return dct -@register_response('disconnect') +@register_response("disconnect") @register class DisconnectResponse(BaseSchema): """ @@ -4133,58 +3373,33 @@ class DisconnectResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -4196,7 +3411,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -4205,7 +3420,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -4215,35 +3429,35 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('terminate') +@register_request("terminate") @register class TerminateRequest(BaseSchema): """ The `terminate` request is sent from the client to the debug adapter in order to shut down the debuggee gracefully. Clients should only call this request if the capability `supportsTerminateRequest` is true. - + Typically a debug adapter implements `terminate` by sending a software signal which the debuggee intercepts in order to clean things up properly before terminating itself. - + Please note that this request does not directly affect the state of the debug session: if the debuggee decides to veto the graceful shutdown for any reason by not terminating itself, then the debug session just continues. - + Clients can surface the `terminate` request as an explicit command or they can integrate it into a two stage Stop command that first sends `terminate` to request a graceful shutdown, and if that fails uses `disconnect` for a forceful shutdown. @@ -4254,57 +3468,48 @@ class TerminateRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "terminate" - ] - }, - "arguments": { - "type": "TerminateArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["terminate"]}, + "arguments": {"type": "TerminateArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param TerminateArguments arguments: + :param TerminateArguments arguments: """ - self.type = 'request' - self.command = 'terminate' + self.type = "request" + self.command = "terminate" self.seq = seq if arguments is None: self.arguments = TerminateArguments() else: - self.arguments = TerminateArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != TerminateArguments else arguments + self.arguments = ( + TerminateArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != TerminateArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -4320,12 +3525,12 @@ class TerminateArguments(BaseSchema): __props__ = { "restart": { "type": "boolean", - "description": "A value of True indicates that this `terminate` request is part of a restart sequence." + "description": "A value of True indicates that this `terminate` request is part of a restart sequence.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, restart=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -4334,18 +3539,16 @@ def __init__(self, restart=None, update_ids_from_dap=False, **kwargs): # noqa ( self.restart = restart self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) restart = self.restart - dct = { - } + dct = {} if restart is not None: - dct['restart'] = restart + dct["restart"] = restart dct.update(self.kwargs) return dct -@register_response('terminate') +@register_response("terminate") @register class TerminateResponse(BaseSchema): """ @@ -4357,58 +3560,33 @@ class TerminateResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -4420,7 +3598,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -4429,7 +3607,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -4439,27 +3616,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('breakpointLocations') +@register_request("breakpointLocations") @register class BreakpointLocationsRequest(BaseSchema): """ The `breakpointLocations` request returns all possible locations for source breakpoints in a given range. - + Clients should only call this request if the corresponding capability `supportsBreakpointLocationsRequest` is true. @@ -4469,57 +3646,48 @@ class BreakpointLocationsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "breakpointLocations" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "BreakpointLocationsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["breakpointLocations"]}, + "arguments": {"type": "BreakpointLocationsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param BreakpointLocationsArguments arguments: + :param BreakpointLocationsArguments arguments: """ - self.type = 'request' - self.command = 'breakpointLocations' + self.type = "request" + self.command = "breakpointLocations" self.seq = seq if arguments is None: self.arguments = BreakpointLocationsArguments() else: - self.arguments = BreakpointLocationsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != BreakpointLocationsArguments else arguments + self.arguments = ( + BreakpointLocationsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != BreakpointLocationsArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -4535,28 +3703,28 @@ class BreakpointLocationsArguments(BaseSchema): __props__ = { "source": { "description": "The source location of the breakpoints; either `source.path` or `source.sourceReference` must be specified.", - "type": "Source" + "type": "Source", }, "line": { "type": "integer", - "description": "Start line of range to search possible breakpoint locations in. If only the line is specified, the request returns all possible locations in that line." + "description": "Start line of range to search possible breakpoint locations in. If only the line is specified, the request returns all possible locations in that line.", }, "column": { "type": "integer", - "description": "Start position within `line` to search possible breakpoint locations in. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based. If no column is given, the first position in the start line is assumed." + "description": "Start position within `line` to search possible breakpoint locations in. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based. If no column is given, the first position in the start line is assumed.", }, "endLine": { "type": "integer", - "description": "End line of range to search possible breakpoint locations in. If no end line is given, then the end line is assumed to be the start line." + "description": "End line of range to search possible breakpoint locations in. If no end line is given, then the end line is assumed to be the start line.", }, "endColumn": { "type": "integer", - "description": "End position within `endLine` to search possible breakpoint locations in. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based. If no end column is given, the last position in the end line is assumed." - } + "description": "End position within `endLine` to search possible breakpoint locations in. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based. If no end column is given, the last position in the end line is assumed.", + }, } - __refs__ = set(['source']) + __refs__ = set(["source"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, source, line, column=None, endLine=None, endColumn=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -4569,14 +3737,13 @@ def __init__(self, source, line, column=None, endLine=None, endColumn=None, upda if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.line = line self.column = column self.endLine = endLine self.endColumn = endColumn self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) source = self.source line = self.line @@ -4584,25 +3751,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un endLine = self.endLine endColumn = self.endColumn dct = { - 'source': source.to_dict(update_ids_to_dap=update_ids_to_dap), - 'line': line, + "source": source.to_dict(update_ids_to_dap=update_ids_to_dap), + "line": line, } if column is not None: - dct['column'] = column + dct["column"] = column if endLine is not None: - dct['endLine'] = endLine + dct["endLine"] = endLine if endColumn is not None: - dct['endColumn'] = endColumn + dct["endColumn"] = endColumn dct.update(self.kwargs) return dct -@register_response('breakpointLocations') +@register_response("breakpointLocations") @register class BreakpointLocationsResponse(BaseSchema): """ Response to `breakpointLocations` request. - + Contains possible locations for source breakpoints. Note: automatically generated code. Do not edit manually. @@ -4611,85 +3778,67 @@ class BreakpointLocationsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/BreakpointLocation" - }, - "description": "Sorted set of possible breakpoint locations." + "items": {"$ref": "#/definitions/BreakpointLocation"}, + "description": "Sorted set of possible breakpoint locations.", } }, - "required": [ - "breakpoints" - ] - } + "required": ["breakpoints"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param BreakpointLocationsResponseBody body: + :param BreakpointLocationsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = BreakpointLocationsResponseBody() else: - self.body = BreakpointLocationsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != BreakpointLocationsResponseBody else body + self.body = ( + BreakpointLocationsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != BreakpointLocationsResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -4699,27 +3848,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('setBreakpoints') +@register_request("setBreakpoints") @register class SetBreakpointsRequest(BaseSchema): """ Sets multiple breakpoints for a single source and clears all previous breakpoints in that source. - + To clear all breakpoint for a source, specify an empty array. - + When a breakpoint is hit, a `stopped` event (with reason `breakpoint`) is generated. Note: automatically generated code. Do not edit manually. @@ -4728,55 +3877,46 @@ class SetBreakpointsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "setBreakpoints" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "SetBreakpointsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setBreakpoints"]}, + "arguments": {"type": "SetBreakpointsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetBreakpointsArguments arguments: + :param string type: + :param string command: + :param SetBreakpointsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setBreakpoints' + self.type = "request" + self.command = "setBreakpoints" if arguments is None: self.arguments = SetBreakpointsArguments() else: - self.arguments = SetBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetBreakpointsArguments else arguments + self.arguments = ( + SetBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetBreakpointsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -4793,30 +3933,22 @@ class SetBreakpointsArguments(BaseSchema): __props__ = { "source": { "description": "The source location of the breakpoints; either `source.path` or `source.sourceReference` must be specified.", - "type": "Source" + "type": "Source", }, "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/SourceBreakpoint" - }, - "description": "The code locations of the breakpoints." - }, - "lines": { - "type": "array", - "items": { - "type": "integer" - }, - "description": "Deprecated: The code locations of the breakpoints." + "items": {"$ref": "#/definitions/SourceBreakpoint"}, + "description": "The code locations of the breakpoints.", }, + "lines": {"type": "array", "items": {"type": "integer"}, "description": "Deprecated: The code locations of the breakpoints."}, "sourceModified": { "type": "boolean", - "description": "A value of True indicates that the underlying source has been modified which results in new breakpoint locations." - } + "description": "A value of True indicates that the underlying source has been modified which results in new breakpoint locations.", + }, } - __refs__ = set(['source']) + __refs__ = set(["source"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, source, breakpoints=None, lines=None, sourceModified=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -4828,7 +3960,7 @@ def __init__(self, source, breakpoints=None, lines=None, sourceModified=None, up if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.breakpoints = breakpoints if update_ids_from_dap and self.breakpoints: for o in self.breakpoints: @@ -4837,7 +3969,6 @@ def __init__(self, source, breakpoints=None, lines=None, sourceModified=None, up self.sourceModified = sourceModified self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) source = self.source breakpoints = self.breakpoints @@ -4848,30 +3979,32 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un lines = [x.to_dict() for x in lines] sourceModified = self.sourceModified dct = { - 'source': source.to_dict(update_ids_to_dap=update_ids_to_dap), + "source": source.to_dict(update_ids_to_dap=update_ids_to_dap), } if breakpoints is not None: - dct['breakpoints'] = [SourceBreakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints + dct["breakpoints"] = ( + [SourceBreakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints + ) if lines is not None: - dct['lines'] = lines + dct["lines"] = lines if sourceModified is not None: - dct['sourceModified'] = sourceModified + dct["sourceModified"] = sourceModified dct.update(self.kwargs) return dct -@register_response('setBreakpoints') +@register_response("setBreakpoints") @register class SetBreakpointsResponse(BaseSchema): """ Response to `setBreakpoints` request. - + Returned is information about each breakpoint created by this request. - + This includes the actual code location and whether the breakpoint could be verified. - + The breakpoints returned are in the same order as the elements of the `breakpoints` - + (or the deprecated `lines`) array in the arguments. Note: automatically generated code. Do not edit manually. @@ -4880,85 +4013,67 @@ class SetBreakpointsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the breakpoints.\nThe array elements are in the same order as the elements of the `breakpoints` (or the deprecated `lines`) array in the arguments." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the breakpoints.\nThe array elements are in the same order as the elements of the `breakpoints` (or the deprecated `lines`) array in the arguments.", } }, - "required": [ - "breakpoints" - ] - } + "required": ["breakpoints"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param SetBreakpointsResponseBody body: + :param SetBreakpointsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = SetBreakpointsResponseBody() else: - self.body = SetBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SetBreakpointsResponseBody else body + self.body = ( + SetBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != SetBreakpointsResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -4968,30 +4083,30 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('setFunctionBreakpoints') +@register_request("setFunctionBreakpoints") @register class SetFunctionBreakpointsRequest(BaseSchema): """ Replaces all existing function breakpoints with new function breakpoints. - + To clear all function breakpoints, specify an empty array. - + When a function breakpoint is hit, a `stopped` event (with reason `function breakpoint`) is generated. - + Clients should only call this request if the corresponding capability `supportsFunctionBreakpoints` is true. @@ -5001,55 +4116,46 @@ class SetFunctionBreakpointsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "setFunctionBreakpoints" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "SetFunctionBreakpointsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setFunctionBreakpoints"]}, + "arguments": {"type": "SetFunctionBreakpointsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetFunctionBreakpointsArguments arguments: + :param string type: + :param string command: + :param SetFunctionBreakpointsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setFunctionBreakpoints' + self.type = "request" + self.command = "setFunctionBreakpoints" if arguments is None: self.arguments = SetFunctionBreakpointsArguments() else: - self.arguments = SetFunctionBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetFunctionBreakpointsArguments else arguments + self.arguments = ( + SetFunctionBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetFunctionBreakpointsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -5066,15 +4172,13 @@ class SetFunctionBreakpointsArguments(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/FunctionBreakpoint" - }, - "description": "The function names of the breakpoints." + "items": {"$ref": "#/definitions/FunctionBreakpoint"}, + "description": "The function names of the breakpoints.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -5086,24 +4190,25 @@ def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (u FunctionBreakpoint.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] dct = { - 'breakpoints': [FunctionBreakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints, + "breakpoints": [FunctionBreakpoint.update_dict_ids_to_dap(o) for o in breakpoints] + if (update_ids_to_dap and breakpoints) + else breakpoints, } dct.update(self.kwargs) return dct -@register_response('setFunctionBreakpoints') +@register_response("setFunctionBreakpoints") @register class SetFunctionBreakpointsResponse(BaseSchema): """ Response to `setFunctionBreakpoints` request. - + Returned is information about each breakpoint created by this request. Note: automatically generated code. Do not edit manually. @@ -5112,85 +4217,67 @@ class SetFunctionBreakpointsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the breakpoints. The array elements correspond to the elements of the `breakpoints` array." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the breakpoints. The array elements correspond to the elements of the `breakpoints` array.", } }, - "required": [ - "breakpoints" - ] - } + "required": ["breakpoints"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param SetFunctionBreakpointsResponseBody body: + :param SetFunctionBreakpointsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = SetFunctionBreakpointsResponseBody() else: - self.body = SetFunctionBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SetFunctionBreakpointsResponseBody else body + self.body = ( + SetFunctionBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != SetFunctionBreakpointsResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -5200,27 +4287,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('setExceptionBreakpoints') +@register_request("setExceptionBreakpoints") @register class SetExceptionBreakpointsRequest(BaseSchema): """ The request configures the debugger's response to thrown exceptions. - + If an exception is configured to break, a `stopped` event is fired (with reason `exception`). - + Clients should only call this request if the corresponding capability `exceptionBreakpointFilters` returns one or more filters. @@ -5230,55 +4317,46 @@ class SetExceptionBreakpointsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "setExceptionBreakpoints" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "SetExceptionBreakpointsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setExceptionBreakpoints"]}, + "arguments": {"type": "SetExceptionBreakpointsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetExceptionBreakpointsArguments arguments: + :param string type: + :param string command: + :param SetExceptionBreakpointsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setExceptionBreakpoints' + self.type = "request" + self.command = "setExceptionBreakpoints" if arguments is None: self.arguments = SetExceptionBreakpointsArguments() else: - self.arguments = SetExceptionBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetExceptionBreakpointsArguments else arguments + self.arguments = ( + SetExceptionBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetExceptionBreakpointsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -5295,29 +4373,23 @@ class SetExceptionBreakpointsArguments(BaseSchema): __props__ = { "filters": { "type": "array", - "items": { - "type": "string" - }, - "description": "Set of exception filters specified by their ID. The set of all possible exception filters is defined by the `exceptionBreakpointFilters` capability. The `filter` and `filterOptions` sets are additive." + "items": {"type": "string"}, + "description": "Set of exception filters specified by their ID. The set of all possible exception filters is defined by the `exceptionBreakpointFilters` capability. The `filter` and `filterOptions` sets are additive.", }, "filterOptions": { "type": "array", - "items": { - "$ref": "#/definitions/ExceptionFilterOptions" - }, - "description": "Set of exception filters and their options. The set of all possible exception filters is defined by the `exceptionBreakpointFilters` capability. This attribute is only honored by a debug adapter if the corresponding capability `supportsExceptionFilterOptions` is True. The `filter` and `filterOptions` sets are additive." + "items": {"$ref": "#/definitions/ExceptionFilterOptions"}, + "description": "Set of exception filters and their options. The set of all possible exception filters is defined by the `exceptionBreakpointFilters` capability. This attribute is only honored by a debug adapter if the corresponding capability `supportsExceptionFilterOptions` is True. The `filter` and `filterOptions` sets are additive.", }, "exceptionOptions": { "type": "array", - "items": { - "$ref": "#/definitions/ExceptionOptions" - }, - "description": "Configuration options for selected exceptions.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsExceptionOptions` is True." - } + "items": {"$ref": "#/definitions/ExceptionOptions"}, + "description": "Configuration options for selected exceptions.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsExceptionOptions` is True.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, filters, filterOptions=None, exceptionOptions=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -5337,7 +4409,6 @@ def __init__(self, filters, filterOptions=None, exceptionOptions=None, update_id ExceptionOptions.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) filters = self.filters if filters and hasattr(filters[0], "to_dict"): @@ -5349,33 +4420,41 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if exceptionOptions and hasattr(exceptionOptions[0], "to_dict"): exceptionOptions = [x.to_dict() for x in exceptionOptions] dct = { - 'filters': filters, + "filters": filters, } if filterOptions is not None: - dct['filterOptions'] = [ExceptionFilterOptions.update_dict_ids_to_dap(o) for o in filterOptions] if (update_ids_to_dap and filterOptions) else filterOptions + dct["filterOptions"] = ( + [ExceptionFilterOptions.update_dict_ids_to_dap(o) for o in filterOptions] + if (update_ids_to_dap and filterOptions) + else filterOptions + ) if exceptionOptions is not None: - dct['exceptionOptions'] = [ExceptionOptions.update_dict_ids_to_dap(o) for o in exceptionOptions] if (update_ids_to_dap and exceptionOptions) else exceptionOptions + dct["exceptionOptions"] = ( + [ExceptionOptions.update_dict_ids_to_dap(o) for o in exceptionOptions] + if (update_ids_to_dap and exceptionOptions) + else exceptionOptions + ) dct.update(self.kwargs) return dct -@register_response('setExceptionBreakpoints') +@register_response("setExceptionBreakpoints") @register class SetExceptionBreakpointsResponse(BaseSchema): """ Response to `setExceptionBreakpoints` request. - + The response contains an array of `Breakpoint` objects with information about each exception breakpoint or filter. The `Breakpoint` objects are in the same order as the elements of the `filters`, `filterOptions`, `exceptionOptions` arrays given as arguments. If both `filters` and `filterOptions` are given, the returned array must start with `filters` information first, followed by `filterOptions` information. - + The `verified` property of a `Breakpoint` object signals whether the exception breakpoint or filter could be successfully created and whether the condition is valid. In case of an error the `message` property explains the problem. The `id` property can be used to introduce a unique ID for the exception breakpoint or filter so that it can be updated subsequently by sending breakpoint events. - + For backward compatibility both the `breakpoints` array and the enclosing `body` are optional. If these elements are missing a client is not able to show problems for individual exception breakpoints or filters. @@ -5386,58 +4465,39 @@ class SetExceptionBreakpointsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the exception breakpoints or filters.\nThe breakpoints returned are in the same order as the elements of the `filters`, `filterOptions`, `exceptionOptions` arrays in the arguments. If both `filters` and `filterOptions` are given, the returned array must start with `filters` information first, followed by `filterOptions` information." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the exception breakpoints or filters.\nThe breakpoints returned are in the same order as the elements of the `filters`, `filterOptions`, `exceptionOptions` arrays in the arguments. If both `filters` and `filterOptions` are given, the returned array must start with `filters` information first, followed by `filterOptions` information.", } - } - } + }, + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -5447,9 +4507,9 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. - :param SetExceptionBreakpointsResponseBody body: + :param SetExceptionBreakpointsResponseBody body: """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -5458,10 +4518,13 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non if body is None: self.body = SetExceptionBreakpointsResponseBody() else: - self.body = SetExceptionBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SetExceptionBreakpointsResponseBody else body + self.body = ( + SetExceptionBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != SetExceptionBreakpointsResponseBody + else body + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -5471,26 +4534,26 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["body"] = body.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct -@register_request('dataBreakpointInfo') +@register_request("dataBreakpointInfo") @register class DataBreakpointInfoRequest(BaseSchema): """ Obtains information on a possible data breakpoint that could be set on an expression or variable. - + Clients should only call this request if the corresponding capability `supportsDataBreakpoints` is true. @@ -5500,55 +4563,46 @@ class DataBreakpointInfoRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "dataBreakpointInfo" - ] - }, - "arguments": { - "type": "DataBreakpointInfoArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["dataBreakpointInfo"]}, + "arguments": {"type": "DataBreakpointInfoArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param DataBreakpointInfoArguments arguments: + :param string type: + :param string command: + :param DataBreakpointInfoArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'dataBreakpointInfo' + self.type = "request" + self.command = "dataBreakpointInfo" if arguments is None: self.arguments = DataBreakpointInfoArguments() else: - self.arguments = DataBreakpointInfoArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != DataBreakpointInfoArguments else arguments + self.arguments = ( + DataBreakpointInfoArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != DataBreakpointInfoArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -5565,20 +4619,20 @@ class DataBreakpointInfoArguments(BaseSchema): __props__ = { "variablesReference": { "type": "integer", - "description": "Reference to the variable container if the data breakpoint is requested for a child of the container. The `variablesReference` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details." + "description": "Reference to the variable container if the data breakpoint is requested for a child of the container. The `variablesReference` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details.", }, "name": { "type": "string", - "description": "The name of the variable's child to obtain data breakpoint information for.\nIf `variablesReference` isn't specified, this can be an expression." + "description": "The name of the variable's child to obtain data breakpoint information for.\nIf `variablesReference` isn't specified, this can be an expression.", }, "frameId": { "type": "integer", - "description": "When `name` is an expression, evaluate it in the scope of this stack frame. If not specified, the expression is evaluated in the global scope. When `variablesReference` is specified, this property has no effect." - } + "description": "When `name` is an expression, evaluate it in the scope of this stack frame. If not specified, the expression is evaluated in the global scope. When `variablesReference` is specified, this property has no effect.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, name, variablesReference=None, frameId=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -5594,14 +4648,13 @@ def __init__(self, name, variablesReference=None, frameId=None, update_ids_from_ self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.frameId = self._translate_id_from_dap(self.frameId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_from_dap(dct['frameId']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_from_dap(dct["frameId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -5614,25 +4667,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if frameId is not None: frameId = self._translate_id_to_dap(frameId) dct = { - 'name': name, + "name": name, } if variablesReference is not None: - dct['variablesReference'] = variablesReference + dct["variablesReference"] = variablesReference if frameId is not None: - dct['frameId'] = frameId + dct["frameId"] = frameId dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_to_dap(dct['frameId']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_to_dap(dct["frameId"]) return dct -@register_response('dataBreakpointInfo') +@register_response("dataBreakpointInfo") @register class DataBreakpointInfoResponse(BaseSchema): """ @@ -5644,101 +4697,79 @@ class DataBreakpointInfoResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "dataId": { - "type": [ - "string", - "null" - ], - "description": "An identifier for the data on which a data breakpoint can be registered with the `setDataBreakpoints` request or null if no data breakpoint is available. If a `variablesReference` or `frameId` is passed, the `dataId` is valid in the current suspended state, otherwise it's valid indefinitely. See 'Lifetime of Object References' in the Overview section for details. Breakpoints set using the `dataId` in the `setDataBreakpoints` request may outlive the lifetime of the associated `dataId`." + "type": ["string", "null"], + "description": "An identifier for the data on which a data breakpoint can be registered with the `setDataBreakpoints` request or null if no data breakpoint is available. If a `variablesReference` or `frameId` is passed, the `dataId` is valid in the current suspended state, otherwise it's valid indefinitely. See 'Lifetime of Object References' in the Overview section for details. Breakpoints set using the `dataId` in the `setDataBreakpoints` request may outlive the lifetime of the associated `dataId`.", }, "description": { "type": "string", - "description": "UI string that describes on what data the breakpoint is set on or why a data breakpoint is not available." + "description": "UI string that describes on what data the breakpoint is set on or why a data breakpoint is not available.", }, "accessTypes": { "type": "array", - "items": { - "$ref": "#/definitions/DataBreakpointAccessType" - }, - "description": "Attribute lists the available access types for a potential data breakpoint. A UI client could surface this information." + "items": {"$ref": "#/definitions/DataBreakpointAccessType"}, + "description": "Attribute lists the available access types for a potential data breakpoint. A UI client could surface this information.", }, "canPersist": { "type": "boolean", - "description": "Attribute indicates that a potential data breakpoint could be persisted across sessions." - } + "description": "Attribute indicates that a potential data breakpoint could be persisted across sessions.", + }, }, - "required": [ - "dataId", - "description" - ] - } + "required": ["dataId", "description"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param DataBreakpointInfoResponseBody body: + :param DataBreakpointInfoResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = DataBreakpointInfoResponseBody() else: - self.body = DataBreakpointInfoResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != DataBreakpointInfoResponseBody else body + self.body = ( + DataBreakpointInfoResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != DataBreakpointInfoResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -5748,29 +4779,29 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('setDataBreakpoints') +@register_request("setDataBreakpoints") @register class SetDataBreakpointsRequest(BaseSchema): """ Replaces all existing data breakpoints with new data breakpoints. - + To clear all data breakpoints, specify an empty array. - + When a data breakpoint is hit, a `stopped` event (with reason `data breakpoint`) is generated. - + Clients should only call this request if the corresponding capability `supportsDataBreakpoints` is true. @@ -5780,55 +4811,46 @@ class SetDataBreakpointsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "setDataBreakpoints" - ] - }, - "arguments": { - "type": "SetDataBreakpointsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setDataBreakpoints"]}, + "arguments": {"type": "SetDataBreakpointsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetDataBreakpointsArguments arguments: + :param string type: + :param string command: + :param SetDataBreakpointsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setDataBreakpoints' + self.type = "request" + self.command = "setDataBreakpoints" if arguments is None: self.arguments = SetDataBreakpointsArguments() else: - self.arguments = SetDataBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetDataBreakpointsArguments else arguments + self.arguments = ( + SetDataBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetDataBreakpointsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -5845,15 +4867,13 @@ class SetDataBreakpointsArguments(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/DataBreakpoint" - }, - "description": "The contents of this array replaces all existing data breakpoints. An empty array clears all data breakpoints." + "items": {"$ref": "#/definitions/DataBreakpoint"}, + "description": "The contents of this array replaces all existing data breakpoints. An empty array clears all data breakpoints.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -5865,24 +4885,25 @@ def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (u DataBreakpoint.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] dct = { - 'breakpoints': [DataBreakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints, + "breakpoints": [DataBreakpoint.update_dict_ids_to_dap(o) for o in breakpoints] + if (update_ids_to_dap and breakpoints) + else breakpoints, } dct.update(self.kwargs) return dct -@register_response('setDataBreakpoints') +@register_response("setDataBreakpoints") @register class SetDataBreakpointsResponse(BaseSchema): """ Response to `setDataBreakpoints` request. - + Returned is information about each breakpoint created by this request. Note: automatically generated code. Do not edit manually. @@ -5891,85 +4912,67 @@ class SetDataBreakpointsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the data breakpoints. The array elements correspond to the elements of the input argument `breakpoints` array." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the data breakpoints. The array elements correspond to the elements of the input argument `breakpoints` array.", } }, - "required": [ - "breakpoints" - ] - } + "required": ["breakpoints"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param SetDataBreakpointsResponseBody body: + :param SetDataBreakpointsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = SetDataBreakpointsResponseBody() else: - self.body = SetDataBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SetDataBreakpointsResponseBody else body + self.body = ( + SetDataBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != SetDataBreakpointsResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -5979,31 +4982,31 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('setInstructionBreakpoints') +@register_request("setInstructionBreakpoints") @register class SetInstructionBreakpointsRequest(BaseSchema): """ Replaces all existing instruction breakpoints. Typically, instruction breakpoints would be set from a disassembly window. - + To clear all instruction breakpoints, specify an empty array. - + When an instruction breakpoint is hit, a `stopped` event (with reason `instruction breakpoint`) is generated. - + Clients should only call this request if the corresponding capability `supportsInstructionBreakpoints` is true. @@ -6013,55 +5016,46 @@ class SetInstructionBreakpointsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "setInstructionBreakpoints" - ] - }, - "arguments": { - "type": "SetInstructionBreakpointsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setInstructionBreakpoints"]}, + "arguments": {"type": "SetInstructionBreakpointsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetInstructionBreakpointsArguments arguments: + :param string type: + :param string command: + :param SetInstructionBreakpointsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setInstructionBreakpoints' + self.type = "request" + self.command = "setInstructionBreakpoints" if arguments is None: self.arguments = SetInstructionBreakpointsArguments() else: - self.arguments = SetInstructionBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetInstructionBreakpointsArguments else arguments + self.arguments = ( + SetInstructionBreakpointsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetInstructionBreakpointsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -6078,15 +5072,13 @@ class SetInstructionBreakpointsArguments(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/InstructionBreakpoint" - }, - "description": "The instruction references of the breakpoints" + "items": {"$ref": "#/definitions/InstructionBreakpoint"}, + "description": "The instruction references of the breakpoints", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -6098,19 +5090,20 @@ def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (u InstructionBreakpoint.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] dct = { - 'breakpoints': [InstructionBreakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints, + "breakpoints": [InstructionBreakpoint.update_dict_ids_to_dap(o) for o in breakpoints] + if (update_ids_to_dap and breakpoints) + else breakpoints, } dct.update(self.kwargs) return dct -@register_response('setInstructionBreakpoints') +@register_response("setInstructionBreakpoints") @register class SetInstructionBreakpointsResponse(BaseSchema): """ @@ -6122,85 +5115,67 @@ class SetInstructionBreakpointsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the breakpoints. The array elements correspond to the elements of the `breakpoints` array." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the breakpoints. The array elements correspond to the elements of the `breakpoints` array.", } }, - "required": [ - "breakpoints" - ] - } + "required": ["breakpoints"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param SetInstructionBreakpointsResponseBody body: + :param SetInstructionBreakpointsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = SetInstructionBreakpointsResponseBody() else: - self.body = SetInstructionBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SetInstructionBreakpointsResponseBody else body + self.body = ( + SetInstructionBreakpointsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != SetInstructionBreakpointsResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -6210,20 +5185,20 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('continue') +@register_request("continue") @register class ContinueRequest(BaseSchema): """ @@ -6238,55 +5213,46 @@ class ContinueRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "continue" - ] - }, - "arguments": { - "type": "ContinueArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["continue"]}, + "arguments": {"type": "ContinueArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param ContinueArguments arguments: + :param string type: + :param string command: + :param ContinueArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'continue' + self.type = "request" + self.command = "continue" if arguments is None: self.arguments = ContinueArguments() else: - self.arguments = ContinueArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != ContinueArguments else arguments + self.arguments = ( + ContinueArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != ContinueArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -6303,16 +5269,16 @@ class ContinueArguments(BaseSchema): __props__ = { "threadId": { "type": "integer", - "description": "Specifies the active thread. If the debug adapter supports single thread execution (see `supportsSingleThreadExecutionRequests`) and the argument `singleThread` is True, only the thread with this ID is resumed." + "description": "Specifies the active thread. If the debug adapter supports single thread execution (see `supportsSingleThreadExecutionRequests`) and the argument `singleThread` is True, only the thread with this ID is resumed.", }, "singleThread": { "type": "boolean", - "description": "If this flag is True, execution is resumed only for the thread with given `threadId`." - } + "description": "If this flag is True, execution is resumed only for the thread with given `threadId`.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, singleThread=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -6324,12 +5290,11 @@ def __init__(self, threadId, singleThread=None, update_ids_from_dap=False, **kwa if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -6339,21 +5304,21 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } if singleThread is not None: - dct['singleThread'] = singleThread + dct["singleThread"] = singleThread dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('continue') +@register_response("continue") @register class ContinueResponse(BaseSchema): """ @@ -6365,79 +5330,63 @@ class ContinueResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "allThreadsContinued": { "type": "boolean", - "description": "The value True (or a missing property) signals to the client that all threads have been resumed. The value false indicates that not all threads were resumed." + "description": "The value True (or a missing property) signals to the client that all threads have been resumed. The value false indicates that not all threads were resumed.", } - } - } + }, + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param ContinueResponseBody body: + :param ContinueResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = ContinueResponseBody() else: - self.body = ContinueResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ContinueResponseBody else body + self.body = ( + ContinueResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ContinueResponseBody else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -6447,30 +5396,30 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('next') +@register_request("next") @register class NextRequest(BaseSchema): """ The request executes one step (in the given granularity) for the specified thread and allows all other threads to run freely by resuming them. - + If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming. - + The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed. @@ -6480,55 +5429,44 @@ class NextRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "next" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "NextArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["next"]}, + "arguments": {"type": "NextArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param NextArguments arguments: + :param string type: + :param string command: + :param NextArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'next' + self.type = "request" + self.command = "next" if arguments is None: self.arguments = NextArguments() else: - self.arguments = NextArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != NextArguments else arguments + self.arguments = ( + NextArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != NextArguments else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -6545,20 +5483,17 @@ class NextArguments(BaseSchema): __props__ = { "threadId": { "type": "integer", - "description": "Specifies the thread for which to resume execution for one step (of the given granularity)." - }, - "singleThread": { - "type": "boolean", - "description": "If this flag is True, all other suspended threads are not resumed." + "description": "Specifies the thread for which to resume execution for one step (of the given granularity).", }, + "singleThread": {"type": "boolean", "description": "If this flag is True, all other suspended threads are not resumed."}, "granularity": { "description": "Stepping granularity. If no granularity is specified, a granularity of `statement` is assumed.", - "type": "SteppingGranularity" - } + "type": "SteppingGranularity", + }, } - __refs__ = set(['granularity']) + __refs__ = set(["granularity"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, singleThread=None, granularity=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -6574,12 +5509,11 @@ def __init__(self, threadId, singleThread=None, granularity=None, update_ids_fro if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -6590,23 +5524,23 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } if singleThread is not None: - dct['singleThread'] = singleThread + dct["singleThread"] = singleThread if granularity is not None: - dct['granularity'] = granularity + dct["granularity"] = granularity dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('next') +@register_response("next") @register class NextResponse(BaseSchema): """ @@ -6618,58 +5552,33 @@ class NextResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -6681,7 +5590,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -6690,7 +5599,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -6700,40 +5608,40 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('stepIn') +@register_request("stepIn") @register class StepInRequest(BaseSchema): """ The request resumes the given thread to step into a function/method and allows all other threads to run freely by resuming them. - + If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming. - + If the request cannot step into a target, `stepIn` behaves like the `next` request. - + The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed. - + If there are multiple function/method calls (or other targets) on the source line, - + the argument `targetId` can be used to control into which target the `stepIn` should occur. - + The list of possible targets for a given source line can be retrieved via the `stepInTargets` request. @@ -6743,55 +5651,46 @@ class StepInRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "stepIn" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "StepInArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["stepIn"]}, + "arguments": {"type": "StepInArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param StepInArguments arguments: + :param string type: + :param string command: + :param StepInArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'stepIn' + self.type = "request" + self.command = "stepIn" if arguments is None: self.arguments = StepInArguments() else: - self.arguments = StepInArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != StepInArguments else arguments + self.arguments = ( + StepInArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != StepInArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -6808,24 +5707,18 @@ class StepInArguments(BaseSchema): __props__ = { "threadId": { "type": "integer", - "description": "Specifies the thread for which to resume execution for one step-into (of the given granularity)." - }, - "singleThread": { - "type": "boolean", - "description": "If this flag is True, all other suspended threads are not resumed." - }, - "targetId": { - "type": "integer", - "description": "Id of the target to step into." + "description": "Specifies the thread for which to resume execution for one step-into (of the given granularity).", }, + "singleThread": {"type": "boolean", "description": "If this flag is True, all other suspended threads are not resumed."}, + "targetId": {"type": "integer", "description": "Id of the target to step into."}, "granularity": { "description": "Stepping granularity. If no granularity is specified, a granularity of `statement` is assumed.", - "type": "SteppingGranularity" - } + "type": "SteppingGranularity", + }, } - __refs__ = set(['granularity']) + __refs__ = set(["granularity"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, singleThread=None, targetId=None, granularity=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -6843,12 +5736,11 @@ def __init__(self, threadId, singleThread=None, targetId=None, granularity=None, if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -6860,25 +5752,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } if singleThread is not None: - dct['singleThread'] = singleThread + dct["singleThread"] = singleThread if targetId is not None: - dct['targetId'] = targetId + dct["targetId"] = targetId if granularity is not None: - dct['granularity'] = granularity + dct["granularity"] = granularity dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('stepIn') +@register_response("stepIn") @register class StepInResponse(BaseSchema): """ @@ -6890,58 +5782,33 @@ class StepInResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -6953,7 +5820,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -6962,7 +5829,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -6972,31 +5838,31 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('stepOut') +@register_request("stepOut") @register class StepOutRequest(BaseSchema): """ The request resumes the given thread to step out (return) from a function/method and allows all other threads to run freely by resuming them. - + If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming. - + The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed. @@ -7006,55 +5872,46 @@ class StepOutRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "stepOut" - ] - }, - "arguments": { - "type": "StepOutArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["stepOut"]}, + "arguments": {"type": "StepOutArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param StepOutArguments arguments: + :param string type: + :param string command: + :param StepOutArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'stepOut' + self.type = "request" + self.command = "stepOut" if arguments is None: self.arguments = StepOutArguments() else: - self.arguments = StepOutArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != StepOutArguments else arguments + self.arguments = ( + StepOutArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != StepOutArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -7071,20 +5928,17 @@ class StepOutArguments(BaseSchema): __props__ = { "threadId": { "type": "integer", - "description": "Specifies the thread for which to resume execution for one step-out (of the given granularity)." - }, - "singleThread": { - "type": "boolean", - "description": "If this flag is True, all other suspended threads are not resumed." + "description": "Specifies the thread for which to resume execution for one step-out (of the given granularity).", }, + "singleThread": {"type": "boolean", "description": "If this flag is True, all other suspended threads are not resumed."}, "granularity": { "description": "Stepping granularity. If no granularity is specified, a granularity of `statement` is assumed.", - "type": "SteppingGranularity" - } + "type": "SteppingGranularity", + }, } - __refs__ = set(['granularity']) + __refs__ = set(["granularity"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, singleThread=None, granularity=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -7100,12 +5954,11 @@ def __init__(self, threadId, singleThread=None, granularity=None, update_ids_fro if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -7116,23 +5969,23 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } if singleThread is not None: - dct['singleThread'] = singleThread + dct["singleThread"] = singleThread if granularity is not None: - dct['granularity'] = granularity + dct["granularity"] = granularity dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('stepOut') +@register_response("stepOut") @register class StepOutResponse(BaseSchema): """ @@ -7144,58 +5997,33 @@ class StepOutResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -7207,7 +6035,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -7216,7 +6044,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -7226,34 +6053,34 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('stepBack') +@register_request("stepBack") @register class StepBackRequest(BaseSchema): """ The request executes one backward step (in the given granularity) for the specified thread and allows all other threads to run backward freely by resuming them. - + If the debug adapter supports single thread execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true prevents other suspended threads from resuming. - + The debug adapter first sends the response and then a `stopped` event (with reason `step`) after the step has completed. - + Clients should only call this request if the corresponding capability `supportsStepBack` is true. Note: automatically generated code. Do not edit manually. @@ -7262,55 +6089,46 @@ class StepBackRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "stepBack" - ] - }, - "arguments": { - "type": "StepBackArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["stepBack"]}, + "arguments": {"type": "StepBackArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param StepBackArguments arguments: + :param string type: + :param string command: + :param StepBackArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'stepBack' + self.type = "request" + self.command = "stepBack" if arguments is None: self.arguments = StepBackArguments() else: - self.arguments = StepBackArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != StepBackArguments else arguments + self.arguments = ( + StepBackArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != StepBackArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -7327,20 +6145,17 @@ class StepBackArguments(BaseSchema): __props__ = { "threadId": { "type": "integer", - "description": "Specifies the thread for which to resume execution for one step backwards (of the given granularity)." - }, - "singleThread": { - "type": "boolean", - "description": "If this flag is True, all other suspended threads are not resumed." + "description": "Specifies the thread for which to resume execution for one step backwards (of the given granularity).", }, + "singleThread": {"type": "boolean", "description": "If this flag is True, all other suspended threads are not resumed."}, "granularity": { "description": "Stepping granularity to step. If no granularity is specified, a granularity of `statement` is assumed.", - "type": "SteppingGranularity" - } + "type": "SteppingGranularity", + }, } - __refs__ = set(['granularity']) + __refs__ = set(["granularity"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, singleThread=None, granularity=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -7356,12 +6171,11 @@ def __init__(self, threadId, singleThread=None, granularity=None, update_ids_fro if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -7372,23 +6186,23 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } if singleThread is not None: - dct['singleThread'] = singleThread + dct["singleThread"] = singleThread if granularity is not None: - dct['granularity'] = granularity + dct["granularity"] = granularity dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('stepBack') +@register_response("stepBack") @register class StepBackResponse(BaseSchema): """ @@ -7400,58 +6214,33 @@ class StepBackResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -7463,7 +6252,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -7472,7 +6261,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -7482,21 +6270,21 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('reverseContinue') +@register_request("reverseContinue") @register class ReverseContinueRequest(BaseSchema): """ @@ -7504,7 +6292,7 @@ class ReverseContinueRequest(BaseSchema): execution (see capability `supportsSingleThreadExecutionRequests`), setting the `singleThread` argument to true resumes only the specified thread. If not all threads were resumed, the `allThreadsContinued` attribute of the response should be set to false. - + Clients should only call this request if the corresponding capability `supportsStepBack` is true. Note: automatically generated code. Do not edit manually. @@ -7513,55 +6301,46 @@ class ReverseContinueRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "reverseContinue" - ] - }, - "arguments": { - "type": "ReverseContinueArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["reverseContinue"]}, + "arguments": {"type": "ReverseContinueArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param ReverseContinueArguments arguments: + :param string type: + :param string command: + :param ReverseContinueArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'reverseContinue' + self.type = "request" + self.command = "reverseContinue" if arguments is None: self.arguments = ReverseContinueArguments() else: - self.arguments = ReverseContinueArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != ReverseContinueArguments else arguments + self.arguments = ( + ReverseContinueArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != ReverseContinueArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -7578,16 +6357,16 @@ class ReverseContinueArguments(BaseSchema): __props__ = { "threadId": { "type": "integer", - "description": "Specifies the active thread. If the debug adapter supports single thread execution (see `supportsSingleThreadExecutionRequests`) and the `singleThread` argument is True, only the thread with this ID is resumed." + "description": "Specifies the active thread. If the debug adapter supports single thread execution (see `supportsSingleThreadExecutionRequests`) and the `singleThread` argument is True, only the thread with this ID is resumed.", }, "singleThread": { "type": "boolean", - "description": "If this flag is True, backward execution is resumed only for the thread with given `threadId`." - } + "description": "If this flag is True, backward execution is resumed only for the thread with given `threadId`.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, singleThread=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -7599,12 +6378,11 @@ def __init__(self, threadId, singleThread=None, update_ids_from_dap=False, **kwa if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -7614,21 +6392,21 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } if singleThread is not None: - dct['singleThread'] = singleThread + dct["singleThread"] = singleThread dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('reverseContinue') +@register_response("reverseContinue") @register class ReverseContinueResponse(BaseSchema): """ @@ -7641,58 +6419,33 @@ class ReverseContinueResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -7704,7 +6457,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -7713,7 +6466,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -7723,29 +6475,29 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('restartFrame') +@register_request("restartFrame") @register class RestartFrameRequest(BaseSchema): """ The request restarts execution of the specified stack frame. - + The debug adapter first sends the response and then a `stopped` event (with reason `restart`) after the restart has completed. - + Clients should only call this request if the corresponding capability `supportsRestartFrame` is true. @@ -7755,55 +6507,46 @@ class RestartFrameRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "restartFrame" - ] - }, - "arguments": { - "type": "RestartFrameArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["restartFrame"]}, + "arguments": {"type": "RestartFrameArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param RestartFrameArguments arguments: + :param string type: + :param string command: + :param RestartFrameArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'restartFrame' + self.type = "request" + self.command = "restartFrame" if arguments is None: self.arguments = RestartFrameArguments() else: - self.arguments = RestartFrameArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != RestartFrameArguments else arguments + self.arguments = ( + RestartFrameArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != RestartFrameArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -7820,12 +6563,12 @@ class RestartFrameArguments(BaseSchema): __props__ = { "frameId": { "type": "integer", - "description": "Restart the stack frame identified by `frameId`. The `frameId` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details." + "description": "Restart the stack frame identified by `frameId`. The `frameId` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, frameId, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -7835,12 +6578,11 @@ def __init__(self, frameId, update_ids_from_dap=False, **kwargs): # noqa (updat if update_ids_from_dap: self.frameId = self._translate_id_from_dap(self.frameId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_from_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_from_dap(dct["frameId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -7849,19 +6591,19 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if frameId is not None: frameId = self._translate_id_to_dap(frameId) dct = { - 'frameId': frameId, + "frameId": frameId, } dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_to_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_to_dap(dct["frameId"]) return dct -@register_response('restartFrame') +@register_response("restartFrame") @register class RestartFrameResponse(BaseSchema): """ @@ -7873,58 +6615,33 @@ class RestartFrameResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -7936,7 +6653,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -7945,7 +6662,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -7955,32 +6671,32 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('goto') +@register_request("goto") @register class GotoRequest(BaseSchema): """ The request sets the location where the debuggee will continue to run. - + This makes it possible to skip the execution of code or to execute code again. - + The code between the current location and the goto target is not executed but skipped. - + The debug adapter first sends the response and then a `stopped` event with reason `goto`. - + Clients should only call this request if the corresponding capability `supportsGotoTargetsRequest` is true (because only then goto targets exist that can be passed as arguments). @@ -7990,55 +6706,44 @@ class GotoRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "goto" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "GotoArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["goto"]}, + "arguments": {"type": "GotoArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param GotoArguments arguments: + :param string type: + :param string command: + :param GotoArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'goto' + self.type = "request" + self.command = "goto" if arguments is None: self.arguments = GotoArguments() else: - self.arguments = GotoArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != GotoArguments else arguments + self.arguments = ( + GotoArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != GotoArguments else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -8053,18 +6758,12 @@ class GotoArguments(BaseSchema): """ __props__ = { - "threadId": { - "type": "integer", - "description": "Set the goto target for this thread." - }, - "targetId": { - "type": "integer", - "description": "The location where the debuggee will continue to run." - } + "threadId": {"type": "integer", "description": "Set the goto target for this thread."}, + "targetId": {"type": "integer", "description": "The location where the debuggee will continue to run."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, targetId, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -8076,12 +6775,11 @@ def __init__(self, threadId, targetId, update_ids_from_dap=False, **kwargs): # if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -8091,20 +6789,20 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, - 'targetId': targetId, + "threadId": threadId, + "targetId": targetId, } dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('goto') +@register_response("goto") @register class GotoResponse(BaseSchema): """ @@ -8116,58 +6814,33 @@ class GotoResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -8179,7 +6852,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -8188,7 +6861,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -8198,26 +6870,26 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('pause') +@register_request("pause") @register class PauseRequest(BaseSchema): """ The request suspends the debuggee. - + The debug adapter first sends the response and then a `stopped` event (with reason `pause`) after the thread has been paused successfully. @@ -8227,55 +6899,44 @@ class PauseRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "pause" - ] - }, - "arguments": { - "type": "PauseArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["pause"]}, + "arguments": {"type": "PauseArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param PauseArguments arguments: + :param string type: + :param string command: + :param PauseArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'pause' + self.type = "request" + self.command = "pause" if arguments is None: self.arguments = PauseArguments() else: - self.arguments = PauseArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != PauseArguments else arguments + self.arguments = ( + PauseArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != PauseArguments else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -8289,15 +6950,10 @@ class PauseArguments(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "threadId": { - "type": "integer", - "description": "Pause execution for this thread." - } - } + __props__ = {"threadId": {"type": "integer", "description": "Pause execution for this thread."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -8307,12 +6963,11 @@ def __init__(self, threadId, update_ids_from_dap=False, **kwargs): # noqa (upda if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -8321,19 +6976,19 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('pause') +@register_response("pause") @register class PauseResponse(BaseSchema): """ @@ -8345,58 +7000,33 @@ class PauseResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -8408,7 +7038,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -8417,7 +7047,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -8427,26 +7056,26 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('stackTrace') +@register_request("stackTrace") @register class StackTraceRequest(BaseSchema): """ The request returns a stacktrace from the current execution state of a given thread. - + A client can request all stack frames by omitting the startFrame and levels arguments. For performance-conscious clients and if the corresponding capability `supportsDelayedStackTraceLoading` is true, stack frames can be retrieved in a piecemeal way with the `startFrame` and `levels` @@ -8462,55 +7091,46 @@ class StackTraceRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "stackTrace" - ] - }, - "arguments": { - "type": "StackTraceArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["stackTrace"]}, + "arguments": {"type": "StackTraceArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param StackTraceArguments arguments: + :param string type: + :param string command: + :param StackTraceArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'stackTrace' + self.type = "request" + self.command = "stackTrace" if arguments is None: self.arguments = StackTraceArguments() else: - self.arguments = StackTraceArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != StackTraceArguments else arguments + self.arguments = ( + StackTraceArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != StackTraceArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -8525,26 +7145,20 @@ class StackTraceArguments(BaseSchema): """ __props__ = { - "threadId": { - "type": "integer", - "description": "Retrieve the stacktrace for this thread." - }, - "startFrame": { - "type": "integer", - "description": "The index of the first frame to return; if omitted frames start at 0." - }, + "threadId": {"type": "integer", "description": "Retrieve the stacktrace for this thread."}, + "startFrame": {"type": "integer", "description": "The index of the first frame to return; if omitted frames start at 0."}, "levels": { "type": "integer", - "description": "The maximum number of frames to return. If levels is not specified or 0, all frames are returned." + "description": "The maximum number of frames to return. If levels is not specified or 0, all frames are returned.", }, "format": { "description": "Specifies details on how to format the stack frames.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsValueFormattingOptions` is True.", - "type": "StackFrameFormat" - } + "type": "StackFrameFormat", + }, } - __refs__ = set(['format']) + __refs__ = set(["format"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, startFrame=None, levels=None, format=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -8560,16 +7174,17 @@ def __init__(self, threadId, startFrame=None, levels=None, format=None, update_i if format is None: self.format = StackFrameFormat() else: - self.format = StackFrameFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != StackFrameFormat else format + self.format = ( + StackFrameFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != StackFrameFormat else format + ) if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -8581,25 +7196,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } if startFrame is not None: - dct['startFrame'] = startFrame + dct["startFrame"] = startFrame if levels is not None: - dct['levels'] = levels + dct["levels"] = levels if format is not None: - dct['format'] = format.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["format"] = format.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('stackTrace') +@register_response("stackTrace") @register class StackTraceResponse(BaseSchema): """ @@ -8611,89 +7226,71 @@ class StackTraceResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "stackFrames": { "type": "array", - "items": { - "$ref": "#/definitions/StackFrame" - }, - "description": "The frames of the stack frame. If the array has length zero, there are no stack frames available.\nThis means that there is no location information available." + "items": {"$ref": "#/definitions/StackFrame"}, + "description": "The frames of the stack frame. If the array has length zero, there are no stack frames available.\nThis means that there is no location information available.", }, "totalFrames": { "type": "integer", - "description": "The total number of frames available in the stack. If omitted or if `totalFrames` is larger than the available frames, a client is expected to request frames until a request returns less frames than requested (which indicates the end of the stack). Returning monotonically increasing `totalFrames` values for subsequent requests can be used to enforce paging in the client." - } + "description": "The total number of frames available in the stack. If omitted or if `totalFrames` is larger than the available frames, a client is expected to request frames until a request returns less frames than requested (which indicates the end of the stack). Returning monotonically increasing `totalFrames` values for subsequent requests can be used to enforce paging in the client.", + }, }, - "required": [ - "stackFrames" - ] - } + "required": ["stackFrames"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param StackTraceResponseBody body: + :param StackTraceResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = StackTraceResponseBody() else: - self.body = StackTraceResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != StackTraceResponseBody else body + self.body = ( + StackTraceResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != StackTraceResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -8703,20 +7300,20 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('scopes') +@register_request("scopes") @register class ScopesRequest(BaseSchema): """ @@ -8728,55 +7325,46 @@ class ScopesRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "scopes" - ] - }, - "arguments": { - "type": "ScopesArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["scopes"]}, + "arguments": {"type": "ScopesArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param ScopesArguments arguments: + :param string type: + :param string command: + :param ScopesArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'scopes' + self.type = "request" + self.command = "scopes" if arguments is None: self.arguments = ScopesArguments() else: - self.arguments = ScopesArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != ScopesArguments else arguments + self.arguments = ( + ScopesArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != ScopesArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -8793,12 +7381,12 @@ class ScopesArguments(BaseSchema): __props__ = { "frameId": { "type": "integer", - "description": "Retrieve the scopes for the stack frame identified by `frameId`. The `frameId` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details." + "description": "Retrieve the scopes for the stack frame identified by `frameId`. The `frameId` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, frameId, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -8808,12 +7396,11 @@ def __init__(self, frameId, update_ids_from_dap=False, **kwargs): # noqa (updat if update_ids_from_dap: self.frameId = self._translate_id_from_dap(self.frameId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_from_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_from_dap(dct["frameId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -8822,19 +7409,19 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if frameId is not None: frameId = self._translate_id_to_dap(frameId) dct = { - 'frameId': frameId, + "frameId": frameId, } dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_to_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_to_dap(dct["frameId"]) return dct -@register_response('scopes') +@register_response("scopes") @register class ScopesResponse(BaseSchema): """ @@ -8846,85 +7433,65 @@ class ScopesResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "scopes": { "type": "array", - "items": { - "$ref": "#/definitions/Scope" - }, - "description": "The scopes of the stack frame. If the array has length zero, there are no scopes available." + "items": {"$ref": "#/definitions/Scope"}, + "description": "The scopes of the stack frame. If the array has length zero, there are no scopes available.", } }, - "required": [ - "scopes" - ] - } + "required": ["scopes"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param ScopesResponseBody body: + :param ScopesResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = ScopesResponseBody() else: - self.body = ScopesResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ScopesResponseBody else body + self.body = ( + ScopesResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ScopesResponseBody else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -8934,25 +7501,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('variables') +@register_request("variables") @register class VariablesRequest(BaseSchema): """ Retrieves all child variables for the given variable reference. - + A filter can be used to limit the fetched children to either named or indexed children. Note: automatically generated code. Do not edit manually. @@ -8961,55 +7528,46 @@ class VariablesRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "variables" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "VariablesArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["variables"]}, + "arguments": {"type": "VariablesArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param VariablesArguments arguments: + :param string type: + :param string command: + :param VariablesArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'variables' + self.type = "request" + self.command = "variables" if arguments is None: self.arguments = VariablesArguments() else: - self.arguments = VariablesArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != VariablesArguments else arguments + self.arguments = ( + VariablesArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != VariablesArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -9026,32 +7584,29 @@ class VariablesArguments(BaseSchema): __props__ = { "variablesReference": { "type": "integer", - "description": "The variable for which to retrieve its children. The `variablesReference` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details." + "description": "The variable for which to retrieve its children. The `variablesReference` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details.", }, "filter": { "type": "string", - "enum": [ - "indexed", - "named" - ], - "description": "Filter to limit the child variables to either named or indexed. If omitted, both types are fetched." + "enum": ["indexed", "named"], + "description": "Filter to limit the child variables to either named or indexed. If omitted, both types are fetched.", }, "start": { "type": "integer", - "description": "The index of the first variable to return; if omitted children start at 0.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsVariablePaging` is True." + "description": "The index of the first variable to return; if omitted children start at 0.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsVariablePaging` is True.", }, "count": { "type": "integer", - "description": "The number of variables to return. If count is missing or 0, all variables are returned.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsVariablePaging` is True." + "description": "The number of variables to return. If count is missing or 0, all variables are returned.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsVariablePaging` is True.", }, "format": { "description": "Specifies details on how to format the Variable values.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsValueFormattingOptions` is True.", - "type": "ValueFormat" - } + "type": "ValueFormat", + }, } - __refs__ = set(['format']) + __refs__ = set(["format"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, variablesReference, filter=None, start=None, count=None, format=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -9071,16 +7626,15 @@ def __init__(self, variablesReference, filter=None, start=None, count=None, form if format is None: self.format = ValueFormat() else: - self.format = ValueFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != ValueFormat else format + self.format = ValueFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != ValueFormat else format if update_ids_from_dap: self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -9093,27 +7647,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if variablesReference is not None: variablesReference = self._translate_id_to_dap(variablesReference) dct = { - 'variablesReference': variablesReference, + "variablesReference": variablesReference, } if filter is not None: - dct['filter'] = filter + dct["filter"] = filter if start is not None: - dct['start'] = start + dct["start"] = start if count is not None: - dct['count'] = count + dct["count"] = count if format is not None: - dct['format'] = format.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["format"] = format.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) return dct -@register_response('variables') +@register_response("variables") @register class VariablesResponse(BaseSchema): """ @@ -9125,85 +7679,65 @@ class VariablesResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "variables": { "type": "array", - "items": { - "$ref": "#/definitions/Variable" - }, - "description": "All (or a range) of variables for the given variable reference." + "items": {"$ref": "#/definitions/Variable"}, + "description": "All (or a range) of variables for the given variable reference.", } }, - "required": [ - "variables" - ] - } + "required": ["variables"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param VariablesResponseBody body: + :param VariablesResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = VariablesResponseBody() else: - self.body = VariablesResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != VariablesResponseBody else body + self.body = ( + VariablesResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != VariablesResponseBody else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -9213,26 +7747,26 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('setVariable') +@register_request("setVariable") @register class SetVariableRequest(BaseSchema): """ Set the variable with the given name in the variable container to a new value. Clients should only call this request if the corresponding capability `supportsSetVariable` is true. - + If a debug adapter implements both `setVariable` and `setExpression`, a client will only use `setExpression` if the variable has an `evaluateName` property. @@ -9242,55 +7776,46 @@ class SetVariableRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "setVariable" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "SetVariableArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setVariable"]}, + "arguments": {"type": "SetVariableArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetVariableArguments arguments: + :param string type: + :param string command: + :param SetVariableArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setVariable' + self.type = "request" + self.command = "setVariable" if arguments is None: self.arguments = SetVariableArguments() else: - self.arguments = SetVariableArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetVariableArguments else arguments + self.arguments = ( + SetVariableArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetVariableArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -9307,24 +7832,15 @@ class SetVariableArguments(BaseSchema): __props__ = { "variablesReference": { "type": "integer", - "description": "The reference of the variable container. The `variablesReference` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details." - }, - "name": { - "type": "string", - "description": "The name of the variable in the container." - }, - "value": { - "type": "string", - "description": "The value of the variable." + "description": "The reference of the variable container. The `variablesReference` must have been obtained in the current suspended state. See 'Lifetime of Object References' in the Overview section for details.", }, - "format": { - "description": "Specifies details on how to format the response value.", - "type": "ValueFormat" - } + "name": {"type": "string", "description": "The name of the variable in the container."}, + "value": {"type": "string", "description": "The value of the variable."}, + "format": {"description": "Specifies details on how to format the response value.", "type": "ValueFormat"}, } - __refs__ = set(['format']) + __refs__ = set(["format"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, variablesReference, name, value, format=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -9339,16 +7855,15 @@ def __init__(self, variablesReference, name, value, format=None, update_ids_from if format is None: self.format = ValueFormat() else: - self.format = ValueFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != ValueFormat else format + self.format = ValueFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != ValueFormat else format if update_ids_from_dap: self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -9360,23 +7875,23 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if variablesReference is not None: variablesReference = self._translate_id_to_dap(variablesReference) dct = { - 'variablesReference': variablesReference, - 'name': name, - 'value': value, + "variablesReference": variablesReference, + "name": name, + "value": value, } if format is not None: - dct['format'] = format.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["format"] = format.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) return dct -@register_response('setVariable') +@register_response("setVariable") @register class SetVariableResponse(BaseSchema): """ @@ -9388,102 +7903,83 @@ class SetVariableResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { - "value": { - "type": "string", - "description": "The new value of the variable." - }, + "value": {"type": "string", "description": "The new value of the variable."}, "type": { "type": "string", - "description": "The type of the new value. Typically shown in the UI when hovering over the value." + "description": "The type of the new value. Typically shown in the UI when hovering over the value.", }, "variablesReference": { "type": "integer", - "description": "If `variablesReference` is > 0, the new value is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." + "description": "If `variablesReference` is > 0, the new value is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, "namedVariables": { "type": "integer", - "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "indexedVariables": { "type": "integer", - "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "memoryReference": { "type": "string", - "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True." - } + "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True.", + }, }, - "required": [ - "value" - ] - } + "required": ["value"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param SetVariableResponseBody body: + :param SetVariableResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = SetVariableResponseBody() else: - self.body = SetVariableResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SetVariableResponseBody else body + self.body = ( + SetVariableResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != SetVariableResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -9493,20 +7989,20 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('source') +@register_request("source") @register class SourceRequest(BaseSchema): """ @@ -9518,55 +8014,46 @@ class SourceRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "source" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "SourceArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["source"]}, + "arguments": {"type": "SourceArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SourceArguments arguments: + :param string type: + :param string command: + :param SourceArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'source' + self.type = "request" + self.command = "source" if arguments is None: self.arguments = SourceArguments() else: - self.arguments = SourceArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SourceArguments else arguments + self.arguments = ( + SourceArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SourceArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -9583,16 +8070,16 @@ class SourceArguments(BaseSchema): __props__ = { "source": { "description": "Specifies the source content to load. Either `source.path` or `source.sourceReference` must be specified.", - "type": "Source" + "type": "Source", }, "sourceReference": { "type": "integer", - "description": "The reference to the source. This is the same as `source.sourceReference`.\nThis is provided for backward compatibility since old clients do not understand the `source` attribute." - } + "description": "The reference to the source. This is the same as `source.sourceReference`.\nThis is provided for backward compatibility since old clients do not understand the `source` attribute.", + }, } - __refs__ = set(['source']) + __refs__ = set(["source"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, sourceReference, source=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -9604,23 +8091,22 @@ def __init__(self, sourceReference, source=None, update_ids_from_dap=False, **kw if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) sourceReference = self.sourceReference source = self.source dct = { - 'sourceReference': sourceReference, + "sourceReference": sourceReference, } if source is not None: - dct['source'] = source.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["source"] = source.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct -@register_response('source') +@register_response("source") @register class SourceResponse(BaseSchema): """ @@ -9632,86 +8118,62 @@ class SourceResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { - "content": { - "type": "string", - "description": "Content of the source reference." - }, - "mimeType": { - "type": "string", - "description": "Content type (MIME type) of the source." - } + "content": {"type": "string", "description": "Content of the source reference."}, + "mimeType": {"type": "string", "description": "Content type (MIME type) of the source."}, }, - "required": [ - "content" - ] - } + "required": ["content"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param SourceResponseBody body: + :param SourceResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = SourceResponseBody() else: - self.body = SourceResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SourceResponseBody else body + self.body = ( + SourceResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SourceResponseBody else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -9721,20 +8183,20 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('threads') +@register_request("threads") @register class ThreadsRequest(BaseSchema): """ @@ -9746,68 +8208,49 @@ class ThreadsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "threads" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["threads"]}, "arguments": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Object containing arguments for the command." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Object containing arguments for the command.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] arguments: Object containing arguments for the command. """ - self.type = 'request' - self.command = 'threads' + self.type = "request" + self.command = "threads" self.seq = seq self.arguments = arguments self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments + dct["arguments"] = arguments dct.update(self.kwargs) return dct -@register_response('threads') +@register_response("threads") @register class ThreadsResponse(BaseSchema): """ @@ -9819,85 +8262,59 @@ class ThreadsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], + }, + "body": { + "type": "object", + "properties": {"threads": {"type": "array", "items": {"$ref": "#/definitions/Thread"}, "description": "All threads."}}, + "required": ["threads"], }, - "body": { - "type": "object", - "properties": { - "threads": { - "type": "array", - "items": { - "$ref": "#/definitions/Thread" - }, - "description": "All threads." - } - }, - "required": [ - "threads" - ] - } } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param ThreadsResponseBody body: + :param ThreadsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = ThreadsResponseBody() else: - self.body = ThreadsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ThreadsResponseBody else body + self.body = ( + ThreadsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ThreadsResponseBody else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -9907,25 +8324,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('terminateThreads') +@register_request("terminateThreads") @register class TerminateThreadsRequest(BaseSchema): """ The request terminates the threads with the given ids. - + Clients should only call this request if the corresponding capability `supportsTerminateThreadsRequest` is true. @@ -9935,55 +8352,46 @@ class TerminateThreadsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "terminateThreads" - ] - }, - "arguments": { - "type": "TerminateThreadsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["terminateThreads"]}, + "arguments": {"type": "TerminateThreadsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param TerminateThreadsArguments arguments: + :param string type: + :param string command: + :param TerminateThreadsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'terminateThreads' + self.type = "request" + self.command = "terminateThreads" if arguments is None: self.arguments = TerminateThreadsArguments() else: - self.arguments = TerminateThreadsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != TerminateThreadsArguments else arguments + self.arguments = ( + TerminateThreadsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != TerminateThreadsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -9997,18 +8405,10 @@ class TerminateThreadsArguments(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "threadIds": { - "type": "array", - "items": { - "type": "integer" - }, - "description": "Ids of threads to be terminated." - } - } + __props__ = {"threadIds": {"type": "array", "items": {"type": "integer"}, "description": "Ids of threads to be terminated."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadIds=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -10017,20 +8417,18 @@ def __init__(self, threadIds=None, update_ids_from_dap=False, **kwargs): # noqa self.threadIds = threadIds self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) threadIds = self.threadIds if threadIds and hasattr(threadIds[0], "to_dict"): threadIds = [x.to_dict() for x in threadIds] - dct = { - } + dct = {} if threadIds is not None: - dct['threadIds'] = threadIds + dct["threadIds"] = threadIds dct.update(self.kwargs) return dct -@register_response('terminateThreads') +@register_response("terminateThreads") @register class TerminateThreadsResponse(BaseSchema): """ @@ -10042,58 +8440,33 @@ class TerminateThreadsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -10105,7 +8478,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -10114,7 +8487,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -10124,27 +8496,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('modules') +@register_request("modules") @register class ModulesRequest(BaseSchema): """ Modules can be retrieved from the debug adapter with this request which can either return all modules or a range of modules to support paging. - + Clients should only call this request if the corresponding capability `supportsModulesRequest` is true. @@ -10154,57 +8526,48 @@ class ModulesRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "modules" - ] - }, - "arguments": { - "type": "ModulesArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["modules"]}, + "arguments": {"type": "ModulesArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param ModulesArguments arguments: + :param ModulesArguments arguments: """ - self.type = 'request' - self.command = 'modules' + self.type = "request" + self.command = "modules" self.seq = seq if arguments is None: self.arguments = ModulesArguments() else: - self.arguments = ModulesArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != ModulesArguments else arguments + self.arguments = ( + ModulesArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != ModulesArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -10218,18 +8581,15 @@ class ModulesArguments(BaseSchema): """ __props__ = { - "startModule": { - "type": "integer", - "description": "The index of the first module to return; if omitted modules start at 0." - }, + "startModule": {"type": "integer", "description": "The index of the first module to return; if omitted modules start at 0."}, "moduleCount": { "type": "integer", - "description": "The number of modules to return. If `moduleCount` is not specified or 0, all modules are returned." - } + "description": "The number of modules to return. If `moduleCount` is not specified or 0, all modules are returned.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, startModule=None, moduleCount=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -10240,21 +8600,19 @@ def __init__(self, startModule=None, moduleCount=None, update_ids_from_dap=False self.moduleCount = moduleCount self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) startModule = self.startModule moduleCount = self.moduleCount - dct = { - } + dct = {} if startModule is not None: - dct['startModule'] = startModule + dct["startModule"] = startModule if moduleCount is not None: - dct['moduleCount'] = moduleCount + dct["moduleCount"] = moduleCount dct.update(self.kwargs) return dct -@register_response('modules') +@register_response("modules") @register class ModulesResponse(BaseSchema): """ @@ -10266,89 +8624,62 @@ class ModulesResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { - "modules": { - "type": "array", - "items": { - "$ref": "#/definitions/Module" - }, - "description": "All modules or range of modules." - }, - "totalModules": { - "type": "integer", - "description": "The total number of modules available." - } + "modules": {"type": "array", "items": {"$ref": "#/definitions/Module"}, "description": "All modules or range of modules."}, + "totalModules": {"type": "integer", "description": "The total number of modules available."}, }, - "required": [ - "modules" - ] - } + "required": ["modules"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param ModulesResponseBody body: + :param ModulesResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = ModulesResponseBody() else: - self.body = ModulesResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ModulesResponseBody else body + self.body = ( + ModulesResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ModulesResponseBody else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -10358,25 +8689,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('loadedSources') +@register_request("loadedSources") @register class LoadedSourcesRequest(BaseSchema): """ Retrieves the set of all sources currently loaded by the debugged process. - + Clients should only call this request if the corresponding capability `supportsLoadedSourcesRequest` is true. @@ -10386,57 +8717,48 @@ class LoadedSourcesRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "loadedSources" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "LoadedSourcesArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["loadedSources"]}, + "arguments": {"type": "LoadedSourcesArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param LoadedSourcesArguments arguments: + :param LoadedSourcesArguments arguments: """ - self.type = 'request' - self.command = 'loadedSources' + self.type = "request" + self.command = "loadedSources" self.seq = seq if arguments is None: self.arguments = LoadedSourcesArguments() else: - self.arguments = LoadedSourcesArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != LoadedSourcesArguments else arguments + self.arguments = ( + LoadedSourcesArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != LoadedSourcesArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -10452,24 +8774,20 @@ class LoadedSourcesArguments(BaseSchema): __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct -@register_response('loadedSources') +@register_response("loadedSources") @register class LoadedSourcesResponse(BaseSchema): """ @@ -10481,85 +8799,63 @@ class LoadedSourcesResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { - "sources": { - "type": "array", - "items": { - "$ref": "#/definitions/Source" - }, - "description": "Set of loaded sources." - } + "sources": {"type": "array", "items": {"$ref": "#/definitions/Source"}, "description": "Set of loaded sources."} }, - "required": [ - "sources" - ] - } + "required": ["sources"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param LoadedSourcesResponseBody body: + :param LoadedSourcesResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = LoadedSourcesResponseBody() else: - self.body = LoadedSourcesResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != LoadedSourcesResponseBody else body + self.body = ( + LoadedSourcesResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != LoadedSourcesResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -10569,25 +8865,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('evaluate') +@register_request("evaluate") @register class EvaluateRequest(BaseSchema): """ Evaluates the given expression in the context of the topmost stack frame. - + The expression has access to any variables and arguments that are in scope. Note: automatically generated code. Do not edit manually. @@ -10596,55 +8892,46 @@ class EvaluateRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "evaluate" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "EvaluateArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["evaluate"]}, + "arguments": {"type": "EvaluateArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param EvaluateArguments arguments: + :param string type: + :param string command: + :param EvaluateArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'evaluate' + self.type = "request" + self.command = "evaluate" if arguments is None: self.arguments = EvaluateArguments() else: - self.arguments = EvaluateArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != EvaluateArguments else arguments + self.arguments = ( + EvaluateArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != EvaluateArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -10659,40 +8946,31 @@ class EvaluateArguments(BaseSchema): """ __props__ = { - "expression": { - "type": "string", - "description": "The expression to evaluate." - }, + "expression": {"type": "string", "description": "The expression to evaluate."}, "frameId": { "type": "integer", - "description": "Evaluate the expression in the scope of this stack frame. If not specified, the expression is evaluated in the global scope." + "description": "Evaluate the expression in the scope of this stack frame. If not specified, the expression is evaluated in the global scope.", }, "context": { "type": "string", - "_enum": [ - "watch", - "repl", - "hover", - "clipboard", - "variables" - ], + "_enum": ["watch", "repl", "hover", "clipboard", "variables"], "enumDescriptions": [ "evaluate is called from a watch view context.", "evaluate is called from a REPL context.", "evaluate is called to generate the debug hover contents.\nThis value should only be used if the corresponding capability `supportsEvaluateForHovers` is True.", "evaluate is called to generate clipboard contents.\nThis value should only be used if the corresponding capability `supportsClipboardContext` is True.", - "evaluate is called from a variables view context." + "evaluate is called from a variables view context.", ], - "description": "The context in which the evaluate request is used." + "description": "The context in which the evaluate request is used.", }, "format": { "description": "Specifies details on how to format the result.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsValueFormattingOptions` is True.", - "type": "ValueFormat" - } + "type": "ValueFormat", + }, } - __refs__ = set(['format']) + __refs__ = set(["format"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, expression, frameId=None, context=None, format=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -10708,16 +8986,15 @@ def __init__(self, expression, frameId=None, context=None, format=None, update_i if format is None: self.format = ValueFormat() else: - self.format = ValueFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != ValueFormat else format + self.format = ValueFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != ValueFormat else format if update_ids_from_dap: self.frameId = self._translate_id_from_dap(self.frameId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_from_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_from_dap(dct["frameId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -10729,25 +9006,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if frameId is not None: frameId = self._translate_id_to_dap(frameId) dct = { - 'expression': expression, + "expression": expression, } if frameId is not None: - dct['frameId'] = frameId + dct["frameId"] = frameId if context is not None: - dct['context'] = context + dct["context"] = context if format is not None: - dct['format'] = format.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["format"] = format.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_to_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_to_dap(dct["frameId"]) return dct -@register_response('evaluate') +@register_response("evaluate") @register class EvaluateResponse(BaseSchema): """ @@ -10759,107 +9036,85 @@ class EvaluateResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { - "result": { - "type": "string", - "description": "The result of the evaluate request." - }, + "result": {"type": "string", "description": "The result of the evaluate request."}, "type": { "type": "string", - "description": "The type of the evaluate result.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True." + "description": "The type of the evaluate result.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True.", }, "presentationHint": { "$ref": "#/definitions/VariablePresentationHint", - "description": "Properties of an evaluate result that can be used to determine how to render the result in the UI." + "description": "Properties of an evaluate result that can be used to determine how to render the result in the UI.", }, "variablesReference": { "type": "integer", - "description": "If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." + "description": "If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, "namedVariables": { "type": "integer", - "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "indexedVariables": { "type": "integer", - "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "memoryReference": { "type": "string", - "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True." - } + "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True.", + }, }, - "required": [ - "result", - "variablesReference" - ] - } + "required": ["result", "variablesReference"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param EvaluateResponseBody body: + :param EvaluateResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = EvaluateResponseBody() else: - self.body = EvaluateResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != EvaluateResponseBody else body + self.body = ( + EvaluateResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != EvaluateResponseBody else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -10869,31 +9124,31 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('setExpression') +@register_request("setExpression") @register class SetExpressionRequest(BaseSchema): """ Evaluates the given `value` expression and assigns it to the `expression` which must be a modifiable l-value. - + The expressions have access to any variables and arguments that are in scope of the specified frame. - + Clients should only call this request if the corresponding capability `supportsSetExpression` is true. - + If a debug adapter implements both `setExpression` and `setVariable`, a client uses `setExpression` if the variable has an `evaluateName` property. @@ -10903,55 +9158,46 @@ class SetExpressionRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "setExpression" - ] - }, - "arguments": { - "type": "SetExpressionArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setExpression"]}, + "arguments": {"type": "SetExpressionArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetExpressionArguments arguments: + :param string type: + :param string command: + :param SetExpressionArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setExpression' + self.type = "request" + self.command = "setExpression" if arguments is None: self.arguments = SetExpressionArguments() else: - self.arguments = SetExpressionArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetExpressionArguments else arguments + self.arguments = ( + SetExpressionArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetExpressionArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -10966,26 +9212,17 @@ class SetExpressionArguments(BaseSchema): """ __props__ = { - "expression": { - "type": "string", - "description": "The l-value expression to assign to." - }, - "value": { - "type": "string", - "description": "The value expression to assign to the l-value expression." - }, + "expression": {"type": "string", "description": "The l-value expression to assign to."}, + "value": {"type": "string", "description": "The value expression to assign to the l-value expression."}, "frameId": { "type": "integer", - "description": "Evaluate the expressions in the scope of this stack frame. If not specified, the expressions are evaluated in the global scope." + "description": "Evaluate the expressions in the scope of this stack frame. If not specified, the expressions are evaluated in the global scope.", }, - "format": { - "description": "Specifies how the resulting value should be formatted.", - "type": "ValueFormat" - } + "format": {"description": "Specifies how the resulting value should be formatted.", "type": "ValueFormat"}, } - __refs__ = set(['format']) + __refs__ = set(["format"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, expression, value, frameId=None, format=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -11000,16 +9237,15 @@ def __init__(self, expression, value, frameId=None, format=None, update_ids_from if format is None: self.format = ValueFormat() else: - self.format = ValueFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != ValueFormat else format + self.format = ValueFormat(update_ids_from_dap=update_ids_from_dap, **format) if format.__class__ != ValueFormat else format if update_ids_from_dap: self.frameId = self._translate_id_from_dap(self.frameId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_from_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_from_dap(dct["frameId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -11021,24 +9257,24 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if frameId is not None: frameId = self._translate_id_to_dap(frameId) dct = { - 'expression': expression, - 'value': value, + "expression": expression, + "value": value, } if frameId is not None: - dct['frameId'] = frameId + dct["frameId"] = frameId if format is not None: - dct['format'] = format.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["format"] = format.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_to_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_to_dap(dct["frameId"]) return dct -@register_response('setExpression') +@register_response("setExpression") @register class SetExpressionResponse(BaseSchema): """ @@ -11050,106 +9286,87 @@ class SetExpressionResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { - "value": { - "type": "string", - "description": "The new value of the expression." - }, + "value": {"type": "string", "description": "The new value of the expression."}, "type": { "type": "string", - "description": "The type of the value.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True." + "description": "The type of the value.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True.", }, "presentationHint": { "$ref": "#/definitions/VariablePresentationHint", - "description": "Properties of a value that can be used to determine how to render the result in the UI." + "description": "Properties of a value that can be used to determine how to render the result in the UI.", }, "variablesReference": { "type": "integer", - "description": "If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." + "description": "If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, "namedVariables": { "type": "integer", - "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "indexedVariables": { "type": "integer", - "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "memoryReference": { "type": "string", - "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True." - } + "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True.", + }, }, - "required": [ - "value" - ] - } + "required": ["value"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param SetExpressionResponseBody body: + :param SetExpressionResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = SetExpressionResponseBody() else: - self.body = SetExpressionResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != SetExpressionResponseBody else body + self.body = ( + SetExpressionResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != SetExpressionResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -11159,27 +9376,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('stepInTargets') +@register_request("stepInTargets") @register class StepInTargetsRequest(BaseSchema): """ This request retrieves the possible step-in targets for the specified stack frame. - + These targets can be used in the `stepIn` request. - + Clients should only call this request if the corresponding capability `supportsStepInTargetsRequest` is true. @@ -11189,55 +9406,46 @@ class StepInTargetsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "stepInTargets" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "StepInTargetsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["stepInTargets"]}, + "arguments": {"type": "StepInTargetsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param StepInTargetsArguments arguments: + :param string type: + :param string command: + :param StepInTargetsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'stepInTargets' + self.type = "request" + self.command = "stepInTargets" if arguments is None: self.arguments = StepInTargetsArguments() else: - self.arguments = StepInTargetsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != StepInTargetsArguments else arguments + self.arguments = ( + StepInTargetsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != StepInTargetsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -11251,15 +9459,10 @@ class StepInTargetsArguments(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "frameId": { - "type": "integer", - "description": "The stack frame for which to retrieve the possible step-in targets." - } - } + __props__ = {"frameId": {"type": "integer", "description": "The stack frame for which to retrieve the possible step-in targets."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, frameId, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -11269,12 +9472,11 @@ def __init__(self, frameId, update_ids_from_dap=False, **kwargs): # noqa (updat if update_ids_from_dap: self.frameId = self._translate_id_from_dap(self.frameId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_from_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_from_dap(dct["frameId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -11283,19 +9485,19 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if frameId is not None: frameId = self._translate_id_to_dap(frameId) dct = { - 'frameId': frameId, + "frameId": frameId, } dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_to_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_to_dap(dct["frameId"]) return dct -@register_response('stepInTargets') +@register_response("stepInTargets") @register class StepInTargetsResponse(BaseSchema): """ @@ -11307,85 +9509,67 @@ class StepInTargetsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "targets": { "type": "array", - "items": { - "$ref": "#/definitions/StepInTarget" - }, - "description": "The possible step-in targets of the specified source location." + "items": {"$ref": "#/definitions/StepInTarget"}, + "description": "The possible step-in targets of the specified source location.", } }, - "required": [ - "targets" - ] - } + "required": ["targets"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param StepInTargetsResponseBody body: + :param StepInTargetsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = StepInTargetsResponseBody() else: - self.body = StepInTargetsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != StepInTargetsResponseBody else body + self.body = ( + StepInTargetsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != StepInTargetsResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -11395,27 +9579,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('gotoTargets') +@register_request("gotoTargets") @register class GotoTargetsRequest(BaseSchema): """ This request retrieves the possible goto targets for the specified source location. - + These targets can be used in the `goto` request. - + Clients should only call this request if the corresponding capability `supportsGotoTargetsRequest` is true. @@ -11425,55 +9609,46 @@ class GotoTargetsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "gotoTargets" - ] - }, - "arguments": { - "type": "GotoTargetsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["gotoTargets"]}, + "arguments": {"type": "GotoTargetsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param GotoTargetsArguments arguments: + :param string type: + :param string command: + :param GotoTargetsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'gotoTargets' + self.type = "request" + self.command = "gotoTargets" if arguments is None: self.arguments = GotoTargetsArguments() else: - self.arguments = GotoTargetsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != GotoTargetsArguments else arguments + self.arguments = ( + GotoTargetsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != GotoTargetsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -11488,22 +9663,16 @@ class GotoTargetsArguments(BaseSchema): """ __props__ = { - "source": { - "description": "The source location for which the goto targets are determined.", - "type": "Source" - }, - "line": { - "type": "integer", - "description": "The line location for which the goto targets are determined." - }, + "source": {"description": "The source location for which the goto targets are determined.", "type": "Source"}, + "line": {"type": "integer", "description": "The line location for which the goto targets are determined."}, "column": { "type": "integer", - "description": "The position within `line` for which the goto targets are determined. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." - } + "description": "The position within `line` for which the goto targets are determined. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", + }, } - __refs__ = set(['source']) + __refs__ = set(["source"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, source, line, column=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -11514,27 +9683,26 @@ def __init__(self, source, line, column=None, update_ids_from_dap=False, **kwarg if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.line = line self.column = column self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) source = self.source line = self.line column = self.column dct = { - 'source': source.to_dict(update_ids_to_dap=update_ids_to_dap), - 'line': line, + "source": source.to_dict(update_ids_to_dap=update_ids_to_dap), + "line": line, } if column is not None: - dct['column'] = column + dct["column"] = column dct.update(self.kwargs) return dct -@register_response('gotoTargets') +@register_response("gotoTargets") @register class GotoTargetsResponse(BaseSchema): """ @@ -11546,85 +9714,67 @@ class GotoTargetsResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "targets": { "type": "array", - "items": { - "$ref": "#/definitions/GotoTarget" - }, - "description": "The possible goto targets of the specified location." + "items": {"$ref": "#/definitions/GotoTarget"}, + "description": "The possible goto targets of the specified location.", } }, - "required": [ - "targets" - ] - } + "required": ["targets"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param GotoTargetsResponseBody body: + :param GotoTargetsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = GotoTargetsResponseBody() else: - self.body = GotoTargetsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != GotoTargetsResponseBody else body + self.body = ( + GotoTargetsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != GotoTargetsResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -11634,25 +9784,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('completions') +@register_request("completions") @register class CompletionsRequest(BaseSchema): """ Returns a list of possible completions for a given caret position and text. - + Clients should only call this request if the corresponding capability `supportsCompletionsRequest` is true. @@ -11662,55 +9812,46 @@ class CompletionsRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "completions" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "CompletionsArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["completions"]}, + "arguments": {"type": "CompletionsArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param CompletionsArguments arguments: + :param string type: + :param string command: + :param CompletionsArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'completions' + self.type = "request" + self.command = "completions" if arguments is None: self.arguments = CompletionsArguments() else: - self.arguments = CompletionsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != CompletionsArguments else arguments + self.arguments = ( + CompletionsArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != CompletionsArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -11727,24 +9868,24 @@ class CompletionsArguments(BaseSchema): __props__ = { "frameId": { "type": "integer", - "description": "Returns completions in the scope of this stack frame. If not specified, the completions are returned for the global scope." + "description": "Returns completions in the scope of this stack frame. If not specified, the completions are returned for the global scope.", }, "text": { "type": "string", - "description": "One or more source lines. Typically this is the text users have typed into the debug console before they asked for completion." + "description": "One or more source lines. Typically this is the text users have typed into the debug console before they asked for completion.", }, "column": { "type": "integer", - "description": "The position within `text` for which to determine the completion proposals. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." + "description": "The position within `text` for which to determine the completion proposals. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, "line": { "type": "integer", - "description": "A line for which to determine the completion proposals. If missing the first line of the text is assumed." - } + "description": "A line for which to determine the completion proposals. If missing the first line of the text is assumed.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, text, column, frameId=None, line=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -11760,12 +9901,11 @@ def __init__(self, text, column, frameId=None, line=None, update_ids_from_dap=Fa if update_ids_from_dap: self.frameId = self._translate_id_from_dap(self.frameId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_from_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_from_dap(dct["frameId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -11777,24 +9917,24 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if frameId is not None: frameId = self._translate_id_to_dap(frameId) dct = { - 'text': text, - 'column': column, + "text": text, + "column": column, } if frameId is not None: - dct['frameId'] = frameId + dct["frameId"] = frameId if line is not None: - dct['line'] = line + dct["line"] = line dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'frameId' in dct: - dct['frameId'] = cls._translate_id_to_dap(dct['frameId']) + if "frameId" in dct: + dct["frameId"] = cls._translate_id_to_dap(dct["frameId"]) return dct -@register_response('completions') +@register_response("completions") @register class CompletionsResponse(BaseSchema): """ @@ -11802,89 +9942,71 @@ class CompletionsResponse(BaseSchema): Note: automatically generated code. Do not edit manually. """ - - __props__ = { - "seq": { - "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { + + __props__ = { + "seq": { "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "targets": { "type": "array", - "items": { - "$ref": "#/definitions/CompletionItem" - }, - "description": "The possible completions for ." + "items": {"$ref": "#/definitions/CompletionItem"}, + "description": "The possible completions for .", } }, - "required": [ - "targets" - ] - } + "required": ["targets"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param CompletionsResponseBody body: + :param CompletionsResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = CompletionsResponseBody() else: - self.body = CompletionsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != CompletionsResponseBody else body + self.body = ( + CompletionsResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != CompletionsResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -11894,25 +10016,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('exceptionInfo') +@register_request("exceptionInfo") @register class ExceptionInfoRequest(BaseSchema): """ Retrieves the details of the exception that caused this event to be raised. - + Clients should only call this request if the corresponding capability `supportsExceptionInfoRequest` is true. @@ -11922,55 +10044,46 @@ class ExceptionInfoRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "exceptionInfo" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "ExceptionInfoArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["exceptionInfo"]}, + "arguments": {"type": "ExceptionInfoArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param ExceptionInfoArguments arguments: + :param string type: + :param string command: + :param ExceptionInfoArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'exceptionInfo' + self.type = "request" + self.command = "exceptionInfo" if arguments is None: self.arguments = ExceptionInfoArguments() else: - self.arguments = ExceptionInfoArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != ExceptionInfoArguments else arguments + self.arguments = ( + ExceptionInfoArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != ExceptionInfoArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -11984,15 +10097,10 @@ class ExceptionInfoArguments(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "threadId": { - "type": "integer", - "description": "Thread for which exception information should be retrieved." - } - } + __props__ = {"threadId": {"type": "integer", "description": "Thread for which exception information should be retrieved."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -12002,12 +10110,11 @@ def __init__(self, threadId, update_ids_from_dap=False, **kwargs): # noqa (upda if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -12016,19 +10123,19 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct -@register_response('exceptionInfo') +@register_response("exceptionInfo") @register class ExceptionInfoResponse(BaseSchema): """ @@ -12040,95 +10147,69 @@ class ExceptionInfoResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { - "exceptionId": { - "type": "string", - "description": "ID of the exception that was thrown." - }, - "description": { - "type": "string", - "description": "Descriptive text for the exception." - }, + "exceptionId": {"type": "string", "description": "ID of the exception that was thrown."}, + "description": {"type": "string", "description": "Descriptive text for the exception."}, "breakMode": { "$ref": "#/definitions/ExceptionBreakMode", - "description": "Mode that caused the exception notification to be raised." + "description": "Mode that caused the exception notification to be raised.", }, - "details": { - "$ref": "#/definitions/ExceptionDetails", - "description": "Detailed information about the exception." - } + "details": {"$ref": "#/definitions/ExceptionDetails", "description": "Detailed information about the exception."}, }, - "required": [ - "exceptionId", - "breakMode" - ] - } + "required": ["exceptionId", "breakMode"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param ExceptionInfoResponseBody body: + :param ExceptionInfoResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = ExceptionInfoResponseBody() else: - self.body = ExceptionInfoResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ExceptionInfoResponseBody else body + self.body = ( + ExceptionInfoResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != ExceptionInfoResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -12138,25 +10219,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct -@register_request('readMemory') +@register_request("readMemory") @register class ReadMemoryRequest(BaseSchema): """ Reads bytes from memory at the provided location. - + Clients should only call this request if the corresponding capability `supportsReadMemoryRequest` is true. @@ -12166,55 +10247,46 @@ class ReadMemoryRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "readMemory" - ] - }, - "arguments": { - "type": "ReadMemoryArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["readMemory"]}, + "arguments": {"type": "ReadMemoryArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param ReadMemoryArguments arguments: + :param string type: + :param string command: + :param ReadMemoryArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'readMemory' + self.type = "request" + self.command = "readMemory" if arguments is None: self.arguments = ReadMemoryArguments() else: - self.arguments = ReadMemoryArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != ReadMemoryArguments else arguments + self.arguments = ( + ReadMemoryArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != ReadMemoryArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -12229,22 +10301,16 @@ class ReadMemoryArguments(BaseSchema): """ __props__ = { - "memoryReference": { - "type": "string", - "description": "Memory reference to the base location from which data should be read." - }, + "memoryReference": {"type": "string", "description": "Memory reference to the base location from which data should be read."}, "offset": { "type": "integer", - "description": "Offset (in bytes) to be applied to the reference location before reading data. Can be negative." + "description": "Offset (in bytes) to be applied to the reference location before reading data. Can be negative.", }, - "count": { - "type": "integer", - "description": "Number of bytes to read at the specified location and offset." - } + "count": {"type": "integer", "description": "Number of bytes to read at the specified location and offset."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, memoryReference, count, offset=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -12257,22 +10323,21 @@ def __init__(self, memoryReference, count, offset=None, update_ids_from_dap=Fals self.offset = offset self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) memoryReference = self.memoryReference count = self.count offset = self.offset dct = { - 'memoryReference': memoryReference, - 'count': count, + "memoryReference": memoryReference, + "count": count, } if offset is not None: - dct['offset'] = offset + dct["offset"] = offset dct.update(self.kwargs) return dct -@register_response('readMemory') +@register_response("readMemory") @register class ReadMemoryResponse(BaseSchema): """ @@ -12284,66 +10349,47 @@ class ReadMemoryResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "address": { "type": "string", - "description": "The address of the first byte of data returned.\nTreated as a hex value if prefixed with `0x`, or as a decimal value otherwise." + "description": "The address of the first byte of data returned.\nTreated as a hex value if prefixed with `0x`, or as a decimal value otherwise.", }, "unreadableBytes": { "type": "integer", - "description": "The number of unreadable bytes encountered after the last successfully read byte.\nThis can be used to determine the number of bytes that should be skipped before a subsequent `readMemory` request succeeds." + "description": "The number of unreadable bytes encountered after the last successfully read byte.\nThis can be used to determine the number of bytes that should be skipped before a subsequent `readMemory` request succeeds.", }, "data": { "type": "string", - "description": "The bytes read from memory, encoded using base64. If the decoded length of `data` is less than the requested `count` in the original `readMemory` request, and `unreadableBytes` is zero or omitted, then the client should assume it's reached the end of readable memory." - } + "description": "The bytes read from memory, encoded using base64. If the decoded length of `data` is less than the requested `count` in the original `readMemory` request, and `unreadableBytes` is zero or omitted, then the client should assume it's reached the end of readable memory.", + }, }, - "required": [ - "address" - ] - } + "required": ["address"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -12353,9 +10399,9 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. - :param ReadMemoryResponseBody body: + :param ReadMemoryResponseBody body: """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -12364,10 +10410,13 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non if body is None: self.body = ReadMemoryResponseBody() else: - self.body = ReadMemoryResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != ReadMemoryResponseBody else body + self.body = ( + ReadMemoryResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != ReadMemoryResponseBody + else body + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -12377,26 +10426,26 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["body"] = body.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct -@register_request('writeMemory') +@register_request("writeMemory") @register class WriteMemoryRequest(BaseSchema): """ Writes bytes to memory at the provided location. - + Clients should only call this request if the corresponding capability `supportsWriteMemoryRequest` is true. @@ -12406,55 +10455,46 @@ class WriteMemoryRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "writeMemory" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "WriteMemoryArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["writeMemory"]}, + "arguments": {"type": "WriteMemoryArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param WriteMemoryArguments arguments: + :param string type: + :param string command: + :param WriteMemoryArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'writeMemory' + self.type = "request" + self.command = "writeMemory" if arguments is None: self.arguments = WriteMemoryArguments() else: - self.arguments = WriteMemoryArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != WriteMemoryArguments else arguments + self.arguments = ( + WriteMemoryArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != WriteMemoryArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -12469,26 +10509,20 @@ class WriteMemoryArguments(BaseSchema): """ __props__ = { - "memoryReference": { - "type": "string", - "description": "Memory reference to the base location to which data should be written." - }, + "memoryReference": {"type": "string", "description": "Memory reference to the base location to which data should be written."}, "offset": { "type": "integer", - "description": "Offset (in bytes) to be applied to the reference location before writing data. Can be negative." + "description": "Offset (in bytes) to be applied to the reference location before writing data. Can be negative.", }, "allowPartial": { "type": "boolean", - "description": "Property to control partial writes. If True, the debug adapter should attempt to write memory even if the entire memory region is not writable. In such a case the debug adapter should stop after hitting the first byte of memory that cannot be written and return the number of bytes written in the response via the `offset` and `bytesWritten` properties.\nIf false or missing, a debug adapter should attempt to verify the region is writable before writing, and fail the response if it is not." + "description": "Property to control partial writes. If True, the debug adapter should attempt to write memory even if the entire memory region is not writable. In such a case the debug adapter should stop after hitting the first byte of memory that cannot be written and return the number of bytes written in the response via the `offset` and `bytesWritten` properties.\nIf false or missing, a debug adapter should attempt to verify the region is writable before writing, and fail the response if it is not.", }, - "data": { - "type": "string", - "description": "Bytes to write, encoded using base64." - } + "data": {"type": "string", "description": "Bytes to write, encoded using base64."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, memoryReference, data, offset=None, allowPartial=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -12504,25 +10538,24 @@ def __init__(self, memoryReference, data, offset=None, allowPartial=None, update self.allowPartial = allowPartial self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) memoryReference = self.memoryReference data = self.data offset = self.offset allowPartial = self.allowPartial dct = { - 'memoryReference': memoryReference, - 'data': data, + "memoryReference": memoryReference, + "data": data, } if offset is not None: - dct['offset'] = offset + dct["offset"] = offset if allowPartial is not None: - dct['allowPartial'] = allowPartial + dct["allowPartial"] = allowPartial dct.update(self.kwargs) return dct -@register_response('writeMemory') +@register_response("writeMemory") @register class WriteMemoryResponse(BaseSchema): """ @@ -12534,59 +10567,42 @@ class WriteMemoryResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "offset": { "type": "integer", - "description": "Property that should be returned when `allowPartial` is True to indicate the offset of the first byte of data successfully written. Can be negative." + "description": "Property that should be returned when `allowPartial` is True to indicate the offset of the first byte of data successfully written. Can be negative.", }, "bytesWritten": { "type": "integer", - "description": "Property that should be returned when `allowPartial` is True to indicate the number of bytes starting from address that were successfully written." - } - } - } + "description": "Property that should be returned when `allowPartial` is True to indicate the number of bytes starting from address that were successfully written.", + }, + }, + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -12596,9 +10612,9 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. - :param WriteMemoryResponseBody body: + :param WriteMemoryResponseBody body: """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -12607,10 +10623,13 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non if body is None: self.body = WriteMemoryResponseBody() else: - self.body = WriteMemoryResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != WriteMemoryResponseBody else body + self.body = ( + WriteMemoryResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != WriteMemoryResponseBody + else body + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -12620,26 +10639,26 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["body"] = body.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct -@register_request('disassemble') +@register_request("disassemble") @register class DisassembleRequest(BaseSchema): """ Disassembles code stored at the provided location. - + Clients should only call this request if the corresponding capability `supportsDisassembleRequest` is true. @@ -12649,55 +10668,46 @@ class DisassembleRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "disassemble" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "DisassembleArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["disassemble"]}, + "arguments": {"type": "DisassembleArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param DisassembleArguments arguments: + :param string type: + :param string command: + :param DisassembleArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'disassemble' + self.type = "request" + self.command = "disassemble" if arguments is None: self.arguments = DisassembleArguments() else: - self.arguments = DisassembleArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != DisassembleArguments else arguments + self.arguments = ( + DisassembleArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != DisassembleArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -12714,30 +10724,39 @@ class DisassembleArguments(BaseSchema): __props__ = { "memoryReference": { "type": "string", - "description": "Memory reference to the base location containing the instructions to disassemble." + "description": "Memory reference to the base location containing the instructions to disassemble.", }, "offset": { "type": "integer", - "description": "Offset (in bytes) to be applied to the reference location before disassembling. Can be negative." + "description": "Offset (in bytes) to be applied to the reference location before disassembling. Can be negative.", }, "instructionOffset": { "type": "integer", - "description": "Offset (in instructions) to be applied after the byte offset (if any) before disassembling. Can be negative." + "description": "Offset (in instructions) to be applied after the byte offset (if any) before disassembling. Can be negative.", }, "instructionCount": { "type": "integer", - "description": "Number of instructions to disassemble starting at the specified location and offset.\nAn adapter must return exactly this number of instructions - any unavailable instructions should be replaced with an implementation-defined 'invalid instruction' value." + "description": "Number of instructions to disassemble starting at the specified location and offset.\nAn adapter must return exactly this number of instructions - any unavailable instructions should be replaced with an implementation-defined 'invalid instruction' value.", }, "resolveSymbols": { "type": "boolean", - "description": "If True, the adapter should attempt to resolve memory addresses and other values to symbolic names." - } + "description": "If True, the adapter should attempt to resolve memory addresses and other values to symbolic names.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] - def __init__(self, memoryReference, instructionCount, offset=None, instructionOffset=None, resolveSymbols=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__( + self, + memoryReference, + instructionCount, + offset=None, + instructionOffset=None, + resolveSymbols=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string memoryReference: Memory reference to the base location containing the instructions to disassemble. :param integer instructionCount: Number of instructions to disassemble starting at the specified location and offset. @@ -12753,7 +10772,6 @@ def __init__(self, memoryReference, instructionCount, offset=None, instructionOf self.resolveSymbols = resolveSymbols self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) memoryReference = self.memoryReference instructionCount = self.instructionCount @@ -12761,20 +10779,20 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un instructionOffset = self.instructionOffset resolveSymbols = self.resolveSymbols dct = { - 'memoryReference': memoryReference, - 'instructionCount': instructionCount, + "memoryReference": memoryReference, + "instructionCount": instructionCount, } if offset is not None: - dct['offset'] = offset + dct["offset"] = offset if instructionOffset is not None: - dct['instructionOffset'] = instructionOffset + dct["instructionOffset"] = instructionOffset if resolveSymbols is not None: - dct['resolveSymbols'] = resolveSymbols + dct["resolveSymbols"] = resolveSymbols dct.update(self.kwargs) return dct -@register_response('disassemble') +@register_response("disassemble") @register class DisassembleResponse(BaseSchema): """ @@ -12786,61 +10804,40 @@ class DisassembleResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "instructions": { "type": "array", - "items": { - "$ref": "#/definitions/DisassembledInstruction" - }, - "description": "The list of disassembled instructions." + "items": {"$ref": "#/definitions/DisassembledInstruction"}, + "description": "The list of disassembled instructions.", } }, - "required": [ - "instructions" - ] - } + "required": ["instructions"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -12850,9 +10847,9 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. - :param DisassembleResponseBody body: + :param DisassembleResponseBody body: """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -12861,10 +10858,13 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non if body is None: self.body = DisassembleResponseBody() else: - self.body = DisassembleResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != DisassembleResponseBody else body + self.body = ( + DisassembleResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != DisassembleResponseBody + else body + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -12874,16 +10874,16 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["body"] = body.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -12899,178 +10899,159 @@ class Capabilities(BaseSchema): __props__ = { "supportsConfigurationDoneRequest": { "type": "boolean", - "description": "The debug adapter supports the `configurationDone` request." - }, - "supportsFunctionBreakpoints": { - "type": "boolean", - "description": "The debug adapter supports function breakpoints." - }, - "supportsConditionalBreakpoints": { - "type": "boolean", - "description": "The debug adapter supports conditional breakpoints." + "description": "The debug adapter supports the `configurationDone` request.", }, + "supportsFunctionBreakpoints": {"type": "boolean", "description": "The debug adapter supports function breakpoints."}, + "supportsConditionalBreakpoints": {"type": "boolean", "description": "The debug adapter supports conditional breakpoints."}, "supportsHitConditionalBreakpoints": { "type": "boolean", - "description": "The debug adapter supports breakpoints that break execution after a specified number of hits." + "description": "The debug adapter supports breakpoints that break execution after a specified number of hits.", }, "supportsEvaluateForHovers": { "type": "boolean", - "description": "The debug adapter supports a (side effect free) `evaluate` request for data hovers." + "description": "The debug adapter supports a (side effect free) `evaluate` request for data hovers.", }, "exceptionBreakpointFilters": { "type": "array", - "items": { - "$ref": "#/definitions/ExceptionBreakpointsFilter" - }, - "description": "Available exception filter options for the `setExceptionBreakpoints` request." + "items": {"$ref": "#/definitions/ExceptionBreakpointsFilter"}, + "description": "Available exception filter options for the `setExceptionBreakpoints` request.", }, "supportsStepBack": { "type": "boolean", - "description": "The debug adapter supports stepping back via the `stepBack` and `reverseContinue` requests." - }, - "supportsSetVariable": { - "type": "boolean", - "description": "The debug adapter supports setting a variable to a value." - }, - "supportsRestartFrame": { - "type": "boolean", - "description": "The debug adapter supports restarting a frame." - }, - "supportsGotoTargetsRequest": { - "type": "boolean", - "description": "The debug adapter supports the `gotoTargets` request." - }, - "supportsStepInTargetsRequest": { - "type": "boolean", - "description": "The debug adapter supports the `stepInTargets` request." - }, - "supportsCompletionsRequest": { - "type": "boolean", - "description": "The debug adapter supports the `completions` request." + "description": "The debug adapter supports stepping back via the `stepBack` and `reverseContinue` requests.", }, + "supportsSetVariable": {"type": "boolean", "description": "The debug adapter supports setting a variable to a value."}, + "supportsRestartFrame": {"type": "boolean", "description": "The debug adapter supports restarting a frame."}, + "supportsGotoTargetsRequest": {"type": "boolean", "description": "The debug adapter supports the `gotoTargets` request."}, + "supportsStepInTargetsRequest": {"type": "boolean", "description": "The debug adapter supports the `stepInTargets` request."}, + "supportsCompletionsRequest": {"type": "boolean", "description": "The debug adapter supports the `completions` request."}, "completionTriggerCharacters": { "type": "array", - "items": { - "type": "string" - }, - "description": "The set of characters that should trigger completion in a REPL. If not specified, the UI should assume the `.` character." - }, - "supportsModulesRequest": { - "type": "boolean", - "description": "The debug adapter supports the `modules` request." + "items": {"type": "string"}, + "description": "The set of characters that should trigger completion in a REPL. If not specified, the UI should assume the `.` character.", }, + "supportsModulesRequest": {"type": "boolean", "description": "The debug adapter supports the `modules` request."}, "additionalModuleColumns": { "type": "array", - "items": { - "$ref": "#/definitions/ColumnDescriptor" - }, - "description": "The set of additional module information exposed by the debug adapter." + "items": {"$ref": "#/definitions/ColumnDescriptor"}, + "description": "The set of additional module information exposed by the debug adapter.", }, "supportedChecksumAlgorithms": { "type": "array", - "items": { - "$ref": "#/definitions/ChecksumAlgorithm" - }, - "description": "Checksum algorithms supported by the debug adapter." + "items": {"$ref": "#/definitions/ChecksumAlgorithm"}, + "description": "Checksum algorithms supported by the debug adapter.", }, "supportsRestartRequest": { "type": "boolean", - "description": "The debug adapter supports the `restart` request. In this case a client should not implement `restart` by terminating and relaunching the adapter but by calling the `restart` request." + "description": "The debug adapter supports the `restart` request. In this case a client should not implement `restart` by terminating and relaunching the adapter but by calling the `restart` request.", }, "supportsExceptionOptions": { "type": "boolean", - "description": "The debug adapter supports `exceptionOptions` on the `setExceptionBreakpoints` request." + "description": "The debug adapter supports `exceptionOptions` on the `setExceptionBreakpoints` request.", }, "supportsValueFormattingOptions": { "type": "boolean", - "description": "The debug adapter supports a `format` attribute on the `stackTrace`, `variables`, and `evaluate` requests." - }, - "supportsExceptionInfoRequest": { - "type": "boolean", - "description": "The debug adapter supports the `exceptionInfo` request." + "description": "The debug adapter supports a `format` attribute on the `stackTrace`, `variables`, and `evaluate` requests.", }, + "supportsExceptionInfoRequest": {"type": "boolean", "description": "The debug adapter supports the `exceptionInfo` request."}, "supportTerminateDebuggee": { "type": "boolean", - "description": "The debug adapter supports the `terminateDebuggee` attribute on the `disconnect` request." + "description": "The debug adapter supports the `terminateDebuggee` attribute on the `disconnect` request.", }, "supportSuspendDebuggee": { "type": "boolean", - "description": "The debug adapter supports the `suspendDebuggee` attribute on the `disconnect` request." + "description": "The debug adapter supports the `suspendDebuggee` attribute on the `disconnect` request.", }, "supportsDelayedStackTraceLoading": { "type": "boolean", - "description": "The debug adapter supports the delayed loading of parts of the stack, which requires that both the `startFrame` and `levels` arguments and the `totalFrames` result of the `stackTrace` request are supported." - }, - "supportsLoadedSourcesRequest": { - "type": "boolean", - "description": "The debug adapter supports the `loadedSources` request." + "description": "The debug adapter supports the delayed loading of parts of the stack, which requires that both the `startFrame` and `levels` arguments and the `totalFrames` result of the `stackTrace` request are supported.", }, + "supportsLoadedSourcesRequest": {"type": "boolean", "description": "The debug adapter supports the `loadedSources` request."}, "supportsLogPoints": { "type": "boolean", - "description": "The debug adapter supports log points by interpreting the `logMessage` attribute of the `SourceBreakpoint`." - }, - "supportsTerminateThreadsRequest": { - "type": "boolean", - "description": "The debug adapter supports the `terminateThreads` request." - }, - "supportsSetExpression": { - "type": "boolean", - "description": "The debug adapter supports the `setExpression` request." - }, - "supportsTerminateRequest": { - "type": "boolean", - "description": "The debug adapter supports the `terminate` request." - }, - "supportsDataBreakpoints": { - "type": "boolean", - "description": "The debug adapter supports data breakpoints." - }, - "supportsReadMemoryRequest": { - "type": "boolean", - "description": "The debug adapter supports the `readMemory` request." - }, - "supportsWriteMemoryRequest": { - "type": "boolean", - "description": "The debug adapter supports the `writeMemory` request." - }, - "supportsDisassembleRequest": { - "type": "boolean", - "description": "The debug adapter supports the `disassemble` request." - }, - "supportsCancelRequest": { - "type": "boolean", - "description": "The debug adapter supports the `cancel` request." - }, + "description": "The debug adapter supports log points by interpreting the `logMessage` attribute of the `SourceBreakpoint`.", + }, + "supportsTerminateThreadsRequest": {"type": "boolean", "description": "The debug adapter supports the `terminateThreads` request."}, + "supportsSetExpression": {"type": "boolean", "description": "The debug adapter supports the `setExpression` request."}, + "supportsTerminateRequest": {"type": "boolean", "description": "The debug adapter supports the `terminate` request."}, + "supportsDataBreakpoints": {"type": "boolean", "description": "The debug adapter supports data breakpoints."}, + "supportsReadMemoryRequest": {"type": "boolean", "description": "The debug adapter supports the `readMemory` request."}, + "supportsWriteMemoryRequest": {"type": "boolean", "description": "The debug adapter supports the `writeMemory` request."}, + "supportsDisassembleRequest": {"type": "boolean", "description": "The debug adapter supports the `disassemble` request."}, + "supportsCancelRequest": {"type": "boolean", "description": "The debug adapter supports the `cancel` request."}, "supportsBreakpointLocationsRequest": { "type": "boolean", - "description": "The debug adapter supports the `breakpointLocations` request." + "description": "The debug adapter supports the `breakpointLocations` request.", }, "supportsClipboardContext": { "type": "boolean", - "description": "The debug adapter supports the `clipboard` context value in the `evaluate` request." + "description": "The debug adapter supports the `clipboard` context value in the `evaluate` request.", }, "supportsSteppingGranularity": { "type": "boolean", - "description": "The debug adapter supports stepping granularities (argument `granularity`) for the stepping requests." + "description": "The debug adapter supports stepping granularities (argument `granularity`) for the stepping requests.", }, "supportsInstructionBreakpoints": { "type": "boolean", - "description": "The debug adapter supports adding breakpoints based on instruction references." + "description": "The debug adapter supports adding breakpoints based on instruction references.", }, "supportsExceptionFilterOptions": { "type": "boolean", - "description": "The debug adapter supports `filterOptions` as an argument on the `setExceptionBreakpoints` request." + "description": "The debug adapter supports `filterOptions` as an argument on the `setExceptionBreakpoints` request.", }, "supportsSingleThreadExecutionRequests": { "type": "boolean", - "description": "The debug adapter supports the `singleThread` property on the execution requests (`continue`, `next`, `stepIn`, `stepOut`, `reverseContinue`, `stepBack`)." - } + "description": "The debug adapter supports the `singleThread` property on the execution requests (`continue`, `next`, `stepIn`, `stepOut`, `reverseContinue`, `stepBack`).", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, supportsConfigurationDoneRequest=None, supportsFunctionBreakpoints=None, supportsConditionalBreakpoints=None, supportsHitConditionalBreakpoints=None, supportsEvaluateForHovers=None, exceptionBreakpointFilters=None, supportsStepBack=None, supportsSetVariable=None, supportsRestartFrame=None, supportsGotoTargetsRequest=None, supportsStepInTargetsRequest=None, supportsCompletionsRequest=None, completionTriggerCharacters=None, supportsModulesRequest=None, additionalModuleColumns=None, supportedChecksumAlgorithms=None, supportsRestartRequest=None, supportsExceptionOptions=None, supportsValueFormattingOptions=None, supportsExceptionInfoRequest=None, supportTerminateDebuggee=None, supportSuspendDebuggee=None, supportsDelayedStackTraceLoading=None, supportsLoadedSourcesRequest=None, supportsLogPoints=None, supportsTerminateThreadsRequest=None, supportsSetExpression=None, supportsTerminateRequest=None, supportsDataBreakpoints=None, supportsReadMemoryRequest=None, supportsWriteMemoryRequest=None, supportsDisassembleRequest=None, supportsCancelRequest=None, supportsBreakpointLocationsRequest=None, supportsClipboardContext=None, supportsSteppingGranularity=None, supportsInstructionBreakpoints=None, supportsExceptionFilterOptions=None, supportsSingleThreadExecutionRequests=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + supportsConfigurationDoneRequest=None, + supportsFunctionBreakpoints=None, + supportsConditionalBreakpoints=None, + supportsHitConditionalBreakpoints=None, + supportsEvaluateForHovers=None, + exceptionBreakpointFilters=None, + supportsStepBack=None, + supportsSetVariable=None, + supportsRestartFrame=None, + supportsGotoTargetsRequest=None, + supportsStepInTargetsRequest=None, + supportsCompletionsRequest=None, + completionTriggerCharacters=None, + supportsModulesRequest=None, + additionalModuleColumns=None, + supportedChecksumAlgorithms=None, + supportsRestartRequest=None, + supportsExceptionOptions=None, + supportsValueFormattingOptions=None, + supportsExceptionInfoRequest=None, + supportTerminateDebuggee=None, + supportSuspendDebuggee=None, + supportsDelayedStackTraceLoading=None, + supportsLoadedSourcesRequest=None, + supportsLogPoints=None, + supportsTerminateThreadsRequest=None, + supportsSetExpression=None, + supportsTerminateRequest=None, + supportsDataBreakpoints=None, + supportsReadMemoryRequest=None, + supportsWriteMemoryRequest=None, + supportsDisassembleRequest=None, + supportsCancelRequest=None, + supportsBreakpointLocationsRequest=None, + supportsClipboardContext=None, + supportsSteppingGranularity=None, + supportsInstructionBreakpoints=None, + supportsExceptionFilterOptions=None, + supportsSingleThreadExecutionRequests=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param boolean supportsConfigurationDoneRequest: The debug adapter supports the `configurationDone` request. :param boolean supportsFunctionBreakpoints: The debug adapter supports function breakpoints. @@ -13162,7 +11143,6 @@ def __init__(self, supportsConfigurationDoneRequest=None, supportsFunctionBreakp self.supportsSingleThreadExecutionRequests = supportsSingleThreadExecutionRequests self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) supportsConfigurationDoneRequest = self.supportsConfigurationDoneRequest supportsFunctionBreakpoints = self.supportsFunctionBreakpoints @@ -13211,86 +11191,97 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un supportsInstructionBreakpoints = self.supportsInstructionBreakpoints supportsExceptionFilterOptions = self.supportsExceptionFilterOptions supportsSingleThreadExecutionRequests = self.supportsSingleThreadExecutionRequests - dct = { - } + dct = {} if supportsConfigurationDoneRequest is not None: - dct['supportsConfigurationDoneRequest'] = supportsConfigurationDoneRequest + dct["supportsConfigurationDoneRequest"] = supportsConfigurationDoneRequest if supportsFunctionBreakpoints is not None: - dct['supportsFunctionBreakpoints'] = supportsFunctionBreakpoints + dct["supportsFunctionBreakpoints"] = supportsFunctionBreakpoints if supportsConditionalBreakpoints is not None: - dct['supportsConditionalBreakpoints'] = supportsConditionalBreakpoints + dct["supportsConditionalBreakpoints"] = supportsConditionalBreakpoints if supportsHitConditionalBreakpoints is not None: - dct['supportsHitConditionalBreakpoints'] = supportsHitConditionalBreakpoints + dct["supportsHitConditionalBreakpoints"] = supportsHitConditionalBreakpoints if supportsEvaluateForHovers is not None: - dct['supportsEvaluateForHovers'] = supportsEvaluateForHovers + dct["supportsEvaluateForHovers"] = supportsEvaluateForHovers if exceptionBreakpointFilters is not None: - dct['exceptionBreakpointFilters'] = [ExceptionBreakpointsFilter.update_dict_ids_to_dap(o) for o in exceptionBreakpointFilters] if (update_ids_to_dap and exceptionBreakpointFilters) else exceptionBreakpointFilters + dct["exceptionBreakpointFilters"] = ( + [ExceptionBreakpointsFilter.update_dict_ids_to_dap(o) for o in exceptionBreakpointFilters] + if (update_ids_to_dap and exceptionBreakpointFilters) + else exceptionBreakpointFilters + ) if supportsStepBack is not None: - dct['supportsStepBack'] = supportsStepBack + dct["supportsStepBack"] = supportsStepBack if supportsSetVariable is not None: - dct['supportsSetVariable'] = supportsSetVariable + dct["supportsSetVariable"] = supportsSetVariable if supportsRestartFrame is not None: - dct['supportsRestartFrame'] = supportsRestartFrame + dct["supportsRestartFrame"] = supportsRestartFrame if supportsGotoTargetsRequest is not None: - dct['supportsGotoTargetsRequest'] = supportsGotoTargetsRequest + dct["supportsGotoTargetsRequest"] = supportsGotoTargetsRequest if supportsStepInTargetsRequest is not None: - dct['supportsStepInTargetsRequest'] = supportsStepInTargetsRequest + dct["supportsStepInTargetsRequest"] = supportsStepInTargetsRequest if supportsCompletionsRequest is not None: - dct['supportsCompletionsRequest'] = supportsCompletionsRequest + dct["supportsCompletionsRequest"] = supportsCompletionsRequest if completionTriggerCharacters is not None: - dct['completionTriggerCharacters'] = completionTriggerCharacters + dct["completionTriggerCharacters"] = completionTriggerCharacters if supportsModulesRequest is not None: - dct['supportsModulesRequest'] = supportsModulesRequest + dct["supportsModulesRequest"] = supportsModulesRequest if additionalModuleColumns is not None: - dct['additionalModuleColumns'] = [ColumnDescriptor.update_dict_ids_to_dap(o) for o in additionalModuleColumns] if (update_ids_to_dap and additionalModuleColumns) else additionalModuleColumns + dct["additionalModuleColumns"] = ( + [ColumnDescriptor.update_dict_ids_to_dap(o) for o in additionalModuleColumns] + if (update_ids_to_dap and additionalModuleColumns) + else additionalModuleColumns + ) if supportedChecksumAlgorithms is not None: - dct['supportedChecksumAlgorithms'] = [ChecksumAlgorithm.update_dict_ids_to_dap(o) for o in supportedChecksumAlgorithms] if (update_ids_to_dap and supportedChecksumAlgorithms) else supportedChecksumAlgorithms + dct["supportedChecksumAlgorithms"] = ( + [ChecksumAlgorithm.update_dict_ids_to_dap(o) for o in supportedChecksumAlgorithms] + if (update_ids_to_dap and supportedChecksumAlgorithms) + else supportedChecksumAlgorithms + ) if supportsRestartRequest is not None: - dct['supportsRestartRequest'] = supportsRestartRequest + dct["supportsRestartRequest"] = supportsRestartRequest if supportsExceptionOptions is not None: - dct['supportsExceptionOptions'] = supportsExceptionOptions + dct["supportsExceptionOptions"] = supportsExceptionOptions if supportsValueFormattingOptions is not None: - dct['supportsValueFormattingOptions'] = supportsValueFormattingOptions + dct["supportsValueFormattingOptions"] = supportsValueFormattingOptions if supportsExceptionInfoRequest is not None: - dct['supportsExceptionInfoRequest'] = supportsExceptionInfoRequest + dct["supportsExceptionInfoRequest"] = supportsExceptionInfoRequest if supportTerminateDebuggee is not None: - dct['supportTerminateDebuggee'] = supportTerminateDebuggee + dct["supportTerminateDebuggee"] = supportTerminateDebuggee if supportSuspendDebuggee is not None: - dct['supportSuspendDebuggee'] = supportSuspendDebuggee + dct["supportSuspendDebuggee"] = supportSuspendDebuggee if supportsDelayedStackTraceLoading is not None: - dct['supportsDelayedStackTraceLoading'] = supportsDelayedStackTraceLoading + dct["supportsDelayedStackTraceLoading"] = supportsDelayedStackTraceLoading if supportsLoadedSourcesRequest is not None: - dct['supportsLoadedSourcesRequest'] = supportsLoadedSourcesRequest + dct["supportsLoadedSourcesRequest"] = supportsLoadedSourcesRequest if supportsLogPoints is not None: - dct['supportsLogPoints'] = supportsLogPoints + dct["supportsLogPoints"] = supportsLogPoints if supportsTerminateThreadsRequest is not None: - dct['supportsTerminateThreadsRequest'] = supportsTerminateThreadsRequest + dct["supportsTerminateThreadsRequest"] = supportsTerminateThreadsRequest if supportsSetExpression is not None: - dct['supportsSetExpression'] = supportsSetExpression + dct["supportsSetExpression"] = supportsSetExpression if supportsTerminateRequest is not None: - dct['supportsTerminateRequest'] = supportsTerminateRequest + dct["supportsTerminateRequest"] = supportsTerminateRequest if supportsDataBreakpoints is not None: - dct['supportsDataBreakpoints'] = supportsDataBreakpoints + dct["supportsDataBreakpoints"] = supportsDataBreakpoints if supportsReadMemoryRequest is not None: - dct['supportsReadMemoryRequest'] = supportsReadMemoryRequest + dct["supportsReadMemoryRequest"] = supportsReadMemoryRequest if supportsWriteMemoryRequest is not None: - dct['supportsWriteMemoryRequest'] = supportsWriteMemoryRequest + dct["supportsWriteMemoryRequest"] = supportsWriteMemoryRequest if supportsDisassembleRequest is not None: - dct['supportsDisassembleRequest'] = supportsDisassembleRequest + dct["supportsDisassembleRequest"] = supportsDisassembleRequest if supportsCancelRequest is not None: - dct['supportsCancelRequest'] = supportsCancelRequest + dct["supportsCancelRequest"] = supportsCancelRequest if supportsBreakpointLocationsRequest is not None: - dct['supportsBreakpointLocationsRequest'] = supportsBreakpointLocationsRequest + dct["supportsBreakpointLocationsRequest"] = supportsBreakpointLocationsRequest if supportsClipboardContext is not None: - dct['supportsClipboardContext'] = supportsClipboardContext + dct["supportsClipboardContext"] = supportsClipboardContext if supportsSteppingGranularity is not None: - dct['supportsSteppingGranularity'] = supportsSteppingGranularity + dct["supportsSteppingGranularity"] = supportsSteppingGranularity if supportsInstructionBreakpoints is not None: - dct['supportsInstructionBreakpoints'] = supportsInstructionBreakpoints + dct["supportsInstructionBreakpoints"] = supportsInstructionBreakpoints if supportsExceptionFilterOptions is not None: - dct['supportsExceptionFilterOptions'] = supportsExceptionFilterOptions + dct["supportsExceptionFilterOptions"] = supportsExceptionFilterOptions if supportsSingleThreadExecutionRequests is not None: - dct['supportsSingleThreadExecutionRequests'] = supportsSingleThreadExecutionRequests + dct["supportsSingleThreadExecutionRequests"] = supportsSingleThreadExecutionRequests dct.update(self.kwargs) return dct @@ -13307,34 +11298,38 @@ class ExceptionBreakpointsFilter(BaseSchema): __props__ = { "filter": { "type": "string", - "description": "The internal ID of the filter option. This value is passed to the `setExceptionBreakpoints` request." - }, - "label": { - "type": "string", - "description": "The name of the filter option. This is shown in the UI." + "description": "The internal ID of the filter option. This value is passed to the `setExceptionBreakpoints` request.", }, + "label": {"type": "string", "description": "The name of the filter option. This is shown in the UI."}, "description": { "type": "string", - "description": "A help text providing additional information about the exception filter. This string is typically shown as a hover and can be translated." - }, - "default": { - "type": "boolean", - "description": "Initial value of the filter option. If not specified a value false is assumed." + "description": "A help text providing additional information about the exception filter. This string is typically shown as a hover and can be translated.", }, + "default": {"type": "boolean", "description": "Initial value of the filter option. If not specified a value false is assumed."}, "supportsCondition": { "type": "boolean", - "description": "Controls whether a condition can be specified for this filter option. If false or missing, a condition can not be set." + "description": "Controls whether a condition can be specified for this filter option. If false or missing, a condition can not be set.", }, "conditionDescription": { "type": "string", - "description": "A help text providing information about the condition. This string is shown as the placeholder text for a text box and can be translated." - } + "description": "A help text providing information about the condition. This string is shown as the placeholder text for a text box and can be translated.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] - def __init__(self, filter, label, description=None, default=None, supportsCondition=None, conditionDescription=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__( + self, + filter, + label, + description=None, + default=None, + supportsCondition=None, + conditionDescription=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string filter: The internal ID of the filter option. This value is passed to the `setExceptionBreakpoints` request. :param string label: The name of the filter option. This is shown in the UI. @@ -13351,7 +11346,6 @@ def __init__(self, filter, label, description=None, default=None, supportsCondit self.conditionDescription = conditionDescription self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) filter = self.filter # noqa (assign to builtin) label = self.label @@ -13360,17 +11354,17 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un supportsCondition = self.supportsCondition conditionDescription = self.conditionDescription dct = { - 'filter': filter, - 'label': label, + "filter": filter, + "label": label, } if description is not None: - dct['description'] = description + dct["description"] = description if default is not None: - dct['default'] = default + dct["default"] = default if supportsCondition is not None: - dct['supportsCondition'] = supportsCondition + dct["supportsCondition"] = supportsCondition if conditionDescription is not None: - dct['conditionDescription'] = conditionDescription + dct["conditionDescription"] = conditionDescription dct.update(self.kwargs) return dct @@ -13386,42 +11380,29 @@ class Message(BaseSchema): __props__ = { "id": { "type": "integer", - "description": "Unique (within a debug adapter implementation) identifier for the message. The purpose of these error IDs is to help extension authors that have the requirement that every user visible error message needs a corresponding error number, so that users or customer support can find information about the specific error more easily." + "description": "Unique (within a debug adapter implementation) identifier for the message. The purpose of these error IDs is to help extension authors that have the requirement that every user visible error message needs a corresponding error number, so that users or customer support can find information about the specific error more easily.", }, "format": { "type": "string", - "description": "A format string for the message. Embedded variables have the form `{name}`.\nIf variable name starts with an underscore character, the variable does not contain user data (PII) and can be safely used for telemetry purposes." + "description": "A format string for the message. Embedded variables have the form `{name}`.\nIf variable name starts with an underscore character, the variable does not contain user data (PII) and can be safely used for telemetry purposes.", }, "variables": { "type": "object", "description": "An object used as a dictionary for looking up the variables in the format string.", - "additionalProperties": { - "type": "string", - "description": "All dictionary values must be strings." - } - }, - "sendTelemetry": { - "type": "boolean", - "description": "If True send to telemetry." - }, - "showUser": { - "type": "boolean", - "description": "If True show user." + "additionalProperties": {"type": "string", "description": "All dictionary values must be strings."}, }, - "url": { - "type": "string", - "description": "A url where additional information about this message can be found." - }, - "urlLabel": { - "type": "string", - "description": "A label that is presented to the user as the UI for opening the url." - } + "sendTelemetry": {"type": "boolean", "description": "If True send to telemetry."}, + "showUser": {"type": "boolean", "description": "If True show user."}, + "url": {"type": "string", "description": "A url where additional information about this message can be found."}, + "urlLabel": {"type": "string", "description": "A label that is presented to the user as the UI for opening the url."}, } - __refs__ = set(['variables']) + __refs__ = set(["variables"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] - def __init__(self, id, format, variables=None, sendTelemetry=None, showUser=None, url=None, urlLabel=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__( + self, id, format, variables=None, sendTelemetry=None, showUser=None, url=None, urlLabel=None, update_ids_from_dap=False, **kwargs + ): # noqa (update_ids_from_dap may be unused) """ :param integer id: Unique (within a debug adapter implementation) identifier for the message. The purpose of these error IDs is to help extension authors that have the requirement that every user visible error message needs a corresponding error number, so that users or customer support can find information about the specific error more easily. :param string format: A format string for the message. Embedded variables have the form `{name}`. @@ -13437,14 +11418,17 @@ def __init__(self, id, format, variables=None, sendTelemetry=None, showUser=None if variables is None: self.variables = MessageVariables() else: - self.variables = MessageVariables(update_ids_from_dap=update_ids_from_dap, **variables) if variables.__class__ != MessageVariables else variables + self.variables = ( + MessageVariables(update_ids_from_dap=update_ids_from_dap, **variables) + if variables.__class__ != MessageVariables + else variables + ) self.sendTelemetry = sendTelemetry self.showUser = showUser self.url = url self.urlLabel = urlLabel self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) id = self.id # noqa (assign to builtin) format = self.format # noqa (assign to builtin) @@ -13454,19 +11438,19 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un url = self.url urlLabel = self.urlLabel dct = { - 'id': id, - 'format': format, + "id": id, + "format": format, } if variables is not None: - dct['variables'] = variables.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["variables"] = variables.to_dict(update_ids_to_dap=update_ids_to_dap) if sendTelemetry is not None: - dct['sendTelemetry'] = sendTelemetry + dct["sendTelemetry"] = sendTelemetry if showUser is not None: - dct['showUser'] = showUser + dct["showUser"] = showUser if url is not None: - dct['url'] = url + dct["url"] = url if urlLabel is not None: - dct['urlLabel'] = urlLabel + dct["urlLabel"] = urlLabel dct.update(self.kwargs) return dct @@ -13475,17 +11459,17 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un class Module(BaseSchema): """ A Module object represents a row in the modules view. - + The `id` attribute identifies a module in the modules view and is used in a `module` event for identifying a module for adding, updating or deleting. - + The `name` attribute is used to minimally render the module in the UI. - - + + Additional attributes can be added to the module. They show up in the module view if they have a corresponding `ColumnDescriptor`. - - + + To avoid an unnecessary proliferation of additional attributes with similar semantics but different names, we recommend to re-use attributes from the 'recommended' list below first, and only introduce new attributes if nothing appropriate could be found. @@ -13494,55 +11478,48 @@ class Module(BaseSchema): """ __props__ = { - "id": { - "type": [ - "integer", - "string" - ], - "description": "Unique identifier for the module." - }, - "name": { - "type": "string", - "description": "A name of the module." - }, + "id": {"type": ["integer", "string"], "description": "Unique identifier for the module."}, + "name": {"type": "string", "description": "A name of the module."}, "path": { "type": "string", - "description": "Logical full path to the module. The exact definition is implementation defined, but usually this would be a full path to the on-disk file for the module." - }, - "isOptimized": { - "type": "boolean", - "description": "True if the module is optimized." + "description": "Logical full path to the module. The exact definition is implementation defined, but usually this would be a full path to the on-disk file for the module.", }, + "isOptimized": {"type": "boolean", "description": "True if the module is optimized."}, "isUserCode": { "type": "boolean", - "description": "True if the module is considered 'user code' by a debugger that supports 'Just My Code'." - }, - "version": { - "type": "string", - "description": "Version of Module." + "description": "True if the module is considered 'user code' by a debugger that supports 'Just My Code'.", }, + "version": {"type": "string", "description": "Version of Module."}, "symbolStatus": { "type": "string", - "description": "User-understandable description of if symbols were found for the module (ex: 'Symbols Loaded', 'Symbols not found', etc.)" + "description": "User-understandable description of if symbols were found for the module (ex: 'Symbols Loaded', 'Symbols not found', etc.)", }, "symbolFilePath": { "type": "string", - "description": "Logical full path to the symbol file. The exact definition is implementation defined." - }, - "dateTimeStamp": { - "type": "string", - "description": "Module created or modified, encoded as a RFC 3339 timestamp." + "description": "Logical full path to the symbol file. The exact definition is implementation defined.", }, - "addressRange": { - "type": "string", - "description": "Address range covered by this module." - } + "dateTimeStamp": {"type": "string", "description": "Module created or modified, encoded as a RFC 3339 timestamp."}, + "addressRange": {"type": "string", "description": "Address range covered by this module."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, id, name, path=None, isOptimized=None, isUserCode=None, version=None, symbolStatus=None, symbolFilePath=None, dateTimeStamp=None, addressRange=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + id, + name, + path=None, + isOptimized=None, + isUserCode=None, + version=None, + symbolStatus=None, + symbolFilePath=None, + dateTimeStamp=None, + addressRange=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param ['integer', 'string'] id: Unique identifier for the module. :param string name: A name of the module. @@ -13567,7 +11544,6 @@ def __init__(self, id, name, path=None, isOptimized=None, isUserCode=None, versi self.addressRange = addressRange self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) id = self.id # noqa (assign to builtin) name = self.name @@ -13580,25 +11556,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un dateTimeStamp = self.dateTimeStamp addressRange = self.addressRange dct = { - 'id': id, - 'name': name, + "id": id, + "name": name, } if path is not None: - dct['path'] = path + dct["path"] = path if isOptimized is not None: - dct['isOptimized'] = isOptimized + dct["isOptimized"] = isOptimized if isUserCode is not None: - dct['isUserCode'] = isUserCode + dct["isUserCode"] = isUserCode if version is not None: - dct['version'] = version + dct["version"] = version if symbolStatus is not None: - dct['symbolStatus'] = symbolStatus + dct["symbolStatus"] = symbolStatus if symbolFilePath is not None: - dct['symbolFilePath'] = symbolFilePath + dct["symbolFilePath"] = symbolFilePath if dateTimeStamp is not None: - dct['dateTimeStamp'] = dateTimeStamp + dct["dateTimeStamp"] = dateTimeStamp if addressRange is not None: - dct['addressRange'] = addressRange + dct["addressRange"] = addressRange dct.update(self.kwargs) return dct @@ -13608,45 +11584,31 @@ class ColumnDescriptor(BaseSchema): """ A `ColumnDescriptor` specifies what module attribute to show in a column of the modules view, how to format it, - + and what the column's label should be. - + It is only used if the underlying UI actually supports this level of customization. Note: automatically generated code. Do not edit manually. """ __props__ = { - "attributeName": { - "type": "string", - "description": "Name of the attribute rendered in this column." - }, - "label": { - "type": "string", - "description": "Header UI label of column." - }, + "attributeName": {"type": "string", "description": "Name of the attribute rendered in this column."}, + "label": {"type": "string", "description": "Header UI label of column."}, "format": { "type": "string", - "description": "Format to use for the rendered values in this column. TBD how the format strings looks like." + "description": "Format to use for the rendered values in this column. TBD how the format strings looks like.", }, "type": { "type": "string", - "enum": [ - "string", - "number", - "boolean", - "unixTimestampUTC" - ], - "description": "Datatype of values in this column. Defaults to `string` if not specified." + "enum": ["string", "number", "boolean", "unixTimestampUTC"], + "description": "Datatype of values in this column. Defaults to `string` if not specified.", }, - "width": { - "type": "integer", - "description": "Width of this column in characters (hint only)." - } + "width": {"type": "integer", "description": "Width of this column in characters (hint only)."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, attributeName, label, format=None, type=None, width=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -13663,7 +11625,6 @@ def __init__(self, attributeName, label, format=None, type=None, width=None, upd self.width = width self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) attributeName = self.attributeName label = self.label @@ -13671,15 +11632,15 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un type = self.type # noqa (assign to builtin) width = self.width dct = { - 'attributeName': attributeName, - 'label': label, + "attributeName": attributeName, + "label": label, } if format is not None: - dct['format'] = format + dct["format"] = format if type is not None: - dct['type'] = type + dct["type"] = type if width is not None: - dct['width'] = width + dct["width"] = width dct.update(self.kwargs) return dct @@ -13693,18 +11654,12 @@ class Thread(BaseSchema): """ __props__ = { - "id": { - "type": "integer", - "description": "Unique identifier for the thread." - }, - "name": { - "type": "string", - "description": "The name of the thread." - } + "id": {"type": "integer", "description": "Unique identifier for the thread."}, + "name": {"type": "string", "description": "The name of the thread."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, id, name, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -13716,12 +11671,11 @@ def __init__(self, id, name, update_ids_from_dap=False, **kwargs): # noqa (upda if update_ids_from_dap: self.id = self._translate_id_from_dap(self.id) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'id' in dct: - dct['id'] = cls._translate_id_from_dap(dct['id']) + if "id" in dct: + dct["id"] = cls._translate_id_from_dap(dct["id"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -13731,16 +11685,16 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if id is not None: id = self._translate_id_to_dap(id) # noqa (assign to builtin) dct = { - 'id': id, - 'name': name, + "id": id, + "name": name, } dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'id' in dct: - dct['id'] = cls._translate_id_to_dap(dct['id']) + if "id" in dct: + dct["id"] = cls._translate_id_to_dap(dct["id"]) return dct @@ -13748,7 +11702,7 @@ def update_dict_ids_to_dap(cls, dct): class Source(BaseSchema): """ A `Source` is a descriptor for source code. - + It is returned from the debug adapter as part of a `StackFrame` and it is used by clients when specifying breakpoints. @@ -13758,61 +11712,57 @@ class Source(BaseSchema): __props__ = { "name": { "type": "string", - "description": "The short name of the source. Every source returned from the debug adapter has a name.\nWhen sending a source to the debug adapter this name is optional." + "description": "The short name of the source. Every source returned from the debug adapter has a name.\nWhen sending a source to the debug adapter this name is optional.", }, "path": { "type": "string", - "description": "The path of the source to be shown in the UI.\nIt is only used to locate and load the content of the source if no `sourceReference` is specified (or its value is 0)." + "description": "The path of the source to be shown in the UI.\nIt is only used to locate and load the content of the source if no `sourceReference` is specified (or its value is 0).", }, "sourceReference": { "type": "integer", - "description": "If the value > 0 the contents of the source must be retrieved through the `source` request (even if a path is specified).\nSince a `sourceReference` is only valid for a session, it can not be used to persist a source.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "If the value > 0 the contents of the source must be retrieved through the `source` request (even if a path is specified).\nSince a `sourceReference` is only valid for a session, it can not be used to persist a source.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "presentationHint": { "type": "string", "description": "A hint for how to present the source in the UI.\nA value of `deemphasize` can be used to indicate that the source is not available or that it is skipped on stepping.", - "enum": [ - "normal", - "emphasize", - "deemphasize" - ] + "enum": ["normal", "emphasize", "deemphasize"], }, "origin": { "type": "string", - "description": "The origin of this source. For example, 'internal module', 'inlined content from source map', etc." + "description": "The origin of this source. For example, 'internal module', 'inlined content from source map', etc.", }, "sources": { "type": "array", - "items": { - "$ref": "#/definitions/Source" - }, - "description": "A list of sources that are related to this source. These may be the source that generated this source." + "items": {"$ref": "#/definitions/Source"}, + "description": "A list of sources that are related to this source. These may be the source that generated this source.", }, "adapterData": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Additional data that a debug adapter might want to loop through the client.\nThe client should leave the data intact and persist it across sessions. The client should not interpret the data." + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Additional data that a debug adapter might want to loop through the client.\nThe client should leave the data intact and persist it across sessions. The client should not interpret the data.", }, "checksums": { "type": "array", - "items": { - "$ref": "#/definitions/Checksum" - }, - "description": "The checksums associated with this file." - } + "items": {"$ref": "#/definitions/Checksum"}, + "description": "The checksums associated with this file.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, name=None, path=None, sourceReference=None, presentationHint=None, origin=None, sources=None, adapterData=None, checksums=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + name=None, + path=None, + sourceReference=None, + presentationHint=None, + origin=None, + sources=None, + adapterData=None, + checksums=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string name: The short name of the source. Every source returned from the debug adapter has a name. When sending a source to the debug adapter this name is optional. @@ -13845,7 +11795,6 @@ def __init__(self, name=None, path=None, sourceReference=None, presentationHint= Checksum.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) name = self.name path = self.path @@ -13859,24 +11808,23 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un checksums = self.checksums if checksums and hasattr(checksums[0], "to_dict"): checksums = [x.to_dict() for x in checksums] - dct = { - } + dct = {} if name is not None: - dct['name'] = name + dct["name"] = name if path is not None: - dct['path'] = path + dct["path"] = path if sourceReference is not None: - dct['sourceReference'] = sourceReference + dct["sourceReference"] = sourceReference if presentationHint is not None: - dct['presentationHint'] = presentationHint + dct["presentationHint"] = presentationHint if origin is not None: - dct['origin'] = origin + dct["origin"] = origin if sources is not None: - dct['sources'] = [Source.update_dict_ids_to_dap(o) for o in sources] if (update_ids_to_dap and sources) else sources + dct["sources"] = [Source.update_dict_ids_to_dap(o) for o in sources] if (update_ids_to_dap and sources) else sources if adapterData is not None: - dct['adapterData'] = adapterData + dct["adapterData"] = adapterData if checksums is not None: - dct['checksums'] = [Checksum.update_dict_ids_to_dap(o) for o in checksums] if (update_ids_to_dap and checksums) else checksums + dct["checksums"] = [Checksum.update_dict_ids_to_dap(o) for o in checksums] if (update_ids_to_dap and checksums) else checksums dct.update(self.kwargs) return dct @@ -13892,62 +11840,58 @@ class StackFrame(BaseSchema): __props__ = { "id": { "type": "integer", - "description": "An identifier for the stack frame. It must be unique across all threads.\nThis id can be used to retrieve the scopes of the frame with the `scopes` request or to restart the execution of a stack frame." - }, - "name": { - "type": "string", - "description": "The name of the stack frame, typically a method name." - }, - "source": { - "description": "The source of the frame.", - "type": "Source" + "description": "An identifier for the stack frame. It must be unique across all threads.\nThis id can be used to retrieve the scopes of the frame with the `scopes` request or to restart the execution of a stack frame.", }, + "name": {"type": "string", "description": "The name of the stack frame, typically a method name."}, + "source": {"description": "The source of the frame.", "type": "Source"}, "line": { "type": "integer", - "description": "The line within the source of the frame. If the source attribute is missing or doesn't exist, `line` is 0 and should be ignored by the client." + "description": "The line within the source of the frame. If the source attribute is missing or doesn't exist, `line` is 0 and should be ignored by the client.", }, "column": { "type": "integer", - "description": "Start position of the range covered by the stack frame. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based. If attribute `source` is missing or doesn't exist, `column` is 0 and should be ignored by the client." - }, - "endLine": { - "type": "integer", - "description": "The end line of the range covered by the stack frame." + "description": "Start position of the range covered by the stack frame. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based. If attribute `source` is missing or doesn't exist, `column` is 0 and should be ignored by the client.", }, + "endLine": {"type": "integer", "description": "The end line of the range covered by the stack frame."}, "endColumn": { "type": "integer", - "description": "End position of the range covered by the stack frame. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." + "description": "End position of the range covered by the stack frame. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, "canRestart": { "type": "boolean", - "description": "Indicates whether this frame can be restarted with the `restart` request. Clients should only use this if the debug adapter supports the `restart` request and the corresponding capability `supportsRestartRequest` is True. If a debug adapter has this capability, then `canRestart` defaults to `True` if the property is absent." + "description": "Indicates whether this frame can be restarted with the `restart` request. Clients should only use this if the debug adapter supports the `restart` request and the corresponding capability `supportsRestartRequest` is True. If a debug adapter has this capability, then `canRestart` defaults to `True` if the property is absent.", }, "instructionPointerReference": { "type": "string", - "description": "A memory reference for the current instruction pointer in this frame." - }, - "moduleId": { - "type": [ - "integer", - "string" - ], - "description": "The module associated with this frame, if any." + "description": "A memory reference for the current instruction pointer in this frame.", }, + "moduleId": {"type": ["integer", "string"], "description": "The module associated with this frame, if any."}, "presentationHint": { "type": "string", - "enum": [ - "normal", - "label", - "subtle" - ], - "description": "A hint for how to present this frame in the UI.\nA value of `label` can be used to indicate that the frame is an artificial frame that is used as a visual label or separator. A value of `subtle` can be used to change the appearance of a frame in a 'subtle' way." - } + "enum": ["normal", "label", "subtle"], + "description": "A hint for how to present this frame in the UI.\nA value of `label` can be used to indicate that the frame is an artificial frame that is used as a visual label or separator. A value of `subtle` can be used to change the appearance of a frame in a 'subtle' way.", + }, } - __refs__ = set(['source']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, id, name, line, column, source=None, endLine=None, endColumn=None, canRestart=None, instructionPointerReference=None, moduleId=None, presentationHint=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["source"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + id, + name, + line, + column, + source=None, + endLine=None, + endColumn=None, + canRestart=None, + instructionPointerReference=None, + moduleId=None, + presentationHint=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param integer id: An identifier for the stack frame. It must be unique across all threads. This id can be used to retrieve the scopes of the frame with the `scopes` request or to restart the execution of a stack frame. @@ -13970,7 +11914,7 @@ def __init__(self, id, name, line, column, source=None, endLine=None, endColumn= if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.endLine = endLine self.endColumn = endColumn self.canRestart = canRestart @@ -13980,12 +11924,11 @@ def __init__(self, id, name, line, column, source=None, endLine=None, endColumn= if update_ids_from_dap: self.id = self._translate_id_from_dap(self.id) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'id' in dct: - dct['id'] = cls._translate_id_from_dap(dct['id']) + if "id" in dct: + dct["id"] = cls._translate_id_from_dap(dct["id"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -14004,32 +11947,32 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if id is not None: id = self._translate_id_to_dap(id) # noqa (assign to builtin) dct = { - 'id': id, - 'name': name, - 'line': line, - 'column': column, + "id": id, + "name": name, + "line": line, + "column": column, } if source is not None: - dct['source'] = source.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["source"] = source.to_dict(update_ids_to_dap=update_ids_to_dap) if endLine is not None: - dct['endLine'] = endLine + dct["endLine"] = endLine if endColumn is not None: - dct['endColumn'] = endColumn + dct["endColumn"] = endColumn if canRestart is not None: - dct['canRestart'] = canRestart + dct["canRestart"] = canRestart if instructionPointerReference is not None: - dct['instructionPointerReference'] = instructionPointerReference + dct["instructionPointerReference"] = instructionPointerReference if moduleId is not None: - dct['moduleId'] = moduleId + dct["moduleId"] = moduleId if presentationHint is not None: - dct['presentationHint'] = presentationHint + dct["presentationHint"] = presentationHint dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'id' in dct: - dct['id'] = cls._translate_id_to_dap(dct['id']) + if "id" in dct: + dct["id"] = cls._translate_id_to_dap(dct["id"]) return dct @@ -14045,64 +11988,66 @@ class Scope(BaseSchema): __props__ = { "name": { "type": "string", - "description": "Name of the scope such as 'Arguments', 'Locals', or 'Registers'. This string is shown in the UI as is and can be translated." + "description": "Name of the scope such as 'Arguments', 'Locals', or 'Registers'. This string is shown in the UI as is and can be translated.", }, "presentationHint": { "type": "string", "description": "A hint for how to present this scope in the UI. If this attribute is missing, the scope is shown with a generic UI.", - "_enum": [ - "arguments", - "locals", - "registers" - ], + "_enum": ["arguments", "locals", "registers"], "enumDescriptions": [ "Scope contains method arguments.", "Scope contains local variables.", - "Scope contains registers. Only a single `registers` scope should be returned from a `scopes` request." - ] + "Scope contains registers. Only a single `registers` scope should be returned from a `scopes` request.", + ], }, "variablesReference": { "type": "integer", - "description": "The variables of this scope can be retrieved by passing the value of `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." + "description": "The variables of this scope can be retrieved by passing the value of `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, "namedVariables": { "type": "integer", - "description": "The number of named variables in this scope.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks." + "description": "The number of named variables in this scope.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.", }, "indexedVariables": { "type": "integer", - "description": "The number of indexed variables in this scope.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks." + "description": "The number of indexed variables in this scope.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.", }, "expensive": { "type": "boolean", - "description": "If True, the number of variables in this scope is large or expensive to retrieve." - }, - "source": { - "description": "The source for this scope.", - "type": "Source" - }, - "line": { - "type": "integer", - "description": "The start line of the range covered by this scope." + "description": "If True, the number of variables in this scope is large or expensive to retrieve.", }, + "source": {"description": "The source for this scope.", "type": "Source"}, + "line": {"type": "integer", "description": "The start line of the range covered by this scope."}, "column": { "type": "integer", - "description": "Start position of the range covered by the scope. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." - }, - "endLine": { - "type": "integer", - "description": "The end line of the range covered by this scope." + "description": "Start position of the range covered by the scope. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, + "endLine": {"type": "integer", "description": "The end line of the range covered by this scope."}, "endColumn": { "type": "integer", - "description": "End position of the range covered by the scope. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." - } + "description": "End position of the range covered by the scope. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", + }, } - __refs__ = set(['source']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, name, variablesReference, expensive, presentationHint=None, namedVariables=None, indexedVariables=None, source=None, line=None, column=None, endLine=None, endColumn=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["source"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + name, + variablesReference, + expensive, + presentationHint=None, + namedVariables=None, + indexedVariables=None, + source=None, + line=None, + column=None, + endLine=None, + endColumn=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string name: Name of the scope such as 'Arguments', 'Locals', or 'Registers'. This string is shown in the UI as is and can be translated. :param integer variablesReference: The variables of this scope can be retrieved by passing the value of `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details. @@ -14127,7 +12072,7 @@ def __init__(self, name, variablesReference, expensive, presentationHint=None, n if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.line = line self.column = column self.endLine = endLine @@ -14135,12 +12080,11 @@ def __init__(self, name, variablesReference, expensive, presentationHint=None, n if update_ids_from_dap: self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -14159,33 +12103,33 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if variablesReference is not None: variablesReference = self._translate_id_to_dap(variablesReference) dct = { - 'name': name, - 'variablesReference': variablesReference, - 'expensive': expensive, + "name": name, + "variablesReference": variablesReference, + "expensive": expensive, } if presentationHint is not None: - dct['presentationHint'] = presentationHint + dct["presentationHint"] = presentationHint if namedVariables is not None: - dct['namedVariables'] = namedVariables + dct["namedVariables"] = namedVariables if indexedVariables is not None: - dct['indexedVariables'] = indexedVariables + dct["indexedVariables"] = indexedVariables if source is not None: - dct['source'] = source.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["source"] = source.to_dict(update_ids_to_dap=update_ids_to_dap) if line is not None: - dct['line'] = line + dct["line"] = line if column is not None: - dct['column'] = column + dct["column"] = column if endLine is not None: - dct['endLine'] = endLine + dct["endLine"] = endLine if endColumn is not None: - dct['endColumn'] = endColumn + dct["endColumn"] = endColumn dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) return dct @@ -14193,66 +12137,76 @@ def update_dict_ids_to_dap(cls, dct): class Variable(BaseSchema): """ A Variable is a name/value pair. - + The `type` attribute is shown if space permits or when hovering over the variable's name. - + The `kind` attribute is used to render additional properties of the variable, e.g. different icons can be used to indicate that a variable is public or private. - + If the value is structured (has children), a handle is provided to retrieve the children with the `variables` request. - + If the number of named or indexed children is large, the numbers should be returned via the `namedVariables` and `indexedVariables` attributes. - + The client can use this information to present the children in a paged UI and fetch them in chunks. Note: automatically generated code. Do not edit manually. """ __props__ = { - "name": { - "type": "string", - "description": "The variable's name." - }, + "name": {"type": "string", "description": "The variable's name."}, "value": { "type": "string", - "description": "The variable's value.\nThis can be a multi-line text, e.g. for a function the body of a function.\nFor structured variables (which do not have a simple value), it is recommended to provide a one-line representation of the structured object. This helps to identify the structured object in the collapsed state when its children are not yet visible.\nAn empty string can be used if no value should be shown in the UI." + "description": "The variable's value.\nThis can be a multi-line text, e.g. for a function the body of a function.\nFor structured variables (which do not have a simple value), it is recommended to provide a one-line representation of the structured object. This helps to identify the structured object in the collapsed state when its children are not yet visible.\nAn empty string can be used if no value should be shown in the UI.", }, "type": { "type": "string", - "description": "The type of the variable's value. Typically shown in the UI when hovering over the value.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True." + "description": "The type of the variable's value. Typically shown in the UI when hovering over the value.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True.", }, "presentationHint": { "description": "Properties of a variable that can be used to determine how to render the variable in the UI.", - "type": "VariablePresentationHint" + "type": "VariablePresentationHint", }, "evaluateName": { "type": "string", - "description": "The evaluatable name of this variable which can be passed to the `evaluate` request to fetch the variable's value." + "description": "The evaluatable name of this variable which can be passed to the `evaluate` request to fetch the variable's value.", }, "variablesReference": { "type": "integer", - "description": "If `variablesReference` is > 0, the variable is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." + "description": "If `variablesReference` is > 0, the variable is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, "namedVariables": { "type": "integer", - "description": "The number of named child variables.\nThe client can use this information to present the children in a paged UI and fetch them in chunks." + "description": "The number of named child variables.\nThe client can use this information to present the children in a paged UI and fetch them in chunks.", }, "indexedVariables": { "type": "integer", - "description": "The number of indexed child variables.\nThe client can use this information to present the children in a paged UI and fetch them in chunks." + "description": "The number of indexed child variables.\nThe client can use this information to present the children in a paged UI and fetch them in chunks.", }, "memoryReference": { "type": "string", - "description": "A memory reference associated with this variable.\nFor pointer type variables, this is generally a reference to the memory address contained in the pointer.\nFor executable data, this reference may later be used in a `disassemble` request.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True." - } + "description": "A memory reference associated with this variable.\nFor pointer type variables, this is generally a reference to the memory address contained in the pointer.\nFor executable data, this reference may later be used in a `disassemble` request.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True.", + }, } - __refs__ = set(['presentationHint']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, name, value, variablesReference, type=None, presentationHint=None, evaluateName=None, namedVariables=None, indexedVariables=None, memoryReference=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["presentationHint"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + name, + value, + variablesReference, + type=None, + presentationHint=None, + evaluateName=None, + namedVariables=None, + indexedVariables=None, + memoryReference=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string name: The variable's name. :param string value: The variable's value. @@ -14280,7 +12234,11 @@ def __init__(self, name, value, variablesReference, type=None, presentationHint= if presentationHint is None: self.presentationHint = VariablePresentationHint() else: - self.presentationHint = VariablePresentationHint(update_ids_from_dap=update_ids_from_dap, **presentationHint) if presentationHint.__class__ != VariablePresentationHint else presentationHint + self.presentationHint = ( + VariablePresentationHint(update_ids_from_dap=update_ids_from_dap, **presentationHint) + if presentationHint.__class__ != VariablePresentationHint + else presentationHint + ) self.evaluateName = evaluateName self.namedVariables = namedVariables self.indexedVariables = indexedVariables @@ -14288,12 +12246,11 @@ def __init__(self, name, value, variablesReference, type=None, presentationHint= if update_ids_from_dap: self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -14310,29 +12267,29 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if variablesReference is not None: variablesReference = self._translate_id_to_dap(variablesReference) dct = { - 'name': name, - 'value': value, - 'variablesReference': variablesReference, + "name": name, + "value": value, + "variablesReference": variablesReference, } if type is not None: - dct['type'] = type + dct["type"] = type if presentationHint is not None: - dct['presentationHint'] = presentationHint.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["presentationHint"] = presentationHint.to_dict(update_ids_to_dap=update_ids_to_dap) if evaluateName is not None: - dct['evaluateName'] = evaluateName + dct["evaluateName"] = evaluateName if namedVariables is not None: - dct['namedVariables'] = namedVariables + dct["namedVariables"] = namedVariables if indexedVariables is not None: - dct['indexedVariables'] = indexedVariables + dct["indexedVariables"] = indexedVariables if memoryReference is not None: - dct['memoryReference'] = memoryReference + dct["memoryReference"] = memoryReference dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) return dct @@ -14359,7 +12316,7 @@ class VariablePresentationHint(BaseSchema): "interface", "mostDerivedClass", "virtual", - "dataBreakpoint" + "dataBreakpoint", ], "enumDescriptions": [ "Indicates that the object is a property.", @@ -14372,8 +12329,8 @@ class VariablePresentationHint(BaseSchema): "Indicates that the object is an interface.", "Indicates that the object is the most derived class.", "Indicates that the object is virtual, that means it is a synthetic object introduced by the adapter for rendering purposes, e.g. an index range for large arrays.", - "Deprecated: Indicates that a data breakpoint is registered for the object. The `hasDataBreakpoint` attribute should generally be used instead." - ] + "Deprecated: Indicates that a data breakpoint is registered for the object. The `hasDataBreakpoint` attribute should generally be used instead.", + ], }, "attributes": { "description": "Set of attributes represented as an array of strings. Before introducing additional values, try to use the listed values.", @@ -14388,7 +12345,7 @@ class VariablePresentationHint(BaseSchema): "hasObjectId", "canHaveObjectId", "hasSideEffects", - "hasDataBreakpoint" + "hasDataBreakpoint", ], "enumDescriptions": [ "Indicates that the object is static.", @@ -14398,29 +12355,23 @@ class VariablePresentationHint(BaseSchema): "Indicates that the object can have an Object ID created for it. This is a vestigial attribute that is used by some clients; 'Object ID's are not specified in the protocol.", "Indicates that the object has an Object ID associated with it. This is a vestigial attribute that is used by some clients; 'Object ID's are not specified in the protocol.", "Indicates that the evaluation had side effects.", - "Indicates that the object has its value tracked by a data breakpoint." - ] - } + "Indicates that the object has its value tracked by a data breakpoint.", + ], + }, }, "visibility": { "description": "Visibility of variable. Before introducing additional values, try to use the listed values.", "type": "string", - "_enum": [ - "public", - "private", - "protected", - "internal", - "final" - ] + "_enum": ["public", "private", "protected", "internal", "final"], }, "lazy": { "description": "If True, clients can present the variable with a UI that supports a specific gesture to trigger its evaluation.\nThis mechanism can be used for properties that require executing code when retrieving their value and where the code execution can be expensive and/or produce side-effects. A typical example are properties based on a getter function.\nPlease note that in addition to the `lazy` flag, the variable's `variablesReference` is expected to refer to a variable that will provide the value through another `variable` request.", - "type": "boolean" - } + "type": "boolean", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, kind=None, attributes=None, visibility=None, lazy=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -14437,7 +12388,6 @@ def __init__(self, kind=None, attributes=None, visibility=None, lazy=None, updat self.lazy = lazy self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) kind = self.kind attributes = self.attributes @@ -14445,16 +12395,15 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un attributes = [x.to_dict() for x in attributes] visibility = self.visibility lazy = self.lazy - dct = { - } + dct = {} if kind is not None: - dct['kind'] = kind + dct["kind"] = kind if attributes is not None: - dct['attributes'] = attributes + dct["attributes"] = attributes if visibility is not None: - dct['visibility'] = visibility + dct["visibility"] = visibility if lazy is not None: - dct['lazy'] = lazy + dct["lazy"] = lazy dct.update(self.kwargs) return dct @@ -14468,26 +12417,20 @@ class BreakpointLocation(BaseSchema): """ __props__ = { - "line": { - "type": "integer", - "description": "Start line of breakpoint location." - }, + "line": {"type": "integer", "description": "Start line of breakpoint location."}, "column": { "type": "integer", - "description": "The start position of a breakpoint location. Position is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." - }, - "endLine": { - "type": "integer", - "description": "The end line of breakpoint location if the location covers a range." + "description": "The start position of a breakpoint location. Position is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, + "endLine": {"type": "integer", "description": "The end line of breakpoint location if the location covers a range."}, "endColumn": { "type": "integer", - "description": "The end position of a breakpoint location (if the location covers a range). Position is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." - } + "description": "The end position of a breakpoint location (if the location covers a range). Position is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, line, column=None, endLine=None, endColumn=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -14502,21 +12445,20 @@ def __init__(self, line, column=None, endLine=None, endColumn=None, update_ids_f self.endColumn = endColumn self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) line = self.line column = self.column endLine = self.endLine endColumn = self.endColumn dct = { - 'line': line, + "line": line, } if column is not None: - dct['column'] = column + dct["column"] = column if endLine is not None: - dct['endLine'] = endLine + dct["endLine"] = endLine if endColumn is not None: - dct['endColumn'] = endColumn + dct["endColumn"] = endColumn dct.update(self.kwargs) return dct @@ -14530,30 +12472,27 @@ class SourceBreakpoint(BaseSchema): """ __props__ = { - "line": { - "type": "integer", - "description": "The source line of the breakpoint or logpoint." - }, + "line": {"type": "integer", "description": "The source line of the breakpoint or logpoint."}, "column": { "type": "integer", - "description": "Start position within source line of the breakpoint or logpoint. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." + "description": "Start position within source line of the breakpoint or logpoint. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, "condition": { "type": "string", - "description": "The expression for conditional breakpoints.\nIt is only honored by a debug adapter if the corresponding capability `supportsConditionalBreakpoints` is True." + "description": "The expression for conditional breakpoints.\nIt is only honored by a debug adapter if the corresponding capability `supportsConditionalBreakpoints` is True.", }, "hitCondition": { "type": "string", - "description": "The expression that controls how many hits of the breakpoint are ignored.\nThe debug adapter is expected to interpret the expression as needed.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsHitConditionalBreakpoints` is True.\nIf both this property and `condition` are specified, `hitCondition` should be evaluated only if the `condition` is met, and the debug adapter should stop only if both conditions are met." + "description": "The expression that controls how many hits of the breakpoint are ignored.\nThe debug adapter is expected to interpret the expression as needed.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsHitConditionalBreakpoints` is True.\nIf both this property and `condition` are specified, `hitCondition` should be evaluated only if the `condition` is met, and the debug adapter should stop only if both conditions are met.", }, "logMessage": { "type": "string", - "description": "If this attribute exists and is non-empty, the debug adapter must not 'break' (stop)\nbut log the message instead. Expressions within `{}` are interpolated.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsLogPoints` is True.\nIf either `hitCondition` or `condition` is specified, then the message should only be logged if those conditions are met." - } + "description": "If this attribute exists and is non-empty, the debug adapter must not 'break' (stop)\nbut log the message instead. Expressions within `{}` are interpolated.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsLogPoints` is True.\nIf either `hitCondition` or `condition` is specified, then the message should only be logged if those conditions are met.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, line, column=None, condition=None, hitCondition=None, logMessage=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -14577,7 +12516,6 @@ def __init__(self, line, column=None, condition=None, hitCondition=None, logMess self.logMessage = logMessage self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) line = self.line column = self.column @@ -14585,16 +12523,16 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un hitCondition = self.hitCondition logMessage = self.logMessage dct = { - 'line': line, + "line": line, } if column is not None: - dct['column'] = column + dct["column"] = column if condition is not None: - dct['condition'] = condition + dct["condition"] = condition if hitCondition is not None: - dct['hitCondition'] = hitCondition + dct["hitCondition"] = hitCondition if logMessage is not None: - dct['logMessage'] = logMessage + dct["logMessage"] = logMessage dct.update(self.kwargs) return dct @@ -14608,22 +12546,19 @@ class FunctionBreakpoint(BaseSchema): """ __props__ = { - "name": { - "type": "string", - "description": "The name of the function." - }, + "name": {"type": "string", "description": "The name of the function."}, "condition": { "type": "string", - "description": "An expression for conditional breakpoints.\nIt is only honored by a debug adapter if the corresponding capability `supportsConditionalBreakpoints` is True." + "description": "An expression for conditional breakpoints.\nIt is only honored by a debug adapter if the corresponding capability `supportsConditionalBreakpoints` is True.", }, "hitCondition": { "type": "string", - "description": "An expression that controls how many hits of the breakpoint are ignored.\nThe debug adapter is expected to interpret the expression as needed.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsHitConditionalBreakpoints` is True." - } + "description": "An expression that controls how many hits of the breakpoint are ignored.\nThe debug adapter is expected to interpret the expression as needed.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsHitConditionalBreakpoints` is True.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, name, condition=None, hitCondition=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -14639,18 +12574,17 @@ def __init__(self, name, condition=None, hitCondition=None, update_ids_from_dap= self.hitCondition = hitCondition self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) name = self.name condition = self.condition hitCondition = self.hitCondition dct = { - 'name': name, + "name": name, } if condition is not None: - dct['condition'] = condition + dct["condition"] = condition if hitCondition is not None: - dct['hitCondition'] = hitCondition + dct["hitCondition"] = hitCondition dct.update(self.kwargs) return dct @@ -14663,28 +12597,24 @@ class DataBreakpointAccessType(BaseSchema): Note: automatically generated code. Do not edit manually. """ - READ = 'read' - WRITE = 'write' - READWRITE = 'readWrite' + READ = "read" + WRITE = "write" + READWRITE = "readWrite" - VALID_VALUES = set(['read', 'write', 'readWrite']) + VALID_VALUES = set(["read", "write", "readWrite"]) __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct @@ -14700,24 +12630,18 @@ class DataBreakpoint(BaseSchema): __props__ = { "dataId": { "type": "string", - "description": "An id representing the data. This id is returned from the `dataBreakpointInfo` request." - }, - "accessType": { - "description": "The access type of the data.", - "type": "DataBreakpointAccessType" - }, - "condition": { - "type": "string", - "description": "An expression for conditional breakpoints." + "description": "An id representing the data. This id is returned from the `dataBreakpointInfo` request.", }, + "accessType": {"description": "The access type of the data.", "type": "DataBreakpointAccessType"}, + "condition": {"type": "string", "description": "An expression for conditional breakpoints."}, "hitCondition": { "type": "string", - "description": "An expression that controls how many hits of the breakpoint are ignored.\nThe debug adapter is expected to interpret the expression as needed." - } + "description": "An expression that controls how many hits of the breakpoint are ignored.\nThe debug adapter is expected to interpret the expression as needed.", + }, } - __refs__ = set(['accessType']) + __refs__ = set(["accessType"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, dataId, accessType=None, condition=None, hitCondition=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -14735,21 +12659,20 @@ def __init__(self, dataId, accessType=None, condition=None, hitCondition=None, u self.hitCondition = hitCondition self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) dataId = self.dataId accessType = self.accessType condition = self.condition hitCondition = self.hitCondition dct = { - 'dataId': dataId, + "dataId": dataId, } if accessType is not None: - dct['accessType'] = accessType + dct["accessType"] = accessType if condition is not None: - dct['condition'] = condition + dct["condition"] = condition if hitCondition is not None: - dct['hitCondition'] = hitCondition + dct["hitCondition"] = hitCondition dct.update(self.kwargs) return dct @@ -14765,24 +12688,21 @@ class InstructionBreakpoint(BaseSchema): __props__ = { "instructionReference": { "type": "string", - "description": "The instruction reference of the breakpoint.\nThis should be a memory or instruction pointer reference from an `EvaluateResponse`, `Variable`, `StackFrame`, `GotoTarget`, or `Breakpoint`." - }, - "offset": { - "type": "integer", - "description": "The offset from the instruction reference in bytes.\nThis can be negative." + "description": "The instruction reference of the breakpoint.\nThis should be a memory or instruction pointer reference from an `EvaluateResponse`, `Variable`, `StackFrame`, `GotoTarget`, or `Breakpoint`.", }, + "offset": {"type": "integer", "description": "The offset from the instruction reference in bytes.\nThis can be negative."}, "condition": { "type": "string", - "description": "An expression for conditional breakpoints.\nIt is only honored by a debug adapter if the corresponding capability `supportsConditionalBreakpoints` is True." + "description": "An expression for conditional breakpoints.\nIt is only honored by a debug adapter if the corresponding capability `supportsConditionalBreakpoints` is True.", }, "hitCondition": { "type": "string", - "description": "An expression that controls how many hits of the breakpoint are ignored.\nThe debug adapter is expected to interpret the expression as needed.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsHitConditionalBreakpoints` is True." - } + "description": "An expression that controls how many hits of the breakpoint are ignored.\nThe debug adapter is expected to interpret the expression as needed.\nThe attribute is only honored by a debug adapter if the corresponding capability `supportsHitConditionalBreakpoints` is True.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, instructionReference, offset=None, condition=None, hitCondition=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -14802,21 +12722,20 @@ def __init__(self, instructionReference, offset=None, condition=None, hitConditi self.hitCondition = hitCondition self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) instructionReference = self.instructionReference offset = self.offset condition = self.condition hitCondition = self.hitCondition dct = { - 'instructionReference': instructionReference, + "instructionReference": instructionReference, } if offset is not None: - dct['offset'] = offset + dct["offset"] = offset if condition is not None: - dct['condition'] = condition + dct["condition"] = condition if hitCondition is not None: - dct['hitCondition'] = hitCondition + dct["hitCondition"] = hitCondition dct.update(self.kwargs) return dct @@ -14833,58 +12752,55 @@ class Breakpoint(BaseSchema): __props__ = { "id": { "type": "integer", - "description": "The identifier for the breakpoint. It is needed if breakpoint events are used to update or remove breakpoints." + "description": "The identifier for the breakpoint. It is needed if breakpoint events are used to update or remove breakpoints.", }, "verified": { "type": "boolean", - "description": "If True, the breakpoint could be set (but not necessarily at the desired location)." + "description": "If True, the breakpoint could be set (but not necessarily at the desired location).", }, "message": { "type": "string", - "description": "A message about the state of the breakpoint.\nThis is shown to the user and can be used to explain why a breakpoint could not be verified." - }, - "source": { - "description": "The source where the breakpoint is located.", - "type": "Source" - }, - "line": { - "type": "integer", - "description": "The start line of the actual range covered by the breakpoint." + "description": "A message about the state of the breakpoint.\nThis is shown to the user and can be used to explain why a breakpoint could not be verified.", }, + "source": {"description": "The source where the breakpoint is located.", "type": "Source"}, + "line": {"type": "integer", "description": "The start line of the actual range covered by the breakpoint."}, "column": { "type": "integer", - "description": "Start position of the source range covered by the breakpoint. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." - }, - "endLine": { - "type": "integer", - "description": "The end line of the actual range covered by the breakpoint." + "description": "Start position of the source range covered by the breakpoint. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, + "endLine": {"type": "integer", "description": "The end line of the actual range covered by the breakpoint."}, "endColumn": { "type": "integer", - "description": "End position of the source range covered by the breakpoint. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.\nIf no end line is given, then the end column is assumed to be in the start line." - }, - "instructionReference": { - "type": "string", - "description": "A memory reference to where the breakpoint is set." - }, - "offset": { - "type": "integer", - "description": "The offset from the instruction reference.\nThis can be negative." + "description": "End position of the source range covered by the breakpoint. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.\nIf no end line is given, then the end column is assumed to be in the start line.", }, + "instructionReference": {"type": "string", "description": "A memory reference to where the breakpoint is set."}, + "offset": {"type": "integer", "description": "The offset from the instruction reference.\nThis can be negative."}, "reason": { "type": "string", "description": "A machine-readable explanation of why a breakpoint may not be verified. If a breakpoint is verified or a specific reason is not known, the adapter should omit this property. Possible values include:\n\n- `pending`: Indicates a breakpoint might be verified in the future, but the adapter cannot verify it in the current state.\n - `failed`: Indicates a breakpoint was not able to be verified, and the adapter does not believe it can be verified without intervention.", - "enum": [ - "pending", - "failed" - ] - } + "enum": ["pending", "failed"], + }, } - __refs__ = set(['source']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, verified, id=None, message=None, source=None, line=None, column=None, endLine=None, endColumn=None, instructionReference=None, offset=None, reason=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["source"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + verified, + id=None, + message=None, + source=None, + line=None, + column=None, + endLine=None, + endColumn=None, + instructionReference=None, + offset=None, + reason=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param boolean verified: If true, the breakpoint could be set (but not necessarily at the desired location). :param integer id: The identifier for the breakpoint. It is needed if breakpoint events are used to update or remove breakpoints. @@ -14900,7 +12816,7 @@ def __init__(self, verified, id=None, message=None, source=None, line=None, colu :param integer offset: The offset from the instruction reference. This can be negative. :param string reason: A machine-readable explanation of why a breakpoint may not be verified. If a breakpoint is verified or a specific reason is not known, the adapter should omit this property. Possible values include: - + - `pending`: Indicates a breakpoint might be verified in the future, but the adapter cannot verify it in the current state. - `failed`: Indicates a breakpoint was not able to be verified, and the adapter does not believe it can be verified without intervention. """ @@ -14910,7 +12826,7 @@ def __init__(self, verified, id=None, message=None, source=None, line=None, colu if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.line = line self.column = column self.endLine = endLine @@ -14920,7 +12836,6 @@ def __init__(self, verified, id=None, message=None, source=None, line=None, colu self.reason = reason self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) verified = self.verified id = self.id # noqa (assign to builtin) @@ -14934,28 +12849,28 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un offset = self.offset reason = self.reason dct = { - 'verified': verified, + "verified": verified, } if id is not None: - dct['id'] = id + dct["id"] = id if message is not None: - dct['message'] = message + dct["message"] = message if source is not None: - dct['source'] = source.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["source"] = source.to_dict(update_ids_to_dap=update_ids_to_dap) if line is not None: - dct['line'] = line + dct["line"] = line if column is not None: - dct['column'] = column + dct["column"] = column if endLine is not None: - dct['endLine'] = endLine + dct["endLine"] = endLine if endColumn is not None: - dct['endColumn'] = endColumn + dct["endColumn"] = endColumn if instructionReference is not None: - dct['instructionReference'] = instructionReference + dct["instructionReference"] = instructionReference if offset is not None: - dct['offset'] = offset + dct["offset"] = offset if reason is not None: - dct['reason'] = reason + dct["reason"] = reason dct.update(self.kwargs) return dct @@ -14968,28 +12883,24 @@ class SteppingGranularity(BaseSchema): Note: automatically generated code. Do not edit manually. """ - STATEMENT = 'statement' - LINE = 'line' - INSTRUCTION = 'instruction' + STATEMENT = "statement" + LINE = "line" + INSTRUCTION = "instruction" - VALID_VALUES = set(['statement', 'line', 'instruction']) + VALID_VALUES = set(["statement", "line", "instruction"]) __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct @@ -15004,34 +12915,22 @@ class StepInTarget(BaseSchema): """ __props__ = { - "id": { - "type": "integer", - "description": "Unique identifier for a step-in target." - }, - "label": { - "type": "string", - "description": "The name of the step-in target (shown in the UI)." - }, - "line": { - "type": "integer", - "description": "The line of the step-in target." - }, + "id": {"type": "integer", "description": "Unique identifier for a step-in target."}, + "label": {"type": "string", "description": "The name of the step-in target (shown in the UI)."}, + "line": {"type": "integer", "description": "The line of the step-in target."}, "column": { "type": "integer", - "description": "Start position of the range covered by the step in target. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." - }, - "endLine": { - "type": "integer", - "description": "The end line of the range covered by the step-in target." + "description": "Start position of the range covered by the step in target. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, + "endLine": {"type": "integer", "description": "The end line of the range covered by the step-in target."}, "endColumn": { "type": "integer", - "description": "End position of the range covered by the step in target. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." - } + "description": "End position of the range covered by the step in target. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, id, label, line=None, column=None, endLine=None, endColumn=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -15050,7 +12949,6 @@ def __init__(self, id, label, line=None, column=None, endLine=None, endColumn=No self.endColumn = endColumn self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) id = self.id # noqa (assign to builtin) label = self.label @@ -15059,17 +12957,17 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un endLine = self.endLine endColumn = self.endColumn dct = { - 'id': id, - 'label': label, + "id": id, + "label": label, } if line is not None: - dct['line'] = line + dct["line"] = line if column is not None: - dct['column'] = column + dct["column"] = column if endLine is not None: - dct['endLine'] = endLine + dct["endLine"] = endLine if endColumn is not None: - dct['endColumn'] = endColumn + dct["endColumn"] = endColumn dct.update(self.kwargs) return dct @@ -15078,47 +12976,40 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un class GotoTarget(BaseSchema): """ A `GotoTarget` describes a code location that can be used as a target in the `goto` request. - + The possible goto targets can be determined via the `gotoTargets` request. Note: automatically generated code. Do not edit manually. """ __props__ = { - "id": { - "type": "integer", - "description": "Unique identifier for a goto target. This is used in the `goto` request." - }, - "label": { - "type": "string", - "description": "The name of the goto target (shown in the UI)." - }, - "line": { - "type": "integer", - "description": "The line of the goto target." - }, - "column": { - "type": "integer", - "description": "The column of the goto target." - }, - "endLine": { - "type": "integer", - "description": "The end line of the range covered by the goto target." - }, - "endColumn": { - "type": "integer", - "description": "The end column of the range covered by the goto target." - }, + "id": {"type": "integer", "description": "Unique identifier for a goto target. This is used in the `goto` request."}, + "label": {"type": "string", "description": "The name of the goto target (shown in the UI)."}, + "line": {"type": "integer", "description": "The line of the goto target."}, + "column": {"type": "integer", "description": "The column of the goto target."}, + "endLine": {"type": "integer", "description": "The end line of the range covered by the goto target."}, + "endColumn": {"type": "integer", "description": "The end column of the range covered by the goto target."}, "instructionPointerReference": { "type": "string", - "description": "A memory reference for the instruction pointer value represented by this target." - } + "description": "A memory reference for the instruction pointer value represented by this target.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, id, label, line, column=None, endLine=None, endColumn=None, instructionPointerReference=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + id, + label, + line, + column=None, + endLine=None, + endColumn=None, + instructionPointerReference=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param integer id: Unique identifier for a goto target. This is used in the `goto` request. :param string label: The name of the goto target (shown in the UI). @@ -15137,7 +13028,6 @@ def __init__(self, id, label, line, column=None, endLine=None, endColumn=None, i self.instructionPointerReference = instructionPointerReference self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) id = self.id # noqa (assign to builtin) label = self.label @@ -15147,18 +13037,18 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un endColumn = self.endColumn instructionPointerReference = self.instructionPointerReference dct = { - 'id': id, - 'label': label, - 'line': line, + "id": id, + "label": label, + "line": line, } if column is not None: - dct['column'] = column + dct["column"] = column if endLine is not None: - dct['endLine'] = endLine + dct["endLine"] = endLine if endColumn is not None: - dct['endColumn'] = endColumn + dct["endColumn"] = endColumn if instructionPointerReference is not None: - dct['instructionPointerReference'] = instructionPointerReference + dct["instructionPointerReference"] = instructionPointerReference dct.update(self.kwargs) return dct @@ -15174,46 +13064,56 @@ class CompletionItem(BaseSchema): __props__ = { "label": { "type": "string", - "description": "The label of this completion item. By default this is also the text that is inserted when selecting this completion." - }, - "text": { - "type": "string", - "description": "If text is returned and not an empty string, then it is inserted instead of the label." + "description": "The label of this completion item. By default this is also the text that is inserted when selecting this completion.", }, + "text": {"type": "string", "description": "If text is returned and not an empty string, then it is inserted instead of the label."}, "sortText": { "type": "string", - "description": "A string that should be used when comparing this item with other items. If not returned or an empty string, the `label` is used instead." + "description": "A string that should be used when comparing this item with other items. If not returned or an empty string, the `label` is used instead.", }, "detail": { "type": "string", - "description": "A human-readable string with additional information about this item, like type or symbol information." + "description": "A human-readable string with additional information about this item, like type or symbol information.", }, "type": { "description": "The item's type. Typically the client uses this information to render the item in the UI with an icon.", - "type": "CompletionItemType" + "type": "CompletionItemType", }, "start": { "type": "integer", - "description": "Start position (within the `text` attribute of the `completions` request) where the completion text is added. The position is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based. If the start position is omitted the text is added at the location specified by the `column` attribute of the `completions` request." + "description": "Start position (within the `text` attribute of the `completions` request) where the completion text is added. The position is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based. If the start position is omitted the text is added at the location specified by the `column` attribute of the `completions` request.", }, "length": { "type": "integer", - "description": "Length determines how many characters are overwritten by the completion text and it is measured in UTF-16 code units. If missing the value 0 is assumed which results in the completion text being inserted." + "description": "Length determines how many characters are overwritten by the completion text and it is measured in UTF-16 code units. If missing the value 0 is assumed which results in the completion text being inserted.", }, "selectionStart": { "type": "integer", - "description": "Determines the start of the new selection after the text has been inserted (or replaced). `selectionStart` is measured in UTF-16 code units and must be in the range 0 and length of the completion text. If omitted the selection starts at the end of the completion text." + "description": "Determines the start of the new selection after the text has been inserted (or replaced). `selectionStart` is measured in UTF-16 code units and must be in the range 0 and length of the completion text. If omitted the selection starts at the end of the completion text.", }, "selectionLength": { "type": "integer", - "description": "Determines the length of the new selection after the text has been inserted (or replaced) and it is measured in UTF-16 code units. The selection can not extend beyond the bounds of the completion text. If omitted the length is assumed to be 0." - } + "description": "Determines the length of the new selection after the text has been inserted (or replaced) and it is measured in UTF-16 code units. The selection can not extend beyond the bounds of the completion text. If omitted the length is assumed to be 0.", + }, } - __refs__ = set(['type']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, label, text=None, sortText=None, detail=None, type=None, start=None, length=None, selectionStart=None, selectionLength=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["type"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + label, + text=None, + sortText=None, + detail=None, + type=None, + start=None, + length=None, + selectionStart=None, + selectionLength=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string label: The label of this completion item. By default this is also the text that is inserted when selecting this completion. :param string text: If text is returned and not an empty string, then it is inserted instead of the label. @@ -15238,7 +13138,6 @@ def __init__(self, label, text=None, sortText=None, detail=None, type=None, star self.selectionLength = selectionLength self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) label = self.label text = self.text @@ -15250,24 +13149,24 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un selectionStart = self.selectionStart selectionLength = self.selectionLength dct = { - 'label': label, + "label": label, } if text is not None: - dct['text'] = text + dct["text"] = text if sortText is not None: - dct['sortText'] = sortText + dct["sortText"] = sortText if detail is not None: - dct['detail'] = detail + dct["detail"] = detail if type is not None: - dct['type'] = type + dct["type"] = type if start is not None: - dct['start'] = start + dct["start"] = start if length is not None: - dct['length'] = length + dct["length"] = length if selectionStart is not None: - dct['selectionStart'] = selectionStart + dct["selectionStart"] = selectionStart if selectionLength is not None: - dct['selectionLength'] = selectionLength + dct["selectionLength"] = selectionLength dct.update(self.kwargs) return dct @@ -15281,44 +13180,62 @@ class CompletionItemType(BaseSchema): Note: automatically generated code. Do not edit manually. """ - METHOD = 'method' - FUNCTION = 'function' - CONSTRUCTOR = 'constructor' - FIELD = 'field' - VARIABLE = 'variable' - CLASS = 'class' - INTERFACE = 'interface' - MODULE = 'module' - PROPERTY = 'property' - UNIT = 'unit' - VALUE = 'value' - ENUM = 'enum' - KEYWORD = 'keyword' - SNIPPET = 'snippet' - TEXT = 'text' - COLOR = 'color' - FILE = 'file' - REFERENCE = 'reference' - CUSTOMCOLOR = 'customcolor' - - VALID_VALUES = set(['method', 'function', 'constructor', 'field', 'variable', 'class', 'interface', 'module', 'property', 'unit', 'value', 'enum', 'keyword', 'snippet', 'text', 'color', 'file', 'reference', 'customcolor']) + METHOD = "method" + FUNCTION = "function" + CONSTRUCTOR = "constructor" + FIELD = "field" + VARIABLE = "variable" + CLASS = "class" + INTERFACE = "interface" + MODULE = "module" + PROPERTY = "property" + UNIT = "unit" + VALUE = "value" + ENUM = "enum" + KEYWORD = "keyword" + SNIPPET = "snippet" + TEXT = "text" + COLOR = "color" + FILE = "file" + REFERENCE = "reference" + CUSTOMCOLOR = "customcolor" + + VALID_VALUES = set( + [ + "method", + "function", + "constructor", + "field", + "variable", + "class", + "interface", + "module", + "property", + "unit", + "value", + "enum", + "keyword", + "snippet", + "text", + "color", + "file", + "reference", + "customcolor", + ] + ) __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct @@ -15331,29 +13248,25 @@ class ChecksumAlgorithm(BaseSchema): Note: automatically generated code. Do not edit manually. """ - MD5 = 'MD5' - SHA1 = 'SHA1' - SHA256 = 'SHA256' - TIMESTAMP = 'timestamp' + MD5 = "MD5" + SHA1 = "SHA1" + SHA256 = "SHA256" + TIMESTAMP = "timestamp" - VALID_VALUES = set(['MD5', 'SHA1', 'SHA256', 'timestamp']) + VALID_VALUES = set(["MD5", "SHA1", "SHA256", "timestamp"]) __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct @@ -15367,18 +13280,12 @@ class Checksum(BaseSchema): """ __props__ = { - "algorithm": { - "description": "The algorithm used to calculate this checksum.", - "type": "ChecksumAlgorithm" - }, - "checksum": { - "type": "string", - "description": "Value of the checksum, encoded as a hexadecimal value." - } + "algorithm": {"description": "The algorithm used to calculate this checksum.", "type": "ChecksumAlgorithm"}, + "checksum": {"type": "string", "description": "Value of the checksum, encoded as a hexadecimal value."}, } - __refs__ = set(['algorithm']) + __refs__ = set(["algorithm"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, algorithm, checksum, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -15391,13 +13298,12 @@ def __init__(self, algorithm, checksum, update_ids_from_dap=False, **kwargs): # self.checksum = checksum self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) algorithm = self.algorithm checksum = self.checksum dct = { - 'algorithm': algorithm, - 'checksum': checksum, + "algorithm": algorithm, + "checksum": checksum, } dct.update(self.kwargs) return dct @@ -15411,15 +13317,10 @@ class ValueFormat(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "hex": { - "type": "boolean", - "description": "Display the value in hex." - } - } + __props__ = {"hex": {"type": "boolean", "description": "Display the value in hex."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, hex=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -15428,13 +13329,11 @@ def __init__(self, hex=None, update_ids_from_dap=False, **kwargs): # noqa (upda self.hex = hex self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) hex = self.hex # noqa (assign to builtin) - dct = { - } + dct = {} if hex is not None: - dct['hex'] = hex + dct["hex"] = hex dct.update(self.kwargs) return dct @@ -15448,44 +13347,35 @@ class StackFrameFormat(BaseSchema): """ __props__ = { - "hex": { - "type": "boolean", - "description": "Display the value in hex." - }, - "parameters": { - "type": "boolean", - "description": "Displays parameters for the stack frame." - }, - "parameterTypes": { - "type": "boolean", - "description": "Displays the types of parameters for the stack frame." - }, - "parameterNames": { - "type": "boolean", - "description": "Displays the names of parameters for the stack frame." - }, - "parameterValues": { - "type": "boolean", - "description": "Displays the values of parameters for the stack frame." - }, - "line": { - "type": "boolean", - "description": "Displays the line number of the stack frame." - }, - "module": { - "type": "boolean", - "description": "Displays the module of the stack frame." - }, + "hex": {"type": "boolean", "description": "Display the value in hex."}, + "parameters": {"type": "boolean", "description": "Displays parameters for the stack frame."}, + "parameterTypes": {"type": "boolean", "description": "Displays the types of parameters for the stack frame."}, + "parameterNames": {"type": "boolean", "description": "Displays the names of parameters for the stack frame."}, + "parameterValues": {"type": "boolean", "description": "Displays the values of parameters for the stack frame."}, + "line": {"type": "boolean", "description": "Displays the line number of the stack frame."}, + "module": {"type": "boolean", "description": "Displays the module of the stack frame."}, "includeAll": { "type": "boolean", - "description": "Includes all stack frames, including those the debug adapter might otherwise hide." - } + "description": "Includes all stack frames, including those the debug adapter might otherwise hide.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, hex=None, parameters=None, parameterTypes=None, parameterNames=None, parameterValues=None, line=None, module=None, includeAll=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + hex=None, + parameters=None, + parameterTypes=None, + parameterNames=None, + parameterValues=None, + line=None, + module=None, + includeAll=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param boolean hex: Display the value in hex. :param boolean parameters: Displays parameters for the stack frame. @@ -15506,7 +13396,6 @@ def __init__(self, hex=None, parameters=None, parameterTypes=None, parameterName self.includeAll = includeAll self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) hex = self.hex # noqa (assign to builtin) parameters = self.parameters @@ -15516,24 +13405,23 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un line = self.line module = self.module includeAll = self.includeAll - dct = { - } + dct = {} if hex is not None: - dct['hex'] = hex + dct["hex"] = hex if parameters is not None: - dct['parameters'] = parameters + dct["parameters"] = parameters if parameterTypes is not None: - dct['parameterTypes'] = parameterTypes + dct["parameterTypes"] = parameterTypes if parameterNames is not None: - dct['parameterNames'] = parameterNames + dct["parameterNames"] = parameterNames if parameterValues is not None: - dct['parameterValues'] = parameterValues + dct["parameterValues"] = parameterValues if line is not None: - dct['line'] = line + dct["line"] = line if module is not None: - dct['module'] = module + dct["module"] = module if includeAll is not None: - dct['includeAll'] = includeAll + dct["includeAll"] = includeAll dct.update(self.kwargs) return dct @@ -15548,18 +13436,15 @@ class ExceptionFilterOptions(BaseSchema): """ __props__ = { - "filterId": { - "type": "string", - "description": "ID of an exception filter returned by the `exceptionBreakpointFilters` capability." - }, + "filterId": {"type": "string", "description": "ID of an exception filter returned by the `exceptionBreakpointFilters` capability."}, "condition": { "type": "string", - "description": "An expression for conditional exceptions.\nThe exception breaks into the debugger if the result of the condition is True." - } + "description": "An expression for conditional exceptions.\nThe exception breaks into the debugger if the result of the condition is True.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, filterId, condition=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -15571,15 +13456,14 @@ def __init__(self, filterId, condition=None, update_ids_from_dap=False, **kwargs self.condition = condition self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) filterId = self.filterId condition = self.condition dct = { - 'filterId': filterId, + "filterId": filterId, } if condition is not None: - dct['condition'] = condition + dct["condition"] = condition dct.update(self.kwargs) return dct @@ -15595,19 +13479,14 @@ class ExceptionOptions(BaseSchema): __props__ = { "path": { "type": "array", - "items": { - "$ref": "#/definitions/ExceptionPathSegment" - }, - "description": "A path that selects a single or multiple exceptions in a tree. If `path` is missing, the whole tree is selected.\nBy convention the first segment of the path is a category that is used to group exceptions in the UI." + "items": {"$ref": "#/definitions/ExceptionPathSegment"}, + "description": "A path that selects a single or multiple exceptions in a tree. If `path` is missing, the whole tree is selected.\nBy convention the first segment of the path is a category that is used to group exceptions in the UI.", }, - "breakMode": { - "description": "Condition when a thrown exception should result in a break.", - "type": "ExceptionBreakMode" - } + "breakMode": {"description": "Condition when a thrown exception should result in a break.", "type": "ExceptionBreakMode"}, } - __refs__ = set(['breakMode']) + __refs__ = set(["breakMode"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakMode, path=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -15624,17 +13503,16 @@ def __init__(self, breakMode, path=None, update_ids_from_dap=False, **kwargs): ExceptionPathSegment.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakMode = self.breakMode path = self.path if path and hasattr(path[0], "to_dict"): path = [x.to_dict() for x in path] dct = { - 'breakMode': breakMode, + "breakMode": breakMode, } if path is not None: - dct['path'] = [ExceptionPathSegment.update_dict_ids_to_dap(o) for o in path] if (update_ids_to_dap and path) else path + dct["path"] = [ExceptionPathSegment.update_dict_ids_to_dap(o) for o in path] if (update_ids_to_dap and path) else path dct.update(self.kwargs) return dct @@ -15643,41 +13521,37 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un class ExceptionBreakMode(BaseSchema): """ This enumeration defines all possible conditions when a thrown exception should result in a break. - + never: never breaks, - + always: always breaks, - + unhandled: breaks when exception unhandled, - + userUnhandled: breaks if the exception is not handled by user code. Note: automatically generated code. Do not edit manually. """ - NEVER = 'never' - ALWAYS = 'always' - UNHANDLED = 'unhandled' - USERUNHANDLED = 'userUnhandled' + NEVER = "never" + ALWAYS = "always" + UNHANDLED = "unhandled" + USERUNHANDLED = "userUnhandled" - VALID_VALUES = set(['never', 'always', 'unhandled', 'userUnhandled']) + VALID_VALUES = set(["never", "always", "unhandled", "userUnhandled"]) __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct @@ -15687,7 +13561,7 @@ class ExceptionPathSegment(BaseSchema): """ An `ExceptionPathSegment` represents a segment in a path that is used to match leafs or nodes in a tree of exceptions. - + If a segment consists of more than one name, it matches the names provided if `negate` is false or missing, or it matches anything except the names provided if `negate` is true. @@ -15697,19 +13571,17 @@ class ExceptionPathSegment(BaseSchema): __props__ = { "negate": { "type": "boolean", - "description": "If false or missing this segment matches the names provided, otherwise it matches anything except the names provided." + "description": "If false or missing this segment matches the names provided, otherwise it matches anything except the names provided.", }, "names": { "type": "array", - "items": { - "type": "string" - }, - "description": "Depending on the value of `negate` the names that should match or not match." - } + "items": {"type": "string"}, + "description": "Depending on the value of `negate` the names that should match or not match.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, names, negate=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -15720,17 +13592,16 @@ def __init__(self, names, negate=None, update_ids_from_dap=False, **kwargs): # self.negate = negate self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) names = self.names if names and hasattr(names[0], "to_dict"): names = [x.to_dict() for x in names] negate = self.negate dct = { - 'names': names, + "names": names, } if negate is not None: - dct['negate'] = negate + dct["negate"] = negate dct.update(self.kwargs) return dct @@ -15744,39 +13615,35 @@ class ExceptionDetails(BaseSchema): """ __props__ = { - "message": { - "type": "string", - "description": "Message contained in the exception." - }, - "typeName": { - "type": "string", - "description": "Short type name of the exception object." - }, - "fullTypeName": { - "type": "string", - "description": "Fully-qualified type name of the exception object." - }, + "message": {"type": "string", "description": "Message contained in the exception."}, + "typeName": {"type": "string", "description": "Short type name of the exception object."}, + "fullTypeName": {"type": "string", "description": "Fully-qualified type name of the exception object."}, "evaluateName": { "type": "string", - "description": "An expression that can be evaluated in the current scope to obtain the exception object." - }, - "stackTrace": { - "type": "string", - "description": "Stack trace at the time the exception was thrown." + "description": "An expression that can be evaluated in the current scope to obtain the exception object.", }, + "stackTrace": {"type": "string", "description": "Stack trace at the time the exception was thrown."}, "innerException": { "type": "array", - "items": { - "$ref": "#/definitions/ExceptionDetails" - }, - "description": "Details of the exception contained by this exception, if any." - } + "items": {"$ref": "#/definitions/ExceptionDetails"}, + "description": "Details of the exception contained by this exception, if any.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] - def __init__(self, message=None, typeName=None, fullTypeName=None, evaluateName=None, stackTrace=None, innerException=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__( + self, + message=None, + typeName=None, + fullTypeName=None, + evaluateName=None, + stackTrace=None, + innerException=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string message: Message contained in the exception. :param string typeName: Short type name of the exception object. @@ -15796,7 +13663,6 @@ def __init__(self, message=None, typeName=None, fullTypeName=None, evaluateName= ExceptionDetails.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) message = self.message typeName = self.typeName @@ -15806,20 +13672,23 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un innerException = self.innerException if innerException and hasattr(innerException[0], "to_dict"): innerException = [x.to_dict() for x in innerException] - dct = { - } + dct = {} if message is not None: - dct['message'] = message + dct["message"] = message if typeName is not None: - dct['typeName'] = typeName + dct["typeName"] = typeName if fullTypeName is not None: - dct['fullTypeName'] = fullTypeName + dct["fullTypeName"] = fullTypeName if evaluateName is not None: - dct['evaluateName'] = evaluateName + dct["evaluateName"] = evaluateName if stackTrace is not None: - dct['stackTrace'] = stackTrace + dct["stackTrace"] = stackTrace if innerException is not None: - dct['innerException'] = [ExceptionDetails.update_dict_ids_to_dap(o) for o in innerException] if (update_ids_to_dap and innerException) else innerException + dct["innerException"] = ( + [ExceptionDetails.update_dict_ids_to_dap(o) for o in innerException] + if (update_ids_to_dap and innerException) + else innerException + ) dct.update(self.kwargs) return dct @@ -15835,54 +13704,50 @@ class DisassembledInstruction(BaseSchema): __props__ = { "address": { "type": "string", - "description": "The address of the instruction. Treated as a hex value if prefixed with `0x`, or as a decimal value otherwise." + "description": "The address of the instruction. Treated as a hex value if prefixed with `0x`, or as a decimal value otherwise.", }, "instructionBytes": { "type": "string", - "description": "Raw bytes representing the instruction and its operands, in an implementation-defined format." + "description": "Raw bytes representing the instruction and its operands, in an implementation-defined format.", }, "instruction": { "type": "string", - "description": "Text representing the instruction and its operands, in an implementation-defined format." - }, - "symbol": { - "type": "string", - "description": "Name of the symbol that corresponds with the location of this instruction, if any." + "description": "Text representing the instruction and its operands, in an implementation-defined format.", }, + "symbol": {"type": "string", "description": "Name of the symbol that corresponds with the location of this instruction, if any."}, "location": { "description": "Source location that corresponds to this instruction, if any.\nShould always be set (if available) on the first instruction returned,\nbut can be omitted afterwards if this instruction maps to the same source file as the previous instruction.", - "type": "Source" - }, - "line": { - "type": "integer", - "description": "The line within the source location that corresponds to this instruction, if any." - }, - "column": { - "type": "integer", - "description": "The column within the line that corresponds to this instruction, if any." - }, - "endLine": { - "type": "integer", - "description": "The end line of the range that corresponds to this instruction, if any." - }, - "endColumn": { - "type": "integer", - "description": "The end column of the range that corresponds to this instruction, if any." + "type": "Source", }, + "line": {"type": "integer", "description": "The line within the source location that corresponds to this instruction, if any."}, + "column": {"type": "integer", "description": "The column within the line that corresponds to this instruction, if any."}, + "endLine": {"type": "integer", "description": "The end line of the range that corresponds to this instruction, if any."}, + "endColumn": {"type": "integer", "description": "The end column of the range that corresponds to this instruction, if any."}, "presentationHint": { "type": "string", "description": "A hint for how to present the instruction in the UI.\n\nA value of `invalid` may be used to indicate this instruction is 'filler' and cannot be reached by the program. For example, unreadable memory addresses may be presented is 'invalid.'", - "enum": [ - "normal", - "invalid" - ] - } + "enum": ["normal", "invalid"], + }, } - __refs__ = set(['location']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, address, instruction, instructionBytes=None, symbol=None, location=None, line=None, column=None, endLine=None, endColumn=None, presentationHint=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["location"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + address, + instruction, + instructionBytes=None, + symbol=None, + location=None, + line=None, + column=None, + endLine=None, + endColumn=None, + presentationHint=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string address: The address of the instruction. Treated as a hex value if prefixed with `0x`, or as a decimal value otherwise. :param string instruction: Text representing the instruction and its operands, in an implementation-defined format. @@ -15896,7 +13761,7 @@ def __init__(self, address, instruction, instructionBytes=None, symbol=None, loc :param integer endLine: The end line of the range that corresponds to this instruction, if any. :param integer endColumn: The end column of the range that corresponds to this instruction, if any. :param string presentationHint: A hint for how to present the instruction in the UI. - + A value of `invalid` may be used to indicate this instruction is 'filler' and cannot be reached by the program. For example, unreadable memory addresses may be presented is 'invalid.' """ self.address = address @@ -15906,7 +13771,7 @@ def __init__(self, address, instruction, instructionBytes=None, symbol=None, loc if location is None: self.location = Source() else: - self.location = Source(update_ids_from_dap=update_ids_from_dap, **location) if location.__class__ != Source else location + self.location = Source(update_ids_from_dap=update_ids_from_dap, **location) if location.__class__ != Source else location self.line = line self.column = column self.endLine = endLine @@ -15914,7 +13779,6 @@ def __init__(self, address, instruction, instructionBytes=None, symbol=None, loc self.presentationHint = presentationHint self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) address = self.address instruction = self.instruction @@ -15927,25 +13791,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un endColumn = self.endColumn presentationHint = self.presentationHint dct = { - 'address': address, - 'instruction': instruction, + "address": address, + "instruction": instruction, } if instructionBytes is not None: - dct['instructionBytes'] = instructionBytes + dct["instructionBytes"] = instructionBytes if symbol is not None: - dct['symbol'] = symbol + dct["symbol"] = symbol if location is not None: - dct['location'] = location.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["location"] = location.to_dict(update_ids_to_dap=update_ids_to_dap) if line is not None: - dct['line'] = line + dct["line"] = line if column is not None: - dct['column'] = column + dct["column"] = column if endLine is not None: - dct['endLine'] = endLine + dct["endLine"] = endLine if endColumn is not None: - dct['endColumn'] = endColumn + dct["endColumn"] = endColumn if presentationHint is not None: - dct['presentationHint'] = presentationHint + dct["presentationHint"] = presentationHint dct.update(self.kwargs) return dct @@ -15961,24 +13825,20 @@ class InvalidatedAreas(BaseSchema): __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct -@register_request('setDebuggerProperty') +@register_request("setDebuggerProperty") @register class SetDebuggerPropertyRequest(BaseSchema): """ @@ -15990,55 +13850,46 @@ class SetDebuggerPropertyRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "setDebuggerProperty" - ] - }, - "arguments": { - "type": "SetDebuggerPropertyArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setDebuggerProperty"]}, + "arguments": {"type": "SetDebuggerPropertyArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetDebuggerPropertyArguments arguments: + :param string type: + :param string command: + :param SetDebuggerPropertyArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setDebuggerProperty' + self.type = "request" + self.command = "setDebuggerProperty" if arguments is None: self.arguments = SetDebuggerPropertyArguments() else: - self.arguments = SetDebuggerPropertyArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetDebuggerPropertyArguments else arguments + self.arguments = ( + SetDebuggerPropertyArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetDebuggerPropertyArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -16053,48 +13904,43 @@ class SetDebuggerPropertyArguments(BaseSchema): """ __props__ = { - "ideOS": { - "type": [ - "string" - ], - "description": "OS where the ide is running. Supported values [Windows, Linux]" - }, + "ideOS": {"type": ["string"], "description": "OS where the ide is running. Supported values [Windows, Linux]"}, "dontTraceStartPatterns": { - "type": [ - "array" - ], - "description": "Patterns to match with the start of the file paths. Matching paths will be added to a list of file where trace is ignored." + "type": ["array"], + "description": "Patterns to match with the start of the file paths. Matching paths will be added to a list of file where trace is ignored.", }, "dontTraceEndPatterns": { - "type": [ - "array" - ], - "description": "Patterns to match with the end of the file paths. Matching paths will be added to a list of file where trace is ignored." + "type": ["array"], + "description": "Patterns to match with the end of the file paths. Matching paths will be added to a list of file where trace is ignored.", }, "skipSuspendOnBreakpointException": { - "type": [ - "array" - ], - "description": "List of exceptions that should be skipped when doing condition evaluations." + "type": ["array"], + "description": "List of exceptions that should be skipped when doing condition evaluations.", }, "skipPrintBreakpointException": { - "type": [ - "array" - ], - "description": "List of exceptions that should skip printing to stderr when doing condition evaluations." + "type": ["array"], + "description": "List of exceptions that should skip printing to stderr when doing condition evaluations.", }, "multiThreadsSingleNotification": { - "type": [ - "boolean" - ], - "description": "If false then a notification is generated for each thread event. If True a single event is gnenerated, and all threads follow that behavior." - } + "type": ["boolean"], + "description": "If false then a notification is generated for each thread event. If True a single event is gnenerated, and all threads follow that behavior.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] - def __init__(self, ideOS=None, dontTraceStartPatterns=None, dontTraceEndPatterns=None, skipSuspendOnBreakpointException=None, skipPrintBreakpointException=None, multiThreadsSingleNotification=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__( + self, + ideOS=None, + dontTraceStartPatterns=None, + dontTraceEndPatterns=None, + skipSuspendOnBreakpointException=None, + skipPrintBreakpointException=None, + multiThreadsSingleNotification=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param ['string'] ideOS: OS where the ide is running. Supported values [Windows, Linux] :param ['array'] dontTraceStartPatterns: Patterns to match with the start of the file paths. Matching paths will be added to a list of file where trace is ignored. @@ -16111,7 +13957,6 @@ def __init__(self, ideOS=None, dontTraceStartPatterns=None, dontTraceEndPatterns self.multiThreadsSingleNotification = multiThreadsSingleNotification self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) ideOS = self.ideOS dontTraceStartPatterns = self.dontTraceStartPatterns @@ -16119,25 +13964,24 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un skipSuspendOnBreakpointException = self.skipSuspendOnBreakpointException skipPrintBreakpointException = self.skipPrintBreakpointException multiThreadsSingleNotification = self.multiThreadsSingleNotification - dct = { - } + dct = {} if ideOS is not None: - dct['ideOS'] = ideOS + dct["ideOS"] = ideOS if dontTraceStartPatterns is not None: - dct['dontTraceStartPatterns'] = dontTraceStartPatterns + dct["dontTraceStartPatterns"] = dontTraceStartPatterns if dontTraceEndPatterns is not None: - dct['dontTraceEndPatterns'] = dontTraceEndPatterns + dct["dontTraceEndPatterns"] = dontTraceEndPatterns if skipSuspendOnBreakpointException is not None: - dct['skipSuspendOnBreakpointException'] = skipSuspendOnBreakpointException + dct["skipSuspendOnBreakpointException"] = skipSuspendOnBreakpointException if skipPrintBreakpointException is not None: - dct['skipPrintBreakpointException'] = skipPrintBreakpointException + dct["skipPrintBreakpointException"] = skipPrintBreakpointException if multiThreadsSingleNotification is not None: - dct['multiThreadsSingleNotification'] = multiThreadsSingleNotification + dct["multiThreadsSingleNotification"] = multiThreadsSingleNotification dct.update(self.kwargs) return dct -@register_response('setDebuggerProperty') +@register_response("setDebuggerProperty") @register class SetDebuggerPropertyResponse(BaseSchema): """ @@ -16150,58 +13994,33 @@ class SetDebuggerPropertyResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -16213,7 +14032,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -16222,7 +14041,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -16232,21 +14050,21 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_event('pydevdInputRequested') +@register_event("pydevdInputRequested") @register class PydevdInputRequestedEvent(BaseSchema): """ @@ -16258,82 +14076,63 @@ class PydevdInputRequestedEvent(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "event" - ] - }, - "event": { - "type": "string", - "enum": [ - "pydevdInputRequested" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["event"]}, + "event": {"type": "string", "enum": ["pydevdInputRequested"]}, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Event-specific information." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Event-specific information.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string event: + :param string type: + :param string event: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Event-specific information. """ - self.type = 'event' - self.event = 'pydevdInputRequested' + self.type = "event" + self.event = "pydevdInputRequested" self.seq = seq self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) event = self.event seq = self.seq body = self.body dct = { - 'type': type, - 'event': event, - 'seq': seq, + "type": type, + "event": event, + "seq": seq, } if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct -@register_request('setPydevdSourceMap') +@register_request("setPydevdSourceMap") @register class SetPydevdSourceMapRequest(BaseSchema): """ Sets multiple PydevdSourceMap for a single source and clears all previous PydevdSourceMap in that source. - + i.e.: Maps paths and lines in a 1:N mapping (use case: map a single file in the IDE to multiple IPython cells). - + To clear all PydevdSourceMap for a source, specify an empty array. - + Interaction with breakpoints: When a new mapping is sent, breakpoints that match the source (or previously matched a source) are reapplied. - + Interaction with launch pathMapping: both mappings are independent. This mapping is applied after the launch pathMapping. @@ -16343,55 +14142,46 @@ class SetPydevdSourceMapRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "setPydevdSourceMap" - ] - }, - "arguments": { - "type": "SetPydevdSourceMapArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["setPydevdSourceMap"]}, + "arguments": {"type": "SetPydevdSourceMapArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param SetPydevdSourceMapArguments arguments: + :param string type: + :param string command: + :param SetPydevdSourceMapArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'setPydevdSourceMap' + self.type = "request" + self.command = "setPydevdSourceMap" if arguments is None: self.arguments = SetPydevdSourceMapArguments() else: - self.arguments = SetPydevdSourceMapArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != SetPydevdSourceMapArguments else arguments + self.arguments = ( + SetPydevdSourceMapArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != SetPydevdSourceMapArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -16408,19 +14198,17 @@ class SetPydevdSourceMapArguments(BaseSchema): __props__ = { "source": { "description": "The source location of the PydevdSourceMap; 'source.path' must be specified (e.g.: for an ipython notebook this could be something as /home/notebook/note.py).", - "type": "Source" + "type": "Source", }, "pydevdSourceMaps": { "type": "array", - "items": { - "$ref": "#/definitions/PydevdSourceMap" - }, - "description": "The PydevdSourceMaps to be set to the given source (provide an empty array to clear the source mappings for a given path)." - } + "items": {"$ref": "#/definitions/PydevdSourceMap"}, + "description": "The PydevdSourceMaps to be set to the given source (provide an empty array to clear the source mappings for a given path).", + }, } - __refs__ = set(['source']) + __refs__ = set(["source"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, source, pydevdSourceMaps=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -16430,29 +14218,32 @@ def __init__(self, source, pydevdSourceMaps=None, update_ids_from_dap=False, **k if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.pydevdSourceMaps = pydevdSourceMaps if update_ids_from_dap and self.pydevdSourceMaps: for o in self.pydevdSourceMaps: PydevdSourceMap.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) source = self.source pydevdSourceMaps = self.pydevdSourceMaps if pydevdSourceMaps and hasattr(pydevdSourceMaps[0], "to_dict"): pydevdSourceMaps = [x.to_dict() for x in pydevdSourceMaps] dct = { - 'source': source.to_dict(update_ids_to_dap=update_ids_to_dap), + "source": source.to_dict(update_ids_to_dap=update_ids_to_dap), } if pydevdSourceMaps is not None: - dct['pydevdSourceMaps'] = [PydevdSourceMap.update_dict_ids_to_dap(o) for o in pydevdSourceMaps] if (update_ids_to_dap and pydevdSourceMaps) else pydevdSourceMaps + dct["pydevdSourceMaps"] = ( + [PydevdSourceMap.update_dict_ids_to_dap(o) for o in pydevdSourceMaps] + if (update_ids_to_dap and pydevdSourceMaps) + else pydevdSourceMaps + ) dct.update(self.kwargs) return dct -@register_response('setPydevdSourceMap') +@register_response("setPydevdSourceMap") @register class SetPydevdSourceMapResponse(BaseSchema): """ @@ -16465,58 +14256,33 @@ class SetPydevdSourceMapResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Contains request result if success is True and error details if success is false." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Contains request result if success is True and error details if success is false.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, seq=-1, message=None, body=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. @@ -16528,7 +14294,7 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non Some predefined values exist. :param ['array', 'boolean', 'integer', 'null', 'number', 'object', 'string'] body: Contains request result if success is true and error details if success is false. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command @@ -16537,7 +14303,6 @@ def __init__(self, request_seq, success, command, seq=-1, message=None, body=Non self.body = body self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -16547,16 +14312,16 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message body = self.body dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message if body is not None: - dct['body'] = body + dct["body"] = body dct.update(self.kwargs) return dct @@ -16572,24 +14337,21 @@ class PydevdSourceMap(BaseSchema): __props__ = { "line": { "type": "integer", - "description": "The local line to which the mapping should map to (e.g.: for an ipython notebook this would be the first line of the cell in the file)." - }, - "endLine": { - "type": "integer", - "description": "The end line." + "description": "The local line to which the mapping should map to (e.g.: for an ipython notebook this would be the first line of the cell in the file).", }, + "endLine": {"type": "integer", "description": "The end line."}, "runtimeSource": { "description": "The path that the user has remotely -- 'source.path' must be specified (e.g.: for an ipython notebook this could be something as '')", - "type": "Source" + "type": "Source", }, "runtimeLine": { "type": "integer", - "description": "The remote line to which the mapping should map to (e.g.: for an ipython notebook this would be always 1 as it'd map the start of the cell)." - } + "description": "The remote line to which the mapping should map to (e.g.: for an ipython notebook this would be always 1 as it'd map the start of the cell).", + }, } - __refs__ = set(['runtimeSource']) + __refs__ = set(["runtimeSource"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, line, endLine, runtimeSource, runtimeLine, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -16603,27 +14365,28 @@ def __init__(self, line, endLine, runtimeSource, runtimeLine, update_ids_from_da if runtimeSource is None: self.runtimeSource = Source() else: - self.runtimeSource = Source(update_ids_from_dap=update_ids_from_dap, **runtimeSource) if runtimeSource.__class__ != Source else runtimeSource + self.runtimeSource = ( + Source(update_ids_from_dap=update_ids_from_dap, **runtimeSource) if runtimeSource.__class__ != Source else runtimeSource + ) self.runtimeLine = runtimeLine self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) line = self.line endLine = self.endLine runtimeSource = self.runtimeSource runtimeLine = self.runtimeLine dct = { - 'line': line, - 'endLine': endLine, - 'runtimeSource': runtimeSource.to_dict(update_ids_to_dap=update_ids_to_dap), - 'runtimeLine': runtimeLine, + "line": line, + "endLine": endLine, + "runtimeSource": runtimeSource.to_dict(update_ids_to_dap=update_ids_to_dap), + "runtimeLine": runtimeLine, } dct.update(self.kwargs) return dct -@register_request('pydevdSystemInfo') +@register_request("pydevdSystemInfo") @register class PydevdSystemInfoRequest(BaseSchema): """ @@ -16635,57 +14398,48 @@ class PydevdSystemInfoRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "command": { - "type": "string", - "enum": [ - "pydevdSystemInfo" - ] - }, - "arguments": { - "type": "PydevdSystemInfoArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["pydevdSystemInfo"]}, + "arguments": {"type": "PydevdSystemInfoArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, seq=-1, arguments=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: + :param string type: + :param string command: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. - :param PydevdSystemInfoArguments arguments: + :param PydevdSystemInfoArguments arguments: """ - self.type = 'request' - self.command = 'pydevdSystemInfo' + self.type = "request" + self.command = "pydevdSystemInfo" self.seq = seq if arguments is None: self.arguments = PydevdSystemInfoArguments() else: - self.arguments = PydevdSystemInfoArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != PydevdSystemInfoArguments else arguments + self.arguments = ( + PydevdSystemInfoArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != PydevdSystemInfoArguments + else arguments + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command seq = self.seq arguments = self.arguments dct = { - 'type': type, - 'command': command, - 'seq': seq, + "type": type, + "command": command, + "seq": seq, } if arguments is not None: - dct['arguments'] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["arguments"] = arguments.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -16701,24 +14455,20 @@ class PydevdSystemInfoArguments(BaseSchema): __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct -@register_response('pydevdSystemInfo') +@register_response("pydevdSystemInfo") @register class PydevdSystemInfoResponse(BaseSchema): """ @@ -16730,97 +14480,72 @@ class PydevdSystemInfoResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { "python": { "$ref": "#/definitions/PydevdPythonInfo", - "description": "Information about the python version running in the current process." + "description": "Information about the python version running in the current process.", }, "platform": { "$ref": "#/definitions/PydevdPlatformInfo", - "description": "Information about the plarforn on which the current process is running." - }, - "process": { - "$ref": "#/definitions/PydevdProcessInfo", - "description": "Information about the current process." + "description": "Information about the plarforn on which the current process is running.", }, - "pydevd": { - "$ref": "#/definitions/PydevdInfo", - "description": "Information about pydevd." - } + "process": {"$ref": "#/definitions/PydevdProcessInfo", "description": "Information about the current process."}, + "pydevd": {"$ref": "#/definitions/PydevdInfo", "description": "Information about pydevd."}, }, - "required": [ - "python", - "platform", - "process", - "pydevd" - ] - } + "required": ["python", "platform", "process", "pydevd"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param PydevdSystemInfoResponseBody body: + :param PydevdSystemInfoResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = PydevdSystemInfoResponseBody() else: - self.body = PydevdSystemInfoResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != PydevdSystemInfoResponseBody else body + self.body = ( + PydevdSystemInfoResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != PydevdSystemInfoResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -16830,15 +14555,15 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct @@ -16854,16 +14579,16 @@ class PydevdPythonInfo(BaseSchema): __props__ = { "version": { "type": "string", - "description": "Python version as a string in semver format: ..." + "description": "Python version as a string in semver format: ...", }, "implementation": { "description": "Python version as a string in this format ...", - "type": "PydevdPythonImplementationInfo" - } + "type": "PydevdPythonImplementationInfo", + }, } - __refs__ = set(['implementation']) + __refs__ = set(["implementation"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, version=None, implementation=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -16874,19 +14599,21 @@ def __init__(self, version=None, implementation=None, update_ids_from_dap=False, if implementation is None: self.implementation = PydevdPythonImplementationInfo() else: - self.implementation = PydevdPythonImplementationInfo(update_ids_from_dap=update_ids_from_dap, **implementation) if implementation.__class__ != PydevdPythonImplementationInfo else implementation + self.implementation = ( + PydevdPythonImplementationInfo(update_ids_from_dap=update_ids_from_dap, **implementation) + if implementation.__class__ != PydevdPythonImplementationInfo + else implementation + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) version = self.version implementation = self.implementation - dct = { - } + dct = {} if version is not None: - dct['version'] = version + dct["version"] = version if implementation is not None: - dct['implementation'] = implementation.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["implementation"] = implementation.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -16900,22 +14627,16 @@ class PydevdPythonImplementationInfo(BaseSchema): """ __props__ = { - "name": { - "type": "string", - "description": "Python implementation name." - }, + "name": {"type": "string", "description": "Python implementation name."}, "version": { "type": "string", - "description": "Python version as a string in semver format: ..." + "description": "Python version as a string in semver format: ...", }, - "description": { - "type": "string", - "description": "Optional description for this python implementation." - } + "description": {"type": "string", "description": "Optional description for this python implementation."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, name=None, version=None, description=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -16928,19 +14649,17 @@ def __init__(self, name=None, version=None, description=None, update_ids_from_da self.description = description self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) name = self.name version = self.version description = self.description - dct = { - } + dct = {} if name is not None: - dct['name'] = name + dct["name"] = name if version is not None: - dct['version'] = version + dct["version"] = version if description is not None: - dct['description'] = description + dct["description"] = description dct.update(self.kwargs) return dct @@ -16953,15 +14672,10 @@ class PydevdPlatformInfo(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "name": { - "type": "string", - "description": "Name of the platform as returned by 'sys.platform'." - } - } + __props__ = {"name": {"type": "string", "description": "Name of the platform as returned by 'sys.platform'."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, name=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -16970,13 +14684,11 @@ def __init__(self, name=None, update_ids_from_dap=False, **kwargs): # noqa (upd self.name = name self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) name = self.name - dct = { - } + dct = {} if name is not None: - dct['name'] = name + dct["name"] = name dct.update(self.kwargs) return dct @@ -16990,26 +14702,14 @@ class PydevdProcessInfo(BaseSchema): """ __props__ = { - "pid": { - "type": "integer", - "description": "Process ID for the current process." - }, - "ppid": { - "type": "integer", - "description": "Parent Process ID for the current process." - }, - "executable": { - "type": "string", - "description": "Path to the executable as returned by 'sys.executable'." - }, - "bitness": { - "type": "integer", - "description": "Integer value indicating the bitness of the current process." - } + "pid": {"type": "integer", "description": "Process ID for the current process."}, + "ppid": {"type": "integer", "description": "Parent Process ID for the current process."}, + "executable": {"type": "string", "description": "Path to the executable as returned by 'sys.executable'."}, + "bitness": {"type": "integer", "description": "Integer value indicating the bitness of the current process."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, pid=None, ppid=None, executable=None, bitness=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17024,22 +14724,20 @@ def __init__(self, pid=None, ppid=None, executable=None, bitness=None, update_id self.bitness = bitness self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) pid = self.pid ppid = self.ppid executable = self.executable bitness = self.bitness - dct = { - } + dct = {} if pid is not None: - dct['pid'] = pid + dct["pid"] = pid if ppid is not None: - dct['ppid'] = ppid + dct["ppid"] = ppid if executable is not None: - dct['executable'] = executable + dct["executable"] = executable if bitness is not None: - dct['bitness'] = bitness + dct["bitness"] = bitness dct.update(self.kwargs) return dct @@ -17053,18 +14751,12 @@ class PydevdInfo(BaseSchema): """ __props__ = { - "usingCython": { - "type": "boolean", - "description": "Specifies whether the cython native module is being used." - }, - "usingFrameEval": { - "type": "boolean", - "description": "Specifies whether the frame eval native module is being used." - } + "usingCython": {"type": "boolean", "description": "Specifies whether the cython native module is being used."}, + "usingFrameEval": {"type": "boolean", "description": "Specifies whether the frame eval native module is being used."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, usingCython=None, usingFrameEval=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17075,21 +14767,19 @@ def __init__(self, usingCython=None, usingFrameEval=None, update_ids_from_dap=Fa self.usingFrameEval = usingFrameEval self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) usingCython = self.usingCython usingFrameEval = self.usingFrameEval - dct = { - } + dct = {} if usingCython is not None: - dct['usingCython'] = usingCython + dct["usingCython"] = usingCython if usingFrameEval is not None: - dct['usingFrameEval'] = usingFrameEval + dct["usingFrameEval"] = usingFrameEval dct.update(self.kwargs) return dct -@register_request('pydevdAuthorize') +@register_request("pydevdAuthorize") @register class PydevdAuthorizeRequest(BaseSchema): """ @@ -17101,55 +14791,46 @@ class PydevdAuthorizeRequest(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "request" - ] - }, - "command": { - "type": "string", - "enum": [ - "pydevdAuthorize" - ] + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, - "arguments": { - "type": "PydevdAuthorizeArguments" - } + "type": {"type": "string", "enum": ["request"]}, + "command": {"type": "string", "enum": ["pydevdAuthorize"]}, + "arguments": {"type": "PydevdAuthorizeArguments"}, } - __refs__ = set(['arguments']) + __refs__ = set(["arguments"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, arguments, seq=-1, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: - :param string command: - :param PydevdAuthorizeArguments arguments: + :param string type: + :param string command: + :param PydevdAuthorizeArguments arguments: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. """ - self.type = 'request' - self.command = 'pydevdAuthorize' + self.type = "request" + self.command = "pydevdAuthorize" if arguments is None: self.arguments = PydevdAuthorizeArguments() else: - self.arguments = PydevdAuthorizeArguments(update_ids_from_dap=update_ids_from_dap, **arguments) if arguments.__class__ != PydevdAuthorizeArguments else arguments + self.arguments = ( + PydevdAuthorizeArguments(update_ids_from_dap=update_ids_from_dap, **arguments) + if arguments.__class__ != PydevdAuthorizeArguments + else arguments + ) self.seq = seq self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) command = self.command arguments = self.arguments seq = self.seq dct = { - 'type': type, - 'command': command, - 'arguments': arguments.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "command": command, + "arguments": arguments.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } dct.update(self.kwargs) return dct @@ -17163,15 +14844,10 @@ class PydevdAuthorizeArguments(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "debugServerAccessToken": { - "type": "string", - "description": "The access token to access the debug server." - } - } + __props__ = {"debugServerAccessToken": {"type": "string", "description": "The access token to access the debug server."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, debugServerAccessToken=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17180,18 +14856,16 @@ def __init__(self, debugServerAccessToken=None, update_ids_from_dap=False, **kwa self.debugServerAccessToken = debugServerAccessToken self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) debugServerAccessToken = self.debugServerAccessToken - dct = { - } + dct = {} if debugServerAccessToken is not None: - dct['debugServerAccessToken'] = debugServerAccessToken + dct["debugServerAccessToken"] = debugServerAccessToken dct.update(self.kwargs) return dct -@register_response('pydevdAuthorize') +@register_response("pydevdAuthorize") @register class PydevdAuthorizeResponse(BaseSchema): """ @@ -17203,82 +14877,63 @@ class PydevdAuthorizeResponse(BaseSchema): __props__ = { "seq": { "type": "integer", - "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request." - }, - "type": { - "type": "string", - "enum": [ - "response" - ] - }, - "request_seq": { - "type": "integer", - "description": "Sequence number of the corresponding request." + "description": "Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request.", }, + "type": {"type": "string", "enum": ["response"]}, + "request_seq": {"type": "integer", "description": "Sequence number of the corresponding request."}, "success": { "type": "boolean", - "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`)." - }, - "command": { - "type": "string", - "description": "The command requested." + "description": "Outcome of the request.\nIf True, the request was successful and the `body` attribute may contain the result of the request.\nIf the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`).", }, + "command": {"type": "string", "description": "The command requested."}, "message": { "type": "string", "description": "Contains the raw error in short form if `success` is false.\nThis raw error might be interpreted by the client and is not shown in the UI.\nSome predefined values exist.", - "_enum": [ - "cancelled", - "notStopped" - ], - "enumDescriptions": [ - "the request was cancelled.", - "the request may be retried once the adapter is in a 'stopped' state." - ] + "_enum": ["cancelled", "notStopped"], + "enumDescriptions": ["the request was cancelled.", "the request may be retried once the adapter is in a 'stopped' state."], }, "body": { "type": "object", "properties": { - "clientAccessToken": { - "type": "string", - "description": "The access token to access the client (i.e.: usually the IDE)." - } + "clientAccessToken": {"type": "string", "description": "The access token to access the client (i.e.: usually the IDE)."} }, - "required": [ - "clientAccessToken" - ] - } + "required": ["clientAccessToken"], + }, } - __refs__ = set(['body']) + __refs__ = set(["body"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, request_seq, success, command, body, seq=-1, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ - :param string type: + :param string type: :param integer request_seq: Sequence number of the corresponding request. :param boolean success: Outcome of the request. If true, the request was successful and the `body` attribute may contain the result of the request. If the value is false, the attribute `message` contains the error in short form and the `body` may contain additional information (see `ErrorResponse.body.error`). :param string command: The command requested. - :param PydevdAuthorizeResponseBody body: + :param PydevdAuthorizeResponseBody body: :param integer seq: Sequence number of the message (also known as message ID). The `seq` for the first message sent by a client or debug adapter is 1, and for each subsequent message is 1 greater than the previous message sent by that actor. `seq` can be used to order requests, responses, and events, and to associate requests with their corresponding responses. For protocol messages of type `request` the sequence number can be used to cancel the request. :param string message: Contains the raw error in short form if `success` is false. This raw error might be interpreted by the client and is not shown in the UI. Some predefined values exist. """ - self.type = 'response' + self.type = "response" self.request_seq = request_seq self.success = success self.command = command if body is None: self.body = PydevdAuthorizeResponseBody() else: - self.body = PydevdAuthorizeResponseBody(update_ids_from_dap=update_ids_from_dap, **body) if body.__class__ != PydevdAuthorizeResponseBody else body + self.body = ( + PydevdAuthorizeResponseBody(update_ids_from_dap=update_ids_from_dap, **body) + if body.__class__ != PydevdAuthorizeResponseBody + else body + ) self.seq = seq self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) type = self.type # noqa (assign to builtin) request_seq = self.request_seq @@ -17288,15 +14943,15 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un seq = self.seq message = self.message dct = { - 'type': type, - 'request_seq': request_seq, - 'success': success, - 'command': command, - 'body': body.to_dict(update_ids_to_dap=update_ids_to_dap), - 'seq': seq, + "type": type, + "request_seq": request_seq, + "success": success, + "command": command, + "body": body.to_dict(update_ids_to_dap=update_ids_to_dap), + "seq": seq, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct @@ -17309,15 +14964,10 @@ class ErrorResponseBody(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "error": { - "description": "A structured error message.", - "type": "Message" - } - } - __refs__ = set(['error']) + __props__ = {"error": {"description": "A structured error message.", "type": "Message"}} + __refs__ = set(["error"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, error=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17326,16 +14976,14 @@ def __init__(self, error=None, update_ids_from_dap=False, **kwargs): # noqa (up if error is None: self.error = Message() else: - self.error = Message(update_ids_from_dap=update_ids_from_dap, **error) if error.__class__ != Message else error + self.error = Message(update_ids_from_dap=update_ids_from_dap, **error) if error.__class__ != Message else error self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) error = self.error - dct = { - } + dct = {} if error is not None: - dct['error'] = error.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["error"] = error.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -17361,42 +15009,48 @@ class StoppedEventBody(BaseSchema): "goto", "function breakpoint", "data breakpoint", - "instruction breakpoint" - ] + "instruction breakpoint", + ], }, "description": { "type": "string", - "description": "The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is and can be translated." - }, - "threadId": { - "type": "integer", - "description": "The thread which was stopped." + "description": "The full reason for the event, e.g. 'Paused on exception'. This string is shown in the UI as is and can be translated.", }, + "threadId": {"type": "integer", "description": "The thread which was stopped."}, "preserveFocusHint": { "type": "boolean", - "description": "A value of True hints to the client that this event should not change the focus." + "description": "A value of True hints to the client that this event should not change the focus.", }, "text": { "type": "string", - "description": "Additional information. E.g. if reason is `exception`, text contains the exception name. This string is shown in the UI." + "description": "Additional information. E.g. if reason is `exception`, text contains the exception name. This string is shown in the UI.", }, "allThreadsStopped": { "type": "boolean", - "description": "If `allThreadsStopped` is True, a debug adapter can announce that all threads have stopped.\n- The client should use this information to enable that all threads can be expanded to access their stacktraces.\n- If the attribute is missing or false, only the thread with the given `threadId` can be expanded." + "description": "If `allThreadsStopped` is True, a debug adapter can announce that all threads have stopped.\n- The client should use this information to enable that all threads can be expanded to access their stacktraces.\n- If the attribute is missing or false, only the thread with the given `threadId` can be expanded.", }, "hitBreakpointIds": { "type": "array", - "items": { - "type": "integer" - }, - "description": "Ids of the breakpoints that triggered the event. In most cases there is only a single breakpoint but here are some examples for multiple breakpoints:\n- Different types of breakpoints map to the same location.\n- Multiple source breakpoints get collapsed to the same instruction by the compiler/runtime.\n- Multiple function breakpoints with different function names map to the same location." - } + "items": {"type": "integer"}, + "description": "Ids of the breakpoints that triggered the event. In most cases there is only a single breakpoint but here are some examples for multiple breakpoints:\n- Different types of breakpoints map to the same location.\n- Multiple source breakpoints get collapsed to the same instruction by the compiler/runtime.\n- Multiple function breakpoints with different function names map to the same location.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, reason, description=None, threadId=None, preserveFocusHint=None, text=None, allThreadsStopped=None, hitBreakpointIds=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + reason, + description=None, + threadId=None, + preserveFocusHint=None, + text=None, + allThreadsStopped=None, + hitBreakpointIds=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string reason: The reason for the event. For backward compatibility this string is shown in the UI if the `description` attribute is missing (but it must not be translated). @@ -17422,12 +15076,11 @@ def __init__(self, reason, description=None, threadId=None, preserveFocusHint=No if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -17444,27 +15097,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'reason': reason, + "reason": reason, } if description is not None: - dct['description'] = description + dct["description"] = description if threadId is not None: - dct['threadId'] = threadId + dct["threadId"] = threadId if preserveFocusHint is not None: - dct['preserveFocusHint'] = preserveFocusHint + dct["preserveFocusHint"] = preserveFocusHint if text is not None: - dct['text'] = text + dct["text"] = text if allThreadsStopped is not None: - dct['allThreadsStopped'] = allThreadsStopped + dct["allThreadsStopped"] = allThreadsStopped if hitBreakpointIds is not None: - dct['hitBreakpointIds'] = hitBreakpointIds + dct["hitBreakpointIds"] = hitBreakpointIds dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct @@ -17477,18 +15130,15 @@ class ContinuedEventBody(BaseSchema): """ __props__ = { - "threadId": { - "type": "integer", - "description": "The thread which was continued." - }, + "threadId": {"type": "integer", "description": "The thread which was continued."}, "allThreadsContinued": { "type": "boolean", - "description": "If `allThreadsContinued` is True, a debug adapter can announce that all threads have continued." - } + "description": "If `allThreadsContinued` is True, a debug adapter can announce that all threads have continued.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threadId, allThreadsContinued=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17500,12 +15150,11 @@ def __init__(self, threadId, allThreadsContinued=None, update_ids_from_dap=False if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -17515,17 +15164,17 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'threadId': threadId, + "threadId": threadId, } if allThreadsContinued is not None: - dct['allThreadsContinued'] = allThreadsContinued + dct["allThreadsContinued"] = allThreadsContinued dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct @@ -17537,15 +15186,10 @@ class ExitedEventBody(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "exitCode": { - "type": "integer", - "description": "The exit code returned from the debuggee." - } - } + __props__ = {"exitCode": {"type": "integer", "description": "The exit code returned from the debuggee."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, exitCode, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17554,11 +15198,10 @@ def __init__(self, exitCode, update_ids_from_dap=False, **kwargs): # noqa (upda self.exitCode = exitCode self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) exitCode = self.exitCode dct = { - 'exitCode': exitCode, + "exitCode": exitCode, } dct.update(self.kwargs) return dct @@ -17574,21 +15217,13 @@ class TerminatedEventBody(BaseSchema): __props__ = { "restart": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "A debug adapter may set `restart` to True (or to an arbitrary object) to request that the client restarts the session.\nThe value is not interpreted by the client and passed unmodified as an attribute `__restart` to the `launch` and `attach` requests." + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "A debug adapter may set `restart` to True (or to an arbitrary object) to request that the client restarts the session.\nThe value is not interpreted by the client and passed unmodified as an attribute `__restart` to the `launch` and `attach` requests.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, restart=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17598,13 +15233,11 @@ def __init__(self, restart=None, update_ids_from_dap=False, **kwargs): # noqa ( self.restart = restart self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) restart = self.restart - dct = { - } + dct = {} if restart is not None: - dct['restart'] = restart + dct["restart"] = restart dct.update(self.kwargs) return dct @@ -17618,22 +15251,12 @@ class ThreadEventBody(BaseSchema): """ __props__ = { - "reason": { - "type": "string", - "description": "The reason for the event.", - "_enum": [ - "started", - "exited" - ] - }, - "threadId": { - "type": "integer", - "description": "The identifier of the thread." - } + "reason": {"type": "string", "description": "The reason for the event.", "_enum": ["started", "exited"]}, + "threadId": {"type": "integer", "description": "The identifier of the thread."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, reason, threadId, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17645,12 +15268,11 @@ def __init__(self, reason, threadId, update_ids_from_dap=False, **kwargs): # no if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -17660,16 +15282,16 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if threadId is not None: threadId = self._translate_id_to_dap(threadId) dct = { - 'reason': reason, - 'threadId': threadId, + "reason": reason, + "threadId": threadId, } dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct @@ -17685,73 +15307,58 @@ class OutputEventBody(BaseSchema): "category": { "type": "string", "description": "The output category. If not specified or if the category is not understood by the client, `console` is assumed.", - "_enum": [ - "console", - "important", - "stdout", - "stderr", - "telemetry" - ], + "_enum": ["console", "important", "stdout", "stderr", "telemetry"], "enumDescriptions": [ "Show the output in the client's default message UI, e.g. a 'debug console'. This category should only be used for informational output from the debugger (as opposed to the debuggee).", "A hint for the client to show the output in the client's UI for important and highly visible information, e.g. as a popup notification. This category should only be used for important messages from the debugger (as opposed to the debuggee). Since this category value is a hint, clients might ignore the hint and assume the `console` category.", "Show the output as normal program output from the debuggee.", "Show the output as error program output from the debuggee.", - "Send the output to telemetry instead of showing it to the user." - ] - }, - "output": { - "type": "string", - "description": "The output to report." + "Send the output to telemetry instead of showing it to the user.", + ], }, + "output": {"type": "string", "description": "The output to report."}, "group": { "type": "string", "description": "Support for keeping an output log organized by grouping related messages.", - "enum": [ - "start", - "startCollapsed", - "end" - ], + "enum": ["start", "startCollapsed", "end"], "enumDescriptions": [ "Start a new group in expanded mode. Subsequent output events are members of the group and should be shown indented.\nThe `output` attribute becomes the name of the group and is not indented.", "Start a new group in collapsed mode. Subsequent output events are members of the group and should be shown indented (as soon as the group is expanded).\nThe `output` attribute becomes the name of the group and is not indented.", - "End the current group and decrease the indentation of subsequent output events.\nA non-empty `output` attribute is shown as the unindented end of the group." - ] + "End the current group and decrease the indentation of subsequent output events.\nA non-empty `output` attribute is shown as the unindented end of the group.", + ], }, "variablesReference": { "type": "integer", - "description": "If an attribute `variablesReference` exists and its value is > 0, the output contains objects which can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." - }, - "source": { - "description": "The source location where the output was produced.", - "type": "Source" - }, - "line": { - "type": "integer", - "description": "The source location's line where the output was produced." + "description": "If an attribute `variablesReference` exists and its value is > 0, the output contains objects which can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, + "source": {"description": "The source location where the output was produced.", "type": "Source"}, + "line": {"type": "integer", "description": "The source location's line where the output was produced."}, "column": { "type": "integer", - "description": "The position in `line` where the output was produced. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based." + "description": "The position in `line` where the output was produced. It is measured in UTF-16 code units and the client capability `columnsStartAt1` determines whether it is 0- or 1-based.", }, "data": { - "type": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ], - "description": "Additional data to report. For the `telemetry` category the data is sent to telemetry, for the other categories the data is shown in JSON format." - } + "type": ["array", "boolean", "integer", "null", "number", "object", "string"], + "description": "Additional data to report. For the `telemetry` category the data is sent to telemetry, for the other categories the data is shown in JSON format.", + }, } - __refs__ = set(['source']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, output, category=None, group=None, variablesReference=None, source=None, line=None, column=None, data=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["source"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + output, + category=None, + group=None, + variablesReference=None, + source=None, + line=None, + column=None, + data=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string output: The output to report. :param string category: The output category. If not specified or if the category is not understood by the client, `console` is assumed. @@ -17769,19 +15376,18 @@ def __init__(self, output, category=None, group=None, variablesReference=None, s if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.line = line self.column = column self.data = data if update_ids_from_dap: self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -17797,29 +15403,29 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if variablesReference is not None: variablesReference = self._translate_id_to_dap(variablesReference) dct = { - 'output': output, + "output": output, } if category is not None: - dct['category'] = category + dct["category"] = category if group is not None: - dct['group'] = group + dct["group"] = group if variablesReference is not None: - dct['variablesReference'] = variablesReference + dct["variablesReference"] = variablesReference if source is not None: - dct['source'] = source.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["source"] = source.to_dict(update_ids_to_dap=update_ids_to_dap) if line is not None: - dct['line'] = line + dct["line"] = line if column is not None: - dct['column'] = column + dct["column"] = column if data is not None: - dct['data'] = data + dct["data"] = data dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) return dct @@ -17832,23 +15438,15 @@ class BreakpointEventBody(BaseSchema): """ __props__ = { - "reason": { - "type": "string", - "description": "The reason for the event.", - "_enum": [ - "changed", - "new", - "removed" - ] - }, + "reason": {"type": "string", "description": "The reason for the event.", "_enum": ["changed", "new", "removed"]}, "breakpoint": { "description": "The `id` attribute is used to find the target breakpoint, the other attributes are used as the new values.", - "type": "Breakpoint" - } + "type": "Breakpoint", + }, } - __refs__ = set(['breakpoint']) + __refs__ = set(["breakpoint"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, reason, breakpoint, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17859,16 +15457,17 @@ def __init__(self, reason, breakpoint, update_ids_from_dap=False, **kwargs): # if breakpoint is None: self.breakpoint = Breakpoint() else: - self.breakpoint = Breakpoint(update_ids_from_dap=update_ids_from_dap, **breakpoint) if breakpoint.__class__ != Breakpoint else breakpoint + self.breakpoint = ( + Breakpoint(update_ids_from_dap=update_ids_from_dap, **breakpoint) if breakpoint.__class__ != Breakpoint else breakpoint + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) reason = self.reason breakpoint = self.breakpoint # noqa (assign to builtin) dct = { - 'reason': reason, - 'breakpoint': breakpoint.to_dict(update_ids_to_dap=update_ids_to_dap), + "reason": reason, + "breakpoint": breakpoint.to_dict(update_ids_to_dap=update_ids_to_dap), } dct.update(self.kwargs) return dct @@ -17883,23 +15482,15 @@ class ModuleEventBody(BaseSchema): """ __props__ = { - "reason": { - "type": "string", - "description": "The reason for the event.", - "enum": [ - "new", - "changed", - "removed" - ] - }, + "reason": {"type": "string", "description": "The reason for the event.", "enum": ["new", "changed", "removed"]}, "module": { "description": "The new, changed, or removed module. In case of `removed` only the module id is used.", - "type": "Module" - } + "type": "Module", + }, } - __refs__ = set(['module']) + __refs__ = set(["module"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, reason, module, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17910,16 +15501,15 @@ def __init__(self, reason, module, update_ids_from_dap=False, **kwargs): # noqa if module is None: self.module = Module() else: - self.module = Module(update_ids_from_dap=update_ids_from_dap, **module) if module.__class__ != Module else module + self.module = Module(update_ids_from_dap=update_ids_from_dap, **module) if module.__class__ != Module else module self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) reason = self.reason module = self.module dct = { - 'reason': reason, - 'module': module.to_dict(update_ids_to_dap=update_ids_to_dap), + "reason": reason, + "module": module.to_dict(update_ids_to_dap=update_ids_to_dap), } dct.update(self.kwargs) return dct @@ -17934,23 +15524,12 @@ class LoadedSourceEventBody(BaseSchema): """ __props__ = { - "reason": { - "type": "string", - "description": "The reason for the event.", - "enum": [ - "new", - "changed", - "removed" - ] - }, - "source": { - "description": "The new, changed, or removed source.", - "type": "Source" - } + "reason": {"type": "string", "description": "The reason for the event.", "enum": ["new", "changed", "removed"]}, + "source": {"description": "The new, changed, or removed source.", "type": "Source"}, } - __refs__ = set(['source']) + __refs__ = set(["source"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, reason, source, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -17961,16 +15540,15 @@ def __init__(self, reason, source, update_ids_from_dap=False, **kwargs): # noqa if source is None: self.source = Source() else: - self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source + self.source = Source(update_ids_from_dap=update_ids_from_dap, **source) if source.__class__ != Source else source self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) reason = self.reason source = self.source dct = { - 'reason': reason, - 'source': source.to_dict(update_ids_to_dap=update_ids_to_dap), + "reason": reason, + "source": source.to_dict(update_ids_to_dap=update_ids_to_dap), } dct.update(self.kwargs) return dct @@ -17987,40 +15565,35 @@ class ProcessEventBody(BaseSchema): __props__ = { "name": { "type": "string", - "description": "The logical name of the process. This is usually the full path to process's executable file. Example: /home/example/myproj/program.js." + "description": "The logical name of the process. This is usually the full path to process's executable file. Example: /home/example/myproj/program.js.", }, "systemProcessId": { "type": "integer", - "description": "The system process id of the debugged process. This property is missing for non-system processes." - }, - "isLocalProcess": { - "type": "boolean", - "description": "If True, the process is running on the same computer as the debug adapter." + "description": "The system process id of the debugged process. This property is missing for non-system processes.", }, + "isLocalProcess": {"type": "boolean", "description": "If True, the process is running on the same computer as the debug adapter."}, "startMethod": { "type": "string", - "enum": [ - "launch", - "attach", - "attachForSuspendedLaunch" - ], + "enum": ["launch", "attach", "attachForSuspendedLaunch"], "description": "Describes how the debug engine started debugging this process.", "enumDescriptions": [ "Process was launched under the debugger.", "Debugger attached to an existing process.", - "A project launcher component has launched a new process in a suspended state and then asked the debugger to attach." - ] + "A project launcher component has launched a new process in a suspended state and then asked the debugger to attach.", + ], }, "pointerSize": { "type": "integer", - "description": "The size of a pointer or address for this process, in bits. This value may be used by clients when formatting addresses for display." - } + "description": "The size of a pointer or address for this process, in bits. This value may be used by clients when formatting addresses for display.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] - def __init__(self, name, systemProcessId=None, isLocalProcess=None, startMethod=None, pointerSize=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__( + self, name, systemProcessId=None, isLocalProcess=None, startMethod=None, pointerSize=None, update_ids_from_dap=False, **kwargs + ): # noqa (update_ids_from_dap may be unused) """ :param string name: The logical name of the process. This is usually the full path to process's executable file. Example: /home/example/myproj/program.js. :param integer systemProcessId: The system process id of the debugged process. This property is missing for non-system processes. @@ -18035,7 +15608,6 @@ def __init__(self, name, systemProcessId=None, isLocalProcess=None, startMethod= self.pointerSize = pointerSize self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) name = self.name systemProcessId = self.systemProcessId @@ -18043,16 +15615,16 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un startMethod = self.startMethod pointerSize = self.pointerSize dct = { - 'name': name, + "name": name, } if systemProcessId is not None: - dct['systemProcessId'] = systemProcessId + dct["systemProcessId"] = systemProcessId if isLocalProcess is not None: - dct['isLocalProcess'] = isLocalProcess + dct["isLocalProcess"] = isLocalProcess if startMethod is not None: - dct['startMethod'] = startMethod + dct["startMethod"] = startMethod if pointerSize is not None: - dct['pointerSize'] = pointerSize + dct["pointerSize"] = pointerSize dct.update(self.kwargs) return dct @@ -18065,15 +15637,10 @@ class CapabilitiesEventBody(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "capabilities": { - "description": "The set of updated capabilities.", - "type": "Capabilities" - } - } - __refs__ = set(['capabilities']) + __props__ = {"capabilities": {"description": "The set of updated capabilities.", "type": "Capabilities"}} + __refs__ = set(["capabilities"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, capabilities, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18082,14 +15649,17 @@ def __init__(self, capabilities, update_ids_from_dap=False, **kwargs): # noqa ( if capabilities is None: self.capabilities = Capabilities() else: - self.capabilities = Capabilities(update_ids_from_dap=update_ids_from_dap, **capabilities) if capabilities.__class__ != Capabilities else capabilities + self.capabilities = ( + Capabilities(update_ids_from_dap=update_ids_from_dap, **capabilities) + if capabilities.__class__ != Capabilities + else capabilities + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) capabilities = self.capabilities dct = { - 'capabilities': capabilities.to_dict(update_ids_to_dap=update_ids_to_dap), + "capabilities": capabilities.to_dict(update_ids_to_dap=update_ids_to_dap), } dct.update(self.kwargs) return dct @@ -18106,34 +15676,33 @@ class ProgressStartEventBody(BaseSchema): __props__ = { "progressId": { "type": "string", - "description": "An ID that can be used in subsequent `progressUpdate` and `progressEnd` events to make them refer to the same progress reporting.\nIDs must be unique within a debug session." + "description": "An ID that can be used in subsequent `progressUpdate` and `progressEnd` events to make them refer to the same progress reporting.\nIDs must be unique within a debug session.", }, "title": { "type": "string", - "description": "Short title of the progress reporting. Shown in the UI to describe the long running operation." + "description": "Short title of the progress reporting. Shown in the UI to describe the long running operation.", }, "requestId": { "type": "integer", - "description": "The request ID that this progress report is related to. If specified a debug adapter is expected to emit progress events for the long running request until the request has been either completed or cancelled.\nIf the request ID is omitted, the progress report is assumed to be related to some general activity of the debug adapter." + "description": "The request ID that this progress report is related to. If specified a debug adapter is expected to emit progress events for the long running request until the request has been either completed or cancelled.\nIf the request ID is omitted, the progress report is assumed to be related to some general activity of the debug adapter.", }, "cancellable": { "type": "boolean", - "description": "If True, the request that reports progress may be cancelled with a `cancel` request.\nSo this property basically controls whether the client should use UX that supports cancellation.\nClients that don't support cancellation are allowed to ignore the setting." - }, - "message": { - "type": "string", - "description": "More detailed progress message." + "description": "If True, the request that reports progress may be cancelled with a `cancel` request.\nSo this property basically controls whether the client should use UX that supports cancellation.\nClients that don't support cancellation are allowed to ignore the setting.", }, + "message": {"type": "string", "description": "More detailed progress message."}, "percentage": { "type": "number", - "description": "Progress percentage to display (value range: 0 to 100). If omitted no percentage is shown." - } + "description": "Progress percentage to display (value range: 0 to 100). If omitted no percentage is shown.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] - def __init__(self, progressId, title, requestId=None, cancellable=None, message=None, percentage=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__( + self, progressId, title, requestId=None, cancellable=None, message=None, percentage=None, update_ids_from_dap=False, **kwargs + ): # noqa (update_ids_from_dap may be unused) """ :param string progressId: An ID that can be used in subsequent `progressUpdate` and `progressEnd` events to make them refer to the same progress reporting. IDs must be unique within a debug session. @@ -18154,7 +15723,6 @@ def __init__(self, progressId, title, requestId=None, cancellable=None, message= self.percentage = percentage self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) progressId = self.progressId title = self.title @@ -18163,17 +15731,17 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un message = self.message percentage = self.percentage dct = { - 'progressId': progressId, - 'title': title, + "progressId": progressId, + "title": title, } if requestId is not None: - dct['requestId'] = requestId + dct["requestId"] = requestId if cancellable is not None: - dct['cancellable'] = cancellable + dct["cancellable"] = cancellable if message is not None: - dct['message'] = message + dct["message"] = message if percentage is not None: - dct['percentage'] = percentage + dct["percentage"] = percentage dct.update(self.kwargs) return dct @@ -18187,22 +15755,16 @@ class ProgressUpdateEventBody(BaseSchema): """ __props__ = { - "progressId": { - "type": "string", - "description": "The ID that was introduced in the initial `progressStart` event." - }, - "message": { - "type": "string", - "description": "More detailed progress message. If omitted, the previous message (if any) is used." - }, + "progressId": {"type": "string", "description": "The ID that was introduced in the initial `progressStart` event."}, + "message": {"type": "string", "description": "More detailed progress message. If omitted, the previous message (if any) is used."}, "percentage": { "type": "number", - "description": "Progress percentage to display (value range: 0 to 100). If omitted no percentage is shown." - } + "description": "Progress percentage to display (value range: 0 to 100). If omitted no percentage is shown.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, progressId, message=None, percentage=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18215,18 +15777,17 @@ def __init__(self, progressId, message=None, percentage=None, update_ids_from_da self.percentage = percentage self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) progressId = self.progressId message = self.message percentage = self.percentage dct = { - 'progressId': progressId, + "progressId": progressId, } if message is not None: - dct['message'] = message + dct["message"] = message if percentage is not None: - dct['percentage'] = percentage + dct["percentage"] = percentage dct.update(self.kwargs) return dct @@ -18240,18 +15801,12 @@ class ProgressEndEventBody(BaseSchema): """ __props__ = { - "progressId": { - "type": "string", - "description": "The ID that was introduced in the initial `ProgressStartEvent`." - }, - "message": { - "type": "string", - "description": "More detailed progress message. If omitted, the previous message (if any) is used." - } + "progressId": {"type": "string", "description": "The ID that was introduced in the initial `ProgressStartEvent`."}, + "message": {"type": "string", "description": "More detailed progress message. If omitted, the previous message (if any) is used."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, progressId, message=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18262,15 +15817,14 @@ def __init__(self, progressId, message=None, update_ids_from_dap=False, **kwargs self.message = message self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) progressId = self.progressId message = self.message dct = { - 'progressId': progressId, + "progressId": progressId, } if message is not None: - dct['message'] = message + dct["message"] = message dct.update(self.kwargs) return dct @@ -18287,22 +15841,17 @@ class InvalidatedEventBody(BaseSchema): "areas": { "type": "array", "description": "Set of logical areas that got invalidated. This property has a hint characteristic: a client can only be expected to make a 'best effort' in honoring the areas but there are no guarantees. If this property is missing, empty, or if values are not understood, the client should assume a single value `all`.", - "items": { - "$ref": "#/definitions/InvalidatedAreas" - } - }, - "threadId": { - "type": "integer", - "description": "If specified, the client only needs to refetch data related to this thread." + "items": {"$ref": "#/definitions/InvalidatedAreas"}, }, + "threadId": {"type": "integer", "description": "If specified, the client only needs to refetch data related to this thread."}, "stackFrameId": { "type": "integer", - "description": "If specified, the client only needs to refetch data related to this stack frame (and the `threadId` is ignored)." - } + "description": "If specified, the client only needs to refetch data related to this stack frame (and the `threadId` is ignored).", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, areas=None, threadId=None, stackFrameId=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18319,12 +15868,11 @@ def __init__(self, areas=None, threadId=None, stackFrameId=None, update_ids_from if update_ids_from_dap: self.threadId = self._translate_id_from_dap(self.threadId) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_from_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_from_dap(dct["threadId"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -18336,21 +15884,20 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if update_ids_to_dap: if threadId is not None: threadId = self._translate_id_to_dap(threadId) - dct = { - } + dct = {} if areas is not None: - dct['areas'] = [InvalidatedAreas.update_dict_ids_to_dap(o) for o in areas] if (update_ids_to_dap and areas) else areas + dct["areas"] = [InvalidatedAreas.update_dict_ids_to_dap(o) for o in areas] if (update_ids_to_dap and areas) else areas if threadId is not None: - dct['threadId'] = threadId + dct["threadId"] = threadId if stackFrameId is not None: - dct['stackFrameId'] = stackFrameId + dct["stackFrameId"] = stackFrameId dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'threadId' in dct: - dct['threadId'] = cls._translate_id_to_dap(dct['threadId']) + if "threadId" in dct: + dct["threadId"] = cls._translate_id_to_dap(dct["threadId"]) return dct @@ -18363,22 +15910,13 @@ class MemoryEventBody(BaseSchema): """ __props__ = { - "memoryReference": { - "type": "string", - "description": "Memory reference of a memory range that has been updated." - }, - "offset": { - "type": "integer", - "description": "Starting offset in bytes where memory has been updated. Can be negative." - }, - "count": { - "type": "integer", - "description": "Number of bytes updated." - } + "memoryReference": {"type": "string", "description": "Memory reference of a memory range that has been updated."}, + "offset": {"type": "integer", "description": "Starting offset in bytes where memory has been updated. Can be negative."}, + "count": {"type": "integer", "description": "Number of bytes updated."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, memoryReference, offset, count, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18391,15 +15929,14 @@ def __init__(self, memoryReference, offset, count, update_ids_from_dap=False, ** self.count = count self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) memoryReference = self.memoryReference offset = self.offset count = self.count dct = { - 'memoryReference': memoryReference, - 'offset': offset, - 'count': count, + "memoryReference": memoryReference, + "offset": offset, + "count": count, } dct.update(self.kwargs) return dct @@ -18416,19 +15953,15 @@ class RunInTerminalRequestArgumentsEnv(BaseSchema): __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct @@ -18442,18 +15975,15 @@ class RunInTerminalResponseBody(BaseSchema): """ __props__ = { - "processId": { - "type": "integer", - "description": "The process ID. The value should be less than or equal to 2147483647 (2^31-1)." - }, + "processId": {"type": "integer", "description": "The process ID. The value should be less than or equal to 2147483647 (2^31-1)."}, "shellProcessId": { "type": "integer", - "description": "The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31-1)." - } + "description": "The process ID of the terminal shell. The value should be less than or equal to 2147483647 (2^31-1).", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, processId=None, shellProcessId=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18464,16 +15994,14 @@ def __init__(self, processId=None, shellProcessId=None, update_ids_from_dap=Fals self.shellProcessId = shellProcessId self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) processId = self.processId shellProcessId = self.shellProcessId - dct = { - } + dct = {} if processId is not None: - dct['processId'] = processId + dct["processId"] = processId if shellProcessId is not None: - dct['shellProcessId'] = shellProcessId + dct["shellProcessId"] = shellProcessId dct.update(self.kwargs) return dct @@ -18489,19 +16017,15 @@ class StartDebuggingRequestArgumentsConfiguration(BaseSchema): __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct @@ -18517,15 +16041,13 @@ class BreakpointLocationsResponseBody(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/BreakpointLocation" - }, - "description": "Sorted set of possible breakpoint locations." + "items": {"$ref": "#/definitions/BreakpointLocation"}, + "description": "Sorted set of possible breakpoint locations.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18537,13 +16059,14 @@ def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (u BreakpointLocation.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] dct = { - 'breakpoints': [BreakpointLocation.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints, + "breakpoints": [BreakpointLocation.update_dict_ids_to_dap(o) for o in breakpoints] + if (update_ids_to_dap and breakpoints) + else breakpoints, } dct.update(self.kwargs) return dct @@ -18560,15 +16083,13 @@ class SetBreakpointsResponseBody(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the breakpoints.\nThe array elements are in the same order as the elements of the `breakpoints` (or the deprecated `lines`) array in the arguments." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the breakpoints.\nThe array elements are in the same order as the elements of the `breakpoints` (or the deprecated `lines`) array in the arguments.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18581,13 +16102,14 @@ def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (u Breakpoint.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] dct = { - 'breakpoints': [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints, + "breakpoints": [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] + if (update_ids_to_dap and breakpoints) + else breakpoints, } dct.update(self.kwargs) return dct @@ -18604,15 +16126,13 @@ class SetFunctionBreakpointsResponseBody(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the breakpoints. The array elements correspond to the elements of the `breakpoints` array." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the breakpoints. The array elements correspond to the elements of the `breakpoints` array.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18624,13 +16144,14 @@ def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (u Breakpoint.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] dct = { - 'breakpoints': [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints, + "breakpoints": [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] + if (update_ids_to_dap and breakpoints) + else breakpoints, } dct.update(self.kwargs) return dct @@ -18647,15 +16168,13 @@ class SetExceptionBreakpointsResponseBody(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the exception breakpoints or filters.\nThe breakpoints returned are in the same order as the elements of the `filters`, `filterOptions`, `exceptionOptions` arrays in the arguments. If both `filters` and `filterOptions` are given, the returned array must start with `filters` information first, followed by `filterOptions` information." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the exception breakpoints or filters.\nThe breakpoints returned are in the same order as the elements of the `filters`, `filterOptions`, `exceptionOptions` arrays in the arguments. If both `filters` and `filterOptions` are given, the returned array must start with `filters` information first, followed by `filterOptions` information.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18668,15 +16187,15 @@ def __init__(self, breakpoints=None, update_ids_from_dap=False, **kwargs): # no Breakpoint.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] - dct = { - } + dct = {} if breakpoints is not None: - dct['breakpoints'] = [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints + dct["breakpoints"] = ( + [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints + ) dct.update(self.kwargs) return dct @@ -18691,31 +16210,26 @@ class DataBreakpointInfoResponseBody(BaseSchema): __props__ = { "dataId": { - "type": [ - "string", - "null" - ], - "description": "An identifier for the data on which a data breakpoint can be registered with the `setDataBreakpoints` request or null if no data breakpoint is available. If a `variablesReference` or `frameId` is passed, the `dataId` is valid in the current suspended state, otherwise it's valid indefinitely. See 'Lifetime of Object References' in the Overview section for details. Breakpoints set using the `dataId` in the `setDataBreakpoints` request may outlive the lifetime of the associated `dataId`." + "type": ["string", "null"], + "description": "An identifier for the data on which a data breakpoint can be registered with the `setDataBreakpoints` request or null if no data breakpoint is available. If a `variablesReference` or `frameId` is passed, the `dataId` is valid in the current suspended state, otherwise it's valid indefinitely. See 'Lifetime of Object References' in the Overview section for details. Breakpoints set using the `dataId` in the `setDataBreakpoints` request may outlive the lifetime of the associated `dataId`.", }, "description": { "type": "string", - "description": "UI string that describes on what data the breakpoint is set on or why a data breakpoint is not available." + "description": "UI string that describes on what data the breakpoint is set on or why a data breakpoint is not available.", }, "accessTypes": { "type": "array", - "items": { - "$ref": "#/definitions/DataBreakpointAccessType" - }, - "description": "Attribute lists the available access types for a potential data breakpoint. A UI client could surface this information." + "items": {"$ref": "#/definitions/DataBreakpointAccessType"}, + "description": "Attribute lists the available access types for a potential data breakpoint. A UI client could surface this information.", }, "canPersist": { "type": "boolean", - "description": "Attribute indicates that a potential data breakpoint could be persisted across sessions." - } + "description": "Attribute indicates that a potential data breakpoint could be persisted across sessions.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, dataId, description, accessTypes=None, canPersist=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18733,7 +16247,6 @@ def __init__(self, dataId, description, accessTypes=None, canPersist=None, updat self.canPersist = canPersist self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) dataId = self.dataId description = self.description @@ -18742,13 +16255,17 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un accessTypes = [x.to_dict() for x in accessTypes] canPersist = self.canPersist dct = { - 'dataId': dataId, - 'description': description, + "dataId": dataId, + "description": description, } if accessTypes is not None: - dct['accessTypes'] = [DataBreakpointAccessType.update_dict_ids_to_dap(o) for o in accessTypes] if (update_ids_to_dap and accessTypes) else accessTypes + dct["accessTypes"] = ( + [DataBreakpointAccessType.update_dict_ids_to_dap(o) for o in accessTypes] + if (update_ids_to_dap and accessTypes) + else accessTypes + ) if canPersist is not None: - dct['canPersist'] = canPersist + dct["canPersist"] = canPersist dct.update(self.kwargs) return dct @@ -18764,15 +16281,13 @@ class SetDataBreakpointsResponseBody(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the data breakpoints. The array elements correspond to the elements of the input argument `breakpoints` array." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the data breakpoints. The array elements correspond to the elements of the input argument `breakpoints` array.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18784,13 +16299,14 @@ def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (u Breakpoint.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] dct = { - 'breakpoints': [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints, + "breakpoints": [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] + if (update_ids_to_dap and breakpoints) + else breakpoints, } dct.update(self.kwargs) return dct @@ -18807,15 +16323,13 @@ class SetInstructionBreakpointsResponseBody(BaseSchema): __props__ = { "breakpoints": { "type": "array", - "items": { - "$ref": "#/definitions/Breakpoint" - }, - "description": "Information about the breakpoints. The array elements correspond to the elements of the `breakpoints` array." + "items": {"$ref": "#/definitions/Breakpoint"}, + "description": "Information about the breakpoints. The array elements correspond to the elements of the `breakpoints` array.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18827,13 +16341,14 @@ def __init__(self, breakpoints, update_ids_from_dap=False, **kwargs): # noqa (u Breakpoint.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) breakpoints = self.breakpoints if breakpoints and hasattr(breakpoints[0], "to_dict"): breakpoints = [x.to_dict() for x in breakpoints] dct = { - 'breakpoints': [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] if (update_ids_to_dap and breakpoints) else breakpoints, + "breakpoints": [Breakpoint.update_dict_ids_to_dap(o) for o in breakpoints] + if (update_ids_to_dap and breakpoints) + else breakpoints, } dct.update(self.kwargs) return dct @@ -18850,12 +16365,12 @@ class ContinueResponseBody(BaseSchema): __props__ = { "allThreadsContinued": { "type": "boolean", - "description": "The value True (or a missing property) signals to the client that all threads have been resumed. The value false indicates that not all threads were resumed." + "description": "The value True (or a missing property) signals to the client that all threads have been resumed. The value false indicates that not all threads were resumed.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, allThreadsContinued=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18864,13 +16379,11 @@ def __init__(self, allThreadsContinued=None, update_ids_from_dap=False, **kwargs self.allThreadsContinued = allThreadsContinued self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) allThreadsContinued = self.allThreadsContinued - dct = { - } + dct = {} if allThreadsContinued is not None: - dct['allThreadsContinued'] = allThreadsContinued + dct["allThreadsContinued"] = allThreadsContinued dct.update(self.kwargs) return dct @@ -18886,19 +16399,17 @@ class StackTraceResponseBody(BaseSchema): __props__ = { "stackFrames": { "type": "array", - "items": { - "$ref": "#/definitions/StackFrame" - }, - "description": "The frames of the stack frame. If the array has length zero, there are no stack frames available.\nThis means that there is no location information available." + "items": {"$ref": "#/definitions/StackFrame"}, + "description": "The frames of the stack frame. If the array has length zero, there are no stack frames available.\nThis means that there is no location information available.", }, "totalFrames": { "type": "integer", - "description": "The total number of frames available in the stack. If omitted or if `totalFrames` is larger than the available frames, a client is expected to request frames until a request returns less frames than requested (which indicates the end of the stack). Returning monotonically increasing `totalFrames` values for subsequent requests can be used to enforce paging in the client." - } + "description": "The total number of frames available in the stack. If omitted or if `totalFrames` is larger than the available frames, a client is expected to request frames until a request returns less frames than requested (which indicates the end of the stack). Returning monotonically increasing `totalFrames` values for subsequent requests can be used to enforce paging in the client.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, stackFrames, totalFrames=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18913,17 +16424,18 @@ def __init__(self, stackFrames, totalFrames=None, update_ids_from_dap=False, **k self.totalFrames = totalFrames self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) stackFrames = self.stackFrames if stackFrames and hasattr(stackFrames[0], "to_dict"): stackFrames = [x.to_dict() for x in stackFrames] totalFrames = self.totalFrames dct = { - 'stackFrames': [StackFrame.update_dict_ids_to_dap(o) for o in stackFrames] if (update_ids_to_dap and stackFrames) else stackFrames, + "stackFrames": [StackFrame.update_dict_ids_to_dap(o) for o in stackFrames] + if (update_ids_to_dap and stackFrames) + else stackFrames, } if totalFrames is not None: - dct['totalFrames'] = totalFrames + dct["totalFrames"] = totalFrames dct.update(self.kwargs) return dct @@ -18939,15 +16451,13 @@ class ScopesResponseBody(BaseSchema): __props__ = { "scopes": { "type": "array", - "items": { - "$ref": "#/definitions/Scope" - }, - "description": "The scopes of the stack frame. If the array has length zero, there are no scopes available." + "items": {"$ref": "#/definitions/Scope"}, + "description": "The scopes of the stack frame. If the array has length zero, there are no scopes available.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, scopes, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -18959,13 +16469,12 @@ def __init__(self, scopes, update_ids_from_dap=False, **kwargs): # noqa (update Scope.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) scopes = self.scopes if scopes and hasattr(scopes[0], "to_dict"): scopes = [x.to_dict() for x in scopes] dct = { - 'scopes': [Scope.update_dict_ids_to_dap(o) for o in scopes] if (update_ids_to_dap and scopes) else scopes, + "scopes": [Scope.update_dict_ids_to_dap(o) for o in scopes] if (update_ids_to_dap and scopes) else scopes, } dct.update(self.kwargs) return dct @@ -18982,15 +16491,13 @@ class VariablesResponseBody(BaseSchema): __props__ = { "variables": { "type": "array", - "items": { - "$ref": "#/definitions/Variable" - }, - "description": "All (or a range) of variables for the given variable reference." + "items": {"$ref": "#/definitions/Variable"}, + "description": "All (or a range) of variables for the given variable reference.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, variables, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19002,13 +16509,12 @@ def __init__(self, variables, update_ids_from_dap=False, **kwargs): # noqa (upd Variable.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) variables = self.variables if variables and hasattr(variables[0], "to_dict"): variables = [x.to_dict() for x in variables] dct = { - 'variables': [Variable.update_dict_ids_to_dap(o) for o in variables] if (update_ids_to_dap and variables) else variables, + "variables": [Variable.update_dict_ids_to_dap(o) for o in variables] if (update_ids_to_dap and variables) else variables, } dct.update(self.kwargs) return dct @@ -19023,36 +16529,40 @@ class SetVariableResponseBody(BaseSchema): """ __props__ = { - "value": { - "type": "string", - "description": "The new value of the variable." - }, - "type": { - "type": "string", - "description": "The type of the new value. Typically shown in the UI when hovering over the value." - }, + "value": {"type": "string", "description": "The new value of the variable."}, + "type": {"type": "string", "description": "The type of the new value. Typically shown in the UI when hovering over the value."}, "variablesReference": { "type": "integer", - "description": "If `variablesReference` is > 0, the new value is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." + "description": "If `variablesReference` is > 0, the new value is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, "namedVariables": { "type": "integer", - "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "indexedVariables": { "type": "integer", - "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "memoryReference": { "type": "string", - "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True." - } + "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] - def __init__(self, value, type=None, variablesReference=None, namedVariables=None, indexedVariables=None, memoryReference=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + def __init__( + self, + value, + type=None, + variablesReference=None, + namedVariables=None, + indexedVariables=None, + memoryReference=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string value: The new value of the variable. :param string type: The type of the new value. Typically shown in the UI when hovering over the value. @@ -19076,12 +16586,11 @@ def __init__(self, value, type=None, variablesReference=None, namedVariables=Non if update_ids_from_dap: self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -19095,25 +16604,25 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if variablesReference is not None: variablesReference = self._translate_id_to_dap(variablesReference) dct = { - 'value': value, + "value": value, } if type is not None: - dct['type'] = type + dct["type"] = type if variablesReference is not None: - dct['variablesReference'] = variablesReference + dct["variablesReference"] = variablesReference if namedVariables is not None: - dct['namedVariables'] = namedVariables + dct["namedVariables"] = namedVariables if indexedVariables is not None: - dct['indexedVariables'] = indexedVariables + dct["indexedVariables"] = indexedVariables if memoryReference is not None: - dct['memoryReference'] = memoryReference + dct["memoryReference"] = memoryReference dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) return dct @@ -19126,18 +16635,12 @@ class SourceResponseBody(BaseSchema): """ __props__ = { - "content": { - "type": "string", - "description": "Content of the source reference." - }, - "mimeType": { - "type": "string", - "description": "Content type (MIME type) of the source." - } + "content": {"type": "string", "description": "Content of the source reference."}, + "mimeType": {"type": "string", "description": "Content type (MIME type) of the source."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, content, mimeType=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19148,15 +16651,14 @@ def __init__(self, content, mimeType=None, update_ids_from_dap=False, **kwargs): self.mimeType = mimeType self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) content = self.content mimeType = self.mimeType dct = { - 'content': content, + "content": content, } if mimeType is not None: - dct['mimeType'] = mimeType + dct["mimeType"] = mimeType dct.update(self.kwargs) return dct @@ -19169,18 +16671,10 @@ class ThreadsResponseBody(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "threads": { - "type": "array", - "items": { - "$ref": "#/definitions/Thread" - }, - "description": "All threads." - } - } + __props__ = {"threads": {"type": "array", "items": {"$ref": "#/definitions/Thread"}, "description": "All threads."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, threads, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19192,13 +16686,12 @@ def __init__(self, threads, update_ids_from_dap=False, **kwargs): # noqa (updat Thread.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) threads = self.threads if threads and hasattr(threads[0], "to_dict"): threads = [x.to_dict() for x in threads] dct = { - 'threads': [Thread.update_dict_ids_to_dap(o) for o in threads] if (update_ids_to_dap and threads) else threads, + "threads": [Thread.update_dict_ids_to_dap(o) for o in threads] if (update_ids_to_dap and threads) else threads, } dct.update(self.kwargs) return dct @@ -19213,21 +16706,12 @@ class ModulesResponseBody(BaseSchema): """ __props__ = { - "modules": { - "type": "array", - "items": { - "$ref": "#/definitions/Module" - }, - "description": "All modules or range of modules." - }, - "totalModules": { - "type": "integer", - "description": "The total number of modules available." - } + "modules": {"type": "array", "items": {"$ref": "#/definitions/Module"}, "description": "All modules or range of modules."}, + "totalModules": {"type": "integer", "description": "The total number of modules available."}, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, modules, totalModules=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19241,17 +16725,16 @@ def __init__(self, modules, totalModules=None, update_ids_from_dap=False, **kwar self.totalModules = totalModules self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) modules = self.modules if modules and hasattr(modules[0], "to_dict"): modules = [x.to_dict() for x in modules] totalModules = self.totalModules dct = { - 'modules': [Module.update_dict_ids_to_dap(o) for o in modules] if (update_ids_to_dap and modules) else modules, + "modules": [Module.update_dict_ids_to_dap(o) for o in modules] if (update_ids_to_dap and modules) else modules, } if totalModules is not None: - dct['totalModules'] = totalModules + dct["totalModules"] = totalModules dct.update(self.kwargs) return dct @@ -19264,18 +16747,10 @@ class LoadedSourcesResponseBody(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "sources": { - "type": "array", - "items": { - "$ref": "#/definitions/Source" - }, - "description": "Set of loaded sources." - } - } + __props__ = {"sources": {"type": "array", "items": {"$ref": "#/definitions/Source"}, "description": "Set of loaded sources."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, sources, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19287,13 +16762,12 @@ def __init__(self, sources, update_ids_from_dap=False, **kwargs): # noqa (updat Source.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) sources = self.sources if sources and hasattr(sources[0], "to_dict"): sources = [x.to_dict() for x in sources] dct = { - 'sources': [Source.update_dict_ids_to_dap(o) for o in sources] if (update_ids_to_dap and sources) else sources, + "sources": [Source.update_dict_ids_to_dap(o) for o in sources] if (update_ids_to_dap and sources) else sources, } dct.update(self.kwargs) return dct @@ -19308,40 +16782,48 @@ class EvaluateResponseBody(BaseSchema): """ __props__ = { - "result": { - "type": "string", - "description": "The result of the evaluate request." - }, + "result": {"type": "string", "description": "The result of the evaluate request."}, "type": { "type": "string", - "description": "The type of the evaluate result.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True." + "description": "The type of the evaluate result.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True.", }, "presentationHint": { "description": "Properties of an evaluate result that can be used to determine how to render the result in the UI.", - "type": "VariablePresentationHint" + "type": "VariablePresentationHint", }, "variablesReference": { "type": "integer", - "description": "If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." + "description": "If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, "namedVariables": { "type": "integer", - "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "indexedVariables": { "type": "integer", - "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "memoryReference": { "type": "string", - "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True." - } + "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True.", + }, } - __refs__ = set(['presentationHint']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, result, variablesReference, type=None, presentationHint=None, namedVariables=None, indexedVariables=None, memoryReference=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["presentationHint"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + result, + variablesReference, + type=None, + presentationHint=None, + namedVariables=None, + indexedVariables=None, + memoryReference=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string result: The result of the evaluate request. :param integer variablesReference: If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details. @@ -19364,19 +16846,22 @@ def __init__(self, result, variablesReference, type=None, presentationHint=None, if presentationHint is None: self.presentationHint = VariablePresentationHint() else: - self.presentationHint = VariablePresentationHint(update_ids_from_dap=update_ids_from_dap, **presentationHint) if presentationHint.__class__ != VariablePresentationHint else presentationHint + self.presentationHint = ( + VariablePresentationHint(update_ids_from_dap=update_ids_from_dap, **presentationHint) + if presentationHint.__class__ != VariablePresentationHint + else presentationHint + ) self.namedVariables = namedVariables self.indexedVariables = indexedVariables self.memoryReference = memoryReference if update_ids_from_dap: self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -19391,26 +16876,26 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if variablesReference is not None: variablesReference = self._translate_id_to_dap(variablesReference) dct = { - 'result': result, - 'variablesReference': variablesReference, + "result": result, + "variablesReference": variablesReference, } if type is not None: - dct['type'] = type + dct["type"] = type if presentationHint is not None: - dct['presentationHint'] = presentationHint.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["presentationHint"] = presentationHint.to_dict(update_ids_to_dap=update_ids_to_dap) if namedVariables is not None: - dct['namedVariables'] = namedVariables + dct["namedVariables"] = namedVariables if indexedVariables is not None: - dct['indexedVariables'] = indexedVariables + dct["indexedVariables"] = indexedVariables if memoryReference is not None: - dct['memoryReference'] = memoryReference + dct["memoryReference"] = memoryReference dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) return dct @@ -19423,40 +16908,48 @@ class SetExpressionResponseBody(BaseSchema): """ __props__ = { - "value": { - "type": "string", - "description": "The new value of the expression." - }, + "value": {"type": "string", "description": "The new value of the expression."}, "type": { "type": "string", - "description": "The type of the value.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True." + "description": "The type of the value.\nThis attribute should only be returned by a debug adapter if the corresponding capability `supportsVariableType` is True.", }, "presentationHint": { "description": "Properties of a value that can be used to determine how to render the result in the UI.", - "type": "VariablePresentationHint" + "type": "VariablePresentationHint", }, "variablesReference": { "type": "integer", - "description": "If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details." + "description": "If `variablesReference` is > 0, the evaluate result is structured and its children can be retrieved by passing `variablesReference` to the `variables` request as long as execution remains suspended. See 'Lifetime of Object References' in the Overview section for details.", }, "namedVariables": { "type": "integer", - "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of named child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "indexedVariables": { "type": "integer", - "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1)." + "description": "The number of indexed child variables.\nThe client can use this information to present the variables in a paged UI and fetch them in chunks.\nThe value should be less than or equal to 2147483647 (2^31-1).", }, "memoryReference": { "type": "string", - "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True." - } + "description": "A memory reference to a location appropriate for this result.\nFor pointer type eval results, this is generally a reference to the memory address contained in the pointer.\nThis attribute may be returned by a debug adapter if corresponding capability `supportsMemoryReferences` is True.", + }, } - __refs__ = set(['presentationHint']) - - __slots__ = list(__props__.keys()) + ['kwargs'] - - def __init__(self, value, type=None, presentationHint=None, variablesReference=None, namedVariables=None, indexedVariables=None, memoryReference=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) + __refs__ = set(["presentationHint"]) + + __slots__ = list(__props__.keys()) + ["kwargs"] + + def __init__( + self, + value, + type=None, + presentationHint=None, + variablesReference=None, + namedVariables=None, + indexedVariables=None, + memoryReference=None, + update_ids_from_dap=False, + **kwargs, + ): # noqa (update_ids_from_dap may be unused) """ :param string value: The new value of the expression. :param string type: The type of the value. @@ -19478,7 +16971,11 @@ def __init__(self, value, type=None, presentationHint=None, variablesReference=N if presentationHint is None: self.presentationHint = VariablePresentationHint() else: - self.presentationHint = VariablePresentationHint(update_ids_from_dap=update_ids_from_dap, **presentationHint) if presentationHint.__class__ != VariablePresentationHint else presentationHint + self.presentationHint = ( + VariablePresentationHint(update_ids_from_dap=update_ids_from_dap, **presentationHint) + if presentationHint.__class__ != VariablePresentationHint + else presentationHint + ) self.variablesReference = variablesReference self.namedVariables = namedVariables self.indexedVariables = indexedVariables @@ -19486,12 +16983,11 @@ def __init__(self, value, type=None, presentationHint=None, variablesReference=N if update_ids_from_dap: self.variablesReference = self._translate_id_from_dap(self.variablesReference) self.kwargs = kwargs - - + @classmethod def update_dict_ids_from_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_from_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_from_dap(dct["variablesReference"]) return dct def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) @@ -19506,27 +17002,27 @@ def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be un if variablesReference is not None: variablesReference = self._translate_id_to_dap(variablesReference) dct = { - 'value': value, + "value": value, } if type is not None: - dct['type'] = type + dct["type"] = type if presentationHint is not None: - dct['presentationHint'] = presentationHint.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["presentationHint"] = presentationHint.to_dict(update_ids_to_dap=update_ids_to_dap) if variablesReference is not None: - dct['variablesReference'] = variablesReference + dct["variablesReference"] = variablesReference if namedVariables is not None: - dct['namedVariables'] = namedVariables + dct["namedVariables"] = namedVariables if indexedVariables is not None: - dct['indexedVariables'] = indexedVariables + dct["indexedVariables"] = indexedVariables if memoryReference is not None: - dct['memoryReference'] = memoryReference + dct["memoryReference"] = memoryReference dct.update(self.kwargs) - return dct - + return dct + @classmethod def update_dict_ids_to_dap(cls, dct): - if 'variablesReference' in dct: - dct['variablesReference'] = cls._translate_id_to_dap(dct['variablesReference']) + if "variablesReference" in dct: + dct["variablesReference"] = cls._translate_id_to_dap(dct["variablesReference"]) return dct @@ -19541,15 +17037,13 @@ class StepInTargetsResponseBody(BaseSchema): __props__ = { "targets": { "type": "array", - "items": { - "$ref": "#/definitions/StepInTarget" - }, - "description": "The possible step-in targets of the specified source location." + "items": {"$ref": "#/definitions/StepInTarget"}, + "description": "The possible step-in targets of the specified source location.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, targets, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19561,13 +17055,12 @@ def __init__(self, targets, update_ids_from_dap=False, **kwargs): # noqa (updat StepInTarget.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) targets = self.targets if targets and hasattr(targets[0], "to_dict"): targets = [x.to_dict() for x in targets] dct = { - 'targets': [StepInTarget.update_dict_ids_to_dap(o) for o in targets] if (update_ids_to_dap and targets) else targets, + "targets": [StepInTarget.update_dict_ids_to_dap(o) for o in targets] if (update_ids_to_dap and targets) else targets, } dct.update(self.kwargs) return dct @@ -19584,15 +17077,13 @@ class GotoTargetsResponseBody(BaseSchema): __props__ = { "targets": { "type": "array", - "items": { - "$ref": "#/definitions/GotoTarget" - }, - "description": "The possible goto targets of the specified location." + "items": {"$ref": "#/definitions/GotoTarget"}, + "description": "The possible goto targets of the specified location.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, targets, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19604,13 +17095,12 @@ def __init__(self, targets, update_ids_from_dap=False, **kwargs): # noqa (updat GotoTarget.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) targets = self.targets if targets and hasattr(targets[0], "to_dict"): targets = [x.to_dict() for x in targets] dct = { - 'targets': [GotoTarget.update_dict_ids_to_dap(o) for o in targets] if (update_ids_to_dap and targets) else targets, + "targets": [GotoTarget.update_dict_ids_to_dap(o) for o in targets] if (update_ids_to_dap and targets) else targets, } dct.update(self.kwargs) return dct @@ -19625,17 +17115,11 @@ class CompletionsResponseBody(BaseSchema): """ __props__ = { - "targets": { - "type": "array", - "items": { - "$ref": "#/definitions/CompletionItem" - }, - "description": "The possible completions for ." - } + "targets": {"type": "array", "items": {"$ref": "#/definitions/CompletionItem"}, "description": "The possible completions for ."} } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, targets, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19647,13 +17131,12 @@ def __init__(self, targets, update_ids_from_dap=False, **kwargs): # noqa (updat CompletionItem.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) targets = self.targets if targets and hasattr(targets[0], "to_dict"): targets = [x.to_dict() for x in targets] dct = { - 'targets': [CompletionItem.update_dict_ids_to_dap(o) for o in targets] if (update_ids_to_dap and targets) else targets, + "targets": [CompletionItem.update_dict_ids_to_dap(o) for o in targets] if (update_ids_to_dap and targets) else targets, } dct.update(self.kwargs) return dct @@ -19668,26 +17151,14 @@ class ExceptionInfoResponseBody(BaseSchema): """ __props__ = { - "exceptionId": { - "type": "string", - "description": "ID of the exception that was thrown." - }, - "description": { - "type": "string", - "description": "Descriptive text for the exception." - }, - "breakMode": { - "description": "Mode that caused the exception notification to be raised.", - "type": "ExceptionBreakMode" - }, - "details": { - "description": "Detailed information about the exception.", - "type": "ExceptionDetails" - } + "exceptionId": {"type": "string", "description": "ID of the exception that was thrown."}, + "description": {"type": "string", "description": "Descriptive text for the exception."}, + "breakMode": {"description": "Mode that caused the exception notification to be raised.", "type": "ExceptionBreakMode"}, + "details": {"description": "Detailed information about the exception.", "type": "ExceptionDetails"}, } - __refs__ = set(['breakMode', 'details']) + __refs__ = set(["breakMode", "details"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, exceptionId, breakMode, description=None, details=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19704,23 +17175,24 @@ def __init__(self, exceptionId, breakMode, description=None, details=None, updat if details is None: self.details = ExceptionDetails() else: - self.details = ExceptionDetails(update_ids_from_dap=update_ids_from_dap, **details) if details.__class__ != ExceptionDetails else details + self.details = ( + ExceptionDetails(update_ids_from_dap=update_ids_from_dap, **details) if details.__class__ != ExceptionDetails else details + ) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) exceptionId = self.exceptionId breakMode = self.breakMode description = self.description details = self.details dct = { - 'exceptionId': exceptionId, - 'breakMode': breakMode, + "exceptionId": exceptionId, + "breakMode": breakMode, } if description is not None: - dct['description'] = description + dct["description"] = description if details is not None: - dct['details'] = details.to_dict(update_ids_to_dap=update_ids_to_dap) + dct["details"] = details.to_dict(update_ids_to_dap=update_ids_to_dap) dct.update(self.kwargs) return dct @@ -19736,20 +17208,20 @@ class ReadMemoryResponseBody(BaseSchema): __props__ = { "address": { "type": "string", - "description": "The address of the first byte of data returned.\nTreated as a hex value if prefixed with `0x`, or as a decimal value otherwise." + "description": "The address of the first byte of data returned.\nTreated as a hex value if prefixed with `0x`, or as a decimal value otherwise.", }, "unreadableBytes": { "type": "integer", - "description": "The number of unreadable bytes encountered after the last successfully read byte.\nThis can be used to determine the number of bytes that should be skipped before a subsequent `readMemory` request succeeds." + "description": "The number of unreadable bytes encountered after the last successfully read byte.\nThis can be used to determine the number of bytes that should be skipped before a subsequent `readMemory` request succeeds.", }, "data": { "type": "string", - "description": "The bytes read from memory, encoded using base64. If the decoded length of `data` is less than the requested `count` in the original `readMemory` request, and `unreadableBytes` is zero or omitted, then the client should assume it's reached the end of readable memory." - } + "description": "The bytes read from memory, encoded using base64. If the decoded length of `data` is less than the requested `count` in the original `readMemory` request, and `unreadableBytes` is zero or omitted, then the client should assume it's reached the end of readable memory.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, address, unreadableBytes=None, data=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19764,18 +17236,17 @@ def __init__(self, address, unreadableBytes=None, data=None, update_ids_from_dap self.data = data self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) address = self.address unreadableBytes = self.unreadableBytes data = self.data dct = { - 'address': address, + "address": address, } if unreadableBytes is not None: - dct['unreadableBytes'] = unreadableBytes + dct["unreadableBytes"] = unreadableBytes if data is not None: - dct['data'] = data + dct["data"] = data dct.update(self.kwargs) return dct @@ -19791,16 +17262,16 @@ class WriteMemoryResponseBody(BaseSchema): __props__ = { "offset": { "type": "integer", - "description": "Property that should be returned when `allowPartial` is True to indicate the offset of the first byte of data successfully written. Can be negative." + "description": "Property that should be returned when `allowPartial` is True to indicate the offset of the first byte of data successfully written. Can be negative.", }, "bytesWritten": { "type": "integer", - "description": "Property that should be returned when `allowPartial` is True to indicate the number of bytes starting from address that were successfully written." - } + "description": "Property that should be returned when `allowPartial` is True to indicate the number of bytes starting from address that were successfully written.", + }, } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, offset=None, bytesWritten=None, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19811,16 +17282,14 @@ def __init__(self, offset=None, bytesWritten=None, update_ids_from_dap=False, ** self.bytesWritten = bytesWritten self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) offset = self.offset bytesWritten = self.bytesWritten - dct = { - } + dct = {} if offset is not None: - dct['offset'] = offset + dct["offset"] = offset if bytesWritten is not None: - dct['bytesWritten'] = bytesWritten + dct["bytesWritten"] = bytesWritten dct.update(self.kwargs) return dct @@ -19836,15 +17305,13 @@ class DisassembleResponseBody(BaseSchema): __props__ = { "instructions": { "type": "array", - "items": { - "$ref": "#/definitions/DisassembledInstruction" - }, - "description": "The list of disassembled instructions." + "items": {"$ref": "#/definitions/DisassembledInstruction"}, + "description": "The list of disassembled instructions.", } } __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, instructions, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19856,13 +17323,14 @@ def __init__(self, instructions, update_ids_from_dap=False, **kwargs): # noqa ( DisassembledInstruction.update_dict_ids_from_dap(o) self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) instructions = self.instructions if instructions and hasattr(instructions[0], "to_dict"): instructions = [x.to_dict() for x in instructions] dct = { - 'instructions': [DisassembledInstruction.update_dict_ids_to_dap(o) for o in instructions] if (update_ids_to_dap and instructions) else instructions, + "instructions": [DisassembledInstruction.update_dict_ids_to_dap(o) for o in instructions] + if (update_ids_to_dap and instructions) + else instructions, } dct.update(self.kwargs) return dct @@ -19879,19 +17347,15 @@ class MessageVariables(BaseSchema): __props__ = {} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) - """ - - """ - - self.kwargs = kwargs + """ """ + self.kwargs = kwargs def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) - dct = { - } + dct = {} dct.update(self.kwargs) return dct @@ -19905,26 +17369,17 @@ class PydevdSystemInfoResponseBody(BaseSchema): """ __props__ = { - "python": { - "description": "Information about the python version running in the current process.", - "type": "PydevdPythonInfo" - }, + "python": {"description": "Information about the python version running in the current process.", "type": "PydevdPythonInfo"}, "platform": { "description": "Information about the plarforn on which the current process is running.", - "type": "PydevdPlatformInfo" + "type": "PydevdPlatformInfo", }, - "process": { - "description": "Information about the current process.", - "type": "PydevdProcessInfo" - }, - "pydevd": { - "description": "Information about pydevd.", - "type": "PydevdInfo" - } + "process": {"description": "Information about the current process.", "type": "PydevdProcessInfo"}, + "pydevd": {"description": "Information about pydevd.", "type": "PydevdInfo"}, } - __refs__ = set(['python', 'platform', 'process', 'pydevd']) + __refs__ = set(["python", "platform", "process", "pydevd"]) - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, python, platform, process, pydevd, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19936,32 +17391,39 @@ def __init__(self, python, platform, process, pydevd, update_ids_from_dap=False, if python is None: self.python = PydevdPythonInfo() else: - self.python = PydevdPythonInfo(update_ids_from_dap=update_ids_from_dap, **python) if python.__class__ != PydevdPythonInfo else python + self.python = ( + PydevdPythonInfo(update_ids_from_dap=update_ids_from_dap, **python) if python.__class__ != PydevdPythonInfo else python + ) if platform is None: self.platform = PydevdPlatformInfo() else: - self.platform = PydevdPlatformInfo(update_ids_from_dap=update_ids_from_dap, **platform) if platform.__class__ != PydevdPlatformInfo else platform + self.platform = ( + PydevdPlatformInfo(update_ids_from_dap=update_ids_from_dap, **platform) + if platform.__class__ != PydevdPlatformInfo + else platform + ) if process is None: self.process = PydevdProcessInfo() else: - self.process = PydevdProcessInfo(update_ids_from_dap=update_ids_from_dap, **process) if process.__class__ != PydevdProcessInfo else process + self.process = ( + PydevdProcessInfo(update_ids_from_dap=update_ids_from_dap, **process) if process.__class__ != PydevdProcessInfo else process + ) if pydevd is None: self.pydevd = PydevdInfo() else: - self.pydevd = PydevdInfo(update_ids_from_dap=update_ids_from_dap, **pydevd) if pydevd.__class__ != PydevdInfo else pydevd + self.pydevd = PydevdInfo(update_ids_from_dap=update_ids_from_dap, **pydevd) if pydevd.__class__ != PydevdInfo else pydevd self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) python = self.python platform = self.platform process = self.process pydevd = self.pydevd dct = { - 'python': python.to_dict(update_ids_to_dap=update_ids_to_dap), - 'platform': platform.to_dict(update_ids_to_dap=update_ids_to_dap), - 'process': process.to_dict(update_ids_to_dap=update_ids_to_dap), - 'pydevd': pydevd.to_dict(update_ids_to_dap=update_ids_to_dap), + "python": python.to_dict(update_ids_to_dap=update_ids_to_dap), + "platform": platform.to_dict(update_ids_to_dap=update_ids_to_dap), + "process": process.to_dict(update_ids_to_dap=update_ids_to_dap), + "pydevd": pydevd.to_dict(update_ids_to_dap=update_ids_to_dap), } dct.update(self.kwargs) return dct @@ -19975,15 +17437,10 @@ class PydevdAuthorizeResponseBody(BaseSchema): Note: automatically generated code. Do not edit manually. """ - __props__ = { - "clientAccessToken": { - "type": "string", - "description": "The access token to access the client (i.e.: usually the IDE)." - } - } + __props__ = {"clientAccessToken": {"type": "string", "description": "The access token to access the client (i.e.: usually the IDE)."}} __refs__ = set() - __slots__ = list(__props__.keys()) + ['kwargs'] + __slots__ = list(__props__.keys()) + ["kwargs"] def __init__(self, clientAccessToken, update_ids_from_dap=False, **kwargs): # noqa (update_ids_from_dap may be unused) """ @@ -19992,11 +17449,10 @@ def __init__(self, clientAccessToken, update_ids_from_dap=False, **kwargs): # n self.clientAccessToken = clientAccessToken self.kwargs = kwargs - def to_dict(self, update_ids_to_dap=False): # noqa (update_ids_to_dap may be unused) clientAccessToken = self.clientAccessToken dct = { - 'clientAccessToken': clientAccessToken, + "clientAccessToken": clientAccessToken, } dct.update(self.kwargs) return dct diff --git a/_pydevd_bundle/_debug_adapter/pydevd_schema_log.py b/_pydevd_bundle/_debug_adapter/pydevd_schema_log.py index 28b729266..b3dda5ad8 100644 --- a/_pydevd_bundle/_debug_adapter/pydevd_schema_log.py +++ b/_pydevd_bundle/_debug_adapter/pydevd_schema_log.py @@ -3,12 +3,12 @@ from _pydevd_bundle.pydevd_constants import ForkSafeLock _pid = os.getpid() -_pid_msg = '%s: ' % (_pid,) +_pid_msg = "%s: " % (_pid,) _debug_lock = ForkSafeLock() DEBUG = False -DEBUG_FILE = os.path.join(os.path.dirname(__file__), '__debug_output__.txt') +DEBUG_FILE = os.path.join(os.path.dirname(__file__), "__debug_output__.txt") def debug(msg): @@ -16,15 +16,15 @@ def debug(msg): with _debug_lock: _pid_prefix = _pid_msg if isinstance(msg, bytes): - _pid_prefix = _pid_prefix.encode('utf-8') + _pid_prefix = _pid_prefix.encode("utf-8") - if not msg.endswith(b'\r') and not msg.endswith(b'\n'): - msg += b'\n' - mode = 'a+b' + if not msg.endswith(b"\r") and not msg.endswith(b"\n"): + msg += b"\n" + mode = "a+b" else: - if not msg.endswith('\r') and not msg.endswith('\n'): - msg += '\n' - mode = 'a+' + if not msg.endswith("\r") and not msg.endswith("\n"): + msg += "\n" + mode = "a+" with open(DEBUG_FILE, mode) as stream: stream.write(_pid_prefix) stream.write(msg) @@ -36,11 +36,10 @@ def debug_exception(msg=None): debug(msg) with _debug_lock: - - with open(DEBUG_FILE, 'a+') as stream: + with open(DEBUG_FILE, "a+") as stream: _pid_prefix = _pid_msg if isinstance(msg, bytes): - _pid_prefix = _pid_prefix.encode('utf-8') + _pid_prefix = _pid_prefix.encode("utf-8") stream.write(_pid_prefix) traceback.print_exc(file=stream) diff --git a/_pydevd_bundle/pydevconsole_code.py b/_pydevd_bundle/pydevconsole_code.py index e6ba30023..760036e0b 100644 --- a/_pydevd_bundle/pydevconsole_code.py +++ b/_pydevd_bundle/pydevconsole_code.py @@ -76,8 +76,7 @@ import __future__ -_features = [getattr(__future__, fname) - for fname in __future__.all_feature_names] +_features = [getattr(__future__, fname) for fname in __future__.all_feature_names] __all__ = ["compile_command", "Compile", "CommandCompiler"] @@ -88,7 +87,7 @@ def _maybe_compile(compiler, source, filename, symbol): # Check for source consisting of only blank lines and comments for line in source.split("\n"): line = line.strip() - if line and line[0] != '#': + if line and line[0] != "#": break # Leave it alone else: if symbol != "eval": @@ -157,6 +156,7 @@ def __init__(self): try: from ast import PyCF_ALLOW_TOP_LEVEL_AWAIT + self.flags |= PyCF_ALLOW_TOP_LEVEL_AWAIT except: pass @@ -176,7 +176,9 @@ class CommandCompiler: the instance 'remembers' and compiles all subsequent program texts with the statement in force.""" - def __init__(self,): + def __init__( + self, + ): self.compiler = Compile() def __call__(self, source, filename="", symbol="single"): @@ -200,6 +202,7 @@ def __call__(self, source, filename="", symbol="single"): """ return _maybe_compile(self.compiler, source, filename, symbol) + # END --------------------------- from codeop import CommandCompiler, compile_command # END --------------------------- from codeop import CommandCompiler, compile_command # END --------------------------- from codeop import CommandCompiler, compile_command @@ -207,14 +210,12 @@ def __call__(self, source, filename="", symbol="single"): # END --------------------------- from codeop import CommandCompiler, compile_command -__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", - "compile_command"] +__all__ = ["InteractiveInterpreter", "InteractiveConsole", "interact", "compile_command"] from _pydev_bundle._pydev_saved_modules import threading class _EvalAwaitInNewEventLoop(threading.Thread): - def __init__(self, compiled, updated_globals, updated_locals): threading.Thread.__init__(self) self.daemon = True @@ -232,6 +233,7 @@ async def _async_func(self): def run(self): try: import asyncio + loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.evaluated_value = asyncio.run(self._async_func()) @@ -315,7 +317,7 @@ def runcode(self, code): """ try: is_async = False - if hasattr(inspect, 'CO_COROUTINE'): + if hasattr(inspect, "CO_COROUTINE"): is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE if is_async: @@ -362,7 +364,7 @@ def showsyntaxerror(self, filename=None): sys.last_value = value if sys.excepthook is sys.__excepthook__: lines = traceback.format_exception_only(type, value) - self.write(''.join(lines)) + self.write("".join(lines)) else: # If someone has set sys.excepthook, we let that take precedence # over self.write @@ -381,7 +383,7 @@ def showtraceback(self): try: lines = traceback.format_exception(ei[0], ei[1], last_tb.tb_next) if sys.excepthook is sys.__excepthook__: - self.write(''.join(lines)) + self.write("".join(lines)) else: # If someone has set sys.excepthook, we let that take precedence # over self.write @@ -451,9 +453,7 @@ def interact(self, banner=None, exitmsg=None): sys.ps2 = "... " cprt = 'Type "help", "copyright", "credits" or "license" for more information.' if banner is None: - self.write("Python %s on %s\n%s\n(%s)\n" % - (sys.version, sys.platform, cprt, - self.__class__.__name__)) + self.write("Python %s on %s\n%s\n(%s)\n" % (sys.version, sys.platform, cprt, self.__class__.__name__)) elif banner: self.write("%s\n" % str(banner)) more = 0 @@ -475,9 +475,9 @@ def interact(self, banner=None, exitmsg=None): self.resetbuffer() more = 0 if exitmsg is None: - self.write('now exiting %s...\n' % self.__class__.__name__) - elif exitmsg != '': - self.write('%s\n' % exitmsg) + self.write("now exiting %s...\n" % self.__class__.__name__) + elif exitmsg != "": + self.write("%s\n" % exitmsg) def push(self, line): """Push a line to the interpreter. @@ -544,11 +544,10 @@ def interact(banner=None, readfunc=None, local=None, exitmsg=None): import argparse parser = argparse.ArgumentParser() - parser.add_argument('-q', action='store_true', - help="don't print version and copyright messages") + parser.add_argument("-q", action="store_true", help="don't print version and copyright messages") args = parser.parse_args() if args.q or sys.flags.quiet: - banner = '' + banner = "" else: banner = None interact(banner) diff --git a/_pydevd_bundle/pydevd_additional_thread_info.py b/_pydevd_bundle/pydevd_additional_thread_info.py index 3ee776a00..f3ee78286 100644 --- a/_pydevd_bundle/pydevd_additional_thread_info.py +++ b/_pydevd_bundle/pydevd_additional_thread_info.py @@ -1,27 +1,41 @@ # Defines which version of the PyDBAdditionalThreadInfo we'll use. -from _pydevd_bundle.pydevd_constants import ENV_FALSE_LOWER_VALUES, USE_CYTHON_FLAG, \ - ENV_TRUE_LOWER_VALUES +from _pydevd_bundle.pydevd_constants import ENV_FALSE_LOWER_VALUES, USE_CYTHON_FLAG, ENV_TRUE_LOWER_VALUES if USE_CYTHON_FLAG in ENV_TRUE_LOWER_VALUES: # We must import the cython version if forcing cython from _pydevd_bundle.pydevd_cython_wrapper import ( - PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock, # @UnusedImport - any_thread_stepping, remove_additional_info) # @UnusedImport + PyDBAdditionalThreadInfo, + set_additional_thread_info, + _set_additional_thread_info_lock, # @UnusedImport + any_thread_stepping, + remove_additional_info, + ) # @UnusedImport elif USE_CYTHON_FLAG in ENV_FALSE_LOWER_VALUES: # Use the regular version if not forcing cython from _pydevd_bundle.pydevd_additional_thread_info_regular import ( - PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock, # @UnusedImport @Reimport - any_thread_stepping, remove_additional_info) # @UnusedImport @Reimport + PyDBAdditionalThreadInfo, + set_additional_thread_info, + _set_additional_thread_info_lock, # @UnusedImport @Reimport + any_thread_stepping, + remove_additional_info, + ) # @UnusedImport @Reimport else: # Regular: use fallback if not found (message is already given elsewhere). try: from _pydevd_bundle.pydevd_cython_wrapper import ( - PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock, - any_thread_stepping, remove_additional_info) + PyDBAdditionalThreadInfo, + set_additional_thread_info, + _set_additional_thread_info_lock, + any_thread_stepping, + remove_additional_info, + ) except ImportError: from _pydevd_bundle.pydevd_additional_thread_info_regular import ( - PyDBAdditionalThreadInfo, set_additional_thread_info, _set_additional_thread_info_lock, # @UnusedImport - any_thread_stepping, remove_additional_info) # @UnusedImport - + PyDBAdditionalThreadInfo, + set_additional_thread_info, + _set_additional_thread_info_lock, # @UnusedImport + any_thread_stepping, + remove_additional_info, + ) # @UnusedImport diff --git a/_pydevd_bundle/pydevd_additional_thread_info_regular.py b/_pydevd_bundle/pydevd_additional_thread_info_regular.py index a01bef52b..cff3e6b22 100644 --- a/_pydevd_bundle/pydevd_additional_thread_info_regular.py +++ b/_pydevd_bundle/pydevd_additional_thread_info_regular.py @@ -1,5 +1,13 @@ -from _pydevd_bundle.pydevd_constants import (STATE_RUN, PYTHON_SUSPEND, SUPPORT_GEVENT, ForkSafeLock, - _current_frames, STATE_SUSPEND, get_global_debugger, get_thread_id) +from _pydevd_bundle.pydevd_constants import ( + STATE_RUN, + PYTHON_SUSPEND, + SUPPORT_GEVENT, + ForkSafeLock, + _current_frames, + STATE_SUSPEND, + get_global_debugger, + get_thread_id, +) from _pydev_bundle import pydev_log from _pydev_bundle._pydev_saved_modules import threading import weakref @@ -7,55 +15,50 @@ version = 11 -#======================================================================================================================= +# ======================================================================================================================= # PyDBAdditionalThreadInfo -#======================================================================================================================= +# ======================================================================================================================= # IFDEF CYTHON # cdef class PyDBAdditionalThreadInfo: # ELSE class PyDBAdditionalThreadInfo(object): -# ENDIF + # ENDIF # Note: the params in cython are declared in pydevd_cython.pxd. # IFDEF CYTHON # ELSE __slots__ = [ - 'pydev_state', - 'pydev_step_stop', - 'pydev_original_step_cmd', - 'pydev_step_cmd', - 'pydev_notify_kill', - 'pydev_django_resolve_frame', - 'pydev_call_from_jinja2', - 'pydev_call_inside_jinja2', - 'is_tracing', - 'conditional_breakpoint_exception', - 'pydev_message', - 'suspend_type', - 'pydev_next_line', - 'pydev_func_name', - 'suspended_at_unhandled', - 'trace_suspend_type', - 'top_level_thread_tracer_no_back_frames', - 'top_level_thread_tracer_unhandled', - 'thread_tracer', - 'step_in_initial_location', - + "pydev_state", + "pydev_step_stop", + "pydev_original_step_cmd", + "pydev_step_cmd", + "pydev_notify_kill", + "pydev_django_resolve_frame", + "pydev_call_from_jinja2", + "pydev_call_inside_jinja2", + "is_tracing", + "conditional_breakpoint_exception", + "pydev_message", + "suspend_type", + "pydev_next_line", + "pydev_func_name", + "suspended_at_unhandled", + "trace_suspend_type", + "top_level_thread_tracer_no_back_frames", + "top_level_thread_tracer_unhandled", + "thread_tracer", + "step_in_initial_location", # Used for CMD_SMART_STEP_INTO (to know which smart step into variant to use) - 'pydev_smart_parent_offset', - 'pydev_smart_child_offset', - + "pydev_smart_parent_offset", + "pydev_smart_child_offset", # Used for CMD_SMART_STEP_INTO (list[_pydevd_bundle.pydevd_bytecode_utils.Variant]) # Filled when the cmd_get_smart_step_into_variants is requested (so, this is a copy # of the last request for a given thread and pydev_smart_parent_offset/pydev_smart_child_offset relies on it). - 'pydev_smart_step_into_variants', - 'target_id_to_smart_step_into_variant', - - 'pydev_use_scoped_step_frame', - - 'weak_thread', - - 'is_in_wait_loop', + "pydev_smart_step_into_variants", + "target_id_to_smart_step_into_variant", + "pydev_use_scoped_step_frame", + "weak_thread", + "is_in_wait_loop", ] # ENDIF @@ -78,12 +81,12 @@ def __init__(self): self.pydev_call_inside_jinja2 = None self.is_tracing = 0 self.conditional_breakpoint_exception = None - self.pydev_message = '' + self.pydev_message = "" self.suspend_type = PYTHON_SUSPEND self.pydev_next_line = -1 - self.pydev_func_name = '.invalid.' # Must match the type in cython + self.pydev_func_name = ".invalid." # Must match the type in cython self.suspended_at_unhandled = False - self.trace_suspend_type = 'trace' # 'trace' or 'frame_eval' + self.trace_suspend_type = "trace" # 'trace' or 'frame_eval' self.top_level_thread_tracer_no_back_frames = [] self.top_level_thread_tracer_unhandled = None self.thread_tracer = None @@ -111,11 +114,11 @@ def __init__(self): # to pause). self.is_in_wait_loop = False -# IFDEF CYTHON -# cpdef object _get_related_thread(self): -# ELSE + # IFDEF CYTHON + # cpdef object _get_related_thread(self): + # ELSE def _get_related_thread(self): -# ENDIF + # ENDIF if self.pydev_notify_kill: # Already killed return None @@ -130,7 +133,7 @@ def _get_related_thread(self): return None if thread._ident is None: # Can this happen? - pydev_log.critical('thread._ident is None in _get_related_thread!') + pydev_log.critical("thread._ident is None in _get_related_thread!") return None if threading._active.get(thread._ident) is not thread: @@ -138,11 +141,11 @@ def _get_related_thread(self): return thread -# IFDEF CYTHON -# cpdef bint _is_stepping(self): -# ELSE + # IFDEF CYTHON + # cpdef bint _is_stepping(self): + # ELSE def _is_stepping(self): -# ENDIF + # ENDIF if self.pydev_state == STATE_RUN and self.pydev_step_cmd != -1: # This means actually stepping in a step operation. return True @@ -154,16 +157,16 @@ def _is_stepping(self): return False -# IFDEF CYTHON -# cpdef get_topmost_frame(self, thread): -# ELSE + # IFDEF CYTHON + # cpdef get_topmost_frame(self, thread): + # ELSE def get_topmost_frame(self, thread): -# ENDIF - ''' + # ENDIF + """ Gets the topmost frame for the given thread. Note that it may be None and callers should remove the reference to the frame as soon as possible to avoid disturbing user code. - ''' + """ # sys._current_frames(): dictionary with thread id -> topmost frame current_frames = _current_frames() topmost_frame = current_frames.get(thread._ident) @@ -171,8 +174,7 @@ def get_topmost_frame(self, thread): # Note: this is expected for dummy threads (so, getting the topmost frame should be # treated as optional). pydev_log.info( - 'Unable to get topmost frame for thread: %s, thread.ident: %s, id(thread): %s\nCurrent frames: %s.\n' - 'GEVENT_SUPPORT: %s', + "Unable to get topmost frame for thread: %s, thread.ident: %s, id(thread): %s\nCurrent frames: %s.\n" "GEVENT_SUPPORT: %s", thread, thread.ident, id(thread), @@ -182,16 +184,15 @@ def get_topmost_frame(self, thread): return topmost_frame -# IFDEF CYTHON -# cpdef update_stepping_info(self): -# ELSE + # IFDEF CYTHON + # cpdef update_stepping_info(self): + # ELSE def update_stepping_info(self): -# ENDIF + # ENDIF _update_stepping_info(self) def __str__(self): - return 'State:%s Stop:%s Cmd: %s Kill:%s' % ( - self.pydev_state, self.pydev_step_stop, self.pydev_step_cmd, self.pydev_notify_kill) + return "State:%s Stop:%s Cmd: %s Kill:%s" % (self.pydev_state, self.pydev_step_stop, self.pydev_step_cmd, self.pydev_notify_kill) _set_additional_thread_info_lock = ForkSafeLock() @@ -202,7 +203,7 @@ def __str__(self): # cpdef set_additional_thread_info(thread): # ELSE def set_additional_thread_info(thread): -# ENDIF + # ENDIF try: additional_info = thread.additional_info if additional_info is None: @@ -230,6 +231,7 @@ def set_additional_thread_info(thread): return additional_info + # IFDEF CYTHON # cdef set _all_infos # cdef set _infos_stepping @@ -247,7 +249,7 @@ def set_additional_thread_info(thread): # cdef _update_stepping_info(PyDBAdditionalThreadInfo info): # ELSE def _update_stepping_info(info): -# ENDIF + # ENDIF global _infos_stepping global _all_infos @@ -278,7 +280,7 @@ def _update_stepping_info(info): # cpdef add_additional_info(PyDBAdditionalThreadInfo info): # ELSE def add_additional_info(info): -# ENDIF + # ENDIF with _update_infos_lock: _all_infos.add(info) if info._is_stepping(): @@ -289,7 +291,7 @@ def add_additional_info(info): # cpdef remove_additional_info(PyDBAdditionalThreadInfo info): # ELSE def remove_additional_info(info): -# ENDIF + # ENDIF with _update_infos_lock: _all_infos.discard(info) _infos_stepping.discard(info) @@ -299,5 +301,5 @@ def remove_additional_info(info): # cpdef bint any_thread_stepping(): # ELSE def any_thread_stepping(): -# ENDIF + # ENDIF return bool(_infos_stepping) diff --git a/_pydevd_bundle/pydevd_api.py b/_pydevd_bundle/pydevd_api.py index 6b1c6f574..c8b2100c0 100644 --- a/_pydevd_bundle/pydevd_api.py +++ b/_pydevd_bundle/pydevd_api.py @@ -5,18 +5,44 @@ from _pydev_bundle._pydev_saved_modules import threading from _pydevd_bundle import pydevd_utils, pydevd_source_mapping from _pydevd_bundle.pydevd_additional_thread_info import set_additional_thread_info -from _pydevd_bundle.pydevd_comm import (InternalGetThreadStack, internal_get_completions, - InternalSetNextStatementThread, internal_reload_code, - InternalGetVariable, InternalGetArray, InternalLoadFullValue, - internal_get_description, internal_get_frame, internal_evaluate_expression, InternalConsoleExec, - internal_get_variable_json, internal_change_variable, internal_change_variable_json, - internal_evaluate_expression_json, internal_set_expression_json, internal_get_exception_details_json, - internal_step_in_thread, internal_smart_step_into) -from _pydevd_bundle.pydevd_comm_constants import (CMD_THREAD_SUSPEND, file_system_encoding, - CMD_STEP_INTO_MY_CODE, CMD_STOP_ON_START, CMD_SMART_STEP_INTO) -from _pydevd_bundle.pydevd_constants import (get_current_thread_id, set_protocol, get_protocol, - HTTP_JSON_PROTOCOL, JSON_PROTOCOL, DebugInfoHolder, IS_WINDOWS, - PYDEVD_USE_SYS_MONITORING) +from _pydevd_bundle.pydevd_comm import ( + InternalGetThreadStack, + internal_get_completions, + InternalSetNextStatementThread, + internal_reload_code, + InternalGetVariable, + InternalGetArray, + InternalLoadFullValue, + internal_get_description, + internal_get_frame, + internal_evaluate_expression, + InternalConsoleExec, + internal_get_variable_json, + internal_change_variable, + internal_change_variable_json, + internal_evaluate_expression_json, + internal_set_expression_json, + internal_get_exception_details_json, + internal_step_in_thread, + internal_smart_step_into, +) +from _pydevd_bundle.pydevd_comm_constants import ( + CMD_THREAD_SUSPEND, + file_system_encoding, + CMD_STEP_INTO_MY_CODE, + CMD_STOP_ON_START, + CMD_SMART_STEP_INTO, +) +from _pydevd_bundle.pydevd_constants import ( + get_current_thread_id, + set_protocol, + get_protocol, + HTTP_JSON_PROTOCOL, + JSON_PROTOCOL, + DebugInfoHolder, + IS_WINDOWS, + PYDEVD_USE_SYS_MONITORING, +) from _pydevd_bundle.pydevd_net_command_factory_json import NetCommandFactoryJson from _pydevd_bundle.pydevd_net_command_factory_xml import NetCommandFactory import pydevd_file_utils @@ -49,7 +75,7 @@ def _get_code_lines(code): path = code with tokenize.open(path) as f: src = f.read() - code = compile(src, path, 'exec', 0, dont_inherit=True) + code = compile(src, path, "exec", 0, dont_inherit=True) return _get_code_lines(code) def iterate(): @@ -70,10 +96,8 @@ def iterate(): class PyDevdAPI(object): - class VariablePresentation(object): - - def __init__(self, special='group', function='group', class_='group', protected='inline'): + def __init__(self, special="group", function="group", class_="group", protected="inline"): self._presentation = { DAPGrouper.SCOPE_SPECIAL_VARS: special, DAPGrouper.SCOPE_FUNCTION_VARS: function, @@ -109,11 +133,11 @@ def set_protocol(self, py_db, seq, protocol): return py_db.cmd_factory.make_protocol_set_message(seq) def set_ide_os_and_breakpoints_by(self, py_db, seq, ide_os, breakpoints_by): - ''' + """ :param ide_os: 'WINDOWS' or 'UNIX' :param breakpoints_by: 'ID' or 'LINE' - ''' - if breakpoints_by == 'ID': + """ + if breakpoints_by == "ID": py_db._set_breakpoints_with_id = True else: py_db._set_breakpoints_with_id = False @@ -123,16 +147,16 @@ def set_ide_os_and_breakpoints_by(self, py_db, seq, ide_os, breakpoints_by): return py_db.cmd_factory.make_version_message(seq) def set_ide_os(self, ide_os): - ''' + """ :param ide_os: 'WINDOWS' or 'UNIX' - ''' + """ pydevd_file_utils.set_ide_os(ide_os) def set_gui_event_loop(self, py_db, gui_event_loop): py_db._gui_event_loop = gui_event_loop def send_error_message(self, py_db, msg): - cmd = py_db.cmd_factory.make_warning_message('pydevd: %s\n' % (msg,)) + cmd = py_db.cmd_factory.make_warning_message("pydevd: %s\n" % (msg,)) py_db.writer.add_command(cmd) def set_show_return_values(self, py_db, show_return_values): @@ -149,14 +173,14 @@ def list_threads(self, py_db, seq): # Response is the command with the list of threads to be added to the writer thread. return py_db.cmd_factory.make_list_threads_message(py_db, seq) - def request_suspend_thread(self, py_db, thread_id='*'): + def request_suspend_thread(self, py_db, thread_id="*"): # Yes, thread suspend is done at this point, not through an internal command. threads = [] - suspend_all = thread_id.strip() == '*' + suspend_all = thread_id.strip() == "*" if suspend_all: threads = pydevd_utils.get_non_pydevd_threads() - elif thread_id.startswith('__frame__:'): + elif thread_id.startswith("__frame__:"): sys.stderr.write("Can't suspend tasklet: %s\n" % (thread_id,)) else: @@ -176,40 +200,42 @@ def request_suspend_thread(self, py_db, thread_id='*'): break def set_enable_thread_notifications(self, py_db, enable): - ''' + """ When disabled, no thread notifications (for creation/removal) will be issued until it's re-enabled. Note that when it's re-enabled, a creation notification will be sent for all existing threads even if it was previously sent (this is meant to be used on disconnect/reconnect). - ''' + """ py_db.set_enable_thread_notifications(enable) def request_disconnect(self, py_db, resume_threads): self.set_enable_thread_notifications(py_db, False) - self.remove_all_breakpoints(py_db, '*') + self.remove_all_breakpoints(py_db, "*") self.remove_all_exception_breakpoints(py_db) self.notify_disconnect(py_db) if resume_threads: - self.request_resume_thread(thread_id='*') + self.request_resume_thread(thread_id="*") def request_resume_thread(self, thread_id): resume_threads(thread_id) def request_completions(self, py_db, seq, thread_id, frame_id, act_tok, line=-1, column=-1): py_db.post_method_as_internal_command( - thread_id, internal_get_completions, seq, thread_id, frame_id, act_tok, line=line, column=column) + thread_id, internal_get_completions, seq, thread_id, frame_id, act_tok, line=line, column=column + ) - def request_stack(self, py_db, seq, thread_id, fmt=None, timeout=.5, start_frame=0, levels=0): + def request_stack(self, py_db, seq, thread_id, fmt=None, timeout=0.5, start_frame=0, levels=0): # If it's already suspended, get it right away. internal_get_thread_stack = InternalGetThreadStack( - seq, thread_id, py_db, set_additional_thread_info, fmt=fmt, timeout=timeout, start_frame=start_frame, levels=levels) + seq, thread_id, py_db, set_additional_thread_info, fmt=fmt, timeout=timeout, start_frame=start_frame, levels=levels + ) if internal_get_thread_stack.can_be_executed_by(get_current_thread_id(threading.current_thread())): internal_get_thread_stack.do_it(py_db) else: - py_db.post_internal_command(internal_get_thread_stack, '*') + py_db.post_internal_command(internal_get_thread_stack, "*") def request_exception_info_json(self, py_db, request, thread_id, thread, max_frames): py_db.post_method_as_internal_command( @@ -233,15 +259,16 @@ def request_step(self, py_db, thread_id, step_cmd_id): step_cmd_id, set_additional_thread_info=set_additional_thread_info, ) - elif thread_id.startswith('__frame__:'): + elif thread_id.startswith("__frame__:"): sys.stderr.write("Can't make tasklet step command: %s\n" % (thread_id,)) def request_smart_step_into(self, py_db, seq, thread_id, offset, child_offset): t = pydevd_find_thread_by_id(thread_id) if t: py_db.post_method_as_internal_command( - thread_id, internal_smart_step_into, thread_id, offset, child_offset, set_additional_thread_info=set_additional_thread_info) - elif thread_id.startswith('__frame__:'): + thread_id, internal_smart_step_into, thread_id, offset, child_offset, set_additional_thread_info=set_additional_thread_info + ) + elif thread_id.startswith("__frame__:"): sys.stderr.write("Can't set next statement in tasklet: %s\n" % (thread_id,)) def request_smart_step_into_by_func_name(self, py_db, seq, thread_id, line, func_name): @@ -249,7 +276,7 @@ def request_smart_step_into_by_func_name(self, py_db, seq, thread_id, line, func self.request_set_next(py_db, seq, thread_id, CMD_SMART_STEP_INTO, None, line, func_name) def request_set_next(self, py_db, seq, thread_id, set_next_cmd_id, original_filename, line, func_name): - ''' + """ set_next_cmd_id may actually be one of: CMD_RUN_TO_LINE @@ -263,52 +290,49 @@ def request_set_next(self, py_db, seq, thread_id, set_next_cmd_id, original_file place (the set next just needs the line afterwards as it executes locally, but for the Jupyter integration, the source mapping may change the actual lines and not only the filename). - ''' + """ t = pydevd_find_thread_by_id(thread_id) if t: if original_filename is not None: translated_filename = self.filename_to_server(original_filename) # Apply user path mapping. - pydev_log.debug('Set next (after path translation) in: %s line: %s', translated_filename, line) + pydev_log.debug("Set next (after path translation) in: %s line: %s", translated_filename, line) func_name = self.to_str(func_name) assert translated_filename.__class__ == str # i.e.: bytes on py2 and str on py3 assert func_name.__class__ == str # i.e.: bytes on py2 and str on py3 # Apply source mapping (i.e.: ipython). - _source_mapped_filename, new_line, multi_mapping_applied = py_db.source_mapping.map_to_server( - translated_filename, line) + _source_mapped_filename, new_line, multi_mapping_applied = py_db.source_mapping.map_to_server(translated_filename, line) if multi_mapping_applied: - pydev_log.debug('Set next (after source mapping) in: %s line: %s', translated_filename, line) + pydev_log.debug("Set next (after source mapping) in: %s line: %s", translated_filename, line) line = new_line int_cmd = InternalSetNextStatementThread(thread_id, set_next_cmd_id, line, func_name, seq=seq) py_db.post_internal_command(int_cmd, thread_id) - elif thread_id.startswith('__frame__:'): + elif thread_id.startswith("__frame__:"): sys.stderr.write("Can't set next statement in tasklet: %s\n" % (thread_id,)) def request_reload_code(self, py_db, seq, module_name, filename): - ''' + """ :param seq: if -1 no message will be sent back when the reload is done. Note: either module_name or filename may be None (but not both at the same time). - ''' - thread_id = '*' # Any thread + """ + thread_id = "*" # Any thread # Note: not going for the main thread because in this case it'd only do the load # when we stopped on a breakpoint. - py_db.post_method_as_internal_command( - thread_id, internal_reload_code, seq, module_name, filename) + py_db.post_method_as_internal_command(thread_id, internal_reload_code, seq, module_name, filename) def request_change_variable(self, py_db, seq, thread_id, frame_id, scope, attr, value): - ''' + """ :param scope: 'FRAME' or 'GLOBAL' - ''' - py_db.post_method_as_internal_command( - thread_id, internal_change_variable, seq, thread_id, frame_id, scope, attr, value) + """ + py_db.post_method_as_internal_command(thread_id, internal_change_variable, seq, thread_id, frame_id, scope, attr, value) def request_get_variable(self, py_db, seq, thread_id, frame_id, scope, attrs): - ''' + """ :param scope: 'FRAME' or 'GLOBAL' - ''' + """ int_cmd = InternalGetVariable(seq, thread_id, frame_id, scope, attrs) py_db.post_internal_command(int_cmd, thread_id) @@ -321,27 +345,25 @@ def request_load_full_value(self, py_db, seq, thread_id, frame_id, vars): py_db.post_internal_command(int_cmd, thread_id) def request_get_description(self, py_db, seq, thread_id, frame_id, expression): - py_db.post_method_as_internal_command( - thread_id, internal_get_description, seq, thread_id, frame_id, expression) + py_db.post_method_as_internal_command(thread_id, internal_get_description, seq, thread_id, frame_id, expression) def request_get_frame(self, py_db, seq, thread_id, frame_id): - py_db.post_method_as_internal_command( - thread_id, internal_get_frame, seq, thread_id, frame_id) + py_db.post_method_as_internal_command(thread_id, internal_get_frame, seq, thread_id, frame_id) def to_str(self, s): - ''' + """ -- in py3 raises an error if it's not str already. - ''' + """ if s.__class__ != str: - raise AssertionError('Expected to have str on Python 3. Found: %s (%s)' % (s, s.__class__)) + raise AssertionError("Expected to have str on Python 3. Found: %s (%s)" % (s, s.__class__)) return s def filename_to_str(self, filename): - ''' + """ -- in py3 raises an error if it's not str already. - ''' + """ if filename.__class__ != str: - raise AssertionError('Expected to have str on Python 3. Found: %s (%s)' % (filename, filename.__class__)) + raise AssertionError("Expected to have str on Python 3. Found: %s (%s)" % (filename, filename.__class__)) return filename def filename_to_server(self, filename): @@ -350,17 +372,16 @@ def filename_to_server(self, filename): return filename class _DummyFrame(object): - ''' + """ Dummy frame to be used with PyDB.apply_files_filter (as we don't really have the related frame as breakpoints are added before execution). - ''' + """ class _DummyCode(object): - def __init__(self, filename): self.co_firstlineno = 1 self.co_filename = filename - self.co_name = 'invalid func name ' + self.co_name = "invalid func name " def __init__(self, filename): self.f_code = self._DummyCode(filename) @@ -376,14 +397,13 @@ def __init__(self, filename): ADD_BREAKPOINT_INVALID_LINE = 4 class _AddBreakpointResult(object): - # :see: ADD_BREAKPOINT_NO_ERROR = 0 # :see: ADD_BREAKPOINT_FILE_NOT_FOUND = 1 # :see: ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS = 2 # :see: ADD_BREAKPOINT_LAZY_VALIDATION = 3 # :see: ADD_BREAKPOINT_INVALID_LINE = 4 - __slots__ = ['error_code', 'breakpoint_id', 'translated_filename', 'translated_line', 'original_line'] + __slots__ = ["error_code", "breakpoint_id", "translated_filename", "translated_line", "original_line"] def __init__(self, breakpoint_id, translated_filename, translated_line, original_line): self.error_code = PyDevdAPI.ADD_BREAKPOINT_NO_ERROR @@ -393,9 +413,22 @@ def __init__(self, breakpoint_id, translated_filename, translated_line, original self.original_line = original_line def add_breakpoint( - self, py_db, original_filename, breakpoint_type, breakpoint_id, line, condition, func_name, - expression, suspend_policy, hit_condition, is_logpoint, adjust_line=False, on_changed_breakpoint_state=None): - ''' + self, + py_db, + original_filename, + breakpoint_type, + breakpoint_id, + line, + condition, + func_name, + expression, + suspend_policy, + hit_condition, + is_logpoint, + adjust_line=False, + on_changed_breakpoint_state=None, + ): + """ :param str original_filename: Note: must be sent as it was received in the protocol. It may be translated in this function and its final value will be available in the returned _AddBreakpointResult. @@ -448,30 +481,41 @@ def add_breakpoint( implementation may internally reuse the same instance multiple times). :return _AddBreakpointResult: - ''' - assert original_filename.__class__ == str, 'Expected str, found: %s' % (original_filename.__class__,) # i.e.: bytes on py2 and str on py3 + """ + assert original_filename.__class__ == str, "Expected str, found: %s" % ( + original_filename.__class__, + ) # i.e.: bytes on py2 and str on py3 original_filename_normalized = pydevd_file_utils.normcase_from_client(original_filename) - pydev_log.debug('Request for breakpoint in: %s line: %s', original_filename, line) + pydev_log.debug("Request for breakpoint in: %s line: %s", original_filename, line) original_line = line # Parameters to reapply breakpoint. - api_add_breakpoint_params = (original_filename, breakpoint_type, breakpoint_id, line, condition, func_name, - expression, suspend_policy, hit_condition, is_logpoint) + api_add_breakpoint_params = ( + original_filename, + breakpoint_type, + breakpoint_id, + line, + condition, + func_name, + expression, + suspend_policy, + hit_condition, + is_logpoint, + ) translated_filename = self.filename_to_server(original_filename) # Apply user path mapping. - pydev_log.debug('Breakpoint (after path translation) in: %s line: %s', translated_filename, line) + pydev_log.debug("Breakpoint (after path translation) in: %s line: %s", translated_filename, line) func_name = self.to_str(func_name) assert translated_filename.__class__ == str # i.e.: bytes on py2 and str on py3 assert func_name.__class__ == str # i.e.: bytes on py2 and str on py3 # Apply source mapping (i.e.: ipython). - source_mapped_filename, new_line, multi_mapping_applied = py_db.source_mapping.map_to_server( - translated_filename, line) + source_mapped_filename, new_line, multi_mapping_applied = py_db.source_mapping.map_to_server(translated_filename, line) if multi_mapping_applied: - pydev_log.debug('Breakpoint (after source mapping) in: %s line: %s', source_mapped_filename, new_line) + pydev_log.debug("Breakpoint (after source mapping) in: %s line: %s", source_mapped_filename, new_line) # Note that source mapping is internal and does not change the resulting filename nor line # (we want the outside world to see the line in the original file and not in the ipython # cell, otherwise the editor wouldn't be correct as the returned line is the line to @@ -487,7 +531,7 @@ def add_breakpoint( translated_absolute_filename = pydevd_file_utils.absolute_path(translated_filename) canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path(translated_filename) - if adjust_line and not translated_absolute_filename.startswith('<'): + if adjust_line and not translated_absolute_filename.startswith("<"): # Validate file_to_line_to_breakpoints and adjust their positions. try: lines = sorted(_get_code_lines(translated_absolute_filename)) @@ -502,9 +546,12 @@ def add_breakpoint( result = self._AddBreakpointResult(breakpoint_id, original_filename, line, original_line) - py_db.api_received_breakpoints[(original_filename_normalized, breakpoint_id)] = (canonical_normalized_filename, api_add_breakpoint_params) + py_db.api_received_breakpoints[(original_filename_normalized, breakpoint_id)] = ( + canonical_normalized_filename, + api_add_breakpoint_params, + ) - if not translated_absolute_filename.startswith('<'): + if not translated_absolute_filename.startswith("<"): # Note: if a mapping pointed to a file starting with '<', don't validate. if not pydevd_file_utils.exists(translated_absolute_filename): @@ -512,10 +559,10 @@ def add_breakpoint( return result if ( - py_db.is_files_filter_enabled and - not py_db.get_require_module_for_filters() and - py_db.apply_files_filter(self._DummyFrame(translated_absolute_filename), translated_absolute_filename, False) - ): + py_db.is_files_filter_enabled + and not py_db.get_require_module_for_filters() + and py_db.apply_files_filter(self._DummyFrame(translated_absolute_filename), translated_absolute_filename, False) + ): # Note that if `get_require_module_for_filters()` returns False, we don't do this check. # This is because we don't have the module name given a file at this point (in # runtime it's gotten from the frame.f_globals). @@ -527,9 +574,10 @@ def add_breakpoint( # breakpoint even with the error code. result.error_code = self.ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS - if breakpoint_type == 'python-line': + if breakpoint_type == "python-line": added_breakpoint = LineBreakpoint( - breakpoint_id, line, condition, func_name, expression, suspend_policy, hit_condition=hit_condition, is_logpoint=is_logpoint) + breakpoint_id, line, condition, func_name, expression, suspend_policy, hit_condition=hit_condition, is_logpoint=is_logpoint + ) file_to_line_to_breakpoints = py_db.breakpoints file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint @@ -540,9 +588,20 @@ def add_breakpoint( plugin = py_db.get_plugin_lazy_init() if plugin is not None: add_plugin_breakpoint_result = plugin.add_breakpoint( - 'add_line_breakpoint', py_db, breakpoint_type, canonical_normalized_filename, - breakpoint_id, line, condition, expression, func_name, hit_condition=hit_condition, is_logpoint=is_logpoint, - add_breakpoint_result=result, on_changed_breakpoint_state=on_changed_breakpoint_state) + "add_line_breakpoint", + py_db, + breakpoint_type, + canonical_normalized_filename, + breakpoint_id, + line, + condition, + expression, + func_name, + hit_condition=hit_condition, + is_logpoint=is_logpoint, + add_breakpoint_result=result, + on_changed_breakpoint_state=on_changed_breakpoint_state, + ) if add_plugin_breakpoint_result is not None: supported_type = True @@ -554,7 +613,7 @@ def add_breakpoint( if not supported_type: raise NameError(breakpoint_type) - pydev_log.debug('Added breakpoint:%s - line:%s - func_name:%s\n', canonical_normalized_filename, line, func_name) + pydev_log.debug("Added breakpoint:%s - line:%s - func_name:%s\n", canonical_normalized_filename, line, func_name) if canonical_normalized_filename in file_to_id_to_breakpoint: id_to_pybreakpoint = file_to_id_to_breakpoint[canonical_normalized_filename] @@ -565,45 +624,43 @@ def add_breakpoint( py_db.consolidate_breakpoints(canonical_normalized_filename, id_to_pybreakpoint, file_to_line_to_breakpoints) if py_db.plugin is not None: py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks(py_db) - py_db.plugin.after_breakpoints_consolidated(py_db, canonical_normalized_filename, id_to_pybreakpoint, file_to_line_to_breakpoints) + py_db.plugin.after_breakpoints_consolidated( + py_db, canonical_normalized_filename, id_to_pybreakpoint, file_to_line_to_breakpoints + ) py_db.on_breakpoints_changed() return result def reapply_breakpoints(self, py_db): - ''' + """ Reapplies all the received breakpoints as they were received by the API (so, new translations are applied). - ''' - pydev_log.debug('Reapplying breakpoints.') + """ + pydev_log.debug("Reapplying breakpoints.") values = list(py_db.api_received_breakpoints.values()) # Create a copy with items to reapply. - self.remove_all_breakpoints(py_db, '*') + self.remove_all_breakpoints(py_db, "*") for val in values: _new_filename, api_add_breakpoint_params = val self.add_breakpoint(py_db, *api_add_breakpoint_params) def remove_all_breakpoints(self, py_db, received_filename): - ''' + """ Removes all the breakpoints from a given file or from all files if received_filename == '*'. :param str received_filename: Note: must be sent as it was received in the protocol. It may be translated in this function. - ''' + """ assert received_filename.__class__ == str # i.e.: bytes on py2 and str on py3 changed = False - lst = [ - py_db.file_to_id_to_line_breakpoint, - py_db.file_to_id_to_plugin_breakpoint, - py_db.breakpoints - ] - if hasattr(py_db, 'django_breakpoints'): + lst = [py_db.file_to_id_to_line_breakpoint, py_db.file_to_id_to_plugin_breakpoint, py_db.breakpoints] + if hasattr(py_db, "django_breakpoints"): lst.append(py_db.django_breakpoints) - if hasattr(py_db, 'jinja2_breakpoints'): + if hasattr(py_db, "jinja2_breakpoints"): lst.append(py_db.jinja2_breakpoints) - if received_filename == '*': + if received_filename == "*": py_db.api_received_breakpoints.clear() for file_to_id_to_breakpoint in lst: @@ -633,7 +690,7 @@ def remove_all_breakpoints(self, py_db, received_filename): py_db.on_breakpoints_changed(removed=True) def remove_breakpoint(self, py_db, received_filename, breakpoint_type, breakpoint_id): - ''' + """ :param str received_filename: Note: must be sent as it was received in the protocol. It may be translated in this function. @@ -642,7 +699,7 @@ def remove_breakpoint(self, py_db, received_filename, breakpoint_type, breakpoin One of: 'python-line', 'django-line', 'jinja2-line'. :param int breakpoint_id: - ''' + """ received_filename_normalized = pydevd_file_utils.normcase_from_client(received_filename) for key, val in list(py_db.api_received_breakpoints.items()): original_filename_normalized, existing_breakpoint_id = key @@ -651,14 +708,13 @@ def remove_breakpoint(self, py_db, received_filename, breakpoint_type, breakpoin del py_db.api_received_breakpoints[key] break else: - pydev_log.info( - 'Did not find breakpoint to remove: %s (breakpoint id: %s)', received_filename, breakpoint_id) + pydev_log.info("Did not find breakpoint to remove: %s (breakpoint id: %s)", received_filename, breakpoint_id) file_to_id_to_breakpoint = None received_filename = self.filename_to_server(received_filename) canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path(received_filename) - if breakpoint_type == 'python-line': + if breakpoint_type == "python-line": file_to_line_to_breakpoints = py_db.breakpoints file_to_id_to_breakpoint = py_db.file_to_id_to_line_breakpoint @@ -669,25 +725,33 @@ def remove_breakpoint(self, py_db, received_filename, breakpoint_type, breakpoin file_to_line_to_breakpoints = result if file_to_id_to_breakpoint is None: - pydev_log.critical('Error removing breakpoint. Cannot handle breakpoint of type %s', breakpoint_type) + pydev_log.critical("Error removing breakpoint. Cannot handle breakpoint of type %s", breakpoint_type) else: try: id_to_pybreakpoint = file_to_id_to_breakpoint.get(canonical_normalized_filename, {}) if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: existing = id_to_pybreakpoint[breakpoint_id] - pydev_log.info('Removed breakpoint:%s - line:%s - func_name:%s (id: %s)\n' % ( - canonical_normalized_filename, existing.line, existing.func_name, breakpoint_id)) + pydev_log.info( + "Removed breakpoint:%s - line:%s - func_name:%s (id: %s)\n" + % (canonical_normalized_filename, existing.line, existing.func_name, breakpoint_id) + ) del id_to_pybreakpoint[breakpoint_id] py_db.consolidate_breakpoints(canonical_normalized_filename, id_to_pybreakpoint, file_to_line_to_breakpoints) if py_db.plugin is not None: py_db.has_plugin_line_breaks = py_db.plugin.has_line_breaks(py_db) - py_db.plugin.after_breakpoints_consolidated(py_db, canonical_normalized_filename, id_to_pybreakpoint, file_to_line_to_breakpoints) + py_db.plugin.after_breakpoints_consolidated( + py_db, canonical_normalized_filename, id_to_pybreakpoint, file_to_line_to_breakpoints + ) except KeyError: - pydev_log.info("Error removing breakpoint: Breakpoint id not found: %s id: %s. Available ids: %s\n", - canonical_normalized_filename, breakpoint_id, list(id_to_pybreakpoint)) + pydev_log.info( + "Error removing breakpoint: Breakpoint id not found: %s id: %s. Available ids: %s\n", + canonical_normalized_filename, + breakpoint_id, + list(id_to_pybreakpoint), + ) py_db.on_breakpoints_changed(removed=True) @@ -699,31 +763,27 @@ def set_function_breakpoints(self, py_db, function_breakpoints): py_db.function_breakpoint_name_to_breakpoint = function_breakpoint_name_to_breakpoint py_db.on_breakpoints_changed() - def request_exec_or_evaluate( - self, py_db, seq, thread_id, frame_id, expression, is_exec, trim_if_too_big, attr_to_set_result): + def request_exec_or_evaluate(self, py_db, seq, thread_id, frame_id, expression, is_exec, trim_if_too_big, attr_to_set_result): py_db.post_method_as_internal_command( - thread_id, internal_evaluate_expression, - seq, thread_id, frame_id, expression, is_exec, trim_if_too_big, attr_to_set_result) + thread_id, internal_evaluate_expression, seq, thread_id, frame_id, expression, is_exec, trim_if_too_big, attr_to_set_result + ) - def request_exec_or_evaluate_json( - self, py_db, request, thread_id): - py_db.post_method_as_internal_command( - thread_id, internal_evaluate_expression_json, request, thread_id) + def request_exec_or_evaluate_json(self, py_db, request, thread_id): + py_db.post_method_as_internal_command(thread_id, internal_evaluate_expression_json, request, thread_id) def request_set_expression_json(self, py_db, request, thread_id): - py_db.post_method_as_internal_command( - thread_id, internal_set_expression_json, request, thread_id) + py_db.post_method_as_internal_command(thread_id, internal_set_expression_json, request, thread_id) def request_console_exec(self, py_db, seq, thread_id, frame_id, expression): int_cmd = InternalConsoleExec(seq, thread_id, frame_id, expression) py_db.post_internal_command(int_cmd, thread_id) def request_load_source(self, py_db, seq, filename): - ''' + """ :param str filename: Note: must be sent as it was received in the protocol. It may be translated in this function. - ''' + """ try: filename = self.filename_to_server(filename) assert filename.__class__ == str # i.e.: bytes on py2 and str on py3 @@ -737,13 +797,13 @@ def request_load_source(self, py_db, seq, filename): py_db.writer.add_command(cmd) def get_decompiled_source_from_frame_id(self, py_db, frame_id): - ''' + """ :param py_db: :param frame_id: :throws Exception: If unable to get the frame in the currently paused frames or if some error happened when decompiling. - ''' + """ variable = py_db.suspended_frames_manager.get_variable(int(frame_id)) frame = variable.value @@ -751,7 +811,7 @@ def get_decompiled_source_from_frame_id(self, py_db, frame_id): lines = (linecache.getline(frame.f_code.co_filename, i) for i in itertools.count(1)) lines = itertools.takewhile(bool, lines) # empty lines are '\n', EOF is '' - source = ''.join(lines) + source = "".join(lines) if not source: source = code_to_bytecode_representation(frame.f_code) @@ -767,17 +827,17 @@ def request_load_source_from_frame_id(self, py_db, seq, frame_id): py_db.writer.add_command(cmd) def add_python_exception_breakpoint( - self, - py_db, - exception, - condition, - expression, - notify_on_handled_exceptions, - notify_on_unhandled_exceptions, - notify_on_user_unhandled_exceptions, - notify_on_first_raise_only, - ignore_libraries, - ): + self, + py_db, + exception, + condition, + expression, + notify_on_handled_exceptions, + notify_on_unhandled_exceptions, + notify_on_user_unhandled_exceptions, + notify_on_first_raise_only, + ignore_libraries, + ): exception_breakpoint = py_db.add_break_on_exception( exception, condition=condition, @@ -796,7 +856,7 @@ def add_plugins_exception_breakpoint(self, py_db, breakpoint_type, exception): supported_type = False plugin = py_db.get_plugin_lazy_init() if plugin is not None: - supported_type = plugin.add_breakpoint('add_exception_breakpoint', py_db, breakpoint_type, exception) + supported_type = plugin.add_breakpoint("add_exception_breakpoint", py_db, breakpoint_type, exception) if supported_type: py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks(py_db) @@ -834,7 +894,7 @@ def remove_plugins_exception_breakpoint(self, py_db, exception_type, exception): if supported_type: py_db.has_plugin_exception_breaks = py_db.plugin.has_exception_breaks(py_db) else: - pydev_log.info('No exception of type: %s was previously registered.', exception_type) + pydev_log.info("No exception of type: %s was previously registered.", exception_type) py_db.on_breakpoints_changed(removed=True) @@ -849,9 +909,9 @@ def remove_all_exception_breakpoints(self, py_db): py_db.on_breakpoints_changed(removed=True) def set_project_roots(self, py_db, project_roots): - ''' + """ :param str project_roots: - ''' + """ py_db.set_project_roots(project_roots) def set_stepping_resumes_all_threads(self, py_db, stepping_resumes_all_threads): @@ -861,27 +921,25 @@ def set_stepping_resumes_all_threads(self, py_db, stepping_resumes_all_threads): from _pydevd_bundle.pydevd_filtering import ExcludeFilter # noqa def set_exclude_filters(self, py_db, exclude_filters): - ''' + """ :param list(PyDevdAPI.ExcludeFilter) exclude_filters: - ''' + """ py_db.set_exclude_filters(exclude_filters) def set_use_libraries_filter(self, py_db, use_libraries_filter): py_db.set_use_libraries_filter(use_libraries_filter) def request_get_variable_json(self, py_db, request, thread_id): - ''' + """ :param VariablesRequest request: - ''' - py_db.post_method_as_internal_command( - thread_id, internal_get_variable_json, request) + """ + py_db.post_method_as_internal_command(thread_id, internal_get_variable_json, request) def request_change_variable_json(self, py_db, request, thread_id): - ''' + """ :param SetVariableRequest request: - ''' - py_db.post_method_as_internal_command( - thread_id, internal_change_variable_json, request) + """ + py_db.post_method_as_internal_command(thread_id, internal_change_variable_json, request) def set_dont_trace_start_end_patterns(self, py_db, start_patterns, end_patterns): # Note: start/end patterns normalized internally. @@ -891,8 +949,7 @@ def set_dont_trace_start_end_patterns(self, py_db, start_patterns, end_patterns) # After it's set the first time, we can still change it, but we need to reset the # related caches. reset_caches = False - dont_trace_start_end_patterns_previously_set = \ - py_db.dont_trace_external_files.__name__ == 'custom_dont_trace_external_files' + dont_trace_start_end_patterns_previously_set = py_db.dont_trace_external_files.__name__ == "custom_dont_trace_external_files" if not dont_trace_start_end_patterns_previously_set and not start_patterns and not end_patterns: # If it wasn't set previously and start and end patterns are empty we don't need to do anything. @@ -901,8 +958,10 @@ def set_dont_trace_start_end_patterns(self, py_db, start_patterns, end_patterns) if not py_db.is_cache_file_type_empty(): # i.e.: custom function set in set_dont_trace_start_end_patterns. if dont_trace_start_end_patterns_previously_set: - reset_caches = py_db.dont_trace_external_files.start_patterns != start_patterns or \ - py_db.dont_trace_external_files.end_patterns != end_patterns + reset_caches = ( + py_db.dont_trace_external_files.start_patterns != start_patterns + or py_db.dont_trace_external_files.end_patterns != end_patterns + ) else: reset_caches = True @@ -921,7 +980,7 @@ def custom_dont_trace_external_files(abs_path): def stop_on_entry(self): main_thread = pydevd_utils.get_main_thread() if main_thread is None: - pydev_log.critical('Could not find main thread while setting Stop on Entry.') + pydev_log.critical("Could not find main thread while setting Stop on Entry.") else: info = set_additional_thread_info(main_thread) info.pydev_original_step_cmd = CMD_STOP_ON_START @@ -937,7 +996,7 @@ def set_ignore_system_exit_codes(self, py_db, ignore_system_exit_codes): SourceMappingEntry = pydevd_source_mapping.SourceMappingEntry def set_source_mapping(self, py_db, source_filename, mapping): - ''' + """ :param str source_filename: The filename for the source mapping (bytes on py2 and str on py3). This filename will be made absolute in this function. @@ -948,7 +1007,7 @@ def set_source_mapping(self, py_db, source_filename, mapping): :return str: An error message if it was not possible to set the mapping or an empty string if everything is ok. - ''' + """ source_filename = self.filename_to_server(source_filename) absolute_source_filename = pydevd_file_utils.absolute_path(source_filename) for map_entry in mapping: @@ -958,16 +1017,16 @@ def set_source_mapping(self, py_db, source_filename, mapping): return error_msg self.reapply_breakpoints(py_db) - return '' + return "" def set_variable_presentation(self, py_db, variable_presentation): assert isinstance(variable_presentation, self.VariablePresentation) py_db.variable_presentation = variable_presentation def get_ppid(self): - ''' + """ Provides the parent pid (even for older versions of Python on Windows). - ''' + """ ppid = None try: @@ -991,7 +1050,6 @@ def _get_windows_ppid(self): def _terminate_child_processes_windows(self, dont_terminate_child_pids): this_pid = os.getpid() for _ in range(50): # Try this at most 50 times before giving up. - # Note: we can't kill the process itself with taskkill, so, we # list immediate children, kill that tree and then exit this process. @@ -1005,11 +1063,7 @@ def _terminate_child_processes_windows(self, dont_terminate_child_pids): break else: for pid in children_pids: - self._call( - ['taskkill', '/F', '/PID', str(pid), '/T'], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) + self._call(["taskkill", "/F", "/PID", str(pid), "/T"], stdout=subprocess.PIPE, stderr=subprocess.PIPE) del children_pids[:] @@ -1020,22 +1074,14 @@ def list_children_and_stop_forking(initial_pid, stop=True): children_pids = [] if stop: # Ask to stop forking (shouldn't be called for this process, only subprocesses). - self._call( - ['kill', '-STOP', str(initial_pid)], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) + self._call(["kill", "-STOP", str(initial_pid)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) - list_popen = self._popen( - ['pgrep', '-P', str(initial_pid)], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) + list_popen = self._popen(["pgrep", "-P", str(initial_pid)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if list_popen is not None: stdout, _ = list_popen.communicate() for line in stdout.splitlines(): - line = line.decode('ascii').strip() + line = line.decode("ascii").strip() if line: pid = str(line) if pid in dont_terminate_child_pids: @@ -1048,7 +1094,6 @@ def list_children_and_stop_forking(initial_pid, stop=True): previously_found = set() for _ in range(50): # Try this at most 50 times before giving up. - children_pids = list_children_and_stop_forking(this_pid, stop=False) found_new = False @@ -1056,11 +1101,7 @@ def list_children_and_stop_forking(initial_pid, stop=True): if pid not in previously_found: found_new = True previously_found.add(pid) - self._call( - ['kill', '-KILL', str(pid)], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE - ) + self._call(["kill", "-KILL", str(pid)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if not found_new: break @@ -1070,7 +1111,7 @@ def _popen(self, cmdline, **kwargs): return subprocess.Popen(cmdline, **kwargs) except: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: - pydev_log.exception('Error running: %s' % (' '.join(cmdline))) + pydev_log.exception("Error running: %s" % (" ".join(cmdline))) return None def _call(self, cmdline, **kwargs): @@ -1078,7 +1119,7 @@ def _call(self, cmdline, **kwargs): subprocess.check_call(cmdline, **kwargs) except: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: - pydev_log.exception('Error running: %s' % (' '.join(cmdline))) + pydev_log.exception("Error running: %s" % (" ".join(cmdline))) def set_terminate_child_processes(self, py_db, terminate_child_processes): py_db.terminate_child_processes = terminate_child_processes @@ -1087,19 +1128,19 @@ def set_terminate_keyboard_interrupt(self, py_db, terminate_keyboard_interrupt): py_db.terminate_keyboard_interrupt = terminate_keyboard_interrupt def terminate_process(self, py_db): - ''' + """ Terminates the current process (and child processes if the option to also terminate child processes is enabled). - ''' + """ try: if py_db.terminate_child_processes: - pydev_log.debug('Terminating child processes.') + pydev_log.debug("Terminating child processes.") if IS_WINDOWS: self._terminate_child_processes_windows(py_db.dont_terminate_child_pids) else: self._terminate_child_processes_linux_and_mac(py_db.dont_terminate_child_pids) finally: - pydev_log.debug('Exiting process (os._exit(0)).') + pydev_log.debug("Exiting process (os._exit(0)).") os._exit(0) def _terminate_if_commands_processed(self, py_db): @@ -1126,16 +1167,18 @@ def _list_ppid_and_pid(): _TH32CS_SNAPPROCESS = 0x00000002 class PROCESSENTRY32(ctypes.Structure): - _fields_ = [("dwSize", ctypes.c_uint32), - ("cntUsage", ctypes.c_uint32), - ("th32ProcessID", ctypes.c_uint32), - ("th32DefaultHeapID", ctypes.c_size_t), - ("th32ModuleID", ctypes.c_uint32), - ("cntThreads", ctypes.c_uint32), - ("th32ParentProcessID", ctypes.c_uint32), - ("pcPriClassBase", ctypes.c_long), - ("dwFlags", ctypes.c_uint32), - ("szExeFile", ctypes.c_char * 260)] + _fields_ = [ + ("dwSize", ctypes.c_uint32), + ("cntUsage", ctypes.c_uint32), + ("th32ProcessID", ctypes.c_uint32), + ("th32DefaultHeapID", ctypes.c_size_t), + ("th32ModuleID", ctypes.c_uint32), + ("cntThreads", ctypes.c_uint32), + ("th32ParentProcessID", ctypes.c_uint32), + ("pcPriClassBase", ctypes.c_long), + ("dwFlags", ctypes.c_uint32), + ("szExeFile", ctypes.c_char * 260), + ] kernel32 = ctypes.windll.kernel32 snapshot = kernel32.CreateToolhelp32Snapshot(_TH32CS_SNAPPROCESS, 0) @@ -1144,7 +1187,7 @@ class PROCESSENTRY32(ctypes.Structure): process_entry = PROCESSENTRY32() process_entry.dwSize = ctypes.sizeof(PROCESSENTRY32) if not kernel32.Process32First(ctypes.c_void_p(snapshot), ctypes.byref(process_entry)): - pydev_log.critical('Process32First failed (getting process from CreateToolhelp32Snapshot).') + pydev_log.critical("Process32First failed (getting process from CreateToolhelp32Snapshot).") else: while True: ppid_and_pids.append((process_entry.th32ParentProcessID, process_entry.th32ProcessID)) diff --git a/_pydevd_bundle/pydevd_breakpoints.py b/_pydevd_bundle/pydevd_breakpoints.py index d92fccf52..7d4d02202 100644 --- a/_pydevd_bundle/pydevd_breakpoints.py +++ b/_pydevd_bundle/pydevd_breakpoints.py @@ -5,7 +5,6 @@ class ExceptionBreakpoint(object): - def __init__( self, qname, @@ -15,8 +14,8 @@ def __init__( notify_on_unhandled_exceptions, notify_on_user_unhandled_exceptions, notify_on_first_raise_only, - ignore_libraries - ): + ignore_libraries, + ): exctype = get_exception_class(qname) self.qname = qname if exctype is not None: @@ -46,7 +45,6 @@ def handle_hit_condition(self, frame): class LineBreakpoint(object): - def __init__(self, breakpoint_id, line, condition, func_name, expression, suspend_policy="NONE", hit_condition=None, is_logpoint=False): self.breakpoint_id = breakpoint_id self.line = line @@ -69,7 +67,7 @@ def handle_hit_condition(self, frame): ret = False with self._hit_condition_lock: self._hit_count += 1 - expr = self.hit_condition.replace('@HIT@', str(self._hit_count)) + expr = self.hit_condition.replace("@HIT@", str(self._hit_count)) try: ret = bool(eval(expr, frame.f_globals, frame.f_locals)) except Exception: @@ -78,7 +76,6 @@ def handle_hit_condition(self, frame): class FunctionBreakpoint(object): - def __init__(self, func_name, condition, expression, suspend_policy="NONE", hit_condition=None, is_logpoint=False): self.condition = condition self.func_name = func_name @@ -99,7 +96,7 @@ def handle_hit_condition(self, frame): ret = False with self._hit_condition_lock: self._hit_count += 1 - expr = self.hit_condition.replace('@HIT@', str(self._hit_count)) + expr = self.hit_condition.replace("@HIT@", str(self._hit_count)) try: ret = bool(eval(expr, frame.f_globals, frame.f_locals)) except Exception: @@ -111,7 +108,7 @@ def get_exception_breakpoint(exctype, exceptions): if not exctype: exception_full_qname = None else: - exception_full_qname = str(exctype.__module__) + '.' + exctype.__name__ + exception_full_qname = str(exctype.__module__) + "." + exctype.__name__ exc = None if exceptions is not None: @@ -170,9 +167,9 @@ def stop_on_unhandled_exception(py_db, thread, additional_info, arg): try: additional_info.pydev_message = exception_breakpoint.qname except: - additional_info.pydev_message = exception_breakpoint.qname.encode('utf-8') + additional_info.pydev_message = exception_breakpoint.qname.encode("utf-8") - pydev_log.debug('Handling post-mortem stop on exception breakpoint %s' % (exception_breakpoint.qname,)) + pydev_log.debug("Handling post-mortem stop on exception breakpoint %s" % (exception_breakpoint.qname,)) py_db.do_stop_on_unhandled_exception(thread, user_frame, frames_byid, arg) diff --git a/_pydevd_bundle/pydevd_bytecode_utils.py b/_pydevd_bundle/pydevd_bytecode_utils.py index 0d2ef79f1..8a470444a 100644 --- a/_pydevd_bundle/pydevd_bytecode_utils.py +++ b/_pydevd_bundle/pydevd_bytecode_utils.py @@ -24,44 +24,52 @@ DEBUG = False -_BINARY_OPS = set([opname for opname in dis.opname if opname.startswith('BINARY_')]) +_BINARY_OPS = set([opname for opname in dis.opname if opname.startswith("BINARY_")]) _BINARY_OP_MAP = { - 'BINARY_POWER': '__pow__', - 'BINARY_MULTIPLY': '__mul__', - 'BINARY_MATRIX_MULTIPLY': '__matmul__', - 'BINARY_FLOOR_DIVIDE': '__floordiv__', - 'BINARY_TRUE_DIVIDE': '__div__', - 'BINARY_MODULO': '__mod__', - 'BINARY_ADD': '__add__', - 'BINARY_SUBTRACT': '__sub__', - 'BINARY_LSHIFT': '__lshift__', - 'BINARY_RSHIFT': '__rshift__', - 'BINARY_AND': '__and__', - 'BINARY_OR': '__or__', - 'BINARY_XOR': '__xor__', - 'BINARY_SUBSCR': '__getitem__', - 'BINARY_DIVIDE': '__div__' + "BINARY_POWER": "__pow__", + "BINARY_MULTIPLY": "__mul__", + "BINARY_MATRIX_MULTIPLY": "__matmul__", + "BINARY_FLOOR_DIVIDE": "__floordiv__", + "BINARY_TRUE_DIVIDE": "__div__", + "BINARY_MODULO": "__mod__", + "BINARY_ADD": "__add__", + "BINARY_SUBTRACT": "__sub__", + "BINARY_LSHIFT": "__lshift__", + "BINARY_RSHIFT": "__rshift__", + "BINARY_AND": "__and__", + "BINARY_OR": "__or__", + "BINARY_XOR": "__xor__", + "BINARY_SUBSCR": "__getitem__", + "BINARY_DIVIDE": "__div__", } _COMP_OP_MAP = { - '<': '__lt__', - '<=': '__le__', - '==': '__eq__', - '!=': '__ne__', - '>': '__gt__', - '>=': '__ge__', - 'in': '__contains__', - 'not in': '__contains__', + "<": "__lt__", + "<=": "__le__", + "==": "__eq__", + "!=": "__ne__", + ">": "__gt__", + ">=": "__ge__", + "in": "__contains__", + "not in": "__contains__", } class Target(object): - __slots__ = ['arg', 'lineno', 'endlineno', 'startcol', 'endcol', 'offset', 'children_targets'] - - def __init__(self, arg, lineno, offset, children_targets=(), + __slots__ = ["arg", "lineno", "endlineno", "startcol", "endcol", "offset", "children_targets"] + + def __init__( + self, + arg, + lineno, + offset, + children_targets=(), # These are optional (only Python 3.11 onwards). - endlineno=-1, startcol=-1, endcol=-1): + endlineno=-1, + startcol=-1, + endcol=-1, + ): self.arg = arg self.lineno = lineno self.endlineno = endlineno @@ -74,19 +82,18 @@ def __init__(self, arg, lineno, offset, children_targets=(), def __repr__(self): ret = [] for s in self.__slots__: - ret.append('%s: %s' % (s, getattr(self, s))) - return 'Target(%s)' % ', '.join(ret) + ret.append("%s: %s" % (s, getattr(self, s))) + return "Target(%s)" % ", ".join(ret) __str__ = __repr__ class _TargetIdHashable(object): - def __init__(self, target): self.target = target def __eq__(self, other): - if not hasattr(other, 'target'): + if not hasattr(other, "target"): return return other.target is self.target @@ -98,9 +105,9 @@ def __hash__(self): class _StackInterpreter(object): - ''' + """ Good reference: https://github.com/python/cpython/blob/fcb55c0037baab6f98f91ee38ce84b6f874f034a/Python/ceval.c - ''' + """ def __init__(self, bytecode): self.bytecode = bytecode @@ -111,28 +118,28 @@ def __init__(self, bytecode): self.func_name_id_to_code_object = {} def __str__(self): - return 'Stack:\nFunction calls:\n%s\nLoad attrs:\n%s\n' % (self.function_calls, list(self.load_attrs.values())) + return "Stack:\nFunction calls:\n%s\nLoad attrs:\n%s\n" % (self.function_calls, list(self.load_attrs.values())) def _getname(self, instr): if instr.opcode in _opcode.hascompare: cmp_op = dis.cmp_op[instr.arg] - if cmp_op not in ('exception match', 'BAD'): + if cmp_op not in ("exception match", "BAD"): return _COMP_OP_MAP.get(cmp_op, cmp_op) return instr.arg def _getcallname(self, instr): - if instr.name == 'BINARY_SUBSCR': - return '__getitem__().__call__' - if instr.name == 'CALL_FUNCTION': + if instr.name == "BINARY_SUBSCR": + return "__getitem__().__call__" + if instr.name == "CALL_FUNCTION": # Note: previously a '__call__().__call__' was returned, but this was a bit weird # and on Python 3.9 this construct could appear for some internal things where # it wouldn't be expected. # Note: it'd be what we had in func()(). return None - if instr.name == 'MAKE_FUNCTION': - return '__func__().__call__' - if instr.name == 'LOAD_ASSERTION_ERROR': - return 'AssertionError' + if instr.name == "MAKE_FUNCTION": + return "__func__().__call__" + if instr.name == "LOAD_ASSERTION_ERROR": + return "AssertionError" name = self._getname(instr) if isinstance(name, CodeType): name = name.co_qualname # Note: only available for Python 3.11 @@ -145,8 +152,8 @@ def _getcallname(self, instr): if not isinstance(name, str): return None - if name.endswith('>'): # xxx., xxx., ... - return name.split('.')[-1] + if name.endswith(">"): # xxx., xxx., ... + return name.split(".")[-1] return name def _no_stack_change(self, instr): @@ -216,7 +223,7 @@ def _handle_call_from_instr(self, func_name_instr, func_call_instr): target = None if not call_name: pass # Ignore if we can't identify a name - elif call_name in ('', '', '', ''): + elif call_name in ("", "", "", ""): code_obj = self.func_name_id_to_code_object[_TargetIdHashable(func_name_instr)] if code_obj is not None and GO_INTO_INNER_CODES: children_targets = _get_smart_step_into_targets(code_obj) @@ -225,8 +232,7 @@ def _handle_call_from_instr(self, func_name_instr, func_call_instr): # Note that to actually match this in the debugger we need to do matches on 2 frames, # the one with the and then the actual target inside the . target = Target(call_name, func_name_instr.lineno, func_call_instr.offset, children_targets) - self.function_calls.append( - target) + self.function_calls.append(target) else: # Ok, regular call @@ -234,7 +240,7 @@ def _handle_call_from_instr(self, func_name_instr, func_call_instr): self.function_calls.append(target) if DEBUG and target is not None: - print('Created target', target) + print("Created target", target) self._stack.append(func_call_instr) # Keep the func call as the result def on_COMPARE_OP(self, instr): @@ -248,7 +254,7 @@ def on_COMPARE_OP(self, instr): return cmp_op = dis.cmp_op[instr.arg] - if cmp_op not in ('exception match', 'BAD'): + if cmp_op not in ("exception match", "BAD"): self.function_calls.append(Target(self._getname(instr), instr.lineno, instr.offset)) self._stack.append(instr) @@ -313,7 +319,7 @@ def on_MAKE_FUNCTION(self, instr): _func_defaults = self._stack.pop() call_name = self._getcallname(qualname) - if call_name in ('', '', '', ''): + if call_name in ("", "", "", ""): if isinstance(code_obj_instr.arg, CodeType): self.func_name_id_to_code_object[_TargetIdHashable(qualname)] = code_obj_instr.arg self._stack.append(qualname) @@ -348,7 +354,7 @@ def on_CALL(self, instr): if self._stack: peeked = self._stack[-1] - if peeked.name == 'PUSH_NULL': + if peeked.name == "PUSH_NULL": self._stack.pop() self._handle_call_from_instr(func_name_instr, instr) @@ -361,7 +367,7 @@ def on_CALL_INTRINSIC_1(self, instr): if self._stack: peeked = self._stack[-1] - if peeked.name == 'PUSH_NULL': + if peeked.name == "PUSH_NULL": self._stack.pop() self._handle_call_from_instr(func_name_instr, instr) @@ -378,8 +384,8 @@ def on_RETURN_CONST(self, instr): def on_CALL_FUNCTION(self, instr): arg = instr.arg - argc = arg & 0xff # positional args - argc += ((arg >> 8) * 2) # keyword args + argc = arg & 0xFF # positional args + argc += (arg >> 8) * 2 # keyword args # pop the actual args for _ in range(argc): @@ -401,8 +407,8 @@ def on_CALL_FUNCTION_KW(self, instr): # pop the actual args arg = instr.arg - argc = arg & 0xff # positional args - argc += ((arg >> 8) * 2) # keyword args + argc = arg & 0xFF # positional args + argc += (arg >> 8) * 2 # keyword args for _ in range(argc): self._stack.pop() @@ -417,8 +423,8 @@ def on_CALL_FUNCTION_VAR(self, instr): # pop the actual args arg = instr.arg - argc = arg & 0xff # positional args - argc += ((arg >> 8) * 2) # keyword args + argc = arg & 0xFF # positional args + argc += (arg >> 8) * 2 # keyword args for _ in range(argc): self._stack.pop() @@ -432,8 +438,8 @@ def on_CALL_FUNCTION_VAR_KW(self, instr): arg = instr.arg - argc = arg & 0xff # positional args - argc += ((arg >> 8) * 2) # keyword args + argc = arg & 0xFF # positional args + argc += (arg >> 8) * 2 # keyword args # also pop **kwargs self._stack.pop() @@ -734,9 +740,9 @@ def on_DELETE_SUBSCR(self, instr): def _get_smart_step_into_targets(code): - ''' + """ :return list(Target) - ''' + """ b = bytecode.Bytecode.from_code(code) cfg = bytecode_cfg.ControlFlowGraph.from_bytecode(b) @@ -744,39 +750,39 @@ def _get_smart_step_into_targets(code): for block in cfg: if DEBUG: - print('\nStart block----') + print("\nStart block----") stack = _StackInterpreter(block) for instr in block: if isinstance(instr, (Label,)): # No name for these continue try: - func_name = 'on_%s' % (instr.name,) + func_name = "on_%s" % (instr.name,) func = getattr(stack, func_name, None) if func is None: if STRICT_MODE: - raise AssertionError('%s not found.' % (func_name,)) + raise AssertionError("%s not found." % (func_name,)) else: if DEBUG: - print('Skipping: %s.' % (func_name,)) + print("Skipping: %s." % (func_name,)) continue func(instr) if DEBUG: - if instr.name != 'CACHE': # Filter the ones we don't want to see. - print('\nHandled: ', instr, '>>', stack._getname(instr), '<<') - print('New stack:') + if instr.name != "CACHE": # Filter the ones we don't want to see. + print("\nHandled: ", instr, ">>", stack._getname(instr), "<<") + print("New stack:") for entry in stack._stack: - print(' arg:', stack._getname(entry), '(', entry, ')') + print(" arg:", stack._getname(entry), "(", entry, ")") except: if STRICT_MODE: raise # Error in strict mode. else: # In non-strict mode, log it (if in verbose mode) and keep on going. if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 2: - pydev_log.exception('Exception computing step into targets (handled).') + pydev_log.exception("Exception computing step into targets (handled).") ret.extend(stack.function_calls) # No longer considering attr loads as calls (while in theory sometimes it's possible @@ -786,7 +792,7 @@ def _get_smart_step_into_targets(code): # ret.extend(stack.load_attrs.values()) if DEBUG: - print('\nEnd block----') + print("\nEnd block----") return ret @@ -795,7 +801,7 @@ def _get_smart_step_into_targets(code): # to inspect the parent frame for frame.f_lasti to know where we actually are (as the # caller name may not always match the new frame name). class Variant(object): - __slots__ = ['name', 'is_visited', 'line', 'offset', 'call_order', 'children_variants', 'parent', 'endlineno', 'startcol', 'endcol'] + __slots__ = ["name", "is_visited", "line", "offset", "call_order", "children_variants", "parent", "endlineno", "startcol", "endcol"] def __init__(self, name, is_visited, line, offset, call_order, children_variants=None, endlineno=-1, startcol=-1, endcol=-1): self.name = name @@ -815,32 +821,32 @@ def __init__(self, name, is_visited, line, offset, call_order, children_variants def __repr__(self): ret = [] for s in self.__slots__: - if s == 'parent': + if s == "parent": try: parent = self.parent except AttributeError: - ret.append('%s: ' % (s,)) + ret.append("%s: " % (s,)) else: if parent is None: - ret.append('parent: None') + ret.append("parent: None") else: - ret.append('parent: %s (%s)' % (parent.name, parent.offset)) + ret.append("parent: %s (%s)" % (parent.name, parent.offset)) continue - if s == 'children_variants': - ret.append('children_variants: %s' % (len(self.children_variants) if self.children_variants else 0)) + if s == "children_variants": + ret.append("children_variants: %s" % (len(self.children_variants) if self.children_variants else 0)) continue try: - ret.append('%s= %s' % (s, getattr(self, s))) + ret.append("%s= %s" % (s, getattr(self, s))) except AttributeError: - ret.append('%s: ' % (s,)) - return 'Variant(%s)' % ', '.join(ret) + ret.append("%s: " % (s,)) + return "Variant(%s)" % ", ".join(ret) __str__ = __repr__ -def _convert_target_to_variant(target, start_line, end_line, call_order_cache: dict, lasti:int, base:int): +def _convert_target_to_variant(target, start_line, end_line, call_order_cache: dict, lasti: int, base: int): name = target.arg if not isinstance(name, str): return @@ -857,8 +863,8 @@ def _convert_target_to_variant(target, start_line, end_line, call_order_cache: d children_variants = None if children_targets: children_variants = [ - _convert_target_to_variant(child, start_line, end_line, call_order_cache, lasti, base) - for child in target.children_targets] + _convert_target_to_variant(child, start_line, end_line, call_order_cache, lasti, base) for child in target.children_targets + ] return Variant( name, @@ -887,6 +893,7 @@ def calculate_smart_step_into_variants(frame, start_line, end_line, base=0): """ if IS_PY311_OR_GREATER: from . import pydevd_bytecode_utils_py311 + return pydevd_bytecode_utils_py311.calculate_smart_step_into_variants(frame, start_line, end_line, base) variants = [] @@ -895,7 +902,7 @@ def calculate_smart_step_into_variants(frame, start_line, end_line, base=0): call_order_cache = {} if DEBUG: - print('dis.dis:') + print("dis.dis:") if IS_PY311_OR_GREATER: dis.dis(code, show_caches=False) else: @@ -922,7 +929,7 @@ def get_smart_step_into_variant_from_frame_offset(frame_f_lasti, variants): if not variants: return None - i = bisect(KeyifyList(variants, lambda entry:entry.offset), frame_f_lasti) + i = bisect(KeyifyList(variants, lambda entry: entry.offset), frame_f_lasti) if i == 0: return None diff --git a/_pydevd_bundle/pydevd_bytecode_utils_py311.py b/_pydevd_bundle/pydevd_bytecode_utils_py311.py index f71572343..7ebaa7fb3 100644 --- a/_pydevd_bundle/pydevd_bytecode_utils_py311.py +++ b/_pydevd_bundle/pydevd_bytecode_utils_py311.py @@ -2,16 +2,14 @@ import dis from types import CodeType from collections import namedtuple + DEBUG = False -_Pos = namedtuple('_Pos', 'lineno endlineno startcol endcol') +_Pos = namedtuple("_Pos", "lineno endlineno startcol endcol") -def _is_inside(item_pos:_Pos, container_pos: _Pos): - if ( - item_pos.lineno < container_pos.lineno - or item_pos.endlineno > container_pos.endlineno - ): +def _is_inside(item_pos: _Pos, container_pos: _Pos): + if item_pos.lineno < container_pos.lineno or item_pos.endlineno > container_pos.endlineno: return False if item_pos.lineno == container_pos.lineno: @@ -35,11 +33,11 @@ def _get_smart_step_into_targets(code): targets_root = [] children = [] for instr in dis.Bytecode(code): - if instr.opname == 'LOAD_CONST': + if instr.opname == "LOAD_CONST": if isinstance(instr.argval, CodeType): children.append(_get_smart_step_into_targets(instr.argval)) - elif instr.opname in ('CALL', 'CALL_INTRINSIC_1'): + elif instr.opname in ("CALL", "CALL_INTRINSIC_1"): positions = instr.positions if positions.lineno is None: continue @@ -59,24 +57,14 @@ def _get_smart_step_into_targets(code): lines[-1] = lines[-1][:endcol] pos = _Pos(positions.lineno, positions.end_lineno, startcol, endcol) - targets_root.append(Target(''.join(lines), positions.lineno, instr.offset, [], positions.end_lineno, startcol, endcol)) + targets_root.append(Target("".join(lines), positions.lineno, instr.offset, [], positions.end_lineno, startcol, endcol)) for targets in children: for child_target in targets: - pos = _Pos( - child_target.lineno, - child_target.endlineno, - child_target.startcol, - child_target.endcol - ) + pos = _Pos(child_target.lineno, child_target.endlineno, child_target.startcol, child_target.endcol) for outer_target in targets_root: - outer_pos = _Pos( - outer_target.lineno, - outer_target.endlineno, - outer_target.startcol, - outer_target.endcol - ) + outer_pos = _Pos(outer_target.lineno, outer_target.endlineno, outer_target.startcol, outer_target.endcol) if _is_inside(pos, outer_pos): outer_target.children_targets.append(child_target) break @@ -95,13 +83,14 @@ def calculate_smart_step_into_variants(frame, start_line, end_line, base=0): :raise: :py:class:`RuntimeError` if failed to parse the bytecode or if dis cannot be used. """ from .pydevd_bytecode_utils import _convert_target_to_variant + variants = [] code = frame.f_code lasti = frame.f_lasti call_order_cache = {} if DEBUG: - print('dis.dis:') + print("dis.dis:") if IS_PY311_OR_GREATER: dis.dis(code, show_caches=False) else: diff --git a/_pydevd_bundle/pydevd_code_to_source.py b/_pydevd_bundle/pydevd_code_to_source.py index 40feb7675..6b6e97752 100644 --- a/_pydevd_bundle/pydevd_code_to_source.py +++ b/_pydevd_bundle/pydevd_code_to_source.py @@ -15,7 +15,6 @@ class _Stack(object): - def __init__(self): self._contents = [] @@ -35,9 +34,8 @@ def pop(self): class _Token(object): - def __init__(self, i_line, instruction=None, tok=_SENTINEL, priority=0, after=None, end_of_line=False): - ''' + """ :param i_line: :param instruction: :param tok: @@ -45,18 +43,18 @@ def __init__(self, i_line, instruction=None, tok=_SENTINEL, priority=0, after=No :param after: :param end_of_line: Marker to signal only after all the other tokens have been written. - ''' + """ self.i_line = i_line if tok is not _SENTINEL: self.tok = tok else: if instruction is not None: if inspect.iscode(instruction.argval): - self.tok = '' + self.tok = "" else: self.tok = str(instruction.argval) else: - raise AssertionError('Either the tok or the instruction is needed.') + raise AssertionError("Either the tok or the instruction is needed.") self.instruction = instruction self.priority = priority self.end_of_line = end_of_line @@ -72,7 +70,7 @@ def mark_after(self, v): self._after_handler_tokens.add(v) else: - raise AssertionError('Unhandled: %s' % (v,)) + raise AssertionError("Unhandled: %s" % (v,)) def get_after_tokens(self): ret = self._after_tokens.copy() @@ -81,13 +79,12 @@ def get_after_tokens(self): return ret def __repr__(self): - return 'Token(%s, after: %s)' % (self.tok, self.get_after_tokens()) + return "Token(%s, after: %s)" % (self.tok, self.get_after_tokens()) __str__ = __repr__ class _Writer(object): - def __init__(self): self.line_to_contents = {} self.all_tokens = set() @@ -114,7 +111,6 @@ def write(self, line, token): class _BaseHandler(object): - def __init__(self, i_line, instruction, stack, writer, disassembler): self.i_line = i_line self.instruction = instruction @@ -149,13 +145,11 @@ def _register(cls): class _BasePushHandler(_BaseHandler): - def _handle(self): self.stack.push(self) class _BaseLoadHandler(_BasePushHandler): - def _handle(self): _BasePushHandler._handle(self) self.tokens = [_Token(self.i_line, self.instruction)] @@ -188,9 +182,10 @@ class _LoadFast(_BaseLoadHandler): @_register class _GetIter(_BaseHandler): - ''' + """ Implements TOS = iter(TOS). - ''' + """ + opname = "GET_ITER" iter_target = None @@ -202,11 +197,12 @@ def _handle(self): @_register class _ForIter(_BaseHandler): - ''' + """ TOS is an iterator. Call its __next__() method. If this yields a new value, push it on the stack (leaving the iterator below it). If the iterator indicates it is exhausted TOS is popped, and the byte code counter is incremented by delta. - ''' + """ + opname = "FOR_ITER" iter_in = None @@ -216,7 +212,7 @@ def _handle(self): self.stack.push(self) def store_in_name(self, store_name): - for_token = _Token(self.i_line, None, 'for ') + for_token = _Token(self.i_line, None, "for ") self.tokens.append(for_token) prev = for_token @@ -224,7 +220,7 @@ def store_in_name(self, store_name): self.tokens.append(t_name) prev = t_name - in_token = _Token(store_name.i_line, None, ' in ', after=prev) + in_token = _Token(store_name.i_line, None, " in ", after=prev) self.tokens.append(in_token) prev = in_token @@ -236,7 +232,7 @@ def store_in_name(self, store_name): prev = t self.tokens.extend(self.iter_in.tokens) - colon_token = _Token(self.i_line, None, ':', after=prev) + colon_token = _Token(self.i_line, None, ":", after=prev) self.tokens.append(colon_token) prev = for_token @@ -245,10 +241,10 @@ def store_in_name(self, store_name): @_register class _StoreName(_BaseHandler): - ''' + """ Implements name = TOS. namei is the index of name in the attribute co_names of the code object. The compiler tries to use STORE_FAST or STORE_GLOBAL if possible. - ''' + """ opname = "STORE_NAME" @@ -264,7 +260,7 @@ def _handle(self): line = min(line, t.i_line) t_name = _Token(line, self.instruction) - t_equal = _Token(line, None, '=', after=t_name) + t_equal = _Token(line, None, "=", after=t_name) self.tokens.append(t_name) self.tokens.append(t_equal) @@ -286,7 +282,7 @@ class _ReturnValue(_BaseHandler): def _handle(self): v = self.stack.pop() - return_token = _Token(self.i_line, None, 'return ', end_of_line=True) + return_token = _Token(self.i_line, None, "return ", end_of_line=True) self.tokens.append(return_token) for token in v.tokens: token.mark_after(return_token) @@ -324,7 +320,7 @@ def _handle(self): for t in name.tokens: self.tokens.append(t) - tok_open_parens = _Token(name.i_line, None, '(', after=name) + tok_open_parens = _Token(name.i_line, None, "(", after=name) self.tokens.append(tok_open_parens) prev = tok_open_parens @@ -337,11 +333,11 @@ def _handle(self): prev = arg if i > 0: - comma_token = _Token(prev.i_line, None, ',', after=prev) + comma_token = _Token(prev.i_line, None, ",", after=prev) self.tokens.append(comma_token) prev = comma_token - tok_close_parens = _Token(max_line, None, ')', after=prev) + tok_close_parens = _Token(max_line, None, ")", after=prev) self.tokens.append(tok_close_parens) self._write_tokens() @@ -380,10 +376,10 @@ def _handle(self): if self.instruction.argval & 0x01: default_node = stack.pop() - is_lambda = self.is_lambda = '' in [x.tok for x in self.qualified_name.tokens] + is_lambda = self.is_lambda = "" in [x.tok for x in self.qualified_name.tokens] if not is_lambda: - def_token = _Token(self.i_line, None, 'def ') + def_token = _Token(self.i_line, None, "def ") self.tokens.append(def_token) for token in self.qualified_name.tokens: @@ -392,20 +388,22 @@ def _handle(self): token.mark_after(def_token) prev = token - open_parens_token = _Token(self.i_line, None, '(', after=prev) + open_parens_token = _Token(self.i_line, None, "(", after=prev) self.tokens.append(open_parens_token) prev = open_parens_token code = self.code.instruction.argval if default_node: - defaults = ([_SENTINEL] * (len(code.co_varnames) - len(default_node.instruction.argval))) + list(default_node.instruction.argval) + defaults = ([_SENTINEL] * (len(code.co_varnames) - len(default_node.instruction.argval))) + list( + default_node.instruction.argval + ) else: defaults = [_SENTINEL] * len(code.co_varnames) for i, arg in enumerate(code.co_varnames): if i > 0: - comma_token = _Token(prev.i_line, None, ', ', after=prev) + comma_token = _Token(prev.i_line, None, ", ", after=prev) self.tokens.append(comma_token) prev = comma_token @@ -414,7 +412,7 @@ def _handle(self): default = defaults[i] if default is not _SENTINEL: - eq_token = _Token(default_node.i_line, None, '=', after=prev) + eq_token = _Token(default_node.i_line, None, "=", after=prev) self.tokens.append(eq_token) prev = eq_token @@ -422,7 +420,7 @@ def _handle(self): self.tokens.append(default_token) prev = default_token - tok_close_parens = _Token(prev.i_line, None, '):', after=prev) + tok_close_parens = _Token(prev.i_line, None, "):", after=prev) self.tokens.append(tok_close_parens) self._write_tokens() @@ -441,12 +439,10 @@ def _print_after_info(line_contents, stream=None): for token in line_contents: after_tokens = token.get_after_tokens() if after_tokens: - s = '%s after: %s\n' % ( - repr(token.tok), - ('"' + '", "'.join(t.tok for t in token.get_after_tokens()) + '"')) + s = "%s after: %s\n" % (repr(token.tok), ('"' + '", "'.join(t.tok for t in token.get_after_tokens()) + '"')) stream.write(s) else: - stream.write('%s (NO REQUISITES)' % repr(token.tok)) + stream.write("%s (NO REQUISITES)" % repr(token.tok)) def _compose_line_contents(line_contents, previous_line_tokens): @@ -495,13 +491,12 @@ def _compose_line_contents(line_contents, previous_line_tokens): stream = StringIO() _print_after_info(line_contents, stream) - pydev_log.critical('Error. After markers are not correct:\n%s', stream.getvalue()) + pydev_log.critical("Error. After markers are not correct:\n%s", stream.getvalue()) break - return ''.join(lst) + return "".join(lst) class _PyCodeToSource(object): - def __init__(self, co, memo=None): if memo is None: memo = {} @@ -542,7 +537,7 @@ def build_line_to_contents(self): def merge_code(self, code): if DEBUG: - print('merge code ----') + print("merge code ----") # for d in dir(code): # if not d.startswith('_'): # print(d, getattr(code, d)) @@ -552,7 +547,7 @@ def merge_code(self, code): lines.append(line) self.writer.get_line(line).extend(contents) if DEBUG: - print('end merge code ----') + print("end merge code ----") return lines def disassemble(self): @@ -560,14 +555,14 @@ def disassemble(self): line_to_contents = self.build_line_to_contents() stream = StringIO() last_line = 0 - indent = '' + indent = "" previous_line_tokens = set() for i_line, contents in sorted(line_to_contents.items()): while last_line < i_line - 1: if show_lines: - stream.write(u"%s.\n" % (last_line + 1,)) + stream.write("%s.\n" % (last_line + 1,)) else: - stream.write(u"\n") + stream.write("\n") last_line += 1 line_contents = [] @@ -575,24 +570,24 @@ def disassemble(self): for part in contents: if part is INDENT_MARKER: if DEBUG: - print('found indent', i_line) - indent += ' ' + print("found indent", i_line) + indent += " " continue if part is DEDENT_MARKER: if DEBUG: - print('found dedent', i_line) + print("found dedent", i_line) dedents_found += 1 continue line_contents.append(part) s = indent + _compose_line_contents(line_contents, previous_line_tokens) if show_lines: - stream.write(u"%s. %s\n" % (i_line, s)) + stream.write("%s. %s\n" % (i_line, s)) else: - stream.write(u"%s\n" % s) + stream.write("%s\n" % s) if dedents_found: - indent = indent[:-(4 * dedents_found)] + indent = indent[: -(4 * dedents_found)] last_line = i_line return stream.getvalue() diff --git a/_pydevd_bundle/pydevd_collect_bytecode_info.py b/_pydevd_bundle/pydevd_collect_bytecode_info.py index be9776dbc..2958565ae 100644 --- a/_pydevd_bundle/pydevd_collect_bytecode_info.py +++ b/_pydevd_bundle/pydevd_collect_bytecode_info.py @@ -4,22 +4,20 @@ from collections import namedtuple from _pydev_bundle import pydev_log -from opcode import (EXTENDED_ARG, HAVE_ARGUMENT, cmp_op, hascompare, hasconst, - hasfree, hasjrel, haslocal, hasname, opname) +from opcode import EXTENDED_ARG, HAVE_ARGUMENT, cmp_op, hascompare, hasconst, hasfree, hasjrel, haslocal, hasname, opname from io import StringIO class TryExceptInfo(object): - def __init__(self, try_line, ignore=False): - ''' + """ :param try_line: :param ignore: Usually we should ignore any block that's not a try..except (this can happen for finally blocks, with statements, etc, for which we create temporary entries). - ''' + """ self.try_line = try_line self.ignore = ignore self.except_line = -1 @@ -38,29 +36,28 @@ def is_line_in_except_block(self, line): def __str__(self): lst = [ - '{try:', + "{try:", str(self.try_line), - ' except ', + " except ", str(self.except_line), - ' end block ', + " end block ", str(self.except_end_line), ] if self.raise_lines_in_except: - lst.append(' raises: %s' % (', '.join(str(x) for x in self.raise_lines_in_except),)) + lst.append(" raises: %s" % (", ".join(str(x) for x in self.raise_lines_in_except),)) - lst.append('}') - return ''.join(lst) + lst.append("}") + return "".join(lst) __repr__ = __str__ class ReturnInfo(object): - def __init__(self, return_line): self.return_line = return_line def __str__(self): - return '{return: %s}' % (self.return_line,) + return "{return: %s}" % (self.return_line,) __repr__ = __str__ @@ -75,15 +72,14 @@ def _get_line(op_offset_to_line, op_offset, firstlineno, search=False): return ret else: op_offset -= 1 - raise AssertionError('Unable to find line for offset: %s.Info: %s' % ( - op_offset_original, op_offset_to_line)) + raise AssertionError("Unable to find line for offset: %s.Info: %s" % (op_offset_original, op_offset_to_line)) def debug(s): pass -_Instruction = namedtuple('_Instruction', 'opname, opcode, starts_line, argval, is_jump_target, offset, argrepr') +_Instruction = namedtuple("_Instruction", "opname, opcode, starts_line, argval, is_jump_target, offset, argrepr") def _iter_as_bytecode_as_instructions_py2(co): @@ -107,7 +103,15 @@ def _iter_as_bytecode_as_instructions_py2(co): i = i + 1 if op < HAVE_ARGUMENT: - yield _Instruction(curr_op_name, op, _get_line(op_offset_to_line, initial_bytecode_offset, 0), None, is_jump_target, initial_bytecode_offset, '') + yield _Instruction( + curr_op_name, + op, + _get_line(op_offset_to_line, initial_bytecode_offset, 0), + None, + is_jump_target, + initial_bytecode_offset, + "", + ) else: oparg = ord(code[i]) + ord(code[i + 1]) * 256 + extended_arg @@ -118,22 +122,78 @@ def _iter_as_bytecode_as_instructions_py2(co): extended_arg = oparg * 65536 if op in hasconst: - yield _Instruction(curr_op_name, op, _get_line(op_offset_to_line, initial_bytecode_offset, 0), co.co_consts[oparg], is_jump_target, initial_bytecode_offset, repr(co.co_consts[oparg])) + yield _Instruction( + curr_op_name, + op, + _get_line(op_offset_to_line, initial_bytecode_offset, 0), + co.co_consts[oparg], + is_jump_target, + initial_bytecode_offset, + repr(co.co_consts[oparg]), + ) elif op in hasname: - yield _Instruction(curr_op_name, op, _get_line(op_offset_to_line, initial_bytecode_offset, 0), co.co_names[oparg], is_jump_target, initial_bytecode_offset, str(co.co_names[oparg])) + yield _Instruction( + curr_op_name, + op, + _get_line(op_offset_to_line, initial_bytecode_offset, 0), + co.co_names[oparg], + is_jump_target, + initial_bytecode_offset, + str(co.co_names[oparg]), + ) elif op in hasjrel: argval = i + oparg - yield _Instruction(curr_op_name, op, _get_line(op_offset_to_line, initial_bytecode_offset, 0), argval, is_jump_target, initial_bytecode_offset, "to " + repr(argval)) + yield _Instruction( + curr_op_name, + op, + _get_line(op_offset_to_line, initial_bytecode_offset, 0), + argval, + is_jump_target, + initial_bytecode_offset, + "to " + repr(argval), + ) elif op in haslocal: - yield _Instruction(curr_op_name, op, _get_line(op_offset_to_line, initial_bytecode_offset, 0), co.co_varnames[oparg], is_jump_target, initial_bytecode_offset, str(co.co_varnames[oparg])) + yield _Instruction( + curr_op_name, + op, + _get_line(op_offset_to_line, initial_bytecode_offset, 0), + co.co_varnames[oparg], + is_jump_target, + initial_bytecode_offset, + str(co.co_varnames[oparg]), + ) elif op in hascompare: - yield _Instruction(curr_op_name, op, _get_line(op_offset_to_line, initial_bytecode_offset, 0), cmp_op[oparg], is_jump_target, initial_bytecode_offset, cmp_op[oparg]) + yield _Instruction( + curr_op_name, + op, + _get_line(op_offset_to_line, initial_bytecode_offset, 0), + cmp_op[oparg], + is_jump_target, + initial_bytecode_offset, + cmp_op[oparg], + ) elif op in hasfree: if free is None: free = co.co_cellvars + co.co_freevars - yield _Instruction(curr_op_name, op, _get_line(op_offset_to_line, initial_bytecode_offset, 0), free[oparg], is_jump_target, initial_bytecode_offset, str(free[oparg])) + yield _Instruction( + curr_op_name, + op, + _get_line(op_offset_to_line, initial_bytecode_offset, 0), + free[oparg], + is_jump_target, + initial_bytecode_offset, + str(free[oparg]), + ) else: - yield _Instruction(curr_op_name, op, _get_line(op_offset_to_line, initial_bytecode_offset, 0), oparg, is_jump_target, initial_bytecode_offset, str(oparg)) + yield _Instruction( + curr_op_name, + op, + _get_line(op_offset_to_line, initial_bytecode_offset, 0), + oparg, + is_jump_target, + initial_bytecode_offset, + str(oparg), + ) def iter_instructions(co): @@ -153,7 +213,7 @@ def iter_instructions(co): def collect_return_info(co, use_func_first_line=False): - if not hasattr(co, 'co_lines') and not hasattr(co, 'co_lnotab'): + if not hasattr(co, "co_lines") and not hasattr(co, "co_lnotab"): return [] if use_func_first_line: @@ -165,7 +225,7 @@ def collect_return_info(co, use_func_first_line=False): op_offset_to_line = dict(dis.findlinestarts(co)) for instruction in iter_instructions(co): curr_op_name = instruction.opname - if curr_op_name in ('RETURN_VALUE', 'RETURN_CONST'): + if curr_op_name in ("RETURN_VALUE", "RETURN_CONST"): lst.append(ReturnInfo(_get_line(op_offset_to_line, instruction.offset, firstlineno, search=True))) return lst @@ -174,35 +234,36 @@ def collect_return_info(co, use_func_first_line=False): if sys.version_info[:2] <= (3, 9): class _TargetInfo(object): - def __init__(self, except_end_instruction, jump_if_not_exc_instruction=None): self.except_end_instruction = except_end_instruction self.jump_if_not_exc_instruction = jump_if_not_exc_instruction def __str__(self): - msg = ['_TargetInfo('] + msg = ["_TargetInfo("] msg.append(self.except_end_instruction.opname) if self.jump_if_not_exc_instruction: - msg.append(' - ') + msg.append(" - ") msg.append(self.jump_if_not_exc_instruction.opname) - msg.append('(') + msg.append("(") msg.append(str(self.jump_if_not_exc_instruction.argval)) - msg.append(')') - msg.append(')') - return ''.join(msg) + msg.append(")") + msg.append(")") + return "".join(msg) def _get_except_target_info(instructions, exception_end_instruction_index, offset_to_instruction_idx): - next_3 = [j_instruction.opname for j_instruction in instructions[exception_end_instruction_index:exception_end_instruction_index + 3]] + next_3 = [ + j_instruction.opname for j_instruction in instructions[exception_end_instruction_index : exception_end_instruction_index + 3] + ] # print('next_3:', [(j_instruction.opname, j_instruction.argval) for j_instruction in instructions[exception_end_instruction_index:exception_end_instruction_index + 3]]) - if next_3 == ['POP_TOP', 'POP_TOP', 'POP_TOP']: # try..except without checking exception. + if next_3 == ["POP_TOP", "POP_TOP", "POP_TOP"]: # try..except without checking exception. try: jump_instruction = instructions[exception_end_instruction_index - 1] - if jump_instruction.opname not in ('JUMP_FORWARD', 'JUMP_ABSOLUTE'): + if jump_instruction.opname not in ("JUMP_FORWARD", "JUMP_ABSOLUTE"): return None except IndexError: pass - if jump_instruction.opname == 'JUMP_ABSOLUTE': + if jump_instruction.opname == "JUMP_ABSOLUTE": # On latest versions of Python 3 the interpreter has a go-backwards step, # used to show the initial line of a for/while, etc (which is this # JUMP_ABSOLUTE)... we're not really interested in it, but rather on where @@ -211,7 +272,7 @@ def _get_except_target_info(instructions, exception_end_instruction_index, offse idx = offset_to_instruction_idx[except_end_instruction.argval] # Search for the POP_EXCEPT which should be at the end of the block. for pop_except_instruction in reversed(instructions[:idx]): - if pop_except_instruction.opname == 'POP_EXCEPT': + if pop_except_instruction.opname == "POP_EXCEPT": except_end_instruction = pop_except_instruction return _TargetInfo(except_end_instruction) else: @@ -226,25 +287,25 @@ def _get_except_target_info(instructions, exception_end_instruction_index, offse # block finishes). except_end_instruction = instructions[i - 1] except: - pydev_log.critical('Error when computing try..except block end.') + pydev_log.critical("Error when computing try..except block end.") return None return _TargetInfo(except_end_instruction) - elif next_3 and next_3[0] == 'DUP_TOP': # try..except AssertionError. - iter_in = instructions[exception_end_instruction_index + 1:] + elif next_3 and next_3[0] == "DUP_TOP": # try..except AssertionError. + iter_in = instructions[exception_end_instruction_index + 1 :] for j, jump_if_not_exc_instruction in enumerate(iter_in): - if jump_if_not_exc_instruction.opname == 'JUMP_IF_NOT_EXC_MATCH': + if jump_if_not_exc_instruction.opname == "JUMP_IF_NOT_EXC_MATCH": # Python 3.9 except_end_instruction = instructions[offset_to_instruction_idx[jump_if_not_exc_instruction.argval]] return _TargetInfo(except_end_instruction, jump_if_not_exc_instruction) - elif jump_if_not_exc_instruction.opname == 'COMPARE_OP' and jump_if_not_exc_instruction.argval == 'exception match': + elif jump_if_not_exc_instruction.opname == "COMPARE_OP" and jump_if_not_exc_instruction.argval == "exception match": # Python 3.8 and before try: next_instruction = iter_in[j + 1] except: continue - if next_instruction.opname == 'POP_JUMP_IF_FALSE': + if next_instruction.opname == "POP_JUMP_IF_FALSE": except_end_instruction = instructions[offset_to_instruction_idx[next_instruction.argval]] return _TargetInfo(except_end_instruction, next_instruction) else: @@ -256,7 +317,7 @@ def _get_except_target_info(instructions, exception_end_instruction_index, offse def collect_try_except_info(co, use_func_first_line=False): # We no longer have 'END_FINALLY', so, we need to do things differently in Python 3.9 - if not hasattr(co, 'co_lines') and not hasattr(co, 'co_lnotab'): + if not hasattr(co, "co_lines") and not hasattr(co, "co_lnotab"): return [] if use_func_first_line: @@ -277,11 +338,11 @@ def collect_try_except_info(co, use_func_first_line=False): for i, instruction in enumerate(instructions): curr_op_name = instruction.opname - if curr_op_name in ('SETUP_FINALLY', 'SETUP_EXCEPT'): # SETUP_EXCEPT before Python 3.8, SETUP_FINALLY Python 3.8 onwards. + if curr_op_name in ("SETUP_FINALLY", "SETUP_EXCEPT"): # SETUP_EXCEPT before Python 3.8, SETUP_FINALLY Python 3.8 onwards. exception_end_instruction_index = offset_to_instruction_idx[instruction.argval] jump_instruction = instructions[exception_end_instruction_index - 1] - if jump_instruction.opname not in ('JUMP_FORWARD', 'JUMP_ABSOLUTE'): + if jump_instruction.opname not in ("JUMP_FORWARD", "JUMP_ABSOLUTE"): continue except_end_instruction = None @@ -304,66 +365,64 @@ def collect_try_except_info(co, use_func_first_line=False): if except_end_instruction is not None: try_except_info = TryExceptInfo( - _get_line(op_offset_to_line, instruction.offset, firstlineno, search=True), - ignore=False + _get_line(op_offset_to_line, instruction.offset, firstlineno, search=True), ignore=False ) try_except_info.except_bytecode_offset = instruction.argval try_except_info.except_line = _get_line( - op_offset_to_line, - try_except_info.except_bytecode_offset, - firstlineno, - search=True + op_offset_to_line, try_except_info.except_bytecode_offset, firstlineno, search=True ) try_except_info.except_end_bytecode_offset = except_end_instruction.offset try_except_info.except_end_line = _get_line(op_offset_to_line, except_end_instruction.offset, firstlineno, search=True) try_except_info_lst.append(try_except_info) - for raise_instruction in instructions[i:offset_to_instruction_idx[try_except_info.except_end_bytecode_offset]]: - if raise_instruction.opname == 'RAISE_VARARGS': + for raise_instruction in instructions[i : offset_to_instruction_idx[try_except_info.except_end_bytecode_offset]]: + if raise_instruction.opname == "RAISE_VARARGS": if raise_instruction.argval == 0: try_except_info.raise_lines_in_except.append( - _get_line(op_offset_to_line, raise_instruction.offset, firstlineno, search=True)) + _get_line(op_offset_to_line, raise_instruction.offset, firstlineno, search=True) + ) return try_except_info_lst elif sys.version_info[:2] == (3, 10): class _TargetInfo(object): - def __init__(self, except_end_instruction, jump_if_not_exc_instruction=None): self.except_end_instruction = except_end_instruction self.jump_if_not_exc_instruction = jump_if_not_exc_instruction def __str__(self): - msg = ['_TargetInfo('] + msg = ["_TargetInfo("] msg.append(self.except_end_instruction.opname) if self.jump_if_not_exc_instruction: - msg.append(' - ') + msg.append(" - ") msg.append(self.jump_if_not_exc_instruction.opname) - msg.append('(') + msg.append("(") msg.append(str(self.jump_if_not_exc_instruction.argval)) - msg.append(')') - msg.append(')') - return ''.join(msg) + msg.append(")") + msg.append(")") + return "".join(msg) def _get_except_target_info(instructions, exception_end_instruction_index, offset_to_instruction_idx): - next_3 = [j_instruction.opname for j_instruction in instructions[exception_end_instruction_index:exception_end_instruction_index + 3]] + next_3 = [ + j_instruction.opname for j_instruction in instructions[exception_end_instruction_index : exception_end_instruction_index + 3] + ] # print('next_3:', [(j_instruction.opname, j_instruction.argval) for j_instruction in instructions[exception_end_instruction_index:exception_end_instruction_index + 3]]) - if next_3 == ['POP_TOP', 'POP_TOP', 'POP_TOP']: # try..except without checking exception. + if next_3 == ["POP_TOP", "POP_TOP", "POP_TOP"]: # try..except without checking exception. # Previously there was a jump which was able to point where the exception would end. This # is no longer true, now a bare except doesn't really have any indication in the bytecode # where the end would be expected if the exception wasn't raised, so, we just blindly # search for a POP_EXCEPT from the current position. - for pop_except_instruction in instructions[exception_end_instruction_index + 3:]: - if pop_except_instruction.opname == 'POP_EXCEPT': + for pop_except_instruction in instructions[exception_end_instruction_index + 3 :]: + if pop_except_instruction.opname == "POP_EXCEPT": except_end_instruction = pop_except_instruction return _TargetInfo(except_end_instruction) - elif next_3 and next_3[0] == 'DUP_TOP': # try..except AssertionError. - iter_in = instructions[exception_end_instruction_index + 1:] + elif next_3 and next_3[0] == "DUP_TOP": # try..except AssertionError. + iter_in = instructions[exception_end_instruction_index + 1 :] for jump_if_not_exc_instruction in iter_in: - if jump_if_not_exc_instruction.opname == 'JUMP_IF_NOT_EXC_MATCH': + if jump_if_not_exc_instruction.opname == "JUMP_IF_NOT_EXC_MATCH": # Python 3.9 except_end_instruction = instructions[offset_to_instruction_idx[jump_if_not_exc_instruction.argval]] return _TargetInfo(except_end_instruction, jump_if_not_exc_instruction) @@ -376,7 +435,7 @@ def _get_except_target_info(instructions, exception_end_instruction_index, offse def collect_try_except_info(co, use_func_first_line=False): # We no longer have 'END_FINALLY', so, we need to do things differently in Python 3.9 - if not hasattr(co, 'co_lines') and not hasattr(co, 'co_lnotab'): + if not hasattr(co, "co_lines") and not hasattr(co, "co_lnotab"): return [] if use_func_first_line: @@ -397,11 +456,11 @@ def collect_try_except_info(co, use_func_first_line=False): for i, instruction in enumerate(instructions): curr_op_name = instruction.opname - if curr_op_name == 'SETUP_FINALLY': + if curr_op_name == "SETUP_FINALLY": exception_end_instruction_index = offset_to_instruction_idx[instruction.argval] jump_instruction = instructions[exception_end_instruction_index] - if jump_instruction.opname != 'DUP_TOP': + if jump_instruction.opname != "DUP_TOP": continue except_end_instruction = None @@ -424,15 +483,11 @@ def collect_try_except_info(co, use_func_first_line=False): if except_end_instruction is not None: try_except_info = TryExceptInfo( - _get_line(op_offset_to_line, instruction.offset, firstlineno, search=True), - ignore=False + _get_line(op_offset_to_line, instruction.offset, firstlineno, search=True), ignore=False ) try_except_info.except_bytecode_offset = instruction.argval try_except_info.except_line = _get_line( - op_offset_to_line, - try_except_info.except_bytecode_offset, - firstlineno, - search=True + op_offset_to_line, try_except_info.except_bytecode_offset, firstlineno, search=True ) try_except_info.except_end_bytecode_offset = except_end_instruction.offset @@ -444,7 +499,7 @@ def collect_try_except_info(co, use_func_first_line=False): except_end_line = -1 start_i = offset_to_instruction_idx[try_except_info.except_bytecode_offset] end_i = offset_to_instruction_idx[except_end_instruction.offset] - for instruction in instructions[start_i: end_i + 1]: + for instruction in instructions[start_i : end_i + 1]: found_at_line = op_offset_to_line.get(instruction.offset) if found_at_line is not None and found_at_line > except_end_line: except_end_line = found_at_line @@ -452,29 +507,30 @@ def collect_try_except_info(co, use_func_first_line=False): try_except_info_lst.append(try_except_info) - for raise_instruction in instructions[i:offset_to_instruction_idx[try_except_info.except_end_bytecode_offset]]: - if raise_instruction.opname == 'RAISE_VARARGS': + for raise_instruction in instructions[i : offset_to_instruction_idx[try_except_info.except_end_bytecode_offset]]: + if raise_instruction.opname == "RAISE_VARARGS": if raise_instruction.argval == 0: try_except_info.raise_lines_in_except.append( - _get_line(op_offset_to_line, raise_instruction.offset, firstlineno, search=True)) + _get_line(op_offset_to_line, raise_instruction.offset, firstlineno, search=True) + ) return try_except_info_lst elif sys.version_info[:2] >= (3, 11): def collect_try_except_info(co, use_func_first_line=False): - ''' + """ Note: if the filename is available and we can get the source, `collect_try_except_info_from_source` is preferred (this is kept as a fallback for cases where sources aren't available). - ''' + """ return [] + import ast as ast_module class _Visitor(ast_module.NodeVisitor): - def __init__(self): self.try_except_infos = [] self._stack = [] @@ -482,7 +538,7 @@ def __init__(self): self.max_line = -1 def generic_visit(self, node): - if hasattr(node, 'lineno'): + if hasattr(node, "lineno"): if node.lineno > self.max_line: self.max_line = node.lineno return ast_module.NodeVisitor.generic_visit(self, node) @@ -505,7 +561,7 @@ def visit_ExceptHandler(self, node): info.except_line = node.lineno self._in_except_stack.append(info) self.generic_visit(node) - if hasattr(node, 'end_lineno'): + if hasattr(node, "end_lineno"): info.except_end_line = node.end_lineno else: info.except_end_line = self.max_line @@ -515,26 +571,26 @@ def visit_ExceptHandler(self, node): def visit_Raise(self, node): for info in self._in_except_stack: - if node.exc is None: - info.raise_lines_in_except.append(node.lineno) + if node.exc is None: + info.raise_lines_in_except.append(node.lineno) self.generic_visit(node) else: def visit_Raise(self, node): for info in self._in_except_stack: - if node.type is None and node.tback is None: - info.raise_lines_in_except.append(node.lineno) + if node.type is None and node.tback is None: + info.raise_lines_in_except.append(node.lineno) self.generic_visit(node) def collect_try_except_info_from_source(filename): - with open(filename, 'rb') as stream: + with open(filename, "rb") as stream: contents = stream.read() return collect_try_except_info_from_contents(contents, filename) -def collect_try_except_info_from_contents(contents, filename=''): +def collect_try_except_info_from_contents(contents, filename=""): ast = ast_module.parse(contents, filename) visitor = _Visitor() visitor.visit(ast) @@ -546,14 +602,13 @@ def collect_try_except_info_from_contents(contents, filename=''): class _MsgPart(object): - def __init__(self, line, tok): assert line >= 0 self.line = line self.tok = tok def __str__(self) -> str: - return '_MsgPart(line: %s tok: %s)' % (self.line, self.tok) + return "_MsgPart(line: %s tok: %s)" % (self.line, self.tok) __repr__ = __str__ @@ -585,7 +640,6 @@ def add_to_line_to_contents(cls, obj, line_to_contents, line=None): class _Disassembler(object): - def __init__(self, co, firstlineno, level=0): self.co = co self.firstlineno = firstlineno @@ -616,7 +670,7 @@ def min_line(self, *args): elif isinstance(arg, _MsgPart): m = min(m, arg.line) - elif hasattr(arg, 'offset'): + elif hasattr(arg, "offset"): m = min(m, self.op_offset_to_line[arg.offset]) return m @@ -629,23 +683,23 @@ def max_line(self, *args): elif isinstance(arg, _MsgPart): m = max(m, arg.line) - elif hasattr(arg, 'offset'): + elif hasattr(arg, "offset"): m = max(m, self.op_offset_to_line[arg.offset]) return m def _lookahead(self): - ''' + """ This handles and converts some common constructs from bytecode to actual source code. It may change the list of instructions. - ''' + """ msg = self._create_msg_part found = [] fullrepr = None # Collect all the load instructions for next_instruction in self.instructions: - if next_instruction.opname in ('LOAD_GLOBAL', 'LOAD_FAST', 'LOAD_CONST', 'LOAD_NAME'): + if next_instruction.opname in ("LOAD_GLOBAL", "LOAD_FAST", "LOAD_CONST", "LOAD_NAME"): found.append(next_instruction) else: break @@ -653,7 +707,7 @@ def _lookahead(self): if not found: return None - if next_instruction.opname == 'LOAD_ATTR': + if next_instruction.opname == "LOAD_ATTR": prev_instruction = found[-1] # Remove the current LOAD_ATTR assert self.instructions.pop(len(found)) is next_instruction @@ -666,15 +720,11 @@ def _lookahead(self): prev_instruction.argval, False, # prev_instruction.is_jump_target, prev_instruction.offset, - ( - msg(prev_instruction), - msg(prev_instruction, '.'), - msg(next_instruction) - ), + (msg(prev_instruction), msg(prev_instruction, "."), msg(next_instruction)), ) return RESTART_FROM_LOOKAHEAD - if next_instruction.opname in ('CALL_FUNCTION', 'PRECALL', 'CALL'): + if next_instruction.opname in ("CALL_FUNCTION", "PRECALL", "CALL"): if len(found) == next_instruction.argval + 1: force_restart = False delta = 0 @@ -686,7 +736,7 @@ def _lookahead(self): return None # This is odd del_upto = delta + next_instruction.argval + 2 # +2 = NAME / CALL_FUNCTION - if next_instruction.opname == 'PRECALL': + if next_instruction.opname == "PRECALL": del_upto += 1 # Also remove the CALL right after the PRECALL. del self.instructions[delta:del_upto] @@ -695,31 +745,33 @@ def _lookahead(self): args = list(found) fullrepr = [ msg(call_func), - msg(call_func, '('), + msg(call_func, "("), ] prev = call_func for i, arg in enumerate(args): if i > 0: - fullrepr.append(msg(prev, ', ')) + fullrepr.append(msg(prev, ", ")) prev = arg fullrepr.append(msg(arg)) - fullrepr.append(msg(prev, ')')) + fullrepr.append(msg(prev, ")")) if force_restart: - self.instructions.insert(delta, _Instruction( - call_func.opname, - call_func.opcode, - call_func.starts_line, - call_func.argval, - False, # call_func.is_jump_target, - call_func.offset, - tuple(fullrepr), - )) + self.instructions.insert( + delta, + _Instruction( + call_func.opname, + call_func.opcode, + call_func.starts_line, + call_func.argval, + False, # call_func.is_jump_target, + call_func.offset, + tuple(fullrepr), + ), + ) return RESTART_FROM_LOOKAHEAD - elif next_instruction.opname == 'BUILD_TUPLE': - + elif next_instruction.opname == "BUILD_TUPLE": if len(found) == next_instruction.argval: force_restart = False delta = 0 @@ -730,7 +782,7 @@ def _lookahead(self): else: return None # This is odd - del self.instructions[delta:delta + next_instruction.argval + 1] # +1 = BUILD_TUPLE + del self.instructions[delta : delta + next_instruction.argval + 1] # +1 = BUILD_TUPLE found = iter(found[delta:]) @@ -742,44 +794,47 @@ def _lookahead(self): prev = first_instruction fullrepr = [] - fullrepr.append(msg(prev, '(')) + fullrepr.append(msg(prev, "(")) for i, arg in enumerate(args): if i > 0: - fullrepr.append(msg(prev, ', ')) + fullrepr.append(msg(prev, ", ")) prev = arg fullrepr.append(msg(arg)) - fullrepr.append(msg(prev, ')')) + fullrepr.append(msg(prev, ")")) if force_restart: - self.instructions.insert(delta, _Instruction( - first_instruction.opname, - first_instruction.opcode, - first_instruction.starts_line, - first_instruction.argval, - False, # first_instruction.is_jump_target, - first_instruction.offset, - tuple(fullrepr), - )) + self.instructions.insert( + delta, + _Instruction( + first_instruction.opname, + first_instruction.opcode, + first_instruction.starts_line, + first_instruction.argval, + False, # first_instruction.is_jump_target, + first_instruction.offset, + tuple(fullrepr), + ), + ) return RESTART_FROM_LOOKAHEAD if fullrepr is not None and self.instructions: - if self.instructions[0].opname == 'POP_TOP': + if self.instructions[0].opname == "POP_TOP": self.instructions.pop(0) - if self.instructions[0].opname in ('STORE_FAST', 'STORE_NAME'): + if self.instructions[0].opname in ("STORE_FAST", "STORE_NAME"): next_instruction = self.instructions.pop(0) - return msg(next_instruction), msg(next_instruction, ' = '), fullrepr + return msg(next_instruction), msg(next_instruction, " = "), fullrepr - if self.instructions[0].opname == 'RETURN_VALUE': + if self.instructions[0].opname == "RETURN_VALUE": next_instruction = self.instructions.pop(0) - return msg(next_instruction, 'return ', line=self.min_line(next_instruction, fullrepr)), fullrepr + return msg(next_instruction, "return ", line=self.min_line(next_instruction, fullrepr)), fullrepr return fullrepr def _decorate_jump_target(self, instruction, instruction_repr): if instruction.is_jump_target: - return ('|', str(instruction.offset), '|', instruction_repr) + return ("|", str(instruction.offset), "|", instruction_repr) return instruction_repr @@ -789,10 +844,9 @@ def _create_msg_part(self, instruction, tok=None, line=None): line = self.op_offset_to_line[instruction.offset] argrepr = instruction.argrepr - if isinstance(argrepr, str) and argrepr.startswith('NULL + '): + if isinstance(argrepr, str) and argrepr.startswith("NULL + "): argrepr = argrepr[7:] - return _MsgPart( - line, tok if tok is not None else dec(instruction, argrepr)) + return _MsgPart(line, tok if tok is not None else dec(instruction, argrepr)) def _next_instruction_to_str(self, line_to_contents): # indent = '' @@ -809,54 +863,55 @@ def _next_instruction_to_str(self, line_to_contents): instruction = self.instructions.pop(0) - if instruction.opname in ('RESUME', 'NULL'): + if instruction.opname in ("RESUME", "NULL"): return None - if instruction.opname == 'RETURN_CONST': - return (msg(instruction, 'return ', line=self.min_line(instruction)), msg(instruction)) + if instruction.opname == "RETURN_CONST": + return (msg(instruction, "return ", line=self.min_line(instruction)), msg(instruction)) - if instruction.opname in ('LOAD_GLOBAL', 'LOAD_FAST', 'LOAD_CONST', 'LOAD_NAME'): + if instruction.opname in ("LOAD_GLOBAL", "LOAD_FAST", "LOAD_CONST", "LOAD_NAME"): next_instruction = self.instructions[0] - if next_instruction.opname in ('STORE_FAST', 'STORE_NAME'): + if next_instruction.opname in ("STORE_FAST", "STORE_NAME"): self.instructions.pop(0) - return ( - msg(next_instruction), - msg(next_instruction, ' = '), - msg(instruction)) + return (msg(next_instruction), msg(next_instruction, " = "), msg(instruction)) - if next_instruction.opname == 'RETURN_VALUE': + if next_instruction.opname == "RETURN_VALUE": self.instructions.pop(0) - return (msg(instruction, 'return ', line=self.min_line(instruction)), msg(instruction)) + return (msg(instruction, "return ", line=self.min_line(instruction)), msg(instruction)) - if next_instruction.opname == 'RAISE_VARARGS' and next_instruction.argval == 1: + if next_instruction.opname == "RAISE_VARARGS" and next_instruction.argval == 1: self.instructions.pop(0) - return (msg(instruction, 'raise ', line=self.min_line(instruction)), msg(instruction)) + return (msg(instruction, "raise ", line=self.min_line(instruction)), msg(instruction)) - if instruction.opname == 'LOAD_CONST': + if instruction.opname == "LOAD_CONST": if inspect.iscode(instruction.argval): - - code_line_to_contents = _Disassembler( - instruction.argval, self.firstlineno, self.level + 1 - ).build_line_to_contents() + code_line_to_contents = _Disassembler(instruction.argval, self.firstlineno, self.level + 1).build_line_to_contents() for contents in code_line_to_contents.values(): - contents.insert(0, ' ') + contents.insert(0, " ") for line, contents in code_line_to_contents.items(): line_to_contents.setdefault(line, []).extend(contents) - return msg(instruction, 'LOAD_CONST(code)') + return msg(instruction, "LOAD_CONST(code)") - if instruction.opname == 'RAISE_VARARGS': + if instruction.opname == "RAISE_VARARGS": if instruction.argval == 0: - return msg(instruction, 'raise') + return msg(instruction, "raise") - if instruction.opname == 'SETUP_FINALLY': - return msg(instruction, ('try(', instruction.argrepr, '):')) + if instruction.opname == "SETUP_FINALLY": + return msg(instruction, ("try(", instruction.argrepr, "):")) if instruction.argrepr: - return msg(instruction, (instruction.opname, '(', instruction.argrepr, ')')) + return msg(instruction, (instruction.opname, "(", instruction.argrepr, ")")) if instruction.argval: - return msg(instruction, '%s{%s}' % (instruction.opname, instruction.argval,)) + return msg( + instruction, + "%s{%s}" + % ( + instruction.opname, + instruction.argval, + ), + ) return msg(instruction, instruction.opname) @@ -890,22 +945,22 @@ def disassemble(self): for line, contents in sorted(line_to_contents.items()): while last_line < line - 1: if show_lines: - stream.write('%s.\n' % (last_line + 1,)) + stream.write("%s.\n" % (last_line + 1,)) else: - stream.write('\n') + stream.write("\n") last_line += 1 if show_lines: - stream.write('%s. ' % (line,)) + stream.write("%s. " % (line,)) for i, content in enumerate(contents): if content == SEPARATOR: if i != len(contents) - 1: - stream.write(', ') + stream.write(", ") else: stream.write(content) - stream.write('\n') + stream.write("\n") last_line = line @@ -913,7 +968,7 @@ def disassemble(self): def code_to_bytecode_representation(co, use_func_first_line=False): - ''' + """ A simple disassemble of bytecode. It does not attempt to provide the full Python source code, rather, it provides a low-level @@ -922,7 +977,7 @@ def code_to_bytecode_representation(co, use_func_first_line=False): Note that it does show jump locations/targets and converts some common bytecode constructs to Python code to make it a bit easier to understand. - ''' + """ # Reference for bytecodes: # https://docs.python.org/3/library/dis.html if use_func_first_line: diff --git a/_pydevd_bundle/pydevd_comm.py b/_pydevd_bundle/pydevd_comm.py index b9d75306a..b15479151 100644 --- a/_pydevd_bundle/pydevd_comm.py +++ b/_pydevd_bundle/pydevd_comm.py @@ -1,4 +1,4 @@ -''' pydevd - a debugging daemon +""" pydevd - a debugging daemon This is the daemon you launch for python remote debugging. Protocol: @@ -61,7 +61,7 @@ * JAVA - remote debugger, the java end * PYDB - pydevd, the python end -''' +""" import linecache import os @@ -69,15 +69,30 @@ from _pydev_bundle.pydev_imports import _queue from _pydev_bundle._pydev_saved_modules import time, ThreadingEvent from _pydev_bundle._pydev_saved_modules import socket as socket_module -from _pydevd_bundle.pydevd_constants import (DebugInfoHolder, IS_WINDOWS, IS_JYTHON, IS_WASM, - IS_PY36_OR_GREATER, STATE_RUN, ASYNC_EVAL_TIMEOUT_SEC, - get_global_debugger, GetGlobalDebugger, set_global_debugger, # Keep for backward compatibility @UnusedImport - silence_warnings_decorator, filter_all_warnings, IS_PY311_OR_GREATER) +from _pydevd_bundle.pydevd_constants import ( + DebugInfoHolder, + IS_WINDOWS, + IS_JYTHON, + IS_WASM, + IS_PY36_OR_GREATER, + STATE_RUN, + ASYNC_EVAL_TIMEOUT_SEC, + get_global_debugger, + GetGlobalDebugger, + set_global_debugger, # Keep for backward compatibility @UnusedImport + silence_warnings_decorator, + filter_all_warnings, + IS_PY311_OR_GREATER, +) from _pydev_bundle.pydev_override import overrides import weakref from _pydev_bundle._pydev_completer import extract_token_and_qualifier -from _pydevd_bundle._debug_adapter.pydevd_schema import VariablesResponseBody, \ - SetVariableResponseBody, StepInTarget, StepInTargetsResponseBody +from _pydevd_bundle._debug_adapter.pydevd_schema import ( + VariablesResponseBody, + SetVariableResponseBody, + StepInTarget, + StepInTargetsResponseBody, +) from _pydevd_bundle._debug_adapter import pydevd_base_schema, pydevd_schema from _pydevd_bundle.pydevd_net_command import NetCommand from _pydevd_bundle.pydevd_xml import ExceptionOnEvaluate @@ -96,9 +111,16 @@ from _pydevd_bundle import pydevd_vm_type import sys import traceback -from _pydevd_bundle.pydevd_utils import quote_smart as quote, compare_object_attrs_key, \ - notify_about_gevent_if_needed, isinstance_checked, ScopeRequest, getattr_checked, Timer, \ - is_current_thread_main_thread +from _pydevd_bundle.pydevd_utils import ( + quote_smart as quote, + compare_object_attrs_key, + notify_about_gevent_if_needed, + isinstance_checked, + ScopeRequest, + getattr_checked, + Timer, + is_current_thread_main_thread, +) from _pydev_bundle import pydev_log, fsnotify from _pydev_bundle.pydev_log import exception as pydev_log_exception from _pydev_bundle import _pydev_completer @@ -129,7 +151,7 @@ class ReaderThread(PyDBDaemonThread): - ''' reader thread reads and dispatches commands in an infinite loop ''' + """reader thread reads and dispatches commands in an infinite loop""" def __init__(self, sock, py_db, PyDevJsonCommandProcessor, process_net_command, terminate_on_socket_close=True): assert sock is not None @@ -137,7 +159,7 @@ def __init__(self, sock, py_db, PyDevJsonCommandProcessor, process_net_command, self.__terminate_on_socket_close = terminate_on_socket_close self.sock = sock - self._buffer = b'' + self._buffer = b"" self.name = "pydevd.Reader" self.process_net_command = process_net_command self.process_net_command_json = PyDevJsonCommandProcessor(self._from_json).process_net_command_json @@ -176,7 +198,7 @@ def _read(self, size): buffer_len = len(self._buffer) if buffer_len == size: ret = self._buffer - self._buffer = b'' + self._buffer = b"" return ret if buffer_len > size: @@ -187,14 +209,14 @@ def _read(self, size): try: r = self.sock.recv(max(size - buffer_len, 1024)) except OSError: - return b'' + return b"" if not r: - return b'' + return b"" self._buffer += r def _read_line(self): while True: - i = self._buffer.find(b'\n') + i = self._buffer.find(b"\n") if i != -1: i += 1 # Add the newline to the return ret = self._buffer[:i] @@ -204,9 +226,9 @@ def _read_line(self): try: r = self.sock.recv(1024) except OSError: - return b'' + return b"" if not r: - return b'' + return b"" self._buffer += r @overrides(PyDBDaemonThread._on_run) @@ -223,26 +245,26 @@ def _on_run(self): line = self._read_line() if len(line) == 0: - pydev_log.debug('ReaderThread: empty contents received (len(line) == 0).') + pydev_log.debug("ReaderThread: empty contents received (len(line) == 0).") self._terminate_on_socket_close() return # Finished communication. if self._kill_received: continue - if line.startswith(b'Content-Length:'): - content_len = int(line.strip().split(b':', 1)[1]) + if line.startswith(b"Content-Length:"): + content_len = int(line.strip().split(b":", 1)[1]) continue if content_len != -1: # If we previously received a content length, read until a '\r\n'. - if line == b'\r\n': + if line == b"\r\n": json_contents = self._read(content_len) content_len = -1 if len(json_contents) == 0: - pydev_log.debug('ReaderThread: empty contents received (len(json_contents) == 0).') + pydev_log.debug("ReaderThread: empty contents received (len(json_contents) == 0).") self._terminate_on_socket_close() return # Finished communication. @@ -255,13 +277,13 @@ def _on_run(self): continue else: # No content len, regular line-based protocol message (remove trailing new-line). - if line.endswith(b'\n\n'): + if line.endswith(b"\n\n"): line = line[:-2] - elif line.endswith(b'\n'): + elif line.endswith(b"\n"): line = line[:-1] - elif line.endswith(b'\r'): + elif line.endswith(b"\r"): line = line[:-1] except: if not self._kill_received: @@ -272,17 +294,17 @@ def _on_run(self): # Note: the java backend is always expected to pass utf-8 encoded strings. We now work with str # internally and thus, we may need to convert to the actual encoding where needed (i.e.: filenames # on python 2 may need to be converted to the filesystem encoding). - if hasattr(line, 'decode'): - line = line.decode('utf-8') + if hasattr(line, "decode"): + line = line.decode("utf-8") if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 3: - pydev_log.debug('debugger: received >>%s<<\n', line) + pydev_log.debug("debugger: received >>%s<<\n", line) - args = line.split('\t', 2) + args = line.split("\t", 2) try: cmd_id = int(args[0]) if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 3: - pydev_log.debug('Received command: %s %s\n', ID_TO_MEANING.get(str(cmd_id), '???'), line) + pydev_log.debug("Received command: %s %s\n", ID_TO_MEANING.get(str(cmd_id), "???"), line) self.process_command(cmd_id, int(args[1]), args[2]) except: if sys is not None and pydev_log_exception is not None: # Could happen at interpreter shutdown @@ -295,7 +317,7 @@ def _on_run(self): self._terminate_on_socket_close() finally: - pydev_log.debug('ReaderThread: exit') + pydev_log.debug("ReaderThread: exit") def _terminate_on_socket_close(self): if self.__terminate_on_socket_close: @@ -306,7 +328,6 @@ def process_command(self, cmd_id, seq, text): class FSNotifyThread(PyDBDaemonThread): - def __init__(self, py_db, api, watch_dirs): PyDBDaemonThread.__init__(self, py_db) self.api = api @@ -317,7 +338,7 @@ def __init__(self, py_db, api, watch_dirs): @overrides(PyDBDaemonThread._on_run) def _on_run(self): try: - pydev_log.info('Watching directories for code reload:\n---\n%s\n---' % ('\n'.join(sorted(self.watch_dirs)))) + pydev_log.info("Watching directories for code reload:\n---\n%s\n---" % ("\n".join(sorted(self.watch_dirs)))) # i.e.: The first call to set_tracked_paths will do a full scan, so, do it in the thread # too (after everything is configured). @@ -326,12 +347,12 @@ def _on_run(self): for change_enum, change_path in self.watcher.iter_changes(): # We're only interested in modified events if change_enum == fsnotify.Change.modified: - pydev_log.info('Modified: %s', change_path) + pydev_log.info("Modified: %s", change_path) self.api.request_reload_code(self.py_db, -1, None, change_path) else: - pydev_log.info('Ignored (add or remove) change in: %s', change_path) + pydev_log.info("Ignored (add or remove) change in: %s", change_path) except: - pydev_log.exception('Error when waiting for filesystem changes in FSNotifyThread.') + pydev_log.exception("Error when waiting for filesystem changes in FSNotifyThread.") @overrides(PyDBDaemonThread.do_kill_pydev_thread) def do_kill_pydev_thread(self): @@ -340,7 +361,7 @@ def do_kill_pydev_thread(self): class WriterThread(PyDBDaemonThread): - ''' writer thread writes out the commands in an infinite loop ''' + """writer thread writes out the commands in an infinite loop""" def __init__(self, sock, py_db, terminate_on_socket_close=True): PyDBDaemonThread.__init__(self, py_db) @@ -348,19 +369,19 @@ def __init__(self, sock, py_db, terminate_on_socket_close=True): self.__terminate_on_socket_close = terminate_on_socket_close self.name = "pydevd.Writer" self._cmd_queue = _queue.Queue() - if pydevd_vm_type.get_vm_type() == 'python': + if pydevd_vm_type.get_vm_type() == "python": self.timeout = 0 else: self.timeout = 0.1 def add_command(self, cmd): - ''' cmd is NetCommand ''' + """cmd is NetCommand""" if not self._kill_received: # we don't take new data after everybody die self._cmd_queue.put(cmd, False) @overrides(PyDBDaemonThread._on_run) def _on_run(self): - ''' just loop and write responses ''' + """just loop and write responses""" try: while True: @@ -369,7 +390,7 @@ def _on_run(self): cmd = self._cmd_queue.get(True, 0.1) except _queue.Empty: if self._kill_received: - pydev_log.debug('WriterThread: kill_received (sock.shutdown(SHUT_WR))') + pydev_log.debug("WriterThread: kill_received (sock.shutdown(SHUT_WR))") try: self.sock.shutdown(SHUT_WR) except: @@ -401,7 +422,7 @@ def _on_run(self): cmd.send(self.sock) if cmd.id == CMD_EXIT: - pydev_log.debug('WriterThread: CMD_EXIT received') + pydev_log.debug("WriterThread: CMD_EXIT received") break if time is None: break # interpreter shutdown @@ -412,7 +433,7 @@ def _on_run(self): if DebugInfoHolder.DEBUG_TRACE_LEVEL > 0: pydev_log_exception() finally: - pydev_log.debug('WriterThread: exit') + pydev_log.debug("WriterThread: exit") def empty(self): return self._cmd_queue.empty() @@ -445,14 +466,14 @@ def create_server_socket(host, port): def start_server(port): - ''' binds to a port, waits for the debugger to connect ''' - s = create_server_socket(host='', port=port) + """binds to a port, waits for the debugger to connect""" + s = create_server_socket(host="", port=port) try: s.listen(1) # Let the user know it's halted waiting for the connection. pydev_log.critical("pydevd: waiting for connection at: %s:%s\n", *s.getsockname()) - + new_socket, _addr = s.accept() pydev_log.info("Connection accepted") # closing server socket is not necessary but we don't need it @@ -464,7 +485,7 @@ def start_server(port): def start_client(host, port): - ''' connects to a host/port ''' + """connects to a host/port""" pydev_log.info("Connecting to %s:%s", host, port) address_family = AF_INET @@ -502,7 +523,7 @@ def start_client(host, port): try: # 10 seconds default timeout - timeout = int(os.environ.get('PYDEVD_CONNECT_TIMEOUT', 10)) + timeout = int(os.environ.get("PYDEVD_CONNECT_TIMEOUT", 10)) s.settimeout(timeout) s.connect((host, port)) s.settimeout(None) # no timeout after connected @@ -518,12 +539,12 @@ def start_client(host, port): class InternalThreadCommand(object): - ''' internal commands are generated/executed by the debugger. + """internal commands are generated/executed by the debugger. The reason for their existence is that some commands have to be executed on specific threads. These are the InternalThreadCommands that get get posted to PyDB. - ''' + """ def __init__(self, thread_id, method=None, *args, **kwargs): self.thread_id = thread_id @@ -532,9 +553,8 @@ def __init__(self, thread_id, method=None, *args, **kwargs): self.kwargs = kwargs def can_be_executed_by(self, thread_id): - '''By default, it must be in the same thread to be executed - ''' - return self.thread_id == thread_id or self.thread_id.endswith('|' + thread_id) + """By default, it must be in the same thread to be executed""" + return self.thread_id == thread_id or self.thread_id.endswith("|" + thread_id) def do_it(self, dbg): try: @@ -547,15 +567,14 @@ def do_it(self, dbg): self.kwargs = None def __str__(self): - return 'InternalThreadCommands(%s, %s, %s)' % (self.method, self.args, self.kwargs) + return "InternalThreadCommands(%s, %s, %s)" % (self.method, self.args, self.kwargs) __repr__ = __str__ class InternalThreadCommandForAnyThread(InternalThreadCommand): - def __init__(self, thread_id, method=None, *args, **kwargs): - assert thread_id == '*' + assert thread_id == "*" InternalThreadCommand.__init__(self, thread_id, method, *args, **kwargs) @@ -586,8 +605,8 @@ def internal_reload_code(dbg, seq, module_name, filename): if module_name is not None: module_name = module_name if module_name not in sys.modules: - if '.' in module_name: - new_module_name = module_name.split('.')[-1] + if "." in module_name: + new_module_name = module_name.split(".")[-1] if new_module_name in sys.modules: module_name = new_module_name @@ -599,9 +618,9 @@ def internal_reload_code(dbg, seq, module_name, filename): if filename: filename = pydevd_file_utils.normcase(filename) for module_name, module in sys.modules.copy().items(): - f = getattr_checked(module, '__file__') + f = getattr_checked(module, "__file__") if f is not None: - if f.endswith(('.pyc', '.pyo')): + if f.endswith((".pyc", ".pyo")): f = f[:-1] if pydevd_file_utils.normcase(f) == filename: @@ -609,11 +628,11 @@ def internal_reload_code(dbg, seq, module_name, filename): if not modules_to_reload: if filename and module_name: - _send_io_message(dbg, 'code reload: Unable to find module %s to reload for path: %s\n' % (module_name, filename)) + _send_io_message(dbg, "code reload: Unable to find module %s to reload for path: %s\n" % (module_name, filename)) elif filename: - _send_io_message(dbg, 'code reload: Unable to find module to reload for path: %s\n' % (filename,)) + _send_io_message(dbg, "code reload: Unable to find module to reload for path: %s\n" % (filename,)) elif module_name: - _send_io_message(dbg, 'code reload: Unable to find module to reload: %s\n' % (module_name,)) + _send_io_message(dbg, "code reload: Unable to find module to reload: %s\n" % (module_name,)) else: # Too much info... @@ -623,25 +642,25 @@ def internal_reload_code(dbg, seq, module_name, filename): found_module_to_reload = True if pydevd_reload.xreload(module): - _send_io_message(dbg, 'code reload: reload finished\n') + _send_io_message(dbg, "code reload: reload finished\n") else: - _send_io_message(dbg, 'code reload: reload finished without applying any change\n') + _send_io_message(dbg, "code reload: reload finished without applying any change\n") cmd = dbg.cmd_factory.make_reloaded_code_message(seq, found_module_to_reload) dbg.writer.add_command(cmd) except: - pydev_log.exception('Error reloading code') + pydev_log.exception("Error reloading code") class InternalGetThreadStack(InternalThreadCommand): - ''' + """ This command will either wait for a given thread to be paused to get its stack or will provide it anyways after a timeout (in which case the stack will be gotten but local variables won't be available and it'll not be possible to interact with the frame as it's not actually stopped in a breakpoint). - ''' + """ - def __init__(self, seq, thread_id, py_db, set_additional_thread_info, fmt, timeout=.5, start_frame=0, levels=0): + def __init__(self, seq, thread_id, py_db, set_additional_thread_info, fmt, timeout=0.5, start_frame=0, levels=0): InternalThreadCommand.__init__(self, thread_id) self._py_db = weakref.ref(py_db) self._timeout = time.time() + timeout @@ -662,12 +681,20 @@ def can_be_executed_by(self, _thread_id): py_db = self._py_db() t = pydevd_find_thread_by_id(self.thread_id) frame = None - if t and not getattr(t, 'pydev_do_not_trace', None): + if t and not getattr(t, "pydev_do_not_trace", None): additional_info = self._set_additional_thread_info(t) frame = additional_info.get_topmost_frame(t) try: self._cmd = py_db.cmd_factory.make_get_thread_stack_message( - py_db, self.seq, self.thread_id, frame, self._fmt, must_be_suspended=not timed_out, start_frame=self._start_frame, levels=self._levels) + py_db, + self.seq, + self.thread_id, + frame, + self._fmt, + must_be_suspended=not timed_out, + start_frame=self._start_frame, + levels=self._levels, + ) finally: frame = None t = None @@ -692,7 +719,7 @@ def internal_step_in_thread(py_db, thread_id, cmd_id, set_additional_thread_info info.update_stepping_info() if py_db.stepping_resumes_all_threads: - resume_threads('*', except_thread=thread_to_step) + resume_threads("*", except_thread=thread_to_step) def internal_smart_step_into(py_db, thread_id, offset, child_offset, set_additional_thread_info): @@ -708,19 +735,18 @@ def internal_smart_step_into(py_db, thread_id, offset, child_offset, set_additio info.update_stepping_info() if py_db.stepping_resumes_all_threads: - resume_threads('*', except_thread=thread_to_step) + resume_threads("*", except_thread=thread_to_step) class InternalSetNextStatementThread(InternalThreadCommand): - def __init__(self, thread_id, cmd_id, line, func_name, seq=0): - ''' + """ cmd_id may actually be one of: CMD_RUN_TO_LINE CMD_SET_NEXT_STATEMENT CMD_SMART_STEP_INTO - ''' + """ self.thread_id = thread_id self.cmd_id = cmd_id self.line = line @@ -746,9 +772,9 @@ def do_it(self, dbg): @silence_warnings_decorator def internal_get_variable_json(py_db, request): - ''' - :param VariablesRequest request: - ''' + """ + :param VariablesRequest request: + """ arguments = request.arguments # : :type arguments: VariablesArguments variables_reference = arguments.variablesReference scope = None @@ -757,7 +783,7 @@ def internal_get_variable_json(py_db, request): variables_reference = variables_reference.variable_reference fmt = arguments.format - if hasattr(fmt, 'to_dict'): + if hasattr(fmt, "to_dict"): fmt = fmt.to_dict() variables = [] @@ -772,25 +798,20 @@ def internal_get_variable_json(py_db, request): except: try: exc, exc_type, tb = sys.exc_info() - err = ''.join(traceback.format_exception(exc, exc_type, tb)) - variables = [{ - 'name': '', - 'value': err, - 'type': '', - 'variablesReference': 0 - }] + err = "".join(traceback.format_exception(exc, exc_type, tb)) + variables = [{"name": "", "value": err, "type": "", "variablesReference": 0}] except: - err = '' + err = "" pydev_log.exception(err) variables = [] body = VariablesResponseBody(variables) - variables_response = pydevd_base_schema.build_response(request, kwargs={'body':body}) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True)) class InternalGetVariable(InternalThreadCommand): - ''' gets the value of a variable ''' + """gets the value of a variable""" def __init__(self, seq, thread_id, frame_id, scope, attrs): self.sequence = seq @@ -801,12 +822,13 @@ def __init__(self, seq, thread_id, frame_id, scope, attrs): @silence_warnings_decorator def do_it(self, dbg): - ''' Converts request into python variable ''' + """Converts request into python variable""" try: xml = StringIO() xml.write("") type_name, val_dict = pydevd_vars.resolve_compound_variable_fields( - dbg, self.thread_id, self.frame_id, self.scope, self.attributes) + dbg, self.thread_id, self.frame_id, self.scope, self.attributes + ) if val_dict is None: val_dict = {} @@ -828,13 +850,11 @@ def do_it(self, dbg): xml.close() dbg.writer.add_command(cmd) except Exception: - cmd = dbg.cmd_factory.make_error_message( - self.sequence, "Error resolving variables %s" % (get_exception_traceback_str(),)) + cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error resolving variables %s" % (get_exception_traceback_str(),)) dbg.writer.add_command(cmd) class InternalGetArray(InternalThreadCommand): - def __init__(self, seq, roffset, coffset, rows, cols, format, thread_id, frame_id, scope, attrs): self.sequence = seq self.thread_id = thread_id @@ -861,7 +881,7 @@ def do_it(self, dbg): def internal_change_variable(dbg, seq, thread_id, frame_id, scope, attr, value): - ''' Changes the value of a variable ''' + """Changes the value of a variable""" try: frame = dbg.find_frame(thread_id, frame_id) if frame is not None: @@ -874,18 +894,20 @@ def internal_change_variable(dbg, seq, thread_id, frame_id, scope, attr, value): cmd = dbg.cmd_factory.make_variable_changed_message(seq, xml) dbg.writer.add_command(cmd) except Exception: - cmd = dbg.cmd_factory.make_error_message(seq, "Error changing variable attr:%s expression:%s traceback:%s" % (attr, value, get_exception_traceback_str())) + cmd = dbg.cmd_factory.make_error_message( + seq, "Error changing variable attr:%s expression:%s traceback:%s" % (attr, value, get_exception_traceback_str()) + ) dbg.writer.add_command(cmd) def internal_change_variable_json(py_db, request): - ''' + """ The pydevd_vars.change_attr_expression(thread_id, frame_id, attr, value, dbg) can only deal with changing at a frame level, so, currently changing the contents of something in a different scope is currently not supported. :param SetVariableRequest request: - ''' + """ # : :type arguments: SetVariableArguments arguments = request.arguments variables_reference = arguments.variablesReference @@ -895,7 +917,7 @@ def internal_change_variable_json(py_db, request): variables_reference = variables_reference.variable_reference fmt = arguments.format - if hasattr(fmt, 'to_dict'): + if hasattr(fmt, "to_dict"): fmt = fmt.to_dict() try: @@ -905,44 +927,38 @@ def internal_change_variable_json(py_db, request): if variable is None: _write_variable_response( - py_db, request, value='', success=False, message='Unable to find variable container to change: %s.' % (variables_reference,)) + py_db, request, value="", success=False, message="Unable to find variable container to change: %s." % (variables_reference,) + ) return child_var = variable.change_variable(arguments.name, arguments.value, py_db, fmt=fmt) if child_var is None: - _write_variable_response( - py_db, request, value='', success=False, message='Unable to change: %s.' % (arguments.name,)) + _write_variable_response(py_db, request, value="", success=False, message="Unable to change: %s." % (arguments.name,)) return var_data = child_var.get_var_data(fmt=fmt) body = SetVariableResponseBody( - value=var_data['value'], - type=var_data['type'], - variablesReference=var_data.get('variablesReference'), - namedVariables=var_data.get('namedVariables'), - indexedVariables=var_data.get('indexedVariables'), + value=var_data["value"], + type=var_data["type"], + variablesReference=var_data.get("variablesReference"), + namedVariables=var_data.get("namedVariables"), + indexedVariables=var_data.get("indexedVariables"), ) - variables_response = pydevd_base_schema.build_response(request, kwargs={'body':body}) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True)) def _write_variable_response(py_db, request, value, success, message): - body = SetVariableResponseBody('') - variables_response = pydevd_base_schema.build_response( - request, - kwargs={ - 'body':body, - 'success': False, - 'message': message - }) + body = SetVariableResponseBody("") + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body, "success": False, "message": message}) cmd = NetCommand(CMD_RETURN, 0, variables_response, is_json=True) py_db.writer.add_command(cmd) @silence_warnings_decorator def internal_get_frame(dbg, seq, thread_id, frame_id): - ''' Converts request into python variable ''' + """Converts request into python variable""" try: frame = dbg.find_frame(thread_id, frame_id) if frame is not None: @@ -989,27 +1005,33 @@ def internal_get_smart_step_into_variants(dbg, seq, thread_id, frame_id, start_l for child_variant in variant.children_variants: # If there are child variants, the current one is just an intermediary, so, # just create variants for the child (notifying properly about the parent too). - xml += '' % ( - quote(child_variant.name), - str(child_variant.is_visited).lower(), - child_variant.line, + xml += ( + '' + % ( + quote(child_variant.name), + str(child_variant.is_visited).lower(), + child_variant.line, + variant.offset, + child_variant.offset, + child_variant.call_order, + variant.endlineno, + variant.startcol, + variant.endcol, + ) + ) + else: + xml += ( + '' + % ( + quote(variant.name), + str(variant.is_visited).lower(), + variant.line, variant.offset, - child_variant.offset, - child_variant.call_order, + variant.call_order, variant.endlineno, variant.startcol, variant.endcol, ) - else: - xml += '' % ( - quote(variant.name), - str(variant.is_visited).lower(), - variant.line, - variant.offset, - variant.call_order, - variant.endlineno, - variant.startcol, - variant.endcol, ) xml += "" @@ -1017,10 +1039,10 @@ def internal_get_smart_step_into_variants(dbg, seq, thread_id, frame_id, start_l dbg.writer.add_command(cmd) except: # Error is expected (if `dis` module cannot be used -- i.e.: Jython). - pydev_log.exception('Error calculating Smart Step Into Variants.') + pydev_log.exception("Error calculating Smart Step Into Variants.") cmd = dbg.cmd_factory.make_error_message( - seq, "Error getting smart step into variants for frame: %s from thread: %s" - % (frame_id, thread_id)) + seq, "Error getting smart step into variants for frame: %s from thread: %s" % (frame_id, thread_id) + ) dbg.writer.add_command(cmd) @@ -1032,12 +1054,8 @@ def internal_get_step_in_targets_json(dbg, seq, thread_id, frame_id, request, se if thread is None or frame is None: body = StepInTargetsResponseBody([]) variables_response = pydevd_base_schema.build_response( - request, - kwargs={ - 'body': body, - 'success': False, - 'message': 'Thread to get step in targets seems to have resumed already.' - }) + request, kwargs={"body": body, "success": False, "message": "Thread to get step in targets seems to have resumed already."} + ) cmd = NetCommand(CMD_RETURN, 0, variables_response, is_json=True) dbg.writer.add_command(cmd) return @@ -1060,7 +1078,12 @@ def internal_get_step_in_targets_json(dbg, seq, thread_id, frame_id, request, se target_id = next(counter) if child_variant.call_order > 1: - targets.append(StepInTarget(id=target_id, label='%s (call %s)' % (child_variant.name, child_variant.call_order),)) + targets.append( + StepInTarget( + id=target_id, + label="%s (call %s)" % (child_variant.name, child_variant.call_order), + ) + ) else: targets.append(StepInTarget(id=target_id, label=child_variant.name)) target_id_to_variant[target_id] = child_variant @@ -1070,7 +1093,12 @@ def internal_get_step_in_targets_json(dbg, seq, thread_id, frame_id, request, se else: target_id = next(counter) if variant.call_order > 1: - targets.append(StepInTarget(id=target_id, label='%s (call %s)' % (variant.name, variant.call_order),)) + targets.append( + StepInTarget( + id=target_id, + label="%s (call %s)" % (variant.name, variant.call_order), + ) + ) else: targets.append(StepInTarget(id=target_id, label=variant.name)) target_id_to_variant[target_id] = variant @@ -1083,26 +1111,20 @@ def internal_get_step_in_targets_json(dbg, seq, thread_id, frame_id, request, se info.target_id_to_smart_step_into_variant = target_id_to_variant body = StepInTargetsResponseBody(targets=targets) - response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + response = pydevd_base_schema.build_response(request, kwargs={"body": body}) cmd = NetCommand(CMD_RETURN, 0, response, is_json=True) dbg.writer.add_command(cmd) except Exception as e: # Error is expected (if `dis` module cannot be used -- i.e.: Jython). - pydev_log.exception('Error calculating Smart Step Into Variants.') + pydev_log.exception("Error calculating Smart Step Into Variants.") body = StepInTargetsResponseBody([]) - variables_response = pydevd_base_schema.build_response( - request, - kwargs={ - 'body': body, - 'success': False, - 'message': str(e) - }) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body, "success": False, "message": str(e)}) cmd = NetCommand(CMD_RETURN, 0, variables_response, is_json=True) dbg.writer.add_command(cmd) def internal_get_next_statement_targets(dbg, seq, thread_id, frame_id): - ''' gets the valid line numbers for use with set next statement ''' + """gets the valid line numbers for use with set next statement""" try: frame = dbg.find_frame(thread_id, frame_id) if frame is not None: @@ -1128,18 +1150,17 @@ def internal_get_next_statement_targets(dbg, seq, thread_id, frame_id): dbg.writer.add_command(cmd) -def _evaluate_response(py_db, request, result, error_message=''): +def _evaluate_response(py_db, request, result, error_message=""): is_error = isinstance(result, ExceptionOnEvaluate) if is_error: result = result.result if not error_message: body = pydevd_schema.EvaluateResponseBody(result=result, variablesReference=0) - variables_response = pydevd_base_schema.build_response(request, kwargs={'body':body}) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True)) else: body = pydevd_schema.EvaluateResponseBody(result=result, variablesReference=0) - variables_response = pydevd_base_schema.build_response(request, kwargs={ - 'body':body, 'success':False, 'message': error_message}) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body, "success": False, "message": error_message}) py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True)) @@ -1147,9 +1168,9 @@ def _evaluate_response(py_db, request, result, error_message=''): def internal_evaluate_expression_json(py_db, request, thread_id): - ''' + """ :param EvaluateRequest request: - ''' + """ global _global_frame # : :type arguments: EvaluateArguments @@ -1158,11 +1179,11 @@ def internal_evaluate_expression_json(py_db, request, thread_id): frame_id = arguments.frameId context = arguments.context fmt = arguments.format - if hasattr(fmt, 'to_dict'): + if hasattr(fmt, "to_dict"): fmt = fmt.to_dict() ctx = NULL - if context == 'repl': + if context == "repl": if not py_db.is_output_redirected: ctx = pydevd_io.redirect_stream_to_pydb_io_messages_context() else: @@ -1189,14 +1210,16 @@ def __create_frame(): eval_result = pydevd_vars.evaluate_expression(py_db, frame, expression, is_exec=False) is_error = isinstance_checked(eval_result, ExceptionOnEvaluate) if is_error: - if context == 'hover': # In a hover it doesn't make sense to do an exec. - _evaluate_response(py_db, request, result='', error_message='Exception occurred during evaluation.') + if context == "hover": # In a hover it doesn't make sense to do an exec. + _evaluate_response(py_db, request, result="", error_message="Exception occurred during evaluation.") return - elif context == 'watch': + elif context == "watch": # If it's a watch, don't show it as an exception object, rather, format # it and show it as a string (with success=False). - msg = '%s: %s' % ( - eval_result.result.__class__.__name__, eval_result.result,) + msg = "%s: %s" % ( + eval_result.result.__class__.__name__, + eval_result.result, + ) _evaluate_response(py_db, request, result=msg, error_message=msg) return else: @@ -1205,10 +1228,10 @@ def __create_frame(): try: pydevd_vars.compile_as_eval(expression) except Exception: - try_exec = context == 'repl' + try_exec = context == "repl" else: try_exec = False - if context == 'repl': + if context == "repl": # In the repl we should show the exception to the user. _evaluate_response_return_exception(py_db, request, eval_result.etype, eval_result.result, eval_result.tb) return @@ -1220,29 +1243,29 @@ def __create_frame(): _evaluate_response_return_exception(py_db, request, *sys.exc_info()) return # No result on exec. - _evaluate_response(py_db, request, result='') + _evaluate_response(py_db, request, result="") return # Ok, we have the result (could be an error), let's put it into the saved variables. frame_tracker = py_db.suspended_frames_manager.get_frame_tracker(thread_id) if frame_tracker is None: # This is not really expected. - _evaluate_response(py_db, request, result='', error_message='Thread id: %s is not current thread id.' % (thread_id,)) + _evaluate_response(py_db, request, result="", error_message="Thread id: %s is not current thread id." % (thread_id,)) return safe_repr_custom_attrs = {} - if context == 'clipboard': + if context == "clipboard": safe_repr_custom_attrs = dict( - maxstring_outer=2 ** 64, - maxstring_inner=2 ** 64, - maxother_outer=2 ** 64, - maxother_inner=2 ** 64, + maxstring_outer=2**64, + maxstring_inner=2**64, + maxother_outer=2**64, + maxother_inner=2**64, ) - if context == 'repl' and eval_result is None: + if context == "repl" and eval_result is None: # We don't want "None" to appear when typing in the repl. body = pydevd_schema.EvaluateResponseBody( - result='', + result="", variablesReference=0, ) @@ -1251,14 +1274,14 @@ def __create_frame(): var_data = variable.get_var_data(fmt=fmt, context=context, **safe_repr_custom_attrs) body = pydevd_schema.EvaluateResponseBody( - result=var_data['value'], - variablesReference=var_data.get('variablesReference', 0), - type=var_data.get('type'), - presentationHint=var_data.get('presentationHint'), - namedVariables=var_data.get('namedVariables'), - indexedVariables=var_data.get('indexedVariables'), + result=var_data["value"], + variablesReference=var_data.get("variablesReference", 0), + type=var_data.get("type"), + presentationHint=var_data.get("presentationHint"), + namedVariables=var_data.get("namedVariables"), + indexedVariables=var_data.get("indexedVariables"), ) - variables_response = pydevd_base_schema.build_response(request, kwargs={'body':body}) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True)) @@ -1275,7 +1298,7 @@ def _evaluate_response_return_exception(py_db, request, exc_type, exc, initial_t if tb is None: tb = initial_tb - err = ''.join(traceback.format_exception(exc_type, exc, tb)) + err = "".join(traceback.format_exception(exc_type, exc, tb)) # Make sure we don't keep references to them. exc = None @@ -1284,7 +1307,7 @@ def _evaluate_response_return_exception(py_db, request, exc_type, exc, initial_t temp_tb = None initial_tb = None except: - err = '' + err = "" pydev_log.exception(err) # Currently there is an issue in VSC where returning success=false for an @@ -1295,7 +1318,7 @@ def _evaluate_response_return_exception(py_db, request, exc_type, exc, initial_t @silence_warnings_decorator def internal_evaluate_expression(dbg, seq, thread_id, frame_id, expression, is_exec, trim_if_too_big, attr_to_set_result): - ''' gets the value of a variable ''' + """gets the value of a variable""" try: frame = dbg.find_frame(thread_id, frame_id) if frame is not None: @@ -1317,9 +1340,8 @@ def internal_evaluate_expression(dbg, seq, thread_id, frame_id, expression, is_e def _set_expression_response(py_db, request, result, error_message): - body = pydevd_schema.SetExpressionResponseBody(result='', variablesReference=0) - variables_response = pydevd_base_schema.build_response(request, kwargs={ - 'body':body, 'success':False, 'message': error_message}) + body = pydevd_schema.SetExpressionResponseBody(result="", variablesReference=0) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body, "success": False, "message": error_message}) py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True)) @@ -1331,23 +1353,23 @@ def internal_set_expression_json(py_db, request, thread_id): frame_id = arguments.frameId value = arguments.value fmt = arguments.format - if hasattr(fmt, 'to_dict'): + if hasattr(fmt, "to_dict"): fmt = fmt.to_dict() frame = py_db.find_frame(thread_id, frame_id) - exec_code = '%s = (%s)' % (expression, value) + exec_code = "%s = (%s)" % (expression, value) result = pydevd_vars.evaluate_expression(py_db, frame, exec_code, is_exec=True) is_error = isinstance(result, ExceptionOnEvaluate) if is_error: - _set_expression_response(py_db, request, result, error_message='Error executing: %s' % (exec_code,)) + _set_expression_response(py_db, request, result, error_message="Error executing: %s" % (exec_code,)) return # Ok, we have the result (could be an error), let's put it into the saved variables. frame_tracker = py_db.suspended_frames_manager.get_frame_tracker(thread_id) if frame_tracker is None: # This is not really expected. - _set_expression_response(py_db, request, result, error_message='Thread id: %s is not current thread id.' % (thread_id,)) + _set_expression_response(py_db, request, result, error_message="Thread id: %s is not current thread id." % (thread_id,)) return # Now that the exec is done, get the actual value changed to return. @@ -1356,31 +1378,31 @@ def internal_set_expression_json(py_db, request, thread_id): var_data = variable.get_var_data(fmt=fmt) body = pydevd_schema.SetExpressionResponseBody( - value=var_data['value'], - variablesReference=var_data.get('variablesReference', 0), - type=var_data.get('type'), - presentationHint=var_data.get('presentationHint'), - namedVariables=var_data.get('namedVariables'), - indexedVariables=var_data.get('indexedVariables'), + value=var_data["value"], + variablesReference=var_data.get("variablesReference", 0), + type=var_data.get("type"), + presentationHint=var_data.get("presentationHint"), + namedVariables=var_data.get("namedVariables"), + indexedVariables=var_data.get("indexedVariables"), ) - variables_response = pydevd_base_schema.build_response(request, kwargs={'body':body}) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) py_db.writer.add_command(NetCommand(CMD_RETURN, 0, variables_response, is_json=True)) def internal_get_completions(dbg, seq, thread_id, frame_id, act_tok, line=-1, column=-1): - ''' + """ Note that if the column is >= 0, the act_tok is considered text and the actual activation token/qualifier is computed in this command. - ''' + """ try: remove_path = None try: - qualifier = '' + qualifier = "" if column >= 0: token_and_qualifier = extract_token_and_qualifier(act_tok, line, column) act_tok = token_and_qualifier[0] if act_tok: - act_tok += '.' + act_tok += "." qualifier = token_and_qualifier[1] frame = dbg.find_frame(thread_id, frame_id) @@ -1390,11 +1412,12 @@ def internal_get_completions(dbg, seq, thread_id, frame_id, act_tok, line=-1, co # Note that qualifier and start are only actually valid for the # Debug Adapter Protocol (for the line-based protocol, the IDE # is required to filter the completions returned). - cmd = dbg.cmd_factory.make_get_completions_message( - seq, completions, qualifier, start=column - len(qualifier)) + cmd = dbg.cmd_factory.make_get_completions_message(seq, completions, qualifier, start=column - len(qualifier)) dbg.writer.add_command(cmd) else: - cmd = dbg.cmd_factory.make_error_message(seq, "internal_get_completions: Frame not found: %s from thread: %s" % (frame_id, thread_id)) + cmd = dbg.cmd_factory.make_error_message( + seq, "internal_get_completions: Frame not found: %s from thread: %s" % (frame_id, thread_id) + ) dbg.writer.add_command(cmd) finally: @@ -1403,18 +1426,17 @@ def internal_get_completions(dbg, seq, thread_id, frame_id, act_tok, line=-1, co except: exc = get_exception_traceback_str() - sys.stderr.write('%s\n' % (exc,)) + sys.stderr.write("%s\n" % (exc,)) cmd = dbg.cmd_factory.make_error_message(seq, "Error evaluating expression " + exc) dbg.writer.add_command(cmd) def internal_get_description(dbg, seq, thread_id, frame_id, expression): - ''' Fetch the variable description stub from the debug console - ''' + """Fetch the variable description stub from the debug console""" try: frame = dbg.find_frame(thread_id, frame_id) description = pydevd_console.get_description(frame, thread_id, frame_id, expression) - description = pydevd_xml.make_valid_xml_value(quote(description, '/>_= \t')) + description = pydevd_xml.make_valid_xml_value(quote(description, "/>_= \t")) description_xml = '' % description cmd = dbg.cmd_factory.make_get_description_message(seq, description_xml) dbg.writer.add_command(cmd) @@ -1425,15 +1447,15 @@ def internal_get_description(dbg, seq, thread_id, frame_id, expression): def build_exception_info_response(dbg, thread_id, thread, request_seq, set_additional_thread_info, iter_visible_frames_info, max_frames): - ''' + """ :return ExceptionInfoResponse - ''' + """ additional_info = set_additional_thread_info(thread) topmost_frame = additional_info.get_topmost_frame(thread) - current_paused_frame_name = '' + current_paused_frame_name = "" - source_path = '' # This is an extra bit of data used by Visual Studio + source_path = "" # This is an extra bit of data used by Visual Studio stack_str_lst = [] name = None description = None @@ -1469,19 +1491,27 @@ def build_exception_info_response(dbg, thread_id, thread, request_seq, set_addit except: pass - for frame_id, frame, method_name, original_filename, filename_in_utf8, lineno, _applied_mapping, show_as_current_frame, line_col_info in \ - iter_visible_frames_info(dbg, frames_list): - + for ( + frame_id, + frame, + method_name, + original_filename, + filename_in_utf8, + lineno, + _applied_mapping, + show_as_current_frame, + line_col_info, + ) in iter_visible_frames_info(dbg, frames_list): line_text = linecache.getline(original_filename, lineno) # Never filter out plugin frames! - if not getattr(frame, 'IS_PLUGIN_FRAME', False): + if not getattr(frame, "IS_PLUGIN_FRAME", False): if dbg.is_files_filter_enabled and dbg.apply_files_filter(frame, original_filename, False): continue if show_as_current_frame: current_paused_frame_name = method_name - method_name += ' (Current frame)' + method_name += " (Current frame)" frames.append((filename_in_utf8, lineno, method_name, line_text, line_col_info)) if not source_path and frames: @@ -1497,11 +1527,11 @@ def build_exception_info_response(dbg, thread_id, thread, request_seq, set_addit frame_summary.end_colno = line_col_info.end_colno stack_summary.append(frame_summary) - stack_str = ''.join(stack_summary.format()) + stack_str = "".join(stack_summary.format()) else: # Note: remove col info (just used in 3.11). - stack_str = ''.join(traceback.format_list((x[:-1] for x in frames[-max_frames:]))) + stack_str = "".join(traceback.format_list((x[:-1] for x in frames[-max_frames:]))) try: stype = frames_list.exc_type.__qualname__ @@ -1509,12 +1539,12 @@ def build_exception_info_response(dbg, thread_id, thread, request_seq, set_addit if smod not in ("__main__", "builtins"): if not isinstance(smod, str): smod = "" - stype = smod + '.' + stype + stype = smod + "." + stype except Exception: - stype = '' - pydev_log.exception('Error getting exception type.') + stype = "" + pydev_log.exception("Error getting exception type.") - stack_str += '%s: %s\n' % (stype, frames_list.exc_desc) + stack_str += "%s: %s\n" % (stype, frames_list.exc_desc) stack_str += frames_list.exc_context_msg stack_str_lst.append(stack_str) @@ -1523,18 +1553,18 @@ def build_exception_info_response(dbg, thread_id, thread, request_seq, set_addit break except: - pydev_log.exception('Error on build_exception_info_response.') + pydev_log.exception("Error on build_exception_info_response.") finally: topmost_frame = None - full_stack_str = ''.join(reversed(stack_str_lst)) + full_stack_str = "".join(reversed(stack_str_lst)) if not name: - name = 'exception: type unknown' + name = "exception: type unknown" if not description: - description = 'exception: no description' + description = "exception: no description" if current_paused_frame_name: - name += ' (note: full exception trace is shown but execution is paused at: %s)' % (current_paused_frame_name,) + name += " (note: full exception trace is shown but execution is paused at: %s)" % (current_paused_frame_name,) if thread.stop_reason == CMD_STEP_CAUGHT_EXCEPTION: break_mode = pydevd_schema.ExceptionBreakMode.ALWAYS @@ -1544,7 +1574,7 @@ def build_exception_info_response(dbg, thread_id, thread, request_seq, set_addit response = pydevd_schema.ExceptionInfoResponse( request_seq=request_seq, success=True, - command='exceptionInfo', + command="exceptionInfo", body=pydevd_schema.ExceptionInfoResponseBody( exceptionId=name, description=description, @@ -1556,29 +1586,28 @@ def build_exception_info_response(dbg, thread_id, thread, request_seq, set_addit source=source_path, # Note: ExceptionDetails actually accepts an 'innerException', but # when passing it, VSCode is not showing the stack trace at all. - ) - ) + ), + ), ) return response -def internal_get_exception_details_json(dbg, request, thread_id, thread, max_frames, set_additional_thread_info=None, iter_visible_frames_info=None): - ''' Fetch exception details - ''' +def internal_get_exception_details_json( + dbg, request, thread_id, thread, max_frames, set_additional_thread_info=None, iter_visible_frames_info=None +): + """Fetch exception details""" try: - response = build_exception_info_response(dbg, thread_id, thread, request.seq, set_additional_thread_info, iter_visible_frames_info, max_frames) + response = build_exception_info_response( + dbg, thread_id, thread, request.seq, set_additional_thread_info, iter_visible_frames_info, max_frames + ) except: exc = get_exception_traceback_str() - response = pydevd_base_schema.build_response(request, kwargs={ - 'success': False, - 'message': exc, - 'body':{} - }) + response = pydevd_base_schema.build_response(request, kwargs={"success": False, "message": exc, "body": {}}) dbg.writer.add_command(NetCommand(CMD_RETURN, 0, response, is_json=True)) class InternalGetBreakpointException(InternalThreadCommand): - ''' Send details of exception raised while evaluating conditional breakpoint ''' + """Send details of exception raised while evaluating conditional breakpoint""" def __init__(self, thread_id, exc_type, stacktrace): self.sequence = 0 @@ -1598,27 +1627,31 @@ def do_it(self, dbg): # convert it to utf8 filename = filename.decode(file_system_encoding).encode("utf-8") - callstack += '' \ - % (self.thread_id, makeValid(filename), line, makeValid(methodname), makeValid(methodobj)) + callstack += '' % ( + self.thread_id, + makeValid(filename), + line, + makeValid(methodname), + makeValid(methodobj), + ) callstack += "" cmd = dbg.cmd_factory.make_send_breakpoint_exception_message(self.sequence, self.exc_type + "\t" + callstack) dbg.writer.add_command(cmd) except: exc = get_exception_traceback_str() - sys.stderr.write('%s\n' % (exc,)) + sys.stderr.write("%s\n" % (exc,)) cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error Sending Exception: " + exc) dbg.writer.add_command(cmd) class InternalSendCurrExceptionTrace(InternalThreadCommand): - ''' Send details of the exception that was caught and where we've broken in. - ''' + """Send details of the exception that was caught and where we've broken in.""" def __init__(self, thread_id, arg, curr_frame_id): - ''' + """ :param arg: exception type, description, traceback object - ''' + """ self.sequence = 0 self.thread_id = thread_id self.curr_frame_id = curr_frame_id @@ -1631,14 +1664,13 @@ def do_it(self, dbg): dbg.writer.add_command(cmd) except: exc = get_exception_traceback_str() - sys.stderr.write('%s\n' % (exc,)) + sys.stderr.write("%s\n" % (exc,)) cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error Sending Current Exception Trace: " + exc) dbg.writer.add_command(cmd) class InternalSendCurrExceptionTraceProceeded(InternalThreadCommand): - ''' Send details of the exception that was caught and where we've broken in. - ''' + """Send details of the exception that was caught and where we've broken in.""" def __init__(self, thread_id): self.sequence = 0 @@ -1650,13 +1682,13 @@ def do_it(self, dbg): dbg.writer.add_command(cmd) except: exc = get_exception_traceback_str() - sys.stderr.write('%s\n' % (exc,)) + sys.stderr.write("%s\n" % (exc,)) cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error Sending Current Exception Trace Proceeded: " + exc) dbg.writer.add_command(cmd) class InternalEvaluateConsoleExpression(InternalThreadCommand): - ''' Execute the given command in the debug console ''' + """Execute the given command in the debug console""" def __init__(self, seq, thread_id, frame_id, line, buffer_output=True): self.sequence = seq @@ -1666,22 +1698,24 @@ def __init__(self, seq, thread_id, frame_id, line, buffer_output=True): self.buffer_output = buffer_output def do_it(self, dbg): - ''' Create an XML for console output, error and more (true/false) + """Create an XML for console output, error and more (true/false) true/false - ''' + """ try: frame = dbg.find_frame(self.thread_id, self.frame_id) if frame is not None: console_message = pydevd_console.execute_console_command( - frame, self.thread_id, self.frame_id, self.line, self.buffer_output) + frame, self.thread_id, self.frame_id, self.line, self.buffer_output + ) cmd = dbg.cmd_factory.make_send_console_message(self.sequence, console_message.to_xml()) else: from _pydevd_bundle.pydevd_console import ConsoleMessage + console_message = ConsoleMessage() console_message.add_console_message( pydevd_console.CONSOLE_ERROR, @@ -1695,8 +1729,7 @@ def do_it(self, dbg): class InternalRunCustomOperation(InternalThreadCommand): - ''' Run a custom command on an expression - ''' + """Run a custom command on an expression""" def __init__(self, seq, thread_id, frame_id, scope, attrs, style, encoded_code_or_file, fnname): self.sequence = seq @@ -1710,8 +1743,9 @@ def __init__(self, seq, thread_id, frame_id, scope, attrs, style, encoded_code_o def do_it(self, dbg): try: - res = pydevd_vars.custom_operation(dbg, self.thread_id, self.frame_id, self.scope, self.attrs, - self.style, self.code_or_file, self.fnname) + res = pydevd_vars.custom_operation( + dbg, self.thread_id, self.frame_id, self.scope, self.attrs, self.style, self.code_or_file, self.fnname + ) resEncoded = quote_plus(res) cmd = dbg.cmd_factory.make_custom_operation_message(self.sequence, resEncoded) dbg.writer.add_command(cmd) @@ -1722,8 +1756,7 @@ def do_it(self, dbg): class InternalConsoleGetCompletions(InternalThreadCommand): - ''' Fetch the completions in the debug console - ''' + """Fetch the completions in the debug console""" def __init__(self, seq, thread_id, frame_id, act_tok): self.sequence = seq @@ -1732,8 +1765,7 @@ def __init__(self, seq, thread_id, frame_id, act_tok): self.act_tok = act_tok def do_it(self, dbg): - ''' Get completions and write back to the client - ''' + """Get completions and write back to the client""" try: frame = dbg.find_frame(self.thread_id, self.frame_id) completions_xml = pydevd_console.get_completions(frame, self.act_tok) @@ -1746,7 +1778,7 @@ def do_it(self, dbg): class InternalConsoleExec(InternalThreadCommand): - ''' gets the value of a variable ''' + """gets the value of a variable""" def __init__(self, seq, thread_id, frame_id, expression): self.sequence = seq @@ -1757,6 +1789,7 @@ def __init__(self, seq, thread_id, frame_id, expression): def init_matplotlib_in_debug_console(self, py_db): # import hook and patches for matplotlib support in debug console from _pydev_bundle.pydev_import_hook import import_hook_manager + if is_current_thread_main_thread(): for module in list(py_db.mpl_modules_for_patching): import_hook_manager.add_module_name(module, py_db.mpl_modules_for_patching.pop(module)) @@ -1784,7 +1817,7 @@ def do_it(self, py_db): py_db.writer.add_command(cmd) except: exc = get_exception_traceback_str() - sys.stderr.write('%s\n' % (exc,)) + sys.stderr.write("%s\n" % (exc,)) cmd = py_db.cmd_factory.make_error_message(self.sequence, "Error evaluating console expression " + exc) py_db.writer.add_command(cmd) finally: @@ -1795,9 +1828,9 @@ def do_it(self, py_db): class InternalLoadFullValue(InternalThreadCommand): - ''' + """ Loads values asynchronously - ''' + """ def __init__(self, seq, thread_id, frame_id, vars): self.sequence = seq @@ -1807,14 +1840,14 @@ def __init__(self, seq, thread_id, frame_id, vars): @silence_warnings_decorator def do_it(self, dbg): - '''Starts a thread that will load values asynchronously''' + """Starts a thread that will load values asynchronously""" try: var_objects = [] for variable in self.vars: variable = variable.strip() if len(variable) > 0: - if '\t' in variable: # there are attributes beyond scope - scope, attrs = variable.split('\t', 1) + if "\t" in variable: # there are attributes beyond scope + scope, attrs = variable.split("\t", 1) name = attrs[0] else: scope, attrs = (variable, None) @@ -1826,15 +1859,15 @@ def do_it(self, dbg): t.start() except: exc = get_exception_traceback_str() - sys.stderr.write('%s\n' % (exc,)) + sys.stderr.write("%s\n" % (exc,)) cmd = dbg.cmd_factory.make_error_message(self.sequence, "Error evaluating variable %s " % exc) dbg.writer.add_command(cmd) class AbstractGetValueAsyncThread(PyDBDaemonThread): - ''' + """ Abstract class for a thread, which evaluates values for async variables - ''' + """ def __init__(self, py_db, frame_accessor, seq, var_objects): PyDBDaemonThread.__init__(self, py_db) @@ -1851,7 +1884,7 @@ def _on_run(self): start = time.time() xml = StringIO() xml.write("") - for (var_obj, name) in self.var_objs: + for var_obj, name in self.var_objs: current_time = time.time() if current_time - start > ASYNC_EVAL_TIMEOUT_SEC or self.cancel_event.is_set(): break @@ -1862,10 +1895,10 @@ def _on_run(self): class GetValueAsyncThreadDebug(AbstractGetValueAsyncThread): - ''' + """ A thread for evaluation async values, which returns result for debugger Create message and send it via writer thread - ''' + """ def send_result(self, xml): if self.frame_accessor is not None: @@ -1874,12 +1907,11 @@ def send_result(self, xml): class GetValueAsyncThreadConsole(AbstractGetValueAsyncThread): - ''' + """ A thread for evaluation async values, which returns result for Console Send result directly to Console's server - ''' + """ def send_result(self, xml): if self.frame_accessor is not None: self.frame_accessor.ReturnFullValue(self.seq, xml.getvalue()) - diff --git a/_pydevd_bundle/pydevd_comm_constants.py b/_pydevd_bundle/pydevd_comm_constants.py index ad05a3250..7de3d8ef8 100644 --- a/_pydevd_bundle/pydevd_comm_constants.py +++ b/_pydevd_bundle/pydevd_comm_constants.py @@ -110,99 +110,91 @@ VERSION_STRING = "@@BUILD_NUMBER@@" from _pydev_bundle._pydev_filesystem_encoding import getfilesystemencoding + file_system_encoding = getfilesystemencoding() -filesystem_encoding_is_utf8 = file_system_encoding.lower() in ('utf-8', 'utf_8', 'utf8') +filesystem_encoding_is_utf8 = file_system_encoding.lower() in ("utf-8", "utf_8", "utf8") ID_TO_MEANING = { - '101': 'CMD_RUN', - '102': 'CMD_LIST_THREADS', - '103': 'CMD_THREAD_CREATE', - '104': 'CMD_THREAD_KILL', - '105': 'CMD_THREAD_SUSPEND', - '106': 'CMD_THREAD_RUN', - '107': 'CMD_STEP_INTO', - '108': 'CMD_STEP_OVER', - '109': 'CMD_STEP_RETURN', - '110': 'CMD_GET_VARIABLE', - '111': 'CMD_SET_BREAK', - '112': 'CMD_REMOVE_BREAK', - '113': 'CMD_EVALUATE_EXPRESSION', - '114': 'CMD_GET_FRAME', - '115': 'CMD_EXEC_EXPRESSION', - '116': 'CMD_WRITE_TO_CONSOLE', - '117': 'CMD_CHANGE_VARIABLE', - '118': 'CMD_RUN_TO_LINE', - '119': 'CMD_RELOAD_CODE', - '120': 'CMD_GET_COMPLETIONS', - '121': 'CMD_CONSOLE_EXEC', - '122': 'CMD_ADD_EXCEPTION_BREAK', - '123': 'CMD_REMOVE_EXCEPTION_BREAK', - '124': 'CMD_LOAD_SOURCE', - '125': 'CMD_ADD_DJANGO_EXCEPTION_BREAK', - '126': 'CMD_REMOVE_DJANGO_EXCEPTION_BREAK', - '127': 'CMD_SET_NEXT_STATEMENT', - '128': 'CMD_SMART_STEP_INTO', - '129': 'CMD_EXIT', - '130': 'CMD_SIGNATURE_CALL_TRACE', - - '131': 'CMD_SET_PY_EXCEPTION', - '132': 'CMD_GET_FILE_CONTENTS', - '133': 'CMD_SET_PROPERTY_TRACE', - '134': 'CMD_EVALUATE_CONSOLE_EXPRESSION', - '135': 'CMD_RUN_CUSTOM_OPERATION', - '136': 'CMD_GET_BREAKPOINT_EXCEPTION', - '137': 'CMD_STEP_CAUGHT_EXCEPTION', - '138': 'CMD_SEND_CURR_EXCEPTION_TRACE', - '139': 'CMD_SEND_CURR_EXCEPTION_TRACE_PROCEEDED', - '140': 'CMD_IGNORE_THROWN_EXCEPTION_AT', - '141': 'CMD_ENABLE_DONT_TRACE', - '142': 'CMD_SHOW_CONSOLE', - '143': 'CMD_GET_ARRAY', - '144': 'CMD_STEP_INTO_MY_CODE', - '145': 'CMD_GET_CONCURRENCY_EVENT', - '146': 'CMD_SHOW_RETURN_VALUES', - '147': 'CMD_INPUT_REQUESTED', - '148': 'CMD_GET_DESCRIPTION', - - '149': 'CMD_PROCESS_CREATED', # Note: this is actually a notification of a sub-process created. - '150': 'CMD_SHOW_CYTHON_WARNING', - '151': 'CMD_LOAD_FULL_VALUE', - '152': 'CMD_GET_THREAD_STACK', - '153': 'CMD_THREAD_DUMP_TO_STDERR', - '154': 'CMD_STOP_ON_START', - '155': 'CMD_GET_EXCEPTION_DETAILS', - '156': 'CMD_PYDEVD_JSON_CONFIG', - '157': 'CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION', - '158': 'CMD_THREAD_RESUME_SINGLE_NOTIFICATION', - - '159': 'CMD_STEP_OVER_MY_CODE', - '160': 'CMD_STEP_RETURN_MY_CODE', - - '161': 'CMD_SET_PY_EXCEPTION_JSON', - '162': 'CMD_SET_PATH_MAPPING_JSON', - '163': 'CMD_GET_SMART_STEP_INTO_VARIANTS', - - '200': 'CMD_REDIRECT_OUTPUT', - '201': 'CMD_GET_NEXT_STATEMENT_TARGETS', - '202': 'CMD_SET_PROJECT_ROOTS', - '203': 'CMD_MODULE_EVENT', - '204': 'CMD_PROCESS_EVENT', # DAP process event. - - '205': 'CMD_AUTHENTICATE', - - '206': 'CMD_STEP_INTO_COROUTINE', - - '207': 'CMD_LOAD_SOURCE_FROM_FRAME_ID', - - '501': 'CMD_VERSION', - '502': 'CMD_RETURN', - '503': 'CMD_SET_PROTOCOL', - '901': 'CMD_ERROR', + "101": "CMD_RUN", + "102": "CMD_LIST_THREADS", + "103": "CMD_THREAD_CREATE", + "104": "CMD_THREAD_KILL", + "105": "CMD_THREAD_SUSPEND", + "106": "CMD_THREAD_RUN", + "107": "CMD_STEP_INTO", + "108": "CMD_STEP_OVER", + "109": "CMD_STEP_RETURN", + "110": "CMD_GET_VARIABLE", + "111": "CMD_SET_BREAK", + "112": "CMD_REMOVE_BREAK", + "113": "CMD_EVALUATE_EXPRESSION", + "114": "CMD_GET_FRAME", + "115": "CMD_EXEC_EXPRESSION", + "116": "CMD_WRITE_TO_CONSOLE", + "117": "CMD_CHANGE_VARIABLE", + "118": "CMD_RUN_TO_LINE", + "119": "CMD_RELOAD_CODE", + "120": "CMD_GET_COMPLETIONS", + "121": "CMD_CONSOLE_EXEC", + "122": "CMD_ADD_EXCEPTION_BREAK", + "123": "CMD_REMOVE_EXCEPTION_BREAK", + "124": "CMD_LOAD_SOURCE", + "125": "CMD_ADD_DJANGO_EXCEPTION_BREAK", + "126": "CMD_REMOVE_DJANGO_EXCEPTION_BREAK", + "127": "CMD_SET_NEXT_STATEMENT", + "128": "CMD_SMART_STEP_INTO", + "129": "CMD_EXIT", + "130": "CMD_SIGNATURE_CALL_TRACE", + "131": "CMD_SET_PY_EXCEPTION", + "132": "CMD_GET_FILE_CONTENTS", + "133": "CMD_SET_PROPERTY_TRACE", + "134": "CMD_EVALUATE_CONSOLE_EXPRESSION", + "135": "CMD_RUN_CUSTOM_OPERATION", + "136": "CMD_GET_BREAKPOINT_EXCEPTION", + "137": "CMD_STEP_CAUGHT_EXCEPTION", + "138": "CMD_SEND_CURR_EXCEPTION_TRACE", + "139": "CMD_SEND_CURR_EXCEPTION_TRACE_PROCEEDED", + "140": "CMD_IGNORE_THROWN_EXCEPTION_AT", + "141": "CMD_ENABLE_DONT_TRACE", + "142": "CMD_SHOW_CONSOLE", + "143": "CMD_GET_ARRAY", + "144": "CMD_STEP_INTO_MY_CODE", + "145": "CMD_GET_CONCURRENCY_EVENT", + "146": "CMD_SHOW_RETURN_VALUES", + "147": "CMD_INPUT_REQUESTED", + "148": "CMD_GET_DESCRIPTION", + "149": "CMD_PROCESS_CREATED", # Note: this is actually a notification of a sub-process created. + "150": "CMD_SHOW_CYTHON_WARNING", + "151": "CMD_LOAD_FULL_VALUE", + "152": "CMD_GET_THREAD_STACK", + "153": "CMD_THREAD_DUMP_TO_STDERR", + "154": "CMD_STOP_ON_START", + "155": "CMD_GET_EXCEPTION_DETAILS", + "156": "CMD_PYDEVD_JSON_CONFIG", + "157": "CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION", + "158": "CMD_THREAD_RESUME_SINGLE_NOTIFICATION", + "159": "CMD_STEP_OVER_MY_CODE", + "160": "CMD_STEP_RETURN_MY_CODE", + "161": "CMD_SET_PY_EXCEPTION_JSON", + "162": "CMD_SET_PATH_MAPPING_JSON", + "163": "CMD_GET_SMART_STEP_INTO_VARIANTS", + "200": "CMD_REDIRECT_OUTPUT", + "201": "CMD_GET_NEXT_STATEMENT_TARGETS", + "202": "CMD_SET_PROJECT_ROOTS", + "203": "CMD_MODULE_EVENT", + "204": "CMD_PROCESS_EVENT", # DAP process event. + "205": "CMD_AUTHENTICATE", + "206": "CMD_STEP_INTO_COROUTINE", + "207": "CMD_LOAD_SOURCE_FROM_FRAME_ID", + "501": "CMD_VERSION", + "502": "CMD_RETURN", + "503": "CMD_SET_PROTOCOL", + "901": "CMD_ERROR", } def constant_to_str(constant): s = ID_TO_MEANING.get(str(constant)) if not s: - s = '' % (constant,) + s = "" % (constant,) return s diff --git a/_pydevd_bundle/pydevd_command_line_handling.py b/_pydevd_bundle/pydevd_command_line_handling.py index b46c98b1e..8fb3e03ce 100644 --- a/_pydevd_bundle/pydevd_command_line_handling.py +++ b/_pydevd_bundle/pydevd_command_line_handling.py @@ -3,13 +3,13 @@ class ArgHandlerWithParam: - ''' + """ Handler for some arguments which needs a value - ''' + """ def __init__(self, arg_name, convert_val=None, default_val=None): self.arg_name = arg_name - self.arg_v_rep = '--%s' % (arg_name,) + self.arg_v_rep = "--%s" % (arg_name,) self.convert_val = convert_val self.default_val = default_val @@ -17,7 +17,7 @@ def to_argv(self, lst, setup): v = setup.get(self.arg_name) if v is not None and v != self.default_val: lst.append(self.arg_v_rep) - lst.append('%s' % (v,)) + lst.append("%s" % (v,)) def handle_argv(self, argv, i, setup): assert argv[i] == self.arg_v_rep @@ -32,13 +32,13 @@ def handle_argv(self, argv, i, setup): class ArgHandlerBool: - ''' + """ If a given flag is received, mark it as 'True' in setup. - ''' + """ def __init__(self, arg_name, default_val=False): self.arg_name = arg_name - self.arg_v_rep = '--%s' % (arg_name,) + self.arg_v_rep = "--%s" % (arg_name,) self.default_val = default_val def to_argv(self, lst, setup): @@ -56,42 +56,38 @@ def convert_ppid(ppid): ret = int(ppid) if ret != 0: if ret == os.getpid(): - raise AssertionError( - 'ppid passed is the same as the current process pid (%s)!' % (ret,)) + raise AssertionError("ppid passed is the same as the current process pid (%s)!" % (ret,)) return ret ACCEPTED_ARG_HANDLERS = [ - ArgHandlerWithParam('port', int, 0), - ArgHandlerWithParam('ppid', convert_ppid, 0), - ArgHandlerWithParam('vm_type'), - ArgHandlerWithParam('client'), - ArgHandlerWithParam('access-token'), - ArgHandlerWithParam('client-access-token'), - ArgHandlerWithParam('debug-mode'), - ArgHandlerWithParam('preimport'), - + ArgHandlerWithParam("port", int, 0), + ArgHandlerWithParam("ppid", convert_ppid, 0), + ArgHandlerWithParam("vm_type"), + ArgHandlerWithParam("client"), + ArgHandlerWithParam("access-token"), + ArgHandlerWithParam("client-access-token"), + ArgHandlerWithParam("debug-mode"), + ArgHandlerWithParam("preimport"), # Logging - ArgHandlerWithParam('log-file'), - ArgHandlerWithParam('log-level', int, None), - - ArgHandlerBool('server'), - ArgHandlerBool('multiproc'), # Used by PyCharm (reuses connection: ssh tunneling) - ArgHandlerBool('multiprocess'), # Used by PyDev (creates new connection to ide) - ArgHandlerBool('save-signatures'), - ArgHandlerBool('save-threading'), - ArgHandlerBool('save-asyncio'), - ArgHandlerBool('print-in-debugger-startup'), - ArgHandlerBool('cmd-line'), - ArgHandlerBool('module'), - ArgHandlerBool('skip-notify-stdin'), - + ArgHandlerWithParam("log-file"), + ArgHandlerWithParam("log-level", int, None), + ArgHandlerBool("server"), + ArgHandlerBool("multiproc"), # Used by PyCharm (reuses connection: ssh tunneling) + ArgHandlerBool("multiprocess"), # Used by PyDev (creates new connection to ide) + ArgHandlerBool("save-signatures"), + ArgHandlerBool("save-threading"), + ArgHandlerBool("save-asyncio"), + ArgHandlerBool("print-in-debugger-startup"), + ArgHandlerBool("cmd-line"), + ArgHandlerBool("module"), + ArgHandlerBool("skip-notify-stdin"), # The ones below should've been just one setting to specify the protocol, but for compatibility # reasons they're passed as a flag but are mutually exclusive. - ArgHandlerBool('json-dap'), # Protocol used by ptvsd to communicate with pydevd (a single json message in each read) - ArgHandlerBool('json-dap-http'), # Actual DAP (json messages over http protocol). - ArgHandlerBool('protocol-quoted-line'), # Custom protocol with quoted lines. - ArgHandlerBool('protocol-http'), # Custom protocol with http. + ArgHandlerBool("json-dap"), # Protocol used by ptvsd to communicate with pydevd (a single json message in each read) + ArgHandlerBool("json-dap-http"), # Actual DAP (json messages over http protocol). + ArgHandlerBool("protocol-quoted-line"), # Custom protocol with quoted lines. + ArgHandlerBool("protocol-http"), # Custom protocol with http. ] ARGV_REP_TO_HANDLER = {} @@ -101,16 +97,17 @@ def convert_ppid(ppid): def get_pydevd_file(): import pydevd + f = pydevd.__file__ - if f.endswith('.pyc'): + if f.endswith(".pyc"): f = f[:-1] - elif f.endswith('$py.class'): - f = f[:-len('$py.class')] + '.py' + elif f.endswith("$py.class"): + f = f[: -len("$py.class")] + ".py" return f def setup_to_argv(setup, skip_names=None): - ''' + """ :param dict setup: A dict previously gotten from process_command_line. @@ -118,7 +115,7 @@ def setup_to_argv(setup, skip_names=None): The names in the setup which shouldn't be converted to argv. :note: does not handle --file nor --DEBUG. - ''' + """ if skip_names is None: skip_names = set() ret = [get_pydevd_file()] @@ -130,13 +127,13 @@ def setup_to_argv(setup, skip_names=None): def process_command_line(argv): - """ parses the arguments. - removes our arguments from the command line """ + """parses the arguments. + removes our arguments from the command line""" setup = {} for handler in ACCEPTED_ARG_HANDLERS: setup[handler.arg_name] = handler.default_val - setup['file'] = '' - setup['qt-support'] = '' + setup["file"] = "" + setup["qt-support"] = "" initial_argv = tuple(argv) @@ -147,39 +144,38 @@ def process_command_line(argv): if handler is not None: handler.handle_argv(argv, i, setup) - elif argv[i].startswith('--qt-support'): + elif argv[i].startswith("--qt-support"): # The --qt-support is special because we want to keep backward compatibility: # Previously, just passing '--qt-support' meant that we should use the auto-discovery mode # whereas now, if --qt-support is passed, it should be passed as --qt-support=, where # mode can be one of 'auto', 'none', 'pyqt5', 'pyqt4', 'pyside', 'pyside2'. - if argv[i] == '--qt-support': - setup['qt-support'] = 'auto' + if argv[i] == "--qt-support": + setup["qt-support"] = "auto" - elif argv[i].startswith('--qt-support='): - qt_support = argv[i][len('--qt-support='):] - valid_modes = ('none', 'auto', 'pyqt5', 'pyqt4', 'pyside', 'pyside2') + elif argv[i].startswith("--qt-support="): + qt_support = argv[i][len("--qt-support=") :] + valid_modes = ("none", "auto", "pyqt5", "pyqt4", "pyside", "pyside2") if qt_support not in valid_modes: raise ValueError("qt-support mode invalid: " + qt_support) - if qt_support == 'none': + if qt_support == "none": # On none, actually set an empty string to evaluate to False. - setup['qt-support'] = '' + setup["qt-support"] = "" else: - setup['qt-support'] = qt_support + setup["qt-support"] = qt_support else: raise ValueError("Unexpected definition for qt-support flag: " + argv[i]) del argv[i] - elif argv[i] == '--file': + elif argv[i] == "--file": # --file is special because it's the last one (so, no handler for it). del argv[i] - setup['file'] = argv[i] + setup["file"] = argv[i] i = len(argv) # pop out, file is our last argument - elif argv[i] == '--DEBUG': - sys.stderr.write('pydevd: --DEBUG parameter deprecated. Use `--debug-level=3` instead.\n') + elif argv[i] == "--DEBUG": + sys.stderr.write("pydevd: --DEBUG parameter deprecated. Use `--debug-level=3` instead.\n") else: raise ValueError("Unexpected option: %s when processing: %s" % (argv[i], initial_argv)) return setup - diff --git a/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_concurrency_logger.py b/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_concurrency_logger.py index 95fc0543c..af5a8b99c 100644 --- a/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_concurrency_logger.py +++ b/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_concurrency_logger.py @@ -17,12 +17,12 @@ threadingCurrentThread = threading.current_thread -DONT_TRACE_THREADING = ['threading.py', 'pydevd.py'] -INNER_METHODS = ['_stop'] -INNER_FILES = ['threading.py'] -THREAD_METHODS = ['start', '_stop', 'join'] -LOCK_METHODS = ['__init__', 'acquire', 'release', '__enter__', '__exit__'] -QUEUE_METHODS = ['put', 'get'] +DONT_TRACE_THREADING = ["threading.py", "pydevd.py"] +INNER_METHODS = ["_stop"] +INNER_FILES = ["threading.py"] +THREAD_METHODS = ["start", "_stop", "join"] +LOCK_METHODS = ["__init__", "acquire", "release", "__enter__", "__exit__"] +QUEUE_METHODS = ["put", "get"] # return time since epoch in milliseconds cur_time = lambda: int(round(time.time() * 1000000)) @@ -60,9 +60,9 @@ def get_text_list_for_frame(frame): # the variables are all gotten 'on-demand' # variables = pydevd_xml.frame_vars_to_xml(curFrame.f_locals) - variables = '' - cmdTextList.append('' % (quote(my_file, '/>_= \t'), myLine)) + variables = "" + cmdTextList.append('' % (quote(my_file, "/>_= \t"), myLine)) cmdTextList.append(variables) cmdTextList.append("") curFrame = curFrame.f_back @@ -76,9 +76,9 @@ def send_concurrency_message(event_class, time, name, thread_id, type, event, fi dbg = GlobalDebuggerHolder.global_dbg if dbg is None: return - cmdTextList = [''] + cmdTextList = [""] - cmdTextList.append('<' + event_class) + cmdTextList.append("<" + event_class) cmdTextList.append(' time="%s"' % pydevd_xml.make_valid_xml_value(str(time))) cmdTextList.append(' name="%s"' % pydevd_xml.make_valid_xml_value(name)) cmdTextList.append(' thread_id="%s"' % pydevd_xml.make_valid_xml_value(thread_id)) @@ -90,24 +90,24 @@ def send_concurrency_message(event_class, time, name, thread_id, type, event, fi cmdTextList.append(' event="%s"' % pydevd_xml.make_valid_xml_value(event)) cmdTextList.append(' file="%s"' % pydevd_xml.make_valid_xml_value(file)) cmdTextList.append(' line="%s"' % pydevd_xml.make_valid_xml_value(str(line))) - cmdTextList.append('>') + cmdTextList.append(">") cmdTextList += get_text_list_for_frame(frame) - cmdTextList.append('') + cmdTextList.append("") - text = ''.join(cmdTextList) + text = "".join(cmdTextList) if dbg.writer is not None: dbg.writer.add_command(NetCommand(145, 0, text)) def log_new_thread(global_debugger, t): event_time = cur_time() - global_debugger.thread_analyser.start_time - send_concurrency_message("threading_event", event_time, t.name, get_thread_id(t), "thread", - "start", "code_name", 0, None, parent=get_thread_id(t)) + send_concurrency_message( + "threading_event", event_time, t.name, get_thread_id(t), "thread", "start", "code_name", 0, None, parent=get_thread_id(t) + ) class ThreadingLogger: - def __init__(self): self.start_time = cur_time() @@ -141,15 +141,15 @@ def log_event(self, frame): if isinstance(self_obj, threading.Thread): if not hasattr(self_obj, "_pydev_run_patched"): wrap_attr(self_obj, "run") - if (method_name in THREAD_METHODS) and (back_base not in DONT_TRACE_THREADING or \ - (method_name in INNER_METHODS and back_base in INNER_FILES)): + if (method_name in THREAD_METHODS) and ( + back_base not in DONT_TRACE_THREADING or (method_name in INNER_METHODS and back_base in INNER_FILES) + ): thread_id = get_thread_id(self_obj) name = self_obj.getName() real_method = frame.f_code.co_name parent = None if real_method == "_stop": - if back_base in INNER_FILES and \ - back.f_code.co_name == "_wait_for_tstate_lock": + if back_base in INNER_FILES and back.f_code.co_name == "_wait_for_tstate_lock": back = back.f_back.f_back real_method = "stop" if hasattr(self_obj, "_pydev_join_called"): @@ -164,8 +164,18 @@ def log_event(self, frame): if real_method == "start": parent = get_thread_id(t) - send_concurrency_message("threading_event", event_time, name, thread_id, "thread", - real_method, back.f_code.co_filename, back.f_lineno, back, parent=parent) + send_concurrency_message( + "threading_event", + event_time, + name, + thread_id, + "thread", + real_method, + back.f_code.co_filename, + back.f_lineno, + back, + parent=parent, + ) # print(event_time, self_obj.getName(), thread_id, "thread", # real_method, back.f_code.co_filename, back.f_lineno) @@ -184,8 +194,18 @@ def log_event(self, frame): send_massage = False # we can't detect stop after join in Python 2 yet if send_massage: - send_concurrency_message("threading_event", event_time, "Thread", my_thread_id, "thread", - "stop", my_back.f_code.co_filename, my_back.f_lineno, my_back, parent=None) + send_concurrency_message( + "threading_event", + event_time, + "Thread", + my_thread_id, + "thread", + "stop", + my_back.f_code.co_filename, + my_back.f_lineno, + my_back, + parent=None, + ) if self_obj.__class__ == ObjectWrapper: if back_base in DONT_TRACE_THREADING: @@ -197,11 +217,19 @@ def log_event(self, frame): # back_back_base is the file, where the method was called froms return if method_name == "__init__": - send_concurrency_message("threading_event", event_time, t.name, get_thread_id(t), "lock", - method_name, back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(frame.f_locals["self"]))) - if "attr" in frame.f_locals and \ - (frame.f_locals["attr"] in LOCK_METHODS or - frame.f_locals["attr"] in QUEUE_METHODS): + send_concurrency_message( + "threading_event", + event_time, + t.name, + get_thread_id(t), + "lock", + method_name, + back.f_code.co_filename, + back.f_lineno, + back, + lock_id=str(id(frame.f_locals["self"])), + ) + if "attr" in frame.f_locals and (frame.f_locals["attr"] in LOCK_METHODS or frame.f_locals["attr"] in QUEUE_METHODS): real_method = frame.f_locals["attr"] if method_name == "call_begin": real_method += "_begin" @@ -212,13 +240,33 @@ def log_event(self, frame): if real_method == "release_end": # do not log release end. Maybe use it later return - send_concurrency_message("threading_event", event_time, t.name, get_thread_id(t), "lock", - real_method, back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(self_obj))) + send_concurrency_message( + "threading_event", + event_time, + t.name, + get_thread_id(t), + "lock", + real_method, + back.f_code.co_filename, + back.f_lineno, + back, + lock_id=str(id(self_obj)), + ) if real_method in ("put_end", "get_end"): # fake release for queue, cause we don't call it directly - send_concurrency_message("threading_event", event_time, t.name, get_thread_id(t), "lock", - "release", back.f_code.co_filename, back.f_lineno, back, lock_id=str(id(self_obj))) + send_concurrency_message( + "threading_event", + event_time, + t.name, + get_thread_id(t), + "lock", + "release", + back.f_code.co_filename, + back.f_lineno, + back, + lock_id=str(id(self_obj)), + ) # print(event_time, t.name, get_thread_id(t), "lock", # real_method, back.f_code.co_filename, back.f_lineno) @@ -227,7 +275,6 @@ def log_event(self, frame): class NameManager: - def __init__(self, name_prefix): self.tasks = {} self.last = 0 @@ -241,14 +288,13 @@ def get(self, id): class AsyncioLogger: - def __init__(self): self.task_mgr = NameManager("Task") self.coro_mgr = NameManager("Coro") self.start_time = cur_time() def get_task_id(self, frame): - asyncio = sys.modules.get('asyncio') + asyncio = sys.modules.get("asyncio") if asyncio is None: # If asyncio was not imported, there's nothing to be done # (also fixes issue where multiprocessing is imported due @@ -275,7 +321,7 @@ def log_event(self, frame): if not hasattr(frame, "f_back") or frame.f_back is None: return - asyncio = sys.modules.get('asyncio') + asyncio = sys.modules.get("asyncio") if asyncio is None: # If asyncio was not imported, there's nothing to be done # (also fixes issue where multiprocessing is imported due @@ -291,15 +337,25 @@ def log_event(self, frame): if method_name == "set_result": task_id = id(self_obj) task_name = self.task_mgr.get(str(task_id)) - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "thread", "stop", frame.f_code.co_filename, - frame.f_lineno, frame) + send_concurrency_message( + "asyncio_event", event_time, task_name, task_name, "thread", "stop", frame.f_code.co_filename, frame.f_lineno, frame + ) method_name = back.f_code.co_name if method_name == "__init__": task_id = id(self_obj) task_name = self.task_mgr.get(str(task_id)) - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "thread", "start", frame.f_code.co_filename, - frame.f_lineno, frame) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "thread", + "start", + frame.f_code.co_filename, + frame.f_lineno, + frame, + ) method_name = frame.f_code.co_name if isinstance(self_obj, asyncio.Lock): @@ -309,8 +365,18 @@ def log_event(self, frame): if method_name == "acquire": if not self_obj._waiters and not self_obj.locked(): - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "lock", - method_name + "_begin", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj))) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "lock", + method_name + "_begin", + frame.f_code.co_filename, + frame.f_lineno, + frame, + lock_id=str(id(self_obj)), + ) if self_obj.locked(): method_name += "_begin" else: @@ -318,8 +384,18 @@ def log_event(self, frame): elif method_name == "release": method_name += "_end" - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "lock", - method_name, frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj))) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "lock", + method_name, + frame.f_code.co_filename, + frame.f_lineno, + frame, + lock_id=str(id(self_obj)), + ) if isinstance(self_obj, asyncio.Queue): if method_name in ("put", "get", "_put", "_get"): @@ -327,20 +403,80 @@ def log_event(self, frame): task_name = self.task_mgr.get(str(task_id)) if method_name == "put": - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "lock", - "acquire_begin", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj))) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "lock", + "acquire_begin", + frame.f_code.co_filename, + frame.f_lineno, + frame, + lock_id=str(id(self_obj)), + ) elif method_name == "_put": - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "lock", - "acquire_end", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj))) - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "lock", - "release", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj))) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "lock", + "acquire_end", + frame.f_code.co_filename, + frame.f_lineno, + frame, + lock_id=str(id(self_obj)), + ) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "lock", + "release", + frame.f_code.co_filename, + frame.f_lineno, + frame, + lock_id=str(id(self_obj)), + ) elif method_name == "get": back = frame.f_back if back.f_code.co_name != "send": - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "lock", - "acquire_begin", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj))) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "lock", + "acquire_begin", + frame.f_code.co_filename, + frame.f_lineno, + frame, + lock_id=str(id(self_obj)), + ) else: - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "lock", - "acquire_end", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj))) - send_concurrency_message("asyncio_event", event_time, task_name, task_name, "lock", - "release", frame.f_code.co_filename, frame.f_lineno, frame, lock_id=str(id(self_obj))) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "lock", + "acquire_end", + frame.f_code.co_filename, + frame.f_lineno, + frame, + lock_id=str(id(self_obj)), + ) + send_concurrency_message( + "asyncio_event", + event_time, + task_name, + task_name, + "lock", + "release", + frame.f_code.co_filename, + frame.f_lineno, + frame, + lock_id=str(id(self_obj)), + ) diff --git a/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_thread_wrappers.py b/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_thread_wrappers.py index 526bb0c15..e71f3e591 100644 --- a/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_thread_wrappers.py +++ b/_pydevd_bundle/pydevd_concurrency_analyser/pydevd_thread_wrappers.py @@ -2,7 +2,6 @@ def wrapper(fun): - def pydev_after_run_call(): pass @@ -20,11 +19,11 @@ def wrap_attr(obj, attr): class ObjectWrapper(object): - def __init__(self, obj): self.wrapped_object = obj try: import functools + functools.update_wrapper(self, obj) except: pass @@ -62,7 +61,6 @@ def __exit__(self, exc_type, exc_val, exc_tb): def factory_wrapper(fun): - def inner(*args, **kwargs): obj = fun(*args, **kwargs) return ObjectWrapper(obj) @@ -80,4 +78,5 @@ def wrap_threads(): # queue patching import queue # @UnresolvedImport + queue.Queue = factory_wrapper(queue.Queue) diff --git a/_pydevd_bundle/pydevd_console.py b/_pydevd_bundle/pydevd_console.py index 925e010a5..9221f68cc 100644 --- a/_pydevd_bundle/pydevd_console.py +++ b/_pydevd_bundle/pydevd_console.py @@ -1,5 +1,5 @@ -'''An helper file for the pydev debugger (REPL) console -''' +"""An helper file for the pydev debugger (REPL) console +""" import sys import traceback from _pydevd_bundle.pydevconsole_code import InteractiveConsole, _EvalAwaitInNewEventLoop @@ -18,12 +18,11 @@ CONSOLE_ERROR = "error" -#======================================================================================================================= +# ======================================================================================================================= # ConsoleMessage -#======================================================================================================================= +# ======================================================================================================================= class ConsoleMessage: - """Console Messages - """ + """Console Messages""" def __init__(self): self.more = False @@ -31,8 +30,7 @@ def __init__(self): self.console_messages = [] def add_console_message(self, message_type, message): - """add messages in the console_messages list - """ + """add messages in the console_messages list""" for m in message.split("\n"): if m.strip(): self.console_messages.append((message_type, m)) @@ -53,30 +51,29 @@ def to_xml(self): """ makeValid = make_valid_xml_value - xml = '%s' % (self.more) + xml = "%s" % (self.more) for message_type, message in self.console_messages: xml += '<%s message="%s">' % (message_type, makeValid(message), message_type) - xml += '' + xml += "" return xml -#======================================================================================================================= +# ======================================================================================================================= # _DebugConsoleStdIn -#======================================================================================================================= +# ======================================================================================================================= class _DebugConsoleStdIn(BaseStdIn): - @overrides(BaseStdIn.readline) def readline(self, *args, **kwargs): - sys.stderr.write('Warning: Reading from stdin is still not supported in this console.\n') - return '\n' + sys.stderr.write("Warning: Reading from stdin is still not supported in this console.\n") + return "\n" -#======================================================================================================================= +# ======================================================================================================================= # DebugConsole -#======================================================================================================================= +# ======================================================================================================================= class DebugConsole(InteractiveConsole, BaseInterpreterInterface): """Wrapper around code.InteractiveConsole, in order to send errors and outputs to the debug console @@ -159,7 +156,7 @@ def runcode(self, code): updated_locals = None is_async = False - if hasattr(inspect, 'CO_COROUTINE'): + if hasattr(inspect, "CO_COROUTINE"): is_async = inspect.CO_COROUTINE & code.co_flags == inspect.CO_COROUTINE if is_async: @@ -194,11 +191,10 @@ def get_namespace(self): return dbg_namespace -#======================================================================================================================= +# ======================================================================================================================= # InteractiveConsoleCache -#======================================================================================================================= +# ======================================================================================================================= class InteractiveConsoleCache: - thread_id = None frame_id = None interactive_console_instance = None @@ -263,8 +259,7 @@ def get_description(frame, thread_id, frame_id, expression): def get_completions(frame, act_tok): - """ fetch all completions, create xml for the same + """fetch all completions, create xml for the same return the completions xml """ return _pydev_completer.generate_completions_as_xml(frame, act_tok) - diff --git a/_pydevd_bundle/pydevd_constants.py b/_pydevd_bundle/pydevd_constants.py index 402634580..4ebe83ed5 100644 --- a/_pydevd_bundle/pydevd_constants.py +++ b/_pydevd_bundle/pydevd_constants.py @@ -1,6 +1,6 @@ -''' +""" This module holds the constants used for specifying the states of the debugger. -''' +""" from __future__ import nested_scopes import platform import weakref @@ -28,6 +28,7 @@ # Preload codecs to avoid imports to them later on which can potentially halt the debugger. import codecs as _codecs + for _codec in ["ascii", "utf8", "utf-8", "latin1", "latin-1", "idna"]: _codecs.lookup(_codec) @@ -47,22 +48,22 @@ class DebugInfoHolder: # In PyPy " ..." can appear and should be ignored for the user. # has special heuristics to know whether it should be traced or not (it's part of # user code when it's the used in python -c and part of the library otherwise). # Any filename that starts with these strings is considered user (project) code. Note # that files for which we have a source mapping are also considered as a part of the project. -USER_CODE_BASENAMES_STARTING_WITH = (' (2 ** 32) +IS_64BIT_PROCESS = sys.maxsize > (2**32) IS_JYTHON = pydevd_vm_type.get_vm_type() == pydevd_vm_type.PydevdVmType.JYTHON -IS_PYPY = platform.python_implementation() == 'PyPy' +IS_PYPY = platform.python_implementation() == "PyPy" if IS_JYTHON: import java.lang.System # @UnresolvedImport + IS_WINDOWS = java.lang.System.getProperty("os.name").lower().startswith("windows") -USE_CUSTOM_SYS_CURRENT_FRAMES = not hasattr(sys, '_current_frames') or IS_PYPY +USE_CUSTOM_SYS_CURRENT_FRAMES = not hasattr(sys, "_current_frames") or IS_PYPY USE_CUSTOM_SYS_CURRENT_FRAMES_MAP = USE_CUSTOM_SYS_CURRENT_FRAMES and (IS_PYPY or IS_IRONPYTHON) if USE_CUSTOM_SYS_CURRENT_FRAMES: - # Some versions of Jython don't have it (but we can provide a replacement) if IS_JYTHON: from java.lang import NoSuchFieldException from org.python.core import ThreadStateMapping + try: - cachedThreadState = ThreadStateMapping.getDeclaredField('globalThreadStates') # Dev version + cachedThreadState = ThreadStateMapping.getDeclaredField("globalThreadStates") # Dev version except NoSuchFieldException: - cachedThreadState = ThreadStateMapping.getDeclaredField('cachedThreadState') # Release Jython 2.7.0 + cachedThreadState = ThreadStateMapping.getDeclaredField("cachedThreadState") # Release Jython 2.7.0 cachedThreadState.accessible = True thread_states = cachedThreadState.get(ThreadStateMapping) @@ -148,7 +151,7 @@ def _current_frames(): return constructed_tid_to_last_frame else: - raise RuntimeError('Unable to proceed (sys._current_frames not available in this Python implementation).') + raise RuntimeError("Unable to proceed (sys._current_frames not available in this Python implementation).") else: _current_frames = sys._current_frames @@ -156,13 +159,13 @@ def _current_frames(): CYTHON_SUPPORTED = False python_implementation = platform.python_implementation() -if python_implementation == 'CPython': +if python_implementation == "CPython": # Only available for CPython! CYTHON_SUPPORTED = True -#======================================================================================================================= +# ======================================================================================================================= # Python 3? -#======================================================================================================================= +# ======================================================================================================================= IS_PY36_OR_GREATER = sys.version_info >= (3, 6) IS_PY37_OR_GREATER = sys.version_info >= (3, 7) IS_PY38_OR_GREATER = sys.version_info >= (3, 8) @@ -176,26 +179,26 @@ def _current_frames(): def version_str(v): - return '.'.join((str(x) for x in v[:3])) + ''.join((str(x) for x in v[3:])) + return ".".join((str(x) for x in v[:3])) + "".join((str(x) for x in v[3:])) PY_VERSION_STR = version_str(sys.version_info) try: PY_IMPL_VERSION_STR = version_str(sys.implementation.version) except AttributeError: - PY_IMPL_VERSION_STR = '' + PY_IMPL_VERSION_STR = "" try: PY_IMPL_NAME = sys.implementation.name except AttributeError: - PY_IMPL_NAME = '' + PY_IMPL_NAME = "" -ENV_TRUE_LOWER_VALUES = ('yes', 'true', '1') -ENV_FALSE_LOWER_VALUES = ('no', 'false', '0') +ENV_TRUE_LOWER_VALUES = ("yes", "true", "1") +ENV_FALSE_LOWER_VALUES = ("no", "false", "0") -PYDEVD_USE_SYS_MONITORING = IS_PY312_OR_GREATER and hasattr(sys, 'monitoring') +PYDEVD_USE_SYS_MONITORING = IS_PY312_OR_GREATER and hasattr(sys, "monitoring") if PYDEVD_USE_SYS_MONITORING: # Default gotten, let's see if it was somehow customize by the user. - _use_sys_monitoring_env_var = os.getenv('PYDEVD_USE_SYS_MONITORING', '').lower() + _use_sys_monitoring_env_var = os.getenv("PYDEVD_USE_SYS_MONITORING", "").lower() if _use_sys_monitoring_env_var: # Check if the user specified something. if _use_sys_monitoring_env_var in ENV_FALSE_LOWER_VALUES: @@ -203,7 +206,7 @@ def version_str(v): elif _use_sys_monitoring_env_var in ENV_TRUE_LOWER_VALUES: PYDEVD_USE_SYS_MONITORING = True else: - raise RuntimeError('Unrecognized value for PYDEVD_USE_SYS_MONITORING: %s' % (_use_sys_monitoring_env_var,)) + raise RuntimeError("Unrecognized value for PYDEVD_USE_SYS_MONITORING: %s" % (_use_sys_monitoring_env_var,)) def is_true_in_env(env_key): @@ -214,7 +217,7 @@ def is_true_in_env(env_key): return True return False else: - return os.getenv(env_key, '').lower() in ENV_TRUE_LOWER_VALUES + return os.getenv(env_key, "").lower() in ENV_TRUE_LOWER_VALUES def as_float_in_env(env_key, default): @@ -224,9 +227,7 @@ def as_float_in_env(env_key, default): try: return float(value) except Exception: - raise RuntimeError( - 'Error: expected the env variable: %s to be set to a float value. Found: %s' % ( - env_key, value)) + raise RuntimeError("Error: expected the env variable: %s to be set to a float value. Found: %s" % (env_key, value)) def as_int_in_env(env_key, default): @@ -236,52 +237,52 @@ def as_int_in_env(env_key, default): try: return int(value) except Exception: - raise RuntimeError( - 'Error: expected the env variable: %s to be set to a int value. Found: %s' % ( - env_key, value)) + raise RuntimeError("Error: expected the env variable: %s to be set to a int value. Found: %s" % (env_key, value)) # If true in env, use gevent mode. -SUPPORT_GEVENT = is_true_in_env('GEVENT_SUPPORT') +SUPPORT_GEVENT = is_true_in_env("GEVENT_SUPPORT") # Opt-in support to show gevent paused greenlets. False by default because if too many greenlets are # paused the UI can slow-down (i.e.: if 1000 greenlets are paused, each one would be shown separate # as a different thread, but if the UI isn't optimized for that the experience is lacking...). -GEVENT_SHOW_PAUSED_GREENLETS = is_true_in_env('GEVENT_SHOW_PAUSED_GREENLETS') +GEVENT_SHOW_PAUSED_GREENLETS = is_true_in_env("GEVENT_SHOW_PAUSED_GREENLETS") -DISABLE_FILE_VALIDATION = is_true_in_env('PYDEVD_DISABLE_FILE_VALIDATION') +DISABLE_FILE_VALIDATION = is_true_in_env("PYDEVD_DISABLE_FILE_VALIDATION") GEVENT_SUPPORT_NOT_SET_MSG = os.getenv( - 'GEVENT_SUPPORT_NOT_SET_MSG', - 'It seems that the gevent monkey-patching is being used.\n' - 'Please set an environment variable with:\n' - 'GEVENT_SUPPORT=True\n' - 'to enable gevent support in the debugger.' + "GEVENT_SUPPORT_NOT_SET_MSG", + "It seems that the gevent monkey-patching is being used.\n" + "Please set an environment variable with:\n" + "GEVENT_SUPPORT=True\n" + "to enable gevent support in the debugger.", ) USE_LIB_COPY = SUPPORT_GEVENT -INTERACTIVE_MODE_AVAILABLE = sys.platform in ('darwin', 'win32') or os.getenv('DISPLAY') is not None +INTERACTIVE_MODE_AVAILABLE = sys.platform in ("darwin", "win32") or os.getenv("DISPLAY") is not None # If true in env, forces cython to be used (raises error if not available). # If false in env, disables it. # If not specified, uses default heuristic to determine if it should be loaded. -USE_CYTHON_FLAG = os.getenv('PYDEVD_USE_CYTHON') +USE_CYTHON_FLAG = os.getenv("PYDEVD_USE_CYTHON") if USE_CYTHON_FLAG is not None: USE_CYTHON_FLAG = USE_CYTHON_FLAG.lower() if USE_CYTHON_FLAG not in ENV_TRUE_LOWER_VALUES and USE_CYTHON_FLAG not in ENV_FALSE_LOWER_VALUES: - raise RuntimeError('Unexpected value for PYDEVD_USE_CYTHON: %s (enable with one of: %s, disable with one of: %s)' % ( - USE_CYTHON_FLAG, ENV_TRUE_LOWER_VALUES, ENV_FALSE_LOWER_VALUES)) + raise RuntimeError( + "Unexpected value for PYDEVD_USE_CYTHON: %s (enable with one of: %s, disable with one of: %s)" + % (USE_CYTHON_FLAG, ENV_TRUE_LOWER_VALUES, ENV_FALSE_LOWER_VALUES) + ) else: if not CYTHON_SUPPORTED: - USE_CYTHON_FLAG = 'no' + USE_CYTHON_FLAG = "no" # If true in env, forces frame eval to be used (raises error if not available). # If false in env, disables it. # If not specified, uses default heuristic to determine if it should be loaded. -PYDEVD_USE_FRAME_EVAL = os.getenv('PYDEVD_USE_FRAME_EVAL', '').lower() +PYDEVD_USE_FRAME_EVAL = os.getenv("PYDEVD_USE_FRAME_EVAL", "").lower() # Values used to determine how much container items will be shown. # PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS: @@ -297,48 +298,48 @@ def as_int_in_env(env_key, default): # PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS # - Defines the maximum number of items for dicts and sets. # -PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS = as_int_in_env('PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS', 100) -PYDEVD_CONTAINER_BUCKET_SIZE = as_int_in_env('PYDEVD_CONTAINER_BUCKET_SIZE', 1000) -PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS = as_int_in_env('PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS', 500) -PYDEVD_CONTAINER_NUMPY_MAX_ITEMS = as_int_in_env('PYDEVD_CONTAINER_NUMPY_MAX_ITEMS', 500) +PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS = as_int_in_env("PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS", 100) +PYDEVD_CONTAINER_BUCKET_SIZE = as_int_in_env("PYDEVD_CONTAINER_BUCKET_SIZE", 1000) +PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS = as_int_in_env("PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS", 500) +PYDEVD_CONTAINER_NUMPY_MAX_ITEMS = as_int_in_env("PYDEVD_CONTAINER_NUMPY_MAX_ITEMS", 500) -PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING = is_true_in_env('PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING') +PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING = is_true_in_env("PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING") # If specified in PYDEVD_IPYTHON_CONTEXT it must be a string with the basename # and then the name of 2 methods in which the evaluate is done. -PYDEVD_IPYTHON_CONTEXT = ('interactiveshell.py', 'run_code', 'run_ast_nodes') -_ipython_ctx = os.getenv('PYDEVD_IPYTHON_CONTEXT') +PYDEVD_IPYTHON_CONTEXT = ("interactiveshell.py", "run_code", "run_ast_nodes") +_ipython_ctx = os.getenv("PYDEVD_IPYTHON_CONTEXT") if _ipython_ctx: - PYDEVD_IPYTHON_CONTEXT = tuple(x.strip() for x in _ipython_ctx.split(',')) - assert len(PYDEVD_IPYTHON_CONTEXT) == 3, 'Invalid PYDEVD_IPYTHON_CONTEXT: %s' % (_ipython_ctx,) + PYDEVD_IPYTHON_CONTEXT = tuple(x.strip() for x in _ipython_ctx.split(",")) + assert len(PYDEVD_IPYTHON_CONTEXT) == 3, "Invalid PYDEVD_IPYTHON_CONTEXT: %s" % (_ipython_ctx,) # Use to disable loading the lib to set tracing to all threads (default is using heuristics based on where we're running). -LOAD_NATIVE_LIB_FLAG = os.getenv('PYDEVD_LOAD_NATIVE_LIB', '').lower() +LOAD_NATIVE_LIB_FLAG = os.getenv("PYDEVD_LOAD_NATIVE_LIB", "").lower() -LOG_TIME = os.getenv('PYDEVD_LOG_TIME', 'true').lower() in ENV_TRUE_LOWER_VALUES +LOG_TIME = os.getenv("PYDEVD_LOG_TIME", "true").lower() in ENV_TRUE_LOWER_VALUES -SHOW_COMPILE_CYTHON_COMMAND_LINE = is_true_in_env('PYDEVD_SHOW_COMPILE_CYTHON_COMMAND_LINE') +SHOW_COMPILE_CYTHON_COMMAND_LINE = is_true_in_env("PYDEVD_SHOW_COMPILE_CYTHON_COMMAND_LINE") -LOAD_VALUES_ASYNC = is_true_in_env('PYDEVD_LOAD_VALUES_ASYNC') +LOAD_VALUES_ASYNC = is_true_in_env("PYDEVD_LOAD_VALUES_ASYNC") DEFAULT_VALUE = "__pydevd_value_async" ASYNC_EVAL_TIMEOUT_SEC = 60 NEXT_VALUE_SEPARATOR = "__pydev_val__" -BUILTINS_MODULE_NAME = 'builtins' +BUILTINS_MODULE_NAME = "builtins" # Pandas customization. -PANDAS_MAX_ROWS = as_int_in_env('PYDEVD_PANDAS_MAX_ROWS', 60) -PANDAS_MAX_COLS = as_int_in_env('PYDEVD_PANDAS_MAX_COLS', 10) -PANDAS_MAX_COLWIDTH = as_int_in_env('PYDEVD_PANDAS_MAX_COLWIDTH', 50) +PANDAS_MAX_ROWS = as_int_in_env("PYDEVD_PANDAS_MAX_ROWS", 60) +PANDAS_MAX_COLS = as_int_in_env("PYDEVD_PANDAS_MAX_COLS", 10) +PANDAS_MAX_COLWIDTH = as_int_in_env("PYDEVD_PANDAS_MAX_COLWIDTH", 50) # If getting an attribute or computing some value is too slow, let the user know if the given timeout elapses. -PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT = as_float_in_env('PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT', 0.50) +PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT = as_float_in_env("PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT", 0.50) # This timeout is used to track the time to send a message saying that the evaluation # is taking too long and possible mitigations. -PYDEVD_WARN_EVALUATION_TIMEOUT = as_float_in_env('PYDEVD_WARN_EVALUATION_TIMEOUT', 3.) +PYDEVD_WARN_EVALUATION_TIMEOUT = as_float_in_env("PYDEVD_WARN_EVALUATION_TIMEOUT", 3.0) # If True in env shows a thread dump when the evaluation times out. -PYDEVD_THREAD_DUMP_ON_WARN_EVALUATION_TIMEOUT = is_true_in_env('PYDEVD_THREAD_DUMP_ON_WARN_EVALUATION_TIMEOUT') +PYDEVD_THREAD_DUMP_ON_WARN_EVALUATION_TIMEOUT = is_true_in_env("PYDEVD_THREAD_DUMP_ON_WARN_EVALUATION_TIMEOUT") # This timeout is used only when the mode that all threads are stopped/resumed at once is used # (i.e.: multi_threads_single_notification) @@ -350,29 +351,31 @@ def as_int_in_env(env_key, default): # (without any notification) when the evaluation is started and pause all threads when the # evaluation is finished. A positive value will run run all threads after the timeout # elapses. -PYDEVD_UNBLOCK_THREADS_TIMEOUT = as_float_in_env('PYDEVD_UNBLOCK_THREADS_TIMEOUT', -1.) +PYDEVD_UNBLOCK_THREADS_TIMEOUT = as_float_in_env("PYDEVD_UNBLOCK_THREADS_TIMEOUT", -1.0) # Timeout to interrupt a thread (so, if some evaluation doesn't finish until this # timeout, the thread doing the evaluation is interrupted). # A value <= 0 means this is disabled. # See: _pydevd_bundle.pydevd_timeout.create_interrupt_this_thread_callback for details # on how the thread interruption works (there are some caveats related to it). -PYDEVD_INTERRUPT_THREAD_TIMEOUT = as_float_in_env('PYDEVD_INTERRUPT_THREAD_TIMEOUT', -1) +PYDEVD_INTERRUPT_THREAD_TIMEOUT = as_float_in_env("PYDEVD_INTERRUPT_THREAD_TIMEOUT", -1) # If PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS is set to False, the patching to hide pydevd threads won't be applied. -PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS = os.getenv('PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS', 'true').lower() in ENV_TRUE_LOWER_VALUES +PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS = ( + os.getenv("PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS", "true").lower() in ENV_TRUE_LOWER_VALUES +) -EXCEPTION_TYPE_UNHANDLED = 'UNHANDLED' -EXCEPTION_TYPE_USER_UNHANDLED = 'USER_UNHANDLED' -EXCEPTION_TYPE_HANDLED = 'HANDLED' +EXCEPTION_TYPE_UNHANDLED = "UNHANDLED" +EXCEPTION_TYPE_USER_UNHANDLED = "USER_UNHANDLED" +EXCEPTION_TYPE_HANDLED = "HANDLED" -SHOW_DEBUG_INFO_ENV = is_true_in_env(('PYCHARM_DEBUG', 'PYDEV_DEBUG', 'PYDEVD_DEBUG')) +SHOW_DEBUG_INFO_ENV = is_true_in_env(("PYCHARM_DEBUG", "PYDEV_DEBUG", "PYDEVD_DEBUG")) if SHOW_DEBUG_INFO_ENV: # show debug info before the debugger start DebugInfoHolder.DEBUG_TRACE_LEVEL = 3 -DebugInfoHolder.PYDEVD_DEBUG_FILE = os.getenv('PYDEVD_DEBUG_FILE') +DebugInfoHolder.PYDEVD_DEBUG_FILE = os.getenv("PYDEVD_DEBUG_FILE") def protect_libraries_from_patching(): @@ -381,9 +384,23 @@ def protect_libraries_from_patching(): `_pydev_saved_modules` in order to save their original copies there. After that we can use these saved modules within the debugger to protect them from patching by external libraries (e.g. gevent). """ - patched = ['threading', 'thread', '_thread', 'time', 'socket', 'queue', 'select', - 'xmlrpclib', 'SimpleXMLRPCServer', 'BaseHTTPServer', 'SocketServer', - 'xmlrpc.client', 'xmlrpc.server', 'http.server', 'socketserver'] + patched = [ + "threading", + "thread", + "_thread", + "time", + "socket", + "queue", + "select", + "xmlrpclib", + "SimpleXMLRPCServer", + "BaseHTTPServer", + "SocketServer", + "xmlrpc.client", + "xmlrpc.server", + "http.server", + "socketserver", + ] for name in patched: try: @@ -391,8 +408,7 @@ def protect_libraries_from_patching(): except: pass - patched_modules = dict([(k, v) for k, v in sys.modules.items() - if k in patched]) + patched_modules = dict([(k, v) for k, v in sys.modules.items() if k in patched]) for name in patched_modules: del sys.modules[name] @@ -422,7 +438,7 @@ def ForkSafeLock(rlock=False): else: class ForkSafeLock(object): - ''' + """ A lock which is fork-safe (when a fork is done, `pydevd_constants.after_fork()` should be called to reset the locks in the new process to avoid deadlocks from a lock which was locked during the fork). @@ -445,7 +461,7 @@ class ForkSafeLock(object): `ForkSafeLock.release` instead of the context manager (as acquire/release are bound to the original implementation, whereas __enter__/__exit__ is not due to Python limitations). - ''' + """ def __init__(self, rlock=False): self._rlock = rlock @@ -470,9 +486,9 @@ def _init(self): def after_fork(): - ''' + """ Must be called after a fork operation (will reset the ForkSafeLock). - ''' + """ global _fork_safe_locks locks = _fork_safe_locks[:] _fork_safe_locks = [] @@ -499,7 +515,6 @@ def filter_all_warnings(): def silence_warnings_decorator(func): - @functools.wraps(func) def new_func(*args, **kwargs): with filter_all_warnings(): @@ -509,8 +524,8 @@ def new_func(*args, **kwargs): def sorted_dict_repr(d): - s = sorted(d.items(), key=lambda x:str(x[0])) - return '{' + ', '.join(('%r: %r' % x) for x in s) + '}' + s = sorted(d.items(), key=lambda x: str(x[0])) + return "{" + ", ".join(("%r: %r" % x) for x in s) + "}" def iter_chars(b): @@ -518,7 +533,7 @@ def iter_chars(b): # changed that behavior so that when iterating bytes we actually get ints! if isinstance(b, bytes): # i.e.: do something as struct.unpack('3c', b) - return iter(struct.unpack(str(len(b)) + 'c', b)) + return iter(struct.unpack(str(len(b)) + "c", b)) return iter(b) @@ -538,9 +553,9 @@ def _temp_trace(frame, event, arg): sys.settrace(_temp_trace) def _check_ftrace_set_none(): - ''' + """ Will throw an error when executing a line event - ''' + """ sys._getframe().f_trace = None _line_event = 1 _line_event = 2 @@ -568,9 +583,9 @@ def NO_FTRACE(frame, event, arg): sys.settrace(_curr_trace) -#======================================================================================================================= +# ======================================================================================================================= # get_pid -#======================================================================================================================= +# ======================================================================================================================= def get_pid(): try: return os.getpid() @@ -578,17 +593,18 @@ def get_pid(): try: # Jython does not have it! import java.lang.management.ManagementFactory # @UnresolvedImport -- just for jython + pid = java.lang.management.ManagementFactory.getRuntimeMXBean().getName() - return pid.replace('@', '_') + return pid.replace("@", "_") except: # ok, no pid available (will be unable to debug multiple processes) - return '000001' + return "000001" def clear_cached_thread_id(thread): with _thread_id_lock: try: - if thread.__pydevd_id__ != 'console_main': + if thread.__pydevd_id__ != "console_main": # The console_main is a special thread id used in the console and its id should never be reset # (otherwise we may no longer be able to get its variables -- see: https://www.brainwy.com/tracker/PyDev/776). del thread.__pydevd_id__ @@ -603,7 +619,7 @@ def clear_cached_thread_id(thread): def _get_or_compute_thread_id_with_lock(thread, is_current_thread): with _thread_id_lock: # We do a new check with the lock in place just to be sure that nothing changed - tid = getattr(thread, '__pydevd_id__', None) + tid = getattr(thread, "__pydevd_id__", None) if tid is not None: return tid @@ -612,7 +628,7 @@ def _get_or_compute_thread_id_with_lock(thread, is_current_thread): # Note: don't use thread.ident because a new thread may have the # same id from an old thread. pid = get_pid() - tid = 'pid_%s_id_%s' % (pid, id(thread)) + tid = "pid_%s_id_%s" % (pid, id(thread)) thread.__pydevd_id__ = tid @@ -620,11 +636,11 @@ def _get_or_compute_thread_id_with_lock(thread, is_current_thread): def get_current_thread_id(thread): - ''' + """ Note: the difference from get_current_thread_id to get_thread_id is that for the current thread we can get the thread id while the thread.ident is still not set in the Thread instance. - ''' + """ try: # Fast path without getting lock. tid = thread.__pydevd_id__ @@ -659,9 +675,9 @@ def set_thread_id(thread, thread_id): thread.__pydevd_id__ = thread_id -#======================================================================================================================= +# ======================================================================================================================= # Null -#======================================================================================================================= +# ======================================================================================================================= class Null: """ Gotten from: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/68205 @@ -680,7 +696,7 @@ def __exit__(self, *args, **kwargs): return self def __getattr__(self, mname): - if len(mname) > 4 and mname[:2] == '__' and mname[-2:] == '__': + if len(mname) > 4 and mname[:2] == "__" and mname[-2:] == "__": # Don't pretend to implement special method names. raise AttributeError(mname) return self @@ -721,7 +737,6 @@ def __iter__(self): class KeyifyList(object): - def __init__(self, inner, key): self.inner = inner self.key = key @@ -734,7 +749,7 @@ def __getitem__(self, k): def call_only_once(func): - ''' + """ To be used as a decorator @call_only_once @@ -744,7 +759,7 @@ def func(): Actually, in PyDev it must be called as: func = call_only_once(func) to support older versions of Python. - ''' + """ def new_func(*args, **kwargs): if not new_func._called: @@ -757,26 +772,26 @@ def new_func(*args, **kwargs): # Protocol where each line is a new message (text is quoted to prevent new lines). # payload is xml -QUOTED_LINE_PROTOCOL = 'quoted-line' -ARGUMENT_QUOTED_LINE_PROTOCOL = 'protocol-quoted-line' +QUOTED_LINE_PROTOCOL = "quoted-line" +ARGUMENT_QUOTED_LINE_PROTOCOL = "protocol-quoted-line" # Uses http protocol to provide a new message. # i.e.: Content-Length:xxx\r\n\r\npayload # payload is xml -HTTP_PROTOCOL = 'http' -ARGUMENT_HTTP_PROTOCOL = 'protocol-http' +HTTP_PROTOCOL = "http" +ARGUMENT_HTTP_PROTOCOL = "protocol-http" # Message is sent without any header. # payload is json -JSON_PROTOCOL = 'json' -ARGUMENT_JSON_PROTOCOL = 'json-dap' +JSON_PROTOCOL = "json" +ARGUMENT_JSON_PROTOCOL = "json-dap" # Same header as the HTTP_PROTOCOL # payload is json -HTTP_JSON_PROTOCOL = 'http_json' -ARGUMENT_HTTP_JSON_PROTOCOL = 'json-dap-http' +HTTP_JSON_PROTOCOL = "http_json" +ARGUMENT_HTTP_JSON_PROTOCOL = "json-dap-http" -ARGUMENT_PPID = 'ppid' +ARGUMENT_PPID = "ppid" class _GlobalSettings: @@ -785,8 +800,7 @@ class _GlobalSettings: def set_protocol(protocol): expected = (HTTP_PROTOCOL, QUOTED_LINE_PROTOCOL, JSON_PROTOCOL, HTTP_JSON_PROTOCOL) - assert protocol in expected, 'Protocol (%s) should be one of: %s' % ( - protocol, expected) + assert protocol in expected, "Protocol (%s) should be one of: %s" % (protocol, expected) _GlobalSettings.protocol = protocol @@ -800,9 +814,10 @@ def is_json_protocol(): class GlobalDebuggerHolder: - ''' - Holder for the global debugger. - ''' + """ + Holder for the global debugger. + """ + global_dbg = None # Note: don't rename (the name is used in our attach to process) @@ -817,7 +832,6 @@ def set_global_debugger(dbg): GlobalDebuggerHolder.global_dbg = dbg -if __name__ == '__main__': +if __name__ == "__main__": if Null(): - sys.stdout.write('here\n') - + sys.stdout.write("here\n") diff --git a/_pydevd_bundle/pydevd_custom_frames.py b/_pydevd_bundle/pydevd_custom_frames.py index 66e400fbf..65c83c458 100644 --- a/_pydevd_bundle/pydevd_custom_frames.py +++ b/_pydevd_bundle/pydevd_custom_frames.py @@ -8,7 +8,6 @@ class CustomFramesContainer: - # Actual Values initialized later on. custom_frames_lock = None # : :type custom_frames_lock: threading.Lock @@ -20,7 +19,6 @@ class CustomFramesContainer: def custom_frames_container_init(): # Note: no staticmethod on jython 2.1 (so, use free-function) - CustomFramesContainer.custom_frames_lock = ForkSafeLock() # custom_frames can only be accessed if properly locked with custom_frames_lock! @@ -42,7 +40,6 @@ def custom_frames_container_init(): # Note: no staticmethod on jython 2.1 (so, class CustomFrame: - def __init__(self, name, frame, thread_id): # 0 = string with the representation of that frame self.name = name @@ -58,7 +55,7 @@ def __init__(self, name, frame, thread_id): def add_custom_frame(frame, name, thread_id): - ''' + """ It's possible to show paused frames by adding a custom frame through this API (it's intended to be used for coroutines, but could potentially be used for generators too). @@ -73,17 +70,19 @@ def add_custom_frame(frame, name, thread_id): :return: str Returns the custom thread id which will be used to show the given frame paused. - ''' + """ with CustomFramesContainer.custom_frames_lock: curr_thread_id = get_current_thread_id(threading.current_thread()) next_id = CustomFramesContainer._next_frame_id = CustomFramesContainer._next_frame_id + 1 # Note: the frame id kept contains an id and thread information on the thread where the frame was added # so that later on we can check if the frame is from the current thread by doing frame_id.endswith('|'+thread_id). - frame_custom_thread_id = '__frame__:%s|%s' % (next_id, curr_thread_id) + frame_custom_thread_id = "__frame__:%s|%s" % (next_id, curr_thread_id) if DEBUG: - sys.stderr.write('add_custom_frame: %s (%s) %s %s\n' % ( - frame_custom_thread_id, get_abs_path_real_path_and_base_from_frame(frame)[-1], frame.f_lineno, frame.f_code.co_name)) + sys.stderr.write( + "add_custom_frame: %s (%s) %s %s\n" + % (frame_custom_thread_id, get_abs_path_real_path_and_base_from_frame(frame)[-1], frame.f_lineno, frame.f_code.co_name) + ) CustomFramesContainer.custom_frames[frame_custom_thread_id] = CustomFrame(name, frame, thread_id) CustomFramesContainer._py_db_command_thread_event.set() @@ -93,7 +92,7 @@ def add_custom_frame(frame, name, thread_id): def update_custom_frame(frame_custom_thread_id, frame, thread_id, name=None): with CustomFramesContainer.custom_frames_lock: if DEBUG: - sys.stderr.write('update_custom_frame: %s\n' % frame_custom_thread_id) + sys.stderr.write("update_custom_frame: %s\n" % frame_custom_thread_id) try: old = CustomFramesContainer.custom_frames[frame_custom_thread_id] if name is not None: @@ -101,7 +100,7 @@ def update_custom_frame(frame_custom_thread_id, frame, thread_id, name=None): old.mod_time += 1 old.thread_id = thread_id except: - sys.stderr.write('Unable to get frame to replace: %s\n' % (frame_custom_thread_id,)) + sys.stderr.write("Unable to get frame to replace: %s\n" % (frame_custom_thread_id,)) pydev_log.exception() CustomFramesContainer._py_db_command_thread_event.set() @@ -110,7 +109,6 @@ def update_custom_frame(frame_custom_thread_id, frame, thread_id, name=None): def remove_custom_frame(frame_custom_thread_id): with CustomFramesContainer.custom_frames_lock: if DEBUG: - sys.stderr.write('remove_custom_frame: %s\n' % frame_custom_thread_id) + sys.stderr.write("remove_custom_frame: %s\n" % frame_custom_thread_id) CustomFramesContainer.custom_frames.pop(frame_custom_thread_id, None) CustomFramesContainer._py_db_command_thread_event.set() - diff --git a/_pydevd_bundle/pydevd_cython_wrapper.py b/_pydevd_bundle/pydevd_cython_wrapper.py index 0323f6ca5..4d5038c43 100644 --- a/_pydevd_bundle/pydevd_cython_wrapper.py +++ b/_pydevd_bundle/pydevd_cython_wrapper.py @@ -1,4 +1,5 @@ import sys + try: try: from _pydevd_bundle_ext import pydevd_cython as mod @@ -10,13 +11,13 @@ import struct try: - is_python_64bit = (struct.calcsize('P') == 8) + is_python_64bit = struct.calcsize("P") == 8 except: # In Jython this call fails, but this is Ok, we don't support Jython for speedups anyways. raise ImportError - plat = '32' + plat = "32" if is_python_64bit: - plat = '64' + plat = "64" # We also accept things as: # @@ -26,14 +27,14 @@ # to have multiple pre-compiled pyds distributed along the IDE # (generated by build_tools/build_binaries_windows.py). - mod_name = 'pydevd_cython_%s_%s%s_%s' % (sys.platform, sys.version_info[0], sys.version_info[1], plat) - check_name = '_pydevd_bundle.%s' % (mod_name,) + mod_name = "pydevd_cython_%s_%s%s_%s" % (sys.platform, sys.version_info[0], sys.version_info[1], plat) + check_name = "_pydevd_bundle.%s" % (mod_name,) mod = getattr(__import__(check_name), mod_name) # Regardless of how it was found, make sure it's later available as the # initial name so that the expected types from cython in frame eval # are valid. -sys.modules['_pydevd_bundle.pydevd_cython'] = mod +sys.modules["_pydevd_bundle.pydevd_cython"] = mod trace_dispatch = mod.trace_dispatch @@ -59,4 +60,4 @@ is_unhandled_exception = mod.is_unhandled_exception -version = getattr(mod, 'version', 0) +version = getattr(mod, "version", 0) diff --git a/_pydevd_bundle/pydevd_daemon_thread.py b/_pydevd_bundle/pydevd_daemon_thread.py index 228737a26..de2f59874 100644 --- a/_pydevd_bundle/pydevd_daemon_thread.py +++ b/_pydevd_bundle/pydevd_daemon_thread.py @@ -2,8 +2,12 @@ from _pydev_bundle import _pydev_saved_modules from _pydevd_bundle.pydevd_utils import notify_about_gevent_if_needed import weakref -from _pydevd_bundle.pydevd_constants import IS_JYTHON, IS_IRONPYTHON, \ - PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS, PYDEVD_USE_SYS_MONITORING +from _pydevd_bundle.pydevd_constants import ( + IS_JYTHON, + IS_IRONPYTHON, + PYDEVD_APPLY_PATCHING_TO_HIDE_PYDEVD_THREADS, + PYDEVD_USE_SYS_MONITORING, +) from _pydev_bundle.pydev_log import exception as pydev_log_exception import sys from _pydev_bundle import pydev_log @@ -16,13 +20,12 @@ class PyDBDaemonThread(threading.Thread): - def __init__(self, py_db, target_and_args=None): - ''' + """ :param target_and_args: tuple(func, args, kwargs) if this should be a function and args to run. -- Note: use through run_as_pydevd_daemon_thread(). - ''' + """ threading.Thread.__init__(self) notify_about_gevent_if_needed() self._py_db = weakref.ref(py_db) @@ -59,11 +62,11 @@ def _on_run(self): target, args, kwargs = self._target_and_args target(*args, **kwargs) else: - raise NotImplementedError('Should be reimplemented by: %s' % self.__class__) + raise NotImplementedError("Should be reimplemented by: %s" % self.__class__) def do_kill_pydev_thread(self): if not self._kill_received: - pydev_log.debug('%s received kill signal', self.name) + pydev_log.debug("%s received kill signal", self.name) self._kill_received = True def _stop_trace(self): @@ -77,47 +80,47 @@ def _stop_trace(self): def _collect_load_names(func): found_load_names = set() for instruction in iter_instructions(func.__code__): - if instruction.opname in ('LOAD_GLOBAL', 'LOAD_ATTR', 'LOAD_METHOD'): + if instruction.opname in ("LOAD_GLOBAL", "LOAD_ATTR", "LOAD_METHOD"): found_load_names.add(instruction.argrepr) return found_load_names def _patch_threading_to_hide_pydevd_threads(): - ''' + """ Patches the needed functions on the `threading` module so that the pydevd threads are hidden. Note that we patch the functions __code__ to avoid issues if some code had already imported those variables prior to the patching. - ''' + """ found_load_names = _collect_load_names(threading.enumerate) # i.e.: we'll only apply the patching if the function seems to be what we expect. new_threading_enumerate = None if found_load_names in ( - {'_active_limbo_lock', '_limbo', '_active', 'values', 'list'}, - {'_active_limbo_lock', '_limbo', '_active', 'values', 'NULL + list'}, - {'NULL + list', '_active', '_active_limbo_lock', 'NULL|self + values', '_limbo'} - ): - pydev_log.debug('Applying patching to hide pydevd threads (Py3 version).') + {"_active_limbo_lock", "_limbo", "_active", "values", "list"}, + {"_active_limbo_lock", "_limbo", "_active", "values", "NULL + list"}, + {"NULL + list", "_active", "_active_limbo_lock", "NULL|self + values", "_limbo"}, + ): + pydev_log.debug("Applying patching to hide pydevd threads (Py3 version).") def new_threading_enumerate(): with _active_limbo_lock: ret = list(_active.values()) + list(_limbo.values()) - return [t for t in ret if not getattr(t, 'is_pydev_daemon_thread', False)] + return [t for t in ret if not getattr(t, "is_pydev_daemon_thread", False)] - elif found_load_names == set(('_active_limbo_lock', '_limbo', '_active', 'values')): - pydev_log.debug('Applying patching to hide pydevd threads (Py2 version).') + elif found_load_names == set(("_active_limbo_lock", "_limbo", "_active", "values")): + pydev_log.debug("Applying patching to hide pydevd threads (Py2 version).") def new_threading_enumerate(): with _active_limbo_lock: ret = _active.values() + _limbo.values() - return [t for t in ret if not getattr(t, 'is_pydev_daemon_thread', False)] + return [t for t in ret if not getattr(t, "is_pydev_daemon_thread", False)] else: - pydev_log.info('Unable to hide pydevd threads. Found names in threading.enumerate: %s', found_load_names) + pydev_log.info("Unable to hide pydevd threads. Found names in threading.enumerate: %s", found_load_names) if new_threading_enumerate is not None: @@ -148,7 +151,7 @@ def new_active_count(): # But in this particular case, we do want threads with `is_pydev_daemon_thread` to appear # explicitly due to the pydevd `CheckAliveThread` (because we want the shutdown to wait on it). # So, it can't rely on the `enumerate` for that anymore as it's patched to not return pydevd threads. - if hasattr(threading, '_pickSomeNonDaemonThread'): + if hasattr(threading, "_pickSomeNonDaemonThread"): def new_pick_some_non_daemon_thread(): with _active_limbo_lock: @@ -181,7 +184,7 @@ def mark_as_pydevd_daemon_thread(thread): try: _patch_threading_to_hide_pydevd_threads() except: - pydev_log.exception('Error applying patching to hide pydevd threads.') + pydev_log.exception("Error applying patching to hide pydevd threads.") thread.pydev_do_not_trace = True thread.is_pydev_daemon_thread = True @@ -189,10 +192,10 @@ def mark_as_pydevd_daemon_thread(thread): def run_as_pydevd_daemon_thread(py_db, func, *args, **kwargs): - ''' + """ Runs a function as a pydevd daemon thread (without any tracing in place). - ''' + """ t = PyDBDaemonThread(py_db, target_and_args=(func, args, kwargs)) - t.name = '%s (pydevd daemon thread)' % (func.__name__,) + t.name = "%s (pydevd daemon thread)" % (func.__name__,) t.start() return t diff --git a/_pydevd_bundle/pydevd_defaults.py b/_pydevd_bundle/pydevd_defaults.py index 918ce719e..b32576baa 100644 --- a/_pydevd_bundle/pydevd_defaults.py +++ b/_pydevd_bundle/pydevd_defaults.py @@ -1,6 +1,6 @@ -''' +""" This module holds the customization settings for the debugger. -''' +""" from _pydevd_bundle.pydevd_constants import QUOTED_LINE_PROTOCOL from _pydev_bundle import pydev_log @@ -17,7 +17,7 @@ class PydevdCustomization(object): # py_db.skip_suspend_on_breakpoint_exception = (BaseException,) # py_db.skip_print_breakpoint_exception = (NameError,) # py_db.multi_threads_single_notification = True - DEBUG_MODE: str = '' + DEBUG_MODE: str = "" # This may be a ; to be pre-imported # Something as: 'c:/temp/foo;my_module.bar' @@ -33,24 +33,24 @@ class PydevdCustomization(object): # If the pre-import fails an output message is # sent (but apart from that debugger execution # should continue). - PREIMPORT: str = '' + PREIMPORT: str = "" def on_pydb_init(py_db): - if PydevdCustomization.DEBUG_MODE == 'debugpy-dap': - pydev_log.debug('Apply debug mode: debugpy-dap') + if PydevdCustomization.DEBUG_MODE == "debugpy-dap": + pydev_log.debug("Apply debug mode: debugpy-dap") py_db.skip_suspend_on_breakpoint_exception = (BaseException,) py_db.skip_print_breakpoint_exception = (NameError,) py_db.multi_threads_single_notification = True elif not PydevdCustomization.DEBUG_MODE: - pydev_log.debug('Apply debug mode: default') + pydev_log.debug("Apply debug mode: default") else: - pydev_log.debug('WARNING: unknown debug mode: %s', PydevdCustomization.DEBUG_MODE) + pydev_log.debug("WARNING: unknown debug mode: %s", PydevdCustomization.DEBUG_MODE) if PydevdCustomization.PREIMPORT: - pydev_log.debug('Preimport: %s', PydevdCustomization.PREIMPORT) + pydev_log.debug("Preimport: %s", PydevdCustomization.PREIMPORT) try: - sys_path_entry, module_name = PydevdCustomization.PREIMPORT.rsplit(';', maxsplit=1) + sys_path_entry, module_name = PydevdCustomization.PREIMPORT.rsplit(";", maxsplit=1) except Exception: pydev_log.exception("Expected ';' in %s" % (PydevdCustomization.PREIMPORT,)) else: @@ -61,6 +61,4 @@ def on_pydb_init(py_db): finally: sys.path.remove(sys_path_entry) except Exception: - pydev_log.exception( - "Error importing %s (with sys.path entry: %s)" % (module_name, sys_path_entry)) - + pydev_log.exception("Error importing %s (with sys.path entry: %s)" % (module_name, sys_path_entry)) diff --git a/_pydevd_bundle/pydevd_dont_trace.py b/_pydevd_bundle/pydevd_dont_trace.py index d43aac8bf..500cbcefc 100644 --- a/_pydevd_bundle/pydevd_dont_trace.py +++ b/_pydevd_bundle/pydevd_dont_trace.py @@ -1,6 +1,6 @@ -''' +""" Support for a tag that allows skipping over functions while debugging. -''' +""" import linecache import re @@ -17,11 +17,11 @@ # # def test2(): #@DontTrace # pass -DONT_TRACE_TAG = '@DontTrace' +DONT_TRACE_TAG = "@DontTrace" # Regular expression to match a decorator (at the beginning # of a line). -RE_DECORATOR = re.compile(r'^\s*@') +RE_DECORATOR = re.compile(r"^\s*@") # Mapping from code object to bool. # If the key exists, the value is the cached result of should_trace_hook @@ -29,9 +29,9 @@ def default_should_trace_hook(code, absolute_filename): - ''' + """ Return True if this frame should be traced, False if tracing should be blocked. - ''' + """ # First, check whether this code object has a cached value ignored_lines = _filename_to_ignored_lines.get(absolute_filename) if ignored_lines is None: @@ -47,7 +47,7 @@ def default_should_trace_hook(code, absolute_filename): ignored_lines = {} lines = linecache.getlines(absolute_filename) for i_line, line in enumerate(lines): - j = line.find('#') + j = line.find("#") if j >= 0: comment = line[j:] if DONT_TRACE_TAG in comment: @@ -74,18 +74,19 @@ def default_should_trace_hook(code, absolute_filename): func_line = code.co_firstlineno - 1 # co_firstlineno is 1-based, so -1 is needed return not ( - func_line - 1 in ignored_lines or # -1 to get line before method - func_line in ignored_lines) # method line + func_line - 1 in ignored_lines # -1 to get line before method + or func_line in ignored_lines + ) # method line should_trace_hook = None def clear_trace_filter_cache(): - ''' + """ Clear the trace filter cache. Call this after reloading. - ''' + """ global should_trace_hook try: # Need to temporarily disable a hook because otherwise @@ -102,14 +103,14 @@ def clear_trace_filter_cache(): def trace_filter(mode): - ''' + """ Set the trace filter mode. mode: Whether to enable the trace hook. True: Trace filtering on (skipping methods tagged @DontTrace) False: Trace filtering off (trace methods tagged @DontTrace) None/default: Toggle trace filtering. - ''' + """ global should_trace_hook if mode is None: mode = should_trace_hook is None @@ -120,4 +121,3 @@ def trace_filter(mode): should_trace_hook = None return mode - diff --git a/_pydevd_bundle/pydevd_dont_trace_files.py b/_pydevd_bundle/pydevd_dont_trace_files.py index f4b15a1af..800b3a435 100644 --- a/_pydevd_bundle/pydevd_dont_trace_files.py +++ b/_pydevd_bundle/pydevd_dont_trace_files.py @@ -7,168 +7,167 @@ PYDEV_FILE = 2 DONT_TRACE_DIRS = { - '_pydev_bundle': PYDEV_FILE, - '_pydev_runfiles': PYDEV_FILE, - '_pydevd_bundle': PYDEV_FILE, - '_pydevd_frame_eval': PYDEV_FILE, - '_pydevd_sys_monitoring': PYDEV_FILE, - 'pydev_ipython': LIB_FILE, - 'pydev_sitecustomize': PYDEV_FILE, - 'pydevd_attach_to_process': PYDEV_FILE, - 'pydevd_concurrency_analyser': PYDEV_FILE, - 'pydevd_plugins': PYDEV_FILE, - 'test_pydevd_reload': PYDEV_FILE, + "_pydev_bundle": PYDEV_FILE, + "_pydev_runfiles": PYDEV_FILE, + "_pydevd_bundle": PYDEV_FILE, + "_pydevd_frame_eval": PYDEV_FILE, + "_pydevd_sys_monitoring": PYDEV_FILE, + "pydev_ipython": LIB_FILE, + "pydev_sitecustomize": PYDEV_FILE, + "pydevd_attach_to_process": PYDEV_FILE, + "pydevd_concurrency_analyser": PYDEV_FILE, + "pydevd_plugins": PYDEV_FILE, + "test_pydevd_reload": PYDEV_FILE, } LIB_FILES_IN_DONT_TRACE_DIRS = { - '__init__.py', - 'inputhook.py', - 'inputhookglut.py', - 'inputhookgtk.py', - 'inputhookgtk3.py', - 'inputhookpyglet.py', - 'inputhookqt4.py', - 'inputhookqt5.py', - 'inputhooktk.py', - 'inputhookwx.py', - 'matplotlibtools.py', - 'qt.py', - 'qt_for_kernel.py', - 'qt_loaders.py', - 'version.py', + "__init__.py", + "inputhook.py", + "inputhookglut.py", + "inputhookgtk.py", + "inputhookgtk3.py", + "inputhookpyglet.py", + "inputhookqt4.py", + "inputhookqt5.py", + "inputhooktk.py", + "inputhookwx.py", + "matplotlibtools.py", + "qt.py", + "qt_for_kernel.py", + "qt_loaders.py", + "version.py", } DONT_TRACE = { # commonly used things from the stdlib that we don't want to trace - 'Queue.py':LIB_FILE, - 'queue.py':LIB_FILE, - 'socket.py':LIB_FILE, - 'weakref.py':LIB_FILE, - '_weakrefset.py':LIB_FILE, - 'linecache.py':LIB_FILE, - 'threading.py':LIB_FILE, - 'dis.py':LIB_FILE, - + "Queue.py": LIB_FILE, + "queue.py": LIB_FILE, + "socket.py": LIB_FILE, + "weakref.py": LIB_FILE, + "_weakrefset.py": LIB_FILE, + "linecache.py": LIB_FILE, + "threading.py": LIB_FILE, + "dis.py": LIB_FILE, # things from pydev that we don't want to trace - '__main__pydevd_gen_debug_adapter_protocol.py': PYDEV_FILE, - '_pydev_calltip_util.py': PYDEV_FILE, - '_pydev_completer.py': PYDEV_FILE, - '_pydev_execfile.py': PYDEV_FILE, - '_pydev_filesystem_encoding.py': PYDEV_FILE, - '_pydev_getopt.py': PYDEV_FILE, - '_pydev_imports_tipper.py': PYDEV_FILE, - '_pydev_jy_imports_tipper.py': PYDEV_FILE, - '_pydev_log.py': PYDEV_FILE, - '_pydev_saved_modules.py': PYDEV_FILE, - '_pydev_sys_patch.py': PYDEV_FILE, - '_pydev_tipper_common.py': PYDEV_FILE, - '_pydevd_sys_monitoring.py': PYDEV_FILE, - 'django_debug.py': PYDEV_FILE, - 'jinja2_debug.py': PYDEV_FILE, - 'pycompletionserver.py': PYDEV_FILE, - 'pydev_app_engine_debug_startup.py': PYDEV_FILE, - 'pydev_console_utils.py': PYDEV_FILE, - 'pydev_import_hook.py': PYDEV_FILE, - 'pydev_imports.py': PYDEV_FILE, - 'pydev_ipython_console.py': PYDEV_FILE, - 'pydev_ipython_console_011.py': PYDEV_FILE, - 'pydev_is_thread_alive.py': PYDEV_FILE, - 'pydev_localhost.py': PYDEV_FILE, - 'pydev_log.py': PYDEV_FILE, - 'pydev_monkey.py': PYDEV_FILE, - 'pydev_monkey_qt.py': PYDEV_FILE, - 'pydev_override.py': PYDEV_FILE, - 'pydev_run_in_console.py': PYDEV_FILE, - 'pydev_runfiles.py': PYDEV_FILE, - 'pydev_runfiles_coverage.py': PYDEV_FILE, - 'pydev_runfiles_nose.py': PYDEV_FILE, - 'pydev_runfiles_parallel.py': PYDEV_FILE, - 'pydev_runfiles_parallel_client.py': PYDEV_FILE, - 'pydev_runfiles_pytest2.py': PYDEV_FILE, - 'pydev_runfiles_unittest.py': PYDEV_FILE, - 'pydev_runfiles_xml_rpc.py': PYDEV_FILE, - 'pydev_umd.py': PYDEV_FILE, - 'pydev_versioncheck.py': PYDEV_FILE, - 'pydevconsole.py': PYDEV_FILE, - 'pydevconsole_code.py': PYDEV_FILE, - 'pydevd.py': PYDEV_FILE, - 'pydevd_additional_thread_info.py': PYDEV_FILE, - 'pydevd_additional_thread_info_regular.py': PYDEV_FILE, - 'pydevd_api.py': PYDEV_FILE, - 'pydevd_base_schema.py': PYDEV_FILE, - 'pydevd_breakpoints.py': PYDEV_FILE, - 'pydevd_bytecode_utils.py': PYDEV_FILE, - 'pydevd_bytecode_utils_py311.py': PYDEV_FILE, - 'pydevd_code_to_source.py': PYDEV_FILE, - 'pydevd_collect_bytecode_info.py': PYDEV_FILE, - 'pydevd_comm.py': PYDEV_FILE, - 'pydevd_comm_constants.py': PYDEV_FILE, - 'pydevd_command_line_handling.py': PYDEV_FILE, - 'pydevd_concurrency_logger.py': PYDEV_FILE, - 'pydevd_console.py': PYDEV_FILE, - 'pydevd_constants.py': PYDEV_FILE, - 'pydevd_custom_frames.py': PYDEV_FILE, - 'pydevd_cython_wrapper.py': PYDEV_FILE, - 'pydevd_daemon_thread.py': PYDEV_FILE, - 'pydevd_defaults.py': PYDEV_FILE, - 'pydevd_dont_trace.py': PYDEV_FILE, - 'pydevd_dont_trace_files.py': PYDEV_FILE, - 'pydevd_exec2.py': PYDEV_FILE, - 'pydevd_extension_api.py': PYDEV_FILE, - 'pydevd_extension_utils.py': PYDEV_FILE, - 'pydevd_file_utils.py': PYDEV_FILE, - 'pydevd_filtering.py': PYDEV_FILE, - 'pydevd_frame.py': PYDEV_FILE, - 'pydevd_frame_eval_cython_wrapper.py': PYDEV_FILE, - 'pydevd_frame_eval_main.py': PYDEV_FILE, - 'pydevd_frame_tracing.py': PYDEV_FILE, - 'pydevd_frame_utils.py': PYDEV_FILE, - 'pydevd_gevent_integration.py': PYDEV_FILE, - 'pydevd_helpers.py': PYDEV_FILE, - 'pydevd_import_class.py': PYDEV_FILE, - 'pydevd_io.py': PYDEV_FILE, - 'pydevd_json_debug_options.py': PYDEV_FILE, - 'pydevd_line_validation.py': PYDEV_FILE, - 'pydevd_modify_bytecode.py': PYDEV_FILE, - 'pydevd_net_command.py': PYDEV_FILE, - 'pydevd_net_command_factory_json.py': PYDEV_FILE, - 'pydevd_net_command_factory_xml.py': PYDEV_FILE, - 'pydevd_plugin_numpy_types.py': PYDEV_FILE, - 'pydevd_plugin_pandas_types.py': PYDEV_FILE, - 'pydevd_plugin_utils.py': PYDEV_FILE, - 'pydevd_plugins_django_form_str.py': PYDEV_FILE, - 'pydevd_process_net_command.py': PYDEV_FILE, - 'pydevd_process_net_command_json.py': PYDEV_FILE, - 'pydevd_referrers.py': PYDEV_FILE, - 'pydevd_reload.py': PYDEV_FILE, - 'pydevd_resolver.py': PYDEV_FILE, - 'pydevd_runpy.py': PYDEV_FILE, - 'pydevd_safe_repr.py': PYDEV_FILE, - 'pydevd_save_locals.py': PYDEV_FILE, - 'pydevd_schema.py': PYDEV_FILE, - 'pydevd_schema_log.py': PYDEV_FILE, - 'pydevd_signature.py': PYDEV_FILE, - 'pydevd_source_mapping.py': PYDEV_FILE, - 'pydevd_stackless.py': PYDEV_FILE, - 'pydevd_suspended_frames.py': PYDEV_FILE, - 'pydevd_sys_monitoring.py': PYDEV_FILE, - 'pydevd_thread_lifecycle.py': PYDEV_FILE, - 'pydevd_thread_wrappers.py': PYDEV_FILE, - 'pydevd_timeout.py': PYDEV_FILE, - 'pydevd_trace_dispatch.py': PYDEV_FILE, - 'pydevd_trace_dispatch_regular.py': PYDEV_FILE, - 'pydevd_traceproperty.py': PYDEV_FILE, - 'pydevd_tracing.py': PYDEV_FILE, - 'pydevd_utils.py': PYDEV_FILE, - 'pydevd_vars.py': PYDEV_FILE, - 'pydevd_vm_type.py': PYDEV_FILE, - 'pydevd_xml.py': PYDEV_FILE, + "__main__pydevd_gen_debug_adapter_protocol.py": PYDEV_FILE, + "_pydev_calltip_util.py": PYDEV_FILE, + "_pydev_completer.py": PYDEV_FILE, + "_pydev_execfile.py": PYDEV_FILE, + "_pydev_filesystem_encoding.py": PYDEV_FILE, + "_pydev_getopt.py": PYDEV_FILE, + "_pydev_imports_tipper.py": PYDEV_FILE, + "_pydev_jy_imports_tipper.py": PYDEV_FILE, + "_pydev_log.py": PYDEV_FILE, + "_pydev_saved_modules.py": PYDEV_FILE, + "_pydev_sys_patch.py": PYDEV_FILE, + "_pydev_tipper_common.py": PYDEV_FILE, + "_pydevd_sys_monitoring.py": PYDEV_FILE, + "django_debug.py": PYDEV_FILE, + "jinja2_debug.py": PYDEV_FILE, + "pycompletionserver.py": PYDEV_FILE, + "pydev_app_engine_debug_startup.py": PYDEV_FILE, + "pydev_console_utils.py": PYDEV_FILE, + "pydev_import_hook.py": PYDEV_FILE, + "pydev_imports.py": PYDEV_FILE, + "pydev_ipython_console.py": PYDEV_FILE, + "pydev_ipython_console_011.py": PYDEV_FILE, + "pydev_is_thread_alive.py": PYDEV_FILE, + "pydev_localhost.py": PYDEV_FILE, + "pydev_log.py": PYDEV_FILE, + "pydev_monkey.py": PYDEV_FILE, + "pydev_monkey_qt.py": PYDEV_FILE, + "pydev_override.py": PYDEV_FILE, + "pydev_run_in_console.py": PYDEV_FILE, + "pydev_runfiles.py": PYDEV_FILE, + "pydev_runfiles_coverage.py": PYDEV_FILE, + "pydev_runfiles_nose.py": PYDEV_FILE, + "pydev_runfiles_parallel.py": PYDEV_FILE, + "pydev_runfiles_parallel_client.py": PYDEV_FILE, + "pydev_runfiles_pytest2.py": PYDEV_FILE, + "pydev_runfiles_unittest.py": PYDEV_FILE, + "pydev_runfiles_xml_rpc.py": PYDEV_FILE, + "pydev_umd.py": PYDEV_FILE, + "pydev_versioncheck.py": PYDEV_FILE, + "pydevconsole.py": PYDEV_FILE, + "pydevconsole_code.py": PYDEV_FILE, + "pydevd.py": PYDEV_FILE, + "pydevd_additional_thread_info.py": PYDEV_FILE, + "pydevd_additional_thread_info_regular.py": PYDEV_FILE, + "pydevd_api.py": PYDEV_FILE, + "pydevd_base_schema.py": PYDEV_FILE, + "pydevd_breakpoints.py": PYDEV_FILE, + "pydevd_bytecode_utils.py": PYDEV_FILE, + "pydevd_bytecode_utils_py311.py": PYDEV_FILE, + "pydevd_code_to_source.py": PYDEV_FILE, + "pydevd_collect_bytecode_info.py": PYDEV_FILE, + "pydevd_comm.py": PYDEV_FILE, + "pydevd_comm_constants.py": PYDEV_FILE, + "pydevd_command_line_handling.py": PYDEV_FILE, + "pydevd_concurrency_logger.py": PYDEV_FILE, + "pydevd_console.py": PYDEV_FILE, + "pydevd_constants.py": PYDEV_FILE, + "pydevd_custom_frames.py": PYDEV_FILE, + "pydevd_cython_wrapper.py": PYDEV_FILE, + "pydevd_daemon_thread.py": PYDEV_FILE, + "pydevd_defaults.py": PYDEV_FILE, + "pydevd_dont_trace.py": PYDEV_FILE, + "pydevd_dont_trace_files.py": PYDEV_FILE, + "pydevd_exec2.py": PYDEV_FILE, + "pydevd_extension_api.py": PYDEV_FILE, + "pydevd_extension_utils.py": PYDEV_FILE, + "pydevd_file_utils.py": PYDEV_FILE, + "pydevd_filtering.py": PYDEV_FILE, + "pydevd_frame.py": PYDEV_FILE, + "pydevd_frame_eval_cython_wrapper.py": PYDEV_FILE, + "pydevd_frame_eval_main.py": PYDEV_FILE, + "pydevd_frame_tracing.py": PYDEV_FILE, + "pydevd_frame_utils.py": PYDEV_FILE, + "pydevd_gevent_integration.py": PYDEV_FILE, + "pydevd_helpers.py": PYDEV_FILE, + "pydevd_import_class.py": PYDEV_FILE, + "pydevd_io.py": PYDEV_FILE, + "pydevd_json_debug_options.py": PYDEV_FILE, + "pydevd_line_validation.py": PYDEV_FILE, + "pydevd_modify_bytecode.py": PYDEV_FILE, + "pydevd_net_command.py": PYDEV_FILE, + "pydevd_net_command_factory_json.py": PYDEV_FILE, + "pydevd_net_command_factory_xml.py": PYDEV_FILE, + "pydevd_plugin_numpy_types.py": PYDEV_FILE, + "pydevd_plugin_pandas_types.py": PYDEV_FILE, + "pydevd_plugin_utils.py": PYDEV_FILE, + "pydevd_plugins_django_form_str.py": PYDEV_FILE, + "pydevd_process_net_command.py": PYDEV_FILE, + "pydevd_process_net_command_json.py": PYDEV_FILE, + "pydevd_referrers.py": PYDEV_FILE, + "pydevd_reload.py": PYDEV_FILE, + "pydevd_resolver.py": PYDEV_FILE, + "pydevd_runpy.py": PYDEV_FILE, + "pydevd_safe_repr.py": PYDEV_FILE, + "pydevd_save_locals.py": PYDEV_FILE, + "pydevd_schema.py": PYDEV_FILE, + "pydevd_schema_log.py": PYDEV_FILE, + "pydevd_signature.py": PYDEV_FILE, + "pydevd_source_mapping.py": PYDEV_FILE, + "pydevd_stackless.py": PYDEV_FILE, + "pydevd_suspended_frames.py": PYDEV_FILE, + "pydevd_sys_monitoring.py": PYDEV_FILE, + "pydevd_thread_lifecycle.py": PYDEV_FILE, + "pydevd_thread_wrappers.py": PYDEV_FILE, + "pydevd_timeout.py": PYDEV_FILE, + "pydevd_trace_dispatch.py": PYDEV_FILE, + "pydevd_trace_dispatch_regular.py": PYDEV_FILE, + "pydevd_traceproperty.py": PYDEV_FILE, + "pydevd_tracing.py": PYDEV_FILE, + "pydevd_utils.py": PYDEV_FILE, + "pydevd_vars.py": PYDEV_FILE, + "pydevd_vm_type.py": PYDEV_FILE, + "pydevd_xml.py": PYDEV_FILE, } # if we try to trace io.py it seems it can get halted (see http://bugs.python.org/issue4716) -DONT_TRACE['io.py'] = LIB_FILE +DONT_TRACE["io.py"] = LIB_FILE # Don't trace common encodings too -DONT_TRACE['cp1252.py'] = LIB_FILE -DONT_TRACE['utf_8.py'] = LIB_FILE -DONT_TRACE['codecs.py'] = LIB_FILE +DONT_TRACE["cp1252.py"] = LIB_FILE +DONT_TRACE["utf_8.py"] = LIB_FILE +DONT_TRACE["codecs.py"] = LIB_FILE diff --git a/_pydevd_bundle/pydevd_exec2.py b/_pydevd_bundle/pydevd_exec2.py index ee4f37a6c..486e8eb1d 100644 --- a/_pydevd_bundle/pydevd_exec2.py +++ b/_pydevd_bundle/pydevd_exec2.py @@ -2,4 +2,4 @@ def Exec(exp, global_vars, local_vars=None): if local_vars is not None: exec(exp, global_vars, local_vars) else: - exec(exp, global_vars) \ No newline at end of file + exec(exp, global_vars) diff --git a/_pydevd_bundle/pydevd_extension_api.py b/_pydevd_bundle/pydevd_extension_api.py index 8c5a441b1..8cabe7995 100644 --- a/_pydevd_bundle/pydevd_extension_api.py +++ b/_pydevd_bundle/pydevd_extension_api.py @@ -7,11 +7,10 @@ def _with_metaclass(meta, *bases): """Create a base class with a metaclass.""" class metaclass(meta): - def __new__(cls, name, this_bases, d): return meta(name, bases, d) - return type.__new__(metaclass, 'temporary_class', (), {}) + return type.__new__(metaclass, "temporary_class", (), {}) # ======================================================================================================================= @@ -50,11 +49,11 @@ def get_dictionary(self, var): class _AbstractProvider(_with_metaclass(abc.ABCMeta)): - @abc.abstractmethod def can_provide(self, type_object, type_name): raise NotImplementedError + # ======================================================================================================================= # API CLASSES: # ======================================================================================================================= @@ -72,7 +71,7 @@ class StrPresentationProvider(_AbstractProvider): """ def get_str_in_context(self, val: Any, context: str): - ''' + """ :param val: This is the object for which we want a string representation. @@ -86,7 +85,7 @@ def get_str_in_context(self, val: Any, context: str): :note: this method is not required (if it's not available, get_str is called directly, so, it's only needed if the string representation needs to be converted based on the context). - ''' + """ return self.get_str(val) @abc.abstractmethod diff --git a/_pydevd_bundle/pydevd_extension_utils.py b/_pydevd_bundle/pydevd_extension_utils.py index 1386cc758..e10b69b4a 100644 --- a/_pydevd_bundle/pydevd_extension_utils.py +++ b/_pydevd_bundle/pydevd_extension_utils.py @@ -1,6 +1,7 @@ import pkgutil import sys from _pydev_bundle import pydev_log + try: import pydevd_plugins.extensions as extensions except: @@ -9,7 +10,6 @@ class ExtensionManager(object): - def __init__(self): self.loaded_extensions = None self.type_to_instance = {} @@ -17,16 +17,15 @@ def __init__(self): def _load_modules(self): self.loaded_extensions = [] if extensions: - for module_loader, name, ispkg in pkgutil.walk_packages(extensions.__path__, - extensions.__name__ + '.'): - mod_name = name.split('.')[-1] - if not ispkg and mod_name.startswith('pydevd_plugin'): + for module_loader, name, ispkg in pkgutil.walk_packages(extensions.__path__, extensions.__name__ + "."): + mod_name = name.split(".")[-1] + if not ispkg and mod_name.startswith("pydevd_plugin"): try: __import__(name) module = sys.modules[name] self.loaded_extensions.append(module) except ImportError: - pydev_log.critical('Unable to load extension: %s', name) + pydev_log.critical("Unable to load extension: %s", name) def _ensure_loaded(self): if self.loaded_extensions is None: @@ -34,9 +33,9 @@ def _ensure_loaded(self): def _iter_attr(self): for extension in self.loaded_extensions: - dunder_all = getattr(extension, '__all__', None) + dunder_all = getattr(extension, "__all__", None) for attr_name in dir(extension): - if not attr_name.startswith('_'): + if not attr_name.startswith("_"): if dunder_all is None or attr_name in dunder_all: yield attr_name, getattr(extension, attr_name) @@ -50,7 +49,7 @@ def get_extension_classes(self, extension_type): try: handlers.append(attr()) except: - pydev_log.exception('Unable to load extension class: %s', attr_name) + pydev_log.exception("Unable to load extension class: %s", attr_name) return handlers @@ -64,4 +63,3 @@ def extensions_of_type(extension_type): :rtype: list[T] """ return EXTENSION_MANAGER_INSTANCE.get_extension_classes(extension_type) - diff --git a/_pydevd_bundle/pydevd_filtering.py b/_pydevd_bundle/pydevd_filtering.py index 3d0376a59..c0cf39542 100644 --- a/_pydevd_bundle/pydevd_filtering.py +++ b/_pydevd_bundle/pydevd_filtering.py @@ -9,18 +9,17 @@ from collections import namedtuple from _pydev_bundle._pydev_saved_modules import threading from pydevd_file_utils import normcase -from _pydevd_bundle.pydevd_constants import USER_CODE_BASENAMES_STARTING_WITH, \ - LIBRARY_CODE_BASENAMES_STARTING_WITH, IS_PYPY, IS_WINDOWS +from _pydevd_bundle.pydevd_constants import USER_CODE_BASENAMES_STARTING_WITH, LIBRARY_CODE_BASENAMES_STARTING_WITH, IS_PYPY, IS_WINDOWS from _pydevd_bundle import pydevd_constants from _pydevd_bundle.pydevd_constants import is_true_in_env -ExcludeFilter = namedtuple('ExcludeFilter', 'name, exclude, is_path') +ExcludeFilter = namedtuple("ExcludeFilter", "name, exclude, is_path") def _convert_to_str_and_clear_empty(roots): new_roots = [] for root in roots: - assert isinstance(root, str), '%s not str (found: %s)' % (root, type(root)) + assert isinstance(root, str), "%s not str (found: %s)" % (root, type(root)) if root: new_roots.append(root) return new_roots @@ -38,11 +37,10 @@ def _check_matches(patterns, paths): path = normcase(paths[0]) if not glob.has_magic(pattern): - if pattern != path: return False - elif pattern == '**': + elif pattern == "**": if len(patterns) == 1: return True # if ** is the last one it matches anything to the right. @@ -64,12 +62,12 @@ def glob_matches_path(path, pattern, sep=os.sep, altsep=os.altsep): pattern = pattern.replace(altsep, sep) path = path.replace(altsep, sep) - drive = '' - if len(path) > 1 and path[1] == ':': + drive = "" + if len(path) > 1 and path[1] == ":": drive, path = path[0], path[2:] if drive and len(pattern) > 1: - if pattern[1] == ':': + if pattern[1] == ":": if drive.lower() != pattern[0].lower(): return False pattern = pattern[2:] @@ -77,21 +75,21 @@ def glob_matches_path(path, pattern, sep=os.sep, altsep=os.altsep): patterns = pattern.split(sep) paths = path.split(sep) if paths: - if paths[0] == '': + if paths[0] == "": paths = paths[1:] if patterns: - if patterns[0] == '': + if patterns[0] == "": patterns = patterns[1:] return _check_matches(patterns, paths) class FilesFiltering(object): - ''' + """ Note: calls at FilesFiltering are uncached. The actual API used should be through PyDB. - ''' + """ def __init__(self): self._exclude_filters = [] @@ -102,16 +100,16 @@ def __init__(self): self._use_libraries_filter = False self.require_module = False # True if some exclude filter filters by the module. - self.set_use_libraries_filter(is_true_in_env('PYDEVD_FILTER_LIBRARIES')) + self.set_use_libraries_filter(is_true_in_env("PYDEVD_FILTER_LIBRARIES")) - project_roots = os.getenv('IDE_PROJECT_ROOTS', None) + project_roots = os.getenv("IDE_PROJECT_ROOTS", None) if project_roots is not None: project_roots = project_roots.split(os.pathsep) else: project_roots = [] self.set_project_roots(project_roots) - library_roots = os.getenv('LIBRARY_ROOTS', None) + library_roots = os.getenv("LIBRARY_ROOTS", None) if library_roots is not None: library_roots = library_roots.split(os.pathsep) else: @@ -119,11 +117,11 @@ def __init__(self): self.set_library_roots(library_roots) # Stepping filters. - pydevd_filters = os.getenv('PYDEVD_FILTERS', '') + pydevd_filters = os.getenv("PYDEVD_FILTERS", "") # To filter out it's something as: {'**/not_my_code/**': True} if pydevd_filters: pydev_log.debug("PYDEVD_FILTERS %s", (pydevd_filters,)) - if pydevd_filters.startswith('{'): + if pydevd_filters.startswith("{"): # dict(glob_pattern (str) -> exclude(True or False)) exclude_filters = [] for key, val in json.loads(pydevd_filters).items(): @@ -132,7 +130,7 @@ def __init__(self): else: # A ';' separated list of strings with globs for the # list of excludes. - filters = pydevd_filters.split(';') + filters = pydevd_filters.split(";") new_filters = [] for new_filter in filters: if new_filter.strip(): @@ -152,7 +150,7 @@ def _get_default_library_roots(cls): except ImportError: pass else: - for path_name in set(('stdlib', 'platstdlib', 'purelib', 'platlib')) & set(sysconfig.get_path_names()): + for path_name in set(("stdlib", "platstdlib", "purelib", "platlib")) & set(sysconfig.get_path_names()): roots.append(sysconfig.get_path(path_name)) # Make sure we always get at least the standard library location (based on the `os` and @@ -171,7 +169,7 @@ def _get_default_library_roots(cls): pydev_log.debug("Adding %s to default library roots.", pypy_lib_dir) roots.append(pypy_lib_dir) - if hasattr(site, 'getusersitepackages'): + if hasattr(site, "getusersitepackages"): site_paths = site.getusersitepackages() if isinstance(site_paths, (list, tuple)): for site_path in site_paths: @@ -179,7 +177,7 @@ def _get_default_library_roots(cls): else: roots.append(site_paths) - if hasattr(site, 'getsitepackages'): + if hasattr(site, "getsitepackages"): site_paths = site.getsitepackages() if isinstance(site_paths, (list, tuple)): for site_path in site_paths: @@ -188,7 +186,7 @@ def _get_default_library_roots(cls): roots.append(site_paths) for path in sys.path: - if os.path.exists(path) and os.path.basename(path) in ('site-packages', 'pip-global'): + if os.path.exists(path) and os.path.basename(path) in ("site-packages", "pip-global"): roots.append(path) # On WASM some of the roots may not exist, filter those out. @@ -203,15 +201,15 @@ def _fix_roots(self, roots): for root in roots: path = self._absolute_normalized_path(root) if pydevd_constants.IS_WINDOWS: - new_roots.append(path + '\\') + new_roots.append(path + "\\") else: - new_roots.append(path + '/') + new_roots.append(path + "/") return new_roots def _absolute_normalized_path(self, filename): - ''' + """ Provides a version of the filename that's absolute and normalized. - ''' + """ return normcase(pydevd_file_utils.absolute_path(filename)) def set_project_roots(self, project_roots): @@ -229,33 +227,39 @@ def _get_library_roots(self): return self._library_roots def in_project_roots(self, received_filename): - ''' + """ Note: don't call directly. Use PyDb.in_project_scope (there's no caching here and it doesn't handle all possibilities for knowing whether a project is actually in the scope, it just handles the heuristics based on the absolute_normalized_filename without the actual frame). - ''' + """ DEBUG = False if received_filename.startswith(USER_CODE_BASENAMES_STARTING_WITH): if DEBUG: - pydev_log.debug('In in_project_roots - user basenames - starts with %s (%s)', received_filename, USER_CODE_BASENAMES_STARTING_WITH) + pydev_log.debug( + "In in_project_roots - user basenames - starts with %s (%s)", received_filename, USER_CODE_BASENAMES_STARTING_WITH + ) return True if received_filename.startswith(LIBRARY_CODE_BASENAMES_STARTING_WITH): if DEBUG: - pydev_log.debug('Not in in_project_roots - library basenames - starts with %s (%s)', received_filename, LIBRARY_CODE_BASENAMES_STARTING_WITH) + pydev_log.debug( + "Not in in_project_roots - library basenames - starts with %s (%s)", + received_filename, + LIBRARY_CODE_BASENAMES_STARTING_WITH, + ) return False project_roots = self._get_project_roots() # roots are absolute/normalized. absolute_normalized_filename = self._absolute_normalized_path(received_filename) - absolute_normalized_filename_as_dir = absolute_normalized_filename + ('\\' if IS_WINDOWS else '/') + absolute_normalized_filename_as_dir = absolute_normalized_filename + ("\\" if IS_WINDOWS else "/") found_in_project = [] for root in project_roots: if root and (absolute_normalized_filename.startswith(root) or root == absolute_normalized_filename_as_dir): if DEBUG: - pydev_log.debug('In project: %s (%s)', absolute_normalized_filename, root) + pydev_log.debug("In project: %s (%s)", absolute_normalized_filename, root) found_in_project.append(root) found_in_library = [] @@ -264,10 +268,10 @@ def in_project_roots(self, received_filename): if root and (absolute_normalized_filename.startswith(root) or root == absolute_normalized_filename_as_dir): found_in_library.append(root) if DEBUG: - pydev_log.debug('In library: %s (%s)', absolute_normalized_filename, root) + pydev_log.debug("In library: %s (%s)", absolute_normalized_filename, root) else: if DEBUG: - pydev_log.debug('Not in library: %s (%s)', absolute_normalized_filename, root) + pydev_log.debug("Not in library: %s (%s)", absolute_normalized_filename, root) if not project_roots: # If we have no project roots configured, consider it being in the project @@ -275,28 +279,28 @@ def in_project_roots(self, received_filename): # and not the other way around). in_project = not found_in_library if DEBUG: - pydev_log.debug('Final in project (no project roots): %s (%s)', absolute_normalized_filename, in_project) + pydev_log.debug("Final in project (no project roots): %s (%s)", absolute_normalized_filename, in_project) else: in_project = False if found_in_project: if not found_in_library: if DEBUG: - pydev_log.debug('Final in project (in_project and not found_in_library): %s (True)', absolute_normalized_filename) + pydev_log.debug("Final in project (in_project and not found_in_library): %s (True)", absolute_normalized_filename) in_project = True else: # Found in both, let's see which one has the bigger path matched. if max(len(x) for x in found_in_project) > max(len(x) for x in found_in_library): in_project = True if DEBUG: - pydev_log.debug('Final in project (found in both): %s (%s)', absolute_normalized_filename, in_project) + pydev_log.debug("Final in project (found in both): %s (%s)", absolute_normalized_filename, in_project) return in_project def use_libraries_filter(self): - ''' + """ Should we debug only what's inside project folders? - ''' + """ return self._use_libraries_filter def set_use_libraries_filter(self, use): @@ -308,24 +312,24 @@ def use_exclude_filters(self): return len(self._exclude_filters) > 0 def exclude_by_filter(self, absolute_filename, module_name): - ''' + """ :return: True if it should be excluded, False if it should be included and None if no rule matched the given file. - ''' + """ for exclude_filter in self._exclude_filters: # : :type exclude_filter: ExcludeFilter if exclude_filter.is_path: if glob_matches_path(absolute_filename, exclude_filter.name): return exclude_filter.exclude else: # Module filter. - if exclude_filter.name == module_name or module_name.startswith(exclude_filter.name + '.'): + if exclude_filter.name == module_name or module_name.startswith(exclude_filter.name + "."): return exclude_filter.exclude return None def set_exclude_filters(self, exclude_filters): - ''' + """ :param list(ExcludeFilter) exclude_filters: - ''' + """ self._exclude_filters = exclude_filters self.require_module = False for exclude_filter in exclude_filters: diff --git a/_pydevd_bundle/pydevd_frame.py b/_pydevd_bundle/pydevd_frame.py index be8eb4406..0b96228a5 100644 --- a/_pydevd_bundle/pydevd_frame.py +++ b/_pydevd_bundle/pydevd_frame.py @@ -4,14 +4,20 @@ from _pydev_bundle import pydev_log from _pydevd_bundle import pydevd_dont_trace -from _pydevd_bundle.pydevd_constants import (RETURN_VALUES_DICT, NO_FTRACE, - EXCEPTION_TYPE_HANDLED, EXCEPTION_TYPE_USER_UNHANDLED, PYDEVD_IPYTHON_CONTEXT, - PYDEVD_USE_SYS_MONITORING) +from _pydevd_bundle.pydevd_constants import ( + RETURN_VALUES_DICT, + NO_FTRACE, + EXCEPTION_TYPE_HANDLED, + EXCEPTION_TYPE_USER_UNHANDLED, + PYDEVD_IPYTHON_CONTEXT, + PYDEVD_USE_SYS_MONITORING, +) from _pydevd_bundle.pydevd_frame_utils import add_exception_to_frame, just_raised, remove_exception_from_frame, ignore_exception_trace from _pydevd_bundle.pydevd_utils import get_clsname_for_code from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame from _pydevd_bundle.pydevd_comm_constants import constant_to_str, CMD_SET_FUNCTION_BREAK import sys + try: from _pydevd_bundle.pydevd_bytecode_utils import get_smart_step_into_variant_from_frame_offset except ImportError: @@ -19,6 +25,7 @@ def get_smart_step_into_variant_from_frame_offset(*args, **kwargs): return None + # IFDEF CYTHON # cython_inline_constant: CMD_STEP_INTO = 107 # cython_inline_constant: CMD_STEP_INTO_MY_CODE = 144 @@ -50,10 +57,10 @@ def get_smart_step_into_variant_from_frame_offset(*args, **kwargs): basename = os.path.basename -IGNORE_EXCEPTION_TAG = re.compile('[^#]*#.*@IgnoreException') -DEBUG_START = ('pydevd.py', 'run') -DEBUG_START_PY3K = ('_pydev_execfile.py', 'execfile') -TRACE_PROPERTY = 'pydevd_traceproperty.py' +IGNORE_EXCEPTION_TAG = re.compile("[^#]*#.*@IgnoreException") +DEBUG_START = ("pydevd.py", "run") +DEBUG_START_PY3K = ("_pydev_execfile.py", "execfile") +TRACE_PROPERTY = "pydevd_traceproperty.py" import dis @@ -67,7 +74,7 @@ def get_smart_step_into_variant_from_frame_offset(*args, **kwargs): # def is_unhandled_exception(container_obj, py_db, frame, int last_raise_line, set raise_lines): # ELSE def is_unhandled_exception(container_obj, py_db, frame, last_raise_line, raise_lines): -# ENDIF + # ENDIF if frame.f_lineno in raise_lines: return True @@ -96,10 +103,7 @@ def is_unhandled_exception(container_obj, py_db, frame, last_raise_line, raise_l # and it's gotten in the except line. for try_except_info in try_except_infos: if try_except_info.is_line_in_except_block(frame.f_lineno): - if ( - frame.f_lineno == try_except_info.except_line or - frame.f_lineno in try_except_info.raise_lines_in_except - ): + if frame.f_lineno == try_except_info.except_line or frame.f_lineno in try_except_info.raise_lines_in_except: # In a raise inside a try..except block or some except which doesn't # match the raised exception. return True @@ -113,35 +117,39 @@ def is_unhandled_exception(container_obj, py_db, frame, last_raise_line, raise_l # self.try_except_infos = None # ELSE class _TryExceptContainerObj(object): - ''' + """ A dumb container object just to contain the try..except info when needed. Meant to be persistent among multiple PyDBFrames to the same code object. - ''' + """ + try_except_infos = None + + # ENDIF -#======================================================================================================================= +# ======================================================================================================================= # PyDBFrame -#======================================================================================================================= +# ======================================================================================================================= # IFDEF CYTHON # cdef class PyDBFrame: # ELSE class PyDBFrame: - '''This makes the tracing for a given frame, so, the trace_dispatch + """This makes the tracing for a given frame, so, the trace_dispatch is used initially when we enter into a new context ('call') and then is reused for the entire context. - ''' -# ENDIF + """ + + # ENDIF # IFDEF CYTHON # cdef tuple _args # cdef int should_skip # cdef object exc_info # def __init__(self, tuple args): - # self._args = args # In the cython version we don't need to pass the frame - # self.should_skip = -1 # On cythonized version, put in instance. - # self.exc_info = () + # self._args = args # In the cython version we don't need to pass the frame + # self.should_skip = -1 # On cythonized version, put in instance. + # self.exc_info = () # ELSE should_skip = -1 # Default value in class (put in instance on set). exc_info = () # Default value in class (put in instance on set). @@ -171,8 +179,8 @@ def do_wait_suspend(self, *args, **kwargs): # cdef tuple exc_info; # ELSE def trace_exception(self, frame, event, arg): - # ENDIF - if event == 'exception': + # ENDIF + if event == "exception": should_stop, frame, exc_info = should_stop_on_exception(self._args[0], self._args[2], frame, self._args[3], arg, self.exc_info) self.exc_info = exc_info @@ -180,16 +188,17 @@ def trace_exception(self, frame, event, arg): if handle_exception(self._args[0], self._args[3], frame, arg, EXCEPTION_TYPE_HANDLED): return self.trace_dispatch - elif event == 'return': + elif event == "return": exc_info = self.exc_info if exc_info and arg is None: frame_skips_cache, frame_cache_key = self._args[4], self._args[5] - custom_key = (frame_cache_key, 'try_exc_info') + custom_key = (frame_cache_key, "try_exc_info") container_obj = frame_skips_cache.get(custom_key) if container_obj is None: container_obj = frame_skips_cache[custom_key] = _TryExceptContainerObj() - if is_unhandled_exception(container_obj, self._args[0], frame, exc_info[1], exc_info[2]) and \ - self.handle_user_exception(frame): + if is_unhandled_exception(container_obj, self._args[0], frame, exc_info[1], exc_info[2]) and self.handle_user_exception( + frame + ): return self.trace_dispatch return self.trace_exception @@ -205,7 +214,7 @@ def handle_user_exception(self, frame): # cdef str func_name # ELSE def get_func_name(self, frame): - # ENDIF + # ENDIF code_obj = frame.f_code func_name = code_obj.co_name try: @@ -222,7 +231,7 @@ def get_func_name(self, frame): # cdef _show_return_values(self, frame, arg): # ELSE def _show_return_values(self, frame, arg): - # ENDIF + # ENDIF try: try: f_locals_back = getattr(frame.f_back, "f_locals", None) @@ -242,7 +251,7 @@ def _show_return_values(self, frame, arg): # cdef _remove_return_values(self, py_db, frame): # ELSE def _remove_return_values(self, py_db, frame): - # ENDIF + # ENDIF try: try: # Showing return values was turned off, we should remove them from locals dict. @@ -261,7 +270,7 @@ def _remove_return_values(self, py_db, frame): # cdef _get_unfiltered_back_frame(self, py_db, frame): # ELSE def _get_unfiltered_back_frame(self, py_db, frame): - # ENDIF + # ENDIF f = frame.f_back while f is not None: if not py_db.is_files_filter_enabled: @@ -281,7 +290,7 @@ def _get_unfiltered_back_frame(self, py_db, frame): # cdef PyDBAdditionalThreadInfo info; # ELSE def _is_same_frame(self, target_frame, current_frame): - # ENDIF + # ENDIF if target_frame is current_frame: return True @@ -333,7 +342,7 @@ def _is_same_frame(self, target_frame, current_frame): # cdef tuple pydev_smart_step_into_variants # ELSE def trace_dispatch(self, frame, event, arg): - # ENDIF + # ENDIF # Note: this is a big function because most of the logic related to hitting a breakpoint and # stepping is contained in it. Ideally this could be split among multiple functions, but the # problem in this case is that in pure-python function calls are expensive and even more so @@ -355,35 +364,34 @@ def trace_dispatch(self, frame, event, arg): line_cache_key = (frame_cache_key, line) if py_db.pydb_disposed: - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE plugin_manager = py_db.plugin has_exception_breakpoints = ( - py_db.break_on_caught_exceptions - or py_db.break_on_user_uncaught_exceptions - or py_db.has_plugin_exception_breaks) + py_db.break_on_caught_exceptions or py_db.break_on_user_uncaught_exceptions or py_db.has_plugin_exception_breaks + ) stop_frame = info.pydev_step_stop step_cmd = info.pydev_step_cmd function_breakpoint_on_call_event = None - if frame.f_code.co_flags & 0xa0: # 0xa0 == CO_GENERATOR = 0x20 | CO_COROUTINE = 0x80 + if frame.f_code.co_flags & 0xA0: # 0xa0 == CO_GENERATOR = 0x20 | CO_COROUTINE = 0x80 # Dealing with coroutines and generators: # When in a coroutine we change the perceived event to the debugger because # a call, StopIteration exception and return are usually just pausing/unpausing it. - if event == 'line': + if event == "line": is_line = True is_call = False is_return = False is_exception_event = False - elif event == 'return': + elif event == "return": is_line = False is_call = False is_return = True is_exception_event = False - returns_cache_key = (frame_cache_key, 'returns') + returns_cache_key = (frame_cache_key, "returns") return_lines = frame_skips_cache.get(returns_cache_key) if return_lines is None: # Note: we're collecting the return lines by inspecting the bytecode as @@ -446,10 +454,12 @@ def trace_dispatch(self, frame, event, arg): info.pydev_step_cmd = CMD_STEP_INTO info.pydev_step_stop = None - elif event == 'exception': + elif event == "exception": breakpoints_for_file = None if has_exception_breakpoints: - should_stop, frame, exc_info = should_stop_on_exception(self._args[0], self._args[2], frame, self._args[3], arg, self.exc_info) + should_stop, frame, exc_info = should_stop_on_exception( + self._args[0], self._args[2], frame, self._args[3], arg, self.exc_info + ) self.exc_info = exc_info if should_stop: if handle_exception(self._args[0], self._args[3], frame, arg, EXCEPTION_TYPE_HANDLED): @@ -461,13 +471,13 @@ def trace_dispatch(self, frame, event, arg): return self.trace_dispatch else: # Not coroutine nor generator - if event == 'line': + if event == "line": is_line = True is_call = False is_return = False is_exception_event = False - elif event == 'return': + elif event == "return": is_line = False is_return = True is_call = False @@ -480,11 +490,12 @@ def trace_dispatch(self, frame, event, arg): # Note: this is especially troublesome when we're skipping code with the # @DontTrace comment. if ( - stop_frame is frame and - not info.pydev_use_scoped_step_frame and is_return and - step_cmd in (CMD_STEP_OVER, CMD_STEP_RETURN, CMD_STEP_OVER_MY_CODE, CMD_STEP_RETURN_MY_CODE, CMD_SMART_STEP_INTO) - ): - + stop_frame is frame + and not info.pydev_use_scoped_step_frame + and is_return + and step_cmd + in (CMD_STEP_OVER, CMD_STEP_RETURN, CMD_STEP_OVER_MY_CODE, CMD_STEP_RETURN_MY_CODE, CMD_SMART_STEP_INTO) + ): if step_cmd in (CMD_STEP_OVER, CMD_STEP_RETURN, CMD_SMART_STEP_INTO): info.pydev_step_cmd = CMD_STEP_INTO else: @@ -495,7 +506,7 @@ def trace_dispatch(self, frame, event, arg): if self.handle_user_exception(frame): return self.trace_dispatch - elif event == 'call': + elif event == "call": is_line = False is_call = True is_return = False @@ -503,11 +514,13 @@ def trace_dispatch(self, frame, event, arg): if frame.f_code.co_firstlineno == frame.f_lineno: # Check line to deal with async/await. function_breakpoint_on_call_event = py_db.function_breakpoint_name_to_breakpoint.get(frame.f_code.co_name) - elif event == 'exception': + elif event == "exception": is_exception_event = True breakpoints_for_file = None if has_exception_breakpoints: - should_stop, frame, exc_info = should_stop_on_exception(self._args[0], self._args[2], frame, self._args[3], arg, self.exc_info) + should_stop, frame, exc_info = should_stop_on_exception( + self._args[0], self._args[2], frame, self._args[3], arg, self.exc_info + ) self.exc_info = exc_info if should_stop: if handle_exception(self._args[0], self._args[3], frame, arg, EXCEPTION_TYPE_HANDLED): @@ -533,22 +546,27 @@ def trace_dispatch(self, frame, event, arg): if step_cmd == -1: can_skip = True - elif step_cmd in (CMD_STEP_OVER, CMD_STEP_RETURN, CMD_STEP_OVER_MY_CODE, CMD_STEP_RETURN_MY_CODE) and not self._is_same_frame(stop_frame, frame): + elif step_cmd in ( + CMD_STEP_OVER, + CMD_STEP_RETURN, + CMD_STEP_OVER_MY_CODE, + CMD_STEP_RETURN_MY_CODE, + ) and not self._is_same_frame(stop_frame, frame): can_skip = True elif step_cmd == CMD_SMART_STEP_INTO and ( - stop_frame is not None and - stop_frame is not frame and - stop_frame is not frame.f_back and - (frame.f_back is None or stop_frame is not frame.f_back.f_back)): + stop_frame is not None + and stop_frame is not frame + and stop_frame is not frame.f_back + and (frame.f_back is None or stop_frame is not frame.f_back.f_back) + ): can_skip = True elif step_cmd == CMD_STEP_INTO_MY_CODE: - if ( - py_db.apply_files_filter(frame, frame.f_code.co_filename, True) - and (frame.f_back is None or py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True)) - ): - can_skip = True + if py_db.apply_files_filter(frame, frame.f_code.co_filename, True) and ( + frame.f_back is None or py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True) + ): + can_skip = True elif step_cmd == CMD_STEP_INTO_COROUTINE: f = frame @@ -560,11 +578,15 @@ def trace_dispatch(self, frame, event, arg): can_skip = True if can_skip: - if plugin_manager is not None and ( - py_db.has_plugin_line_breaks or py_db.has_plugin_exception_breaks): + if plugin_manager is not None and (py_db.has_plugin_line_breaks or py_db.has_plugin_exception_breaks): can_skip = plugin_manager.can_skip(py_db, frame) - if can_skip and py_db.show_return_values and info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE) and self._is_same_frame(stop_frame, frame.f_back): + if ( + can_skip + and py_db.show_return_values + and info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE) + and self._is_same_frame(stop_frame, frame.f_back) + ): # trace function for showing return values after step over can_skip = False @@ -612,12 +634,12 @@ def trace_dispatch(self, frame, event, arg): curr_func_name = frame.f_code.co_name # global context is set with an empty name - if curr_func_name in ('?', '', ''): - curr_func_name = '' + if curr_func_name in ("?", "", ""): + curr_func_name = "" for bp in breakpoints_for_file.values(): # will match either global or some function - if bp.func_name in ('None', curr_func_name): + if bp.func_name in ("None", curr_func_name): has_breakpoint_in_frame = True break else: @@ -683,7 +705,9 @@ def trace_dispatch(self, frame, event, arg): stop = False stop_on_plugin_breakpoint = False - if is_call and (frame.f_code.co_name in ('', '') or (line == 1 and frame.f_code.co_name.startswith('", "") or (line == 1 and frame.f_code.co_name.startswith(" 0: - cmd = py_db.cmd_factory.make_io_message(info.pydev_message + os.linesep, '1') + cmd = py_db.cmd_factory.make_io_message(info.pydev_message + os.linesep, "1") py_db.writer.add_command(cmd) if py_db.show_return_values: if is_return and ( - (info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, CMD_SMART_STEP_INTO) and (self._is_same_frame(stop_frame, frame.f_back))) or - (info.pydev_step_cmd in (CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE) and (self._is_same_frame(stop_frame, frame))) or - (info.pydev_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_COROUTINE)) or - ( - info.pydev_step_cmd == CMD_STEP_INTO_MY_CODE - and frame.f_back is not None - and not py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True) - ) - ): + ( + info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, CMD_SMART_STEP_INTO) + and (self._is_same_frame(stop_frame, frame.f_back)) + ) + or (info.pydev_step_cmd in (CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE) and (self._is_same_frame(stop_frame, frame))) + or (info.pydev_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_COROUTINE)) + or ( + info.pydev_step_cmd == CMD_STEP_INTO_MY_CODE + and frame.f_back is not None + and not py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True) + ) + ): self._show_return_values(frame, arg) elif py_db.remove_return_values_flag: @@ -751,7 +778,12 @@ def trace_dispatch(self, frame, event, arg): # the tracing function, so, we can't do much about it (just let the user know). exc = sys.exc_info()[0] cmd = py_db.cmd_factory.make_console_message( - '%s raised from within the callback set in sys.settrace.\nDebugging will be disabled for this thread (%s).\n' % (exc, thread,)) + "%s raised from within the callback set in sys.settrace.\nDebugging will be disabled for this thread (%s).\n" + % ( + exc, + thread, + ) + ) py_db.writer.add_command(cmd) if not issubclass(exc, (KeyboardInterrupt, SystemExit)): pydev_log.exception() @@ -794,7 +826,7 @@ def trace_dispatch(self, frame, event, arg): # We can only stop inside the ipython call. filename = frame.f_code.co_filename - if filename.endswith('.pyc'): + if filename.endswith(".pyc"): filename = filename[:-1] if not filename.endswith(PYDEVD_IPYTHON_CONTEXT[0]): @@ -803,7 +835,7 @@ def trace_dispatch(self, frame, event, arg): if f.f_code.co_name == PYDEVD_IPYTHON_CONTEXT[1]: f2 = f.f_back if f2 is not None and f2.f_code.co_name == PYDEVD_IPYTHON_CONTEXT[2]: - pydev_log.debug('Stop inside ipython call') + pydev_log.debug("Stop inside ipython call") stop = True break f = f.f_back @@ -820,7 +852,9 @@ def trace_dispatch(self, frame, event, arg): stop = False else: if force_check_project_scope or py_db.is_files_filter_enabled: - stop = not py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, force_check_project_scope) + stop = not py_db.apply_files_filter( + frame.f_back, frame.f_back.f_code.co_filename, force_check_project_scope + ) if stop: # Prevent stopping in a return to the same location we were initially # (i.e.: double-stop at the same place due to some filtering). @@ -880,16 +914,19 @@ def trace_dispatch(self, frame, event, arg): if pydev_smart_parent_offset >= 0 and pydev_smart_step_into_variants: # Preferred mode (when the smart step into variants are available # and the offset is set). - stop = get_smart_step_into_variant_from_frame_offset(back.f_lasti, pydev_smart_step_into_variants) is \ - get_smart_step_into_variant_from_frame_offset(pydev_smart_parent_offset, pydev_smart_step_into_variants) + stop = get_smart_step_into_variant_from_frame_offset( + back.f_lasti, pydev_smart_step_into_variants + ) is get_smart_step_into_variant_from_frame_offset( + pydev_smart_parent_offset, pydev_smart_step_into_variants + ) else: # Only the name/line is available, so, check that. curr_func_name = frame.f_code.co_name # global context is set with an empty name - if curr_func_name in ('?', '') or curr_func_name is None: - curr_func_name = '' + if curr_func_name in ("?", "") or curr_func_name is None: + curr_func_name = "" if curr_func_name == info.pydev_func_name and stop_frame.f_lineno == info.pydev_next_line: stop = True @@ -916,13 +953,15 @@ def trace_dispatch(self, frame, event, arg): # the child (because this is a generator, the parent may have moved forward # already -- and that's ok, so, we just check that the parent frame # matches in this case). - smart_step_into_variant = get_smart_step_into_variant_from_frame_offset(pydev_smart_parent_offset, pydev_smart_step_into_variants) + smart_step_into_variant = get_smart_step_into_variant_from_frame_offset( + pydev_smart_parent_offset, pydev_smart_step_into_variants + ) # print('matched parent offset', pydev_smart_parent_offset) # Ok, now, check the child variant children_variants = smart_step_into_variant.children_variants stop = children_variants and ( - get_smart_step_into_variant_from_frame_offset(back.f_lasti, children_variants) is \ - get_smart_step_into_variant_from_frame_offset(pydev_smart_child_offset, children_variants) + get_smart_step_into_variant_from_frame_offset(back.f_lasti, children_variants) + is get_smart_step_into_variant_from_frame_offset(pydev_smart_child_offset, children_variants) ) # print('stop at child', stop) @@ -938,7 +977,7 @@ def trace_dispatch(self, frame, event, arg): stop = False if stop and step_cmd != -1 and is_return and hasattr(frame, "f_back"): - f_code = getattr(frame.f_back, 'f_code', None) + f_code = getattr(frame.f_back, "f_code", None) if f_code is not None: if py_db.get_file_type(frame.f_back) == py_db.PYDEV_FILE: stop = False @@ -996,7 +1035,12 @@ def trace_dispatch(self, frame, event, arg): # the tracing function, so, we can't do much about it (just let the user know). exc = sys.exc_info()[0] cmd = py_db.cmd_factory.make_console_message( - '%s raised from within the callback set in sys.settrace.\nDebugging will be disabled for this thread (%s).\n' % (exc, thread,)) + "%s raised from within the callback set in sys.settrace.\nDebugging will be disabled for this thread (%s).\n" + % ( + exc, + thread, + ) + ) py_db.writer.add_command(cmd) if not issubclass(exc, (KeyboardInterrupt, SystemExit)): pydev_log.exception() @@ -1015,7 +1059,7 @@ def trace_dispatch(self, frame, event, arg): # cdef list check_excs; # ELSE def should_stop_on_exception(py_db, info, frame, thread, arg, prev_user_uncaught_exc_info): -# ENDIF + # ENDIF should_stop = False maybe_user_uncaught_exc_info = prev_user_uncaught_exc_info @@ -1024,7 +1068,7 @@ def should_stop_on_exception(py_db, info, frame, thread, arg, prev_user_uncaught if info.pydev_state != 2: # and breakpoint is not None: exception, value, trace = arg - if trace is not None and hasattr(trace, 'tb_next'): + if trace is not None and hasattr(trace, "tb_next"): # on jython trace is None on the first event and it may not have a tb_next. should_stop = False @@ -1057,13 +1101,11 @@ def should_stop_on_exception(py_db, info, frame, thread, arg, prev_user_uncaught check_excs = [] # Note: check user unhandled before regular exceptions. - exc_break_user = py_db.get_exception_breakpoint( - exception, py_db.break_on_user_uncaught_exceptions) + exc_break_user = py_db.get_exception_breakpoint(exception, py_db.break_on_user_uncaught_exceptions) if exc_break_user is not None: check_excs.append((exc_break_user, True)) - exc_break_caught = py_db.get_exception_breakpoint( - exception, py_db.break_on_caught_exceptions) + exc_break_caught = py_db.get_exception_breakpoint(exception, py_db.break_on_caught_exceptions) if exc_break_caught is not None: check_excs.append((exc_break_caught, False)) @@ -1072,18 +1114,20 @@ def should_stop_on_exception(py_db, info, frame, thread, arg, prev_user_uncaught should_stop = True if py_db.exclude_exception_by_filter(exc_break, trace): - pydev_log.debug("Ignore exception %s in library %s -- (%s)" % (exception, frame.f_code.co_filename, frame.f_code.co_name)) + pydev_log.debug( + "Ignore exception %s in library %s -- (%s)" % (exception, frame.f_code.co_filename, frame.f_code.co_name) + ) should_stop = False - elif exc_break.condition is not None and \ - not py_db.handle_breakpoint_condition(info, exc_break, frame): + elif exc_break.condition is not None and not py_db.handle_breakpoint_condition(info, exc_break, frame): should_stop = False elif is_user_uncaught: # Note: we don't stop here, we just collect the exc_info to use later on... should_stop = False - if not py_db.apply_files_filter(frame, frame.f_code.co_filename, True) \ - and (frame.f_back is None or py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True)): + if not py_db.apply_files_filter(frame, frame.f_code.co_filename, True) and ( + frame.f_back is None or py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True) + ): # User uncaught means that we're currently in user code but the code # up the stack is library code. exc_info = prev_user_uncaught_exc_info @@ -1096,14 +1140,21 @@ def should_stop_on_exception(py_db, info, frame, thread, arg, prev_user_uncaught maybe_user_uncaught_exc_info = exc_info else: # I.e.: these are only checked if we're not dealing with user uncaught exceptions. - if exc_break.notify_on_first_raise_only and py_db.skip_on_exceptions_thrown_in_same_context \ - and not was_just_raised and not just_raised(trace.tb_next): + if ( + exc_break.notify_on_first_raise_only + and py_db.skip_on_exceptions_thrown_in_same_context + and not was_just_raised + and not just_raised(trace.tb_next) + ): # In this case we never stop if it was just raised, so, to know if it was the first we # need to check if we're in the 2nd method. should_stop = False # I.e.: we stop only when we're at the caller of a method that throws an exception - elif exc_break.notify_on_first_raise_only and not py_db.skip_on_exceptions_thrown_in_same_context \ - and not was_just_raised: + elif ( + exc_break.notify_on_first_raise_only + and not py_db.skip_on_exceptions_thrown_in_same_context + and not was_just_raised + ): should_stop = False # I.e.: we stop only when it was just raised elif was_just_raised and py_db.skip_on_exceptions_thrown_in_same_context: @@ -1115,7 +1166,7 @@ def should_stop_on_exception(py_db, info, frame, thread, arg, prev_user_uncaught try: info.pydev_message = exc_break.qname except: - info.pydev_message = exc_break.qname.encode('utf-8') + info.pydev_message = exc_break.qname.encode("utf-8") break if should_stop: @@ -1146,7 +1197,7 @@ def should_stop_on_exception(py_db, info, frame, thread, arg, prev_user_uncaught # cdef object trace_obj; # ELSE def handle_exception(py_db, thread, frame, arg, exception_type): -# ENDIF + # ENDIF stopped = False try: # print('handle_exception', frame.f_lineno, frame.f_code.co_name) @@ -1186,7 +1237,7 @@ def handle_exception(py_db, thread, frame, arg, exception_type): try: linecache.checkcache(absolute_filename) except: - pydev_log.exception('Error in linecache.checkcache(%r)', absolute_filename) + pydev_log.exception("Error in linecache.checkcache(%r)", absolute_filename) from_user_input = py_db.filename_to_lines_where_exceptions_are_ignored.get(canonical_normalized_filename) if from_user_input: @@ -1207,8 +1258,8 @@ def handle_exception(py_db, thread, frame, arg, exception_type): try: line = linecache.getline(absolute_filename, exc_lineno, check_trace_obj.tb_frame.f_globals) except: - pydev_log.exception('Error in linecache.getline(%r, %s, f_globals)', absolute_filename, exc_lineno) - line = '' + pydev_log.exception("Error in linecache.getline(%r, %s, f_globals)", absolute_filename, exc_lineno) + line = "" if IGNORE_EXCEPTION_TAG.match(line) is not None: lines_ignored[exc_lineno] = 1 @@ -1234,7 +1285,7 @@ def handle_exception(py_db, thread, frame, arg, exception_type): py_db.send_caught_exception_stack(thread, arg, id(frame)) try: py_db.set_suspend(thread, CMD_STEP_CAUGHT_EXCEPTION) - py_db.do_wait_suspend(thread, frame, 'exception', arg, exception_type=exception_type) + py_db.do_wait_suspend(thread, frame, "exception", arg, exception_type=exception_type) finally: py_db.send_caught_exception_stack_proceeded(thread) except: diff --git a/_pydevd_bundle/pydevd_frame_utils.py b/_pydevd_bundle/pydevd_frame_utils.py index d11810066..b282f093d 100644 --- a/_pydevd_bundle/pydevd_frame_utils.py +++ b/_pydevd_bundle/pydevd_frame_utils.py @@ -1,20 +1,11 @@ -from _pydevd_bundle.pydevd_constants import EXCEPTION_TYPE_USER_UNHANDLED, EXCEPTION_TYPE_UNHANDLED, \ - IS_PY311_OR_GREATER +from _pydevd_bundle.pydevd_constants import EXCEPTION_TYPE_USER_UNHANDLED, EXCEPTION_TYPE_UNHANDLED, IS_PY311_OR_GREATER from _pydev_bundle import pydev_log import itertools from typing import Any, Dict class Frame(object): - - def __init__( - self, - f_back, - f_fileno, - f_code, - f_locals, - f_globals=None, - f_trace=None): + def __init__(self, f_back, f_fileno, f_code, f_locals, f_globals=None, f_trace=None): self.f_back = f_back self.f_lineno = f_fileno self.f_code = f_code @@ -27,7 +18,6 @@ def __init__( class FCode(object): - def __init__(self, name, filename): self.co_name = name self.co_filename = filename @@ -39,14 +29,14 @@ def co_lines(self): def add_exception_to_frame(frame, exception_info): - frame.f_locals['__exception__'] = exception_info + frame.f_locals["__exception__"] = exception_info def remove_exception_from_frame(frame): - frame.f_locals.pop('__exception__', None) + frame.f_locals.pop("__exception__", None) -FILES_WITH_IMPORT_HOOKS = ['pydev_monkey_qt.py', 'pydev_import_hook.py'] +FILES_WITH_IMPORT_HOOKS = ["pydev_monkey_qt.py", "pydev_import_hook.py"] def just_raised(trace): @@ -58,8 +48,7 @@ def just_raised(trace): def ignore_exception_trace(trace): while trace is not None: filename = trace.tb_frame.f_code.co_filename - if filename in ( - '', ''): + if filename in ("", ""): # Do not stop on inner exceptions in py3 while importing return True @@ -74,7 +63,7 @@ def ignore_exception_trace(trace): def cached_call(obj, func, *args): - cached_name = '_cached_' + func.__name__ + cached_name = "_cached_" + func.__name__ if not hasattr(obj, cached_name): setattr(obj, cached_name, func(*args)) @@ -82,7 +71,6 @@ def cached_call(obj, func, *args): class _LineColInfo: - def __init__(self, lineno, end_lineno, colno, end_colno): self.lineno = lineno self.end_lineno = end_lineno @@ -90,7 +78,7 @@ def __init__(self, lineno, end_lineno, colno, end_colno): self.end_colno = end_colno def map_columns_to_line(self, original_line: str): - ''' + """ The columns internally are actually based on bytes. Also, the position isn't always the ideal one as the start may not be @@ -100,19 +88,17 @@ def map_columns_to_line(self, original_line: str): https://github.com/microsoft/debugpy/issues/1099#issuecomment-1303403995 So, this function maps the start/end columns to the position to be shown in the editor. - ''' + """ colno = _utf8_byte_offset_to_character_offset(original_line, self.colno) end_colno = _utf8_byte_offset_to_character_offset(original_line, self.end_colno) if self.lineno == self.end_lineno: try: - ret = _extract_caret_anchors_in_bytes_from_line_segment( - original_line[colno:end_colno] - ) + ret = _extract_caret_anchors_in_bytes_from_line_segment(original_line[colno:end_colno]) if ret is not None: return ( _utf8_byte_offset_to_character_offset(original_line, ret[0] + self.colno), - _utf8_byte_offset_to_character_offset(original_line, ret[1] + self.colno) + _utf8_byte_offset_to_character_offset(original_line, ret[1] + self.colno), ) except Exception: pass # Suppress exception @@ -156,7 +142,7 @@ def _extract_caret_anchors_in_bytes_from_line_segment(segment: str): import ast try: - segment = segment.encode('utf-8') + segment = segment.encode("utf-8") except UnicodeEncodeError: return None try: @@ -171,15 +157,12 @@ def _extract_caret_anchors_in_bytes_from_line_segment(segment: str): if isinstance(statement, ast.Expr): expr = statement.value if isinstance(expr, ast.BinOp): - operator_str = segment[expr.left.end_col_offset:expr.right.col_offset] + operator_str = segment[expr.left.end_col_offset : expr.right.col_offset] operator_offset = len(operator_str) - len(operator_str.lstrip()) left_anchor = expr.left.end_col_offset + operator_offset right_anchor = left_anchor + 1 - if ( - operator_offset + 1 < len(operator_str) - and not operator_str[operator_offset + 1] == ord(b' ') - ): + if operator_offset + 1 < len(operator_str) and not operator_str[operator_offset + 1] == ord(b" "): right_anchor += 1 return left_anchor, right_anchor if isinstance(expr, ast.Subscript): @@ -189,7 +172,6 @@ def _extract_caret_anchors_in_bytes_from_line_segment(segment: str): class FramesList(object): - def __init__(self): self._frames = [] @@ -209,7 +191,7 @@ def __init__(self): self.current_frame = None # This is to know whether an exception was extracted from a __cause__ or __context__. - self.exc_context_msg = '' + self.exc_context_msg = "" self.chained_frames_list = None @@ -226,38 +208,37 @@ def __iter__(self): return iter(self._frames) def __repr__(self): - lst = ['FramesList('] + lst = ["FramesList("] - lst.append('\n exc_type: ') + lst.append("\n exc_type: ") lst.append(str(self.exc_type)) - lst.append('\n exc_desc: ') + lst.append("\n exc_desc: ") lst.append(str(self.exc_desc)) - lst.append('\n trace_obj: ') + lst.append("\n trace_obj: ") lst.append(str(self.trace_obj)) - lst.append('\n current_frame: ') + lst.append("\n current_frame: ") lst.append(str(self.current_frame)) for frame in self._frames: - lst.append('\n ') + lst.append("\n ") lst.append(repr(frame)) - lst.append(',') + lst.append(",") if self.chained_frames_list is not None: - lst.append('\n--- Chained ---\n') + lst.append("\n--- Chained ---\n") lst.append(str(self.chained_frames_list)) - lst.append('\n)') + lst.append("\n)") - return ''.join(lst) + return "".join(lst) __str__ = __repr__ class _DummyFrameWrapper(object): - def __init__(self, frame, f_lineno, f_back): self._base_frame = frame self.f_lineno = f_lineno @@ -281,27 +262,23 @@ def __str__(self): __repr__ = __str__ -_cause_message = ( - "\nThe above exception was the direct cause " - "of the following exception:\n\n") +_cause_message = "\nThe above exception was the direct cause " "of the following exception:\n\n" -_context_message = ( - "\nDuring handling of the above exception, " - "another exception occurred:\n\n") +_context_message = "\nDuring handling of the above exception, " "another exception occurred:\n\n" def create_frames_list_from_exception_cause(trace_obj, frame, exc_type, exc_desc, memo): lst = [] - msg = '' + msg = "" try: - exc_cause = getattr(exc_desc, '__cause__', None) + exc_cause = getattr(exc_desc, "__cause__", None) msg = _cause_message except Exception: exc_cause = None if exc_cause is None: try: - exc_cause = getattr(exc_desc, '__context__', None) + exc_cause = getattr(exc_desc, "__context__", None) msg = _context_message except Exception: exc_cause = None @@ -358,7 +335,7 @@ def _get_line_col_info_from_tb(tb): def create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, exception_type=None): - ''' + """ :param trace_obj: This is the traceback from which the list should be created. @@ -369,7 +346,7 @@ def create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, exce :param exception_type: If this is an unhandled exception or user unhandled exception, we'll not trim the stack to create from the passed frame, rather, we'll just mark the frame in the frames list. - ''' + """ lst = [] tb = trace_obj @@ -386,11 +363,7 @@ def create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, exce frames_list = None for tb_frame, tb_lineno, line_col_info in reversed(lst): - if frames_list is None and ( - (frame is tb_frame) or - (frame is None) or - (exception_type == EXCEPTION_TYPE_USER_UNHANDLED) - ): + if frames_list is None and ((frame is tb_frame) or (frame is None) or (exception_type == EXCEPTION_TYPE_USER_UNHANDLED)): frames_list = FramesList() if frames_list is not None: @@ -400,7 +373,7 @@ def create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, exce if frames_list is None and frame is not None: # Fallback (shouldn't happen in practice). - pydev_log.info('create_frames_list_from_traceback did not find topmost frame in list.') + pydev_log.info("create_frames_list_from_traceback did not find topmost frame in list.") frames_list = create_frames_list_from_frame(frame) frames_list.exc_type = exc_type diff --git a/_pydevd_bundle/pydevd_gevent_integration.py b/_pydevd_bundle/pydevd_gevent_integration.py index f42d909d5..ee5acc2d0 100644 --- a/_pydevd_bundle/pydevd_gevent_integration.py +++ b/_pydevd_bundle/pydevd_gevent_integration.py @@ -3,8 +3,7 @@ import gevent from _pydev_bundle._pydev_saved_modules import threading from _pydevd_bundle.pydevd_custom_frames import add_custom_frame, update_custom_frame, remove_custom_frame -from _pydevd_bundle.pydevd_constants import GEVENT_SHOW_PAUSED_GREENLETS, get_global_debugger, \ - thread_get_ident +from _pydevd_bundle.pydevd_constants import GEVENT_SHOW_PAUSED_GREENLETS, get_global_debugger, thread_get_ident from _pydev_bundle import pydev_log from pydevd_file_utils import basename @@ -27,10 +26,10 @@ def _get_paused_name(py_db, g): if use_frame is None: use_frame = frame - return '%s: %s - %s' % (type(g).__name__, use_frame.f_code.co_name, basename(use_frame.f_code.co_filename)) + return "%s: %s - %s" % (type(g).__name__, use_frame.f_code.co_name, basename(use_frame.f_code.co_filename)) def greenlet_events(event, args): - if event in ('switch', 'throw'): + if event in ("switch", "throw"): py_db = get_global_debugger() origin, target = args @@ -38,10 +37,10 @@ def greenlet_events(event, args): frame_custom_thread_id = _saved_greenlets_to_custom_frame_thread_id.get(origin) if frame_custom_thread_id is None: _saved_greenlets_to_custom_frame_thread_id[origin] = add_custom_frame( - origin.gr_frame, _get_paused_name(py_db, origin), thread_get_ident()) + origin.gr_frame, _get_paused_name(py_db, origin), thread_get_ident() + ) else: - update_custom_frame( - frame_custom_thread_id, origin.gr_frame, _get_paused_name(py_db, origin), thread_get_ident()) + update_custom_frame(frame_custom_thread_id, origin.gr_frame, _get_paused_name(py_db, origin), thread_get_ident()) else: frame_custom_thread_id = _saved_greenlets_to_custom_frame_thread_id.pop(origin, None) if frame_custom_thread_id is not None: @@ -57,7 +56,6 @@ def greenlet_events(event, args): pydevd_tracing.reapply_settrace() else: - # i.e.: no logic related to showing paused greenlets is needed. def greenlet_events(event, args): pydevd_tracing.reapply_settrace() @@ -70,24 +68,24 @@ def enable_gevent_integration(): # Note: gevent.version_info is WRONG (gevent.__version__ must be used). try: - if tuple(int(x) for x in gevent.__version__.split('.')[:2]) <= (20, 0): + if tuple(int(x) for x in gevent.__version__.split(".")[:2]) <= (20, 0): if not GEVENT_SHOW_PAUSED_GREENLETS: return - if not hasattr(greenlet, 'settrace'): + if not hasattr(greenlet, "settrace"): # In older versions it was optional. # We still try to use if available though. - pydev_log.debug('greenlet.settrace not available. GEVENT_SHOW_PAUSED_GREENLETS will have no effect.') + pydev_log.debug("greenlet.settrace not available. GEVENT_SHOW_PAUSED_GREENLETS will have no effect.") return try: greenlet.settrace(greenlet_events) except: - pydev_log.exception('Error with greenlet.settrace.') + pydev_log.exception("Error with greenlet.settrace.") except: - pydev_log.exception('Error setting up gevent %s.', gevent.__version__) + pydev_log.exception("Error setting up gevent %s.", gevent.__version__) def log_gevent_debug_info(): - pydev_log.debug('Greenlet version: %s', greenlet.__version__) - pydev_log.debug('Gevent version: %s', gevent.__version__) - pydev_log.debug('Gevent install location: %s', gevent.__file__) + pydev_log.debug("Greenlet version: %s", greenlet.__version__) + pydev_log.debug("Gevent version: %s", gevent.__version__) + pydev_log.debug("Gevent install location: %s", gevent.__file__) diff --git a/_pydevd_bundle/pydevd_import_class.py b/_pydevd_bundle/pydevd_import_class.py index ee3527c50..a655e4700 100644 --- a/_pydevd_bundle/pydevd_import_class.py +++ b/_pydevd_bundle/pydevd_import_class.py @@ -1,68 +1,70 @@ -#Note: code gotten from _pydev_imports_tipper. +# Note: code gotten from _pydev_imports_tipper. import sys + def _imp(name, log=None): try: return __import__(name) except: - if '.' in name: - sub = name[0:name.rfind('.')] - + if "." in name: + sub = name[0 : name.rfind(".")] + if log is not None: - log.add_content('Unable to import', name, 'trying with', sub) + log.add_content("Unable to import", name, "trying with", sub) log.add_exception() - + return _imp(sub, log) else: - s = 'Unable to import module: %s - sys.path: %s' % (str(name), sys.path) + s = "Unable to import module: %s - sys.path: %s" % (str(name), sys.path) if log is not None: log.add_content(s) log.add_exception() - + raise ImportError(s) - + IS_IPY = False -if sys.platform == 'cli': +if sys.platform == "cli": IS_IPY = True _old_imp = _imp + def _imp(name, log=None): - #We must add a reference in clr for .Net - import clr #@UnresolvedImport + # We must add a reference in clr for .Net + import clr # @UnresolvedImport + initial_name = name - while '.' in name: + while "." in name: try: clr.AddReference(name) - break #If it worked, that's OK. + break # If it worked, that's OK. except: - name = name[0:name.rfind('.')] + name = name[0 : name.rfind(".")] else: try: clr.AddReference(name) except: - pass #That's OK (not dot net module). - + pass # That's OK (not dot net module). + return _old_imp(initial_name, log) - + def import_name(name, log=None): mod = _imp(name, log) - components = name.split('.') + components = name.split(".") old_comp = None for comp in components[1:]: try: - #this happens in the following case: - #we have mx.DateTime.mxDateTime.mxDateTime.pyd - #but after importing it, mx.DateTime.mxDateTime shadows access to mxDateTime.pyd + # this happens in the following case: + # we have mx.DateTime.mxDateTime.mxDateTime.pyd + # but after importing it, mx.DateTime.mxDateTime shadows access to mxDateTime.pyd mod = getattr(mod, comp) except AttributeError: if old_comp != comp: raise - + old_comp = comp - + return mod - diff --git a/_pydevd_bundle/pydevd_io.py b/_pydevd_bundle/pydevd_io.py index 3682c4ded..7d3bffb80 100644 --- a/_pydevd_bundle/pydevd_io.py +++ b/_pydevd_bundle/pydevd_io.py @@ -5,12 +5,12 @@ class IORedirector: - ''' + """ This class works to wrap a stream (stdout/stderr) with an additional redirect. - ''' + """ def __init__(self, original, new_redirect, wrap_buffer=False): - ''' + """ :param stream original: The stream to be wrapped (usually stdout/stderr, but could be None). @@ -20,11 +20,11 @@ def __init__(self, original, new_redirect, wrap_buffer=False): :param bool wrap_buffer: Whether to create a buffer attribute (needed to mimick python 3 s tdout/stderr which has a buffer to write binary data). - ''' + """ self._lock = ForkSafeLock(rlock=True) self._writing = False self._redirect_to = (original, new_redirect) - if wrap_buffer and hasattr(original, 'buffer'): + if wrap_buffer and hasattr(original, "buffer"): self.buffer = IORedirector(original.buffer, new_redirect.buffer, False) def write(self, s): @@ -36,20 +36,20 @@ def write(self, s): self._writing = True try: for r in self._redirect_to: - if hasattr(r, 'write'): + if hasattr(r, "write"): r.write(s) finally: self._writing = False def isatty(self): for r in self._redirect_to: - if hasattr(r, 'isatty'): + if hasattr(r, "isatty"): return r.isatty() return False def flush(self): for r in self._redirect_to: - if hasattr(r, 'flush'): + if hasattr(r, "flush"): r.flush() def __getattr__(self, name): @@ -60,9 +60,8 @@ def __getattr__(self, name): class RedirectToPyDBIoMessages(object): - def __init__(self, out_ctx, wrap_stream, wrap_buffer, on_write=None): - ''' + """ :param out_ctx: 1=stdout and 2=stderr @@ -77,10 +76,10 @@ def __init__(self, out_ctx, wrap_stream, wrap_buffer, on_write=None): May be a custom callable to be called when to write something. If not passed the default implementation will create an io message and send it through the debugger. - ''' - encoding = getattr(wrap_stream, 'encoding', None) + """ + encoding = getattr(wrap_stream, "encoding", None) if not encoding: - encoding = os.environ.get('PYTHONIOENCODING', 'utf-8') + encoding = os.environ.get("PYTHONIOENCODING", "utf-8") self.encoding = encoding self._out_ctx = out_ctx if wrap_buffer: @@ -102,7 +101,7 @@ def write(self, s): if s: # Need s in str if isinstance(s, bytes): - s = s.decode(self.encoding, errors='replace') + s = s.decode(self.encoding, errors="replace") py_db = self.get_pydb() if py_db is not None: @@ -114,24 +113,25 @@ def write(self, s): class IOBuf: - '''This class works as a replacement for stdio and stderr. + """This class works as a replacement for stdio and stderr. It is a buffer and when its contents are requested, it will erase what it has so far so that the next return will not return the same contents again. - ''' + """ def __init__(self): self.buflist = [] import os - self.encoding = os.environ.get('PYTHONIOENCODING', 'utf-8') + + self.encoding = os.environ.get("PYTHONIOENCODING", "utf-8") def getvalue(self): b = self.buflist self.buflist = [] # clear it - return ''.join(b) # bytes on py2, str on py3. + return "".join(b) # bytes on py2, str on py3. def write(self, s): if isinstance(s, bytes): - s = s.decode(self.encoding, errors='replace') + s = s.decode(self.encoding, errors="replace") self.buflist.append(s) def isatty(self): @@ -145,7 +145,6 @@ def empty(self): class _RedirectInfo(object): - def __init__(self, original, redirect_to): self.original = original self.redirect_to = redirect_to @@ -160,25 +159,25 @@ class _RedirectionsHolder: _pydevd_stderr_redirect_ = None -def start_redirect(keep_original_redirection=False, std='stdout', redirect_to=None): - ''' +def start_redirect(keep_original_redirection=False, std="stdout", redirect_to=None): + """ @param std: 'stdout', 'stderr', or 'both' - ''' + """ with _RedirectionsHolder._lock: if redirect_to is None: redirect_to = IOBuf() - if std == 'both': - config_stds = ['stdout', 'stderr'] + if std == "both": + config_stds = ["stdout", "stderr"] else: config_stds = [std] for std in config_stds: original = getattr(sys, std) - stack = getattr(_RedirectionsHolder, '_stack_%s' % std) + stack = getattr(_RedirectionsHolder, "_stack_%s" % std) if keep_original_redirection: - wrap_buffer = True if hasattr(redirect_to, 'buffer') else False + wrap_buffer = True if hasattr(redirect_to, "buffer") else False new_std_instance = IORedirector(getattr(sys, std), redirect_to, wrap_buffer=wrap_buffer) setattr(sys, std, new_std_instance) else: @@ -190,33 +189,33 @@ def start_redirect(keep_original_redirection=False, std='stdout', redirect_to=No return redirect_to -def end_redirect(std='stdout'): +def end_redirect(std="stdout"): with _RedirectionsHolder._lock: - if std == 'both': - config_stds = ['stdout', 'stderr'] + if std == "both": + config_stds = ["stdout", "stderr"] else: config_stds = [std] for std in config_stds: - stack = getattr(_RedirectionsHolder, '_stack_%s' % std) + stack = getattr(_RedirectionsHolder, "_stack_%s" % std) redirect_info = stack.pop() setattr(sys, std, redirect_info.original) def redirect_stream_to_pydb_io_messages(std): - ''' + """ :param std: 'stdout' or 'stderr' - ''' + """ with _RedirectionsHolder._lock: - redirect_to_name = '_pydevd_%s_redirect_' % (std,) + redirect_to_name = "_pydevd_%s_redirect_" % (std,) if getattr(_RedirectionsHolder, redirect_to_name) is None: wrap_buffer = True original = getattr(sys, std) - redirect_to = RedirectToPyDBIoMessages(1 if std == 'stdout' else 2, original, wrap_buffer) + redirect_to = RedirectToPyDBIoMessages(1 if std == "stdout" else 2, original, wrap_buffer) start_redirect(keep_original_redirection=True, std=std, redirect_to=redirect_to) - stack = getattr(_RedirectionsHolder, '_stack_%s' % std) + stack = getattr(_RedirectionsHolder, "_stack_%s" % std) setattr(_RedirectionsHolder, redirect_to_name, stack[-1]) return True @@ -224,17 +223,17 @@ def redirect_stream_to_pydb_io_messages(std): def stop_redirect_stream_to_pydb_io_messages(std): - ''' + """ :param std: 'stdout' or 'stderr' - ''' + """ with _RedirectionsHolder._lock: - redirect_to_name = '_pydevd_%s_redirect_' % (std,) + redirect_to_name = "_pydevd_%s_redirect_" % (std,) redirect_info = getattr(_RedirectionsHolder, redirect_to_name) if redirect_info is not None: # :type redirect_info: _RedirectInfo setattr(_RedirectionsHolder, redirect_to_name, None) - stack = getattr(_RedirectionsHolder, '_stack_%s' % std) + stack = getattr(_RedirectionsHolder, "_stack_%s" % std) prev_info = stack.pop() curr = getattr(sys, std) @@ -246,7 +245,7 @@ def stop_redirect_stream_to_pydb_io_messages(std): def redirect_stream_to_pydb_io_messages_context(): with _RedirectionsHolder._lock: redirecting = [] - for std in ('stdout', 'stderr'): + for std in ("stdout", "stderr"): if redirect_stream_to_pydb_io_messages(std): redirecting.append(std) @@ -255,4 +254,3 @@ def redirect_stream_to_pydb_io_messages_context(): finally: for std in redirecting: stop_redirect_stream_to_pydb_io_messages(std) - diff --git a/_pydevd_bundle/pydevd_json_debug_options.py b/_pydevd_bundle/pydevd_json_debug_options.py index 0165455c9..d8f93c1ea 100644 --- a/_pydevd_bundle/pydevd_json_debug_options.py +++ b/_pydevd_bundle/pydevd_json_debug_options.py @@ -3,18 +3,17 @@ class DebugOptions(object): - __slots__ = [ - 'just_my_code', - 'redirect_output', - 'show_return_value', - 'break_system_exit_zero', - 'django_debug', - 'flask_debug', - 'stop_on_entry', - 'max_exception_stack_frames', - 'gui_event_loop', - 'client_os', + "just_my_code", + "redirect_output", + "show_return_value", + "break_system_exit_zero", + "django_debug", + "flask_debug", + "stop_on_entry", + "max_exception_stack_frames", + "gui_event_loop", + "client_os", ] def __init__(self): @@ -26,7 +25,7 @@ def __init__(self): self.flask_debug = False self.stop_on_entry = False self.max_exception_stack_frames = 0 - self.gui_event_loop = 'matplotlib' + self.gui_event_loop = "matplotlib" self.client_os = None def to_json(self): @@ -36,68 +35,68 @@ def to_json(self): return json.dumps(dct) def update_fom_debug_options(self, debug_options): - if 'DEBUG_STDLIB' in debug_options: - self.just_my_code = not debug_options.get('DEBUG_STDLIB') + if "DEBUG_STDLIB" in debug_options: + self.just_my_code = not debug_options.get("DEBUG_STDLIB") - if 'REDIRECT_OUTPUT' in debug_options: - self.redirect_output = debug_options.get('REDIRECT_OUTPUT') + if "REDIRECT_OUTPUT" in debug_options: + self.redirect_output = debug_options.get("REDIRECT_OUTPUT") - if 'SHOW_RETURN_VALUE' in debug_options: - self.show_return_value = debug_options.get('SHOW_RETURN_VALUE') + if "SHOW_RETURN_VALUE" in debug_options: + self.show_return_value = debug_options.get("SHOW_RETURN_VALUE") - if 'BREAK_SYSTEMEXIT_ZERO' in debug_options: - self.break_system_exit_zero = debug_options.get('BREAK_SYSTEMEXIT_ZERO') + if "BREAK_SYSTEMEXIT_ZERO" in debug_options: + self.break_system_exit_zero = debug_options.get("BREAK_SYSTEMEXIT_ZERO") - if 'DJANGO_DEBUG' in debug_options: - self.django_debug = debug_options.get('DJANGO_DEBUG') + if "DJANGO_DEBUG" in debug_options: + self.django_debug = debug_options.get("DJANGO_DEBUG") - if 'FLASK_DEBUG' in debug_options: - self.flask_debug = debug_options.get('FLASK_DEBUG') + if "FLASK_DEBUG" in debug_options: + self.flask_debug = debug_options.get("FLASK_DEBUG") - if 'STOP_ON_ENTRY' in debug_options: - self.stop_on_entry = debug_options.get('STOP_ON_ENTRY') + if "STOP_ON_ENTRY" in debug_options: + self.stop_on_entry = debug_options.get("STOP_ON_ENTRY") - if 'CLIENT_OS_TYPE' in debug_options: - self.client_os = debug_options.get('CLIENT_OS_TYPE') + if "CLIENT_OS_TYPE" in debug_options: + self.client_os = debug_options.get("CLIENT_OS_TYPE") # Note: _max_exception_stack_frames cannot be set by debug options. def update_from_args(self, args): - if 'justMyCode' in args: - self.just_my_code = bool_parser(args['justMyCode']) + if "justMyCode" in args: + self.just_my_code = bool_parser(args["justMyCode"]) else: # i.e.: if justMyCode is provided, don't check the deprecated value - if 'debugStdLib' in args: - self.just_my_code = not bool_parser(args['debugStdLib']) + if "debugStdLib" in args: + self.just_my_code = not bool_parser(args["debugStdLib"]) - if 'redirectOutput' in args: - self.redirect_output = bool_parser(args['redirectOutput']) + if "redirectOutput" in args: + self.redirect_output = bool_parser(args["redirectOutput"]) - if 'showReturnValue' in args: - self.show_return_value = bool_parser(args['showReturnValue']) + if "showReturnValue" in args: + self.show_return_value = bool_parser(args["showReturnValue"]) - if 'breakOnSystemExitZero' in args: - self.break_system_exit_zero = bool_parser(args['breakOnSystemExitZero']) + if "breakOnSystemExitZero" in args: + self.break_system_exit_zero = bool_parser(args["breakOnSystemExitZero"]) - if 'django' in args: - self.django_debug = bool_parser(args['django']) + if "django" in args: + self.django_debug = bool_parser(args["django"]) - if 'flask' in args: - self.flask_debug = bool_parser(args['flask']) + if "flask" in args: + self.flask_debug = bool_parser(args["flask"]) - if 'jinja' in args: - self.flask_debug = bool_parser(args['jinja']) + if "jinja" in args: + self.flask_debug = bool_parser(args["jinja"]) - if 'stopOnEntry' in args: - self.stop_on_entry = bool_parser(args['stopOnEntry']) + if "stopOnEntry" in args: + self.stop_on_entry = bool_parser(args["stopOnEntry"]) - self.max_exception_stack_frames = int_parser(args.get('maxExceptionStackFrames', 0)) + self.max_exception_stack_frames = int_parser(args.get("maxExceptionStackFrames", 0)) - if 'guiEventLoop' in args: - self.gui_event_loop = str(args['guiEventLoop']) + if "guiEventLoop" in args: + self.gui_event_loop = str(args["guiEventLoop"]) - if 'clientOS' in args: - self.client_os = str(args['clientOS']).upper() + if "clientOS" in args: + self.client_os = str(args["clientOS"]).upper() def int_parser(s, default_value=0): @@ -116,55 +115,52 @@ def unquote(s): DEBUG_OPTIONS_PARSER = { - 'WAIT_ON_ABNORMAL_EXIT': bool_parser, - 'WAIT_ON_NORMAL_EXIT': bool_parser, - 'BREAK_SYSTEMEXIT_ZERO': bool_parser, - 'REDIRECT_OUTPUT': bool_parser, - 'DJANGO_DEBUG': bool_parser, - 'FLASK_DEBUG': bool_parser, - 'FIX_FILE_PATH_CASE': bool_parser, - 'CLIENT_OS_TYPE': unquote, - 'DEBUG_STDLIB': bool_parser, - 'STOP_ON_ENTRY': bool_parser, - 'SHOW_RETURN_VALUE': bool_parser, - 'MULTIPROCESS': bool_parser, + "WAIT_ON_ABNORMAL_EXIT": bool_parser, + "WAIT_ON_NORMAL_EXIT": bool_parser, + "BREAK_SYSTEMEXIT_ZERO": bool_parser, + "REDIRECT_OUTPUT": bool_parser, + "DJANGO_DEBUG": bool_parser, + "FLASK_DEBUG": bool_parser, + "FIX_FILE_PATH_CASE": bool_parser, + "CLIENT_OS_TYPE": unquote, + "DEBUG_STDLIB": bool_parser, + "STOP_ON_ENTRY": bool_parser, + "SHOW_RETURN_VALUE": bool_parser, + "MULTIPROCESS": bool_parser, } DEBUG_OPTIONS_BY_FLAG = { - 'RedirectOutput': 'REDIRECT_OUTPUT=True', - 'WaitOnNormalExit': 'WAIT_ON_NORMAL_EXIT=True', - 'WaitOnAbnormalExit': 'WAIT_ON_ABNORMAL_EXIT=True', - 'BreakOnSystemExitZero': 'BREAK_SYSTEMEXIT_ZERO=True', - 'Django': 'DJANGO_DEBUG=True', - 'Flask': 'FLASK_DEBUG=True', - 'Jinja': 'FLASK_DEBUG=True', - 'FixFilePathCase': 'FIX_FILE_PATH_CASE=True', - 'DebugStdLib': 'DEBUG_STDLIB=True', - 'WindowsClient': 'CLIENT_OS_TYPE=WINDOWS', - 'UnixClient': 'CLIENT_OS_TYPE=UNIX', - 'StopOnEntry': 'STOP_ON_ENTRY=True', - 'ShowReturnValue': 'SHOW_RETURN_VALUE=True', - 'Multiprocess': 'MULTIPROCESS=True', + "RedirectOutput": "REDIRECT_OUTPUT=True", + "WaitOnNormalExit": "WAIT_ON_NORMAL_EXIT=True", + "WaitOnAbnormalExit": "WAIT_ON_ABNORMAL_EXIT=True", + "BreakOnSystemExitZero": "BREAK_SYSTEMEXIT_ZERO=True", + "Django": "DJANGO_DEBUG=True", + "Flask": "FLASK_DEBUG=True", + "Jinja": "FLASK_DEBUG=True", + "FixFilePathCase": "FIX_FILE_PATH_CASE=True", + "DebugStdLib": "DEBUG_STDLIB=True", + "WindowsClient": "CLIENT_OS_TYPE=WINDOWS", + "UnixClient": "CLIENT_OS_TYPE=UNIX", + "StopOnEntry": "STOP_ON_ENTRY=True", + "ShowReturnValue": "SHOW_RETURN_VALUE=True", + "Multiprocess": "MULTIPROCESS=True", } def _build_debug_options(flags): """Build string representation of debug options from the launch config.""" - return ';'.join(DEBUG_OPTIONS_BY_FLAG[flag] - for flag in flags or [] - if flag in DEBUG_OPTIONS_BY_FLAG) + return ";".join(DEBUG_OPTIONS_BY_FLAG[flag] for flag in flags or [] if flag in DEBUG_OPTIONS_BY_FLAG) def _parse_debug_options(opts): - """Debug options are semicolon separated key=value pairs - """ + """Debug options are semicolon separated key=value pairs""" options = {} if not opts: return options - for opt in opts.split(';'): + for opt in opts.split(";"): try: - key, value = opt.split('=') + key, value = opt.split("=") except ValueError: continue try: diff --git a/_pydevd_bundle/pydevd_net_command.py b/_pydevd_bundle/pydevd_net_command.py index 506f5fd27..cc345f1c4 100644 --- a/_pydevd_bundle/pydevd_net_command.py +++ b/_pydevd_bundle/pydevd_net_command.py @@ -1,15 +1,17 @@ -from _pydevd_bundle.pydevd_constants import DebugInfoHolder, \ - get_global_debugger, GetGlobalDebugger, set_global_debugger # Keep for backward compatibility @UnusedImport +from _pydevd_bundle.pydevd_constants import ( + DebugInfoHolder, + get_global_debugger, + GetGlobalDebugger, + set_global_debugger, +) # Keep for backward compatibility @UnusedImport from _pydevd_bundle.pydevd_utils import quote_smart as quote, to_string from _pydevd_bundle.pydevd_comm_constants import ID_TO_MEANING, CMD_EXIT -from _pydevd_bundle.pydevd_constants import HTTP_PROTOCOL, HTTP_JSON_PROTOCOL, \ - get_protocol, IS_JYTHON, ForkSafeLock +from _pydevd_bundle.pydevd_constants import HTTP_PROTOCOL, HTTP_JSON_PROTOCOL, get_protocol, IS_JYTHON, ForkSafeLock import json from _pydev_bundle import pydev_log class _BaseNetCommand(object): - # Command id. Should be set in instance. id = -1 @@ -28,7 +30,6 @@ class _NullNetCommand(_BaseNetCommand): class _NullExitCommand(_NullNetCommand): - id = CMD_EXIT @@ -46,6 +47,7 @@ class NetCommand(_BaseNetCommand): Command can represent command received from the debugger, or one to be sent by daemon. """ + next_seq = 0 # sequence numbers _showing_debug_info = 0 @@ -67,13 +69,13 @@ def __init__(self, cmd_id, seq, text, is_json=False): self.seq = seq if is_json: - if hasattr(text, 'to_dict'): + if hasattr(text, "to_dict"): as_dict = text.to_dict(update_ids_to_dap=True) else: assert isinstance(text, dict) as_dict = text - as_dict['pydevd_cmd_id'] = cmd_id - as_dict['seq'] = seq + as_dict["pydevd_cmd_id"] = cmd_id + as_dict["seq"] = seq self.as_dict = as_dict text = json.dumps(as_dict) @@ -87,13 +89,13 @@ def __init__(self, cmd_id, seq, text, is_json=False): else: if protocol not in (HTTP_PROTOCOL, HTTP_JSON_PROTOCOL): encoded = quote(to_string(text), '/<>_=" \t') - msg = '%s\t%s\t%s\n' % (cmd_id, seq, encoded) + msg = "%s\t%s\t%s\n" % (cmd_id, seq, encoded) else: - msg = '%s\t%s\t%s' % (cmd_id, seq, text) + msg = "%s\t%s\t%s" % (cmd_id, seq, text) if isinstance(msg, str): - msg = msg.encode('utf-8') + msg = msg.encode("utf-8") assert isinstance(msg, bytes) as_bytes = msg @@ -103,7 +105,7 @@ def send(self, sock): as_bytes = self._as_bytes try: if get_protocol() in (HTTP_PROTOCOL, HTTP_JSON_PROTOCOL): - sock.sendall(('Content-Length: %s\r\n\r\n' % len(as_bytes)).encode('ascii')) + sock.sendall(("Content-Length: %s\r\n\r\n" % len(as_bytes)).encode("ascii")) sock.sendall(as_bytes) if self._after_send: for method in self._after_send: @@ -133,14 +135,13 @@ def _show_debug_info(cls, cmd_id, seq, text): cls._showing_debug_info += 1 try: - out_message = 'sending cmd (%s) --> ' % (get_protocol(),) - out_message += "%20s" % ID_TO_MEANING.get(str(cmd_id), 'UNKNOWN') - out_message += ' ' - out_message += text.replace('\n', ' ') + out_message = "sending cmd (%s) --> " % (get_protocol(),) + out_message += "%20s" % ID_TO_MEANING.get(str(cmd_id), "UNKNOWN") + out_message += " " + out_message += text.replace("\n", " ") try: - pydev_log.critical('%s\n', out_message) + pydev_log.critical("%s\n", out_message) except: pass finally: cls._showing_debug_info -= 1 - diff --git a/_pydevd_bundle/pydevd_net_command_factory_json.py b/_pydevd_bundle/pydevd_net_command_factory_json.py index 1fad2e42f..7715ddb00 100644 --- a/_pydevd_bundle/pydevd_net_command_factory_json.py +++ b/_pydevd_bundle/pydevd_net_command_factory_json.py @@ -4,21 +4,46 @@ import sys import socket as socket_module -from _pydev_bundle._pydev_imports_tipper import TYPE_IMPORT, TYPE_CLASS, TYPE_FUNCTION, TYPE_ATTR, \ - TYPE_BUILTIN, TYPE_PARAM +from _pydev_bundle._pydev_imports_tipper import TYPE_IMPORT, TYPE_CLASS, TYPE_FUNCTION, TYPE_ATTR, TYPE_BUILTIN, TYPE_PARAM from _pydev_bundle.pydev_is_thread_alive import is_thread_alive from _pydev_bundle.pydev_override import overrides from _pydevd_bundle._debug_adapter import pydevd_schema -from _pydevd_bundle._debug_adapter.pydevd_schema import ModuleEvent, ModuleEventBody, Module, \ - OutputEventBody, OutputEvent, ContinuedEventBody, ExitedEventBody, \ - ExitedEvent -from _pydevd_bundle.pydevd_comm_constants import CMD_THREAD_CREATE, CMD_RETURN, CMD_MODULE_EVENT, \ - CMD_WRITE_TO_CONSOLE, CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE, CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, \ - CMD_STEP_RETURN, CMD_STEP_CAUGHT_EXCEPTION, CMD_ADD_EXCEPTION_BREAK, CMD_SET_BREAK, \ - CMD_SET_NEXT_STATEMENT, CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, \ - CMD_THREAD_RESUME_SINGLE_NOTIFICATION, CMD_THREAD_KILL, CMD_STOP_ON_START, CMD_INPUT_REQUESTED, \ - CMD_EXIT, CMD_STEP_INTO_COROUTINE, CMD_STEP_RETURN_MY_CODE, CMD_SMART_STEP_INTO, \ - CMD_SET_FUNCTION_BREAK, CMD_THREAD_RUN +from _pydevd_bundle._debug_adapter.pydevd_schema import ( + ModuleEvent, + ModuleEventBody, + Module, + OutputEventBody, + OutputEvent, + ContinuedEventBody, + ExitedEventBody, + ExitedEvent, +) +from _pydevd_bundle.pydevd_comm_constants import ( + CMD_THREAD_CREATE, + CMD_RETURN, + CMD_MODULE_EVENT, + CMD_WRITE_TO_CONSOLE, + CMD_STEP_INTO, + CMD_STEP_INTO_MY_CODE, + CMD_STEP_OVER, + CMD_STEP_OVER_MY_CODE, + CMD_STEP_RETURN, + CMD_STEP_CAUGHT_EXCEPTION, + CMD_ADD_EXCEPTION_BREAK, + CMD_SET_BREAK, + CMD_SET_NEXT_STATEMENT, + CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, + CMD_THREAD_RESUME_SINGLE_NOTIFICATION, + CMD_THREAD_KILL, + CMD_STOP_ON_START, + CMD_INPUT_REQUESTED, + CMD_EXIT, + CMD_STEP_INTO_COROUTINE, + CMD_STEP_RETURN_MY_CODE, + CMD_SMART_STEP_INTO, + CMD_SET_FUNCTION_BREAK, + CMD_THREAD_RUN, +) from _pydevd_bundle.pydevd_constants import get_thread_id, ForkSafeLock, DebugInfoHolder from _pydevd_bundle.pydevd_net_command import NetCommand, NULL_NET_COMMAND from _pydevd_bundle.pydevd_net_command_factory_xml import NetCommandFactory @@ -33,17 +58,16 @@ class ModulesManager(object): - def __init__(self): self._lock = ForkSafeLock() self._modules = {} self._next_id = partial(next, itertools.count(0)) def track_module(self, filename_in_utf8, module_name, frame): - ''' + """ :return list(NetCommand): Returns a list with the module events to be sent. - ''' + """ if filename_in_utf8 in self._modules: return [] @@ -54,14 +78,14 @@ def track_module(self, filename_in_utf8, module_name, frame): return try: - version = str(frame.f_globals.get('__version__', '')) + version = str(frame.f_globals.get("__version__", "")) except: - version = '' + version = "" try: - package_name = str(frame.f_globals.get('__package__', '')) + package_name = str(frame.f_globals.get("__package__", "")) except: - package_name = '' + package_name = "" module_id = self._next_id() @@ -71,9 +95,9 @@ def track_module(self, filename_in_utf8, module_name, frame): if package_name: # Note: package doesn't appear in the docs but seems to be expected? - module.kwargs['package'] = package_name + module.kwargs["package"] = package_name - module_event = ModuleEvent(ModuleEventBody('new', module)) + module_event = ModuleEvent(ModuleEventBody("new", module)) module_events.append(NetCommand(CMD_MODULE_EVENT, 0, module_event, is_json=True)) @@ -81,15 +105,15 @@ def track_module(self, filename_in_utf8, module_name, frame): return module_events def get_modules_info(self): - ''' + """ :return list(Module) - ''' + """ with self._lock: return list(self._modules.values()) class NetCommandFactoryJson(NetCommandFactory): - ''' + """ Factory for commands which will provide messages as json (they should be similar to the debug adapter where possible, although some differences are currently Ok). @@ -98,7 +122,7 @@ class NetCommandFactoryJson(NetCommandFactory): can be done one at a time (any message not overridden will currently use the xml version) -- after having all messages handled, it should no longer use NetCommandFactory as the base class. - ''' + """ def __init__(self): NetCommandFactory.__init__(self) @@ -114,11 +138,10 @@ def make_protocol_set_message(self, seq): @overrides(NetCommandFactory.make_thread_created_message) def make_thread_created_message(self, thread): - # Note: the thread id for the debug adapter must be an int # (make the actual id from get_thread_id respect that later on). msg = pydevd_schema.ThreadEvent( - pydevd_schema.ThreadEventBody('started', get_thread_id(thread)), + pydevd_schema.ThreadEventBody("started", get_thread_id(thread)), ) return NetCommand(CMD_THREAD_CREATE, 0, msg, is_json=True) @@ -127,7 +150,7 @@ def make_thread_created_message(self, thread): def make_custom_frame_created_message(self, frame_id, frame_description): self._additional_thread_id_to_thread_name[frame_id] = frame_description msg = pydevd_schema.ThreadEvent( - pydevd_schema.ThreadEventBody('started', frame_id), + pydevd_schema.ThreadEventBody("started", frame_id), ) return NetCommand(CMD_THREAD_CREATE, 0, msg, is_json=True) @@ -136,7 +159,7 @@ def make_custom_frame_created_message(self, frame_id, frame_description): def make_thread_killed_message(self, tid): self._additional_thread_id_to_thread_name.pop(tid, None) msg = pydevd_schema.ThreadEvent( - pydevd_schema.ThreadEventBody('exited', tid), + pydevd_schema.ThreadEventBody("exited", tid), ) return NetCommand(CMD_THREAD_KILL, 0, msg, is_json=True) @@ -159,8 +182,7 @@ def make_list_threads_message(self, py_db, seq): threads.append(thread_schema.to_dict()) body = pydevd_schema.ThreadsResponseBody(threads) - response = pydevd_schema.ThreadsResponse( - request_seq=seq, success=True, command='threads', body=body) + response = pydevd_schema.ThreadsResponse(request_seq=seq, success=True, command="threads", body=body) return NetCommand(CMD_RETURN, 0, response, is_json=True) @@ -182,34 +204,34 @@ def make_get_completions_message(self, seq, completions, qualifier, start): label = completion[0] if label.lower().startswith(qualifier): completion = pydevd_schema.CompletionItem( - label=label, type=COMPLETION_TYPE_LOOK_UP[completion[3]], start=start, length=qualifier_len) + label=label, type=COMPLETION_TYPE_LOOK_UP[completion[3]], start=start, length=qualifier_len + ) targets.append(completion.to_dict()) body = pydevd_schema.CompletionsResponseBody(targets) - response = pydevd_schema.CompletionsResponse( - request_seq=seq, success=True, command='completions', body=body) + response = pydevd_schema.CompletionsResponse(request_seq=seq, success=True, command="completions", body=body) return NetCommand(CMD_RETURN, 0, response, is_json=True) def _format_frame_name(self, fmt, initial_name, module_name, line, path): if fmt is None: return initial_name frame_name = initial_name - if fmt.get('module', False): + if fmt.get("module", False): if module_name: - if initial_name == '': + if initial_name == "": frame_name = module_name else: - frame_name = '%s.%s' % (module_name, initial_name) + frame_name = "%s.%s" % (module_name, initial_name) else: basename = os.path.basename(path) - basename = basename[0:-3] if basename.lower().endswith('.py') else basename - if initial_name == '': - frame_name = '%s in %s' % (initial_name, basename) + basename = basename[0:-3] if basename.lower().endswith(".py") else basename + if initial_name == "": + frame_name = "%s in %s" % (initial_name, basename) else: - frame_name = '%s.%s' % (basename, initial_name) + frame_name = "%s.%s" % (basename, initial_name) - if fmt.get('line', False): - frame_name = '%s : %d' % (frame_name, line) + if fmt.get("line", False): + frame_name = "%s : %d" % (frame_name, line) return frame_name @@ -229,32 +251,39 @@ def make_get_thread_stack_message(self, py_db, seq, thread_id, topmost_frame, fm else: frames_list = pydevd_frame_utils.create_frames_list_from_frame(topmost_frame) - for frame_id, frame, method_name, original_filename, filename_in_utf8, lineno, applied_mapping, show_as_current_frame, line_col_info in self._iter_visible_frames_info( - py_db, frames_list, flatten_chained=True - ): - + for ( + frame_id, + frame, + method_name, + original_filename, + filename_in_utf8, + lineno, + applied_mapping, + show_as_current_frame, + line_col_info, + ) in self._iter_visible_frames_info(py_db, frames_list, flatten_chained=True): try: - module_name = str(frame.f_globals.get('__name__', '')) + module_name = str(frame.f_globals.get("__name__", "")) except: - module_name = '' + module_name = "" module_events.extend(self.modules_manager.track_module(filename_in_utf8, module_name, frame)) presentation_hint = None - if not getattr(frame, 'IS_PLUGIN_FRAME', False): # Never filter out plugin frames! + if not getattr(frame, "IS_PLUGIN_FRAME", False): # Never filter out plugin frames! if py_db.is_files_filter_enabled and py_db.apply_files_filter(frame, original_filename, False): continue if not py_db.in_project_scope(frame): - presentation_hint = 'subtle' + presentation_hint = "subtle" formatted_name = self._format_frame_name(fmt, method_name, module_name, lineno, filename_in_utf8) if show_as_current_frame: - formatted_name += ' (Current frame)' + formatted_name += " (Current frame)" source_reference = pydevd_file_utils.get_client_filename_source_reference(filename_in_utf8) if not source_reference and not applied_mapping and not os.path.exists(original_filename): - if getattr(frame.f_code, 'co_lines', None) or getattr(frame.f_code, 'co_lnotab', None): + if getattr(frame.f_code, "co_lines", None) or getattr(frame.f_code, "co_lnotab", None): # Create a source-reference to be used where we provide the source by decompiling the code. # Note: When the time comes to retrieve the source reference in this case, we'll # check the linecache first (see: get_decompiled_source_from_frame_id). @@ -262,8 +291,7 @@ def make_get_thread_stack_message(self, py_db, seq, thread_id, topmost_frame, fm else: # Check if someone added a source reference to the linecache (Python attrs does this). if linecache.getline(original_filename, 1): - source_reference = pydevd_file_utils.create_source_reference_for_linecache( - original_filename) + source_reference = pydevd_file_utils.create_source_reference_for_linecache(original_filename) column = 1 endcol = None @@ -272,7 +300,7 @@ def make_get_thread_stack_message(self, py_db, seq, thread_id, topmost_frame, fm line_text = linecache.getline(original_filename, lineno) except: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 2: - pydev_log.exception('Unable to get line from linecache for file: %s', original_filename) + pydev_log.exception("Unable to get line from linecache for file: %s", original_filename) else: if line_text: colno, endcolno = line_col_info.map_columns_to_line(line_text) @@ -280,12 +308,20 @@ def make_get_thread_stack_message(self, py_db, seq, thread_id, topmost_frame, fm if line_col_info.lineno == line_col_info.end_lineno: endcol = endcolno + 1 - frames.append(pydevd_schema.StackFrame( - frame_id, formatted_name, lineno, column=column, endColumn=endcol, source={ - 'path': filename_in_utf8, - 'sourceReference': source_reference, - }, - presentationHint=presentation_hint).to_dict()) + frames.append( + pydevd_schema.StackFrame( + frame_id, + formatted_name, + lineno, + column=column, + endColumn=endcol, + source={ + "path": filename_in_utf8, + "sourceReference": source_reference, + }, + presentationHint=presentation_hint, + ).to_dict() + ) finally: topmost_frame = None @@ -302,47 +338,52 @@ def make_get_thread_stack_message(self, py_db, seq, thread_id, topmost_frame, fm response = pydevd_schema.StackTraceResponse( request_seq=seq, success=True, - command='stackTrace', - body=pydevd_schema.StackTraceResponseBody(stackFrames=stack_frames, totalFrames=total_frames)) + command="stackTrace", + body=pydevd_schema.StackTraceResponseBody(stackFrames=stack_frames, totalFrames=total_frames), + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) @overrides(NetCommandFactory.make_warning_message) def make_warning_message(self, msg): - category = 'important' + category = "important" body = OutputEventBody(msg, category) event = OutputEvent(body) return NetCommand(CMD_WRITE_TO_CONSOLE, 0, event, is_json=True) @overrides(NetCommandFactory.make_io_message) def make_io_message(self, msg, ctx): - category = 'stdout' if int(ctx) == 1 else 'stderr' + category = "stdout" if int(ctx) == 1 else "stderr" body = OutputEventBody(msg, category) event = OutputEvent(body) return NetCommand(CMD_WRITE_TO_CONSOLE, 0, event, is_json=True) @overrides(NetCommandFactory.make_console_message) def make_console_message(self, msg): - category = 'console' + category = "console" body = OutputEventBody(msg, category) event = OutputEvent(body) return NetCommand(CMD_WRITE_TO_CONSOLE, 0, event, is_json=True) - _STEP_REASONS = set([ - CMD_STEP_INTO, - CMD_STEP_INTO_MY_CODE, - CMD_STEP_OVER, - CMD_STEP_OVER_MY_CODE, - CMD_STEP_RETURN, - CMD_STEP_RETURN_MY_CODE, - CMD_STEP_INTO_MY_CODE, - CMD_STOP_ON_START, - CMD_STEP_INTO_COROUTINE, - CMD_SMART_STEP_INTO, - ]) - _EXCEPTION_REASONS = set([ - CMD_STEP_CAUGHT_EXCEPTION, - CMD_ADD_EXCEPTION_BREAK, - ]) + _STEP_REASONS = set( + [ + CMD_STEP_INTO, + CMD_STEP_INTO_MY_CODE, + CMD_STEP_OVER, + CMD_STEP_OVER_MY_CODE, + CMD_STEP_RETURN, + CMD_STEP_RETURN_MY_CODE, + CMD_STEP_INTO_MY_CODE, + CMD_STOP_ON_START, + CMD_STEP_INTO_COROUTINE, + CMD_SMART_STEP_INTO, + ] + ) + _EXCEPTION_REASONS = set( + [ + CMD_STEP_CAUGHT_EXCEPTION, + CMD_ADD_EXCEPTION_BREAK, + ] + ) @overrides(NetCommandFactory.make_thread_suspend_single_notification) def make_thread_suspend_single_notification(self, py_db, thread_id, thread, stop_reason): @@ -353,27 +394,27 @@ def make_thread_suspend_single_notification(self, py_db, thread_id, thread, stop preserve_focus_hint = False if stop_reason in self._STEP_REASONS: if info.pydev_original_step_cmd == CMD_STOP_ON_START: - # Just to make sure that's not set as the original reason anymore. info.pydev_original_step_cmd = -1 - stop_reason = 'entry' + stop_reason = "entry" else: - stop_reason = 'step' + stop_reason = "step" elif stop_reason in self._EXCEPTION_REASONS: - stop_reason = 'exception' + stop_reason = "exception" elif stop_reason == CMD_SET_BREAK: - stop_reason = 'breakpoint' + stop_reason = "breakpoint" elif stop_reason == CMD_SET_FUNCTION_BREAK: - stop_reason = 'function breakpoint' + stop_reason = "function breakpoint" elif stop_reason == CMD_SET_NEXT_STATEMENT: - stop_reason = 'goto' + stop_reason = "goto" else: - stop_reason = 'pause' + stop_reason = "pause" preserve_focus_hint = True - if stop_reason == 'exception': + if stop_reason == "exception": exception_info_response = build_exception_info_response( - py_db, thread_id, thread, -1, set_additional_thread_info, self._iter_visible_frames_info, max_frames=-1) + py_db, thread_id, thread, -1, set_additional_thread_info, self._iter_visible_frames_info, max_frames=-1 + ) exception_info_response exc_name = exception_info_response.body.exceptionId @@ -399,11 +440,8 @@ def make_thread_resume_single_notification(self, thread_id): @overrides(NetCommandFactory.make_set_next_stmnt_status_message) def make_set_next_stmnt_status_message(self, seq, is_success, exception_msg): response = pydevd_schema.GotoResponse( - request_seq=int(seq), - success=is_success, - command='goto', - body={}, - message=(None if is_success else exception_msg)) + request_seq=int(seq), success=is_success, command="goto", body={}, message=(None if is_success else exception_msg) + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) @overrides(NetCommandFactory.make_send_curr_exception_trace_message) @@ -437,6 +475,7 @@ def after_send(socket): @overrides(NetCommandFactory.make_thread_suspend_message) def make_thread_suspend_message(self, py_db, thread_id, frames_list, stop_reason, message, trace_suspend_type, thread, info): from _pydevd_bundle.pydevd_comm_constants import CMD_THREAD_SUSPEND + if py_db.multi_threads_single_notification: pydev_log.debug("Skipping per-thread thread suspend notification.") return NULL_NET_COMMAND # Don't send per-thread, send a single one. @@ -447,27 +486,27 @@ def make_thread_suspend_message(self, py_db, thread_id, frames_list, stop_reason preserve_focus_hint = False if stop_reason in self._STEP_REASONS: if info.pydev_original_step_cmd == CMD_STOP_ON_START: - # Just to make sure that's not set as the original reason anymore. info.pydev_original_step_cmd = -1 - stop_reason = 'entry' + stop_reason = "entry" else: - stop_reason = 'step' + stop_reason = "step" elif stop_reason in self._EXCEPTION_REASONS: - stop_reason = 'exception' + stop_reason = "exception" elif stop_reason == CMD_SET_BREAK: - stop_reason = 'breakpoint' + stop_reason = "breakpoint" elif stop_reason == CMD_SET_FUNCTION_BREAK: - stop_reason = 'function breakpoint' + stop_reason = "function breakpoint" elif stop_reason == CMD_SET_NEXT_STATEMENT: - stop_reason = 'goto' + stop_reason = "goto" else: - stop_reason = 'pause' + stop_reason = "pause" preserve_focus_hint = True - if stop_reason == 'exception': + if stop_reason == "exception": exception_info_response = build_exception_info_response( - py_db, thread_id, thread, -1, set_additional_thread_info, self._iter_visible_frames_info, max_frames=-1) + py_db, thread_id, thread, -1, set_additional_thread_info, self._iter_visible_frames_info, max_frames=-1 + ) exception_info_response exc_name = exception_info_response.body.exceptionId @@ -503,15 +542,17 @@ def make_input_requested_message(self, started): @overrides(NetCommandFactory.make_skipped_step_in_because_of_filters) def make_skipped_step_in_because_of_filters(self, py_db, frame): - msg = 'Frame skipped from debugging during step-in.' + msg = "Frame skipped from debugging during step-in." if py_db.get_use_libraries_filter(): - msg += ('\nNote: may have been skipped because of "justMyCode" option (default == true). ' - 'Try setting \"justMyCode\": false in the debug configuration (e.g., launch.json).\n') + msg += ( + '\nNote: may have been skipped because of "justMyCode" option (default == true). ' + 'Try setting "justMyCode": false in the debug configuration (e.g., launch.json).\n' + ) return self.make_warning_message(msg) @overrides(NetCommandFactory.make_evaluation_timeout_msg) def make_evaluation_timeout_msg(self, py_db, expression, curr_thread): - msg = '''Evaluating: %s did not finish after %.2f seconds. + msg = """Evaluating: %s did not finish after %.2f seconds. This may mean a number of things: - This evaluation is really slow and this is expected. In this case it's possible to silence this error by raising the timeout, setting the @@ -531,12 +572,12 @@ def make_evaluation_timeout_msg(self, py_db, expression, curr_thread): environment variable to true so that a thread dump is shown along with this message and optionally, set the PYDEVD_INTERRUPT_THREAD_TIMEOUT to some value so that the debugger tries to interrupt the evaluation (if possible) when this happens. -''' % (expression, pydevd_constants.PYDEVD_WARN_EVALUATION_TIMEOUT) +""" % (expression, pydevd_constants.PYDEVD_WARN_EVALUATION_TIMEOUT) if pydevd_constants.PYDEVD_THREAD_DUMP_ON_WARN_EVALUATION_TIMEOUT: stream = StringIO() pydevd_utils.dump_threads(stream, show_pydevd_threads=False) - msg += '\n\n%s\n' % stream.getvalue() + msg += "\n\n%s\n" % stream.getvalue() return self.make_warning_message(msg) @overrides(NetCommandFactory.make_exit_command) diff --git a/_pydevd_bundle/pydevd_net_command_factory_xml.py b/_pydevd_bundle/pydevd_net_command_factory_xml.py index de525e255..a9c3ad5be 100644 --- a/_pydevd_bundle/pydevd_net_command_factory_xml.py +++ b/_pydevd_bundle/pydevd_net_command_factory_xml.py @@ -4,21 +4,52 @@ from _pydev_bundle._pydev_saved_modules import thread from _pydevd_bundle import pydevd_xml, pydevd_frame_utils, pydevd_constants, pydevd_utils from _pydevd_bundle.pydevd_comm_constants import ( - CMD_THREAD_CREATE, CMD_THREAD_KILL, CMD_THREAD_SUSPEND, CMD_THREAD_RUN, CMD_GET_VARIABLE, - CMD_EVALUATE_EXPRESSION, CMD_GET_FRAME, CMD_WRITE_TO_CONSOLE, CMD_GET_COMPLETIONS, - CMD_LOAD_SOURCE, CMD_SET_NEXT_STATEMENT, CMD_EXIT, CMD_GET_FILE_CONTENTS, - CMD_EVALUATE_CONSOLE_EXPRESSION, CMD_RUN_CUSTOM_OPERATION, - CMD_GET_BREAKPOINT_EXCEPTION, CMD_SEND_CURR_EXCEPTION_TRACE, - CMD_SEND_CURR_EXCEPTION_TRACE_PROCEEDED, CMD_SHOW_CONSOLE, CMD_GET_ARRAY, - CMD_INPUT_REQUESTED, CMD_GET_DESCRIPTION, CMD_PROCESS_CREATED, - CMD_SHOW_CYTHON_WARNING, CMD_LOAD_FULL_VALUE, CMD_GET_THREAD_STACK, - CMD_GET_EXCEPTION_DETAILS, CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, + CMD_THREAD_CREATE, + CMD_THREAD_KILL, + CMD_THREAD_SUSPEND, + CMD_THREAD_RUN, + CMD_GET_VARIABLE, + CMD_EVALUATE_EXPRESSION, + CMD_GET_FRAME, + CMD_WRITE_TO_CONSOLE, + CMD_GET_COMPLETIONS, + CMD_LOAD_SOURCE, + CMD_SET_NEXT_STATEMENT, + CMD_EXIT, + CMD_GET_FILE_CONTENTS, + CMD_EVALUATE_CONSOLE_EXPRESSION, + CMD_RUN_CUSTOM_OPERATION, + CMD_GET_BREAKPOINT_EXCEPTION, + CMD_SEND_CURR_EXCEPTION_TRACE, + CMD_SEND_CURR_EXCEPTION_TRACE_PROCEEDED, + CMD_SHOW_CONSOLE, + CMD_GET_ARRAY, + CMD_INPUT_REQUESTED, + CMD_GET_DESCRIPTION, + CMD_PROCESS_CREATED, + CMD_SHOW_CYTHON_WARNING, + CMD_LOAD_FULL_VALUE, + CMD_GET_THREAD_STACK, + CMD_GET_EXCEPTION_DETAILS, + CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, CMD_THREAD_RESUME_SINGLE_NOTIFICATION, - CMD_GET_NEXT_STATEMENT_TARGETS, CMD_VERSION, - CMD_RETURN, CMD_SET_PROTOCOL, CMD_ERROR, MAX_IO_MSG_SIZE, VERSION_STRING, - CMD_RELOAD_CODE, CMD_LOAD_SOURCE_FROM_FRAME_ID) -from _pydevd_bundle.pydevd_constants import (DebugInfoHolder, get_thread_id, - get_global_debugger, GetGlobalDebugger, set_global_debugger) # Keep for backward compatibility @UnusedImport + CMD_GET_NEXT_STATEMENT_TARGETS, + CMD_VERSION, + CMD_RETURN, + CMD_SET_PROTOCOL, + CMD_ERROR, + MAX_IO_MSG_SIZE, + VERSION_STRING, + CMD_RELOAD_CODE, + CMD_LOAD_SOURCE_FROM_FRAME_ID, +) +from _pydevd_bundle.pydevd_constants import ( + DebugInfoHolder, + get_thread_id, + get_global_debugger, + GetGlobalDebugger, + set_global_debugger, +) # Keep for backward compatibility @UnusedImport from _pydevd_bundle.pydevd_net_command import NetCommand, NULL_NET_COMMAND, NULL_EXIT_COMMAND from _pydevd_bundle.pydevd_utils import quote_smart as quote, get_non_pydevd_threads from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame @@ -30,16 +61,15 @@ from io import StringIO -#======================================================================================================================= +# ======================================================================================================================= # NetCommandFactory -#======================================================================================================================= +# ======================================================================================================================= class NetCommandFactory(object): - def __init__(self): self._additional_thread_id_to_thread_name = {} def _thread_to_xml(self, thread): - """ thread information as XML """ + """thread information as XML""" name = pydevd_xml.make_valid_xml_value(thread.name) cmd_text = '' % (quote(name), get_thread_id(thread)) return cmd_text @@ -51,14 +81,14 @@ def make_error_message(self, seq, text): return cmd def make_protocol_set_message(self, seq): - return NetCommand(CMD_SET_PROTOCOL, seq, '') + return NetCommand(CMD_SET_PROTOCOL, seq, "") def make_thread_created_message(self, thread): cmdText = "" + self._thread_to_xml(thread) + "" return NetCommand(CMD_THREAD_CREATE, 0, cmdText) def make_process_created_message(self): - cmdText = '' + cmdText = "" return NetCommand(CMD_PROCESS_CREATED, 0, cmdText) def make_process_about_to_be_replaced_message(self): @@ -66,7 +96,7 @@ def make_process_about_to_be_replaced_message(self): def make_show_cython_warning_message(self): try: - return NetCommand(CMD_SHOW_CYTHON_WARNING, 0, '') + return NetCommand(CMD_SHOW_CYTHON_WARNING, 0, "") except: return self.make_error_message(0, get_exception_traceback_str()) @@ -76,7 +106,7 @@ def make_custom_frame_created_message(self, frame_id, frame_description): return NetCommand(CMD_THREAD_CREATE, 0, '' % (frame_description, frame_id)) def make_list_threads_message(self, py_db, seq): - """ returns thread listing as XML """ + """returns thread listing as XML""" try: threads = get_non_pydevd_threads() cmd_text = [""] @@ -90,7 +120,7 @@ def make_list_threads_message(self, py_db, seq): append('' % (quote(name), thread_id)) append("") - return NetCommand(CMD_RETURN, seq, ''.join(cmd_text)) + return NetCommand(CMD_RETURN, seq, "".join(cmd_text)) except: return self.make_error_message(seq, get_exception_traceback_str()) @@ -119,8 +149,8 @@ def make_get_thread_stack_message(self, py_db, seq, thread_id, topmost_frame, fm cmd_text.append(self.make_thread_stack_str(py_db, frames_list)) finally: topmost_frame = None - cmd_text.append('') - return NetCommand(CMD_GET_THREAD_STACK, seq, ''.join(cmd_text)) + cmd_text.append("") + return NetCommand(CMD_GET_THREAD_STACK, seq, "".join(cmd_text)) except: return self.make_error_message(seq, get_exception_traceback_str()) @@ -135,18 +165,18 @@ def make_console_message(self, msg): return self.make_io_message(msg, 2) def make_io_message(self, msg, ctx): - ''' + """ @param msg: the message to pass to the debug server @param ctx: 1 for stdio 2 for stderr - ''' + """ try: msg = pydevd_constants.as_str(msg) if len(msg) > MAX_IO_MSG_SIZE: msg = msg[0:MAX_IO_MSG_SIZE] - msg += '...' + msg += "..." - msg = pydevd_xml.make_valid_xml_value(quote(msg, '/>_= ')) + msg = pydevd_xml.make_valid_xml_value(quote(msg, "/>_= ")) return NetCommand(str(CMD_WRITE_TO_CONSOLE), 0, '' % (msg, ctx)) except: return self.make_error_message(0, get_exception_traceback_str()) @@ -171,16 +201,16 @@ def _iter_visible_frames_info(self, py_db, frames_list, flatten_chained=False): for frame in frames_list: show_as_current_frame = frame is frames_list.current_frame if frame.f_code is None: - pydev_log.info('Frame without f_code: %s', frame) + pydev_log.info("Frame without f_code: %s", frame) continue # IronPython sometimes does not have it! method_name = frame.f_code.co_name # method name (if in method) or ? if global if method_name is None: - pydev_log.info('Frame without co_name: %s', frame) + pydev_log.info("Frame without co_name: %s", frame) continue # IronPython sometimes does not have it! if is_chained: - method_name = '[Chained Exc: %s] %s' % (frames_list.exc_desc, method_name) + method_name = "[Chained Exc: %s] %s" % (frames_list.exc_desc, method_name) abs_path_real_path_and_base = get_abs_path_real_path_and_base_from_frame(frame) if py_db.get_file_type(frame, abs_path_real_path_and_base) == py_db.PYDEV_FILE: @@ -196,7 +226,17 @@ def _iter_visible_frames_info(self, py_db, frames_list, flatten_chained=False): new_filename_in_utf8, applied_mapping = pydevd_file_utils.map_file_to_client(filename_in_utf8) applied_mapping = applied_mapping or changed - yield frame_id, frame, method_name, abs_path_real_path_and_base[0], new_filename_in_utf8, lineno, applied_mapping, show_as_current_frame, line_col_info + yield ( + frame_id, + frame, + method_name, + abs_path_real_path_and_base[0], + new_filename_in_utf8, + lineno, + applied_mapping, + show_as_current_frame, + line_col_info, + ) if not flatten_chained: break @@ -213,21 +253,28 @@ def make_thread_stack_str(self, py_db, frames_list): append = cmd_text_list.append try: - for frame_id, frame, method_name, _original_filename, filename_in_utf8, lineno, _applied_mapping, _show_as_current_frame, line_col_info in self._iter_visible_frames_info( - py_db, frames_list, flatten_chained=True - ): - + for ( + frame_id, + frame, + method_name, + _original_filename, + filename_in_utf8, + lineno, + _applied_mapping, + _show_as_current_frame, + line_col_info, + ) in self._iter_visible_frames_info(py_db, frames_list, flatten_chained=True): # print("file is ", filename_in_utf8) # print("line is ", lineno) # Note: variables are all gotten 'on-demand'. - append('' % (quote(make_valid_xml_value(filename_in_utf8), '/>_= \t'), lineno)) + append('' % (quote(make_valid_xml_value(filename_in_utf8), "/>_= \t"), lineno)) append("") except: pydev_log.exception() - return ''.join(cmd_text_list) + return "".join(cmd_text_list) def make_thread_suspend_str( self, @@ -237,7 +284,7 @@ def make_thread_suspend_str( stop_reason=None, message=None, trace_suspend_type="trace", - ): + ): """ :return tuple(str,str): Returns tuple(thread_suspended_str, thread_stack_str). @@ -264,7 +311,7 @@ def make_thread_suspend_str( cmd_text_list = [] append = cmd_text_list.append - cmd_text_list.append('') + cmd_text_list.append("") if message: message = make_valid_xml_value(message) @@ -275,17 +322,18 @@ def make_thread_suspend_str( append(' message="%s"' % (message,)) if trace_suspend_type is not None: append(' suspend_type="%s"' % (trace_suspend_type,)) - append('>') + append(">") thread_stack_str = self.make_thread_stack_str(py_db, frames_list) append(thread_stack_str) append("") - return ''.join(cmd_text_list), thread_stack_str + return "".join(cmd_text_list), thread_stack_str def make_thread_suspend_message(self, py_db, thread_id, frames_list, stop_reason, message, trace_suspend_type, thread, additional_info): try: thread_suspend_str, thread_stack_str = self.make_thread_suspend_str( - py_db, thread_id, frames_list, stop_reason, message, trace_suspend_type) + py_db, thread_id, frames_list, stop_reason, message, trace_suspend_type + ) cmd = NetCommand(CMD_THREAD_SUSPEND, 0, thread_suspend_str) cmd.thread_stack_str = thread_stack_str cmd.thread_suspend_str = thread_suspend_str @@ -295,15 +343,13 @@ def make_thread_suspend_message(self, py_db, thread_id, frames_list, stop_reason def make_thread_suspend_single_notification(self, py_db, thread_id, thread, stop_reason): try: - return NetCommand(CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, 0, json.dumps( - {'thread_id': thread_id, 'stop_reason':stop_reason})) + return NetCommand(CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, 0, json.dumps({"thread_id": thread_id, "stop_reason": stop_reason})) except: return self.make_error_message(0, get_exception_traceback_str()) def make_thread_resume_single_notification(self, thread_id): try: - return NetCommand(CMD_THREAD_RESUME_SINGLE_NOTIFICATION, 0, json.dumps( - {'thread_id': thread_id})) + return NetCommand(CMD_THREAD_RESUME_SINGLE_NOTIFICATION, 0, json.dumps({"thread_id": thread_id})) except: return self.make_error_message(0, get_exception_traceback_str()) @@ -371,24 +417,26 @@ def make_send_breakpoint_exception_message(self, seq, payload): def _make_send_curr_exception_trace_str(self, py_db, thread_id, exc_type, exc_desc, trace_obj): frames_list = pydevd_frame_utils.create_frames_list_from_traceback(trace_obj, None, exc_type, exc_desc) - exc_type = pydevd_xml.make_valid_xml_value(str(exc_type)).replace('\t', ' ') or 'exception: type unknown' - exc_desc = pydevd_xml.make_valid_xml_value(str(exc_desc)).replace('\t', ' ') or 'exception: no description' + exc_type = pydevd_xml.make_valid_xml_value(str(exc_type)).replace("\t", " ") or "exception: type unknown" + exc_desc = pydevd_xml.make_valid_xml_value(str(exc_desc)).replace("\t", " ") or "exception: no description" thread_suspend_str, thread_stack_str = self.make_thread_suspend_str( - py_db, thread_id, frames_list, CMD_SEND_CURR_EXCEPTION_TRACE, '') + py_db, thread_id, frames_list, CMD_SEND_CURR_EXCEPTION_TRACE, "" + ) return exc_type, exc_desc, thread_suspend_str, thread_stack_str def make_send_curr_exception_trace_message(self, py_db, seq, thread_id, curr_frame_id, exc_type, exc_desc, trace_obj): try: exc_type, exc_desc, thread_suspend_str, _thread_stack_str = self._make_send_curr_exception_trace_str( - py_db, thread_id, exc_type, exc_desc, trace_obj) - payload = str(curr_frame_id) + '\t' + exc_type + "\t" + exc_desc + "\t" + thread_suspend_str + py_db, thread_id, exc_type, exc_desc, trace_obj + ) + payload = str(curr_frame_id) + "\t" + exc_type + "\t" + exc_desc + "\t" + thread_suspend_str return NetCommand(CMD_SEND_CURR_EXCEPTION_TRACE, seq, payload) except Exception: return self.make_error_message(seq, get_exception_traceback_str()) def make_get_exception_details_message(self, py_db, seq, thread_id, topmost_frame): - """Returns exception details as XML """ + """Returns exception details as XML""" try: # If the debugger is not suspended, just return the thread and its id. cmd_text = ['') + cmd_text.append(">") cmd_text.append(thread_stack_str) break frame = frame.f_back else: - cmd_text.append('>') + cmd_text.append(">") finally: frame = None - cmd_text.append('') - return NetCommand(CMD_GET_EXCEPTION_DETAILS, seq, ''.join(cmd_text)) + cmd_text.append("") + return NetCommand(CMD_GET_EXCEPTION_DETAILS, seq, "".join(cmd_text)) except: return self.make_error_message(seq, get_exception_traceback_str()) @@ -445,8 +494,7 @@ def make_load_source_from_frame_id_message(self, seq, source): def make_show_console_message(self, py_db, thread_id, frame): try: frames_list = pydevd_frame_utils.create_frames_list_from_frame(frame) - thread_suspended_str, _thread_stack_str = self.make_thread_suspend_str( - py_db, thread_id, frames_list, CMD_SHOW_CONSOLE, '') + thread_suspended_str, _thread_stack_str = self.make_thread_suspend_str(py_db, thread_id, frames_list, CMD_SHOW_CONSOLE, "") return NetCommand(CMD_SHOW_CONSOLE, 0, thread_suspended_str) except: return self.make_error_message(0, get_exception_traceback_str()) @@ -459,7 +507,7 @@ def make_input_requested_message(self, started): def make_set_next_stmnt_status_message(self, seq, is_success, exception_msg): try: - message = str(is_success) + '\t' + exception_msg + message = str(is_success) + "\t" + exception_msg return NetCommand(CMD_SET_NEXT_STATEMENT, int(seq), message) except: return self.make_error_message(0, get_exception_traceback_str()) @@ -480,7 +528,7 @@ def make_skipped_step_in_because_of_filters(self, py_db, frame): return NULL_NET_COMMAND # Not a part of the xml protocol def make_evaluation_timeout_msg(self, py_db, expression, thread): - msg = '''pydevd: Evaluating: %s did not finish after %.2f seconds. + msg = """pydevd: Evaluating: %s did not finish after %.2f seconds. This may mean a number of things: - This evaluation is really slow and this is expected. In this case it's possible to silence this error by raising the timeout, setting the @@ -498,12 +546,12 @@ def make_evaluation_timeout_msg(self, py_db, expression, thread): environment variable to true so that a thread dump is shown along with this message and optionally, set the PYDEVD_INTERRUPT_THREAD_TIMEOUT to some value so that the debugger tries to interrupt the evaluation (if possible) when this happens. -''' % (expression, pydevd_constants.PYDEVD_WARN_EVALUATION_TIMEOUT) +""" % (expression, pydevd_constants.PYDEVD_WARN_EVALUATION_TIMEOUT) if pydevd_constants.PYDEVD_THREAD_DUMP_ON_WARN_EVALUATION_TIMEOUT: stream = StringIO() pydevd_utils.dump_threads(stream, show_pydevd_threads=False) - msg += '\n\n%s\n' % stream.getvalue() + msg += "\n\n%s\n" % stream.getvalue() return self.make_warning_message(msg) def make_exit_command(self, py_db): diff --git a/_pydevd_bundle/pydevd_plugin_utils.py b/_pydevd_bundle/pydevd_plugin_utils.py index 972b8a344..71b526896 100644 --- a/_pydevd_bundle/pydevd_plugin_utils.py +++ b/_pydevd_bundle/pydevd_plugin_utils.py @@ -2,17 +2,18 @@ from _pydev_bundle import pydev_log from typing import Tuple, Literal + try: from pydevd_plugins import django_debug except: django_debug = None - pydev_log.debug('Unable to load django_debug plugin') + pydev_log.debug("Unable to load django_debug plugin") try: from pydevd_plugins import jinja2_debug except: jinja2_debug = None - pydev_log.debug('Unable to load jinja2_debug plugin') + pydev_log.debug("Unable to load jinja2_debug plugin") def load_plugins(): @@ -33,7 +34,6 @@ def bind_func_to_method(func, obj, method_name): class PluginManager(object): - EMPTY_SENTINEL = object() def __init__(self, main_debugger): @@ -70,9 +70,9 @@ def after_breakpoints_consolidated(self, py_db, canonical_normalized_filename, i plugin.after_breakpoints_consolidated(py_db, canonical_normalized_filename, id_to_pybreakpoint, file_to_line_to_breakpoints) def remove_exception_breakpoint(self, py_db, exception_type, exception): - ''' + """ :param exception_type: 'django', 'jinja2' (can be extended) - ''' + """ for plugin in self.active_plugins: ret = plugin.remove_exception_breakpoint(py_db, exception_type, exception) if ret: @@ -85,9 +85,9 @@ def remove_all_exception_breakpoints(self, py_db): plugin.remove_all_exception_breakpoints(py_db) def get_breakpoints(self, py_db, breakpoint_type): - ''' + """ :param breakpoint_type: 'django-line', 'jinja2-line' - ''' + """ for plugin in self.active_plugins: ret = plugin.get_breakpoints(py_db, breakpoint_type) if ret: @@ -99,7 +99,7 @@ def can_skip(self, py_db, frame): return False return True - def required_events_breakpoint(self) -> Tuple[Literal['line', 'call'], ...]: + def required_events_breakpoint(self) -> Tuple[Literal["line", "call"], ...]: ret = () for plugin in self.active_plugins: new = plugin.required_events_breakpoint() @@ -108,7 +108,7 @@ def required_events_breakpoint(self) -> Tuple[Literal['line', 'call'], ...]: return ret - def required_events_stepping(self) -> Tuple[Literal['line', 'call', 'return'], ...]: + def required_events_stepping(self) -> Tuple[Literal["line", "call", "return"], ...]: ret = () for plugin in self.active_plugins: new = plugin.required_events_stepping() @@ -136,13 +136,13 @@ def has_line_breaks(self, py_db) -> bool: return False def cmd_step_into(self, py_db, frame, event, info, thread, stop_info, stop: bool): - ''' + """ :param stop_info: in/out information. If it should stop then it'll be filled by the plugin. :param stop: whether the stop has already been flagged for this frame. :returns: tuple(stop, plugin_stop) - ''' + """ plugin_stop = False for plugin in self.active_plugins: stop, plugin_stop = plugin.cmd_step_into(py_db, frame, event, info, thread, stop_info, stop) @@ -159,11 +159,11 @@ def cmd_step_over(self, py_db, frame, event, info, thread, stop_info, stop): return stop, plugin_stop def stop(self, py_db, frame, event, thread, stop_info, arg, step_cmd): - ''' + """ The way this works is that the `cmd_step_into` or `cmd_step_over` is called which then fills the `stop_info` and then this method is called to do the actual stop. - ''' + """ for plugin in self.active_plugins: stopped = plugin.stop(py_db, frame, event, thread, stop_info, arg, step_cmd) if stopped: @@ -178,12 +178,12 @@ def get_breakpoint(self, py_db, frame, event, info): return None def suspend(self, py_db, thread, frame, bp_type): - ''' + """ :param bp_type: 'django' or 'jinja2' :return: The frame for the suspend or None if it should not be suspended. - ''' + """ for plugin in self.active_plugins: ret = plugin.suspend(py_db, thread, frame, bp_type) if ret is not None: @@ -206,4 +206,3 @@ def change_variable(self, frame, attr, expression): return ret return self.EMPTY_SENTINEL - diff --git a/_pydevd_bundle/pydevd_process_net_command.py b/_pydevd_bundle/pydevd_process_net_command.py index 046048411..92902ed2f 100644 --- a/_pydevd_bundle/pydevd_process_net_command.py +++ b/_pydevd_bundle/pydevd_process_net_command.py @@ -9,8 +9,12 @@ from _pydevd_bundle.pydevd_additional_thread_info import set_additional_thread_info from _pydevd_bundle.pydevd_breakpoints import get_exception_class from _pydevd_bundle.pydevd_comm import ( - InternalEvaluateConsoleExpression, InternalConsoleGetCompletions, InternalRunCustomOperation, - internal_get_next_statement_targets, internal_get_smart_step_into_variants) + InternalEvaluateConsoleExpression, + InternalConsoleGetCompletions, + InternalRunCustomOperation, + internal_get_next_statement_targets, + internal_get_smart_step_into_variants, +) from _pydevd_bundle.pydevd_constants import NEXT_VALUE_SEPARATOR, IS_WINDOWS, NULL from _pydevd_bundle.pydevd_comm_constants import ID_TO_MEANING, CMD_EXEC_EXPRESSION, CMD_AUTHENTICATE from _pydevd_bundle.pydevd_api import PyDevdAPI @@ -21,22 +25,21 @@ class _PyDevCommandProcessor(object): - def __init__(self): self.api = PyDevdAPI() def process_net_command(self, py_db, cmd_id, seq, text): - '''Processes a command received from the Java side + """Processes a command received from the Java side @param cmd_id: the id of the command @param seq: the sequence of the command @param text: the text received in the command - ''' + """ # We can only proceed if the client is already authenticated or if it's the # command to authenticate. if cmd_id != CMD_AUTHENTICATE and not py_db.authentication.is_authenticated(): - cmd = py_db.cmd_factory.make_error_message(seq, 'Client not authenticated.') + cmd = py_db.cmd_factory.make_error_message(seq, "Client not authenticated.") py_db.writer.add_command(cmd) return @@ -54,7 +57,7 @@ def process_net_command(self, py_db, cmd_id, seq, text): return lock = py_db._main_lock - if method_name == 'cmd_thread_dump_to_stderr': + if method_name == "cmd_thread_dump_to_stderr": # We can skip the main debugger locks for cases where we know it's not needed. lock = NULL @@ -71,9 +74,8 @@ def process_net_command(self, py_db, cmd_id, seq, text): traceback.print_exc(file=stream) cmd = py_db.cmd_factory.make_error_message( seq, - "Unexpected exception in process_net_command.\nInitial params: %s. Exception: %s" % ( - ((cmd_id, seq, text), stream.getvalue()) - ) + "Unexpected exception in process_net_command.\nInitial params: %s. Exception: %s" + % (((cmd_id, seq, text), stream.getvalue())), ) if cmd is not None: py_db.writer.add_command(cmd) @@ -84,7 +86,7 @@ def cmd_authenticate(self, py_db, cmd_id, seq, text): if py_db.authentication.is_authenticated(): return NetCommand(cmd_id, seq, py_db.authentication.client_access_token) - return py_db.cmd_factory.make_error_message(seq, 'Client not authenticated.') + return py_db.cmd_factory.make_error_message(seq, "Client not authenticated.") def cmd_run(self, py_db, cmd_id, seq, text): return self.api.run(py_db) @@ -95,19 +97,19 @@ def cmd_list_threads(self, py_db, cmd_id, seq, text): def cmd_get_completions(self, py_db, cmd_id, seq, text): # we received some command to get a variable # the text is: thread_id\tframe_id\tactivation token - thread_id, frame_id, _scope, act_tok = text.split('\t', 3) + thread_id, frame_id, _scope, act_tok = text.split("\t", 3) return self.api.request_completions(py_db, seq, thread_id, frame_id, act_tok) def cmd_get_thread_stack(self, py_db, cmd_id, seq, text): # Receives a thread_id and a given timeout, which is the time we should # wait to the provide the stack if a given thread is still not suspended. - if '\t' in text: - thread_id, timeout = text.split('\t') + if "\t" in text: + thread_id, timeout = text.split("\t") timeout = float(timeout) else: thread_id = text - timeout = .5 # Default timeout is .5 seconds + timeout = 0.5 # Default timeout is .5 seconds return self.api.request_stack(py_db, seq, thread_id, fmt={}, timeout=timeout) @@ -121,14 +123,14 @@ def cmd_version(self, py_db, cmd_id, seq, text): # Default based on server process (although ideally the IDE should # provide it). if IS_WINDOWS: - ide_os = 'WINDOWS' + ide_os = "WINDOWS" else: - ide_os = 'UNIX' + ide_os = "UNIX" # Breakpoints can be grouped by 'LINE' or by 'ID'. - breakpoints_by = 'LINE' + breakpoints_by = "LINE" - splitted = text.split('\t') + splitted = text.split("\t") if len(splitted) == 1: _local_version = splitted @@ -159,23 +161,23 @@ def _cmd_step(self, py_db, cmd_id, seq, text): cmd_step_return_my_code = _cmd_step def _cmd_set_next(self, py_db, cmd_id, seq, text): - thread_id, line, func_name = text.split('\t', 2) + thread_id, line, func_name = text.split("\t", 2) return self.api.request_set_next(py_db, seq, thread_id, cmd_id, None, line, func_name) cmd_run_to_line = _cmd_set_next cmd_set_next_statement = _cmd_set_next def cmd_smart_step_into(self, py_db, cmd_id, seq, text): - thread_id, line_or_bytecode_offset, func_name = text.split('\t', 2) - if line_or_bytecode_offset.startswith('offset='): + thread_id, line_or_bytecode_offset, func_name = text.split("\t", 2) + if line_or_bytecode_offset.startswith("offset="): # In this case we request the smart step into to stop given the parent frame # and the location of the parent frame bytecode offset and not just the func_name # (this implies that `CMD_GET_SMART_STEP_INTO_VARIANTS` was previously used # to know what are the valid stop points). - temp = line_or_bytecode_offset[len('offset='):] - if ';' in temp: - offset, child_offset = temp.split(';') + temp = line_or_bytecode_offset[len("offset=") :] + if ";" in temp: + offset, child_offset = temp.split(";") offset = int(offset) child_offset = int(child_offset) else: @@ -188,29 +190,29 @@ def cmd_smart_step_into(self, py_db, cmd_id, seq, text): def cmd_reload_code(self, py_db, cmd_id, seq, text): text = text.strip() - if '\t' not in text: + if "\t" not in text: module_name = text.strip() filename = None else: - module_name, filename = text.split('\t', 1) + module_name, filename = text.split("\t", 1) self.api.request_reload_code(py_db, seq, module_name, filename) def cmd_change_variable(self, py_db, cmd_id, seq, text): # the text is: thread\tstackframe\tFRAME|GLOBAL\tattribute_to_change\tvalue_to_change - thread_id, frame_id, scope, attr_and_value = text.split('\t', 3) + thread_id, frame_id, scope, attr_and_value = text.split("\t", 3) - tab_index = attr_and_value.rindex('\t') - attr = attr_and_value[0:tab_index].replace('\t', '.') - value = attr_and_value[tab_index + 1:] + tab_index = attr_and_value.rindex("\t") + attr = attr_and_value[0:tab_index].replace("\t", ".") + value = attr_and_value[tab_index + 1 :] self.api.request_change_variable(py_db, seq, thread_id, frame_id, scope, attr, value) def cmd_get_variable(self, py_db, cmd_id, seq, text): # we received some command to get a variable # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tattributes* - thread_id, frame_id, scopeattrs = text.split('\t', 2) + thread_id, frame_id, scopeattrs = text.split("\t", 2) - if scopeattrs.find('\t') != -1: # there are attributes beyond scope - scope, attrs = scopeattrs.split('\t', 1) + if scopeattrs.find("\t") != -1: # there are attributes beyond scope + scope, attrs = scopeattrs.split("\t", 1) else: scope, attrs = (scopeattrs, None) @@ -220,84 +222,91 @@ def cmd_get_array(self, py_db, cmd_id, seq, text): # Note: untested and unused in pydev # we received some command to get an array variable # the text is: thread_id\tframe_id\tFRAME|GLOBAL\tname\ttemp\troffs\tcoffs\trows\tcols\tformat - roffset, coffset, rows, cols, format, thread_id, frame_id, scopeattrs = text.split('\t', 7) + roffset, coffset, rows, cols, format, thread_id, frame_id, scopeattrs = text.split("\t", 7) - if scopeattrs.find('\t') != -1: # there are attributes beyond scope - scope, attrs = scopeattrs.split('\t', 1) + if scopeattrs.find("\t") != -1: # there are attributes beyond scope + scope, attrs = scopeattrs.split("\t", 1) else: scope, attrs = (scopeattrs, None) self.api.request_get_array(py_db, seq, roffset, coffset, rows, cols, format, thread_id, frame_id, scope, attrs) def cmd_show_return_values(self, py_db, cmd_id, seq, text): - show_return_values = text.split('\t')[1] + show_return_values = text.split("\t")[1] self.api.set_show_return_values(py_db, int(show_return_values) == 1) def cmd_load_full_value(self, py_db, cmd_id, seq, text): # Note: untested and unused in pydev - thread_id, frame_id, scopeattrs = text.split('\t', 2) + thread_id, frame_id, scopeattrs = text.split("\t", 2) vars = scopeattrs.split(NEXT_VALUE_SEPARATOR) self.api.request_load_full_value(py_db, seq, thread_id, frame_id, vars) def cmd_get_description(self, py_db, cmd_id, seq, text): # Note: untested and unused in pydev - thread_id, frame_id, expression = text.split('\t', 2) + thread_id, frame_id, expression = text.split("\t", 2) self.api.request_get_description(py_db, seq, thread_id, frame_id, expression) def cmd_get_frame(self, py_db, cmd_id, seq, text): - thread_id, frame_id, scope = text.split('\t', 2) + thread_id, frame_id, scope = text.split("\t", 2) self.api.request_get_frame(py_db, seq, thread_id, frame_id) def cmd_set_break(self, py_db, cmd_id, seq, text): # func name: 'None': match anything. Empty: match global, specified: only method context. # command to add some breakpoint. # text is filename\tline. Add to breakpoints dictionary - suspend_policy = u"NONE" # Can be 'NONE' or 'ALL' + suspend_policy = "NONE" # Can be 'NONE' or 'ALL' is_logpoint = False hit_condition = None if py_db._set_breakpoints_with_id: try: try: - breakpoint_id, btype, filename, line, func_name, condition, expression, hit_condition, is_logpoint, suspend_policy = text.split(u'\t', 9) + ( + breakpoint_id, + btype, + filename, + line, + func_name, + condition, + expression, + hit_condition, + is_logpoint, + suspend_policy, + ) = text.split("\t", 9) except ValueError: # not enough values to unpack # No suspend_policy passed (use default). - breakpoint_id, btype, filename, line, func_name, condition, expression, hit_condition, is_logpoint = text.split(u'\t', 8) - is_logpoint = is_logpoint == u'True' + breakpoint_id, btype, filename, line, func_name, condition, expression, hit_condition, is_logpoint = text.split("\t", 8) + is_logpoint = is_logpoint == "True" except ValueError: # not enough values to unpack - breakpoint_id, btype, filename, line, func_name, condition, expression = text.split(u'\t', 6) + breakpoint_id, btype, filename, line, func_name, condition, expression = text.split("\t", 6) breakpoint_id = int(breakpoint_id) line = int(line) # We must restore new lines and tabs as done in # AbstractDebugTarget.breakpointAdded - condition = condition.replace(u"@_@NEW_LINE_CHAR@_@", u'\n').\ - replace(u"@_@TAB_CHAR@_@", u'\t').strip() + condition = condition.replace("@_@NEW_LINE_CHAR@_@", "\n").replace("@_@TAB_CHAR@_@", "\t").strip() - expression = expression.replace(u"@_@NEW_LINE_CHAR@_@", u'\n').\ - replace(u"@_@TAB_CHAR@_@", u'\t').strip() + expression = expression.replace("@_@NEW_LINE_CHAR@_@", "\n").replace("@_@TAB_CHAR@_@", "\t").strip() else: # Note: this else should be removed after PyCharm migrates to setting # breakpoints by id (and ideally also provides func_name). - btype, filename, line, func_name, suspend_policy, condition, expression = text.split(u'\t', 6) + btype, filename, line, func_name, suspend_policy, condition, expression = text.split("\t", 6) # If we don't have an id given for each breakpoint, consider # the id to be the line. breakpoint_id = line = int(line) - condition = condition.replace(u"@_@NEW_LINE_CHAR@_@", u'\n'). \ - replace(u"@_@TAB_CHAR@_@", u'\t').strip() + condition = condition.replace("@_@NEW_LINE_CHAR@_@", "\n").replace("@_@TAB_CHAR@_@", "\t").strip() - expression = expression.replace(u"@_@NEW_LINE_CHAR@_@", u'\n'). \ - replace(u"@_@TAB_CHAR@_@", u'\t').strip() + expression = expression.replace("@_@NEW_LINE_CHAR@_@", "\n").replace("@_@TAB_CHAR@_@", "\t").strip() - if condition is not None and (len(condition) <= 0 or condition == u"None"): + if condition is not None and (len(condition) <= 0 or condition == "None"): condition = None - if expression is not None and (len(expression) <= 0 or expression == u"None"): + if expression is not None and (len(expression) <= 0 or expression == "None"): expression = None - if hit_condition is not None and (len(hit_condition) <= 0 or hit_condition == u"None"): + if hit_condition is not None and (len(hit_condition) <= 0 or hit_condition == "None"): hit_condition = None def on_changed_breakpoint_state(breakpoint_id, add_breakpoint_result): @@ -305,49 +314,73 @@ def on_changed_breakpoint_state(breakpoint_id, add_breakpoint_result): translated_line = add_breakpoint_result.translated_line translated_filename = add_breakpoint_result.translated_filename - msg = '' + msg = "" if error_code: - if error_code == self.api.ADD_BREAKPOINT_FILE_NOT_FOUND: - msg = 'pydev debugger: Trying to add breakpoint to file that does not exist: %s (will have no effect).\n' % (translated_filename,) + msg = "pydev debugger: Trying to add breakpoint to file that does not exist: %s (will have no effect).\n" % ( + translated_filename, + ) elif error_code == self.api.ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS: - msg = 'pydev debugger: Trying to add breakpoint to file that is excluded by filters: %s (will have no effect).\n' % (translated_filename,) + msg = "pydev debugger: Trying to add breakpoint to file that is excluded by filters: %s (will have no effect).\n" % ( + translated_filename, + ) elif error_code == self.api.ADD_BREAKPOINT_LAZY_VALIDATION: - msg = '' # Ignore this here (if/when loaded, it'll call on_changed_breakpoint_state again accordingly). + msg = "" # Ignore this here (if/when loaded, it'll call on_changed_breakpoint_state again accordingly). elif error_code == self.api.ADD_BREAKPOINT_INVALID_LINE: - msg = 'pydev debugger: Trying to add breakpoint to line (%s) that is not valid in: %s.\n' % (translated_line, translated_filename,) + msg = "pydev debugger: Trying to add breakpoint to line (%s) that is not valid in: %s.\n" % ( + translated_line, + translated_filename, + ) else: # Shouldn't get here. - msg = 'pydev debugger: Breakpoint not validated (reason unknown -- please report as error): %s (%s).\n' % (translated_filename, translated_line) + msg = "pydev debugger: Breakpoint not validated (reason unknown -- please report as error): %s (%s).\n" % ( + translated_filename, + translated_line, + ) else: if add_breakpoint_result.original_line != translated_line: - msg = 'pydev debugger (info): Breakpoint in line: %s moved to line: %s (in %s).\n' % (add_breakpoint_result.original_line, translated_line, translated_filename) + msg = "pydev debugger (info): Breakpoint in line: %s moved to line: %s (in %s).\n" % ( + add_breakpoint_result.original_line, + translated_line, + translated_filename, + ) if msg: py_db.writer.add_command(py_db.cmd_factory.make_warning_message(msg)) result = self.api.add_breakpoint( - py_db, self.api.filename_to_str(filename), btype, breakpoint_id, line, condition, func_name, - expression, suspend_policy, hit_condition, is_logpoint, on_changed_breakpoint_state=on_changed_breakpoint_state) + py_db, + self.api.filename_to_str(filename), + btype, + breakpoint_id, + line, + condition, + func_name, + expression, + suspend_policy, + hit_condition, + is_logpoint, + on_changed_breakpoint_state=on_changed_breakpoint_state, + ) on_changed_breakpoint_state(breakpoint_id, result) def cmd_remove_break(self, py_db, cmd_id, seq, text): # command to remove some breakpoint # text is type\file\tid. Remove from breakpoints dictionary - breakpoint_type, filename, breakpoint_id = text.split('\t', 2) + breakpoint_type, filename, breakpoint_id = text.split("\t", 2) filename = self.api.filename_to_str(filename) try: breakpoint_id = int(breakpoint_id) except ValueError: - pydev_log.critical('Error removing breakpoint. Expected breakpoint_id to be an int. Found: %s', breakpoint_id) + pydev_log.critical("Error removing breakpoint. Expected breakpoint_id to be an int. Found: %s", breakpoint_id) else: self.api.remove_breakpoint(py_db, filename, breakpoint_type, breakpoint_id) @@ -357,14 +390,13 @@ def _cmd_exec_or_evaluate_expression(self, py_db, cmd_id, seq, text): # text is: thread\tstackframe\tLOCAL\texpression attr_to_set_result = "" try: - thread_id, frame_id, scope, expression, trim, attr_to_set_result = text.split('\t', 5) + thread_id, frame_id, scope, expression, trim, attr_to_set_result = text.split("\t", 5) except ValueError: - thread_id, frame_id, scope, expression, trim = text.split('\t', 4) + thread_id, frame_id, scope, expression, trim = text.split("\t", 4) is_exec = cmd_id == CMD_EXEC_EXPRESSION trim_if_too_big = int(trim) == 1 - self.api.request_exec_or_evaluate( - py_db, seq, thread_id, frame_id, expression, is_exec, trim_if_too_big, attr_to_set_result) + self.api.request_exec_or_evaluate(py_db, seq, thread_id, frame_id, expression, is_exec, trim_if_too_big, attr_to_set_result) cmd_evaluate_expression = _cmd_exec_or_evaluate_expression cmd_exec_expression = _cmd_exec_or_evaluate_expression @@ -373,11 +405,11 @@ def cmd_console_exec(self, py_db, cmd_id, seq, text): # command to exec expression in console, in case expression is only partially valid 'False' is returned # text is: thread\tstackframe\tLOCAL\texpression - thread_id, frame_id, scope, expression = text.split('\t', 3) + thread_id, frame_id, scope, expression = text.split("\t", 3) self.api.request_console_exec(py_db, seq, thread_id, frame_id, expression) def cmd_set_path_mapping_json(self, py_db, cmd_id, seq, text): - ''' + """ :param text: Json text. Something as: @@ -391,21 +423,21 @@ def cmd_set_path_mapping_json(self, py_db, cmd_id, seq, text): "debug": true, "force": false } - ''' + """ as_json = json.loads(text) - force = as_json.get('force', False) + force = as_json.get("force", False) path_mappings = [] - for pathMapping in as_json.get('pathMappings', []): - localRoot = pathMapping.get('localRoot', '') - remoteRoot = pathMapping.get('remoteRoot', '') - if (localRoot != '') and (remoteRoot != ''): + for pathMapping in as_json.get("pathMappings", []): + localRoot = pathMapping.get("localRoot", "") + remoteRoot = pathMapping.get("remoteRoot", "") + if (localRoot != "") and (remoteRoot != ""): path_mappings.append((localRoot, remoteRoot)) if bool(path_mappings) or force: pydevd_file_utils.setup_client_server_paths(path_mappings) - debug = as_json.get('debug', False) + debug = as_json.get("debug", False) if debug or force: pydevd_file_utils.DEBUG_CLIENT_SERVER_TRANSLATION = debug @@ -423,13 +455,15 @@ def cmd_set_py_exception_json(self, py_db, cmd_id, seq, text): py_db.break_on_user_uncaught_exceptions = {} as_json = json.loads(text) - break_on_uncaught = as_json.get('break_on_uncaught', False) - break_on_caught = as_json.get('break_on_caught', False) - break_on_user_caught = as_json.get('break_on_user_caught', False) - py_db.skip_on_exceptions_thrown_in_same_context = as_json.get('skip_on_exceptions_thrown_in_same_context', False) - py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = as_json.get('ignore_exceptions_thrown_in_lines_with_ignore_exception', False) - ignore_libraries = as_json.get('ignore_libraries', False) - exception_types = as_json.get('exception_types', []) + break_on_uncaught = as_json.get("break_on_uncaught", False) + break_on_caught = as_json.get("break_on_caught", False) + break_on_user_caught = as_json.get("break_on_user_caught", False) + py_db.skip_on_exceptions_thrown_in_same_context = as_json.get("skip_on_exceptions_thrown_in_same_context", False) + py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = as_json.get( + "ignore_exceptions_thrown_in_lines_with_ignore_exception", False + ) + ignore_libraries = as_json.get("ignore_libraries", False) + exception_types = as_json.get("exception_types", []) for exception_type in exception_types: if not exception_type: @@ -453,32 +487,32 @@ def cmd_set_py_exception_json(self, py_db, cmd_id, seq, text): def cmd_set_py_exception(self, py_db, cmd_id, seq, text): # DEPRECATED. Use cmd_set_py_exception_json instead. try: - splitted = text.split(';') + splitted = text.split(";") py_db.break_on_uncaught_exceptions = {} py_db.break_on_caught_exceptions = {} py_db.break_on_user_uncaught_exceptions = {} if len(splitted) >= 5: - if splitted[0] == 'true': + if splitted[0] == "true": break_on_uncaught = True else: break_on_uncaught = False - if splitted[1] == 'true': + if splitted[1] == "true": break_on_caught = True else: break_on_caught = False - if splitted[2] == 'true': + if splitted[2] == "true": py_db.skip_on_exceptions_thrown_in_same_context = True else: py_db.skip_on_exceptions_thrown_in_same_context = False - if splitted[3] == 'true': + if splitted[3] == "true": py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = True else: py_db.ignore_exceptions_thrown_in_lines_with_ignore_exception = False - if splitted[4] == 'true': + if splitted[4] == "true": ignore_libraries = True else: ignore_libraries = False @@ -520,24 +554,24 @@ def cmd_set_property_trace(self, py_db, cmd_id, seq, text): # Command which receives whether to trace property getter/setter/deleter # text is feature_state(true/false);disable_getter/disable_setter/disable_deleter if text: - splitted = text.split(';') + splitted = text.split(";") if len(splitted) >= 3: - if not py_db.disable_property_trace and splitted[0] == 'true': + if not py_db.disable_property_trace and splitted[0] == "true": # Replacing property by custom property only when the debugger starts pydevd_traceproperty.replace_builtin_property() py_db.disable_property_trace = True # Enable/Disable tracing of the property getter - if splitted[1] == 'true': + if splitted[1] == "true": py_db.disable_property_getter_trace = True else: py_db.disable_property_getter_trace = False # Enable/Disable tracing of the property setter - if splitted[2] == 'true': + if splitted[2] == "true": py_db.disable_property_setter_trace = True else: py_db.disable_property_setter_trace = False # Enable/Disable tracing of the property deleter - if splitted[3] == 'true': + if splitted[3] == "true": py_db.disable_property_deleter_trace = True else: py_db.disable_property_deleter_trace = False @@ -565,32 +599,42 @@ def cmd_add_exception_break(self, py_db, cmd_id, seq, text): condition = "" expression = "" - if text.find('\t') != -1: + if text.find("\t") != -1: try: - exception, condition, expression, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text.split('\t', 5) + ( + exception, + condition, + expression, + notify_on_handled_exceptions, + notify_on_unhandled_exceptions, + ignore_libraries, + ) = text.split("\t", 5) except: - exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text.split('\t', 3) + exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text.split("\t", 3) else: exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries = text, 0, 0, 0 - condition = condition.replace("@_@NEW_LINE_CHAR@_@", '\n').replace("@_@TAB_CHAR@_@", '\t').strip() + condition = condition.replace("@_@NEW_LINE_CHAR@_@", "\n").replace("@_@TAB_CHAR@_@", "\t").strip() if condition is not None and (len(condition) == 0 or condition == "None"): condition = None - expression = expression.replace("@_@NEW_LINE_CHAR@_@", '\n').replace("@_@TAB_CHAR@_@", '\t').strip() + expression = expression.replace("@_@NEW_LINE_CHAR@_@", "\n").replace("@_@TAB_CHAR@_@", "\t").strip() if expression is not None and (len(expression) == 0 or expression == "None"): expression = None - if exception.find('-') != -1: - breakpoint_type, exception = exception.split('-') + if exception.find("-") != -1: + breakpoint_type, exception = exception.split("-") else: - breakpoint_type = 'python' + breakpoint_type = "python" - if breakpoint_type == 'python': + if breakpoint_type == "python": self.api.add_python_exception_breakpoint( - py_db, exception, condition, expression, + py_db, + exception, + condition, + expression, notify_on_handled_exceptions=int(notify_on_handled_exceptions) > 0, notify_on_unhandled_exceptions=int(notify_on_unhandled_exceptions) == 1, notify_on_user_unhandled_exceptions=0, # TODO (not currently supported in this API). @@ -602,41 +646,39 @@ def cmd_add_exception_break(self, py_db, cmd_id, seq, text): def cmd_remove_exception_break(self, py_db, cmd_id, seq, text): exception = text - if exception.find('-') != -1: - exception_type, exception = exception.split('-') + if exception.find("-") != -1: + exception_type, exception = exception.split("-") else: - exception_type = 'python' + exception_type = "python" - if exception_type == 'python': + if exception_type == "python": self.api.remove_python_exception_breakpoint(py_db, exception) else: self.api.remove_plugins_exception_breakpoint(py_db, exception_type, exception) def cmd_add_django_exception_break(self, py_db, cmd_id, seq, text): - self.api.add_plugins_exception_breakpoint(py_db, breakpoint_type='django', exception=text) + self.api.add_plugins_exception_breakpoint(py_db, breakpoint_type="django", exception=text) def cmd_remove_django_exception_break(self, py_db, cmd_id, seq, text): - self.api.remove_plugins_exception_breakpoint(py_db, exception_type='django', exception=text) + self.api.remove_plugins_exception_breakpoint(py_db, exception_type="django", exception=text) def cmd_evaluate_console_expression(self, py_db, cmd_id, seq, text): # Command which takes care for the debug console communication if text != "": - thread_id, frame_id, console_command = text.split('\t', 2) - console_command, line = console_command.split('\t') + thread_id, frame_id, console_command = text.split("\t", 2) + console_command, line = console_command.split("\t") - if console_command == 'EVALUATE': - int_cmd = InternalEvaluateConsoleExpression( - seq, thread_id, frame_id, line, buffer_output=True) + if console_command == "EVALUATE": + int_cmd = InternalEvaluateConsoleExpression(seq, thread_id, frame_id, line, buffer_output=True) - elif console_command == 'EVALUATE_UNBUFFERED': - int_cmd = InternalEvaluateConsoleExpression( - seq, thread_id, frame_id, line, buffer_output=False) + elif console_command == "EVALUATE_UNBUFFERED": + int_cmd = InternalEvaluateConsoleExpression(seq, thread_id, frame_id, line, buffer_output=False) - elif console_command == 'GET_COMPLETIONS': + elif console_command == "GET_COMPLETIONS": int_cmd = InternalConsoleGetCompletions(seq, thread_id, frame_id, line) else: - raise ValueError('Unrecognized command: %s' % (console_command,)) + raise ValueError("Unrecognized command: %s" % (console_command,)) py_db.post_internal_command(int_cmd, thread_id) @@ -644,36 +686,35 @@ def cmd_run_custom_operation(self, py_db, cmd_id, seq, text): # Command which runs a custom operation if text != "": try: - location, custom = text.split('||', 1) + location, custom = text.split("||", 1) except: - sys.stderr.write('Custom operation now needs a || separator. Found: %s\n' % (text,)) + sys.stderr.write("Custom operation now needs a || separator. Found: %s\n" % (text,)) raise - thread_id, frame_id, scopeattrs = location.split('\t', 2) + thread_id, frame_id, scopeattrs = location.split("\t", 2) - if scopeattrs.find('\t') != -1: # there are attributes beyond scope - scope, attrs = scopeattrs.split('\t', 1) + if scopeattrs.find("\t") != -1: # there are attributes beyond scope + scope, attrs = scopeattrs.split("\t", 1) else: scope, attrs = (scopeattrs, None) # : style: EXECFILE or EXEC # : encoded_code_or_file: file to execute or code # : fname: name of function to be executed in the resulting namespace - style, encoded_code_or_file, fnname = custom.split('\t', 3) - int_cmd = InternalRunCustomOperation(seq, thread_id, frame_id, scope, attrs, - style, encoded_code_or_file, fnname) + style, encoded_code_or_file, fnname = custom.split("\t", 3) + int_cmd = InternalRunCustomOperation(seq, thread_id, frame_id, scope, attrs, style, encoded_code_or_file, fnname) py_db.post_internal_command(int_cmd, thread_id) def cmd_ignore_thrown_exception_at(self, py_db, cmd_id, seq, text): if text: - replace = 'REPLACE:' # Not all 3.x versions support u'REPLACE:', so, doing workaround. + replace = "REPLACE:" # Not all 3.x versions support u'REPLACE:', so, doing workaround. if text.startswith(replace): text = text[8:] py_db.filename_to_lines_where_exceptions_are_ignored.clear() if text: - for line in text.split('||'): # Can be bulk-created (one in each line) - original_filename, line_number = line.split('|') + for line in text.split("||"): # Can be bulk-created (one in each line) + original_filename, line_number = line.split("|") original_filename = self.api.filename_to_server(original_filename) canonical_normalized_filename = pydevd_file_utils.canonical_normalized_path(original_filename) @@ -685,39 +726,48 @@ def cmd_ignore_thrown_exception_at(self, py_db, cmd_id, seq, text): lines_ignored = py_db.filename_to_lines_where_exceptions_are_ignored[canonical_normalized_filename] = {} lines_ignored[int(line_number)] = 1 else: - sys.stderr.write('pydev debugger: warning: trying to ignore exception thrown'\ - ' on file that does not exist: %s (will have no effect)\n' % (absolute_filename,)) + sys.stderr.write( + "pydev debugger: warning: trying to ignore exception thrown" + " on file that does not exist: %s (will have no effect)\n" % (absolute_filename,) + ) def cmd_enable_dont_trace(self, py_db, cmd_id, seq, text): if text: - true_str = 'true' # Not all 3.x versions support u'str', so, doing workaround. + true_str = "true" # Not all 3.x versions support u'str', so, doing workaround. mode = text.strip() == true_str pydevd_dont_trace.trace_filter(mode) def cmd_redirect_output(self, py_db, cmd_id, seq, text): if text: - py_db.enable_output_redirection('STDOUT' in text, 'STDERR' in text) + py_db.enable_output_redirection("STDOUT" in text, "STDERR" in text) def cmd_get_next_statement_targets(self, py_db, cmd_id, seq, text): - thread_id, frame_id = text.split('\t', 1) + thread_id, frame_id = text.split("\t", 1) - py_db.post_method_as_internal_command( - thread_id, internal_get_next_statement_targets, seq, thread_id, frame_id) + py_db.post_method_as_internal_command(thread_id, internal_get_next_statement_targets, seq, thread_id, frame_id) def cmd_get_smart_step_into_variants(self, py_db, cmd_id, seq, text): - thread_id, frame_id, start_line, end_line = text.split('\t', 3) + thread_id, frame_id, start_line, end_line = text.split("\t", 3) py_db.post_method_as_internal_command( - thread_id, internal_get_smart_step_into_variants, seq, thread_id, frame_id, start_line, end_line, set_additional_thread_info=set_additional_thread_info) + thread_id, + internal_get_smart_step_into_variants, + seq, + thread_id, + frame_id, + start_line, + end_line, + set_additional_thread_info=set_additional_thread_info, + ) def cmd_set_project_roots(self, py_db, cmd_id, seq, text): - self.api.set_project_roots(py_db, text.split(u'\t')) + self.api.set_project_roots(py_db, text.split("\t")) def cmd_thread_dump_to_stderr(self, py_db, cmd_id, seq, text): pydevd_utils.dump_threads() def cmd_stop_on_start(self, py_db, cmd_id, seq, text): - if text.strip() in ('True', 'true', '1'): + if text.strip() in ("True", "true", "1"): self.api.stop_on_entry() def cmd_pydevd_json_config(self, py_db, cmd_id, seq, text): @@ -728,22 +778,20 @@ def cmd_pydevd_json_config(self, py_db, cmd_id, seq, text): # 'multi_threads_single_notification': bool, # } msg = json.loads(text.strip()) - if 'skip_suspend_on_breakpoint_exception' in msg: - py_db.skip_suspend_on_breakpoint_exception = tuple( - get_exception_class(x) for x in msg['skip_suspend_on_breakpoint_exception']) + if "skip_suspend_on_breakpoint_exception" in msg: + py_db.skip_suspend_on_breakpoint_exception = tuple(get_exception_class(x) for x in msg["skip_suspend_on_breakpoint_exception"]) - if 'skip_print_breakpoint_exception' in msg: - py_db.skip_print_breakpoint_exception = tuple( - get_exception_class(x) for x in msg['skip_print_breakpoint_exception']) + if "skip_print_breakpoint_exception" in msg: + py_db.skip_print_breakpoint_exception = tuple(get_exception_class(x) for x in msg["skip_print_breakpoint_exception"]) - if 'multi_threads_single_notification' in msg: - py_db.multi_threads_single_notification = msg['multi_threads_single_notification'] + if "multi_threads_single_notification" in msg: + py_db.multi_threads_single_notification = msg["multi_threads_single_notification"] def cmd_get_exception_details(self, py_db, cmd_id, seq, text): thread_id = text t = pydevd_find_thread_by_id(thread_id) frame = None - if t is not None and not getattr(t, 'pydev_do_not_trace', None): + if t is not None and not getattr(t, "pydev_do_not_trace", None): additional_info = set_additional_thread_info(t) frame = additional_info.get_topmost_frame(t) try: @@ -755,4 +803,3 @@ def cmd_get_exception_details(self, py_db, cmd_id, seq, text): process_net_command = _PyDevCommandProcessor().process_net_command - diff --git a/_pydevd_bundle/pydevd_process_net_command_json.py b/_pydevd_bundle/pydevd_process_net_command_json.py index 94cce79aa..9b51fcf9e 100644 --- a/_pydevd_bundle/pydevd_process_net_command_json.py +++ b/_pydevd_bundle/pydevd_process_net_command_json.py @@ -10,26 +10,50 @@ from _pydev_bundle import pydev_log from _pydevd_bundle._debug_adapter import pydevd_base_schema, pydevd_schema from _pydevd_bundle._debug_adapter.pydevd_schema import ( - CompletionsResponseBody, EvaluateResponseBody, ExceptionOptions, - GotoTargetsResponseBody, ModulesResponseBody, ProcessEventBody, - ProcessEvent, Scope, ScopesResponseBody, SetExpressionResponseBody, - SetVariableResponseBody, SourceBreakpoint, SourceResponseBody, - VariablesResponseBody, SetBreakpointsResponseBody, Response, - Capabilities, PydevdAuthorizeRequest, Request, - StepInTargetsResponseBody, SetFunctionBreakpointsResponseBody, BreakpointEvent, - BreakpointEventBody, InitializedEvent) + CompletionsResponseBody, + EvaluateResponseBody, + ExceptionOptions, + GotoTargetsResponseBody, + ModulesResponseBody, + ProcessEventBody, + ProcessEvent, + Scope, + ScopesResponseBody, + SetExpressionResponseBody, + SetVariableResponseBody, + SourceBreakpoint, + SourceResponseBody, + VariablesResponseBody, + SetBreakpointsResponseBody, + Response, + Capabilities, + PydevdAuthorizeRequest, + Request, + StepInTargetsResponseBody, + SetFunctionBreakpointsResponseBody, + BreakpointEvent, + BreakpointEventBody, + InitializedEvent, +) from _pydevd_bundle.pydevd_api import PyDevdAPI from _pydevd_bundle.pydevd_breakpoints import get_exception_class, FunctionBreakpoint from _pydevd_bundle.pydevd_comm_constants import ( - CMD_PROCESS_EVENT, CMD_RETURN, CMD_SET_NEXT_STATEMENT, CMD_STEP_INTO, - CMD_STEP_INTO_MY_CODE, CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, file_system_encoding, - CMD_STEP_RETURN_MY_CODE, CMD_STEP_RETURN) + CMD_PROCESS_EVENT, + CMD_RETURN, + CMD_SET_NEXT_STATEMENT, + CMD_STEP_INTO, + CMD_STEP_INTO_MY_CODE, + CMD_STEP_OVER, + CMD_STEP_OVER_MY_CODE, + file_system_encoding, + CMD_STEP_RETURN_MY_CODE, + CMD_STEP_RETURN, +) from _pydevd_bundle.pydevd_filtering import ExcludeFilter from _pydevd_bundle.pydevd_json_debug_options import _extract_debug_options, DebugOptions from _pydevd_bundle.pydevd_net_command import NetCommand from _pydevd_bundle.pydevd_utils import convert_dap_log_message_to_expression, ScopeRequest -from _pydevd_bundle.pydevd_constants import (PY_IMPL_NAME, DebugInfoHolder, PY_VERSION_STR, - PY_IMPL_VERSION_STR, IS_64BIT_PROCESS) +from _pydevd_bundle.pydevd_constants import PY_IMPL_NAME, DebugInfoHolder, PY_VERSION_STR, PY_IMPL_VERSION_STR, IS_64BIT_PROCESS from _pydevd_bundle.pydevd_trace_dispatch import USING_CYTHON from _pydevd_frame_eval.pydevd_frame_eval_main import USING_FRAME_EVAL from _pydevd_bundle.pydevd_comm import internal_get_step_in_targets_json @@ -52,27 +76,27 @@ def _convert_rules_to_exclude_filters(rules, on_error): on_error('Invalid "rules" (expected list of dicts). Found: %s' % (rules,)) continue - include = rule.get('include') + include = rule.get("include") if include is None: on_error('Invalid "rule" (expected dict with "include"). Found: %s' % (rule,)) continue - path = rule.get('path') - module = rule.get('module') + path = rule.get("path") + module = rule.get("module") if path is None and module is None: on_error('Invalid "rule" (expected dict with "path" or "module"). Found: %s' % (rule,)) continue if path is not None: glob_pattern = path - if '*' not in path and '?' not in path: + if "*" not in path and "?" not in path: if os.path.isdir(glob_pattern): # If a directory was specified, add a '/**' # to be consistent with the glob pattern required # by pydevd. - if not glob_pattern.endswith('/') and not glob_pattern.endswith('\\'): - glob_pattern += '/' - glob_pattern += '**' + if not glob_pattern.endswith("/") and not glob_pattern.endswith("\\"): + glob_pattern += "/" + glob_pattern += "**" directory_exclude_filters.append(ExcludeFilter(glob_pattern, not include, True)) else: glob_exclude_filters.append(ExcludeFilter(glob_pattern, not include, True)) @@ -81,22 +105,21 @@ def _convert_rules_to_exclude_filters(rules, on_error): module_exclude_filters.append(ExcludeFilter(module, not include, False)) else: - on_error('Internal error: expected path or module to be specified.') + on_error("Internal error: expected path or module to be specified.") # Note that we have to sort the directory/module exclude filters so that the biggest # paths match first. # i.e.: if we have: # /sub1/sub2/sub3 # a rule with /sub1/sub2 would match before a rule only with /sub1. - directory_exclude_filters = sorted(directory_exclude_filters, key=lambda exclude_filter:-len(exclude_filter.name)) - module_exclude_filters = sorted(module_exclude_filters, key=lambda exclude_filter:-len(exclude_filter.name)) + directory_exclude_filters = sorted(directory_exclude_filters, key=lambda exclude_filter: -len(exclude_filter.name)) + module_exclude_filters = sorted(module_exclude_filters, key=lambda exclude_filter: -len(exclude_filter.name)) exclude_filters = directory_exclude_filters + glob_exclude_filters + module_exclude_filters return exclude_filters class IDMap(object): - def __init__(self): self._value_to_key = {} self._key_to_value = {} @@ -116,7 +139,6 @@ def obtain_key(self, value): class PyDevJsonCommandProcessor(object): - def __init__(self, from_json): self.from_json = from_json self.api = PyDevdAPI() @@ -126,24 +148,24 @@ def __init__(self, from_json): self._launch_or_attach_request_done = False def process_net_command_json(self, py_db, json_contents, send_response=True): - ''' + """ Processes a debug adapter protocol json command. - ''' + """ DEBUG = False try: if isinstance(json_contents, bytes): - json_contents = json_contents.decode('utf-8') + json_contents = json_contents.decode("utf-8") request = self.from_json(json_contents, update_ids_from_dap=True) except Exception as e: try: loaded_json = json.loads(json_contents) - request = Request(loaded_json.get('command', ''), loaded_json['seq']) + request = Request(loaded_json.get("command", ""), loaded_json["seq"]) except: # There's not much we can do in this case... - pydev_log.exception('Error loading json: %s', json_contents) + pydev_log.exception("Error loading json: %s", json_contents) return error_msg = str(e) @@ -154,28 +176,33 @@ def process_net_command_json(self, py_db, json_contents, send_response=True): # so, answer with a failure response). def on_request(py_db, request): error_response = { - 'type': 'response', - 'request_seq': request.seq, - 'success': False, - 'command': request.command, - 'message': error_msg, + "type": "response", + "request_seq": request.seq, + "success": False, + "command": request.command, + "message": error_msg, } return NetCommand(CMD_RETURN, 0, error_response, is_json=True) else: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: - pydev_log.info('Process %s: %s\n' % ( - request.__class__.__name__, json.dumps(request.to_dict(update_ids_to_dap=True), indent=4, sort_keys=True),)) + pydev_log.info( + "Process %s: %s\n" + % ( + request.__class__.__name__, + json.dumps(request.to_dict(update_ids_to_dap=True), indent=4, sort_keys=True), + ) + ) - assert request.type == 'request' - method_name = 'on_%s_request' % (request.command.lower(),) + assert request.type == "request" + method_name = "on_%s_request" % (request.command.lower(),) on_request = getattr(self, method_name, None) if on_request is None: - print('Unhandled: %s not available in PyDevJsonCommandProcessor.\n' % (method_name,)) + print("Unhandled: %s not available in PyDevJsonCommandProcessor.\n" % (method_name,)) return if DEBUG: - print('Handled in pydevd: %s (in PyDevJsonCommandProcessor).\n' % (method_name,)) + print("Handled in pydevd: %s (in PyDevJsonCommandProcessor).\n" % (method_name,)) with py_db._main_lock: if request.__class__ == PydevdAuthorizeRequest: @@ -184,8 +211,7 @@ def on_request(py_db, request): py_db.authentication.login(access_token) if not py_db.authentication.is_authenticated(): - response = Response( - request.seq, success=False, command=request.command, message='Client not authenticated.', body={}) + response = Response(request.seq, success=False, command=request.command, message="Client not authenticated.", body={}) cmd = NetCommand(CMD_RETURN, 0, response, is_json=True) py_db.writer.add_command(cmd) return @@ -196,11 +222,11 @@ def on_request(py_db, request): def on_pydevdauthorize_request(self, py_db, request): client_access_token = py_db.authentication.client_access_token - body = {'clientAccessToken': None} + body = {"clientAccessToken": None} if client_access_token: - body['clientAccessToken'] = client_access_token + body["clientAccessToken"] = client_access_token - response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + response = pydevd_base_schema.build_response(request, kwargs={"body": body}) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_initialize_request(self, py_db, request): @@ -224,13 +250,11 @@ def on_initialize_request(self, py_db, request): supportsTerminateRequest=True, supportsClipboardContext=True, supportsFunctionBreakpoints=True, - exceptionBreakpointFilters=[ - {'filter': 'raised', 'label': 'Raised Exceptions', 'default': False}, - {'filter': 'uncaught', 'label': 'Uncaught Exceptions', 'default': True}, + {"filter": "raised", "label": "Raised Exceptions", "default": False}, + {"filter": "uncaught", "label": "Uncaught Exceptions", "default": True}, {"filter": "userUnhandled", "label": "User Uncaught Exceptions", "default": False}, ], - # Not supported. supportsStepBack=False, supportsRestartFrame=False, @@ -247,20 +271,20 @@ def on_initialize_request(self, py_db, request): ).to_dict() # Non-standard capabilities/info below. - body['supportsDebuggerProperties'] = True + body["supportsDebuggerProperties"] = True - body['pydevd'] = pydevd_info = {} - pydevd_info['processId'] = os.getpid() + body["pydevd"] = pydevd_info = {} + pydevd_info["processId"] = os.getpid() self.api.notify_initialize(py_db) - response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + response = pydevd_base_schema.build_response(request, kwargs={"body": body}) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_configurationdone_request(self, py_db, request): - ''' + """ :param ConfigurationDoneRequest request: - ''' + """ if not self._launch_or_attach_request_done: - pydev_log.critical('Missing launch request or attach request before configuration done request.') + pydev_log.critical("Missing launch request or attach request before configuration done request.") self.api.run(py_db) self.api.notify_configuration_done(py_db) @@ -269,15 +293,15 @@ def on_configurationdone_request(self, py_db, request): return NetCommand(CMD_RETURN, 0, configuration_done_response, is_json=True) def on_threads_request(self, py_db, request): - ''' + """ :param ThreadsRequest request: - ''' + """ return self.api.list_threads(py_db, request.seq) def on_terminate_request(self, py_db, request): - ''' + """ :param TerminateRequest request: - ''' + """ self._request_terminate_process(py_db) response = pydevd_base_schema.build_response(request) return NetCommand(CMD_RETURN, 0, response, is_json=True) @@ -286,25 +310,20 @@ def _request_terminate_process(self, py_db): self.api.request_terminate_process(py_db) def on_completions_request(self, py_db, request): - ''' + """ :param CompletionsRequest request: - ''' + """ arguments = request.arguments # : :type arguments: CompletionsArguments seq = request.seq text = arguments.text frame_id = arguments.frameId - thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference( - frame_id) + thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference(frame_id) if thread_id is None: body = CompletionsResponseBody([]) variables_response = pydevd_base_schema.build_response( - request, - kwargs={ - 'body': body, - 'success': False, - 'message': 'Thread to get completions seems to have resumed already.' - }) + request, kwargs={"body": body, "success": False, "message": "Thread to get completions seems to have resumed already."} + ) return NetCommand(CMD_RETURN, 0, variables_response, is_json=True) # Note: line and column are 1-based (convert to 0-based for pydevd). @@ -319,61 +338,62 @@ def on_completions_request(self, py_db, request): self.api.request_completions(py_db, seq, thread_id, frame_id, text, line=line, column=column) def _resolve_remote_root(self, local_root, remote_root): - if remote_root == '.': + if remote_root == ".": cwd = os.getcwd() - append_pathsep = local_root.endswith('\\') or local_root.endswith('/') - return cwd + (os.path.sep if append_pathsep else '') + append_pathsep = local_root.endswith("\\") or local_root.endswith("/") + return cwd + (os.path.sep if append_pathsep else "") return remote_root def _set_debug_options(self, py_db, args, start_reason): - rules = args.get('rules') - stepping_resumes_all_threads = args.get('steppingResumesAllThreads', True) + rules = args.get("rules") + stepping_resumes_all_threads = args.get("steppingResumesAllThreads", True) self.api.set_stepping_resumes_all_threads(py_db, stepping_resumes_all_threads) - terminate_child_processes = args.get('terminateChildProcesses', True) + terminate_child_processes = args.get("terminateChildProcesses", True) self.api.set_terminate_child_processes(py_db, terminate_child_processes) - terminate_keyboard_interrupt = args.get('onTerminate', 'kill') == 'KeyboardInterrupt' + terminate_keyboard_interrupt = args.get("onTerminate", "kill") == "KeyboardInterrupt" self.api.set_terminate_keyboard_interrupt(py_db, terminate_keyboard_interrupt) - variable_presentation = args.get('variablePresentation', None) + variable_presentation = args.get("variablePresentation", None) if isinstance(variable_presentation, dict): def get_variable_presentation(setting, default): value = variable_presentation.get(setting, default) - if value not in ('group', 'inline', 'hide'): + if value not in ("group", "inline", "hide"): pydev_log.info( - 'The value set for "%s" (%s) in the variablePresentation is not valid. Valid values are: "group", "inline", "hide"' % ( - setting, value,)) + 'The value set for "%s" (%s) in the variablePresentation is not valid. Valid values are: "group", "inline", "hide"' + % ( + setting, + value, + ) + ) value = default return value - default = get_variable_presentation('all', 'group') + default = get_variable_presentation("all", "group") - special_presentation = get_variable_presentation('special', default) - function_presentation = get_variable_presentation('function', default) - class_presentation = get_variable_presentation('class', default) - protected_presentation = get_variable_presentation('protected', default) + special_presentation = get_variable_presentation("special", default) + function_presentation = get_variable_presentation("function", default) + class_presentation = get_variable_presentation("class", default) + protected_presentation = get_variable_presentation("protected", default) - self.api.set_variable_presentation(py_db, self.api.VariablePresentation( - special_presentation, - function_presentation, - class_presentation, - protected_presentation - )) + self.api.set_variable_presentation( + py_db, + self.api.VariablePresentation(special_presentation, function_presentation, class_presentation, protected_presentation), + ) exclude_filters = [] if rules is not None: - exclude_filters = _convert_rules_to_exclude_filters( - rules, lambda msg: self.api.send_error_message(py_db, msg)) + exclude_filters = _convert_rules_to_exclude_filters(rules, lambda msg: self.api.send_error_message(py_db, msg)) self.api.set_exclude_filters(py_db, exclude_filters) debug_options = _extract_debug_options( - args.get('options'), - args.get('debugOptions'), + args.get("options"), + args.get("debugOptions"), ) self._options.update_fom_debug_options(debug_options) self._options.update_from_args(args) @@ -384,17 +404,17 @@ def get_variable_presentation(setting, default): self.api.set_ide_os(self._options.client_os) path_mappings = [] - for pathMapping in args.get('pathMappings', []): - localRoot = pathMapping.get('localRoot', '') - remoteRoot = pathMapping.get('remoteRoot', '') + for pathMapping in args.get("pathMappings", []): + localRoot = pathMapping.get("localRoot", "") + remoteRoot = pathMapping.get("remoteRoot", "") remoteRoot = self._resolve_remote_root(localRoot, remoteRoot) - if (localRoot != '') and (remoteRoot != ''): + if (localRoot != "") and (remoteRoot != ""): path_mappings.append((localRoot, remoteRoot)) if bool(path_mappings): pydevd_file_utils.setup_client_server_paths(path_mappings) - resolve_symlinks = args.get('resolveSymlinks', None) + resolve_symlinks = args.get("resolveSymlinks", None) if resolve_symlinks is not None: pydevd_file_utils.set_resolve_symlinks(resolve_symlinks) @@ -416,13 +436,13 @@ def get_variable_presentation(setting, default): self.api.set_ignore_system_exit_codes(py_db, ignore_system_exit_codes) - auto_reload = args.get('autoReload', {}) + auto_reload = args.get("autoReload", {}) if not isinstance(auto_reload, dict): - pydev_log.info('Expected autoReload to be a dict. Received: %s' % (auto_reload,)) + pydev_log.info("Expected autoReload to be a dict. Received: %s" % (auto_reload,)) auto_reload = {} - enable_auto_reload = auto_reload.get('enable', False) - watch_dirs = auto_reload.get('watchDirectories') + enable_auto_reload = auto_reload.get("enable", False) + watch_dirs = auto_reload.get("watchDirectories") if not watch_dirs: watch_dirs = [] # Note: by default this is no longer done because on some cases there are entries in the PYTHONPATH @@ -435,15 +455,15 @@ def get_variable_presentation(setting, default): # watch_dirs = [pydevd_file_utils.absolute_path(w) for w in check] # watch_dirs = [w for w in watch_dirs if py_db.in_project_roots_filename_uncached(w) and os.path.isdir(w)] - program = args.get('program') + program = args.get("program") if program: if os.path.isdir(program): watch_dirs.append(program) else: watch_dirs.append(os.path.dirname(program)) - watch_dirs.append(os.path.abspath('.')) + watch_dirs.append(os.path.abspath(".")) - argv = getattr(sys, 'argv', []) + argv = getattr(sys, "argv", []) if argv: f = argv[0] if f: # argv[0] could be None (https://github.com/microsoft/debugpy/issues/987) @@ -459,30 +479,31 @@ def get_variable_presentation(setting, default): try: new_watch_dirs.add(pydevd_file_utils.get_path_with_real_case(pydevd_file_utils.absolute_path(w))) except Exception: - pydev_log.exception('Error adding watch dir: %s', w) + pydev_log.exception("Error adding watch dir: %s", w) watch_dirs = new_watch_dirs - poll_target_time = auto_reload.get('pollingInterval', 1) - exclude_patterns = auto_reload.get('exclude', ('**/.git/**', '**/__pycache__/**', '**/node_modules/**', '**/.metadata/**', '**/site-packages/**')) - include_patterns = auto_reload.get('include', ('**/*.py', '**/*.pyw')) - self.api.setup_auto_reload_watcher( - py_db, enable_auto_reload, watch_dirs, poll_target_time, exclude_patterns, include_patterns) + poll_target_time = auto_reload.get("pollingInterval", 1) + exclude_patterns = auto_reload.get( + "exclude", ("**/.git/**", "**/__pycache__/**", "**/node_modules/**", "**/.metadata/**", "**/site-packages/**") + ) + include_patterns = auto_reload.get("include", ("**/*.py", "**/*.pyw")) + self.api.setup_auto_reload_watcher(py_db, enable_auto_reload, watch_dirs, poll_target_time, exclude_patterns, include_patterns) - if self._options.stop_on_entry and start_reason == 'launch': + if self._options.stop_on_entry and start_reason == "launch": self.api.stop_on_entry() self.api.set_gui_event_loop(py_db, self._options.gui_event_loop) def _send_process_event(self, py_db, start_method): - argv = getattr(sys, 'argv', []) + argv = getattr(sys, "argv", []) if len(argv) > 0: name = argv[0] else: - name = '' + name = "" if isinstance(name, bytes): - name = name.decode(file_system_encoding, 'replace') - name = name.encode('utf-8') + name = name.decode(file_system_encoding, "replace") + name = name.encode("utf-8") body = ProcessEventBody( name=name, @@ -505,21 +526,21 @@ def _handle_launch_or_attach_request(self, py_db, request, start_reason): return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_launch_request(self, py_db, request): - ''' + """ :param LaunchRequest request: - ''' - return self._handle_launch_or_attach_request(py_db, request, start_reason='launch') + """ + return self._handle_launch_or_attach_request(py_db, request, start_reason="launch") def on_attach_request(self, py_db, request): - ''' + """ :param AttachRequest request: - ''' - return self._handle_launch_or_attach_request(py_db, request, start_reason='attach') + """ + return self._handle_launch_or_attach_request(py_db, request, start_reason="attach") def on_pause_request(self, py_db, request): - ''' + """ :param PauseRequest request: - ''' + """ arguments = request.arguments # : :type arguments: PauseArguments thread_id = arguments.threadId @@ -529,20 +550,19 @@ def on_pause_request(self, py_db, request): return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_continue_request(self, py_db, request): - ''' + """ :param ContinueRequest request: - ''' + """ arguments = request.arguments # : :type arguments: ContinueArguments thread_id = arguments.threadId def on_resumed(): - body = {'allThreadsContinued': thread_id == '*'} - response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + body = {"allThreadsContinued": thread_id == "*"} + response = pydevd_base_schema.build_response(request, kwargs={"body": body}) cmd = NetCommand(CMD_RETURN, 0, response, is_json=True) py_db.writer.add_command(cmd) if py_db.multi_threads_single_notification: - # Only send resumed notification when it has actually resumed! # (otherwise the user could send a continue, receive the notification and then # request a new pause which would be paused without sending any notification as @@ -558,9 +578,9 @@ def on_resumed(): on_resumed() def on_next_request(self, py_db, request): - ''' + """ :param NextRequest request: - ''' + """ arguments = request.arguments # : :type arguments: NextArguments thread_id = arguments.threadId @@ -575,9 +595,9 @@ def on_next_request(self, py_db, request): return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_stepin_request(self, py_db, request): - ''' + """ :param StepInRequest request: - ''' + """ arguments = request.arguments # : :type arguments: StepInArguments thread_id = arguments.threadId @@ -589,7 +609,7 @@ def on_stepin_request(self, py_db, request): request_seq=request.seq, success=False, command=request.command, - message='Unable to find thread from thread_id: %s' % (thread_id,), + message="Unable to find thread from thread_id: %s" % (thread_id,), body={}, ) return NetCommand(CMD_RETURN, 0, response, is_json=True) @@ -598,11 +618,8 @@ def on_stepin_request(self, py_db, request): target_id_to_smart_step_into_variant = info.target_id_to_smart_step_into_variant if not target_id_to_smart_step_into_variant: variables_response = pydevd_base_schema.build_response( - request, - kwargs={ - 'success': False, - 'message': 'Unable to step into target (no targets are saved in the thread info).' - }) + request, kwargs={"success": False, "message": "Unable to step into target (no targets are saved in the thread info)."} + ) return NetCommand(CMD_RETURN, 0, variables_response, is_json=True) variant = target_id_to_smart_step_into_variant.get(target_id) @@ -616,10 +633,11 @@ def on_stepin_request(self, py_db, request): variables_response = pydevd_base_schema.build_response( request, kwargs={ - 'success': False, - 'message': 'Unable to find step into target %s. Available targets: %s' % ( - target_id, target_id_to_smart_step_into_variant) - }) + "success": False, + "message": "Unable to find step into target %s. Available targets: %s" + % (target_id, target_id_to_smart_step_into_variant), + }, + ) return NetCommand(CMD_RETURN, 0, variables_response, is_json=True) else: @@ -634,31 +652,32 @@ def on_stepin_request(self, py_db, request): return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_stepintargets_request(self, py_db, request): - ''' + """ :param StepInTargetsRequest request: - ''' + """ frame_id = request.arguments.frameId - thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference( - frame_id) + thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference(frame_id) if thread_id is None: body = StepInTargetsResponseBody([]) variables_response = pydevd_base_schema.build_response( request, kwargs={ - 'body': body, - 'success': False, - 'message': 'Unable to get thread_id from frame_id (thread to get step in targets seems to have resumed already).' - }) + "body": body, + "success": False, + "message": "Unable to get thread_id from frame_id (thread to get step in targets seems to have resumed already).", + }, + ) return NetCommand(CMD_RETURN, 0, variables_response, is_json=True) py_db.post_method_as_internal_command( - thread_id, internal_get_step_in_targets_json, request.seq, thread_id, frame_id, request, set_additional_thread_info) + thread_id, internal_get_step_in_targets_json, request.seq, thread_id, frame_id, request, set_additional_thread_info + ) def on_stepout_request(self, py_db, request): - ''' + """ :param StepOutRequest request: - ''' + """ arguments = request.arguments # : :type arguments: StepOutArguments thread_id = arguments.threadId @@ -673,38 +692,36 @@ def on_stepout_request(self, py_db, request): return NetCommand(CMD_RETURN, 0, response, is_json=True) def _get_hit_condition_expression(self, hit_condition): - '''Following hit condition values are supported + """Following hit condition values are supported * x or == x when breakpoint is hit x times * >= x when breakpoint is hit more than or equal to x times * % x when breakpoint is hit multiple of x times Returns '@HIT@ == x' where @HIT@ will be replaced by number of hits - ''' + """ if not hit_condition: return None expr = hit_condition.strip() try: int(expr) - return '@HIT@ == {}'.format(expr) + return "@HIT@ == {}".format(expr) except ValueError: pass - if expr.startswith('%'): - return '@HIT@ {} == 0'.format(expr) + if expr.startswith("%"): + return "@HIT@ {} == 0".format(expr) - if expr.startswith('==') or \ - expr.startswith('>') or \ - expr.startswith('<'): - return '@HIT@ {}'.format(expr) + if expr.startswith("==") or expr.startswith(">") or expr.startswith("<"): + return "@HIT@ {}".format(expr) return hit_condition def on_disconnect_request(self, py_db, request): - ''' + """ :param DisconnectRequest request: - ''' + """ if request.arguments.terminateDebuggee: self._request_terminate_process(py_db) response = pydevd_base_schema.build_response(request) @@ -721,30 +738,27 @@ def _verify_launch_or_attach_done(self, request): if not self._launch_or_attach_request_done: # Note that to validate the breakpoints we need the launch request to be done already # (otherwise the filters wouldn't be set for the breakpoint validation). - if request.command == 'setFunctionBreakpoints': + if request.command == "setFunctionBreakpoints": body = SetFunctionBreakpointsResponseBody([]) else: body = SetBreakpointsResponseBody([]) response = pydevd_base_schema.build_response( request, - kwargs={ - 'body': body, - 'success': False, - 'message': 'Breakpoints may only be set after the launch request is received.' - }) + kwargs={"body": body, "success": False, "message": "Breakpoints may only be set after the launch request is received."}, + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_setfunctionbreakpoints_request(self, py_db, request): - ''' + """ :param SetFunctionBreakpointsRequest request: - ''' + """ response = self._verify_launch_or_attach_done(request) if response is not None: return response arguments = request.arguments # : :type arguments: SetFunctionBreakpointsArguments function_breakpoints = [] - suspend_policy = 'ALL' if py_db.multi_threads_single_notification else 'NONE' + suspend_policy = "ALL" if py_db.multi_threads_single_notification else "NONE" # Not currently covered by the DAP. is_logpoint = False @@ -752,26 +766,24 @@ def on_setfunctionbreakpoints_request(self, py_db, request): breakpoints_set = [] for bp in arguments.breakpoints: - hit_condition = self._get_hit_condition_expression(bp.get('hitCondition')) - condition = bp.get('condition') + hit_condition = self._get_hit_condition_expression(bp.get("hitCondition")) + condition = bp.get("condition") - function_breakpoints.append( - FunctionBreakpoint(bp['name'], condition, expression, suspend_policy, hit_condition, is_logpoint)) + function_breakpoints.append(FunctionBreakpoint(bp["name"], condition, expression, suspend_policy, hit_condition, is_logpoint)) # Note: always succeeds. - breakpoints_set.append(pydevd_schema.Breakpoint( - verified=True, id=self._next_breakpoint_id()).to_dict()) + breakpoints_set.append(pydevd_schema.Breakpoint(verified=True, id=self._next_breakpoint_id()).to_dict()) self.api.set_function_breakpoints(py_db, function_breakpoints) - body = {'breakpoints': breakpoints_set} - set_breakpoints_response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + body = {"breakpoints": breakpoints_set} + set_breakpoints_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) return NetCommand(CMD_RETURN, 0, set_breakpoints_response, is_json=True) def on_setbreakpoints_request(self, py_db, request): - ''' + """ :param SetBreakpointsRequest request: - ''' + """ response = self._verify_launch_or_attach_done(request) if response is not None: return response @@ -779,18 +791,18 @@ def on_setbreakpoints_request(self, py_db, request): arguments = request.arguments # : :type arguments: SetBreakpointsArguments # TODO: Path is optional here it could be source reference. filename = self.api.filename_to_str(arguments.source.path) - func_name = 'None' + func_name = "None" self.api.remove_all_breakpoints(py_db, filename) - btype = 'python-line' - suspend_policy = 'ALL' if py_db.multi_threads_single_notification else 'NONE' + btype = "python-line" + suspend_policy = "ALL" if py_db.multi_threads_single_notification else "NONE" - if not filename.lower().endswith('.py'): # Note: check based on original file, not mapping. + if not filename.lower().endswith(".py"): # Note: check based on original file, not mapping. if self._options.django_debug: - btype = 'django-line' + btype = "django-line" elif self._options.flask_debug: - btype = 'jinja2-line' + btype = "jinja2-line" breakpoints_set = [] @@ -811,20 +823,32 @@ def on_setbreakpoints_request(self, py_db, request): on_changed_breakpoint_state = partial(self._on_changed_breakpoint_state, py_db, arguments.source) result = self.api.add_breakpoint( - py_db, filename, btype, breakpoint_id, line, condition, func_name, expression, - suspend_policy, hit_condition, is_logpoint, adjust_line=True, on_changed_breakpoint_state=on_changed_breakpoint_state) + py_db, + filename, + btype, + breakpoint_id, + line, + condition, + func_name, + expression, + suspend_policy, + hit_condition, + is_logpoint, + adjust_line=True, + on_changed_breakpoint_state=on_changed_breakpoint_state, + ) bp = self._create_breakpoint_from_add_breakpoint_result(py_db, arguments.source, breakpoint_id, result) breakpoints_set.append(bp) - body = {'breakpoints': breakpoints_set} - set_breakpoints_response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + body = {"breakpoints": breakpoints_set} + set_breakpoints_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) return NetCommand(CMD_RETURN, 0, set_breakpoints_response, is_json=True) def _on_changed_breakpoint_state(self, py_db, source, breakpoint_id, result): bp = self._create_breakpoint_from_add_breakpoint_result(py_db, source, breakpoint_id, result) body = BreakpointEventBody( - reason='changed', + reason="changed", breakpoint=bp, ) event = BreakpointEvent(body) @@ -836,34 +860,36 @@ def _create_breakpoint_from_add_breakpoint_result(self, py_db, source, breakpoin if error_code: if error_code == self.api.ADD_BREAKPOINT_FILE_NOT_FOUND: - error_msg = 'Breakpoint in file that does not exist.' + error_msg = "Breakpoint in file that does not exist." elif error_code == self.api.ADD_BREAKPOINT_FILE_EXCLUDED_BY_FILTERS: - error_msg = 'Breakpoint in file excluded by filters.' + error_msg = "Breakpoint in file excluded by filters." if py_db.get_use_libraries_filter(): - error_msg += ('\nNote: may be excluded because of "justMyCode" option (default == true).' - 'Try setting \"justMyCode\": false in the debug configuration (e.g., launch.json).\n') + error_msg += ( + '\nNote: may be excluded because of "justMyCode" option (default == true).' + 'Try setting "justMyCode": false in the debug configuration (e.g., launch.json).\n' + ) elif error_code == self.api.ADD_BREAKPOINT_LAZY_VALIDATION: - error_msg = 'Waiting for code to be loaded to verify breakpoint.' + error_msg = "Waiting for code to be loaded to verify breakpoint." elif error_code == self.api.ADD_BREAKPOINT_INVALID_LINE: - error_msg = 'Breakpoint added to invalid line.' + error_msg = "Breakpoint added to invalid line." else: # Shouldn't get here. - error_msg = 'Breakpoint not validated (reason unknown -- please report as bug).' + error_msg = "Breakpoint not validated (reason unknown -- please report as bug)." return pydevd_schema.Breakpoint( - verified=False, id=breakpoint_id, line=result.translated_line, message=error_msg, source=source).to_dict() + verified=False, id=breakpoint_id, line=result.translated_line, message=error_msg, source=source + ).to_dict() else: - return pydevd_schema.Breakpoint( - verified=True, id=breakpoint_id, line=result.translated_line, source=source).to_dict() + return pydevd_schema.Breakpoint(verified=True, id=breakpoint_id, line=result.translated_line, source=source).to_dict() def on_setexceptionbreakpoints_request(self, py_db, request): - ''' + """ :param SetExceptionBreakpointsRequest request: - ''' + """ # : :type arguments: SetExceptionBreakpointsArguments arguments = request.arguments filters = arguments.filters @@ -894,9 +920,9 @@ def on_setexceptionbreakpoints_request(self, py_db, request): # # userUnhandled: breaks if the exception is not handled by user code - notify_on_handled_exceptions = 1 if option.breakMode == 'always' else 0 - notify_on_unhandled_exceptions = 1 if option.breakMode == 'unhandled' else 0 - notify_on_user_unhandled_exceptions = 1 if option.breakMode == 'userUnhandled' else 0 + notify_on_handled_exceptions = 1 if option.breakMode == "always" else 0 + notify_on_unhandled_exceptions = 1 if option.breakMode == "unhandled" else 0 + notify_on_user_unhandled_exceptions = 1 if option.breakMode == "userUnhandled" else 0 exception_paths = option.path break_raised |= notify_on_handled_exceptions break_uncaught |= notify_on_unhandled_exceptions @@ -906,14 +932,14 @@ def on_setexceptionbreakpoints_request(self, py_db, request): continue elif len(exception_paths) == 1: - if 'Python Exceptions' in exception_paths[0]['names']: - exception_names = ['BaseException'] + if "Python Exceptions" in exception_paths[0]["names"]: + exception_names = ["BaseException"] else: path_iterator = iter(exception_paths) - if 'Python Exceptions' in next(path_iterator)['names']: + if "Python Exceptions" in next(path_iterator)["names"]: for path in path_iterator: - for ex_name in path['names']: + for ex_name in path["names"]: exception_names.append(ex_name) for exception_name in exception_names: @@ -926,18 +952,18 @@ def on_setexceptionbreakpoints_request(self, py_db, request): notify_on_unhandled_exceptions, notify_on_user_unhandled_exceptions, notify_on_first_raise_only, - ignore_libraries + ignore_libraries, ) else: - break_raised = 'raised' in filters - break_uncaught = 'uncaught' in filters - break_user = 'userUnhandled' in filters + break_raised = "raised" in filters + break_uncaught = "uncaught" in filters + break_user = "userUnhandled" in filters if break_raised or break_uncaught or break_user: notify_on_handled_exceptions = 1 if break_raised else 0 notify_on_unhandled_exceptions = 1 if break_uncaught else 0 notify_on_user_unhandled_exceptions = 1 if break_user else 0 - exception = 'BaseException' + exception = "BaseException" self.api.add_python_exception_breakpoint( py_db, @@ -948,28 +974,27 @@ def on_setexceptionbreakpoints_request(self, py_db, request): notify_on_unhandled_exceptions, notify_on_user_unhandled_exceptions, notify_on_first_raise_only, - ignore_libraries + ignore_libraries, ) if break_raised: btype = None if self._options.django_debug: - btype = 'django' + btype = "django" elif self._options.flask_debug: - btype = 'jinja2' + btype = "jinja2" if btype: - self.api.add_plugins_exception_breakpoint( - py_db, btype, 'BaseException') # Note: Exception name could be anything here. + self.api.add_plugins_exception_breakpoint(py_db, btype, "BaseException") # Note: Exception name could be anything here. # Note: no body required on success. set_breakpoints_response = pydevd_base_schema.build_response(request) return NetCommand(CMD_RETURN, 0, set_breakpoints_response, is_json=True) def on_stacktrace_request(self, py_db, request): - ''' + """ :param StackTraceRequest request: - ''' + """ # : :type stack_trace_arguments: StackTraceArguments stack_trace_arguments = request.arguments thread_id = stack_trace_arguments.threadId @@ -985,14 +1010,14 @@ def on_stacktrace_request(self, py_db, request): levels = 0 fmt = stack_trace_arguments.format - if hasattr(fmt, 'to_dict'): + if hasattr(fmt, "to_dict"): fmt = fmt.to_dict() self.api.request_stack(py_db, request.seq, thread_id, fmt=fmt, start_frame=start_frame, levels=levels) def on_exceptioninfo_request(self, py_db, request): - ''' + """ :param ExceptionInfoRequest request: - ''' + """ # : :type exception_into_arguments: ExceptionInfoArguments exception_into_arguments = request.arguments thread_id = exception_into_arguments.threadId @@ -1005,78 +1030,67 @@ def on_exceptioninfo_request(self, py_db, request): request_seq=request.seq, success=False, command=request.command, - message='Unable to find thread from thread_id: %s' % (thread_id,), + message="Unable to find thread from thread_id: %s" % (thread_id,), body={}, ) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_scopes_request(self, py_db, request): - ''' + """ Scopes are the top-level items which appear for a frame (so, we receive the frame id and provide the scopes it has). :param ScopesRequest request: - ''' + """ frame_id = request.arguments.frameId variables_reference = frame_id scopes = [ - Scope('Locals', ScopeRequest(int(variables_reference), 'locals'), False, presentationHint='locals'), - Scope('Globals', ScopeRequest(int(variables_reference), 'globals'), False), + Scope("Locals", ScopeRequest(int(variables_reference), "locals"), False, presentationHint="locals"), + Scope("Globals", ScopeRequest(int(variables_reference), "globals"), False), ] body = ScopesResponseBody(scopes) - scopes_response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + scopes_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) return NetCommand(CMD_RETURN, 0, scopes_response, is_json=True) def on_evaluate_request(self, py_db, request): - ''' + """ :param EvaluateRequest request: - ''' + """ # : :type arguments: EvaluateArguments arguments = request.arguments if arguments.frameId is None: - self.api.request_exec_or_evaluate_json(py_db, request, thread_id='*') + self.api.request_exec_or_evaluate_json(py_db, request, thread_id="*") else: - thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference( - arguments.frameId) + thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference(arguments.frameId) if thread_id is not None: - self.api.request_exec_or_evaluate_json( - py_db, request, thread_id) + self.api.request_exec_or_evaluate_json(py_db, request, thread_id) else: - body = EvaluateResponseBody('', 0) + body = EvaluateResponseBody("", 0) response = pydevd_base_schema.build_response( - request, - kwargs={ - 'body': body, - 'success': False, - 'message': 'Unable to find thread for evaluation.' - }) + request, kwargs={"body": body, "success": False, "message": "Unable to find thread for evaluation."} + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_setexpression_request(self, py_db, request): # : :type arguments: SetExpressionArguments arguments = request.arguments - thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference( - arguments.frameId) + thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference(arguments.frameId) if thread_id is not None: self.api.request_set_expression_json(py_db, request, thread_id) else: - body = SetExpressionResponseBody('') + body = SetExpressionResponseBody("") response = pydevd_base_schema.build_response( - request, - kwargs={ - 'body': body, - 'success': False, - 'message': 'Unable to find thread to set expression.' - }) + request, kwargs={"body": body, "success": False, "message": "Unable to find thread to set expression."} + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_variables_request(self, py_db, request): - ''' + """ Variables can be asked whenever some place returned a variables reference (so, it can be a scope gotten from on_scopes_request, the result of some evaluation, etc.). @@ -1089,25 +1103,22 @@ def on_variables_request(self, py_db, request): see: SuspendedFramesManager :param VariablesRequest request: - ''' + """ arguments = request.arguments # : :type arguments: VariablesArguments variables_reference = arguments.variablesReference if isinstance(variables_reference, ScopeRequest): variables_reference = variables_reference.variable_reference - thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference( - variables_reference) + thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference(variables_reference) if thread_id is not None: self.api.request_get_variable_json(py_db, request, thread_id) else: variables = [] body = VariablesResponseBody(variables) - variables_response = pydevd_base_schema.build_response(request, kwargs={ - 'body': body, - 'success': False, - 'message': 'Unable to find thread to evaluate variable reference.' - }) + variables_response = pydevd_base_schema.build_response( + request, kwargs={"body": body, "success": False, "message": "Unable to find thread to evaluate variable reference."} + ) return NetCommand(CMD_RETURN, 0, variables_response, is_json=True) def on_setvariable_request(self, py_db, request): @@ -1117,18 +1128,13 @@ def on_setvariable_request(self, py_db, request): if isinstance(variables_reference, ScopeRequest): variables_reference = variables_reference.variable_reference - if arguments.name.startswith('(return) '): + if arguments.name.startswith("(return) "): response = pydevd_base_schema.build_response( - request, - kwargs={ - 'body': SetVariableResponseBody(''), - 'success': False, - 'message': 'Cannot change return value' - }) + request, kwargs={"body": SetVariableResponseBody(""), "success": False, "message": "Cannot change return value"} + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) - thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference( - variables_reference) + thread_id = py_db.suspended_frames_manager.get_thread_id_for_variable_reference(variables_reference) if thread_id is not None: self.api.request_change_variable_json(py_db, request, thread_id) @@ -1136,23 +1142,24 @@ def on_setvariable_request(self, py_db, request): response = pydevd_base_schema.build_response( request, kwargs={ - 'body': SetVariableResponseBody(''), - 'success': False, - 'message': 'Unable to find thread to evaluate variable reference.' - }) + "body": SetVariableResponseBody(""), + "success": False, + "message": "Unable to find thread to evaluate variable reference.", + }, + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_modules_request(self, py_db, request): modules_manager = py_db.cmd_factory.modules_manager # : :type modules_manager: ModulesManager modules_info = modules_manager.get_modules_info() body = ModulesResponseBody(modules_info) - variables_response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + variables_response = pydevd_base_schema.build_response(request, kwargs={"body": body}) return NetCommand(CMD_RETURN, 0, variables_response, is_json=True) def on_source_request(self, py_db, request): - ''' + """ :param SourceRequest request: - ''' + """ source_reference = request.arguments.sourceReference server_filename = None content = None @@ -1165,7 +1172,7 @@ def on_source_request(self, py_db, request): if server_filename: # Try direct file access first - it's much faster when available. try: - with open(server_filename, 'r') as stream: + with open(server_filename, "r") as stream: content = stream.read() except: pass @@ -1179,29 +1186,29 @@ def on_source_request(self, py_db, request): # If we didn't get at least one line back, reset it to None so that it's # reported as error below, and not as an empty file. - content = ''.join(lines) or None + content = "".join(lines) or None if content is None: frame_id = pydevd_file_utils.get_frame_id_from_source_reference(source_reference) - pydev_log.debug('Found frame id: %s for source reference: %s', frame_id, source_reference) + pydev_log.debug("Found frame id: %s for source reference: %s", frame_id, source_reference) if frame_id is not None: try: content = self.api.get_decompiled_source_from_frame_id(py_db, frame_id) except Exception: - pydev_log.exception('Error getting source for frame id: %s', frame_id) + pydev_log.exception("Error getting source for frame id: %s", frame_id) content = None - body = SourceResponseBody(content or '') - response_args = {'body': body} + body = SourceResponseBody(content or "") + response_args = {"body": body} if content is None: if source_reference == 0: - message = 'Source unavailable' + message = "Source unavailable" elif server_filename: - message = 'Unable to retrieve source for %s' % (server_filename,) + message = "Unable to retrieve source for %s" % (server_filename,) else: - message = 'Invalid sourceReference %d' % (source_reference,) - response_args.update({'success': False, 'message': message}) + message = "Invalid sourceReference %d" % (source_reference,) + response_args.update({"success": False, "message": message}) response = pydevd_base_schema.build_response(request, kwargs=response_args) return NetCommand(CMD_RETURN, 0, response, is_json=True) @@ -1210,13 +1217,9 @@ def on_gototargets_request(self, py_db, request): path = request.arguments.source.path line = request.arguments.line target_id = self._goto_targets_map.obtain_key((path, line)) - target = { - 'id': target_id, - 'label': '%s:%s' % (path, line), - 'line': line - } + target = {"id": target_id, "label": "%s:%s" % (path, line), "line": line} body = GotoTargetsResponseBody(targets=[target]) - response_args = {'body': body} + response_args = {"body": body} response = pydevd_base_schema.build_response(request, kwargs=response_args) return NetCommand(CMD_RETURN, 0, response, is_json=True) @@ -1229,13 +1232,14 @@ def on_goto_request(self, py_db, request): response = pydevd_base_schema.build_response( request, kwargs={ - 'body': {}, - 'success': False, - 'message': 'Unknown goto target id: %d' % (target_id,), - }) + "body": {}, + "success": False, + "message": "Unknown goto target id: %d" % (target_id,), + }, + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) - self.api.request_set_next(py_db, request.seq, thread_id, CMD_SET_NEXT_STATEMENT, path, line, '*') + self.api.request_set_next(py_db, request.seq, thread_id, CMD_SET_NEXT_STATEMENT, path, line, "*") # See 'NetCommandFactoryJson.make_set_next_stmnt_status_message' for response return None @@ -1250,12 +1254,10 @@ def on_setdebuggerproperty_request(self, py_db, request): self.api.set_dont_trace_start_end_patterns(py_db, start_patterns, end_patterns) if args.skipSuspendOnBreakpointException is not None: - py_db.skip_suspend_on_breakpoint_exception = tuple( - get_exception_class(x) for x in args.skipSuspendOnBreakpointException) + py_db.skip_suspend_on_breakpoint_exception = tuple(get_exception_class(x) for x in args.skipSuspendOnBreakpointException) if args.skipPrintBreakpointException is not None: - py_db.skip_print_breakpoint_exception = tuple( - get_exception_class(x) for x in args.skipPrintBreakpointException) + py_db.skip_print_breakpoint_exception = tuple(get_exception_class(x) for x in args.skipPrintBreakpointException) if args.multiThreadsSingleNotification is not None: py_db.multi_threads_single_notification = args.multiThreadsSingleNotification @@ -1269,7 +1271,7 @@ def on_setdebuggerproperty_request(self, py_db, request): # WarnIfNoUserCodeOnLaunch: 0 or 1 # EnableStepFiltering: true of false - response = pydevd_base_schema.build_response(request, kwargs={'body': {}}) + response = pydevd_base_schema.build_response(request, kwargs={"body": {}}) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_pydevdsysteminfo_request(self, py_db, request): @@ -1296,7 +1298,7 @@ def on_pydevdsysteminfo_request(self, py_db, request): name=PY_IMPL_NAME, version=PY_IMPL_VERSION_STR, description=impl_desc, - ) + ), ) platform_info = pydevd_schema.PydevdPlatformInfo(name=sys.platform) process_info = pydevd_schema.PydevdProcessInfo( @@ -1310,12 +1312,12 @@ def on_pydevdsysteminfo_request(self, py_db, request): usingFrameEval=USING_FRAME_EVAL, ) body = { - 'python': py_info, - 'platform': platform_info, - 'process': process_info, - 'pydevd': pydevd_info, + "python": py_info, + "platform": platform_info, + "process": process_info, + "pydevd": pydevd_info, } - response = pydevd_base_schema.build_response(request, kwargs={'body': body}) + response = pydevd_base_schema.build_response(request, kwargs={"body": body}) return NetCommand(CMD_RETURN, 0, response, is_json=True) def on_setpydevdsourcemap_request(self, py_db, request): @@ -1327,11 +1329,12 @@ def on_setpydevdsourcemap_request(self, py_db, request): # : :type source_map: PydevdSourceMap new_mappings = [ SourceMappingEntry( - source_map['line'], - source_map['endLine'], - source_map['runtimeLine'], - self.api.filename_to_str(source_map['runtimeSource']['path']) - ) for source_map in source_maps + source_map["line"], + source_map["endLine"], + source_map["runtimeLine"], + self.api.filename_to_str(source_map["runtimeSource"]["path"]), + ) + for source_map in source_maps ] error_msg = self.api.set_source_mapping(py_db, path, new_mappings) @@ -1339,12 +1342,12 @@ def on_setpydevdsourcemap_request(self, py_db, request): response = pydevd_base_schema.build_response( request, kwargs={ - 'body': {}, - 'success': False, - 'message': error_msg, - }) + "body": {}, + "success": False, + "message": error_msg, + }, + ) return NetCommand(CMD_RETURN, 0, response, is_json=True) response = pydevd_base_schema.build_response(request) return NetCommand(CMD_RETURN, 0, response, is_json=True) - diff --git a/_pydevd_bundle/pydevd_referrers.py b/_pydevd_bundle/pydevd_referrers.py index c7e1bfaf4..9f8a29c4e 100644 --- a/_pydevd_bundle/pydevd_referrers.py +++ b/_pydevd_bundle/pydevd_referrers.py @@ -6,103 +6,107 @@ from _pydevd_bundle.pydevd_constants import IS_PY311_OR_GREATER -#=================================================================================================== +# =================================================================================================== # print_var_node -#=================================================================================================== +# =================================================================================================== def print_var_node(xml_node, stream): - name = xml_node.getAttribute('name') - value = xml_node.getAttribute('value') - val_type = xml_node.getAttribute('type') + name = xml_node.getAttribute("name") + value = xml_node.getAttribute("value") + val_type = xml_node.getAttribute("type") - found_as = xml_node.getAttribute('found_as') - stream.write('Name: ') + found_as = xml_node.getAttribute("found_as") + stream.write("Name: ") stream.write(unquote_plus(name)) - stream.write(', Value: ') + stream.write(", Value: ") stream.write(unquote_plus(value)) - stream.write(', Type: ') + stream.write(", Type: ") stream.write(unquote_plus(val_type)) if found_as: - stream.write(', Found as: %s' % (unquote_plus(found_as),)) - stream.write('\n') + stream.write(", Found as: %s" % (unquote_plus(found_as),)) + stream.write("\n") -#=================================================================================================== +# =================================================================================================== # print_referrers -#=================================================================================================== +# =================================================================================================== def print_referrers(obj, stream=None): if stream is None: stream = sys.stdout result = get_referrer_info(obj) from xml.dom.minidom import parseString + dom = parseString(result) - xml = dom.getElementsByTagName('xml')[0] + xml = dom.getElementsByTagName("xml")[0] for node in xml.childNodes: if node.nodeType == node.TEXT_NODE: continue - if node.localName == 'for': - stream.write('Searching references for: ') + if node.localName == "for": + stream.write("Searching references for: ") for child in node.childNodes: if child.nodeType == node.TEXT_NODE: continue print_var_node(child, stream) - elif node.localName == 'var': - stream.write('Referrer found: ') + elif node.localName == "var": + stream.write("Referrer found: ") print_var_node(node, stream) else: - sys.stderr.write('Unhandled node: %s\n' % (node,)) + sys.stderr.write("Unhandled node: %s\n" % (node,)) return result -#=================================================================================================== +# =================================================================================================== # get_referrer_info -#=================================================================================================== +# =================================================================================================== def get_referrer_info(searched_obj): DEBUG = 0 if DEBUG: - sys.stderr.write('Getting referrers info.\n') + sys.stderr.write("Getting referrers info.\n") try: try: if searched_obj is None: - ret = ['\n'] - - ret.append('\n') - ret.append(pydevd_xml.var_to_xml( - searched_obj, - 'Skipping getting referrers for None', - additional_in_xml=' id="%s"' % (id(searched_obj),))) - ret.append('\n') - ret.append('') - ret = ''.join(ret) + ret = ["\n"] + + ret.append("\n") + ret.append( + pydevd_xml.var_to_xml( + searched_obj, "Skipping getting referrers for None", additional_in_xml=' id="%s"' % (id(searched_obj),) + ) + ) + ret.append("\n") + ret.append("") + ret = "".join(ret) return ret obj_id = id(searched_obj) try: if DEBUG: - sys.stderr.write('Getting referrers...\n') + sys.stderr.write("Getting referrers...\n") import gc + referrers = gc.get_referrers(searched_obj) except: pydev_log.exception() - ret = ['\n'] - - ret.append('\n') - ret.append(pydevd_xml.var_to_xml( - searched_obj, - 'Exception raised while trying to get_referrers.', - additional_in_xml=' id="%s"' % (id(searched_obj),))) - ret.append('\n') - ret.append('') - ret = ''.join(ret) + ret = ["\n"] + + ret.append("\n") + ret.append( + pydevd_xml.var_to_xml( + searched_obj, "Exception raised while trying to get_referrers.", additional_in_xml=' id="%s"' % (id(searched_obj),) + ) + ) + ret.append("\n") + ret.append("") + ret = "".join(ret) return ret if DEBUG: - sys.stderr.write('Found %s referrers.\n' % (len(referrers),)) + sys.stderr.write("Found %s referrers.\n" % (len(referrers),)) curr_frame = sys._getframe() frame_type = type(curr_frame) @@ -111,20 +115,18 @@ def get_referrer_info(searched_obj): ignore_frames = {} # Should be a set, but it's not available on all python versions. while curr_frame is not None: - if basename(curr_frame.f_code.co_filename).startswith('pydev'): + if basename(curr_frame.f_code.co_filename).startswith("pydev"): ignore_frames[curr_frame] = 1 curr_frame = curr_frame.f_back - ret = ['\n'] + ret = ["\n"] - ret.append('\n') + ret.append("\n") if DEBUG: sys.stderr.write('Searching Referrers of obj with id="%s"\n' % (obj_id,)) - ret.append(pydevd_xml.var_to_xml( - searched_obj, - 'Referrers of obj with id="%s"' % (obj_id,))) - ret.append('\n') + ret.append(pydevd_xml.var_to_xml(searched_obj, 'Referrers of obj with id="%s"' % (obj_id,))) + ret.append("\n") curr_frame = sys._getframe() all_objects = None @@ -147,10 +149,10 @@ def get_referrer_info(searched_obj): representation = str(r_type) - found_as = '' + found_as = "" if r_type == frame_type: if DEBUG: - sys.stderr.write('Found frame referrer: %r\n' % (r,)) + sys.stderr.write("Found frame referrer: %r\n" % (r,)) for key, val in r.f_locals.items(): if val is searched_obj: found_as = key @@ -158,14 +160,14 @@ def get_referrer_info(searched_obj): elif r_type == dict: if DEBUG: - sys.stderr.write('Found dict referrer: %r\n' % (r,)) + sys.stderr.write("Found dict referrer: %r\n" % (r,)) # Try to check if it's a value in the dict (and under which key it was found) for key, val in r.items(): if val is searched_obj: found_as = key if DEBUG: - sys.stderr.write(' Found as %r in dict\n' % (found_as,)) + sys.stderr.write(" Found as %r in dict\n" % (found_as,)) break # Ok, there's one annoying thing: many times we find it in a dict from an instance, @@ -176,7 +178,7 @@ def get_referrer_info(searched_obj): for x in all_objects: try: - if getattr(x, '__dict__', None) is r: + if getattr(x, "__dict__", None) is r: r = x r_type = type(x) r_id = str(id(r)) @@ -187,13 +189,13 @@ def get_referrer_info(searched_obj): elif r_type in (tuple, list): if DEBUG: - sys.stderr.write('Found tuple referrer: %r\n' % (r,)) + sys.stderr.write("Found tuple referrer: %r\n" % (r,)) for i, x in enumerate(r): if x is searched_obj: - found_as = '%s[%s]' % (r_type.__name__, i) + found_as = "%s[%s]" % (r_type.__name__, i) if DEBUG: - sys.stderr.write(' Found as %s in tuple: \n' % (found_as,)) + sys.stderr.write(" Found as %s in tuple: \n" % (found_as,)) break elif IS_PY311_OR_GREATER: @@ -202,16 +204,16 @@ def get_referrer_info(searched_obj): # handling is a bit easier (we don't need the workaround from the dict # case to find the actual instance, we just need to find the attribute name). if DEBUG: - sys.stderr.write('Found dict referrer: %r\n' % (r,)) + sys.stderr.write("Found dict referrer: %r\n" % (r,)) - dct = getattr(r, '__dict__', None) + dct = getattr(r, "__dict__", None) if dct: # Try to check if it's a value in the dict (and under which key it was found) for key, val in dct.items(): if val is searched_obj: found_as = key if DEBUG: - sys.stderr.write(' Found as %r in object instance\n' % (found_as,)) + sys.stderr.write(" Found as %r in object instance\n" % (found_as,)) break if found_as: @@ -219,13 +221,10 @@ def get_referrer_info(searched_obj): found_as = str(found_as) found_as = ' found_as="%s"' % (pydevd_xml.make_valid_xml_value(found_as),) - ret.append(pydevd_xml.var_to_xml( - r, - representation, - additional_in_xml=' id="%s"%s' % (r_id, found_as))) + ret.append(pydevd_xml.var_to_xml(r, representation, additional_in_xml=' id="%s"%s' % (r_id, found_as))) finally: if DEBUG: - sys.stderr.write('Done searching for references.\n') + sys.stderr.write("Done searching for references.\n") # If we have any exceptions, don't keep dangling references from this frame to any of our objects. all_objects = None @@ -239,19 +238,15 @@ def get_referrer_info(searched_obj): ignore_frames = None except: pydev_log.exception() - ret = ['\n'] - - ret.append('\n') - ret.append(pydevd_xml.var_to_xml( - searched_obj, - 'Error getting referrers for:', - additional_in_xml=' id="%s"' % (id(searched_obj),))) - ret.append('\n') - ret.append('') - ret = ''.join(ret) + ret = ["\n"] + + ret.append("\n") + ret.append(pydevd_xml.var_to_xml(searched_obj, "Error getting referrers for:", additional_in_xml=' id="%s"' % (id(searched_obj),))) + ret.append("\n") + ret.append("") + ret = "".join(ret) return ret - ret.append('') - ret = ''.join(ret) + ret.append("") + ret = "".join(ret) return ret - diff --git a/_pydevd_bundle/pydevd_reload.py b/_pydevd_bundle/pydevd_reload.py index 507e73be2..60131a7cc 100644 --- a/_pydevd_bundle/pydevd_reload.py +++ b/_pydevd_bundle/pydevd_reload.py @@ -118,8 +118,8 @@ def write_err(*args): for a in args: new_lst.append(str(a)) - msg = ' '.join(new_lst) - s = 'code reload: %s\n' % (msg,) + msg = " ".join(new_lst) + s = "code reload: %s\n" % (msg,) cmd = py_db.cmd_factory.make_io_message(s, 2) if py_db.writer is not None: py_db.writer.add_command(cmd) @@ -143,21 +143,21 @@ def notify_error(*args): write_err(*args) -#======================================================================================================================= +# ======================================================================================================================= # code_objects_equal -#======================================================================================================================= +# ======================================================================================================================= def code_objects_equal(code0, code1): for d in dir(code0): - if d.startswith('_') or 'line' in d or d in ('replace', 'co_positions', 'co_qualname'): + if d.startswith("_") or "line" in d or d in ("replace", "co_positions", "co_qualname"): continue if getattr(code0, d) != getattr(code1, d): return False return True -#======================================================================================================================= +# ======================================================================================================================= # xreload -#======================================================================================================================= +# ======================================================================================================================= def xreload(mod): """Reload a module in place, updating classes, methods and functions. @@ -172,6 +172,7 @@ def xreload(mod): pydevd_dont_trace.clear_trace_filter_cache() return found_change + # This isn't actually used... Initially I planned to reload variables which are immutable on the # namespace, but this can destroy places where we're saving state, which may not be what we want, # so, we're being conservative and giving the user hooks if he wants to do a reload. @@ -186,11 +187,10 @@ def xreload(mod): # immutable_types = tuple(immutable_types) -#======================================================================================================================= +# ======================================================================================================================= # Reload -#======================================================================================================================= +# ======================================================================================================================= class Reload: - def __init__(self, mod, mod_name=None, mod_filename=None): self.mod = mod if mod_name: @@ -229,11 +229,11 @@ def apply(self): if self.mod_name: new_namespace["__name__"] = self.mod_name - if new_namespace["__name__"] == '__main__': + if new_namespace["__name__"] == "__main__": # We do this because usually the __main__ starts-up the program, guarded by # the if __name__ == '__main__', but we don't want to start the program again # on a reload. - new_namespace["__name__"] = '__main_reloaded__' + new_namespace["__name__"] = "__main_reloaded__" execfile(self.mod_filename, new_namespace, new_namespace) # Now we get to the hard part @@ -242,7 +242,7 @@ def apply(self): # Create new tokens (note: not deleting existing) for name in newnames - oldnames: - notify_info0('Added:', name, 'to namespace') + notify_info0("Added:", name, "to namespace") self.found_change = True modns[name] = new_namespace[name] @@ -261,13 +261,13 @@ def apply(self): def _handle_namespace(self, namespace, is_class_namespace=False): on_finish = None if is_class_namespace: - xreload_after_update = getattr(namespace, '__xreload_after_reload_update__', None) + xreload_after_update = getattr(namespace, "__xreload_after_reload_update__", None) if xreload_after_update is not None: self.found_change = True on_finish = lambda: xreload_after_update() - elif '__xreload_after_reload_update__' in namespace: - xreload_after_update = namespace['__xreload_after_reload_update__'] + elif "__xreload_after_reload_update__" in namespace: + xreload_after_update = namespace["__xreload_after_reload_update__"] self.found_change = True on_finish = lambda: xreload_after_update(namespace) @@ -285,15 +285,15 @@ def _update(self, namespace, name, oldobj, newobj, is_class_namespace=False): newobj: the object used as the source for the update """ try: - notify_info2('Updating: ', oldobj) + notify_info2("Updating: ", oldobj) if oldobj is newobj: # Probably something imported return if type(oldobj) is not type(newobj): # Cop-out: if the type changed, give up - if name not in ('__builtins__',): - notify_error('Type of: %s (old: %s != new: %s) changed... Skipping.' % (name, type(oldobj), type(newobj))) + if name not in ("__builtins__",): + notify_error("Type of: %s (old: %s != new: %s) changed... Skipping." % (name, type(oldobj), type(newobj))) return if isinstance(newobj, types.FunctionType): @@ -312,7 +312,7 @@ def _update(self, namespace, name, oldobj, newobj, is_class_namespace=False): self._update_staticmethod(oldobj, newobj) return - if hasattr(types, 'ClassType'): + if hasattr(types, "ClassType"): classtype = (types.ClassType, type) # object is not instance of types.ClassType. else: classtype = type @@ -322,7 +322,7 @@ def _update(self, namespace, name, oldobj, newobj, is_class_namespace=False): return # New: dealing with metaclasses. - if hasattr(newobj, '__metaclass__') and hasattr(newobj, '__class__') and newobj.__metaclass__ == newobj.__class__: + if hasattr(newobj, "__metaclass__") and hasattr(newobj, "__class__") and newobj.__metaclass__ == newobj.__class__: self._update_class(oldobj, newobj) return @@ -331,13 +331,13 @@ def _update(self, namespace, name, oldobj, newobj, is_class_namespace=False): # as even doing a comparison may break things -- see: https://github.com/microsoft/debugpy/issues/615). xreload_old_new = None if is_class_namespace: - xreload_old_new = getattr(namespace, '__xreload_old_new__', None) + xreload_old_new = getattr(namespace, "__xreload_old_new__", None) if xreload_old_new is not None: self.found_change = True xreload_old_new(name, oldobj, newobj) - elif '__xreload_old_new__' in namespace: - xreload_old_new = namespace['__xreload_old_new__'] + elif "__xreload_old_new__" in namespace: + xreload_old_new = namespace["__xreload_old_new__"] xreload_old_new(namespace, name, oldobj, newobj) self.found_change = True @@ -346,7 +346,7 @@ def _update(self, namespace, name, oldobj, newobj, is_class_namespace=False): # notify_info0('%s NOT updated. Create __xreload_old_new__(name, old, new) for custom reload' % (name,)) except: - notify_error('Exception found when updating %s. Proceeding for other items.' % (name,)) + notify_error("Exception found when updating %s. Proceeding for other items." % (name,)) pydev_log.exception() # All of the following functions have the same signature as _update() @@ -358,15 +358,15 @@ def _update_function(self, oldfunc, newfunc): try: newfunc.__code__ - attr_name = '__code__' + attr_name = "__code__" except AttributeError: newfunc.func_code - attr_name = 'func_code' + attr_name = "func_code" old_code = getattr(oldfunc, attr_name) new_code = getattr(newfunc, attr_name) if not code_objects_equal(old_code, new_code): - notify_info0('Updated function code:', oldfunc) + notify_info0("Updated function code:", oldfunc) setattr(oldfunc, attr_name, new_code) self.found_change = True @@ -380,9 +380,9 @@ def _update_function(self, oldfunc, newfunc): def _update_method(self, oldmeth, newmeth): """Update a method object.""" # XXX What if im_func is not a function? - if hasattr(oldmeth, 'im_func') and hasattr(newmeth, 'im_func'): + if hasattr(oldmeth, "im_func") and hasattr(newmeth, "im_func"): self._update(None, None, oldmeth.im_func, newmeth.im_func) - elif hasattr(oldmeth, '__func__') and hasattr(newmeth, '__func__'): + elif hasattr(oldmeth, "__func__") and hasattr(newmeth, "__func__"): self._update(None, None, oldmeth.__func__, newmeth.__func__) return oldmeth @@ -396,7 +396,7 @@ def _update_class(self, oldclass, newclass): for name in newnames - oldnames: setattr(oldclass, name, newdict[name]) - notify_info0('Added:', name, 'to', oldclass) + notify_info0("Added:", name, "to", oldclass) self.found_change = True # Note: not removing old things... @@ -404,13 +404,13 @@ def _update_class(self, oldclass, newclass): # notify_info('Removed:', name, 'from', oldclass) # delattr(oldclass, name) - for name in (oldnames & newnames) - set(['__dict__', '__doc__']): + for name in (oldnames & newnames) - set(["__dict__", "__doc__"]): self._update(oldclass, name, olddict[name], newdict[name], is_class_namespace=True) - old_bases = getattr(oldclass, '__bases__', None) - new_bases = getattr(newclass, '__bases__', None) + old_bases = getattr(oldclass, "__bases__", None) + new_bases = getattr(newclass, "__bases__", None) if str(old_bases) != str(new_bases): - notify_error('Changing the hierarchy of a class is not supported. %s may be inconsistent.' % (oldclass,)) + notify_error("Changing the hierarchy of a class is not supported. %s may be inconsistent." % (oldclass,)) self._handle_namespace(oldclass, is_class_namespace=True) diff --git a/_pydevd_bundle/pydevd_resolver.py b/_pydevd_bundle/pydevd_resolver.py index 90e313fa6..20a7351a9 100644 --- a/_pydevd_bundle/pydevd_resolver.py +++ b/_pydevd_bundle/pydevd_resolver.py @@ -5,18 +5,24 @@ from os.path import basename from functools import partial -from _pydevd_bundle.pydevd_constants import IS_PY36_OR_GREATER, \ - MethodWrapperType, RETURN_VALUES_DICT, DebugInfoHolder, IS_PYPY, GENERATED_LEN_ATTR_NAME +from _pydevd_bundle.pydevd_constants import ( + IS_PY36_OR_GREATER, + MethodWrapperType, + RETURN_VALUES_DICT, + DebugInfoHolder, + IS_PYPY, + GENERATED_LEN_ATTR_NAME, +) from _pydevd_bundle.pydevd_safe_repr import SafeRepr from _pydevd_bundle import pydevd_constants -TOO_LARGE_MSG = 'Maximum number of items (%s) reached. To show more items customize the value of the PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS environment variable.' -TOO_LARGE_ATTR = 'Unable to handle:' +TOO_LARGE_MSG = "Maximum number of items (%s) reached. To show more items customize the value of the PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS environment variable." +TOO_LARGE_ATTR = "Unable to handle:" -#======================================================================================================================= +# ======================================================================================================================= # UnableToResolveVariableException -#======================================================================================================================= +# ======================================================================================================================= class UnableToResolveVariableException(Exception): pass @@ -31,20 +37,20 @@ class UnableToResolveVariableException(Exception): except: pass -#======================================================================================================================= +# ======================================================================================================================= # See: pydevd_extension_api module for resolver interface -#======================================================================================================================= +# ======================================================================================================================= def sorted_attributes_key(attr_name): - if attr_name.startswith('__'): - if attr_name.endswith('__'): + if attr_name.startswith("__"): + if attr_name.endswith("__"): # __ double under before and after __ return (3, attr_name) else: # __ double under before return (2, attr_name) - elif attr_name.startswith('_'): + elif attr_name.startswith("_"): # _ single under return (1, attr_name) else: @@ -52,13 +58,13 @@ def sorted_attributes_key(attr_name): return (0, attr_name) -#======================================================================================================================= +# ======================================================================================================================= # DefaultResolver -#======================================================================================================================= +# ======================================================================================================================= class DefaultResolver: - ''' - DefaultResolver is the class that'll actually resolve how to show some variable. - ''' + """ + DefaultResolver is the class that'll actually resolve how to show some variable. + """ def resolve(self, var, attribute): return getattr(var, attribute) @@ -71,9 +77,9 @@ def get_contents_debug_adapter_protocol(self, obj, fmt=None): lst = sorted(dct.items(), key=lambda tup: sorted_attributes_key(tup[0])) if used___dict__: - eval_name = '.__dict__[%s]' + eval_name = ".__dict__[%s]" else: - eval_name = '.%s' + eval_name = ".%s" ret = [] for attr_name, attr_value in lst: @@ -93,8 +99,7 @@ def _get_jy_dictionary(self, obj): found = java.util.HashMap() original = obj - if hasattr_checked(obj, '__class__') and obj.__class__ == java.lang.Class: - + if hasattr_checked(obj, "__class__") and obj.__class__ == java.lang.Class: # get info about superclasses classes = [] classes.append(obj) @@ -111,7 +116,6 @@ def _get_jy_dictionary(self, obj): # now is the time when we actually get info on the declared methods and fields for obj in classes: - declaredMethods = obj.getDeclaredMethods() declaredFields = obj.getDeclaredFields() for i in range(len(declaredMethods)): @@ -151,16 +155,16 @@ def get_names(self, var): except Exception: names = [] if not names: - if hasattr_checked(var, '__dict__'): + if hasattr_checked(var, "__dict__"): names = list(var.__dict__) used___dict__ = True return names, used___dict__ def _get_py_dictionary(self, var, names=None, used___dict__=False): - ''' + """ :return tuple(names, used___dict__), where used___dict__ means we have to access using obj.__dict__[name] instead of getattr(obj, name) - ''' + """ # On PyPy we never show functions. This is because of a corner case where PyPy becomes # absurdly slow -- it takes almost half a second to introspect a single numpy function (so, @@ -183,7 +187,7 @@ def _get_py_dictionary(self, var, names=None, used___dict__=False): try: name_as_str = name if name_as_str.__class__ != str: - name_as_str = '%r' % (name_as_str,) + name_as_str = "%r" % (name_as_str,) if not used___dict__: attr = getattr(var, name) @@ -209,7 +213,6 @@ def _get_py_dictionary(self, var, names=None, used___dict__=False): class DAPGrouperResolver: - def get_contents_debug_adapter_protocol(self, obj, fmt=None): return obj.get_contents_debug_adapter_protocol() @@ -218,10 +221,10 @@ def get_contents_debug_adapter_protocol(self, obj, fmt=None): def _does_obj_repr_evaluate_to_obj(obj): - ''' + """ If obj is an object where evaluating its representation leads to the same object, return True, otherwise, return False. - ''' + """ try: if isinstance(obj, tuple): for o in obj: @@ -234,18 +237,17 @@ def _does_obj_repr_evaluate_to_obj(obj): return False -#======================================================================================================================= +# ======================================================================================================================= # DictResolver -#======================================================================================================================= +# ======================================================================================================================= class DictResolver: - sort_keys = not IS_PY36_OR_GREATER def resolve(self, dct, key): if key in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR): return None - if '(' not in key: + if "(" not in key: # we have to treat that because the dict resolver is also used to directly resolve the global and local # scopes (which already have the items directly) try: @@ -255,7 +257,7 @@ def resolve(self, dct, key): # ok, we have to iterate over the items to find the one that matches the id, because that's the only way # to actually find the reference from the string we have before. - expected_id = int(key.split('(')[-1][:-1]) + expected_id = int(key.split("(")[-1][:-1]) for key, val in dct.items(): if id(key) == expected_id: return val @@ -264,17 +266,17 @@ def resolve(self, dct, key): def key_to_str(self, key, fmt=None): if fmt is not None: - if fmt.get('hex', False): + if fmt.get("hex", False): safe_repr = SafeRepr() safe_repr.convert_to_hex = True return safe_repr(key) - return '%r' % (key,) + return "%r" % (key,) def init_dict(self): return {} def get_contents_debug_adapter_protocol(self, dct, fmt=None): - ''' + """ This method is to be used in the case where the variables are all saved by its id (and as such don't need to have the `resolve` method called later on, so, keys don't need to embed the reference in the key). @@ -282,7 +284,7 @@ def get_contents_debug_adapter_protocol(self, dct, fmt=None): Note that the return should be ordered. :return list(tuple(name:str, value:object, evaluateName:str)) - ''' + """ ret = [] i = 0 @@ -299,12 +301,12 @@ def get_contents_debug_adapter_protocol(self, dct, fmt=None): # If the key would be a duplicate, add the key id (otherwise # VSCode won't show all keys correctly). # See: https://github.com/microsoft/debugpy/issues/148 - key_as_str = '%s (id: %s)' % (key_as_str, id(key)) + key_as_str = "%s (id: %s)" % (key_as_str, id(key)) found_representations.add(key_as_str) if _does_obj_repr_evaluate_to_obj(key): s = self.key_to_str(key) # do not format the key - eval_key_str = '[%s]' % (s,) + eval_key_str = "[%s]" % (s,) else: eval_key_str = None ret.append((key_as_str, val, eval_key_str)) @@ -321,7 +323,7 @@ def get_contents_debug_adapter_protocol(self, dct, fmt=None): if self.sort_keys: ret = sorted(ret, key=lambda tup: sorted_attributes_key(tup[0])) - ret.append((GENERATED_LEN_ATTR_NAME, len(dct), partial(_apply_evaluate_name, evaluate_name='len(%s)'))) + ret.append((GENERATED_LEN_ATTR_NAME, len(dct), partial(_apply_evaluate_name, evaluate_name="len(%s)"))) return ret def get_dictionary(self, dct): @@ -331,7 +333,7 @@ def get_dictionary(self, dct): for key, val in dct.items(): i += 1 # we need to add the id because otherwise we cannot find the real object to get its contents later on. - key = '%s (%s)' % (self.key_to_str(key), id(key)) + key = "%s (%s)" % (self.key_to_str(key), id(key)) ret[key] = val if i >= pydevd_constants.PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS: ret[TOO_LARGE_ATTR] = TOO_LARGE_MSG % (pydevd_constants.PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS,) @@ -349,7 +351,6 @@ def _apply_evaluate_name(parent_name, evaluate_name): class MoreItemsRange: - def __init__(self, value, from_i, to_i): self.value = value self.from_i = from_i @@ -359,13 +360,13 @@ def get_contents_debug_adapter_protocol(self, _self, fmt=None): l = len(self.value) ret = [] - format_str = '%0' + str(int(len(str(l - 1)))) + 'd' - if fmt is not None and fmt.get('hex', False): - format_str = '0x%0' + str(int(len(hex(l).lstrip('0x')))) + 'x' + format_str = "%0" + str(int(len(str(l - 1)))) + "d" + if fmt is not None and fmt.get("hex", False): + format_str = "0x%0" + str(int(len(hex(l).lstrip("0x")))) + "x" - for i, item in enumerate(self.value[self.from_i:self.to_i]): + for i, item in enumerate(self.value[self.from_i : self.to_i]): i += self.from_i - ret.append((format_str % i, item, '[%s]' % i)) + ret.append((format_str % i, item, "[%s]" % i)) return ret def get_dictionary(self, _self, fmt=None): @@ -375,25 +376,23 @@ def get_dictionary(self, _self, fmt=None): return dct def resolve(self, attribute): - ''' + """ :param var: that's the original object we're dealing with. :param attribute: that's the key to resolve -- either the dict key in get_dictionary or the name in the dap protocol. - ''' + """ return self.value[int(attribute)] def __eq__(self, o): - return isinstance(o, MoreItemsRange) and self.value is o.value and \ - self.from_i == o.from_i and self.to_i == o.to_i + return isinstance(o, MoreItemsRange) and self.value is o.value and self.from_i == o.from_i and self.to_i == o.to_i def __str__(self): - return '[%s:%s]' % (self.from_i, self.to_i) + return "[%s:%s]" % (self.from_i, self.to_i) __repr__ = __str__ class MoreItems: - def __init__(self, value, handled_items): self.value = value self.handled_items = handled_items @@ -424,7 +423,7 @@ def get_dictionary(self, _self, fmt=None): return dct def resolve(self, attribute): - from_i, to_i = attribute[1:-1].split(':') + from_i, to_i = attribute[1:-1].split(":") from_i = int(from_i) to_i = int(to_i) return MoreItemsRange(self.value, from_i, to_i) @@ -433,15 +432,15 @@ def __eq__(self, o): return isinstance(o, MoreItems) and self.value is o.value def __str__(self): - return '...' + return "..." __repr__ = __str__ class ForwardInternalResolverToObject: - ''' + """ To be used when we provide some internal object that'll actually do the resolution. - ''' + """ def get_contents_debug_adapter_protocol(self, obj, fmt=None): return obj.get_contents_debug_adapter_protocol(fmt) @@ -454,25 +453,24 @@ def resolve(self, var, attribute): class TupleResolver: # to enumerate tuples and lists - def resolve(self, var, attribute): - ''' + """ :param var: that's the original object we're dealing with. :param attribute: that's the key to resolve -- either the dict key in get_dictionary or the name in the dap protocol. - ''' + """ if attribute in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR): return None try: return var[int(attribute)] except: - if attribute == 'more': + if attribute == "more": return MoreItems(var, pydevd_constants.PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS) return getattr(var, attribute) def get_contents_debug_adapter_protocol(self, lst, fmt=None): - ''' + """ This method is to be used in the case where the variables are all saved by its id (and as such don't need to have the `resolve` method called later on, so, keys don't need to embed the reference in the key). @@ -480,17 +478,17 @@ def get_contents_debug_adapter_protocol(self, lst, fmt=None): Note that the return should be ordered. :return list(tuple(name:str, value:object, evaluateName:str)) - ''' + """ lst_len = len(lst) ret = [] - format_str = '%0' + str(int(len(str(lst_len - 1)))) + 'd' - if fmt is not None and fmt.get('hex', False): - format_str = '0x%0' + str(int(len(hex(lst_len).lstrip('0x')))) + 'x' + format_str = "%0" + str(int(len(str(lst_len - 1)))) + "d" + if fmt is not None and fmt.get("hex", False): + format_str = "0x%0" + str(int(len(hex(lst_len).lstrip("0x")))) + "x" initial_expanded = pydevd_constants.PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS for i, item in enumerate(lst): - ret.append((format_str % i, item, '[%s]' % i)) + ret.append((format_str % i, item, "[%s]" % i)) if i >= initial_expanded - 1: if (lst_len - initial_expanded) < pydevd_constants.PYDEVD_CONTAINER_BUCKET_SIZE: @@ -500,7 +498,7 @@ def get_contents_debug_adapter_protocol(self, lst, fmt=None): else: # Multiple buckets item = MoreItems(lst, initial_expanded) - ret.append(('more', item, None)) + ret.append(("more", item, None)) break # Needed in case the class extends the built-in type and has some additional fields. @@ -508,16 +506,16 @@ def get_contents_debug_adapter_protocol(self, lst, fmt=None): if from_default_resolver: ret = from_default_resolver + ret - ret.append((GENERATED_LEN_ATTR_NAME, len(lst), partial(_apply_evaluate_name, evaluate_name='len(%s)'))) + ret.append((GENERATED_LEN_ATTR_NAME, len(lst), partial(_apply_evaluate_name, evaluate_name="len(%s)"))) return ret def get_dictionary(self, var, fmt={}): l = len(var) d = {} - format_str = '%0' + str(int(len(str(l - 1)))) + 'd' - if fmt is not None and fmt.get('hex', False): - format_str = '0x%0' + str(int(len(hex(l).lstrip('0x')))) + 'x' + format_str = "%0" + str(int(len(str(l - 1)))) + "d" + if fmt is not None and fmt.get("hex", False): + format_str = "0x%0" + str(int(len(hex(l).lstrip("0x")))) + "x" initial_expanded = pydevd_constants.PYDEVD_CONTAINER_INITIAL_EXPANDED_ITEMS for i, item in enumerate(var): @@ -525,7 +523,7 @@ def get_dictionary(self, var, fmt={}): if i >= initial_expanded - 1: item = MoreItems(var, initial_expanded) - d['more'] = item + d["more"] = item break # in case if the class extends built-in type and has some additional fields @@ -535,13 +533,13 @@ def get_dictionary(self, var, fmt={}): return d -#======================================================================================================================= +# ======================================================================================================================= # SetResolver -#======================================================================================================================= +# ======================================================================================================================= class SetResolver: - ''' - Resolves a set as dict id(object)->object - ''' + """ + Resolves a set as dict id(object)->object + """ def get_contents_debug_adapter_protocol(self, obj, fmt=None): ret = [] @@ -557,7 +555,7 @@ def get_contents_debug_adapter_protocol(self, obj, fmt=None): from_default_resolver = defaultResolver.get_contents_debug_adapter_protocol(obj, fmt=fmt) if from_default_resolver: ret = from_default_resolver + ret - ret.append((GENERATED_LEN_ATTR_NAME, len(obj), partial(_apply_evaluate_name, evaluate_name='len(%s)'))) + ret.append((GENERATED_LEN_ATTR_NAME, len(obj), partial(_apply_evaluate_name, evaluate_name="len(%s)"))) return ret def resolve(self, var, attribute): @@ -573,7 +571,7 @@ def resolve(self, var, attribute): if id(v) == attribute: return v - raise UnableToResolveVariableException('Unable to resolve %s in %s' % (attribute, var)) + raise UnableToResolveVariableException("Unable to resolve %s in %s" % (attribute, var)) def get_dictionary(self, var): d = {} @@ -609,11 +607,10 @@ def change_var_from_name(self, container, name, new_value): return None -#======================================================================================================================= +# ======================================================================================================================= # InstanceResolver -#======================================================================================================================= +# ======================================================================================================================= class InstanceResolver: - def resolve(self, var, attribute): field = var.__class__.getDeclaredField(attribute) field.setAccessible(True) @@ -634,13 +631,13 @@ def get_dictionary(self, obj): return ret -#======================================================================================================================= +# ======================================================================================================================= # JyArrayResolver -#======================================================================================================================= +# ======================================================================================================================= class JyArrayResolver: - ''' - This resolves a regular Object[] array from java - ''' + """ + This resolves a regular Object[] array from java + """ def resolve(self, var, attribute): if attribute == GENERATED_LEN_ATTR_NAME: @@ -651,24 +648,23 @@ def get_dictionary(self, obj): ret = {} for i in range(len(obj)): - ret[ i ] = obj[i] + ret[i] = obj[i] ret[GENERATED_LEN_ATTR_NAME] = len(obj) return ret -#======================================================================================================================= +# ======================================================================================================================= # MultiValueDictResolver -#======================================================================================================================= +# ======================================================================================================================= class MultiValueDictResolver(DictResolver): - def resolve(self, dct, key): if key in (GENERATED_LEN_ATTR_NAME, TOO_LARGE_ATTR): return None # ok, we have to iterate over the items to find the one that matches the id, because that's the only way # to actually find the reference from the string we have before. - expected_id = int(key.split('(')[-1][:-1]) + expected_id = int(key.split("(")[-1][:-1]) for key in list(dct.keys()): val = dct.getlist(key) if id(key) == expected_id: @@ -677,11 +673,10 @@ def resolve(self, dct, key): raise UnableToResolveVariableException() -#======================================================================================================================= +# ======================================================================================================================= # DjangoFormResolver -#======================================================================================================================= +# ======================================================================================================================= class DjangoFormResolver(DefaultResolver): - def get_dictionary(self, var, names=None): # Do not call self.errors because it is a property and has side effects. names, used___dict__ = self.get_names(var) @@ -701,53 +696,51 @@ def get_dictionary(self, var, names=None): return d -#======================================================================================================================= +# ======================================================================================================================= # DequeResolver -#======================================================================================================================= +# ======================================================================================================================= class DequeResolver(TupleResolver): - def get_dictionary(self, var): d = TupleResolver.get_dictionary(self, var) - d['maxlen'] = getattr(var, 'maxlen', None) + d["maxlen"] = getattr(var, "maxlen", None) return d -#======================================================================================================================= +# ======================================================================================================================= # OrderedDictResolver -#======================================================================================================================= +# ======================================================================================================================= class OrderedDictResolver(DictResolver): - sort_keys = False def init_dict(self): return OrderedDict() -#======================================================================================================================= +# ======================================================================================================================= # FrameResolver -#======================================================================================================================= +# ======================================================================================================================= class FrameResolver: - ''' + """ This resolves a frame. - ''' + """ def resolve(self, obj, attribute): - if attribute == '__internals__': + if attribute == "__internals__": return defaultResolver.get_dictionary(obj) - if attribute == 'stack': + if attribute == "stack": return self.get_frame_stack(obj) - if attribute == 'f_locals': + if attribute == "f_locals": return obj.f_locals return None def get_dictionary(self, obj): ret = {} - ret['__internals__'] = defaultResolver.get_dictionary(obj) - ret['stack'] = self.get_frame_stack(obj) - ret['f_locals'] = obj.f_locals + ret["__internals__"] = defaultResolver.get_dictionary(obj) + ret["stack"] = self.get_frame_stack(obj) + ret["f_locals"] = obj.f_locals return ret def get_frame_stack(self, frame): @@ -763,12 +756,12 @@ def get_frame_stack(self, frame): def get_frame_name(self, frame): if frame is None: - return 'None' + return "None" try: name = basename(frame.f_code.co_filename) - return 'frame: %s [%s:%s] id:%s' % (frame.f_code.co_name, name, frame.f_lineno, id(frame)) + return "frame: %s [%s:%s] id:%s" % (frame.f_code.co_name, name, frame.f_lineno, id(frame)) except: - return 'frame object' + return "frame object" defaultResolver = DefaultResolver() @@ -787,7 +780,6 @@ def get_frame_name(self, frame): class InspectStub: - def isbuiltin(self, _args): return False @@ -805,23 +797,23 @@ def get_var_scope(attr_name, attr_value, evaluate_name, handle_return_values): if attr_name.startswith("'"): if attr_name.endswith("'"): # i.e.: strings denote that it is a regular value in some container. - return '' + return "" else: i = attr_name.find("__' (") if i >= 0: # Handle attr_name such as: >>'__name__' (1732494379184)<< - attr_name = attr_name[1: i + 2] + attr_name = attr_name[1 : i + 2] if handle_return_values and attr_name == RETURN_VALUES_DICT: - return '' + return "" elif attr_name == GENERATED_LEN_ATTR_NAME: - return '' + return "" - if attr_name.startswith('__') and attr_name.endswith('__'): + if attr_name.startswith("__") and attr_name.endswith("__"): return DAPGrouper.SCOPE_SPECIAL_VARS - if attr_name.startswith('_') or attr_name.endswith('__'): + if attr_name.startswith("_") or attr_name.endswith("__"): return DAPGrouper.SCOPE_PROTECTED_VARS try: @@ -835,4 +827,4 @@ def get_var_scope(attr_name, attr_value, evaluate_name, handle_return_values): if DebugInfoHolder.DEBUG_TRACE_LEVEL > 0: pydev_log.exception() - return '' + return "" diff --git a/_pydevd_bundle/pydevd_runpy.py b/_pydevd_bundle/pydevd_runpy.py index 09b713f06..ba8f7afca 100644 --- a/_pydevd_bundle/pydevd_runpy.py +++ b/_pydevd_bundle/pydevd_runpy.py @@ -23,7 +23,8 @@ import os __all__ = [ - "run_module", "run_path", + "run_module", + "run_path", ] @@ -81,7 +82,6 @@ def __exit__(self, *args): class _ModifiedArgv0(object): - def __init__(self, value): self.value = value self._saved_value = self._sentinel = object() @@ -98,9 +98,7 @@ def __exit__(self, *args): # TODO: Replace these helpers with importlib._bootstrap_external functions. -def _run_code(code, run_globals, init_globals=None, - mod_name=None, mod_spec=None, - pkg_name=None, script_name=None): +def _run_code(code, run_globals, init_globals=None, mod_name=None, mod_spec=None, pkg_name=None, script_name=None): """Helper to run code in nominated namespace""" if init_globals is not None: run_globals.update(init_globals) @@ -114,26 +112,19 @@ def _run_code(code, run_globals, init_globals=None, cached = mod_spec.cached if pkg_name is None: pkg_name = mod_spec.parent - run_globals.update(__name__=mod_name, - __file__=fname, - __cached__=cached, - __doc__=None, - __loader__=loader, - __package__=pkg_name, - __spec__=mod_spec) + run_globals.update( + __name__=mod_name, __file__=fname, __cached__=cached, __doc__=None, __loader__=loader, __package__=pkg_name, __spec__=mod_spec + ) exec(code, run_globals) return run_globals -def _run_module_code(code, init_globals=None, - mod_name=None, mod_spec=None, - pkg_name=None, script_name=None): +def _run_module_code(code, init_globals=None, mod_name=None, mod_spec=None, pkg_name=None, script_name=None): """Helper to run code in new namespace with sys modified""" fname = script_name if mod_spec is None else mod_spec.origin with _TempModule(mod_name) as temp_module, _ModifiedArgv0(fname): mod_globals = temp_module.module.__dict__ - _run_code(code, mod_globals, init_globals, - mod_name, mod_spec, pkg_name, script_name) + _run_code(code, mod_globals, init_globals, mod_name, mod_spec, pkg_name, script_name) # Copy the globals of the temporary module, as they # may be cleared when the temporary module goes away return mod_globals.copy() @@ -152,17 +143,19 @@ def _get_module_details(mod_name, error=ImportError): # If the parent or higher ancestor package is missing, let the # error be raised by find_spec() below and then be caught. But do # not allow other errors to be caught. - if e.name is None or (e.name != pkg_name and - not pkg_name.startswith(e.name + ".")): + if e.name is None or (e.name != pkg_name and not pkg_name.startswith(e.name + ".")): raise # Warn if the module has already been imported under its normal name existing = sys.modules.get(mod_name) if existing is not None and not hasattr(existing, "__path__"): from warnings import warn - msg = "{mod_name!r} found in sys.modules after import of " \ - "package {pkg_name!r}, but prior to execution of " \ - "{mod_name!r}; this may result in unpredictable " \ + + msg = ( + "{mod_name!r} found in sys.modules after import of " + "package {pkg_name!r}, but prior to execution of " + "{mod_name!r}; this may result in unpredictable " "behaviour".format(mod_name=mod_name, pkg_name=pkg_name) + ) warn(RuntimeWarning(msg)) try: @@ -173,8 +166,7 @@ def _get_module_details(mod_name, error=ImportError): # pkgutil previously raised ImportError msg = "Error while finding module specification for {!r} ({}: {})" if mod_name.endswith(".py"): - msg += (f". Try using '{mod_name[:-3]}' instead of " - f"'{mod_name}' as the module name.") + msg += f". Try using '{mod_name[:-3]}' instead of " f"'{mod_name}' as the module name." raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex if spec is None: raise error("No module named %s" % mod_name) @@ -187,12 +179,10 @@ def _get_module_details(mod_name, error=ImportError): except error as e: if mod_name not in sys.modules: raise # No module loaded; being a package is irrelevant - raise error(("%s; %r is a package and cannot " + - "be directly executed") % (e, mod_name)) + raise error(("%s; %r is a package and cannot " + "be directly executed") % (e, mod_name)) loader = spec.loader if loader is None: - raise error("%r is a namespace package and cannot be executed" - % mod_name) + raise error("%r is a namespace package and cannot be executed" % mod_name) try: code = loader.get_code(mod_name) except ImportError as e: @@ -213,16 +203,16 @@ class _Error(Exception): def _run_module_as_main(mod_name, alter_argv=True): """Runs the designated module in the __main__ namespace - Note that the executed module will have full access to the - __main__ namespace. If this is not desirable, the run_module() - function should be used to run the module code in a fresh namespace. + Note that the executed module will have full access to the + __main__ namespace. If this is not desirable, the run_module() + function should be used to run the module code in a fresh namespace. - At the very least, these variables in __main__ will be overwritten: - __name__ - __file__ - __cached__ - __loader__ - __package__ + At the very least, these variables in __main__ will be overwritten: + __name__ + __file__ + __cached__ + __loader__ + __package__ """ try: if alter_argv or mod_name != "__main__": # i.e. -m switch @@ -235,15 +225,13 @@ def _run_module_as_main(mod_name, alter_argv=True): main_globals = sys.modules["__main__"].__dict__ if alter_argv: sys.argv[0] = mod_spec.origin - return _run_code(code, main_globals, None, - "__main__", mod_spec) + return _run_code(code, main_globals, None, "__main__", mod_spec) -def run_module(mod_name, init_globals=None, - run_name=None, alter_sys=False): +def run_module(mod_name, init_globals=None, run_name=None, alter_sys=False): """Execute a module's code without importing it - Returns the resulting top level namespace dictionary + Returns the resulting top level namespace dictionary """ mod_name, mod_spec, code = _get_module_details(mod_name) if run_name is None: @@ -267,8 +255,7 @@ def _get_main_module_details(error=ImportError): return _get_module_details(main_name) except ImportError as exc: if main_name in str(exc): - raise error("can't find %r module in %r" % - (main_name, sys.path[0])) from exc + raise error("can't find %r module in %r" % (main_name, sys.path[0])) from exc raise finally: sys.modules[main_name] = saved_main @@ -279,31 +266,33 @@ def _get_main_module_details(error=ImportError): except AttributeError: # Compatibility with Python 3.6/3.7 import tokenize + io_open_code = tokenize.open def _get_code_from_file(run_name, fname): # Check for a compiled file first from pkgutil import read_code + decoded_path = os.path.abspath(os.fsdecode(fname)) with io_open_code(decoded_path) as f: code = read_code(f) if code is None: # That didn't work, so try it as normal source code with io_open_code(decoded_path) as f: - code = compile(f.read(), fname, 'exec') + code = compile(f.read(), fname, "exec") return code, fname def run_path(path_name, init_globals=None, run_name=None): """Execute code located at the specified filesystem location - Returns the resulting top level namespace dictionary + Returns the resulting top level namespace dictionary - The file path may refer directly to a Python script (i.e. - one that could be directly executed with execfile) or else - it may refer to a zipfile or directory containing a top - level __main__.py script. + The file path may refer directly to a Python script (i.e. + one that could be directly executed with execfile) or else + it may refer to a zipfile or directory containing a top + level __main__.py script. """ if run_name is None: run_name = "" @@ -311,15 +300,14 @@ def run_path(path_name, init_globals=None, run_name=None): importer = pkgutil_get_importer(path_name) # Trying to avoid importing imp so as to not consume the deprecation warning. is_NullImporter = False - if type(importer).__module__ == 'imp': - if type(importer).__name__ == 'NullImporter': + if type(importer).__module__ == "imp": + if type(importer).__name__ == "NullImporter": is_NullImporter = True if isinstance(importer, type(None)) or is_NullImporter: # Not a valid sys.path entry, so run the code directly # execfile() doesn't help as we want to allow compiled files code, fname = _get_code_from_file(run_name, path_name) - return _run_module_code(code, init_globals, run_name, - pkg_name=pkg_name, script_name=fname) + return _run_module_code(code, init_globals, run_name, pkg_name=pkg_name, script_name=fname) else: # Finder is defined for path, so add it to # the start of sys.path @@ -332,11 +320,9 @@ def run_path(path_name, init_globals=None, run_name=None): # code. If we don't do this, a __loader__ attribute in the # existing __main__ module may prevent location of the new module. mod_name, mod_spec, code = _get_main_module_details() - with _TempModule(run_name) as temp_module, \ - _ModifiedArgv0(path_name): + with _TempModule(run_name) as temp_module, _ModifiedArgv0(path_name): mod_globals = temp_module.module.__dict__ - return _run_code(code, mod_globals, init_globals, - run_name, mod_spec, pkg_name).copy() + return _run_code(code, mod_globals, init_globals, run_name, mod_spec, pkg_name).copy() finally: try: sys.path.remove(path_name) diff --git a/_pydevd_bundle/pydevd_safe_repr.py b/_pydevd_bundle/pydevd_safe_repr.py index f1b64b753..bbb1b0bef 100644 --- a/_pydevd_bundle/pydevd_safe_repr.py +++ b/_pydevd_bundle/pydevd_safe_repr.py @@ -19,15 +19,14 @@ class SafeRepr(object): # String types are truncated to maxstring_outer when at the outer- # most level, and truncated to maxstring_inner characters inside # collections. - maxstring_outer = 2 ** 16 + maxstring_outer = 2**16 maxstring_inner = 30 string_types = (str, bytes) bytes = bytes - set_info = (set, '{', '}', False) - frozenset_info = (frozenset, 'frozenset({', '})', False) + set_info = (set, "{", "}", False) + frozenset_info = (frozenset, "frozenset({", "})", False) int_types = (int,) - long_iter_types = (list, tuple, bytearray, range, - dict, set, frozenset) + long_iter_types = (list, tuple, bytearray, range, dict, set, frozenset) # Collection types are recursively iterated for each limit in # maxcollection. @@ -37,52 +36,54 @@ class SafeRepr(object): # comma if there is only one element. (Using a sequence rather than a # mapping because we use isinstance() to determine the matching type.) collection_types = [ - (tuple, '(', ')', True), - (list, '[', ']', False), + (tuple, "(", ")", True), + (list, "[", "]", False), frozenset_info, set_info, ] try: from collections import deque - collection_types.append((deque, 'deque([', '])', False)) + + collection_types.append((deque, "deque([", "])", False)) except Exception: pass # type, prefix string, suffix string, item prefix string, # item key/value separator, item suffix string - dict_types = [(dict, '{', '}', '', ': ', '')] + dict_types = [(dict, "{", "}", "", ": ", "")] try: from collections import OrderedDict - dict_types.append((OrderedDict, 'OrderedDict([', '])', '(', ', ', ')')) + + dict_types.append((OrderedDict, "OrderedDict([", "])", "(", ", ", ")")) except Exception: pass # All other types are treated identically to strings, but using # different limits. - maxother_outer = 2 ** 16 + maxother_outer = 2**16 maxother_inner = 30 convert_to_hex = False raw_value = False def __call__(self, obj): - ''' + """ :param object obj: The object for which we want a representation. :return str: Returns bytes encoded as utf-8 on py2 and str on py3. - ''' + """ try: - return ''.join(self._repr(obj, 0)) + return "".join(self._repr(obj, 0)) except Exception: try: - return 'An exception was raised: %r' % sys.exc_info()[1] + return "An exception was raised: %r" % sys.exc_info()[1] except Exception: - return 'An exception was raised' + return "An exception was raised" def _repr(self, obj, level): - '''Returns an iterable of the parts in the final repr string.''' + """Returns an iterable of the parts in the final repr string.""" try: obj_repr = type(obj).__repr__ @@ -102,8 +103,7 @@ def has_obj_repr(t): for t, prefix, suffix, item_prefix, item_sep, item_suffix in self.dict_types: # noqa if isinstance(obj, t) and has_obj_repr(t): - return self._repr_dict(obj, level, prefix, suffix, - item_prefix, item_sep, item_suffix) + return self._repr_dict(obj, level, prefix, suffix, item_prefix, item_sep, item_suffix) for t in self.string_types: if isinstance(obj, t) and has_obj_repr(t): @@ -125,7 +125,7 @@ def _is_long_iter(self, obj, level=0): return len(obj) > self.maxstring_inner # If it's not an iterable (and not a string), it's fine. - if not hasattr(obj, '__iter__'): + if not hasattr(obj, "__iter__"): return False # If it's not an instance of these collection types then it @@ -148,8 +148,8 @@ def _is_long_iter(self, obj, level=0): # numpy and scipy collections (ndarray etc) have # self-truncating repr, so they're always safe. try: - module = type(obj).__module__.partition('.')[0] - if module in ('numpy', 'scipy'): + module = type(obj).__module__.partition(".")[0] + if module in ("numpy", "scipy"): return False except Exception: pass @@ -160,7 +160,7 @@ def _is_long_iter(self, obj, level=0): # It is too long if the length exceeds the limit, or any # of its elements are long iterables. - if hasattr(obj, '__len__'): + if hasattr(obj, "__len__"): try: size = len(obj) except Exception: @@ -174,23 +174,22 @@ def _is_long_iter(self, obj, level=0): # If anything breaks, assume the worst case. return True - def _repr_iter(self, obj, level, prefix, suffix, - comma_after_single_element=False): + def _repr_iter(self, obj, level, prefix, suffix, comma_after_single_element=False): yield prefix if level >= len(self.maxcollection): - yield '...' + yield "..." else: count = self.maxcollection[level] yield_comma = False for item in obj: if yield_comma: - yield ', ' + yield ", " yield_comma = True count -= 1 if count <= 0: - yield '...' + yield "..." break for p in self._repr(item, 100 if item is obj else level + 1): @@ -198,27 +197,26 @@ def _repr_iter(self, obj, level, prefix, suffix, else: if comma_after_single_element: if count == self.maxcollection[level] - 1: - yield ',' + yield "," yield suffix def _repr_long_iter(self, obj): try: length = hex(len(obj)) if self.convert_to_hex else len(obj) - obj_repr = '<%s, len() = %s>' % (type(obj).__name__, length) + obj_repr = "<%s, len() = %s>" % (type(obj).__name__, length) except Exception: try: - obj_repr = '<' + type(obj).__name__ + '>' + obj_repr = "<" + type(obj).__name__ + ">" except Exception: - obj_repr = '' + obj_repr = "" yield obj_repr - def _repr_dict(self, obj, level, prefix, suffix, - item_prefix, item_sep, item_suffix): + def _repr_dict(self, obj, level, prefix, suffix, item_prefix, item_sep, item_suffix): if not obj: yield prefix + suffix return if level >= len(self.maxcollection): - yield prefix + '...' + suffix + yield prefix + "..." + suffix return yield prefix @@ -238,12 +236,12 @@ def _repr_dict(self, obj, level, prefix, suffix, for key in sorted_keys: if yield_comma: - yield ', ' + yield ", " yield_comma = True count -= 1 if count <= 0: - yield '...' + yield "..." break yield item_prefix @@ -255,7 +253,7 @@ def _repr_dict(self, obj, level, prefix, suffix, try: item = obj[key] except Exception: - yield '' + yield "" else: for p in self._repr(item, 100 if item is obj else level + 1): yield p @@ -268,7 +266,7 @@ def _repr_str(self, obj, level): if self.raw_value: # For raw value retrieval, ignore all limits. if isinstance(obj, bytes): - yield obj.decode('latin-1') + yield obj.decode("latin-1") else: yield obj return @@ -304,32 +302,30 @@ def _repr_str(self, obj, level): part1 = obj[:left_count] part1 = repr(part1) - part1 = part1[:part1.rindex("'")] # Remove the last ' + part1 = part1[: part1.rindex("'")] # Remove the last ' part2 = obj[-right_count:] part2 = repr(part2) - part2 = part2[part2.index("'") + 1:] # Remove the first ' (and possibly u or b). + part2 = part2[part2.index("'") + 1 :] # Remove the first ' (and possibly u or b). yield part1 - yield '...' + yield "..." yield part2 except: # This shouldn't really happen, but let's play it safe. - pydev_log.exception('Error getting string representation to show.') - for part in self._repr_obj(obj, level, - self.maxother_inner, self.maxother_outer): + pydev_log.exception("Error getting string representation to show.") + for part in self._repr_obj(obj, level, self.maxother_inner, self.maxother_outer): yield part def _repr_other(self, obj, level): - return self._repr_obj(obj, level, - self.maxother_inner, self.maxother_outer) + return self._repr_obj(obj, level, self.maxother_inner, self.maxother_outer) def _repr_obj(self, obj, level, limit_inner, limit_outer): try: if self.raw_value: # For raw value retrieval, ignore all limits. if isinstance(obj, bytes): - yield obj.decode('latin-1') + yield obj.decode("latin-1") return try: @@ -339,7 +335,7 @@ def _repr_obj(self, obj, level, limit_inner, limit_outer): return else: # Map bytes to Unicode codepoints with same values. - yield mv.tobytes().decode('latin-1') + yield mv.tobytes().decode("latin-1") return elif self.convert_to_hex and isinstance(obj, self.int_types): obj_repr = hex(obj) @@ -350,9 +346,9 @@ def _repr_obj(self, obj, level, limit_inner, limit_outer): obj_repr = object.__repr__(obj) except Exception: try: - obj_repr = '' # noqa + obj_repr = "" # noqa except Exception: - obj_repr = '' + obj_repr = "" limit = limit_inner if level > 0 else limit_outer @@ -366,7 +362,7 @@ def _repr_obj(self, obj, level, limit_inner, limit_outer): left_count, right_count = max(1, int(2 * limit / 3)), max(1, int(limit / 3)) # noqa yield obj_repr[:left_count] - yield '...' + yield "..." yield obj_repr[-right_count:] def _convert_to_unicode_or_bytes_repr(self, obj_repr): @@ -377,7 +373,7 @@ def _bytes_as_unicode_if_possible(self, obj_repr): # locale.getpreferredencoding() and 'utf-8). If no encoding can decode # the input, we return the original bytes. try_encodings = [] - encoding = self.sys_stdout_encoding or getattr(sys.stdout, 'encoding', '') + encoding = self.sys_stdout_encoding or getattr(sys.stdout, "encoding", "") if encoding: try_encodings.append(encoding.lower()) @@ -387,8 +383,8 @@ def _bytes_as_unicode_if_possible(self, obj_repr): if preferred_encoding not in try_encodings: try_encodings.append(preferred_encoding) - if 'utf-8' not in try_encodings: - try_encodings.append('utf-8') + if "utf-8" not in try_encodings: + try_encodings.append("utf-8") for encoding in try_encodings: try: diff --git a/_pydevd_bundle/pydevd_save_locals.py b/_pydevd_bundle/pydevd_save_locals.py index c6bc37542..023370b69 100644 --- a/_pydevd_bundle/pydevd_save_locals.py +++ b/_pydevd_bundle/pydevd_save_locals.py @@ -40,13 +40,14 @@ def make_save_locals_impl(): lock being taken in different order in different threads. """ try: - if '__pypy__' in sys.builtin_module_names: + if "__pypy__" in sys.builtin_module_names: import __pypy__ # @UnresolvedImport + save_locals = __pypy__.locals_to_fast except: pass else: - if '__pypy__' in sys.builtin_module_names: + if "__pypy__" in sys.builtin_module_names: def save_locals_pypy_impl(frame): save_locals(frame) @@ -55,6 +56,7 @@ def save_locals_pypy_impl(frame): try: import ctypes + locals_to_fast = ctypes.pythonapi.PyFrame_LocalsToFast except: pass diff --git a/_pydevd_bundle/pydevd_signature.py b/_pydevd_bundle/pydevd_signature.py index 3877e6222..9664364f0 100644 --- a/_pydevd_bundle/pydevd_signature.py +++ b/_pydevd_bundle/pydevd_signature.py @@ -14,7 +14,6 @@ class Signature(object): - def __init__(self, file, name): self.file = file self.name = name @@ -42,37 +41,36 @@ def __str__(self): return "%s %s(%s)" % (self.file, self.name, ", ".join(self.args_str)) -def get_type_of_value(value, ignore_module_name=('__main__', '__builtin__', 'builtins'), recursive=False): +def get_type_of_value(value, ignore_module_name=("__main__", "__builtin__", "builtins"), recursive=False): tp = type(value) class_name = tp.__name__ - if class_name == 'instance': # old-style classes + if class_name == "instance": # old-style classes tp = value.__class__ class_name = tp.__name__ - if hasattr(tp, '__module__') and tp.__module__ and tp.__module__ not in ignore_module_name: + if hasattr(tp, "__module__") and tp.__module__ and tp.__module__ not in ignore_module_name: class_name = "%s.%s" % (tp.__module__, class_name) - if class_name == 'list': - class_name = 'List' + if class_name == "list": + class_name = "List" if len(value) > 0 and recursive: - class_name += '[%s]' % get_type_of_value(value[0], recursive=recursive) + class_name += "[%s]" % get_type_of_value(value[0], recursive=recursive) return class_name - if class_name == 'dict': - class_name = 'Dict' + if class_name == "dict": + class_name = "Dict" if len(value) > 0 and recursive: - for (k, v) in value.items(): - class_name += '[%s, %s]' % (get_type_of_value(k, recursive=recursive), - get_type_of_value(v, recursive=recursive)) + for k, v in value.items(): + class_name += "[%s, %s]" % (get_type_of_value(k, recursive=recursive), get_type_of_value(v, recursive=recursive)) break return class_name - if class_name == 'tuple': - class_name = 'Tuple' + if class_name == "tuple": + class_name = "Tuple" if len(value) > 0 and recursive: - class_name += '[' - class_name += ', '.join(get_type_of_value(v, recursive=recursive) for v in value) - class_name += ']' + class_name += "[" + class_name += ", ".join(get_type_of_value(v, recursive=recursive) for v in value) + class_name += "]" return class_name @@ -85,7 +83,6 @@ def _modname(path): class SignatureFactory(object): - def __init__(self): self._caller_cache = {} self.cache = CallSignatureCache() @@ -130,7 +127,7 @@ def file_module_function_of(self, frame): # this code is take from trace module def get_signature_info(signature): - return signature.file, signature.name, ' '.join([arg[1] for arg in signature.args]) + return signature.file, signature.name, " ".join([arg[1] for arg in signature.args]) def get_frame_info(frame): @@ -139,7 +136,6 @@ def get_frame_info(frame): class CallSignatureCache(object): - def __init__(self): self.cache = {} @@ -159,16 +155,21 @@ def is_in_cache(self, signature): def create_signature_message(signature): cmdTextList = [""] - cmdTextList.append('' % (pydevd_xml.make_valid_xml_value(signature.file), pydevd_xml.make_valid_xml_value(signature.name))) + cmdTextList.append( + '' + % (pydevd_xml.make_valid_xml_value(signature.file), pydevd_xml.make_valid_xml_value(signature.name)) + ) for arg in signature.args: - cmdTextList.append('' % (pydevd_xml.make_valid_xml_value(arg[0]), pydevd_xml.make_valid_xml_value(arg[1]))) + cmdTextList.append( + '' % (pydevd_xml.make_valid_xml_value(arg[0]), pydevd_xml.make_valid_xml_value(arg[1])) + ) if signature.return_type is not None: cmdTextList.append('' % (pydevd_xml.make_valid_xml_value(signature.return_type))) cmdTextList.append("") - cmdText = ''.join(cmdTextList) + cmdText = "".join(cmdTextList) return NetCommand(CMD_SIGNATURE_CALL_TRACE, 0, cmdText) @@ -198,4 +199,3 @@ def send_signature_return_trace(dbg, frame, filename, return_value): return True return False - diff --git a/_pydevd_bundle/pydevd_source_mapping.py b/_pydevd_bundle/pydevd_source_mapping.py index 545530718..7e75c8271 100644 --- a/_pydevd_bundle/pydevd_source_mapping.py +++ b/_pydevd_bundle/pydevd_source_mapping.py @@ -4,8 +4,7 @@ class SourceMappingEntry(object): - - __slots__ = ['source_filename', 'line', 'end_line', 'runtime_line', 'runtime_source'] + __slots__ = ["source_filename", "line", "end_line", "runtime_line", "runtime_source"] def __init__(self, line, end_line, runtime_line, runtime_source): assert isinstance(runtime_source, str) @@ -28,14 +27,12 @@ def contains_runtime_line(self, i): return self.runtime_line <= i <= runtime_end_line def __str__(self): - return 'SourceMappingEntry(%s)' % ( - ', '.join('%s=%r' % (attr, getattr(self, attr)) for attr in self.__slots__)) + return "SourceMappingEntry(%s)" % (", ".join("%s=%r" % (attr, getattr(self, attr)) for attr in self.__slots__)) __repr__ = __str__ class SourceMapping(object): - def __init__(self, on_source_mapping_changed=NULL): self._mappings_to_server = {} # dict(normalized(file.py) to [SourceMappingEntry]) self._mappings_to_client = {} # dict( to File.py) @@ -43,7 +40,7 @@ def __init__(self, on_source_mapping_changed=NULL): self._on_source_mapping_changed = on_source_mapping_changed def set_source_mapping(self, absolute_filename, mapping): - ''' + """ :param str absolute_filename: The filename for the source mapping (bytes on py2 and str on py3). @@ -53,7 +50,7 @@ def set_source_mapping(self, absolute_filename, mapping): :return str: An error message if it was not possible to set the mapping or an empty string if everything is ok. - ''' + """ # Let's first validate if it's ok to apply that mapping. # File mappings must be 1:N, not M:N (i.e.: if there's a mapping from file1.py to , # there can be no other mapping from any other file to ). @@ -63,8 +60,12 @@ def set_source_mapping(self, absolute_filename, mapping): for map_entry in mapping: existing_source_filename = self._mappings_to_client.get(map_entry.runtime_source) if existing_source_filename and existing_source_filename != absolute_filename: - return 'Cannot apply mapping from %s to %s (it conflicts with mapping: %s to %s)' % ( - absolute_filename, map_entry.runtime_source, existing_source_filename, map_entry.runtime_source) + return "Cannot apply mapping from %s to %s (it conflicts with mapping: %s to %s)" % ( + absolute_filename, + map_entry.runtime_source, + existing_source_filename, + map_entry.runtime_source, + ) try: absolute_normalized_filename = pydevd_file_utils.normcase(absolute_filename) @@ -72,17 +73,17 @@ def set_source_mapping(self, absolute_filename, mapping): for map_entry in current_mapping: del self._mappings_to_client[map_entry.runtime_source] - self._mappings_to_server[absolute_normalized_filename] = sorted(mapping, key=lambda entry:entry.line) + self._mappings_to_server[absolute_normalized_filename] = sorted(mapping, key=lambda entry: entry.line) for map_entry in mapping: self._mappings_to_client[map_entry.runtime_source] = absolute_filename finally: self._cache.clear() self._on_source_mapping_changed() - return '' + return "" def map_to_client(self, runtime_source_filename, lineno): - key = (lineno, 'client', runtime_source_filename) + key = (lineno, "client", runtime_source_filename) try: return self._cache[key] except KeyError: @@ -97,13 +98,13 @@ def map_to_client(self, runtime_source_filename, lineno): return self._cache[key] def has_mapping_entry(self, runtime_source_filename): - ''' + """ :param runtime_source_filename: Something as - ''' + """ # Note that we're not interested in the line here, just on knowing if a given filename # (from the server) has a mapping for it. - key = ('has_entry', runtime_source_filename) + key = ("has_entry", runtime_source_filename) try: return self._cache[key] except KeyError: @@ -117,18 +118,17 @@ def has_mapping_entry(self, runtime_source_filename): return self._cache[key] def map_to_server(self, absolute_filename, lineno): - ''' + """ Convert something as 'file1.py' at line 10 to '' at line 2. Note that the name should be already normalized at this point. - ''' + """ absolute_normalized_filename = pydevd_file_utils.normcase(absolute_filename) changed = False mappings = self._mappings_to_server.get(absolute_normalized_filename) if mappings: - - i = bisect.bisect(KeyifyList(mappings, lambda entry:entry.line), lineno) + i = bisect.bisect(KeyifyList(mappings, lambda entry: entry.line), lineno) if i >= len(mappings): i -= 1 @@ -150,4 +150,3 @@ def map_to_server(self, absolute_filename, lineno): changed = True return absolute_filename, lineno, changed - diff --git a/_pydevd_bundle/pydevd_stackless.py b/_pydevd_bundle/pydevd_stackless.py index 44bb768ac..ba574e944 100644 --- a/_pydevd_bundle/pydevd_stackless.py +++ b/_pydevd_bundle/pydevd_stackless.py @@ -14,11 +14,11 @@ # Used so that we don't loose the id (because we'll remove when it's not alive and would generate a new id for the # same tasklet). class TaskletToLastId: - ''' + """ So, why not a WeakKeyDictionary? The problem is that removals from the WeakKeyDictionary will create a new tasklet (as it adds a callback to remove the key when it's garbage-collected), so, we can get into a recursion. - ''' + """ def __init__(self): self.tasklet_ref_to_last_id = {} @@ -39,11 +39,10 @@ def __setitem__(self, tasklet, last_id): _tasklet_to_last_id = TaskletToLastId() -#======================================================================================================================= +# ======================================================================================================================= # _TaskletInfo -#======================================================================================================================= +# ======================================================================================================================= class _TaskletInfo: - _last_id = 0 def __init__(self, tasklet_weakref, tasklet): @@ -64,21 +63,21 @@ def update_name(self): tasklet = self.tasklet_weakref() if tasklet: if tasklet.blocked: - state = 'blocked' + state = "blocked" elif tasklet.paused: - state = 'paused' + state = "paused" elif tasklet.scheduled: - state = 'scheduled' + state = "scheduled" else: - state = '' + state = "" try: name = tasklet.name except AttributeError: if tasklet.is_main: - name = 'MainTasklet' + name = "MainTasklet" else: - name = 'Tasklet-%s' % (self._tasklet_id,) + name = "Tasklet-%s" % (self._tasklet_id,) thread_id = tasklet.thread_id if thread_id != -1: @@ -100,14 +99,13 @@ def update_name(self): tid = id(tasklet) tasklet = None else: - state = 'dead' - name = 'Tasklet-%s' % (self._tasklet_id,) + state = "dead" + name = "Tasklet-%s" % (self._tasklet_id,) thread_name = "" - tid = '-' - self.tasklet_name = '%s %s %s (%s)' % (state, name, thread_name, tid) + tid = "-" + self.tasklet_name = "%s %s %s (%s)" % (state, name, thread_name, tid) if not hasattr(stackless.tasklet, "trace_function"): - # bug https://bitbucket.org/stackless-dev/stackless/issue/42 # is not fixed. Stackless releases before 2014 def update_name(self): @@ -117,9 +115,9 @@ def update_name(self): name = tasklet.name except AttributeError: if tasklet.is_main: - name = 'MainTasklet' + name = "MainTasklet" else: - name = 'Tasklet-%s' % (self._tasklet_id,) + name = "Tasklet-%s" % (self._tasklet_id,) thread_id = tasklet.thread_id for thread in threading.enumerate(): @@ -137,25 +135,25 @@ def update_name(self): tid = id(tasklet) tasklet = None else: - name = 'Tasklet-%s' % (self._tasklet_id,) + name = "Tasklet-%s" % (self._tasklet_id,) thread_name = "" - tid = '-' - self.tasklet_name = '%s %s (%s)' % (name, thread_name, tid) + tid = "-" + self.tasklet_name = "%s %s (%s)" % (name, thread_name, tid) _weak_tasklet_registered_to_info = {} -#======================================================================================================================= +# ======================================================================================================================= # get_tasklet_info -#======================================================================================================================= +# ======================================================================================================================= def get_tasklet_info(tasklet): return register_tasklet_info(tasklet) -#======================================================================================================================= +# ======================================================================================================================= # register_tasklet_info -#======================================================================================================================= +# ======================================================================================================================= def register_tasklet_info(tasklet): r = weakref.ref(tasklet) info = _weak_tasklet_registered_to_info.get(r) @@ -168,13 +166,13 @@ def register_tasklet_info(tasklet): _application_set_schedule_callback = None -#======================================================================================================================= +# ======================================================================================================================= # _schedule_callback -#======================================================================================================================= +# ======================================================================================================================= def _schedule_callback(prev, next): - ''' + """ Called when a context is stopped or a new context is made runnable. - ''' + """ try: if not prev and not next: return @@ -191,7 +189,7 @@ def _schedule_callback(prev, next): frame = next.frame if frame is current_frame: frame = frame.f_back - if hasattr(frame, 'f_trace'): # Note: can be None (but hasattr should cover for that too). + if hasattr(frame, "f_trace"): # Note: can be None (but hasattr should cover for that too). frame.f_trace = debugger.get_thread_local_trace_func() debugger = None @@ -249,14 +247,13 @@ def _schedule_callback(prev, next): if not hasattr(stackless.tasklet, "trace_function"): - # Older versions of Stackless, released before 2014 # This code does not work reliable! It is affected by several # stackless bugs: Stackless issues #44, #42, #40 def _schedule_callback(prev, next): - ''' + """ Called when a context is stopped or a new context is made runnable. - ''' + """ try: if not prev and not next: return @@ -267,7 +264,7 @@ def _schedule_callback(prev, next): # Ok, making next runnable: set the tracing facility in it. debugger = get_global_debugger() if debugger is not None and next.frame: - if hasattr(next.frame, 'f_trace'): + if hasattr(next.frame, "f_trace"): next.frame.f_trace = debugger.get_thread_local_trace_func() debugger = None @@ -316,18 +313,17 @@ def _schedule_callback(prev, next): _original_setup = stackless.tasklet.setup - #======================================================================================================================= + # ======================================================================================================================= # setup - #======================================================================================================================= + # ======================================================================================================================= def setup(self, *args, **kwargs): - ''' + """ Called to run a new tasklet: rebind the creation so that we can trace it. - ''' + """ f = self.tempval def new_f(old_f, args, kwargs): - debugger = get_global_debugger() if debugger is not None: debugger.enable_tracing() @@ -350,21 +346,21 @@ def new_f(old_f, args, kwargs): return _original_setup(self, f, args, kwargs) - #======================================================================================================================= + # ======================================================================================================================= # __call__ - #======================================================================================================================= + # ======================================================================================================================= def __call__(self, *args, **kwargs): - ''' + """ Called to run a new tasklet: rebind the creation so that we can trace it. - ''' + """ return setup(self, *args, **kwargs) _original_run = stackless.run - #======================================================================================================================= + # ======================================================================================================================= # run - #======================================================================================================================= + # ======================================================================================================================= def run(*args, **kwargs): debugger = get_global_debugger() if debugger is not None: @@ -374,14 +370,14 @@ def run(*args, **kwargs): return _original_run(*args, **kwargs) -#======================================================================================================================= +# ======================================================================================================================= # patch_stackless -#======================================================================================================================= +# ======================================================================================================================= def patch_stackless(): - ''' + """ This function should be called to patch the stackless module so that new tasklets are properly tracked in the debugger. - ''' + """ global _application_set_schedule_callback _application_set_schedule_callback = stackless.set_schedule_callback(_schedule_callback) diff --git a/_pydevd_bundle/pydevd_suspended_frames.py b/_pydevd_bundle/pydevd_suspended_frames.py index 6e3243c05..b82823229 100644 --- a/_pydevd_bundle/pydevd_suspended_frames.py +++ b/_pydevd_bundle/pydevd_suspended_frames.py @@ -1,8 +1,7 @@ from contextlib import contextmanager import sys -from _pydevd_bundle.pydevd_constants import get_frame, RETURN_VALUES_DICT, \ - ForkSafeLock, GENERATED_LEN_ATTR_NAME, silence_warnings_decorator +from _pydevd_bundle.pydevd_constants import get_frame, RETURN_VALUES_DICT, ForkSafeLock, GENERATED_LEN_ATTR_NAME, silence_warnings_decorator from _pydevd_bundle.pydevd_xml import get_variable_details, get_type from _pydev_bundle.pydev_override import overrides from _pydevd_bundle.pydevd_resolver import sorted_attributes_key, TOO_LARGE_ATTR, get_var_scope @@ -16,7 +15,6 @@ class _AbstractVariable(object): - # Default attributes in class, set in instance. name = None @@ -36,8 +34,8 @@ def get_value(self): def get_variable_reference(self): return id(self.value) - def get_var_data(self, fmt: Optional[dict]=None, context: Optional[str]=None, **safe_repr_custom_attrs): - ''' + def get_var_data(self, fmt: Optional[dict] = None, context: Optional[str] = None, **safe_repr_custom_attrs): + """ :param dict fmt: Format expected by the DAP (keys: 'hex': bool, 'rawString': bool) @@ -47,58 +45,59 @@ def get_var_data(self, fmt: Optional[dict]=None, context: Optional[str]=None, ** "repl", "hover", "clipboard" - ''' + """ timer = Timer() safe_repr = SafeRepr() if fmt is not None: - safe_repr.convert_to_hex = fmt.get('hex', False) - safe_repr.raw_value = fmt.get('rawString', False) + safe_repr.convert_to_hex = fmt.get("hex", False) + safe_repr.raw_value = fmt.get("rawString", False) for key, val in safe_repr_custom_attrs.items(): setattr(safe_repr, key, val) type_name, _type_qualifier, _is_exception_on_eval, resolver, value = get_variable_details( - self.value, to_string=safe_repr, context=context) + self.value, to_string=safe_repr, context=context + ) - is_raw_string = type_name in ('str', 'bytes', 'bytearray') + is_raw_string = type_name in ("str", "bytes", "bytearray") attributes = [] if is_raw_string: - attributes.append('rawString') + attributes.append("rawString") name = self.name if self._is_return_value: - attributes.append('readOnly') - name = '(return) %s' % (name,) + attributes.append("readOnly") + name = "(return) %s" % (name,) elif name in (TOO_LARGE_ATTR, GENERATED_LEN_ATTR_NAME): - attributes.append('readOnly') + attributes.append("readOnly") try: if self.value.__class__ == DAPGrouper: - type_name = '' + type_name = "" except: pass # Ignore errors accessing __class__. var_data = { - 'name': name, - 'value': value, - 'type': type_name, + "name": name, + "value": value, + "type": type_name, } if self.evaluate_name is not None: - var_data['evaluateName'] = self.evaluate_name + var_data["evaluateName"] = self.evaluate_name if resolver is not None: # I.e.: it's a container - var_data['variablesReference'] = self.get_variable_reference() + var_data["variablesReference"] = self.get_variable_reference() else: - var_data['variablesReference'] = 0 # It's mandatory (although if == 0 it doesn't have children). + var_data["variablesReference"] = 0 # It's mandatory (although if == 0 it doesn't have children). if len(attributes) > 0: - var_data['presentationHint'] = {'attributes': attributes} + var_data["presentationHint"] = {"attributes": attributes} - timer.report_if_compute_repr_attr_slow('', name, type_name) + timer.report_if_compute_repr_attr_slow("", name, type_name) return var_data def get_children_variables(self, fmt=None, scope=None): @@ -126,10 +125,10 @@ def _group_entries(self, lst, handle_return_values): entry = (attr_name, attr_value, evaluate_name) if scope: presentation = get_presentation(scope) - if presentation == 'hide': + if presentation == "hide": continue - elif presentation == 'inline': + elif presentation == "inline": new_lst.append(entry) else: # group @@ -153,7 +152,6 @@ def _group_entries(self, lst, handle_return_values): class _ObjectVariable(_AbstractVariable): - def __init__(self, py_db, name, value, register_variable, is_return_value=False, evaluate_name=None, frame=None): _AbstractVariable.__init__(self, py_db) self.frame = frame @@ -171,7 +169,7 @@ def get_children_variables(self, fmt=None, scope=None): children_variables = [] if resolver is not None: # i.e.: it's a container. - if hasattr(resolver, 'get_contents_debug_adapter_protocol'): + if hasattr(resolver, "get_contents_debug_adapter_protocol"): # The get_contents_debug_adapter_protocol needs to return sorted. lst = resolver.get_contents_debug_adapter_protocol(self.value, fmt=fmt) else: @@ -192,8 +190,7 @@ def get_children_variables(self, fmt=None, scope=None): evaluate_name = evaluate_name(parent_evaluate_name) else: evaluate_name = parent_evaluate_name + evaluate_name - variable = _ObjectVariable( - self.py_db, key, val, self._register_variable, evaluate_name=evaluate_name, frame=self.frame) + variable = _ObjectVariable(self.py_db, key, val, self._register_variable, evaluate_name=evaluate_name, frame=self.frame) children_variables.append(variable) else: for key, val, evaluate_name in lst: @@ -204,13 +201,12 @@ def get_children_variables(self, fmt=None, scope=None): return children_variables def change_variable(self, name, value, py_db, fmt=None): - children_variable = self.get_child_variable_named(name) if children_variable is None: return None var_data = children_variable.get_var_data() - evaluate_name = var_data.get('evaluateName') + evaluate_name = var_data.get("evaluateName") if not evaluate_name: # Note: right now we only pass control to the resolver in the cases where @@ -218,15 +214,14 @@ def change_variable(self, name, value, py_db, fmt=None): # we can use that evaluation to set the value too -- if in the future # a case where this isn't true is found this logic may need to be changed). _type, _type_name, container_resolver = get_type(self.value) - if hasattr(container_resolver, 'change_var_from_name'): + if hasattr(container_resolver, "change_var_from_name"): try: new_value = eval(value) except: return None new_key = container_resolver.change_var_from_name(self.value, name, new_value) if new_key is not None: - return _ObjectVariable( - self.py_db, new_key, new_value, self._register_variable, evaluate_name=None, frame=self.frame) + return _ObjectVariable(self.py_db, new_key, new_value, self._register_variable, evaluate_name=None, frame=self.frame) return None else: @@ -238,7 +233,7 @@ def change_variable(self, name, value, py_db, fmt=None): try: # This handles the simple cases (such as dict, list, object) - Exec('%s=%s' % (evaluate_name, value), frame.f_globals, frame.f_locals) + Exec("%s=%s" % (evaluate_name, value), frame.f_globals, frame.f_locals) except: return None @@ -250,7 +245,6 @@ def sorted_variables_key(obj): class _FrameVariable(_AbstractVariable): - def __init__(self, py_db, frame, register_variable): _AbstractVariable.__init__(self, py_db) self.frame = frame @@ -276,19 +270,21 @@ def get_children_variables(self, fmt=None, scope=None): assert isinstance(scope, ScopeRequest) scope = scope.scope - if scope in ('locals', None): + if scope in ("locals", None): dct = self.frame.f_locals - elif scope == 'globals': + elif scope == "globals": dct = self.frame.f_globals else: - raise AssertionError('Unexpected scope: %s' % (scope,)) + raise AssertionError("Unexpected scope: %s" % (scope,)) - lst, group_entries = self._group_entries([(x[0], x[1], None) for x in list(dct.items()) if x[0] != '_pydev_stop_at_break'], handle_return_values=True) + lst, group_entries = self._group_entries( + [(x[0], x[1], None) for x in list(dct.items()) if x[0] != "_pydev_stop_at_break"], handle_return_values=True + ) group_variables = [] for key, val, _ in group_entries: # Make sure that the contents in the group are also sorted. - val.contents_debug_adapter_protocol.sort(key=lambda v:sorted_attributes_key(v[0])) + val.contents_debug_adapter_protocol.sort(key=lambda v: sorted_attributes_key(v[0])) variable = _ObjectVariable(self.py_db, key, val, self._register_variable, False, key, frame=self.frame) group_variables.append(variable) @@ -297,7 +293,14 @@ def get_children_variables(self, fmt=None, scope=None): if is_return_value: for return_key, return_value in val.items(): variable = _ObjectVariable( - self.py_db, return_key, return_value, self._register_variable, is_return_value, '%s[%r]' % (key, return_key), frame=self.frame) + self.py_db, + return_key, + return_value, + self._register_variable, + is_return_value, + "%s[%r]" % (key, return_key), + frame=self.frame, + ) children_variables.append(variable) else: variable = _ObjectVariable(self.py_db, key, val, self._register_variable, is_return_value, key, frame=self.frame) @@ -313,9 +316,9 @@ def get_children_variables(self, fmt=None, scope=None): class _FramesTracker(object): - ''' + """ This is a helper class to be used to track frames when a thread becomes suspended. - ''' + """ def __init__(self, suspended_frames_manager, py_db): self._suspended_frames_manager = suspended_frames_manager @@ -361,7 +364,8 @@ def obtain_as_variable(self, name, value, evaluate_name=None, frame=None): # Still not created, let's do it now. return _ObjectVariable( - self.py_db, name, value, self._register_variable, is_return_value=False, evaluate_name=evaluate_name, frame=frame) + self.py_db, name, value, self._register_variable, is_return_value=False, evaluate_name=evaluate_name, frame=frame + ) def get_main_thread_id(self): return self._main_thread_id @@ -370,7 +374,7 @@ def get_variable(self, variable_reference): return self._variable_reference_to_variable[variable_reference] def track(self, thread_id, frames_list, frame_custom_thread_id=None): - ''' + """ :param thread_id: The thread id to be used for this frame. @@ -379,19 +383,18 @@ def track(self, thread_id, frames_list, frame_custom_thread_id=None): :param frame_custom_thread_id: If None this this is the id of the thread id for the custom frame (i.e.: coroutine). - ''' + """ assert frames_list.__class__ == FramesList with self._lock: coroutine_or_main_thread_id = frame_custom_thread_id or thread_id if coroutine_or_main_thread_id in self._suspended_frames_manager._thread_id_to_tracker: - sys.stderr.write('pydevd: Something is wrong. Tracker being added twice to the same thread id.\n') + sys.stderr.write("pydevd: Something is wrong. Tracker being added twice to the same thread id.\n") self._suspended_frames_manager._thread_id_to_tracker[coroutine_or_main_thread_id] = self self._main_thread_id = thread_id - frame_ids_from_thread = self._thread_id_to_frame_ids.setdefault( - coroutine_or_main_thread_id, []) + frame_ids_from_thread = self._thread_id_to_frame_ids.setdefault(coroutine_or_main_thread_id, []) self._thread_id_to_frames_list[coroutine_or_main_thread_id] = frames_list for frame in frames_list: @@ -439,14 +442,14 @@ def create_thread_suspend_command(self, thread_id, stop_reason, message, trace_s frames_list = self._thread_id_to_frames_list[thread_id] cmd = self.py_db.cmd_factory.make_thread_suspend_message( - self.py_db, thread_id, frames_list, stop_reason, message, trace_suspend_type, thread, additional_info) + self.py_db, thread_id, frames_list, stop_reason, message, trace_suspend_type, thread, additional_info + ) frames_list = None return cmd class SuspendedFramesManager(object): - def __init__(self): self._thread_id_to_fake_frames = {} self._thread_id_to_tracker = {} @@ -470,7 +473,7 @@ def _get_tracker_for_variable_reference(self, variable_reference): return None def get_thread_id_for_variable_reference(self, variable_reference): - ''' + """ We can't evaluate variable references values on any thread, only in the suspended thread (the main reason for this is that in UI frameworks inspecting a UI object from a different thread can potentially crash the application). @@ -482,7 +485,7 @@ def get_thread_id_for_variable_reference(self, variable_reference): :return str: The thread id for the thread to be used to inspect the given variable reference or None if the thread was already resumed. - ''' + """ frames_tracker = self._get_tracker_for_variable_reference(variable_reference) if frames_tracker is not None: return frames_tracker.get_main_thread_id() @@ -492,9 +495,9 @@ def get_frame_tracker(self, thread_id): return self._thread_id_to_tracker.get(thread_id) def get_variable(self, variable_reference): - ''' + """ :raises KeyError - ''' + """ frames_tracker = self._get_tracker_for_variable_reference(variable_reference) if frames_tracker is None: raise KeyError() diff --git a/_pydevd_bundle/pydevd_thread_lifecycle.py b/_pydevd_bundle/pydevd_thread_lifecycle.py index 66fb96544..2d205c176 100644 --- a/_pydevd_bundle/pydevd_thread_lifecycle.py +++ b/_pydevd_bundle/pydevd_thread_lifecycle.py @@ -1,8 +1,7 @@ from _pydevd_bundle import pydevd_utils from _pydevd_bundle.pydevd_additional_thread_info import set_additional_thread_info from _pydevd_bundle.pydevd_comm_constants import CMD_STEP_INTO, CMD_THREAD_SUSPEND -from _pydevd_bundle.pydevd_constants import PYTHON_SUSPEND, STATE_SUSPEND, get_thread_id, STATE_RUN, \ - PYDEVD_USE_SYS_MONITORING +from _pydevd_bundle.pydevd_constants import PYTHON_SUSPEND, STATE_SUSPEND, get_thread_id, STATE_RUN, PYDEVD_USE_SYS_MONITORING from _pydev_bundle._pydev_saved_modules import threading from _pydev_bundle import pydev_log import sys @@ -14,7 +13,7 @@ def pydevd_find_thread_by_id(thread_id): threads = threading.enumerate() for i in threads: tid = get_thread_id(i) - if thread_id == tid or thread_id.endswith('|' + tid): + if thread_id == tid or thread_id.endswith("|" + tid): return i # This can happen when a request comes for a thread which was previously removed. @@ -26,7 +25,7 @@ def pydevd_find_thread_by_id(thread_id): return None -def mark_thread_suspended(thread, stop_reason: int, original_step_cmd: int=-1): +def mark_thread_suspended(thread, stop_reason: int, original_step_cmd: int = -1): info = set_additional_thread_info(thread) info.suspend_type = PYTHON_SUSPEND if original_step_cmd != -1: @@ -57,12 +56,12 @@ def internal_run_thread(thread, set_additional_thread_info): def resume_threads(thread_id, except_thread=None): - pydev_log.info('Resuming threads: %s (except thread: %s)', thread_id, except_thread) + pydev_log.info("Resuming threads: %s (except thread: %s)", thread_id, except_thread) threads = [] - if thread_id == '*': + if thread_id == "*": threads = pydevd_utils.get_non_pydevd_threads() - elif thread_id.startswith('__frame__:'): + elif thread_id.startswith("__frame__:"): pydev_log.critical("Can't make tasklet run: %s", thread_id) else: @@ -70,24 +69,24 @@ def resume_threads(thread_id, except_thread=None): for t in threads: if t is None or t is except_thread: - pydev_log.info('Skipped resuming thread: %s', t) + pydev_log.info("Skipped resuming thread: %s", t) continue internal_run_thread(t, set_additional_thread_info=set_additional_thread_info) def suspend_all_threads(py_db, except_thread): - ''' + """ Suspend all except the one passed as a parameter. :param except_thread: - ''' + """ if PYDEVD_USE_SYS_MONITORING: pydevd_sys_monitoring.update_monitor_events(suspend_requested=True) - pydev_log.info('Suspending all threads except: %s', except_thread) + pydev_log.info("Suspending all threads except: %s", except_thread) all_threads = pydevd_utils.get_non_pydevd_threads() for t in all_threads: - if getattr(t, 'pydev_do_not_trace', None): + if getattr(t, "pydev_do_not_trace", None): pass # skip some other threads, i.e. ipython history saving thread from debug console else: if t is except_thread: diff --git a/_pydevd_bundle/pydevd_timeout.py b/_pydevd_bundle/pydevd_timeout.py index d745191ee..e9c30bcc8 100644 --- a/_pydevd_bundle/pydevd_timeout.py +++ b/_pydevd_bundle/pydevd_timeout.py @@ -1,5 +1,4 @@ -from _pydev_bundle._pydev_saved_modules import (ThreadingEvent, - ThreadingLock, threading_current_thread) +from _pydev_bundle._pydev_saved_modules import ThreadingEvent, ThreadingLock, threading_current_thread from _pydevd_bundle.pydevd_daemon_thread import PyDBDaemonThread from _pydevd_bundle.pydevd_constants import thread_get_ident, IS_CPYTHON, NULL import ctypes @@ -13,7 +12,7 @@ class _TimeoutThread(PyDBDaemonThread): - ''' + """ The idea in this class is that it should be usually stopped waiting for the next event to be called (paused in a threading.Event.wait). @@ -21,7 +20,7 @@ class _TimeoutThread(PyDBDaemonThread): then keeps on waiting as needed again. This is done so that it's a bit more optimized than creating many Timer threads. - ''' + """ def __init__(self, py_db): PyDBDaemonThread.__init__(self, py_db) @@ -38,9 +37,9 @@ def _on_run(self): while not self._kill_received: if _DEBUG: if wait_time is None: - pydev_log.critical('pydevd_timeout: Wait until a new handle is added.') + pydev_log.critical("pydevd_timeout: Wait until a new handle is added.") else: - pydev_log.critical('pydevd_timeout: Next wait time: %s.', wait_time) + pydev_log.critical("pydevd_timeout: Next wait time: %s.", wait_time) self._event.wait(wait_time) if self._kill_received: @@ -50,13 +49,13 @@ def _on_run(self): wait_time = self.process_handles() def process_handles(self): - ''' + """ :return int: Returns the time we should be waiting for to process the next event properly. - ''' + """ with self._lock: if _DEBUG: - pydev_log.critical('pydevd_timeout: Processing handles') + pydev_log.critical("pydevd_timeout: Processing handles") self._event.clear() handles = self._handles new_handles = self._handles = [] @@ -72,7 +71,7 @@ def process_handles(self): if curtime < handle.abs_timeout and not handle.disposed: # It still didn't time out. if _DEBUG: - pydev_log.critical('pydevd_timeout: Handle NOT processed: %s', handle) + pydev_log.critical("pydevd_timeout: Handle NOT processed: %s", handle) new_handles.append(handle) if min_handle_timeout is None: min_handle_timeout = handle.abs_timeout @@ -82,7 +81,7 @@ def process_handles(self): else: if _DEBUG: - pydev_log.critical('pydevd_timeout: Handle processed: %s', handle) + pydev_log.critical("pydevd_timeout: Handle processed: %s", handle) # Timed out (or disposed), so, let's execute it (should be no-op if disposed). handle.exec_on_timeout() @@ -91,7 +90,7 @@ def process_handles(self): else: timeout = min_handle_timeout - curtime if timeout <= 0: - pydev_log.critical('pydevd_timeout: Expected timeout to be > 0. Found: %s', timeout) + pydev_log.critical("pydevd_timeout: Expected timeout to be > 0. Found: %s", timeout) return timeout @@ -107,9 +106,8 @@ def add_on_timeout_handle(self, handle): class _OnTimeoutHandle(object): - def __init__(self, tracker, abs_timeout, on_timeout, kwargs): - self._str = '_OnTimeoutHandle(%s)' % (on_timeout,) + self._str = "_OnTimeoutHandle(%s)" % (on_timeout,) self._tracker = weakref.ref(tracker) self.abs_timeout = abs_timeout @@ -131,11 +129,11 @@ def exec_on_timeout(self): try: if _DEBUG: - pydev_log.critical('pydevd_timeout: Calling on timeout: %s with kwargs: %s', on_timeout, kwargs) + pydev_log.critical("pydevd_timeout: Calling on timeout: %s with kwargs: %s", on_timeout, kwargs) on_timeout(**kwargs) except Exception: - pydev_log.exception('pydevd_timeout: Exception on callback timeout.') + pydev_log.exception("pydevd_timeout: Exception on callback timeout.") def __enter__(self): pass @@ -160,9 +158,9 @@ def __str__(self): class TimeoutTracker(object): - ''' + """ This is a helper class to track the timeout of something. - ''' + """ def __init__(self, py_db): self._thread = None @@ -170,7 +168,7 @@ def __init__(self, py_db): self._py_db = weakref.ref(py_db) def call_on_timeout(self, timeout, on_timeout, kwargs=None): - ''' + """ This can be called regularly to always execute the given function after a given timeout: call_on_timeout(py_db, 10, on_timeout) @@ -183,11 +181,11 @@ def call_on_timeout(self, timeout, on_timeout, kwargs=None): ... Note: the callback will be called from a PyDBDaemonThread. - ''' + """ with self._lock: if self._thread is None: if _DEBUG: - pydev_log.critical('pydevd_timeout: Created _TimeoutThread.') + pydev_log.critical("pydevd_timeout: Created _TimeoutThread.") self._thread = _TimeoutThread(self._py_db()) self._thread.start() @@ -195,13 +193,13 @@ def call_on_timeout(self, timeout, on_timeout, kwargs=None): curtime = time.time() handle = _OnTimeoutHandle(self, curtime + timeout, on_timeout, kwargs) if _DEBUG: - pydev_log.critical('pydevd_timeout: Added handle: %s.', handle) + pydev_log.critical("pydevd_timeout: Added handle: %s.", handle) self._thread.add_on_timeout_handle(handle) return handle def create_interrupt_this_thread_callback(): - ''' + """ The idea here is returning a callback that when called will generate a KeyboardInterrupt in the thread that called this function. @@ -215,26 +213,25 @@ def create_interrupt_this_thread_callback(): :return callable: Returns a callback that will interrupt the current thread (this may be called from an auxiliary thread). - ''' + """ tid = thread_get_ident() if is_current_thread_main_thread(): main_thread = threading_current_thread() def raise_on_this_thread(): - pydev_log.debug('Callback to interrupt main thread.') + pydev_log.debug("Callback to interrupt main thread.") pydevd_utils.interrupt_main_thread(main_thread) else: - # Note: this works in the sense that it can stop some cpu-intensive slow operation, # but we can't really interrupt the thread out of some sleep or I/O operation # (this will only be raised when Python is about to execute the next instruction). def raise_on_this_thread(): if IS_CPYTHON: - pydev_log.debug('Interrupt thread: %s', tid) + pydev_log.debug("Interrupt thread: %s", tid) ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(KeyboardInterrupt)) else: - pydev_log.debug('It is only possible to interrupt non-main threads in CPython.') + pydev_log.debug("It is only possible to interrupt non-main threads in CPython.") return raise_on_this_thread diff --git a/_pydevd_bundle/pydevd_trace_dispatch.py b/_pydevd_bundle/pydevd_trace_dispatch.py index f6291bd23..19b83e328 100644 --- a/_pydevd_bundle/pydevd_trace_dispatch.py +++ b/_pydevd_bundle/pydevd_trace_dispatch.py @@ -2,8 +2,7 @@ # Should give warning only here if cython is not available but supported. import os -from _pydevd_bundle.pydevd_constants import USE_CYTHON_FLAG, ENV_TRUE_LOWER_VALUES, \ - ENV_FALSE_LOWER_VALUES +from _pydevd_bundle.pydevd_constants import USE_CYTHON_FLAG, ENV_TRUE_LOWER_VALUES, ENV_FALSE_LOWER_VALUES from _pydev_bundle import pydev_log dirname = os.path.dirname(os.path.dirname(__file__)) @@ -12,11 +11,13 @@ def delete_old_compiled_extensions(): import _pydevd_bundle + cython_extensions_dir = os.path.dirname(os.path.dirname(_pydevd_bundle.__file__)) _pydevd_bundle_ext_dir = os.path.dirname(_pydevd_bundle.__file__) - _pydevd_frame_eval_ext_dir = os.path.join(cython_extensions_dir, '_pydevd_frame_eval_ext') + _pydevd_frame_eval_ext_dir = os.path.join(cython_extensions_dir, "_pydevd_frame_eval_ext") try: import shutil + for file in os.listdir(_pydevd_bundle_ext_dir): if file.startswith("pydevd") and file.endswith(".so"): os.remove(os.path.join(_pydevd_bundle_ext_dir, file)) @@ -27,40 +28,65 @@ def delete_old_compiled_extensions(): if os.path.exists(build_dir): shutil.rmtree(os.path.join(cython_extensions_dir, "build")) except OSError: - pydev_log.error_once("warning: failed to delete old cython speedups. Please delete all *.so files from the directories " - "\"%s\" and \"%s\"" % (_pydevd_bundle_ext_dir, _pydevd_frame_eval_ext_dir)) + pydev_log.error_once( + "warning: failed to delete old cython speedups. Please delete all *.so files from the directories " + '"%s" and "%s"' % (_pydevd_bundle_ext_dir, _pydevd_frame_eval_ext_dir) + ) if USE_CYTHON_FLAG in ENV_TRUE_LOWER_VALUES: # We must import the cython version if forcing cython - from _pydevd_bundle.pydevd_cython_wrapper import trace_dispatch, global_cache_skips, global_cache_frame_skips, fix_top_level_trace_and_get_trace_func + from _pydevd_bundle.pydevd_cython_wrapper import ( + trace_dispatch, + global_cache_skips, + global_cache_frame_skips, + fix_top_level_trace_and_get_trace_func, + ) from _pydevd_bundle.pydevd_cython_wrapper import should_stop_on_exception, handle_exception, is_unhandled_exception + USING_CYTHON = True elif USE_CYTHON_FLAG in ENV_FALSE_LOWER_VALUES: # Use the regular version if not forcing cython - from _pydevd_bundle.pydevd_trace_dispatch_regular import trace_dispatch, global_cache_skips, global_cache_frame_skips, fix_top_level_trace_and_get_trace_func # @UnusedImport + from _pydevd_bundle.pydevd_trace_dispatch_regular import ( + trace_dispatch, + global_cache_skips, + global_cache_frame_skips, + fix_top_level_trace_and_get_trace_func, + ) # @UnusedImport from .pydevd_frame import should_stop_on_exception, handle_exception, is_unhandled_exception else: # Regular: use fallback if not found and give message to user try: - from _pydevd_bundle.pydevd_cython_wrapper import trace_dispatch, global_cache_skips, global_cache_frame_skips, fix_top_level_trace_and_get_trace_func + from _pydevd_bundle.pydevd_cython_wrapper import ( + trace_dispatch, + global_cache_skips, + global_cache_frame_skips, + fix_top_level_trace_and_get_trace_func, + ) from _pydevd_bundle.pydevd_cython_wrapper import should_stop_on_exception, handle_exception, is_unhandled_exception # This version number is always available from _pydevd_bundle.pydevd_additional_thread_info_regular import version as regular_version + # This version number from the already compiled cython extension from _pydevd_bundle.pydevd_cython_wrapper import version as cython_version + if cython_version != regular_version: # delete_old_compiled_extensions() -- would be ok in dev mode but we don't want to erase # files from other python versions on release, so, just raise import error here. - raise ImportError('Cython version of speedups does not match.') + raise ImportError("Cython version of speedups does not match.") else: USING_CYTHON = True except ImportError: - from _pydevd_bundle.pydevd_trace_dispatch_regular import trace_dispatch, global_cache_skips, global_cache_frame_skips, fix_top_level_trace_and_get_trace_func # @UnusedImport + from _pydevd_bundle.pydevd_trace_dispatch_regular import ( + trace_dispatch, + global_cache_skips, + global_cache_frame_skips, + fix_top_level_trace_and_get_trace_func, + ) # @UnusedImport from .pydevd_frame import should_stop_on_exception, handle_exception, is_unhandled_exception - pydev_log.show_compile_cython_command_line() + pydev_log.show_compile_cython_command_line() diff --git a/_pydevd_bundle/pydevd_trace_dispatch_regular.py b/_pydevd_bundle/pydevd_trace_dispatch_regular.py index 0f2760de5..8d8becae3 100644 --- a/_pydevd_bundle/pydevd_trace_dispatch_regular.py +++ b/_pydevd_bundle/pydevd_trace_dispatch_regular.py @@ -1,8 +1,13 @@ from _pydev_bundle.pydev_is_thread_alive import is_thread_alive from _pydev_bundle.pydev_log import exception as pydev_log_exception from _pydev_bundle._pydev_saved_modules import threading -from _pydevd_bundle.pydevd_constants import (get_current_thread_id, NO_FTRACE, - USE_CUSTOM_SYS_CURRENT_FRAMES_MAP, ForkSafeLock, PYDEVD_USE_SYS_MONITORING) +from _pydevd_bundle.pydevd_constants import ( + get_current_thread_id, + NO_FTRACE, + USE_CUSTOM_SYS_CURRENT_FRAMES_MAP, + ForkSafeLock, + PYDEVD_USE_SYS_MONITORING, +) from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame, NORM_PATHS_AND_BASE_CONTAINER # IFDEF CYTHON @@ -48,6 +53,7 @@ def notify_skipped_step_in_because_of_filters(py_db, frame): _global_notify_skipped_step_in = True py_db.notify_skipped_step_in_because_of_filters(frame) + # IFDEF CYTHON # cdef class SafeCallWrapper: # cdef method_object @@ -90,45 +96,45 @@ def fix_top_level_trace_and_get_trace_func(py_db, frame): name = f_unhandled.f_code.co_filename # basename - i = name.rfind('/') - j = name.rfind('\\') + i = name.rfind("/") + j = name.rfind("\\") if j > i: i = j if i >= 0: - name = name[i + 1:] + name = name[i + 1 :] # remove ext - i = name.rfind('.') + i = name.rfind(".") if i >= 0: name = name[:i] - if name == 'threading': - if f_unhandled.f_code.co_name in ('__bootstrap', '_bootstrap'): + if name == "threading": + if f_unhandled.f_code.co_name in ("__bootstrap", "_bootstrap"): # We need __bootstrap_inner, not __bootstrap. return None, False - elif f_unhandled.f_code.co_name in ('__bootstrap_inner', '_bootstrap_inner'): + elif f_unhandled.f_code.co_name in ("__bootstrap_inner", "_bootstrap_inner"): # Note: be careful not to use threading.currentThread to avoid creating a dummy thread. - t = f_unhandled.f_locals.get('self') + t = f_unhandled.f_locals.get("self") force_only_unhandled_tracer = True if t is not None and isinstance(t, threading.Thread): thread = t break - elif name == 'pydev_monkey': - if f_unhandled.f_code.co_name == '__call__': + elif name == "pydev_monkey": + if f_unhandled.f_code.co_name == "__call__": force_only_unhandled_tracer = True break - elif name == 'pydevd': - if f_unhandled.f_code.co_name in ('run', 'main'): + elif name == "pydevd": + if f_unhandled.f_code.co_name in ("run", "main"): # We need to get to _exec return None, False - if f_unhandled.f_code.co_name == '_exec': + if f_unhandled.f_code.co_name == "_exec": force_only_unhandled_tracer = True break - elif name == 'pydevd_tracing': + elif name == "pydevd_tracing": return None, False elif f_unhandled.f_back is None: @@ -147,7 +153,7 @@ def fix_top_level_trace_and_get_trace_func(py_db, frame): # Jython does not have threading.get_ident(). thread = py_db.threading_current_thread() - if getattr(thread, 'pydev_do_not_trace', None): + if getattr(thread, "pydev_do_not_trace", None): py_db.disable_tracing() return None, False @@ -165,7 +171,9 @@ def fix_top_level_trace_and_get_trace_func(py_db, frame): if f_unhandled.f_back is None and not force_only_unhandled_tracer: # Happens when we attach to a running program (cannot reuse instance because it's mutable). top_level_thread_tracer = TopLevelThreadTracerNoBackFrame(ThreadTracer(args), args) - additional_info.top_level_thread_tracer_no_back_frames.append(top_level_thread_tracer) # Hack for cython to keep it alive while the thread is alive (just the method in the SetTrace is not enough). + additional_info.top_level_thread_tracer_no_back_frames.append( + top_level_thread_tracer + ) # Hack for cython to keep it alive while the thread is alive (just the method in the SetTrace is not enough). else: top_level_thread_tracer = additional_info.top_level_thread_tracer_unhandled if top_level_thread_tracer is None: @@ -188,17 +196,19 @@ def fix_top_level_trace_and_get_trace_func(py_db, frame): thread_tracer = ThreadTracer(args) additional_info.thread_tracer = thread_tracer -# IFDEF CYTHON -# return SafeCallWrapper(thread_tracer), True -# ELSE + # IFDEF CYTHON + # return SafeCallWrapper(thread_tracer), True + # ELSE return thread_tracer, True + + # ENDIF def trace_dispatch(py_db, frame, event, arg): thread_trace_func, apply_to_settrace = py_db.fix_top_level_trace_and_get_trace_func(py_db, frame) if thread_trace_func is None: - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE if apply_to_settrace: py_db.enable_tracing(thread_trace_func) return thread_trace_func(frame, event, arg) @@ -211,15 +221,15 @@ def trace_dispatch(py_db, frame, event, arg): # self._args = args # ELSE class TopLevelThreadTracerOnlyUnhandledExceptions(object): - def __init__(self, args): self._args = args -# ENDIF + + # ENDIF def trace_unhandled_exceptions(self, frame, event, arg): # Note that we ignore the frame as this tracing method should only be put in topmost frames already. # print('trace_unhandled_exceptions', event, frame.f_code.co_name, frame.f_code.co_filename, frame.f_code.co_firstlineno) - if event == 'exception' and arg is not None: + if event == "exception" and arg is not None: py_db, t, additional_info = self._args[0:3] if arg is not None: if not additional_info.suspended_at_unhandled: @@ -253,7 +263,7 @@ def get_trace_dispatch_func(self): # self._last_raise_line = -1 # ELSE class TopLevelThreadTracerNoBackFrame(object): - ''' + """ This tracer is pretty special in that it's dealing with a frame without f_back (i.e.: top frame on remote attach or QThread). @@ -263,7 +273,7 @@ class TopLevelThreadTracerNoBackFrame(object): work with in the tracing -- see: https://bugs.python.org/issue34099, so, we inspect bytecode to determine if some exception will be traced or not... note that if this is not available -- such as on Jython -- we consider any top-level exception to be unnhandled). - ''' + """ def __init__(self, frame_trace_dispatch, args): self._frame_trace_dispatch = frame_trace_dispatch @@ -272,7 +282,8 @@ def __init__(self, frame_trace_dispatch, args): self._last_exc_arg = None self._raise_lines = set() self._last_raise_line = -1 -# ENDIF + + # ENDIF def trace_dispatch_and_unhandled_exceptions(self, frame, event, arg): # DEBUG = 'code_to_debug' in frame.f_code.co_filename @@ -281,12 +292,12 @@ def trace_dispatch_and_unhandled_exceptions(self, frame, event, arg): if frame_trace_dispatch is not None: self._frame_trace_dispatch = frame_trace_dispatch(frame, event, arg) - if event == 'exception': + if event == "exception": self._last_exc_arg = arg self._raise_lines.add(frame.f_lineno) self._last_raise_line = frame.f_lineno - elif event == 'return' and self._last_exc_arg is not None: + elif event == "return" and self._last_exc_arg is not None: # For unhandled exceptions we actually track the return when at the topmost level. try: py_db, t, additional_info = self._args[0:3] @@ -318,13 +329,13 @@ def get_trace_dispatch_func(self): # self._args = args # ELSE class ThreadTracer(object): - def __init__(self, args): self._args = args -# ENDIF + + # ENDIF def __call__(self, frame, event, arg): - ''' This is the callback used when we enter some context in the debugger. + """This is the callback used when we enter some context in the debugger. We also decorate the thread we are in with info about the debugging. The attributes added are: @@ -335,7 +346,7 @@ def __call__(self, frame, event, arg): :param PyDB py_db: This is the global debugger (this method should actually be added as a method to it). - ''' + """ # IFDEF CYTHON # cdef str filename; # cdef str base; @@ -351,19 +362,19 @@ def __call__(self, frame, event, arg): # if DEBUG: print('ENTER: trace_dispatch: %s %s %s %s' % (frame.f_code.co_filename, frame.f_lineno, event, frame.f_code.co_name)) py_db, t, additional_info, cache_skips, frame_skips_cache = self._args if additional_info.is_tracing: - return None if event == 'call' else NO_FTRACE # we don't wan't to trace code invoked from pydevd_frame.trace_dispatch + return None if event == "call" else NO_FTRACE # we don't wan't to trace code invoked from pydevd_frame.trace_dispatch additional_info.is_tracing += 1 try: pydev_step_cmd = additional_info.pydev_step_cmd is_stepping = pydev_step_cmd != -1 if py_db.pydb_disposed: - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE # if thread is not alive, cancel trace_dispatch processing if not is_thread_alive(t): py_db.notify_thread_not_alive(get_current_thread_id(t)) - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE # Note: it's important that the context name is also given because we may hit something once # in the global context and another in the local context. @@ -371,23 +382,30 @@ def __call__(self, frame, event, arg): if frame_cache_key in cache_skips: if not is_stepping: # if DEBUG: print('skipped: trace_dispatch (cache hit)', frame_cache_key, frame.f_lineno, event, frame.f_code.co_name) - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE else: # When stepping we can't take into account caching based on the breakpoints (only global filtering). if cache_skips.get(frame_cache_key) == 1: - - if additional_info.pydev_original_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE) and not _global_notify_skipped_step_in: + if ( + additional_info.pydev_original_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE) + and not _global_notify_skipped_step_in + ): notify_skipped_step_in_because_of_filters(py_db, frame) back_frame = frame.f_back - if back_frame is not None and pydev_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE, CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE): + if back_frame is not None and pydev_step_cmd in ( + CMD_STEP_INTO, + CMD_STEP_INTO_MY_CODE, + CMD_STEP_RETURN, + CMD_STEP_RETURN_MY_CODE, + ): back_frame_cache_key = back_frame.f_code if cache_skips.get(back_frame_cache_key) == 1: # if DEBUG: print('skipped: trace_dispatch (cache hit: 1)', frame_cache_key, frame.f_lineno, event, frame.f_code.co_name) - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE else: # if DEBUG: print('skipped: trace_dispatch (cache hit: 2)', frame_cache_key, frame.f_lineno, event, frame.f_code.co_name) - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE try: # Make fast path faster! @@ -395,39 +413,50 @@ def __call__(self, frame, event, arg): except: abs_path_canonical_path_and_base = get_abs_path_real_path_and_base_from_frame(frame) - file_type = py_db.get_file_type(frame, abs_path_canonical_path_and_base) # we don't want to debug threading or anything related to pydevd + file_type = py_db.get_file_type( + frame, abs_path_canonical_path_and_base + ) # we don't want to debug threading or anything related to pydevd if file_type is not None: if file_type == 1: # inlining LIB_FILE = 1 if not py_db.in_project_scope(frame, abs_path_canonical_path_and_base[0]): # if DEBUG: print('skipped: trace_dispatch (not in scope)', abs_path_canonical_path_and_base[2], frame.f_lineno, event, frame.f_code.co_name, file_type) cache_skips[frame_cache_key] = 1 - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE else: # if DEBUG: print('skipped: trace_dispatch', abs_path_canonical_path_and_base[2], frame.f_lineno, event, frame.f_code.co_name, file_type) cache_skips[frame_cache_key] = 1 - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE if py_db.is_files_filter_enabled: if py_db.apply_files_filter(frame, abs_path_canonical_path_and_base[0], False): cache_skips[frame_cache_key] = 1 - if is_stepping and additional_info.pydev_original_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE) and not _global_notify_skipped_step_in: + if ( + is_stepping + and additional_info.pydev_original_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE) + and not _global_notify_skipped_step_in + ): notify_skipped_step_in_because_of_filters(py_db, frame) # A little gotcha, sometimes when we're stepping in we have to stop in a # return event showing the back frame as the current frame, so, we need # to check not only the current frame but the back frame too. back_frame = frame.f_back - if back_frame is not None and pydev_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE, CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE): + if back_frame is not None and pydev_step_cmd in ( + CMD_STEP_INTO, + CMD_STEP_INTO_MY_CODE, + CMD_STEP_RETURN, + CMD_STEP_RETURN_MY_CODE, + ): if py_db.apply_files_filter(back_frame, back_frame.f_code.co_filename, False): back_frame_cache_key = back_frame.f_code cache_skips[back_frame_cache_key] = 1 # if DEBUG: print('skipped: trace_dispatch (filtered out: 1)', frame_cache_key, frame.f_lineno, event, frame.f_code.co_name) - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE else: # if DEBUG: print('skipped: trace_dispatch (filtered out: 2)', frame_cache_key, frame.f_lineno, event, frame.f_code.co_name) - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE # if DEBUG: print('trace_dispatch', filename, frame.f_lineno, event, frame.f_code.co_name, file_type) @@ -435,14 +464,19 @@ def __call__(self, frame, event, arg): # reference to the frame). ret = PyDBFrame( ( - py_db, abs_path_canonical_path_and_base, additional_info, t, frame_skips_cache, frame_cache_key, + py_db, + abs_path_canonical_path_and_base, + additional_info, + t, + frame_skips_cache, + frame_cache_key, ) ).trace_dispatch(frame, event, arg) if ret is None: # 1 means skipped because of filters. # 2 means skipped because no breakpoints were hit. cache_skips[frame_cache_key] = 2 - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE # IFDEF CYTHON # frame.f_trace = SafeCallWrapper(ret) # Make sure we keep the returned tracer. @@ -452,11 +486,11 @@ def __call__(self, frame, event, arg): return ret except SystemExit: - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE except Exception: if py_db.pydb_disposed: - return None if event == 'call' else NO_FTRACE # Don't log errors when we're shutting down. + return None if event == "call" else NO_FTRACE # Don't log errors when we're shutting down. # Log it try: if pydev_log_exception is not None: @@ -466,7 +500,7 @@ def __call__(self, frame, event, arg): # Error logging? We're really in the interpreter shutdown... # (https://github.com/fabioz/PyDev.Debugger/issues/8) pass - return None if event == 'call' else NO_FTRACE + return None if event == "call" else NO_FTRACE finally: additional_info.is_tracing -= 1 @@ -492,4 +526,4 @@ def __call__(self, frame, event, arg): if PYDEVD_USE_SYS_MONITORING: def fix_top_level_trace_and_get_trace_func(*args, **kwargs): - raise RuntimeError('Not used in sys.monitoring mode.') + raise RuntimeError("Not used in sys.monitoring mode.") diff --git a/_pydevd_bundle/pydevd_traceproperty.py b/_pydevd_bundle/pydevd_traceproperty.py index 2f38e4be8..c07e9534a 100644 --- a/_pydevd_bundle/pydevd_traceproperty.py +++ b/_pydevd_bundle/pydevd_traceproperty.py @@ -1,27 +1,28 @@ -'''For debug purpose we are replacing actual builtin property by the debug property -''' +"""For debug purpose we are replacing actual builtin property by the debug property +""" from _pydevd_bundle.pydevd_comm import get_global_debugger from _pydev_bundle import pydev_log -#======================================================================================================================= +# ======================================================================================================================= # replace_builtin_property -#======================================================================================================================= +# ======================================================================================================================= def replace_builtin_property(new_property=None): if new_property is None: new_property = DebugProperty original = property try: import builtins - builtins.__dict__['property'] = new_property + + builtins.__dict__["property"] = new_property except: pydev_log.exception() # @Reimport return original -#======================================================================================================================= +# ======================================================================================================================= # DebugProperty -#======================================================================================================================= +# ======================================================================================================================= class DebugProperty(object): """A custom property which allows python property to get controlled by the debugger and selectively disable/re-enable @@ -73,20 +74,16 @@ def __delete__(self, obj): global_debugger.enable_tracing() def getter(self, fget): - """Overriding getter decorator for the property - """ + """Overriding getter decorator for the property""" self.fget = fget return self def setter(self, fset): - """Overriding setter decorator for the property - """ + """Overriding setter decorator for the property""" self.fset = fset return self def deleter(self, fdel): - """Overriding deleter decorator for the property - """ + """Overriding deleter decorator for the property""" self.fdel = fdel return self - diff --git a/_pydevd_bundle/pydevd_utils.py b/_pydevd_bundle/pydevd_utils.py index b83e9b1aa..4ac447d37 100644 --- a/_pydevd_bundle/pydevd_utils.py +++ b/_pydevd_bundle/pydevd_utils.py @@ -13,9 +13,15 @@ import time import inspect import sys -from _pydevd_bundle.pydevd_constants import USE_CUSTOM_SYS_CURRENT_FRAMES, IS_PYPY, SUPPORT_GEVENT, \ - GEVENT_SUPPORT_NOT_SET_MSG, GENERATED_LEN_ATTR_NAME, PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT, \ - get_global_debugger +from _pydevd_bundle.pydevd_constants import ( + USE_CUSTOM_SYS_CURRENT_FRAMES, + IS_PYPY, + SUPPORT_GEVENT, + GEVENT_SUPPORT_NOT_SET_MSG, + GENERATED_LEN_ATTR_NAME, + PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT, + get_global_debugger, +) def save_main_module(file, module_name): @@ -24,24 +30,24 @@ def save_main_module(file, module_name): # This will prevent the pydevd script from contaminating the namespace for the script to be debugged # pretend pydevd is not the main module, and # convince the file to be debugged that it was loaded as main - m = sys.modules[module_name] = sys.modules['__main__'] + m = sys.modules[module_name] = sys.modules["__main__"] m.__name__ = module_name - loader = m.__loader__ if hasattr(m, '__loader__') else None - spec = spec_from_file_location('__main__', file, loader=loader) + loader = m.__loader__ if hasattr(m, "__loader__") else None + spec = spec_from_file_location("__main__", file, loader=loader) m = module_from_spec(spec) - sys.modules['__main__'] = m + sys.modules["__main__"] = m return m def is_current_thread_main_thread(): - if hasattr(threading, 'main_thread'): + if hasattr(threading, "main_thread"): return threading.current_thread() is threading.main_thread() else: return isinstance(threading.current_thread(), threading._MainThread) def get_main_thread(): - if hasattr(threading, 'main_thread'): + if hasattr(threading, "main_thread"): return threading.main_thread() else: for t in threading.enumerate(): @@ -58,9 +64,9 @@ def to_number(x): except ValueError: pass - l = x.find('(') + l = x.find("(") if l != -1: - y = x[0:l - 1] + y = x[0 : l - 1] # print y try: n = float(y) @@ -97,7 +103,7 @@ def print_exc(): traceback.print_exc() -def quote_smart(s, safe='/'): +def quote_smart(s, safe="/"): return quote(s, safe) @@ -120,9 +126,9 @@ def get_clsname_for_code(code, frame): if hasattr(first_arg_class, func_name): method = getattr(first_arg_class, func_name) func_code = None - if hasattr(method, 'func_code'): # Python2 + if hasattr(method, "func_code"): # Python2 func_code = method.func_code - elif hasattr(method, '__code__'): # Python3 + elif hasattr(method, "__code__"): # Python3 func_code = method.__code__ if func_code and func_code == code: clsname = first_arg_class.__name__ @@ -132,7 +138,7 @@ def get_clsname_for_code(code, frame): def get_non_pydevd_threads(): threads = threading.enumerate() - return [t for t in threads if t and not getattr(t, 'is_pydev_daemon_thread', False)] + return [t for t in threads if t and not getattr(t, "is_pydev_daemon_thread", False)] if USE_CUSTOM_SYS_CURRENT_FRAMES and IS_PYPY: @@ -144,9 +150,9 @@ def get_non_pydevd_threads(): def dump_threads(stream=None, show_pydevd_threads=True): - ''' + """ Helper to dump thread info. - ''' + """ if stream is None: stream = sys.stderr thread_id_to_name_and_is_pydevd_thread = {} @@ -156,17 +162,17 @@ def dump_threads(stream=None, show_pydevd_threads=True): threading_enumerate = threading.enumerate for t in threading_enumerate(): - is_pydevd_thread = getattr(t, 'is_pydev_daemon_thread', False) + is_pydevd_thread = getattr(t, "is_pydev_daemon_thread", False) thread_id_to_name_and_is_pydevd_thread[t.ident] = ( - '%s (daemon: %s, pydevd thread: %s)' % (t.name, t.daemon, is_pydevd_thread), - is_pydevd_thread + "%s (daemon: %s, pydevd thread: %s)" % (t.name, t.daemon, is_pydevd_thread), + is_pydevd_thread, ) except: pass - stream.write('===============================================================================\n') - stream.write('Threads running\n') - stream.write('================================= Thread Dump =================================\n') + stream.write("===============================================================================\n") + stream.write("Threads running\n") + stream.write("================================= Thread Dump =================================\n") stream.flush() for thread_id, frame in _tid_to_frame_for_dump_threads().items(): @@ -174,26 +180,25 @@ def dump_threads(stream=None, show_pydevd_threads=True): if not show_pydevd_threads and is_pydevd_thread: continue - stream.write('\n-------------------------------------------------------------------------------\n') + stream.write("\n-------------------------------------------------------------------------------\n") stream.write(" Thread %s" % (name,)) - stream.write('\n\n') + stream.write("\n\n") for i, (filename, lineno, name, line) in enumerate(traceback.extract_stack(frame)): - stream.write(' File "%s", line %d, in %s\n' % (filename, lineno, name)) if line: stream.write(" %s\n" % (line.strip())) - if i == 0 and 'self' in frame.f_locals: - stream.write(' self: ') + if i == 0 and "self" in frame.f_locals: + stream.write(" self: ") try: - stream.write(str(frame.f_locals['self'])) + stream.write(str(frame.f_locals["self"])) except: - stream.write('Unable to get str of: %s' % (type(frame.f_locals['self']),)) - stream.write('\n') + stream.write("Unable to get str of: %s" % (type(frame.f_locals["self"]),)) + stream.write("\n") stream.flush() - stream.write('\n=============================== END Thread Dump ===============================') + stream.write("\n=============================== END Thread Dump ===============================") stream.flush() @@ -201,14 +206,14 @@ def _extract_variable_nested_braces(char_iter): expression = [] level = 0 for c in char_iter: - if c == '{': + if c == "{": level += 1 - if c == '}': + if c == "}": level -= 1 if level == -1: - return ''.join(expression).strip() + return "".join(expression).strip() expression.append(c) - raise SyntaxError('Unbalanced braces in expression.') + raise SyntaxError("Unbalanced braces in expression.") def _extract_expression_list(log_message): @@ -217,15 +222,15 @@ def _extract_expression_list(log_message): expression_vars = [] char_iter = iter(log_message) for c in char_iter: - if c == '{': + if c == "{": expression_var = _extract_variable_nested_braces(char_iter) if expression_var: - expression.append('%s') + expression.append("%s") expression_vars.append(expression_var) else: expression.append(c) - expression = ''.join(expression) + expression = "".join(expression) return expression, expression_vars @@ -233,34 +238,34 @@ def convert_dap_log_message_to_expression(log_message): try: expression, expression_vars = _extract_expression_list(log_message) except SyntaxError: - return repr('Unbalanced braces in: %s' % (log_message)) + return repr("Unbalanced braces in: %s" % (log_message)) if not expression_vars: return repr(expression) # Note: use '%' to be compatible with Python 2.6. - return repr(expression) + ' % (' + ', '.join(str(x) for x in expression_vars) + ',)' + return repr(expression) + " % (" + ", ".join(str(x) for x in expression_vars) + ",)" def notify_about_gevent_if_needed(stream=None): - ''' + """ When debugging with gevent check that the gevent flag is used if the user uses the gevent monkey-patching. :return bool: Returns True if a message had to be shown to the user and False otherwise. - ''' + """ stream = stream if stream is not None else sys.stderr if not SUPPORT_GEVENT: - gevent_monkey = sys.modules.get('gevent.monkey') + gevent_monkey = sys.modules.get("gevent.monkey") if gevent_monkey is not None: try: saved = gevent_monkey.saved except AttributeError: - pydev_log.exception_once('Error checking for gevent monkey-patching.') + pydev_log.exception_once("Error checking for gevent monkey-patching.") return False if saved: # Note: print to stderr as it may deadlock the debugger. - sys.stderr.write('%s\n' % (GEVENT_SUPPORT_NOT_SET_MSG,)) + sys.stderr.write("%s\n" % (GEVENT_SUPPORT_NOT_SET_MSG,)) return True return False @@ -299,11 +304,10 @@ def isinstance_checked(obj, cls): class ScopeRequest(object): - - __slots__ = ['variable_reference', 'scope'] + __slots__ = ["variable_reference", "scope"] def __init__(self, variable_reference, scope): - assert scope in ('globals', 'locals') + assert scope in ("globals", "locals") self.variable_reference = variable_reference self.scope = scope @@ -321,15 +325,15 @@ def __hash__(self): class DAPGrouper(object): - ''' + """ Note: this is a helper class to group variables on the debug adapter protocol (DAP). For the xml protocol the type is just added to each variable and the UI can group/hide it as needed. - ''' + """ - SCOPE_SPECIAL_VARS = 'special variables' - SCOPE_PROTECTED_VARS = 'protected variables' - SCOPE_FUNCTION_VARS = 'function variables' - SCOPE_CLASS_VARS = 'class variables' + SCOPE_SPECIAL_VARS = "special variables" + SCOPE_PROTECTED_VARS = "protected variables" + SCOPE_FUNCTION_VARS = "function variables" + SCOPE_CLASS_VARS = "class variables" SCOPES_SORTED = [ SCOPE_SPECIAL_VARS, @@ -338,7 +342,7 @@ class DAPGrouper(object): SCOPE_CLASS_VARS, ] - __slots__ = ['variable_reference', 'scope', 'contents_debug_adapter_protocol'] + __slots__ = ["variable_reference", "scope", "contents_debug_adapter_protocol"] def __init__(self, scope): self.variable_reference = id(self) @@ -361,14 +365,14 @@ def __hash__(self): return hash((self.variable_reference, self.scope)) def __repr__(self): - return '' + return "" def __str__(self): - return '' + return "" def interrupt_main_thread(main_thread=None): - ''' + """ Generates a KeyboardInterrupt in the main thread by sending a Ctrl+C or by calling thread.interrupt_main(). @@ -378,21 +382,21 @@ def interrupt_main_thread(main_thread=None): Note: if unable to send a Ctrl+C, the KeyboardInterrupt will only be raised when the next Python instruction is about to be executed (so, it won't interrupt a sleep(1000)). - ''' + """ if main_thread is None: main_thread = threading.main_thread() - pydev_log.debug('Interrupt main thread.') + pydev_log.debug("Interrupt main thread.") called = False try: - if os.name == 'posix': + if os.name == "posix": # On Linux we can't interrupt 0 as in Windows because it's # actually owned by a process -- on the good side, signals # work much better on Linux! os.kill(os.getpid(), signal.SIGINT) called = True - elif os.name == 'nt': + elif os.name == "nt": # This generates a Ctrl+C only for the current process and not # to the process group! # Note: there doesn't seem to be any public documentation for this @@ -417,33 +421,32 @@ def interrupt_main_thread(main_thread=None): except: # If something went wrong, fallback to interrupting when the next # Python instruction is being called. - pydev_log.exception('Error interrupting main thread (using fallback).') + pydev_log.exception("Error interrupting main thread (using fallback).") if not called: try: # In this case, we don't really interrupt a sleep() nor IO operations # (this makes the KeyboardInterrupt be sent only when the next Python # instruction is about to be executed). - if hasattr(thread, 'interrupt_main'): + if hasattr(thread, "interrupt_main"): thread.interrupt_main() else: main_thread._thread.interrupt() # Jython except: - pydev_log.exception('Error on interrupt main thread fallback.') + pydev_log.exception("Error on interrupt main thread fallback.") class Timer(object): - def __init__(self, min_diff=PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT): self.min_diff = min_diff self._curr_time = time.time() - def print_time(self, msg='Elapsed:'): + def print_time(self, msg="Elapsed:"): old = self._curr_time new = self._curr_time = time.time() diff = new - old if diff >= self.min_diff: - print('%s: %.2fs' % (msg, diff)) + print("%s: %.2fs" % (msg, diff)) def _report_slow(self, compute_msg, *args): old = self._curr_time @@ -465,16 +468,14 @@ def _compute_repr_slow(self, diff, attrs_tab_separated, attr_name, attr_type): pass if attrs_tab_separated: return ( - 'pydevd warning: Computing repr of %s.%s (%s) was slow (took %.2fs).\n' - 'Customize report timeout by setting the `PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT` environment variable to a higher timeout (default is: %ss)\n' - ) % ( - attrs_tab_separated.replace('\t', '.'), attr_name, attr_type, diff, PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT) + "pydevd warning: Computing repr of %s.%s (%s) was slow (took %.2fs).\n" + "Customize report timeout by setting the `PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT` environment variable to a higher timeout (default is: %ss)\n" + ) % (attrs_tab_separated.replace("\t", "."), attr_name, attr_type, diff, PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT) else: return ( - 'pydevd warning: Computing repr of %s (%s) was slow (took %.2fs)\n' - 'Customize report timeout by setting the `PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT` environment variable to a higher timeout (default is: %ss)\n' - ) % ( - attr_name, attr_type, diff, PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT) + "pydevd warning: Computing repr of %s (%s) was slow (took %.2fs)\n" + "Customize report timeout by setting the `PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT` environment variable to a higher timeout (default is: %ss)\n" + ) % (attr_name, attr_type, diff, PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT) def report_if_getting_attr_slow(self, cls, attr_name): self._report_slow(self._compute_get_attr_slow, cls, attr_name) @@ -485,32 +486,32 @@ def _compute_get_attr_slow(self, diff, cls, attr_name): except: pass return ( - 'pydevd warning: Getting attribute %s.%s was slow (took %.2fs)\n' - 'Customize report timeout by setting the `PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT` environment variable to a higher timeout (default is: %ss)\n' - ) % (cls, attr_name, diff, PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT) + "pydevd warning: Getting attribute %s.%s was slow (took %.2fs)\n" + "Customize report timeout by setting the `PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT` environment variable to a higher timeout (default is: %ss)\n" + ) % (cls, attr_name, diff, PYDEVD_WARN_SLOW_RESOLVE_TIMEOUT) def import_attr_from_module(import_with_attr_access): - if '.' not in import_with_attr_access: + if "." not in import_with_attr_access: # We need at least one '.' (we don't support just the module import, we need the attribute access too). - raise ImportError('Unable to import module with attr access: %s' % (import_with_attr_access,)) + raise ImportError("Unable to import module with attr access: %s" % (import_with_attr_access,)) - module_name, attr_name = import_with_attr_access.rsplit('.', 1) + module_name, attr_name = import_with_attr_access.rsplit(".", 1) while True: try: mod = import_module(module_name) except ImportError: - if '.' not in module_name: - raise ImportError('Unable to import module with attr access: %s' % (import_with_attr_access,)) + if "." not in module_name: + raise ImportError("Unable to import module with attr access: %s" % (import_with_attr_access,)) - module_name, new_attr_part = module_name.rsplit('.', 1) - attr_name = new_attr_part + '.' + attr_name + module_name, new_attr_part = module_name.rsplit(".", 1) + attr_name = new_attr_part + "." + attr_name else: # Ok, we got the base module, now, get the attribute we need. try: - for attr in attr_name.split('.'): + for attr in attr_name.split("."): mod = getattr(mod, attr) return mod except: - raise ImportError('Unable to import module with attr access: %s' % (import_with_attr_access,)) + raise ImportError("Unable to import module with attr access: %s" % (import_with_attr_access,)) diff --git a/_pydevd_bundle/pydevd_vars.py b/_pydevd_bundle/pydevd_vars.py index 58d87c2d4..8ec4dec4a 100644 --- a/_pydevd_bundle/pydevd_vars.py +++ b/_pydevd_bundle/pydevd_vars.py @@ -2,8 +2,7 @@ resolution/conversion to XML. """ import pickle -from _pydevd_bundle.pydevd_constants import get_frame, get_current_thread_id, \ - iter_chars, silence_warnings_decorator, get_global_debugger +from _pydevd_bundle.pydevd_constants import get_frame, get_current_thread_id, iter_chars, silence_warnings_decorator, get_global_debugger from _pydevd_bundle.pydevd_xml import ExceptionOnEvaluate, get_type, var_to_xml from _pydev_bundle import pydev_log @@ -37,13 +36,13 @@ def iter_frames(frame): def dump_frames(thread_id): - sys.stdout.write('dumping frames\n') + sys.stdout.write("dumping frames\n") if thread_id != get_current_thread_id(threading.current_thread()): raise VariableError("find_frame: must execute on same thread") frame = get_frame() for frame in iter_frames(frame): - sys.stdout.write('%s\n' % pickle.dumps(frame)) + sys.stdout.write("%s\n" % pickle.dumps(frame)) @silence_warnings_decorator @@ -61,12 +60,13 @@ def getVariable(dbg, thread_id, frame_id, scope, locator): :note: when BY_ID is used, the frame_id is considered the id of the object to find and not the frame (as we don't care about the frame in this case). """ - if scope == 'BY_ID': + if scope == "BY_ID": if thread_id != get_current_thread_id(threading.current_thread()): raise VariableError("getVariable: must execute on same thread") try: import gc + objects = gc.get_objects() except: pass # Not all python variants have it. @@ -75,7 +75,7 @@ def getVariable(dbg, thread_id, frame_id, scope, locator): for var in objects: if id(var) == frame_id: if locator is not None: - locator_parts = locator.split('\t') + locator_parts = locator.split("\t") for k in locator_parts: _type, _type_name, resolver = get_type(var) var = resolver.resolve(var, k) @@ -83,7 +83,7 @@ def getVariable(dbg, thread_id, frame_id, scope, locator): return var # If it didn't return previously, we coudn't find it by id (i.e.: already garbage collected). - sys.stderr.write('Unable to find object with id: %s\n' % (frame_id,)) + sys.stderr.write("Unable to find object with id: %s\n" % (frame_id,)) return None frame = dbg.find_frame(thread_id, frame_id) @@ -91,14 +91,14 @@ def getVariable(dbg, thread_id, frame_id, scope, locator): return {} if locator is not None: - locator_parts = locator.split('\t') + locator_parts = locator.split("\t") else: locator_parts = [] for attr in locator_parts: - attr.replace("@_@TAB_CHAR@_@", '\t') + attr.replace("@_@TAB_CHAR@_@", "\t") - if scope == 'EXPRESSION': + if scope == "EXPRESSION": for count in range(len(locator_parts)): if count == 0: # An Expression can be in any scope (globals/locals), therefore it needs to evaluated as an expression @@ -141,8 +141,7 @@ def resolve_compound_variable_fields(dbg, thread_id, frame_id, scope, attrs): _type, type_name, resolver = get_type(var) return type_name, resolver.get_dictionary(var) except: - pydev_log.exception('Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s.', - thread_id, frame_id, scope, attrs) + pydev_log.exception("Error evaluating: thread_id: %s\nframe_id: %s\nscope: %s\nattrs: %s.", thread_id, frame_id, scope, attrs) def resolve_var_object(var, attrs): @@ -154,7 +153,7 @@ def resolve_var_object(var, attrs): :return: a value of resolved variable's attribute """ if attrs is not None: - attr_list = attrs.split('\t') + attr_list = attrs.split("\t") else: attr_list = [] for k in attr_list: @@ -171,7 +170,7 @@ def resolve_compound_var_object_fields(var, attrs): :param attrs: a sequence of variable's attributes separated by \t (i.e.: obj\tattr1\tattr2) :return: a dictionary of variables's fields """ - attr_list = attrs.split('\t') + attr_list = attrs.split("\t") for k in attr_list: type, _type_name, resolver = get_type(var) @@ -194,12 +193,12 @@ def custom_operation(dbg, thread_id, frame_id, scope, attrs, style, code_or_file expressionValue = getVariable(dbg, thread_id, frame_id, scope, attrs) try: - namespace = {'__name__': ''} + namespace = {"__name__": ""} if style == "EXECFILE": - namespace['__file__'] = code_or_file + namespace["__file__"] = code_or_file execfile(code_or_file, namespace, namespace) else: # style == EXEC - namespace['__file__'] = '' + namespace["__file__"] = "" Exec(code_or_file, namespace, namespace) return str(namespace[operation_fn_name](expressionValue)) @@ -238,9 +237,9 @@ def _expression_to_evaluate(expression): if proceed: if isinstance(expression, bytes): - expression = b''.join(new_lines) + expression = b"".join(new_lines) else: - expression = u''.join(new_lines) + expression = "".join(new_lines) return expression @@ -255,7 +254,7 @@ def eval_in_context(expression, global_vars, local_vars, py_db=None): if py_db is None: py_db = get_global_debugger() if py_db is None: - raise RuntimeError('Cannot evaluate async without py_db.') + raise RuntimeError("Cannot evaluate async without py_db.") t = _EvalAwaitInNewEventLoop(py_db, compiled, global_vars, local_vars) t.start() t.join() @@ -272,17 +271,17 @@ def eval_in_context(expression, global_vars, local_vars, py_db=None): # Ok, we have the initial error message, but let's see if we're dealing with a name mangling error... try: - if '.__' in expression: + if ".__" in expression: # Try to handle '__' name mangling (for simple cases such as self.__variable.__another_var). - split = expression.split('.') + split = expression.split(".") entry = split[0] if local_vars is None: local_vars = global_vars curr = local_vars[entry] # Note: we want the KeyError if it's not there. for entry in split[1:]: - if entry.startswith('__') and not hasattr(curr, entry): - entry = '_%s%s' % (curr.__class__.__name__, entry) + if entry.startswith("__") and not hasattr(curr, entry): + entry = "_%s%s" % (curr.__class__.__name__, entry) curr = getattr(curr, entry) result = curr @@ -299,7 +298,7 @@ def _run_with_interrupt_thread(original_func, py_db, curr_thread, frame, express if interrupt_thread_timeout > 0: on_interrupt_threads = pydevd_timeout.create_interrupt_this_thread_callback() - pydev_log.info('Doing evaluate with interrupt threads timeout: %s.', interrupt_thread_timeout) + pydev_log.info("Doing evaluate with interrupt threads timeout: %s.", interrupt_thread_timeout) if on_interrupt_threads is None: return original_func(py_db, frame, expression, is_exec) @@ -318,13 +317,13 @@ def _run_with_unblock_threads(original_func, py_db, curr_thread, frame, expressi unblock_threads_timeout = -1 # Don't use this if threads are managed individually. if unblock_threads_timeout >= 0: - pydev_log.info('Doing evaluate with unblock threads timeout: %s.', unblock_threads_timeout) + pydev_log.info("Doing evaluate with unblock threads timeout: %s.", unblock_threads_timeout) tid = get_current_thread_id(curr_thread) def on_timeout_unblock_threads(): on_timeout_unblock_threads.called = True - pydev_log.info('Resuming threads after evaluate timeout.') - resume_threads('*', except_thread=curr_thread) + pydev_log.info("Resuming threads after evaluate timeout.") + resume_threads("*", except_thread=curr_thread) py_db.threads_suspended_single_notification.on_thread_resume(tid, curr_thread) on_timeout_unblock_threads.called = False @@ -345,25 +344,24 @@ def on_timeout_unblock_threads(): def _evaluate_with_timeouts(original_func): - ''' + """ Provides a decorator that wraps the original evaluate to deal with slow evaluates. If some evaluation is too slow, we may show a message, resume threads or interrupt them as needed (based on the related configurations). - ''' + """ @functools.wraps(original_func) def new_func(py_db, frame, expression, is_exec): if py_db is None: # Only for testing... - pydev_log.critical('_evaluate_with_timeouts called without py_db!') + pydev_log.critical("_evaluate_with_timeouts called without py_db!") return original_func(py_db, frame, expression, is_exec) warn_evaluation_timeout = pydevd_constants.PYDEVD_WARN_EVALUATION_TIMEOUT curr_thread = threading.current_thread() def on_warn_evaluation_timeout(): - py_db.writer.add_command(py_db.cmd_factory.make_evaluation_timeout_msg( - py_db, expression, curr_thread)) + py_db.writer.add_command(py_db.cmd_factory.make_evaluation_timeout_msg(py_db, expression, curr_thread)) timeout_tracker = py_db.timeout_tracker # : :type timeout_tracker: TimeoutTracker with timeout_tracker.call_on_timeout(warn_evaluation_timeout, on_warn_evaluation_timeout): @@ -375,13 +373,14 @@ def on_warn_evaluation_timeout(): _ASYNC_COMPILE_FLAGS = None try: from ast import PyCF_ALLOW_TOP_LEVEL_AWAIT + _ASYNC_COMPILE_FLAGS = PyCF_ALLOW_TOP_LEVEL_AWAIT except: pass def compile_as_eval(expression): - ''' + """ :param expression: The expression to be _compiled. @@ -389,16 +388,16 @@ def compile_as_eval(expression): :return: code object :raises Exception if the expression cannot be evaluated. - ''' + """ expression_to_evaluate = _expression_to_evaluate(expression) if _ASYNC_COMPILE_FLAGS is not None: - return compile(expression_to_evaluate, '', 'eval', _ASYNC_COMPILE_FLAGS) + return compile(expression_to_evaluate, "", "eval", _ASYNC_COMPILE_FLAGS) else: - return compile(expression_to_evaluate, '', 'eval') + return compile(expression_to_evaluate, "", "eval") def _compile_as_exec(expression): - ''' + """ :param expression: The expression to be _compiled. @@ -406,16 +405,15 @@ def _compile_as_exec(expression): :return: code object :raises Exception if the expression cannot be evaluated. - ''' + """ expression_to_evaluate = _expression_to_evaluate(expression) if _ASYNC_COMPILE_FLAGS is not None: - return compile(expression_to_evaluate, '', 'exec', _ASYNC_COMPILE_FLAGS) + return compile(expression_to_evaluate, "", "exec", _ASYNC_COMPILE_FLAGS) else: - return compile(expression_to_evaluate, '', 'exec') + return compile(expression_to_evaluate, "", "exec") class _EvalAwaitInNewEventLoop(PyDBDaemonThread): - def __init__(self, py_db, compiled, updated_globals, updated_locals): PyDBDaemonThread.__init__(self, py_db) self._compiled = compiled @@ -432,6 +430,7 @@ async def _async_func(self): def _on_run(self): try: import asyncio + loop = asyncio.new_event_loop() asyncio.set_event_loop(loop) self.evaluated_value = asyncio.run(self._async_func()) @@ -441,7 +440,7 @@ def _on_run(self): @_evaluate_with_timeouts def evaluate_expression(py_db, frame, expression, is_exec): - ''' + """ :param str expression: The expression to be evaluated. @@ -483,7 +482,7 @@ def method(): :param py_db: The debugger. Only needed if some top-level await is detected (for creating a PyDBDaemonThread). - ''' + """ if frame is None: return @@ -523,17 +522,17 @@ def method(): updated_globals = {} updated_globals.update(frame.f_globals) updated_globals.update(frame.f_locals) - if 'globals' not in updated_globals: + if "globals" not in updated_globals: # If the user explicitly uses 'globals()' then we provide the # frame globals (unless he has shadowed it already). - updated_globals['globals'] = lambda: frame.f_globals + updated_globals["globals"] = lambda: frame.f_globals initial_globals = updated_globals.copy() updated_locals = None try: - expression = expression.replace('@LINE@', '\n') + expression = expression.replace("@LINE@", "\n") if is_exec: try: @@ -573,7 +572,7 @@ def method(): else: result = eval(compiled, updated_globals, updated_locals) if result is not None: # Only print if it's not None (as python does) - sys.stdout.write('%s\n' % (result,)) + sys.stdout.write("%s\n" % (result,)) return else: @@ -597,13 +596,12 @@ def method(): def change_attr_expression(frame, attr, expression, dbg, value=SENTINEL_VALUE): - '''Changes some attribute in a given frame. - ''' + """Changes some attribute in a given frame.""" if frame is None: return try: - expression = expression.replace('@LINE@', '\n') + expression = expression.replace("@LINE@", "\n") if dbg.plugin and value is SENTINEL_VALUE: result = dbg.plugin.change_variable(frame, attr, expression) @@ -618,7 +616,7 @@ def change_attr_expression(frame, attr, expression, dbg, value=SENTINEL_VALUE): frame.f_globals[attr] = value return frame.f_globals[attr] else: - if '.' not in attr: # i.e.: if we have a '.', we're changing some attribute of a local var. + if "." not in attr: # i.e.: if we have a '.', we're changing some attribute of a local var. if pydevd_save_locals.is_save_locals_available(): if value is SENTINEL_VALUE: value = eval(expression, frame.f_globals, frame.f_locals) @@ -630,7 +628,7 @@ def change_attr_expression(frame, attr, expression, dbg, value=SENTINEL_VALUE): if value is SENTINEL_VALUE: value = eval(expression, frame.f_globals, frame.f_locals) result = value - Exec('%s=%s' % (attr, expression), frame.f_globals, frame.f_locals) + Exec("%s=%s" % (attr, expression), frame.f_globals, frame.f_locals) return result except Exception: @@ -643,15 +641,15 @@ def change_attr_expression(frame, attr, expression, dbg, value=SENTINEL_VALUE): def table_like_struct_to_xml(array, name, roffset, coffset, rows, cols, format): _, type_name, _ = get_type(array) - if type_name == 'ndarray': + if type_name == "ndarray": array, metaxml, r, c, f = array_to_meta_xml(array, name, format) xml = metaxml - format = '%' + f + format = "%" + f if rows == -1 and cols == -1: rows = r cols = c xml += array_to_xml(array, roffset, coffset, rows, cols, format) - elif type_name == 'DataFrame': + elif type_name == "DataFrame": xml = dataframe_to_xml(array, name, roffset, coffset, rows, cols, format) else: raise VariableError("Do not know how to convert type %s to table" % (type_name)) @@ -681,9 +679,9 @@ def array_to_xml(array, roffset, coffset, rows, cols, format): array = array[roffset:] rows = min(rows, len(array)) - xml += "" % (rows, cols) + xml += '' % (rows, cols) for row in range(rows): - xml += "" % to_string(row) + xml += '' % to_string(row) for col in range(cols): value = array if rows == 1 or cols == 1: @@ -700,7 +698,7 @@ def array_to_xml(array, roffset, coffset, rows, cols, format): else: value = array[row][col] value = format % value - xml += var_to_xml(value, '') + xml += var_to_xml(value, "") return xml @@ -710,19 +708,19 @@ def array_to_meta_xml(array, name, format): l = len(array.shape) # initial load, compute slice - if format == '%': + if format == "%": if l > 2: - slice += '[0]' * (l - 2) + slice += "[0]" * (l - 2) for r in range(l - 2): array = array[0] - if type == 'f': - format = '.5f' - elif type == 'i' or type == 'u': - format = 'd' + if type == "f": + format = ".5f" + elif type == "i" or type == "u": + format = "d" else: - format = 's' + format = "s" else: - format = format.replace('%', '') + format = format.replace("%", "") l = len(array.shape) reslice = "" @@ -733,25 +731,25 @@ def array_to_meta_xml(array, name, format): # http://stackoverflow.com/questions/16837946/numpy-a-2-rows-1-column-file-loadtxt-returns-1row-2-columns # explanation: http://stackoverflow.com/questions/15165170/how-do-i-maintain-row-column-orientation-of-vectors-in-numpy?rq=1 # we use kind of a hack - get information about memory from C_CONTIGUOUS - is_row = array.flags['C_CONTIGUOUS'] + is_row = array.flags["C_CONTIGUOUS"] if is_row: rows = 1 cols = min(len(array), MAX_SLICE_SIZE) if cols < len(array): - reslice = '[0:%s]' % (cols) + reslice = "[0:%s]" % (cols) array = array[0:cols] else: cols = 1 rows = min(len(array), MAX_SLICE_SIZE) if rows < len(array): - reslice = '[0:%s]' % (rows) + reslice = "[0:%s]" % (rows) array = array[0:rows] elif l == 2: rows = min(array.shape[-2], MAX_SLICE_SIZE) cols = min(array.shape[-1], MAX_SLICE_SIZE) if cols < array.shape[-1] or rows < array.shape[-2]: - reslice = '[0:%s, 0:%s]' % (rows, cols) + reslice = "[0:%s, 0:%s]" % (rows, cols) array = array[0:rows, 0:cols] # avoid slice duplication @@ -761,8 +759,15 @@ def array_to_meta_xml(array, name, format): bounds = (0, 0) if type in "biufc": bounds = (array.min(), array.max()) - xml = '' % \ - (slice, rows, cols, format, type, bounds[1], bounds[0]) + xml = '' % ( + slice, + rows, + cols, + format, + type, + bounds[1], + bounds[0], + ) return array, xml, rows, cols, format @@ -781,13 +786,12 @@ def dataframe_to_xml(df, name, roffset, coffset, rows, cols, format): num_rows = min(df.shape[0], MAX_SLICE_SIZE) num_cols = min(df.shape[1], MAX_SLICE_SIZE) if (num_rows, num_cols) != df.shape: - df = df.iloc[0:num_rows, 0: num_cols] - slice = '.iloc[0:%s, 0:%s]' % (num_rows, num_cols) + df = df.iloc[0:num_rows, 0:num_cols] + slice = ".iloc[0:%s, 0:%s]" % (num_rows, num_cols) else: - slice = '' + slice = "" slice = name + slice - xml = '\n' % \ - (slice, num_rows, num_cols) + xml = '\n' % (slice, num_rows, num_cols) if (rows, cols) == (-1, -1): rows, cols = num_rows, num_cols @@ -805,39 +809,44 @@ def dataframe_to_xml(df, name, roffset, coffset, rows, cols, format): bounds = (0, 0) col_bounds[col] = bounds - df = df.iloc[roffset: roffset + rows, coffset: coffset + cols] + df = df.iloc[roffset : roffset + rows, coffset : coffset + cols] rows, cols = df.shape - xml += "\n" % (rows, cols) - format = format.replace('%', '') + xml += '\n' % (rows, cols) + format = format.replace("%", "") col_formats = [] - get_label = lambda label: str(label) if not isinstance(label, tuple) else '/'.join(map(str, label)) + get_label = lambda label: str(label) if not isinstance(label, tuple) else "/".join(map(str, label)) for col in range(cols): dtype = df.dtypes.iloc[col].kind - if dtype == 'f' and format: + if dtype == "f" and format: fmt = format - elif dtype == 'f': - fmt = '.5f' - elif dtype == 'i' or dtype == 'u': - fmt = 'd' + elif dtype == "f": + fmt = ".5f" + elif dtype == "i" or dtype == "u": + fmt = "d" else: - fmt = 's' - col_formats.append('%' + fmt) + fmt = "s" + col_formats.append("%" + fmt) bounds = col_bounds[col] - xml += '\n' % \ - (str(col), get_label(df.axes[1].values[col]), dtype, fmt, bounds[1], bounds[0]) + xml += '\n' % ( + str(col), + get_label(df.axes[1].values[col]), + dtype, + fmt, + bounds[1], + bounds[0], + ) for row, label in enumerate(iter(df.axes[0])): - xml += "\n" % \ - (str(row), get_label(label)) + xml += '\n' % (str(row), get_label(label)) xml += "\n" - xml += "\n" % (rows, cols) + xml += '\n' % (rows, cols) for row in range(rows): - xml += "\n" % str(row) + xml += '\n' % str(row) for col in range(cols): value = df.iat[row, col] value = col_formats[col] % value - xml += var_to_xml(value, '') + xml += var_to_xml(value, "") return xml diff --git a/_pydevd_bundle/pydevd_vm_type.py b/_pydevd_bundle/pydevd_vm_type.py index d2cf5b67b..aaca38e41 100644 --- a/_pydevd_bundle/pydevd_vm_type.py +++ b/_pydevd_bundle/pydevd_vm_type.py @@ -1,41 +1,40 @@ import sys -#======================================================================================================================= + +# ======================================================================================================================= # PydevdVmType -#======================================================================================================================= +# ======================================================================================================================= class PydevdVmType: - - PYTHON = 'python' - JYTHON = 'jython' + PYTHON = "python" + JYTHON = "jython" vm_type = None - -#======================================================================================================================= + +# ======================================================================================================================= # set_vm_type -#======================================================================================================================= +# ======================================================================================================================= def set_vm_type(vm_type): PydevdVmType.vm_type = vm_type - - -#======================================================================================================================= + + +# ======================================================================================================================= # get_vm_type -#======================================================================================================================= +# ======================================================================================================================= def get_vm_type(): if PydevdVmType.vm_type is None: setup_type() return PydevdVmType.vm_type -#======================================================================================================================= +# ======================================================================================================================= # setup_type -#======================================================================================================================= +# ======================================================================================================================= def setup_type(str=None): if str is not None: PydevdVmType.vm_type = str return - + if sys.platform.startswith("java"): PydevdVmType.vm_type = PydevdVmType.JYTHON else: PydevdVmType.vm_type = PydevdVmType.PYTHON - diff --git a/_pydevd_bundle/pydevd_xml.py b/_pydevd_bundle/pydevd_xml.py index 5d1ed0fd7..af8ad0faa 100644 --- a/_pydevd_bundle/pydevd_xml.py +++ b/_pydevd_bundle/pydevd_xml.py @@ -2,8 +2,13 @@ from _pydevd_bundle import pydevd_extension_utils from _pydevd_bundle import pydevd_resolver import sys -from _pydevd_bundle.pydevd_constants import BUILTINS_MODULE_NAME, MAXIMUM_VARIABLE_REPRESENTATION_SIZE, \ - RETURN_VALUES_DICT, LOAD_VALUES_ASYNC, DEFAULT_VALUE +from _pydevd_bundle.pydevd_constants import ( + BUILTINS_MODULE_NAME, + MAXIMUM_VARIABLE_REPRESENTATION_SIZE, + RETURN_VALUES_DICT, + LOAD_VALUES_ASYNC, + DEFAULT_VALUE, +) from _pydev_bundle.pydev_imports import quote from _pydevd_bundle.pydevd_extension_api import TypeResolveProvider, StrPresentationProvider from _pydevd_bundle.pydevd_utils import isinstance_checked, hasattr_checked, DAPGrouper @@ -20,11 +25,10 @@ def make_valid_xml_value(s): # Same thing as xml.sax.saxutils.escape but also escaping double quotes. - return s.replace("&", "&").replace('<', '<').replace('>', '>').replace('"', '"') + return s.replace("&", "&").replace("<", "<").replace(">", ">").replace('"', """) class ExceptionOnEvaluate: - def __init__(self, result, etype, tb): self.result = result self.etype = etype @@ -37,9 +41,11 @@ def __init__(self, result, etype, tb): def _create_default_type_map(): default_type_map = [ # None means that it should not be treated as a compound variable - # isintance does not accept a tuple on some versions of python, so, we must declare it expanded - (type(None), None,), + ( + type(None), + None, + ), (int, None), (float, None), (complex, None), @@ -50,6 +56,7 @@ def _create_default_type_map(): ] try: from collections import OrderedDict + default_type_map.insert(0, (OrderedDict, pydevd_resolver.orderedDictResolver)) # we should put it before dict except: @@ -76,6 +83,7 @@ def _create_default_type_map(): try: from django.utils.datastructures import MultiValueDict + default_type_map.insert(0, (MultiValueDict, pydevd_resolver.multiValueDictResolver)) # we should put it before dict except: @@ -83,6 +91,7 @@ def _create_default_type_map(): try: from django.forms import BaseForm + default_type_map.insert(0, (BaseForm, pydevd_resolver.djangoFormResolver)) # we should put it before instance resolver except: @@ -90,12 +99,14 @@ def _create_default_type_map(): try: from collections import deque + default_type_map.append((deque, pydevd_resolver.dequeResolver)) except: pass try: from ctypes import Array + default_type_map.append((Array, pydevd_resolver.tupleResolver)) except: pass @@ -105,6 +116,7 @@ def _create_default_type_map(): if _IS_JYTHON: from org.python import core # @UnresolvedImport + default_type_map.append((core.PyNone, None)) default_type_map.append((core.PyInteger, None)) default_type_map.append((core.PyLong, None)) @@ -116,7 +128,7 @@ def _create_default_type_map(): default_type_map.append((core.PyDictionary, pydevd_resolver.dictResolver)) default_type_map.append((core.PyStringMap, pydevd_resolver.dictResolver)) - if hasattr(core, 'PyJavaInstance'): + if hasattr(core, "PyJavaInstance"): # Jython 2.5b3 removed it. default_type_map.append((core.PyJavaInstance, pydevd_resolver.instanceResolver)) @@ -159,10 +171,10 @@ def get_type(self, o): # fallback to saying that it wasn't possible to get any info on it. return type_object, str(type_name), pydevd_resolver.defaultResolver - return 'Unable to get Type', 'Unable to get Type', None + return "Unable to get Type", "Unable to get Type", None except: # This happens for org.python.core.InitModule - return 'Unable to get Type', 'Unable to get Type', None + return "Unable to get Type", "Unable to get Type", None def _get_type(self, o, type_object, type_name): # Note: we could have an exception here if the type_object is not hashable... @@ -198,23 +210,23 @@ def _get_type(self, o, type_object, type_name): _base_get_type = _get_type def _get_type(self, o, type_object, type_name): - if type_name == 'org.python.core.PyJavaInstance': + if type_name == "org.python.core.PyJavaInstance": return type_object, type_name, pydevd_resolver.instanceResolver - if type_name == 'org.python.core.PyArray': + if type_name == "org.python.core.PyArray": return type_object, type_name, pydevd_resolver.jyArrayResolver return self._base_get_type(o, type_object, type_name) - def _get_str_from_provider(self, provider, o, context: Optional[str]=None): + def _get_str_from_provider(self, provider, o, context: Optional[str] = None): if context is not None: - get_str_in_context = getattr(provider, 'get_str_in_context', None) + get_str_in_context = getattr(provider, "get_str_in_context", None) if get_str_in_context is not None: return get_str_in_context(o, context) return provider.get_str(o) - def str_from_providers(self, o, type_object, type_name, context: Optional[str]=None): + def str_from_providers(self, o, type_object, type_name, context: Optional[str] = None): provider = self._type_to_str_provider_cache.get(type_object) if provider is self.NO_PROVIDER: @@ -256,7 +268,7 @@ def get_type(o): def is_builtin(x): - return getattr(x, '__module__', None) == BUILTINS_MODULE_NAME + return getattr(x, "__module__", None) == BUILTINS_MODULE_NAME def should_evaluate_full_value(val): @@ -267,11 +279,11 @@ def return_values_from_dict_to_xml(return_dict): res = [] for name, val in return_dict.items(): res.append(var_to_xml(val, name, additional_in_xml=' isRetVal="True"')) - return ''.join(res) + return "".join(res) def frame_vars_to_xml(frame_f_locals, hidden_ns=None): - """ dumps frame variables to XML + """dumps frame variables to XML """ xml = [] @@ -285,7 +297,7 @@ def frame_vars_to_xml(frame_f_locals, hidden_ns=None): v = frame_f_locals[k] eval_full_val = should_evaluate_full_value(v) - if k == '_pydev_stop_at_break': + if k == "_pydev_stop_at_break": continue if k == RETURN_VALUES_DICT: @@ -294,8 +306,7 @@ def frame_vars_to_xml(frame_f_locals, hidden_ns=None): else: if hidden_ns is not None and k in hidden_ns: - xml.append(var_to_xml(v, str(k), additional_in_xml=' isIPythonHidden="True"', - evaluate_full_value=eval_full_val)) + xml.append(var_to_xml(v, str(k), additional_in_xml=' isIPythonHidden="True"', evaluate_full_value=eval_full_val)) else: xml.append(var_to_xml(v, str(k), evaluate_full_value=eval_full_val)) except Exception: @@ -303,18 +314,18 @@ def frame_vars_to_xml(frame_f_locals, hidden_ns=None): # Show return values as the first entry. return_values_xml.extend(xml) - return ''.join(return_values_xml) + return "".join(return_values_xml) -def get_variable_details(val, evaluate_full_value=True, to_string=None, context: Optional[str]=None): - ''' +def get_variable_details(val, evaluate_full_value=True, to_string=None, context: Optional[str] = None): + """ :param context: This is the context in which the variable is being requested. Valid values: "watch", "repl", "hover", "clipboard" - ''' + """ try: # This should be faster than isinstance (but we have to protect against not having a '__class__' attribute). is_exception_on_eval = val.__class__ == ExceptionOnEvaluate @@ -339,57 +350,56 @@ def get_variable_details(val, evaluate_full_value=True, to_string=None, context: elif to_string is not None: value = to_string(v) - elif hasattr_checked(v, '__class__'): + elif hasattr_checked(v, "__class__"): if v.__class__ == frame_type: value = pydevd_resolver.frameResolver.get_frame_name(v) elif v.__class__ in (list, tuple): if len(v) > 300: - value = '%s: %s' % (str(v.__class__), '' % (len(v),)) + value = "%s: %s" % (str(v.__class__), "" % (len(v),)) else: - value = '%s: %s' % (str(v.__class__), v) + value = "%s: %s" % (str(v.__class__), v) else: try: cName = str(v.__class__) - if cName.find('.') != -1: - cName = cName.split('.')[-1] + if cName.find(".") != -1: + cName = cName.split(".")[-1] elif cName.find("'") != -1: # does not have '.' (could be something like ) - cName = cName[cName.index("'") + 1:] + cName = cName[cName.index("'") + 1 :] if cName.endswith("'>"): cName = cName[:-2] except: cName = str(v.__class__) - value = '%s: %s' % (cName, v) + value = "%s: %s" % (cName, v) else: value = str(v) except: try: value = repr(v) except: - value = 'Unable to get repr for %s' % v.__class__ + value = "Unable to get repr for %s" % v.__class__ # fix to work with unicode values try: if value.__class__ == bytes: - value = value.decode('utf-8', 'replace') + value = value.decode("utf-8", "replace") except TypeError: pass return type_name, type_qualifier, is_exception_on_eval, resolver, value -def var_to_xml(val, name, trim_if_too_big=True, additional_in_xml='', evaluate_full_value=True): - """ single variable or dictionary to xml representation """ +def var_to_xml(val, name, trim_if_too_big=True, additional_in_xml="", evaluate_full_value=True): + """single variable or dictionary to xml representation""" - type_name, type_qualifier, is_exception_on_eval, resolver, value = get_variable_details( - val, evaluate_full_value) + type_name, type_qualifier, is_exception_on_eval, resolver, value = get_variable_details(val, evaluate_full_value) - scope = get_var_scope(name, val, '', True) + scope = get_var_scope(name, val, "", True) try: - name = quote(name, '/>_= ') # TODO: Fix PY-5834 without using quote + name = quote(name, "/>_= ") # TODO: Fix PY-5834 without using quote except: pass @@ -398,17 +408,17 @@ def var_to_xml(val, name, trim_if_too_big=True, additional_in_xml='', evaluate_f if type_qualifier: xml_qualifier = 'qualifier="%s"' % make_valid_xml_value(type_qualifier) else: - xml_qualifier = '' + xml_qualifier = "" if value: # cannot be too big... communication may not handle it. if len(value) > MAXIMUM_VARIABLE_REPRESENTATION_SIZE and trim_if_too_big: value = value[0:MAXIMUM_VARIABLE_REPRESENTATION_SIZE] - value += '...' + value += "..." - xml_value = ' value="%s"' % (make_valid_xml_value(quote(value, '/>_= '))) + xml_value = ' value="%s"' % (make_valid_xml_value(quote(value, "/>_= "))) else: - xml_value = '' + xml_value = "" if is_exception_on_eval: xml_container = ' isErrorOnEval="True"' @@ -416,9 +426,9 @@ def var_to_xml(val, name, trim_if_too_big=True, additional_in_xml='', evaluate_f if resolver is not None: xml_container = ' isContainer="True"' else: - xml_container = '' + xml_container = "" if scope: - return ''.join((xml, xml_qualifier, xml_value, xml_container, additional_in_xml, ' scope="', scope, '"', ' />\n')) + return "".join((xml, xml_qualifier, xml_value, xml_container, additional_in_xml, ' scope="', scope, '"', " />\n")) else: - return ''.join((xml, xml_qualifier, xml_value, xml_container, additional_in_xml, ' />\n')) + return "".join((xml, xml_qualifier, xml_value, xml_container, additional_in_xml, " />\n")) diff --git a/_pydevd_frame_eval/pydevd_frame_eval_cython_wrapper.py b/_pydevd_frame_eval/pydevd_frame_eval_cython_wrapper.py index 0864a4e38..7b7effcfb 100644 --- a/_pydevd_frame_eval/pydevd_frame_eval_cython_wrapper.py +++ b/_pydevd_frame_eval/pydevd_frame_eval_cython_wrapper.py @@ -9,13 +9,13 @@ import sys try: - is_64bits = sys.maxsize > 2 ** 32 + is_64bits = sys.maxsize > 2**32 except: # In Jython this call fails, but this is Ok, we don't support Jython for speedups anyways. raise ImportError - plat = '32' + plat = "32" if is_64bits: - plat = '64' + plat = "64" # We also accept things as: # @@ -25,8 +25,8 @@ # to have multiple pre-compiled pyds distributed along the IDE # (generated by build_tools/build_binaries_windows.py). - mod_name = 'pydevd_frame_evaluator_%s_%s%s_%s' % (sys.platform, sys.version_info[0], sys.version_info[1], plat) - check_name = '_pydevd_frame_eval.%s' % (mod_name,) + mod_name = "pydevd_frame_evaluator_%s_%s%s_%s" % (sys.platform, sys.version_info[0], sys.version_info[1], plat) + check_name = "_pydevd_frame_eval.%s" % (mod_name,) mod = __import__(check_name) mod = getattr(mod, mod_name) except ImportError: diff --git a/_pydevd_frame_eval/pydevd_frame_eval_main.py b/_pydevd_frame_eval/pydevd_frame_eval_main.py index a4e1ce67d..1049be0dd 100644 --- a/_pydevd_frame_eval/pydevd_frame_eval_main.py +++ b/_pydevd_frame_eval/pydevd_frame_eval_main.py @@ -2,9 +2,18 @@ from _pydev_bundle import pydev_log from _pydevd_bundle.pydevd_trace_dispatch import USING_CYTHON -from _pydevd_bundle.pydevd_constants import USE_CYTHON_FLAG, ENV_FALSE_LOWER_VALUES, \ - ENV_TRUE_LOWER_VALUES, IS_PY36_OR_GREATER, IS_PY38_OR_GREATER, SUPPORT_GEVENT, IS_PYTHON_STACKLESS, \ - PYDEVD_USE_FRAME_EVAL, PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING, IS_PY311_OR_GREATER +from _pydevd_bundle.pydevd_constants import ( + USE_CYTHON_FLAG, + ENV_FALSE_LOWER_VALUES, + ENV_TRUE_LOWER_VALUES, + IS_PY36_OR_GREATER, + IS_PY38_OR_GREATER, + SUPPORT_GEVENT, + IS_PYTHON_STACKLESS, + PYDEVD_USE_FRAME_EVAL, + PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING, + IS_PY311_OR_GREATER, +) frame_eval_func = None stop_frame_eval = None @@ -13,16 +22,16 @@ # "NO" means we should not use frame evaluation, 'YES' we should use it (and fail if not there) and unspecified uses if possible. if ( - PYDEVD_USE_FRAME_EVAL in ENV_FALSE_LOWER_VALUES or - USE_CYTHON_FLAG in ENV_FALSE_LOWER_VALUES or - not USING_CYTHON or - - # Frame eval mode does not work with ipython compatible debugging (this happens because the - # way that frame eval works is run untraced and set tracing only for the frames with - # breakpoints, but ipython compatible debugging creates separate frames for what's logically - # the same frame). - PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING - ): + PYDEVD_USE_FRAME_EVAL in ENV_FALSE_LOWER_VALUES + or USE_CYTHON_FLAG in ENV_FALSE_LOWER_VALUES + or not USING_CYTHON + or + # Frame eval mode does not work with ipython compatible debugging (this happens because the + # way that frame eval works is run untraced and set tracing only for the frames with + # breakpoints, but ipython compatible debugging creates separate frames for what's logically + # the same frame). + PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING +): USING_FRAME_EVAL = False elif SUPPORT_GEVENT or (IS_PYTHON_STACKLESS and not IS_PY38_OR_GREATER): @@ -35,7 +44,13 @@ elif PYDEVD_USE_FRAME_EVAL in ENV_TRUE_LOWER_VALUES and not IS_PY311_OR_GREATER: # Python 3.11 onwards doesn't have frame eval mode implemented # Fail if unable to use - from _pydevd_frame_eval.pydevd_frame_eval_cython_wrapper import frame_eval_func, stop_frame_eval, dummy_trace_dispatch, clear_thread_local_info + from _pydevd_frame_eval.pydevd_frame_eval_cython_wrapper import ( + frame_eval_func, + stop_frame_eval, + dummy_trace_dispatch, + clear_thread_local_info, + ) + USING_FRAME_EVAL = True else: @@ -44,7 +59,13 @@ if IS_PY36_OR_GREATER and not IS_PY311_OR_GREATER: # Python 3.11 onwards doesn't have frame eval mode implemented try: - from _pydevd_frame_eval.pydevd_frame_eval_cython_wrapper import frame_eval_func, stop_frame_eval, dummy_trace_dispatch, clear_thread_local_info + from _pydevd_frame_eval.pydevd_frame_eval_cython_wrapper import ( + frame_eval_func, + stop_frame_eval, + dummy_trace_dispatch, + clear_thread_local_info, + ) + USING_FRAME_EVAL = True except ImportError: pydev_log.show_compile_cython_command_line() diff --git a/_pydevd_frame_eval/pydevd_frame_tracing.py b/_pydevd_frame_eval/pydevd_frame_tracing.py index 7b34cd50c..a14f999bd 100644 --- a/_pydevd_frame_eval/pydevd_frame_tracing.py +++ b/_pydevd_frame_eval/pydevd_frame_tracing.py @@ -18,7 +18,7 @@ def set_trace_func(self, trace_func): def update_globals_dict(globals_dict): - new_globals = {'_pydev_stop_at_break': _pydev_stop_at_break} + new_globals = {"_pydev_stop_at_break": _pydev_stop_at_break} globals_dict.update(new_globals) @@ -50,9 +50,9 @@ def _pydev_stop_at_break(line): return pydev_log.debug("Setting f_trace due to frame eval mode in file: %s on line %s", frame.f_code.co_filename, line) - additional_info.trace_suspend_type = 'frame_eval' + additional_info.trace_suspend_type = "frame_eval" - pydevd_frame_eval_cython_wrapper = sys.modules['_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper'] + pydevd_frame_eval_cython_wrapper = sys.modules["_pydevd_frame_eval.pydevd_frame_eval_cython_wrapper"] thread_info = pydevd_frame_eval_cython_wrapper.get_thread_info_py() if thread_info.thread_trace_func is not None: frame.f_trace = thread_info.thread_trace_func @@ -63,7 +63,7 @@ def _pydev_stop_at_break(line): def _pydev_needs_stop_at_break(line): - ''' + """ We separate the functionality into 2 functions so that we can generate a bytecode which generates a spurious line change so that we can do: @@ -72,7 +72,7 @@ def _pydev_needs_stop_at_break(line): _pydev_stop_at_break() # then, proceed to go to the current line # (which will then trigger a line event). - ''' + """ t = threading.current_thread() try: additional_info = t.additional_info @@ -119,4 +119,3 @@ def _pydev_needs_stop_at_break(line): additional_info.is_tracing -= 1 return False - diff --git a/_pydevd_frame_eval/pydevd_modify_bytecode.py b/_pydevd_frame_eval/pydevd_modify_bytecode.py index 7e7635850..8c9dabb03 100644 --- a/_pydevd_frame_eval/pydevd_modify_bytecode.py +++ b/_pydevd_frame_eval/pydevd_modify_bytecode.py @@ -14,43 +14,42 @@ class DebugHelper(object): - def __init__(self): - self._debug_dir = os.path.join(os.path.dirname(__file__), 'debug_info') + self._debug_dir = os.path.join(os.path.dirname(__file__), "debug_info") try: os.makedirs(self._debug_dir) except: pass self._next = partial(next, itertools.count(0)) - def _get_filename(self, op_number=None, prefix=''): + def _get_filename(self, op_number=None, prefix=""): if op_number is None: op_number = self._next() - name = '%03d_before.txt' % op_number + name = "%03d_before.txt" % op_number else: - name = '%03d_change.txt' % op_number + name = "%03d_change.txt" % op_number filename = os.path.join(self._debug_dir, prefix + name) return filename, op_number - def write_bytecode(self, b, op_number=None, prefix=''): + def write_bytecode(self, b, op_number=None, prefix=""): filename, op_number = self._get_filename(op_number, prefix) - with open(filename, 'w') as stream: + with open(filename, "w") as stream: bytecode.dump_bytecode(b, stream=stream, lineno=True) return op_number - def write_dis(self, code_to_modify, op_number=None, prefix=''): + def write_dis(self, code_to_modify, op_number=None, prefix=""): filename, op_number = self._get_filename(op_number, prefix) - with open(filename, 'w') as stream: - stream.write('-------- ') - stream.write('-------- ') - stream.write('id(code_to_modify): %s' % id(code_to_modify)) - stream.write('\n\n') + with open(filename, "w") as stream: + stream.write("-------- ") + stream.write("-------- ") + stream.write("id(code_to_modify): %s" % id(code_to_modify)) + stream.write("\n\n") dis.dis(code_to_modify, file=stream) return op_number -_CodeLineInfo = namedtuple('_CodeLineInfo', 'line_to_offset, first_line, last_line') +_CodeLineInfo = namedtuple("_CodeLineInfo", "line_to_offset, first_line, last_line") # Note: this method has a version in cython too (that one is usually used, this is just for tests). @@ -72,19 +71,15 @@ def _get_code_line_info(code_obj): debug_helper = DebugHelper() -def get_instructions_to_add( - stop_at_line, - _pydev_stop_at_break=_pydev_stop_at_break, - _pydev_needs_stop_at_break=_pydev_needs_stop_at_break - ): - ''' +def get_instructions_to_add(stop_at_line, _pydev_stop_at_break=_pydev_stop_at_break, _pydev_needs_stop_at_break=_pydev_needs_stop_at_break): + """ This is the bytecode for something as: if _pydev_needs_stop_at_break(): _pydev_stop_at_break() but with some special handling for lines. - ''' + """ # Good reference to how things work regarding line numbers and jumps: # https://github.com/python/cpython/blob/3.6/Objects/lnotab_notes.txt @@ -100,7 +95,6 @@ def get_instructions_to_add( Instr("LOAD_CONST", stop_at_line, lineno=stop_at_line), Instr("CALL_FUNCTION", 1, lineno=stop_at_line), Instr("POP_JUMP_IF_FALSE", label, lineno=stop_at_line), - # -- _pydev_stop_at_break() # # Note that this has line numbers -1 so that when the NOP just below @@ -109,7 +103,6 @@ def get_instructions_to_add( Instr("LOAD_CONST", stop_at_line, lineno=spurious_line), Instr("CALL_FUNCTION", 1, lineno=spurious_line), Instr("POP_TOP", lineno=spurious_line), - # Reason for the NOP: Python will give us a 'line' trace event whenever we forward jump to # the first instruction of a line, so, in the case where we haven't added a programmatic # breakpoint (either because we didn't hit a breakpoint anymore or because it was already @@ -122,7 +115,6 @@ def get_instructions_to_add( class _Node(object): - def __init__(self, data): self.prev = None self.next = None @@ -158,11 +150,11 @@ def prepend(self, data): class _HelperBytecodeList(object): - ''' + """ A helper double-linked list to make the manipulation a bit easier (so that we don't need to keep track of indices that change) and performant (because adding multiple items to the middle of a regular list isn't ideal). - ''' + """ def __init__(self, lst=None): self._head = None @@ -206,16 +198,24 @@ def __iter__(self): _PREDICT_TABLE = { - 'LIST_APPEND': ('JUMP_ABSOLUTE',), - 'SET_ADD': ('JUMP_ABSOLUTE',), - 'GET_ANEXT': ('LOAD_CONST',), - 'GET_AWAITABLE': ('LOAD_CONST',), - 'DICT_MERGE': ('CALL_FUNCTION_EX',), - 'MAP_ADD': ('JUMP_ABSOLUTE',), - 'COMPARE_OP': ('POP_JUMP_IF_FALSE', 'POP_JUMP_IF_TRUE',), - 'IS_OP': ('POP_JUMP_IF_FALSE', 'POP_JUMP_IF_TRUE',), - 'CONTAINS_OP': ('POP_JUMP_IF_FALSE', 'POP_JUMP_IF_TRUE',), - + "LIST_APPEND": ("JUMP_ABSOLUTE",), + "SET_ADD": ("JUMP_ABSOLUTE",), + "GET_ANEXT": ("LOAD_CONST",), + "GET_AWAITABLE": ("LOAD_CONST",), + "DICT_MERGE": ("CALL_FUNCTION_EX",), + "MAP_ADD": ("JUMP_ABSOLUTE",), + "COMPARE_OP": ( + "POP_JUMP_IF_FALSE", + "POP_JUMP_IF_TRUE", + ), + "IS_OP": ( + "POP_JUMP_IF_FALSE", + "POP_JUMP_IF_TRUE", + ), + "CONTAINS_OP": ( + "POP_JUMP_IF_FALSE", + "POP_JUMP_IF_TRUE", + ), # Note: there are some others with PREDICT on ceval, but they have more logic # and it needs more experimentation to know how it behaves in the static generated # code (and it's only an issue for us if there's actually a line change between @@ -236,12 +236,12 @@ def __iter__(self): def insert_pydevd_breaks( - code_to_modify, - breakpoint_lines, - code_line_info=None, - _pydev_stop_at_break=_pydev_stop_at_break, - _pydev_needs_stop_at_break=_pydev_needs_stop_at_break, - ): + code_to_modify, + breakpoint_lines, + code_line_info=None, + _pydev_stop_at_break=_pydev_stop_at_break, + _pydev_needs_stop_at_break=_pydev_needs_stop_at_break, +): """ Inserts pydevd programmatic breaks into the code (at the given lines). @@ -268,14 +268,14 @@ def insert_pydevd_breaks( for line in breakpoint_lines: if line <= 0: # The first line is line 1, so, a break at line 0 is not valid. - pydev_log.info('Trying to add breakpoint in invalid line: %s', line) + pydev_log.info("Trying to add breakpoint in invalid line: %s", line) return False, code_to_modify try: b = bytecode.Bytecode.from_code(code_to_modify) if DEBUG: - op_number_bytecode = debug_helper.write_bytecode(b, prefix='bytecode.') + op_number_bytecode = debug_helper.write_bytecode(b, prefix="bytecode.") helper_list = _HelperBytecodeList(b) @@ -286,8 +286,8 @@ def insert_pydevd_breaks( last_lineno = None while curr_node is not None: instruction = curr_node.data - instruction_lineno = getattr(instruction, 'lineno', None) - curr_name = getattr(instruction, 'name', None) + instruction_lineno = getattr(instruction, "lineno", None) + curr_name = getattr(instruction, "name", None) if FIX_PREDICT: predict_targets = _PREDICT_TABLE.get(curr_name) @@ -297,9 +297,9 @@ def insert_pydevd_breaks( # that it does things the way that ceval actually interprets it. # See: https://mail.python.org/archives/list/python-dev@python.org/thread/CP2PTFCMTK57KM3M3DLJNWGO66R5RVPB/ next_instruction = curr_node.next.data - next_name = getattr(next_instruction, 'name', None) + next_name = getattr(next_instruction, "name", None) if next_name in predict_targets: - next_instruction_lineno = getattr(next_instruction, 'lineno', None) + next_instruction_lineno = getattr(next_instruction, "lineno", None) if next_instruction_lineno: next_instruction.lineno = None @@ -323,9 +323,7 @@ def insert_pydevd_breaks( if instruction_lineno in modified_breakpoint_lines: added_breaks_in_lines.add(instruction_lineno) - if curr_node.prev is not None and curr_node.prev.data.__class__ == Label \ - and curr_name == 'POP_TOP': - + if curr_node.prev is not None and curr_node.prev.data.__class__ == Label and curr_name == "POP_TOP": # If we have a SETUP_FINALLY where the target is a POP_TOP, we can't change # the target to be the breakpoint instruction (this can crash the interpreter). @@ -333,7 +331,7 @@ def insert_pydevd_breaks( instruction_lineno, _pydev_stop_at_break=_pydev_stop_at_break, _pydev_needs_stop_at_break=_pydev_needs_stop_at_break, - ): + ): curr_node = curr_node.append(new_instruction) else: @@ -341,7 +339,7 @@ def insert_pydevd_breaks( instruction_lineno, _pydev_stop_at_break=_pydev_stop_at_break, _pydev_needs_stop_at_break=_pydev_needs_stop_at_break, - ): + ): curr_node.prepend(new_instruction) curr_node = curr_node.next @@ -349,12 +347,12 @@ def insert_pydevd_breaks( b[:] = helper_list if DEBUG: - debug_helper.write_bytecode(b, op_number_bytecode, prefix='bytecode.') + debug_helper.write_bytecode(b, op_number_bytecode, prefix="bytecode.") new_code = b.to_code() except: - pydev_log.exception('Error inserting pydevd breaks.') + pydev_log.exception("Error inserting pydevd breaks.") return False, code_to_modify if DEBUG: @@ -362,4 +360,3 @@ def insert_pydevd_breaks( debug_helper.write_dis(new_code, op_number) return True, new_code - diff --git a/_pydevd_frame_eval/vendored/bytecode/__init__.py b/_pydevd_frame_eval/vendored/bytecode/__init__.py index f970fbc00..a68ddcc63 100644 --- a/_pydevd_frame_eval/vendored/bytecode/__init__.py +++ b/_pydevd_frame_eval/vendored/bytecode/__init__.py @@ -37,6 +37,7 @@ from _pydevd_frame_eval.vendored.bytecode.cfg import BasicBlock, ControlFlowGraph # noqa import sys + def dump_bytecode(bytecode, *, lineno=False, stream=sys.stdout): def format_line(index, line): nonlocal cur_lineno, prev_lineno diff --git a/_pydevd_frame_eval/vendored/bytecode/bytecode.py b/_pydevd_frame_eval/vendored/bytecode/bytecode.py index 2ead43f08..868065942 100644 --- a/_pydevd_frame_eval/vendored/bytecode/bytecode.py +++ b/_pydevd_frame_eval/vendored/bytecode/bytecode.py @@ -6,7 +6,6 @@ class BaseBytecode: - def __init__(self): self.argcount = 0 if sys.version_info > (3, 8): @@ -130,7 +129,6 @@ def _check_instr(self, instr): class _InstrList(list): - def _flat(self): instructions = [] labels = {} @@ -162,7 +160,6 @@ def __eq__(self, other): class Bytecode(_InstrList, _BaseBytecodeList): - def __init__(self, instructions=()): BaseBytecode.__init__(self) self.argnames = [] @@ -179,9 +176,7 @@ def __iter__(self): def _check_instr(self, instr): if not isinstance(instr, (Label, SetLineno, Instr)): raise ValueError( - "Bytecode must only contain Label, " - "SetLineno, and Instr objects, " - "but %s was found" % type(instr).__name__ + "Bytecode must only contain Label, " "SetLineno, and Instr objects, " "but %s was found" % type(instr).__name__ ) def _copy_attr_from(self, bytecode): @@ -192,7 +187,7 @@ def _copy_attr_from(self, bytecode): @staticmethod def from_code(code): if sys.version_info[:2] >= (3, 11): - raise RuntimeError('This is not updated for Python 3.11 onwards, use only up to Python 3.10!!') + raise RuntimeError("This is not updated for Python 3.11 onwards, use only up to Python 3.10!!") concrete = _bytecode.ConcreteBytecode.from_code(code) return concrete.to_bytecode() @@ -200,9 +195,7 @@ def compute_stacksize(self, *, check_pre_and_post=True): cfg = _bytecode.ControlFlowGraph.from_bytecode(self) return cfg.compute_stacksize(check_pre_and_post=check_pre_and_post) - def to_code( - self, compute_jumps_passes=None, stacksize=None, *, check_pre_and_post=True - ): + def to_code(self, compute_jumps_passes=None, stacksize=None, *, check_pre_and_post=True): # Prevent reconverting the concrete bytecode to bytecode and cfg to do the # calculation if we need to do it. if stacksize is None: diff --git a/_pydevd_frame_eval/vendored/bytecode/cfg.py b/_pydevd_frame_eval/vendored/bytecode/cfg.py index 5e2f32290..6024c4f1c 100644 --- a/_pydevd_frame_eval/vendored/bytecode/cfg.py +++ b/_pydevd_frame_eval/vendored/bytecode/cfg.py @@ -21,16 +21,11 @@ def __iter__(self): index += 1 if not isinstance(instr, (SetLineno, Instr)): - raise ValueError( - "BasicBlock must only contain SetLineno and Instr objects, " - "but %s was found" % instr.__class__.__name__ - ) + raise ValueError("BasicBlock must only contain SetLineno and Instr objects, " "but %s was found" % instr.__class__.__name__) if isinstance(instr, Instr) and instr.has_jump(): if index < len(self): - raise ValueError( - "Only the last instruction of a basic " "block can be a jump" - ) + raise ValueError("Only the last instruction of a basic " "block can be a jump") if not isinstance(instr.arg, BasicBlock): raise ValueError( @@ -135,7 +130,6 @@ def update_size(pre_delta, post_delta, size, maxsize): block.startsize = size for instr in block: - # Ignore SetLineno if isinstance(instr, SetLineno): continue @@ -143,11 +137,7 @@ def update_size(pre_delta, post_delta, size, maxsize): # For instructions with a jump first compute the stacksize required when the # jump is taken. if instr.has_jump(): - effect = ( - instr.pre_and_post_stack_effect(jump=True) - if check_pre_and_post - else (instr.stack_effect(jump=True), 0) - ) + effect = instr.pre_and_post_stack_effect(jump=True) if check_pre_and_post else (instr.stack_effect(jump=True), 0) taken_size, maxsize = update_size(*effect, size, maxsize) # Yield the parameters required to compute the stacksize required # by the block to which the jumnp points to and resume when we now @@ -161,11 +151,7 @@ def update_size(pre_delta, post_delta, size, maxsize): yield maxsize # jump=False: non-taken path of jumps, or any non-jump - effect = ( - instr.pre_and_post_stack_effect(jump=False) - if check_pre_and_post - else (instr.stack_effect(jump=False), 0) - ) + effect = instr.pre_and_post_stack_effect(jump=False) if check_pre_and_post else (instr.stack_effect(jump=False), 0) size, maxsize = update_size(*effect, size, maxsize) if block.next_block: @@ -225,17 +211,11 @@ def compute_stacksize(self, *, check_pre_and_post=True): # Starting with Python 3.10, generator and coroutines start with one object # on the stack (None, anything is an error). initial_stack_size = 0 - if sys.version_info >= (3, 10) and self.flags & ( - CompilerFlags.GENERATOR - | CompilerFlags.COROUTINE - | CompilerFlags.ASYNC_GENERATOR - ): + if sys.version_info >= (3, 10) and self.flags & (CompilerFlags.GENERATOR | CompilerFlags.COROUTINE | CompilerFlags.ASYNC_GENERATOR): initial_stack_size = 1 # Create a generator/coroutine responsible of dealing with the first block - coro = _compute_stack_size( - self[0], initial_stack_size, 0, check_pre_and_post=check_pre_and_post - ) + coro = _compute_stack_size(self[0], initial_stack_size, 0, check_pre_and_post=check_pre_and_post) # Create a list of generator that have not yet been exhausted coroutines = [] diff --git a/_pydevd_frame_eval/vendored/bytecode/concrete.py b/_pydevd_frame_eval/vendored/bytecode/concrete.py index bd756cba7..f62ac503d 100644 --- a/_pydevd_frame_eval/vendored/bytecode/concrete.py +++ b/_pydevd_frame_eval/vendored/bytecode/concrete.py @@ -138,9 +138,7 @@ def __iter__(self): def _check_instr(self, instr): if not isinstance(instr, (ConcreteInstr, SetLineno)): raise ValueError( - "ConcreteBytecode must only contain " - "ConcreteInstr and SetLineno objects, " - "but %s was found" % type(instr).__name__ + "ConcreteBytecode must only contain " "ConcreteInstr and SetLineno objects, " "but %s was found" % type(instr).__name__ ) def _copy_attr_from(self, bytecode): @@ -236,9 +234,7 @@ def _assemble_code(self): for lineno, instr in self._normalize_lineno(self, self.first_lineno): code_str.append(instr.assemble()) i_size = instr.size - linenos.append( - ((offset * 2) if OFFSET_AS_INSTRUCTION else offset, i_size, lineno) - ) + linenos.append(((offset * 2) if OFFSET_AS_INSTRUCTION else offset, i_size, lineno)) offset += (i_size // 2) if OFFSET_AS_INSTRUCTION else i_size code_str = b"".join(code_str) return (code_str, linenos) @@ -254,9 +250,7 @@ def _assemble_lnotab(first_lineno, linenos): continue # FIXME: be kind, force monotonic line numbers? add an option? if dlineno < 0 and sys.version_info < (3, 6): - raise ValueError( - "negative line number delta is not supported " "on Python < 3.6" - ) + raise ValueError("negative line number delta is not supported " "on Python < 3.6") old_lineno = lineno doff = offset - old_offset @@ -285,7 +279,6 @@ def _assemble_lnotab(first_lineno, linenos): @staticmethod def _pack_linetable(doff, dlineno, linetable): - while dlineno < -127: linetable.append(struct.pack("Bb", 0, -127)) dlineno -= -127 @@ -309,16 +302,15 @@ def _pack_linetable(doff, dlineno, linetable): assert 0 <= doff <= 254 assert -127 <= dlineno <= 127 - def _assemble_linestable(self, first_lineno, linenos): if not linenos: return b"" linetable = [] old_offset = 0 - + iter_in = iter(linenos) - + offset, i_size, old_lineno = next(iter_in) old_dlineno = old_lineno - first_lineno for offset, i_size, lineno in iter_in: @@ -442,7 +434,6 @@ def to_code(self, stacksize=None, *, check_pre_and_post=True): ) def to_bytecode(self): - # Copy instruction and remove extended args if any (in-place) c_instructions = self[:] self._remove_extended_args(c_instructions) @@ -527,7 +518,6 @@ def to_bytecode(self): class _ConvertBytecodeToConcrete: - # Default number of passes of compute_jumps() before giving up. Refer to # assemble_jump_offsets() in compile.c for background. _compute_jumps_passes = 10 @@ -631,9 +621,7 @@ def compute_jumps(self): if instr.opcode in _opcode.hasjrel: instr_offset = offsets[index] - target_offset -= instr_offset + ( - instr.size // 2 if OFFSET_AS_INSTRUCTION else instr.size - ) + target_offset -= instr_offset + (instr.size // 2 if OFFSET_AS_INSTRUCTION else instr.size) old_size = instr.size # FIXME: better error report if target_offset is negative @@ -659,9 +647,7 @@ def to_concrete_bytecode(self, compute_jumps_passes=None): if not modified: break else: - raise RuntimeError( - "compute_jumps() failed to converge after" " %d passes" % (pas + 1) - ) + raise RuntimeError("compute_jumps() failed to converge after" " %d passes" % (pas + 1)) concrete = ConcreteBytecode( self.instructions, diff --git a/_pydevd_frame_eval/vendored/bytecode/flags.py b/_pydevd_frame_eval/vendored/bytecode/flags.py index b0c5239cd..ea72f9e74 100644 --- a/_pydevd_frame_eval/vendored/bytecode/flags.py +++ b/_pydevd_frame_eval/vendored/bytecode/flags.py @@ -62,22 +62,11 @@ def infer_flags(bytecode, is_async=None): bytecode, (_bytecode.Bytecode, _bytecode.ConcreteBytecode, _bytecode.ControlFlowGraph), ): - msg = ( - "Expected a Bytecode, ConcreteBytecode or ControlFlowGraph " - "instance not %s" - ) + msg = "Expected a Bytecode, ConcreteBytecode or ControlFlowGraph " "instance not %s" raise ValueError(msg % bytecode) - instructions = ( - bytecode.get_instructions() - if isinstance(bytecode, _bytecode.ControlFlowGraph) - else bytecode - ) - instr_names = { - i.name - for i in instructions - if not isinstance(i, (_bytecode.SetLineno, _bytecode.Label)) - } + instructions = bytecode.get_instructions() if isinstance(bytecode, _bytecode.ControlFlowGraph) else bytecode + instr_names = {i.name for i in instructions if not isinstance(i, (_bytecode.SetLineno, _bytecode.Label))} # Identify optimized code if not (instr_names & {"STORE_NAME", "LOAD_NAME", "DELETE_NAME"}): @@ -97,12 +86,7 @@ def infer_flags(bytecode, is_async=None): flags |= CompilerFlags.NOFREE # Copy flags for which we cannot infer the right value - flags |= bytecode.flags & ( - CompilerFlags.NEWLOCALS - | CompilerFlags.VARARGS - | CompilerFlags.VARKEYWORDS - | CompilerFlags.NESTED - ) + flags |= bytecode.flags & (CompilerFlags.NEWLOCALS | CompilerFlags.VARARGS | CompilerFlags.VARKEYWORDS | CompilerFlags.NESTED) sure_generator = instr_names & {"YIELD_VALUE"} maybe_generator = instr_names & {"YIELD_VALUE", "YIELD_FROM"} @@ -119,7 +103,6 @@ def infer_flags(bytecode, is_async=None): # If performing inference or forcing an async behavior, first inspect # the flags since this is the only way to identify iterable coroutines if is_async in (None, True): - if bytecode.flags & CompilerFlags.COROUTINE: if sure_generator: flags |= CompilerFlags.ASYNC_GENERATOR @@ -168,9 +151,7 @@ def infer_flags(bytecode, is_async=None): else: if sure_async: raise ValueError( - "The is_async argument is False but bytecodes " - "that can only be used in async functions have " - "been detected." + "The is_async argument is False but bytecodes " "that can only be used in async functions have " "been detected." ) if maybe_generator: diff --git a/_pydevd_frame_eval/vendored/bytecode/instr.py b/_pydevd_frame_eval/vendored/bytecode/instr.py index 9247a5495..a25bea82a 100644 --- a/_pydevd_frame_eval/vendored/bytecode/instr.py +++ b/_pydevd_frame_eval/vendored/bytecode/instr.py @@ -123,15 +123,10 @@ class FreeVar(_Variable): def _check_arg_int(name, arg): if not isinstance(arg, int): - raise TypeError( - "operation %s argument must be an int, " - "got %s" % (name, type(arg).__name__) - ) + raise TypeError("operation %s argument must be an int, " "got %s" % (name, type(arg).__name__)) if not (0 <= arg <= 2147483647): - raise ValueError( - "operation %s argument must be in " "the range 0..2,147,483,647" % name - ) + raise ValueError("operation %s argument must be in " "the range 0..2,147,483,647" % name) if sys.version_info < (3, 8): @@ -174,8 +169,7 @@ def __init__(self, name, arg=UNSET, *, lineno=None, offset=None): def _check_arg(self, name, opcode, arg): if name == "EXTENDED_ARG": raise ValueError( - "only concrete instruction can contain EXTENDED_ARG, " - "highlevel instruction can represent arbitrary argument without it" + "only concrete instruction can contain EXTENDED_ARG, " "highlevel instruction can represent arbitrary argument without it" ) if opcode >= _opcode.HAVE_ARGUMENT: @@ -187,41 +181,25 @@ def _check_arg(self, name, opcode, arg): if self._has_jump(opcode): if not isinstance(arg, (Label, _bytecode.BasicBlock)): - raise TypeError( - "operation %s argument type must be " - "Label or BasicBlock, got %s" % (name, type(arg).__name__) - ) + raise TypeError("operation %s argument type must be " "Label or BasicBlock, got %s" % (name, type(arg).__name__)) elif opcode in _opcode.hasfree: if not isinstance(arg, (CellVar, FreeVar)): - raise TypeError( - "operation %s argument must be CellVar " - "or FreeVar, got %s" % (name, type(arg).__name__) - ) + raise TypeError("operation %s argument must be CellVar " "or FreeVar, got %s" % (name, type(arg).__name__)) elif opcode in _opcode.haslocal or opcode in _opcode.hasname: if not isinstance(arg, str): - raise TypeError( - "operation %s argument must be a str, " - "got %s" % (name, type(arg).__name__) - ) + raise TypeError("operation %s argument must be a str, " "got %s" % (name, type(arg).__name__)) elif opcode in _opcode.hasconst: if isinstance(arg, Label): - raise ValueError( - "label argument cannot be used " "in %s operation" % name - ) + raise ValueError("label argument cannot be used " "in %s operation" % name) if isinstance(arg, _bytecode.BasicBlock): - raise ValueError( - "block argument cannot be used " "in %s operation" % name - ) + raise ValueError("block argument cannot be used " "in %s operation" % name) elif opcode in _opcode.hascompare: if not isinstance(arg, Compare): - raise TypeError( - "operation %s argument type must be " - "Compare, got %s" % (name, type(arg).__name__) - ) + raise TypeError("operation %s argument type must be " "Compare, got %s" % (name, type(arg).__name__)) elif opcode >= _opcode.HAVE_ARGUMENT: _check_arg_int(name, arg) @@ -340,9 +318,7 @@ def pre_and_post_stack_effect(self, jump=None): return -1, 2 if _opname == "ROT_N": return (-self._arg, self._arg) - return {"ROT_TWO": (-2, 2), "ROT_THREE": (-3, 3), "ROT_FOUR": (-4, 4)}.get( - _opname, (_effect, 0) - ) + return {"ROT_TWO": (-2, 2), "ROT_THREE": (-3, 3), "ROT_FOUR": (-4, 4)}.get(_opname, (_effect, 0)) def copy(self): return self.__class__(self._name, self._arg, lineno=self._lineno, offset=self.offset) diff --git a/_pydevd_frame_eval/vendored/bytecode/peephole_opt.py b/_pydevd_frame_eval/vendored/bytecode/peephole_opt.py index 9ece96bf0..4ed147f45 100644 --- a/_pydevd_frame_eval/vendored/bytecode/peephole_opt.py +++ b/_pydevd_frame_eval/vendored/bytecode/peephole_opt.py @@ -483,9 +483,6 @@ class CodeTransformer: def code_transformer(self, code, context): if sys.flags.verbose: - print( - "Optimize %s:%s: %s" - % (code.co_filename, code.co_firstlineno, code.co_name) - ) + print("Optimize %s:%s: %s" % (code.co_filename, code.co_firstlineno, code.co_name)) optimizer = PeepholeOptimizer() return optimizer.optimize(code) diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/__init__.py b/_pydevd_frame_eval/vendored/bytecode/tests/__init__.py index ee0f7d1b5..cc33b30a4 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/__init__.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/__init__.py @@ -129,9 +129,7 @@ def get_code(source, *, filename="", function=False): source = textwrap.dedent(source).strip() code = compile(source, filename, "exec") if function: - sub_code = [ - const for const in code.co_consts if isinstance(const, types.CodeType) - ] + sub_code = [const for const in code.co_consts if isinstance(const, types.CodeType)] if len(sub_code) != 1: raise ValueError("unable to find function code") code = sub_code[0] @@ -149,6 +147,4 @@ def assertBlocksEqual(self, code, *expected_blocks): for block1, block2 in zip(code, expected_blocks): block_index = code.get_block_index(block1) - self.assertListEqual( - list(block1), block2, "Block #%s is different" % block_index - ) + self.assertListEqual(list(block1), block2, "Block #%s is different" % block_index) diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/test_bytecode.py b/_pydevd_frame_eval/vendored/bytecode/tests/test_bytecode.py index c629f75e9..e219643f1 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/test_bytecode.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/test_bytecode.py @@ -1,8 +1,8 @@ - import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') + +pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6") #!/usr/bin/env python3 import sys import textwrap @@ -90,9 +90,7 @@ def test_slice(self): "freevars", "argnames", ): - self.assertEqual( - getattr(code, name, None), getattr(sliced_code, name, None) - ) + self.assertEqual(getattr(code, name, None), getattr(sliced_code, name, None)) def test_copy(self): code = Bytecode() diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/test_cfg.py b/_pydevd_frame_eval/vendored/bytecode/tests/test_cfg.py index 9b5b07b1c..6cc731a0e 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/test_cfg.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/test_cfg.py @@ -1,8 +1,8 @@ - import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') + +pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6") #!/usr/bin/env python3 import io import sys @@ -21,24 +21,16 @@ from _pydevd_frame_eval.vendored.bytecode.tests import disassemble as _disassemble, TestCase -def disassemble( - source, *, filename="", function=False, remove_last_return_none=False -): +def disassemble(source, *, filename="", function=False, remove_last_return_none=False): code = _disassemble(source, filename=filename, function=function) blocks = ControlFlowGraph.from_bytecode(code) if remove_last_return_none: # drop LOAD_CONST+RETURN_VALUE to only keep 2 instructions, # to make unit tests shorter block = blocks[-1] - test = ( - block[-2].name == "LOAD_CONST" - and block[-2].arg is None - and block[-1].name == "RETURN_VALUE" - ) + test = block[-2].name == "LOAD_CONST" and block[-2].arg is None and block[-1].name == "RETURN_VALUE" if not test: - raise ValueError( - "unable to find implicit RETURN_VALUE : %s" % block[-2:] - ) + raise ValueError("unable to find implicit RETURN_VALUE : %s" % block[-2:]) del block[-2:] return blocks @@ -458,9 +450,7 @@ def test_delitem(self): def sample_code(self): code = disassemble("x = 1", remove_last_return_none=True) - self.assertBlocksEqual( - code, [Instr("LOAD_CONST", 1, lineno=1), Instr("STORE_NAME", "x", lineno=1)] - ) + self.assertBlocksEqual(code, [Instr("LOAD_CONST", 1, lineno=1), Instr("STORE_NAME", "x", lineno=1)]) return code def test_split_block(self): @@ -522,9 +512,7 @@ def test_split_block_dont_split(self): # FIXME: is it really useful to support that? block = code.split_block(code[0], 0) self.assertIs(block, code[0]) - self.assertBlocksEqual( - code, [Instr("LOAD_CONST", 1, lineno=1), Instr("STORE_NAME", "x", lineno=1)] - ) + self.assertBlocksEqual(code, [Instr("LOAD_CONST", 1, lineno=1), Instr("STORE_NAME", "x", lineno=1)]) def test_split_block_error(self): code = self.sample_code() @@ -555,9 +543,7 @@ def test_to_code(self): Instr("POP_JUMP_IF_FALSE", block2, lineno=4), ] ) - block1.extend( - [Instr("LOAD_FAST", "arg", lineno=5), Instr("STORE_FAST", "x", lineno=5)] - ) + block1.extend([Instr("LOAD_FAST", "arg", lineno=5), Instr("STORE_FAST", "x", lineno=5)]) block2.extend( [ Instr("LOAD_CONST", 3, lineno=6), @@ -569,13 +555,9 @@ def test_to_code(self): if OFFSET_AS_INSTRUCTION: # The argument of the jump is divided by 2 - expected = ( - b"|\x05" b"r\x04" b"|\x00" b"}\x05" b"d\x01" b"}\x05" b"|\x05" b"S\x00" - ) + expected = b"|\x05" b"r\x04" b"|\x00" b"}\x05" b"d\x01" b"}\x05" b"|\x05" b"S\x00" else: - expected = ( - b"|\x05" b"r\x08" b"|\x00" b"}\x05" b"d\x01" b"}\x05" b"|\x05" b"S\x00" - ) + expected = b"|\x05" b"r\x08" b"|\x00" b"}\x05" b"d\x01" b"}\x05" b"|\x05" b"S\x00" code = bytecode.to_code() self.assertEqual(code.co_consts, (None, 3)) @@ -589,9 +571,7 @@ def test_to_code(self): self.assertEqual(code.co_flags, 0x43) self.assertEqual(code.co_code, expected) self.assertEqual(code.co_names, ()) - self.assertEqual( - code.co_varnames, ("arg", "arg2", "arg3", "kwonly", "kwonly2", "x") - ) + self.assertEqual(code.co_varnames, ("arg", "arg2", "arg3", "kwonly", "kwonly2", "x")) self.assertEqual(code.co_filename, "hello.py") self.assertEqual(code.co_name, "func") self.assertEqual(code.co_firstlineno, 3) diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/test_code.py b/_pydevd_frame_eval/vendored/bytecode/tests/test_code.py index 6938bd1bf..4820e875d 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/test_code.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/test_code.py @@ -1,8 +1,8 @@ - import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') + +pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6") import unittest from _pydevd_frame_eval.vendored.bytecode import ConcreteBytecode, Bytecode, ControlFlowGraph diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/test_concrete.py b/_pydevd_frame_eval/vendored/bytecode/tests/test_concrete.py index 510f6cd55..f1fe5e6b7 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/test_concrete.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/test_concrete.py @@ -1,8 +1,8 @@ - import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') + +pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6") #!/usr/bin/env python3 import opcode import sys @@ -167,9 +167,7 @@ def test_get_jump_target(self): self.assertEqual(jump_abs.get_jump_target(100), 3) jump_forward = ConcreteInstr("JUMP_FORWARD", 5) - self.assertEqual( - jump_forward.get_jump_target(10), 16 if OFFSET_AS_INSTRUCTION else 17 - ) + self.assertEqual(jump_forward.get_jump_target(10), 16 if OFFSET_AS_INSTRUCTION else 17) class ConcreteBytecodeTests(TestCase): @@ -241,7 +239,6 @@ def test_invalid_types(self): ConcreteBytecode([Label()]) def test_to_code_lnotab(self): - # We use an actual function for the simple case to # ensure we get lnotab right def f(): @@ -454,9 +451,7 @@ def test_load_classderef(self): concrete = ConcreteBytecode() concrete.cellvars = ["__class__"] concrete.freevars = ["__class__"] - concrete.extend( - [ConcreteInstr("LOAD_CLASSDEREF", 1), ConcreteInstr("STORE_DEREF", 1)] - ) + concrete.extend([ConcreteInstr("LOAD_CLASSDEREF", 1), ConcreteInstr("STORE_DEREF", 1)]) bytecode = concrete.to_bytecode() self.assertEqual(bytecode.freevars, ["__class__"]) @@ -582,11 +577,7 @@ def test_extended_arg(self): # Create a code object from arbitrary bytecode co_code = b"\x90\x12\x904\x90\xabd\xcd" code = get_code("x=1") - args = ( - (code.co_argcount,) - if sys.version_info < (3, 8) - else (code.co_argcount, code.co_posonlyargcount) - ) + args = (code.co_argcount,) if sys.version_info < (3, 8) else (code.co_argcount, code.co_posonlyargcount) args += ( code.co_kwonlyargcount, code.co_nlocals, @@ -608,9 +599,7 @@ def test_extended_arg(self): # without EXTENDED_ARG opcode bytecode = ConcreteBytecode.from_code(code) - self.assertListEqual( - list(bytecode), [ConcreteInstr("LOAD_CONST", 0x1234ABCD, lineno=1)] - ) + self.assertListEqual(list(bytecode), [ConcreteInstr("LOAD_CONST", 0x1234ABCD, lineno=1)]) # with EXTENDED_ARG opcode bytecode = ConcreteBytecode.from_code(code, extended_arg=True) @@ -655,10 +644,7 @@ def foo(x: int, y: int): ConcreteInstr("LOAD_NAME", 0, lineno=1), ConcreteInstr("BUILD_TUPLE", 4, lineno=1), ] - elif ( - sys.version_info >= (3, 7) - and concrete.flags & CompilerFlags.FUTURE_ANNOTATIONS - ): + elif sys.version_info >= (3, 7) and concrete.flags & CompilerFlags.FUTURE_ANNOTATIONS: func_code = concrete.consts[2] names = ["foo"] consts = ["int", ("x", "y"), func_code, "foo", None] @@ -726,9 +712,7 @@ def test(): return q, r, s, t cpython_stacksize = test.__code__.co_stacksize - test.__code__ = ConcreteBytecode.from_code( - test.__code__, extended_arg=True - ).to_code() + test.__code__ = ConcreteBytecode.from_code(test.__code__, extended_arg=True).to_code() self.assertEqual(test.__code__.co_stacksize, cpython_stacksize) self.assertEqual(test(), (1, 2, [3, 4, 5], 6)) @@ -997,9 +981,7 @@ def test(): return var - test.__code__ = ConcreteBytecode.from_code( - test.__code__, extended_arg=True - ).to_code() + test.__code__ = ConcreteBytecode.from_code(test.__code__, extended_arg=True).to_code() self.assertEqual(test.__code__.co_stacksize, 1) self.assertEqual(test(), 259) @@ -1130,9 +1112,7 @@ def test_label2(self): concrete = bytecode.to_concrete_bytecode() expected = [ ConcreteInstr("LOAD_NAME", 0, lineno=1), - ConcreteInstr( - "POP_JUMP_IF_FALSE", 7 if OFFSET_AS_INSTRUCTION else 14, lineno=1 - ), + ConcreteInstr("POP_JUMP_IF_FALSE", 7 if OFFSET_AS_INSTRUCTION else 14, lineno=1), ConcreteInstr("LOAD_CONST", 0, lineno=2), ConcreteInstr("STORE_NAME", 1, lineno=2), ConcreteInstr("JUMP_FORWARD", 2 if OFFSET_AS_INSTRUCTION else 4, lineno=2), @@ -1205,9 +1185,7 @@ def func(x): self.assertEqual(func(18), -1) # Ensure that we properly round trip in such cases - self.assertEqual( - ConcreteBytecode.from_code(code).to_code().co_code, code.co_code - ) + self.assertEqual(ConcreteBytecode.from_code(code).to_code().co_code, code.co_code) def test_setlineno(self): # x = 7 @@ -1259,7 +1237,7 @@ def assemble(self): # (invalid) code using jumps > 0xffff to test extended arg label = Label() - nb_nop = 2 ** 16 + nb_nop = 2**16 code = Bytecode( [ Instr("JUMP_ABSOLUTE", label), @@ -1304,9 +1282,7 @@ def test_jumps(self): code = code.to_concrete_bytecode() expected = [ ConcreteInstr("LOAD_NAME", 0, lineno=1), - ConcreteInstr( - "POP_JUMP_IF_FALSE", 5 if OFFSET_AS_INSTRUCTION else 10, lineno=1 - ), + ConcreteInstr("POP_JUMP_IF_FALSE", 5 if OFFSET_AS_INSTRUCTION else 10, lineno=1), ConcreteInstr("LOAD_CONST", 0, lineno=2), ConcreteInstr("STORE_NAME", 1, lineno=2), ConcreteInstr("JUMP_FORWARD", 2 if OFFSET_AS_INSTRUCTION else 4, lineno=2), @@ -1448,10 +1424,7 @@ def test_extreme_compute_jumps_convergence(self): labels = [Label() for x in range(0, 3 * N)] code = Bytecode() - code.extend( - Instr("JUMP_FORWARD", labels[len(labels) - x - 1]) - for x in range(0, len(labels)) - ) + code.extend(Instr("JUMP_FORWARD", labels[len(labels) - x - 1]) for x in range(0, len(labels))) end_of_jumps = len(code) code.extend(Instr(nop) for x in range(0, N)) diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/test_flags.py b/_pydevd_frame_eval/vendored/bytecode/tests/test_flags.py index b7744fbd0..08c7cb264 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/test_flags.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/test_flags.py @@ -1,8 +1,8 @@ - import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') + +pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6") #!/usr/bin/env python3 import unittest from _pydevd_frame_eval.vendored.bytecode import ( @@ -21,7 +21,6 @@ def test_type_validation_on_inference(self): infer_flags(1) def test_flag_inference(self): - # Check no loss of non-infered flags code = ControlFlowGraph() code.flags |= ( @@ -122,7 +121,6 @@ def test_async_gen_flags(self): # Test inference in the presence of pre-existing flags for is_async in (None, True): - # Infer generator code = ConcreteBytecode() code.append(ConcreteInstr("YIELD_VALUE")) diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/test_instr.py b/_pydevd_frame_eval/vendored/bytecode/tests/test_instr.py index ca4a66a73..bc5db5257 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/test_instr.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/test_instr.py @@ -1,8 +1,8 @@ - import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') + +pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6") #!/usr/bin/env python3 import opcode import unittest @@ -78,7 +78,6 @@ def test_constructor(self): Instr("xxx") def test_repr(self): - # No arg r = repr(Instr("NOP", lineno=10)) self.assertIn("NOP", r) @@ -253,9 +252,7 @@ def test_const_key_equal(self): self.assertNotEqual(Instr("LOAD_CONST", 0), Instr("LOAD_CONST", 0.0)) # float: -0.0 == +0.0 - self.assertNotEqual( - Instr("LOAD_CONST", neg_zero), Instr("LOAD_CONST", pos_zero) - ) + self.assertNotEqual(Instr("LOAD_CONST", neg_zero), Instr("LOAD_CONST", pos_zero)) # complex self.assertNotEqual( @@ -273,14 +270,10 @@ def test_const_key_equal(self): nested_tuple1 = (nested_tuple1,) nested_tuple2 = (0.0,) nested_tuple2 = (nested_tuple2,) - self.assertNotEqual( - Instr("LOAD_CONST", nested_tuple1), Instr("LOAD_CONST", nested_tuple2) - ) + self.assertNotEqual(Instr("LOAD_CONST", nested_tuple1), Instr("LOAD_CONST", nested_tuple2)) # frozenset - self.assertNotEqual( - Instr("LOAD_CONST", frozenset({0})), Instr("LOAD_CONST", frozenset({0.0})) - ) + self.assertNotEqual(Instr("LOAD_CONST", frozenset({0})), Instr("LOAD_CONST", frozenset({0.0}))) def test_stack_effects(self): # Verify all opcodes are handled and that "jump=None" really returns @@ -322,7 +315,7 @@ def check(instr): # (As a result we can calculate stack_effect for # any LOAD_CONST instructions, even for large integers) - for arg in 2 ** 31, 2 ** 32, 2 ** 63, 2 ** 64, -1: + for arg in 2**31, 2**32, 2**63, 2**64, -1: self.assertEqual(Instr("LOAD_CONST", arg).stack_effect(), 1) def test_code_object_containing_mutable_data(self): @@ -340,11 +333,7 @@ def g(): mutable_datum = [4, 2] for each in f_code: - if ( - isinstance(each, Instr) - and each.name == "LOAD_CONST" - and isinstance(each.arg, CodeType) - ): + if isinstance(each, Instr) and each.name == "LOAD_CONST" and isinstance(each.arg, CodeType): instr_load_code = each break diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/test_misc.py b/_pydevd_frame_eval/vendored/bytecode/tests/test_misc.py index 5f4c0636a..6a700e931 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/test_misc.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/test_misc.py @@ -1,8 +1,8 @@ - import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') + +pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6") #!/usr/bin/env python3 import contextlib import io @@ -62,11 +62,7 @@ def func(test): LOAD_CONST 3 RETURN_VALUE - """[ - 1: - ].rstrip( - " " - ) + """[1:].rstrip(" ") self.check_dump_bytecode(code, expected) # with line numbers @@ -90,11 +86,7 @@ def func(test): L. 6 14: LOAD_CONST 3 15: RETURN_VALUE - """[ - 1: - ].rstrip( - " " - ) + """[1:].rstrip(" ") self.check_dump_bytecode(code, expected, lineno=True) def test_bytecode_broken_label(self): @@ -225,9 +217,7 @@ def func(test): 22 RETURN_VALUE 24 LOAD_CONST 3 26 RETURN_VALUE -""".lstrip( - "\n" - ) +""".lstrip("\n") self.check_dump_bytecode(code, expected) # with line numbers @@ -246,9 +236,7 @@ def func(test): 22: RETURN_VALUE L. 6 24: LOAD_CONST 3 26: RETURN_VALUE -""".lstrip( - "\n" - ) +""".lstrip("\n") self.check_dump_bytecode(code, expected, lineno=True) def test_type_validation(self): diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/test_peephole_opt.py b/_pydevd_frame_eval/vendored/bytecode/tests/test_peephole_opt.py index 387a7829f..4689b28fd 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/test_peephole_opt.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/test_peephole_opt.py @@ -1,8 +1,8 @@ - import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') + +pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6") import sys import unittest from _pydevd_frame_eval.vendored.bytecode import Label, Instr, Compare, Bytecode, ControlFlowGraph @@ -12,7 +12,6 @@ class Tests(TestCase): - maxDiff = 80 * 100 def optimize_blocks(self, code): @@ -51,9 +50,7 @@ def check_dont_optimize(self, code): def test_unary_op(self): def check_unary_op(op, value, result): - code = Bytecode( - [Instr("LOAD_CONST", value), Instr(op), Instr("STORE_NAME", "x")] - ) + code = Bytecode([Instr("LOAD_CONST", value), Instr(op), Instr("STORE_NAME", "x")]) self.check(code, Instr("LOAD_CONST", result), Instr("STORE_NAME", "x")) check_unary_op("UNARY_POSITIVE", 2, 2) @@ -520,9 +517,7 @@ def test_return_value(self): ] ) code = ControlFlowGraph.from_bytecode(code) - self.check( - code, Instr("LOAD_CONST", 4, lineno=2), Instr("RETURN_VALUE", lineno=2) - ) + self.check(code, Instr("LOAD_CONST", 4, lineno=2), Instr("RETURN_VALUE", lineno=2)) # return+return + return+return: remove second and fourth return # @@ -544,9 +539,7 @@ def test_return_value(self): ] ) code = ControlFlowGraph.from_bytecode(code) - self.check( - code, Instr("LOAD_CONST", 4, lineno=2), Instr("RETURN_VALUE", lineno=2) - ) + self.check(code, Instr("LOAD_CONST", 4, lineno=2), Instr("RETURN_VALUE", lineno=2)) # return + JUMP_ABSOLUTE: remove JUMP_ABSOLUTE # while 1: @@ -594,9 +587,7 @@ def test_return_value(self): ) code = ControlFlowGraph.from_bytecode(code) - self.check( - code, Instr("LOAD_CONST", 7, lineno=3), Instr("RETURN_VALUE", lineno=3) - ) + self.check(code, Instr("LOAD_CONST", 7, lineno=3), Instr("RETURN_VALUE", lineno=3)) def test_not_jump_if_false(self): # Replace UNARY_NOT+POP_JUMP_IF_FALSE with POP_JUMP_IF_TRUE @@ -905,9 +896,7 @@ def test_jump_if_false_to_jump_if_false(self): ) def test_nop(self): - code = Bytecode( - [Instr("LOAD_NAME", "x"), Instr("NOP"), Instr("STORE_NAME", "test")] - ) + code = Bytecode([Instr("LOAD_NAME", "x"), Instr("NOP"), Instr("STORE_NAME", "test")]) self.check(code, Instr("LOAD_NAME", "x"), Instr("STORE_NAME", "test")) diff --git a/_pydevd_frame_eval/vendored/bytecode/tests/util_annotation.py b/_pydevd_frame_eval/vendored/bytecode/tests/util_annotation.py index b64754346..4d6be6c59 100644 --- a/_pydevd_frame_eval/vendored/bytecode/tests/util_annotation.py +++ b/_pydevd_frame_eval/vendored/bytecode/tests/util_annotation.py @@ -8,9 +8,7 @@ def get_code(source, *, filename="", function=False): source = textwrap.dedent(source).strip() code = compile(source, filename, "exec") if function: - sub_code = [ - const for const in code.co_consts if isinstance(const, types.CodeType) - ] + sub_code = [const for const in code.co_consts if isinstance(const, types.CodeType)] if len(sub_code) != 1: raise ValueError("unable to find function code") code = sub_code[0] diff --git a/_pydevd_frame_eval/vendored/pydevd_fix_code.py b/_pydevd_frame_eval/vendored/pydevd_fix_code.py index 6b3d87ff8..73a7c79bf 100644 --- a/_pydevd_frame_eval/vendored/pydevd_fix_code.py +++ b/_pydevd_frame_eval/vendored/pydevd_fix_code.py @@ -1,27 +1,21 @@ def _fix_contents(filename, contents): import re - contents = re.sub( - r"from bytecode", r'from _pydevd_frame_eval.vendored.bytecode', contents, flags=re.MULTILINE - ) + contents = re.sub(r"from bytecode", r"from _pydevd_frame_eval.vendored.bytecode", contents, flags=re.MULTILINE) - contents = re.sub( - r"import bytecode", r'from _pydevd_frame_eval.vendored import bytecode', contents, flags=re.MULTILINE - ) + contents = re.sub(r"import bytecode", r"from _pydevd_frame_eval.vendored import bytecode", contents, flags=re.MULTILINE) # This test will import the wrong setup (we're not interested in it). - contents = re.sub( - r"def test_version\(self\):", r'def skip_test_version(self):', contents, flags=re.MULTILINE - ) + contents = re.sub(r"def test_version\(self\):", r"def skip_test_version(self):", contents, flags=re.MULTILINE) - if filename.startswith('test_'): - if 'pytestmark' not in contents: - pytest_mark = ''' + if filename.startswith("test_"): + if "pytestmark" not in contents: + pytest_mark = """ import pytest from tests_python.debugger_unittest import IS_PY36_OR_GREATER, IS_CPYTHON from tests_python.debug_constants import TEST_CYTHON pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason='Requires CPython >= 3.6') -''' +""" contents = pytest_mark + contents return contents @@ -33,18 +27,19 @@ def main(): for root, dirs, files in os.walk(os.path.dirname(__file__)): path = root.split(os.sep) for filename in files: - if filename.endswith('.py') and filename != 'pydevd_fix_code.py': - with open(os.path.join(root, filename), 'r') as stream: + if filename.endswith(".py") and filename != "pydevd_fix_code.py": + with open(os.path.join(root, filename), "r") as stream: contents = stream.read() new_contents = _fix_contents(filename, contents) if contents != new_contents: - print('fixed ', os.path.join(root, filename)) - with open(os.path.join(root, filename), 'w') as stream: + print("fixed ", os.path.join(root, filename)) + with open(os.path.join(root, filename), "w") as stream: stream.write(new_contents) + # print(len(path) * '---', filename) -if __name__ == '__main__': - main() \ No newline at end of file +if __name__ == "__main__": + main() diff --git a/_pydevd_sys_monitoring/_pydevd_sys_monitoring.py b/_pydevd_sys_monitoring/_pydevd_sys_monitoring.py index 69c859a3c..44ce42d72 100644 --- a/_pydevd_sys_monitoring/_pydevd_sys_monitoring.py +++ b/_pydevd_sys_monitoring/_pydevd_sys_monitoring.py @@ -14,12 +14,19 @@ from _pydev_bundle import pydev_log from _pydevd_bundle import pydevd_dont_trace -from _pydevd_bundle.pydevd_constants import (GlobalDebuggerHolder, ForkSafeLock, - PYDEVD_IPYTHON_CONTEXT, EXCEPTION_TYPE_USER_UNHANDLED, RETURN_VALUES_DICT, - PYTHON_SUSPEND) -from pydevd_file_utils import (NORM_PATHS_AND_BASE_CONTAINER, +from _pydevd_bundle.pydevd_constants import ( + GlobalDebuggerHolder, + ForkSafeLock, + PYDEVD_IPYTHON_CONTEXT, + EXCEPTION_TYPE_USER_UNHANDLED, + RETURN_VALUES_DICT, + PYTHON_SUSPEND, +) +from pydevd_file_utils import ( + NORM_PATHS_AND_BASE_CONTAINER, get_abs_path_real_path_and_base_from_file, - get_abs_path_real_path_and_base_from_frame) + get_abs_path_real_path_and_base_from_frame, +) from _pydevd_bundle.pydevd_trace_dispatch import should_stop_on_exception, handle_exception from _pydevd_bundle.pydevd_constants import EXCEPTION_TYPE_HANDLED from _pydevd_bundle.pydevd_trace_dispatch import is_unhandled_exception @@ -40,7 +47,8 @@ def get_smart_step_into_variant_from_frame_offset(*args, **kwargs): return None -if hasattr(sys, 'monitoring'): + +if hasattr(sys, "monitoring"): DEBUGGER_ID = sys.monitoring.DEBUGGER_ID monitor = sys.monitoring @@ -64,10 +72,10 @@ def get_smart_step_into_variant_from_frame_offset(*args, **kwargs): STATE_RUN: int = 1 STATE_SUSPEND: int = 2 -IGNORE_EXCEPTION_TAG = re.compile('[^#]*#.*@IgnoreException') -DEBUG_START = ('pydevd.py', 'run') -DEBUG_START_PY3K = ('_pydev_execfile.py', 'execfile') -TRACE_PROPERTY = 'pydevd_traceproperty.py' +IGNORE_EXCEPTION_TAG = re.compile("[^#]*#.*@IgnoreException") +DEBUG_START = ("pydevd.py", "run") +DEBUG_START_PY3K = ("_pydev_execfile.py", "execfile") +TRACE_PROPERTY = "pydevd_traceproperty.py" _global_notify_skipped_step_in = False _global_notify_skipped_step_in_lock = ForkSafeLock() @@ -77,7 +85,7 @@ def get_smart_step_into_variant_from_frame_offset(*args, **kwargs): # cdef _notify_skipped_step_in_because_of_filters(py_db, frame): # ELSE def _notify_skipped_step_in_because_of_filters(py_db, frame): -# ENDIF + # ENDIF global _global_notify_skipped_step_in with _global_notify_skipped_step_in_lock: @@ -104,7 +112,7 @@ def _notify_skipped_step_in_because_of_filters(py_db, frame): # cdef _get_bootstrap_frame(depth): # ELSE def _get_bootstrap_frame(depth: int) -> Tuple[Optional[FrameType], bool]: -# ENDIF + # ENDIF try: return _thread_local_info.f_bootstrap, _thread_local_info.is_bootstrap_frame_internal except: @@ -116,27 +124,27 @@ def _get_bootstrap_frame(depth: int) -> Tuple[Optional[FrameType], bool]: filename = f_bootstrap.f_code.co_filename name = splitext(basename(filename))[0] - if name == 'threading': - if f_bootstrap.f_code.co_name in ('__bootstrap', '_bootstrap'): + if name == "threading": + if f_bootstrap.f_code.co_name in ("__bootstrap", "_bootstrap"): # We need __bootstrap_inner, not __bootstrap. return None, False - elif f_bootstrap.f_code.co_name in ('__bootstrap_inner', '_bootstrap_inner', 'is_alive'): + elif f_bootstrap.f_code.co_name in ("__bootstrap_inner", "_bootstrap_inner", "is_alive"): # Note: be careful not to use threading.current_thread to avoid creating a dummy thread. is_bootstrap_frame_internal = True break - elif name == 'pydev_monkey': - if f_bootstrap.f_code.co_name == '__call__': + elif name == "pydev_monkey": + if f_bootstrap.f_code.co_name == "__call__": is_bootstrap_frame_internal = True break - elif name == 'pydevd': - if f_bootstrap.f_code.co_name in ('run', 'main'): + elif name == "pydevd": + if f_bootstrap.f_code.co_name in ("run", "main"): # We need to get to _exec return None, False - if f_bootstrap.f_code.co_name == '_exec': + if f_bootstrap.f_code.co_name == "_exec": is_bootstrap_frame_internal = True break @@ -157,7 +165,7 @@ def _get_bootstrap_frame(depth: int) -> Tuple[Optional[FrameType], bool]: # cdef _get_unhandled_exception_frame(int depth): # ELSE def _get_unhandled_exception_frame(depth: int) -> Optional[FrameType]: -# ENDIF + # ENDIF try: return _thread_local_info.f_unhandled except: @@ -171,20 +179,20 @@ def _get_unhandled_exception_frame(depth: int) -> Optional[FrameType]: # When the back frame is the bootstrap (or if we have no back # frame) then use this frame as the one to track. - if name == 'threading': - if f_back.f_code.co_name in ('__bootstrap', '_bootstrap', '__bootstrap_inner', '_bootstrap_inner', 'run'): + if name == "threading": + if f_back.f_code.co_name in ("__bootstrap", "_bootstrap", "__bootstrap_inner", "_bootstrap_inner", "run"): break - elif name == 'pydev_monkey': - if f_back.f_code.co_name == '__call__': + elif name == "pydev_monkey": + if f_back.f_code.co_name == "__call__": break - elif name == 'pydevd': - if f_back.f_code.co_name in ('_exec', 'run', 'main'): + elif name == "pydevd": + if f_back.f_code.co_name in ("_exec", "run", "main"): break - elif name == 'pydevd_runpy': - if f_back.f_code.co_name.startswith(('run', '_run')): + elif name == "pydevd_runpy": + if f_back.f_code.co_name.startswith(("run", "_run")): break f_unhandled = f_back @@ -208,13 +216,13 @@ class ThreadInfo: thread_ident: int thread: threading.Thread trace: bool -# ENDIF + # ENDIF -# IFDEF CYTHON -# def __init__(self, thread, unsigned long thread_ident, bint trace, PyDBAdditionalThreadInfo additional_info): -# ELSE + # IFDEF CYTHON + # def __init__(self, thread, unsigned long thread_ident, bint trace, PyDBAdditionalThreadInfo additional_info): + # ELSE def __init__(self, thread: threading.Thread, thread_ident: int, trace: bool, additional_info: PyDBAdditionalThreadInfo): -# ENDIF + # ENDIF self.thread = thread self.thread_ident = thread_ident self.additional_info = additional_info @@ -222,9 +230,9 @@ def __init__(self, thread: threading.Thread, thread_ident: int, trace: bool, add class _DeleteDummyThreadOnDel: - ''' + """ Helper class to remove a dummy thread from threading._active on __del__. - ''' + """ def __init__(self, dummy_thread): self._dummy_thread = dummy_thread @@ -248,7 +256,7 @@ def __del__(self): # cdef unsigned long thread_ident # ELSE def _create_thread_info(depth): -# ENDIF + # ENDIF # Don't call threading.currentThread because if we're too early in the process # we may create a dummy thread. thread_ident = _get_ident() @@ -259,15 +267,15 @@ def _create_thread_info(depth): if is_bootstrap_frame_internal: t = None - if f_bootstrap_frame.f_code.co_name in ('__bootstrap_inner', '_bootstrap_inner', 'is_alive'): + if f_bootstrap_frame.f_code.co_name in ("__bootstrap_inner", "_bootstrap_inner", "is_alive"): # Note: be careful not to use threading.current_thread to avoid creating a dummy thread. - t = f_bootstrap_frame.f_locals.get('self') + t = f_bootstrap_frame.f_locals.get("self") if not isinstance(t, threading.Thread): t = None - elif f_bootstrap_frame.f_code.co_name in ('_exec', '__call__'): + elif f_bootstrap_frame.f_code.co_name in ("_exec", "__call__"): # Note: be careful not to use threading.current_thread to avoid creating a dummy thread. - t = f_bootstrap_frame.f_locals.get('t') + t = f_bootstrap_frame.f_locals.get("t") if not isinstance(t, threading.Thread): t = None @@ -286,7 +294,7 @@ def _create_thread_info(depth): if t is None: return None - if getattr(t, 'is_pydev_daemon_thread', False): + if getattr(t, "is_pydev_daemon_thread", False): return ThreadInfo(t, thread_ident, False, None) else: try: @@ -321,12 +329,11 @@ def _create_thread_info(depth): # cdef str co_name # ELSE class FuncCodeInfo: - -# ENDIF + # ENDIF def __init__(self): - self.co_filename: str = '' - self.canonical_normalized_filename:str = '' - self.abs_path_filename: str = '' + self.co_filename: str = "" + self.canonical_normalized_filename: str = "" + self.abs_path_filename: str = "" # These is never seen and we never stop, even if it's a callback coming # from user code (these are completely invisible to the debugging tracing). @@ -362,7 +369,7 @@ def __init__(self): self.try_except_container_obj: Optional[_TryExceptContainerObj] = None self.code_obj: CodeType = None - self.co_name: str = '' + self.co_name: str = "" def get_line_of_offset(self, offset): for start, end, line in self.code_obj.co_lines(): @@ -374,13 +381,13 @@ def get_line_of_offset(self, offset): # IFDEF CYTHON # cdef _get_thread_info(bint create, int depth): # ELSE -def _get_thread_info(create: bool, depth:int) -> Optional[ThreadInfo]: -# ENDIF - ''' +def _get_thread_info(create: bool, depth: int) -> Optional[ThreadInfo]: + # ENDIF + """ Provides thread-related info. May return None if the thread is still not active. - ''' + """ try: # Note: changing to a `dict[thread.ident] = thread_info` had almost no # effect in the performance. @@ -396,7 +403,7 @@ def _get_thread_info(create: bool, depth:int) -> Optional[ThreadInfo]: return _thread_local_info.thread_info -_CodeLineInfo = namedtuple('_CodeLineInfo', 'line_to_offset, first_line, last_line') +_CodeLineInfo = namedtuple("_CodeLineInfo", "line_to_offset, first_line, last_line") # Note: this method has a version in cython too @@ -404,7 +411,7 @@ def _get_thread_info(create: bool, depth:int) -> Optional[ThreadInfo]: # cdef _get_code_line_info(code_obj, _cache={}): # ELSE def _get_code_line_info(code_obj, _cache={}): -# ENDIF + # ENDIF try: return _cache[code_obj] except: @@ -423,7 +430,7 @@ def _get_code_line_info(code_obj, _cache={}): return ret -_code_to_func_code_info_cache: Dict[CodeType, 'FuncCodeInfo'] = {} +_code_to_func_code_info_cache: Dict[CodeType, "FuncCodeInfo"] = {} # IFDEF CYTHON @@ -431,15 +438,15 @@ def _get_code_line_info(code_obj, _cache={}): # cdef FuncCodeInfo func_code_info # ELSE def _get_func_code_info(code_obj, frame_or_depth) -> FuncCodeInfo: -# ENDIF - ''' + # ENDIF + """ Provides code-object related info. Note that it contains informations on the breakpoints for a given function. If breakpoints change a new FuncCodeInfo instance will be created. Note that this can be called by any thread. - ''' + """ py_db = GlobalDebuggerHolder.global_dbg if py_db is None: return None @@ -451,22 +458,22 @@ def _get_func_code_info(code_obj, frame_or_depth) -> FuncCodeInfo: # print('_get_func_code_info: matched mtime', key, code_obj) return func_code_info -# IFDEF CYTHON -# cdef dict cache_file_type -# cdef tuple cache_file_type_key -# cdef PyCodeObject * code -# cdef str co_filename -# cdef str co_name -# code = code_obj -# co_filename = code.co_filename -# co_name = code.co_name -# ELSE + # IFDEF CYTHON + # cdef dict cache_file_type + # cdef tuple cache_file_type_key + # cdef PyCodeObject * code + # cdef str co_filename + # cdef str co_name + # code = code_obj + # co_filename = code.co_filename + # co_name = code.co_name + # ELSE cache_file_type: dict cache_file_type_key: tuple code = code_obj co_filename: str = code.co_filename co_name: str = code.co_name -# ENDIF + # ENDIF # print('_get_func_code_info: new (mtime did not match)', key, code_obj) @@ -501,7 +508,7 @@ def _get_func_code_info(code_obj, frame_or_depth) -> FuncCodeInfo: frame = _getframe(frame_or_depth + 1) else: frame = frame_or_depth - assert frame.f_code is code_obj, '%s != %s' % (frame.f_code, code_obj) + assert frame.f_code is code_obj, "%s != %s" % (frame.f_code, code_obj) file_type = py_db.get_file_type(frame, abs_path_real_path_and_base) # we don't want to debug anything related to pydevd @@ -578,13 +585,13 @@ def _get_func_code_info(code_obj, frame_or_depth) -> FuncCodeInfo: if is_tracked_frame: if py_db.has_plugin_line_breaks: required_events_breakpoint = plugin_manager.required_events_breakpoint() - func_code_info.plugin_line_breakpoint_found = 'line' in required_events_breakpoint - func_code_info.plugin_call_breakpoint_found = 'call' in required_events_breakpoint + func_code_info.plugin_line_breakpoint_found = "line" in required_events_breakpoint + func_code_info.plugin_call_breakpoint_found = "call" in required_events_breakpoint required_events_stepping = plugin_manager.required_events_stepping() - func_code_info.plugin_line_stepping: bool = 'line' in required_events_stepping - func_code_info.plugin_call_stepping: bool = 'call' in required_events_stepping - func_code_info.plugin_return_stepping: bool = 'return' in required_events_stepping + func_code_info.plugin_line_stepping: bool = "line" in required_events_stepping + func_code_info.plugin_call_stepping: bool = "call" in required_events_stepping + func_code_info.plugin_return_stepping: bool = "return" in required_events_stepping _code_to_func_code_info_cache[code_obj] = func_code_info return func_code_info @@ -594,7 +601,7 @@ def _get_func_code_info(code_obj, frame_or_depth) -> FuncCodeInfo: # cdef _enable_line_tracing(code): # ELSE def _enable_line_tracing(code): -# ENDIF + # ENDIF # print('enable line tracing', code) events = monitor.get_local_events(DEBUGGER_ID, code) monitor.set_local_events(DEBUGGER_ID, code, events | monitor.events.LINE | monitor.events.JUMP) @@ -604,7 +611,7 @@ def _enable_line_tracing(code): # cdef _enable_return_tracing(code): # ELSE def _enable_return_tracing(code): -# ENDIF + # ENDIF # print('enable return tracing', code) events = monitor.get_local_events(DEBUGGER_ID, code) monitor.set_local_events(DEBUGGER_ID, code, events | monitor.events.PY_RETURN) @@ -614,7 +621,7 @@ def _enable_return_tracing(code): # cpdef disable_code_tracing(code): # ELSE def disable_code_tracing(code): -# ENDIF + # ENDIF monitor.set_local_events(DEBUGGER_ID, code, 0) @@ -622,14 +629,14 @@ def disable_code_tracing(code): # cpdef enable_code_tracing(unsigned long thread_ident, code, frame): # ELSE def enable_code_tracing(thread_ident: Optional[int], code, frame) -> bool: -# ENDIF - ''' + # ENDIF + """ Note: this must enable code tracing for the given code/frame. The frame can be from any thread! :return: Whether code tracing was added in this function to the given code. - ''' + """ # DEBUG = False # 'my_code.py' in code.co_filename or 'other.py' in code.co_filename # if DEBUG: # print('==== enable code tracing', code.co_filename[-30:], code.co_name) @@ -662,10 +669,10 @@ def enable_code_tracing(thread_ident: Optional[int], code, frame) -> bool: # cdef bint code_tracing_added # ELSE def _enable_code_tracing(py_db, additional_info, func_code_info: FuncCodeInfo, code, frame, warn_on_filtered_out) -> bool: -# ENDIF - ''' + # ENDIF + """ :return: Whether code tracing was added in this function to the given code. - ''' + """ # DEBUG = False # 'my_code.py' in code.co_filename or 'other.py' in code.co_filename step_cmd = additional_info.pydev_step_cmd is_stepping = step_cmd != -1 @@ -674,7 +681,12 @@ def _enable_code_tracing(py_db, additional_info, func_code_info: FuncCodeInfo, c if func_code_info.always_filtered_out: # if DEBUG: # print('disable (always filtered out)') - if warn_on_filtered_out and is_stepping and additional_info.pydev_original_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE) and not _global_notify_skipped_step_in: + if ( + warn_on_filtered_out + and is_stepping + and additional_info.pydev_original_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE) + and not _global_notify_skipped_step_in + ): _notify_skipped_step_in_because_of_filters(py_db, frame) if is_stepping: @@ -698,7 +710,7 @@ def _enable_code_tracing(py_db, additional_info, func_code_info: FuncCodeInfo, c # cdef _enable_step_tracing(py_db, code, step_cmd, PyDBAdditionalThreadInfo info, frame): # ELSE def _enable_step_tracing(py_db, code, step_cmd, info, frame): -# ENDIF + # ENDIF if step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE, CMD_STEP_INTO_COROUTINE, CMD_SMART_STEP_INTO): # Stepping (must have line/return tracing enabled). _enable_line_tracing(code) @@ -724,18 +736,19 @@ def _enable_step_tracing(py_db, code, step_cmd, info, frame): # cdef list try_except_infos # ELSE class _TryExceptContainerObj: -# ENDIF - ''' + # ENDIF + """ A dumb container object just to contain the try..except info when needed. Meant to be persistent among multiple PyDBFrames to the same code object. - ''' + """ # IFDEF CYTHON -# def __init__(self, list try_except_infos): -# self.try_except_infos = try_except_infos + # def __init__(self, list try_except_infos): + # self.try_except_infos = try_except_infos # ELSE def __init__(self, try_except_infos): self.try_except_infos = try_except_infos + # ENDIF @@ -745,7 +758,7 @@ def __init__(self, try_except_infos): # cdef FuncCodeInfo func_code_info # ELSE def _unwind_event(code, instruction, exc): -# ENDIF + # ENDIF try: thread_info = _thread_local_info.thread_info except: @@ -771,12 +784,13 @@ def _unwind_event(code, instruction, exc): arg = (type(exc), exc, exc.__traceback__) has_caught_exception_breakpoint_in_pydb = ( - py_db.break_on_caught_exceptions - or py_db.break_on_user_uncaught_exceptions - or py_db.has_plugin_exception_breaks) + py_db.break_on_caught_exceptions or py_db.break_on_user_uncaught_exceptions or py_db.has_plugin_exception_breaks + ) if has_caught_exception_breakpoint_in_pydb: - _should_stop, frame, user_uncaught_exc_info = should_stop_on_exception(py_db, thread_info.additional_info, frame, thread_info.thread, arg, None) + _should_stop, frame, user_uncaught_exc_info = should_stop_on_exception( + py_db, thread_info.additional_info, frame, thread_info.thread, arg, None + ) if user_uncaught_exc_info: # TODO: Check: this may no longer be needed as in the unwind we know it's # an exception bubbling up (wait for all tests to pass to check it). @@ -784,7 +798,9 @@ def _unwind_event(code, instruction, exc): container_obj = _TryExceptContainerObj(py_db.collect_try_except_info(frame.f_code)) func_code_info.try_except_container_obj = container_obj - if is_unhandled_exception(func_code_info.try_except_container_obj, py_db, frame, user_uncaught_exc_info[1], user_uncaught_exc_info[2]): + if is_unhandled_exception( + func_code_info.try_except_container_obj, py_db, frame, user_uncaught_exc_info[1], user_uncaught_exc_info[2] + ): # print('stop in user uncaught') handle_exception(py_db, thread_info.thread, frame, user_uncaught_exc_info[0], EXCEPTION_TYPE_USER_UNHANDLED) return @@ -802,8 +818,8 @@ def _unwind_event(code, instruction, exc): # cdef FuncCodeInfo func_code_info # ELSE def _raise_event(code, instruction, exc): -# ENDIF - ''' + # ENDIF + """ The way this should work is the following: when the user is using pydevd to do the launch and we're on a managed stack, we should consider unhandled only if it gets into a pydevd. If it's a thread, if it stops @@ -812,7 +828,7 @@ def _raise_event(code, instruction, exc): Note: unlike other events, this one is global and not per-code (so, it cannot be individually enabled/disabled for a given code object). - ''' + """ try: thread_info = _thread_local_info.thread_info except: @@ -837,7 +853,9 @@ def _raise_event(code, instruction, exc): frame = _getframe(1) arg = (type(exc), exc, exc.__traceback__) - should_stop, frame, _user_uncaught_exc_info = should_stop_on_exception(py_db, thread_info.additional_info, frame, thread_info.thread, arg, None) + should_stop, frame, _user_uncaught_exc_info = should_stop_on_exception( + py_db, thread_info.additional_info, frame, thread_info.thread, arg, None + ) # print('!!!! should_stop (in raise)', should_stop) if should_stop: handle_exception(py_db, thread_info.thread, frame, arg, EXCEPTION_TYPE_HANDLED) @@ -849,7 +867,7 @@ def _raise_event(code, instruction, exc): # cdef str func_name # ELSE def get_func_name(frame): -# ENDIF + # ENDIF code_obj = frame.f_code func_name = code_obj.co_name try: @@ -867,7 +885,7 @@ def get_func_name(frame): # cdef _show_return_values(frame, arg): # ELSE def _show_return_values(frame, arg): -# ENDIF + # ENDIF try: try: f_locals_back = getattr(frame.f_back, "f_locals", None) @@ -888,7 +906,7 @@ def _show_return_values(frame, arg): # cdef _remove_return_values(py_db, frame): # ELSE def _remove_return_values(py_db, frame): -# ENDIF + # ENDIF try: try: # Showing return values was turned off, we should remove them from locals dict. @@ -912,7 +930,7 @@ def _remove_return_values(py_db, frame): # cdef int step_cmd # ELSE def _return_event(code, instruction, retval): -# ENDIF + # ENDIF try: thread_info = _thread_local_info.thread_info except: @@ -945,7 +963,7 @@ def _return_event(code, instruction, retval): if info.suspend_type != PYTHON_SUSPEND: # Plugin stepping if func_code_info.plugin_return_stepping: - _plugin_stepping(py_db, step_cmd, 'return', frame, thread_info) + _plugin_stepping(py_db, step_cmd, "return", frame, thread_info) return # Python line stepping @@ -956,18 +974,18 @@ def _return_event(code, instruction, retval): back_func_code_info = _get_func_code_info(frame.f_back.f_code, frame.f_back) if ( # Not filtered out. - not back_func_code_info.always_skip_code and not back_func_code_info.always_filtered_out + not back_func_code_info.always_skip_code + and not back_func_code_info.always_filtered_out and not (force_check_project_scope and back_func_code_info.filtered_out_force_checked) - # Prevent stopping in a return to the same location we were initially # (i.e.: double-stop at the same place due to some filtering). and info.step_in_initial_location != (frame.f_back, frame.f_back.f_lineno) - ): - if py_db.show_return_values: - _show_return_values(frame, retval) + ): + if py_db.show_return_values: + _show_return_values(frame, retval) - _stop_on_return(py_db, thread_info, info, step_cmd, frame, retval) - return + _stop_on_return(py_db, thread_info, info, step_cmd, frame, retval) + return if step_cmd in (CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE) and _is_same_frame(info, stop_frame, frame): if py_db.show_return_values: @@ -976,7 +994,11 @@ def _return_event(code, instruction, retval): _stop_on_return(py_db, thread_info, info, step_cmd, frame, retval) return - elif step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE) and not info.pydev_use_scoped_step_frame and _is_same_frame(info, stop_frame, frame): + elif ( + step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE) + and not info.pydev_use_scoped_step_frame + and _is_same_frame(info, stop_frame, frame) + ): # This isn't in the sys.settrace version: on a step over, if we return and the return is valid, show # as a step return instead of going back to step into mode (but if the back frame is not valid, then # go to step into mode). @@ -985,10 +1007,12 @@ def _return_event(code, instruction, retval): back_func_code_info = _get_func_code_info(f_back.f_code, 2) force_check_project_scope = step_cmd == CMD_STEP_OVER_MY_CODE - if back_func_code_info is not None and not back_func_code_info.always_skip_code \ - and not back_func_code_info.always_filtered_out \ - and not (force_check_project_scope and back_func_code_info.filtered_out_force_checked): - + if ( + back_func_code_info is not None + and not back_func_code_info.always_skip_code + and not back_func_code_info.always_filtered_out + and not (force_check_project_scope and back_func_code_info.filtered_out_force_checked) + ): if py_db.show_return_values: _show_return_values(frame, retval) @@ -1006,15 +1030,18 @@ def _return_event(code, instruction, retval): if py_db.show_return_values: if ( - (info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, CMD_SMART_STEP_INTO) and (_is_same_frame(info, stop_frame, frame.f_back))) or - (info.pydev_step_cmd in (CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE) and (info, _is_same_frame(info, stop_frame, frame))) or - (info.pydev_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_COROUTINE)) or - ( - info.pydev_step_cmd == CMD_STEP_INTO_MY_CODE - and frame.f_back is not None - and not py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True) - ) - ): + ( + info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, CMD_SMART_STEP_INTO) + and (_is_same_frame(info, stop_frame, frame.f_back)) + ) + or (info.pydev_step_cmd in (CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE) and (info, _is_same_frame(info, stop_frame, frame))) + or (info.pydev_step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_COROUTINE)) + or ( + info.pydev_step_cmd == CMD_STEP_INTO_MY_CODE + and frame.f_back is not None + and not py_db.apply_files_filter(frame.f_back, frame.f_back.f_code.co_filename, True) + ) + ): _show_return_values(frame, retval) if step_cmd in (CMD_STEP_OVER, CMD_STEP_RETURN, CMD_STEP_OVER_MY_CODE, CMD_STEP_RETURN_MY_CODE, CMD_SMART_STEP_INTO): @@ -1041,7 +1068,7 @@ def _return_event(code, instruction, retval): # cdef FuncCodeInfo func_code_info # ELSE def _enable_code_tracing_for_frame_and_parents(thread_info, frame): -# ENDIF + # ENDIF py_db: object = GlobalDebuggerHolder.global_dbg if py_db is None or py_db.pydb_disposed: return @@ -1060,7 +1087,7 @@ def _enable_code_tracing_for_frame_and_parents(thread_info, frame): # cdef _stop_on_return(py_db, ThreadInfo thread_info, PyDBAdditionalThreadInfo info, int step_cmd, frame, retval): # ELSE def _stop_on_return(py_db, thread_info, info, step_cmd, frame, retval): -# ENDIF + # ENDIF back = frame.f_back if back is not None: # When we get to the pydevd run function, the debugging has actually finished for the main thread @@ -1088,7 +1115,7 @@ def _stop_on_return(py_db, thread_info, info, step_cmd, frame, retval): if back is not None: # if we're in a return, we want it to appear to the user in the previous frame! py_db.set_suspend(thread_info.thread, step_cmd, original_step_cmd=info.pydev_original_step_cmd) - _do_wait_suspend(py_db, thread_info, back, 'return', retval) + _do_wait_suspend(py_db, thread_info, back, "return", retval) else: # in jython we may not have a back frame info.pydev_step_stop = None @@ -1102,9 +1129,11 @@ def _stop_on_return(py_db, thread_info, info, step_cmd, frame, retval): # cdef _stop_on_breakpoint(py_db, ThreadInfo thread_info, int stop_reason, bp, frame, new_frame, bint stop, bint stop_on_plugin_breakpoint, str bp_type): # cdef PyDBAdditionalThreadInfo additional_info # ELSE -def _stop_on_breakpoint(py_db, thread_info: ThreadInfo, stop_reason: int, bp, frame, new_frame, stop: bool, stop_on_plugin_breakpoint: bool, bp_type:str): -# ENDIF - ''' +def _stop_on_breakpoint( + py_db, thread_info: ThreadInfo, stop_reason: int, bp, frame, new_frame, stop: bool, stop_on_plugin_breakpoint: bool, bp_type: str +): + # ENDIF + """ :param bp: the breakpoint hit (additional conditions will be checked now). :param frame: the actual frame :param new_frame: either the actual frame or the frame provided by the plugins. @@ -1114,7 +1143,7 @@ def _stop_on_breakpoint(py_db, thread_info: ThreadInfo, stop_reason: int, bp, fr :return: True if the breakpoint was suspended inside this function and False otherwise. Note that even if False is returned, it's still possible - ''' + """ additional_info = thread_info.additional_info # ok, hit breakpoint, now, we have to discover if it is a conditional breakpoint # lets do the conditional stuff here @@ -1135,7 +1164,7 @@ def _stop_on_breakpoint(py_db, thread_info: ThreadInfo, stop_reason: int, bp, fr stop_on_plugin_breakpoint = False if additional_info.pydev_message is not None and len(additional_info.pydev_message) > 0: - cmd = py_db.cmd_factory.make_io_message(additional_info.pydev_message + os.linesep, '1') + cmd = py_db.cmd_factory.make_io_message(additional_info.pydev_message + os.linesep, "1") py_db.writer.add_command(cmd) if stop: @@ -1145,13 +1174,13 @@ def _stop_on_breakpoint(py_db, thread_info: ThreadInfo, stop_reason: int, bp, fr suspend_other_threads=bp and bp.suspend_policy == "ALL", ) # print('suspend on breakpoint...') - _do_wait_suspend(py_db, thread_info, frame, 'line', None) + _do_wait_suspend(py_db, thread_info, frame, "line", None) return True elif stop_on_plugin_breakpoint: stop_at_frame = py_db.plugin.suspend(py_db, thread_info.thread, frame, bp_type) if stop_at_frame and thread_info.additional_info.pydev_state == STATE_SUSPEND: - _do_wait_suspend(py_db, thread_info, stop_at_frame, 'line', None) + _do_wait_suspend(py_db, thread_info, stop_at_frame, "line", None) return return False @@ -1163,10 +1192,13 @@ def _stop_on_breakpoint(py_db, thread_info: ThreadInfo, stop_reason: int, bp, fr # cdef dict stop_info # ELSE def _plugin_stepping(py_db, step_cmd, event, frame, thread_info): -# ENDIF + # ENDIF plugin_manager = py_db.plugin # Step return makes no sense for plugins (I guess?!?), so, just handle as step into. - if step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE, CMD_STEP_INTO_COROUTINE, CMD_SMART_STEP_INTO) or step_cmd in (CMD_STEP_RETURN, CMD_STEP_RETURN_MY_CODE): + if step_cmd in (CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE, CMD_STEP_INTO_COROUTINE, CMD_SMART_STEP_INTO) or step_cmd in ( + CMD_STEP_RETURN, + CMD_STEP_RETURN_MY_CODE, + ): stop_info = {} stop = False result = plugin_manager.cmd_step_into(py_db, frame, event, thread_info.additional_info, thread_info.thread, stop_info, stop) @@ -1196,7 +1228,7 @@ def _plugin_stepping(py_db, step_cmd, event, frame, thread_info): # cdef int to_line # ELSE def _jump_event(code, from_offset, to_offset): -# ENDIF + # ENDIF # A bunch of things have to be repeated especially because in the sys.monitoring # everything is global, yet, when we start tracing something for stepping that # needs to be per-thread. @@ -1246,7 +1278,7 @@ def _jump_event(code, from_offset, to_offset): # cdef FuncCodeInfo func_code_info # ELSE def _line_event(code, line): -# ENDIF + # ENDIF # A bunch of things have to be repeated especially because in the sys.monitoring # everything is global, yet, when we start tracing something for stepping that @@ -1289,7 +1321,7 @@ def _line_event(code, line): # cdef bint force_check_project_scope # ELSE def _internal_line_event(func_code_info, frame, line): -# ENDIF + # ENDIF py_db: object = GlobalDebuggerHolder.global_dbg thread_info = _thread_local_info.thread_info info = thread_info.additional_info @@ -1315,11 +1347,11 @@ def _internal_line_event(func_code_info, frame, line): stop = True if bp: - if _stop_on_breakpoint(py_db, thread_info, stop_reason, bp, frame, new_frame, stop, stop_on_plugin_breakpoint, 'python-line'): + if _stop_on_breakpoint(py_db, thread_info, stop_reason, bp, frame, new_frame, stop, stop_on_plugin_breakpoint, "python-line"): return if func_code_info.plugin_line_breakpoint_found: - result = py_db.plugin.get_breakpoint(py_db, frame, 'line', info) + result = py_db.plugin.get_breakpoint(py_db, frame, "line", info) if result: stop_reason = CMD_SET_BREAK stop = False @@ -1331,7 +1363,7 @@ def _internal_line_event(func_code_info, frame, line): if info.pydev_state == STATE_SUSPEND: # Note: it's possible that it was suspended with a pause (and we'd stop here too). # print('suspend (pause)...') - _do_wait_suspend(py_db, thread_info, frame, 'line', None) + _do_wait_suspend(py_db, thread_info, frame, "line", None) return # Ok, did not suspend due to a breakpoint, let's see if we're stepping. @@ -1345,7 +1377,7 @@ def _internal_line_event(func_code_info, frame, line): if info.suspend_type != PYTHON_SUSPEND: # Plugin stepping if func_code_info.plugin_line_stepping: - _plugin_stepping(py_db, step_cmd, 'line', frame, thread_info) + _plugin_stepping(py_db, step_cmd, "line", frame, thread_info) return # Python stepping now @@ -1356,7 +1388,7 @@ def _internal_line_event(func_code_info, frame, line): return py_db.set_suspend(thread_info.thread, step_cmd, original_step_cmd=info.pydev_original_step_cmd) - _do_wait_suspend(py_db, thread_info, frame, 'line', None) + _do_wait_suspend(py_db, thread_info, frame, "line", None) return else: # Make sure we check the filtering inside ipython calls too... @@ -1366,7 +1398,7 @@ def _internal_line_event(func_code_info, frame, line): stop = False # We can only stop inside the ipython call. filename = frame.f_code.co_filename - if filename.endswith('.pyc'): + if filename.endswith(".pyc"): filename = filename[:-1] if not filename.endswith(PYDEVD_IPYTHON_CONTEXT[0]): @@ -1375,10 +1407,10 @@ def _internal_line_event(func_code_info, frame, line): if f.f_code.co_name == PYDEVD_IPYTHON_CONTEXT[1]: f2 = f.f_back if f2 is not None and f2.f_code.co_name == PYDEVD_IPYTHON_CONTEXT[2]: - pydev_log.debug('Stop inside ipython call') + pydev_log.debug("Stop inside ipython call") py_db.set_suspend(thread_info.thread, step_cmd, original_step_cmd=info.pydev_original_step_cmd) - thread_info.additional_info.trace_suspend_type = 'sys_monitor' - _do_wait_suspend(py_db, thread_info, frame, 'line', None) + thread_info.additional_info.trace_suspend_type = "sys_monitor" + _do_wait_suspend(py_db, thread_info, frame, "line", None) break f = f.f_back @@ -1394,7 +1426,7 @@ def _internal_line_event(func_code_info, frame, line): # into and in the other we go to a step into my code). if _is_same_frame(info, stop_frame, frame): py_db.set_suspend(thread_info.thread, step_cmd, original_step_cmd=info.pydev_original_step_cmd) - _do_wait_suspend(py_db, thread_info, frame, 'line', None) + _do_wait_suspend(py_db, thread_info, frame, "line", None) return elif step_cmd == CMD_SMART_STEP_INTO: @@ -1413,16 +1445,17 @@ def _internal_line_event(func_code_info, frame, line): if pydev_smart_parent_offset >= 0 and pydev_smart_step_into_variants: # Preferred mode (when the smart step into variants are available # and the offset is set). - stop = get_smart_step_into_variant_from_frame_offset(back.f_lasti, pydev_smart_step_into_variants) is \ - get_smart_step_into_variant_from_frame_offset(pydev_smart_parent_offset, pydev_smart_step_into_variants) + stop = get_smart_step_into_variant_from_frame_offset( + back.f_lasti, pydev_smart_step_into_variants + ) is get_smart_step_into_variant_from_frame_offset(pydev_smart_parent_offset, pydev_smart_step_into_variants) else: # Only the name/line is available, so, check that. curr_func_name = frame.f_code.co_name # global context is set with an empty name - if curr_func_name in ('?', '') or curr_func_name is None: - curr_func_name = '' + if curr_func_name in ("?", "") or curr_func_name is None: + curr_func_name = "" if curr_func_name == info.pydev_func_name and stop_frame.f_lineno == info.pydev_next_line: stop = True @@ -1449,13 +1482,15 @@ def _internal_line_event(func_code_info, frame, line): # the child (because this is a generator, the parent may have moved forward # already -- and that's ok, so, we just check that the parent frame # matches in this case). - smart_step_into_variant = get_smart_step_into_variant_from_frame_offset(pydev_smart_parent_offset, pydev_smart_step_into_variants) + smart_step_into_variant = get_smart_step_into_variant_from_frame_offset( + pydev_smart_parent_offset, pydev_smart_step_into_variants + ) # print('matched parent offset', pydev_smart_parent_offset) # Ok, now, check the child variant children_variants = smart_step_into_variant.children_variants stop = children_variants and ( - get_smart_step_into_variant_from_frame_offset(back.f_lasti, children_variants) is \ - get_smart_step_into_variant_from_frame_offset(pydev_smart_child_offset, children_variants) + get_smart_step_into_variant_from_frame_offset(back.f_lasti, children_variants) + is get_smart_step_into_variant_from_frame_offset(pydev_smart_child_offset, children_variants) ) # print('stop at child', stop) @@ -1466,7 +1501,7 @@ def _internal_line_event(func_code_info, frame, line): if stop: py_db.set_suspend(thread_info.thread, step_cmd, original_step_cmd=info.pydev_original_step_cmd) - _do_wait_suspend(py_db, thread_info, frame, 'line', None) + _do_wait_suspend(py_db, thread_info, frame, "line", None) return @@ -1482,7 +1517,7 @@ def _internal_line_event(func_code_info, frame, line): # cdef bint code_tracing_added # ELSE def _start_method_event(code, instruction_offset): -# ENDIF + # ENDIF try: thread_info = _thread_local_info.thread_info except: @@ -1515,7 +1550,7 @@ def _start_method_event(code, instruction_offset): stop_reason = CMD_SET_FUNCTION_BREAK stop_on_plugin_breakpoint = False - _stop_on_breakpoint(py_db, thread_info, stop_reason, bp, frame, new_frame, stop, stop_on_plugin_breakpoint, 'python-function') + _stop_on_breakpoint(py_db, thread_info, stop_reason, bp, frame, new_frame, stop, stop_on_plugin_breakpoint, "python-function") return if py_db.plugin: @@ -1524,7 +1559,7 @@ def _start_method_event(code, instruction_offset): # Check breaking on breakpoints in a 'call' info = thread_info.additional_info if func_code_info.plugin_call_breakpoint_found: - result = plugin_manager.get_breakpoint(py_db, frame, 'call', info) + result = plugin_manager.get_breakpoint(py_db, frame, "call", info) if result: stop_reason = CMD_SET_BREAK stop = False @@ -1538,7 +1573,7 @@ def _start_method_event(code, instruction_offset): # Check breaking on line stepping in a 'call' step_cmd = info.pydev_step_cmd if step_cmd != -1 and func_code_info.plugin_call_stepping and info.suspend_type != PYTHON_SUSPEND: - _plugin_stepping(py_db, step_cmd, 'call', frame, thread_info) + _plugin_stepping(py_db, step_cmd, "call", frame, thread_info) return if keep_enabled or any_thread_stepping(): @@ -1552,12 +1587,12 @@ def _start_method_event(code, instruction_offset): # cdef ThreadInfo thread_info # ELSE def start_monitoring(all_threads=False): -# ENDIF + # ENDIF if all_threads: # print('start monitoring, all_threads=', all_threads) DEBUGGER_ID = monitor.DEBUGGER_ID if not monitor.get_tool(DEBUGGER_ID): - monitor.use_tool_id(DEBUGGER_ID, 'pydevd') + monitor.use_tool_id(DEBUGGER_ID, "pydevd") update_monitor_events() restart_events() else: @@ -1578,10 +1613,10 @@ def start_monitoring(all_threads=False): # cdef ThreadInfo thread_info # ELSE def stop_monitoring(all_threads=False): -# ENDIF + # ENDIF if all_threads: # print('stop monitoring, all_threads=', all_threads) - if monitor.get_tool(monitor.DEBUGGER_ID) == 'pydevd': + if monitor.get_tool(monitor.DEBUGGER_ID) == "pydevd": monitor.set_events(monitor.DEBUGGER_ID, 0) monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, None) monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RESUME, None) @@ -1601,13 +1636,13 @@ def stop_monitoring(all_threads=False): thread_info.trace = False -def update_monitor_events(suspend_requested: Optional[bool]=None) -> None: - ''' +def update_monitor_events(suspend_requested: Optional[bool] = None) -> None: + """ This should be called when breakpoints change. :param suspend: means the user requested threads to be suspended - ''' - if monitor.get_tool(monitor.DEBUGGER_ID) != 'pydevd': + """ + if monitor.get_tool(monitor.DEBUGGER_ID) != "pydevd": # It is still not initialized. return @@ -1621,7 +1656,7 @@ def update_monitor_events(suspend_requested: Optional[bool]=None) -> None: suspend_requested = False for t in threading.enumerate(): - if getattr(t, 'pydev_do_not_trace', False): + if getattr(t, "pydev_do_not_trace", False): continue try: additional_info = t.additional_info @@ -1637,9 +1672,8 @@ def update_monitor_events(suspend_requested: Optional[bool]=None) -> None: required_events = 0 has_caught_exception_breakpoint_in_pydb = ( - py_db.break_on_caught_exceptions - or py_db.break_on_user_uncaught_exceptions - or py_db.has_plugin_exception_breaks) + py_db.break_on_caught_exceptions or py_db.break_on_user_uncaught_exceptions or py_db.has_plugin_exception_breaks + ) break_on_uncaught_exceptions = py_db.break_on_uncaught_exceptions @@ -1698,7 +1732,7 @@ def restart_events() -> None: # cdef _is_same_frame(PyDBAdditionalThreadInfo info, target_frame, current_frame): # ELSE def _is_same_frame(info, target_frame, current_frame): -# ENDIF + # ENDIF if target_frame is current_frame: return True @@ -1722,10 +1756,11 @@ def _is_same_frame(info, target_frame, current_frame): # def _do_wait_suspend(py_db, ThreadInfo thread_info, frame, event, arg): # ELSE def _do_wait_suspend(py_db, thread_info, frame, event, arg): -# ENDIF - thread_info.additional_info.trace_suspend_type = 'sys_monitor' + # ENDIF + thread_info.additional_info.trace_suspend_type = "sys_monitor" py_db.do_wait_suspend(thread_info.thread, frame, event, arg) + # This can be used to diagnose exceptions inside of the debugger itself. # # import types diff --git a/_pydevd_sys_monitoring/pydevd_sys_monitoring.py b/_pydevd_sys_monitoring/pydevd_sys_monitoring.py index c74f9240d..3378a7ebf 100644 --- a/_pydevd_sys_monitoring/pydevd_sys_monitoring.py +++ b/_pydevd_sys_monitoring/pydevd_sys_monitoring.py @@ -1,5 +1,4 @@ -from _pydevd_bundle.pydevd_constants import (USE_CYTHON_FLAG, - ENV_TRUE_LOWER_VALUES, ENV_FALSE_LOWER_VALUES, IS_PY312_OR_GREATER) +from _pydevd_bundle.pydevd_constants import USE_CYTHON_FLAG, ENV_TRUE_LOWER_VALUES, ENV_FALSE_LOWER_VALUES, IS_PY312_OR_GREATER if IS_PY312_OR_GREATER: if USE_CYTHON_FLAG in ENV_TRUE_LOWER_VALUES: diff --git a/build_tools/build.py b/build_tools/build.py index c57bfa584..d8c52566a 100644 --- a/build_tools/build.py +++ b/build_tools/build.py @@ -1,4 +1,4 @@ -''' +""" Helper to build pydevd. It should: @@ -6,7 +6,7 @@ * compile cython deps (properly setting up the environment first). Note that it's used in the CI to build the cython deps based on the PYDEVD_USE_CYTHON environment variable. -''' +""" from __future__ import print_function import os @@ -49,12 +49,12 @@ def get_environment_from_batch_command(env_cmd, initial=None): if not isinstance(env_cmd, (list, tuple)): env_cmd = [env_cmd] if not os.path.exists(env_cmd[0]): - raise RuntimeError('Error: %s does not exist' % (env_cmd[0],)) + raise RuntimeError("Error: %s does not exist" % (env_cmd[0],)) # construct the command that will alter the environment env_cmd = subprocess.list2cmdline(env_cmd) # create a tag so we can tell in the output when the proc is done - tag = 'Done running command' + tag = "Done running command" # construct a cmd.exe command to do accomplish this cmd = 'cmd.exe /s /c "{env_cmd} && echo "{tag}" && set"'.format(**vars()) # launch the process @@ -63,17 +63,20 @@ def get_environment_from_batch_command(env_cmd, initial=None): lines = proc.stdout # consume whatever output occurs until the tag is reached for line in lines: - line = line.decode('utf-8') - if 'The specified configuration type is missing.' in line: - raise AssertionError('Error executing %s. View http://blog.ionelmc.ro/2014/12/21/compiling-python-extensions-on-windows/ for details.' % (env_cmd)) + line = line.decode("utf-8") + if "The specified configuration type is missing." in line: + raise AssertionError( + "Error executing %s. View http://blog.ionelmc.ro/2014/12/21/compiling-python-extensions-on-windows/ for details." + % (env_cmd) + ) if tag in line: break if sys.version_info[0] > 2: # define a way to handle each KEY=VALUE line - handle_line = lambda l: l.decode('utf-8').rstrip().split('=', 1) + handle_line = lambda l: l.decode("utf-8").rstrip().split("=", 1) else: # define a way to handle each KEY=VALUE line - handle_line = lambda l: l.rstrip().split('=', 1) + handle_line = lambda l: l.rstrip().split("=", 1) # parse key/values into pairs pairs = map(handle_line, lines) # make sure the pairs are valid @@ -86,28 +89,28 @@ def get_environment_from_batch_command(env_cmd, initial=None): def remove_binaries(suffixes): - for f in os.listdir(os.path.join(root_dir, '_pydevd_bundle')): + for f in os.listdir(os.path.join(root_dir, "_pydevd_bundle")): for suffix in suffixes: if f.endswith(suffix): - remove_if_exists(os.path.join(root_dir, '_pydevd_bundle', f)) + remove_if_exists(os.path.join(root_dir, "_pydevd_bundle", f)) def build(): - if '--no-remove-binaries' not in sys.argv: - remove_binaries(['.pyd', '.so']) + if "--no-remove-binaries" not in sys.argv: + remove_binaries([".pyd", ".so"]) os.chdir(root_dir) env = os.environ.copy() - if sys.platform == 'win32': + if sys.platform == "win32": # "C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\vcvars64.bat" # set MSSdk=1 # set DISTUTILS_USE_SDK=1 # set VS100COMNTOOLS=C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools - if 'GITHUB_ACTION' not in os.environ: + if "GITHUB_ACTION" not in os.environ: if sys.version_info[:2] in ((3, 6), (3, 7), (3, 8), (3, 9), (3, 10), (3, 11), (3, 12)): - FORCE_PYDEVD_VC_VARS = os.environ.get('FORCE_PYDEVD_VC_VARS') + FORCE_PYDEVD_VC_VARS = os.environ.get("FORCE_PYDEVD_VC_VARS") if FORCE_PYDEVD_VC_VARS: env.update(get_environment_from_batch_command([FORCE_PYDEVD_VC_VARS], initial=os.environ.copy())) else: @@ -117,56 +120,58 @@ def build(): vcvarsall = msvc9compiler.find_vcvarsall(14.0) if vcvarsall is None or not os.path.exists(vcvarsall): msvc_version = msvc9compiler.get_build_version() - print('msvc_version', msvc_version) + print("msvc_version", msvc_version) vcvarsall = msvc9compiler.find_vcvarsall(msvc_version) if vcvarsall is None or not os.path.exists(vcvarsall): - raise RuntimeError('Error finding vcvarsall.') + raise RuntimeError("Error finding vcvarsall.") if is_python_64bit(): - env.update(get_environment_from_batch_command( - [vcvarsall, 'amd64'], - initial=os.environ.copy())) + env.update(get_environment_from_batch_command([vcvarsall, "amd64"], initial=os.environ.copy())) else: - env.update(get_environment_from_batch_command( - [vcvarsall, 'x86'], - initial=os.environ.copy())) + env.update(get_environment_from_batch_command([vcvarsall, "x86"], initial=os.environ.copy())) else: - raise AssertionError('Unable to setup environment for Python: %s' % (sys.version,)) + raise AssertionError("Unable to setup environment for Python: %s" % (sys.version,)) - env['MSSdk'] = '1' - env['DISTUTILS_USE_SDK'] = '1' + env["MSSdk"] = "1" + env["DISTUTILS_USE_SDK"] = "1" additional_args = [] for arg in sys.argv: - if arg.startswith('--target-pyd-name='): + if arg.startswith("--target-pyd-name="): additional_args.append(arg) - if arg.startswith('--target-pyd-frame-eval='): + if arg.startswith("--target-pyd-frame-eval="): additional_args.append(arg) break else: - additional_args.append('--force-cython') # Build always forces cython! + additional_args.append("--force-cython") # Build always forces cython! args = [ - sys.executable, os.path.join(os.path.dirname(__file__), '..', 'setup_pydevd_cython.py'), 'build_ext', '--inplace', + sys.executable, + os.path.join(os.path.dirname(__file__), "..", "setup_pydevd_cython.py"), + "build_ext", + "--inplace", ] + additional_args - print('Calling args: %s' % (args,)) - subprocess.check_call(args, env=env,) + print("Calling args: %s" % (args,)) + subprocess.check_call( + args, + env=env, + ) -if __name__ == '__main__': - use_cython = os.getenv('PYDEVD_USE_CYTHON', '').lower() +if __name__ == "__main__": + use_cython = os.getenv("PYDEVD_USE_CYTHON", "").lower() # Note: don't import pydevd during build (so, accept just yes/no in this case). - if use_cython == 'yes': + if use_cython == "yes": print("Building") build() - elif use_cython == 'no': + elif use_cython == "no": print("Removing binaries") - remove_binaries(['.pyd', '.so']) + remove_binaries([".pyd", ".so"]) elif not use_cython: # Regular process - if '--no-regenerate-files' not in sys.argv: + if "--no-regenerate-files" not in sys.argv: print("Generating dont trace files") generate_dont_trace_files() print("Generating cython modules") @@ -174,5 +179,4 @@ def build(): print("Building") build() else: - raise RuntimeError('Unexpected value for PYDEVD_USE_CYTHON: %s (accepted: yes, no)' % (use_cython,)) - + raise RuntimeError("Unexpected value for PYDEVD_USE_CYTHON: %s (accepted: yes, no)" % (use_cython,)) diff --git a/build_tools/build_binaries_osx.py b/build_tools/build_binaries_osx.py index a3e376fff..3d6197ad0 100644 --- a/build_tools/build_binaries_osx.py +++ b/build_tools/build_binaries_osx.py @@ -1,28 +1,27 @@ - from __future__ import unicode_literals import os import subprocess import sys -miniconda64_envs = os.getenv('MINICONDA64_ENVS') +miniconda64_envs = os.getenv("MINICONDA64_ENVS") python_installations = [ - r'%s/py34_64/bin/python' % miniconda64_envs, - r'%s/py35_64/bin/python' % miniconda64_envs, - r'%s/py36_64/bin/python' % miniconda64_envs, - r'%s/py37_64/bin/python' % miniconda64_envs, - ] + r"%s/py34_64/bin/python" % miniconda64_envs, + r"%s/py35_64/bin/python" % miniconda64_envs, + r"%s/py36_64/bin/python" % miniconda64_envs, + r"%s/py37_64/bin/python" % miniconda64_envs, +] root_dir = os.path.dirname(os.path.dirname(__file__)) def list_binaries(): - for f in os.listdir(os.path.join(root_dir, '_pydevd_bundle')): - if f.endswith('.so'): + for f in os.listdir(os.path.join(root_dir, "_pydevd_bundle")): + if f.endswith(".so"): yield f def extract_version(python_install): - return python_install.split('/')[-3][2:] + return python_install.split("/")[-3][2:] def main(): @@ -37,24 +36,30 @@ def main(): assert os.path.exists(python_install) from build import remove_binaries - remove_binaries(['.so']) + + remove_binaries([".so"]) for f in list_binaries(): - raise AssertionError('Binary not removed: %s' % (f,)) + raise AssertionError("Binary not removed: %s" % (f,)) for i, python_install in enumerate(python_installations): - new_name = 'pydevd_cython_%s_%s' % (sys.platform, extract_version(python_install)) + new_name = "pydevd_cython_%s_%s" % (sys.platform, extract_version(python_install)) args = [ - python_install, os.path.join(root_dir, 'build_tools', 'build.py'), '--no-remove-binaries', '--target-pyd-name=%s' % new_name, '--force-cython'] + python_install, + os.path.join(root_dir, "build_tools", "build.py"), + "--no-remove-binaries", + "--target-pyd-name=%s" % new_name, + "--force-cython", + ] if i != 0: - args.append('--no-regenerate-files') + args.append("--no-regenerate-files") version_number = extract_version(python_install) - if version_number.startswith('36') or version_number.startswith('37'): - name_frame_eval = 'pydevd_frame_evaluator_%s_%s' % (sys.platform, extract_version(python_install)) - args.append('--target-pyd-frame-eval=%s' % name_frame_eval) - print('Calling: %s' % (' '.join(args))) + if version_number.startswith("36") or version_number.startswith("37"): + name_frame_eval = "pydevd_frame_evaluator_%s_%s" % (sys.platform, extract_version(python_install)) + args.append("--target-pyd-frame-eval=%s" % name_frame_eval) + print("Calling: %s" % (" ".join(args))) subprocess.check_call(args) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/build_tools/build_binaries_windows.py b/build_tools/build_binaries_windows.py index 925b431f8..82eaf75a3 100644 --- a/build_tools/build_binaries_windows.py +++ b/build_tools/build_binaries_windows.py @@ -1,4 +1,4 @@ -r''' +r""" Creating the needed environments for creating the pre-compiled distribution on Windows: See: @@ -6,22 +6,21 @@ build_tools\pydevd_release_process.txt for building binaries/release process. -''' +""" from __future__ import unicode_literals import os import subprocess import sys -miniconda_envs = os.getenv('MINICONDA_ENVS', r'D:\bin\miniconda\envs') +miniconda_envs = os.getenv("MINICONDA_ENVS", r"D:\bin\miniconda\envs") python_installations = [ - r'%s\py38_64\python.exe' % miniconda_envs, - r'%s\py39_64\python.exe' % miniconda_envs, - r'%s\py310_64\python.exe' % miniconda_envs, - r'%s\py311_64\python.exe' % miniconda_envs, - r'%s\py312_64\python.exe' % miniconda_envs, - + r"%s\py38_64\python.exe" % miniconda_envs, + r"%s\py39_64\python.exe" % miniconda_envs, + r"%s\py310_64\python.exe" % miniconda_envs, + r"%s\py311_64\python.exe" % miniconda_envs, + r"%s\py312_64\python.exe" % miniconda_envs, # See: build_tools\pydevd_release_process.txt when adding a new one ] @@ -29,13 +28,13 @@ def list_binaries(): - for f in os.listdir(os.path.join(root_dir, '_pydevd_bundle')): - if f.endswith('.pyd'): + for f in os.listdir(os.path.join(root_dir, "_pydevd_bundle")): + if f.endswith(".pyd"): yield f def extract_version(python_install): - return python_install.split('\\')[-2][2:] + return python_install.split("\\")[-2][2:] def main(): @@ -47,35 +46,41 @@ def main(): generate_cython_module() for python_install in python_installations: - assert os.path.exists(python_install), '%s does not exist.' % (python_install,) + assert os.path.exists(python_install), "%s does not exist." % (python_install,) from build import remove_binaries - remove_binaries(['.pyd']) + + remove_binaries([".pyd"]) for f in list_binaries(): - raise AssertionError('Binary not removed: %s' % (f,)) + raise AssertionError("Binary not removed: %s" % (f,)) for i, python_install in enumerate(python_installations): print() - print('*' * 80) - print('*' * 80) + print("*" * 80) + print("*" * 80) print() - new_name = 'pydevd_cython_%s_%s' % (sys.platform, extract_version(python_install)) + new_name = "pydevd_cython_%s_%s" % (sys.platform, extract_version(python_install)) args = [ - python_install, os.path.join(root_dir, 'build_tools', 'build.py'), '--no-remove-binaries', '--target-pyd-name=%s' % new_name, '--force-cython'] + python_install, + os.path.join(root_dir, "build_tools", "build.py"), + "--no-remove-binaries", + "--target-pyd-name=%s" % new_name, + "--force-cython", + ] if i != 0: - args.append('--no-regenerate-files') - name_frame_eval = 'pydevd_frame_evaluator_%s_%s' % (sys.platform, extract_version(python_install)) - args.append('--target-pyd-frame-eval=%s' % name_frame_eval) - print('Calling: %s' % (' '.join(args))) + args.append("--no-regenerate-files") + name_frame_eval = "pydevd_frame_evaluator_%s_%s" % (sys.platform, extract_version(python_install)) + args.append("--target-pyd-frame-eval=%s" % name_frame_eval) + print("Calling: %s" % (" ".join(args))) env = os.environ.copy() python_exe_dir = os.path.dirname(python_install) - env['PATH'] = env['PATH'] + ';' + os.path.join(python_exe_dir, 'DLLs') + ';' + os.path.join(python_exe_dir, 'Library', 'bin') + env["PATH"] = env["PATH"] + ";" + os.path.join(python_exe_dir, "DLLs") + ";" + os.path.join(python_exe_dir, "Library", "bin") subprocess.check_call(args, env=env) -if __name__ == '__main__': +if __name__ == "__main__": main() # To run do: diff --git a/build_tools/check_no_git_modifications.py b/build_tools/check_no_git_modifications.py index 4bb85f76a..78ce4bab9 100644 --- a/build_tools/check_no_git_modifications.py +++ b/build_tools/check_no_git_modifications.py @@ -1,6 +1,8 @@ import sys -expected_differences = set(line.strip() for line in r''' +expected_differences = set( + line.strip() + for line in r""" --- a/_pydevd_bundle/pydevd_cython.c +++ b/_pydevd_bundle/pydevd_cython.c - "_pydevd_bundle\\\\pydevd_cython.pyx", @@ -40,46 +42,48 @@ -static const char __pyx_k_pydevd_sys_monitoring__pydevd_s[] = "_pydevd_sys_monitoring\\_pydevd_sys_monitoring_cython.pyx"; - ".\\\\\\\\_pydevd_bundle\\\\\\\\pydevd_cython.pxd", - ".\\\\_pydevd_bundle\\\\pydevd_cython.pxd", -'''.splitlines() if line.strip()) +""".splitlines() + if line.strip() +) def main(): import subprocess - process = subprocess.Popen( - 'git status --porcelain'.split(), stderr=subprocess.STDOUT, stdout=subprocess.PIPE) + + process = subprocess.Popen("git status --porcelain".split(), stderr=subprocess.STDOUT, stdout=subprocess.PIPE) output, _ = process.communicate() if output: if sys.version_info[0] > 2: - output = output.decode('utf-8') + output = output.decode("utf-8") files = set() for line in output.splitlines(): filename = line[3:] files.add(filename.strip()) - files.discard('.travis_install_python_deps.sh') - files.discard('miniconda.sh') - files.discard('build_tools/check_no_git_modifications.py') + files.discard(".travis_install_python_deps.sh") + files.discard("miniconda.sh") + files.discard("build_tools/check_no_git_modifications.py") found_unexpected = True if files: found_unexpected = False - output = subprocess.check_output('git diff'.split()) - for line in output.decode('utf-8').splitlines(): - if line.startswith('+') or line.startswith('-'): + output = subprocess.check_output("git diff".split()) + for line in output.decode("utf-8").splitlines(): + if line.startswith("+") or line.startswith("-"): if line.strip() not in expected_differences: - print('Found unexpected: %r' % (line,)) + print("Found unexpected: %r" % (line,)) found_unexpected = True if files and found_unexpected: # If there are modifications, show a diff of the modifications and fail the script. # (we're mostly interested in modifications to the .c generated files by cython). - print('Found modifications in git:\n%s ' % (output,)) - print('Files: %s' % (files,)) - print('----------- diff -------------') - subprocess.call('git diff'.split()) - print('----------- end diff -------------') + print("Found modifications in git:\n%s " % (output,)) + print("Files: %s" % (files,)) + print("----------- diff -------------") + subprocess.call("git diff".split()) + print("----------- end diff -------------") sys.exit(1) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/build_tools/generate_code.py b/build_tools/generate_code.py index 9764ecde8..163938654 100644 --- a/build_tools/generate_code.py +++ b/build_tools/generate_code.py @@ -1,7 +1,7 @@ -''' +""" This module should be run to recreate the files that we generate automatically (i.e.: modules that shouldn't be traced and cython .pyx) -''' +""" from __future__ import print_function @@ -11,98 +11,102 @@ def is_python_64bit(): - return (struct.calcsize('P') == 8) + return struct.calcsize("P") == 8 -root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +root_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) def get_cython_contents(filename): - if filename.endswith('.pyc'): + if filename.endswith(".pyc"): filename = filename[:-1] - state = 'regular' + state = "regular" replacements = [] new_contents = [] - with open(filename, 'r') as stream: + with open(filename, "r") as stream: for line in stream: strip = line.strip() - if state == 'regular': - if strip == '# IFDEF CYTHON': - state = 'cython' + if state == "regular": + if strip == "# IFDEF CYTHON": + state = "cython" - new_contents.append('%s -- DONT EDIT THIS FILE (it is automatically generated)\n' % line.replace('\n', '').replace('\r', '')) + new_contents.append( + "%s -- DONT EDIT THIS FILE (it is automatically generated)\n" % line.replace("\n", "").replace("\r", "") + ) continue new_contents.append(line) - elif state == 'cython': - if strip == '# ELSE': - state = 'nocython' + elif state == "cython": + if strip == "# ELSE": + state = "nocython" new_contents.append(line) continue - elif strip == '# ENDIF': - state = 'regular' + elif strip == "# ENDIF": + state = "regular" new_contents.append(line) continue - if strip == '#': + if strip == "#": continue - assert strip.startswith('# '), 'Line inside # IFDEF CYTHON must start with "# ". Found: %s' % (strip,) - strip = strip.replace('# ', '', 1).strip() + assert strip.startswith("# "), 'Line inside # IFDEF CYTHON must start with "# ". Found: %s' % (strip,) + strip = strip.replace("# ", "", 1).strip() - if strip.startswith('cython_inline_constant:'): - strip = strip.replace('cython_inline_constant:', '') - word_to_replace, replacement = strip.split('=') + if strip.startswith("cython_inline_constant:"): + strip = strip.replace("cython_inline_constant:", "") + word_to_replace, replacement = strip.split("=") replacements.append((word_to_replace.strip(), replacement.strip())) continue - line = line.replace('# ', '', 1) + line = line.replace("# ", "", 1) new_contents.append(line) - elif state == 'nocython': - if strip == '# ENDIF': - state = 'regular' + elif state == "nocython": + if strip == "# ENDIF": + state = "regular" new_contents.append(line) continue - new_contents.append('# %s' % line) + new_contents.append("# %s" % line) - assert state == 'regular', 'Error: # IFDEF CYTHON found without # ENDIF' + assert state == "regular", "Error: # IFDEF CYTHON found without # ENDIF" - ret = ''.join(new_contents) + ret = "".join(new_contents) - for (word_to_replace, replacement) in replacements: + for word_to_replace, replacement in replacements: ret = re.sub(r"\b%s\b" % (word_to_replace,), replacement, ret) return ret def _generate_cython_from_files(target, modules): - contents = ['''from __future__ import print_function + contents = [ + """from __future__ import print_function # Important: Autogenerated file. # DO NOT edit manually! # DO NOT edit manually! -'''] +""" + ] found = [] for mod in modules: found.append(mod.__file__) contents.append(get_cython_contents(mod.__file__)) - print('Generating cython from: %s' % (found,)) + print("Generating cython from: %s" % (found,)) - with open(target, 'w') as stream: - stream.write(''.join(contents)) + with open(target, "w") as stream: + stream.write("".join(contents)) def generate_dont_trace_files(): - template = '''# Important: Autogenerated file. + template = """# Important: Autogenerated file. # DO NOT edit manually! # DO NOT edit manually! @@ -140,42 +144,41 @@ def generate_dont_trace_files(): DONT_TRACE['cp1252.py'] = LIB_FILE DONT_TRACE['utf_8.py'] = LIB_FILE DONT_TRACE['codecs.py'] = LIB_FILE -''' +""" pydev_files = [] pydev_dirs = [] pydev_lib_files_in_dont_trace_dirs = [] exclude_dirs = [ - '.git', - '.settings', - 'build', - 'build_tools', - 'dist', - 'pydevd.egg-info', - 'pydevd_attach_to_process', - 'pydev_sitecustomize', - 'stubs', - 'tests', - 'tests_mainloop', - 'tests_python', - 'tests_runfiles', - 'test_pydevd_reload', - 'third_party', - '__pycache__', - 'vendored', - '.mypy_cache', - 'pydevd.egg-info', + ".git", + ".settings", + "build", + "build_tools", + "dist", + "pydevd.egg-info", + "pydevd_attach_to_process", + "pydev_sitecustomize", + "stubs", + "tests", + "tests_mainloop", + "tests_python", + "tests_runfiles", + "test_pydevd_reload", + "third_party", + "__pycache__", + "vendored", + ".mypy_cache", + "pydevd.egg-info", ] for root, dirs, files in os.walk(root_dir): - for d in dirs: - if d == 'pydev_ipython': + if d == "pydev_ipython": pydev_dirs.append(" '%s': LIB_FILE," % (d,)) continue - if 'pydev' in d and d != 'pydevd.egg-info': + if "pydev" in d and d != "pydevd.egg-info": # print(os.path.join(root, d)) pydev_dirs.append(" '%s': PYDEV_FILE," % (d,)) @@ -185,34 +188,36 @@ def generate_dont_trace_files(): except: pass - if os.path.basename(root) == 'pydev_ipython': + if os.path.basename(root) == "pydev_ipython": for f in files: - if f.endswith('.py'): + if f.endswith(".py"): pydev_lib_files_in_dont_trace_dirs.append(" '%s'," % (f,)) continue for f in files: - if f.endswith('.py'): + if f.endswith(".py"): if f not in ( - '__init__.py', - 'runfiles.py', - 'pydev_coverage.py', - 'pydev_pysrc.py', - 'setup.py', - 'setup_pydevd_cython.py', - 'interpreterInfo.py', - 'conftest.py', - ): + "__init__.py", + "runfiles.py", + "pydev_coverage.py", + "pydev_pysrc.py", + "setup.py", + "setup_pydevd_cython.py", + "interpreterInfo.py", + "conftest.py", + ): pydev_files.append(" '%s': PYDEV_FILE," % (f,)) - contents = template % (dict( - pydev_files='\n'.join(sorted(set(pydev_files))), - pydev_dirs='\n'.join(sorted(set(pydev_dirs))), - pydev_lib_files_in_dont_trace_dirs='\n'.join(sorted(set(pydev_lib_files_in_dont_trace_dirs))), - )) - assert 'pydevd.py' in contents - assert 'pydevd_dont_trace.py' in contents - with open(os.path.join(root_dir, '_pydevd_bundle', 'pydevd_dont_trace_files.py'), 'w') as stream: + contents = template % ( + dict( + pydev_files="\n".join(sorted(set(pydev_files))), + pydev_dirs="\n".join(sorted(set(pydev_dirs))), + pydev_lib_files_in_dont_trace_dirs="\n".join(sorted(set(pydev_lib_files_in_dont_trace_dirs))), + ) + ) + assert "pydevd.py" in contents + assert "pydevd_dont_trace.py" in contents + with open(os.path.join(root_dir, "_pydevd_bundle", "pydevd_dont_trace_files.py"), "w") as stream: stream.write(contents) @@ -221,7 +226,9 @@ def remove_if_exists(f): if os.path.exists(f): os.remove(f) except: - import traceback;traceback.print_exc() + import traceback + + traceback.print_exc() def generate_cython_module(): @@ -230,42 +237,44 @@ def generate_cython_module(): def _generate_cython_module(): - print('Removing pydevd_cython.pyx') - remove_if_exists(os.path.join(root_dir, '_pydevd_bundle', 'pydevd_cython.pyx')) + print("Removing pydevd_cython.pyx") + remove_if_exists(os.path.join(root_dir, "_pydevd_bundle", "pydevd_cython.pyx")) - target = os.path.join(root_dir, '_pydevd_bundle', 'pydevd_cython.pyx') - curr = os.environ.get('PYDEVD_USE_CYTHON') + target = os.path.join(root_dir, "_pydevd_bundle", "pydevd_cython.pyx") + curr = os.environ.get("PYDEVD_USE_CYTHON") try: - os.environ['PYDEVD_USE_CYTHON'] = 'NO' + os.environ["PYDEVD_USE_CYTHON"] = "NO" from _pydevd_bundle import pydevd_additional_thread_info_regular from _pydevd_bundle import pydevd_frame, pydevd_trace_dispatch_regular + _generate_cython_from_files(target, [pydevd_additional_thread_info_regular, pydevd_frame, pydevd_trace_dispatch_regular]) finally: if curr is None: - del os.environ['PYDEVD_USE_CYTHON'] + del os.environ["PYDEVD_USE_CYTHON"] else: - os.environ['PYDEVD_USE_CYTHON'] = curr + os.environ["PYDEVD_USE_CYTHON"] = curr def _generate_sys_monitoring_cython_module(): - print('Removing _pydevd_sys_monitoring_cython.pyx') - remove_if_exists(os.path.join(root_dir, '_pydevd_sys_monitoring', '_pydevd_sys_monitoring_cython.pyx')) + print("Removing _pydevd_sys_monitoring_cython.pyx") + remove_if_exists(os.path.join(root_dir, "_pydevd_sys_monitoring", "_pydevd_sys_monitoring_cython.pyx")) - target = os.path.join(root_dir, '_pydevd_sys_monitoring', '_pydevd_sys_monitoring_cython.pyx') - curr = os.environ.get('PYDEVD_USE_CYTHON') + target = os.path.join(root_dir, "_pydevd_sys_monitoring", "_pydevd_sys_monitoring_cython.pyx") + curr = os.environ.get("PYDEVD_USE_CYTHON") try: - os.environ['PYDEVD_USE_CYTHON'] = 'NO' + os.environ["PYDEVD_USE_CYTHON"] = "NO" from _pydevd_sys_monitoring import _pydevd_sys_monitoring + _generate_cython_from_files(target, [_pydevd_sys_monitoring]) finally: if curr is None: - del os.environ['PYDEVD_USE_CYTHON'] + del os.environ["PYDEVD_USE_CYTHON"] else: - os.environ['PYDEVD_USE_CYTHON'] = curr + os.environ["PYDEVD_USE_CYTHON"] = curr -if __name__ == '__main__': +if __name__ == "__main__": generate_dont_trace_files() generate_cython_module() diff --git a/build_tools/names_to_rename.py b/build_tools/names_to_rename.py index 1525974d5..2e98d4857 100644 --- a/build_tools/names_to_rename.py +++ b/build_tools/names_to_rename.py @@ -1,7 +1,7 @@ -''' +""" Helper module to hold the names to rename while doing refactoring to convert to pep8. -''' -NAMES = ''' +""" +NAMES = """ # sendCaughtExceptionStack # sendBreakpointConditionException # setSuspend @@ -315,4 +315,4 @@ # setUpModule -- skip # tearDown -- skip -''' \ No newline at end of file +""" diff --git a/build_tools/rename_pep8.py b/build_tools/rename_pep8.py index 9a01203f9..c2a5dcfb4 100644 --- a/build_tools/rename_pep8.py +++ b/build_tools/rename_pep8.py @@ -1,16 +1,16 @@ -''' +""" Helper module to do refactoring to convert names to pep8. -''' +""" import re import os import names_to_rename -_CAMEL_RE = re.compile(r'(?<=[a-z])([A-Z])') -_CAMEL_DEF_RE = re.compile(r'(def )((([A-Z0-9]+|[a-z0-9])[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*)') +_CAMEL_RE = re.compile(r"(?<=[a-z])([A-Z])") +_CAMEL_DEF_RE = re.compile(r"(def )((([A-Z0-9]+|[a-z0-9])[a-z][a-z0-9]*[A-Z]|[a-z0-9]*[A-Z][A-Z0-9]*[a-z])[A-Za-z0-9]*)") def _normalize(name): - return _CAMEL_RE.sub(lambda x: '_' + x.group(1).lower(), name).lower() + return _CAMEL_RE.sub(lambda x: "_" + x.group(1).lower(), name).lower() def find_matches_in_contents(contents): @@ -19,15 +19,15 @@ def find_matches_in_contents(contents): def iter_files_in_dir(dirname): for root, dirs, files in os.walk(dirname): - for name in ('pydevd_attach_to_process', '.git', 'stubs', 'pydev_ipython', 'third_party', 'pydev_ipython'): + for name in ("pydevd_attach_to_process", ".git", "stubs", "pydev_ipython", "third_party", "pydev_ipython"): try: dirs.remove(name) except: pass for filename in files: - if filename.endswith('.py') and filename not in ('rename_pep8.py', 'names_to_rename.py'): + if filename.endswith(".py") and filename not in ("rename_pep8.py", "names_to_rename.py"): path = os.path.join(root, filename) - with open(path, 'rb') as stream: + with open(path, "rb") as stream: initial_contents = stream.read() yield path, initial_contents @@ -37,8 +37,8 @@ def find_matches(): found = set() for path, initial_contents in iter_files_in_dir(os.path.dirname(os.path.dirname(__file__))): found.update(find_matches_in_contents(initial_contents)) - print('\n'.join(sorted(found))) - print('Total', len(found)) + print("\n".join(sorted(found))) + print("Total", len(found)) def substitute_contents(re_name_to_new_val, initial_contents): @@ -54,14 +54,20 @@ def make_replace(): for path, initial_contents in iter_files_in_dir(os.path.dirname(os.path.dirname(__file__))): contents = substitute_contents(re_name_to_new_val, initial_contents) if contents != initial_contents: - print('Changed something at: %s' % (path,)) + print("Changed something at: %s" % (path,)) for val in re_name_to_new_val.itervalues(): # Check in initial contents to see if it already existed! - if re.findall(r'\b%s\b' % (val,), initial_contents): - raise AssertionError('Error in:\n%s\n%s is already being used (and changes may conflict).' % (path, val,)) - - with open(path, 'wb') as stream: + if re.findall(r"\b%s\b" % (val,), initial_contents): + raise AssertionError( + "Error in:\n%s\n%s is already being used (and changes may conflict)." + % ( + path, + val, + ) + ) + + with open(path, "wb") as stream: stream.write(contents) @@ -69,25 +75,28 @@ def load_re_to_new_val(names): name_to_new_val = {} for n in names.splitlines(): n = n.strip() - if not n.startswith('#') and n: - name_to_new_val[r'\b' + n + r'\b'] = _normalize(n) + if not n.startswith("#") and n: + name_to_new_val[r"\b" + n + r"\b"] = _normalize(n) return name_to_new_val def test(): - assert _normalize('RestoreSysSetTraceFunc') == 'restore_sys_set_trace_func' - assert _normalize('restoreSysSetTraceFunc') == 'restore_sys_set_trace_func' - assert _normalize('Restore') == 'restore' - matches = find_matches_in_contents(''' + assert _normalize("RestoreSysSetTraceFunc") == "restore_sys_set_trace_func" + assert _normalize("restoreSysSetTraceFunc") == "restore_sys_set_trace_func" + assert _normalize("Restore") == "restore" + matches = find_matches_in_contents( + """ def CamelCase() def camelCase() def ignore() def ignore_this() def Camel() def CamelCaseAnother() - ''') - assert matches == ['CamelCase', 'camelCase', 'Camel', 'CamelCaseAnother'] - re_name_to_new_val = load_re_to_new_val(''' + """ + ) + assert matches == ["CamelCase", "camelCase", "Camel", "CamelCaseAnother"] + re_name_to_new_val = load_re_to_new_val( + """ # Call -- skip # Call1 -- skip # Call2 -- skip @@ -101,9 +110,22 @@ def CamelCaseAnother() DictKeys DictPop DictValues -''') - assert re_name_to_new_val == {'\\bDictPop\\b': 'dict_pop', '\\bDictItems\\b': 'dict_items', '\\bDictIterValues\\b': 'dict_iter_values', '\\bDictKeys\\b': 'dict_keys', '\\bDictContains\\b': 'dict_contains', '\\bDictIterItems\\b': 'dict_iter_items', '\\bCustomFramesContainerInit\\b': 'custom_frames_container_init', '\\bDictValues\\b': 'dict_values'} - assert substitute_contents(re_name_to_new_val, ''' +""" + ) + assert re_name_to_new_val == { + "\\bDictPop\\b": "dict_pop", + "\\bDictItems\\b": "dict_items", + "\\bDictIterValues\\b": "dict_iter_values", + "\\bDictKeys\\b": "dict_keys", + "\\bDictContains\\b": "dict_contains", + "\\bDictIterItems\\b": "dict_iter_items", + "\\bCustomFramesContainerInit\\b": "custom_frames_container_init", + "\\bDictValues\\b": "dict_values", + } + assert ( + substitute_contents( + re_name_to_new_val, + """ CustomFramesContainerInit DictContains DictItems @@ -112,7 +134,9 @@ def CamelCaseAnother() DictKeys DictPop DictValues -''') == ''' +""", + ) + == """ custom_frames_container_init dict_contains dict_items @@ -121,11 +145,11 @@ def CamelCaseAnother() dict_keys dict_pop dict_values -''' +""" + ) -if __name__ == '__main__': -# find_matches() +if __name__ == "__main__": + # find_matches() make_replace() # test() - diff --git a/conftest.py b/conftest.py index c46c3f9f5..37728e657 100644 --- a/conftest.py +++ b/conftest.py @@ -9,33 +9,33 @@ def pytest_report_header(config): - print('PYDEVD_USE_CYTHON: %s' % (TEST_CYTHON,)) - print('PYDEVD_TEST_VM: %s' % (PYDEVD_TEST_VM,)) + print("PYDEVD_USE_CYTHON: %s" % (TEST_CYTHON,)) + print("PYDEVD_TEST_VM: %s" % (PYDEVD_TEST_VM,)) try: import multiprocessing except ImportError: pass else: - print('Number of processors: %s' % (multiprocessing.cpu_count(),)) + print("Number of processors: %s" % (multiprocessing.cpu_count(),)) - print('Relevant system paths:') - print('sys.executable: %s' % (sys.executable,)) - print('sys.prefix: %s' % (sys.prefix,)) + print("Relevant system paths:") + print("sys.executable: %s" % (sys.executable,)) + print("sys.prefix: %s" % (sys.prefix,)) - if hasattr(sys, 'base_prefix'): - print('sys.base_prefix: %s' % (sys.base_prefix,)) + if hasattr(sys, "base_prefix"): + print("sys.base_prefix: %s" % (sys.base_prefix,)) - if hasattr(sys, 'real_prefix'): - print('sys.real_prefix: %s' % (sys.real_prefix,)) + if hasattr(sys, "real_prefix"): + print("sys.real_prefix: %s" % (sys.real_prefix,)) - if hasattr(site, 'getusersitepackages'): - print('site.getusersitepackages(): %s' % (site.getusersitepackages(),)) + if hasattr(site, "getusersitepackages"): + print("site.getusersitepackages(): %s" % (site.getusersitepackages(),)) - if hasattr(site, 'getsitepackages'): - print('site.getsitepackages(): %s' % (site.getsitepackages(),)) + if hasattr(site, "getsitepackages"): + print("site.getsitepackages(): %s" % (site.getsitepackages(),)) for path in sys.path: - if os.path.exists(path) and os.path.basename(path) == 'site-packages': + if os.path.exists(path) and os.path.basename(path) == "site-packages": print('Folder with "site-packages" in sys.path: %s' % (path,)) @@ -51,44 +51,46 @@ def _start_monitoring_threads(): _started_monitoring_threads = True import threading - if hasattr(sys, '_current_frames') and hasattr(threading, 'enumerate'): + + if hasattr(sys, "_current_frames") and hasattr(threading, "enumerate"): import time import traceback class DumpThreads(threading.Thread): - def run(self): time.sleep(20) thread_id_to_name = {} try: for t in threading.enumerate(): - thread_id_to_name[t.ident] = '%s (daemon: %s)' % (t.name, t.daemon) + thread_id_to_name[t.ident] = "%s (daemon: %s)" % (t.name, t.daemon) except: pass stack_trace = [ - '===============================================================================', - 'pydev pyunit runner: Threads still found running after tests finished', - '================================= Thread Dump ================================='] + "===============================================================================", + "pydev pyunit runner: Threads still found running after tests finished", + "================================= Thread Dump =================================", + ] for thread_id, stack in sys._current_frames().items(): - stack_trace.append('\n-------------------------------------------------------------------------------') + stack_trace.append("\n-------------------------------------------------------------------------------") stack_trace.append(" Thread %s" % thread_id_to_name.get(thread_id, thread_id)) - stack_trace.append('') + stack_trace.append("") - if 'self' in stack.f_locals: - sys.stderr.write(str(stack.f_locals['self']) + '\n') + if "self" in stack.f_locals: + sys.stderr.write(str(stack.f_locals["self"]) + "\n") for filename, lineno, name, line in traceback.extract_stack(stack): stack_trace.append(' File "%s", line %d, in %s' % (filename, lineno, name)) if line: stack_trace.append(" %s" % (line.strip())) - stack_trace.append('\n=============================== END Thread Dump ===============================') - sys.stderr.write('\n'.join(stack_trace)) + stack_trace.append("\n=============================== END Thread Dump ===============================") + sys.stderr.write("\n".join(stack_trace)) # Force thread run to finish import os + os._exit(123) dump_current_frames_thread = DumpThreads() @@ -108,16 +110,14 @@ def check_no_threads(): # see: http://goo.gl/kTQMs SYMBOLS = { - 'customary': ('B', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'), - 'customary_ext': ('byte', 'kilo', 'mega', 'giga', 'tera', 'peta', 'exa', - 'zetta', 'iotta'), - 'iec': ('Bi', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi'), - 'iec_ext': ('byte', 'kibi', 'mebi', 'gibi', 'tebi', 'pebi', 'exbi', - 'zebi', 'yobi'), + "customary": ("B", "K", "M", "G", "T", "P", "E", "Z", "Y"), + "customary_ext": ("byte", "kilo", "mega", "giga", "tera", "peta", "exa", "zetta", "iotta"), + "iec": ("Bi", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"), + "iec_ext": ("byte", "kibi", "mebi", "gibi", "tebi", "pebi", "exbi", "zebi", "yobi"), } -def bytes2human(n, format='%(value).1f %(symbol)s', symbols='customary'): +def bytes2human(n, format="%(value).1f %(symbol)s", symbols="customary"): """ Bytes-to-human / human-to-bytes converter. Based on: http://goo.gl/kTQMs @@ -178,8 +178,12 @@ def bytes2human(n, format='%(value).1f %(symbol)s', symbols='customary'): def format_memory_info(memory_info, curr_proc_memory_info): - return 'Total: %s, Available: %s, Used: %s %%, Curr process: %s' % ( - bytes2human(memory_info.total), bytes2human(memory_info.available), memory_info.percent, format_process_memory_info(curr_proc_memory_info)) + return "Total: %s, Available: %s, Used: %s %%, Curr process: %s" % ( + bytes2human(memory_info.total), + bytes2human(memory_info.available), + memory_info.percent, + format_process_memory_info(curr_proc_memory_info), + ) def format_process_memory_info(proc_memory_info): @@ -209,17 +213,20 @@ def before_after_each_function(request): if _global_collect_info and DEBUG_MEMORY_INFO: try: from pympler import summary, muppy + sum1 = summary.summarize(muppy.get_objects()) except: pydev_log.exception() sys.stdout.write( -''' + """ =============================================================================== Memory before: %s %s =============================================================================== -''' % (request.function, format_memory_info(psutil.virtual_memory(), before_curr_proc_memory_info))) +""" + % (request.function, format_memory_info(psutil.virtual_memory(), before_curr_proc_memory_info)) + ) yield processes_info = [] @@ -229,14 +236,9 @@ def before_after_each_function(request): try: cmdline = proc.cmdline() except: - cmdline = '' + cmdline = "" processes_info.append( - 'New Process: %s(%s - %s) - %s' % ( - proc.name(), - proc.pid, - cmdline, - format_process_memory_info(proc.memory_info()) - ) + "New Process: %s(%s - %s) - %s" % (proc.name(), proc.pid, cmdline, format_process_memory_info(proc.memory_info())) ) except (psutil.NoSuchProcess, psutil.AccessDenied): pass # The process could've died in the meanwhile @@ -250,11 +252,11 @@ def before_after_each_function(request): if _global_collect_info: sum2 = summary.summarize(muppy.get_objects()) diff = summary.get_diff(sum1, sum2) - sys.stdout.write('===============================================================================\n') - sys.stdout.write('Leak info:\n') - sys.stdout.write('===============================================================================\n') + sys.stdout.write("===============================================================================\n") + sys.stdout.write("Leak info:\n") + sys.stdout.write("===============================================================================\n") summary.print_(diff) - sys.stdout.write('===============================================================================\n') + sys.stdout.write("===============================================================================\n") _global_collect_info = True # We'll only really collect the info on the next test (i.e.: if at one test @@ -265,17 +267,19 @@ def before_after_each_function(request): pydev_log.exception() sys.stdout.write( -''' + """ =============================================================================== Memory after: %s %s%s =============================================================================== -''' % ( - request.function, - format_memory_info(psutil.virtual_memory(), after_curr_proc_memory_info), - '' if not processes_info else '\nLeaked processes:\n' + '\n'.join(processes_info)), +""" + % ( + request.function, + format_memory_info(psutil.virtual_memory(), after_curr_proc_memory_info), + "" if not processes_info else "\nLeaked processes:\n" + "\n".join(processes_info), + ), ) @@ -337,7 +341,7 @@ def factory(source): raise ValueError("Failed to locate function header.") # Remove everything up to and including "def". - source = source[def_lineno + 1:] + source = source[def_lineno + 1 :] assert source # Now we need to adjust indentation. Compute how much the first line of @@ -353,8 +357,8 @@ def factory(source): # Write it to file. tmpfile = os.path.join(str(tmpdir), name + ".py") - assert not os.path.exists(tmpfile), '%s already exists.' % (tmpfile,) - with open(tmpfile, 'w') as stream: + assert not os.path.exists(tmpfile), "%s already exists." % (tmpfile,) + with open(tmpfile, "w") as stream: stream.write(source) return tmpfile @@ -363,7 +367,6 @@ def factory(source): if IS_JYTHON or IS_IRONPYTHON: - # On Jython and IronPython, it's a no-op. def before_after_each_function(): pass diff --git a/interpreterInfo.py b/interpreterInfo.py index de6aa0035..73dd43960 100644 --- a/interpreterInfo.py +++ b/interpreterInfo.py @@ -1,4 +1,4 @@ -''' +""" This module was created to get information available in the interpreter, such as libraries, paths, etc. @@ -10,30 +10,28 @@ EXECUTABLE:python.exe|libs@compiled_dlls$builtin_mods all internal are separated by | -''' +""" import sys try: import os.path def fully_normalize_path(path): - '''fixes the path so that the format of the path really reflects the directories in the system - ''' + """fixes the path so that the format of the path really reflects the directories in the system""" return os.path.normpath(path) join = os.path.join except: # ImportError or AttributeError. - # See: http://stackoverflow.com/questions/10254353/error-while-installing-jython-for-pydev def fully_normalize_path(path): - '''fixes the path so that the format of the path really reflects the directories in the system - ''' + """fixes the path so that the format of the path really reflects the directories in the system""" return path def join(a, b): - if a.endswith('/') or a.endswith('\\'): + if a.endswith("/") or a.endswith("\\"): return a + b - return a + '/' + b + return a + "/" + b + IS_PYTHON_3_ONWARDS = 0 @@ -48,21 +46,20 @@ def join(a, b): False True except: - exec ('True, False = 1,0') # An exec is used so that python 3k does not give a syntax error + exec("True, False = 1,0") # An exec is used so that python 3k does not give a syntax error if sys.platform == "cygwin": - import ctypes def native_path(path): MAX_PATH = 512 # On cygwin NT, its 260 lately, but just need BIG ENOUGH buffer - '''Get the native form of the path, like c:\\Foo for /cygdrive/c/Foo''' + """Get the native form of the path, like c:\\Foo for /cygdrive/c/Foo""" retval = ctypes.create_string_buffer(MAX_PATH) path = fully_normalize_path(path) path = tobytes(path) CCP_POSIX_TO_WIN_A = 0 - cygwin1dll = ctypes.cdll.LoadLibrary('cygwin1.dll') + cygwin1dll = ctypes.cdll.LoadLibrary("cygwin1.dll") cygwin1dll.cygwin_conv_path(CCP_POSIX_TO_WIN_A, path, retval, MAX_PATH) return retval.value @@ -74,29 +71,30 @@ def native_path(path): def __getfilesystemencoding(): - ''' + """ Note: there's a copy of this method in _pydev_filesystem_encoding.py - ''' + """ try: ret = sys.getfilesystemencoding() if not ret: - raise RuntimeError('Unable to get encoding.') + raise RuntimeError("Unable to get encoding.") return ret except: try: # Handle Jython from java.lang import System # @UnresolvedImport + env = System.getProperty("os.name").lower() - if env.find('win') != -1: - return 'ISO-8859-1' # mbcs does not work on Jython, so, use a (hopefully) suitable replacement - return 'utf-8' + if env.find("win") != -1: + return "ISO-8859-1" # mbcs does not work on Jython, so, use a (hopefully) suitable replacement + return "utf-8" except: pass # Only available from 2.3 onwards. - if sys.platform == 'win32': - return 'mbcs' - return 'utf-8' + if sys.platform == "win32": + return "mbcs" + return "utf-8" def getfilesystemencoding(): @@ -104,14 +102,14 @@ def getfilesystemencoding(): ret = __getfilesystemencoding() # Check if the encoding is actually there to be used! - if hasattr('', 'encode'): - ''.encode(ret) - if hasattr('', 'decode'): - ''.decode(ret) + if hasattr("", "encode"): + "".encode(ret) + if hasattr("", "decode"): + "".decode(ret) return ret except: - return 'utf-8' + return "utf-8" file_system_encoding = getfilesystemencoding() @@ -126,7 +124,7 @@ def getfilesystemencoding(): def tounicode(s): - if hasattr(s, 'decode'): + if hasattr(s, "decode"): if not isinstance(s, unicode_type): # Depending on the platform variant we may have decode on string or not. return s.decode(file_system_encoding) @@ -134,7 +132,7 @@ def tounicode(s): def tobytes(s): - if hasattr(s, 'encode'): + if hasattr(s, "encode"): if not isinstance(s, bytes_type): return s.encode(file_system_encoding) return s @@ -148,13 +146,13 @@ def toasciimxl(s): s = s.replace("&", "&") try: - ret = s.encode('ascii', 'xmlcharrefreplace') + ret = s.encode("ascii", "xmlcharrefreplace") except: # use workaround - ret = '' + ret = "" for c in s: try: - ret += c.encode('ascii') + ret += c.encode("ascii") except: try: # Python 2: unicode is a valid identifier @@ -165,10 +163,11 @@ def toasciimxl(s): return ret -if __name__ == '__main__': +if __name__ == "__main__": try: # just give some time to get the reading threads attached (just in case) import time + time.sleep(0.1) except: pass @@ -178,8 +177,8 @@ def toasciimxl(s): except: executable = tounicode(sys.executable) - if sys.platform == "cygwin" and not executable.endswith(tounicode('.exe')): - executable += tounicode('.exe') + if sys.platform == "cygwin" and not executable.endswith(tounicode(".exe")): + executable += tounicode(".exe") try: major = str(sys.version_info[0]) @@ -187,17 +186,18 @@ def toasciimxl(s): except AttributeError: # older versions of python don't have version_info import string - s = string.split(sys.version, ' ')[0] - s = string.split(s, '.') + + s = string.split(sys.version, " ")[0] + s = string.split(s, ".") major = s[0] minor = s[1] - s = tounicode('%s.%s') % (tounicode(major), tounicode(minor)) + s = tounicode("%s.%s") % (tounicode(major), tounicode(minor)) - contents = [tounicode('')] - contents.append(tounicode('%s') % (tounicode(s),)) + contents = [tounicode("")] + contents.append(tounicode("%s") % (tounicode(s),)) - contents.append(tounicode('%s') % tounicode(executable)) + contents.append(tounicode("%s") % tounicode(executable)) # this is the new implementation to get the system folders # (still need to check if it works in linux) @@ -218,6 +218,7 @@ def toasciimxl(s): try: import string # to be compatible with older versions + if string.find(p, prefix) == 0: # was startswith result.append((p, True)) else: @@ -240,10 +241,10 @@ def toasciimxl(s): # nor forced libs for builtinMod in sys.builtin_module_names: - contents.append(tounicode('%s') % tounicode(builtinMod)) + contents.append(tounicode("%s") % tounicode(builtinMod)) - contents.append(tounicode('')) - unic = tounicode('\n').join(contents) + contents.append(tounicode("")) + unic = tounicode("\n").join(contents) inasciixml = toasciimxl(unic) if IS_PYTHON_3_ONWARDS: # This is the 'official' way of writing binary output in Py3K (see: http://bugs.python.org/issue4571) diff --git a/pycompletionserver.py b/pycompletionserver.py index 2fb04f8d9..e2a7cbfa8 100644 --- a/pycompletionserver.py +++ b/pycompletionserver.py @@ -1,24 +1,27 @@ -''' +""" Entry-point module to start the code-completion server for PyDev. @author Fabio Zadrozny -''' +""" from _pydevd_bundle.pydevd_constants import IS_JYTHON if IS_JYTHON: import java.lang # @UnresolvedImport - SERVER_NAME = 'jycompletionserver' + + SERVER_NAME = "jycompletionserver" from _pydev_bundle import _pydev_jy_imports_tipper + _pydev_imports_tipper = _pydev_jy_imports_tipper else: # it is python - SERVER_NAME = 'pycompletionserver' + SERVER_NAME = "pycompletionserver" from _pydev_bundle import _pydev_imports_tipper from _pydev_bundle._pydev_saved_modules import socket import sys + if sys.platform == "darwin": # See: https://sourceforge.net/projects/pydev/forums/forum/293649/topic/3454227 try: @@ -53,27 +56,30 @@ def dbg(s, prior): if prior & DEBUG != 0: - sys.stdout.write('%s\n' % (s,)) + sys.stdout.write("%s\n" % (s,)) + + # f = open('c:/temp/test.txt', 'a') # print_ >> f, s # f.close() from _pydev_bundle import pydev_localhost + HOST = pydev_localhost.get_localhost() # Symbolic name meaning the local host -MSG_KILL_SERVER = '@@KILL_SERVER_END@@' -MSG_COMPLETIONS = '@@COMPLETIONS' -MSG_END = 'END@@' -MSG_INVALID_REQUEST = '@@INVALID_REQUEST' -MSG_JYTHON_INVALID_REQUEST = '@@JYTHON_INVALID_REQUEST' -MSG_CHANGE_DIR = '@@CHANGE_DIR:' -MSG_OK = '@@MSG_OK_END@@' -MSG_IMPORTS = '@@IMPORTS:' -MSG_PYTHONPATH = '@@PYTHONPATH_END@@' -MSG_CHANGE_PYTHONPATH = '@@CHANGE_PYTHONPATH:' -MSG_JEDI = '@@MSG_JEDI:' -MSG_SEARCH = '@@SEARCH' +MSG_KILL_SERVER = "@@KILL_SERVER_END@@" +MSG_COMPLETIONS = "@@COMPLETIONS" +MSG_END = "END@@" +MSG_INVALID_REQUEST = "@@INVALID_REQUEST" +MSG_JYTHON_INVALID_REQUEST = "@@JYTHON_INVALID_REQUEST" +MSG_CHANGE_DIR = "@@CHANGE_DIR:" +MSG_OK = "@@MSG_OK_END@@" +MSG_IMPORTS = "@@IMPORTS:" +MSG_PYTHONPATH = "@@PYTHONPATH_END@@" +MSG_CHANGE_PYTHONPATH = "@@CHANGE_PYTHONPATH:" +MSG_JEDI = "@@MSG_JEDI:" +MSG_SEARCH = "@@SEARCH" BUFFER_SIZE = 1024 @@ -81,10 +87,10 @@ def dbg(s, prior): def complete_from_dir(directory): - ''' + """ This is necessary so that we get the imports from the same directory where the file we are completing is located. - ''' + """ global currDirModule if currDirModule is not None: if len(sys.path) > 0 and sys.path[0] == currDirModule: @@ -95,12 +101,12 @@ def complete_from_dir(directory): def change_python_path(pythonpath): - '''Changes the pythonpath (clears all the previous pythonpath) + """Changes the pythonpath (clears all the previous pythonpath) @param pythonpath: string with paths separated by | - ''' + """ - split = pythonpath.split('|') + split = pythonpath.split("|") sys.path = [] for path in split: path = path.strip() @@ -109,7 +115,6 @@ def change_python_path(pythonpath): class Processor: - def __init__(self): # nothing to do return @@ -124,36 +129,36 @@ def remove_invalid_chars(self, msg): try: return quote_plus(msg) except: - sys.stdout.write('error making quote plus in %s\n' % (msg,)) + sys.stdout.write("error making quote plus in %s\n" % (msg,)) raise - return ' ' + return " " def format_completion_message(self, defFile, completionsList): - ''' + """ Format the completions suggestions in the following format: @@COMPLETIONS(modFile(token,description),(token,description),(token,description))END@@ - ''' + """ compMsg = [] - compMsg.append('%s' % defFile) + compMsg.append("%s" % defFile) for tup in completionsList: - compMsg.append(',') + compMsg.append(",") - compMsg.append('(') + compMsg.append("(") compMsg.append(str(self.remove_invalid_chars(tup[0]))) # token - compMsg.append(',') + compMsg.append(",") compMsg.append(self.remove_invalid_chars(tup[1])) # description - if(len(tup) > 2): - compMsg.append(',') + if len(tup) > 2: + compMsg.append(",") compMsg.append(self.remove_invalid_chars(tup[2])) # args - only if function. - if(len(tup) > 3): - compMsg.append(',') + if len(tup) > 3: + compMsg.append(",") compMsg.append(self.remove_invalid_chars(tup[3])) # TYPE - compMsg.append(')') + compMsg.append(")") - return '%s(%s)%s' % (MSG_COMPLETIONS, ''.join(compMsg), MSG_END) + return "%s(%s)%s" % (MSG_COMPLETIONS, "".join(compMsg), MSG_END) class Exit(Exception): @@ -161,7 +166,6 @@ class Exit(Exception): class CompletionServer: - def __init__(self, port): self.ended = False self.port = port @@ -176,27 +180,27 @@ def connect_to_server(self): try: s.connect((HOST, self.port)) except: - sys.stderr.write('Error on connect_to_server with parameters: host: %s port: %s\n' % (HOST, self.port)) + sys.stderr.write("Error on connect_to_server with parameters: host: %s port: %s\n" % (HOST, self.port)) raise def get_completions_message(self, defFile, completionsList): - ''' + """ get message with completions. - ''' + """ return self.processor.format_completion_message(defFile, completionsList) def get_token_and_data(self, data): - ''' + """ When we receive this, we have 'token):data' - ''' - token = '' + """ + token = "" for c in data: - if c != ')': + if c != ")": token = token + c else: - break; + break - return token, data.lstrip(token + '):') + return token, data.lstrip(token + "):") def emulated_sendall(self, msg): MSGLEN = 1024 * 20 @@ -209,68 +213,69 @@ def emulated_sendall(self, msg): totalsent = totalsent + sent def send(self, msg): - self.socket.sendall(bytearray(msg, 'utf-8')) + self.socket.sendall(bytearray(msg, "utf-8")) def run(self): # Echo server program try: from _pydev_bundle import _pydev_log + log = _pydev_log.Log() - dbg(SERVER_NAME + ' connecting to java server on %s (%s)' % (HOST, self.port) , INFO1) + dbg(SERVER_NAME + " connecting to java server on %s (%s)" % (HOST, self.port), INFO1) # after being connected, create a socket as a client. self.connect_to_server() - dbg(SERVER_NAME + ' Connected to java server', INFO1) + dbg(SERVER_NAME + " Connected to java server", INFO1) while not self.ended: - data = '' + data = "" while data.find(MSG_END) == -1: received = self.socket.recv(BUFFER_SIZE) if len(received) == 0: raise Exit() # ok, connection ended - data = data + received.decode('utf-8') + data = data + received.decode("utf-8") try: try: if data.find(MSG_KILL_SERVER) != -1: - dbg(SERVER_NAME + ' kill message received', INFO1) + dbg(SERVER_NAME + " kill message received", INFO1) # break if we received kill message. self.ended = True raise Exit() - dbg(SERVER_NAME + ' starting keep alive thread', INFO2) + dbg(SERVER_NAME + " starting keep alive thread", INFO2) if data.find(MSG_PYTHONPATH) != -1: comps = [] for p in _sys_path: - comps.append((p, ' ')) + comps.append((p, " ")) self.send(self.get_completions_message(None, comps)) else: - data = data[:data.rfind(MSG_END)] + data = data[: data.rfind(MSG_END)] if data.startswith(MSG_IMPORTS): - data = data[len(MSG_IMPORTS):] + data = data[len(MSG_IMPORTS) :] data = unquote_plus(data) defFile, comps = _pydev_imports_tipper.generate_tip(data, log) self.send(self.get_completions_message(defFile, comps)) elif data.startswith(MSG_CHANGE_PYTHONPATH): - data = data[len(MSG_CHANGE_PYTHONPATH):] + data = data[len(MSG_CHANGE_PYTHONPATH) :] data = unquote_plus(data) change_python_path(data) self.send(MSG_OK) elif data.startswith(MSG_JEDI): - data = data[len(MSG_JEDI):] + data = data[len(MSG_JEDI) :] data = unquote_plus(data) - line, column, encoding, path, source = data.split('|', 4) + line, column, encoding, path, source = data.split("|", 4) try: import jedi # @UnresolvedImport except: - self.send(self.get_completions_message(None, [('Error on import jedi', 'Error importing jedi', '')])) + self.send(self.get_completions_message(None, [("Error on import jedi", "Error importing jedi", "")])) else: script = jedi.Script( # Line +1 because it expects lines 1-based (and col 0-based) @@ -283,36 +288,36 @@ def run(self): lst = [] for completion in script.completions(): t = completion.type - if t == 'class': - t = '1' + if t == "class": + t = "1" - elif t == 'function': - t = '2' + elif t == "function": + t = "2" - elif t == 'import': - t = '0' + elif t == "import": + t = "0" - elif t == 'keyword': + elif t == "keyword": continue # Keywords are already handled in PyDev - elif t == 'statement': - t = '3' + elif t == "statement": + t = "3" else: - t = '-1' + t = "-1" # gen list(tuple(name, doc, args, type)) - lst.append((completion.name, '', '', t)) - self.send(self.get_completions_message('empty', lst)) + lst.append((completion.name, "", "", t)) + self.send(self.get_completions_message("empty", lst)) elif data.startswith(MSG_SEARCH): - data = data[len(MSG_SEARCH):] + data = data[len(MSG_SEARCH) :] data = unquote_plus(data) (f, line, col), foundAs = _pydev_imports_tipper.search_definition(data) self.send(self.get_completions_message(f, [(line, col, foundAs)])) elif data.startswith(MSG_CHANGE_DIR): - data = data[len(MSG_CHANGE_DIR):] + data = data[len(MSG_CHANGE_DIR) :] data = unquote_plus(data) complete_from_dir(data) self.send(MSG_OK) @@ -321,7 +326,7 @@ def run(self): self.send(MSG_INVALID_REQUEST) except Exit: e = sys.exc_info()[1] - msg = self.get_completions_message(None, [('Exit:', 'SystemExit', '')]) + msg = self.get_completions_message(None, [("Exit:", "SystemExit", "")]) try: self.send(msg) except socket.error: @@ -330,13 +335,13 @@ def run(self): raise e # raise original error. except: - dbg(SERVER_NAME + ' exception occurred', ERROR) + dbg(SERVER_NAME + " exception occurred", ERROR) s = StringIO() traceback.print_exc(file=s) err = s.getvalue() - dbg(SERVER_NAME + ' received error: ' + str(err), ERROR) - msg = self.get_completions_message(None, [('ERROR:', '%s\nLog:%s' % (err, log.get_contents()), '')]) + dbg(SERVER_NAME + " received error: " + str(err), ERROR) + msg = self.get_completions_message(None, [("ERROR:", "%s\nLog:%s" % (err, log.get_contents()), "")]) try: self.send(msg) except socket.error: @@ -359,14 +364,13 @@ def run(self): traceback.print_exception(exc_info[0], exc_info[1], exc_info[2], limit=None, file=s) err = s.getvalue() - dbg(SERVER_NAME + ' received error: ' + str(err), ERROR) + dbg(SERVER_NAME + " received error: " + str(err), ERROR) raise -if __name__ == '__main__': - +if __name__ == "__main__": port = int(sys.argv[1]) # this is from where we want to receive messages. t = CompletionServer(port) - dbg(SERVER_NAME + ' will start', INFO1) + dbg(SERVER_NAME + " will start", INFO1) t.run() diff --git a/pydev_app_engine_debug_startup.py b/pydev_app_engine_debug_startup.py index 464f0ddf3..7325d1a88 100644 --- a/pydev_app_engine_debug_startup.py +++ b/pydev_app_engine_debug_startup.py @@ -1,21 +1,22 @@ if False: config = None - - + + # See: https://docs.google.com/document/d/1CCSaRiIWCLgbD3OwmuKsRoHHDfBffbROWyVWWL0ZXN4/edit -if ':' not in config.version_id: +if ":" not in config.version_id: # The default server version_id does not contain ':' - import json + import json import os import sys - + startup = config.python_config.startup_args if not startup: - raise AssertionError('Expected --python_startup_args to be passed from the pydev debugger.') - - setup = json.loads(startup) - pydevd_path = setup['pydevd'] + raise AssertionError("Expected --python_startup_args to be passed from the pydev debugger.") + + setup = json.loads(startup) + pydevd_path = setup["pydevd"] sys.path.append(os.path.dirname(pydevd_path)) - + import pydevd - pydevd.settrace(setup['client'], port=setup['port'], suspend=False, trace_only_current_thread=False) + + pydevd.settrace(setup["client"], port=setup["port"], suspend=False, trace_only_current_thread=False) diff --git a/pydev_coverage.py b/pydev_coverage.py index 665e87ba9..77324c8f5 100644 --- a/pydev_coverage.py +++ b/pydev_coverage.py @@ -1,20 +1,20 @@ -''' +""" Entry point module to run code-coverage. -''' +""" def is_valid_py_file(path): - ''' + """ Checks whether the file can be read by the coverage module. This is especially needed for .pyx files and .py files with syntax errors. - ''' + """ import os is_valid = False - if os.path.isfile(path) and not os.path.splitext(path)[1] == '.pyx': + if os.path.isfile(path) and not os.path.splitext(path)[1] == ".pyx": try: - with open(path, 'rb') as f: - compile(f.read(), path, 'exec') + with open(path, "rb") as f: + compile(f.read(), path, "exec") is_valid = True except: pass @@ -26,29 +26,26 @@ def execute(): import sys files = None - if 'combine' not in sys.argv: - - if '--pydev-analyze' in sys.argv: - + if "combine" not in sys.argv: + if "--pydev-analyze" in sys.argv: # Ok, what we want here is having the files passed through stdin (because # there may be too many files for passing in the command line -- we could # just pass a dir and make the find files here, but as that's already # given in the java side, let's just gather that info here). - sys.argv.remove('--pydev-analyze') + sys.argv.remove("--pydev-analyze") s = input() - s = s.replace('\r', '') - s = s.replace('\n', '') + s = s.replace("\r", "") + s = s.replace("\n", "") files = [] invalid_files = [] - for v in s.split('|'): + for v in s.split("|"): if is_valid_py_file(v): files.append(v) else: invalid_files.append(v) if invalid_files: - sys.stderr.write('Invalid files not passed to coverage: %s\n' - % ', '.join(invalid_files)) + sys.stderr.write("Invalid files not passed to coverage: %s\n" % ", ".join(invalid_files)) # Note that in this case we'll already be in the working dir with the coverage files, # so, the coverage file location is not passed. @@ -56,39 +53,40 @@ def execute(): else: # For all commands, the coverage file is configured in pydev, and passed as the first # argument in the command line, so, let's make sure this gets to the coverage module. - os.environ['COVERAGE_FILE'] = sys.argv[1] + os.environ["COVERAGE_FILE"] = sys.argv[1] del sys.argv[1] try: import coverage # @UnresolvedImport except: - sys.stderr.write('Error: coverage module could not be imported\n') - sys.stderr.write('Please make sure that the coverage module ' - '(http://nedbatchelder.com/code/coverage/)\n') - sys.stderr.write('is properly installed in your interpreter: %s\n' % (sys.executable,)) + sys.stderr.write("Error: coverage module could not be imported\n") + sys.stderr.write("Please make sure that the coverage module " "(http://nedbatchelder.com/code/coverage/)\n") + sys.stderr.write("is properly installed in your interpreter: %s\n" % (sys.executable,)) + + import traceback - import traceback;traceback.print_exc() + traceback.print_exc() return - if hasattr(coverage, '__version__'): - version = tuple(map(int, coverage.__version__.split('.')[:2])) + if hasattr(coverage, "__version__"): + version = tuple(map(int, coverage.__version__.split(".")[:2])) if version < (4, 3): - sys.stderr.write('Error: minimum supported coverage version is 4.3.' - '\nFound: %s\nLocation: %s\n' - % ('.'.join(str(x) for x in version), coverage.__file__)) + sys.stderr.write( + "Error: minimum supported coverage version is 4.3." + "\nFound: %s\nLocation: %s\n" % (".".join(str(x) for x in version), coverage.__file__) + ) sys.exit(1) else: - sys.stderr.write('Warning: Could not determine version of python module coverage.' - '\nEnsure coverage version is >= 4.3\n') + sys.stderr.write("Warning: Could not determine version of python module coverage." "\nEnsure coverage version is >= 4.3\n") from coverage.cmdline import main # @UnresolvedImport if files is not None: - sys.argv.append('xml') + sys.argv.append("xml") sys.argv += files main() -if __name__ == '__main__': +if __name__ == "__main__": execute() diff --git a/pydev_ipython/inputhook.py b/pydev_ipython/inputhook.py index fe088466f..47b935477 100644 --- a/pydev_ipython/inputhook.py +++ b/pydev_ipython/inputhook.py @@ -3,40 +3,40 @@ Inputhook management for GUI event loop integration. """ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- import sys import select -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Constants -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Constants for identifying the GUI toolkits. -GUI_WX = 'wx' -GUI_QT = 'qt' -GUI_QT4 = 'qt4' -GUI_QT5 = 'qt5' -GUI_GTK = 'gtk' -GUI_TK = 'tk' -GUI_OSX = 'osx' -GUI_GLUT = 'glut' -GUI_PYGLET = 'pyglet' -GUI_GTK3 = 'gtk3' -GUI_NONE = 'none' # i.e. disable - -#----------------------------------------------------------------------------- +GUI_WX = "wx" +GUI_QT = "qt" +GUI_QT4 = "qt4" +GUI_QT5 = "qt5" +GUI_GTK = "gtk" +GUI_TK = "tk" +GUI_OSX = "osx" +GUI_GLUT = "glut" +GUI_PYGLET = "pyglet" +GUI_GTK3 = "gtk3" +GUI_NONE = "none" # i.e. disable + +# ----------------------------------------------------------------------------- # Utilities -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def ignore_CTRL_C(): @@ -48,9 +48,10 @@ def allow_CTRL_C(): """Take CTRL+C into account (not implemented).""" pass -#----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- # Main InputHookManager class -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- class InputHookManager(object): @@ -146,12 +147,14 @@ def enable_wx(self, app=None): """ import wx from distutils.version import LooseVersion as V + wx_version = V(wx.__version__).version # @UndefinedVariable if wx_version < [2, 8]: raise ValueError("requires wxPython >= 2.8, but you have %s" % wx.__version__) # @UndefinedVariable from pydev_ipython.inputhookwx import inputhook_wx + self.set_inputhook(inputhook_wx) self._current_gui = GUI_WX @@ -174,6 +177,7 @@ def disable_wx(self): def enable_qt(self, app=None): from pydev_ipython.qt_for_kernel import QT_API, QT_API_PYQT5 + if QT_API == QT_API_PYQT5: self.enable_qt5(app) else: @@ -202,6 +206,7 @@ def enable_qt4(self, app=None): app = QtGui.QApplication(sys.argv) """ from pydev_ipython.inputhookqt4 import create_inputhook_qt4 + app, inputhook_qt4 = create_inputhook_qt4(self, app) self.set_inputhook(inputhook_qt4) @@ -221,6 +226,7 @@ def disable_qt4(self): def enable_qt5(self, app=None): from pydev_ipython.inputhookqt5 import create_inputhook_qt5 + app, inputhook_qt5 = create_inputhook_qt5(self, app) self.set_inputhook(inputhook_qt5) @@ -251,6 +257,7 @@ def enable_gtk(self, app=None): IPython. """ from pydev_ipython.inputhookgtk import create_inputhook_gtk + self.set_inputhook(create_inputhook_gtk(self._stdin_file)) self._current_gui = GUI_GTK @@ -289,6 +296,7 @@ def enable_tk(self, app=None): self._apps[GUI_TK] = app from pydev_ipython.inputhooktk import create_inputhook_tk + self.set_inputhook(create_inputhook_tk(app)) return app @@ -300,7 +308,7 @@ def disable_tk(self): self.clear_inputhook() def enable_glut(self, app=None): - """ Enable event loop integration with GLUT. + """Enable event loop integration with GLUT. Parameters ---------- @@ -325,19 +333,16 @@ def enable_glut(self, app=None): """ import OpenGL.GLUT as glut # @UnresolvedImport - from pydev_ipython.inputhookglut import glut_display_mode, \ - glut_close, glut_display, \ - glut_idle, inputhook_glut + from pydev_ipython.inputhookglut import glut_display_mode, glut_close, glut_display, glut_idle, inputhook_glut if GUI_GLUT not in self._apps: - argv = getattr(sys, 'argv', []) + argv = getattr(sys, "argv", []) glut.glutInit(argv) glut.glutInitDisplayMode(glut_display_mode) # This is specific to freeglut if bool(glut.glutSetOption): - glut.glutSetOption(glut.GLUT_ACTION_ON_WINDOW_CLOSE, - glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS) - glut.glutCreateWindow(argv[0] if len(argv) > 0 else '') + glut.glutSetOption(glut.GLUT_ACTION_ON_WINDOW_CLOSE, glut.GLUT_ACTION_GLUTMAINLOOP_RETURNS) + glut.glutCreateWindow(argv[0] if len(argv) > 0 else "") glut.glutReshapeWindow(1, 1) glut.glutHideWindow() glut.glutWMCloseFunc(glut_close) @@ -383,6 +388,7 @@ def enable_pyglet(self, app=None): """ from pydev_ipython.inputhookpyglet import inputhook_pyglet + self.set_inputhook(inputhook_pyglet) self._current_gui = GUI_PYGLET return app @@ -411,6 +417,7 @@ def enable_gtk3(self, app=None): IPython. """ from pydev_ipython.inputhookgtk3 import create_inputhook_gtk3 + self.set_inputhook(create_inputhook_gtk3(self._stdin_file)) self._current_gui = GUI_GTK @@ -422,7 +429,7 @@ def disable_gtk3(self): self.clear_inputhook() def enable_mac(self, app=None): - """ Enable event loop integration with MacOSX. + """Enable event loop integration with MacOSX. We call function pyplot.pause, which updates and displays active figure during pause. It's not MacOSX-specific, but it enables to @@ -434,13 +441,13 @@ def enable_mac(self, app=None): def inputhook_mac(app=None): if self.pyplot_imported: - pyplot = sys.modules['matplotlib.pyplot'] + pyplot = sys.modules["matplotlib.pyplot"] try: pyplot.pause(0.01) except: pass else: - if 'matplotlib.pyplot' in sys.modules: + if "matplotlib.pyplot" in sys.modules: self.pyplot_imported = True self.set_inputhook(inputhook_mac) @@ -517,22 +524,23 @@ def enable_gui(gui=None, app=None): if get_return_control_callback() is None: raise ValueError("A return_control_callback must be supplied as a reference before a gui can be enabled") - guis = {GUI_NONE: clear_inputhook, - GUI_OSX: enable_mac, - GUI_TK: enable_tk, - GUI_GTK: enable_gtk, - GUI_WX: enable_wx, - GUI_QT: enable_qt, - GUI_QT4: enable_qt4, - GUI_QT5: enable_qt5, - GUI_GLUT: enable_glut, - GUI_PYGLET: enable_pyglet, - GUI_GTK3: enable_gtk3, - } + guis = { + GUI_NONE: clear_inputhook, + GUI_OSX: enable_mac, + GUI_TK: enable_tk, + GUI_GTK: enable_gtk, + GUI_WX: enable_wx, + GUI_QT: enable_qt, + GUI_QT4: enable_qt4, + GUI_QT5: enable_qt5, + GUI_GLUT: enable_glut, + GUI_PYGLET: enable_pyglet, + GUI_GTK3: enable_gtk3, + } try: gui_hook = guis[gui] except KeyError: - if gui is None or gui == '': + if gui is None or gui == "": gui_hook = clear_inputhook else: e = "Invalid GUI request %r, valid ones are:%s" % (gui, list(guis.keys())) @@ -552,14 +560,10 @@ def enable_gui(gui=None, app=None): "GUI_PYGLET", "GUI_GTK3", "GUI_NONE", - "ignore_CTRL_C", "allow_CTRL_C", - "InputHookManager", - "inputhook_manager", - "enable_wx", "disable_wx", "enable_qt", @@ -583,10 +587,9 @@ def enable_gui(gui=None, app=None): "set_inputhook", "current_gui", "clear_app_refs", - "stdin_ready", "set_return_control_callback", "get_return_control_callback", "get_inputhook", - - "enable_gui"] + "enable_gui", +] diff --git a/pydev_ipython/inputhookglut.py b/pydev_ipython/inputhookglut.py index d65add9b9..feab648dc 100644 --- a/pydev_ipython/inputhookglut.py +++ b/pydev_ipython/inputhookglut.py @@ -3,12 +3,12 @@ GLUT Inputhook support functions """ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # GLUT is quite an old library and it is difficult to ensure proper # integration within IPython since original GLUT does not allow to handle @@ -26,9 +26,9 @@ # them later without modifying the code. This should probably be made available # via IPython options system. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- import os import sys from _pydev_bundle._pydev_saved_modules import time @@ -38,9 +38,9 @@ from timeit import default_timer as clock from pydev_ipython.inputhook import stdin_ready -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Constants -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Frame per second : 60 # Should probably be an IPython option @@ -48,34 +48,30 @@ # Display mode : double buffeed + rgba + depth # Should probably be an IPython option -glut_display_mode = (glut.GLUT_DOUBLE | - glut.GLUT_RGBA | - glut.GLUT_DEPTH) +glut_display_mode = glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH glutMainLoopEvent = None -if sys.platform == 'darwin': +if sys.platform == "darwin": try: glutCheckLoop = platform.createBaseFunction( - 'glutCheckLoop', dll=platform.GLUT, resultType=None, + "glutCheckLoop", + dll=platform.GLUT, + resultType=None, argTypes=[], - doc='glutCheckLoop( ) -> None', + doc="glutCheckLoop( ) -> None", argNames=(), - ) + ) except AttributeError: - raise RuntimeError( - '''Your glut implementation does not allow interactive sessions''' - '''Consider installing freeglut.''') + raise RuntimeError("""Your glut implementation does not allow interactive sessions""" """Consider installing freeglut.""") glutMainLoopEvent = glutCheckLoop elif glut.HAVE_FREEGLUT: glutMainLoopEvent = glut.glutMainLoopEvent else: - raise RuntimeError( - '''Your glut implementation does not allow interactive sessions. ''' - '''Consider installing freeglut.''') + raise RuntimeError("""Your glut implementation does not allow interactive sessions. """ """Consider installing freeglut.""") -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Callback functions -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def glut_display(): @@ -97,13 +93,13 @@ def glut_close(): def glut_int_handler(signum, frame): # Catch sigint and print the defautl message signal.signal(signal.SIGINT, signal.default_int_handler) - print('\nKeyboardInterrupt') + print("\nKeyboardInterrupt") # Need to reprint the prompt at this stage -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def inputhook_glut(): """Run the pyglet event loop by processing pending events only. diff --git a/pydev_ipython/inputhookgtk.py b/pydev_ipython/inputhookgtk.py index 53006cde9..8911a868b 100644 --- a/pydev_ipython/inputhookgtk.py +++ b/pydev_ipython/inputhookgtk.py @@ -5,32 +5,33 @@ Authors: Brian Granger """ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- import gtk, gobject # @UnresolvedImport -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def _main_quit(*args, **kwargs): gtk.main_quit() return False + def create_inputhook_gtk(stdin_file): def inputhook_gtk(): gobject.io_add_watch(stdin_file, gobject.IO_IN, _main_quit) gtk.main() return 0 - return inputhook_gtk + return inputhook_gtk diff --git a/pydev_ipython/inputhookgtk3.py b/pydev_ipython/inputhookgtk3.py index f2ca39f39..198f9b816 100644 --- a/pydev_ipython/inputhookgtk3.py +++ b/pydev_ipython/inputhookgtk3.py @@ -4,23 +4,24 @@ Authors: Thomi Richards """ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (c) 2012, the IPython Development Team. # # Distributed under the terms of the Modified BSD License. # # The full license is in the file COPYING.txt, distributed with this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- from gi.repository import Gtk, GLib # @UnresolvedImport -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- + def _main_quit(*args, **kwargs): Gtk.main_quit() @@ -32,4 +33,5 @@ def inputhook_gtk3(): GLib.io_add_watch(stdin_file, GLib.IO_IN, _main_quit) Gtk.main() return 0 + return inputhook_gtk3 diff --git a/pydev_ipython/inputhookpyglet.py b/pydev_ipython/inputhookpyglet.py index 552930796..76d5f6385 100644 --- a/pydev_ipython/inputhookpyglet.py +++ b/pydev_ipython/inputhookpyglet.py @@ -9,16 +9,16 @@ * Fernando Perez """ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- import os import sys @@ -32,19 +32,22 @@ # window close. For details, see: # http://groups.google.com/group/pyglet-users/browse_thread/thread/47c1aab9aa4a3d23/c22f9e819826799e?#c22f9e819826799e -if sys.platform.startswith('linux'): +if sys.platform.startswith("linux"): + def flip(window): try: window.flip() except AttributeError: pass else: + def flip(window): window.flip() -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- + def inputhook_pyglet(): """Run the pyglet event loop by processing pending events only. @@ -63,7 +66,7 @@ def inputhook_pyglet(): for window in pyglet.app.windows: window.switch_to() window.dispatch_events() - window.dispatch_event('on_draw') + window.dispatch_event("on_draw") flip(window) # We need to sleep at this point to keep the idle CPU load diff --git a/pydev_ipython/inputhookqt4.py b/pydev_ipython/inputhookqt4.py index 2b4d159a5..137e33e81 100644 --- a/pydev_ipython/inputhookqt4.py +++ b/pydev_ipython/inputhookqt4.py @@ -5,16 +5,16 @@ Author: Christian Boos """ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (C) 2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- import os import signal @@ -41,17 +41,18 @@ def set_hook(self, *args, **kwargs): # KeyboardInterrupts to consider since we are running under PyDev pass -#----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- # Module Globals -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- got_kbdint = False sigint_timer = None -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def create_inputhook_qt4(mgr, app=None): @@ -88,7 +89,7 @@ def create_inputhook_qt4(mgr, app=None): # Re-use previously created inputhook if any ip = InteractiveShell.instance() - if hasattr(ip, '_inputhook_qt4'): + if hasattr(ip, "_inputhook_qt4"): return app, ip._inputhook_qt4 # Otherwise create the inputhook_qt4/preprompthook_qt4 pair of @@ -157,11 +158,10 @@ def inputhook_qt4(): # # Unfortunately this doesn't work on Windows (SIGINT kills # Python and CTRL_C_EVENT doesn't work). - if(os.name == 'posix'): + if os.name == "posix": pid = os.getpid() - if(not sigint_timer): - sigint_timer = threading.Timer(.01, os.kill, - args=[pid, signal.SIGINT]) + if not sigint_timer: + sigint_timer = threading.Timer(0.01, os.kill, args=[pid, signal.SIGINT]) sigint_timer.start() else: print("\nKeyboardInterrupt - Ctrl-C again for new prompt") @@ -169,6 +169,7 @@ def inputhook_qt4(): except: # NO exceptions are allowed to escape from a ctypes callback ignore_CTRL_C() from traceback import print_exc + print_exc() print("Got exception from inputhook_qt4, unregistering.") mgr.clear_inputhook() @@ -184,7 +185,7 @@ def preprompthook_qt4(ishell): """ global got_kbdint, sigint_timer - if(sigint_timer): + if sigint_timer: sigint_timer.cancel() sigint_timer = None @@ -193,6 +194,6 @@ def preprompthook_qt4(ishell): got_kbdint = False ip._inputhook_qt4 = inputhook_qt4 - ip.set_hook('pre_prompt_hook', preprompthook_qt4) + ip.set_hook("pre_prompt_hook", preprompthook_qt4) return app, inputhook_qt4 diff --git a/pydev_ipython/inputhookqt5.py b/pydev_ipython/inputhookqt5.py index 4e7c60575..f38383e3a 100644 --- a/pydev_ipython/inputhookqt5.py +++ b/pydev_ipython/inputhookqt5.py @@ -5,16 +5,16 @@ Author: Christian Boos """ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (C) 2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- import os import signal @@ -41,17 +41,18 @@ def set_hook(self, *args, **kwargs): # KeyboardInterrupts to consider since we are running under PyDev pass -#----------------------------------------------------------------------------- + +# ----------------------------------------------------------------------------- # Module Globals -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- got_kbdint = False sigint_timer = None -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- def create_inputhook_qt5(mgr, app=None): @@ -85,11 +86,12 @@ def create_inputhook_qt5(mgr, app=None): app = QtCore.QCoreApplication.instance() if app is None: from PyQt5 import QtWidgets + app = QtWidgets.QApplication([" "]) # Re-use previously created inputhook if any ip = InteractiveShell.instance() - if hasattr(ip, '_inputhook_qt5'): + if hasattr(ip, "_inputhook_qt5"): return app, ip._inputhook_qt5 # Otherwise create the inputhook_qt5/preprompthook_qt5 pair of @@ -158,11 +160,10 @@ def inputhook_qt5(): # # Unfortunately this doesn't work on Windows (SIGINT kills # Python and CTRL_C_EVENT doesn't work). - if(os.name == 'posix'): + if os.name == "posix": pid = os.getpid() - if(not sigint_timer): - sigint_timer = threading.Timer(.01, os.kill, - args=[pid, signal.SIGINT]) + if not sigint_timer: + sigint_timer = threading.Timer(0.01, os.kill, args=[pid, signal.SIGINT]) sigint_timer.start() else: print("\nKeyboardInterrupt - Ctrl-C again for new prompt") @@ -170,6 +171,7 @@ def inputhook_qt5(): except: # NO exceptions are allowed to escape from a ctypes callback ignore_CTRL_C() from traceback import print_exc + print_exc() print("Got exception from inputhook_qt5, unregistering.") mgr.clear_inputhook() @@ -185,7 +187,7 @@ def preprompthook_qt5(ishell): """ global got_kbdint, sigint_timer - if(sigint_timer): + if sigint_timer: sigint_timer.cancel() sigint_timer = None @@ -194,6 +196,6 @@ def preprompthook_qt5(ishell): got_kbdint = False ip._inputhook_qt5 = inputhook_qt5 - ip.set_hook('pre_prompt_hook', preprompthook_qt5) + ip.set_hook("pre_prompt_hook", preprompthook_qt5) return app, inputhook_qt5 diff --git a/pydev_ipython/inputhooktk.py b/pydev_ipython/inputhooktk.py index e245cc05c..b853c1765 100644 --- a/pydev_ipython/inputhooktk.py +++ b/pydev_ipython/inputhooktk.py @@ -2,22 +2,24 @@ # Unlike what IPython does, we need to have an explicit inputhook because tkinter handles # input hook in the C Source code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- from pydev_ipython.inputhook import stdin_ready -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- TCL_DONT_WAIT = 1 << 1 + def create_inputhook_tk(app): def inputhook_tk(): while app.dooneevent(TCL_DONT_WAIT) == 1: if stdin_ready(): break return 0 + return inputhook_tk diff --git a/pydev_ipython/inputhookwx.py b/pydev_ipython/inputhookwx.py index c2e4b91d0..455114b65 100644 --- a/pydev_ipython/inputhookwx.py +++ b/pydev_ipython/inputhookwx.py @@ -5,16 +5,16 @@ Authors: Robin Dunn, Brian Granger, Ondrej Certik """ -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Copyright (C) 2008-2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Imports -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- import sys import signal @@ -25,9 +25,10 @@ from pydev_ipython.inputhook import stdin_ready -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- # Code -#----------------------------------------------------------------------------- +# ----------------------------------------------------------------------------- + def inputhook_wx1(): """Run the wx event loop by processing pending events only. @@ -53,8 +54,8 @@ def inputhook_wx1(): pass return 0 -class EventLoopTimer(wx.Timer): # @UndefinedVariable +class EventLoopTimer(wx.Timer): # @UndefinedVariable def __init__(self, func): self.func = func wx.Timer.__init__(self) # @UndefinedVariable @@ -62,8 +63,8 @@ def __init__(self, func): def Notify(self): self.func() -class EventLoopRunner(object): +class EventLoopRunner(object): def Run(self, time): self.evtloop = wx.EventLoop() # @UndefinedVariable self.timer = EventLoopTimer(self.check_stdin) @@ -75,6 +76,7 @@ def check_stdin(self): self.timer.Stop() self.evtloop.Exit() + def inputhook_wx2(): """Run the wx event loop, polling for stdin. @@ -101,6 +103,7 @@ def inputhook_wx2(): pass return 0 + def inputhook_wx3(): """Run the wx event loop by processing pending events only. @@ -114,7 +117,7 @@ def inputhook_wx3(): try: app = wx.GetApp() # @UndefinedVariable if app is not None: - if hasattr(wx, 'IsMainThread'): + if hasattr(wx, "IsMainThread"): assert wx.IsMainThread() # @UndefinedVariable else: assert wx.Thread_IsMain() # @UndefinedVariable @@ -159,7 +162,8 @@ def inputhook_wx3(): pass return 0 -if sys.platform == 'darwin': + +if sys.platform == "darwin": # On OSX, evtloop.Pending() always returns True, regardless of there being # any events pending. As such we can't use implementations 1 or 3 of the # inputhook as those depend on a pending/dispatch loop. diff --git a/pydev_ipython/matplotlibtools.py b/pydev_ipython/matplotlibtools.py index 71f026443..2fbfb9922 100644 --- a/pydev_ipython/matplotlibtools.py +++ b/pydev_ipython/matplotlibtools.py @@ -1,14 +1,15 @@ - import sys from _pydev_bundle import pydev_log -backends = {'tk': 'TkAgg', - 'gtk': 'GTKAgg', - 'wx': 'WXAgg', - 'qt': 'QtAgg', # Auto-choose qt4/5 - 'qt4': 'Qt4Agg', - 'qt5': 'Qt5Agg', - 'osx': 'MacOSX'} +backends = { + "tk": "TkAgg", + "gtk": "GTKAgg", + "wx": "WXAgg", + "qt": "QtAgg", # Auto-choose qt4/5 + "qt4": "Qt4Agg", + "qt5": "Qt5Agg", + "osx": "MacOSX", +} # We also need a reverse backends2guis mapping that will properly choose which # GUI support to activate based on the desired matplotlib backend. For the @@ -17,21 +18,23 @@ backend2gui = dict(zip(backends.values(), backends.keys())) # In the reverse mapping, there are a few extra valid matplotlib backends that # map to the same GUI support -backend2gui['GTK'] = backend2gui['GTKCairo'] = 'gtk' -backend2gui['WX'] = 'wx' -backend2gui['CocoaAgg'] = 'osx' +backend2gui["GTK"] = backend2gui["GTKCairo"] = "gtk" +backend2gui["WX"] = "wx" +backend2gui["CocoaAgg"] = "osx" def do_enable_gui(guiname): from _pydev_bundle.pydev_versioncheck import versionok_for_gui + if versionok_for_gui(): try: from pydev_ipython.inputhook import enable_gui + enable_gui(guiname) except: sys.stderr.write("Failed to enable GUI event loop integration for '%s'\n" % guiname) pydev_log.exception() - elif guiname not in ['none', '', None]: + elif guiname not in ["none", "", None]: # Only print a warning if the guiname was going to do something sys.stderr.write("Debug console: Python version does not support GUI event loop integration for '%s'\n" % guiname) # Return value does not matter, so return back what was sent @@ -40,9 +43,9 @@ def do_enable_gui(guiname): def find_gui_and_backend(): """Return the gui and mpl backend.""" - matplotlib = sys.modules['matplotlib'] + matplotlib = sys.modules["matplotlib"] # WARNING: this assumes matplotlib 1.1 or newer!! - backend = matplotlib.rcParams['backend'] + backend = matplotlib.rcParams["backend"] # In this case, we need to find what the appropriate gui selection call # should be for IPython, so we can activate inputhook accordingly gui = backend2gui.get(backend, None) @@ -50,9 +53,10 @@ def find_gui_and_backend(): def is_interactive_backend(backend): - """ Check if backend is interactive """ - matplotlib = sys.modules['matplotlib'] + """Check if backend is interactive""" + matplotlib = sys.modules["matplotlib"] from matplotlib.rcsetup import interactive_bk, non_interactive_bk # @UnresolvedImport + if backend in interactive_bk: return True elif backend in non_interactive_bk: @@ -62,8 +66,8 @@ def is_interactive_backend(backend): def patch_use(enable_gui_function): - """ Patch matplotlib function 'use' """ - matplotlib = sys.modules['matplotlib'] + """Patch matplotlib function 'use'""" + matplotlib = sys.modules["matplotlib"] def patched_use(*args, **kwargs): matplotlib.real_use(*args, **kwargs) @@ -75,11 +79,11 @@ def patched_use(*args, **kwargs): def patch_is_interactive(): - """ Patch matplotlib function 'use' """ - matplotlib = sys.modules['matplotlib'] + """Patch matplotlib function 'use'""" + matplotlib = sys.modules["matplotlib"] def patched_is_interactive(): - return matplotlib.rcParams['interactive'] + return matplotlib.rcParams["interactive"] matplotlib.real_is_interactive = matplotlib.is_interactive matplotlib.is_interactive = patched_is_interactive @@ -89,7 +93,7 @@ def activate_matplotlib(enable_gui_function): """Set interactive to True for interactive backends. enable_gui_function - Function which enables gui, should be run in the main thread. """ - matplotlib = sys.modules['matplotlib'] + matplotlib = sys.modules["matplotlib"] gui, backend = find_gui_and_backend() is_interactive = is_interactive_backend(backend) if is_interactive: @@ -119,7 +123,7 @@ def flag_calls(func): func() was attempted and succeeded.""" # don't wrap twice - if hasattr(func, 'called'): + if hasattr(func, "called"): return func def wrapper(*args, **kw): @@ -134,7 +138,7 @@ def wrapper(*args, **kw): def activate_pylab(): - pylab = sys.modules['pylab'] + pylab = sys.modules["pylab"] pylab.show._needmain = False # We need to detect at runtime whether show() is called by the user. # For this, we wrap it into a decorator which adds a 'called' flag. @@ -142,7 +146,7 @@ def activate_pylab(): def activate_pyplot(): - pyplot = sys.modules['matplotlib.pyplot'] + pyplot = sys.modules["matplotlib.pyplot"] pyplot.show._needmain = False # We need to detect at runtime whether show() is called by the user. # For this, we wrap it into a decorator which adds a 'called' flag. diff --git a/pydev_ipython/qt.py b/pydev_ipython/qt.py index 222c81b91..66cd2483f 100644 --- a/pydev_ipython/qt.py +++ b/pydev_ipython/qt.py @@ -8,13 +8,11 @@ import os -from pydev_ipython.qt_loaders import (load_qt, QT_API_PYSIDE, - QT_API_PYQT, QT_API_PYQT5) +from pydev_ipython.qt_loaders import load_qt, QT_API_PYSIDE, QT_API_PYQT, QT_API_PYQT5 -QT_API = os.environ.get('QT_API', None) +QT_API = os.environ.get("QT_API", None) if QT_API not in [QT_API_PYSIDE, QT_API_PYQT, QT_API_PYQT5, None]: - raise RuntimeError("Invalid Qt API %r, valid values are: %r, %r" % - (QT_API, QT_API_PYSIDE, QT_API_PYQT, QT_API_PYQT5)) + raise RuntimeError("Invalid Qt API %r, valid values are: %r, %r" % (QT_API, QT_API_PYSIDE, QT_API_PYQT, QT_API_PYQT5)) if QT_API is None: api_opts = [QT_API_PYSIDE, QT_API_PYQT, QT_API_PYQT5] else: diff --git a/pydev_ipython/qt_for_kernel.py b/pydev_ipython/qt_for_kernel.py index 500d25a74..de26bd3c0 100644 --- a/pydev_ipython/qt_for_kernel.py +++ b/pydev_ipython/qt_for_kernel.py @@ -35,9 +35,7 @@ import sys from pydev_ipython.version import check_version -from pydev_ipython.qt_loaders import (load_qt, QT_API_PYSIDE, QT_API_PYSIDE2, - QT_API_PYQT, QT_API_PYQT_DEFAULT, - loaded_api, QT_API_PYQT5) +from pydev_ipython.qt_loaders import load_qt, QT_API_PYSIDE, QT_API_PYSIDE2, QT_API_PYQT, QT_API_PYQT_DEFAULT, loaded_api, QT_API_PYQT5 # Constraints placed on an imported matplotlib @@ -48,44 +46,41 @@ def matplotlib_options(mpl): # #PyDev-779: In pysrc/pydev_ipython/qt_for_kernel.py, matplotlib_options should be replaced with latest from ipython # (i.e.: properly check backend to decide upon qt4/qt5). - backend = mpl.rcParams.get('backend', None) - if backend == 'Qt4Agg': - mpqt = mpl.rcParams.get('backend.qt4', None) + backend = mpl.rcParams.get("backend", None) + if backend == "Qt4Agg": + mpqt = mpl.rcParams.get("backend.qt4", None) if mpqt is None: return None - if mpqt.lower() == 'pyside': + if mpqt.lower() == "pyside": return [QT_API_PYSIDE] - elif mpqt.lower() == 'pyqt4': + elif mpqt.lower() == "pyqt4": return [QT_API_PYQT_DEFAULT] - elif mpqt.lower() == 'pyqt4v2': + elif mpqt.lower() == "pyqt4v2": return [QT_API_PYQT] - raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" % - mpqt) + raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" % mpqt) - elif backend == 'Qt5Agg': - mpqt = mpl.rcParams.get('backend.qt5', None) + elif backend == "Qt5Agg": + mpqt = mpl.rcParams.get("backend.qt5", None) if mpqt is None: return None - if mpqt.lower() == 'pyqt5': + if mpqt.lower() == "pyqt5": return [QT_API_PYQT5] - raise ImportError("unhandled value for backend.qt5 from matplotlib: %r" % - mpqt) + raise ImportError("unhandled value for backend.qt5 from matplotlib: %r" % mpqt) # Fallback without checking backend (previous code) - mpqt = mpl.rcParams.get('backend.qt4', None) + mpqt = mpl.rcParams.get("backend.qt4", None) if mpqt is None: - mpqt = mpl.rcParams.get('backend.qt5', None) + mpqt = mpl.rcParams.get("backend.qt5", None) if mpqt is None: return None - if mpqt.lower() == 'pyside': + if mpqt.lower() == "pyside": return [QT_API_PYSIDE] - elif mpqt.lower() == 'pyqt4': + elif mpqt.lower() == "pyqt4": return [QT_API_PYQT_DEFAULT] - elif mpqt.lower() == 'pyqt5': + elif mpqt.lower() == "pyqt5": return [QT_API_PYQT5] - raise ImportError("unhandled value for qt backend from matplotlib: %r" % - mpqt) + raise ImportError("unhandled value for qt backend from matplotlib: %r" % mpqt) def get_options(): @@ -97,13 +92,13 @@ def get_options(): if loaded is not None: return [loaded] - mpl = sys.modules.get('matplotlib', None) + mpl = sys.modules.get("matplotlib", None) - if mpl is not None and not check_version(mpl.__version__, '1.0.2'): + if mpl is not None and not check_version(mpl.__version__, "1.0.2"): # 1.0.1 only supports PyQt4 v1 return [QT_API_PYQT_DEFAULT] - if os.environ.get('QT_API', None) is None: + if os.environ.get("QT_API", None) is None: # no ETS variable. Ask mpl, then use either return matplotlib_options(mpl) or [QT_API_PYQT_DEFAULT, QT_API_PYSIDE, QT_API_PYSIDE2, QT_API_PYQT5] diff --git a/pydev_ipython/qt_loaders.py b/pydev_ipython/qt_loaders.py index 7f071e0c2..a0b46f7b5 100644 --- a/pydev_ipython/qt_loaders.py +++ b/pydev_ipython/qt_loaders.py @@ -14,12 +14,12 @@ from pydev_ipython.version import check_version # Available APIs. -QT_API_PYQT = 'pyqt' -QT_API_PYQTv1 = 'pyqtv1' -QT_API_PYQT_DEFAULT = 'pyqtdefault' # don't set SIP explicitly -QT_API_PYSIDE = 'pyside' -QT_API_PYSIDE2 = 'pyside2' -QT_API_PYQT5 = 'pyqt5' +QT_API_PYQT = "pyqt" +QT_API_PYQTv1 = "pyqtv1" +QT_API_PYQT_DEFAULT = "pyqtdefault" # don't set SIP explicitly +QT_API_PYSIDE = "pyside" +QT_API_PYSIDE2 = "pyside2" +QT_API_PYQT5 = "pyqt5" class ImportDenier(object): @@ -41,10 +41,13 @@ def find_module(self, fullname, path=None): return self def load_module(self, fullname): - raise ImportError(""" + raise ImportError( + """ Importing %s disabled by IPython, which has already imported an Incompatible QT Binding: %s - """ % (fullname, loaded_api())) + """ + % (fullname, loaded_api()) + ) ID = ImportDenier() @@ -53,14 +56,14 @@ def load_module(self, fullname): def commit_api(api): """Commit to a particular API, and trigger ImportErrors on subsequent - dangerous imports""" + dangerous imports""" if api == QT_API_PYSIDE: - ID.forbid('PyQt4') - ID.forbid('PyQt5') + ID.forbid("PyQt4") + ID.forbid("PyQt5") else: - ID.forbid('PySide') - ID.forbid('PySide2') + ID.forbid("PySide") + ID.forbid("PySide2") def loaded_api(): @@ -73,58 +76,60 @@ def loaded_api(): ------- None, 'pyside', 'pyside2', 'pyqt', or 'pyqtv1' """ - if 'PyQt4.QtCore' in sys.modules: + if "PyQt4.QtCore" in sys.modules: if qtapi_version() == 2: return QT_API_PYQT else: return QT_API_PYQTv1 - elif 'PySide.QtCore' in sys.modules: + elif "PySide.QtCore" in sys.modules: return QT_API_PYSIDE - elif 'PySide2.QtCore' in sys.modules: + elif "PySide2.QtCore" in sys.modules: return QT_API_PYSIDE2 - elif 'PyQt5.QtCore' in sys.modules: + elif "PyQt5.QtCore" in sys.modules: return QT_API_PYQT5 return None def has_binding(api): """Safely check for PyQt4 or PySide, without importing - submodules + submodules - Parameters - ---------- - api : str [ 'pyqtv1' | 'pyqt' | 'pyside' | 'pyqtdefault'] - Which module to check for + Parameters + ---------- + api : str [ 'pyqtv1' | 'pyqt' | 'pyside' | 'pyqtdefault'] + Which module to check for - Returns - ------- - True if the relevant module appears to be importable + Returns + ------- + True if the relevant module appears to be importable """ # we can't import an incomplete pyside and pyqt4 # this will cause a crash in sip (#1431) # check for complete presence before importing - module_name = {QT_API_PYSIDE: 'PySide', - QT_API_PYSIDE2: 'PySide2', - QT_API_PYQT: 'PyQt4', - QT_API_PYQTv1: 'PyQt4', - QT_API_PYQT_DEFAULT: 'PyQt4', - QT_API_PYQT5: 'PyQt5', - } + module_name = { + QT_API_PYSIDE: "PySide", + QT_API_PYSIDE2: "PySide2", + QT_API_PYQT: "PyQt4", + QT_API_PYQTv1: "PyQt4", + QT_API_PYQT_DEFAULT: "PyQt4", + QT_API_PYQT5: "PyQt5", + } module_name = module_name[api] import importlib + try: # importing top level PyQt4/PySide module is ok... mod = __import__(module_name) # ...importing submodules is not - for check in ('QtCore', 'QtGui', 'QtSvg'): - if importlib.util.find_spec('%s.%s' % (module_name, check)) is None: + for check in ("QtCore", "QtGui", "QtSvg"): + if importlib.util.find_spec("%s.%s" % (module_name, check)) is None: return False # we can also safely check PySide version if api == QT_API_PYSIDE: - return check_version(mod.__version__, '1.0.3') + return check_version(mod.__version__, "1.0.3") else: return True except ImportError: @@ -143,7 +148,7 @@ def qtapi_version(): except ImportError: return try: - return sip.getapi('QString') + return sip.getapi("QString") except ValueError: return @@ -178,21 +183,20 @@ def import_pyqt4(version=2): import sip if version is not None: - sip.setapi('QString', version) - sip.setapi('QVariant', version) + sip.setapi("QString", version) + sip.setapi("QVariant", version) from PyQt4 import QtGui, QtCore, QtSvg - if not check_version(QtCore.PYQT_VERSION_STR, '4.7'): - raise ImportError("IPython requires PyQt4 >= 4.7, found %s" % - QtCore.PYQT_VERSION_STR) + if not check_version(QtCore.PYQT_VERSION_STR, "4.7"): + raise ImportError("IPython requires PyQt4 >= 4.7, found %s" % QtCore.PYQT_VERSION_STR) # Alias PyQt-specific functions for PySide compatibility. QtCore.Signal = QtCore.pyqtSignal QtCore.Slot = QtCore.pyqtSlot # query for the API version (in case version == None) - version = sip.getapi('QString') + version = sip.getapi("QString") api = QT_API_PYQTv1 if version == 1 else QT_API_PYQT return QtCore, QtGui, QtSvg, api @@ -219,6 +223,7 @@ def import_pyside(): ImportErrors raised within this function are non-recoverable """ from PySide import QtGui, QtCore, QtSvg # @UnresolvedImport + return QtCore, QtGui, QtSvg, QT_API_PYSIDE @@ -229,6 +234,7 @@ def import_pyside2(): ImportErrors raised within this function are non-recoverable """ from PySide2 import QtGui, QtCore, QtSvg # @UnresolvedImport + return QtCore, QtGui, QtSvg, QT_API_PYSIDE @@ -258,21 +264,21 @@ def load_qt(api_options): bindings (either becaues they aren't installed, or because an incompatible library has already been installed) """ - loaders = {QT_API_PYSIDE: import_pyside, - QT_API_PYSIDE2: import_pyside2, - QT_API_PYQT: import_pyqt4, - QT_API_PYQTv1: partial(import_pyqt4, version=1), - QT_API_PYQT_DEFAULT: partial(import_pyqt4, version=None), - QT_API_PYQT5: import_pyqt5, - } + loaders = { + QT_API_PYSIDE: import_pyside, + QT_API_PYSIDE2: import_pyside2, + QT_API_PYQT: import_pyqt4, + QT_API_PYQTv1: partial(import_pyqt4, version=1), + QT_API_PYQT_DEFAULT: partial(import_pyqt4, version=None), + QT_API_PYQT5: import_pyqt5, + } for api in api_options: - if api not in loaders: raise RuntimeError( - "Invalid Qt API %r, valid values are: %r, %r, %r, %r, %r, %r" % - (api, QT_API_PYSIDE, QT_API_PYSIDE, QT_API_PYQT, - QT_API_PYQTv1, QT_API_PYQT_DEFAULT, QT_API_PYQT5)) + "Invalid Qt API %r, valid values are: %r, %r, %r, %r, %r, %r" + % (api, QT_API_PYSIDE, QT_API_PYSIDE, QT_API_PYQT, QT_API_PYQTv1, QT_API_PYQT_DEFAULT, QT_API_PYQT5) + ) if not can_import(api): continue @@ -283,7 +289,8 @@ def load_qt(api_options): commit_api(api) return result else: - raise ImportError(""" + raise ImportError( + """ Could not load requested Qt binding. Please ensure that PyQt4 >= 4.7 or PySide >= 1.0.3 is available, and only one is imported per session. @@ -294,9 +301,13 @@ def load_qt(api_options): PySide >= 1.0.3 installed: %s PySide2 installed: %s Tried to load: %r - """ % (loaded_api(), - has_binding(QT_API_PYQT), - has_binding(QT_API_PYQT5), - has_binding(QT_API_PYSIDE), - has_binding(QT_API_PYSIDE2), - api_options)) + """ + % ( + loaded_api(), + has_binding(QT_API_PYQT), + has_binding(QT_API_PYQT5), + has_binding(QT_API_PYSIDE), + has_binding(QT_API_PYSIDE2), + api_options, + ) + ) diff --git a/pydev_ipython/version.py b/pydev_ipython/version.py index 920accd02..e47463645 100644 --- a/pydev_ipython/version.py +++ b/pydev_ipython/version.py @@ -4,9 +4,8 @@ class _Version: - def __init__(self, s): - parts = s.split('.') + parts = s.split(".") version_parts = [] for p in parts: try: @@ -39,13 +38,13 @@ def check_version(found_version, expected_min_or_eq_to_version): return True -if __name__ == '__main__': - assert check_version('1.2.3', '1.2.3') - assert check_version('1.2.4', '1.2.3') - assert check_version('1.2', '1.2.bar') - assert check_version('1.3', '1.2.bar') - assert check_version('1.3', '1.2b') - assert not check_version('1.2', '1.3') - assert not check_version('1.2.0', '1.2.1') - assert not check_version('1.2', '1.2.1') - print('Ok, checks passed') +if __name__ == "__main__": + assert check_version("1.2.3", "1.2.3") + assert check_version("1.2.4", "1.2.3") + assert check_version("1.2", "1.2.bar") + assert check_version("1.3", "1.2.bar") + assert check_version("1.3", "1.2b") + assert not check_version("1.2", "1.3") + assert not check_version("1.2.0", "1.2.1") + assert not check_version("1.2", "1.2.1") + print("Ok, checks passed") diff --git a/pydev_pysrc.py b/pydev_pysrc.py index b9ed49e80..f02d9fd8f 100644 --- a/pydev_pysrc.py +++ b/pydev_pysrc.py @@ -1 +1 @@ -'''An empty file in pysrc that can be imported (from sitecustomize) to find the location of pysrc''' \ No newline at end of file +"""An empty file in pysrc that can be imported (from sitecustomize) to find the location of pysrc""" diff --git a/pydev_run_in_console.py b/pydev_run_in_console.py index a87a0e4b3..bffc88c9d 100644 --- a/pydev_run_in_console.py +++ b/pydev_run_in_console.py @@ -1,6 +1,6 @@ -''' +""" Entry point module to run a file in the interactive console. -''' +""" import os import sys import traceback @@ -17,7 +17,7 @@ def run_file(file, globals=None, locals=None, is_module=False): module_name = None entry_point_fn = None if is_module: - file, _, entry_point_fn = file.partition(':') + file, _, entry_point_fn = file.partition(":") module_name = file filename = get_fullname(file) if filename is None: @@ -27,16 +27,16 @@ def run_file(file, globals=None, locals=None, is_module=False): file = filename if os.path.isdir(file): - new_target = os.path.join(file, '__main__.py') + new_target = os.path.join(file, "__main__.py") if os.path.isfile(new_target): file = new_target if globals is None: - m = save_main_module(file, 'pydev_run_in_console') + m = save_main_module(file, "pydev_run_in_console") globals = m.__dict__ try: - globals['__builtins__'] = __builtins__ + globals["__builtins__"] = __builtins__ except NameError: pass # Not there on Jython... @@ -46,7 +46,7 @@ def run_file(file, globals=None, locals=None, is_module=False): if not is_module: sys.path.insert(0, os.path.split(file)[0]) - print('Running %s' % file) + print("Running %s" % file) try: if not is_module: pydev_imports.execfile(file, globals, locals) # execute the script @@ -61,6 +61,7 @@ def run_file(file, globals=None, locals=None, is_module=False): else: # Run with the -m switch from _pydevd_bundle import pydevd_runpy + pydevd_runpy._run_module_as_main(module_name) except: traceback.print_exc() @@ -69,7 +70,7 @@ def run_file(file, globals=None, locals=None, is_module=False): def skip_successful_exit(*args): - """ System exit in file shouldn't kill interpreter (i.e. in `timeit`)""" + """System exit in file shouldn't kill interpreter (i.e. in `timeit`)""" if len(args) == 1 and args[0] in (0, None): pass else: @@ -77,38 +78,38 @@ def skip_successful_exit(*args): def process_args(argv): - setup_args = {'file': '', 'module': False} + setup_args = {"file": "", "module": False} - setup_args['port'] = argv[1] + setup_args["port"] = argv[1] del argv[1] - setup_args['client_port'] = argv[1] + setup_args["client_port"] = argv[1] del argv[1] module_flag = "--module" if module_flag in argv: i = argv.index(module_flag) if i != -1: - setup_args['module'] = True - setup_args['file'] = argv[i + 1] + setup_args["module"] = True + setup_args["file"] = argv[i + 1] del sys.argv[i] else: - setup_args['file'] = argv[1] + setup_args["file"] = argv[1] del argv[0] return setup_args -#======================================================================================================================= +# ======================================================================================================================= # main -#======================================================================================================================= -if __name__ == '__main__': +# ======================================================================================================================= +if __name__ == "__main__": setup = process_args(sys.argv) - port = setup['port'] - client_port = setup['client_port'] - file = setup['file'] - is_module = setup['module'] + port = setup["port"] + client_port = setup["client_port"] + file = setup["file"] + is_module = setup["module"] from _pydev_bundle import pydev_localhost @@ -125,9 +126,7 @@ def process_args(argv): connect_status_queue = _queue.Queue() interpreter = InterpreterInterface(host, int(client_port), threading.current_thread(), connect_status_queue=connect_status_queue) - server_thread = threading.Thread(target=start_console_server, - name='ServerThread', - args=(host, int(port), interpreter)) + server_thread = threading.Thread(target=start_console_server, name="ServerThread", args=(host, int(port), interpreter)) server_thread.daemon = True server_thread.start() diff --git a/pydev_sitecustomize/sitecustomize.py b/pydev_sitecustomize/sitecustomize.py index 8b51eba78..f683ae50e 100644 --- a/pydev_sitecustomize/sitecustomize.py +++ b/pydev_sitecustomize/sitecustomize.py @@ -1,4 +1,4 @@ -''' +""" This module will: - change the input() and raw_input() commands to change \r\n or \r into \n - execute the user site customize -- if available @@ -7,10 +7,11 @@ Up to PyDev 3.4 it also was setting the default encoding, but it was removed because of differences when running from a shell (i.e.: now we just set the PYTHONIOENCODING related to that -- which is properly treated on Py 2.7 onwards). -''' -DEBUG = 0 #0 or 1 because of jython +""" +DEBUG = 0 # 0 or 1 because of jython import sys + encoding = None IS_PYTHON_3_ONWARDS = 0 @@ -18,15 +19,17 @@ try: IS_PYTHON_3_ONWARDS = sys.version_info[0] >= 3 except: - #That's OK, not all versions of python have sys.version_info + # That's OK, not all versions of python have sys.version_info if DEBUG: - import traceback;traceback.print_exc() #@Reimport + import traceback + + traceback.print_exc() # @Reimport -#----------------------------------------------------------------------------------------------------------------------- -#Line buffering +# ----------------------------------------------------------------------------------------------------------------------- +# Line buffering if IS_PYTHON_3_ONWARDS: - #Python 3 has a bug (http://bugs.python.org/issue4705) in which -u doesn't properly make output/input unbuffered - #so, we need to enable that ourselves here. + # Python 3 has a bug (http://bugs.python.org/issue4705) in which -u doesn't properly make output/input unbuffered + # so, we need to enable that ourselves here. try: sys.stdout._line_buffering = True except: @@ -42,50 +45,55 @@ try: - import org.python.core.PyDictionary #@UnresolvedImport @UnusedImport -- just to check if it could be valid + import org.python.core.PyDictionary # @UnresolvedImport @UnusedImport -- just to check if it could be valid + def dict_contains(d, key): return d.has_key(key) except: try: - #Py3k does not have has_key anymore, and older versions don't have __contains__ + # Py3k does not have has_key anymore, and older versions don't have __contains__ dict_contains = dict.__contains__ except: try: dict_contains = dict.has_key except NameError: + def dict_contains(d, key): return d.has_key(key) + def install_breakpointhook(): def custom_sitecustomize_breakpointhook(*args, **kwargs): import os - hookname = os.getenv('PYTHONBREAKPOINT') + + hookname = os.getenv("PYTHONBREAKPOINT") if ( - hookname is not None - and len(hookname) > 0 - and hasattr(sys, '__breakpointhook__') - and sys.__breakpointhook__ != custom_sitecustomize_breakpointhook - ): + hookname is not None + and len(hookname) > 0 + and hasattr(sys, "__breakpointhook__") + and sys.__breakpointhook__ != custom_sitecustomize_breakpointhook + ): sys.__breakpointhook__(*args, **kwargs) else: sys.path.append(os.path.dirname(os.path.dirname(__file__))) import pydevd - kwargs.setdefault('stop_at_frame', sys._getframe().f_back) + + kwargs.setdefault("stop_at_frame", sys._getframe().f_back) pydevd.settrace(*args, **kwargs) if sys.version_info[0:2] >= (3, 7): - # There are some choices on how to provide the breakpoint hook. Namely, we can provide a + # There are some choices on how to provide the breakpoint hook. Namely, we can provide a # PYTHONBREAKPOINT which provides the import path for a method to be executed or we # can override sys.breakpointhook. # pydevd overrides sys.breakpointhook instead of providing an environment variable because - # it's possible that the debugger starts the user program but is not available in the + # it's possible that the debugger starts the user program but is not available in the # PYTHONPATH (and would thus fail to be imported if PYTHONBREAKPOINT was set to pydevd.settrace). # Note that the implementation still takes PYTHONBREAKPOINT in account (so, if it was provided # by someone else, it'd still work). sys.breakpointhook = custom_sitecustomize_breakpointhook else: if sys.version_info[0] >= 3: - import builtins as __builtin__ # Py3 + import builtins as __builtin__ # Py3 else: import __builtin__ @@ -94,144 +102,166 @@ def custom_sitecustomize_breakpointhook(*args, **kwargs): __builtin__.breakpoint = custom_sitecustomize_breakpointhook sys.__breakpointhook__ = custom_sitecustomize_breakpointhook + # Install the breakpoint hook at import time. install_breakpointhook() -#----------------------------------------------------------------------------------------------------------------------- -#now that we've finished the needed pydev sitecustomize, let's run the default one (if available) +# ----------------------------------------------------------------------------------------------------------------------- +# now that we've finished the needed pydev sitecustomize, let's run the default one (if available) -#Ok, some weirdness going on in Python 3k: when removing this module from the sys.module to import the 'real' -#sitecustomize, all the variables in this scope become None (as if it was garbage-collected), so, the the reference -#below is now being kept to create a cyclic reference so that it neven dies) -__pydev_sitecustomize_module__ = sys.modules.get('sitecustomize') #A ref to this module +# Ok, some weirdness going on in Python 3k: when removing this module from the sys.module to import the 'real' +# sitecustomize, all the variables in this scope become None (as if it was garbage-collected), so, the the reference +# below is now being kept to create a cyclic reference so that it neven dies) +__pydev_sitecustomize_module__ = sys.modules.get("sitecustomize") # A ref to this module -#remove the pydev site customize (and the pythonpath for it) +# remove the pydev site customize (and the pythonpath for it) paths_removed = [] try: for c in sys.path[:]: - #Pydev controls the whole classpath in Jython already, so, we don't want a a duplicate for - #what we've already added there (this is needed to support Jython 2.5b1 onwards -- otherwise, as - #we added the sitecustomize to the pythonpath and to the classpath, we'd have to remove it from the - #classpath too -- and I don't think there's a way to do that... or not?) - if c.find('pydev_sitecustomize') != -1 or c == '__classpath__' or c == '__pyclasspath__' or \ - c == '__classpath__/' or c == '__pyclasspath__/' or c == '__classpath__\\' or c == '__pyclasspath__\\': + # Pydev controls the whole classpath in Jython already, so, we don't want a a duplicate for + # what we've already added there (this is needed to support Jython 2.5b1 onwards -- otherwise, as + # we added the sitecustomize to the pythonpath and to the classpath, we'd have to remove it from the + # classpath too -- and I don't think there's a way to do that... or not?) + if ( + c.find("pydev_sitecustomize") != -1 + or c == "__classpath__" + or c == "__pyclasspath__" + or c == "__classpath__/" + or c == "__pyclasspath__/" + or c == "__classpath__\\" + or c == "__pyclasspath__\\" + ): sys.path.remove(c) - if c.find('pydev_sitecustomize') == -1: - #We'll re-add any paths removed but the pydev_sitecustomize we added from pydev. + if c.find("pydev_sitecustomize") == -1: + # We'll re-add any paths removed but the pydev_sitecustomize we added from pydev. paths_removed.append(c) - if dict_contains(sys.modules, 'sitecustomize'): - del sys.modules['sitecustomize'] #this module + if dict_contains(sys.modules, "sitecustomize"): + del sys.modules["sitecustomize"] # this module except: - #print the error... should never happen (so, always show, and not only on debug)! - import traceback;traceback.print_exc() #@Reimport + # print the error... should never happen (so, always show, and not only on debug)! + import traceback + + traceback.print_exc() # @Reimport else: - #Now, execute the default sitecustomize + # Now, execute the default sitecustomize try: - import sitecustomize #@UnusedImport + import sitecustomize # @UnusedImport + sitecustomize.__pydev_sitecustomize_module__ = __pydev_sitecustomize_module__ except: pass - if not dict_contains(sys.modules, 'sitecustomize'): - #If there was no sitecustomize, re-add the pydev sitecustomize (pypy gives a KeyError if it's not there) - sys.modules['sitecustomize'] = __pydev_sitecustomize_module__ + if not dict_contains(sys.modules, "sitecustomize"): + # If there was no sitecustomize, re-add the pydev sitecustomize (pypy gives a KeyError if it's not there) + sys.modules["sitecustomize"] = __pydev_sitecustomize_module__ try: if paths_removed: if sys is None: import sys if sys is not None: - #And after executing the default sitecustomize, restore the paths (if we didn't remove it before, - #the import sitecustomize would recurse). + # And after executing the default sitecustomize, restore the paths (if we didn't remove it before, + # the import sitecustomize would recurse). sys.path.extend(paths_removed) except: - #print the error... should never happen (so, always show, and not only on debug)! - import traceback;traceback.print_exc() #@Reimport - + # print the error... should never happen (so, always show, and not only on debug)! + import traceback + traceback.print_exc() # @Reimport if sys.version_info[0] < 3: try: - #Redefine input and raw_input only after the original sitecustomize was executed - #(because otherwise, the original raw_input and input would still not be defined) + # Redefine input and raw_input only after the original sitecustomize was executed + # (because otherwise, the original raw_input and input would still not be defined) import __builtin__ + original_raw_input = __builtin__.raw_input original_input = __builtin__.input - - def raw_input(prompt=''): - #the original raw_input would only remove a trailing \n, so, at - #this point if we had a \r\n the \r would remain (which is valid for eclipse) - #so, let's remove the remaining \r which python didn't expect. + def raw_input(prompt=""): + # the original raw_input would only remove a trailing \n, so, at + # this point if we had a \r\n the \r would remain (which is valid for eclipse) + # so, let's remove the remaining \r which python didn't expect. ret = original_raw_input(prompt) - if ret.endswith('\r'): + if ret.endswith("\r"): return ret[:-1] return ret + raw_input.__doc__ = original_raw_input.__doc__ - def input(prompt=''): - #input must also be rebinded for using the new raw_input defined + def input(prompt=""): + # input must also be rebinded for using the new raw_input defined return eval(raw_input(prompt)) - input.__doc__ = original_input.__doc__ + input.__doc__ = original_input.__doc__ __builtin__.raw_input = raw_input __builtin__.input = input except: - #Don't report errors at this stage + # Don't report errors at this stage if DEBUG: - import traceback;traceback.print_exc() #@Reimport + import traceback + + traceback.print_exc() # @Reimport else: try: - import builtins #Python 3.0 does not have the __builtin__ module @UnresolvedImport + import builtins # Python 3.0 does not have the __builtin__ module @UnresolvedImport + original_input = builtins.input - def input(prompt=''): - #the original input would only remove a trailing \n, so, at - #this point if we had a \r\n the \r would remain (which is valid for eclipse) - #so, let's remove the remaining \r which python didn't expect. + + def input(prompt=""): + # the original input would only remove a trailing \n, so, at + # this point if we had a \r\n the \r would remain (which is valid for eclipse) + # so, let's remove the remaining \r which python didn't expect. ret = original_input(prompt) - if ret.endswith('\r'): + if ret.endswith("\r"): return ret[:-1] return ret + input.__doc__ = original_input.__doc__ builtins.input = input except: - #Don't report errors at this stage + # Don't report errors at this stage if DEBUG: - import traceback;traceback.print_exc() #@Reimport + import traceback + traceback.print_exc() # @Reimport try: - #The original getpass doesn't work from the eclipse console, so, let's put a replacement - #here (note that it'll not go into echo mode in the console, so, what' the user writes - #will actually be seen) - #Note: same thing from the fix_getpass module -- but we don't want to import it in this - #custom sitecustomize. + # The original getpass doesn't work from the eclipse console, so, let's put a replacement + # here (note that it'll not go into echo mode in the console, so, what' the user writes + # will actually be seen) + # Note: same thing from the fix_getpass module -- but we don't want to import it in this + # custom sitecustomize. def fix_get_pass(): try: import getpass except ImportError: - return #If we can't import it, we can't fix it + return # If we can't import it, we can't fix it import warnings - fallback = getattr(getpass, 'fallback_getpass', None) # >= 2.6 + + fallback = getattr(getpass, "fallback_getpass", None) # >= 2.6 if not fallback: - fallback = getpass.default_getpass # <= 2.5 + fallback = getpass.default_getpass # <= 2.5 getpass.getpass = fallback - if hasattr(getpass, 'GetPassWarning'): + if hasattr(getpass, "GetPassWarning"): warnings.simplefilter("ignore", category=getpass.GetPassWarning) + fix_get_pass() except: - #Don't report errors at this stage + # Don't report errors at this stage if DEBUG: - import traceback;traceback.print_exc() #@Reimport + import traceback + + traceback.print_exc() # @Reimport diff --git a/pydevconsole.py b/pydevconsole.py index 6b1378887..342ca1527 100644 --- a/pydevconsole.py +++ b/pydevconsole.py @@ -1,8 +1,9 @@ -''' +""" Entry point module to start the interactive console. -''' +""" from _pydev_bundle._pydev_saved_modules import thread, _code from _pydevd_bundle.pydevd_constants import IS_JYTHON + start_new_thread = thread.start_new_thread from _pydevd_bundle.pydevconsole_code import InteractiveConsole @@ -30,7 +31,6 @@ class Command: - def __init__(self, interpreter, code_fragment): """ :type code_fragment: CodeFragment @@ -42,12 +42,12 @@ def __init__(self, interpreter, code_fragment): def symbol_for_fragment(code_fragment): if code_fragment.is_single_line: - symbol = 'single' + symbol = "single" else: if IS_JYTHON: - symbol = 'single' # Jython doesn't support exec + symbol = "single" # Jython doesn't support exec else: - symbol = 'exec' + symbol = "exec" return symbol symbol_for_fragment = staticmethod(symbol_for_fragment) @@ -56,7 +56,7 @@ def run(self): text = self.code_fragment.text symbol = self.symbol_for_fragment(self.code_fragment) - self.more = self.interpreter.runsource(text, '', symbol) + self.more = self.interpreter.runsource(text, "", symbol) try: @@ -68,19 +68,20 @@ def run(self): # Pull in runfile, the interface to UMD that wraps execfile from _pydev_bundle.pydev_umd import runfile, _set_globals_function + if sys.version_info[0] >= 3: __builtin__.runfile = runfile else: __builtin__.runfile = runfile -#======================================================================================================================= +# ======================================================================================================================= # InterpreterInterface -#======================================================================================================================= +# ======================================================================================================================= class InterpreterInterface(BaseInterpreterInterface): - ''' - The methods in this class should be registered in the xml-rpc server. - ''' + """ + The methods in this class should be registered in the xml-rpc server. + """ def __init__(self, host, client_port, mainThread, connect_status_queue=None): BaseInterpreterInterface.__init__(self, mainThread, connect_status_queue) @@ -112,7 +113,7 @@ def close(self): sys.exit(0) def get_greeting_msg(self): - return 'PyDev console: starting.\n' + return "PyDev console: starting.\n" class _ProcessExecQueueHelper: @@ -136,8 +137,8 @@ def init_set_return_control_back(interpreter): from pydev_ipython.inputhook import set_return_control_callback def return_control(): - ''' A function that the inputhooks can call (via inputhook.stdin_ready()) to find - out if they should cede control and return ''' + """A function that the inputhooks can call (via inputhook.stdin_ready()) to find + out if they should cede control and return""" if _ProcessExecQueueHelper._debug_hook: # Some of the input hooks check return control without doing # a single operation, so we don't return True on every @@ -164,13 +165,13 @@ def init_mpl_in_console(interpreter): activate_mpl_if_already_imported(interpreter) from _pydev_bundle.pydev_import_hook import import_hook_manager + for mod in list(interpreter.mpl_modules_for_patching): import_hook_manager.add_module_name(mod, interpreter.mpl_modules_for_patching.pop(mod)) -if sys.platform != 'win32': - - if not hasattr(os, 'kill'): # Jython may not have it. +if sys.platform != "win32": + if not hasattr(os, "kill"): # Jython may not have it. def pid_exists(pid): return True @@ -183,6 +184,7 @@ def pid_exists(pid): # no longer running, so, we need to be 100% sure it actually exited). import errno + if pid == 0: # According to "man 2 kill" PID 0 has a special meaning: # it refers to < 1 - expression = str(expression.replace('@LINE@', '\n')) + is_multiline = expression.count("@LINE@") > 1 + expression = str(expression.replace("@LINE@", "\n")) # Not using frame.f_globals because of https://sourceforge.net/tracker2/?func=detail&aid=2541355&group_id=85796&atid=577329 # (Names not resolved in generator expression in method) @@ -581,16 +588,17 @@ def console_exec(thread_id, frame_id, expression, dbg): return False -#======================================================================================================================= +# ======================================================================================================================= # main -#======================================================================================================================= -if __name__ == '__main__': +# ======================================================================================================================= +if __name__ == "__main__": # Important: don't use this module directly as the __main__ module, rather, import itself as pydevconsole # so that we don't get multiple pydevconsole modules if it's executed directly (otherwise we'd have multiple # representations of its classes). # See: https://sw-brainwy.rhcloud.com/tracker/PyDev/446: # 'Variables' and 'Expressions' views stopped working when debugging interactive console import pydevconsole + sys.stdin = pydevconsole.BaseStdIn(sys.stdin) port, client_port = sys.argv[1:3] from _pydev_bundle import pydev_localhost diff --git a/pydevd.py b/pydevd.py index e3b1e8a63..532eb88e8 100644 --- a/pydevd.py +++ b/pydevd.py @@ -1,11 +1,14 @@ -''' +""" Entry point module (keep at root): This module starts the debugger. -''' +""" import sys # @NoMove + if sys.version_info[:2] < (3, 6): - raise RuntimeError('The PyDev.Debugger requires Python 3.6 onwards to be run. If you need to use an older Python version, use an older version of the debugger.') + raise RuntimeError( + "The PyDev.Debugger requires Python 3.6 onwards to be run. If you need to use an older Python version, use an older version of the debugger." + ) import os try: @@ -50,17 +53,49 @@ from _pydev_bundle.pydev_console_utils import DebugConsoleStdIn from _pydevd_bundle.pydevd_additional_thread_info import set_additional_thread_info, remove_additional_info from _pydevd_bundle.pydevd_breakpoints import ExceptionBreakpoint, get_exception_breakpoint -from _pydevd_bundle.pydevd_comm_constants import (CMD_THREAD_SUSPEND, CMD_STEP_INTO, CMD_SET_BREAK, - CMD_STEP_INTO_MY_CODE, CMD_STEP_OVER, CMD_SMART_STEP_INTO, CMD_RUN_TO_LINE, - CMD_SET_NEXT_STATEMENT, CMD_STEP_RETURN, CMD_ADD_EXCEPTION_BREAK, CMD_STEP_RETURN_MY_CODE, - CMD_STEP_OVER_MY_CODE, constant_to_str, CMD_STEP_INTO_COROUTINE) -from _pydevd_bundle.pydevd_constants import (get_thread_id, get_current_thread_id, - DebugInfoHolder, PYTHON_SUSPEND, STATE_SUSPEND, STATE_RUN, get_frame, - clear_cached_thread_id, INTERACTIVE_MODE_AVAILABLE, SHOW_DEBUG_INFO_ENV, NULL, - NO_FTRACE, IS_IRONPYTHON, JSON_PROTOCOL, IS_CPYTHON, HTTP_JSON_PROTOCOL, USE_CUSTOM_SYS_CURRENT_FRAMES_MAP, call_only_once, - ForkSafeLock, IGNORE_BASENAMES_STARTING_WITH, EXCEPTION_TYPE_UNHANDLED, SUPPORT_GEVENT, - PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING, PYDEVD_IPYTHON_CONTEXT, - PYDEVD_USE_SYS_MONITORING) +from _pydevd_bundle.pydevd_comm_constants import ( + CMD_THREAD_SUSPEND, + CMD_STEP_INTO, + CMD_SET_BREAK, + CMD_STEP_INTO_MY_CODE, + CMD_STEP_OVER, + CMD_SMART_STEP_INTO, + CMD_RUN_TO_LINE, + CMD_SET_NEXT_STATEMENT, + CMD_STEP_RETURN, + CMD_ADD_EXCEPTION_BREAK, + CMD_STEP_RETURN_MY_CODE, + CMD_STEP_OVER_MY_CODE, + constant_to_str, + CMD_STEP_INTO_COROUTINE, +) +from _pydevd_bundle.pydevd_constants import ( + get_thread_id, + get_current_thread_id, + DebugInfoHolder, + PYTHON_SUSPEND, + STATE_SUSPEND, + STATE_RUN, + get_frame, + clear_cached_thread_id, + INTERACTIVE_MODE_AVAILABLE, + SHOW_DEBUG_INFO_ENV, + NULL, + NO_FTRACE, + IS_IRONPYTHON, + JSON_PROTOCOL, + IS_CPYTHON, + HTTP_JSON_PROTOCOL, + USE_CUSTOM_SYS_CURRENT_FRAMES_MAP, + call_only_once, + ForkSafeLock, + IGNORE_BASENAMES_STARTING_WITH, + EXCEPTION_TYPE_UNHANDLED, + SUPPORT_GEVENT, + PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING, + PYDEVD_IPYTHON_CONTEXT, + PYDEVD_USE_SYS_MONITORING, +) from _pydevd_bundle.pydevd_defaults import PydevdCustomization # Note: import alias used on pydev_monkey. from _pydevd_bundle.pydevd_custom_frames import CustomFramesContainer, custom_frames_container_init from _pydevd_bundle.pydevd_dont_trace_files import DONT_TRACE, PYDEV_FILE, LIB_FILE, DONT_TRACE_DIRS @@ -68,26 +103,46 @@ from _pydevd_bundle.pydevd_frame_utils import add_exception_to_frame, remove_exception_from_frame from _pydevd_bundle.pydevd_net_command_factory_xml import NetCommandFactory from _pydevd_bundle.pydevd_trace_dispatch import ( - trace_dispatch as _trace_dispatch, global_cache_skips, global_cache_frame_skips, fix_top_level_trace_and_get_trace_func, USING_CYTHON) -from _pydevd_bundle.pydevd_utils import save_main_module, is_current_thread_main_thread, \ - import_attr_from_module -from _pydevd_frame_eval.pydevd_frame_eval_main import ( - frame_eval_func, dummy_trace_dispatch, USING_FRAME_EVAL) + trace_dispatch as _trace_dispatch, + global_cache_skips, + global_cache_frame_skips, + fix_top_level_trace_and_get_trace_func, + USING_CYTHON, +) +from _pydevd_bundle.pydevd_utils import save_main_module, is_current_thread_main_thread, import_attr_from_module +from _pydevd_frame_eval.pydevd_frame_eval_main import frame_eval_func, dummy_trace_dispatch, USING_FRAME_EVAL import pydev_ipython # @UnusedImport from _pydevd_bundle.pydevd_source_mapping import SourceMapping -from _pydevd_bundle.pydevd_concurrency_analyser.pydevd_concurrency_logger import ThreadingLogger, AsyncioLogger, send_concurrency_message, cur_time +from _pydevd_bundle.pydevd_concurrency_analyser.pydevd_concurrency_logger import ( + ThreadingLogger, + AsyncioLogger, + send_concurrency_message, + cur_time, +) from _pydevd_bundle.pydevd_concurrency_analyser.pydevd_thread_wrappers import wrap_threads -from pydevd_file_utils import get_abs_path_real_path_and_base_from_frame, get_abs_path_real_path_and_base_from_file, NORM_PATHS_AND_BASE_CONTAINER +from pydevd_file_utils import ( + get_abs_path_real_path_and_base_from_frame, + get_abs_path_real_path_and_base_from_file, + NORM_PATHS_AND_BASE_CONTAINER, +) from pydevd_file_utils import get_fullname, get_package_dir from os.path import abspath as os_path_abspath import pydevd_tracing -from _pydevd_bundle.pydevd_comm import (InternalThreadCommand, InternalThreadCommandForAnyThread, - create_server_socket, FSNotifyThread) -from _pydevd_bundle.pydevd_comm import(InternalConsoleExec, - _queue, ReaderThread, GetGlobalDebugger, get_global_debugger, - set_global_debugger, WriterThread, - start_client, start_server, InternalGetBreakpointException, InternalSendCurrExceptionTrace, - InternalSendCurrExceptionTraceProceeded) +from _pydevd_bundle.pydevd_comm import InternalThreadCommand, InternalThreadCommandForAnyThread, create_server_socket, FSNotifyThread +from _pydevd_bundle.pydevd_comm import ( + InternalConsoleExec, + _queue, + ReaderThread, + GetGlobalDebugger, + get_global_debugger, + set_global_debugger, + WriterThread, + start_client, + start_server, + InternalGetBreakpointException, + InternalSendCurrExceptionTrace, + InternalSendCurrExceptionTraceProceeded, +) from _pydevd_bundle.pydevd_daemon_thread import PyDBDaemonThread, mark_as_pydevd_daemon_thread from _pydevd_bundle.pydevd_process_net_command_json import PyDevJsonCommandProcessor from _pydevd_bundle.pydevd_process_net_command import process_net_command @@ -111,8 +166,9 @@ from _pydevd_bundle import pydevd_gevent_integration except: pydev_log.exception( - 'pydevd: GEVENT_SUPPORT is set but gevent is not available in the environment.\n' - 'Please unset GEVENT_SUPPORT from the environment variables or install gevent.') + "pydevd: GEVENT_SUPPORT is set but gevent is not available in the environment.\n" + "Please unset GEVENT_SUPPORT from the environment variables or install gevent." + ) else: pydevd_gevent_integration.log_gevent_debug_info() @@ -124,7 +180,7 @@ for v in __version_info__: __version_info_str__.append(str(v)) -__version__ = '.'.join(__version_info_str__) +__version__ = ".".join(__version_info_str__) # IMPORTANT: pydevd_constants must be the 1st thing defined because it'll keep a reference to the original sys._getframe @@ -133,13 +189,13 @@ def install_breakpointhook(pydevd_breakpointhook=None): if pydevd_breakpointhook is None: def pydevd_breakpointhook(*args, **kwargs): - hookname = os.getenv('PYTHONBREAKPOINT') + hookname = os.getenv("PYTHONBREAKPOINT") if ( - hookname is not None - and len(hookname) > 0 - and hasattr(sys, '__breakpointhook__') - and sys.__breakpointhook__ != pydevd_breakpointhook - ): + hookname is not None + and len(hookname) > 0 + and hasattr(sys, "__breakpointhook__") + and sys.__breakpointhook__ != pydevd_breakpointhook + ): sys.__breakpointhook__(*args, **kwargs) else: settrace(*args, **kwargs) @@ -175,7 +231,7 @@ def pydevd_breakpointhook(*args, **kwargs): threadingCurrentThread = threading.current_thread try: - 'dummy'.encode('utf-8') # Added because otherwise Jython 2.2.1 wasn't finding the encoding (if it wasn't loaded in the main thread). + "dummy".encode("utf-8") # Added because otherwise Jython 2.2.1 wasn't finding the encoding (if it wasn't loaded in the main thread). except: pass @@ -186,26 +242,25 @@ def pydevd_breakpointhook(*args, **kwargs): _CACHE_FILE_TYPE = {} -pydev_log.debug('Using GEVENT_SUPPORT: %s', pydevd_constants.SUPPORT_GEVENT) -pydev_log.debug('Using GEVENT_SHOW_PAUSED_GREENLETS: %s', pydevd_constants.GEVENT_SHOW_PAUSED_GREENLETS) -pydev_log.debug('pydevd __file__: %s', os.path.abspath(__file__)) -pydev_log.debug('Using PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING: %s', pydevd_constants.PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING) +pydev_log.debug("Using GEVENT_SUPPORT: %s", pydevd_constants.SUPPORT_GEVENT) +pydev_log.debug("Using GEVENT_SHOW_PAUSED_GREENLETS: %s", pydevd_constants.GEVENT_SHOW_PAUSED_GREENLETS) +pydev_log.debug("pydevd __file__: %s", os.path.abspath(__file__)) +pydev_log.debug("Using PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING: %s", pydevd_constants.PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING) if pydevd_constants.PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING: - pydev_log.debug('PYDEVD_IPYTHON_CONTEXT: %s', pydevd_constants.PYDEVD_IPYTHON_CONTEXT) + pydev_log.debug("PYDEVD_IPYTHON_CONTEXT: %s", pydevd_constants.PYDEVD_IPYTHON_CONTEXT) TIMEOUT_SLOW = 0.2 -TIMEOUT_FAST = 1. / 50 +TIMEOUT_FAST = 1.0 / 50 -#======================================================================================================================= +# ======================================================================================================================= # PyDBCommandThread -#======================================================================================================================= +# ======================================================================================================================= class PyDBCommandThread(PyDBDaemonThread): - def __init__(self, py_db): PyDBDaemonThread.__init__(self, py_db) self._py_db_command_thread_event = py_db._py_db_command_thread_event - self.name = 'pydevd.CommandThread' + self.name = "pydevd.CommandThread" @overrides(PyDBDaemonThread._on_run) def _on_run(self): @@ -218,9 +273,9 @@ def _on_run(self): try: while not self._kill_received: try: - self.py_db.process_internal_commands(('*',)) + self.py_db.process_internal_commands(("*",)) except: - pydev_log.info('Finishing debug communication...(2)') + pydev_log.info("Finishing debug communication...(2)") self._py_db_command_thread_event.clear() self._py_db_command_thread_event.wait(TIMEOUT_SLOW) except: @@ -241,15 +296,14 @@ def do_kill_pydev_thread(self): self._py_db_command_thread_event.set() -#======================================================================================================================= +# ======================================================================================================================= # CheckAliveThread # Non-daemon thread: guarantees that all data is written even if program is finished -#======================================================================================================================= +# ======================================================================================================================= class CheckAliveThread(PyDBDaemonThread): - def __init__(self, py_db): PyDBDaemonThread.__init__(self, py_db) - self.name = 'pydevd.CheckAliveThread' + self.name = "pydevd.CheckAliveThread" self.daemon = False self._wait_event = ThreadingEvent() @@ -294,7 +348,7 @@ def do_kill_pydev_thread(self): class AbstractSingleNotificationBehavior(object): - ''' + """ The basic usage should be: # Increment the request time for the suspend. @@ -310,20 +364,20 @@ class AbstractSingleNotificationBehavior(object): def do_wait_suspend(...): with single_notification_behavior.notify_thread_suspended(thread_id, thread, reason): ... - ''' + """ __slots__ = [ - '_last_resume_notification_time', - '_last_suspend_notification_time', - '_lock', - '_next_request_time', - '_suspend_time_request', - '_suspended_thread_id_to_thread', - '_pause_requested', - '_py_db', + "_last_resume_notification_time", + "_last_suspend_notification_time", + "_lock", + "_next_request_time", + "_suspend_time_request", + "_suspended_thread_id_to_thread", + "_pause_requested", + "_py_db", ] - NOTIFY_OF_PAUSE_TIMEOUT = .5 + NOTIFY_OF_PAUSE_TIMEOUT = 0.5 def __init__(self, py_db): self._py_db = weakref.ref(py_db) @@ -336,10 +390,10 @@ def __init__(self, py_db): self._pause_requested = False def send_suspend_notification(self, thread_id, thread, stop_reason): - raise AssertionError('abstract: subclasses must override.') + raise AssertionError("abstract: subclasses must override.") def send_resume_notification(self, thread_id): - raise AssertionError('abstract: subclasses must override.') + raise AssertionError("abstract: subclasses must override.") def increment_suspend_time(self): with self._lock: @@ -354,9 +408,7 @@ def on_pause(self): py_db = self._py_db() if py_db is not None: py_db.timeout_tracker.call_on_timeout( - self.NOTIFY_OF_PAUSE_TIMEOUT, - self._notify_after_timeout, - kwargs={'global_suspend_time': global_suspend_time} + self.NOTIFY_OF_PAUSE_TIMEOUT, self._notify_after_timeout, kwargs={"global_suspend_time": global_suspend_time} ) def _notify_after_timeout(self, global_suspend_time): @@ -365,7 +417,7 @@ def _notify_after_timeout(self, global_suspend_time): if global_suspend_time > self._last_suspend_notification_time: self._last_suspend_notification_time = global_suspend_time # Notify about any thread which is currently suspended. - pydev_log.info('Sending suspend notification after timeout.') + pydev_log.info("Sending suspend notification after timeout.") thread_id, thread = next(iter(self._suspended_thread_id_to_thread.items())) self.send_suspend_notification(thread_id, thread, CMD_THREAD_SUSPEND) @@ -382,18 +434,18 @@ def on_thread_suspend(self, thread_id, thread, stop_reason): # issue for a CMD_THREAD_SUSPEND if a pause is pending. if stop_reason != CMD_THREAD_SUSPEND or pause_requested: if self._suspend_time_request > self._last_suspend_notification_time: - pydev_log.info('Sending suspend notification.') + pydev_log.info("Sending suspend notification.") self._last_suspend_notification_time = self._suspend_time_request self.send_suspend_notification(thread_id, thread, stop_reason) else: pydev_log.info( - 'Suspend not sent (it was already sent). Last suspend % <= Last resume %s', + "Suspend not sent (it was already sent). Last suspend % <= Last resume %s", self._last_suspend_notification_time, self._last_resume_notification_time, ) else: pydev_log.info( - 'Suspend not sent because stop reason is thread suspend and pause was not requested.', + "Suspend not sent because stop reason is thread suspend and pause was not requested.", ) def on_thread_resume(self, thread_id, thread): @@ -401,12 +453,12 @@ def on_thread_resume(self, thread_id, thread): with self._lock: self._suspended_thread_id_to_thread.pop(thread_id) if self._last_resume_notification_time < self._last_suspend_notification_time: - pydev_log.info('Sending resume notification.') + pydev_log.info("Sending resume notification.") self._last_resume_notification_time = self._last_suspend_notification_time self.send_resume_notification(thread_id) else: pydev_log.info( - 'Resume not sent (it was already sent). Last resume %s >= Last suspend %s', + "Resume not sent (it was already sent). Last resume %s >= Last suspend %s", self._last_resume_notification_time, self._last_suspend_notification_time, ) @@ -421,9 +473,7 @@ def notify_thread_suspended(self, thread_id, thread, stop_reason): class ThreadsSuspendedSingleNotification(AbstractSingleNotificationBehavior): - - __slots__ = AbstractSingleNotificationBehavior.__slots__ + [ - 'multi_threads_single_notification', '_callbacks', '_callbacks_lock'] + __slots__ = AbstractSingleNotificationBehavior.__slots__ + ["multi_threads_single_notification", "_callbacks", "_callbacks_lock"] def __init__(self, py_db): AbstractSingleNotificationBehavior.__init__(self, py_db) @@ -453,25 +503,22 @@ def send_resume_notification(self, thread_id): def send_suspend_notification(self, thread_id, thread, stop_reason): py_db = self._py_db() if py_db is not None: - py_db.writer.add_command( - py_db.cmd_factory.make_thread_suspend_single_notification( - py_db, thread_id, thread, stop_reason)) + py_db.writer.add_command(py_db.cmd_factory.make_thread_suspend_single_notification(py_db, thread_id, thread, stop_reason)) @overrides(AbstractSingleNotificationBehavior.notify_thread_suspended) @contextmanager def notify_thread_suspended(self, thread_id, thread, stop_reason): if self.multi_threads_single_notification: - pydev_log.info('Thread suspend mode: single notification') + pydev_log.info("Thread suspend mode: single notification") with AbstractSingleNotificationBehavior.notify_thread_suspended(self, thread_id, thread, stop_reason): yield else: - pydev_log.info('Thread suspend mode: NOT single notification') + pydev_log.info("Thread suspend mode: NOT single notification") yield class _Authentication(object): - - __slots__ = ['access_token', 'client_access_token', '_authenticated', '_wrong_attempts'] + __slots__ = ["access_token", "client_access_token", "_authenticated", "_wrong_attempts"] def __init__(self): # A token to be send in the command line or through the settrace api -- when such token @@ -509,7 +556,7 @@ def logout(self): class PyDB(object): - """ Main debugging class + """Main debugging class Lots of stuff going on here: PyDB starts two threads on startup that connect to remote debugger (RDB) @@ -645,7 +692,7 @@ def __init__(self, set_as_global=True): # matplotlib - Whatever GUI backend matplotlib is using. # 'wx'/'qt'/'none'/... - GUI toolkits that have bulitin support. See pydevd_ipython/inputhook.py:24. # Other - A custom function that'll be imported and run. - self._gui_event_loop = 'matplotlib' + self._gui_event_loop = "matplotlib" self._installed_gui_support = False self.gui_in_use = False @@ -686,7 +733,6 @@ def __init__(self, set_as_global=True): # in the namespace (and thus can't be relied upon unless the reference was previously # saved). if IS_IRONPYTHON: - # A partial() cannot be used in IronPython for sys.settrace. def new_trace_dispatch(frame, event, arg): return _trace_dispatch(self, frame, event, arg) @@ -740,14 +786,13 @@ def collect_try_except_info(self, code_obj): filename = code_obj.co_filename try: if os.path.exists(filename): - pydev_log.debug('Collecting try..except info from source for %s', filename) + pydev_log.debug("Collecting try..except info from source for %s", filename) try_except_infos = collect_try_except_info_from_source(filename) if try_except_infos: # Filter for the current function max_line = -1 min_line = sys.maxsize for _, line in dis.findlinestarts(code_obj): - if line > max_line: max_line = line @@ -758,15 +803,14 @@ def collect_try_except_info(self, code_obj): return try_except_infos except: - pydev_log.exception('Error collecting try..except info from source (%s)', filename) + pydev_log.exception("Error collecting try..except info from source (%s)", filename) - pydev_log.debug('Collecting try..except info from bytecode for %s', filename) + pydev_log.debug("Collecting try..except info from bytecode for %s", filename) return collect_try_except_info(code_obj) def setup_auto_reload_watcher(self, enable_auto_reload, watch_dirs, poll_target_time, exclude_patterns, include_patterns): try: with self._lock_create_fs_notify: - # When setting up, dispose of the previous one (if any). if self._fsnotify_thread is not None: self._fsnotify_thread.do_kill_pydev_thread() @@ -782,7 +826,7 @@ def accept_directory(absolute_filename, cache={}): try: return cache[absolute_filename] except: - if absolute_filename and absolute_filename[-1] not in ('/', '\\'): + if absolute_filename and absolute_filename[-1] not in ("/", "\\"): # I.e.: for directories we always end with '/' or '\\' so that # we match exclusions such as "**/node_modules/**" absolute_filename += os.path.sep @@ -832,15 +876,15 @@ def accept_file(absolute_filename, cache={}): watcher.target_time_for_notification = poll_target_time self._fsnotify_thread.start() except: - pydev_log.exception('Error setting up auto-reload.') + pydev_log.exception("Error setting up auto-reload.") def get_arg_ppid(self): try: setup = SetupHolder.setup if setup: - return int(setup.get('ppid', 0)) + return int(setup.get("ppid", 0)) except: - pydev_log.exception('Error getting ppid.') + pydev_log.exception("Error getting ppid.") return 0 @@ -852,15 +896,15 @@ def wait_for_ready_to_run(self): self._py_db_command_thread_event.wait(TIMEOUT_FAST) def on_initialize(self): - ''' + """ Note: only called when using the DAP (Debug Adapter Protocol). - ''' + """ self._on_configuration_done_event.clear() def on_configuration_done(self): - ''' + """ Note: only called when using the DAP (Debug Adapter Protocol). - ''' + """ self._on_configuration_done_event.set() self._py_db_command_thread_event.set() @@ -868,9 +912,9 @@ def is_attached(self): return self._on_configuration_done_event.is_set() def on_disconnect(self): - ''' + """ Note: only called when using the DAP (Debug Adapter Protocol). - ''' + """ self.authentication.logout() self._on_configuration_done_event.clear() @@ -879,7 +923,7 @@ def set_ignore_system_exit_codes(self, ignore_system_exit_codes): self._ignore_system_exit_codes = set(ignore_system_exit_codes) def ignore_system_exit_code(self, system_exit_exc): - if hasattr(system_exit_exc, 'code'): + if hasattr(system_exit_exc, "code"): return system_exit_exc.code in self._ignore_system_exit_codes else: return system_exit_exc in self._ignore_system_exit_codes @@ -916,8 +960,7 @@ def handle_breakpoint_condition(self, info, pybreakpoint, new_frame): etype, value, tb = sys.exc_info() traceback.print_exception(etype, value, tb.tb_next, file=stack_trace) - msg = 'Error while evaluating expression in conditional breakpoint: %s\n%s' % ( - condition, stack_trace.getvalue()) + msg = "Error while evaluating expression in conditional breakpoint: %s\n%s" % (condition, stack_trace.getvalue()) api = PyDevdAPI() api.send_error_message(self, msg) @@ -925,13 +968,12 @@ def handle_breakpoint_condition(self, info, pybreakpoint, new_frame): try: # add exception_type and stacktrace into thread additional info etype, value, tb = sys.exc_info() - error = ''.join(traceback.format_exception_only(etype, value)) + error = "".join(traceback.format_exception_only(etype, value)) stack = traceback.extract_stack(f=tb.tb_frame.f_back) # On self.set_suspend(thread, CMD_SET_BREAK) this info will be # sent to the client. - info.conditional_breakpoint_exception = \ - ('Condition:\n' + condition + '\n\nError:\n' + error, stack) + info.conditional_breakpoint_exception = ("Condition:\n" + condition + "\n\nError:\n" + error, stack) except: pydev_log.exception() return True @@ -953,10 +995,7 @@ def handle_breakpoint_expression(self, pybreakpoint, info, new_frame): def _internal_get_file_type(self, abs_real_path_and_basename): basename = abs_real_path_and_basename[-1] - if ( - basename.startswith(IGNORE_BASENAMES_STARTING_WITH) or - abs_real_path_and_basename[0].startswith(IGNORE_BASENAMES_STARTING_WITH) - ): + if basename.startswith(IGNORE_BASENAMES_STARTING_WITH) or abs_real_path_and_basename[0].startswith(IGNORE_BASENAMES_STARTING_WITH): # Note: these are the files that are completely ignored (they aren't shown to the user # as user nor library code as it's usually just noise in the frame stack). return self.PYDEV_FILE @@ -964,16 +1003,16 @@ def _internal_get_file_type(self, abs_real_path_and_basename): if file_type is not None: return file_type - if basename.startswith('__init__.py') or basename in LIB_FILES_IN_DONT_TRACE_DIRS: + if basename.startswith("__init__.py") or basename in LIB_FILES_IN_DONT_TRACE_DIRS: # i.e.: ignore the __init__ files inside pydevd (the other # files are ignored just by their name). abs_path = abs_real_path_and_basename[0] - i = max(abs_path.rfind('/'), abs_path.rfind('\\')) + i = max(abs_path.rfind("/"), abs_path.rfind("\\")) if i: abs_path = abs_path[0:i] - i = max(abs_path.rfind('/'), abs_path.rfind('\\')) + i = max(abs_path.rfind("/"), abs_path.rfind("\\")) if i: - dirname = abs_path[i + 1:] + dirname = abs_path[i + 1 :] # At this point, something as: # "my_path\_pydev_runfiles\__init__.py" # is now "_pydev_runfiles". @@ -981,7 +1020,7 @@ def _internal_get_file_type(self, abs_real_path_and_basename): return None def dont_trace_external_files(self, abs_path): - ''' + """ :param abs_path: The result from get_abs_path_real_path_and_base_from_file or get_abs_path_real_path_and_base_from_frame. @@ -992,13 +1031,13 @@ def dont_trace_external_files(self, abs_path): False: If files should be traced. - ''' + """ # By default all external files are traced. Note: this function is expected to # be changed for another function in PyDevdAPI.set_dont_trace_start_end_patterns. return False def get_file_type(self, frame, abs_real_path_and_basename=None, _cache_file_type=_CACHE_FILE_TYPE): - ''' + """ :param abs_real_path_and_basename: The result from get_abs_path_real_path_and_base_from_file or get_abs_path_real_path_and_base_from_frame. @@ -1013,7 +1052,7 @@ def get_file_type(self, frame, abs_real_path_and_basename=None, _cache_file_type None: If it's a regular user file which should be traced. - ''' + """ if abs_real_path_and_basename is None: try: # Make fast path faster! @@ -1035,13 +1074,15 @@ def get_file_type(self, frame, abs_real_path_and_basename=None, _cache_file_type try: return _cache_file_type[cache_key] except: - if abs_real_path_and_basename[0] == '': + if abs_real_path_and_basename[0] == "": # Consider it an untraceable file unless there's no back frame (ignoring # internal files and runpy.py). f = frame.f_back while f is not None: - if (self.get_file_type(f) != self.PYDEV_FILE and - pydevd_file_utils.basename(f.f_code.co_filename) not in ('runpy.py', '')): + if self.get_file_type(f) != self.PYDEV_FILE and pydevd_file_utils.basename(f.f_code.co_filename) not in ( + "runpy.py", + "", + ): # We found some back frame that's not internal, which means we must consider # this a library file. # This is done because we only want to trace files as if they don't @@ -1082,7 +1123,7 @@ def get_thread_local_trace_func(self): return thread_trace_func def enable_tracing(self, thread_trace_func=None, apply_to_all_threads=False): - ''' + """ Enables tracing. If in regular mode (tracing), will set the tracing function to the tracing @@ -1096,7 +1137,7 @@ def enable_tracing(self, thread_trace_func=None, apply_to_all_threads=False): In general apply_to_all_threads should only be true if this is the first time this function is called on a multi-threaded program (either programmatically or attach to pid). - ''' + """ if PYDEVD_USE_SYS_MONITORING: pydevd_sys_monitoring.start_monitoring(all_threads=apply_to_all_threads) return @@ -1132,9 +1173,9 @@ def disable_tracing(self): pydevd_tracing.SetTrace(None) def on_breakpoints_changed(self, removed=False): - ''' + """ When breakpoints change, we have to re-evaluate all the assumptions we've made so far. - ''' + """ if not self.ready_to_run: # No need to do anything if we're still not running. return @@ -1162,8 +1203,9 @@ def set_tracing_for_untraced_contexts(self, breakpoints_changed=False): tid_to_frame = sys._current_frames() ignore_thread_ids = set( - t.ident for t in threadingEnumerate() - if getattr(t, 'is_pydev_daemon_thread', False) or getattr(t, 'pydev_do_not_trace', False) + t.ident + for t in threadingEnumerate() + if getattr(t, "is_pydev_daemon_thread", False) or getattr(t, "pydev_do_not_trace", False) ) for thread_ident, frame in tid_to_frame.items(): @@ -1174,7 +1216,7 @@ def set_tracing_for_untraced_contexts(self, breakpoints_changed=False): try: threads = threadingEnumerate() for t in threads: - if getattr(t, 'is_pydev_daemon_thread', False) or getattr(t, 'pydev_do_not_trace', False): + if getattr(t, "is_pydev_daemon_thread", False) or getattr(t, "pydev_do_not_trace", False): continue additional_info = set_additional_thread_info(t) @@ -1211,7 +1253,7 @@ def get_plugin_lazy_init(self): return self.plugin def in_project_scope(self, frame, absolute_filename=None): - ''' + """ Note: in general this method should not be used (apply_files_filter should be used in most cases as it also handles the project scope check). @@ -1222,7 +1264,7 @@ def in_project_scope(self, frame, absolute_filename=None): Must be the result from get_abs_path_real_path_and_base_from_frame(frame)[0] (can be used to speed this function a bit if it's already available to the caller, but in general it's not needed). - ''' + """ try: if absolute_filename is None: try: @@ -1248,7 +1290,7 @@ def in_project_scope(self, frame, absolute_filename=None): if file_type == self.PYDEV_FILE: cache[cache_key] = False - elif absolute_filename == '': + elif absolute_filename == "": # Special handling for '' if file_type == self.LIB_FILE: cache[cache_key] = False @@ -1293,12 +1335,12 @@ def clear_dont_trace_start_end_patterns_caches(self): self._clear_caches() def _exclude_by_filter(self, frame, absolute_filename): - ''' + """ :return: True if it should be excluded, False if it should be included and None if no rule matched the given file. :note: it'll be normalized as needed inside of this method. - ''' + """ cache_key = (absolute_filename, frame.f_code.co_name, frame.f_code.co_firstlineno) try: return self._exclude_by_filter_cache[cache_key] @@ -1311,13 +1353,13 @@ def _exclude_by_filter(self, frame, absolute_filename): else: module_name = None if self._files_filtering.require_module: - module_name = frame.f_globals.get('__name__', '') + module_name = frame.f_globals.get("__name__", "") cache[cache_key] = self._files_filtering.exclude_by_filter(absolute_filename, module_name) return cache[cache_key] def apply_files_filter(self, frame, original_filename, force_check_project_scope): - ''' + """ Should only be called if `self.is_files_filter_enabled == True` or `force_check_project_scope == True`. Note that it covers both the filter by specific paths includes/excludes as well @@ -1333,7 +1375,7 @@ def apply_files_filter(self, frame, original_filename, force_check_project_scope :return bool: True if it should be excluded when stepping and False if it should be included. - ''' + """ cache_key = (frame.f_code.co_firstlineno, original_filename, force_check_project_scope, frame.f_code) try: return self._apply_filter_cache[cache_key] @@ -1343,7 +1385,7 @@ def apply_files_filter(self, frame, original_filename, force_check_project_scope # If it's explicitly needed by some plugin, we can't skip it. if not self.plugin.can_skip(self, frame): if DEBUG: - pydev_log.debug_once('File traced (included by plugins): %s', original_filename) + pydev_log.debug_once("File traced (included by plugins): %s", original_filename) self._apply_filter_cache[cache_key] = False return False @@ -1354,13 +1396,13 @@ def apply_files_filter(self, frame, original_filename, force_check_project_scope if exclude_by_filter: # ignore files matching stepping filters if DEBUG: - pydev_log.debug_once('File not traced (excluded by filters): %s', original_filename) + pydev_log.debug_once("File not traced (excluded by filters): %s", original_filename) self._apply_filter_cache[cache_key] = True return True else: if DEBUG: - pydev_log.debug_once('File traced (explicitly included by filters): %s', original_filename) + pydev_log.debug_once("File traced (explicitly included by filters): %s", original_filename) self._apply_filter_cache[cache_key] = False return False @@ -1370,19 +1412,19 @@ def apply_files_filter(self, frame, original_filename, force_check_project_scope self._apply_filter_cache[cache_key] = True if force_check_project_scope: if DEBUG: - pydev_log.debug_once('File not traced (not in project): %s', original_filename) + pydev_log.debug_once("File not traced (not in project): %s", original_filename) else: if DEBUG: - pydev_log.debug_once('File not traced (not in project - force_check_project_scope): %s', original_filename) + pydev_log.debug_once("File not traced (not in project - force_check_project_scope): %s", original_filename) return True if force_check_project_scope: if DEBUG: - pydev_log.debug_once('File traced: %s (force_check_project_scope)', original_filename) + pydev_log.debug_once("File traced: %s (force_check_project_scope)", original_filename) else: if DEBUG: - pydev_log.debug_once('File traced: %s', original_filename) + pydev_log.debug_once("File traced: %s", original_filename) self._apply_filter_cache[cache_key] = False return False @@ -1396,10 +1438,10 @@ def exclude_exception_by_filter(self, exception_breakpoint, trace): ignore_libraries = exception_breakpoint.ignore_libraries exclude_filters_enabled = self._exclude_filters_enabled - if (ignore_libraries and not self.in_project_scope(trace.tb_frame)) \ - or (exclude_filters_enabled and self._exclude_by_filter( - trace.tb_frame, - pydevd_file_utils.absolute_path(trace.tb_frame.f_code.co_filename))): + if (ignore_libraries and not self.in_project_scope(trace.tb_frame)) or ( + exclude_filters_enabled + and self._exclude_by_filter(trace.tb_frame, pydevd_file_utils.absolute_path(trace.tb_frame.f_code.co_filename)) + ): return True return False @@ -1425,8 +1467,7 @@ def get_require_module_for_filters(self): def has_user_threads_alive(self): for t in pydevd_utils.get_non_pydevd_threads(): if isinstance(t, PyDBDaemonThread): - pydev_log.error_once( - 'Error in debugger: Found PyDBDaemonThread not marked with is_pydev_daemon_thread=True.\n') + pydev_log.error_once("Error in debugger: Found PyDBDaemonThread not marked with is_pydev_daemon_thread=True.\n") if is_thread_alive(t): if not t.daemon or hasattr(t, "__pydevd_main_thread"): @@ -1440,8 +1481,8 @@ def initialize_network(self, sock, terminate_on_socket_close=True): sock.settimeout(None) # infinite, no timeouts from now on - jython does not have it except: pass - curr_reader = getattr(self, 'reader', None) - curr_writer = getattr(self, 'writer', None) + curr_reader = getattr(self, "reader", None) + curr_writer = getattr(self, "writer", None) if curr_reader: curr_reader.do_kill_pydev_thread() if curr_writer: @@ -1453,7 +1494,7 @@ def initialize_network(self, sock, terminate_on_socket_close=True): self, PyDevJsonCommandProcessor=PyDevJsonCommandProcessor, process_net_command=process_net_command, - terminate_on_socket_close=terminate_on_socket_close + terminate_on_socket_close=terminate_on_socket_close, ) self.writer.start() self.reader.start() @@ -1470,7 +1511,7 @@ def connect(self, host, port): def create_wait_for_connection_thread(self): if self._waiting_for_connection_thread is not None: - raise AssertionError('There is already another thread waiting for a connection.') + raise AssertionError("There is already another thread waiting for a connection.") self._server_socket_ready_event.clear() self._waiting_for_connection_thread = self._WaitForConnectionThread(self) @@ -1490,14 +1531,13 @@ def add_dap_messages_listener(self, listener): self._dap_messages_listeners.append(listener) class _WaitForConnectionThread(PyDBDaemonThread): - def __init__(self, py_db): PyDBDaemonThread.__init__(self, py_db) self._server_socket = None def run(self): - host = SetupHolder.setup['client'] - port = SetupHolder.setup['port'] + host = SetupHolder.setup["client"] + port = SetupHolder.setup["port"] self._server_socket = create_server_socket(host=host, port=port) self.py_db._server_socket_name = self._server_socket.getsockname() @@ -1516,7 +1556,7 @@ def run(self): return pydev_log.info("Connection (from wait_for_attach) accepted.") - reader = getattr(self.py_db, 'reader', None) + reader = getattr(self.py_db, "reader", None) if reader is not None: # This is needed if a new connection is done without the client properly # sending a disconnect for the previous connection. @@ -1541,24 +1581,24 @@ def do_kill_pydev_thread(self): self._server_socket = None def get_internal_queue_and_event(self, thread_id) -> Tuple[_queue.Queue, ThreadingEvent]: - """ returns internal command queue for a given thread. - if new queue is created, notify the RDB about it """ - if thread_id.startswith('__frame__'): - thread_id = thread_id[thread_id.rfind('|') + 1:] + """returns internal command queue for a given thread. + if new queue is created, notify the RDB about it""" + if thread_id.startswith("__frame__"): + thread_id = thread_id[thread_id.rfind("|") + 1 :] return self._cmd_queue[thread_id], self._thread_events[thread_id] def post_method_as_internal_command(self, thread_id, method, *args, **kwargs): - if thread_id == '*': + if thread_id == "*": internal_cmd = InternalThreadCommandForAnyThread(thread_id, method, *args, **kwargs) else: internal_cmd = InternalThreadCommand(thread_id, method, *args, **kwargs) self.post_internal_command(internal_cmd, thread_id) def post_internal_command(self, int_cmd, thread_id): - """ if thread_id is *, post to the '*' queue""" + """if thread_id is *, post to the '*' queue""" queue, event = self.get_internal_queue_and_event(thread_id) queue.put(int_cmd) - if thread_id == '*': + if thread_id == "*": self._py_db_command_thread_event.set() else: event.set() @@ -1607,13 +1647,15 @@ def return_control(): set_return_control_callback(return_control) - if self._gui_event_loop == 'matplotlib': + if self._gui_event_loop == "matplotlib": # prepare debugger for matplotlib integration with GUI event loop from pydev_ipython.matplotlibtools import activate_matplotlib, activate_pylab, activate_pyplot, do_enable_gui - self.mpl_modules_for_patching = {"matplotlib": lambda: activate_matplotlib(do_enable_gui), - "matplotlib.pyplot": activate_pyplot, - "pylab": activate_pylab } + self.mpl_modules_for_patching = { + "matplotlib": lambda: activate_matplotlib(do_enable_gui), + "matplotlib.pyplot": activate_pyplot, + "pylab": activate_pylab, + } else: self.activate_gui_function = enable_gui @@ -1640,6 +1682,7 @@ def _activate_gui_if_needed(self): except ValueError: # The user requested a custom GUI event loop, try to import it. from pydev_ipython.inputhook import set_inputhook + try: inputhook_function = import_attr_from_module(self._gui_event_loop) set_inputhook(inputhook_function) @@ -1652,6 +1695,7 @@ def _activate_gui_if_needed(self): def _call_input_hook(self): try: from pydev_ipython.inputhook import get_inputhook + inputhook = get_inputhook() if inputhook: inputhook() @@ -1687,7 +1731,7 @@ def notify_thread_created(self, thread_id, thread, use_lock=True): self.writer.add_command(self.cmd_factory.make_thread_created_message(thread)) def notify_thread_not_alive(self, thread_id, use_lock=True): - """ if thread is not alive, cancel trace_dispatch processing """ + """if thread is not alive, cancel trace_dispatch processing""" if self.writer is None: return @@ -1717,10 +1761,10 @@ def set_enable_thread_notifications(self, enable): # (so, clear the cache related to that). self._running_thread_ids = {} - def process_internal_commands(self, process_thread_ids: Optional[tuple]=None): - ''' + def process_internal_commands(self, process_thread_ids: Optional[tuple] = None): + """ This function processes internal commands. - ''' + """ # If this method is being called before the debugger is ready to run we should not notify # about threads and should only process commands sent to all threads. ready_to_run = self.ready_to_run @@ -1737,10 +1781,10 @@ def process_internal_commands(self, process_thread_ids: Optional[tuple]=None): reset_cache = not self._running_thread_ids for t in all_threads: - if getattr(t, 'is_pydev_daemon_thread', False): + if getattr(t, "is_pydev_daemon_thread", False): pass # I.e.: skip the DummyThreads created from pydev daemon threads elif isinstance(t, PyDBDaemonThread): - pydev_log.error_once('Error in debugger: Found PyDBDaemonThread not marked with is_pydev_daemon_thread=True.') + pydev_log.error_once("Error in debugger: Found PyDBDaemonThread not marked with is_pydev_daemon_thread=True.") elif is_thread_alive(t): if reset_cache: @@ -1777,9 +1821,9 @@ def process_internal_commands(self, process_thread_ids: Optional[tuple]=None): # acquired at this point as it could lead to a deadlock if some command evaluated tried to # create a thread and wait for it -- which would try to notify about it getting that lock). if ready_to_run: - process_thread_ids = (curr_thread_id, '*') + process_thread_ids = (curr_thread_id, "*") else: - process_thread_ids = ('*',) + process_thread_ids = ("*",) for thread_id in process_thread_ids: queue, _event = self.get_internal_queue_and_event(thread_id) @@ -1816,7 +1860,7 @@ def process_internal_commands(self, process_thread_ids: Optional[tuple]=None): try: internal_cmd.do_it(self) except: - pydev_log.exception('Error processing internal command.') + pydev_log.exception("Error processing internal command.") def consolidate_breakpoints(self, canonical_normalized_filename, id_to_breakpoint, file_to_line_to_breakpoints): break_dict = {} @@ -1835,8 +1879,8 @@ def add_break_on_exception( notify_on_unhandled_exceptions, notify_on_user_unhandled_exceptions, notify_on_first_raise_only, - ignore_libraries=False - ): + ignore_libraries=False, + ): try: eb = ExceptionBreakpoint( exception, @@ -1846,7 +1890,7 @@ def add_break_on_exception( notify_on_unhandled_exceptions, notify_on_user_unhandled_exceptions, notify_on_first_raise_only, - ignore_libraries + ignore_libraries, ) except ImportError: pydev_log.critical("Error unable to add break on exception for: %s (exception could not be imported).", exception) @@ -1873,9 +1917,15 @@ def add_break_on_exception( return eb def set_suspend( - self, thread, stop_reason: int, suspend_other_threads: bool=False, - is_pause=False, original_step_cmd: int=-1, suspend_requested: bool=False): - ''' + self, + thread, + stop_reason: int, + suspend_other_threads: bool = False, + is_pause=False, + original_step_cmd: int = -1, + suspend_requested: bool = False, + ): + """ :param thread: The thread which should be suspended. @@ -1897,7 +1947,7 @@ def set_suspend( If the execution will be suspended right away then this may be false, otherwise, if the thread should be stopped due to this suspend at a later time then it should be true. - ''' + """ self._threads_suspended_single_notification.increment_suspend_time() if is_pause: self._threads_suspended_single_notification.on_pause() @@ -1957,24 +2007,21 @@ def send_caught_exception_stack(self, thread, arg, curr_frame_id): self.post_internal_command(int_cmd, thread_id) def send_caught_exception_stack_proceeded(self, thread): - """Sends that some thread was resumed and is no longer showing an exception trace. - """ + """Sends that some thread was resumed and is no longer showing an exception trace.""" thread_id = get_thread_id(thread) int_cmd = InternalSendCurrExceptionTraceProceeded(thread_id) self.post_internal_command(int_cmd, thread_id) self.process_internal_commands() def send_process_created_message(self): - """Sends a message that a new process has been created. - """ + """Sends a message that a new process has been created.""" if self.writer is None or self.cmd_factory is None: return cmd = self.cmd_factory.make_process_created_message() self.writer.add_command(cmd) def send_process_about_to_be_replaced(self): - """Sends a message that a new process has been created. - """ + """Sends a message that a new process has been created.""" if self.writer is None or self.cmd_factory is None: return cmd = self.cmd_factory.make_process_about_to_be_replaced_message() @@ -1992,17 +2039,17 @@ def after_sent(*args, **kwargs): timeout = 5 # Wait up to 5 seconds initial_time = time.time() while not sent[0]: - time.sleep(.05) + time.sleep(0.05) if (time.time() - initial_time) > timeout: - pydev_log.critical('pydevd: Sending message related to process being replaced timed-out after %s seconds', timeout) + pydev_log.critical("pydevd: Sending message related to process being replaced timed-out after %s seconds", timeout) break def set_next_statement(self, frame, event, func_name, next_line): stop = False response_msg = "" old_line = frame.f_lineno - if event == 'line' or event == 'exception': + if event == "line" or event == "exception": # If we're already in the correct context, we have to stop it now, because we can act only on # line events -- if a return was the next statement it wouldn't work (so, we have this code # repeated at pydevd_frame). @@ -2010,10 +2057,10 @@ def set_next_statement(self, frame, event, func_name, next_line): curr_func_name = frame.f_code.co_name # global context is set with an empty name - if curr_func_name in ('?', ''): - curr_func_name = '' + if curr_func_name in ("?", ""): + curr_func_name = "" - if func_name == '*' or curr_func_name == func_name: + if func_name == "*" or curr_func_name == func_name: line = next_line frame.f_trace = self.trace_dispatch frame.f_lineno = line @@ -2027,18 +2074,22 @@ def cancel_async_evaluation(self, thread_id, frame_id): try: all_threads = threadingEnumerate() for t in all_threads: - if getattr(t, 'is_pydev_daemon_thread', False) and hasattr(t, 'cancel_event') and t.thread_id == thread_id and \ - t.frame_id == frame_id: + if ( + getattr(t, "is_pydev_daemon_thread", False) + and hasattr(t, "cancel_event") + and t.thread_id == thread_id + and t.frame_id == frame_id + ): t.cancel_event.set() except: pydev_log.exception() def find_frame(self, thread_id, frame_id): - """ returns a frame on the thread that has a given frame_id """ + """returns a frame on the thread that has a given frame_id""" return self.suspended_frames_manager.find_frame(thread_id, frame_id) def do_wait_suspend(self, thread, frame, event, arg, exception_type=None): # @UnusedVariable - """ busy waits until the thread state changes to RUN + """busy waits until the thread state changes to RUN it expects thread's state as attributes of the thread. Upon running, processes any outstanding Stepping commands. @@ -2049,7 +2100,7 @@ def do_wait_suspend(self, thread, frame, event, arg, exception_type=None): # @U constructed_tid_to_last_frame[thread.ident] = sys._getframe() # Only process from all threads, not for current one (we'll do that later on in this method). - self.process_internal_commands(('*',)) + self.process_internal_commands(("*",)) thread_id = get_current_thread_id(thread) @@ -2065,23 +2116,25 @@ def do_wait_suspend(self, thread, frame, event, arg, exception_type=None): # @U # Send the suspend message message = thread.additional_info.pydev_message trace_suspend_type = thread.additional_info.trace_suspend_type - thread.additional_info.trace_suspend_type = 'trace' # Reset to trace mode for next call. + thread.additional_info.trace_suspend_type = "trace" # Reset to trace mode for next call. stop_reason = thread.stop_reason frames_list = None - if arg is not None and event == 'exception': + if arg is not None and event == "exception": # arg must be the exception info (tuple(exc_type, exc, traceback)) exc_type, exc_desc, trace_obj = arg if trace_obj is not None: - frames_list = pydevd_frame_utils.create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, exception_type=exception_type) + frames_list = pydevd_frame_utils.create_frames_list_from_traceback( + trace_obj, frame, exc_type, exc_desc, exception_type=exception_type + ) if frames_list is None: frames_list = pydevd_frame_utils.create_frames_list_from_frame(frame) if DebugInfoHolder.DEBUG_TRACE_LEVEL > 2: pydev_log.debug( - 'PyDB.do_wait_suspend\nname: %s (line: %s)\n file: %s\n event: %s\n arg: %s\n step: %s (original step: %s)\n thread: %s, thread id: %s, id(thread): %s', + "PyDB.do_wait_suspend\nname: %s (line: %s)\n file: %s\n event: %s\n arg: %s\n step: %s (original step: %s)\n thread: %s, thread id: %s, id(thread): %s", frame.f_code.co_name, frame.f_lineno, frame.f_code.co_filename, @@ -2094,11 +2147,13 @@ def do_wait_suspend(self, thread, frame, event, arg, exception_type=None): # @U id(thread), ) for f in frames_list: - pydev_log.debug(' Stack: %s, %s, %s', f.f_code.co_filename, f.f_code.co_name, f.f_lineno) + pydev_log.debug(" Stack: %s, %s, %s", f.f_code.co_filename, f.f_code.co_name, f.f_lineno) with self.suspended_frames_manager.track_frames(self) as frames_tracker: frames_tracker.track(thread_id, frames_list) - cmd = frames_tracker.create_thread_suspend_command(thread_id, stop_reason, message, trace_suspend_type, thread, thread.additional_info) + cmd = frames_tracker.create_thread_suspend_command( + thread_id, stop_reason, message, trace_suspend_type, thread, thread.additional_info + ) self.writer.add_command(cmd) with CustomFramesContainer.custom_frames_lock: # @UndefinedVariable @@ -2106,14 +2161,22 @@ def do_wait_suspend(self, thread, frame, event, arg, exception_type=None): # @U for frame_custom_thread_id, custom_frame in CustomFramesContainer.custom_frames.items(): if custom_frame.thread_id == thread.ident: - frames_tracker.track(thread_id, pydevd_frame_utils.create_frames_list_from_frame(custom_frame.frame), frame_custom_thread_id=frame_custom_thread_id) + frames_tracker.track( + thread_id, + pydevd_frame_utils.create_frames_list_from_frame(custom_frame.frame), + frame_custom_thread_id=frame_custom_thread_id, + ) # print('Frame created as thread: %s' % (frame_custom_thread_id,)) - self.writer.add_command(self.cmd_factory.make_custom_frame_created_message( - frame_custom_thread_id, custom_frame.name)) + self.writer.add_command( + self.cmd_factory.make_custom_frame_created_message(frame_custom_thread_id, custom_frame.name) + ) self.writer.add_command( - frames_tracker.create_thread_suspend_command(frame_custom_thread_id, CMD_THREAD_SUSPEND, "", trace_suspend_type, thread, thread.additional_info)) + frames_tracker.create_thread_suspend_command( + frame_custom_thread_id, CMD_THREAD_SUSPEND, "", trace_suspend_type, thread, thread.additional_info + ) + ) from_this_thread.append(frame_custom_thread_id) @@ -2127,7 +2190,7 @@ def do_wait_suspend(self, thread, frame, event, arg, exception_type=None): # @U self._threads_suspended_single_notification.increment_suspend_time() self.do_wait_suspend(thread, frame, event, arg, exception_type) if DebugInfoHolder.DEBUG_TRACE_LEVEL > 2: - pydev_log.debug('Leaving PyDB.do_wait_suspend: %s (%s) %s', thread, thread_id, id(thread)) + pydev_log.debug("Leaving PyDB.do_wait_suspend: %s (%s) %s", thread, thread_id, id(thread)) def _do_wait_suspend(self, thread, frame, event, arg, trace_suspend_type, from_this_thread, frames_tracker): info = thread.additional_info @@ -2180,7 +2243,7 @@ def _do_wait_suspend(self, thread, frame, event, arg, trace_suspend_type, from_t try: internal_cmd.do_it(self) except: - pydev_log.exception('Error processing internal command.') + pydev_log.exception("Error processing internal command.") else: # This shouldn't really happen... pydev_log.verbose("NOT processing internal command: %s ", internal_cmd) @@ -2225,7 +2288,7 @@ def _do_wait_suspend(self, thread, frame, event, arg, trace_suspend_type, from_t seq = info.pydev_message cmd = self.cmd_factory.make_set_next_stmnt_status_message(seq, stop, response_msg) self.writer.add_command(cmd) - info.pydev_message = '' + info.pydev_message = "" if stop: # Uninstall the current frames tracker before running it. @@ -2273,10 +2336,7 @@ def _do_wait_suspend(self, thread, frame, event, arg, trace_suspend_type, from_t if PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING: info.pydev_use_scoped_step_frame = False - if info.pydev_step_cmd in ( - CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, - CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE - ): + if info.pydev_step_cmd in (CMD_STEP_OVER, CMD_STEP_OVER_MY_CODE, CMD_STEP_INTO, CMD_STEP_INTO_MY_CODE): # i.e.: We're stepping: check if the stepping should be scoped (i.e.: in ipython # each line is executed separately in a new frame, in which case we need to consider # the next line as if it was still in the same frame). @@ -2285,7 +2345,7 @@ def _do_wait_suspend(self, thread, frame, event, arg, trace_suspend_type, from_t f = f.f_back if f and f.f_code.co_name == PYDEVD_IPYTHON_CONTEXT[2]: info.pydev_use_scoped_step_frame = True - pydev_log.info('Using (ipython) scoped stepping.') + pydev_log.info("Using (ipython) scoped stepping.") del f del frame @@ -2308,7 +2368,7 @@ def do_stop_on_unhandled_exception(self, thread, frame, frames_byid, arg): self.send_caught_exception_stack(thread, arg, id(frame)) try: self.set_suspend(thread, CMD_ADD_EXCEPTION_BREAK) - self.do_wait_suspend(thread, frame, 'exception', arg, EXCEPTION_TYPE_UNHANDLED) + self.do_wait_suspend(thread, frame, "exception", arg, EXCEPTION_TYPE_UNHANDLED) except: self.send_caught_exception_stack_proceeded(thread) except: @@ -2318,7 +2378,7 @@ def do_stop_on_unhandled_exception(self, thread, frame, frames_byid, arg): frame = None def set_trace_for_frame_and_parents(self, thread_ident: Optional[int], frame, **kwargs): - disable = kwargs.pop('disable', False) + disable = kwargs.pop("disable", False) assert not kwargs DEBUG = True # 'defaulttags' in frame.f_code.co_filename @@ -2335,32 +2395,32 @@ def set_trace_for_frame_and_parents(self, thread_ident: Optional[int], frame, ** if file_type is None: if disable: if DEBUG: - pydev_log.debug('Disable tracing of frame: %s - %s', frame.f_code.co_filename, frame.f_code.co_name) + pydev_log.debug("Disable tracing of frame: %s - %s", frame.f_code.co_filename, frame.f_code.co_name) pydevd_sys_monitoring.disable_code_tracing(frame.f_code) else: if DEBUG: - pydev_log.debug('Set tracing of frame: %s - %s', frame.f_code.co_filename, frame.f_code.co_name) + pydev_log.debug("Set tracing of frame: %s - %s", frame.f_code.co_filename, frame.f_code.co_name) pydevd_sys_monitoring.enable_code_tracing(thread_ident, frame.f_code, frame) else: if DEBUG: - pydev_log.debug('SKIP set tracing of frame: %s - %s', frame.f_code.co_filename, frame.f_code.co_name) + pydev_log.debug("SKIP set tracing of frame: %s - %s", frame.f_code.co_filename, frame.f_code.co_name) else: # Not using sys.monitoring. if file_type is None: if disable: if DEBUG: - pydev_log.debug('Disable tracing of frame: %s - %s', frame.f_code.co_filename, frame.f_code.co_name) + pydev_log.debug("Disable tracing of frame: %s - %s", frame.f_code.co_filename, frame.f_code.co_name) if frame.f_trace is not None and frame.f_trace is not NO_FTRACE: frame.f_trace = NO_FTRACE elif frame.f_trace is not self.trace_dispatch: if DEBUG: - pydev_log.debug('Set tracing of frame: %s - %s', frame.f_code.co_filename, frame.f_code.co_name) + pydev_log.debug("Set tracing of frame: %s - %s", frame.f_code.co_filename, frame.f_code.co_name) frame.f_trace = self.trace_dispatch else: if DEBUG: - pydev_log.debug('SKIP set tracing of frame: %s - %s', frame.f_code.co_filename, frame.f_code.co_name) + pydev_log.debug("SKIP set tracing of frame: %s - %s", frame.f_code.co_filename, frame.f_code.co_name) frame = frame.f_back @@ -2411,19 +2471,18 @@ def get_pydb_daemon_threads_to_wait(): while time.time() < started_at + timeout: if len(get_pydb_daemon_threads_to_wait()) == 0: break - time.sleep(1 / 10.) + time.sleep(1 / 10.0) else: thread_names = [t.name for t in get_pydb_daemon_threads_to_wait()] if thread_names: - pydev_log.debug("The following pydb threads may not have finished correctly: %s", - ', '.join(thread_names)) + pydev_log.debug("The following pydb threads may not have finished correctly: %s", ", ".join(thread_names)) finally: self._wait_for_threads_to_finish_called_event.set() except: pydev_log.exception() - def dispose_and_kill_all_pydevd_threads(self, wait=True, timeout=.5): - ''' + def dispose_and_kill_all_pydevd_threads(self, wait=True, timeout=0.5): + """ When this method is called we finish the debug session, terminate threads and if this was registered as the global instance, unregister it -- afterwards it should be possible to create a new instance and set as global to start @@ -2434,12 +2493,14 @@ def dispose_and_kill_all_pydevd_threads(self, wait=True, timeout=.5): (based on the available timeout). Note that this must be thread-safe and if one thread is waiting the other thread should also wait. - ''' + """ try: back_frame = sys._getframe().f_back pydev_log.debug( 'PyDB.dispose_and_kill_all_pydevd_threads (called from: File "%s", line %s, in %s)', - back_frame.f_code.co_filename, back_frame.f_lineno, back_frame.f_code.co_name + back_frame.f_code.co_filename, + back_frame.f_lineno, + back_frame.f_code.co_name, ) back_frame = None with self._disposed_lock: @@ -2469,7 +2530,7 @@ def dispose_and_kill_all_pydevd_threads(self, wait=True, timeout=.5): pydb_daemon_threads = set(self.created_pydb_daemon_threads) for t in pydb_daemon_threads: - if hasattr(t, 'do_kill_pydev_thread'): + if hasattr(t, "do_kill_pydev_thread"): pydev_log.debug("PyDB.dispose_and_kill_all_pydevd_threads killing thread: %s", t) t.do_kill_pydev_thread() @@ -2492,7 +2553,7 @@ def dispose_and_kill_all_pydevd_threads(self, wait=True, timeout=.5): pydev_log.debug("PyDB.dispose_and_kill_all_pydevd_threads: finished") def prepare_to_run(self): - ''' Shared code to prepare debugging by installing traces and registering threads ''' + """Shared code to prepare debugging by installing traces and registering threads""" self.patch_threads() self.start_auxiliary_daemon_threads() @@ -2507,20 +2568,21 @@ def patch_threads(self): pass from _pydev_bundle.pydev_monkey import patch_thread_modules + patch_thread_modules() def run(self, file, globals=None, locals=None, is_module=False, set_trace=True): module_name = None - entry_point_fn = '' + entry_point_fn = "" if is_module: # When launching with `python -m `, python automatically adds # an empty path to the PYTHONPATH which resolves files in the current # directory, so, depending how pydevd itself is launched, we may need # to manually add such an entry to properly resolve modules in the # current directory (see: https://github.com/Microsoft/ptvsd/issues/1010). - if '' not in sys.path: - sys.path.insert(0, '') - file, _, entry_point_fn = file.partition(':') + if "" not in sys.path: + sys.path.insert(0, "") + file, _, entry_point_fn = file.partition(":") module_name = file filename = get_fullname(file) if filename is None: @@ -2538,14 +2600,14 @@ def run(self, file, globals=None, locals=None, is_module=False, set_trace=True): else: file = filename mod_dir = os.path.dirname(filename) - main_py = os.path.join(mod_dir, '__main__.py') - main_pyc = os.path.join(mod_dir, '__main__.pyc') - if filename.endswith('__init__.pyc'): + main_py = os.path.join(mod_dir, "__main__.py") + main_pyc = os.path.join(mod_dir, "__main__.pyc") + if filename.endswith("__init__.pyc"): if os.path.exists(main_pyc): filename = main_pyc elif os.path.exists(main_py): filename = main_py - elif filename.endswith('__init__.py'): + elif filename.endswith("__init__.py"): if os.path.exists(main_pyc) and not os.path.exists(main_py): filename = main_pyc elif os.path.exists(main_py): @@ -2554,16 +2616,16 @@ def run(self, file, globals=None, locals=None, is_module=False, set_trace=True): sys.argv[0] = filename if os.path.isdir(file): - new_target = os.path.join(file, '__main__.py') + new_target = os.path.join(file, "__main__.py") if os.path.isfile(new_target): file = new_target m = None if globals is None: - m = save_main_module(file, 'pydevd') + m = save_main_module(file, "pydevd") globals = m.__dict__ try: - globals['__builtins__'] = __builtins__ + globals["__builtins__"] = __builtins__ except NameError: pass # Not there on Jython... @@ -2579,7 +2641,7 @@ def run(self, file, globals=None, locals=None, is_module=False, set_trace=True): # I think this is an ugly hack, bug it works (seems to) for the bug that says that sys.path should be the same in # debug and run. - if sys.path[0] != '' and m is not None and m.__file__.startswith(sys.path[0]): + if sys.path[0] != "" and m is not None and m.__file__.startswith(sys.path[0]): # print >> sys.stderr, 'Deleting: ', sys.path[0] del sys.path[0] @@ -2614,7 +2676,7 @@ def run(self, file, globals=None, locals=None, is_module=False, set_trace=True): except: pydev_log.exception("Matplotlib support in debugger failed") - if hasattr(sys, 'exc_clear'): + if hasattr(sys, "exc_clear"): # we should clean exception information in Python 2, before user's code execution sys.exc_clear() @@ -2628,12 +2690,12 @@ def run(self, file, globals=None, locals=None, is_module=False, set_trace=True): return self._exec(is_module, entry_point_fn, module_name, file, globals, locals) def _exec(self, is_module, entry_point_fn, module_name, file, globals, locals): - ''' + """ This function should have frames tracked by unhandled exceptions (the `_exec` name is important). - ''' + """ t = threading.current_thread() # Keep in 't' local variable to be accessed afterwards from frame.f_locals. if not is_module: - globals = pydevd_runpy.run_path(file, globals, '__main__') + globals = pydevd_runpy.run_path(file, globals, "__main__") else: # treat ':' as a separator between module and entry point function # if there is no entry point we run we same as with -m switch. Otherwise we perform @@ -2652,8 +2714,10 @@ def wait_for_commands(self, globals): thread = threading.current_thread() from _pydevd_bundle import pydevd_frame_utils - frame = pydevd_frame_utils.Frame(None, -1, pydevd_frame_utils.FCode("Console", - os.path.abspath(os.path.dirname(__file__))), globals, globals) + + frame = pydevd_frame_utils.Frame( + None, -1, pydevd_frame_utils.FCode("Console", os.path.abspath(os.path.dirname(__file__))), globals, globals + ) thread_id = get_current_thread_id(thread) self.add_fake_frame(thread_id, id(frame), frame) @@ -2670,24 +2734,23 @@ def wait_for_commands(self, globals): class IDAPMessagesListener(object): - def before_send(self, message_as_dict): - ''' + """ Called just before a message is sent to the IDE. :type message_as_dict: dict - ''' + """ def after_receive(self, message_as_dict): - ''' + """ Called just after a message is received from the IDE. :type message_as_dict: dict - ''' + """ def add_dap_messages_listener(dap_messages_listener): - ''' + """ Adds a listener for the DAP (debug adapter protocol) messages. :type dap_messages_listener: IDAPMessagesListener @@ -2696,16 +2759,16 @@ def add_dap_messages_listener(dap_messages_listener): :note: the notifications are sent from threads and they are not synchronized (so, it's possible that a message is sent and received from different threads at the same time). - ''' + """ py_db = get_global_debugger() if py_db is None: - raise AssertionError('PyDB is still not setup.') + raise AssertionError("PyDB is still not setup.") py_db.add_dap_messages_listener(dap_messages_listener) def send_json_message(msg): - ''' + """ API to send some custom json message. :param dict|pydevd_schema.BaseSchema msg: @@ -2713,7 +2776,7 @@ def send_json_message(msg): :return bool: True if the message was added to the queue to be sent and False otherwise. - ''' + """ py_db = get_global_debugger() if py_db is None: return False @@ -2729,11 +2792,12 @@ def send_json_message(msg): def enable_qt_support(qt_support_mode): from _pydev_bundle import pydev_monkey_qt + pydev_monkey_qt.patch_qt(qt_support_mode) def start_dump_threads_thread(filename_template, timeout, recurrent): - ''' + """ Helper to dump threads after a timeout. :param filename_template: @@ -2743,9 +2807,8 @@ def start_dump_threads_thread(filename_template, timeout, recurrent): The timeout (in seconds) for the dump. :param recurrent: If True we'll keep on doing thread dumps. - ''' - assert filename_template.count('%s') == 1, \ - 'Expected one %%s to appear in: %s' % (filename_template,) + """ + assert filename_template.count("%s") == 1, "Expected one %%s to appear in: %s" % (filename_template,) def _threads_on_timeout(): try: @@ -2756,7 +2819,7 @@ def _threads_on_timeout(): os.makedirs(os.path.dirname(filename)) except Exception: pass - with open(filename, 'w') as stream: + with open(filename, "w") as stream: dump_threads(stream) if not recurrent: return @@ -2769,25 +2832,25 @@ def _threads_on_timeout(): def dump_threads(stream=None): - ''' + """ Helper to dump thread info (default is printing to stderr). - ''' + """ pydevd_utils.dump_threads(stream) def usage(doExit=0): - sys.stdout.write('Usage:\n') - sys.stdout.write('pydevd.py --port N [(--client hostname) | --server] --file executable [file_options]\n') + sys.stdout.write("Usage:\n") + sys.stdout.write("pydevd.py --port N [(--client hostname) | --server] --file executable [file_options]\n") if doExit: sys.exit(0) def _init_stdout_redirect(): - pydevd_io.redirect_stream_to_pydb_io_messages(std='stdout') + pydevd_io.redirect_stream_to_pydb_io_messages(std="stdout") def _init_stderr_redirect(): - pydevd_io.redirect_stream_to_pydb_io_messages(std='stderr') + pydevd_io.redirect_stream_to_pydb_io_messages(std="stderr") def _enable_attach( @@ -2797,8 +2860,8 @@ def _enable_attach( patch_multiprocessing=False, access_token=None, client_access_token=None, - ): - ''' +): + """ Starts accepting connections at the given host/port. The debugger will not be initialized nor configured, it'll only start accepting connections (and will have the tracing setup in this thread). @@ -2807,13 +2870,13 @@ def _enable_attach( :param address: (host, port) :type address: tuple(str, int) - ''' + """ host = address[0] port = int(address[1]) if SetupHolder.setup is not None: - if port != SetupHolder.setup['port']: - raise AssertionError('Unable to listen in port: %s (already listening in port: %s)' % (port, SetupHolder.setup['port'])) + if port != SetupHolder.setup["port"]: + raise AssertionError("Unable to listen in port: %s (already listening in port: %s)" % (port, SetupHolder.setup["port"])) settrace( host=host, port=port, @@ -2833,30 +2896,30 @@ def _enable_attach( def _wait_for_attach(cancel=None): - ''' + """ Meant to be called after _enable_attach() -- the current thread will only unblock after a connection is in place and the DAP (Debug Adapter Protocol) sends the ConfigurationDone request. - ''' + """ py_db = get_global_debugger() if py_db is None: - raise AssertionError('Debugger still not created. Please use _enable_attach() before using _wait_for_attach().') + raise AssertionError("Debugger still not created. Please use _enable_attach() before using _wait_for_attach().") py_db.block_until_configuration_done(cancel=cancel) def _is_attached(): - ''' + """ Can be called any time to check if the connection was established and the DAP (Debug Adapter Protocol) has sent the ConfigurationDone request. - ''' + """ py_db = get_global_debugger() return (py_db is not None) and py_db.is_attached() -#======================================================================================================================= +# ======================================================================================================================= # settrace -#======================================================================================================================= +# ======================================================================================================================= def settrace( host=None, stdout_to_server=False, @@ -2874,9 +2937,9 @@ def settrace( access_token=None, client_access_token=None, notify_stdin=True, - **kwargs - ): - '''Sets the tracing function with the pydev debug function and initializes needed facilities. + **kwargs, +): + """Sets the tracing function with the pydev debug function and initializes needed facilities. :param host: the user may specify another host, if the debug server is not in the same machine (default is the local host) @@ -2928,13 +2991,13 @@ def settrace( as an input to the process or as a command to be evaluated. Note that parallel-python has issues with this (because it tries to assert that sys.stdin is of a given type instead of just checking that it has what it needs). - ''' + """ - stdout_to_server = stdout_to_server or kwargs.get('stdoutToServer', False) # Backward compatibility - stderr_to_server = stderr_to_server or kwargs.get('stderrToServer', False) # Backward compatibility + stdout_to_server = stdout_to_server or kwargs.get("stdoutToServer", False) # Backward compatibility + stderr_to_server = stderr_to_server or kwargs.get("stderrToServer", False) # Backward compatibility # Internal use (may be used to set the setup info directly for subprocesess). - __setup_holder__ = kwargs.get('__setup_holder__') + __setup_holder__ = kwargs.get("__setup_holder__") with _set_trace_lock: _locked_settrace( @@ -2977,7 +3040,7 @@ def _locked_settrace( client_access_token, __setup_holder__, notify_stdin, - ): +): if patch_multiprocessing: try: from _pydev_bundle import pydev_monkey @@ -2988,6 +3051,7 @@ def _locked_settrace( if host is None: from _pydev_bundle import pydev_localhost + host = pydev_localhost.get_localhost() global _global_redirect_stdout_to_server @@ -3002,20 +3066,20 @@ def _locked_settrace( if SetupHolder.setup is None: setup = { - 'client': host, # dispatch expects client to be set to the host address when server is False - 'server': False, - 'port': int(port), - 'multiprocess': patch_multiprocessing, - 'skip-notify-stdin': not notify_stdin, + "client": host, # dispatch expects client to be set to the host address when server is False + "server": False, + "port": int(port), + "multiprocess": patch_multiprocessing, + "skip-notify-stdin": not notify_stdin, } SetupHolder.setup = setup if access_token is not None: py_db.authentication.access_token = access_token - SetupHolder.setup['access-token'] = access_token + SetupHolder.setup["access-token"] = access_token if client_access_token is not None: py_db.authentication.client_access_token = client_access_token - SetupHolder.setup['client-access-token'] = client_access_token + SetupHolder.setup["client-access-token"] = client_access_token if block_until_connected: py_db.connect(host, port) # Note: connect can raise error. @@ -3126,6 +3190,7 @@ def stoptrace(): pass from _pydev_bundle.pydev_monkey import undo_patch_thread_modules + undo_patch_thread_modules() # Either or both standard streams can be closed at this point, @@ -3146,7 +3211,6 @@ def stoptrace(): class Dispatcher(object): - def __init__(self): self.port = None @@ -3166,7 +3230,6 @@ def close(self): class DispatchReader(ReaderThread): - def __init__(self, dispatcher): self.dispatcher = dispatcher @@ -3210,8 +3273,8 @@ def process_command(self, cmd_id, seq, text): def dispatch(): setup = SetupHolder.setup - host = setup['client'] - port = setup['port'] + host = setup["client"] + port = setup["port"] if DISPATCH_APPROACH == DISPATCH_APPROACH_EXISTING_CONNECTION: dispatcher = Dispatcher() try: @@ -3223,10 +3286,11 @@ def dispatch(): def settrace_forked(setup_tracing=True): - ''' + """ When creating a fork from a process in the debugger, we need to reset the whole debugger environment! - ''' + """ from _pydevd_bundle.pydevd_constants import GlobalDebuggerHolder + py_db = GlobalDebuggerHolder.global_dbg if py_db is not None: py_db.created_pydb_daemon_threads = {} # Just making sure we won't touch those (paused) threads. @@ -3243,14 +3307,16 @@ def settrace_forked(setup_tracing=True): # i.e.: Get the ppid at this point as it just changed. # If we later do an exec() it should remain the same ppid. setup[pydevd_constants.ARGUMENT_PPID] = PyDevdAPI().get_ppid() - access_token = setup.get('access-token') - client_access_token = setup.get('client-access-token') + access_token = setup.get("access-token") + client_access_token = setup.get("client-access-token") if setup_tracing: from _pydevd_frame_eval.pydevd_frame_eval_main import clear_thread_local_info + host, port = dispatch() import pydevd_tracing + pydevd_tracing.restore_sys_set_trace_func() if setup_tracing: @@ -3261,20 +3327,20 @@ def settrace_forked(setup_tracing=True): clear_thread_local_info() settrace( - host, - port=port, - suspend=False, - trace_only_current_thread=False, - overwrite_prev_trace=True, - patch_multiprocessing=True, - access_token=access_token, - client_access_token=client_access_token, + host, + port=port, + suspend=False, + trace_only_current_thread=False, + overwrite_prev_trace=True, + patch_multiprocessing=True, + access_token=access_token, + client_access_token=client_access_token, ) @contextmanager def skip_subprocess_arg_patch(): - ''' + """ May be used to skip the monkey-patching that pydevd does to skip changing arguments to embed the debugger into child processes. @@ -3282,14 +3348,15 @@ def skip_subprocess_arg_patch(): with pydevd.skip_subprocess_arg_patch(): subprocess.call(...) - ''' + """ from _pydev_bundle import pydev_monkey + with pydev_monkey.skip_subprocess_arg_patch(): yield def add_dont_terminate_child_pid(pid): - ''' + """ May be used to ask pydevd to skip the termination of some process when it's asked to terminate (debug adapter protocol only). @@ -3300,14 +3367,13 @@ def add_dont_terminate_child_pid(pid): process = subprocess.Popen(...) pydevd.add_dont_terminate_child_pid(process.pid) - ''' + """ py_db = get_global_debugger() if py_db is not None: py_db.dont_terminate_child_pids.add(pid) class SetupHolder: - setup = None @@ -3316,21 +3382,22 @@ def apply_debugger_options(setup_options): :type setup_options: dict[str, bool] """ - default_options = {'save-signatures': False, 'qt-support': ''} + default_options = {"save-signatures": False, "qt-support": ""} default_options.update(setup_options) setup_options = default_options debugger = get_global_debugger() - if setup_options['save-signatures']: + if setup_options["save-signatures"]: if pydevd_vm_type.get_vm_type() == pydevd_vm_type.PydevdVmType.JYTHON: sys.stderr.write("Collecting run-time type information is not supported for Jython\n") else: # Only import it if we're going to use it! from _pydevd_bundle.pydevd_signature import SignatureFactory + debugger.signature_factory = SignatureFactory() - if setup_options['qt-support']: - enable_qt_support(setup_options['qt-support']) + if setup_options["qt-support"]: + enable_qt_support(setup_options["qt-support"]) @call_only_once @@ -3339,10 +3406,10 @@ def patch_stdin(): def _internal_patch_stdin(py_db=None, sys=None, getpass_mod=None): - ''' + """ Note: don't use this function directly, use `patch_stdin()` instead. (this function is only meant to be used on test-cases to avoid patching the actual globals). - ''' + """ # Patch stdin so that we notify when readline() is called. original_sys_stdin = sys.stdin debug_console_stdin = DebugConsoleStdIn(py_db, original_sys_stdin) @@ -3363,6 +3430,7 @@ def getpass(*args, **kwargs): getpass_mod.getpass = getpass + # Dispatch on_debugger_modules_loaded here, after all primary py_db modules are loaded @@ -3370,8 +3438,8 @@ def getpass(*args, **kwargs): handler.on_debugger_modules_loaded(debugger_version=__version__) -def log_to(log_file:str, log_level=3) -> None: - ''' +def log_to(log_file: str, log_level=3) -> None: + """ In pydevd it's possible to log by setting the following environment variables: PYDEVD_DEBUG=1 (sets the default log level to 3 along with other default options) @@ -3385,7 +3453,7 @@ def log_to(log_file:str, log_level=3) -> None: pydevd is still doing its imports and not just after this method is called, but on cases where this is hard to do this function may be called to set the tracing after pydevd itself is already imported. - ''' + """ pydev_log.log_to(log_file, log_level) @@ -3397,45 +3465,45 @@ def _log_initial_info(): pydev_log.debug("Using gevent mode: %s / imported gevent module support: %s", SUPPORT_GEVENT, bool(pydevd_gevent_integration)) -def config(protocol='', debug_mode='', preimport=''): - pydev_log.debug('Config: protocol: %s, debug_mode: %s, preimport: %s', protocol, debug_mode, preimport) +def config(protocol="", debug_mode="", preimport=""): + pydev_log.debug("Config: protocol: %s, debug_mode: %s, preimport: %s", protocol, debug_mode, preimport) PydevdCustomization.DEFAULT_PROTOCOL = protocol PydevdCustomization.DEBUG_MODE = debug_mode PydevdCustomization.PREIMPORT = preimport -#======================================================================================================================= +# ======================================================================================================================= # main -#======================================================================================================================= +# ======================================================================================================================= def main(): - # parse the command line. --file is our last argument that is required _log_initial_info() original_argv = sys.argv[:] try: from _pydevd_bundle.pydevd_command_line_handling import process_command_line + setup = process_command_line(sys.argv) SetupHolder.setup = setup except ValueError: pydev_log.exception() usage(1) - preimport = setup.get('preimport') + preimport = setup.get("preimport") if preimport: pydevd_defaults.PydevdCustomization.PREIMPORT = preimport - debug_mode = setup.get('debug-mode') + debug_mode = setup.get("debug-mode") if debug_mode: pydevd_defaults.PydevdCustomization.DEBUG_MODE = debug_mode - log_trace_level = setup.get('log-level') + log_trace_level = setup.get("log-level") # Note: the logging info could've been changed (this would happen if this is a # subprocess and the value in the environment variable does not match the value in the # argument because the user used `pydevd.log_to` instead of supplying the environment # variable). If this is the case, update the logging info and re-log some information # in the new target. - new_debug_file = setup.get('log-file') + new_debug_file = setup.get("log-file") if new_debug_file and DebugInfoHolder.PYDEVD_DEBUG_FILE != new_debug_file: # The debug file can't be set directly, we need to use log_to() so that the a # new stream is actually created for the new file. @@ -3445,23 +3513,23 @@ def main(): elif log_trace_level is not None: # The log file was not specified DebugInfoHolder.DEBUG_TRACE_LEVEL = log_trace_level - pydev_log.debug('Original sys.argv: %s', original_argv) + pydev_log.debug("Original sys.argv: %s", original_argv) - if setup['print-in-debugger-startup']: + if setup["print-in-debugger-startup"]: try: - pid = ' (pid: %s)' % os.getpid() + pid = " (pid: %s)" % os.getpid() except: - pid = '' + pid = "" sys.stderr.write("pydev debugger: starting%s\n" % pid) - pydev_log.debug("Executing file %s", setup['file']) + pydev_log.debug("Executing file %s", setup["file"]) pydev_log.debug("arguments: %s", (sys.argv,)) - pydevd_vm_type.setup_type(setup.get('vm_type', None)) + pydevd_vm_type.setup_type(setup.get("vm_type", None)) - port = setup['port'] - host = setup['client'] - f = setup['file'] + port = setup["port"] + host = setup["client"] + f = setup["file"] fix_app_engine_debug = False debugger = get_global_debugger() @@ -3473,10 +3541,10 @@ def main(): except: pass # Not usable on jython 2.1 else: - if setup['multiprocess']: # PyDev + if setup["multiprocess"]: # PyDev pydev_monkey.patch_new_process_functions() - elif setup['multiproc']: # PyCharm + elif setup["multiproc"]: # PyCharm pydev_log.debug("Started in multiproc mode\n") global DISPATCH_APPROACH DISPATCH_APPROACH = DISPATCH_APPROACH_EXISTING_CONNECTION @@ -3504,20 +3572,20 @@ def main(): pydev_log.exception("Error patching process functions.") # Only do this patching if we're not running with multiprocess turned on. - if f.find('dev_appserver.py') != -1: - if os.path.basename(f).startswith('dev_appserver.py'): + if f.find("dev_appserver.py") != -1: + if os.path.basename(f).startswith("dev_appserver.py"): appserver_dir = os.path.dirname(f) - version_file = os.path.join(appserver_dir, 'VERSION') + version_file = os.path.join(appserver_dir, "VERSION") if os.path.exists(version_file): try: - stream = open(version_file, 'r') + stream = open(version_file, "r") try: for line in stream.read().splitlines(): line = line.strip() - if line.startswith('release:'): + if line.startswith("release:"): line = line[8:].strip() - version = line.replace('"', '') - version = version.split('.') + version = line.replace('"', "") + version = version.split(".") if int(version[0]) > 1: fix_app_engine_debug = True @@ -3546,17 +3614,18 @@ def main(): # # itself to be able to benefit from seeing the tasklets created before the remote debugger is attached. from _pydevd_bundle import pydevd_stackless + pydevd_stackless.patch_stackless() except: # It's ok not having stackless there... try: - if hasattr(sys, 'exc_clear'): + if hasattr(sys, "exc_clear"): sys.exc_clear() # the exception information should be cleaned in Python 2 except: pass - is_module = setup['module'] - if not setup['skip-notify-stdin']: + is_module = setup["module"] + if not setup["skip-notify-stdin"]: patch_stdin() if setup[pydevd_constants.ARGUMENT_JSON_PROTOCOL]: @@ -3571,32 +3640,36 @@ def main(): elif setup[pydevd_constants.ARGUMENT_QUOTED_LINE_PROTOCOL]: PyDevdAPI().set_protocol(debugger, 0, pydevd_constants.QUOTED_LINE_PROTOCOL) - access_token = setup['access-token'] + access_token = setup["access-token"] if access_token: debugger.authentication.access_token = access_token - client_access_token = setup['client-access-token'] + client_access_token = setup["client-access-token"] if client_access_token: debugger.authentication.client_access_token = client_access_token if fix_app_engine_debug: sys.stderr.write("pydev debugger: google app engine integration enabled\n") curr_dir = os.path.dirname(__file__) - app_engine_startup_file = os.path.join(curr_dir, 'pydev_app_engine_debug_startup.py') + app_engine_startup_file = os.path.join(curr_dir, "pydev_app_engine_debug_startup.py") - sys.argv.insert(1, '--python_startup_script=' + app_engine_startup_file) + sys.argv.insert(1, "--python_startup_script=" + app_engine_startup_file) import json - setup['pydevd'] = __file__ - sys.argv.insert(2, '--python_startup_args=%s' % json.dumps(setup),) - sys.argv.insert(3, '--automatic_restart=no') - sys.argv.insert(4, '--max_module_instances=1') + + setup["pydevd"] = __file__ + sys.argv.insert( + 2, + "--python_startup_args=%s" % json.dumps(setup), + ) + sys.argv.insert(3, "--automatic_restart=no") + sys.argv.insert(4, "--max_module_instances=1") # Run the dev_appserver - debugger.run(setup['file'], None, None, is_module, set_trace=False) + debugger.run(setup["file"], None, None, is_module, set_trace=False) else: - if setup['save-threading']: + if setup["save-threading"]: debugger.thread_analyser = ThreadingLogger() - if setup['save-asyncio']: + if setup["save-asyncio"]: debugger.asyncio_analyser = AsyncioLogger() apply_debugger_options(setup) @@ -3608,11 +3681,11 @@ def main(): pydev_log.exception() sys.exit(1) - globals = debugger.run(setup['file'], None, None, is_module) + globals = debugger.run(setup["file"], None, None, is_module) - if setup['cmd-line']: + if setup["cmd-line"]: debugger.wait_for_commands(globals) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/pydevd_attach_to_process/_always_live_program.py b/pydevd_attach_to_process/_always_live_program.py index 6369508ed..78ad8ac56 100644 --- a/pydevd_attach_to_process/_always_live_program.py +++ b/pydevd_attach_to_process/_always_live_program.py @@ -1,32 +1,40 @@ import sys import struct -print('Executable: %s' % sys.executable) + +print("Executable: %s" % sys.executable) import os + + def loop_in_thread(): while True: import time - time.sleep(.5) - sys.stdout.write('#') + + time.sleep(0.5) + sys.stdout.write("#") sys.stdout.flush() + import threading + threading.Thread(target=loop_in_thread).start() def is_python_64bit(): - return (struct.calcsize('P') == 8) + return struct.calcsize("P") == 8 -print('Is 64: %s' % is_python_64bit()) -if __name__ == '__main__': - print('pid:%s' % (os.getpid())) +print("Is 64: %s" % is_python_64bit()) + +if __name__ == "__main__": + print("pid:%s" % (os.getpid())) i = 0 while True: i += 1 import time - time.sleep(.5) - sys.stdout.write('.') + + time.sleep(0.5) + sys.stdout.write(".") sys.stdout.flush() if i % 40 == 0: - sys.stdout.write('\n') + sys.stdout.write("\n") sys.stdout.flush() diff --git a/pydevd_attach_to_process/_check.py b/pydevd_attach_to_process/_check.py index 2dbeafe3c..979b6f7ac 100644 --- a/pydevd_attach_to_process/_check.py +++ b/pydevd_attach_to_process/_check.py @@ -1,2 +1,3 @@ import add_code_to_python_process + print(add_code_to_python_process.run_python_code(3736, "print(20)", connect_debugger_tracing=False)) diff --git a/pydevd_attach_to_process/_test_attach_to_process.py b/pydevd_attach_to_process/_test_attach_to_process.py index daeee93f4..c934dd2af 100644 --- a/pydevd_attach_to_process/_test_attach_to_process.py +++ b/pydevd_attach_to_process/_test_attach_to_process.py @@ -1,9 +1,11 @@ import subprocess import sys + print(sys.executable) -if __name__ == '__main__': - p = subprocess.Popen([sys.executable, '-u', '_always_live_program.py']) +if __name__ == "__main__": + p = subprocess.Popen([sys.executable, "-u", "_always_live_program.py"]) import attach_pydevd - attach_pydevd.main(attach_pydevd.process_command_line(['--pid', str(p.pid), '--protocol', 'http'])) + + attach_pydevd.main(attach_pydevd.process_command_line(["--pid", str(p.pid), "--protocol", "http"])) p.wait() diff --git a/pydevd_attach_to_process/_test_attach_to_process_linux.py b/pydevd_attach_to_process/_test_attach_to_process_linux.py index 842e71a13..0bc7729bb 100644 --- a/pydevd_attach_to_process/_test_attach_to_process_linux.py +++ b/pydevd_attach_to_process/_test_attach_to_process_linux.py @@ -1,4 +1,4 @@ -''' +""" This module is just for testing concepts. It should be erased later on. Experiments: @@ -17,58 +17,59 @@ // call dlopen("/home/fabioz/Desktop/dev/PyDev.Debugger/pydevd_attach_to_process/linux/attach_linux.so", 1|8) // call dlsym($1, "hello") // call hello() -''' +""" import subprocess import sys import os import time -if __name__ == '__main__': - - linux_dir = os.path.join(os.path.dirname(__file__), 'linux') +if __name__ == "__main__": + linux_dir = os.path.join(os.path.dirname(__file__), "linux") os.chdir(linux_dir) - so_location = os.path.join(linux_dir, 'attach_linux.so') + so_location = os.path.join(linux_dir, "attach_linux.so") try: os.remove(so_location) except: pass - subprocess.call('g++ -shared -o attach_linux.so -fPIC -nostartfiles attach_linux.c'.split()) - print('Finished compiling') - assert os.path.exists('/home/fabioz/Desktop/dev/PyDev.Debugger/pydevd_attach_to_process/linux/attach_linux.so') + subprocess.call("g++ -shared -o attach_linux.so -fPIC -nostartfiles attach_linux.c".split()) + print("Finished compiling") + assert os.path.exists("/home/fabioz/Desktop/dev/PyDev.Debugger/pydevd_attach_to_process/linux/attach_linux.so") os.chdir(os.path.dirname(linux_dir)) -# import attach_pydevd -# attach_pydevd.main(attach_pydevd.process_command_line(['--pid', str(p.pid)])) - p = subprocess.Popen([sys.executable, '-u', '_always_live_program.py']) - print('Size of file: %s' % (os.stat(so_location).st_size)) + # import attach_pydevd + # attach_pydevd.main(attach_pydevd.process_command_line(['--pid', str(p.pid)])) + p = subprocess.Popen([sys.executable, "-u", "_always_live_program.py"]) + print("Size of file: %s" % (os.stat(so_location).st_size)) # (gdb) set architecture # Requires an argument. Valid arguments are i386, i386:x86-64, i386:x64-32, i8086, i386:intel, i386:x86-64:intel, i386:x64-32:intel, i386:nacl, i386:x86-64:nacl, i386:x64-32:nacl, auto. cmd = [ - 'gdb', - '--pid', + "gdb", + "--pid", str(p.pid), - '--batch', + "--batch", ] - arch = 'i386:x86-64' + arch = "i386:x86-64" if arch: cmd.extend(["--eval-command='set architecture %s'" % arch]) - cmd.extend([ - "--eval-command='call dlopen(\"/home/fabioz/Desktop/dev/PyDev.Debugger/pydevd_attach_to_process/linux/attach_linux.so\", 2)'", - "--eval-command='call (int)DoAttach(1, \"print(\\\"check11111check\\\")\", 0)'", - # "--eval-command='call (int)SetSysTraceFunc(1, 0)'", -- never call this way, always use "--command='...gdb_threads_settrace.py'", - # So that threads are all stopped! - ]) + cmd.extend( + [ + "--eval-command='call dlopen(\"/home/fabioz/Desktop/dev/PyDev.Debugger/pydevd_attach_to_process/linux/attach_linux.so\", 2)'", + '--eval-command=\'call (int)DoAttach(1, "print(\\"check11111check\\")", 0)\'', + # "--eval-command='call (int)SetSysTraceFunc(1, 0)'", -- never call this way, always use "--command='...gdb_threads_settrace.py'", + # So that threads are all stopped! + ] + ) - print(' '.join(cmd)) - time.sleep(.5) + print(" ".join(cmd)) + time.sleep(0.5) env = os.environ.copy() - env.pop('PYTHONIOENCODING', None) - env.pop('PYTHONPATH', None) - p2 = subprocess.call(' '.join(cmd), env=env, shell=True) + env.pop("PYTHONIOENCODING", None) + env.pop("PYTHONPATH", None) + p2 = subprocess.call(" ".join(cmd), env=env, shell=True) time.sleep(1) p.kill() diff --git a/pydevd_attach_to_process/add_code_to_python_process.py b/pydevd_attach_to_process/add_code_to_python_process.py index 5fd7be66c..4edb46948 100644 --- a/pydevd_attach_to_process/add_code_to_python_process.py +++ b/pydevd_attach_to_process/add_code_to_python_process.py @@ -1,4 +1,4 @@ -r''' +r""" Copyright: Brainwy Software Ltda. License: EPL. @@ -64,7 +64,7 @@ To build the dlls needed on windows, visual studio express 13 was used (see compile_dll.bat) See: attach_pydevd.py to attach the pydev debugger to a running python process. -''' +""" # Note: to work with nasm compiling asm to code and decompiling to see asm with shellcode: # x:\nasm\nasm-2.07-win32\nasm-2.07\nasm.exe @@ -94,17 +94,16 @@ def _create_win_event(name): manual_reset = False # i.e.: after someone waits it, automatically set to False. initial_state = False if not isinstance(name, bytes): - name = name.encode('utf-8') + name = name.encode("utf-8") event = CreateEventA(None, manual_reset, initial_state, name) if not event: raise ctypes.WinError() class _WinEvent(object): - def wait_for_event_set(self, timeout=None): - ''' + """ :param timeout: in seconds - ''' + """ if timeout is None: timeout = 0xFFFFFFFF else: @@ -124,13 +123,13 @@ def wait_for_event_set(self, timeout=None): CloseHandle(event) -IS_WINDOWS = sys.platform == 'win32' -IS_LINUX = sys.platform in ('linux', 'linux2') -IS_MAC = sys.platform == 'darwin' +IS_WINDOWS = sys.platform == "win32" +IS_LINUX = sys.platform in ("linux", "linux2") +IS_MAC = sys.platform == "darwin" def is_python_64bit(): - return (struct.calcsize('P') == 8) + return struct.calcsize("P") == 8 def get_target_filename(is_target_process_64=None, prefix=None, extension=None): @@ -150,41 +149,41 @@ def get_target_filename(is_target_process_64=None, prefix=None, extension=None): # For other platforms, just use the the same bitness of the process we're running in. is_target_process_64 = is_python_64bit() - arch = '' + arch = "" if IS_WINDOWS: # prefer not using platform.machine() when possible (it's a bit heavyweight as it may # spawn a subprocess). - arch = os.environ.get("PROCESSOR_ARCHITEW6432", os.environ.get('PROCESSOR_ARCHITECTURE', '')) + arch = os.environ.get("PROCESSOR_ARCHITEW6432", os.environ.get("PROCESSOR_ARCHITECTURE", "")) if not arch: arch = platform.machine() if not arch: - print('platform.machine() did not return valid value.') # This shouldn't happen... + print("platform.machine() did not return valid value.") # This shouldn't happen... return None if IS_WINDOWS: if not extension: - extension = '.dll' - suffix_64 = 'amd64' - suffix_32 = 'x86' + extension = ".dll" + suffix_64 = "amd64" + suffix_32 = "x86" elif IS_LINUX: if not extension: - extension = '.so' - suffix_64 = 'amd64' - suffix_32 = 'x86' + extension = ".so" + suffix_64 = "amd64" + suffix_32 = "x86" elif IS_MAC: if not extension: - extension = '.dylib' - suffix_64 = 'x86_64' - suffix_32 = 'x86' + extension = ".dylib" + suffix_64 = "x86_64" + suffix_32 = "x86" else: - print('Unable to attach to process in platform: %s', sys.platform) + print("Unable to attach to process in platform: %s", sys.platform) return None - if arch.lower() not in ('amd64', 'x86', 'x86_64', 'i386', 'x86'): + if arch.lower() not in ("amd64", "x86", "x86_64", "i386", "x86"): # We don't support this processor by default. Still, let's support the case where the # user manually compiled it himself with some heuristics. # @@ -195,19 +194,19 @@ def get_target_filename(is_target_process_64=None, prefix=None, extension=None): # - linux_and_mac/compile_mac.sh try: - found = [name for name in os.listdir(libdir) if name.startswith('attach_') and name.endswith(extension)] + found = [name for name in os.listdir(libdir) if name.startswith("attach_") and name.endswith(extension)] except: - print('Error listing dir: %s' % (libdir,)) + print("Error listing dir: %s" % (libdir,)) traceback.print_exc() return None if prefix: expected_name = prefix + arch + extension - expected_name_linux = prefix + 'linux_' + arch + extension + expected_name_linux = prefix + "linux_" + arch + extension else: # Default is looking for the attach_ / attach_linux - expected_name = 'attach_' + arch + extension - expected_name_linux = 'attach_linux_' + arch + extension + expected_name = "attach_" + arch + extension + expected_name_linux = "attach_linux_" + arch + extension filename = None if expected_name in found: # Heuristic: user compiled with "attach_." @@ -225,14 +224,10 @@ def get_target_filename(is_target_process_64=None, prefix=None, extension=None): filename = os.path.join(libdir, found[0]) if filename is None: - print( - 'Unable to attach to process in arch: %s (did not find %s in %s).' % ( - arch, expected_name, libdir - ) - ) + print("Unable to attach to process in arch: %s (did not find %s in %s)." % (arch, expected_name, libdir)) return None - print('Using %s in arch: %s.' % (filename, arch)) + print("Using %s in arch: %s." % (filename, arch)) else: if is_target_process_64: @@ -243,33 +238,34 @@ def get_target_filename(is_target_process_64=None, prefix=None, extension=None): if not prefix: # Default is looking for the attach_ / attach_linux if IS_WINDOWS or IS_MAC: # just the extension changes - prefix = 'attach_' + prefix = "attach_" elif IS_LINUX: - prefix = 'attach_linux_' # historically it has a different name + prefix = "attach_linux_" # historically it has a different name else: - print('Unable to attach to process in platform: %s' % (sys.platform,)) + print("Unable to attach to process in platform: %s" % (sys.platform,)) return None - filename = os.path.join(libdir, '%s%s%s' % (prefix, suffix, extension)) + filename = os.path.join(libdir, "%s%s%s" % (prefix, suffix, extension)) if not os.path.exists(filename): - print('Expected: %s to exist.' % (filename,)) + print("Expected: %s to exist." % (filename,)) return None return filename def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): - assert '\'' not in python_code, 'Having a single quote messes with our command.' + assert "'" not in python_code, "Having a single quote messes with our command." # Suppress winappdbg warning about sql package missing. import warnings + with warnings.catch_warnings(): warnings.simplefilter("ignore", category=ImportWarning) from winappdbg.process import Process if not isinstance(python_code, bytes): - python_code = python_code.encode('utf-8') + python_code = python_code.encode("utf-8") process = Process(pid) bits = process.get_bits() @@ -282,41 +278,40 @@ def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, sh # "Target 64 bits: %s\n" # "Current Python 64 bits: %s" % (is_target_process_64, is_python_64bit())) - with _acquire_mutex('_pydevd_pid_attach_mutex_%s' % (pid,), 10): - print('--- Connecting to %s bits target (current process is: %s) ---' % (bits, 64 if is_python_64bit() else 32)) + with _acquire_mutex("_pydevd_pid_attach_mutex_%s" % (pid,), 10): + print("--- Connecting to %s bits target (current process is: %s) ---" % (bits, 64 if is_python_64bit() else 32)) sys.stdout.flush() with _win_write_to_shared_named_memory(python_code, pid): - - target_executable = get_target_filename(is_target_process_64, 'inject_dll_', '.exe') + target_executable = get_target_filename(is_target_process_64, "inject_dll_", ".exe") if not target_executable: - raise RuntimeError('Could not find expected .exe file to inject dll in attach to process.') + raise RuntimeError("Could not find expected .exe file to inject dll in attach to process.") target_dll = get_target_filename(is_target_process_64) if not target_dll: - raise RuntimeError('Could not find expected .dll file in attach to process.') + raise RuntimeError("Could not find expected .dll file in attach to process.") - print('\n--- Injecting attach dll: %s into pid: %s ---' % (os.path.basename(target_dll), pid)) + print("\n--- Injecting attach dll: %s into pid: %s ---" % (os.path.basename(target_dll), pid)) sys.stdout.flush() args = [target_executable, str(pid), target_dll] subprocess.check_call(args) # Now, if the first injection worked, go on to the second which will actually # run the code. - target_dll_run_on_dllmain = get_target_filename(is_target_process_64, 'run_code_on_dllmain_', '.dll') + target_dll_run_on_dllmain = get_target_filename(is_target_process_64, "run_code_on_dllmain_", ".dll") if not target_dll_run_on_dllmain: - raise RuntimeError('Could not find expected .dll in attach to process.') + raise RuntimeError("Could not find expected .dll in attach to process.") - with _create_win_event('_pydevd_pid_event_%s' % (pid,)) as event: - print('\n--- Injecting run code dll: %s into pid: %s ---' % (os.path.basename(target_dll_run_on_dllmain), pid)) + with _create_win_event("_pydevd_pid_event_%s" % (pid,)) as event: + print("\n--- Injecting run code dll: %s into pid: %s ---" % (os.path.basename(target_dll_run_on_dllmain), pid)) sys.stdout.flush() args = [target_executable, str(pid), target_dll_run_on_dllmain] subprocess.check_call(args) if not event.wait_for_event_set(15): - print('Timeout error: the attach may not have completed.') + print("Timeout error: the attach may not have completed.") sys.stdout.flush() - print('--- Finished dll injection ---\n') + print("--- Finished dll injection ---\n") sys.stdout.flush() return 0 @@ -324,10 +319,10 @@ def run_python_code_windows(pid, python_code, connect_debugger_tracing=False, sh @contextmanager def _acquire_mutex(mutex_name, timeout): - ''' + """ Only one process may be attaching to a pid, so, create a system mutex to make sure this holds in practice. - ''' + """ from winappdbg.win32.kernel32 import CreateMutex, GetLastError, CloseHandle from winappdbg.win32.defines import ERROR_ALREADY_EXISTS @@ -338,8 +333,8 @@ def _acquire_mutex(mutex_name, timeout): if acquired: break if time.time() - initial_time > timeout: - raise TimeoutError('Unable to acquire mutex to make attach before timeout.') - time.sleep(.2) + raise TimeoutError("Unable to acquire mutex to make attach before timeout.") + time.sleep(0.2) try: yield @@ -369,18 +364,17 @@ def _win_write_to_shared_named_memory(python_code, pid): # Note: BUFSIZE must be the same from run_code_in_memory.hpp BUFSIZE = 2048 assert isinstance(python_code, bytes) - assert len(python_code) > 0, 'Python code must not be empty.' + assert len(python_code) > 0, "Python code must not be empty." # Note: -1 so that we're sure we'll add a \0 to the end. - assert len(python_code) < BUFSIZE - 1, 'Python code must have at most %s bytes (found: %s)' % (BUFSIZE - 1, len(python_code)) + assert len(python_code) < BUFSIZE - 1, "Python code must have at most %s bytes (found: %s)" % (BUFSIZE - 1, len(python_code)) - python_code += b'\0' * (BUFSIZE - len(python_code)) - assert python_code.endswith(b'\0') + python_code += b"\0" * (BUFSIZE - len(python_code)) + assert python_code.endswith(b"\0") INVALID_HANDLE_VALUE = -1 PAGE_READWRITE = 0x4 FILE_MAP_WRITE = 0x2 - filemap = CreateFileMapping( - INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, BUFSIZE, u"__pydevd_pid_code_to_run__%s" % (pid,)) + filemap = CreateFileMapping(INVALID_HANDLE_VALUE, 0, PAGE_READWRITE, 0, BUFSIZE, "__pydevd_pid_code_to_run__%s" % (pid,)) if filemap == INVALID_HANDLE_VALUE or filemap is None: raise Exception("Failed to create named file mapping (ctypes: CreateFileMapping): %s" % (filemap,)) @@ -399,28 +393,34 @@ def _win_write_to_shared_named_memory(python_code, pid): def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): - assert '\'' not in python_code, 'Having a single quote messes with our command.' + assert "'" not in python_code, "Having a single quote messes with our command." target_dll = get_target_filename() if not target_dll: libdir = os.path.dirname(os.path.abspath(__file__)) - found = [name for name in os.listdir(libdir) if name.startswith('attach_') and name.endswith('.so')] - raise RuntimeError('Could not find .so for attach to process.\nLibdir: %s.\nAvailable: %s' % (libdir, found,)) + found = [name for name in os.listdir(libdir) if name.startswith("attach_") and name.endswith(".so")] + raise RuntimeError( + "Could not find .so for attach to process.\nLibdir: %s.\nAvailable: %s" + % ( + libdir, + found, + ) + ) target_dll_name = os.path.splitext(os.path.basename(target_dll))[0] # Note: we currently don't support debug builds is_debug = 0 # Note that the space in the beginning of each line in the multi-line is important! cmd = [ - 'gdb', - '--nw', # no gui interface - '--nh', # no ~/.gdbinit - '--nx', # no .gdbinit -# '--quiet', # no version number on startup - '--pid', + "gdb", + "--nw", # no gui interface + "--nh", # no ~/.gdbinit + "--nx", # no .gdbinit + # '--quiet', # no version number on startup + "--pid", str(pid), - '--batch', -# '--batch-silent', + "--batch", + # '--batch-silent', ] # PYDEVD_GDB_SCAN_SHARED_LIBRARIES can be a list of strings with the shared libraries @@ -444,16 +444,16 @@ def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show # # The downside is that it may be dependent on the Linux version being attached to (which is the # reason why this is no longer done by default -- see: https://github.com/microsoft/debugpy/issues/882). - gdb_load_shared_libraries = os.environ.get('PYDEVD_GDB_SCAN_SHARED_LIBRARIES', '').strip() + gdb_load_shared_libraries = os.environ.get("PYDEVD_GDB_SCAN_SHARED_LIBRARIES", "").strip() if gdb_load_shared_libraries: - print('PYDEVD_GDB_SCAN_SHARED_LIBRARIES set: %s.' % (gdb_load_shared_libraries,)) + print("PYDEVD_GDB_SCAN_SHARED_LIBRARIES set: %s." % (gdb_load_shared_libraries,)) cmd.extend(["--init-eval-command='set auto-solib-add off'"]) # Don't scan all libraries. - for lib in gdb_load_shared_libraries.split(','): + for lib in gdb_load_shared_libraries.split(","): lib = lib.strip() cmd.extend(["--eval-command='sharedlibrary %s'" % (lib,)]) # Scan the specified library else: - print('PYDEVD_GDB_SCAN_SHARED_LIBRARIES not set (scanning all libraries for needed symbols).') + print("PYDEVD_GDB_SCAN_SHARED_LIBRARIES not set (scanning all libraries for needed symbols).") cmd.extend(["--eval-command='set scheduler-locking off'"]) # If on we'll deadlock. @@ -461,79 +461,83 @@ def run_python_code_linux(pid, python_code, connect_debugger_tracing=False, show # current host). cmd.extend(["--eval-command='set architecture auto'"]) - cmd.extend([ - "--eval-command='call (void*)dlopen(\"%s\", 2)'" % target_dll, - "--eval-command='sharedlibrary %s'" % target_dll_name, - "--eval-command='call (int)DoAttach(%s, \"%s\", %s)'" % ( - is_debug, python_code, show_debug_info) - ]) + cmd.extend( + [ + "--eval-command='call (void*)dlopen(\"%s\", 2)'" % target_dll, + "--eval-command='sharedlibrary %s'" % target_dll_name, + "--eval-command='call (int)DoAttach(%s, \"%s\", %s)'" % (is_debug, python_code, show_debug_info), + ] + ) # print ' '.join(cmd) env = os.environ.copy() # Remove the PYTHONPATH (if gdb has a builtin Python it could fail if we # have the PYTHONPATH for a different python version or some forced encoding). - env.pop('PYTHONIOENCODING', None) - env.pop('PYTHONPATH', None) - print('Running: %s' % (' '.join(cmd))) - subprocess.check_call(' '.join(cmd), shell=True, env=env) + env.pop("PYTHONIOENCODING", None) + env.pop("PYTHONPATH", None) + print("Running: %s" % (" ".join(cmd))) + subprocess.check_call(" ".join(cmd), shell=True, env=env) def find_helper_script(filedir, script_name): - target_filename = os.path.join(filedir, 'linux_and_mac', script_name) + target_filename = os.path.join(filedir, "linux_and_mac", script_name) target_filename = os.path.normpath(target_filename) if not os.path.exists(target_filename): - raise RuntimeError('Could not find helper script: %s' % target_filename) + raise RuntimeError("Could not find helper script: %s" % target_filename) return target_filename def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_debug_info=0): - assert '\'' not in python_code, 'Having a single quote messes with our command.' + assert "'" not in python_code, "Having a single quote messes with our command." target_dll = get_target_filename() if not target_dll: - raise RuntimeError('Could not find .dylib for attach to process.') + raise RuntimeError("Could not find .dylib for attach to process.") libdir = os.path.dirname(__file__) - lldb_prepare_file = find_helper_script(libdir, 'lldb_prepare.py') + lldb_prepare_file = find_helper_script(libdir, "lldb_prepare.py") # Note: we currently don't support debug builds is_debug = 0 # Note that the space in the beginning of each line in the multi-line is important! cmd = [ - 'lldb', - '--no-lldbinit', # Do not automatically parse any '.lldbinit' files. + "lldb", + "--no-lldbinit", # Do not automatically parse any '.lldbinit' files. # '--attach-pid', # str(pid), # '--arch', # arch, - '--script-language', - 'Python' + "--script-language", + "Python", # '--batch-silent', ] - cmd.extend([ - "-o 'process attach --pid %d'" % pid, - "-o 'command script import \"%s\"'" % (lldb_prepare_file,), - "-o 'load_lib_and_attach \"%s\" %s \"%s\" %s'" % (target_dll, - is_debug, python_code, show_debug_info), - ]) + cmd.extend( + [ + "-o 'process attach --pid %d'" % pid, + "-o 'command script import \"%s\"'" % (lldb_prepare_file,), + '-o \'load_lib_and_attach "%s" %s "%s" %s\'' % (target_dll, is_debug, python_code, show_debug_info), + ] + ) - cmd.extend([ - "-o 'process detach'", - "-o 'script import os; os._exit(1)'", - ]) + cmd.extend( + [ + "-o 'process detach'", + "-o 'script import os; os._exit(1)'", + ] + ) # print ' '.join(cmd) env = os.environ.copy() # Remove the PYTHONPATH (if lldb has a builtin Python it could fail if we # have the PYTHONPATH for a different python version or some forced encoding). - env.pop('PYTHONIOENCODING', None) - env.pop('PYTHONPATH', None) - print('Running: %s' % (' '.join(cmd))) - subprocess.check_call(' '.join(cmd), shell=True, env=env) + env.pop("PYTHONIOENCODING", None) + env.pop("PYTHONPATH", None) + print("Running: %s" % (" ".join(cmd))) + subprocess.check_call(" ".join(cmd), shell=True, env=env) if IS_WINDOWS: @@ -545,12 +549,12 @@ def run_python_code_mac(pid, python_code, connect_debugger_tracing=False, show_d else: def run_python_code(*args, **kwargs): - print('Unable to attach to process in platform: %s', sys.platform) + print("Unable to attach to process in platform: %s", sys.platform) def test(): - print('Running with: %s' % (sys.executable,)) - code = ''' + print("Running with: %s" % (sys.executable,)) + code = """ import os, time, sys print(os.getpid()) #from threading import Thread @@ -560,16 +564,16 @@ def test(): time.sleep(.5) sys.stdout.write('.\\n') sys.stdout.flush() -''' +""" - p = subprocess.Popen([sys.executable, '-u', '-c', code]) + p = subprocess.Popen([sys.executable, "-u", "-c", code]) try: code = 'print("It worked!")\n' # Real code will be something as: # code = '''import sys;sys.path.append(r'X:\winappdbg-code\examples'); import imported;''' run_python_code(p.pid, python_code=code) - print('\nRun a 2nd time...\n') + print("\nRun a 2nd time...\n") run_python_code(p.pid, python_code=code) time.sleep(3) @@ -582,19 +586,18 @@ def main(args): # in the target process. pid = int(args[0]) del args[0] - python_code = ';'.join(args) + python_code = ";".join(args) # Note: on Linux the python code may not have a single quote char: ' run_python_code(pid, python_code) -if __name__ == '__main__': +if __name__ == "__main__": args = sys.argv[1:] if not args: - print('Expected pid and Python code to execute in target process.') + print("Expected pid and Python code to execute in target process.") else: - if '--test' == args[0]: + if "--test" == args[0]: test() else: main(args) - diff --git a/pydevd_attach_to_process/attach_pydevd.py b/pydevd_attach_to_process/attach_pydevd.py index 25076f46e..7eccf5326 100644 --- a/pydevd_attach_to_process/attach_pydevd.py +++ b/pydevd_attach_to_process/attach_pydevd.py @@ -4,41 +4,41 @@ def process_command_line(argv): setup = {} - setup['port'] = 5678 # Default port for PyDev remote debugger - setup['pid'] = 0 - setup['host'] = '127.0.0.1' - setup['protocol'] = '' - setup['debug-mode'] = '' + setup["port"] = 5678 # Default port for PyDev remote debugger + setup["pid"] = 0 + setup["host"] = "127.0.0.1" + setup["protocol"] = "" + setup["debug-mode"] = "" i = 0 while i < len(argv): - if argv[i] == '--port': + if argv[i] == "--port": del argv[i] - setup['port'] = int(argv[i]) + setup["port"] = int(argv[i]) del argv[i] - elif argv[i] == '--pid': + elif argv[i] == "--pid": del argv[i] - setup['pid'] = int(argv[i]) + setup["pid"] = int(argv[i]) del argv[i] - elif argv[i] == '--host': + elif argv[i] == "--host": del argv[i] - setup['host'] = argv[i] + setup["host"] = argv[i] del argv[i] - elif argv[i] == '--protocol': + elif argv[i] == "--protocol": del argv[i] - setup['protocol'] = argv[i] + setup["protocol"] = argv[i] del argv[i] - elif argv[i] == '--debug-mode': + elif argv[i] == "--debug-mode": del argv[i] - setup['debug-mode'] = argv[i] + setup["debug-mode"] = argv[i] del argv[i] - if not setup['pid']: - sys.stderr.write('Expected --pid to be passed.\n') + if not setup["pid"]: + sys.stderr.write("Expected --pid to be passed.\n") sys.exit(1) return setup @@ -46,34 +46,44 @@ def process_command_line(argv): def main(setup): sys.path.append(os.path.dirname(__file__)) import add_code_to_python_process + show_debug_info_on_target_process = 0 pydevd_dirname = os.path.dirname(os.path.dirname(__file__)) - if sys.platform == 'win32': - setup['pythonpath'] = pydevd_dirname.replace('\\', '/') - setup['pythonpath2'] = os.path.dirname(__file__).replace('\\', '/') - python_code = '''import sys; + if sys.platform == "win32": + setup["pythonpath"] = pydevd_dirname.replace("\\", "/") + setup["pythonpath2"] = os.path.dirname(__file__).replace("\\", "/") + python_code = ( + """import sys; sys.path.append("%(pythonpath)s"); sys.path.append("%(pythonpath2)s"); import attach_script; attach_script.attach(port=%(port)s, host="%(host)s", protocol="%(protocol)s", debug_mode="%(debug-mode)s"); -'''.replace('\r\n', '').replace('\r', '').replace('\n', '') +""".replace("\r\n", "") + .replace("\r", "") + .replace("\n", "") + ) else: - setup['pythonpath'] = pydevd_dirname - setup['pythonpath2'] = os.path.dirname(__file__) + setup["pythonpath"] = pydevd_dirname + setup["pythonpath2"] = os.path.dirname(__file__) # We have to pass it a bit differently for gdb - python_code = '''import sys; + python_code = ( + """import sys; sys.path.append(\\\"%(pythonpath)s\\\"); sys.path.append(\\\"%(pythonpath2)s\\\"); import attach_script; attach_script.attach(port=%(port)s, host=\\\"%(host)s\\\", protocol=\\\"%(protocol)s\\\", debug_mode=\\\"%(debug-mode)s\\\"); -'''.replace('\r\n', '').replace('\r', '').replace('\n', '') +""".replace("\r\n", "") + .replace("\r", "") + .replace("\n", "") + ) python_code = python_code % setup add_code_to_python_process.run_python_code( - setup['pid'], python_code, connect_debugger_tracing=True, show_debug_info=show_debug_info_on_target_process) + setup["pid"], python_code, connect_debugger_tracing=True, show_debug_info=show_debug_info_on_target_process + ) -if __name__ == '__main__': +if __name__ == "__main__": main(process_command_line(sys.argv[1:])) diff --git a/pydevd_attach_to_process/attach_script.py b/pydevd_attach_to_process/attach_script.py index af23e5613..eb5f8d0a7 100644 --- a/pydevd_attach_to_process/attach_script.py +++ b/pydevd_attach_to_process/attach_script.py @@ -1,7 +1,5 @@ - - def get_main_thread_instance(threading): - if hasattr(threading, 'main_thread'): + if hasattr(threading, "main_thread"): return threading.main_thread() else: # On Python 2 we don't really have an API to get the main thread, @@ -10,12 +8,12 @@ def get_main_thread_instance(threading): def get_main_thread_id(unlikely_thread_id=None): - ''' + """ :param unlikely_thread_id: Pass to mark some thread id as not likely the main thread. :return tuple(thread_id, critical_warning) - ''' + """ import sys import os @@ -26,22 +24,22 @@ def get_main_thread_id(unlikely_thread_id=None): frame = frame.f_back basename = os.path.basename(frame.f_code.co_filename) - if basename.endswith(('.pyc', '.pyo')): + if basename.endswith((".pyc", ".pyo")): basename = basename[:-1] if (frame.f_code.co_name, basename) in [ - ('_run_module_as_main', 'runpy.py'), - ('_run_module_as_main', ''), - ('run_module_as_main', 'runpy.py'), - ('run_module', 'runpy.py'), - ('run_path', 'runpy.py'), - ]: + ("_run_module_as_main", "runpy.py"), + ("_run_module_as_main", ""), + ("run_module_as_main", "runpy.py"), + ("run_module", "runpy.py"), + ("run_path", "runpy.py"), + ]: # This is the case for python -m (this is an ideal match, so, # let's return it). - return thread_ident, '' + return thread_ident, "" - if frame.f_code.co_name == '': - if frame.f_globals.get('__name__') == '__main__': + if frame.f_code.co_name == "": + if frame.f_globals.get("__name__") == "__main__": possible_thread_ids.insert(0, thread_ident) # Add with higher priority continue @@ -53,25 +51,26 @@ def get_main_thread_id(unlikely_thread_id=None): if len(possible_thread_ids) > 0: if len(possible_thread_ids) == 1: - return possible_thread_ids[0], '' # Ideal: only one match + return possible_thread_ids[0], "" # Ideal: only one match while unlikely_thread_id in possible_thread_ids: possible_thread_ids.remove(unlikely_thread_id) if len(possible_thread_ids) == 1: - return possible_thread_ids[0], '' # Ideal: only one match + return possible_thread_ids[0], "" # Ideal: only one match elif len(possible_thread_ids) > 1: # Bad: we can't really be certain of anything at this point. - return possible_thread_ids[0], \ - 'Multiple thread ids found (%s). Choosing main thread id randomly (%s).' % ( - possible_thread_ids, possible_thread_ids[0]) + return possible_thread_ids[0], "Multiple thread ids found (%s). Choosing main thread id randomly (%s)." % ( + possible_thread_ids, + possible_thread_ids[0], + ) # If we got here we couldn't discover the main thread id. - return None, 'Unable to discover main thread id.' + return None, "Unable to discover main thread id." -def fix_main_thread_id(on_warn=lambda msg:None, on_exception=lambda msg:None, on_critical=lambda msg:None): +def fix_main_thread_id(on_warn=lambda msg: None, on_exception=lambda msg: None, on_critical=lambda msg: None): # This means that we weren't able to import threading in the main thread (which most # likely means that the main thread is paused or in some very long operation). # In this case we'll import threading here and hotfix what may be wrong in the threading @@ -86,10 +85,10 @@ def fix_main_thread_id(on_warn=lambda msg:None, on_exception=lambda msg:None, on with threading._active_limbo_lock: main_thread_instance = get_main_thread_instance(threading) - if sys.platform == 'win32': + if sys.platform == "win32": # On windows this code would be called in a secondary thread, so, # the current thread is unlikely to be the main thread. - if hasattr(threading, '_get_ident'): + if hasattr(threading, "_get_ident"): unlikely_thread_id = threading._get_ident() # py2 else: unlikely_thread_id = threading.get_ident() # py3 @@ -99,9 +98,9 @@ def fix_main_thread_id(on_warn=lambda msg:None, on_exception=lambda msg:None, on main_thread_id, critical_warning = get_main_thread_id(unlikely_thread_id) if main_thread_id is not None: - main_thread_id_attr = '_ident' + main_thread_id_attr = "_ident" if not hasattr(main_thread_instance, main_thread_id_attr): - main_thread_id_attr = '_Thread__ident' + main_thread_id_attr = "_Thread__ident" assert hasattr(main_thread_instance, main_thread_id_attr) if main_thread_id != getattr(main_thread_instance, main_thread_id_attr): @@ -121,45 +120,54 @@ def fix_main_thread_id(on_warn=lambda msg:None, on_exception=lambda msg:None, on # Note: only import from pydevd after the patching is done (we want to do the minimum # possible when doing that patching). - on_warn('The threading module was not imported by user code in the main thread. The debugger will attempt to work around https://bugs.python.org/issue37416.') + on_warn( + "The threading module was not imported by user code in the main thread. The debugger will attempt to work around https://bugs.python.org/issue37416." + ) if critical_warning: - on_critical('Issue found when debugger was trying to work around https://bugs.python.org/issue37416:\n%s' % (critical_warning,)) + on_critical("Issue found when debugger was trying to work around https://bugs.python.org/issue37416:\n%s" % (critical_warning,)) except: - on_exception('Error patching main thread id.') + on_exception("Error patching main thread id.") -def attach(port, host, protocol='', debug_mode=''): +def attach(port, host, protocol="", debug_mode=""): try: import sys - fix_main_thread = 'threading' not in sys.modules + + fix_main_thread = "threading" not in sys.modules if fix_main_thread: def on_warn(msg): from _pydev_bundle import pydev_log + pydev_log.warn(msg) def on_exception(msg): from _pydev_bundle import pydev_log + pydev_log.exception(msg) def on_critical(msg): from _pydev_bundle import pydev_log + pydev_log.critical(msg) fix_main_thread_id(on_warn=on_warn, on_exception=on_exception, on_critical=on_critical) else: from _pydev_bundle import pydev_log # @Reimport - pydev_log.debug('The threading module is already imported by user code.') + + pydev_log.debug("The threading module is already imported by user code.") if protocol: from _pydevd_bundle import pydevd_defaults + pydevd_defaults.PydevdCustomization.DEFAULT_PROTOCOL = protocol if debug_mode: from _pydevd_bundle import pydevd_defaults + pydevd_defaults.PydevdCustomization.DEBUG_MODE = debug_mode import pydevd @@ -185,4 +193,5 @@ def on_critical(msg): ) except: import traceback + traceback.print_exc() diff --git a/pydevd_attach_to_process/linux_and_mac/lldb_prepare.py b/pydevd_attach_to_process/linux_and_mac/lldb_prepare.py index 8a220542c..aa48b061b 100644 --- a/pydevd_attach_to_process/linux_and_mac/lldb_prepare.py +++ b/pydevd_attach_to_process/linux_and_mac/lldb_prepare.py @@ -3,8 +3,10 @@ # Also it marks process threads to to distinguish them from debugger # threads later while settings trace in threads + def load_lib_and_attach(debugger, command, result, internal_dict): import shlex + args = shlex.split(command) dll = args[0] @@ -13,6 +15,7 @@ def load_lib_and_attach(debugger, command, result, internal_dict): show_debug_info = args[3] import lldb + options = lldb.SBExpressionOptions() options.SetFetchDynamicValue() options.SetTryAllThreads(run_others=False) @@ -20,23 +23,22 @@ def load_lib_and_attach(debugger, command, result, internal_dict): print(dll) target = debugger.GetSelectedTarget() - res = target.EvaluateExpression("(void*)dlopen(\"%s\", 2);" % ( - dll), options) + res = target.EvaluateExpression('(void*)dlopen("%s", 2);' % (dll), options) error = res.GetError() if error: print(error) print(python_code) - res = target.EvaluateExpression("(int)DoAttach(%s, \"%s\", %s);" % ( - is_debug, python_code.replace('"', "'"), show_debug_info), options) + res = target.EvaluateExpression('(int)DoAttach(%s, "%s", %s);' % (is_debug, python_code.replace('"', "'"), show_debug_info), options) error = res.GetError() if error: print(error) + def __lldb_init_module(debugger, internal_dict): import lldb - debugger.HandleCommand('command script add -f lldb_prepare.load_lib_and_attach load_lib_and_attach') + debugger.HandleCommand("command script add -f lldb_prepare.load_lib_and_attach load_lib_and_attach") try: target = debugger.GetSelectedTarget() @@ -45,10 +47,9 @@ def __lldb_init_module(debugger, internal_dict): if process: for thread in process: # print('Marking process thread %d'%thread.GetThreadID()) - internal_dict['_thread_%d' % thread.GetThreadID()] = True + internal_dict["_thread_%d" % thread.GetThreadID()] = True # thread.Suspend() except: - import traceback;traceback.print_exc() - - + import traceback + traceback.print_exc() diff --git a/pydevd_attach_to_process/winappdbg/__init__.py b/pydevd_attach_to_process/winappdbg/__init__.py index aa138ccfd..4dbb06068 100644 --- a/pydevd_attach_to_process/winappdbg/__init__.py +++ b/pydevd_attach_to_process/winappdbg/__init__.py @@ -113,122 +113,105 @@ __revision__ = "$Id$" # List of all public symbols -__all__ = [ - # Library version - 'version', - 'version_number', - - # from breakpoint import * -## 'Breakpoint', -## 'CodeBreakpoint', -## 'PageBreakpoint', -## 'HardwareBreakpoint', -## 'Hook', -## 'ApiHook', -## 'BufferWatch', - 'BreakpointWarning', - 'BreakpointCallbackWarning', - - # from crash import * - 'Crash', - 'CrashWarning', - 'CrashDictionary', - 'CrashContainer', - 'CrashTable', - 'CrashTableMSSQL', - 'VolatileCrashContainer', - 'DummyCrashContainer', - - # from debug import * - 'Debug', - 'MixedBitsWarning', - - # from disasm import * - 'Disassembler', - 'BeaEngine', - 'DistormEngine', - 'PyDasmEngine', - - # from event import * - 'EventHandler', - 'EventSift', -## 'EventFactory', -## 'EventDispatcher', - 'EventCallbackWarning', - 'Event', -## 'NoEvent', - 'CreateProcessEvent', - 'CreateThreadEvent', - 'ExitProcessEvent', - 'ExitThreadEvent', - 'LoadDLLEvent', - 'UnloadDLLEvent', - 'OutputDebugStringEvent', - 'RIPEvent', - 'ExceptionEvent', - - # from interactive import * -## 'ConsoleDebugger', - - # from module import * - 'Module', - 'DebugSymbolsWarning', - - # from process import * - 'Process', - - # from system import * - 'System', - - # from search import * - 'Search', - 'Pattern', - 'BytePattern', - 'TextPattern', - 'RegExpPattern', - 'HexPattern', - - # from registry import * - 'Registry', - - # from textio import * - 'HexDump', - 'HexInput', - 'HexOutput', - 'Color', - 'Table', - 'CrashDump', - 'DebugLog', - 'Logger', - - # from thread import * - 'Thread', - - # from util import * - 'PathOperations', - 'MemoryAddresses', - 'CustomAddressIterator', - 'DataAddressIterator', - 'ImageAddressIterator', - 'MappedAddressIterator', - 'ExecutableAddressIterator', - 'ReadableAddressIterator', - 'WriteableAddressIterator', - 'ExecutableAndWriteableAddressIterator', - 'DebugRegister', - - # from window import * - 'Window', - - # import win32 - 'win32', - - # from win32 import Handle, ProcessHandle, ThreadHandle, FileHandle - 'Handle', - 'ProcessHandle', - 'ThreadHandle', - 'FileHandle', - ] +__all__ = [ + # Library version + "version", + "version_number", + # from breakpoint import * + ## 'Breakpoint', + ## 'CodeBreakpoint', + ## 'PageBreakpoint', + ## 'HardwareBreakpoint', + ## 'Hook', + ## 'ApiHook', + ## 'BufferWatch', + "BreakpointWarning", + "BreakpointCallbackWarning", + # from crash import * + "Crash", + "CrashWarning", + "CrashDictionary", + "CrashContainer", + "CrashTable", + "CrashTableMSSQL", + "VolatileCrashContainer", + "DummyCrashContainer", + # from debug import * + "Debug", + "MixedBitsWarning", + # from disasm import * + "Disassembler", + "BeaEngine", + "DistormEngine", + "PyDasmEngine", + # from event import * + "EventHandler", + "EventSift", + ## 'EventFactory', + ## 'EventDispatcher', + "EventCallbackWarning", + "Event", + ## 'NoEvent', + "CreateProcessEvent", + "CreateThreadEvent", + "ExitProcessEvent", + "ExitThreadEvent", + "LoadDLLEvent", + "UnloadDLLEvent", + "OutputDebugStringEvent", + "RIPEvent", + "ExceptionEvent", + # from interactive import * + ## 'ConsoleDebugger', + # from module import * + "Module", + "DebugSymbolsWarning", + # from process import * + "Process", + # from system import * + "System", + # from search import * + "Search", + "Pattern", + "BytePattern", + "TextPattern", + "RegExpPattern", + "HexPattern", + # from registry import * + "Registry", + # from textio import * + "HexDump", + "HexInput", + "HexOutput", + "Color", + "Table", + "CrashDump", + "DebugLog", + "Logger", + # from thread import * + "Thread", + # from util import * + "PathOperations", + "MemoryAddresses", + "CustomAddressIterator", + "DataAddressIterator", + "ImageAddressIterator", + "MappedAddressIterator", + "ExecutableAddressIterator", + "ReadableAddressIterator", + "WriteableAddressIterator", + "ExecutableAndWriteableAddressIterator", + "DebugRegister", + # from window import * + "Window", + # import win32 + "win32", + # from win32 import Handle, ProcessHandle, ThreadHandle, FileHandle + "Handle", + "ProcessHandle", + "ThreadHandle", + "FileHandle", +] # Import all public symbols from winappdbg.breakpoint import * @@ -252,11 +235,12 @@ try: from sql import * - __all__.append('CrashDAO') + + __all__.append("CrashDAO") except ImportError: import warnings - warnings.warn("No SQL database support present (missing dependencies?)", - ImportWarning) + + warnings.warn("No SQL database support present (missing dependencies?)", ImportWarning) # Library version version_number = 1.5 diff --git a/pydevd_attach_to_process/winappdbg/breakpoint.py b/pydevd_attach_to_process/winappdbg/breakpoint.py index 3b9ca73ff..5fa5d51eb 100644 --- a/pydevd_attach_to_process/winappdbg/breakpoint.py +++ b/pydevd_attach_to_process/winappdbg/breakpoint.py @@ -42,25 +42,20 @@ __revision__ = "$Id$" __all__ = [ - # Base class for breakpoints - 'Breakpoint', - + "Breakpoint", # Breakpoint implementations - 'CodeBreakpoint', - 'PageBreakpoint', - 'HardwareBreakpoint', - + "CodeBreakpoint", + "PageBreakpoint", + "HardwareBreakpoint", # Hooks and watches - 'Hook', - 'ApiHook', - 'BufferWatch', - + "Hook", + "ApiHook", + "BufferWatch", # Warnings - 'BreakpointWarning', - 'BreakpointCallbackWarning', - - ] + "BreakpointWarning", + "BreakpointCallbackWarning", +] from winappdbg import win32 from winappdbg import compat @@ -73,23 +68,27 @@ import warnings import traceback -#============================================================================== +# ============================================================================== + -class BreakpointWarning (UserWarning): +class BreakpointWarning(UserWarning): """ This warning is issued when a non-fatal error occurs that's related to breakpoints. """ -class BreakpointCallbackWarning (RuntimeWarning): + +class BreakpointCallbackWarning(RuntimeWarning): """ This warning is issued when an uncaught exception was raised by a breakpoint's user-defined callback. """ -#============================================================================== -class Breakpoint (object): +# ============================================================================== + + +class Breakpoint(object): """ Base class for breakpoints. Here's the breakpoints state machine. @@ -131,21 +130,21 @@ class Breakpoint (object): # I don't think transitions Enabled <-> OneShot should be allowed... plus # it would require special handling to avoid setting the same bp twice - DISABLED = 0 - ENABLED = 1 - ONESHOT = 2 - RUNNING = 3 + DISABLED = 0 + ENABLED = 1 + ONESHOT = 2 + RUNNING = 3 - typeName = 'breakpoint' + typeName = "breakpoint" - stateNames = { - DISABLED : 'disabled', - ENABLED : 'enabled', - ONESHOT : 'one shot', - RUNNING : 'running', + stateNames = { + DISABLED: "disabled", + ENABLED: "enabled", + ONESHOT: "one shot", + RUNNING: "running", } - def __init__(self, address, size = 1, condition = True, action = None): + def __init__(self, address, size=1, condition=True, action=None): """ Breakpoint object. @@ -179,37 +178,37 @@ def action_callback(event): Where B{event} is an L{Event} object. """ - self.__address = address - self.__size = size - self.__state = self.DISABLED + self.__address = address + self.__size = size + self.__state = self.DISABLED self.set_condition(condition) self.set_action(action) def __repr__(self): if self.is_disabled(): - state = 'Disabled' + state = "Disabled" else: - state = 'Active (%s)' % self.get_state_name() + state = "Active (%s)" % self.get_state_name() if self.is_conditional(): - condition = 'conditional' + condition = "conditional" else: - condition = 'unconditional' + condition = "unconditional" name = self.typeName size = self.get_size() if size == 1: - address = HexDump.address( self.get_address() ) + address = HexDump.address(self.get_address()) else: - begin = self.get_address() - end = begin + size - begin = HexDump.address(begin) - end = HexDump.address(end) + begin = self.get_address() + end = begin + size + begin = HexDump.address(begin) + end = HexDump.address(end) address = "range %s-%s" % (begin, end) msg = "<%s %s %s at remote address %s>" msg = msg % (state, condition, name, address) return msg -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def is_disabled(self): """ @@ -245,7 +244,7 @@ def is_here(self, address): @return: C{True} if the address is within the range of the breakpoint. """ begin = self.get_address() - end = begin + self.get_size() + end = begin + self.get_size() return begin <= address < end def get_address(self): @@ -270,8 +269,8 @@ def get_span(self): covered by the breakpoint. """ address = self.get_address() - size = self.get_size() - return ( address, address + size ) + size = self.get_size() + return (address, address + size) def get_state(self): """ @@ -286,9 +285,9 @@ def get_state_name(self): @rtype: str @return: The name of the current state of the breakpoint. """ - return self.stateNames[ self.get_state() ] + return self.stateNames[self.get_state()] -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def is_conditional(self): """ @@ -315,7 +314,7 @@ def get_condition(self): """ return self.__condition - def set_condition(self, condition = True): + def set_condition(self, condition=True): """ Sets a new condition callback for the breakpoint. @@ -340,21 +339,20 @@ def eval_condition(self, event): @return: C{True} to dispatch the event, C{False} otherwise. """ condition = self.get_condition() - if condition is True: # shortcut for unconditional breakpoints + if condition is True: # shortcut for unconditional breakpoints return True if callable(condition): try: - return bool( condition(event) ) + return bool(condition(event)) except Exception: e = sys.exc_info()[1] - msg = ("Breakpoint condition callback %r" - " raised an exception: %s") + msg = "Breakpoint condition callback %r" " raised an exception: %s" msg = msg % (condition, traceback.format_exc(e)) warnings.warn(msg, BreakpointCallbackWarning) return False - return bool( condition ) # force evaluation now + return bool(condition) # force evaluation now -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def is_automatic(self): """ @@ -379,7 +377,7 @@ def get_action(self): """ return self.__action - def set_action(self, action = None): + def set_action(self, action=None): """ Sets a new action callback for the breakpoint. @@ -398,17 +396,16 @@ def run_action(self, event): action = self.get_action() if action is not None: try: - return bool( action(event) ) + return bool(action(event)) except Exception: e = sys.exc_info()[1] - msg = ("Breakpoint action callback %r" - " raised an exception: %s") + msg = "Breakpoint action callback %r" " raised an exception: %s" msg = msg % (action, traceback.format_exc(e)) warnings.warn(msg, BreakpointCallbackWarning) return False return True -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def __bad_transition(self, state): """ @@ -422,10 +419,9 @@ def __bad_transition(self, state): @raise Exception: Always. """ statemsg = "" - oldState = self.stateNames[ self.get_state() ] - newState = self.stateNames[ state ] - msg = "Invalid state transition (%s -> %s)" \ - " for breakpoint at address %s" + oldState = self.stateNames[self.get_state()] + newState = self.stateNames[state] + msg = "Invalid state transition (%s -> %s)" " for breakpoint at address %s" msg = msg % (oldState, newState, HexDump.address(self.get_address())) raise AssertionError(msg) @@ -443,8 +439,8 @@ def disable(self, aProcess, aThread): @type aThread: L{Thread} @param aThread: Thread object. """ -## if self.__state not in (self.ENABLED, self.ONESHOT, self.RUNNING): -## self.__bad_transition(self.DISABLED) + ## if self.__state not in (self.ENABLED, self.ONESHOT, self.RUNNING): + ## self.__bad_transition(self.DISABLED) self.__state = self.DISABLED def enable(self, aProcess, aThread): @@ -461,8 +457,8 @@ def enable(self, aProcess, aThread): @type aThread: L{Thread} @param aThread: Thread object. """ -## if self.__state not in (self.DISABLED, self.RUNNING): -## self.__bad_transition(self.ENABLED) + ## if self.__state not in (self.DISABLED, self.RUNNING): + ## self.__bad_transition(self.ENABLED) self.__state = self.ENABLED def one_shot(self, aProcess, aThread): @@ -476,8 +472,8 @@ def one_shot(self, aProcess, aThread): @type aThread: L{Thread} @param aThread: Thread object. """ -## if self.__state != self.DISABLED: -## self.__bad_transition(self.ONESHOT) + ## if self.__state != self.DISABLED: + ## self.__bad_transition(self.ONESHOT) self.__state = self.ONESHOT def running(self, aProcess, aThread): @@ -510,8 +506,8 @@ def hit(self, event): @raise AssertionError: Disabled breakpoints can't be hit. """ aProcess = event.get_process() - aThread = event.get_thread() - state = self.get_state() + aThread = event.get_thread() + state = self.get_state() event.breakpoint = self @@ -527,16 +523,18 @@ def hit(self, event): elif state == self.DISABLED: # this should not happen msg = "Hit a disabled breakpoint at address %s" - msg = msg % HexDump.address( self.get_address() ) + msg = msg % HexDump.address(self.get_address()) warnings.warn(msg, BreakpointWarning) -#============================================================================== + +# ============================================================================== # XXX TODO # Check if the user is trying to set a code breakpoint on a memory mapped file, # so we don't end up writing the int3 instruction in the file by accident. -class CodeBreakpoint (Breakpoint): + +class CodeBreakpoint(Breakpoint): """ Code execution breakpoints (using an int3 opcode). @@ -546,12 +544,12 @@ class CodeBreakpoint (Breakpoint): @cvar bpInstruction: Breakpoint instruction for the current processor. """ - typeName = 'code breakpoint' + typeName = "code breakpoint" if win32.arch in (win32.ARCH_I386, win32.ARCH_AMD64): - bpInstruction = '\xCC' # int 3 + bpInstruction = "\xCC" # int 3 - def __init__(self, address, condition = True, action = None): + def __init__(self, address, condition=True, action=None): """ Code breakpoint object. @@ -569,8 +567,7 @@ def __init__(self, address, condition = True, action = None): if win32.arch not in (win32.ARCH_I386, win32.ARCH_AMD64): msg = "Code breakpoints not supported for %s" % win32.arch raise NotImplementedError(msg) - Breakpoint.__init__(self, address, len(self.bpInstruction), - condition, action) + Breakpoint.__init__(self, address, len(self.bpInstruction), condition, action) self.__previousValue = self.bpInstruction def __set_bp(self, aProcess): @@ -632,7 +629,8 @@ def running(self, aProcess, aThread): aThread.set_tf() super(CodeBreakpoint, self).running(aProcess, aThread) -#============================================================================== + +# ============================================================================== # TODO: # * If the original page was already a guard page, the exception should be @@ -647,7 +645,8 @@ def running(self, aProcess, aThread): # protect bits (for example the pages where the PEB and TEB reside). Maybe # a more descriptive error message could be shown in this case. -class PageBreakpoint (Breakpoint): + +class PageBreakpoint(Breakpoint): """ Page access breakpoint (using guard pages). @@ -657,11 +656,11 @@ class PageBreakpoint (Breakpoint): get_size_in_pages """ - typeName = 'page breakpoint' + typeName = "page breakpoint" -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def __init__(self, address, pages = 1, condition = True, action = None): + def __init__(self, address, pages=1, condition=True, action=None): """ Page breakpoint object. @@ -679,15 +678,12 @@ def __init__(self, address, pages = 1, condition = True, action = None): @type action: function @param action: (Optional) Action callback function. """ - Breakpoint.__init__(self, address, pages * MemoryAddresses.pageSize, - condition, action) -## if (address & 0x00000FFF) != 0: + Breakpoint.__init__(self, address, pages * MemoryAddresses.pageSize, condition, action) + ## if (address & 0x00000FFF) != 0: floordiv_align = long(address) // long(MemoryAddresses.pageSize) - truediv_align = float(address) / float(MemoryAddresses.pageSize) + truediv_align = float(address) / float(MemoryAddresses.pageSize) if floordiv_align != truediv_align: - msg = "Address of page breakpoint " \ - "must be aligned to a page size boundary " \ - "(value %s received)" % HexDump.address(address) + msg = "Address of page breakpoint " "must be aligned to a page size boundary " "(value %s received)" % HexDump.address(address) raise ValueError(msg) def get_size_in_pages(self): @@ -705,8 +701,8 @@ def __set_bp(self, aProcess): @type aProcess: L{Process} @param aProcess: Process object. """ - lpAddress = self.get_address() - dwSize = self.get_size() + lpAddress = self.get_address() + dwSize = self.get_size() flNewProtect = aProcess.mquery(lpAddress).Protect flNewProtect = flNewProtect | win32.PAGE_GUARD aProcess.mprotect(lpAddress, dwSize, flNewProtect) @@ -718,9 +714,9 @@ def __clear_bp(self, aProcess): @type aProcess: L{Process} @param aProcess: Process object. """ - lpAddress = self.get_address() + lpAddress = self.get_address() flNewProtect = aProcess.mquery(lpAddress).Protect - flNewProtect = flNewProtect & (0xFFFFFFFF ^ win32.PAGE_GUARD) # DWORD + flNewProtect = flNewProtect & (0xFFFFFFFF ^ win32.PAGE_GUARD) # DWORD aProcess.mprotect(lpAddress, self.get_size(), flNewProtect) def disable(self, aProcess, aThread): @@ -745,9 +741,11 @@ def running(self, aProcess, aThread): aThread.set_tf() super(PageBreakpoint, self).running(aProcess, aThread) -#============================================================================== -class HardwareBreakpoint (Breakpoint): +# ============================================================================== + + +class HardwareBreakpoint(Breakpoint): """ Hardware breakpoint (using debug registers). @@ -790,14 +788,14 @@ class HardwareBreakpoint (Breakpoint): @cvar validWatchSizes: Valid watch flag values. """ - typeName = 'hardware breakpoint' + typeName = "hardware breakpoint" - BREAK_ON_EXECUTION = DebugRegister.BREAK_ON_EXECUTION - BREAK_ON_WRITE = DebugRegister.BREAK_ON_WRITE - BREAK_ON_ACCESS = DebugRegister.BREAK_ON_ACCESS + BREAK_ON_EXECUTION = DebugRegister.BREAK_ON_EXECUTION + BREAK_ON_WRITE = DebugRegister.BREAK_ON_WRITE + BREAK_ON_ACCESS = DebugRegister.BREAK_ON_ACCESS - WATCH_BYTE = DebugRegister.WATCH_BYTE - WATCH_WORD = DebugRegister.WATCH_WORD + WATCH_BYTE = DebugRegister.WATCH_BYTE + WATCH_WORD = DebugRegister.WATCH_WORD WATCH_DWORD = DebugRegister.WATCH_DWORD WATCH_QWORD = DebugRegister.WATCH_QWORD @@ -814,10 +812,7 @@ class HardwareBreakpoint (Breakpoint): WATCH_QWORD, ) - def __init__(self, address, triggerFlag = BREAK_ON_ACCESS, - sizeFlag = WATCH_DWORD, - condition = True, - action = None): + def __init__(self, address, triggerFlag=BREAK_ON_ACCESS, sizeFlag=WATCH_DWORD, condition=True, action=None): """ Hardware breakpoint object. @@ -869,7 +864,7 @@ def __init__(self, address, triggerFlag = BREAK_ON_ACCESS, if win32.arch not in (win32.ARCH_I386, win32.ARCH_AMD64): msg = "Hardware breakpoints not supported for %s" % win32.arch raise NotImplementedError(msg) - if sizeFlag == self.WATCH_BYTE: + if sizeFlag == self.WATCH_BYTE: size = 1 elif sizeFlag == self.WATCH_WORD: size = 2 @@ -888,9 +883,9 @@ def __init__(self, address, triggerFlag = BREAK_ON_ACCESS, raise ValueError(msg) Breakpoint.__init__(self, address, size, condition, action) - self.__trigger = triggerFlag - self.__watch = sizeFlag - self.__slot = None + self.__trigger = triggerFlag + self.__watch = sizeFlag + self.__slot = None def __clear_bp(self, aThread): """ @@ -925,8 +920,7 @@ def __set_bp(self, aThread): msg = "No available hardware breakpoint slots for thread ID %d" msg = msg % aThread.get_tid() raise RuntimeError(msg) - DebugRegister.set_bp(ctx, self.__slot, self.get_address(), - self.__trigger, self.__watch) + DebugRegister.set_bp(ctx, self.__slot, self.get_address(), self.__trigger, self.__watch) aThread.set_context(ctx) finally: aThread.resume() @@ -975,7 +969,8 @@ def running(self, aProcess, aThread): super(HardwareBreakpoint, self).running(aProcess, aThread) aThread.set_tf() -#============================================================================== + +# ============================================================================== # XXX FIXME # @@ -1010,7 +1005,8 @@ def running(self, aProcess, aThread): # TODO: an API to modify the hooked function's arguments -class Hook (object): + +class Hook(object): """ Factory class to produce hook objects. Used by L{Debug.hook_function} and L{Debug.stalk_function}. @@ -1034,8 +1030,8 @@ class Hook (object): # the architecture specific implementation. def __new__(cls, *argv, **argd): try: - arch = argd['arch'] - del argd['arch'] + arch = argd["arch"] + del argd["arch"] except KeyError: try: arch = argv[4] @@ -1063,9 +1059,7 @@ def __new__(cls, *argv, **argd): # useHardwareBreakpoints = False - def __init__(self, preCB = None, postCB = None, - paramCount = None, signature = None, - arch = None): + def __init__(self, preCB=None, postCB=None, paramCount=None, signature=None, arch=None): """ @type preCB: function @param preCB: (Optional) Callback triggered on function entry. @@ -1122,9 +1116,9 @@ def post_LoadLibraryEx(event, return_value): @param arch: (Optional) Target architecture. Defaults to the current architecture. See: L{win32.arch} """ - self.__preCB = preCB - self.__postCB = postCB - self.__paramStack = dict() # tid -> list of tuple( arg, arg, arg... ) + self.__preCB = preCB + self.__postCB = postCB + self.__paramStack = dict() # tid -> list of tuple( arg, arg, arg... ) self._paramCount = paramCount @@ -1140,30 +1134,25 @@ def post_LoadLibraryEx(event, return_value): self._signature = None def _cast_signature_pointers_to_void(self, signature): - c_void_p = ctypes.c_void_p - c_char_p = ctypes.c_char_p + c_void_p = ctypes.c_void_p + c_char_p = ctypes.c_char_p c_wchar_p = ctypes.c_wchar_p - _Pointer = ctypes._Pointer - cast = ctypes.cast + _Pointer = ctypes._Pointer + cast = ctypes.cast for i in compat.xrange(len(signature)): t = signature[i] - if t is not c_void_p and (issubclass(t, _Pointer) \ - or t in [c_char_p, c_wchar_p]): + if t is not c_void_p and (issubclass(t, _Pointer) or t in [c_char_p, c_wchar_p]): signature[i] = cast(t, c_void_p) def _calc_signature(self, signature): - raise NotImplementedError( - "Hook signatures are not supported for architecture: %s" \ - % win32.arch) + raise NotImplementedError("Hook signatures are not supported for architecture: %s" % win32.arch) def _get_return_address(self, aProcess, aThread): return None def _get_function_arguments(self, aProcess, aThread): if self._signature or self._paramCount: - raise NotImplementedError( - "Hook signatures are not supported for architecture: %s" \ - % win32.arch) + raise NotImplementedError("Hook signatures are not supported for architecture: %s" % win32.arch) return () def _get_return_value(self, aThread): @@ -1188,12 +1177,12 @@ def __call__(self, event): debug = event.debug dwProcessId = event.get_pid() - dwThreadId = event.get_tid() - aProcess = event.get_process() - aThread = event.get_thread() + dwThreadId = event.get_tid() + aProcess = event.get_process() + aThread = event.get_thread() # Get the return address and function arguments. - ra = self._get_return_address(aProcess, aThread) + ra = self._get_return_address(aProcess, aThread) params = self._get_function_arguments(aProcess, aThread) # Keep the function arguments for later use. @@ -1202,39 +1191,30 @@ def __call__(self, event): # If we need to hook the return from the function... bHookedReturn = False if ra is not None and self.__postCB is not None: - # Try to set a one shot hardware breakpoint at the return address. useHardwareBreakpoints = self.useHardwareBreakpoints if useHardwareBreakpoints: try: debug.define_hardware_breakpoint( - dwThreadId, - ra, - event.debug.BP_BREAK_ON_EXECUTION, - event.debug.BP_WATCH_BYTE, - True, - self.__postCallAction_hwbp - ) + dwThreadId, ra, event.debug.BP_BREAK_ON_EXECUTION, event.debug.BP_WATCH_BYTE, True, self.__postCallAction_hwbp + ) debug.enable_one_shot_hardware_breakpoint(dwThreadId, ra) bHookedReturn = True except Exception: e = sys.exc_info()[1] useHardwareBreakpoints = False - msg = ("Failed to set hardware breakpoint" - " at address %s for thread ID %d") + msg = "Failed to set hardware breakpoint" " at address %s for thread ID %d" msg = msg % (HexDump.address(ra), dwThreadId) warnings.warn(msg, BreakpointWarning) # If not possible, set a code breakpoint instead. if not useHardwareBreakpoints: try: - debug.break_at(dwProcessId, ra, - self.__postCallAction_codebp) + debug.break_at(dwProcessId, ra, self.__postCallAction_codebp) bHookedReturn = True except Exception: e = sys.exc_info()[1] - msg = ("Failed to set code breakpoint" - " at address %s for process ID %d") + msg = "Failed to set code breakpoint" " at address %s for process ID %d" msg = msg % (HexDump.address(ra), dwProcessId) warnings.warn(msg, BreakpointWarning) @@ -1257,7 +1237,7 @@ def __postCallAction_hwbp(self, event): # Remove the one shot hardware breakpoint # at the return address location in the stack. - tid = event.get_tid() + tid = event.get_tid() address = event.breakpoint.get_address() event.debug.erase_hardware_breakpoint(tid, address) @@ -1288,7 +1268,7 @@ def __postCallAction_codebp(self, event): return True # Remove the code breakpoint at the return address. - pid = event.get_pid() + pid = event.get_pid() address = event.breakpoint.get_address() event.debug.dont_break_at(pid, address) @@ -1308,7 +1288,7 @@ def __postCallAction(self, event): @param event: Breakpoint hit event. """ aThread = event.get_thread() - retval = self._get_return_value(aThread) + retval = self._get_return_value(aThread) self.__callHandler(self.__postCB, event, retval) def __callHandler(self, callback, event, *params): @@ -1339,7 +1319,7 @@ def __push_params(self, tid, params): @type params: tuple( arg, arg, arg... ) @param params: Tuple of arguments. """ - stack = self.__paramStack.get( tid, [] ) + stack = self.__paramStack.get(tid, []) stack.append(params) self.__paramStack[tid] = stack @@ -1430,7 +1410,8 @@ def unhook(self, debug, pid, address): """ return debug.dont_break_at(pid, address) -class _Hook_i386 (Hook): + +class _Hook_i386(Hook): """ Implementation details for L{Hook} on the L{win32.ARCH_I386} architecture. """ @@ -1440,30 +1421,30 @@ class _Hook_i386 (Hook): def _calc_signature(self, signature): self._cast_signature_pointers_to_void(signature) - class Arguments (ctypes.Structure): - _fields_ = [ ("arg_%s" % i, signature[i]) \ - for i in compat.xrange(len(signature) - 1, -1, -1) ] + + class Arguments(ctypes.Structure): + _fields_ = [("arg_%s" % i, signature[i]) for i in compat.xrange(len(signature) - 1, -1, -1)] + return Arguments def _get_return_address(self, aProcess, aThread): - return aProcess.read_pointer( aThread.get_sp() ) + return aProcess.read_pointer(aThread.get_sp()) def _get_function_arguments(self, aProcess, aThread): if self._signature: - params = aThread.read_stack_structure(self._signature, - offset = win32.sizeof(win32.LPVOID)) + params = aThread.read_stack_structure(self._signature, offset=win32.sizeof(win32.LPVOID)) elif self._paramCount: - params = aThread.read_stack_dwords(self._paramCount, - offset = win32.sizeof(win32.LPVOID)) + params = aThread.read_stack_dwords(self._paramCount, offset=win32.sizeof(win32.LPVOID)) else: params = () return params def _get_return_value(self, aThread): ctx = aThread.get_context(win32.CONTEXT_INTEGER) - return ctx['Eax'] + return ctx["Eax"] -class _Hook_amd64 (Hook): + +class _Hook_amd64(Hook): """ Implementation details for L{Hook} on the L{win32.ARCH_AMD64} architecture. """ @@ -1486,67 +1467,60 @@ def _calc_signature(self, signature): self._cast_signature_pointers_to_void(signature) float_types = self.__float_types - c_sizeof = ctypes.sizeof - reg_size = c_sizeof(ctypes.c_size_t) + c_sizeof = ctypes.sizeof + reg_size = c_sizeof(ctypes.c_size_t) - reg_int_sig = [] + reg_int_sig = [] reg_float_sig = [] - stack_sig = [] + stack_sig = [] for i in compat.xrange(len(signature)): - arg = signature[i] + arg = signature[i] name = "arg_%d" % i - stack_sig.insert( 0, (name, arg) ) + stack_sig.insert(0, (name, arg)) if i < 4: if type(arg) in float_types: - reg_float_sig.append( (name, arg) ) + reg_float_sig.append((name, arg)) elif c_sizeof(arg) <= reg_size: - reg_int_sig.append( (name, arg) ) + reg_int_sig.append((name, arg)) else: - msg = ("Hook signatures don't support structures" - " within the first 4 arguments of a function" - " for the %s architecture") % win32.arch + msg = ( + "Hook signatures don't support structures" " within the first 4 arguments of a function" " for the %s architecture" + ) % win32.arch raise NotImplementedError(msg) if reg_int_sig: - class RegisterArguments (ctypes.Structure): + + class RegisterArguments(ctypes.Structure): _fields_ = reg_int_sig else: RegisterArguments = None if reg_float_sig: - class FloatArguments (ctypes.Structure): + + class FloatArguments(ctypes.Structure): _fields_ = reg_float_sig else: FloatArguments = None if stack_sig: - class StackArguments (ctypes.Structure): + + class StackArguments(ctypes.Structure): _fields_ = stack_sig else: StackArguments = None - return (len(signature), - RegisterArguments, - FloatArguments, - StackArguments) + return (len(signature), RegisterArguments, FloatArguments, StackArguments) def _get_return_address(self, aProcess, aThread): - return aProcess.read_pointer( aThread.get_sp() ) + return aProcess.read_pointer(aThread.get_sp()) def _get_function_arguments(self, aProcess, aThread): if self._signature: - (args_count, - RegisterArguments, - FloatArguments, - StackArguments) = self._signature + (args_count, RegisterArguments, FloatArguments, StackArguments) = self._signature arguments = {} if StackArguments: address = aThread.get_sp() + win32.sizeof(win32.LPVOID) - stack_struct = aProcess.read_structure(address, - StackArguments) - stack_args = dict( - [ (name, stack_struct.__getattribute__(name)) - for (name, type) in stack_struct._fields_ ] - ) + stack_struct = aProcess.read_structure(address, StackArguments) + stack_args = dict([(name, stack_struct.__getattribute__(name)) for (name, type) in stack_struct._fields_]) arguments.update(stack_args) flags = 0 if RegisterArguments: @@ -1556,43 +1530,37 @@ def _get_function_arguments(self, aProcess, aThread): if flags: ctx = aThread.get_context(flags) if RegisterArguments: - buffer = (win32.QWORD * 4)(ctx['Rcx'], ctx['Rdx'], - ctx['R8'], ctx['R9']) - reg_args = self._get_arguments_from_buffer(buffer, - RegisterArguments) + buffer = (win32.QWORD * 4)(ctx["Rcx"], ctx["Rdx"], ctx["R8"], ctx["R9"]) + reg_args = self._get_arguments_from_buffer(buffer, RegisterArguments) arguments.update(reg_args) if FloatArguments: - buffer = (win32.M128A * 4)(ctx['XMM0'], ctx['XMM1'], - ctx['XMM2'], ctx['XMM3']) - float_args = self._get_arguments_from_buffer(buffer, - FloatArguments) + buffer = (win32.M128A * 4)(ctx["XMM0"], ctx["XMM1"], ctx["XMM2"], ctx["XMM3"]) + float_args = self._get_arguments_from_buffer(buffer, FloatArguments) arguments.update(float_args) - params = tuple( [ arguments["arg_%d" % i] - for i in compat.xrange(args_count) ] ) + params = tuple([arguments["arg_%d" % i] for i in compat.xrange(args_count)]) else: params = () return params def _get_arguments_from_buffer(self, buffer, structure): - b_ptr = ctypes.pointer(buffer) - v_ptr = ctypes.cast(b_ptr, ctypes.c_void_p) - s_ptr = ctypes.cast(v_ptr, ctypes.POINTER(structure)) + b_ptr = ctypes.pointer(buffer) + v_ptr = ctypes.cast(b_ptr, ctypes.c_void_p) + s_ptr = ctypes.cast(v_ptr, ctypes.POINTER(structure)) struct = s_ptr.contents - return dict( - [ (name, struct.__getattribute__(name)) - for (name, type) in struct._fields_ ] - ) + return dict([(name, struct.__getattribute__(name)) for (name, type) in struct._fields_]) def _get_return_value(self, aThread): ctx = aThread.get_context(win32.CONTEXT_INTEGER) - return ctx['Rax'] + return ctx["Rax"] + -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # This class acts as a factory of Hook objects, one per target process. # Said objects are deleted by the unhook() method. -class ApiHook (object): + +class ApiHook(object): """ Used by L{EventHandler}. @@ -1610,8 +1578,7 @@ class ApiHook (object): @ivar procName: Procedure name. """ - def __init__(self, eventHandler, modName, procName, paramCount = None, - signature = None): + def __init__(self, eventHandler, modName, procName, paramCount=None, signature=None): """ @type eventHandler: L{EventHandler} @param eventHandler: Event handler instance. This is where the hook @@ -1670,13 +1637,13 @@ def post_LoadLibraryEx(self, event, return_value): be used to parse the arguments from the stack. Overrides the C{paramCount} argument. """ - self.__modName = modName - self.__procName = procName + self.__modName = modName + self.__procName = procName self.__paramCount = paramCount - self.__signature = signature - self.__preCB = getattr(eventHandler, 'pre_%s' % procName, None) - self.__postCB = getattr(eventHandler, 'post_%s' % procName, None) - self.__hook = dict() + self.__signature = signature + self.__preCB = getattr(eventHandler, "pre_%s" % procName, None) + self.__postCB = getattr(eventHandler, "post_%s" % procName, None) + self.__hook = dict() def __call__(self, event): """ @@ -1691,9 +1658,7 @@ def __call__(self, event): try: hook = self.__hook[pid] except KeyError: - hook = Hook(self.__preCB, self.__postCB, - self.__paramCount, self.__signature, - event.get_process().get_arch() ) + hook = Hook(self.__preCB, self.__postCB, self.__paramCount, self.__signature, event.get_process().get_arch()) self.__hook[pid] = hook return hook(event) @@ -1725,9 +1690,7 @@ def hook(self, debug, pid): aProcess = debug.system.get_process(pid) except KeyError: aProcess = Process(pid) - hook = Hook(self.__preCB, self.__postCB, - self.__paramCount, self.__signature, - aProcess.get_arch() ) + hook = Hook(self.__preCB, self.__postCB, self.__paramCount, self.__signature, aProcess.get_arch()) self.__hook[pid] = hook hook.hook(debug, pid, label) @@ -1751,9 +1714,11 @@ def unhook(self, debug, pid): hook.unhook(debug, pid, label) del self.__hook[pid] -#============================================================================== -class BufferWatch (object): +# ============================================================================== + + +class BufferWatch(object): """ Returned by L{Debug.watch_buffer}. @@ -1776,11 +1741,11 @@ class BufferWatch (object): @ivar oneshot: C{True} for one shot breakpoints, C{False} otherwise. """ - def __init__(self, pid, start, end, action = None, oneshot = False): - self.__pid = pid - self.__start = start - self.__end = end - self.__action = action + def __init__(self, pid, start, end, action=None, oneshot=False): + self.__pid = pid + self.__start = start + self.__end = end + self.__action = action self.__oneshot = oneshot @property @@ -1813,9 +1778,11 @@ def match(self, address): """ return self.__start <= address < self.__end -#============================================================================== -class _BufferWatchCondition (object): +# ============================================================================== + + +class _BufferWatchCondition(object): """ Used by L{Debug.watch_buffer}. @@ -1873,7 +1840,7 @@ def remove_last_match(self, address, size): """ count = 0 start = address - end = address + size - 1 + end = address + size - 1 matched = None for item in self.__ranges: if item.match(start) and item.match(end): @@ -1904,7 +1871,7 @@ def __call__(self, event): to at least one of the buffers that was being watched and had no action callback. """ - address = event.get_exception_information(1) + address = event.get_exception_information(1) bCondition = False for bw in self.__ranges: bMatched = bw.match(address) @@ -1915,8 +1882,7 @@ def __call__(self, event): action(event) except Exception: e = sys.exc_info()[1] - msg = ("Breakpoint action callback %r" - " raised an exception: %s") + msg = "Breakpoint action callback %r" " raised an exception: %s" msg = msg % (action, traceback.format_exc(e)) warnings.warn(msg, BreakpointCallbackWarning) else: @@ -1926,9 +1892,11 @@ def __call__(self, event): event.debug.dont_watch_buffer(bw) return bCondition -#============================================================================== -class _BreakpointContainer (object): +# ============================================================================== + + +class _BreakpointContainer(object): """ Encapsulates the capability to contain Breakpoint objects. @@ -2034,37 +2002,37 @@ class _BreakpointContainer (object): """ # Breakpoint types - BP_TYPE_ANY = 0 # to get all breakpoints - BP_TYPE_CODE = 1 - BP_TYPE_PAGE = 2 - BP_TYPE_HARDWARE = 3 + BP_TYPE_ANY = 0 # to get all breakpoints + BP_TYPE_CODE = 1 + BP_TYPE_PAGE = 2 + BP_TYPE_HARDWARE = 3 # Breakpoint states - BP_STATE_DISABLED = Breakpoint.DISABLED - BP_STATE_ENABLED = Breakpoint.ENABLED - BP_STATE_ONESHOT = Breakpoint.ONESHOT - BP_STATE_RUNNING = Breakpoint.RUNNING + BP_STATE_DISABLED = Breakpoint.DISABLED + BP_STATE_ENABLED = Breakpoint.ENABLED + BP_STATE_ONESHOT = Breakpoint.ONESHOT + BP_STATE_RUNNING = Breakpoint.RUNNING # Memory breakpoint trigger flags - BP_BREAK_ON_EXECUTION = HardwareBreakpoint.BREAK_ON_EXECUTION - BP_BREAK_ON_WRITE = HardwareBreakpoint.BREAK_ON_WRITE - BP_BREAK_ON_ACCESS = HardwareBreakpoint.BREAK_ON_ACCESS + BP_BREAK_ON_EXECUTION = HardwareBreakpoint.BREAK_ON_EXECUTION + BP_BREAK_ON_WRITE = HardwareBreakpoint.BREAK_ON_WRITE + BP_BREAK_ON_ACCESS = HardwareBreakpoint.BREAK_ON_ACCESS # Memory breakpoint size flags - BP_WATCH_BYTE = HardwareBreakpoint.WATCH_BYTE - BP_WATCH_WORD = HardwareBreakpoint.WATCH_WORD - BP_WATCH_QWORD = HardwareBreakpoint.WATCH_QWORD - BP_WATCH_DWORD = HardwareBreakpoint.WATCH_DWORD + BP_WATCH_BYTE = HardwareBreakpoint.WATCH_BYTE + BP_WATCH_WORD = HardwareBreakpoint.WATCH_WORD + BP_WATCH_QWORD = HardwareBreakpoint.WATCH_QWORD + BP_WATCH_DWORD = HardwareBreakpoint.WATCH_DWORD def __init__(self): - self.__codeBP = dict() # (pid, address) -> CodeBreakpoint - self.__pageBP = dict() # (pid, address) -> PageBreakpoint - self.__hardwareBP = dict() # tid -> [ HardwareBreakpoint ] - self.__runningBP = dict() # tid -> set( Breakpoint ) - self.__tracing = set() # set( tid ) - self.__deferredBP = dict() # pid -> label -> (action, oneshot) + self.__codeBP = dict() # (pid, address) -> CodeBreakpoint + self.__pageBP = dict() # (pid, address) -> PageBreakpoint + self.__hardwareBP = dict() # tid -> [ HardwareBreakpoint ] + self.__runningBP = dict() # tid -> set( Breakpoint ) + self.__tracing = set() # set( tid ) + self.__deferredBP = dict() # pid -> label -> (action, oneshot) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # This operates on the dictionary of running breakpoints. # Since the bps are meant to stay alive no cleanup is done here. @@ -2087,12 +2055,12 @@ def __del_running_bp(self, tid, bp): def __del_running_bp_from_all_threads(self, bp): "Auxiliary method." - for (tid, bpset) in compat.iteritems(self.__runningBP): + for tid, bpset in compat.iteritems(self.__runningBP): if bp in bpset: bpset.remove(bp) self.system.get_thread(tid).clear_tf() -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # This is the cleanup code. Mostly called on response to exit/unload debug # events. If possible it shouldn't raise exceptions on runtime errors. @@ -2102,12 +2070,12 @@ def __cleanup_breakpoint(self, event, bp): "Auxiliary method." try: process = event.get_process() - thread = event.get_thread() - bp.disable(process, thread) # clear the debug regs / trap flag + thread = event.get_thread() + bp.disable(process, thread) # clear the debug regs / trap flag except Exception: pass bp.set_condition(True) # break possible circular reference - bp.set_action(None) # break possible circular reference + bp.set_action(None) # break possible circular reference def __cleanup_thread(self, event): """ @@ -2140,22 +2108,22 @@ def __cleanup_process(self, event): """ Auxiliary method for L{_notify_exit_process}. """ - pid = event.get_pid() + pid = event.get_pid() process = event.get_process() # Cleanup code breakpoints - for (bp_pid, bp_address) in compat.keys(self.__codeBP): + for bp_pid, bp_address in compat.keys(self.__codeBP): if bp_pid == pid: - bp = self.__codeBP[ (bp_pid, bp_address) ] + bp = self.__codeBP[(bp_pid, bp_address)] self.__cleanup_breakpoint(event, bp) - del self.__codeBP[ (bp_pid, bp_address) ] + del self.__codeBP[(bp_pid, bp_address)] # Cleanup page breakpoints - for (bp_pid, bp_address) in compat.keys(self.__pageBP): + for bp_pid, bp_address in compat.keys(self.__pageBP): if bp_pid == pid: - bp = self.__pageBP[ (bp_pid, bp_address) ] + bp = self.__pageBP[(bp_pid, bp_address)] self.__cleanup_breakpoint(event, bp) - del self.__pageBP[ (bp_pid, bp_address) ] + del self.__pageBP[(bp_pid, bp_address)] # Cleanup deferred code breakpoints try: @@ -2167,9 +2135,9 @@ def __cleanup_module(self, event): """ Auxiliary method for L{_notify_unload_dll}. """ - pid = event.get_pid() + pid = event.get_pid() process = event.get_process() - module = event.get_module() + module = event.get_module() # Cleanup thread breakpoints on this module for tid in process.iter_thread_ids(): @@ -2194,28 +2162,27 @@ def __cleanup_module(self, event): self.__hardwareBP[tid].remove(bp) # Cleanup code breakpoints on this module - for (bp_pid, bp_address) in compat.keys(self.__codeBP): + for bp_pid, bp_address in compat.keys(self.__codeBP): if bp_pid == pid: if process.get_module_at_address(bp_address) == module: - bp = self.__codeBP[ (bp_pid, bp_address) ] + bp = self.__codeBP[(bp_pid, bp_address)] self.__cleanup_breakpoint(event, bp) - del self.__codeBP[ (bp_pid, bp_address) ] + del self.__codeBP[(bp_pid, bp_address)] # Cleanup page breakpoints on this module - for (bp_pid, bp_address) in compat.keys(self.__pageBP): + for bp_pid, bp_address in compat.keys(self.__pageBP): if bp_pid == pid: if process.get_module_at_address(bp_address) == module: - bp = self.__pageBP[ (bp_pid, bp_address) ] + bp = self.__pageBP[(bp_pid, bp_address)] self.__cleanup_breakpoint(event, bp) - del self.__pageBP[ (bp_pid, bp_address) ] + del self.__pageBP[(bp_pid, bp_address)] -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Defining breakpoints. # Code breakpoints. - def define_code_breakpoint(self, dwProcessId, address, condition = True, - action = None): + def define_code_breakpoint(self, dwProcessId, address, condition=True, action=None): """ Creates a disabled code breakpoint at the given address. @@ -2273,9 +2240,7 @@ def action_callback(event): return bp # Page breakpoints. - def define_page_breakpoint(self, dwProcessId, address, pages = 1, - condition = True, - action = None): + def define_page_breakpoint(self, dwProcessId, address, pages=1, condition=True, action=None): """ Creates a disabled page breakpoint at the given address. @@ -2326,11 +2291,11 @@ def action_callback(event): @return: The page breakpoint object. """ process = self.system.get_process(dwProcessId) - bp = PageBreakpoint(address, pages, condition, action) - begin = bp.get_address() - end = begin + bp.get_size() + bp = PageBreakpoint(address, pages, condition, action) + begin = bp.get_address() + end = begin + bp.get_size() - address = begin + address = begin pageSize = MemoryAddresses.pageSize while address < end: key = (dwProcessId, address) @@ -2348,11 +2313,9 @@ def action_callback(event): return bp # Hardware breakpoints. - def define_hardware_breakpoint(self, dwThreadId, address, - triggerFlag = BP_BREAK_ON_ACCESS, - sizeFlag = BP_WATCH_DWORD, - condition = True, - action = None): + def define_hardware_breakpoint( + self, dwThreadId, address, triggerFlag=BP_BREAK_ON_ACCESS, sizeFlag=BP_WATCH_DWORD, condition=True, action=None + ): """ Creates a disabled hardware breakpoint at the given address. @@ -2437,19 +2400,17 @@ def action_callback(event): @rtype: L{HardwareBreakpoint} @return: The hardware breakpoint object. """ - thread = self.system.get_thread(dwThreadId) - bp = HardwareBreakpoint(address, triggerFlag, sizeFlag, condition, - action) - begin = bp.get_address() - end = begin + bp.get_size() + thread = self.system.get_thread(dwThreadId) + bp = HardwareBreakpoint(address, triggerFlag, sizeFlag, condition, action) + begin = bp.get_address() + end = begin + bp.get_size() if dwThreadId in self.__hardwareBP: bpSet = self.__hardwareBP[dwThreadId] for oldbp in bpSet: old_begin = oldbp.get_address() - old_end = old_begin + oldbp.get_size() - if MemoryAddresses.do_ranges_intersect(begin, end, old_begin, - old_end): + old_end = old_begin + oldbp.get_size() + if MemoryAddresses.do_ranges_intersect(begin, end, old_begin, old_end): msg = "Already exists (TID %d) : %r" % (dwThreadId, oldbp) raise KeyError(msg) else: @@ -2458,7 +2419,7 @@ def action_callback(event): bpSet.add(bp) return bp -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Checking breakpoint definitions. @@ -2536,7 +2497,7 @@ def has_hardware_breakpoint(self, dwThreadId, address): return True return False -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Getting breakpoints. @@ -2639,7 +2600,7 @@ def get_hardware_breakpoint(self, dwThreadId, address): msg = "No hardware breakpoint at thread %d, address %s" raise KeyError(msg % (dwThreadId, HexDump.address(address))) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Enabling and disabling breakpoints. @@ -2660,11 +2621,11 @@ def enable_code_breakpoint(self, dwProcessId, address): @type address: int @param address: Memory address of breakpoint. """ - p = self.system.get_process(dwProcessId) + p = self.system.get_process(dwProcessId) bp = self.get_code_breakpoint(dwProcessId, address) if bp.is_running(): self.__del_running_bp_from_all_threads(bp) - bp.enable(p, None) # XXX HACK thread is not used + bp.enable(p, None) # XXX HACK thread is not used def enable_page_breakpoint(self, dwProcessId, address): """ @@ -2684,11 +2645,11 @@ def enable_page_breakpoint(self, dwProcessId, address): @type address: int @param address: Memory address of breakpoint. """ - p = self.system.get_process(dwProcessId) + p = self.system.get_process(dwProcessId) bp = self.get_page_breakpoint(dwProcessId, address) if bp.is_running(): self.__del_running_bp_from_all_threads(bp) - bp.enable(p, None) # XXX HACK thread is not used + bp.enable(p, None) # XXX HACK thread is not used def enable_hardware_breakpoint(self, dwThreadId, address): """ @@ -2711,11 +2672,11 @@ def enable_hardware_breakpoint(self, dwThreadId, address): @type address: int @param address: Memory address of breakpoint. """ - t = self.system.get_thread(dwThreadId) + t = self.system.get_thread(dwThreadId) bp = self.get_hardware_breakpoint(dwThreadId, address) if bp.is_running(): self.__del_running_bp_from_all_threads(bp) - bp.enable(None, t) # XXX HACK process is not used + bp.enable(None, t) # XXX HACK process is not used def enable_one_shot_code_breakpoint(self, dwProcessId, address): """ @@ -2735,11 +2696,11 @@ def enable_one_shot_code_breakpoint(self, dwProcessId, address): @type address: int @param address: Memory address of breakpoint. """ - p = self.system.get_process(dwProcessId) + p = self.system.get_process(dwProcessId) bp = self.get_code_breakpoint(dwProcessId, address) if bp.is_running(): self.__del_running_bp_from_all_threads(bp) - bp.one_shot(p, None) # XXX HACK thread is not used + bp.one_shot(p, None) # XXX HACK thread is not used def enable_one_shot_page_breakpoint(self, dwProcessId, address): """ @@ -2759,11 +2720,11 @@ def enable_one_shot_page_breakpoint(self, dwProcessId, address): @type address: int @param address: Memory address of breakpoint. """ - p = self.system.get_process(dwProcessId) + p = self.system.get_process(dwProcessId) bp = self.get_page_breakpoint(dwProcessId, address) if bp.is_running(): self.__del_running_bp_from_all_threads(bp) - bp.one_shot(p, None) # XXX HACK thread is not used + bp.one_shot(p, None) # XXX HACK thread is not used def enable_one_shot_hardware_breakpoint(self, dwThreadId, address): """ @@ -2783,11 +2744,11 @@ def enable_one_shot_hardware_breakpoint(self, dwThreadId, address): @type address: int @param address: Memory address of breakpoint. """ - t = self.system.get_thread(dwThreadId) + t = self.system.get_thread(dwThreadId) bp = self.get_hardware_breakpoint(dwThreadId, address) if bp.is_running(): self.__del_running_bp_from_all_threads(bp) - bp.one_shot(None, t) # XXX HACK process is not used + bp.one_shot(None, t) # XXX HACK process is not used def disable_code_breakpoint(self, dwProcessId, address): """ @@ -2807,11 +2768,11 @@ def disable_code_breakpoint(self, dwProcessId, address): @type address: int @param address: Memory address of breakpoint. """ - p = self.system.get_process(dwProcessId) + p = self.system.get_process(dwProcessId) bp = self.get_code_breakpoint(dwProcessId, address) if bp.is_running(): self.__del_running_bp_from_all_threads(bp) - bp.disable(p, None) # XXX HACK thread is not used + bp.disable(p, None) # XXX HACK thread is not used def disable_page_breakpoint(self, dwProcessId, address): """ @@ -2831,11 +2792,11 @@ def disable_page_breakpoint(self, dwProcessId, address): @type address: int @param address: Memory address of breakpoint. """ - p = self.system.get_process(dwProcessId) + p = self.system.get_process(dwProcessId) bp = self.get_page_breakpoint(dwProcessId, address) if bp.is_running(): self.__del_running_bp_from_all_threads(bp) - bp.disable(p, None) # XXX HACK thread is not used + bp.disable(p, None) # XXX HACK thread is not used def disable_hardware_breakpoint(self, dwThreadId, address): """ @@ -2855,14 +2816,14 @@ def disable_hardware_breakpoint(self, dwThreadId, address): @type address: int @param address: Memory address of breakpoint. """ - t = self.system.get_thread(dwThreadId) - p = t.get_process() + t = self.system.get_thread(dwThreadId) + p = t.get_process() bp = self.get_hardware_breakpoint(dwThreadId, address) if bp.is_running(): self.__del_running_bp(dwThreadId, bp) bp.disable(p, t) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Undefining (erasing) breakpoints. @@ -2887,7 +2848,7 @@ def erase_code_breakpoint(self, dwProcessId, address): bp = self.get_code_breakpoint(dwProcessId, address) if not bp.is_disabled(): self.disable_code_breakpoint(dwProcessId, address) - del self.__codeBP[ (dwProcessId, address) ] + del self.__codeBP[(dwProcessId, address)] def erase_page_breakpoint(self, dwProcessId, address): """ @@ -2907,15 +2868,15 @@ def erase_page_breakpoint(self, dwProcessId, address): @type address: int @param address: Memory address of breakpoint. """ - bp = self.get_page_breakpoint(dwProcessId, address) + bp = self.get_page_breakpoint(dwProcessId, address) begin = bp.get_address() - end = begin + bp.get_size() + end = begin + bp.get_size() if not bp.is_disabled(): self.disable_page_breakpoint(dwProcessId, address) - address = begin + address = begin pageSize = MemoryAddresses.pageSize while address < end: - del self.__pageBP[ (dwProcessId, address) ] + del self.__pageBP[(dwProcessId, address)] address = address + pageSize def erase_hardware_breakpoint(self, dwThreadId, address): @@ -2944,7 +2905,7 @@ def erase_hardware_breakpoint(self, dwThreadId, address): if not bpSet: del self.__hardwareBP[dwThreadId] -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Listing breakpoints. @@ -2974,17 +2935,17 @@ def get_all_breakpoints(self): bplist = list() # Get the code breakpoints. - for (pid, bp) in self.get_all_code_breakpoints(): - bplist.append( (pid, None, bp) ) + for pid, bp in self.get_all_code_breakpoints(): + bplist.append((pid, None, bp)) # Get the page breakpoints. - for (pid, bp) in self.get_all_page_breakpoints(): - bplist.append( (pid, None, bp) ) + for pid, bp in self.get_all_page_breakpoints(): + bplist.append((pid, None, bp)) # Get the hardware breakpoints. - for (tid, bp) in self.get_all_hardware_breakpoints(): + for tid, bp in self.get_all_hardware_breakpoints(): pid = self.system.get_thread(tid).get_pid() - bplist.append( (pid, tid, bp) ) + bplist.append((pid, tid, bp)) # Return the list of breakpoints. return bplist @@ -2994,17 +2955,17 @@ def get_all_code_breakpoints(self): @rtype: list of tuple( int, L{CodeBreakpoint} ) @return: All code breakpoints as a list of tuples (pid, bp). """ - return [ (pid, bp) for ((pid, address), bp) in compat.iteritems(self.__codeBP) ] + return [(pid, bp) for ((pid, address), bp) in compat.iteritems(self.__codeBP)] def get_all_page_breakpoints(self): """ @rtype: list of tuple( int, L{PageBreakpoint} ) @return: All page breakpoints as a list of tuples (pid, bp). """ -## return list( set( [ (pid, bp) for ((pid, address), bp) in compat.iteritems(self.__pageBP) ] ) ) + ## return list( set( [ (pid, bp) for ((pid, address), bp) in compat.iteritems(self.__pageBP) ] ) ) result = set() - for ((pid, address), bp) in compat.iteritems(self.__pageBP): - result.add( (pid, bp) ) + for (pid, address), bp in compat.iteritems(self.__pageBP): + result.add((pid, bp)) return list(result) def get_all_hardware_breakpoints(self): @@ -3013,9 +2974,9 @@ def get_all_hardware_breakpoints(self): @return: All hardware breakpoints as a list of tuples (tid, bp). """ result = list() - for (tid, bplist) in compat.iteritems(self.__hardwareBP): + for tid, bplist in compat.iteritems(self.__hardwareBP): for bp in bplist: - result.append( (tid, bp) ) + result.append((tid, bp)) return result def get_process_breakpoints(self, dwProcessId): @@ -3048,16 +3009,16 @@ def get_process_breakpoints(self, dwProcessId): # Get the code breakpoints. for bp in self.get_process_code_breakpoints(dwProcessId): - bplist.append( (dwProcessId, None, bp) ) + bplist.append((dwProcessId, None, bp)) # Get the page breakpoints. for bp in self.get_process_page_breakpoints(dwProcessId): - bplist.append( (dwProcessId, None, bp) ) + bplist.append((dwProcessId, None, bp)) # Get the hardware breakpoints. - for (tid, bp) in self.get_process_hardware_breakpoints(dwProcessId): + for tid, bp in self.get_process_hardware_breakpoints(dwProcessId): pid = self.system.get_thread(tid).get_pid() - bplist.append( (dwProcessId, tid, bp) ) + bplist.append((dwProcessId, tid, bp)) # Return the list of breakpoints. return bplist @@ -3070,8 +3031,7 @@ def get_process_code_breakpoints(self, dwProcessId): @rtype: list of L{CodeBreakpoint} @return: All code breakpoints for the given process. """ - return [ bp for ((pid, address), bp) in compat.iteritems(self.__codeBP) \ - if pid == dwProcessId ] + return [bp for ((pid, address), bp) in compat.iteritems(self.__codeBP) if pid == dwProcessId] def get_process_page_breakpoints(self, dwProcessId): """ @@ -3081,8 +3041,7 @@ def get_process_page_breakpoints(self, dwProcessId): @rtype: list of L{PageBreakpoint} @return: All page breakpoints for the given process. """ - return [ bp for ((pid, address), bp) in compat.iteritems(self.__pageBP) \ - if pid == dwProcessId ] + return [bp for ((pid, address), bp) in compat.iteritems(self.__pageBP) if pid == dwProcessId] def get_thread_hardware_breakpoints(self, dwThreadId): """ @@ -3095,7 +3054,7 @@ def get_thread_hardware_breakpoints(self, dwThreadId): @return: All hardware breakpoints for the given thread. """ result = list() - for (tid, bplist) in compat.iteritems(self.__hardwareBP): + for tid, bplist in compat.iteritems(self.__hardwareBP): if tid == dwThreadId: for bp in bplist: result.append(bp) @@ -3118,35 +3077,35 @@ def get_process_hardware_breakpoints(self, dwProcessId): if dwThreadId in self.__hardwareBP: bplist = self.__hardwareBP[dwThreadId] for bp in bplist: - result.append( (dwThreadId, bp) ) + result.append((dwThreadId, bp)) return result -## def get_all_hooks(self): -## """ -## @see: L{get_process_hooks} -## -## @rtype: list of tuple( int, int, L{Hook} ) -## @return: All defined hooks as a list of tuples (pid, address, hook). -## """ -## return [ (pid, address, hook) \ -## for ((pid, address), hook) in self.__hook_objects ] -## -## def get_process_hooks(self, dwProcessId): -## """ -## @see: L{get_all_hooks} -## -## @type dwProcessId: int -## @param dwProcessId: Process global ID. -## -## @rtype: list of tuple( int, int, L{Hook} ) -## @return: All hooks for the given process as a list of tuples -## (pid, address, hook). -## """ -## return [ (pid, address, hook) \ -## for ((pid, address), hook) in self.__hook_objects \ -## if pid == dwProcessId ] - -#------------------------------------------------------------------------------ + ## def get_all_hooks(self): + ## """ + ## @see: L{get_process_hooks} + ## + ## @rtype: list of tuple( int, int, L{Hook} ) + ## @return: All defined hooks as a list of tuples (pid, address, hook). + ## """ + ## return [ (pid, address, hook) \ + ## for ((pid, address), hook) in self.__hook_objects ] + ## + ## def get_process_hooks(self, dwProcessId): + ## """ + ## @see: L{get_all_hooks} + ## + ## @type dwProcessId: int + ## @param dwProcessId: Process global ID. + ## + ## @rtype: list of tuple( int, int, L{Hook} ) + ## @return: All hooks for the given process as a list of tuples + ## (pid, address, hook). + ## """ + ## return [ (pid, address, hook) \ + ## for ((pid, address), hook) in self.__hook_objects \ + ## if pid == dwProcessId ] + + # ------------------------------------------------------------------------------ # Batch operations on all breakpoints. @@ -3161,17 +3120,17 @@ def enable_all_breakpoints(self): """ # disable code breakpoints - for (pid, bp) in self.get_all_code_breakpoints(): + for pid, bp in self.get_all_code_breakpoints(): if bp.is_disabled(): self.enable_code_breakpoint(pid, bp.get_address()) # disable page breakpoints - for (pid, bp) in self.get_all_page_breakpoints(): + for pid, bp in self.get_all_page_breakpoints(): if bp.is_disabled(): self.enable_page_breakpoint(pid, bp.get_address()) # disable hardware breakpoints - for (tid, bp) in self.get_all_hardware_breakpoints(): + for tid, bp in self.get_all_hardware_breakpoints(): if bp.is_disabled(): self.enable_hardware_breakpoint(tid, bp.get_address()) @@ -3186,17 +3145,17 @@ def enable_one_shot_all_breakpoints(self): """ # disable code breakpoints for one shot - for (pid, bp) in self.get_all_code_breakpoints(): + for pid, bp in self.get_all_code_breakpoints(): if bp.is_disabled(): self.enable_one_shot_code_breakpoint(pid, bp.get_address()) # disable page breakpoints for one shot - for (pid, bp) in self.get_all_page_breakpoints(): + for pid, bp in self.get_all_page_breakpoints(): if bp.is_disabled(): self.enable_one_shot_page_breakpoint(pid, bp.get_address()) # disable hardware breakpoints for one shot - for (tid, bp) in self.get_all_hardware_breakpoints(): + for tid, bp in self.get_all_hardware_breakpoints(): if bp.is_disabled(): self.enable_one_shot_hardware_breakpoint(tid, bp.get_address()) @@ -3211,15 +3170,15 @@ def disable_all_breakpoints(self): """ # disable code breakpoints - for (pid, bp) in self.get_all_code_breakpoints(): + for pid, bp in self.get_all_code_breakpoints(): self.disable_code_breakpoint(pid, bp.get_address()) # disable page breakpoints - for (pid, bp) in self.get_all_page_breakpoints(): + for pid, bp in self.get_all_page_breakpoints(): self.disable_page_breakpoint(pid, bp.get_address()) # disable hardware breakpoints - for (tid, bp) in self.get_all_hardware_breakpoints(): + for tid, bp in self.get_all_hardware_breakpoints(): self.disable_hardware_breakpoint(tid, bp.get_address()) def erase_all_breakpoints(self): @@ -3240,23 +3199,23 @@ def erase_all_breakpoints(self): # self.__runningBP = dict() # self.__hook_objects = dict() -## # erase hooks -## for (pid, address, hook) in self.get_all_hooks(): -## self.dont_hook_function(pid, address) + ## # erase hooks + ## for (pid, address, hook) in self.get_all_hooks(): + ## self.dont_hook_function(pid, address) # erase code breakpoints - for (pid, bp) in self.get_all_code_breakpoints(): + for pid, bp in self.get_all_code_breakpoints(): self.erase_code_breakpoint(pid, bp.get_address()) # erase page breakpoints - for (pid, bp) in self.get_all_page_breakpoints(): + for pid, bp in self.get_all_page_breakpoints(): self.erase_page_breakpoint(pid, bp.get_address()) # erase hardware breakpoints - for (tid, bp) in self.get_all_hardware_breakpoints(): + for tid, bp in self.get_all_hardware_breakpoints(): self.erase_hardware_breakpoint(tid, bp.get_address()) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Batch operations on breakpoints per process. @@ -3359,9 +3318,9 @@ def erase_process_breakpoints(self, dwProcessId): # if an error occurs, no breakpoint is erased self.disable_process_breakpoints(dwProcessId) -## # erase hooks -## for address, hook in self.get_process_hooks(dwProcessId): -## self.dont_hook_function(dwProcessId, address) + ## # erase hooks + ## for address, hook in self.get_process_hooks(dwProcessId): + ## self.dont_hook_function(dwProcessId, address) # erase code breakpoints for bp in self.get_process_code_breakpoints(dwProcessId): @@ -3382,7 +3341,7 @@ def erase_process_breakpoints(self, dwProcessId): for bp in self.get_thread_hardware_breakpoints(dwThreadId): self.erase_hardware_breakpoint(dwThreadId, bp.get_address()) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Internal handlers of debug events. @@ -3396,9 +3355,9 @@ def _notify_guard_page(self, event): @rtype: bool @return: C{True} to call the user-defined handle, C{False} otherwise. """ - address = event.get_fault_address() - pid = event.get_pid() - bCallHandler = True + address = event.get_fault_address() + pid = event.get_pid() + bCallHandler = True # Align address to page boundary. mask = ~(MemoryAddresses.pageSize - 1) @@ -3409,10 +3368,9 @@ def _notify_guard_page(self, event): if key in self.__pageBP: bp = self.__pageBP[key] if bp.is_enabled() or bp.is_one_shot(): - # Breakpoint is ours. event.continueStatus = win32.DBG_CONTINUE -## event.continueStatus = win32.DBG_EXCEPTION_HANDLED + ## event.continueStatus = win32.DBG_EXCEPTION_HANDLED # Hit the breakpoint. bp.hit(event) @@ -3450,16 +3408,15 @@ def _notify_breakpoint(self, event): @rtype: bool @return: C{True} to call the user-defined handle, C{False} otherwise. """ - address = event.get_exception_address() - pid = event.get_pid() - bCallHandler = True + address = event.get_exception_address() + pid = event.get_pid() + bCallHandler = True # Do we have an active code breakpoint there? key = (pid, address) if key in self.__codeBP: bp = self.__codeBP[key] if not bp.is_disabled(): - # Change the program counter (PC) to the exception address. # This accounts for the change in PC caused by # executing the breakpoint instruction, no matter @@ -3516,12 +3473,12 @@ def _notify_single_step(self, event): @rtype: bool @return: C{True} to call the user-defined handle, C{False} otherwise. """ - pid = event.get_pid() - tid = event.get_tid() - aThread = event.get_thread() - aProcess = event.get_process() - bCallHandler = True - bIsOurs = False + pid = event.get_pid() + tid = event.get_tid() + aThread = event.get_thread() + aProcess = event.get_process() + bCallHandler = True + bIsOurs = False # In hostile mode set the default to pass the exception to the debugee. # If we later determine the exception is ours, hide it instead. @@ -3545,24 +3502,24 @@ def _notify_single_step(self, event): # the trap flag. # bNextIsPopFlags: Don't let popf instructions clear the trap flag. # - bFakeSingleStep = False + bFakeSingleStep = False bLastIsPushFlags = False - bNextIsPopFlags = False + bNextIsPopFlags = False if self.in_hostile_mode(): pc = aThread.get_pc() c = aProcess.read_char(pc - 1) - if c == 0xF1: # int1 - bFakeSingleStep = True - elif c == 0x9C: # pushf + if c == 0xF1: # int1 + bFakeSingleStep = True + elif c == 0x9C: # pushf bLastIsPushFlags = True c = aProcess.peek_char(pc) - if c == 0x66: # the only valid prefix for popf + if c == 0x66: # the only valid prefix for popf c = aProcess.peek_char(pc + 1) - if c == 0x9D: # popf + if c == 0x9D: # popf if bLastIsPushFlags: bLastIsPushFlags = False # they cancel each other out else: - bNextIsPopFlags = True + bNextIsPopFlags = True # When the thread is in tracing mode, # don't pass the exception to the debugee @@ -3580,7 +3537,7 @@ def _notify_single_step(self, event): flags = aProcess.read_dword(sp) if bLastIsPushFlags: flags &= ~Thread.Flags.Trap - else: # if bNextIsPopFlags: + else: # if bNextIsPopFlags: flags |= Thread.Flags.Trap aProcess.write_dword(sp, flags) @@ -3600,20 +3557,19 @@ def _notify_single_step(self, event): # Handle hardware breakpoints. if tid in self.__hardwareBP: - ctx = aThread.get_context(win32.CONTEXT_DEBUG_REGISTERS) - Dr6 = ctx['Dr6'] - ctx['Dr6'] = Dr6 & DebugRegister.clearHitMask + ctx = aThread.get_context(win32.CONTEXT_DEBUG_REGISTERS) + Dr6 = ctx["Dr6"] + ctx["Dr6"] = Dr6 & DebugRegister.clearHitMask aThread.set_context(ctx) bFoundBreakpoint = False - bCondition = False - hwbpList = [ bp for bp in self.__hardwareBP[tid] ] + bCondition = False + hwbpList = [bp for bp in self.__hardwareBP[tid]] for bp in hwbpList: if not bp in self.__hardwareBP[tid]: - continue # it was removed by a user-defined callback + continue # it was removed by a user-defined callback slot = bp.get_slot() - if (slot is not None) and \ - (Dr6 & DebugRegister.hitMask[slot]): - if not bFoundBreakpoint: #set before actions are called + if (slot is not None) and (Dr6 & DebugRegister.hitMask[slot]): + if not bFoundBreakpoint: # set before actions are called if not bFakeSingleStep: event.continueStatus = win32.DBG_CONTINUE bFoundBreakpoint = True @@ -3700,7 +3656,7 @@ def _notify_exit_process(self, event): self.__cleanup_thread(event) return True -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # This is the high level breakpoint interface. Here we don't have to care # about defining or enabling breakpoints, and many errors are ignored @@ -3709,7 +3665,7 @@ def _notify_exit_process(self, event): # and more intuitive, if less detailed. It also allows the use of deferred # breakpoints. -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Code breakpoints @@ -3759,7 +3715,7 @@ def __set_break(self, pid, address, action, oneshot): return None if self.has_code_breakpoint(pid, address): bp = self.get_code_breakpoint(pid, address) - if bp.get_action() != action: # can't use "is not", fails for bound methods + if bp.get_action() != action: # can't use "is not", fails for bound methods bp.set_action(action) msg = "Redefined code breakpoint at %s in process ID %d" msg = msg % (label, pid) @@ -3796,7 +3752,7 @@ def __clear_break(self, pid, address): del deferred[label] unknown = False except KeyError: -## traceback.print_last() # XXX DEBUG + ## traceback.print_last() # XXX DEBUG pass aProcess = self.system.get_process(pid) try: @@ -3804,10 +3760,9 @@ def __clear_break(self, pid, address): if not address: raise Exception() except Exception: -## traceback.print_last() # XXX DEBUG + ## traceback.print_last() # XXX DEBUG if unknown: - msg = ("Can't clear unknown code breakpoint" - " at %s in process ID %d") + msg = "Can't clear unknown code breakpoint" " at %s in process ID %d" msg = msg % (label, pid) warnings.warn(msg, BreakpointWarning) return @@ -3828,7 +3783,7 @@ def __set_deferred_breakpoints(self, event): except KeyError: return aProcess = event.get_process() - for (label, (action, oneshot)) in deferred.items(): + for label, (action, oneshot) in deferred.items(): try: address = aProcess.resolve_label(label) except Exception: @@ -3854,8 +3809,8 @@ def get_all_deferred_code_breakpoints(self): """ result = [] for pid, deferred in compat.iteritems(self.__deferredBP): - for (label, (action, oneshot)) in compat.iteritems(deferred): - result.add( (pid, label, action, oneshot) ) + for label, (action, oneshot) in compat.iteritems(deferred): + result.add((pid, label, action, oneshot)) return result def get_process_deferred_code_breakpoints(self, dwProcessId): @@ -3871,11 +3826,9 @@ def get_process_deferred_code_breakpoints(self, dwProcessId): - Action callback for the breakpoint. - C{True} of the breakpoint is one-shot, C{False} otherwise. """ - return [ (label, action, oneshot) - for (label, (action, oneshot)) - in compat.iteritems(self.__deferredBP.get(dwProcessId, {})) ] + return [(label, action, oneshot) for (label, (action, oneshot)) in compat.iteritems(self.__deferredBP.get(dwProcessId, {}))] - def stalk_at(self, pid, address, action = None): + def stalk_at(self, pid, address, action=None): """ Sets a one shot code breakpoint at the given process and address. @@ -3902,10 +3855,10 @@ def stalk_at(self, pid, address, action = None): @return: C{True} if the breakpoint was set immediately, or C{False} if it was deferred. """ - bp = self.__set_break(pid, address, action, oneshot = True) + bp = self.__set_break(pid, address, action, oneshot=True) return bp is not None - def break_at(self, pid, address, action = None): + def break_at(self, pid, address, action=None): """ Sets a code breakpoint at the given process and address. @@ -3932,7 +3885,7 @@ def break_at(self, pid, address, action = None): @return: C{True} if the breakpoint was set immediately, or C{False} if it was deferred. """ - bp = self.__set_break(pid, address, action, oneshot = False) + bp = self.__set_break(pid, address, action, oneshot=False) return bp is not None def dont_break_at(self, pid, address): @@ -3965,13 +3918,11 @@ def dont_stalk_at(self, pid, address): """ self.__clear_break(pid, address) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Function hooks - def hook_function(self, pid, address, - preCB = None, postCB = None, - paramCount = None, signature = None): + def hook_function(self, pid, address, preCB=None, postCB=None, paramCount=None, signature=None): """ Sets a function hook at the given address. @@ -4051,9 +4002,7 @@ def post_LoadLibraryEx(event, return_value): bp = self.break_at(pid, address, hookObj) return bp is not None - def stalk_function(self, pid, address, - preCB = None, postCB = None, - paramCount = None, signature = None): + def stalk_function(self, pid, address, preCB=None, postCB=None, paramCount=None, signature=None): """ Sets a one-shot function hook at the given address. @@ -4166,7 +4115,7 @@ def dont_stalk_function(self, pid, address): """ self.dont_stalk_at(pid, address) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Variable watches @@ -4211,22 +4160,19 @@ def __set_variable_watch(self, tid, address, size, action): if self.has_hardware_breakpoint(tid, address): warnings.warn( - "Hardware breakpoint in thread %d at address %s was overwritten!" \ - % (tid, HexDump.address(address, - self.system.get_thread(tid).get_bits())), - BreakpointWarning) + "Hardware breakpoint in thread %d at address %s was overwritten!" + % (tid, HexDump.address(address, self.system.get_thread(tid).get_bits())), + BreakpointWarning, + ) bp = self.get_hardware_breakpoint(tid, address) - if bp.get_trigger() != self.BP_BREAK_ON_ACCESS or \ - bp.get_watch() != sizeFlag: - self.erase_hardware_breakpoint(tid, address) - self.define_hardware_breakpoint(tid, address, - self.BP_BREAK_ON_ACCESS, sizeFlag, True, action) - bp = self.get_hardware_breakpoint(tid, address) + if bp.get_trigger() != self.BP_BREAK_ON_ACCESS or bp.get_watch() != sizeFlag: + self.erase_hardware_breakpoint(tid, address) + self.define_hardware_breakpoint(tid, address, self.BP_BREAK_ON_ACCESS, sizeFlag, True, action) + bp = self.get_hardware_breakpoint(tid, address) else: - self.define_hardware_breakpoint(tid, address, - self.BP_BREAK_ON_ACCESS, sizeFlag, True, action) + self.define_hardware_breakpoint(tid, address, self.BP_BREAK_ON_ACCESS, sizeFlag, True, action) bp = self.get_hardware_breakpoint(tid, address) return bp @@ -4244,7 +4190,7 @@ def __clear_variable_watch(self, tid, address): if self.has_hardware_breakpoint(tid, address): self.erase_hardware_breakpoint(tid, address) - def watch_variable(self, tid, address, size, action = None): + def watch_variable(self, tid, address, size, action=None): """ Sets a hardware breakpoint at the given thread, address and size. @@ -4269,7 +4215,7 @@ def watch_variable(self, tid, address, size, action = None): if not bp.is_enabled(): self.enable_hardware_breakpoint(tid, address) - def stalk_variable(self, tid, address, size, action = None): + def stalk_variable(self, tid, address, size, action=None): """ Sets a one-shot hardware breakpoint at the given thread, address and size. @@ -4319,7 +4265,7 @@ def dont_stalk_variable(self, tid, address): """ self.__clear_variable_watch(tid, address) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Buffer watches @@ -4355,31 +4301,29 @@ def __set_buffer_watch(self, pid, address, size, action, bOneShot): bw = BufferWatch(pid, address, address + size, action, bOneShot) # Get the base address and size in pages required for this buffer. - base = MemoryAddresses.align_address_to_page_start(address) + base = MemoryAddresses.align_address_to_page_start(address) limit = MemoryAddresses.align_address_to_page_end(address + size) pages = MemoryAddresses.get_buffer_size_in_pages(address, size) try: - # For each page: # + if a page breakpoint exists reuse it # + if it doesn't exist define it - bset = set() # all breakpoints used - nset = set() # newly defined breakpoints - cset = set() # condition objects + bset = set() # all breakpoints used + nset = set() # newly defined breakpoints + cset = set() # condition objects page_addr = base - pageSize = MemoryAddresses.pageSize + pageSize = MemoryAddresses.pageSize while page_addr < limit: - # If a breakpoints exists, reuse it. if self.has_page_breakpoint(pid, page_addr): bp = self.get_page_breakpoint(pid, page_addr) if bp not in bset: condition = bp.get_condition() if not condition in cset: - if not isinstance(condition,_BufferWatchCondition): + if not isinstance(condition, _BufferWatchCondition): # this shouldn't happen unless you tinkered # with it or defined your own page breakpoints # manually. @@ -4392,8 +4336,7 @@ def __set_buffer_watch(self, pid, address, size, action, bOneShot): # If it doesn't, define it. else: condition = _BufferWatchCondition() - bp = self.define_page_breakpoint(pid, page_addr, 1, - condition = condition) + bp = self.define_page_breakpoint(pid, page_addr, 1, condition=condition) bset.add(bp) nset.add(bp) cset.add(condition) @@ -4409,7 +4352,6 @@ def __set_buffer_watch(self, pid, address, size, action, bOneShot): # On error... except: - # Erase the newly defined breakpoints. for bp in nset: try: @@ -4446,14 +4388,14 @@ def __clear_buffer_watch_old_method(self, pid, address, size): raise ValueError("Bad size for buffer watch: %r" % size) # Get the base address and size in pages required for this buffer. - base = MemoryAddresses.align_address_to_page_start(address) + base = MemoryAddresses.align_address_to_page_start(address) limit = MemoryAddresses.align_address_to_page_end(address + size) pages = MemoryAddresses.get_buffer_size_in_pages(address, size) # For each page, get the breakpoint and it's condition object. # For each condition, remove the buffer. # For each breakpoint, if no buffers are on watch, erase it. - cset = set() # condition objects + cset = set() # condition objects page_addr = base pageSize = MemoryAddresses.pageSize while page_addr < limit: @@ -4483,19 +4425,19 @@ def __clear_buffer_watch(self, bw): """ # Get the PID and the start and end addresses of the buffer. - pid = bw.pid + pid = bw.pid start = bw.start - end = bw.end + end = bw.end # Get the base address and size in pages required for the buffer. - base = MemoryAddresses.align_address_to_page_start(start) + base = MemoryAddresses.align_address_to_page_start(start) limit = MemoryAddresses.align_address_to_page_end(end) pages = MemoryAddresses.get_buffer_size_in_pages(start, end - start) # For each page, get the breakpoint and it's condition object. # For each condition, remove the buffer. # For each breakpoint, if no buffers are on watch, erase it. - cset = set() # condition objects + cset = set() # condition objects page_addr = base pageSize = MemoryAddresses.pageSize while page_addr < limit: @@ -4514,11 +4456,11 @@ def __clear_buffer_watch(self, bw): self.erase_page_breakpoint(pid, bp.get_address()) except WindowsError: msg = "Cannot remove page breakpoint at address %s" - msg = msg % HexDump.address( bp.get_address() ) + msg = msg % HexDump.address(bp.get_address()) warnings.warn(msg, BreakpointWarning) page_addr = page_addr + pageSize - def watch_buffer(self, pid, address, size, action = None): + def watch_buffer(self, pid, address, size, action=None): """ Sets a page breakpoint and notifies when the given buffer is accessed. @@ -4543,7 +4485,7 @@ def watch_buffer(self, pid, address, size, action = None): """ self.__set_buffer_watch(pid, address, size, action, False) - def stalk_buffer(self, pid, address, size, action = None): + def stalk_buffer(self, pid, address, size, action=None): """ Sets a one-shot page breakpoint and notifies when the given buffer is accessed. @@ -4586,12 +4528,12 @@ def dont_watch_buffer(self, bw, *argv, **argd): else: argv = list(argv) argv.insert(0, bw) - if 'pid' in argd: - argv.insert(0, argd.pop('pid')) - if 'address' in argd: - argv.insert(1, argd.pop('address')) - if 'size' in argd: - argv.insert(2, argd.pop('size')) + if "pid" in argd: + argv.insert(0, argd.pop("pid")) + if "address" in argd: + argv.insert(1, argd.pop("address")) + if "size" in argd: + argv.insert(2, argd.pop("size")) if argd: raise TypeError("Wrong arguments for dont_watch_buffer()") try: @@ -4610,12 +4552,12 @@ def dont_stalk_buffer(self, bw, *argv, **argd): """ self.dont_watch_buffer(bw, *argv, **argd) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Tracing -# XXX TODO -# Add "action" parameter to tracing mode + # XXX TODO + # Add "action" parameter to tracing mode def __start_tracing(self, thread): """ @@ -4715,7 +4657,7 @@ def stop_tracing_all(self): for pid in self.get_debugee_pids(): self.stop_tracing_process(pid) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Break on LastError values (only available since Windows Server 2003) @@ -4751,10 +4693,9 @@ def break_on_error(self, pid, errorCode): An error occurred while processing this request. """ aProcess = self.system.get_process(pid) - address = aProcess.get_break_on_error_ptr() + address = aProcess.get_break_on_error_ptr() if not address: - raise NotImplementedError( - "The functionality is not supported in this system.") + raise NotImplementedError("The functionality is not supported in this system.") aProcess.write_dword(address, errorCode) def dont_break_on_error(self, pid): @@ -4772,7 +4713,7 @@ def dont_break_on_error(self, pid): """ self.break_on_error(pid, 0) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Simplified symbol resolving, useful for hooking functions diff --git a/pydevd_attach_to_process/winappdbg/compat.py b/pydevd_attach_to_process/winappdbg/compat.py index ad64901cf..65590f72b 100644 --- a/pydevd_attach_to_process/winappdbg/compat.py +++ b/pydevd_attach_to_process/winappdbg/compat.py @@ -28,21 +28,20 @@ import types - # Useful for very coarse version differentiation. PY2 = sys.version_info[0] == 2 PY3 = sys.version_info[0] == 3 if PY3: - string_types = str, - integer_types = int, - class_types = type, + string_types = (str,) + integer_types = (int,) + class_types = (type,) text_type = str binary_type = bytes MAXSIZE = sys.maxsize else: - string_types = basestring, + string_types = (basestring,) integer_types = (int, long) class_types = (type, types.ClassType) text_type = unicode @@ -56,6 +55,7 @@ class X(object): def __len__(self): return 1 << 31 + try: len(X()) except OverflowError: @@ -71,23 +71,24 @@ def __len__(self): xrange = range unicode = str bytes = bytes + def iterkeys(d, **kw): - if hasattr(d, 'iterkeys'): + if hasattr(d, "iterkeys"): return iter(d.iterkeys(**kw)) return iter(d.keys(**kw)) def itervalues(d, **kw): - if hasattr(d, 'itervalues'): + if hasattr(d, "itervalues"): return iter(d.itervalues(**kw)) return iter(d.values(**kw)) def iteritems(d, **kw): - if hasattr(d, 'iteritems'): + if hasattr(d, "iteritems"): return iter(d.iteritems(**kw)) return iter(d.items(**kw)) def iterlists(d, **kw): - if hasattr(d, 'iterlists'): + if hasattr(d, "iterlists"): return iter(d.iterlists(**kw)) return iter(d.lists(**kw)) @@ -97,6 +98,7 @@ def keys(d, **kw): unicode = unicode xrange = xrange bytes = str + def keys(d, **kw): return d.keys(**kw) @@ -112,10 +114,11 @@ def iteritems(d, **kw): def iterlists(d, **kw): return iter(d.iterlists(**kw)) + if PY3: import builtins - exec_ = getattr(builtins, "exec") + exec_ = getattr(builtins, "exec") def reraise(tp, value, tb=None): if value is None: @@ -125,6 +128,7 @@ def reraise(tp, value, tb=None): raise value else: + def exec_(_code_, _globs_=None, _locs_=None): """Execute code in a namespace.""" if _globs_ is None: @@ -137,23 +141,28 @@ def exec_(_code_, _globs_=None, _locs_=None): _locs_ = _globs_ exec("""exec _code_ in _globs_, _locs_""") - - exec_("""def reraise(tp, value, tb=None): + exec_( + """def reraise(tp, value, tb=None): raise tp, value, tb -""") +""" + ) if PY3: import operator + def b(s): if isinstance(s, str): return s.encode("latin-1") assert isinstance(s, bytes) return s + def u(s): return s + unichr = chr if sys.version_info[1] <= 1: + def int2byte(i): return bytes((i,)) else: @@ -163,21 +172,30 @@ def int2byte(i): indexbytes = operator.getitem iterbytes = iter import io + StringIO = io.StringIO BytesIO = io.BytesIO else: + def b(s): return s + # Workaround for standalone backslash def u(s): - return unicode(s.replace(r'\\', r'\\\\'), "unicode_escape") + return unicode(s.replace(r"\\", r"\\\\"), "unicode_escape") + unichr = unichr int2byte = chr + def byte2int(bs): return ord(bs[0]) + def indexbytes(buf, i): return ord(buf[i]) + def iterbytes(buf): return (ord(byte) for byte in buf) + import StringIO - StringIO = BytesIO = StringIO.StringIO \ No newline at end of file + + StringIO = BytesIO = StringIO.StringIO diff --git a/pydevd_attach_to_process/winappdbg/crash.py b/pydevd_attach_to_process/winappdbg/crash.py index a53172e55..5471ce4e1 100644 --- a/pydevd_attach_to_process/winappdbg/crash.py +++ b/pydevd_attach_to_process/winappdbg/crash.py @@ -45,22 +45,18 @@ __revision__ = "$Id$" __all__ = [ - # Object that represents a crash in the debugee. - 'Crash', - + "Crash", # Crash storage. - 'CrashDictionary', - + "CrashDictionary", # Warnings. - 'CrashWarning', - + "CrashWarning", # Backwards compatibility with WinAppDbg 1.4 and before. - 'CrashContainer', - 'CrashTable', - 'CrashTableMSSQL', - 'VolatileCrashContainer', - 'DummyCrashContainer', + "CrashContainer", + "CrashTable", + "CrashTableMSSQL", + "VolatileCrashContainer", + "DummyCrashContainer", ] from winappdbg import win32 @@ -79,11 +75,12 @@ sql = None anydbm = None -#============================================================================== +# ============================================================================== # Secure alternative to pickle, use it if present. try: import cerealizer + pickle = cerealizer # There is no optimization function for cerealized objects. @@ -102,7 +99,6 @@ def optimize(picklestring): # If cerealizer is not present fallback to the insecure pickle module. except ImportError: - # Faster implementation of the pickle module as a C extension. try: import cPickle as pickle @@ -118,10 +114,12 @@ def optimize(picklestring): try: from pickletools import optimize except ImportError: + def optimize(picklestring): return picklestring -class Marshaller (StaticClass): + +class Marshaller(StaticClass): """ Custom pickler for L{Crash} objects. Optimizes the pickled data when using the standard C{pickle} (or C{cPickle}) module. The pickled data is then @@ -136,18 +134,22 @@ def dumps(obj, protocol=HIGHEST_PROTOCOL): def loads(data): return pickle.loads(zlib.decompress(data)) -#============================================================================== -class CrashWarning (Warning): +# ============================================================================== + + +class CrashWarning(Warning): """ An error occurred while gathering crash data. Some data may be incomplete or missing. """ -#============================================================================== + +# ============================================================================== + # Crash object. Must be serializable. -class Crash (object): +class Crash(object): """ Represents a crash, bug, or another interesting event in the debugee. @@ -427,59 +429,59 @@ def __init__(self, event): """ # First of all, take the timestamp. - self.timeStamp = time.time() + self.timeStamp = time.time() # Notes are initially empty. - self.notes = list() + self.notes = list() # Get the process and thread, but dont't store them in the DB. process = event.get_process() - thread = event.get_thread() + thread = event.get_thread() # Determine the architecture. - self.os = System.os - self.arch = process.get_arch() - self.bits = process.get_bits() + self.os = System.os + self.arch = process.get_arch() + self.bits = process.get_bits() # The following properties are always retrieved for all events. - self.eventCode = event.get_event_code() - self.eventName = event.get_event_name() - self.pid = event.get_pid() - self.tid = event.get_tid() - self.registers = dict(thread.get_context()) - self.labelPC = process.get_label_at_address(self.pc) + self.eventCode = event.get_event_code() + self.eventName = event.get_event_name() + self.pid = event.get_pid() + self.tid = event.get_tid() + self.registers = dict(thread.get_context()) + self.labelPC = process.get_label_at_address(self.pc) # The following properties are only retrieved for some events. - self.commandLine = None - self.environment = None - self.environmentData = None - self.registersPeek = None - self.debugString = None - self.modFileName = None - self.lpBaseOfDll = None - self.exceptionCode = None - self.exceptionName = None + self.commandLine = None + self.environment = None + self.environmentData = None + self.registersPeek = None + self.debugString = None + self.modFileName = None + self.lpBaseOfDll = None + self.exceptionCode = None + self.exceptionName = None self.exceptionDescription = None - self.exceptionAddress = None - self.exceptionLabel = None - self.firstChance = None - self.faultType = None - self.faultAddress = None - self.faultLabel = None - self.isOurBreakpoint = None + self.exceptionAddress = None + self.exceptionLabel = None + self.firstChance = None + self.faultType = None + self.faultAddress = None + self.faultLabel = None + self.isOurBreakpoint = None self.isSystemBreakpoint = None - self.stackTrace = None - self.stackTracePC = None - self.stackTraceLabels = None - self.stackTracePretty = None - self.stackRange = None - self.stackFrame = None - self.stackPeek = None - self.faultCode = None - self.faultMem = None - self.faultPeek = None - self.faultDisasm = None - self.memoryMap = None + self.stackTrace = None + self.stackTracePC = None + self.stackTraceLabels = None + self.stackTracePretty = None + self.stackRange = None + self.stackFrame = None + self.stackPeek = None + self.faultCode = None + self.faultMem = None + self.faultPeek = None + self.faultDisasm = None + self.memoryMap = None # Get information for debug string events. if self.eventCode == win32.OUTPUT_DEBUG_STRING_EVENT: @@ -488,10 +490,12 @@ def __init__(self, event): # Get information for module load and unload events. # For create and exit process events, get the information # for the main module. - elif self.eventCode in (win32.CREATE_PROCESS_DEBUG_EVENT, - win32.EXIT_PROCESS_DEBUG_EVENT, - win32.LOAD_DLL_DEBUG_EVENT, - win32.UNLOAD_DLL_DEBUG_EVENT): + elif self.eventCode in ( + win32.CREATE_PROCESS_DEBUG_EVENT, + win32.EXIT_PROCESS_DEBUG_EVENT, + win32.LOAD_DLL_DEBUG_EVENT, + win32.UNLOAD_DLL_DEBUG_EVENT, + ): aModule = event.get_module() self.modFileName = event.get_filename() if not self.modFileName: @@ -503,50 +507,38 @@ def __init__(self, event): # Get some information for exception events. # To get the remaining information call fetch_extra_data(). elif self.eventCode == win32.EXCEPTION_DEBUG_EVENT: - # Exception information. - self.exceptionCode = event.get_exception_code() - self.exceptionName = event.get_exception_name() - self.exceptionDescription = event.get_exception_description() - self.exceptionAddress = event.get_exception_address() - self.firstChance = event.is_first_chance() - self.exceptionLabel = process.get_label_at_address( - self.exceptionAddress) - if self.exceptionCode in (win32.EXCEPTION_ACCESS_VIOLATION, - win32.EXCEPTION_GUARD_PAGE, - win32.EXCEPTION_IN_PAGE_ERROR): - self.faultType = event.get_fault_type() + self.exceptionCode = event.get_exception_code() + self.exceptionName = event.get_exception_name() + self.exceptionDescription = event.get_exception_description() + self.exceptionAddress = event.get_exception_address() + self.firstChance = event.is_first_chance() + self.exceptionLabel = process.get_label_at_address(self.exceptionAddress) + if self.exceptionCode in (win32.EXCEPTION_ACCESS_VIOLATION, win32.EXCEPTION_GUARD_PAGE, win32.EXCEPTION_IN_PAGE_ERROR): + self.faultType = event.get_fault_type() self.faultAddress = event.get_fault_address() - self.faultLabel = process.get_label_at_address( - self.faultAddress) - elif self.exceptionCode in (win32.EXCEPTION_BREAKPOINT, - win32.EXCEPTION_SINGLE_STEP): - self.isOurBreakpoint = hasattr(event, 'breakpoint') \ - and event.breakpoint - self.isSystemBreakpoint = \ - process.is_system_defined_breakpoint(self.exceptionAddress) + self.faultLabel = process.get_label_at_address(self.faultAddress) + elif self.exceptionCode in (win32.EXCEPTION_BREAKPOINT, win32.EXCEPTION_SINGLE_STEP): + self.isOurBreakpoint = hasattr(event, "breakpoint") and event.breakpoint + self.isSystemBreakpoint = process.is_system_defined_breakpoint(self.exceptionAddress) # Stack trace. try: self.stackTracePretty = thread.get_stack_trace_with_labels() except Exception: e = sys.exc_info()[1] - warnings.warn( - "Cannot get stack trace with labels, reason: %s" % str(e), - CrashWarning) + warnings.warn("Cannot get stack trace with labels, reason: %s" % str(e), CrashWarning) try: - self.stackTrace = thread.get_stack_trace() - stackTracePC = [ ra for (_,ra,_) in self.stackTrace ] - self.stackTracePC = tuple(stackTracePC) - stackTraceLabels = [ process.get_label_at_address(ra) \ - for ra in self.stackTracePC ] + self.stackTrace = thread.get_stack_trace() + stackTracePC = [ra for (_, ra, _) in self.stackTrace] + self.stackTracePC = tuple(stackTracePC) + stackTraceLabels = [process.get_label_at_address(ra) for ra in self.stackTracePC] self.stackTraceLabels = tuple(stackTraceLabels) except Exception: e = sys.exc_info()[1] - warnings.warn("Cannot get stack trace, reason: %s" % str(e), - CrashWarning) + warnings.warn("Cannot get stack trace, reason: %s" % str(e), CrashWarning) - def fetch_extra_data(self, event, takeMemorySnapshot = 0): + def fetch_extra_data(self, event, takeMemorySnapshot=0): """ Fetch extra data from the L{Event} object. @@ -571,25 +563,22 @@ def fetch_extra_data(self, event, takeMemorySnapshot = 0): # Get the process and thread, we'll use them below. process = event.get_process() - thread = event.get_thread() + thread = event.get_thread() # Get the command line for the target process. try: self.commandLine = process.get_command_line() except Exception: e = sys.exc_info()[1] - warnings.warn("Cannot get command line, reason: %s" % str(e), - CrashWarning) + warnings.warn("Cannot get command line, reason: %s" % str(e), CrashWarning) # Get the environment variables for the target process. try: self.environmentData = process.get_environment_data() - self.environment = process.parse_environment_data( - self.environmentData) + self.environment = process.parse_environment_data(self.environmentData) except Exception: e = sys.exc_info()[1] - warnings.warn("Cannot get environment, reason: %s" % str(e), - CrashWarning) + warnings.warn("Cannot get environment, reason: %s" % str(e), CrashWarning) # Data pointed to by registers. self.registersPeek = thread.peek_pointers_in_registers() @@ -605,8 +594,7 @@ def fetch_extra_data(self, event, takeMemorySnapshot = 0): self.stackRange = thread.get_stack_range() except Exception: e = sys.exc_info()[1] - warnings.warn("Cannot get stack range, reason: %s" % str(e), - CrashWarning) + warnings.warn("Cannot get stack range, reason: %s" % str(e), CrashWarning) try: self.stackFrame = thread.get_stack_frame() stackFrame = self.stackFrame @@ -617,29 +605,27 @@ def fetch_extra_data(self, event, takeMemorySnapshot = 0): self.stackPeek = process.peek_pointers_in_data(stackFrame) # Code being executed. - self.faultCode = thread.peek_code_bytes() + self.faultCode = thread.peek_code_bytes() try: self.faultDisasm = thread.disassemble_around_pc(32) except Exception: e = sys.exc_info()[1] - warnings.warn("Cannot disassemble, reason: %s" % str(e), - CrashWarning) + warnings.warn("Cannot disassemble, reason: %s" % str(e), CrashWarning) # For memory related exceptions, get the memory contents # of the location that caused the exception to be raised. if self.eventCode == win32.EXCEPTION_DEBUG_EVENT: if self.pc != self.exceptionAddress and self.exceptionCode in ( - win32.EXCEPTION_ACCESS_VIOLATION, - win32.EXCEPTION_ARRAY_BOUNDS_EXCEEDED, - win32.EXCEPTION_DATATYPE_MISALIGNMENT, - win32.EXCEPTION_IN_PAGE_ERROR, - win32.EXCEPTION_STACK_OVERFLOW, - win32.EXCEPTION_GUARD_PAGE, - ): + win32.EXCEPTION_ACCESS_VIOLATION, + win32.EXCEPTION_ARRAY_BOUNDS_EXCEEDED, + win32.EXCEPTION_DATATYPE_MISALIGNMENT, + win32.EXCEPTION_IN_PAGE_ERROR, + win32.EXCEPTION_STACK_OVERFLOW, + win32.EXCEPTION_GUARD_PAGE, + ): self.faultMem = process.peek(self.exceptionAddress, 64) if self.faultMem: - self.faultPeek = process.peek_pointers_in_data( - self.faultMem) + self.faultPeek = process.peek_pointers_in_data(self.faultMem) # TODO: maybe add names and versions of DLLs and EXE? @@ -650,7 +636,7 @@ def fetch_extra_data(self, event, takeMemorySnapshot = 0): mappedFilenames = process.get_mapped_filenames(self.memoryMap) for mbi in self.memoryMap: mbi.filename = mappedFilenames.get(mbi.BaseAddress, None) - mbi.content = None + mbi.content = None elif takeMemorySnapshot == 2: self.memoryMap = process.take_memory_snapshot() elif takeMemorySnapshot == 3: @@ -664,9 +650,9 @@ def pc(self): @rtype: int """ try: - return self.registers['Eip'] # i386 + return self.registers["Eip"] # i386 except KeyError: - return self.registers['Rip'] # amd64 + return self.registers["Rip"] # amd64 @property def sp(self): @@ -676,9 +662,9 @@ def sp(self): @rtype: int """ try: - return self.registers['Esp'] # i386 + return self.registers["Esp"] # i386 except KeyError: - return self.registers['Rsp'] # amd64 + return self.registers["Rsp"] # amd64 @property def fp(self): @@ -688,9 +674,9 @@ def fp(self): @rtype: int """ try: - return self.registers['Ebp'] # i386 + return self.registers["Ebp"] # i386 except KeyError: - return self.registers['Rbp'] # amd64 + return self.registers["Rbp"] # amd64 def __str__(self): return self.fullReport() @@ -699,8 +685,7 @@ def key(self): """ Alias of L{signature}. Deprecated since WinAppDbg 1.5. """ - warnings.warn("Crash.key() method was deprecated in WinAppDbg 1.5", - DeprecationWarning) + warnings.warn("Crash.key() method was deprecated in WinAppDbg 1.5", DeprecationWarning) return self.signature @property @@ -713,14 +698,14 @@ def signature(self): trace = self.stackTraceLabels else: trace = self.stackTracePC - return ( - self.arch, - self.eventCode, - self.exceptionCode, - pc, - trace, - self.debugString, - ) + return ( + self.arch, + self.eventCode, + self.exceptionCode, + pc, + trace, + self.debugString, + ) # TODO # add the name and version of the binary where the crash happened? @@ -770,47 +755,95 @@ def isExploitable(self): return ("Exploitable", "StackPointerCorruption", "Stack pointer corruption is considered exploitable.") if self.exceptionCode == win32.EXCEPTION_ILLEGAL_INSTRUCTION: - return ("Exploitable", "IllegalInstruction", "An illegal instruction exception indicates that the attacker controls execution flow.") + return ( + "Exploitable", + "IllegalInstruction", + "An illegal instruction exception indicates that the attacker controls execution flow.", + ) if self.exceptionCode == win32.EXCEPTION_PRIV_INSTRUCTION: - return ("Exploitable", "PrivilegedInstruction", "A privileged instruction exception indicates that the attacker controls execution flow.") + return ( + "Exploitable", + "PrivilegedInstruction", + "A privileged instruction exception indicates that the attacker controls execution flow.", + ) if self.exceptionCode == win32.EXCEPTION_GUARD_PAGE: - return ("Exploitable", "GuardPage", "A guard page violation indicates a stack overflow has occured, and the stack of another thread was reached (possibly the overflow length is not controlled by the attacker).") + return ( + "Exploitable", + "GuardPage", + "A guard page violation indicates a stack overflow has occured, and the stack of another thread was reached (possibly the overflow length is not controlled by the attacker).", + ) if self.exceptionCode == win32.STATUS_STACK_BUFFER_OVERRUN: - return ("Exploitable", "GSViolation", "An overrun of a protected stack buffer has been detected. This is considered exploitable, and must be fixed.") + return ( + "Exploitable", + "GSViolation", + "An overrun of a protected stack buffer has been detected. This is considered exploitable, and must be fixed.", + ) if self.exceptionCode == win32.STATUS_HEAP_CORRUPTION: - return ("Exploitable", "HeapCorruption", "Heap Corruption has been detected. This is considered exploitable, and must be fixed.") + return ( + "Exploitable", + "HeapCorruption", + "Heap Corruption has been detected. This is considered exploitable, and must be fixed.", + ) if self.exceptionCode == win32.EXCEPTION_ACCESS_VIOLATION: - nearNull = self.faultAddress is None or MemoryAddresses.align_address_to_page_start(self.faultAddress) == 0 - controlFlow = self.__is_control_flow() + nearNull = self.faultAddress is None or MemoryAddresses.align_address_to_page_start(self.faultAddress) == 0 + controlFlow = self.__is_control_flow() blockDataMove = self.__is_block_data_move() if self.faultType == win32.EXCEPTION_EXECUTE_FAULT: if nearNull: - return ("Probably exploitable", "DEPViolation", "User mode DEP access violations are probably exploitable if near NULL.") + return ( + "Probably exploitable", + "DEPViolation", + "User mode DEP access violations are probably exploitable if near NULL.", + ) else: return ("Exploitable", "DEPViolation", "User mode DEP access violations are exploitable.") elif self.faultType == win32.EXCEPTION_WRITE_FAULT: if nearNull: - return ("Probably exploitable", "WriteAV", "User mode write access violations that are near NULL are probably exploitable.") + return ( + "Probably exploitable", + "WriteAV", + "User mode write access violations that are near NULL are probably exploitable.", + ) else: return ("Exploitable", "WriteAV", "User mode write access violations that are not near NULL are exploitable.") elif self.faultType == win32.EXCEPTION_READ_FAULT: if self.faultAddress == self.pc: if nearNull: - return ("Probably exploitable", "ReadAVonIP", "Access violations at the instruction pointer are probably exploitable if near NULL.") + return ( + "Probably exploitable", + "ReadAVonIP", + "Access violations at the instruction pointer are probably exploitable if near NULL.", + ) else: - return ("Exploitable", "ReadAVonIP", "Access violations at the instruction pointer are exploitable if not near NULL.") + return ( + "Exploitable", + "ReadAVonIP", + "Access violations at the instruction pointer are exploitable if not near NULL.", + ) if controlFlow: if nearNull: - return ("Probably exploitable", "ReadAVonControlFlow", "Access violations near null in control flow instructions are considered probably exploitable.") + return ( + "Probably exploitable", + "ReadAVonControlFlow", + "Access violations near null in control flow instructions are considered probably exploitable.", + ) else: - return ("Exploitable", "ReadAVonControlFlow", "Access violations not near null in control flow instructions are considered exploitable.") + return ( + "Exploitable", + "ReadAVonControlFlow", + "Access violations not near null in control flow instructions are considered exploitable.", + ) if blockDataMove: - return ("Probably exploitable", "ReadAVonBlockMove", "This is a read access violation in a block data move, and is therefore classified as probably exploitable.") + return ( + "Probably exploitable", + "ReadAVonBlockMove", + "This is a read access violation in a block data move, and is therefore classified as probably exploitable.", + ) # Rule: Tainted information used to control branch addresses is considered probably exploitable # Rule: Tainted information used to control the target of a later write is probably exploitable @@ -826,7 +859,11 @@ def isExploitable(self): if self.exceptionCode == win32.EXCEPTION_ACCESS_VIOLATION: if self.faultType == win32.EXCEPTION_READ_FAULT: if nearNull: - result = ("Not likely exploitable", "ReadAVNearNull", "This is a user mode read access violation near null, and is probably not exploitable.") + result = ( + "Not likely exploitable", + "ReadAVNearNull", + "This is a user mode read access violation near null, and is probably not exploitable.", + ) elif self.exceptionCode == win32.EXCEPTION_INT_DIVIDE_BY_ZERO: result = ("Not likely exploitable", "DivideByZero", "This is an integer divide by zero, and is probably not exploitable.") @@ -835,7 +872,11 @@ def isExploitable(self): result = ("Not likely exploitable", "DivideByZero", "This is a floating point divide by zero, and is probably not exploitable.") elif self.exceptionCode in (win32.EXCEPTION_BREAKPOINT, win32.STATUS_WX86_BREAKPOINT): - result = ("Unknown", "Breakpoint", "While a breakpoint itself is probably not exploitable, it may also be an indication that an attacker is testing a target. In either case breakpoints should not exist in production code.") + result = ( + "Unknown", + "Breakpoint", + "While a breakpoint itself is probably not exploitable, it may also be an indication that an attacker is testing a target. In either case breakpoints should not exist in production code.", + ) # Rule: If the stack contains unknown symbols in user mode, call that out # Rule: Tainted information used to control the source of a later block move unknown, but called out explicitly @@ -852,15 +893,43 @@ def __is_control_flow(self): Currently only works for x86 and amd64 architectures. """ jump_instructions = ( - 'jmp', 'jecxz', 'jcxz', - 'ja', 'jnbe', 'jae', 'jnb', 'jb', 'jnae', 'jbe', 'jna', 'jc', 'je', - 'jz', 'jnc', 'jne', 'jnz', 'jnp', 'jpo', 'jp', 'jpe', 'jg', 'jnle', - 'jge', 'jnl', 'jl', 'jnge', 'jle', 'jng', 'jno', 'jns', 'jo', 'js' + "jmp", + "jecxz", + "jcxz", + "ja", + "jnbe", + "jae", + "jnb", + "jb", + "jnae", + "jbe", + "jna", + "jc", + "je", + "jz", + "jnc", + "jne", + "jnz", + "jnp", + "jpo", + "jp", + "jpe", + "jg", + "jnle", + "jge", + "jnl", + "jl", + "jnge", + "jle", + "jng", + "jno", + "jns", + "jo", + "js", ) - call_instructions = ( 'call', 'ret', 'retn' ) - loop_instructions = ( 'loop', 'loopz', 'loopnz', 'loope', 'loopne' ) - control_flow_instructions = call_instructions + loop_instructions + \ - jump_instructions + call_instructions = ("call", "ret", "retn") + loop_instructions = ("loop", "loopz", "loopnz", "loope", "loopne") + control_flow_instructions = call_instructions + loop_instructions + jump_instructions isControlFlow = False instruction = None if self.pc is not None and self.faultDisasm: @@ -882,7 +951,7 @@ def __is_block_data_move(self): Currently only works for x86 and amd64 architectures. """ - block_data_move_instructions = ('movs', 'stos', 'lods') + block_data_move_instructions = ("movs", "stos", "lods") isBlockDataMove = False instruction = None if self.pc is not None and self.faultDisasm: @@ -915,12 +984,11 @@ def briefReport(self): elif self.exceptionName: what = self.exceptionName else: - what = "Exception %s" % \ - HexDump.integer(self.exceptionCode, self.bits) + what = "Exception %s" % HexDump.integer(self.exceptionCode, self.bits) if self.firstChance: - chance = 'first' + chance = "first" else: - chance = 'second' + chance = "second" if self.exceptionLabel: where = self.exceptionLabel elif self.exceptionAddress: @@ -941,14 +1009,10 @@ def briefReport(self): where = self.labelPC else: where = HexDump.address(self.pc, self.bits) - msg = "%s (%s) at %s" % ( - self.eventName, - HexDump.integer(self.eventCode, self.bits), - where - ) + msg = "%s (%s) at %s" % (self.eventName, HexDump.integer(self.eventCode, self.bits), where) return msg - def fullReport(self, bShowNotes = True): + def fullReport(self, bShowNotes=True): """ @type bShowNotes: bool @param bShowNotes: C{True} to show the user notes, C{False} otherwise. @@ -956,8 +1020,8 @@ def fullReport(self, bShowNotes = True): @rtype: str @return: Long description of the event. """ - msg = self.briefReport() - msg += '\n' + msg = self.briefReport() + msg += "\n" if self.bits == 32: width = 16 @@ -966,89 +1030,76 @@ def fullReport(self, bShowNotes = True): if self.eventCode == win32.EXCEPTION_DEBUG_EVENT: (exploitability, expcode, expdescription) = self.isExploitable() - msg += '\nSecurity risk level: %s\n' % exploitability - msg += ' %s\n' % expdescription + msg += "\nSecurity risk level: %s\n" % exploitability + msg += " %s\n" % expdescription if bShowNotes and self.notes: - msg += '\nNotes:\n' + msg += "\nNotes:\n" msg += self.notesReport() if self.commandLine: - msg += '\nCommand line: %s\n' % self.commandLine + msg += "\nCommand line: %s\n" % self.commandLine if self.environment: - msg += '\nEnvironment:\n' + msg += "\nEnvironment:\n" msg += self.environmentReport() if not self.labelPC: base = HexDump.address(self.lpBaseOfDll, self.bits) if self.modFileName: - fn = PathOperations.pathname_to_filename(self.modFileName) - msg += '\nRunning in %s (%s)\n' % (fn, base) + fn = PathOperations.pathname_to_filename(self.modFileName) + msg += "\nRunning in %s (%s)\n" % (fn, base) else: - msg += '\nRunning in module at %s\n' % base + msg += "\nRunning in module at %s\n" % base if self.registers: - msg += '\nRegisters:\n' + msg += "\nRegisters:\n" msg += CrashDump.dump_registers(self.registers) if self.registersPeek: - msg += '\n' - msg += CrashDump.dump_registers_peek(self.registers, - self.registersPeek, - width = width) + msg += "\n" + msg += CrashDump.dump_registers_peek(self.registers, self.registersPeek, width=width) if self.faultDisasm: - msg += '\nCode disassembly:\n' - msg += CrashDump.dump_code(self.faultDisasm, self.pc, - bits = self.bits) + msg += "\nCode disassembly:\n" + msg += CrashDump.dump_code(self.faultDisasm, self.pc, bits=self.bits) if self.stackTrace: - msg += '\nStack trace:\n' + msg += "\nStack trace:\n" if self.stackTracePretty: - msg += CrashDump.dump_stack_trace_with_labels( - self.stackTracePretty, - bits = self.bits) + msg += CrashDump.dump_stack_trace_with_labels(self.stackTracePretty, bits=self.bits) else: - msg += CrashDump.dump_stack_trace(self.stackTrace, - bits = self.bits) + msg += CrashDump.dump_stack_trace(self.stackTrace, bits=self.bits) if self.stackFrame: if self.stackPeek: - msg += '\nStack pointers:\n' - msg += CrashDump.dump_stack_peek(self.stackPeek, width = width) - msg += '\nStack dump:\n' - msg += HexDump.hexblock(self.stackFrame, self.sp, - bits = self.bits, width = width) + msg += "\nStack pointers:\n" + msg += CrashDump.dump_stack_peek(self.stackPeek, width=width) + msg += "\nStack dump:\n" + msg += HexDump.hexblock(self.stackFrame, self.sp, bits=self.bits, width=width) if self.faultCode and not self.modFileName: - msg += '\nCode dump:\n' - msg += HexDump.hexblock(self.faultCode, self.pc, - bits = self.bits, width = width) + msg += "\nCode dump:\n" + msg += HexDump.hexblock(self.faultCode, self.pc, bits=self.bits, width=width) if self.faultMem: if self.faultPeek: - msg += '\nException address pointers:\n' - msg += CrashDump.dump_data_peek(self.faultPeek, - self.exceptionAddress, - bits = self.bits, - width = width) - msg += '\nException address dump:\n' - msg += HexDump.hexblock(self.faultMem, self.exceptionAddress, - bits = self.bits, width = width) + msg += "\nException address pointers:\n" + msg += CrashDump.dump_data_peek(self.faultPeek, self.exceptionAddress, bits=self.bits, width=width) + msg += "\nException address dump:\n" + msg += HexDump.hexblock(self.faultMem, self.exceptionAddress, bits=self.bits, width=width) if self.memoryMap: - msg += '\nMemory map:\n' + msg += "\nMemory map:\n" mappedFileNames = dict() for mbi in self.memoryMap: - if hasattr(mbi, 'filename') and mbi.filename: + if hasattr(mbi, "filename") and mbi.filename: mappedFileNames[mbi.BaseAddress] = mbi.filename - msg += CrashDump.dump_memory_map(self.memoryMap, mappedFileNames, - bits = self.bits) + msg += CrashDump.dump_memory_map(self.memoryMap, mappedFileNames, bits=self.bits) - if not msg.endswith('\n\n'): - if not msg.endswith('\n'): - msg += '\n' - msg += '\n' + if not msg.endswith("\n\n"): + if not msg.endswith("\n"): + msg += "\n" + msg += "\n" return msg def environmentReport(self): @@ -1057,10 +1108,10 @@ def environmentReport(self): @return: The process environment variables, merged and formatted for a report. """ - msg = '' + msg = "" if self.environment: for key, value in compat.iteritems(self.environment): - msg += ' %s=%s\n' % (key, value) + msg += " %s=%s\n" % (key, value) return msg def notesReport(self): @@ -1068,17 +1119,17 @@ def notesReport(self): @rtype: str @return: All notes, merged and formatted for a report. """ - msg = '' + msg = "" if self.notes: for n in self.notes: - n = n.strip('\n') - if '\n' in n: - n = n.strip('\n') - msg += ' * %s\n' % n.pop(0) + n = n.strip("\n") + if "\n" in n: + n = n.strip("\n") + msg += " * %s\n" % n.pop(0) for x in n: - msg += ' %s\n' % x + msg += " %s\n" % x else: - msg += ' * %s\n' % n + msg += " * %s\n" % n return msg def addNote(self, msg): @@ -1119,11 +1170,13 @@ def hasNotes(self): @rtype: bool @return: C{True} if there are notes for this crash event. """ - return bool( self.notes ) + return bool(self.notes) + -#============================================================================== +# ============================================================================== -class CrashContainer (object): + +class CrashContainer(object): """ Old crash dump persistencer using a DBM database. Doesn't support duplicate crashes. @@ -1181,16 +1234,16 @@ class CrashContainer (object): C{buffer} type), C{False} to use text marshalled values (C{str} type). """ - optimizeKeys = False - optimizeValues = True - compressKeys = False - compressValues = True - escapeKeys = False - escapeValues = False - binaryKeys = False - binaryValues = False + optimizeKeys = False + optimizeValues = True + compressKeys = False + compressValues = True + escapeKeys = False + escapeValues = False + binaryKeys = False + binaryValues = False - def __init__(self, filename = None, allowRepeatedKeys = False): + def __init__(self, filename=None, allowRepeatedKeys=False): """ @type filename: str @param filename: (Optional) File name for crash database. @@ -1210,9 +1263,8 @@ def __init__(self, filename = None, allowRepeatedKeys = False): global anydbm if not anydbm: import anydbm - self.__db = anydbm.open(filename, 'c') - self.__keys = dict([ (self.unmarshall_key(mk), mk) - for mk in self.__db.keys() ]) + self.__db = anydbm.open(filename, "c") + self.__keys = dict([(self.unmarshall_key(mk), mk) for mk in self.__db.keys()]) else: self.__db = dict() self.__keys = dict() @@ -1240,11 +1292,11 @@ def marshall_key(self, key): """ if key in self.__keys: return self.__keys[key] - skey = pickle.dumps(key, protocol = 0) + skey = pickle.dumps(key, protocol=0) if self.compressKeys: skey = zlib.compress(skey, zlib.Z_BEST_COMPRESSION) if self.escapeKeys: - skey = skey.encode('hex') + skey = skey.encode("hex") if self.binaryKeys: skey = buffer(skey) self.__keys[key] = skey @@ -1262,13 +1314,13 @@ def unmarshall_key(self, key): """ key = str(key) if self.escapeKeys: - key = key.decode('hex') + key = key.decode("hex") if self.compressKeys: key = zlib.decompress(key) key = pickle.loads(key) return key - def marshall_value(self, value, storeMemoryMap = False): + def marshall_value(self, value, storeMemoryMap=False): """ Marshalls a Crash object to be used in the database. By default the C{memoryMap} member is B{NOT} stored here. @@ -1286,7 +1338,7 @@ def marshall_value(self, value, storeMemoryMap = False): @rtype: str @return: Converted object. """ - if hasattr(value, 'memoryMap'): + if hasattr(value, "memoryMap"): crash = value memoryMap = crash.memoryMap try: @@ -1295,10 +1347,10 @@ def marshall_value(self, value, storeMemoryMap = False): # convert the generator to a list crash.memoryMap = list(memoryMap) if self.optimizeValues: - value = pickle.dumps(crash, protocol = HIGHEST_PROTOCOL) + value = pickle.dumps(crash, protocol=HIGHEST_PROTOCOL) value = optimize(value) else: - value = pickle.dumps(crash, protocol = 0) + value = pickle.dumps(crash, protocol=0) finally: crash.memoryMap = memoryMap del memoryMap @@ -1306,7 +1358,7 @@ def marshall_value(self, value, storeMemoryMap = False): if self.compressValues: value = zlib.compress(value, zlib.Z_BEST_COMPRESSION) if self.escapeValues: - value = value.encode('hex') + value = value.encode("hex") if self.binaryValues: value = buffer(value) return value @@ -1323,7 +1375,7 @@ def unmarshall_value(self, value): """ value = str(value) if self.escapeValues: - value = value.decode('hex') + value = value.decode("hex") if self.compressValues: value = zlib.decompress(value) value = pickle.loads(value) @@ -1357,7 +1409,7 @@ def __contains__(self, crash): @return: C{True} if a Crash object with the same key is in the container. """ - return self.has_key( crash.key() ) + return self.has_key(crash.key()) def has_key(self, key): """ @@ -1376,7 +1428,7 @@ def iterkeys(self): """ return compat.iterkeys(self.__keys) - class __CrashContainerIterator (object): + class __CrashContainerIterator(object): """ Iterator of Crash objects. Returned by L{CrashContainer.__iter__}. """ @@ -1402,7 +1454,7 @@ def next(self): @return: A B{copy} of a Crash object in the L{CrashContainer}. @raise StopIteration: No more items left. """ - key = self.__keys_iter.next() + key = self.__keys_iter.next() return self.__container.get(key) def __del__(self): @@ -1447,9 +1499,9 @@ def add(self, crash): @param crash: Crash object to add. """ if crash not in self: - key = crash.key() + key = crash.key() skey = self.marshall_key(key) - data = self.marshall_value(crash, storeMemoryMap = True) + data = self.marshall_value(crash, storeMemoryMap=True) self.__db[skey] = data def __delitem__(self, key): @@ -1470,7 +1522,7 @@ def remove(self, crash): @type crash: L{Crash} @param crash: Crash object to remove. """ - del self[ crash.key() ] + del self[crash.key()] def get(self, key): """ @@ -1491,8 +1543,8 @@ def get(self, key): 2. Delete the object from the set. 3. Modify the object and add it again. """ - skey = self.marshall_key(key) - data = self.__db[skey] + skey = self.marshall_key(key) + data = self.__db[skey] crash = self.unmarshall_value(data) return crash @@ -1517,7 +1569,9 @@ def __getitem__(self, key): """ return self.get(key) -#============================================================================== + +# ============================================================================== + class CrashDictionary(object): """ @@ -1526,7 +1580,7 @@ class CrashDictionary(object): Currently the only implementation is through L{sql.CrashDAO}. """ - def __init__(self, url, creator = None, allowRepeatedKeys = True): + def __init__(self, url, creator=None, allowRepeatedKeys=True): """ @type url: str @param url: Connection URL of the crash database. @@ -1599,7 +1653,7 @@ def __iter__(self): @return: Iterator of the contained L{Crash} objects. """ offset = 0 - limit = 10 + limit = 10 while 1: found = self._dao.find(offset=offset, limit=limit) if not found: @@ -1621,7 +1675,7 @@ def iterkeys(self): @return: Iterator of the contained L{Crash} heuristic signatures. """ for crash in self: - yield crash.signature # FIXME this gives repeated results! + yield crash.signature # FIXME this gives repeated results! def __contains__(self, crash): """ @@ -1655,7 +1709,8 @@ def __bool__(self): @rtype: bool @return: C{False} if the container is empty. """ - return bool( len(self) ) + return bool(len(self)) + class CrashTable(CrashDictionary): """ @@ -1666,7 +1721,7 @@ class CrashTable(CrashDictionary): New applications should not use this class. """ - def __init__(self, location = None, allowRepeatedKeys = True): + def __init__(self, location=None, allowRepeatedKeys=True): """ @type location: str @param location: (Optional) Location of the crash database. @@ -1683,16 +1738,15 @@ def __init__(self, location = None, allowRepeatedKeys = True): If C{False} any L{Crash} object with the same signature as a previously existing object will be ignored. """ - warnings.warn( - "The %s class is deprecated since WinAppDbg 1.5." % self.__class__, - DeprecationWarning) + warnings.warn("The %s class is deprecated since WinAppDbg 1.5." % self.__class__, DeprecationWarning) if location: url = "sqlite:///%s" % location else: url = "sqlite://" super(CrashTable, self).__init__(url, allowRepeatedKeys) -class CrashTableMSSQL (CrashDictionary): + +class CrashTableMSSQL(CrashDictionary): """ Old crash dump persistencer using a Microsoft SQL Server database. @@ -1701,7 +1755,7 @@ class CrashTableMSSQL (CrashDictionary): New applications should not use this class. """ - def __init__(self, location = None, allowRepeatedKeys = True): + def __init__(self, location=None, allowRepeatedKeys=True): """ @type location: str @param location: Location of the crash database. @@ -1714,14 +1768,14 @@ def __init__(self, location = None, allowRepeatedKeys = True): If C{False} any L{Crash} object with the same signature as a previously existing object will be ignored. """ - warnings.warn( - "The %s class is deprecated since WinAppDbg 1.5." % self.__class__, - DeprecationWarning) + warnings.warn("The %s class is deprecated since WinAppDbg 1.5." % self.__class__, DeprecationWarning) import urllib + url = "mssql+pyodbc:///?odbc_connect=" + urllib.quote_plus(location) super(CrashTableMSSQL, self).__init__(url, allowRepeatedKeys) -class VolatileCrashContainer (CrashTable): + +class VolatileCrashContainer(CrashTable): """ Old in-memory crash dump storage. @@ -1730,7 +1784,7 @@ class VolatileCrashContainer (CrashTable): New applications should not use this class. """ - def __init__(self, allowRepeatedKeys = True): + def __init__(self, allowRepeatedKeys=True): """ Volatile containers are stored only in memory and destroyed when they go out of scope. @@ -1742,8 +1796,8 @@ def __init__(self, allowRepeatedKeys = True): If C{False} any L{Crash} object with the same key as a previously existing object will be ignored. """ - super(VolatileCrashContainer, self).__init__( - allowRepeatedKeys=allowRepeatedKeys) + super(VolatileCrashContainer, self).__init__(allowRepeatedKeys=allowRepeatedKeys) + class DummyCrashContainer(object): """ @@ -1756,7 +1810,7 @@ class DummyCrashContainer(object): @see: L{CrashDictionary} """ - def __init__(self, allowRepeatedKeys = True): + def __init__(self, allowRepeatedKeys=True): """ Fake containers don't store L{Crash} objects, but they implement the interface properly. @@ -1765,7 +1819,7 @@ def __init__(self, allowRepeatedKeys = True): @param allowRepeatedKeys: Mimics the duplicate filter behavior found in real containers. """ - self.__keys = set() + self.__keys = set() self.__count = 0 self.__allowRepeatedKeys = allowRepeatedKeys @@ -1786,14 +1840,14 @@ def __len__(self): """ if self.__allowRepeatedKeys: return self.__count - return len( self.__keys ) + return len(self.__keys) def __bool__(self): """ @rtype: bool @return: C{False} if the container is empty. """ - return bool( len(self) ) + return bool(len(self)) def add(self, crash): """ @@ -1808,7 +1862,7 @@ def add(self, crash): @type crash: L{Crash} @param crash: Crash object to add. """ - self.__keys.add( crash.signature ) + self.__keys.add(crash.signature) self.__count += 1 def get(self, key): @@ -1825,7 +1879,7 @@ def has_key(self, key): @rtype: bool @return: C{True} if a matching L{Crash} object is in the container. """ - return self.__keys.has_key( key ) + return self.__keys.has_key(key) def iterkeys(self): """ @@ -1843,7 +1897,8 @@ def iterkeys(self): """ return iter(self.__keys) -#============================================================================== + +# ============================================================================== # Register the Crash class with the secure serializer. try: diff --git a/pydevd_attach_to_process/winappdbg/debug.py b/pydevd_attach_to_process/winappdbg/debug.py index 8364a5b8c..8d7a4a49e 100644 --- a/pydevd_attach_to_process/winappdbg/debug.py +++ b/pydevd_attach_to_process/winappdbg/debug.py @@ -40,7 +40,7 @@ __revision__ = "$Id$" -__all__ = [ 'Debug', 'MixedBitsWarning' ] +__all__ = ["Debug", "MixedBitsWarning"] import sys from winappdbg import win32 @@ -56,17 +56,19 @@ import warnings ##import traceback -#============================================================================== +# ============================================================================== + # If you set this warning to be considered as an error, you can stop the # debugger from attaching to 64-bit processes from a 32-bit Python VM and # visceversa. -class MixedBitsWarning (RuntimeWarning): +class MixedBitsWarning(RuntimeWarning): """ This warning is issued when mixing 32 and 64 bit processes. """ -#============================================================================== + +# ============================================================================== # TODO # * Add memory read and write operations, similar to those in the Process @@ -81,7 +83,8 @@ class MixedBitsWarning (RuntimeWarning): # not such a great idea to use the snapshot to store data that really belongs # to the Debug class. -class Debug (EventDispatcher, _BreakpointContainer): + +class Debug(EventDispatcher, _BreakpointContainer): """ The main debugger class. @@ -107,8 +110,7 @@ class Debug (EventDispatcher, _BreakpointContainer): # Automatically set to True the first time a Debug object is instanced. _debug_static_init = False - def __init__(self, eventHandler = None, bKillOnExit = False, - bHostileCode = False): + def __init__(self, eventHandler=None, bKillOnExit=False, bHostileCode=False): """ Debugger object. @@ -141,14 +143,14 @@ def __init__(self, eventHandler = None, bKillOnExit = False, EventDispatcher.__init__(self, eventHandler) _BreakpointContainer.__init__(self) - self.system = System() - self.lastEvent = None - self.__firstDebugee = True - self.__bKillOnExit = bKillOnExit - self.__bHostileCode = bHostileCode - self.__breakOnEP = set() # set of pids - self.__attachedDebugees = set() # set of pids - self.__startedDebugees = set() # set of pids + self.system = System() + self.lastEvent = None + self.__firstDebugee = True + self.__bKillOnExit = bKillOnExit + self.__bHostileCode = bHostileCode + self.__breakOnEP = set() # set of pids + self.__attachedDebugees = set() # set of pids + self.__startedDebugees = set() # set of pids if not self._debug_static_init: self._debug_static_init = True @@ -156,19 +158,19 @@ def __init__(self, eventHandler = None, bKillOnExit = False, # Request debug privileges for the current process. # Only do this once, and only after instancing a Debug object, # so passive debuggers don't get detected because of this. - self.system.request_debug_privileges(bIgnoreExceptions = False) + self.system.request_debug_privileges(bIgnoreExceptions=False) # Try to fix the symbol store path if it wasn't set. # But don't enable symbol downloading by default, since it may # degrade performance severely. - self.system.fix_symbol_store_path(remote = False, force = False) + self.system.fix_symbol_store_path(remote=False, force=False) -## # It's hard not to create circular references, -## # and if we have a destructor, we can end up leaking everything. -## # It's best to code the debugging loop properly to always -## # stop the debugger before going out of scope. -## def __del__(self): -## self.stop() + ## # It's hard not to create circular references, + ## # and if we have a destructor, we can end up leaking everything. + ## # It's best to code the debugging loop properly to always + ## # stop the debugger before going out of scope. + ## def __del__(self): + ## self.stop() def __enter__(self): """ @@ -193,7 +195,7 @@ def __len__(self): # it already does work (because of __len__) but it'd be # useful to do it from the event handler anyway -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def __setSystemKillOnExitMode(self): # Make sure the default system behavior on detaching from processes @@ -237,8 +239,7 @@ def attach(self, dwProcessId): # This also allows the user to stop attaching altogether, # depending on how the warnings are configured. if System.bits != aProcess.get_bits(): - msg = "Mixture of 32 and 64 bits is considered experimental." \ - " Use at your own risk!" + msg = "Mixture of 32 and 64 bits is considered experimental." " Use at your own risk!" warnings.warn(msg, MixedBitsWarning) # Attach to the process. @@ -434,55 +435,46 @@ def execl(self, lpCmdLine, **kwargs): warnings.warn("Debug.execl expects a string") # Set the "debug" flag to True. - kwargs['bDebug'] = True + kwargs["bDebug"] = True # Pop the "break on entry point" flag. - bBreakOnEntryPoint = kwargs.pop('bBreakOnEntryPoint', False) + bBreakOnEntryPoint = kwargs.pop("bBreakOnEntryPoint", False) # Set the default trust level if requested. - if 'iTrustLevel' not in kwargs: + if "iTrustLevel" not in kwargs: if self.__bHostileCode: - kwargs['iTrustLevel'] = 0 + kwargs["iTrustLevel"] = 0 else: - kwargs['iTrustLevel'] = 2 + kwargs["iTrustLevel"] = 2 # Set the default UAC elevation flag if requested. - if 'bAllowElevation' not in kwargs: - kwargs['bAllowElevation'] = not self.__bHostileCode + if "bAllowElevation" not in kwargs: + kwargs["bAllowElevation"] = not self.__bHostileCode # In hostile mode the default parent process is explorer.exe. # Only supported for Windows Vista and above. - if self.__bHostileCode and not kwargs.get('dwParentProcessId', None): + if self.__bHostileCode and not kwargs.get("dwParentProcessId", None): try: vista_and_above = self.__vista_and_above except AttributeError: osi = win32.OSVERSIONINFOEXW() osi.dwMajorVersion = 6 osi.dwMinorVersion = 0 - osi.dwPlatformId = win32.VER_PLATFORM_WIN32_NT + osi.dwPlatformId = win32.VER_PLATFORM_WIN32_NT mask = 0 - mask = win32.VerSetConditionMask(mask, - win32.VER_MAJORVERSION, - win32.VER_GREATER_EQUAL) - mask = win32.VerSetConditionMask(mask, - win32.VER_MAJORVERSION, - win32.VER_GREATER_EQUAL) - mask = win32.VerSetConditionMask(mask, - win32.VER_PLATFORMID, - win32.VER_EQUAL) - vista_and_above = win32.VerifyVersionInfoW(osi, - win32.VER_MAJORVERSION | \ - win32.VER_MINORVERSION | \ - win32.VER_PLATFORMID, - mask) + mask = win32.VerSetConditionMask(mask, win32.VER_MAJORVERSION, win32.VER_GREATER_EQUAL) + mask = win32.VerSetConditionMask(mask, win32.VER_MAJORVERSION, win32.VER_GREATER_EQUAL) + mask = win32.VerSetConditionMask(mask, win32.VER_PLATFORMID, win32.VER_EQUAL) + vista_and_above = win32.VerifyVersionInfoW( + osi, win32.VER_MAJORVERSION | win32.VER_MINORVERSION | win32.VER_PLATFORMID, mask + ) self.__vista_and_above = vista_and_above if vista_and_above: dwParentProcessId = self.system.get_explorer_pid() if dwParentProcessId: - kwargs['dwParentProcessId'] = dwParentProcessId + kwargs["dwParentProcessId"] = dwParentProcessId else: - msg = ("Failed to find \"explorer.exe\"!" - " Using the debugger as parent process.") + msg = 'Failed to find "explorer.exe"!' " Using the debugger as parent process." warnings.warn(msg, RuntimeWarning) # Start the new process. @@ -498,8 +490,7 @@ def execl(self, lpCmdLine, **kwargs): # This also allows the user to stop attaching altogether, # depending on how the warnings are configured. if System.bits != aProcess.get_bits(): - msg = "Mixture of 32 and 64 bits is considered experimental." \ - " Use at your own risk!" + msg = "Mixture of 32 and 64 bits is considered experimental." " Use at your own risk!" warnings.warn(msg, MixedBitsWarning) # Add the new PID to the set of debugees. @@ -533,7 +524,7 @@ def execl(self, lpCmdLine, **kwargs): pass raise - def add_existing_session(self, dwProcessId, bStarted = False): + def add_existing_session(self, dwProcessId, bStarted=False): """ Use this method only when for some reason the debugger's been attached to the target outside of WinAppDbg (for example when integrating with @@ -579,7 +570,7 @@ def add_existing_session(self, dwProcessId, bStarted = False): aProcess.scan_threads() aProcess.scan_modules() - def __cleanup_process(self, dwProcessId, bIgnoreExceptions = False): + def __cleanup_process(self, dwProcessId, bIgnoreExceptions=False): """ Perform the necessary cleanup of a process about to be killed or detached from. @@ -598,14 +589,13 @@ def __cleanup_process(self, dwProcessId, bIgnoreExceptions = False): """ # If the process is being debugged... if self.is_debugee(dwProcessId): - # Make sure a Process object exists or the following calls fail. if not self.system.has_process(dwProcessId): aProcess = Process(dwProcessId) try: aProcess.get_handle() except WindowsError: - pass # fails later on with more specific reason + pass # fails later on with more specific reason self.system._add_process(aProcess) # Erase all breakpoints in the process. @@ -663,7 +653,7 @@ def __cleanup_process(self, dwProcessId, bIgnoreExceptions = False): e = sys.exc_info()[1] warnings.warn(str(e), RuntimeWarning) - def kill(self, dwProcessId, bIgnoreExceptions = False): + def kill(self, dwProcessId, bIgnoreExceptions=False): """ Kills a process currently being debugged. @@ -687,8 +677,7 @@ def kill(self, dwProcessId, bIgnoreExceptions = False): aProcess = Process(dwProcessId) # Cleanup all data referring to the process. - self.__cleanup_process(dwProcessId, - bIgnoreExceptions = bIgnoreExceptions) + self.__cleanup_process(dwProcessId, bIgnoreExceptions=bIgnoreExceptions) # Kill the process. try: @@ -698,8 +687,7 @@ def kill(self, dwProcessId, bIgnoreExceptions = False): if aProcess.is_alive(): aProcess.suspend() finally: - self.detach(dwProcessId, - bIgnoreExceptions = bIgnoreExceptions) + self.detach(dwProcessId, bIgnoreExceptions=bIgnoreExceptions) finally: aProcess.kill() except Exception: @@ -717,7 +705,7 @@ def kill(self, dwProcessId, bIgnoreExceptions = False): e = sys.exc_info()[1] warnings.warn(str(e), RuntimeWarning) - def kill_all(self, bIgnoreExceptions = False): + def kill_all(self, bIgnoreExceptions=False): """ Kills from all processes currently being debugged. @@ -730,9 +718,9 @@ def kill_all(self, bIgnoreExceptions = False): C{bIgnoreExceptions} is C{True}. """ for pid in self.get_debugee_pids(): - self.kill(pid, bIgnoreExceptions = bIgnoreExceptions) + self.kill(pid, bIgnoreExceptions=bIgnoreExceptions) - def detach(self, dwProcessId, bIgnoreExceptions = False): + def detach(self, dwProcessId, bIgnoreExceptions=False): """ Detaches from a process currently being debugged. @@ -769,8 +757,7 @@ def detach(self, dwProcessId, bIgnoreExceptions = False): # Continue the last event before detaching. # XXX not sure about this... try: - if can_detach and self.lastEvent and \ - self.lastEvent.get_pid() == dwProcessId: + if can_detach and self.lastEvent and self.lastEvent.get_pid() == dwProcessId: self.cont(self.lastEvent) except Exception: if not bIgnoreExceptions: @@ -779,8 +766,7 @@ def detach(self, dwProcessId, bIgnoreExceptions = False): warnings.warn(str(e), RuntimeWarning) # Cleanup all data referring to the process. - self.__cleanup_process(dwProcessId, - bIgnoreExceptions = bIgnoreExceptions) + self.__cleanup_process(dwProcessId, bIgnoreExceptions=bIgnoreExceptions) try: # Detach from the process. @@ -803,11 +789,10 @@ def detach(self, dwProcessId, bIgnoreExceptions = False): warnings.warn(str(e), RuntimeWarning) finally: - # Cleanup what remains of the process data. aProcess.clear() - def detach_from_all(self, bIgnoreExceptions = False): + def detach_from_all(self, bIgnoreExceptions=False): """ Detaches from all processes currently being debugged. @@ -821,11 +806,11 @@ def detach_from_all(self, bIgnoreExceptions = False): C{bIgnoreExceptions} is C{True}. """ for pid in self.get_debugee_pids(): - self.detach(pid, bIgnoreExceptions = bIgnoreExceptions) + self.detach(pid, bIgnoreExceptions=bIgnoreExceptions) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def wait(self, dwMilliseconds = None): + def wait(self, dwMilliseconds=None): """ Waits for the next debug event. @@ -844,7 +829,7 @@ def wait(self, dwMilliseconds = None): """ # Wait for the next debug event. - raw = win32.WaitForDebugEvent(dwMilliseconds) + raw = win32.WaitForDebugEvent(dwMilliseconds) event = EventFactory.get(self, raw) # Remember it. @@ -853,7 +838,7 @@ def wait(self, dwMilliseconds = None): # Return it. return event - def dispatch(self, event = None): + def dispatch(self, event=None): """ Calls the debug event notify callbacks. @@ -881,7 +866,6 @@ def dispatch(self, event = None): code = event.get_event_code() if code == win32.EXCEPTION_DEBUG_EVENT: - # At this point, by default some exception types are swallowed by # the debugger, because we don't know yet if it was caused by the # debugger itself or the debugged process. @@ -899,11 +883,11 @@ def dispatch(self, event = None): exc_code = event.get_exception_code() if exc_code in ( - win32.EXCEPTION_BREAKPOINT, - win32.EXCEPTION_WX86_BREAKPOINT, - win32.EXCEPTION_SINGLE_STEP, - win32.EXCEPTION_GUARD_PAGE, - ): + win32.EXCEPTION_BREAKPOINT, + win32.EXCEPTION_WX86_BREAKPOINT, + win32.EXCEPTION_SINGLE_STEP, + win32.EXCEPTION_GUARD_PAGE, + ): event.continueStatus = win32.DBG_CONTINUE elif exc_code == win32.EXCEPTION_INVALID_HANDLE: if self.__bHostileCode: @@ -913,14 +897,11 @@ def dispatch(self, event = None): else: event.continueStatus = win32.DBG_EXCEPTION_NOT_HANDLED - elif code == win32.RIP_EVENT and \ - event.get_rip_type() == win32.SLE_ERROR: - + elif code == win32.RIP_EVENT and event.get_rip_type() == win32.SLE_ERROR: # RIP events that signal fatal events should kill the process. event.continueStatus = win32.DBG_TERMINATE_PROCESS else: - # Other events need this continue code. # Sometimes other codes can be used and are ignored, sometimes not. # For example, when using the DBG_EXCEPTION_NOT_HANDLED code, @@ -930,7 +911,7 @@ def dispatch(self, event = None): # Dispatch the debug event. return EventDispatcher.dispatch(self, event) - def cont(self, event = None): + def cont(self, event=None): """ Resumes execution after processing a debug event. @@ -951,13 +932,12 @@ def cont(self, event = None): return # Get the event continue status information. - dwProcessId = event.get_pid() - dwThreadId = event.get_tid() + dwProcessId = event.get_pid() + dwThreadId = event.get_tid() dwContinueStatus = event.continueStatus # Check if the process is still being debugged. if self.is_debugee(dwProcessId): - # Try to flush the instruction cache. try: if self.system.has_process(dwProcessId): @@ -986,7 +966,7 @@ def cont(self, event = None): if event == self.lastEvent: self.lastEvent = None - def stop(self, bIgnoreExceptions = True): + def stop(self, bIgnoreExceptions=True): """ Stops debugging all processes. @@ -1016,7 +996,6 @@ def stop(self, bIgnoreExceptions = True): # If we do... if has_event: - # Disable all breakpoints in the process before resuming execution. try: pid = event.get_pid() @@ -1156,8 +1135,7 @@ def is_debugee(self, dwProcessId): @return: C{True} if the given process is being debugged by this L{Debug} instance. """ - return self.is_debugee_attached(dwProcessId) or \ - self.is_debugee_started(dwProcessId) + return self.is_debugee_attached(dwProcessId) or self.is_debugee_started(dwProcessId) def is_debugee_started(self, dwProcessId): """ @@ -1199,9 +1177,9 @@ def in_hostile_mode(self): """ return self.__bHostileCode -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def interactive(self, bConfirmQuit = True, bShowBanner = True): + def interactive(self, bConfirmQuit=True, bShowBanner=True): """ Start an interactive debugging session. @@ -1217,14 +1195,14 @@ def interactive(self, bConfirmQuit = True, bShowBanner = True): This method returns when the user closes the session. """ - print('') + print("") print("-" * 79) print("Interactive debugging session started.") - print("Use the \"help\" command to list all available commands.") - print("Use the \"quit\" command to close this session.") + print('Use the "help" command to list all available commands.') + print('Use the "quit" command to close this session.') print("-" * 79) if self.lastEvent is None: - print('') + print("") console = ConsoleDebugger() console.confirm_quit = bConfirmQuit console.load_history() @@ -1234,16 +1212,16 @@ def interactive(self, bConfirmQuit = True, bShowBanner = True): finally: console.stop_using_debugger() console.save_history() - print('') + print("") print("-" * 79) print("Interactive debugging session closed.") print("-" * 79) - print('') + print("") -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ @staticmethod - def force_garbage_collection(bIgnoreExceptions = True): + def force_garbage_collection(bIgnoreExceptions=True): """ Close all Win32 handles the Python garbage collector failed to close. @@ -1253,6 +1231,7 @@ def force_garbage_collection(bIgnoreExceptions = True): """ try: import gc + gc.collect() bRecollect = False for obj in list(gc.garbage): @@ -1288,7 +1267,7 @@ def force_garbage_collection(bIgnoreExceptions = True): e = sys.exc_info()[1] warnings.warn(str(e), RuntimeWarning) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def _notify_create_process(self, event): """ @@ -1333,15 +1312,13 @@ def _notify_create_process(self, event): aProcess = event.get_process() try: hProcess = aProcess.get_handle(win32.PROCESS_QUERY_INFORMATION) - pbi = win32.NtQueryInformationProcess( - hProcess, win32.ProcessBasicInformation) + pbi = win32.NtQueryInformationProcess(hProcess, win32.ProcessBasicInformation) ptr = pbi.PebBaseAddress + 2 - if aProcess.peek(ptr, 1) == '\x01': - aProcess.poke(ptr, '\x00') + if aProcess.peek(ptr, 1) == "\x01": + aProcess.poke(ptr, "\x00") except WindowsError: e = sys.exc_info()[1] - warnings.warn( - "Cannot patch PEB->BeingDebugged, reason: %s" % e.strerror) + warnings.warn("Cannot patch PEB->BeingDebugged, reason: %s" % e.strerror) return retval @@ -1384,8 +1361,7 @@ def _notify_load_dll(self, event): # Anti-anti-debugging tricks on ntdll.dll. if self.__bHostileCode: aModule = event.get_module() - if aModule.match_name('ntdll.dll'): - + if aModule.match_name("ntdll.dll"): # Since we've overwritten the PEB to hide # ourselves, we no longer have the system # breakpoint when attaching to the process. @@ -1395,8 +1371,7 @@ def _notify_load_dll(self, event): # a simple anti-debugging trick: the hostile # process could have overwritten the int3 # instruction at the system breakpoint. - self.break_at(aProcess.get_pid(), - aProcess.resolve_label('ntdll!DbgUiRemoteBreakin')) + self.break_at(aProcess.get_pid(), aProcess.resolve_label("ntdll!DbgUiRemoteBreakin")) return bCallHandler @@ -1416,18 +1391,14 @@ def _notify_exit_process(self, event): bCallHandler2 = self.system._notify_exit_process(event) try: - self.detach( event.get_pid() ) + self.detach(event.get_pid()) except WindowsError: e = sys.exc_info()[1] if e.winerror != win32.ERROR_INVALID_PARAMETER: - warnings.warn( - "Failed to detach from dead process, reason: %s" % str(e), - RuntimeWarning) + warnings.warn("Failed to detach from dead process, reason: %s" % str(e), RuntimeWarning) except Exception: e = sys.exc_info()[1] - warnings.warn( - "Failed to detach from dead process, reason: %s" % str(e), - RuntimeWarning) + warnings.warn("Failed to detach from dead process, reason: %s" % str(e), RuntimeWarning) return bCallHandler1 and bCallHandler2 @@ -1475,7 +1446,7 @@ def _notify_rip(self, event): @rtype: bool @return: C{True} to call the user-defined handle, C{False} otherwise. """ - event.debug.detach( event.get_pid() ) + event.debug.detach(event.get_pid()) return True def _notify_debug_control_c(self, event): @@ -1519,14 +1490,13 @@ def _notify_ms_vc_exception(self, event): """ dwType = event.get_exception_information(0) if dwType == 0x1000: - pszName = event.get_exception_information(1) - dwThreadId = event.get_exception_information(2) - dwFlags = event.get_exception_information(3) + pszName = event.get_exception_information(1) + dwThreadId = event.get_exception_information(2) + dwFlags = event.get_exception_information(3) aProcess = event.get_process() - szName = aProcess.peek_string(pszName, fUnicode = False) + szName = aProcess.peek_string(pszName, fUnicode=False) if szName: - if dwThreadId == -1: dwThreadId = event.get_tid() @@ -1536,8 +1506,8 @@ def _notify_ms_vc_exception(self, event): aThread = Thread(dwThreadId) aProcess._add_thread(aThread) -## if aThread.get_name() is None: -## aThread.set_name(szName) + ## if aThread.get_name() is None: + ## aThread.set_name(szName) aThread.set_name(szName) return True diff --git a/pydevd_attach_to_process/winappdbg/disasm.py b/pydevd_attach_to_process/winappdbg/disasm.py index 230e3314a..306c4ea0e 100644 --- a/pydevd_attach_to_process/winappdbg/disasm.py +++ b/pydevd_attach_to_process/winappdbg/disasm.py @@ -44,13 +44,13 @@ __revision__ = "$Id$" __all__ = [ - 'Disassembler', - 'Engine', - 'BeaEngine', - 'CapstoneEngine', - 'DistormEngine', - 'LibdisassembleEngine', - 'PyDasmEngine', + "Disassembler", + "Engine", + "BeaEngine", + "CapstoneEngine", + "DistormEngine", + "LibdisassembleEngine", + "PyDasmEngine", ] from winappdbg.textio import HexDump @@ -66,9 +66,10 @@ libdisassemble = None capstone = None -#============================================================================== +# ============================================================================== -class Engine (object): + +class Engine(object): """ Base class for disassembly engine adaptors. @@ -91,10 +92,10 @@ class Engine (object): name = "" desc = "" - url = "" + url = "" supported = set() - def __init__(self, arch = None): + def __init__(self, arch=None): """ @type arch: str @param arch: Name of the processor architecture. @@ -112,7 +113,7 @@ def __init__(self, arch = None): msg = msg % (self.name, self.url) raise NotImplementedError(msg) - def _validate_arch(self, arch = None): + def _validate_arch(self, arch=None): """ @type arch: str @param arch: Name of the processor architecture. @@ -171,9 +172,11 @@ def decode(self, address, code): """ raise NotImplementedError() -#============================================================================== -class BeaEngine (Engine): +# ============================================================================== + + +class BeaEngine(Engine): """ Integration with the BeaEngine disassembler by Beatrix. @@ -182,15 +185,16 @@ class BeaEngine (Engine): name = "BeaEngine" desc = "BeaEngine disassembler by Beatrix" - url = "https://sourceforge.net/projects/winappdbg/files/additional%20packages/BeaEngine/" + url = "https://sourceforge.net/projects/winappdbg/files/additional%20packages/BeaEngine/" - supported = set(( - win32.ARCH_I386, - win32.ARCH_AMD64, - )) + supported = set( + ( + win32.ARCH_I386, + win32.ARCH_AMD64, + ) + ) def _import_dependencies(self): - # Load the BeaEngine ctypes wrapper. global BeaEnginePython if BeaEnginePython is None: @@ -212,10 +216,9 @@ def decode(self, address, code): Instruction.Archi = 0 else: Instruction.Archi = 0x40 - Instruction.Options = ( BeaEnginePython.Tabulation + - BeaEnginePython.NasmSyntax + - BeaEnginePython.SuffixedNumeral + - BeaEnginePython.ShowSegmentRegs ) + Instruction.Options = ( + BeaEnginePython.Tabulation + BeaEnginePython.NasmSyntax + BeaEnginePython.SuffixedNumeral + BeaEnginePython.ShowSegmentRegs + ) # Prepare for looping over each instruction. result = [] @@ -223,12 +226,11 @@ def decode(self, address, code): InstructionPtr = addressof(Instruction) hexdump = HexDump.hexadecimal append = result.append - OUT_OF_BLOCK = BeaEnginePython.OUT_OF_BLOCK + OUT_OF_BLOCK = BeaEnginePython.OUT_OF_BLOCK UNKNOWN_OPCODE = BeaEnginePython.UNKNOWN_OPCODE # For each decoded instruction... while True: - # Calculate the current offset into the buffer. offset = Instruction.EIP - buffer_ptr @@ -245,15 +247,16 @@ def decode(self, address, code): # The instruction could not be decoded. if InstrLength == UNKNOWN_OPCODE: - # Output a single byte as a "db" instruction. char = "%.2X" % ord(buffer[offset]) - result.append(( - Instruction.VirtualAddr, - 1, - "db %sh" % char, - char, - )) + result.append( + ( + Instruction.VirtualAddr, + 1, + "db %sh" % char, + char, + ) + ) Instruction.VirtualAddr += 1 Instruction.EIP += 1 @@ -261,38 +264,42 @@ def decode(self, address, code): # This can happen when the last instruction is a prefix without an # opcode. For example: decode(0, '\x66') elif offset + InstrLength > len(code): - # Output each byte as a "db" instruction. - for char in buffer[ offset : offset + len(code) ]: + for char in buffer[offset : offset + len(code)]: char = "%.2X" % ord(char) - result.append(( - Instruction.VirtualAddr, - 1, - "db %sh" % char, - char, - )) + result.append( + ( + Instruction.VirtualAddr, + 1, + "db %sh" % char, + char, + ) + ) Instruction.VirtualAddr += 1 Instruction.EIP += 1 # The instruction was decoded correctly. else: - # Output the decoded instruction. - append(( - Instruction.VirtualAddr, - InstrLength, - Instruction.CompleteInstr.strip(), - hexdump(buffer.raw[offset:offset+InstrLength]), - )) + append( + ( + Instruction.VirtualAddr, + InstrLength, + Instruction.CompleteInstr.strip(), + hexdump(buffer.raw[offset : offset + InstrLength]), + ) + ) Instruction.VirtualAddr += InstrLength Instruction.EIP += InstrLength # Return the list of decoded instructions. return result -#============================================================================== -class DistormEngine (Engine): +# ============================================================================== + + +class DistormEngine(Engine): """ Integration with the diStorm disassembler by Gil Dabah. @@ -301,15 +308,16 @@ class DistormEngine (Engine): name = "diStorm" desc = "diStorm disassembler by Gil Dabah" - url = "https://code.google.com/p/distorm3" + url = "https://code.google.com/p/distorm3" - supported = set(( - win32.ARCH_I386, - win32.ARCH_AMD64, - )) + supported = set( + ( + win32.ARCH_I386, + win32.ARCH_AMD64, + ) + ) def _import_dependencies(self): - # Load the distorm bindings. global distorm3 if distorm3 is None: @@ -323,16 +331,18 @@ def _import_dependencies(self): # Load the bits flag. self.__flag = { - win32.ARCH_I386: distorm3.Decode32Bits, + win32.ARCH_I386: distorm3.Decode32Bits, win32.ARCH_AMD64: distorm3.Decode64Bits, }[self.arch] def decode(self, address, code): return self.__decode(address, code, self.__flag) -#============================================================================== -class PyDasmEngine (Engine): +# ============================================================================== + + +class PyDasmEngine(Engine): """ Integration with PyDasm: Python bindings to libdasm. @@ -341,54 +351,48 @@ class PyDasmEngine (Engine): name = "PyDasm" desc = "PyDasm: Python bindings to libdasm" - url = "https://code.google.com/p/libdasm/" + url = "https://code.google.com/p/libdasm/" - supported = set(( - win32.ARCH_I386, - )) + supported = set((win32.ARCH_I386,)) def _import_dependencies(self): - # Load the libdasm bindings. global pydasm if pydasm is None: import pydasm def decode(self, address, code): - # Decode each instruction in the buffer. result = [] offset = 0 while offset < len(code): - # Try to decode the current instruction. - instruction = pydasm.get_instruction(code[offset:offset+32], - pydasm.MODE_32) + instruction = pydasm.get_instruction(code[offset : offset + 32], pydasm.MODE_32) # Get the memory address of the current instruction. current = address + offset # Illegal opcode or opcode longer than remaining buffer. if not instruction or instruction.length + offset > len(code): - hexdump = '%.2X' % ord(code[offset]) - disasm = 'db 0x%s' % hexdump - ilen = 1 + hexdump = "%.2X" % ord(code[offset]) + disasm = "db 0x%s" % hexdump + ilen = 1 # Correctly decoded instruction. else: - disasm = pydasm.get_instruction_string(instruction, - pydasm.FORMAT_INTEL, - current) - ilen = instruction.length - hexdump = HexDump.hexadecimal(code[offset:offset+ilen]) + disasm = pydasm.get_instruction_string(instruction, pydasm.FORMAT_INTEL, current) + ilen = instruction.length + hexdump = HexDump.hexadecimal(code[offset : offset + ilen]) # Add the decoded instruction to the list. - result.append(( - current, - ilen, - disasm, - hexdump, - )) + result.append( + ( + current, + ilen, + disasm, + hexdump, + ) + ) # Move to the next instruction. offset += ilen @@ -396,9 +400,11 @@ def decode(self, address, code): # Return the list of decoded instructions. return result -#============================================================================== -class LibdisassembleEngine (Engine): +# ============================================================================== + + +class LibdisassembleEngine(Engine): """ Integration with Immunity libdisassemble. @@ -407,14 +413,11 @@ class LibdisassembleEngine (Engine): name = "Libdisassemble" desc = "Immunity libdisassemble" - url = "http://www.immunitysec.com/resources-freesoftware.shtml" + url = "http://www.immunitysec.com/resources-freesoftware.shtml" - supported = set(( - win32.ARCH_I386, - )) + supported = set((win32.ARCH_I386,)) def _import_dependencies(self): - # Load the libdisassemble module. # Since it doesn't come with an installer or an __init__.py file # users can only install it manually however they feel like it, @@ -423,35 +426,33 @@ def _import_dependencies(self): global libdisassemble if libdisassemble is None: try: - # If installed properly with __init__.py import libdisassemble.disassemble as libdisassemble except ImportError: - # If installed by just copying and pasting the files import disassemble as libdisassemble def decode(self, address, code): - # Decode each instruction in the buffer. result = [] offset = 0 while offset < len(code): - # Decode the current instruction. - opcode = libdisassemble.Opcode( code[offset:offset+32] ) - length = opcode.getSize() - disasm = opcode.printOpcode('INTEL') - hexdump = HexDump.hexadecimal( code[offset:offset+length] ) + opcode = libdisassemble.Opcode(code[offset : offset + 32]) + length = opcode.getSize() + disasm = opcode.printOpcode("INTEL") + hexdump = HexDump.hexadecimal(code[offset : offset + length]) # Add the decoded instruction to the list. - result.append(( - address + offset, - length, - disasm, - hexdump, - )) + result.append( + ( + address + offset, + length, + disasm, + hexdump, + ) + ) # Move to the next instruction. offset += length @@ -459,9 +460,11 @@ def decode(self, address, code): # Return the list of decoded instructions. return result -#============================================================================== -class CapstoneEngine (Engine): +# ============================================================================== + + +class CapstoneEngine(Engine): """ Integration with the Capstone disassembler by Nguyen Anh Quynh. @@ -470,18 +473,19 @@ class CapstoneEngine (Engine): name = "Capstone" desc = "Capstone disassembler by Nguyen Anh Quynh" - url = "http://www.capstone-engine.org/" - - supported = set(( - win32.ARCH_I386, - win32.ARCH_AMD64, - win32.ARCH_THUMB, - win32.ARCH_ARM, - win32.ARCH_ARM64, - )) + url = "http://www.capstone-engine.org/" + + supported = set( + ( + win32.ARCH_I386, + win32.ARCH_AMD64, + win32.ARCH_THUMB, + win32.ARCH_ARM, + win32.ARCH_ARM64, + ) + ) def _import_dependencies(self): - # Load the Capstone bindings. global capstone if capstone is None: @@ -489,36 +493,27 @@ def _import_dependencies(self): # Load the constants for the requested architecture. self.__constants = { - win32.ARCH_I386: - (capstone.CS_ARCH_X86, capstone.CS_MODE_32), - win32.ARCH_AMD64: - (capstone.CS_ARCH_X86, capstone.CS_MODE_64), - win32.ARCH_THUMB: - (capstone.CS_ARCH_ARM, capstone.CS_MODE_THUMB), - win32.ARCH_ARM: - (capstone.CS_ARCH_ARM, capstone.CS_MODE_ARM), - win32.ARCH_ARM64: - (capstone.CS_ARCH_ARM64, capstone.CS_MODE_ARM), + win32.ARCH_I386: (capstone.CS_ARCH_X86, capstone.CS_MODE_32), + win32.ARCH_AMD64: (capstone.CS_ARCH_X86, capstone.CS_MODE_64), + win32.ARCH_THUMB: (capstone.CS_ARCH_ARM, capstone.CS_MODE_THUMB), + win32.ARCH_ARM: (capstone.CS_ARCH_ARM, capstone.CS_MODE_ARM), + win32.ARCH_ARM64: (capstone.CS_ARCH_ARM64, capstone.CS_MODE_ARM), } # Test for the bug in early versions of Capstone. # If found, warn the user about it. try: self.__bug = not isinstance( - capstone.cs_disasm_quick( - capstone.CS_ARCH_X86, capstone.CS_MODE_32, "\x90", 1)[0], - capstone.capstone.CsInsn) + capstone.cs_disasm_quick(capstone.CS_ARCH_X86, capstone.CS_MODE_32, "\x90", 1)[0], capstone.capstone.CsInsn + ) except AttributeError: self.__bug = False if self.__bug: warnings.warn( - "This version of the Capstone bindings is unstable," - " please upgrade to a newer one!", - RuntimeWarning, stacklevel=4) - + "This version of the Capstone bindings is unstable," " please upgrade to a newer one!", RuntimeWarning, stacklevel=4 + ) def decode(self, address, code): - # Get the constants for the requested architecture. arch, mode = self.__constants[self.arch] @@ -543,29 +538,26 @@ def decode(self, address, code): result = [] offset = 0 while offset < len(code): - # Disassemble a single instruction, because disassembling multiple # instructions may cause excessive memory usage (Capstone allocates # approximately 1K of metadata per each decoded instruction). instr = None try: - instr = decoder( - arch, mode, code[offset:offset+16], address+offset, 1)[0] + instr = decoder(arch, mode, code[offset : offset + 16], address + offset, 1)[0] except IndexError: - pass # No instructions decoded. + pass # No instructions decoded. except CsError: - pass # Any other error. + pass # Any other error. # On success add the decoded instruction. if instr is not None: - # Get the instruction length, mnemonic and operands. # Copy the values quickly before someone overwrites them, # if using the buggy version of the bindings (otherwise it's # irrelevant in which order we access the properties). - length = instr.size + length = instr.size mnemonic = instr.mnemonic - op_str = instr.op_str + op_str = instr.op_str # Concatenate the mnemonic and the operands. if op_str: @@ -574,12 +566,11 @@ def decode(self, address, code): disasm = mnemonic # Get the instruction bytes as a hexadecimal dump. - hexdump = HexDump.hexadecimal( code[offset:offset+length] ) + hexdump = HexDump.hexadecimal(code[offset : offset + length]) # On error add a "define constant" instruction. # The exact instruction depends on the architecture. else: - # The number of bytes to skip depends on the architecture. # On Intel processors we'll skip one byte, since we can't # really know the instruction length. On the rest of the @@ -590,7 +581,7 @@ def decode(self, address, code): length = 4 # Get the skipped bytes as a hexadecimal dump. - skipped = code[offset:offset+length] + skipped = code[offset : offset + length] hexdump = HexDump.hexadecimal(skipped) # Build the "define constant" instruction. @@ -610,12 +601,14 @@ def decode(self, address, code): disasm = mnemonic + op_str # Add the decoded instruction to the list. - result.append(( - address + offset, - length, - disasm, - hexdump, - )) + result.append( + ( + address + offset, + length, + disasm, + hexdump, + ) + ) # Update the offset. offset += length @@ -623,12 +616,14 @@ def decode(self, address, code): # Return the list of decoded instructions. return result -#============================================================================== + +# ============================================================================== # TODO: use a lock to access __decoder # TODO: look in sys.modules for whichever disassembler is already loaded -class Disassembler (object): + +class Disassembler(object): """ Generic disassembler. Uses a set of adapters to decide which library to load for which supported platform. @@ -656,7 +651,7 @@ class Disassembler (object): # Cache of already loaded disassemblers. __decoder = {} - def __new__(cls, arch = None, engine = None): + def __new__(cls, arch=None, engine=None): """ Factory class. You can't really instance a L{Disassembler} object, instead one of the adapter L{Engine} subclasses is returned. diff --git a/pydevd_attach_to_process/winappdbg/event.py b/pydevd_attach_to_process/winappdbg/event.py index af64727be..57e9a3751 100644 --- a/pydevd_attach_to_process/winappdbg/event.py +++ b/pydevd_attach_to_process/winappdbg/event.py @@ -58,38 +58,32 @@ __revision__ = "$Id$" __all__ = [ - # Factory of Event objects and all of it's subclasses. - # Users should not need to instance Event objects directly. - 'EventFactory', - - # Event dispatcher used internally by the Debug class. - 'EventDispatcher', - - # Base classes for user-defined event handlers. - 'EventHandler', - 'EventSift', - - # Warning for uncaught exceptions on event callbacks. - 'EventCallbackWarning', - - # Dummy event object that can be used as a placeholder. - # It's never returned by the EventFactory. - 'NoEvent', - - # Base class for event objects. - 'Event', - - # Event objects. - 'CreateProcessEvent', - 'CreateThreadEvent', - 'ExitProcessEvent', - 'ExitThreadEvent', - 'LoadDLLEvent', - 'UnloadDLLEvent', - 'OutputDebugStringEvent', - 'RIPEvent', - 'ExceptionEvent' - ] + # Factory of Event objects and all of it's subclasses. + # Users should not need to instance Event objects directly. + "EventFactory", + # Event dispatcher used internally by the Debug class. + "EventDispatcher", + # Base classes for user-defined event handlers. + "EventHandler", + "EventSift", + # Warning for uncaught exceptions on event callbacks. + "EventCallbackWarning", + # Dummy event object that can be used as a placeholder. + # It's never returned by the EventFactory. + "NoEvent", + # Base class for event objects. + "Event", + # Event objects. + "CreateProcessEvent", + "CreateThreadEvent", + "ExitProcessEvent", + "ExitThreadEvent", + "LoadDLLEvent", + "UnloadDLLEvent", + "OutputDebugStringEvent", + "RIPEvent", + "ExceptionEvent", +] from winappdbg import win32 from winappdbg import compat @@ -106,17 +100,20 @@ import warnings import traceback -#============================================================================== +# ============================================================================== -class EventCallbackWarning (RuntimeWarning): + +class EventCallbackWarning(RuntimeWarning): """ This warning is issued when an uncaught exception was raised by a user-defined event handler. """ -#============================================================================== -class Event (object): +# ============================================================================== + + +class Event(object): """ Event object. @@ -146,9 +143,9 @@ class Event (object): Continue status to pass to L{win32.ContinueDebugEvent}. """ - eventMethod = 'unknown_event' - eventName = 'Unknown event' - eventDescription = 'A debug event of an unknown type has occured.' + eventMethod = "unknown_event" + eventName = "Unknown event" + eventDescription = "A debug event of an unknown type has occured." def __init__(self, debug, raw): """ @@ -158,18 +155,18 @@ def __init__(self, debug, raw): @type raw: L{DEBUG_EVENT} @param raw: Raw DEBUG_EVENT structure as used by the Win32 API. """ - self.debug = debug - self.raw = raw + self.debug = debug + self.raw = raw self.continueStatus = win32.DBG_EXCEPTION_NOT_HANDLED -## @property -## def debug(self): -## """ -## @rtype debug: L{Debug} -## @return debug: -## Debug object that received the event. -## """ -## return self.__debug() + ## @property + ## def debug(self): + ## """ + ## @rtype debug: L{Debug} + ## @return debug: + ## Debug object that received the event. + ## """ + ## return self.__debug() def get_event_name(self): """ @@ -192,18 +189,18 @@ def get_event_code(self): """ return self.raw.dwDebugEventCode -## # Compatibility with version 1.0 -## # XXX to be removed in version 1.4 -## def get_code(self): -## """ -## Alias of L{get_event_code} for backwards compatibility -## with WinAppDbg version 1.0. -## Will be phased out in the next version. -## -## @rtype: int -## @return: Debug event code as defined in the Win32 API. -## """ -## return self.get_event_code() + ## # Compatibility with version 1.0 + ## # XXX to be removed in version 1.4 + ## def get_code(self): + ## """ + ## Alias of L{get_event_code} for backwards compatibility + ## with WinAppDbg version 1.0. + ## Will be phased out in the next version. + ## + ## @rtype: int + ## @return: Debug event code as defined in the Win32 API. + ## """ + ## return self.get_event_code() def get_pid(self): """ @@ -230,8 +227,8 @@ def get_process(self): @rtype: L{Process} @return: Process where the event occured. """ - pid = self.get_pid() - system = self.debug.system + pid = self.get_pid() + system = self.debug.system if system.has_process(pid): process = system.get_process(pid) else: @@ -239,7 +236,7 @@ def get_process(self): # The process object was missing for some reason, so make a new one. process = Process(pid) system._add_process(process) -## process.scan_threads() # not needed + ## process.scan_threads() # not needed process.scan_modules() return process @@ -250,7 +247,7 @@ def get_thread(self): @rtype: L{Thread} @return: Thread where the event occured. """ - tid = self.get_tid() + tid = self.get_tid() process = self.get_process() if process.has_thread(tid): thread = process.get_thread(tid) @@ -261,9 +258,11 @@ def get_thread(self): process._add_thread(thread) return thread -#============================================================================== -class NoEvent (Event): +# ============================================================================== + + +class NoEvent(Event): """ No event. @@ -271,11 +270,11 @@ class NoEvent (Event): event has occured yet. It's never returned by the L{EventFactory}. """ - eventMethod = 'no_event' - eventName = 'No event' - eventDescription = 'No debug event has occured.' + eventMethod = "no_event" + eventName = "No event" + eventDescription = "No debug event has occured." - def __init__(self, debug, raw = None): + def __init__(self, debug, raw=None): Event.__init__(self, debug, raw) def __len__(self): @@ -301,9 +300,11 @@ def get_process(self): def get_thread(self): return Thread(self.get_tid()) -#============================================================================== -class ExceptionEvent (Event): +# ============================================================================== + + +class ExceptionEvent(Event): """ Exception event. @@ -330,103 +331,102 @@ class ExceptionEvent (Event): handler. """ - eventName = 'Exception event' - eventDescription = 'An exception was raised by the debugee.' + eventName = "Exception event" + eventDescription = "An exception was raised by the debugee." __exceptionMethod = { - win32.EXCEPTION_ACCESS_VIOLATION : 'access_violation', - win32.EXCEPTION_ARRAY_BOUNDS_EXCEEDED : 'array_bounds_exceeded', - win32.EXCEPTION_BREAKPOINT : 'breakpoint', - win32.EXCEPTION_DATATYPE_MISALIGNMENT : 'datatype_misalignment', - win32.EXCEPTION_FLT_DENORMAL_OPERAND : 'float_denormal_operand', - win32.EXCEPTION_FLT_DIVIDE_BY_ZERO : 'float_divide_by_zero', - win32.EXCEPTION_FLT_INEXACT_RESULT : 'float_inexact_result', - win32.EXCEPTION_FLT_INVALID_OPERATION : 'float_invalid_operation', - win32.EXCEPTION_FLT_OVERFLOW : 'float_overflow', - win32.EXCEPTION_FLT_STACK_CHECK : 'float_stack_check', - win32.EXCEPTION_FLT_UNDERFLOW : 'float_underflow', - win32.EXCEPTION_ILLEGAL_INSTRUCTION : 'illegal_instruction', - win32.EXCEPTION_IN_PAGE_ERROR : 'in_page_error', - win32.EXCEPTION_INT_DIVIDE_BY_ZERO : 'integer_divide_by_zero', - win32.EXCEPTION_INT_OVERFLOW : 'integer_overflow', - win32.EXCEPTION_INVALID_DISPOSITION : 'invalid_disposition', - win32.EXCEPTION_NONCONTINUABLE_EXCEPTION : 'noncontinuable_exception', - win32.EXCEPTION_PRIV_INSTRUCTION : 'privileged_instruction', - win32.EXCEPTION_SINGLE_STEP : 'single_step', - win32.EXCEPTION_STACK_OVERFLOW : 'stack_overflow', - win32.EXCEPTION_GUARD_PAGE : 'guard_page', - win32.EXCEPTION_INVALID_HANDLE : 'invalid_handle', - win32.EXCEPTION_POSSIBLE_DEADLOCK : 'possible_deadlock', - win32.EXCEPTION_WX86_BREAKPOINT : 'wow64_breakpoint', - win32.CONTROL_C_EXIT : 'control_c_exit', - win32.DBG_CONTROL_C : 'debug_control_c', - win32.MS_VC_EXCEPTION : 'ms_vc_exception', + win32.EXCEPTION_ACCESS_VIOLATION: "access_violation", + win32.EXCEPTION_ARRAY_BOUNDS_EXCEEDED: "array_bounds_exceeded", + win32.EXCEPTION_BREAKPOINT: "breakpoint", + win32.EXCEPTION_DATATYPE_MISALIGNMENT: "datatype_misalignment", + win32.EXCEPTION_FLT_DENORMAL_OPERAND: "float_denormal_operand", + win32.EXCEPTION_FLT_DIVIDE_BY_ZERO: "float_divide_by_zero", + win32.EXCEPTION_FLT_INEXACT_RESULT: "float_inexact_result", + win32.EXCEPTION_FLT_INVALID_OPERATION: "float_invalid_operation", + win32.EXCEPTION_FLT_OVERFLOW: "float_overflow", + win32.EXCEPTION_FLT_STACK_CHECK: "float_stack_check", + win32.EXCEPTION_FLT_UNDERFLOW: "float_underflow", + win32.EXCEPTION_ILLEGAL_INSTRUCTION: "illegal_instruction", + win32.EXCEPTION_IN_PAGE_ERROR: "in_page_error", + win32.EXCEPTION_INT_DIVIDE_BY_ZERO: "integer_divide_by_zero", + win32.EXCEPTION_INT_OVERFLOW: "integer_overflow", + win32.EXCEPTION_INVALID_DISPOSITION: "invalid_disposition", + win32.EXCEPTION_NONCONTINUABLE_EXCEPTION: "noncontinuable_exception", + win32.EXCEPTION_PRIV_INSTRUCTION: "privileged_instruction", + win32.EXCEPTION_SINGLE_STEP: "single_step", + win32.EXCEPTION_STACK_OVERFLOW: "stack_overflow", + win32.EXCEPTION_GUARD_PAGE: "guard_page", + win32.EXCEPTION_INVALID_HANDLE: "invalid_handle", + win32.EXCEPTION_POSSIBLE_DEADLOCK: "possible_deadlock", + win32.EXCEPTION_WX86_BREAKPOINT: "wow64_breakpoint", + win32.CONTROL_C_EXIT: "control_c_exit", + win32.DBG_CONTROL_C: "debug_control_c", + win32.MS_VC_EXCEPTION: "ms_vc_exception", } __exceptionName = { - win32.EXCEPTION_ACCESS_VIOLATION : 'EXCEPTION_ACCESS_VIOLATION', - win32.EXCEPTION_ARRAY_BOUNDS_EXCEEDED : 'EXCEPTION_ARRAY_BOUNDS_EXCEEDED', - win32.EXCEPTION_BREAKPOINT : 'EXCEPTION_BREAKPOINT', - win32.EXCEPTION_DATATYPE_MISALIGNMENT : 'EXCEPTION_DATATYPE_MISALIGNMENT', - win32.EXCEPTION_FLT_DENORMAL_OPERAND : 'EXCEPTION_FLT_DENORMAL_OPERAND', - win32.EXCEPTION_FLT_DIVIDE_BY_ZERO : 'EXCEPTION_FLT_DIVIDE_BY_ZERO', - win32.EXCEPTION_FLT_INEXACT_RESULT : 'EXCEPTION_FLT_INEXACT_RESULT', - win32.EXCEPTION_FLT_INVALID_OPERATION : 'EXCEPTION_FLT_INVALID_OPERATION', - win32.EXCEPTION_FLT_OVERFLOW : 'EXCEPTION_FLT_OVERFLOW', - win32.EXCEPTION_FLT_STACK_CHECK : 'EXCEPTION_FLT_STACK_CHECK', - win32.EXCEPTION_FLT_UNDERFLOW : 'EXCEPTION_FLT_UNDERFLOW', - win32.EXCEPTION_ILLEGAL_INSTRUCTION : 'EXCEPTION_ILLEGAL_INSTRUCTION', - win32.EXCEPTION_IN_PAGE_ERROR : 'EXCEPTION_IN_PAGE_ERROR', - win32.EXCEPTION_INT_DIVIDE_BY_ZERO : 'EXCEPTION_INT_DIVIDE_BY_ZERO', - win32.EXCEPTION_INT_OVERFLOW : 'EXCEPTION_INT_OVERFLOW', - win32.EXCEPTION_INVALID_DISPOSITION : 'EXCEPTION_INVALID_DISPOSITION', - win32.EXCEPTION_NONCONTINUABLE_EXCEPTION : 'EXCEPTION_NONCONTINUABLE_EXCEPTION', - win32.EXCEPTION_PRIV_INSTRUCTION : 'EXCEPTION_PRIV_INSTRUCTION', - win32.EXCEPTION_SINGLE_STEP : 'EXCEPTION_SINGLE_STEP', - win32.EXCEPTION_STACK_OVERFLOW : 'EXCEPTION_STACK_OVERFLOW', - win32.EXCEPTION_GUARD_PAGE : 'EXCEPTION_GUARD_PAGE', - win32.EXCEPTION_INVALID_HANDLE : 'EXCEPTION_INVALID_HANDLE', - win32.EXCEPTION_POSSIBLE_DEADLOCK : 'EXCEPTION_POSSIBLE_DEADLOCK', - win32.EXCEPTION_WX86_BREAKPOINT : 'EXCEPTION_WX86_BREAKPOINT', - win32.CONTROL_C_EXIT : 'CONTROL_C_EXIT', - win32.DBG_CONTROL_C : 'DBG_CONTROL_C', - win32.MS_VC_EXCEPTION : 'MS_VC_EXCEPTION', + win32.EXCEPTION_ACCESS_VIOLATION: "EXCEPTION_ACCESS_VIOLATION", + win32.EXCEPTION_ARRAY_BOUNDS_EXCEEDED: "EXCEPTION_ARRAY_BOUNDS_EXCEEDED", + win32.EXCEPTION_BREAKPOINT: "EXCEPTION_BREAKPOINT", + win32.EXCEPTION_DATATYPE_MISALIGNMENT: "EXCEPTION_DATATYPE_MISALIGNMENT", + win32.EXCEPTION_FLT_DENORMAL_OPERAND: "EXCEPTION_FLT_DENORMAL_OPERAND", + win32.EXCEPTION_FLT_DIVIDE_BY_ZERO: "EXCEPTION_FLT_DIVIDE_BY_ZERO", + win32.EXCEPTION_FLT_INEXACT_RESULT: "EXCEPTION_FLT_INEXACT_RESULT", + win32.EXCEPTION_FLT_INVALID_OPERATION: "EXCEPTION_FLT_INVALID_OPERATION", + win32.EXCEPTION_FLT_OVERFLOW: "EXCEPTION_FLT_OVERFLOW", + win32.EXCEPTION_FLT_STACK_CHECK: "EXCEPTION_FLT_STACK_CHECK", + win32.EXCEPTION_FLT_UNDERFLOW: "EXCEPTION_FLT_UNDERFLOW", + win32.EXCEPTION_ILLEGAL_INSTRUCTION: "EXCEPTION_ILLEGAL_INSTRUCTION", + win32.EXCEPTION_IN_PAGE_ERROR: "EXCEPTION_IN_PAGE_ERROR", + win32.EXCEPTION_INT_DIVIDE_BY_ZERO: "EXCEPTION_INT_DIVIDE_BY_ZERO", + win32.EXCEPTION_INT_OVERFLOW: "EXCEPTION_INT_OVERFLOW", + win32.EXCEPTION_INVALID_DISPOSITION: "EXCEPTION_INVALID_DISPOSITION", + win32.EXCEPTION_NONCONTINUABLE_EXCEPTION: "EXCEPTION_NONCONTINUABLE_EXCEPTION", + win32.EXCEPTION_PRIV_INSTRUCTION: "EXCEPTION_PRIV_INSTRUCTION", + win32.EXCEPTION_SINGLE_STEP: "EXCEPTION_SINGLE_STEP", + win32.EXCEPTION_STACK_OVERFLOW: "EXCEPTION_STACK_OVERFLOW", + win32.EXCEPTION_GUARD_PAGE: "EXCEPTION_GUARD_PAGE", + win32.EXCEPTION_INVALID_HANDLE: "EXCEPTION_INVALID_HANDLE", + win32.EXCEPTION_POSSIBLE_DEADLOCK: "EXCEPTION_POSSIBLE_DEADLOCK", + win32.EXCEPTION_WX86_BREAKPOINT: "EXCEPTION_WX86_BREAKPOINT", + win32.CONTROL_C_EXIT: "CONTROL_C_EXIT", + win32.DBG_CONTROL_C: "DBG_CONTROL_C", + win32.MS_VC_EXCEPTION: "MS_VC_EXCEPTION", } __exceptionDescription = { - win32.EXCEPTION_ACCESS_VIOLATION : 'Access violation', - win32.EXCEPTION_ARRAY_BOUNDS_EXCEEDED : 'Array bounds exceeded', - win32.EXCEPTION_BREAKPOINT : 'Breakpoint', - win32.EXCEPTION_DATATYPE_MISALIGNMENT : 'Datatype misalignment', - win32.EXCEPTION_FLT_DENORMAL_OPERAND : 'Float denormal operand', - win32.EXCEPTION_FLT_DIVIDE_BY_ZERO : 'Float divide by zero', - win32.EXCEPTION_FLT_INEXACT_RESULT : 'Float inexact result', - win32.EXCEPTION_FLT_INVALID_OPERATION : 'Float invalid operation', - win32.EXCEPTION_FLT_OVERFLOW : 'Float overflow', - win32.EXCEPTION_FLT_STACK_CHECK : 'Float stack check', - win32.EXCEPTION_FLT_UNDERFLOW : 'Float underflow', - win32.EXCEPTION_ILLEGAL_INSTRUCTION : 'Illegal instruction', - win32.EXCEPTION_IN_PAGE_ERROR : 'In-page error', - win32.EXCEPTION_INT_DIVIDE_BY_ZERO : 'Integer divide by zero', - win32.EXCEPTION_INT_OVERFLOW : 'Integer overflow', - win32.EXCEPTION_INVALID_DISPOSITION : 'Invalid disposition', - win32.EXCEPTION_NONCONTINUABLE_EXCEPTION : 'Noncontinuable exception', - win32.EXCEPTION_PRIV_INSTRUCTION : 'Privileged instruction', - win32.EXCEPTION_SINGLE_STEP : 'Single step event', - win32.EXCEPTION_STACK_OVERFLOW : 'Stack limits overflow', - win32.EXCEPTION_GUARD_PAGE : 'Guard page hit', - win32.EXCEPTION_INVALID_HANDLE : 'Invalid handle', - win32.EXCEPTION_POSSIBLE_DEADLOCK : 'Possible deadlock', - win32.EXCEPTION_WX86_BREAKPOINT : 'WOW64 breakpoint', - win32.CONTROL_C_EXIT : 'Control-C exit', - win32.DBG_CONTROL_C : 'Debug Control-C', - win32.MS_VC_EXCEPTION : 'Microsoft Visual C++ exception', + win32.EXCEPTION_ACCESS_VIOLATION: "Access violation", + win32.EXCEPTION_ARRAY_BOUNDS_EXCEEDED: "Array bounds exceeded", + win32.EXCEPTION_BREAKPOINT: "Breakpoint", + win32.EXCEPTION_DATATYPE_MISALIGNMENT: "Datatype misalignment", + win32.EXCEPTION_FLT_DENORMAL_OPERAND: "Float denormal operand", + win32.EXCEPTION_FLT_DIVIDE_BY_ZERO: "Float divide by zero", + win32.EXCEPTION_FLT_INEXACT_RESULT: "Float inexact result", + win32.EXCEPTION_FLT_INVALID_OPERATION: "Float invalid operation", + win32.EXCEPTION_FLT_OVERFLOW: "Float overflow", + win32.EXCEPTION_FLT_STACK_CHECK: "Float stack check", + win32.EXCEPTION_FLT_UNDERFLOW: "Float underflow", + win32.EXCEPTION_ILLEGAL_INSTRUCTION: "Illegal instruction", + win32.EXCEPTION_IN_PAGE_ERROR: "In-page error", + win32.EXCEPTION_INT_DIVIDE_BY_ZERO: "Integer divide by zero", + win32.EXCEPTION_INT_OVERFLOW: "Integer overflow", + win32.EXCEPTION_INVALID_DISPOSITION: "Invalid disposition", + win32.EXCEPTION_NONCONTINUABLE_EXCEPTION: "Noncontinuable exception", + win32.EXCEPTION_PRIV_INSTRUCTION: "Privileged instruction", + win32.EXCEPTION_SINGLE_STEP: "Single step event", + win32.EXCEPTION_STACK_OVERFLOW: "Stack limits overflow", + win32.EXCEPTION_GUARD_PAGE: "Guard page hit", + win32.EXCEPTION_INVALID_HANDLE: "Invalid handle", + win32.EXCEPTION_POSSIBLE_DEADLOCK: "Possible deadlock", + win32.EXCEPTION_WX86_BREAKPOINT: "WOW64 breakpoint", + win32.CONTROL_C_EXIT: "Control-C exit", + win32.DBG_CONTROL_C: "Debug Control-C", + win32.MS_VC_EXCEPTION: "Microsoft Visual C++ exception", } @property def eventMethod(self): - return self.__exceptionMethod.get( - self.get_exception_code(), 'unknown_exception') + return self.__exceptionMethod.get(self.get_exception_code(), "unknown_exception") def get_exception_name(self): """ @@ -434,7 +434,7 @@ def get_exception_name(self): @return: Name of the exception as defined by the Win32 API. """ code = self.get_exception_code() - unk = HexDump.integer(code) + unk = HexDump.integer(code) return self.__exceptionName.get(code, unk) def get_exception_description(self): @@ -446,11 +446,10 @@ def get_exception_description(self): description = self.__exceptionDescription.get(code, None) if description is None: try: - description = 'Exception code %s (%s)' - description = description % (HexDump.integer(code), - ctypes.FormatError(code)) + description = "Exception code %s (%s)" + description = description % (HexDump.integer(code), ctypes.FormatError(code)) except OverflowError: - description = 'Exception code %s' % HexDump.integer(code) + description = "Exception code %s" % HexDump.integer(code) return description def is_first_chance(self): @@ -478,8 +477,7 @@ def is_noncontinuable(self): Attempting to continue a noncontinuable exception results in an EXCEPTION_NONCONTINUABLE_EXCEPTION exception to be raised. """ - return bool( self.raw.u.Exception.ExceptionRecord.ExceptionFlags & \ - win32.EXCEPTION_NONCONTINUABLE ) + return bool(self.raw.u.Exception.ExceptionRecord.ExceptionFlags & win32.EXCEPTION_NONCONTINUABLE) def is_continuable(self): """ @@ -570,8 +568,7 @@ def get_fault_type(self): @raise NotImplementedError: Wrong kind of exception. """ - if self.get_exception_code() not in (win32.EXCEPTION_ACCESS_VIOLATION, - win32.EXCEPTION_IN_PAGE_ERROR, win32.EXCEPTION_GUARD_PAGE): + if self.get_exception_code() not in (win32.EXCEPTION_ACCESS_VIOLATION, win32.EXCEPTION_IN_PAGE_ERROR, win32.EXCEPTION_GUARD_PAGE): msg = "This method is not meaningful for %s." raise NotImplementedError(msg % self.get_exception_name()) return self.get_exception_information(0) @@ -586,8 +583,7 @@ def get_fault_address(self): @raise NotImplementedError: Wrong kind of exception. """ - if self.get_exception_code() not in (win32.EXCEPTION_ACCESS_VIOLATION, - win32.EXCEPTION_IN_PAGE_ERROR, win32.EXCEPTION_GUARD_PAGE): + if self.get_exception_code() not in (win32.EXCEPTION_ACCESS_VIOLATION, win32.EXCEPTION_IN_PAGE_ERROR, win32.EXCEPTION_GUARD_PAGE): msg = "This method is not meaningful for %s." raise NotImplementedError(msg % self.get_exception_name()) return self.get_exception_information(1) @@ -603,8 +599,7 @@ def get_ntstatus_code(self): @raise NotImplementedError: Not an in-page memory error. """ if self.get_exception_code() != win32.EXCEPTION_IN_PAGE_ERROR: - msg = "This method is only meaningful "\ - "for in-page memory error exceptions." + msg = "This method is only meaningful " "for in-page memory error exceptions." raise NotImplementedError(msg) return self.get_exception_information(2) @@ -665,37 +660,39 @@ def get_nested_exceptions(self): # The list always begins with ourselves. # Just put a reference to "self" as the first element, # and start looping from the second exception record. - nested = [ self ] + nested = [self] raw = self.raw dwDebugEventCode = raw.dwDebugEventCode - dwProcessId = raw.dwProcessId - dwThreadId = raw.dwThreadId - dwFirstChance = raw.u.Exception.dwFirstChance - record = raw.u.Exception.ExceptionRecord + dwProcessId = raw.dwProcessId + dwThreadId = raw.dwThreadId + dwFirstChance = raw.u.Exception.dwFirstChance + record = raw.u.Exception.ExceptionRecord while True: record = record.ExceptionRecord if not record: break raw = win32.DEBUG_EVENT() - raw.dwDebugEventCode = dwDebugEventCode - raw.dwProcessId = dwProcessId - raw.dwThreadId = dwThreadId + raw.dwDebugEventCode = dwDebugEventCode + raw.dwProcessId = dwProcessId + raw.dwThreadId = dwThreadId raw.u.Exception.ExceptionRecord = record - raw.u.Exception.dwFirstChance = dwFirstChance + raw.u.Exception.dwFirstChance = dwFirstChance event = EventFactory.get(self.debug, raw) nested.append(event) return nested -#============================================================================== -class CreateThreadEvent (Event): +# ============================================================================== + + +class CreateThreadEvent(Event): """ Thread creation event. """ - eventMethod = 'create_thread' - eventName = 'Thread creation event' - eventDescription = 'A new thread has started.' + eventMethod = "create_thread" + eventName = "Thread creation event" + eventDescription = "A new thread has started." def get_thread_handle(self): """ @@ -731,16 +728,18 @@ def get_start_address(self): """ return self.raw.u.CreateThread.lpStartAddress -#============================================================================== -class CreateProcessEvent (Event): +# ============================================================================== + + +class CreateProcessEvent(Event): """ Process creation event. """ - eventMethod = 'create_process' - eventName = 'Process creation event' - eventDescription = 'A new process has started.' + eventMethod = "create_process" + eventName = "Process creation event" + eventDescription = "A new process has started." def get_file_handle(self): """ @@ -825,8 +824,8 @@ def get_debug_info(self): @rtype: str @return: Debugging information. """ - raw = self.raw.u.CreateProcessInfo - ptr = raw.lpBaseOfImage + raw.dwDebugInfoFileOffset + raw = self.raw.u.CreateProcessInfo + ptr = raw.lpBaseOfImage + raw.dwDebugInfoFileOffset size = raw.nDebugInfoSize data = self.get_process().peek(ptr, size) if len(data) == size: @@ -847,16 +846,15 @@ def get_filename(self): if hFile: szFilename = hFile.get_filename() if not szFilename: - # Try to get it from CREATE_PROCESS_DEBUG_INFO.lpImageName # It's NULL or *NULL most of the times, see MSDN: # http://msdn.microsoft.com/en-us/library/ms679286(VS.85).aspx aProcess = self.get_process() lpRemoteFilenamePtr = self.raw.u.CreateProcessInfo.lpImageName if lpRemoteFilenamePtr: - lpFilename = aProcess.peek_uint(lpRemoteFilenamePtr) - fUnicode = bool( self.raw.u.CreateProcessInfo.fUnicode ) - szFilename = aProcess.peek_string(lpFilename, fUnicode) + lpFilename = aProcess.peek_uint(lpRemoteFilenamePtr) + fUnicode = bool(self.raw.u.CreateProcessInfo.fUnicode) + szFilename = aProcess.peek_string(lpFilename, fUnicode) # XXX TODO # Sometimes the filename is relative (ntdll.dll, kernel32.dll). @@ -881,18 +879,20 @@ def get_module(self): @rtype: L{Module} @return: Main module of the process. """ - return self.get_process().get_module( self.get_module_base() ) + return self.get_process().get_module(self.get_module_base()) + -#============================================================================== +# ============================================================================== -class ExitThreadEvent (Event): + +class ExitThreadEvent(Event): """ Thread termination event. """ - eventMethod = 'exit_thread' - eventName = 'Thread termination event' - eventDescription = 'A thread has finished executing.' + eventMethod = "exit_thread" + eventName = "Thread termination event" + eventDescription = "A thread has finished executing." def get_exit_code(self): """ @@ -901,16 +901,18 @@ def get_exit_code(self): """ return self.raw.u.ExitThread.dwExitCode -#============================================================================== -class ExitProcessEvent (Event): +# ============================================================================== + + +class ExitProcessEvent(Event): """ Process termination event. """ - eventMethod = 'exit_process' - eventName = 'Process termination event' - eventDescription = 'A process has finished executing.' + eventMethod = "exit_process" + eventName = "Process termination event" + eventDescription = "A process has finished executing." def get_exit_code(self): """ @@ -948,16 +950,18 @@ def get_module(self): """ return self.get_process().get_main_module() -#============================================================================== -class LoadDLLEvent (Event): +# ============================================================================== + + +class LoadDLLEvent(Event): """ Module load event. """ - eventMethod = 'load_dll' - eventName = 'Module load event' - eventDescription = 'A new DLL library was loaded by the debugee.' + eventMethod = "load_dll" + eventName = "Module load event" + eventDescription = "A new DLL library was loaded by the debugee." def get_module_base(self): """ @@ -972,16 +976,13 @@ def get_module(self): @return: Module object for the newly loaded DLL. """ lpBaseOfDll = self.get_module_base() - aProcess = self.get_process() + aProcess = self.get_process() if aProcess.has_module(lpBaseOfDll): aModule = aProcess.get_module(lpBaseOfDll) else: # XXX HACK # For some reason the module object is missing, so make a new one. - aModule = Module(lpBaseOfDll, - hFile = self.get_file_handle(), - fileName = self.get_filename(), - process = aProcess) + aModule = Module(lpBaseOfDll, hFile=self.get_file_handle(), fileName=self.get_filename(), process=aProcess) aProcess._add_module(aModule) return aModule @@ -1020,9 +1021,9 @@ def get_filename(self): aProcess = self.get_process() lpRemoteFilenamePtr = self.raw.u.LoadDll.lpImageName if lpRemoteFilenamePtr: - lpFilename = aProcess.peek_uint(lpRemoteFilenamePtr) - fUnicode = bool( self.raw.u.LoadDll.fUnicode ) - szFilename = aProcess.peek_string(lpFilename, fUnicode) + lpFilename = aProcess.peek_uint(lpRemoteFilenamePtr) + fUnicode = bool(self.raw.u.LoadDll.fUnicode) + szFilename = aProcess.peek_string(lpFilename, fUnicode) if not szFilename: szFilename = None @@ -1035,16 +1036,18 @@ def get_filename(self): # Return the filename, or None on error. return szFilename -#============================================================================== -class UnloadDLLEvent (Event): +# ============================================================================== + + +class UnloadDLLEvent(Event): """ Module unload event. """ - eventMethod = 'unload_dll' - eventName = 'Module unload event' - eventDescription = 'A DLL library was unloaded by the debugee.' + eventMethod = "unload_dll" + eventName = "Module unload event" + eventDescription = "A DLL library was unloaded by the debugee." def get_module_base(self): """ @@ -1059,11 +1062,11 @@ def get_module(self): @return: Module object for the recently unloaded DLL. """ lpBaseOfDll = self.get_module_base() - aProcess = self.get_process() + aProcess = self.get_process() if aProcess.has_module(lpBaseOfDll): aModule = aProcess.get_module(lpBaseOfDll) else: - aModule = Module(lpBaseOfDll, process = aProcess) + aModule = Module(lpBaseOfDll, process=aProcess) aProcess._add_module(aModule) return aModule @@ -1086,16 +1089,18 @@ def get_filename(self): """ return self.get_module().get_filename() -#============================================================================== -class OutputDebugStringEvent (Event): +# ============================================================================== + + +class OutputDebugStringEvent(Event): """ Debug string output event. """ - eventMethod = 'output_string' - eventName = 'Debug string output event' - eventDescription = 'The debugee sent a message to the debugger.' + eventMethod = "output_string" + eventName = "Debug string output event" + eventDescription = "The debugee sent a message to the debugger." def get_debug_string(self): """ @@ -1104,21 +1109,21 @@ def get_debug_string(self): It may be ANSI or Unicode and may end with a null character. """ return self.get_process().peek_string( - self.raw.u.DebugString.lpDebugStringData, - bool( self.raw.u.DebugString.fUnicode ), - self.raw.u.DebugString.nDebugStringLength) + self.raw.u.DebugString.lpDebugStringData, bool(self.raw.u.DebugString.fUnicode), self.raw.u.DebugString.nDebugStringLength + ) -#============================================================================== -class RIPEvent (Event): +# ============================================================================== + + +class RIPEvent(Event): """ RIP event. """ - eventMethod = 'rip' - eventName = 'RIP event' - eventDescription = 'An error has occured and the process ' \ - 'can no longer be debugged.' + eventMethod = "rip" + eventName = "RIP event" + eventDescription = "An error has occured and the process " "can no longer be debugged." def get_rip_error(self): """ @@ -1138,9 +1143,11 @@ def get_rip_type(self): """ return self.raw.u.RipInfo.dwType -#============================================================================== -class EventFactory (StaticClass): +# ============================================================================== + + +class EventFactory(StaticClass): """ Factory of L{Event} objects. @@ -1154,17 +1161,17 @@ class EventFactory (StaticClass): Dictionary that maps event codes to L{Event} subclasses. """ - baseEvent = Event + baseEvent = Event eventClasses = { - win32.EXCEPTION_DEBUG_EVENT : ExceptionEvent, # 1 - win32.CREATE_THREAD_DEBUG_EVENT : CreateThreadEvent, # 2 - win32.CREATE_PROCESS_DEBUG_EVENT : CreateProcessEvent, # 3 - win32.EXIT_THREAD_DEBUG_EVENT : ExitThreadEvent, # 4 - win32.EXIT_PROCESS_DEBUG_EVENT : ExitProcessEvent, # 5 - win32.LOAD_DLL_DEBUG_EVENT : LoadDLLEvent, # 6 - win32.UNLOAD_DLL_DEBUG_EVENT : UnloadDLLEvent, # 7 - win32.OUTPUT_DEBUG_STRING_EVENT : OutputDebugStringEvent, # 8 - win32.RIP_EVENT : RIPEvent, # 9 + win32.EXCEPTION_DEBUG_EVENT: ExceptionEvent, # 1 + win32.CREATE_THREAD_DEBUG_EVENT: CreateThreadEvent, # 2 + win32.CREATE_PROCESS_DEBUG_EVENT: CreateProcessEvent, # 3 + win32.EXIT_THREAD_DEBUG_EVENT: ExitThreadEvent, # 4 + win32.EXIT_PROCESS_DEBUG_EVENT: ExitProcessEvent, # 5 + win32.LOAD_DLL_DEBUG_EVENT: LoadDLLEvent, # 6 + win32.UNLOAD_DLL_DEBUG_EVENT: UnloadDLLEvent, # 7 + win32.OUTPUT_DEBUG_STRING_EVENT: OutputDebugStringEvent, # 8 + win32.RIP_EVENT: RIPEvent, # 9 } @classmethod @@ -1183,9 +1190,11 @@ def get(cls, debug, raw): eventClass = cls.eventClasses.get(raw.dwDebugEventCode, cls.baseEvent) return eventClass(debug, raw) -#============================================================================== -class EventHandler (object): +# ============================================================================== + + +class EventHandler(object): """ Base class for debug event handlers. @@ -1360,7 +1369,7 @@ def post_LoadLibraryEx(self, event, retval): return value from the hooked function. """ -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Default (empty) API hooks dictionary. apiHooks = {} @@ -1403,9 +1412,9 @@ def __init__(self, myArgument): hook_objs = [] for proc, args in hooks: if type(args) in (int, long): - h = ApiHook(self, lib, proc, paramCount = args) + h = ApiHook(self, lib, proc, paramCount=args) else: - h = ApiHook(self, lib, proc, signature = args) + h = ApiHook(self, lib, proc, signature=args) hook_objs.append(h) apiHooks[lib] = hook_objs self.__apiHooks = apiHooks @@ -1433,7 +1442,7 @@ def __hook_dll(self, event): This method is called automatically whenever a DLL is loaded. """ debug = event.debug - pid = event.get_pid() + pid = event.get_pid() for hook_api_stub in self.__get_hooks_for_dll(event): hook_api_stub.hook(debug, pid) @@ -1444,7 +1453,7 @@ def __unhook_dll(self, event): This method is called automatically whenever a DLL is unloaded. """ debug = event.debug - pid = event.get_pid() + pid = event.get_pid() for hook_api_stub in self.__get_hooks_for_dll(event): hook_api_stub.unhook(debug, pid) @@ -1468,7 +1477,8 @@ def __call__(self, event): if method is not None: return method(event) -#============================================================================== + +# ============================================================================== # TODO # * Make it more generic by adding a few more callbacks. @@ -1476,6 +1486,7 @@ def __call__(self, event): # * This interface feels too much like an antipattern. # When apiHooks is deprecated this will have to be reviewed. + class EventSift(EventHandler): """ Event handler that allows you to use customized event handlers for each @@ -1598,9 +1609,9 @@ def __init__(self, cls, *argv, **argd): the event forwarder will be passed on to the constructor of this class as well. """ - self.cls = cls - self.argv = argv - self.argd = argd + self.cls = cls + self.argv = argv + self.argd = argd self.forward = dict() super(EventSift, self).__init__() @@ -1609,8 +1620,7 @@ class as well. def __call__(self, event): try: eventCode = event.get_event_code() - if eventCode in (win32.LOAD_DLL_DEBUG_EVENT, - win32.LOAD_DLL_DEBUG_EVENT): + if eventCode in (win32.LOAD_DLL_DEBUG_EVENT, win32.LOAD_DLL_DEBUG_EVENT): pid = event.get_pid() handler = self.forward.get(pid, None) if handler is None: @@ -1646,9 +1656,11 @@ def event(self, event): del self.forward[pid] return handler(event) -#============================================================================== -class EventDispatcher (object): +# ============================================================================== + + +class EventDispatcher(object): """ Implements debug event dispatching capabilities. @@ -1660,40 +1672,39 @@ class EventDispatcher (object): # These routines are called BEFORE the user-defined handlers. # Unknown codes are ignored. __preEventNotifyCallbackName = { - win32.CREATE_THREAD_DEBUG_EVENT : '_notify_create_thread', - win32.CREATE_PROCESS_DEBUG_EVENT : '_notify_create_process', - win32.LOAD_DLL_DEBUG_EVENT : '_notify_load_dll', + win32.CREATE_THREAD_DEBUG_EVENT: "_notify_create_thread", + win32.CREATE_PROCESS_DEBUG_EVENT: "_notify_create_process", + win32.LOAD_DLL_DEBUG_EVENT: "_notify_load_dll", } # Maps event code constants to the names of the post-notify routines. # These routines are called AFTER the user-defined handlers. # Unknown codes are ignored. __postEventNotifyCallbackName = { - win32.EXIT_THREAD_DEBUG_EVENT : '_notify_exit_thread', - win32.EXIT_PROCESS_DEBUG_EVENT : '_notify_exit_process', - win32.UNLOAD_DLL_DEBUG_EVENT : '_notify_unload_dll', - win32.RIP_EVENT : '_notify_rip', + win32.EXIT_THREAD_DEBUG_EVENT: "_notify_exit_thread", + win32.EXIT_PROCESS_DEBUG_EVENT: "_notify_exit_process", + win32.UNLOAD_DLL_DEBUG_EVENT: "_notify_unload_dll", + win32.RIP_EVENT: "_notify_rip", } # Maps exception code constants to the names of the pre-notify routines. # These routines are called BEFORE the user-defined handlers. # Unknown codes are ignored. __preExceptionNotifyCallbackName = { - win32.EXCEPTION_BREAKPOINT : '_notify_breakpoint', - win32.EXCEPTION_WX86_BREAKPOINT : '_notify_breakpoint', - win32.EXCEPTION_SINGLE_STEP : '_notify_single_step', - win32.EXCEPTION_GUARD_PAGE : '_notify_guard_page', - win32.DBG_CONTROL_C : '_notify_debug_control_c', - win32.MS_VC_EXCEPTION : '_notify_ms_vc_exception', + win32.EXCEPTION_BREAKPOINT: "_notify_breakpoint", + win32.EXCEPTION_WX86_BREAKPOINT: "_notify_breakpoint", + win32.EXCEPTION_SINGLE_STEP: "_notify_single_step", + win32.EXCEPTION_GUARD_PAGE: "_notify_guard_page", + win32.DBG_CONTROL_C: "_notify_debug_control_c", + win32.MS_VC_EXCEPTION: "_notify_ms_vc_exception", } # Maps exception code constants to the names of the post-notify routines. # These routines are called AFTER the user-defined handlers. # Unknown codes are ignored. - __postExceptionNotifyCallbackName = { - } + __postExceptionNotifyCallbackName = {} - def __init__(self, eventHandler = None): + def __init__(self, eventHandler=None): """ Event dispatcher. @@ -1747,9 +1758,9 @@ def set_event_handler(self, eventHandler): wrong_type = False if wrong_type: classname = str(eventHandler) - msg = "Event handler must be an instance of class %s" + msg = "Event handler must be an instance of class %s" msg += "rather than the %s class itself. (Missing parens?)" - msg = msg % (classname, classname) + msg = msg % (classname, classname) raise TypeError(msg) try: previous = self.__eventHandler @@ -1780,9 +1791,9 @@ def get_handler_method(eventHandler, event, fallback=None): Returns C{None} if no such method is defined. """ eventCode = event.get_event_code() - method = getattr(eventHandler, 'event', fallback) + method = getattr(eventHandler, "event", fallback) if eventCode == win32.EXCEPTION_DEBUG_EVENT: - method = getattr(eventHandler, 'exception', method) + method = getattr(eventHandler, "exception", method) method = getattr(eventHandler, event.eventMethod, method) return method @@ -1804,23 +1815,21 @@ def dispatch(self, event): @raise WindowsError: Raises an exception on error. """ - returnValue = None + returnValue = None bCallHandler = True - pre_handler = None + pre_handler = None post_handler = None - eventCode = event.get_event_code() + eventCode = event.get_event_code() # Get the pre and post notification methods for exceptions. # If not found, the following steps take care of that. if eventCode == win32.EXCEPTION_DEBUG_EVENT: exceptionCode = event.get_exception_code() - pre_name = self.__preExceptionNotifyCallbackName.get( - exceptionCode, None) - post_name = self.__postExceptionNotifyCallbackName.get( - exceptionCode, None) - if pre_name is not None: - pre_handler = getattr(self, pre_name, None) - if post_name is not None: + pre_name = self.__preExceptionNotifyCallbackName.get(exceptionCode, None) + post_name = self.__postExceptionNotifyCallbackName.get(exceptionCode, None) + if pre_name is not None: + pre_handler = getattr(self, pre_name, None) + if post_name is not None: post_handler = getattr(self, post_name, None) # Get the pre notification method for all other events. @@ -1828,7 +1837,7 @@ def dispatch(self, event): # for this exception code. if pre_handler is None: pre_name = self.__preEventNotifyCallbackName.get(eventCode, None) - if pre_name is not None: + if pre_name is not None: pre_handler = getattr(self, pre_name, pre_handler) # Get the post notification method for all other events. @@ -1836,7 +1845,7 @@ def dispatch(self, event): # for this exception code. if post_handler is None: post_name = self.__postEventNotifyCallbackName.get(eventCode, None) - if post_name is not None: + if post_name is not None: post_handler = getattr(self, post_name, post_handler) # Call the pre-notify method only if it was defined. @@ -1852,8 +1861,7 @@ def dispatch(self, event): returnValue = self.__eventHandler(event) except Exception: e = sys.exc_info()[1] - msg = ("Event handler pre-callback %r" - " raised an exception: %s") + msg = "Event handler pre-callback %r" " raised an exception: %s" msg = msg % (self.__eventHandler, traceback.format_exc(e)) warnings.warn(msg, EventCallbackWarning) returnValue = None diff --git a/pydevd_attach_to_process/winappdbg/interactive.py b/pydevd_attach_to_process/winappdbg/interactive.py index b9d842f6f..bf8253f72 100644 --- a/pydevd_attach_to_process/winappdbg/interactive.py +++ b/pydevd_attach_to_process/winappdbg/interactive.py @@ -46,7 +46,7 @@ __revision__ = "$Id$" -__all__ = [ 'ConsoleDebugger', 'CmdError' ] +__all__ = ["ConsoleDebugger", "CmdError"] # TODO document this module with docstrings. # TODO command to set a last error breakpoint. @@ -72,10 +72,10 @@ # lazy imports readline = None -#============================================================================== +# ============================================================================== -class DummyEvent (NoEvent): +class DummyEvent(NoEvent): "Dummy event object used internally by L{ConsoleDebugger}." def get_pid(self): @@ -90,27 +90,29 @@ def get_process(self): def get_thread(self): return self._thread -#============================================================================== +# ============================================================================== -class CmdError (Exception): + +class CmdError(Exception): """ Exception raised when a command parsing error occurs. Used internally by L{ConsoleDebugger}. """ -#============================================================================== + +# ============================================================================== -class ConsoleDebugger (Cmd, EventHandler): +class ConsoleDebugger(Cmd, EventHandler): """ Interactive console debugger. @see: L{Debug.interactive} """ -#------------------------------------------------------------------------------ -# Class variables + # ------------------------------------------------------------------------------ + # Class variables # Exception to raise when an error occurs executing a command. command_error_exception = CmdError @@ -119,30 +121,34 @@ class ConsoleDebugger (Cmd, EventHandler): dwMilliseconds = 100 # History file name. - history_file = '.winappdbg_history' + history_file = ".winappdbg_history" # Confirm before quitting? confirm_quit = True # Valid plugin name characters. - valid_plugin_name_chars = 'ABCDEFGHIJKLMNOPQRSTUVWXY' \ - 'abcdefghijklmnopqrstuvwxy' \ - '012345678' \ - '_' + valid_plugin_name_chars = "ABCDEFGHIJKLMNOPQRSTUVWXY" "abcdefghijklmnopqrstuvwxy" "012345678" "_" # Names of the registers. - segment_names = ('cs', 'ds', 'es', 'fs', 'gs') + segment_names = ("cs", "ds", "es", "fs", "gs") register_alias_64_to_32 = { - 'eax':'Rax', 'ebx':'Rbx', 'ecx':'Rcx', 'edx':'Rdx', - 'eip':'Rip', 'ebp':'Rbp', 'esp':'Rsp', 'esi':'Rsi', 'edi':'Rdi' + "eax": "Rax", + "ebx": "Rbx", + "ecx": "Rcx", + "edx": "Rdx", + "eip": "Rip", + "ebp": "Rbp", + "esp": "Rsp", + "esi": "Rsi", + "edi": "Rdi", } - register_alias_64_to_16 = { 'ax':'Rax', 'bx':'Rbx', 'cx':'Rcx', 'dx':'Rdx' } - register_alias_64_to_8_low = { 'al':'Rax', 'bl':'Rbx', 'cl':'Rcx', 'dl':'Rdx' } - register_alias_64_to_8_high = { 'ah':'Rax', 'bh':'Rbx', 'ch':'Rcx', 'dh':'Rdx' } - register_alias_32_to_16 = { 'ax':'Eax', 'bx':'Ebx', 'cx':'Ecx', 'dx':'Edx' } - register_alias_32_to_8_low = { 'al':'Eax', 'bl':'Ebx', 'cl':'Ecx', 'dl':'Edx' } - register_alias_32_to_8_high = { 'ah':'Eax', 'bh':'Ebx', 'ch':'Ecx', 'dh':'Edx' } + register_alias_64_to_16 = {"ax": "Rax", "bx": "Rbx", "cx": "Rcx", "dx": "Rdx"} + register_alias_64_to_8_low = {"al": "Rax", "bl": "Rbx", "cl": "Rcx", "dl": "Rdx"} + register_alias_64_to_8_high = {"ah": "Rax", "bh": "Rbx", "ch": "Rcx", "dh": "Rdx"} + register_alias_32_to_16 = {"ax": "Eax", "bx": "Ebx", "cx": "Ecx", "dx": "Edx"} + register_alias_32_to_8_low = {"al": "Eax", "bl": "Ebx", "cl": "Ecx", "dl": "Edx"} + register_alias_32_to_8_high = {"ah": "Eax", "bh": "Ebx", "ch": "Ecx", "dh": "Edx"} register_aliases_full_32 = list(segment_names) register_aliases_full_32.extend(compat.iterkeys(register_alias_32_to_16)) @@ -159,18 +165,46 @@ class ConsoleDebugger (Cmd, EventHandler): # Names of the control flow instructions. jump_instructions = ( - 'jmp', 'jecxz', 'jcxz', - 'ja', 'jnbe', 'jae', 'jnb', 'jb', 'jnae', 'jbe', 'jna', 'jc', 'je', - 'jz', 'jnc', 'jne', 'jnz', 'jnp', 'jpo', 'jp', 'jpe', 'jg', 'jnle', - 'jge', 'jnl', 'jl', 'jnge', 'jle', 'jng', 'jno', 'jns', 'jo', 'js' + "jmp", + "jecxz", + "jcxz", + "ja", + "jnbe", + "jae", + "jnb", + "jb", + "jnae", + "jbe", + "jna", + "jc", + "je", + "jz", + "jnc", + "jne", + "jnz", + "jnp", + "jpo", + "jp", + "jpe", + "jg", + "jnle", + "jge", + "jnl", + "jl", + "jnge", + "jle", + "jng", + "jno", + "jns", + "jo", + "js", ) - call_instructions = ('call', 'ret', 'retn') - loop_instructions = ('loop', 'loopz', 'loopnz', 'loope', 'loopne') - control_flow_instructions = call_instructions + loop_instructions + \ - jump_instructions + call_instructions = ("call", "ret", "retn") + loop_instructions = ("loop", "loopz", "loopnz", "loope", "loopne") + control_flow_instructions = call_instructions + loop_instructions + jump_instructions -#------------------------------------------------------------------------------ -# Instance variables + # ------------------------------------------------------------------------------ + # Instance variables def __init__(self): """ @@ -190,12 +224,11 @@ def __init__(self): # Last executed command. self.__lastcmd = "" -#------------------------------------------------------------------------------ -# Debugger + # ------------------------------------------------------------------------------ + # Debugger # Use this Debug object. def start_using_debugger(self, debug): - # Clear the previous Debug object. self.stop_using_debugger() @@ -208,7 +241,7 @@ def start_using_debugger(self, debug): # Stop using the Debug object given by start_using_debugger(). # Circular references must be removed, or the destructors never get called. def stop_using_debugger(self): - if hasattr(self, 'debug'): + if hasattr(self, "debug"): debug = self.debug debug.set_event_handler(self.prevHandler) del self.prevHandler @@ -234,21 +267,20 @@ def set_fake_last_event(self, process): if self.lastEvent is None: self.debug.lastEvent = DummyEvent(self.debug) self.debug.lastEvent._process = process - self.debug.lastEvent._thread = process.get_thread( - process.get_thread_ids()[0]) + self.debug.lastEvent._thread = process.get_thread(process.get_thread_ids()[0]) self.debug.lastEvent._pid = process.get_pid() self.debug.lastEvent._tid = self.lastEvent._thread.get_tid() -#------------------------------------------------------------------------------ -# Input + # ------------------------------------------------------------------------------ + # Input -# TODO -# * try to guess breakpoints when insufficient data is given -# * child Cmd instances will have to be used for other prompts, for example -# when assembling or editing memory - it may also be a good idea to think -# if it's possible to make the main Cmd instance also a child, instead of -# the debugger itself - probably the same goes for the EventHandler, maybe -# it can be used as a contained object rather than a parent class. + # TODO + # * try to guess breakpoints when insufficient data is given + # * child Cmd instances will have to be used for other prompts, for example + # when assembling or editing memory - it may also be a good idea to think + # if it's possible to make the main Cmd instance also a child, instead of + # the debugger itself - probably the same goes for the EventHandler, maybe + # it can be used as a contained object rather than a parent class. # Join a token list into an argument string. def join_tokens(self, token_list): @@ -272,7 +304,7 @@ def input_thread(self, token): msg = "more than one thread with that name:\n" for tid in targets: msg += "\t%d\n" % tid - msg = msg[:-len("\n")] + msg = msg[: -len("\n")] raise CmdError(msg) return targets[0] @@ -307,7 +339,7 @@ def input_process(self, token): msg = "more than one process with that name:\n" for pid in targets: msg += "\t%d\n" % pid - msg = msg[:-len("\n")] + msg = msg[: -len("\n")] raise CmdError(msg) return targets[0] @@ -325,7 +357,7 @@ def input_process_list(self, token_list): found = system.find_processes_by_filename(token) if not found: raise CmdError("process not found (%s)" % token) - for (process, _) in found: + for process, _ in found: targets.add(process.get_pid()) targets = list(targets) targets.sort() @@ -339,7 +371,7 @@ def input_command_line(self, command_line): fname = argv[0] if not os.path.exists(fname): try: - fname, _ = win32.SearchPath(None, fname, '.exe') + fname, _ = win32.SearchPath(None, fname, ".exe") except WindowsError: raise CmdError("file not found: %s" % fname) argv[0] = fname @@ -355,7 +387,8 @@ def input_hexadecimal_integer(self, token): # It can be in any supported format. def input_integer(self, token): return HexInput.integer(token) -# # input_integer = input_hexadecimal_integer + + # # input_integer = input_hexadecimal_integer # Token is an address. # The address can be a integer, a label or a register. @@ -401,9 +434,9 @@ def input_address_range(self, token_list, pid=None, tid=None): raise CmdError("bad address range: %s %s" % (token_1, token_2)) elif len(token_list) == 1: token = token_list[0] - if '-' in token: + if "-" in token: try: - token_1, token_2 = token.split('-') + token_1, token_2 = token.split("-") except Exception: raise CmdError("bad address range: %s" % token) address = self.input_address(token_1, pid, tid) @@ -416,18 +449,18 @@ def input_address_range(self, token_list, pid=None, tid=None): # XXX TODO # Support non-integer registers here. def is_register(self, token): - if win32.arch == 'i386': + if win32.arch == "i386": if token in self.register_aliases_full_32: return True token = token.title() - for (name, typ) in win32.CONTEXT._fields_: + for name, typ in win32.CONTEXT._fields_: if name == token: return win32.sizeof(typ) == win32.sizeof(win32.DWORD) - elif win32.arch == 'amd64': + elif win32.arch == "amd64": if token in self.register_aliases_full_64: return True token = token.title() - for (name, typ) in win32.CONTEXT._fields_: + for name, typ in win32.CONTEXT._fields_: if name == token: return win32.sizeof(typ) == win32.sizeof(win32.DWORD64) return False @@ -449,10 +482,9 @@ def input_register(self, token, tid=None): if title in ctx: return ctx.get(title) # eax -> Eax - if ctx.arch == 'i386': - + if ctx.arch == "i386": if token in self.segment_names: - return ctx.get('Seg%s' % title) # cs -> SegCs + return ctx.get("Seg%s" % title) # cs -> SegCs if token in self.register_alias_32_to_16: return ctx.get(self.register_alias_32_to_16[token]) & 0xFFFF @@ -463,10 +495,9 @@ def input_register(self, token, tid=None): if token in self.register_alias_32_to_8_high: return (ctx.get(self.register_alias_32_to_8_high[token]) & 0xFF00) >> 8 - elif ctx.arch == 'amd64': - + elif ctx.arch == "amd64": if token in self.segment_names: - return ctx.get('Seg%s' % title) # cs -> SegCs + return ctx.get("Seg%s" % title) # cs -> SegCs if token in self.register_alias_64_to_32: return ctx.get(self.register_alias_64_to_32[token]) & 0xFFFFFFFF @@ -506,8 +537,8 @@ def input_display(self, token_list, default_size=64): self.default_display_target = next_address return pid, tid, address, size -#------------------------------------------------------------------------------ -# Output + # ------------------------------------------------------------------------------ + # Output # Tell the user a module was loaded. def print_module_load(self, event): @@ -515,7 +546,7 @@ def print_module_load(self, event): base = mod.get_base() name = mod.get_filename() if not name: - name = '' + name = "" msg = "Loaded module (%s) %s" msg = msg % (HexDump.address(base), name) print(msg) @@ -526,7 +557,7 @@ def print_module_unload(self, event): base = mod.get_base() name = mod.get_filename() if not name: - name = '' + name = "" msg = "Unloaded module (%s) %s" msg = msg % (HexDump.address(base), name) print(msg) @@ -577,10 +608,10 @@ def print_event(self, event): name = event.get_event_name() desc = event.get_event_description() if code in desc: - print('') + print("") print("%s: %s" % (name, desc)) else: - print('') + print("") print("%s (%s): %s" % (name, code, desc)) self.print_event_location(event) @@ -590,14 +621,14 @@ def print_exception(self, event): code = HexDump.integer(event.get_exception_code()) desc = event.get_exception_description() if event.is_first_chance(): - chance = 'first' + chance = "first" else: - chance = 'second' + chance = "second" if code in desc: msg = "%s at address %s (%s chance)" % (desc, address, chance) else: msg = "%s (%s) at address %s (%s chance)" % (desc, code, address, chance) - print('') + print("") print(msg) self.print_event_location(event) @@ -638,8 +669,10 @@ def print_current_location(self, process=None, thread=None, pc=None): disasm = None except NotImplementedError: disasm = None - print('') - print(CrashDump.dump_registers(ctx),) + print("") + print( + CrashDump.dump_registers(ctx), + ) print("%s:" % label) if disasm: print(CrashDump.dump_code_line(disasm[0], pc, bShowDump=True)) @@ -649,9 +682,9 @@ def print_current_location(self, process=None, thread=None, pc=None): except Exception: data = None if data: - print('%s: %s' % (HexDump.address(pc), HexDump.hexblock_byte(data))) + print("%s: %s" % (HexDump.address(pc), HexDump.hexblock_byte(data))) else: - print('%s: ???' % HexDump.address(pc)) + print("%s: ???" % HexDump.address(pc)) # Display memory contents using a given method. def print_memory_display(self, arg, method): @@ -663,10 +696,12 @@ def print_memory_display(self, arg, method): data = self.read_memory(address, size, pid) if data: print("%s:" % label) - print(method(data, address),) + print( + method(data, address), + ) -#------------------------------------------------------------------------------ -# Debugging + # ------------------------------------------------------------------------------ + # Debugging # Get the process ID from the prefix or the last event. def get_process_id_from_prefix(self): @@ -783,7 +818,6 @@ def write_memory(self, address, data, pid=None): # Change a register value. def change_register(self, register, value, tid=None): - # Get the thread. if tid is None: if self.lastEvent is None: @@ -806,7 +840,6 @@ def change_register(self, register, value, tid=None): # The finally clause ensures the thread is resumed before returning. thread.suspend() try: - # Get the current context. ctx = thread.get_context() @@ -819,7 +852,7 @@ def change_register(self, register, value, tid=None): # Segment (16 bit) registers. if register in self.segment_names: - register = 'Seg%s' % register.title() # cs -> SegCs + register = "Seg%s" % register.title() # cs -> SegCs value = value & 0x0000FFFF # Integer 16 bits registers. @@ -866,7 +899,7 @@ def find_in_memory(self, query, process): p = data.find(query) while p >= 0: q = p + len(query) - d = data[ p: min(q, p + width) ] + d = data[p : min(q, p + width)] h = HexDump.hexline(d, width=width) a = HexDump.address(address + p) print("%s: %s" % (a, h)) @@ -896,8 +929,8 @@ def kill_thread(self, tid): except Exception: print("Error trying to kill thread (%d)" % tid) -#------------------------------------------------------------------------------ -# Command prompt input + # ------------------------------------------------------------------------------ + # Command prompt input # Prompt the user for commands. def prompt_user(self): @@ -910,14 +943,15 @@ def prompt_user(self): print("*** Error: %s" % str(e)) except Exception: traceback.print_exc() -# # self.debuggerExit = True + + # # self.debuggerExit = True # Prompt the user for a YES/NO kind of question. def ask_user(self, msg, prompt="Are you sure? (y/N): "): print(msg) answer = raw_input(prompt) answer = answer.strip()[:1].lower() - return answer == 'y' + return answer == "y" # Autocomplete the given command when not ambiguous. # Convert it to lowercase (so commands are seen as case insensitive). @@ -936,42 +970,41 @@ def autocomplete(self, cmd): def get_help(self, commands): msg = set() for name in commands: - if name != 'do_help': + if name != "do_help": try: - doc = getattr(self, name).__doc__.split('\n') + doc = getattr(self, name).__doc__.split("\n") except Exception: - return ("No help available when Python" - " is run with the -OO switch.") + return "No help available when Python" " is run with the -OO switch." for x in doc: x = x.strip() if x: - msg.add(' %s' % x) + msg.add(" %s" % x) msg = list(msg) msg.sort() - msg = '\n'.join(msg) + msg = "\n".join(msg) return msg # Parse the prefix and remove it from the command line. def split_prefix(self, line): prefix = None - if line.startswith('~'): - pos = line.find(' ') + if line.startswith("~"): + pos = line.find(" ") if pos == 1: - pos = line.find(' ', pos + 1) + pos = line.find(" ", pos + 1) if not pos < 0: - prefix = line[ 1: pos ].strip() - line = line[ pos: ].strip() + prefix = line[1:pos].strip() + line = line[pos:].strip() return prefix, line -#------------------------------------------------------------------------------ -# Cmd() hacks + # ------------------------------------------------------------------------------ + # Cmd() hacks # Header for help page. - doc_header = 'Available commands (type help * or help )' + doc_header = "Available commands (type help * or help )" -# # # Read and write directly to stdin and stdout. -# # # This prevents the use of raw_input and print. -# # use_rawinput = False + # # # Read and write directly to stdin and stdout. + # # # This prevents the use of raw_input and print. + # # use_rawinput = False @property def prompt(self): @@ -979,15 +1012,15 @@ def prompt(self): pid = self.lastEvent.get_pid() tid = self.lastEvent.get_tid() if self.debug.is_debugee(pid): -# # return '~%d(%d)> ' % (tid, pid) - return '%d:%d> ' % (pid, tid) - return '> ' + # # return '~%d(%d)> ' % (tid, pid) + return "%d:%d> " % (pid, tid) + return "> " # Return a sorted list of method names. # Only returns the methods that implement commands. def get_names(self): names = Cmd.get_names(self) - names = [ x for x in set(names) if x.startswith('do_') ] + names = [x for x in set(names) if x.startswith("do_")] names.sort() return names @@ -998,23 +1031,23 @@ def parseline(self, line): self.cmdprefix, line = self.split_prefix(line) line = line.strip() if line: - if line[0] == '.': - line = 'plugin ' + line[1:] - elif line[0] == '#': - line = 'python ' + line[1:] + if line[0] == ".": + line = "plugin " + line[1:] + elif line[0] == "#": + line = "python " + line[1:] cmd, arg, line = Cmd.parseline(self, line) if cmd: cmd = self.autocomplete(cmd) return cmd, arg, line -# # # Don't repeat the last executed command. -# # def emptyline(self): -# # pass + # # # Don't repeat the last executed command. + # # def emptyline(self): + # # pass # Reset the defaults for some commands. def preloop(self): - self.default_disasm_target = 'eip' - self.default_display_target = 'eip' + self.default_disasm_target = "eip" + self.default_display_target = "eip" self.last_display_command = self.do_db # Put the prefix back in the command line. @@ -1023,7 +1056,7 @@ def get_lastcmd(self): def set_lastcmd(self, lastcmd): if self.cmdprefix: - lastcmd = '~%s %s' % (self.cmdprefix, lastcmd) + lastcmd = "~%s %s" % (self.cmdprefix, lastcmd) self.__lastcmd = lastcmd lastcmd = property(get_lastcmd, set_lastcmd) @@ -1032,8 +1065,8 @@ def set_lastcmd(self, lastcmd): def postcmd(self, stop, line): return stop or self.debuggerExit -#------------------------------------------------------------------------------ -# Commands + # ------------------------------------------------------------------------------ + # Commands # Each command contains a docstring with it's help text. # The help text consist of independent text lines, @@ -1055,23 +1088,23 @@ def do_help(self, arg): """ if not arg: Cmd.do_help(self, arg) - elif arg in ('?', 'help'): + elif arg in ("?", "help"): # An easter egg :) print(" Help! I need somebody...") print(" Help! Not just anybody...") print(" Help! You know, I need someone...") print(" Heeelp!") else: - if arg == '*': + if arg == "*": commands = self.get_names() - commands = [ x for x in commands if x.startswith('do_') ] + commands = [x for x in commands if x.startswith("do_")] else: commands = set() - for x in arg.split(' '): + for x in arg.split(" "): x = x.strip() if x: for n in self.completenames(x): - commands.add('do_%s' % n) + commands.add("do_%s" % n) commands = list(commands) commands.sort() print(self.get_help(commands)) @@ -1090,12 +1123,12 @@ def do_shell(self, arg): # If not found, it's usually OK to just use the filename, # since cmd.exe is one of those "magic" programs that # can be automatically found by CreateProcess. - shell = os.getenv('ComSpec', 'cmd.exe') + shell = os.getenv("ComSpec", "cmd.exe") # When given a command, run it and return. # When no command is given, spawn a shell. if arg: - arg = '%s /c %s' % (shell, arg) + arg = "%s /c %s" % (shell, arg) else: arg = shell process = self.debug.system.start_process(arg, bConsole=True) @@ -1104,7 +1137,6 @@ def do_shell(self, arg): # This hack fixes a bug in Python, the interpreter console is closing the # stdin pipe when calling the exit() function (Ctrl+Z seems to work fine). class _PythonExit(object): - def __repr__(self): return "Use exit() or Ctrl-Z plus Return to exit" @@ -1117,21 +1149,23 @@ def __call__(self): # module already imported. Also the console banner is improved. def _spawn_python_shell(self, arg): import winappdbg - banner = ('Python %s on %s\nType "help", "copyright", ' - '"credits" or "license" for more information.\n') + + banner = 'Python %s on %s\nType "help", "copyright", ' '"credits" or "license" for more information.\n' platform = winappdbg.version.lower() - platform = 'WinAppDbg %s' % platform + platform = "WinAppDbg %s" % platform banner = banner % (sys.version, platform) local = {} local.update(__builtins__) - local.update({ - '__name__': '__console__', - '__doc__': None, - 'exit': self._python_exit, - 'self': self, - 'arg': arg, - 'winappdbg': winappdbg, - }) + local.update( + { + "__name__": "__console__", + "__doc__": None, + "exit": self._python_exit, + "self": self, + "arg": arg, + "winappdbg": winappdbg, + } + ) try: code.interact(banner=banner, local=local) except SystemExit: @@ -1161,8 +1195,7 @@ def do_python(self, arg): self._spawn_python_shell(arg) except Exception: e = sys.exc_info()[1] - raise CmdError( - "unhandled exception when running Python console: %s" % e) + raise CmdError("unhandled exception when running Python console: %s" % e) def do_quit(self, arg): """ @@ -1219,7 +1252,7 @@ def do_detach(self, arg): if not targets: if self.lastEvent is None: raise CmdError("no current process set") - targets = [ self.lastEvent.get_pid() ] + targets = [self.lastEvent.get_pid()] for pid in targets: try: debug.detach(pid) @@ -1235,9 +1268,7 @@ def do_windowed(self, arg): raise CmdError("prefix not allowed") cmdline = self.input_command_line(arg) try: - process = self.debug.execl(arg, - bConsole=False, - bFollow=self.options.follow) + process = self.debug.execl(arg, bConsole=False, bFollow=self.options.follow) print("Spawned process (%d)" % process.get_pid()) except Exception: raise CmdError("can't execute") @@ -1251,9 +1282,7 @@ def do_console(self, arg): raise CmdError("prefix not allowed") cmdline = self.input_command_line(arg) try: - process = self.debug.execl(arg, - bConsole=True, - bFollow=self.options.follow) + process = self.debug.execl(arg, bConsole=True, bFollow=self.options.follow) print("Spawned process (%d)" % process.get_pid()) except Exception: raise CmdError("can't execute") @@ -1326,7 +1355,7 @@ def do_processlist(self, arg): if pid_list: print("Process ID File name") for pid in pid_list: - if pid == 0: + if pid == 0: filename = "System Idle Process" elif pid == 4: filename = "System" @@ -1373,7 +1402,7 @@ def do_kill(self, arg): kill - kill the given processes and threads """ if arg: - if arg == '*': + if arg == "*": target_pids = self.debug.get_debugee_pids() target_tids = list() else: @@ -1458,7 +1487,9 @@ def do_stack(self, arg): try: stack_trace = thread.get_stack_trace_with_labels() if stack_trace: - print(CrashDump.dump_stack_trace_with_labels(stack_trace),) + print( + CrashDump.dump_stack_trace_with_labels(stack_trace), + ) else: print("No stack trace available for thread (%d)" % tid) except WindowsError: @@ -1507,12 +1538,12 @@ def do_step(self, arg): code = thread.disassemble(pc, 16)[0] size = code[1] opcode = code[2].lower() - if ' ' in opcode: - opcode = opcode[: opcode.find(' ') ] - if opcode in self.jump_instructions or opcode in ('int', 'ret', 'retn'): + if " " in opcode: + opcode = opcode[: opcode.find(" ")] + if opcode in self.jump_instructions or opcode in ("int", "ret", "retn"): return self.do_trace(arg) address = pc + size -# # print(hex(pc), hex(address), size # XXX DEBUG + # # print(hex(pc), hex(address), size # XXX DEBUG self.debug.stalk_at(pid, address) return True @@ -1571,21 +1602,21 @@ def do_ba(self, arg): access = token_list[0].lower() size = token_list[1] address = token_list[2] - if access == 'a': + if access == "a": access = debug.BP_BREAK_ON_ACCESS - elif access == 'w': + elif access == "w": access = debug.BP_BREAK_ON_WRITE - elif access == 'e': + elif access == "e": access = debug.BP_BREAK_ON_EXECUTION else: raise CmdError("bad access type: %s" % token_list[0]) - if size == '1': + if size == "1": size = debug.BP_WATCH_BYTE - elif size == '2': + elif size == "2": size = debug.BP_WATCH_WORD - elif size == '4': + elif size == "4": size = debug.BP_WATCH_DWORD - elif size == '8': + elif size == "8": size = debug.BP_WATCH_QWORD else: raise CmdError("bad breakpoint size: %s" % size) @@ -1620,7 +1651,7 @@ def do_bl(self, arg): bl [process...] - list the breakpoints for each given process """ debug = self.debug - if arg == '*': + if arg == "*": if self.cmdprefix: raise CmdError("prefix not supported") breakpoints = debug.get_debugee_pids() @@ -1631,7 +1662,7 @@ def do_bl(self, arg): if not targets: if self.lastEvent is None: raise CmdError("no current process is set") - targets = [ self.lastEvent.get_pid() ] + targets = [self.lastEvent.get_pid()] for pid in targets: bplist = debug.get_process_code_breakpoints(pid) printed_process_banner = False @@ -1640,20 +1671,18 @@ def do_bl(self, arg): print("Process %d:" % pid) printed_process_banner = True for bp in bplist: - address = repr(bp)[1:-1].replace('remote address ', '') + address = repr(bp)[1:-1].replace("remote address ", "") print(" %s" % address) dbplist = debug.get_process_deferred_code_breakpoints(pid) if dbplist: if not printed_process_banner: print("Process %d:" % pid) printed_process_banner = True - for (label, action, oneshot) in dbplist: + for label, action, oneshot in dbplist: if oneshot: - address = " Deferred unconditional one-shot" \ - " code breakpoint at %s" + address = " Deferred unconditional one-shot" " code breakpoint at %s" else: - address = " Deferred unconditional" \ - " code breakpoint at %s" + address = " Deferred unconditional" " code breakpoint at %s" address = address % label print(" %s" % address) bplist = debug.get_process_page_breakpoints(pid) @@ -1662,14 +1691,14 @@ def do_bl(self, arg): print("Process %d:" % pid) printed_process_banner = True for bp in bplist: - address = repr(bp)[1:-1].replace('remote address ', '') + address = repr(bp)[1:-1].replace("remote address ", "") print(" %s" % address) for tid in debug.system.get_process(pid).iter_thread_ids(): bplist = debug.get_thread_hardware_breakpoints(tid) if bplist: print("Thread %d:" % tid) for bp in bplist: - address = repr(bp)[1:-1].replace('remote address ', '') + address = repr(bp)[1:-1].replace("remote address ", "") print(" %s" % address) def do_bo(self, arg): @@ -1806,7 +1835,7 @@ def do_disassemble(self, arg): next_address = HexOutput.integer(next_address) self.default_disasm_target = next_address print("%s:" % label) -# # print(CrashDump.dump_code(code)) + # # print(CrashDump.dump_code(code)) for line in code: print(CrashDump.dump_code_line(line, bShowDump=False)) @@ -1863,20 +1892,22 @@ def do_searchhex(self, arg): else: addr_width = 16 for addr, bytes in iter: - print(HexDump.hexblock(bytes, addr, addr_width),) + print( + HexDump.hexblock(bytes, addr, addr_width), + ) do_sh = do_searchhex -# # def do_strings(self, arg): -# # """ -# # [~process] strings - extract ASCII strings from memory -# # """ -# # if arg: -# # raise CmdError("too many arguments") -# # pid, tid = self.get_process_and_thread_ids_from_prefix() -# # process = self.get_process(pid) -# # for addr, size, data in process.strings(): -# # print("%s: %r" % (HexDump.address(addr), data) + # # def do_strings(self, arg): + # # """ + # # [~process] strings - extract ASCII strings from memory + # # """ + # # if arg: + # # raise CmdError("too many arguments") + # # pid, tid = self.get_process_and_thread_ids_from_prefix() + # # process = self.get_process(pid) + # # for addr, size, data in process.strings(): + # # print("%s: %r" % (HexDump.address(addr), data) def do_d(self, arg): """ @@ -1983,12 +2014,12 @@ def do_register(self, arg): if not arg: self.print_current_location() else: - equ = arg.find('=') + equ = arg.find("=") if equ >= 0: register = arg[:equ].strip() - value = arg[equ + 1:].strip() + value = arg[equ + 1 :].strip() if not value: - value = '0' + value = "0" self.change_register(register, value) else: value = self.input_register(arg) @@ -2021,7 +2052,7 @@ def do_eb(self, arg): pid = self.get_process_id_from_prefix() token_list = self.split_tokens(arg, 2) address = self.input_address(token_list[0], pid) - data = HexInput.hexadecimal(' '.join(token_list[1:])) + data = HexInput.hexadecimal(" ".join(token_list[1:])) self.write_memory(address, data, pid) # XXX TODO @@ -2050,7 +2081,7 @@ def do_memory(self, arg): try: memoryMap = process.get_memory_map() mappedFilenames = process.get_mapped_filenames() - print('') + print("") print(CrashDump.dump_memory_map(memoryMap, mappedFilenames)) except WindowsError: msg = "can't get memory information for process (%d)" @@ -2058,11 +2089,11 @@ def do_memory(self, arg): do_m = do_memory -#------------------------------------------------------------------------------ -# Event handling + # ------------------------------------------------------------------------------ + # Event handling -# TODO -# * add configurable stop/don't stop behavior on events and exceptions + # TODO + # * add configurable stop/don't stop behavior on events and exceptions # Stop for all events, unless stated otherwise. def event(self, event): @@ -2076,7 +2107,7 @@ def exception(self, event): # Stop for breakpoint exceptions. def breakpoint(self, event): - if hasattr(event, 'breakpoint') and event.breakpoint: + if hasattr(event, "breakpoint") and event.breakpoint: self.print_breakpoint_location(event) else: self.print_exception(event) @@ -2130,8 +2161,8 @@ def unload_dll(self, event): def output_string(self, event): self.print_debug_string(event) -#------------------------------------------------------------------------------ -# History file + # ------------------------------------------------------------------------------ + # History file def load_history(self): global readline @@ -2141,15 +2172,14 @@ def load_history(self): except ImportError: return if self.history_file_full_path is None: - folder = os.environ.get('USERPROFILE', '') + folder = os.environ.get("USERPROFILE", "") if not folder: - folder = os.environ.get('HOME', '') + folder = os.environ.get("HOME", "") if not folder: folder = os.path.split(sys.argv[0])[1] if not folder: folder = os.path.curdir - self.history_file_full_path = os.path.join(folder, - self.history_file) + self.history_file_full_path = os.path.join(folder, self.history_file) try: if os.path.exists(self.history_file_full_path): readline.read_history_file(self.history_file_full_path) @@ -2171,8 +2201,8 @@ def save_history(self): e = sys.exc_info()[1] warnings.warn("Cannot save history file, reason: %s" % str(e)) -#------------------------------------------------------------------------------ -# Main loop + # ------------------------------------------------------------------------------ + # Main loop # Debugging loop. def loop(self): @@ -2181,14 +2211,12 @@ def loop(self): # Stop on the initial event, if any. if self.lastEvent is not None: - self.cmdqueue.append('r') + self.cmdqueue.append("r") self.prompt_user() # Loop until the debugger is told to quit. while not self.debuggerExit: - try: - # If for some reason the last event wasn't continued, # continue it here. This won't be done more than once # for a given Event instance, though. @@ -2203,7 +2231,6 @@ def loop(self): # Some debug events may cause the command prompt to be shown. if self.debug.get_debugee_count() > 0: try: - # Get the next debug event. debug.wait() diff --git a/pydevd_attach_to_process/winappdbg/module.py b/pydevd_attach_to_process/winappdbg/module.py index 6ae01831b..223524ebe 100644 --- a/pydevd_attach_to_process/winappdbg/module.py +++ b/pydevd_attach_to_process/winappdbg/module.py @@ -42,7 +42,7 @@ __revision__ = "$Id$" -__all__ = ['Module', 'DebugSymbolsWarning'] +__all__ = ["Module", "DebugSymbolsWarning"] import sys from winappdbg import win32 @@ -57,17 +57,20 @@ import warnings import traceback -#============================================================================== +# ============================================================================== -class DebugSymbolsWarning (UserWarning): + +class DebugSymbolsWarning(UserWarning): """ This warning is issued if the support for debug symbols isn't working properly. """ -#============================================================================== -class Module (object): +# ============================================================================== + + +class Module(object): """ Interface to a DLL library loaded in the context of another process. @@ -115,14 +118,14 @@ class Module (object): Use the L{get_process} method instead. """ - unknown = '' + unknown = "" - class _SymbolEnumerator (object): + class _SymbolEnumerator(object): """ Internally used by L{Module} to enumerate symbols in a module. """ - def __init__(self, undecorate = False): + def __init__(self, undecorate=False): self.symbols = list() self.undecorate = undecorate @@ -134,14 +137,11 @@ def __call__(self, SymbolName, SymbolAddress, SymbolSize, UserContext): try: SymbolName = win32.UnDecorateSymbolName(SymbolName) except Exception: - pass # not all symbols are decorated! - self.symbols.append( (SymbolName, SymbolAddress, SymbolSize) ) + pass # not all symbols are decorated! + self.symbols.append((SymbolName, SymbolAddress, SymbolSize)) return win32.TRUE - def __init__(self, lpBaseOfDll, hFile = None, fileName = None, - SizeOfImage = None, - EntryPoint = None, - process = None): + def __init__(self, lpBaseOfDll, hFile=None, fileName=None, SizeOfImage=None, EntryPoint=None, process=None): """ @type lpBaseOfDll: str @param lpBaseOfDll: Base address of the module. @@ -161,10 +161,10 @@ def __init__(self, lpBaseOfDll, hFile = None, fileName = None, @type process: L{Process} @param process: (Optional) Process where the module is loaded. """ - self.lpBaseOfDll = lpBaseOfDll - self.fileName = fileName - self.SizeOfImage = SizeOfImage - self.EntryPoint = EntryPoint + self.lpBaseOfDll = lpBaseOfDll + self.fileName = fileName + self.SizeOfImage = SizeOfImage + self.EntryPoint = EntryPoint self.__symbols = list() @@ -172,21 +172,21 @@ def __init__(self, lpBaseOfDll, hFile = None, fileName = None, self.set_process(process) # Not really sure if it's a good idea... -## def __eq__(self, aModule): -## """ -## Compare two Module objects. The comparison is made using the process -## IDs and the module bases. -## -## @type aModule: L{Module} -## @param aModule: Another Module object. -## -## @rtype: bool -## @return: C{True} if the two process IDs and module bases are equal, -## C{False} otherwise. -## """ -## return isinstance(aModule, Module) and \ -## self.get_pid() == aModule.get_pid() and \ -## self.get_base() == aModule.get_base() + ## def __eq__(self, aModule): + ## """ + ## Compare two Module objects. The comparison is made using the process + ## IDs and the module bases. + ## + ## @type aModule: L{Module} + ## @param aModule: Another Module object. + ## + ## @rtype: bool + ## @return: C{True} if the two process IDs and module bases are equal, + ## C{False} otherwise. + ## """ + ## return isinstance(aModule, Module) and \ + ## self.get_pid() == aModule.get_pid() and \ + ## self.get_base() == aModule.get_base() def get_handle(self): """ @@ -217,7 +217,7 @@ def get_process(self): # no way to guess! return self.__process - def set_process(self, process = None): + def set_process(self, process=None): """ Manually set the parent process. Use with care! @@ -227,11 +227,11 @@ def set_process(self, process = None): if process is None: self.__process = None else: - global Process # delayed import + global Process # delayed import if Process is None: from winappdbg.process import Process if not isinstance(process, Process): - msg = "Parent process must be a Process instance, " + msg = "Parent process must be a Process instance, " msg += "got %s instead" % type(process) raise TypeError(msg) self.__process = process @@ -281,17 +281,14 @@ def __get_size_and_entry_point(self): process = self.get_process() if process: try: - handle = process.get_handle( win32.PROCESS_VM_READ | - win32.PROCESS_QUERY_INFORMATION ) - base = self.get_base() - mi = win32.GetModuleInformation(handle, base) + handle = process.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION) + base = self.get_base() + mi = win32.GetModuleInformation(handle, base) self.SizeOfImage = mi.SizeOfImage - self.EntryPoint = mi.EntryPoint + self.EntryPoint = mi.EntryPoint except WindowsError: e = sys.exc_info()[1] - warnings.warn( - "Cannot get size and entry point of module %s, reason: %s"\ - % (self.get_name(), e.strerror), RuntimeWarning) + warnings.warn("Cannot get size and entry point of module %s, reason: %s" % (self.get_name(), e.strerror), RuntimeWarning) def get_filename(self): """ @@ -344,7 +341,7 @@ def get_name(self): modName = self.__filename_to_modname(pathname) if isinstance(modName, compat.unicode): try: - modName = modName.encode('cp1252') + modName = modName.encode("cp1252") except UnicodeEncodeError: e = sys.exc_info()[1] warnings.warn(str(e)) @@ -383,7 +380,7 @@ def match_name(self, name): # No match. return False -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def open_handle(self): """ @@ -394,16 +391,14 @@ def open_handle(self): if not self.get_filename(): msg = "Cannot retrieve filename for module at %s" - msg = msg % HexDump.address( self.get_base() ) + msg = msg % HexDump.address(self.get_base()) raise Exception(msg) - hFile = win32.CreateFile(self.get_filename(), - dwShareMode = win32.FILE_SHARE_READ, - dwCreationDisposition = win32.OPEN_EXISTING) + hFile = win32.CreateFile(self.get_filename(), dwShareMode=win32.FILE_SHARE_READ, dwCreationDisposition=win32.OPEN_EXISTING) # In case hFile was set to an actual handle value instead of a Handle # object. This shouldn't happen unless the user tinkered with hFile. - if not hasattr(self.hFile, '__del__'): + if not hasattr(self.hFile, "__del__"): self.close_handle() self.hFile = hFile @@ -418,7 +413,7 @@ def close_handle(self): setting L{hFile} to C{None} should be enough. """ try: - if hasattr(self.hFile, 'close'): + if hasattr(self.hFile, "close"): self.hFile.close() elif self.hFile not in (None, win32.INVALID_HANDLE_VALUE): win32.CloseHandle(self.hFile) @@ -443,7 +438,7 @@ def clear(self): finally: self.close_handle() -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # XXX FIXME # I've been told sometimes the debugging symbols APIs don't correctly @@ -458,47 +453,38 @@ def load_symbols(self): dwAccess = win32.PROCESS_QUERY_LIMITED_INFORMATION else: dwAccess = win32.PROCESS_QUERY_INFORMATION - hProcess = self.get_process().get_handle(dwAccess) - hFile = self.hFile - BaseOfDll = self.get_base() - SizeOfDll = self.get_size() - Enumerator = self._SymbolEnumerator() + hProcess = self.get_process().get_handle(dwAccess) + hFile = self.hFile + BaseOfDll = self.get_base() + SizeOfDll = self.get_size() + Enumerator = self._SymbolEnumerator() try: win32.SymInitialize(hProcess) SymOptions = win32.SymGetOptions() SymOptions |= ( - win32.SYMOPT_ALLOW_ZERO_ADDRESS | - win32.SYMOPT_CASE_INSENSITIVE | - win32.SYMOPT_FAVOR_COMPRESSED | - win32.SYMOPT_INCLUDE_32BIT_MODULES | - win32.SYMOPT_UNDNAME - ) - SymOptions &= ~( - win32.SYMOPT_LOAD_LINES | - win32.SYMOPT_NO_IMAGE_SEARCH | - win32.SYMOPT_NO_CPP | - win32.SYMOPT_IGNORE_NT_SYMPATH + win32.SYMOPT_ALLOW_ZERO_ADDRESS + | win32.SYMOPT_CASE_INSENSITIVE + | win32.SYMOPT_FAVOR_COMPRESSED + | win32.SYMOPT_INCLUDE_32BIT_MODULES + | win32.SYMOPT_UNDNAME ) + SymOptions &= ~(win32.SYMOPT_LOAD_LINES | win32.SYMOPT_NO_IMAGE_SEARCH | win32.SYMOPT_NO_CPP | win32.SYMOPT_IGNORE_NT_SYMPATH) win32.SymSetOptions(SymOptions) try: - win32.SymSetOptions( - SymOptions | win32.SYMOPT_ALLOW_ABSOLUTE_SYMBOLS) + win32.SymSetOptions(SymOptions | win32.SYMOPT_ALLOW_ABSOLUTE_SYMBOLS) except WindowsError: pass try: try: - success = win32.SymLoadModule64( - hProcess, hFile, None, None, BaseOfDll, SizeOfDll) + success = win32.SymLoadModule64(hProcess, hFile, None, None, BaseOfDll, SizeOfDll) except WindowsError: success = 0 if not success: ImageName = self.get_filename() - success = win32.SymLoadModule64( - hProcess, None, ImageName, None, BaseOfDll, SizeOfDll) + success = win32.SymLoadModule64(hProcess, None, ImageName, None, BaseOfDll, SizeOfDll) if success: try: - win32.SymEnumerateSymbols64( - hProcess, BaseOfDll, Enumerator) + win32.SymEnumerateSymbols64(hProcess, BaseOfDll, Enumerator) finally: win32.SymUnloadModule64(hProcess, BaseOfDll) finally: @@ -549,7 +535,7 @@ def iter_symbols(self): self.load_symbols() return self.__symbols.__iter__() - def resolve_symbol(self, symbol, bCaseSensitive = False): + def resolve_symbol(self, symbol, bCaseSensitive=False): """ Resolves a debugging symbol's address. @@ -564,10 +550,10 @@ def resolve_symbol(self, symbol, bCaseSensitive = False): @return: Memory address of symbol. C{None} if not found. """ if bCaseSensitive: - for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols(): + for SymbolName, SymbolAddress, SymbolSize in self.iter_symbols(): if symbol == SymbolName: return SymbolAddress - for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols(): + for SymbolName, SymbolAddress, SymbolSize in self.iter_symbols(): try: SymbolName = win32.UnDecorateSymbolName(SymbolName) except Exception: @@ -576,10 +562,10 @@ def resolve_symbol(self, symbol, bCaseSensitive = False): return SymbolAddress else: symbol = symbol.lower() - for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols(): + for SymbolName, SymbolAddress, SymbolSize in self.iter_symbols(): if symbol == SymbolName.lower(): return SymbolAddress - for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols(): + for SymbolName, SymbolAddress, SymbolSize in self.iter_symbols(): try: SymbolName = win32.UnDecorateSymbolName(SymbolName) except Exception: @@ -602,7 +588,7 @@ def get_symbol_at_address(self, address): Returns C{None} if no symbol could be matched. """ found = None - for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols(): + for SymbolName, SymbolAddress, SymbolSize in self.iter_symbols(): if SymbolAddress > address: continue if SymbolAddress + SymbolSize > address: @@ -610,9 +596,9 @@ def get_symbol_at_address(self, address): found = (SymbolName, SymbolAddress, SymbolSize) return found -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def get_label(self, function = None, offset = None): + def get_label(self, function=None, offset=None): """ Retrieves the label for the given function of this module or the module base address if no function name is given. @@ -628,7 +614,7 @@ def get_label(self, function = None, offset = None): """ return _ModuleContainer.parse_label(self.get_name(), function, offset) - def get_label_at_address(self, address, offset = None): + def get_label_at_address(self, address, offset=None): """ Creates a label from the given memory address. @@ -650,16 +636,16 @@ def get_label_at_address(self, address, offset = None): address = address + offset # Make the label relative to the base address if no match is found. - module = self.get_name() - function = None - offset = address - self.get_base() + module = self.get_name() + function = None + offset = address - self.get_base() # Make the label relative to the entrypoint if no other match is found. # Skip if the entry point is unknown. start = self.get_entry_point() if start and start <= address: - function = "start" - offset = address - start + function = "start" + offset = address - start # Enumerate exported functions and debug symbols, # then find the closest match, if possible. @@ -669,8 +655,8 @@ def get_label_at_address(self, address, offset = None): (SymbolName, SymbolAddress, SymbolSize) = symbol new_offset = address - SymbolAddress if new_offset <= offset: - function = SymbolName - offset = new_offset + function = SymbolName + offset = new_offset except WindowsError: pass @@ -716,14 +702,12 @@ def resolve(self, function): # If the DLL is already mapped locally, resolve the function. try: - hlib = win32.GetModuleHandle(filename) + hlib = win32.GetModuleHandle(filename) address = win32.GetProcAddress(hlib, function) except WindowsError: - # Load the DLL locally, resolve the function and unload it. try: - hlib = win32.LoadLibraryEx(filename, - win32.DONT_RESOLVE_DLL_REFERENCES) + hlib = win32.LoadLibraryEx(filename, win32.DONT_RESOLVE_DLL_REFERENCES) try: address = win32.GetProcAddress(hlib, function) finally: @@ -770,7 +754,6 @@ def resolve_label(self, label): if procedure: address = self.resolve(procedure) if address is None: - # If it's a debug symbol, use the symbol. address = self.resolve_symbol(procedure) @@ -794,7 +777,8 @@ def resolve_label(self, label): address = address + offset return address -#============================================================================== + +# ============================================================================== # TODO # An alternative approach to the toolhelp32 snapshots: parsing the PEB and @@ -802,7 +786,8 @@ def resolve_label(self, label): # of toolhelp32 not working when the process hasn't finished initializing. # See: http://pferrie.host22.com/misc/lowlevel3.htm -class _ModuleContainer (object): + +class _ModuleContainer(object): """ Encapsulates the capability to contain Module objects. @@ -947,7 +932,7 @@ def get_module_count(self): self.__initialize_snapshot() return len(self.__moduleDict) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def get_module_by_name(self, modName): """ @@ -975,12 +960,12 @@ def get_module_by_name(self, modName): for lib in self.iter_modules(): if modName == lib.get_filename().lower(): return lib - return None # Stop trying to match the name. + return None # Stop trying to match the name. # Get all the module names. # This prevents having to iterate through the module list # more than once. - modDict = [ ( lib.get_name(), lib ) for lib in self.iter_modules() ] + modDict = [(lib.get_name(), lib) for lib in self.iter_modules()] modDict = dict(modDict) # modName is a base filename. @@ -1020,13 +1005,13 @@ def get_module_at_address(self, address): i = 0 max_i = len(bases) - 1 while i < max_i: - begin, end = bases[i:i+2] + begin, end = bases[i : i + 2] if begin <= address < end: module = self.get_module(begin) - here = module.is_address_here(address) + here = module.is_address_here(address) if here is False: break - else: # True or None + else: # True or None return module i = i + 1 return None @@ -1057,35 +1042,32 @@ def scan_modules(self): # It would seem easier to clear the snapshot first. # But then all open handles would be closed. found_bases = set() - with win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPMODULE, - dwProcessId) as hSnapshot: + with win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPMODULE, dwProcessId) as hSnapshot: me = win32.Module32First(hSnapshot) while me is not None: lpBaseAddress = me.modBaseAddr - fileName = me.szExePath # full pathname + fileName = me.szExePath # full pathname if not fileName: - fileName = me.szModule # filename only + fileName = me.szModule # filename only if not fileName: fileName = None else: fileName = PathOperations.native_to_win32_pathname(fileName) found_bases.add(lpBaseAddress) -## if not self.has_module(lpBaseAddress): # XXX triggers a scan + ## if not self.has_module(lpBaseAddress): # XXX triggers a scan if lpBaseAddress not in self.__moduleDict: - aModule = Module(lpBaseAddress, fileName = fileName, - SizeOfImage = me.modBaseSize, - process = self) + aModule = Module(lpBaseAddress, fileName=fileName, SizeOfImage=me.modBaseSize, process=self) self._add_module(aModule) else: aModule = self.get_module(lpBaseAddress) if not aModule.fileName: - aModule.fileName = fileName + aModule.fileName = fileName if not aModule.SizeOfImage: aModule.SizeOfImage = me.modBaseSize if not aModule.process: - aModule.process = self + aModule.process = self me = win32.Module32Next(hSnapshot) -## for base in self.get_module_bases(): # XXX triggers a scan + ## for base in self.get_module_bases(): # XXX triggers a scan for base in compat.keys(self.__moduleDict): if base not in found_bases: self._del_module(base) @@ -1098,10 +1080,10 @@ def clear_modules(self): aModule.clear() self.__moduleDict = dict() -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ @staticmethod - def parse_label(module = None, function = None, offset = None): + def parse_label(module=None, function=None, offset=None): """ Creates a label from a module and a function name, plus an offset. @@ -1139,9 +1121,9 @@ def parse_label(module = None, function = None, offset = None): pass # Validate the parameters. - if module is not None and ('!' in module or '+' in module): + if module is not None and ("!" in module or "+" in module): raise ValueError("Invalid module name: %s" % module) - if function is not None and ('!' in function or '+' in function): + if function is not None and ("!" in function or "+" in function): raise ValueError("Invalid function name: %s" % function) # Parse the label. @@ -1153,7 +1135,7 @@ def parse_label(module = None, function = None, offset = None): label = "%s!%s" % (module, function) else: if offset: -## label = "%s+0x%x!" % (module, offset) + ## label = "%s+0x%x!" % (module, offset) label = "%s!0x%x" % (module, offset) else: label = "%s!" % module @@ -1207,33 +1189,32 @@ def split_label_strict(label): if not label: label = "0x0" else: - # Remove all blanks. - label = label.replace(' ', '') - label = label.replace('\t', '') - label = label.replace('\r', '') - label = label.replace('\n', '') + label = label.replace(" ", "") + label = label.replace("\t", "") + label = label.replace("\r", "") + label = label.replace("\n", "") # Special case: empty label. if not label: label = "0x0" # * ! * - if '!' in label: + if "!" in label: try: - module, function = label.split('!') + module, function = label.split("!") except ValueError: raise ValueError("Malformed label: %s" % label) # module ! function if function: - if '+' in module: + if "+" in module: raise ValueError("Malformed label: %s" % label) # module ! function + offset - if '+' in function: + if "+" in function: try: - function, offset = function.split('+') + function, offset = function.split("+") except ValueError: raise ValueError("Malformed label: %s" % label) try: @@ -1241,19 +1222,17 @@ def split_label_strict(label): except ValueError: raise ValueError("Malformed label: %s" % label) else: - # module ! offset try: - offset = HexInput.integer(function) + offset = HexInput.integer(function) function = None except ValueError: pass else: - # module + offset ! - if '+' in module: + if "+" in module: try: - module, offset = module.split('+') + module, offset = module.split("+") except ValueError: raise ValueError("Malformed label: %s" % label) try: @@ -1262,7 +1241,6 @@ def split_label_strict(label): raise ValueError("Malformed label: %s" % label) else: - # module ! try: offset = HexInput.integer(module) @@ -1273,20 +1251,19 @@ def split_label_strict(label): pass if not module: - module = None + module = None if not function: function = None # * else: - # offset try: offset = HexInput.integer(label) # # ordinal except ValueError: - if label.startswith('#'): + if label.startswith("#"): function = label try: HexInput.integer(function[1:]) @@ -1302,7 +1279,7 @@ def split_label_strict(label): raise ValueError("Ambiguous label: %s" % label) # Convert function ordinal strings into integers. - if function and function.startswith('#'): + if function and function.startswith("#"): try: function = HexInput.integer(function[1:]) except ValueError: @@ -1352,31 +1329,30 @@ def split_label_fuzzy(self, label): if not label: label = compat.b("0x0") else: - # Remove all blanks. - label = label.replace(compat.b(' '), compat.b('')) - label = label.replace(compat.b('\t'), compat.b('')) - label = label.replace(compat.b('\r'), compat.b('')) - label = label.replace(compat.b('\n'), compat.b('')) + label = label.replace(compat.b(" "), compat.b("")) + label = label.replace(compat.b("\t"), compat.b("")) + label = label.replace(compat.b("\r"), compat.b("")) + label = label.replace(compat.b("\n"), compat.b("")) # Special case: empty label. if not label: label = compat.b("0x0") # If an exclamation sign is present, we know we can parse it strictly. - if compat.b('!') in label: + if compat.b("!") in label: return self.split_label_strict(label) -## # Try to parse it strictly, on error do it the fuzzy way. -## try: -## return self.split_label(label) -## except ValueError: -## pass + ## # Try to parse it strictly, on error do it the fuzzy way. + ## try: + ## return self.split_label(label) + ## except ValueError: + ## pass # * + offset - if compat.b('+') in label: + if compat.b("+") in label: try: - prefix, offset = label.split(compat.b('+')) + prefix, offset = label.split(compat.b("+")) except ValueError: raise ValueError("Malformed label: %s" % label) try: @@ -1388,13 +1364,11 @@ def split_label_fuzzy(self, label): # This parses both filenames and base addresses. modobj = self.get_module_by_name(label) if modobj: - # module # module + offset module = modobj.get_name() else: - # TODO # If 0xAAAAAAAA + 0xBBBBBBBB is given, # A is interpreted as a module base address, @@ -1426,8 +1400,7 @@ def split_label_fuzzy(self, label): # to prevent an infinite recursion if there's a bug here. try: new_label = self.get_label_at_address(offset) - module, function, offset = \ - self.split_label_strict(new_label) + module, function, offset = self.split_label_strict(new_label) except ValueError: pass @@ -1437,7 +1410,7 @@ def split_label_fuzzy(self, label): function = label # Convert function ordinal strings into integers. - if function and function.startswith(compat.b('#')): + if function and function.startswith(compat.b("#")): try: function = HexInput.integer(function[1:]) except ValueError: @@ -1452,37 +1425,37 @@ def split_label_fuzzy(self, label): @classmethod def split_label(cls, label): """ -Splits a label into it's C{module}, C{function} and C{offset} -components, as used in L{parse_label}. + Splits a label into it's C{module}, C{function} and C{offset} + components, as used in L{parse_label}. -When called as a static method, the strict syntax mode is used:: + When called as a static method, the strict syntax mode is used:: - winappdbg.Process.split_label( "kernel32!CreateFileA" ) + winappdbg.Process.split_label( "kernel32!CreateFileA" ) -When called as an instance method, the fuzzy syntax mode is used:: + When called as an instance method, the fuzzy syntax mode is used:: - aProcessInstance.split_label( "CreateFileA" ) + aProcessInstance.split_label( "CreateFileA" ) -@see: L{split_label_strict}, L{split_label_fuzzy} + @see: L{split_label_strict}, L{split_label_fuzzy} -@type label: str -@param label: Label to split. + @type label: str + @param label: Label to split. -@rtype: tuple( str or None, str or int or None, int or None ) -@return: - Tuple containing the C{module} name, - the C{function} name or ordinal, and the C{offset} value. + @rtype: tuple( str or None, str or int or None, int or None ) + @return: + Tuple containing the C{module} name, + the C{function} name or ordinal, and the C{offset} value. - If the label doesn't specify a module, - then C{module} is C{None}. + If the label doesn't specify a module, + then C{module} is C{None}. - If the label doesn't specify a function, - then C{function} is C{None}. + If the label doesn't specify a function, + then C{function} is C{None}. - If the label doesn't specify an offset, - then C{offset} is C{0}. + If the label doesn't specify an offset, + then C{offset} is C{0}. -@raise ValueError: The label is malformed. + @raise ValueError: The label is malformed. """ # XXX @@ -1497,7 +1470,8 @@ def split_label(cls, label): def __use_fuzzy_mode(self, label): "@see: L{split_label}" return self.split_label_fuzzy(label) -## __use_fuzzy_mode.__doc__ = split_label.__doc__ + + ## __use_fuzzy_mode.__doc__ = split_label.__doc__ def sanitize_label(self, label): """ @@ -1548,9 +1522,7 @@ def resolve_label(self, label): # Return the memory address. return address - def resolve_label_components(self, module = None, - function = None, - offset = None): + def resolve_label_components(self, module=None, function=None, offset=None): """ Resolve the memory address of the given module, function and/or offset. @@ -1639,7 +1611,7 @@ def resolve_label_components(self, module = None, address = address + offset return address - def get_label_at_address(self, address, offset = None): + def get_label_at_address(self, address, offset=None): """ Creates a label from the given memory address. @@ -1665,7 +1637,7 @@ def get_label_at_address(self, address, offset = None): label = self.parse_label(None, None, address) return label -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # The memory addresses of system breakpoints are be cached, since they're # all in system libraries it's not likely they'll ever change their address @@ -1693,8 +1665,7 @@ def get_break_on_error_ptr(self): """ address = self.__get_system_breakpoint("ntdll!g_dwLastErrorToBreakOn") if not address: - address = self.__get_system_breakpoint( - "kernel32!g_dwLastErrorToBreakOn") + address = self.__get_system_breakpoint("kernel32!g_dwLastErrorToBreakOn") # cheat a little :) self.__system_breakpoints["ntdll!g_dwLastErrorToBreakOn"] = address return address @@ -1712,8 +1683,7 @@ def is_system_defined_breakpoint(self, address): if address: module = self.get_module_at_address(address) if module: - return module.match_name("ntdll") or \ - module.match_name("kernel32") + return module.match_name("ntdll") or module.match_name("kernel32") return False # FIXME @@ -1778,7 +1748,7 @@ def get_wow64_breakin_breakpoint(self): """ return self.__get_system_breakpoint("ntdll32!DbgUiRemoteBreakin") -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def load_symbols(self): """ @@ -1830,7 +1800,7 @@ def iter_symbols(self): for symbol in aModule.iter_symbols(): yield symbol - def resolve_symbol(self, symbol, bCaseSensitive = False): + def resolve_symbol(self, symbol, bCaseSensitive=False): """ Resolves a debugging symbol's address. @@ -1845,12 +1815,12 @@ def resolve_symbol(self, symbol, bCaseSensitive = False): @return: Memory address of symbol. C{None} if not found. """ if bCaseSensitive: - for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols(): + for SymbolName, SymbolAddress, SymbolSize in self.iter_symbols(): if symbol == SymbolName: return SymbolAddress else: symbol = symbol.lower() - for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols(): + for SymbolName, SymbolAddress, SymbolSize in self.iter_symbols(): if symbol == SymbolName.lower(): return SymbolAddress @@ -1871,7 +1841,7 @@ def get_symbol_at_address(self, address): # Any module may have symbols pointing anywhere in memory, so there's # no easy way to optimize this. I guess we're stuck with brute force. found = None - for (SymbolName, SymbolAddress, SymbolSize) in self.iter_symbols(): + for SymbolName, SymbolAddress, SymbolSize in self.iter_symbols(): if SymbolAddress > address: continue @@ -1885,7 +1855,8 @@ def get_symbol_at_address(self, address): else: found = (SymbolName, SymbolAddress, SymbolSize) return found -#------------------------------------------------------------------------------ + + # ------------------------------------------------------------------------------ # XXX _notify_* methods should not trigger a scan @@ -1896,17 +1867,17 @@ def _add_module(self, aModule): @type aModule: L{Module} @param aModule: Module object. """ -## if not isinstance(aModule, Module): -## if hasattr(aModule, '__class__'): -## typename = aModule.__class__.__name__ -## else: -## typename = str(type(aModule)) -## msg = "Expected Module, got %s instead" % typename -## raise TypeError(msg) + ## if not isinstance(aModule, Module): + ## if hasattr(aModule, '__class__'): + ## typename = aModule.__class__.__name__ + ## else: + ## typename = str(type(aModule)) + ## msg = "Expected Module, got %s instead" % typename + ## raise TypeError(msg) lpBaseOfDll = aModule.get_base() -## if lpBaseOfDll in self.__moduleDict: -## msg = "Module already exists: %d" % lpBaseOfDll -## raise KeyError(msg) + ## if lpBaseOfDll in self.__moduleDict: + ## msg = "Module already exists: %d" % lpBaseOfDll + ## raise KeyError(msg) aModule.set_process(self) self.__moduleDict[lpBaseOfDll] = aModule @@ -1925,7 +1896,7 @@ def _del_module(self, lpBaseOfDll): msg = "Unknown base address %d" % HexDump.address(lpBaseOfDll) warnings.warn(msg, RuntimeWarning) if aModule: - aModule.clear() # remove circular references + aModule.clear() # remove circular references def __add_loaded_module(self, event): """ @@ -1935,29 +1906,25 @@ def __add_loaded_module(self, event): @param event: Event object. """ lpBaseOfDll = event.get_module_base() - hFile = event.get_file_handle() -## if not self.has_module(lpBaseOfDll): # XXX this would trigger a scan + hFile = event.get_file_handle() + ## if not self.has_module(lpBaseOfDll): # XXX this would trigger a scan if lpBaseOfDll not in self.__moduleDict: fileName = event.get_filename() if not fileName: fileName = None - if hasattr(event, 'get_start_address'): + if hasattr(event, "get_start_address"): EntryPoint = event.get_start_address() else: EntryPoint = None - aModule = Module(lpBaseOfDll, hFile, fileName = fileName, - EntryPoint = EntryPoint, - process = self) + aModule = Module(lpBaseOfDll, hFile, fileName=fileName, EntryPoint=EntryPoint, process=self) self._add_module(aModule) else: aModule = self.get_module(lpBaseOfDll) - if not aModule.hFile and hFile not in (None, 0, - win32.INVALID_HANDLE_VALUE): + if not aModule.hFile and hFile not in (None, 0, win32.INVALID_HANDLE_VALUE): aModule.hFile = hFile if not aModule.process: aModule.process = self - if aModule.EntryPoint is None and \ - hasattr(event, 'get_start_address'): + if aModule.EntryPoint is None and hasattr(event, "get_start_address"): aModule.EntryPoint = event.get_start_address() if not aModule.fileName: fileName = event.get_filename() @@ -2010,7 +1977,7 @@ def _notify_unload_dll(self, event): @return: C{True} to call the user-defined handle, C{False} otherwise. """ lpBaseOfDll = event.get_module_base() -## if self.has_module(lpBaseOfDll): # XXX this would trigger a scan + ## if self.has_module(lpBaseOfDll): # XXX this would trigger a scan if lpBaseOfDll in self.__moduleDict: self._del_module(lpBaseOfDll) return True diff --git a/pydevd_attach_to_process/winappdbg/process.py b/pydevd_attach_to_process/winappdbg/process.py index 5d2ae3c17..c27495876 100644 --- a/pydevd_attach_to_process/winappdbg/process.py +++ b/pydevd_attach_to_process/winappdbg/process.py @@ -45,7 +45,7 @@ __revision__ = "$Id$" -__all__ = ['Process'] +__all__ = ["Process"] import sys from winappdbg import win32 @@ -55,8 +55,7 @@ from winappdbg.module import Module, _ModuleContainer from winappdbg.thread import Thread, _ThreadContainer from winappdbg.window import Window -from winappdbg.search import Search, \ - Pattern, BytePattern, TextPattern, RegExpPattern, HexPattern +from winappdbg.search import Search, Pattern, BytePattern, TextPattern, RegExpPattern, HexPattern from winappdbg.disasm import Disassembler import re @@ -70,7 +69,7 @@ # delayed import System = None -#============================================================================== +# ============================================================================== # TODO # * Remote GetLastError() @@ -79,7 +78,8 @@ # retrieve the original memory contents where code breakpoints are enabled. # * A memory cache could be implemented here. -class Process (_ThreadContainer, _ModuleContainer): + +class Process(_ThreadContainer, _ModuleContainer): """ Interface to a process. Contains threads and modules snapshots. @@ -150,7 +150,7 @@ class Process (_ThreadContainer, _ModuleContainer): @ivar fileName: Filename of the main module. Use L{get_filename} instead. """ - def __init__(self, dwProcessId, hProcess = None, fileName = None): + def __init__(self, dwProcessId, hProcess=None, fileName=None): """ @type dwProcessId: int @param dwProcessId: Global process ID. @@ -165,8 +165,8 @@ def __init__(self, dwProcessId, hProcess = None, fileName = None): _ModuleContainer.__init__(self) self.dwProcessId = dwProcessId - self.hProcess = hProcess - self.fileName = fileName + self.hProcess = hProcess + self.fileName = fileName def get_pid(self): """ @@ -184,7 +184,7 @@ def get_filename(self): self.fileName = self.get_image_name() return self.fileName - def open_handle(self, dwDesiredAccess = win32.PROCESS_ALL_ACCESS): + def open_handle(self, dwDesiredAccess=win32.PROCESS_ALL_ACCESS): """ Opens a new handle to the process. @@ -208,8 +208,7 @@ def open_handle(self, dwDesiredAccess = win32.PROCESS_ALL_ACCESS): try: self.close_handle() except Exception: - warnings.warn( - "Failed to close process handle: %s" % traceback.format_exc()) + warnings.warn("Failed to close process handle: %s" % traceback.format_exc()) self.hProcess = hProcess @@ -223,14 +222,14 @@ def close_handle(self): setting L{hProcess} to C{None} should be enough. """ try: - if hasattr(self.hProcess, 'close'): + if hasattr(self.hProcess, "close"): self.hProcess.close() elif self.hProcess not in (None, win32.INVALID_HANDLE_VALUE): win32.CloseHandle(self.hProcess) finally: self.hProcess = None - def get_handle(self, dwDesiredAccess = win32.PROCESS_ALL_ACCESS): + def get_handle(self, dwDesiredAccess=win32.PROCESS_ALL_ACCESS): """ Returns a handle to the process with I{at least} the access rights requested. @@ -261,26 +260,26 @@ def get_handle(self, dwDesiredAccess = win32.PROCESS_ALL_ACCESS): self.open_handle(dwAccess | dwDesiredAccess) return self.hProcess -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Not really sure if it's a good idea... -## def __eq__(self, aProcess): -## """ -## Compare two Process objects. The comparison is made using the IDs. -## -## @warning: -## If you have two Process instances with different handles the -## equality operator still returns C{True}, so be careful! -## -## @type aProcess: L{Process} -## @param aProcess: Another Process object. -## -## @rtype: bool -## @return: C{True} if the two process IDs are equal, -## C{False} otherwise. -## """ -## return isinstance(aProcess, Process) and \ -## self.get_pid() == aProcess.get_pid() + ## def __eq__(self, aProcess): + ## """ + ## Compare two Process objects. The comparison is made using the IDs. + ## + ## @warning: + ## If you have two Process instances with different handles the + ## equality operator still returns C{True}, so be careful! + ## + ## @type aProcess: L{Process} + ## @param aProcess: Another Process object. + ## + ## @rtype: bool + ## @return: C{True} if the two process IDs are equal, + ## C{False} otherwise. + ## """ + ## return isinstance(aProcess, Process) and \ + ## self.get_pid() == aProcess.get_pid() def __contains__(self, anObject): """ @@ -293,8 +292,7 @@ def __contains__(self, anObject): @rtype: bool @return: C{True} if the requested object was found in the snapshot. """ - return _ThreadContainer.__contains__(self, anObject) or \ - _ModuleContainer.__contains__(self, anObject) + return _ThreadContainer.__contains__(self, anObject) or _ModuleContainer.__contains__(self, anObject) def __len__(self): """ @@ -302,10 +300,9 @@ def __len__(self): @rtype: int @return: Count of L{Thread} and L{Module} objects in this snapshot. """ - return _ThreadContainer.__len__(self) + \ - _ModuleContainer.__len__(self) + return _ThreadContainer.__len__(self) + _ModuleContainer.__len__(self) - class __ThreadsAndModulesIterator (object): + class __ThreadsAndModulesIterator(object): """ Iterator object for L{Process} objects. Iterates through L{Thread} objects first, L{Module} objects next. @@ -317,30 +314,30 @@ def __init__(self, container): @param container: L{Thread} and L{Module} container. """ self.__container = container - self.__iterator = None - self.__state = 0 + self.__iterator = None + self.__state = 0 def __iter__(self): - 'x.__iter__() <==> iter(x)' + "x.__iter__() <==> iter(x)" return self def next(self): - 'x.next() -> the next value, or raise StopIteration' + "x.next() -> the next value, or raise StopIteration" if self.__state == 0: self.__iterator = self.__container.iter_threads() - self.__state = 1 + self.__state = 1 if self.__state == 1: try: return self.__iterator.next() except StopIteration: self.__iterator = self.__container.iter_modules() - self.__state = 2 + self.__state = 2 if self.__state == 2: try: return self.__iterator.next() except StopIteration: self.__iterator = None - self.__state = 3 + self.__state = 3 raise StopIteration def __iter__(self): @@ -352,9 +349,9 @@ def __iter__(self): """ return self.__ThreadsAndModulesIterator(self) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def wait(self, dwTimeout = None): + def wait(self, dwTimeout=None): """ Waits for the process to finish executing. @@ -362,7 +359,7 @@ def wait(self, dwTimeout = None): """ self.get_handle(win32.SYNCHRONIZE).wait(dwTimeout) - def kill(self, dwExitCode = 0): + def kill(self, dwExitCode=0): """ Terminates the execution of the process. @@ -377,7 +374,7 @@ def suspend(self): @raise WindowsError: On error an exception is raised. """ - self.scan_threads() # force refresh the snapshot + self.scan_threads() # force refresh the snapshot suspended = list() try: for aThread in self.iter_threads(): @@ -398,7 +395,7 @@ def resume(self): @raise WindowsError: On error an exception is raised. """ if self.get_thread_count() == 0: - self.scan_threads() # only refresh the snapshot if empty + self.scan_threads() # only refresh the snapshot if empty resumed = list() try: for aThread in self.iter_threads(): @@ -459,9 +456,9 @@ def get_exit_code(self): dwAccess = win32.PROCESS_QUERY_LIMITED_INFORMATION else: dwAccess = win32.PROCESS_QUERY_INFORMATION - return win32.GetExitCodeProcess( self.get_handle(dwAccess) ) + return win32.GetExitCodeProcess(self.get_handle(dwAccess)) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def scan(self): """ @@ -482,10 +479,10 @@ def clear(self): finally: self.close_handle() -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Regular expression to find hexadecimal values of any size. - __hexa_parameter = re.compile('0x[0-9A-Fa-f]+') + __hexa_parameter = re.compile("0x[0-9A-Fa-f]+") def __fixup_labels(self, disasm): """ @@ -504,7 +501,7 @@ def __fixup_labels(self, disasm): s, e = m.span() value = text[s:e] try: - label = self.get_label_at_address( int(value, 0x10) ) + label = self.get_label_at_address(int(value, 0x10)) except Exception: label = None if label: @@ -537,7 +534,7 @@ def disassemble_string(self, lpAddress, code): try: disasm = self.__disasm except AttributeError: - disasm = self.__disasm = Disassembler( self.get_arch() ) + disasm = self.__disasm = Disassembler(self.get_arch()) return disasm.decode(lpAddress, code) def disassemble(self, lpAddress, dwSize): @@ -558,14 +555,14 @@ def disassemble(self, lpAddress, dwSize): - Disassembly line of instruction. - Hexadecimal dump of instruction. """ - data = self.read(lpAddress, dwSize) + data = self.read(lpAddress, dwSize) disasm = self.disassemble_string(lpAddress, data) self.__fixup_labels(disasm) return disasm # FIXME # This algorithm really bad, I've got to write a better one :P - def disassemble_around(self, lpAddress, dwSize = 64): + def disassemble_around(self, lpAddress, dwSize=64): """ Disassemble around the given address. @@ -584,21 +581,21 @@ def disassemble_around(self, lpAddress, dwSize = 64): - Disassembly line of instruction. - Hexadecimal dump of instruction. """ - dwDelta = int(float(dwSize) / 2.0) - addr_1 = lpAddress - dwDelta - addr_2 = lpAddress - size_1 = dwDelta - size_2 = dwSize - dwDelta - data = self.read(addr_1, dwSize) - data_1 = data[:size_1] - data_2 = data[size_1:] + dwDelta = int(float(dwSize) / 2.0) + addr_1 = lpAddress - dwDelta + addr_2 = lpAddress + size_1 = dwDelta + size_2 = dwSize - dwDelta + data = self.read(addr_1, dwSize) + data_1 = data[:size_1] + data_2 = data[size_1:] disasm_1 = self.disassemble_string(addr_1, data_1) disasm_2 = self.disassemble_string(addr_2, data_2) - disasm = disasm_1 + disasm_2 + disasm = disasm_1 + disasm_2 self.__fixup_labels(disasm) return disasm - def disassemble_around_pc(self, dwThreadId, dwSize = 64): + def disassemble_around_pc(self, dwThreadId, dwSize=64): """ Disassemble around the program counter of the given thread. @@ -659,7 +656,7 @@ def disassemble_current(self, dwThreadId): aThread = self.get_thread(dwThreadId) return self.disassemble_instruction(aThread.get_pc()) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def flush_instruction_cache(self): """ @@ -676,7 +673,7 @@ def flush_instruction_cache(self): # Maybe PROCESS_VM_OPERATION ??? # In any case we're only calling this from the debugger, # so it should be fine (we already have PROCESS_ALL_ACCESS). - win32.FlushInstructionCache( self.get_handle() ) + win32.FlushInstructionCache(self.get_handle()) def debug_break(self): """ @@ -687,7 +684,7 @@ def debug_break(self): # The exception is raised by a new thread. # When continuing the exception, the thread dies by itself. # This thread is hidden from the debugger. - win32.DebugBreakProcess( self.get_handle() ) + win32.DebugBreakProcess(self.get_handle()) def is_wow64(self): """ @@ -709,7 +706,7 @@ def is_wow64(self): try: wow64 = self.__wow64 except AttributeError: - if (win32.bits == 32 and not win32.wow64): + if win32.bits == 32 and not win32.wow64: wow64 = False else: if win32.PROCESS_ALL_ACCESS == win32.PROCESS_ALL_ACCESS_VISTA: @@ -759,13 +756,11 @@ def get_bits(self): # Are we in a 32 bit machine? if win32.bits == 32 and not win32.wow64: - # All processes are 32 bits. return 32 # Is the process inside WOW64? if self.is_wow64(): - # The process is 32 bits. return 32 @@ -775,7 +770,7 @@ def get_bits(self): # TODO: get_os, to test compatibility run # See: http://msdn.microsoft.com/en-us/library/windows/desktop/ms683224(v=vs.85).aspx -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def get_start_time(self): """ @@ -827,14 +822,14 @@ def get_running_time(self): if self.is_alive(): ExitTime = win32.GetSystemTimeAsFileTime() CreationTime = CreationTime.dwLowDateTime + (CreationTime.dwHighDateTime << 32) - ExitTime = ExitTime.dwLowDateTime + ( ExitTime.dwHighDateTime << 32) - RunningTime = ExitTime - CreationTime - return RunningTime / 10000 # 100 nanoseconds steps => milliseconds + ExitTime = ExitTime.dwLowDateTime + (ExitTime.dwHighDateTime << 32) + RunningTime = ExitTime - CreationTime + return RunningTime / 10000 # 100 nanoseconds steps => milliseconds -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def __load_System_class(self): - global System # delayed import + global System # delayed import if System is None: from system import System @@ -852,7 +847,7 @@ def get_services(self): pid = self.get_pid() return [d for d in System.get_active_services() if d.ProcessId == pid] -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def get_dep_policy(self): """ @@ -884,7 +879,7 @@ def get_dep_policy(self): msg = "This method is only available in Windows XP SP3 and above." raise NotImplementedError(msg) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def get_peb(self): """ @@ -895,8 +890,7 @@ def get_peb(self): @return: PEB structure. @raise WindowsError: An exception is raised on error. """ - self.get_handle( win32.PROCESS_VM_READ | - win32.PROCESS_QUERY_INFORMATION ) + self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION) return self.read_structure(self.get_peb_address(), win32.PEB) def get_peb_address(self): @@ -911,8 +905,7 @@ def get_peb_address(self): return self._peb_ptr except AttributeError: hProcess = self.get_handle(win32.PROCESS_QUERY_INFORMATION) - pbi = win32.NtQueryInformationProcess(hProcess, - win32.ProcessBasicInformation) + pbi = win32.NtQueryInformationProcess(hProcess, win32.ProcessBasicInformation) address = pbi.PebBaseAddress self._peb_ptr = address return address @@ -961,18 +954,17 @@ def get_image_name(self): if not name: name = None except (KeyError, AttributeError, WindowsError): -## traceback.print_exc() # XXX DEBUG + ## traceback.print_exc() # XXX DEBUG name = None # Method 2: QueryFullProcessImageName() # Not implemented until Windows Vista. if not name: try: - hProcess = self.get_handle( - win32.PROCESS_QUERY_LIMITED_INFORMATION) + hProcess = self.get_handle(win32.PROCESS_QUERY_LIMITED_INFORMATION) name = win32.QueryFullProcessImageName(hProcess) except (AttributeError, WindowsError): -## traceback.print_exc() # XXX DEBUG + ## traceback.print_exc() # XXX DEBUG name = None # Method 3: GetProcessImageFileName() @@ -989,7 +981,7 @@ def get_image_name(self): else: name = None except (AttributeError, WindowsError): -## traceback.print_exc() # XXX DEBUG + ## traceback.print_exc() # XXX DEBUG if not name: name = None @@ -1000,20 +992,18 @@ def get_image_name(self): # in usermode space (see http://www.ragestorm.net/blogs/?p=163). if not name: try: - hProcess = self.get_handle( win32.PROCESS_VM_READ | - win32.PROCESS_QUERY_INFORMATION ) + hProcess = self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION) try: name = win32.GetModuleFileNameEx(hProcess) except WindowsError: -## traceback.print_exc() # XXX DEBUG - name = win32.GetModuleFileNameEx( - hProcess, self.get_image_base()) + ## traceback.print_exc() # XXX DEBUG + name = win32.GetModuleFileNameEx(hProcess, self.get_image_base()) if name: name = PathOperations.native_to_win32_pathname(name) else: name = None except (AttributeError, WindowsError): -## traceback.print_exc() # XXX DEBUG + ## traceback.print_exc() # XXX DEBUG if not name: name = None @@ -1026,17 +1016,15 @@ def get_image_name(self): if not name: try: peb = self.get_peb() - pp = self.read_structure(peb.ProcessParameters, - win32.RTL_USER_PROCESS_PARAMETERS) + pp = self.read_structure(peb.ProcessParameters, win32.RTL_USER_PROCESS_PARAMETERS) s = pp.ImagePathName - name = self.peek_string(s.Buffer, - dwMaxSize=s.MaximumLength, fUnicode=True) + name = self.peek_string(s.Buffer, dwMaxSize=s.MaximumLength, fUnicode=True) if name: name = PathOperations.native_to_win32_pathname(name) else: name = None except (AttributeError, WindowsError): -## traceback.print_exc() # XXX DEBUG + ## traceback.print_exc() # XXX DEBUG name = None # Method 6: Module.get_filename() @@ -1051,7 +1039,7 @@ def get_image_name(self): if not name: name = None except (AttributeError, WindowsError): -## traceback.print_exc() # XXX DEBUG + ## traceback.print_exc() # XXX DEBUG name = None # Remember the filename. @@ -1072,8 +1060,7 @@ def get_command_line_block(self): @raise WindowsError: On error an exception is raised. """ peb = self.get_peb() - pp = self.read_structure(peb.ProcessParameters, - win32.RTL_USER_PROCESS_PARAMETERS) + pp = self.read_structure(peb.ProcessParameters, win32.RTL_USER_PROCESS_PARAMETERS) s = pp.CommandLine return (s.Buffer, s.MaximumLength) @@ -1092,8 +1079,7 @@ def get_environment_block(self): @raise WindowsError: On error an exception is raised. """ peb = self.get_peb() - pp = self.read_structure(peb.ProcessParameters, - win32.RTL_USER_PROCESS_PARAMETERS) + pp = self.read_structure(peb.ProcessParameters, win32.RTL_USER_PROCESS_PARAMETERS) Environment = pp.Environment try: EnvironmentSize = pp.EnvironmentSize @@ -1112,11 +1098,10 @@ def get_command_line(self): @raise WindowsError: On error an exception is raised. """ (Buffer, MaximumLength) = self.get_command_line_block() - CommandLine = self.peek_string(Buffer, dwMaxSize=MaximumLength, - fUnicode=True) + CommandLine = self.peek_string(Buffer, dwMaxSize=MaximumLength, fUnicode=True) gst = win32.GuessStringType if gst.t_default == gst.t_ansi: - CommandLine = CommandLine.encode('cp1252') + CommandLine = CommandLine.encode("cp1252") return CommandLine def get_environment_variables(self): @@ -1140,7 +1125,7 @@ def get_environment_variables(self): # renders garbage. # Read the environment block contents. - data = self.peek( *self.get_environment_block() ) + data = self.peek(*self.get_environment_block()) # Put them into a Unicode buffer. tmp = ctypes.create_string_buffer(data) @@ -1150,26 +1135,23 @@ def get_environment_variables(self): # Skip until the first Unicode null char is found. pos = 0 - while buffer[pos] != u'\0': + while buffer[pos] != "\0": pos += 1 pos += 1 # Loop for each environment variable... environment = [] - while buffer[pos] != u'\0': - + while buffer[pos] != "\0": # Until we find a null char... env_name_pos = pos - env_name = u'' + env_name = "" found_name = False - while buffer[pos] != u'\0': - + while buffer[pos] != "\0": # Get the current char. char = buffer[pos] # Is it an equal sign? - if char == u'=': - + if char == "=": # Skip leading equal signs. if env_name_pos == pos: env_name_pos += 1 @@ -1192,8 +1174,8 @@ def get_environment_variables(self): break # Read the variable value until we find a null char. - env_value = u'' - while buffer[pos] != u'\0': + env_value = "" + while buffer[pos] != "\0": env_value += buffer[pos] pos += 1 @@ -1201,7 +1183,7 @@ def get_environment_variables(self): pos += 1 # Add to the list of environment variables found. - environment.append( (env_name, env_value) ) + environment.append((env_name, env_value)) # Remove the last entry, it's garbage. if environment: @@ -1210,7 +1192,7 @@ def get_environment_variables(self): # Return the environment variables. return environment - def get_environment_data(self, fUnicode = None): + def get_environment_data(self, fUnicode=None): """ Retrieves the environment block data with wich the program is running. @@ -1231,21 +1213,17 @@ def get_environment_data(self, fUnicode = None): """ # Issue a deprecation warning. - warnings.warn( - "Process.get_environment_data() is deprecated" \ - " since WinAppDbg 1.5.", - DeprecationWarning) + warnings.warn("Process.get_environment_data() is deprecated" " since WinAppDbg 1.5.", DeprecationWarning) # Get the environment variables. - block = [ key + u'=' + value for (key, value) \ - in self.get_environment_variables() ] + block = [key + "=" + value for (key, value) in self.get_environment_variables()] # Convert the data to ANSI if requested. if fUnicode is None: gst = win32.GuessStringType fUnicode = gst.t_default == gst.t_unicode if not fUnicode: - block = [x.encode('cp1252') for x in block] + block = [x.encode("cp1252") for x in block] # Return the environment data. return block @@ -1267,10 +1245,7 @@ def parse_environment_data(block): """ # Issue a deprecation warning. - warnings.warn( - "Process.parse_environment_data() is deprecated" \ - " since WinAppDbg 1.5.", - DeprecationWarning) + warnings.warn("Process.parse_environment_data() is deprecated" " since WinAppDbg 1.5.", DeprecationWarning) # Create an empty environment dictionary. environment = dict() @@ -1282,19 +1257,19 @@ def parse_environment_data(block): # Prepare the tokens (ANSI or Unicode). gst = win32.GuessStringType if type(block[0]) == gst.t_ansi: - equals = '=' - terminator = '\0' + equals = "=" + terminator = "\0" else: - equals = u'=' - terminator = u'\0' + equals = "=" + terminator = "\0" # Split the blocks into key/value pairs. for chunk in block: sep = chunk.find(equals, 1) if sep < 0: -## raise Exception() - continue # corrupted environment block? - key, value = chunk[:sep], chunk[sep+1:] + ## raise Exception() + continue # corrupted environment block? + key, value = chunk[:sep], chunk[sep + 1 :] # For duplicated keys, append the value. # Values are separated using null terminators. @@ -1306,7 +1281,7 @@ def parse_environment_data(block): # Return the environment dictionary. return environment - def get_environment(self, fUnicode = None): + def get_environment(self, fUnicode=None): """ Retrieves the environment with wich the program is running. @@ -1336,23 +1311,22 @@ def get_environment(self, fUnicode = None): gst = win32.GuessStringType fUnicode = gst.t_default == gst.t_unicode if not fUnicode: - variables = [ ( key.encode('cp1252'), value.encode('cp1252') ) \ - for (key, value) in variables ] + variables = [(key.encode("cp1252"), value.encode("cp1252")) for (key, value) in variables] # Add the variables to a dictionary, concatenating duplicates. environment = dict() for key, value in variables: if key in environment: - environment[key] = environment[key] + u'\0' + value + environment[key] = environment[key] + "\0" + value else: environment[key] = value # Return the dictionary. return environment -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def search(self, pattern, minAddr = None, maxAddr = None): + def search(self, pattern, minAddr=None, maxAddr=None): """ Search for the given pattern within the process memory. @@ -1388,13 +1362,12 @@ def search(self, pattern, minAddr = None, maxAddr = None): if isinstance(pattern, str): return self.search_bytes(pattern, minAddr, maxAddr) if isinstance(pattern, compat.unicode): - return self.search_bytes(pattern.encode("utf-16le"), - minAddr, maxAddr) + return self.search_bytes(pattern.encode("utf-16le"), minAddr, maxAddr) if isinstance(pattern, Pattern): return Search.search_process(self, pattern, minAddr, maxAddr) raise TypeError("Unknown pattern type: %r" % type(pattern)) - def search_bytes(self, bytes, minAddr = None, maxAddr = None): + def search_bytes(self, bytes, minAddr=None, maxAddr=None): """ Search for the given byte pattern within the process memory. @@ -1418,10 +1391,7 @@ def search_bytes(self, bytes, minAddr = None, maxAddr = None): for addr, size, data in matches: yield addr - def search_text(self, text, encoding = "utf-16le", - caseSensitive = False, - minAddr = None, - maxAddr = None): + def search_text(self, text, encoding="utf-16le", caseSensitive=False, minAddr=None, maxAddr=None): """ Search for the given text within the process memory. @@ -1456,10 +1426,7 @@ def search_text(self, text, encoding = "utf-16le", for addr, size, data in matches: yield addr, data - def search_regexp(self, regexp, flags = 0, - minAddr = None, - maxAddr = None, - bufferPages = -1): + def search_regexp(self, regexp, flags=0, minAddr=None, maxAddr=None, bufferPages=-1): """ Search for the given regular expression within the process memory. @@ -1500,11 +1467,9 @@ def search_regexp(self, regexp, flags = 0, process memory. """ pattern = RegExpPattern(regexp, flags) - return Search.search_process(self, pattern, - minAddr, maxAddr, - bufferPages) + return Search.search_process(self, pattern, minAddr, maxAddr, bufferPages) - def search_hexa(self, hexa, minAddr = None, maxAddr = None): + def search_hexa(self, hexa, minAddr=None, maxAddr=None): """ Search for the given hexadecimal pattern within the process memory. @@ -1541,7 +1506,7 @@ def search_hexa(self, hexa, minAddr = None, maxAddr = None): for addr, size, data in matches: yield addr, data - def strings(self, minSize = 4, maxSize = 1024): + def strings(self, minSize=4, maxSize=1024): """ Extract ASCII strings from the process memory. @@ -1558,10 +1523,9 @@ def strings(self, minSize = 4, maxSize = 1024): - The size of the string. - The string. """ - return Search.extract_ascii_strings(self, minSize = minSize, - maxSize = maxSize) + return Search.extract_ascii_strings(self, minSize=minSize, maxSize=maxSize) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def __read_c_type(self, address, format, c_type): size = ctypes.sizeof(c_type) @@ -1571,7 +1535,7 @@ def __read_c_type(self, address, format, c_type): return struct.unpack(format, packed)[0] def __write_c_type(self, address, format, unpacked): - packed = struct.pack('@L', unpacked) + packed = struct.pack("@L", unpacked) self.write(address, packed) # XXX TODO @@ -1593,8 +1557,7 @@ def read(self, lpBaseAddress, nSize): @raise WindowsError: On error an exception is raised. """ - hProcess = self.get_handle( win32.PROCESS_VM_READ | - win32.PROCESS_QUERY_INFORMATION ) + hProcess = self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION) if not self.is_buffer(lpBaseAddress, nSize): raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS) data = win32.ReadProcessMemory(hProcess, lpBaseAddress, nSize) @@ -1636,7 +1599,7 @@ def read_char(self, lpBaseAddress): @raise WindowsError: On error an exception is raised. """ - return ord( self.read(lpBaseAddress, 1) ) + return ord(self.read(lpBaseAddress, 1)) def write_char(self, lpBaseAddress, char): """ @@ -1670,7 +1633,7 @@ def read_int(self, lpBaseAddress): @raise WindowsError: On error an exception is raised. """ - return self.__read_c_type(lpBaseAddress, compat.b('@l'), ctypes.c_int) + return self.__read_c_type(lpBaseAddress, compat.b("@l"), ctypes.c_int) def write_int(self, lpBaseAddress, unpackedValue): """ @@ -1688,7 +1651,7 @@ def write_int(self, lpBaseAddress, unpackedValue): @raise WindowsError: On error an exception is raised. """ - self.__write_c_type(lpBaseAddress, '@l', unpackedValue) + self.__write_c_type(lpBaseAddress, "@l", unpackedValue) def read_uint(self, lpBaseAddress): """ @@ -1704,7 +1667,7 @@ def read_uint(self, lpBaseAddress): @raise WindowsError: On error an exception is raised. """ - return self.__read_c_type(lpBaseAddress, '@L', ctypes.c_uint) + return self.__read_c_type(lpBaseAddress, "@L", ctypes.c_uint) def write_uint(self, lpBaseAddress, unpackedValue): """ @@ -1722,7 +1685,7 @@ def write_uint(self, lpBaseAddress, unpackedValue): @raise WindowsError: On error an exception is raised. """ - self.__write_c_type(lpBaseAddress, '@L', unpackedValue) + self.__write_c_type(lpBaseAddress, "@L", unpackedValue) def read_float(self, lpBaseAddress): """ @@ -1738,7 +1701,7 @@ def read_float(self, lpBaseAddress): @raise WindowsError: On error an exception is raised. """ - return self.__read_c_type(lpBaseAddress, '@f', ctypes.c_float) + return self.__read_c_type(lpBaseAddress, "@f", ctypes.c_float) def write_float(self, lpBaseAddress, unpackedValue): """ @@ -1756,7 +1719,7 @@ def write_float(self, lpBaseAddress, unpackedValue): @raise WindowsError: On error an exception is raised. """ - self.__write_c_type(lpBaseAddress, '@f', unpackedValue) + self.__write_c_type(lpBaseAddress, "@f", unpackedValue) def read_double(self, lpBaseAddress): """ @@ -1772,7 +1735,7 @@ def read_double(self, lpBaseAddress): @raise WindowsError: On error an exception is raised. """ - return self.__read_c_type(lpBaseAddress, '@d', ctypes.c_double) + return self.__read_c_type(lpBaseAddress, "@d", ctypes.c_double) def write_double(self, lpBaseAddress, unpackedValue): """ @@ -1790,7 +1753,7 @@ def write_double(self, lpBaseAddress, unpackedValue): @raise WindowsError: On error an exception is raised. """ - self.__write_c_type(lpBaseAddress, '@d', unpackedValue) + self.__write_c_type(lpBaseAddress, "@d", unpackedValue) def read_pointer(self, lpBaseAddress): """ @@ -1806,7 +1769,7 @@ def read_pointer(self, lpBaseAddress): @raise WindowsError: On error an exception is raised. """ - return self.__read_c_type(lpBaseAddress, '@P', ctypes.c_void_p) + return self.__read_c_type(lpBaseAddress, "@P", ctypes.c_void_p) def write_pointer(self, lpBaseAddress, unpackedValue): """ @@ -1824,7 +1787,7 @@ def write_pointer(self, lpBaseAddress, unpackedValue): @raise WindowsError: On error an exception is raised. """ - self.__write_c_type(lpBaseAddress, '@P', unpackedValue) + self.__write_c_type(lpBaseAddress, "@P", unpackedValue) def read_dword(self, lpBaseAddress): """ @@ -1840,7 +1803,7 @@ def read_dword(self, lpBaseAddress): @raise WindowsError: On error an exception is raised. """ - return self.__read_c_type(lpBaseAddress, '=L', win32.DWORD) + return self.__read_c_type(lpBaseAddress, "=L", win32.DWORD) def write_dword(self, lpBaseAddress, unpackedValue): """ @@ -1858,7 +1821,7 @@ def write_dword(self, lpBaseAddress, unpackedValue): @raise WindowsError: On error an exception is raised. """ - self.__write_c_type(lpBaseAddress, '=L', unpackedValue) + self.__write_c_type(lpBaseAddress, "=L", unpackedValue) def read_qword(self, lpBaseAddress): """ @@ -1874,7 +1837,7 @@ def read_qword(self, lpBaseAddress): @raise WindowsError: On error an exception is raised. """ - return self.__read_c_type(lpBaseAddress, '=Q', win32.QWORD) + return self.__read_c_type(lpBaseAddress, "=Q", win32.QWORD) def write_qword(self, lpBaseAddress, unpackedValue): """ @@ -1892,7 +1855,7 @@ def write_qword(self, lpBaseAddress, unpackedValue): @raise WindowsError: On error an exception is raised. """ - self.__write_c_type(lpBaseAddress, '=Q', unpackedValue) + self.__write_c_type(lpBaseAddress, "=Q", unpackedValue) def read_structure(self, lpBaseAddress, stype): """ @@ -1916,36 +1879,36 @@ def read_structure(self, lpBaseAddress, stype): lpBaseAddress = ctypes.cast(lpBaseAddress, ctypes.c_void_p) data = self.read(lpBaseAddress, ctypes.sizeof(stype)) buff = ctypes.create_string_buffer(data) - ptr = ctypes.cast(ctypes.pointer(buff), ctypes.POINTER(stype)) + ptr = ctypes.cast(ctypes.pointer(buff), ctypes.POINTER(stype)) return ptr.contents -# XXX TODO -## def write_structure(self, lpBaseAddress, sStructure): -## """ -## Writes a ctypes structure into the memory of the process. -## -## @note: Page permissions may be changed temporarily while writing. -## -## @see: L{write} -## -## @type lpBaseAddress: int -## @param lpBaseAddress: Memory address to begin writing. -## -## @type sStructure: ctypes.Structure or a subclass' instance. -## @param sStructure: Structure definition. -## -## @rtype: int -## @return: Structure instance filled in with data -## read from the process memory. -## -## @raise WindowsError: On error an exception is raised. -## """ -## size = ctypes.sizeof(sStructure) -## data = ctypes.create_string_buffer("", size = size) -## win32.CopyMemory(ctypes.byref(data), ctypes.byref(sStructure), size) -## self.write(lpBaseAddress, data.raw) - - def read_string(self, lpBaseAddress, nChars, fUnicode = False): + # XXX TODO + ## def write_structure(self, lpBaseAddress, sStructure): + ## """ + ## Writes a ctypes structure into the memory of the process. + ## + ## @note: Page permissions may be changed temporarily while writing. + ## + ## @see: L{write} + ## + ## @type lpBaseAddress: int + ## @param lpBaseAddress: Memory address to begin writing. + ## + ## @type sStructure: ctypes.Structure or a subclass' instance. + ## @param sStructure: Structure definition. + ## + ## @rtype: int + ## @return: Structure instance filled in with data + ## read from the process memory. + ## + ## @raise WindowsError: On error an exception is raised. + ## """ + ## size = ctypes.sizeof(sStructure) + ## data = ctypes.create_string_buffer("", size = size) + ## win32.CopyMemory(ctypes.byref(data), ctypes.byref(sStructure), size) + ## self.write(lpBaseAddress, data.raw) + + def read_string(self, lpBaseAddress, nChars, fUnicode=False): """ Reads an ASCII or Unicode string from the address space of the process. @@ -1972,23 +1935,23 @@ def read_string(self, lpBaseAddress, nChars, fUnicode = False): nChars = nChars * 2 szString = self.read(lpBaseAddress, nChars) if fUnicode: - szString = compat.unicode(szString, 'U16', 'ignore') + szString = compat.unicode(szString, "U16", "ignore") return szString -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # FIXME this won't work properly with a different endianness! def __peek_c_type(self, address, format, c_type): size = ctypes.sizeof(c_type) packed = self.peek(address, size) if len(packed) < size: - packed = '\0' * (size - len(packed)) + packed + packed = "\0" * (size - len(packed)) + packed elif len(packed) > size: packed = packed[:size] return struct.unpack(format, packed)[0] def __poke_c_type(self, address, format, unpacked): - packed = struct.pack('@L', unpacked) + packed = struct.pack("@L", unpacked) return self.poke(address, packed) def peek(self, lpBaseAddress, nSize): @@ -2011,25 +1974,20 @@ def peek(self, lpBaseAddress, nSize): # + Maybe change page permissions before trying to read? # + Maybe use mquery instead of get_memory_map? # (less syscalls if we break out of the loop earlier) - data = '' + data = "" if nSize > 0: try: - hProcess = self.get_handle( win32.PROCESS_VM_READ | - win32.PROCESS_QUERY_INFORMATION ) - for mbi in self.get_memory_map(lpBaseAddress, - lpBaseAddress + nSize): + hProcess = self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION) + for mbi in self.get_memory_map(lpBaseAddress, lpBaseAddress + nSize): if not mbi.is_readable(): nSize = mbi.BaseAddress - lpBaseAddress break if nSize > 0: - data = win32.ReadProcessMemory( - hProcess, lpBaseAddress, nSize) + data = win32.ReadProcessMemory(hProcess, lpBaseAddress, nSize) except WindowsError: e = sys.exc_info()[1] msg = "Error reading process %d address %s: %s" - msg %= (self.get_pid(), - HexDump.address(lpBaseAddress), - e.strerror) + msg %= (self.get_pid(), HexDump.address(lpBaseAddress), e.strerror) warnings.warn(msg) return data @@ -2052,9 +2010,7 @@ def poke(self, lpBaseAddress, lpBuffer): May be less than the number of bytes to write. """ assert isinstance(lpBuffer, compat.bytes) - hProcess = self.get_handle( win32.PROCESS_VM_WRITE | - win32.PROCESS_VM_OPERATION | - win32.PROCESS_QUERY_INFORMATION ) + hProcess = self.get_handle(win32.PROCESS_VM_WRITE | win32.PROCESS_VM_OPERATION | win32.PROCESS_QUERY_INFORMATION) mbi = self.mquery(lpBaseAddress) if not mbi.has_content(): raise ctypes.WinError(win32.ERROR_INVALID_ADDRESS) @@ -2071,11 +2027,8 @@ def poke(self, lpBaseAddress, lpBuffer): self.mprotect(lpBaseAddress, len(lpBuffer), prot) except Exception: prot = None - msg = ("Failed to adjust page permissions" - " for process %s at address %s: %s") - msg = msg % (self.get_pid(), - HexDump.address(lpBaseAddress, self.get_bits()), - traceback.format_exc()) + msg = "Failed to adjust page permissions" " for process %s at address %s: %s" + msg = msg % (self.get_pid(), HexDump.address(lpBaseAddress, self.get_bits()), traceback.format_exc()) warnings.warn(msg, RuntimeWarning) try: r = win32.WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer) @@ -2135,7 +2088,7 @@ def peek_int(self, lpBaseAddress): @return: Integer value read from the process memory. Returns zero on error. """ - return self.__peek_c_type(lpBaseAddress, '@l', ctypes.c_int) + return self.__peek_c_type(lpBaseAddress, "@l", ctypes.c_int) def poke_int(self, lpBaseAddress, unpackedValue): """ @@ -2155,7 +2108,7 @@ def poke_int(self, lpBaseAddress, unpackedValue): @return: Number of bytes written. May be less than the number of bytes to write. """ - return self.__poke_c_type(lpBaseAddress, '@l', unpackedValue) + return self.__poke_c_type(lpBaseAddress, "@l", unpackedValue) def peek_uint(self, lpBaseAddress): """ @@ -2170,7 +2123,7 @@ def peek_uint(self, lpBaseAddress): @return: Integer value read from the process memory. Returns zero on error. """ - return self.__peek_c_type(lpBaseAddress, '@L', ctypes.c_uint) + return self.__peek_c_type(lpBaseAddress, "@L", ctypes.c_uint) def poke_uint(self, lpBaseAddress, unpackedValue): """ @@ -2190,7 +2143,7 @@ def poke_uint(self, lpBaseAddress, unpackedValue): @return: Number of bytes written. May be less than the number of bytes to write. """ - return self.__poke_c_type(lpBaseAddress, '@L', unpackedValue) + return self.__poke_c_type(lpBaseAddress, "@L", unpackedValue) def peek_float(self, lpBaseAddress): """ @@ -2205,7 +2158,7 @@ def peek_float(self, lpBaseAddress): @return: Integer value read from the process memory. Returns zero on error. """ - return self.__peek_c_type(lpBaseAddress, '@f', ctypes.c_float) + return self.__peek_c_type(lpBaseAddress, "@f", ctypes.c_float) def poke_float(self, lpBaseAddress, unpackedValue): """ @@ -2225,7 +2178,7 @@ def poke_float(self, lpBaseAddress, unpackedValue): @return: Number of bytes written. May be less than the number of bytes to write. """ - return self.__poke_c_type(lpBaseAddress, '@f', unpackedValue) + return self.__poke_c_type(lpBaseAddress, "@f", unpackedValue) def peek_double(self, lpBaseAddress): """ @@ -2240,7 +2193,7 @@ def peek_double(self, lpBaseAddress): @return: Integer value read from the process memory. Returns zero on error. """ - return self.__peek_c_type(lpBaseAddress, '@d', ctypes.c_double) + return self.__peek_c_type(lpBaseAddress, "@d", ctypes.c_double) def poke_double(self, lpBaseAddress, unpackedValue): """ @@ -2260,7 +2213,7 @@ def poke_double(self, lpBaseAddress, unpackedValue): @return: Number of bytes written. May be less than the number of bytes to write. """ - return self.__poke_c_type(lpBaseAddress, '@d', unpackedValue) + return self.__poke_c_type(lpBaseAddress, "@d", unpackedValue) def peek_dword(self, lpBaseAddress): """ @@ -2275,7 +2228,7 @@ def peek_dword(self, lpBaseAddress): @return: Integer value read from the process memory. Returns zero on error. """ - return self.__peek_c_type(lpBaseAddress, '=L', win32.DWORD) + return self.__peek_c_type(lpBaseAddress, "=L", win32.DWORD) def poke_dword(self, lpBaseAddress, unpackedValue): """ @@ -2295,7 +2248,7 @@ def poke_dword(self, lpBaseAddress, unpackedValue): @return: Number of bytes written. May be less than the number of bytes to write. """ - return self.__poke_c_type(lpBaseAddress, '=L', unpackedValue) + return self.__poke_c_type(lpBaseAddress, "=L", unpackedValue) def peek_qword(self, lpBaseAddress): """ @@ -2310,7 +2263,7 @@ def peek_qword(self, lpBaseAddress): @return: Integer value read from the process memory. Returns zero on error. """ - return self.__peek_c_type(lpBaseAddress, '=Q', win32.QWORD) + return self.__peek_c_type(lpBaseAddress, "=Q", win32.QWORD) def poke_qword(self, lpBaseAddress, unpackedValue): """ @@ -2330,7 +2283,7 @@ def poke_qword(self, lpBaseAddress, unpackedValue): @return: Number of bytes written. May be less than the number of bytes to write. """ - return self.__poke_c_type(lpBaseAddress, '=Q', unpackedValue) + return self.__poke_c_type(lpBaseAddress, "=Q", unpackedValue) def peek_pointer(self, lpBaseAddress): """ @@ -2345,7 +2298,7 @@ def peek_pointer(self, lpBaseAddress): @return: Pointer value read from the process memory. Returns zero on error. """ - return self.__peek_c_type(lpBaseAddress, '@P', ctypes.c_void_p) + return self.__peek_c_type(lpBaseAddress, "@P", ctypes.c_void_p) def poke_pointer(self, lpBaseAddress, unpackedValue): """ @@ -2365,9 +2318,9 @@ def poke_pointer(self, lpBaseAddress, unpackedValue): @return: Number of bytes written. May be less than the number of bytes to write. """ - return self.__poke_c_type(lpBaseAddress, '@P', unpackedValue) + return self.__poke_c_type(lpBaseAddress, "@P", unpackedValue) - def peek_string(self, lpBaseAddress, fUnicode = False, dwMaxSize = 0x1000): + def peek_string(self, lpBaseAddress, fUnicode=False, dwMaxSize=0x1000): """ Tries to read an ASCII or Unicode string from the address space of the process. @@ -2393,8 +2346,8 @@ def peek_string(self, lpBaseAddress, fUnicode = False, dwMaxSize = 0x1000): # Validate the parameters. if not lpBaseAddress or dwMaxSize == 0: if fUnicode: - return u'' - return '' + return "" + return "" if not dwMaxSize: dwMaxSize = 0x1000 @@ -2403,31 +2356,29 @@ def peek_string(self, lpBaseAddress, fUnicode = False, dwMaxSize = 0x1000): # If the string is Unicode... if fUnicode: - # Decode the string. - szString = compat.unicode(szString, 'U16', 'replace') -## try: -## szString = compat.unicode(szString, 'U16') -## except UnicodeDecodeError: -## szString = struct.unpack('H' * (len(szString) / 2), szString) -## szString = [ unichr(c) for c in szString ] -## szString = u''.join(szString) + szString = compat.unicode(szString, "U16", "replace") + ## try: + ## szString = compat.unicode(szString, 'U16') + ## except UnicodeDecodeError: + ## szString = struct.unpack('H' * (len(szString) / 2), szString) + ## szString = [ unichr(c) for c in szString ] + ## szString = u''.join(szString) # Truncate the string when the first null char is found. - szString = szString[ : szString.find(u'\0') ] + szString = szString[: szString.find("\0")] # If the string is ANSI... else: - # Truncate the string when the first null char is found. - szString = szString[ : szString.find('\0') ] + szString = szString[: szString.find("\0")] # Return the decoded string. return szString # TODO # try to avoid reading the same page twice by caching it - def peek_pointers_in_data(self, data, peekSize = 16, peekStep = 1): + def peek_pointers_in_data(self, data, peekSize=16, peekStep=1): """ Tries to guess which values in the given data are valid pointers, and reads some data from them. @@ -2452,23 +2403,23 @@ def peek_pointers_in_data(self, data, peekSize = 16, peekStep = 1): result = dict() ptrSize = win32.sizeof(win32.LPVOID) if ptrSize == 4: - ptrFmt = ' 0: for i in compat.xrange(0, len(data), peekStep): - packed = data[i:i+ptrSize] + packed = data[i : i + ptrSize] if len(packed) == ptrSize: - address = struct.unpack(ptrFmt, packed)[0] -## if not address & (~0xFFFF): continue - peek_data = self.peek(address, peekSize) + address = struct.unpack(ptrFmt, packed)[0] + ## if not address & (~0xFFFF): continue + peek_data = self.peek(address, peekSize) if peek_data: result[i] = peek_data return result -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def malloc(self, dwSize, lpAddress = None): + def malloc(self, dwSize, lpAddress=None): """ Allocates memory into the address space of the process. @@ -2547,7 +2498,7 @@ def free(self, lpAddress): hProcess = self.get_handle(win32.PROCESS_VM_OPERATION) win32.VirtualFreeEx(hProcess, lpAddress) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def is_pointer(self, address): """ @@ -3031,7 +2982,7 @@ def is_buffer_executable_and_writeable(self, address, size): size = size - mbi.RegionSize return True - def get_memory_map(self, minAddr = None, maxAddr = None): + def get_memory_map(self, minAddr=None, maxAddr=None): """ Produces a memory map to the process address space. @@ -3050,7 +3001,7 @@ def get_memory_map(self, minAddr = None, maxAddr = None): """ return list(self.iter_memory_map(minAddr, maxAddr)) - def generate_memory_map(self, minAddr = None, maxAddr = None): + def generate_memory_map(self, minAddr=None, maxAddr=None): """ Returns a L{Regenerator} that can iterate indefinitely over the memory map to the process address space. @@ -3070,7 +3021,7 @@ def generate_memory_map(self, minAddr = None, maxAddr = None): """ return Regenerator(self.iter_memory_map, minAddr, maxAddr) - def iter_memory_map(self, minAddr = None, maxAddr = None): + def iter_memory_map(self, minAddr=None, maxAddr=None): """ Produces an iterator over the memory map to the process address space. @@ -3087,8 +3038,8 @@ def iter_memory_map(self, minAddr = None, maxAddr = None): @rtype: iterator of L{win32.MemoryBasicInformation} @return: List of memory region information objects. """ - minAddr, maxAddr = MemoryAddresses.align_address_range(minAddr,maxAddr) - prevAddr = minAddr - 1 + minAddr, maxAddr = MemoryAddresses.align_address_range(minAddr, maxAddr) + prevAddr = minAddr - 1 currentAddr = minAddr while prevAddr < currentAddr < maxAddr: try: @@ -3099,10 +3050,10 @@ def iter_memory_map(self, minAddr = None, maxAddr = None): break raise yield mbi - prevAddr = currentAddr + prevAddr = currentAddr currentAddr = mbi.BaseAddress + mbi.RegionSize - def get_mapped_filenames(self, memoryMap = None): + def get_mapped_filenames(self, memoryMap=None): """ Retrieves the filenames for memory mapped files in the debugee. @@ -3114,8 +3065,7 @@ def get_mapped_filenames(self, memoryMap = None): @return: Dictionary mapping memory addresses to file names. Native filenames are converted to Win32 filenames when possible. """ - hProcess = self.get_handle( win32.PROCESS_VM_READ | - win32.PROCESS_QUERY_INFORMATION ) + hProcess = self.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION) if not memoryMap: memoryMap = self.get_memory_map() mappedFilenames = dict() @@ -3123,24 +3073,24 @@ def get_mapped_filenames(self, memoryMap = None): if mbi.Type not in (win32.MEM_IMAGE, win32.MEM_MAPPED): continue baseAddress = mbi.BaseAddress - fileName = "" + fileName = "" try: fileName = win32.GetMappedFileName(hProcess, baseAddress) fileName = PathOperations.native_to_win32_pathname(fileName) except WindowsError: - #e = sys.exc_info()[1] - #try: + # e = sys.exc_info()[1] + # try: # msg = "Can't get mapped file name at address %s in process " \ # "%d, reason: %s" % (HexDump.address(baseAddress), # self.get_pid(), # e.strerror) # warnings.warn(msg, Warning) - #except Exception: + # except Exception: pass mappedFilenames[baseAddress] = fileName return mappedFilenames - def generate_memory_snapshot(self, minAddr = None, maxAddr = None): + def generate_memory_snapshot(self, minAddr=None, maxAddr=None): """ Returns a L{Regenerator} that allows you to iterate through the memory contents of a process indefinitely. @@ -3185,7 +3135,7 @@ def generate_memory_snapshot(self, minAddr = None, maxAddr = None): """ return Regenerator(self.iter_memory_snapshot, minAddr, maxAddr) - def iter_memory_snapshot(self, minAddr = None, maxAddr = None): + def iter_memory_snapshot(self, minAddr=None, maxAddr=None): """ Returns an iterator that allows you to go through the memory contents of a process. @@ -3257,7 +3207,7 @@ def iter_memory_snapshot(self, minAddr = None, maxAddr = None): minAddr = MemoryAddresses.align_address_to_page_start(minAddr) mbi = memory[0] if mbi.BaseAddress < minAddr: - mbi.RegionSize = mbi.BaseAddress + mbi.RegionSize - minAddr + mbi.RegionSize = mbi.BaseAddress + mbi.RegionSize - minAddr mbi.BaseAddress = minAddr # Trim the last memory information block if needed. @@ -3270,7 +3220,7 @@ def iter_memory_snapshot(self, minAddr = None, maxAddr = None): # Read the contents of each block and yield it. while memory: - mbi = memory.pop(0) # so the garbage collector can take it + mbi = memory.pop(0) # so the garbage collector can take it mbi.filename = filenames.get(mbi.BaseAddress, None) if mbi.has_content(): mbi.content = self.read(mbi.BaseAddress, mbi.RegionSize) @@ -3278,7 +3228,7 @@ def iter_memory_snapshot(self, minAddr = None, maxAddr = None): mbi.content = None yield mbi - def take_memory_snapshot(self, minAddr = None, maxAddr = None): + def take_memory_snapshot(self, minAddr=None, maxAddr=None): """ Takes a snapshot of the memory contents of the process. @@ -3316,11 +3266,9 @@ def take_memory_snapshot(self, minAddr = None, maxAddr = None): - C{filename}: Mapped filename, or C{None}. - C{content}: Memory contents, or C{None}. """ - return list( self.iter_memory_snapshot(minAddr, maxAddr) ) + return list(self.iter_memory_snapshot(minAddr, maxAddr)) - def restore_memory_snapshot(self, snapshot, - bSkipMappedFiles = True, - bSkipOnError = False): + def restore_memory_snapshot(self, snapshot, bSkipMappedFiles=True, bSkipOnError=False): """ Attempts to restore the memory state as it was when the given snapshot was taken. @@ -3352,42 +3300,34 @@ def restore_memory_snapshot(self, snapshot, @raise RuntimeError: An error occured while restoring the snapshot. @raise TypeError: A snapshot of the wrong type was passed. """ - if not snapshot or not isinstance(snapshot, list) \ - or not isinstance(snapshot[0], win32.MemoryBasicInformation): - raise TypeError( "Only snapshots returned by " \ - "take_memory_snapshot() can be used here." ) + if not snapshot or not isinstance(snapshot, list) or not isinstance(snapshot[0], win32.MemoryBasicInformation): + raise TypeError("Only snapshots returned by " "take_memory_snapshot() can be used here.") # Get the process handle. - hProcess = self.get_handle( win32.PROCESS_VM_WRITE | - win32.PROCESS_VM_OPERATION | - win32.PROCESS_SUSPEND_RESUME | - win32.PROCESS_QUERY_INFORMATION ) + hProcess = self.get_handle( + win32.PROCESS_VM_WRITE | win32.PROCESS_VM_OPERATION | win32.PROCESS_SUSPEND_RESUME | win32.PROCESS_QUERY_INFORMATION + ) # Freeze the process. self.suspend() try: - # For each memory region in the snapshot... for old_mbi in snapshot: - # If the region matches, restore it directly. new_mbi = self.mquery(old_mbi.BaseAddress) - if new_mbi.BaseAddress == old_mbi.BaseAddress and \ - new_mbi.RegionSize == old_mbi.RegionSize: - self.__restore_mbi(hProcess, new_mbi, old_mbi, - bSkipMappedFiles) + if new_mbi.BaseAddress == old_mbi.BaseAddress and new_mbi.RegionSize == old_mbi.RegionSize: + self.__restore_mbi(hProcess, new_mbi, old_mbi, bSkipMappedFiles) # If the region doesn't match, restore it page by page. else: - # We need a copy so we don't corrupt the snapshot. old_mbi = win32.MemoryBasicInformation(old_mbi) # Get the overlapping range of pages. old_start = old_mbi.BaseAddress - old_end = old_start + old_mbi.RegionSize + old_end = old_start + old_mbi.RegionSize new_start = new_mbi.BaseAddress - new_end = new_start + new_mbi.RegionSize + new_end = new_start + new_mbi.RegionSize if old_start > new_start: start = old_start else: @@ -3405,114 +3345,83 @@ def restore_memory_snapshot(self, snapshot, while address < end: old_mbi.BaseAddress = address new_mbi.BaseAddress = address - self.__restore_mbi(hProcess, new_mbi, old_mbi, - bSkipMappedFiles, bSkipOnError) + self.__restore_mbi(hProcess, new_mbi, old_mbi, bSkipMappedFiles, bSkipOnError) address = address + step # Resume execution. finally: self.resume() - def __restore_mbi(self, hProcess, new_mbi, old_mbi, bSkipMappedFiles, - bSkipOnError): + def __restore_mbi(self, hProcess, new_mbi, old_mbi, bSkipMappedFiles, bSkipOnError): """ Used internally by L{restore_memory_snapshot}. """ -## print "Restoring %s-%s" % ( -## HexDump.address(old_mbi.BaseAddress, self.get_bits()), -## HexDump.address(old_mbi.BaseAddress + old_mbi.RegionSize, -## self.get_bits())) + ## print "Restoring %s-%s" % ( + ## HexDump.address(old_mbi.BaseAddress, self.get_bits()), + ## HexDump.address(old_mbi.BaseAddress + old_mbi.RegionSize, + ## self.get_bits())) try: - # Restore the region state. if new_mbi.State != old_mbi.State: if new_mbi.is_free(): if old_mbi.is_reserved(): - # Free -> Reserved - address = win32.VirtualAllocEx(hProcess, - old_mbi.BaseAddress, - old_mbi.RegionSize, - win32.MEM_RESERVE, - old_mbi.Protect) + address = win32.VirtualAllocEx( + hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RESERVE, old_mbi.Protect + ) if address != old_mbi.BaseAddress: self.free(address) msg = "Error restoring region at address %s" - msg = msg % HexDump(old_mbi.BaseAddress, - self.get_bits()) + msg = msg % HexDump(old_mbi.BaseAddress, self.get_bits()) raise RuntimeError(msg) # permissions already restored new_mbi.Protect = old_mbi.Protect - else: # elif old_mbi.is_commited(): - + else: # elif old_mbi.is_commited(): # Free -> Commited - address = win32.VirtualAllocEx(hProcess, - old_mbi.BaseAddress, - old_mbi.RegionSize, - win32.MEM_RESERVE | \ - win32.MEM_COMMIT, - old_mbi.Protect) + address = win32.VirtualAllocEx( + hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RESERVE | win32.MEM_COMMIT, old_mbi.Protect + ) if address != old_mbi.BaseAddress: self.free(address) msg = "Error restoring region at address %s" - msg = msg % HexDump(old_mbi.BaseAddress, - self.get_bits()) + msg = msg % HexDump(old_mbi.BaseAddress, self.get_bits()) raise RuntimeError(msg) # permissions already restored new_mbi.Protect = old_mbi.Protect elif new_mbi.is_reserved(): if old_mbi.is_commited(): - # Reserved -> Commited - address = win32.VirtualAllocEx(hProcess, - old_mbi.BaseAddress, - old_mbi.RegionSize, - win32.MEM_COMMIT, - old_mbi.Protect) + address = win32.VirtualAllocEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_COMMIT, old_mbi.Protect) if address != old_mbi.BaseAddress: self.free(address) msg = "Error restoring region at address %s" - msg = msg % HexDump(old_mbi.BaseAddress, - self.get_bits()) + msg = msg % HexDump(old_mbi.BaseAddress, self.get_bits()) raise RuntimeError(msg) # permissions already restored new_mbi.Protect = old_mbi.Protect - else: # elif old_mbi.is_free(): - + else: # elif old_mbi.is_free(): # Reserved -> Free - win32.VirtualFreeEx(hProcess, - old_mbi.BaseAddress, - old_mbi.RegionSize, - win32.MEM_RELEASE) + win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_RELEASE) - else: # elif new_mbi.is_commited(): + else: # elif new_mbi.is_commited(): if old_mbi.is_reserved(): - # Commited -> Reserved - win32.VirtualFreeEx(hProcess, - old_mbi.BaseAddress, - old_mbi.RegionSize, - win32.MEM_DECOMMIT) - - else: # elif old_mbi.is_free(): + win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_DECOMMIT) + else: # elif old_mbi.is_free(): # Commited -> Free - win32.VirtualFreeEx(hProcess, - old_mbi.BaseAddress, - old_mbi.RegionSize, - win32.MEM_DECOMMIT | win32.MEM_RELEASE) + win32.VirtualFreeEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, win32.MEM_DECOMMIT | win32.MEM_RELEASE) new_mbi.State = old_mbi.State # Restore the region permissions. if old_mbi.is_commited() and old_mbi.Protect != new_mbi.Protect: - win32.VirtualProtectEx(hProcess, old_mbi.BaseAddress, - old_mbi.RegionSize, old_mbi.Protect) + win32.VirtualProtectEx(hProcess, old_mbi.BaseAddress, old_mbi.RegionSize, old_mbi.Protect) new_mbi.Protect = old_mbi.Protect # Restore the region data. @@ -3530,14 +3439,12 @@ def __restore_mbi(self, hProcess, new_mbi, old_mbi, bSkipMappedFiles, if not bSkipOnError: raise msg = "Error restoring region at address %s: %s" - msg = msg % ( - HexDump(old_mbi.BaseAddress, self.get_bits()), - traceback.format_exc()) + msg = msg % (HexDump(old_mbi.BaseAddress, self.get_bits()), traceback.format_exc()) warnings.warn(msg, RuntimeWarning) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def inject_code(self, payload, lpParameter = 0): + def inject_code(self, payload, lpParameter=0): """ Injects relocatable code into the process memory and executes it. @@ -3560,20 +3467,18 @@ def inject_code(self, payload, lpParameter = 0): """ # Uncomment for debugging... -## payload = '\xCC' + payload + ## payload = '\xCC' + payload # Allocate the memory for the shellcode. lpStartAddress = self.malloc(len(payload)) # Catch exceptions so we can free the memory on error. try: - # Write the shellcode to our memory location. self.write(lpStartAddress, payload) # Start a new thread for the shellcode to run. - aThread = self.start_thread(lpStartAddress, lpParameter, - bSuspended = False) + aThread = self.start_thread(lpStartAddress, lpParameter, bSuspended=False) # Remember the shellcode address. # It will be freed ONLY by the Thread.kill() method @@ -3594,8 +3499,7 @@ def inject_code(self, payload, lpParameter = 0): # The shellcode should check for errors, otherwise it just crashes # when the DLL can't be loaded or the procedure can't be found. # On error the shellcode should execute an int3 instruction. - def inject_dll(self, dllname, procname = None, lpParameter = 0, - bWait = True, dwTimeout = None): + def inject_dll(self, dllname, procname=None, lpParameter=0, bWait=True, dwTimeout=None): """ Injects a DLL into the process memory. @@ -3652,13 +3556,12 @@ def inject_dll(self, dllname, procname = None, lpParameter = 0, """ # Resolve kernel32.dll - aModule = self.get_module_by_name(compat.b('kernel32.dll')) + aModule = self.get_module_by_name(compat.b("kernel32.dll")) if aModule is None: self.scan_modules() - aModule = self.get_module_by_name(compat.b('kernel32.dll')) + aModule = self.get_module_by_name(compat.b("kernel32.dll")) if aModule is None: - raise RuntimeError( - "Cannot resolve kernel32.dll in the remote process") + raise RuntimeError("Cannot resolve kernel32.dll in the remote process") # Old method, using shellcode. if procname: @@ -3667,88 +3570,81 @@ def inject_dll(self, dllname, procname = None, lpParameter = 0, dllname = compat.b(dllname) # Resolve kernel32.dll!LoadLibraryA - pllib = aModule.resolve(compat.b('LoadLibraryA')) + pllib = aModule.resolve(compat.b("LoadLibraryA")) if not pllib: - raise RuntimeError( - "Cannot resolve kernel32.dll!LoadLibraryA" - " in the remote process") + raise RuntimeError("Cannot resolve kernel32.dll!LoadLibraryA" " in the remote process") # Resolve kernel32.dll!GetProcAddress - pgpad = aModule.resolve(compat.b('GetProcAddress')) + pgpad = aModule.resolve(compat.b("GetProcAddress")) if not pgpad: - raise RuntimeError( - "Cannot resolve kernel32.dll!GetProcAddress" - " in the remote process") + raise RuntimeError("Cannot resolve kernel32.dll!GetProcAddress" " in the remote process") # Resolve kernel32.dll!VirtualFree - pvf = aModule.resolve(compat.b('VirtualFree')) + pvf = aModule.resolve(compat.b("VirtualFree")) if not pvf: - raise RuntimeError( - "Cannot resolve kernel32.dll!VirtualFree" - " in the remote process") + raise RuntimeError("Cannot resolve kernel32.dll!VirtualFree" " in the remote process") # Shellcode follows... - code = compat.b('') + code = compat.b("") # push dllname - code += compat.b('\xe8') + struct.pack('= 2 and bAllowElevation: - pi = win32.CreateProcess(None, lpCmdLine, - bInheritHandles = bInheritHandles, - dwCreationFlags = dwCreationFlags, - lpStartupInfo = lpStartupInfo) + pi = win32.CreateProcess( + None, lpCmdLine, bInheritHandles=bInheritHandles, dwCreationFlags=dwCreationFlags, lpStartupInfo=lpStartupInfo + ) # Create the process the hard way... else: - # If we allow elevation, use the current process token. # If not, get the token from the current shell process. hToken = None try: if not bAllowElevation: if bFollow: - msg = ( - "Child processes can't be autofollowed" - " when dropping UAC elevation.") + msg = "Child processes can't be autofollowed" " when dropping UAC elevation." raise NotImplementedError(msg) if bConsole: - msg = ( - "Child processes can't inherit the debugger's" - " console when dropping UAC elevation.") + msg = "Child processes can't inherit the debugger's" " console when dropping UAC elevation." raise NotImplementedError(msg) if bInheritHandles: - msg = ( - "Child processes can't inherit the debugger's" - " handles when dropping UAC elevation.") + msg = "Child processes can't inherit the debugger's" " handles when dropping UAC elevation." raise NotImplementedError(msg) try: hWnd = self.get_shell_window() @@ -4308,8 +4178,7 @@ def start_process(self, lpCmdLine, **kwargs): hWnd = self.get_desktop_window() shell = hWnd.get_process() try: - hShell = shell.get_handle( - win32.PROCESS_QUERY_INFORMATION) + hShell = shell.get_handle(win32.PROCESS_QUERY_INFORMATION) with win32.OpenProcessToken(hShell) as hShellToken: hToken = win32.DuplicateTokenEx(hShellToken) finally: @@ -4321,9 +4190,8 @@ def start_process(self, lpCmdLine, **kwargs): dwLevelId = win32.SAFER_LEVELID_NORMALUSER else: dwLevelId = win32.SAFER_LEVELID_UNTRUSTED - with win32.SaferCreateLevel(dwLevelId = dwLevelId) as hSafer: - hSaferToken = win32.SaferComputeTokenFromLevel( - hSafer, hToken)[0] + with win32.SaferCreateLevel(dwLevelId=dwLevelId) as hSafer: + hSaferToken = win32.SaferComputeTokenFromLevel(hSafer, hToken)[0] try: if hToken is not None: hToken.close() @@ -4335,11 +4203,12 @@ def start_process(self, lpCmdLine, **kwargs): # If we have a computed token, call CreateProcessAsUser(). if bAllowElevation: pi = win32.CreateProcessAsUser( - hToken = hToken, - lpCommandLine = lpCmdLine, - bInheritHandles = bInheritHandles, - dwCreationFlags = dwCreationFlags, - lpStartupInfo = lpStartupInfo) + hToken=hToken, + lpCommandLine=lpCmdLine, + bInheritHandles=bInheritHandles, + dwCreationFlags=dwCreationFlags, + lpStartupInfo=lpStartupInfo, + ) # If we have a primary token call CreateProcessWithToken(). # The problem is, there are many flags CreateProcess() and @@ -4347,7 +4216,6 @@ def start_process(self, lpCmdLine, **kwargs): # and CreateProcessWithLogonW() don't, so we need to work # around them. else: - # Remove the debug flags. dwCreationFlags &= ~win32.DEBUG_PROCESS dwCreationFlags &= ~win32.DEBUG_ONLY_THIS_PROCESS @@ -4360,11 +4228,12 @@ def start_process(self, lpCmdLine, **kwargs): # Create the process using the new primary token. pi = win32.CreateProcessWithToken( - hToken = hToken, - dwLogonFlags = win32.LOGON_WITH_PROFILE, - lpCommandLine = lpCmdLine, - dwCreationFlags = dwCreationFlags, - lpStartupInfo = lpStartupInfo) + hToken=hToken, + dwLogonFlags=win32.LOGON_WITH_PROFILE, + lpCommandLine=lpCmdLine, + dwCreationFlags=dwCreationFlags, + lpStartupInfo=lpStartupInfo, + ) # Attach as a debugger, if requested. if bDebug: @@ -4382,7 +4251,7 @@ def start_process(self, lpCmdLine, **kwargs): # Wrap the new process and thread in Process and Thread objects, # and add them to the corresponding snapshots. aProcess = Process(pi.dwProcessId, pi.hProcess) - aThread = Thread (pi.dwThreadId, pi.hThread) + aThread = Thread(pi.dwThreadId, pi.hThread) aProcess._add_thread(aThread) self._add_process(aProcess) @@ -4412,15 +4281,15 @@ def get_explorer_pid(self): except Exception: exp = None if not exp: - exp = os.getenv('SystemRoot') + exp = os.getenv("SystemRoot") if exp: - exp = os.path.join(exp, 'explorer.exe') + exp = os.path.join(exp, "explorer.exe") exp_list = self.find_processes_by_filename(exp) if exp_list: return exp_list[0][0].get_pid() return None -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # XXX this methods musn't end up calling __initialize_snapshot by accident! @@ -4441,13 +4310,11 @@ def scan(self): has_threads = True try: try: - # Try using the Toolhelp API # to scan for processes and threads. self.scan_processes_and_threads() except Exception: - # On error, try using the PSAPI to scan for process IDs only. self.scan_processes_fast() @@ -4460,7 +4327,6 @@ def scan(self): has_threads = False finally: - # Try using the Remote Desktop API to scan for processes only. # This will update the filenames when it's not possible # to obtain them from the Toolhelp API. @@ -4494,8 +4360,8 @@ def scan_processes_and_threads(self): # since this information resides in usermode space. # See: http://www.ragestorm.net/blogs/?p=163 - our_pid = win32.GetCurrentProcessId() - dead_pids = set( compat.iterkeys(self.__processDict) ) + our_pid = win32.GetCurrentProcessId() + dead_pids = set(compat.iterkeys(self.__processDict)) found_tids = set() # Ignore our own process if it's in the snapshot for some reason @@ -4503,9 +4369,8 @@ def scan_processes_and_threads(self): dead_pids.remove(our_pid) # Take a snapshot of all processes and threads - dwFlags = win32.TH32CS_SNAPPROCESS | win32.TH32CS_SNAPTHREAD + dwFlags = win32.TH32CS_SNAPPROCESS | win32.TH32CS_SNAPTHREAD with win32.CreateToolhelp32Snapshot(dwFlags) as hSnapshot: - # Add all the processes (excluding our own) pe = win32.Process32First(hSnapshot) while pe is not None: @@ -4537,7 +4402,7 @@ def scan_processes_and_threads(self): dwThreadId = te.th32ThreadID found_tids.add(dwThreadId) if not aProcess._has_thread_id(dwThreadId): - aThread = Thread(dwThreadId, process = aProcess) + aThread = Thread(dwThreadId, process=aProcess) aProcess._add_thread(aThread) te = win32.Thread32Next(hSnapshot) @@ -4547,7 +4412,7 @@ def scan_processes_and_threads(self): # Remove dead threads for aProcess in compat.itervalues(self.__processDict): - dead_tids = set( aProcess._get_thread_ids() ) + dead_tids = set(aProcess._get_thread_ids()) dead_tids.difference_update(found_tids) for tid in dead_tids: aProcess._del_thread(tid) @@ -4597,8 +4462,8 @@ def scan_processes(self): # Get the previous list of PIDs. # We'll be removing live PIDs from it as we find them. - our_pid = win32.GetCurrentProcessId() - dead_pids = set( compat.iterkeys(self.__processDict) ) + our_pid = win32.GetCurrentProcessId() + dead_pids = set(compat.iterkeys(self.__processDict)) # Ignore our own PID. if our_pid in dead_pids: @@ -4607,16 +4472,15 @@ def scan_processes(self): # Get the list of processes from the Remote Desktop API. pProcessInfo = None try: - pProcessInfo, dwCount = win32.WTSEnumerateProcesses( - win32.WTS_CURRENT_SERVER_HANDLE) + pProcessInfo, dwCount = win32.WTSEnumerateProcesses(win32.WTS_CURRENT_SERVER_HANDLE) # For each process found... for index in compat.xrange(dwCount): sProcessInfo = pProcessInfo[index] -## # Ignore processes belonging to other sessions. -## if sProcessInfo.SessionId != win32.WTS_CURRENT_SESSION: -## continue + ## # Ignore processes belonging to other sessions. + ## if sProcessInfo.SessionId != win32.WTS_CURRENT_SESSION: + ## continue # Ignore our own PID. pid = sProcessInfo.ProcessId @@ -4634,7 +4498,7 @@ def scan_processes(self): # If the process is new, add a new Process object. if pid not in self.__processDict: - aProcess = Process(pid, fileName = fileName) + aProcess = Process(pid, fileName=fileName) self._add_process(aProcess) # If the process was already in the snapshot, and the @@ -4674,11 +4538,11 @@ def scan_processes_fast(self): """ # Get the new and old list of pids - new_pids = set( win32.EnumProcesses() ) - old_pids = set( compat.iterkeys(self.__processDict) ) + new_pids = set(win32.EnumProcesses()) + old_pids = set(compat.iterkeys(self.__processDict)) # Ignore our own pid - our_pid = win32.GetCurrentProcessId() + our_pid = win32.GetCurrentProcessId() if our_pid in new_pids: new_pids.remove(our_pid) if our_pid in old_pids: @@ -4686,7 +4550,7 @@ def scan_processes_fast(self): # Add newly found pids for pid in new_pids.difference(old_pids): - self._add_process( Process(pid) ) + self._add_process(Process(pid)) # Remove missing pids for pid in old_pids.difference(new_pids): @@ -4727,7 +4591,7 @@ def scan_process_filenames(self): complete = False return complete -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def clear_dead_processes(self): """ @@ -4787,7 +4651,7 @@ def clear_processes(self): """ Removes all L{Process}, L{Thread} and L{Module} objects in this snapshot. """ - #self.close_process_and_thread_handles() + # self.close_process_and_thread_handles() for aProcess in self.iter_processes(): aProcess.clear() self.__processDict = dict() @@ -4800,7 +4664,7 @@ def clear(self): """ self.clear_processes() -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Docs for these methods are taken from the _ThreadContainer class. @@ -4829,12 +4693,12 @@ def get_thread_count(self): count += aProcess.get_thread_count() return count - has_thread.__doc__ = _ThreadContainer.has_thread.__doc__ - get_thread.__doc__ = _ThreadContainer.get_thread.__doc__ - get_thread_ids.__doc__ = _ThreadContainer.get_thread_ids.__doc__ + has_thread.__doc__ = _ThreadContainer.has_thread.__doc__ + get_thread.__doc__ = _ThreadContainer.get_thread.__doc__ + get_thread_ids.__doc__ = _ThreadContainer.get_thread_ids.__doc__ get_thread_count.__doc__ = _ThreadContainer.get_thread_count.__doc__ -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Docs for these methods are taken from the _ModuleContainer class. @@ -4846,7 +4710,7 @@ def get_module_count(self): get_module_count.__doc__ = _ModuleContainer.get_module_count.__doc__ -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def find_modules_by_base(self, lpBaseOfDll): """ @@ -4857,7 +4721,7 @@ def find_modules_by_base(self, lpBaseOfDll): for aProcess in self.iter_processes(): if aProcess.has_module(lpBaseOfDll): aModule = aProcess.get_module(lpBaseOfDll) - found.append( (aProcess, aModule) ) + found.append((aProcess, aModule)) return found def find_modules_by_name(self, fileName): @@ -4869,7 +4733,7 @@ def find_modules_by_name(self, fileName): for aProcess in self.iter_processes(): aModule = aProcess.get_module_by_name(fileName) if aModule is not None: - found.append( (aProcess, aModule) ) + found.append((aProcess, aModule)) return found def find_modules_by_address(self, address): @@ -4881,27 +4745,27 @@ def find_modules_by_address(self, address): for aProcess in self.iter_processes(): aModule = aProcess.get_module_at_address(address) if aModule is not None: - found.append( (aProcess, aModule) ) + found.append((aProcess, aModule)) return found def __find_processes_by_filename(self, filename): """ Internally used by L{find_processes_by_filename}. """ - found = list() + found = list() filename = filename.lower() if PathOperations.path_is_absolute(filename): for aProcess in self.iter_processes(): imagename = aProcess.get_filename() if imagename and imagename.lower() == filename: - found.append( (aProcess, imagename) ) + found.append((aProcess, imagename)) else: for aProcess in self.iter_processes(): imagename = aProcess.get_filename() if imagename: imagename = PathOperations.pathname_to_filename(imagename) if imagename.lower() == filename: - found.append( (aProcess, imagename) ) + found.append((aProcess, imagename)) return found def find_processes_by_filename(self, fileName): @@ -4924,11 +4788,11 @@ def find_processes_by_filename(self, fileName): if not found: fn, ext = PathOperations.split_extension(fileName) if not ext: - fileName = '%s.exe' % fn - found = self.__find_processes_by_filename(fileName) + fileName = "%s.exe" % fn + found = self.__find_processes_by_filename(fileName) return found -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # XXX _notify_* methods should not trigger a scan @@ -4939,17 +4803,17 @@ def _add_process(self, aProcess): @type aProcess: L{Process} @param aProcess: Process object. """ -## if not isinstance(aProcess, Process): -## if hasattr(aProcess, '__class__'): -## typename = aProcess.__class__.__name__ -## else: -## typename = str(type(aProcess)) -## msg = "Expected Process, got %s instead" % typename -## raise TypeError(msg) + ## if not isinstance(aProcess, Process): + ## if hasattr(aProcess, '__class__'): + ## typename = aProcess.__class__.__name__ + ## else: + ## typename = str(type(aProcess)) + ## msg = "Expected Process, got %s instead" % typename + ## raise TypeError(msg) dwProcessId = aProcess.dwProcessId -## if dwProcessId in self.__processDict: -## msg = "Process already exists: %d" % dwProcessId -## raise KeyError(msg) + ## if dwProcessId in self.__processDict: + ## msg = "Process already exists: %d" % dwProcessId + ## raise KeyError(msg) self.__processDict[dwProcessId] = aProcess def _del_process(self, dwProcessId): @@ -4967,7 +4831,7 @@ def _del_process(self, dwProcessId): msg = "Unknown process ID %d" % dwProcessId warnings.warn(msg, RuntimeWarning) if aProcess: - aProcess.clear() # remove circular references + aProcess.clear() # remove circular references # Notify the creation of a new process. def _notify_create_process(self, event): @@ -4984,16 +4848,16 @@ def _notify_create_process(self, event): @return: C{True} to call the user-defined handle, C{False} otherwise. """ dwProcessId = event.get_pid() - dwThreadId = event.get_tid() - hProcess = event.get_process_handle() -## if not self.has_process(dwProcessId): # XXX this would trigger a scan + dwThreadId = event.get_tid() + hProcess = event.get_process_handle() + ## if not self.has_process(dwProcessId): # XXX this would trigger a scan if dwProcessId not in self.__processDict: aProcess = Process(dwProcessId, hProcess) self._add_process(aProcess) aProcess.fileName = event.get_filename() else: aProcess = self.get_process(dwProcessId) - #if hProcess != win32.INVALID_HANDLE_VALUE: + # if hProcess != win32.INVALID_HANDLE_VALUE: # aProcess.hProcess = hProcess # may have more privileges if not aProcess.fileName: fileName = event.get_filename() @@ -5015,7 +4879,7 @@ def _notify_exit_process(self, event): @return: C{True} to call the user-defined handle, C{False} otherwise. """ dwProcessId = event.get_pid() -## if self.has_process(dwProcessId): # XXX this would trigger a scan + ## if self.has_process(dwProcessId): # XXX this would trigger a scan if dwProcessId in self.__processDict: self._del_process(dwProcessId) return True diff --git a/pydevd_attach_to_process/winappdbg/registry.py b/pydevd_attach_to_process/winappdbg/registry.py index 5623b80ad..7a8b38eb3 100644 --- a/pydevd_attach_to_process/winappdbg/registry.py +++ b/pydevd_attach_to_process/winappdbg/registry.py @@ -39,7 +39,7 @@ __revision__ = "$Id$" -__all__ = ['Registry'] +__all__ = ["Registry"] import sys from winappdbg import win32 @@ -47,9 +47,10 @@ import collections import warnings -#============================================================================== +# ============================================================================== -class _RegistryContainer (object): + +class _RegistryContainer(object): """ Base class for L{Registry} and L{RegistryKey}. """ @@ -57,6 +58,7 @@ class _RegistryContainer (object): # Dummy object to detect empty arguments. class __EmptyArgument: pass + __emptyArgument = __EmptyArgument() def __init__(self): @@ -79,9 +81,11 @@ def setdefault(self, default): def __iter__(self): return compat.iterkeys(self) -#============================================================================== -class RegistryKey (_RegistryContainer): +# ============================================================================== + + +class RegistryKey(_RegistryContainer): """ Exposes a single Windows Registry key as a dictionary-like object. @@ -103,9 +107,9 @@ def __init__(self, path, handle): @param handle: Registry key handle. """ super(RegistryKey, self).__init__() - if path.endswith('\\'): + if path.endswith("\\"): path = path[:-1] - self._path = path + self._path = path self._handle = handle @property @@ -114,12 +118,12 @@ def path(self): @property def handle(self): - #if not self._handle: + # if not self._handle: # msg = "This Registry key handle has already been closed." # raise RuntimeError(msg) return self._handle - #def close(self): + # def close(self): # """ # Close the Registry key handle, freeing its resources. It cannot be # used again after calling this method. @@ -131,13 +135,13 @@ def handle(self): # """ # self.handle.close() # - #def __enter__(self): + # def __enter__(self): # """ # Compatibility with the "C{with}" Python statement. # """ # return self # - #def __exit__(self, type, value, traceback): + # def __exit__(self, type, value, traceback): # """ # Compatibility with the "C{with}" Python statement. # """ @@ -236,7 +240,7 @@ def items(self): resp = win32.RegEnumValue(handle, index) if resp is None: break - items.append( (resp[0], resp[2]) ) + items.append((resp[0], resp[2])) index += 1 return items @@ -281,11 +285,11 @@ def clear(self): win32.RegDeleteValue(handle, resp[0]) def __str__(self): - default = self[''] + default = self[""] return str(default) def __unicode__(self): - default = self[u''] + default = self[""] return compat.unicode(default) def __repr__(self): @@ -322,7 +326,7 @@ def children(self): subkey = win32.RegEnumKey(handle, index) if subkey is None: break - result.append( self.child(subkey) ) + result.append(self.child(subkey)) index += 1 return result @@ -336,7 +340,7 @@ def child(self, subkey): @rtype: L{RegistryKey} @return: Subkey. """ - path = self._path + '\\' + subkey + path = self._path + "\\" + subkey handle = win32.RegOpenKey(self.handle, subkey) return RegistryKey(path, handle) @@ -352,7 +356,8 @@ def flush(self): """ win32.RegFlushKey(self.handle) -#============================================================================== + +# ============================================================================== # TODO: possibly cache the RegistryKey objects # to avoid opening and closing handles many times on code sequences like this: @@ -372,7 +377,8 @@ def flush(self): # Apparently RegDeleteTree won't work remotely from Win7 to WinXP, and the only # solution is to recursively call RegDeleteKey. -class Registry (_RegistryContainer): + +class Registry(_RegistryContainer): """ Exposes the Windows Registry as a Python container. @@ -382,36 +388,34 @@ class Registry (_RegistryContainer): """ _hives_by_name = { - # Short names - 'HKCR' : win32.HKEY_CLASSES_ROOT, - 'HKCU' : win32.HKEY_CURRENT_USER, - 'HKLM' : win32.HKEY_LOCAL_MACHINE, - 'HKU' : win32.HKEY_USERS, - 'HKPD' : win32.HKEY_PERFORMANCE_DATA, - 'HKCC' : win32.HKEY_CURRENT_CONFIG, - + "HKCR": win32.HKEY_CLASSES_ROOT, + "HKCU": win32.HKEY_CURRENT_USER, + "HKLM": win32.HKEY_LOCAL_MACHINE, + "HKU": win32.HKEY_USERS, + "HKPD": win32.HKEY_PERFORMANCE_DATA, + "HKCC": win32.HKEY_CURRENT_CONFIG, # Long names - 'HKEY_CLASSES_ROOT' : win32.HKEY_CLASSES_ROOT, - 'HKEY_CURRENT_USER' : win32.HKEY_CURRENT_USER, - 'HKEY_LOCAL_MACHINE' : win32.HKEY_LOCAL_MACHINE, - 'HKEY_USERS' : win32.HKEY_USERS, - 'HKEY_PERFORMANCE_DATA' : win32.HKEY_PERFORMANCE_DATA, - 'HKEY_CURRENT_CONFIG' : win32.HKEY_CURRENT_CONFIG, + "HKEY_CLASSES_ROOT": win32.HKEY_CLASSES_ROOT, + "HKEY_CURRENT_USER": win32.HKEY_CURRENT_USER, + "HKEY_LOCAL_MACHINE": win32.HKEY_LOCAL_MACHINE, + "HKEY_USERS": win32.HKEY_USERS, + "HKEY_PERFORMANCE_DATA": win32.HKEY_PERFORMANCE_DATA, + "HKEY_CURRENT_CONFIG": win32.HKEY_CURRENT_CONFIG, } _hives_by_value = { - win32.HKEY_CLASSES_ROOT : 'HKEY_CLASSES_ROOT', - win32.HKEY_CURRENT_USER : 'HKEY_CURRENT_USER', - win32.HKEY_LOCAL_MACHINE : 'HKEY_LOCAL_MACHINE', - win32.HKEY_USERS : 'HKEY_USERS', - win32.HKEY_PERFORMANCE_DATA : 'HKEY_PERFORMANCE_DATA', - win32.HKEY_CURRENT_CONFIG : 'HKEY_CURRENT_CONFIG', + win32.HKEY_CLASSES_ROOT: "HKEY_CLASSES_ROOT", + win32.HKEY_CURRENT_USER: "HKEY_CURRENT_USER", + win32.HKEY_LOCAL_MACHINE: "HKEY_LOCAL_MACHINE", + win32.HKEY_USERS: "HKEY_USERS", + win32.HKEY_PERFORMANCE_DATA: "HKEY_PERFORMANCE_DATA", + win32.HKEY_CURRENT_CONFIG: "HKEY_CURRENT_CONFIG", } _hives = sorted(compat.itervalues(_hives_by_value)) - def __init__(self, machine = None): + def __init__(self, machine=None): """ Opens a local or remote registry. @@ -443,14 +447,14 @@ def _split_path(self, path): - L{win32.HKEY_PERFORMANCE_DATA} - L{win32.HKEY_CURRENT_CONFIG} """ - if '\\' in path: - p = path.find('\\') + if "\\" in path: + p = path.find("\\") hive = path[:p] - path = path[p+1:] + path = path[p + 1 :] else: hive = path path = None - handle = self._hives_by_name[ hive.upper() ] + handle = self._hives_by_name[hive.upper()] return handle, path def _parse_path(self, path): @@ -492,7 +496,7 @@ def _join_path(self, hive, subkey): """ path = self._hives_by_value[hive] if subkey: - path = path + '\\' + subkey + path = path + "\\" + subkey return path def _sanitize_path(self, path): @@ -505,7 +509,7 @@ def _sanitize_path(self, path): @rtype: str @return: Registry path. """ - return self._join_path( *self._split_path(path) ) + return self._join_path(*self._split_path(path)) def _connect_hive(self, hive): """ @@ -560,7 +564,7 @@ def __exit__(self, exc_type, exc_value, traceback): def __repr__(self): if self._machine: return '' % self._machine - return '' + return "" def __contains__(self, path): hive, subpath = self._parse_path(path) @@ -587,8 +591,7 @@ def __getitem__(self, path): def __setitem__(self, path, value): do_copy = isinstance(value, RegistryKey) - if not do_copy and not isinstance(value, str) \ - and not isinstance(value, compat.unicode): + if not do_copy and not isinstance(value, str) and not isinstance(value, compat.unicode): if isinstance(value, object): t = value.__class__.__name__ else: @@ -606,9 +609,7 @@ def __setitem__(self, path, value): def __delitem__(self, path): hive, subpath = self._parse_path(path) if not subpath: - raise TypeError( - "Are you SURE you want to wipe out an entire hive?!" - " Call win32.RegDeleteTree() directly if you must...") + raise TypeError("Are you SURE you want to wipe out an entire hive?!" " Call win32.RegDeleteTree() directly if you must...") try: win32.RegDeleteTree(hive, subpath) except WindowsError: @@ -666,7 +667,7 @@ def iterate(self, path): @raise KeyError: The specified path does not exist. """ - if path.endswith('\\'): + if path.endswith("\\"): path = path[:-1] if not self.has_key(path): raise KeyError(path) @@ -690,6 +691,6 @@ def __iterate(self, stack): subkeys = self.subkeys(path) except WindowsError: continue - prefix = path + '\\' + prefix = path + "\\" subkeys = [prefix + name for name in subkeys] stack.extendleft(subkeys) diff --git a/pydevd_attach_to_process/winappdbg/search.py b/pydevd_attach_to_process/winappdbg/search.py index 6efaea6df..de1ddebd4 100644 --- a/pydevd_attach_to_process/winappdbg/search.py +++ b/pydevd_attach_to_process/winappdbg/search.py @@ -43,14 +43,14 @@ __revision__ = "$Id$" -__all__ = [ - 'Search', - 'Pattern', - 'BytePattern', - 'TextPattern', - 'RegExpPattern', - 'HexPattern', - ] +__all__ = [ + "Search", + "Pattern", + "BytePattern", + "TextPattern", + "RegExpPattern", + "HexPattern", +] from winappdbg.textio import HexInput from winappdbg.util import StaticClass, MemoryAddresses @@ -64,9 +64,10 @@ except ImportError: import re -#============================================================================== +# ============================================================================== -class Pattern (object): + +class Pattern(object): """ Base class for search patterns. @@ -116,7 +117,7 @@ def read(self, process, address, size): """ return process.read(address, size) - def find(self, buffer, pos = None): + def find(self, buffer, pos=None): """ Searches for the pattern in the given buffer, optionally starting at the given position within the buffer. @@ -169,9 +170,11 @@ def found(self, address, size, data): """ return (address, size, data) -#------------------------------------------------------------------------------ -class BytePattern (Pattern): +# ------------------------------------------------------------------------------ + + +class BytePattern(Pattern): """ Fixed byte pattern. @@ -188,7 +191,7 @@ def __init__(self, pattern): @param pattern: Byte string to search for. """ self.pattern = str(pattern) - self.length = len(pattern) + self.length = len(pattern) def __len__(self): """ @@ -198,14 +201,16 @@ def __len__(self): """ return self.length - def find(self, buffer, pos = None): + def find(self, buffer, pos=None): return buffer.find(self.pattern, pos), self.length -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # FIXME: case insensitive compat.unicode searches are probably buggy! -class TextPattern (BytePattern): + +class TextPattern(BytePattern): """ Text pattern. @@ -223,7 +228,7 @@ class TextPattern (BytePattern): C{False} otherwise. """ - def __init__(self, text, encoding = "utf-16le", caseSensitive = False): + def __init__(self, text, encoding="utf-16le", caseSensitive=False): """ @type text: str or compat.unicode @param text: Text to search for. @@ -270,13 +275,15 @@ def found(self, address, size, data): try: data = compat.unicode(data, self.encoding) except Exception: -## traceback.print_exc() # XXX DEBUG + ## traceback.print_exc() # XXX DEBUG return None return (address, size, data) -#------------------------------------------------------------------------------ -class RegExpPattern (Pattern): +# ------------------------------------------------------------------------------ + + +class RegExpPattern(Pattern): """ Regular expression pattern. @@ -305,7 +312,7 @@ class RegExpPattern (Pattern): buffered search. """ - def __init__(self, regexp, flags = 0, maxLength = None): + def __init__(self, regexp, flags=0, maxLength=None): """ @type regexp: str @param regexp: Regular expression string. @@ -327,9 +334,9 @@ def __init__(self, regexp, flags = 0, maxLength = None): cause an exception to be raised if this pattern is used in a buffered search. """ - self.pattern = regexp - self.flags = flags - self.regexp = re.compile(regexp, flags) + self.pattern = regexp + self.flags = flags + self.regexp = re.compile(regexp, flags) self.maxLength = maxLength def __len__(self): @@ -350,8 +357,8 @@ def __len__(self): raise NotImplementedError() return self.maxLength - def find(self, buffer, pos = None): - if not pos: # make sure pos is an int + def find(self, buffer, pos=None): + if not pos: # make sure pos is an int pos = 0 match = self.regexp.search(buffer, pos) if match: @@ -359,9 +366,11 @@ def find(self, buffer, pos = None): return start, end - start return -1, 0 -#------------------------------------------------------------------------------ -class HexPattern (RegExpPattern): +# ------------------------------------------------------------------------------ + + +class HexPattern(RegExpPattern): """ Hexadecimal pattern. @@ -386,8 +395,8 @@ def __new__(cls, pattern): L{BytePattern} is created instead. That's because searching for a fixed byte pattern is faster than searching for a regular expression. """ - if '?' not in pattern: - return BytePattern( HexInput.hexadecimal(pattern) ) + if "?" not in pattern: + return BytePattern(HexInput.hexadecimal(pattern)) return object.__new__(cls, pattern) def __init__(self, hexa): @@ -406,14 +415,14 @@ def __init__(self, hexa): @type hexa: str @param hexa: Pattern to search for. """ - maxLength = len([x for x in hexa - if x in "?0123456789ABCDEFabcdef"]) / 2 - super(HexPattern, self).__init__(HexInput.pattern(hexa), - maxLength = maxLength) + maxLength = len([x for x in hexa if x in "?0123456789ABCDEFabcdef"]) / 2 + super(HexPattern, self).__init__(HexInput.pattern(hexa), maxLength=maxLength) -#============================================================================== -class Search (StaticClass): +# ============================================================================== + + +class Search(StaticClass): """ Static class to group the search functionality. @@ -426,10 +435,7 @@ class Search (StaticClass): # TODO: search non-ascii C strings @staticmethod - def search_process(process, pattern, minAddr = None, - maxAddr = None, - bufferPages = None, - overlapping = False): + def search_process(process, pattern, minAddr=None, maxAddr=None, bufferPages=None, overlapping=False): """ Search for the given pattern within the process memory. @@ -517,38 +523,35 @@ def search_process(process, pattern, minAddr = None, # Calculate the buffer size from the number of pages. if bufferPages is None: try: - size = MemoryAddresses.\ - align_address_to_page_end(len(pattern)) + page + size = MemoryAddresses.align_address_to_page_end(len(pattern)) + page except NotImplementedError: size = None elif bufferPages > 0: - size = page * (bufferPages + 1) + size = page * (bufferPages + 1) else: - size = None + size = None # Get the memory map of the process. memory_map = process.iter_memory_map(minAddr, maxAddr) # Perform search with buffering enabled. if size: - # Loop through all memory blocks containing data. - buffer = "" # buffer to hold the memory data - prev_addr = 0 # previous memory block address - last = 0 # position of the last match - delta = 0 # delta of last read address and start of buffer + buffer = "" # buffer to hold the memory data + prev_addr = 0 # previous memory block address + last = 0 # position of the last match + delta = 0 # delta of last read address and start of buffer for mbi in memory_map: - # Skip blocks with no data to search on. if not mbi.has_content(): continue # Get the address and size of this block. - address = mbi.BaseAddress # current address to search on - block_size = mbi.RegionSize # total size of the block + address = mbi.BaseAddress # current address to search on + block_size = mbi.RegionSize # total size of the block if address >= maxAddr: break - end = address + block_size # end address of the block + end = address + block_size # end address of the block # If the block is contiguous to the previous block, # coalesce the new data in the buffer. @@ -558,20 +561,17 @@ def search_process(process, pattern, minAddr = None, # If not, clear the buffer and read new data. else: buffer = read(process, address, min(size, block_size)) - last = 0 - delta = 0 + last = 0 + delta = 0 # Search for the pattern in this block. while 1: - # Yield each match of the pattern in the buffer. pos, length = find(buffer, last) while pos >= last: match_addr = address + pos - delta if minAddr <= match_addr < maxAddr: - result = pattern.found( - match_addr, length, - buffer [ pos : pos + length ] ) + result = pattern.found(match_addr, length, buffer[pos : pos + length]) if result is not None: yield result if overlapping: @@ -581,9 +581,9 @@ def search_process(process, pattern, minAddr = None, pos, length = find(buffer, last) # Advance to the next page. - address = address + page + address = address + page block_size = block_size - page - prev_addr = address + prev_addr = address # Fix the position of the last match. last = last - page @@ -591,8 +591,8 @@ def search_process(process, pattern, minAddr = None, last = 0 # Remove the first page in the buffer. - buffer = buffer[ page : ] - delta = page + buffer = buffer[page:] + delta = page # If we haven't reached the end of the block yet, # read the next page in the block and keep seaching. @@ -605,19 +605,17 @@ def search_process(process, pattern, minAddr = None, # Perform search with buffering disabled. else: - # Loop through all memory blocks containing data. for mbi in memory_map: - # Skip blocks with no data to search on. if not mbi.has_content(): continue # Get the address and size of this block. - address = mbi.BaseAddress + address = mbi.BaseAddress block_size = mbi.RegionSize if address >= maxAddr: - break; + break # Read the whole memory region. buffer = process.read(address, block_size) @@ -628,9 +626,7 @@ def search_process(process, pattern, minAddr = None, while pos >= last: match_addr = address + pos if minAddr <= match_addr < maxAddr: - result = pattern.found( - match_addr, length, - buffer [ pos : pos + length ] ) + result = pattern.found(match_addr, length, buffer[pos : pos + length]) if result is not None: yield result if overlapping: @@ -640,7 +636,7 @@ def search_process(process, pattern, minAddr = None, pos, length = find(buffer, last) @classmethod - def extract_ascii_strings(cls, process, minSize = 4, maxSize = 1024): + def extract_ascii_strings(cls, process, minSize=4, maxSize=1024): """ Extract ASCII strings from the process memory. @@ -662,4 +658,4 @@ def extract_ascii_strings(cls, process, minSize = 4, maxSize = 1024): """ regexp = r"[\s\w\!\@\#\$\%%\^\&\*\(\)\{\}\[\]\~\`\'\"\:\;\.\,\\\/\-\+\=\_\<\>]{%d,%d}\0" % (minSize, maxSize) pattern = RegExpPattern(regexp, 0, maxSize) - return cls.search_process(process, pattern, overlapping = False) + return cls.search_process(process, pattern, overlapping=False) diff --git a/pydevd_attach_to_process/winappdbg/sql.py b/pydevd_attach_to_process/winappdbg/sql.py index d97411059..50d7455aa 100644 --- a/pydevd_attach_to_process/winappdbg/sql.py +++ b/pydevd_attach_to_process/winappdbg/sql.py @@ -37,7 +37,7 @@ __revision__ = "$Id$" -__all__ = ['CrashDAO'] +__all__ = ["CrashDAO"] import sqlite3 import datetime @@ -50,46 +50,52 @@ from sqlalchemy.interfaces import PoolListener from sqlalchemy.orm import sessionmaker, deferred from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound -from sqlalchemy.types import Integer, BigInteger, Boolean, DateTime, String, \ - LargeBinary, Enum, VARCHAR +from sqlalchemy.types import Integer, BigInteger, Boolean, DateTime, String, LargeBinary, Enum, VARCHAR from sqlalchemy.sql.expression import asc, desc from crash import Crash, Marshaller, pickle, HIGHEST_PROTOCOL from textio import CrashDump import win32 -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ try: from decorator import decorator except ImportError: import functools + def decorator(w): """ The C{decorator} module was not found. You can install it from: U{http://pypi.python.org/pypi/decorator/} """ + def d(fn): @functools.wraps(fn) def x(*argv, **argd): return w(fn, *argv, **argd) + return x + return d -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ -@compiles(String, 'mysql') -@compiles(VARCHAR, 'mysql') + +@compiles(String, "mysql") +@compiles(VARCHAR, "mysql") def _compile_varchar_mysql(element, compiler, **kw): """MySQL hack to avoid the "VARCHAR requires a length" error.""" - if not element.length or element.length == 'max': + if not element.length or element.length == "max": return "TEXT" else: return compiler.visit_VARCHAR(element, **kw) -#------------------------------------------------------------------------------ -class _SQLitePatch (PoolListener): +# ------------------------------------------------------------------------------ + + +class _SQLitePatch(PoolListener): """ Used internally by L{BaseDAO}. @@ -98,6 +104,7 @@ class _SQLitePatch (PoolListener): @see: U{http://sqlite.org/foreignkeys.html} """ + def connect(dbapi_connection, connection_record): """ Called once by SQLAlchemy for each new SQLite DB-API connection. @@ -124,29 +131,28 @@ def connect(dbapi_connection, connection_record): dbapi_connection.close() raise sqlite3.Error() -#------------------------------------------------------------------------------ -class BaseDTO (object): +# ------------------------------------------------------------------------------ + + +class BaseDTO(object): """ Customized declarative base for SQLAlchemy. """ __table_args__ = { - # Don't use MyISAM in MySQL. It doesn't support ON DELETE CASCADE. - 'mysql_engine': 'InnoDB', - + "mysql_engine": "InnoDB", # Don't use BlitzDB in Drizzle. It doesn't support foreign keys. - 'drizzle_engine': 'InnoDB', - + "drizzle_engine": "InnoDB", # Collate to UTF-8. - 'mysql_charset': 'utf8', + "mysql_charset": "utf8", + } - } -BaseDTO = declarative_base(cls = BaseDTO) +BaseDTO = declarative_base(cls=BaseDTO) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # TODO: if using mssql, check it's at least SQL Server 2005 # (LIMIT and OFFSET support is required). @@ -160,7 +166,8 @@ class BaseDTO (object): # http://dev.mysql.com/doc/refman/5.1/en/optimize-table.html # http://msdn.microsoft.com/en-us/library/ms174459(v=sql.90).aspx -class BaseDAO (object): + +class BaseDAO(object): """ Data Access Object base class. @@ -187,12 +194,9 @@ class BaseDAO (object): _echo = False - _new_session = sessionmaker(autoflush = True, - autocommit = True, - expire_on_commit = True, - weak_identity_map = True) + _new_session = sessionmaker(autoflush=True, autocommit=True, expire_on_commit=True, weak_identity_map=True) - def __init__(self, url, creator = None): + def __init__(self, url, creator=None): """ Connect to the database using the given connection URL. @@ -252,34 +256,34 @@ def __init__(self, url, creator = None): # Parse the connection URL. parsed_url = URL(url) schema = parsed_url.drivername - if '+' in schema: - dialect, driver = schema.split('+') + if "+" in schema: + dialect, driver = schema.split("+") else: - dialect, driver = schema, 'base' + dialect, driver = schema, "base" dialect = dialect.strip().lower() driver = driver.strip() # Prepare the database engine arguments. - arguments = {'echo' : self._echo} - if dialect == 'sqlite': - arguments['module'] = sqlite3.dbapi2 - arguments['listeners'] = [_SQLitePatch()] + arguments = {"echo": self._echo} + if dialect == "sqlite": + arguments["module"] = sqlite3.dbapi2 + arguments["listeners"] = [_SQLitePatch()] if creator is not None: - arguments['creator'] = creator + arguments["creator"] = creator # Load the database engine. engine = create_engine(url, **arguments) # Create a new session. - session = self._new_session(bind = engine) + session = self._new_session(bind=engine) # Create the required tables if they don't exist. BaseDTO.metadata.create_all(engine) # TODO: create a dialect specific index on the "signature" column. # Set the instance properties. - self._url = parsed_url - self._driver = driver + self._url = parsed_url + self._driver = driver self._dialect = dialect self._session = session @@ -299,7 +303,7 @@ def _transactional(self, method, *argv, **argd): @raise Exception: Any exception raised by the method. """ - self._session.begin(subtransactions = True) + self._session.begin(subtransactions=True) try: result = method(self, *argv, **argd) self._session.commit() @@ -308,7 +312,9 @@ def _transactional(self, method, *argv, **argd): self._session.rollback() raise -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ + @decorator def Transactional(fn, self, *argv, **argd): @@ -319,7 +325,9 @@ def Transactional(fn, self, *argv, **argd): """ return self._transactional(fn, *argv, **argd) -#============================================================================== + +# ============================================================================== + # Generates all possible memory access flags. def _gen_valid_access_flags(): @@ -330,19 +338,17 @@ def _gen_valid_access_flags(): for a4 in ("W", "-"): f.append("%s %s%s%s" % (a1, a2, a3, a4)) return tuple(f) + + _valid_access_flags = _gen_valid_access_flags() # Enumerated types for the memory table. -n_MEM_ACCESS_ENUM = {"name" : "MEM_ACCESS_ENUM"} -n_MEM_ALLOC_ACCESS_ENUM = {"name" : "MEM_ALLOC_ACCESS_ENUM"} -MEM_ACCESS_ENUM = Enum(*_valid_access_flags, - **n_MEM_ACCESS_ENUM) -MEM_ALLOC_ACCESS_ENUM = Enum(*_valid_access_flags, - **n_MEM_ALLOC_ACCESS_ENUM) -MEM_STATE_ENUM = Enum("Reserved", "Commited", "Free", "Unknown", - name = "MEM_STATE_ENUM") -MEM_TYPE_ENUM = Enum("Image", "Mapped", "Private", "Unknown", - name = "MEM_TYPE_ENUM") +n_MEM_ACCESS_ENUM = {"name": "MEM_ACCESS_ENUM"} +n_MEM_ALLOC_ACCESS_ENUM = {"name": "MEM_ALLOC_ACCESS_ENUM"} +MEM_ACCESS_ENUM = Enum(*_valid_access_flags, **n_MEM_ACCESS_ENUM) +MEM_ALLOC_ACCESS_ENUM = Enum(*_valid_access_flags, **n_MEM_ALLOC_ACCESS_ENUM) +MEM_STATE_ENUM = Enum("Reserved", "Commited", "Free", "Unknown", name="MEM_STATE_ENUM") +MEM_TYPE_ENUM = Enum("Image", "Mapped", "Private", "Unknown", name="MEM_TYPE_ENUM") # Cleanup the namespace. del _gen_valid_access_flags @@ -350,30 +356,27 @@ def _gen_valid_access_flags(): del n_MEM_ACCESS_ENUM del n_MEM_ALLOC_ACCESS_ENUM -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ + -class MemoryDTO (BaseDTO): +class MemoryDTO(BaseDTO): """ Database mapping for memory dumps. """ # Declare the table mapping. - __tablename__ = 'memory' - id = Column(Integer, Sequence(__tablename__ + '_seq'), - primary_key = True, autoincrement = True) - crash_id = Column(Integer, ForeignKey('crashes.id', - ondelete = 'CASCADE', - onupdate = 'CASCADE'), - nullable = False) - address = Column(BigInteger, nullable = False, index = True) - size = Column(BigInteger, nullable = False) - state = Column(MEM_STATE_ENUM, nullable = False) - access = Column(MEM_ACCESS_ENUM) - type = Column(MEM_TYPE_ENUM) - alloc_base = Column(BigInteger) - alloc_access = Column(MEM_ALLOC_ACCESS_ENUM) - filename = Column(String) - content = deferred(Column(LargeBinary)) + __tablename__ = "memory" + id = Column(Integer, Sequence(__tablename__ + "_seq"), primary_key=True, autoincrement=True) + crash_id = Column(Integer, ForeignKey("crashes.id", ondelete="CASCADE", onupdate="CASCADE"), nullable=False) + address = Column(BigInteger, nullable=False, index=True) + size = Column(BigInteger, nullable=False) + state = Column(MEM_STATE_ENUM, nullable=False) + access = Column(MEM_ACCESS_ENUM) + type = Column(MEM_TYPE_ENUM) + alloc_base = Column(BigInteger) + alloc_access = Column(MEM_ALLOC_ACCESS_ENUM) + filename = Column(String) + content = deferred(Column(LargeBinary)) def __init__(self, crash_id, mbi): """ @@ -390,7 +393,7 @@ def __init__(self, crash_id, mbi): self.size = mbi.RegionSize # State (free or allocated). - if mbi.State == win32.MEM_RESERVE: + if mbi.State == win32.MEM_RESERVE: self.state = "Reserved" elif mbi.State == win32.MEM_COMMIT: self.state = "Commited" @@ -406,7 +409,7 @@ def __init__(self, crash_id, mbi): self.access = self._to_access(mbi.Protect) # Type (file mapping, executable image, or private memory). - if mbi.Type == win32.MEM_IMAGE: + if mbi.Type == win32.MEM_IMAGE: self.type = "Image" elif mbi.Type == win32.MEM_MAPPED: self.type = "Mapped" @@ -418,7 +421,7 @@ def __init__(self, crash_id, mbi): self.type = "Unknown" # Allocation info. - self.alloc_base = mbi.AllocationBase + self.alloc_base = mbi.AllocationBase if not mbi.AllocationProtect: self.alloc_access = None else: @@ -437,7 +440,7 @@ def __init__(self, crash_id, mbi): self.content = None def _to_access(self, protect): - if protect & win32.PAGE_NOACCESS: + if protect & win32.PAGE_NOACCESS: access = "--- " elif protect & win32.PAGE_READONLY: access = "R-- " @@ -455,21 +458,21 @@ def _to_access(self, protect): access = "RCX " else: access = "??? " - if protect & win32.PAGE_GUARD: + if protect & win32.PAGE_GUARD: access += "G" else: access += "-" - if protect & win32.PAGE_NOCACHE: + if protect & win32.PAGE_NOCACHE: access += "N" else: access += "-" - if protect & win32.PAGE_WRITECOMBINE: + if protect & win32.PAGE_WRITECOMBINE: access += "W" else: access += "-" return access - def toMBI(self, getMemoryDump = False): + def toMBI(self, getMemoryDump=False): """ Returns a L{win32.MemoryBasicInformation} object using the data retrieved from the database. @@ -483,10 +486,10 @@ def toMBI(self, getMemoryDump = False): """ mbi = win32.MemoryBasicInformation() mbi.BaseAddress = self.address - mbi.RegionSize = self.size - mbi.State = self._parse_state(self.state) - mbi.Protect = self._parse_access(self.access) - mbi.Type = self._parse_type(self.type) + mbi.RegionSize = self.size + mbi.State = self._parse_state(self.state) + mbi.Protect = self._parse_access(self.access) + mbi.Type = self._parse_type(self.type) if self.alloc_base is not None: mbi.AllocationBase = self.alloc_base else: @@ -498,7 +501,7 @@ def toMBI(self, getMemoryDump = False): if self.filename is not None: mbi.filename = self.filename if getMemoryDump and self.content is not None: - mbi.content = self.content + mbi.content = self.content return mbi @staticmethod @@ -529,7 +532,7 @@ def _parse_access(access): if not access: return 0 perm = access[:3] - if perm == "R--": + if perm == "R--": protect = win32.PAGE_READONLY elif perm == "RW-": protect = win32.PAGE_READWRITE @@ -553,9 +556,11 @@ def _parse_access(access): protect = protect | win32.PAGE_WRITECOMBINE return protect -#------------------------------------------------------------------------------ -class CrashDTO (BaseDTO): +# ------------------------------------------------------------------------------ + + +class CrashDTO(BaseDTO): """ Database mapping for crash dumps. """ @@ -564,31 +569,30 @@ class CrashDTO (BaseDTO): __tablename__ = "crashes" # Primary key. - id = Column(Integer, Sequence(__tablename__ + '_seq'), - primary_key = True, autoincrement = True) + id = Column(Integer, Sequence(__tablename__ + "_seq"), primary_key=True, autoincrement=True) # Timestamp. - timestamp = Column(DateTime, nullable = False, index = True) + timestamp = Column(DateTime, nullable=False, index=True) # Exploitability test. - exploitable = Column(Integer, nullable = False) - exploitability_rule = Column(String(32), nullable = False) - exploitability_rating = Column(String(32), nullable = False) - exploitability_desc = Column(String, nullable = False) + exploitable = Column(Integer, nullable=False) + exploitability_rule = Column(String(32), nullable=False) + exploitability_rating = Column(String(32), nullable=False) + exploitability_desc = Column(String, nullable=False) # Platform description. - os = Column(String(32), nullable = False) - arch = Column(String(16), nullable = False) - bits = Column(Integer, nullable = False) # Integer(4) is deprecated :( + os = Column(String(32), nullable=False) + arch = Column(String(16), nullable=False) + bits = Column(Integer, nullable=False) # Integer(4) is deprecated :( # Event description. - event = Column(String, nullable = False) - pid = Column(Integer, nullable = False) - tid = Column(Integer, nullable = False) - pc = Column(BigInteger, nullable = False) - sp = Column(BigInteger, nullable = False) - fp = Column(BigInteger, nullable = False) - pc_label = Column(String, nullable = False) + event = Column(String, nullable=False) + pid = Column(Integer, nullable=False) + tid = Column(Integer, nullable=False) + pc = Column(BigInteger, nullable=False) + sp = Column(BigInteger, nullable=False) + fp = Column(BigInteger, nullable=False) + pc_label = Column(String, nullable=False) # Exception description. exception = Column(String(64)) @@ -613,10 +617,10 @@ class CrashDTO (BaseDTO): notes = Column(String) # Heuristic signature. - signature = Column(String, nullable = False) + signature = Column(String, nullable=False) # Pickled Crash object, minus the memory dump. - data = deferred(Column(LargeBinary, nullable = False)) + data = deferred(Column(LargeBinary, nullable=False)) def __init__(self, crash): """ @@ -625,60 +629,56 @@ def __init__(self, crash): """ # Timestamp and signature. - self.timestamp = datetime.datetime.fromtimestamp( crash.timeStamp ) - self.signature = pickle.dumps(crash.signature, protocol = 0) + self.timestamp = datetime.datetime.fromtimestamp(crash.timeStamp) + self.signature = pickle.dumps(crash.signature, protocol=0) # Marshalled Crash object, minus the memory dump. # This code is *not* thread safe! memoryMap = crash.memoryMap try: crash.memoryMap = None - self.data = buffer( Marshaller.dumps(crash) ) + self.data = buffer(Marshaller.dumps(crash)) finally: crash.memoryMap = memoryMap # Exploitability test. - self.exploitability_rating, \ - self.exploitability_rule, \ - self.exploitability_desc = crash.isExploitable() + self.exploitability_rating, self.exploitability_rule, self.exploitability_desc = crash.isExploitable() # Exploitability test as an integer result (for sorting). self.exploitable = [ - "Not an exception", - "Not exploitable", - "Not likely exploitable", - "Unknown", - "Probably exploitable", - "Exploitable", - ].index(self.exploitability_rating) + "Not an exception", + "Not exploitable", + "Not likely exploitable", + "Unknown", + "Probably exploitable", + "Exploitable", + ].index(self.exploitability_rating) # Platform description. - self.os = crash.os + self.os = crash.os self.arch = crash.arch self.bits = crash.bits # Event description. - self.event = crash.eventName - self.pid = crash.pid - self.tid = crash.tid - self.pc = crash.pc - self.sp = crash.sp - self.fp = crash.fp + self.event = crash.eventName + self.pid = crash.pid + self.tid = crash.tid + self.pc = crash.pc + self.sp = crash.sp + self.fp = crash.fp self.pc_label = crash.labelPC # Exception description. - self.exception = crash.exceptionName - self.exception_text = crash.exceptionDescription + self.exception = crash.exceptionName + self.exception_text = crash.exceptionDescription self.exception_address = crash.exceptionAddress - self.exception_label = crash.exceptionLabel - self.first_chance = crash.firstChance - self.fault_type = crash.faultType - self.fault_address = crash.faultAddress - self.fault_label = crash.faultLabel - self.fault_disasm = CrashDump.dump_code( crash.faultDisasm, - crash.pc ) - self.stack_trace = CrashDump.dump_stack_trace_with_labels( - crash.stackTracePretty ) + self.exception_label = crash.exceptionLabel + self.first_chance = crash.firstChance + self.fault_type = crash.faultType + self.fault_address = crash.faultAddress + self.fault_label = crash.faultLabel + self.fault_disasm = CrashDump.dump_code(crash.faultDisasm, crash.pc) + self.stack_trace = CrashDump.dump_stack_trace_with_labels(crash.stackTracePretty) # Command line. self.command_line = crash.commandLine @@ -687,11 +687,11 @@ def __init__(self, crash): if crash.environment: envList = crash.environment.items() envList.sort() - environment = '' + environment = "" for envKey, envVal in envList: # Must concatenate here instead of using a substitution, # so strings can be automatically promoted to Unicode. - environment += envKey + '=' + envVal + '\n' + environment += envKey + "=" + envVal + "\n" if environment: self.environment = environment @@ -701,7 +701,7 @@ def __init__(self, crash): # Notes. self.notes = crash.notesReport() - def toCrash(self, getMemoryDump = False): + def toCrash(self, getMemoryDump=False): """ Returns a L{Crash} object using the data retrieved from the database. @@ -714,8 +714,7 @@ def toCrash(self, getMemoryDump = False): """ crash = Marshaller.loads(str(self.data)) if not isinstance(crash, Crash): - raise TypeError( - "Expected Crash instance, got %s instead" % type(crash)) + raise TypeError("Expected Crash instance, got %s instead" % type(crash)) crash._rowid = self.id if not crash.memoryMap: memory = getattr(self, "memory", []) @@ -723,18 +722,20 @@ def toCrash(self, getMemoryDump = False): crash.memoryMap = [dto.toMBI(getMemoryDump) for dto in memory] return crash -#============================================================================== + +# ============================================================================== # TODO: add a method to modify already stored crash dumps. -class CrashDAO (BaseDAO): + +class CrashDAO(BaseDAO): """ Data Access Object to read, write and search for L{Crash} objects in a database. """ @Transactional - def add(self, crash, allow_duplicates = True): + def add(self, crash, allow_duplicates=True): """ Add a new crash dump to the database, optionally filtering them by signature to avoid duplicates. @@ -757,10 +758,8 @@ def add(self, crash, allow_duplicates = True): # Filter out duplicated crashes, if requested. if not allow_duplicates: - signature = pickle.dumps(crash.signature, protocol = 0) - if self._session.query(CrashDTO.id) \ - .filter_by(signature = signature) \ - .count() > 0: + signature = pickle.dumps(crash.signature, protocol=0) + if self._session.query(CrashDTO.id).filter_by(signature=signature).count() > 0: return # Fill out a new row for the crashes table. @@ -779,7 +778,6 @@ def __add_crash(self, crash): session = self._session r_crash = None try: - # Fill out a new row for the crashes table. r_crash = CrashDTO(crash) session.add(r_crash) @@ -790,13 +788,11 @@ def __add_crash(self, crash): finally: try: - # Make the ORM forget the CrashDTO object. if r_crash is not None: session.expire(r_crash) finally: - # Delete the last reference to the CrashDTO # object, so the Python garbage collector claims it. del r_crash @@ -814,10 +810,7 @@ def __add_memory(self, crash_id, memoryMap): session.flush() @Transactional - def find(self, - signature = None, order = 0, - since = None, until = None, - offset = None, limit = None): + def find(self, signature=None, order=0, since=None, until=None, offset=None, limit=None): """ Retrieve all crash dumps in the database, optionally filtering them by signature and timestamp, and/or sorting them by timestamp. @@ -857,18 +850,16 @@ def find(self, # Validate the parameters. if since and until and since > until: - warnings.warn("CrashDAO.find() got the 'since' and 'until'" - " arguments reversed, corrected automatically.") + warnings.warn("CrashDAO.find() got the 'since' and 'until'" " arguments reversed, corrected automatically.") since, until = until, since if limit is not None and not limit: - warnings.warn("CrashDAO.find() was set a limit of 0 results," - " returning without executing a query.") + warnings.warn("CrashDAO.find() was set a limit of 0 results," " returning without executing a query.") return [] # Build the SQL query. query = self._session.query(CrashDTO) if signature is not None: - sig_pickled = pickle.dumps(signature, protocol = 0) + sig_pickled = pickle.dumps(signature, protocol=0) query = query.filter(CrashDTO.signature == sig_pickled) if since: query = query.filter(CrashDTO.timestamp >= since) @@ -895,7 +886,7 @@ def find(self, return [] @Transactional - def find_by_example(self, crash, offset = None, limit = None): + def find_by_example(self, crash, offset=None, limit=None): """ Find all crash dumps that have common properties with the crash dump provided. @@ -924,8 +915,7 @@ def find_by_example(self, crash, offset = None, limit = None): # Validate the parameters. if limit is not None and not limit: - warnings.warn("CrashDAO.find_by_example() was set a limit of 0" - " results, returning without executing a query.") + warnings.warn("CrashDAO.find_by_example() was set a limit of 0" " results, returning without executing a query.") return [] # Build the query. @@ -941,9 +931,7 @@ def find_by_example(self, crash, offset = None, limit = None): # Filter all the fields in the crashes table that are present in the # CrashDTO object and not set to None, except for the row ID. for name, column in compat.iteritems(CrashDTO.__dict__): - if not name.startswith('__') and name not in ('id', - 'signature', - 'data'): + if not name.startswith("__") and name not in ("id", "signature", "data"): if isinstance(column, Column): value = getattr(dto, name, None) if value is not None: @@ -962,7 +950,7 @@ def find_by_example(self, crash, offset = None, limit = None): return [] @Transactional - def count(self, signature = None): + def count(self, signature=None): """ Counts how many crash dumps have been stored in this database. Optionally filters the count by heuristic signature. @@ -976,8 +964,8 @@ def count(self, signature = None): """ query = self._session.query(CrashDTO.id) if signature: - sig_pickled = pickle.dumps(signature, protocol = 0) - query = query.filter_by(signature = sig_pickled) + sig_pickled = pickle.dumps(signature, protocol=0) + query = query.filter_by(signature=sig_pickled) return query.count() @Transactional @@ -988,6 +976,6 @@ def delete(self, crash): @type crash: L{Crash} @param crash: Crash dump to remove. """ - query = self._session.query(CrashDTO).filter_by(id = crash._rowid) - query.delete(synchronize_session = False) + query = self._session.query(CrashDTO).filter_by(id=crash._rowid) + query.delete(synchronize_session=False) del crash._rowid diff --git a/pydevd_attach_to_process/winappdbg/system.py b/pydevd_attach_to_process/winappdbg/system.py index 9ee320012..11eea80c5 100644 --- a/pydevd_attach_to_process/winappdbg/system.py +++ b/pydevd_attach_to_process/winappdbg/system.py @@ -39,13 +39,12 @@ __revision__ = "$Id$" -__all__ = ['System'] +__all__ = ["System"] from winappdbg import win32 from winappdbg.registry import Registry from winappdbg.textio import HexInput, HexDump -from winappdbg.util import Regenerator, PathOperations, MemoryAddresses, DebugRegister, \ - classproperty +from winappdbg.util import Regenerator, PathOperations, MemoryAddresses, DebugRegister, classproperty from winappdbg.process import _ProcessContainer from winappdbg.window import Window @@ -56,9 +55,10 @@ from os import path, getenv -#============================================================================== +# ============================================================================== -class System (_ProcessContainer): + +class System(_ProcessContainer): """ Interface to a batch of processes, plus some system wide settings. Contains a snapshot of processes. @@ -116,9 +116,9 @@ class System (_ProcessContainer): @cvar registry: Windows Registry for this machine. """ - arch = win32.arch - bits = win32.bits - os = win32.os + arch = win32.arch + bits = win32.bits + os = win32.os wow64 = win32.wow64 @classproperty @@ -129,10 +129,10 @@ def pageSize(cls): registry = Registry() -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ @staticmethod - def find_window(className = None, windowName = None): + def find_window(className=None, windowName=None): """ Find the first top-level window in the current desktop to match the given class name and/or window name. If neither are provided any @@ -180,7 +180,7 @@ def get_window_at(x, y): @raise WindowsError: An error occured while processing this request. """ - return Window( win32.WindowFromPoint( (x, y) ) ) + return Window(win32.WindowFromPoint((x, y))) @staticmethod def get_foreground_window(): @@ -189,7 +189,7 @@ def get_foreground_window(): @return: Returns the foreground window. @raise WindowsError: An error occured while processing this request. """ - return Window( win32.GetForegroundWindow() ) + return Window(win32.GetForegroundWindow()) @staticmethod def get_desktop_window(): @@ -198,7 +198,7 @@ def get_desktop_window(): @return: Returns the desktop window. @raise WindowsError: An error occured while processing this request. """ - return Window( win32.GetDesktopWindow() ) + return Window(win32.GetDesktopWindow()) @staticmethod def get_shell_window(): @@ -207,12 +207,12 @@ def get_shell_window(): @return: Returns the shell window. @raise WindowsError: An error occured while processing this request. """ - return Window( win32.GetShellWindow() ) + return Window(win32.GetShellWindow()) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ @classmethod - def request_debug_privileges(cls, bIgnoreExceptions = False): + def request_debug_privileges(cls, bIgnoreExceptions=False): """ Requests debug privileges. @@ -238,7 +238,7 @@ def request_debug_privileges(cls, bIgnoreExceptions = False): return False @classmethod - def drop_debug_privileges(cls, bIgnoreExceptions = False): + def drop_debug_privileges(cls, bIgnoreExceptions=False): """ Drops debug privileges. @@ -300,9 +300,8 @@ def adjust_privileges(state, privileges): @raise WindowsError: Raises an exception on error. """ - with win32.OpenProcessToken(win32.GetCurrentProcess(), - win32.TOKEN_ADJUST_PRIVILEGES) as hToken: - NewState = ( (priv, state) for priv in privileges ) + with win32.OpenProcessToken(win32.GetCurrentProcess(), win32.TOKEN_ADJUST_PRIVILEGES) as hToken: + NewState = ((priv, state) for priv in privileges) win32.AdjustTokenPrivileges(hToken, NewState) @staticmethod @@ -315,35 +314,35 @@ def is_admin(): """ return win32.IsUserAnAdmin() -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ __binary_types = { - win32.VFT_APP: "application", - win32.VFT_DLL: "dynamic link library", + win32.VFT_APP: "application", + win32.VFT_DLL: "dynamic link library", win32.VFT_STATIC_LIB: "static link library", - win32.VFT_FONT: "font", - win32.VFT_DRV: "driver", - win32.VFT_VXD: "legacy driver", + win32.VFT_FONT: "font", + win32.VFT_DRV: "driver", + win32.VFT_VXD: "legacy driver", } __driver_types = { - win32.VFT2_DRV_COMM: "communications driver", - win32.VFT2_DRV_DISPLAY: "display driver", - win32.VFT2_DRV_INSTALLABLE: "installable driver", - win32.VFT2_DRV_KEYBOARD: "keyboard driver", - win32.VFT2_DRV_LANGUAGE: "language driver", - win32.VFT2_DRV_MOUSE: "mouse driver", - win32.VFT2_DRV_NETWORK: "network driver", - win32.VFT2_DRV_PRINTER: "printer driver", - win32.VFT2_DRV_SOUND: "sound driver", - win32.VFT2_DRV_SYSTEM: "system driver", - win32.VFT2_DRV_VERSIONED_PRINTER: "versioned printer driver", + win32.VFT2_DRV_COMM: "communications driver", + win32.VFT2_DRV_DISPLAY: "display driver", + win32.VFT2_DRV_INSTALLABLE: "installable driver", + win32.VFT2_DRV_KEYBOARD: "keyboard driver", + win32.VFT2_DRV_LANGUAGE: "language driver", + win32.VFT2_DRV_MOUSE: "mouse driver", + win32.VFT2_DRV_NETWORK: "network driver", + win32.VFT2_DRV_PRINTER: "printer driver", + win32.VFT2_DRV_SOUND: "sound driver", + win32.VFT2_DRV_SYSTEM: "system driver", + win32.VFT2_DRV_VERSIONED_PRINTER: "versioned printer driver", } __font_types = { - win32.VFT2_FONT_RASTER: "raster font", + win32.VFT2_FONT_RASTER: "raster font", win32.VFT2_FONT_TRUETYPE: "TrueType font", - win32.VFT2_FONT_VECTOR: "vector font", + win32.VFT2_FONT_VECTOR: "vector font", } __months = ( @@ -420,17 +419,14 @@ def get_file_version_info(cls, filename): pBuffer, dwLen = win32.VerQueryValue(pBlock, "\\") if dwLen != ctypes.sizeof(win32.VS_FIXEDFILEINFO): raise ctypes.WinError(win32.ERROR_BAD_LENGTH) - pVersionInfo = ctypes.cast(pBuffer, - ctypes.POINTER(win32.VS_FIXEDFILEINFO)) + pVersionInfo = ctypes.cast(pBuffer, ctypes.POINTER(win32.VS_FIXEDFILEINFO)) VersionInfo = pVersionInfo.contents if VersionInfo.dwSignature != 0xFEEF04BD: raise ctypes.WinError(win32.ERROR_BAD_ARGUMENTS) # File and product versions. - FileVersion = "%d.%d" % (VersionInfo.dwFileVersionMS, - VersionInfo.dwFileVersionLS) - ProductVersion = "%d.%d" % (VersionInfo.dwProductVersionMS, - VersionInfo.dwProductVersionLS) + FileVersion = "%d.%d" % (VersionInfo.dwFileVersionMS, VersionInfo.dwFileVersionLS) + ProductVersion = "%d.%d" % (VersionInfo.dwProductVersionMS, VersionInfo.dwProductVersionLS) # Debug build? if VersionInfo.dwFileFlagsMask & win32.VS_FF_DEBUG: @@ -439,7 +435,7 @@ def get_file_version_info(cls, filename): DebugBuild = None # Legacy OS build? - LegacyBuild = (VersionInfo.dwFileOS != win32.VOS_NT_WINDOWS32) + LegacyBuild = VersionInfo.dwFileOS != win32.VOS_NT_WINDOWS32 # File type. FileType = cls.__binary_types.get(VersionInfo.dwFileType) @@ -476,77 +472,53 @@ def get_file_version_info(cls, filename): CreationTimestamp, ) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # Locations for dbghelp.dll. # Unfortunately, Microsoft started bundling WinDbg with the # platform SDK, so the install directories may vary across # versions and platforms. __dbghelp_locations = { - # Intel 64 bits. - win32.ARCH_AMD64: set([ - - # WinDbg bundled with the SDK, version 8.0. - path.join( - getenv("ProgramFiles", "C:\\Program Files"), - "Windows Kits", - "8.0", - "Debuggers", - "x64", - "dbghelp.dll"), - path.join( - getenv("ProgramW6432", getenv("ProgramFiles", - "C:\\Program Files")), - "Windows Kits", - "8.0", - "Debuggers", - "x64", - "dbghelp.dll"), - - # Old standalone versions of WinDbg. - path.join( - getenv("ProgramFiles", "C:\\Program Files"), - "Debugging Tools for Windows (x64)", - "dbghelp.dll"), - ]), - + win32.ARCH_AMD64: set( + [ + # WinDbg bundled with the SDK, version 8.0. + path.join(getenv("ProgramFiles", "C:\\Program Files"), "Windows Kits", "8.0", "Debuggers", "x64", "dbghelp.dll"), + path.join( + getenv("ProgramW6432", getenv("ProgramFiles", "C:\\Program Files")), + "Windows Kits", + "8.0", + "Debuggers", + "x64", + "dbghelp.dll", + ), + # Old standalone versions of WinDbg. + path.join(getenv("ProgramFiles", "C:\\Program Files"), "Debugging Tools for Windows (x64)", "dbghelp.dll"), + ] + ), # Intel 32 bits. - win32.ARCH_I386 : set([ - - # WinDbg bundled with the SDK, version 8.0. - path.join( - getenv("ProgramFiles", "C:\\Program Files"), - "Windows Kits", - "8.0", - "Debuggers", - "x86", - "dbghelp.dll"), - path.join( - getenv("ProgramW6432", getenv("ProgramFiles", - "C:\\Program Files")), - "Windows Kits", - "8.0", - "Debuggers", - "x86", - "dbghelp.dll"), - - # Old standalone versions of WinDbg. - path.join( - getenv("ProgramFiles", "C:\\Program Files"), - "Debugging Tools for Windows (x86)", - "dbghelp.dll"), - - # Version shipped with Windows. - path.join( - getenv("ProgramFiles", "C:\\Program Files"), - "Debugging Tools for Windows (x86)", - "dbghelp.dll"), - ]), + win32.ARCH_I386: set( + [ + # WinDbg bundled with the SDK, version 8.0. + path.join(getenv("ProgramFiles", "C:\\Program Files"), "Windows Kits", "8.0", "Debuggers", "x86", "dbghelp.dll"), + path.join( + getenv("ProgramW6432", getenv("ProgramFiles", "C:\\Program Files")), + "Windows Kits", + "8.0", + "Debuggers", + "x86", + "dbghelp.dll", + ), + # Old standalone versions of WinDbg. + path.join(getenv("ProgramFiles", "C:\\Program Files"), "Debugging Tools for Windows (x86)", "dbghelp.dll"), + # Version shipped with Windows. + path.join(getenv("ProgramFiles", "C:\\Program Files"), "Debugging Tools for Windows (x86)", "dbghelp.dll"), + ] + ), } @classmethod - def load_dbghelp(cls, pathname = None): + def load_dbghelp(cls, pathname=None): """ Load the specified version of the C{dbghelp.dll} library. @@ -597,7 +569,6 @@ def simple_debugger( argv ): # If an explicit pathname was not given, search for the library. if not pathname: - # Under WOW64 we'll treat AMD64 as I386. arch = win32.arch if arch == win32.ARCH_AMD64 and win32.bits == 32: @@ -606,7 +577,7 @@ def simple_debugger( argv ): # Check if the architecture is supported. if not arch in cls.__dbghelp_locations: msg = "Architecture %s is not currently supported." - raise NotImplementedError(msg % arch) + raise NotImplementedError(msg % arch) # Grab all versions of the library we can find. found = [] @@ -621,7 +592,7 @@ def simple_debugger( argv ): f_ver = p_ver elif p_ver and p_ver > f_ver: f_ver = p_ver - found.append( (f_ver, pathname) ) + found.append((f_ver, pathname)) # If we found any, use the newest version. if found: @@ -642,9 +613,7 @@ def simple_debugger( argv ): return dbghelp @staticmethod - def fix_symbol_store_path(symbol_store_path = None, - remote = True, - force = False): + def fix_symbol_store_path(symbol_store_path=None, remote=True, force=False): """ Fix the symbol store path. Equivalent to the C{.symfix} command in Microsoft WinDbg. @@ -716,12 +685,7 @@ def simple_debugger( argv ): if not path.isdir(local_path): local_path = path.abspath(".") if remote: - symbol_store_path = ( - "cache*;SRV*" - + local_path + - "*" - "http://msdl.microsoft.com/download/symbols" - ) + symbol_store_path = "cache*;SRV*" + local_path + "*" "http://msdl.microsoft.com/download/symbols" else: symbol_store_path = "cache*;SRV*" + local_path previous = os.environ.get("_NT_SYMBOL_PATH", None) @@ -730,13 +694,12 @@ def simple_debugger( argv ): return previous except Exception: e = sys.exc_info()[1] - warnings.warn("Cannot fix symbol path, reason: %s" % str(e), - RuntimeWarning) + warnings.warn("Cannot fix symbol path, reason: %s" % str(e), RuntimeWarning) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ @staticmethod - def set_kill_on_exit_mode(bKillOnExit = False): + def set_kill_on_exit_mode(bKillOnExit=False): """ Defines the behavior of the debugged processes when the debugging thread dies. This method only affects the calling thread. @@ -793,14 +756,11 @@ def read_msr(address): It works on my machine, but your mileage may vary. """ if win32.arch not in (win32.ARCH_I386, win32.ARCH_AMD64): - raise NotImplementedError( - "MSR reading is only supported on i386 or amd64 processors.") - msr = win32.SYSDBG_MSR() + raise NotImplementedError("MSR reading is only supported on i386 or amd64 processors.") + msr = win32.SYSDBG_MSR() msr.Address = address - msr.Data = 0 - win32.NtSystemDebugControl(win32.SysDbgReadMsr, - InputBuffer = msr, - OutputBuffer = msr) + msr.Data = 0 + win32.NtSystemDebugControl(win32.SysDbgReadMsr, InputBuffer=msr, OutputBuffer=msr) return msr.Data @staticmethod @@ -825,12 +785,11 @@ def write_msr(address, value): It works on my machine, but your mileage may vary. """ if win32.arch not in (win32.ARCH_I386, win32.ARCH_AMD64): - raise NotImplementedError( - "MSR writing is only supported on i386 or amd64 processors.") - msr = win32.SYSDBG_MSR() + raise NotImplementedError("MSR writing is only supported on i386 or amd64 processors.") + msr = win32.SYSDBG_MSR() msr.Address = address - msr.Data = value - win32.NtSystemDebugControl(win32.SysDbgWriteMsr, InputBuffer = msr) + msr.Data = value + win32.NtSystemDebugControl(win32.SysDbgWriteMsr, InputBuffer=msr) @classmethod def enable_step_on_branch_mode(cls): @@ -855,8 +814,7 @@ def enable_step_on_branch_mode(cls): Maybe it fails in other virtualization/emulation environments, no extensive testing was made so far. """ - cls.write_msr(DebugRegister.DebugCtlMSR, - DebugRegister.BranchTrapFlag | DebugRegister.LastBranchRecord) + cls.write_msr(DebugRegister.DebugCtlMSR, DebugRegister.BranchTrapFlag | DebugRegister.LastBranchRecord) @classmethod def get_last_branch_location(cls): @@ -883,13 +841,13 @@ def get_last_branch_location(cls): no extensive testing was made so far. """ LastBranchFromIP = cls.read_msr(DebugRegister.LastBranchFromIP) - LastBranchToIP = cls.read_msr(DebugRegister.LastBranchToIP) - return ( LastBranchFromIP, LastBranchToIP ) + LastBranchToIP = cls.read_msr(DebugRegister.LastBranchToIP) + return (LastBranchFromIP, LastBranchToIP) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ @classmethod - def get_postmortem_debugger(cls, bits = None): + def get_postmortem_debugger(cls, bits=None): """ Returns the postmortem debugging settings from the Registry. @@ -915,15 +873,15 @@ def get_postmortem_debugger(cls, bits = None): raise NotImplementedError("Unknown architecture (%r bits)" % bits) if bits == 32 and cls.bits == 64: - keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug' + keyname = "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" else: - keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug' + keyname = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" key = cls.registry[keyname] - debugger = key.get('Debugger') - auto = key.get('Auto') - hotkey = key.get('UserDebuggerHotkey') + debugger = key.get("Debugger") + auto = key.get("Auto") + hotkey = key.get("UserDebuggerHotkey") if auto is not None: auto = bool(auto) @@ -931,7 +889,7 @@ def get_postmortem_debugger(cls, bits = None): return (debugger, auto, hotkey) @classmethod - def get_postmortem_exclusion_list(cls, bits = None): + def get_postmortem_exclusion_list(cls, bits=None): """ Returns the exclusion list for the postmortem debugger. @@ -953,9 +911,9 @@ def get_postmortem_exclusion_list(cls, bits = None): raise NotImplementedError("Unknown architecture (%r bits)" % bits) if bits == 32 and cls.bits == 64: - keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList' + keyname = "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList" else: - keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList' + keyname = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList" try: key = cls.registry[keyname] @@ -965,8 +923,7 @@ def get_postmortem_exclusion_list(cls, bits = None): return [name for (name, enabled) in key.items() if enabled] @classmethod - def set_postmortem_debugger(cls, cmdline, - auto = None, hotkey = None, bits = None): + def set_postmortem_debugger(cls, cmdline, auto=None, hotkey=None, bits=None): """ Sets the postmortem debugging settings in the Registry. @@ -1007,21 +964,21 @@ def set_postmortem_debugger(cls, cmdline, raise NotImplementedError("Unknown architecture (%r bits)" % bits) if bits == 32 and cls.bits == 64: - keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug' + keyname = "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" else: - keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug' + keyname = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug" key = cls.registry[keyname] if cmdline is not None: - key['Debugger'] = cmdline + key["Debugger"] = cmdline if auto is not None: - key['Auto'] = int(bool(auto)) + key["Auto"] = int(bool(auto)) if hotkey is not None: - key['UserDebuggerHotkey'] = int(hotkey) + key["UserDebuggerHotkey"] = int(hotkey) @classmethod - def add_to_postmortem_exclusion_list(cls, pathname, bits = None): + def add_to_postmortem_exclusion_list(cls, pathname, bits=None): """ Adds the given filename to the exclusion list for postmortem debugging. @@ -1046,9 +1003,9 @@ def add_to_postmortem_exclusion_list(cls, pathname, bits = None): raise NotImplementedError("Unknown architecture (%r bits)" % bits) if bits == 32 and cls.bits == 64: - keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList' + keyname = "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList" else: - keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList' + keyname = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList" try: key = cls.registry[keyname] @@ -1058,7 +1015,7 @@ def add_to_postmortem_exclusion_list(cls, pathname, bits = None): key[pathname] = 1 @classmethod - def remove_from_postmortem_exclusion_list(cls, pathname, bits = None): + def remove_from_postmortem_exclusion_list(cls, pathname, bits=None): """ Removes the given filename to the exclusion list for postmortem debugging from the Registry. @@ -1091,9 +1048,9 @@ def remove_from_postmortem_exclusion_list(cls, pathname, bits = None): raise NotImplementedError("Unknown architecture (%r bits)" % bits) if bits == 32 and cls.bits == 64: - keyname = 'HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList' + keyname = "HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList" else: - keyname = 'HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList' + keyname = "HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug\\AutoExclusionList" try: key = cls.registry[keyname] @@ -1105,7 +1062,7 @@ def remove_from_postmortem_exclusion_list(cls, pathname, bits = None): except KeyError: return -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ @staticmethod def get_services(): @@ -1119,13 +1076,11 @@ def get_services(): @rtype: list( L{win32.ServiceStatusProcessEntry} ) @return: List of service status descriptors. """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE - ) as hSCManager: - try: - return win32.EnumServicesStatusEx(hSCManager) - except AttributeError: - return win32.EnumServicesStatus(hSCManager) + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_ENUMERATE_SERVICE) as hSCManager: + try: + return win32.EnumServicesStatusEx(hSCManager) + except AttributeError: + return win32.EnumServicesStatus(hSCManager) @staticmethod def get_active_services(): @@ -1139,13 +1094,12 @@ def get_active_services(): @rtype: list( L{win32.ServiceStatusProcessEntry} ) @return: List of service status descriptors. """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE - ) as hSCManager: - return [ entry for entry in win32.EnumServicesStatusEx(hSCManager, - dwServiceType = win32.SERVICE_WIN32, - dwServiceState = win32.SERVICE_ACTIVE) \ - if entry.ProcessId ] + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_ENUMERATE_SERVICE) as hSCManager: + return [ + entry + for entry in win32.EnumServicesStatusEx(hSCManager, dwServiceType=win32.SERVICE_WIN32, dwServiceState=win32.SERVICE_ACTIVE) + if entry.ProcessId + ] @staticmethod def get_service(name): @@ -1163,12 +1117,8 @@ def get_service(name): @rtype: L{win32.ServiceStatusProcess} @return: Service status descriptor. """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE - ) as hSCManager: - with win32.OpenService(hSCManager, name, - dwDesiredAccess = win32.SERVICE_QUERY_STATUS - ) as hService: + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_ENUMERATE_SERVICE) as hSCManager: + with win32.OpenService(hSCManager, name, dwDesiredAccess=win32.SERVICE_QUERY_STATUS) as hService: try: return win32.QueryServiceStatusEx(hService) except AttributeError: @@ -1189,9 +1139,7 @@ def get_service_display_name(name): @rtype: str @return: Service display name. """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE - ) as hSCManager: + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_ENUMERATE_SERVICE) as hSCManager: return win32.GetServiceDisplayName(hSCManager, name) @staticmethod @@ -1209,13 +1157,11 @@ def get_service_from_display_name(displayName): @rtype: str @return: Service unique name. """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_ENUMERATE_SERVICE - ) as hSCManager: + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_ENUMERATE_SERVICE) as hSCManager: return win32.GetServiceKeyName(hSCManager, displayName) @staticmethod - def start_service(name, argv = None): + def start_service(name, argv=None): """ Start the service given by name. @@ -1228,12 +1174,8 @@ def start_service(name, argv = None): C{ServiceName} member of the service descriptors returned by L{get_services} or L{get_active_services}. """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_CONNECT - ) as hSCManager: - with win32.OpenService(hSCManager, name, - dwDesiredAccess = win32.SERVICE_START - ) as hService: + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_CONNECT) as hSCManager: + with win32.OpenService(hSCManager, name, dwDesiredAccess=win32.SERVICE_START) as hService: win32.StartService(hService) @staticmethod @@ -1246,12 +1188,8 @@ def stop_service(name): @see: L{get_services}, L{get_active_services}, L{start_service}, L{pause_service}, L{resume_service} """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_CONNECT - ) as hSCManager: - with win32.OpenService(hSCManager, name, - dwDesiredAccess = win32.SERVICE_STOP - ) as hService: + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_CONNECT) as hSCManager: + with win32.OpenService(hSCManager, name, dwDesiredAccess=win32.SERVICE_STOP) as hService: win32.ControlService(hService, win32.SERVICE_CONTROL_STOP) @staticmethod @@ -1266,12 +1204,8 @@ def pause_service(name): @see: L{get_services}, L{get_active_services}, L{start_service}, L{stop_service}, L{resume_service} """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_CONNECT - ) as hSCManager: - with win32.OpenService(hSCManager, name, - dwDesiredAccess = win32.SERVICE_PAUSE_CONTINUE - ) as hService: + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_CONNECT) as hSCManager: + with win32.OpenService(hSCManager, name, dwDesiredAccess=win32.SERVICE_PAUSE_CONTINUE) as hService: win32.ControlService(hService, win32.SERVICE_CONTROL_PAUSE) @staticmethod @@ -1286,12 +1220,8 @@ def resume_service(name): @see: L{get_services}, L{get_active_services}, L{start_service}, L{stop_service}, L{pause_service} """ - with win32.OpenSCManager( - dwDesiredAccess = win32.SC_MANAGER_CONNECT - ) as hSCManager: - with win32.OpenService(hSCManager, name, - dwDesiredAccess = win32.SERVICE_PAUSE_CONTINUE - ) as hService: + with win32.OpenSCManager(dwDesiredAccess=win32.SC_MANAGER_CONNECT) as hSCManager: + with win32.OpenService(hSCManager, name, dwDesiredAccess=win32.SERVICE_PAUSE_CONTINUE) as hService: win32.ControlService(hService, win32.SERVICE_CONTROL_CONTINUE) # TODO: create_service, delete_service diff --git a/pydevd_attach_to_process/winappdbg/textio.py b/pydevd_attach_to_process/winappdbg/textio.py index 402f631d5..afb4de21e 100644 --- a/pydevd_attach_to_process/winappdbg/textio.py +++ b/pydevd_attach_to_process/winappdbg/textio.py @@ -44,16 +44,16 @@ __revision__ = "$Id$" -__all__ = [ - 'HexDump', - 'HexInput', - 'HexOutput', - 'Color', - 'Table', - 'CrashDump', - 'DebugLog', - 'Logger', - ] +__all__ = [ + "HexDump", + "HexInput", + "HexOutput", + "Color", + "Table", + "CrashDump", + "DebugLog", + "Logger", +] import sys from winappdbg import win32 @@ -65,9 +65,10 @@ import struct import traceback -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ -class HexInput (StaticClass): + +class HexInput(StaticClass): """ Static functions for user input parsing. The counterparts for each method are in the L{HexOutput} class. @@ -86,20 +87,20 @@ def integer(token): """ token = token.strip() neg = False - if token.startswith(compat.b('-')): + if token.startswith(compat.b("-")): token = token[1:] neg = True - if token.startswith(compat.b('0x')): - result = int(token, 16) # hexadecimal - elif token.startswith(compat.b('0b')): + if token.startswith(compat.b("0x")): + result = int(token, 16) # hexadecimal + elif token.startswith(compat.b("0b")): result = int(token[2:], 2) # binary - elif token.startswith(compat.b('0o')): - result = int(token, 8) # octal + elif token.startswith(compat.b("0o")): + result = int(token, 8) # octal else: try: - result = int(token) # decimal + result = int(token) # decimal except ValueError: - result = int(token, 16) # hexadecimal (no "0x" prefix) + result = int(token, 16) # hexadecimal (no "0x" prefix) if neg: result = -result return result @@ -128,14 +129,14 @@ def hexadecimal(token): @rtype: str @return: Parsed string value. """ - token = ''.join([ c for c in token if c.isalnum() ]) + token = "".join([c for c in token if c.isalnum()]) if len(token) % 2 != 0: raise ValueError("Missing characters in hex data") - data = '' + data = "" for i in compat.xrange(0, len(token), 2): - x = token[i:i+2] + x = token[i : i + 2] d = int(x, 16) - s = struct.pack('= 0: - return ('0x%%.%dx' % (integer_size - 2)) % integer - return ('-0x%%.%dx' % (integer_size - 2)) % -integer + return ("0x%%.%dx" % (integer_size - 2)) % integer + return ("-0x%%.%dx" % (integer_size - 2)) % -integer @classmethod - def address(cls, address, bits = None): + def address(cls, address, bits=None): """ @type address: int @param address: Memory address. @@ -364,8 +367,8 @@ def address(cls, address, bits = None): else: address_size = (bits / 4) + 2 if address < 0: - address = ((2 ** bits) - 1) ^ ~address - return ('0x%%.%dx' % (address_size - 2)) % address + address = ((2**bits) - 1) ^ ~address + return ("0x%%.%dx" % (address_size - 2)) % address @staticmethod def hexadecimal(data): @@ -378,10 +381,10 @@ def hexadecimal(data): @rtype: str @return: Hexadecimal representation. """ - return HexDump.hexadecimal(data, separator = '') + return HexDump.hexadecimal(data, separator="") @classmethod - def integer_list_file(cls, filename, values, bits = None): + def integer_list_file(cls, filename, values, bits=None): """ Write a list of integers to a file. If a file of the same name exists, it's contents are replaced. @@ -399,7 +402,7 @@ def integer_list_file(cls, filename, values, bits = None): (Optional) Number of bits of the target architecture. The default is platform dependent. See: L{HexOutput.integer_size} """ - fd = open(filename, 'w') + fd = open(filename, "w") for integer in values: print >> fd, cls.integer(integer, bits) fd.close() @@ -418,7 +421,7 @@ def string_list_file(cls, filename, values): @type values: list( int ) @param values: List of strings to write to the file. """ - fd = open(filename, 'w') + fd = open(filename, "w") for string in values: print >> fd, string fd.close() @@ -442,7 +445,7 @@ def mixed_list_file(cls, filename, values, bits): (Optional) Number of bits of the target architecture. The default is platform dependent. See: L{HexOutput.integer_size} """ - fd = open(filename, 'w') + fd = open(filename, "w") for original in values: try: parsed = cls.integer(original, bits) @@ -451,9 +454,11 @@ def mixed_list_file(cls, filename, values, bits): print >> fd, parsed fd.close() -#------------------------------------------------------------------------------ -class HexDump (StaticClass): +# ------------------------------------------------------------------------------ + + +class HexDump(StaticClass): """ Static functions for hexadecimal dumps. @@ -466,11 +471,11 @@ class HexDump (StaticClass): This value is platform dependent. """ - integer_size = (win32.SIZEOF(win32.DWORD) * 2) - address_size = (win32.SIZEOF(win32.SIZE_T) * 2) + integer_size = win32.SIZEOF(win32.DWORD) * 2 + address_size = win32.SIZEOF(win32.SIZE_T) * 2 @classmethod - def integer(cls, integer, bits = None): + def integer(cls, integer, bits=None): """ @type integer: int @param integer: Integer. @@ -487,10 +492,10 @@ def integer(cls, integer, bits = None): integer_size = cls.integer_size else: integer_size = bits / 4 - return ('%%.%dX' % integer_size) % integer + return ("%%.%dX" % integer_size) % integer @classmethod - def address(cls, address, bits = None): + def address(cls, address, bits=None): """ @type address: int @param address: Memory address. @@ -509,8 +514,8 @@ def address(cls, address, bits = None): else: address_size = bits / 4 if address < 0: - address = ((2 ** bits) - 1) ^ ~address - return ('%%.%dX' % address_size) % address + address = ((2**bits) - 1) ^ ~address + return ("%%.%dX" % address_size) % address @staticmethod def printable(data): @@ -523,16 +528,16 @@ def printable(data): @rtype: str @return: Printable text. """ - result = '' + result = "" for c in data: if 32 < ord(c) < 128: result += c else: - result += '.' + result += "." return result @staticmethod - def hexadecimal(data, separator = ''): + def hexadecimal(data, separator=""): """ Convert binary data to a string of hexadecimal numbers. @@ -546,10 +551,10 @@ def hexadecimal(data, separator = ''): @rtype: str @return: Hexadecimal representation. """ - return separator.join( [ '%.2x' % ord(c) for c in data ] ) + return separator.join(["%.2x" % ord(c) for c in data]) @staticmethod - def hexa_word(data, separator = ' '): + def hexa_word(data, separator=" "): """ Convert binary data to a string of hexadecimal WORDs. @@ -564,12 +569,11 @@ def hexa_word(data, separator = ' '): @return: Hexadecimal representation. """ if len(data) & 1 != 0: - data += '\0' - return separator.join( [ '%.4x' % struct.unpack(' 0: - width.extend( len_row[ -missing : ] ) + width.extend(len_row[-missing:]) elif missing < 0: - len_row.extend( [0] * (-missing) ) - self.__width = [ max( width[i], len_row[i] ) for i in compat.xrange(len(len_row)) ] + len_row.extend([0] * (-missing)) + self.__width = [max(width[i], len_row[i]) for i in compat.xrange(len(len_row))] self.__cols.append(row) def justify(self, column, direction): @@ -1148,9 +1121,9 @@ def justify(self, column, direction): @raise ValueError: Bad direction value. """ if direction == -1: - self.__width[column] = abs(self.__width[column]) + self.__width[column] = abs(self.__width[column]) elif direction == 1: - self.__width[column] = - abs(self.__width[column]) + self.__width[column] = -abs(self.__width[column]) else: raise ValueError("Bad direction value.") @@ -1164,7 +1137,7 @@ def getWidth(self): """ width = 0 if self.__width: - width = sum( abs(x) for x in self.__width ) + width = sum(abs(x) for x in self.__width) width = width + len(self.__width) * len(self.__sep) + 1 return width @@ -1175,7 +1148,7 @@ def getOutput(self): @rtype: str @return: Text output. """ - return '%s\n' % '\n'.join( self.yieldOutput() ) + return "%s\n" % "\n".join(self.yieldOutput()) def yieldOutput(self): """ @@ -1187,12 +1160,12 @@ def yieldOutput(self): width = self.__width if width: num_cols = len(width) - fmt = ['%%%ds' % -w for w in width] + fmt = ["%%%ds" % -w for w in width] if width[-1] > 0: - fmt[-1] = '%s' + fmt[-1] = "%s" fmt = self.__sep.join(fmt) for row in self.__cols: - row.extend( [''] * (num_cols - len(row)) ) + row.extend([""] * (num_cols - len(row))) yield fmt % tuple(row) def show(self): @@ -1201,9 +1174,11 @@ def show(self): """ print(self.getOutput()) -#------------------------------------------------------------------------------ -class CrashDump (StaticClass): +# ------------------------------------------------------------------------------ + + +class CrashDump(StaticClass): """ Static functions for crash dumps. @@ -1213,21 +1188,21 @@ class CrashDump (StaticClass): # Templates for the dump_registers method. reg_template = { - win32.ARCH_I386 : ( - 'eax=%(Eax).8x ebx=%(Ebx).8x ecx=%(Ecx).8x edx=%(Edx).8x esi=%(Esi).8x edi=%(Edi).8x\n' - 'eip=%(Eip).8x esp=%(Esp).8x ebp=%(Ebp).8x %(efl_dump)s\n' - 'cs=%(SegCs).4x ss=%(SegSs).4x ds=%(SegDs).4x es=%(SegEs).4x fs=%(SegFs).4x gs=%(SegGs).4x efl=%(EFlags).8x\n' - ), - win32.ARCH_AMD64 : ( - 'rax=%(Rax).16x rbx=%(Rbx).16x rcx=%(Rcx).16x\n' - 'rdx=%(Rdx).16x rsi=%(Rsi).16x rdi=%(Rdi).16x\n' - 'rip=%(Rip).16x rsp=%(Rsp).16x rbp=%(Rbp).16x\n' - ' r8=%(R8).16x r9=%(R9).16x r10=%(R10).16x\n' - 'r11=%(R11).16x r12=%(R12).16x r13=%(R13).16x\n' - 'r14=%(R14).16x r15=%(R15).16x\n' - '%(efl_dump)s\n' - 'cs=%(SegCs).4x ss=%(SegSs).4x ds=%(SegDs).4x es=%(SegEs).4x fs=%(SegFs).4x gs=%(SegGs).4x efl=%(EFlags).8x\n' - ), + win32.ARCH_I386: ( + "eax=%(Eax).8x ebx=%(Ebx).8x ecx=%(Ecx).8x edx=%(Edx).8x esi=%(Esi).8x edi=%(Edi).8x\n" + "eip=%(Eip).8x esp=%(Esp).8x ebp=%(Ebp).8x %(efl_dump)s\n" + "cs=%(SegCs).4x ss=%(SegSs).4x ds=%(SegDs).4x es=%(SegEs).4x fs=%(SegFs).4x gs=%(SegGs).4x efl=%(EFlags).8x\n" + ), + win32.ARCH_AMD64: ( + "rax=%(Rax).16x rbx=%(Rbx).16x rcx=%(Rcx).16x\n" + "rdx=%(Rdx).16x rsi=%(Rsi).16x rdi=%(Rdi).16x\n" + "rip=%(Rip).16x rsp=%(Rsp).16x rbp=%(Rbp).16x\n" + " r8=%(R8).16x r9=%(R9).16x r10=%(R10).16x\n" + "r11=%(R11).16x r12=%(R12).16x r13=%(R13).16x\n" + "r14=%(R14).16x r15=%(R15).16x\n" + "%(efl_dump)s\n" + "cs=%(SegCs).4x ss=%(SegSs).4x ds=%(SegDs).4x es=%(SegEs).4x fs=%(SegFs).4x gs=%(SegGs).4x efl=%(EFlags).8x\n" + ), } @staticmethod @@ -1244,56 +1219,56 @@ def dump_flags(efl): @return: Text suitable for logging. """ if efl is None: - return '' - efl_dump = 'iopl=%1d' % ((efl & 0x3000) >> 12) + return "" + efl_dump = "iopl=%1d" % ((efl & 0x3000) >> 12) if efl & 0x100000: - efl_dump += ' vip' + efl_dump += " vip" else: - efl_dump += ' ' + efl_dump += " " if efl & 0x80000: - efl_dump += ' vif' + efl_dump += " vif" else: - efl_dump += ' ' + efl_dump += " " # 0x20000 ??? if efl & 0x800: - efl_dump += ' ov' # Overflow + efl_dump += " ov" # Overflow else: - efl_dump += ' no' # No overflow + efl_dump += " no" # No overflow if efl & 0x400: - efl_dump += ' dn' # Downwards + efl_dump += " dn" # Downwards else: - efl_dump += ' up' # Upwards + efl_dump += " up" # Upwards if efl & 0x200: - efl_dump += ' ei' # Enable interrupts + efl_dump += " ei" # Enable interrupts else: - efl_dump += ' di' # Disable interrupts + efl_dump += " di" # Disable interrupts # 0x100 trap flag if efl & 0x80: - efl_dump += ' ng' # Negative + efl_dump += " ng" # Negative else: - efl_dump += ' pl' # Positive + efl_dump += " pl" # Positive if efl & 0x40: - efl_dump += ' zr' # Zero + efl_dump += " zr" # Zero else: - efl_dump += ' nz' # Nonzero + efl_dump += " nz" # Nonzero if efl & 0x10: - efl_dump += ' ac' # Auxiliary carry + efl_dump += " ac" # Auxiliary carry else: - efl_dump += ' na' # No auxiliary carry + efl_dump += " na" # No auxiliary carry # 0x8 ??? if efl & 0x4: - efl_dump += ' pe' # Parity odd + efl_dump += " pe" # Parity odd else: - efl_dump += ' po' # Parity even + efl_dump += " po" # Parity even # 0x2 ??? if efl & 0x1: - efl_dump += ' cy' # Carry + efl_dump += " cy" # Carry else: - efl_dump += ' nc' # No carry + efl_dump += " nc" # No carry return efl_dump @classmethod - def dump_registers(cls, registers, arch = None): + def dump_registers(cls, registers, arch=None): """ Dump the x86/x64 processor register values. The output mimics that of the WinDBG debugger. @@ -1312,23 +1287,23 @@ def dump_registers(cls, registers, arch = None): @return: Text suitable for logging. """ if registers is None: - return '' + return "" if arch is None: - if 'Eax' in registers: + if "Eax" in registers: arch = win32.ARCH_I386 - elif 'Rax' in registers: + elif "Rax" in registers: arch = win32.ARCH_AMD64 else: - arch = 'Unknown' + arch = "Unknown" if arch not in cls.reg_template: msg = "Don't know how to dump the registers for architecture: %s" raise NotImplementedError(msg % arch) registers = registers.copy() - registers['efl_dump'] = cls.dump_flags( registers['EFlags'] ) + registers["efl_dump"] = cls.dump_flags(registers["EFlags"]) return cls.reg_template[arch] % registers @staticmethod - def dump_registers_peek(registers, data, separator = ' ', width = 16): + def dump_registers_peek(registers, data, separator=" ", width=16): """ Dump data pointed to by the given registers, if any. @@ -1344,21 +1319,18 @@ def dump_registers_peek(registers, data, separator = ' ', width = 16): @return: Text suitable for logging. """ if None in (registers, data): - return '' + return "" names = compat.keys(data) names.sort() - result = '' + result = "" for reg_name in names: - tag = reg_name.lower() - dumped = HexDump.hexline(data[reg_name], separator, width) - result += '%s -> %s\n' % (tag, dumped) + tag = reg_name.lower() + dumped = HexDump.hexline(data[reg_name], separator, width) + result += "%s -> %s\n" % (tag, dumped) return result @staticmethod - def dump_data_peek(data, base = 0, - separator = ' ', - width = 16, - bits = None): + def dump_data_peek(data, base=0, separator=" ", width=16, bits=None): """ Dump data from pointers guessed within the given binary data. @@ -1377,18 +1349,18 @@ def dump_data_peek(data, base = 0, @return: Text suitable for logging. """ if data is None: - return '' + return "" pointers = compat.keys(data) pointers.sort() - result = '' + result = "" for offset in pointers: - dumped = HexDump.hexline(data[offset], separator, width) + dumped = HexDump.hexline(data[offset], separator, width) address = HexDump.address(base + offset, bits) - result += '%s -> %s\n' % (address, dumped) + result += "%s -> %s\n" % (address, dumped) return result @staticmethod - def dump_stack_peek(data, separator = ' ', width = 16, arch = None): + def dump_stack_peek(data, separator=" ", width=16, arch=None): """ Dump data from pointers guessed within the given stack dump. @@ -1412,28 +1384,28 @@ def dump_stack_peek(data, separator = ' ', width = 16, arch = None): @return: Text suitable for logging. """ if data is None: - return '' + return "" if arch is None: arch = win32.arch pointers = compat.keys(data) pointers.sort() - result = '' + result = "" if pointers: if arch == win32.ARCH_I386: - spreg = 'esp' + spreg = "esp" elif arch == win32.ARCH_AMD64: - spreg = 'rsp' + spreg = "rsp" else: - spreg = 'STACK' # just a generic tag - tag_fmt = '[%s+0x%%.%dx]' % (spreg, len( '%x' % pointers[-1] ) ) + spreg = "STACK" # just a generic tag + tag_fmt = "[%s+0x%%.%dx]" % (spreg, len("%x" % pointers[-1])) for offset in pointers: - dumped = HexDump.hexline(data[offset], separator, width) - tag = tag_fmt % offset - result += '%s -> %s\n' % (tag, dumped) + dumped = HexDump.hexline(data[offset], separator, width) + tag = tag_fmt % offset + result += "%s -> %s\n" % (tag, dumped) return result @staticmethod - def dump_stack_trace(stack_trace, bits = None): + def dump_stack_trace(stack_trace, bits=None): """ Dump a stack trace, as returned by L{Thread.get_stack_trace} with the C{bUseLabels} parameter set to C{False}. @@ -1451,17 +1423,17 @@ def dump_stack_trace(stack_trace, bits = None): @return: Text suitable for logging. """ if not stack_trace: - return '' + return "" table = Table() - table.addRow('Frame', 'Origin', 'Module') - for (fp, ra, mod) in stack_trace: + table.addRow("Frame", "Origin", "Module") + for fp, ra, mod in stack_trace: fp_d = HexDump.address(fp, bits) ra_d = HexDump.address(ra, bits) table.addRow(fp_d, ra_d, mod) return table.getOutput() @staticmethod - def dump_stack_trace_with_labels(stack_trace, bits = None): + def dump_stack_trace_with_labels(stack_trace, bits=None): """ Dump a stack trace, as returned by L{Thread.get_stack_trace_with_labels}. @@ -1479,11 +1451,11 @@ def dump_stack_trace_with_labels(stack_trace, bits = None): @return: Text suitable for logging. """ if not stack_trace: - return '' + return "" table = Table() - table.addRow('Frame', 'Origin') - for (fp, label) in stack_trace: - table.addRow( HexDump.address(fp, bits), label ) + table.addRow("Frame", "Origin") + for fp, label in stack_trace: + table.addRow(HexDump.address(fp, bits), label) return table.getOutput() # TODO @@ -1493,9 +1465,7 @@ def dump_stack_trace_with_labels(stack_trace, bits = None): # + It'd be very useful to show some labels here. # + It'd be very useful to show register contents for code at EIP @staticmethod - def dump_code(disassembly, pc = None, - bLowercase = True, - bits = None): + def dump_code(disassembly, pc=None, bLowercase=True, bits=None): """ Dump a disassembly. Optionally mark where the program counter is. @@ -1518,26 +1488,21 @@ def dump_code(disassembly, pc = None, @return: Text suitable for logging. """ if not disassembly: - return '' - table = Table(sep = ' | ') - for (addr, size, code, dump) in disassembly: + return "" + table = Table(sep=" | ") + for addr, size, code, dump in disassembly: if bLowercase: code = code.lower() if addr == pc: - addr = ' * %s' % HexDump.address(addr, bits) + addr = " * %s" % HexDump.address(addr, bits) else: - addr = ' %s' % HexDump.address(addr, bits) + addr = " %s" % HexDump.address(addr, bits) table.addRow(addr, dump, code) table.justify(1, 1) return table.getOutput() @staticmethod - def dump_code_line(disassembly_line, bShowAddress = True, - bShowDump = True, - bLowercase = True, - dwDumpWidth = None, - dwCodeWidth = None, - bits = None): + def dump_code_line(disassembly_line, bShowAddress=True, bShowDump=True, bLowercase=True, dwDumpWidth=None, dwCodeWidth=None, bits=None): """ Dump a single line of code. To dump a block of code use L{dump_code}. @@ -1573,29 +1538,29 @@ def dump_code_line(disassembly_line, bShowAddress = True, else: address_size = bits / 4 (addr, size, code, dump) = disassembly_line - dump = dump.replace(' ', '') + dump = dump.replace(" ", "") result = list() - fmt = '' + fmt = "" if bShowAddress: - result.append( HexDump.address(addr, bits) ) - fmt += '%%%ds:' % address_size + result.append(HexDump.address(addr, bits)) + fmt += "%%%ds:" % address_size if bShowDump: result.append(dump) if dwDumpWidth: - fmt += ' %%-%ds' % dwDumpWidth + fmt += " %%-%ds" % dwDumpWidth else: - fmt += ' %s' + fmt += " %s" if bLowercase: code = code.lower() result.append(code) if dwCodeWidth: - fmt += ' %%-%ds' % dwCodeWidth + fmt += " %%-%ds" % dwCodeWidth else: - fmt += ' %s' + fmt += " %s" return fmt % tuple(result) @staticmethod - def dump_memory_map(memoryMap, mappedFilenames = None, bits = None): + def dump_memory_map(memoryMap, mappedFilenames=None, bits=None): """ Dump the memory map of a process. Optionally show the filenames for memory mapped files as well. @@ -1616,7 +1581,7 @@ def dump_memory_map(memoryMap, mappedFilenames = None, bits = None): @return: Text suitable for logging. """ if not memoryMap: - return '' + return "" table = Table() if mappedFilenames: @@ -1626,28 +1591,27 @@ def dump_memory_map(memoryMap, mappedFilenames = None, bits = None): # For each memory block in the map... for mbi in memoryMap: - # Address and size of memory block. BaseAddress = HexDump.address(mbi.BaseAddress, bits) - RegionSize = HexDump.address(mbi.RegionSize, bits) + RegionSize = HexDump.address(mbi.RegionSize, bits) # State (free or allocated). mbiState = mbi.State - if mbiState == win32.MEM_RESERVE: - State = "Reserved" + if mbiState == win32.MEM_RESERVE: + State = "Reserved" elif mbiState == win32.MEM_COMMIT: - State = "Commited" + State = "Commited" elif mbiState == win32.MEM_FREE: - State = "Free" + State = "Free" else: - State = "Unknown" + State = "Unknown" # Page protection bits (R/W/X/G). if mbiState != win32.MEM_COMMIT: Protect = "" else: mbiProtect = mbi.Protect - if mbiProtect & win32.PAGE_NOACCESS: + if mbiProtect & win32.PAGE_NOACCESS: Protect = "--- " elif mbiProtect & win32.PAGE_READONLY: Protect = "R-- " @@ -1665,46 +1629,48 @@ def dump_memory_map(memoryMap, mappedFilenames = None, bits = None): Protect = "RCX " else: Protect = "??? " - if mbiProtect & win32.PAGE_GUARD: + if mbiProtect & win32.PAGE_GUARD: Protect += "G" else: Protect += "-" - if mbiProtect & win32.PAGE_NOCACHE: + if mbiProtect & win32.PAGE_NOCACHE: Protect += "N" else: Protect += "-" - if mbiProtect & win32.PAGE_WRITECOMBINE: + if mbiProtect & win32.PAGE_WRITECOMBINE: Protect += "W" else: Protect += "-" # Type (file mapping, executable image, or private memory). mbiType = mbi.Type - if mbiType == win32.MEM_IMAGE: - Type = "Image" + if mbiType == win32.MEM_IMAGE: + Type = "Image" elif mbiType == win32.MEM_MAPPED: - Type = "Mapped" + Type = "Mapped" elif mbiType == win32.MEM_PRIVATE: - Type = "Private" + Type = "Private" elif mbiType == 0: - Type = "" + Type = "" else: - Type = "Unknown" + Type = "Unknown" # Output a row in the table. if mappedFilenames: - FileName = mappedFilenames.get(mbi.BaseAddress, '') - table.addRow( BaseAddress, RegionSize, State, Protect, Type, FileName ) + FileName = mappedFilenames.get(mbi.BaseAddress, "") + table.addRow(BaseAddress, RegionSize, State, Protect, Type, FileName) else: - table.addRow( BaseAddress, RegionSize, State, Protect, Type ) + table.addRow(BaseAddress, RegionSize, State, Protect, Type) # Return the table output. return table.getOutput() -#------------------------------------------------------------------------------ -class DebugLog (StaticClass): - 'Static functions for debug logging.' +# ------------------------------------------------------------------------------ + + +class DebugLog(StaticClass): + "Static functions for debug logging." @staticmethod def log_text(text): @@ -1717,16 +1683,16 @@ def log_text(text): @rtype: str @return: Log line. """ - if text.endswith('\n'): - text = text[:-len('\n')] - #text = text.replace('\n', '\n\t\t') # text CSV + if text.endswith("\n"): + text = text[: -len("\n")] + # text = text.replace('\n', '\n\t\t') # text CSV ltime = time.strftime("%X") msecs = (time.time() % 1) * 1000 - return '[%s.%04d] %s' % (ltime, msecs, text) - #return '[%s.%04d]\t%s' % (ltime, msecs, text) # text CSV + return "[%s.%04d] %s" % (ltime, msecs, text) + # return '[%s.%04d]\t%s' % (ltime, msecs, text) # text CSV @classmethod - def log_event(cls, event, text = None): + def log_event(cls, event, text=None): """ Log lines of text associated with a debug event. @@ -1744,29 +1710,31 @@ def log_event(cls, event, text = None): if event.get_event_code() == win32.EXCEPTION_DEBUG_EVENT: what = event.get_exception_description() if event.is_first_chance(): - what = '%s (first chance)' % what + what = "%s (first chance)" % what else: - what = '%s (second chance)' % what + what = "%s (second chance)" % what try: address = event.get_fault_address() except NotImplementedError: address = event.get_exception_address() else: - what = event.get_event_name() + what = event.get_event_name() address = event.get_thread().get_pc() process = event.get_process() label = process.get_label_at_address(address) address = HexDump.address(address, process.get_bits()) if label: - where = '%s (%s)' % (address, label) + where = "%s (%s)" % (address, label) else: where = address - text = '%s at %s' % (what, where) - text = 'pid %d tid %d: %s' % (event.get_pid(), event.get_tid(), text) - #text = 'pid %d tid %d:\t%s' % (event.get_pid(), event.get_tid(), text) # text CSV + text = "%s at %s" % (what, where) + text = "pid %d tid %d: %s" % (event.get_pid(), event.get_tid(), text) + # text = 'pid %d tid %d:\t%s' % (event.get_pid(), event.get_tid(), text) # text CSV return cls.log_text(text) -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ + class Logger(object): """ @@ -1783,7 +1751,7 @@ class Logger(object): C{None} if no log file is used. """ - def __init__(self, logfile = None, verbose = True): + def __init__(self, logfile=None, verbose=True): """ @type logfile: str or None @param logfile: Append messages to this text file. @@ -1794,7 +1762,7 @@ def __init__(self, logfile = None, verbose = True): self.verbose = verbose self.logfile = logfile if self.logfile: - self.fd = open(self.logfile, 'a+') + self.fd = open(self.logfile, "a+") def __logfile_error(self, e): """ @@ -1807,11 +1775,12 @@ def __logfile_error(self, e): @param e: Exception raised when trying to write to the log file. """ from sys import stderr + msg = "Warning, error writing log file %s: %s\n" msg = msg % (self.logfile, str(e)) stderr.write(DebugLog.log_text(msg)) self.logfile = None - self.fd = None + self.fd = None def __do_log(self, text): """ @@ -1824,12 +1793,12 @@ def __do_log(self, text): @param text: Text to print. """ if isinstance(text, compat.unicode): - text = text.encode('cp1252') + text = text.encode("cp1252") if self.verbose: print(text) if self.logfile: try: - self.fd.writelines('%s\n' % text) + self.fd.writelines("%s\n" % text) except IOError: e = sys.exc_info()[1] self.__logfile_error(e) @@ -1841,9 +1810,9 @@ def log_text(self, text): @type text: str @param text: Text to log. """ - self.__do_log( DebugLog.log_text(text) ) + self.__do_log(DebugLog.log_text(text)) - def log_event(self, event, text = None): + def log_event(self, event, text=None): """ Log lines of text associated with a debug event. @@ -1854,13 +1823,13 @@ def log_event(self, event, text = None): @param text: (Optional) Text to log. If no text is provided the default is to show a description of the event itself. """ - self.__do_log( DebugLog.log_event(event, text) ) + self.__do_log(DebugLog.log_event(event, text)) def log_exc(self): """ Log lines of text associated with the last Python exception. """ - self.__do_log( 'Exception raised: %s' % traceback.format_exc() ) + self.__do_log("Exception raised: %s" % traceback.format_exc()) def is_enabled(self): """ diff --git a/pydevd_attach_to_process/winappdbg/thread.py b/pydevd_attach_to_process/winappdbg/thread.py index 07313f225..91bc41332 100644 --- a/pydevd_attach_to_process/winappdbg/thread.py +++ b/pydevd_attach_to_process/winappdbg/thread.py @@ -39,7 +39,7 @@ __revision__ = "$Id$" -__all__ = ['Thread'] +__all__ = ["Thread"] from winappdbg import win32 from winappdbg import compat @@ -54,12 +54,13 @@ # delayed imports Process = None -#============================================================================== +# ============================================================================== # TODO # + fetch special registers (MMX, XMM, 3DNow!, etc) -class Thread (object): + +class Thread(object): """ Interface to a thread in another process. @@ -126,7 +127,7 @@ class Thread (object): when the injected thread is killed. """ - def __init__(self, dwThreadId, hThread = None, process = None): + def __init__(self, dwThreadId, hThread=None, process=None): """ @type dwThreadId: int @param dwThreadId: Global thread ID. @@ -137,34 +138,34 @@ def __init__(self, dwThreadId, hThread = None, process = None): @type process: L{Process} @param process: (Optional) Parent Process object. """ - self.dwProcessId = None - self.dwThreadId = dwThreadId - self.hThread = hThread + self.dwProcessId = None + self.dwThreadId = dwThreadId + self.hThread = hThread self.pInjectedMemory = None self.set_name(None) self.set_process(process) # Not really sure if it's a good idea... -## def __eq__(self, aThread): -## """ -## Compare two Thread objects. The comparison is made using the IDs. -## -## @warning: -## If you have two Thread instances with different handles the -## equality operator still returns C{True}, so be careful! -## -## @type aThread: L{Thread} -## @param aThread: Another Thread object. -## -## @rtype: bool -## @return: C{True} if the two thread IDs are equal, -## C{False} otherwise. -## """ -## return isinstance(aThread, Thread) and \ -## self.get_tid() == aThread.get_tid() + ## def __eq__(self, aThread): + ## """ + ## Compare two Thread objects. The comparison is made using the IDs. + ## + ## @warning: + ## If you have two Thread instances with different handles the + ## equality operator still returns C{True}, so be careful! + ## + ## @type aThread: L{Thread} + ## @param aThread: Another Thread object. + ## + ## @rtype: bool + ## @return: C{True} if the two thread IDs are equal, + ## C{False} otherwise. + ## """ + ## return isinstance(aThread, Thread) and \ + ## self.get_tid() == aThread.get_tid() def __load_Process_class(self): - global Process # delayed import + global Process # delayed import if Process is None: from winappdbg.process import Process @@ -180,7 +181,7 @@ def get_process(self): self.__process = Process(self.get_pid()) return self.__process - def set_process(self, process = None): + def set_process(self, process=None): """ Manually set the parent Process object. Use with care! @@ -189,11 +190,11 @@ def set_process(self, process = None): """ if process is None: self.dwProcessId = None - self.__process = None + self.__process = None else: self.__load_Process_class() if not isinstance(process, Process): - msg = "Parent process must be a Process instance, " + msg = "Parent process must be a Process instance, " msg += "got %s instead" % type(process) raise TypeError(msg) self.dwProcessId = process.get_pid() @@ -217,8 +218,7 @@ def get_pid(self): try: # I wish this had been implemented before Vista... # XXX TODO find the real ntdll call under this api - hThread = self.get_handle( - win32.THREAD_QUERY_LIMITED_INFORMATION) + hThread = self.get_handle(win32.THREAD_QUERY_LIMITED_INFORMATION) self.dwProcessId = win32.GetProcessIdOfThread(hThread) except AttributeError: # This method is really bad :P @@ -226,7 +226,7 @@ def get_pid(self): return self.dwProcessId def __get_pid_by_scanning(self): - 'Internally used by get_pid().' + "Internally used by get_pid()." dwProcessId = None dwThreadId = self.get_tid() with win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPTHREAD) as hSnapshot: @@ -255,7 +255,7 @@ def get_name(self): """ return self.name - def set_name(self, name = None): + def set_name(self, name=None): """ Sets the thread's name. @@ -264,9 +264,9 @@ def set_name(self, name = None): """ self.name = name -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def open_handle(self, dwDesiredAccess = win32.THREAD_ALL_ACCESS): + def open_handle(self, dwDesiredAccess=win32.THREAD_ALL_ACCESS): """ Opens a new handle to the thread, closing the previous one. @@ -289,7 +289,7 @@ def open_handle(self, dwDesiredAccess = win32.THREAD_ALL_ACCESS): # In case hThread was set to an actual handle value instead of a Handle # object. This shouldn't happen unless the user tinkered with it. - if not hasattr(self.hThread, '__del__'): + if not hasattr(self.hThread, "__del__"): self.close_handle() self.hThread = hThread @@ -303,14 +303,14 @@ def close_handle(self): collector claims them. """ try: - if hasattr(self.hThread, 'close'): + if hasattr(self.hThread, "close"): self.hThread.close() elif self.hThread not in (None, win32.INVALID_HANDLE_VALUE): win32.CloseHandle(self.hThread) finally: self.hThread = None - def get_handle(self, dwDesiredAccess = win32.THREAD_ALL_ACCESS): + def get_handle(self, dwDesiredAccess=win32.THREAD_ALL_ACCESS): """ Returns a handle to the thread with I{at least} the access rights requested. @@ -349,9 +349,9 @@ def clear(self): finally: self.close_handle() -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def wait(self, dwTimeout = None): + def wait(self, dwTimeout=None): """ Waits for the thread to finish executing. @@ -361,7 +361,7 @@ def wait(self, dwTimeout = None): """ self.get_handle(win32.SYNCHRONIZE).wait(dwTimeout) - def kill(self, dwExitCode = 0): + def kill(self, dwExitCode=0): """ Terminates the thread execution. @@ -381,7 +381,7 @@ def kill(self, dwExitCode = 0): self.get_process().free(self.pInjectedMemory) self.pInjectedMemory = None except Exception: -## raise # XXX DEBUG + ## raise # XXX DEBUG pass # XXX TODO @@ -441,9 +441,9 @@ def get_exit_code(self): dwAccess = win32.THREAD_QUERY_LIMITED_INFORMATION else: dwAccess = win32.THREAD_QUERY_INFORMATION - return win32.GetExitCodeThread( self.get_handle(dwAccess) ) + return win32.GetExitCodeThread(self.get_handle(dwAccess)) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # XXX TODO # Support for string searches on the window captions. @@ -457,16 +457,13 @@ def get_windows(self): process = self.get_process() except Exception: process = None - return [ - Window( hWnd, process, self ) \ - for hWnd in win32.EnumThreadWindows( self.get_tid() ) - ] + return [Window(hWnd, process, self) for hWnd in win32.EnumThreadWindows(self.get_tid())] -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # TODO # A registers cache could be implemented here. - def get_context(self, ContextFlags = None, bSuspend = False): + def get_context(self, ContextFlags=None, bSuspend=False): """ Retrieves the execution context (i.e. the registers values) for this thread. @@ -523,37 +520,30 @@ def get_context(self, ContextFlags = None, bSuspend = False): # If an exception is raised, make sure the thread execution is resumed. try: - if win32.bits == self.get_bits(): - # 64 bit debugger attached to 64 bit process, or # 32 bit debugger attached to 32 bit process. - ctx = win32.GetThreadContext(hThread, - ContextFlags = ContextFlags) + ctx = win32.GetThreadContext(hThread, ContextFlags=ContextFlags) else: if self.is_wow64(): - # 64 bit debugger attached to 32 bit process. if ContextFlags is not None: ContextFlags &= ~win32.ContextArchMask - ContextFlags |= win32.WOW64_CONTEXT_i386 + ContextFlags |= win32.WOW64_CONTEXT_i386 ctx = win32.Wow64GetThreadContext(hThread, ContextFlags) else: - # 32 bit debugger attached to 64 bit process. # XXX only i386/AMD64 is supported in this particular case if win32.arch not in (win32.ARCH_I386, win32.ARCH_AMD64): raise NotImplementedError() if ContextFlags is not None: ContextFlags &= ~win32.ContextArchMask - ContextFlags |= win32.context_amd64.CONTEXT_AMD64 - ctx = win32.context_amd64.GetThreadContext(hThread, - ContextFlags = ContextFlags) + ContextFlags |= win32.context_amd64.CONTEXT_AMD64 + ctx = win32.context_amd64.GetThreadContext(hThread, ContextFlags=ContextFlags) finally: - # Resume the thread if we suspended it. if bSuspend: self.resume() @@ -561,7 +551,7 @@ def get_context(self, ContextFlags = None, bSuspend = False): # Return the context. return ctx - def set_context(self, context, bSuspend = False): + def set_context(self, context, bSuspend=False): """ Sets the values of the registers. @@ -614,7 +604,7 @@ def get_register(self, register): @rtype: int @return: Value of the requested register. """ - 'Returns the value of a specific register.' + "Returns the value of a specific register." context = self.get_context() return context[register] @@ -632,7 +622,7 @@ def set_register(self, register, value): context[register] = value self.set_context(context) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # TODO: a metaclass would do a better job instead of checking the platform # during module import, also would support mixing 32 and 64 bits @@ -698,26 +688,27 @@ def set_fp(self, fp): context.fp = fp self.set_context(context) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ if win32.arch in (win32.ARCH_I386, win32.ARCH_AMD64): - class Flags (object): - 'Commonly used processor flags' - Overflow = 0x800 - Direction = 0x400 - Interrupts = 0x200 - Trap = 0x100 - Sign = 0x80 - Zero = 0x40 + class Flags(object): + "Commonly used processor flags" + + Overflow = 0x800 + Direction = 0x400 + Interrupts = 0x200 + Trap = 0x100 + Sign = 0x80 + Zero = 0x40 # 0x20 ??? - Auxiliary = 0x10 + Auxiliary = 0x10 # 0x8 ??? - Parity = 0x4 + Parity = 0x4 # 0x2 ??? - Carry = 0x1 + Carry = 0x1 - def get_flags(self, FlagMask = 0xFFFFFFFF): + def get_flags(self, FlagMask=0xFFFFFFFF): """ @type FlagMask: int @param FlagMask: (Optional) Bitwise-AND mask. @@ -726,9 +717,9 @@ def get_flags(self, FlagMask = 0xFFFFFFFF): @return: Flags register contents, optionally masking out some bits. """ context = self.get_context(win32.CONTEXT_CONTROL) - return context['EFlags'] & FlagMask + return context["EFlags"] & FlagMask - def set_flags(self, eflags, FlagMask = 0xFFFFFFFF): + def set_flags(self, eflags, FlagMask=0xFFFFFFFF): """ Sets the flags register, optionally masking some bits. @@ -739,7 +730,7 @@ def set_flags(self, eflags, FlagMask = 0xFFFFFFFF): @param FlagMask: (Optional) Bitwise-AND mask. """ context = self.get_context(win32.CONTEXT_CONTROL) - context['EFlags'] = (context['EFlags'] & FlagMask) | eflags + context["EFlags"] = (context["EFlags"] & FlagMask) | eflags self.set_context(context) def get_flag_value(self, FlagBit): @@ -750,7 +741,7 @@ def get_flag_value(self, FlagBit): @rtype: bool @return: Boolean value of the requested flag. """ - return bool( self.get_flags(FlagBit) ) + return bool(self.get_flags(FlagBit)) def set_flag_value(self, FlagBit, FlagValue): """ @@ -805,46 +796,46 @@ def get_tf(self): return self.get_flag_value(self.Flags.Trap) def clear_zf(self): - 'Clears the Zero flag.' + "Clears the Zero flag." self.set_flag_value(self.Flags.Zero, False) def clear_cf(self): - 'Clears the Carry flag.' + "Clears the Carry flag." self.set_flag_value(self.Flags.Carry, False) def clear_sf(self): - 'Clears the Sign flag.' + "Clears the Sign flag." self.set_flag_value(self.Flags.Sign, False) def clear_df(self): - 'Clears the Direction flag.' + "Clears the Direction flag." self.set_flag_value(self.Flags.Direction, False) def clear_tf(self): - 'Clears the Trap flag.' + "Clears the Trap flag." self.set_flag_value(self.Flags.Trap, False) def set_zf(self): - 'Sets the Zero flag.' + "Sets the Zero flag." self.set_flag_value(self.Flags.Zero, True) def set_cf(self): - 'Sets the Carry flag.' + "Sets the Carry flag." self.set_flag_value(self.Flags.Carry, True) def set_sf(self): - 'Sets the Sign flag.' + "Sets the Sign flag." self.set_flag_value(self.Flags.Sign, True) def set_df(self): - 'Sets the Direction flag.' + "Sets the Direction flag." self.set_flag_value(self.Flags.Direction, True) def set_tf(self): - 'Sets the Trap flag.' + "Sets the Trap flag." self.set_flag_value(self.Flags.Trap, True) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def is_wow64(self): """ @@ -866,7 +857,7 @@ def is_wow64(self): try: wow64 = self.__wow64 except AttributeError: - if (win32.bits == 32 and not win32.wow64): + if win32.bits == 32 and not win32.wow64: wow64 = False else: wow64 = self.get_process().is_wow64() @@ -909,8 +900,9 @@ def is_hidden(self): events, and thus said events won't be sent to the debugger. """ return win32.NtQueryInformationThread( - self.get_handle(), # XXX what permissions do I need? - win32.ThreadHideFromDebugger) + self.get_handle(), # XXX what permissions do I need? + win32.ThreadHideFromDebugger, + ) def get_teb(self): """ @@ -921,8 +913,7 @@ def get_teb(self): @return: TEB structure. @raise WindowsError: An exception is raised on error. """ - return self.get_process().read_structure( self.get_teb_address(), - win32.TEB ) + return self.get_process().read_structure(self.get_teb_address(), win32.TEB) def get_teb_address(self): """ @@ -937,11 +928,10 @@ def get_teb_address(self): except AttributeError: try: hThread = self.get_handle(win32.THREAD_QUERY_INFORMATION) - tbi = win32.NtQueryInformationThread( hThread, - win32.ThreadBasicInformation) + tbi = win32.NtQueryInformationThread(hThread, win32.ThreadBasicInformation) address = tbi.TebBaseAddress except WindowsError: - address = self.get_linear_address('SegFs', 0) # fs:[0] + address = self.get_linear_address("SegFs", 0) # fs:[0] if not address: raise self._teb_ptr = address @@ -969,20 +959,19 @@ def get_linear_address(self, segment, address): The current architecture does not support selectors. Selectors only exist in x86-based systems. """ - hThread = self.get_handle(win32.THREAD_QUERY_INFORMATION) + hThread = self.get_handle(win32.THREAD_QUERY_INFORMATION) selector = self.get_register(segment) - ldt = win32.GetThreadSelectorEntry(hThread, selector) - BaseLow = ldt.BaseLow - BaseMid = ldt.HighWord.Bytes.BaseMid << 16 - BaseHi = ldt.HighWord.Bytes.BaseHi << 24 - Base = BaseLow | BaseMid | BaseHi + ldt = win32.GetThreadSelectorEntry(hThread, selector) + BaseLow = ldt.BaseLow + BaseMid = ldt.HighWord.Bytes.BaseMid << 16 + BaseHi = ldt.HighWord.Bytes.BaseHi << 24 + Base = BaseLow | BaseMid | BaseHi LimitLow = ldt.LimitLow - LimitHi = ldt.HighWord.Bits.LimitHi << 16 - Limit = LimitLow | LimitHi + LimitHi = ldt.HighWord.Bits.LimitHi << 16 + Limit = LimitLow | LimitHi if address > Limit: msg = "Address %s too large for segment %s (selector %d)" - msg = msg % (HexDump.address(address, self.get_bits()), - segment, selector) + msg = msg % (HexDump.address(address, self.get_bits()), segment, selector) raise ValueError(msg) return Base + address @@ -991,7 +980,7 @@ def get_label_at_pc(self): @rtype: str @return: Label that points to the instruction currently being executed. """ - return self.get_process().get_label_at_address( self.get_pc() ) + return self.get_process().get_label_at_address(self.get_pc()) def get_seh_chain_pointer(self): """ @@ -1006,12 +995,11 @@ def get_seh_chain_pointer(self): This method is only supported in 32 bits versions of Windows. """ if win32.arch != win32.ARCH_I386: - raise NotImplementedError( - "SEH chain parsing is only supported in 32-bit Windows.") + raise NotImplementedError("SEH chain parsing is only supported in 32-bit Windows.") process = self.get_process() - address = self.get_linear_address( 'SegFs', 0 ) - return process.read_pointer( address ) + address = self.get_linear_address("SegFs", 0) + return process.read_pointer(address) def set_seh_chain_pointer(self, value): """ @@ -1026,12 +1014,11 @@ def set_seh_chain_pointer(self, value): This method is only supported in 32 bits versions of Windows. """ if win32.arch != win32.ARCH_I386: - raise NotImplementedError( - "SEH chain parsing is only supported in 32-bit Windows.") + raise NotImplementedError("SEH chain parsing is only supported in 32-bit Windows.") process = self.get_process() - address = self.get_linear_address( 'SegFs', 0 ) - process.write_pointer( address, value ) + address = self.get_linear_address("SegFs", 0) + process.write_pointer(address, value) def get_seh_chain(self): """ @@ -1051,11 +1038,11 @@ def get_seh_chain(self): process = self.get_process() seh = self.get_seh_chain_pointer() while seh != 0xFFFFFFFF: - seh_func = process.read_pointer( seh + 4 ) - seh_chain.append( (seh, seh_func) ) - seh = process.read_pointer( seh ) + seh_func = process.read_pointer(seh + 4) + seh_chain.append((seh, seh_func)) + seh = process.read_pointer(seh) except WindowsError: - seh_chain.append( (seh, None) ) + seh_chain.append((seh, None)) return seh_chain def get_wait_chain(self): @@ -1073,7 +1060,7 @@ def get_wait_chain(self): U{http://msdn.microsoft.com/en-us/library/ms681622%28VS.85%29.aspx} """ with win32.OpenThreadWaitChainSession() as hWct: - return win32.GetThreadWaitChain(hWct, ThreadId = self.get_tid()) + return win32.GetThreadWaitChain(hWct, ThreadId=self.get_tid()) def get_stack_range(self): """ @@ -1087,10 +1074,9 @@ def get_stack_range(self): # TODO use teb.DeallocationStack too (max. possible stack size) teb = self.get_teb() tib = teb.NtTib - return ( tib.StackLimit, tib.StackBase ) # top, bottom + return (tib.StackLimit, tib.StackBase) # top, bottom - def __get_stack_trace(self, depth = 16, bUseLabels = True, - bMakePretty = True): + def __get_stack_trace(self, depth=16, bUseLabels=True, bMakePretty=True): """ Tries to get a stack trace for the current function using the debug helper API (dbghelp.dll). @@ -1133,15 +1119,13 @@ def __get_stack_trace(self, depth = 16, bUseLabels = True, msg = "Stack walking is not available for this architecture: %s" raise NotImplementedError(msg % arch) - hProcess = aProcess.get_handle( win32.PROCESS_VM_READ | - win32.PROCESS_QUERY_INFORMATION ) - hThread = self.get_handle( win32.THREAD_GET_CONTEXT | - win32.THREAD_QUERY_INFORMATION ) + hProcess = aProcess.get_handle(win32.PROCESS_VM_READ | win32.PROCESS_QUERY_INFORMATION) + hThread = self.get_handle(win32.THREAD_GET_CONTEXT | win32.THREAD_QUERY_INFORMATION) StackFrame = win32.STACKFRAME64() - StackFrame.AddrPC = win32.ADDRESS64( self.get_pc() ) - StackFrame.AddrFrame = win32.ADDRESS64( self.get_fp() ) - StackFrame.AddrStack = win32.ADDRESS64( self.get_sp() ) + StackFrame.AddrPC = win32.ADDRESS64(self.get_pc()) + StackFrame.AddrFrame = win32.ADDRESS64(self.get_fp()) + StackFrame.AddrStack = win32.ADDRESS64(self.get_sp()) trace = list() while win32.StackWalk64(MachineType, hProcess, hThread, StackFrame): @@ -1162,15 +1146,14 @@ def __get_stack_trace(self, depth = 16, bUseLabels = True, if bUseLabels: label = aProcess.get_label_at_address(ra) if bMakePretty: - label = '%s (%s)' % (HexDump.address(ra, bits), label) - trace.append( (fp, label) ) + label = "%s (%s)" % (HexDump.address(ra, bits), label) + trace.append((fp, label)) else: - trace.append( (fp, ra, lib) ) + trace.append((fp, ra, lib)) fp = aProcess.peek_pointer(fp) return tuple(trace) - def __get_stack_trace_manually(self, depth = 16, bUseLabels = True, - bMakePretty = True): + def __get_stack_trace_manually(self, depth=16, bUseLabels=True, bMakePretty=True): """ Tries to get a stack trace for the current function. Only works for functions with standard prologue and epilogue. @@ -1199,9 +1182,9 @@ def __get_stack_trace_manually(self, depth = 16, bUseLabels = True, @raise WindowsError: Raises an exception on error. """ aProcess = self.get_process() - st, sb = self.get_stack_range() # top, bottom - fp = self.get_fp() - trace = list() + st, sb = self.get_stack_range() # top, bottom + fp = self.get_fp() + trace = list() if aProcess.get_module_count() == 0: aProcess.scan_modules() bits = aProcess.get_bits() @@ -1210,7 +1193,7 @@ def __get_stack_trace_manually(self, depth = 16, bUseLabels = True, break if not st <= fp < sb: break - ra = aProcess.peek_pointer(fp + 4) + ra = aProcess.peek_pointer(fp + 4) if ra == 0: break lib = aProcess.get_module_at_address(ra) @@ -1224,14 +1207,14 @@ def __get_stack_trace_manually(self, depth = 16, bUseLabels = True, if bUseLabels: label = aProcess.get_label_at_address(ra) if bMakePretty: - label = '%s (%s)' % (HexDump.address(ra, bits), label) - trace.append( (fp, label) ) + label = "%s (%s)" % (HexDump.address(ra, bits), label) + trace.append((fp, label)) else: - trace.append( (fp, ra, lib) ) + trace.append((fp, ra, lib)) fp = aProcess.peek_pointer(fp) return tuple(trace) - def get_stack_trace(self, depth = 16): + def get_stack_trace(self, depth=16): """ Tries to get a stack trace for the current function. Only works for functions with standard prologue and epilogue. @@ -1249,13 +1232,14 @@ def get_stack_trace(self, depth = 16): trace = self.__get_stack_trace(depth, False) except Exception: import traceback + traceback.print_exc() trace = () if not trace: trace = self.__get_stack_trace_manually(depth, False) return trace - def get_stack_trace_with_labels(self, depth = 16, bMakePretty = True): + def get_stack_trace_with_labels(self, depth=16, bMakePretty=True): """ Tries to get a stack trace for the current function. Only works for functions with standard prologue and epilogue. @@ -1300,19 +1284,19 @@ def get_stack_frame_range(self): @raise WindowsError: An error occured when getting the thread context. """ - st, sb = self.get_stack_range() # top, bottom - sp = self.get_sp() - fp = self.get_fp() - size = fp - sp + st, sb = self.get_stack_range() # top, bottom + sp = self.get_sp() + fp = self.get_fp() + size = fp - sp if not st <= sp < sb: - raise RuntimeError('Stack pointer lies outside the stack') + raise RuntimeError("Stack pointer lies outside the stack") if not st <= fp < sb: - raise RuntimeError('Frame pointer lies outside the stack') + raise RuntimeError("Frame pointer lies outside the stack") if sp > fp: - raise RuntimeError('No valid stack frame found') + raise RuntimeError("No valid stack frame found") return (sp, fp) - def get_stack_frame(self, max_size = None): + def get_stack_frame(self, max_size=None): """ Reads the contents of the current stack frame. Only works for functions with standard prologue and epilogue. @@ -1332,13 +1316,13 @@ def get_stack_frame(self, max_size = None): @raise WindowsError: An error occured when getting the thread context or reading data from the process memory. """ - sp, fp = self.get_stack_frame_range() - size = fp - sp + sp, fp = self.get_stack_frame_range() + size = fp - sp if max_size and size > max_size: size = max_size return self.get_process().peek(sp, size) - def read_stack_data(self, size = 128, offset = 0): + def read_stack_data(self, size=128, offset=0): """ Reads the contents of the top of the stack. @@ -1356,7 +1340,7 @@ def read_stack_data(self, size = 128, offset = 0): aProcess = self.get_process() return aProcess.read(self.get_sp() + offset, size) - def peek_stack_data(self, size = 128, offset = 0): + def peek_stack_data(self, size=128, offset=0): """ Tries to read the contents of the top of the stack. @@ -1373,7 +1357,7 @@ def peek_stack_data(self, size = 128, offset = 0): aProcess = self.get_process() return aProcess.peek(self.get_sp() + offset, size) - def read_stack_dwords(self, count, offset = 0): + def read_stack_dwords(self, count, offset=0): """ Reads DWORDs from the top of the stack. @@ -1390,10 +1374,10 @@ def read_stack_dwords(self, count, offset = 0): """ if count > 0: stackData = self.read_stack_data(count * 4, offset) - return struct.unpack('<'+('L'*count), stackData) + return struct.unpack("<" + ("L" * count), stackData) return () - def peek_stack_dwords(self, count, offset = 0): + def peek_stack_dwords(self, count, offset=0): """ Tries to read DWORDs from the top of the stack. @@ -1409,12 +1393,12 @@ def peek_stack_dwords(self, count, offset = 0): """ stackData = self.peek_stack_data(count * 4, offset) if len(stackData) & 3: - stackData = stackData[:-len(stackData) & 3] + stackData = stackData[: -len(stackData) & 3] if not stackData: return () - return struct.unpack('<'+('L'*count), stackData) + return struct.unpack("<" + ("L" * count), stackData) - def read_stack_qwords(self, count, offset = 0): + def read_stack_qwords(self, count, offset=0): """ Reads QWORDs from the top of the stack. @@ -1430,9 +1414,9 @@ def read_stack_qwords(self, count, offset = 0): @raise WindowsError: Could not read the requested data. """ stackData = self.read_stack_data(count * 8, offset) - return struct.unpack('<'+('Q'*count), stackData) + return struct.unpack("<" + ("Q" * count), stackData) - def peek_stack_qwords(self, count, offset = 0): + def peek_stack_qwords(self, count, offset=0): """ Tries to read QWORDs from the top of the stack. @@ -1448,12 +1432,12 @@ def peek_stack_qwords(self, count, offset = 0): """ stackData = self.peek_stack_data(count * 8, offset) if len(stackData) & 7: - stackData = stackData[:-len(stackData) & 7] + stackData = stackData[: -len(stackData) & 7] if not stackData: return () - return struct.unpack('<'+('Q'*count), stackData) + return struct.unpack("<" + ("Q" * count), stackData) - def read_stack_structure(self, structure, offset = 0): + def read_stack_structure(self, structure, offset=0): """ Reads the given structure at the top of the stack. @@ -1468,12 +1452,11 @@ def read_stack_structure(self, structure, offset = 0): @return: Tuple of elements read from the stack. The type of each element matches the types in the stack frame structure. """ - aProcess = self.get_process() + aProcess = self.get_process() stackData = aProcess.read_structure(self.get_sp() + offset, structure) - return tuple([ stackData.__getattribute__(name) - for (name, type) in stackData._fields_ ]) + return tuple([stackData.__getattribute__(name) for (name, type) in stackData._fields_]) - def read_stack_frame(self, structure, offset = 0): + def read_stack_frame(self, structure, offset=0): """ Reads the stack frame of the thread. @@ -1488,12 +1471,11 @@ def read_stack_frame(self, structure, offset = 0): @return: Tuple of elements read from the stack frame. The type of each element matches the types in the stack frame structure. """ - aProcess = self.get_process() + aProcess = self.get_process() stackData = aProcess.read_structure(self.get_fp() + offset, structure) - return tuple([ stackData.__getattribute__(name) - for (name, type) in stackData._fields_ ]) + return tuple([stackData.__getattribute__(name) for (name, type) in stackData._fields_]) - def read_code_bytes(self, size = 128, offset = 0): + def read_code_bytes(self, size=128, offset=0): """ Tries to read some bytes of the code currently being executed. @@ -1510,7 +1492,7 @@ def read_code_bytes(self, size = 128, offset = 0): """ return self.get_process().read(self.get_pc() + offset, size) - def peek_code_bytes(self, size = 128, offset = 0): + def peek_code_bytes(self, size=128, offset=0): """ Tries to read some bytes of the code currently being executed. @@ -1526,7 +1508,7 @@ def peek_code_bytes(self, size = 128, offset = 0): """ return self.get_process().peek(self.get_pc() + offset, size) - def peek_pointers_in_registers(self, peekSize = 16, context = None): + def peek_pointers_in_registers(self, peekSize=16, context=None): """ Tries to guess which values in the registers are valid pointers, and reads some data from them. @@ -1542,23 +1524,20 @@ def peek_pointers_in_registers(self, peekSize = 16, context = None): @rtype: dict( str S{->} str ) @return: Dictionary mapping register names to the data they point to. """ - peekable_registers = ( - 'Eax', 'Ebx', 'Ecx', 'Edx', 'Esi', 'Edi', 'Ebp' - ) + peekable_registers = ("Eax", "Ebx", "Ecx", "Edx", "Esi", "Edi", "Ebp") if not context: - context = self.get_context(win32.CONTEXT_CONTROL | \ - win32.CONTEXT_INTEGER) - aProcess = self.get_process() - data = dict() - for (reg_name, reg_value) in compat.iteritems(context): + context = self.get_context(win32.CONTEXT_CONTROL | win32.CONTEXT_INTEGER) + aProcess = self.get_process() + data = dict() + for reg_name, reg_value in compat.iteritems(context): if reg_name not in peekable_registers: continue -## if reg_name == 'Ebp': -## stack_begin, stack_end = self.get_stack_range() -## print hex(stack_end), hex(reg_value), hex(stack_begin) -## if stack_begin and stack_end and stack_end < stack_begin and \ -## stack_begin <= reg_value <= stack_end: -## continue + ## if reg_name == 'Ebp': + ## stack_begin, stack_end = self.get_stack_range() + ## print hex(stack_end), hex(reg_value), hex(stack_begin) + ## if stack_begin and stack_end and stack_end < stack_begin and \ + ## stack_begin <= reg_value <= stack_end: + ## continue reg_data = aProcess.peek(reg_value, peekSize) if reg_data: data[reg_name] = reg_data @@ -1566,7 +1545,7 @@ def peek_pointers_in_registers(self, peekSize = 16, context = None): # TODO # try to avoid reading the same page twice by caching it - def peek_pointers_in_data(self, data, peekSize = 16, peekStep = 1): + def peek_pointers_in_data(self, data, peekSize=16, peekStep=1): """ Tries to guess which values in the given data are valid pointers, and reads some data from them. @@ -1589,7 +1568,7 @@ def peek_pointers_in_data(self, data, peekSize = 16, peekStep = 1): aProcess = self.get_process() return aProcess.peek_pointers_in_data(data, peekSize, peekStep) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # TODO # The disassemble_around and disassemble_around_pc methods @@ -1637,7 +1616,7 @@ def disassemble(self, lpAddress, dwSize): aProcess = self.get_process() return aProcess.disassemble(lpAddress, dwSize) - def disassemble_around(self, lpAddress, dwSize = 64): + def disassemble_around(self, lpAddress, dwSize=64): """ Disassemble around the given address. @@ -1659,7 +1638,7 @@ def disassemble_around(self, lpAddress, dwSize = 64): aProcess = self.get_process() return aProcess.disassemble_around(lpAddress, dwSize) - def disassemble_around_pc(self, dwSize = 64): + def disassemble_around_pc(self, dwSize=64): """ Disassemble around the program counter of the given thread. @@ -1708,11 +1687,13 @@ def disassemble_current(self): - Disassembly line of instruction. - Hexadecimal dump of instruction. """ - return self.disassemble_instruction( self.get_pc() ) + return self.disassemble_instruction(self.get_pc()) + + +# ============================================================================== -#============================================================================== -class _ThreadContainer (object): +class _ThreadContainer(object): """ Encapsulates the capability to contain Thread objects. @@ -1830,9 +1811,9 @@ def get_thread_count(self): self.__initialize_snapshot() return len(self.__threadDict) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def find_threads_by_name(self, name, bExactMatch = True): + def find_threads_by_name(self, name, bExactMatch=True): """ Find threads by name, using different search methods. @@ -1872,7 +1853,7 @@ def find_threads_by_name(self, name, bExactMatch = True): return found_threads -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # XXX TODO # Support for string searches on the window captions. @@ -1884,12 +1865,12 @@ def get_windows(self): """ window_list = list() for thread in self.iter_threads(): - window_list.extend( thread.get_windows() ) + window_list.extend(thread.get_windows()) return window_list -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ - def start_thread(self, lpStartAddress, lpParameter=0, bSuspended = False): + def start_thread(self, lpStartAddress, lpParameter=0, bSuspended=False): """ Remotely creates a new thread in the process. @@ -1907,18 +1888,19 @@ def start_thread(self, lpStartAddress, lpParameter=0, bSuspended = False): dwCreationFlags = win32.CREATE_SUSPENDED else: dwCreationFlags = 0 - hProcess = self.get_handle( win32.PROCESS_CREATE_THREAD | - win32.PROCESS_QUERY_INFORMATION | - win32.PROCESS_VM_OPERATION | - win32.PROCESS_VM_WRITE | - win32.PROCESS_VM_READ ) - hThread, dwThreadId = win32.CreateRemoteThread( - hProcess, 0, 0, lpStartAddress, lpParameter, dwCreationFlags) + hProcess = self.get_handle( + win32.PROCESS_CREATE_THREAD + | win32.PROCESS_QUERY_INFORMATION + | win32.PROCESS_VM_OPERATION + | win32.PROCESS_VM_WRITE + | win32.PROCESS_VM_READ + ) + hThread, dwThreadId = win32.CreateRemoteThread(hProcess, 0, 0, lpStartAddress, lpParameter, dwCreationFlags) aThread = Thread(dwThreadId, hThread, self) self._add_thread(aThread) return aThread -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # TODO # maybe put all the toolhelp code into their own set of classes? @@ -1942,11 +1924,10 @@ def scan_threads(self): if dwProcessId in (0, 4, 8): return -## dead_tids = set( self.get_thread_ids() ) # XXX triggers a scan - dead_tids = self._get_thread_ids() + ## dead_tids = set( self.get_thread_ids() ) # XXX triggers a scan + dead_tids = self._get_thread_ids() dwProcessId = self.get_pid() - hSnapshot = win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPTHREAD, - dwProcessId) + hSnapshot = win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPTHREAD, dwProcessId) try: te = win32.Thread32First(hSnapshot) while te is not None: @@ -1954,9 +1935,9 @@ def scan_threads(self): dwThreadId = te.th32ThreadID if dwThreadId in dead_tids: dead_tids.remove(dwThreadId) -## if not self.has_thread(dwThreadId): # XXX triggers a scan + ## if not self.has_thread(dwThreadId): # XXX triggers a scan if not self._has_thread_id(dwThreadId): - aThread = Thread(dwThreadId, process = self) + aThread = Thread(dwThreadId, process=self) self._add_thread(aThread) te = win32.Thread32Next(hSnapshot) finally: @@ -1998,7 +1979,7 @@ def close_thread_handles(self): except Exception: pass -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ # XXX _notify_* methods should not trigger a scan @@ -2009,17 +1990,17 @@ def _add_thread(self, aThread): @type aThread: L{Thread} @param aThread: Thread object. """ -## if not isinstance(aThread, Thread): -## if hasattr(aThread, '__class__'): -## typename = aThread.__class__.__name__ -## else: -## typename = str(type(aThread)) -## msg = "Expected Thread, got %s instead" % typename -## raise TypeError(msg) + ## if not isinstance(aThread, Thread): + ## if hasattr(aThread, '__class__'): + ## typename = aThread.__class__.__name__ + ## else: + ## typename = str(type(aThread)) + ## msg = "Expected Thread, got %s instead" % typename + ## raise TypeError(msg) dwThreadId = aThread.dwThreadId -## if dwThreadId in self.__threadDict: -## msg = "Already have a Thread object with ID %d" % dwThreadId -## raise KeyError(msg) + ## if dwThreadId in self.__threadDict: + ## msg = "Already have a Thread object with ID %d" % dwThreadId + ## raise KeyError(msg) aThread.set_process(self) self.__threadDict[dwThreadId] = aThread @@ -2038,7 +2019,7 @@ def _del_thread(self, dwThreadId): msg = "Unknown thread ID %d" % dwThreadId warnings.warn(msg, RuntimeWarning) if aThread: - aThread.clear() # remove circular references + aThread.clear() # remove circular references def _has_thread_id(self, dwThreadId): """ @@ -2061,16 +2042,16 @@ def __add_created_thread(self, event): @type event: L{Event} @param event: Event object. """ - dwThreadId = event.get_tid() - hThread = event.get_thread_handle() -## if not self.has_thread(dwThreadId): # XXX this would trigger a scan + dwThreadId = event.get_tid() + hThread = event.get_thread_handle() + ## if not self.has_thread(dwThreadId): # XXX this would trigger a scan if not self._has_thread_id(dwThreadId): aThread = Thread(dwThreadId, hThread, self) - teb_ptr = event.get_teb() # remember the TEB pointer + teb_ptr = event.get_teb() # remember the TEB pointer if teb_ptr: aThread._teb_ptr = teb_ptr self._add_thread(aThread) - #else: + # else: # aThread = self.get_thread(dwThreadId) # if hThread != win32.INVALID_HANDLE_VALUE: # aThread.hThread = hThread # may have more privileges @@ -2121,7 +2102,7 @@ def _notify_exit_thread(self, event): @return: C{True} to call the user-defined handle, C{False} otherwise. """ dwThreadId = event.get_tid() -## if self.has_thread(dwThreadId): # XXX this would trigger a scan + ## if self.has_thread(dwThreadId): # XXX this would trigger a scan if self._has_thread_id(dwThreadId): self._del_thread(dwThreadId) return True diff --git a/pydevd_attach_to_process/winappdbg/util.py b/pydevd_attach_to_process/winappdbg/util.py index dbde5ad3d..6bbff1b98 100644 --- a/pydevd_attach_to_process/winappdbg/util.py +++ b/pydevd_attach_to_process/winappdbg/util.py @@ -52,27 +52,23 @@ __revision__ = "$Id$" __all__ = [ - # Filename and pathname manipulation - 'PathOperations', - + "PathOperations", # Memory address operations - 'MemoryAddresses', - 'CustomAddressIterator', - 'DataAddressIterator', - 'ImageAddressIterator', - 'MappedAddressIterator', - 'ExecutableAddressIterator', - 'ReadableAddressIterator', - 'WriteableAddressIterator', - 'ExecutableAndWriteableAddressIterator', - + "MemoryAddresses", + "CustomAddressIterator", + "DataAddressIterator", + "ImageAddressIterator", + "MappedAddressIterator", + "ExecutableAddressIterator", + "ReadableAddressIterator", + "WriteableAddressIterator", + "ExecutableAndWriteableAddressIterator", # Debug registers manipulation - 'DebugRegister', - + "DebugRegister", # Miscellaneous - 'Regenerator', - ] + "Regenerator", +] import sys import os @@ -82,7 +78,8 @@ from winappdbg import win32 from winappdbg import compat -#============================================================================== +# ============================================================================== + class classproperty(property): """ @@ -93,21 +90,27 @@ class classproperty(property): Inspired on: U{http://stackoverflow.com/a/7864317/426293} """ + def __init__(self, fget=None, fset=None, fdel=None, doc=""): if fset is not None or fdel is not None: raise NotImplementedError() super(classproperty, self).__init__(fget=classmethod(fget), doc=doc) + def __get__(self, cls, owner): return self.fget.__get__(None, owner)() + class BannerHelpFormatter(optparse.IndentedHelpFormatter): "Just a small tweak to optparse to be able to print a banner." + def __init__(self, banner, *argv, **argd): self.banner = banner optparse.IndentedHelpFormatter.__init__(self, *argv, **argd) + def format_usage(self, usage): msg = optparse.IndentedHelpFormatter.format_usage(self, usage) - return '%s\n%s' % (self.banner, msg) + return "%s\n%s" % (self.banner, msg) + # See Process.generate_memory_snapshot() class Regenerator(object): @@ -129,33 +132,35 @@ def __init__(self, g_function, *v_args, **d_args): @param d_args: Variable arguments to pass to the generator function. """ self.__g_function = g_function - self.__v_args = v_args - self.__d_args = d_args - self.__g_object = None + self.__v_args = v_args + self.__d_args = d_args + self.__g_object = None def __iter__(self): - 'x.__iter__() <==> iter(x)' + "x.__iter__() <==> iter(x)" return self def next(self): - 'x.next() -> the next value, or raise StopIteration' + "x.next() -> the next value, or raise StopIteration" if self.__g_object is None: - self.__g_object = self.__g_function( *self.__v_args, **self.__d_args ) + self.__g_object = self.__g_function(*self.__v_args, **self.__d_args) try: return self.__g_object.next() except StopIteration: self.__g_object = None raise -class StaticClass (object): + +class StaticClass(object): def __new__(cls, *argv, **argd): "Don't try to instance this class, just use the static methods." - raise NotImplementedError( - "Cannot instance static class %s" % cls.__name__) + raise NotImplementedError("Cannot instance static class %s" % cls.__name__) + + +# ============================================================================== -#============================================================================== -class PathOperations (StaticClass): +class PathOperations(StaticClass): """ Static methods for filename and pathname manipulation. """ @@ -187,7 +192,7 @@ def path_is_absolute(path): return not win32.PathIsRelative(path) @staticmethod - def make_relative(path, current = None): + def make_relative(path, current=None): """ @type path: str @param path: Absolute path. @@ -202,7 +207,7 @@ def make_relative(path, current = None): This happens when the path and the current path are not on the same disk drive or network share. """ - return win32.PathRelativePathTo(pszFrom = current, pszTo = path) + return win32.PathRelativePathTo(pszFrom=current, pszTo=path) @staticmethod def make_absolute(path): @@ -226,7 +231,7 @@ def split_extension(pathname): Tuple containing the file and extension components of the filename. """ filepart = win32.PathRemoveExtension(pathname) - extpart = win32.PathFindExtension(pathname) + extpart = win32.PathFindExtension(pathname) return (filepart, extpart) @staticmethod @@ -257,7 +262,7 @@ def split_path(path): while path: next = win32.PathFindNextComponent(path) if next: - prev = path[ : -len(next) ] + prev = path[: -len(next)] components.append(prev) path = next return components @@ -297,26 +302,24 @@ def native_to_win32_pathname(name): if name.startswith("\\??\\"): name = name[4:] elif name.startswith("\\SystemRoot\\"): - system_root_path = os.environ['SYSTEMROOT'] - if system_root_path.endswith('\\'): + system_root_path = os.environ["SYSTEMROOT"] + if system_root_path.endswith("\\"): system_root_path = system_root_path[:-1] name = system_root_path + name[11:] else: - for drive_number in compat.xrange(ord('A'), ord('Z') + 1): - drive_letter = '%c:' % drive_number + for drive_number in compat.xrange(ord("A"), ord("Z") + 1): + drive_letter = "%c:" % drive_number try: device_native_path = win32.QueryDosDevice(drive_letter) except WindowsError: e = sys.exc_info()[1] - if e.winerror in (win32.ERROR_FILE_NOT_FOUND, \ - win32.ERROR_PATH_NOT_FOUND): + if e.winerror in (win32.ERROR_FILE_NOT_FOUND, win32.ERROR_PATH_NOT_FOUND): continue raise - if not device_native_path.endswith('\\'): - device_native_path += '\\' + if not device_native_path.endswith("\\"): + device_native_path += "\\" if name.startswith(device_native_path): - name = drive_letter + '\\' + \ - name[ len(device_native_path) : ] + name = drive_letter + "\\" + name[len(device_native_path) :] break return name @@ -336,9 +339,11 @@ def pathname_to_filename(pathname): """ return win32.PathFindFileName(pathname) -#============================================================================== -class MemoryAddresses (StaticClass): +# ============================================================================== + + +class MemoryAddresses(StaticClass): """ Class to manipulate memory addresses. @@ -359,7 +364,7 @@ def pageSize(cls): pageSize = 0x1000 except NameError: pageSize = 0x1000 - cls.pageSize = pageSize # now this function won't be called again + cls.pageSize = pageSize # now this function won't be called again return pageSize @classmethod @@ -373,7 +378,7 @@ def align_address_to_page_start(cls, address): @rtype: int @return: Aligned memory address. """ - return address - ( address % cls.pageSize ) + return address - (address % cls.pageSize) @classmethod def align_address_to_page_end(cls, address): @@ -387,7 +392,7 @@ def align_address_to_page_end(cls, address): @rtype: int @return: Aligned memory address. """ - return address + cls.pageSize - ( address % cls.pageSize ) + return address + cls.pageSize - (address % cls.pageSize) @classmethod def align_address_range(cls, begin, end): @@ -431,7 +436,7 @@ def get_buffer_size_in_pages(cls, address, size): @return: Buffer size in number of pages. """ if size < 0: - size = -size + size = -size address = address - size begin, end = cls.align_address_range(address, address + size) # XXX FIXME @@ -458,12 +463,11 @@ def do_ranges_intersect(begin, end, old_begin, old_end): @rtype: bool @return: C{True} if the two ranges intersect, C{False} otherwise. """ - return (old_begin <= begin < old_end) or \ - (old_begin < end <= old_end) or \ - (begin <= old_begin < end) or \ - (begin < old_end <= end) + return (old_begin <= begin < old_end) or (old_begin < end <= old_end) or (begin <= old_begin < end) or (begin < old_end <= end) + + +# ============================================================================== -#============================================================================== def CustomAddressIterator(memory_map, condition): """ @@ -483,12 +487,13 @@ def CustomAddressIterator(memory_map, condition): """ for mbi in memory_map: if condition(mbi): - address = mbi.BaseAddress + address = mbi.BaseAddress max_addr = address + mbi.RegionSize while address < max_addr: yield address address = address + 1 + def DataAddressIterator(memory_map): """ Generator function that iterates through a memory map, returning only those @@ -501,8 +506,8 @@ def DataAddressIterator(memory_map): @rtype: generator of L{win32.MemoryBasicInformation} @return: Generator object to iterate memory blocks. """ - return CustomAddressIterator(memory_map, - win32.MemoryBasicInformation.has_content) + return CustomAddressIterator(memory_map, win32.MemoryBasicInformation.has_content) + def ImageAddressIterator(memory_map): """ @@ -516,8 +521,8 @@ def ImageAddressIterator(memory_map): @rtype: generator of L{win32.MemoryBasicInformation} @return: Generator object to iterate memory blocks. """ - return CustomAddressIterator(memory_map, - win32.MemoryBasicInformation.is_image) + return CustomAddressIterator(memory_map, win32.MemoryBasicInformation.is_image) + def MappedAddressIterator(memory_map): """ @@ -531,8 +536,8 @@ def MappedAddressIterator(memory_map): @rtype: generator of L{win32.MemoryBasicInformation} @return: Generator object to iterate memory blocks. """ - return CustomAddressIterator(memory_map, - win32.MemoryBasicInformation.is_mapped) + return CustomAddressIterator(memory_map, win32.MemoryBasicInformation.is_mapped) + def ReadableAddressIterator(memory_map): """ @@ -546,8 +551,8 @@ def ReadableAddressIterator(memory_map): @rtype: generator of L{win32.MemoryBasicInformation} @return: Generator object to iterate memory blocks. """ - return CustomAddressIterator(memory_map, - win32.MemoryBasicInformation.is_readable) + return CustomAddressIterator(memory_map, win32.MemoryBasicInformation.is_readable) + def WriteableAddressIterator(memory_map): """ @@ -563,8 +568,8 @@ def WriteableAddressIterator(memory_map): @rtype: generator of L{win32.MemoryBasicInformation} @return: Generator object to iterate memory blocks. """ - return CustomAddressIterator(memory_map, - win32.MemoryBasicInformation.is_writeable) + return CustomAddressIterator(memory_map, win32.MemoryBasicInformation.is_writeable) + def ExecutableAddressIterator(memory_map): """ @@ -580,8 +585,8 @@ def ExecutableAddressIterator(memory_map): @rtype: generator of L{win32.MemoryBasicInformation} @return: Generator object to iterate memory blocks. """ - return CustomAddressIterator(memory_map, - win32.MemoryBasicInformation.is_executable) + return CustomAddressIterator(memory_map, win32.MemoryBasicInformation.is_executable) + def ExecutableAndWriteableAddressIterator(memory_map): """ @@ -598,10 +603,10 @@ def ExecutableAndWriteableAddressIterator(memory_map): @rtype: generator of L{win32.MemoryBasicInformation} @return: Generator object to iterate memory blocks. """ - return CustomAddressIterator(memory_map, - win32.MemoryBasicInformation.is_executable_and_writeable) + return CustomAddressIterator(memory_map, win32.MemoryBasicInformation.is_executable_and_writeable) + -#============================================================================== +# ============================================================================== try: _registerMask = win32.SIZE_T(-1).value except TypeError: @@ -612,7 +617,8 @@ def ExecutableAndWriteableAddressIterator(memory_map): else: raise -class DebugRegister (StaticClass): + +class DebugRegister(StaticClass): """ Class to manipulate debug registers. Used by L{HardwareBreakpoint}. @@ -720,19 +726,19 @@ class DebugRegister (StaticClass): Bitmask to clear all meaningful bits in C{Dr6}. """ - BREAK_ON_EXECUTION = 0 - BREAK_ON_WRITE = 1 - BREAK_ON_ACCESS = 3 - BREAK_ON_IO_ACCESS = 2 + BREAK_ON_EXECUTION = 0 + BREAK_ON_WRITE = 1 + BREAK_ON_ACCESS = 3 + BREAK_ON_IO_ACCESS = 2 - WATCH_BYTE = 0 - WATCH_WORD = 1 + WATCH_BYTE = 0 + WATCH_WORD = 1 WATCH_DWORD = 3 WATCH_QWORD = 2 registerMask = _registerMask -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ ########################################################################### # http://en.wikipedia.org/wiki/Debug_register @@ -759,16 +765,16 @@ class DebugRegister (StaticClass): # Dr7 |= enableMask[register] enableMask = ( - 1 << 0, # Dr0 (bit 0) - 1 << 2, # Dr1 (bit 2) - 1 << 4, # Dr2 (bit 4) - 1 << 6, # Dr3 (bit 6) + 1 << 0, # Dr0 (bit 0) + 1 << 2, # Dr1 (bit 2) + 1 << 4, # Dr2 (bit 4) + 1 << 6, # Dr3 (bit 6) ) # Dr7 &= disableMask[register] - disableMask = tuple( [_registerMask ^ x for x in enableMask] ) # The registerMask from the class is not there in py3 + disableMask = tuple([_registerMask ^ x for x in enableMask]) # The registerMask from the class is not there in py3 try: - del x # It's not there in py3 + del x # It's not there in py3 except: pass @@ -842,14 +848,14 @@ class DebugRegister (StaticClass): # Dr7 = Dr7 & clearMask[register] clearMask = ( - registerMask ^ ( (1 << 0) + (3 << 16) + (3 << 18) ), # Dr0 - registerMask ^ ( (1 << 2) + (3 << 20) + (3 << 22) ), # Dr1 - registerMask ^ ( (1 << 4) + (3 << 24) + (3 << 26) ), # Dr2 - registerMask ^ ( (1 << 6) + (3 << 28) + (3 << 30) ), # Dr3 + registerMask ^ ((1 << 0) + (3 << 16) + (3 << 18)), # Dr0 + registerMask ^ ((1 << 2) + (3 << 20) + (3 << 22)), # Dr1 + registerMask ^ ((1 << 4) + (3 << 24) + (3 << 26)), # Dr2 + registerMask ^ ((1 << 6) + (3 << 28) + (3 << 30)), # Dr3 ) # Dr7 = Dr7 | generalDetectMask - generalDetectMask = (1 << 13) + generalDetectMask = 1 << 13 ########################################################################### # http://en.wikipedia.org/wiki/Debug_register @@ -868,10 +874,10 @@ class DebugRegister (StaticClass): # bool(Dr6 & hitMask[register]) hitMask = ( - (1 << 0), # Dr0 - (1 << 1), # Dr1 - (1 << 2), # Dr2 - (1 << 3), # Dr3 + (1 << 0), # Dr0 + (1 << 1), # Dr1 + (1 << 2), # Dr2 + (1 << 3), # Dr3 ) # bool(Dr6 & anyHitMask) @@ -881,91 +887,90 @@ class DebugRegister (StaticClass): clearHitMask = registerMask ^ hitMaskAll # bool(Dr6 & debugAccessMask) - debugAccessMask = (1 << 13) + debugAccessMask = 1 << 13 # bool(Dr6 & singleStepMask) - singleStepMask = (1 << 14) + singleStepMask = 1 << 14 # bool(Dr6 & taskSwitchMask) - taskSwitchMask = (1 << 15) + taskSwitchMask = 1 << 15 # Dr6 = Dr6 & clearDr6Mask - clearDr6Mask = registerMask ^ (hitMaskAll | \ - debugAccessMask | singleStepMask | taskSwitchMask) + clearDr6Mask = registerMask ^ (hitMaskAll | debugAccessMask | singleStepMask | taskSwitchMask) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ -############################################################################### -# -# (from the AMD64 manuals) -# -# The fields within the DebugCtlMSR register are: -# -# Last-Branch Record (LBR) - Bit 0, read/write. Software sets this bit to 1 -# to cause the processor to record the source and target addresses of the -# last control transfer taken before a debug exception occurs. The recorded -# control transfers include branch instructions, interrupts, and exceptions. -# -# Branch Single Step (BTF) - Bit 1, read/write. Software uses this bit to -# change the behavior of the rFLAGS.TF bit. When this bit is cleared to 0, -# the rFLAGS.TF bit controls instruction single stepping, (normal behavior). -# When this bit is set to 1, the rFLAGS.TF bit controls single stepping on -# control transfers. The single-stepped control transfers include branch -# instructions, interrupts, and exceptions. Control-transfer single stepping -# requires both BTF=1 and rFLAGS.TF=1. -# -# Performance-Monitoring/Breakpoint Pin-Control (PBi) - Bits 5-2, read/write. -# Software uses these bits to control the type of information reported by -# the four external performance-monitoring/breakpoint pins on the processor. -# When a PBi bit is cleared to 0, the corresponding external pin (BPi) -# reports performance-monitor information. When a PBi bit is set to 1, the -# corresponding external pin (BPi) reports breakpoint information. -# -# All remaining bits in the DebugCtlMSR register are reserved. -# -# Software can enable control-transfer single stepping by setting -# DebugCtlMSR.BTF to 1 and rFLAGS.TF to 1. The processor automatically -# disables control-transfer single stepping when a debug exception (#DB) -# occurs by clearing DebugCtlMSR.BTF to 0. rFLAGS.TF is also cleared when a -# #DB exception occurs. Before exiting the debug-exception handler, software -# must set both DebugCtlMSR.BTF and rFLAGS.TF to 1 to restart single -# stepping. -# -############################################################################### - - DebugCtlMSR = 0x1D9 - LastBranchRecord = (1 << 0) - BranchTrapFlag = (1 << 1) - PinControl = ( - (1 << 2), # PB1 - (1 << 3), # PB2 - (1 << 4), # PB3 - (1 << 5), # PB4 - ) - -############################################################################### -# -# (from the AMD64 manuals) -# -# Control-transfer recording MSRs: LastBranchToIP, LastBranchFromIP, -# LastExceptionToIP, and LastExceptionFromIP. These registers are loaded -# automatically by the processor when the DebugCtlMSR.LBR bit is set to 1. -# These MSRs are read-only. -# -# The processor automatically disables control-transfer recording when a -# debug exception (#DB) occurs by clearing DebugCtlMSR.LBR to 0. The -# contents of the control-transfer recording MSRs are not altered by the -# processor when the #DB occurs. Before exiting the debug-exception handler, -# software can set DebugCtlMSR.LBR to 1 to re-enable the recording mechanism. -# -############################################################################### + ############################################################################### + # + # (from the AMD64 manuals) + # + # The fields within the DebugCtlMSR register are: + # + # Last-Branch Record (LBR) - Bit 0, read/write. Software sets this bit to 1 + # to cause the processor to record the source and target addresses of the + # last control transfer taken before a debug exception occurs. The recorded + # control transfers include branch instructions, interrupts, and exceptions. + # + # Branch Single Step (BTF) - Bit 1, read/write. Software uses this bit to + # change the behavior of the rFLAGS.TF bit. When this bit is cleared to 0, + # the rFLAGS.TF bit controls instruction single stepping, (normal behavior). + # When this bit is set to 1, the rFLAGS.TF bit controls single stepping on + # control transfers. The single-stepped control transfers include branch + # instructions, interrupts, and exceptions. Control-transfer single stepping + # requires both BTF=1 and rFLAGS.TF=1. + # + # Performance-Monitoring/Breakpoint Pin-Control (PBi) - Bits 5-2, read/write. + # Software uses these bits to control the type of information reported by + # the four external performance-monitoring/breakpoint pins on the processor. + # When a PBi bit is cleared to 0, the corresponding external pin (BPi) + # reports performance-monitor information. When a PBi bit is set to 1, the + # corresponding external pin (BPi) reports breakpoint information. + # + # All remaining bits in the DebugCtlMSR register are reserved. + # + # Software can enable control-transfer single stepping by setting + # DebugCtlMSR.BTF to 1 and rFLAGS.TF to 1. The processor automatically + # disables control-transfer single stepping when a debug exception (#DB) + # occurs by clearing DebugCtlMSR.BTF to 0. rFLAGS.TF is also cleared when a + # #DB exception occurs. Before exiting the debug-exception handler, software + # must set both DebugCtlMSR.BTF and rFLAGS.TF to 1 to restart single + # stepping. + # + ############################################################################### + + DebugCtlMSR = 0x1D9 + LastBranchRecord = 1 << 0 + BranchTrapFlag = 1 << 1 + PinControl = ( + (1 << 2), # PB1 + (1 << 3), # PB2 + (1 << 4), # PB3 + (1 << 5), # PB4 + ) + + ############################################################################### + # + # (from the AMD64 manuals) + # + # Control-transfer recording MSRs: LastBranchToIP, LastBranchFromIP, + # LastExceptionToIP, and LastExceptionFromIP. These registers are loaded + # automatically by the processor when the DebugCtlMSR.LBR bit is set to 1. + # These MSRs are read-only. + # + # The processor automatically disables control-transfer recording when a + # debug exception (#DB) occurs by clearing DebugCtlMSR.LBR to 0. The + # contents of the control-transfer recording MSRs are not altered by the + # processor when the #DB occurs. Before exiting the debug-exception handler, + # software can set DebugCtlMSR.LBR to 1 to re-enable the recording mechanism. + # + ############################################################################### - LastBranchToIP = 0x1DC - LastBranchFromIP = 0x1DB - LastExceptionToIP = 0x1DE + LastBranchToIP = 0x1DC + LastBranchFromIP = 0x1DB + LastExceptionToIP = 0x1DE LastExceptionFromIP = 0x1DD -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ @classmethod def clear_bp(cls, ctx, register): @@ -980,8 +985,8 @@ def clear_bp(cls, ctx, register): @type register: int @param register: Slot (debug register) for hardware breakpoint. """ - ctx['Dr7'] &= cls.clearMask[register] - ctx['Dr%d' % register] = 0 + ctx["Dr7"] &= cls.clearMask[register] + ctx["Dr%d" % register] = 0 @classmethod def set_bp(cls, ctx, register, address, trigger, watch): @@ -1005,7 +1010,7 @@ def set_bp(cls, ctx, register, address, trigger, watch): @type watch: int @param watch: Watch flag. See L{HardwareBreakpoint.validWatchSizes}. """ - Dr7 = ctx['Dr7'] + Dr7 = ctx["Dr7"] Dr7 |= cls.enableMask[register] orMask, andMask = cls.triggerMask[register][trigger] Dr7 &= andMask @@ -1013,8 +1018,8 @@ def set_bp(cls, ctx, register, address, trigger, watch): orMask, andMask = cls.watchMask[register][watch] Dr7 &= andMask Dr7 |= orMask - ctx['Dr7'] = Dr7 - ctx['Dr%d' % register] = address + ctx["Dr7"] = Dr7 + ctx["Dr%d" % register] = address @classmethod def find_slot(cls, ctx): @@ -1029,7 +1034,7 @@ def find_slot(cls, ctx): @rtype: int @return: Slot (debug register) for hardware breakpoint. """ - Dr7 = ctx['Dr7'] + Dr7 = ctx["Dr7"] slot = 0 for m in cls.enableMask: if (Dr7 & m) == 0: diff --git a/pydevd_attach_to_process/winappdbg/win32/__init__.py b/pydevd_attach_to_process/winappdbg/win32/__init__.py index b5536c176..a46153b42 100644 --- a/pydevd_attach_to_process/winappdbg/win32/__init__.py +++ b/pydevd_attach_to_process/winappdbg/win32/__init__.py @@ -45,16 +45,16 @@ from winappdbg.win32 import dbghelp from winappdbg.win32 import ntdll -from winappdbg.win32.defines import * -from winappdbg.win32.kernel32 import * -from winappdbg.win32.user32 import * -from winappdbg.win32.advapi32 import * -from winappdbg.win32.wtsapi32 import * -from winappdbg.win32.shell32 import * -from winappdbg.win32.shlwapi import * -from winappdbg.win32.psapi import * -from winappdbg.win32.dbghelp import * -from winappdbg.win32.ntdll import * +from winappdbg.win32.defines import * +from winappdbg.win32.kernel32 import * +from winappdbg.win32.user32 import * +from winappdbg.win32.advapi32 import * +from winappdbg.win32.wtsapi32 import * +from winappdbg.win32.shell32 import * +from winappdbg.win32.shlwapi import * +from winappdbg.win32.psapi import * +from winappdbg.win32.dbghelp import * +from winappdbg.win32.ntdll import * # This calculates the list of exported symbols. _all = set() @@ -68,5 +68,5 @@ _all.update(psapi._all) _all.update(dbghelp._all) _all.update(ntdll._all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() diff --git a/pydevd_attach_to_process/winappdbg/win32/advapi32.py b/pydevd_attach_to_process/winappdbg/win32/advapi32.py index 4e49889ee..12a6f261a 100644 --- a/pydevd_attach_to_process/winappdbg/win32/advapi32.py +++ b/pydevd_attach_to_process/winappdbg/win32/advapi32.py @@ -40,116 +40,125 @@ # XXX TODO # + add transacted registry operations -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== -#--- Constants ---------------------------------------------------------------- +# --- Constants ---------------------------------------------------------------- # Privilege constants -SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege" -SE_AUDIT_NAME = "SeAuditPrivilege" -SE_BACKUP_NAME = "SeBackupPrivilege" -SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege" -SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege" -SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege" -SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege" -SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege" -SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege" -SE_DEBUG_NAME = "SeDebugPrivilege" -SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege" -SE_IMPERSONATE_NAME = "SeImpersonatePrivilege" -SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege" -SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege" -SE_INC_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege" -SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege" -SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege" -SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege" -SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege" -SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege" -SE_RELABEL_NAME = "SeRelabelPrivilege" -SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege" -SE_RESTORE_NAME = "SeRestorePrivilege" -SE_SECURITY_NAME = "SeSecurityPrivilege" -SE_SHUTDOWN_NAME = "SeShutdownPrivilege" -SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege" -SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege" -SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege" -SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege" -SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege" -SE_TCB_NAME = "SeTcbPrivilege" -SE_TIME_ZONE_NAME = "SeTimeZonePrivilege" -SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege" -SE_UNDOCK_NAME = "SeUndockPrivilege" -SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege" +SE_ASSIGNPRIMARYTOKEN_NAME = "SeAssignPrimaryTokenPrivilege" +SE_AUDIT_NAME = "SeAuditPrivilege" +SE_BACKUP_NAME = "SeBackupPrivilege" +SE_CHANGE_NOTIFY_NAME = "SeChangeNotifyPrivilege" +SE_CREATE_GLOBAL_NAME = "SeCreateGlobalPrivilege" +SE_CREATE_PAGEFILE_NAME = "SeCreatePagefilePrivilege" +SE_CREATE_PERMANENT_NAME = "SeCreatePermanentPrivilege" +SE_CREATE_SYMBOLIC_LINK_NAME = "SeCreateSymbolicLinkPrivilege" +SE_CREATE_TOKEN_NAME = "SeCreateTokenPrivilege" +SE_DEBUG_NAME = "SeDebugPrivilege" +SE_ENABLE_DELEGATION_NAME = "SeEnableDelegationPrivilege" +SE_IMPERSONATE_NAME = "SeImpersonatePrivilege" +SE_INC_BASE_PRIORITY_NAME = "SeIncreaseBasePriorityPrivilege" +SE_INCREASE_QUOTA_NAME = "SeIncreaseQuotaPrivilege" +SE_INC_WORKING_SET_NAME = "SeIncreaseWorkingSetPrivilege" +SE_LOAD_DRIVER_NAME = "SeLoadDriverPrivilege" +SE_LOCK_MEMORY_NAME = "SeLockMemoryPrivilege" +SE_MACHINE_ACCOUNT_NAME = "SeMachineAccountPrivilege" +SE_MANAGE_VOLUME_NAME = "SeManageVolumePrivilege" +SE_PROF_SINGLE_PROCESS_NAME = "SeProfileSingleProcessPrivilege" +SE_RELABEL_NAME = "SeRelabelPrivilege" +SE_REMOTE_SHUTDOWN_NAME = "SeRemoteShutdownPrivilege" +SE_RESTORE_NAME = "SeRestorePrivilege" +SE_SECURITY_NAME = "SeSecurityPrivilege" +SE_SHUTDOWN_NAME = "SeShutdownPrivilege" +SE_SYNC_AGENT_NAME = "SeSyncAgentPrivilege" +SE_SYSTEM_ENVIRONMENT_NAME = "SeSystemEnvironmentPrivilege" +SE_SYSTEM_PROFILE_NAME = "SeSystemProfilePrivilege" +SE_SYSTEMTIME_NAME = "SeSystemtimePrivilege" +SE_TAKE_OWNERSHIP_NAME = "SeTakeOwnershipPrivilege" +SE_TCB_NAME = "SeTcbPrivilege" +SE_TIME_ZONE_NAME = "SeTimeZonePrivilege" +SE_TRUSTED_CREDMAN_ACCESS_NAME = "SeTrustedCredManAccessPrivilege" +SE_UNDOCK_NAME = "SeUndockPrivilege" +SE_UNSOLICITED_INPUT_NAME = "SeUnsolicitedInputPrivilege" SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001 -SE_PRIVILEGE_ENABLED = 0x00000002 -SE_PRIVILEGE_REMOVED = 0x00000004 -SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000 +SE_PRIVILEGE_ENABLED = 0x00000002 +SE_PRIVILEGE_REMOVED = 0x00000004 +SE_PRIVILEGE_USED_FOR_ACCESS = 0x80000000 -TOKEN_ADJUST_PRIVILEGES = 0x00000020 +TOKEN_ADJUST_PRIVILEGES = 0x00000020 -LOGON_WITH_PROFILE = 0x00000001 -LOGON_NETCREDENTIALS_ONLY = 0x00000002 +LOGON_WITH_PROFILE = 0x00000001 +LOGON_NETCREDENTIALS_ONLY = 0x00000002 # Token access rights -TOKEN_ASSIGN_PRIMARY = 0x0001 -TOKEN_DUPLICATE = 0x0002 -TOKEN_IMPERSONATE = 0x0004 -TOKEN_QUERY = 0x0008 -TOKEN_QUERY_SOURCE = 0x0010 +TOKEN_ASSIGN_PRIMARY = 0x0001 +TOKEN_DUPLICATE = 0x0002 +TOKEN_IMPERSONATE = 0x0004 +TOKEN_QUERY = 0x0008 +TOKEN_QUERY_SOURCE = 0x0010 TOKEN_ADJUST_PRIVILEGES = 0x0020 -TOKEN_ADJUST_GROUPS = 0x0040 -TOKEN_ADJUST_DEFAULT = 0x0080 -TOKEN_ADJUST_SESSIONID = 0x0100 -TOKEN_READ = (STANDARD_RIGHTS_READ | TOKEN_QUERY) -TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | - TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | - TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_DEFAULT | - TOKEN_ADJUST_SESSIONID) +TOKEN_ADJUST_GROUPS = 0x0040 +TOKEN_ADJUST_DEFAULT = 0x0080 +TOKEN_ADJUST_SESSIONID = 0x0100 +TOKEN_READ = STANDARD_RIGHTS_READ | TOKEN_QUERY +TOKEN_ALL_ACCESS = ( + STANDARD_RIGHTS_REQUIRED + | TOKEN_ASSIGN_PRIMARY + | TOKEN_DUPLICATE + | TOKEN_IMPERSONATE + | TOKEN_QUERY + | TOKEN_QUERY_SOURCE + | TOKEN_ADJUST_PRIVILEGES + | TOKEN_ADJUST_GROUPS + | TOKEN_ADJUST_DEFAULT + | TOKEN_ADJUST_SESSIONID +) # Predefined HKEY values -HKEY_CLASSES_ROOT = 0x80000000 -HKEY_CURRENT_USER = 0x80000001 -HKEY_LOCAL_MACHINE = 0x80000002 -HKEY_USERS = 0x80000003 -HKEY_PERFORMANCE_DATA = 0x80000004 -HKEY_CURRENT_CONFIG = 0x80000005 +HKEY_CLASSES_ROOT = 0x80000000 +HKEY_CURRENT_USER = 0x80000001 +HKEY_LOCAL_MACHINE = 0x80000002 +HKEY_USERS = 0x80000003 +HKEY_PERFORMANCE_DATA = 0x80000004 +HKEY_CURRENT_CONFIG = 0x80000005 # Registry access rights -KEY_ALL_ACCESS = 0xF003F -KEY_CREATE_LINK = 0x0020 -KEY_CREATE_SUB_KEY = 0x0004 -KEY_ENUMERATE_SUB_KEYS = 0x0008 -KEY_EXECUTE = 0x20019 -KEY_NOTIFY = 0x0010 -KEY_QUERY_VALUE = 0x0001 -KEY_READ = 0x20019 -KEY_SET_VALUE = 0x0002 -KEY_WOW64_32KEY = 0x0200 -KEY_WOW64_64KEY = 0x0100 -KEY_WRITE = 0x20006 +KEY_ALL_ACCESS = 0xF003F +KEY_CREATE_LINK = 0x0020 +KEY_CREATE_SUB_KEY = 0x0004 +KEY_ENUMERATE_SUB_KEYS = 0x0008 +KEY_EXECUTE = 0x20019 +KEY_NOTIFY = 0x0010 +KEY_QUERY_VALUE = 0x0001 +KEY_READ = 0x20019 +KEY_SET_VALUE = 0x0002 +KEY_WOW64_32KEY = 0x0200 +KEY_WOW64_64KEY = 0x0100 +KEY_WRITE = 0x20006 # Registry value types -REG_NONE = 0 -REG_SZ = 1 -REG_EXPAND_SZ = 2 -REG_BINARY = 3 -REG_DWORD = 4 -REG_DWORD_LITTLE_ENDIAN = REG_DWORD -REG_DWORD_BIG_ENDIAN = 5 -REG_LINK = 6 -REG_MULTI_SZ = 7 -REG_RESOURCE_LIST = 8 -REG_FULL_RESOURCE_DESCRIPTOR = 9 -REG_RESOURCE_REQUIREMENTS_LIST = 10 -REG_QWORD = 11 -REG_QWORD_LITTLE_ENDIAN = REG_QWORD - -#--- TOKEN_PRIVILEGE structure ------------------------------------------------ +REG_NONE = 0 +REG_SZ = 1 +REG_EXPAND_SZ = 2 +REG_BINARY = 3 +REG_DWORD = 4 +REG_DWORD_LITTLE_ENDIAN = REG_DWORD +REG_DWORD_BIG_ENDIAN = 5 +REG_LINK = 6 +REG_MULTI_SZ = 7 +REG_RESOURCE_LIST = 8 +REG_FULL_RESOURCE_DESCRIPTOR = 9 +REG_RESOURCE_REQUIREMENTS_LIST = 10 +REG_QWORD = 11 +REG_QWORD_LITTLE_ENDIAN = REG_QWORD + +# --- TOKEN_PRIVILEGE structure ------------------------------------------------ + # typedef struct _LUID { # DWORD LowPart; @@ -158,12 +167,14 @@ # *PLUID; class LUID(Structure): _fields_ = [ - ("LowPart", DWORD), - ("HighPart", LONG), + ("LowPart", DWORD), + ("HighPart", LONG), ] + PLUID = POINTER(LUID) + # typedef struct _LUID_AND_ATTRIBUTES { # LUID Luid; # DWORD Attributes; @@ -171,10 +182,11 @@ class LUID(Structure): # *PLUID_AND_ATTRIBUTES; class LUID_AND_ATTRIBUTES(Structure): _fields_ = [ - ("Luid", LUID), - ("Attributes", DWORD), + ("Luid", LUID), + ("Attributes", DWORD), ] + # typedef struct _TOKEN_PRIVILEGES { # DWORD PrivilegeCount; # LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; @@ -182,15 +194,16 @@ class LUID_AND_ATTRIBUTES(Structure): # *PTOKEN_PRIVILEGES; class TOKEN_PRIVILEGES(Structure): _fields_ = [ - ("PrivilegeCount", DWORD), -## ("Privileges", LUID_AND_ATTRIBUTES * ANYSIZE_ARRAY), - ("Privileges", LUID_AND_ATTRIBUTES), + ("PrivilegeCount", DWORD), + ## ("Privileges", LUID_AND_ATTRIBUTES * ANYSIZE_ARRAY), + ("Privileges", LUID_AND_ATTRIBUTES), ] # See comments on AdjustTokenPrivileges about this structure + PTOKEN_PRIVILEGES = POINTER(TOKEN_PRIVILEGES) -#--- GetTokenInformation enums and structures --------------------------------- +# --- GetTokenInformation enums and structures --------------------------------- # typedef enum _TOKEN_INFORMATION_CLASS { # TokenUser = 1, @@ -238,47 +251,47 @@ class TOKEN_PRIVILEGES(Structure): TOKEN_INFORMATION_CLASS = ctypes.c_int -TokenUser = 1 -TokenGroups = 2 -TokenPrivileges = 3 -TokenOwner = 4 -TokenPrimaryGroup = 5 -TokenDefaultDacl = 6 -TokenSource = 7 -TokenType = 8 -TokenImpersonationLevel = 9 -TokenStatistics = 10 -TokenRestrictedSids = 11 -TokenSessionId = 12 -TokenGroupsAndPrivileges = 13 -TokenSessionReference = 14 -TokenSandBoxInert = 15 -TokenAuditPolicy = 16 -TokenOrigin = 17 -TokenElevationType = 18 -TokenLinkedToken = 19 -TokenElevation = 20 -TokenHasRestrictions = 21 -TokenAccessInformation = 22 -TokenVirtualizationAllowed = 23 -TokenVirtualizationEnabled = 24 -TokenIntegrityLevel = 25 -TokenUIAccess = 26 -TokenMandatoryPolicy = 27 -TokenLogonSid = 28 -TokenIsAppContainer = 29 -TokenCapabilities = 30 -TokenAppContainerSid = 31 -TokenAppContainerNumber = 32 -TokenUserClaimAttributes = 33 -TokenDeviceClaimAttributes = 34 -TokenRestrictedUserClaimAttributes = 35 -TokenRestrictedDeviceClaimAttributes = 36 -TokenDeviceGroups = 37 -TokenRestrictedDeviceGroups = 38 -TokenSecurityAttributes = 39 -TokenIsRestricted = 40 -MaxTokenInfoClass = 41 +TokenUser = 1 +TokenGroups = 2 +TokenPrivileges = 3 +TokenOwner = 4 +TokenPrimaryGroup = 5 +TokenDefaultDacl = 6 +TokenSource = 7 +TokenType = 8 +TokenImpersonationLevel = 9 +TokenStatistics = 10 +TokenRestrictedSids = 11 +TokenSessionId = 12 +TokenGroupsAndPrivileges = 13 +TokenSessionReference = 14 +TokenSandBoxInert = 15 +TokenAuditPolicy = 16 +TokenOrigin = 17 +TokenElevationType = 18 +TokenLinkedToken = 19 +TokenElevation = 20 +TokenHasRestrictions = 21 +TokenAccessInformation = 22 +TokenVirtualizationAllowed = 23 +TokenVirtualizationEnabled = 24 +TokenIntegrityLevel = 25 +TokenUIAccess = 26 +TokenMandatoryPolicy = 27 +TokenLogonSid = 28 +TokenIsAppContainer = 29 +TokenCapabilities = 30 +TokenAppContainerSid = 31 +TokenAppContainerNumber = 32 +TokenUserClaimAttributes = 33 +TokenDeviceClaimAttributes = 34 +TokenRestrictedUserClaimAttributes = 35 +TokenRestrictedDeviceClaimAttributes = 36 +TokenDeviceGroups = 37 +TokenRestrictedDeviceGroups = 38 +TokenSecurityAttributes = 39 +TokenIsRestricted = 40 +MaxTokenInfoClass = 41 # typedef enum tagTOKEN_TYPE { # TokenPrimary = 1, @@ -288,8 +301,8 @@ class TOKEN_PRIVILEGES(Structure): TOKEN_TYPE = ctypes.c_int PTOKEN_TYPE = POINTER(TOKEN_TYPE) -TokenPrimary = 1 -TokenImpersonation = 2 +TokenPrimary = 1 +TokenImpersonation = 2 # typedef enum { # TokenElevationTypeDefault = 1, @@ -297,9 +310,9 @@ class TOKEN_PRIVILEGES(Structure): # TokenElevationTypeLimited # } TOKEN_ELEVATION_TYPE , *PTOKEN_ELEVATION_TYPE; -TokenElevationTypeDefault = 1 -TokenElevationTypeFull = 2 -TokenElevationTypeLimited = 3 +TokenElevationTypeDefault = 1 +TokenElevationTypeFull = 2 +TokenElevationTypeLimited = 3 TOKEN_ELEVATION_TYPE = ctypes.c_int PTOKEN_ELEVATION_TYPE = POINTER(TOKEN_ELEVATION_TYPE) @@ -311,25 +324,29 @@ class TOKEN_PRIVILEGES(Structure): # SecurityDelegation # } SECURITY_IMPERSONATION_LEVEL, *PSECURITY_IMPERSONATION_LEVEL; -SecurityAnonymous = 0 -SecurityIdentification = 1 -SecurityImpersonation = 2 -SecurityDelegation = 3 +SecurityAnonymous = 0 +SecurityIdentification = 1 +SecurityImpersonation = 2 +SecurityDelegation = 3 SECURITY_IMPERSONATION_LEVEL = ctypes.c_int PSECURITY_IMPERSONATION_LEVEL = POINTER(SECURITY_IMPERSONATION_LEVEL) + # typedef struct _SID_AND_ATTRIBUTES { # PSID Sid; # DWORD Attributes; # } SID_AND_ATTRIBUTES, *PSID_AND_ATTRIBUTES; class SID_AND_ATTRIBUTES(Structure): _fields_ = [ - ("Sid", PSID), - ("Attributes", DWORD), + ("Sid", PSID), + ("Attributes", DWORD), ] + + PSID_AND_ATTRIBUTES = POINTER(SID_AND_ATTRIBUTES) + # typedef struct _TOKEN_USER { # SID_AND_ATTRIBUTES User; # } TOKEN_USER, *PTOKEN_USER; @@ -337,8 +354,11 @@ class TOKEN_USER(Structure): _fields_ = [ ("User", SID_AND_ATTRIBUTES), ] + + PTOKEN_USER = POINTER(TOKEN_USER) + # typedef struct _TOKEN_MANDATORY_LABEL { # SID_AND_ATTRIBUTES Label; # } TOKEN_MANDATORY_LABEL, *PTOKEN_MANDATORY_LABEL; @@ -346,8 +366,11 @@ class TOKEN_MANDATORY_LABEL(Structure): _fields_ = [ ("Label", SID_AND_ATTRIBUTES), ] + + PTOKEN_MANDATORY_LABEL = POINTER(TOKEN_MANDATORY_LABEL) + # typedef struct _TOKEN_OWNER { # PSID Owner; # } TOKEN_OWNER, *PTOKEN_OWNER; @@ -355,8 +378,11 @@ class TOKEN_OWNER(Structure): _fields_ = [ ("Owner", PSID), ] + + PTOKEN_OWNER = POINTER(TOKEN_OWNER) + # typedef struct _TOKEN_PRIMARY_GROUP { # PSID PrimaryGroup; # } TOKEN_PRIMARY_GROUP, *PTOKEN_PRIMARY_GROUP; @@ -364,8 +390,11 @@ class TOKEN_PRIMARY_GROUP(Structure): _fields_ = [ ("PrimaryGroup", PSID), ] + + PTOKEN_PRIMARY_GROUP = POINTER(TOKEN_PRIMARY_GROUP) + # typedef struct _TOKEN_APPCONTAINER_INFORMATION { # PSID TokenAppContainer; # } TOKEN_APPCONTAINER_INFORMATION, *PTOKEN_APPCONTAINER_INFORMATION; @@ -373,8 +402,11 @@ class TOKEN_APPCONTAINER_INFORMATION(Structure): _fields_ = [ ("TokenAppContainer", PSID), ] + + PTOKEN_APPCONTAINER_INFORMATION = POINTER(TOKEN_APPCONTAINER_INFORMATION) + # typedef struct _TOKEN_ORIGIN { # LUID OriginatingLogonSession; # } TOKEN_ORIGIN, *PTOKEN_ORIGIN; @@ -382,8 +414,11 @@ class TOKEN_ORIGIN(Structure): _fields_ = [ ("OriginatingLogonSession", LUID), ] + + PTOKEN_ORIGIN = POINTER(TOKEN_ORIGIN) + # typedef struct _TOKEN_LINKED_TOKEN { # HANDLE LinkedToken; # } TOKEN_LINKED_TOKEN, *PTOKEN_LINKED_TOKEN; @@ -391,8 +426,11 @@ class TOKEN_LINKED_TOKEN(Structure): _fields_ = [ ("LinkedToken", HANDLE), ] + + PTOKEN_LINKED_TOKEN = POINTER(TOKEN_LINKED_TOKEN) + # typedef struct _TOKEN_STATISTICS { # LUID TokenId; # LUID AuthenticationId; @@ -407,20 +445,22 @@ class TOKEN_LINKED_TOKEN(Structure): # } TOKEN_STATISTICS, *PTOKEN_STATISTICS; class TOKEN_STATISTICS(Structure): _fields_ = [ - ("TokenId", LUID), - ("AuthenticationId", LUID), - ("ExpirationTime", LONGLONG), # LARGE_INTEGER - ("TokenType", TOKEN_TYPE), - ("ImpersonationLevel", SECURITY_IMPERSONATION_LEVEL), - ("DynamicCharged", DWORD), - ("DynamicAvailable", DWORD), - ("GroupCount", DWORD), - ("PrivilegeCount", DWORD), - ("ModifiedId", LUID), + ("TokenId", LUID), + ("AuthenticationId", LUID), + ("ExpirationTime", LONGLONG), # LARGE_INTEGER + ("TokenType", TOKEN_TYPE), + ("ImpersonationLevel", SECURITY_IMPERSONATION_LEVEL), + ("DynamicCharged", DWORD), + ("DynamicAvailable", DWORD), + ("GroupCount", DWORD), + ("PrivilegeCount", DWORD), + ("ModifiedId", LUID), ] + + PTOKEN_STATISTICS = POINTER(TOKEN_STATISTICS) -#--- SID_NAME_USE enum -------------------------------------------------------- +# --- SID_NAME_USE enum -------------------------------------------------------- # typedef enum _SID_NAME_USE { # SidTypeUser = 1, @@ -435,27 +475,27 @@ class TOKEN_STATISTICS(Structure): # SidTypeLabel # } SID_NAME_USE, *PSID_NAME_USE; -SidTypeUser = 1 -SidTypeGroup = 2 -SidTypeDomain = 3 -SidTypeAlias = 4 -SidTypeWellKnownGroup = 5 -SidTypeDeletedAccount = 6 -SidTypeInvalid = 7 -SidTypeUnknown = 8 -SidTypeComputer = 9 -SidTypeLabel = 10 - -#--- WAITCHAIN_NODE_INFO structure and types ---------------------------------- - -WCT_MAX_NODE_COUNT = 16 -WCT_OBJNAME_LENGTH = 128 -WCT_ASYNC_OPEN_FLAG = 1 -WCTP_OPEN_ALL_FLAGS = WCT_ASYNC_OPEN_FLAG -WCT_OUT_OF_PROC_FLAG = 1 +SidTypeUser = 1 +SidTypeGroup = 2 +SidTypeDomain = 3 +SidTypeAlias = 4 +SidTypeWellKnownGroup = 5 +SidTypeDeletedAccount = 6 +SidTypeInvalid = 7 +SidTypeUnknown = 8 +SidTypeComputer = 9 +SidTypeLabel = 10 + +# --- WAITCHAIN_NODE_INFO structure and types ---------------------------------- + +WCT_MAX_NODE_COUNT = 16 +WCT_OBJNAME_LENGTH = 128 +WCT_ASYNC_OPEN_FLAG = 1 +WCTP_OPEN_ALL_FLAGS = WCT_ASYNC_OPEN_FLAG +WCT_OUT_OF_PROC_FLAG = 1 WCT_OUT_OF_PROC_COM_FLAG = 2 -WCT_OUT_OF_PROC_CS_FLAG = 4 -WCTP_GETINFO_ALL_FLAGS = WCT_OUT_OF_PROC_FLAG | WCT_OUT_OF_PROC_COM_FLAG | WCT_OUT_OF_PROC_CS_FLAG +WCT_OUT_OF_PROC_CS_FLAG = 4 +WCTP_GETINFO_ALL_FLAGS = WCT_OUT_OF_PROC_FLAG | WCT_OUT_OF_PROC_COM_FLAG | WCT_OUT_OF_PROC_CS_FLAG HWCT = LPVOID @@ -474,19 +514,19 @@ class TOKEN_STATISTICS(Structure): # WctMaxType # } WCT_OBJECT_TYPE; -WCT_OBJECT_TYPE = DWORD +WCT_OBJECT_TYPE = DWORD -WctCriticalSectionType = 1 -WctSendMessageType = 2 -WctMutexType = 3 -WctAlpcType = 4 -WctComType = 5 -WctThreadWaitType = 6 -WctProcessWaitType = 7 -WctThreadType = 8 -WctComActivationType = 9 -WctUnknownType = 10 -WctMaxType = 11 +WctCriticalSectionType = 1 +WctSendMessageType = 2 +WctMutexType = 3 +WctAlpcType = 4 +WctComType = 5 +WctThreadWaitType = 6 +WctProcessWaitType = 7 +WctThreadType = 8 +WctComActivationType = 9 +WctUnknownType = 10 +WctMaxType = 11 # typedef enum _WCT_OBJECT_STATUS # { @@ -503,19 +543,19 @@ class TOKEN_STATISTICS(Structure): # WctStatusMax # } WCT_OBJECT_STATUS; -WCT_OBJECT_STATUS = DWORD +WCT_OBJECT_STATUS = DWORD -WctStatusNoAccess = 1 # ACCESS_DENIED for this object -WctStatusRunning = 2 # Thread status -WctStatusBlocked = 3 # Thread status -WctStatusPidOnly = 4 # Thread status -WctStatusPidOnlyRpcss = 5 # Thread status -WctStatusOwned = 6 # Dispatcher object status -WctStatusNotOwned = 7 # Dispatcher object status -WctStatusAbandoned = 8 # Dispatcher object status -WctStatusUnknown = 9 # All objects -WctStatusError = 10 # All objects -WctStatusMax = 11 +WctStatusNoAccess = 1 # ACCESS_DENIED for this object +WctStatusRunning = 2 # Thread status +WctStatusBlocked = 3 # Thread status +WctStatusPidOnly = 4 # Thread status +WctStatusPidOnlyRpcss = 5 # Thread status +WctStatusOwned = 6 # Dispatcher object status +WctStatusNotOwned = 7 # Dispatcher object status +WctStatusAbandoned = 8 # Dispatcher object status +WctStatusUnknown = 9 # All objects +WctStatusError = 10 # All objects +WctStatusMax = 11 # typedef struct _WAITCHAIN_NODE_INFO { # WCT_OBJECT_TYPE ObjectType; @@ -535,37 +575,43 @@ class TOKEN_STATISTICS(Structure): # } ; # }WAITCHAIN_NODE_INFO, *PWAITCHAIN_NODE_INFO; + class _WAITCHAIN_NODE_INFO_STRUCT_1(Structure): _fields_ = [ - ("ObjectName", WCHAR * WCT_OBJNAME_LENGTH), - ("Timeout", LONGLONG), # LARGE_INTEGER - ("Alertable", BOOL), + ("ObjectName", WCHAR * WCT_OBJNAME_LENGTH), + ("Timeout", LONGLONG), # LARGE_INTEGER + ("Alertable", BOOL), ] + class _WAITCHAIN_NODE_INFO_STRUCT_2(Structure): _fields_ = [ - ("ProcessId", DWORD), - ("ThreadId", DWORD), - ("WaitTime", DWORD), + ("ProcessId", DWORD), + ("ThreadId", DWORD), + ("WaitTime", DWORD), ("ContextSwitches", DWORD), ] + class _WAITCHAIN_NODE_INFO_UNION(Union): _fields_ = [ - ("LockObject", _WAITCHAIN_NODE_INFO_STRUCT_1), - ("ThreadObject", _WAITCHAIN_NODE_INFO_STRUCT_2), + ("LockObject", _WAITCHAIN_NODE_INFO_STRUCT_1), + ("ThreadObject", _WAITCHAIN_NODE_INFO_STRUCT_2), ] + class WAITCHAIN_NODE_INFO(Structure): _fields_ = [ - ("ObjectType", WCT_OBJECT_TYPE), - ("ObjectStatus", WCT_OBJECT_STATUS), - ("u", _WAITCHAIN_NODE_INFO_UNION), + ("ObjectType", WCT_OBJECT_TYPE), + ("ObjectStatus", WCT_OBJECT_STATUS), + ("u", _WAITCHAIN_NODE_INFO_UNION), ] + PWAITCHAIN_NODE_INFO = POINTER(WAITCHAIN_NODE_INFO) -class WaitChainNodeInfo (object): + +class WaitChainNodeInfo(object): """ Represents a node in the wait chain. @@ -624,11 +670,11 @@ class WaitChainNodeInfo (object): @ivar ContextSwitches: Number of context switches. """ - #@type Timeout: int - #@ivar Timeout: Currently not documented in MSDN. + # @type Timeout: int + # @ivar Timeout: Currently not documented in MSDN. # - #@type Alertable: bool - #@ivar Alertable: Currently not documented in MSDN. + # @type Alertable: bool + # @ivar Alertable: Currently not documented in MSDN. # TODO: __repr__ @@ -640,13 +686,14 @@ def __init__(self, aStructure): self.ThreadId = aStructure.u.ThreadObject.ThreadId self.WaitTime = aStructure.u.ThreadObject.WaitTime self.ContextSwitches = aStructure.u.ThreadObject.ContextSwitches - self.ObjectName = u'' + self.ObjectName = "" else: self.ObjectName = aStructure.u.LockObject.ObjectName.value - #self.Timeout = aStructure.u.LockObject.Timeout - #self.Alertable = bool(aStructure.u.LockObject.Alertable) + # self.Timeout = aStructure.u.LockObject.Timeout + # self.Alertable = bool(aStructure.u.LockObject.Alertable) -class ThreadWaitChainSessionHandle (Handle): + +class ThreadWaitChainSessionHandle(Handle): """ Thread wait chain session handle. @@ -655,13 +702,12 @@ class ThreadWaitChainSessionHandle (Handle): @see: L{Handle} """ - def __init__(self, aHandle = None): + def __init__(self, aHandle=None): """ @type aHandle: int @param aHandle: Win32 handle value. """ - super(ThreadWaitChainSessionHandle, self).__init__(aHandle, - bOwnership = True) + super(ThreadWaitChainSessionHandle, self).__init__(aHandle, bOwnership=True) def _close(self): if self.value is None: @@ -671,7 +717,7 @@ def _close(self): def dup(self): raise NotImplementedError() - def wait(self, dwMilliseconds = None): + def wait(self, dwMilliseconds=None): raise NotImplementedError() @property @@ -682,19 +728,20 @@ def inherit(self): def protectFromClose(self): return False -#--- Privilege dropping ------------------------------------------------------- + +# --- Privilege dropping ------------------------------------------------------- SAFER_LEVEL_HANDLE = HANDLE SAFER_SCOPEID_MACHINE = 1 -SAFER_SCOPEID_USER = 2 +SAFER_SCOPEID_USER = 2 SAFER_LEVEL_OPEN = 1 -SAFER_LEVELID_DISALLOWED = 0x00000 -SAFER_LEVELID_UNTRUSTED = 0x01000 -SAFER_LEVELID_CONSTRAINED = 0x10000 -SAFER_LEVELID_NORMALUSER = 0x20000 +SAFER_LEVELID_DISALLOWED = 0x00000 +SAFER_LEVELID_UNTRUSTED = 0x01000 +SAFER_LEVELID_CONSTRAINED = 0x10000 +SAFER_LEVELID_NORMALUSER = 0x20000 SAFER_LEVELID_FULLYTRUSTED = 0x40000 SAFER_POLICY_INFO_CLASS = DWORD @@ -705,150 +752,151 @@ def protectFromClose(self): SaferPolicyScopeFlags = 5 SAFER_TOKEN_NULL_IF_EQUAL = 1 -SAFER_TOKEN_COMPARE_ONLY = 2 -SAFER_TOKEN_MAKE_INERT = 4 -SAFER_TOKEN_WANT_FLAGS = 8 -SAFER_TOKEN_MASK = 15 +SAFER_TOKEN_COMPARE_ONLY = 2 +SAFER_TOKEN_MAKE_INERT = 4 +SAFER_TOKEN_WANT_FLAGS = 8 +SAFER_TOKEN_MASK = 15 -#--- Service Control Manager types, constants and structures ------------------ +# --- Service Control Manager types, constants and structures ------------------ SC_HANDLE = HANDLE -SERVICES_ACTIVE_DATABASEW = u"ServicesActive" -SERVICES_FAILED_DATABASEW = u"ServicesFailed" +SERVICES_ACTIVE_DATABASEW = "ServicesActive" +SERVICES_FAILED_DATABASEW = "ServicesFailed" SERVICES_ACTIVE_DATABASEA = "ServicesActive" SERVICES_FAILED_DATABASEA = "ServicesFailed" -SC_GROUP_IDENTIFIERW = u'+' -SC_GROUP_IDENTIFIERA = '+' +SC_GROUP_IDENTIFIERW = "+" +SC_GROUP_IDENTIFIERA = "+" -SERVICE_NO_CHANGE = 0xffffffff +SERVICE_NO_CHANGE = 0xFFFFFFFF # enum SC_STATUS_TYPE -SC_STATUS_TYPE = ctypes.c_int +SC_STATUS_TYPE = ctypes.c_int SC_STATUS_PROCESS_INFO = 0 # enum SC_ENUM_TYPE -SC_ENUM_TYPE = ctypes.c_int +SC_ENUM_TYPE = ctypes.c_int SC_ENUM_PROCESS_INFO = 0 # Access rights # http://msdn.microsoft.com/en-us/library/windows/desktop/ms685981(v=vs.85).aspx -SERVICE_ALL_ACCESS = 0xF01FF -SERVICE_QUERY_CONFIG = 0x0001 -SERVICE_CHANGE_CONFIG = 0x0002 -SERVICE_QUERY_STATUS = 0x0004 +SERVICE_ALL_ACCESS = 0xF01FF +SERVICE_QUERY_CONFIG = 0x0001 +SERVICE_CHANGE_CONFIG = 0x0002 +SERVICE_QUERY_STATUS = 0x0004 SERVICE_ENUMERATE_DEPENDENTS = 0x0008 -SERVICE_START = 0x0010 -SERVICE_STOP = 0x0020 -SERVICE_PAUSE_CONTINUE = 0x0040 -SERVICE_INTERROGATE = 0x0080 +SERVICE_START = 0x0010 +SERVICE_STOP = 0x0020 +SERVICE_PAUSE_CONTINUE = 0x0040 +SERVICE_INTERROGATE = 0x0080 SERVICE_USER_DEFINED_CONTROL = 0x0100 -SC_MANAGER_ALL_ACCESS = 0xF003F -SC_MANAGER_CONNECT = 0x0001 -SC_MANAGER_CREATE_SERVICE = 0x0002 -SC_MANAGER_ENUMERATE_SERVICE = 0x0004 -SC_MANAGER_LOCK = 0x0008 -SC_MANAGER_QUERY_LOCK_STATUS = 0x0010 -SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020 +SC_MANAGER_ALL_ACCESS = 0xF003F +SC_MANAGER_CONNECT = 0x0001 +SC_MANAGER_CREATE_SERVICE = 0x0002 +SC_MANAGER_ENUMERATE_SERVICE = 0x0004 +SC_MANAGER_LOCK = 0x0008 +SC_MANAGER_QUERY_LOCK_STATUS = 0x0010 +SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020 # CreateService() service start type -SERVICE_BOOT_START = 0x00000000 +SERVICE_BOOT_START = 0x00000000 SERVICE_SYSTEM_START = 0x00000001 -SERVICE_AUTO_START = 0x00000002 +SERVICE_AUTO_START = 0x00000002 SERVICE_DEMAND_START = 0x00000003 -SERVICE_DISABLED = 0x00000004 +SERVICE_DISABLED = 0x00000004 # CreateService() error control flags -SERVICE_ERROR_IGNORE = 0x00000000 -SERVICE_ERROR_NORMAL = 0x00000001 -SERVICE_ERROR_SEVERE = 0x00000002 -SERVICE_ERROR_CRITICAL = 0x00000003 +SERVICE_ERROR_IGNORE = 0x00000000 +SERVICE_ERROR_NORMAL = 0x00000001 +SERVICE_ERROR_SEVERE = 0x00000002 +SERVICE_ERROR_CRITICAL = 0x00000003 # EnumServicesStatusEx() service state filters -SERVICE_ACTIVE = 1 -SERVICE_INACTIVE = 2 +SERVICE_ACTIVE = 1 +SERVICE_INACTIVE = 2 SERVICE_STATE_ALL = 3 # SERVICE_STATUS_PROCESS.dwServiceType -SERVICE_KERNEL_DRIVER = 0x00000001 -SERVICE_FILE_SYSTEM_DRIVER = 0x00000002 -SERVICE_ADAPTER = 0x00000004 -SERVICE_RECOGNIZER_DRIVER = 0x00000008 -SERVICE_WIN32_OWN_PROCESS = 0x00000010 +SERVICE_KERNEL_DRIVER = 0x00000001 +SERVICE_FILE_SYSTEM_DRIVER = 0x00000002 +SERVICE_ADAPTER = 0x00000004 +SERVICE_RECOGNIZER_DRIVER = 0x00000008 +SERVICE_WIN32_OWN_PROCESS = 0x00000010 SERVICE_WIN32_SHARE_PROCESS = 0x00000020 SERVICE_INTERACTIVE_PROCESS = 0x00000100 # EnumServicesStatusEx() service type filters (in addition to actual types) -SERVICE_DRIVER = 0x0000000B # SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER -SERVICE_WIN32 = 0x00000030 # SERVICE_WIN32_OWN_PROCESS and SERVICE_WIN32_SHARE_PROCESS +SERVICE_DRIVER = 0x0000000B # SERVICE_KERNEL_DRIVER and SERVICE_FILE_SYSTEM_DRIVER +SERVICE_WIN32 = 0x00000030 # SERVICE_WIN32_OWN_PROCESS and SERVICE_WIN32_SHARE_PROCESS # SERVICE_STATUS_PROCESS.dwCurrentState -SERVICE_STOPPED = 0x00000001 -SERVICE_START_PENDING = 0x00000002 -SERVICE_STOP_PENDING = 0x00000003 -SERVICE_RUNNING = 0x00000004 -SERVICE_CONTINUE_PENDING = 0x00000005 -SERVICE_PAUSE_PENDING = 0x00000006 -SERVICE_PAUSED = 0x00000007 +SERVICE_STOPPED = 0x00000001 +SERVICE_START_PENDING = 0x00000002 +SERVICE_STOP_PENDING = 0x00000003 +SERVICE_RUNNING = 0x00000004 +SERVICE_CONTINUE_PENDING = 0x00000005 +SERVICE_PAUSE_PENDING = 0x00000006 +SERVICE_PAUSED = 0x00000007 # SERVICE_STATUS_PROCESS.dwControlsAccepted -SERVICE_ACCEPT_STOP = 0x00000001 -SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002 -SERVICE_ACCEPT_SHUTDOWN = 0x00000004 -SERVICE_ACCEPT_PARAMCHANGE = 0x00000008 -SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010 +SERVICE_ACCEPT_STOP = 0x00000001 +SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002 +SERVICE_ACCEPT_SHUTDOWN = 0x00000004 +SERVICE_ACCEPT_PARAMCHANGE = 0x00000008 +SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010 SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020 -SERVICE_ACCEPT_POWEREVENT = 0x00000040 -SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080 -SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100 +SERVICE_ACCEPT_POWEREVENT = 0x00000040 +SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080 +SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100 # SERVICE_STATUS_PROCESS.dwServiceFlags SERVICE_RUNS_IN_SYSTEM_PROCESS = 0x00000001 # Service control flags -SERVICE_CONTROL_STOP = 0x00000001 -SERVICE_CONTROL_PAUSE = 0x00000002 -SERVICE_CONTROL_CONTINUE = 0x00000003 -SERVICE_CONTROL_INTERROGATE = 0x00000004 -SERVICE_CONTROL_SHUTDOWN = 0x00000005 -SERVICE_CONTROL_PARAMCHANGE = 0x00000006 -SERVICE_CONTROL_NETBINDADD = 0x00000007 -SERVICE_CONTROL_NETBINDREMOVE = 0x00000008 -SERVICE_CONTROL_NETBINDENABLE = 0x00000009 -SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A -SERVICE_CONTROL_DEVICEEVENT = 0x0000000B +SERVICE_CONTROL_STOP = 0x00000001 +SERVICE_CONTROL_PAUSE = 0x00000002 +SERVICE_CONTROL_CONTINUE = 0x00000003 +SERVICE_CONTROL_INTERROGATE = 0x00000004 +SERVICE_CONTROL_SHUTDOWN = 0x00000005 +SERVICE_CONTROL_PARAMCHANGE = 0x00000006 +SERVICE_CONTROL_NETBINDADD = 0x00000007 +SERVICE_CONTROL_NETBINDREMOVE = 0x00000008 +SERVICE_CONTROL_NETBINDENABLE = 0x00000009 +SERVICE_CONTROL_NETBINDDISABLE = 0x0000000A +SERVICE_CONTROL_DEVICEEVENT = 0x0000000B SERVICE_CONTROL_HARDWAREPROFILECHANGE = 0x0000000C -SERVICE_CONTROL_POWEREVENT = 0x0000000D -SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E +SERVICE_CONTROL_POWEREVENT = 0x0000000D +SERVICE_CONTROL_SESSIONCHANGE = 0x0000000E # Service control accepted bitmasks -SERVICE_ACCEPT_STOP = 0x00000001 -SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002 -SERVICE_ACCEPT_SHUTDOWN = 0x00000004 -SERVICE_ACCEPT_PARAMCHANGE = 0x00000008 -SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010 +SERVICE_ACCEPT_STOP = 0x00000001 +SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002 +SERVICE_ACCEPT_SHUTDOWN = 0x00000004 +SERVICE_ACCEPT_PARAMCHANGE = 0x00000008 +SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010 SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020 -SERVICE_ACCEPT_POWEREVENT = 0x00000040 -SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080 -SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100 -SERVICE_ACCEPT_TIMECHANGE = 0x00000200 -SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400 -SERVICE_ACCEPT_USERMODEREBOOT = 0x00000800 +SERVICE_ACCEPT_POWEREVENT = 0x00000040 +SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080 +SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100 +SERVICE_ACCEPT_TIMECHANGE = 0x00000200 +SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400 +SERVICE_ACCEPT_USERMODEREBOOT = 0x00000800 # enum SC_ACTION_TYPE -SC_ACTION_NONE = 0 -SC_ACTION_RESTART = 1 -SC_ACTION_REBOOT = 2 +SC_ACTION_NONE = 0 +SC_ACTION_RESTART = 1 +SC_ACTION_REBOOT = 2 SC_ACTION_RUN_COMMAND = 3 # QueryServiceConfig2 -SERVICE_CONFIG_DESCRIPTION = 1 +SERVICE_CONFIG_DESCRIPTION = 1 SERVICE_CONFIG_FAILURE_ACTIONS = 2 + # typedef struct _SERVICE_STATUS { # DWORD dwServiceType; # DWORD dwCurrentState; @@ -860,16 +908,19 @@ def protectFromClose(self): # } SERVICE_STATUS, *LPSERVICE_STATUS; class SERVICE_STATUS(Structure): _fields_ = [ - ("dwServiceType", DWORD), - ("dwCurrentState", DWORD), - ("dwControlsAccepted", DWORD), - ("dwWin32ExitCode", DWORD), - ("dwServiceSpecificExitCode", DWORD), - ("dwCheckPoint", DWORD), - ("dwWaitHint", DWORD), + ("dwServiceType", DWORD), + ("dwCurrentState", DWORD), + ("dwControlsAccepted", DWORD), + ("dwWin32ExitCode", DWORD), + ("dwServiceSpecificExitCode", DWORD), + ("dwCheckPoint", DWORD), + ("dwWaitHint", DWORD), ] + + LPSERVICE_STATUS = POINTER(SERVICE_STATUS) + # typedef struct _SERVICE_STATUS_PROCESS { # DWORD dwServiceType; # DWORD dwCurrentState; @@ -883,11 +934,14 @@ class SERVICE_STATUS(Structure): # } SERVICE_STATUS_PROCESS, *LPSERVICE_STATUS_PROCESS; class SERVICE_STATUS_PROCESS(Structure): _fields_ = SERVICE_STATUS._fields_ + [ - ("dwProcessId", DWORD), - ("dwServiceFlags", DWORD), + ("dwProcessId", DWORD), + ("dwServiceFlags", DWORD), ] + + LPSERVICE_STATUS_PROCESS = POINTER(SERVICE_STATUS_PROCESS) + # typedef struct _ENUM_SERVICE_STATUS { # LPTSTR lpServiceName; # LPTSTR lpDisplayName; @@ -899,15 +953,20 @@ class ENUM_SERVICE_STATUSA(Structure): ("lpDisplayName", LPSTR), ("ServiceStatus", SERVICE_STATUS), ] + + class ENUM_SERVICE_STATUSW(Structure): _fields_ = [ ("lpServiceName", LPWSTR), ("lpDisplayName", LPWSTR), ("ServiceStatus", SERVICE_STATUS), ] + + LPENUM_SERVICE_STATUSA = POINTER(ENUM_SERVICE_STATUSA) LPENUM_SERVICE_STATUSW = POINTER(ENUM_SERVICE_STATUSW) + # typedef struct _ENUM_SERVICE_STATUS_PROCESS { # LPTSTR lpServiceName; # LPTSTR lpDisplayName; @@ -915,19 +974,24 @@ class ENUM_SERVICE_STATUSW(Structure): # } ENUM_SERVICE_STATUS_PROCESS, *LPENUM_SERVICE_STATUS_PROCESS; class ENUM_SERVICE_STATUS_PROCESSA(Structure): _fields_ = [ - ("lpServiceName", LPSTR), - ("lpDisplayName", LPSTR), + ("lpServiceName", LPSTR), + ("lpDisplayName", LPSTR), ("ServiceStatusProcess", SERVICE_STATUS_PROCESS), ] + + class ENUM_SERVICE_STATUS_PROCESSW(Structure): _fields_ = [ - ("lpServiceName", LPWSTR), - ("lpDisplayName", LPWSTR), + ("lpServiceName", LPWSTR), + ("lpDisplayName", LPWSTR), ("ServiceStatusProcess", SERVICE_STATUS_PROCESS), ] + + LPENUM_SERVICE_STATUS_PROCESSA = POINTER(ENUM_SERVICE_STATUS_PROCESSA) LPENUM_SERVICE_STATUS_PROCESSW = POINTER(ENUM_SERVICE_STATUS_PROCESSW) + class ServiceStatus(object): """ Wrapper for the L{SERVICE_STATUS} structure. @@ -938,13 +1002,14 @@ def __init__(self, raw): @type raw: L{SERVICE_STATUS} @param raw: Raw structure for this service status data. """ - self.ServiceType = raw.dwServiceType - self.CurrentState = raw.dwCurrentState - self.ControlsAccepted = raw.dwControlsAccepted - self.Win32ExitCode = raw.dwWin32ExitCode + self.ServiceType = raw.dwServiceType + self.CurrentState = raw.dwCurrentState + self.ControlsAccepted = raw.dwControlsAccepted + self.Win32ExitCode = raw.dwWin32ExitCode self.ServiceSpecificExitCode = raw.dwServiceSpecificExitCode - self.CheckPoint = raw.dwCheckPoint - self.WaitHint = raw.dwWaitHint + self.CheckPoint = raw.dwCheckPoint + self.WaitHint = raw.dwWaitHint + class ServiceStatusProcess(object): """ @@ -956,15 +1021,16 @@ def __init__(self, raw): @type raw: L{SERVICE_STATUS_PROCESS} @param raw: Raw structure for this service status data. """ - self.ServiceType = raw.dwServiceType - self.CurrentState = raw.dwCurrentState - self.ControlsAccepted = raw.dwControlsAccepted - self.Win32ExitCode = raw.dwWin32ExitCode + self.ServiceType = raw.dwServiceType + self.CurrentState = raw.dwCurrentState + self.ControlsAccepted = raw.dwControlsAccepted + self.Win32ExitCode = raw.dwWin32ExitCode self.ServiceSpecificExitCode = raw.dwServiceSpecificExitCode - self.CheckPoint = raw.dwCheckPoint - self.WaitHint = raw.dwWaitHint - self.ProcessId = raw.dwProcessId - self.ServiceFlags = raw.dwServiceFlags + self.CheckPoint = raw.dwCheckPoint + self.WaitHint = raw.dwWaitHint + self.ProcessId = raw.dwProcessId + self.ServiceFlags = raw.dwServiceFlags + class ServiceStatusEntry(object): """ @@ -976,15 +1042,15 @@ def __init__(self, raw): @type raw: L{ENUM_SERVICE_STATUSA} or L{ENUM_SERVICE_STATUSW} @param raw: Raw structure for this service status entry. """ - self.ServiceName = raw.lpServiceName - self.DisplayName = raw.lpDisplayName - self.ServiceType = raw.ServiceStatus.dwServiceType - self.CurrentState = raw.ServiceStatus.dwCurrentState - self.ControlsAccepted = raw.ServiceStatus.dwControlsAccepted - self.Win32ExitCode = raw.ServiceStatus.dwWin32ExitCode + self.ServiceName = raw.lpServiceName + self.DisplayName = raw.lpDisplayName + self.ServiceType = raw.ServiceStatus.dwServiceType + self.CurrentState = raw.ServiceStatus.dwCurrentState + self.ControlsAccepted = raw.ServiceStatus.dwControlsAccepted + self.Win32ExitCode = raw.ServiceStatus.dwWin32ExitCode self.ServiceSpecificExitCode = raw.ServiceStatus.dwServiceSpecificExitCode - self.CheckPoint = raw.ServiceStatus.dwCheckPoint - self.WaitHint = raw.ServiceStatus.dwWaitHint + self.CheckPoint = raw.ServiceStatus.dwCheckPoint + self.WaitHint = raw.ServiceStatus.dwWaitHint def __str__(self): output = [] @@ -993,10 +1059,10 @@ def __str__(self): else: output.append("Service") if self.DisplayName: - output.append("\"%s\" (%s)" % (self.DisplayName, self.ServiceName)) + output.append('"%s" (%s)' % (self.DisplayName, self.ServiceName)) else: - output.append("\"%s\"" % self.ServiceName) - if self.CurrentState == SERVICE_CONTINUE_PENDING: + output.append('"%s"' % self.ServiceName) + if self.CurrentState == SERVICE_CONTINUE_PENDING: output.append("is about to continue.") elif self.CurrentState == SERVICE_PAUSE_PENDING: output.append("is pausing.") @@ -1012,6 +1078,7 @@ def __str__(self): output.append("is stopped.") return " ".join(output) + class ServiceStatusProcessEntry(object): """ Service status entry returned by L{EnumServicesStatusEx}. @@ -1022,17 +1089,17 @@ def __init__(self, raw): @type raw: L{ENUM_SERVICE_STATUS_PROCESSA} or L{ENUM_SERVICE_STATUS_PROCESSW} @param raw: Raw structure for this service status entry. """ - self.ServiceName = raw.lpServiceName - self.DisplayName = raw.lpDisplayName - self.ServiceType = raw.ServiceStatusProcess.dwServiceType - self.CurrentState = raw.ServiceStatusProcess.dwCurrentState - self.ControlsAccepted = raw.ServiceStatusProcess.dwControlsAccepted - self.Win32ExitCode = raw.ServiceStatusProcess.dwWin32ExitCode + self.ServiceName = raw.lpServiceName + self.DisplayName = raw.lpDisplayName + self.ServiceType = raw.ServiceStatusProcess.dwServiceType + self.CurrentState = raw.ServiceStatusProcess.dwCurrentState + self.ControlsAccepted = raw.ServiceStatusProcess.dwControlsAccepted + self.Win32ExitCode = raw.ServiceStatusProcess.dwWin32ExitCode self.ServiceSpecificExitCode = raw.ServiceStatusProcess.dwServiceSpecificExitCode - self.CheckPoint = raw.ServiceStatusProcess.dwCheckPoint - self.WaitHint = raw.ServiceStatusProcess.dwWaitHint - self.ProcessId = raw.ServiceStatusProcess.dwProcessId - self.ServiceFlags = raw.ServiceStatusProcess.dwServiceFlags + self.CheckPoint = raw.ServiceStatusProcess.dwCheckPoint + self.WaitHint = raw.ServiceStatusProcess.dwWaitHint + self.ProcessId = raw.ServiceStatusProcess.dwProcessId + self.ServiceFlags = raw.ServiceStatusProcess.dwServiceFlags def __str__(self): output = [] @@ -1041,10 +1108,10 @@ def __str__(self): else: output.append("Service ") if self.DisplayName: - output.append("\"%s\" (%s)" % (self.DisplayName, self.ServiceName)) + output.append('"%s" (%s)' % (self.DisplayName, self.ServiceName)) else: - output.append("\"%s\"" % self.ServiceName) - if self.CurrentState == SERVICE_CONTINUE_PENDING: + output.append('"%s"' % self.ServiceName) + if self.CurrentState == SERVICE_CONTINUE_PENDING: output.append(" is about to continue") elif self.CurrentState == SERVICE_PAUSE_PENDING: output.append(" is pausing") @@ -1063,18 +1130,22 @@ def __str__(self): output.append(".") return "".join(output) -#--- Handle wrappers ---------------------------------------------------------- + +# --- Handle wrappers ---------------------------------------------------------- + # XXX maybe add functions related to the tokens here? -class TokenHandle (Handle): +class TokenHandle(Handle): """ Access token handle. @see: L{Handle} """ + pass -class RegistryKeyHandle (UserModeHandle): + +class RegistryKeyHandle(UserModeHandle): """ Registry key handle. """ @@ -1084,7 +1155,8 @@ class RegistryKeyHandle (UserModeHandle): def _close(self): RegCloseKey(self.value) -class SaferLevelHandle (UserModeHandle): + +class SaferLevelHandle(UserModeHandle): """ Safer level handle. @@ -1096,7 +1168,8 @@ class SaferLevelHandle (UserModeHandle): def _close(self): SaferCloseLevel(self.value) -class ServiceHandle (UserModeHandle): + +class ServiceHandle(UserModeHandle): """ Service handle. @@ -1108,7 +1181,8 @@ class ServiceHandle (UserModeHandle): def _close(self): CloseServiceHandle(self.value) -class ServiceControlManagerHandle (UserModeHandle): + +class ServiceControlManagerHandle(UserModeHandle): """ Service Control Manager (SCM) handle. @@ -1120,7 +1194,9 @@ class ServiceControlManagerHandle (UserModeHandle): def _close(self): CloseServiceHandle(self.value) -#--- advapi32.dll ------------------------------------------------------------- + +# --- advapi32.dll ------------------------------------------------------------- + # BOOL WINAPI GetUserName( # __out LPTSTR lpBuffer, @@ -1129,35 +1205,37 @@ def _close(self): def GetUserNameA(): _GetUserNameA = windll.advapi32.GetUserNameA _GetUserNameA.argtypes = [LPSTR, LPDWORD] - _GetUserNameA.restype = bool + _GetUserNameA.restype = bool nSize = DWORD(0) _GetUserNameA(None, byref(nSize)) error = GetLastError() if error != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError(error) - lpBuffer = ctypes.create_string_buffer('', nSize.value + 1) + lpBuffer = ctypes.create_string_buffer("", nSize.value + 1) success = _GetUserNameA(lpBuffer, byref(nSize)) if not success: raise ctypes.WinError() return lpBuffer.value + def GetUserNameW(): _GetUserNameW = windll.advapi32.GetUserNameW _GetUserNameW.argtypes = [LPWSTR, LPDWORD] - _GetUserNameW.restype = bool + _GetUserNameW.restype = bool nSize = DWORD(0) _GetUserNameW(None, byref(nSize)) error = GetLastError() if error != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError(error) - lpBuffer = ctypes.create_unicode_buffer(u'', nSize.value + 1) + lpBuffer = ctypes.create_unicode_buffer("", nSize.value + 1) success = _GetUserNameW(lpBuffer, byref(nSize)) if not success: raise ctypes.WinError() return lpBuffer.value + GetUserName = DefaultStringType(GetUserNameA, GetUserNameW) # BOOL WINAPI LookupAccountName( @@ -1172,6 +1250,7 @@ def GetUserNameW(): # XXX TO DO + # BOOL WINAPI LookupAccountSid( # __in_opt LPCTSTR lpSystemName, # __in PSID lpSid, @@ -1184,7 +1263,7 @@ def GetUserNameW(): def LookupAccountSidA(lpSystemName, lpSid): _LookupAccountSidA = windll.advapi32.LookupAccountSidA _LookupAccountSidA.argtypes = [LPSTR, PSID, LPSTR, LPDWORD, LPSTR, LPDWORD, LPDWORD] - _LookupAccountSidA.restype = bool + _LookupAccountSidA.restype = bool cchName = DWORD(0) cchReferencedDomainName = DWORD(0) @@ -1193,17 +1272,20 @@ def LookupAccountSidA(lpSystemName, lpSid): error = GetLastError() if error != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError(error) - lpName = ctypes.create_string_buffer('', cchName + 1) - lpReferencedDomainName = ctypes.create_string_buffer('', cchReferencedDomainName + 1) - success = _LookupAccountSidA(lpSystemName, lpSid, lpName, byref(cchName), lpReferencedDomainName, byref(cchReferencedDomainName), byref(peUse)) + lpName = ctypes.create_string_buffer("", cchName + 1) + lpReferencedDomainName = ctypes.create_string_buffer("", cchReferencedDomainName + 1) + success = _LookupAccountSidA( + lpSystemName, lpSid, lpName, byref(cchName), lpReferencedDomainName, byref(cchReferencedDomainName), byref(peUse) + ) if not success: raise ctypes.WinError() return lpName.value, lpReferencedDomainName.value, peUse.value + def LookupAccountSidW(lpSystemName, lpSid): _LookupAccountSidW = windll.advapi32.LookupAccountSidA _LookupAccountSidW.argtypes = [LPSTR, PSID, LPWSTR, LPDWORD, LPWSTR, LPDWORD, LPDWORD] - _LookupAccountSidW.restype = bool + _LookupAccountSidW.restype = bool cchName = DWORD(0) cchReferencedDomainName = DWORD(0) @@ -1212,15 +1294,19 @@ def LookupAccountSidW(lpSystemName, lpSid): error = GetLastError() if error != ERROR_INSUFFICIENT_BUFFER: raise ctypes.WinError(error) - lpName = ctypes.create_unicode_buffer(u'', cchName + 1) - lpReferencedDomainName = ctypes.create_unicode_buffer(u'', cchReferencedDomainName + 1) - success = _LookupAccountSidW(lpSystemName, lpSid, lpName, byref(cchName), lpReferencedDomainName, byref(cchReferencedDomainName), byref(peUse)) + lpName = ctypes.create_unicode_buffer("", cchName + 1) + lpReferencedDomainName = ctypes.create_unicode_buffer("", cchReferencedDomainName + 1) + success = _LookupAccountSidW( + lpSystemName, lpSid, lpName, byref(cchName), lpReferencedDomainName, byref(cchReferencedDomainName), byref(peUse) + ) if not success: raise ctypes.WinError() return lpName.value, lpReferencedDomainName.value, peUse.value + LookupAccountSid = GuessStringType(LookupAccountSidA, LookupAccountSidW) + # BOOL ConvertSidToStringSid( # __in PSID Sid, # __out LPTSTR *StringSid @@ -1228,7 +1314,7 @@ def LookupAccountSidW(lpSystemName, lpSid): def ConvertSidToStringSidA(Sid): _ConvertSidToStringSidA = windll.advapi32.ConvertSidToStringSidA _ConvertSidToStringSidA.argtypes = [PSID, LPSTR] - _ConvertSidToStringSidA.restype = bool + _ConvertSidToStringSidA.restype = bool _ConvertSidToStringSidA.errcheck = RaiseIfZero pStringSid = LPSTR() @@ -1239,10 +1325,11 @@ def ConvertSidToStringSidA(Sid): LocalFree(pStringSid) return StringSid + def ConvertSidToStringSidW(Sid): _ConvertSidToStringSidW = windll.advapi32.ConvertSidToStringSidW _ConvertSidToStringSidW.argtypes = [PSID, LPWSTR] - _ConvertSidToStringSidW.restype = bool + _ConvertSidToStringSidW.restype = bool _ConvertSidToStringSidW.errcheck = RaiseIfZero pStringSid = LPWSTR() @@ -1253,8 +1340,10 @@ def ConvertSidToStringSidW(Sid): LocalFree(pStringSid) return StringSid + ConvertSidToStringSid = DefaultStringType(ConvertSidToStringSidA, ConvertSidToStringSidW) + # BOOL WINAPI ConvertStringSidToSid( # __in LPCTSTR StringSid, # __out PSID *Sid @@ -1262,34 +1351,38 @@ def ConvertSidToStringSidW(Sid): def ConvertStringSidToSidA(StringSid): _ConvertStringSidToSidA = windll.advapi32.ConvertStringSidToSidA _ConvertStringSidToSidA.argtypes = [LPSTR, PVOID] - _ConvertStringSidToSidA.restype = bool + _ConvertStringSidToSidA.restype = bool _ConvertStringSidToSidA.errcheck = RaiseIfZero Sid = PVOID() _ConvertStringSidToSidA(StringSid, ctypes.pointer(Sid)) return Sid.value + def ConvertStringSidToSidW(StringSid): _ConvertStringSidToSidW = windll.advapi32.ConvertStringSidToSidW _ConvertStringSidToSidW.argtypes = [LPWSTR, PVOID] - _ConvertStringSidToSidW.restype = bool + _ConvertStringSidToSidW.restype = bool _ConvertStringSidToSidW.errcheck = RaiseIfZero Sid = PVOID() _ConvertStringSidToSidW(StringSid, ctypes.pointer(Sid)) return Sid.value + ConvertStringSidToSid = GuessStringType(ConvertStringSidToSidA, ConvertStringSidToSidW) + # BOOL WINAPI IsValidSid( # __in PSID pSid # ); def IsValidSid(pSid): _IsValidSid = windll.advapi32.IsValidSid _IsValidSid.argtypes = [PSID] - _IsValidSid.restype = bool + _IsValidSid.restype = bool return _IsValidSid(pSid) + # BOOL WINAPI EqualSid( # __in PSID pSid1, # __in PSID pSid2 @@ -1297,18 +1390,20 @@ def IsValidSid(pSid): def EqualSid(pSid1, pSid2): _EqualSid = windll.advapi32.EqualSid _EqualSid.argtypes = [PSID, PSID] - _EqualSid.restype = bool + _EqualSid.restype = bool return _EqualSid(pSid1, pSid2) + # DWORD WINAPI GetLengthSid( # __in PSID pSid # ); def GetLengthSid(pSid): _GetLengthSid = windll.advapi32.GetLengthSid _GetLengthSid.argtypes = [PSID] - _GetLengthSid.restype = DWORD + _GetLengthSid.restype = DWORD return _GetLengthSid(pSid) + # BOOL WINAPI CopySid( # __in DWORD nDestinationSidLength, # __out PSID pDestinationSid, @@ -1317,71 +1412,76 @@ def GetLengthSid(pSid): def CopySid(pSourceSid): _CopySid = windll.advapi32.CopySid _CopySid.argtypes = [DWORD, PVOID, PSID] - _CopySid.restype = bool + _CopySid.restype = bool _CopySid.errcheck = RaiseIfZero nDestinationSidLength = GetLengthSid(pSourceSid) - DestinationSid = ctypes.create_string_buffer('', nDestinationSidLength) + DestinationSid = ctypes.create_string_buffer("", nDestinationSidLength) pDestinationSid = ctypes.cast(ctypes.pointer(DestinationSid), PVOID) _CopySid(nDestinationSidLength, pDestinationSid, pSourceSid) return ctypes.cast(pDestinationSid, PSID) + # PVOID WINAPI FreeSid( # __in PSID pSid # ); def FreeSid(pSid): _FreeSid = windll.advapi32.FreeSid _FreeSid.argtypes = [PSID] - _FreeSid.restype = PSID + _FreeSid.restype = PSID _FreeSid.errcheck = RaiseIfNotZero _FreeSid(pSid) + # BOOL WINAPI OpenProcessToken( # __in HANDLE ProcessHandle, # __in DWORD DesiredAccess, # __out PHANDLE TokenHandle # ); -def OpenProcessToken(ProcessHandle, DesiredAccess = TOKEN_ALL_ACCESS): +def OpenProcessToken(ProcessHandle, DesiredAccess=TOKEN_ALL_ACCESS): _OpenProcessToken = windll.advapi32.OpenProcessToken _OpenProcessToken.argtypes = [HANDLE, DWORD, PHANDLE] - _OpenProcessToken.restype = bool + _OpenProcessToken.restype = bool _OpenProcessToken.errcheck = RaiseIfZero NewTokenHandle = HANDLE(INVALID_HANDLE_VALUE) _OpenProcessToken(ProcessHandle, DesiredAccess, byref(NewTokenHandle)) return TokenHandle(NewTokenHandle.value) + # BOOL WINAPI OpenThreadToken( # __in HANDLE ThreadHandle, # __in DWORD DesiredAccess, # __in BOOL OpenAsSelf, # __out PHANDLE TokenHandle # ); -def OpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf = True): +def OpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf=True): _OpenThreadToken = windll.advapi32.OpenThreadToken _OpenThreadToken.argtypes = [HANDLE, DWORD, BOOL, PHANDLE] - _OpenThreadToken.restype = bool + _OpenThreadToken.restype = bool _OpenThreadToken.errcheck = RaiseIfZero NewTokenHandle = HANDLE(INVALID_HANDLE_VALUE) _OpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, byref(NewTokenHandle)) return TokenHandle(NewTokenHandle.value) + # BOOL WINAPI DuplicateToken( # _In_ HANDLE ExistingTokenHandle, # _In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel, # _Out_ PHANDLE DuplicateTokenHandle # ); -def DuplicateToken(ExistingTokenHandle, ImpersonationLevel = SecurityImpersonation): +def DuplicateToken(ExistingTokenHandle, ImpersonationLevel=SecurityImpersonation): _DuplicateToken = windll.advapi32.DuplicateToken _DuplicateToken.argtypes = [HANDLE, SECURITY_IMPERSONATION_LEVEL, PHANDLE] - _DuplicateToken.restype = bool + _DuplicateToken.restype = bool _DuplicateToken.errcheck = RaiseIfZero DuplicateTokenHandle = HANDLE(INVALID_HANDLE_VALUE) _DuplicateToken(ExistingTokenHandle, ImpersonationLevel, byref(DuplicateTokenHandle)) return TokenHandle(DuplicateTokenHandle.value) + # BOOL WINAPI DuplicateTokenEx( # _In_ HANDLE hExistingToken, # _In_ DWORD dwDesiredAccess, @@ -1390,28 +1490,36 @@ def DuplicateToken(ExistingTokenHandle, ImpersonationLevel = SecurityImpersonati # _In_ TOKEN_TYPE TokenType, # _Out_ PHANDLE phNewToken # ); -def DuplicateTokenEx(hExistingToken, dwDesiredAccess = TOKEN_ALL_ACCESS, lpTokenAttributes = None, ImpersonationLevel = SecurityImpersonation, TokenType = TokenPrimary): +def DuplicateTokenEx( + hExistingToken, + dwDesiredAccess=TOKEN_ALL_ACCESS, + lpTokenAttributes=None, + ImpersonationLevel=SecurityImpersonation, + TokenType=TokenPrimary, +): _DuplicateTokenEx = windll.advapi32.DuplicateTokenEx _DuplicateTokenEx.argtypes = [HANDLE, DWORD, LPSECURITY_ATTRIBUTES, SECURITY_IMPERSONATION_LEVEL, TOKEN_TYPE, PHANDLE] - _DuplicateTokenEx.restype = bool + _DuplicateTokenEx.restype = bool _DuplicateTokenEx.errcheck = RaiseIfZero DuplicateTokenHandle = HANDLE(INVALID_HANDLE_VALUE) _DuplicateTokenEx(hExistingToken, dwDesiredAccess, lpTokenAttributes, ImpersonationLevel, TokenType, byref(DuplicateTokenHandle)) return TokenHandle(DuplicateTokenHandle.value) + # BOOL WINAPI IsTokenRestricted( # __in HANDLE TokenHandle # ); def IsTokenRestricted(hTokenHandle): _IsTokenRestricted = windll.advapi32.IsTokenRestricted _IsTokenRestricted.argtypes = [HANDLE] - _IsTokenRestricted.restype = bool + _IsTokenRestricted.restype = bool _IsTokenRestricted.errcheck = RaiseIfNotErrorSuccess SetLastError(ERROR_SUCCESS) return _IsTokenRestricted(hTokenHandle) + # BOOL WINAPI LookupPrivilegeValue( # __in_opt LPCTSTR lpSystemName, # __in LPCTSTR lpName, @@ -1420,7 +1528,7 @@ def IsTokenRestricted(hTokenHandle): def LookupPrivilegeValueA(lpSystemName, lpName): _LookupPrivilegeValueA = windll.advapi32.LookupPrivilegeValueA _LookupPrivilegeValueA.argtypes = [LPSTR, LPSTR, PLUID] - _LookupPrivilegeValueA.restype = bool + _LookupPrivilegeValueA.restype = bool _LookupPrivilegeValueA.errcheck = RaiseIfZero lpLuid = LUID() @@ -1429,10 +1537,11 @@ def LookupPrivilegeValueA(lpSystemName, lpName): _LookupPrivilegeValueA(lpSystemName, lpName, byref(lpLuid)) return lpLuid + def LookupPrivilegeValueW(lpSystemName, lpName): _LookupPrivilegeValueW = windll.advapi32.LookupPrivilegeValueW _LookupPrivilegeValueW.argtypes = [LPWSTR, LPWSTR, PLUID] - _LookupPrivilegeValueW.restype = bool + _LookupPrivilegeValueW.restype = bool _LookupPrivilegeValueW.errcheck = RaiseIfZero lpLuid = LUID() @@ -1441,6 +1550,7 @@ def LookupPrivilegeValueW(lpSystemName, lpName): _LookupPrivilegeValueW(lpSystemName, lpName, byref(lpLuid)) return lpLuid + LookupPrivilegeValue = GuessStringType(LookupPrivilegeValueA, LookupPrivilegeValueW) # BOOL WINAPI LookupPrivilegeName( @@ -1450,10 +1560,11 @@ def LookupPrivilegeValueW(lpSystemName, lpName): # __inout LPDWORD cchName # ); + def LookupPrivilegeNameA(lpSystemName, lpLuid): _LookupPrivilegeNameA = windll.advapi32.LookupPrivilegeNameA _LookupPrivilegeNameA.argtypes = [LPSTR, PLUID, LPSTR, LPDWORD] - _LookupPrivilegeNameA.restype = bool + _LookupPrivilegeNameA.restype = bool _LookupPrivilegeNameA.errcheck = RaiseIfZero cchName = DWORD(0) @@ -1462,20 +1573,23 @@ def LookupPrivilegeNameA(lpSystemName, lpLuid): _LookupPrivilegeNameA(lpSystemName, byref(lpLuid), byref(lpName), byref(cchName)) return lpName.value + def LookupPrivilegeNameW(lpSystemName, lpLuid): _LookupPrivilegeNameW = windll.advapi32.LookupPrivilegeNameW _LookupPrivilegeNameW.argtypes = [LPWSTR, PLUID, LPWSTR, LPDWORD] - _LookupPrivilegeNameW.restype = bool + _LookupPrivilegeNameW.restype = bool _LookupPrivilegeNameW.errcheck = RaiseIfZero cchName = DWORD(0) _LookupPrivilegeNameW(lpSystemName, byref(lpLuid), NULL, byref(cchName)) - lpName = ctypes.create_unicode_buffer(u"", cchName.value) + lpName = ctypes.create_unicode_buffer("", cchName.value) _LookupPrivilegeNameW(lpSystemName, byref(lpLuid), byref(lpName), byref(cchName)) return lpName.value + LookupPrivilegeName = GuessStringType(LookupPrivilegeNameA, LookupPrivilegeNameW) + # BOOL WINAPI AdjustTokenPrivileges( # __in HANDLE TokenHandle, # __in BOOL DisableAllPrivileges, @@ -1484,10 +1598,10 @@ def LookupPrivilegeNameW(lpSystemName, lpLuid): # __out_opt PTOKEN_PRIVILEGES PreviousState, # __out_opt PDWORD ReturnLength # ); -def AdjustTokenPrivileges(TokenHandle, NewState = ()): +def AdjustTokenPrivileges(TokenHandle, NewState=()): _AdjustTokenPrivileges = windll.advapi32.AdjustTokenPrivileges _AdjustTokenPrivileges.argtypes = [HANDLE, BOOL, LPVOID, DWORD, LPVOID, LPVOID] - _AdjustTokenPrivileges.restype = bool + _AdjustTokenPrivileges.restype = bool _AdjustTokenPrivileges.errcheck = RaiseIfZero # # I don't know how to allocate variable sized structures in ctypes :( @@ -1500,7 +1614,7 @@ def AdjustTokenPrivileges(TokenHandle, NewState = ()): _AdjustTokenPrivileges(TokenHandle, TRUE, NULL, 0, NULL, NULL) else: success = True - for (privilege, enabled) in NewState: + for privilege, enabled in NewState: if not isinstance(privilege, LUID): privilege = LookupPrivilegeValue(NULL, privilege) if enabled == True: @@ -1512,9 +1626,10 @@ def AdjustTokenPrivileges(TokenHandle, NewState = ()): else: flags = enabled laa = LUID_AND_ATTRIBUTES(privilege, flags) - tp = TOKEN_PRIVILEGES(1, laa) + tp = TOKEN_PRIVILEGES(1, laa) _AdjustTokenPrivileges(TokenHandle, FALSE, byref(tp), sizeof(tp), NULL, NULL) + # BOOL WINAPI GetTokenInformation( # __in HANDLE TokenHandle, # __in TOKEN_INFORMATION_CLASS TokenInformationClass, @@ -1587,8 +1702,13 @@ def GetTokenInformation(hTokenHandle, TokenInformationClass): return TokenInformation.value # Various boolean flags. - if TokenInformationClass in (TokenSandBoxInert, TokenHasRestrictions, TokenUIAccess, - TokenVirtualizationAllowed, TokenVirtualizationEnabled): + if TokenInformationClass in ( + TokenSandBoxInert, + TokenHasRestrictions, + TokenUIAccess, + TokenVirtualizationAllowed, + TokenVirtualizationEnabled, + ): TokenInformation = DWORD(0) _internal_GetTokenInformation(hTokenHandle, TokenInformationClass, TokenInformation) return bool(TokenInformation.value) @@ -1597,21 +1717,22 @@ def GetTokenInformation(hTokenHandle, TokenInformationClass): if TokenInformationClass == TokenLinkedToken: TokenInformation = TOKEN_LINKED_TOKEN(0) _internal_GetTokenInformation(hTokenHandle, TokenInformationClass, TokenInformation) - return TokenHandle(TokenInformation.LinkedToken.value, bOwnership = True) + return TokenHandle(TokenInformation.LinkedToken.value, bOwnership=True) # Token statistics. if TokenInformationClass == TokenStatistics: TokenInformation = TOKEN_STATISTICS() _internal_GetTokenInformation(hTokenHandle, TokenInformationClass, TokenInformation) - return TokenInformation # TODO add a class wrapper? + return TokenInformation # TODO add a class wrapper? # Currently unsupported flags. raise NotImplementedError("TokenInformationClass(%i) not yet supported!" % TokenInformationClass) + def _internal_GetTokenInformation(hTokenHandle, TokenInformationClass, TokenInformation): _GetTokenInformation = windll.advapi32.GetTokenInformation _GetTokenInformation.argtypes = [HANDLE, TOKEN_INFORMATION_CLASS, LPVOID, DWORD, PDWORD] - _GetTokenInformation.restype = bool + _GetTokenInformation.restype = bool _GetTokenInformation.errcheck = RaiseIfZero ReturnLength = DWORD(0) @@ -1621,6 +1742,7 @@ def _internal_GetTokenInformation(hTokenHandle, TokenInformationClass, TokenInfo raise ctypes.WinError(ERROR_INSUFFICIENT_BUFFER) return TokenInformation + # BOOL WINAPI SetTokenInformation( # __in HANDLE TokenHandle, # __in TOKEN_INFORMATION_CLASS TokenInformationClass, @@ -1630,6 +1752,7 @@ def _internal_GetTokenInformation(hTokenHandle, TokenInformationClass, TokenInfo # XXX TODO + # BOOL WINAPI CreateProcessWithLogonW( # __in LPCWSTR lpUsername, # __in_opt LPCWSTR lpDomain, @@ -1643,50 +1766,87 @@ def _internal_GetTokenInformation(hTokenHandle, TokenInformationClass, TokenInfo # __in LPSTARTUPINFOW lpStartupInfo, # __out LPPROCESS_INFORMATION lpProcessInfo # ); -def CreateProcessWithLogonW(lpUsername = None, lpDomain = None, lpPassword = None, dwLogonFlags = 0, lpApplicationName = None, lpCommandLine = None, dwCreationFlags = 0, lpEnvironment = None, lpCurrentDirectory = None, lpStartupInfo = None): +def CreateProcessWithLogonW( + lpUsername=None, + lpDomain=None, + lpPassword=None, + dwLogonFlags=0, + lpApplicationName=None, + lpCommandLine=None, + dwCreationFlags=0, + lpEnvironment=None, + lpCurrentDirectory=None, + lpStartupInfo=None, +): _CreateProcessWithLogonW = windll.advapi32.CreateProcessWithLogonW - _CreateProcessWithLogonW.argtypes = [LPWSTR, LPWSTR, LPWSTR, DWORD, LPWSTR, LPWSTR, DWORD, LPVOID, LPWSTR, LPVOID, LPPROCESS_INFORMATION] + _CreateProcessWithLogonW.argtypes = [ + LPWSTR, + LPWSTR, + LPWSTR, + DWORD, + LPWSTR, + LPWSTR, + DWORD, + LPVOID, + LPWSTR, + LPVOID, + LPPROCESS_INFORMATION, + ] _CreateProcessWithLogonW.restype = bool _CreateProcessWithLogonW.errcheck = RaiseIfZero if not lpUsername: - lpUsername = None + lpUsername = None if not lpDomain: - lpDomain = None + lpDomain = None if not lpPassword: - lpPassword = None + lpPassword = None if not lpApplicationName: - lpApplicationName = None + lpApplicationName = None if not lpCommandLine: - lpCommandLine = None + lpCommandLine = None else: - lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) + lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) if not lpEnvironment: - lpEnvironment = None + lpEnvironment = None else: - lpEnvironment = ctypes.create_unicode_buffer(lpEnvironment) + lpEnvironment = ctypes.create_unicode_buffer(lpEnvironment) if not lpCurrentDirectory: - lpCurrentDirectory = None + lpCurrentDirectory = None if not lpStartupInfo: - lpStartupInfo = STARTUPINFOW() - lpStartupInfo.cb = sizeof(STARTUPINFOW) - lpStartupInfo.lpReserved = 0 - lpStartupInfo.lpDesktop = 0 - lpStartupInfo.lpTitle = 0 - lpStartupInfo.dwFlags = 0 - lpStartupInfo.cbReserved2 = 0 - lpStartupInfo.lpReserved2 = 0 - lpProcessInformation = PROCESS_INFORMATION() - lpProcessInformation.hProcess = INVALID_HANDLE_VALUE - lpProcessInformation.hThread = INVALID_HANDLE_VALUE - lpProcessInformation.dwProcessId = 0 - lpProcessInformation.dwThreadId = 0 - _CreateProcessWithLogonW(lpUsername, lpDomain, lpPassword, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, byref(lpStartupInfo), byref(lpProcessInformation)) + lpStartupInfo = STARTUPINFOW() + lpStartupInfo.cb = sizeof(STARTUPINFOW) + lpStartupInfo.lpReserved = 0 + lpStartupInfo.lpDesktop = 0 + lpStartupInfo.lpTitle = 0 + lpStartupInfo.dwFlags = 0 + lpStartupInfo.cbReserved2 = 0 + lpStartupInfo.lpReserved2 = 0 + lpProcessInformation = PROCESS_INFORMATION() + lpProcessInformation.hProcess = INVALID_HANDLE_VALUE + lpProcessInformation.hThread = INVALID_HANDLE_VALUE + lpProcessInformation.dwProcessId = 0 + lpProcessInformation.dwThreadId = 0 + _CreateProcessWithLogonW( + lpUsername, + lpDomain, + lpPassword, + dwLogonFlags, + lpApplicationName, + lpCommandLine, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + byref(lpStartupInfo), + byref(lpProcessInformation), + ) return ProcessInformation(lpProcessInformation) + CreateProcessWithLogonA = MakeANSIVersion(CreateProcessWithLogonW) CreateProcessWithLogon = DefaultStringType(CreateProcessWithLogonA, CreateProcessWithLogonW) + # BOOL WINAPI CreateProcessWithTokenW( # __in HANDLE hToken, # __in DWORD dwLogonFlags, @@ -1698,46 +1858,67 @@ def CreateProcessWithLogonW(lpUsername = None, lpDomain = None, lpPassword = Non # __in LPSTARTUPINFOW lpStartupInfo, # __out LPPROCESS_INFORMATION lpProcessInfo # ); -def CreateProcessWithTokenW(hToken = None, dwLogonFlags = 0, lpApplicationName = None, lpCommandLine = None, dwCreationFlags = 0, lpEnvironment = None, lpCurrentDirectory = None, lpStartupInfo = None): +def CreateProcessWithTokenW( + hToken=None, + dwLogonFlags=0, + lpApplicationName=None, + lpCommandLine=None, + dwCreationFlags=0, + lpEnvironment=None, + lpCurrentDirectory=None, + lpStartupInfo=None, +): _CreateProcessWithTokenW = windll.advapi32.CreateProcessWithTokenW _CreateProcessWithTokenW.argtypes = [HANDLE, DWORD, LPWSTR, LPWSTR, DWORD, LPVOID, LPWSTR, LPVOID, LPPROCESS_INFORMATION] _CreateProcessWithTokenW.restype = bool _CreateProcessWithTokenW.errcheck = RaiseIfZero if not hToken: - hToken = None + hToken = None if not lpApplicationName: - lpApplicationName = None + lpApplicationName = None if not lpCommandLine: - lpCommandLine = None + lpCommandLine = None else: - lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) + lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) if not lpEnvironment: - lpEnvironment = None + lpEnvironment = None else: - lpEnvironment = ctypes.create_unicode_buffer(lpEnvironment) + lpEnvironment = ctypes.create_unicode_buffer(lpEnvironment) if not lpCurrentDirectory: - lpCurrentDirectory = None + lpCurrentDirectory = None if not lpStartupInfo: - lpStartupInfo = STARTUPINFOW() - lpStartupInfo.cb = sizeof(STARTUPINFOW) - lpStartupInfo.lpReserved = 0 - lpStartupInfo.lpDesktop = 0 - lpStartupInfo.lpTitle = 0 - lpStartupInfo.dwFlags = 0 - lpStartupInfo.cbReserved2 = 0 - lpStartupInfo.lpReserved2 = 0 - lpProcessInformation = PROCESS_INFORMATION() - lpProcessInformation.hProcess = INVALID_HANDLE_VALUE - lpProcessInformation.hThread = INVALID_HANDLE_VALUE - lpProcessInformation.dwProcessId = 0 - lpProcessInformation.dwThreadId = 0 - _CreateProcessWithTokenW(hToken, dwLogonFlags, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, lpCurrentDirectory, byref(lpStartupInfo), byref(lpProcessInformation)) + lpStartupInfo = STARTUPINFOW() + lpStartupInfo.cb = sizeof(STARTUPINFOW) + lpStartupInfo.lpReserved = 0 + lpStartupInfo.lpDesktop = 0 + lpStartupInfo.lpTitle = 0 + lpStartupInfo.dwFlags = 0 + lpStartupInfo.cbReserved2 = 0 + lpStartupInfo.lpReserved2 = 0 + lpProcessInformation = PROCESS_INFORMATION() + lpProcessInformation.hProcess = INVALID_HANDLE_VALUE + lpProcessInformation.hThread = INVALID_HANDLE_VALUE + lpProcessInformation.dwProcessId = 0 + lpProcessInformation.dwThreadId = 0 + _CreateProcessWithTokenW( + hToken, + dwLogonFlags, + lpApplicationName, + lpCommandLine, + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + byref(lpStartupInfo), + byref(lpProcessInformation), + ) return ProcessInformation(lpProcessInformation) + CreateProcessWithTokenA = MakeANSIVersion(CreateProcessWithTokenW) CreateProcessWithToken = DefaultStringType(CreateProcessWithTokenA, CreateProcessWithTokenW) + # BOOL WINAPI CreateProcessAsUser( # __in_opt HANDLE hToken, # __in_opt LPCTSTR lpApplicationName, @@ -1751,24 +1932,47 @@ def CreateProcessWithTokenW(hToken = None, dwLogonFlags = 0, lpApplicationName = # __in LPSTARTUPINFO lpStartupInfo, # __out LPPROCESS_INFORMATION lpProcessInformation # ); -def CreateProcessAsUserA(hToken = None, lpApplicationName = None, lpCommandLine=None, lpProcessAttributes=None, lpThreadAttributes=None, bInheritHandles=False, dwCreationFlags=0, lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None): +def CreateProcessAsUserA( + hToken=None, + lpApplicationName=None, + lpCommandLine=None, + lpProcessAttributes=None, + lpThreadAttributes=None, + bInheritHandles=False, + dwCreationFlags=0, + lpEnvironment=None, + lpCurrentDirectory=None, + lpStartupInfo=None, +): _CreateProcessAsUserA = windll.advapi32.CreateProcessAsUserA - _CreateProcessAsUserA.argtypes = [HANDLE, LPSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPSTR, LPVOID, LPPROCESS_INFORMATION] - _CreateProcessAsUserA.restype = bool + _CreateProcessAsUserA.argtypes = [ + HANDLE, + LPSTR, + LPSTR, + LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES, + BOOL, + DWORD, + LPVOID, + LPSTR, + LPVOID, + LPPROCESS_INFORMATION, + ] + _CreateProcessAsUserA.restype = bool _CreateProcessAsUserA.errcheck = RaiseIfZero if not lpApplicationName: - lpApplicationName = None + lpApplicationName = None if not lpCommandLine: - lpCommandLine = None + lpCommandLine = None else: - lpCommandLine = ctypes.create_string_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) + lpCommandLine = ctypes.create_string_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) if not lpEnvironment: - lpEnvironment = None + lpEnvironment = None else: - lpEnvironment = ctypes.create_string_buffer(lpEnvironment) + lpEnvironment = ctypes.create_string_buffer(lpEnvironment) if not lpCurrentDirectory: - lpCurrentDirectory = None + lpCurrentDirectory = None if not lpProcessAttributes: lpProcessAttributes = None else: @@ -1778,40 +1982,76 @@ def CreateProcessAsUserA(hToken = None, lpApplicationName = None, lpCommandLine= else: lpThreadAttributes = byref(lpThreadAttributes) if not lpStartupInfo: - lpStartupInfo = STARTUPINFO() - lpStartupInfo.cb = sizeof(STARTUPINFO) - lpStartupInfo.lpReserved = 0 - lpStartupInfo.lpDesktop = 0 - lpStartupInfo.lpTitle = 0 - lpStartupInfo.dwFlags = 0 - lpStartupInfo.cbReserved2 = 0 - lpStartupInfo.lpReserved2 = 0 - lpProcessInformation = PROCESS_INFORMATION() - lpProcessInformation.hProcess = INVALID_HANDLE_VALUE - lpProcessInformation.hThread = INVALID_HANDLE_VALUE - lpProcessInformation.dwProcessId = 0 - lpProcessInformation.dwThreadId = 0 - _CreateProcessAsUserA(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bool(bInheritHandles), dwCreationFlags, lpEnvironment, lpCurrentDirectory, byref(lpStartupInfo), byref(lpProcessInformation)) + lpStartupInfo = STARTUPINFO() + lpStartupInfo.cb = sizeof(STARTUPINFO) + lpStartupInfo.lpReserved = 0 + lpStartupInfo.lpDesktop = 0 + lpStartupInfo.lpTitle = 0 + lpStartupInfo.dwFlags = 0 + lpStartupInfo.cbReserved2 = 0 + lpStartupInfo.lpReserved2 = 0 + lpProcessInformation = PROCESS_INFORMATION() + lpProcessInformation.hProcess = INVALID_HANDLE_VALUE + lpProcessInformation.hThread = INVALID_HANDLE_VALUE + lpProcessInformation.dwProcessId = 0 + lpProcessInformation.dwThreadId = 0 + _CreateProcessAsUserA( + hToken, + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bool(bInheritHandles), + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + byref(lpStartupInfo), + byref(lpProcessInformation), + ) return ProcessInformation(lpProcessInformation) -def CreateProcessAsUserW(hToken = None, lpApplicationName = None, lpCommandLine=None, lpProcessAttributes=None, lpThreadAttributes=None, bInheritHandles=False, dwCreationFlags=0, lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None): + +def CreateProcessAsUserW( + hToken=None, + lpApplicationName=None, + lpCommandLine=None, + lpProcessAttributes=None, + lpThreadAttributes=None, + bInheritHandles=False, + dwCreationFlags=0, + lpEnvironment=None, + lpCurrentDirectory=None, + lpStartupInfo=None, +): _CreateProcessAsUserW = windll.advapi32.CreateProcessAsUserW - _CreateProcessAsUserW.argtypes = [HANDLE, LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPWSTR, LPVOID, LPPROCESS_INFORMATION] - _CreateProcessAsUserW.restype = bool + _CreateProcessAsUserW.argtypes = [ + HANDLE, + LPWSTR, + LPWSTR, + LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES, + BOOL, + DWORD, + LPVOID, + LPWSTR, + LPVOID, + LPPROCESS_INFORMATION, + ] + _CreateProcessAsUserW.restype = bool _CreateProcessAsUserW.errcheck = RaiseIfZero if not lpApplicationName: - lpApplicationName = None + lpApplicationName = None if not lpCommandLine: - lpCommandLine = None + lpCommandLine = None else: - lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) + lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) if not lpEnvironment: - lpEnvironment = None + lpEnvironment = None else: - lpEnvironment = ctypes.create_unicode_buffer(lpEnvironment) + lpEnvironment = ctypes.create_unicode_buffer(lpEnvironment) if not lpCurrentDirectory: - lpCurrentDirectory = None + lpCurrentDirectory = None if not lpProcessAttributes: lpProcessAttributes = None else: @@ -1821,22 +2061,35 @@ def CreateProcessAsUserW(hToken = None, lpApplicationName = None, lpCommandLine= else: lpThreadAttributes = byref(lpThreadAttributes) if not lpStartupInfo: - lpStartupInfo = STARTUPINFO() - lpStartupInfo.cb = sizeof(STARTUPINFO) - lpStartupInfo.lpReserved = 0 - lpStartupInfo.lpDesktop = 0 - lpStartupInfo.lpTitle = 0 - lpStartupInfo.dwFlags = 0 - lpStartupInfo.cbReserved2 = 0 - lpStartupInfo.lpReserved2 = 0 - lpProcessInformation = PROCESS_INFORMATION() - lpProcessInformation.hProcess = INVALID_HANDLE_VALUE - lpProcessInformation.hThread = INVALID_HANDLE_VALUE - lpProcessInformation.dwProcessId = 0 - lpProcessInformation.dwThreadId = 0 - _CreateProcessAsUserW(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bool(bInheritHandles), dwCreationFlags, lpEnvironment, lpCurrentDirectory, byref(lpStartupInfo), byref(lpProcessInformation)) + lpStartupInfo = STARTUPINFO() + lpStartupInfo.cb = sizeof(STARTUPINFO) + lpStartupInfo.lpReserved = 0 + lpStartupInfo.lpDesktop = 0 + lpStartupInfo.lpTitle = 0 + lpStartupInfo.dwFlags = 0 + lpStartupInfo.cbReserved2 = 0 + lpStartupInfo.lpReserved2 = 0 + lpProcessInformation = PROCESS_INFORMATION() + lpProcessInformation.hProcess = INVALID_HANDLE_VALUE + lpProcessInformation.hThread = INVALID_HANDLE_VALUE + lpProcessInformation.dwProcessId = 0 + lpProcessInformation.dwThreadId = 0 + _CreateProcessAsUserW( + hToken, + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bool(bInheritHandles), + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + byref(lpStartupInfo), + byref(lpProcessInformation), + ) return ProcessInformation(lpProcessInformation) + CreateProcessAsUser = GuessStringType(CreateProcessAsUserA, CreateProcessAsUserW) # VOID CALLBACK WaitChainCallback( @@ -1849,14 +2102,15 @@ def CreateProcessAsUserW(hToken = None, lpApplicationName = None, lpCommandLine= # ); PWAITCHAINCALLBACK = WINFUNCTYPE(HWCT, DWORD_PTR, DWORD, LPDWORD, PWAITCHAIN_NODE_INFO, LPBOOL) + # HWCT WINAPI OpenThreadWaitChainSession( # __in DWORD Flags, # __in_opt PWAITCHAINCALLBACK callback # ); -def OpenThreadWaitChainSession(Flags = 0, callback = None): +def OpenThreadWaitChainSession(Flags=0, callback=None): _OpenThreadWaitChainSession = windll.advapi32.OpenThreadWaitChainSession _OpenThreadWaitChainSession.argtypes = [DWORD, PVOID] - _OpenThreadWaitChainSession.restype = HWCT + _OpenThreadWaitChainSession.restype = HWCT _OpenThreadWaitChainSession.errcheck = RaiseIfZero if callback is not None: @@ -1864,6 +2118,7 @@ def OpenThreadWaitChainSession(Flags = 0, callback = None): aHandle = _OpenThreadWaitChainSession(Flags, callback) return ThreadWaitChainSessionHandle(aHandle) + # BOOL WINAPI GetThreadWaitChain( # _In_ HWCT WctHandle, # _In_opt_ DWORD_PTR Context, @@ -1873,24 +2128,38 @@ def OpenThreadWaitChainSession(Flags = 0, callback = None): # _Out_ PWAITCHAIN_NODE_INFO NodeInfoArray, # _Out_ LPBOOL IsCycle # ); -def GetThreadWaitChain(WctHandle, Context = None, Flags = WCTP_GETINFO_ALL_FLAGS, ThreadId = -1, NodeCount = WCT_MAX_NODE_COUNT): +def GetThreadWaitChain(WctHandle, Context=None, Flags=WCTP_GETINFO_ALL_FLAGS, ThreadId=-1, NodeCount=WCT_MAX_NODE_COUNT): _GetThreadWaitChain = windll.advapi32.GetThreadWaitChain _GetThreadWaitChain.argtypes = [HWCT, LPDWORD, DWORD, DWORD, LPDWORD, PWAITCHAIN_NODE_INFO, LPBOOL] - _GetThreadWaitChain.restype = bool + _GetThreadWaitChain.restype = bool _GetThreadWaitChain.errcheck = RaiseIfZero dwNodeCount = DWORD(NodeCount) NodeInfoArray = (WAITCHAIN_NODE_INFO * NodeCount)() IsCycle = BOOL(0) - _GetThreadWaitChain(WctHandle, Context, Flags, ThreadId, byref(dwNodeCount), ctypes.cast(ctypes.pointer(NodeInfoArray), PWAITCHAIN_NODE_INFO), byref(IsCycle)) + _GetThreadWaitChain( + WctHandle, + Context, + Flags, + ThreadId, + byref(dwNodeCount), + ctypes.cast(ctypes.pointer(NodeInfoArray), PWAITCHAIN_NODE_INFO), + byref(IsCycle), + ) while dwNodeCount.value > NodeCount: NodeCount = dwNodeCount.value NodeInfoArray = (WAITCHAIN_NODE_INFO * NodeCount)() - _GetThreadWaitChain(WctHandle, Context, Flags, ThreadId, byref(dwNodeCount), ctypes.cast(ctypes.pointer(NodeInfoArray), PWAITCHAIN_NODE_INFO), byref(IsCycle)) - return ( - [ WaitChainNodeInfo(NodeInfoArray[index]) for index in compat.xrange(dwNodeCount.value) ], - bool(IsCycle.value) - ) + _GetThreadWaitChain( + WctHandle, + Context, + Flags, + ThreadId, + byref(dwNodeCount), + ctypes.cast(ctypes.pointer(NodeInfoArray), PWAITCHAIN_NODE_INFO), + byref(IsCycle), + ) + return ([WaitChainNodeInfo(NodeInfoArray[index]) for index in compat.xrange(dwNodeCount.value)], bool(IsCycle.value)) + # VOID WINAPI CloseThreadWaitChainSession( # __in HWCT WctHandle @@ -1900,6 +2169,7 @@ def CloseThreadWaitChainSession(WctHandle): _CloseThreadWaitChainSession.argtypes = [HWCT] _CloseThreadWaitChainSession(WctHandle) + # BOOL WINAPI SaferCreateLevel( # __in DWORD dwScopeId, # __in DWORD dwLevelId, @@ -1910,13 +2180,14 @@ def CloseThreadWaitChainSession(WctHandle): def SaferCreateLevel(dwScopeId=SAFER_SCOPEID_USER, dwLevelId=SAFER_LEVELID_NORMALUSER, OpenFlags=0): _SaferCreateLevel = windll.advapi32.SaferCreateLevel _SaferCreateLevel.argtypes = [DWORD, DWORD, DWORD, POINTER(SAFER_LEVEL_HANDLE), LPVOID] - _SaferCreateLevel.restype = BOOL + _SaferCreateLevel.restype = BOOL _SaferCreateLevel.errcheck = RaiseIfZero hLevelHandle = SAFER_LEVEL_HANDLE(INVALID_HANDLE_VALUE) _SaferCreateLevel(dwScopeId, dwLevelId, OpenFlags, byref(hLevelHandle), None) return SaferLevelHandle(hLevelHandle.value) + # BOOL WINAPI SaferIdentifyLevel( # __in DWORD dwNumProperties, # __in_opt PSAFER_CODE_PROPERTIES pCodeProperties, @@ -1926,6 +2197,7 @@ def SaferCreateLevel(dwScopeId=SAFER_SCOPEID_USER, dwLevelId=SAFER_LEVELID_NORMA # XXX TODO + # BOOL WINAPI SaferComputeTokenFromLevel( # __in SAFER_LEVEL_HANDLE LevelHandle, # __in_opt HANDLE InAccessToken, @@ -1936,7 +2208,7 @@ def SaferCreateLevel(dwScopeId=SAFER_SCOPEID_USER, dwLevelId=SAFER_LEVELID_NORMA def SaferComputeTokenFromLevel(LevelHandle, InAccessToken=None, dwFlags=0): _SaferComputeTokenFromLevel = windll.advapi32.SaferComputeTokenFromLevel _SaferComputeTokenFromLevel.argtypes = [SAFER_LEVEL_HANDLE, HANDLE, PHANDLE, DWORD, LPDWORD] - _SaferComputeTokenFromLevel.restype = BOOL + _SaferComputeTokenFromLevel.restype = BOOL _SaferComputeTokenFromLevel.errcheck = RaiseIfZero OutAccessToken = HANDLE(INVALID_HANDLE_VALUE) @@ -1944,115 +2216,118 @@ def SaferComputeTokenFromLevel(LevelHandle, InAccessToken=None, dwFlags=0): _SaferComputeTokenFromLevel(LevelHandle, InAccessToken, byref(OutAccessToken), dwFlags, byref(lpReserved)) return TokenHandle(OutAccessToken.value), lpReserved.value + # BOOL WINAPI SaferCloseLevel( # __in SAFER_LEVEL_HANDLE hLevelHandle # ); def SaferCloseLevel(hLevelHandle): _SaferCloseLevel = windll.advapi32.SaferCloseLevel _SaferCloseLevel.argtypes = [SAFER_LEVEL_HANDLE] - _SaferCloseLevel.restype = BOOL + _SaferCloseLevel.restype = BOOL _SaferCloseLevel.errcheck = RaiseIfZero - if hasattr(hLevelHandle, 'value'): + if hasattr(hLevelHandle, "value"): _SaferCloseLevel(hLevelHandle.value) else: _SaferCloseLevel(hLevelHandle) + # BOOL SaferiIsExecutableFileType( # __in LPCWSTR szFullPath, # __in BOOLEAN bFromShellExecute # ); -def SaferiIsExecutableFileType(szFullPath, bFromShellExecute = False): +def SaferiIsExecutableFileType(szFullPath, bFromShellExecute=False): _SaferiIsExecutableFileType = windll.advapi32.SaferiIsExecutableFileType _SaferiIsExecutableFileType.argtypes = [LPWSTR, BOOLEAN] - _SaferiIsExecutableFileType.restype = BOOL + _SaferiIsExecutableFileType.restype = BOOL _SaferiIsExecutableFileType.errcheck = RaiseIfLastError SetLastError(ERROR_SUCCESS) return bool(_SaferiIsExecutableFileType(compat.unicode(szFullPath), bFromShellExecute)) + # useful alias since I'm likely to misspell it :P SaferIsExecutableFileType = SaferiIsExecutableFileType -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ + # LONG WINAPI RegCloseKey( # __in HKEY hKey # ); def RegCloseKey(hKey): - if hasattr(hKey, 'value'): + if hasattr(hKey, "value"): value = hKey.value else: value = hKey - if value in ( - HKEY_CLASSES_ROOT, - HKEY_CURRENT_USER, - HKEY_LOCAL_MACHINE, - HKEY_USERS, - HKEY_PERFORMANCE_DATA, - HKEY_CURRENT_CONFIG - ): + if value in (HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_PERFORMANCE_DATA, HKEY_CURRENT_CONFIG): return _RegCloseKey = windll.advapi32.RegCloseKey _RegCloseKey.argtypes = [HKEY] - _RegCloseKey.restype = LONG + _RegCloseKey.restype = LONG _RegCloseKey.errcheck = RaiseIfNotErrorSuccess _RegCloseKey(hKey) + # LONG WINAPI RegConnectRegistry( # __in_opt LPCTSTR lpMachineName, # __in HKEY hKey, # __out PHKEY phkResult # ); -def RegConnectRegistryA(lpMachineName = None, hKey = HKEY_LOCAL_MACHINE): +def RegConnectRegistryA(lpMachineName=None, hKey=HKEY_LOCAL_MACHINE): _RegConnectRegistryA = windll.advapi32.RegConnectRegistryA _RegConnectRegistryA.argtypes = [LPSTR, HKEY, PHKEY] - _RegConnectRegistryA.restype = LONG + _RegConnectRegistryA.restype = LONG _RegConnectRegistryA.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegConnectRegistryA(lpMachineName, hKey, byref(hkResult)) return RegistryKeyHandle(hkResult.value) -def RegConnectRegistryW(lpMachineName = None, hKey = HKEY_LOCAL_MACHINE): + +def RegConnectRegistryW(lpMachineName=None, hKey=HKEY_LOCAL_MACHINE): _RegConnectRegistryW = windll.advapi32.RegConnectRegistryW _RegConnectRegistryW.argtypes = [LPWSTR, HKEY, PHKEY] - _RegConnectRegistryW.restype = LONG + _RegConnectRegistryW.restype = LONG _RegConnectRegistryW.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegConnectRegistryW(lpMachineName, hKey, byref(hkResult)) return RegistryKeyHandle(hkResult.value) + RegConnectRegistry = GuessStringType(RegConnectRegistryA, RegConnectRegistryW) + # LONG WINAPI RegCreateKey( # __in HKEY hKey, # __in_opt LPCTSTR lpSubKey, # __out PHKEY phkResult # ); -def RegCreateKeyA(hKey = HKEY_LOCAL_MACHINE, lpSubKey = None): +def RegCreateKeyA(hKey=HKEY_LOCAL_MACHINE, lpSubKey=None): _RegCreateKeyA = windll.advapi32.RegCreateKeyA _RegCreateKeyA.argtypes = [HKEY, LPSTR, PHKEY] - _RegCreateKeyA.restype = LONG + _RegCreateKeyA.restype = LONG _RegCreateKeyA.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegCreateKeyA(hKey, lpSubKey, byref(hkResult)) return RegistryKeyHandle(hkResult.value) -def RegCreateKeyW(hKey = HKEY_LOCAL_MACHINE, lpSubKey = None): + +def RegCreateKeyW(hKey=HKEY_LOCAL_MACHINE, lpSubKey=None): _RegCreateKeyW = windll.advapi32.RegCreateKeyW _RegCreateKeyW.argtypes = [HKEY, LPWSTR, PHKEY] - _RegCreateKeyW.restype = LONG + _RegCreateKeyW.restype = LONG _RegCreateKeyW.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegCreateKeyW(hKey, lpSubKey, byref(hkResult)) return RegistryKeyHandle(hkResult.value) + RegCreateKey = GuessStringType(RegCreateKeyA, RegCreateKeyW) # LONG WINAPI RegCreateKeyEx( @@ -2069,33 +2344,37 @@ def RegCreateKeyW(hKey = HKEY_LOCAL_MACHINE, lpSubKey = None): # XXX TODO + # LONG WINAPI RegOpenKey( # __in HKEY hKey, # __in_opt LPCTSTR lpSubKey, # __out PHKEY phkResult # ); -def RegOpenKeyA(hKey = HKEY_LOCAL_MACHINE, lpSubKey = None): +def RegOpenKeyA(hKey=HKEY_LOCAL_MACHINE, lpSubKey=None): _RegOpenKeyA = windll.advapi32.RegOpenKeyA _RegOpenKeyA.argtypes = [HKEY, LPSTR, PHKEY] - _RegOpenKeyA.restype = LONG + _RegOpenKeyA.restype = LONG _RegOpenKeyA.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegOpenKeyA(hKey, lpSubKey, byref(hkResult)) return RegistryKeyHandle(hkResult.value) -def RegOpenKeyW(hKey = HKEY_LOCAL_MACHINE, lpSubKey = None): + +def RegOpenKeyW(hKey=HKEY_LOCAL_MACHINE, lpSubKey=None): _RegOpenKeyW = windll.advapi32.RegOpenKeyW _RegOpenKeyW.argtypes = [HKEY, LPWSTR, PHKEY] - _RegOpenKeyW.restype = LONG + _RegOpenKeyW.restype = LONG _RegOpenKeyW.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegOpenKeyW(hKey, lpSubKey, byref(hkResult)) return RegistryKeyHandle(hkResult.value) + RegOpenKey = GuessStringType(RegOpenKeyA, RegOpenKeyW) + # LONG WINAPI RegOpenKeyEx( # __in HKEY hKey, # __in_opt LPCTSTR lpSubKey, @@ -2103,68 +2382,73 @@ def RegOpenKeyW(hKey = HKEY_LOCAL_MACHINE, lpSubKey = None): # __in REGSAM samDesired, # __out PHKEY phkResult # ); -def RegOpenKeyExA(hKey = HKEY_LOCAL_MACHINE, lpSubKey = None, samDesired = KEY_ALL_ACCESS): +def RegOpenKeyExA(hKey=HKEY_LOCAL_MACHINE, lpSubKey=None, samDesired=KEY_ALL_ACCESS): _RegOpenKeyExA = windll.advapi32.RegOpenKeyExA _RegOpenKeyExA.argtypes = [HKEY, LPSTR, DWORD, REGSAM, PHKEY] - _RegOpenKeyExA.restype = LONG + _RegOpenKeyExA.restype = LONG _RegOpenKeyExA.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegOpenKeyExA(hKey, lpSubKey, 0, samDesired, byref(hkResult)) return RegistryKeyHandle(hkResult.value) -def RegOpenKeyExW(hKey = HKEY_LOCAL_MACHINE, lpSubKey = None, samDesired = KEY_ALL_ACCESS): + +def RegOpenKeyExW(hKey=HKEY_LOCAL_MACHINE, lpSubKey=None, samDesired=KEY_ALL_ACCESS): _RegOpenKeyExW = windll.advapi32.RegOpenKeyExW _RegOpenKeyExW.argtypes = [HKEY, LPWSTR, DWORD, REGSAM, PHKEY] - _RegOpenKeyExW.restype = LONG + _RegOpenKeyExW.restype = LONG _RegOpenKeyExW.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegOpenKeyExW(hKey, lpSubKey, 0, samDesired, byref(hkResult)) return RegistryKeyHandle(hkResult.value) + RegOpenKeyEx = GuessStringType(RegOpenKeyExA, RegOpenKeyExW) + # LONG WINAPI RegOpenCurrentUser( # __in REGSAM samDesired, # __out PHKEY phkResult # ); -def RegOpenCurrentUser(samDesired = KEY_ALL_ACCESS): +def RegOpenCurrentUser(samDesired=KEY_ALL_ACCESS): _RegOpenCurrentUser = windll.advapi32.RegOpenCurrentUser _RegOpenCurrentUser.argtypes = [REGSAM, PHKEY] - _RegOpenCurrentUser.restype = LONG + _RegOpenCurrentUser.restype = LONG _RegOpenCurrentUser.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegOpenCurrentUser(samDesired, byref(hkResult)) return RegistryKeyHandle(hkResult.value) + # LONG WINAPI RegOpenUserClassesRoot( # __in HANDLE hToken, # __reserved DWORD dwOptions, # __in REGSAM samDesired, # __out PHKEY phkResult # ); -def RegOpenUserClassesRoot(hToken, samDesired = KEY_ALL_ACCESS): +def RegOpenUserClassesRoot(hToken, samDesired=KEY_ALL_ACCESS): _RegOpenUserClassesRoot = windll.advapi32.RegOpenUserClassesRoot _RegOpenUserClassesRoot.argtypes = [HANDLE, DWORD, REGSAM, PHKEY] - _RegOpenUserClassesRoot.restype = LONG + _RegOpenUserClassesRoot.restype = LONG _RegOpenUserClassesRoot.errcheck = RaiseIfNotErrorSuccess hkResult = HKEY(INVALID_HANDLE_VALUE) _RegOpenUserClassesRoot(hToken, 0, samDesired, byref(hkResult)) return RegistryKeyHandle(hkResult.value) + # LONG WINAPI RegQueryValue( # __in HKEY hKey, # __in_opt LPCTSTR lpSubKey, # __out_opt LPTSTR lpValue, # __inout_opt PLONG lpcbValue # ); -def RegQueryValueA(hKey, lpSubKey = None): +def RegQueryValueA(hKey, lpSubKey=None): _RegQueryValueA = windll.advapi32.RegQueryValueA _RegQueryValueA.argtypes = [HKEY, LPSTR, LPVOID, PLONG] - _RegQueryValueA.restype = LONG + _RegQueryValueA.restype = LONG _RegQueryValueA.errcheck = RaiseIfNotErrorSuccess cbValue = LONG(0) @@ -2173,10 +2457,11 @@ def RegQueryValueA(hKey, lpSubKey = None): _RegQueryValueA(hKey, lpSubKey, lpValue, byref(cbValue)) return lpValue.value -def RegQueryValueW(hKey, lpSubKey = None): + +def RegQueryValueW(hKey, lpSubKey=None): _RegQueryValueW = windll.advapi32.RegQueryValueW _RegQueryValueW.argtypes = [HKEY, LPWSTR, LPVOID, PLONG] - _RegQueryValueW.restype = LONG + _RegQueryValueW.restype = LONG _RegQueryValueW.errcheck = RaiseIfNotErrorSuccess cbValue = LONG(0) @@ -2185,8 +2470,10 @@ def RegQueryValueW(hKey, lpSubKey = None): _RegQueryValueW(hKey, lpSubKey, lpValue, byref(cbValue)) return lpValue.value + RegQueryValue = GuessStringType(RegQueryValueA, RegQueryValueW) + # LONG WINAPI RegQueryValueEx( # __in HKEY hKey, # __in_opt LPCTSTR lpValueName, @@ -2195,7 +2482,7 @@ def RegQueryValueW(hKey, lpSubKey = None): # __out_opt LPBYTE lpData, # __inout_opt LPDWORD lpcbData # ); -def _internal_RegQueryValueEx(ansi, hKey, lpValueName = None, bGetData = True): +def _internal_RegQueryValueEx(ansi, hKey, lpValueName=None, bGetData=True): _RegQueryValueEx = _caller_RegQueryValueEx(ansi) cbData = DWORD(0) @@ -2206,14 +2493,14 @@ def _internal_RegQueryValueEx(ansi, hKey, lpValueName = None, bGetData = True): if not bGetData: return cbData.value, Type - if Type in (REG_DWORD, REG_DWORD_BIG_ENDIAN): # REG_DWORD_LITTLE_ENDIAN + if Type in (REG_DWORD, REG_DWORD_BIG_ENDIAN): # REG_DWORD_LITTLE_ENDIAN if cbData.value != 4: raise ValueError("REG_DWORD value of size %d" % cbData.value) dwData = DWORD(0) _RegQueryValueEx(hKey, lpValueName, None, None, byref(dwData), byref(cbData)) return dwData.value, Type - if Type == REG_QWORD: # REG_QWORD_LITTLE_ENDIAN + if Type == REG_QWORD: # REG_QWORD_LITTLE_ENDIAN if cbData.value != 8: raise ValueError("REG_QWORD value of size %d" % cbData.value) qwData = QWORD(long(0)) @@ -2236,9 +2523,9 @@ def _internal_RegQueryValueEx(ansi, hKey, lpValueName = None, bGetData = True): _RegQueryValueEx(hKey, lpValueName, None, None, byref(szData), byref(cbData)) Data = szData[:] if ansi: - aData = Data.split('\0') + aData = Data.split("\0") else: - aData = Data.split(u'\0') + aData = Data.split("\0") aData = [token for token in aData if token] return aData, Type @@ -2252,6 +2539,7 @@ def _internal_RegQueryValueEx(ansi, hKey, lpValueName = None, bGetData = True): _RegQueryValueEx(hKey, lpValueName, None, None, byref(szData), byref(cbData)) return szData.raw, Type + def _caller_RegQueryValueEx(ansi): if ansi: _RegQueryValueEx = windll.advapi32.RegQueryValueExA @@ -2259,20 +2547,24 @@ def _caller_RegQueryValueEx(ansi): else: _RegQueryValueEx = windll.advapi32.RegQueryValueExW _RegQueryValueEx.argtypes = [HKEY, LPWSTR, LPVOID, PDWORD, LPVOID, PDWORD] - _RegQueryValueEx.restype = LONG + _RegQueryValueEx.restype = LONG _RegQueryValueEx.errcheck = RaiseIfNotErrorSuccess return _RegQueryValueEx + # see _internal_RegQueryValueEx -def RegQueryValueExA(hKey, lpValueName = None, bGetData = True): +def RegQueryValueExA(hKey, lpValueName=None, bGetData=True): return _internal_RegQueryValueEx(True, hKey, lpValueName, bGetData) + # see _internal_RegQueryValueEx -def RegQueryValueExW(hKey, lpValueName = None, bGetData = True): +def RegQueryValueExW(hKey, lpValueName=None, bGetData=True): return _internal_RegQueryValueEx(False, hKey, lpValueName, bGetData) + RegQueryValueEx = GuessStringType(RegQueryValueExA, RegQueryValueExW) + # LONG WINAPI RegSetValueEx( # __in HKEY hKey, # __in_opt LPCTSTR lpValueName, @@ -2281,8 +2573,7 @@ def RegQueryValueExW(hKey, lpValueName = None, bGetData = True): # __in_opt const BYTE *lpData, # __in DWORD cbData # ); -def RegSetValueEx(hKey, lpValueName = None, lpData = None, dwType = None): - +def RegSetValueEx(hKey, lpValueName=None, lpData=None, dwType=None): # Determine which version of the API to use, ANSI or Widechar. if lpValueName is None: if isinstance(lpData, GuessStringType.t_ansi): @@ -2290,7 +2581,7 @@ def RegSetValueEx(hKey, lpValueName = None, lpData = None, dwType = None): elif isinstance(lpData, GuessStringType.t_unicode): ansi = False else: - ansi = (GuessStringType.t_ansi == GuessStringType.t_default) + ansi = GuessStringType.t_ansi == GuessStringType.t_default elif isinstance(lpValueName, GuessStringType.t_ansi): ansi = True elif isinstance(lpValueName, GuessStringType.t_unicode): @@ -2323,17 +2614,17 @@ def RegSetValueEx(hKey, lpValueName = None, lpData = None, dwType = None): else: _RegSetValueEx = windll.advapi32.RegSetValueExW _RegSetValueEx.argtypes = [HKEY, LPWSTR, DWORD, DWORD, LPVOID, DWORD] - _RegSetValueEx.restype = LONG + _RegSetValueEx.restype = LONG _RegSetValueEx.errcheck = RaiseIfNotErrorSuccess # Convert the arguments so ctypes can understand them. if lpData is None: - DataRef = None + DataRef = None DataSize = 0 else: if dwType in (REG_DWORD, REG_DWORD_BIG_ENDIAN): # REG_DWORD_LITTLE_ENDIAN Data = DWORD(lpData) - elif dwType == REG_QWORD: # REG_QWORD_LITTLE_ENDIAN + elif dwType == REG_QWORD: # REG_QWORD_LITTLE_ENDIAN Data = QWORD(lpData) elif dwType in (REG_SZ, REG_EXPAND_SZ): if ansi: @@ -2342,22 +2633,24 @@ def RegSetValueEx(hKey, lpValueName = None, lpData = None, dwType = None): Data = ctypes.create_unicode_buffer(lpData) elif dwType == REG_MULTI_SZ: if ansi: - Data = ctypes.create_string_buffer('\0'.join(lpData) + '\0\0') + Data = ctypes.create_string_buffer("\0".join(lpData) + "\0\0") else: - Data = ctypes.create_unicode_buffer(u'\0'.join(lpData) + u'\0\0') + Data = ctypes.create_unicode_buffer("\0".join(lpData) + "\0\0") elif dwType == REG_LINK: Data = ctypes.create_unicode_buffer(lpData) else: Data = ctypes.create_string_buffer(lpData) - DataRef = byref(Data) + DataRef = byref(Data) DataSize = sizeof(Data) # Call the API with the converted arguments. _RegSetValueEx(hKey, lpValueName, 0, dwType, DataRef, DataSize) + # No "GuessStringType" here since detection is done inside. RegSetValueExA = RegSetValueExW = RegSetValueEx + # LONG WINAPI RegEnumKey( # __in HKEY hKey, # __in DWORD dwIndex, @@ -2367,7 +2660,7 @@ def RegSetValueEx(hKey, lpValueName = None, lpData = None, dwType = None): def RegEnumKeyA(hKey, dwIndex): _RegEnumKeyA = windll.advapi32.RegEnumKeyA _RegEnumKeyA.argtypes = [HKEY, DWORD, LPSTR, DWORD] - _RegEnumKeyA.restype = LONG + _RegEnumKeyA.restype = LONG cchName = 1024 while True: @@ -2384,10 +2677,11 @@ def RegEnumKeyA(hKey, dwIndex): raise ctypes.WinError(errcode) return lpName.value + def RegEnumKeyW(hKey, dwIndex): _RegEnumKeyW = windll.advapi32.RegEnumKeyW _RegEnumKeyW.argtypes = [HKEY, DWORD, LPWSTR, DWORD] - _RegEnumKeyW.restype = LONG + _RegEnumKeyW.restype = LONG cchName = 512 while True: @@ -2404,6 +2698,7 @@ def RegEnumKeyW(hKey, dwIndex): raise ctypes.WinError(errcode) return lpName.value + RegEnumKey = DefaultStringType(RegEnumKeyA, RegEnumKeyW) # LONG WINAPI RegEnumKeyEx( @@ -2419,6 +2714,7 @@ def RegEnumKeyW(hKey, dwIndex): # XXX TODO + # LONG WINAPI RegEnumValue( # __in HKEY hKey, # __in DWORD dwIndex, @@ -2429,14 +2725,14 @@ def RegEnumKeyW(hKey, dwIndex): # __out_opt LPBYTE lpData, # __inout_opt LPDWORD lpcbData # ); -def _internal_RegEnumValue(ansi, hKey, dwIndex, bGetData = True): +def _internal_RegEnumValue(ansi, hKey, dwIndex, bGetData=True): if ansi: _RegEnumValue = windll.advapi32.RegEnumValueA _RegEnumValue.argtypes = [HKEY, DWORD, LPSTR, LPDWORD, LPVOID, LPDWORD, LPVOID, LPDWORD] else: _RegEnumValue = windll.advapi32.RegEnumValueW _RegEnumValue.argtypes = [HKEY, DWORD, LPWSTR, LPDWORD, LPVOID, LPDWORD, LPVOID, LPDWORD] - _RegEnumValue.restype = LONG + _RegEnumValue.restype = LONG cchValueName = DWORD(1024) dwType = DWORD(-1) @@ -2465,12 +2761,12 @@ def _internal_RegEnumValue(ansi, hKey, dwIndex, bGetData = True): if bGetData: Type = dwType.value - if Type in (REG_DWORD, REG_DWORD_BIG_ENDIAN): # REG_DWORD_LITTLE_ENDIAN + if Type in (REG_DWORD, REG_DWORD_BIG_ENDIAN): # REG_DWORD_LITTLE_ENDIAN if cbData.value != sizeof(DWORD): raise ValueError("REG_DWORD value of size %d" % cbData.value) Data = DWORD(0) - elif Type == REG_QWORD: # REG_QWORD_LITTLE_ENDIAN + elif Type == REG_QWORD: # REG_QWORD_LITTLE_ENDIAN if cbData.value != sizeof(QWORD): raise ValueError("REG_QWORD value of size %d" % cbData.value) Data = QWORD(long(0)) @@ -2484,7 +2780,7 @@ def _internal_RegEnumValue(ansi, hKey, dwIndex, bGetData = True): elif Type == REG_LINK: Data = ctypes.create_unicode_buffer(cbData.value) - else: # REG_BINARY, REG_NONE, and any future types + else: # REG_BINARY, REG_NONE, and any future types Data = ctypes.create_string_buffer(cbData.value) lpData = byref(Data) @@ -2493,34 +2789,44 @@ def _internal_RegEnumValue(ansi, hKey, dwIndex, bGetData = True): if errcode == ERROR_NO_MORE_ITEMS: return None - #if errcode != ERROR_SUCCESS: + # if errcode != ERROR_SUCCESS: # raise ctypes.WinError(errcode) if not bGetData: return lpValueName.value, dwType.value - if Type in (REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD, REG_SZ, REG_EXPAND_SZ, REG_LINK): # REG_DWORD_LITTLE_ENDIAN, REG_QWORD_LITTLE_ENDIAN + if Type in ( + REG_DWORD, + REG_DWORD_BIG_ENDIAN, + REG_QWORD, + REG_SZ, + REG_EXPAND_SZ, + REG_LINK, + ): # REG_DWORD_LITTLE_ENDIAN, REG_QWORD_LITTLE_ENDIAN return lpValueName.value, dwType.value, Data.value if Type == REG_MULTI_SZ: sData = Data[:] del Data if ansi: - aData = sData.split('\0') + aData = sData.split("\0") else: - aData = sData.split(u'\0') + aData = sData.split("\0") aData = [token for token in aData if token] return lpValueName.value, dwType.value, aData # REG_BINARY, REG_NONE, and any future types return lpValueName.value, dwType.value, Data.raw -def RegEnumValueA(hKey, dwIndex, bGetData = True): + +def RegEnumValueA(hKey, dwIndex, bGetData=True): return _internal_RegEnumValue(True, hKey, dwIndex, bGetData) -def RegEnumValueW(hKey, dwIndex, bGetData = True): + +def RegEnumValueW(hKey, dwIndex, bGetData=True): return _internal_RegEnumValue(False, hKey, dwIndex, bGetData) + RegEnumValue = DefaultStringType(RegEnumValueA, RegEnumValueW) # XXX TODO @@ -2546,59 +2852,74 @@ def RegEnumValueW(hKey, dwIndex, bGetData = True): # XXX TODO + # LONG WINAPI RegDeleteValue( # __in HKEY hKey, # __in_opt LPCTSTR lpValueName # ); -def RegDeleteValueA(hKeySrc, lpValueName = None): +def RegDeleteValueA(hKeySrc, lpValueName=None): _RegDeleteValueA = windll.advapi32.RegDeleteValueA _RegDeleteValueA.argtypes = [HKEY, LPSTR] - _RegDeleteValueA.restype = LONG + _RegDeleteValueA.restype = LONG _RegDeleteValueA.errcheck = RaiseIfNotErrorSuccess _RegDeleteValueA(hKeySrc, lpValueName) -def RegDeleteValueW(hKeySrc, lpValueName = None): + + +def RegDeleteValueW(hKeySrc, lpValueName=None): _RegDeleteValueW = windll.advapi32.RegDeleteValueW _RegDeleteValueW.argtypes = [HKEY, LPWSTR] - _RegDeleteValueW.restype = LONG + _RegDeleteValueW.restype = LONG _RegDeleteValueW.errcheck = RaiseIfNotErrorSuccess _RegDeleteValueW(hKeySrc, lpValueName) + + RegDeleteValue = GuessStringType(RegDeleteValueA, RegDeleteValueW) + # LONG WINAPI RegDeleteKeyValue( # __in HKEY hKey, # __in_opt LPCTSTR lpSubKey, # __in_opt LPCTSTR lpValueName # ); -def RegDeleteKeyValueA(hKeySrc, lpSubKey = None, lpValueName = None): +def RegDeleteKeyValueA(hKeySrc, lpSubKey=None, lpValueName=None): _RegDeleteKeyValueA = windll.advapi32.RegDeleteKeyValueA _RegDeleteKeyValueA.argtypes = [HKEY, LPSTR, LPSTR] - _RegDeleteKeyValueA.restype = LONG + _RegDeleteKeyValueA.restype = LONG _RegDeleteKeyValueA.errcheck = RaiseIfNotErrorSuccess _RegDeleteKeyValueA(hKeySrc, lpSubKey, lpValueName) -def RegDeleteKeyValueW(hKeySrc, lpSubKey = None, lpValueName = None): + + +def RegDeleteKeyValueW(hKeySrc, lpSubKey=None, lpValueName=None): _RegDeleteKeyValueW = windll.advapi32.RegDeleteKeyValueW _RegDeleteKeyValueW.argtypes = [HKEY, LPWSTR, LPWSTR] - _RegDeleteKeyValueW.restype = LONG + _RegDeleteKeyValueW.restype = LONG _RegDeleteKeyValueW.errcheck = RaiseIfNotErrorSuccess _RegDeleteKeyValueW(hKeySrc, lpSubKey, lpValueName) + + RegDeleteKeyValue = GuessStringType(RegDeleteKeyValueA, RegDeleteKeyValueW) + # LONG WINAPI RegDeleteKey( # __in HKEY hKey, # __in LPCTSTR lpSubKey # ); -def RegDeleteKeyA(hKeySrc, lpSubKey = None): +def RegDeleteKeyA(hKeySrc, lpSubKey=None): _RegDeleteKeyA = windll.advapi32.RegDeleteKeyA _RegDeleteKeyA.argtypes = [HKEY, LPSTR] - _RegDeleteKeyA.restype = LONG + _RegDeleteKeyA.restype = LONG _RegDeleteKeyA.errcheck = RaiseIfNotErrorSuccess _RegDeleteKeyA(hKeySrc, lpSubKey) -def RegDeleteKeyW(hKeySrc, lpSubKey = None): + + +def RegDeleteKeyW(hKeySrc, lpSubKey=None): _RegDeleteKeyW = windll.advapi32.RegDeleteKeyW _RegDeleteKeyW.argtypes = [HKEY, LPWSTR] - _RegDeleteKeyW.restype = LONG + _RegDeleteKeyW.restype = LONG _RegDeleteKeyW.errcheck = RaiseIfNotErrorSuccess _RegDeleteKeyW(hKeySrc, lpSubKey) + + RegDeleteKey = GuessStringType(RegDeleteKeyA, RegDeleteKeyW) # LONG WINAPI RegDeleteKeyEx( @@ -2608,20 +2929,26 @@ def RegDeleteKeyW(hKeySrc, lpSubKey = None): # __reserved DWORD Reserved # ); -def RegDeleteKeyExA(hKeySrc, lpSubKey = None, samDesired = KEY_WOW64_32KEY): + +def RegDeleteKeyExA(hKeySrc, lpSubKey=None, samDesired=KEY_WOW64_32KEY): _RegDeleteKeyExA = windll.advapi32.RegDeleteKeyExA _RegDeleteKeyExA.argtypes = [HKEY, LPSTR, REGSAM, DWORD] - _RegDeleteKeyExA.restype = LONG + _RegDeleteKeyExA.restype = LONG _RegDeleteKeyExA.errcheck = RaiseIfNotErrorSuccess _RegDeleteKeyExA(hKeySrc, lpSubKey, samDesired, 0) -def RegDeleteKeyExW(hKeySrc, lpSubKey = None, samDesired = KEY_WOW64_32KEY): + + +def RegDeleteKeyExW(hKeySrc, lpSubKey=None, samDesired=KEY_WOW64_32KEY): _RegDeleteKeyExW = windll.advapi32.RegDeleteKeyExW _RegDeleteKeyExW.argtypes = [HKEY, LPWSTR, REGSAM, DWORD] - _RegDeleteKeyExW.restype = LONG + _RegDeleteKeyExW.restype = LONG _RegDeleteKeyExW.errcheck = RaiseIfNotErrorSuccess _RegDeleteKeyExW(hKeySrc, lpSubKey, samDesired, 0) + + RegDeleteKeyEx = GuessStringType(RegDeleteKeyExA, RegDeleteKeyExW) + # LONG WINAPI RegCopyTree( # __in HKEY hKeySrc, # __in_opt LPCTSTR lpSubKey, @@ -2630,45 +2957,56 @@ def RegDeleteKeyExW(hKeySrc, lpSubKey = None, samDesired = KEY_WOW64_32KEY): def RegCopyTreeA(hKeySrc, lpSubKey, hKeyDest): _RegCopyTreeA = windll.advapi32.RegCopyTreeA _RegCopyTreeA.argtypes = [HKEY, LPSTR, HKEY] - _RegCopyTreeA.restype = LONG + _RegCopyTreeA.restype = LONG _RegCopyTreeA.errcheck = RaiseIfNotErrorSuccess _RegCopyTreeA(hKeySrc, lpSubKey, hKeyDest) + + def RegCopyTreeW(hKeySrc, lpSubKey, hKeyDest): _RegCopyTreeW = windll.advapi32.RegCopyTreeW _RegCopyTreeW.argtypes = [HKEY, LPWSTR, HKEY] - _RegCopyTreeW.restype = LONG + _RegCopyTreeW.restype = LONG _RegCopyTreeW.errcheck = RaiseIfNotErrorSuccess _RegCopyTreeW(hKeySrc, lpSubKey, hKeyDest) + + RegCopyTree = GuessStringType(RegCopyTreeA, RegCopyTreeW) + # LONG WINAPI RegDeleteTree( # __in HKEY hKey, # __in_opt LPCTSTR lpSubKey # ); -def RegDeleteTreeA(hKey, lpSubKey = None): +def RegDeleteTreeA(hKey, lpSubKey=None): _RegDeleteTreeA = windll.advapi32.RegDeleteTreeA _RegDeleteTreeA.argtypes = [HKEY, LPWSTR] - _RegDeleteTreeA.restype = LONG + _RegDeleteTreeA.restype = LONG _RegDeleteTreeA.errcheck = RaiseIfNotErrorSuccess _RegDeleteTreeA(hKey, lpSubKey) -def RegDeleteTreeW(hKey, lpSubKey = None): + + +def RegDeleteTreeW(hKey, lpSubKey=None): _RegDeleteTreeW = windll.advapi32.RegDeleteTreeW _RegDeleteTreeW.argtypes = [HKEY, LPWSTR] - _RegDeleteTreeW.restype = LONG + _RegDeleteTreeW.restype = LONG _RegDeleteTreeW.errcheck = RaiseIfNotErrorSuccess _RegDeleteTreeW(hKey, lpSubKey) + + RegDeleteTree = GuessStringType(RegDeleteTreeA, RegDeleteTreeW) + # LONG WINAPI RegFlushKey( # __in HKEY hKey # ); def RegFlushKey(hKey): _RegFlushKey = windll.advapi32.RegFlushKey _RegFlushKey.argtypes = [HKEY] - _RegFlushKey.restype = LONG + _RegFlushKey.restype = LONG _RegFlushKey.errcheck = RaiseIfNotErrorSuccess _RegFlushKey(hKey) + # LONG WINAPI RegLoadMUIString( # _In_ HKEY hKey, # _In_opt_ LPCTSTR pszValue, @@ -2681,7 +3019,8 @@ def RegFlushKey(hKey): # TO DO -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ + # BOOL WINAPI CloseServiceHandle( # _In_ SC_HANDLE hSCObject @@ -2689,7 +3028,7 @@ def RegFlushKey(hKey): def CloseServiceHandle(hSCObject): _CloseServiceHandle = windll.advapi32.CloseServiceHandle _CloseServiceHandle.argtypes = [SC_HANDLE] - _CloseServiceHandle.restype = bool + _CloseServiceHandle.restype = bool _CloseServiceHandle.errcheck = RaiseIfZero if isinstance(hSCObject, Handle): @@ -2698,52 +3037,59 @@ def CloseServiceHandle(hSCObject): else: _CloseServiceHandle(hSCObject) + # SC_HANDLE WINAPI OpenSCManager( # _In_opt_ LPCTSTR lpMachineName, # _In_opt_ LPCTSTR lpDatabaseName, # _In_ DWORD dwDesiredAccess # ); -def OpenSCManagerA(lpMachineName = None, lpDatabaseName = None, dwDesiredAccess = SC_MANAGER_ALL_ACCESS): +def OpenSCManagerA(lpMachineName=None, lpDatabaseName=None, dwDesiredAccess=SC_MANAGER_ALL_ACCESS): _OpenSCManagerA = windll.advapi32.OpenSCManagerA _OpenSCManagerA.argtypes = [LPSTR, LPSTR, DWORD] - _OpenSCManagerA.restype = SC_HANDLE + _OpenSCManagerA.restype = SC_HANDLE _OpenSCManagerA.errcheck = RaiseIfZero hSCObject = _OpenSCManagerA(lpMachineName, lpDatabaseName, dwDesiredAccess) return ServiceControlManagerHandle(hSCObject) -def OpenSCManagerW(lpMachineName = None, lpDatabaseName = None, dwDesiredAccess = SC_MANAGER_ALL_ACCESS): + +def OpenSCManagerW(lpMachineName=None, lpDatabaseName=None, dwDesiredAccess=SC_MANAGER_ALL_ACCESS): _OpenSCManagerW = windll.advapi32.OpenSCManagerW _OpenSCManagerW.argtypes = [LPWSTR, LPWSTR, DWORD] - _OpenSCManagerW.restype = SC_HANDLE + _OpenSCManagerW.restype = SC_HANDLE _OpenSCManagerW.errcheck = RaiseIfZero hSCObject = _OpenSCManagerA(lpMachineName, lpDatabaseName, dwDesiredAccess) return ServiceControlManagerHandle(hSCObject) + OpenSCManager = GuessStringType(OpenSCManagerA, OpenSCManagerW) + # SC_HANDLE WINAPI OpenService( # _In_ SC_HANDLE hSCManager, # _In_ LPCTSTR lpServiceName, # _In_ DWORD dwDesiredAccess # ); -def OpenServiceA(hSCManager, lpServiceName, dwDesiredAccess = SERVICE_ALL_ACCESS): +def OpenServiceA(hSCManager, lpServiceName, dwDesiredAccess=SERVICE_ALL_ACCESS): _OpenServiceA = windll.advapi32.OpenServiceA _OpenServiceA.argtypes = [SC_HANDLE, LPSTR, DWORD] - _OpenServiceA.restype = SC_HANDLE + _OpenServiceA.restype = SC_HANDLE _OpenServiceA.errcheck = RaiseIfZero - return ServiceHandle( _OpenServiceA(hSCManager, lpServiceName, dwDesiredAccess) ) + return ServiceHandle(_OpenServiceA(hSCManager, lpServiceName, dwDesiredAccess)) -def OpenServiceW(hSCManager, lpServiceName, dwDesiredAccess = SERVICE_ALL_ACCESS): + +def OpenServiceW(hSCManager, lpServiceName, dwDesiredAccess=SERVICE_ALL_ACCESS): _OpenServiceW = windll.advapi32.OpenServiceW _OpenServiceW.argtypes = [SC_HANDLE, LPWSTR, DWORD] - _OpenServiceW.restype = SC_HANDLE + _OpenServiceW.restype = SC_HANDLE _OpenServiceW.errcheck = RaiseIfZero - return ServiceHandle( _OpenServiceW(hSCManager, lpServiceName, dwDesiredAccess) ) + return ServiceHandle(_OpenServiceW(hSCManager, lpServiceName, dwDesiredAccess)) + OpenService = GuessStringType(OpenServiceA, OpenServiceW) + # SC_HANDLE WINAPI CreateService( # _In_ SC_HANDLE hSCManager, # _In_ LPCTSTR lpServiceName, @@ -2759,60 +3105,94 @@ def OpenServiceW(hSCManager, lpServiceName, dwDesiredAccess = SERVICE_ALL_ACCESS # _In_opt_ LPCTSTR lpServiceStartName, # _In_opt_ LPCTSTR lpPassword # ); -def CreateServiceA(hSCManager, lpServiceName, - lpDisplayName = None, - dwDesiredAccess = SERVICE_ALL_ACCESS, - dwServiceType = SERVICE_WIN32_OWN_PROCESS, - dwStartType = SERVICE_DEMAND_START, - dwErrorControl = SERVICE_ERROR_NORMAL, - lpBinaryPathName = None, - lpLoadOrderGroup = None, - lpDependencies = None, - lpServiceStartName = None, - lpPassword = None): - +def CreateServiceA( + hSCManager, + lpServiceName, + lpDisplayName=None, + dwDesiredAccess=SERVICE_ALL_ACCESS, + dwServiceType=SERVICE_WIN32_OWN_PROCESS, + dwStartType=SERVICE_DEMAND_START, + dwErrorControl=SERVICE_ERROR_NORMAL, + lpBinaryPathName=None, + lpLoadOrderGroup=None, + lpDependencies=None, + lpServiceStartName=None, + lpPassword=None, +): _CreateServiceA = windll.advapi32.CreateServiceA _CreateServiceA.argtypes = [SC_HANDLE, LPSTR, LPSTR, DWORD, DWORD, DWORD, DWORD, LPSTR, LPSTR, LPDWORD, LPSTR, LPSTR, LPSTR] - _CreateServiceA.restype = SC_HANDLE + _CreateServiceA.restype = SC_HANDLE _CreateServiceA.errcheck = RaiseIfZero dwTagId = DWORD(0) - hService = _CreateServiceA(hSCManager, lpServiceName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, byref(dwTagId), lpDependencies, lpServiceStartName, lpPassword) + hService = _CreateServiceA( + hSCManager, + lpServiceName, + dwDesiredAccess, + dwServiceType, + dwStartType, + dwErrorControl, + lpBinaryPathName, + lpLoadOrderGroup, + byref(dwTagId), + lpDependencies, + lpServiceStartName, + lpPassword, + ) return ServiceHandle(hService), dwTagId.value -def CreateServiceW(hSCManager, lpServiceName, - lpDisplayName = None, - dwDesiredAccess = SERVICE_ALL_ACCESS, - dwServiceType = SERVICE_WIN32_OWN_PROCESS, - dwStartType = SERVICE_DEMAND_START, - dwErrorControl = SERVICE_ERROR_NORMAL, - lpBinaryPathName = None, - lpLoadOrderGroup = None, - lpDependencies = None, - lpServiceStartName = None, - lpPassword = None): +def CreateServiceW( + hSCManager, + lpServiceName, + lpDisplayName=None, + dwDesiredAccess=SERVICE_ALL_ACCESS, + dwServiceType=SERVICE_WIN32_OWN_PROCESS, + dwStartType=SERVICE_DEMAND_START, + dwErrorControl=SERVICE_ERROR_NORMAL, + lpBinaryPathName=None, + lpLoadOrderGroup=None, + lpDependencies=None, + lpServiceStartName=None, + lpPassword=None, +): _CreateServiceW = windll.advapi32.CreateServiceW _CreateServiceW.argtypes = [SC_HANDLE, LPWSTR, LPWSTR, DWORD, DWORD, DWORD, DWORD, LPWSTR, LPWSTR, LPDWORD, LPWSTR, LPWSTR, LPWSTR] - _CreateServiceW.restype = SC_HANDLE + _CreateServiceW.restype = SC_HANDLE _CreateServiceW.errcheck = RaiseIfZero dwTagId = DWORD(0) - hService = _CreateServiceW(hSCManager, lpServiceName, dwDesiredAccess, dwServiceType, dwStartType, dwErrorControl, lpBinaryPathName, lpLoadOrderGroup, byref(dwTagId), lpDependencies, lpServiceStartName, lpPassword) + hService = _CreateServiceW( + hSCManager, + lpServiceName, + dwDesiredAccess, + dwServiceType, + dwStartType, + dwErrorControl, + lpBinaryPathName, + lpLoadOrderGroup, + byref(dwTagId), + lpDependencies, + lpServiceStartName, + lpPassword, + ) return ServiceHandle(hService), dwTagId.value + CreateService = GuessStringType(CreateServiceA, CreateServiceW) + # BOOL WINAPI DeleteService( # _In_ SC_HANDLE hService # ); def DeleteService(hService): _DeleteService = windll.advapi32.DeleteService _DeleteService.argtypes = [SC_HANDLE] - _DeleteService.restype = bool + _DeleteService.restype = bool _DeleteService.errcheck = RaiseIfZero _DeleteService(hService) + # BOOL WINAPI GetServiceKeyName( # _In_ SC_HANDLE hSCManager, # _In_ LPCTSTR lpDisplayName, @@ -2822,7 +3202,7 @@ def DeleteService(hService): def GetServiceKeyNameA(hSCManager, lpDisplayName): _GetServiceKeyNameA = windll.advapi32.GetServiceKeyNameA _GetServiceKeyNameA.argtypes = [SC_HANDLE, LPSTR, LPSTR, LPDWORD] - _GetServiceKeyNameA.restype = bool + _GetServiceKeyNameA.restype = bool cchBuffer = DWORD(0) _GetServiceKeyNameA(hSCManager, lpDisplayName, None, byref(cchBuffer)) @@ -2835,10 +3215,11 @@ def GetServiceKeyNameA(hSCManager, lpDisplayName): raise ctypes.WinError() return lpServiceName.value + def GetServiceKeyNameW(hSCManager, lpDisplayName): _GetServiceKeyNameW = windll.advapi32.GetServiceKeyNameW _GetServiceKeyNameW.argtypes = [SC_HANDLE, LPWSTR, LPWSTR, LPDWORD] - _GetServiceKeyNameW.restype = bool + _GetServiceKeyNameW.restype = bool cchBuffer = DWORD(0) _GetServiceKeyNameW(hSCManager, lpDisplayName, None, byref(cchBuffer)) @@ -2851,8 +3232,10 @@ def GetServiceKeyNameW(hSCManager, lpDisplayName): raise ctypes.WinError() return lpServiceName.value + GetServiceKeyName = GuessStringType(GetServiceKeyNameA, GetServiceKeyNameW) + # BOOL WINAPI GetServiceDisplayName( # _In_ SC_HANDLE hSCManager, # _In_ LPCTSTR lpServiceName, @@ -2862,7 +3245,7 @@ def GetServiceKeyNameW(hSCManager, lpDisplayName): def GetServiceDisplayNameA(hSCManager, lpServiceName): _GetServiceDisplayNameA = windll.advapi32.GetServiceDisplayNameA _GetServiceDisplayNameA.argtypes = [SC_HANDLE, LPSTR, LPSTR, LPDWORD] - _GetServiceDisplayNameA.restype = bool + _GetServiceDisplayNameA.restype = bool cchBuffer = DWORD(0) _GetServiceDisplayNameA(hSCManager, lpServiceName, None, byref(cchBuffer)) @@ -2875,10 +3258,11 @@ def GetServiceDisplayNameA(hSCManager, lpServiceName): raise ctypes.WinError() return lpDisplayName.value + def GetServiceDisplayNameW(hSCManager, lpServiceName): _GetServiceDisplayNameW = windll.advapi32.GetServiceDisplayNameW _GetServiceDisplayNameW.argtypes = [SC_HANDLE, LPWSTR, LPWSTR, LPDWORD] - _GetServiceDisplayNameW.restype = bool + _GetServiceDisplayNameW.restype = bool cchBuffer = DWORD(0) _GetServiceDisplayNameW(hSCManager, lpServiceName, None, byref(cchBuffer)) @@ -2891,6 +3275,7 @@ def GetServiceDisplayNameW(hSCManager, lpServiceName): raise ctypes.WinError() return lpDisplayName.value + GetServiceDisplayName = GuessStringType(GetServiceDisplayNameA, GetServiceDisplayNameW) # BOOL WINAPI QueryServiceConfig( @@ -2936,15 +3321,16 @@ def GetServiceDisplayNameW(hSCManager, lpServiceName): # TO DO + # BOOL WINAPI StartService( # _In_ SC_HANDLE hService, # _In_ DWORD dwNumServiceArgs, # _In_opt_ LPCTSTR *lpServiceArgVectors # ); -def StartServiceA(hService, ServiceArgVectors = None): +def StartServiceA(hService, ServiceArgVectors=None): _StartServiceA = windll.advapi32.StartServiceA _StartServiceA.argtypes = [SC_HANDLE, DWORD, LPVOID] - _StartServiceA.restype = bool + _StartServiceA.restype = bool _StartServiceA.errcheck = RaiseIfZero if ServiceArgVectors: @@ -2956,10 +3342,11 @@ def StartServiceA(hService, ServiceArgVectors = None): lpServiceArgVectors = None _StartServiceA(hService, dwNumServiceArgs, lpServiceArgVectors) -def StartServiceW(hService, ServiceArgVectors = None): + +def StartServiceW(hService, ServiceArgVectors=None): _StartServiceW = windll.advapi32.StartServiceW _StartServiceW.argtypes = [SC_HANDLE, DWORD, LPVOID] - _StartServiceW.restype = bool + _StartServiceW.restype = bool _StartServiceW.errcheck = RaiseIfZero if ServiceArgVectors: @@ -2971,8 +3358,10 @@ def StartServiceW(hService, ServiceArgVectors = None): lpServiceArgVectors = None _StartServiceW(hService, dwNumServiceArgs, lpServiceArgVectors) + StartService = GuessStringType(StartServiceA, StartServiceW) + # BOOL WINAPI ControlService( # _In_ SC_HANDLE hService, # _In_ DWORD dwControl, @@ -2981,13 +3370,14 @@ def StartServiceW(hService, ServiceArgVectors = None): def ControlService(hService, dwControl): _ControlService = windll.advapi32.ControlService _ControlService.argtypes = [SC_HANDLE, DWORD, LPSERVICE_STATUS] - _ControlService.restype = bool + _ControlService.restype = bool _ControlService.errcheck = RaiseIfZero rawServiceStatus = SERVICE_STATUS() _ControlService(hService, dwControl, byref(rawServiceStatus)) return ServiceStatus(rawServiceStatus) + # BOOL WINAPI ControlServiceEx( # _In_ SC_HANDLE hService, # _In_ DWORD dwControl, @@ -3005,6 +3395,7 @@ def ControlService(hService, dwControl): # TO DO + # BOOL WINAPI QueryServiceStatus( # _In_ SC_HANDLE hService, # _Out_ LPSERVICE_STATUS lpServiceStatus @@ -3012,13 +3403,14 @@ def ControlService(hService, dwControl): def QueryServiceStatus(hService): _QueryServiceStatus = windll.advapi32.QueryServiceStatus _QueryServiceStatus.argtypes = [SC_HANDLE, LPSERVICE_STATUS] - _QueryServiceStatus.restype = bool + _QueryServiceStatus.restype = bool _QueryServiceStatus.errcheck = RaiseIfZero rawServiceStatus = SERVICE_STATUS() _QueryServiceStatus(hService, byref(rawServiceStatus)) return ServiceStatus(rawServiceStatus) + # BOOL WINAPI QueryServiceStatusEx( # _In_ SC_HANDLE hService, # _In_ SC_STATUS_TYPE InfoLevel, @@ -3026,14 +3418,13 @@ def QueryServiceStatus(hService): # _In_ DWORD cbBufSize, # _Out_ LPDWORD pcbBytesNeeded # ); -def QueryServiceStatusEx(hService, InfoLevel = SC_STATUS_PROCESS_INFO): - +def QueryServiceStatusEx(hService, InfoLevel=SC_STATUS_PROCESS_INFO): if InfoLevel != SC_STATUS_PROCESS_INFO: raise NotImplementedError() _QueryServiceStatusEx = windll.advapi32.QueryServiceStatusEx _QueryServiceStatusEx.argtypes = [SC_HANDLE, SC_STATUS_TYPE, LPVOID, DWORD, LPDWORD] - _QueryServiceStatusEx.restype = bool + _QueryServiceStatusEx.restype = bool _QueryServiceStatusEx.errcheck = RaiseIfZero lpBuffer = SERVICE_STATUS_PROCESS() @@ -3041,6 +3432,7 @@ def QueryServiceStatusEx(hService, InfoLevel = SC_STATUS_PROCESS_INFO): _QueryServiceStatusEx(hService, InfoLevel, byref(lpBuffer), sizeof(lpBuffer), byref(cbBytesNeeded)) return ServiceStatusProcess(lpBuffer) + # BOOL WINAPI EnumServicesStatus( # _In_ SC_HANDLE hSCManager, # _In_ DWORD dwServiceType, @@ -3051,16 +3443,18 @@ def QueryServiceStatusEx(hService, InfoLevel = SC_STATUS_PROCESS_INFO): # _Out_ LPDWORD lpServicesReturned, # _Inout_opt_ LPDWORD lpResumeHandle # ); -def EnumServicesStatusA(hSCManager, dwServiceType = SERVICE_DRIVER | SERVICE_WIN32, dwServiceState = SERVICE_STATE_ALL): +def EnumServicesStatusA(hSCManager, dwServiceType=SERVICE_DRIVER | SERVICE_WIN32, dwServiceState=SERVICE_STATE_ALL): _EnumServicesStatusA = windll.advapi32.EnumServicesStatusA _EnumServicesStatusA.argtypes = [SC_HANDLE, DWORD, DWORD, LPVOID, DWORD, LPDWORD, LPDWORD, LPDWORD] - _EnumServicesStatusA.restype = bool + _EnumServicesStatusA.restype = bool - cbBytesNeeded = DWORD(0) + cbBytesNeeded = DWORD(0) ServicesReturned = DWORD(0) - ResumeHandle = DWORD(0) + ResumeHandle = DWORD(0) - _EnumServicesStatusA(hSCManager, dwServiceType, dwServiceState, None, 0, byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle)) + _EnumServicesStatusA( + hSCManager, dwServiceType, dwServiceState, None, 0, byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle) + ) Services = [] success = False @@ -3068,28 +3462,41 @@ def EnumServicesStatusA(hSCManager, dwServiceType = SERVICE_DRIVER | SERVICE_WIN if cbBytesNeeded.value < sizeof(ENUM_SERVICE_STATUSA): break ServicesBuffer = ctypes.create_string_buffer("", cbBytesNeeded.value) - success = _EnumServicesStatusA(hSCManager, dwServiceType, dwServiceState, byref(ServicesBuffer), sizeof(ServicesBuffer), byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle)) + success = _EnumServicesStatusA( + hSCManager, + dwServiceType, + dwServiceState, + byref(ServicesBuffer), + sizeof(ServicesBuffer), + byref(cbBytesNeeded), + byref(ServicesReturned), + byref(ResumeHandle), + ) if sizeof(ServicesBuffer) < (sizeof(ENUM_SERVICE_STATUSA) * ServicesReturned.value): raise ctypes.WinError() lpServicesArray = ctypes.cast(ctypes.cast(ctypes.pointer(ServicesBuffer), ctypes.c_void_p), LPENUM_SERVICE_STATUSA) for index in compat.xrange(0, ServicesReturned.value): - Services.append( ServiceStatusEntry(lpServicesArray[index]) ) - if success: break + Services.append(ServiceStatusEntry(lpServicesArray[index])) + if success: + break if not success: raise ctypes.WinError() return Services -def EnumServicesStatusW(hSCManager, dwServiceType = SERVICE_DRIVER | SERVICE_WIN32, dwServiceState = SERVICE_STATE_ALL): + +def EnumServicesStatusW(hSCManager, dwServiceType=SERVICE_DRIVER | SERVICE_WIN32, dwServiceState=SERVICE_STATE_ALL): _EnumServicesStatusW = windll.advapi32.EnumServicesStatusW _EnumServicesStatusW.argtypes = [SC_HANDLE, DWORD, DWORD, LPVOID, DWORD, LPDWORD, LPDWORD, LPDWORD] - _EnumServicesStatusW.restype = bool + _EnumServicesStatusW.restype = bool - cbBytesNeeded = DWORD(0) + cbBytesNeeded = DWORD(0) ServicesReturned = DWORD(0) - ResumeHandle = DWORD(0) + ResumeHandle = DWORD(0) - _EnumServicesStatusW(hSCManager, dwServiceType, dwServiceState, None, 0, byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle)) + _EnumServicesStatusW( + hSCManager, dwServiceType, dwServiceState, None, 0, byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle) + ) Services = [] success = False @@ -3097,20 +3504,32 @@ def EnumServicesStatusW(hSCManager, dwServiceType = SERVICE_DRIVER | SERVICE_WIN if cbBytesNeeded.value < sizeof(ENUM_SERVICE_STATUSW): break ServicesBuffer = ctypes.create_string_buffer("", cbBytesNeeded.value) - success = _EnumServicesStatusW(hSCManager, dwServiceType, dwServiceState, byref(ServicesBuffer), sizeof(ServicesBuffer), byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle)) + success = _EnumServicesStatusW( + hSCManager, + dwServiceType, + dwServiceState, + byref(ServicesBuffer), + sizeof(ServicesBuffer), + byref(cbBytesNeeded), + byref(ServicesReturned), + byref(ResumeHandle), + ) if sizeof(ServicesBuffer) < (sizeof(ENUM_SERVICE_STATUSW) * ServicesReturned.value): raise ctypes.WinError() lpServicesArray = ctypes.cast(ctypes.cast(ctypes.pointer(ServicesBuffer), ctypes.c_void_p), LPENUM_SERVICE_STATUSW) for index in compat.xrange(0, ServicesReturned.value): - Services.append( ServiceStatusEntry(lpServicesArray[index]) ) - if success: break + Services.append(ServiceStatusEntry(lpServicesArray[index])) + if success: + break if not success: raise ctypes.WinError() return Services + EnumServicesStatus = DefaultStringType(EnumServicesStatusA, EnumServicesStatusW) + # BOOL WINAPI EnumServicesStatusEx( # _In_ SC_HANDLE hSCManager, # _In_ SC_ENUM_TYPE InfoLevel, @@ -3123,20 +3542,36 @@ def EnumServicesStatusW(hSCManager, dwServiceType = SERVICE_DRIVER | SERVICE_WIN # _Inout_opt_ LPDWORD lpResumeHandle, # _In_opt_ LPCTSTR pszGroupName # ); -def EnumServicesStatusExA(hSCManager, InfoLevel = SC_ENUM_PROCESS_INFO, dwServiceType = SERVICE_DRIVER | SERVICE_WIN32, dwServiceState = SERVICE_STATE_ALL, pszGroupName = None): - +def EnumServicesStatusExA( + hSCManager, + InfoLevel=SC_ENUM_PROCESS_INFO, + dwServiceType=SERVICE_DRIVER | SERVICE_WIN32, + dwServiceState=SERVICE_STATE_ALL, + pszGroupName=None, +): if InfoLevel != SC_ENUM_PROCESS_INFO: raise NotImplementedError() _EnumServicesStatusExA = windll.advapi32.EnumServicesStatusExA _EnumServicesStatusExA.argtypes = [SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPVOID, DWORD, LPDWORD, LPDWORD, LPDWORD, LPSTR] - _EnumServicesStatusExA.restype = bool + _EnumServicesStatusExA.restype = bool - cbBytesNeeded = DWORD(0) + cbBytesNeeded = DWORD(0) ServicesReturned = DWORD(0) - ResumeHandle = DWORD(0) - - _EnumServicesStatusExA(hSCManager, InfoLevel, dwServiceType, dwServiceState, None, 0, byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle), pszGroupName) + ResumeHandle = DWORD(0) + + _EnumServicesStatusExA( + hSCManager, + InfoLevel, + dwServiceType, + dwServiceState, + None, + 0, + byref(cbBytesNeeded), + byref(ServicesReturned), + byref(ResumeHandle), + pszGroupName, + ) Services = [] success = False @@ -3144,31 +3579,61 @@ def EnumServicesStatusExA(hSCManager, InfoLevel = SC_ENUM_PROCESS_INFO, dwServic if cbBytesNeeded.value < sizeof(ENUM_SERVICE_STATUS_PROCESSA): break ServicesBuffer = ctypes.create_string_buffer("", cbBytesNeeded.value) - success = _EnumServicesStatusExA(hSCManager, InfoLevel, dwServiceType, dwServiceState, byref(ServicesBuffer), sizeof(ServicesBuffer), byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle), pszGroupName) + success = _EnumServicesStatusExA( + hSCManager, + InfoLevel, + dwServiceType, + dwServiceState, + byref(ServicesBuffer), + sizeof(ServicesBuffer), + byref(cbBytesNeeded), + byref(ServicesReturned), + byref(ResumeHandle), + pszGroupName, + ) if sizeof(ServicesBuffer) < (sizeof(ENUM_SERVICE_STATUS_PROCESSA) * ServicesReturned.value): raise ctypes.WinError() lpServicesArray = ctypes.cast(ctypes.cast(ctypes.pointer(ServicesBuffer), ctypes.c_void_p), LPENUM_SERVICE_STATUS_PROCESSA) for index in compat.xrange(0, ServicesReturned.value): - Services.append( ServiceStatusProcessEntry(lpServicesArray[index]) ) - if success: break + Services.append(ServiceStatusProcessEntry(lpServicesArray[index])) + if success: + break if not success: raise ctypes.WinError() return Services -def EnumServicesStatusExW(hSCManager, InfoLevel = SC_ENUM_PROCESS_INFO, dwServiceType = SERVICE_DRIVER | SERVICE_WIN32, dwServiceState = SERVICE_STATE_ALL, pszGroupName = None): + +def EnumServicesStatusExW( + hSCManager, + InfoLevel=SC_ENUM_PROCESS_INFO, + dwServiceType=SERVICE_DRIVER | SERVICE_WIN32, + dwServiceState=SERVICE_STATE_ALL, + pszGroupName=None, +): _EnumServicesStatusExW = windll.advapi32.EnumServicesStatusExW _EnumServicesStatusExW.argtypes = [SC_HANDLE, SC_ENUM_TYPE, DWORD, DWORD, LPVOID, DWORD, LPDWORD, LPDWORD, LPDWORD, LPWSTR] - _EnumServicesStatusExW.restype = bool + _EnumServicesStatusExW.restype = bool if InfoLevel != SC_ENUM_PROCESS_INFO: raise NotImplementedError() - cbBytesNeeded = DWORD(0) + cbBytesNeeded = DWORD(0) ServicesReturned = DWORD(0) - ResumeHandle = DWORD(0) - - _EnumServicesStatusExW(hSCManager, InfoLevel, dwServiceType, dwServiceState, None, 0, byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle), pszGroupName) + ResumeHandle = DWORD(0) + + _EnumServicesStatusExW( + hSCManager, + InfoLevel, + dwServiceType, + dwServiceState, + None, + 0, + byref(cbBytesNeeded), + byref(ServicesReturned), + byref(ResumeHandle), + pszGroupName, + ) Services = [] success = False @@ -3176,18 +3641,31 @@ def EnumServicesStatusExW(hSCManager, InfoLevel = SC_ENUM_PROCESS_INFO, dwServic if cbBytesNeeded.value < sizeof(ENUM_SERVICE_STATUS_PROCESSW): break ServicesBuffer = ctypes.create_string_buffer("", cbBytesNeeded.value) - success = _EnumServicesStatusExW(hSCManager, InfoLevel, dwServiceType, dwServiceState, byref(ServicesBuffer), sizeof(ServicesBuffer), byref(cbBytesNeeded), byref(ServicesReturned), byref(ResumeHandle), pszGroupName) + success = _EnumServicesStatusExW( + hSCManager, + InfoLevel, + dwServiceType, + dwServiceState, + byref(ServicesBuffer), + sizeof(ServicesBuffer), + byref(cbBytesNeeded), + byref(ServicesReturned), + byref(ResumeHandle), + pszGroupName, + ) if sizeof(ServicesBuffer) < (sizeof(ENUM_SERVICE_STATUS_PROCESSW) * ServicesReturned.value): raise ctypes.WinError() lpServicesArray = ctypes.cast(ctypes.cast(ctypes.pointer(ServicesBuffer), ctypes.c_void_p), LPENUM_SERVICE_STATUS_PROCESSW) for index in compat.xrange(0, ServicesReturned.value): - Services.append( ServiceStatusProcessEntry(lpServicesArray[index]) ) - if success: break + Services.append(ServiceStatusProcessEntry(lpServicesArray[index])) + if success: + break if not success: raise ctypes.WinError() return Services + EnumServicesStatusEx = DefaultStringType(EnumServicesStatusExA, EnumServicesStatusExW) # BOOL WINAPI EnumDependentServices( @@ -3201,9 +3679,9 @@ def EnumServicesStatusExW(hSCManager, InfoLevel = SC_ENUM_PROCESS_INFO, dwServic # TO DO -#============================================================================== +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/context_amd64.py b/pydevd_attach_to_process/winappdbg/win32/context_amd64.py index eb786b652..cc1e59a36 100644 --- a/pydevd_attach_to_process/winappdbg/win32/context_amd64.py +++ b/pydevd_attach_to_process/winappdbg/win32/context_amd64.py @@ -38,43 +38,43 @@ from winappdbg.win32.version import ARCH_AMD64 from winappdbg.win32 import context_i386 -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== -#--- CONTEXT structures and constants ----------------------------------------- +# --- CONTEXT structures and constants ----------------------------------------- # The following values specify the type of access in the first parameter # of the exception record when the exception code specifies an access # violation. -EXCEPTION_READ_FAULT = 0 # exception caused by a read -EXCEPTION_WRITE_FAULT = 1 # exception caused by a write -EXCEPTION_EXECUTE_FAULT = 8 # exception caused by an instruction fetch +EXCEPTION_READ_FAULT = 0 # exception caused by a read +EXCEPTION_WRITE_FAULT = 1 # exception caused by a write +EXCEPTION_EXECUTE_FAULT = 8 # exception caused by an instruction fetch -CONTEXT_AMD64 = 0x00100000 +CONTEXT_AMD64 = 0x00100000 -CONTEXT_CONTROL = (CONTEXT_AMD64 | long(0x1)) -CONTEXT_INTEGER = (CONTEXT_AMD64 | long(0x2)) -CONTEXT_SEGMENTS = (CONTEXT_AMD64 | long(0x4)) -CONTEXT_FLOATING_POINT = (CONTEXT_AMD64 | long(0x8)) -CONTEXT_DEBUG_REGISTERS = (CONTEXT_AMD64 | long(0x10)) +CONTEXT_CONTROL = CONTEXT_AMD64 | long(0x1) +CONTEXT_INTEGER = CONTEXT_AMD64 | long(0x2) +CONTEXT_SEGMENTS = CONTEXT_AMD64 | long(0x4) +CONTEXT_FLOATING_POINT = CONTEXT_AMD64 | long(0x8) +CONTEXT_DEBUG_REGISTERS = CONTEXT_AMD64 | long(0x10) -CONTEXT_MMX_REGISTERS = CONTEXT_FLOATING_POINT +CONTEXT_MMX_REGISTERS = CONTEXT_FLOATING_POINT -CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT) +CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_FLOATING_POINT -CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \ - CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS) +CONTEXT_ALL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS -CONTEXT_EXCEPTION_ACTIVE = 0x8000000 -CONTEXT_SERVICE_ACTIVE = 0x10000000 -CONTEXT_EXCEPTION_REQUEST = 0x40000000 +CONTEXT_EXCEPTION_ACTIVE = 0x8000000 +CONTEXT_SERVICE_ACTIVE = 0x10000000 +CONTEXT_EXCEPTION_REQUEST = 0x40000000 CONTEXT_EXCEPTION_REPORTING = 0x80000000 -INITIAL_MXCSR = 0x1f80 # initial MXCSR value -INITIAL_FPCSR = 0x027f # initial FPCSR value +INITIAL_MXCSR = 0x1F80 # initial MXCSR value +INITIAL_FPCSR = 0x027F # initial FPCSR value + # typedef struct _XMM_SAVE_AREA32 { # WORD ControlWord; @@ -97,22 +97,22 @@ class XMM_SAVE_AREA32(Structure): _pack_ = 1 _fields_ = [ - ('ControlWord', WORD), - ('StatusWord', WORD), - ('TagWord', BYTE), - ('Reserved1', BYTE), - ('ErrorOpcode', WORD), - ('ErrorOffset', DWORD), - ('ErrorSelector', WORD), - ('Reserved2', WORD), - ('DataOffset', DWORD), - ('DataSelector', WORD), - ('Reserved3', WORD), - ('MxCsr', DWORD), - ('MxCsr_Mask', DWORD), - ('FloatRegisters', M128A * 8), - ('XmmRegisters', M128A * 16), - ('Reserved4', BYTE * 96), + ("ControlWord", WORD), + ("StatusWord", WORD), + ("TagWord", BYTE), + ("Reserved1", BYTE), + ("ErrorOpcode", WORD), + ("ErrorOffset", DWORD), + ("ErrorSelector", WORD), + ("Reserved2", WORD), + ("DataOffset", DWORD), + ("DataSelector", WORD), + ("Reserved3", WORD), + ("MxCsr", DWORD), + ("MxCsr_Mask", DWORD), + ("FloatRegisters", M128A * 8), + ("XmmRegisters", M128A * 16), + ("Reserved4", BYTE * 96), ] def from_dict(self): @@ -121,14 +121,15 @@ def from_dict(self): def to_dict(self): d = dict() for name, type in self._fields_: - if name in ('FloatRegisters', 'XmmRegisters'): - d[name] = tuple([ (x.LowPart + (x.HighPart << 64)) for x in getattr(self, name) ]) - elif name == 'Reserved4': - d[name] = tuple([ chr(x) for x in getattr(self, name) ]) + if name in ("FloatRegisters", "XmmRegisters"): + d[name] = tuple([(x.LowPart + (x.HighPart << 64)) for x in getattr(self, name)]) + elif name == "Reserved4": + d[name] = tuple([chr(x) for x in getattr(self, name)]) else: d[name] = getattr(self, name) return d + LEGACY_SAVE_AREA_LENGTH = sizeof(XMM_SAVE_AREA32) PXMM_SAVE_AREA32 = ctypes.POINTER(XMM_SAVE_AREA32) @@ -286,26 +287,27 @@ def to_dict(self): # DWORD64 LastExceptionFromRip; # } CONTEXT, *PCONTEXT; + class _CONTEXT_FLTSAVE_STRUCT(Structure): _fields_ = [ - ('Header', M128A * 2), - ('Legacy', M128A * 8), - ('Xmm0', M128A), - ('Xmm1', M128A), - ('Xmm2', M128A), - ('Xmm3', M128A), - ('Xmm4', M128A), - ('Xmm5', M128A), - ('Xmm6', M128A), - ('Xmm7', M128A), - ('Xmm8', M128A), - ('Xmm9', M128A), - ('Xmm10', M128A), - ('Xmm11', M128A), - ('Xmm12', M128A), - ('Xmm13', M128A), - ('Xmm14', M128A), - ('Xmm15', M128A), + ("Header", M128A * 2), + ("Legacy", M128A * 8), + ("Xmm0", M128A), + ("Xmm1", M128A), + ("Xmm2", M128A), + ("Xmm3", M128A), + ("Xmm4", M128A), + ("Xmm5", M128A), + ("Xmm6", M128A), + ("Xmm7", M128A), + ("Xmm8", M128A), + ("Xmm9", M128A), + ("Xmm10", M128A), + ("Xmm11", M128A), + ("Xmm12", M128A), + ("Xmm13", M128A), + ("Xmm14", M128A), + ("Xmm15", M128A), ] def from_dict(self): @@ -314,17 +316,18 @@ def from_dict(self): def to_dict(self): d = dict() for name, type in self._fields_: - if name in ('Header', 'Legacy'): - d[name] = tuple([ (x.Low + (x.High << 64)) for x in getattr(self, name) ]) + if name in ("Header", "Legacy"): + d[name] = tuple([(x.Low + (x.High << 64)) for x in getattr(self, name)]) else: x = getattr(self, name) d[name] = x.Low + (x.High << 64) return d + class _CONTEXT_FLTSAVE_UNION(Union): _fields_ = [ - ('flt', XMM_SAVE_AREA32), - ('xmm', _CONTEXT_FLTSAVE_STRUCT), + ("flt", XMM_SAVE_AREA32), + ("xmm", _CONTEXT_FLTSAVE_STRUCT), ] def from_dict(self): @@ -332,105 +335,121 @@ def from_dict(self): def to_dict(self): d = dict() - d['flt'] = self.flt.to_dict() - d['xmm'] = self.xmm.to_dict() + d["flt"] = self.flt.to_dict() + d["xmm"] = self.xmm.to_dict() return d + class CONTEXT(Structure): arch = ARCH_AMD64 _pack_ = 16 _fields_ = [ - # Register parameter home addresses. - ('P1Home', DWORD64), - ('P2Home', DWORD64), - ('P3Home', DWORD64), - ('P4Home', DWORD64), - ('P5Home', DWORD64), - ('P6Home', DWORD64), - + ("P1Home", DWORD64), + ("P2Home", DWORD64), + ("P3Home", DWORD64), + ("P4Home", DWORD64), + ("P5Home", DWORD64), + ("P6Home", DWORD64), # Control flags. - ('ContextFlags', DWORD), - ('MxCsr', DWORD), - + ("ContextFlags", DWORD), + ("MxCsr", DWORD), # Segment Registers and processor flags. - ('SegCs', WORD), - ('SegDs', WORD), - ('SegEs', WORD), - ('SegFs', WORD), - ('SegGs', WORD), - ('SegSs', WORD), - ('EFlags', DWORD), - + ("SegCs", WORD), + ("SegDs", WORD), + ("SegEs", WORD), + ("SegFs", WORD), + ("SegGs", WORD), + ("SegSs", WORD), + ("EFlags", DWORD), # Debug registers. - ('Dr0', DWORD64), - ('Dr1', DWORD64), - ('Dr2', DWORD64), - ('Dr3', DWORD64), - ('Dr6', DWORD64), - ('Dr7', DWORD64), - + ("Dr0", DWORD64), + ("Dr1", DWORD64), + ("Dr2", DWORD64), + ("Dr3", DWORD64), + ("Dr6", DWORD64), + ("Dr7", DWORD64), # Integer registers. - ('Rax', DWORD64), - ('Rcx', DWORD64), - ('Rdx', DWORD64), - ('Rbx', DWORD64), - ('Rsp', DWORD64), - ('Rbp', DWORD64), - ('Rsi', DWORD64), - ('Rdi', DWORD64), - ('R8', DWORD64), - ('R9', DWORD64), - ('R10', DWORD64), - ('R11', DWORD64), - ('R12', DWORD64), - ('R13', DWORD64), - ('R14', DWORD64), - ('R15', DWORD64), - + ("Rax", DWORD64), + ("Rcx", DWORD64), + ("Rdx", DWORD64), + ("Rbx", DWORD64), + ("Rsp", DWORD64), + ("Rbp", DWORD64), + ("Rsi", DWORD64), + ("Rdi", DWORD64), + ("R8", DWORD64), + ("R9", DWORD64), + ("R10", DWORD64), + ("R11", DWORD64), + ("R12", DWORD64), + ("R13", DWORD64), + ("R14", DWORD64), + ("R15", DWORD64), # Program counter. - ('Rip', DWORD64), - + ("Rip", DWORD64), # Floating point state. - ('FltSave', _CONTEXT_FLTSAVE_UNION), - + ("FltSave", _CONTEXT_FLTSAVE_UNION), # Vector registers. - ('VectorRegister', M128A * 26), - ('VectorControl', DWORD64), - + ("VectorRegister", M128A * 26), + ("VectorControl", DWORD64), # Special debug control registers. - ('DebugControl', DWORD64), - ('LastBranchToRip', DWORD64), - ('LastBranchFromRip', DWORD64), - ('LastExceptionToRip', DWORD64), - ('LastExceptionFromRip', DWORD64), + ("DebugControl", DWORD64), + ("LastBranchToRip", DWORD64), + ("LastBranchFromRip", DWORD64), + ("LastExceptionToRip", DWORD64), + ("LastExceptionFromRip", DWORD64), ] - _others = ('P1Home', 'P2Home', 'P3Home', 'P4Home', 'P5Home', 'P6Home', \ - 'MxCsr', 'VectorRegister', 'VectorControl') - _control = ('SegSs', 'Rsp', 'SegCs', 'Rip', 'EFlags') - _integer = ('Rax', 'Rcx', 'Rdx', 'Rbx', 'Rsp', 'Rbp', 'Rsi', 'Rdi', \ - 'R8', 'R9', 'R10', 'R11', 'R12', 'R13', 'R14', 'R15') - _segments = ('SegDs', 'SegEs', 'SegFs', 'SegGs') - _debug = ('Dr0', 'Dr1', 'Dr2', 'Dr3', 'Dr6', 'Dr7', \ - 'DebugControl', 'LastBranchToRip', 'LastBranchFromRip', \ - 'LastExceptionToRip', 'LastExceptionFromRip') - _mmx = ('Xmm0', 'Xmm1', 'Xmm2', 'Xmm3', 'Xmm4', 'Xmm5', 'Xmm6', 'Xmm7', \ - 'Xmm8', 'Xmm9', 'Xmm10', 'Xmm11', 'Xmm12', 'Xmm13', 'Xmm14', 'Xmm15') + _others = ("P1Home", "P2Home", "P3Home", "P4Home", "P5Home", "P6Home", "MxCsr", "VectorRegister", "VectorControl") + _control = ("SegSs", "Rsp", "SegCs", "Rip", "EFlags") + _integer = ("Rax", "Rcx", "Rdx", "Rbx", "Rsp", "Rbp", "Rsi", "Rdi", "R8", "R9", "R10", "R11", "R12", "R13", "R14", "R15") + _segments = ("SegDs", "SegEs", "SegFs", "SegGs") + _debug = ( + "Dr0", + "Dr1", + "Dr2", + "Dr3", + "Dr6", + "Dr7", + "DebugControl", + "LastBranchToRip", + "LastBranchFromRip", + "LastExceptionToRip", + "LastExceptionFromRip", + ) + _mmx = ( + "Xmm0", + "Xmm1", + "Xmm2", + "Xmm3", + "Xmm4", + "Xmm5", + "Xmm6", + "Xmm7", + "Xmm8", + "Xmm9", + "Xmm10", + "Xmm11", + "Xmm12", + "Xmm13", + "Xmm14", + "Xmm15", + ) # XXX TODO # Convert VectorRegister and Xmm0-Xmm15 to pure Python types! @classmethod def from_dict(cls, ctx): - 'Instance a new structure from a Python native type.' + "Instance a new structure from a Python native type." ctx = Context(ctx) s = cls() - ContextFlags = ctx['ContextFlags'] + ContextFlags = ctx["ContextFlags"] s.ContextFlags = ContextFlags for key in cls._others: - if key != 'VectorRegister': + if key != "VectorRegister": setattr(s, key, ctx[key]) else: w = ctx[key] @@ -465,15 +484,15 @@ def from_dict(cls, ctx): return s def to_dict(self): - 'Convert a structure into a Python dictionary.' + "Convert a structure into a Python dictionary." ctx = Context() ContextFlags = self.ContextFlags - ctx['ContextFlags'] = ContextFlags + ctx["ContextFlags"] = ContextFlags for key in self._others: - if key != 'VectorRegister': + if key != "VectorRegister": ctx[key] = getattr(self, key) else: - ctx[key] = tuple([ (x.Low + (x.High << 64)) for x in getattr(self, key) ]) + ctx[key] = tuple([(x.Low + (x.High << 64)) for x in getattr(self, key)]) if (ContextFlags & CONTEXT_CONTROL) == CONTEXT_CONTROL: for key in self._control: ctx[key] = getattr(self, key) @@ -492,9 +511,11 @@ def to_dict(self): ctx[key] = xmm.get(key) return ctx + PCONTEXT = ctypes.POINTER(CONTEXT) LPCONTEXT = PCONTEXT + class Context(dict): """ Register context dictionary for the amd64 architecture. @@ -503,24 +524,31 @@ class Context(dict): arch = CONTEXT.arch def __get_pc(self): - return self['Rip'] + return self["Rip"] + def __set_pc(self, value): - self['Rip'] = value + self["Rip"] = value + pc = property(__get_pc, __set_pc) def __get_sp(self): - return self['Rsp'] + return self["Rsp"] + def __set_sp(self, value): - self['Rsp'] = value + self["Rsp"] = value + sp = property(__get_sp, __set_sp) def __get_fp(self): - return self['Rbp'] + return self["Rbp"] + def __set_fp(self, value): - self['Rbp'] = value + self["Rbp"] = value + fp = property(__get_fp, __set_fp) -#--- LDT_ENTRY structure ------------------------------------------------------ + +# --- LDT_ENTRY structure ------------------------------------------------------ # typedef struct _LDT_ENTRY { # WORD LimitLow; @@ -548,49 +576,54 @@ def __set_fp(self, value): # } LDT_ENTRY, # *PLDT_ENTRY; + class _LDT_ENTRY_BYTES_(Structure): _pack_ = 1 _fields_ = [ - ('BaseMid', BYTE), - ('Flags1', BYTE), - ('Flags2', BYTE), - ('BaseHi', BYTE), + ("BaseMid", BYTE), + ("Flags1", BYTE), + ("Flags2", BYTE), + ("BaseHi", BYTE), ] + class _LDT_ENTRY_BITS_(Structure): _pack_ = 1 _fields_ = [ - ('BaseMid', DWORD, 8), - ('Type', DWORD, 5), - ('Dpl', DWORD, 2), - ('Pres', DWORD, 1), - ('LimitHi', DWORD, 4), - ('Sys', DWORD, 1), - ('Reserved_0', DWORD, 1), - ('Default_Big', DWORD, 1), - ('Granularity', DWORD, 1), - ('BaseHi', DWORD, 8), + ("BaseMid", DWORD, 8), + ("Type", DWORD, 5), + ("Dpl", DWORD, 2), + ("Pres", DWORD, 1), + ("LimitHi", DWORD, 4), + ("Sys", DWORD, 1), + ("Reserved_0", DWORD, 1), + ("Default_Big", DWORD, 1), + ("Granularity", DWORD, 1), + ("BaseHi", DWORD, 8), ] + class _LDT_ENTRY_HIGHWORD_(Union): _pack_ = 1 _fields_ = [ - ('Bytes', _LDT_ENTRY_BYTES_), - ('Bits', _LDT_ENTRY_BITS_), + ("Bytes", _LDT_ENTRY_BYTES_), + ("Bits", _LDT_ENTRY_BITS_), ] + class LDT_ENTRY(Structure): _pack_ = 1 _fields_ = [ - ('LimitLow', WORD), - ('BaseLow', WORD), - ('HighWord', _LDT_ENTRY_HIGHWORD_), + ("LimitLow", WORD), + ("BaseLow", WORD), + ("HighWord", _LDT_ENTRY_HIGHWORD_), ] + PLDT_ENTRY = POINTER(LDT_ENTRY) LPLDT_ENTRY = PLDT_ENTRY -#--- WOW64 CONTEXT structure and constants ------------------------------------ +# --- WOW64 CONTEXT structure and constants ------------------------------------ # Value of SegCs in a Wow64 thread when running in 32 bits mode WOW64_CS32 = 0x23 @@ -598,34 +631,46 @@ class LDT_ENTRY(Structure): WOW64_CONTEXT_i386 = long(0x00010000) WOW64_CONTEXT_i486 = long(0x00010000) -WOW64_CONTEXT_CONTROL = (WOW64_CONTEXT_i386 | long(0x00000001)) -WOW64_CONTEXT_INTEGER = (WOW64_CONTEXT_i386 | long(0x00000002)) -WOW64_CONTEXT_SEGMENTS = (WOW64_CONTEXT_i386 | long(0x00000004)) -WOW64_CONTEXT_FLOATING_POINT = (WOW64_CONTEXT_i386 | long(0x00000008)) -WOW64_CONTEXT_DEBUG_REGISTERS = (WOW64_CONTEXT_i386 | long(0x00000010)) -WOW64_CONTEXT_EXTENDED_REGISTERS = (WOW64_CONTEXT_i386 | long(0x00000020)) +WOW64_CONTEXT_CONTROL = WOW64_CONTEXT_i386 | long(0x00000001) +WOW64_CONTEXT_INTEGER = WOW64_CONTEXT_i386 | long(0x00000002) +WOW64_CONTEXT_SEGMENTS = WOW64_CONTEXT_i386 | long(0x00000004) +WOW64_CONTEXT_FLOATING_POINT = WOW64_CONTEXT_i386 | long(0x00000008) +WOW64_CONTEXT_DEBUG_REGISTERS = WOW64_CONTEXT_i386 | long(0x00000010) +WOW64_CONTEXT_EXTENDED_REGISTERS = WOW64_CONTEXT_i386 | long(0x00000020) + +WOW64_CONTEXT_FULL = WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS +WOW64_CONTEXT_ALL = ( + WOW64_CONTEXT_CONTROL + | WOW64_CONTEXT_INTEGER + | WOW64_CONTEXT_SEGMENTS + | WOW64_CONTEXT_FLOATING_POINT + | WOW64_CONTEXT_DEBUG_REGISTERS + | WOW64_CONTEXT_EXTENDED_REGISTERS +) -WOW64_CONTEXT_FULL = (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS) -WOW64_CONTEXT_ALL = (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS | WOW64_CONTEXT_FLOATING_POINT | WOW64_CONTEXT_DEBUG_REGISTERS | WOW64_CONTEXT_EXTENDED_REGISTERS) +WOW64_SIZE_OF_80387_REGISTERS = 80 +WOW64_MAXIMUM_SUPPORTED_EXTENSION = 512 -WOW64_SIZE_OF_80387_REGISTERS = 80 -WOW64_MAXIMUM_SUPPORTED_EXTENSION = 512 -class WOW64_FLOATING_SAVE_AREA (context_i386.FLOATING_SAVE_AREA): +class WOW64_FLOATING_SAVE_AREA(context_i386.FLOATING_SAVE_AREA): pass -class WOW64_CONTEXT (context_i386.CONTEXT): + +class WOW64_CONTEXT(context_i386.CONTEXT): pass -class WOW64_LDT_ENTRY (context_i386.LDT_ENTRY): + +class WOW64_LDT_ENTRY(context_i386.LDT_ENTRY): pass -PWOW64_FLOATING_SAVE_AREA = POINTER(WOW64_FLOATING_SAVE_AREA) -PWOW64_CONTEXT = POINTER(WOW64_CONTEXT) -PWOW64_LDT_ENTRY = POINTER(WOW64_LDT_ENTRY) + +PWOW64_FLOATING_SAVE_AREA = POINTER(WOW64_FLOATING_SAVE_AREA) +PWOW64_CONTEXT = POINTER(WOW64_CONTEXT) +PWOW64_LDT_ENTRY = POINTER(WOW64_LDT_ENTRY) ############################################################################### + # BOOL WINAPI GetThreadSelectorEntry( # __in HANDLE hThread, # __in DWORD dwSelector, @@ -634,21 +679,22 @@ class WOW64_LDT_ENTRY (context_i386.LDT_ENTRY): def GetThreadSelectorEntry(hThread, dwSelector): _GetThreadSelectorEntry = windll.kernel32.GetThreadSelectorEntry _GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, LPLDT_ENTRY] - _GetThreadSelectorEntry.restype = bool + _GetThreadSelectorEntry.restype = bool _GetThreadSelectorEntry.errcheck = RaiseIfZero ldt = LDT_ENTRY() _GetThreadSelectorEntry(hThread, dwSelector, byref(ldt)) return ldt + # BOOL WINAPI GetThreadContext( # __in HANDLE hThread, # __inout LPCONTEXT lpContext # ); -def GetThreadContext(hThread, ContextFlags = None, raw = False): +def GetThreadContext(hThread, ContextFlags=None, raw=False): _GetThreadContext = windll.kernel32.GetThreadContext _GetThreadContext.argtypes = [HANDLE, LPCONTEXT] - _GetThreadContext.restype = bool + _GetThreadContext.restype = bool _GetThreadContext.errcheck = RaiseIfZero if ContextFlags is None: @@ -660,6 +706,7 @@ def GetThreadContext(hThread, ContextFlags = None, raw = False): return Context return Context.to_dict() + # BOOL WINAPI SetThreadContext( # __in HANDLE hThread, # __in const CONTEXT* lpContext @@ -667,13 +714,14 @@ def GetThreadContext(hThread, ContextFlags = None, raw = False): def SetThreadContext(hThread, lpContext): _SetThreadContext = windll.kernel32.SetThreadContext _SetThreadContext.argtypes = [HANDLE, LPCONTEXT] - _SetThreadContext.restype = bool + _SetThreadContext.restype = bool _SetThreadContext.errcheck = RaiseIfZero if isinstance(lpContext, dict): lpContext = CONTEXT.from_dict(lpContext) _SetThreadContext(hThread, byref(lpContext)) + # BOOL Wow64GetThreadSelectorEntry( # __in HANDLE hThread, # __in DWORD dwSelector, @@ -682,50 +730,54 @@ def SetThreadContext(hThread, lpContext): def Wow64GetThreadSelectorEntry(hThread, dwSelector): _Wow64GetThreadSelectorEntry = windll.kernel32.Wow64GetThreadSelectorEntry _Wow64GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, PWOW64_LDT_ENTRY] - _Wow64GetThreadSelectorEntry.restype = bool + _Wow64GetThreadSelectorEntry.restype = bool _Wow64GetThreadSelectorEntry.errcheck = RaiseIfZero lpSelectorEntry = WOW64_LDT_ENTRY() _Wow64GetThreadSelectorEntry(hThread, dwSelector, byref(lpSelectorEntry)) return lpSelectorEntry + # DWORD WINAPI Wow64ResumeThread( # __in HANDLE hThread # ); def Wow64ResumeThread(hThread): _Wow64ResumeThread = windll.kernel32.Wow64ResumeThread _Wow64ResumeThread.argtypes = [HANDLE] - _Wow64ResumeThread.restype = DWORD + _Wow64ResumeThread.restype = DWORD previousCount = _Wow64ResumeThread(hThread) if previousCount == DWORD(-1).value: raise ctypes.WinError() return previousCount + # DWORD WINAPI Wow64SuspendThread( # __in HANDLE hThread # ); def Wow64SuspendThread(hThread): _Wow64SuspendThread = windll.kernel32.Wow64SuspendThread _Wow64SuspendThread.argtypes = [HANDLE] - _Wow64SuspendThread.restype = DWORD + _Wow64SuspendThread.restype = DWORD previousCount = _Wow64SuspendThread(hThread) if previousCount == DWORD(-1).value: raise ctypes.WinError() return previousCount + # XXX TODO Use this http://www.nynaeve.net/Code/GetThreadWow64Context.cpp # Also see http://www.woodmann.com/forum/archive/index.php/t-11162.html + # BOOL WINAPI Wow64GetThreadContext( # __in HANDLE hThread, # __inout PWOW64_CONTEXT lpContext # ); -def Wow64GetThreadContext(hThread, ContextFlags = None): +def Wow64GetThreadContext(hThread, ContextFlags=None): _Wow64GetThreadContext = windll.kernel32.Wow64GetThreadContext _Wow64GetThreadContext.argtypes = [HANDLE, PWOW64_CONTEXT] - _Wow64GetThreadContext.restype = bool + _Wow64GetThreadContext.restype = bool _Wow64GetThreadContext.errcheck = RaiseIfZero # XXX doesn't exist in XP 64 bits @@ -738,6 +790,7 @@ def Wow64GetThreadContext(hThread, ContextFlags = None): _Wow64GetThreadContext(hThread, byref(Context)) return Context.to_dict() + # BOOL WINAPI Wow64SetThreadContext( # __in HANDLE hThread, # __in const WOW64_CONTEXT *lpContext @@ -745,7 +798,7 @@ def Wow64GetThreadContext(hThread, ContextFlags = None): def Wow64SetThreadContext(hThread, lpContext): _Wow64SetThreadContext = windll.kernel32.Wow64SetThreadContext _Wow64SetThreadContext.argtypes = [HANDLE, PWOW64_CONTEXT] - _Wow64SetThreadContext.restype = bool + _Wow64SetThreadContext.restype = bool _Wow64SetThreadContext.errcheck = RaiseIfZero # XXX doesn't exist in XP 64 bits @@ -754,9 +807,10 @@ def Wow64SetThreadContext(hThread, lpContext): lpContext = WOW64_CONTEXT.from_dict(lpContext) _Wow64SetThreadContext(hThread, byref(lpContext)) -#============================================================================== + +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/context_i386.py b/pydevd_attach_to_process/winappdbg/win32/context_i386.py index 91ff2d93e..fa24b3bf7 100644 --- a/pydevd_attach_to_process/winappdbg/win32/context_i386.py +++ b/pydevd_attach_to_process/winappdbg/win32/context_i386.py @@ -37,40 +37,41 @@ from winappdbg.win32.defines import * from winappdbg.win32.version import ARCH_I386 -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== -#--- CONTEXT structures and constants ----------------------------------------- +# --- CONTEXT structures and constants ----------------------------------------- # The following values specify the type of access in the first parameter # of the exception record when the exception code specifies an access # violation. -EXCEPTION_READ_FAULT = 0 # exception caused by a read -EXCEPTION_WRITE_FAULT = 1 # exception caused by a write -EXCEPTION_EXECUTE_FAULT = 8 # exception caused by an instruction fetch +EXCEPTION_READ_FAULT = 0 # exception caused by a read +EXCEPTION_WRITE_FAULT = 1 # exception caused by a write +EXCEPTION_EXECUTE_FAULT = 8 # exception caused by an instruction fetch -CONTEXT_i386 = 0x00010000 # this assumes that i386 and -CONTEXT_i486 = 0x00010000 # i486 have identical context records +CONTEXT_i386 = 0x00010000 # this assumes that i386 and +CONTEXT_i486 = 0x00010000 # i486 have identical context records -CONTEXT_CONTROL = (CONTEXT_i386 | long(0x00000001)) # SS:SP, CS:IP, FLAGS, BP -CONTEXT_INTEGER = (CONTEXT_i386 | long(0x00000002)) # AX, BX, CX, DX, SI, DI -CONTEXT_SEGMENTS = (CONTEXT_i386 | long(0x00000004)) # DS, ES, FS, GS -CONTEXT_FLOATING_POINT = (CONTEXT_i386 | long(0x00000008)) # 387 state -CONTEXT_DEBUG_REGISTERS = (CONTEXT_i386 | long(0x00000010)) # DB 0-3,6,7 -CONTEXT_EXTENDED_REGISTERS = (CONTEXT_i386 | long(0x00000020)) # cpu specific extensions +CONTEXT_CONTROL = CONTEXT_i386 | long(0x00000001) # SS:SP, CS:IP, FLAGS, BP +CONTEXT_INTEGER = CONTEXT_i386 | long(0x00000002) # AX, BX, CX, DX, SI, DI +CONTEXT_SEGMENTS = CONTEXT_i386 | long(0x00000004) # DS, ES, FS, GS +CONTEXT_FLOATING_POINT = CONTEXT_i386 | long(0x00000008) # 387 state +CONTEXT_DEBUG_REGISTERS = CONTEXT_i386 | long(0x00000010) # DB 0-3,6,7 +CONTEXT_EXTENDED_REGISTERS = CONTEXT_i386 | long(0x00000020) # cpu specific extensions -CONTEXT_FULL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS) +CONTEXT_FULL = CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS -CONTEXT_ALL = (CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | \ - CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | \ - CONTEXT_EXTENDED_REGISTERS) +CONTEXT_ALL = ( + CONTEXT_CONTROL | CONTEXT_INTEGER | CONTEXT_SEGMENTS | CONTEXT_FLOATING_POINT | CONTEXT_DEBUG_REGISTERS | CONTEXT_EXTENDED_REGISTERS +) -SIZE_OF_80387_REGISTERS = 80 +SIZE_OF_80387_REGISTERS = 80 MAXIMUM_SUPPORTED_EXTENSION = 512 + # typedef struct _FLOATING_SAVE_AREA { # DWORD ControlWord; # DWORD StatusWord; @@ -85,45 +86,47 @@ class FLOATING_SAVE_AREA(Structure): _pack_ = 1 _fields_ = [ - ('ControlWord', DWORD), - ('StatusWord', DWORD), - ('TagWord', DWORD), - ('ErrorOffset', DWORD), - ('ErrorSelector', DWORD), - ('DataOffset', DWORD), - ('DataSelector', DWORD), - ('RegisterArea', BYTE * SIZE_OF_80387_REGISTERS), - ('Cr0NpxState', DWORD), + ("ControlWord", DWORD), + ("StatusWord", DWORD), + ("TagWord", DWORD), + ("ErrorOffset", DWORD), + ("ErrorSelector", DWORD), + ("DataOffset", DWORD), + ("DataSelector", DWORD), + ("RegisterArea", BYTE * SIZE_OF_80387_REGISTERS), + ("Cr0NpxState", DWORD), ] - _integer_members = ('ControlWord', 'StatusWord', 'TagWord', 'ErrorOffset', 'ErrorSelector', 'DataOffset', 'DataSelector', 'Cr0NpxState') + _integer_members = ("ControlWord", "StatusWord", "TagWord", "ErrorOffset", "ErrorSelector", "DataOffset", "DataSelector", "Cr0NpxState") @classmethod def from_dict(cls, fsa): - 'Instance a new structure from a Python dictionary.' + "Instance a new structure from a Python dictionary." fsa = dict(fsa) s = cls() for key in cls._integer_members: setattr(s, key, fsa.get(key)) - ra = fsa.get('RegisterArea', None) + ra = fsa.get("RegisterArea", None) if ra is not None: for index in compat.xrange(0, SIZE_OF_80387_REGISTERS): s.RegisterArea[index] = ra[index] return s def to_dict(self): - 'Convert a structure into a Python dictionary.' + "Convert a structure into a Python dictionary." fsa = dict() for key in self._integer_members: fsa[key] = getattr(self, key) - ra = [ self.RegisterArea[index] for index in compat.xrange(0, SIZE_OF_80387_REGISTERS) ] + ra = [self.RegisterArea[index] for index in compat.xrange(0, SIZE_OF_80387_REGISTERS)] ra = tuple(ra) - fsa['RegisterArea'] = ra + fsa["RegisterArea"] = ra return fsa + PFLOATING_SAVE_AREA = POINTER(FLOATING_SAVE_AREA) LPFLOATING_SAVE_AREA = PFLOATING_SAVE_AREA + # typedef struct _CONTEXT { # DWORD ContextFlags; # DWORD Dr0; @@ -165,7 +168,6 @@ class CONTEXT(Structure): # The layout of the record conforms to a standard call frame. _fields_ = [ - # The flags values within this flag control the contents of # a CONTEXT record. # @@ -181,77 +183,69 @@ class CONTEXT(Structure): # context corresponding to set flags will be returned. # # The context record is never used as an OUT only parameter. - - ('ContextFlags', DWORD), - + ("ContextFlags", DWORD), # This section is specified/returned if CONTEXT_DEBUG_REGISTERS is # set in ContextFlags. Note that CONTEXT_DEBUG_REGISTERS is NOT # included in CONTEXT_FULL. - - ('Dr0', DWORD), - ('Dr1', DWORD), - ('Dr2', DWORD), - ('Dr3', DWORD), - ('Dr6', DWORD), - ('Dr7', DWORD), - + ("Dr0", DWORD), + ("Dr1", DWORD), + ("Dr2", DWORD), + ("Dr3", DWORD), + ("Dr6", DWORD), + ("Dr7", DWORD), # This section is specified/returned if the # ContextFlags word contains the flag CONTEXT_FLOATING_POINT. - - ('FloatSave', FLOATING_SAVE_AREA), - + ("FloatSave", FLOATING_SAVE_AREA), # This section is specified/returned if the # ContextFlags word contains the flag CONTEXT_SEGMENTS. - - ('SegGs', DWORD), - ('SegFs', DWORD), - ('SegEs', DWORD), - ('SegDs', DWORD), - + ("SegGs", DWORD), + ("SegFs", DWORD), + ("SegEs", DWORD), + ("SegDs", DWORD), # This section is specified/returned if the # ContextFlags word contains the flag CONTEXT_INTEGER. - - ('Edi', DWORD), - ('Esi', DWORD), - ('Ebx', DWORD), - ('Edx', DWORD), - ('Ecx', DWORD), - ('Eax', DWORD), - + ("Edi", DWORD), + ("Esi", DWORD), + ("Ebx", DWORD), + ("Edx", DWORD), + ("Ecx", DWORD), + ("Eax", DWORD), # This section is specified/returned if the # ContextFlags word contains the flag CONTEXT_CONTROL. - - ('Ebp', DWORD), - ('Eip', DWORD), - ('SegCs', DWORD), # MUST BE SANITIZED - ('EFlags', DWORD), # MUST BE SANITIZED - ('Esp', DWORD), - ('SegSs', DWORD), - + ("Ebp", DWORD), + ("Eip", DWORD), + ("SegCs", DWORD), # MUST BE SANITIZED + ("EFlags", DWORD), # MUST BE SANITIZED + ("Esp", DWORD), + ("SegSs", DWORD), # This section is specified/returned if the ContextFlags word # contains the flag CONTEXT_EXTENDED_REGISTERS. # The format and contexts are processor specific. - - ('ExtendedRegisters', BYTE * MAXIMUM_SUPPORTED_EXTENSION), + ("ExtendedRegisters", BYTE * MAXIMUM_SUPPORTED_EXTENSION), ] - _ctx_debug = ('Dr0', 'Dr1', 'Dr2', 'Dr3', 'Dr6', 'Dr7') - _ctx_segs = ('SegGs', 'SegFs', 'SegEs', 'SegDs', ) - _ctx_int = ('Edi', 'Esi', 'Ebx', 'Edx', 'Ecx', 'Eax') - _ctx_ctrl = ('Ebp', 'Eip', 'SegCs', 'EFlags', 'Esp', 'SegSs') + _ctx_debug = ("Dr0", "Dr1", "Dr2", "Dr3", "Dr6", "Dr7") + _ctx_segs = ( + "SegGs", + "SegFs", + "SegEs", + "SegDs", + ) + _ctx_int = ("Edi", "Esi", "Ebx", "Edx", "Ecx", "Eax") + _ctx_ctrl = ("Ebp", "Eip", "SegCs", "EFlags", "Esp", "SegSs") @classmethod def from_dict(cls, ctx): - 'Instance a new structure from a Python dictionary.' + "Instance a new structure from a Python dictionary." ctx = Context(ctx) s = cls() - ContextFlags = ctx['ContextFlags'] - setattr(s, 'ContextFlags', ContextFlags) + ContextFlags = ctx["ContextFlags"] + setattr(s, "ContextFlags", ContextFlags) if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS: for key in s._ctx_debug: setattr(s, key, ctx[key]) if (ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT: - fsa = ctx['FloatSave'] + fsa = ctx["FloatSave"] s.FloatSave = FLOATING_SAVE_AREA.from_dict(fsa) if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS: for key in s._ctx_segs: @@ -263,21 +257,21 @@ def from_dict(cls, ctx): for key in s._ctx_ctrl: setattr(s, key, ctx[key]) if (ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS: - er = ctx['ExtendedRegisters'] + er = ctx["ExtendedRegisters"] for index in compat.xrange(0, MAXIMUM_SUPPORTED_EXTENSION): s.ExtendedRegisters[index] = er[index] return s def to_dict(self): - 'Convert a structure into a Python native type.' + "Convert a structure into a Python native type." ctx = Context() ContextFlags = self.ContextFlags - ctx['ContextFlags'] = ContextFlags + ctx["ContextFlags"] = ContextFlags if (ContextFlags & CONTEXT_DEBUG_REGISTERS) == CONTEXT_DEBUG_REGISTERS: for key in self._ctx_debug: ctx[key] = getattr(self, key) if (ContextFlags & CONTEXT_FLOATING_POINT) == CONTEXT_FLOATING_POINT: - ctx['FloatSave'] = self.FloatSave.to_dict() + ctx["FloatSave"] = self.FloatSave.to_dict() if (ContextFlags & CONTEXT_SEGMENTS) == CONTEXT_SEGMENTS: for key in self._ctx_segs: ctx[key] = getattr(self, key) @@ -288,14 +282,16 @@ def to_dict(self): for key in self._ctx_ctrl: ctx[key] = getattr(self, key) if (ContextFlags & CONTEXT_EXTENDED_REGISTERS) == CONTEXT_EXTENDED_REGISTERS: - er = [ self.ExtendedRegisters[index] for index in compat.xrange(0, MAXIMUM_SUPPORTED_EXTENSION) ] + er = [self.ExtendedRegisters[index] for index in compat.xrange(0, MAXIMUM_SUPPORTED_EXTENSION)] er = tuple(er) - ctx['ExtendedRegisters'] = er + ctx["ExtendedRegisters"] = er return ctx + PCONTEXT = POINTER(CONTEXT) LPCONTEXT = PCONTEXT + class Context(dict): """ Register context dictionary for the i386 architecture. @@ -304,24 +300,31 @@ class Context(dict): arch = CONTEXT.arch def __get_pc(self): - return self['Eip'] + return self["Eip"] + def __set_pc(self, value): - self['Eip'] = value + self["Eip"] = value + pc = property(__get_pc, __set_pc) def __get_sp(self): - return self['Esp'] + return self["Esp"] + def __set_sp(self, value): - self['Esp'] = value + self["Esp"] = value + sp = property(__get_sp, __set_sp) def __get_fp(self): - return self['Ebp'] + return self["Ebp"] + def __set_fp(self, value): - self['Ebp'] = value + self["Ebp"] = value + fp = property(__get_fp, __set_fp) -#--- LDT_ENTRY structure ------------------------------------------------------ + +# --- LDT_ENTRY structure ------------------------------------------------------ # typedef struct _LDT_ENTRY { # WORD LimitLow; @@ -349,50 +352,56 @@ def __set_fp(self, value): # } LDT_ENTRY, # *PLDT_ENTRY; + class _LDT_ENTRY_BYTES_(Structure): _pack_ = 1 _fields_ = [ - ('BaseMid', BYTE), - ('Flags1', BYTE), - ('Flags2', BYTE), - ('BaseHi', BYTE), + ("BaseMid", BYTE), + ("Flags1", BYTE), + ("Flags2", BYTE), + ("BaseHi", BYTE), ] + class _LDT_ENTRY_BITS_(Structure): _pack_ = 1 _fields_ = [ - ('BaseMid', DWORD, 8), - ('Type', DWORD, 5), - ('Dpl', DWORD, 2), - ('Pres', DWORD, 1), - ('LimitHi', DWORD, 4), - ('Sys', DWORD, 1), - ('Reserved_0', DWORD, 1), - ('Default_Big', DWORD, 1), - ('Granularity', DWORD, 1), - ('BaseHi', DWORD, 8), + ("BaseMid", DWORD, 8), + ("Type", DWORD, 5), + ("Dpl", DWORD, 2), + ("Pres", DWORD, 1), + ("LimitHi", DWORD, 4), + ("Sys", DWORD, 1), + ("Reserved_0", DWORD, 1), + ("Default_Big", DWORD, 1), + ("Granularity", DWORD, 1), + ("BaseHi", DWORD, 8), ] + class _LDT_ENTRY_HIGHWORD_(Union): _pack_ = 1 _fields_ = [ - ('Bytes', _LDT_ENTRY_BYTES_), - ('Bits', _LDT_ENTRY_BITS_), + ("Bytes", _LDT_ENTRY_BYTES_), + ("Bits", _LDT_ENTRY_BITS_), ] + class LDT_ENTRY(Structure): _pack_ = 1 _fields_ = [ - ('LimitLow', WORD), - ('BaseLow', WORD), - ('HighWord', _LDT_ENTRY_HIGHWORD_), + ("LimitLow", WORD), + ("BaseLow", WORD), + ("HighWord", _LDT_ENTRY_HIGHWORD_), ] + PLDT_ENTRY = POINTER(LDT_ENTRY) LPLDT_ENTRY = PLDT_ENTRY ############################################################################### + # BOOL WINAPI GetThreadSelectorEntry( # __in HANDLE hThread, # __in DWORD dwSelector, @@ -401,21 +410,22 @@ class LDT_ENTRY(Structure): def GetThreadSelectorEntry(hThread, dwSelector): _GetThreadSelectorEntry = windll.kernel32.GetThreadSelectorEntry _GetThreadSelectorEntry.argtypes = [HANDLE, DWORD, LPLDT_ENTRY] - _GetThreadSelectorEntry.restype = bool + _GetThreadSelectorEntry.restype = bool _GetThreadSelectorEntry.errcheck = RaiseIfZero ldt = LDT_ENTRY() _GetThreadSelectorEntry(hThread, dwSelector, byref(ldt)) return ldt + # BOOL WINAPI GetThreadContext( # __in HANDLE hThread, # __inout LPCONTEXT lpContext # ); -def GetThreadContext(hThread, ContextFlags = None, raw = False): +def GetThreadContext(hThread, ContextFlags=None, raw=False): _GetThreadContext = windll.kernel32.GetThreadContext _GetThreadContext.argtypes = [HANDLE, LPCONTEXT] - _GetThreadContext.restype = bool + _GetThreadContext.restype = bool _GetThreadContext.errcheck = RaiseIfZero if ContextFlags is None: @@ -427,6 +437,7 @@ def GetThreadContext(hThread, ContextFlags = None, raw = False): return Context return Context.to_dict() + # BOOL WINAPI SetThreadContext( # __in HANDLE hThread, # __in const CONTEXT* lpContext @@ -434,16 +445,17 @@ def GetThreadContext(hThread, ContextFlags = None, raw = False): def SetThreadContext(hThread, lpContext): _SetThreadContext = windll.kernel32.SetThreadContext _SetThreadContext.argtypes = [HANDLE, LPCONTEXT] - _SetThreadContext.restype = bool + _SetThreadContext.restype = bool _SetThreadContext.errcheck = RaiseIfZero if isinstance(lpContext, dict): lpContext = CONTEXT.from_dict(lpContext) _SetThreadContext(hThread, byref(lpContext)) -#============================================================================== + +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/dbghelp.py b/pydevd_attach_to_process/winappdbg/win32/dbghelp.py index 17c843ee1..c3f5bfd83 100644 --- a/pydevd_attach_to_process/winappdbg/win32/dbghelp.py +++ b/pydevd_attach_to_process/winappdbg/win32/dbghelp.py @@ -41,36 +41,27 @@ # DbgHelp versions and features list: # http://msdn.microsoft.com/en-us/library/windows/desktop/ms679294(v=vs.85).aspx -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Tries to load the newest version of dbghelp.dll if available. -def _load_latest_dbghelp_dll(): +def _load_latest_dbghelp_dll(): from os import getenv from os.path import join, exists program_files_location = getenv("ProgramFiles") if not program_files_location: program_files_location = "C:\\Program Files" - + program_files_x86_location = getenv("ProgramFiles(x86)") - + if arch == ARCH_AMD64: if wow64: - pathname = join( - program_files_x86_location or program_files_location, - "Debugging Tools for Windows (x86)", - "dbghelp.dll") + pathname = join(program_files_x86_location or program_files_location, "Debugging Tools for Windows (x86)", "dbghelp.dll") else: - pathname = join( - program_files_location, - "Debugging Tools for Windows (x64)", - "dbghelp.dll") + pathname = join(program_files_location, "Debugging Tools for Windows (x64)", "dbghelp.dll") elif arch == ARCH_I386: - pathname = join( - program_files_location, - "Debugging Tools for Windows (x86)", - "dbghelp.dll") + pathname = join(program_files_location, "Debugging Tools for Windows (x86)", "dbghelp.dll") else: pathname = None @@ -81,71 +72,72 @@ def _load_latest_dbghelp_dll(): except Exception: pass + _load_latest_dbghelp_dll() # Recover the old binding of the "os" symbol. # XXX FIXME not sure if I really need to do this! ##from version import os -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== # SymGetHomeDirectory "type" values hdBase = 0 -hdSym = 1 -hdSrc = 2 - -UNDNAME_32_BIT_DECODE = 0x0800 -UNDNAME_COMPLETE = 0x0000 -UNDNAME_NAME_ONLY = 0x1000 -UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 -UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 -UNDNAME_NO_ALLOCATION_MODEL = 0x0008 -UNDNAME_NO_ARGUMENTS = 0x2000 -UNDNAME_NO_CV_THISTYPE = 0x0040 -UNDNAME_NO_FUNCTION_RETURNS = 0x0004 -UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 -UNDNAME_NO_MEMBER_TYPE = 0x0200 -UNDNAME_NO_MS_KEYWORDS = 0x0002 -UNDNAME_NO_MS_THISTYPE = 0x0020 -UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 -UNDNAME_NO_SPECIAL_SYMS = 0x4000 -UNDNAME_NO_THISTYPE = 0x0060 -UNDNAME_NO_THROW_SIGNATURES = 0x0100 - -#--- IMAGEHLP_MODULE structure and related ------------------------------------ - -SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x00000800 -SYMOPT_ALLOW_ZERO_ADDRESS = 0x01000000 -SYMOPT_AUTO_PUBLICS = 0x00010000 -SYMOPT_CASE_INSENSITIVE = 0x00000001 -SYMOPT_DEBUG = 0x80000000 -SYMOPT_DEFERRED_LOADS = 0x00000004 -SYMOPT_DISABLE_SYMSRV_AUTODETECT = 0x02000000 -SYMOPT_EXACT_SYMBOLS = 0x00000400 -SYMOPT_FAIL_CRITICAL_ERRORS = 0x00000200 -SYMOPT_FAVOR_COMPRESSED = 0x00800000 -SYMOPT_FLAT_DIRECTORY = 0x00400000 -SYMOPT_IGNORE_CVREC = 0x00000080 -SYMOPT_IGNORE_IMAGEDIR = 0x00200000 -SYMOPT_IGNORE_NT_SYMPATH = 0x00001000 -SYMOPT_INCLUDE_32BIT_MODULES = 0x00002000 -SYMOPT_LOAD_ANYTHING = 0x00000040 -SYMOPT_LOAD_LINES = 0x00000010 -SYMOPT_NO_CPP = 0x00000008 -SYMOPT_NO_IMAGE_SEARCH = 0x00020000 -SYMOPT_NO_PROMPTS = 0x00080000 -SYMOPT_NO_PUBLICS = 0x00008000 -SYMOPT_NO_UNQUALIFIED_LOADS = 0x00000100 -SYMOPT_OVERWRITE = 0x00100000 -SYMOPT_PUBLICS_ONLY = 0x00004000 -SYMOPT_SECURE = 0x00040000 -SYMOPT_UNDNAME = 0x00000002 +hdSym = 1 +hdSrc = 2 + +UNDNAME_32_BIT_DECODE = 0x0800 +UNDNAME_COMPLETE = 0x0000 +UNDNAME_NAME_ONLY = 0x1000 +UNDNAME_NO_ACCESS_SPECIFIERS = 0x0080 +UNDNAME_NO_ALLOCATION_LANGUAGE = 0x0010 +UNDNAME_NO_ALLOCATION_MODEL = 0x0008 +UNDNAME_NO_ARGUMENTS = 0x2000 +UNDNAME_NO_CV_THISTYPE = 0x0040 +UNDNAME_NO_FUNCTION_RETURNS = 0x0004 +UNDNAME_NO_LEADING_UNDERSCORES = 0x0001 +UNDNAME_NO_MEMBER_TYPE = 0x0200 +UNDNAME_NO_MS_KEYWORDS = 0x0002 +UNDNAME_NO_MS_THISTYPE = 0x0020 +UNDNAME_NO_RETURN_UDT_MODEL = 0x0400 +UNDNAME_NO_SPECIAL_SYMS = 0x4000 +UNDNAME_NO_THISTYPE = 0x0060 +UNDNAME_NO_THROW_SIGNATURES = 0x0100 + +# --- IMAGEHLP_MODULE structure and related ------------------------------------ + +SYMOPT_ALLOW_ABSOLUTE_SYMBOLS = 0x00000800 +SYMOPT_ALLOW_ZERO_ADDRESS = 0x01000000 +SYMOPT_AUTO_PUBLICS = 0x00010000 +SYMOPT_CASE_INSENSITIVE = 0x00000001 +SYMOPT_DEBUG = 0x80000000 +SYMOPT_DEFERRED_LOADS = 0x00000004 +SYMOPT_DISABLE_SYMSRV_AUTODETECT = 0x02000000 +SYMOPT_EXACT_SYMBOLS = 0x00000400 +SYMOPT_FAIL_CRITICAL_ERRORS = 0x00000200 +SYMOPT_FAVOR_COMPRESSED = 0x00800000 +SYMOPT_FLAT_DIRECTORY = 0x00400000 +SYMOPT_IGNORE_CVREC = 0x00000080 +SYMOPT_IGNORE_IMAGEDIR = 0x00200000 +SYMOPT_IGNORE_NT_SYMPATH = 0x00001000 +SYMOPT_INCLUDE_32BIT_MODULES = 0x00002000 +SYMOPT_LOAD_ANYTHING = 0x00000040 +SYMOPT_LOAD_LINES = 0x00000010 +SYMOPT_NO_CPP = 0x00000008 +SYMOPT_NO_IMAGE_SEARCH = 0x00020000 +SYMOPT_NO_PROMPTS = 0x00080000 +SYMOPT_NO_PUBLICS = 0x00008000 +SYMOPT_NO_UNQUALIFIED_LOADS = 0x00000100 +SYMOPT_OVERWRITE = 0x00100000 +SYMOPT_PUBLICS_ONLY = 0x00004000 +SYMOPT_SECURE = 0x00040000 +SYMOPT_UNDNAME = 0x00000002 ##SSRVOPT_DWORD ##SSRVOPT_DWORDPTR @@ -179,15 +171,15 @@ def _load_latest_dbghelp_dll(): # SymVirtual, # NumSymTypes # } SYM_TYPE; -SymNone = 0 -SymCoff = 1 -SymCv = 2 -SymPdb = 3 -SymExport = 4 +SymNone = 0 +SymCoff = 1 +SymCv = 2 +SymPdb = 3 +SymExport = 4 SymDeferred = 5 -SymSym = 6 -SymDia = 7 -SymVirtual = 8 +SymSym = 6 +SymDia = 7 +SymVirtual = 8 NumSymTypes = 9 # typedef struct _IMAGEHLP_MODULE64 { @@ -216,173 +208,195 @@ def _load_latest_dbghelp_dll(): # BOOL Publics; # } IMAGEHLP_MODULE64, *PIMAGEHLP_MODULE64; -class IMAGEHLP_MODULE (Structure): + +class IMAGEHLP_MODULE(Structure): _fields_ = [ - ("SizeOfStruct", DWORD), - ("BaseOfImage", DWORD), - ("ImageSize", DWORD), - ("TimeDateStamp", DWORD), - ("CheckSum", DWORD), - ("NumSyms", DWORD), - ("SymType", DWORD), # SYM_TYPE - ("ModuleName", CHAR * 32), - ("ImageName", CHAR * 256), + ("SizeOfStruct", DWORD), + ("BaseOfImage", DWORD), + ("ImageSize", DWORD), + ("TimeDateStamp", DWORD), + ("CheckSum", DWORD), + ("NumSyms", DWORD), + ("SymType", DWORD), # SYM_TYPE + ("ModuleName", CHAR * 32), + ("ImageName", CHAR * 256), ("LoadedImageName", CHAR * 256), ] + + PIMAGEHLP_MODULE = POINTER(IMAGEHLP_MODULE) -class IMAGEHLP_MODULE64 (Structure): + +class IMAGEHLP_MODULE64(Structure): _fields_ = [ - ("SizeOfStruct", DWORD), - ("BaseOfImage", DWORD64), - ("ImageSize", DWORD), - ("TimeDateStamp", DWORD), - ("CheckSum", DWORD), - ("NumSyms", DWORD), - ("SymType", DWORD), # SYM_TYPE - ("ModuleName", CHAR * 32), - ("ImageName", CHAR * 256), + ("SizeOfStruct", DWORD), + ("BaseOfImage", DWORD64), + ("ImageSize", DWORD), + ("TimeDateStamp", DWORD), + ("CheckSum", DWORD), + ("NumSyms", DWORD), + ("SymType", DWORD), # SYM_TYPE + ("ModuleName", CHAR * 32), + ("ImageName", CHAR * 256), ("LoadedImageName", CHAR * 256), - ("LoadedPdbName", CHAR * 256), - ("CVSig", DWORD), - ("CVData", CHAR * (MAX_PATH * 3)), - ("PdbSig", DWORD), - ("PdbSig70", GUID), - ("PdbAge", DWORD), - ("PdbUnmatched", BOOL), - ("DbgUnmatched", BOOL), - ("LineNumbers", BOOL), - ("GlobalSymbols", BOOL), - ("TypeInfo", BOOL), - ("SourceIndexed", BOOL), - ("Publics", BOOL), + ("LoadedPdbName", CHAR * 256), + ("CVSig", DWORD), + ("CVData", CHAR * (MAX_PATH * 3)), + ("PdbSig", DWORD), + ("PdbSig70", GUID), + ("PdbAge", DWORD), + ("PdbUnmatched", BOOL), + ("DbgUnmatched", BOOL), + ("LineNumbers", BOOL), + ("GlobalSymbols", BOOL), + ("TypeInfo", BOOL), + ("SourceIndexed", BOOL), + ("Publics", BOOL), ] + + PIMAGEHLP_MODULE64 = POINTER(IMAGEHLP_MODULE64) -class IMAGEHLP_MODULEW (Structure): + +class IMAGEHLP_MODULEW(Structure): _fields_ = [ - ("SizeOfStruct", DWORD), - ("BaseOfImage", DWORD), - ("ImageSize", DWORD), - ("TimeDateStamp", DWORD), - ("CheckSum", DWORD), - ("NumSyms", DWORD), - ("SymType", DWORD), # SYM_TYPE - ("ModuleName", WCHAR * 32), - ("ImageName", WCHAR * 256), + ("SizeOfStruct", DWORD), + ("BaseOfImage", DWORD), + ("ImageSize", DWORD), + ("TimeDateStamp", DWORD), + ("CheckSum", DWORD), + ("NumSyms", DWORD), + ("SymType", DWORD), # SYM_TYPE + ("ModuleName", WCHAR * 32), + ("ImageName", WCHAR * 256), ("LoadedImageName", WCHAR * 256), ] + + PIMAGEHLP_MODULEW = POINTER(IMAGEHLP_MODULEW) -class IMAGEHLP_MODULEW64 (Structure): + +class IMAGEHLP_MODULEW64(Structure): _fields_ = [ - ("SizeOfStruct", DWORD), - ("BaseOfImage", DWORD64), - ("ImageSize", DWORD), - ("TimeDateStamp", DWORD), - ("CheckSum", DWORD), - ("NumSyms", DWORD), - ("SymType", DWORD), # SYM_TYPE - ("ModuleName", WCHAR * 32), - ("ImageName", WCHAR * 256), + ("SizeOfStruct", DWORD), + ("BaseOfImage", DWORD64), + ("ImageSize", DWORD), + ("TimeDateStamp", DWORD), + ("CheckSum", DWORD), + ("NumSyms", DWORD), + ("SymType", DWORD), # SYM_TYPE + ("ModuleName", WCHAR * 32), + ("ImageName", WCHAR * 256), ("LoadedImageName", WCHAR * 256), - ("LoadedPdbName", WCHAR * 256), - ("CVSig", DWORD), - ("CVData", WCHAR * (MAX_PATH * 3)), - ("PdbSig", DWORD), - ("PdbSig70", GUID), - ("PdbAge", DWORD), - ("PdbUnmatched", BOOL), - ("DbgUnmatched", BOOL), - ("LineNumbers", BOOL), - ("GlobalSymbols", BOOL), - ("TypeInfo", BOOL), - ("SourceIndexed", BOOL), - ("Publics", BOOL), + ("LoadedPdbName", WCHAR * 256), + ("CVSig", DWORD), + ("CVData", WCHAR * (MAX_PATH * 3)), + ("PdbSig", DWORD), + ("PdbSig70", GUID), + ("PdbAge", DWORD), + ("PdbUnmatched", BOOL), + ("DbgUnmatched", BOOL), + ("LineNumbers", BOOL), + ("GlobalSymbols", BOOL), + ("TypeInfo", BOOL), + ("SourceIndexed", BOOL), + ("Publics", BOOL), ] + + PIMAGEHLP_MODULEW64 = POINTER(IMAGEHLP_MODULEW64) -#--- dbghelp.dll -------------------------------------------------------------- +# --- dbghelp.dll -------------------------------------------------------------- # XXX the ANSI versions of these functions don't end in "A" as expected! + # BOOL WINAPI MakeSureDirectoryPathExists( # _In_ PCSTR DirPath # ); def MakeSureDirectoryPathExistsA(DirPath): _MakeSureDirectoryPathExists = windll.dbghelp.MakeSureDirectoryPathExists _MakeSureDirectoryPathExists.argtypes = [LPSTR] - _MakeSureDirectoryPathExists.restype = bool + _MakeSureDirectoryPathExists.restype = bool _MakeSureDirectoryPathExists.errcheck = RaiseIfZero return _MakeSureDirectoryPathExists(DirPath) + MakeSureDirectoryPathExistsW = MakeWideVersion(MakeSureDirectoryPathExistsA) MakeSureDirectoryPathExists = GuessStringType(MakeSureDirectoryPathExistsA, MakeSureDirectoryPathExistsW) + # BOOL WINAPI SymInitialize( # __in HANDLE hProcess, # __in_opt PCTSTR UserSearchPath, # __in BOOL fInvadeProcess # ); -def SymInitializeA(hProcess, UserSearchPath = None, fInvadeProcess = False): +def SymInitializeA(hProcess, UserSearchPath=None, fInvadeProcess=False): _SymInitialize = windll.dbghelp.SymInitialize _SymInitialize.argtypes = [HANDLE, LPSTR, BOOL] - _SymInitialize.restype = bool + _SymInitialize.restype = bool _SymInitialize.errcheck = RaiseIfZero if not UserSearchPath: UserSearchPath = None _SymInitialize(hProcess, UserSearchPath, fInvadeProcess) + SymInitializeW = MakeWideVersion(SymInitializeA) SymInitialize = GuessStringType(SymInitializeA, SymInitializeW) + # BOOL WINAPI SymCleanup( # __in HANDLE hProcess # ); def SymCleanup(hProcess): _SymCleanup = windll.dbghelp.SymCleanup _SymCleanup.argtypes = [HANDLE] - _SymCleanup.restype = bool + _SymCleanup.restype = bool _SymCleanup.errcheck = RaiseIfZero _SymCleanup(hProcess) + # BOOL WINAPI SymRefreshModuleList( # __in HANDLE hProcess # ); def SymRefreshModuleList(hProcess): _SymRefreshModuleList = windll.dbghelp.SymRefreshModuleList _SymRefreshModuleList.argtypes = [HANDLE] - _SymRefreshModuleList.restype = bool + _SymRefreshModuleList.restype = bool _SymRefreshModuleList.errcheck = RaiseIfZero _SymRefreshModuleList(hProcess) + # BOOL WINAPI SymSetParentWindow( # __in HWND hwnd # ); def SymSetParentWindow(hwnd): _SymSetParentWindow = windll.dbghelp.SymSetParentWindow _SymSetParentWindow.argtypes = [HWND] - _SymSetParentWindow.restype = bool + _SymSetParentWindow.restype = bool _SymSetParentWindow.errcheck = RaiseIfZero _SymSetParentWindow(hwnd) + # DWORD WINAPI SymSetOptions( # __in DWORD SymOptions # ); def SymSetOptions(SymOptions): _SymSetOptions = windll.dbghelp.SymSetOptions _SymSetOptions.argtypes = [DWORD] - _SymSetOptions.restype = DWORD + _SymSetOptions.restype = DWORD _SymSetOptions.errcheck = RaiseIfZero _SymSetOptions(SymOptions) + # DWORD WINAPI SymGetOptions(void); def SymGetOptions(): _SymGetOptions = windll.dbghelp.SymGetOptions _SymGetOptions.argtypes = [] - _SymGetOptions.restype = DWORD + _SymGetOptions.restype = DWORD return _SymGetOptions() + # DWORD WINAPI SymLoadModule( # __in HANDLE hProcess, # __in_opt HANDLE hFile, @@ -391,10 +405,10 @@ def SymGetOptions(): # __in DWORD BaseOfDll, # __in DWORD SizeOfDll # ); -def SymLoadModuleA(hProcess, hFile = None, ImageName = None, ModuleName = None, BaseOfDll = None, SizeOfDll = None): +def SymLoadModuleA(hProcess, hFile=None, ImageName=None, ModuleName=None, BaseOfDll=None, SizeOfDll=None): _SymLoadModule = windll.dbghelp.SymLoadModule _SymLoadModule.argtypes = [HANDLE, HANDLE, LPSTR, LPSTR, DWORD, DWORD] - _SymLoadModule.restype = DWORD + _SymLoadModule.restype = DWORD if not ImageName: ImageName = None @@ -412,9 +426,11 @@ def SymLoadModuleA(hProcess, hFile = None, ImageName = None, ModuleName = None, raise ctypes.WinError(dwErrorCode) return lpBaseAddress + SymLoadModuleW = MakeWideVersion(SymLoadModuleA) SymLoadModule = GuessStringType(SymLoadModuleA, SymLoadModuleW) + # DWORD64 WINAPI SymLoadModule64( # __in HANDLE hProcess, # __in_opt HANDLE hFile, @@ -423,10 +439,10 @@ def SymLoadModuleA(hProcess, hFile = None, ImageName = None, ModuleName = None, # __in DWORD64 BaseOfDll, # __in DWORD SizeOfDll # ); -def SymLoadModule64A(hProcess, hFile = None, ImageName = None, ModuleName = None, BaseOfDll = None, SizeOfDll = None): +def SymLoadModule64A(hProcess, hFile=None, ImageName=None, ModuleName=None, BaseOfDll=None, SizeOfDll=None): _SymLoadModule64 = windll.dbghelp.SymLoadModule64 _SymLoadModule64.argtypes = [HANDLE, HANDLE, LPSTR, LPSTR, DWORD64, DWORD] - _SymLoadModule64.restype = DWORD64 + _SymLoadModule64.restype = DWORD64 if not ImageName: ImageName = None @@ -444,9 +460,11 @@ def SymLoadModule64A(hProcess, hFile = None, ImageName = None, ModuleName = None raise ctypes.WinError(dwErrorCode) return lpBaseAddress + SymLoadModule64W = MakeWideVersion(SymLoadModule64A) SymLoadModule64 = GuessStringType(SymLoadModule64A, SymLoadModule64W) + # BOOL WINAPI SymUnloadModule( # __in HANDLE hProcess, # __in DWORD BaseOfDll @@ -454,10 +472,11 @@ def SymLoadModule64A(hProcess, hFile = None, ImageName = None, ModuleName = None def SymUnloadModule(hProcess, BaseOfDll): _SymUnloadModule = windll.dbghelp.SymUnloadModule _SymUnloadModule.argtypes = [HANDLE, DWORD] - _SymUnloadModule.restype = bool + _SymUnloadModule.restype = bool _SymUnloadModule.errcheck = RaiseIfZero _SymUnloadModule(hProcess, BaseOfDll) + # BOOL WINAPI SymUnloadModule64( # __in HANDLE hProcess, # __in DWORD64 BaseOfDll @@ -465,10 +484,11 @@ def SymUnloadModule(hProcess, BaseOfDll): def SymUnloadModule64(hProcess, BaseOfDll): _SymUnloadModule64 = windll.dbghelp.SymUnloadModule64 _SymUnloadModule64.argtypes = [HANDLE, DWORD64] - _SymUnloadModule64.restype = bool + _SymUnloadModule64.restype = bool _SymUnloadModule64.errcheck = RaiseIfZero _SymUnloadModule64(hProcess, BaseOfDll) + # BOOL WINAPI SymGetModuleInfo( # __in HANDLE hProcess, # __in DWORD dwAddr, @@ -477,7 +497,7 @@ def SymUnloadModule64(hProcess, BaseOfDll): def SymGetModuleInfoA(hProcess, dwAddr): _SymGetModuleInfo = windll.dbghelp.SymGetModuleInfo _SymGetModuleInfo.argtypes = [HANDLE, DWORD, PIMAGEHLP_MODULE] - _SymGetModuleInfo.restype = bool + _SymGetModuleInfo.restype = bool _SymGetModuleInfo.errcheck = RaiseIfZero ModuleInfo = IMAGEHLP_MODULE() @@ -485,10 +505,11 @@ def SymGetModuleInfoA(hProcess, dwAddr): _SymGetModuleInfo(hProcess, dwAddr, byref(ModuleInfo)) return ModuleInfo + def SymGetModuleInfoW(hProcess, dwAddr): _SymGetModuleInfoW = windll.dbghelp.SymGetModuleInfoW _SymGetModuleInfoW.argtypes = [HANDLE, DWORD, PIMAGEHLP_MODULEW] - _SymGetModuleInfoW.restype = bool + _SymGetModuleInfoW.restype = bool _SymGetModuleInfoW.errcheck = RaiseIfZero ModuleInfo = IMAGEHLP_MODULEW() @@ -496,8 +517,10 @@ def SymGetModuleInfoW(hProcess, dwAddr): _SymGetModuleInfoW(hProcess, dwAddr, byref(ModuleInfo)) return ModuleInfo + SymGetModuleInfo = GuessStringType(SymGetModuleInfoA, SymGetModuleInfoW) + # BOOL WINAPI SymGetModuleInfo64( # __in HANDLE hProcess, # __in DWORD64 dwAddr, @@ -506,7 +529,7 @@ def SymGetModuleInfoW(hProcess, dwAddr): def SymGetModuleInfo64A(hProcess, dwAddr): _SymGetModuleInfo64 = windll.dbghelp.SymGetModuleInfo64 _SymGetModuleInfo64.argtypes = [HANDLE, DWORD64, PIMAGEHLP_MODULE64] - _SymGetModuleInfo64.restype = bool + _SymGetModuleInfo64.restype = bool _SymGetModuleInfo64.errcheck = RaiseIfZero ModuleInfo = IMAGEHLP_MODULE64() @@ -514,10 +537,11 @@ def SymGetModuleInfo64A(hProcess, dwAddr): _SymGetModuleInfo64(hProcess, dwAddr, byref(ModuleInfo)) return ModuleInfo + def SymGetModuleInfo64W(hProcess, dwAddr): _SymGetModuleInfo64W = windll.dbghelp.SymGetModuleInfo64W _SymGetModuleInfo64W.argtypes = [HANDLE, DWORD64, PIMAGEHLP_MODULE64W] - _SymGetModuleInfo64W.restype = bool + _SymGetModuleInfo64W.restype = bool _SymGetModuleInfo64W.errcheck = RaiseIfZero ModuleInfo = IMAGEHLP_MODULE64W() @@ -525,6 +549,7 @@ def SymGetModuleInfo64W(hProcess, dwAddr): _SymGetModuleInfo64W(hProcess, dwAddr, byref(ModuleInfo)) return ModuleInfo + SymGetModuleInfo64 = GuessStringType(SymGetModuleInfo64A, SymGetModuleInfo64W) # BOOL CALLBACK SymEnumerateModulesProc( @@ -532,26 +557,27 @@ def SymGetModuleInfo64W(hProcess, dwAddr): # __in DWORD BaseOfDll, # __in_opt PVOID UserContext # ); -PSYM_ENUMMODULES_CALLBACK = WINFUNCTYPE(BOOL, LPSTR, DWORD, PVOID) -PSYM_ENUMMODULES_CALLBACKW = WINFUNCTYPE(BOOL, LPWSTR, DWORD, PVOID) +PSYM_ENUMMODULES_CALLBACK = WINFUNCTYPE(BOOL, LPSTR, DWORD, PVOID) +PSYM_ENUMMODULES_CALLBACKW = WINFUNCTYPE(BOOL, LPWSTR, DWORD, PVOID) # BOOL CALLBACK SymEnumerateModulesProc64( # __in PCTSTR ModuleName, # __in DWORD64 BaseOfDll, # __in_opt PVOID UserContext # ); -PSYM_ENUMMODULES_CALLBACK64 = WINFUNCTYPE(BOOL, LPSTR, DWORD64, PVOID) +PSYM_ENUMMODULES_CALLBACK64 = WINFUNCTYPE(BOOL, LPSTR, DWORD64, PVOID) PSYM_ENUMMODULES_CALLBACKW64 = WINFUNCTYPE(BOOL, LPWSTR, DWORD64, PVOID) + # BOOL WINAPI SymEnumerateModules( # __in HANDLE hProcess, # __in PSYM_ENUMMODULES_CALLBACK EnumModulesCallback, # __in_opt PVOID UserContext # ); -def SymEnumerateModulesA(hProcess, EnumModulesCallback, UserContext = None): +def SymEnumerateModulesA(hProcess, EnumModulesCallback, UserContext=None): _SymEnumerateModules = windll.dbghelp.SymEnumerateModules _SymEnumerateModules.argtypes = [HANDLE, PSYM_ENUMMODULES_CALLBACK, PVOID] - _SymEnumerateModules.restype = bool + _SymEnumerateModules.restype = bool _SymEnumerateModules.errcheck = RaiseIfZero EnumModulesCallback = PSYM_ENUMMODULES_CALLBACK(EnumModulesCallback) @@ -561,10 +587,11 @@ def SymEnumerateModulesA(hProcess, EnumModulesCallback, UserContext = None): UserContext = LPVOID(NULL) _SymEnumerateModules(hProcess, EnumModulesCallback, UserContext) -def SymEnumerateModulesW(hProcess, EnumModulesCallback, UserContext = None): + +def SymEnumerateModulesW(hProcess, EnumModulesCallback, UserContext=None): _SymEnumerateModulesW = windll.dbghelp.SymEnumerateModulesW _SymEnumerateModulesW.argtypes = [HANDLE, PSYM_ENUMMODULES_CALLBACKW, PVOID] - _SymEnumerateModulesW.restype = bool + _SymEnumerateModulesW.restype = bool _SymEnumerateModulesW.errcheck = RaiseIfZero EnumModulesCallback = PSYM_ENUMMODULES_CALLBACKW(EnumModulesCallback) @@ -574,17 +601,19 @@ def SymEnumerateModulesW(hProcess, EnumModulesCallback, UserContext = None): UserContext = LPVOID(NULL) _SymEnumerateModulesW(hProcess, EnumModulesCallback, UserContext) + SymEnumerateModules = GuessStringType(SymEnumerateModulesA, SymEnumerateModulesW) + # BOOL WINAPI SymEnumerateModules64( # __in HANDLE hProcess, # __in PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, # __in_opt PVOID UserContext # ); -def SymEnumerateModules64A(hProcess, EnumModulesCallback, UserContext = None): +def SymEnumerateModules64A(hProcess, EnumModulesCallback, UserContext=None): _SymEnumerateModules64 = windll.dbghelp.SymEnumerateModules64 _SymEnumerateModules64.argtypes = [HANDLE, PSYM_ENUMMODULES_CALLBACK64, PVOID] - _SymEnumerateModules64.restype = bool + _SymEnumerateModules64.restype = bool _SymEnumerateModules64.errcheck = RaiseIfZero EnumModulesCallback = PSYM_ENUMMODULES_CALLBACK64(EnumModulesCallback) @@ -594,10 +623,11 @@ def SymEnumerateModules64A(hProcess, EnumModulesCallback, UserContext = None): UserContext = LPVOID(NULL) _SymEnumerateModules64(hProcess, EnumModulesCallback, UserContext) -def SymEnumerateModules64W(hProcess, EnumModulesCallback, UserContext = None): + +def SymEnumerateModules64W(hProcess, EnumModulesCallback, UserContext=None): _SymEnumerateModules64W = windll.dbghelp.SymEnumerateModules64W _SymEnumerateModules64W.argtypes = [HANDLE, PSYM_ENUMMODULES_CALLBACK64W, PVOID] - _SymEnumerateModules64W.restype = bool + _SymEnumerateModules64W.restype = bool _SymEnumerateModules64W.errcheck = RaiseIfZero EnumModulesCallback = PSYM_ENUMMODULES_CALLBACK64W(EnumModulesCallback) @@ -607,6 +637,7 @@ def SymEnumerateModules64W(hProcess, EnumModulesCallback, UserContext = None): UserContext = LPVOID(NULL) _SymEnumerateModules64W(hProcess, EnumModulesCallback, UserContext) + SymEnumerateModules64 = GuessStringType(SymEnumerateModules64A, SymEnumerateModules64W) # BOOL CALLBACK SymEnumerateSymbolsProc( @@ -615,8 +646,8 @@ def SymEnumerateModules64W(hProcess, EnumModulesCallback, UserContext = None): # __in ULONG SymbolSize, # __in_opt PVOID UserContext # ); -PSYM_ENUMSYMBOLS_CALLBACK = WINFUNCTYPE(BOOL, LPSTR, DWORD, ULONG, PVOID) -PSYM_ENUMSYMBOLS_CALLBACKW = WINFUNCTYPE(BOOL, LPWSTR, DWORD, ULONG, PVOID) +PSYM_ENUMSYMBOLS_CALLBACK = WINFUNCTYPE(BOOL, LPSTR, DWORD, ULONG, PVOID) +PSYM_ENUMSYMBOLS_CALLBACKW = WINFUNCTYPE(BOOL, LPWSTR, DWORD, ULONG, PVOID) # BOOL CALLBACK SymEnumerateSymbolsProc64( # __in PCTSTR SymbolName, @@ -624,19 +655,20 @@ def SymEnumerateModules64W(hProcess, EnumModulesCallback, UserContext = None): # __in ULONG SymbolSize, # __in_opt PVOID UserContext # ); -PSYM_ENUMSYMBOLS_CALLBACK64 = WINFUNCTYPE(BOOL, LPSTR, DWORD64, ULONG, PVOID) +PSYM_ENUMSYMBOLS_CALLBACK64 = WINFUNCTYPE(BOOL, LPSTR, DWORD64, ULONG, PVOID) PSYM_ENUMSYMBOLS_CALLBACKW64 = WINFUNCTYPE(BOOL, LPWSTR, DWORD64, ULONG, PVOID) + # BOOL WINAPI SymEnumerateSymbols( # __in HANDLE hProcess, # __in ULONG BaseOfDll, # __in PSYM_ENUMSYMBOLS_CALLBACK EnumSymbolsCallback, # __in_opt PVOID UserContext # ); -def SymEnumerateSymbolsA(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None): +def SymEnumerateSymbolsA(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext=None): _SymEnumerateSymbols = windll.dbghelp.SymEnumerateSymbols _SymEnumerateSymbols.argtypes = [HANDLE, ULONG, PSYM_ENUMSYMBOLS_CALLBACK, PVOID] - _SymEnumerateSymbols.restype = bool + _SymEnumerateSymbols.restype = bool _SymEnumerateSymbols.errcheck = RaiseIfZero EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACK(EnumSymbolsCallback) @@ -646,10 +678,11 @@ def SymEnumerateSymbolsA(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = UserContext = LPVOID(NULL) _SymEnumerateSymbols(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext) -def SymEnumerateSymbolsW(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None): + +def SymEnumerateSymbolsW(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext=None): _SymEnumerateSymbolsW = windll.dbghelp.SymEnumerateSymbolsW _SymEnumerateSymbolsW.argtypes = [HANDLE, ULONG, PSYM_ENUMSYMBOLS_CALLBACKW, PVOID] - _SymEnumerateSymbolsW.restype = bool + _SymEnumerateSymbolsW.restype = bool _SymEnumerateSymbolsW.errcheck = RaiseIfZero EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACKW(EnumSymbolsCallback) @@ -659,18 +692,20 @@ def SymEnumerateSymbolsW(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = UserContext = LPVOID(NULL) _SymEnumerateSymbolsW(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext) + SymEnumerateSymbols = GuessStringType(SymEnumerateSymbolsA, SymEnumerateSymbolsW) + # BOOL WINAPI SymEnumerateSymbols64( # __in HANDLE hProcess, # __in ULONG64 BaseOfDll, # __in PSYM_ENUMSYMBOLS_CALLBACK64 EnumSymbolsCallback, # __in_opt PVOID UserContext # ); -def SymEnumerateSymbols64A(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None): +def SymEnumerateSymbols64A(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext=None): _SymEnumerateSymbols64 = windll.dbghelp.SymEnumerateSymbols64 _SymEnumerateSymbols64.argtypes = [HANDLE, ULONG64, PSYM_ENUMSYMBOLS_CALLBACK64, PVOID] - _SymEnumerateSymbols64.restype = bool + _SymEnumerateSymbols64.restype = bool _SymEnumerateSymbols64.errcheck = RaiseIfZero EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACK64(EnumSymbolsCallback) @@ -680,10 +715,11 @@ def SymEnumerateSymbols64A(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext UserContext = LPVOID(NULL) _SymEnumerateSymbols64(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext) -def SymEnumerateSymbols64W(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext = None): + +def SymEnumerateSymbols64W(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext=None): _SymEnumerateSymbols64W = windll.dbghelp.SymEnumerateSymbols64W _SymEnumerateSymbols64W.argtypes = [HANDLE, ULONG64, PSYM_ENUMSYMBOLS_CALLBACK64W, PVOID] - _SymEnumerateSymbols64W.restype = bool + _SymEnumerateSymbols64W.restype = bool _SymEnumerateSymbols64W.errcheck = RaiseIfZero EnumSymbolsCallback = PSYM_ENUMSYMBOLS_CALLBACK64W(EnumSymbolsCallback) @@ -693,38 +729,43 @@ def SymEnumerateSymbols64W(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext UserContext = LPVOID(NULL) _SymEnumerateSymbols64W(hProcess, BaseOfDll, EnumSymbolsCallback, UserContext) + SymEnumerateSymbols64 = GuessStringType(SymEnumerateSymbols64A, SymEnumerateSymbols64W) + # DWORD WINAPI UnDecorateSymbolName( # __in PCTSTR DecoratedName, # __out PTSTR UnDecoratedName, # __in DWORD UndecoratedLength, # __in DWORD Flags # ); -def UnDecorateSymbolNameA(DecoratedName, Flags = UNDNAME_COMPLETE): +def UnDecorateSymbolNameA(DecoratedName, Flags=UNDNAME_COMPLETE): _UnDecorateSymbolNameA = windll.dbghelp.UnDecorateSymbolName _UnDecorateSymbolNameA.argtypes = [LPSTR, LPSTR, DWORD, DWORD] - _UnDecorateSymbolNameA.restype = DWORD + _UnDecorateSymbolNameA.restype = DWORD _UnDecorateSymbolNameA.errcheck = RaiseIfZero UndecoratedLength = _UnDecorateSymbolNameA(DecoratedName, None, 0, Flags) - UnDecoratedName = ctypes.create_string_buffer('', UndecoratedLength + 1) + UnDecoratedName = ctypes.create_string_buffer("", UndecoratedLength + 1) _UnDecorateSymbolNameA(DecoratedName, UnDecoratedName, UndecoratedLength, Flags) return UnDecoratedName.value -def UnDecorateSymbolNameW(DecoratedName, Flags = UNDNAME_COMPLETE): + +def UnDecorateSymbolNameW(DecoratedName, Flags=UNDNAME_COMPLETE): _UnDecorateSymbolNameW = windll.dbghelp.UnDecorateSymbolNameW _UnDecorateSymbolNameW.argtypes = [LPWSTR, LPWSTR, DWORD, DWORD] - _UnDecorateSymbolNameW.restype = DWORD + _UnDecorateSymbolNameW.restype = DWORD _UnDecorateSymbolNameW.errcheck = RaiseIfZero UndecoratedLength = _UnDecorateSymbolNameW(DecoratedName, None, 0, Flags) - UnDecoratedName = ctypes.create_unicode_buffer(u'', UndecoratedLength + 1) + UnDecoratedName = ctypes.create_unicode_buffer("", UndecoratedLength + 1) _UnDecorateSymbolNameW(DecoratedName, UnDecoratedName, UndecoratedLength, Flags) return UnDecoratedName.value + UnDecorateSymbolName = GuessStringType(UnDecorateSymbolNameA, UnDecorateSymbolNameW) + # BOOL WINAPI SymGetSearchPath( # __in HANDLE hProcess, # __out PTSTR SearchPath, @@ -733,7 +774,7 @@ def UnDecorateSymbolNameW(DecoratedName, Flags = UNDNAME_COMPLETE): def SymGetSearchPathA(hProcess): _SymGetSearchPath = windll.dbghelp.SymGetSearchPath _SymGetSearchPath.argtypes = [HANDLE, LPSTR, DWORD] - _SymGetSearchPath.restype = bool + _SymGetSearchPath.restype = bool _SymGetSearchPath.errcheck = RaiseIfZero SearchPathLength = MAX_PATH @@ -741,43 +782,49 @@ def SymGetSearchPathA(hProcess): _SymGetSearchPath(hProcess, SearchPath, SearchPathLength) return SearchPath.value + def SymGetSearchPathW(hProcess): _SymGetSearchPathW = windll.dbghelp.SymGetSearchPathW _SymGetSearchPathW.argtypes = [HANDLE, LPWSTR, DWORD] - _SymGetSearchPathW.restype = bool + _SymGetSearchPathW.restype = bool _SymGetSearchPathW.errcheck = RaiseIfZero SearchPathLength = MAX_PATH - SearchPath = ctypes.create_unicode_buffer(u"", SearchPathLength) + SearchPath = ctypes.create_unicode_buffer("", SearchPathLength) _SymGetSearchPathW(hProcess, SearchPath, SearchPathLength) return SearchPath.value + SymGetSearchPath = GuessStringType(SymGetSearchPathA, SymGetSearchPathW) + # BOOL WINAPI SymSetSearchPath( # __in HANDLE hProcess, # __in_opt PCTSTR SearchPath # ); -def SymSetSearchPathA(hProcess, SearchPath = None): +def SymSetSearchPathA(hProcess, SearchPath=None): _SymSetSearchPath = windll.dbghelp.SymSetSearchPath _SymSetSearchPath.argtypes = [HANDLE, LPSTR] - _SymSetSearchPath.restype = bool + _SymSetSearchPath.restype = bool _SymSetSearchPath.errcheck = RaiseIfZero if not SearchPath: SearchPath = None _SymSetSearchPath(hProcess, SearchPath) -def SymSetSearchPathW(hProcess, SearchPath = None): + +def SymSetSearchPathW(hProcess, SearchPath=None): _SymSetSearchPathW = windll.dbghelp.SymSetSearchPathW _SymSetSearchPathW.argtypes = [HANDLE, LPWSTR] - _SymSetSearchPathW.restype = bool + _SymSetSearchPathW.restype = bool _SymSetSearchPathW.errcheck = RaiseIfZero if not SearchPath: SearchPath = None _SymSetSearchPathW(hProcess, SearchPath) + SymSetSearchPath = GuessStringType(SymSetSearchPathA, SymSetSearchPathW) + # PTCHAR WINAPI SymGetHomeDirectory( # __in DWORD type, # __out PTSTR dir, @@ -786,54 +833,59 @@ def SymSetSearchPathW(hProcess, SearchPath = None): def SymGetHomeDirectoryA(type): _SymGetHomeDirectoryA = windll.dbghelp.SymGetHomeDirectoryA _SymGetHomeDirectoryA.argtypes = [DWORD, LPSTR, SIZE_T] - _SymGetHomeDirectoryA.restype = LPSTR + _SymGetHomeDirectoryA.restype = LPSTR _SymGetHomeDirectoryA.errcheck = RaiseIfZero size = MAX_PATH - dir = ctypes.create_string_buffer("", size) + dir = ctypes.create_string_buffer("", size) _SymGetHomeDirectoryA(type, dir, size) return dir.value + def SymGetHomeDirectoryW(type): _SymGetHomeDirectoryW = windll.dbghelp.SymGetHomeDirectoryW _SymGetHomeDirectoryW.argtypes = [DWORD, LPWSTR, SIZE_T] - _SymGetHomeDirectoryW.restype = LPWSTR + _SymGetHomeDirectoryW.restype = LPWSTR _SymGetHomeDirectoryW.errcheck = RaiseIfZero size = MAX_PATH - dir = ctypes.create_unicode_buffer(u"", size) + dir = ctypes.create_unicode_buffer("", size) _SymGetHomeDirectoryW(type, dir, size) return dir.value + SymGetHomeDirectory = GuessStringType(SymGetHomeDirectoryA, SymGetHomeDirectoryW) + # PTCHAR WINAPI SymSetHomeDirectory( # __in HANDLE hProcess, # __in_opt PCTSTR dir # ); -def SymSetHomeDirectoryA(hProcess, dir = None): +def SymSetHomeDirectoryA(hProcess, dir=None): _SymSetHomeDirectoryA = windll.dbghelp.SymSetHomeDirectoryA _SymSetHomeDirectoryA.argtypes = [HANDLE, LPSTR] - _SymSetHomeDirectoryA.restype = LPSTR + _SymSetHomeDirectoryA.restype = LPSTR _SymSetHomeDirectoryA.errcheck = RaiseIfZero if not dir: dir = None _SymSetHomeDirectoryA(hProcess, dir) return dir -def SymSetHomeDirectoryW(hProcess, dir = None): + +def SymSetHomeDirectoryW(hProcess, dir=None): _SymSetHomeDirectoryW = windll.dbghelp.SymSetHomeDirectoryW _SymSetHomeDirectoryW.argtypes = [HANDLE, LPWSTR] - _SymSetHomeDirectoryW.restype = LPWSTR + _SymSetHomeDirectoryW.restype = LPWSTR _SymSetHomeDirectoryW.errcheck = RaiseIfZero if not dir: dir = None _SymSetHomeDirectoryW(hProcess, dir) return dir + SymSetHomeDirectory = GuessStringType(SymSetHomeDirectoryA, SymSetHomeDirectoryW) -#--- DbgHelp 5+ support, patch by Neitsa -------------------------------------- +# --- DbgHelp 5+ support, patch by Neitsa -------------------------------------- # XXX TODO # + use the GuessStringType decorator for ANSI/Wide versions @@ -843,56 +895,63 @@ def SymSetHomeDirectoryW(hProcess, dir = None): # ourselves with a default error code?) # /Mario -#maximum length of a symbol name +# maximum length of a symbol name MAX_SYM_NAME = 2000 + class SYM_INFO(Structure): _fields_ = [ - ("SizeOfStruct", ULONG), - ("TypeIndex", ULONG), - ("Reserved", ULONG64 * 2), - ("Index", ULONG), - ("Size", ULONG), - ("ModBase", ULONG64), - ("Flags", ULONG), - ("Value", ULONG64), - ("Address", ULONG64), - ("Register", ULONG), - ("Scope", ULONG), - ("Tag", ULONG), - ("NameLen", ULONG), - ("MaxNameLen", ULONG), - ("Name", CHAR * (MAX_SYM_NAME + 1)), + ("SizeOfStruct", ULONG), + ("TypeIndex", ULONG), + ("Reserved", ULONG64 * 2), + ("Index", ULONG), + ("Size", ULONG), + ("ModBase", ULONG64), + ("Flags", ULONG), + ("Value", ULONG64), + ("Address", ULONG64), + ("Register", ULONG), + ("Scope", ULONG), + ("Tag", ULONG), + ("NameLen", ULONG), + ("MaxNameLen", ULONG), + ("Name", CHAR * (MAX_SYM_NAME + 1)), ] + + PSYM_INFO = POINTER(SYM_INFO) + class SYM_INFOW(Structure): _fields_ = [ - ("SizeOfStruct", ULONG), - ("TypeIndex", ULONG), - ("Reserved", ULONG64 * 2), - ("Index", ULONG), - ("Size", ULONG), - ("ModBase", ULONG64), - ("Flags", ULONG), - ("Value", ULONG64), - ("Address", ULONG64), - ("Register", ULONG), - ("Scope", ULONG), - ("Tag", ULONG), - ("NameLen", ULONG), - ("MaxNameLen", ULONG), - ("Name", WCHAR * (MAX_SYM_NAME + 1)), + ("SizeOfStruct", ULONG), + ("TypeIndex", ULONG), + ("Reserved", ULONG64 * 2), + ("Index", ULONG), + ("Size", ULONG), + ("ModBase", ULONG64), + ("Flags", ULONG), + ("Value", ULONG64), + ("Address", ULONG64), + ("Register", ULONG), + ("Scope", ULONG), + ("Tag", ULONG), + ("NameLen", ULONG), + ("MaxNameLen", ULONG), + ("Name", WCHAR * (MAX_SYM_NAME + 1)), ] + + PSYM_INFOW = POINTER(SYM_INFOW) -#=============================================================================== + +# =============================================================================== # BOOL WINAPI SymFromName( # __in HANDLE hProcess, # __in PCTSTR Name, # __inout PSYMBOL_INFO Symbol # ); -#=============================================================================== +# =============================================================================== def SymFromName(hProcess, Name): _SymFromNameA = windll.dbghelp.SymFromName _SymFromNameA.argtypes = [HANDLE, LPSTR, PSYM_INFO] @@ -900,13 +959,14 @@ def SymFromName(hProcess, Name): _SymFromNameA.errcheck = RaiseIfZero SymInfo = SYM_INFO() - SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFO) in C. + SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFO) in C. SymInfo.MaxNameLen = MAX_SYM_NAME _SymFromNameA(hProcess, Name, byref(SymInfo)) return SymInfo + def SymFromNameW(hProcess, Name): _SymFromNameW = windll.dbghelp.SymFromNameW _SymFromNameW.argtypes = [HANDLE, LPWSTR, PSYM_INFOW] @@ -914,21 +974,22 @@ def SymFromNameW(hProcess, Name): _SymFromNameW.errcheck = RaiseIfZero SymInfo = SYM_INFOW() - SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFOW) in C. + SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFOW) in C. SymInfo.MaxNameLen = MAX_SYM_NAME _SymFromNameW(hProcess, Name, byref(SymInfo)) return SymInfo -#=============================================================================== + +# =============================================================================== # BOOL WINAPI SymFromAddr( # __in HANDLE hProcess, # __in DWORD64 Address, # __out_opt PDWORD64 Displacement, # __inout PSYMBOL_INFO Symbol # ); -#=============================================================================== +# =============================================================================== def SymFromAddr(hProcess, Address): _SymFromAddr = windll.dbghelp.SymFromAddr _SymFromAddr.argtypes = [HANDLE, DWORD64, PDWORD64, PSYM_INFO] @@ -936,7 +997,7 @@ def SymFromAddr(hProcess, Address): _SymFromAddr.errcheck = RaiseIfZero SymInfo = SYM_INFO() - SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFO) in C. + SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFO) in C. SymInfo.MaxNameLen = MAX_SYM_NAME Displacement = DWORD64(0) @@ -944,6 +1005,7 @@ def SymFromAddr(hProcess, Address): return (Displacement.value, SymInfo) + def SymFromAddrW(hProcess, Address): _SymFromAddr = windll.dbghelp.SymFromAddrW _SymFromAddr.argtypes = [HANDLE, DWORD64, PDWORD64, PSYM_INFOW] @@ -951,7 +1013,7 @@ def SymFromAddrW(hProcess, Address): _SymFromAddr.errcheck = RaiseIfZero SymInfo = SYM_INFOW() - SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFOW) in C. + SymInfo.SizeOfStruct = 88 # *don't modify*: sizeof(SYMBOL_INFOW) in C. SymInfo.MaxNameLen = MAX_SYM_NAME Displacement = DWORD64(0) @@ -959,7 +1021,8 @@ def SymFromAddrW(hProcess, Address): return (Displacement.value, SymInfo) -#=============================================================================== + +# =============================================================================== # typedef struct _IMAGEHLP_SYMBOL64 { # DWORD SizeOfStruct; # DWORD64 Address; @@ -968,19 +1031,22 @@ def SymFromAddrW(hProcess, Address): # DWORD MaxNameLength; # CHAR Name[1]; # } IMAGEHLP_SYMBOL64, *PIMAGEHLP_SYMBOL64; -#=============================================================================== -class IMAGEHLP_SYMBOL64 (Structure): +# =============================================================================== +class IMAGEHLP_SYMBOL64(Structure): _fields_ = [ - ("SizeOfStruct", DWORD), - ("Address", DWORD64), - ("Size", DWORD), - ("Flags", DWORD), - ("MaxNameLength", DWORD), - ("Name", CHAR * (MAX_SYM_NAME + 1)), + ("SizeOfStruct", DWORD), + ("Address", DWORD64), + ("Size", DWORD), + ("Flags", DWORD), + ("MaxNameLength", DWORD), + ("Name", CHAR * (MAX_SYM_NAME + 1)), ] + + PIMAGEHLP_SYMBOL64 = POINTER(IMAGEHLP_SYMBOL64) -#=============================================================================== + +# =============================================================================== # typedef struct _IMAGEHLP_SYMBOLW64 { # DWORD SizeOfStruct; # DWORD64 Address; @@ -989,26 +1055,29 @@ class IMAGEHLP_SYMBOL64 (Structure): # DWORD MaxNameLength; # WCHAR Name[1]; # } IMAGEHLP_SYMBOLW64, *PIMAGEHLP_SYMBOLW64; -#=============================================================================== -class IMAGEHLP_SYMBOLW64 (Structure): +# =============================================================================== +class IMAGEHLP_SYMBOLW64(Structure): _fields_ = [ - ("SizeOfStruct", DWORD), - ("Address", DWORD64), - ("Size", DWORD), - ("Flags", DWORD), - ("MaxNameLength", DWORD), - ("Name", WCHAR * (MAX_SYM_NAME + 1)), + ("SizeOfStruct", DWORD), + ("Address", DWORD64), + ("Size", DWORD), + ("Flags", DWORD), + ("MaxNameLength", DWORD), + ("Name", WCHAR * (MAX_SYM_NAME + 1)), ] + + PIMAGEHLP_SYMBOLW64 = POINTER(IMAGEHLP_SYMBOLW64) -#=============================================================================== + +# =============================================================================== # BOOL WINAPI SymGetSymFromAddr64( # __in HANDLE hProcess, # __in DWORD64 Address, # __out_opt PDWORD64 Displacement, # __inout PIMAGEHLP_SYMBOL64 Symbol # ); -#=============================================================================== +# =============================================================================== def SymGetSymFromAddr64(hProcess, Address): _SymGetSymFromAddr64 = windll.dbghelp.SymGetSymFromAddr64 _SymGetSymFromAddr64.argtypes = [HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64] @@ -1016,7 +1085,7 @@ def SymGetSymFromAddr64(hProcess, Address): _SymGetSymFromAddr64.errcheck = RaiseIfZero imagehlp_symbol64 = IMAGEHLP_SYMBOL64() - imagehlp_symbol64.SizeOfStruct = 32 # *don't modify*: sizeof(IMAGEHLP_SYMBOL64) in C. + imagehlp_symbol64.SizeOfStruct = 32 # *don't modify*: sizeof(IMAGEHLP_SYMBOL64) in C. imagehlp_symbol64.MaxNameLen = MAX_SYM_NAME Displacement = DWORD64(0) @@ -1024,30 +1093,34 @@ def SymGetSymFromAddr64(hProcess, Address): return (Displacement.value, imagehlp_symbol64) -#TODO: check for the 'W' version of SymGetSymFromAddr64() +# TODO: check for the 'W' version of SymGetSymFromAddr64() -#=============================================================================== + +# =============================================================================== # typedef struct API_VERSION { # USHORT MajorVersion; # USHORT MinorVersion; # USHORT Revision; # USHORT Reserved; # } API_VERSION, *LPAPI_VERSION; -#=============================================================================== -class API_VERSION (Structure): +# =============================================================================== +class API_VERSION(Structure): _fields_ = [ - ("MajorVersion", USHORT), - ("MinorVersion", USHORT), - ("Revision", USHORT), - ("Reserved", USHORT), + ("MajorVersion", USHORT), + ("MinorVersion", USHORT), + ("Revision", USHORT), + ("Reserved", USHORT), ] + + PAPI_VERSION = POINTER(API_VERSION) LPAPI_VERSION = PAPI_VERSION -#=============================================================================== + +# =============================================================================== # LPAPI_VERSION WINAPI ImagehlpApiVersion(void); -#=============================================================================== +# =============================================================================== def ImagehlpApiVersion(): _ImagehlpApiVersion = windll.dbghelp.ImagehlpApiVersion _ImagehlpApiVersion.restype = LPAPI_VERSION @@ -1056,11 +1129,11 @@ def ImagehlpApiVersion(): return api_version.contents -#=============================================================================== +# =============================================================================== # LPAPI_VERSION WINAPI ImagehlpApiVersionEx( # __in LPAPI_VERSION AppVersion # ); -#=============================================================================== +# =============================================================================== def ImagehlpApiVersionEx(MajorVersion, MinorVersion, Revision): _ImagehlpApiVersionEx = windll.dbghelp.ImagehlpApiVersionEx _ImagehlpApiVersionEx.argtypes = [LPAPI_VERSION] @@ -1072,37 +1145,42 @@ def ImagehlpApiVersionEx(MajorVersion, MinorVersion, Revision): return ret_api_version.contents -#=============================================================================== + +# =============================================================================== # typedef enum { # AddrMode1616, # AddrMode1632, # AddrModeReal, # AddrModeFlat # } ADDRESS_MODE; -#=============================================================================== +# =============================================================================== AddrMode1616 = 0 AddrMode1632 = 1 AddrModeReal = 2 AddrModeFlat = 3 -ADDRESS_MODE = DWORD #needed for the size of an ADDRESS_MODE (see ADDRESS64) +ADDRESS_MODE = DWORD # needed for the size of an ADDRESS_MODE (see ADDRESS64) + -#=============================================================================== +# =============================================================================== # typedef struct _tagADDRESS64 { # DWORD64 Offset; # WORD Segment; # ADDRESS_MODE Mode; # } ADDRESS64, *LPADDRESS64; -#=============================================================================== -class ADDRESS64 (Structure): +# =============================================================================== +class ADDRESS64(Structure): _fields_ = [ - ("Offset", DWORD64), - ("Segment", WORD), - ("Mode", ADDRESS_MODE), #it's a member of the ADDRESS_MODE enum. + ("Offset", DWORD64), + ("Segment", WORD), + ("Mode", ADDRESS_MODE), # it's a member of the ADDRESS_MODE enum. ] + + LPADDRESS64 = POINTER(ADDRESS64) -#=============================================================================== + +# =============================================================================== # typedef struct _KDHELP64 { # DWORD64 Thread; # DWORD ThCallbackStack; @@ -1117,25 +1195,28 @@ class ADDRESS64 (Structure): # DWORD64 StackLimit; # DWORD64 Reserved[5]; # } KDHELP64, *PKDHELP64; -#=============================================================================== -class KDHELP64 (Structure): +# =============================================================================== +class KDHELP64(Structure): _fields_ = [ - ("Thread", DWORD64), - ("ThCallbackStack", DWORD), - ("ThCallbackBStore", DWORD), - ("NextCallback", DWORD), - ("FramePointer", DWORD), - ("KiCallUserMode", DWORD64), - ("KeUserCallbackDispatcher", DWORD64), - ("SystemRangeStart", DWORD64), - ("KiUserExceptionDispatcher", DWORD64), - ("StackBase", DWORD64), - ("StackLimit", DWORD64), - ("Reserved", DWORD64 * 5), + ("Thread", DWORD64), + ("ThCallbackStack", DWORD), + ("ThCallbackBStore", DWORD), + ("NextCallback", DWORD), + ("FramePointer", DWORD), + ("KiCallUserMode", DWORD64), + ("KeUserCallbackDispatcher", DWORD64), + ("SystemRangeStart", DWORD64), + ("KiUserExceptionDispatcher", DWORD64), + ("StackBase", DWORD64), + ("StackLimit", DWORD64), + ("Reserved", DWORD64 * 5), ] + + PKDHELP64 = POINTER(KDHELP64) -#=============================================================================== + +# =============================================================================== # typedef struct _tagSTACKFRAME64 { # ADDRESS64 AddrPC; # ADDRESS64 AddrReturn; @@ -1149,24 +1230,26 @@ class KDHELP64 (Structure): # DWORD64 Reserved[3]; # KDHELP64 KdHelp; # } STACKFRAME64, *LPSTACKFRAME64; -#=============================================================================== +# =============================================================================== class STACKFRAME64(Structure): _fields_ = [ - ("AddrPC", ADDRESS64), - ("AddrReturn", ADDRESS64), - ("AddrFrame", ADDRESS64), - ("AddrStack", ADDRESS64), - ("AddrBStore", ADDRESS64), - ("FuncTableEntry", PVOID), - ("Params", DWORD64 * 4), - ("Far", BOOL), - ("Virtual", BOOL), - ("Reserved", DWORD64 * 3), - ("KdHelp", KDHELP64), + ("AddrPC", ADDRESS64), + ("AddrReturn", ADDRESS64), + ("AddrFrame", ADDRESS64), + ("AddrStack", ADDRESS64), + ("AddrBStore", ADDRESS64), + ("FuncTableEntry", PVOID), + ("Params", DWORD64 * 4), + ("Far", BOOL), + ("Virtual", BOOL), + ("Reserved", DWORD64 * 3), + ("KdHelp", KDHELP64), ] + + LPSTACKFRAME64 = POINTER(STACKFRAME64) -#=============================================================================== +# =============================================================================== # BOOL CALLBACK ReadProcessMemoryProc64( # __in HANDLE hProcess, # __in DWORD64 lpBaseAddress, @@ -1174,39 +1257,40 @@ class STACKFRAME64(Structure): # __in DWORD nSize, # __out LPDWORD lpNumberOfBytesRead # ); -#=============================================================================== +# =============================================================================== PREAD_PROCESS_MEMORY_ROUTINE64 = WINFUNCTYPE(BOOL, HANDLE, DWORD64, PVOID, DWORD, LPDWORD) -#=============================================================================== +# =============================================================================== # PVOID CALLBACK FunctionTableAccessProc64( # __in HANDLE hProcess, # __in DWORD64 AddrBase # ); -#=============================================================================== +# =============================================================================== PFUNCTION_TABLE_ACCESS_ROUTINE64 = WINFUNCTYPE(PVOID, HANDLE, DWORD64) -#=============================================================================== +# =============================================================================== # DWORD64 CALLBACK GetModuleBaseProc64( # __in HANDLE hProcess, # __in DWORD64 Address # ); -#=============================================================================== +# =============================================================================== PGET_MODULE_BASE_ROUTINE64 = WINFUNCTYPE(DWORD64, HANDLE, DWORD64) -#=============================================================================== +# =============================================================================== # DWORD64 CALLBACK GetModuleBaseProc64( # __in HANDLE hProcess, # __in DWORD64 Address # ); -#=============================================================================== +# =============================================================================== PTRANSLATE_ADDRESS_ROUTINE64 = WINFUNCTYPE(DWORD64, HANDLE, DWORD64) # Valid machine types for StackWalk64 function -IMAGE_FILE_MACHINE_I386 = 0x014c #Intel x86 -IMAGE_FILE_MACHINE_IA64 = 0x0200 #Intel Itanium Processor Family (IPF) -IMAGE_FILE_MACHINE_AMD64 = 0x8664 #x64 (AMD64 or EM64T) +IMAGE_FILE_MACHINE_I386 = 0x014C # Intel x86 +IMAGE_FILE_MACHINE_IA64 = 0x0200 # Intel Itanium Processor Family (IPF) +IMAGE_FILE_MACHINE_AMD64 = 0x8664 # x64 (AMD64 or EM64T) + -#=============================================================================== +# =============================================================================== # BOOL WINAPI StackWalk64( # __in DWORD MachineType, # __in HANDLE hProcess, @@ -1218,18 +1302,30 @@ class STACKFRAME64(Structure): # __in_opt PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine, # __in_opt PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress # ); -#=============================================================================== -def StackWalk64(MachineType, hProcess, hThread, StackFrame, - ContextRecord = None, ReadMemoryRoutine = None, - FunctionTableAccessRoutine = None, GetModuleBaseRoutine = None, - TranslateAddress = None): - +# =============================================================================== +def StackWalk64( + MachineType, + hProcess, + hThread, + StackFrame, + ContextRecord=None, + ReadMemoryRoutine=None, + FunctionTableAccessRoutine=None, + GetModuleBaseRoutine=None, + TranslateAddress=None, +): _StackWalk64 = windll.dbghelp.StackWalk64 - _StackWalk64.argtypes = [DWORD, HANDLE, HANDLE, LPSTACKFRAME64, PVOID, - PREAD_PROCESS_MEMORY_ROUTINE64, - PFUNCTION_TABLE_ACCESS_ROUTINE64, - PGET_MODULE_BASE_ROUTINE64, - PTRANSLATE_ADDRESS_ROUTINE64] + _StackWalk64.argtypes = [ + DWORD, + HANDLE, + HANDLE, + LPSTACKFRAME64, + PVOID, + PREAD_PROCESS_MEMORY_ROUTINE64, + PFUNCTION_TABLE_ACCESS_ROUTINE64, + PGET_MODULE_BASE_ROUTINE64, + PTRANSLATE_ADDRESS_ROUTINE64, + ] _StackWalk64.restype = bool pReadMemoryRoutine = None @@ -1252,7 +1348,7 @@ def StackWalk64(MachineType, hProcess, hThread, StackFrame, pTranslateAddress = None if TranslateAddress: - pTranslateAddress = PTRANSLATE_ADDRESS_ROUTINE64(TranslateAddress) + pTranslateAddress = PTRANSLATE_ADDRESS_ROUTINE64(TranslateAddress) else: pTranslateAddress = ctypes.cast(None, PTRANSLATE_ADDRESS_ROUTINE64) @@ -1261,17 +1357,25 @@ def StackWalk64(MachineType, hProcess, hThread, StackFrame, ContextRecord = GetThreadContext(hThread, raw=True) pContextRecord = PCONTEXT(ContextRecord) - #this function *DOESN'T* set last error [GetLastError()] properly most of the time. - ret = _StackWalk64(MachineType, hProcess, hThread, byref(StackFrame), - pContextRecord, pReadMemoryRoutine, - pFunctionTableAccessRoutine, pGetModuleBaseRoutine, - pTranslateAddress) + # this function *DOESN'T* set last error [GetLastError()] properly most of the time. + ret = _StackWalk64( + MachineType, + hProcess, + hThread, + byref(StackFrame), + pContextRecord, + pReadMemoryRoutine, + pFunctionTableAccessRoutine, + pGetModuleBaseRoutine, + pTranslateAddress, + ) return ret -#============================================================================== + +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/defines.py b/pydevd_attach_to_process/winappdbg/win32/defines.py index 187e4294c..d38d6095a 100644 --- a/pydevd_attach_to_process/winappdbg/win32/defines.py +++ b/pydevd_attach_to_process/winappdbg/win32/defines.py @@ -41,17 +41,17 @@ import functools from winappdbg import compat -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Some stuff from ctypes we'll be using very frequently. -addressof = ctypes.addressof -sizeof = ctypes.sizeof -SIZEOF = ctypes.sizeof -POINTER = ctypes.POINTER -Structure = ctypes.Structure -Union = ctypes.Union +addressof = ctypes.addressof +sizeof = ctypes.sizeof +SIZEOF = ctypes.sizeof +POINTER = ctypes.POINTER +Structure = ctypes.Structure +Union = ctypes.Union WINFUNCTYPE = ctypes.WINFUNCTYPE -windll = ctypes.windll +windll = ctypes.windll # The IronPython implementation of byref() was giving me problems, # so I'm replacing it with the slower pointer() function. @@ -73,7 +73,7 @@ class WinDllHook(object): def __getattr__(self, name): - if name.startswith('_'): + if name.startswith("_"): return object.__getattr__(self, name) return WinFuncHook(name) @@ -82,7 +82,7 @@ def __init__(self, name): self.__name = name def __getattr__(self, name): - if name.startswith('_'): + if name.startswith("_"): return object.__getattr__(self, name) return WinCallHook(self.__name, name) @@ -103,10 +103,10 @@ def __copy_attribute(self, attribute): pass def __call__(self, *argv): - self.__copy_attribute('argtypes') - self.__copy_attribute('restype') - self.__copy_attribute('errcheck') - print("-"*10) + self.__copy_attribute("argtypes") + self.__copy_attribute("restype") + self.__copy_attribute("errcheck") + print("-" * 10) print("%s ! %s %r" % (self.__dllname, self.__funcname, argv)) retval = self.__func(*argv) print("== %r" % (retval,)) @@ -114,13 +114,14 @@ def __call__(self, *argv): windll = WinDllHook() -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== -def RaiseIfZero(result, func = None, arguments = ()): + +def RaiseIfZero(result, func=None, arguments=()): """ Error checking for most Win32 API calls. @@ -131,7 +132,8 @@ def RaiseIfZero(result, func = None, arguments = ()): raise ctypes.WinError() return result -def RaiseIfNotZero(result, func = None, arguments = ()): + +def RaiseIfNotZero(result, func=None, arguments=()): """ Error checking for some odd Win32 API calls. @@ -145,7 +147,8 @@ def RaiseIfNotZero(result, func = None, arguments = ()): raise ctypes.WinError() return result -def RaiseIfNotErrorSuccess(result, func = None, arguments = ()): + +def RaiseIfNotErrorSuccess(result, func=None, arguments=()): """ Error checking for Win32 Registry API calls. @@ -156,6 +159,7 @@ def RaiseIfNotErrorSuccess(result, func = None, arguments = ()): raise ctypes.WinError(result) return result + class GuessStringType(object): """ Decorator that guesses the correct version (A or W) to call @@ -181,8 +185,8 @@ class GuessStringType(object): """ # ANSI and Unicode types - t_ansi = type('') - t_unicode = type(u'') + t_ansi = type("") + t_unicode = type("") # Default is ANSI for Python 2.x t_default = t_ansi @@ -194,7 +198,7 @@ def __init__(self, fn_ansi, fn_unicode): @type fn_unicode: function @param fn_unicode: Unicode (wide) version of the API function to call. """ - self.fn_ansi = fn_ansi + self.fn_ansi = fn_ansi self.fn_unicode = fn_unicode # Copy the wrapped function attributes. @@ -212,13 +216,12 @@ def __init__(self, fn_ansi, fn_unicode): pass def __call__(self, *argv, **argd): - # Shortcut to self.t_ansi - t_ansi = self.t_ansi + t_ansi = self.t_ansi # Get the types of all arguments for the function - v_types = [ type(item) for item in argv ] - v_types.extend( [ type(value) for (key, value) in compat.iteritems(argd) ] ) + v_types = [type(item) for item in argv] + v_types.extend([type(value) for (key, value) in compat.iteritems(argd)]) # Get the appropriate function for the default type if self.t_default == t_ansi: @@ -228,7 +231,6 @@ def __call__(self, *argv, **argd): # If at least one argument is a Unicode string... if self.t_unicode in v_types: - # If al least one argument is an ANSI string, # convert all ANSI strings to Unicode if t_ansi in v_types: @@ -236,7 +238,7 @@ def __call__(self, *argv, **argd): for index in compat.xrange(len(argv)): if v_types[index] == t_ansi: argv[index] = compat.unicode(argv[index]) - for (key, value) in argd.items(): + for key, value in argd.items(): if type(value) == t_ansi: argd[key] = compat.unicode(value) @@ -246,13 +248,13 @@ def __call__(self, *argv, **argd): # If at least one argument is an ANSI string, # but there are no Unicode strings... elif t_ansi in v_types: - # Use the A version fn = self.fn_ansi # Call the function and return the result return fn(*argv, **argd) + class DefaultStringType(object): """ Decorator that uses the default version (A or W) to call @@ -273,7 +275,7 @@ def __init__(self, fn_ansi, fn_unicode): @type fn_unicode: function @param fn_unicode: Unicode (wide) version of the API function to call. """ - self.fn_ansi = fn_ansi + self.fn_ansi = fn_ansi self.fn_unicode = fn_unicode # Copy the wrapped function attributes. @@ -291,7 +293,6 @@ def __init__(self, fn_ansi, fn_unicode): pass def __call__(self, *argv, **argd): - # Get the appropriate function based on the default. if GuessStringType.t_default == GuessStringType.t_ansi: fn = self.fn_ansi @@ -301,6 +302,7 @@ def __call__(self, *argv, **argd): # Call the function and return the result return fn(*argv, **argd) + def MakeANSIVersion(fn): """ Decorator that generates an ANSI version of a Unicode (wide) only API call. @@ -308,12 +310,13 @@ def MakeANSIVersion(fn): @type fn: callable @param fn: Unicode (wide) version of the API function to call. """ + @functools.wraps(fn) def wrapper(*argv, **argd): - t_ansi = GuessStringType.t_ansi + t_ansi = GuessStringType.t_ansi t_unicode = GuessStringType.t_unicode - v_types = [ type(item) for item in argv ] - v_types.extend( [ type(value) for (key, value) in compat.iteritems(argd) ] ) + v_types = [type(item) for item in argv] + v_types.extend([type(value) for (key, value) in compat.iteritems(argd)]) if t_ansi in v_types: argv = list(argv) for index in compat.xrange(len(argv)): @@ -323,8 +326,10 @@ def wrapper(*argv, **argd): if type(value) == t_ansi: argd[key] = t_unicode(value) return fn(*argv, **argd) + return wrapper + def MakeWideVersion(fn): """ Decorator that generates a Unicode (wide) version of an ANSI only API call. @@ -332,12 +337,13 @@ def MakeWideVersion(fn): @type fn: callable @param fn: ANSI version of the API function to call. """ + @functools.wraps(fn) def wrapper(*argv, **argd): - t_ansi = GuessStringType.t_ansi + t_ansi = GuessStringType.t_ansi t_unicode = GuessStringType.t_unicode - v_types = [ type(item) for item in argv ] - v_types.extend( [ type(value) for (key, value) in compat.iteritems(argd) ] ) + v_types = [type(item) for item in argv] + v_types.extend([type(value) for (key, value) in compat.iteritems(argd)]) if t_unicode in v_types: argv = list(argv) for index in compat.xrange(len(argv)): @@ -347,143 +353,145 @@ def wrapper(*argv, **argd): if type(value) == t_unicode: argd[key] = t_ansi(value) return fn(*argv, **argd) + return wrapper -#--- Types -------------------------------------------------------------------- + +# --- Types -------------------------------------------------------------------- # http://msdn.microsoft.com/en-us/library/aa383751(v=vs.85).aspx # Map of basic C types to Win32 types -LPVOID = ctypes.c_void_p -CHAR = ctypes.c_char -WCHAR = ctypes.c_wchar -BYTE = ctypes.c_ubyte -SBYTE = ctypes.c_byte -WORD = ctypes.c_uint16 -SWORD = ctypes.c_int16 -DWORD = ctypes.c_uint32 -SDWORD = ctypes.c_int32 -QWORD = ctypes.c_uint64 -SQWORD = ctypes.c_int64 -SHORT = ctypes.c_short -USHORT = ctypes.c_ushort -INT = ctypes.c_int -UINT = ctypes.c_uint -LONG = ctypes.c_long -ULONG = ctypes.c_ulong -LONGLONG = ctypes.c_int64 # c_longlong -ULONGLONG = ctypes.c_uint64 # c_ulonglong -LPSTR = ctypes.c_char_p -LPWSTR = ctypes.c_wchar_p -INT8 = ctypes.c_int8 -INT16 = ctypes.c_int16 -INT32 = ctypes.c_int32 -INT64 = ctypes.c_int64 -UINT8 = ctypes.c_uint8 -UINT16 = ctypes.c_uint16 -UINT32 = ctypes.c_uint32 -UINT64 = ctypes.c_uint64 -LONG32 = ctypes.c_int32 -LONG64 = ctypes.c_int64 -ULONG32 = ctypes.c_uint32 -ULONG64 = ctypes.c_uint64 -DWORD32 = ctypes.c_uint32 -DWORD64 = ctypes.c_uint64 -BOOL = ctypes.c_int -FLOAT = ctypes.c_float +LPVOID = ctypes.c_void_p +CHAR = ctypes.c_char +WCHAR = ctypes.c_wchar +BYTE = ctypes.c_ubyte +SBYTE = ctypes.c_byte +WORD = ctypes.c_uint16 +SWORD = ctypes.c_int16 +DWORD = ctypes.c_uint32 +SDWORD = ctypes.c_int32 +QWORD = ctypes.c_uint64 +SQWORD = ctypes.c_int64 +SHORT = ctypes.c_short +USHORT = ctypes.c_ushort +INT = ctypes.c_int +UINT = ctypes.c_uint +LONG = ctypes.c_long +ULONG = ctypes.c_ulong +LONGLONG = ctypes.c_int64 # c_longlong +ULONGLONG = ctypes.c_uint64 # c_ulonglong +LPSTR = ctypes.c_char_p +LPWSTR = ctypes.c_wchar_p +INT8 = ctypes.c_int8 +INT16 = ctypes.c_int16 +INT32 = ctypes.c_int32 +INT64 = ctypes.c_int64 +UINT8 = ctypes.c_uint8 +UINT16 = ctypes.c_uint16 +UINT32 = ctypes.c_uint32 +UINT64 = ctypes.c_uint64 +LONG32 = ctypes.c_int32 +LONG64 = ctypes.c_int64 +ULONG32 = ctypes.c_uint32 +ULONG64 = ctypes.c_uint64 +DWORD32 = ctypes.c_uint32 +DWORD64 = ctypes.c_uint64 +BOOL = ctypes.c_int +FLOAT = ctypes.c_float # Map size_t to SIZE_T try: - SIZE_T = ctypes.c_size_t + SIZE_T = ctypes.c_size_t SSIZE_T = ctypes.c_ssize_t except AttributeError: # Size of a pointer - SIZE_T = {1:BYTE, 2:WORD, 4:DWORD, 8:QWORD}[sizeof(LPVOID)] - SSIZE_T = {1:SBYTE, 2:SWORD, 4:SDWORD, 8:SQWORD}[sizeof(LPVOID)] -PSIZE_T = POINTER(SIZE_T) + SIZE_T = {1: BYTE, 2: WORD, 4: DWORD, 8: QWORD}[sizeof(LPVOID)] + SSIZE_T = {1: SBYTE, 2: SWORD, 4: SDWORD, 8: SQWORD}[sizeof(LPVOID)] +PSIZE_T = POINTER(SIZE_T) # Not really pointers but pointer-sized integers -DWORD_PTR = SIZE_T -ULONG_PTR = SIZE_T -LONG_PTR = SIZE_T +DWORD_PTR = SIZE_T +ULONG_PTR = SIZE_T +LONG_PTR = SIZE_T # Other Win32 types, more may be added as needed -PVOID = LPVOID -PPVOID = POINTER(PVOID) -PSTR = LPSTR -PWSTR = LPWSTR -PCHAR = LPSTR -PWCHAR = LPWSTR -LPBYTE = POINTER(BYTE) -LPSBYTE = POINTER(SBYTE) -LPWORD = POINTER(WORD) -LPSWORD = POINTER(SWORD) -LPDWORD = POINTER(DWORD) -LPSDWORD = POINTER(SDWORD) -LPULONG = POINTER(ULONG) -LPLONG = POINTER(LONG) -PDWORD = LPDWORD -PDWORD_PTR = POINTER(DWORD_PTR) -PULONG = LPULONG -PLONG = LPLONG -CCHAR = CHAR -BOOLEAN = BYTE -PBOOL = POINTER(BOOL) -LPBOOL = PBOOL -TCHAR = CHAR # XXX ANSI by default? -UCHAR = BYTE -DWORDLONG = ULONGLONG -LPDWORD32 = POINTER(DWORD32) -LPULONG32 = POINTER(ULONG32) -LPDWORD64 = POINTER(DWORD64) -LPULONG64 = POINTER(ULONG64) -PDWORD32 = LPDWORD32 -PULONG32 = LPULONG32 -PDWORD64 = LPDWORD64 -PULONG64 = LPULONG64 -ATOM = WORD -HANDLE = LPVOID -PHANDLE = POINTER(HANDLE) -LPHANDLE = PHANDLE -HMODULE = HANDLE -HINSTANCE = HANDLE -HTASK = HANDLE -HKEY = HANDLE -PHKEY = POINTER(HKEY) -HDESK = HANDLE -HRSRC = HANDLE -HSTR = HANDLE -HWINSTA = HANDLE -HKL = HANDLE -HDWP = HANDLE -HFILE = HANDLE -HRESULT = LONG -HGLOBAL = HANDLE -HLOCAL = HANDLE -HGDIOBJ = HANDLE -HDC = HGDIOBJ -HRGN = HGDIOBJ -HBITMAP = HGDIOBJ -HPALETTE = HGDIOBJ -HPEN = HGDIOBJ -HBRUSH = HGDIOBJ -HMF = HGDIOBJ -HEMF = HGDIOBJ +PVOID = LPVOID +PPVOID = POINTER(PVOID) +PSTR = LPSTR +PWSTR = LPWSTR +PCHAR = LPSTR +PWCHAR = LPWSTR +LPBYTE = POINTER(BYTE) +LPSBYTE = POINTER(SBYTE) +LPWORD = POINTER(WORD) +LPSWORD = POINTER(SWORD) +LPDWORD = POINTER(DWORD) +LPSDWORD = POINTER(SDWORD) +LPULONG = POINTER(ULONG) +LPLONG = POINTER(LONG) +PDWORD = LPDWORD +PDWORD_PTR = POINTER(DWORD_PTR) +PULONG = LPULONG +PLONG = LPLONG +CCHAR = CHAR +BOOLEAN = BYTE +PBOOL = POINTER(BOOL) +LPBOOL = PBOOL +TCHAR = CHAR # XXX ANSI by default? +UCHAR = BYTE +DWORDLONG = ULONGLONG +LPDWORD32 = POINTER(DWORD32) +LPULONG32 = POINTER(ULONG32) +LPDWORD64 = POINTER(DWORD64) +LPULONG64 = POINTER(ULONG64) +PDWORD32 = LPDWORD32 +PULONG32 = LPULONG32 +PDWORD64 = LPDWORD64 +PULONG64 = LPULONG64 +ATOM = WORD +HANDLE = LPVOID +PHANDLE = POINTER(HANDLE) +LPHANDLE = PHANDLE +HMODULE = HANDLE +HINSTANCE = HANDLE +HTASK = HANDLE +HKEY = HANDLE +PHKEY = POINTER(HKEY) +HDESK = HANDLE +HRSRC = HANDLE +HSTR = HANDLE +HWINSTA = HANDLE +HKL = HANDLE +HDWP = HANDLE +HFILE = HANDLE +HRESULT = LONG +HGLOBAL = HANDLE +HLOCAL = HANDLE +HGDIOBJ = HANDLE +HDC = HGDIOBJ +HRGN = HGDIOBJ +HBITMAP = HGDIOBJ +HPALETTE = HGDIOBJ +HPEN = HGDIOBJ +HBRUSH = HGDIOBJ +HMF = HGDIOBJ +HEMF = HGDIOBJ HENHMETAFILE = HGDIOBJ -HMETAFILE = HGDIOBJ +HMETAFILE = HGDIOBJ HMETAFILEPICT = HGDIOBJ -HWND = HANDLE -NTSTATUS = LONG -PNTSTATUS = POINTER(NTSTATUS) -KAFFINITY = ULONG_PTR -RVA = DWORD -RVA64 = QWORD -WPARAM = DWORD -LPARAM = LPVOID -LRESULT = LPVOID +HWND = HANDLE +NTSTATUS = LONG +PNTSTATUS = POINTER(NTSTATUS) +KAFFINITY = ULONG_PTR +RVA = DWORD +RVA64 = QWORD +WPARAM = DWORD +LPARAM = LPVOID +LRESULT = LPVOID ACCESS_MASK = DWORD -REGSAM = ACCESS_MASK +REGSAM = ACCESS_MASK PACCESS_MASK = POINTER(ACCESS_MASK) -PREGSAM = POINTER(REGSAM) +PREGSAM = POINTER(REGSAM) # Since the SID is an opaque structure, let's treat its pointers as void* PSID = PVOID @@ -503,41 +511,47 @@ def wrapper(*argv, **argd): # XXX TODO + # typedef struct _FLOAT128 { # __int64 LowPart; # __int64 HighPart; # } FLOAT128; -class FLOAT128 (Structure): +class FLOAT128(Structure): _fields_ = [ - ("LowPart", QWORD), - ("HighPart", QWORD), + ("LowPart", QWORD), + ("HighPart", QWORD), ] + + PFLOAT128 = POINTER(FLOAT128) + # typedef struct DECLSPEC_ALIGN(16) _M128A { # ULONGLONG Low; # LONGLONG High; # } M128A, *PM128A; class M128A(Structure): _fields_ = [ - ("Low", ULONGLONG), - ("High", LONGLONG), + ("Low", ULONGLONG), + ("High", LONGLONG), ] + + PM128A = POINTER(M128A) -#--- Constants ---------------------------------------------------------------- +# --- Constants ---------------------------------------------------------------- -NULL = None -INFINITE = -1 -TRUE = 1 -FALSE = 0 +NULL = None +INFINITE = -1 +TRUE = 1 +FALSE = 0 # http://blogs.msdn.com/oldnewthing/archive/2004/08/26/220873.aspx ANYSIZE_ARRAY = 1 # Invalid handle value is -1 casted to void pointer. try: - INVALID_HANDLE_VALUE = ctypes.c_void_p(-1).value #-1 #0xFFFFFFFF + INVALID_HANDLE_VALUE = ctypes.c_void_p(-1).value # -1 #0xFFFFFFFF except TypeError: if sizeof(ctypes.c_void_p) == 4: INVALID_HANDLE_VALUE = 0xFFFFFFFF @@ -546,126 +560,128 @@ class M128A(Structure): else: raise -MAX_MODULE_NAME32 = 255 -MAX_PATH = 260 +MAX_MODULE_NAME32 = 255 +MAX_PATH = 260 # Error codes # TODO maybe add more error codes? # if they're too many they could be pickled instead, # or at the very least put in a new file -ERROR_SUCCESS = 0 -ERROR_INVALID_FUNCTION = 1 -ERROR_FILE_NOT_FOUND = 2 -ERROR_PATH_NOT_FOUND = 3 -ERROR_ACCESS_DENIED = 5 -ERROR_INVALID_HANDLE = 6 -ERROR_NOT_ENOUGH_MEMORY = 8 -ERROR_INVALID_DRIVE = 15 -ERROR_NO_MORE_FILES = 18 -ERROR_BAD_LENGTH = 24 -ERROR_HANDLE_EOF = 38 -ERROR_HANDLE_DISK_FULL = 39 -ERROR_NOT_SUPPORTED = 50 -ERROR_FILE_EXISTS = 80 -ERROR_INVALID_PARAMETER = 87 -ERROR_BUFFER_OVERFLOW = 111 -ERROR_DISK_FULL = 112 -ERROR_CALL_NOT_IMPLEMENTED = 120 -ERROR_SEM_TIMEOUT = 121 -ERROR_INSUFFICIENT_BUFFER = 122 -ERROR_INVALID_NAME = 123 -ERROR_MOD_NOT_FOUND = 126 -ERROR_PROC_NOT_FOUND = 127 -ERROR_DIR_NOT_EMPTY = 145 -ERROR_BAD_THREADID_ADDR = 159 -ERROR_BAD_ARGUMENTS = 160 -ERROR_BAD_PATHNAME = 161 -ERROR_ALREADY_EXISTS = 183 -ERROR_INVALID_FLAG_NUMBER = 186 -ERROR_ENVVAR_NOT_FOUND = 203 -ERROR_FILENAME_EXCED_RANGE = 206 -ERROR_MORE_DATA = 234 - -WAIT_TIMEOUT = 258 - -ERROR_NO_MORE_ITEMS = 259 -ERROR_PARTIAL_COPY = 299 -ERROR_INVALID_ADDRESS = 487 -ERROR_THREAD_NOT_IN_PROCESS = 566 -ERROR_CONTROL_C_EXIT = 572 -ERROR_UNHANDLED_EXCEPTION = 574 -ERROR_ASSERTION_FAILURE = 668 -ERROR_WOW_ASSERTION = 670 - -ERROR_DBG_EXCEPTION_NOT_HANDLED = 688 -ERROR_DBG_REPLY_LATER = 689 -ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE = 690 -ERROR_DBG_TERMINATE_THREAD = 691 -ERROR_DBG_TERMINATE_PROCESS = 692 -ERROR_DBG_CONTROL_C = 693 -ERROR_DBG_PRINTEXCEPTION_C = 694 -ERROR_DBG_RIPEXCEPTION = 695 -ERROR_DBG_CONTROL_BREAK = 696 -ERROR_DBG_COMMAND_EXCEPTION = 697 -ERROR_DBG_EXCEPTION_HANDLED = 766 -ERROR_DBG_CONTINUE = 767 - -ERROR_ELEVATION_REQUIRED = 740 -ERROR_NOACCESS = 998 - -ERROR_CIRCULAR_DEPENDENCY = 1059 -ERROR_SERVICE_DOES_NOT_EXIST = 1060 -ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061 -ERROR_SERVICE_NOT_ACTIVE = 1062 +ERROR_SUCCESS = 0 +ERROR_INVALID_FUNCTION = 1 +ERROR_FILE_NOT_FOUND = 2 +ERROR_PATH_NOT_FOUND = 3 +ERROR_ACCESS_DENIED = 5 +ERROR_INVALID_HANDLE = 6 +ERROR_NOT_ENOUGH_MEMORY = 8 +ERROR_INVALID_DRIVE = 15 +ERROR_NO_MORE_FILES = 18 +ERROR_BAD_LENGTH = 24 +ERROR_HANDLE_EOF = 38 +ERROR_HANDLE_DISK_FULL = 39 +ERROR_NOT_SUPPORTED = 50 +ERROR_FILE_EXISTS = 80 +ERROR_INVALID_PARAMETER = 87 +ERROR_BUFFER_OVERFLOW = 111 +ERROR_DISK_FULL = 112 +ERROR_CALL_NOT_IMPLEMENTED = 120 +ERROR_SEM_TIMEOUT = 121 +ERROR_INSUFFICIENT_BUFFER = 122 +ERROR_INVALID_NAME = 123 +ERROR_MOD_NOT_FOUND = 126 +ERROR_PROC_NOT_FOUND = 127 +ERROR_DIR_NOT_EMPTY = 145 +ERROR_BAD_THREADID_ADDR = 159 +ERROR_BAD_ARGUMENTS = 160 +ERROR_BAD_PATHNAME = 161 +ERROR_ALREADY_EXISTS = 183 +ERROR_INVALID_FLAG_NUMBER = 186 +ERROR_ENVVAR_NOT_FOUND = 203 +ERROR_FILENAME_EXCED_RANGE = 206 +ERROR_MORE_DATA = 234 + +WAIT_TIMEOUT = 258 + +ERROR_NO_MORE_ITEMS = 259 +ERROR_PARTIAL_COPY = 299 +ERROR_INVALID_ADDRESS = 487 +ERROR_THREAD_NOT_IN_PROCESS = 566 +ERROR_CONTROL_C_EXIT = 572 +ERROR_UNHANDLED_EXCEPTION = 574 +ERROR_ASSERTION_FAILURE = 668 +ERROR_WOW_ASSERTION = 670 + +ERROR_DBG_EXCEPTION_NOT_HANDLED = 688 +ERROR_DBG_REPLY_LATER = 689 +ERROR_DBG_UNABLE_TO_PROVIDE_HANDLE = 690 +ERROR_DBG_TERMINATE_THREAD = 691 +ERROR_DBG_TERMINATE_PROCESS = 692 +ERROR_DBG_CONTROL_C = 693 +ERROR_DBG_PRINTEXCEPTION_C = 694 +ERROR_DBG_RIPEXCEPTION = 695 +ERROR_DBG_CONTROL_BREAK = 696 +ERROR_DBG_COMMAND_EXCEPTION = 697 +ERROR_DBG_EXCEPTION_HANDLED = 766 +ERROR_DBG_CONTINUE = 767 + +ERROR_ELEVATION_REQUIRED = 740 +ERROR_NOACCESS = 998 + +ERROR_CIRCULAR_DEPENDENCY = 1059 +ERROR_SERVICE_DOES_NOT_EXIST = 1060 +ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061 +ERROR_SERVICE_NOT_ACTIVE = 1062 ERROR_FAILED_SERVICE_CONTROLLER_CONNECT = 1063 -ERROR_EXCEPTION_IN_SERVICE = 1064 -ERROR_DATABASE_DOES_NOT_EXIST = 1065 -ERROR_SERVICE_SPECIFIC_ERROR = 1066 -ERROR_PROCESS_ABORTED = 1067 -ERROR_SERVICE_DEPENDENCY_FAIL = 1068 -ERROR_SERVICE_LOGON_FAILED = 1069 -ERROR_SERVICE_START_HANG = 1070 -ERROR_INVALID_SERVICE_LOCK = 1071 -ERROR_SERVICE_MARKED_FOR_DELETE = 1072 -ERROR_SERVICE_EXISTS = 1073 -ERROR_ALREADY_RUNNING_LKG = 1074 -ERROR_SERVICE_DEPENDENCY_DELETED = 1075 -ERROR_BOOT_ALREADY_ACCEPTED = 1076 -ERROR_SERVICE_NEVER_STARTED = 1077 -ERROR_DUPLICATE_SERVICE_NAME = 1078 -ERROR_DIFFERENT_SERVICE_ACCOUNT = 1079 -ERROR_CANNOT_DETECT_DRIVER_FAILURE = 1080 -ERROR_CANNOT_DETECT_PROCESS_ABORT = 1081 -ERROR_NO_RECOVERY_PROGRAM = 1082 -ERROR_SERVICE_NOT_IN_EXE = 1083 -ERROR_NOT_SAFEBOOT_SERVICE = 1084 - -ERROR_DEBUGGER_INACTIVE = 1284 - -ERROR_PRIVILEGE_NOT_HELD = 1314 - -ERROR_NONE_MAPPED = 1332 - -RPC_S_SERVER_UNAVAILABLE = 1722 +ERROR_EXCEPTION_IN_SERVICE = 1064 +ERROR_DATABASE_DOES_NOT_EXIST = 1065 +ERROR_SERVICE_SPECIFIC_ERROR = 1066 +ERROR_PROCESS_ABORTED = 1067 +ERROR_SERVICE_DEPENDENCY_FAIL = 1068 +ERROR_SERVICE_LOGON_FAILED = 1069 +ERROR_SERVICE_START_HANG = 1070 +ERROR_INVALID_SERVICE_LOCK = 1071 +ERROR_SERVICE_MARKED_FOR_DELETE = 1072 +ERROR_SERVICE_EXISTS = 1073 +ERROR_ALREADY_RUNNING_LKG = 1074 +ERROR_SERVICE_DEPENDENCY_DELETED = 1075 +ERROR_BOOT_ALREADY_ACCEPTED = 1076 +ERROR_SERVICE_NEVER_STARTED = 1077 +ERROR_DUPLICATE_SERVICE_NAME = 1078 +ERROR_DIFFERENT_SERVICE_ACCOUNT = 1079 +ERROR_CANNOT_DETECT_DRIVER_FAILURE = 1080 +ERROR_CANNOT_DETECT_PROCESS_ABORT = 1081 +ERROR_NO_RECOVERY_PROGRAM = 1082 +ERROR_SERVICE_NOT_IN_EXE = 1083 +ERROR_NOT_SAFEBOOT_SERVICE = 1084 + +ERROR_DEBUGGER_INACTIVE = 1284 + +ERROR_PRIVILEGE_NOT_HELD = 1314 + +ERROR_NONE_MAPPED = 1332 + +RPC_S_SERVER_UNAVAILABLE = 1722 # Standard access rights import sys + if sys.version_info[0] >= 3: long = int -DELETE = long(0x00010000) -READ_CONTROL = long(0x00020000) -WRITE_DAC = long(0x00040000) -WRITE_OWNER = long(0x00080000) -SYNCHRONIZE = long(0x00100000) -STANDARD_RIGHTS_REQUIRED = long(0x000F0000) -STANDARD_RIGHTS_READ = READ_CONTROL -STANDARD_RIGHTS_WRITE = READ_CONTROL -STANDARD_RIGHTS_EXECUTE = READ_CONTROL -STANDARD_RIGHTS_ALL = long(0x001F0000) -SPECIFIC_RIGHTS_ALL = long(0x0000FFFF) +DELETE = long(0x00010000) +READ_CONTROL = long(0x00020000) +WRITE_DAC = long(0x00040000) +WRITE_OWNER = long(0x00080000) +SYNCHRONIZE = long(0x00100000) +STANDARD_RIGHTS_REQUIRED = long(0x000F0000) +STANDARD_RIGHTS_READ = READ_CONTROL +STANDARD_RIGHTS_WRITE = READ_CONTROL +STANDARD_RIGHTS_EXECUTE = READ_CONTROL +STANDARD_RIGHTS_ALL = long(0x001F0000) +SPECIFIC_RIGHTS_ALL = long(0x0000FFFF) + +# --- Structures --------------------------------------------------------------- -#--- Structures --------------------------------------------------------------- # typedef struct _LSA_UNICODE_STRING { # USHORT Length; @@ -677,11 +693,12 @@ class M128A(Structure): # *PUNICODE_STRING; class UNICODE_STRING(Structure): _fields_ = [ - ("Length", USHORT), - ("MaximumLength", USHORT), - ("Buffer", PVOID), + ("Length", USHORT), + ("MaximumLength", USHORT), + ("Buffer", PVOID), ] + # From MSDN: # # typedef struct _GUID { @@ -692,11 +709,12 @@ class UNICODE_STRING(Structure): # } GUID; class GUID(Structure): _fields_ = [ - ("Data1", DWORD), - ("Data2", WORD), - ("Data3", WORD), - ("Data4", BYTE * 8), -] + ("Data1", DWORD), + ("Data2", WORD), + ("Data3", WORD), + ("Data4", BYTE * 8), + ] + # From MSDN: # @@ -706,13 +724,14 @@ class GUID(Structure): # } LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY; class LIST_ENTRY(Structure): _fields_ = [ - ("Flink", PVOID), # POINTER(LIST_ENTRY) - ("Blink", PVOID), # POINTER(LIST_ENTRY) -] + ("Flink", PVOID), # POINTER(LIST_ENTRY) + ("Blink", PVOID), # POINTER(LIST_ENTRY) + ] + -#============================================================================== +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) ##__all__ = [_x for _x in _all if not _x.startswith('_')] ##__all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/gdi32.py b/pydevd_attach_to_process/winappdbg/win32/gdi32.py index c3b5e6ebc..77c5b1382 100644 --- a/pydevd_attach_to_process/winappdbg/win32/gdi32.py +++ b/pydevd_attach_to_process/winappdbg/win32/gdi32.py @@ -37,271 +37,272 @@ from winappdbg.win32.defines import * from winappdbg.win32.kernel32 import GetLastError, SetLastError -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== -#--- Helpers ------------------------------------------------------------------ +# --- Helpers ------------------------------------------------------------------ -#--- Types -------------------------------------------------------------------- +# --- Types -------------------------------------------------------------------- -#--- Constants ---------------------------------------------------------------- +# --- Constants ---------------------------------------------------------------- # GDI object types -OBJ_PEN = 1 -OBJ_BRUSH = 2 -OBJ_DC = 3 -OBJ_METADC = 4 -OBJ_PAL = 5 -OBJ_FONT = 6 -OBJ_BITMAP = 7 -OBJ_REGION = 8 -OBJ_METAFILE = 9 -OBJ_MEMDC = 10 -OBJ_EXTPEN = 11 -OBJ_ENHMETADC = 12 -OBJ_ENHMETAFILE = 13 -OBJ_COLORSPACE = 14 -GDI_OBJ_LAST = OBJ_COLORSPACE +OBJ_PEN = 1 +OBJ_BRUSH = 2 +OBJ_DC = 3 +OBJ_METADC = 4 +OBJ_PAL = 5 +OBJ_FONT = 6 +OBJ_BITMAP = 7 +OBJ_REGION = 8 +OBJ_METAFILE = 9 +OBJ_MEMDC = 10 +OBJ_EXTPEN = 11 +OBJ_ENHMETADC = 12 +OBJ_ENHMETAFILE = 13 +OBJ_COLORSPACE = 14 +GDI_OBJ_LAST = OBJ_COLORSPACE # Ternary raster operations -SRCCOPY = 0x00CC0020 # dest = source -SRCPAINT = 0x00EE0086 # dest = source OR dest -SRCAND = 0x008800C6 # dest = source AND dest -SRCINVERT = 0x00660046 # dest = source XOR dest -SRCERASE = 0x00440328 # dest = source AND (NOT dest) -NOTSRCCOPY = 0x00330008 # dest = (NOT source) -NOTSRCERASE = 0x001100A6 # dest = (NOT src) AND (NOT dest) -MERGECOPY = 0x00C000CA # dest = (source AND pattern) -MERGEPAINT = 0x00BB0226 # dest = (NOT source) OR dest -PATCOPY = 0x00F00021 # dest = pattern -PATPAINT = 0x00FB0A09 # dest = DPSnoo -PATINVERT = 0x005A0049 # dest = pattern XOR dest -DSTINVERT = 0x00550009 # dest = (NOT dest) -BLACKNESS = 0x00000042 # dest = BLACK -WHITENESS = 0x00FF0062 # dest = WHITE -NOMIRRORBITMAP = 0x80000000 # Do not Mirror the bitmap in this call -CAPTUREBLT = 0x40000000 # Include layered windows +SRCCOPY = 0x00CC0020 # dest = source +SRCPAINT = 0x00EE0086 # dest = source OR dest +SRCAND = 0x008800C6 # dest = source AND dest +SRCINVERT = 0x00660046 # dest = source XOR dest +SRCERASE = 0x00440328 # dest = source AND (NOT dest) +NOTSRCCOPY = 0x00330008 # dest = (NOT source) +NOTSRCERASE = 0x001100A6 # dest = (NOT src) AND (NOT dest) +MERGECOPY = 0x00C000CA # dest = (source AND pattern) +MERGEPAINT = 0x00BB0226 # dest = (NOT source) OR dest +PATCOPY = 0x00F00021 # dest = pattern +PATPAINT = 0x00FB0A09 # dest = DPSnoo +PATINVERT = 0x005A0049 # dest = pattern XOR dest +DSTINVERT = 0x00550009 # dest = (NOT dest) +BLACKNESS = 0x00000042 # dest = BLACK +WHITENESS = 0x00FF0062 # dest = WHITE +NOMIRRORBITMAP = 0x80000000 # Do not Mirror the bitmap in this call +CAPTUREBLT = 0x40000000 # Include layered windows # Region flags -ERROR = 0 -NULLREGION = 1 -SIMPLEREGION = 2 -COMPLEXREGION = 3 -RGN_ERROR = ERROR +ERROR = 0 +NULLREGION = 1 +SIMPLEREGION = 2 +COMPLEXREGION = 3 +RGN_ERROR = ERROR # CombineRgn() styles -RGN_AND = 1 -RGN_OR = 2 -RGN_XOR = 3 -RGN_DIFF = 4 -RGN_COPY = 5 -RGN_MIN = RGN_AND -RGN_MAX = RGN_COPY +RGN_AND = 1 +RGN_OR = 2 +RGN_XOR = 3 +RGN_DIFF = 4 +RGN_COPY = 5 +RGN_MIN = RGN_AND +RGN_MAX = RGN_COPY # StretchBlt() modes -BLACKONWHITE = 1 -WHITEONBLACK = 2 -COLORONCOLOR = 3 -HALFTONE = 4 -MAXSTRETCHBLTMODE = 4 -STRETCH_ANDSCANS = BLACKONWHITE -STRETCH_ORSCANS = WHITEONBLACK +BLACKONWHITE = 1 +WHITEONBLACK = 2 +COLORONCOLOR = 3 +HALFTONE = 4 +MAXSTRETCHBLTMODE = 4 +STRETCH_ANDSCANS = BLACKONWHITE +STRETCH_ORSCANS = WHITEONBLACK STRETCH_DELETESCANS = COLORONCOLOR -STRETCH_HALFTONE = HALFTONE +STRETCH_HALFTONE = HALFTONE # PolyFill() modes -ALTERNATE = 1 -WINDING = 2 -POLYFILL_LAST = 2 +ALTERNATE = 1 +WINDING = 2 +POLYFILL_LAST = 2 # Layout orientation options -LAYOUT_RTL = 0x00000001 # Right to left -LAYOUT_BTT = 0x00000002 # Bottom to top -LAYOUT_VBH = 0x00000004 # Vertical before horizontal -LAYOUT_ORIENTATIONMASK = LAYOUT_RTL + LAYOUT_BTT + LAYOUT_VBH -LAYOUT_BITMAPORIENTATIONPRESERVED = 0x00000008 +LAYOUT_RTL = 0x00000001 # Right to left +LAYOUT_BTT = 0x00000002 # Bottom to top +LAYOUT_VBH = 0x00000004 # Vertical before horizontal +LAYOUT_ORIENTATIONMASK = LAYOUT_RTL + LAYOUT_BTT + LAYOUT_VBH +LAYOUT_BITMAPORIENTATIONPRESERVED = 0x00000008 # Stock objects -WHITE_BRUSH = 0 -LTGRAY_BRUSH = 1 -GRAY_BRUSH = 2 -DKGRAY_BRUSH = 3 -BLACK_BRUSH = 4 -NULL_BRUSH = 5 -HOLLOW_BRUSH = NULL_BRUSH -WHITE_PEN = 6 -BLACK_PEN = 7 -NULL_PEN = 8 -OEM_FIXED_FONT = 10 -ANSI_FIXED_FONT = 11 -ANSI_VAR_FONT = 12 -SYSTEM_FONT = 13 +WHITE_BRUSH = 0 +LTGRAY_BRUSH = 1 +GRAY_BRUSH = 2 +DKGRAY_BRUSH = 3 +BLACK_BRUSH = 4 +NULL_BRUSH = 5 +HOLLOW_BRUSH = NULL_BRUSH +WHITE_PEN = 6 +BLACK_PEN = 7 +NULL_PEN = 8 +OEM_FIXED_FONT = 10 +ANSI_FIXED_FONT = 11 +ANSI_VAR_FONT = 12 +SYSTEM_FONT = 13 DEVICE_DEFAULT_FONT = 14 -DEFAULT_PALETTE = 15 -SYSTEM_FIXED_FONT = 16 +DEFAULT_PALETTE = 15 +SYSTEM_FIXED_FONT = 16 # Metafile functions -META_SETBKCOLOR = 0x0201 -META_SETBKMODE = 0x0102 -META_SETMAPMODE = 0x0103 -META_SETROP2 = 0x0104 -META_SETRELABS = 0x0105 -META_SETPOLYFILLMODE = 0x0106 -META_SETSTRETCHBLTMODE = 0x0107 -META_SETTEXTCHAREXTRA = 0x0108 -META_SETTEXTCOLOR = 0x0209 -META_SETTEXTJUSTIFICATION = 0x020A -META_SETWINDOWORG = 0x020B -META_SETWINDOWEXT = 0x020C -META_SETVIEWPORTORG = 0x020D -META_SETVIEWPORTEXT = 0x020E -META_OFFSETWINDOWORG = 0x020F -META_SCALEWINDOWEXT = 0x0410 -META_OFFSETVIEWPORTORG = 0x0211 -META_SCALEVIEWPORTEXT = 0x0412 -META_LINETO = 0x0213 -META_MOVETO = 0x0214 -META_EXCLUDECLIPRECT = 0x0415 -META_INTERSECTCLIPRECT = 0x0416 -META_ARC = 0x0817 -META_ELLIPSE = 0x0418 -META_FLOODFILL = 0x0419 -META_PIE = 0x081A -META_RECTANGLE = 0x041B -META_ROUNDRECT = 0x061C -META_PATBLT = 0x061D -META_SAVEDC = 0x001E -META_SETPIXEL = 0x041F -META_OFFSETCLIPRGN = 0x0220 -META_TEXTOUT = 0x0521 -META_BITBLT = 0x0922 -META_STRETCHBLT = 0x0B23 -META_POLYGON = 0x0324 -META_POLYLINE = 0x0325 -META_ESCAPE = 0x0626 -META_RESTOREDC = 0x0127 -META_FILLREGION = 0x0228 -META_FRAMEREGION = 0x0429 -META_INVERTREGION = 0x012A -META_PAINTREGION = 0x012B -META_SELECTCLIPREGION = 0x012C -META_SELECTOBJECT = 0x012D -META_SETTEXTALIGN = 0x012E -META_CHORD = 0x0830 -META_SETMAPPERFLAGS = 0x0231 -META_EXTTEXTOUT = 0x0a32 -META_SETDIBTODEV = 0x0d33 -META_SELECTPALETTE = 0x0234 -META_REALIZEPALETTE = 0x0035 -META_ANIMATEPALETTE = 0x0436 -META_SETPALENTRIES = 0x0037 -META_POLYPOLYGON = 0x0538 -META_RESIZEPALETTE = 0x0139 -META_DIBBITBLT = 0x0940 -META_DIBSTRETCHBLT = 0x0b41 -META_DIBCREATEPATTERNBRUSH = 0x0142 -META_STRETCHDIB = 0x0f43 -META_EXTFLOODFILL = 0x0548 -META_SETLAYOUT = 0x0149 -META_DELETEOBJECT = 0x01f0 -META_CREATEPALETTE = 0x00f7 -META_CREATEPATTERNBRUSH = 0x01F9 -META_CREATEPENINDIRECT = 0x02FA -META_CREATEFONTINDIRECT = 0x02FB -META_CREATEBRUSHINDIRECT = 0x02FC -META_CREATEREGION = 0x06FF +META_SETBKCOLOR = 0x0201 +META_SETBKMODE = 0x0102 +META_SETMAPMODE = 0x0103 +META_SETROP2 = 0x0104 +META_SETRELABS = 0x0105 +META_SETPOLYFILLMODE = 0x0106 +META_SETSTRETCHBLTMODE = 0x0107 +META_SETTEXTCHAREXTRA = 0x0108 +META_SETTEXTCOLOR = 0x0209 +META_SETTEXTJUSTIFICATION = 0x020A +META_SETWINDOWORG = 0x020B +META_SETWINDOWEXT = 0x020C +META_SETVIEWPORTORG = 0x020D +META_SETVIEWPORTEXT = 0x020E +META_OFFSETWINDOWORG = 0x020F +META_SCALEWINDOWEXT = 0x0410 +META_OFFSETVIEWPORTORG = 0x0211 +META_SCALEVIEWPORTEXT = 0x0412 +META_LINETO = 0x0213 +META_MOVETO = 0x0214 +META_EXCLUDECLIPRECT = 0x0415 +META_INTERSECTCLIPRECT = 0x0416 +META_ARC = 0x0817 +META_ELLIPSE = 0x0418 +META_FLOODFILL = 0x0419 +META_PIE = 0x081A +META_RECTANGLE = 0x041B +META_ROUNDRECT = 0x061C +META_PATBLT = 0x061D +META_SAVEDC = 0x001E +META_SETPIXEL = 0x041F +META_OFFSETCLIPRGN = 0x0220 +META_TEXTOUT = 0x0521 +META_BITBLT = 0x0922 +META_STRETCHBLT = 0x0B23 +META_POLYGON = 0x0324 +META_POLYLINE = 0x0325 +META_ESCAPE = 0x0626 +META_RESTOREDC = 0x0127 +META_FILLREGION = 0x0228 +META_FRAMEREGION = 0x0429 +META_INVERTREGION = 0x012A +META_PAINTREGION = 0x012B +META_SELECTCLIPREGION = 0x012C +META_SELECTOBJECT = 0x012D +META_SETTEXTALIGN = 0x012E +META_CHORD = 0x0830 +META_SETMAPPERFLAGS = 0x0231 +META_EXTTEXTOUT = 0x0A32 +META_SETDIBTODEV = 0x0D33 +META_SELECTPALETTE = 0x0234 +META_REALIZEPALETTE = 0x0035 +META_ANIMATEPALETTE = 0x0436 +META_SETPALENTRIES = 0x0037 +META_POLYPOLYGON = 0x0538 +META_RESIZEPALETTE = 0x0139 +META_DIBBITBLT = 0x0940 +META_DIBSTRETCHBLT = 0x0B41 +META_DIBCREATEPATTERNBRUSH = 0x0142 +META_STRETCHDIB = 0x0F43 +META_EXTFLOODFILL = 0x0548 +META_SETLAYOUT = 0x0149 +META_DELETEOBJECT = 0x01F0 +META_CREATEPALETTE = 0x00F7 +META_CREATEPATTERNBRUSH = 0x01F9 +META_CREATEPENINDIRECT = 0x02FA +META_CREATEFONTINDIRECT = 0x02FB +META_CREATEBRUSHINDIRECT = 0x02FC +META_CREATEREGION = 0x06FF # Metafile escape codes -NEWFRAME = 1 -ABORTDOC = 2 -NEXTBAND = 3 -SETCOLORTABLE = 4 -GETCOLORTABLE = 5 -FLUSHOUTPUT = 6 -DRAFTMODE = 7 -QUERYESCSUPPORT = 8 -SETABORTPROC = 9 -STARTDOC = 10 -ENDDOC = 11 -GETPHYSPAGESIZE = 12 -GETPRINTINGOFFSET = 13 -GETSCALINGFACTOR = 14 -MFCOMMENT = 15 -GETPENWIDTH = 16 -SETCOPYCOUNT = 17 -SELECTPAPERSOURCE = 18 -DEVICEDATA = 19 -PASSTHROUGH = 19 -GETTECHNOLGY = 20 -GETTECHNOLOGY = 20 -SETLINECAP = 21 -SETLINEJOIN = 22 -SETMITERLIMIT = 23 -BANDINFO = 24 -DRAWPATTERNRECT = 25 -GETVECTORPENSIZE = 26 -GETVECTORBRUSHSIZE = 27 -ENABLEDUPLEX = 28 -GETSETPAPERBINS = 29 -GETSETPRINTORIENT = 30 -ENUMPAPERBINS = 31 -SETDIBSCALING = 32 -EPSPRINTING = 33 -ENUMPAPERMETRICS = 34 -GETSETPAPERMETRICS = 35 -POSTSCRIPT_DATA = 37 -POSTSCRIPT_IGNORE = 38 -MOUSETRAILS = 39 -GETDEVICEUNITS = 42 -GETEXTENDEDTEXTMETRICS = 256 -GETEXTENTTABLE = 257 -GETPAIRKERNTABLE = 258 -GETTRACKKERNTABLE = 259 -EXTTEXTOUT = 512 -GETFACENAME = 513 -DOWNLOADFACE = 514 -ENABLERELATIVEWIDTHS = 768 -ENABLEPAIRKERNING = 769 -SETKERNTRACK = 770 -SETALLJUSTVALUES = 771 -SETCHARSET = 772 -STRETCHBLT = 2048 -METAFILE_DRIVER = 2049 -GETSETSCREENPARAMS = 3072 -QUERYDIBSUPPORT = 3073 -BEGIN_PATH = 4096 -CLIP_TO_PATH = 4097 -END_PATH = 4098 -EXT_DEVICE_CAPS = 4099 -RESTORE_CTM = 4100 -SAVE_CTM = 4101 -SET_ARC_DIRECTION = 4102 -SET_BACKGROUND_COLOR = 4103 -SET_POLY_MODE = 4104 -SET_SCREEN_ANGLE = 4105 -SET_SPREAD = 4106 -TRANSFORM_CTM = 4107 -SET_CLIP_BOX = 4108 -SET_BOUNDS = 4109 -SET_MIRROR_MODE = 4110 -OPENCHANNEL = 4110 -DOWNLOADHEADER = 4111 -CLOSECHANNEL = 4112 -POSTSCRIPT_PASSTHROUGH = 4115 -ENCAPSULATED_POSTSCRIPT = 4116 -POSTSCRIPT_IDENTIFY = 4117 -POSTSCRIPT_INJECTION = 4118 -CHECKJPEGFORMAT = 4119 -CHECKPNGFORMAT = 4120 -GET_PS_FEATURESETTING = 4121 -GDIPLUS_TS_QUERYVER = 4122 -GDIPLUS_TS_RECORD = 4123 -SPCLPASSTHROUGH2 = 4568 - -#--- Structures --------------------------------------------------------------- +NEWFRAME = 1 +ABORTDOC = 2 +NEXTBAND = 3 +SETCOLORTABLE = 4 +GETCOLORTABLE = 5 +FLUSHOUTPUT = 6 +DRAFTMODE = 7 +QUERYESCSUPPORT = 8 +SETABORTPROC = 9 +STARTDOC = 10 +ENDDOC = 11 +GETPHYSPAGESIZE = 12 +GETPRINTINGOFFSET = 13 +GETSCALINGFACTOR = 14 +MFCOMMENT = 15 +GETPENWIDTH = 16 +SETCOPYCOUNT = 17 +SELECTPAPERSOURCE = 18 +DEVICEDATA = 19 +PASSTHROUGH = 19 +GETTECHNOLGY = 20 +GETTECHNOLOGY = 20 +SETLINECAP = 21 +SETLINEJOIN = 22 +SETMITERLIMIT = 23 +BANDINFO = 24 +DRAWPATTERNRECT = 25 +GETVECTORPENSIZE = 26 +GETVECTORBRUSHSIZE = 27 +ENABLEDUPLEX = 28 +GETSETPAPERBINS = 29 +GETSETPRINTORIENT = 30 +ENUMPAPERBINS = 31 +SETDIBSCALING = 32 +EPSPRINTING = 33 +ENUMPAPERMETRICS = 34 +GETSETPAPERMETRICS = 35 +POSTSCRIPT_DATA = 37 +POSTSCRIPT_IGNORE = 38 +MOUSETRAILS = 39 +GETDEVICEUNITS = 42 +GETEXTENDEDTEXTMETRICS = 256 +GETEXTENTTABLE = 257 +GETPAIRKERNTABLE = 258 +GETTRACKKERNTABLE = 259 +EXTTEXTOUT = 512 +GETFACENAME = 513 +DOWNLOADFACE = 514 +ENABLERELATIVEWIDTHS = 768 +ENABLEPAIRKERNING = 769 +SETKERNTRACK = 770 +SETALLJUSTVALUES = 771 +SETCHARSET = 772 +STRETCHBLT = 2048 +METAFILE_DRIVER = 2049 +GETSETSCREENPARAMS = 3072 +QUERYDIBSUPPORT = 3073 +BEGIN_PATH = 4096 +CLIP_TO_PATH = 4097 +END_PATH = 4098 +EXT_DEVICE_CAPS = 4099 +RESTORE_CTM = 4100 +SAVE_CTM = 4101 +SET_ARC_DIRECTION = 4102 +SET_BACKGROUND_COLOR = 4103 +SET_POLY_MODE = 4104 +SET_SCREEN_ANGLE = 4105 +SET_SPREAD = 4106 +TRANSFORM_CTM = 4107 +SET_CLIP_BOX = 4108 +SET_BOUNDS = 4109 +SET_MIRROR_MODE = 4110 +OPENCHANNEL = 4110 +DOWNLOADHEADER = 4111 +CLOSECHANNEL = 4112 +POSTSCRIPT_PASSTHROUGH = 4115 +ENCAPSULATED_POSTSCRIPT = 4116 +POSTSCRIPT_IDENTIFY = 4117 +POSTSCRIPT_INJECTION = 4118 +CHECKJPEGFORMAT = 4119 +CHECKPNGFORMAT = 4120 +GET_PS_FEATURESETTING = 4121 +GDIPLUS_TS_QUERYVER = 4122 +GDIPLUS_TS_RECORD = 4123 +SPCLPASSTHROUGH2 = 4568 + +# --- Structures --------------------------------------------------------------- + # typedef struct _RECT { # LONG left; @@ -311,26 +312,32 @@ # }RECT, *PRECT; class RECT(Structure): _fields_ = [ - ('left', LONG), - ('top', LONG), - ('right', LONG), - ('bottom', LONG), + ("left", LONG), + ("top", LONG), + ("right", LONG), + ("bottom", LONG), ] -PRECT = POINTER(RECT) + + +PRECT = POINTER(RECT) LPRECT = PRECT + # typedef struct tagPOINT { # LONG x; # LONG y; # } POINT; class POINT(Structure): _fields_ = [ - ('x', LONG), - ('y', LONG), + ("x", LONG), + ("y", LONG), ] -PPOINT = POINTER(POINT) + + +PPOINT = POINTER(POINT) LPPOINT = PPOINT + # typedef struct tagBITMAP { # LONG bmType; # LONG bmWidth; @@ -342,20 +349,23 @@ class POINT(Structure): # } BITMAP, *PBITMAP; class BITMAP(Structure): _fields_ = [ - ("bmType", LONG), - ("bmWidth", LONG), - ("bmHeight", LONG), - ("bmWidthBytes", LONG), - ("bmPlanes", WORD), - ("bmBitsPixel", WORD), - ("bmBits", LPVOID), + ("bmType", LONG), + ("bmWidth", LONG), + ("bmHeight", LONG), + ("bmWidthBytes", LONG), + ("bmPlanes", WORD), + ("bmBitsPixel", WORD), + ("bmBits", LPVOID), ] -PBITMAP = POINTER(BITMAP) + + +PBITMAP = POINTER(BITMAP) LPBITMAP = PBITMAP -#--- High level classes ------------------------------------------------------- +# --- High level classes ------------------------------------------------------- + +# --- gdi32.dll ---------------------------------------------------------------- -#--- gdi32.dll ---------------------------------------------------------------- # HDC GetDC( # __in HWND hWnd @@ -363,20 +373,22 @@ class BITMAP(Structure): def GetDC(hWnd): _GetDC = windll.gdi32.GetDC _GetDC.argtypes = [HWND] - _GetDC.restype = HDC + _GetDC.restype = HDC _GetDC.errcheck = RaiseIfZero return _GetDC(hWnd) + # HDC GetWindowDC( # __in HWND hWnd # ); def GetWindowDC(hWnd): _GetWindowDC = windll.gdi32.GetWindowDC _GetWindowDC.argtypes = [HWND] - _GetWindowDC.restype = HDC + _GetWindowDC.restype = HDC _GetWindowDC.errcheck = RaiseIfZero return _GetWindowDC(hWnd) + # int ReleaseDC( # __in HWND hWnd, # __in HDC hDC @@ -384,10 +396,11 @@ def GetWindowDC(hWnd): def ReleaseDC(hWnd, hDC): _ReleaseDC = windll.gdi32.ReleaseDC _ReleaseDC.argtypes = [HWND, HDC] - _ReleaseDC.restype = ctypes.c_int + _ReleaseDC.restype = ctypes.c_int _ReleaseDC.errcheck = RaiseIfZero _ReleaseDC(hWnd, hDC) + # HGDIOBJ SelectObject( # __in HDC hdc, # __in HGDIOBJ hgdiobj @@ -395,39 +408,42 @@ def ReleaseDC(hWnd, hDC): def SelectObject(hdc, hgdiobj): _SelectObject = windll.gdi32.SelectObject _SelectObject.argtypes = [HDC, HGDIOBJ] - _SelectObject.restype = HGDIOBJ + _SelectObject.restype = HGDIOBJ _SelectObject.errcheck = RaiseIfZero return _SelectObject(hdc, hgdiobj) + # HGDIOBJ GetStockObject( # __in int fnObject # ); def GetStockObject(fnObject): _GetStockObject = windll.gdi32.GetStockObject _GetStockObject.argtypes = [ctypes.c_int] - _GetStockObject.restype = HGDIOBJ + _GetStockObject.restype = HGDIOBJ _GetStockObject.errcheck = RaiseIfZero return _GetStockObject(fnObject) + # DWORD GetObjectType( # __in HGDIOBJ h # ); def GetObjectType(h): _GetObjectType = windll.gdi32.GetObjectType _GetObjectType.argtypes = [HGDIOBJ] - _GetObjectType.restype = DWORD + _GetObjectType.restype = DWORD _GetObjectType.errcheck = RaiseIfZero return _GetObjectType(h) + # int GetObject( # __in HGDIOBJ hgdiobj, # __in int cbBuffer, # __out LPVOID lpvObject # ); -def GetObject(hgdiobj, cbBuffer = None, lpvObject = None): +def GetObject(hgdiobj, cbBuffer=None, lpvObject=None): _GetObject = windll.gdi32.GetObject _GetObject.argtypes = [HGDIOBJ, ctypes.c_int, LPVOID] - _GetObject.restype = ctypes.c_int + _GetObject.restype = ctypes.c_int _GetObject.errcheck = RaiseIfZero # Both cbBuffer and lpvObject can be omitted, the correct @@ -440,38 +456,39 @@ def GetObject(hgdiobj, cbBuffer = None, lpvObject = None): lpvObject = ctypes.create_string_buffer("", cbBuffer) elif lpvObject is not None: cbBuffer = sizeof(lpvObject) - else: # most likely case, both are None + else: # most likely case, both are None t = GetObjectType(hgdiobj) - if t == OBJ_PEN: - cbBuffer = sizeof(LOGPEN) + if t == OBJ_PEN: + cbBuffer = sizeof(LOGPEN) lpvObject = LOGPEN() elif t == OBJ_BRUSH: - cbBuffer = sizeof(LOGBRUSH) + cbBuffer = sizeof(LOGBRUSH) lpvObject = LOGBRUSH() elif t == OBJ_PAL: - cbBuffer = _GetObject(hgdiobj, 0, None) + cbBuffer = _GetObject(hgdiobj, 0, None) lpvObject = (WORD * (cbBuffer // sizeof(WORD)))() elif t == OBJ_FONT: - cbBuffer = sizeof(LOGFONT) + cbBuffer = sizeof(LOGFONT) lpvObject = LOGFONT() elif t == OBJ_BITMAP: # try the two possible types of bitmap - cbBuffer = sizeof(DIBSECTION) + cbBuffer = sizeof(DIBSECTION) lpvObject = DIBSECTION() try: _GetObject(hgdiobj, cbBuffer, byref(lpvObject)) return lpvObject except WindowsError: - cbBuffer = sizeof(BITMAP) + cbBuffer = sizeof(BITMAP) lpvObject = BITMAP() elif t == OBJ_EXTPEN: - cbBuffer = sizeof(LOGEXTPEN) + cbBuffer = sizeof(LOGEXTPEN) lpvObject = LOGEXTPEN() else: - cbBuffer = _GetObject(hgdiobj, 0, None) + cbBuffer = _GetObject(hgdiobj, 0, None) lpvObject = ctypes.create_string_buffer("", cbBuffer) _GetObject(hgdiobj, cbBuffer, byref(lpvObject)) return lpvObject + # LONG GetBitmapBits( # __in HBITMAP hbmp, # __in LONG cbBuffer, @@ -480,28 +497,30 @@ def GetObject(hgdiobj, cbBuffer = None, lpvObject = None): def GetBitmapBits(hbmp): _GetBitmapBits = windll.gdi32.GetBitmapBits _GetBitmapBits.argtypes = [HBITMAP, LONG, LPVOID] - _GetBitmapBits.restype = LONG + _GetBitmapBits.restype = LONG _GetBitmapBits.errcheck = RaiseIfZero - bitmap = GetObject(hbmp, lpvObject = BITMAP()) + bitmap = GetObject(hbmp, lpvObject=BITMAP()) cbBuffer = bitmap.bmWidthBytes * bitmap.bmHeight - lpvBits = ctypes.create_string_buffer("", cbBuffer) + lpvBits = ctypes.create_string_buffer("", cbBuffer) _GetBitmapBits(hbmp, cbBuffer, byref(lpvBits)) return lpvBits.raw + # HBITMAP CreateBitmapIndirect( # __in const BITMAP *lpbm # ); def CreateBitmapIndirect(lpbm): _CreateBitmapIndirect = windll.gdi32.CreateBitmapIndirect _CreateBitmapIndirect.argtypes = [PBITMAP] - _CreateBitmapIndirect.restype = HBITMAP + _CreateBitmapIndirect.restype = HBITMAP _CreateBitmapIndirect.errcheck = RaiseIfZero return _CreateBitmapIndirect(lpbm) -#============================================================================== + +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/kernel32.py b/pydevd_attach_to_process/winappdbg/win32/kernel32.py index d0c0468f6..013a7c205 100644 --- a/pydevd_attach_to_process/winappdbg/win32/kernel32.py +++ b/pydevd_attach_to_process/winappdbg/win32/kernel32.py @@ -41,19 +41,20 @@ from winappdbg.win32 import context_i386 from winappdbg.win32 import context_amd64 -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -_all.add('version') -#============================================================================== +_all.add("version") +# ============================================================================== from winappdbg.win32.version import * -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ + # This can't be defined in defines.py because it calls GetLastError(). -def RaiseIfLastError(result, func = None, arguments = ()): +def RaiseIfLastError(result, func=None, arguments=()): """ Error checking for Win32 API calls with no error-specific return value. @@ -69,11 +70,12 @@ def RaiseIfLastError(result, func = None, arguments = ()): raise ctypes.WinError(code) return result -#--- CONTEXT structure and constants ------------------------------------------ -ContextArchMask = 0x0FFF0000 # just guessing here! seems to work, though +# --- CONTEXT structure and constants ------------------------------------------ + +ContextArchMask = 0x0FFF0000 # just guessing here! seems to work, though -if arch == ARCH_I386: +if arch == ARCH_I386: from winappdbg.win32.context_i386 import * elif arch == ARCH_AMD64: if bits == 64: @@ -83,42 +85,42 @@ def RaiseIfLastError(result, func = None, arguments = ()): else: warnings.warn("Unknown or unsupported architecture: %s" % arch) -#--- Constants ---------------------------------------------------------------- +# --- Constants ---------------------------------------------------------------- STILL_ACTIVE = 259 -WAIT_TIMEOUT = 0x102 -WAIT_FAILED = -1 -WAIT_OBJECT_0 = 0 +WAIT_TIMEOUT = 0x102 +WAIT_FAILED = -1 +WAIT_OBJECT_0 = 0 -EXCEPTION_NONCONTINUABLE = 0x1 # Noncontinuable exception -EXCEPTION_MAXIMUM_PARAMETERS = 15 # maximum number of exception parameters -MAXIMUM_WAIT_OBJECTS = 64 # Maximum number of wait objects -MAXIMUM_SUSPEND_COUNT = 0x7f # Maximum times thread can be suspended +EXCEPTION_NONCONTINUABLE = 0x1 # Noncontinuable exception +EXCEPTION_MAXIMUM_PARAMETERS = 15 # maximum number of exception parameters +MAXIMUM_WAIT_OBJECTS = 64 # Maximum number of wait objects +MAXIMUM_SUSPEND_COUNT = 0x7F # Maximum times thread can be suspended -FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100 -FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000 +FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100 +FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000 -GR_GDIOBJECTS = 0 +GR_GDIOBJECTS = 0 GR_USEROBJECTS = 1 PROCESS_NAME_NATIVE = 1 MAXINTATOM = 0xC000 -STD_INPUT_HANDLE = 0xFFFFFFF6 # (DWORD)-10 -STD_OUTPUT_HANDLE = 0xFFFFFFF5 # (DWORD)-11 -STD_ERROR_HANDLE = 0xFFFFFFF4 # (DWORD)-12 +STD_INPUT_HANDLE = 0xFFFFFFF6 # (DWORD)-10 +STD_OUTPUT_HANDLE = 0xFFFFFFF5 # (DWORD)-11 +STD_ERROR_HANDLE = 0xFFFFFFF4 # (DWORD)-12 ATTACH_PARENT_PROCESS = 0xFFFFFFFF # (DWORD)-1 # LoadLibraryEx constants -DONT_RESOLVE_DLL_REFERENCES = 0x00000001 -LOAD_LIBRARY_AS_DATAFILE = 0x00000002 -LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008 -LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010 -LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020 -LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040 +DONT_RESOLVE_DLL_REFERENCES = 0x00000001 +LOAD_LIBRARY_AS_DATAFILE = 0x00000002 +LOAD_WITH_ALTERED_SEARCH_PATH = 0x00000008 +LOAD_IGNORE_CODE_AUTHZ_LEVEL = 0x00000010 +LOAD_LIBRARY_AS_IMAGE_RESOURCE = 0x00000020 +LOAD_LIBRARY_AS_DATAFILE_EXCLUSIVE = 0x00000040 # SetSearchPathMode flags # TODO I couldn't find these constants :( @@ -127,82 +129,82 @@ def RaiseIfLastError(result, func = None, arguments = ()): ##BASE_SEARCH_PATH_PERMANENT = ??? # Console control events -CTRL_C_EVENT = 0 -CTRL_BREAK_EVENT = 1 -CTRL_CLOSE_EVENT = 2 -CTRL_LOGOFF_EVENT = 5 +CTRL_C_EVENT = 0 +CTRL_BREAK_EVENT = 1 +CTRL_CLOSE_EVENT = 2 +CTRL_LOGOFF_EVENT = 5 CTRL_SHUTDOWN_EVENT = 6 # Heap flags -HEAP_NO_SERIALIZE = 0x00000001 -HEAP_GENERATE_EXCEPTIONS = 0x00000004 -HEAP_ZERO_MEMORY = 0x00000008 -HEAP_CREATE_ENABLE_EXECUTE = 0x00040000 +HEAP_NO_SERIALIZE = 0x00000001 +HEAP_GENERATE_EXCEPTIONS = 0x00000004 +HEAP_ZERO_MEMORY = 0x00000008 +HEAP_CREATE_ENABLE_EXECUTE = 0x00040000 # Standard access rights -DELETE = long(0x00010000) -READ_CONTROL = long(0x00020000) -WRITE_DAC = long(0x00040000) -WRITE_OWNER = long(0x00080000) -SYNCHRONIZE = long(0x00100000) -STANDARD_RIGHTS_REQUIRED = long(0x000F0000) -STANDARD_RIGHTS_READ = (READ_CONTROL) -STANDARD_RIGHTS_WRITE = (READ_CONTROL) -STANDARD_RIGHTS_EXECUTE = (READ_CONTROL) -STANDARD_RIGHTS_ALL = long(0x001F0000) -SPECIFIC_RIGHTS_ALL = long(0x0000FFFF) +DELETE = long(0x00010000) +READ_CONTROL = long(0x00020000) +WRITE_DAC = long(0x00040000) +WRITE_OWNER = long(0x00080000) +SYNCHRONIZE = long(0x00100000) +STANDARD_RIGHTS_REQUIRED = long(0x000F0000) +STANDARD_RIGHTS_READ = READ_CONTROL +STANDARD_RIGHTS_WRITE = READ_CONTROL +STANDARD_RIGHTS_EXECUTE = READ_CONTROL +STANDARD_RIGHTS_ALL = long(0x001F0000) +SPECIFIC_RIGHTS_ALL = long(0x0000FFFF) # Mutex access rights -MUTEX_ALL_ACCESS = 0x1F0001 +MUTEX_ALL_ACCESS = 0x1F0001 MUTEX_MODIFY_STATE = 1 # Event access rights -EVENT_ALL_ACCESS = 0x1F0003 +EVENT_ALL_ACCESS = 0x1F0003 EVENT_MODIFY_STATE = 2 # Semaphore access rights -SEMAPHORE_ALL_ACCESS = 0x1F0003 +SEMAPHORE_ALL_ACCESS = 0x1F0003 SEMAPHORE_MODIFY_STATE = 2 # Timer access rights -TIMER_ALL_ACCESS = 0x1F0003 +TIMER_ALL_ACCESS = 0x1F0003 TIMER_MODIFY_STATE = 2 -TIMER_QUERY_STATE = 1 +TIMER_QUERY_STATE = 1 # Process access rights for OpenProcess -PROCESS_TERMINATE = 0x0001 -PROCESS_CREATE_THREAD = 0x0002 -PROCESS_SET_SESSIONID = 0x0004 -PROCESS_VM_OPERATION = 0x0008 -PROCESS_VM_READ = 0x0010 -PROCESS_VM_WRITE = 0x0020 -PROCESS_DUP_HANDLE = 0x0040 -PROCESS_CREATE_PROCESS = 0x0080 -PROCESS_SET_QUOTA = 0x0100 -PROCESS_SET_INFORMATION = 0x0200 -PROCESS_QUERY_INFORMATION = 0x0400 -PROCESS_SUSPEND_RESUME = 0x0800 +PROCESS_TERMINATE = 0x0001 +PROCESS_CREATE_THREAD = 0x0002 +PROCESS_SET_SESSIONID = 0x0004 +PROCESS_VM_OPERATION = 0x0008 +PROCESS_VM_READ = 0x0010 +PROCESS_VM_WRITE = 0x0020 +PROCESS_DUP_HANDLE = 0x0040 +PROCESS_CREATE_PROCESS = 0x0080 +PROCESS_SET_QUOTA = 0x0100 +PROCESS_SET_INFORMATION = 0x0200 +PROCESS_QUERY_INFORMATION = 0x0400 +PROCESS_SUSPEND_RESUME = 0x0800 PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 # Thread access rights for OpenThread -THREAD_TERMINATE = 0x0001 -THREAD_SUSPEND_RESUME = 0x0002 -THREAD_ALERT = 0x0004 -THREAD_GET_CONTEXT = 0x0008 -THREAD_SET_CONTEXT = 0x0010 -THREAD_SET_INFORMATION = 0x0020 -THREAD_QUERY_INFORMATION = 0x0040 -THREAD_SET_THREAD_TOKEN = 0x0080 -THREAD_IMPERSONATE = 0x0100 -THREAD_DIRECT_IMPERSONATION = 0x0200 -THREAD_SET_LIMITED_INFORMATION = 0x0400 +THREAD_TERMINATE = 0x0001 +THREAD_SUSPEND_RESUME = 0x0002 +THREAD_ALERT = 0x0004 +THREAD_GET_CONTEXT = 0x0008 +THREAD_SET_CONTEXT = 0x0010 +THREAD_SET_INFORMATION = 0x0020 +THREAD_QUERY_INFORMATION = 0x0040 +THREAD_SET_THREAD_TOKEN = 0x0080 +THREAD_IMPERSONATE = 0x0100 +THREAD_DIRECT_IMPERSONATION = 0x0200 +THREAD_SET_LIMITED_INFORMATION = 0x0400 THREAD_QUERY_LIMITED_INFORMATION = 0x0800 # The values of PROCESS_ALL_ACCESS and THREAD_ALL_ACCESS were changed in Vista/2008 -PROCESS_ALL_ACCESS_NT = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF) -PROCESS_ALL_ACCESS_VISTA = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF) -THREAD_ALL_ACCESS_NT = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3FF) -THREAD_ALL_ACCESS_VISTA = (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF) +PROCESS_ALL_ACCESS_NT = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFF +PROCESS_ALL_ACCESS_VISTA = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF +THREAD_ALL_ACCESS_NT = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x3FF +THREAD_ALL_ACCESS_VISTA = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xFFFF if NTDDI_VERSION < NTDDI_VISTA: PROCESS_ALL_ACCESS = PROCESS_ALL_ACCESS_NT THREAD_ALL_ACCESS = THREAD_ALL_ACCESS_NT @@ -212,295 +214,291 @@ def RaiseIfLastError(result, func = None, arguments = ()): # Process priority classes -IDLE_PRIORITY_CLASS = 0x00000040 +IDLE_PRIORITY_CLASS = 0x00000040 BELOW_NORMAL_PRIORITY_CLASS = 0x00004000 -NORMAL_PRIORITY_CLASS = 0x00000020 +NORMAL_PRIORITY_CLASS = 0x00000020 ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000 -HIGH_PRIORITY_CLASS = 0x00000080 -REALTIME_PRIORITY_CLASS = 0x00000100 +HIGH_PRIORITY_CLASS = 0x00000080 +REALTIME_PRIORITY_CLASS = 0x00000100 -PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000 -PROCESS_MODE_BACKGROUND_END = 0x00200000 +PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000 +PROCESS_MODE_BACKGROUND_END = 0x00200000 # dwCreationFlag values -DEBUG_PROCESS = 0x00000001 -DEBUG_ONLY_THIS_PROCESS = 0x00000002 -CREATE_SUSPENDED = 0x00000004 # Threads and processes -DETACHED_PROCESS = 0x00000008 -CREATE_NEW_CONSOLE = 0x00000010 -NORMAL_PRIORITY_CLASS = 0x00000020 -IDLE_PRIORITY_CLASS = 0x00000040 -HIGH_PRIORITY_CLASS = 0x00000080 -REALTIME_PRIORITY_CLASS = 0x00000100 -CREATE_NEW_PROCESS_GROUP = 0x00000200 -CREATE_UNICODE_ENVIRONMENT = 0x00000400 -CREATE_SEPARATE_WOW_VDM = 0x00000800 -CREATE_SHARED_WOW_VDM = 0x00001000 -CREATE_FORCEDOS = 0x00002000 -BELOW_NORMAL_PRIORITY_CLASS = 0x00004000 -ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000 -INHERIT_PARENT_AFFINITY = 0x00010000 -STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000 # Threads only -INHERIT_CALLER_PRIORITY = 0x00020000 # Deprecated -CREATE_PROTECTED_PROCESS = 0x00040000 -EXTENDED_STARTUPINFO_PRESENT = 0x00080000 -PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000 -PROCESS_MODE_BACKGROUND_END = 0x00200000 -CREATE_BREAKAWAY_FROM_JOB = 0x01000000 -CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 -CREATE_DEFAULT_ERROR_MODE = 0x04000000 -CREATE_NO_WINDOW = 0x08000000 -PROFILE_USER = 0x10000000 -PROFILE_KERNEL = 0x20000000 -PROFILE_SERVER = 0x40000000 -CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000 +DEBUG_PROCESS = 0x00000001 +DEBUG_ONLY_THIS_PROCESS = 0x00000002 +CREATE_SUSPENDED = 0x00000004 # Threads and processes +DETACHED_PROCESS = 0x00000008 +CREATE_NEW_CONSOLE = 0x00000010 +NORMAL_PRIORITY_CLASS = 0x00000020 +IDLE_PRIORITY_CLASS = 0x00000040 +HIGH_PRIORITY_CLASS = 0x00000080 +REALTIME_PRIORITY_CLASS = 0x00000100 +CREATE_NEW_PROCESS_GROUP = 0x00000200 +CREATE_UNICODE_ENVIRONMENT = 0x00000400 +CREATE_SEPARATE_WOW_VDM = 0x00000800 +CREATE_SHARED_WOW_VDM = 0x00001000 +CREATE_FORCEDOS = 0x00002000 +BELOW_NORMAL_PRIORITY_CLASS = 0x00004000 +ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000 +INHERIT_PARENT_AFFINITY = 0x00010000 +STACK_SIZE_PARAM_IS_A_RESERVATION = 0x00010000 # Threads only +INHERIT_CALLER_PRIORITY = 0x00020000 # Deprecated +CREATE_PROTECTED_PROCESS = 0x00040000 +EXTENDED_STARTUPINFO_PRESENT = 0x00080000 +PROCESS_MODE_BACKGROUND_BEGIN = 0x00100000 +PROCESS_MODE_BACKGROUND_END = 0x00200000 +CREATE_BREAKAWAY_FROM_JOB = 0x01000000 +CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 +CREATE_DEFAULT_ERROR_MODE = 0x04000000 +CREATE_NO_WINDOW = 0x08000000 +PROFILE_USER = 0x10000000 +PROFILE_KERNEL = 0x20000000 +PROFILE_SERVER = 0x40000000 +CREATE_IGNORE_SYSTEM_DEFAULT = 0x80000000 # Thread priority values -THREAD_BASE_PRIORITY_LOWRT = 15 # value that gets a thread to LowRealtime-1 -THREAD_BASE_PRIORITY_MAX = 2 # maximum thread base priority boost -THREAD_BASE_PRIORITY_MIN = (-2) # minimum thread base priority boost -THREAD_BASE_PRIORITY_IDLE = (-15) # value that gets a thread to idle +THREAD_BASE_PRIORITY_LOWRT = 15 # value that gets a thread to LowRealtime-1 +THREAD_BASE_PRIORITY_MAX = 2 # maximum thread base priority boost +THREAD_BASE_PRIORITY_MIN = -2 # minimum thread base priority boost +THREAD_BASE_PRIORITY_IDLE = -15 # value that gets a thread to idle -THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN -THREAD_PRIORITY_BELOW_NORMAL = (THREAD_PRIORITY_LOWEST+1) -THREAD_PRIORITY_NORMAL = 0 -THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX -THREAD_PRIORITY_ABOVE_NORMAL = (THREAD_PRIORITY_HIGHEST-1) -THREAD_PRIORITY_ERROR_RETURN = long(0xFFFFFFFF) +THREAD_PRIORITY_LOWEST = THREAD_BASE_PRIORITY_MIN +THREAD_PRIORITY_BELOW_NORMAL = THREAD_PRIORITY_LOWEST + 1 +THREAD_PRIORITY_NORMAL = 0 +THREAD_PRIORITY_HIGHEST = THREAD_BASE_PRIORITY_MAX +THREAD_PRIORITY_ABOVE_NORMAL = THREAD_PRIORITY_HIGHEST - 1 +THREAD_PRIORITY_ERROR_RETURN = long(0xFFFFFFFF) -THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT -THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE +THREAD_PRIORITY_TIME_CRITICAL = THREAD_BASE_PRIORITY_LOWRT +THREAD_PRIORITY_IDLE = THREAD_BASE_PRIORITY_IDLE # Memory access -SECTION_QUERY = 0x0001 -SECTION_MAP_WRITE = 0x0002 -SECTION_MAP_READ = 0x0004 -SECTION_MAP_EXECUTE = 0x0008 -SECTION_EXTEND_SIZE = 0x0010 -SECTION_MAP_EXECUTE_EXPLICIT = 0x0020 # not included in SECTION_ALL_ACCESS - -SECTION_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|\ - SECTION_MAP_WRITE | \ - SECTION_MAP_READ | \ - SECTION_MAP_EXECUTE | \ - SECTION_EXTEND_SIZE) -PAGE_NOACCESS = 0x01 -PAGE_READONLY = 0x02 -PAGE_READWRITE = 0x04 -PAGE_WRITECOPY = 0x08 -PAGE_EXECUTE = 0x10 -PAGE_EXECUTE_READ = 0x20 +SECTION_QUERY = 0x0001 +SECTION_MAP_WRITE = 0x0002 +SECTION_MAP_READ = 0x0004 +SECTION_MAP_EXECUTE = 0x0008 +SECTION_EXTEND_SIZE = 0x0010 +SECTION_MAP_EXECUTE_EXPLICIT = 0x0020 # not included in SECTION_ALL_ACCESS + +SECTION_ALL_ACCESS = ( + STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE +) +PAGE_NOACCESS = 0x01 +PAGE_READONLY = 0x02 +PAGE_READWRITE = 0x04 +PAGE_WRITECOPY = 0x08 +PAGE_EXECUTE = 0x10 +PAGE_EXECUTE_READ = 0x20 PAGE_EXECUTE_READWRITE = 0x40 PAGE_EXECUTE_WRITECOPY = 0x80 -PAGE_GUARD = 0x100 -PAGE_NOCACHE = 0x200 -PAGE_WRITECOMBINE = 0x400 -MEM_COMMIT = 0x1000 -MEM_RESERVE = 0x2000 -MEM_DECOMMIT = 0x4000 -MEM_RELEASE = 0x8000 -MEM_FREE = 0x10000 -MEM_PRIVATE = 0x20000 -MEM_MAPPED = 0x40000 -MEM_RESET = 0x80000 -MEM_TOP_DOWN = 0x100000 -MEM_WRITE_WATCH = 0x200000 -MEM_PHYSICAL = 0x400000 -MEM_LARGE_PAGES = 0x20000000 -MEM_4MB_PAGES = 0x80000000 -SEC_FILE = 0x800000 -SEC_IMAGE = 0x1000000 -SEC_RESERVE = 0x4000000 -SEC_COMMIT = 0x8000000 -SEC_NOCACHE = 0x10000000 -SEC_LARGE_PAGES = 0x80000000 -MEM_IMAGE = SEC_IMAGE +PAGE_GUARD = 0x100 +PAGE_NOCACHE = 0x200 +PAGE_WRITECOMBINE = 0x400 +MEM_COMMIT = 0x1000 +MEM_RESERVE = 0x2000 +MEM_DECOMMIT = 0x4000 +MEM_RELEASE = 0x8000 +MEM_FREE = 0x10000 +MEM_PRIVATE = 0x20000 +MEM_MAPPED = 0x40000 +MEM_RESET = 0x80000 +MEM_TOP_DOWN = 0x100000 +MEM_WRITE_WATCH = 0x200000 +MEM_PHYSICAL = 0x400000 +MEM_LARGE_PAGES = 0x20000000 +MEM_4MB_PAGES = 0x80000000 +SEC_FILE = 0x800000 +SEC_IMAGE = 0x1000000 +SEC_RESERVE = 0x4000000 +SEC_COMMIT = 0x8000000 +SEC_NOCACHE = 0x10000000 +SEC_LARGE_PAGES = 0x80000000 +MEM_IMAGE = SEC_IMAGE WRITE_WATCH_FLAG_RESET = 0x01 FILE_MAP_ALL_ACCESS = 0xF001F -SECTION_QUERY = 0x0001 -SECTION_MAP_WRITE = 0x0002 -SECTION_MAP_READ = 0x0004 -SECTION_MAP_EXECUTE = 0x0008 -SECTION_EXTEND_SIZE = 0x0010 -SECTION_MAP_EXECUTE_EXPLICIT = 0x0020 # not included in SECTION_ALL_ACCESS - -SECTION_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED|SECTION_QUERY|\ - SECTION_MAP_WRITE | \ - SECTION_MAP_READ | \ - SECTION_MAP_EXECUTE | \ - SECTION_EXTEND_SIZE) - -FILE_MAP_COPY = SECTION_QUERY -FILE_MAP_WRITE = SECTION_MAP_WRITE -FILE_MAP_READ = SECTION_MAP_READ +SECTION_QUERY = 0x0001 +SECTION_MAP_WRITE = 0x0002 +SECTION_MAP_READ = 0x0004 +SECTION_MAP_EXECUTE = 0x0008 +SECTION_EXTEND_SIZE = 0x0010 +SECTION_MAP_EXECUTE_EXPLICIT = 0x0020 # not included in SECTION_ALL_ACCESS + +SECTION_ALL_ACCESS = ( + STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_WRITE | SECTION_MAP_READ | SECTION_MAP_EXECUTE | SECTION_EXTEND_SIZE +) + +FILE_MAP_COPY = SECTION_QUERY +FILE_MAP_WRITE = SECTION_MAP_WRITE +FILE_MAP_READ = SECTION_MAP_READ FILE_MAP_ALL_ACCESS = SECTION_ALL_ACCESS -FILE_MAP_EXECUTE = SECTION_MAP_EXECUTE_EXPLICIT # not included in FILE_MAP_ALL_ACCESS - -GENERIC_READ = 0x80000000 -GENERIC_WRITE = 0x40000000 -GENERIC_EXECUTE = 0x20000000 -GENERIC_ALL = 0x10000000 - -FILE_SHARE_READ = 0x00000001 -FILE_SHARE_WRITE = 0x00000002 -FILE_SHARE_DELETE = 0x00000004 - -CREATE_NEW = 1 -CREATE_ALWAYS = 2 -OPEN_EXISTING = 3 -OPEN_ALWAYS = 4 -TRUNCATE_EXISTING = 5 - -FILE_ATTRIBUTE_READONLY = 0x00000001 -FILE_ATTRIBUTE_NORMAL = 0x00000080 -FILE_ATTRIBUTE_TEMPORARY = 0x00000100 - -FILE_FLAG_WRITE_THROUGH = 0x80000000 -FILE_FLAG_NO_BUFFERING = 0x20000000 -FILE_FLAG_RANDOM_ACCESS = 0x10000000 -FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000 -FILE_FLAG_DELETE_ON_CLOSE = 0x04000000 -FILE_FLAG_OVERLAPPED = 0x40000000 - -FILE_ATTRIBUTE_READONLY = 0x00000001 -FILE_ATTRIBUTE_HIDDEN = 0x00000002 -FILE_ATTRIBUTE_SYSTEM = 0x00000004 -FILE_ATTRIBUTE_DIRECTORY = 0x00000010 -FILE_ATTRIBUTE_ARCHIVE = 0x00000020 -FILE_ATTRIBUTE_DEVICE = 0x00000040 -FILE_ATTRIBUTE_NORMAL = 0x00000080 -FILE_ATTRIBUTE_TEMPORARY = 0x00000100 +FILE_MAP_EXECUTE = SECTION_MAP_EXECUTE_EXPLICIT # not included in FILE_MAP_ALL_ACCESS + +GENERIC_READ = 0x80000000 +GENERIC_WRITE = 0x40000000 +GENERIC_EXECUTE = 0x20000000 +GENERIC_ALL = 0x10000000 + +FILE_SHARE_READ = 0x00000001 +FILE_SHARE_WRITE = 0x00000002 +FILE_SHARE_DELETE = 0x00000004 + +CREATE_NEW = 1 +CREATE_ALWAYS = 2 +OPEN_EXISTING = 3 +OPEN_ALWAYS = 4 +TRUNCATE_EXISTING = 5 + +FILE_ATTRIBUTE_READONLY = 0x00000001 +FILE_ATTRIBUTE_NORMAL = 0x00000080 +FILE_ATTRIBUTE_TEMPORARY = 0x00000100 + +FILE_FLAG_WRITE_THROUGH = 0x80000000 +FILE_FLAG_NO_BUFFERING = 0x20000000 +FILE_FLAG_RANDOM_ACCESS = 0x10000000 +FILE_FLAG_SEQUENTIAL_SCAN = 0x08000000 +FILE_FLAG_DELETE_ON_CLOSE = 0x04000000 +FILE_FLAG_OVERLAPPED = 0x40000000 + +FILE_ATTRIBUTE_READONLY = 0x00000001 +FILE_ATTRIBUTE_HIDDEN = 0x00000002 +FILE_ATTRIBUTE_SYSTEM = 0x00000004 +FILE_ATTRIBUTE_DIRECTORY = 0x00000010 +FILE_ATTRIBUTE_ARCHIVE = 0x00000020 +FILE_ATTRIBUTE_DEVICE = 0x00000040 +FILE_ATTRIBUTE_NORMAL = 0x00000080 +FILE_ATTRIBUTE_TEMPORARY = 0x00000100 # Debug events -EXCEPTION_DEBUG_EVENT = 1 -CREATE_THREAD_DEBUG_EVENT = 2 -CREATE_PROCESS_DEBUG_EVENT = 3 -EXIT_THREAD_DEBUG_EVENT = 4 -EXIT_PROCESS_DEBUG_EVENT = 5 -LOAD_DLL_DEBUG_EVENT = 6 -UNLOAD_DLL_DEBUG_EVENT = 7 -OUTPUT_DEBUG_STRING_EVENT = 8 -RIP_EVENT = 9 +EXCEPTION_DEBUG_EVENT = 1 +CREATE_THREAD_DEBUG_EVENT = 2 +CREATE_PROCESS_DEBUG_EVENT = 3 +EXIT_THREAD_DEBUG_EVENT = 4 +EXIT_PROCESS_DEBUG_EVENT = 5 +LOAD_DLL_DEBUG_EVENT = 6 +UNLOAD_DLL_DEBUG_EVENT = 7 +OUTPUT_DEBUG_STRING_EVENT = 8 +RIP_EVENT = 9 # Debug status codes (ContinueDebugEvent) -DBG_EXCEPTION_HANDLED = long(0x00010001) -DBG_CONTINUE = long(0x00010002) -DBG_REPLY_LATER = long(0x40010001) -DBG_UNABLE_TO_PROVIDE_HANDLE = long(0x40010002) -DBG_TERMINATE_THREAD = long(0x40010003) -DBG_TERMINATE_PROCESS = long(0x40010004) -DBG_CONTROL_C = long(0x40010005) -DBG_PRINTEXCEPTION_C = long(0x40010006) -DBG_RIPEXCEPTION = long(0x40010007) -DBG_CONTROL_BREAK = long(0x40010008) -DBG_COMMAND_EXCEPTION = long(0x40010009) -DBG_EXCEPTION_NOT_HANDLED = long(0x80010001) -DBG_NO_STATE_CHANGE = long(0xC0010001) -DBG_APP_NOT_IDLE = long(0xC0010002) +DBG_EXCEPTION_HANDLED = long(0x00010001) +DBG_CONTINUE = long(0x00010002) +DBG_REPLY_LATER = long(0x40010001) +DBG_UNABLE_TO_PROVIDE_HANDLE = long(0x40010002) +DBG_TERMINATE_THREAD = long(0x40010003) +DBG_TERMINATE_PROCESS = long(0x40010004) +DBG_CONTROL_C = long(0x40010005) +DBG_PRINTEXCEPTION_C = long(0x40010006) +DBG_RIPEXCEPTION = long(0x40010007) +DBG_CONTROL_BREAK = long(0x40010008) +DBG_COMMAND_EXCEPTION = long(0x40010009) +DBG_EXCEPTION_NOT_HANDLED = long(0x80010001) +DBG_NO_STATE_CHANGE = long(0xC0010001) +DBG_APP_NOT_IDLE = long(0xC0010002) # Status codes -STATUS_WAIT_0 = long(0x00000000) -STATUS_ABANDONED_WAIT_0 = long(0x00000080) -STATUS_USER_APC = long(0x000000C0) -STATUS_TIMEOUT = long(0x00000102) -STATUS_PENDING = long(0x00000103) -STATUS_SEGMENT_NOTIFICATION = long(0x40000005) -STATUS_GUARD_PAGE_VIOLATION = long(0x80000001) -STATUS_DATATYPE_MISALIGNMENT = long(0x80000002) -STATUS_BREAKPOINT = long(0x80000003) -STATUS_SINGLE_STEP = long(0x80000004) -STATUS_INVALID_INFO_CLASS = long(0xC0000003) -STATUS_ACCESS_VIOLATION = long(0xC0000005) -STATUS_IN_PAGE_ERROR = long(0xC0000006) -STATUS_INVALID_HANDLE = long(0xC0000008) -STATUS_NO_MEMORY = long(0xC0000017) -STATUS_ILLEGAL_INSTRUCTION = long(0xC000001D) +STATUS_WAIT_0 = long(0x00000000) +STATUS_ABANDONED_WAIT_0 = long(0x00000080) +STATUS_USER_APC = long(0x000000C0) +STATUS_TIMEOUT = long(0x00000102) +STATUS_PENDING = long(0x00000103) +STATUS_SEGMENT_NOTIFICATION = long(0x40000005) +STATUS_GUARD_PAGE_VIOLATION = long(0x80000001) +STATUS_DATATYPE_MISALIGNMENT = long(0x80000002) +STATUS_BREAKPOINT = long(0x80000003) +STATUS_SINGLE_STEP = long(0x80000004) +STATUS_INVALID_INFO_CLASS = long(0xC0000003) +STATUS_ACCESS_VIOLATION = long(0xC0000005) +STATUS_IN_PAGE_ERROR = long(0xC0000006) +STATUS_INVALID_HANDLE = long(0xC0000008) +STATUS_NO_MEMORY = long(0xC0000017) +STATUS_ILLEGAL_INSTRUCTION = long(0xC000001D) STATUS_NONCONTINUABLE_EXCEPTION = long(0xC0000025) -STATUS_INVALID_DISPOSITION = long(0xC0000026) -STATUS_ARRAY_BOUNDS_EXCEEDED = long(0xC000008C) -STATUS_FLOAT_DENORMAL_OPERAND = long(0xC000008D) -STATUS_FLOAT_DIVIDE_BY_ZERO = long(0xC000008E) -STATUS_FLOAT_INEXACT_RESULT = long(0xC000008F) -STATUS_FLOAT_INVALID_OPERATION = long(0xC0000090) -STATUS_FLOAT_OVERFLOW = long(0xC0000091) -STATUS_FLOAT_STACK_CHECK = long(0xC0000092) -STATUS_FLOAT_UNDERFLOW = long(0xC0000093) -STATUS_INTEGER_DIVIDE_BY_ZERO = long(0xC0000094) -STATUS_INTEGER_OVERFLOW = long(0xC0000095) -STATUS_PRIVILEGED_INSTRUCTION = long(0xC0000096) -STATUS_STACK_OVERFLOW = long(0xC00000FD) -STATUS_CONTROL_C_EXIT = long(0xC000013A) -STATUS_FLOAT_MULTIPLE_FAULTS = long(0xC00002B4) -STATUS_FLOAT_MULTIPLE_TRAPS = long(0xC00002B5) -STATUS_REG_NAT_CONSUMPTION = long(0xC00002C9) -STATUS_SXS_EARLY_DEACTIVATION = long(0xC015000F) +STATUS_INVALID_DISPOSITION = long(0xC0000026) +STATUS_ARRAY_BOUNDS_EXCEEDED = long(0xC000008C) +STATUS_FLOAT_DENORMAL_OPERAND = long(0xC000008D) +STATUS_FLOAT_DIVIDE_BY_ZERO = long(0xC000008E) +STATUS_FLOAT_INEXACT_RESULT = long(0xC000008F) +STATUS_FLOAT_INVALID_OPERATION = long(0xC0000090) +STATUS_FLOAT_OVERFLOW = long(0xC0000091) +STATUS_FLOAT_STACK_CHECK = long(0xC0000092) +STATUS_FLOAT_UNDERFLOW = long(0xC0000093) +STATUS_INTEGER_DIVIDE_BY_ZERO = long(0xC0000094) +STATUS_INTEGER_OVERFLOW = long(0xC0000095) +STATUS_PRIVILEGED_INSTRUCTION = long(0xC0000096) +STATUS_STACK_OVERFLOW = long(0xC00000FD) +STATUS_CONTROL_C_EXIT = long(0xC000013A) +STATUS_FLOAT_MULTIPLE_FAULTS = long(0xC00002B4) +STATUS_FLOAT_MULTIPLE_TRAPS = long(0xC00002B5) +STATUS_REG_NAT_CONSUMPTION = long(0xC00002C9) +STATUS_SXS_EARLY_DEACTIVATION = long(0xC015000F) STATUS_SXS_INVALID_DEACTIVATION = long(0xC0150010) -STATUS_STACK_BUFFER_OVERRUN = long(0xC0000409) -STATUS_WX86_BREAKPOINT = long(0x4000001F) -STATUS_HEAP_CORRUPTION = long(0xC0000374) +STATUS_STACK_BUFFER_OVERRUN = long(0xC0000409) +STATUS_WX86_BREAKPOINT = long(0x4000001F) +STATUS_HEAP_CORRUPTION = long(0xC0000374) -STATUS_POSSIBLE_DEADLOCK = long(0xC0000194) +STATUS_POSSIBLE_DEADLOCK = long(0xC0000194) -STATUS_UNWIND_CONSOLIDATE = long(0x80000029) +STATUS_UNWIND_CONSOLIDATE = long(0x80000029) # Exception codes -EXCEPTION_ACCESS_VIOLATION = STATUS_ACCESS_VIOLATION -EXCEPTION_ARRAY_BOUNDS_EXCEEDED = STATUS_ARRAY_BOUNDS_EXCEEDED -EXCEPTION_BREAKPOINT = STATUS_BREAKPOINT -EXCEPTION_DATATYPE_MISALIGNMENT = STATUS_DATATYPE_MISALIGNMENT -EXCEPTION_FLT_DENORMAL_OPERAND = STATUS_FLOAT_DENORMAL_OPERAND -EXCEPTION_FLT_DIVIDE_BY_ZERO = STATUS_FLOAT_DIVIDE_BY_ZERO -EXCEPTION_FLT_INEXACT_RESULT = STATUS_FLOAT_INEXACT_RESULT -EXCEPTION_FLT_INVALID_OPERATION = STATUS_FLOAT_INVALID_OPERATION -EXCEPTION_FLT_OVERFLOW = STATUS_FLOAT_OVERFLOW -EXCEPTION_FLT_STACK_CHECK = STATUS_FLOAT_STACK_CHECK -EXCEPTION_FLT_UNDERFLOW = STATUS_FLOAT_UNDERFLOW -EXCEPTION_ILLEGAL_INSTRUCTION = STATUS_ILLEGAL_INSTRUCTION -EXCEPTION_IN_PAGE_ERROR = STATUS_IN_PAGE_ERROR -EXCEPTION_INT_DIVIDE_BY_ZERO = STATUS_INTEGER_DIVIDE_BY_ZERO -EXCEPTION_INT_OVERFLOW = STATUS_INTEGER_OVERFLOW -EXCEPTION_INVALID_DISPOSITION = STATUS_INVALID_DISPOSITION -EXCEPTION_NONCONTINUABLE_EXCEPTION = STATUS_NONCONTINUABLE_EXCEPTION -EXCEPTION_PRIV_INSTRUCTION = STATUS_PRIVILEGED_INSTRUCTION -EXCEPTION_SINGLE_STEP = STATUS_SINGLE_STEP -EXCEPTION_STACK_OVERFLOW = STATUS_STACK_OVERFLOW - -EXCEPTION_GUARD_PAGE = STATUS_GUARD_PAGE_VIOLATION -EXCEPTION_INVALID_HANDLE = STATUS_INVALID_HANDLE -EXCEPTION_POSSIBLE_DEADLOCK = STATUS_POSSIBLE_DEADLOCK -EXCEPTION_WX86_BREAKPOINT = STATUS_WX86_BREAKPOINT - -CONTROL_C_EXIT = STATUS_CONTROL_C_EXIT - -DBG_CONTROL_C = long(0x40010005) -MS_VC_EXCEPTION = long(0x406D1388) +EXCEPTION_ACCESS_VIOLATION = STATUS_ACCESS_VIOLATION +EXCEPTION_ARRAY_BOUNDS_EXCEEDED = STATUS_ARRAY_BOUNDS_EXCEEDED +EXCEPTION_BREAKPOINT = STATUS_BREAKPOINT +EXCEPTION_DATATYPE_MISALIGNMENT = STATUS_DATATYPE_MISALIGNMENT +EXCEPTION_FLT_DENORMAL_OPERAND = STATUS_FLOAT_DENORMAL_OPERAND +EXCEPTION_FLT_DIVIDE_BY_ZERO = STATUS_FLOAT_DIVIDE_BY_ZERO +EXCEPTION_FLT_INEXACT_RESULT = STATUS_FLOAT_INEXACT_RESULT +EXCEPTION_FLT_INVALID_OPERATION = STATUS_FLOAT_INVALID_OPERATION +EXCEPTION_FLT_OVERFLOW = STATUS_FLOAT_OVERFLOW +EXCEPTION_FLT_STACK_CHECK = STATUS_FLOAT_STACK_CHECK +EXCEPTION_FLT_UNDERFLOW = STATUS_FLOAT_UNDERFLOW +EXCEPTION_ILLEGAL_INSTRUCTION = STATUS_ILLEGAL_INSTRUCTION +EXCEPTION_IN_PAGE_ERROR = STATUS_IN_PAGE_ERROR +EXCEPTION_INT_DIVIDE_BY_ZERO = STATUS_INTEGER_DIVIDE_BY_ZERO +EXCEPTION_INT_OVERFLOW = STATUS_INTEGER_OVERFLOW +EXCEPTION_INVALID_DISPOSITION = STATUS_INVALID_DISPOSITION +EXCEPTION_NONCONTINUABLE_EXCEPTION = STATUS_NONCONTINUABLE_EXCEPTION +EXCEPTION_PRIV_INSTRUCTION = STATUS_PRIVILEGED_INSTRUCTION +EXCEPTION_SINGLE_STEP = STATUS_SINGLE_STEP +EXCEPTION_STACK_OVERFLOW = STATUS_STACK_OVERFLOW + +EXCEPTION_GUARD_PAGE = STATUS_GUARD_PAGE_VIOLATION +EXCEPTION_INVALID_HANDLE = STATUS_INVALID_HANDLE +EXCEPTION_POSSIBLE_DEADLOCK = STATUS_POSSIBLE_DEADLOCK +EXCEPTION_WX86_BREAKPOINT = STATUS_WX86_BREAKPOINT + +CONTROL_C_EXIT = STATUS_CONTROL_C_EXIT + +DBG_CONTROL_C = long(0x40010005) +MS_VC_EXCEPTION = long(0x406D1388) # Access violation types -ACCESS_VIOLATION_TYPE_READ = EXCEPTION_READ_FAULT -ACCESS_VIOLATION_TYPE_WRITE = EXCEPTION_WRITE_FAULT -ACCESS_VIOLATION_TYPE_DEP = EXCEPTION_EXECUTE_FAULT +ACCESS_VIOLATION_TYPE_READ = EXCEPTION_READ_FAULT +ACCESS_VIOLATION_TYPE_WRITE = EXCEPTION_WRITE_FAULT +ACCESS_VIOLATION_TYPE_DEP = EXCEPTION_EXECUTE_FAULT # RIP event types -SLE_ERROR = 1 +SLE_ERROR = 1 SLE_MINORERROR = 2 -SLE_WARNING = 3 +SLE_WARNING = 3 # DuplicateHandle constants -DUPLICATE_CLOSE_SOURCE = 0x00000001 -DUPLICATE_SAME_ACCESS = 0x00000002 +DUPLICATE_CLOSE_SOURCE = 0x00000001 +DUPLICATE_SAME_ACCESS = 0x00000002 # GetFinalPathNameByHandle constants -FILE_NAME_NORMALIZED = 0x0 -FILE_NAME_OPENED = 0x8 -VOLUME_NAME_DOS = 0x0 -VOLUME_NAME_GUID = 0x1 -VOLUME_NAME_NONE = 0x4 -VOLUME_NAME_NT = 0x2 +FILE_NAME_NORMALIZED = 0x0 +FILE_NAME_OPENED = 0x8 +VOLUME_NAME_DOS = 0x0 +VOLUME_NAME_GUID = 0x1 +VOLUME_NAME_NONE = 0x4 +VOLUME_NAME_NT = 0x2 # GetProductInfo constants PRODUCT_BUSINESS = 0x00000006 @@ -559,18 +557,19 @@ def RaiseIfLastError(result, func = None, arguments = ()): PROCESS_DEP_DISABLE_ATL_THUNK_EMULATION = 2 # Error modes -SEM_FAILCRITICALERRORS = 0x001 -SEM_NOGPFAULTERRORBOX = 0x002 -SEM_NOALIGNMENTFAULTEXCEPT = 0x004 -SEM_NOOPENFILEERRORBOX = 0x800 +SEM_FAILCRITICALERRORS = 0x001 +SEM_NOGPFAULTERRORBOX = 0x002 +SEM_NOALIGNMENTFAULTEXCEPT = 0x004 +SEM_NOOPENFILEERRORBOX = 0x800 # GetHandleInformation / SetHandleInformation -HANDLE_FLAG_INHERIT = 0x00000001 -HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002 +HANDLE_FLAG_INHERIT = 0x00000001 +HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002 -#--- Handle wrappers ---------------------------------------------------------- +# --- Handle wrappers ---------------------------------------------------------- -class Handle (object): + +class Handle(object): """ Encapsulates Win32 handles to avoid leaking them. @@ -593,7 +592,7 @@ class Handle (object): # detecting handle leaks within WinAppDbg itself. __bLeakDetection = False - def __init__(self, aHandle = None, bOwnership = True): + def __init__(self, aHandle=None, bOwnership=True): """ @type aHandle: int @param aHandle: Win32 handle value. @@ -604,9 +603,9 @@ def __init__(self, aHandle = None, bOwnership = True): C{False} if someone else will be calling L{CloseHandle}. """ super(Handle, self).__init__() - self._value = self._normalize(aHandle) + self._value = self._normalize(aHandle) self.bOwnership = bOwnership - if Handle.__bLeakDetection: # XXX DEBUG + if Handle.__bLeakDetection: # XXX DEBUG print("INIT HANDLE (%r) %r" % (self.value, self)) @property @@ -618,7 +617,7 @@ def __del__(self): Closes the Win32 handle when the Python object is destroyed. """ try: - if Handle.__bLeakDetection: # XXX DEBUG + if Handle.__bLeakDetection: # XXX DEBUG print("DEL HANDLE %r" % self) self.close() except Exception: @@ -628,7 +627,7 @@ def __enter__(self): """ Compatibility with the "C{with}" Python statement. """ - if Handle.__bLeakDetection: # XXX DEBUG + if Handle.__bLeakDetection: # XXX DEBUG print("ENTER HANDLE %r" % self) return self @@ -636,7 +635,7 @@ def __exit__(self, type, value, traceback): """ Compatibility with the "C{with}" Python statement. """ - if Handle.__bLeakDetection: # XXX DEBUG + if Handle.__bLeakDetection: # XXX DEBUG print("EXIT HANDLE %r" % self) try: self.close() @@ -685,7 +684,7 @@ def close(self): Closes the Win32 handle. """ if self.bOwnership and self.value not in (None, INVALID_HANDLE_VALUE): - if Handle.__bLeakDetection: # XXX DEBUG + if Handle.__bLeakDetection: # XXX DEBUG print("CLOSE HANDLE (%d) %r" % (self.value, self)) try: self._close() @@ -707,9 +706,8 @@ def dup(self): if self.value is None: raise ValueError("Closed handles can't be duplicated!") new_handle = DuplicateHandle(self.value) - if Handle.__bLeakDetection: # XXX DEBUG - print("DUP HANDLE (%d -> %d) %r %r" % \ - (self.value, new_handle.value, self, new_handle)) + if Handle.__bLeakDetection: # XXX DEBUG + print("DUP HANDLE (%d -> %d) %r %r" % (self.value, new_handle.value, self, new_handle)) return new_handle @staticmethod @@ -717,13 +715,13 @@ def _normalize(value): """ Normalize handle values. """ - if hasattr(value, 'value'): + if hasattr(value, "value"): value = value.value if value is not None: value = long(value) return value - def wait(self, dwMilliseconds = None): + def wait(self, dwMilliseconds=None): """ Wait for the Win32 object to be signaled. @@ -740,17 +738,17 @@ def wait(self, dwMilliseconds = None): raise ctypes.WinError(r) def __repr__(self): - return '<%s: %s>' % (self.__class__.__name__, self.value) + return "<%s: %s>" % (self.__class__.__name__, self.value) def __get_inherit(self): if self.value is None: raise ValueError("Handle is already closed!") - return bool( GetHandleInformation(self.value) & HANDLE_FLAG_INHERIT ) + return bool(GetHandleInformation(self.value) & HANDLE_FLAG_INHERIT) def __set_inherit(self, value): if self.value is None: raise ValueError("Handle is already closed!") - flag = (0, HANDLE_FLAG_INHERIT)[ bool(value) ] + flag = (0, HANDLE_FLAG_INHERIT)[bool(value)] SetHandleInformation(self.value, flag, flag) inherit = property(__get_inherit, __set_inherit) @@ -758,17 +756,18 @@ def __set_inherit(self, value): def __get_protectFromClose(self): if self.value is None: raise ValueError("Handle is already closed!") - return bool( GetHandleInformation(self.value) & HANDLE_FLAG_PROTECT_FROM_CLOSE ) + return bool(GetHandleInformation(self.value) & HANDLE_FLAG_PROTECT_FROM_CLOSE) def __set_protectFromClose(self, value): if self.value is None: raise ValueError("Handle is already closed!") - flag = (0, HANDLE_FLAG_PROTECT_FROM_CLOSE)[ bool(value) ] + flag = (0, HANDLE_FLAG_PROTECT_FROM_CLOSE)[bool(value)] SetHandleInformation(self.value, flag, flag) protectFromClose = property(__get_protectFromClose, __set_protectFromClose) -class UserModeHandle (Handle): + +class UserModeHandle(Handle): """ Base class for non-kernel handles. Generally this means they are closed by special Win32 API functions instead of CloseHandle() and some standard @@ -812,10 +811,11 @@ def dup(self): raise NotImplementedError() # Operation not supported. - def wait(self, dwMilliseconds = None): + def wait(self, dwMilliseconds=None): raise NotImplementedError() -class ProcessHandle (Handle): + +class ProcessHandle(Handle): """ Win32 process handle. @@ -828,8 +828,7 @@ class ProcessHandle (Handle): @see: L{Handle} """ - def __init__(self, aHandle = None, bOwnership = True, - dwAccess = PROCESS_ALL_ACCESS): + def __init__(self, aHandle=None, bOwnership=True, dwAccess=PROCESS_ALL_ACCESS): """ @type aHandle: int @param aHandle: Win32 handle value. @@ -858,7 +857,8 @@ def get_pid(self): """ return GetProcessId(self.value) -class ThreadHandle (Handle): + +class ThreadHandle(Handle): """ Win32 thread handle. @@ -871,8 +871,7 @@ class ThreadHandle (Handle): @see: L{Handle} """ - def __init__(self, aHandle = None, bOwnership = True, - dwAccess = THREAD_ALL_ACCESS): + def __init__(self, aHandle=None, bOwnership=True, dwAccess=THREAD_ALL_ACCESS): """ @type aHandle: int @param aHandle: Win32 handle value. @@ -901,7 +900,8 @@ def get_tid(self): """ return GetThreadId(self.value) -class FileHandle (Handle): + +class FileHandle(Handle): """ Win32 file handle. @@ -925,99 +925,78 @@ def get_filename(self): # Note that using the "official" GetFileInformationByHandleEx # API introduced in Vista doesn't change the results! # - dwBufferSize = 0x1004 + dwBufferSize = 0x1004 lpFileInformation = ctypes.create_string_buffer(dwBufferSize) try: - GetFileInformationByHandleEx(self.value, - FILE_INFO_BY_HANDLE_CLASS.FileNameInfo, - lpFileInformation, dwBufferSize) + GetFileInformationByHandleEx(self.value, FILE_INFO_BY_HANDLE_CLASS.FileNameInfo, lpFileInformation, dwBufferSize) except AttributeError: - from winappdbg.win32.ntdll import NtQueryInformationFile, \ - FileNameInformation, \ - FILE_NAME_INFORMATION - NtQueryInformationFile(self.value, - FileNameInformation, - lpFileInformation, - dwBufferSize) - FileName = compat.unicode(lpFileInformation.raw[sizeof(DWORD):], 'U16') + from winappdbg.win32.ntdll import NtQueryInformationFile, FileNameInformation, FILE_NAME_INFORMATION + + NtQueryInformationFile(self.value, FileNameInformation, lpFileInformation, dwBufferSize) + FileName = compat.unicode(lpFileInformation.raw[sizeof(DWORD) :], "U16") FileName = ctypes.create_unicode_buffer(FileName).value if not FileName: FileName = None - elif FileName[1:2] != ':': + elif FileName[1:2] != ":": # When the drive letter is missing, we'll assume SYSTEMROOT. # Not a good solution but it could be worse. import os - FileName = os.environ['SYSTEMROOT'][:2] + FileName + + FileName = os.environ["SYSTEMROOT"][:2] + FileName return FileName -class FileMappingHandle (Handle): + +class FileMappingHandle(Handle): """ File mapping handle. @see: L{Handle} """ + pass + # XXX maybe add functions related to the toolhelp snapshots here? -class SnapshotHandle (Handle): +class SnapshotHandle(Handle): """ Toolhelp32 snapshot handle. @see: L{Handle} """ + pass -#--- Structure wrappers ------------------------------------------------------- -class ProcessInformation (object): +# --- Structure wrappers ------------------------------------------------------- + + +class ProcessInformation(object): """ Process information object returned by L{CreateProcess}. """ def __init__(self, pi): - self.hProcess = ProcessHandle(pi.hProcess) - self.hThread = ThreadHandle(pi.hThread) + self.hProcess = ProcessHandle(pi.hProcess) + self.hThread = ThreadHandle(pi.hThread) self.dwProcessId = pi.dwProcessId - self.dwThreadId = pi.dwThreadId + self.dwThreadId = pi.dwThreadId + # Don't psyco-optimize this class because it needs to be serialized. -class MemoryBasicInformation (object): +class MemoryBasicInformation(object): """ Memory information object returned by L{VirtualQueryEx}. """ - READABLE = ( - PAGE_EXECUTE_READ | - PAGE_EXECUTE_READWRITE | - PAGE_EXECUTE_WRITECOPY | - PAGE_READONLY | - PAGE_READWRITE | - PAGE_WRITECOPY - ) + READABLE = PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY - WRITEABLE = ( - PAGE_EXECUTE_READWRITE | - PAGE_EXECUTE_WRITECOPY | - PAGE_READWRITE | - PAGE_WRITECOPY - ) + WRITEABLE = PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY | PAGE_READWRITE | PAGE_WRITECOPY - COPY_ON_WRITE = ( - PAGE_EXECUTE_WRITECOPY | - PAGE_WRITECOPY - ) + COPY_ON_WRITE = PAGE_EXECUTE_WRITECOPY | PAGE_WRITECOPY - EXECUTABLE = ( - PAGE_EXECUTE | - PAGE_EXECUTE_READ | - PAGE_EXECUTE_READWRITE | - PAGE_EXECUTE_WRITECOPY - ) + EXECUTABLE = PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY - EXECUTABLE_AND_WRITEABLE = ( - PAGE_EXECUTE_READWRITE | - PAGE_EXECUTE_WRITECOPY - ) + EXECUTABLE_AND_WRITEABLE = PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY def __init__(self, mbi=None): """ @@ -1026,27 +1005,27 @@ def __init__(self, mbi=None): L{MemoryBasicInformation} instance. """ if mbi is None: - self.BaseAddress = None - self.AllocationBase = None - self.AllocationProtect = None - self.RegionSize = None - self.State = None - self.Protect = None - self.Type = None + self.BaseAddress = None + self.AllocationBase = None + self.AllocationProtect = None + self.RegionSize = None + self.State = None + self.Protect = None + self.Type = None else: - self.BaseAddress = mbi.BaseAddress - self.AllocationBase = mbi.AllocationBase - self.AllocationProtect = mbi.AllocationProtect - self.RegionSize = mbi.RegionSize - self.State = mbi.State - self.Protect = mbi.Protect - self.Type = mbi.Type + self.BaseAddress = mbi.BaseAddress + self.AllocationBase = mbi.AllocationBase + self.AllocationProtect = mbi.AllocationProtect + self.RegionSize = mbi.RegionSize + self.State = mbi.State + self.Protect = mbi.Protect + self.Type = mbi.Type # Only used when copying MemoryBasicInformation objects, instead of # instancing them from a MEMORY_BASIC_INFORMATION structure. - if hasattr(mbi, 'content'): + if hasattr(mbi, "content"): self.content = mbi.content - if hasattr(mbi, 'filename'): + if hasattr(mbi, "filename"): self.content = mbi.filename def __contains__(self, address): @@ -1162,7 +1141,8 @@ def is_executable_and_writeable(self): """ return self.has_content() and bool(self.Protect & self.EXECUTABLE_AND_WRITEABLE) -class ProcThreadAttributeList (object): + +class ProcThreadAttributeList(object): """ Extended process and thread attribute support. @@ -1186,12 +1166,10 @@ def __init__(self, AttributeList): @param AttributeList: List of (Attribute, Value) pairs. """ self.AttributeList = AttributeList - self.AttributeListBuffer = InitializeProcThreadAttributeList( - len(AttributeList)) + self.AttributeListBuffer = InitializeProcThreadAttributeList(len(AttributeList)) try: for Attribute, Value in AttributeList: - UpdateProcThreadAttribute(self.AttributeListBuffer, - Attribute, Value) + UpdateProcThreadAttribute(self.AttributeListBuffer, Attribute, Value) except: ProcThreadAttributeList.__del__(self) raise @@ -1222,7 +1200,9 @@ def _as_parameter_(self): def from_param(value): raise NotImplementedError() -#--- OVERLAPPED structure ----------------------------------------------------- + +# --- OVERLAPPED structure ----------------------------------------------------- + # typedef struct _OVERLAPPED { # ULONG_PTR Internal; @@ -1238,24 +1218,31 @@ def from_param(value): # }OVERLAPPED, *LPOVERLAPPED; class _OVERLAPPED_STRUCT(Structure): _fields_ = [ - ('Offset', DWORD), - ('OffsetHigh', DWORD), + ("Offset", DWORD), + ("OffsetHigh", DWORD), ] + + class _OVERLAPPED_UNION(Union): _fields_ = [ - ('s', _OVERLAPPED_STRUCT), - ('Pointer', PVOID), + ("s", _OVERLAPPED_STRUCT), + ("Pointer", PVOID), ] + + class OVERLAPPED(Structure): _fields_ = [ - ('Internal', ULONG_PTR), - ('InternalHigh', ULONG_PTR), - ('u', _OVERLAPPED_UNION), - ('hEvent', HANDLE), + ("Internal", ULONG_PTR), + ("InternalHigh", ULONG_PTR), + ("u", _OVERLAPPED_UNION), + ("hEvent", HANDLE), ] + + LPOVERLAPPED = POINTER(OVERLAPPED) -#--- SECURITY_ATTRIBUTES structure -------------------------------------------- +# --- SECURITY_ATTRIBUTES structure -------------------------------------------- + # typedef struct _SECURITY_ATTRIBUTES { # DWORD nLength; @@ -1264,47 +1251,50 @@ class OVERLAPPED(Structure): # } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES; class SECURITY_ATTRIBUTES(Structure): _fields_ = [ - ('nLength', DWORD), - ('lpSecurityDescriptor', LPVOID), - ('bInheritHandle', BOOL), + ("nLength", DWORD), + ("lpSecurityDescriptor", LPVOID), + ("bInheritHandle", BOOL), ] + + LPSECURITY_ATTRIBUTES = POINTER(SECURITY_ATTRIBUTES) # --- Extended process and thread attribute support --------------------------- -PPROC_THREAD_ATTRIBUTE_LIST = LPVOID +PPROC_THREAD_ATTRIBUTE_LIST = LPVOID LPPROC_THREAD_ATTRIBUTE_LIST = PPROC_THREAD_ATTRIBUTE_LIST -PROC_THREAD_ATTRIBUTE_NUMBER = 0x0000FFFF -PROC_THREAD_ATTRIBUTE_THREAD = 0x00010000 # Attribute may be used with thread creation -PROC_THREAD_ATTRIBUTE_INPUT = 0x00020000 # Attribute is input only +PROC_THREAD_ATTRIBUTE_NUMBER = 0x0000FFFF +PROC_THREAD_ATTRIBUTE_THREAD = 0x00010000 # Attribute may be used with thread creation +PROC_THREAD_ATTRIBUTE_INPUT = 0x00020000 # Attribute is input only PROC_THREAD_ATTRIBUTE_ADDITIVE = 0x00040000 # Attribute may be "accumulated," e.g. bitmasks, counters, etc. # PROC_THREAD_ATTRIBUTE_NUM -ProcThreadAttributeParentProcess = 0 -ProcThreadAttributeExtendedFlags = 1 -ProcThreadAttributeHandleList = 2 -ProcThreadAttributeGroupAffinity = 3 -ProcThreadAttributePreferredNode = 4 -ProcThreadAttributeIdealProcessor = 5 -ProcThreadAttributeUmsThread = 6 +ProcThreadAttributeParentProcess = 0 +ProcThreadAttributeExtendedFlags = 1 +ProcThreadAttributeHandleList = 2 +ProcThreadAttributeGroupAffinity = 3 +ProcThreadAttributePreferredNode = 4 +ProcThreadAttributeIdealProcessor = 5 +ProcThreadAttributeUmsThread = 6 ProcThreadAttributeMitigationPolicy = 7 -ProcThreadAttributeMax = 8 - -PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = ProcThreadAttributeParentProcess | PROC_THREAD_ATTRIBUTE_INPUT -PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS = ProcThreadAttributeExtendedFlags | PROC_THREAD_ATTRIBUTE_INPUT | PROC_THREAD_ATTRIBUTE_ADDITIVE -PROC_THREAD_ATTRIBUTE_HANDLE_LIST = ProcThreadAttributeHandleList | PROC_THREAD_ATTRIBUTE_INPUT -PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY = ProcThreadAttributeGroupAffinity | PROC_THREAD_ATTRIBUTE_THREAD | PROC_THREAD_ATTRIBUTE_INPUT -PROC_THREAD_ATTRIBUTE_PREFERRED_NODE = ProcThreadAttributePreferredNode | PROC_THREAD_ATTRIBUTE_INPUT -PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR = ProcThreadAttributeIdealProcessor | PROC_THREAD_ATTRIBUTE_THREAD | PROC_THREAD_ATTRIBUTE_INPUT -PROC_THREAD_ATTRIBUTE_UMS_THREAD = ProcThreadAttributeUmsThread | PROC_THREAD_ATTRIBUTE_THREAD | PROC_THREAD_ATTRIBUTE_INPUT -PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = ProcThreadAttributeMitigationPolicy | PROC_THREAD_ATTRIBUTE_INPUT - -PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE = 0x01 +ProcThreadAttributeMax = 8 + +PROC_THREAD_ATTRIBUTE_PARENT_PROCESS = ProcThreadAttributeParentProcess | PROC_THREAD_ATTRIBUTE_INPUT +PROC_THREAD_ATTRIBUTE_EXTENDED_FLAGS = ProcThreadAttributeExtendedFlags | PROC_THREAD_ATTRIBUTE_INPUT | PROC_THREAD_ATTRIBUTE_ADDITIVE +PROC_THREAD_ATTRIBUTE_HANDLE_LIST = ProcThreadAttributeHandleList | PROC_THREAD_ATTRIBUTE_INPUT +PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY = ProcThreadAttributeGroupAffinity | PROC_THREAD_ATTRIBUTE_THREAD | PROC_THREAD_ATTRIBUTE_INPUT +PROC_THREAD_ATTRIBUTE_PREFERRED_NODE = ProcThreadAttributePreferredNode | PROC_THREAD_ATTRIBUTE_INPUT +PROC_THREAD_ATTRIBUTE_IDEAL_PROCESSOR = ProcThreadAttributeIdealProcessor | PROC_THREAD_ATTRIBUTE_THREAD | PROC_THREAD_ATTRIBUTE_INPUT +PROC_THREAD_ATTRIBUTE_UMS_THREAD = ProcThreadAttributeUmsThread | PROC_THREAD_ATTRIBUTE_THREAD | PROC_THREAD_ATTRIBUTE_INPUT +PROC_THREAD_ATTRIBUTE_MITIGATION_POLICY = ProcThreadAttributeMitigationPolicy | PROC_THREAD_ATTRIBUTE_INPUT + +PROCESS_CREATION_MITIGATION_POLICY_DEP_ENABLE = 0x01 PROCESS_CREATION_MITIGATION_POLICY_DEP_ATL_THUNK_ENABLE = 0x02 -PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE = 0x04 +PROCESS_CREATION_MITIGATION_POLICY_SEHOP_ENABLE = 0x04 + +# --- VS_FIXEDFILEINFO structure ----------------------------------------------- -#--- VS_FIXEDFILEINFO structure ----------------------------------------------- # struct VS_FIXEDFILEINFO { # DWORD dwSignature; @@ -1321,24 +1311,26 @@ class SECURITY_ATTRIBUTES(Structure): # DWORD dwFileDateMS; # DWORD dwFileDateLS; # }; -class VS_FIXEDFILEINFO (Structure): +class VS_FIXEDFILEINFO(Structure): _fields_ = [ - ("dwSignature", DWORD), # 0xFEEF04BD - ("dwStrucVersion", DWORD), - ("dwFileVersionMS", DWORD), - ("dwFileVersionLS", DWORD), - ("dwProductVersionMS", DWORD), - ("dwProductVersionLS", DWORD), - ("dwFileFlagsMask", DWORD), - ("dwFileFlags", DWORD), - ("dwFileOS", DWORD), - ("dwFileType", DWORD), - ("dwFileSubtype", DWORD), - ("dwFileDateMS", DWORD), - ("dwFileDateLS", DWORD), + ("dwSignature", DWORD), # 0xFEEF04BD + ("dwStrucVersion", DWORD), + ("dwFileVersionMS", DWORD), + ("dwFileVersionLS", DWORD), + ("dwProductVersionMS", DWORD), + ("dwProductVersionLS", DWORD), + ("dwFileFlagsMask", DWORD), + ("dwFileFlags", DWORD), + ("dwFileOS", DWORD), + ("dwFileType", DWORD), + ("dwFileSubtype", DWORD), + ("dwFileDateMS", DWORD), + ("dwFileDateLS", DWORD), ] -#--- THREADNAME_INFO structure ------------------------------------------------ + +# --- THREADNAME_INFO structure ------------------------------------------------ + # typedef struct tagTHREADNAME_INFO # { @@ -1349,13 +1341,15 @@ class VS_FIXEDFILEINFO (Structure): # } THREADNAME_INFO; class THREADNAME_INFO(Structure): _fields_ = [ - ("dwType", DWORD), # 0x1000 - ("szName", LPVOID), # remote pointer - ("dwThreadID", DWORD), # -1 usually - ("dwFlags", DWORD), # 0 + ("dwType", DWORD), # 0x1000 + ("szName", LPVOID), # remote pointer + ("dwThreadID", DWORD), # -1 usually + ("dwFlags", DWORD), # 0 ] -#--- MEMORY_BASIC_INFORMATION structure --------------------------------------- + +# --- MEMORY_BASIC_INFORMATION structure --------------------------------------- + # typedef struct _MEMORY_BASIC_INFORMATION32 { # DWORD BaseAddress; @@ -1368,15 +1362,16 @@ class THREADNAME_INFO(Structure): # } MEMORY_BASIC_INFORMATION32, *PMEMORY_BASIC_INFORMATION32; class MEMORY_BASIC_INFORMATION32(Structure): _fields_ = [ - ('BaseAddress', DWORD), # remote pointer - ('AllocationBase', DWORD), # remote pointer - ('AllocationProtect', DWORD), - ('RegionSize', DWORD), - ('State', DWORD), - ('Protect', DWORD), - ('Type', DWORD), + ("BaseAddress", DWORD), # remote pointer + ("AllocationBase", DWORD), # remote pointer + ("AllocationProtect", DWORD), + ("RegionSize", DWORD), + ("State", DWORD), + ("Protect", DWORD), + ("Type", DWORD), ] + # typedef struct DECLSPEC_ALIGN(16) _MEMORY_BASIC_INFORMATION64 { # ULONGLONG BaseAddress; # ULONGLONG AllocationBase; @@ -1390,17 +1385,18 @@ class MEMORY_BASIC_INFORMATION32(Structure): # } MEMORY_BASIC_INFORMATION64, *PMEMORY_BASIC_INFORMATION64; class MEMORY_BASIC_INFORMATION64(Structure): _fields_ = [ - ('BaseAddress', ULONGLONG), # remote pointer - ('AllocationBase', ULONGLONG), # remote pointer - ('AllocationProtect', DWORD), - ('__alignment1', DWORD), - ('RegionSize', ULONGLONG), - ('State', DWORD), - ('Protect', DWORD), - ('Type', DWORD), - ('__alignment2', DWORD), + ("BaseAddress", ULONGLONG), # remote pointer + ("AllocationBase", ULONGLONG), # remote pointer + ("AllocationProtect", DWORD), + ("__alignment1", DWORD), + ("RegionSize", ULONGLONG), + ("State", DWORD), + ("Protect", DWORD), + ("Type", DWORD), + ("__alignment2", DWORD), ] + # typedef struct _MEMORY_BASIC_INFORMATION { # PVOID BaseAddress; # PVOID AllocationBase; @@ -1412,17 +1408,20 @@ class MEMORY_BASIC_INFORMATION64(Structure): # } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION; class MEMORY_BASIC_INFORMATION(Structure): _fields_ = [ - ('BaseAddress', SIZE_T), # remote pointer - ('AllocationBase', SIZE_T), # remote pointer - ('AllocationProtect', DWORD), - ('RegionSize', SIZE_T), - ('State', DWORD), - ('Protect', DWORD), - ('Type', DWORD), + ("BaseAddress", SIZE_T), # remote pointer + ("AllocationBase", SIZE_T), # remote pointer + ("AllocationProtect", DWORD), + ("RegionSize", SIZE_T), + ("State", DWORD), + ("Protect", DWORD), + ("Type", DWORD), ] + + PMEMORY_BASIC_INFORMATION = POINTER(MEMORY_BASIC_INFORMATION) -#--- BY_HANDLE_FILE_INFORMATION structure ------------------------------------- +# --- BY_HANDLE_FILE_INFORMATION structure ------------------------------------- + # typedef struct _FILETIME { # DWORD dwLowDateTime; @@ -1430,11 +1429,14 @@ class MEMORY_BASIC_INFORMATION(Structure): # } FILETIME, *PFILETIME; class FILETIME(Structure): _fields_ = [ - ('dwLowDateTime', DWORD), - ('dwHighDateTime', DWORD), + ("dwLowDateTime", DWORD), + ("dwHighDateTime", DWORD), ] + + LPFILETIME = POINTER(FILETIME) + # typedef struct _SYSTEMTIME { # WORD wYear; # WORD wMonth; @@ -1447,17 +1449,20 @@ class FILETIME(Structure): # }SYSTEMTIME, *PSYSTEMTIME; class SYSTEMTIME(Structure): _fields_ = [ - ('wYear', WORD), - ('wMonth', WORD), - ('wDayOfWeek', WORD), - ('wDay', WORD), - ('wHour', WORD), - ('wMinute', WORD), - ('wSecond', WORD), - ('wMilliseconds', WORD), + ("wYear", WORD), + ("wMonth", WORD), + ("wDayOfWeek", WORD), + ("wDay", WORD), + ("wHour", WORD), + ("wMinute", WORD), + ("wSecond", WORD), + ("wMilliseconds", WORD), ] + + LPSYSTEMTIME = POINTER(SYSTEMTIME) + # typedef struct _BY_HANDLE_FILE_INFORMATION { # DWORD dwFileAttributes; # FILETIME ftCreationTime; @@ -1472,19 +1477,22 @@ class SYSTEMTIME(Structure): # } BY_HANDLE_FILE_INFORMATION, *PBY_HANDLE_FILE_INFORMATION; class BY_HANDLE_FILE_INFORMATION(Structure): _fields_ = [ - ('dwFileAttributes', DWORD), - ('ftCreationTime', FILETIME), - ('ftLastAccessTime', FILETIME), - ('ftLastWriteTime', FILETIME), - ('dwVolumeSerialNumber', DWORD), - ('nFileSizeHigh', DWORD), - ('nFileSizeLow', DWORD), - ('nNumberOfLinks', DWORD), - ('nFileIndexHigh', DWORD), - ('nFileIndexLow', DWORD), + ("dwFileAttributes", DWORD), + ("ftCreationTime", FILETIME), + ("ftLastAccessTime", FILETIME), + ("ftLastWriteTime", FILETIME), + ("dwVolumeSerialNumber", DWORD), + ("nFileSizeHigh", DWORD), + ("nFileSizeLow", DWORD), + ("nNumberOfLinks", DWORD), + ("nFileIndexHigh", DWORD), + ("nFileIndexLow", DWORD), ] + + LPBY_HANDLE_FILE_INFORMATION = POINTER(BY_HANDLE_FILE_INFORMATION) + # typedef enum _FILE_INFO_BY_HANDLE_CLASS { # FileBasicInfo = 0, # FileStandardInfo = 1, @@ -1502,20 +1510,21 @@ class BY_HANDLE_FILE_INFORMATION(Structure): # MaximumFileInfoByHandlesClass = 13 # } FILE_INFO_BY_HANDLE_CLASS, *PFILE_INFO_BY_HANDLE_CLASS; class FILE_INFO_BY_HANDLE_CLASS(object): - FileBasicInfo = 0 - FileStandardInfo = 1 - FileNameInfo = 2 - FileRenameInfo = 3 - FileDispositionInfo = 4 - FileAllocationInfo = 5 - FileEndOfFileInfo = 6 - FileStreamInfo = 7 - FileCompressionInfo = 8 - FileAttributeTagInfo = 9 - FileIdBothDirectoryInfo = 10 - FileIdBothDirectoryRestartInfo = 11 - FileIoPriorityHintInfo = 12 - MaximumFileInfoByHandlesClass = 13 + FileBasicInfo = 0 + FileStandardInfo = 1 + FileNameInfo = 2 + FileRenameInfo = 3 + FileDispositionInfo = 4 + FileAllocationInfo = 5 + FileEndOfFileInfo = 6 + FileStreamInfo = 7 + FileCompressionInfo = 8 + FileAttributeTagInfo = 9 + FileIdBothDirectoryInfo = 10 + FileIdBothDirectoryRestartInfo = 11 + FileIoPriorityHintInfo = 12 + MaximumFileInfoByHandlesClass = 13 + # typedef struct _FILE_NAME_INFO { # DWORD FileNameLength; @@ -1529,7 +1538,8 @@ class FILE_INFO_BY_HANDLE_CLASS(object): # TO DO: add more structures used by GetFileInformationByHandleEx() -#--- PROCESS_INFORMATION structure -------------------------------------------- +# --- PROCESS_INFORMATION structure -------------------------------------------- + # typedef struct _PROCESS_INFORMATION { # HANDLE hProcess; @@ -1539,14 +1549,17 @@ class FILE_INFO_BY_HANDLE_CLASS(object): # } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; class PROCESS_INFORMATION(Structure): _fields_ = [ - ('hProcess', HANDLE), - ('hThread', HANDLE), - ('dwProcessId', DWORD), - ('dwThreadId', DWORD), + ("hProcess", HANDLE), + ("hThread", HANDLE), + ("dwProcessId", DWORD), + ("dwThreadId", DWORD), ] + + LPPROCESS_INFORMATION = POINTER(PROCESS_INFORMATION) -#--- STARTUPINFO and STARTUPINFOEX structures --------------------------------- +# --- STARTUPINFO and STARTUPINFOEX structures --------------------------------- + # typedef struct _STARTUPINFO { # DWORD cb; @@ -1570,69 +1583,81 @@ class PROCESS_INFORMATION(Structure): # }STARTUPINFO, *LPSTARTUPINFO; class STARTUPINFO(Structure): _fields_ = [ - ('cb', DWORD), - ('lpReserved', LPSTR), - ('lpDesktop', LPSTR), - ('lpTitle', LPSTR), - ('dwX', DWORD), - ('dwY', DWORD), - ('dwXSize', DWORD), - ('dwYSize', DWORD), - ('dwXCountChars', DWORD), - ('dwYCountChars', DWORD), - ('dwFillAttribute', DWORD), - ('dwFlags', DWORD), - ('wShowWindow', WORD), - ('cbReserved2', WORD), - ('lpReserved2', LPVOID), # LPBYTE - ('hStdInput', HANDLE), - ('hStdOutput', HANDLE), - ('hStdError', HANDLE), + ("cb", DWORD), + ("lpReserved", LPSTR), + ("lpDesktop", LPSTR), + ("lpTitle", LPSTR), + ("dwX", DWORD), + ("dwY", DWORD), + ("dwXSize", DWORD), + ("dwYSize", DWORD), + ("dwXCountChars", DWORD), + ("dwYCountChars", DWORD), + ("dwFillAttribute", DWORD), + ("dwFlags", DWORD), + ("wShowWindow", WORD), + ("cbReserved2", WORD), + ("lpReserved2", LPVOID), # LPBYTE + ("hStdInput", HANDLE), + ("hStdOutput", HANDLE), + ("hStdError", HANDLE), ] + + LPSTARTUPINFO = POINTER(STARTUPINFO) + # typedef struct _STARTUPINFOEX { # STARTUPINFO StartupInfo; # PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList; # } STARTUPINFOEX, *LPSTARTUPINFOEX; class STARTUPINFOEX(Structure): _fields_ = [ - ('StartupInfo', STARTUPINFO), - ('lpAttributeList', PPROC_THREAD_ATTRIBUTE_LIST), + ("StartupInfo", STARTUPINFO), + ("lpAttributeList", PPROC_THREAD_ATTRIBUTE_LIST), ] + + LPSTARTUPINFOEX = POINTER(STARTUPINFOEX) + class STARTUPINFOW(Structure): _fields_ = [ - ('cb', DWORD), - ('lpReserved', LPWSTR), - ('lpDesktop', LPWSTR), - ('lpTitle', LPWSTR), - ('dwX', DWORD), - ('dwY', DWORD), - ('dwXSize', DWORD), - ('dwYSize', DWORD), - ('dwXCountChars', DWORD), - ('dwYCountChars', DWORD), - ('dwFillAttribute', DWORD), - ('dwFlags', DWORD), - ('wShowWindow', WORD), - ('cbReserved2', WORD), - ('lpReserved2', LPVOID), # LPBYTE - ('hStdInput', HANDLE), - ('hStdOutput', HANDLE), - ('hStdError', HANDLE), + ("cb", DWORD), + ("lpReserved", LPWSTR), + ("lpDesktop", LPWSTR), + ("lpTitle", LPWSTR), + ("dwX", DWORD), + ("dwY", DWORD), + ("dwXSize", DWORD), + ("dwYSize", DWORD), + ("dwXCountChars", DWORD), + ("dwYCountChars", DWORD), + ("dwFillAttribute", DWORD), + ("dwFlags", DWORD), + ("wShowWindow", WORD), + ("cbReserved2", WORD), + ("lpReserved2", LPVOID), # LPBYTE + ("hStdInput", HANDLE), + ("hStdOutput", HANDLE), + ("hStdError", HANDLE), ] + + LPSTARTUPINFOW = POINTER(STARTUPINFOW) + class STARTUPINFOEXW(Structure): _fields_ = [ - ('StartupInfo', STARTUPINFOW), - ('lpAttributeList', PPROC_THREAD_ATTRIBUTE_LIST), + ("StartupInfo", STARTUPINFOW), + ("lpAttributeList", PPROC_THREAD_ATTRIBUTE_LIST), ] + + LPSTARTUPINFOEXW = POINTER(STARTUPINFOEXW) -#--- JIT_DEBUG_INFO structure ------------------------------------------------- +# --- JIT_DEBUG_INFO structure ------------------------------------------------- + # typedef struct _JIT_DEBUG_INFO { # DWORD dwSize; @@ -1645,22 +1670,25 @@ class STARTUPINFOEXW(Structure): # } JIT_DEBUG_INFO, *LPJIT_DEBUG_INFO; class JIT_DEBUG_INFO(Structure): _fields_ = [ - ('dwSize', DWORD), - ('dwProcessorArchitecture', DWORD), - ('dwThreadID', DWORD), - ('dwReserved0', DWORD), - ('lpExceptionAddress', ULONG64), - ('lpExceptionRecord', ULONG64), - ('lpContextRecord', ULONG64), + ("dwSize", DWORD), + ("dwProcessorArchitecture", DWORD), + ("dwThreadID", DWORD), + ("dwReserved0", DWORD), + ("lpExceptionAddress", ULONG64), + ("lpExceptionRecord", ULONG64), + ("lpContextRecord", ULONG64), ] + + JIT_DEBUG_INFO32 = JIT_DEBUG_INFO JIT_DEBUG_INFO64 = JIT_DEBUG_INFO -LPJIT_DEBUG_INFO = POINTER(JIT_DEBUG_INFO) +LPJIT_DEBUG_INFO = POINTER(JIT_DEBUG_INFO) LPJIT_DEBUG_INFO32 = POINTER(JIT_DEBUG_INFO32) LPJIT_DEBUG_INFO64 = POINTER(JIT_DEBUG_INFO64) -#--- DEBUG_EVENT structure ---------------------------------------------------- +# --- DEBUG_EVENT structure ---------------------------------------------------- + # typedef struct _EXCEPTION_RECORD32 { # DWORD ExceptionCode; @@ -1672,16 +1700,18 @@ class JIT_DEBUG_INFO(Structure): # } EXCEPTION_RECORD32, *PEXCEPTION_RECORD32; class EXCEPTION_RECORD32(Structure): _fields_ = [ - ('ExceptionCode', DWORD), - ('ExceptionFlags', DWORD), - ('ExceptionRecord', DWORD), - ('ExceptionAddress', DWORD), - ('NumberParameters', DWORD), - ('ExceptionInformation', DWORD * EXCEPTION_MAXIMUM_PARAMETERS), + ("ExceptionCode", DWORD), + ("ExceptionFlags", DWORD), + ("ExceptionRecord", DWORD), + ("ExceptionAddress", DWORD), + ("NumberParameters", DWORD), + ("ExceptionInformation", DWORD * EXCEPTION_MAXIMUM_PARAMETERS), ] + PEXCEPTION_RECORD32 = POINTER(EXCEPTION_RECORD32) + # typedef struct _EXCEPTION_RECORD64 { # DWORD ExceptionCode; # DWORD ExceptionFlags; @@ -1693,17 +1723,19 @@ class EXCEPTION_RECORD32(Structure): # } EXCEPTION_RECORD64, *PEXCEPTION_RECORD64; class EXCEPTION_RECORD64(Structure): _fields_ = [ - ('ExceptionCode', DWORD), - ('ExceptionFlags', DWORD), - ('ExceptionRecord', DWORD64), - ('ExceptionAddress', DWORD64), - ('NumberParameters', DWORD), - ('__unusedAlignment', DWORD), - ('ExceptionInformation', DWORD64 * EXCEPTION_MAXIMUM_PARAMETERS), + ("ExceptionCode", DWORD), + ("ExceptionFlags", DWORD), + ("ExceptionRecord", DWORD64), + ("ExceptionAddress", DWORD64), + ("NumberParameters", DWORD), + ("__unusedAlignment", DWORD), + ("ExceptionInformation", DWORD64 * EXCEPTION_MAXIMUM_PARAMETERS), ] + PEXCEPTION_RECORD64 = POINTER(EXCEPTION_RECORD64) + # typedef struct _EXCEPTION_RECORD { # DWORD ExceptionCode; # DWORD ExceptionFlags; @@ -1714,15 +1746,18 @@ class EXCEPTION_RECORD64(Structure): # } EXCEPTION_RECORD, *PEXCEPTION_RECORD; class EXCEPTION_RECORD(Structure): pass + + PEXCEPTION_RECORD = POINTER(EXCEPTION_RECORD) EXCEPTION_RECORD._fields_ = [ - ('ExceptionCode', DWORD), - ('ExceptionFlags', DWORD), - ('ExceptionRecord', PEXCEPTION_RECORD), - ('ExceptionAddress', LPVOID), - ('NumberParameters', DWORD), - ('ExceptionInformation', LPVOID * EXCEPTION_MAXIMUM_PARAMETERS), - ] + ("ExceptionCode", DWORD), + ("ExceptionFlags", DWORD), + ("ExceptionRecord", PEXCEPTION_RECORD), + ("ExceptionAddress", LPVOID), + ("NumberParameters", DWORD), + ("ExceptionInformation", LPVOID * EXCEPTION_MAXIMUM_PARAMETERS), +] + # typedef struct _EXCEPTION_DEBUG_INFO { # EXCEPTION_RECORD ExceptionRecord; @@ -1730,10 +1765,11 @@ class EXCEPTION_RECORD(Structure): # } EXCEPTION_DEBUG_INFO; class EXCEPTION_DEBUG_INFO(Structure): _fields_ = [ - ('ExceptionRecord', EXCEPTION_RECORD), - ('dwFirstChance', DWORD), + ("ExceptionRecord", EXCEPTION_RECORD), + ("dwFirstChance", DWORD), ] + # typedef struct _CREATE_THREAD_DEBUG_INFO { # HANDLE hThread; # LPVOID lpThreadLocalBase; @@ -1741,11 +1777,12 @@ class EXCEPTION_DEBUG_INFO(Structure): # } CREATE_THREAD_DEBUG_INFO; class CREATE_THREAD_DEBUG_INFO(Structure): _fields_ = [ - ('hThread', HANDLE), - ('lpThreadLocalBase', LPVOID), - ('lpStartAddress', LPVOID), + ("hThread", HANDLE), + ("lpThreadLocalBase", LPVOID), + ("lpStartAddress", LPVOID), ] + # typedef struct _CREATE_PROCESS_DEBUG_INFO { # HANDLE hFile; # HANDLE hProcess; @@ -1760,34 +1797,37 @@ class CREATE_THREAD_DEBUG_INFO(Structure): # } CREATE_PROCESS_DEBUG_INFO; class CREATE_PROCESS_DEBUG_INFO(Structure): _fields_ = [ - ('hFile', HANDLE), - ('hProcess', HANDLE), - ('hThread', HANDLE), - ('lpBaseOfImage', LPVOID), - ('dwDebugInfoFileOffset', DWORD), - ('nDebugInfoSize', DWORD), - ('lpThreadLocalBase', LPVOID), - ('lpStartAddress', LPVOID), - ('lpImageName', LPVOID), - ('fUnicode', WORD), + ("hFile", HANDLE), + ("hProcess", HANDLE), + ("hThread", HANDLE), + ("lpBaseOfImage", LPVOID), + ("dwDebugInfoFileOffset", DWORD), + ("nDebugInfoSize", DWORD), + ("lpThreadLocalBase", LPVOID), + ("lpStartAddress", LPVOID), + ("lpImageName", LPVOID), + ("fUnicode", WORD), ] + # typedef struct _EXIT_THREAD_DEBUG_INFO { # DWORD dwExitCode; # } EXIT_THREAD_DEBUG_INFO; class EXIT_THREAD_DEBUG_INFO(Structure): _fields_ = [ - ('dwExitCode', DWORD), + ("dwExitCode", DWORD), ] + # typedef struct _EXIT_PROCESS_DEBUG_INFO { # DWORD dwExitCode; # } EXIT_PROCESS_DEBUG_INFO; class EXIT_PROCESS_DEBUG_INFO(Structure): _fields_ = [ - ('dwExitCode', DWORD), + ("dwExitCode", DWORD), ] + # typedef struct _LOAD_DLL_DEBUG_INFO { # HANDLE hFile; # LPVOID lpBaseOfDll; @@ -1798,22 +1838,24 @@ class EXIT_PROCESS_DEBUG_INFO(Structure): # } LOAD_DLL_DEBUG_INFO; class LOAD_DLL_DEBUG_INFO(Structure): _fields_ = [ - ('hFile', HANDLE), - ('lpBaseOfDll', LPVOID), - ('dwDebugInfoFileOffset', DWORD), - ('nDebugInfoSize', DWORD), - ('lpImageName', LPVOID), - ('fUnicode', WORD), + ("hFile", HANDLE), + ("lpBaseOfDll", LPVOID), + ("dwDebugInfoFileOffset", DWORD), + ("nDebugInfoSize", DWORD), + ("lpImageName", LPVOID), + ("fUnicode", WORD), ] + # typedef struct _UNLOAD_DLL_DEBUG_INFO { # LPVOID lpBaseOfDll; # } UNLOAD_DLL_DEBUG_INFO; class UNLOAD_DLL_DEBUG_INFO(Structure): _fields_ = [ - ('lpBaseOfDll', LPVOID), + ("lpBaseOfDll", LPVOID), ] + # typedef struct _OUTPUT_DEBUG_STRING_INFO { # LPSTR lpDebugStringData; # WORD fUnicode; @@ -1821,21 +1863,23 @@ class UNLOAD_DLL_DEBUG_INFO(Structure): # } OUTPUT_DEBUG_STRING_INFO; class OUTPUT_DEBUG_STRING_INFO(Structure): _fields_ = [ - ('lpDebugStringData', LPVOID), # don't use LPSTR - ('fUnicode', WORD), - ('nDebugStringLength', WORD), + ("lpDebugStringData", LPVOID), # don't use LPSTR + ("fUnicode", WORD), + ("nDebugStringLength", WORD), ] + # typedef struct _RIP_INFO { # DWORD dwError; # DWORD dwType; # } RIP_INFO, *LPRIP_INFO; class RIP_INFO(Structure): _fields_ = [ - ('dwError', DWORD), - ('dwType', DWORD), + ("dwError", DWORD), + ("dwType", DWORD), ] + # typedef struct _DEBUG_EVENT { # DWORD dwDebugEventCode; # DWORD dwProcessId; @@ -1854,58 +1898,63 @@ class RIP_INFO(Structure): # } DEBUG_EVENT;. class _DEBUG_EVENT_UNION_(Union): _fields_ = [ - ('Exception', EXCEPTION_DEBUG_INFO), - ('CreateThread', CREATE_THREAD_DEBUG_INFO), - ('CreateProcessInfo', CREATE_PROCESS_DEBUG_INFO), - ('ExitThread', EXIT_THREAD_DEBUG_INFO), - ('ExitProcess', EXIT_PROCESS_DEBUG_INFO), - ('LoadDll', LOAD_DLL_DEBUG_INFO), - ('UnloadDll', UNLOAD_DLL_DEBUG_INFO), - ('DebugString', OUTPUT_DEBUG_STRING_INFO), - ('RipInfo', RIP_INFO), + ("Exception", EXCEPTION_DEBUG_INFO), + ("CreateThread", CREATE_THREAD_DEBUG_INFO), + ("CreateProcessInfo", CREATE_PROCESS_DEBUG_INFO), + ("ExitThread", EXIT_THREAD_DEBUG_INFO), + ("ExitProcess", EXIT_PROCESS_DEBUG_INFO), + ("LoadDll", LOAD_DLL_DEBUG_INFO), + ("UnloadDll", UNLOAD_DLL_DEBUG_INFO), + ("DebugString", OUTPUT_DEBUG_STRING_INFO), + ("RipInfo", RIP_INFO), ] + + class DEBUG_EVENT(Structure): _fields_ = [ - ('dwDebugEventCode', DWORD), - ('dwProcessId', DWORD), - ('dwThreadId', DWORD), - ('u', _DEBUG_EVENT_UNION_), + ("dwDebugEventCode", DWORD), + ("dwProcessId", DWORD), + ("dwThreadId", DWORD), + ("u", _DEBUG_EVENT_UNION_), ] + + LPDEBUG_EVENT = POINTER(DEBUG_EVENT) -#--- Console API defines and structures --------------------------------------- +# --- Console API defines and structures --------------------------------------- FOREGROUND_MASK = 0x000F BACKGROUND_MASK = 0x00F0 COMMON_LVB_MASK = 0xFF00 -FOREGROUND_BLACK = 0x0000 -FOREGROUND_BLUE = 0x0001 -FOREGROUND_GREEN = 0x0002 -FOREGROUND_CYAN = 0x0003 -FOREGROUND_RED = 0x0004 -FOREGROUND_MAGENTA = 0x0005 -FOREGROUND_YELLOW = 0x0006 -FOREGROUND_GREY = 0x0007 +FOREGROUND_BLACK = 0x0000 +FOREGROUND_BLUE = 0x0001 +FOREGROUND_GREEN = 0x0002 +FOREGROUND_CYAN = 0x0003 +FOREGROUND_RED = 0x0004 +FOREGROUND_MAGENTA = 0x0005 +FOREGROUND_YELLOW = 0x0006 +FOREGROUND_GREY = 0x0007 FOREGROUND_INTENSITY = 0x0008 -BACKGROUND_BLACK = 0x0000 -BACKGROUND_BLUE = 0x0010 -BACKGROUND_GREEN = 0x0020 -BACKGROUND_CYAN = 0x0030 -BACKGROUND_RED = 0x0040 -BACKGROUND_MAGENTA = 0x0050 -BACKGROUND_YELLOW = 0x0060 -BACKGROUND_GREY = 0x0070 +BACKGROUND_BLACK = 0x0000 +BACKGROUND_BLUE = 0x0010 +BACKGROUND_GREEN = 0x0020 +BACKGROUND_CYAN = 0x0030 +BACKGROUND_RED = 0x0040 +BACKGROUND_MAGENTA = 0x0050 +BACKGROUND_YELLOW = 0x0060 +BACKGROUND_GREY = 0x0070 BACKGROUND_INTENSITY = 0x0080 -COMMON_LVB_LEADING_BYTE = 0x0100 -COMMON_LVB_TRAILING_BYTE = 0x0200 +COMMON_LVB_LEADING_BYTE = 0x0100 +COMMON_LVB_TRAILING_BYTE = 0x0200 COMMON_LVB_GRID_HORIZONTAL = 0x0400 -COMMON_LVB_GRID_LVERTICAL = 0x0800 -COMMON_LVB_GRID_RVERTICAL = 0x1000 -COMMON_LVB_REVERSE_VIDEO = 0x4000 -COMMON_LVB_UNDERSCORE = 0x8000 +COMMON_LVB_GRID_LVERTICAL = 0x0800 +COMMON_LVB_GRID_RVERTICAL = 0x1000 +COMMON_LVB_REVERSE_VIDEO = 0x4000 +COMMON_LVB_UNDERSCORE = 0x8000 + # typedef struct _CHAR_INFO { # union { @@ -1916,27 +1965,35 @@ class DEBUG_EVENT(Structure): # } CHAR_INFO, *PCHAR_INFO; class _CHAR_INFO_CHAR(Union): _fields_ = [ - ('UnicodeChar', WCHAR), - ('AsciiChar', CHAR), + ("UnicodeChar", WCHAR), + ("AsciiChar", CHAR), ] + + class CHAR_INFO(Structure): _fields_ = [ - ('Char', _CHAR_INFO_CHAR), - ('Attributes', WORD), - ] + ("Char", _CHAR_INFO_CHAR), + ("Attributes", WORD), + ] + + PCHAR_INFO = POINTER(CHAR_INFO) + # typedef struct _COORD { # SHORT X; # SHORT Y; # } COORD, *PCOORD; class COORD(Structure): _fields_ = [ - ('X', SHORT), - ('Y', SHORT), + ("X", SHORT), + ("Y", SHORT), ] + + PCOORD = POINTER(COORD) + # typedef struct _SMALL_RECT { # SHORT Left; # SHORT Top; @@ -1945,13 +2002,16 @@ class COORD(Structure): # } SMALL_RECT; class SMALL_RECT(Structure): _fields_ = [ - ('Left', SHORT), - ('Top', SHORT), - ('Right', SHORT), - ('Bottom', SHORT), + ("Left", SHORT), + ("Top", SHORT), + ("Right", SHORT), + ("Bottom", SHORT), ] + + PSMALL_RECT = POINTER(SMALL_RECT) + # typedef struct _CONSOLE_SCREEN_BUFFER_INFO { # COORD dwSize; # COORD dwCursorPosition; @@ -1961,22 +2021,25 @@ class SMALL_RECT(Structure): # } CONSOLE_SCREEN_BUFFER_INFO; class CONSOLE_SCREEN_BUFFER_INFO(Structure): _fields_ = [ - ('dwSize', COORD), - ('dwCursorPosition', COORD), - ('wAttributes', WORD), - ('srWindow', SMALL_RECT), - ('dwMaximumWindowSize', COORD), + ("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", WORD), + ("srWindow", SMALL_RECT), + ("dwMaximumWindowSize", COORD), ] + + PCONSOLE_SCREEN_BUFFER_INFO = POINTER(CONSOLE_SCREEN_BUFFER_INFO) -#--- Toolhelp library defines and structures ---------------------------------- +# --- Toolhelp library defines and structures ---------------------------------- TH32CS_SNAPHEAPLIST = 0x00000001 -TH32CS_SNAPPROCESS = 0x00000002 -TH32CS_SNAPTHREAD = 0x00000004 -TH32CS_SNAPMODULE = 0x00000008 -TH32CS_INHERIT = 0x80000000 -TH32CS_SNAPALL = (TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE) +TH32CS_SNAPPROCESS = 0x00000002 +TH32CS_SNAPTHREAD = 0x00000004 +TH32CS_SNAPMODULE = 0x00000008 +TH32CS_INHERIT = 0x80000000 +TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD | TH32CS_SNAPMODULE + # typedef struct tagTHREADENTRY32 { # DWORD dwSize; @@ -1989,16 +2052,19 @@ class CONSOLE_SCREEN_BUFFER_INFO(Structure): # } THREADENTRY32, *PTHREADENTRY32; class THREADENTRY32(Structure): _fields_ = [ - ('dwSize', DWORD), - ('cntUsage', DWORD), - ('th32ThreadID', DWORD), - ('th32OwnerProcessID', DWORD), - ('tpBasePri', LONG), - ('tpDeltaPri', LONG), - ('dwFlags', DWORD), + ("dwSize", DWORD), + ("cntUsage", DWORD), + ("th32ThreadID", DWORD), + ("th32OwnerProcessID", DWORD), + ("tpBasePri", LONG), + ("tpDeltaPri", LONG), + ("dwFlags", DWORD), ] + + LPTHREADENTRY32 = POINTER(THREADENTRY32) + # typedef struct tagPROCESSENTRY32 { # DWORD dwSize; # DWORD cntUsage; @@ -2013,19 +2079,22 @@ class THREADENTRY32(Structure): # } PROCESSENTRY32, *PPROCESSENTRY32; class PROCESSENTRY32(Structure): _fields_ = [ - ('dwSize', DWORD), - ('cntUsage', DWORD), - ('th32ProcessID', DWORD), - ('th32DefaultHeapID', ULONG_PTR), - ('th32ModuleID', DWORD), - ('cntThreads', DWORD), - ('th32ParentProcessID', DWORD), - ('pcPriClassBase', LONG), - ('dwFlags', DWORD), - ('szExeFile', TCHAR * 260), + ("dwSize", DWORD), + ("cntUsage", DWORD), + ("th32ProcessID", DWORD), + ("th32DefaultHeapID", ULONG_PTR), + ("th32ModuleID", DWORD), + ("cntThreads", DWORD), + ("th32ParentProcessID", DWORD), + ("pcPriClassBase", LONG), + ("dwFlags", DWORD), + ("szExeFile", TCHAR * 260), ] + + LPPROCESSENTRY32 = POINTER(PROCESSENTRY32) + # typedef struct tagMODULEENTRY32 { # DWORD dwSize; # DWORD th32ModuleID; @@ -2040,19 +2109,22 @@ class PROCESSENTRY32(Structure): # } MODULEENTRY32, *PMODULEENTRY32; class MODULEENTRY32(Structure): _fields_ = [ - ("dwSize", DWORD), - ("th32ModuleID", DWORD), + ("dwSize", DWORD), + ("th32ModuleID", DWORD), ("th32ProcessID", DWORD), - ("GlblcntUsage", DWORD), - ("ProccntUsage", DWORD), - ("modBaseAddr", LPVOID), # BYTE* - ("modBaseSize", DWORD), - ("hModule", HMODULE), - ("szModule", TCHAR * (MAX_MODULE_NAME32 + 1)), - ("szExePath", TCHAR * MAX_PATH), + ("GlblcntUsage", DWORD), + ("ProccntUsage", DWORD), + ("modBaseAddr", LPVOID), # BYTE* + ("modBaseSize", DWORD), + ("hModule", HMODULE), + ("szModule", TCHAR * (MAX_MODULE_NAME32 + 1)), + ("szExePath", TCHAR * MAX_PATH), ] + + LPMODULEENTRY32 = POINTER(MODULEENTRY32) + # typedef struct tagHEAPENTRY32 { # SIZE_T dwSize; # HANDLE hHandle; @@ -2067,18 +2139,21 @@ class MODULEENTRY32(Structure): # *PHEAPENTRY32; class HEAPENTRY32(Structure): _fields_ = [ - ("dwSize", SIZE_T), - ("hHandle", HANDLE), - ("dwAddress", ULONG_PTR), - ("dwBlockSize", SIZE_T), - ("dwFlags", DWORD), - ("dwLockCount", DWORD), - ("dwResvd", DWORD), - ("th32ProcessID", DWORD), - ("th32HeapID", ULONG_PTR), -] + ("dwSize", SIZE_T), + ("hHandle", HANDLE), + ("dwAddress", ULONG_PTR), + ("dwBlockSize", SIZE_T), + ("dwFlags", DWORD), + ("dwLockCount", DWORD), + ("dwResvd", DWORD), + ("th32ProcessID", DWORD), + ("th32HeapID", ULONG_PTR), + ] + + LPHEAPENTRY32 = POINTER(HEAPENTRY32) + # typedef struct tagHEAPLIST32 { # SIZE_T dwSize; # DWORD th32ProcessID; @@ -2088,54 +2163,62 @@ class HEAPENTRY32(Structure): # *PHEAPLIST32; class HEAPLIST32(Structure): _fields_ = [ - ("dwSize", SIZE_T), - ("th32ProcessID", DWORD), - ("th32HeapID", ULONG_PTR), - ("dwFlags", DWORD), -] + ("dwSize", SIZE_T), + ("th32ProcessID", DWORD), + ("th32HeapID", ULONG_PTR), + ("dwFlags", DWORD), + ] + + LPHEAPLIST32 = POINTER(HEAPLIST32) -#--- kernel32.dll ------------------------------------------------------------- +# --- kernel32.dll ------------------------------------------------------------- + # DWORD WINAPI GetLastError(void); def GetLastError(): _GetLastError = windll.kernel32.GetLastError _GetLastError.argtypes = [] - _GetLastError.restype = DWORD + _GetLastError.restype = DWORD return _GetLastError() + # void WINAPI SetLastError( # __in DWORD dwErrCode # ); def SetLastError(dwErrCode): _SetLastError = windll.kernel32.SetLastError _SetLastError.argtypes = [DWORD] - _SetLastError.restype = None + _SetLastError.restype = None _SetLastError(dwErrCode) + # UINT WINAPI GetErrorMode(void); def GetErrorMode(): _GetErrorMode = windll.kernel32.GetErrorMode _GetErrorMode.argtypes = [] - _GetErrorMode.restype = UINT + _GetErrorMode.restype = UINT return _GetErrorMode() + # UINT WINAPI SetErrorMode( # __in UINT uMode # ); def SetErrorMode(uMode): _SetErrorMode = windll.kernel32.SetErrorMode _SetErrorMode.argtypes = [UINT] - _SetErrorMode.restype = UINT + _SetErrorMode.restype = UINT return _SetErrorMode(dwErrCode) + # DWORD GetThreadErrorMode(void); def GetThreadErrorMode(): _GetThreadErrorMode = windll.kernel32.GetThreadErrorMode _GetThreadErrorMode.argtypes = [] - _GetThreadErrorMode.restype = DWORD + _GetThreadErrorMode.restype = DWORD return _GetThreadErrorMode() + # BOOL SetThreadErrorMode( # __in DWORD dwNewMode, # __out LPDWORD lpOldMode @@ -2143,13 +2226,14 @@ def GetThreadErrorMode(): def SetThreadErrorMode(dwNewMode): _SetThreadErrorMode = windll.kernel32.SetThreadErrorMode _SetThreadErrorMode.argtypes = [DWORD, LPDWORD] - _SetThreadErrorMode.restype = BOOL + _SetThreadErrorMode.restype = BOOL _SetThreadErrorMode.errcheck = RaiseIfZero old = DWORD(0) _SetThreadErrorMode(dwErrCode, byref(old)) return old.value + # BOOL WINAPI CloseHandle( # __in HANDLE hObject # ); @@ -2160,10 +2244,11 @@ def CloseHandle(hHandle): else: _CloseHandle = windll.kernel32.CloseHandle _CloseHandle.argtypes = [HANDLE] - _CloseHandle.restype = bool + _CloseHandle.restype = bool _CloseHandle.errcheck = RaiseIfZero _CloseHandle(hHandle) + # BOOL WINAPI DuplicateHandle( # __in HANDLE hSourceProcessHandle, # __in HANDLE hSourceHandle, @@ -2173,10 +2258,17 @@ def CloseHandle(hHandle): # __in BOOL bInheritHandle, # __in DWORD dwOptions # ); -def DuplicateHandle(hSourceHandle, hSourceProcessHandle = None, hTargetProcessHandle = None, dwDesiredAccess = STANDARD_RIGHTS_ALL, bInheritHandle = False, dwOptions = DUPLICATE_SAME_ACCESS): +def DuplicateHandle( + hSourceHandle, + hSourceProcessHandle=None, + hTargetProcessHandle=None, + dwDesiredAccess=STANDARD_RIGHTS_ALL, + bInheritHandle=False, + dwOptions=DUPLICATE_SAME_ACCESS, +): _DuplicateHandle = windll.kernel32.DuplicateHandle _DuplicateHandle.argtypes = [HANDLE, HANDLE, HANDLE, LPHANDLE, DWORD, BOOL, DWORD] - _DuplicateHandle.restype = bool + _DuplicateHandle.restype = bool _DuplicateHandle.errcheck = RaiseIfZero # NOTE: the arguments to this function are in a different order, @@ -2187,40 +2279,46 @@ def DuplicateHandle(hSourceHandle, hSourceProcessHandle = None, hTargetProcessHa if hTargetProcessHandle is None: hTargetProcessHandle = hSourceProcessHandle lpTargetHandle = HANDLE(INVALID_HANDLE_VALUE) - _DuplicateHandle(hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, byref(lpTargetHandle), dwDesiredAccess, bool(bInheritHandle), dwOptions) + _DuplicateHandle( + hSourceProcessHandle, hSourceHandle, hTargetProcessHandle, byref(lpTargetHandle), dwDesiredAccess, bool(bInheritHandle), dwOptions + ) if isinstance(hSourceHandle, Handle): HandleClass = hSourceHandle.__class__ else: HandleClass = Handle - if hasattr(hSourceHandle, 'dwAccess'): - return HandleClass(lpTargetHandle.value, dwAccess = hSourceHandle.dwAccess) + if hasattr(hSourceHandle, "dwAccess"): + return HandleClass(lpTargetHandle.value, dwAccess=hSourceHandle.dwAccess) else: return HandleClass(lpTargetHandle.value) + # HLOCAL WINAPI LocalFree( # __in HLOCAL hMem # ); def LocalFree(hMem): _LocalFree = windll.kernel32.LocalFree _LocalFree.argtypes = [HLOCAL] - _LocalFree.restype = HLOCAL + _LocalFree.restype = HLOCAL result = _LocalFree(hMem) if result != NULL: ctypes.WinError() -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # Console API + # HANDLE WINAPI GetStdHandle( # _In_ DWORD nStdHandle # ); def GetStdHandle(nStdHandle): _GetStdHandle = windll.kernel32.GetStdHandle _GetStdHandle.argytpes = [DWORD] - _GetStdHandle.restype = HANDLE + _GetStdHandle.restype = HANDLE _GetStdHandle.errcheck = RaiseIfZero - return Handle( _GetStdHandle(nStdHandle), bOwnership = False ) + return Handle(_GetStdHandle(nStdHandle), bOwnership=False) + # BOOL WINAPI SetStdHandle( # _In_ DWORD nStdHandle, @@ -2229,40 +2327,45 @@ def GetStdHandle(nStdHandle): # TODO + # UINT WINAPI GetConsoleCP(void); def GetConsoleCP(): _GetConsoleCP = windll.kernel32.GetConsoleCP _GetConsoleCP.argytpes = [] - _GetConsoleCP.restype = UINT + _GetConsoleCP.restype = UINT return _GetConsoleCP() + # UINT WINAPI GetConsoleOutputCP(void); def GetConsoleOutputCP(): _GetConsoleOutputCP = windll.kernel32.GetConsoleOutputCP _GetConsoleOutputCP.argytpes = [] - _GetConsoleOutputCP.restype = UINT + _GetConsoleOutputCP.restype = UINT return _GetConsoleOutputCP() -#BOOL WINAPI SetConsoleCP( + +# BOOL WINAPI SetConsoleCP( # _In_ UINT wCodePageID -#); +# ); def SetConsoleCP(wCodePageID): _SetConsoleCP = windll.kernel32.SetConsoleCP _SetConsoleCP.argytpes = [UINT] - _SetConsoleCP.restype = bool + _SetConsoleCP.restype = bool _SetConsoleCP.errcheck = RaiseIfZero _SetConsoleCP(wCodePageID) -#BOOL WINAPI SetConsoleOutputCP( + +# BOOL WINAPI SetConsoleOutputCP( # _In_ UINT wCodePageID -#); +# ); def SetConsoleOutputCP(wCodePageID): _SetConsoleOutputCP = windll.kernel32.SetConsoleOutputCP _SetConsoleOutputCP.argytpes = [UINT] - _SetConsoleOutputCP.restype = bool + _SetConsoleOutputCP.restype = bool _SetConsoleOutputCP.errcheck = RaiseIfZero _SetConsoleOutputCP(wCodePageID) + # HANDLE WINAPI CreateConsoleScreenBuffer( # _In_ DWORD dwDesiredAccess, # _In_ DWORD dwShareMode, @@ -2273,27 +2376,29 @@ def SetConsoleOutputCP(wCodePageID): # TODO + # BOOL WINAPI SetConsoleActiveScreenBuffer( # _In_ HANDLE hConsoleOutput # ); -def SetConsoleActiveScreenBuffer(hConsoleOutput = None): +def SetConsoleActiveScreenBuffer(hConsoleOutput=None): _SetConsoleActiveScreenBuffer = windll.kernel32.SetConsoleActiveScreenBuffer _SetConsoleActiveScreenBuffer.argytpes = [HANDLE] - _SetConsoleActiveScreenBuffer.restype = bool + _SetConsoleActiveScreenBuffer.restype = bool _SetConsoleActiveScreenBuffer.errcheck = RaiseIfZero if hConsoleOutput is None: hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE) _SetConsoleActiveScreenBuffer(hConsoleOutput) + # BOOL WINAPI GetConsoleScreenBufferInfo( # _In_ HANDLE hConsoleOutput, # _Out_ PCONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo # ); -def GetConsoleScreenBufferInfo(hConsoleOutput = None): +def GetConsoleScreenBufferInfo(hConsoleOutput=None): _GetConsoleScreenBufferInfo = windll.kernel32.GetConsoleScreenBufferInfo _GetConsoleScreenBufferInfo.argytpes = [HANDLE, PCONSOLE_SCREEN_BUFFER_INFO] - _GetConsoleScreenBufferInfo.restype = bool + _GetConsoleScreenBufferInfo.restype = bool _GetConsoleScreenBufferInfo.errcheck = RaiseIfZero if hConsoleOutput is None: @@ -2302,6 +2407,7 @@ def GetConsoleScreenBufferInfo(hConsoleOutput = None): _GetConsoleScreenBufferInfo(hConsoleOutput, byref(ConsoleScreenBufferInfo)) return ConsoleScreenBufferInfo + # BOOL WINAPI GetConsoleScreenBufferInfoEx( # _In_ HANDLE hConsoleOutput, # _Out_ PCONSOLE_SCREEN_BUFFER_INFOEX lpConsoleScreenBufferInfoEx @@ -2309,6 +2415,7 @@ def GetConsoleScreenBufferInfo(hConsoleOutput = None): # TODO + # BOOL WINAPI SetConsoleWindowInfo( # _In_ HANDLE hConsoleOutput, # _In_ BOOL bAbsolute, @@ -2317,7 +2424,7 @@ def GetConsoleScreenBufferInfo(hConsoleOutput = None): def SetConsoleWindowInfo(hConsoleOutput, bAbsolute, lpConsoleWindow): _SetConsoleWindowInfo = windll.kernel32.SetConsoleWindowInfo _SetConsoleWindowInfo.argytpes = [HANDLE, BOOL, PSMALL_RECT] - _SetConsoleWindowInfo.restype = bool + _SetConsoleWindowInfo.restype = bool _SetConsoleWindowInfo.errcheck = RaiseIfZero if hConsoleOutput is None: @@ -2328,20 +2435,22 @@ def SetConsoleWindowInfo(hConsoleOutput, bAbsolute, lpConsoleWindow): ConsoleWindow = SMALL_RECT(*lpConsoleWindow) _SetConsoleWindowInfo(hConsoleOutput, bAbsolute, byref(ConsoleWindow)) + # BOOL WINAPI SetConsoleTextAttribute( # _In_ HANDLE hConsoleOutput, # _In_ WORD wAttributes # ); -def SetConsoleTextAttribute(hConsoleOutput = None, wAttributes = 0): +def SetConsoleTextAttribute(hConsoleOutput=None, wAttributes=0): _SetConsoleTextAttribute = windll.kernel32.SetConsoleTextAttribute _SetConsoleTextAttribute.argytpes = [HANDLE, WORD] - _SetConsoleTextAttribute.restype = bool + _SetConsoleTextAttribute.restype = bool _SetConsoleTextAttribute.errcheck = RaiseIfZero if hConsoleOutput is None: hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE) _SetConsoleTextAttribute(hConsoleOutput, wAttributes) + # HANDLE WINAPI CreateConsoleScreenBuffer( # _In_ DWORD dwDesiredAccess, # _In_ DWORD dwShareMode, @@ -2352,32 +2461,36 @@ def SetConsoleTextAttribute(hConsoleOutput = None, wAttributes = 0): # TODO + # BOOL WINAPI AllocConsole(void); def AllocConsole(): _AllocConsole = windll.kernel32.AllocConsole _AllocConsole.argytpes = [] - _AllocConsole.restype = bool + _AllocConsole.restype = bool _AllocConsole.errcheck = RaiseIfZero _AllocConsole() + # BOOL WINAPI AttachConsole( # _In_ DWORD dwProcessId # ); -def AttachConsole(dwProcessId = ATTACH_PARENT_PROCESS): +def AttachConsole(dwProcessId=ATTACH_PARENT_PROCESS): _AttachConsole = windll.kernel32.AttachConsole _AttachConsole.argytpes = [DWORD] - _AttachConsole.restype = bool + _AttachConsole.restype = bool _AttachConsole.errcheck = RaiseIfZero _AttachConsole(dwProcessId) + # BOOL WINAPI FreeConsole(void); def FreeConsole(): _FreeConsole = windll.kernel32.FreeConsole _FreeConsole.argytpes = [] - _FreeConsole.restype = bool + _FreeConsole.restype = bool _FreeConsole.errcheck = RaiseIfZero _FreeConsole() + # DWORD WINAPI GetConsoleProcessList( # _Out_ LPDWORD lpdwProcessList, # _In_ DWORD dwProcessCount @@ -2392,9 +2505,9 @@ def FreeConsole(): # TODO -#BOOL WINAPI SetConsoleTitle( +# BOOL WINAPI SetConsoleTitle( # _In_ LPCTSTR lpConsoleTitle -#); +# ); # TODO @@ -2410,9 +2523,10 @@ def FreeConsole(): # TODO -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # DLL API + # DWORD WINAPI GetDllDirectory( # __in DWORD nBufferLength, # __out LPTSTR lpBuffer @@ -2420,7 +2534,7 @@ def FreeConsole(): def GetDllDirectoryA(): _GetDllDirectoryA = windll.kernel32.GetDllDirectoryA _GetDllDirectoryA.argytpes = [DWORD, LPSTR] - _GetDllDirectoryA.restype = DWORD + _GetDllDirectoryA.restype = DWORD nBufferLength = _GetDllDirectoryA(0, None) if nBufferLength == 0: @@ -2429,110 +2543,125 @@ def GetDllDirectoryA(): _GetDllDirectoryA(nBufferLength, byref(lpBuffer)) return lpBuffer.value + def GetDllDirectoryW(): _GetDllDirectoryW = windll.kernel32.GetDllDirectoryW _GetDllDirectoryW.argytpes = [DWORD, LPWSTR] - _GetDllDirectoryW.restype = DWORD + _GetDllDirectoryW.restype = DWORD nBufferLength = _GetDllDirectoryW(0, None) if nBufferLength == 0: return None - lpBuffer = ctypes.create_unicode_buffer(u"", nBufferLength) + lpBuffer = ctypes.create_unicode_buffer("", nBufferLength) _GetDllDirectoryW(nBufferLength, byref(lpBuffer)) return lpBuffer.value + GetDllDirectory = GuessStringType(GetDllDirectoryA, GetDllDirectoryW) + # BOOL WINAPI SetDllDirectory( # __in_opt LPCTSTR lpPathName # ); -def SetDllDirectoryA(lpPathName = None): +def SetDllDirectoryA(lpPathName=None): _SetDllDirectoryA = windll.kernel32.SetDllDirectoryA _SetDllDirectoryA.argytpes = [LPSTR] - _SetDllDirectoryA.restype = bool + _SetDllDirectoryA.restype = bool _SetDllDirectoryA.errcheck = RaiseIfZero _SetDllDirectoryA(lpPathName) + def SetDllDirectoryW(lpPathName): _SetDllDirectoryW = windll.kernel32.SetDllDirectoryW _SetDllDirectoryW.argytpes = [LPWSTR] - _SetDllDirectoryW.restype = bool + _SetDllDirectoryW.restype = bool _SetDllDirectoryW.errcheck = RaiseIfZero _SetDllDirectoryW(lpPathName) + SetDllDirectory = GuessStringType(SetDllDirectoryA, SetDllDirectoryW) + # HMODULE WINAPI LoadLibrary( # __in LPCTSTR lpFileName # ); def LoadLibraryA(pszLibrary): _LoadLibraryA = windll.kernel32.LoadLibraryA _LoadLibraryA.argtypes = [LPSTR] - _LoadLibraryA.restype = HMODULE + _LoadLibraryA.restype = HMODULE hModule = _LoadLibraryA(pszLibrary) if hModule == NULL: raise ctypes.WinError() return hModule + def LoadLibraryW(pszLibrary): _LoadLibraryW = windll.kernel32.LoadLibraryW _LoadLibraryW.argtypes = [LPWSTR] - _LoadLibraryW.restype = HMODULE + _LoadLibraryW.restype = HMODULE hModule = _LoadLibraryW(pszLibrary) if hModule == NULL: raise ctypes.WinError() return hModule + LoadLibrary = GuessStringType(LoadLibraryA, LoadLibraryW) + # HMODULE WINAPI LoadLibraryEx( # __in LPCTSTR lpFileName, # __reserved HANDLE hFile, # __in DWORD dwFlags # ); -def LoadLibraryExA(pszLibrary, dwFlags = 0): +def LoadLibraryExA(pszLibrary, dwFlags=0): _LoadLibraryExA = windll.kernel32.LoadLibraryExA _LoadLibraryExA.argtypes = [LPSTR, HANDLE, DWORD] - _LoadLibraryExA.restype = HMODULE + _LoadLibraryExA.restype = HMODULE hModule = _LoadLibraryExA(pszLibrary, NULL, dwFlags) if hModule == NULL: raise ctypes.WinError() return hModule -def LoadLibraryExW(pszLibrary, dwFlags = 0): + +def LoadLibraryExW(pszLibrary, dwFlags=0): _LoadLibraryExW = windll.kernel32.LoadLibraryExW _LoadLibraryExW.argtypes = [LPWSTR, HANDLE, DWORD] - _LoadLibraryExW.restype = HMODULE + _LoadLibraryExW.restype = HMODULE hModule = _LoadLibraryExW(pszLibrary, NULL, dwFlags) if hModule == NULL: raise ctypes.WinError() return hModule + LoadLibraryEx = GuessStringType(LoadLibraryExA, LoadLibraryExW) + # HMODULE WINAPI GetModuleHandle( # __in_opt LPCTSTR lpModuleName # ); def GetModuleHandleA(lpModuleName): _GetModuleHandleA = windll.kernel32.GetModuleHandleA _GetModuleHandleA.argtypes = [LPSTR] - _GetModuleHandleA.restype = HMODULE + _GetModuleHandleA.restype = HMODULE hModule = _GetModuleHandleA(lpModuleName) if hModule == NULL: raise ctypes.WinError() return hModule + def GetModuleHandleW(lpModuleName): _GetModuleHandleW = windll.kernel32.GetModuleHandleW _GetModuleHandleW.argtypes = [LPWSTR] - _GetModuleHandleW.restype = HMODULE + _GetModuleHandleW.restype = HMODULE hModule = _GetModuleHandleW(lpModuleName) if hModule == NULL: raise ctypes.WinError() return hModule + GetModuleHandle = GuessStringType(GetModuleHandleA, GetModuleHandleW) + # FARPROC WINAPI GetProcAddress( # __in HMODULE hModule, # __in LPCSTR lpProcName @@ -2540,31 +2669,34 @@ def GetModuleHandleW(lpModuleName): def GetProcAddressA(hModule, lpProcName): _GetProcAddress = windll.kernel32.GetProcAddress _GetProcAddress.argtypes = [HMODULE, LPVOID] - _GetProcAddress.restype = LPVOID + _GetProcAddress.restype = LPVOID if type(lpProcName) in (type(0), type(long(0))): lpProcName = LPVOID(lpProcName) if lpProcName.value & (~0xFFFF): - raise ValueError('Ordinal number too large: %d' % lpProcName.value) + raise ValueError("Ordinal number too large: %d" % lpProcName.value) elif type(lpProcName) == type(compat.b("")): lpProcName = ctypes.c_char_p(lpProcName) else: raise TypeError(str(type(lpProcName))) return _GetProcAddress(hModule, lpProcName) + GetProcAddressW = MakeWideVersion(GetProcAddressA) GetProcAddress = GuessStringType(GetProcAddressA, GetProcAddressW) + # BOOL WINAPI FreeLibrary( # __in HMODULE hModule # ); def FreeLibrary(hModule): _FreeLibrary = windll.kernel32.FreeLibrary _FreeLibrary.argtypes = [HMODULE] - _FreeLibrary.restype = bool + _FreeLibrary.restype = bool _FreeLibrary.errcheck = RaiseIfZero _FreeLibrary(hModule) + # PVOID WINAPI RtlPcToFileHeader( # __in PVOID PcValue, # __out PVOID *BaseOfImage @@ -2572,15 +2704,17 @@ def FreeLibrary(hModule): def RtlPcToFileHeader(PcValue): _RtlPcToFileHeader = windll.kernel32.RtlPcToFileHeader _RtlPcToFileHeader.argtypes = [PVOID, POINTER(PVOID)] - _RtlPcToFileHeader.restype = PRUNTIME_FUNCTION + _RtlPcToFileHeader.restype = PRUNTIME_FUNCTION BaseOfImage = PVOID(0) _RtlPcToFileHeader(PcValue, byref(BaseOfImage)) return BaseOfImage.value -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # File API and related + # BOOL WINAPI GetHandleInformation( # __in HANDLE hObject, # __out LPDWORD lpdwFlags @@ -2588,13 +2722,14 @@ def RtlPcToFileHeader(PcValue): def GetHandleInformation(hObject): _GetHandleInformation = windll.kernel32.GetHandleInformation _GetHandleInformation.argtypes = [HANDLE, PDWORD] - _GetHandleInformation.restype = bool + _GetHandleInformation.restype = bool _GetHandleInformation.errcheck = RaiseIfZero dwFlags = DWORD(0) _GetHandleInformation(hObject, byref(dwFlags)) return dwFlags.value + # BOOL WINAPI SetHandleInformation( # __in HANDLE hObject, # __in DWORD dwMask, @@ -2603,10 +2738,11 @@ def GetHandleInformation(hObject): def SetHandleInformation(hObject, dwMask, dwFlags): _SetHandleInformation = windll.kernel32.SetHandleInformation _SetHandleInformation.argtypes = [HANDLE, DWORD, DWORD] - _SetHandleInformation.restype = bool + _SetHandleInformation.restype = bool _SetHandleInformation.errcheck = RaiseIfZero _SetHandleInformation(hObject, dwMask, dwFlags) + # UINT WINAPI GetWindowModuleFileName( # __in HWND hwnd, # __out LPTSTR lpszFileName, @@ -2615,21 +2751,22 @@ def SetHandleInformation(hObject, dwMask, dwFlags): # Not included because it doesn't work in other processes. # See: http://support.microsoft.com/?id=228469 + # BOOL WINAPI QueryFullProcessImageName( # __in HANDLE hProcess, # __in DWORD dwFlags, # __out LPTSTR lpExeName, # __inout PDWORD lpdwSize # ); -def QueryFullProcessImageNameA(hProcess, dwFlags = 0): +def QueryFullProcessImageNameA(hProcess, dwFlags=0): _QueryFullProcessImageNameA = windll.kernel32.QueryFullProcessImageNameA _QueryFullProcessImageNameA.argtypes = [HANDLE, DWORD, LPSTR, PDWORD] - _QueryFullProcessImageNameA.restype = bool + _QueryFullProcessImageNameA.restype = bool dwSize = MAX_PATH while 1: lpdwSize = DWORD(dwSize) - lpExeName = ctypes.create_string_buffer('', lpdwSize.value + 1) + lpExeName = ctypes.create_string_buffer("", lpdwSize.value + 1) success = _QueryFullProcessImageNameA(hProcess, dwFlags, lpExeName, byref(lpdwSize)) if success and 0 < lpdwSize.value < dwSize: break @@ -2643,15 +2780,16 @@ def QueryFullProcessImageNameA(hProcess, dwFlags = 0): raise ctypes.WinError(error) return lpExeName.value -def QueryFullProcessImageNameW(hProcess, dwFlags = 0): + +def QueryFullProcessImageNameW(hProcess, dwFlags=0): _QueryFullProcessImageNameW = windll.kernel32.QueryFullProcessImageNameW _QueryFullProcessImageNameW.argtypes = [HANDLE, DWORD, LPWSTR, PDWORD] - _QueryFullProcessImageNameW.restype = bool + _QueryFullProcessImageNameW.restype = bool dwSize = MAX_PATH while 1: lpdwSize = DWORD(dwSize) - lpExeName = ctypes.create_unicode_buffer('', lpdwSize.value + 1) + lpExeName = ctypes.create_unicode_buffer("", lpdwSize.value + 1) success = _QueryFullProcessImageNameW(hProcess, dwFlags, lpExeName, byref(lpdwSize)) if success and 0 < lpdwSize.value < dwSize: break @@ -2665,8 +2803,10 @@ def QueryFullProcessImageNameW(hProcess, dwFlags = 0): raise ctypes.WinError(error) return lpExeName.value + QueryFullProcessImageName = GuessStringType(QueryFullProcessImageNameA, QueryFullProcessImageNameW) + # DWORD WINAPI GetLogicalDriveStrings( # __in DWORD nBufferLength, # __out LPTSTR lpBuffer @@ -2674,43 +2814,45 @@ def QueryFullProcessImageNameW(hProcess, dwFlags = 0): def GetLogicalDriveStringsA(): _GetLogicalDriveStringsA = ctypes.windll.kernel32.GetLogicalDriveStringsA _GetLogicalDriveStringsA.argtypes = [DWORD, LPSTR] - _GetLogicalDriveStringsA.restype = DWORD + _GetLogicalDriveStringsA.restype = DWORD _GetLogicalDriveStringsA.errcheck = RaiseIfZero - nBufferLength = (4 * 26) + 1 # "X:\\\0" from A to Z plus empty string - lpBuffer = ctypes.create_string_buffer('', nBufferLength) + nBufferLength = (4 * 26) + 1 # "X:\\\0" from A to Z plus empty string + lpBuffer = ctypes.create_string_buffer("", nBufferLength) _GetLogicalDriveStringsA(nBufferLength, lpBuffer) drive_strings = list() string_p = addressof(lpBuffer) sizeof_char = sizeof(ctypes.c_char) while True: string_v = ctypes.string_at(string_p) - if string_v == '': + if string_v == "": break drive_strings.append(string_v) string_p += len(string_v) + sizeof_char return drive_strings + def GetLogicalDriveStringsW(): _GetLogicalDriveStringsW = ctypes.windll.kernel32.GetLogicalDriveStringsW _GetLogicalDriveStringsW.argtypes = [DWORD, LPWSTR] - _GetLogicalDriveStringsW.restype = DWORD + _GetLogicalDriveStringsW.restype = DWORD _GetLogicalDriveStringsW.errcheck = RaiseIfZero - nBufferLength = (4 * 26) + 1 # "X:\\\0" from A to Z plus empty string - lpBuffer = ctypes.create_unicode_buffer(u'', nBufferLength) + nBufferLength = (4 * 26) + 1 # "X:\\\0" from A to Z plus empty string + lpBuffer = ctypes.create_unicode_buffer("", nBufferLength) _GetLogicalDriveStringsW(nBufferLength, lpBuffer) drive_strings = list() string_p = addressof(lpBuffer) sizeof_wchar = sizeof(ctypes.c_wchar) while True: string_v = ctypes.wstring_at(string_p) - if string_v == u'': + if string_v == "": break drive_strings.append(string_v) string_p += (len(string_v) * sizeof_wchar) + sizeof_wchar return drive_strings + ##def GetLogicalDriveStringsA(): ## _GetLogicalDriveStringsA = windll.kernel32.GetLogicalDriveStringsA ## _GetLogicalDriveStringsA.argtypes = [DWORD, LPSTR] @@ -2761,39 +2903,43 @@ def GetLogicalDriveStringsW(): GetLogicalDriveStrings = GuessStringType(GetLogicalDriveStringsA, GetLogicalDriveStringsW) + # DWORD WINAPI QueryDosDevice( # __in_opt LPCTSTR lpDeviceName, # __out LPTSTR lpTargetPath, # __in DWORD ucchMax # ); -def QueryDosDeviceA(lpDeviceName = None): +def QueryDosDeviceA(lpDeviceName=None): _QueryDosDeviceA = windll.kernel32.QueryDosDeviceA _QueryDosDeviceA.argtypes = [LPSTR, LPSTR, DWORD] - _QueryDosDeviceA.restype = DWORD + _QueryDosDeviceA.restype = DWORD _QueryDosDeviceA.errcheck = RaiseIfZero if not lpDeviceName: lpDeviceName = None ucchMax = 0x1000 - lpTargetPath = ctypes.create_string_buffer('', ucchMax) + lpTargetPath = ctypes.create_string_buffer("", ucchMax) _QueryDosDeviceA(lpDeviceName, lpTargetPath, ucchMax) return lpTargetPath.value + def QueryDosDeviceW(lpDeviceName): _QueryDosDeviceW = windll.kernel32.QueryDosDeviceW _QueryDosDeviceW.argtypes = [LPWSTR, LPWSTR, DWORD] - _QueryDosDeviceW.restype = DWORD + _QueryDosDeviceW.restype = DWORD _QueryDosDeviceW.errcheck = RaiseIfZero if not lpDeviceName: lpDeviceName = None ucchMax = 0x1000 - lpTargetPath = ctypes.create_unicode_buffer(u'', ucchMax) + lpTargetPath = ctypes.create_unicode_buffer("", ucchMax) _QueryDosDeviceW(lpDeviceName, lpTargetPath, ucchMax) return lpTargetPath.value + QueryDosDevice = GuessStringType(QueryDosDeviceA, QueryDosDeviceW) + # LPVOID WINAPI MapViewOfFile( # __in HANDLE hFileMappingObject, # __in DWORD dwDesiredAccess, @@ -2801,25 +2947,33 @@ def QueryDosDeviceW(lpDeviceName): # __in DWORD dwFileOffsetLow, # __in SIZE_T dwNumberOfBytesToMap # ); -def MapViewOfFile(hFileMappingObject, dwDesiredAccess = FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, dwFileOffsetHigh = 0, dwFileOffsetLow = 0, dwNumberOfBytesToMap = 0): +def MapViewOfFile( + hFileMappingObject, + dwDesiredAccess=FILE_MAP_ALL_ACCESS | FILE_MAP_EXECUTE, + dwFileOffsetHigh=0, + dwFileOffsetLow=0, + dwNumberOfBytesToMap=0, +): _MapViewOfFile = windll.kernel32.MapViewOfFile _MapViewOfFile.argtypes = [HANDLE, DWORD, DWORD, DWORD, SIZE_T] - _MapViewOfFile.restype = LPVOID + _MapViewOfFile.restype = LPVOID lpBaseAddress = _MapViewOfFile(hFileMappingObject, dwDesiredAccess, dwFileOffsetHigh, dwFileOffsetLow, dwNumberOfBytesToMap) if lpBaseAddress == NULL: raise ctypes.WinError() return lpBaseAddress + # BOOL WINAPI UnmapViewOfFile( # __in LPCVOID lpBaseAddress # ); def UnmapViewOfFile(lpBaseAddress): _UnmapViewOfFile = windll.kernel32.UnmapViewOfFile _UnmapViewOfFile.argtypes = [LPVOID] - _UnmapViewOfFile.restype = bool + _UnmapViewOfFile.restype = bool _UnmapViewOfFile.errcheck = RaiseIfZero _UnmapViewOfFile(lpBaseAddress) + # HANDLE WINAPI OpenFileMapping( # __in DWORD dwDesiredAccess, # __in BOOL bInheritHandle, @@ -2828,21 +2982,24 @@ def UnmapViewOfFile(lpBaseAddress): def OpenFileMappingA(dwDesiredAccess, bInheritHandle, lpName): _OpenFileMappingA = windll.kernel32.OpenFileMappingA _OpenFileMappingA.argtypes = [DWORD, BOOL, LPSTR] - _OpenFileMappingA.restype = HANDLE + _OpenFileMappingA.restype = HANDLE _OpenFileMappingA.errcheck = RaiseIfZero hFileMappingObject = _OpenFileMappingA(dwDesiredAccess, bool(bInheritHandle), lpName) return FileMappingHandle(hFileMappingObject) + def OpenFileMappingW(dwDesiredAccess, bInheritHandle, lpName): _OpenFileMappingW = windll.kernel32.OpenFileMappingW _OpenFileMappingW.argtypes = [DWORD, BOOL, LPWSTR] - _OpenFileMappingW.restype = HANDLE + _OpenFileMappingW.restype = HANDLE _OpenFileMappingW.errcheck = RaiseIfZero hFileMappingObject = _OpenFileMappingW(dwDesiredAccess, bool(bInheritHandle), lpName) return FileMappingHandle(hFileMappingObject) + OpenFileMapping = GuessStringType(OpenFileMappingA, OpenFileMappingW) + # HANDLE WINAPI CreateFileMapping( # __in HANDLE hFile, # __in_opt LPSECURITY_ATTRIBUTES lpAttributes, @@ -2851,10 +3008,10 @@ def OpenFileMappingW(dwDesiredAccess, bInheritHandle, lpName): # __in DWORD dwMaximumSizeLow, # __in_opt LPCTSTR lpName # ); -def CreateFileMappingA(hFile, lpAttributes = None, flProtect = PAGE_EXECUTE_READWRITE, dwMaximumSizeHigh = 0, dwMaximumSizeLow = 0, lpName = None): +def CreateFileMappingA(hFile, lpAttributes=None, flProtect=PAGE_EXECUTE_READWRITE, dwMaximumSizeHigh=0, dwMaximumSizeLow=0, lpName=None): _CreateFileMappingA = windll.kernel32.CreateFileMappingA _CreateFileMappingA.argtypes = [HANDLE, LPVOID, DWORD, DWORD, DWORD, LPSTR] - _CreateFileMappingA.restype = HANDLE + _CreateFileMappingA.restype = HANDLE _CreateFileMappingA.errcheck = RaiseIfZero if lpAttributes: @@ -2864,10 +3021,11 @@ def CreateFileMappingA(hFile, lpAttributes = None, flProtect = PAGE_EXECUTE_READ hFileMappingObject = _CreateFileMappingA(hFile, lpAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName) return FileMappingHandle(hFileMappingObject) -def CreateFileMappingW(hFile, lpAttributes = None, flProtect = PAGE_EXECUTE_READWRITE, dwMaximumSizeHigh = 0, dwMaximumSizeLow = 0, lpName = None): + +def CreateFileMappingW(hFile, lpAttributes=None, flProtect=PAGE_EXECUTE_READWRITE, dwMaximumSizeHigh=0, dwMaximumSizeLow=0, lpName=None): _CreateFileMappingW = windll.kernel32.CreateFileMappingW _CreateFileMappingW.argtypes = [HANDLE, LPVOID, DWORD, DWORD, DWORD, LPWSTR] - _CreateFileMappingW.restype = HANDLE + _CreateFileMappingW.restype = HANDLE _CreateFileMappingW.errcheck = RaiseIfZero if lpAttributes: @@ -2877,8 +3035,10 @@ def CreateFileMappingW(hFile, lpAttributes = None, flProtect = PAGE_EXECUTE_READ hFileMappingObject = _CreateFileMappingW(hFile, lpAttributes, flProtect, dwMaximumSizeHigh, dwMaximumSizeLow, lpName) return FileMappingHandle(hFileMappingObject) + CreateFileMapping = GuessStringType(CreateFileMappingA, CreateFileMappingW) + # HANDLE WINAPI CreateFile( # __in LPCTSTR lpFileName, # __in DWORD dwDesiredAccess, @@ -2888,57 +3048,82 @@ def CreateFileMappingW(hFile, lpAttributes = None, flProtect = PAGE_EXECUTE_READ # __in DWORD dwFlagsAndAttributes, # __in_opt HANDLE hTemplateFile # ); -def CreateFileA(lpFileName, dwDesiredAccess = GENERIC_ALL, dwShareMode = 0, lpSecurityAttributes = None, dwCreationDisposition = OPEN_ALWAYS, dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, hTemplateFile = None): +def CreateFileA( + lpFileName, + dwDesiredAccess=GENERIC_ALL, + dwShareMode=0, + lpSecurityAttributes=None, + dwCreationDisposition=OPEN_ALWAYS, + dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL, + hTemplateFile=None, +): _CreateFileA = windll.kernel32.CreateFileA _CreateFileA.argtypes = [LPSTR, DWORD, DWORD, LPVOID, DWORD, DWORD, HANDLE] - _CreateFileA.restype = HANDLE + _CreateFileA.restype = HANDLE if not lpFileName: lpFileName = None if lpSecurityAttributes: lpSecurityAttributes = ctypes.pointer(lpSecurityAttributes) - hFile = _CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile) + hFile = _CreateFileA( + lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile + ) if hFile == INVALID_HANDLE_VALUE: raise ctypes.WinError() return FileHandle(hFile) -def CreateFileW(lpFileName, dwDesiredAccess = GENERIC_ALL, dwShareMode = 0, lpSecurityAttributes = None, dwCreationDisposition = OPEN_ALWAYS, dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, hTemplateFile = None): + +def CreateFileW( + lpFileName, + dwDesiredAccess=GENERIC_ALL, + dwShareMode=0, + lpSecurityAttributes=None, + dwCreationDisposition=OPEN_ALWAYS, + dwFlagsAndAttributes=FILE_ATTRIBUTE_NORMAL, + hTemplateFile=None, +): _CreateFileW = windll.kernel32.CreateFileW _CreateFileW.argtypes = [LPWSTR, DWORD, DWORD, LPVOID, DWORD, DWORD, HANDLE] - _CreateFileW.restype = HANDLE + _CreateFileW.restype = HANDLE if not lpFileName: lpFileName = None if lpSecurityAttributes: lpSecurityAttributes = ctypes.pointer(lpSecurityAttributes) - hFile = _CreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile) + hFile = _CreateFileW( + lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile + ) if hFile == INVALID_HANDLE_VALUE: raise ctypes.WinError() return FileHandle(hFile) + CreateFile = GuessStringType(CreateFileA, CreateFileW) + # BOOL WINAPI FlushFileBuffers( # __in HANDLE hFile # ); def FlushFileBuffers(hFile): _FlushFileBuffers = windll.kernel32.FlushFileBuffers _FlushFileBuffers.argtypes = [HANDLE] - _FlushFileBuffers.restype = bool + _FlushFileBuffers.restype = bool _FlushFileBuffers.errcheck = RaiseIfZero _FlushFileBuffers(hFile) + # BOOL WINAPI FlushViewOfFile( # __in LPCVOID lpBaseAddress, # __in SIZE_T dwNumberOfBytesToFlush # ); -def FlushViewOfFile(lpBaseAddress, dwNumberOfBytesToFlush = 0): +def FlushViewOfFile(lpBaseAddress, dwNumberOfBytesToFlush=0): _FlushViewOfFile = windll.kernel32.FlushViewOfFile _FlushViewOfFile.argtypes = [LPVOID, SIZE_T] - _FlushViewOfFile.restype = bool + _FlushViewOfFile.restype = bool _FlushViewOfFile.errcheck = RaiseIfZero _FlushViewOfFile(lpBaseAddress, dwNumberOfBytesToFlush) + # DWORD WINAPI SearchPath( # __in_opt LPCTSTR lpPath, # __in LPCTSTR lpFileName, @@ -2950,7 +3135,7 @@ def FlushViewOfFile(lpBaseAddress, dwNumberOfBytesToFlush = 0): def SearchPathA(lpPath, lpFileName, lpExtension): _SearchPathA = windll.kernel32.SearchPathA _SearchPathA.argtypes = [LPSTR, LPSTR, LPSTR, DWORD, LPSTR, POINTER(LPSTR)] - _SearchPathA.restype = DWORD + _SearchPathA.restype = DWORD _SearchPathA.errcheck = RaiseIfZero if not lpPath: @@ -2958,21 +3143,22 @@ def SearchPathA(lpPath, lpFileName, lpExtension): if not lpExtension: lpExtension = None nBufferLength = _SearchPathA(lpPath, lpFileName, lpExtension, 0, None, None) - lpBuffer = ctypes.create_string_buffer('', nBufferLength + 1) + lpBuffer = ctypes.create_string_buffer("", nBufferLength + 1) lpFilePart = LPSTR() _SearchPathA(lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, byref(lpFilePart)) lpFilePart = lpFilePart.value lpBuffer = lpBuffer.value - if lpBuffer == '': + if lpBuffer == "": if GetLastError() == ERROR_SUCCESS: raise ctypes.WinError(ERROR_FILE_NOT_FOUND) raise ctypes.WinError() return (lpBuffer, lpFilePart) + def SearchPathW(lpPath, lpFileName, lpExtension): _SearchPathW = windll.kernel32.SearchPathW _SearchPathW.argtypes = [LPWSTR, LPWSTR, LPWSTR, DWORD, LPWSTR, POINTER(LPWSTR)] - _SearchPathW.restype = DWORD + _SearchPathW.restype = DWORD _SearchPathW.errcheck = RaiseIfZero if not lpPath: @@ -2980,29 +3166,32 @@ def SearchPathW(lpPath, lpFileName, lpExtension): if not lpExtension: lpExtension = None nBufferLength = _SearchPathW(lpPath, lpFileName, lpExtension, 0, None, None) - lpBuffer = ctypes.create_unicode_buffer(u'', nBufferLength + 1) + lpBuffer = ctypes.create_unicode_buffer("", nBufferLength + 1) lpFilePart = LPWSTR() _SearchPathW(lpPath, lpFileName, lpExtension, nBufferLength, lpBuffer, byref(lpFilePart)) lpFilePart = lpFilePart.value lpBuffer = lpBuffer.value - if lpBuffer == u'': + if lpBuffer == "": if GetLastError() == ERROR_SUCCESS: raise ctypes.WinError(ERROR_FILE_NOT_FOUND) raise ctypes.WinError() return (lpBuffer, lpFilePart) + SearchPath = GuessStringType(SearchPathA, SearchPathW) + # BOOL SetSearchPathMode( # __in DWORD Flags # ); def SetSearchPathMode(Flags): _SetSearchPathMode = windll.kernel32.SetSearchPathMode _SetSearchPathMode.argtypes = [DWORD] - _SetSearchPathMode.restype = bool + _SetSearchPathMode.restype = bool _SetSearchPathMode.errcheck = RaiseIfZero _SetSearchPathMode(Flags) + # BOOL WINAPI DeviceIoControl( # __in HANDLE hDevice, # __in DWORD dwIoControlCode, @@ -3016,7 +3205,7 @@ def SetSearchPathMode(Flags): def DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpOverlapped): _DeviceIoControl = windll.kernel32.DeviceIoControl _DeviceIoControl.argtypes = [HANDLE, DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD, LPOVERLAPPED] - _DeviceIoControl.restype = bool + _DeviceIoControl.restype = bool _DeviceIoControl.errcheck = RaiseIfZero if not lpInBuffer: @@ -3029,6 +3218,7 @@ def DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBu _DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, byref(lpBytesReturned), lpOverlapped) return lpBytesReturned.value + # BOOL GetFileInformationByHandle( # HANDLE hFile, # LPBY_HANDLE_FILE_INFORMATION lpFileInformation @@ -3036,13 +3226,14 @@ def DeviceIoControl(hDevice, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBu def GetFileInformationByHandle(hFile): _GetFileInformationByHandle = windll.kernel32.GetFileInformationByHandle _GetFileInformationByHandle.argtypes = [HANDLE, LPBY_HANDLE_FILE_INFORMATION] - _GetFileInformationByHandle.restype = bool + _GetFileInformationByHandle.restype = bool _GetFileInformationByHandle.errcheck = RaiseIfZero lpFileInformation = BY_HANDLE_FILE_INFORMATION() _GetFileInformationByHandle(hFile, byref(lpFileInformation)) return lpFileInformation + # BOOL WINAPI GetFileInformationByHandleEx( # __in HANDLE hFile, # __in FILE_INFO_BY_HANDLE_CLASS FileInformationClass, @@ -3052,49 +3243,53 @@ def GetFileInformationByHandle(hFile): def GetFileInformationByHandleEx(hFile, FileInformationClass, lpFileInformation, dwBufferSize): _GetFileInformationByHandleEx = windll.kernel32.GetFileInformationByHandleEx _GetFileInformationByHandleEx.argtypes = [HANDLE, DWORD, LPVOID, DWORD] - _GetFileInformationByHandleEx.restype = bool + _GetFileInformationByHandleEx.restype = bool _GetFileInformationByHandleEx.errcheck = RaiseIfZero # XXX TODO # support each FileInformationClass so the function can allocate the # corresponding structure for the lpFileInformation parameter _GetFileInformationByHandleEx(hFile, FileInformationClass, byref(lpFileInformation), dwBufferSize) + # DWORD WINAPI GetFinalPathNameByHandle( # __in HANDLE hFile, # __out LPTSTR lpszFilePath, # __in DWORD cchFilePath, # __in DWORD dwFlags # ); -def GetFinalPathNameByHandleA(hFile, dwFlags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS): +def GetFinalPathNameByHandleA(hFile, dwFlags=FILE_NAME_NORMALIZED | VOLUME_NAME_DOS): _GetFinalPathNameByHandleA = windll.kernel32.GetFinalPathNameByHandleA _GetFinalPathNameByHandleA.argtypes = [HANDLE, LPSTR, DWORD, DWORD] - _GetFinalPathNameByHandleA.restype = DWORD + _GetFinalPathNameByHandleA.restype = DWORD cchFilePath = _GetFinalPathNameByHandleA(hFile, None, 0, dwFlags) if cchFilePath == 0: raise ctypes.WinError() - lpszFilePath = ctypes.create_string_buffer('', cchFilePath + 1) + lpszFilePath = ctypes.create_string_buffer("", cchFilePath + 1) nCopied = _GetFinalPathNameByHandleA(hFile, lpszFilePath, cchFilePath, dwFlags) if nCopied <= 0 or nCopied > cchFilePath: raise ctypes.WinError() return lpszFilePath.value -def GetFinalPathNameByHandleW(hFile, dwFlags = FILE_NAME_NORMALIZED | VOLUME_NAME_DOS): + +def GetFinalPathNameByHandleW(hFile, dwFlags=FILE_NAME_NORMALIZED | VOLUME_NAME_DOS): _GetFinalPathNameByHandleW = windll.kernel32.GetFinalPathNameByHandleW _GetFinalPathNameByHandleW.argtypes = [HANDLE, LPWSTR, DWORD, DWORD] - _GetFinalPathNameByHandleW.restype = DWORD + _GetFinalPathNameByHandleW.restype = DWORD cchFilePath = _GetFinalPathNameByHandleW(hFile, None, 0, dwFlags) if cchFilePath == 0: raise ctypes.WinError() - lpszFilePath = ctypes.create_unicode_buffer(u'', cchFilePath + 1) + lpszFilePath = ctypes.create_unicode_buffer("", cchFilePath + 1) nCopied = _GetFinalPathNameByHandleW(hFile, lpszFilePath, cchFilePath, dwFlags) if nCopied <= 0 or nCopied > cchFilePath: raise ctypes.WinError() return lpszFilePath.value + GetFinalPathNameByHandle = GuessStringType(GetFinalPathNameByHandleA, GetFinalPathNameByHandleW) + # DWORD GetFullPathName( # LPCTSTR lpFileName, # DWORD nBufferLength, @@ -3104,35 +3299,38 @@ def GetFinalPathNameByHandleW(hFile, dwFlags = FILE_NAME_NORMALIZED | VOLUME_NAM def GetFullPathNameA(lpFileName): _GetFullPathNameA = windll.kernel32.GetFullPathNameA _GetFullPathNameA.argtypes = [LPSTR, DWORD, LPSTR, POINTER(LPSTR)] - _GetFullPathNameA.restype = DWORD + _GetFullPathNameA.restype = DWORD nBufferLength = _GetFullPathNameA(lpFileName, 0, None, None) if nBufferLength <= 0: raise ctypes.WinError() - lpBuffer = ctypes.create_string_buffer('', nBufferLength + 1) + lpBuffer = ctypes.create_string_buffer("", nBufferLength + 1) lpFilePart = LPSTR() nCopied = _GetFullPathNameA(lpFileName, nBufferLength, lpBuffer, byref(lpFilePart)) if nCopied > nBufferLength or nCopied == 0: raise ctypes.WinError() return lpBuffer.value, lpFilePart.value + def GetFullPathNameW(lpFileName): _GetFullPathNameW = windll.kernel32.GetFullPathNameW _GetFullPathNameW.argtypes = [LPWSTR, DWORD, LPWSTR, POINTER(LPWSTR)] - _GetFullPathNameW.restype = DWORD + _GetFullPathNameW.restype = DWORD nBufferLength = _GetFullPathNameW(lpFileName, 0, None, None) if nBufferLength <= 0: raise ctypes.WinError() - lpBuffer = ctypes.create_unicode_buffer(u'', nBufferLength + 1) + lpBuffer = ctypes.create_unicode_buffer("", nBufferLength + 1) lpFilePart = LPWSTR() nCopied = _GetFullPathNameW(lpFileName, nBufferLength, lpBuffer, byref(lpFilePart)) if nCopied > nBufferLength or nCopied == 0: raise ctypes.WinError() return lpBuffer.value, lpFilePart.value + GetFullPathName = GuessStringType(GetFullPathNameA, GetFullPathNameW) + # DWORD WINAPI GetTempPath( # __in DWORD nBufferLength, # __out LPTSTR lpBuffer @@ -3140,67 +3338,73 @@ def GetFullPathNameW(lpFileName): def GetTempPathA(): _GetTempPathA = windll.kernel32.GetTempPathA _GetTempPathA.argtypes = [DWORD, LPSTR] - _GetTempPathA.restype = DWORD + _GetTempPathA.restype = DWORD nBufferLength = _GetTempPathA(0, None) if nBufferLength <= 0: raise ctypes.WinError() - lpBuffer = ctypes.create_string_buffer('', nBufferLength) + lpBuffer = ctypes.create_string_buffer("", nBufferLength) nCopied = _GetTempPathA(nBufferLength, lpBuffer) if nCopied > nBufferLength or nCopied == 0: raise ctypes.WinError() return lpBuffer.value + def GetTempPathW(): _GetTempPathW = windll.kernel32.GetTempPathW _GetTempPathW.argtypes = [DWORD, LPWSTR] - _GetTempPathW.restype = DWORD + _GetTempPathW.restype = DWORD nBufferLength = _GetTempPathW(0, None) if nBufferLength <= 0: raise ctypes.WinError() - lpBuffer = ctypes.create_unicode_buffer(u'', nBufferLength) + lpBuffer = ctypes.create_unicode_buffer("", nBufferLength) nCopied = _GetTempPathW(nBufferLength, lpBuffer) if nCopied > nBufferLength or nCopied == 0: raise ctypes.WinError() return lpBuffer.value + GetTempPath = GuessStringType(GetTempPathA, GetTempPathW) + # UINT WINAPI GetTempFileName( # __in LPCTSTR lpPathName, # __in LPCTSTR lpPrefixString, # __in UINT uUnique, # __out LPTSTR lpTempFileName # ); -def GetTempFileNameA(lpPathName = None, lpPrefixString = "TMP", uUnique = 0): +def GetTempFileNameA(lpPathName=None, lpPrefixString="TMP", uUnique=0): _GetTempFileNameA = windll.kernel32.GetTempFileNameA _GetTempFileNameA.argtypes = [LPSTR, LPSTR, UINT, LPSTR] - _GetTempFileNameA.restype = UINT + _GetTempFileNameA.restype = UINT if lpPathName is None: lpPathName = GetTempPathA() - lpTempFileName = ctypes.create_string_buffer('', MAX_PATH) + lpTempFileName = ctypes.create_string_buffer("", MAX_PATH) uUnique = _GetTempFileNameA(lpPathName, lpPrefixString, uUnique, lpTempFileName) if uUnique == 0: raise ctypes.WinError() return lpTempFileName.value, uUnique -def GetTempFileNameW(lpPathName = None, lpPrefixString = u"TMP", uUnique = 0): + +def GetTempFileNameW(lpPathName=None, lpPrefixString="TMP", uUnique=0): _GetTempFileNameW = windll.kernel32.GetTempFileNameW _GetTempFileNameW.argtypes = [LPWSTR, LPWSTR, UINT, LPWSTR] - _GetTempFileNameW.restype = UINT + _GetTempFileNameW.restype = UINT if lpPathName is None: lpPathName = GetTempPathW() - lpTempFileName = ctypes.create_unicode_buffer(u'', MAX_PATH) + lpTempFileName = ctypes.create_unicode_buffer("", MAX_PATH) uUnique = _GetTempFileNameW(lpPathName, lpPrefixString, uUnique, lpTempFileName) if uUnique == 0: raise ctypes.WinError() return lpTempFileName.value, uUnique + GetTempFileName = GuessStringType(GetTempFileNameA, GetTempFileNameW) + # DWORD WINAPI GetCurrentDirectory( # __in DWORD nBufferLength, # __out LPTSTR lpBuffer @@ -3208,34 +3412,36 @@ def GetTempFileNameW(lpPathName = None, lpPrefixString = u"TMP", uUnique = 0): def GetCurrentDirectoryA(): _GetCurrentDirectoryA = windll.kernel32.GetCurrentDirectoryA _GetCurrentDirectoryA.argtypes = [DWORD, LPSTR] - _GetCurrentDirectoryA.restype = DWORD + _GetCurrentDirectoryA.restype = DWORD nBufferLength = _GetCurrentDirectoryA(0, None) if nBufferLength <= 0: raise ctypes.WinError() - lpBuffer = ctypes.create_string_buffer('', nBufferLength) + lpBuffer = ctypes.create_string_buffer("", nBufferLength) nCopied = _GetCurrentDirectoryA(nBufferLength, lpBuffer) if nCopied > nBufferLength or nCopied == 0: raise ctypes.WinError() return lpBuffer.value + def GetCurrentDirectoryW(): _GetCurrentDirectoryW = windll.kernel32.GetCurrentDirectoryW _GetCurrentDirectoryW.argtypes = [DWORD, LPWSTR] - _GetCurrentDirectoryW.restype = DWORD + _GetCurrentDirectoryW.restype = DWORD nBufferLength = _GetCurrentDirectoryW(0, None) if nBufferLength <= 0: raise ctypes.WinError() - lpBuffer = ctypes.create_unicode_buffer(u'', nBufferLength) + lpBuffer = ctypes.create_unicode_buffer("", nBufferLength) nCopied = _GetCurrentDirectoryW(nBufferLength, lpBuffer) if nCopied > nBufferLength or nCopied == 0: raise ctypes.WinError() return lpBuffer.value + GetCurrentDirectory = GuessStringType(GetCurrentDirectoryA, GetCurrentDirectoryW) -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Contrl-C handler # BOOL WINAPI HandlerRoutine( @@ -3243,20 +3449,22 @@ def GetCurrentDirectoryW(): # ); PHANDLER_ROUTINE = ctypes.WINFUNCTYPE(BOOL, DWORD) + # BOOL WINAPI SetConsoleCtrlHandler( # __in_opt PHANDLER_ROUTINE HandlerRoutine, # __in BOOL Add # ); -def SetConsoleCtrlHandler(HandlerRoutine = None, Add = True): +def SetConsoleCtrlHandler(HandlerRoutine=None, Add=True): _SetConsoleCtrlHandler = windll.kernel32.SetConsoleCtrlHandler _SetConsoleCtrlHandler.argtypes = [PHANDLER_ROUTINE, BOOL] - _SetConsoleCtrlHandler.restype = bool + _SetConsoleCtrlHandler.restype = bool _SetConsoleCtrlHandler.errcheck = RaiseIfZero _SetConsoleCtrlHandler(HandlerRoutine, bool(Add)) # we can't automagically transform Python functions to PHANDLER_ROUTINE # because a) the actual pointer value is meaningful to the API # and b) if it gets garbage collected bad things would happen + # BOOL WINAPI GenerateConsoleCtrlEvent( # __in DWORD dwCtrlEvent, # __in DWORD dwProcessGroupId @@ -3264,11 +3472,12 @@ def SetConsoleCtrlHandler(HandlerRoutine = None, Add = True): def GenerateConsoleCtrlEvent(dwCtrlEvent, dwProcessGroupId): _GenerateConsoleCtrlEvent = windll.kernel32.GenerateConsoleCtrlEvent _GenerateConsoleCtrlEvent.argtypes = [DWORD, DWORD] - _GenerateConsoleCtrlEvent.restype = bool + _GenerateConsoleCtrlEvent.restype = bool _GenerateConsoleCtrlEvent.errcheck = RaiseIfZero _GenerateConsoleCtrlEvent(dwCtrlEvent, dwProcessGroupId) -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # Synchronization API # XXX NOTE @@ -3281,14 +3490,15 @@ def GenerateConsoleCtrlEvent(dwCtrlEvent, dwProcessGroupId): # Also see: bug #2793618 in Psyco project # http://sourceforge.net/tracker/?func=detail&aid=2793618&group_id=41036&atid=429622 + # DWORD WINAPI WaitForSingleObject( # HANDLE hHandle, # DWORD dwMilliseconds # ); -def WaitForSingleObject(hHandle, dwMilliseconds = INFINITE): +def WaitForSingleObject(hHandle, dwMilliseconds=INFINITE): _WaitForSingleObject = windll.kernel32.WaitForSingleObject _WaitForSingleObject.argtypes = [HANDLE, DWORD] - _WaitForSingleObject.restype = DWORD + _WaitForSingleObject.restype = DWORD if not dwMilliseconds and dwMilliseconds != 0: dwMilliseconds = INFINITE @@ -3305,15 +3515,16 @@ def WaitForSingleObject(hHandle, dwMilliseconds = INFINITE): break return r + # DWORD WINAPI WaitForSingleObjectEx( # HANDLE hHandle, # DWORD dwMilliseconds, # BOOL bAlertable # ); -def WaitForSingleObjectEx(hHandle, dwMilliseconds = INFINITE, bAlertable = True): +def WaitForSingleObjectEx(hHandle, dwMilliseconds=INFINITE, bAlertable=True): _WaitForSingleObjectEx = windll.kernel32.WaitForSingleObjectEx _WaitForSingleObjectEx.argtypes = [HANDLE, DWORD, BOOL] - _WaitForSingleObjectEx.restype = DWORD + _WaitForSingleObjectEx.restype = DWORD if not dwMilliseconds and dwMilliseconds != 0: dwMilliseconds = INFINITE @@ -3330,22 +3541,23 @@ def WaitForSingleObjectEx(hHandle, dwMilliseconds = INFINITE, bAlertable = True) break return r + # DWORD WINAPI WaitForMultipleObjects( # DWORD nCount, # const HANDLE *lpHandles, # BOOL bWaitAll, # DWORD dwMilliseconds # ); -def WaitForMultipleObjects(handles, bWaitAll = False, dwMilliseconds = INFINITE): +def WaitForMultipleObjects(handles, bWaitAll=False, dwMilliseconds=INFINITE): _WaitForMultipleObjects = windll.kernel32.WaitForMultipleObjects _WaitForMultipleObjects.argtypes = [DWORD, POINTER(HANDLE), BOOL, DWORD] - _WaitForMultipleObjects.restype = DWORD + _WaitForMultipleObjects.restype = DWORD if not dwMilliseconds and dwMilliseconds != 0: dwMilliseconds = INFINITE - nCount = len(handles) - lpHandlesType = HANDLE * nCount - lpHandles = lpHandlesType(*handles) + nCount = len(handles) + lpHandlesType = HANDLE * nCount + lpHandles = lpHandlesType(*handles) if dwMilliseconds != INFINITE: r = _WaitForMultipleObjects(byref(lpHandles), bool(bWaitAll), dwMilliseconds) if r == WAIT_FAILED: @@ -3359,6 +3571,7 @@ def WaitForMultipleObjects(handles, bWaitAll = False, dwMilliseconds = INFINITE) break return r + # DWORD WINAPI WaitForMultipleObjectsEx( # DWORD nCount, # const HANDLE *lpHandles, @@ -3366,16 +3579,16 @@ def WaitForMultipleObjects(handles, bWaitAll = False, dwMilliseconds = INFINITE) # DWORD dwMilliseconds, # BOOL bAlertable # ); -def WaitForMultipleObjectsEx(handles, bWaitAll = False, dwMilliseconds = INFINITE, bAlertable = True): +def WaitForMultipleObjectsEx(handles, bWaitAll=False, dwMilliseconds=INFINITE, bAlertable=True): _WaitForMultipleObjectsEx = windll.kernel32.WaitForMultipleObjectsEx _WaitForMultipleObjectsEx.argtypes = [DWORD, POINTER(HANDLE), BOOL, DWORD] - _WaitForMultipleObjectsEx.restype = DWORD + _WaitForMultipleObjectsEx.restype = DWORD if not dwMilliseconds and dwMilliseconds != 0: dwMilliseconds = INFINITE - nCount = len(handles) - lpHandlesType = HANDLE * nCount - lpHandles = lpHandlesType(*handles) + nCount = len(handles) + lpHandlesType = HANDLE * nCount + lpHandles = lpHandlesType(*handles) if dwMilliseconds != INFINITE: r = _WaitForMultipleObjectsEx(byref(lpHandles), bool(bWaitAll), dwMilliseconds, bool(bAlertable)) if r == WAIT_FAILED: @@ -3389,88 +3602,100 @@ def WaitForMultipleObjectsEx(handles, bWaitAll = False, dwMilliseconds = INFINIT break return r + # HANDLE WINAPI CreateMutex( # _In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes, # _In_ BOOL bInitialOwner, # _In_opt_ LPCTSTR lpName # ); -def CreateMutexA(lpMutexAttributes = None, bInitialOwner = True, lpName = None): +def CreateMutexA(lpMutexAttributes=None, bInitialOwner=True, lpName=None): _CreateMutexA = windll.kernel32.CreateMutexA _CreateMutexA.argtypes = [LPVOID, BOOL, LPSTR] - _CreateMutexA.restype = HANDLE + _CreateMutexA.restype = HANDLE _CreateMutexA.errcheck = RaiseIfZero - return Handle( _CreateMutexA(lpMutexAttributes, bInitialOwner, lpName) ) + return Handle(_CreateMutexA(lpMutexAttributes, bInitialOwner, lpName)) -def CreateMutexW(lpMutexAttributes = None, bInitialOwner = True, lpName = None): + +def CreateMutexW(lpMutexAttributes=None, bInitialOwner=True, lpName=None): _CreateMutexW = windll.kernel32.CreateMutexW _CreateMutexW.argtypes = [LPVOID, BOOL, LPWSTR] - _CreateMutexW.restype = HANDLE + _CreateMutexW.restype = HANDLE _CreateMutexW.errcheck = RaiseIfZero - return Handle( _CreateMutexW(lpMutexAttributes, bInitialOwner, lpName) ) + return Handle(_CreateMutexW(lpMutexAttributes, bInitialOwner, lpName)) + CreateMutex = GuessStringType(CreateMutexA, CreateMutexW) + # HANDLE WINAPI OpenMutex( # _In_ DWORD dwDesiredAccess, # _In_ BOOL bInheritHandle, # _In_ LPCTSTR lpName # ); -def OpenMutexA(dwDesiredAccess = MUTEX_ALL_ACCESS, bInitialOwner = True, lpName = None): +def OpenMutexA(dwDesiredAccess=MUTEX_ALL_ACCESS, bInitialOwner=True, lpName=None): _OpenMutexA = windll.kernel32.OpenMutexA _OpenMutexA.argtypes = [DWORD, BOOL, LPSTR] - _OpenMutexA.restype = HANDLE + _OpenMutexA.restype = HANDLE _OpenMutexA.errcheck = RaiseIfZero - return Handle( _OpenMutexA(lpMutexAttributes, bInitialOwner, lpName) ) + return Handle(_OpenMutexA(lpMutexAttributes, bInitialOwner, lpName)) -def OpenMutexW(dwDesiredAccess = MUTEX_ALL_ACCESS, bInitialOwner = True, lpName = None): + +def OpenMutexW(dwDesiredAccess=MUTEX_ALL_ACCESS, bInitialOwner=True, lpName=None): _OpenMutexW = windll.kernel32.OpenMutexW _OpenMutexW.argtypes = [DWORD, BOOL, LPWSTR] - _OpenMutexW.restype = HANDLE + _OpenMutexW.restype = HANDLE _OpenMutexW.errcheck = RaiseIfZero - return Handle( _OpenMutexW(lpMutexAttributes, bInitialOwner, lpName) ) + return Handle(_OpenMutexW(lpMutexAttributes, bInitialOwner, lpName)) + OpenMutex = GuessStringType(OpenMutexA, OpenMutexW) + # HANDLE WINAPI CreateEvent( # _In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes, # _In_ BOOL bManualReset, # _In_ BOOL bInitialState, # _In_opt_ LPCTSTR lpName # ); -def CreateEventA(lpMutexAttributes = None, bManualReset = False, bInitialState = False, lpName = None): +def CreateEventA(lpMutexAttributes=None, bManualReset=False, bInitialState=False, lpName=None): _CreateEventA = windll.kernel32.CreateEventA _CreateEventA.argtypes = [LPVOID, BOOL, BOOL, LPSTR] - _CreateEventA.restype = HANDLE + _CreateEventA.restype = HANDLE _CreateEventA.errcheck = RaiseIfZero - return Handle( _CreateEventA(lpMutexAttributes, bManualReset, bInitialState, lpName) ) + return Handle(_CreateEventA(lpMutexAttributes, bManualReset, bInitialState, lpName)) -def CreateEventW(lpMutexAttributes = None, bManualReset = False, bInitialState = False, lpName = None): + +def CreateEventW(lpMutexAttributes=None, bManualReset=False, bInitialState=False, lpName=None): _CreateEventW = windll.kernel32.CreateEventW _CreateEventW.argtypes = [LPVOID, BOOL, BOOL, LPWSTR] - _CreateEventW.restype = HANDLE + _CreateEventW.restype = HANDLE _CreateEventW.errcheck = RaiseIfZero - return Handle( _CreateEventW(lpMutexAttributes, bManualReset, bInitialState, lpName) ) + return Handle(_CreateEventW(lpMutexAttributes, bManualReset, bInitialState, lpName)) + CreateEvent = GuessStringType(CreateEventA, CreateEventW) + # HANDLE WINAPI OpenEvent( # _In_ DWORD dwDesiredAccess, # _In_ BOOL bInheritHandle, # _In_ LPCTSTR lpName # ); -def OpenEventA(dwDesiredAccess = EVENT_ALL_ACCESS, bInheritHandle = False, lpName = None): +def OpenEventA(dwDesiredAccess=EVENT_ALL_ACCESS, bInheritHandle=False, lpName=None): _OpenEventA = windll.kernel32.OpenEventA _OpenEventA.argtypes = [DWORD, BOOL, LPSTR] - _OpenEventA.restype = HANDLE + _OpenEventA.restype = HANDLE _OpenEventA.errcheck = RaiseIfZero - return Handle( _OpenEventA(dwDesiredAccess, bInheritHandle, lpName) ) + return Handle(_OpenEventA(dwDesiredAccess, bInheritHandle, lpName)) + -def OpenEventW(dwDesiredAccess = EVENT_ALL_ACCESS, bInheritHandle = False, lpName = None): +def OpenEventW(dwDesiredAccess=EVENT_ALL_ACCESS, bInheritHandle=False, lpName=None): _OpenEventW = windll.kernel32.OpenEventW _OpenEventW.argtypes = [DWORD, BOOL, LPWSTR] - _OpenEventW.restype = HANDLE + _OpenEventW.restype = HANDLE _OpenEventW.errcheck = RaiseIfZero - return Handle( _OpenEventW(dwDesiredAccess, bInheritHandle, lpName) ) + return Handle(_OpenEventW(dwDesiredAccess, bInheritHandle, lpName)) + OpenEvent = GuessStringType(OpenEventA, OpenEventW) @@ -3491,46 +3716,51 @@ def OpenEventW(dwDesiredAccess = EVENT_ALL_ACCESS, bInheritHandle = False, lpNam # TODO + # BOOL WINAPI ReleaseMutex( # _In_ HANDLE hMutex # ); def ReleaseMutex(hMutex): _ReleaseMutex = windll.kernel32.ReleaseMutex _ReleaseMutex.argtypes = [HANDLE] - _ReleaseMutex.restype = bool + _ReleaseMutex.restype = bool _ReleaseMutex.errcheck = RaiseIfZero _ReleaseMutex(hMutex) + # BOOL WINAPI SetEvent( # _In_ HANDLE hEvent # ); def SetEvent(hEvent): _SetEvent = windll.kernel32.SetEvent _SetEvent.argtypes = [HANDLE] - _SetEvent.restype = bool + _SetEvent.restype = bool _SetEvent.errcheck = RaiseIfZero _SetEvent(hEvent) + # BOOL WINAPI ResetEvent( # _In_ HANDLE hEvent # ); def ResetEvent(hEvent): _ResetEvent = windll.kernel32.ResetEvent _ResetEvent.argtypes = [HANDLE] - _ResetEvent.restype = bool + _ResetEvent.restype = bool _ResetEvent.errcheck = RaiseIfZero _ResetEvent(hEvent) + # BOOL WINAPI PulseEvent( # _In_ HANDLE hEvent # ); def PulseEvent(hEvent): _PulseEvent = windll.kernel32.PulseEvent _PulseEvent.argtypes = [HANDLE] - _PulseEvent.restype = bool + _PulseEvent.restype = bool _PulseEvent.errcheck = RaiseIfZero _PulseEvent(hEvent) + # BOOL WINAPI ReleaseSemaphore( # _In_ HANDLE hSemaphore, # _In_ LONG lReleaseCount, @@ -3539,24 +3769,25 @@ def PulseEvent(hEvent): # TODO -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Debug API + # BOOL WaitForDebugEvent( # LPDEBUG_EVENT lpDebugEvent, # DWORD dwMilliseconds # ); -def WaitForDebugEvent(dwMilliseconds = INFINITE): +def WaitForDebugEvent(dwMilliseconds=INFINITE): _WaitForDebugEvent = windll.kernel32.WaitForDebugEvent _WaitForDebugEvent.argtypes = [LPDEBUG_EVENT, DWORD] - _WaitForDebugEvent.restype = DWORD + _WaitForDebugEvent.restype = DWORD if not dwMilliseconds and dwMilliseconds != 0: dwMilliseconds = INFINITE - lpDebugEvent = DEBUG_EVENT() + lpDebugEvent = DEBUG_EVENT() lpDebugEvent.dwDebugEventCode = 0 - lpDebugEvent.dwProcessId = 0 - lpDebugEvent.dwThreadId = 0 + lpDebugEvent.dwProcessId = 0 + lpDebugEvent.dwThreadId = 0 if dwMilliseconds != INFINITE: success = _WaitForDebugEvent(byref(lpDebugEvent), dwMilliseconds) if success == 0: @@ -3572,51 +3803,56 @@ def WaitForDebugEvent(dwMilliseconds = INFINITE): raise ctypes.WinError(code) return lpDebugEvent + # BOOL ContinueDebugEvent( # DWORD dwProcessId, # DWORD dwThreadId, # DWORD dwContinueStatus # ); -def ContinueDebugEvent(dwProcessId, dwThreadId, dwContinueStatus = DBG_EXCEPTION_NOT_HANDLED): +def ContinueDebugEvent(dwProcessId, dwThreadId, dwContinueStatus=DBG_EXCEPTION_NOT_HANDLED): _ContinueDebugEvent = windll.kernel32.ContinueDebugEvent _ContinueDebugEvent.argtypes = [DWORD, DWORD, DWORD] - _ContinueDebugEvent.restype = bool + _ContinueDebugEvent.restype = bool _ContinueDebugEvent.errcheck = RaiseIfZero _ContinueDebugEvent(dwProcessId, dwThreadId, dwContinueStatus) + # BOOL WINAPI FlushInstructionCache( # __in HANDLE hProcess, # __in LPCVOID lpBaseAddress, # __in SIZE_T dwSize # ); -def FlushInstructionCache(hProcess, lpBaseAddress = None, dwSize = 0): +def FlushInstructionCache(hProcess, lpBaseAddress=None, dwSize=0): # http://blogs.msdn.com/oldnewthing/archive/2003/12/08/55954.aspx#55958 _FlushInstructionCache = windll.kernel32.FlushInstructionCache _FlushInstructionCache.argtypes = [HANDLE, LPVOID, SIZE_T] - _FlushInstructionCache.restype = bool + _FlushInstructionCache.restype = bool _FlushInstructionCache.errcheck = RaiseIfZero _FlushInstructionCache(hProcess, lpBaseAddress, dwSize) + # BOOL DebugActiveProcess( # DWORD dwProcessId # ); def DebugActiveProcess(dwProcessId): _DebugActiveProcess = windll.kernel32.DebugActiveProcess _DebugActiveProcess.argtypes = [DWORD] - _DebugActiveProcess.restype = bool + _DebugActiveProcess.restype = bool _DebugActiveProcess.errcheck = RaiseIfZero _DebugActiveProcess(dwProcessId) + # BOOL DebugActiveProcessStop( # DWORD dwProcessId # ); def DebugActiveProcessStop(dwProcessId): _DebugActiveProcessStop = windll.kernel32.DebugActiveProcessStop _DebugActiveProcessStop.argtypes = [DWORD] - _DebugActiveProcessStop.restype = bool + _DebugActiveProcessStop.restype = bool _DebugActiveProcessStop.errcheck = RaiseIfZero _DebugActiveProcessStop(dwProcessId) + # BOOL CheckRemoteDebuggerPresent( # HANDLE hProcess, # PBOOL pbDebuggerPresent @@ -3624,50 +3860,56 @@ def DebugActiveProcessStop(dwProcessId): def CheckRemoteDebuggerPresent(hProcess): _CheckRemoteDebuggerPresent = windll.kernel32.CheckRemoteDebuggerPresent _CheckRemoteDebuggerPresent.argtypes = [HANDLE, PBOOL] - _CheckRemoteDebuggerPresent.restype = bool + _CheckRemoteDebuggerPresent.restype = bool _CheckRemoteDebuggerPresent.errcheck = RaiseIfZero pbDebuggerPresent = BOOL(0) _CheckRemoteDebuggerPresent(hProcess, byref(pbDebuggerPresent)) return bool(pbDebuggerPresent.value) + # BOOL DebugSetProcessKillOnExit( # BOOL KillOnExit # ); def DebugSetProcessKillOnExit(KillOnExit): _DebugSetProcessKillOnExit = windll.kernel32.DebugSetProcessKillOnExit _DebugSetProcessKillOnExit.argtypes = [BOOL] - _DebugSetProcessKillOnExit.restype = bool + _DebugSetProcessKillOnExit.restype = bool _DebugSetProcessKillOnExit.errcheck = RaiseIfZero _DebugSetProcessKillOnExit(bool(KillOnExit)) + # BOOL DebugBreakProcess( # HANDLE Process # ); def DebugBreakProcess(hProcess): _DebugBreakProcess = windll.kernel32.DebugBreakProcess _DebugBreakProcess.argtypes = [HANDLE] - _DebugBreakProcess.restype = bool + _DebugBreakProcess.restype = bool _DebugBreakProcess.errcheck = RaiseIfZero _DebugBreakProcess(hProcess) + # void WINAPI OutputDebugString( # __in_opt LPCTSTR lpOutputString # ); def OutputDebugStringA(lpOutputString): _OutputDebugStringA = windll.kernel32.OutputDebugStringA _OutputDebugStringA.argtypes = [LPSTR] - _OutputDebugStringA.restype = None + _OutputDebugStringA.restype = None _OutputDebugStringA(lpOutputString) + def OutputDebugStringW(lpOutputString): _OutputDebugStringW = windll.kernel32.OutputDebugStringW _OutputDebugStringW.argtypes = [LPWSTR] - _OutputDebugStringW.restype = None + _OutputDebugStringW.restype = None _OutputDebugStringW(lpOutputString) + OutputDebugString = GuessStringType(OutputDebugStringA, OutputDebugStringW) + # BOOL WINAPI ReadProcessMemory( # __in HANDLE hProcess, # __in LPCVOID lpBaseAddress, @@ -3678,14 +3920,15 @@ def OutputDebugStringW(lpOutputString): def ReadProcessMemory(hProcess, lpBaseAddress, nSize): _ReadProcessMemory = windll.kernel32.ReadProcessMemory _ReadProcessMemory.argtypes = [HANDLE, LPVOID, LPVOID, SIZE_T, POINTER(SIZE_T)] - _ReadProcessMemory.restype = bool + _ReadProcessMemory.restype = bool - lpBuffer = ctypes.create_string_buffer(compat.b(''), nSize) + lpBuffer = ctypes.create_string_buffer(compat.b(""), nSize) lpNumberOfBytesRead = SIZE_T(0) success = _ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, byref(lpNumberOfBytesRead)) if not success and GetLastError() != ERROR_PARTIAL_COPY: raise ctypes.WinError() - return compat.b(lpBuffer.raw)[:lpNumberOfBytesRead.value] + return compat.b(lpBuffer.raw)[: lpNumberOfBytesRead.value] + # BOOL WINAPI WriteProcessMemory( # __in HANDLE hProcess, @@ -3697,16 +3940,17 @@ def ReadProcessMemory(hProcess, lpBaseAddress, nSize): def WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer): _WriteProcessMemory = windll.kernel32.WriteProcessMemory _WriteProcessMemory.argtypes = [HANDLE, LPVOID, LPVOID, SIZE_T, POINTER(SIZE_T)] - _WriteProcessMemory.restype = bool + _WriteProcessMemory.restype = bool - nSize = len(lpBuffer) - lpBuffer = ctypes.create_string_buffer(lpBuffer) - lpNumberOfBytesWritten = SIZE_T(0) + nSize = len(lpBuffer) + lpBuffer = ctypes.create_string_buffer(lpBuffer) + lpNumberOfBytesWritten = SIZE_T(0) success = _WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, byref(lpNumberOfBytesWritten)) if not success and GetLastError() != ERROR_PARTIAL_COPY: raise ctypes.WinError() return lpNumberOfBytesWritten.value + # LPVOID WINAPI VirtualAllocEx( # __in HANDLE hProcess, # __in_opt LPVOID lpAddress, @@ -3714,16 +3958,17 @@ def WriteProcessMemory(hProcess, lpBaseAddress, lpBuffer): # __in DWORD flAllocationType, # __in DWORD flProtect # ); -def VirtualAllocEx(hProcess, lpAddress = 0, dwSize = 0x1000, flAllocationType = MEM_COMMIT | MEM_RESERVE, flProtect = PAGE_EXECUTE_READWRITE): +def VirtualAllocEx(hProcess, lpAddress=0, dwSize=0x1000, flAllocationType=MEM_COMMIT | MEM_RESERVE, flProtect=PAGE_EXECUTE_READWRITE): _VirtualAllocEx = windll.kernel32.VirtualAllocEx _VirtualAllocEx.argtypes = [HANDLE, LPVOID, SIZE_T, DWORD, DWORD] - _VirtualAllocEx.restype = LPVOID + _VirtualAllocEx.restype = LPVOID lpAddress = _VirtualAllocEx(hProcess, lpAddress, dwSize, flAllocationType, flProtect) if lpAddress == NULL: raise ctypes.WinError() return lpAddress + # SIZE_T WINAPI VirtualQueryEx( # __in HANDLE hProcess, # __in_opt LPCVOID lpAddress, @@ -3733,15 +3978,16 @@ def VirtualAllocEx(hProcess, lpAddress = 0, dwSize = 0x1000, flAllocationType = def VirtualQueryEx(hProcess, lpAddress): _VirtualQueryEx = windll.kernel32.VirtualQueryEx _VirtualQueryEx.argtypes = [HANDLE, LPVOID, PMEMORY_BASIC_INFORMATION, SIZE_T] - _VirtualQueryEx.restype = SIZE_T + _VirtualQueryEx.restype = SIZE_T - lpBuffer = MEMORY_BASIC_INFORMATION() - dwLength = sizeof(MEMORY_BASIC_INFORMATION) - success = _VirtualQueryEx(hProcess, lpAddress, byref(lpBuffer), dwLength) + lpBuffer = MEMORY_BASIC_INFORMATION() + dwLength = sizeof(MEMORY_BASIC_INFORMATION) + success = _VirtualQueryEx(hProcess, lpAddress, byref(lpBuffer), dwLength) if success == 0: raise ctypes.WinError() return MemoryBasicInformation(lpBuffer) + # BOOL WINAPI VirtualProtectEx( # __in HANDLE hProcess, # __in LPVOID lpAddress, @@ -3749,29 +3995,31 @@ def VirtualQueryEx(hProcess, lpAddress): # __in DWORD flNewProtect, # __out PDWORD lpflOldProtect # ); -def VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect = PAGE_EXECUTE_READWRITE): +def VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect=PAGE_EXECUTE_READWRITE): _VirtualProtectEx = windll.kernel32.VirtualProtectEx _VirtualProtectEx.argtypes = [HANDLE, LPVOID, SIZE_T, DWORD, PDWORD] - _VirtualProtectEx.restype = bool + _VirtualProtectEx.restype = bool _VirtualProtectEx.errcheck = RaiseIfZero flOldProtect = DWORD(0) _VirtualProtectEx(hProcess, lpAddress, dwSize, flNewProtect, byref(flOldProtect)) return flOldProtect.value + # BOOL WINAPI VirtualFreeEx( # __in HANDLE hProcess, # __in LPVOID lpAddress, # __in SIZE_T dwSize, # __in DWORD dwFreeType # ); -def VirtualFreeEx(hProcess, lpAddress, dwSize = 0, dwFreeType = MEM_RELEASE): +def VirtualFreeEx(hProcess, lpAddress, dwSize=0, dwFreeType=MEM_RELEASE): _VirtualFreeEx = windll.kernel32.VirtualFreeEx _VirtualFreeEx.argtypes = [HANDLE, LPVOID, SIZE_T, DWORD] - _VirtualFreeEx.restype = bool + _VirtualFreeEx.restype = bool _VirtualFreeEx.errcheck = RaiseIfZero _VirtualFreeEx(hProcess, lpAddress, dwSize, dwFreeType) + # HANDLE WINAPI CreateRemoteThread( # __in HANDLE hProcess, # __in LPSECURITY_ATTRIBUTES lpThreadAttributes, @@ -3784,21 +4032,25 @@ def VirtualFreeEx(hProcess, lpAddress, dwSize = 0, dwFreeType = MEM_RELEASE): def CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags): _CreateRemoteThread = windll.kernel32.CreateRemoteThread _CreateRemoteThread.argtypes = [HANDLE, LPSECURITY_ATTRIBUTES, SIZE_T, LPVOID, LPVOID, DWORD, LPDWORD] - _CreateRemoteThread.restype = HANDLE + _CreateRemoteThread.restype = HANDLE if not lpThreadAttributes: lpThreadAttributes = None else: lpThreadAttributes = byref(lpThreadAttributes) dwThreadId = DWORD(0) - hThread = _CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, byref(dwThreadId)) + hThread = _CreateRemoteThread( + hProcess, lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, byref(dwThreadId) + ) if not hThread: raise ctypes.WinError() return ThreadHandle(hThread), dwThreadId.value -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # Process API + # BOOL WINAPI CreateProcess( # __in_opt LPCTSTR lpApplicationName, # __inout_opt LPTSTR lpCommandLine, @@ -3811,24 +4063,45 @@ def CreateRemoteThread(hProcess, lpThreadAttributes, dwStackSize, lpStartAddress # __in LPSTARTUPINFO lpStartupInfo, # __out LPPROCESS_INFORMATION lpProcessInformation # ); -def CreateProcessA(lpApplicationName, lpCommandLine=None, lpProcessAttributes=None, lpThreadAttributes=None, bInheritHandles=False, dwCreationFlags=0, lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None): +def CreateProcessA( + lpApplicationName, + lpCommandLine=None, + lpProcessAttributes=None, + lpThreadAttributes=None, + bInheritHandles=False, + dwCreationFlags=0, + lpEnvironment=None, + lpCurrentDirectory=None, + lpStartupInfo=None, +): _CreateProcessA = windll.kernel32.CreateProcessA - _CreateProcessA.argtypes = [LPSTR, LPSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPSTR, LPVOID, LPPROCESS_INFORMATION] - _CreateProcessA.restype = bool + _CreateProcessA.argtypes = [ + LPSTR, + LPSTR, + LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES, + BOOL, + DWORD, + LPVOID, + LPSTR, + LPVOID, + LPPROCESS_INFORMATION, + ] + _CreateProcessA.restype = bool _CreateProcessA.errcheck = RaiseIfZero if not lpApplicationName: - lpApplicationName = None + lpApplicationName = None if not lpCommandLine: - lpCommandLine = None + lpCommandLine = None else: - lpCommandLine = ctypes.create_string_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) + lpCommandLine = ctypes.create_string_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) if not lpEnvironment: - lpEnvironment = None + lpEnvironment = None else: - lpEnvironment = ctypes.create_string_buffer(lpEnvironment) + lpEnvironment = ctypes.create_string_buffer(lpEnvironment) if not lpCurrentDirectory: - lpCurrentDirectory = None + lpCurrentDirectory = None if not lpProcessAttributes: lpProcessAttributes = None else: @@ -3838,40 +4111,73 @@ def CreateProcessA(lpApplicationName, lpCommandLine=None, lpProcessAttributes=No else: lpThreadAttributes = byref(lpThreadAttributes) if not lpStartupInfo: - lpStartupInfo = STARTUPINFO() - lpStartupInfo.cb = sizeof(STARTUPINFO) - lpStartupInfo.lpReserved = 0 - lpStartupInfo.lpDesktop = 0 - lpStartupInfo.lpTitle = 0 - lpStartupInfo.dwFlags = 0 - lpStartupInfo.cbReserved2 = 0 - lpStartupInfo.lpReserved2 = 0 - lpProcessInformation = PROCESS_INFORMATION() - lpProcessInformation.hProcess = INVALID_HANDLE_VALUE - lpProcessInformation.hThread = INVALID_HANDLE_VALUE - lpProcessInformation.dwProcessId = 0 - lpProcessInformation.dwThreadId = 0 - _CreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bool(bInheritHandles), dwCreationFlags, lpEnvironment, lpCurrentDirectory, byref(lpStartupInfo), byref(lpProcessInformation)) + lpStartupInfo = STARTUPINFO() + lpStartupInfo.cb = sizeof(STARTUPINFO) + lpStartupInfo.lpReserved = 0 + lpStartupInfo.lpDesktop = 0 + lpStartupInfo.lpTitle = 0 + lpStartupInfo.dwFlags = 0 + lpStartupInfo.cbReserved2 = 0 + lpStartupInfo.lpReserved2 = 0 + lpProcessInformation = PROCESS_INFORMATION() + lpProcessInformation.hProcess = INVALID_HANDLE_VALUE + lpProcessInformation.hThread = INVALID_HANDLE_VALUE + lpProcessInformation.dwProcessId = 0 + lpProcessInformation.dwThreadId = 0 + _CreateProcessA( + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bool(bInheritHandles), + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + byref(lpStartupInfo), + byref(lpProcessInformation), + ) return ProcessInformation(lpProcessInformation) -def CreateProcessW(lpApplicationName, lpCommandLine=None, lpProcessAttributes=None, lpThreadAttributes=None, bInheritHandles=False, dwCreationFlags=0, lpEnvironment=None, lpCurrentDirectory=None, lpStartupInfo=None): + +def CreateProcessW( + lpApplicationName, + lpCommandLine=None, + lpProcessAttributes=None, + lpThreadAttributes=None, + bInheritHandles=False, + dwCreationFlags=0, + lpEnvironment=None, + lpCurrentDirectory=None, + lpStartupInfo=None, +): _CreateProcessW = windll.kernel32.CreateProcessW - _CreateProcessW.argtypes = [LPWSTR, LPWSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES, BOOL, DWORD, LPVOID, LPWSTR, LPVOID, LPPROCESS_INFORMATION] - _CreateProcessW.restype = bool + _CreateProcessW.argtypes = [ + LPWSTR, + LPWSTR, + LPSECURITY_ATTRIBUTES, + LPSECURITY_ATTRIBUTES, + BOOL, + DWORD, + LPVOID, + LPWSTR, + LPVOID, + LPPROCESS_INFORMATION, + ] + _CreateProcessW.restype = bool _CreateProcessW.errcheck = RaiseIfZero if not lpApplicationName: - lpApplicationName = None + lpApplicationName = None if not lpCommandLine: - lpCommandLine = None + lpCommandLine = None else: - lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) + lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine, max(MAX_PATH, len(lpCommandLine))) if not lpEnvironment: - lpEnvironment = None + lpEnvironment = None else: - lpEnvironment = ctypes.create_unicode_buffer(lpEnvironment) + lpEnvironment = ctypes.create_unicode_buffer(lpEnvironment) if not lpCurrentDirectory: - lpCurrentDirectory = None + lpCurrentDirectory = None if not lpProcessAttributes: lpProcessAttributes = None else: @@ -3881,24 +4187,37 @@ def CreateProcessW(lpApplicationName, lpCommandLine=None, lpProcessAttributes=No else: lpThreadAttributes = byref(lpThreadAttributes) if not lpStartupInfo: - lpStartupInfo = STARTUPINFO() - lpStartupInfo.cb = sizeof(STARTUPINFO) - lpStartupInfo.lpReserved = 0 - lpStartupInfo.lpDesktop = 0 - lpStartupInfo.lpTitle = 0 - lpStartupInfo.dwFlags = 0 - lpStartupInfo.cbReserved2 = 0 - lpStartupInfo.lpReserved2 = 0 - lpProcessInformation = PROCESS_INFORMATION() - lpProcessInformation.hProcess = INVALID_HANDLE_VALUE - lpProcessInformation.hThread = INVALID_HANDLE_VALUE - lpProcessInformation.dwProcessId = 0 - lpProcessInformation.dwThreadId = 0 - _CreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bool(bInheritHandles), dwCreationFlags, lpEnvironment, lpCurrentDirectory, byref(lpStartupInfo), byref(lpProcessInformation)) + lpStartupInfo = STARTUPINFO() + lpStartupInfo.cb = sizeof(STARTUPINFO) + lpStartupInfo.lpReserved = 0 + lpStartupInfo.lpDesktop = 0 + lpStartupInfo.lpTitle = 0 + lpStartupInfo.dwFlags = 0 + lpStartupInfo.cbReserved2 = 0 + lpStartupInfo.lpReserved2 = 0 + lpProcessInformation = PROCESS_INFORMATION() + lpProcessInformation.hProcess = INVALID_HANDLE_VALUE + lpProcessInformation.hThread = INVALID_HANDLE_VALUE + lpProcessInformation.dwProcessId = 0 + lpProcessInformation.dwThreadId = 0 + _CreateProcessW( + lpApplicationName, + lpCommandLine, + lpProcessAttributes, + lpThreadAttributes, + bool(bInheritHandles), + dwCreationFlags, + lpEnvironment, + lpCurrentDirectory, + byref(lpStartupInfo), + byref(lpProcessInformation), + ) return ProcessInformation(lpProcessInformation) + CreateProcess = GuessStringType(CreateProcessA, CreateProcessW) + # BOOL WINAPI InitializeProcThreadAttributeList( # __out_opt LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, # __in DWORD dwAttributeCount, @@ -3908,7 +4227,7 @@ def CreateProcessW(lpApplicationName, lpCommandLine=None, lpProcessAttributes=No def InitializeProcThreadAttributeList(dwAttributeCount): _InitializeProcThreadAttributeList = windll.kernel32.InitializeProcThreadAttributeList _InitializeProcThreadAttributeList.argtypes = [LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD, PSIZE_T] - _InitializeProcThreadAttributeList.restype = bool + _InitializeProcThreadAttributeList.restype = bool Size = SIZE_T(0) _InitializeProcThreadAttributeList(None, dwAttributeCount, 0, byref(Size)) @@ -3918,6 +4237,7 @@ def InitializeProcThreadAttributeList(dwAttributeCount): RaiseIfZero(success) return AttributeList + # BOOL WINAPI UpdateProcThreadAttribute( # __inout LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, # __in DWORD dwFlags, @@ -3927,16 +4247,17 @@ def InitializeProcThreadAttributeList(dwAttributeCount): # __out_opt PVOID lpPreviousValue, # __in_opt PSIZE_T lpReturnSize # ); -def UpdateProcThreadAttribute(lpAttributeList, Attribute, Value, cbSize = None): +def UpdateProcThreadAttribute(lpAttributeList, Attribute, Value, cbSize=None): _UpdateProcThreadAttribute = windll.kernel32.UpdateProcThreadAttribute _UpdateProcThreadAttribute.argtypes = [LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD_PTR, PVOID, SIZE_T, PVOID, PSIZE_T] - _UpdateProcThreadAttribute.restype = bool + _UpdateProcThreadAttribute.restype = bool _UpdateProcThreadAttribute.errcheck = RaiseIfZero if cbSize is None: cbSize = sizeof(Value) _UpdateProcThreadAttribute(byref(lpAttributeList), 0, Attribute, byref(Value), cbSize, None, None) + # VOID WINAPI DeleteProcThreadAttributeList( # __inout LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList # ); @@ -3945,6 +4266,7 @@ def DeleteProcThreadAttributeList(lpAttributeList): _DeleteProcThreadAttributeList.restype = None _DeleteProcThreadAttributeList(byref(lpAttributeList)) + # HANDLE WINAPI OpenProcess( # __in DWORD dwDesiredAccess, # __in BOOL bInheritHandle, @@ -3953,12 +4275,13 @@ def DeleteProcThreadAttributeList(lpAttributeList): def OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId): _OpenProcess = windll.kernel32.OpenProcess _OpenProcess.argtypes = [DWORD, BOOL, DWORD] - _OpenProcess.restype = HANDLE + _OpenProcess.restype = HANDLE hProcess = _OpenProcess(dwDesiredAccess, bool(bInheritHandle), dwProcessId) if hProcess == NULL: raise ctypes.WinError() - return ProcessHandle(hProcess, dwAccess = dwDesiredAccess) + return ProcessHandle(hProcess, dwAccess=dwDesiredAccess) + # HANDLE WINAPI OpenThread( # __in DWORD dwDesiredAccess, @@ -3968,12 +4291,13 @@ def OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId): def OpenThread(dwDesiredAccess, bInheritHandle, dwThreadId): _OpenThread = windll.kernel32.OpenThread _OpenThread.argtypes = [DWORD, BOOL, DWORD] - _OpenThread.restype = HANDLE + _OpenThread.restype = HANDLE hThread = _OpenThread(dwDesiredAccess, bool(bInheritHandle), dwThreadId) if hThread == NULL: raise ctypes.WinError() - return ThreadHandle(hThread, dwAccess = dwDesiredAccess) + return ThreadHandle(hThread, dwAccess=dwDesiredAccess) + # DWORD WINAPI SuspendThread( # __in HANDLE hThread @@ -3981,98 +4305,107 @@ def OpenThread(dwDesiredAccess, bInheritHandle, dwThreadId): def SuspendThread(hThread): _SuspendThread = windll.kernel32.SuspendThread _SuspendThread.argtypes = [HANDLE] - _SuspendThread.restype = DWORD + _SuspendThread.restype = DWORD previousCount = _SuspendThread(hThread) if previousCount == DWORD(-1).value: raise ctypes.WinError() return previousCount + # DWORD WINAPI ResumeThread( # __in HANDLE hThread # ); def ResumeThread(hThread): _ResumeThread = windll.kernel32.ResumeThread _ResumeThread.argtypes = [HANDLE] - _ResumeThread.restype = DWORD + _ResumeThread.restype = DWORD previousCount = _ResumeThread(hThread) if previousCount == DWORD(-1).value: raise ctypes.WinError() return previousCount + # BOOL WINAPI TerminateThread( # __inout HANDLE hThread, # __in DWORD dwExitCode # ); -def TerminateThread(hThread, dwExitCode = 0): +def TerminateThread(hThread, dwExitCode=0): _TerminateThread = windll.kernel32.TerminateThread _TerminateThread.argtypes = [HANDLE, DWORD] - _TerminateThread.restype = bool + _TerminateThread.restype = bool _TerminateThread.errcheck = RaiseIfZero _TerminateThread(hThread, dwExitCode) + # BOOL WINAPI TerminateProcess( # __inout HANDLE hProcess, # __in DWORD dwExitCode # ); -def TerminateProcess(hProcess, dwExitCode = 0): +def TerminateProcess(hProcess, dwExitCode=0): _TerminateProcess = windll.kernel32.TerminateProcess _TerminateProcess.argtypes = [HANDLE, DWORD] - _TerminateProcess.restype = bool + _TerminateProcess.restype = bool _TerminateProcess.errcheck = RaiseIfZero _TerminateProcess(hProcess, dwExitCode) + # DWORD WINAPI GetCurrentProcessId(void); def GetCurrentProcessId(): _GetCurrentProcessId = windll.kernel32.GetCurrentProcessId _GetCurrentProcessId.argtypes = [] - _GetCurrentProcessId.restype = DWORD + _GetCurrentProcessId.restype = DWORD return _GetCurrentProcessId() + # DWORD WINAPI GetCurrentThreadId(void); def GetCurrentThreadId(): _GetCurrentThreadId = windll.kernel32.GetCurrentThreadId _GetCurrentThreadId.argtypes = [] - _GetCurrentThreadId.restype = DWORD + _GetCurrentThreadId.restype = DWORD return _GetCurrentThreadId() + # DWORD WINAPI GetProcessId( # __in HANDLE hProcess # ); def GetProcessId(hProcess): _GetProcessId = windll.kernel32.GetProcessId _GetProcessId.argtypes = [HANDLE] - _GetProcessId.restype = DWORD + _GetProcessId.restype = DWORD _GetProcessId.errcheck = RaiseIfZero return _GetProcessId(hProcess) + # DWORD WINAPI GetThreadId( # __in HANDLE hThread # ); def GetThreadId(hThread): _GetThreadId = windll.kernel32._GetThreadId _GetThreadId.argtypes = [HANDLE] - _GetThreadId.restype = DWORD + _GetThreadId.restype = DWORD dwThreadId = _GetThreadId(hThread) if dwThreadId == 0: raise ctypes.WinError() return dwThreadId + # DWORD WINAPI GetProcessIdOfThread( # __in HANDLE hThread # ); def GetProcessIdOfThread(hThread): _GetProcessIdOfThread = windll.kernel32.GetProcessIdOfThread _GetProcessIdOfThread.argtypes = [HANDLE] - _GetProcessIdOfThread.restype = DWORD + _GetProcessIdOfThread.restype = DWORD dwProcessId = _GetProcessIdOfThread(hThread) if dwProcessId == 0: raise ctypes.WinError() return dwProcessId + # BOOL WINAPI GetExitCodeProcess( # __in HANDLE hProcess, # __out LPDWORD lpExitCode @@ -4080,13 +4413,14 @@ def GetProcessIdOfThread(hThread): def GetExitCodeProcess(hProcess): _GetExitCodeProcess = windll.kernel32.GetExitCodeProcess _GetExitCodeProcess.argtypes = [HANDLE] - _GetExitCodeProcess.restype = bool + _GetExitCodeProcess.restype = bool _GetExitCodeProcess.errcheck = RaiseIfZero lpExitCode = DWORD(0) _GetExitCodeProcess(hProcess, byref(lpExitCode)) return lpExitCode.value + # BOOL WINAPI GetExitCodeThread( # __in HANDLE hThread, # __out LPDWORD lpExitCode @@ -4094,50 +4428,54 @@ def GetExitCodeProcess(hProcess): def GetExitCodeThread(hThread): _GetExitCodeThread = windll.kernel32.GetExitCodeThread _GetExitCodeThread.argtypes = [HANDLE] - _GetExitCodeThread.restype = bool + _GetExitCodeThread.restype = bool _GetExitCodeThread.errcheck = RaiseIfZero lpExitCode = DWORD(0) _GetExitCodeThread(hThread, byref(lpExitCode)) return lpExitCode.value + # DWORD WINAPI GetProcessVersion( # __in DWORD ProcessId # ); def GetProcessVersion(ProcessId): _GetProcessVersion = windll.kernel32.GetProcessVersion _GetProcessVersion.argtypes = [DWORD] - _GetProcessVersion.restype = DWORD + _GetProcessVersion.restype = DWORD retval = _GetProcessVersion(ProcessId) if retval == 0: raise ctypes.WinError() return retval + # DWORD WINAPI GetPriorityClass( # __in HANDLE hProcess # ); def GetPriorityClass(hProcess): _GetPriorityClass = windll.kernel32.GetPriorityClass _GetPriorityClass.argtypes = [HANDLE] - _GetPriorityClass.restype = DWORD + _GetPriorityClass.restype = DWORD retval = _GetPriorityClass(hProcess) if retval == 0: raise ctypes.WinError() return retval + # BOOL WINAPI SetPriorityClass( # __in HANDLE hProcess, # __in DWORD dwPriorityClass # ); -def SetPriorityClass(hProcess, dwPriorityClass = NORMAL_PRIORITY_CLASS): +def SetPriorityClass(hProcess, dwPriorityClass=NORMAL_PRIORITY_CLASS): _SetPriorityClass = windll.kernel32.SetPriorityClass _SetPriorityClass.argtypes = [HANDLE, DWORD] - _SetPriorityClass.restype = bool + _SetPriorityClass.restype = bool _SetPriorityClass.errcheck = RaiseIfZero _SetPriorityClass(hProcess, dwPriorityClass) + # BOOL WINAPI GetProcessPriorityBoost( # __in HANDLE hProcess, # __out PBOOL pDisablePriorityBoost @@ -4145,13 +4483,14 @@ def SetPriorityClass(hProcess, dwPriorityClass = NORMAL_PRIORITY_CLASS): def GetProcessPriorityBoost(hProcess): _GetProcessPriorityBoost = windll.kernel32.GetProcessPriorityBoost _GetProcessPriorityBoost.argtypes = [HANDLE, PBOOL] - _GetProcessPriorityBoost.restype = bool + _GetProcessPriorityBoost.restype = bool _GetProcessPriorityBoost.errcheck = RaiseIfZero pDisablePriorityBoost = BOOL(False) _GetProcessPriorityBoost(hProcess, byref(pDisablePriorityBoost)) return bool(pDisablePriorityBoost.value) + # BOOL WINAPI SetProcessPriorityBoost( # __in HANDLE hProcess, # __in BOOL DisablePriorityBoost @@ -4159,10 +4498,11 @@ def GetProcessPriorityBoost(hProcess): def SetProcessPriorityBoost(hProcess, DisablePriorityBoost): _SetProcessPriorityBoost = windll.kernel32.SetProcessPriorityBoost _SetProcessPriorityBoost.argtypes = [HANDLE, BOOL] - _SetProcessPriorityBoost.restype = bool + _SetProcessPriorityBoost.restype = bool _SetProcessPriorityBoost.errcheck = RaiseIfZero _SetProcessPriorityBoost(hProcess, bool(DisablePriorityBoost)) + # BOOL WINAPI GetProcessAffinityMask( # __in HANDLE hProcess, # __out PDWORD_PTR lpProcessAffinityMask, @@ -4171,14 +4511,15 @@ def SetProcessPriorityBoost(hProcess, DisablePriorityBoost): def GetProcessAffinityMask(hProcess): _GetProcessAffinityMask = windll.kernel32.GetProcessAffinityMask _GetProcessAffinityMask.argtypes = [HANDLE, PDWORD_PTR, PDWORD_PTR] - _GetProcessAffinityMask.restype = bool + _GetProcessAffinityMask.restype = bool _GetProcessAffinityMask.errcheck = RaiseIfZero lpProcessAffinityMask = DWORD_PTR(0) - lpSystemAffinityMask = DWORD_PTR(0) + lpSystemAffinityMask = DWORD_PTR(0) _GetProcessAffinityMask(hProcess, byref(lpProcessAffinityMask), byref(lpSystemAffinityMask)) return lpProcessAffinityMask.value, lpSystemAffinityMask.value + # BOOL WINAPI SetProcessAffinityMask( # __in HANDLE hProcess, # __in DWORD_PTR dwProcessAffinityMask @@ -4186,27 +4527,30 @@ def GetProcessAffinityMask(hProcess): def SetProcessAffinityMask(hProcess, dwProcessAffinityMask): _SetProcessAffinityMask = windll.kernel32.SetProcessAffinityMask _SetProcessAffinityMask.argtypes = [HANDLE, DWORD_PTR] - _SetProcessAffinityMask.restype = bool + _SetProcessAffinityMask.restype = bool _SetProcessAffinityMask.errcheck = RaiseIfZero _SetProcessAffinityMask(hProcess, dwProcessAffinityMask) -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # Toolhelp32 API + # HANDLE WINAPI CreateToolhelp32Snapshot( # __in DWORD dwFlags, # __in DWORD th32ProcessID # ); -def CreateToolhelp32Snapshot(dwFlags = TH32CS_SNAPALL, th32ProcessID = 0): +def CreateToolhelp32Snapshot(dwFlags=TH32CS_SNAPALL, th32ProcessID=0): _CreateToolhelp32Snapshot = windll.kernel32.CreateToolhelp32Snapshot _CreateToolhelp32Snapshot.argtypes = [DWORD, DWORD] - _CreateToolhelp32Snapshot.restype = HANDLE + _CreateToolhelp32Snapshot.restype = HANDLE hSnapshot = _CreateToolhelp32Snapshot(dwFlags, th32ProcessID) if hSnapshot == INVALID_HANDLE_VALUE: raise ctypes.WinError() return SnapshotHandle(hSnapshot) + # BOOL WINAPI Process32First( # __in HANDLE hSnapshot, # __inout LPPROCESSENTRY32 lppe @@ -4214,9 +4558,9 @@ def CreateToolhelp32Snapshot(dwFlags = TH32CS_SNAPALL, th32ProcessID = 0): def Process32First(hSnapshot): _Process32First = windll.kernel32.Process32First _Process32First.argtypes = [HANDLE, LPPROCESSENTRY32] - _Process32First.restype = bool + _Process32First.restype = bool - pe = PROCESSENTRY32() + pe = PROCESSENTRY32() pe.dwSize = sizeof(PROCESSENTRY32) success = _Process32First(hSnapshot, byref(pe)) if not success: @@ -4225,14 +4569,15 @@ def Process32First(hSnapshot): raise ctypes.WinError() return pe + # BOOL WINAPI Process32Next( # __in HANDLE hSnapshot, # __out LPPROCESSENTRY32 lppe # ); -def Process32Next(hSnapshot, pe = None): +def Process32Next(hSnapshot, pe=None): _Process32Next = windll.kernel32.Process32Next _Process32Next.argtypes = [HANDLE, LPPROCESSENTRY32] - _Process32Next.restype = bool + _Process32Next.restype = bool if pe is None: pe = PROCESSENTRY32() @@ -4244,6 +4589,7 @@ def Process32Next(hSnapshot, pe = None): raise ctypes.WinError() return pe + # BOOL WINAPI Thread32First( # __in HANDLE hSnapshot, # __inout LPTHREADENTRY32 lpte @@ -4251,7 +4597,7 @@ def Process32Next(hSnapshot, pe = None): def Thread32First(hSnapshot): _Thread32First = windll.kernel32.Thread32First _Thread32First.argtypes = [HANDLE, LPTHREADENTRY32] - _Thread32First.restype = bool + _Thread32First.restype = bool te = THREADENTRY32() te.dwSize = sizeof(THREADENTRY32) @@ -4262,14 +4608,15 @@ def Thread32First(hSnapshot): raise ctypes.WinError() return te + # BOOL WINAPI Thread32Next( # __in HANDLE hSnapshot, # __out LPTHREADENTRY32 lpte # ); -def Thread32Next(hSnapshot, te = None): +def Thread32Next(hSnapshot, te=None): _Thread32Next = windll.kernel32.Thread32Next _Thread32Next.argtypes = [HANDLE, LPTHREADENTRY32] - _Thread32Next.restype = bool + _Thread32Next.restype = bool if te is None: te = THREADENTRY32() @@ -4281,6 +4628,7 @@ def Thread32Next(hSnapshot, te = None): raise ctypes.WinError() return te + # BOOL WINAPI Module32First( # __in HANDLE hSnapshot, # __inout LPMODULEENTRY32 lpme @@ -4288,7 +4636,7 @@ def Thread32Next(hSnapshot, te = None): def Module32First(hSnapshot): _Module32First = windll.kernel32.Module32First _Module32First.argtypes = [HANDLE, LPMODULEENTRY32] - _Module32First.restype = bool + _Module32First.restype = bool me = MODULEENTRY32() me.dwSize = sizeof(MODULEENTRY32) @@ -4299,14 +4647,15 @@ def Module32First(hSnapshot): raise ctypes.WinError() return me + # BOOL WINAPI Module32Next( # __in HANDLE hSnapshot, # __out LPMODULEENTRY32 lpme # ); -def Module32Next(hSnapshot, me = None): +def Module32Next(hSnapshot, me=None): _Module32Next = windll.kernel32.Module32Next _Module32Next.argtypes = [HANDLE, LPMODULEENTRY32] - _Module32Next.restype = bool + _Module32Next.restype = bool if me is None: me = MODULEENTRY32() @@ -4318,6 +4667,7 @@ def Module32Next(hSnapshot, me = None): raise ctypes.WinError() return me + # BOOL WINAPI Heap32First( # __inout LPHEAPENTRY32 lphe, # __in DWORD th32ProcessID, @@ -4326,7 +4676,7 @@ def Module32Next(hSnapshot, me = None): def Heap32First(th32ProcessID, th32HeapID): _Heap32First = windll.kernel32.Heap32First _Heap32First.argtypes = [LPHEAPENTRY32, DWORD, ULONG_PTR] - _Heap32First.restype = bool + _Heap32First.restype = bool he = HEAPENTRY32() he.dwSize = sizeof(HEAPENTRY32) @@ -4337,13 +4687,14 @@ def Heap32First(th32ProcessID, th32HeapID): raise ctypes.WinError() return he + # BOOL WINAPI Heap32Next( # __out LPHEAPENTRY32 lphe # ); def Heap32Next(he): _Heap32Next = windll.kernel32.Heap32Next _Heap32Next.argtypes = [LPHEAPENTRY32] - _Heap32Next.restype = bool + _Heap32Next.restype = bool he.dwSize = sizeof(HEAPENTRY32) success = _Heap32Next(byref(he)) @@ -4353,6 +4704,7 @@ def Heap32Next(he): raise ctypes.WinError() return he + # BOOL WINAPI Heap32ListFirst( # __in HANDLE hSnapshot, # __inout LPHEAPLIST32 lphl @@ -4360,7 +4712,7 @@ def Heap32Next(he): def Heap32ListFirst(hSnapshot): _Heap32ListFirst = windll.kernel32.Heap32ListFirst _Heap32ListFirst.argtypes = [HANDLE, LPHEAPLIST32] - _Heap32ListFirst.restype = bool + _Heap32ListFirst.restype = bool hl = HEAPLIST32() hl.dwSize = sizeof(HEAPLIST32) @@ -4371,14 +4723,15 @@ def Heap32ListFirst(hSnapshot): raise ctypes.WinError() return hl + # BOOL WINAPI Heap32ListNext( # __in HANDLE hSnapshot, # __out LPHEAPLIST32 lphl # ); -def Heap32ListNext(hSnapshot, hl = None): +def Heap32ListNext(hSnapshot, hl=None): _Heap32ListNext = windll.kernel32.Heap32ListNext _Heap32ListNext.argtypes = [HANDLE, LPHEAPLIST32] - _Heap32ListNext.restype = bool + _Heap32ListNext.restype = bool if hl is None: hl = HEAPLIST32() @@ -4390,6 +4743,7 @@ def Heap32ListNext(hSnapshot, hl = None): raise ctypes.WinError() return hl + # BOOL WINAPI Toolhelp32ReadProcessMemory( # __in DWORD th32ProcessID, # __in LPCVOID lpBaseAddress, @@ -4400,18 +4754,20 @@ def Heap32ListNext(hSnapshot, hl = None): def Toolhelp32ReadProcessMemory(th32ProcessID, lpBaseAddress, cbRead): _Toolhelp32ReadProcessMemory = windll.kernel32.Toolhelp32ReadProcessMemory _Toolhelp32ReadProcessMemory.argtypes = [DWORD, LPVOID, LPVOID, SIZE_T, POINTER(SIZE_T)] - _Toolhelp32ReadProcessMemory.restype = bool + _Toolhelp32ReadProcessMemory.restype = bool - lpBuffer = ctypes.create_string_buffer('', cbRead) + lpBuffer = ctypes.create_string_buffer("", cbRead) lpNumberOfBytesRead = SIZE_T(0) success = _Toolhelp32ReadProcessMemory(th32ProcessID, lpBaseAddress, lpBuffer, cbRead, byref(lpNumberOfBytesRead)) if not success and GetLastError() != ERROR_PARTIAL_COPY: raise ctypes.WinError() - return str(lpBuffer.raw)[:lpNumberOfBytesRead.value] + return str(lpBuffer.raw)[: lpNumberOfBytesRead.value] + -#------------------------------------------------------------------------------ +# ------------------------------------------------------------------------------ # Miscellaneous system information + # BOOL WINAPI GetProcessDEPPolicy( # __in HANDLE hProcess, # __out LPDWORD lpFlags, @@ -4422,7 +4778,7 @@ def Toolhelp32ReadProcessMemory(th32ProcessID, lpBaseAddress, cbRead): def GetProcessDEPPolicy(hProcess): _GetProcessDEPPolicy = windll.kernel32.GetProcessDEPPolicy _GetProcessDEPPolicy.argtypes = [HANDLE, LPDWORD, PBOOL] - _GetProcessDEPPolicy.restype = bool + _GetProcessDEPPolicy.restype = bool _GetProcessDEPPolicy.errcheck = RaiseIfZero lpFlags = DWORD(0) @@ -4430,21 +4786,24 @@ def GetProcessDEPPolicy(hProcess): _GetProcessDEPPolicy(hProcess, byref(lpFlags), byref(lpPermanent)) return (lpFlags.value, lpPermanent.value) + # DWORD WINAPI GetCurrentProcessorNumber(void); def GetCurrentProcessorNumber(): _GetCurrentProcessorNumber = windll.kernel32.GetCurrentProcessorNumber _GetCurrentProcessorNumber.argtypes = [] - _GetCurrentProcessorNumber.restype = DWORD + _GetCurrentProcessorNumber.restype = DWORD _GetCurrentProcessorNumber.errcheck = RaiseIfZero return _GetCurrentProcessorNumber() + # VOID WINAPI FlushProcessWriteBuffers(void); def FlushProcessWriteBuffers(): _FlushProcessWriteBuffers = windll.kernel32.FlushProcessWriteBuffers _FlushProcessWriteBuffers.argtypes = [] - _FlushProcessWriteBuffers.restype = None + _FlushProcessWriteBuffers.restype = None _FlushProcessWriteBuffers() + # BOOL WINAPI GetLogicalProcessorInformation( # __out PSYSTEM_LOGICAL_PROCESSOR_INFORMATION Buffer, # __inout PDWORD ReturnLength @@ -4459,14 +4818,15 @@ def FlushProcessWriteBuffers(): # TO DO http://msdn.microsoft.com/en-us/library/ms683218(VS.85).aspx + # DWORD WINAPI GetGuiResources( # __in HANDLE hProcess, # __in DWORD uiFlags # ); -def GetGuiResources(hProcess, uiFlags = GR_GDIOBJECTS): +def GetGuiResources(hProcess, uiFlags=GR_GDIOBJECTS): _GetGuiResources = windll.kernel32.GetGuiResources _GetGuiResources.argtypes = [HANDLE, DWORD] - _GetGuiResources.restype = DWORD + _GetGuiResources.restype = DWORD dwCount = _GetGuiResources(hProcess, uiFlags) if dwCount == 0: @@ -4475,6 +4835,7 @@ def GetGuiResources(hProcess, uiFlags = GR_GDIOBJECTS): raise ctypes.WinError(errcode) return dwCount + # BOOL WINAPI GetProcessHandleCount( # __in HANDLE hProcess, # __inout PDWORD pdwHandleCount @@ -4482,13 +4843,14 @@ def GetGuiResources(hProcess, uiFlags = GR_GDIOBJECTS): def GetProcessHandleCount(hProcess): _GetProcessHandleCount = windll.kernel32.GetProcessHandleCount _GetProcessHandleCount.argtypes = [HANDLE, PDWORD] - _GetProcessHandleCount.restype = DWORD + _GetProcessHandleCount.restype = DWORD _GetProcessHandleCount.errcheck = RaiseIfZero pdwHandleCount = DWORD(0) _GetProcessHandleCount(hProcess, byref(pdwHandleCount)) return pdwHandleCount.value + # BOOL WINAPI GetProcessTimes( # __in HANDLE hProcess, # __out LPFILETIME lpCreationTime, @@ -4496,24 +4858,25 @@ def GetProcessHandleCount(hProcess): # __out LPFILETIME lpKernelTime, # __out LPFILETIME lpUserTime # ); -def GetProcessTimes(hProcess = None): +def GetProcessTimes(hProcess=None): _GetProcessTimes = windll.kernel32.GetProcessTimes _GetProcessTimes.argtypes = [HANDLE, LPFILETIME, LPFILETIME, LPFILETIME, LPFILETIME] - _GetProcessTimes.restype = bool + _GetProcessTimes.restype = bool _GetProcessTimes.errcheck = RaiseIfZero if hProcess is None: hProcess = GetCurrentProcess() CreationTime = FILETIME() - ExitTime = FILETIME() - KernelTime = FILETIME() - UserTime = FILETIME() + ExitTime = FILETIME() + KernelTime = FILETIME() + UserTime = FILETIME() _GetProcessTimes(hProcess, byref(CreationTime), byref(ExitTime), byref(KernelTime), byref(UserTime)) return (CreationTime, ExitTime, KernelTime, UserTime) + # BOOL WINAPI FileTimeToSystemTime( # __in const FILETIME *lpFileTime, # __out LPSYSTEMTIME lpSystemTime @@ -4521,72 +4884,81 @@ def GetProcessTimes(hProcess = None): def FileTimeToSystemTime(lpFileTime): _FileTimeToSystemTime = windll.kernel32.FileTimeToSystemTime _FileTimeToSystemTime.argtypes = [LPFILETIME, LPSYSTEMTIME] - _FileTimeToSystemTime.restype = bool + _FileTimeToSystemTime.restype = bool _FileTimeToSystemTime.errcheck = RaiseIfZero if isinstance(lpFileTime, FILETIME): FileTime = lpFileTime else: FileTime = FILETIME() - FileTime.dwLowDateTime = lpFileTime & 0xFFFFFFFF + FileTime.dwLowDateTime = lpFileTime & 0xFFFFFFFF FileTime.dwHighDateTime = lpFileTime >> 32 SystemTime = SYSTEMTIME() _FileTimeToSystemTime(byref(FileTime), byref(SystemTime)) return SystemTime + # void WINAPI GetSystemTimeAsFileTime( # __out LPFILETIME lpSystemTimeAsFileTime # ); def GetSystemTimeAsFileTime(): _GetSystemTimeAsFileTime = windll.kernel32.GetSystemTimeAsFileTime _GetSystemTimeAsFileTime.argtypes = [LPFILETIME] - _GetSystemTimeAsFileTime.restype = None + _GetSystemTimeAsFileTime.restype = None FileTime = FILETIME() _GetSystemTimeAsFileTime(byref(FileTime)) return FileTime -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # Global ATOM API + # ATOM GlobalAddAtom( # __in LPCTSTR lpString # ); def GlobalAddAtomA(lpString): _GlobalAddAtomA = windll.kernel32.GlobalAddAtomA _GlobalAddAtomA.argtypes = [LPSTR] - _GlobalAddAtomA.restype = ATOM + _GlobalAddAtomA.restype = ATOM _GlobalAddAtomA.errcheck = RaiseIfZero return _GlobalAddAtomA(lpString) + def GlobalAddAtomW(lpString): _GlobalAddAtomW = windll.kernel32.GlobalAddAtomW _GlobalAddAtomW.argtypes = [LPWSTR] - _GlobalAddAtomW.restype = ATOM + _GlobalAddAtomW.restype = ATOM _GlobalAddAtomW.errcheck = RaiseIfZero return _GlobalAddAtomW(lpString) + GlobalAddAtom = GuessStringType(GlobalAddAtomA, GlobalAddAtomW) + # ATOM GlobalFindAtom( # __in LPCTSTR lpString # ); def GlobalFindAtomA(lpString): _GlobalFindAtomA = windll.kernel32.GlobalFindAtomA _GlobalFindAtomA.argtypes = [LPSTR] - _GlobalFindAtomA.restype = ATOM + _GlobalFindAtomA.restype = ATOM _GlobalFindAtomA.errcheck = RaiseIfZero return _GlobalFindAtomA(lpString) + def GlobalFindAtomW(lpString): _GlobalFindAtomW = windll.kernel32.GlobalFindAtomW _GlobalFindAtomW.argtypes = [LPWSTR] - _GlobalFindAtomW.restype = ATOM + _GlobalFindAtomW.restype = ATOM _GlobalFindAtomW.errcheck = RaiseIfZero return _GlobalFindAtomW(lpString) + GlobalFindAtom = GuessStringType(GlobalFindAtomA, GlobalFindAtomW) + # UINT GlobalGetAtomName( # __in ATOM nAtom, # __out LPTSTR lpBuffer, @@ -4595,35 +4967,38 @@ def GlobalFindAtomW(lpString): def GlobalGetAtomNameA(nAtom): _GlobalGetAtomNameA = windll.kernel32.GlobalGetAtomNameA _GlobalGetAtomNameA.argtypes = [ATOM, LPSTR, ctypes.c_int] - _GlobalGetAtomNameA.restype = UINT + _GlobalGetAtomNameA.restype = UINT _GlobalGetAtomNameA.errcheck = RaiseIfZero nSize = 64 while 1: lpBuffer = ctypes.create_string_buffer("", nSize) - nCopied = _GlobalGetAtomNameA(nAtom, lpBuffer, nSize) + nCopied = _GlobalGetAtomNameA(nAtom, lpBuffer, nSize) if nCopied < nSize - 1: break nSize = nSize + 64 return lpBuffer.value + def GlobalGetAtomNameW(nAtom): _GlobalGetAtomNameW = windll.kernel32.GlobalGetAtomNameW _GlobalGetAtomNameW.argtypes = [ATOM, LPWSTR, ctypes.c_int] - _GlobalGetAtomNameW.restype = UINT + _GlobalGetAtomNameW.restype = UINT _GlobalGetAtomNameW.errcheck = RaiseIfZero nSize = 64 while 1: - lpBuffer = ctypes.create_unicode_buffer(u"", nSize) - nCopied = _GlobalGetAtomNameW(nAtom, lpBuffer, nSize) + lpBuffer = ctypes.create_unicode_buffer("", nSize) + nCopied = _GlobalGetAtomNameW(nAtom, lpBuffer, nSize) if nCopied < nSize - 1: break nSize = nSize + 64 return lpBuffer.value + GlobalGetAtomName = GuessStringType(GlobalGetAtomNameA, GlobalGetAtomNameW) + # ATOM GlobalDeleteAtom( # __in ATOM nAtom # ); @@ -4637,22 +5012,25 @@ def GlobalDeleteAtom(nAtom): if error != ERROR_SUCCESS: raise ctypes.WinError(error) -#------------------------------------------------------------------------------ + +# ------------------------------------------------------------------------------ # Wow64 + # DWORD WINAPI Wow64SuspendThread( # _In_ HANDLE hThread # ); def Wow64SuspendThread(hThread): _Wow64SuspendThread = windll.kernel32.Wow64SuspendThread _Wow64SuspendThread.argtypes = [HANDLE] - _Wow64SuspendThread.restype = DWORD + _Wow64SuspendThread.restype = DWORD previousCount = _Wow64SuspendThread(hThread) if previousCount == DWORD(-1).value: raise ctypes.WinError() return previousCount + # BOOLEAN WINAPI Wow64EnableWow64FsRedirection( # __in BOOLEAN Wow64FsEnableRedirection # ); @@ -4666,46 +5044,50 @@ def Wow64EnableWow64FsRedirection(Wow64FsEnableRedirection): """ _Wow64EnableWow64FsRedirection = windll.kernel32.Wow64EnableWow64FsRedirection _Wow64EnableWow64FsRedirection.argtypes = [BOOLEAN] - _Wow64EnableWow64FsRedirection.restype = BOOLEAN + _Wow64EnableWow64FsRedirection.restype = BOOLEAN _Wow64EnableWow64FsRedirection.errcheck = RaiseIfZero + # BOOL WINAPI Wow64DisableWow64FsRedirection( # __out PVOID *OldValue # ); def Wow64DisableWow64FsRedirection(): _Wow64DisableWow64FsRedirection = windll.kernel32.Wow64DisableWow64FsRedirection _Wow64DisableWow64FsRedirection.argtypes = [PPVOID] - _Wow64DisableWow64FsRedirection.restype = BOOL + _Wow64DisableWow64FsRedirection.restype = BOOL _Wow64DisableWow64FsRedirection.errcheck = RaiseIfZero OldValue = PVOID(None) _Wow64DisableWow64FsRedirection(byref(OldValue)) return OldValue + # BOOL WINAPI Wow64RevertWow64FsRedirection( # __in PVOID OldValue # ); def Wow64RevertWow64FsRedirection(OldValue): _Wow64RevertWow64FsRedirection = windll.kernel32.Wow64RevertWow64FsRedirection _Wow64RevertWow64FsRedirection.argtypes = [PVOID] - _Wow64RevertWow64FsRedirection.restype = BOOL + _Wow64RevertWow64FsRedirection.restype = BOOL _Wow64RevertWow64FsRedirection.errcheck = RaiseIfZero _Wow64RevertWow64FsRedirection(OldValue) -#============================================================================== + +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== -#============================================================================== +# ============================================================================== # Mark functions that Psyco cannot compile. # In your programs, don't use psyco.full(). # Call psyco.bind() on your main function instead. try: import psyco + psyco.cannotcompile(WaitForDebugEvent) psyco.cannotcompile(WaitForSingleObject) psyco.cannotcompile(WaitForSingleObjectEx) @@ -4713,4 +5095,4 @@ def Wow64RevertWow64FsRedirection(OldValue): psyco.cannotcompile(WaitForMultipleObjectsEx) except ImportError: pass -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/ntdll.py b/pydevd_attach_to_process/winappdbg/win32/ntdll.py index 39037661d..7396ececb 100644 --- a/pydevd_attach_to_process/winappdbg/win32/ntdll.py +++ b/pydevd_attach_to_process/winappdbg/win32/ntdll.py @@ -36,88 +36,88 @@ from winappdbg.win32.defines import * -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -_all.add('peb_teb') -#============================================================================== +_all.add("peb_teb") +# ============================================================================== from winappdbg.win32.peb_teb import * -#--- Types -------------------------------------------------------------------- +# --- Types -------------------------------------------------------------------- -SYSDBG_COMMAND = DWORD -PROCESSINFOCLASS = DWORD -THREADINFOCLASS = DWORD -FILE_INFORMATION_CLASS = DWORD +SYSDBG_COMMAND = DWORD +PROCESSINFOCLASS = DWORD +THREADINFOCLASS = DWORD +FILE_INFORMATION_CLASS = DWORD -#--- Constants ---------------------------------------------------------------- +# --- Constants ---------------------------------------------------------------- # DEP flags for ProcessExecuteFlags -MEM_EXECUTE_OPTION_ENABLE = 1 -MEM_EXECUTE_OPTION_DISABLE = 2 +MEM_EXECUTE_OPTION_ENABLE = 1 +MEM_EXECUTE_OPTION_DISABLE = 2 MEM_EXECUTE_OPTION_ATL7_THUNK_EMULATION = 4 -MEM_EXECUTE_OPTION_PERMANENT = 8 +MEM_EXECUTE_OPTION_PERMANENT = 8 # SYSTEM_INFORMATION_CLASS # http://www.informit.com/articles/article.aspx?p=22442&seqNum=4 -SystemBasicInformation = 1 # 0x002C -SystemProcessorInformation = 2 # 0x000C -SystemPerformanceInformation = 3 # 0x0138 -SystemTimeInformation = 4 # 0x0020 -SystemPathInformation = 5 # not implemented -SystemProcessInformation = 6 # 0x00F8 + per process -SystemCallInformation = 7 # 0x0018 + (n * 0x0004) -SystemConfigurationInformation = 8 # 0x0018 -SystemProcessorCounters = 9 # 0x0030 per cpu -SystemGlobalFlag = 10 # 0x0004 -SystemInfo10 = 11 # not implemented -SystemModuleInformation = 12 # 0x0004 + (n * 0x011C) -SystemLockInformation = 13 # 0x0004 + (n * 0x0024) -SystemInfo13 = 14 # not implemented -SystemPagedPoolInformation = 15 # checked build only -SystemNonPagedPoolInformation = 16 # checked build only -SystemHandleInformation = 17 # 0x0004 + (n * 0x0010) -SystemObjectInformation = 18 # 0x0038+ + (n * 0x0030+) -SystemPagefileInformation = 19 # 0x0018+ per page file -SystemInstemulInformation = 20 # 0x0088 -SystemInfo20 = 21 # invalid info class -SystemCacheInformation = 22 # 0x0024 -SystemPoolTagInformation = 23 # 0x0004 + (n * 0x001C) -SystemProcessorStatistics = 24 # 0x0000, or 0x0018 per cpu -SystemDpcInformation = 25 # 0x0014 -SystemMemoryUsageInformation1 = 26 # checked build only -SystemLoadImage = 27 # 0x0018, set mode only -SystemUnloadImage = 28 # 0x0004, set mode only -SystemTimeAdjustmentInformation = 29 # 0x000C, 0x0008 writeable -SystemMemoryUsageInformation2 = 30 # checked build only -SystemInfo30 = 31 # checked build only -SystemInfo31 = 32 # checked build only -SystemCrashDumpInformation = 33 # 0x0004 -SystemExceptionInformation = 34 # 0x0010 -SystemCrashDumpStateInformation = 35 # 0x0008 -SystemDebuggerInformation = 36 # 0x0002 -SystemThreadSwitchInformation = 37 # 0x0030 -SystemRegistryQuotaInformation = 38 # 0x000C -SystemLoadDriver = 39 # 0x0008, set mode only -SystemPrioritySeparationInformation = 40 # 0x0004, set mode only -SystemInfo40 = 41 # not implemented -SystemInfo41 = 42 # not implemented -SystemInfo42 = 43 # invalid info class -SystemInfo43 = 44 # invalid info class -SystemTimeZoneInformation = 45 # 0x00AC -SystemLookasideInformation = 46 # n * 0x0020 +SystemBasicInformation = 1 # 0x002C +SystemProcessorInformation = 2 # 0x000C +SystemPerformanceInformation = 3 # 0x0138 +SystemTimeInformation = 4 # 0x0020 +SystemPathInformation = 5 # not implemented +SystemProcessInformation = 6 # 0x00F8 + per process +SystemCallInformation = 7 # 0x0018 + (n * 0x0004) +SystemConfigurationInformation = 8 # 0x0018 +SystemProcessorCounters = 9 # 0x0030 per cpu +SystemGlobalFlag = 10 # 0x0004 +SystemInfo10 = 11 # not implemented +SystemModuleInformation = 12 # 0x0004 + (n * 0x011C) +SystemLockInformation = 13 # 0x0004 + (n * 0x0024) +SystemInfo13 = 14 # not implemented +SystemPagedPoolInformation = 15 # checked build only +SystemNonPagedPoolInformation = 16 # checked build only +SystemHandleInformation = 17 # 0x0004 + (n * 0x0010) +SystemObjectInformation = 18 # 0x0038+ + (n * 0x0030+) +SystemPagefileInformation = 19 # 0x0018+ per page file +SystemInstemulInformation = 20 # 0x0088 +SystemInfo20 = 21 # invalid info class +SystemCacheInformation = 22 # 0x0024 +SystemPoolTagInformation = 23 # 0x0004 + (n * 0x001C) +SystemProcessorStatistics = 24 # 0x0000, or 0x0018 per cpu +SystemDpcInformation = 25 # 0x0014 +SystemMemoryUsageInformation1 = 26 # checked build only +SystemLoadImage = 27 # 0x0018, set mode only +SystemUnloadImage = 28 # 0x0004, set mode only +SystemTimeAdjustmentInformation = 29 # 0x000C, 0x0008 writeable +SystemMemoryUsageInformation2 = 30 # checked build only +SystemInfo30 = 31 # checked build only +SystemInfo31 = 32 # checked build only +SystemCrashDumpInformation = 33 # 0x0004 +SystemExceptionInformation = 34 # 0x0010 +SystemCrashDumpStateInformation = 35 # 0x0008 +SystemDebuggerInformation = 36 # 0x0002 +SystemThreadSwitchInformation = 37 # 0x0030 +SystemRegistryQuotaInformation = 38 # 0x000C +SystemLoadDriver = 39 # 0x0008, set mode only +SystemPrioritySeparationInformation = 40 # 0x0004, set mode only +SystemInfo40 = 41 # not implemented +SystemInfo41 = 42 # not implemented +SystemInfo42 = 43 # invalid info class +SystemInfo43 = 44 # invalid info class +SystemTimeZoneInformation = 45 # 0x00AC +SystemLookasideInformation = 46 # n * 0x0020 # info classes specific to Windows 2000 # WTS = Windows Terminal Server -SystemSetTimeSlipEvent = 47 # set mode only -SystemCreateSession = 48 # WTS, set mode only -SystemDeleteSession = 49 # WTS, set mode only -SystemInfo49 = 50 # invalid info class -SystemRangeStartInformation = 51 # 0x0004 -SystemVerifierInformation = 52 # 0x0068 -SystemAddVerifier = 53 # set mode only -SystemSessionProcessesInformation = 54 # WTS +SystemSetTimeSlipEvent = 47 # set mode only +SystemCreateSession = 48 # WTS, set mode only +SystemDeleteSession = 49 # WTS, set mode only +SystemInfo49 = 50 # invalid info class +SystemRangeStartInformation = 51 # 0x0004 +SystemVerifierInformation = 52 # 0x0068 +SystemAddVerifier = 53 # set mode only +SystemSessionProcessesInformation = 54 # WTS # NtQueryInformationProcess constants (from MSDN) ##ProcessBasicInformation = 0 @@ -127,107 +127,107 @@ # PROCESS_INFORMATION_CLASS # http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PROCESS_INFORMATION_CLASS.html -ProcessBasicInformation = 0 -ProcessQuotaLimits = 1 -ProcessIoCounters = 2 -ProcessVmCounters = 3 -ProcessTimes = 4 -ProcessBasePriority = 5 -ProcessRaisePriority = 6 -ProcessDebugPort = 7 -ProcessExceptionPort = 8 -ProcessAccessToken = 9 -ProcessLdtInformation = 10 -ProcessLdtSize = 11 -ProcessDefaultHardErrorMode = 12 -ProcessIoPortHandlers = 13 -ProcessPooledUsageAndLimits = 14 -ProcessWorkingSetWatch = 15 -ProcessUserModeIOPL = 16 -ProcessEnableAlignmentFaultFixup = 17 -ProcessPriorityClass = 18 -ProcessWx86Information = 19 -ProcessHandleCount = 20 -ProcessAffinityMask = 21 -ProcessPriorityBoost = 22 - -ProcessWow64Information = 26 -ProcessImageFileName = 27 +ProcessBasicInformation = 0 +ProcessQuotaLimits = 1 +ProcessIoCounters = 2 +ProcessVmCounters = 3 +ProcessTimes = 4 +ProcessBasePriority = 5 +ProcessRaisePriority = 6 +ProcessDebugPort = 7 +ProcessExceptionPort = 8 +ProcessAccessToken = 9 +ProcessLdtInformation = 10 +ProcessLdtSize = 11 +ProcessDefaultHardErrorMode = 12 +ProcessIoPortHandlers = 13 +ProcessPooledUsageAndLimits = 14 +ProcessWorkingSetWatch = 15 +ProcessUserModeIOPL = 16 +ProcessEnableAlignmentFaultFixup = 17 +ProcessPriorityClass = 18 +ProcessWx86Information = 19 +ProcessHandleCount = 20 +ProcessAffinityMask = 21 +ProcessPriorityBoost = 22 + +ProcessWow64Information = 26 +ProcessImageFileName = 27 # http://www.codeproject.com/KB/security/AntiReverseEngineering.aspx -ProcessDebugObjectHandle = 30 +ProcessDebugObjectHandle = 30 -ProcessExecuteFlags = 34 +ProcessExecuteFlags = 34 # THREAD_INFORMATION_CLASS -ThreadBasicInformation = 0 -ThreadTimes = 1 -ThreadPriority = 2 -ThreadBasePriority = 3 -ThreadAffinityMask = 4 -ThreadImpersonationToken = 5 -ThreadDescriptorTableEntry = 6 -ThreadEnableAlignmentFaultFixup = 7 -ThreadEventPair = 8 -ThreadQuerySetWin32StartAddress = 9 -ThreadZeroTlsCell = 10 -ThreadPerformanceCount = 11 -ThreadAmILastThread = 12 -ThreadIdealProcessor = 13 -ThreadPriorityBoost = 14 -ThreadSetTlsArrayAddress = 15 -ThreadIsIoPending = 16 -ThreadHideFromDebugger = 17 +ThreadBasicInformation = 0 +ThreadTimes = 1 +ThreadPriority = 2 +ThreadBasePriority = 3 +ThreadAffinityMask = 4 +ThreadImpersonationToken = 5 +ThreadDescriptorTableEntry = 6 +ThreadEnableAlignmentFaultFixup = 7 +ThreadEventPair = 8 +ThreadQuerySetWin32StartAddress = 9 +ThreadZeroTlsCell = 10 +ThreadPerformanceCount = 11 +ThreadAmILastThread = 12 +ThreadIdealProcessor = 13 +ThreadPriorityBoost = 14 +ThreadSetTlsArrayAddress = 15 +ThreadIsIoPending = 16 +ThreadHideFromDebugger = 17 # OBJECT_INFORMATION_CLASS -ObjectBasicInformation = 0 -ObjectNameInformation = 1 -ObjectTypeInformation = 2 -ObjectAllTypesInformation = 3 -ObjectHandleInformation = 4 +ObjectBasicInformation = 0 +ObjectNameInformation = 1 +ObjectTypeInformation = 2 +ObjectAllTypesInformation = 3 +ObjectHandleInformation = 4 # FILE_INFORMATION_CLASS -FileDirectoryInformation = 1 -FileFullDirectoryInformation = 2 -FileBothDirectoryInformation = 3 -FileBasicInformation = 4 -FileStandardInformation = 5 -FileInternalInformation = 6 -FileEaInformation = 7 -FileAccessInformation = 8 -FileNameInformation = 9 -FileRenameInformation = 10 -FileLinkInformation = 11 -FileNamesInformation = 12 -FileDispositionInformation = 13 -FilePositionInformation = 14 -FileFullEaInformation = 15 -FileModeInformation = 16 -FileAlignmentInformation = 17 -FileAllInformation = 18 -FileAllocationInformation = 19 -FileEndOfFileInformation = 20 -FileAlternateNameInformation = 21 -FileStreamInformation = 22 -FilePipeInformation = 23 -FilePipeLocalInformation = 24 -FilePipeRemoteInformation = 25 -FileMailslotQueryInformation = 26 -FileMailslotSetInformation = 27 -FileCompressionInformation = 28 -FileCopyOnWriteInformation = 29 -FileCompletionInformation = 30 -FileMoveClusterInformation = 31 -FileQuotaInformation = 32 -FileReparsePointInformation = 33 -FileNetworkOpenInformation = 34 -FileObjectIdInformation = 35 -FileTrackingInformation = 36 -FileOleDirectoryInformation = 37 -FileContentIndexInformation = 38 -FileInheritContentIndexInformation = 37 -FileOleInformation = 39 -FileMaximumInformation = 40 +FileDirectoryInformation = 1 +FileFullDirectoryInformation = 2 +FileBothDirectoryInformation = 3 +FileBasicInformation = 4 +FileStandardInformation = 5 +FileInternalInformation = 6 +FileEaInformation = 7 +FileAccessInformation = 8 +FileNameInformation = 9 +FileRenameInformation = 10 +FileLinkInformation = 11 +FileNamesInformation = 12 +FileDispositionInformation = 13 +FilePositionInformation = 14 +FileFullEaInformation = 15 +FileModeInformation = 16 +FileAlignmentInformation = 17 +FileAllInformation = 18 +FileAllocationInformation = 19 +FileEndOfFileInformation = 20 +FileAlternateNameInformation = 21 +FileStreamInformation = 22 +FilePipeInformation = 23 +FilePipeLocalInformation = 24 +FilePipeRemoteInformation = 25 +FileMailslotQueryInformation = 26 +FileMailslotSetInformation = 27 +FileCompressionInformation = 28 +FileCopyOnWriteInformation = 29 +FileCompletionInformation = 30 +FileMoveClusterInformation = 31 +FileQuotaInformation = 32 +FileReparsePointInformation = 33 +FileNetworkOpenInformation = 34 +FileObjectIdInformation = 35 +FileTrackingInformation = 36 +FileOleDirectoryInformation = 37 +FileContentIndexInformation = 38 +FileInheritContentIndexInformation = 37 +FileOleInformation = 39 +FileMaximumInformation = 40 # From http://www.nirsoft.net/kernel_struct/vista/EXCEPTION_DISPOSITION.html # typedef enum _EXCEPTION_DISPOSITION @@ -237,12 +237,12 @@ # ExceptionNestedException = 2, # ExceptionCollidedUnwind = 3 # } EXCEPTION_DISPOSITION; -ExceptionContinueExecution = 0 -ExceptionContinueSearch = 1 -ExceptionNestedException = 2 -ExceptionCollidedUnwind = 3 +ExceptionContinueExecution = 0 +ExceptionContinueSearch = 1 +ExceptionNestedException = 2 +ExceptionCollidedUnwind = 3 -#--- PROCESS_BASIC_INFORMATION structure -------------------------------------- +# --- PROCESS_BASIC_INFORMATION structure -------------------------------------- # From MSDN: # @@ -275,18 +275,21 @@ # ULONG_PTR InheritedFromUniqueProcessId; # } PROCESS_BASIC_INFORMATION; + # My own definition follows: class PROCESS_BASIC_INFORMATION(Structure): _fields_ = [ - ("ExitStatus", SIZE_T), - ("PebBaseAddress", PVOID), # PPEB - ("AffinityMask", KAFFINITY), - ("BasePriority", SDWORD), - ("UniqueProcessId", ULONG_PTR), - ("InheritedFromUniqueProcessId", ULONG_PTR), -] + ("ExitStatus", SIZE_T), + ("PebBaseAddress", PVOID), # PPEB + ("AffinityMask", KAFFINITY), + ("BasePriority", SDWORD), + ("UniqueProcessId", ULONG_PTR), + ("InheritedFromUniqueProcessId", ULONG_PTR), + ] + + +# --- THREAD_BASIC_INFORMATION structure --------------------------------------- -#--- THREAD_BASIC_INFORMATION structure --------------------------------------- # From http://undocumented.ntinternals.net/UserMode/Structures/THREAD_BASIC_INFORMATION.html # @@ -300,15 +303,17 @@ class PROCESS_BASIC_INFORMATION(Structure): # } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION; class THREAD_BASIC_INFORMATION(Structure): _fields_ = [ - ("ExitStatus", NTSTATUS), - ("TebBaseAddress", PVOID), # PTEB - ("ClientId", CLIENT_ID), - ("AffinityMask", KAFFINITY), - ("Priority", SDWORD), - ("BasePriority", SDWORD), -] + ("ExitStatus", NTSTATUS), + ("TebBaseAddress", PVOID), # PTEB + ("ClientId", CLIENT_ID), + ("AffinityMask", KAFFINITY), + ("Priority", SDWORD), + ("BasePriority", SDWORD), + ] + + +# --- FILE_NAME_INFORMATION structure ------------------------------------------ -#--- FILE_NAME_INFORMATION structure ------------------------------------------ # typedef struct _FILE_NAME_INFORMATION { # ULONG FileNameLength; @@ -316,22 +321,26 @@ class THREAD_BASIC_INFORMATION(Structure): # } FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; class FILE_NAME_INFORMATION(Structure): _fields_ = [ - ("FileNameLength", ULONG), - ("FileName", WCHAR * 1), + ("FileNameLength", ULONG), + ("FileName", WCHAR * 1), ] -#--- SYSDBG_MSR structure and constants --------------------------------------- -SysDbgReadMsr = 16 +# --- SYSDBG_MSR structure and constants --------------------------------------- + +SysDbgReadMsr = 16 SysDbgWriteMsr = 17 + class SYSDBG_MSR(Structure): _fields_ = [ ("Address", ULONG), - ("Data", ULONGLONG), -] + ("Data", ULONGLONG), + ] + + +# --- IO_STATUS_BLOCK structure ------------------------------------------------ -#--- IO_STATUS_BLOCK structure ------------------------------------------------ # typedef struct _IO_STATUS_BLOCK { # union { @@ -342,18 +351,23 @@ class SYSDBG_MSR(Structure): # } IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; class IO_STATUS_BLOCK(Structure): _fields_ = [ - ("Status", NTSTATUS), + ("Status", NTSTATUS), ("Information", ULONG_PTR), ] + def __get_Pointer(self): return PVOID(self.Status) + def __set_Pointer(self, ptr): self.Status = ptr.value + Pointer = property(__get_Pointer, __set_Pointer) + PIO_STATUS_BLOCK = POINTER(IO_STATUS_BLOCK) -#--- ntdll.dll ---------------------------------------------------------------- +# --- ntdll.dll ---------------------------------------------------------------- + # ULONG WINAPI RtlNtStatusToDosError( # __in NTSTATUS Status @@ -364,6 +378,7 @@ def RtlNtStatusToDosError(Status): _RtlNtStatusToDosError.restype = ULONG return _RtlNtStatusToDosError(Status) + # NTSYSAPI NTSTATUS NTAPI NtSystemDebugControl( # IN SYSDBG_COMMAND Command, # IN PVOID InputBuffer OPTIONAL, @@ -372,7 +387,7 @@ def RtlNtStatusToDosError(Status): # IN ULONG OutputBufferLength, # OUT PULONG ReturnLength OPTIONAL # ); -def NtSystemDebugControl(Command, InputBuffer = None, InputBufferLength = None, OutputBuffer = None, OutputBufferLength = None): +def NtSystemDebugControl(Command, InputBuffer=None, InputBufferLength=None, OutputBuffer=None, OutputBufferLength=None): _NtSystemDebugControl = windll.ntdll.NtSystemDebugControl _NtSystemDebugControl.argtypes = [SYSDBG_COMMAND, PVOID, ULONG, PVOID, ULONG, PULONG] _NtSystemDebugControl.restype = NTSTATUS @@ -382,9 +397,7 @@ def NtSystemDebugControl(Command, InputBuffer = None, InputBufferLength = None, if InputBufferLength is None: InputBufferLength = 0 else: - raise ValueError( - "Invalid call to NtSystemDebugControl: " - "input buffer length given but no input buffer!") + raise ValueError("Invalid call to NtSystemDebugControl: " "input buffer length given but no input buffer!") else: if InputBufferLength is None: InputBufferLength = sizeof(InputBuffer) @@ -402,9 +415,11 @@ def NtSystemDebugControl(Command, InputBuffer = None, InputBufferLength = None, # Make the call (with an output buffer) if OutputBuffer is not None: ReturnLength = ULONG(0) - ntstatus = _NtSystemDebugControl(Command, InputBuffer, InputBufferLength, byref(OutputBuffer), OutputBufferLength, byref(ReturnLength)) + ntstatus = _NtSystemDebugControl( + Command, InputBuffer, InputBufferLength, byref(OutputBuffer), OutputBufferLength, byref(ReturnLength) + ) if ntstatus != 0: - raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) ) + raise ctypes.WinError(RtlNtStatusToDosError(ntstatus)) ReturnLength = ReturnLength.value if ReturnLength != OutputBufferLength: raise ctypes.WinError(ERROR_BAD_LENGTH) @@ -413,10 +428,12 @@ def NtSystemDebugControl(Command, InputBuffer = None, InputBufferLength = None, # Make the call (without an output buffer) ntstatus = _NtSystemDebugControl(Command, InputBuffer, InputBufferLength, OutputBuffer, OutputBufferLength, None) if ntstatus != 0: - raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) ) + raise ctypes.WinError(RtlNtStatusToDosError(ntstatus)) + ZwSystemDebugControl = NtSystemDebugControl + # NTSTATUS WINAPI NtQueryInformationProcess( # __in HANDLE ProcessHandle, # __in PROCESSINFOCLASS ProcessInformationClass, @@ -424,43 +441,59 @@ def NtSystemDebugControl(Command, InputBuffer = None, InputBufferLength = None, # __in ULONG ProcessInformationLength, # __out_opt PULONG ReturnLength # ); -def NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformationLength = None): +def NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformationLength=None): _NtQueryInformationProcess = windll.ntdll.NtQueryInformationProcess _NtQueryInformationProcess.argtypes = [HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG] _NtQueryInformationProcess.restype = NTSTATUS if ProcessInformationLength is not None: ProcessInformation = ctypes.create_string_buffer("", ProcessInformationLength) else: - if ProcessInformationClass == ProcessBasicInformation: + if ProcessInformationClass == ProcessBasicInformation: ProcessInformation = PROCESS_BASIC_INFORMATION() ProcessInformationLength = sizeof(PROCESS_BASIC_INFORMATION) elif ProcessInformationClass == ProcessImageFileName: - unicode_buffer = ctypes.create_unicode_buffer(u"", 0x1000) + unicode_buffer = ctypes.create_unicode_buffer("", 0x1000) ProcessInformation = UNICODE_STRING(0, 0x1000, addressof(unicode_buffer)) ProcessInformationLength = sizeof(UNICODE_STRING) - elif ProcessInformationClass in (ProcessDebugPort, ProcessWow64Information, ProcessWx86Information, ProcessHandleCount, ProcessPriorityBoost): + elif ProcessInformationClass in ( + ProcessDebugPort, + ProcessWow64Information, + ProcessWx86Information, + ProcessHandleCount, + ProcessPriorityBoost, + ): ProcessInformation = DWORD() ProcessInformationLength = sizeof(DWORD) else: raise Exception("Unknown ProcessInformationClass, use an explicit ProcessInformationLength value instead") ReturnLength = ULONG(0) - ntstatus = _NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, byref(ProcessInformation), ProcessInformationLength, byref(ReturnLength)) + ntstatus = _NtQueryInformationProcess( + ProcessHandle, ProcessInformationClass, byref(ProcessInformation), ProcessInformationLength, byref(ReturnLength) + ) if ntstatus != 0: - raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) ) - if ProcessInformationClass == ProcessBasicInformation: + raise ctypes.WinError(RtlNtStatusToDosError(ntstatus)) + if ProcessInformationClass == ProcessBasicInformation: retval = ProcessInformation - elif ProcessInformationClass in (ProcessDebugPort, ProcessWow64Information, ProcessWx86Information, ProcessHandleCount, ProcessPriorityBoost): + elif ProcessInformationClass in ( + ProcessDebugPort, + ProcessWow64Information, + ProcessWx86Information, + ProcessHandleCount, + ProcessPriorityBoost, + ): retval = ProcessInformation.value elif ProcessInformationClass == ProcessImageFileName: vptr = ctypes.c_void_p(ProcessInformation.Buffer) - cptr = ctypes.cast( vptr, ctypes.c_wchar * ProcessInformation.Length ) + cptr = ctypes.cast(vptr, ctypes.c_wchar * ProcessInformation.Length) retval = cptr.contents.raw else: - retval = ProcessInformation.raw[:ReturnLength.value] + retval = ProcessInformation.raw[: ReturnLength.value] return retval + ZwQueryInformationProcess = NtQueryInformationProcess + # NTSTATUS WINAPI NtQueryInformationThread( # __in HANDLE ThreadHandle, # __in THREADINFOCLASS ThreadInformationClass, @@ -468,14 +501,14 @@ def NtQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInf # __in ULONG ThreadInformationLength, # __out_opt PULONG ReturnLength # ); -def NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformationLength = None): +def NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInformationLength=None): _NtQueryInformationThread = windll.ntdll.NtQueryInformationThread _NtQueryInformationThread.argtypes = [HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG] _NtQueryInformationThread.restype = NTSTATUS if ThreadInformationLength is not None: ThreadInformation = ctypes.create_string_buffer("", ThreadInformationLength) else: - if ThreadInformationClass == ThreadBasicInformation: + if ThreadInformationClass == ThreadBasicInformation: ThreadInformation = THREAD_BASIC_INFORMATION() elif ThreadInformationClass == ThreadHideFromDebugger: ThreadInformation = BOOLEAN() @@ -489,21 +522,25 @@ def NtQueryInformationThread(ThreadHandle, ThreadInformationClass, ThreadInforma raise Exception("Unknown ThreadInformationClass, use an explicit ThreadInformationLength value instead") ThreadInformationLength = sizeof(ThreadInformation) ReturnLength = ULONG(0) - ntstatus = _NtQueryInformationThread(ThreadHandle, ThreadInformationClass, byref(ThreadInformation), ThreadInformationLength, byref(ReturnLength)) + ntstatus = _NtQueryInformationThread( + ThreadHandle, ThreadInformationClass, byref(ThreadInformation), ThreadInformationLength, byref(ReturnLength) + ) if ntstatus != 0: - raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) ) - if ThreadInformationClass == ThreadBasicInformation: + raise ctypes.WinError(RtlNtStatusToDosError(ntstatus)) + if ThreadInformationClass == ThreadBasicInformation: retval = ThreadInformation elif ThreadInformationClass == ThreadHideFromDebugger: retval = bool(ThreadInformation.value) elif ThreadInformationClass in (ThreadQuerySetWin32StartAddress, ThreadAmILastThread, ThreadPriorityBoost, ThreadPerformanceCount): retval = ThreadInformation.value else: - retval = ThreadInformation.raw[:ReturnLength.value] + retval = ThreadInformation.raw[: ReturnLength.value] return retval + ZwQueryInformationThread = NtQueryInformationThread + # NTSTATUS # NtQueryInformationFile( # IN HANDLE FileHandle, @@ -519,11 +556,13 @@ def NtQueryInformationFile(FileHandle, FileInformationClass, FileInformation, Le IoStatusBlock = IO_STATUS_BLOCK() ntstatus = _NtQueryInformationFile(FileHandle, byref(IoStatusBlock), byref(FileInformation), Length, FileInformationClass) if ntstatus != 0: - raise ctypes.WinError( RtlNtStatusToDosError(ntstatus) ) + raise ctypes.WinError(RtlNtStatusToDosError(ntstatus)) return IoStatusBlock + ZwQueryInformationFile = NtQueryInformationFile + # DWORD STDCALL CsrGetProcessId (VOID); def CsrGetProcessId(): _CsrGetProcessId = windll.ntdll.CsrGetProcessId @@ -531,9 +570,10 @@ def CsrGetProcessId(): _CsrGetProcessId.restype = DWORD return _CsrGetProcessId() -#============================================================================== + +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/peb_teb.py b/pydevd_attach_to_process/winappdbg/win32/peb_teb.py index 9d101c709..9ae466074 100644 --- a/pydevd_attach_to_process/winappdbg/win32/peb_teb.py +++ b/pydevd_attach_to_process/winappdbg/win32/peb_teb.py @@ -37,13 +37,14 @@ from winappdbg.win32.defines import * from winappdbg.win32.version import os -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== + +# --- PEB and TEB structures, constants and data types ------------------------- -#--- PEB and TEB structures, constants and data types ------------------------- # From http://www.nirsoft.net/kernel_struct/vista/CLIENT_ID.html # @@ -54,9 +55,10 @@ # } CLIENT_ID, *PCLIENT_ID; class CLIENT_ID(Structure): _fields_ = [ - ("UniqueProcess", PVOID), - ("UniqueThread", PVOID), -] + ("UniqueProcess", PVOID), + ("UniqueThread", PVOID), + ] + # From MSDN: # @@ -208,6 +210,7 @@ class CLIENT_ID(Structure): ## def CurrentDirectories(self): ## return self.CurrentDirectores + # From MSDN: # # typedef struct _RTL_USER_PROCESS_PARAMETERS { @@ -219,21 +222,22 @@ class CLIENT_ID(Structure): # *PRTL_USER_PROCESS_PARAMETERS; class RTL_USER_PROCESS_PARAMETERS(Structure): _fields_ = [ - ("Reserved1", BYTE * 16), - ("Reserved2", PVOID * 10), - ("ImagePathName", UNICODE_STRING), - ("CommandLine", UNICODE_STRING), - ("Environment", PVOID), # undocumented! + ("Reserved1", BYTE * 16), + ("Reserved2", PVOID * 10), + ("ImagePathName", UNICODE_STRING), + ("CommandLine", UNICODE_STRING), + ("Environment", PVOID), # undocumented! # # XXX TODO # This structure should be defined with all undocumented fields for # each version of Windows, just like it's being done for PEB and TEB. # -] + ] + PPS_POST_PROCESS_INIT_ROUTINE = PVOID -#from MSDN: +# from MSDN: # # typedef struct _PEB { # BYTE Reserved1[2]; @@ -284,6 +288,7 @@ class RTL_USER_PROCESS_PARAMETERS(Structure): ## ("TlsExpansionSlots", PVOID), ##] + # from http://undocumented.ntinternals.net/UserMode/Structures/LDR_MODULE.html # # typedef struct _LDR_MODULE { @@ -303,20 +308,21 @@ class RTL_USER_PROCESS_PARAMETERS(Structure): # } LDR_MODULE, *PLDR_MODULE; class LDR_MODULE(Structure): _fields_ = [ - ("InLoadOrderModuleList", LIST_ENTRY), - ("InMemoryOrderModuleList", LIST_ENTRY), + ("InLoadOrderModuleList", LIST_ENTRY), + ("InMemoryOrderModuleList", LIST_ENTRY), ("InInitializationOrderModuleList", LIST_ENTRY), - ("BaseAddress", PVOID), - ("EntryPoint", PVOID), - ("SizeOfImage", ULONG), - ("FullDllName", UNICODE_STRING), - ("BaseDllName", UNICODE_STRING), - ("Flags", ULONG), - ("LoadCount", SHORT), - ("TlsIndex", SHORT), - ("HashTableEntry", LIST_ENTRY), - ("TimeDateStamp", ULONG), -] + ("BaseAddress", PVOID), + ("EntryPoint", PVOID), + ("SizeOfImage", ULONG), + ("FullDllName", UNICODE_STRING), + ("BaseDllName", UNICODE_STRING), + ("Flags", ULONG), + ("LoadCount", SHORT), + ("TlsIndex", SHORT), + ("HashTableEntry", LIST_ENTRY), + ("TimeDateStamp", ULONG), + ] + # from http://undocumented.ntinternals.net/UserMode/Structures/PEB_LDR_DATA.html # @@ -330,13 +336,14 @@ class LDR_MODULE(Structure): # } PEB_LDR_DATA, *PPEB_LDR_DATA; class PEB_LDR_DATA(Structure): _fields_ = [ - ("Length", ULONG), - ("Initialized", BOOLEAN), - ("SsHandle", PVOID), - ("InLoadOrderModuleList", LIST_ENTRY), - ("InMemoryOrderModuleList", LIST_ENTRY), + ("Length", ULONG), + ("Initialized", BOOLEAN), + ("SsHandle", PVOID), + ("InLoadOrderModuleList", LIST_ENTRY), + ("InMemoryOrderModuleList", LIST_ENTRY), ("InInitializationOrderModuleList", LIST_ENTRY), -] + ] + # From http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/Process/PEB_FREE_BLOCK.html # @@ -347,14 +354,16 @@ class PEB_LDR_DATA(Structure): class PEB_FREE_BLOCK(Structure): pass + ##PPEB_FREE_BLOCK = POINTER(PEB_FREE_BLOCK) PPEB_FREE_BLOCK = PVOID PEB_FREE_BLOCK._fields_ = [ - ("Next", PPEB_FREE_BLOCK), - ("Size", ULONG), + ("Next", PPEB_FREE_BLOCK), + ("Size", ULONG), ] + # From http://undocumented.ntinternals.net/UserMode/Structures/RTL_DRIVE_LETTER_CURDIR.html # # typedef struct _RTL_DRIVE_LETTER_CURDIR { @@ -365,11 +374,12 @@ class PEB_FREE_BLOCK(Structure): # } RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR; class RTL_DRIVE_LETTER_CURDIR(Structure): _fields_ = [ - ("Flags", USHORT), - ("Length", USHORT), - ("TimeStamp", ULONG), - ("DosPath", UNICODE_STRING), -] + ("Flags", USHORT), + ("Length", USHORT), + ("TimeStamp", ULONG), + ("DosPath", UNICODE_STRING), + ] + # From http://www.nirsoft.net/kernel_struct/vista/CURDIR.html # @@ -381,8 +391,9 @@ class RTL_DRIVE_LETTER_CURDIR(Structure): class CURDIR(Structure): _fields_ = [ ("DosPath", UNICODE_STRING), - ("Handle", PVOID), -] + ("Handle", PVOID), + ] + # From http://www.nirsoft.net/kernel_struct/vista/RTL_CRITICAL_SECTION_DEBUG.html # @@ -413,147 +424,154 @@ class CURDIR(Structure): # class RTL_CRITICAL_SECTION(Structure): _fields_ = [ - ("DebugInfo", PVOID), # PRTL_CRITICAL_SECTION_DEBUG - ("LockCount", LONG), - ("RecursionCount", LONG), - ("OwningThread", PVOID), - ("LockSemaphore", PVOID), - ("SpinCount", ULONG), -] + ("DebugInfo", PVOID), # PRTL_CRITICAL_SECTION_DEBUG + ("LockCount", LONG), + ("RecursionCount", LONG), + ("OwningThread", PVOID), + ("LockSemaphore", PVOID), + ("SpinCount", ULONG), + ] + + class RTL_CRITICAL_SECTION_DEBUG(Structure): _fields_ = [ - ("Type", WORD), - ("CreatorBackTraceIndex", WORD), - ("CriticalSection", PVOID), # PRTL_CRITICAL_SECTION - ("ProcessLocksList", LIST_ENTRY), - ("EntryCount", ULONG), - ("ContentionCount", ULONG), - ("Flags", ULONG), - ("CreatorBackTraceIndexHigh", WORD), - ("SpareUSHORT", WORD), -] -PRTL_CRITICAL_SECTION = POINTER(RTL_CRITICAL_SECTION) + ("Type", WORD), + ("CreatorBackTraceIndex", WORD), + ("CriticalSection", PVOID), # PRTL_CRITICAL_SECTION + ("ProcessLocksList", LIST_ENTRY), + ("EntryCount", ULONG), + ("ContentionCount", ULONG), + ("Flags", ULONG), + ("CreatorBackTraceIndexHigh", WORD), + ("SpareUSHORT", WORD), + ] + + +PRTL_CRITICAL_SECTION = POINTER(RTL_CRITICAL_SECTION) PRTL_CRITICAL_SECTION_DEBUG = POINTER(RTL_CRITICAL_SECTION_DEBUG) -PPEB_LDR_DATA = POINTER(PEB_LDR_DATA) -PRTL_USER_PROCESS_PARAMETERS = POINTER(RTL_USER_PROCESS_PARAMETERS) +PPEB_LDR_DATA = POINTER(PEB_LDR_DATA) +PRTL_USER_PROCESS_PARAMETERS = POINTER(RTL_USER_PROCESS_PARAMETERS) -PPEBLOCKROUTINE = PVOID +PPEBLOCKROUTINE = PVOID # BitField -ImageUsesLargePages = 1 << 0 -IsProtectedProcess = 1 << 1 -IsLegacyProcess = 1 << 2 -IsImageDynamicallyRelocated = 1 << 3 -SkipPatchingUser32Forwarders = 1 << 4 +ImageUsesLargePages = 1 << 0 +IsProtectedProcess = 1 << 1 +IsLegacyProcess = 1 << 2 +IsImageDynamicallyRelocated = 1 << 3 +SkipPatchingUser32Forwarders = 1 << 4 # CrossProcessFlags -ProcessInJob = 1 << 0 -ProcessInitializing = 1 << 1 -ProcessUsingVEH = 1 << 2 -ProcessUsingVCH = 1 << 3 -ProcessUsingFTH = 1 << 4 +ProcessInJob = 1 << 0 +ProcessInitializing = 1 << 1 +ProcessUsingVEH = 1 << 2 +ProcessUsingVCH = 1 << 3 +ProcessUsingFTH = 1 << 4 # TracingFlags -HeapTracingEnabled = 1 << 0 -CritSecTracingEnabled = 1 << 1 +HeapTracingEnabled = 1 << 0 +CritSecTracingEnabled = 1 << 1 # NtGlobalFlags -FLG_VALID_BITS = 0x003FFFFF # not a flag -FLG_STOP_ON_EXCEPTION = 0x00000001 -FLG_SHOW_LDR_SNAPS = 0x00000002 -FLG_DEBUG_INITIAL_COMMAND = 0x00000004 -FLG_STOP_ON_HUNG_GUI = 0x00000008 -FLG_HEAP_ENABLE_TAIL_CHECK = 0x00000010 -FLG_HEAP_ENABLE_FREE_CHECK = 0x00000020 -FLG_HEAP_VALIDATE_PARAMETERS = 0x00000040 -FLG_HEAP_VALIDATE_ALL = 0x00000080 -FLG_POOL_ENABLE_TAIL_CHECK = 0x00000100 -FLG_POOL_ENABLE_FREE_CHECK = 0x00000200 -FLG_POOL_ENABLE_TAGGING = 0x00000400 -FLG_HEAP_ENABLE_TAGGING = 0x00000800 -FLG_USER_STACK_TRACE_DB = 0x00001000 -FLG_KERNEL_STACK_TRACE_DB = 0x00002000 -FLG_MAINTAIN_OBJECT_TYPELIST = 0x00004000 -FLG_HEAP_ENABLE_TAG_BY_DLL = 0x00008000 -FLG_IGNORE_DEBUG_PRIV = 0x00010000 -FLG_ENABLE_CSRDEBUG = 0x00020000 -FLG_ENABLE_KDEBUG_SYMBOL_LOAD = 0x00040000 -FLG_DISABLE_PAGE_KERNEL_STACKS = 0x00080000 -FLG_HEAP_ENABLE_CALL_TRACING = 0x00100000 -FLG_HEAP_DISABLE_COALESCING = 0x00200000 -FLG_ENABLE_CLOSE_EXCEPTION = 0x00400000 -FLG_ENABLE_EXCEPTION_LOGGING = 0x00800000 -FLG_ENABLE_HANDLE_TYPE_TAGGING = 0x01000000 -FLG_HEAP_PAGE_ALLOCS = 0x02000000 -FLG_DEBUG_WINLOGON = 0x04000000 -FLG_ENABLE_DBGPRINT_BUFFERING = 0x08000000 -FLG_EARLY_CRITICAL_SECTION_EVT = 0x10000000 -FLG_DISABLE_DLL_VERIFICATION = 0x80000000 +FLG_VALID_BITS = 0x003FFFFF # not a flag +FLG_STOP_ON_EXCEPTION = 0x00000001 +FLG_SHOW_LDR_SNAPS = 0x00000002 +FLG_DEBUG_INITIAL_COMMAND = 0x00000004 +FLG_STOP_ON_HUNG_GUI = 0x00000008 +FLG_HEAP_ENABLE_TAIL_CHECK = 0x00000010 +FLG_HEAP_ENABLE_FREE_CHECK = 0x00000020 +FLG_HEAP_VALIDATE_PARAMETERS = 0x00000040 +FLG_HEAP_VALIDATE_ALL = 0x00000080 +FLG_POOL_ENABLE_TAIL_CHECK = 0x00000100 +FLG_POOL_ENABLE_FREE_CHECK = 0x00000200 +FLG_POOL_ENABLE_TAGGING = 0x00000400 +FLG_HEAP_ENABLE_TAGGING = 0x00000800 +FLG_USER_STACK_TRACE_DB = 0x00001000 +FLG_KERNEL_STACK_TRACE_DB = 0x00002000 +FLG_MAINTAIN_OBJECT_TYPELIST = 0x00004000 +FLG_HEAP_ENABLE_TAG_BY_DLL = 0x00008000 +FLG_IGNORE_DEBUG_PRIV = 0x00010000 +FLG_ENABLE_CSRDEBUG = 0x00020000 +FLG_ENABLE_KDEBUG_SYMBOL_LOAD = 0x00040000 +FLG_DISABLE_PAGE_KERNEL_STACKS = 0x00080000 +FLG_HEAP_ENABLE_CALL_TRACING = 0x00100000 +FLG_HEAP_DISABLE_COALESCING = 0x00200000 +FLG_ENABLE_CLOSE_EXCEPTION = 0x00400000 +FLG_ENABLE_EXCEPTION_LOGGING = 0x00800000 +FLG_ENABLE_HANDLE_TYPE_TAGGING = 0x01000000 +FLG_HEAP_PAGE_ALLOCS = 0x02000000 +FLG_DEBUG_WINLOGON = 0x04000000 +FLG_ENABLE_DBGPRINT_BUFFERING = 0x08000000 +FLG_EARLY_CRITICAL_SECTION_EVT = 0x10000000 +FLG_DISABLE_DLL_VERIFICATION = 0x80000000 + class _PEB_NT(Structure): - _pack_ = 4 + _pack_ = 4 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("BitField", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), - ("FastPebLockRoutine", PVOID), # PPEBLOCKROUTINE - ("FastPebUnlockRoutine", PVOID), # PPEBLOCKROUTINE - ("EnvironmentUpdateCount", ULONG), - ("KernelCallbackTable", PVOID), # Ptr32 Ptr32 Void - ("EventLogSection", PVOID), - ("EventLog", PVOID), - ("FreeList", PVOID), # PPEB_FREE_BLOCK - ("TlsExpansionCounter", ULONG), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", ULONG * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("ReadOnlySharedMemoryHeap", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", ULONG), - ("NtGlobalFlag", ULONG), - ("Spare2", BYTE * 4), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", ULONG), - ("HeapSegmentCommit", ULONG), - ("HeapDeCommitTotalFreeThreshold", ULONG), - ("HeapDeCommitFreeBlockThreshold", ULONG), - ("NumberOfHeaps", ULONG), - ("MaximumNumberOfHeaps", ULONG), - ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", PVOID), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", ULONG), - ("OSMinorVersion", ULONG), - ("OSBuildNumber", ULONG), - ("OSPlatformId", ULONG), - ("ImageSubSystem", ULONG), - ("ImageSubSystemMajorVersion", ULONG), - ("ImageSubSystemMinorVersion", ULONG), - ("ImageProcessAffinityMask", ULONG), - ("GdiHandleBuffer", ULONG * 34), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", ULONG), - ("TlsExpansionBitmapBits", BYTE * 128), - ("SessionId", ULONG), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("BitField", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), + ("FastPebLockRoutine", PVOID), # PPEBLOCKROUTINE + ("FastPebUnlockRoutine", PVOID), # PPEBLOCKROUTINE + ("EnvironmentUpdateCount", ULONG), + ("KernelCallbackTable", PVOID), # Ptr32 Ptr32 Void + ("EventLogSection", PVOID), + ("EventLog", PVOID), + ("FreeList", PVOID), # PPEB_FREE_BLOCK + ("TlsExpansionCounter", ULONG), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", ULONG * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("ReadOnlySharedMemoryHeap", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", ULONG), + ("NtGlobalFlag", ULONG), + ("Spare2", BYTE * 4), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", ULONG), + ("HeapSegmentCommit", ULONG), + ("HeapDeCommitTotalFreeThreshold", ULONG), + ("HeapDeCommitFreeBlockThreshold", ULONG), + ("NumberOfHeaps", ULONG), + ("MaximumNumberOfHeaps", ULONG), + ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", PVOID), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", ULONG), + ("OSMinorVersion", ULONG), + ("OSBuildNumber", ULONG), + ("OSPlatformId", ULONG), + ("ImageSubSystem", ULONG), + ("ImageSubSystemMajorVersion", ULONG), + ("ImageSubSystemMinorVersion", ULONG), + ("ImageProcessAffinityMask", ULONG), + ("GdiHandleBuffer", ULONG * 34), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", ULONG), + ("TlsExpansionBitmapBits", BYTE * 128), + ("SessionId", ULONG), ] + # not really, but "dt _PEB" in w2k isn't working for me :( _PEB_2000 = _PEB_NT + # +0x000 InheritedAddressSpace : UChar # +0x001 ReadImageFileExecOptions : UChar # +0x002 BeingDebugged : UChar @@ -620,75 +638,76 @@ class _PEB_NT(Structure): # +0x204 SystemAssemblyStorageMap : Ptr32 Void # +0x208 MinimumStackCommit : Uint4B class _PEB_XP(Structure): - _pack_ = 8 + _pack_ = 8 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("SpareBool", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), - ("FastPebLockRoutine", PVOID), - ("FastPebUnlockRoutine", PVOID), - ("EnvironmentUpdateCount", DWORD), - ("KernelCallbackTable", PVOID), - ("SystemReserved", DWORD), - ("AtlThunkSListPtr32", DWORD), - ("FreeList", PVOID), # PPEB_FREE_BLOCK - ("TlsExpansionCounter", DWORD), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", DWORD * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("ReadOnlySharedMemoryHeap", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", DWORD), - ("NtGlobalFlag", DWORD), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", DWORD), - ("HeapSegmentCommit", DWORD), - ("HeapDeCommitTotalFreeThreshold", DWORD), - ("HeapDeCommitFreeBlockThreshold", DWORD), - ("NumberOfHeaps", DWORD), - ("MaximumNumberOfHeaps", DWORD), - ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", DWORD), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", DWORD), - ("OSMinorVersion", DWORD), - ("OSBuildNumber", WORD), - ("OSCSDVersion", WORD), - ("OSPlatformId", DWORD), - ("ImageSubsystem", DWORD), - ("ImageSubsystemMajorVersion", DWORD), - ("ImageSubsystemMinorVersion", DWORD), - ("ImageProcessAffinityMask", DWORD), - ("GdiHandleBuffer", DWORD * 34), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", PVOID), - ("TlsExpansionBitmapBits", DWORD * 32), - ("SessionId", DWORD), - ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER - ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER - ("pShimData", PVOID), - ("AppCompatInfo", PVOID), - ("CSDVersion", UNICODE_STRING), - ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("MinimumStackCommit", DWORD), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("SpareBool", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), + ("FastPebLockRoutine", PVOID), + ("FastPebUnlockRoutine", PVOID), + ("EnvironmentUpdateCount", DWORD), + ("KernelCallbackTable", PVOID), + ("SystemReserved", DWORD), + ("AtlThunkSListPtr32", DWORD), + ("FreeList", PVOID), # PPEB_FREE_BLOCK + ("TlsExpansionCounter", DWORD), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", DWORD * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("ReadOnlySharedMemoryHeap", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", DWORD), + ("NtGlobalFlag", DWORD), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", DWORD), + ("HeapSegmentCommit", DWORD), + ("HeapDeCommitTotalFreeThreshold", DWORD), + ("HeapDeCommitFreeBlockThreshold", DWORD), + ("NumberOfHeaps", DWORD), + ("MaximumNumberOfHeaps", DWORD), + ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", DWORD), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", DWORD), + ("OSMinorVersion", DWORD), + ("OSBuildNumber", WORD), + ("OSCSDVersion", WORD), + ("OSPlatformId", DWORD), + ("ImageSubsystem", DWORD), + ("ImageSubsystemMajorVersion", DWORD), + ("ImageSubsystemMinorVersion", DWORD), + ("ImageProcessAffinityMask", DWORD), + ("GdiHandleBuffer", DWORD * 34), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", PVOID), + ("TlsExpansionBitmapBits", DWORD * 32), + ("SessionId", DWORD), + ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER + ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER + ("pShimData", PVOID), + ("AppCompatInfo", PVOID), + ("CSDVersion", UNICODE_STRING), + ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("MinimumStackCommit", DWORD), ] + # +0x000 InheritedAddressSpace : UChar # +0x001 ReadImageFileExecOptions : UChar # +0x002 BeingDebugged : UChar @@ -762,80 +781,81 @@ class _PEB_XP(Structure): # +0x340 FlsBitmapBits : [4] Uint4B # +0x350 FlsHighIndex : Uint4B class _PEB_XP_64(Structure): - _pack_ = 8 + _pack_ = 8 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("BitField", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION - ("AtlThunkSListPtr", PVOID), - ("SparePtr2", PVOID), - ("EnvironmentUpdateCount", DWORD), - ("KernelCallbackTable", PVOID), - ("SystemReserved", DWORD), - ("SpareUlong", DWORD), - ("FreeList", PVOID), # PPEB_FREE_BLOCK - ("TlsExpansionCounter", DWORD), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", DWORD * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("ReadOnlySharedMemoryHeap", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr64 Ptr64 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", DWORD), - ("NtGlobalFlag", DWORD), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", QWORD), - ("HeapSegmentCommit", QWORD), - ("HeapDeCommitTotalFreeThreshold", QWORD), - ("HeapDeCommitFreeBlockThreshold", QWORD), - ("NumberOfHeaps", DWORD), - ("MaximumNumberOfHeaps", DWORD), - ("ProcessHeaps", PVOID), # Ptr64 Ptr64 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", DWORD), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", DWORD), - ("OSMinorVersion", DWORD), - ("OSBuildNumber", WORD), - ("OSCSDVersion", WORD), - ("OSPlatformId", DWORD), - ("ImageSubsystem", DWORD), - ("ImageSubsystemMajorVersion", DWORD), - ("ImageSubsystemMinorVersion", DWORD), - ("ImageProcessAffinityMask", QWORD), - ("GdiHandleBuffer", DWORD * 60), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", PVOID), - ("TlsExpansionBitmapBits", DWORD * 32), - ("SessionId", DWORD), - ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER - ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER - ("pShimData", PVOID), - ("AppCompatInfo", PVOID), - ("CSDVersion", UNICODE_STRING), - ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("MinimumStackCommit", QWORD), - ("FlsCallback", PVOID), # Ptr64 Ptr64 Void - ("FlsListHead", LIST_ENTRY), - ("FlsBitmap", PVOID), - ("FlsBitmapBits", DWORD * 4), - ("FlsHighIndex", DWORD), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("BitField", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION + ("AtlThunkSListPtr", PVOID), + ("SparePtr2", PVOID), + ("EnvironmentUpdateCount", DWORD), + ("KernelCallbackTable", PVOID), + ("SystemReserved", DWORD), + ("SpareUlong", DWORD), + ("FreeList", PVOID), # PPEB_FREE_BLOCK + ("TlsExpansionCounter", DWORD), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", DWORD * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("ReadOnlySharedMemoryHeap", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr64 Ptr64 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", DWORD), + ("NtGlobalFlag", DWORD), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", QWORD), + ("HeapSegmentCommit", QWORD), + ("HeapDeCommitTotalFreeThreshold", QWORD), + ("HeapDeCommitFreeBlockThreshold", QWORD), + ("NumberOfHeaps", DWORD), + ("MaximumNumberOfHeaps", DWORD), + ("ProcessHeaps", PVOID), # Ptr64 Ptr64 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", DWORD), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", DWORD), + ("OSMinorVersion", DWORD), + ("OSBuildNumber", WORD), + ("OSCSDVersion", WORD), + ("OSPlatformId", DWORD), + ("ImageSubsystem", DWORD), + ("ImageSubsystemMajorVersion", DWORD), + ("ImageSubsystemMinorVersion", DWORD), + ("ImageProcessAffinityMask", QWORD), + ("GdiHandleBuffer", DWORD * 60), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", PVOID), + ("TlsExpansionBitmapBits", DWORD * 32), + ("SessionId", DWORD), + ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER + ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER + ("pShimData", PVOID), + ("AppCompatInfo", PVOID), + ("CSDVersion", UNICODE_STRING), + ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("MinimumStackCommit", QWORD), + ("FlsCallback", PVOID), # Ptr64 Ptr64 Void + ("FlsListHead", LIST_ENTRY), + ("FlsBitmap", PVOID), + ("FlsBitmapBits", DWORD * 4), + ("FlsHighIndex", DWORD), ] + # +0x000 InheritedAddressSpace : UChar # +0x001 ReadImageFileExecOptions : UChar # +0x002 BeingDebugged : UChar @@ -909,84 +929,86 @@ class _PEB_XP_64(Structure): # +0x21c FlsBitmapBits : [4] Uint4B # +0x22c FlsHighIndex : Uint4B class _PEB_2003(Structure): - _pack_ = 8 + _pack_ = 8 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("BitField", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION - ("AtlThunkSListPtr", PVOID), - ("SparePtr2", PVOID), - ("EnvironmentUpdateCount", DWORD), - ("KernelCallbackTable", PVOID), - ("SystemReserved", DWORD), - ("SpareUlong", DWORD), - ("FreeList", PVOID), # PPEB_FREE_BLOCK - ("TlsExpansionCounter", DWORD), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", DWORD * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("ReadOnlySharedMemoryHeap", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", DWORD), - ("NtGlobalFlag", DWORD), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", DWORD), - ("HeapSegmentCommit", DWORD), - ("HeapDeCommitTotalFreeThreshold", DWORD), - ("HeapDeCommitFreeBlockThreshold", DWORD), - ("NumberOfHeaps", DWORD), - ("MaximumNumberOfHeaps", DWORD), - ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", DWORD), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", DWORD), - ("OSMinorVersion", DWORD), - ("OSBuildNumber", WORD), - ("OSCSDVersion", WORD), - ("OSPlatformId", DWORD), - ("ImageSubsystem", DWORD), - ("ImageSubsystemMajorVersion", DWORD), - ("ImageSubsystemMinorVersion", DWORD), - ("ImageProcessAffinityMask", DWORD), - ("GdiHandleBuffer", DWORD * 34), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", PVOID), - ("TlsExpansionBitmapBits", DWORD * 32), - ("SessionId", DWORD), - ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER - ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER - ("pShimData", PVOID), - ("AppCompatInfo", PVOID), - ("CSDVersion", UNICODE_STRING), - ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("MinimumStackCommit", QWORD), - ("FlsCallback", PVOID), # Ptr32 Ptr32 Void - ("FlsListHead", LIST_ENTRY), - ("FlsBitmap", PVOID), - ("FlsBitmapBits", DWORD * 4), - ("FlsHighIndex", DWORD), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("BitField", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION + ("AtlThunkSListPtr", PVOID), + ("SparePtr2", PVOID), + ("EnvironmentUpdateCount", DWORD), + ("KernelCallbackTable", PVOID), + ("SystemReserved", DWORD), + ("SpareUlong", DWORD), + ("FreeList", PVOID), # PPEB_FREE_BLOCK + ("TlsExpansionCounter", DWORD), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", DWORD * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("ReadOnlySharedMemoryHeap", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", DWORD), + ("NtGlobalFlag", DWORD), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", DWORD), + ("HeapSegmentCommit", DWORD), + ("HeapDeCommitTotalFreeThreshold", DWORD), + ("HeapDeCommitFreeBlockThreshold", DWORD), + ("NumberOfHeaps", DWORD), + ("MaximumNumberOfHeaps", DWORD), + ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", DWORD), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", DWORD), + ("OSMinorVersion", DWORD), + ("OSBuildNumber", WORD), + ("OSCSDVersion", WORD), + ("OSPlatformId", DWORD), + ("ImageSubsystem", DWORD), + ("ImageSubsystemMajorVersion", DWORD), + ("ImageSubsystemMinorVersion", DWORD), + ("ImageProcessAffinityMask", DWORD), + ("GdiHandleBuffer", DWORD * 34), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", PVOID), + ("TlsExpansionBitmapBits", DWORD * 32), + ("SessionId", DWORD), + ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER + ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER + ("pShimData", PVOID), + ("AppCompatInfo", PVOID), + ("CSDVersion", UNICODE_STRING), + ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("MinimumStackCommit", QWORD), + ("FlsCallback", PVOID), # Ptr32 Ptr32 Void + ("FlsListHead", LIST_ENTRY), + ("FlsBitmap", PVOID), + ("FlsBitmapBits", DWORD * 4), + ("FlsHighIndex", DWORD), ] -_PEB_2003_64 = _PEB_XP_64 -_PEB_2003_R2 = _PEB_2003 + +_PEB_2003_64 = _PEB_XP_64 +_PEB_2003_R2 = _PEB_2003 _PEB_2003_R2_64 = _PEB_2003_64 + # +0x000 InheritedAddressSpace : UChar # +0x001 ReadImageFileExecOptions : UChar # +0x002 BeingDebugged : UChar @@ -1072,87 +1094,91 @@ class _PEB_2003(Structure): # +0x230 WerRegistrationData : Ptr32 Void # +0x234 WerShipAssertPtr : Ptr32 Void class _PEB_2008(Structure): - _pack_ = 8 + _pack_ = 8 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("BitField", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION - ("AtlThunkSListPtr", PVOID), - ("IFEOKey", PVOID), - ("CrossProcessFlags", DWORD), - ("KernelCallbackTable", PVOID), - ("SystemReserved", DWORD), - ("SpareUlong", DWORD), - ("SparePebPtr0", PVOID), - ("TlsExpansionCounter", DWORD), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", DWORD * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("HotpatchInformation", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", DWORD), - ("NtGlobalFlag", DWORD), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", DWORD), - ("HeapSegmentCommit", DWORD), - ("HeapDeCommitTotalFreeThreshold", DWORD), - ("HeapDeCommitFreeBlockThreshold", DWORD), - ("NumberOfHeaps", DWORD), - ("MaximumNumberOfHeaps", DWORD), - ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", DWORD), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", DWORD), - ("OSMinorVersion", DWORD), - ("OSBuildNumber", WORD), - ("OSCSDVersion", WORD), - ("OSPlatformId", DWORD), - ("ImageSubsystem", DWORD), - ("ImageSubsystemMajorVersion", DWORD), - ("ImageSubsystemMinorVersion", DWORD), - ("ActiveProcessAffinityMask", DWORD), - ("GdiHandleBuffer", DWORD * 34), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", PVOID), - ("TlsExpansionBitmapBits", DWORD * 32), - ("SessionId", DWORD), - ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER - ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER - ("pShimData", PVOID), - ("AppCompatInfo", PVOID), - ("CSDVersion", UNICODE_STRING), - ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("MinimumStackCommit", DWORD), - ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO - ("FlsListHead", LIST_ENTRY), - ("FlsBitmap", PVOID), - ("FlsBitmapBits", DWORD * 4), - ("FlsHighIndex", DWORD), - ("WerRegistrationData", PVOID), - ("WerShipAssertPtr", PVOID), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("BitField", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION + ("AtlThunkSListPtr", PVOID), + ("IFEOKey", PVOID), + ("CrossProcessFlags", DWORD), + ("KernelCallbackTable", PVOID), + ("SystemReserved", DWORD), + ("SpareUlong", DWORD), + ("SparePebPtr0", PVOID), + ("TlsExpansionCounter", DWORD), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", DWORD * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("HotpatchInformation", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", DWORD), + ("NtGlobalFlag", DWORD), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", DWORD), + ("HeapSegmentCommit", DWORD), + ("HeapDeCommitTotalFreeThreshold", DWORD), + ("HeapDeCommitFreeBlockThreshold", DWORD), + ("NumberOfHeaps", DWORD), + ("MaximumNumberOfHeaps", DWORD), + ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", DWORD), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", DWORD), + ("OSMinorVersion", DWORD), + ("OSBuildNumber", WORD), + ("OSCSDVersion", WORD), + ("OSPlatformId", DWORD), + ("ImageSubsystem", DWORD), + ("ImageSubsystemMajorVersion", DWORD), + ("ImageSubsystemMinorVersion", DWORD), + ("ActiveProcessAffinityMask", DWORD), + ("GdiHandleBuffer", DWORD * 34), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", PVOID), + ("TlsExpansionBitmapBits", DWORD * 32), + ("SessionId", DWORD), + ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER + ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER + ("pShimData", PVOID), + ("AppCompatInfo", PVOID), + ("CSDVersion", UNICODE_STRING), + ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("MinimumStackCommit", DWORD), + ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO + ("FlsListHead", LIST_ENTRY), + ("FlsBitmap", PVOID), + ("FlsBitmapBits", DWORD * 4), + ("FlsHighIndex", DWORD), + ("WerRegistrationData", PVOID), + ("WerShipAssertPtr", PVOID), ] + def __get_UserSharedInfoPtr(self): return self.KernelCallbackTable + def __set_UserSharedInfoPtr(self, value): self.KernelCallbackTable = value + UserSharedInfoPtr = property(__get_UserSharedInfoPtr, __set_UserSharedInfoPtr) + # +0x000 InheritedAddressSpace : UChar # +0x001 ReadImageFileExecOptions : UChar # +0x002 BeingDebugged : UChar @@ -1238,87 +1264,91 @@ def __set_UserSharedInfoPtr(self, value): # +0x358 WerRegistrationData : Ptr64 Void # +0x360 WerShipAssertPtr : Ptr64 Void class _PEB_2008_64(Structure): - _pack_ = 8 + _pack_ = 8 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("BitField", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION - ("AtlThunkSListPtr", PVOID), - ("IFEOKey", PVOID), - ("CrossProcessFlags", DWORD), - ("KernelCallbackTable", PVOID), - ("SystemReserved", DWORD), - ("SpareUlong", DWORD), - ("SparePebPtr0", PVOID), - ("TlsExpansionCounter", DWORD), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", DWORD * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("HotpatchInformation", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr64 Ptr64 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", DWORD), - ("NtGlobalFlag", DWORD), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", QWORD), - ("HeapSegmentCommit", QWORD), - ("HeapDeCommitTotalFreeThreshold", QWORD), - ("HeapDeCommitFreeBlockThreshold", QWORD), - ("NumberOfHeaps", DWORD), - ("MaximumNumberOfHeaps", DWORD), - ("ProcessHeaps", PVOID), # Ptr64 Ptr64 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", DWORD), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", DWORD), - ("OSMinorVersion", DWORD), - ("OSBuildNumber", WORD), - ("OSCSDVersion", WORD), - ("OSPlatformId", DWORD), - ("ImageSubsystem", DWORD), - ("ImageSubsystemMajorVersion", DWORD), - ("ImageSubsystemMinorVersion", DWORD), - ("ActiveProcessAffinityMask", QWORD), - ("GdiHandleBuffer", DWORD * 60), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", PVOID), - ("TlsExpansionBitmapBits", DWORD * 32), - ("SessionId", DWORD), - ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER - ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER - ("pShimData", PVOID), - ("AppCompatInfo", PVOID), - ("CSDVersion", UNICODE_STRING), - ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("MinimumStackCommit", QWORD), - ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO - ("FlsListHead", LIST_ENTRY), - ("FlsBitmap", PVOID), - ("FlsBitmapBits", DWORD * 4), - ("FlsHighIndex", DWORD), - ("WerRegistrationData", PVOID), - ("WerShipAssertPtr", PVOID), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("BitField", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION + ("AtlThunkSListPtr", PVOID), + ("IFEOKey", PVOID), + ("CrossProcessFlags", DWORD), + ("KernelCallbackTable", PVOID), + ("SystemReserved", DWORD), + ("SpareUlong", DWORD), + ("SparePebPtr0", PVOID), + ("TlsExpansionCounter", DWORD), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", DWORD * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("HotpatchInformation", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr64 Ptr64 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", DWORD), + ("NtGlobalFlag", DWORD), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", QWORD), + ("HeapSegmentCommit", QWORD), + ("HeapDeCommitTotalFreeThreshold", QWORD), + ("HeapDeCommitFreeBlockThreshold", QWORD), + ("NumberOfHeaps", DWORD), + ("MaximumNumberOfHeaps", DWORD), + ("ProcessHeaps", PVOID), # Ptr64 Ptr64 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", DWORD), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", DWORD), + ("OSMinorVersion", DWORD), + ("OSBuildNumber", WORD), + ("OSCSDVersion", WORD), + ("OSPlatformId", DWORD), + ("ImageSubsystem", DWORD), + ("ImageSubsystemMajorVersion", DWORD), + ("ImageSubsystemMinorVersion", DWORD), + ("ActiveProcessAffinityMask", QWORD), + ("GdiHandleBuffer", DWORD * 60), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", PVOID), + ("TlsExpansionBitmapBits", DWORD * 32), + ("SessionId", DWORD), + ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER + ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER + ("pShimData", PVOID), + ("AppCompatInfo", PVOID), + ("CSDVersion", UNICODE_STRING), + ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("MinimumStackCommit", QWORD), + ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO + ("FlsListHead", LIST_ENTRY), + ("FlsBitmap", PVOID), + ("FlsBitmapBits", DWORD * 4), + ("FlsHighIndex", DWORD), + ("WerRegistrationData", PVOID), + ("WerShipAssertPtr", PVOID), ] + def __get_UserSharedInfoPtr(self): return self.KernelCallbackTable + def __set_UserSharedInfoPtr(self, value): self.KernelCallbackTable = value + UserSharedInfoPtr = property(__get_UserSharedInfoPtr, __set_UserSharedInfoPtr) + # +0x000 InheritedAddressSpace : UChar # +0x001 ReadImageFileExecOptions : UChar # +0x002 BeingDebugged : UChar @@ -1411,90 +1441,94 @@ def __set_UserSharedInfoPtr(self, value): # +0x240 CritSecTracingEnabled : Pos 1, 1 Bit # +0x240 SpareTracingBits : Pos 2, 30 Bits class _PEB_2008_R2(Structure): - _pack_ = 8 + _pack_ = 8 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("BitField", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION - ("AtlThunkSListPtr", PVOID), - ("IFEOKey", PVOID), - ("CrossProcessFlags", DWORD), - ("KernelCallbackTable", PVOID), - ("SystemReserved", DWORD), - ("AtlThunkSListPtr32", PVOID), - ("ApiSetMap", PVOID), - ("TlsExpansionCounter", DWORD), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", DWORD * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("HotpatchInformation", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", DWORD), - ("NtGlobalFlag", DWORD), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", DWORD), - ("HeapSegmentCommit", DWORD), - ("HeapDeCommitTotalFreeThreshold", DWORD), - ("HeapDeCommitFreeBlockThreshold", DWORD), - ("NumberOfHeaps", DWORD), - ("MaximumNumberOfHeaps", DWORD), - ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", DWORD), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", DWORD), - ("OSMinorVersion", DWORD), - ("OSBuildNumber", WORD), - ("OSCSDVersion", WORD), - ("OSPlatformId", DWORD), - ("ImageSubsystem", DWORD), - ("ImageSubsystemMajorVersion", DWORD), - ("ImageSubsystemMinorVersion", DWORD), - ("ActiveProcessAffinityMask", DWORD), - ("GdiHandleBuffer", DWORD * 34), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", PVOID), - ("TlsExpansionBitmapBits", DWORD * 32), - ("SessionId", DWORD), - ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER - ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER - ("pShimData", PVOID), - ("AppCompatInfo", PVOID), - ("CSDVersion", UNICODE_STRING), - ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("MinimumStackCommit", DWORD), - ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO - ("FlsListHead", LIST_ENTRY), - ("FlsBitmap", PVOID), - ("FlsBitmapBits", DWORD * 4), - ("FlsHighIndex", DWORD), - ("WerRegistrationData", PVOID), - ("WerShipAssertPtr", PVOID), - ("pContextData", PVOID), - ("pImageHeaderHash", PVOID), - ("TracingFlags", DWORD), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("BitField", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION + ("AtlThunkSListPtr", PVOID), + ("IFEOKey", PVOID), + ("CrossProcessFlags", DWORD), + ("KernelCallbackTable", PVOID), + ("SystemReserved", DWORD), + ("AtlThunkSListPtr32", PVOID), + ("ApiSetMap", PVOID), + ("TlsExpansionCounter", DWORD), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", DWORD * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("HotpatchInformation", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", DWORD), + ("NtGlobalFlag", DWORD), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", DWORD), + ("HeapSegmentCommit", DWORD), + ("HeapDeCommitTotalFreeThreshold", DWORD), + ("HeapDeCommitFreeBlockThreshold", DWORD), + ("NumberOfHeaps", DWORD), + ("MaximumNumberOfHeaps", DWORD), + ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", DWORD), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", DWORD), + ("OSMinorVersion", DWORD), + ("OSBuildNumber", WORD), + ("OSCSDVersion", WORD), + ("OSPlatformId", DWORD), + ("ImageSubsystem", DWORD), + ("ImageSubsystemMajorVersion", DWORD), + ("ImageSubsystemMinorVersion", DWORD), + ("ActiveProcessAffinityMask", DWORD), + ("GdiHandleBuffer", DWORD * 34), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", PVOID), + ("TlsExpansionBitmapBits", DWORD * 32), + ("SessionId", DWORD), + ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER + ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER + ("pShimData", PVOID), + ("AppCompatInfo", PVOID), + ("CSDVersion", UNICODE_STRING), + ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("MinimumStackCommit", DWORD), + ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO + ("FlsListHead", LIST_ENTRY), + ("FlsBitmap", PVOID), + ("FlsBitmapBits", DWORD * 4), + ("FlsHighIndex", DWORD), + ("WerRegistrationData", PVOID), + ("WerShipAssertPtr", PVOID), + ("pContextData", PVOID), + ("pImageHeaderHash", PVOID), + ("TracingFlags", DWORD), ] + def __get_UserSharedInfoPtr(self): return self.KernelCallbackTable + def __set_UserSharedInfoPtr(self, value): self.KernelCallbackTable = value + UserSharedInfoPtr = property(__get_UserSharedInfoPtr, __set_UserSharedInfoPtr) + # +0x000 InheritedAddressSpace : UChar # +0x001 ReadImageFileExecOptions : UChar # +0x002 BeingDebugged : UChar @@ -1587,94 +1621,99 @@ def __set_UserSharedInfoPtr(self, value): # +0x378 CritSecTracingEnabled : Pos 1, 1 Bit # +0x378 SpareTracingBits : Pos 2, 30 Bits class _PEB_2008_R2_64(Structure): - _pack_ = 8 + _pack_ = 8 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("BitField", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION - ("AtlThunkSListPtr", PVOID), - ("IFEOKey", PVOID), - ("CrossProcessFlags", DWORD), - ("KernelCallbackTable", PVOID), - ("SystemReserved", DWORD), - ("AtlThunkSListPtr32", DWORD), - ("ApiSetMap", PVOID), - ("TlsExpansionCounter", DWORD), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", DWORD * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("HotpatchInformation", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", DWORD), - ("NtGlobalFlag", DWORD), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", QWORD), - ("HeapSegmentCommit", QWORD), - ("HeapDeCommitTotalFreeThreshold", QWORD), - ("HeapDeCommitFreeBlockThreshold", QWORD), - ("NumberOfHeaps", DWORD), - ("MaximumNumberOfHeaps", DWORD), - ("ProcessHeaps", PVOID), # Ptr64 Ptr64 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", DWORD), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", DWORD), - ("OSMinorVersion", DWORD), - ("OSBuildNumber", WORD), - ("OSCSDVersion", WORD), - ("OSPlatformId", DWORD), - ("ImageSubsystem", DWORD), - ("ImageSubsystemMajorVersion", DWORD), - ("ImageSubsystemMinorVersion", DWORD), - ("ActiveProcessAffinityMask", QWORD), - ("GdiHandleBuffer", DWORD * 60), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", PVOID), - ("TlsExpansionBitmapBits", DWORD * 32), - ("SessionId", DWORD), - ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER - ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER - ("pShimData", PVOID), - ("AppCompatInfo", PVOID), - ("CSDVersion", UNICODE_STRING), - ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("MinimumStackCommit", QWORD), - ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO - ("FlsListHead", LIST_ENTRY), - ("FlsBitmap", PVOID), - ("FlsBitmapBits", DWORD * 4), - ("FlsHighIndex", DWORD), - ("WerRegistrationData", PVOID), - ("WerShipAssertPtr", PVOID), - ("pContextData", PVOID), - ("pImageHeaderHash", PVOID), - ("TracingFlags", DWORD), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("BitField", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION + ("AtlThunkSListPtr", PVOID), + ("IFEOKey", PVOID), + ("CrossProcessFlags", DWORD), + ("KernelCallbackTable", PVOID), + ("SystemReserved", DWORD), + ("AtlThunkSListPtr32", DWORD), + ("ApiSetMap", PVOID), + ("TlsExpansionCounter", DWORD), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", DWORD * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("HotpatchInformation", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", DWORD), + ("NtGlobalFlag", DWORD), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", QWORD), + ("HeapSegmentCommit", QWORD), + ("HeapDeCommitTotalFreeThreshold", QWORD), + ("HeapDeCommitFreeBlockThreshold", QWORD), + ("NumberOfHeaps", DWORD), + ("MaximumNumberOfHeaps", DWORD), + ("ProcessHeaps", PVOID), # Ptr64 Ptr64 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", DWORD), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", DWORD), + ("OSMinorVersion", DWORD), + ("OSBuildNumber", WORD), + ("OSCSDVersion", WORD), + ("OSPlatformId", DWORD), + ("ImageSubsystem", DWORD), + ("ImageSubsystemMajorVersion", DWORD), + ("ImageSubsystemMinorVersion", DWORD), + ("ActiveProcessAffinityMask", QWORD), + ("GdiHandleBuffer", DWORD * 60), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", PVOID), + ("TlsExpansionBitmapBits", DWORD * 32), + ("SessionId", DWORD), + ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER + ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER + ("pShimData", PVOID), + ("AppCompatInfo", PVOID), + ("CSDVersion", UNICODE_STRING), + ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("MinimumStackCommit", QWORD), + ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO + ("FlsListHead", LIST_ENTRY), + ("FlsBitmap", PVOID), + ("FlsBitmapBits", DWORD * 4), + ("FlsHighIndex", DWORD), + ("WerRegistrationData", PVOID), + ("WerShipAssertPtr", PVOID), + ("pContextData", PVOID), + ("pImageHeaderHash", PVOID), + ("TracingFlags", DWORD), ] + def __get_UserSharedInfoPtr(self): return self.KernelCallbackTable + def __set_UserSharedInfoPtr(self, value): self.KernelCallbackTable = value + UserSharedInfoPtr = property(__get_UserSharedInfoPtr, __set_UserSharedInfoPtr) -_PEB_Vista = _PEB_2008 -_PEB_Vista_64 = _PEB_2008_64 -_PEB_W7 = _PEB_2008_R2 -_PEB_W7_64 = _PEB_2008_R2_64 + +_PEB_Vista = _PEB_2008 +_PEB_Vista_64 = _PEB_2008_64 +_PEB_W7 = _PEB_2008_R2 +_PEB_W7_64 = _PEB_2008_R2_64 + # +0x000 InheritedAddressSpace : UChar # +0x001 ReadImageFileExecOptions : UChar @@ -1772,157 +1811,166 @@ class _PEB_W7_Beta(Structure): of Windows 7. For the final version of Windows 7 use L{_PEB_W7} instead. This structure is not chosen automatically. """ - _pack_ = 8 + + _pack_ = 8 _fields_ = [ - ("InheritedAddressSpace", BOOLEAN), - ("ReadImageFileExecOptions", UCHAR), - ("BeingDebugged", BOOLEAN), - ("BitField", UCHAR), - ("Mutant", HANDLE), - ("ImageBaseAddress", PVOID), - ("Ldr", PVOID), # PPEB_LDR_DATA - ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS - ("SubSystemData", PVOID), - ("ProcessHeap", PVOID), - ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION - ("AtlThunkSListPtr", PVOID), - ("IFEOKey", PVOID), - ("CrossProcessFlags", DWORD), - ("KernelCallbackTable", PVOID), - ("SystemReserved", DWORD), - ("TracingFlags", DWORD), - ("ApiSetMap", PVOID), - ("TlsExpansionCounter", DWORD), - ("TlsBitmap", PVOID), - ("TlsBitmapBits", DWORD * 2), - ("ReadOnlySharedMemoryBase", PVOID), - ("HotpatchInformation", PVOID), - ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void - ("AnsiCodePageData", PVOID), - ("OemCodePageData", PVOID), - ("UnicodeCaseTableData", PVOID), - ("NumberOfProcessors", DWORD), - ("NtGlobalFlag", DWORD), - ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER - ("HeapSegmentReserve", DWORD), - ("HeapSegmentCommit", DWORD), - ("HeapDeCommitTotalFreeThreshold", DWORD), - ("HeapDeCommitFreeBlockThreshold", DWORD), - ("NumberOfHeaps", DWORD), - ("MaximumNumberOfHeaps", DWORD), - ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void - ("GdiSharedHandleTable", PVOID), - ("ProcessStarterHelper", PVOID), - ("GdiDCAttributeList", DWORD), - ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION - ("OSMajorVersion", DWORD), - ("OSMinorVersion", DWORD), - ("OSBuildNumber", WORD), - ("OSCSDVersion", WORD), - ("OSPlatformId", DWORD), - ("ImageSubsystem", DWORD), - ("ImageSubsystemMajorVersion", DWORD), - ("ImageSubsystemMinorVersion", DWORD), - ("ActiveProcessAffinityMask", DWORD), - ("GdiHandleBuffer", DWORD * 34), - ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), - ("TlsExpansionBitmap", PVOID), - ("TlsExpansionBitmapBits", DWORD * 32), - ("SessionId", DWORD), - ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER - ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER - ("pShimData", PVOID), - ("AppCompatInfo", PVOID), - ("CSDVersion", UNICODE_STRING), - ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA - ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP - ("MinimumStackCommit", DWORD), - ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO - ("FlsListHead", LIST_ENTRY), - ("FlsBitmap", PVOID), - ("FlsBitmapBits", DWORD * 4), - ("FlsHighIndex", DWORD), - ("WerRegistrationData", PVOID), - ("WerShipAssertPtr", PVOID), - ("pContextData", PVOID), - ("pImageHeaderHash", PVOID), + ("InheritedAddressSpace", BOOLEAN), + ("ReadImageFileExecOptions", UCHAR), + ("BeingDebugged", BOOLEAN), + ("BitField", UCHAR), + ("Mutant", HANDLE), + ("ImageBaseAddress", PVOID), + ("Ldr", PVOID), # PPEB_LDR_DATA + ("ProcessParameters", PVOID), # PRTL_USER_PROCESS_PARAMETERS + ("SubSystemData", PVOID), + ("ProcessHeap", PVOID), + ("FastPebLock", PVOID), # PRTL_CRITICAL_SECTION + ("AtlThunkSListPtr", PVOID), + ("IFEOKey", PVOID), + ("CrossProcessFlags", DWORD), + ("KernelCallbackTable", PVOID), + ("SystemReserved", DWORD), + ("TracingFlags", DWORD), + ("ApiSetMap", PVOID), + ("TlsExpansionCounter", DWORD), + ("TlsBitmap", PVOID), + ("TlsBitmapBits", DWORD * 2), + ("ReadOnlySharedMemoryBase", PVOID), + ("HotpatchInformation", PVOID), + ("ReadOnlyStaticServerData", PVOID), # Ptr32 Ptr32 Void + ("AnsiCodePageData", PVOID), + ("OemCodePageData", PVOID), + ("UnicodeCaseTableData", PVOID), + ("NumberOfProcessors", DWORD), + ("NtGlobalFlag", DWORD), + ("CriticalSectionTimeout", LONGLONG), # LARGE_INTEGER + ("HeapSegmentReserve", DWORD), + ("HeapSegmentCommit", DWORD), + ("HeapDeCommitTotalFreeThreshold", DWORD), + ("HeapDeCommitFreeBlockThreshold", DWORD), + ("NumberOfHeaps", DWORD), + ("MaximumNumberOfHeaps", DWORD), + ("ProcessHeaps", PVOID), # Ptr32 Ptr32 Void + ("GdiSharedHandleTable", PVOID), + ("ProcessStarterHelper", PVOID), + ("GdiDCAttributeList", DWORD), + ("LoaderLock", PVOID), # PRTL_CRITICAL_SECTION + ("OSMajorVersion", DWORD), + ("OSMinorVersion", DWORD), + ("OSBuildNumber", WORD), + ("OSCSDVersion", WORD), + ("OSPlatformId", DWORD), + ("ImageSubsystem", DWORD), + ("ImageSubsystemMajorVersion", DWORD), + ("ImageSubsystemMinorVersion", DWORD), + ("ActiveProcessAffinityMask", DWORD), + ("GdiHandleBuffer", DWORD * 34), + ("PostProcessInitRoutine", PPS_POST_PROCESS_INIT_ROUTINE), + ("TlsExpansionBitmap", PVOID), + ("TlsExpansionBitmapBits", DWORD * 32), + ("SessionId", DWORD), + ("AppCompatFlags", ULONGLONG), # ULARGE_INTEGER + ("AppCompatFlagsUser", ULONGLONG), # ULARGE_INTEGER + ("pShimData", PVOID), + ("AppCompatInfo", PVOID), + ("CSDVersion", UNICODE_STRING), + ("ActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("ProcessAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("SystemDefaultActivationContextData", PVOID), # ACTIVATION_CONTEXT_DATA + ("SystemAssemblyStorageMap", PVOID), # ASSEMBLY_STORAGE_MAP + ("MinimumStackCommit", DWORD), + ("FlsCallback", PVOID), # PFLS_CALLBACK_INFO + ("FlsListHead", LIST_ENTRY), + ("FlsBitmap", PVOID), + ("FlsBitmapBits", DWORD * 4), + ("FlsHighIndex", DWORD), + ("WerRegistrationData", PVOID), + ("WerShipAssertPtr", PVOID), + ("pContextData", PVOID), + ("pImageHeaderHash", PVOID), ] + def __get_UserSharedInfoPtr(self): return self.KernelCallbackTable + def __set_UserSharedInfoPtr(self, value): self.KernelCallbackTable = value + UserSharedInfoPtr = property(__get_UserSharedInfoPtr, __set_UserSharedInfoPtr) + # Use the correct PEB structure definition. # Defaults to the latest Windows version. class PEB(Structure): _pack_ = 8 - if os == 'Windows NT': - _pack_ = _PEB_NT._pack_ + if os == "Windows NT": + _pack_ = _PEB_NT._pack_ _fields_ = _PEB_NT._fields_ - elif os == 'Windows 2000': - _pack_ = _PEB_2000._pack_ + elif os == "Windows 2000": + _pack_ = _PEB_2000._pack_ _fields_ = _PEB_2000._fields_ - elif os == 'Windows XP': + elif os == "Windows XP": _fields_ = _PEB_XP._fields_ - elif os == 'Windows XP (64 bits)': + elif os == "Windows XP (64 bits)": _fields_ = _PEB_XP_64._fields_ - elif os == 'Windows 2003': + elif os == "Windows 2003": _fields_ = _PEB_2003._fields_ - elif os == 'Windows 2003 (64 bits)': + elif os == "Windows 2003 (64 bits)": _fields_ = _PEB_2003_64._fields_ - elif os == 'Windows 2003 R2': + elif os == "Windows 2003 R2": _fields_ = _PEB_2003_R2._fields_ - elif os == 'Windows 2003 R2 (64 bits)': + elif os == "Windows 2003 R2 (64 bits)": _fields_ = _PEB_2003_R2_64._fields_ - elif os == 'Windows 2008': + elif os == "Windows 2008": _fields_ = _PEB_2008._fields_ - elif os == 'Windows 2008 (64 bits)': + elif os == "Windows 2008 (64 bits)": _fields_ = _PEB_2008_64._fields_ - elif os == 'Windows 2008 R2': + elif os == "Windows 2008 R2": _fields_ = _PEB_2008_R2._fields_ - elif os == 'Windows 2008 R2 (64 bits)': + elif os == "Windows 2008 R2 (64 bits)": _fields_ = _PEB_2008_R2_64._fields_ - elif os == 'Windows Vista': + elif os == "Windows Vista": _fields_ = _PEB_Vista._fields_ - elif os == 'Windows Vista (64 bits)': + elif os == "Windows Vista (64 bits)": _fields_ = _PEB_Vista_64._fields_ - elif os == 'Windows 7': + elif os == "Windows 7": _fields_ = _PEB_W7._fields_ - elif os == 'Windows 7 (64 bits)': + elif os == "Windows 7 (64 bits)": _fields_ = _PEB_W7_64._fields_ elif sizeof(SIZE_T) == sizeof(DWORD): _fields_ = _PEB_W7._fields_ else: _fields_ = _PEB_W7_64._fields_ + + PPEB = POINTER(PEB) + # PEB structure for WOW64 processes. class PEB_32(Structure): _pack_ = 8 - if os == 'Windows NT': - _pack_ = _PEB_NT._pack_ + if os == "Windows NT": + _pack_ = _PEB_NT._pack_ _fields_ = _PEB_NT._fields_ - elif os == 'Windows 2000': - _pack_ = _PEB_2000._pack_ + elif os == "Windows 2000": + _pack_ = _PEB_2000._pack_ _fields_ = _PEB_2000._fields_ - elif os.startswith('Windows XP'): + elif os.startswith("Windows XP"): _fields_ = _PEB_XP._fields_ - elif os.startswith('Windows 2003 R2'): + elif os.startswith("Windows 2003 R2"): _fields_ = _PEB_2003_R2._fields_ - elif os.startswith('Windows 2003'): + elif os.startswith("Windows 2003"): _fields_ = _PEB_2003._fields_ - elif os.startswith('Windows 2008 R2'): + elif os.startswith("Windows 2008 R2"): _fields_ = _PEB_2008_R2._fields_ - elif os.startswith('Windows 2008'): + elif os.startswith("Windows 2008"): _fields_ = _PEB_2008._fields_ - elif os.startswith('Windows Vista'): + elif os.startswith("Windows Vista"): _fields_ = _PEB_Vista._fields_ - else: #if os.startswith('Windows 7'): + else: # if os.startswith('Windows 7'): _fields_ = _PEB_W7._fields_ + # from https://vmexplorer.svn.codeplex.com/svn/VMExplorer/src/Win32/Threads.cs # # [StructLayout (LayoutKind.Sequential, Size = 0x0C)] @@ -1935,11 +1983,12 @@ class PEB_32(Structure): # }; class Wx86ThreadState(Structure): _fields_ = [ - ("CallBx86Eip", PVOID), - ("DeallocationCpu", PVOID), - ("UseKnownWx86Dll", UCHAR), - ("OleStubInvoked", CHAR), -] + ("CallBx86Eip", PVOID), + ("DeallocationCpu", PVOID), + ("UseKnownWx86Dll", UCHAR), + ("OleStubInvoked", CHAR), + ] + # ntdll!_RTL_ACTIVATION_CONTEXT_STACK_FRAME # +0x000 Previous : Ptr64 _RTL_ACTIVATION_CONTEXT_STACK_FRAME @@ -1947,10 +1996,11 @@ class Wx86ThreadState(Structure): # +0x010 Flags : Uint4B class RTL_ACTIVATION_CONTEXT_STACK_FRAME(Structure): _fields_ = [ - ("Previous", PVOID), - ("ActivationContext", PVOID), - ("Flags", DWORD), -] + ("Previous", PVOID), + ("ActivationContext", PVOID), + ("Flags", DWORD), + ] + # ntdll!_ACTIVATION_CONTEXT_STACK # +0x000 ActiveFrame : Ptr64 _RTL_ACTIVATION_CONTEXT_STACK_FRAME @@ -1960,12 +2010,13 @@ class RTL_ACTIVATION_CONTEXT_STACK_FRAME(Structure): # +0x020 StackId : Uint4B class ACTIVATION_CONTEXT_STACK(Structure): _fields_ = [ - ("ActiveFrame", PVOID), - ("FrameListCache", LIST_ENTRY), - ("Flags", DWORD), - ("NextCookieSequenceNumber", DWORD), - ("StackId", DWORD), -] + ("ActiveFrame", PVOID), + ("FrameListCache", LIST_ENTRY), + ("Flags", DWORD), + ("NextCookieSequenceNumber", DWORD), + ("StackId", DWORD), + ] + # typedef struct _PROCESSOR_NUMBER { # WORD Group; @@ -1974,10 +2025,11 @@ class ACTIVATION_CONTEXT_STACK(Structure): # }PROCESSOR_NUMBER, *PPROCESSOR_NUMBER; class PROCESSOR_NUMBER(Structure): _fields_ = [ - ("Group", WORD), - ("Number", BYTE), - ("Reserved", BYTE), -] + ("Group", WORD), + ("Number", BYTE), + ("Reserved", BYTE), + ] + # from http://www.nirsoft.net/kernel_struct/vista/NT_TIB.html # @@ -1997,34 +2049,42 @@ class PROCESSOR_NUMBER(Structure): # } NT_TIB, *PNT_TIB; class _NT_TIB_UNION(Union): _fields_ = [ - ("FiberData", PVOID), - ("Version", ULONG), + ("FiberData", PVOID), + ("Version", ULONG), ] + + class NT_TIB(Structure): _fields_ = [ - ("ExceptionList", PVOID), # PEXCEPTION_REGISTRATION_RECORD - ("StackBase", PVOID), - ("StackLimit", PVOID), - ("SubSystemTib", PVOID), - ("u", _NT_TIB_UNION), - ("ArbitraryUserPointer", PVOID), - ("Self", PVOID), # PNTTIB + ("ExceptionList", PVOID), # PEXCEPTION_REGISTRATION_RECORD + ("StackBase", PVOID), + ("StackLimit", PVOID), + ("SubSystemTib", PVOID), + ("u", _NT_TIB_UNION), + ("ArbitraryUserPointer", PVOID), + ("Self", PVOID), # PNTTIB ] def __get_FiberData(self): return self.u.FiberData + def __set_FiberData(self, value): self.u.FiberData = value + FiberData = property(__get_FiberData, __set_FiberData) def __get_Version(self): return self.u.Version + def __set_Version(self, value): self.u.Version = value + Version = property(__get_Version, __set_Version) + PNTTIB = POINTER(NT_TIB) + # From http://www.nirsoft.net/kernel_struct/vista/EXCEPTION_REGISTRATION_RECORD.html # # typedef struct _EXCEPTION_REGISTRATION_RECORD @@ -2035,20 +2095,22 @@ def __set_Version(self, value): class EXCEPTION_REGISTRATION_RECORD(Structure): pass -EXCEPTION_DISPOSITION = DWORD + +EXCEPTION_DISPOSITION = DWORD ##PEXCEPTION_DISPOSITION = POINTER(EXCEPTION_DISPOSITION) ##PEXCEPTION_REGISTRATION_RECORD = POINTER(EXCEPTION_REGISTRATION_RECORD) -PEXCEPTION_DISPOSITION = PVOID -PEXCEPTION_REGISTRATION_RECORD = PVOID +PEXCEPTION_DISPOSITION = PVOID +PEXCEPTION_REGISTRATION_RECORD = PVOID EXCEPTION_REGISTRATION_RECORD._fields_ = [ - ("Next", PEXCEPTION_REGISTRATION_RECORD), - ("Handler", PEXCEPTION_DISPOSITION), + ("Next", PEXCEPTION_REGISTRATION_RECORD), + ("Handler", PEXCEPTION_DISPOSITION), ] ##PPEB = POINTER(PEB) PPEB = PVOID + # From http://www.nirsoft.net/kernel_struct/vista/GDI_TEB_BATCH.html # # typedef struct _GDI_TEB_BATCH @@ -2059,119 +2121,128 @@ class EXCEPTION_REGISTRATION_RECORD(Structure): # } GDI_TEB_BATCH, *PGDI_TEB_BATCH; class GDI_TEB_BATCH(Structure): _fields_ = [ - ("Offset", ULONG), - ("HDC", ULONG), - ("Buffer", ULONG * 310), -] + ("Offset", ULONG), + ("HDC", ULONG), + ("Buffer", ULONG * 310), + ] + # ntdll!_TEB_ACTIVE_FRAME_CONTEXT # +0x000 Flags : Uint4B # +0x008 FrameName : Ptr64 Char class TEB_ACTIVE_FRAME_CONTEXT(Structure): _fields_ = [ - ("Flags", DWORD), - ("FrameName", LPVOID), # LPCHAR -] + ("Flags", DWORD), + ("FrameName", LPVOID), # LPCHAR + ] + + PTEB_ACTIVE_FRAME_CONTEXT = POINTER(TEB_ACTIVE_FRAME_CONTEXT) + # ntdll!_TEB_ACTIVE_FRAME # +0x000 Flags : Uint4B # +0x008 Previous : Ptr64 _TEB_ACTIVE_FRAME # +0x010 Context : Ptr64 _TEB_ACTIVE_FRAME_CONTEXT class TEB_ACTIVE_FRAME(Structure): _fields_ = [ - ("Flags", DWORD), - ("Previous", LPVOID), # PTEB_ACTIVE_FRAME - ("Context", LPVOID), # PTEB_ACTIVE_FRAME_CONTEXT -] + ("Flags", DWORD), + ("Previous", LPVOID), # PTEB_ACTIVE_FRAME + ("Context", LPVOID), # PTEB_ACTIVE_FRAME_CONTEXT + ] + + PTEB_ACTIVE_FRAME = POINTER(TEB_ACTIVE_FRAME) # SameTebFlags -DbgSafeThunkCall = 1 << 0 -DbgInDebugPrint = 1 << 1 -DbgHasFiberData = 1 << 2 -DbgSkipThreadAttach = 1 << 3 -DbgWerInShipAssertCode = 1 << 4 -DbgRanProcessInit = 1 << 5 -DbgClonedThread = 1 << 6 -DbgSuppressDebugMsg = 1 << 7 +DbgSafeThunkCall = 1 << 0 +DbgInDebugPrint = 1 << 1 +DbgHasFiberData = 1 << 2 +DbgSkipThreadAttach = 1 << 3 +DbgWerInShipAssertCode = 1 << 4 +DbgRanProcessInit = 1 << 5 +DbgClonedThread = 1 << 6 +DbgSuppressDebugMsg = 1 << 7 RtlDisableUserStackWalk = 1 << 8 -RtlExceptionAttached = 1 << 9 -RtlInitialThread = 1 << 10 +RtlExceptionAttached = 1 << 9 +RtlInitialThread = 1 << 10 + # XXX This is quite wrong :P class _TEB_NT(Structure): _pack_ = 4 _fields_ = [ - ("NtTib", NT_TIB), - ("EnvironmentPointer", PVOID), - ("ClientId", CLIENT_ID), - ("ActiveRpcHandle", HANDLE), - ("ThreadLocalStoragePointer", PVOID), - ("ProcessEnvironmentBlock", PPEB), - ("LastErrorValue", ULONG), - ("CountOfOwnedCriticalSections", ULONG), - ("CsrClientThread", PVOID), - ("Win32ThreadInfo", PVOID), - ("User32Reserved", ULONG * 26), - ("UserReserved", ULONG * 5), - ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode - ("CurrentLocale", ULONG), - ("FpSoftwareStatusRegister", ULONG), - ("SystemReserved1", PVOID * 54), - ("Spare1", PVOID), - ("ExceptionCode", ULONG), - ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK - ("SpareBytes1", ULONG * 36), - ("TxFsContext", ULONG), - ("GdiTebBatch", GDI_TEB_BATCH), - ("RealClientId", CLIENT_ID), - ("GdiCachedProcessHandle", PVOID), - ("GdiClientPID", ULONG), - ("GdiClientTID", ULONG), - ("GdiThreadLocalInfo", PVOID), - ("Win32ClientInfo", PVOID * 62), - ("glDispatchTable", PVOID * 233), - ("glReserved1", ULONG * 29), - ("glReserved2", PVOID), - ("glSectionInfo", PVOID), - ("glSection", PVOID), - ("glTable", PVOID), - ("glCurrentRC", PVOID), - ("glContext", PVOID), - ("LastStatusValue", NTSTATUS), - ("StaticUnicodeString", UNICODE_STRING), - ("StaticUnicodeBuffer", WCHAR * 261), - ("DeallocationStack", PVOID), - ("TlsSlots", PVOID * 64), - ("TlsLinks", LIST_ENTRY), - ("Vdm", PVOID), - ("ReservedForNtRpc", PVOID), - ("DbgSsReserved", PVOID * 2), - ("HardErrorDisabled", ULONG), - ("Instrumentation", PVOID * 9), - ("ActivityId", GUID), - ("SubProcessTag", PVOID), - ("EtwLocalData", PVOID), - ("EtwTraceData", PVOID), - ("WinSockData", PVOID), - ("GdiBatchCount", ULONG), - ("SpareBool0", BOOLEAN), - ("SpareBool1", BOOLEAN), - ("SpareBool2", BOOLEAN), - ("IdealProcessor", UCHAR), - ("GuaranteedStackBytes", ULONG), - ("ReservedForPerf", PVOID), - ("ReservedForOle", PVOID), - ("WaitingOnLoaderLock", ULONG), - ("StackCommit", PVOID), - ("StackCommitMax", PVOID), - ("StackReserved", PVOID), -] + ("NtTib", NT_TIB), + ("EnvironmentPointer", PVOID), + ("ClientId", CLIENT_ID), + ("ActiveRpcHandle", HANDLE), + ("ThreadLocalStoragePointer", PVOID), + ("ProcessEnvironmentBlock", PPEB), + ("LastErrorValue", ULONG), + ("CountOfOwnedCriticalSections", ULONG), + ("CsrClientThread", PVOID), + ("Win32ThreadInfo", PVOID), + ("User32Reserved", ULONG * 26), + ("UserReserved", ULONG * 5), + ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode + ("CurrentLocale", ULONG), + ("FpSoftwareStatusRegister", ULONG), + ("SystemReserved1", PVOID * 54), + ("Spare1", PVOID), + ("ExceptionCode", ULONG), + ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK + ("SpareBytes1", ULONG * 36), + ("TxFsContext", ULONG), + ("GdiTebBatch", GDI_TEB_BATCH), + ("RealClientId", CLIENT_ID), + ("GdiCachedProcessHandle", PVOID), + ("GdiClientPID", ULONG), + ("GdiClientTID", ULONG), + ("GdiThreadLocalInfo", PVOID), + ("Win32ClientInfo", PVOID * 62), + ("glDispatchTable", PVOID * 233), + ("glReserved1", ULONG * 29), + ("glReserved2", PVOID), + ("glSectionInfo", PVOID), + ("glSection", PVOID), + ("glTable", PVOID), + ("glCurrentRC", PVOID), + ("glContext", PVOID), + ("LastStatusValue", NTSTATUS), + ("StaticUnicodeString", UNICODE_STRING), + ("StaticUnicodeBuffer", WCHAR * 261), + ("DeallocationStack", PVOID), + ("TlsSlots", PVOID * 64), + ("TlsLinks", LIST_ENTRY), + ("Vdm", PVOID), + ("ReservedForNtRpc", PVOID), + ("DbgSsReserved", PVOID * 2), + ("HardErrorDisabled", ULONG), + ("Instrumentation", PVOID * 9), + ("ActivityId", GUID), + ("SubProcessTag", PVOID), + ("EtwLocalData", PVOID), + ("EtwTraceData", PVOID), + ("WinSockData", PVOID), + ("GdiBatchCount", ULONG), + ("SpareBool0", BOOLEAN), + ("SpareBool1", BOOLEAN), + ("SpareBool2", BOOLEAN), + ("IdealProcessor", UCHAR), + ("GuaranteedStackBytes", ULONG), + ("ReservedForPerf", PVOID), + ("ReservedForOle", PVOID), + ("WaitingOnLoaderLock", ULONG), + ("StackCommit", PVOID), + ("StackCommitMax", PVOID), + ("StackReserved", PVOID), + ] + # not really, but "dt _TEB" in w2k isn't working for me :( _TEB_2000 = _TEB_NT + # +0x000 NtTib : _NT_TIB # +0x01c EnvironmentPointer : Ptr32 Void # +0x020 ClientId : _CLIENT_ID @@ -2241,74 +2312,75 @@ class _TEB_NT(Structure): class _TEB_XP(Structure): _pack_ = 8 _fields_ = [ - ("NtTib", NT_TIB), - ("EnvironmentPointer", PVOID), - ("ClientId", CLIENT_ID), - ("ActiveRpcHandle", HANDLE), - ("ThreadLocalStoragePointer", PVOID), - ("ProcessEnvironmentBlock", PVOID), # PPEB - ("LastErrorValue", DWORD), - ("CountOfOwnedCriticalSections", DWORD), - ("CsrClientThread", PVOID), - ("Win32ThreadInfo", PVOID), - ("User32Reserved", DWORD * 26), - ("UserReserved", DWORD * 5), - ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode - ("CurrentLocale", DWORD), - ("FpSoftwareStatusRegister", DWORD), - ("SystemReserved1", PVOID * 54), - ("ExceptionCode", SDWORD), - ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK - ("SpareBytes1", UCHAR * 24), - ("TxFsContext", DWORD), - ("GdiTebBatch", GDI_TEB_BATCH), - ("RealClientId", CLIENT_ID), - ("GdiCachedProcessHandle", HANDLE), - ("GdiClientPID", DWORD), - ("GdiClientTID", DWORD), - ("GdiThreadLocalInfo", PVOID), - ("Win32ClientInfo", DWORD * 62), - ("glDispatchTable", PVOID * 233), - ("glReserved1", DWORD * 29), - ("glReserved2", PVOID), - ("glSectionInfo", PVOID), - ("glSection", PVOID), - ("glTable", PVOID), - ("glCurrentRC", PVOID), - ("glContext", PVOID), - ("LastStatusValue", NTSTATUS), - ("StaticUnicodeString", UNICODE_STRING), - ("StaticUnicodeBuffer", WCHAR * 261), - ("DeallocationStack", PVOID), - ("TlsSlots", PVOID * 64), - ("TlsLinks", LIST_ENTRY), - ("Vdm", PVOID), - ("ReservedForNtRpc", PVOID), - ("DbgSsReserved", PVOID * 2), - ("HardErrorsAreDisabled", DWORD), - ("Instrumentation", PVOID * 16), - ("WinSockData", PVOID), - ("GdiBatchCount", DWORD), - ("InDbgPrint", BOOLEAN), - ("FreeStackOnTermination", BOOLEAN), - ("HasFiberData", BOOLEAN), - ("IdealProcessor", UCHAR), - ("Spare3", DWORD), - ("ReservedForPerf", PVOID), - ("ReservedForOle", PVOID), - ("WaitingOnLoaderLock", DWORD), - ("Wx86Thread", Wx86ThreadState), - ("TlsExpansionSlots", PVOID), # Ptr32 Ptr32 Void - ("ImpersonationLocale", DWORD), - ("IsImpersonating", BOOL), - ("NlsCache", PVOID), - ("pShimData", PVOID), - ("HeapVirtualAffinity", DWORD), - ("CurrentTransactionHandle", HANDLE), - ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME - ("SafeThunkCall", BOOLEAN), - ("BooleanSpare", BOOLEAN * 3), -] + ("NtTib", NT_TIB), + ("EnvironmentPointer", PVOID), + ("ClientId", CLIENT_ID), + ("ActiveRpcHandle", HANDLE), + ("ThreadLocalStoragePointer", PVOID), + ("ProcessEnvironmentBlock", PVOID), # PPEB + ("LastErrorValue", DWORD), + ("CountOfOwnedCriticalSections", DWORD), + ("CsrClientThread", PVOID), + ("Win32ThreadInfo", PVOID), + ("User32Reserved", DWORD * 26), + ("UserReserved", DWORD * 5), + ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode + ("CurrentLocale", DWORD), + ("FpSoftwareStatusRegister", DWORD), + ("SystemReserved1", PVOID * 54), + ("ExceptionCode", SDWORD), + ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK + ("SpareBytes1", UCHAR * 24), + ("TxFsContext", DWORD), + ("GdiTebBatch", GDI_TEB_BATCH), + ("RealClientId", CLIENT_ID), + ("GdiCachedProcessHandle", HANDLE), + ("GdiClientPID", DWORD), + ("GdiClientTID", DWORD), + ("GdiThreadLocalInfo", PVOID), + ("Win32ClientInfo", DWORD * 62), + ("glDispatchTable", PVOID * 233), + ("glReserved1", DWORD * 29), + ("glReserved2", PVOID), + ("glSectionInfo", PVOID), + ("glSection", PVOID), + ("glTable", PVOID), + ("glCurrentRC", PVOID), + ("glContext", PVOID), + ("LastStatusValue", NTSTATUS), + ("StaticUnicodeString", UNICODE_STRING), + ("StaticUnicodeBuffer", WCHAR * 261), + ("DeallocationStack", PVOID), + ("TlsSlots", PVOID * 64), + ("TlsLinks", LIST_ENTRY), + ("Vdm", PVOID), + ("ReservedForNtRpc", PVOID), + ("DbgSsReserved", PVOID * 2), + ("HardErrorsAreDisabled", DWORD), + ("Instrumentation", PVOID * 16), + ("WinSockData", PVOID), + ("GdiBatchCount", DWORD), + ("InDbgPrint", BOOLEAN), + ("FreeStackOnTermination", BOOLEAN), + ("HasFiberData", BOOLEAN), + ("IdealProcessor", UCHAR), + ("Spare3", DWORD), + ("ReservedForPerf", PVOID), + ("ReservedForOle", PVOID), + ("WaitingOnLoaderLock", DWORD), + ("Wx86Thread", Wx86ThreadState), + ("TlsExpansionSlots", PVOID), # Ptr32 Ptr32 Void + ("ImpersonationLocale", DWORD), + ("IsImpersonating", BOOL), + ("NlsCache", PVOID), + ("pShimData", PVOID), + ("HeapVirtualAffinity", DWORD), + ("CurrentTransactionHandle", HANDLE), + ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME + ("SafeThunkCall", BOOLEAN), + ("BooleanSpare", BOOLEAN * 3), + ] + # +0x000 NtTib : _NT_TIB # +0x038 EnvironmentPointer : Ptr64 Void @@ -2386,80 +2458,81 @@ class _TEB_XP(Structure): class _TEB_XP_64(Structure): _pack_ = 8 _fields_ = [ - ("NtTib", NT_TIB), - ("EnvironmentPointer", PVOID), - ("ClientId", CLIENT_ID), - ("ActiveRpcHandle", PVOID), - ("ThreadLocalStoragePointer", PVOID), - ("ProcessEnvironmentBlock", PVOID), # PPEB - ("LastErrorValue", DWORD), - ("CountOfOwnedCriticalSections", DWORD), - ("CsrClientThread", PVOID), - ("Win32ThreadInfo", PVOID), - ("User32Reserved", DWORD * 26), - ("UserReserved", DWORD * 5), - ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode - ("CurrentLocale", DWORD), - ("FpSoftwareStatusRegister", DWORD), - ("SystemReserved1", PVOID * 54), - ("ExceptionCode", SDWORD), - ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK - ("SpareBytes1", UCHAR * 28), - ("GdiTebBatch", GDI_TEB_BATCH), - ("RealClientId", CLIENT_ID), - ("GdiCachedProcessHandle", HANDLE), - ("GdiClientPID", DWORD), - ("GdiClientTID", DWORD), - ("GdiThreadLocalInfo", PVOID), - ("Win32ClientInfo", QWORD * 62), - ("glDispatchTable", PVOID * 233), - ("glReserved1", QWORD * 29), - ("glReserved2", PVOID), - ("glSectionInfo", PVOID), - ("glSection", PVOID), - ("glTable", PVOID), - ("glCurrentRC", PVOID), - ("glContext", PVOID), - ("LastStatusValue", NTSTATUS), - ("StaticUnicodeString", UNICODE_STRING), - ("StaticUnicodeBuffer", WCHAR * 261), - ("DeallocationStack", PVOID), - ("TlsSlots", PVOID * 64), - ("TlsLinks", LIST_ENTRY), - ("Vdm", PVOID), - ("ReservedForNtRpc", PVOID), - ("DbgSsReserved", PVOID * 2), - ("HardErrorMode", DWORD), - ("Instrumentation", PVOID * 14), - ("SubProcessTag", PVOID), - ("EtwTraceData", PVOID), - ("WinSockData", PVOID), - ("GdiBatchCount", DWORD), - ("InDbgPrint", BOOLEAN), - ("FreeStackOnTermination", BOOLEAN), - ("HasFiberData", BOOLEAN), - ("IdealProcessor", UCHAR), - ("GuaranteedStackBytes", DWORD), - ("ReservedForPerf", PVOID), - ("ReservedForOle", PVOID), - ("WaitingOnLoaderLock", DWORD), - ("SparePointer1", PVOID), - ("SoftPatchPtr1", PVOID), - ("SoftPatchPtr2", PVOID), - ("TlsExpansionSlots", PVOID), # Ptr64 Ptr64 Void - ("DeallocationBStore", PVOID), - ("BStoreLimit", PVOID), - ("ImpersonationLocale", DWORD), - ("IsImpersonating", BOOL), - ("NlsCache", PVOID), - ("pShimData", PVOID), - ("HeapVirtualAffinity", DWORD), - ("CurrentTransactionHandle", HANDLE), - ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME - ("FlsData", PVOID), - ("SafeThunkCall", BOOLEAN), - ("BooleanSpare", BOOLEAN * 3), -] + ("NtTib", NT_TIB), + ("EnvironmentPointer", PVOID), + ("ClientId", CLIENT_ID), + ("ActiveRpcHandle", PVOID), + ("ThreadLocalStoragePointer", PVOID), + ("ProcessEnvironmentBlock", PVOID), # PPEB + ("LastErrorValue", DWORD), + ("CountOfOwnedCriticalSections", DWORD), + ("CsrClientThread", PVOID), + ("Win32ThreadInfo", PVOID), + ("User32Reserved", DWORD * 26), + ("UserReserved", DWORD * 5), + ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode + ("CurrentLocale", DWORD), + ("FpSoftwareStatusRegister", DWORD), + ("SystemReserved1", PVOID * 54), + ("ExceptionCode", SDWORD), + ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK + ("SpareBytes1", UCHAR * 28), + ("GdiTebBatch", GDI_TEB_BATCH), + ("RealClientId", CLIENT_ID), + ("GdiCachedProcessHandle", HANDLE), + ("GdiClientPID", DWORD), + ("GdiClientTID", DWORD), + ("GdiThreadLocalInfo", PVOID), + ("Win32ClientInfo", QWORD * 62), + ("glDispatchTable", PVOID * 233), + ("glReserved1", QWORD * 29), + ("glReserved2", PVOID), + ("glSectionInfo", PVOID), + ("glSection", PVOID), + ("glTable", PVOID), + ("glCurrentRC", PVOID), + ("glContext", PVOID), + ("LastStatusValue", NTSTATUS), + ("StaticUnicodeString", UNICODE_STRING), + ("StaticUnicodeBuffer", WCHAR * 261), + ("DeallocationStack", PVOID), + ("TlsSlots", PVOID * 64), + ("TlsLinks", LIST_ENTRY), + ("Vdm", PVOID), + ("ReservedForNtRpc", PVOID), + ("DbgSsReserved", PVOID * 2), + ("HardErrorMode", DWORD), + ("Instrumentation", PVOID * 14), + ("SubProcessTag", PVOID), + ("EtwTraceData", PVOID), + ("WinSockData", PVOID), + ("GdiBatchCount", DWORD), + ("InDbgPrint", BOOLEAN), + ("FreeStackOnTermination", BOOLEAN), + ("HasFiberData", BOOLEAN), + ("IdealProcessor", UCHAR), + ("GuaranteedStackBytes", DWORD), + ("ReservedForPerf", PVOID), + ("ReservedForOle", PVOID), + ("WaitingOnLoaderLock", DWORD), + ("SparePointer1", PVOID), + ("SoftPatchPtr1", PVOID), + ("SoftPatchPtr2", PVOID), + ("TlsExpansionSlots", PVOID), # Ptr64 Ptr64 Void + ("DeallocationBStore", PVOID), + ("BStoreLimit", PVOID), + ("ImpersonationLocale", DWORD), + ("IsImpersonating", BOOL), + ("NlsCache", PVOID), + ("pShimData", PVOID), + ("HeapVirtualAffinity", DWORD), + ("CurrentTransactionHandle", HANDLE), + ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME + ("FlsData", PVOID), + ("SafeThunkCall", BOOLEAN), + ("BooleanSpare", BOOLEAN * 3), + ] + # +0x000 NtTib : _NT_TIB # +0x01c EnvironmentPointer : Ptr32 Void @@ -2535,83 +2608,85 @@ class _TEB_XP_64(Structure): class _TEB_2003(Structure): _pack_ = 8 _fields_ = [ - ("NtTib", NT_TIB), - ("EnvironmentPointer", PVOID), - ("ClientId", CLIENT_ID), - ("ActiveRpcHandle", HANDLE), - ("ThreadLocalStoragePointer", PVOID), - ("ProcessEnvironmentBlock", PVOID), # PPEB - ("LastErrorValue", DWORD), - ("CountOfOwnedCriticalSections", DWORD), - ("CsrClientThread", PVOID), - ("Win32ThreadInfo", PVOID), - ("User32Reserved", DWORD * 26), - ("UserReserved", DWORD * 5), - ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode - ("CurrentLocale", DWORD), - ("FpSoftwareStatusRegister", DWORD), - ("SystemReserved1", PVOID * 54), - ("ExceptionCode", SDWORD), - ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK - ("SpareBytes1", UCHAR * 40), - ("GdiTebBatch", GDI_TEB_BATCH), - ("RealClientId", CLIENT_ID), - ("GdiCachedProcessHandle", HANDLE), - ("GdiClientPID", DWORD), - ("GdiClientTID", DWORD), - ("GdiThreadLocalInfo", PVOID), - ("Win32ClientInfo", DWORD * 62), - ("glDispatchTable", PVOID * 233), - ("glReserved1", DWORD * 29), - ("glReserved2", PVOID), - ("glSectionInfo", PVOID), - ("glSection", PVOID), - ("glTable", PVOID), - ("glCurrentRC", PVOID), - ("glContext", PVOID), - ("LastStatusValue", NTSTATUS), - ("StaticUnicodeString", UNICODE_STRING), - ("StaticUnicodeBuffer", WCHAR * 261), - ("DeallocationStack", PVOID), - ("TlsSlots", PVOID * 64), - ("TlsLinks", LIST_ENTRY), - ("Vdm", PVOID), - ("ReservedForNtRpc", PVOID), - ("DbgSsReserved", PVOID * 2), - ("HardErrorMode", DWORD), - ("Instrumentation", PVOID * 14), - ("SubProcessTag", PVOID), - ("EtwTraceData", PVOID), - ("WinSockData", PVOID), - ("GdiBatchCount", DWORD), - ("InDbgPrint", BOOLEAN), - ("FreeStackOnTermination", BOOLEAN), - ("HasFiberData", BOOLEAN), - ("IdealProcessor", UCHAR), - ("GuaranteedStackBytes", DWORD), - ("ReservedForPerf", PVOID), - ("ReservedForOle", PVOID), - ("WaitingOnLoaderLock", DWORD), - ("SparePointer1", PVOID), - ("SoftPatchPtr1", PVOID), - ("SoftPatchPtr2", PVOID), - ("TlsExpansionSlots", PVOID), # Ptr32 Ptr32 Void - ("ImpersonationLocale", DWORD), - ("IsImpersonating", BOOL), - ("NlsCache", PVOID), - ("pShimData", PVOID), - ("HeapVirtualAffinity", DWORD), - ("CurrentTransactionHandle", HANDLE), - ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME - ("FlsData", PVOID), - ("SafeThunkCall", BOOLEAN), - ("BooleanSpare", BOOLEAN * 3), -] + ("NtTib", NT_TIB), + ("EnvironmentPointer", PVOID), + ("ClientId", CLIENT_ID), + ("ActiveRpcHandle", HANDLE), + ("ThreadLocalStoragePointer", PVOID), + ("ProcessEnvironmentBlock", PVOID), # PPEB + ("LastErrorValue", DWORD), + ("CountOfOwnedCriticalSections", DWORD), + ("CsrClientThread", PVOID), + ("Win32ThreadInfo", PVOID), + ("User32Reserved", DWORD * 26), + ("UserReserved", DWORD * 5), + ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode + ("CurrentLocale", DWORD), + ("FpSoftwareStatusRegister", DWORD), + ("SystemReserved1", PVOID * 54), + ("ExceptionCode", SDWORD), + ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK + ("SpareBytes1", UCHAR * 40), + ("GdiTebBatch", GDI_TEB_BATCH), + ("RealClientId", CLIENT_ID), + ("GdiCachedProcessHandle", HANDLE), + ("GdiClientPID", DWORD), + ("GdiClientTID", DWORD), + ("GdiThreadLocalInfo", PVOID), + ("Win32ClientInfo", DWORD * 62), + ("glDispatchTable", PVOID * 233), + ("glReserved1", DWORD * 29), + ("glReserved2", PVOID), + ("glSectionInfo", PVOID), + ("glSection", PVOID), + ("glTable", PVOID), + ("glCurrentRC", PVOID), + ("glContext", PVOID), + ("LastStatusValue", NTSTATUS), + ("StaticUnicodeString", UNICODE_STRING), + ("StaticUnicodeBuffer", WCHAR * 261), + ("DeallocationStack", PVOID), + ("TlsSlots", PVOID * 64), + ("TlsLinks", LIST_ENTRY), + ("Vdm", PVOID), + ("ReservedForNtRpc", PVOID), + ("DbgSsReserved", PVOID * 2), + ("HardErrorMode", DWORD), + ("Instrumentation", PVOID * 14), + ("SubProcessTag", PVOID), + ("EtwTraceData", PVOID), + ("WinSockData", PVOID), + ("GdiBatchCount", DWORD), + ("InDbgPrint", BOOLEAN), + ("FreeStackOnTermination", BOOLEAN), + ("HasFiberData", BOOLEAN), + ("IdealProcessor", UCHAR), + ("GuaranteedStackBytes", DWORD), + ("ReservedForPerf", PVOID), + ("ReservedForOle", PVOID), + ("WaitingOnLoaderLock", DWORD), + ("SparePointer1", PVOID), + ("SoftPatchPtr1", PVOID), + ("SoftPatchPtr2", PVOID), + ("TlsExpansionSlots", PVOID), # Ptr32 Ptr32 Void + ("ImpersonationLocale", DWORD), + ("IsImpersonating", BOOL), + ("NlsCache", PVOID), + ("pShimData", PVOID), + ("HeapVirtualAffinity", DWORD), + ("CurrentTransactionHandle", HANDLE), + ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME + ("FlsData", PVOID), + ("SafeThunkCall", BOOLEAN), + ("BooleanSpare", BOOLEAN * 3), + ] -_TEB_2003_64 = _TEB_XP_64 -_TEB_2003_R2 = _TEB_2003 + +_TEB_2003_64 = _TEB_XP_64 +_TEB_2003_R2 = _TEB_2003 _TEB_2003_R2_64 = _TEB_2003_64 + # +0x000 NtTib : _NT_TIB # +0x01c EnvironmentPointer : Ptr32 Void # +0x020 ClientId : _CLIENT_ID @@ -2713,93 +2788,94 @@ class _TEB_2003(Structure): class _TEB_2008(Structure): _pack_ = 8 _fields_ = [ - ("NtTib", NT_TIB), - ("EnvironmentPointer", PVOID), - ("ClientId", CLIENT_ID), - ("ActiveRpcHandle", HANDLE), - ("ThreadLocalStoragePointer", PVOID), - ("ProcessEnvironmentBlock", PVOID), # PPEB - ("LastErrorValue", DWORD), - ("CountOfOwnedCriticalSections", DWORD), - ("CsrClientThread", PVOID), - ("Win32ThreadInfo", PVOID), - ("User32Reserved", DWORD * 26), - ("UserReserved", DWORD * 5), - ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode - ("CurrentLocale", DWORD), - ("FpSoftwareStatusRegister", DWORD), - ("SystemReserved1", PVOID * 54), - ("ExceptionCode", SDWORD), - ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK - ("SpareBytes1", UCHAR * 36), - ("TxFsContext", DWORD), - ("GdiTebBatch", GDI_TEB_BATCH), - ("RealClientId", CLIENT_ID), - ("GdiCachedProcessHandle", HANDLE), - ("GdiClientPID", DWORD), - ("GdiClientTID", DWORD), - ("GdiThreadLocalInfo", PVOID), - ("Win32ClientInfo", DWORD * 62), - ("glDispatchTable", PVOID * 233), - ("glReserved1", DWORD * 29), - ("glReserved2", PVOID), - ("glSectionInfo", PVOID), - ("glSection", PVOID), - ("glTable", PVOID), - ("glCurrentRC", PVOID), - ("glContext", PVOID), - ("LastStatusValue", NTSTATUS), - ("StaticUnicodeString", UNICODE_STRING), - ("StaticUnicodeBuffer", WCHAR * 261), - ("DeallocationStack", PVOID), - ("TlsSlots", PVOID * 64), - ("TlsLinks", LIST_ENTRY), - ("Vdm", PVOID), - ("ReservedForNtRpc", PVOID), - ("DbgSsReserved", PVOID * 2), - ("HardErrorMode", DWORD), - ("Instrumentation", PVOID * 9), - ("ActivityId", GUID), - ("SubProcessTag", PVOID), - ("EtwLocalData", PVOID), - ("EtwTraceData", PVOID), - ("WinSockData", PVOID), - ("GdiBatchCount", DWORD), - ("SpareBool0", BOOLEAN), - ("SpareBool1", BOOLEAN), - ("SpareBool2", BOOLEAN), - ("IdealProcessor", UCHAR), - ("GuaranteedStackBytes", DWORD), - ("ReservedForPerf", PVOID), - ("ReservedForOle", PVOID), - ("WaitingOnLoaderLock", DWORD), - ("SavedPriorityState", PVOID), - ("SoftPatchPtr1", PVOID), - ("ThreadPoolData", PVOID), - ("TlsExpansionSlots", PVOID), # Ptr32 Ptr32 Void - ("ImpersonationLocale", DWORD), - ("IsImpersonating", BOOL), - ("NlsCache", PVOID), - ("pShimData", PVOID), - ("HeapVirtualAffinity", DWORD), - ("CurrentTransactionHandle", HANDLE), - ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME - ("FlsData", PVOID), - ("PreferredLanguages", PVOID), - ("UserPrefLanguages", PVOID), - ("MergedPrefLanguages", PVOID), - ("MuiImpersonation", BOOL), - ("CrossTebFlags", WORD), - ("SameTebFlags", WORD), - ("TxnScopeEnterCallback", PVOID), - ("TxnScopeExitCallback", PVOID), - ("TxnScopeContext", PVOID), - ("LockCount", DWORD), - ("ProcessRundown", DWORD), - ("LastSwitchTime", QWORD), - ("TotalSwitchOutTime", QWORD), - ("WaitReasonBitMap", LONGLONG), # LARGE_INTEGER -] + ("NtTib", NT_TIB), + ("EnvironmentPointer", PVOID), + ("ClientId", CLIENT_ID), + ("ActiveRpcHandle", HANDLE), + ("ThreadLocalStoragePointer", PVOID), + ("ProcessEnvironmentBlock", PVOID), # PPEB + ("LastErrorValue", DWORD), + ("CountOfOwnedCriticalSections", DWORD), + ("CsrClientThread", PVOID), + ("Win32ThreadInfo", PVOID), + ("User32Reserved", DWORD * 26), + ("UserReserved", DWORD * 5), + ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode + ("CurrentLocale", DWORD), + ("FpSoftwareStatusRegister", DWORD), + ("SystemReserved1", PVOID * 54), + ("ExceptionCode", SDWORD), + ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK + ("SpareBytes1", UCHAR * 36), + ("TxFsContext", DWORD), + ("GdiTebBatch", GDI_TEB_BATCH), + ("RealClientId", CLIENT_ID), + ("GdiCachedProcessHandle", HANDLE), + ("GdiClientPID", DWORD), + ("GdiClientTID", DWORD), + ("GdiThreadLocalInfo", PVOID), + ("Win32ClientInfo", DWORD * 62), + ("glDispatchTable", PVOID * 233), + ("glReserved1", DWORD * 29), + ("glReserved2", PVOID), + ("glSectionInfo", PVOID), + ("glSection", PVOID), + ("glTable", PVOID), + ("glCurrentRC", PVOID), + ("glContext", PVOID), + ("LastStatusValue", NTSTATUS), + ("StaticUnicodeString", UNICODE_STRING), + ("StaticUnicodeBuffer", WCHAR * 261), + ("DeallocationStack", PVOID), + ("TlsSlots", PVOID * 64), + ("TlsLinks", LIST_ENTRY), + ("Vdm", PVOID), + ("ReservedForNtRpc", PVOID), + ("DbgSsReserved", PVOID * 2), + ("HardErrorMode", DWORD), + ("Instrumentation", PVOID * 9), + ("ActivityId", GUID), + ("SubProcessTag", PVOID), + ("EtwLocalData", PVOID), + ("EtwTraceData", PVOID), + ("WinSockData", PVOID), + ("GdiBatchCount", DWORD), + ("SpareBool0", BOOLEAN), + ("SpareBool1", BOOLEAN), + ("SpareBool2", BOOLEAN), + ("IdealProcessor", UCHAR), + ("GuaranteedStackBytes", DWORD), + ("ReservedForPerf", PVOID), + ("ReservedForOle", PVOID), + ("WaitingOnLoaderLock", DWORD), + ("SavedPriorityState", PVOID), + ("SoftPatchPtr1", PVOID), + ("ThreadPoolData", PVOID), + ("TlsExpansionSlots", PVOID), # Ptr32 Ptr32 Void + ("ImpersonationLocale", DWORD), + ("IsImpersonating", BOOL), + ("NlsCache", PVOID), + ("pShimData", PVOID), + ("HeapVirtualAffinity", DWORD), + ("CurrentTransactionHandle", HANDLE), + ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME + ("FlsData", PVOID), + ("PreferredLanguages", PVOID), + ("UserPrefLanguages", PVOID), + ("MergedPrefLanguages", PVOID), + ("MuiImpersonation", BOOL), + ("CrossTebFlags", WORD), + ("SameTebFlags", WORD), + ("TxnScopeEnterCallback", PVOID), + ("TxnScopeExitCallback", PVOID), + ("TxnScopeContext", PVOID), + ("LockCount", DWORD), + ("ProcessRundown", DWORD), + ("LastSwitchTime", QWORD), + ("TotalSwitchOutTime", QWORD), + ("WaitReasonBitMap", LONGLONG), # LARGE_INTEGER + ] + # +0x000 NtTib : _NT_TIB # +0x038 EnvironmentPointer : Ptr64 Void @@ -2904,95 +2980,96 @@ class _TEB_2008(Structure): class _TEB_2008_64(Structure): _pack_ = 8 _fields_ = [ - ("NtTib", NT_TIB), - ("EnvironmentPointer", PVOID), - ("ClientId", CLIENT_ID), - ("ActiveRpcHandle", HANDLE), - ("ThreadLocalStoragePointer", PVOID), - ("ProcessEnvironmentBlock", PVOID), # PPEB - ("LastErrorValue", DWORD), - ("CountOfOwnedCriticalSections", DWORD), - ("CsrClientThread", PVOID), - ("Win32ThreadInfo", PVOID), - ("User32Reserved", DWORD * 26), - ("UserReserved", DWORD * 5), - ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode - ("CurrentLocale", DWORD), - ("FpSoftwareStatusRegister", DWORD), - ("SystemReserved1", PVOID * 54), - ("ExceptionCode", SDWORD), - ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK - ("SpareBytes1", UCHAR * 24), - ("TxFsContext", DWORD), - ("GdiTebBatch", GDI_TEB_BATCH), - ("RealClientId", CLIENT_ID), - ("GdiCachedProcessHandle", HANDLE), - ("GdiClientPID", DWORD), - ("GdiClientTID", DWORD), - ("GdiThreadLocalInfo", PVOID), - ("Win32ClientInfo", QWORD * 62), - ("glDispatchTable", PVOID * 233), - ("glReserved1", QWORD * 29), - ("glReserved2", PVOID), - ("glSectionInfo", PVOID), - ("glSection", PVOID), - ("glTable", PVOID), - ("glCurrentRC", PVOID), - ("glContext", PVOID), - ("LastStatusValue", NTSTATUS), - ("StaticUnicodeString", UNICODE_STRING), - ("StaticUnicodeBuffer", WCHAR * 261), - ("DeallocationStack", PVOID), - ("TlsSlots", PVOID * 64), - ("TlsLinks", LIST_ENTRY), - ("Vdm", PVOID), - ("ReservedForNtRpc", PVOID), - ("DbgSsReserved", PVOID * 2), - ("HardErrorMode", DWORD), - ("Instrumentation", PVOID * 11), - ("ActivityId", GUID), - ("SubProcessTag", PVOID), - ("EtwLocalData", PVOID), - ("EtwTraceData", PVOID), - ("WinSockData", PVOID), - ("GdiBatchCount", DWORD), - ("SpareBool0", BOOLEAN), - ("SpareBool1", BOOLEAN), - ("SpareBool2", BOOLEAN), - ("IdealProcessor", UCHAR), - ("GuaranteedStackBytes", DWORD), - ("ReservedForPerf", PVOID), - ("ReservedForOle", PVOID), - ("WaitingOnLoaderLock", DWORD), - ("SavedPriorityState", PVOID), - ("SoftPatchPtr1", PVOID), - ("ThreadPoolData", PVOID), - ("TlsExpansionSlots", PVOID), # Ptr64 Ptr64 Void - ("DeallocationBStore", PVOID), - ("BStoreLimit", PVOID), - ("ImpersonationLocale", DWORD), - ("IsImpersonating", BOOL), - ("NlsCache", PVOID), - ("pShimData", PVOID), - ("HeapVirtualAffinity", DWORD), - ("CurrentTransactionHandle", HANDLE), - ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME - ("FlsData", PVOID), - ("PreferredLanguages", PVOID), - ("UserPrefLanguages", PVOID), - ("MergedPrefLanguages", PVOID), - ("MuiImpersonation", BOOL), - ("CrossTebFlags", WORD), - ("SameTebFlags", WORD), - ("TxnScopeEnterCallback", PVOID), - ("TxnScopeExitCallback", PVOID), - ("TxnScopeContext", PVOID), - ("LockCount", DWORD), - ("ProcessRundown", DWORD), - ("LastSwitchTime", QWORD), - ("TotalSwitchOutTime", QWORD), - ("WaitReasonBitMap", LONGLONG), # LARGE_INTEGER -] + ("NtTib", NT_TIB), + ("EnvironmentPointer", PVOID), + ("ClientId", CLIENT_ID), + ("ActiveRpcHandle", HANDLE), + ("ThreadLocalStoragePointer", PVOID), + ("ProcessEnvironmentBlock", PVOID), # PPEB + ("LastErrorValue", DWORD), + ("CountOfOwnedCriticalSections", DWORD), + ("CsrClientThread", PVOID), + ("Win32ThreadInfo", PVOID), + ("User32Reserved", DWORD * 26), + ("UserReserved", DWORD * 5), + ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode + ("CurrentLocale", DWORD), + ("FpSoftwareStatusRegister", DWORD), + ("SystemReserved1", PVOID * 54), + ("ExceptionCode", SDWORD), + ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK + ("SpareBytes1", UCHAR * 24), + ("TxFsContext", DWORD), + ("GdiTebBatch", GDI_TEB_BATCH), + ("RealClientId", CLIENT_ID), + ("GdiCachedProcessHandle", HANDLE), + ("GdiClientPID", DWORD), + ("GdiClientTID", DWORD), + ("GdiThreadLocalInfo", PVOID), + ("Win32ClientInfo", QWORD * 62), + ("glDispatchTable", PVOID * 233), + ("glReserved1", QWORD * 29), + ("glReserved2", PVOID), + ("glSectionInfo", PVOID), + ("glSection", PVOID), + ("glTable", PVOID), + ("glCurrentRC", PVOID), + ("glContext", PVOID), + ("LastStatusValue", NTSTATUS), + ("StaticUnicodeString", UNICODE_STRING), + ("StaticUnicodeBuffer", WCHAR * 261), + ("DeallocationStack", PVOID), + ("TlsSlots", PVOID * 64), + ("TlsLinks", LIST_ENTRY), + ("Vdm", PVOID), + ("ReservedForNtRpc", PVOID), + ("DbgSsReserved", PVOID * 2), + ("HardErrorMode", DWORD), + ("Instrumentation", PVOID * 11), + ("ActivityId", GUID), + ("SubProcessTag", PVOID), + ("EtwLocalData", PVOID), + ("EtwTraceData", PVOID), + ("WinSockData", PVOID), + ("GdiBatchCount", DWORD), + ("SpareBool0", BOOLEAN), + ("SpareBool1", BOOLEAN), + ("SpareBool2", BOOLEAN), + ("IdealProcessor", UCHAR), + ("GuaranteedStackBytes", DWORD), + ("ReservedForPerf", PVOID), + ("ReservedForOle", PVOID), + ("WaitingOnLoaderLock", DWORD), + ("SavedPriorityState", PVOID), + ("SoftPatchPtr1", PVOID), + ("ThreadPoolData", PVOID), + ("TlsExpansionSlots", PVOID), # Ptr64 Ptr64 Void + ("DeallocationBStore", PVOID), + ("BStoreLimit", PVOID), + ("ImpersonationLocale", DWORD), + ("IsImpersonating", BOOL), + ("NlsCache", PVOID), + ("pShimData", PVOID), + ("HeapVirtualAffinity", DWORD), + ("CurrentTransactionHandle", HANDLE), + ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME + ("FlsData", PVOID), + ("PreferredLanguages", PVOID), + ("UserPrefLanguages", PVOID), + ("MergedPrefLanguages", PVOID), + ("MuiImpersonation", BOOL), + ("CrossTebFlags", WORD), + ("SameTebFlags", WORD), + ("TxnScopeEnterCallback", PVOID), + ("TxnScopeExitCallback", PVOID), + ("TxnScopeContext", PVOID), + ("LockCount", DWORD), + ("ProcessRundown", DWORD), + ("LastSwitchTime", QWORD), + ("TotalSwitchOutTime", QWORD), + ("WaitReasonBitMap", LONGLONG), # LARGE_INTEGER + ] + # +0x000 NtTib : _NT_TIB # +0x01c EnvironmentPointer : Ptr32 Void @@ -3096,93 +3173,94 @@ class _TEB_2008_64(Structure): class _TEB_2008_R2(Structure): _pack_ = 8 _fields_ = [ - ("NtTib", NT_TIB), - ("EnvironmentPointer", PVOID), - ("ClientId", CLIENT_ID), - ("ActiveRpcHandle", HANDLE), - ("ThreadLocalStoragePointer", PVOID), - ("ProcessEnvironmentBlock", PVOID), # PPEB - ("LastErrorValue", DWORD), - ("CountOfOwnedCriticalSections", DWORD), - ("CsrClientThread", PVOID), - ("Win32ThreadInfo", PVOID), - ("User32Reserved", DWORD * 26), - ("UserReserved", DWORD * 5), - ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode - ("CurrentLocale", DWORD), - ("FpSoftwareStatusRegister", DWORD), - ("SystemReserved1", PVOID * 54), - ("ExceptionCode", SDWORD), - ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK - ("SpareBytes", UCHAR * 36), - ("TxFsContext", DWORD), - ("GdiTebBatch", GDI_TEB_BATCH), - ("RealClientId", CLIENT_ID), - ("GdiCachedProcessHandle", HANDLE), - ("GdiClientPID", DWORD), - ("GdiClientTID", DWORD), - ("GdiThreadLocalInfo", PVOID), - ("Win32ClientInfo", DWORD * 62), - ("glDispatchTable", PVOID * 233), - ("glReserved1", DWORD * 29), - ("glReserved2", PVOID), - ("glSectionInfo", PVOID), - ("glSection", PVOID), - ("glTable", PVOID), - ("glCurrentRC", PVOID), - ("glContext", PVOID), - ("LastStatusValue", NTSTATUS), - ("StaticUnicodeString", UNICODE_STRING), - ("StaticUnicodeBuffer", WCHAR * 261), - ("DeallocationStack", PVOID), - ("TlsSlots", PVOID * 64), - ("TlsLinks", LIST_ENTRY), - ("Vdm", PVOID), - ("ReservedForNtRpc", PVOID), - ("DbgSsReserved", PVOID * 2), - ("HardErrorMode", DWORD), - ("Instrumentation", PVOID * 9), - ("ActivityId", GUID), - ("SubProcessTag", PVOID), - ("EtwLocalData", PVOID), - ("EtwTraceData", PVOID), - ("WinSockData", PVOID), - ("GdiBatchCount", DWORD), - ("CurrentIdealProcessor", PROCESSOR_NUMBER), - ("IdealProcessorValue", DWORD), - ("ReservedPad0", UCHAR), - ("ReservedPad1", UCHAR), - ("ReservedPad2", UCHAR), - ("IdealProcessor", UCHAR), - ("GuaranteedStackBytes", DWORD), - ("ReservedForPerf", PVOID), - ("ReservedForOle", PVOID), - ("WaitingOnLoaderLock", DWORD), - ("SavedPriorityState", PVOID), - ("SoftPatchPtr1", PVOID), - ("ThreadPoolData", PVOID), - ("TlsExpansionSlots", PVOID), # Ptr32 Ptr32 Void - ("MuiGeneration", DWORD), - ("IsImpersonating", BOOL), - ("NlsCache", PVOID), - ("pShimData", PVOID), - ("HeapVirtualAffinity", DWORD), - ("CurrentTransactionHandle", HANDLE), - ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME - ("FlsData", PVOID), - ("PreferredLanguages", PVOID), - ("UserPrefLanguages", PVOID), - ("MergedPrefLanguages", PVOID), - ("MuiImpersonation", BOOL), - ("CrossTebFlags", WORD), - ("SameTebFlags", WORD), - ("TxnScopeEnterCallback", PVOID), - ("TxnScopeExitCallback", PVOID), - ("TxnScopeContext", PVOID), - ("LockCount", DWORD), - ("SpareUlong0", ULONG), - ("ResourceRetValue", PVOID), -] + ("NtTib", NT_TIB), + ("EnvironmentPointer", PVOID), + ("ClientId", CLIENT_ID), + ("ActiveRpcHandle", HANDLE), + ("ThreadLocalStoragePointer", PVOID), + ("ProcessEnvironmentBlock", PVOID), # PPEB + ("LastErrorValue", DWORD), + ("CountOfOwnedCriticalSections", DWORD), + ("CsrClientThread", PVOID), + ("Win32ThreadInfo", PVOID), + ("User32Reserved", DWORD * 26), + ("UserReserved", DWORD * 5), + ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode + ("CurrentLocale", DWORD), + ("FpSoftwareStatusRegister", DWORD), + ("SystemReserved1", PVOID * 54), + ("ExceptionCode", SDWORD), + ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK + ("SpareBytes", UCHAR * 36), + ("TxFsContext", DWORD), + ("GdiTebBatch", GDI_TEB_BATCH), + ("RealClientId", CLIENT_ID), + ("GdiCachedProcessHandle", HANDLE), + ("GdiClientPID", DWORD), + ("GdiClientTID", DWORD), + ("GdiThreadLocalInfo", PVOID), + ("Win32ClientInfo", DWORD * 62), + ("glDispatchTable", PVOID * 233), + ("glReserved1", DWORD * 29), + ("glReserved2", PVOID), + ("glSectionInfo", PVOID), + ("glSection", PVOID), + ("glTable", PVOID), + ("glCurrentRC", PVOID), + ("glContext", PVOID), + ("LastStatusValue", NTSTATUS), + ("StaticUnicodeString", UNICODE_STRING), + ("StaticUnicodeBuffer", WCHAR * 261), + ("DeallocationStack", PVOID), + ("TlsSlots", PVOID * 64), + ("TlsLinks", LIST_ENTRY), + ("Vdm", PVOID), + ("ReservedForNtRpc", PVOID), + ("DbgSsReserved", PVOID * 2), + ("HardErrorMode", DWORD), + ("Instrumentation", PVOID * 9), + ("ActivityId", GUID), + ("SubProcessTag", PVOID), + ("EtwLocalData", PVOID), + ("EtwTraceData", PVOID), + ("WinSockData", PVOID), + ("GdiBatchCount", DWORD), + ("CurrentIdealProcessor", PROCESSOR_NUMBER), + ("IdealProcessorValue", DWORD), + ("ReservedPad0", UCHAR), + ("ReservedPad1", UCHAR), + ("ReservedPad2", UCHAR), + ("IdealProcessor", UCHAR), + ("GuaranteedStackBytes", DWORD), + ("ReservedForPerf", PVOID), + ("ReservedForOle", PVOID), + ("WaitingOnLoaderLock", DWORD), + ("SavedPriorityState", PVOID), + ("SoftPatchPtr1", PVOID), + ("ThreadPoolData", PVOID), + ("TlsExpansionSlots", PVOID), # Ptr32 Ptr32 Void + ("MuiGeneration", DWORD), + ("IsImpersonating", BOOL), + ("NlsCache", PVOID), + ("pShimData", PVOID), + ("HeapVirtualAffinity", DWORD), + ("CurrentTransactionHandle", HANDLE), + ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME + ("FlsData", PVOID), + ("PreferredLanguages", PVOID), + ("UserPrefLanguages", PVOID), + ("MergedPrefLanguages", PVOID), + ("MuiImpersonation", BOOL), + ("CrossTebFlags", WORD), + ("SameTebFlags", WORD), + ("TxnScopeEnterCallback", PVOID), + ("TxnScopeExitCallback", PVOID), + ("TxnScopeContext", PVOID), + ("LockCount", DWORD), + ("SpareUlong0", ULONG), + ("ResourceRetValue", PVOID), + ] + # +0x000 NtTib : _NT_TIB # +0x038 EnvironmentPointer : Ptr64 Void @@ -3288,148 +3366,152 @@ class _TEB_2008_R2(Structure): class _TEB_2008_R2_64(Structure): _pack_ = 8 _fields_ = [ - ("NtTib", NT_TIB), - ("EnvironmentPointer", PVOID), - ("ClientId", CLIENT_ID), - ("ActiveRpcHandle", HANDLE), - ("ThreadLocalStoragePointer", PVOID), - ("ProcessEnvironmentBlock", PVOID), # PPEB - ("LastErrorValue", DWORD), - ("CountOfOwnedCriticalSections", DWORD), - ("CsrClientThread", PVOID), - ("Win32ThreadInfo", PVOID), - ("User32Reserved", DWORD * 26), - ("UserReserved", DWORD * 5), - ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode - ("CurrentLocale", DWORD), - ("FpSoftwareStatusRegister", DWORD), - ("SystemReserved1", PVOID * 54), - ("ExceptionCode", SDWORD), - ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK - ("SpareBytes", UCHAR * 24), - ("TxFsContext", DWORD), - ("GdiTebBatch", GDI_TEB_BATCH), - ("RealClientId", CLIENT_ID), - ("GdiCachedProcessHandle", HANDLE), - ("GdiClientPID", DWORD), - ("GdiClientTID", DWORD), - ("GdiThreadLocalInfo", PVOID), - ("Win32ClientInfo", DWORD * 62), - ("glDispatchTable", PVOID * 233), - ("glReserved1", QWORD * 29), - ("glReserved2", PVOID), - ("glSectionInfo", PVOID), - ("glSection", PVOID), - ("glTable", PVOID), - ("glCurrentRC", PVOID), - ("glContext", PVOID), - ("LastStatusValue", NTSTATUS), - ("StaticUnicodeString", UNICODE_STRING), - ("StaticUnicodeBuffer", WCHAR * 261), - ("DeallocationStack", PVOID), - ("TlsSlots", PVOID * 64), - ("TlsLinks", LIST_ENTRY), - ("Vdm", PVOID), - ("ReservedForNtRpc", PVOID), - ("DbgSsReserved", PVOID * 2), - ("HardErrorMode", DWORD), - ("Instrumentation", PVOID * 11), - ("ActivityId", GUID), - ("SubProcessTag", PVOID), - ("EtwLocalData", PVOID), - ("EtwTraceData", PVOID), - ("WinSockData", PVOID), - ("GdiBatchCount", DWORD), - ("CurrentIdealProcessor", PROCESSOR_NUMBER), - ("IdealProcessorValue", DWORD), - ("ReservedPad0", UCHAR), - ("ReservedPad1", UCHAR), - ("ReservedPad2", UCHAR), - ("IdealProcessor", UCHAR), - ("GuaranteedStackBytes", DWORD), - ("ReservedForPerf", PVOID), - ("ReservedForOle", PVOID), - ("WaitingOnLoaderLock", DWORD), - ("SavedPriorityState", PVOID), - ("SoftPatchPtr1", PVOID), - ("ThreadPoolData", PVOID), - ("TlsExpansionSlots", PVOID), # Ptr64 Ptr64 Void - ("DeallocationBStore", PVOID), - ("BStoreLimit", PVOID), - ("MuiGeneration", DWORD), - ("IsImpersonating", BOOL), - ("NlsCache", PVOID), - ("pShimData", PVOID), - ("HeapVirtualAffinity", DWORD), - ("CurrentTransactionHandle", HANDLE), - ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME - ("FlsData", PVOID), - ("PreferredLanguages", PVOID), - ("UserPrefLanguages", PVOID), - ("MergedPrefLanguages", PVOID), - ("MuiImpersonation", BOOL), - ("CrossTebFlags", WORD), - ("SameTebFlags", WORD), - ("TxnScopeEnterCallback", PVOID), - ("TxnScopeExitCallback", PVOID), - ("TxnScopeContext", PVOID), - ("LockCount", DWORD), - ("SpareUlong0", ULONG), - ("ResourceRetValue", PVOID), -] + ("NtTib", NT_TIB), + ("EnvironmentPointer", PVOID), + ("ClientId", CLIENT_ID), + ("ActiveRpcHandle", HANDLE), + ("ThreadLocalStoragePointer", PVOID), + ("ProcessEnvironmentBlock", PVOID), # PPEB + ("LastErrorValue", DWORD), + ("CountOfOwnedCriticalSections", DWORD), + ("CsrClientThread", PVOID), + ("Win32ThreadInfo", PVOID), + ("User32Reserved", DWORD * 26), + ("UserReserved", DWORD * 5), + ("WOW32Reserved", PVOID), # ptr to wow64cpu!X86SwitchTo64BitMode + ("CurrentLocale", DWORD), + ("FpSoftwareStatusRegister", DWORD), + ("SystemReserved1", PVOID * 54), + ("ExceptionCode", SDWORD), + ("ActivationContextStackPointer", PVOID), # PACTIVATION_CONTEXT_STACK + ("SpareBytes", UCHAR * 24), + ("TxFsContext", DWORD), + ("GdiTebBatch", GDI_TEB_BATCH), + ("RealClientId", CLIENT_ID), + ("GdiCachedProcessHandle", HANDLE), + ("GdiClientPID", DWORD), + ("GdiClientTID", DWORD), + ("GdiThreadLocalInfo", PVOID), + ("Win32ClientInfo", DWORD * 62), + ("glDispatchTable", PVOID * 233), + ("glReserved1", QWORD * 29), + ("glReserved2", PVOID), + ("glSectionInfo", PVOID), + ("glSection", PVOID), + ("glTable", PVOID), + ("glCurrentRC", PVOID), + ("glContext", PVOID), + ("LastStatusValue", NTSTATUS), + ("StaticUnicodeString", UNICODE_STRING), + ("StaticUnicodeBuffer", WCHAR * 261), + ("DeallocationStack", PVOID), + ("TlsSlots", PVOID * 64), + ("TlsLinks", LIST_ENTRY), + ("Vdm", PVOID), + ("ReservedForNtRpc", PVOID), + ("DbgSsReserved", PVOID * 2), + ("HardErrorMode", DWORD), + ("Instrumentation", PVOID * 11), + ("ActivityId", GUID), + ("SubProcessTag", PVOID), + ("EtwLocalData", PVOID), + ("EtwTraceData", PVOID), + ("WinSockData", PVOID), + ("GdiBatchCount", DWORD), + ("CurrentIdealProcessor", PROCESSOR_NUMBER), + ("IdealProcessorValue", DWORD), + ("ReservedPad0", UCHAR), + ("ReservedPad1", UCHAR), + ("ReservedPad2", UCHAR), + ("IdealProcessor", UCHAR), + ("GuaranteedStackBytes", DWORD), + ("ReservedForPerf", PVOID), + ("ReservedForOle", PVOID), + ("WaitingOnLoaderLock", DWORD), + ("SavedPriorityState", PVOID), + ("SoftPatchPtr1", PVOID), + ("ThreadPoolData", PVOID), + ("TlsExpansionSlots", PVOID), # Ptr64 Ptr64 Void + ("DeallocationBStore", PVOID), + ("BStoreLimit", PVOID), + ("MuiGeneration", DWORD), + ("IsImpersonating", BOOL), + ("NlsCache", PVOID), + ("pShimData", PVOID), + ("HeapVirtualAffinity", DWORD), + ("CurrentTransactionHandle", HANDLE), + ("ActiveFrame", PVOID), # PTEB_ACTIVE_FRAME + ("FlsData", PVOID), + ("PreferredLanguages", PVOID), + ("UserPrefLanguages", PVOID), + ("MergedPrefLanguages", PVOID), + ("MuiImpersonation", BOOL), + ("CrossTebFlags", WORD), + ("SameTebFlags", WORD), + ("TxnScopeEnterCallback", PVOID), + ("TxnScopeExitCallback", PVOID), + ("TxnScopeContext", PVOID), + ("LockCount", DWORD), + ("SpareUlong0", ULONG), + ("ResourceRetValue", PVOID), + ] + + +_TEB_Vista = _TEB_2008 +_TEB_Vista_64 = _TEB_2008_64 +_TEB_W7 = _TEB_2008_R2 +_TEB_W7_64 = _TEB_2008_R2_64 -_TEB_Vista = _TEB_2008 -_TEB_Vista_64 = _TEB_2008_64 -_TEB_W7 = _TEB_2008_R2 -_TEB_W7_64 = _TEB_2008_R2_64 # Use the correct TEB structure definition. # Defaults to the latest Windows version. class TEB(Structure): _pack_ = 8 - if os == 'Windows NT': - _pack_ = _TEB_NT._pack_ + if os == "Windows NT": + _pack_ = _TEB_NT._pack_ _fields_ = _TEB_NT._fields_ - elif os == 'Windows 2000': - _pack_ = _TEB_2000._pack_ + elif os == "Windows 2000": + _pack_ = _TEB_2000._pack_ _fields_ = _TEB_2000._fields_ - elif os == 'Windows XP': + elif os == "Windows XP": _fields_ = _TEB_XP._fields_ - elif os == 'Windows XP (64 bits)': + elif os == "Windows XP (64 bits)": _fields_ = _TEB_XP_64._fields_ - elif os == 'Windows 2003': + elif os == "Windows 2003": _fields_ = _TEB_2003._fields_ - elif os == 'Windows 2003 (64 bits)': + elif os == "Windows 2003 (64 bits)": _fields_ = _TEB_2003_64._fields_ - elif os == 'Windows 2008': + elif os == "Windows 2008": _fields_ = _TEB_2008._fields_ - elif os == 'Windows 2008 (64 bits)': + elif os == "Windows 2008 (64 bits)": _fields_ = _TEB_2008_64._fields_ - elif os == 'Windows 2003 R2': + elif os == "Windows 2003 R2": _fields_ = _TEB_2003_R2._fields_ - elif os == 'Windows 2003 R2 (64 bits)': + elif os == "Windows 2003 R2 (64 bits)": _fields_ = _TEB_2003_R2_64._fields_ - elif os == 'Windows 2008 R2': + elif os == "Windows 2008 R2": _fields_ = _TEB_2008_R2._fields_ - elif os == 'Windows 2008 R2 (64 bits)': + elif os == "Windows 2008 R2 (64 bits)": _fields_ = _TEB_2008_R2_64._fields_ - elif os == 'Windows Vista': + elif os == "Windows Vista": _fields_ = _TEB_Vista._fields_ - elif os == 'Windows Vista (64 bits)': + elif os == "Windows Vista (64 bits)": _fields_ = _TEB_Vista_64._fields_ - elif os == 'Windows 7': + elif os == "Windows 7": _fields_ = _TEB_W7._fields_ - elif os == 'Windows 7 (64 bits)': + elif os == "Windows 7 (64 bits)": _fields_ = _TEB_W7_64._fields_ elif sizeof(SIZE_T) == sizeof(DWORD): _fields_ = _TEB_W7._fields_ else: _fields_ = _TEB_W7_64._fields_ + + PTEB = POINTER(TEB) -#============================================================================== +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/psapi.py b/pydevd_attach_to_process/winappdbg/win32/psapi.py index e353c7f7e..7cdf1bc23 100644 --- a/pydevd_attach_to_process/winappdbg/win32/psapi.py +++ b/pydevd_attach_to_process/winappdbg/win32/psapi.py @@ -36,18 +36,19 @@ from winappdbg.win32.defines import * -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== -#--- PSAPI structures and constants ------------------------------------------- +# --- PSAPI structures and constants ------------------------------------------- + +LIST_MODULES_DEFAULT = 0x00 +LIST_MODULES_32BIT = 0x01 +LIST_MODULES_64BIT = 0x02 +LIST_MODULES_ALL = 0x03 -LIST_MODULES_DEFAULT = 0x00 -LIST_MODULES_32BIT = 0x01 -LIST_MODULES_64BIT = 0x02 -LIST_MODULES_ALL = 0x03 # typedef struct _MODULEINFO { # LPVOID lpBaseOfDll; @@ -56,13 +57,16 @@ # } MODULEINFO, *LPMODULEINFO; class MODULEINFO(Structure): _fields_ = [ - ("lpBaseOfDll", LPVOID), # remote pointer - ("SizeOfImage", DWORD), - ("EntryPoint", LPVOID), # remote pointer -] + ("lpBaseOfDll", LPVOID), # remote pointer + ("SizeOfImage", DWORD), + ("EntryPoint", LPVOID), # remote pointer + ] + + LPMODULEINFO = POINTER(MODULEINFO) -#--- psapi.dll ---------------------------------------------------------------- +# --- psapi.dll ---------------------------------------------------------------- + # BOOL WINAPI EnumDeviceDrivers( # __out LPVOID *lpImageBase, @@ -75,9 +79,9 @@ def EnumDeviceDrivers(): _EnumDeviceDrivers.restype = bool _EnumDeviceDrivers.errcheck = RaiseIfZero - size = 0x1000 + size = 0x1000 lpcbNeeded = DWORD(size) - unit = sizeof(LPVOID) + unit = sizeof(LPVOID) while 1: lpImageBase = (LPVOID * (size // unit))() _EnumDeviceDrivers(byref(lpImageBase), lpcbNeeded, byref(lpcbNeeded)) @@ -85,7 +89,8 @@ def EnumDeviceDrivers(): if needed <= size: break size = needed - return [ lpImageBase[index] for index in compat.xrange(0, (needed // unit)) ] + return [lpImageBase[index] for index in compat.xrange(0, (needed // unit))] + # BOOL WINAPI EnumProcesses( # __out DWORD *pProcessIds, @@ -98,9 +103,9 @@ def EnumProcesses(): _EnumProcesses.restype = bool _EnumProcesses.errcheck = RaiseIfZero - size = 0x1000 + size = 0x1000 cbBytesReturned = DWORD() - unit = sizeof(DWORD) + unit = sizeof(DWORD) while 1: ProcessIds = (DWORD * (size // unit))() cbBytesReturned.value = size @@ -116,6 +121,7 @@ def EnumProcesses(): ProcessIdList.append(ProcessId) return ProcessIdList + # BOOL WINAPI EnumProcessModules( # __in HANDLE hProcess, # __out HMODULE *lphModule, @@ -138,7 +144,8 @@ def EnumProcessModules(hProcess): if needed <= size: break size = needed - return [ lphModule[index] for index in compat.xrange(0, int(needed // unit)) ] + return [lphModule[index] for index in compat.xrange(0, int(needed // unit))] + # BOOL WINAPI EnumProcessModulesEx( # __in HANDLE hProcess, @@ -147,7 +154,7 @@ def EnumProcessModules(hProcess): # __out LPDWORD lpcbNeeded, # __in DWORD dwFilterFlag # ); -def EnumProcessModulesEx(hProcess, dwFilterFlag = LIST_MODULES_DEFAULT): +def EnumProcessModulesEx(hProcess, dwFilterFlag=LIST_MODULES_DEFAULT): _EnumProcessModulesEx = windll.psapi.EnumProcessModulesEx _EnumProcessModulesEx.argtypes = [HANDLE, LPVOID, DWORD, LPDWORD, DWORD] _EnumProcessModulesEx.restype = bool @@ -163,7 +170,8 @@ def EnumProcessModulesEx(hProcess, dwFilterFlag = LIST_MODULES_DEFAULT): if needed <= size: break size = needed - return [ lphModule[index] for index in compat.xrange(0, (needed // unit)) ] + return [lphModule[index] for index in compat.xrange(0, (needed // unit))] + # DWORD WINAPI GetDeviceDriverBaseName( # __in LPVOID ImageBase, @@ -186,6 +194,7 @@ def GetDeviceDriverBaseNameA(ImageBase): nSize = nSize + MAX_PATH return lpBaseName.value + def GetDeviceDriverBaseNameW(ImageBase): _GetDeviceDriverBaseNameW = windll.psapi.GetDeviceDriverBaseNameW _GetDeviceDriverBaseNameW.argtypes = [LPVOID, LPWSTR, DWORD] @@ -193,7 +202,7 @@ def GetDeviceDriverBaseNameW(ImageBase): nSize = MAX_PATH while 1: - lpBaseName = ctypes.create_unicode_buffer(u"", nSize) + lpBaseName = ctypes.create_unicode_buffer("", nSize) nCopied = _GetDeviceDriverBaseNameW(ImageBase, lpBaseName, nSize) if nCopied == 0: raise ctypes.WinError() @@ -202,8 +211,10 @@ def GetDeviceDriverBaseNameW(ImageBase): nSize = nSize + MAX_PATH return lpBaseName.value + GetDeviceDriverBaseName = GuessStringType(GetDeviceDriverBaseNameA, GetDeviceDriverBaseNameW) + # DWORD WINAPI GetDeviceDriverFileName( # __in LPVOID ImageBase, # __out LPTSTR lpFilename, @@ -225,6 +236,7 @@ def GetDeviceDriverFileNameA(ImageBase): nSize = nSize + MAX_PATH return lpFilename.value + def GetDeviceDriverFileNameW(ImageBase): _GetDeviceDriverFileNameW = windll.psapi.GetDeviceDriverFileNameW _GetDeviceDriverFileNameW.argtypes = [LPVOID, LPWSTR, DWORD] @@ -232,7 +244,7 @@ def GetDeviceDriverFileNameW(ImageBase): nSize = MAX_PATH while 1: - lpFilename = ctypes.create_unicode_buffer(u"", nSize) + lpFilename = ctypes.create_unicode_buffer("", nSize) nCopied = ctypes.windll.psapi.GetDeviceDriverFileNameW(ImageBase, lpFilename, nSize) if nCopied == 0: raise ctypes.WinError() @@ -241,8 +253,10 @@ def GetDeviceDriverFileNameW(ImageBase): nSize = nSize + MAX_PATH return lpFilename.value + GetDeviceDriverFileName = GuessStringType(GetDeviceDriverFileNameA, GetDeviceDriverFileNameW) + # DWORD WINAPI GetMappedFileName( # __in HANDLE hProcess, # __in LPVOID lpv, @@ -265,6 +279,7 @@ def GetMappedFileNameA(hProcess, lpv): nSize = nSize + MAX_PATH return lpFilename.value + def GetMappedFileNameW(hProcess, lpv): _GetMappedFileNameW = ctypes.windll.psapi.GetMappedFileNameW _GetMappedFileNameW.argtypes = [HANDLE, LPVOID, LPWSTR, DWORD] @@ -272,7 +287,7 @@ def GetMappedFileNameW(hProcess, lpv): nSize = MAX_PATH while 1: - lpFilename = ctypes.create_unicode_buffer(u"", nSize) + lpFilename = ctypes.create_unicode_buffer("", nSize) nCopied = _GetMappedFileNameW(hProcess, lpv, lpFilename, nSize) if nCopied == 0: raise ctypes.WinError() @@ -281,15 +296,17 @@ def GetMappedFileNameW(hProcess, lpv): nSize = nSize + MAX_PATH return lpFilename.value + GetMappedFileName = GuessStringType(GetMappedFileNameA, GetMappedFileNameW) + # DWORD WINAPI GetModuleFileNameEx( # __in HANDLE hProcess, # __in_opt HMODULE hModule, # __out LPTSTR lpFilename, # __in DWORD nSize # ); -def GetModuleFileNameExA(hProcess, hModule = None): +def GetModuleFileNameExA(hProcess, hModule=None): _GetModuleFileNameExA = ctypes.windll.psapi.GetModuleFileNameExA _GetModuleFileNameExA.argtypes = [HANDLE, HMODULE, LPSTR, DWORD] _GetModuleFileNameExA.restype = DWORD @@ -305,14 +322,15 @@ def GetModuleFileNameExA(hProcess, hModule = None): nSize = nSize + MAX_PATH return lpFilename.value -def GetModuleFileNameExW(hProcess, hModule = None): + +def GetModuleFileNameExW(hProcess, hModule=None): _GetModuleFileNameExW = ctypes.windll.psapi.GetModuleFileNameExW _GetModuleFileNameExW.argtypes = [HANDLE, HMODULE, LPWSTR, DWORD] _GetModuleFileNameExW.restype = DWORD nSize = MAX_PATH while 1: - lpFilename = ctypes.create_unicode_buffer(u"", nSize) + lpFilename = ctypes.create_unicode_buffer("", nSize) nCopied = _GetModuleFileNameExW(hProcess, hModule, lpFilename, nSize) if nCopied == 0: raise ctypes.WinError() @@ -321,15 +339,17 @@ def GetModuleFileNameExW(hProcess, hModule = None): nSize = nSize + MAX_PATH return lpFilename.value + GetModuleFileNameEx = GuessStringType(GetModuleFileNameExA, GetModuleFileNameExW) + # BOOL WINAPI GetModuleInformation( # __in HANDLE hProcess, # __in HMODULE hModule, # __out LPMODULEINFO lpmodinfo, # __in DWORD cb # ); -def GetModuleInformation(hProcess, hModule, lpmodinfo = None): +def GetModuleInformation(hProcess, hModule, lpmodinfo=None): _GetModuleInformation = windll.psapi.GetModuleInformation _GetModuleInformation.argtypes = [HANDLE, HMODULE, LPMODULEINFO, DWORD] _GetModuleInformation.restype = bool @@ -340,6 +360,7 @@ def GetModuleInformation(hProcess, hModule, lpmodinfo = None): _GetModuleInformation(hProcess, hModule, byref(lpmodinfo), sizeof(lpmodinfo)) return lpmodinfo + # DWORD WINAPI GetProcessImageFileName( # __in HANDLE hProcess, # __out LPTSTR lpImageFileName, @@ -361,6 +382,7 @@ def GetProcessImageFileNameA(hProcess): nSize = nSize + MAX_PATH return lpFilename.value + def GetProcessImageFileNameW(hProcess): _GetProcessImageFileNameW = windll.psapi.GetProcessImageFileNameW _GetProcessImageFileNameW.argtypes = [HANDLE, LPWSTR, DWORD] @@ -368,7 +390,7 @@ def GetProcessImageFileNameW(hProcess): nSize = MAX_PATH while 1: - lpFilename = ctypes.create_unicode_buffer(u"", nSize) + lpFilename = ctypes.create_unicode_buffer("", nSize) nCopied = _GetProcessImageFileNameW(hProcess, lpFilename, nSize) if nCopied == 0: raise ctypes.WinError() @@ -377,11 +399,12 @@ def GetProcessImageFileNameW(hProcess): nSize = nSize + MAX_PATH return lpFilename.value + GetProcessImageFileName = GuessStringType(GetProcessImageFileNameA, GetProcessImageFileNameW) -#============================================================================== +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/shell32.py b/pydevd_attach_to_process/winappdbg/win32/shell32.py index 5c945db74..1447da738 100644 --- a/pydevd_attach_to_process/winappdbg/win32/shell32.py +++ b/pydevd_attach_to_process/winappdbg/win32/shell32.py @@ -41,118 +41,118 @@ from winappdbg.win32.defines import * from winappdbg.win32.kernel32 import LocalFree -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== - -#--- Constants ---------------------------------------------------------------- - -SEE_MASK_DEFAULT = 0x00000000 -SEE_MASK_CLASSNAME = 0x00000001 -SEE_MASK_CLASSKEY = 0x00000003 -SEE_MASK_IDLIST = 0x00000004 -SEE_MASK_INVOKEIDLIST = 0x0000000C -SEE_MASK_ICON = 0x00000010 -SEE_MASK_HOTKEY = 0x00000020 -SEE_MASK_NOCLOSEPROCESS = 0x00000040 -SEE_MASK_CONNECTNETDRV = 0x00000080 -SEE_MASK_NOASYNC = 0x00000100 -SEE_MASK_DOENVSUBST = 0x00000200 -SEE_MASK_FLAG_NO_UI = 0x00000400 -SEE_MASK_UNICODE = 0x00004000 -SEE_MASK_NO_CONSOLE = 0x00008000 -SEE_MASK_ASYNCOK = 0x00100000 -SEE_MASK_HMONITOR = 0x00200000 -SEE_MASK_NOZONECHECKS = 0x00800000 -SEE_MASK_WAITFORINPUTIDLE = 0x02000000 -SEE_MASK_FLAG_LOG_USAGE = 0x04000000 - -SE_ERR_FNF = 2 -SE_ERR_PNF = 3 -SE_ERR_ACCESSDENIED = 5 -SE_ERR_OOM = 8 -SE_ERR_DLLNOTFOUND = 32 -SE_ERR_SHARE = 26 -SE_ERR_ASSOCINCOMPLETE = 27 -SE_ERR_DDETIMEOUT = 28 -SE_ERR_DDEFAIL = 29 -SE_ERR_DDEBUSY = 30 -SE_ERR_NOASSOC = 31 +# ============================================================================== + +# --- Constants ---------------------------------------------------------------- + +SEE_MASK_DEFAULT = 0x00000000 +SEE_MASK_CLASSNAME = 0x00000001 +SEE_MASK_CLASSKEY = 0x00000003 +SEE_MASK_IDLIST = 0x00000004 +SEE_MASK_INVOKEIDLIST = 0x0000000C +SEE_MASK_ICON = 0x00000010 +SEE_MASK_HOTKEY = 0x00000020 +SEE_MASK_NOCLOSEPROCESS = 0x00000040 +SEE_MASK_CONNECTNETDRV = 0x00000080 +SEE_MASK_NOASYNC = 0x00000100 +SEE_MASK_DOENVSUBST = 0x00000200 +SEE_MASK_FLAG_NO_UI = 0x00000400 +SEE_MASK_UNICODE = 0x00004000 +SEE_MASK_NO_CONSOLE = 0x00008000 +SEE_MASK_ASYNCOK = 0x00100000 +SEE_MASK_HMONITOR = 0x00200000 +SEE_MASK_NOZONECHECKS = 0x00800000 +SEE_MASK_WAITFORINPUTIDLE = 0x02000000 +SEE_MASK_FLAG_LOG_USAGE = 0x04000000 + +SE_ERR_FNF = 2 +SE_ERR_PNF = 3 +SE_ERR_ACCESSDENIED = 5 +SE_ERR_OOM = 8 +SE_ERR_DLLNOTFOUND = 32 +SE_ERR_SHARE = 26 +SE_ERR_ASSOCINCOMPLETE = 27 +SE_ERR_DDETIMEOUT = 28 +SE_ERR_DDEFAIL = 29 +SE_ERR_DDEBUSY = 30 +SE_ERR_NOASSOC = 31 SHGFP_TYPE_CURRENT = 0 SHGFP_TYPE_DEFAULT = 1 -CSIDL_DESKTOP = 0x0000 -CSIDL_INTERNET = 0x0001 -CSIDL_PROGRAMS = 0x0002 -CSIDL_CONTROLS = 0x0003 -CSIDL_PRINTERS = 0x0004 -CSIDL_PERSONAL = 0x0005 -CSIDL_FAVORITES = 0x0006 -CSIDL_STARTUP = 0x0007 -CSIDL_RECENT = 0x0008 -CSIDL_SENDTO = 0x0009 -CSIDL_BITBUCKET = 0x000a -CSIDL_STARTMENU = 0x000b -CSIDL_MYDOCUMENTS = CSIDL_PERSONAL -CSIDL_MYMUSIC = 0x000d -CSIDL_MYVIDEO = 0x000e -CSIDL_DESKTOPDIRECTORY = 0x0010 -CSIDL_DRIVES = 0x0011 -CSIDL_NETWORK = 0x0012 -CSIDL_NETHOOD = 0x0013 -CSIDL_FONTS = 0x0014 -CSIDL_TEMPLATES = 0x0015 -CSIDL_COMMON_STARTMENU = 0x0016 -CSIDL_COMMON_PROGRAMS = 0x0017 -CSIDL_COMMON_STARTUP = 0x0018 -CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019 -CSIDL_APPDATA = 0x001a -CSIDL_PRINTHOOD = 0x001b -CSIDL_LOCAL_APPDATA = 0x001c -CSIDL_ALTSTARTUP = 0x001d -CSIDL_COMMON_ALTSTARTUP = 0x001e -CSIDL_COMMON_FAVORITES = 0x001f -CSIDL_INTERNET_CACHE = 0x0020 -CSIDL_COOKIES = 0x0021 -CSIDL_HISTORY = 0x0022 -CSIDL_COMMON_APPDATA = 0x0023 -CSIDL_WINDOWS = 0x0024 -CSIDL_SYSTEM = 0x0025 -CSIDL_PROGRAM_FILES = 0x0026 -CSIDL_MYPICTURES = 0x0027 -CSIDL_PROFILE = 0x0028 -CSIDL_SYSTEMX86 = 0x0029 -CSIDL_PROGRAM_FILESX86 = 0x002a -CSIDL_PROGRAM_FILES_COMMON = 0x002b -CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c -CSIDL_COMMON_TEMPLATES = 0x002d -CSIDL_COMMON_DOCUMENTS = 0x002e -CSIDL_COMMON_ADMINTOOLS = 0x002f -CSIDL_ADMINTOOLS = 0x0030 -CSIDL_CONNECTIONS = 0x0031 -CSIDL_COMMON_MUSIC = 0x0035 -CSIDL_COMMON_PICTURES = 0x0036 -CSIDL_COMMON_VIDEO = 0x0037 -CSIDL_RESOURCES = 0x0038 -CSIDL_RESOURCES_LOCALIZED = 0x0039 -CSIDL_COMMON_OEM_LINKS = 0x003a -CSIDL_CDBURN_AREA = 0x003b -CSIDL_COMPUTERSNEARME = 0x003d -CSIDL_PROFILES = 0x003e - -CSIDL_FOLDER_MASK = 0x00ff - -CSIDL_FLAG_PER_USER_INIT = 0x0800 -CSIDL_FLAG_NO_ALIAS = 0x1000 -CSIDL_FLAG_DONT_VERIFY = 0x4000 -CSIDL_FLAG_CREATE = 0x8000 - -CSIDL_FLAG_MASK = 0xff00 - -#--- Structures --------------------------------------------------------------- +CSIDL_DESKTOP = 0x0000 +CSIDL_INTERNET = 0x0001 +CSIDL_PROGRAMS = 0x0002 +CSIDL_CONTROLS = 0x0003 +CSIDL_PRINTERS = 0x0004 +CSIDL_PERSONAL = 0x0005 +CSIDL_FAVORITES = 0x0006 +CSIDL_STARTUP = 0x0007 +CSIDL_RECENT = 0x0008 +CSIDL_SENDTO = 0x0009 +CSIDL_BITBUCKET = 0x000A +CSIDL_STARTMENU = 0x000B +CSIDL_MYDOCUMENTS = CSIDL_PERSONAL +CSIDL_MYMUSIC = 0x000D +CSIDL_MYVIDEO = 0x000E +CSIDL_DESKTOPDIRECTORY = 0x0010 +CSIDL_DRIVES = 0x0011 +CSIDL_NETWORK = 0x0012 +CSIDL_NETHOOD = 0x0013 +CSIDL_FONTS = 0x0014 +CSIDL_TEMPLATES = 0x0015 +CSIDL_COMMON_STARTMENU = 0x0016 +CSIDL_COMMON_PROGRAMS = 0x0017 +CSIDL_COMMON_STARTUP = 0x0018 +CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019 +CSIDL_APPDATA = 0x001A +CSIDL_PRINTHOOD = 0x001B +CSIDL_LOCAL_APPDATA = 0x001C +CSIDL_ALTSTARTUP = 0x001D +CSIDL_COMMON_ALTSTARTUP = 0x001E +CSIDL_COMMON_FAVORITES = 0x001F +CSIDL_INTERNET_CACHE = 0x0020 +CSIDL_COOKIES = 0x0021 +CSIDL_HISTORY = 0x0022 +CSIDL_COMMON_APPDATA = 0x0023 +CSIDL_WINDOWS = 0x0024 +CSIDL_SYSTEM = 0x0025 +CSIDL_PROGRAM_FILES = 0x0026 +CSIDL_MYPICTURES = 0x0027 +CSIDL_PROFILE = 0x0028 +CSIDL_SYSTEMX86 = 0x0029 +CSIDL_PROGRAM_FILESX86 = 0x002A +CSIDL_PROGRAM_FILES_COMMON = 0x002B +CSIDL_PROGRAM_FILES_COMMONX86 = 0x002C +CSIDL_COMMON_TEMPLATES = 0x002D +CSIDL_COMMON_DOCUMENTS = 0x002E +CSIDL_COMMON_ADMINTOOLS = 0x002F +CSIDL_ADMINTOOLS = 0x0030 +CSIDL_CONNECTIONS = 0x0031 +CSIDL_COMMON_MUSIC = 0x0035 +CSIDL_COMMON_PICTURES = 0x0036 +CSIDL_COMMON_VIDEO = 0x0037 +CSIDL_RESOURCES = 0x0038 +CSIDL_RESOURCES_LOCALIZED = 0x0039 +CSIDL_COMMON_OEM_LINKS = 0x003A +CSIDL_CDBURN_AREA = 0x003B +CSIDL_COMPUTERSNEARME = 0x003D +CSIDL_PROFILES = 0x003E + +CSIDL_FOLDER_MASK = 0x00FF + +CSIDL_FLAG_PER_USER_INIT = 0x0800 +CSIDL_FLAG_NO_ALIAS = 0x1000 +CSIDL_FLAG_DONT_VERIFY = 0x4000 +CSIDL_FLAG_CREATE = 0x8000 + +CSIDL_FLAG_MASK = 0xFF00 + +# --- Structures --------------------------------------------------------------- # typedef struct _SHELLEXECUTEINFO { # DWORD cbSize; @@ -175,34 +175,39 @@ # HANDLE hProcess; # } SHELLEXECUTEINFO, *LPSHELLEXECUTEINFO; + class SHELLEXECUTEINFO(Structure): _fields_ = [ - ("cbSize", DWORD), - ("fMask", ULONG), - ("hwnd", HWND), - ("lpVerb", LPSTR), - ("lpFile", LPSTR), + ("cbSize", DWORD), + ("fMask", ULONG), + ("hwnd", HWND), + ("lpVerb", LPSTR), + ("lpFile", LPSTR), ("lpParameters", LPSTR), - ("lpDirectory", LPSTR), - ("nShow", ctypes.c_int), - ("hInstApp", HINSTANCE), - ("lpIDList", LPVOID), - ("lpClass", LPSTR), - ("hkeyClass", HKEY), - ("dwHotKey", DWORD), - ("hIcon", HANDLE), - ("hProcess", HANDLE), + ("lpDirectory", LPSTR), + ("nShow", ctypes.c_int), + ("hInstApp", HINSTANCE), + ("lpIDList", LPVOID), + ("lpClass", LPSTR), + ("hkeyClass", HKEY), + ("dwHotKey", DWORD), + ("hIcon", HANDLE), + ("hProcess", HANDLE), ] def __get_hMonitor(self): return self.hIcon + def __set_hMonitor(self, hMonitor): self.hIcon = hMonitor + hMonitor = property(__get_hMonitor, __set_hMonitor) + LPSHELLEXECUTEINFO = POINTER(SHELLEXECUTEINFO) -#--- shell32.dll -------------------------------------------------------------- +# --- shell32.dll -------------------------------------------------------------- + # LPWSTR *CommandLineToArgvW( # LPCWSTR lpCmdLine, @@ -211,7 +216,7 @@ def __set_hMonitor(self, hMonitor): def CommandLineToArgvW(lpCmdLine): _CommandLineToArgvW = windll.shell32.CommandLineToArgvW _CommandLineToArgvW.argtypes = [LPVOID, POINTER(ctypes.c_int)] - _CommandLineToArgvW.restype = LPVOID + _CommandLineToArgvW.restype = LPVOID if not lpCmdLine: lpCmdLine = None @@ -224,13 +229,14 @@ def CommandLineToArgvW(lpCmdLine): argc = argc.value if argc <= 0: raise ctypes.WinError() - argv = ctypes.cast(argv, ctypes.POINTER(LPWSTR * argc) ) - argv = [ argv.contents[i] for i in compat.xrange(0, argc) ] + argv = ctypes.cast(argv, ctypes.POINTER(LPWSTR * argc)) + argv = [argv.contents[i] for i in compat.xrange(0, argc)] finally: if vptr is not None: LocalFree(vptr) return argv + def CommandLineToArgvA(lpCmdLine): t_ansi = GuessStringType.t_ansi t_unicode = GuessStringType.t_unicode @@ -240,8 +246,10 @@ def CommandLineToArgvA(lpCmdLine): cmdline = lpCmdLine return [t_ansi(x) for x in CommandLineToArgvW(cmdline)] + CommandLineToArgv = GuessStringType(CommandLineToArgvA, CommandLineToArgvW) + # HINSTANCE ShellExecute( # HWND hwnd, # LPCTSTR lpOperation, @@ -250,34 +258,37 @@ def CommandLineToArgvA(lpCmdLine): # LPCTSTR lpDirectory, # INT nShowCmd # ); -def ShellExecuteA(hwnd = None, lpOperation = None, lpFile = None, lpParameters = None, lpDirectory = None, nShowCmd = None): +def ShellExecuteA(hwnd=None, lpOperation=None, lpFile=None, lpParameters=None, lpDirectory=None, nShowCmd=None): _ShellExecuteA = windll.shell32.ShellExecuteA _ShellExecuteA.argtypes = [HWND, LPSTR, LPSTR, LPSTR, LPSTR, INT] - _ShellExecuteA.restype = HINSTANCE + _ShellExecuteA.restype = HINSTANCE if not nShowCmd: nShowCmd = 0 success = _ShellExecuteA(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd) success = ctypes.cast(success, c_int) success = success.value - if not success > 32: # weird! isn't it? + if not success > 32: # weird! isn't it? raise ctypes.WinError(success) -def ShellExecuteW(hwnd = None, lpOperation = None, lpFile = None, lpParameters = None, lpDirectory = None, nShowCmd = None): + +def ShellExecuteW(hwnd=None, lpOperation=None, lpFile=None, lpParameters=None, lpDirectory=None, nShowCmd=None): _ShellExecuteW = windll.shell32.ShellExecuteW _ShellExecuteW.argtypes = [HWND, LPWSTR, LPWSTR, LPWSTR, LPWSTR, INT] - _ShellExecuteW.restype = HINSTANCE + _ShellExecuteW.restype = HINSTANCE if not nShowCmd: nShowCmd = 0 success = _ShellExecuteW(hwnd, lpOperation, lpFile, lpParameters, lpDirectory, nShowCmd) success = ctypes.cast(success, c_int) success = success.value - if not success > 32: # weird! isn't it? + if not success > 32: # weird! isn't it? raise ctypes.WinError(success) + ShellExecute = GuessStringType(ShellExecuteA, ShellExecuteW) + # BOOL ShellExecuteEx( # __inout LPSHELLEXECUTEINFO lpExecInfo # ); @@ -289,53 +300,59 @@ def ShellExecuteEx(lpExecInfo): else: raise TypeError("Expected SHELLEXECUTEINFOA or SHELLEXECUTEINFOW, got %s instead" % type(lpExecInfo)) + def ShellExecuteExA(lpExecInfo): _ShellExecuteExA = windll.shell32.ShellExecuteExA _ShellExecuteExA.argtypes = [LPSHELLEXECUTEINFOA] - _ShellExecuteExA.restype = BOOL + _ShellExecuteExA.restype = BOOL _ShellExecuteExA.errcheck = RaiseIfZero _ShellExecuteExA(byref(lpExecInfo)) + def ShellExecuteExW(lpExecInfo): _ShellExecuteExW = windll.shell32.ShellExecuteExW _ShellExecuteExW.argtypes = [LPSHELLEXECUTEINFOW] - _ShellExecuteExW.restype = BOOL + _ShellExecuteExW.restype = BOOL _ShellExecuteExW.errcheck = RaiseIfZero _ShellExecuteExW(byref(lpExecInfo)) + # HINSTANCE FindExecutable( # __in LPCTSTR lpFile, # __in_opt LPCTSTR lpDirectory, # __out LPTSTR lpResult # ); -def FindExecutableA(lpFile, lpDirectory = None): +def FindExecutableA(lpFile, lpDirectory=None): _FindExecutableA = windll.shell32.FindExecutableA _FindExecutableA.argtypes = [LPSTR, LPSTR, LPSTR] - _FindExecutableA.restype = HINSTANCE + _FindExecutableA.restype = HINSTANCE lpResult = ctypes.create_string_buffer(MAX_PATH) success = _FindExecutableA(lpFile, lpDirectory, lpResult) success = ctypes.cast(success, ctypes.c_void_p) success = success.value - if not success > 32: # weird! isn't it? + if not success > 32: # weird! isn't it? raise ctypes.WinError(success) return lpResult.value -def FindExecutableW(lpFile, lpDirectory = None): + +def FindExecutableW(lpFile, lpDirectory=None): _FindExecutableW = windll.shell32.FindExecutableW _FindExecutableW.argtypes = [LPWSTR, LPWSTR, LPWSTR] - _FindExecutableW.restype = HINSTANCE + _FindExecutableW.restype = HINSTANCE lpResult = ctypes.create_unicode_buffer(MAX_PATH) success = _FindExecutableW(lpFile, lpDirectory, lpResult) success = ctypes.cast(success, ctypes.c_void_p) success = success.value - if not success > 32: # weird! isn't it? + if not success > 32: # weird! isn't it? raise ctypes.WinError(success) return lpResult.value + FindExecutable = GuessStringType(FindExecutableA, FindExecutableW) + # HRESULT SHGetFolderPath( # __in HWND hwndOwner, # __in int nFolder, @@ -343,40 +360,44 @@ def FindExecutableW(lpFile, lpDirectory = None): # __in DWORD dwFlags, # __out LPTSTR pszPath # ); -def SHGetFolderPathA(nFolder, hToken = None, dwFlags = SHGFP_TYPE_CURRENT): - _SHGetFolderPathA = windll.shell32.SHGetFolderPathA # shfolder.dll in older win versions +def SHGetFolderPathA(nFolder, hToken=None, dwFlags=SHGFP_TYPE_CURRENT): + _SHGetFolderPathA = windll.shell32.SHGetFolderPathA # shfolder.dll in older win versions _SHGetFolderPathA.argtypes = [HWND, ctypes.c_int, HANDLE, DWORD, LPSTR] - _SHGetFolderPathA.restype = HRESULT - _SHGetFolderPathA.errcheck = RaiseIfNotZero # S_OK == 0 + _SHGetFolderPathA.restype = HRESULT + _SHGetFolderPathA.errcheck = RaiseIfNotZero # S_OK == 0 pszPath = ctypes.create_string_buffer(MAX_PATH + 1) _SHGetFolderPathA(None, nFolder, hToken, dwFlags, pszPath) return pszPath.value -def SHGetFolderPathW(nFolder, hToken = None, dwFlags = SHGFP_TYPE_CURRENT): - _SHGetFolderPathW = windll.shell32.SHGetFolderPathW # shfolder.dll in older win versions + +def SHGetFolderPathW(nFolder, hToken=None, dwFlags=SHGFP_TYPE_CURRENT): + _SHGetFolderPathW = windll.shell32.SHGetFolderPathW # shfolder.dll in older win versions _SHGetFolderPathW.argtypes = [HWND, ctypes.c_int, HANDLE, DWORD, LPWSTR] - _SHGetFolderPathW.restype = HRESULT - _SHGetFolderPathW.errcheck = RaiseIfNotZero # S_OK == 0 + _SHGetFolderPathW.restype = HRESULT + _SHGetFolderPathW.errcheck = RaiseIfNotZero # S_OK == 0 pszPath = ctypes.create_unicode_buffer(MAX_PATH + 1) _SHGetFolderPathW(None, nFolder, hToken, dwFlags, pszPath) return pszPath.value + SHGetFolderPath = DefaultStringType(SHGetFolderPathA, SHGetFolderPathW) + # BOOL IsUserAnAdmin(void); def IsUserAnAdmin(): # Supposedly, IsUserAnAdmin() is deprecated in Vista. # But I tried it on Windows 7 and it works just fine. _IsUserAnAdmin = windll.shell32.IsUserAnAdmin _IsUserAnAdmin.argtypes = [] - _IsUserAnAdmin.restype = bool + _IsUserAnAdmin.restype = bool return _IsUserAnAdmin() -#============================================================================== + +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/shlwapi.py b/pydevd_attach_to_process/winappdbg/win32/shlwapi.py index 5f6eb3eab..43dfcb5e6 100644 --- a/pydevd_attach_to_process/winappdbg/win32/shlwapi.py +++ b/pydevd_attach_to_process/winappdbg/win32/shlwapi.py @@ -37,50 +37,51 @@ from winappdbg.win32.defines import * from winappdbg.win32.kernel32 import * -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== - -OS_WINDOWS = 0 -OS_NT = 1 -OS_WIN95ORGREATER = 2 -OS_NT4ORGREATER = 3 -OS_WIN98ORGREATER = 5 -OS_WIN98_GOLD = 6 -OS_WIN2000ORGREATER = 7 -OS_WIN2000PRO = 8 -OS_WIN2000SERVER = 9 -OS_WIN2000ADVSERVER = 10 -OS_WIN2000DATACENTER = 11 -OS_WIN2000TERMINAL = 12 -OS_EMBEDDED = 13 -OS_TERMINALCLIENT = 14 -OS_TERMINALREMOTEADMIN = 15 -OS_WIN95_GOLD = 16 -OS_MEORGREATER = 17 -OS_XPORGREATER = 18 -OS_HOME = 19 -OS_PROFESSIONAL = 20 -OS_DATACENTER = 21 -OS_ADVSERVER = 22 -OS_SERVER = 23 -OS_TERMINALSERVER = 24 -OS_PERSONALTERMINALSERVER = 25 -OS_FASTUSERSWITCHING = 26 -OS_WELCOMELOGONUI = 27 -OS_DOMAINMEMBER = 28 -OS_ANYSERVER = 29 -OS_WOW6432 = 30 -OS_WEBSERVER = 31 -OS_SMALLBUSINESSSERVER = 32 -OS_TABLETPC = 33 -OS_SERVERADMINUI = 34 -OS_MEDIACENTER = 35 -OS_APPLIANCE = 36 - -#--- shlwapi.dll -------------------------------------------------------------- +# ============================================================================== + +OS_WINDOWS = 0 +OS_NT = 1 +OS_WIN95ORGREATER = 2 +OS_NT4ORGREATER = 3 +OS_WIN98ORGREATER = 5 +OS_WIN98_GOLD = 6 +OS_WIN2000ORGREATER = 7 +OS_WIN2000PRO = 8 +OS_WIN2000SERVER = 9 +OS_WIN2000ADVSERVER = 10 +OS_WIN2000DATACENTER = 11 +OS_WIN2000TERMINAL = 12 +OS_EMBEDDED = 13 +OS_TERMINALCLIENT = 14 +OS_TERMINALREMOTEADMIN = 15 +OS_WIN95_GOLD = 16 +OS_MEORGREATER = 17 +OS_XPORGREATER = 18 +OS_HOME = 19 +OS_PROFESSIONAL = 20 +OS_DATACENTER = 21 +OS_ADVSERVER = 22 +OS_SERVER = 23 +OS_TERMINALSERVER = 24 +OS_PERSONALTERMINALSERVER = 25 +OS_FASTUSERSWITCHING = 26 +OS_WELCOMELOGONUI = 27 +OS_DOMAINMEMBER = 28 +OS_ANYSERVER = 29 +OS_WOW6432 = 30 +OS_WEBSERVER = 31 +OS_SMALLBUSINESSSERVER = 32 +OS_TABLETPC = 33 +OS_SERVERADMINUI = 34 +OS_MEDIACENTER = 35 +OS_APPLIANCE = 36 + +# --- shlwapi.dll -------------------------------------------------------------- + # BOOL IsOS( # DWORD dwOS @@ -89,25 +90,26 @@ def IsOS(dwOS): try: _IsOS = windll.shlwapi.IsOS _IsOS.argtypes = [DWORD] - _IsOS.restype = bool + _IsOS.restype = bool except AttributeError: # According to MSDN, on Windows versions prior to Vista # this function is exported only by ordinal number 437. # http://msdn.microsoft.com/en-us/library/bb773795%28VS.85%29.aspx _GetProcAddress = windll.kernel32.GetProcAddress _GetProcAddress.argtypes = [HINSTANCE, DWORD] - _GetProcAddress.restype = LPVOID + _GetProcAddress.restype = LPVOID _IsOS = windll.kernel32.GetProcAddress(windll.shlwapi._handle, 437) _IsOS = WINFUNCTYPE(bool, DWORD)(_IsOS) return _IsOS(dwOS) + # LPTSTR PathAddBackslash( # LPTSTR lpszPath # ); def PathAddBackslashA(lpszPath): _PathAddBackslashA = windll.shlwapi.PathAddBackslashA _PathAddBackslashA.argtypes = [LPSTR] - _PathAddBackslashA.restype = LPSTR + _PathAddBackslashA.restype = LPSTR lpszPath = ctypes.create_string_buffer(lpszPath, MAX_PATH) retval = _PathAddBackslashA(lpszPath) @@ -115,10 +117,11 @@ def PathAddBackslashA(lpszPath): raise ctypes.WinError() return lpszPath.value + def PathAddBackslashW(lpszPath): _PathAddBackslashW = windll.shlwapi.PathAddBackslashW _PathAddBackslashW.argtypes = [LPWSTR] - _PathAddBackslashW.restype = LPWSTR + _PathAddBackslashW.restype = LPWSTR lpszPath = ctypes.create_unicode_buffer(lpszPath, MAX_PATH) retval = _PathAddBackslashW(lpszPath) @@ -126,16 +129,18 @@ def PathAddBackslashW(lpszPath): raise ctypes.WinError() return lpszPath.value + PathAddBackslash = GuessStringType(PathAddBackslashA, PathAddBackslashW) + # BOOL PathAddExtension( # LPTSTR pszPath, # LPCTSTR pszExtension # ); -def PathAddExtensionA(lpszPath, pszExtension = None): +def PathAddExtensionA(lpszPath, pszExtension=None): _PathAddExtensionA = windll.shlwapi.PathAddExtensionA _PathAddExtensionA.argtypes = [LPSTR, LPSTR] - _PathAddExtensionA.restype = bool + _PathAddExtensionA.restype = bool _PathAddExtensionA.errcheck = RaiseIfZero if not pszExtension: @@ -144,10 +149,11 @@ def PathAddExtensionA(lpszPath, pszExtension = None): _PathAddExtensionA(lpszPath, pszExtension) return lpszPath.value -def PathAddExtensionW(lpszPath, pszExtension = None): + +def PathAddExtensionW(lpszPath, pszExtension=None): _PathAddExtensionW = windll.shlwapi.PathAddExtensionW _PathAddExtensionW.argtypes = [LPWSTR, LPWSTR] - _PathAddExtensionW.restype = bool + _PathAddExtensionW.restype = bool _PathAddExtensionW.errcheck = RaiseIfZero if not pszExtension: @@ -156,16 +162,18 @@ def PathAddExtensionW(lpszPath, pszExtension = None): _PathAddExtensionW(lpszPath, pszExtension) return lpszPath.value + PathAddExtension = GuessStringType(PathAddExtensionA, PathAddExtensionW) + # BOOL PathAppend( # LPTSTR pszPath, # LPCTSTR pszMore # ); -def PathAppendA(lpszPath, pszMore = None): +def PathAppendA(lpszPath, pszMore=None): _PathAppendA = windll.shlwapi.PathAppendA _PathAppendA.argtypes = [LPSTR, LPSTR] - _PathAppendA.restype = bool + _PathAppendA.restype = bool _PathAppendA.errcheck = RaiseIfZero if not pszMore: @@ -174,10 +182,11 @@ def PathAppendA(lpszPath, pszMore = None): _PathAppendA(lpszPath, pszMore) return lpszPath.value -def PathAppendW(lpszPath, pszMore = None): + +def PathAppendW(lpszPath, pszMore=None): _PathAppendW = windll.shlwapi.PathAppendW _PathAppendW.argtypes = [LPWSTR, LPWSTR] - _PathAppendW.restype = bool + _PathAppendW.restype = bool _PathAppendW.errcheck = RaiseIfZero if not pszMore: @@ -186,8 +195,10 @@ def PathAppendW(lpszPath, pszMore = None): _PathAppendW(lpszPath, pszMore) return lpszPath.value + PathAppend = GuessStringType(PathAppendA, PathAppendW) + # LPTSTR PathCombine( # LPTSTR lpszDest, # LPCTSTR lpszDir, @@ -196,7 +207,7 @@ def PathAppendW(lpszPath, pszMore = None): def PathCombineA(lpszDir, lpszFile): _PathCombineA = windll.shlwapi.PathCombineA _PathCombineA.argtypes = [LPSTR, LPSTR, LPSTR] - _PathCombineA.restype = LPSTR + _PathCombineA.restype = LPSTR lpszDest = ctypes.create_string_buffer("", max(MAX_PATH, len(lpszDir) + len(lpszFile) + 1)) retval = _PathCombineA(lpszDest, lpszDir, lpszFile) @@ -204,19 +215,22 @@ def PathCombineA(lpszDir, lpszFile): return None return lpszDest.value + def PathCombineW(lpszDir, lpszFile): _PathCombineW = windll.shlwapi.PathCombineW _PathCombineW.argtypes = [LPWSTR, LPWSTR, LPWSTR] - _PathCombineW.restype = LPWSTR + _PathCombineW.restype = LPWSTR - lpszDest = ctypes.create_unicode_buffer(u"", max(MAX_PATH, len(lpszDir) + len(lpszFile) + 1)) + lpszDest = ctypes.create_unicode_buffer("", max(MAX_PATH, len(lpszDir) + len(lpszFile) + 1)) retval = _PathCombineW(lpszDest, lpszDir, lpszFile) if retval == NULL: return None return lpszDest.value + PathCombine = GuessStringType(PathCombineA, PathCombineW) + # BOOL PathCanonicalize( # LPTSTR lpszDst, # LPCTSTR lpszSrc @@ -224,25 +238,28 @@ def PathCombineW(lpszDir, lpszFile): def PathCanonicalizeA(lpszSrc): _PathCanonicalizeA = windll.shlwapi.PathCanonicalizeA _PathCanonicalizeA.argtypes = [LPSTR, LPSTR] - _PathCanonicalizeA.restype = bool + _PathCanonicalizeA.restype = bool _PathCanonicalizeA.errcheck = RaiseIfZero lpszDst = ctypes.create_string_buffer("", MAX_PATH) _PathCanonicalizeA(lpszDst, lpszSrc) return lpszDst.value + def PathCanonicalizeW(lpszSrc): _PathCanonicalizeW = windll.shlwapi.PathCanonicalizeW _PathCanonicalizeW.argtypes = [LPWSTR, LPWSTR] - _PathCanonicalizeW.restype = bool + _PathCanonicalizeW.restype = bool _PathCanonicalizeW.errcheck = RaiseIfZero - lpszDst = ctypes.create_unicode_buffer(u"", MAX_PATH) + lpszDst = ctypes.create_unicode_buffer("", MAX_PATH) _PathCanonicalizeW(lpszDst, lpszSrc) return lpszDst.value + PathCanonicalize = GuessStringType(PathCanonicalizeA, PathCanonicalizeW) + # BOOL PathRelativePathTo( # _Out_ LPTSTR pszPath, # _In_ LPCTSTR pszFrom, @@ -250,10 +267,10 @@ def PathCanonicalizeW(lpszSrc): # _In_ LPCTSTR pszTo, # _In_ DWORD dwAttrTo # ); -def PathRelativePathToA(pszFrom = None, dwAttrFrom = FILE_ATTRIBUTE_DIRECTORY, pszTo = None, dwAttrTo = FILE_ATTRIBUTE_DIRECTORY): +def PathRelativePathToA(pszFrom=None, dwAttrFrom=FILE_ATTRIBUTE_DIRECTORY, pszTo=None, dwAttrTo=FILE_ATTRIBUTE_DIRECTORY): _PathRelativePathToA = windll.shlwapi.PathRelativePathToA _PathRelativePathToA.argtypes = [LPSTR, LPSTR, DWORD, LPSTR, DWORD] - _PathRelativePathToA.restype = bool + _PathRelativePathToA.restype = bool _PathRelativePathToA.errcheck = RaiseIfZero # Make the paths absolute or the function fails. @@ -269,7 +286,7 @@ def PathRelativePathToA(pszFrom = None, dwAttrFrom = FILE_ATTRIBUTE_DIRECTORY, p # Argh, this function doesn't receive an output buffer size! # We'll try to guess the maximum possible buffer size. dwPath = max((len(pszFrom) + len(pszTo)) * 2 + 1, MAX_PATH + 1) - pszPath = ctypes.create_string_buffer('', dwPath) + pszPath = ctypes.create_string_buffer("", dwPath) # Also, it doesn't set the last error value. # Whoever coded it must have been drunk or tripping on acid. Or both. @@ -280,10 +297,11 @@ def PathRelativePathToA(pszFrom = None, dwAttrFrom = FILE_ATTRIBUTE_DIRECTORY, p _PathRelativePathToA(pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo) return pszPath.value -def PathRelativePathToW(pszFrom = None, dwAttrFrom = FILE_ATTRIBUTE_DIRECTORY, pszTo = None, dwAttrTo = FILE_ATTRIBUTE_DIRECTORY): + +def PathRelativePathToW(pszFrom=None, dwAttrFrom=FILE_ATTRIBUTE_DIRECTORY, pszTo=None, dwAttrTo=FILE_ATTRIBUTE_DIRECTORY): _PathRelativePathToW = windll.shlwapi.PathRelativePathToW _PathRelativePathToW.argtypes = [LPWSTR, LPWSTR, DWORD, LPWSTR, DWORD] - _PathRelativePathToW.restype = bool + _PathRelativePathToW.restype = bool _PathRelativePathToW.errcheck = RaiseIfZero # Refer to PathRelativePathToA to know why this code is so ugly. @@ -296,95 +314,109 @@ def PathRelativePathToW(pszFrom = None, dwAttrFrom = FILE_ATTRIBUTE_DIRECTORY, p else: pszTo = GetCurrentDirectoryW() dwPath = max((len(pszFrom) + len(pszTo)) * 2 + 1, MAX_PATH + 1) - pszPath = ctypes.create_unicode_buffer(u'', dwPath) + pszPath = ctypes.create_unicode_buffer("", dwPath) SetLastError(ERROR_INVALID_PARAMETER) _PathRelativePathToW(pszPath, pszFrom, dwAttrFrom, pszTo, dwAttrTo) return pszPath.value + PathRelativePathTo = GuessStringType(PathRelativePathToA, PathRelativePathToW) + # BOOL PathFileExists( # LPCTSTR pszPath # ); def PathFileExistsA(pszPath): _PathFileExistsA = windll.shlwapi.PathFileExistsA _PathFileExistsA.argtypes = [LPSTR] - _PathFileExistsA.restype = bool + _PathFileExistsA.restype = bool return _PathFileExistsA(pszPath) + def PathFileExistsW(pszPath): _PathFileExistsW = windll.shlwapi.PathFileExistsW _PathFileExistsW.argtypes = [LPWSTR] - _PathFileExistsW.restype = bool + _PathFileExistsW.restype = bool return _PathFileExistsW(pszPath) + PathFileExists = GuessStringType(PathFileExistsA, PathFileExistsW) + # LPTSTR PathFindExtension( # LPCTSTR pszPath # ); def PathFindExtensionA(pszPath): _PathFindExtensionA = windll.shlwapi.PathFindExtensionA _PathFindExtensionA.argtypes = [LPSTR] - _PathFindExtensionA.restype = LPSTR + _PathFindExtensionA.restype = LPSTR pszPath = ctypes.create_string_buffer(pszPath) return _PathFindExtensionA(pszPath) + def PathFindExtensionW(pszPath): _PathFindExtensionW = windll.shlwapi.PathFindExtensionW _PathFindExtensionW.argtypes = [LPWSTR] - _PathFindExtensionW.restype = LPWSTR + _PathFindExtensionW.restype = LPWSTR pszPath = ctypes.create_unicode_buffer(pszPath) return _PathFindExtensionW(pszPath) + PathFindExtension = GuessStringType(PathFindExtensionA, PathFindExtensionW) + # LPTSTR PathFindFileName( # LPCTSTR pszPath # ); def PathFindFileNameA(pszPath): _PathFindFileNameA = windll.shlwapi.PathFindFileNameA _PathFindFileNameA.argtypes = [LPSTR] - _PathFindFileNameA.restype = LPSTR + _PathFindFileNameA.restype = LPSTR pszPath = ctypes.create_string_buffer(pszPath) return _PathFindFileNameA(pszPath) + def PathFindFileNameW(pszPath): _PathFindFileNameW = windll.shlwapi.PathFindFileNameW _PathFindFileNameW.argtypes = [LPWSTR] - _PathFindFileNameW.restype = LPWSTR + _PathFindFileNameW.restype = LPWSTR pszPath = ctypes.create_unicode_buffer(pszPath) return _PathFindFileNameW(pszPath) + PathFindFileName = GuessStringType(PathFindFileNameA, PathFindFileNameW) + # LPTSTR PathFindNextComponent( # LPCTSTR pszPath # ); def PathFindNextComponentA(pszPath): _PathFindNextComponentA = windll.shlwapi.PathFindNextComponentA _PathFindNextComponentA.argtypes = [LPSTR] - _PathFindNextComponentA.restype = LPSTR + _PathFindNextComponentA.restype = LPSTR pszPath = ctypes.create_string_buffer(pszPath) return _PathFindNextComponentA(pszPath) + def PathFindNextComponentW(pszPath): _PathFindNextComponentW = windll.shlwapi.PathFindNextComponentW _PathFindNextComponentW.argtypes = [LPWSTR] - _PathFindNextComponentW.restype = LPWSTR + _PathFindNextComponentW.restype = LPWSTR pszPath = ctypes.create_unicode_buffer(pszPath) return _PathFindNextComponentW(pszPath) + PathFindNextComponent = GuessStringType(PathFindNextComponentA, PathFindNextComponentW) + # BOOL PathFindOnPath( # LPTSTR pszFile, # LPCTSTR *ppszOtherDirs # ); -def PathFindOnPathA(pszFile, ppszOtherDirs = None): +def PathFindOnPathA(pszFile, ppszOtherDirs=None): _PathFindOnPathA = windll.shlwapi.PathFindOnPathA _PathFindOnPathA.argtypes = [LPSTR, LPSTR] - _PathFindOnPathA.restype = bool + _PathFindOnPathA.restype = bool pszFile = ctypes.create_string_buffer(pszFile, MAX_PATH) if not ppszOtherDirs: @@ -401,47 +433,53 @@ def PathFindOnPathA(pszFile, ppszOtherDirs = None): return pszFile.value return None -def PathFindOnPathW(pszFile, ppszOtherDirs = None): + +def PathFindOnPathW(pszFile, ppszOtherDirs=None): _PathFindOnPathW = windll.shlwapi.PathFindOnPathA _PathFindOnPathW.argtypes = [LPWSTR, LPWSTR] - _PathFindOnPathW.restype = bool + _PathFindOnPathW.restype = bool pszFile = ctypes.create_unicode_buffer(pszFile, MAX_PATH) if not ppszOtherDirs: ppszOtherDirs = None else: - szArray = u"" + szArray = "" for pszOtherDirs in ppszOtherDirs: if pszOtherDirs: - szArray = u"%s%s\0" % (szArray, pszOtherDirs) - szArray = szArray + u"\0" + szArray = "%s%s\0" % (szArray, pszOtherDirs) + szArray = szArray + "\0" pszOtherDirs = ctypes.create_unicode_buffer(szArray) ppszOtherDirs = ctypes.pointer(pszOtherDirs) if _PathFindOnPathW(pszFile, ppszOtherDirs): return pszFile.value return None + PathFindOnPath = GuessStringType(PathFindOnPathA, PathFindOnPathW) + # LPTSTR PathGetArgs( # LPCTSTR pszPath # ); def PathGetArgsA(pszPath): _PathGetArgsA = windll.shlwapi.PathGetArgsA _PathGetArgsA.argtypes = [LPSTR] - _PathGetArgsA.restype = LPSTR + _PathGetArgsA.restype = LPSTR pszPath = ctypes.create_string_buffer(pszPath) return _PathGetArgsA(pszPath) + def PathGetArgsW(pszPath): _PathGetArgsW = windll.shlwapi.PathGetArgsW _PathGetArgsW.argtypes = [LPWSTR] - _PathGetArgsW.restype = LPWSTR + _PathGetArgsW.restype = LPWSTR pszPath = ctypes.create_unicode_buffer(pszPath) return _PathGetArgsW(pszPath) + PathGetArgs = GuessStringType(PathGetArgsA, PathGetArgsW) + # BOOL PathIsContentType( # LPCTSTR pszPath, # LPCTSTR pszContentType @@ -449,102 +487,120 @@ def PathGetArgsW(pszPath): def PathIsContentTypeA(pszPath, pszContentType): _PathIsContentTypeA = windll.shlwapi.PathIsContentTypeA _PathIsContentTypeA.argtypes = [LPSTR, LPSTR] - _PathIsContentTypeA.restype = bool + _PathIsContentTypeA.restype = bool return _PathIsContentTypeA(pszPath, pszContentType) + def PathIsContentTypeW(pszPath, pszContentType): _PathIsContentTypeW = windll.shlwapi.PathIsContentTypeW _PathIsContentTypeW.argtypes = [LPWSTR, LPWSTR] - _PathIsContentTypeW.restype = bool + _PathIsContentTypeW.restype = bool return _PathIsContentTypeW(pszPath, pszContentType) + PathIsContentType = GuessStringType(PathIsContentTypeA, PathIsContentTypeW) + # BOOL PathIsDirectory( # LPCTSTR pszPath # ); def PathIsDirectoryA(pszPath): _PathIsDirectoryA = windll.shlwapi.PathIsDirectoryA _PathIsDirectoryA.argtypes = [LPSTR] - _PathIsDirectoryA.restype = bool + _PathIsDirectoryA.restype = bool return _PathIsDirectoryA(pszPath) + def PathIsDirectoryW(pszPath): _PathIsDirectoryW = windll.shlwapi.PathIsDirectoryW _PathIsDirectoryW.argtypes = [LPWSTR] - _PathIsDirectoryW.restype = bool + _PathIsDirectoryW.restype = bool return _PathIsDirectoryW(pszPath) + PathIsDirectory = GuessStringType(PathIsDirectoryA, PathIsDirectoryW) + # BOOL PathIsDirectoryEmpty( # LPCTSTR pszPath # ); def PathIsDirectoryEmptyA(pszPath): _PathIsDirectoryEmptyA = windll.shlwapi.PathIsDirectoryEmptyA _PathIsDirectoryEmptyA.argtypes = [LPSTR] - _PathIsDirectoryEmptyA.restype = bool + _PathIsDirectoryEmptyA.restype = bool return _PathIsDirectoryEmptyA(pszPath) + def PathIsDirectoryEmptyW(pszPath): _PathIsDirectoryEmptyW = windll.shlwapi.PathIsDirectoryEmptyW _PathIsDirectoryEmptyW.argtypes = [LPWSTR] - _PathIsDirectoryEmptyW.restype = bool + _PathIsDirectoryEmptyW.restype = bool return _PathIsDirectoryEmptyW(pszPath) + PathIsDirectoryEmpty = GuessStringType(PathIsDirectoryEmptyA, PathIsDirectoryEmptyW) + # BOOL PathIsNetworkPath( # LPCTSTR pszPath # ); def PathIsNetworkPathA(pszPath): _PathIsNetworkPathA = windll.shlwapi.PathIsNetworkPathA _PathIsNetworkPathA.argtypes = [LPSTR] - _PathIsNetworkPathA.restype = bool + _PathIsNetworkPathA.restype = bool return _PathIsNetworkPathA(pszPath) + def PathIsNetworkPathW(pszPath): _PathIsNetworkPathW = windll.shlwapi.PathIsNetworkPathW _PathIsNetworkPathW.argtypes = [LPWSTR] - _PathIsNetworkPathW.restype = bool + _PathIsNetworkPathW.restype = bool return _PathIsNetworkPathW(pszPath) + PathIsNetworkPath = GuessStringType(PathIsNetworkPathA, PathIsNetworkPathW) + # BOOL PathIsRelative( # LPCTSTR lpszPath # ); def PathIsRelativeA(pszPath): _PathIsRelativeA = windll.shlwapi.PathIsRelativeA _PathIsRelativeA.argtypes = [LPSTR] - _PathIsRelativeA.restype = bool + _PathIsRelativeA.restype = bool return _PathIsRelativeA(pszPath) + def PathIsRelativeW(pszPath): _PathIsRelativeW = windll.shlwapi.PathIsRelativeW _PathIsRelativeW.argtypes = [LPWSTR] - _PathIsRelativeW.restype = bool + _PathIsRelativeW.restype = bool return _PathIsRelativeW(pszPath) + PathIsRelative = GuessStringType(PathIsRelativeA, PathIsRelativeW) + # BOOL PathIsRoot( # LPCTSTR pPath # ); def PathIsRootA(pszPath): _PathIsRootA = windll.shlwapi.PathIsRootA _PathIsRootA.argtypes = [LPSTR] - _PathIsRootA.restype = bool + _PathIsRootA.restype = bool return _PathIsRootA(pszPath) + def PathIsRootW(pszPath): _PathIsRootW = windll.shlwapi.PathIsRootW _PathIsRootW.argtypes = [LPWSTR] - _PathIsRootW.restype = bool + _PathIsRootW.restype = bool return _PathIsRootW(pszPath) + PathIsRoot = GuessStringType(PathIsRootA, PathIsRootW) + # BOOL PathIsSameRoot( # LPCTSTR pszPath1, # LPCTSTR pszPath2 @@ -552,63 +608,72 @@ def PathIsRootW(pszPath): def PathIsSameRootA(pszPath1, pszPath2): _PathIsSameRootA = windll.shlwapi.PathIsSameRootA _PathIsSameRootA.argtypes = [LPSTR, LPSTR] - _PathIsSameRootA.restype = bool + _PathIsSameRootA.restype = bool return _PathIsSameRootA(pszPath1, pszPath2) + def PathIsSameRootW(pszPath1, pszPath2): _PathIsSameRootW = windll.shlwapi.PathIsSameRootW _PathIsSameRootW.argtypes = [LPWSTR, LPWSTR] - _PathIsSameRootW.restype = bool + _PathIsSameRootW.restype = bool return _PathIsSameRootW(pszPath1, pszPath2) + PathIsSameRoot = GuessStringType(PathIsSameRootA, PathIsSameRootW) + # BOOL PathIsUNC( # LPCTSTR pszPath # ); def PathIsUNCA(pszPath): _PathIsUNCA = windll.shlwapi.PathIsUNCA _PathIsUNCA.argtypes = [LPSTR] - _PathIsUNCA.restype = bool + _PathIsUNCA.restype = bool return _PathIsUNCA(pszPath) + def PathIsUNCW(pszPath): _PathIsUNCW = windll.shlwapi.PathIsUNCW _PathIsUNCW.argtypes = [LPWSTR] - _PathIsUNCW.restype = bool + _PathIsUNCW.restype = bool return _PathIsUNCW(pszPath) + PathIsUNC = GuessStringType(PathIsUNCA, PathIsUNCW) # XXX WARNING # PathMakePretty turns filenames into all lowercase. # I'm not sure how well that might work on Wine. + # BOOL PathMakePretty( # LPCTSTR pszPath # ); def PathMakePrettyA(pszPath): _PathMakePrettyA = windll.shlwapi.PathMakePrettyA _PathMakePrettyA.argtypes = [LPSTR] - _PathMakePrettyA.restype = bool + _PathMakePrettyA.restype = bool _PathMakePrettyA.errcheck = RaiseIfZero pszPath = ctypes.create_string_buffer(pszPath, MAX_PATH) _PathMakePrettyA(pszPath) return pszPath.value + def PathMakePrettyW(pszPath): _PathMakePrettyW = windll.shlwapi.PathMakePrettyW _PathMakePrettyW.argtypes = [LPWSTR] - _PathMakePrettyW.restype = bool + _PathMakePrettyW.restype = bool _PathMakePrettyW.errcheck = RaiseIfZero pszPath = ctypes.create_unicode_buffer(pszPath, MAX_PATH) _PathMakePrettyW(pszPath) return pszPath.value + PathMakePretty = GuessStringType(PathMakePrettyA, PathMakePrettyW) + # void PathRemoveArgs( # LPTSTR pszPath # ); @@ -620,6 +685,7 @@ def PathRemoveArgsA(pszPath): _PathRemoveArgsA(pszPath) return pszPath.value + def PathRemoveArgsW(pszPath): _PathRemoveArgsW = windll.shlwapi.PathRemoveArgsW _PathRemoveArgsW.argtypes = [LPWSTR] @@ -628,8 +694,10 @@ def PathRemoveArgsW(pszPath): _PathRemoveArgsW(pszPath) return pszPath.value + PathRemoveArgs = GuessStringType(PathRemoveArgsA, PathRemoveArgsW) + # void PathRemoveBackslash( # LPTSTR pszPath # ); @@ -641,6 +709,7 @@ def PathRemoveBackslashA(pszPath): _PathRemoveBackslashA(pszPath) return pszPath.value + def PathRemoveBackslashW(pszPath): _PathRemoveBackslashW = windll.shlwapi.PathRemoveBackslashW _PathRemoveBackslashW.argtypes = [LPWSTR] @@ -649,8 +718,10 @@ def PathRemoveBackslashW(pszPath): _PathRemoveBackslashW(pszPath) return pszPath.value + PathRemoveBackslash = GuessStringType(PathRemoveBackslashA, PathRemoveBackslashW) + # void PathRemoveExtension( # LPTSTR pszPath # ); @@ -662,6 +733,7 @@ def PathRemoveExtensionA(pszPath): _PathRemoveExtensionA(pszPath) return pszPath.value + def PathRemoveExtensionW(pszPath): _PathRemoveExtensionW = windll.shlwapi.PathRemoveExtensionW _PathRemoveExtensionW.argtypes = [LPWSTR] @@ -670,8 +742,10 @@ def PathRemoveExtensionW(pszPath): _PathRemoveExtensionW(pszPath) return pszPath.value + PathRemoveExtension = GuessStringType(PathRemoveExtensionA, PathRemoveExtensionW) + # void PathRemoveFileSpec( # LPTSTR pszPath # ); @@ -683,6 +757,7 @@ def PathRemoveFileSpecA(pszPath): _PathRemoveFileSpecA(pszPath) return pszPath.value + def PathRemoveFileSpecW(pszPath): _PathRemoveFileSpecW = windll.shlwapi.PathRemoveFileSpecW _PathRemoveFileSpecW.argtypes = [LPWSTR] @@ -691,8 +766,10 @@ def PathRemoveFileSpecW(pszPath): _PathRemoveFileSpecW(pszPath) return pszPath.value + PathRemoveFileSpec = GuessStringType(PathRemoveFileSpecA, PathRemoveFileSpecW) + # BOOL PathRenameExtension( # LPTSTR pszPath, # LPCTSTR pszExt @@ -700,25 +777,28 @@ def PathRemoveFileSpecW(pszPath): def PathRenameExtensionA(pszPath, pszExt): _PathRenameExtensionA = windll.shlwapi.PathRenameExtensionA _PathRenameExtensionA.argtypes = [LPSTR, LPSTR] - _PathRenameExtensionA.restype = bool + _PathRenameExtensionA.restype = bool pszPath = ctypes.create_string_buffer(pszPath, MAX_PATH) if _PathRenameExtensionA(pszPath, pszExt): return pszPath.value return None + def PathRenameExtensionW(pszPath, pszExt): _PathRenameExtensionW = windll.shlwapi.PathRenameExtensionW _PathRenameExtensionW.argtypes = [LPWSTR, LPWSTR] - _PathRenameExtensionW.restype = bool + _PathRenameExtensionW.restype = bool pszPath = ctypes.create_unicode_buffer(pszPath, MAX_PATH) if _PathRenameExtensionW(pszPath, pszExt): return pszPath.value return None + PathRenameExtension = GuessStringType(PathRenameExtensionA, PathRenameExtensionW) + # BOOL PathUnExpandEnvStrings( # LPCTSTR pszPath, # LPTSTR pszBuf, @@ -727,7 +807,7 @@ def PathRenameExtensionW(pszPath, pszExt): def PathUnExpandEnvStringsA(pszPath): _PathUnExpandEnvStringsA = windll.shlwapi.PathUnExpandEnvStringsA _PathUnExpandEnvStringsA.argtypes = [LPSTR, LPSTR] - _PathUnExpandEnvStringsA.restype = bool + _PathUnExpandEnvStringsA.restype = bool _PathUnExpandEnvStringsA.errcheck = RaiseIfZero cchBuf = MAX_PATH @@ -735,22 +815,24 @@ def PathUnExpandEnvStringsA(pszPath): _PathUnExpandEnvStringsA(pszPath, pszBuf, cchBuf) return pszBuf.value + def PathUnExpandEnvStringsW(pszPath): _PathUnExpandEnvStringsW = windll.shlwapi.PathUnExpandEnvStringsW _PathUnExpandEnvStringsW.argtypes = [LPWSTR, LPWSTR] - _PathUnExpandEnvStringsW.restype = bool + _PathUnExpandEnvStringsW.restype = bool _PathUnExpandEnvStringsW.errcheck = RaiseIfZero cchBuf = MAX_PATH - pszBuf = ctypes.create_unicode_buffer(u"", cchBuf) + pszBuf = ctypes.create_unicode_buffer("", cchBuf) _PathUnExpandEnvStringsW(pszPath, pszBuf, cchBuf) return pszBuf.value + PathUnExpandEnvStrings = GuessStringType(PathUnExpandEnvStringsA, PathUnExpandEnvStringsW) -#============================================================================== +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/user32.py b/pydevd_attach_to_process/winappdbg/win32/user32.py index 18560e552..f6f9feff1 100644 --- a/pydevd_attach_to_process/winappdbg/win32/user32.py +++ b/pydevd_attach_to_process/winappdbg/win32/user32.py @@ -39,13 +39,14 @@ from winappdbg.win32.kernel32 import GetLastError, SetLastError from winappdbg.win32.gdi32 import POINT, PPOINT, LPPOINT, RECT, PRECT, LPRECT -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== + +# --- Helpers ------------------------------------------------------------------ -#--- Helpers ------------------------------------------------------------------ def MAKE_WPARAM(wParam): """ @@ -58,6 +59,7 @@ def MAKE_WPARAM(wParam): wParam = 0 return wParam + def MAKE_LPARAM(lParam): """ Convert arguments to the LPARAM type. @@ -66,281 +68,286 @@ def MAKE_LPARAM(lParam): """ return ctypes.cast(lParam, LPARAM) -class __WindowEnumerator (object): + +class __WindowEnumerator(object): """ Window enumerator class. Used internally by the window enumeration APIs. """ + def __init__(self): self.hwnd = list() + def __call__(self, hwnd, lParam): -## print hwnd # XXX DEBUG + ## print hwnd # XXX DEBUG self.hwnd.append(hwnd) return TRUE -#--- Types -------------------------------------------------------------------- + +# --- Types -------------------------------------------------------------------- WNDENUMPROC = WINFUNCTYPE(BOOL, HWND, PVOID) -#--- Constants ---------------------------------------------------------------- +# --- Constants ---------------------------------------------------------------- -HWND_DESKTOP = 0 -HWND_TOP = 1 -HWND_BOTTOM = 1 -HWND_TOPMOST = -1 -HWND_NOTOPMOST = -2 -HWND_MESSAGE = -3 +HWND_DESKTOP = 0 +HWND_TOP = 1 +HWND_BOTTOM = 1 +HWND_TOPMOST = -1 +HWND_NOTOPMOST = -2 +HWND_MESSAGE = -3 # GetWindowLong / SetWindowLong -GWL_WNDPROC = -4 -GWL_HINSTANCE = -6 -GWL_HWNDPARENT = -8 -GWL_ID = -12 -GWL_STYLE = -16 -GWL_EXSTYLE = -20 -GWL_USERDATA = -21 +GWL_WNDPROC = -4 +GWL_HINSTANCE = -6 +GWL_HWNDPARENT = -8 +GWL_ID = -12 +GWL_STYLE = -16 +GWL_EXSTYLE = -20 +GWL_USERDATA = -21 # GetWindowLongPtr / SetWindowLongPtr -GWLP_WNDPROC = GWL_WNDPROC -GWLP_HINSTANCE = GWL_HINSTANCE -GWLP_HWNDPARENT = GWL_HWNDPARENT -GWLP_STYLE = GWL_STYLE -GWLP_EXSTYLE = GWL_EXSTYLE -GWLP_USERDATA = GWL_USERDATA -GWLP_ID = GWL_ID +GWLP_WNDPROC = GWL_WNDPROC +GWLP_HINSTANCE = GWL_HINSTANCE +GWLP_HWNDPARENT = GWL_HWNDPARENT +GWLP_STYLE = GWL_STYLE +GWLP_EXSTYLE = GWL_EXSTYLE +GWLP_USERDATA = GWL_USERDATA +GWLP_ID = GWL_ID # ShowWindow -SW_HIDE = 0 -SW_SHOWNORMAL = 1 -SW_NORMAL = 1 -SW_SHOWMINIMIZED = 2 -SW_SHOWMAXIMIZED = 3 -SW_MAXIMIZE = 3 -SW_SHOWNOACTIVATE = 4 -SW_SHOW = 5 -SW_MINIMIZE = 6 -SW_SHOWMINNOACTIVE = 7 -SW_SHOWNA = 8 -SW_RESTORE = 9 -SW_SHOWDEFAULT = 10 -SW_FORCEMINIMIZE = 11 +SW_HIDE = 0 +SW_SHOWNORMAL = 1 +SW_NORMAL = 1 +SW_SHOWMINIMIZED = 2 +SW_SHOWMAXIMIZED = 3 +SW_MAXIMIZE = 3 +SW_SHOWNOACTIVATE = 4 +SW_SHOW = 5 +SW_MINIMIZE = 6 +SW_SHOWMINNOACTIVE = 7 +SW_SHOWNA = 8 +SW_RESTORE = 9 +SW_SHOWDEFAULT = 10 +SW_FORCEMINIMIZE = 11 # SendMessageTimeout flags -SMTO_NORMAL = 0 -SMTO_BLOCK = 1 -SMTO_ABORTIFHUNG = 2 -SMTO_NOTIMEOUTIFNOTHUNG = 8 -SMTO_ERRORONEXIT = 0x20 +SMTO_NORMAL = 0 +SMTO_BLOCK = 1 +SMTO_ABORTIFHUNG = 2 +SMTO_NOTIMEOUTIFNOTHUNG = 8 +SMTO_ERRORONEXIT = 0x20 # WINDOWPLACEMENT flags -WPF_SETMINPOSITION = 1 -WPF_RESTORETOMAXIMIZED = 2 -WPF_ASYNCWINDOWPLACEMENT = 4 +WPF_SETMINPOSITION = 1 +WPF_RESTORETOMAXIMIZED = 2 +WPF_ASYNCWINDOWPLACEMENT = 4 # GetAncestor flags -GA_PARENT = 1 -GA_ROOT = 2 -GA_ROOTOWNER = 3 +GA_PARENT = 1 +GA_ROOT = 2 +GA_ROOTOWNER = 3 # GetWindow flags -GW_HWNDFIRST = 0 -GW_HWNDLAST = 1 -GW_HWNDNEXT = 2 -GW_HWNDPREV = 3 -GW_OWNER = 4 -GW_CHILD = 5 -GW_ENABLEDPOPUP = 6 - -#--- Window messages ---------------------------------------------------------- - -WM_USER = 0x400 -WM_APP = 0x800 - -WM_NULL = 0 -WM_CREATE = 1 -WM_DESTROY = 2 -WM_MOVE = 3 -WM_SIZE = 5 -WM_ACTIVATE = 6 -WA_INACTIVE = 0 -WA_ACTIVE = 1 -WA_CLICKACTIVE = 2 -WM_SETFOCUS = 7 -WM_KILLFOCUS = 8 -WM_ENABLE = 0x0A -WM_SETREDRAW = 0x0B -WM_SETTEXT = 0x0C -WM_GETTEXT = 0x0D -WM_GETTEXTLENGTH = 0x0E -WM_PAINT = 0x0F -WM_CLOSE = 0x10 -WM_QUERYENDSESSION = 0x11 -WM_QUIT = 0x12 -WM_QUERYOPEN = 0x13 -WM_ERASEBKGND = 0x14 -WM_SYSCOLORCHANGE = 0x15 -WM_ENDSESSION = 0x16 -WM_SHOWWINDOW = 0x18 -WM_WININICHANGE = 0x1A -WM_SETTINGCHANGE = WM_WININICHANGE -WM_DEVMODECHANGE = 0x1B -WM_ACTIVATEAPP = 0x1C -WM_FONTCHANGE = 0x1D -WM_TIMECHANGE = 0x1E -WM_CANCELMODE = 0x1F -WM_SETCURSOR = 0x20 -WM_MOUSEACTIVATE = 0x21 -WM_CHILDACTIVATE = 0x22 -WM_QUEUESYNC = 0x23 -WM_GETMINMAXINFO = 0x24 -WM_PAINTICON = 0x26 -WM_ICONERASEBKGND = 0x27 -WM_NEXTDLGCTL = 0x28 -WM_SPOOLERSTATUS = 0x2A -WM_DRAWITEM = 0x2B -WM_MEASUREITEM = 0x2C -WM_DELETEITEM = 0x2D -WM_VKEYTOITEM = 0x2E -WM_CHARTOITEM = 0x2F -WM_SETFONT = 0x30 -WM_GETFONT = 0x31 -WM_SETHOTKEY = 0x32 -WM_GETHOTKEY = 0x33 -WM_QUERYDRAGICON = 0x37 -WM_COMPAREITEM = 0x39 -WM_GETOBJECT = 0x3D -WM_COMPACTING = 0x41 -WM_OTHERWINDOWCREATED = 0x42 -WM_OTHERWINDOWDESTROYED = 0x43 -WM_COMMNOTIFY = 0x44 - -CN_RECEIVE = 0x1 -CN_TRANSMIT = 0x2 -CN_EVENT = 0x4 - -WM_WINDOWPOSCHANGING = 0x46 -WM_WINDOWPOSCHANGED = 0x47 -WM_POWER = 0x48 - -PWR_OK = 1 -PWR_FAIL = -1 -PWR_SUSPENDREQUEST = 1 -PWR_SUSPENDRESUME = 2 -PWR_CRITICALRESUME = 3 - -WM_COPYDATA = 0x4A -WM_CANCELJOURNAL = 0x4B -WM_NOTIFY = 0x4E -WM_INPUTLANGCHANGEREQUEST = 0x50 -WM_INPUTLANGCHANGE = 0x51 -WM_TCARD = 0x52 -WM_HELP = 0x53 -WM_USERCHANGED = 0x54 -WM_NOTIFYFORMAT = 0x55 -WM_CONTEXTMENU = 0x7B -WM_STYLECHANGING = 0x7C -WM_STYLECHANGED = 0x7D -WM_DISPLAYCHANGE = 0x7E -WM_GETICON = 0x7F -WM_SETICON = 0x80 -WM_NCCREATE = 0x81 -WM_NCDESTROY = 0x82 -WM_NCCALCSIZE = 0x83 -WM_NCHITTEST = 0x84 -WM_NCPAINT = 0x85 -WM_NCACTIVATE = 0x86 -WM_GETDLGCODE = 0x87 -WM_SYNCPAINT = 0x88 -WM_NCMOUSEMOVE = 0x0A0 -WM_NCLBUTTONDOWN = 0x0A1 -WM_NCLBUTTONUP = 0x0A2 -WM_NCLBUTTONDBLCLK = 0x0A3 -WM_NCRBUTTONDOWN = 0x0A4 -WM_NCRBUTTONUP = 0x0A5 -WM_NCRBUTTONDBLCLK = 0x0A6 -WM_NCMBUTTONDOWN = 0x0A7 -WM_NCMBUTTONUP = 0x0A8 -WM_NCMBUTTONDBLCLK = 0x0A9 -WM_KEYFIRST = 0x100 -WM_KEYDOWN = 0x100 -WM_KEYUP = 0x101 -WM_CHAR = 0x102 -WM_DEADCHAR = 0x103 -WM_SYSKEYDOWN = 0x104 -WM_SYSKEYUP = 0x105 -WM_SYSCHAR = 0x106 -WM_SYSDEADCHAR = 0x107 -WM_KEYLAST = 0x108 -WM_INITDIALOG = 0x110 -WM_COMMAND = 0x111 -WM_SYSCOMMAND = 0x112 -WM_TIMER = 0x113 -WM_HSCROLL = 0x114 -WM_VSCROLL = 0x115 -WM_INITMENU = 0x116 -WM_INITMENUPOPUP = 0x117 -WM_MENUSELECT = 0x11F -WM_MENUCHAR = 0x120 -WM_ENTERIDLE = 0x121 -WM_CTLCOLORMSGBOX = 0x132 -WM_CTLCOLOREDIT = 0x133 -WM_CTLCOLORLISTBOX = 0x134 -WM_CTLCOLORBTN = 0x135 -WM_CTLCOLORDLG = 0x136 -WM_CTLCOLORSCROLLBAR = 0x137 -WM_CTLCOLORSTATIC = 0x138 -WM_MOUSEFIRST = 0x200 -WM_MOUSEMOVE = 0x200 -WM_LBUTTONDOWN = 0x201 -WM_LBUTTONUP = 0x202 -WM_LBUTTONDBLCLK = 0x203 -WM_RBUTTONDOWN = 0x204 -WM_RBUTTONUP = 0x205 -WM_RBUTTONDBLCLK = 0x206 -WM_MBUTTONDOWN = 0x207 -WM_MBUTTONUP = 0x208 -WM_MBUTTONDBLCLK = 0x209 -WM_MOUSELAST = 0x209 -WM_PARENTNOTIFY = 0x210 -WM_ENTERMENULOOP = 0x211 -WM_EXITMENULOOP = 0x212 -WM_MDICREATE = 0x220 -WM_MDIDESTROY = 0x221 -WM_MDIACTIVATE = 0x222 -WM_MDIRESTORE = 0x223 -WM_MDINEXT = 0x224 -WM_MDIMAXIMIZE = 0x225 -WM_MDITILE = 0x226 -WM_MDICASCADE = 0x227 -WM_MDIICONARRANGE = 0x228 -WM_MDIGETACTIVE = 0x229 -WM_MDISETMENU = 0x230 -WM_DROPFILES = 0x233 -WM_MDIREFRESHMENU = 0x234 -WM_CUT = 0x300 -WM_COPY = 0x301 -WM_PASTE = 0x302 -WM_CLEAR = 0x303 -WM_UNDO = 0x304 -WM_RENDERFORMAT = 0x305 -WM_RENDERALLFORMATS = 0x306 -WM_DESTROYCLIPBOARD = 0x307 -WM_DRAWCLIPBOARD = 0x308 -WM_PAINTCLIPBOARD = 0x309 -WM_VSCROLLCLIPBOARD = 0x30A -WM_SIZECLIPBOARD = 0x30B -WM_ASKCBFORMATNAME = 0x30C -WM_CHANGECBCHAIN = 0x30D -WM_HSCROLLCLIPBOARD = 0x30E -WM_QUERYNEWPALETTE = 0x30F -WM_PALETTEISCHANGING = 0x310 -WM_PALETTECHANGED = 0x311 -WM_HOTKEY = 0x312 -WM_PRINT = 0x317 -WM_PRINTCLIENT = 0x318 -WM_PENWINFIRST = 0x380 -WM_PENWINLAST = 0x38F - -#--- Structures --------------------------------------------------------------- +GW_HWNDFIRST = 0 +GW_HWNDLAST = 1 +GW_HWNDNEXT = 2 +GW_HWNDPREV = 3 +GW_OWNER = 4 +GW_CHILD = 5 +GW_ENABLEDPOPUP = 6 + +# --- Window messages ---------------------------------------------------------- + +WM_USER = 0x400 +WM_APP = 0x800 + +WM_NULL = 0 +WM_CREATE = 1 +WM_DESTROY = 2 +WM_MOVE = 3 +WM_SIZE = 5 +WM_ACTIVATE = 6 +WA_INACTIVE = 0 +WA_ACTIVE = 1 +WA_CLICKACTIVE = 2 +WM_SETFOCUS = 7 +WM_KILLFOCUS = 8 +WM_ENABLE = 0x0A +WM_SETREDRAW = 0x0B +WM_SETTEXT = 0x0C +WM_GETTEXT = 0x0D +WM_GETTEXTLENGTH = 0x0E +WM_PAINT = 0x0F +WM_CLOSE = 0x10 +WM_QUERYENDSESSION = 0x11 +WM_QUIT = 0x12 +WM_QUERYOPEN = 0x13 +WM_ERASEBKGND = 0x14 +WM_SYSCOLORCHANGE = 0x15 +WM_ENDSESSION = 0x16 +WM_SHOWWINDOW = 0x18 +WM_WININICHANGE = 0x1A +WM_SETTINGCHANGE = WM_WININICHANGE +WM_DEVMODECHANGE = 0x1B +WM_ACTIVATEAPP = 0x1C +WM_FONTCHANGE = 0x1D +WM_TIMECHANGE = 0x1E +WM_CANCELMODE = 0x1F +WM_SETCURSOR = 0x20 +WM_MOUSEACTIVATE = 0x21 +WM_CHILDACTIVATE = 0x22 +WM_QUEUESYNC = 0x23 +WM_GETMINMAXINFO = 0x24 +WM_PAINTICON = 0x26 +WM_ICONERASEBKGND = 0x27 +WM_NEXTDLGCTL = 0x28 +WM_SPOOLERSTATUS = 0x2A +WM_DRAWITEM = 0x2B +WM_MEASUREITEM = 0x2C +WM_DELETEITEM = 0x2D +WM_VKEYTOITEM = 0x2E +WM_CHARTOITEM = 0x2F +WM_SETFONT = 0x30 +WM_GETFONT = 0x31 +WM_SETHOTKEY = 0x32 +WM_GETHOTKEY = 0x33 +WM_QUERYDRAGICON = 0x37 +WM_COMPAREITEM = 0x39 +WM_GETOBJECT = 0x3D +WM_COMPACTING = 0x41 +WM_OTHERWINDOWCREATED = 0x42 +WM_OTHERWINDOWDESTROYED = 0x43 +WM_COMMNOTIFY = 0x44 + +CN_RECEIVE = 0x1 +CN_TRANSMIT = 0x2 +CN_EVENT = 0x4 + +WM_WINDOWPOSCHANGING = 0x46 +WM_WINDOWPOSCHANGED = 0x47 +WM_POWER = 0x48 + +PWR_OK = 1 +PWR_FAIL = -1 +PWR_SUSPENDREQUEST = 1 +PWR_SUSPENDRESUME = 2 +PWR_CRITICALRESUME = 3 + +WM_COPYDATA = 0x4A +WM_CANCELJOURNAL = 0x4B +WM_NOTIFY = 0x4E +WM_INPUTLANGCHANGEREQUEST = 0x50 +WM_INPUTLANGCHANGE = 0x51 +WM_TCARD = 0x52 +WM_HELP = 0x53 +WM_USERCHANGED = 0x54 +WM_NOTIFYFORMAT = 0x55 +WM_CONTEXTMENU = 0x7B +WM_STYLECHANGING = 0x7C +WM_STYLECHANGED = 0x7D +WM_DISPLAYCHANGE = 0x7E +WM_GETICON = 0x7F +WM_SETICON = 0x80 +WM_NCCREATE = 0x81 +WM_NCDESTROY = 0x82 +WM_NCCALCSIZE = 0x83 +WM_NCHITTEST = 0x84 +WM_NCPAINT = 0x85 +WM_NCACTIVATE = 0x86 +WM_GETDLGCODE = 0x87 +WM_SYNCPAINT = 0x88 +WM_NCMOUSEMOVE = 0x0A0 +WM_NCLBUTTONDOWN = 0x0A1 +WM_NCLBUTTONUP = 0x0A2 +WM_NCLBUTTONDBLCLK = 0x0A3 +WM_NCRBUTTONDOWN = 0x0A4 +WM_NCRBUTTONUP = 0x0A5 +WM_NCRBUTTONDBLCLK = 0x0A6 +WM_NCMBUTTONDOWN = 0x0A7 +WM_NCMBUTTONUP = 0x0A8 +WM_NCMBUTTONDBLCLK = 0x0A9 +WM_KEYFIRST = 0x100 +WM_KEYDOWN = 0x100 +WM_KEYUP = 0x101 +WM_CHAR = 0x102 +WM_DEADCHAR = 0x103 +WM_SYSKEYDOWN = 0x104 +WM_SYSKEYUP = 0x105 +WM_SYSCHAR = 0x106 +WM_SYSDEADCHAR = 0x107 +WM_KEYLAST = 0x108 +WM_INITDIALOG = 0x110 +WM_COMMAND = 0x111 +WM_SYSCOMMAND = 0x112 +WM_TIMER = 0x113 +WM_HSCROLL = 0x114 +WM_VSCROLL = 0x115 +WM_INITMENU = 0x116 +WM_INITMENUPOPUP = 0x117 +WM_MENUSELECT = 0x11F +WM_MENUCHAR = 0x120 +WM_ENTERIDLE = 0x121 +WM_CTLCOLORMSGBOX = 0x132 +WM_CTLCOLOREDIT = 0x133 +WM_CTLCOLORLISTBOX = 0x134 +WM_CTLCOLORBTN = 0x135 +WM_CTLCOLORDLG = 0x136 +WM_CTLCOLORSCROLLBAR = 0x137 +WM_CTLCOLORSTATIC = 0x138 +WM_MOUSEFIRST = 0x200 +WM_MOUSEMOVE = 0x200 +WM_LBUTTONDOWN = 0x201 +WM_LBUTTONUP = 0x202 +WM_LBUTTONDBLCLK = 0x203 +WM_RBUTTONDOWN = 0x204 +WM_RBUTTONUP = 0x205 +WM_RBUTTONDBLCLK = 0x206 +WM_MBUTTONDOWN = 0x207 +WM_MBUTTONUP = 0x208 +WM_MBUTTONDBLCLK = 0x209 +WM_MOUSELAST = 0x209 +WM_PARENTNOTIFY = 0x210 +WM_ENTERMENULOOP = 0x211 +WM_EXITMENULOOP = 0x212 +WM_MDICREATE = 0x220 +WM_MDIDESTROY = 0x221 +WM_MDIACTIVATE = 0x222 +WM_MDIRESTORE = 0x223 +WM_MDINEXT = 0x224 +WM_MDIMAXIMIZE = 0x225 +WM_MDITILE = 0x226 +WM_MDICASCADE = 0x227 +WM_MDIICONARRANGE = 0x228 +WM_MDIGETACTIVE = 0x229 +WM_MDISETMENU = 0x230 +WM_DROPFILES = 0x233 +WM_MDIREFRESHMENU = 0x234 +WM_CUT = 0x300 +WM_COPY = 0x301 +WM_PASTE = 0x302 +WM_CLEAR = 0x303 +WM_UNDO = 0x304 +WM_RENDERFORMAT = 0x305 +WM_RENDERALLFORMATS = 0x306 +WM_DESTROYCLIPBOARD = 0x307 +WM_DRAWCLIPBOARD = 0x308 +WM_PAINTCLIPBOARD = 0x309 +WM_VSCROLLCLIPBOARD = 0x30A +WM_SIZECLIPBOARD = 0x30B +WM_ASKCBFORMATNAME = 0x30C +WM_CHANGECBCHAIN = 0x30D +WM_HSCROLLCLIPBOARD = 0x30E +WM_QUERYNEWPALETTE = 0x30F +WM_PALETTEISCHANGING = 0x310 +WM_PALETTECHANGED = 0x311 +WM_HOTKEY = 0x312 +WM_PRINT = 0x317 +WM_PRINTCLIENT = 0x318 +WM_PENWINFIRST = 0x380 +WM_PENWINLAST = 0x38F + +# --- Structures --------------------------------------------------------------- + # typedef struct _WINDOWPLACEMENT { # UINT length; @@ -352,16 +359,19 @@ def __call__(self, hwnd, lParam): # } WINDOWPLACEMENT; class WINDOWPLACEMENT(Structure): _fields_ = [ - ('length', UINT), - ('flags', UINT), - ('showCmd', UINT), - ('ptMinPosition', POINT), - ('ptMaxPosition', POINT), - ('rcNormalPosition', RECT), + ("length", UINT), + ("flags", UINT), + ("showCmd", UINT), + ("ptMinPosition", POINT), + ("ptMaxPosition", POINT), + ("rcNormalPosition", RECT), ] -PWINDOWPLACEMENT = POINTER(WINDOWPLACEMENT) + + +PWINDOWPLACEMENT = POINTER(WINDOWPLACEMENT) LPWINDOWPLACEMENT = PWINDOWPLACEMENT + # typedef struct tagGUITHREADINFO { # DWORD cbSize; # DWORD flags; @@ -375,20 +385,22 @@ class WINDOWPLACEMENT(Structure): # } GUITHREADINFO, *PGUITHREADINFO; class GUITHREADINFO(Structure): _fields_ = [ - ('cbSize', DWORD), - ('flags', DWORD), - ('hwndActive', HWND), - ('hwndFocus', HWND), - ('hwndCapture', HWND), - ('hwndMenuOwner', HWND), - ('hwndMoveSize', HWND), - ('hwndCaret', HWND), - ('rcCaret', RECT), + ("cbSize", DWORD), + ("flags", DWORD), + ("hwndActive", HWND), + ("hwndFocus", HWND), + ("hwndCapture", HWND), + ("hwndMenuOwner", HWND), + ("hwndMoveSize", HWND), + ("hwndCaret", HWND), + ("rcCaret", RECT), ] -PGUITHREADINFO = POINTER(GUITHREADINFO) + + +PGUITHREADINFO = POINTER(GUITHREADINFO) LPGUITHREADINFO = PGUITHREADINFO -#--- High level classes ------------------------------------------------------- +# --- High level classes ------------------------------------------------------- # Point() and Rect() are here instead of gdi32.py because they were mainly # created to handle window coordinates rather than drawing on the screen. @@ -396,6 +408,7 @@ class GUITHREADINFO(Structure): # XXX not sure if these classes should be psyco-optimized, # it may not work if the user wants to serialize them for some reason + class Point(object): """ Python wrapper over the L{POINT} class. @@ -406,7 +419,7 @@ class Point(object): @ivar y: Vertical coordinate """ - def __init__(self, x = 0, y = 0): + def __init__(self, x=0, y=0): """ @see: L{POINT} @type x: int @@ -424,10 +437,10 @@ def __len__(self): return 2 def __getitem__(self, index): - return (self.x, self.y) [index] + return (self.x, self.y)[index] def __setitem__(self, index, value): - if index == 0: + if index == 0: self.x = value elif index == 1: self.y = value @@ -470,7 +483,7 @@ def client_to_screen(self, hWnd): """ return ClientToScreen(hWnd, self) - def translate(self, hWndFrom = HWND_DESKTOP, hWndTo = HWND_DESKTOP): + def translate(self, hWndFrom=HWND_DESKTOP, hWndTo=HWND_DESKTOP): """ Translate coordinates from one window to another. @@ -492,6 +505,7 @@ def translate(self, hWndFrom = HWND_DESKTOP, hWndTo = HWND_DESKTOP): """ return MapWindowPoints(hWndFrom, hWndTo, [self]) + class Rect(object): """ Python wrapper over the L{RECT} class. @@ -511,7 +525,7 @@ class Rect(object): @ivar height: Height in pixels. Same as C{bottom - top}. """ - def __init__(self, left = 0, top = 0, right = 0, bottom = 0): + def __init__(self, left=0, top=0, right=0, bottom=0): """ @see: L{RECT} @type left: int @@ -523,9 +537,9 @@ def __init__(self, left = 0, top = 0, right = 0, bottom = 0): @type bottom: int @param bottom: Vertical coordinate for the bottom right corner. """ - self.left = left - self.top = top - self.right = right + self.left = left + self.top = top + self.right = right self.bottom = bottom def __iter__(self): @@ -535,15 +549,15 @@ def __len__(self): return 2 def __getitem__(self, index): - return (self.left, self.top, self.right, self.bottom) [index] + return (self.left, self.top, self.right, self.bottom)[index] def __setitem__(self, index, value): - if index == 0: - self.left = value + if index == 0: + self.left = value elif index == 1: - self.top = value + self.top = value elif index == 2: - self.right = value + self.right = value elif index == 3: self.bottom = value else: @@ -569,7 +583,7 @@ def __set_width(self, value): def __set_height(self, value): self.bottom = value - self.top - width = property(__get_width, __set_width) + width = property(__get_width, __set_width) height = property(__get_height, __set_height) def screen_to_client(self, hWnd): @@ -584,9 +598,9 @@ def screen_to_client(self, hWnd): @rtype: L{Rect} @return: New object containing the translated coordinates. """ - topleft = ScreenToClient(hWnd, (self.left, self.top)) + topleft = ScreenToClient(hWnd, (self.left, self.top)) bottomright = ScreenToClient(hWnd, (self.bottom, self.right)) - return Rect( topleft.x, topleft.y, bottomright.x, bottomright.y ) + return Rect(topleft.x, topleft.y, bottomright.x, bottomright.y) def client_to_screen(self, hWnd): """ @@ -600,11 +614,11 @@ def client_to_screen(self, hWnd): @rtype: L{Rect} @return: New object containing the translated coordinates. """ - topleft = ClientToScreen(hWnd, (self.left, self.top)) + topleft = ClientToScreen(hWnd, (self.left, self.top)) bottomright = ClientToScreen(hWnd, (self.bottom, self.right)) - return Rect( topleft.x, topleft.y, bottomright.x, bottomright.y ) + return Rect(topleft.x, topleft.y, bottomright.x, bottomright.y) - def translate(self, hWndFrom = HWND_DESKTOP, hWndTo = HWND_DESKTOP): + def translate(self, hWndFrom=HWND_DESKTOP, hWndTo=HWND_DESKTOP): """ Translate coordinates from one window to another. @@ -621,39 +635,40 @@ def translate(self, hWndFrom = HWND_DESKTOP, hWndTo = HWND_DESKTOP): @rtype: L{Rect} @return: New object containing the translated coordinates. """ - points = [ (self.left, self.top), (self.right, self.bottom) ] + points = [(self.left, self.top), (self.right, self.bottom)] return MapWindowPoints(hWndFrom, hWndTo, points) + class WindowPlacement(object): """ Python wrapper over the L{WINDOWPLACEMENT} class. """ - def __init__(self, wp = None): + def __init__(self, wp=None): """ @type wp: L{WindowPlacement} or L{WINDOWPLACEMENT} @param wp: Another window placement object. """ # Initialize all properties with empty values. - self.flags = 0 - self.showCmd = 0 - self.ptMinPosition = Point() - self.ptMaxPosition = Point() + self.flags = 0 + self.showCmd = 0 + self.ptMinPosition = Point() + self.ptMaxPosition = Point() self.rcNormalPosition = Rect() # If a window placement was given copy it's properties. if wp: - self.flags = wp.flags - self.showCmd = wp.showCmd - self.ptMinPosition = Point( wp.ptMinPosition.x, wp.ptMinPosition.y ) - self.ptMaxPosition = Point( wp.ptMaxPosition.x, wp.ptMaxPosition.y ) + self.flags = wp.flags + self.showCmd = wp.showCmd + self.ptMinPosition = Point(wp.ptMinPosition.x, wp.ptMinPosition.y) + self.ptMaxPosition = Point(wp.ptMaxPosition.x, wp.ptMaxPosition.y) self.rcNormalPosition = Rect( - wp.rcNormalPosition.left, - wp.rcNormalPosition.top, - wp.rcNormalPosition.right, - wp.rcNormalPosition.bottom, - ) + wp.rcNormalPosition.left, + wp.rcNormalPosition.top, + wp.rcNormalPosition.right, + wp.rcNormalPosition.bottom, + ) @property def _as_parameter_(self): @@ -661,40 +676,43 @@ def _as_parameter_(self): Compatibility with ctypes. Allows passing transparently a Point object to an API call. """ - wp = WINDOWPLACEMENT() - wp.length = sizeof(wp) - wp.flags = self.flags - wp.showCmd = self.showCmd - wp.ptMinPosition.x = self.ptMinPosition.x - wp.ptMinPosition.y = self.ptMinPosition.y - wp.ptMaxPosition.x = self.ptMaxPosition.x - wp.ptMaxPosition.y = self.ptMaxPosition.y - wp.rcNormalPosition.left = self.rcNormalPosition.left - wp.rcNormalPosition.top = self.rcNormalPosition.top - wp.rcNormalPosition.right = self.rcNormalPosition.right - wp.rcNormalPosition.bottom = self.rcNormalPosition.bottom + wp = WINDOWPLACEMENT() + wp.length = sizeof(wp) + wp.flags = self.flags + wp.showCmd = self.showCmd + wp.ptMinPosition.x = self.ptMinPosition.x + wp.ptMinPosition.y = self.ptMinPosition.y + wp.ptMaxPosition.x = self.ptMaxPosition.x + wp.ptMaxPosition.y = self.ptMaxPosition.y + wp.rcNormalPosition.left = self.rcNormalPosition.left + wp.rcNormalPosition.top = self.rcNormalPosition.top + wp.rcNormalPosition.right = self.rcNormalPosition.right + wp.rcNormalPosition.bottom = self.rcNormalPosition.bottom return wp -#--- user32.dll --------------------------------------------------------------- + +# --- user32.dll --------------------------------------------------------------- + # void WINAPI SetLastErrorEx( # __in DWORD dwErrCode, # __in DWORD dwType # ); -def SetLastErrorEx(dwErrCode, dwType = 0): +def SetLastErrorEx(dwErrCode, dwType=0): _SetLastErrorEx = windll.user32.SetLastErrorEx _SetLastErrorEx.argtypes = [DWORD, DWORD] - _SetLastErrorEx.restype = None + _SetLastErrorEx.restype = None _SetLastErrorEx(dwErrCode, dwType) + # HWND FindWindow( # LPCTSTR lpClassName, # LPCTSTR lpWindowName # ); -def FindWindowA(lpClassName = None, lpWindowName = None): +def FindWindowA(lpClassName=None, lpWindowName=None): _FindWindowA = windll.user32.FindWindowA _FindWindowA.argtypes = [LPSTR, LPSTR] - _FindWindowA.restype = HWND + _FindWindowA.restype = HWND hWnd = _FindWindowA(lpClassName, lpWindowName) if not hWnd: @@ -703,10 +721,11 @@ def FindWindowA(lpClassName = None, lpWindowName = None): raise ctypes.WinError(errcode) return hWnd -def FindWindowW(lpClassName = None, lpWindowName = None): + +def FindWindowW(lpClassName=None, lpWindowName=None): _FindWindowW = windll.user32.FindWindowW _FindWindowW.argtypes = [LPWSTR, LPWSTR] - _FindWindowW.restype = HWND + _FindWindowW.restype = HWND hWnd = _FindWindowW(lpClassName, lpWindowName) if not hWnd: @@ -715,18 +734,20 @@ def FindWindowW(lpClassName = None, lpWindowName = None): raise ctypes.WinError(errcode) return hWnd + FindWindow = GuessStringType(FindWindowA, FindWindowW) + # HWND WINAPI FindWindowEx( # __in_opt HWND hwndParent, # __in_opt HWND hwndChildAfter, # __in_opt LPCTSTR lpszClass, # __in_opt LPCTSTR lpszWindow # ); -def FindWindowExA(hwndParent = None, hwndChildAfter = None, lpClassName = None, lpWindowName = None): +def FindWindowExA(hwndParent=None, hwndChildAfter=None, lpClassName=None, lpWindowName=None): _FindWindowExA = windll.user32.FindWindowExA _FindWindowExA.argtypes = [HWND, HWND, LPSTR, LPSTR] - _FindWindowExA.restype = HWND + _FindWindowExA.restype = HWND hWnd = _FindWindowExA(hwndParent, hwndChildAfter, lpClassName, lpWindowName) if not hWnd: @@ -735,10 +756,11 @@ def FindWindowExA(hwndParent = None, hwndChildAfter = None, lpClassName = None, raise ctypes.WinError(errcode) return hWnd -def FindWindowExW(hwndParent = None, hwndChildAfter = None, lpClassName = None, lpWindowName = None): + +def FindWindowExW(hwndParent=None, hwndChildAfter=None, lpClassName=None, lpWindowName=None): _FindWindowExW = windll.user32.FindWindowExW _FindWindowExW.argtypes = [HWND, HWND, LPWSTR, LPWSTR] - _FindWindowExW.restype = HWND + _FindWindowExW.restype = HWND hWnd = _FindWindowExW(hwndParent, hwndChildAfter, lpClassName, lpWindowName) if not hWnd: @@ -747,8 +769,10 @@ def FindWindowExW(hwndParent = None, hwndChildAfter = None, lpClassName = None, raise ctypes.WinError(errcode) return hWnd + FindWindowEx = GuessStringType(FindWindowExA, FindWindowExW) + # int GetClassName( # HWND hWnd, # LPTSTR lpClassName, @@ -771,6 +795,7 @@ def GetClassNameA(hWnd): nMaxCount += 0x1000 return lpClassName.value + def GetClassNameW(hWnd): _GetClassNameW = windll.user32.GetClassNameW _GetClassNameW.argtypes = [HWND, LPWSTR, ctypes.c_int] @@ -779,7 +804,7 @@ def GetClassNameW(hWnd): nMaxCount = 0x1000 dwCharSize = sizeof(WCHAR) while 1: - lpClassName = ctypes.create_unicode_buffer(u"", nMaxCount) + lpClassName = ctypes.create_unicode_buffer("", nMaxCount) nCount = _GetClassNameW(hWnd, lpClassName, nMaxCount) if nCount == 0: raise ctypes.WinError() @@ -788,8 +813,10 @@ def GetClassNameW(hWnd): nMaxCount += 0x1000 return lpClassName.value + GetClassName = GuessStringType(GetClassNameA, GetClassNameW) + # int WINAPI GetWindowText( # __in HWND hWnd, # __out LPTSTR lpString, @@ -812,6 +839,7 @@ def GetWindowTextA(hWnd): nMaxCount += 0x1000 return lpString.value + def GetWindowTextW(hWnd): _GetWindowTextW = windll.user32.GetWindowTextW _GetWindowTextW.argtypes = [HWND, LPWSTR, ctypes.c_int] @@ -829,36 +857,41 @@ def GetWindowTextW(hWnd): nMaxCount += 0x1000 return lpString.value + GetWindowText = GuessStringType(GetWindowTextA, GetWindowTextW) + # BOOL WINAPI SetWindowText( # __in HWND hWnd, # __in_opt LPCTSTR lpString # ); -def SetWindowTextA(hWnd, lpString = None): +def SetWindowTextA(hWnd, lpString=None): _SetWindowTextA = windll.user32.SetWindowTextA _SetWindowTextA.argtypes = [HWND, LPSTR] - _SetWindowTextA.restype = bool + _SetWindowTextA.restype = bool _SetWindowTextA.errcheck = RaiseIfZero _SetWindowTextA(hWnd, lpString) -def SetWindowTextW(hWnd, lpString = None): + +def SetWindowTextW(hWnd, lpString=None): _SetWindowTextW = windll.user32.SetWindowTextW _SetWindowTextW.argtypes = [HWND, LPWSTR] - _SetWindowTextW.restype = bool + _SetWindowTextW.restype = bool _SetWindowTextW.errcheck = RaiseIfZero _SetWindowTextW(hWnd, lpString) + SetWindowText = GuessStringType(SetWindowTextA, SetWindowTextW) + # LONG GetWindowLong( # HWND hWnd, # int nIndex # ); -def GetWindowLongA(hWnd, nIndex = 0): +def GetWindowLongA(hWnd, nIndex=0): _GetWindowLongA = windll.user32.GetWindowLongA _GetWindowLongA.argtypes = [HWND, ctypes.c_int] - _GetWindowLongA.restype = DWORD + _GetWindowLongA.restype = DWORD SetLastError(ERROR_SUCCESS) retval = _GetWindowLongA(hWnd, nIndex) @@ -868,10 +901,11 @@ def GetWindowLongA(hWnd, nIndex = 0): raise ctypes.WinError(errcode) return retval -def GetWindowLongW(hWnd, nIndex = 0): + +def GetWindowLongW(hWnd, nIndex=0): _GetWindowLongW = windll.user32.GetWindowLongW _GetWindowLongW.argtypes = [HWND, ctypes.c_int] - _GetWindowLongW.restype = DWORD + _GetWindowLongW.restype = DWORD SetLastError(ERROR_SUCCESS) retval = _GetWindowLongW(hWnd, nIndex) @@ -881,6 +915,7 @@ def GetWindowLongW(hWnd, nIndex = 0): raise ctypes.WinError(errcode) return retval + GetWindowLong = DefaultStringType(GetWindowLongA, GetWindowLongW) # LONG_PTR WINAPI GetWindowLongPtr( @@ -889,17 +924,16 @@ def GetWindowLongW(hWnd, nIndex = 0): # ); if bits == 32: - GetWindowLongPtrA = GetWindowLongA GetWindowLongPtrW = GetWindowLongW - GetWindowLongPtr = GetWindowLong + GetWindowLongPtr = GetWindowLong else: - def GetWindowLongPtrA(hWnd, nIndex = 0): + def GetWindowLongPtrA(hWnd, nIndex=0): _GetWindowLongPtrA = windll.user32.GetWindowLongPtrA _GetWindowLongPtrA.argtypes = [HWND, ctypes.c_int] - _GetWindowLongPtrA.restype = SIZE_T + _GetWindowLongPtrA.restype = SIZE_T SetLastError(ERROR_SUCCESS) retval = _GetWindowLongPtrA(hWnd, nIndex) @@ -909,10 +943,10 @@ def GetWindowLongPtrA(hWnd, nIndex = 0): raise ctypes.WinError(errcode) return retval - def GetWindowLongPtrW(hWnd, nIndex = 0): + def GetWindowLongPtrW(hWnd, nIndex=0): _GetWindowLongPtrW = windll.user32.GetWindowLongPtrW _GetWindowLongPtrW.argtypes = [HWND, ctypes.c_int] - _GetWindowLongPtrW.restype = DWORD + _GetWindowLongPtrW.restype = DWORD SetLastError(ERROR_SUCCESS) retval = _GetWindowLongPtrW(hWnd, nIndex) @@ -930,10 +964,11 @@ def GetWindowLongPtrW(hWnd, nIndex = 0): # _In_ LONG dwNewLong # ); + def SetWindowLongA(hWnd, nIndex, dwNewLong): _SetWindowLongA = windll.user32.SetWindowLongA _SetWindowLongA.argtypes = [HWND, ctypes.c_int, DWORD] - _SetWindowLongA.restype = DWORD + _SetWindowLongA.restype = DWORD SetLastError(ERROR_SUCCESS) retval = _SetWindowLongA(hWnd, nIndex, dwNewLong) @@ -943,10 +978,11 @@ def SetWindowLongA(hWnd, nIndex, dwNewLong): raise ctypes.WinError(errcode) return retval + def SetWindowLongW(hWnd, nIndex, dwNewLong): _SetWindowLongW = windll.user32.SetWindowLongW _SetWindowLongW.argtypes = [HWND, ctypes.c_int, DWORD] - _SetWindowLongW.restype = DWORD + _SetWindowLongW.restype = DWORD SetLastError(ERROR_SUCCESS) retval = _SetWindowLongW(hWnd, nIndex, dwNewLong) @@ -956,6 +992,7 @@ def SetWindowLongW(hWnd, nIndex, dwNewLong): raise ctypes.WinError(errcode) return retval + SetWindowLong = DefaultStringType(SetWindowLongA, SetWindowLongW) # LONG_PTR WINAPI SetWindowLongPtr( @@ -965,17 +1002,16 @@ def SetWindowLongW(hWnd, nIndex, dwNewLong): # ); if bits == 32: - SetWindowLongPtrA = SetWindowLongA SetWindowLongPtrW = SetWindowLongW - SetWindowLongPtr = SetWindowLong + SetWindowLongPtr = SetWindowLong else: def SetWindowLongPtrA(hWnd, nIndex, dwNewLong): _SetWindowLongPtrA = windll.user32.SetWindowLongPtrA _SetWindowLongPtrA.argtypes = [HWND, ctypes.c_int, SIZE_T] - _SetWindowLongPtrA.restype = SIZE_T + _SetWindowLongPtrA.restype = SIZE_T SetLastError(ERROR_SUCCESS) retval = _SetWindowLongPtrA(hWnd, nIndex, dwNewLong) @@ -988,7 +1024,7 @@ def SetWindowLongPtrA(hWnd, nIndex, dwNewLong): def SetWindowLongPtrW(hWnd, nIndex, dwNewLong): _SetWindowLongPtrW = windll.user32.SetWindowLongPtrW _SetWindowLongPtrW.argtypes = [HWND, ctypes.c_int, SIZE_T] - _SetWindowLongPtrW.restype = SIZE_T + _SetWindowLongPtrW.restype = SIZE_T SetLastError(ERROR_SUCCESS) retval = _SetWindowLongPtrW(hWnd, nIndex, dwNewLong) @@ -1000,14 +1036,16 @@ def SetWindowLongPtrW(hWnd, nIndex, dwNewLong): SetWindowLongPtr = DefaultStringType(SetWindowLongPtrA, SetWindowLongPtrW) + # HWND GetShellWindow(VOID); def GetShellWindow(): _GetShellWindow = windll.user32.GetShellWindow _GetShellWindow.argtypes = [] - _GetShellWindow.restype = HWND + _GetShellWindow.restype = HWND _GetShellWindow.errcheck = RaiseIfZero return _GetShellWindow() + # DWORD GetWindowThreadProcessId( # HWND hWnd, # LPDWORD lpdwProcessId @@ -1015,13 +1053,14 @@ def GetShellWindow(): def GetWindowThreadProcessId(hWnd): _GetWindowThreadProcessId = windll.user32.GetWindowThreadProcessId _GetWindowThreadProcessId.argtypes = [HWND, LPDWORD] - _GetWindowThreadProcessId.restype = DWORD + _GetWindowThreadProcessId.restype = DWORD _GetWindowThreadProcessId.errcheck = RaiseIfZero dwProcessId = DWORD(0) dwThreadId = _GetWindowThreadProcessId(hWnd, byref(dwProcessId)) return (dwThreadId, dwProcessId.value) + # HWND WINAPI GetWindow( # __in HWND hwnd, # __in UINT uCmd @@ -1029,7 +1068,7 @@ def GetWindowThreadProcessId(hWnd): def GetWindow(hWnd, uCmd): _GetWindow = windll.user32.GetWindow _GetWindow.argtypes = [HWND, UINT] - _GetWindow.restype = HWND + _GetWindow.restype = HWND SetLastError(ERROR_SUCCESS) hWndTarget = _GetWindow(hWnd, uCmd) @@ -1039,13 +1078,14 @@ def GetWindow(hWnd, uCmd): raise ctypes.WinError(winerr) return hWndTarget + # HWND GetParent( # HWND hWnd # ); def GetParent(hWnd): _GetParent = windll.user32.GetParent _GetParent.argtypes = [HWND] - _GetParent.restype = HWND + _GetParent.restype = HWND SetLastError(ERROR_SUCCESS) hWndParent = _GetParent(hWnd) @@ -1055,14 +1095,15 @@ def GetParent(hWnd): raise ctypes.WinError(winerr) return hWndParent + # HWND WINAPI GetAncestor( # __in HWND hwnd, # __in UINT gaFlags # ); -def GetAncestor(hWnd, gaFlags = GA_PARENT): +def GetAncestor(hWnd, gaFlags=GA_PARENT): _GetAncestor = windll.user32.GetAncestor _GetAncestor.argtypes = [HWND, UINT] - _GetAncestor.restype = HWND + _GetAncestor.restype = HWND SetLastError(ERROR_SUCCESS) hWndParent = _GetAncestor(hWnd, gaFlags) @@ -1072,118 +1113,131 @@ def GetAncestor(hWnd, gaFlags = GA_PARENT): raise ctypes.WinError(winerr) return hWndParent + # BOOL EnableWindow( # HWND hWnd, # BOOL bEnable # ); -def EnableWindow(hWnd, bEnable = True): +def EnableWindow(hWnd, bEnable=True): _EnableWindow = windll.user32.EnableWindow _EnableWindow.argtypes = [HWND, BOOL] - _EnableWindow.restype = bool + _EnableWindow.restype = bool return _EnableWindow(hWnd, bool(bEnable)) + # BOOL ShowWindow( # HWND hWnd, # int nCmdShow # ); -def ShowWindow(hWnd, nCmdShow = SW_SHOW): +def ShowWindow(hWnd, nCmdShow=SW_SHOW): _ShowWindow = windll.user32.ShowWindow _ShowWindow.argtypes = [HWND, ctypes.c_int] - _ShowWindow.restype = bool + _ShowWindow.restype = bool return _ShowWindow(hWnd, nCmdShow) + # BOOL ShowWindowAsync( # HWND hWnd, # int nCmdShow # ); -def ShowWindowAsync(hWnd, nCmdShow = SW_SHOW): +def ShowWindowAsync(hWnd, nCmdShow=SW_SHOW): _ShowWindowAsync = windll.user32.ShowWindowAsync _ShowWindowAsync.argtypes = [HWND, ctypes.c_int] - _ShowWindowAsync.restype = bool + _ShowWindowAsync.restype = bool return _ShowWindowAsync(hWnd, nCmdShow) + # HWND GetDesktopWindow(VOID); def GetDesktopWindow(): _GetDesktopWindow = windll.user32.GetDesktopWindow _GetDesktopWindow.argtypes = [] - _GetDesktopWindow.restype = HWND + _GetDesktopWindow.restype = HWND _GetDesktopWindow.errcheck = RaiseIfZero return _GetDesktopWindow() + # HWND GetForegroundWindow(VOID); def GetForegroundWindow(): _GetForegroundWindow = windll.user32.GetForegroundWindow _GetForegroundWindow.argtypes = [] - _GetForegroundWindow.restype = HWND + _GetForegroundWindow.restype = HWND _GetForegroundWindow.errcheck = RaiseIfZero return _GetForegroundWindow() + # BOOL IsWindow( # HWND hWnd # ); def IsWindow(hWnd): _IsWindow = windll.user32.IsWindow _IsWindow.argtypes = [HWND] - _IsWindow.restype = bool + _IsWindow.restype = bool return _IsWindow(hWnd) + # BOOL IsWindowVisible( # HWND hWnd # ); def IsWindowVisible(hWnd): _IsWindowVisible = windll.user32.IsWindowVisible _IsWindowVisible.argtypes = [HWND] - _IsWindowVisible.restype = bool + _IsWindowVisible.restype = bool return _IsWindowVisible(hWnd) + # BOOL IsWindowEnabled( # HWND hWnd # ); def IsWindowEnabled(hWnd): _IsWindowEnabled = windll.user32.IsWindowEnabled _IsWindowEnabled.argtypes = [HWND] - _IsWindowEnabled.restype = bool + _IsWindowEnabled.restype = bool return _IsWindowEnabled(hWnd) + # BOOL IsZoomed( # HWND hWnd # ); def IsZoomed(hWnd): _IsZoomed = windll.user32.IsZoomed _IsZoomed.argtypes = [HWND] - _IsZoomed.restype = bool + _IsZoomed.restype = bool return _IsZoomed(hWnd) + # BOOL IsIconic( # HWND hWnd # ); def IsIconic(hWnd): _IsIconic = windll.user32.IsIconic _IsIconic.argtypes = [HWND] - _IsIconic.restype = bool + _IsIconic.restype = bool return _IsIconic(hWnd) + # BOOL IsChild( # HWND hWnd # ); def IsChild(hWnd): _IsChild = windll.user32.IsChild _IsChild.argtypes = [HWND] - _IsChild.restype = bool + _IsChild.restype = bool return _IsChild(hWnd) + # HWND WindowFromPoint( # POINT Point # ); def WindowFromPoint(point): _WindowFromPoint = windll.user32.WindowFromPoint _WindowFromPoint.argtypes = [POINT] - _WindowFromPoint.restype = HWND + _WindowFromPoint.restype = HWND _WindowFromPoint.errcheck = RaiseIfZero if isinstance(point, tuple): point = POINT(*point) return _WindowFromPoint(point) + # HWND ChildWindowFromPoint( # HWND hWndParent, # POINT Point @@ -1191,25 +1245,27 @@ def WindowFromPoint(point): def ChildWindowFromPoint(hWndParent, point): _ChildWindowFromPoint = windll.user32.ChildWindowFromPoint _ChildWindowFromPoint.argtypes = [HWND, POINT] - _ChildWindowFromPoint.restype = HWND + _ChildWindowFromPoint.restype = HWND _ChildWindowFromPoint.errcheck = RaiseIfZero if isinstance(point, tuple): point = POINT(*point) return _ChildWindowFromPoint(hWndParent, point) -#HWND RealChildWindowFromPoint( + +# HWND RealChildWindowFromPoint( # HWND hwndParent, # POINT ptParentClientCoords -#); +# ); def RealChildWindowFromPoint(hWndParent, ptParentClientCoords): _RealChildWindowFromPoint = windll.user32.RealChildWindowFromPoint _RealChildWindowFromPoint.argtypes = [HWND, POINT] - _RealChildWindowFromPoint.restype = HWND + _RealChildWindowFromPoint.restype = HWND _RealChildWindowFromPoint.errcheck = RaiseIfZero if isinstance(ptParentClientCoords, tuple): ptParentClientCoords = POINT(*ptParentClientCoords) return _RealChildWindowFromPoint(hWndParent, ptParentClientCoords) + # BOOL ScreenToClient( # __in HWND hWnd, # LPPOINT lpPoint @@ -1217,7 +1273,7 @@ def RealChildWindowFromPoint(hWndParent, ptParentClientCoords): def ScreenToClient(hWnd, lpPoint): _ScreenToClient = windll.user32.ScreenToClient _ScreenToClient.argtypes = [HWND, LPPOINT] - _ScreenToClient.restype = bool + _ScreenToClient.restype = bool _ScreenToClient.errcheck = RaiseIfZero if isinstance(lpPoint, tuple): @@ -1227,6 +1283,7 @@ def ScreenToClient(hWnd, lpPoint): _ScreenToClient(hWnd, byref(lpPoint)) return Point(lpPoint.x, lpPoint.y) + # BOOL ClientToScreen( # HWND hWnd, # LPPOINT lpPoint @@ -1234,7 +1291,7 @@ def ScreenToClient(hWnd, lpPoint): def ClientToScreen(hWnd, lpPoint): _ClientToScreen = windll.user32.ClientToScreen _ClientToScreen.argtypes = [HWND, LPPOINT] - _ClientToScreen.restype = bool + _ClientToScreen.restype = bool _ClientToScreen.errcheck = RaiseIfZero if isinstance(lpPoint, tuple): @@ -1244,6 +1301,7 @@ def ClientToScreen(hWnd, lpPoint): _ClientToScreen(hWnd, byref(lpPoint)) return Point(lpPoint.x, lpPoint.y) + # int MapWindowPoints( # __in HWND hWndFrom, # __in HWND hWndTo, @@ -1253,30 +1311,32 @@ def ClientToScreen(hWnd, lpPoint): def MapWindowPoints(hWndFrom, hWndTo, lpPoints): _MapWindowPoints = windll.user32.MapWindowPoints _MapWindowPoints.argtypes = [HWND, HWND, LPPOINT, UINT] - _MapWindowPoints.restype = ctypes.c_int + _MapWindowPoints.restype = ctypes.c_int - cPoints = len(lpPoints) - lpPoints = (POINT * cPoints)(* lpPoints) + cPoints = len(lpPoints) + lpPoints = (POINT * cPoints)(*lpPoints) SetLastError(ERROR_SUCCESS) - number = _MapWindowPoints(hWndFrom, hWndTo, byref(lpPoints), cPoints) + number = _MapWindowPoints(hWndFrom, hWndTo, byref(lpPoints), cPoints) if number == 0: errcode = GetLastError() if errcode != ERROR_SUCCESS: raise ctypes.WinError(errcode) x_delta = number & 0xFFFF y_delta = (number >> 16) & 0xFFFF - return x_delta, y_delta, [ (Point.x, Point.y) for Point in lpPoints ] + return x_delta, y_delta, [(Point.x, Point.y) for Point in lpPoints] -#BOOL SetForegroundWindow( + +# BOOL SetForegroundWindow( # HWND hWnd -#); +# ); def SetForegroundWindow(hWnd): _SetForegroundWindow = windll.user32.SetForegroundWindow _SetForegroundWindow.argtypes = [HWND] - _SetForegroundWindow.restype = bool + _SetForegroundWindow.restype = bool _SetForegroundWindow.errcheck = RaiseIfZero return _SetForegroundWindow(hWnd) + # BOOL GetWindowPlacement( # HWND hWnd, # WINDOWPLACEMENT *lpwndpl @@ -1284,7 +1344,7 @@ def SetForegroundWindow(hWnd): def GetWindowPlacement(hWnd): _GetWindowPlacement = windll.user32.GetWindowPlacement _GetWindowPlacement.argtypes = [HWND, PWINDOWPLACEMENT] - _GetWindowPlacement.restype = bool + _GetWindowPlacement.restype = bool _GetWindowPlacement.errcheck = RaiseIfZero lpwndpl = WINDOWPLACEMENT() @@ -1292,6 +1352,7 @@ def GetWindowPlacement(hWnd): _GetWindowPlacement(hWnd, byref(lpwndpl)) return WindowPlacement(lpwndpl) + # BOOL SetWindowPlacement( # HWND hWnd, # WINDOWPLACEMENT *lpwndpl @@ -1299,13 +1360,14 @@ def GetWindowPlacement(hWnd): def SetWindowPlacement(hWnd, lpwndpl): _SetWindowPlacement = windll.user32.SetWindowPlacement _SetWindowPlacement.argtypes = [HWND, PWINDOWPLACEMENT] - _SetWindowPlacement.restype = bool + _SetWindowPlacement.restype = bool _SetWindowPlacement.errcheck = RaiseIfZero if isinstance(lpwndpl, WINDOWPLACEMENT): lpwndpl.length = sizeof(lpwndpl) _SetWindowPlacement(hWnd, byref(lpwndpl)) + # BOOL WINAPI GetWindowRect( # __in HWND hWnd, # __out LPRECT lpRect @@ -1313,13 +1375,14 @@ def SetWindowPlacement(hWnd, lpwndpl): def GetWindowRect(hWnd): _GetWindowRect = windll.user32.GetWindowRect _GetWindowRect.argtypes = [HWND, LPRECT] - _GetWindowRect.restype = bool + _GetWindowRect.restype = bool _GetWindowRect.errcheck = RaiseIfZero lpRect = RECT() _GetWindowRect(hWnd, byref(lpRect)) return Rect(lpRect.left, lpRect.top, lpRect.right, lpRect.bottom) + # BOOL WINAPI GetClientRect( # __in HWND hWnd, # __out LPRECT lpRect @@ -1327,28 +1390,30 @@ def GetWindowRect(hWnd): def GetClientRect(hWnd): _GetClientRect = windll.user32.GetClientRect _GetClientRect.argtypes = [HWND, LPRECT] - _GetClientRect.restype = bool + _GetClientRect.restype = bool _GetClientRect.errcheck = RaiseIfZero lpRect = RECT() _GetClientRect(hWnd, byref(lpRect)) return Rect(lpRect.left, lpRect.top, lpRect.right, lpRect.bottom) -#BOOL MoveWindow( + +# BOOL MoveWindow( # HWND hWnd, # int X, # int Y, # int nWidth, # int nHeight, # BOOL bRepaint -#); -def MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint = True): +# ); +def MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint=True): _MoveWindow = windll.user32.MoveWindow _MoveWindow.argtypes = [HWND, ctypes.c_int, ctypes.c_int, ctypes.c_int, ctypes.c_int, BOOL] - _MoveWindow.restype = bool + _MoveWindow.restype = bool _MoveWindow.errcheck = RaiseIfZero _MoveWindow(hWnd, X, Y, nWidth, nHeight, bool(bRepaint)) + # BOOL GetGUIThreadInfo( # DWORD idThread, # LPGUITHREADINFO lpgui @@ -1356,20 +1421,22 @@ def MoveWindow(hWnd, X, Y, nWidth, nHeight, bRepaint = True): def GetGUIThreadInfo(idThread): _GetGUIThreadInfo = windll.user32.GetGUIThreadInfo _GetGUIThreadInfo.argtypes = [DWORD, LPGUITHREADINFO] - _GetGUIThreadInfo.restype = bool + _GetGUIThreadInfo.restype = bool _GetGUIThreadInfo.errcheck = RaiseIfZero gui = GUITHREADINFO() _GetGUIThreadInfo(idThread, byref(gui)) return gui + # BOOL CALLBACK EnumWndProc( # HWND hwnd, # LPARAM lParam # ); -class __EnumWndProc (__WindowEnumerator): +class __EnumWndProc(__WindowEnumerator): pass + # BOOL EnumWindows( # WNDENUMPROC lpEnumFunc, # LPARAM lParam @@ -1377,7 +1444,7 @@ class __EnumWndProc (__WindowEnumerator): def EnumWindows(): _EnumWindows = windll.user32.EnumWindows _EnumWindows.argtypes = [WNDENUMPROC, LPARAM] - _EnumWindows.restype = bool + _EnumWindows.restype = bool EnumFunc = __EnumWndProc() lpEnumFunc = WNDENUMPROC(EnumFunc) @@ -1387,13 +1454,15 @@ def EnumWindows(): raise ctypes.WinError(errcode) return EnumFunc.hwnd + # BOOL CALLBACK EnumThreadWndProc( # HWND hwnd, # LPARAM lParam # ); -class __EnumThreadWndProc (__WindowEnumerator): +class __EnumThreadWndProc(__WindowEnumerator): pass + # BOOL EnumThreadWindows( # DWORD dwThreadId, # WNDENUMPROC lpfn, @@ -1402,7 +1471,7 @@ class __EnumThreadWndProc (__WindowEnumerator): def EnumThreadWindows(dwThreadId): _EnumThreadWindows = windll.user32.EnumThreadWindows _EnumThreadWindows.argtypes = [DWORD, WNDENUMPROC, LPARAM] - _EnumThreadWindows.restype = bool + _EnumThreadWindows.restype = bool fn = __EnumThreadWndProc() lpfn = WNDENUMPROC(fn) @@ -1412,22 +1481,24 @@ def EnumThreadWindows(dwThreadId): raise ctypes.WinError(errcode) return fn.hwnd + # BOOL CALLBACK EnumChildProc( # HWND hwnd, # LPARAM lParam # ); -class __EnumChildProc (__WindowEnumerator): +class __EnumChildProc(__WindowEnumerator): pass + # BOOL EnumChildWindows( # HWND hWndParent, # WNDENUMPROC lpEnumFunc, # LPARAM lParam # ); -def EnumChildWindows(hWndParent = NULL): +def EnumChildWindows(hWndParent=NULL): _EnumChildWindows = windll.user32.EnumChildWindows _EnumChildWindows.argtypes = [HWND, WNDENUMPROC, LPARAM] - _EnumChildWindows.restype = bool + _EnumChildWindows.restype = bool EnumFunc = __EnumChildProc() lpEnumFunc = WNDENUMPROC(EnumFunc) @@ -1438,88 +1509,98 @@ def EnumChildWindows(hWndParent = NULL): raise ctypes.WinError(errcode) return EnumFunc.hwnd + # LRESULT SendMessage( # HWND hWnd, # UINT Msg, # WPARAM wParam, # LPARAM lParam # ); -def SendMessageA(hWnd, Msg, wParam = 0, lParam = 0): +def SendMessageA(hWnd, Msg, wParam=0, lParam=0): _SendMessageA = windll.user32.SendMessageA _SendMessageA.argtypes = [HWND, UINT, WPARAM, LPARAM] - _SendMessageA.restype = LRESULT + _SendMessageA.restype = LRESULT wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) return _SendMessageA(hWnd, Msg, wParam, lParam) -def SendMessageW(hWnd, Msg, wParam = 0, lParam = 0): + +def SendMessageW(hWnd, Msg, wParam=0, lParam=0): _SendMessageW = windll.user32.SendMessageW _SendMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM] - _SendMessageW.restype = LRESULT + _SendMessageW.restype = LRESULT wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) return _SendMessageW(hWnd, Msg, wParam, lParam) + SendMessage = GuessStringType(SendMessageA, SendMessageW) + # BOOL PostMessage( # HWND hWnd, # UINT Msg, # WPARAM wParam, # LPARAM lParam # ); -def PostMessageA(hWnd, Msg, wParam = 0, lParam = 0): +def PostMessageA(hWnd, Msg, wParam=0, lParam=0): _PostMessageA = windll.user32.PostMessageA _PostMessageA.argtypes = [HWND, UINT, WPARAM, LPARAM] - _PostMessageA.restype = bool + _PostMessageA.restype = bool _PostMessageA.errcheck = RaiseIfZero wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) _PostMessageA(hWnd, Msg, wParam, lParam) -def PostMessageW(hWnd, Msg, wParam = 0, lParam = 0): + +def PostMessageW(hWnd, Msg, wParam=0, lParam=0): _PostMessageW = windll.user32.PostMessageW _PostMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM] - _PostMessageW.restype = bool + _PostMessageW.restype = bool _PostMessageW.errcheck = RaiseIfZero wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) _PostMessageW(hWnd, Msg, wParam, lParam) + PostMessage = GuessStringType(PostMessageA, PostMessageW) + # BOOL PostThreadMessage( # DWORD idThread, # UINT Msg, # WPARAM wParam, # LPARAM lParam # ); -def PostThreadMessageA(idThread, Msg, wParam = 0, lParam = 0): +def PostThreadMessageA(idThread, Msg, wParam=0, lParam=0): _PostThreadMessageA = windll.user32.PostThreadMessageA _PostThreadMessageA.argtypes = [DWORD, UINT, WPARAM, LPARAM] - _PostThreadMessageA.restype = bool + _PostThreadMessageA.restype = bool _PostThreadMessageA.errcheck = RaiseIfZero wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) _PostThreadMessageA(idThread, Msg, wParam, lParam) -def PostThreadMessageW(idThread, Msg, wParam = 0, lParam = 0): + +def PostThreadMessageW(idThread, Msg, wParam=0, lParam=0): _PostThreadMessageW = windll.user32.PostThreadMessageW _PostThreadMessageW.argtypes = [DWORD, UINT, WPARAM, LPARAM] - _PostThreadMessageW.restype = bool + _PostThreadMessageW.restype = bool _PostThreadMessageW.errcheck = RaiseIfZero wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) _PostThreadMessageW(idThread, Msg, wParam, lParam) + PostThreadMessage = GuessStringType(PostThreadMessageA, PostThreadMessageW) + # LRESULT c( # HWND hWnd, # UINT Msg, @@ -1529,10 +1610,10 @@ def PostThreadMessageW(idThread, Msg, wParam = 0, lParam = 0): # UINT uTimeout, # PDWORD_PTR lpdwResult # ); -def SendMessageTimeoutA(hWnd, Msg, wParam = 0, lParam = 0, fuFlags = 0, uTimeout = 0): +def SendMessageTimeoutA(hWnd, Msg, wParam=0, lParam=0, fuFlags=0, uTimeout=0): _SendMessageTimeoutA = windll.user32.SendMessageTimeoutA _SendMessageTimeoutA.argtypes = [HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR] - _SendMessageTimeoutA.restype = LRESULT + _SendMessageTimeoutA.restype = LRESULT _SendMessageTimeoutA.errcheck = RaiseIfZero wParam = MAKE_WPARAM(wParam) @@ -1541,10 +1622,11 @@ def SendMessageTimeoutA(hWnd, Msg, wParam = 0, lParam = 0, fuFlags = 0, uTimeout _SendMessageTimeoutA(hWnd, Msg, wParam, lParam, fuFlags, uTimeout, byref(dwResult)) return dwResult.value -def SendMessageTimeoutW(hWnd, Msg, wParam = 0, lParam = 0): + +def SendMessageTimeoutW(hWnd, Msg, wParam=0, lParam=0): _SendMessageTimeoutW = windll.user32.SendMessageTimeoutW _SendMessageTimeoutW.argtypes = [HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR] - _SendMessageTimeoutW.restype = LRESULT + _SendMessageTimeoutW.restype = LRESULT _SendMessageTimeoutW.errcheck = RaiseIfZero wParam = MAKE_WPARAM(wParam) @@ -1553,36 +1635,41 @@ def SendMessageTimeoutW(hWnd, Msg, wParam = 0, lParam = 0): _SendMessageTimeoutW(hWnd, Msg, wParam, lParam, fuFlags, uTimeout, byref(dwResult)) return dwResult.value + SendMessageTimeout = GuessStringType(SendMessageTimeoutA, SendMessageTimeoutW) + # BOOL SendNotifyMessage( # HWND hWnd, # UINT Msg, # WPARAM wParam, # LPARAM lParam # ); -def SendNotifyMessageA(hWnd, Msg, wParam = 0, lParam = 0): +def SendNotifyMessageA(hWnd, Msg, wParam=0, lParam=0): _SendNotifyMessageA = windll.user32.SendNotifyMessageA _SendNotifyMessageA.argtypes = [HWND, UINT, WPARAM, LPARAM] - _SendNotifyMessageA.restype = bool + _SendNotifyMessageA.restype = bool _SendNotifyMessageA.errcheck = RaiseIfZero wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) _SendNotifyMessageA(hWnd, Msg, wParam, lParam) -def SendNotifyMessageW(hWnd, Msg, wParam = 0, lParam = 0): + +def SendNotifyMessageW(hWnd, Msg, wParam=0, lParam=0): _SendNotifyMessageW = windll.user32.SendNotifyMessageW _SendNotifyMessageW.argtypes = [HWND, UINT, WPARAM, LPARAM] - _SendNotifyMessageW.restype = bool + _SendNotifyMessageW.restype = bool _SendNotifyMessageW.errcheck = RaiseIfZero wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) _SendNotifyMessageW(hWnd, Msg, wParam, lParam) + SendNotifyMessage = GuessStringType(SendNotifyMessageA, SendNotifyMessageW) + # LRESULT SendDlgItemMessage( # HWND hDlg, # int nIDDlgItem, @@ -1590,78 +1677,88 @@ def SendNotifyMessageW(hWnd, Msg, wParam = 0, lParam = 0): # WPARAM wParam, # LPARAM lParam # ); -def SendDlgItemMessageA(hDlg, nIDDlgItem, Msg, wParam = 0, lParam = 0): +def SendDlgItemMessageA(hDlg, nIDDlgItem, Msg, wParam=0, lParam=0): _SendDlgItemMessageA = windll.user32.SendDlgItemMessageA _SendDlgItemMessageA.argtypes = [HWND, ctypes.c_int, UINT, WPARAM, LPARAM] - _SendDlgItemMessageA.restype = LRESULT + _SendDlgItemMessageA.restype = LRESULT wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) return _SendDlgItemMessageA(hDlg, nIDDlgItem, Msg, wParam, lParam) -def SendDlgItemMessageW(hDlg, nIDDlgItem, Msg, wParam = 0, lParam = 0): + +def SendDlgItemMessageW(hDlg, nIDDlgItem, Msg, wParam=0, lParam=0): _SendDlgItemMessageW = windll.user32.SendDlgItemMessageW _SendDlgItemMessageW.argtypes = [HWND, ctypes.c_int, UINT, WPARAM, LPARAM] - _SendDlgItemMessageW.restype = LRESULT + _SendDlgItemMessageW.restype = LRESULT wParam = MAKE_WPARAM(wParam) lParam = MAKE_LPARAM(lParam) return _SendDlgItemMessageW(hDlg, nIDDlgItem, Msg, wParam, lParam) + SendDlgItemMessage = GuessStringType(SendDlgItemMessageA, SendDlgItemMessageW) + # DWORD WINAPI WaitForInputIdle( # _In_ HANDLE hProcess, # _In_ DWORD dwMilliseconds # ); -def WaitForInputIdle(hProcess, dwMilliseconds = INFINITE): +def WaitForInputIdle(hProcess, dwMilliseconds=INFINITE): _WaitForInputIdle = windll.user32.WaitForInputIdle _WaitForInputIdle.argtypes = [HANDLE, DWORD] - _WaitForInputIdle.restype = DWORD + _WaitForInputIdle.restype = DWORD r = _WaitForInputIdle(hProcess, dwMilliseconds) if r == WAIT_FAILED: raise ctypes.WinError() return r + # UINT RegisterWindowMessage( # LPCTSTR lpString # ); def RegisterWindowMessageA(lpString): _RegisterWindowMessageA = windll.user32.RegisterWindowMessageA _RegisterWindowMessageA.argtypes = [LPSTR] - _RegisterWindowMessageA.restype = UINT + _RegisterWindowMessageA.restype = UINT _RegisterWindowMessageA.errcheck = RaiseIfZero return _RegisterWindowMessageA(lpString) + def RegisterWindowMessageW(lpString): _RegisterWindowMessageW = windll.user32.RegisterWindowMessageW _RegisterWindowMessageW.argtypes = [LPWSTR] - _RegisterWindowMessageW.restype = UINT + _RegisterWindowMessageW.restype = UINT _RegisterWindowMessageW.errcheck = RaiseIfZero return _RegisterWindowMessageW(lpString) + RegisterWindowMessage = GuessStringType(RegisterWindowMessageA, RegisterWindowMessageW) + # UINT RegisterClipboardFormat( # LPCTSTR lpString # ); def RegisterClipboardFormatA(lpString): _RegisterClipboardFormatA = windll.user32.RegisterClipboardFormatA _RegisterClipboardFormatA.argtypes = [LPSTR] - _RegisterClipboardFormatA.restype = UINT + _RegisterClipboardFormatA.restype = UINT _RegisterClipboardFormatA.errcheck = RaiseIfZero return _RegisterClipboardFormatA(lpString) + def RegisterClipboardFormatW(lpString): _RegisterClipboardFormatW = windll.user32.RegisterClipboardFormatW _RegisterClipboardFormatW.argtypes = [LPWSTR] - _RegisterClipboardFormatW.restype = UINT + _RegisterClipboardFormatW.restype = UINT _RegisterClipboardFormatW.errcheck = RaiseIfZero return _RegisterClipboardFormatW(lpString) + RegisterClipboardFormat = GuessStringType(RegisterClipboardFormatA, RegisterClipboardFormatW) + # HANDLE WINAPI GetProp( # __in HWND hWnd, # __in LPCTSTR lpString @@ -1669,17 +1766,20 @@ def RegisterClipboardFormatW(lpString): def GetPropA(hWnd, lpString): _GetPropA = windll.user32.GetPropA _GetPropA.argtypes = [HWND, LPSTR] - _GetPropA.restype = HANDLE + _GetPropA.restype = HANDLE return _GetPropA(hWnd, lpString) + def GetPropW(hWnd, lpString): _GetPropW = windll.user32.GetPropW _GetPropW.argtypes = [HWND, LPWSTR] - _GetPropW.restype = HANDLE + _GetPropW.restype = HANDLE return _GetPropW(hWnd, lpString) + GetProp = GuessStringType(GetPropA, GetPropW) + # BOOL WINAPI SetProp( # __in HWND hWnd, # __in LPCTSTR lpString, @@ -1688,19 +1788,22 @@ def GetPropW(hWnd, lpString): def SetPropA(hWnd, lpString, hData): _SetPropA = windll.user32.SetPropA _SetPropA.argtypes = [HWND, LPSTR, HANDLE] - _SetPropA.restype = BOOL + _SetPropA.restype = BOOL _SetPropA.errcheck = RaiseIfZero _SetPropA(hWnd, lpString, hData) + def SetPropW(hWnd, lpString, hData): _SetPropW = windll.user32.SetPropW _SetPropW.argtypes = [HWND, LPWSTR, HANDLE] - _SetPropW.restype = BOOL + _SetPropW.restype = BOOL _SetPropW.errcheck = RaiseIfZero _SetPropW(hWnd, lpString, hData) + SetProp = GuessStringType(SetPropA, SetPropW) + # HANDLE WINAPI RemoveProp( # __in HWND hWnd, # __in LPCTSTR lpString @@ -1708,20 +1811,22 @@ def SetPropW(hWnd, lpString, hData): def RemovePropA(hWnd, lpString): _RemovePropA = windll.user32.RemovePropA _RemovePropA.argtypes = [HWND, LPSTR] - _RemovePropA.restype = HANDLE + _RemovePropA.restype = HANDLE return _RemovePropA(hWnd, lpString) + def RemovePropW(hWnd, lpString): _RemovePropW = windll.user32.RemovePropW _RemovePropW.argtypes = [HWND, LPWSTR] - _RemovePropW.restype = HANDLE + _RemovePropW.restype = HANDLE return _RemovePropW(hWnd, lpString) + RemoveProp = GuessStringType(RemovePropA, RemovePropW) -#============================================================================== +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/version.py b/pydevd_attach_to_process/winappdbg/win32/version.py index 19b6d53c0..556bbeb99 100644 --- a/pydevd_attach_to_process/winappdbg/win32/version.py +++ b/pydevd_attach_to_process/winappdbg/win32/version.py @@ -38,79 +38,80 @@ from winappdbg.win32.defines import * -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== - -#--- NTDDI version ------------------------------------------------------------ - -NTDDI_WIN8 = 0x06020000 -NTDDI_WIN7SP1 = 0x06010100 -NTDDI_WIN7 = 0x06010000 -NTDDI_WS08 = 0x06000100 -NTDDI_VISTASP1 = 0x06000100 -NTDDI_VISTA = 0x06000000 -NTDDI_LONGHORN = NTDDI_VISTA -NTDDI_WS03SP2 = 0x05020200 -NTDDI_WS03SP1 = 0x05020100 -NTDDI_WS03 = 0x05020000 -NTDDI_WINXPSP3 = 0x05010300 -NTDDI_WINXPSP2 = 0x05010200 -NTDDI_WINXPSP1 = 0x05010100 -NTDDI_WINXP = 0x05010000 -NTDDI_WIN2KSP4 = 0x05000400 -NTDDI_WIN2KSP3 = 0x05000300 -NTDDI_WIN2KSP2 = 0x05000200 -NTDDI_WIN2KSP1 = 0x05000100 -NTDDI_WIN2K = 0x05000000 -NTDDI_WINNT4 = 0x04000000 - -OSVERSION_MASK = 0xFFFF0000 -SPVERSION_MASK = 0x0000FF00 +# ============================================================================== + +# --- NTDDI version ------------------------------------------------------------ + +NTDDI_WIN8 = 0x06020000 +NTDDI_WIN7SP1 = 0x06010100 +NTDDI_WIN7 = 0x06010000 +NTDDI_WS08 = 0x06000100 +NTDDI_VISTASP1 = 0x06000100 +NTDDI_VISTA = 0x06000000 +NTDDI_LONGHORN = NTDDI_VISTA +NTDDI_WS03SP2 = 0x05020200 +NTDDI_WS03SP1 = 0x05020100 +NTDDI_WS03 = 0x05020000 +NTDDI_WINXPSP3 = 0x05010300 +NTDDI_WINXPSP2 = 0x05010200 +NTDDI_WINXPSP1 = 0x05010100 +NTDDI_WINXP = 0x05010000 +NTDDI_WIN2KSP4 = 0x05000400 +NTDDI_WIN2KSP3 = 0x05000300 +NTDDI_WIN2KSP2 = 0x05000200 +NTDDI_WIN2KSP1 = 0x05000100 +NTDDI_WIN2K = 0x05000000 +NTDDI_WINNT4 = 0x04000000 + +OSVERSION_MASK = 0xFFFF0000 +SPVERSION_MASK = 0x0000FF00 SUBVERSION_MASK = 0x000000FF -#--- OSVERSIONINFO and OSVERSIONINFOEX structures and constants --------------- - -VER_PLATFORM_WIN32s = 0 -VER_PLATFORM_WIN32_WINDOWS = 1 -VER_PLATFORM_WIN32_NT = 2 - -VER_SUITE_BACKOFFICE = 0x00000004 -VER_SUITE_BLADE = 0x00000400 -VER_SUITE_COMPUTE_SERVER = 0x00004000 -VER_SUITE_DATACENTER = 0x00000080 -VER_SUITE_ENTERPRISE = 0x00000002 -VER_SUITE_EMBEDDEDNT = 0x00000040 -VER_SUITE_PERSONAL = 0x00000200 -VER_SUITE_SINGLEUSERTS = 0x00000100 -VER_SUITE_SMALLBUSINESS = 0x00000001 -VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020 -VER_SUITE_STORAGE_SERVER = 0x00002000 -VER_SUITE_TERMINAL = 0x00000010 -VER_SUITE_WH_SERVER = 0x00008000 - -VER_NT_DOMAIN_CONTROLLER = 0x0000002 -VER_NT_SERVER = 0x0000003 -VER_NT_WORKSTATION = 0x0000001 - -VER_BUILDNUMBER = 0x0000004 -VER_MAJORVERSION = 0x0000002 -VER_MINORVERSION = 0x0000001 -VER_PLATFORMID = 0x0000008 -VER_PRODUCT_TYPE = 0x0000080 -VER_SERVICEPACKMAJOR = 0x0000020 -VER_SERVICEPACKMINOR = 0x0000010 -VER_SUITENAME = 0x0000040 - -VER_EQUAL = 1 -VER_GREATER = 2 -VER_GREATER_EQUAL = 3 -VER_LESS = 4 -VER_LESS_EQUAL = 5 -VER_AND = 6 -VER_OR = 7 +# --- OSVERSIONINFO and OSVERSIONINFOEX structures and constants --------------- + +VER_PLATFORM_WIN32s = 0 +VER_PLATFORM_WIN32_WINDOWS = 1 +VER_PLATFORM_WIN32_NT = 2 + +VER_SUITE_BACKOFFICE = 0x00000004 +VER_SUITE_BLADE = 0x00000400 +VER_SUITE_COMPUTE_SERVER = 0x00004000 +VER_SUITE_DATACENTER = 0x00000080 +VER_SUITE_ENTERPRISE = 0x00000002 +VER_SUITE_EMBEDDEDNT = 0x00000040 +VER_SUITE_PERSONAL = 0x00000200 +VER_SUITE_SINGLEUSERTS = 0x00000100 +VER_SUITE_SMALLBUSINESS = 0x00000001 +VER_SUITE_SMALLBUSINESS_RESTRICTED = 0x00000020 +VER_SUITE_STORAGE_SERVER = 0x00002000 +VER_SUITE_TERMINAL = 0x00000010 +VER_SUITE_WH_SERVER = 0x00008000 + +VER_NT_DOMAIN_CONTROLLER = 0x0000002 +VER_NT_SERVER = 0x0000003 +VER_NT_WORKSTATION = 0x0000001 + +VER_BUILDNUMBER = 0x0000004 +VER_MAJORVERSION = 0x0000002 +VER_MINORVERSION = 0x0000001 +VER_PLATFORMID = 0x0000008 +VER_PRODUCT_TYPE = 0x0000080 +VER_SERVICEPACKMAJOR = 0x0000020 +VER_SERVICEPACKMINOR = 0x0000010 +VER_SUITENAME = 0x0000040 + +VER_EQUAL = 1 +VER_GREATER = 2 +VER_GREATER_EQUAL = 3 +VER_LESS = 4 +VER_LESS_EQUAL = 5 +VER_AND = 6 +VER_OR = 7 + # typedef struct _OSVERSIONINFO { # DWORD dwOSVersionInfoSize; @@ -123,22 +124,25 @@ class OSVERSIONINFOA(Structure): _fields_ = [ ("dwOSVersionInfoSize", DWORD), - ("dwMajorVersion", DWORD), - ("dwMinorVersion", DWORD), - ("dwBuildNumber", DWORD), - ("dwPlatformId", DWORD), - ("szCSDVersion", CHAR * 128), + ("dwMajorVersion", DWORD), + ("dwMinorVersion", DWORD), + ("dwBuildNumber", DWORD), + ("dwPlatformId", DWORD), + ("szCSDVersion", CHAR * 128), ] + + class OSVERSIONINFOW(Structure): _fields_ = [ ("dwOSVersionInfoSize", DWORD), - ("dwMajorVersion", DWORD), - ("dwMinorVersion", DWORD), - ("dwBuildNumber", DWORD), - ("dwPlatformId", DWORD), - ("szCSDVersion", WCHAR * 128), + ("dwMajorVersion", DWORD), + ("dwMinorVersion", DWORD), + ("dwBuildNumber", DWORD), + ("dwPlatformId", DWORD), + ("szCSDVersion", WCHAR * 128), ] + # typedef struct _OSVERSIONINFOEX { # DWORD dwOSVersionInfoSize; # DWORD dwMajorVersion; @@ -155,189 +159,192 @@ class OSVERSIONINFOW(Structure): class OSVERSIONINFOEXA(Structure): _fields_ = [ ("dwOSVersionInfoSize", DWORD), - ("dwMajorVersion", DWORD), - ("dwMinorVersion", DWORD), - ("dwBuildNumber", DWORD), - ("dwPlatformId", DWORD), - ("szCSDVersion", CHAR * 128), - ("wServicePackMajor", WORD), - ("wServicePackMinor", WORD), - ("wSuiteMask", WORD), - ("wProductType", BYTE), - ("wReserved", BYTE), + ("dwMajorVersion", DWORD), + ("dwMinorVersion", DWORD), + ("dwBuildNumber", DWORD), + ("dwPlatformId", DWORD), + ("szCSDVersion", CHAR * 128), + ("wServicePackMajor", WORD), + ("wServicePackMinor", WORD), + ("wSuiteMask", WORD), + ("wProductType", BYTE), + ("wReserved", BYTE), ] + + class OSVERSIONINFOEXW(Structure): _fields_ = [ ("dwOSVersionInfoSize", DWORD), - ("dwMajorVersion", DWORD), - ("dwMinorVersion", DWORD), - ("dwBuildNumber", DWORD), - ("dwPlatformId", DWORD), - ("szCSDVersion", WCHAR * 128), - ("wServicePackMajor", WORD), - ("wServicePackMinor", WORD), - ("wSuiteMask", WORD), - ("wProductType", BYTE), - ("wReserved", BYTE), + ("dwMajorVersion", DWORD), + ("dwMinorVersion", DWORD), + ("dwBuildNumber", DWORD), + ("dwPlatformId", DWORD), + ("szCSDVersion", WCHAR * 128), + ("wServicePackMajor", WORD), + ("wServicePackMinor", WORD), + ("wSuiteMask", WORD), + ("wProductType", BYTE), + ("wReserved", BYTE), ] -LPOSVERSIONINFOA = POINTER(OSVERSIONINFOA) -LPOSVERSIONINFOW = POINTER(OSVERSIONINFOW) -LPOSVERSIONINFOEXA = POINTER(OSVERSIONINFOEXA) -LPOSVERSIONINFOEXW = POINTER(OSVERSIONINFOEXW) -POSVERSIONINFOA = LPOSVERSIONINFOA -POSVERSIONINFOW = LPOSVERSIONINFOW -POSVERSIONINFOEXA = LPOSVERSIONINFOEXA -POSVERSIONINFOEXW = LPOSVERSIONINFOA - -#--- GetSystemMetrics constants ----------------------------------------------- - -SM_CXSCREEN = 0 -SM_CYSCREEN = 1 -SM_CXVSCROLL = 2 -SM_CYHSCROLL = 3 -SM_CYCAPTION = 4 -SM_CXBORDER = 5 -SM_CYBORDER = 6 -SM_CXDLGFRAME = 7 -SM_CYDLGFRAME = 8 -SM_CYVTHUMB = 9 -SM_CXHTHUMB = 10 -SM_CXICON = 11 -SM_CYICON = 12 -SM_CXCURSOR = 13 -SM_CYCURSOR = 14 -SM_CYMENU = 15 -SM_CXFULLSCREEN = 16 -SM_CYFULLSCREEN = 17 -SM_CYKANJIWINDOW = 18 -SM_MOUSEPRESENT = 19 -SM_CYVSCROLL = 20 -SM_CXHSCROLL = 21 -SM_DEBUG = 22 -SM_SWAPBUTTON = 23 -SM_RESERVED1 = 24 -SM_RESERVED2 = 25 -SM_RESERVED3 = 26 -SM_RESERVED4 = 27 -SM_CXMIN = 28 -SM_CYMIN = 29 -SM_CXSIZE = 30 -SM_CYSIZE = 31 -SM_CXFRAME = 32 -SM_CYFRAME = 33 -SM_CXMINTRACK = 34 -SM_CYMINTRACK = 35 -SM_CXDOUBLECLK = 36 -SM_CYDOUBLECLK = 37 -SM_CXICONSPACING = 38 -SM_CYICONSPACING = 39 -SM_MENUDROPALIGNMENT = 40 -SM_PENWINDOWS = 41 -SM_DBCSENABLED = 42 -SM_CMOUSEBUTTONS = 43 - -SM_CXFIXEDFRAME = SM_CXDLGFRAME # ;win40 name change -SM_CYFIXEDFRAME = SM_CYDLGFRAME # ;win40 name change -SM_CXSIZEFRAME = SM_CXFRAME # ;win40 name change -SM_CYSIZEFRAME = SM_CYFRAME # ;win40 name change - -SM_SECURE = 44 -SM_CXEDGE = 45 -SM_CYEDGE = 46 -SM_CXMINSPACING = 47 -SM_CYMINSPACING = 48 -SM_CXSMICON = 49 -SM_CYSMICON = 50 -SM_CYSMCAPTION = 51 -SM_CXSMSIZE = 52 -SM_CYSMSIZE = 53 -SM_CXMENUSIZE = 54 -SM_CYMENUSIZE = 55 -SM_ARRANGE = 56 -SM_CXMINIMIZED = 57 -SM_CYMINIMIZED = 58 -SM_CXMAXTRACK = 59 -SM_CYMAXTRACK = 60 -SM_CXMAXIMIZED = 61 -SM_CYMAXIMIZED = 62 -SM_NETWORK = 63 -SM_CLEANBOOT = 67 -SM_CXDRAG = 68 -SM_CYDRAG = 69 -SM_SHOWSOUNDS = 70 -SM_CXMENUCHECK = 71 # Use instead of GetMenuCheckMarkDimensions()! -SM_CYMENUCHECK = 72 -SM_SLOWMACHINE = 73 -SM_MIDEASTENABLED = 74 -SM_MOUSEWHEELPRESENT = 75 -SM_XVIRTUALSCREEN = 76 -SM_YVIRTUALSCREEN = 77 -SM_CXVIRTUALSCREEN = 78 -SM_CYVIRTUALSCREEN = 79 -SM_CMONITORS = 80 -SM_SAMEDISPLAYFORMAT = 81 -SM_IMMENABLED = 82 -SM_CXFOCUSBORDER = 83 -SM_CYFOCUSBORDER = 84 -SM_TABLETPC = 86 -SM_MEDIACENTER = 87 -SM_STARTER = 88 -SM_SERVERR2 = 89 + +LPOSVERSIONINFOA = POINTER(OSVERSIONINFOA) +LPOSVERSIONINFOW = POINTER(OSVERSIONINFOW) +LPOSVERSIONINFOEXA = POINTER(OSVERSIONINFOEXA) +LPOSVERSIONINFOEXW = POINTER(OSVERSIONINFOEXW) +POSVERSIONINFOA = LPOSVERSIONINFOA +POSVERSIONINFOW = LPOSVERSIONINFOW +POSVERSIONINFOEXA = LPOSVERSIONINFOEXA +POSVERSIONINFOEXW = LPOSVERSIONINFOA + +# --- GetSystemMetrics constants ----------------------------------------------- + +SM_CXSCREEN = 0 +SM_CYSCREEN = 1 +SM_CXVSCROLL = 2 +SM_CYHSCROLL = 3 +SM_CYCAPTION = 4 +SM_CXBORDER = 5 +SM_CYBORDER = 6 +SM_CXDLGFRAME = 7 +SM_CYDLGFRAME = 8 +SM_CYVTHUMB = 9 +SM_CXHTHUMB = 10 +SM_CXICON = 11 +SM_CYICON = 12 +SM_CXCURSOR = 13 +SM_CYCURSOR = 14 +SM_CYMENU = 15 +SM_CXFULLSCREEN = 16 +SM_CYFULLSCREEN = 17 +SM_CYKANJIWINDOW = 18 +SM_MOUSEPRESENT = 19 +SM_CYVSCROLL = 20 +SM_CXHSCROLL = 21 +SM_DEBUG = 22 +SM_SWAPBUTTON = 23 +SM_RESERVED1 = 24 +SM_RESERVED2 = 25 +SM_RESERVED3 = 26 +SM_RESERVED4 = 27 +SM_CXMIN = 28 +SM_CYMIN = 29 +SM_CXSIZE = 30 +SM_CYSIZE = 31 +SM_CXFRAME = 32 +SM_CYFRAME = 33 +SM_CXMINTRACK = 34 +SM_CYMINTRACK = 35 +SM_CXDOUBLECLK = 36 +SM_CYDOUBLECLK = 37 +SM_CXICONSPACING = 38 +SM_CYICONSPACING = 39 +SM_MENUDROPALIGNMENT = 40 +SM_PENWINDOWS = 41 +SM_DBCSENABLED = 42 +SM_CMOUSEBUTTONS = 43 + +SM_CXFIXEDFRAME = SM_CXDLGFRAME # ;win40 name change +SM_CYFIXEDFRAME = SM_CYDLGFRAME # ;win40 name change +SM_CXSIZEFRAME = SM_CXFRAME # ;win40 name change +SM_CYSIZEFRAME = SM_CYFRAME # ;win40 name change + +SM_SECURE = 44 +SM_CXEDGE = 45 +SM_CYEDGE = 46 +SM_CXMINSPACING = 47 +SM_CYMINSPACING = 48 +SM_CXSMICON = 49 +SM_CYSMICON = 50 +SM_CYSMCAPTION = 51 +SM_CXSMSIZE = 52 +SM_CYSMSIZE = 53 +SM_CXMENUSIZE = 54 +SM_CYMENUSIZE = 55 +SM_ARRANGE = 56 +SM_CXMINIMIZED = 57 +SM_CYMINIMIZED = 58 +SM_CXMAXTRACK = 59 +SM_CYMAXTRACK = 60 +SM_CXMAXIMIZED = 61 +SM_CYMAXIMIZED = 62 +SM_NETWORK = 63 +SM_CLEANBOOT = 67 +SM_CXDRAG = 68 +SM_CYDRAG = 69 +SM_SHOWSOUNDS = 70 +SM_CXMENUCHECK = 71 # Use instead of GetMenuCheckMarkDimensions()! +SM_CYMENUCHECK = 72 +SM_SLOWMACHINE = 73 +SM_MIDEASTENABLED = 74 +SM_MOUSEWHEELPRESENT = 75 +SM_XVIRTUALSCREEN = 76 +SM_YVIRTUALSCREEN = 77 +SM_CXVIRTUALSCREEN = 78 +SM_CYVIRTUALSCREEN = 79 +SM_CMONITORS = 80 +SM_SAMEDISPLAYFORMAT = 81 +SM_IMMENABLED = 82 +SM_CXFOCUSBORDER = 83 +SM_CYFOCUSBORDER = 84 +SM_TABLETPC = 86 +SM_MEDIACENTER = 87 +SM_STARTER = 88 +SM_SERVERR2 = 89 SM_MOUSEHORIZONTALWHEELPRESENT = 91 -SM_CXPADDEDBORDER = 92 +SM_CXPADDEDBORDER = 92 -SM_CMETRICS = 93 +SM_CMETRICS = 93 -SM_REMOTESESSION = 0x1000 -SM_SHUTTINGDOWN = 0x2000 -SM_REMOTECONTROL = 0x2001 +SM_REMOTESESSION = 0x1000 +SM_SHUTTINGDOWN = 0x2000 +SM_REMOTECONTROL = 0x2001 SM_CARETBLINKINGENABLED = 0x2002 -#--- SYSTEM_INFO structure, GetSystemInfo() and GetNativeSystemInfo() --------- +# --- SYSTEM_INFO structure, GetSystemInfo() and GetNativeSystemInfo() --------- # Values used by Wine # Documented values at MSDN are marked with an asterisk -PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF; # Unknown architecture. -PROCESSOR_ARCHITECTURE_INTEL = 0 # x86 (AMD or Intel) * -PROCESSOR_ARCHITECTURE_MIPS = 1 # MIPS -PROCESSOR_ARCHITECTURE_ALPHA = 2 # Alpha -PROCESSOR_ARCHITECTURE_PPC = 3 # Power PC -PROCESSOR_ARCHITECTURE_SHX = 4 # SHX -PROCESSOR_ARCHITECTURE_ARM = 5 # ARM -PROCESSOR_ARCHITECTURE_IA64 = 6 # Intel Itanium * -PROCESSOR_ARCHITECTURE_ALPHA64 = 7 # Alpha64 -PROCESSOR_ARCHITECTURE_MSIL = 8 # MSIL -PROCESSOR_ARCHITECTURE_AMD64 = 9 # x64 (AMD or Intel) * -PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 = 10 # IA32 on Win64 -PROCESSOR_ARCHITECTURE_SPARC = 20 # Sparc (Wine) +PROCESSOR_ARCHITECTURE_UNKNOWN = 0xFFFF # Unknown architecture. +PROCESSOR_ARCHITECTURE_INTEL = 0 # x86 (AMD or Intel) * +PROCESSOR_ARCHITECTURE_MIPS = 1 # MIPS +PROCESSOR_ARCHITECTURE_ALPHA = 2 # Alpha +PROCESSOR_ARCHITECTURE_PPC = 3 # Power PC +PROCESSOR_ARCHITECTURE_SHX = 4 # SHX +PROCESSOR_ARCHITECTURE_ARM = 5 # ARM +PROCESSOR_ARCHITECTURE_IA64 = 6 # Intel Itanium * +PROCESSOR_ARCHITECTURE_ALPHA64 = 7 # Alpha64 +PROCESSOR_ARCHITECTURE_MSIL = 8 # MSIL +PROCESSOR_ARCHITECTURE_AMD64 = 9 # x64 (AMD or Intel) * +PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 = 10 # IA32 on Win64 +PROCESSOR_ARCHITECTURE_SPARC = 20 # Sparc (Wine) # Values used by Wine # PROCESSOR_OPTIL value found at http://code.google.com/p/ddab-lib/ # Documented values at MSDN are marked with an asterisk -PROCESSOR_INTEL_386 = 386 # Intel i386 * -PROCESSOR_INTEL_486 = 486 # Intel i486 * -PROCESSOR_INTEL_PENTIUM = 586 # Intel Pentium * -PROCESSOR_INTEL_IA64 = 2200 # Intel IA64 (Itanium) * -PROCESSOR_AMD_X8664 = 8664 # AMD X86 64 * -PROCESSOR_MIPS_R4000 = 4000 # MIPS R4000, R4101, R3910 -PROCESSOR_ALPHA_21064 = 21064 # Alpha 210 64 -PROCESSOR_PPC_601 = 601 # PPC 601 -PROCESSOR_PPC_603 = 603 # PPC 603 -PROCESSOR_PPC_604 = 604 # PPC 604 -PROCESSOR_PPC_620 = 620 # PPC 620 -PROCESSOR_HITACHI_SH3 = 10003 # Hitachi SH3 (Windows CE) -PROCESSOR_HITACHI_SH3E = 10004 # Hitachi SH3E (Windows CE) -PROCESSOR_HITACHI_SH4 = 10005 # Hitachi SH4 (Windows CE) -PROCESSOR_MOTOROLA_821 = 821 # Motorola 821 (Windows CE) -PROCESSOR_SHx_SH3 = 103 # SHx SH3 (Windows CE) -PROCESSOR_SHx_SH4 = 104 # SHx SH4 (Windows CE) -PROCESSOR_STRONGARM = 2577 # StrongARM (Windows CE) -PROCESSOR_ARM720 = 1824 # ARM 720 (Windows CE) -PROCESSOR_ARM820 = 2080 # ARM 820 (Windows CE) -PROCESSOR_ARM920 = 2336 # ARM 920 (Windows CE) -PROCESSOR_ARM_7TDMI = 70001 # ARM 7TDMI (Windows CE) -PROCESSOR_OPTIL = 0x494F # MSIL +PROCESSOR_INTEL_386 = 386 # Intel i386 * +PROCESSOR_INTEL_486 = 486 # Intel i486 * +PROCESSOR_INTEL_PENTIUM = 586 # Intel Pentium * +PROCESSOR_INTEL_IA64 = 2200 # Intel IA64 (Itanium) * +PROCESSOR_AMD_X8664 = 8664 # AMD X86 64 * +PROCESSOR_MIPS_R4000 = 4000 # MIPS R4000, R4101, R3910 +PROCESSOR_ALPHA_21064 = 21064 # Alpha 210 64 +PROCESSOR_PPC_601 = 601 # PPC 601 +PROCESSOR_PPC_603 = 603 # PPC 603 +PROCESSOR_PPC_604 = 604 # PPC 604 +PROCESSOR_PPC_620 = 620 # PPC 620 +PROCESSOR_HITACHI_SH3 = 10003 # Hitachi SH3 (Windows CE) +PROCESSOR_HITACHI_SH3E = 10004 # Hitachi SH3E (Windows CE) +PROCESSOR_HITACHI_SH4 = 10005 # Hitachi SH4 (Windows CE) +PROCESSOR_MOTOROLA_821 = 821 # Motorola 821 (Windows CE) +PROCESSOR_SHx_SH3 = 103 # SHx SH3 (Windows CE) +PROCESSOR_SHx_SH4 = 104 # SHx SH4 (Windows CE) +PROCESSOR_STRONGARM = 2577 # StrongARM (Windows CE) +PROCESSOR_ARM720 = 1824 # ARM 720 (Windows CE) +PROCESSOR_ARM820 = 2080 # ARM 820 (Windows CE) +PROCESSOR_ARM920 = 2336 # ARM 920 (Windows CE) +PROCESSOR_ARM_7TDMI = 70001 # ARM 7TDMI (Windows CE) +PROCESSOR_OPTIL = 0x494F # MSIL # typedef struct _SYSTEM_INFO { # union { @@ -358,102 +365,117 @@ class OSVERSIONINFOEXW(Structure): # WORD wProcessorRevision; # } SYSTEM_INFO; + class _SYSTEM_INFO_OEM_ID_STRUCT(Structure): _fields_ = [ - ("wProcessorArchitecture", WORD), - ("wReserved", WORD), -] + ("wProcessorArchitecture", WORD), + ("wReserved", WORD), + ] + class _SYSTEM_INFO_OEM_ID(Union): _fields_ = [ - ("dwOemId", DWORD), - ("w", _SYSTEM_INFO_OEM_ID_STRUCT), -] + ("dwOemId", DWORD), + ("w", _SYSTEM_INFO_OEM_ID_STRUCT), + ] + class SYSTEM_INFO(Structure): _fields_ = [ - ("id", _SYSTEM_INFO_OEM_ID), - ("dwPageSize", DWORD), - ("lpMinimumApplicationAddress", LPVOID), - ("lpMaximumApplicationAddress", LPVOID), - ("dwActiveProcessorMask", DWORD_PTR), - ("dwNumberOfProcessors", DWORD), - ("dwProcessorType", DWORD), - ("dwAllocationGranularity", DWORD), - ("wProcessorLevel", WORD), - ("wProcessorRevision", WORD), + ("id", _SYSTEM_INFO_OEM_ID), + ("dwPageSize", DWORD), + ("lpMinimumApplicationAddress", LPVOID), + ("lpMaximumApplicationAddress", LPVOID), + ("dwActiveProcessorMask", DWORD_PTR), + ("dwNumberOfProcessors", DWORD), + ("dwProcessorType", DWORD), + ("dwAllocationGranularity", DWORD), + ("wProcessorLevel", WORD), + ("wProcessorRevision", WORD), ] def __get_dwOemId(self): return self.id.dwOemId + def __set_dwOemId(self, value): self.id.dwOemId = value + dwOemId = property(__get_dwOemId, __set_dwOemId) def __get_wProcessorArchitecture(self): return self.id.w.wProcessorArchitecture + def __set_wProcessorArchitecture(self, value): self.id.w.wProcessorArchitecture = value + wProcessorArchitecture = property(__get_wProcessorArchitecture, __set_wProcessorArchitecture) + LPSYSTEM_INFO = ctypes.POINTER(SYSTEM_INFO) + # void WINAPI GetSystemInfo( # __out LPSYSTEM_INFO lpSystemInfo # ); def GetSystemInfo(): _GetSystemInfo = windll.kernel32.GetSystemInfo _GetSystemInfo.argtypes = [LPSYSTEM_INFO] - _GetSystemInfo.restype = None + _GetSystemInfo.restype = None sysinfo = SYSTEM_INFO() _GetSystemInfo(byref(sysinfo)) return sysinfo + # void WINAPI GetNativeSystemInfo( # __out LPSYSTEM_INFO lpSystemInfo # ); def GetNativeSystemInfo(): _GetNativeSystemInfo = windll.kernel32.GetNativeSystemInfo _GetNativeSystemInfo.argtypes = [LPSYSTEM_INFO] - _GetNativeSystemInfo.restype = None + _GetNativeSystemInfo.restype = None sysinfo = SYSTEM_INFO() _GetNativeSystemInfo(byref(sysinfo)) return sysinfo + # int WINAPI GetSystemMetrics( # __in int nIndex # ); def GetSystemMetrics(nIndex): _GetSystemMetrics = windll.user32.GetSystemMetrics _GetSystemMetrics.argtypes = [ctypes.c_int] - _GetSystemMetrics.restype = ctypes.c_int + _GetSystemMetrics.restype = ctypes.c_int return _GetSystemMetrics(nIndex) + # SIZE_T WINAPI GetLargePageMinimum(void); def GetLargePageMinimum(): _GetLargePageMinimum = windll.user32.GetLargePageMinimum _GetLargePageMinimum.argtypes = [] - _GetLargePageMinimum.restype = SIZE_T + _GetLargePageMinimum.restype = SIZE_T return _GetLargePageMinimum() + # HANDLE WINAPI GetCurrentProcess(void); def GetCurrentProcess(): -## return 0xFFFFFFFFFFFFFFFFL + ## return 0xFFFFFFFFFFFFFFFFL _GetCurrentProcess = windll.kernel32.GetCurrentProcess _GetCurrentProcess.argtypes = [] - _GetCurrentProcess.restype = HANDLE + _GetCurrentProcess.restype = HANDLE return _GetCurrentProcess() + # HANDLE WINAPI GetCurrentThread(void); def GetCurrentThread(): -## return 0xFFFFFFFFFFFFFFFEL + ## return 0xFFFFFFFFFFFFFFFEL _GetCurrentThread = windll.kernel32.GetCurrentThread _GetCurrentThread.argtypes = [] - _GetCurrentThread.restype = HANDLE + _GetCurrentThread.restype = HANDLE return _GetCurrentThread() + # BOOL WINAPI IsWow64Process( # __in HANDLE hProcess, # __out PBOOL Wow64Process @@ -461,39 +483,41 @@ def GetCurrentThread(): def IsWow64Process(hProcess): _IsWow64Process = windll.kernel32.IsWow64Process _IsWow64Process.argtypes = [HANDLE, PBOOL] - _IsWow64Process.restype = bool + _IsWow64Process.restype = bool _IsWow64Process.errcheck = RaiseIfZero Wow64Process = BOOL(FALSE) _IsWow64Process(hProcess, byref(Wow64Process)) return bool(Wow64Process) + # DWORD WINAPI GetVersion(void); def GetVersion(): _GetVersion = windll.kernel32.GetVersion _GetVersion.argtypes = [] - _GetVersion.restype = DWORD + _GetVersion.restype = DWORD _GetVersion.errcheck = RaiseIfZero # See the example code here: # http://msdn.microsoft.com/en-us/library/ms724439(VS.85).aspx - dwVersion = _GetVersion() - dwMajorVersion = dwVersion & 0x000000FF - dwMinorVersion = (dwVersion & 0x0000FF00) >> 8 + dwVersion = _GetVersion() + dwMajorVersion = dwVersion & 0x000000FF + dwMinorVersion = (dwVersion & 0x0000FF00) >> 8 if (dwVersion & 0x80000000) == 0: - dwBuild = (dwVersion & 0x7FFF0000) >> 16 + dwBuild = (dwVersion & 0x7FFF0000) >> 16 else: - dwBuild = None + dwBuild = None return int(dwMajorVersion), int(dwMinorVersion), int(dwBuild) + # BOOL WINAPI GetVersionEx( # __inout LPOSVERSIONINFO lpVersionInfo # ); def GetVersionExA(): _GetVersionExA = windll.kernel32.GetVersionExA _GetVersionExA.argtypes = [POINTER(OSVERSIONINFOEXA)] - _GetVersionExA.restype = bool + _GetVersionExA.restype = bool _GetVersionExA.errcheck = RaiseIfZero osi = OSVERSIONINFOEXA() @@ -507,10 +531,11 @@ def GetVersionExA(): _GetVersionExA(byref(osi)) return osi + def GetVersionExW(): _GetVersionExW = windll.kernel32.GetVersionExW _GetVersionExW.argtypes = [POINTER(OSVERSIONINFOEXW)] - _GetVersionExW.restype = bool + _GetVersionExW.restype = bool _GetVersionExW.errcheck = RaiseIfZero osi = OSVERSIONINFOEXW() @@ -524,8 +549,10 @@ def GetVersionExW(): _GetVersionExW(byref(osi)) return osi + GetVersionEx = GuessStringType(GetVersionExA, GetVersionExW) + # BOOL WINAPI GetProductInfo( # __in DWORD dwOSMajorVersion, # __in DWORD dwOSMinorVersion, @@ -536,13 +563,14 @@ def GetVersionExW(): def GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion): _GetProductInfo = windll.kernel32.GetProductInfo _GetProductInfo.argtypes = [DWORD, DWORD, DWORD, DWORD, PDWORD] - _GetProductInfo.restype = BOOL + _GetProductInfo.restype = BOOL _GetProductInfo.errcheck = RaiseIfZero dwReturnedProductType = DWORD(0) _GetProductInfo(dwOSMajorVersion, dwOSMinorVersion, dwSpMajorVersion, dwSpMinorVersion, byref(dwReturnedProductType)) return dwReturnedProductType.value + # BOOL WINAPI VerifyVersionInfo( # __in LPOSVERSIONINFOEX lpVersionInfo, # __in DWORD dwTypeMask, @@ -555,18 +583,21 @@ def VerifyVersionInfo(lpVersionInfo, dwTypeMask, dwlConditionMask): return VerifyVersionInfoW(lpVersionInfo, dwTypeMask, dwlConditionMask) raise TypeError("Bad OSVERSIONINFOEX structure") + def VerifyVersionInfoA(lpVersionInfo, dwTypeMask, dwlConditionMask): _VerifyVersionInfoA = windll.kernel32.VerifyVersionInfoA _VerifyVersionInfoA.argtypes = [LPOSVERSIONINFOEXA, DWORD, DWORDLONG] - _VerifyVersionInfoA.restype = bool + _VerifyVersionInfoA.restype = bool return _VerifyVersionInfoA(byref(lpVersionInfo), dwTypeMask, dwlConditionMask) + def VerifyVersionInfoW(lpVersionInfo, dwTypeMask, dwlConditionMask): _VerifyVersionInfoW = windll.kernel32.VerifyVersionInfoW _VerifyVersionInfoW.argtypes = [LPOSVERSIONINFOEXW, DWORD, DWORDLONG] - _VerifyVersionInfoW.restype = bool + _VerifyVersionInfoW.restype = bool return _VerifyVersionInfoW(byref(lpVersionInfo), dwTypeMask, dwlConditionMask) + # ULONGLONG WINAPI VerSetConditionMask( # __in ULONGLONG dwlConditionMask, # __in DWORD dwTypeBitMask, @@ -575,33 +606,34 @@ def VerifyVersionInfoW(lpVersionInfo, dwTypeMask, dwlConditionMask): def VerSetConditionMask(dwlConditionMask, dwTypeBitMask, dwConditionMask): _VerSetConditionMask = windll.kernel32.VerSetConditionMask _VerSetConditionMask.argtypes = [ULONGLONG, DWORD, BYTE] - _VerSetConditionMask.restype = ULONGLONG + _VerSetConditionMask.restype = ULONGLONG return _VerSetConditionMask(dwlConditionMask, dwTypeBitMask, dwConditionMask) -#--- get_bits, get_arch and get_os -------------------------------------------- - -ARCH_UNKNOWN = "unknown" -ARCH_I386 = "i386" -ARCH_MIPS = "mips" -ARCH_ALPHA = "alpha" -ARCH_PPC = "ppc" -ARCH_SHX = "shx" -ARCH_ARM = "arm" -ARCH_ARM64 = "arm64" -ARCH_THUMB = "thumb" -ARCH_IA64 = "ia64" -ARCH_ALPHA64 = "alpha64" -ARCH_MSIL = "msil" -ARCH_AMD64 = "amd64" -ARCH_SPARC = "sparc" + +# --- get_bits, get_arch and get_os -------------------------------------------- + +ARCH_UNKNOWN = "unknown" +ARCH_I386 = "i386" +ARCH_MIPS = "mips" +ARCH_ALPHA = "alpha" +ARCH_PPC = "ppc" +ARCH_SHX = "shx" +ARCH_ARM = "arm" +ARCH_ARM64 = "arm64" +ARCH_THUMB = "thumb" +ARCH_IA64 = "ia64" +ARCH_ALPHA64 = "alpha64" +ARCH_MSIL = "msil" +ARCH_AMD64 = "amd64" +ARCH_SPARC = "sparc" # aliases -ARCH_IA32 = ARCH_I386 -ARCH_X86 = ARCH_I386 -ARCH_X64 = ARCH_AMD64 -ARCH_ARM7 = ARCH_ARM -ARCH_ARM8 = ARCH_ARM64 -ARCH_T32 = ARCH_THUMB +ARCH_IA32 = ARCH_I386 +ARCH_X86 = ARCH_I386 +ARCH_X64 = ARCH_AMD64 +ARCH_ARM7 = ARCH_ARM +ARCH_ARM8 = ARCH_ARM64 +ARCH_T32 = ARCH_THUMB ARCH_AARCH32 = ARCH_ARM7 ARCH_AARCH64 = ARCH_ARM8 ARCH_POWERPC = ARCH_PPC @@ -610,56 +642,57 @@ def VerSetConditionMask(dwlConditionMask, dwTypeBitMask, dwConditionMask): # win32 constants -> our constants _arch_map = { - PROCESSOR_ARCHITECTURE_INTEL : ARCH_I386, - PROCESSOR_ARCHITECTURE_MIPS : ARCH_MIPS, - PROCESSOR_ARCHITECTURE_ALPHA : ARCH_ALPHA, - PROCESSOR_ARCHITECTURE_PPC : ARCH_PPC, - PROCESSOR_ARCHITECTURE_SHX : ARCH_SHX, - PROCESSOR_ARCHITECTURE_ARM : ARCH_ARM, - PROCESSOR_ARCHITECTURE_IA64 : ARCH_IA64, - PROCESSOR_ARCHITECTURE_ALPHA64 : ARCH_ALPHA64, - PROCESSOR_ARCHITECTURE_MSIL : ARCH_MSIL, - PROCESSOR_ARCHITECTURE_AMD64 : ARCH_AMD64, - PROCESSOR_ARCHITECTURE_SPARC : ARCH_SPARC, + PROCESSOR_ARCHITECTURE_INTEL: ARCH_I386, + PROCESSOR_ARCHITECTURE_MIPS: ARCH_MIPS, + PROCESSOR_ARCHITECTURE_ALPHA: ARCH_ALPHA, + PROCESSOR_ARCHITECTURE_PPC: ARCH_PPC, + PROCESSOR_ARCHITECTURE_SHX: ARCH_SHX, + PROCESSOR_ARCHITECTURE_ARM: ARCH_ARM, + PROCESSOR_ARCHITECTURE_IA64: ARCH_IA64, + PROCESSOR_ARCHITECTURE_ALPHA64: ARCH_ALPHA64, + PROCESSOR_ARCHITECTURE_MSIL: ARCH_MSIL, + PROCESSOR_ARCHITECTURE_AMD64: ARCH_AMD64, + PROCESSOR_ARCHITECTURE_SPARC: ARCH_SPARC, } -OS_UNKNOWN = "Unknown" -OS_NT = "Windows NT" -OS_W2K = "Windows 2000" -OS_XP = "Windows XP" -OS_XP_64 = "Windows XP (64 bits)" -OS_W2K3 = "Windows 2003" -OS_W2K3_64 = "Windows 2003 (64 bits)" -OS_W2K3R2 = "Windows 2003 R2" +OS_UNKNOWN = "Unknown" +OS_NT = "Windows NT" +OS_W2K = "Windows 2000" +OS_XP = "Windows XP" +OS_XP_64 = "Windows XP (64 bits)" +OS_W2K3 = "Windows 2003" +OS_W2K3_64 = "Windows 2003 (64 bits)" +OS_W2K3R2 = "Windows 2003 R2" OS_W2K3R2_64 = "Windows 2003 R2 (64 bits)" -OS_W2K8 = "Windows 2008" -OS_W2K8_64 = "Windows 2008 (64 bits)" -OS_W2K8R2 = "Windows 2008 R2" +OS_W2K8 = "Windows 2008" +OS_W2K8_64 = "Windows 2008 (64 bits)" +OS_W2K8R2 = "Windows 2008 R2" OS_W2K8R2_64 = "Windows 2008 R2 (64 bits)" -OS_VISTA = "Windows Vista" -OS_VISTA_64 = "Windows Vista (64 bits)" -OS_W7 = "Windows 7" -OS_W7_64 = "Windows 7 (64 bits)" +OS_VISTA = "Windows Vista" +OS_VISTA_64 = "Windows Vista (64 bits)" +OS_W7 = "Windows 7" +OS_W7_64 = "Windows 7 (64 bits)" -OS_SEVEN = OS_W7 +OS_SEVEN = OS_W7 OS_SEVEN_64 = OS_W7_64 -OS_WINDOWS_NT = OS_NT -OS_WINDOWS_2000 = OS_W2K -OS_WINDOWS_XP = OS_XP -OS_WINDOWS_XP_64 = OS_XP_64 -OS_WINDOWS_2003 = OS_W2K3 -OS_WINDOWS_2003_64 = OS_W2K3_64 -OS_WINDOWS_2003_R2 = OS_W2K3R2 +OS_WINDOWS_NT = OS_NT +OS_WINDOWS_2000 = OS_W2K +OS_WINDOWS_XP = OS_XP +OS_WINDOWS_XP_64 = OS_XP_64 +OS_WINDOWS_2003 = OS_W2K3 +OS_WINDOWS_2003_64 = OS_W2K3_64 +OS_WINDOWS_2003_R2 = OS_W2K3R2 OS_WINDOWS_2003_R2_64 = OS_W2K3R2_64 -OS_WINDOWS_2008 = OS_W2K8 -OS_WINDOWS_2008_64 = OS_W2K8_64 -OS_WINDOWS_2008_R2 = OS_W2K8R2 +OS_WINDOWS_2008 = OS_W2K8 +OS_WINDOWS_2008_64 = OS_W2K8_64 +OS_WINDOWS_2008_R2 = OS_W2K8R2 OS_WINDOWS_2008_R2_64 = OS_W2K8R2_64 -OS_WINDOWS_VISTA = OS_VISTA -OS_WINDOWS_VISTA_64 = OS_VISTA_64 -OS_WINDOWS_SEVEN = OS_W7 -OS_WINDOWS_SEVEN_64 = OS_W7_64 +OS_WINDOWS_VISTA = OS_VISTA +OS_WINDOWS_VISTA_64 = OS_VISTA_64 +OS_WINDOWS_SEVEN = OS_W7 +OS_WINDOWS_SEVEN_64 = OS_W7_64 + def _get_bits(): """ @@ -672,6 +705,7 @@ def _get_bits(): """ return sizeof(SIZE_T) * 8 + def _get_arch(): """ Determines the current processor architecture. @@ -715,6 +749,7 @@ def _get_arch(): except KeyError: return ARCH_UNKNOWN + def _get_wow64(): """ Determines if the current process is running in Windows-On-Windows 64 bits. @@ -730,12 +765,13 @@ def _get_wow64(): wow64 = False else: try: - wow64 = IsWow64Process( GetCurrentProcess() ) + wow64 = IsWow64Process(GetCurrentProcess()) except Exception: wow64 = False return wow64 -def _get_os(osvi = None): + +def _get_os(osvi=None): """ Determines the current operating system. @@ -780,44 +816,45 @@ def _get_os(osvi = None): if osvi.dwMinorVersion == 0: if osvi.wProductType == VER_NT_WORKSTATION: if bits == 64 or wow64: - return 'Windows Vista (64 bits)' - return 'Windows Vista' + return "Windows Vista (64 bits)" + return "Windows Vista" else: if bits == 64 or wow64: - return 'Windows 2008 (64 bits)' - return 'Windows 2008' + return "Windows 2008 (64 bits)" + return "Windows 2008" if osvi.dwMinorVersion == 1: if osvi.wProductType == VER_NT_WORKSTATION: if bits == 64 or wow64: - return 'Windows 7 (64 bits)' - return 'Windows 7' + return "Windows 7 (64 bits)" + return "Windows 7" else: if bits == 64 or wow64: - return 'Windows 2008 R2 (64 bits)' - return 'Windows 2008 R2' + return "Windows 2008 R2 (64 bits)" + return "Windows 2008 R2" if osvi.dwMajorVersion == 5: if osvi.dwMinorVersion == 2: if GetSystemMetrics(SM_SERVERR2): if bits == 64 or wow64: - return 'Windows 2003 R2 (64 bits)' - return 'Windows 2003 R2' + return "Windows 2003 R2 (64 bits)" + return "Windows 2003 R2" if osvi.wSuiteMask in (VER_SUITE_STORAGE_SERVER, VER_SUITE_WH_SERVER): if bits == 64 or wow64: - return 'Windows 2003 (64 bits)' - return 'Windows 2003' + return "Windows 2003 (64 bits)" + return "Windows 2003" if osvi.wProductType == VER_NT_WORKSTATION and arch == ARCH_AMD64: - return 'Windows XP (64 bits)' + return "Windows XP (64 bits)" else: if bits == 64 or wow64: - return 'Windows 2003 (64 bits)' - return 'Windows 2003' + return "Windows 2003 (64 bits)" + return "Windows 2003" if osvi.dwMinorVersion == 1: - return 'Windows XP' + return "Windows XP" if osvi.dwMinorVersion == 0: - return 'Windows 2000' + return "Windows 2000" if osvi.dwMajorVersion == 4: - return 'Windows NT' - return 'Unknown' + return "Windows NT" + return "Unknown" + def _get_ntddi(osvi): """ @@ -841,12 +878,13 @@ def _get_ntddi(osvi): if not osvi: osvi = GetVersionEx() ntddi = 0 - ntddi += (osvi.dwMajorVersion & 0xFF) << 24 - ntddi += (osvi.dwMinorVersion & 0xFF) << 16 + ntddi += (osvi.dwMajorVersion & 0xFF) << 24 + ntddi += (osvi.dwMinorVersion & 0xFF) << 16 ntddi += (osvi.wServicePackMajor & 0xFF) << 8 - ntddi += (osvi.wServicePackMinor & 0xFF) + ntddi += osvi.wServicePackMinor & 0xFF return ntddi + # The order of the following definitions DOES matter! # Current integer size in bits. See L{_get_bits} for more details. @@ -869,58 +907,59 @@ def _get_ntddi(osvi): # Upper word of L{NTDDI_VERSION}, contains the OS major and minor version number. WINVER = NTDDI_VERSION >> 16 -#--- version.dll -------------------------------------------------------------- - -VS_FF_DEBUG = 0x00000001 -VS_FF_PRERELEASE = 0x00000002 -VS_FF_PATCHED = 0x00000004 -VS_FF_PRIVATEBUILD = 0x00000008 -VS_FF_INFOINFERRED = 0x00000010 -VS_FF_SPECIALBUILD = 0x00000020 - -VOS_UNKNOWN = 0x00000000 -VOS__WINDOWS16 = 0x00000001 -VOS__PM16 = 0x00000002 -VOS__PM32 = 0x00000003 -VOS__WINDOWS32 = 0x00000004 -VOS_DOS = 0x00010000 -VOS_OS216 = 0x00020000 -VOS_OS232 = 0x00030000 -VOS_NT = 0x00040000 - -VOS_DOS_WINDOWS16 = 0x00010001 -VOS_DOS_WINDOWS32 = 0x00010004 -VOS_NT_WINDOWS32 = 0x00040004 -VOS_OS216_PM16 = 0x00020002 -VOS_OS232_PM32 = 0x00030003 - -VFT_UNKNOWN = 0x00000000 -VFT_APP = 0x00000001 -VFT_DLL = 0x00000002 -VFT_DRV = 0x00000003 -VFT_FONT = 0x00000004 -VFT_VXD = 0x00000005 -VFT_RESERVED = 0x00000006 # undocumented -VFT_STATIC_LIB = 0x00000007 - -VFT2_UNKNOWN = 0x00000000 - -VFT2_DRV_PRINTER = 0x00000001 -VFT2_DRV_KEYBOARD = 0x00000002 -VFT2_DRV_LANGUAGE = 0x00000003 -VFT2_DRV_DISPLAY = 0x00000004 -VFT2_DRV_MOUSE = 0x00000005 -VFT2_DRV_NETWORK = 0x00000006 -VFT2_DRV_SYSTEM = 0x00000007 -VFT2_DRV_INSTALLABLE = 0x00000008 -VFT2_DRV_SOUND = 0x00000009 -VFT2_DRV_COMM = 0x0000000A -VFT2_DRV_RESERVED = 0x0000000B # undocumented -VFT2_DRV_VERSIONED_PRINTER = 0x0000000C - -VFT2_FONT_RASTER = 0x00000001 -VFT2_FONT_VECTOR = 0x00000002 -VFT2_FONT_TRUETYPE = 0x00000003 +# --- version.dll -------------------------------------------------------------- + +VS_FF_DEBUG = 0x00000001 +VS_FF_PRERELEASE = 0x00000002 +VS_FF_PATCHED = 0x00000004 +VS_FF_PRIVATEBUILD = 0x00000008 +VS_FF_INFOINFERRED = 0x00000010 +VS_FF_SPECIALBUILD = 0x00000020 + +VOS_UNKNOWN = 0x00000000 +VOS__WINDOWS16 = 0x00000001 +VOS__PM16 = 0x00000002 +VOS__PM32 = 0x00000003 +VOS__WINDOWS32 = 0x00000004 +VOS_DOS = 0x00010000 +VOS_OS216 = 0x00020000 +VOS_OS232 = 0x00030000 +VOS_NT = 0x00040000 + +VOS_DOS_WINDOWS16 = 0x00010001 +VOS_DOS_WINDOWS32 = 0x00010004 +VOS_NT_WINDOWS32 = 0x00040004 +VOS_OS216_PM16 = 0x00020002 +VOS_OS232_PM32 = 0x00030003 + +VFT_UNKNOWN = 0x00000000 +VFT_APP = 0x00000001 +VFT_DLL = 0x00000002 +VFT_DRV = 0x00000003 +VFT_FONT = 0x00000004 +VFT_VXD = 0x00000005 +VFT_RESERVED = 0x00000006 # undocumented +VFT_STATIC_LIB = 0x00000007 + +VFT2_UNKNOWN = 0x00000000 + +VFT2_DRV_PRINTER = 0x00000001 +VFT2_DRV_KEYBOARD = 0x00000002 +VFT2_DRV_LANGUAGE = 0x00000003 +VFT2_DRV_DISPLAY = 0x00000004 +VFT2_DRV_MOUSE = 0x00000005 +VFT2_DRV_NETWORK = 0x00000006 +VFT2_DRV_SYSTEM = 0x00000007 +VFT2_DRV_INSTALLABLE = 0x00000008 +VFT2_DRV_SOUND = 0x00000009 +VFT2_DRV_COMM = 0x0000000A +VFT2_DRV_RESERVED = 0x0000000B # undocumented +VFT2_DRV_VERSIONED_PRINTER = 0x0000000C + +VFT2_FONT_RASTER = 0x00000001 +VFT2_FONT_VECTOR = 0x00000002 +VFT2_FONT_TRUETYPE = 0x00000003 + # typedef struct tagVS_FIXEDFILEINFO { # DWORD dwSignature; @@ -939,23 +978,26 @@ def _get_ntddi(osvi): # } VS_FIXEDFILEINFO; class VS_FIXEDFILEINFO(Structure): _fields_ = [ - ("dwSignature", DWORD), - ("dwStrucVersion", DWORD), - ("dwFileVersionMS", DWORD), - ("dwFileVersionLS", DWORD), - ("dwProductVersionMS", DWORD), - ("dwProductVersionLS", DWORD), - ("dwFileFlagsMask", DWORD), - ("dwFileFlags", DWORD), - ("dwFileOS", DWORD), - ("dwFileType", DWORD), - ("dwFileSubtype", DWORD), - ("dwFileDateMS", DWORD), - ("dwFileDateLS", DWORD), -] + ("dwSignature", DWORD), + ("dwStrucVersion", DWORD), + ("dwFileVersionMS", DWORD), + ("dwFileVersionLS", DWORD), + ("dwProductVersionMS", DWORD), + ("dwProductVersionLS", DWORD), + ("dwFileFlagsMask", DWORD), + ("dwFileFlags", DWORD), + ("dwFileOS", DWORD), + ("dwFileType", DWORD), + ("dwFileSubtype", DWORD), + ("dwFileDateMS", DWORD), + ("dwFileDateLS", DWORD), + ] + + PVS_FIXEDFILEINFO = POINTER(VS_FIXEDFILEINFO) LPVS_FIXEDFILEINFO = PVS_FIXEDFILEINFO + # BOOL WINAPI GetFileVersionInfo( # _In_ LPCTSTR lptstrFilename, # _Reserved_ DWORD dwHandle, @@ -969,12 +1011,12 @@ class VS_FIXEDFILEINFO(Structure): def GetFileVersionInfoA(lptstrFilename): _GetFileVersionInfoA = windll.version.GetFileVersionInfoA _GetFileVersionInfoA.argtypes = [LPSTR, DWORD, DWORD, LPVOID] - _GetFileVersionInfoA.restype = bool + _GetFileVersionInfoA.restype = bool _GetFileVersionInfoA.errcheck = RaiseIfZero _GetFileVersionInfoSizeA = windll.version.GetFileVersionInfoSizeA _GetFileVersionInfoSizeA.argtypes = [LPSTR, LPVOID] - _GetFileVersionInfoSizeA.restype = DWORD + _GetFileVersionInfoSizeA.restype = DWORD _GetFileVersionInfoSizeA.errcheck = RaiseIfZero dwLen = _GetFileVersionInfoSizeA(lptstrFilename, None) @@ -982,15 +1024,16 @@ def GetFileVersionInfoA(lptstrFilename): _GetFileVersionInfoA(lptstrFilename, 0, dwLen, byref(lpData)) return lpData + def GetFileVersionInfoW(lptstrFilename): _GetFileVersionInfoW = windll.version.GetFileVersionInfoW _GetFileVersionInfoW.argtypes = [LPWSTR, DWORD, DWORD, LPVOID] - _GetFileVersionInfoW.restype = bool + _GetFileVersionInfoW.restype = bool _GetFileVersionInfoW.errcheck = RaiseIfZero _GetFileVersionInfoSizeW = windll.version.GetFileVersionInfoSizeW _GetFileVersionInfoSizeW.argtypes = [LPWSTR, LPVOID] - _GetFileVersionInfoSizeW.restype = DWORD + _GetFileVersionInfoSizeW.restype = DWORD _GetFileVersionInfoSizeW.errcheck = RaiseIfZero dwLen = _GetFileVersionInfoSizeW(lptstrFilename, None) @@ -998,8 +1041,10 @@ def GetFileVersionInfoW(lptstrFilename): _GetFileVersionInfoW(lptstrFilename, 0, dwLen, byref(lpData)) return lpData + GetFileVersionInfo = GuessStringType(GetFileVersionInfoA, GetFileVersionInfoW) + # BOOL WINAPI VerQueryValue( # _In_ LPCVOID pBlock, # _In_ LPCTSTR lpSubBlock, @@ -1009,7 +1054,7 @@ def GetFileVersionInfoW(lptstrFilename): def VerQueryValueA(pBlock, lpSubBlock): _VerQueryValueA = windll.version.VerQueryValueA _VerQueryValueA.argtypes = [LPVOID, LPSTR, LPVOID, POINTER(UINT)] - _VerQueryValueA.restype = bool + _VerQueryValueA.restype = bool _VerQueryValueA.errcheck = RaiseIfZero lpBuffer = LPVOID(0) @@ -1017,10 +1062,11 @@ def VerQueryValueA(pBlock, lpSubBlock): _VerQueryValueA(pBlock, lpSubBlock, byref(lpBuffer), byref(uLen)) return lpBuffer, uLen.value + def VerQueryValueW(pBlock, lpSubBlock): _VerQueryValueW = windll.version.VerQueryValueW _VerQueryValueW.argtypes = [LPVOID, LPWSTR, LPVOID, POINTER(UINT)] - _VerQueryValueW.restype = bool + _VerQueryValueW.restype = bool _VerQueryValueW.errcheck = RaiseIfZero lpBuffer = LPVOID(0) @@ -1028,11 +1074,12 @@ def VerQueryValueW(pBlock, lpSubBlock): _VerQueryValueW(pBlock, lpSubBlock, byref(lpBuffer), byref(uLen)) return lpBuffer, uLen.value + VerQueryValue = GuessStringType(VerQueryValueA, VerQueryValueW) -#============================================================================== +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/win32/wtsapi32.py b/pydevd_attach_to_process/winappdbg/win32/wtsapi32.py index 13227db32..438094a18 100644 --- a/pydevd_attach_to_process/winappdbg/win32/wtsapi32.py +++ b/pydevd_attach_to_process/winappdbg/win32/wtsapi32.py @@ -37,18 +37,18 @@ from winappdbg.win32.defines import * from winappdbg.win32.advapi32 import * -#============================================================================== +# ============================================================================== # This is used later on to calculate the list of exported symbols. _all = None _all = set(vars().keys()) -#============================================================================== +# ============================================================================== -#--- Constants ---------------------------------------------------------------- +# --- Constants ---------------------------------------------------------------- WTS_CURRENT_SERVER_HANDLE = 0 -WTS_CURRENT_SESSION = 1 +WTS_CURRENT_SESSION = 1 -#--- WTS_PROCESS_INFO structure ----------------------------------------------- +# --- WTS_PROCESS_INFO structure ----------------------------------------------- # typedef struct _WTS_PROCESS_INFO { # DWORD SessionId; @@ -57,25 +57,31 @@ # PSID pUserSid; # } WTS_PROCESS_INFO, *PWTS_PROCESS_INFO; + class WTS_PROCESS_INFOA(Structure): _fields_ = [ - ("SessionId", DWORD), - ("ProcessId", DWORD), + ("SessionId", DWORD), + ("ProcessId", DWORD), ("pProcessName", LPSTR), - ("pUserSid", PSID), + ("pUserSid", PSID), ] + + PWTS_PROCESS_INFOA = POINTER(WTS_PROCESS_INFOA) + class WTS_PROCESS_INFOW(Structure): _fields_ = [ - ("SessionId", DWORD), - ("ProcessId", DWORD), + ("SessionId", DWORD), + ("ProcessId", DWORD), ("pProcessName", LPWSTR), - ("pUserSid", PSID), + ("pUserSid", PSID), ] + + PWTS_PROCESS_INFOW = POINTER(WTS_PROCESS_INFOW) -#--- WTSQuerySessionInformation enums and structures -------------------------- +# --- WTSQuerySessionInformation enums and structures -------------------------- # typedef enum _WTS_INFO_CLASS { # WTSInitialProgram = 0, @@ -110,36 +116,36 @@ class WTS_PROCESS_INFOW(Structure): # WTSIsRemoteSession = 29 # } WTS_INFO_CLASS; -WTSInitialProgram = 0 -WTSApplicationName = 1 -WTSWorkingDirectory = 2 -WTSOEMId = 3 -WTSSessionId = 4 -WTSUserName = 5 -WTSWinStationName = 6 -WTSDomainName = 7 -WTSConnectState = 8 -WTSClientBuildNumber = 9 -WTSClientName = 10 -WTSClientDirectory = 11 -WTSClientProductId = 12 -WTSClientHardwareId = 13 -WTSClientAddress = 14 -WTSClientDisplay = 15 -WTSClientProtocolType = 16 -WTSIdleTime = 17 -WTSLogonTime = 18 -WTSIncomingBytes = 19 -WTSOutgoingBytes = 20 -WTSIncomingFrames = 21 -WTSOutgoingFrames = 22 -WTSClientInfo = 23 -WTSSessionInfo = 24 -WTSSessionInfoEx = 25 -WTSConfigInfo = 26 -WTSValidationInfo = 27 -WTSSessionAddressV4 = 28 -WTSIsRemoteSession = 29 +WTSInitialProgram = 0 +WTSApplicationName = 1 +WTSWorkingDirectory = 2 +WTSOEMId = 3 +WTSSessionId = 4 +WTSUserName = 5 +WTSWinStationName = 6 +WTSDomainName = 7 +WTSConnectState = 8 +WTSClientBuildNumber = 9 +WTSClientName = 10 +WTSClientDirectory = 11 +WTSClientProductId = 12 +WTSClientHardwareId = 13 +WTSClientAddress = 14 +WTSClientDisplay = 15 +WTSClientProtocolType = 16 +WTSIdleTime = 17 +WTSLogonTime = 18 +WTSIncomingBytes = 19 +WTSOutgoingBytes = 20 +WTSIncomingFrames = 21 +WTSOutgoingFrames = 22 +WTSClientInfo = 23 +WTSSessionInfo = 24 +WTSSessionInfoEx = 25 +WTSConfigInfo = 26 +WTSValidationInfo = 27 +WTSSessionAddressV4 = 28 +WTSIsRemoteSession = 29 WTS_INFO_CLASS = ctypes.c_int @@ -156,19 +162,20 @@ class WTS_PROCESS_INFOW(Structure): # WTSInit # } WTS_CONNECTSTATE_CLASS; -WTSActive = 0 -WTSConnected = 1 +WTSActive = 0 +WTSConnected = 1 WTSConnectQuery = 2 -WTSShadow = 3 +WTSShadow = 3 WTSDisconnected = 4 -WTSIdle = 5 -WTSListen = 6 -WTSReset = 7 -WTSDown = 8 -WTSInit = 9 +WTSIdle = 5 +WTSListen = 6 +WTSReset = 7 +WTSDown = 8 +WTSInit = 9 WTS_CONNECTSTATE_CLASS = ctypes.c_int + # typedef struct _WTS_CLIENT_DISPLAY { # DWORD HorizontalResolution; # DWORD VerticalResolution; @@ -177,9 +184,11 @@ class WTS_PROCESS_INFOW(Structure): class WTS_CLIENT_DISPLAY(Structure): _fields_ = [ ("HorizontalResolution", DWORD), - ("VerticalResolution", DWORD), - ("ColorDepth", DWORD), + ("VerticalResolution", DWORD), + ("ColorDepth", DWORD), ] + + PWTS_CLIENT_DISPLAY = POINTER(WTS_CLIENT_DISPLAY) # typedef struct _WTS_CLIENT_ADDRESS { @@ -239,7 +248,8 @@ class WTS_CLIENT_DISPLAY(Structure): # XXX TODO -#--- wtsapi32.dll ------------------------------------------------------------- +# --- wtsapi32.dll ------------------------------------------------------------- + # void WTSFreeMemory( # __in PVOID pMemory @@ -247,9 +257,10 @@ class WTS_CLIENT_DISPLAY(Structure): def WTSFreeMemory(pMemory): _WTSFreeMemory = windll.wtsapi32.WTSFreeMemory _WTSFreeMemory.argtypes = [PVOID] - _WTSFreeMemory.restype = None + _WTSFreeMemory.restype = None _WTSFreeMemory(pMemory) + # BOOL WTSEnumerateProcesses( # __in HANDLE hServer, # __in DWORD Reserved, @@ -257,10 +268,10 @@ def WTSFreeMemory(pMemory): # __out PWTS_PROCESS_INFO *ppProcessInfo, # __out DWORD *pCount # ); -def WTSEnumerateProcessesA(hServer = WTS_CURRENT_SERVER_HANDLE): +def WTSEnumerateProcessesA(hServer=WTS_CURRENT_SERVER_HANDLE): _WTSEnumerateProcessesA = windll.wtsapi32.WTSEnumerateProcessesA _WTSEnumerateProcessesA.argtypes = [HANDLE, DWORD, DWORD, POINTER(PWTS_PROCESS_INFOA), PDWORD] - _WTSEnumerateProcessesA.restype = bool + _WTSEnumerateProcessesA.restype = bool _WTSEnumerateProcessesA.errcheck = RaiseIfZero pProcessInfo = PWTS_PROCESS_INFOA() @@ -268,10 +279,11 @@ def WTSEnumerateProcessesA(hServer = WTS_CURRENT_SERVER_HANDLE): _WTSEnumerateProcessesA(hServer, 0, 1, byref(pProcessInfo), byref(Count)) return pProcessInfo, Count.value -def WTSEnumerateProcessesW(hServer = WTS_CURRENT_SERVER_HANDLE): + +def WTSEnumerateProcessesW(hServer=WTS_CURRENT_SERVER_HANDLE): _WTSEnumerateProcessesW = windll.wtsapi32.WTSEnumerateProcessesW _WTSEnumerateProcessesW.argtypes = [HANDLE, DWORD, DWORD, POINTER(PWTS_PROCESS_INFOW), PDWORD] - _WTSEnumerateProcessesW.restype = bool + _WTSEnumerateProcessesW.restype = bool _WTSEnumerateProcessesW.errcheck = RaiseIfZero pProcessInfo = PWTS_PROCESS_INFOW() @@ -279,8 +291,10 @@ def WTSEnumerateProcessesW(hServer = WTS_CURRENT_SERVER_HANDLE): _WTSEnumerateProcessesW(hServer, 0, 1, byref(pProcessInfo), byref(Count)) return pProcessInfo, Count.value + WTSEnumerateProcesses = DefaultStringType(WTSEnumerateProcessesA, WTSEnumerateProcessesW) + # BOOL WTSTerminateProcess( # __in HANDLE hServer, # __in DWORD ProcessId, @@ -289,10 +303,11 @@ def WTSEnumerateProcessesW(hServer = WTS_CURRENT_SERVER_HANDLE): def WTSTerminateProcess(hServer, ProcessId, ExitCode): _WTSTerminateProcess = windll.wtsapi32.WTSTerminateProcess _WTSTerminateProcess.argtypes = [HANDLE, DWORD, DWORD] - _WTSTerminateProcess.restype = bool + _WTSTerminateProcess.restype = bool _WTSTerminateProcess.errcheck = RaiseIfZero _WTSTerminateProcess(hServer, ProcessId, ExitCode) + # BOOL WTSQuerySessionInformation( # __in HANDLE hServer, # __in DWORD SessionId, @@ -303,10 +318,11 @@ def WTSTerminateProcess(hServer, ProcessId, ExitCode): # XXX TODO -#--- kernel32.dll ------------------------------------------------------------- +# --- kernel32.dll ------------------------------------------------------------- # I've no idea why these functions are in kernel32.dll instead of wtsapi32.dll + # BOOL ProcessIdToSessionId( # __in DWORD dwProcessId, # __out DWORD *pSessionId @@ -314,24 +330,26 @@ def WTSTerminateProcess(hServer, ProcessId, ExitCode): def ProcessIdToSessionId(dwProcessId): _ProcessIdToSessionId = windll.kernel32.ProcessIdToSessionId _ProcessIdToSessionId.argtypes = [DWORD, PDWORD] - _ProcessIdToSessionId.restype = bool + _ProcessIdToSessionId.restype = bool _ProcessIdToSessionId.errcheck = RaiseIfZero dwSessionId = DWORD(0) _ProcessIdToSessionId(dwProcessId, byref(dwSessionId)) return dwSessionId.value + # DWORD WTSGetActiveConsoleSessionId(void); def WTSGetActiveConsoleSessionId(): _WTSGetActiveConsoleSessionId = windll.kernel32.WTSGetActiveConsoleSessionId _WTSGetActiveConsoleSessionId.argtypes = [] - _WTSGetActiveConsoleSessionId.restype = DWORD + _WTSGetActiveConsoleSessionId.restype = DWORD _WTSGetActiveConsoleSessionId.errcheck = RaiseIfZero return _WTSGetActiveConsoleSessionId() -#============================================================================== + +# ============================================================================== # This calculates the list of exported symbols. _all = set(vars().keys()).difference(_all) -__all__ = [_x for _x in _all if not _x.startswith('_')] +__all__ = [_x for _x in _all if not _x.startswith("_")] __all__.sort() -#============================================================================== +# ============================================================================== diff --git a/pydevd_attach_to_process/winappdbg/window.py b/pydevd_attach_to_process/winappdbg/window.py index 6e865e7aa..bb98f793e 100644 --- a/pydevd_attach_to_process/winappdbg/window.py +++ b/pydevd_attach_to_process/winappdbg/window.py @@ -37,15 +37,15 @@ __revision__ = "$Id$" -__all__ = ['Window'] +__all__ = ["Window"] from winappdbg import win32 # delayed imports Process = None -Thread = None +Thread = None -#============================================================================== +# ============================================================================== # Unlike Process, Thread and Module, there's no container for Window objects. # That's because Window objects don't really store any data besides the handle. @@ -65,7 +65,8 @@ # point the hook callback to it. We'd need to have the remote procedure call # feature first as (I believe) the hook can't be set remotely in this case. -class Window (object): + +class Window(object): """ Interface to an open window in the current desktop. @@ -120,7 +121,7 @@ class Window (object): @ivar placement: Window placement in the desktop. """ - def __init__(self, hWnd = None, process = None, thread = None): + def __init__(self, hWnd=None, process=None, thread=None): """ @type hWnd: int or L{win32.HWND} @param hWnd: Window handle. @@ -131,9 +132,9 @@ def __init__(self, hWnd = None, process = None, thread = None): @type thread: L{Thread} @param thread: (Optional) Thread that owns this window. """ - self.hWnd = hWnd + self.hWnd = hWnd self.dwProcessId = None - self.dwThreadId = None + self.dwThreadId = None self.set_process(process) self.set_thread(thread) @@ -177,16 +178,15 @@ def get_tid(self): def __get_pid_and_tid(self): "Internally used by get_pid() and get_tid()." - self.dwThreadId, self.dwProcessId = \ - win32.GetWindowThreadProcessId(self.get_handle()) + self.dwThreadId, self.dwProcessId = win32.GetWindowThreadProcessId(self.get_handle()) def __load_Process_class(self): - global Process # delayed import + global Process # delayed import if Process is None: from winappdbg.process import Process def __load_Thread_class(self): - global Thread # delayed import + global Thread # delayed import if Thread is None: from winappdbg.thread import Thread @@ -201,7 +201,7 @@ def get_process(self): self.__process = Process(self.get_pid()) return self.__process - def set_process(self, process = None): + def set_process(self, process=None): """ Manually set the parent process. Use with care! @@ -213,7 +213,7 @@ def set_process(self, process = None): else: self.__load_Process_class() if not isinstance(process, Process): - msg = "Parent process must be a Process instance, " + msg = "Parent process must be a Process instance, " msg += "got %s instead" % type(process) raise TypeError(msg) self.dwProcessId = process.get_pid() @@ -230,7 +230,7 @@ def get_thread(self): self.__thread = Thread(self.get_tid()) return self.__thread - def set_thread(self, thread = None): + def set_thread(self, thread=None): """ Manually set the thread process. Use with care! @@ -242,7 +242,7 @@ def set_thread(self, thread = None): else: self.__load_Thread_class() if not isinstance(thread, Thread): - msg = "Parent thread must be a Thread instance, " + msg = "Parent thread must be a Thread instance, " msg += "got %s instead" % type(thread) raise TypeError(msg) self.dwThreadId = thread.get_tid() @@ -255,12 +255,12 @@ def __get_window(self, hWnd): """ window = Window(hWnd) if window.get_pid() == self.get_pid(): - window.set_process( self.get_process() ) + window.set_process(self.get_process()) if window.get_tid() == self.get_tid(): - window.set_thread( self.get_thread() ) + window.set_thread(self.get_thread()) return window -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def get_classname(self): """ @@ -269,7 +269,7 @@ def get_classname(self): @raise WindowsError: An error occured while processing this request. """ - return win32.GetClassName( self.get_handle() ) + return win32.GetClassName(self.get_handle()) def get_style(self): """ @@ -278,7 +278,7 @@ def get_style(self): @raise WindowsError: An error occured while processing this request. """ - return win32.GetWindowLongPtr( self.get_handle(), win32.GWL_STYLE ) + return win32.GetWindowLongPtr(self.get_handle(), win32.GWL_STYLE) def get_extended_style(self): """ @@ -287,7 +287,7 @@ def get_extended_style(self): @raise WindowsError: An error occured while processing this request. """ - return win32.GetWindowLongPtr( self.get_handle(), win32.GWL_EXSTYLE ) + return win32.GetWindowLongPtr(self.get_handle(), win32.GWL_EXSTYLE) def get_text(self): """ @@ -296,7 +296,7 @@ def get_text(self): @return: Window text (caption) on success, C{None} on error. """ try: - return win32.GetWindowText( self.get_handle() ) + return win32.GetWindowText(self.get_handle()) except WindowsError: return None @@ -311,7 +311,7 @@ def set_text(self, text): @raise WindowsError: An error occured while processing this request. """ - win32.SetWindowText( self.get_handle(), text ) + win32.SetWindowText(self.get_handle(), text) def get_placement(self): """ @@ -324,7 +324,7 @@ def get_placement(self): @raise WindowsError: An error occured while processing this request. """ - return win32.GetWindowPlacement( self.get_handle() ) + return win32.GetWindowPlacement(self.get_handle()) def set_placement(self, placement): """ @@ -337,7 +337,7 @@ def set_placement(self, placement): @raise WindowsError: An error occured while processing this request. """ - win32.SetWindowPlacement( self.get_handle(), placement ) + win32.SetWindowPlacement(self.get_handle(), placement) def get_screen_rect(self): """ @@ -348,7 +348,7 @@ def get_screen_rect(self): @raise WindowsError: An error occured while processing this request. """ - return win32.GetWindowRect( self.get_handle() ) + return win32.GetWindowRect(self.get_handle()) def get_client_rect(self): """ @@ -359,8 +359,8 @@ def get_client_rect(self): @raise WindowsError: An error occured while processing this request. """ - cr = win32.GetClientRect( self.get_handle() ) - cr.left, cr.top = self.client_to_screen(cr.left, cr.top) + cr = win32.GetClientRect(self.get_handle()) + cr.left, cr.top = self.client_to_screen(cr.left, cr.top) cr.right, cr.bottom = self.client_to_screen(cr.right, cr.bottom) return cr @@ -376,7 +376,7 @@ def get_client_rect(self): text = property(get_text, set_text, doc="") placement = property(get_placement, set_placement, doc="") -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def client_to_screen(self, x, y): """ @@ -397,7 +397,7 @@ def client_to_screen(self, x, y): @raise WindowsError: An error occured while processing this request. """ - return tuple( win32.ClientToScreen( self.get_handle(), (x, y) ) ) + return tuple(win32.ClientToScreen(self.get_handle(), (x, y))) def screen_to_client(self, x, y): """ @@ -418,9 +418,9 @@ def screen_to_client(self, x, y): @raise WindowsError: An error occured while processing this request. """ - return tuple( win32.ScreenToClient( self.get_handle(), (x, y) ) ) + return tuple(win32.ScreenToClient(self.get_handle(), (x, y))) -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def get_parent(self): """ @@ -429,7 +429,7 @@ def get_parent(self): @return: Parent window. Returns C{None} if the window has no parent. @raise WindowsError: An error occured while processing this request. """ - hWnd = win32.GetParent( self.get_handle() ) + hWnd = win32.GetParent(self.get_handle()) if hWnd: return self.__get_window(hWnd) @@ -440,10 +440,7 @@ def get_children(self): @return: List of child windows. @raise WindowsError: An error occured while processing this request. """ - return [ - self.__get_window(hWnd) \ - for hWnd in win32.EnumChildWindows( self.get_handle() ) - ] + return [self.__get_window(hWnd) for hWnd in win32.EnumChildWindows(self.get_handle())] def get_tree(self): """ @@ -454,7 +451,7 @@ def get_tree(self): """ subtree = dict() for aWindow in self.get_children(): - subtree[ aWindow ] = aWindow.get_tree() + subtree[aWindow] = aWindow.get_tree() return subtree def get_root(self): @@ -466,13 +463,13 @@ def get_root(self): If this window is already a top-level window, returns itself. @raise WindowsError: An error occured while processing this request. """ - hWnd = self.get_handle() - history = set() + hWnd = self.get_handle() + history = set() hPrevWnd = hWnd while hWnd and hWnd not in history: history.add(hWnd) hPrevWnd = hWnd - hWnd = win32.GetParent(hWnd) + hWnd = win32.GetParent(hWnd) if hWnd in history: # See: https://docs.google.com/View?id=dfqd62nk_228h28szgz return self @@ -480,7 +477,7 @@ def get_root(self): return self.__get_window(hPrevWnd) return self - def get_child_at(self, x, y, bAllowTransparency = True): + def get_child_at(self, x, y, bAllowTransparency=True): """ Get the child window located at the given coordinates. If no such window exists an exception is raised. @@ -504,23 +501,23 @@ def get_child_at(self, x, y, bAllowTransparency = True): """ try: if bAllowTransparency: - hWnd = win32.RealChildWindowFromPoint( self.get_handle(), (x, y) ) + hWnd = win32.RealChildWindowFromPoint(self.get_handle(), (x, y)) else: - hWnd = win32.ChildWindowFromPoint( self.get_handle(), (x, y) ) + hWnd = win32.ChildWindowFromPoint(self.get_handle(), (x, y)) if hWnd: return self.__get_window(hWnd) except WindowsError: pass return None -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def is_valid(self): """ @rtype: bool @return: C{True} if the window handle is still valid. """ - return win32.IsWindow( self.get_handle() ) + return win32.IsWindow(self.get_handle()) def is_visible(self): """ @@ -528,7 +525,7 @@ def is_visible(self): @rtype: bool @return: C{True} if the window is in a visible state. """ - return win32.IsWindowVisible( self.get_handle() ) + return win32.IsWindowVisible(self.get_handle()) def is_enabled(self): """ @@ -536,7 +533,7 @@ def is_enabled(self): @rtype: bool @return: C{True} if the window is in an enabled state. """ - return win32.IsWindowEnabled( self.get_handle() ) + return win32.IsWindowEnabled(self.get_handle()) def is_maximized(self): """ @@ -544,7 +541,7 @@ def is_maximized(self): @rtype: bool @return: C{True} if the window is maximized. """ - return win32.IsZoomed( self.get_handle() ) + return win32.IsZoomed(self.get_handle()) def is_minimized(self): """ @@ -552,7 +549,7 @@ def is_minimized(self): @rtype: bool @return: C{True} if the window is minimized. """ - return win32.IsIconic( self.get_handle() ) + return win32.IsIconic(self.get_handle()) def is_child(self): """ @@ -560,12 +557,12 @@ def is_child(self): @rtype: bool @return: C{True} if the window is a child window. """ - return win32.IsChild( self.get_handle() ) + return win32.IsChild(self.get_handle()) is_zoomed = is_maximized is_iconic = is_minimized -#------------------------------------------------------------------------------ + # ------------------------------------------------------------------------------ def enable(self): """ @@ -575,7 +572,7 @@ def enable(self): @raise WindowsError: An error occured while processing this request. """ - win32.EnableWindow( self.get_handle(), True ) + win32.EnableWindow(self.get_handle(), True) def disable(self): """ @@ -585,9 +582,9 @@ def disable(self): @raise WindowsError: An error occured while processing this request. """ - win32.EnableWindow( self.get_handle(), False ) + win32.EnableWindow(self.get_handle(), False) - def show(self, bAsync = True): + def show(self, bAsync=True): """ Make the window visible. @@ -599,11 +596,11 @@ def show(self, bAsync = True): @raise WindowsError: An error occured while processing this request. """ if bAsync: - win32.ShowWindowAsync( self.get_handle(), win32.SW_SHOW ) + win32.ShowWindowAsync(self.get_handle(), win32.SW_SHOW) else: - win32.ShowWindow( self.get_handle(), win32.SW_SHOW ) + win32.ShowWindow(self.get_handle(), win32.SW_SHOW) - def hide(self, bAsync = True): + def hide(self, bAsync=True): """ Make the window invisible. @@ -615,11 +612,11 @@ def hide(self, bAsync = True): @raise WindowsError: An error occured while processing this request. """ if bAsync: - win32.ShowWindowAsync( self.get_handle(), win32.SW_HIDE ) + win32.ShowWindowAsync(self.get_handle(), win32.SW_HIDE) else: - win32.ShowWindow( self.get_handle(), win32.SW_HIDE ) + win32.ShowWindow(self.get_handle(), win32.SW_HIDE) - def maximize(self, bAsync = True): + def maximize(self, bAsync=True): """ Maximize the window. @@ -631,11 +628,11 @@ def maximize(self, bAsync = True): @raise WindowsError: An error occured while processing this request. """ if bAsync: - win32.ShowWindowAsync( self.get_handle(), win32.SW_MAXIMIZE ) + win32.ShowWindowAsync(self.get_handle(), win32.SW_MAXIMIZE) else: - win32.ShowWindow( self.get_handle(), win32.SW_MAXIMIZE ) + win32.ShowWindow(self.get_handle(), win32.SW_MAXIMIZE) - def minimize(self, bAsync = True): + def minimize(self, bAsync=True): """ Minimize the window. @@ -647,11 +644,11 @@ def minimize(self, bAsync = True): @raise WindowsError: An error occured while processing this request. """ if bAsync: - win32.ShowWindowAsync( self.get_handle(), win32.SW_MINIMIZE ) + win32.ShowWindowAsync(self.get_handle(), win32.SW_MINIMIZE) else: - win32.ShowWindow( self.get_handle(), win32.SW_MINIMIZE ) + win32.ShowWindow(self.get_handle(), win32.SW_MINIMIZE) - def restore(self, bAsync = True): + def restore(self, bAsync=True): """ Unmaximize and unminimize the window. @@ -663,12 +660,11 @@ def restore(self, bAsync = True): @raise WindowsError: An error occured while processing this request. """ if bAsync: - win32.ShowWindowAsync( self.get_handle(), win32.SW_RESTORE ) + win32.ShowWindowAsync(self.get_handle(), win32.SW_RESTORE) else: - win32.ShowWindow( self.get_handle(), win32.SW_RESTORE ) + win32.ShowWindow(self.get_handle(), win32.SW_RESTORE) - def move(self, x = None, y = None, width = None, height = None, - bRepaint = True): + def move(self, x=None, y=None, width=None, height=None, bRepaint=True): """ Moves and/or resizes the window. @@ -714,7 +710,7 @@ def kill(self): """ self.post(win32.WM_QUIT) - def send(self, uMsg, wParam = None, lParam = None, dwTimeout = None): + def send(self, uMsg, wParam=None, lParam=None, dwTimeout=None): """ Send a low-level window message syncronically. @@ -737,11 +733,9 @@ def send(self, uMsg, wParam = None, lParam = None, dwTimeout = None): """ if dwTimeout is None: return win32.SendMessage(self.get_handle(), uMsg, wParam, lParam) - return win32.SendMessageTimeout( - self.get_handle(), uMsg, wParam, lParam, - win32.SMTO_ABORTIFHUNG | win32.SMTO_ERRORONEXIT, dwTimeout) + return win32.SendMessageTimeout(self.get_handle(), uMsg, wParam, lParam, win32.SMTO_ABORTIFHUNG | win32.SMTO_ERRORONEXIT, dwTimeout) - def post(self, uMsg, wParam = None, lParam = None): + def post(self, uMsg, wParam=None, lParam=None): """ Post a low-level window message asyncronically. diff --git a/pydevd_file_utils.py b/pydevd_file_utils.py index 8e300c7ea..f93f974e8 100644 --- a/pydevd_file_utils.py +++ b/pydevd_file_utils.py @@ -1,4 +1,4 @@ -r''' +r""" This module provides utilities to get the absolute filenames so that we can be sure that: - The case of a file will match the actual file in the filesystem (otherwise breakpoints won't be hit). - Providing means for the user to make path conversions when doing a remote debugging session in @@ -39,11 +39,10 @@ @note: for doing a remote debugging session, all the pydevd_ files must be on the server accessible through the PYTHONPATH (and the PATHS_FROM_ECLIPSE_TO_PYTHON only needs to be set on the target machine for the paths that'll actually have breakpoints). -''' +""" from _pydev_bundle import pydev_log -from _pydevd_bundle.pydevd_constants import DebugInfoHolder, IS_WINDOWS, IS_JYTHON, \ - DISABLE_FILE_VALIDATION, is_true_in_env, IS_MAC +from _pydevd_bundle.pydevd_constants import DebugInfoHolder, IS_WINDOWS, IS_JYTHON, DISABLE_FILE_VALIDATION, is_true_in_env, IS_MAC from _pydev_bundle._pydev_filesystem_encoding import getfilesystemencoding from _pydevd_bundle.pydevd_comm_constants import file_system_encoding, filesystem_encoding_is_utf8 from _pydev_bundle.pydev_log import error_once @@ -77,13 +76,14 @@ def _get_library_dir(): library_dir = None try: import sysconfig - library_dir = sysconfig.get_path('purelib') + + library_dir = sysconfig.get_path("purelib") except ImportError: pass # i.e.: Only 2.7 onwards if library_dir is None or not os_path_exists(library_dir): for path in sys.path: - if os_path_exists(path) and os.path.basename(path) == 'site-packages': + if os_path_exists(path) and os.path.basename(path) == "site-packages": library_dir = path break @@ -101,14 +101,14 @@ def _get_library_dir(): # and the 2nd element is the path in the server machine. # see module docstring for more details. try: - PATHS_FROM_ECLIPSE_TO_PYTHON = json.loads(os.environ.get('PATHS_FROM_ECLIPSE_TO_PYTHON', '[]')) + PATHS_FROM_ECLIPSE_TO_PYTHON = json.loads(os.environ.get("PATHS_FROM_ECLIPSE_TO_PYTHON", "[]")) except Exception: - pydev_log.critical('Error loading PATHS_FROM_ECLIPSE_TO_PYTHON from environment variable.') + pydev_log.critical("Error loading PATHS_FROM_ECLIPSE_TO_PYTHON from environment variable.") pydev_log.exception() PATHS_FROM_ECLIPSE_TO_PYTHON = [] else: if not isinstance(PATHS_FROM_ECLIPSE_TO_PYTHON, list): - pydev_log.critical('Expected PATHS_FROM_ECLIPSE_TO_PYTHON loaded from environment variable to be a list.') + pydev_log.critical("Expected PATHS_FROM_ECLIPSE_TO_PYTHON loaded from environment variable to be a list.") PATHS_FROM_ECLIPSE_TO_PYTHON = [] else: # Converting json lists to tuple @@ -120,9 +120,9 @@ def _get_library_dir(): # r'd:\temp\temp_workspace_2\test_python\src\hhh\xxx') # ] -convert_to_long_pathname = lambda filename:filename -convert_to_short_pathname = lambda filename:filename -get_path_with_real_case = lambda filename:filename +convert_to_long_pathname = lambda filename: filename +convert_to_short_pathname = lambda filename: filename +get_path_with_real_case = lambda filename: filename # Note that we have a cache for previous list dirs... the only case where this may be an # issue is if the user actually changes the case of an existing file on while @@ -155,15 +155,14 @@ def _resolve_listing(resolved, iter_parts_lowercase, cache=_listdir_cache): cache[(resolved_lower, resolve_lowercase)] = resolved_joined break else: - raise FileNotFoundError('Unable to find: %s in %s. Dir Contents: %s' % ( - resolve_lowercase, resolved, dir_contents)) + raise FileNotFoundError("Unable to find: %s in %s. Dir Contents: %s" % (resolve_lowercase, resolved, dir_contents)) resolved = resolved_joined def _resolve_listing_parts(resolved, parts_in_lowercase, filename): try: - if parts_in_lowercase == ['']: + if parts_in_lowercase == [""]: return resolved return _resolve_listing(resolved, iter(parts_in_lowercase)) except FileNotFoundError: @@ -175,10 +174,12 @@ def _resolve_listing_parts(resolved, parts_in_lowercase, filename): if os_path_exists(filename): # This is really strange, ask the user to report as error. pydev_log.critical( - 'pydev debugger: critical: unable to get real case for file. Details:\n' - 'filename: %s\ndrive: %s\nparts: %s\n' - '(please create a ticket in the tracker to address this).', - filename, resolved, parts_in_lowercase + "pydev debugger: critical: unable to get real case for file. Details:\n" + "filename: %s\ndrive: %s\nparts: %s\n" + "(please create a ticket in the tracker to address this).", + filename, + resolved, + parts_in_lowercase, ) pydev_log.exception() # Don't fail, just return the original file passed. @@ -189,15 +190,16 @@ def _resolve_listing_parts(resolved, parts_in_lowercase, filename): # Don't fail nor log unless the trace level is at least info. Just return the original file passed. if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: pydev_log.info( - 'pydev debugger: OSError: Unable to get real case for file. Details:\n' - 'filename: %s\ndrive: %s\nparts: %s\n', - filename, resolved, parts_in_lowercase + "pydev debugger: OSError: Unable to get real case for file. Details:\n" "filename: %s\ndrive: %s\nparts: %s\n", + filename, + resolved, + parts_in_lowercase, ) pydev_log.exception() return filename -if sys.platform == 'win32': +if sys.platform == "win32": try: import ctypes from ctypes.wintypes import MAX_PATH, LPCWSTR, LPWSTR, DWORD @@ -235,10 +237,10 @@ def _get_path_with_real_case(filename): # consistently (there are settings to disable it on Windows). # So, using approach which resolves by listing the dir. - if '~' in filename: + if "~" in filename: filename = convert_to_long_pathname(filename) - if filename.startswith('<') or not os_path_exists(filename): + if filename.startswith("<") or not os_path_exists(filename): return filename # Not much we can do. drive, parts = os.path.splitdrive(os.path.normpath(filename)) @@ -263,10 +265,11 @@ def _get_path_with_real_case(filename): elif IS_JYTHON and IS_WINDOWS: def get_path_with_real_case(filename): - if filename.startswith('<'): + if filename.startswith("<"): return filename from java.io import File # noqa + f = File(filename) ret = f.getCanonicalPath() return ret @@ -274,18 +277,19 @@ def get_path_with_real_case(filename): elif IS_MAC: def get_path_with_real_case(filename): - if filename.startswith('<') or not os_path_exists(filename): + if filename.startswith("<") or not os_path_exists(filename): return filename # Not much we can do. - parts = filename.lower().split('/') + parts = filename.lower().split("/") - found = '' - while parts and parts[0] == '': - found += '/' + found = "" + while parts and parts[0] == "": + found += "/" parts = parts[1:] return _resolve_listing_parts(found, parts, filename) + if IS_JYTHON: def _normcase_windows(filename): @@ -295,7 +299,7 @@ def _normcase_windows(filename): def _normcase_windows(filename): # `normcase` doesn't lower case on Python 2 for non-English locale, so we should do it manually. - if '~' in filename: + if "~" in filename: filename = convert_to_long_pathname(filename) filename = _nt_os_normcase(filename) @@ -306,8 +310,8 @@ def _normcase_linux(filename): return filename # no-op -_filename_normalization = os.environ.get('PYDEVD_FILENAME_NORMALIZATION', '').lower() -if _filename_normalization == 'lower': +_filename_normalization = os.environ.get("PYDEVD_FILENAME_NORMALIZATION", "").lower() +if _filename_normalization == "lower": # Note: this is mostly for testing (forcing to always lower-case all contents # internally -- used to mimick Windows normalization on Linux). @@ -316,7 +320,7 @@ def _normcase_lower(filename): _default_normcase = _normcase_lower -elif _filename_normalization == 'none': +elif _filename_normalization == "none": # Disable any filename normalization may be an option on Windows if the # user is having issues under some circumstances. _default_normcase = _normcase_linux @@ -343,7 +347,7 @@ def normcase(s, NORMCASE_CACHE={}): return normalized -_ide_os = 'WINDOWS' if IS_WINDOWS else 'UNIX' +_ide_os = "WINDOWS" if IS_WINDOWS else "UNIX" _normcase_from_client = normcase @@ -352,32 +356,31 @@ def normcase_from_client(s): return _normcase_from_client(s) -DEBUG_CLIENT_SERVER_TRANSLATION = os.environ.get('DEBUG_PYDEVD_PATHS_TRANSLATION', 'False').lower() in ('1', 'true') +DEBUG_CLIENT_SERVER_TRANSLATION = os.environ.get("DEBUG_PYDEVD_PATHS_TRANSLATION", "False").lower() in ("1", "true") def set_ide_os(os): - ''' + """ We need to set the IDE os because the host where the code is running may be actually different from the client (and the point is that we want the proper paths to translate from the client to the server). :param os: 'UNIX' or 'WINDOWS' - ''' + """ global _ide_os global _normcase_from_client prev = _ide_os - if os == 'WIN': # Apparently PyCharm uses 'WIN' (https://github.com/fabioz/PyDev.Debugger/issues/116) - os = 'WINDOWS' + if os == "WIN": # Apparently PyCharm uses 'WIN' (https://github.com/fabioz/PyDev.Debugger/issues/116) + os = "WINDOWS" - assert os in ('WINDOWS', 'UNIX') + assert os in ("WINDOWS", "UNIX") if DEBUG_CLIENT_SERVER_TRANSLATION: - print('pydev debugger: client OS: %s' % (os,)) + print("pydev debugger: client OS: %s" % (os,)) _normcase_from_client = normcase - if os == 'WINDOWS': - + if os == "WINDOWS": # Client in Windows and server in Unix, we need to normalize the case. if not IS_WINDOWS: _normcase_from_client = _normcase_windows @@ -399,28 +402,28 @@ def set_ide_os(os): def canonical_normalized_path(filename): - ''' + """ This returns a filename that is canonical and it's meant to be used internally to store information on breakpoints and see if there's any hit on it. Note that this version is only internal as it may not match the case and may have symlinks resolved (and thus may not match what the user expects in the editor). - ''' + """ return get_abs_path_real_path_and_base_from_file(filename)[1] def absolute_path(filename): - ''' + """ Provides a version of the filename that's absolute (and NOT normalized). - ''' + """ return get_abs_path_real_path_and_base_from_file(filename)[0] def basename(filename): - ''' + """ Provides the basename for a file. - ''' + """ return get_abs_path_real_path_and_base_from_file(filename)[2] @@ -430,7 +433,7 @@ def _abs_and_canonical_path(filename, NORM_PATHS_CONTAINER=NORM_PATHS_CONTAINER) return NORM_PATHS_CONTAINER[filename] except: if filename.__class__ != str: - raise AssertionError('Paths passed to _abs_and_canonical_path must be str. Found: %s (%s)' % (filename, type(filename))) + raise AssertionError("Paths passed to _abs_and_canonical_path must be str. Found: %s (%s)" % (filename, type(filename))) if os is None: # Interpreter shutdown return filename, filename @@ -475,7 +478,7 @@ def _get_relative_filename_abs_path(filename, func, os_path_exists=os_path_exist def _apply_func_and_normalize_case(filename, func, isabs, normalize_case, os_path_exists=os_path_exists, join=join): - if filename.startswith('<'): + if filename.startswith("<"): # Not really a file, rather a synthetic name like or ; # shouldn't be normalized. return filename @@ -486,23 +489,23 @@ def _apply_func_and_normalize_case(filename, func, isabs, normalize_case, os_pat if not os_path_exists(r): r = _get_relative_filename_abs_path(filename, func) - ind = r.find('.zip') + ind = r.find(".zip") if ind == -1: - ind = r.find('.egg') + ind = r.find(".egg") if ind != -1: ind += 4 zip_path = r[:ind] inner_path = r[ind:] - if inner_path.startswith('!'): + if inner_path.startswith("!"): # Note (fabioz): although I can replicate this by creating a file ending as # .zip! or .egg!, I don't really know what's the real-world case for this # (still kept as it was added by @jetbrains, but it should probably be reviewed # later on). # Note 2: it goes hand-in-hand with 'exists'. inner_path = inner_path[1:] - zip_path = zip_path + '!' + zip_path = zip_path + "!" - if inner_path.startswith('/') or inner_path.startswith('\\'): + if inner_path.startswith("/") or inner_path.startswith("\\"): inner_path = inner_path[1:] if inner_path: if normalize_case: @@ -529,9 +532,9 @@ def exists(filename): if os_path_exists(filename): return True - ind = filename.find('.zip') + ind = filename.find(".zip") if ind == -1: - ind = filename.find('.egg') + ind = filename.find(".egg") if ind != -1: ind += 4 @@ -544,7 +547,7 @@ def exists(filename): # later on). # Note 2: it goes hand-in-hand with '_apply_func_and_normalize_case'. inner_path = inner_path[1:] - zip_path = zip_path + '!' + zip_path = zip_path + "!" zip_file_obj = _ZIP_SEARCH_CACHE.get(zip_path, _NOT_FOUND_SENTINEL) if zip_file_obj is None: @@ -552,24 +555,25 @@ def exists(filename): elif zip_file_obj is _NOT_FOUND_SENTINEL: try: import zipfile - zip_file_obj = zipfile.ZipFile(zip_path, 'r') + + zip_file_obj = zipfile.ZipFile(zip_path, "r") _ZIP_SEARCH_CACHE[zip_path] = zip_file_obj except: _ZIP_SEARCH_CACHE[zip_path] = _NOT_FOUND_SENTINEL return False try: - if inner_path.startswith('/') or inner_path.startswith('\\'): + if inner_path.startswith("/") or inner_path.startswith("\\"): inner_path = inner_path[1:] - _info = zip_file_obj.getinfo(inner_path.replace('\\', '/')) + _info = zip_file_obj.getinfo(inner_path.replace("\\", "/")) return join(zip_path, inner_path) except KeyError: return False else: - pydev_log.debug('os.path.exists(%r) returned False.', filename) + pydev_log.debug("os.path.exists(%r) returned False.", filename) return False @@ -584,22 +588,22 @@ def exists(filename): except AttributeError: code = os_path_real_path.__code__ - if code.co_filename.startswith(' in this case). - f = '' + f = "" - if f.startswith('<'): + if f.startswith("<"): return f, normcase(f), f if _abs_and_canonical_path is None: # Interpreter shutdown - i = max(f.rfind('/'), f.rfind('\\')) - return (f, f, f[i + 1:]) + i = max(f.rfind("/"), f.rfind("\\")) + return (f, f, f[i + 1 :]) if f is not None: - if f.endswith('.pyc'): + if f.endswith(".pyc"): f = f[:-1] - elif f.endswith('$py.class'): - f = f[:-len('$py.class')] + '.py' + elif f.endswith("$py.class"): + f = f[: -len("$py.class")] + ".py" abs_path, canonical_normalized_filename = _abs_and_canonical_path(f) @@ -900,8 +909,8 @@ def get_abs_path_real_path_and_base_from_file( base = os_path_basename(canonical_normalized_filename) except AttributeError: # Error during shutdown. - i = max(f.rfind('/'), f.rfind('\\')) - base = f[i + 1:] + i = max(f.rfind("/"), f.rfind("\\")) + base = f[i + 1 :] ret = abs_path, canonical_normalized_filename, base NORM_PATHS_AND_BASE_CONTAINER[filename] = ret return ret @@ -914,18 +923,18 @@ def get_abs_path_real_path_and_base_from_frame(frame, NORM_PATHS_AND_BASE_CONTAI # This one is just internal (so, does not need any kind of client-server translation) f = frame.f_code.co_filename - if f is not None and f.startswith (('build/bdist.', 'build\\bdist.')): + if f is not None and f.startswith(("build/bdist.", "build\\bdist.")): # files from eggs in Python 2.7 have paths like build/bdist.linux-x86_64/egg/ - f = frame.f_globals['__file__'] + f = frame.f_globals["__file__"] if get_abs_path_real_path_and_base_from_file is None: # Interpreter shutdown if not f: # i.e.: it's possible that the user compiled code with an empty string (consider # it as in this case). - f = '' - i = max(f.rfind('/'), f.rfind('\\')) - return f, f, f[i + 1:] + f = "" + i = max(f.rfind("/"), f.rfind("\\")) + return f, f, f[i + 1 :] ret = get_abs_path_real_path_and_base_from_file(f) # Also cache based on the frame.f_code.co_filename (if we had it inside build/bdist it can make a difference). @@ -935,6 +944,7 @@ def get_abs_path_real_path_and_base_from_frame(frame, NORM_PATHS_AND_BASE_CONTAI def get_fullname(mod_name): import pkgutil + try: loader = pkgutil.get_loader(mod_name) except: @@ -949,8 +959,7 @@ def get_fullname(mod_name): def get_package_dir(mod_name): for path in sys.path: - mod_path = join(path, mod_name.replace('.', '/')) + mod_path = join(path, mod_name.replace(".", "/")) if os.path.isdir(mod_path): return mod_path return None - diff --git a/pydevd_plugins/__init__.py b/pydevd_plugins/__init__.py index bb61062c9..f77af49c2 100644 --- a/pydevd_plugins/__init__.py +++ b/pydevd_plugins/__init__.py @@ -1,2 +1,3 @@ import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/pydevd_plugins/django_debug.py b/pydevd_plugins/django_debug.py index e621891a5..b7baa372b 100644 --- a/pydevd_plugins/django_debug.py +++ b/pydevd_plugins/django_debug.py @@ -2,8 +2,7 @@ from _pydev_bundle import pydev_log from _pydevd_bundle.pydevd_comm import CMD_SET_BREAK, CMD_ADD_EXCEPTION_BREAK -from _pydevd_bundle.pydevd_constants import STATE_SUSPEND, DJANGO_SUSPEND, \ - DebugInfoHolder +from _pydevd_bundle.pydevd_constants import STATE_SUSPEND, DJANGO_SUSPEND, DebugInfoHolder from _pydevd_bundle.pydevd_frame_utils import add_exception_to_frame, FCode, just_raised, ignore_exception_trace from pydevd_file_utils import canonical_normalized_path, absolute_path from _pydevd_bundle.pydevd_api import PyDevdAPI @@ -15,26 +14,29 @@ IS_DJANGO19_OR_HIGHER = False try: import django + version = django.VERSION IS_DJANGO18 = version[0] == 1 and version[1] == 8 IS_DJANGO19 = version[0] == 1 and version[1] == 9 - IS_DJANGO19_OR_HIGHER = ((version[0] == 1 and version[1] >= 9) or version[0] > 1) + IS_DJANGO19_OR_HIGHER = (version[0] == 1 and version[1] >= 9) or version[0] > 1 except: pass class DjangoLineBreakpoint(LineBreakpointWithLazyValidation): - - def __init__(self, canonical_normalized_filename, breakpoint_id, line, condition, func_name, expression, hit_condition=None, is_logpoint=False): + def __init__( + self, canonical_normalized_filename, breakpoint_id, line, condition, func_name, expression, hit_condition=None, is_logpoint=False + ): self.canonical_normalized_filename = canonical_normalized_filename - LineBreakpointWithLazyValidation.__init__(self, breakpoint_id, line, condition, func_name, expression, hit_condition=hit_condition, is_logpoint=is_logpoint) + LineBreakpointWithLazyValidation.__init__( + self, breakpoint_id, line, condition, func_name, expression, hit_condition=hit_condition, is_logpoint=is_logpoint + ) def __str__(self): return "DjangoLineBreakpoint: %s-%d" % (self.canonical_normalized_filename, self.line) class _DjangoValidationInfo(ValidationInfo): - @overrides(ValidationInfo._collect_valid_lines_in_template_uncached) def _collect_valid_lines_in_template_uncached(self, template): lines = set() @@ -47,7 +49,7 @@ def _collect_valid_lines_in_template_uncached(self, template): return lines def _get_lineno(self, node): - if hasattr(node, 'token') and hasattr(node.token, 'lineno'): + if hasattr(node, "token") and hasattr(node.token, "lineno"): return node.token.lineno return None @@ -68,10 +70,32 @@ def _iternodes(self, nodelist): yield node -def add_line_breakpoint(pydb, type, canonical_normalized_filename, breakpoint_id, line, condition, expression, func_name, hit_condition=None, is_logpoint=False, add_breakpoint_result=None, on_changed_breakpoint_state=None): - if type == 'django-line': - django_line_breakpoint = DjangoLineBreakpoint(canonical_normalized_filename, breakpoint_id, line, condition, func_name, expression, hit_condition=hit_condition, is_logpoint=is_logpoint) - if not hasattr(pydb, 'django_breakpoints'): +def add_line_breakpoint( + pydb, + type, + canonical_normalized_filename, + breakpoint_id, + line, + condition, + expression, + func_name, + hit_condition=None, + is_logpoint=False, + add_breakpoint_result=None, + on_changed_breakpoint_state=None, +): + if type == "django-line": + django_line_breakpoint = DjangoLineBreakpoint( + canonical_normalized_filename, + breakpoint_id, + line, + condition, + func_name, + expression, + hit_condition=hit_condition, + is_logpoint=is_logpoint, + ) + if not hasattr(pydb, "django_breakpoints"): _init_plugin_breaks(pydb) if IS_DJANGO19_OR_HIGHER: @@ -91,18 +115,19 @@ def after_breakpoints_consolidated(py_db, canonical_normalized_filename, id_to_p if not django_breakpoints_for_file: return - if not hasattr(py_db, 'django_validation_info'): + if not hasattr(py_db, "django_validation_info"): _init_plugin_breaks(py_db) # In general we validate the breakpoints only when the template is loaded, but if the template # was already loaded, we can validate the breakpoints based on the last loaded value. py_db.django_validation_info.verify_breakpoints_from_template_cached_lines( - py_db, canonical_normalized_filename, django_breakpoints_for_file) + py_db, canonical_normalized_filename, django_breakpoints_for_file + ) def add_exception_breakpoint(pydb, type, exception): - if type == 'django': - if not hasattr(pydb, 'django_exception_break'): + if type == "django": + if not hasattr(pydb, "django_exception_break"): _init_plugin_breaks(pydb) pydb.django_exception_break[exception] = True return True @@ -117,7 +142,7 @@ def _init_plugin_breaks(pydb): def remove_exception_breakpoint(pydb, exception_type, exception): - if exception_type == 'django': + if exception_type == "django": try: del pydb.django_exception_break[exception] return True @@ -127,14 +152,14 @@ def remove_exception_breakpoint(pydb, exception_type, exception): def remove_all_exception_breakpoints(pydb): - if hasattr(pydb, 'django_exception_break'): + if hasattr(pydb, "django_exception_break"): pydb.django_exception_break = {} return True return False def get_breakpoints(pydb, breakpoint_type): - if breakpoint_type == 'django-line': + if breakpoint_type == "django-line": return pydb.django_breakpoints return None @@ -150,21 +175,21 @@ def _inherits(cls, *names): return inherits_node -_IGNORE_RENDER_OF_CLASSES = ('TextNode', 'NodeList') +_IGNORE_RENDER_OF_CLASSES = ("TextNode", "NodeList") def _is_django_render_call(frame): try: name = frame.f_code.co_name - if name != 'render': + if name != "render": return False - if 'self' not in frame.f_locals: + if "self" not in frame.f_locals: return False - cls = frame.f_locals['self'].__class__ + cls = frame.f_locals["self"].__class__ - inherits_node = _inherits(cls, 'Node') + inherits_node = _inherits(cls, "Node") if not inherits_node: return False @@ -172,9 +197,9 @@ def _is_django_render_call(frame): clsname = cls.__name__ if IS_DJANGO19: # in Django 1.9 we need to save the flag that there is included template - if clsname == 'IncludeNode': - if 'context' in frame.f_locals: - context = frame.f_locals['context'] + if clsname == "IncludeNode": + if "context" in frame.f_locals: + context = frame.f_locals["context"] context._has_included_template = True return clsname not in _IGNORE_RENDER_OF_CLASSES @@ -185,12 +210,12 @@ def _is_django_render_call(frame): def _is_django_context_get_call(frame): try: - if 'self' not in frame.f_locals: + if "self" not in frame.f_locals: return False - cls = frame.f_locals['self'].__class__ + cls = frame.f_locals["self"].__class__ - return _inherits(cls, 'BaseContext') + return _inherits(cls, "BaseContext") except: pydev_log.exception() return False @@ -199,16 +224,16 @@ def _is_django_context_get_call(frame): def _is_django_resolve_call(frame): try: name = frame.f_code.co_name - if name != '_resolve_lookup': + if name != "_resolve_lookup": return False - if 'self' not in frame.f_locals: + if "self" not in frame.f_locals: return False - cls = frame.f_locals['self'].__class__ + cls = frame.f_locals["self"].__class__ clsname = cls.__name__ - return clsname == 'Variable' + return clsname == "Variable" except: pydev_log.exception() return False @@ -234,14 +259,15 @@ def _find_django_render_frame(frame): return frame -#======================================================================================================================= + +# ======================================================================================================================= # Django Frame -#======================================================================================================================= +# ======================================================================================================================= def _read_file(filename): # type: (str) -> str - f = open(filename, 'r', encoding='utf-8', errors='replace') + f = open(filename, "r", encoding="utf-8", errors="replace") s = f.read() f.close() return s @@ -254,11 +280,11 @@ def _offset_to_line_number(text, offset): if curOffset == len(text): return -1 c = text[curOffset] - if c == '\n': + if c == "\n": curLine += 1 - elif c == '\r': + elif c == "\r": curLine += 1 - if curOffset < len(text) and text[curOffset + 1] == '\n': + if curOffset < len(text) and text[curOffset + 1] == "\n": curOffset += 1 curOffset += 1 @@ -269,18 +295,21 @@ def _offset_to_line_number(text, offset): def _get_source_django_18_or_lower(frame): # This method is usable only for the Django <= 1.8 try: - node = frame.f_locals['self'] - if hasattr(node, 'source'): + node = frame.f_locals["self"] + if hasattr(node, "source"): return node.source else: if IS_DJANGO18: # The debug setting was changed since Django 1.8 - pydev_log.error_once("WARNING: Template path is not available. Set the 'debug' option in the OPTIONS of a DjangoTemplates " - "backend.") + pydev_log.error_once( + "WARNING: Template path is not available. Set the 'debug' option in the OPTIONS of a DjangoTemplates " "backend." + ) else: # The debug setting for Django < 1.8 - pydev_log.error_once("WARNING: Template path is not available. Please set TEMPLATE_DEBUG=True in your settings.py to make " - "django template breakpoints working") + pydev_log.error_once( + "WARNING: Template path is not available. Please set TEMPLATE_DEBUG=True in your settings.py to make " + "django template breakpoints working" + ) return None except: @@ -296,29 +325,27 @@ def _get_template_original_file_name_from_frame(frame): try: if IS_DJANGO19: # The Node source was removed since Django 1.9 - if 'context' in frame.f_locals: - context = frame.f_locals['context'] - if hasattr(context, '_has_included_template'): + if "context" in frame.f_locals: + context = frame.f_locals["context"] + if hasattr(context, "_has_included_template"): # if there was included template we need to inspect the previous frames and find its name back = frame.f_back - while back is not None and frame.f_code.co_name in ('render', '_render'): + while back is not None and frame.f_code.co_name in ("render", "_render"): locals = back.f_locals - if 'self' in locals: - self = locals['self'] - if self.__class__.__name__ == 'Template' and hasattr(self, 'origin') and \ - hasattr(self.origin, 'name'): + if "self" in locals: + self = locals["self"] + if self.__class__.__name__ == "Template" and hasattr(self, "origin") and hasattr(self.origin, "name"): return _convert_to_str(self.origin.name) back = back.f_back else: - if hasattr(context, 'template') and hasattr(context.template, 'origin') and \ - hasattr(context.template.origin, 'name'): + if hasattr(context, "template") and hasattr(context.template, "origin") and hasattr(context.template.origin, "name"): return _convert_to_str(context.template.origin.name) return None elif IS_DJANGO19_OR_HIGHER: # For Django 1.10 and later there is much simpler way to get template name - if 'self' in frame.f_locals: - self = frame.f_locals['self'] - if hasattr(self, 'origin') and hasattr(self.origin, 'name'): + if "self" in frame.f_locals: + self = frame.f_locals["self"] + if hasattr(self, "origin") and hasattr(self.origin, "name"): return _convert_to_str(self.origin.name) return None @@ -328,21 +355,21 @@ def _get_template_original_file_name_from_frame(frame): return None fname = _convert_to_str(source[0].name) - if fname == '': + if fname == "": pydev_log.debug("Source name is %s\n" % fname) return None else: return fname except: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 2: - pydev_log.exception('Error getting django template filename.') + pydev_log.exception("Error getting django template filename.") return None def _get_template_line(frame): if IS_DJANGO19_OR_HIGHER: - node = frame.f_locals['self'] - if hasattr(node, 'token') and hasattr(node.token, 'lineno'): + node = frame.f_locals["self"] + if hasattr(node, "token") and hasattr(node.token, "lineno"): return node.token.lineno else: return None @@ -359,13 +386,12 @@ def _get_template_line(frame): class DjangoTemplateFrame(object): - IS_PLUGIN_FRAME = True def __init__(self, frame): original_filename = _get_template_original_file_name_from_frame(frame) - self._back_context = frame.f_locals['context'] - self.f_code = FCode('Django Template', original_filename) + self._back_context = frame.f_locals["context"] + self.f_code = FCode("Django Template", original_filename) self.f_lineno = _get_template_line(frame) self.f_back = frame self.f_globals = {} @@ -378,7 +404,7 @@ def _collect_context(self, context): for d in context.dicts: for k, v in d.items(): res[k] = v - except AttributeError: + except AttributeError: pass return res @@ -390,11 +416,10 @@ def _change_variable(self, name, value): class DjangoTemplateSyntaxErrorFrame(object): - IS_PLUGIN_FRAME = True def __init__(self, frame, original_filename, lineno, f_locals): - self.f_code = FCode('Django TemplateSyntaxError', original_filename) + self.f_code = FCode("Django TemplateSyntaxError", original_filename) self.f_lineno = lineno self.f_back = frame self.f_globals = {} @@ -415,22 +440,23 @@ def _is_django_variable_does_not_exist_exception_break_context(frame): name = frame.f_code.co_name except: name = None - return name in ('_resolve_lookup', 'find_template') + return name in ("_resolve_lookup", "find_template") def _is_ignoring_failures(frame): while frame is not None: - if frame.f_code.co_name == 'resolve': - ignore_failures = frame.f_locals.get('ignore_failures') + if frame.f_code.co_name == "resolve": + ignore_failures = frame.f_locals.get("ignore_failures") if ignore_failures: return True frame = frame.f_back return False -#======================================================================================================================= + +# ======================================================================================================================= # Django Step Commands -#======================================================================================================================= +# ======================================================================================================================= def can_skip(py_db, frame): @@ -439,9 +465,9 @@ def can_skip(py_db, frame): return False if py_db.django_exception_break: - module_name = frame.f_globals.get('__name__', '') + module_name = frame.f_globals.get("__name__", "") - if module_name == 'django.template.base': + if module_name == "django.template.base": # Exceptions raised at django.template.base must be checked. return False @@ -452,11 +478,11 @@ def can_skip(py_db, frame): def required_events_breakpoint(): - return ('call',) + return ("call",) def required_events_stepping(): - return ('call', 'return') + return ("call", "return") def has_exception_breaks(py_db): @@ -475,7 +501,7 @@ def has_line_breaks(py_db): def cmd_step_into(py_db, frame, event, info, thread, stop_info, stop): plugin_stop = False if _is_django_suspended(thread): - plugin_stop = stop_info['django_stop'] = event == 'call' and _is_django_render_call(frame) + plugin_stop = stop_info["django_stop"] = event == "call" and _is_django_render_call(frame) stop = stop and _is_django_resolve_call(frame.f_back) and not _is_django_context_get_call(frame) if stop: info.pydev_django_resolve_frame = True # we remember that we've go into python code from django rendering frame @@ -485,21 +511,21 @@ def cmd_step_into(py_db, frame, event, info, thread, stop_info, stop): def cmd_step_over(py_db, frame, event, info, thread, stop_info, stop): plugin_stop = False if _is_django_suspended(thread): - plugin_stop = stop_info['django_stop'] = event == 'call' and _is_django_render_call(frame) + plugin_stop = stop_info["django_stop"] = event == "call" and _is_django_render_call(frame) stop = False return stop, plugin_stop else: - if event == 'return' and info.pydev_django_resolve_frame and _is_django_resolve_call(frame.f_back): + if event == "return" and info.pydev_django_resolve_frame and _is_django_resolve_call(frame.f_back): # we return to Django suspend mode and should not stop before django rendering frame info.pydev_step_stop = frame.f_back info.pydev_django_resolve_frame = False thread.additional_info.suspend_type = DJANGO_SUSPEND - stop = info.pydev_step_stop is frame and event in ('line', 'return') + stop = info.pydev_step_stop is frame and event in ("line", "return") return stop, plugin_stop def stop(py_db, frame, event, thread, stop_info, arg, step_cmd): - if 'django_stop' in stop_info and stop_info['django_stop']: + if "django_stop" in stop_info and stop_info["django_stop"]: frame = suspend_django(py_db, thread, DjangoTemplateFrame(frame), step_cmd) if frame: py_db.do_wait_suspend(thread, frame, event, arg) @@ -508,9 +534,9 @@ def stop(py_db, frame, event, thread, stop_info, arg, step_cmd): def get_breakpoint(py_db, frame, event, info): - breakpoint_type = 'django' + breakpoint_type = "django" - if event == 'call' and info.pydev_state != STATE_SUSPEND and py_db.django_breakpoints and _is_django_render_call(frame): + if event == "call" and info.pydev_state != STATE_SUSPEND and py_db.django_breakpoints and _is_django_render_call(frame): original_filename = _get_template_original_file_name_from_frame(frame) pydev_log.debug("Django is rendering a template: %s", original_filename) @@ -518,13 +544,14 @@ def get_breakpoint(py_db, frame, event, info): django_breakpoints_for_file = py_db.django_breakpoints.get(canonical_normalized_filename) if django_breakpoints_for_file: - # At this point, let's validate whether template lines are correct. if IS_DJANGO19_OR_HIGHER: django_validation_info = py_db.django_validation_info - context = frame.f_locals['context'] + context = frame.f_locals["context"] django_template = context.template - django_validation_info.verify_breakpoints(py_db, canonical_normalized_filename, django_breakpoints_for_file, django_template) + django_validation_info.verify_breakpoints( + py_db, canonical_normalized_filename, django_breakpoints_for_file, django_template + ) pydev_log.debug("Breakpoints for that file: %s", django_breakpoints_for_file) template_line = _get_template_line(frame) @@ -539,7 +566,7 @@ def get_breakpoint(py_db, frame, event, info): def suspend(py_db, thread, frame, bp_type): - if bp_type == 'django': + if bp_type == "django": return suspend_django(py_db, thread, DjangoTemplateFrame(frame)) return None @@ -552,9 +579,9 @@ def _get_original_filename_from_origin_in_parent_frame_locals(frame, parent_fram origin = None if parent_frame is not None: - origin = parent_frame.f_locals.get('origin') + origin = parent_frame.f_locals.get("origin") - if hasattr(origin, 'name') and origin.name is not None: + if hasattr(origin, "name") and origin.name is not None: filename = _convert_to_str(origin.name) return filename @@ -563,47 +590,48 @@ def exception_break(py_db, frame, thread, arg): exception, value, trace = arg if py_db.django_exception_break and exception is not None: - if exception.__name__ in ['VariableDoesNotExist', 'TemplateDoesNotExist', 'TemplateSyntaxError'] and \ - just_raised(trace) and not ignore_exception_trace(trace): - - if exception.__name__ == 'TemplateSyntaxError': + if ( + exception.__name__ in ["VariableDoesNotExist", "TemplateDoesNotExist", "TemplateSyntaxError"] + and just_raised(trace) + and not ignore_exception_trace(trace) + ): + if exception.__name__ == "TemplateSyntaxError": # In this case we don't actually have a regular render frame with the context # (we didn't really get to that point). - token = getattr(value, 'token', None) + token = getattr(value, "token", None) if token is None: # Django 1.7 does not have token in exception. Try to get it from locals. - token = frame.f_locals.get('token') + token = frame.f_locals.get("token") - lineno = getattr(token, 'lineno', None) + lineno = getattr(token, "lineno", None) original_filename = None if lineno is not None: - original_filename = _get_original_filename_from_origin_in_parent_frame_locals(frame, 'get_template') + original_filename = _get_original_filename_from_origin_in_parent_frame_locals(frame, "get_template") if original_filename is None: # Django 1.7 does not have origin in get_template. Try to get it from # load_template. - original_filename = _get_original_filename_from_origin_in_parent_frame_locals(frame, 'load_template') + original_filename = _get_original_filename_from_origin_in_parent_frame_locals(frame, "load_template") if original_filename is not None and lineno is not None: syntax_error_frame = DjangoTemplateSyntaxErrorFrame( - frame, original_filename, lineno, {'token': token, 'exception': exception}) + frame, original_filename, lineno, {"token": token, "exception": exception} + ) - suspend_frame = suspend_django( - py_db, thread, syntax_error_frame, CMD_ADD_EXCEPTION_BREAK) + suspend_frame = suspend_django(py_db, thread, syntax_error_frame, CMD_ADD_EXCEPTION_BREAK) return True, suspend_frame - elif exception.__name__ == 'VariableDoesNotExist': + elif exception.__name__ == "VariableDoesNotExist": if _is_django_variable_does_not_exist_exception_break_context(frame): - if not getattr(exception, 'silent_variable_failure', False) and not _is_ignoring_failures(frame): + if not getattr(exception, "silent_variable_failure", False) and not _is_ignoring_failures(frame): render_frame = _find_django_render_frame(frame) if render_frame: - suspend_frame = suspend_django( - py_db, thread, DjangoTemplateFrame(render_frame), CMD_ADD_EXCEPTION_BREAK) + suspend_frame = suspend_django(py_db, thread, DjangoTemplateFrame(render_frame), CMD_ADD_EXCEPTION_BREAK) if suspend_frame: add_exception_to_frame(suspend_frame, (exception, value, trace)) - thread.additional_info.pydev_message = 'VariableDoesNotExist' + thread.additional_info.pydev_message = "VariableDoesNotExist" suspend_frame.f_back = frame frame = suspend_frame return True, frame diff --git a/pydevd_plugins/extensions/__init__.py b/pydevd_plugins/extensions/__init__.py index bb61062c9..f77af49c2 100644 --- a/pydevd_plugins/extensions/__init__.py +++ b/pydevd_plugins/extensions/__init__.py @@ -1,2 +1,3 @@ import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/pydevd_plugins/extensions/types/__init__.py b/pydevd_plugins/extensions/types/__init__.py index bb61062c9..f77af49c2 100644 --- a/pydevd_plugins/extensions/types/__init__.py +++ b/pydevd_plugins/extensions/types/__init__.py @@ -1,2 +1,3 @@ import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/pydevd_plugins/extensions/types/pydevd_helpers.py b/pydevd_plugins/extensions/types/pydevd_helpers.py index 7c5a4fee4..3360e1f88 100644 --- a/pydevd_plugins/extensions/types/pydevd_helpers.py +++ b/pydevd_plugins/extensions/types/pydevd_helpers.py @@ -4,6 +4,7 @@ def find_cached_module(mod_name): return sys.modules.get(mod_name, None) + def find_mod_attr(mod_name, attr): mod = find_cached_module(mod_name) if mod is None: @@ -13,14 +14,13 @@ def find_mod_attr(mod_name, attr): def find_class_name(val): class_name = str(val.__class__) - if class_name.find('.') != -1: - class_name = class_name.split('.')[-1] + if class_name.find(".") != -1: + class_name = class_name.split(".")[-1] - elif class_name.find("'") != -1: #does not have '.' (could be something like ) - class_name = class_name[class_name.index("'") + 1:] + elif class_name.find("'") != -1: # does not have '.' (could be something like ) + class_name = class_name[class_name.index("'") + 1 :] if class_name.endswith("'>"): class_name = class_name[:-2] return class_name - diff --git a/pydevd_plugins/extensions/types/pydevd_plugin_numpy_types.py b/pydevd_plugins/extensions/types/pydevd_plugin_numpy_types.py index 571f7a9cb..57ed2b4f9 100644 --- a/pydevd_plugins/extensions/types/pydevd_plugin_numpy_types.py +++ b/pydevd_plugins/extensions/types/pydevd_plugin_numpy_types.py @@ -3,8 +3,8 @@ from .pydevd_helpers import find_mod_attr from _pydevd_bundle import pydevd_constants -TOO_LARGE_MSG = 'Maximum number of items (%s) reached. To show more items customize the value of the PYDEVD_CONTAINER_NUMPY_MAX_ITEMS environment variable.' -TOO_LARGE_ATTR = 'Unable to handle:' +TOO_LARGE_MSG = "Maximum number of items (%s) reached. To show more items customize the value of the PYDEVD_CONTAINER_NUMPY_MAX_ITEMS environment variable." +TOO_LARGE_ATTR = "Unable to handle:" class NdArrayItemsContainer(object): @@ -12,42 +12,42 @@ class NdArrayItemsContainer(object): class NDArrayTypeResolveProvider(object): - ''' + """ This resolves a numpy ndarray returning some metadata about the NDArray - ''' + """ def can_provide(self, type_object, type_name): - nd_array = find_mod_attr('numpy', 'ndarray') + nd_array = find_mod_attr("numpy", "ndarray") return nd_array is not None and issubclass(type_object, nd_array) def is_numeric(self, obj): - if not hasattr(obj, 'dtype'): + if not hasattr(obj, "dtype"): return False - return obj.dtype.kind in 'biufc' + return obj.dtype.kind in "biufc" def resolve(self, obj, attribute): - if attribute == '__internals__': + if attribute == "__internals__": return defaultResolver.get_dictionary(obj) - if attribute == 'min': + if attribute == "min": if self.is_numeric(obj) and obj.size > 0: return obj.min() else: return None - if attribute == 'max': + if attribute == "max": if self.is_numeric(obj) and obj.size > 0: return obj.max() else: return None - if attribute == 'shape': + if attribute == "shape": return obj.shape - if attribute == 'dtype': + if attribute == "dtype": return obj.dtype - if attribute == 'size': + if attribute == "size": return obj.size - if attribute.startswith('['): + if attribute.startswith("["): container = NdArrayItemsContainer() i = 0 - format_str = '%0' + str(int(len(str(len(obj))))) + 'd' + format_str = "%0" + str(int(len(str(len(obj))))) + "d" for item in obj: setattr(container, format_str % i, item) i += 1 @@ -59,25 +59,25 @@ def resolve(self, obj, attribute): def get_dictionary(self, obj): ret = dict() - ret['__internals__'] = defaultResolver.get_dictionary(obj) + ret["__internals__"] = defaultResolver.get_dictionary(obj) if obj.size > 1024 * 1024: - ret['min'] = 'ndarray too big, calculating min would slow down debugging' - ret['max'] = 'ndarray too big, calculating max would slow down debugging' + ret["min"] = "ndarray too big, calculating min would slow down debugging" + ret["max"] = "ndarray too big, calculating max would slow down debugging" elif obj.size == 0: - ret['min'] = 'array is empty' - ret['max'] = 'array is empty' + ret["min"] = "array is empty" + ret["max"] = "array is empty" else: if self.is_numeric(obj): - ret['min'] = obj.min() - ret['max'] = obj.max() + ret["min"] = obj.min() + ret["max"] = obj.max() else: - ret['min'] = 'not a numeric object' - ret['max'] = 'not a numeric object' - ret['shape'] = obj.shape - ret['dtype'] = obj.dtype - ret['size'] = obj.size + ret["min"] = "not a numeric object" + ret["max"] = "not a numeric object" + ret["shape"] = obj.shape + ret["dtype"] = obj.dtype + ret["size"] = obj.size try: - ret['[0:%s] ' % (len(obj))] = list(obj[0:pydevd_constants.PYDEVD_CONTAINER_NUMPY_MAX_ITEMS]) + ret["[0:%s] " % (len(obj))] = list(obj[0 : pydevd_constants.PYDEVD_CONTAINER_NUMPY_MAX_ITEMS]) except: # This may not work depending on the array shape. pass diff --git a/pydevd_plugins/extensions/types/pydevd_plugin_pandas_types.py b/pydevd_plugins/extensions/types/pydevd_plugin_pandas_types.py index abddc27bc..631691ef3 100644 --- a/pydevd_plugins/extensions/types/pydevd_plugin_pandas_types.py +++ b/pydevd_plugins/extensions/types/pydevd_plugin_pandas_types.py @@ -13,7 +13,6 @@ def _get_dictionary(obj, replacements): ret = dict() cls = obj.__class__ for attr_name in dir(obj): - # This is interesting but it actually hides too much info from the dataframe. # attr_type_in_cls = type(getattr(cls, attr_name, None)) # if attr_type_in_cls == property: @@ -27,12 +26,12 @@ def _get_dictionary(obj, replacements): ret[attr_name] = replacement continue - attr_value = getattr(obj, attr_name, '') + attr_value = getattr(obj, attr_name, "") if inspect.isroutine(attr_value) or isinstance(attr_value, MethodWrapperType): continue ret[attr_name] = attr_value except Exception as e: - ret[attr_name] = '' % (e,) + ret[attr_name] = "" % (e,) finally: timer.report_if_getting_attr_slow(cls, attr_name) @@ -70,6 +69,7 @@ def customize_pandas_options(): if custom_options: from pandas import option_context + with option_context(*custom_options): yield else: @@ -77,9 +77,8 @@ def customize_pandas_options(): class PandasDataFrameTypeResolveProvider(object): - def can_provide(self, type_object, type_name): - data_frame_class = find_mod_attr('pandas.core.frame', 'DataFrame') + data_frame_class = find_mod_attr("pandas.core.frame", "DataFrame") return data_frame_class is not None and issubclass(type_object, data_frame_class) def resolve(self, obj, attribute): @@ -89,26 +88,24 @@ def get_dictionary(self, obj): replacements = { # This actually calls: DataFrame.transpose(), which can be expensive, so, # let's just add some string representation for it. - 'T': '', - + "T": "", # This creates a whole new dict{index: Series) for each column. Doing a # subsequent repr() from this dict can be very slow, so, don't return it. - '_series': '', - - 'style': '', + "_series": "", + "style": "", } return _get_dictionary(obj, replacements) - def get_str_in_context(self, df, context:str): - ''' + def get_str_in_context(self, df, context: str): + """ :param context: This is the context in which the variable is being requested. Valid values: "watch", "repl", "hover", "clipboard" - ''' - if context in ('repl', 'clipboard'): + """ + if context in ("repl", "clipboard"): return repr(df) return self.get_str(df) @@ -118,9 +115,8 @@ def get_str(self, df): class PandasSeriesTypeResolveProvider(object): - def can_provide(self, type_object, type_name): - series_class = find_mod_attr('pandas.core.series', 'Series') + series_class = find_mod_attr("pandas.core.series", "Series") return series_class is not None and issubclass(type_object, series_class) def resolve(self, obj, attribute): @@ -130,26 +126,24 @@ def get_dictionary(self, obj): replacements = { # This actually calls: DataFrame.transpose(), which can be expensive, so, # let's just add some string representation for it. - 'T': '', - + "T": "", # This creates a whole new dict{index: Series) for each column. Doing a # subsequent repr() from this dict can be very slow, so, don't return it. - '_series': '', - - 'style': '', + "_series": "", + "style": "", } return _get_dictionary(obj, replacements) - def get_str_in_context(self, df, context:str): - ''' + def get_str_in_context(self, df, context: str): + """ :param context: This is the context in which the variable is being requested. Valid values: "watch", "repl", "hover", "clipboard" - ''' - if context in ('repl', 'clipboard'): + """ + if context in ("repl", "clipboard"): return repr(df) return self.get_str(df) @@ -159,9 +153,8 @@ def get_str(self, series): class PandasStylerTypeResolveProvider(object): - def can_provide(self, type_object, type_name): - series_class = find_mod_attr('pandas.io.formats.style', 'Styler') + series_class = find_mod_attr("pandas.io.formats.style", "Styler") return series_class is not None and issubclass(type_object, series_class) def resolve(self, obj, attribute): @@ -169,9 +162,8 @@ def resolve(self, obj, attribute): def get_dictionary(self, obj): replacements = { - 'data': '', - - '__dict__': '', + "data": "", + "__dict__": "", } return _get_dictionary(obj, replacements) diff --git a/pydevd_plugins/extensions/types/pydevd_plugins_django_form_str.py b/pydevd_plugins/extensions/types/pydevd_plugins_django_form_str.py index 8d64095e7..1d6d07315 100644 --- a/pydevd_plugins/extensions/types/pydevd_plugins_django_form_str.py +++ b/pydevd_plugins/extensions/types/pydevd_plugins_django_form_str.py @@ -4,11 +4,12 @@ class DjangoFormStr(object): def can_provide(self, type_object, type_name): - form_class = find_mod_attr('django.forms', 'Form') + form_class = find_mod_attr("django.forms", "Form") return form_class is not None and issubclass(type_object, form_class) def get_str(self, val): - return '%s: %r' % (find_class_name(val), val) + return "%s: %r" % (find_class_name(val), val) + import sys diff --git a/pydevd_plugins/jinja2_debug.py b/pydevd_plugins/jinja2_debug.py index 4903effe6..a8b3e310d 100644 --- a/pydevd_plugins/jinja2_debug.py +++ b/pydevd_plugins/jinja2_debug.py @@ -9,17 +9,19 @@ class Jinja2LineBreakpoint(LineBreakpointWithLazyValidation): - - def __init__(self, canonical_normalized_filename, breakpoint_id, line, condition, func_name, expression, hit_condition=None, is_logpoint=False): + def __init__( + self, canonical_normalized_filename, breakpoint_id, line, condition, func_name, expression, hit_condition=None, is_logpoint=False + ): self.canonical_normalized_filename = canonical_normalized_filename - LineBreakpointWithLazyValidation.__init__(self, breakpoint_id, line, condition, func_name, expression, hit_condition=hit_condition, is_logpoint=is_logpoint) + LineBreakpointWithLazyValidation.__init__( + self, breakpoint_id, line, condition, func_name, expression, hit_condition=hit_condition, is_logpoint=is_logpoint + ) def __str__(self): return "Jinja2LineBreakpoint: %s-%d" % (self.canonical_normalized_filename, self.line) class _Jinja2ValidationInfo(ValidationInfo): - @overrides(ValidationInfo._collect_valid_lines_in_template_uncached) def _collect_valid_lines_in_template_uncached(self, template): lineno_mapping = _get_frame_lineno_mapping(template) @@ -29,10 +31,32 @@ def _collect_valid_lines_in_template_uncached(self, template): return set(x[0] for x in lineno_mapping) -def add_line_breakpoint(pydb, type, canonical_normalized_filename, breakpoint_id, line, condition, expression, func_name, hit_condition=None, is_logpoint=False, add_breakpoint_result=None, on_changed_breakpoint_state=None): - if type == 'jinja2-line': - jinja2_line_breakpoint = Jinja2LineBreakpoint(canonical_normalized_filename, breakpoint_id, line, condition, func_name, expression, hit_condition=hit_condition, is_logpoint=is_logpoint) - if not hasattr(pydb, 'jinja2_breakpoints'): +def add_line_breakpoint( + pydb, + type, + canonical_normalized_filename, + breakpoint_id, + line, + condition, + expression, + func_name, + hit_condition=None, + is_logpoint=False, + add_breakpoint_result=None, + on_changed_breakpoint_state=None, +): + if type == "jinja2-line": + jinja2_line_breakpoint = Jinja2LineBreakpoint( + canonical_normalized_filename, + breakpoint_id, + line, + condition, + func_name, + expression, + hit_condition=hit_condition, + is_logpoint=is_logpoint, + ) + if not hasattr(pydb, "jinja2_breakpoints"): _init_plugin_breaks(pydb) add_breakpoint_result.error_code = PyDevdAPI.ADD_BREAKPOINT_LAZY_VALIDATION @@ -48,18 +72,19 @@ def after_breakpoints_consolidated(py_db, canonical_normalized_filename, id_to_p if not jinja2_breakpoints_for_file: return - if not hasattr(py_db, 'jinja2_validation_info'): + if not hasattr(py_db, "jinja2_validation_info"): _init_plugin_breaks(py_db) # In general we validate the breakpoints only when the template is loaded, but if the template # was already loaded, we can validate the breakpoints based on the last loaded value. py_db.jinja2_validation_info.verify_breakpoints_from_template_cached_lines( - py_db, canonical_normalized_filename, jinja2_breakpoints_for_file) + py_db, canonical_normalized_filename, jinja2_breakpoints_for_file + ) def add_exception_breakpoint(pydb, type, exception): - if type == 'jinja2': - if not hasattr(pydb, 'jinja2_exception_break'): + if type == "jinja2": + if not hasattr(pydb, "jinja2_exception_break"): _init_plugin_breaks(pydb) pydb.jinja2_exception_break[exception] = True return True @@ -74,14 +99,14 @@ def _init_plugin_breaks(pydb): def remove_all_exception_breakpoints(pydb): - if hasattr(pydb, 'jinja2_exception_break'): + if hasattr(pydb, "jinja2_exception_break"): pydb.jinja2_exception_break = {} return True return False def remove_exception_breakpoint(pydb, exception_type, exception): - if exception_type == 'jinja2': + if exception_type == "jinja2": try: del pydb.jinja2_exception_break[exception] return True @@ -91,7 +116,7 @@ def remove_exception_breakpoint(pydb, exception_type, exception): def get_breakpoints(pydb, breakpoint_type): - if breakpoint_type == 'jinja2-line': + if breakpoint_type == "jinja2-line": return pydb.jinja2_breakpoints return None @@ -134,8 +159,12 @@ def _is_jinja2_context_call(frame): def _is_jinja2_internal_function(frame): - return 'self' in frame.f_locals and frame.f_locals['self'].__class__.__name__ in \ - ('LoopContext', 'TemplateReference', 'Macro', 'BlockReference') + return "self" in frame.f_locals and frame.f_locals["self"].__class__.__name__ in ( + "LoopContext", + "TemplateReference", + "Macro", + "BlockReference", + ) def _find_jinja2_render_frame(frame): @@ -144,17 +173,16 @@ def _find_jinja2_render_frame(frame): return frame -#======================================================================================================================= + +# ======================================================================================================================= # Jinja2 Frame -#======================================================================================================================= +# ======================================================================================================================= class Jinja2TemplateFrame(object): - IS_PLUGIN_FRAME = True def __init__(self, frame, original_filename=None, template_lineno=None): - if original_filename is None: original_filename = _get_jinja2_template_original_filename(frame) @@ -162,10 +190,10 @@ def __init__(self, frame, original_filename=None, template_lineno=None): template_lineno = _get_jinja2_template_line(frame) self.back_context = None - if 'context' in frame.f_locals: + if "context" in frame.f_locals: # sometimes we don't have 'context', e.g. in macros - self.back_context = frame.f_locals['context'] - self.f_code = FCode('template', original_filename) + self.back_context = frame.f_locals["context"] + self.f_code = FCode("template", original_filename) self.f_lineno = template_lineno self.f_back = frame self.f_globals = {} @@ -174,7 +202,7 @@ def __init__(self, frame, original_filename=None, template_lineno=None): def _get_real_var_name(self, orig_name): # replace leading number for local variables - parts = orig_name.split('_') + parts = orig_name.split("_") if len(parts) > 1 and parts[0].isdigit(): return parts[1] return orig_name @@ -182,7 +210,7 @@ def _get_real_var_name(self, orig_name): def collect_context(self, frame): res = {} for k, v in frame.f_locals.items(): - if not k.startswith('l_'): + if not k.startswith("l_"): res[k] = v elif v and not _is_missing(v): res[self._get_real_var_name(k[2:])] = v @@ -193,15 +221,15 @@ def collect_context(self, frame): def _change_variable(self, frame, name, value): in_vars_or_parents = False - if 'context' in frame.f_locals: - if name in frame.f_locals['context'].parent: + if "context" in frame.f_locals: + if name in frame.f_locals["context"].parent: self.back_context.parent[name] = value in_vars_or_parents = True - if name in frame.f_locals['context'].vars: + if name in frame.f_locals["context"].vars: self.back_context.vars[name] = value in_vars_or_parents = True - l_name = 'l_' + name + l_name = "l_" + name if l_name in frame.f_locals: if in_vars_or_parents: frame.f_locals[l_name] = self.back_context.resolve(name) @@ -210,11 +238,10 @@ def _change_variable(self, frame, name, value): class Jinja2TemplateSyntaxErrorFrame(object): - IS_PLUGIN_FRAME = True def __init__(self, frame, exception_cls_name, filename, lineno, f_locals): - self.f_code = FCode('Jinja2 %s' % (exception_cls_name,), filename) + self.f_code = FCode("Jinja2 %s" % (exception_cls_name,), filename) self.f_lineno = lineno self.f_back = frame self.f_globals = {} @@ -231,7 +258,7 @@ def change_variable(frame, attr, expression, default): def _is_missing(item): - if item.__class__.__name__ == 'MissingType': + if item.__class__.__name__ == "MissingType": return True return False @@ -240,8 +267,9 @@ def _find_render_function_frame(frame): # in order to hide internal rendering functions old_frame = frame try: - while not ('self' in frame.f_locals and frame.f_locals['self'].__class__.__name__ == 'Template' and \ - frame.f_code.co_name == 'render'): + while not ( + "self" in frame.f_locals and frame.f_locals["self"].__class__.__name__ == "Template" and frame.f_code.co_name == "render" + ): frame = frame.f_back if frame is None: return old_frame @@ -253,7 +281,7 @@ def _find_render_function_frame(frame): def _get_jinja2_template_debug_info(frame): frame_globals = frame.f_globals - jinja_template = frame_globals.get('__jinja_template__') + jinja_template = frame_globals.get("__jinja_template__") if jinja_template is None: return None @@ -262,10 +290,10 @@ def _get_jinja2_template_debug_info(frame): def _get_frame_lineno_mapping(jinja_template): - ''' + """ :rtype: list(tuple(int,int)) :return: list((original_line, line_in_frame)) - ''' + """ # _debug_info is a string with the mapping from frame line to actual line # i.e.: "5=13&8=14" _debug_info = jinja_template._debug_info @@ -297,14 +325,15 @@ def _convert_to_str(s): def _get_jinja2_template_original_filename(frame): - if '__jinja_template__' in frame.f_globals: - return _convert_to_str(frame.f_globals['__jinja_template__'].filename) + if "__jinja_template__" in frame.f_globals: + return _convert_to_str(frame.f_globals["__jinja_template__"].filename) return None -#======================================================================================================================= + +# ======================================================================================================================= # Jinja2 Step Commands -#======================================================================================================================= +# ======================================================================================================================= def has_exception_breaks(py_db): @@ -333,12 +362,12 @@ def can_skip(pydb, frame): name = frame.f_code.co_name # errors in compile time - if name in ('template', 'top-level template code', '') or name.startswith('block '): + if name in ("template", "top-level template code", "") or name.startswith("block "): f_back = frame.f_back - module_name = '' + module_name = "" if f_back is not None: - module_name = f_back.f_globals.get('__name__', '') - if module_name.startswith('jinja2.'): + module_name = f_back.f_globals.get("__name__", "") + if module_name.startswith("jinja2."): return False return True @@ -348,17 +377,17 @@ def can_skip(pydb, frame): def required_events_breakpoint(): - return ('line',) + return ("line",) def required_events_stepping(): - return ('call', 'line', 'return') + return ("call", "line", "return") def cmd_step_into(pydb, frame, event, info, thread, stop_info, stop): plugin_stop = False if _is_jinja2_suspended(thread): - plugin_stop = stop_info['jinja2_stop'] = event in ('call', 'line') and _is_jinja2_render_call(frame) + plugin_stop = stop_info["jinja2_stop"] = event in ("call", "line") and _is_jinja2_render_call(frame) stop = False if info.pydev_call_from_jinja2 is not None: if _is_jinja2_internal_function(frame): @@ -368,11 +397,11 @@ def cmd_step_into(pydb, frame, event, info, thread, stop_info, stop): # we go into python code from Jinja2 rendering frame stop = True - if event == 'call' and _is_jinja2_context_call(frame.f_back): + if event == "call" and _is_jinja2_context_call(frame.f_back): # we called function from context, the next step will be in function info.pydev_call_from_jinja2 = 1 - if event == 'return' and _is_jinja2_context_call(frame.f_back): + if event == "return" and _is_jinja2_context_call(frame.f_back): # we return from python code to Jinja2 rendering frame info.pydev_step_stop = info.pydev_call_from_jinja2 info.pydev_call_from_jinja2 = None @@ -392,20 +421,20 @@ def cmd_step_over(pydb, frame, event, info, thread, stop_info, stop): if info.pydev_call_inside_jinja2 is None: if _is_jinja2_render_call(frame): - if event == 'call': + if event == "call": info.pydev_call_inside_jinja2 = frame.f_back - if event in ('line', 'return'): + if event in ("line", "return"): info.pydev_call_inside_jinja2 = frame else: - if event == 'line': + if event == "line": if _is_jinja2_render_call(frame) and info.pydev_call_inside_jinja2 is frame: - plugin_stop = stop_info['jinja2_stop'] = True - if event == 'return': - if frame is info.pydev_call_inside_jinja2 and 'event' not in frame.f_back.f_locals: + plugin_stop = stop_info["jinja2_stop"] = True + if event == "return": + if frame is info.pydev_call_inside_jinja2 and "event" not in frame.f_back.f_locals: info.pydev_call_inside_jinja2 = _find_jinja2_render_frame(frame.f_back) return stop, plugin_stop else: - if event == 'return' and _is_jinja2_context_call(frame.f_back): + if event == "return" and _is_jinja2_context_call(frame.f_back): # we return from python code to Jinja2 rendering frame info.pydev_call_from_jinja2 = None info.pydev_call_inside_jinja2 = _find_jinja2_render_frame(frame) @@ -423,7 +452,7 @@ def cmd_step_over(pydb, frame, event, info, thread, stop_info, stop): def stop(pydb, frame, event, thread, stop_info, arg, step_cmd): - if 'jinja2_stop' in stop_info and stop_info['jinja2_stop']: + if "jinja2_stop" in stop_info and stop_info["jinja2_stop"]: frame = _suspend_jinja2(pydb, thread, frame, step_cmd) if frame: pydb.do_wait_suspend(thread, frame, event, arg) @@ -432,11 +461,10 @@ def stop(pydb, frame, event, thread, stop_info, arg, step_cmd): def get_breakpoint(py_db, frame, event, info): - break_type = 'jinja2' - - if event == 'line' and info.pydev_state != STATE_SUSPEND and py_db.jinja2_breakpoints and _is_jinja2_render_call(frame): + break_type = "jinja2" - jinja_template = frame.f_globals.get('__jinja_template__') + if event == "line" and info.pydev_state != STATE_SUSPEND and py_db.jinja2_breakpoints and _is_jinja2_render_call(frame): + jinja_template = frame.f_globals.get("__jinja_template__") if jinja_template is None: return None @@ -447,7 +475,6 @@ def get_breakpoint(py_db, frame, event, info): jinja2_breakpoints_for_file = py_db.jinja2_breakpoints.get(canonical_normalized_filename) if jinja2_breakpoints_for_file: - jinja2_validation_info = py_db.jinja2_validation_info jinja2_validation_info.verify_breakpoints(py_db, canonical_normalized_filename, jinja2_breakpoints_for_file, jinja_template) @@ -462,7 +489,7 @@ def get_breakpoint(py_db, frame, event, info): def suspend(pydb, thread, frame, bp_type): - if bp_type == 'jinja2': + if bp_type == "jinja2": return _suspend_jinja2(pydb, thread, frame) return None @@ -471,7 +498,7 @@ def exception_break(pydb, frame, thread, arg): exception, value, trace = arg if pydb.jinja2_exception_break and exception is not None: exception_type = list(pydb.jinja2_exception_break.keys())[0] - if exception.__name__ in ('UndefinedError', 'TemplateNotFound', 'TemplatesNotFound'): + if exception.__name__ in ("UndefinedError", "TemplateNotFound", "TemplatesNotFound"): # errors in rendering render_frame = _find_jinja2_render_frame(frame) if render_frame: @@ -482,17 +509,16 @@ def exception_break(pydb, frame, thread, arg): frame = suspend_frame return True, frame - elif exception.__name__ in ('TemplateSyntaxError', 'TemplateAssertionError'): + elif exception.__name__ in ("TemplateSyntaxError", "TemplateAssertionError"): name = frame.f_code.co_name # errors in compile time - if name in ('template', 'top-level template code', '') or name.startswith('block '): - + if name in ("template", "top-level template code", "") or name.startswith("block "): f_back = frame.f_back if f_back is not None: - module_name = f_back.f_globals.get('__name__', '') + module_name = f_back.f_globals.get("__name__", "") - if module_name.startswith('jinja2.'): + if module_name.startswith("jinja2."): # Jinja2 translates exception info and creates fake frame on his own pydb.set_suspend(thread, CMD_ADD_EXCEPTION_BREAK) add_exception_to_frame(frame, (exception, value, trace)) diff --git a/pydevd_plugins/pydevd_line_validation.py b/pydevd_plugins/pydevd_line_validation.py index 2b64a5255..e32aea654 100644 --- a/pydevd_plugins/pydevd_line_validation.py +++ b/pydevd_plugins/pydevd_line_validation.py @@ -5,7 +5,6 @@ class LineBreakpointWithLazyValidation(LineBreakpoint): - def __init__(self, *args, **kwargs): LineBreakpoint.__init__(self, *args, **kwargs) # This is the _AddBreakpointResult that'll be modified (and then re-sent on the @@ -23,7 +22,6 @@ def __init__(self, *args, **kwargs): class ValidationInfo(object): - def __init__(self): self._canonical_normalized_filename_to_last_template_lines = {} @@ -32,7 +30,7 @@ def _collect_valid_lines_in_template(self, template): # template may be a different instance (because the template contents could be # changed on disk), but this may still be called multiple times during the # same render session, so, caching is interesting. - lines_cache = getattr(template, '__pydevd_lines_cache__', None) + lines_cache = getattr(template, "__pydevd_lines_cache__", None) if lines_cache is not None: lines, sorted_lines = lines_cache return lines, sorted_lines @@ -48,28 +46,34 @@ def _collect_valid_lines_in_template_uncached(self, template): raise NotImplementedError() def verify_breakpoints(self, py_db, canonical_normalized_filename, template_breakpoints_for_file, template): - ''' + """ This function should be called whenever a rendering is detected. :param str canonical_normalized_filename: :param dict[int:LineBreakpointWithLazyValidation] template_breakpoints_for_file: - ''' + """ valid_lines_frozenset, sorted_lines = self._collect_valid_lines_in_template(template) self._canonical_normalized_filename_to_last_template_lines[canonical_normalized_filename] = valid_lines_frozenset, sorted_lines - self._verify_breakpoints_with_lines_collected(py_db, canonical_normalized_filename, template_breakpoints_for_file, valid_lines_frozenset, sorted_lines) + self._verify_breakpoints_with_lines_collected( + py_db, canonical_normalized_filename, template_breakpoints_for_file, valid_lines_frozenset, sorted_lines + ) def verify_breakpoints_from_template_cached_lines(self, py_db, canonical_normalized_filename, template_breakpoints_for_file): - ''' + """ This is used when the lines are already available (if just the template is available, `verify_breakpoints` should be used instead). - ''' + """ cached = self._canonical_normalized_filename_to_last_template_lines.get(canonical_normalized_filename) if cached is not None: valid_lines_frozenset, sorted_lines = cached - self._verify_breakpoints_with_lines_collected(py_db, canonical_normalized_filename, template_breakpoints_for_file, valid_lines_frozenset, sorted_lines) + self._verify_breakpoints_with_lines_collected( + py_db, canonical_normalized_filename, template_breakpoints_for_file, valid_lines_frozenset, sorted_lines + ) - def _verify_breakpoints_with_lines_collected(self, py_db, canonical_normalized_filename, template_breakpoints_for_file, valid_lines_frozenset, sorted_lines): + def _verify_breakpoints_with_lines_collected( + self, py_db, canonical_normalized_filename, template_breakpoints_for_file, valid_lines_frozenset, sorted_lines + ): for line, template_bp in list(template_breakpoints_for_file.items()): # Note: iterate in a copy (we may mutate it). if template_bp.verified_cache_key != valid_lines_frozenset: template_bp.verified_cache_key = valid_lines_frozenset @@ -86,8 +90,13 @@ def _verify_breakpoints_with_lines_collected(self, py_db, canonical_normalized_f if new_line >= 0 and new_line not in template_breakpoints_for_file: # We just add it if found and if there's no existing breakpoint at that # location. - if template_bp.add_breakpoint_result.error_code != PyDevdAPI.ADD_BREAKPOINT_NO_ERROR and template_bp.add_breakpoint_result.translated_line != new_line: - pydev_log.debug('Template breakpoint in %s in line: %s moved to line: %s', canonical_normalized_filename, line, new_line) + if ( + template_bp.add_breakpoint_result.error_code != PyDevdAPI.ADD_BREAKPOINT_NO_ERROR + and template_bp.add_breakpoint_result.translated_line != new_line + ): + pydev_log.debug( + "Template breakpoint in %s in line: %s moved to line: %s", canonical_normalized_filename, line, new_line + ) template_bp.add_breakpoint_result.error_code = PyDevdAPI.ADD_BREAKPOINT_NO_ERROR template_bp.add_breakpoint_result.translated_line = new_line @@ -97,11 +106,15 @@ def _verify_breakpoints_with_lines_collected(self, py_db, canonical_normalized_f template_bp.on_changed_breakpoint_state(template_bp.breakpoint_id, template_bp.add_breakpoint_result) else: if template_bp.add_breakpoint_result.error_code != PyDevdAPI.ADD_BREAKPOINT_INVALID_LINE: - pydev_log.debug('Template breakpoint in %s in line: %s invalid (valid lines: %s)', canonical_normalized_filename, line, valid_lines_frozenset) + pydev_log.debug( + "Template breakpoint in %s in line: %s invalid (valid lines: %s)", + canonical_normalized_filename, + line, + valid_lines_frozenset, + ) template_bp.add_breakpoint_result.error_code = PyDevdAPI.ADD_BREAKPOINT_INVALID_LINE template_bp.on_changed_breakpoint_state(template_bp.breakpoint_id, template_bp.add_breakpoint_result) else: if template_bp.add_breakpoint_result.error_code != PyDevdAPI.ADD_BREAKPOINT_NO_ERROR: template_bp.add_breakpoint_result.error_code = PyDevdAPI.ADD_BREAKPOINT_NO_ERROR template_bp.on_changed_breakpoint_state(template_bp.breakpoint_id, template_bp.add_breakpoint_result) - diff --git a/pydevd_tracing.py b/pydevd_tracing.py index 1400e14bc..dddca43f7 100644 --- a/pydevd_tracing.py +++ b/pydevd_tracing.py @@ -1,6 +1,16 @@ -from _pydevd_bundle.pydevd_constants import get_frame, IS_CPYTHON, IS_64BIT_PROCESS, IS_WINDOWS, \ - IS_LINUX, IS_MAC, DebugInfoHolder, LOAD_NATIVE_LIB_FLAG, \ - ENV_FALSE_LOWER_VALUES, ForkSafeLock, PYDEVD_USE_SYS_MONITORING +from _pydevd_bundle.pydevd_constants import ( + get_frame, + IS_CPYTHON, + IS_64BIT_PROCESS, + IS_WINDOWS, + IS_LINUX, + IS_MAC, + DebugInfoHolder, + LOAD_NATIVE_LIB_FLAG, + ENV_FALSE_LOWER_VALUES, + ForkSafeLock, + PYDEVD_USE_SYS_MONITORING, +) from _pydev_bundle._pydev_saved_modules import thread, threading from _pydev_bundle import pydev_log, pydev_monkey import os.path @@ -14,8 +24,8 @@ class TracingFunctionHolder: - '''This class exists just to keep some variables (so that we don't keep them in the global namespace). - ''' + """This class exists just to keep some variables (so that we don't keep them in the global namespace).""" + _original_tracing = None _warn = True _traceback_limit = 1 @@ -30,14 +40,15 @@ def get_exception_traceback_str(): def _get_stack_str(frame): - - msg = '\nIf this is needed, please check: ' + \ - '\nhttp://pydev.blogspot.com/2007/06/why-cant-pydev-debugger-work-with.html' + \ - '\nto see how to restore the debug tracing back correctly.\n' + msg = ( + "\nIf this is needed, please check: " + + "\nhttp://pydev.blogspot.com/2007/06/why-cant-pydev-debugger-work-with.html" + + "\nto see how to restore the debug tracing back correctly.\n" + ) if TracingFunctionHolder._traceback_limit: s = StringIO() - s.write('Call Location:\n') + s.write("Call Location:\n") traceback.print_stack(f=frame, limit=TracingFunctionHolder._traceback_limit, file=s) msg = msg + s.getvalue() @@ -51,28 +62,28 @@ def _internal_set_trace(tracing_func): frame = get_frame() if frame is not None and frame.f_back is not None: filename = os.path.splitext(frame.f_back.f_code.co_filename.lower())[0] - if filename.endswith('threadpool') and 'gevent' in filename: + if filename.endswith("threadpool") and "gevent" in filename: if tracing_func is None: - pydev_log.debug('Disabled internal sys.settrace from gevent threadpool.') + pydev_log.debug("Disabled internal sys.settrace from gevent threadpool.") return elif not filename.endswith( - ( - 'threading', - 'pydevd_tracing', - ) - ): - - message = \ - '\nPYDEV DEBUGGER WARNING:' + \ - '\nsys.settrace() should not be used when the debugger is being used.' + \ - '\nThis may cause the debugger to stop working correctly.' + \ - '%s' % _get_stack_str(frame.f_back) + ( + "threading", + "pydevd_tracing", + ) + ): + message = ( + "\nPYDEV DEBUGGER WARNING:" + + "\nsys.settrace() should not be used when the debugger is being used." + + "\nThis may cause the debugger to stop working correctly." + + "%s" % _get_stack_str(frame.f_back) + ) if message not in TracingFunctionHolder._warnings_shown: # only warn about each message once... TracingFunctionHolder._warnings_shown[message] = 1 - sys.stderr.write('%s\n' % (message,)) + sys.stderr.write("%s\n" % (message,)) sys.stderr.flush() if TracingFunctionHolder._original_tracing: @@ -84,7 +95,7 @@ def _internal_set_trace(tracing_func): def SetTrace(tracing_func): if PYDEVD_USE_SYS_MONITORING: - raise RuntimeError('SetTrace should not be used when using sys.monitoring.') + raise RuntimeError("SetTrace should not be used when using sys.monitoring.") _last_tracing_func_thread_local.tracing_func = tracing_func if tracing_func is not None: @@ -154,40 +165,40 @@ def get_python_helper_lib_filename(): # debugger -- the only situation where it's imported is if the user actually does an attach to # process, through `attach_pydevd.py`, but this should usually be called from the IDE directly # and not from the debugger). - libdir = os.path.join(os.path.dirname(__file__), 'pydevd_attach_to_process') + libdir = os.path.join(os.path.dirname(__file__), "pydevd_attach_to_process") - arch = '' + arch = "" if IS_WINDOWS: # prefer not using platform.machine() when possible (it's a bit heavyweight as it may # spawn a subprocess). - arch = os.environ.get("PROCESSOR_ARCHITEW6432", os.environ.get('PROCESSOR_ARCHITECTURE', '')) + arch = os.environ.get("PROCESSOR_ARCHITEW6432", os.environ.get("PROCESSOR_ARCHITECTURE", "")) if not arch: arch = platform.machine() if not arch: - pydev_log.info('platform.machine() did not return valid value.') # This shouldn't happen... + pydev_log.info("platform.machine() did not return valid value.") # This shouldn't happen... return None if IS_WINDOWS: - extension = '.dll' - suffix_64 = 'amd64' - suffix_32 = 'x86' + extension = ".dll" + suffix_64 = "amd64" + suffix_32 = "x86" elif IS_LINUX: - extension = '.so' - suffix_64 = 'amd64' - suffix_32 = 'x86' + extension = ".so" + suffix_64 = "amd64" + suffix_32 = "x86" elif IS_MAC: - extension = '.dylib' - suffix_64 = 'x86_64' - suffix_32 = 'x86' + extension = ".dylib" + suffix_64 = "x86_64" + suffix_32 = "x86" else: - pydev_log.info('Unable to set trace to all threads in platform: %s', sys.platform) + pydev_log.info("Unable to set trace to all threads in platform: %s", sys.platform) return None - if arch.lower() not in ('amd64', 'x86', 'x86_64', 'i386', 'x86'): + if arch.lower() not in ("amd64", "x86", "x86_64", "i386", "x86"): # We don't support this processor by default. Still, let's support the case where the # user manually compiled it himself with some heuristics. # @@ -198,15 +209,15 @@ def get_python_helper_lib_filename(): # - linux_and_mac/compile_mac.sh try: - found = [name for name in os.listdir(libdir) if name.startswith('attach_') and name.endswith(extension)] + found = [name for name in os.listdir(libdir) if name.startswith("attach_") and name.endswith(extension)] except: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: # There is no need to show this unless debug tracing is enabled. - pydev_log.exception('Error listing dir: %s', libdir) + pydev_log.exception("Error listing dir: %s", libdir) return None - expected_name = 'attach_' + arch + extension - expected_name_linux = 'attach_linux_' + arch + extension + expected_name = "attach_" + arch + extension + expected_name_linux = "attach_linux_" + arch + extension filename = None if expected_name in found: # Heuristic: user compiled with "attach_." @@ -224,14 +235,10 @@ def get_python_helper_lib_filename(): filename = os.path.join(libdir, found[0]) if filename is None: - pydev_log.info( - 'Unable to set trace to all threads in arch: %s (did not find a %s lib in %s).', - arch, expected_name, libdir - - ) + pydev_log.info("Unable to set trace to all threads in arch: %s (did not find a %s lib in %s).", arch, expected_name, libdir) return None - pydev_log.info('Using %s lib in arch: %s.', filename, arch) + pydev_log.info("Using %s lib in arch: %s.", filename, arch) else: # Happy path for which we have pre-compiled binaries. @@ -241,26 +248,30 @@ def get_python_helper_lib_filename(): suffix = suffix_32 if IS_WINDOWS or IS_MAC: # just the extension changes - prefix = 'attach_' + prefix = "attach_" elif IS_LINUX: # - prefix = 'attach_linux_' # historically it has a different name + prefix = "attach_linux_" # historically it has a different name else: - pydev_log.info('Unable to set trace to all threads in platform: %s', sys.platform) + pydev_log.info("Unable to set trace to all threads in platform: %s", sys.platform) return None - filename = os.path.join(libdir, '%s%s%s' % (prefix, suffix, extension)) + filename = os.path.join(libdir, "%s%s%s" % (prefix, suffix, extension)) if not os.path.exists(filename): - pydev_log.critical('Expected: %s to exist.', filename) + pydev_log.critical("Expected: %s to exist.", filename) return None return filename def _load_python_helper_lib_uncached(): - if (not IS_CPYTHON or sys.version_info[:2] > (3, 11) - or hasattr(sys, 'gettotalrefcount') or LOAD_NATIVE_LIB_FLAG in ENV_FALSE_LOWER_VALUES): - pydev_log.info('Helper lib to set tracing to all threads not loaded.') + if ( + not IS_CPYTHON + or sys.version_info[:2] > (3, 11) + or hasattr(sys, "gettotalrefcount") + or LOAD_NATIVE_LIB_FLAG in ENV_FALSE_LOWER_VALUES + ): + pydev_log.info("Helper lib to set tracing to all threads not loaded.") return None try: @@ -269,19 +280,19 @@ def _load_python_helper_lib_uncached(): return None # Load as pydll so that we don't release the gil. lib = ctypes.pydll.LoadLibrary(filename) - pydev_log.info('Successfully Loaded helper lib to set tracing to all threads.') + pydev_log.info("Successfully Loaded helper lib to set tracing to all threads.") return lib except: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: # Only show message if tracing is on (we don't have pre-compiled # binaries for all architectures -- i.e.: ARM). - pydev_log.exception('Error loading: %s', filename) + pydev_log.exception("Error loading: %s", filename) return None def set_trace_to_threads(tracing_func, thread_idents=None, create_dummy_thread=True): if PYDEVD_USE_SYS_MONITORING: - raise RuntimeError('Should not be called when using sys.monitoring.') + raise RuntimeError("Should not be called when using sys.monitoring.") assert tracing_func is not None ret = 0 @@ -298,7 +309,7 @@ def set_trace_to_threads(tracing_func, thread_idents=None, create_dummy_thread=T # PY-44778: ignore pydevd threads and also add any thread that wasn't found on # sys._current_frames() as some existing threads may not appear in # sys._current_frames() but may be available through the `threading` module. - if getattr(t, 'pydev_do_not_trace', False): + if getattr(t, "pydev_do_not_trace", False): thread_idents.discard(t.ident) else: thread_idents.add(t.ident) @@ -320,7 +331,6 @@ def set_trace_to_threads(tracing_func, thread_idents=None, create_dummy_thread=T if thread_ident not in threading._active: class _DummyThread(threading._DummyThread): - def _set_ident(self): # Note: Hack to set the thread ident that we want. self._ident = thread_ident @@ -341,7 +351,7 @@ def _set_ident(self): if t.ident != thread_ident: # Check if it actually worked. - pydev_log.critical('pydevd: creation of _DummyThread with fixed thread ident did not succeed.') + pydev_log.critical("pydevd: creation of _DummyThread with fixed thread ident did not succeed.") # Some (ptvsd) tests failed because of this, so, leave it always disabled for now. # show_debug_info = 1 if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1 else 0 @@ -370,7 +380,7 @@ def increase_tracing_count(): lib = _load_python_helper_lib() if lib is None: # This is the case if it's not CPython. - pydev_log.info('Unable to load helper lib to set tracing to all threads (unsupported python vm).') + pydev_log.info("Unable to load helper lib to set tracing to all threads (unsupported python vm).") ret = -1 else: try: @@ -384,12 +394,11 @@ def increase_tracing_count(): except: if DebugInfoHolder.DEBUG_TRACE_LEVEL >= 1: # There is no need to show this unless debug tracing is enabled. - pydev_log.exception('Error attaching debugger tracing') + pydev_log.exception("Error attaching debugger tracing") ret = -1 else: if result != 0: - pydev_log.info('Unable to set tracing for existing thread. Result: %s', result) + pydev_log.info("Unable to set tracing for existing thread. Result: %s", result) ret = result return ret - diff --git a/runfiles.py b/runfiles.py index 15b9f3aae..68164f0ef 100644 --- a/runfiles.py +++ b/runfiles.py @@ -1,8 +1,8 @@ -''' +""" Entry point module (keep at root): Used to run with tests with unittest/pytest/nose. -''' +""" import os @@ -15,8 +15,8 @@ def main(): other_test_framework_params = [] found_other_test_framework_param = None - NOSE_PARAMS = '--nose-params' - PY_TEST_PARAMS = '--py-test-params' + NOSE_PARAMS = "--nose-params" + PY_TEST_PARAMS = "--py-test-params" for arg in sys.argv[1:]: if not found_other_test_framework_param and arg != NOSE_PARAMS and arg != PY_TEST_PARAMS: @@ -48,15 +48,15 @@ def get_with_filesystem_case(f): DEBUG = 0 if DEBUG: - sys.stdout.write('Received parameters: %s\n' % (sys.argv,)) - sys.stdout.write('Params for pydev: %s\n' % (pydev_params,)) + sys.stdout.write("Received parameters: %s\n" % (sys.argv,)) + sys.stdout.write("Params for pydev: %s\n" % (pydev_params,)) if found_other_test_framework_param: - sys.stdout.write('Params for test framework: %s, %s\n' % (found_other_test_framework_param, other_test_framework_params)) + sys.stdout.write("Params for test framework: %s, %s\n" % (found_other_test_framework_param, other_test_framework_params)) try: configuration = pydev_runfiles.parse_cmdline([sys.argv[0]] + pydev_params) except: - sys.stderr.write('Command line received: %s\n' % (sys.argv,)) + sys.stderr.write("Command line received: %s\n" % (sys.argv,)) raise pydev_runfiles_xml_rpc.initialize_server(configuration.port) # Note that if the port is None, a Null server will be initialized. @@ -74,7 +74,7 @@ def get_with_filesystem_case(f): import pytest else: - raise ImportError('Test framework: %s not supported.' % (found_other_test_framework_param,)) + raise ImportError("Test framework: %s not supported." % (found_other_test_framework_param,)) else: raise ImportError() @@ -87,11 +87,10 @@ def get_with_filesystem_case(f): # Clear any exception that may be there so that clients don't see it. # See: https://sourceforge.net/tracker/?func=detail&aid=3408057&group_id=85796&atid=577329 - if hasattr(sys, 'exc_clear'): + if hasattr(sys, "exc_clear"): sys.exc_clear() if not test_framework: - return pydev_runfiles.main(configuration) # Note: still doesn't return a proper value. else: @@ -116,7 +115,7 @@ def get_with_filesystem_case(f): for file, tests in files_to_tests.items(): if test_framework == NOSE_FRAMEWORK: for test in tests: - files_or_dirs.append(file + ':' + test) + files_or_dirs.append(file + ":" + test) elif test_framework == PY_TEST_FRAMEWORK: py_test_accept_filter[file] = tests @@ -124,7 +123,7 @@ def get_with_filesystem_case(f): files_or_dirs.append(file) else: - raise AssertionError('Cannot handle test framework: %s at this point.' % (test_framework,)) + raise AssertionError("Cannot handle test framework: %s at this point." % (test_framework,)) else: if configuration.tests: @@ -133,7 +132,7 @@ def get_with_filesystem_case(f): for file in configuration.files_or_dirs: if test_framework == NOSE_FRAMEWORK: for t in configuration.tests: - files_or_dirs.append(file + ':' + t) + files_or_dirs.append(file + ":" + t) elif test_framework == PY_TEST_FRAMEWORK: py_test_accept_filter[file] = configuration.tests @@ -141,7 +140,7 @@ def get_with_filesystem_case(f): files_or_dirs.append(file) else: - raise AssertionError('Cannot handle test framework: %s at this point.' % (test_framework,)) + raise AssertionError("Cannot handle test framework: %s at this point." % (test_framework,)) else: # Only files or dirs passed (let it do the test-loading based on those paths) files_or_dirs = configuration.files_or_dirs @@ -154,42 +153,45 @@ def get_with_filesystem_case(f): # processes_option = ['--processes=2'] argv.insert(0, sys.argv[0]) if DEBUG: - sys.stdout.write('Final test framework args: %s\n' % (argv[1:],)) + sys.stdout.write("Final test framework args: %s\n" % (argv[1:],)) from _pydev_runfiles import pydev_runfiles_nose + PYDEV_NOSE_PLUGIN_SINGLETON = pydev_runfiles_nose.start_pydev_nose_plugin_singleton(configuration) - argv.append('--with-pydevplugin') + argv.append("--with-pydevplugin") # Return 'not' because it will return 'success' (so, exit == 0 if success) return not nose.run(argv=argv, addplugins=[PYDEV_NOSE_PLUGIN_SINGLETON]) elif test_framework == PY_TEST_FRAMEWORK: - - if '--coverage_output_dir' in pydev_params and '--coverage_include' in pydev_params: - coverage_output_dir = pydev_params[pydev_params.index('--coverage_output_dir') + 1] - coverage_include = pydev_params[pydev_params.index('--coverage_include') + 1] + if "--coverage_output_dir" in pydev_params and "--coverage_include" in pydev_params: + coverage_output_dir = pydev_params[pydev_params.index("--coverage_output_dir") + 1] + coverage_include = pydev_params[pydev_params.index("--coverage_include") + 1] try: import pytest_cov except ImportError: - sys.stderr.write('To do a coverage run with pytest the pytest-cov library is needed (i.e.: pip install pytest-cov).\n\n') + sys.stderr.write( + "To do a coverage run with pytest the pytest-cov library is needed (i.e.: pip install pytest-cov).\n\n" + ) raise - argv.insert(0, '--cov-append') - argv.insert(1, '--cov-report=') - argv.insert(2, '--cov=%s' % (coverage_include,)) + argv.insert(0, "--cov-append") + argv.insert(1, "--cov-report=") + argv.insert(2, "--cov=%s" % (coverage_include,)) import time - os.environ['COVERAGE_FILE'] = os.path.join(coverage_output_dir, '.coverage.%s' % (time.time(),)) + + os.environ["COVERAGE_FILE"] = os.path.join(coverage_output_dir, ".coverage.%s" % (time.time(),)) if DEBUG: - sys.stdout.write('Final test framework args: %s\n' % (argv,)) - sys.stdout.write('py_test_accept_filter: %s\n' % (py_test_accept_filter,)) + sys.stdout.write("Final test framework args: %s\n" % (argv,)) + sys.stdout.write("py_test_accept_filter: %s\n" % (py_test_accept_filter,)) def dotted(p): # Helper to convert path to have dots instead of slashes - return os.path.normpath(p).replace(os.sep, "/").replace('/', '.') + return os.path.normpath(p).replace(os.sep, "/").replace("/", ".") - curr_dir = os.path.realpath('.') - curr_dotted = dotted(curr_dir) + '.' + curr_dir = os.path.realpath(".") + curr_dotted = dotted(curr_dir) + "." # Overcome limitation on py.test: # When searching conftest if we have a structure as: @@ -215,13 +217,13 @@ def dotted(p): # Workaround bug in py.test: if we pass the full path it ends up importing conftest # more than once (so, always work with relative paths). if os.path.isfile(arg) or os.path.isdir(arg): - # Args must be passed with the proper case in the filesystem (otherwise # python itself may not recognize it). arg = get_with_filesystem_case(arg) argv[i] = arg from os.path import relpath + try: # May fail if on different drives arg = relpath(arg) @@ -229,7 +231,7 @@ def dotted(p): pass else: argv[i] = arg - elif '' in arg: + elif "" in arg: remove.append(i) for i in reversed(remove): @@ -243,74 +245,76 @@ def dotted(p): import pickle, zlib, base64 # Update environment PYTHONPATH so that it finds our plugin if using xdist. - os.environ['PYTHONPATH'] = os.pathsep.join(sys.path) + os.environ["PYTHONPATH"] = os.pathsep.join(sys.path) # Set what should be skipped in the plugin through an environment variable s = base64.b64encode(zlib.compress(pickle.dumps(py_test_accept_filter))) - s = s.decode('ascii') # Must be str in py3. - os.environ['PYDEV_PYTEST_SKIP'] = s + s = s.decode("ascii") # Must be str in py3. + os.environ["PYDEV_PYTEST_SKIP"] = s # Identifies the main pid (i.e.: if it's not the main pid it has to connect back to the # main pid to give xml-rpc notifications). - os.environ['PYDEV_MAIN_PID'] = str(os.getpid()) - os.environ['PYDEV_PYTEST_SERVER'] = str(configuration.port) + os.environ["PYDEV_MAIN_PID"] = str(os.getpid()) + os.environ["PYDEV_PYTEST_SERVER"] = str(configuration.port) - argv.append('-p') - argv.append('_pydev_runfiles.pydev_runfiles_pytest2') + argv.append("-p") + argv.append("_pydev_runfiles.pydev_runfiles_pytest2") return pytest.main(argv) else: - raise AssertionError('Cannot handle test framework: %s at this point.' % (test_framework,)) + raise AssertionError("Cannot handle test framework: %s at this point." % (test_framework,)) -if __name__ == '__main__': +if __name__ == "__main__": try: main() finally: try: # The server is not a daemon thread, so, we have to ask for it to be killed! from _pydev_runfiles import pydev_runfiles_xml_rpc + pydev_runfiles_xml_rpc.force_server_kill() except: pass # Ignore any errors here import sys import threading - if hasattr(sys, '_current_frames') and hasattr(threading, 'enumerate'): + + if hasattr(sys, "_current_frames") and hasattr(threading, "enumerate"): import time import traceback class DumpThreads(threading.Thread): - def run(self): time.sleep(10) thread_id_to_name = {} try: for t in threading.enumerate(): - thread_id_to_name[t.ident] = '%s (daemon: %s)' % (t.name, t.daemon) + thread_id_to_name[t.ident] = "%s (daemon: %s)" % (t.name, t.daemon) except: pass stack_trace = [ - '===============================================================================', - 'pydev pyunit runner: Threads still found running after tests finished', - '================================= Thread Dump ================================='] + "===============================================================================", + "pydev pyunit runner: Threads still found running after tests finished", + "================================= Thread Dump =================================", + ] for thread_id, stack in sys._current_frames().items(): - stack_trace.append('\n-------------------------------------------------------------------------------') + stack_trace.append("\n-------------------------------------------------------------------------------") stack_trace.append(" Thread %s" % thread_id_to_name.get(thread_id, thread_id)) - stack_trace.append('') + stack_trace.append("") - if 'self' in stack.f_locals: - sys.stderr.write(str(stack.f_locals['self']) + '\n') + if "self" in stack.f_locals: + sys.stderr.write(str(stack.f_locals["self"]) + "\n") for filename, lineno, name, line in traceback.extract_stack(stack): stack_trace.append(' File "%s", line %d, in %s' % (filename, lineno, name)) if line: stack_trace.append(" %s" % (line.strip())) - stack_trace.append('\n=============================== END Thread Dump ===============================') - sys.stderr.write('\n'.join(stack_trace)) + stack_trace.append("\n=============================== END Thread Dump ===============================") + sys.stderr.write("\n".join(stack_trace)) dump_current_frames_thread = DumpThreads() dump_current_frames_thread.daemon = True # Daemon so that this thread doesn't halt it! diff --git a/setup.py b/setup.py index 32487bfe0..2ecc0dadd 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -r''' +r""" Full setup, used to distribute the debugger backend to PyPi. Note that this is mostly so that users can do: @@ -19,7 +19,7 @@ build_tools\pydevd_release_process.txt for release process. -''' +""" from setuptools import setup from setuptools.dist import Distribution @@ -28,7 +28,6 @@ class BinaryDistribution(Distribution): - def is_pure(self): return False @@ -38,105 +37,107 @@ def is_pure(self): def accept_file(f): f = f.lower() - for ext in '.py .dll .so .dylib .txt .cpp .h .bat .c .sh .md .txt'.split(): + for ext in ".py .dll .so .dylib .txt .cpp .h .bat .c .sh .md .txt".split(): if f.endswith(ext): return True - return f in ['readme', 'makefile'] + return f in ["readme", "makefile"] -data_files.append(('pydevd_attach_to_process', [os.path.join('pydevd_attach_to_process', f) for f in os.listdir('pydevd_attach_to_process') if accept_file(f)])) +data_files.append( + ( + "pydevd_attach_to_process", + [os.path.join("pydevd_attach_to_process", f) for f in os.listdir("pydevd_attach_to_process") if accept_file(f)], + ) +) for root, dirs, files in os.walk("pydevd_attach_to_process"): for d in dirs: data_files.append((os.path.join(root, d), [os.path.join(root, d, f) for f in os.listdir(os.path.join(root, d)) if accept_file(f)])) import pydevd + version = pydevd.__version__ -with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'README.md'), 'r', encoding='utf-8') as stream: +with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), "README.md"), "r", encoding="utf-8") as stream: long_description = stream.read() args = dict( - name='pydevd', + name="pydevd", version=version, - description='PyDev.Debugger (used in PyDev, PyCharm and VSCode Python)', - long_description_content_type='text/markdown', + description="PyDev.Debugger (used in PyDev, PyCharm and VSCode Python)", + long_description_content_type="text/markdown", long_description=long_description, - author='Fabio Zadrozny and others', - url='https://github.com/fabioz/PyDev.Debugger/', - license='EPL', + author="Fabio Zadrozny and others", + url="https://github.com/fabioz/PyDev.Debugger/", + license="EPL", packages=[ - '_pydev_bundle', - '_pydev_bundle.fsnotify', - '_pydev_runfiles', - '_pydevd_bundle', - '_pydevd_bundle._debug_adapter', - '_pydevd_bundle.pydevd_concurrency_analyser', - '_pydevd_frame_eval', - '_pydevd_sys_monitoring', - '_pydevd_frame_eval.vendored', - '_pydevd_frame_eval.vendored.bytecode', - 'pydev_ipython', - + "_pydev_bundle", + "_pydev_bundle.fsnotify", + "_pydev_runfiles", + "_pydevd_bundle", + "_pydevd_bundle._debug_adapter", + "_pydevd_bundle.pydevd_concurrency_analyser", + "_pydevd_frame_eval", + "_pydevd_sys_monitoring", + "_pydevd_frame_eval.vendored", + "_pydevd_frame_eval.vendored.bytecode", + "pydev_ipython", # 'pydev_sitecustomize', -- Not actually a package (not added) - - 'pydevd_attach_to_process', - - 'pydevd_plugins', - 'pydevd_plugins.extensions', - 'pydevd_plugins.extensions.types', + "pydevd_attach_to_process", + "pydevd_plugins", + "pydevd_plugins.extensions", + "pydevd_plugins.extensions.types", ], py_modules=[ # 'interpreterInfo', -- Not needed for debugger # 'pycompletionserver', -- Not needed for debugger - 'pydev_app_engine_debug_startup', + "pydev_app_engine_debug_startup", # 'pydev_coverage', -- Not needed for debugger # 'pydev_pysrc', -- Not needed for debugger - 'pydev_run_in_console', - 'pydevconsole', - 'pydevd_file_utils', - 'pydevd', - 'pydevd_tracing', + "pydev_run_in_console", + "pydevconsole", + "pydevd_file_utils", + "pydevd", + "pydevd_tracing", # 'runfiles', -- Not needed for debugger - 'setup_pydevd_cython', # Distributed to clients. See: https://github.com/fabioz/PyDev.Debugger/issues/102 + "setup_pydevd_cython", # Distributed to clients. See: https://github.com/fabioz/PyDev.Debugger/issues/102 # 'setup', -- Should not be included as a module ], classifiers=[ - 'Development Status :: 6 - Mature', - 'Environment :: Console', - 'Intended Audience :: Developers', - - 'License :: OSI Approved :: Eclipse Public License 1.0 (EPL-1.0)', - - 'Operating System :: MacOS :: MacOS X', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: POSIX', - 'Programming Language :: Python', - 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.8', - 'Programming Language :: Python :: 3.9', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Topic :: Software Development :: Debuggers', + "Development Status :: 6 - Mature", + "Environment :: Console", + "Intended Audience :: Developers", + "License :: OSI Approved :: Eclipse Public License 1.0 (EPL-1.0)", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX", + "Programming Language :: Python", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Topic :: Software Development :: Debuggers", ], entry_points={ - 'console_scripts':[ - 'pydevd = pydevd:main', + "console_scripts": [ + "pydevd = pydevd:main", ], }, data_files=data_files, - keywords=['pydev', 'pydevd', 'pydev.debugger'], + keywords=["pydev", "pydevd", "pydev.debugger"], include_package_data=True, zip_safe=False, ) import sys + try: extra_compile_args = [] extra_link_args = [] - if 'linux' in sys.platform: + if "linux" in sys.platform: # Enabling -flto brings executable from 4MB to 0.56MB and -Os to 0.41MB # Profiling shows an execution around 3-5% slower with -Os vs -O3, # so, kept only -flto. @@ -152,7 +153,7 @@ def accept_file(f): # extra_compile_args = ["-flto", "-fprofile-generate"] # ... Run benchmarks ... # extra_compile_args = ["-flto", "-fprofile-use", "-fprofile-correction"] - elif 'win32' in sys.platform: + elif "win32" in sys.platform: pass # uncomment to generate pdbs for visual studio. # extra_compile_args=["-Zi", "/Od"] @@ -160,29 +161,33 @@ def accept_file(f): kwargs = {} if extra_link_args: - kwargs['extra_link_args'] = extra_link_args + kwargs["extra_link_args"] = extra_link_args if extra_compile_args: - kwargs['extra_compile_args'] = extra_compile_args + kwargs["extra_compile_args"] = extra_compile_args ext_modules = [ - # In this setup, don't even try to compile with cython, just go with the .c file which should've - # been properly generated from a tested version. - Extension( - '_pydevd_bundle.pydevd_cython', - ["_pydevd_bundle/pydevd_cython.c", ], - define_macros=[('Py_BUILD_CORE_MODULE', '1')], - **kwargs - ) - ] + # In this setup, don't even try to compile with cython, just go with the .c file which should've + # been properly generated from a tested version. + Extension( + "_pydevd_bundle.pydevd_cython", + [ + "_pydevd_bundle/pydevd_cython.c", + ], + define_macros=[("Py_BUILD_CORE_MODULE", "1")], + **kwargs, + ) + ] py_version = sys.version_info[:2] if (3, 6) <= py_version <= (3, 10): ext_modules.append( Extension( - '_pydevd_frame_eval.pydevd_frame_evaluator', - ["_pydevd_frame_eval/pydevd_frame_evaluator.c", ], - define_macros=[('Py_BUILD_CORE_MODULE', '1')], - **kwargs + "_pydevd_frame_eval.pydevd_frame_evaluator", + [ + "_pydevd_frame_eval/pydevd_frame_evaluator.c", + ], + define_macros=[("Py_BUILD_CORE_MODULE", "1")], + **kwargs, ) ) @@ -191,20 +196,19 @@ def accept_file(f): if py_version >= (3, 12): ext_modules.append( Extension( - '_pydevd_sys_monitoring._pydevd_sys_monitoring_cython', - ["_pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.c", ], - define_macros=[('Py_BUILD_CORE_MODULE', '1')], - **kwargs + "_pydevd_sys_monitoring._pydevd_sys_monitoring_cython", + [ + "_pydevd_sys_monitoring/_pydevd_sys_monitoring_cython.c", + ], + define_macros=[("Py_BUILD_CORE_MODULE", "1")], + **kwargs, ) ) args_with_binaries = args.copy() - args_with_binaries.update(dict( - distclass=BinaryDistribution, - ext_modules=ext_modules - )) + args_with_binaries.update(dict(distclass=BinaryDistribution, ext_modules=ext_modules)) setup(**args_with_binaries) except: # Compile failed: just setup without compiling cython deps. setup(**args) - sys.stdout.write('Plain-python version of pydevd installed (cython speedups not available).\n') + sys.stdout.write("Plain-python version of pydevd installed (cython speedups not available).\n") diff --git a/setup_pydevd_cython.py b/setup_pydevd_cython.py index ef2fd0268..14b97853e 100644 --- a/setup_pydevd_cython.py +++ b/setup_pydevd_cython.py @@ -1,4 +1,4 @@ -''' +""" A simpler setup version just to compile the speedup module. It should be used as: @@ -7,7 +7,7 @@ Note: the .c file and other generated files are regenerated from the .pyx file by running "python build_tools/build.py" -''' +""" import os import sys @@ -27,16 +27,16 @@ def process_args(): force_cython = False for i, arg in enumerate(sys.argv[:]): - if arg == '--build-lib': + if arg == "--build-lib": extension_folder = sys.argv[i + 1] # It shouldn't be removed from sys.argv (among with --build-temp) because they're passed further to setup() - if arg.startswith('--target-pyd-name='): + if arg.startswith("--target-pyd-name="): sys.argv.remove(arg) - target_pydevd_name = arg[len('--target-pyd-name='):] - if arg.startswith('--target-pyd-frame-eval='): + target_pydevd_name = arg[len("--target-pyd-name=") :] + if arg.startswith("--target-pyd-frame-eval="): sys.argv.remove(arg) - target_frame_eval = arg[len('--target-pyd-frame-eval='):] - if arg == '--force-cython': + target_frame_eval = arg[len("--target-pyd-frame-eval=") :] + if arg == "--force-cython": sys.argv.remove(arg) force_cython = True @@ -45,26 +45,32 @@ def process_args(): def process_template_lines(template_lines): # Create 2 versions of the template, one for Python 3.8 and another for Python 3.9 - for version in ('38', '39'): - yield '### WARNING: GENERATED CODE, DO NOT EDIT!' - yield '### WARNING: GENERATED CODE, DO NOT EDIT!' - yield '### WARNING: GENERATED CODE, DO NOT EDIT!' + for version in ("38", "39"): + yield "### WARNING: GENERATED CODE, DO NOT EDIT!" + yield "### WARNING: GENERATED CODE, DO NOT EDIT!" + yield "### WARNING: GENERATED CODE, DO NOT EDIT!" for line in template_lines: - if version == '38': - line = line.replace('get_bytecode_while_frame_eval(PyFrameObject * frame_obj, int exc)', 'get_bytecode_while_frame_eval_38(PyFrameObject * frame_obj, int exc)') - line = line.replace('CALL_EvalFrameDefault', 'CALL_EvalFrameDefault_38(frame_obj, exc)') + if version == "38": + line = line.replace( + "get_bytecode_while_frame_eval(PyFrameObject * frame_obj, int exc)", + "get_bytecode_while_frame_eval_38(PyFrameObject * frame_obj, int exc)", + ) + line = line.replace("CALL_EvalFrameDefault", "CALL_EvalFrameDefault_38(frame_obj, exc)") else: # 3.9 - line = line.replace('get_bytecode_while_frame_eval(PyFrameObject * frame_obj, int exc)', 'get_bytecode_while_frame_eval_39(PyThreadState* tstate, PyFrameObject * frame_obj, int exc)') - line = line.replace('CALL_EvalFrameDefault', 'CALL_EvalFrameDefault_39(tstate, frame_obj, exc)') + line = line.replace( + "get_bytecode_while_frame_eval(PyFrameObject * frame_obj, int exc)", + "get_bytecode_while_frame_eval_39(PyThreadState* tstate, PyFrameObject * frame_obj, int exc)", + ) + line = line.replace("CALL_EvalFrameDefault", "CALL_EvalFrameDefault_39(tstate, frame_obj, exc)") yield line - yield '### WARNING: GENERATED CODE, DO NOT EDIT!' - yield '### WARNING: GENERATED CODE, DO NOT EDIT!' - yield '### WARNING: GENERATED CODE, DO NOT EDIT!' - yield '' - yield '' + yield "### WARNING: GENERATED CODE, DO NOT EDIT!" + yield "### WARNING: GENERATED CODE, DO NOT EDIT!" + yield "### WARNING: GENERATED CODE, DO NOT EDIT!" + yield "" + yield "" def process_template_file(contents): @@ -73,16 +79,16 @@ def process_template_file(contents): append_to = ret for line in contents.splitlines(keepends=False): - if line.strip() == '### TEMPLATE_START': + if line.strip() == "### TEMPLATE_START": append_to = template_lines - elif line.strip() == '### TEMPLATE_END': + elif line.strip() == "### TEMPLATE_END": append_to = ret for line in process_template_lines(template_lines): ret.append(line) else: append_to.append(line) - return '\n'.join(ret) + return "\n".join(ret) def build_extension(dir_name, extension_name, target_pydevd_name, force_cython, extended=False, has_pxd=False, template=False): @@ -90,12 +96,12 @@ def build_extension(dir_name, extension_name, target_pydevd_name, force_cython, if template: pyx_template_file = os.path.join(os.path.dirname(__file__), dir_name, "%s.template.pyx" % (extension_name,)) - with open(pyx_template_file, 'r') as stream: + with open(pyx_template_file, "r") as stream: contents = stream.read() contents = process_template_file(contents) - with open(pyx_file, 'w') as stream: + with open(pyx_file, "w") as stream: stream.write(contents) if target_pydevd_name != extension_name: @@ -118,7 +124,9 @@ def build_extension(dir_name, extension_name, target_pydevd_name, force_cython, assert os.path.exists(pyx_file) try: - c_files = [os.path.join(dir_name, "%s.c" % target_pydevd_name), ] + c_files = [ + os.path.join(dir_name, "%s.c" % target_pydevd_name), + ] if force_cython: for c_file in c_files: try: @@ -128,45 +136,57 @@ def build_extension(dir_name, extension_name, target_pydevd_name, force_cython, from Cython.Build import cythonize # @UnusedImport # Generate the .c files in cythonize (will not compile at this point). - target = "%s/%s.pyx" % (dir_name, target_pydevd_name,) + target = "%s/%s.pyx" % ( + dir_name, + target_pydevd_name, + ) cythonize([target]) # Workarounds needed in CPython 3.8 and 3.9 to access PyInterpreterState.eval_frame. for c_file in c_files: - with open(c_file, 'r') as stream: + with open(c_file, "r") as stream: c_file_contents = stream.read() if '#include "internal/pycore_gc.h"' not in c_file_contents: - c_file_contents = c_file_contents.replace('#include "Python.h"', '''#include "Python.h" + c_file_contents = c_file_contents.replace( + '#include "Python.h"', + """#include "Python.h" #if PY_VERSION_HEX >= 0x03090000 #include "internal/pycore_gc.h" #include "internal/pycore_interp.h" #endif -''') +""", + ) if '#include "internal/pycore_pystate.h"' not in c_file_contents: - c_file_contents = c_file_contents.replace('#include "pystate.h"', '''#include "pystate.h" + c_file_contents = c_file_contents.replace( + '#include "pystate.h"', + """#include "pystate.h" #if PY_VERSION_HEX >= 0x03080000 #include "internal/pycore_pystate.h" #endif -''') +""", + ) # We want the same output on Windows and Linux. - c_file_contents = c_file_contents.replace('\r\n', '\n').replace('\r', '\n') - c_file_contents = c_file_contents.replace(r'_pydevd_frame_eval\\release_mem.h', '_pydevd_frame_eval/release_mem.h') - c_file_contents = c_file_contents.replace(r'_pydevd_frame_eval\\pydevd_frame_evaluator.pyx', '_pydevd_frame_eval/pydevd_frame_evaluator.pyx') - c_file_contents = c_file_contents.replace(r'_pydevd_bundle\\pydevd_cython.pxd', '_pydevd_bundle/pydevd_cython.pxd') - c_file_contents = c_file_contents.replace(r'_pydevd_bundle\\pydevd_cython.pyx', '_pydevd_bundle/pydevd_cython.pyx') - - with open(c_file, 'w') as stream: + c_file_contents = c_file_contents.replace("\r\n", "\n").replace("\r", "\n") + c_file_contents = c_file_contents.replace(r"_pydevd_frame_eval\\release_mem.h", "_pydevd_frame_eval/release_mem.h") + c_file_contents = c_file_contents.replace( + r"_pydevd_frame_eval\\pydevd_frame_evaluator.pyx", "_pydevd_frame_eval/pydevd_frame_evaluator.pyx" + ) + c_file_contents = c_file_contents.replace(r"_pydevd_bundle\\pydevd_cython.pxd", "_pydevd_bundle/pydevd_cython.pxd") + c_file_contents = c_file_contents.replace(r"_pydevd_bundle\\pydevd_cython.pyx", "_pydevd_bundle/pydevd_cython.pyx") + + with open(c_file, "w") as stream: stream.write(c_file_contents) # Always compile the .c (and not the .pyx) file (which we should keep up-to-date by running build_tools/build.py). from distutils.extension import Extension + extra_compile_args = [] extra_link_args = [] - if 'linux' in sys.platform: + if "linux" in sys.platform: # Enabling -flto brings executable from 4MB to 0.56MB and -Os to 0.41MB # Profiling shows an execution around 3-5% slower with -Os vs -O3, # so, kept only -flto. @@ -182,7 +202,7 @@ def build_extension(dir_name, extension_name, target_pydevd_name, force_cython, # extra_compile_args = ["-flto", "-fprofile-generate"] # ... Run benchmarks ... # extra_compile_args = ["-flto", "-fprofile-use", "-fprofile-correction"] - elif 'win32' in sys.platform: + elif "win32" in sys.platform: pass # uncomment to generate pdbs for visual studio. # extra_compile_args=["-Zi", "/Od"] @@ -190,48 +210,54 @@ def build_extension(dir_name, extension_name, target_pydevd_name, force_cython, kwargs = {} if extra_link_args: - kwargs['extra_link_args'] = extra_link_args + kwargs["extra_link_args"] = extra_link_args if extra_compile_args: - kwargs['extra_compile_args'] = extra_compile_args + kwargs["extra_compile_args"] = extra_compile_args ext_modules = [ Extension( - "%s%s.%s" % (dir_name, "_ext" if extended else "", target_pydevd_name,), + "%s%s.%s" + % ( + dir_name, + "_ext" if extended else "", + target_pydevd_name, + ), c_files, - **kwargs - )] + **kwargs, + ) + ] # This is needed in CPython 3.8 to be able to include internal/pycore_pystate.h # (needed to set PyInterpreterState.eval_frame). for module in ext_modules: - module.define_macros = [('Py_BUILD_CORE_MODULE', '1')] - setup( - name='Cythonize', - ext_modules=ext_modules - ) + module.define_macros = [("Py_BUILD_CORE_MODULE", "1")] + setup(name="Cythonize", ext_modules=ext_modules) finally: if target_pydevd_name != extension_name: try: os.remove(new_pyx_file) except: import traceback + traceback.print_exc() try: os.remove(new_c_file) except: import traceback + traceback.print_exc() if has_pxd: try: os.remove(new_pxd_file) except: import traceback + traceback.print_exc() extension_folder, target_pydevd_name, target_frame_eval, force_cython = process_args() -FORCE_BUILD_ALL = os.environ.get('PYDEVD_FORCE_BUILD_ALL', '').lower() in ('true', '1') +FORCE_BUILD_ALL = os.environ.get("PYDEVD_FORCE_BUILD_ALL", "").lower() in ("true", "1") extension_name = "pydevd_cython" if target_pydevd_name is None: @@ -250,8 +276,9 @@ def build_extension(dir_name, extension_name, target_pydevd_name, force_cython, if extension_folder: os.chdir(extension_folder) - for folder in [file for file in os.listdir(extension_folder) if - file != 'build' and os.path.isdir(os.path.join(extension_folder, file))]: + for folder in [ + file for file in os.listdir(extension_folder) if file != "build" and os.path.isdir(os.path.join(extension_folder, file)) + ]: file = os.path.join(folder, "__init__.py") if not os.path.exists(file): - open(file, 'a').close() + open(file, "a").close() diff --git a/stubs/_django_manager_body.py b/stubs/_django_manager_body.py index 2bf47067c..15564b743 100644 --- a/stubs/_django_manager_body.py +++ b/stubs/_django_manager_body.py @@ -1,10 +1,12 @@ # This is a dummy for code-completion purposes. + def __unicode__(self): """ - Return "app_label.model_label.manager_name". + Return "app_label.model_label.manager_name". """ + def _copy_to_model(self, model): """ Makes a copy of the manager and assigns it to 'model', which should be @@ -14,15 +16,11 @@ def _copy_to_model(self, model): def _db(self): - """ - - """ + """ """ def _get_queryset_methods(cls, queryset_class): - """ - - """ + """ """ def _hints(self): @@ -40,9 +38,7 @@ def _hints(self): def _inherited(self): - """ - - """ + """ """ def _insert(self, *args, **kwargs): @@ -78,7 +74,7 @@ def aggregate(self, *args, **kwargs): """ Returns a dictionary containing the calculations (aggregation) over the current queryset - + If args is present the expression is passed as a kwarg using the Aggregate object's default alias. """ @@ -107,36 +103,32 @@ def bulk_create(self, *args, **kwargs): def check(self, **kwargs): - """ - - """ + """ """ def complex_filter(self, *args, **kwargs): """ Returns a new QuerySet instance with filter_obj added to the filters. - + filter_obj can be a Q object (or anything with an add_to_query() method) or a dictionary of keyword lookup arguments. - + This exists to support framework features such as 'limit_choices_to', and usually it will be more natural to use other methods. - + @rtype: django.db.models.query.QuerySet """ def contribute_to_class(self, model, name): - """ - - """ + """ """ def count(self, *args, **kwargs): """ Performs a SELECT COUNT() and returns the number of records as an integer. - + If the QuerySet is already fully cached this simply returns the length of the cached results set to avoid multiple SELECT COUNT(*) calls. """ @@ -150,9 +142,7 @@ def create(self, *args, **kwargs): def creation_counter(self): - """ - - """ + """ """ def dates(self, *args, **kwargs): @@ -170,15 +160,11 @@ def datetimes(self, *args, **kwargs): def db(self): - """ - - """ + """ """ def db_manager(self, using=None, hints=None): - """ - - """ + """ """ def defer(self, *args, **kwargs): @@ -194,30 +180,26 @@ def defer(self, *args, **kwargs): def distinct(self, *args, **kwargs): """ Returns a new QuerySet instance that will select only distinct results. - + @rtype: django.db.models.query.QuerySet """ def earliest(self, *args, **kwargs): - """ - - """ + """ """ def exclude(self, *args, **kwargs): """ Returns a new QuerySet instance with NOT (args) ANDed to the existing set. - + @rtype: django.db.models.query.QuerySet """ def exists(self, *args, **kwargs): - """ - - """ + """ """ def extra(self, *args, **kwargs): @@ -230,7 +212,7 @@ def filter(self, *args, **kwargs): """ Returns a new QuerySet instance with the args ANDed to the existing set. - + @rtype: django.db.models.query.QuerySet """ @@ -242,9 +224,7 @@ def first(self, *args, **kwargs): def from_queryset(cls, queryset_class, class_name=None): - """ - - """ + """ """ def get(self, *args, **kwargs): @@ -266,7 +246,7 @@ def get_queryset(self): """ Returns a new QuerySet object. Subclasses can override this method to easily customize the behavior of the Manager. - + @rtype: django.db.models.query.QuerySet """ @@ -292,9 +272,7 @@ def last(self, *args, **kwargs): def latest(self, *args, **kwargs): - """ - - """ + """ """ def model(self): @@ -306,7 +284,7 @@ def model(self): def none(self, *args, **kwargs): """ Returns an empty QuerySet. - + @rtype: django.db.models.query.QuerySet """ @@ -322,7 +300,7 @@ def only(self, *args, **kwargs): def order_by(self, *args, **kwargs): """ Returns a new QuerySet instance with the ordering changed. - + @rtype: django.db.models.query.QuerySet """ @@ -332,25 +310,23 @@ def prefetch_related(self, *args, **kwargs): Returns a new QuerySet instance that will prefetch the specified Many-To-One and Many-To-Many related objects when the QuerySet is evaluated. - + When prefetch_related() is called more than once, the list of lookups to prefetch is appended to. If prefetch_related(None) is called, the list is cleared. - + @rtype: django.db.models.query.QuerySet """ def raw(self, *args, **kwargs): - """ - - """ + """ """ def reverse(self, *args, **kwargs): """ Reverses the ordering of the QuerySet. - + @rtype: django.db.models.query.QuerySet """ @@ -359,7 +335,7 @@ def select_for_update(self, *args, **kwargs): """ Returns a new QuerySet instance that will select objects with a FOR UPDATE lock. - + @rtype: django.db.models.query.QuerySet """ @@ -367,12 +343,12 @@ def select_for_update(self, *args, **kwargs): def select_related(self, *args, **kwargs): """ Returns a new QuerySet instance that will select related objects. - + If fields are specified, they must be ForeignKey fields and only those related objects are included in the selection. - + If select_related(None) is called, the list is cleared. - + @rtype: django.db.models.query.QuerySet """ @@ -396,19 +372,14 @@ def update_or_create(self, *args, **kwargs): def using(self, *args, **kwargs): """ Selects which database this QuerySet should execute its query against. - + @rtype: django.db.models.query.QuerySet """ def values(self, *args, **kwargs): - """ - - """ + """ """ def values_list(self, *args, **kwargs): - """ - - """ - + """ """ diff --git a/test_pydevd_reload/test_pydevd_reload.py b/test_pydevd_reload/test_pydevd_reload.py index 067f3da6d..faa5c263a 100644 --- a/test_pydevd_reload/test_pydevd_reload.py +++ b/test_pydevd_reload/test_pydevd_reload.py @@ -26,9 +26,8 @@ def unchanged(self): from _pydevd_bundle.pydevd_constants import IS_JYTHON, IS_IRONPYTHON -@pytest.mark.skipif(IS_JYTHON or IS_IRONPYTHON, reason='CPython related test') +@pytest.mark.skipif(IS_JYTHON or IS_IRONPYTHON, reason="CPython related test") class Test(unittest.TestCase): - def setUp(self): unittest.TestCase.setUp(self) self.tempdir = None @@ -37,7 +36,7 @@ def setUp(self): self.save_path = list(sys.path) sys.path.append(self.tempdir) try: - del sys.modules['x'] + del sys.modules["x"] except: pass @@ -45,14 +44,14 @@ def tearDown(self): unittest.TestCase.tearDown(self) sys.path = self.save_path try: - del sys.modules['x'] + del sys.modules["x"] except: pass def make_mod(self, name="x", repl=None, subst=None, sample=SAMPLE_CODE): basedir = self.tempdir - if '.' in name: - splitted = name.split('.') + if "." in name: + splitted = name.split(".") basedir = os.path.join(self.tempdir, *splitted[:-1]) name = splitted[-1] try: @@ -70,7 +69,6 @@ def make_mod(self, name="x", repl=None, subst=None, sample=SAMPLE_CODE): f.close() def test_pydevd_reload(self): - self.make_mod() import x # @UnresolvedImport @@ -112,7 +110,6 @@ def check(expected): check(count) def test_pydevd_reload2(self): - self.make_mod() import x # @UnresolvedImport @@ -121,20 +118,17 @@ def test_pydevd_reload2(self): self.assertEqual(0, c.foo()) self.assertEqual(0, cfoo()) - self.make_mod(repl="0", subst='1') + self.make_mod(repl="0", subst="1") pydevd_reload.xreload(x) self.assertEqual(1, c.foo()) self.assertEqual(1, cfoo()) def test_pydevd_reload3(self): - class F: - def m1(self): return 1 class G: - def m1(self): return 2 @@ -143,39 +137,34 @@ def m1(self): self.assertEqual(F().m1(), 2) def test_pydevd_reload4(self): - class F: pass - F.m1 = lambda a:None + F.m1 = lambda a: None class G: pass - G.m1 = lambda a:10 + G.m1 = lambda a: 10 self.assertEqual(F().m1(), None) pydevd_reload.Reload(None)._update(None, None, F, G) self.assertEqual(F().m1(), 10) def test_if_code_obj_equals(self): - class F: - def m1(self): return 1 class G: - def m1(self): return 1 class H: - def m1(self): return 2 - if hasattr(F.m1, 'func_code'): + if hasattr(F.m1, "func_code"): self.assertTrue(pydevd_reload.code_objects_equal(F.m1.func_code, G.m1.func_code)) self.assertFalse(pydevd_reload.code_objects_equal(F.m1.func_code, H.m1.func_code)) else: @@ -183,9 +172,7 @@ def m1(self): self.assertFalse(pydevd_reload.code_objects_equal(F.m1.__code__, H.m1.__code__)) def test_metaclass(self): - class Meta(type): - def __init__(cls, name, bases, attrs): super(Meta, cls).__init__(name, bases, attrs) @@ -206,19 +193,15 @@ def m1(self): self.assertEqual(F().m1(), 2) def test_change_hierarchy(self): - class F(object): - def m1(self): return 1 class B(object): - def super_call(self): return 2 class G(B): - def m1(self): return self.super_call() @@ -237,19 +220,15 @@ def on_error(*args): pydevd_reload.notify_error = old def test_change_hierarchy_old_style(self): - class F: - def m1(self): return 1 class B: - def super_call(self): return 2 class G(B): - def m1(self): return self.super_call() @@ -285,11 +264,12 @@ def foo(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + foo = x.C().foo self.assertEqual(foo(), 0) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) - self.assertEqual(foo().__name__, 'B') + self.assertEqual(foo().__name__, "B") def test_create_class2(self): SAMPLE_CODE1 = """ @@ -309,11 +289,12 @@ def foo(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + foo = x.C().foo self.assertEqual(foo(), 0) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) - self.assertEqual(foo().__name__, 'B') + self.assertEqual(foo().__name__, "B") def test_parent_function(self): SAMPLE_CODE1 = """ @@ -340,11 +321,12 @@ def call(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + call = x.C().call self.assertEqual(call(), 0) self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) - self.assertEqual(call(), 'bar') + self.assertEqual(call(), "bar") def test_update_constant(self): SAMPLE_CODE1 = """ @@ -364,6 +346,7 @@ def foo(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) @@ -392,6 +375,7 @@ def foo(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) @@ -419,6 +403,7 @@ def foo(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) @@ -450,6 +435,7 @@ def foo(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) @@ -483,6 +469,7 @@ def foo(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + foo = x.B().foo self.assertEqual(foo(), 1) self.make_mod(sample=SAMPLE_CODE2) @@ -509,13 +496,14 @@ def m1(self): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport + B = x.B self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) b = B() self.assertEqual(1, b.m1()) self.assertEqual(10, b.bar) - self.assertRaises(Exception, setattr, b, 'foo', 20) # __slots__ can't be updated + self.assertRaises(Exception, setattr, b, "foo", 20) # __slots__ can't be updated def test_reload_numpy(self): SAMPLE_CODE1 = """ @@ -533,13 +521,14 @@ def method(): self.make_mod(sample=SAMPLE_CODE1) import x # @UnresolvedImport - assert str(x.global_numpy) == '[1 2 3]' + + assert str(x.global_numpy) == "[1 2 3]" self.make_mod(sample=SAMPLE_CODE2) pydevd_reload.xreload(x) # Note that we don't patch globals (the user could do that in a module, # but he'd have to create a custom `__xreload_old_new__` method to # do it). - assert str(x.global_numpy) == '[1 2 3]' + assert str(x.global_numpy) == "[1 2 3]" def test_reload_relative(self): MODULE_CODE = """ @@ -562,12 +551,13 @@ def add_more_text(s): return s + ' module1V2' """ - self.make_mod(sample='', name='package.__init__') - self.make_mod(sample=MODULE_CODE, name='package.module') - self.make_mod(sample=MODULE1_CODE, name='package.module1') + self.make_mod(sample="", name="package.__init__") + self.make_mod(sample=MODULE_CODE, name="package.module") + self.make_mod(sample=MODULE1_CODE, name="package.module1") from package import module1 # @UnresolvedImport - assert module1.add_more_text('1') == '1 module module1' - self.make_mod(sample=MODULE1_CODE_V2, name='package.module1') + assert module1.add_more_text("1") == "1 module module1" + + self.make_mod(sample=MODULE1_CODE_V2, name="package.module1") pydevd_reload.xreload(module1) - assert module1.add_more_text('1') == '1 module module1V2' + assert module1.add_more_text("1") == "1 module module1V2" diff --git a/tests/test_check_pydevconsole.py b/tests/test_check_pydevconsole.py index 8795918b1..53eb28c7e 100644 --- a/tests/test_check_pydevconsole.py +++ b/tests/test_check_pydevconsole.py @@ -9,23 +9,23 @@ try: raw_input - raw_input_name = 'raw_input' + raw_input_name = "raw_input" except NameError: - raw_input_name = 'input' - + raw_input_name = "input" + try: from IPython import core # @UnusedImport + has_ipython = True except: has_ipython = False -#======================================================================================================================= +# ======================================================================================================================= # Test -#======================================================================================================================= -@pytest.mark.skipif(os.environ.get('TRAVIS') == 'true' or not has_ipython, reason='Too flaky on Travis (and requires IPython).') +# ======================================================================================================================= +@pytest.mark.skipif(os.environ.get("TRAVIS") == "true" or not has_ipython, reason="Too flaky on Travis (and requires IPython).") class Test(unittest.TestCase): - def start_client_thread(self, client_port): class ClientThread(threading.Thread): def __init__(self, client_port): @@ -36,7 +36,7 @@ def run(self): class HandleRequestInput: def RequestInput(self): client_thread.requested_input = True - return 'RequestInput: OK' + return "RequestInput: OK" def NotifyFinished(self, *args, **kwargs): client_thread.notified_finished += 1 @@ -45,7 +45,10 @@ def NotifyFinished(self, *args, **kwargs): handle_request_input = HandleRequestInput() from _pydev_bundle import pydev_localhost - self.client_server = client_server = SimpleXMLRPCServer((pydev_localhost.get_localhost(), self.client_port), logRequests=False) + + self.client_server = client_server = SimpleXMLRPCServer( + (pydev_localhost.get_localhost(), self.client_port), logRequests=False + ) client_server.register_function(handle_request_input.RequestInput) client_server.register_function(handle_request_input.NotifyFinished) client_server.serve_forever() @@ -61,18 +64,20 @@ def shutdown(self): client_thread.start() return client_thread - def get_free_addresses(self): from _pydev_bundle.pydev_localhost import get_socket_names + socket_names = get_socket_names(2, close=True) return [socket_name[1] for socket_name in socket_names] def test_server(self): # Just making sure that the singleton is created in this thread. from _pydev_bundle.pydev_ipython_console_011 import get_pydev_frontend + get_pydev_frontend(get_localhost(), 0) client_port, server_port = self.get_free_addresses() + class ServerThread(threading.Thread): def __init__(self, client_port, server_port): threading.Thread.__init__(self) @@ -81,33 +86,36 @@ def __init__(self, client_port, server_port): def run(self): from _pydev_bundle import pydev_localhost - print('Starting server with:', pydev_localhost.get_localhost(), self.server_port, self.client_port) + + print("Starting server with:", pydev_localhost.get_localhost(), self.server_port, self.client_port) pydevconsole.start_server(pydev_localhost.get_localhost(), self.server_port, self.client_port) + server_thread = ServerThread(client_port, server_port) server_thread.daemon = True server_thread.start() - client_thread = self.start_client_thread(client_port) #@UnusedVariable + client_thread = self.start_client_thread(client_port) # @UnusedVariable try: import time - time.sleep(.3) #let's give it some time to start the threads + + time.sleep(0.3) # let's give it some time to start the threads from _pydev_bundle import pydev_localhost - server = xmlrpclib.Server('http://%s:%s' % (pydev_localhost.get_localhost(), server_port)) + + server = xmlrpclib.Server("http://%s:%s" % (pydev_localhost.get_localhost(), server_port)) server.execLine("import sys; print('Running with: %s %s' % (sys.executable or sys.platform, sys.version))") - server.execLine('class Foo:') - server.execLine(' pass') - server.execLine('') - server.execLine('foo = Foo()') - server.execLine('a = %s()' % raw_input_name) + server.execLine("class Foo:") + server.execLine(" pass") + server.execLine("") + server.execLine("foo = Foo()") + server.execLine("a = %s()" % raw_input_name) initial = time.time() while not client_thread.requested_input: if time.time() - initial > 2: - raise AssertionError('Did not get the return asked before the timeout.') - time.sleep(.1) + raise AssertionError("Did not get the return asked before the timeout.") + time.sleep(0.1) frame_xml = server.getFrame() - self.assertTrue('RequestInput' in frame_xml, 'Did not fid RequestInput in:\n%s' % (frame_xml,)) + self.assertTrue("RequestInput" in frame_xml, "Did not fid RequestInput in:\n%s" % (frame_xml,)) finally: client_thread.shutdown() - diff --git a/tests/test_get_referrers.py b/tests/test_get_referrers.py index c4f7c149a..88f688d44 100644 --- a/tests/test_get_referrers.py +++ b/tests/test_get_referrers.py @@ -9,6 +9,7 @@ try: import gc + gc.get_referrers(unittest) has_referrers = True except NotImplementedError: @@ -16,11 +17,9 @@ # Only do get referrers tests if it's actually available. -@pytest.mark.skipif(not has_referrers or IS_PYPY, reason='gc.get_referrers not implemented') +@pytest.mark.skipif(not has_referrers or IS_PYPY, reason="gc.get_referrers not implemented") class Test(unittest.TestCase): - def test_get_referrers1(self): - container = [] contained = [1, 2] container.append(0) @@ -29,13 +28,11 @@ def test_get_referrers1(self): # Ok, we have the contained in this frame and inside the given list (which on turn is in this frame too). # we should skip temporary references inside the get_referrer_info. result = pydevd_referrers.get_referrer_info(contained) - assert 'list[1]' in result + assert "list[1]" in result pydevd_referrers.print_referrers(contained, stream=StringIO()) def test_get_referrers2(self): - class MyClass(object): - def __init__(self): pass @@ -48,12 +45,10 @@ def __init__(self): # we should skip temporary references inside the get_referrer_info. result = pydevd_referrers.get_referrer_info(obj.contained) assert 'found_as="contained"' in result - assert 'MyClass' in result + assert "MyClass" in result def test_get_referrers3(self): - class MyClass(object): - def __init__(self): pass @@ -66,12 +61,10 @@ def __init__(self): # we should skip temporary references inside the get_referrer_info. result = pydevd_referrers.get_referrer_info(obj.contained) assert 'found_as="contained"' in result - assert 'MyClass' in result + assert "MyClass" in result def test_get_referrers4(self): - class MyClass(object): - def __init__(self): pass @@ -86,40 +79,38 @@ def test_get_referrers5(self): container = dict(a=[1]) # Let's see if we detect the cycle... - result = pydevd_referrers.get_referrer_info(container['a']) - assert 'test_get_referrers5' not in result # I.e.: NOT in the current method + result = pydevd_referrers.get_referrer_info(container["a"]) + assert "test_get_referrers5" not in result # I.e.: NOT in the current method assert 'found_as="a"' in result - assert 'dict' in result + assert "dict" in result assert str(id(container)) in result def test_get_referrers6(self): import sys + container = dict(a=[1]) def should_appear(obj): # Let's see if we detect the cycle... return pydevd_referrers.get_referrer_info(obj) - result = should_appear(container['a']) + result = should_appear(container["a"]) if sys.version_info[:2] >= (3, 7): # In Python 3.7 the frame is not appearing in gc.get_referrers. - assert 'should_appear' not in result + assert "should_appear" not in result else: - assert 'should_appear' in result + assert "should_appear" in result def test_get_referrers7(self): - class MyThread(threading.Thread): - def run(self): # Note: we do that because if we do self.frame = sys._getframe() t = MyThread() t.start() - while not hasattr(t, 'frame'): + while not hasattr(t, "frame"): time.sleep(0.01) result = pydevd_referrers.get_referrer_info(t.frame) - assert 'MyThread' in result - + assert "MyThread" in result diff --git a/tests/test_jyserver.py b/tests/test_jyserver.py index 7e7a9f5fb..eb67a649d 100644 --- a/tests/test_jyserver.py +++ b/tests/test_jyserver.py @@ -1,6 +1,6 @@ -''' +""" @author Fabio Zadrozny -''' +""" import sys import unittest import socket @@ -9,87 +9,83 @@ import pycompletionserver -IS_JYTHON = sys.platform.find('java') != -1 +IS_JYTHON = sys.platform.find("java") != -1 DEBUG = 0 + def dbg(s): if DEBUG: - sys.stdout.write('TEST %s\n' % s) + sys.stdout.write("TEST %s\n" % s) -@pytest.mark.skipif(not IS_JYTHON, reason='Jython related test') -class TestJython(unittest.TestCase): +@pytest.mark.skipif(not IS_JYTHON, reason="Jython related test") +class TestJython(unittest.TestCase): def test_it(self): - dbg('ok') + dbg("ok") - def test_message(self): t = pycompletionserver.CompletionServer(0) t.exit_process_on_kill = False l = [] - l.append(('Def', 'description' , 'args')) - l.append(('Def1', 'description1', 'args1')) - l.append(('Def2', 'description2', 'args2')) + l.append(("Def", "description", "args")) + l.append(("Def1", "description1", "args1")) + l.append(("Def2", "description2", "args2")) - msg = t.processor.format_completion_message('test_jyserver.py', l) + msg = t.processor.format_completion_message("test_jyserver.py", l) - self.assertEqual('@@COMPLETIONS(test_jyserver.py,(Def,description,args),(Def1,description1,args1),(Def2,description2,args2))END@@', msg) + self.assertEqual( + "@@COMPLETIONS(test_jyserver.py,(Def,description,args),(Def1,description1,args1),(Def2,description2,args2))END@@", msg + ) l = [] - l.append(('Def', 'desc,,r,,i()ption', '')) - l.append(('Def(1', 'descriptio(n1', '')) - l.append(('De,f)2', 'de,s,c,ription2', '')) + l.append(("Def", "desc,,r,,i()ption", "")) + l.append(("Def(1", "descriptio(n1", "")) + l.append(("De,f)2", "de,s,c,ription2", "")) msg = t.processor.format_completion_message(None, l) - expected = '@@COMPLETIONS(None,(Def,desc%2C%2Cr%2C%2Ci%28%29ption, ),(Def%281,descriptio%28n1, ),(De%2Cf%292,de%2Cs%2Cc%2Cription2, ))END@@' + expected = "@@COMPLETIONS(None,(Def,desc%2C%2Cr%2C%2Ci%28%29ption, ),(Def%281,descriptio%28n1, ),(De%2Cf%292,de%2Cs%2Cc%2Cription2, ))END@@" self.assertEqual(expected, msg) - def test_completion_sockets_and_messages(self): - dbg('test_completion_sockets_and_messages') + dbg("test_completion_sockets_and_messages") t, socket = self.create_connections() self.socket = socket - dbg('connections created') + dbg("connections created") try: - #now that we have the connections all set up, check the code completion messages. - msg = urllib.quote_plus('math') + # now that we have the connections all set up, check the code completion messages. + msg = urllib.quote_plus("math") - toWrite = '@@IMPORTS:%sEND@@' % msg - dbg('writing' + str(toWrite)) - socket.send(toWrite) #math completions + toWrite = "@@IMPORTS:%sEND@@" % msg + dbg("writing" + str(toWrite)) + socket.send(toWrite) # math completions completions = self.read_msg() dbg(urllib.unquote_plus(completions)) - start = '@@COMPLETIONS(' - self.assertTrue(completions.startswith(start), '%s DOESNT START WITH %s' % (completions, start)) - self.assertTrue(completions.find('@@COMPLETIONS') != -1) - self.assertTrue(completions.find('END@@') != -1) + start = "@@COMPLETIONS(" + self.assertTrue(completions.startswith(start), "%s DOESNT START WITH %s" % (completions, start)) + self.assertTrue(completions.find("@@COMPLETIONS") != -1) + self.assertTrue(completions.find("END@@") != -1) - - msg = urllib.quote_plus('__builtin__.str') - toWrite = '@@IMPORTS:%sEND@@' % msg - dbg('writing' + str(toWrite)) - socket.send(toWrite) #math completions + msg = urllib.quote_plus("__builtin__.str") + toWrite = "@@IMPORTS:%sEND@@" % msg + dbg("writing" + str(toWrite)) + socket.send(toWrite) # math completions completions = self.read_msg() dbg(urllib.unquote_plus(completions)) - start = '@@COMPLETIONS(' - self.assertTrue(completions.startswith(start), '%s DOESNT START WITH %s' % (completions, start)) - self.assertTrue(completions.find('@@COMPLETIONS') != -1) - self.assertTrue(completions.find('END@@') != -1) - - + start = "@@COMPLETIONS(" + self.assertTrue(completions.startswith(start), "%s DOESNT START WITH %s" % (completions, start)) + self.assertTrue(completions.find("@@COMPLETIONS") != -1) + self.assertTrue(completions.find("END@@") != -1) finally: try: self.send_kill_msg(socket) - while not t.ended: - pass #wait until it receives the message and quits. - + pass # wait until it receives the message and quits. socket.close() except: @@ -97,18 +93,20 @@ def test_completion_sockets_and_messages(self): def get_free_port(self): from _pydev_bundle.pydev_localhost import get_socket_name + return get_socket_name(close=True)[1] def create_connections(self): - ''' + """ Creates the connections needed for testing. - ''' + """ server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((pycompletionserver.HOST, 0)) - server.listen(1) #socket to receive messages. + server.listen(1) # socket to receive messages. from thread import start_new_thread + t = pycompletionserver.CompletionServer(server.getsockname()[1]) t.exit_process_on_kill = False @@ -119,13 +117,13 @@ def create_connections(self): return t, sock def read_msg(self): - msg = '@@PROCESSING_END@@' - while msg.startswith('@@PROCESSING'): + msg = "@@PROCESSING_END@@" + while msg.startswith("@@PROCESSING"): msg = self.socket.recv(1024) - if msg.startswith('@@PROCESSING:'): - dbg('Status msg:' + str(msg)) + if msg.startswith("@@PROCESSING:"): + dbg("Status msg:" + str(msg)) - while msg.find('END@@') == -1: + while msg.find("END@@") == -1: msg += self.socket.recv(1024) return msg @@ -134,7 +132,5 @@ def send_kill_msg(self, socket): socket.send(pycompletionserver.MSG_KILL_SERVER) - - # Run for jython in command line: # c:\bin\jython2.7.0\bin\jython.exe -m py.test tests\test_jyserver.py diff --git a/tests/test_jysimpleTipper.py b/tests/test_jysimpleTipper.py index a1790cf39..89c7e6df7 100644 --- a/tests/test_jysimpleTipper.py +++ b/tests/test_jysimpleTipper.py @@ -6,7 +6,7 @@ # Note: ant.jar and junit.jar must be in the PYTHONPATH (see jython_test_deps) IS_JYTHON = False -if sys.platform.find('java') != -1: +if sys.platform.find("java") != -1: IS_JYTHON = True from _pydev_bundle._pydev_jy_imports_tipper import ismethod from _pydev_bundle._pydev_jy_imports_tipper import isclass @@ -25,178 +25,178 @@ def dbg(s): if __DBG: - sys.stdout.write('%s\n' % (s,)) + sys.stdout.write("%s\n" % (s,)) -@pytest.mark.skipif(not IS_JYTHON, reason='Jython related test') +@pytest.mark.skipif(not IS_JYTHON, reason="Jython related test") class TestMod(unittest.TestCase): - def assert_args(self, tok, args, tips): for a in tips: if tok == a[0]: self.assertEqual(args, a[2]) return - raise AssertionError('%s not in %s', tok, tips) + raise AssertionError("%s not in %s", tok, tips) def assert_in(self, tok, tips): self.assertEqual(4, len(tips[0])) for a in tips: if tok == a[0]: return a - s = '' + s = "" for a in tips: s += str(a) - s += '\n' - raise AssertionError('%s not in %s' % (tok, s)) + s += "\n" + raise AssertionError("%s not in %s" % (tok, s)) def test_imports1a(self): - f, tip = _pydev_jy_imports_tipper.generate_tip('java.util.HashMap') + f, tip = _pydev_jy_imports_tipper.generate_tip("java.util.HashMap") if f is None: return # Not ok with java 9 - assert f.endswith('rt.jar') + assert f.endswith("rt.jar") def test_imports1c(self): - f, tip = _pydev_jy_imports_tipper.generate_tip('java.lang.Class') + f, tip = _pydev_jy_imports_tipper.generate_tip("java.lang.Class") if f is None: return # Not ok with java 9 - assert f.endswith('rt.jar') + assert f.endswith("rt.jar") def test_imports1b(self): try: - f, tip = _pydev_jy_imports_tipper.generate_tip('__builtin__.m') - self.fail('err') + f, tip = _pydev_jy_imports_tipper.generate_tip("__builtin__.m") + self.fail("err") except: pass def test_imports1(self): - f, tip = _pydev_jy_imports_tipper.generate_tip('junit.framework.TestCase') - assert f.endswith('junit.jar') - ret = self.assert_in('assertEquals', tip) -# self.assertEqual('', ret[2]) + f, tip = _pydev_jy_imports_tipper.generate_tip("junit.framework.TestCase") + assert f.endswith("junit.jar") + ret = self.assert_in("assertEquals", tip) + + # self.assertEqual('', ret[2]) def test_imports2(self): - f, tip = _pydev_jy_imports_tipper.generate_tip('junit.framework') - assert f.endswith('junit.jar') - ret = self.assert_in('TestCase', tip) - self.assertEqual('', ret[2]) + f, tip = _pydev_jy_imports_tipper.generate_tip("junit.framework") + assert f.endswith("junit.jar") + ret = self.assert_in("TestCase", tip) + self.assertEqual("", ret[2]) def test_imports2a(self): - f, tip = _pydev_jy_imports_tipper.generate_tip('org.apache.tools.ant') - assert f.endswith('ant.jar') - ret = self.assert_in('Task', tip) - self.assertEqual('', ret[2]) + f, tip = _pydev_jy_imports_tipper.generate_tip("org.apache.tools.ant") + assert f.endswith("ant.jar") + ret = self.assert_in("Task", tip) + self.assertEqual("", ret[2]) def test_imports3(self): - f, tip = _pydev_jy_imports_tipper.generate_tip('os') - assert f.endswith('os.py') - ret = self.assert_in('path', tip) - self.assertEqual('', ret[2]) + f, tip = _pydev_jy_imports_tipper.generate_tip("os") + assert f.endswith("os.py") + ret = self.assert_in("path", tip) + self.assertEqual("", ret[2]) def test_tip_on_string(self): - f, tip = _pydev_jy_imports_tipper.generate_tip('string') - self.assert_in('join', tip) - self.assert_in('uppercase', tip) + f, tip = _pydev_jy_imports_tipper.generate_tip("string") + self.assert_in("join", tip) + self.assert_in("uppercase", tip) def test_imports(self): - tip = _pydev_jy_imports_tipper.generate_tip('__builtin__')[1] - self.assert_in('tuple' , tip) - self.assert_in('RuntimeError' , tip) - self.assert_in('RuntimeWarning' , tip) + tip = _pydev_jy_imports_tipper.generate_tip("__builtin__")[1] + self.assert_in("tuple", tip) + self.assert_in("RuntimeError", tip) + self.assert_in("RuntimeWarning", tip) def test_imports5(self): - f, tip = _pydev_jy_imports_tipper.generate_tip('java.lang') + f, tip = _pydev_jy_imports_tipper.generate_tip("java.lang") if f is None: return # Not ok with java 9 - assert f.endswith('rt.jar') - tup = self.assert_in('String' , tip) + assert f.endswith("rt.jar") + tup = self.assert_in("String", tip) self.assertEqual(str(_pydev_jy_imports_tipper.TYPE_CLASS), tup[3]) - tip = _pydev_jy_imports_tipper.generate_tip('java')[1] - tup = self.assert_in('lang' , tip) + tip = _pydev_jy_imports_tipper.generate_tip("java")[1] + tup = self.assert_in("lang", tip) self.assertEqual(str(_pydev_jy_imports_tipper.TYPE_IMPORT), tup[3]) - tip = _pydev_jy_imports_tipper.generate_tip('java.lang.String')[1] - tup = self.assert_in('indexOf' , tip) + tip = _pydev_jy_imports_tipper.generate_tip("java.lang.String")[1] + tup = self.assert_in("indexOf", tip) self.assertEqual(str(_pydev_jy_imports_tipper.TYPE_FUNCTION), tup[3]) - tip = _pydev_jy_imports_tipper.generate_tip('java.lang.String')[1] - tup = self.assert_in('charAt' , tip) + tip = _pydev_jy_imports_tipper.generate_tip("java.lang.String")[1] + tup = self.assert_in("charAt", tip) self.assertEqual(str(_pydev_jy_imports_tipper.TYPE_FUNCTION), tup[3]) - self.assertEqual('(int)', tup[2]) + self.assertEqual("(int)", tup[2]) - tup = self.assert_in('format' , tip) + tup = self.assert_in("format", tip) self.assertEqual(str(_pydev_jy_imports_tipper.TYPE_FUNCTION), tup[3]) - self.assertEqual('(string, objectArray)', tup[2]) - self.assertTrue(tup[1].find('[Ljava.lang.Object;') == -1) + self.assertEqual("(string, objectArray)", tup[2]) + self.assertTrue(tup[1].find("[Ljava.lang.Object;") == -1) - tup = self.assert_in('getBytes', tip) + tup = self.assert_in("getBytes", tip) self.assertEqual(str(_pydev_jy_imports_tipper.TYPE_FUNCTION), tup[3]) - assert '[B' not in tup[1] - assert 'byte[]' in tup[1] + assert "[B" not in tup[1] + assert "byte[]" in tup[1] - f, tip = _pydev_jy_imports_tipper.generate_tip('__builtin__.str') - assert f is None or f.endswith('jython.jar') # Depends on jython version - self.assert_in('find' , tip) + f, tip = _pydev_jy_imports_tipper.generate_tip("__builtin__.str") + assert f is None or f.endswith("jython.jar") # Depends on jython version + self.assert_in("find", tip) - f, tip = _pydev_jy_imports_tipper.generate_tip('__builtin__.dict') - assert f is None or f.endswith('jython.jar') # Depends on jython version - self.assert_in('get' , tip) + f, tip = _pydev_jy_imports_tipper.generate_tip("__builtin__.dict") + assert f is None or f.endswith("jython.jar") # Depends on jython version + self.assert_in("get", tip) -@pytest.mark.skipif(not IS_JYTHON, reason='Jython related test') +@pytest.mark.skipif(not IS_JYTHON, reason="Jython related test") class TestSearch(unittest.TestCase): - def test_search_on_jython(self): - assert _pydev_jy_imports_tipper.search_definition('os')[0][0].split(os.sep)[-1] in ('javaos.py', 'os.py') - self.assertEqual(0, _pydev_jy_imports_tipper.search_definition('os')[0][1]) + assert _pydev_jy_imports_tipper.search_definition("os")[0][0].split(os.sep)[-1] in ("javaos.py", "os.py") + self.assertEqual(0, _pydev_jy_imports_tipper.search_definition("os")[0][1]) - assert _pydev_jy_imports_tipper.search_definition('os.makedirs')[0][0].split(os.sep)[-1] in ('javaos.py', 'os.py') - self.assertNotEqual(0, _pydev_jy_imports_tipper.search_definition('os.makedirs')[0][1]) + assert _pydev_jy_imports_tipper.search_definition("os.makedirs")[0][0].split(os.sep)[-1] in ("javaos.py", "os.py") + self.assertNotEqual(0, _pydev_jy_imports_tipper.search_definition("os.makedirs")[0][1]) # print _pydev_jy_imports_tipper.search_definition('os.makedirs') -@pytest.mark.skipif(not IS_JYTHON, reason='Jython related test') +@pytest.mark.skipif(not IS_JYTHON, reason="Jython related test") class TestCompl(unittest.TestCase): - def test_getting_info_on_jython(self): - - dbg('\n\n--------------------------- java') + dbg("\n\n--------------------------- java") assert not ismethod(java)[0] assert not isclass(java) assert _pydev_jy_imports_tipper.ismodule(java) - dbg('\n\n--------------------------- java.lang') + dbg("\n\n--------------------------- java.lang") assert not ismethod(java.lang)[0] assert not isclass(java.lang) assert _pydev_jy_imports_tipper.ismodule(java.lang) - dbg('\n\n--------------------------- Method') + dbg("\n\n--------------------------- Method") assert not ismethod(Method)[0] assert isclass(Method) - dbg('\n\n--------------------------- System') + dbg("\n\n--------------------------- System") assert not ismethod(System)[0] assert isclass(System) - dbg('\n\n--------------------------- String') + dbg("\n\n--------------------------- String") assert not ismethod(System)[0] assert isclass(String) assert len(dir_obj(String)) > 10 - dbg('\n\n--------------------------- arraycopy') + dbg("\n\n--------------------------- arraycopy") isMet = ismethod(arraycopy) assert isMet[0] - assert isMet[1][0].basic_as_str() == "function:arraycopy args=['java.lang.Object', 'int', 'java.lang.Object', 'int', 'int'], varargs=None, kwargs=None, docs:None" + assert ( + isMet[1][0].basic_as_str() + == "function:arraycopy args=['java.lang.Object', 'int', 'java.lang.Object', 'int', 'int'], varargs=None, kwargs=None, docs:None" + ) assert not isclass(arraycopy) - dbg('\n\n--------------------------- out') + dbg("\n\n--------------------------- out") isMet = ismethod(out) assert not isMet[0] assert not isclass(out) - dbg('\n\n--------------------------- out.println') + dbg("\n\n--------------------------- out.println") isMet = ismethod(out.println) # @UndefinedVariable assert isMet[0] assert len(isMet[1]) == 10 @@ -204,7 +204,7 @@ def test_getting_info_on_jython(self): assert isMet[1][1].basic_as_str() == "function:println args=['long'], varargs=None, kwargs=None, docs:None" assert not isclass(out.println) # @UndefinedVariable - dbg('\n\n--------------------------- str') + dbg("\n\n--------------------------- str") isMet = ismethod(str) # the code below should work, but is failing on jython 22a1 # assert isMet[0] @@ -215,24 +215,25 @@ def met1(): a = 3 return a - dbg('\n\n--------------------------- met1') + dbg("\n\n--------------------------- met1") isMet = ismethod(met1) assert isMet[0] assert isMet[1][0].basic_as_str() == "function:met1 args=[], varargs=None, kwargs=None, docs:None" assert not isclass(met1) def met2(arg1, arg2, *vararg, **kwarg): - '''docmet2''' + """docmet2""" a = 1 return a - dbg('\n\n--------------------------- met2') + dbg("\n\n--------------------------- met2") isMet = ismethod(met2) assert isMet[0] assert isMet[1][0].basic_as_str() == "function:met2 args=['arg1', 'arg2'], varargs=vararg, kwargs=kwarg, docs:docmet2" assert not isclass(met2) + # Run for jython in command line: # On Windows: diff --git a/tests/test_pydev_ipython_011.py b/tests/test_pydev_ipython_011.py index 030dc4a9d..8e415511c 100644 --- a/tests/test_pydev_ipython_011.py +++ b/tests/test_pydev_ipython_011.py @@ -13,19 +13,19 @@ def eq_(a, b): if a != b: - raise AssertionError('%s != %s' % (a, b)) + raise AssertionError("%s != %s" % (a, b)) try: from IPython import core + has_ipython = True except: has_ipython = False -@pytest.mark.skipif(not has_ipython, reason='IPython not available') +@pytest.mark.skipif(not has_ipython, reason="IPython not available") class TestBase(unittest.TestCase): - def setUp(self): from _pydev_bundle.pydev_ipython_console_011 import get_pydev_frontend @@ -35,7 +35,8 @@ def setUp(self): self.front_end = get_pydev_frontend(get_localhost(), 0) from pydev_ipython.inputhook import set_return_control_callback - set_return_control_callback(lambda:True) + + set_return_control_callback(lambda: True) self.front_end.clear_buffer() def tearDown(self): @@ -53,99 +54,98 @@ def redirect_stdout(self): def restore_stdout(self): from IPython.utils import io + io.stdout = sys.stdout = self.original_stdout -@pytest.mark.skipif(not has_ipython, reason='IPython not available') +@pytest.mark.skipif(not has_ipython, reason="IPython not available") class TestPyDevFrontEnd(TestBase): - def testAddExec_1(self): - self.add_exec('if True:', True) + self.add_exec("if True:", True) def testAddExec_2(self): # Change: 'more' must now be controlled in the client side after the initial 'True' returned. - self.add_exec('if True:\n testAddExec_a = 10\n', False) - assert 'testAddExec_a' in self.front_end.get_namespace() + self.add_exec("if True:\n testAddExec_a = 10\n", False) + assert "testAddExec_a" in self.front_end.get_namespace() def testAddExec_3(self): - assert 'testAddExec_x' not in self.front_end.get_namespace() - self.add_exec('if True:\n testAddExec_x = 10\n\n') - assert 'testAddExec_x' in self.front_end.get_namespace() - eq_(self.front_end.get_namespace()['testAddExec_x'], 10) + assert "testAddExec_x" not in self.front_end.get_namespace() + self.add_exec("if True:\n testAddExec_x = 10\n\n") + assert "testAddExec_x" in self.front_end.get_namespace() + eq_(self.front_end.get_namespace()["testAddExec_x"], 10) def test_get_namespace(self): - assert 'testGetNamespace_a' not in self.front_end.get_namespace() - self.add_exec('testGetNamespace_a = 10') - assert 'testGetNamespace_a' in self.front_end.get_namespace() - eq_(self.front_end.get_namespace()['testGetNamespace_a'], 10) + assert "testGetNamespace_a" not in self.front_end.get_namespace() + self.add_exec("testGetNamespace_a = 10") + assert "testGetNamespace_a" in self.front_end.get_namespace() + eq_(self.front_end.get_namespace()["testGetNamespace_a"], 10) def test_complete(self): - unused_text, matches = self.front_end.complete('%') - assert len(matches) > 1, 'at least one magic should appear in completions' + unused_text, matches = self.front_end.complete("%") + assert len(matches) > 1, "at least one magic should appear in completions" def test_complete_does_not_do_python_matches(self): # Test that IPython's completions do not do the things that # PyDev's completions will handle - self.add_exec('testComplete_a = 5') - self.add_exec('testComplete_b = 10') - self.add_exec('testComplete_c = 15') - unused_text, matches = self.front_end.complete('testComplete_') + self.add_exec("testComplete_a = 5") + self.add_exec("testComplete_b = 10") + self.add_exec("testComplete_c = 15") + unused_text, matches = self.front_end.complete("testComplete_") assert len(matches) == 0 def testGetCompletions_1(self): # Test the merged completions include the standard completions - self.add_exec('testComplete_a = 5') - self.add_exec('testComplete_b = 10') - self.add_exec('testComplete_c = 15') - res = self.front_end.getCompletions('testComplete_', 'testComplete_') + self.add_exec("testComplete_a = 5") + self.add_exec("testComplete_b = 10") + self.add_exec("testComplete_c = 15") + res = self.front_end.getCompletions("testComplete_", "testComplete_") matches = [f[0] for f in res] assert len(matches) == 3 - eq_(set(['testComplete_a', 'testComplete_b', 'testComplete_c']), set(matches)) + eq_(set(["testComplete_a", "testComplete_b", "testComplete_c"]), set(matches)) def testGetCompletions_2(self): # Test that we get IPython completions in results # we do this by checking kw completion which PyDev does # not do by default - self.add_exec('def ccc(ABC=123): pass') - res = self.front_end.getCompletions('ccc(', '') + self.add_exec("def ccc(ABC=123): pass") + res = self.front_end.getCompletions("ccc(", "") matches = [f[0] for f in res] - assert 'ABC=' in matches + assert "ABC=" in matches def testGetCompletions_3(self): # Test that magics return IPYTHON magic as type - res = self.front_end.getCompletions('%cd', '%cd') + res = self.front_end.getCompletions("%cd", "%cd") assert len(res) == 1 - eq_(res[0][3], '12') # '12' == IToken.TYPE_IPYTHON_MAGIC - assert len(res[0][1]) > 100, 'docstring for %cd should be a reasonably long string' + eq_(res[0][3], "12") # '12' == IToken.TYPE_IPYTHON_MAGIC + assert len(res[0][1]) > 100, "docstring for %cd should be a reasonably long string" -@pytest.mark.skipif(not has_ipython, reason='IPython not available') +@pytest.mark.skipif(not has_ipython, reason="IPython not available") class TestRunningCode(TestBase): - def test_print(self): self.redirect_stdout() try: self.add_exec('print("output")') - eq_(sys.stdout.getvalue(), 'output\n') + eq_(sys.stdout.getvalue(), "output\n") finally: self.restore_stdout() def testQuestionMark_1(self): self.redirect_stdout() try: - self.add_exec('?') + self.add_exec("?") found = sys.stdout.getvalue() if len(found) < 1000: - raise AssertionError('Expected IPython help to be big. Found: %s' % (found,)) + raise AssertionError("Expected IPython help to be big. Found: %s" % (found,)) finally: self.restore_stdout() def testQuestionMark_2(self): self.redirect_stdout() try: - self.add_exec('int?') + self.add_exec("int?") found = sys.stdout.getvalue() - if 'Convert' not in found: + if "Convert" not in found: raise AssertionError('Expected to find "Convert" in %s' % (found,)) finally: self.restore_stdout() @@ -157,36 +157,37 @@ def test_gui(self): return else: from pydev_ipython.inputhook import get_inputhook + assert get_inputhook() is None - self.add_exec('%gui tk') + self.add_exec("%gui tk") # we can't test the GUI works here because we aren't connected to XML-RPC so # nowhere for hook to run assert get_inputhook() is not None - self.add_exec('%gui none') + self.add_exec("%gui none") assert get_inputhook() is None def test_history(self): - ''' Make sure commands are added to IPython's history ''' + """Make sure commands are added to IPython's history""" self.redirect_stdout() try: - self.add_exec('a=1') - self.add_exec('b=2') - _ih = self.front_end.get_namespace()['_ih'] - eq_(_ih[-1], 'b=2') - eq_(_ih[-2], 'a=1') - - self.add_exec('history') - hist = sys.stdout.getvalue().split('\n') - eq_(hist[-1], '') - eq_(hist[-2], 'history') - eq_(hist[-3], 'b=2') - eq_(hist[-4], 'a=1') + self.add_exec("a=1") + self.add_exec("b=2") + _ih = self.front_end.get_namespace()["_ih"] + eq_(_ih[-1], "b=2") + eq_(_ih[-2], "a=1") + + self.add_exec("history") + hist = sys.stdout.getvalue().split("\n") + eq_(hist[-1], "") + eq_(hist[-2], "history") + eq_(hist[-3], "b=2") + eq_(hist[-4], "a=1") finally: self.restore_stdout() def test_edit(self): - ''' Make sure we can issue an edit command''' - if os.environ.get('TRAVIS') == 'true': + """Make sure we can issue an edit command""" + if os.environ.get("TRAVIS") == "true": # This test is too flaky on travis. return @@ -196,20 +197,16 @@ def test_edit(self): called_IPythonEditor = [False] def start_client_thread(client_port): - class ClientThread(threading.Thread): - def __init__(self, client_port): threading.Thread.__init__(self) self.client_port = client_port def run(self): - class HandleRequestInput: - def RequestInput(self): called_RequestInput[0] = True - return '\n' + return "\n" def IPythonEditor(self, name, line): called_IPythonEditor[0] = (name, line) @@ -218,8 +215,10 @@ def IPythonEditor(self, name, line): handle_request_input = HandleRequestInput() from _pydev_bundle import pydev_localhost + self.client_server = client_server = SimpleXMLRPCServer( - (pydev_localhost.get_localhost(), self.client_port), logRequests=False) + (pydev_localhost.get_localhost(), self.client_port), logRequests=False + ) client_server.register_function(handle_request_input.RequestInput) client_server.register_function(handle_request_input.IPythonEditor) client_server.serve_forever() @@ -237,7 +236,7 @@ def shutdown(self): # can't make multiple versions. So we reuse self.front_end for # all the tests s = socket.socket() - s.bind(('', 0)) + s.bind(("", 0)) self.client_port = client_port = s.getsockname()[1] s.close() self.front_end = get_pydev_frontend(get_localhost(), client_port) @@ -246,13 +245,13 @@ def shutdown(self): orig_stdin = sys.stdin sys.stdin = StdIn(self, get_localhost(), self.client_port) try: - filename = 'made_up_file.py' - self.add_exec('%edit ' + filename) + filename = "made_up_file.py" + self.add_exec("%edit " + filename) for i in range(10): - if called_IPythonEditor[0] == (os.path.abspath(filename), '0'): + if called_IPythonEditor[0] == (os.path.abspath(filename), "0"): break - time.sleep(.1) + time.sleep(0.1) if not called_IPythonEditor[0]: # File "/home/travis/miniconda/lib/python3.3/site-packages/IPython/core/interactiveshell.py", line 2883, in run_code @@ -297,12 +296,13 @@ def shutdown(self): # ConnectionRefusedError: [Errno 111] Connection refused # I.e.: just warn that the test failing, don't actually fail. - sys.stderr.write('Test failed: this test is brittle in travis because sometimes the connection is refused (as above) and we do not have a callback.\n') + sys.stderr.write( + "Test failed: this test is brittle in travis because sometimes the connection is refused (as above) and we do not have a callback.\n" + ) return - eq_(called_IPythonEditor[0], (os.path.abspath(filename), '0')) + eq_(called_IPythonEditor[0], (os.path.abspath(filename), "0")) assert called_RequestInput[0], "Make sure the 'wait' parameter has been respected" finally: sys.stdin = orig_stdin client_thread.shutdown() - diff --git a/tests/test_pydevconsole.py b/tests/test_pydevconsole.py index bbfc16efd..ef0c31f53 100644 --- a/tests/test_pydevconsole.py +++ b/tests/test_pydevconsole.py @@ -9,16 +9,16 @@ try: from ast import PyCF_ALLOW_TOP_LEVEL_AWAIT # @UnusedImport + CAN_EVALUATE_TOP_LEVEL_ASYNC = True except: CAN_EVALUATE_TOP_LEVEL_ASYNC = False -#======================================================================================================================= +# ======================================================================================================================= # Test -#======================================================================================================================= +# ======================================================================================================================= class Test(unittest.TestCase): - @contextmanager def interpreter(self): self.original_stdout = sys.stdout @@ -36,9 +36,11 @@ def interpreter(self): client_port, _server_port = self.get_free_addresses() client_thread = self.start_client_thread(client_port) # @UnusedVariable import time - time.sleep(.3) # let's give it some time to start the threads + + time.sleep(0.3) # let's give it some time to start the threads from _pydev_bundle import pydev_localhost + interpreter = pydevconsole.InterpreterInterface(pydev_localhost.get_localhost(), client_port, threading.current_thread()) yield interpreter except: @@ -55,121 +57,123 @@ def test_console_hello(self): (result,) = interpreter.hello("Hello pydevconsole") self.assertEqual(result, "Hello eclipse") - @pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason='Requires top-level async.') + @pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason="Requires top-level async.") def test_console_async(self): with self.interpreter() as interpreter: from _pydev_bundle.pydev_console_utils import CodeFragment - more = interpreter.add_exec(CodeFragment(''' + + more = interpreter.add_exec( + CodeFragment( + """ async def async_func(a): return a -''')) +""" + ) + ) assert not more assert not sys.stderr.getvalue() assert not sys.stdout.getvalue() - more = interpreter.add_exec(CodeFragment('''x = await async_func(1111)''')) + more = interpreter.add_exec(CodeFragment("""x = await async_func(1111)""")) assert not more assert not sys.stderr.getvalue() assert not sys.stdout.getvalue() - more = interpreter.add_exec(CodeFragment('''print(x)''')) + more = interpreter.add_exec(CodeFragment("""print(x)""")) assert not more assert not sys.stderr.getvalue() - assert '1111' in sys.stdout.getvalue() + assert "1111" in sys.stdout.getvalue() def test_console_requests(self): with self.interpreter() as interpreter: from _pydev_bundle.pydev_console_utils import CodeFragment - interpreter.add_exec(CodeFragment('class Foo:\n CONSTANT=1\n')) - interpreter.add_exec(CodeFragment('foo=Foo()')) - interpreter.add_exec(CodeFragment('foo.__doc__=None')) - interpreter.add_exec(CodeFragment('val = input()')) - interpreter.add_exec(CodeFragment('50')) - interpreter.add_exec(CodeFragment('print (val)')) + + interpreter.add_exec(CodeFragment("class Foo:\n CONSTANT=1\n")) + interpreter.add_exec(CodeFragment("foo=Foo()")) + interpreter.add_exec(CodeFragment("foo.__doc__=None")) + interpreter.add_exec(CodeFragment("val = input()")) + interpreter.add_exec(CodeFragment("50")) + interpreter.add_exec(CodeFragment("print (val)")) found = sys.stdout.getvalue().split() try: - self.assertEqual(['50', 'input_request'], found) + self.assertEqual(["50", "input_request"], found) except: try: - self.assertEqual(['input_request'], found) # IPython + self.assertEqual(["input_request"], found) # IPython except: - self.assertEqual([u'50', u'input_request'], found[1:]) # IPython 5.1 - self.assertTrue(found[0].startswith(u'Out')) + self.assertEqual(["50", "input_request"], found[1:]) # IPython 5.1 + self.assertTrue(found[0].startswith("Out")) - comps = interpreter.getCompletions('foo.', 'foo.') - self.assertTrue( - ('CONSTANT', '', '', '3') in comps or ('CONSTANT', '', '', '4') in comps, \ - 'Found: %s' % comps - ) + comps = interpreter.getCompletions("foo.", "foo.") + self.assertTrue(("CONSTANT", "", "", "3") in comps or ("CONSTANT", "", "", "4") in comps, "Found: %s" % comps) comps = interpreter.getCompletions('"".', '"".') self.assertTrue( - ('__add__', 'x.__add__(y) <==> x+y', '', '3') in comps or - ('__add__', '', '', '4') in comps or - ('__add__', 'x.__add__(y) <==> x+y\r\nx.__add__(y) <==> x+y', '()', '2') in comps or - ('__add__', 'x.\n__add__(y) <==> x+yx.\n__add__(y) <==> x+y', '()', '2'), - 'Did not find __add__ in : %s' % (comps,) + ("__add__", "x.__add__(y) <==> x+y", "", "3") in comps + or ("__add__", "", "", "4") in comps + or ("__add__", "x.__add__(y) <==> x+y\r\nx.__add__(y) <==> x+y", "()", "2") in comps + or ("__add__", "x.\n__add__(y) <==> x+yx.\n__add__(y) <==> x+y", "()", "2"), + "Did not find __add__ in : %s" % (comps,), ) - completions = interpreter.getCompletions('', '') + completions = interpreter.getCompletions("", "") for c in completions: - if c[0] == 'AssertionError': + if c[0] == "AssertionError": break else: - self.fail('Could not find AssertionError') + self.fail("Could not find AssertionError") - completions = interpreter.getCompletions('Assert', 'Assert') + completions = interpreter.getCompletions("Assert", "Assert") for c in completions: - if c[0] == 'RuntimeError': - self.fail('Did not expect to find RuntimeError there') + if c[0] == "RuntimeError": + self.fail("Did not expect to find RuntimeError there") - assert ('__doc__', None, '', '3') not in interpreter.getCompletions('foo.CO', 'foo.') + assert ("__doc__", None, "", "3") not in interpreter.getCompletions("foo.CO", "foo.") - comps = interpreter.getCompletions('va', 'va') - assert ('val', '', '', '3') in comps or ('val', '', '', '4') in comps + comps = interpreter.getCompletions("va", "va") + assert ("val", "", "", "3") in comps or ("val", "", "", "4") in comps interpreter.add_exec(CodeFragment('s = "mystring"')) - desc = interpreter.getDescription('val') - self.assertTrue(desc.find('str(object) -> string') >= 0 or - desc == "'input_request'" or - desc.find('str(string[, encoding[, errors]]) -> str') >= 0 or - desc.find('str(Char* value)') >= 0 or - desc.find('str(object=\'\') -> string') >= 0 or - desc.find('str(value: Char*)') >= 0 or - desc.find('str(object=\'\') -> str') >= 0 or - desc.find('The most base type') >= 0 # Jython 2.7 is providing this :P - , - 'Could not find what was needed in %s' % desc) - - desc = interpreter.getDescription('val.join') - self.assertTrue(desc.find('S.join(sequence) -> string') >= 0 or - desc.find('S.join(sequence) -> str') >= 0 or - desc.find('S.join(iterable) -> string') >= 0 or - desc == "" or - desc == "" or - desc.find('str join(str self, list sequence)') >= 0 or - desc.find('S.join(iterable) -> str') >= 0 or - desc.find('join(self: str, sequence: list) -> str') >= 0 or - desc.find('Concatenate any number of strings.') >= 0 or - desc.find('bound method str.join') >= 0, # PyPy - "Could not recognize: %s" % (desc,)) + desc = interpreter.getDescription("val") + self.assertTrue( + desc.find("str(object) -> string") >= 0 + or desc == "'input_request'" + or desc.find("str(string[, encoding[, errors]]) -> str") >= 0 + or desc.find("str(Char* value)") >= 0 + or desc.find("str(object='') -> string") >= 0 + or desc.find("str(value: Char*)") >= 0 + or desc.find("str(object='') -> str") >= 0 + or desc.find("The most base type") >= 0, # Jython 2.7 is providing this :P + "Could not find what was needed in %s" % desc, + ) - def start_client_thread(self, client_port): + desc = interpreter.getDescription("val.join") + self.assertTrue( + desc.find("S.join(sequence) -> string") >= 0 + or desc.find("S.join(sequence) -> str") >= 0 + or desc.find("S.join(iterable) -> string") >= 0 + or desc == "" + or desc == "" + or desc.find("str join(str self, list sequence)") >= 0 + or desc.find("S.join(iterable) -> str") >= 0 + or desc.find("join(self: str, sequence: list) -> str") >= 0 + or desc.find("Concatenate any number of strings.") >= 0 + or desc.find("bound method str.join") >= 0, # PyPy + "Could not recognize: %s" % (desc,), + ) + def start_client_thread(self, client_port): class ClientThread(threading.Thread): - def __init__(self, client_port): threading.Thread.__init__(self) self.client_port = client_port def run(self): - class HandleRequestInput: - def RequestInput(self): client_thread.requested_input = True - return 'input_request' + return "input_request" def NotifyFinished(self, *args, **kwargs): client_thread.notified_finished += 1 @@ -178,6 +182,7 @@ def NotifyFinished(self, *args, **kwargs): handle_request_input = HandleRequestInput() from _pydev_bundle import pydev_localhost + client_server = SimpleXMLRPCServer((pydev_localhost.get_localhost(), self.client_port), logRequests=False) client_server.register_function(handle_request_input.RequestInput) client_server.register_function(handle_request_input.NotifyFinished) @@ -191,9 +196,7 @@ def NotifyFinished(self, *args, **kwargs): return client_thread def start_debugger_server_thread(self, debugger_port, socket_code): - class DebuggerServerThread(threading.Thread): - def __init__(self, debugger_port, socket_code): threading.Thread.__init__(self) self.debugger_port = debugger_port @@ -201,8 +204,9 @@ def __init__(self, debugger_port, socket_code): def run(self): import socket + s = socket.socket() - s.bind(('', debugger_port)) + s.bind(("", debugger_port)) s.listen(1) socket, unused_addr = s.accept() socket_code(socket) @@ -214,6 +218,7 @@ def run(self): def get_free_addresses(self): from _pydev_bundle.pydev_localhost import get_socket_names + socket_names = get_socket_names(2, True) port0 = socket_names[0][1] port1 = socket_names[1][1] @@ -231,7 +236,6 @@ def test_server(self): client_port, server_port = self.get_free_addresses() class ServerThread(threading.Thread): - def __init__(self, client_port, server_port): threading.Thread.__init__(self) self.client_port = client_port @@ -239,6 +243,7 @@ def __init__(self, client_port, server_port): def run(self): from _pydev_bundle import pydev_localhost + pydevconsole.start_server(pydev_localhost.get_localhost(), self.server_port, self.client_port) server_thread = ServerThread(client_port, server_port) @@ -248,30 +253,31 @@ def run(self): client_thread = self.start_client_thread(client_port) # @UnusedVariable import time - time.sleep(.3) # let's give it some time to start the threads + + time.sleep(0.3) # let's give it some time to start the threads sys.stdout = pydevd_io.IOBuf() from _pydev_bundle import pydev_localhost - server = xmlrpclib.Server('http://%s:%s' % (pydev_localhost.get_localhost(), server_port)) - server.execLine('class Foo:') - server.execLine(' pass') - server.execLine('') - server.execLine('foo = Foo()') - server.execLine('a = input()') - server.execLine('print (a)') + + server = xmlrpclib.Server("http://%s:%s" % (pydev_localhost.get_localhost(), server_port)) + server.execLine("class Foo:") + server.execLine(" pass") + server.execLine("") + server.execLine("foo = Foo()") + server.execLine("a = input()") + server.execLine("print (a)") initial = time.time() while not client_thread.requested_input: if time.time() - initial > 2: - raise AssertionError('Did not get the return asked before the timeout.') - time.sleep(.1) + raise AssertionError("Did not get the return asked before the timeout.") + time.sleep(0.1) found = sys.stdout.getvalue() - while ['input_request'] != found.split(): + while ["input_request"] != found.split(): found += sys.stdout.getvalue() if time.time() - initial > 2: break - time.sleep(.1) - self.assertEqual(['input_request'], found.split()) + time.sleep(0.1) + self.assertEqual(["input_request"], found.split()) finally: sys.stdout = self.original_stdout - diff --git a/tests/test_pyserver.py b/tests/test_pyserver.py index de766d43f..fa1696920 100644 --- a/tests/test_pyserver.py +++ b/tests/test_pyserver.py @@ -6,40 +6,42 @@ start_new_thread = thread.start_new_thread -BUILTIN_MOD = 'builtins' +BUILTIN_MOD = "builtins" def send(s, msg): - s.send(bytearray(msg, 'utf-8')) + s.send(bytearray(msg, "utf-8")) import unittest class TestCPython(unittest.TestCase): - def test_message(self): t = pycompletionserver.CompletionServer(0) l = [] - l.append(('Def', 'description' , 'args')) - l.append(('Def1', 'description1', 'args1')) - l.append(('Def2', 'description2', 'args2')) + l.append(("Def", "description", "args")) + l.append(("Def1", "description1", "args1")) + l.append(("Def2", "description2", "args2")) msg = t.processor.format_completion_message(None, l) - self.assertEqual('@@COMPLETIONS(None,(Def,description,args),(Def1,description1,args1),(Def2,description2,args2))END@@', msg) + self.assertEqual("@@COMPLETIONS(None,(Def,description,args),(Def1,description1,args1),(Def2,description2,args2))END@@", msg) l = [] - l.append(('Def', 'desc,,r,,i()ption', '')) - l.append(('Def(1', 'descriptio(n1', '')) - l.append(('De,f)2', 'de,s,c,ription2', '')) + l.append(("Def", "desc,,r,,i()ption", "")) + l.append(("Def(1", "descriptio(n1", "")) + l.append(("De,f)2", "de,s,c,ription2", "")) msg = t.processor.format_completion_message(None, l) - self.assertEqual('@@COMPLETIONS(None,(Def,desc%2C%2Cr%2C%2Ci%28%29ption, ),(Def%281,descriptio%28n1, ),(De%2Cf%292,de%2Cs%2Cc%2Cription2, ))END@@', msg) + self.assertEqual( + "@@COMPLETIONS(None,(Def,desc%2C%2Cr%2C%2Ci%28%29ption, ),(Def%281,descriptio%28n1, ),(De%2Cf%292,de%2Cs%2Cc%2Cription2, ))END@@", + msg, + ) def create_connections(self): - ''' + """ Creates the connections needed for testing. - ''' + """ server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server.bind((pycompletionserver.HOST, 0)) @@ -55,16 +57,16 @@ def create_connections(self): def read_msg(self): finish = False - msg = '' + msg = "" while finish == False: m = self.socket.recv(1024 * 4) - m = m.decode('utf-8') - if m.startswith('@@PROCESSING'): - sys.stdout.write('Status msg: %s\n' % (msg,)) + m = m.decode("utf-8") + if m.startswith("@@PROCESSING"): + sys.stdout.write("Status msg: %s\n" % (msg,)) else: msg += m - if msg.find('END@@') != -1: + if msg.find("END@@") != -1: finish = True return msg @@ -75,76 +77,80 @@ def test_completion_sockets_and_messages(self): try: # now that we have the connections all set up, check the code completion messages. - msg = quote_plus('math') - send(socket, '@@IMPORTS:%sEND@@' % msg) # math completions + msg = quote_plus("math") + send(socket, "@@IMPORTS:%sEND@@" % msg) # math completions completions = self.read_msg() # print_ unquote_plus(completions) # math is a builtin and because of that, it starts with None as a file - start = '@@COMPLETIONS(None,(__doc__,' - start_2 = '@@COMPLETIONS(None,(__name__,' - if ('/math.so,' in completions or - '/math.cpython-33m.so,' in completions or - '/math.cpython-34m.so,' in completions or - 'math.cpython-35m' in completions or - 'math.cpython-36m' in completions or - 'math.cpython-37m' in completions or - 'math.cpython-38' in completions or - 'math.cpython-39' in completions or - 'math.cpython-310' in completions or - 'math.cpython-311' in completions or - 'math.cpython-312' in completions - ): + start = "@@COMPLETIONS(None,(__doc__," + start_2 = "@@COMPLETIONS(None,(__name__," + if ( + "/math.so," in completions + or "/math.cpython-33m.so," in completions + or "/math.cpython-34m.so," in completions + or "math.cpython-35m" in completions + or "math.cpython-36m" in completions + or "math.cpython-37m" in completions + or "math.cpython-38" in completions + or "math.cpython-39" in completions + or "math.cpython-310" in completions + or "math.cpython-311" in completions + or "math.cpython-312" in completions + ): return - self.assertTrue(completions.startswith(start) or completions.startswith(start_2), '%s DOESNT START WITH %s' % (completions, (start, start_2))) + self.assertTrue( + completions.startswith(start) or completions.startswith(start_2), + "%s DOESNT START WITH %s" % (completions, (start, start_2)), + ) - self.assertTrue('@@COMPLETIONS' in completions) - self.assertTrue('END@@' in completions) + self.assertTrue("@@COMPLETIONS" in completions) + self.assertTrue("END@@" in completions) # now, test i - msg = quote_plus('%s.list' % BUILTIN_MOD) + msg = quote_plus("%s.list" % BUILTIN_MOD) send(socket, "@@IMPORTS:%s\nEND@@" % msg) found = self.read_msg() - self.assertTrue('sort' in found, 'Could not find sort in: %s' % (found,)) + self.assertTrue("sort" in found, "Could not find sort in: %s" % (found,)) # now, test search - msg = quote_plus('inspect.ismodule') - send(socket, '@@SEARCH%sEND@@' % msg) # math completions + msg = quote_plus("inspect.ismodule") + send(socket, "@@SEARCH%sEND@@" % msg) # math completions found = self.read_msg() - self.assertTrue('inspect.py' in found) + self.assertTrue("inspect.py" in found) for i in range(33, 100): if str(i) in found: break else: - self.fail('Could not find the ismodule line in %s' % (found,)) + self.fail("Could not find the ismodule line in %s" % (found,)) # now, test search - msg = quote_plus('inspect.CO_NEWLOCALS') - send(socket, '@@SEARCH%sEND@@' % msg) # math completions + msg = quote_plus("inspect.CO_NEWLOCALS") + send(socket, "@@SEARCH%sEND@@" % msg) # math completions found = self.read_msg() - self.assertTrue('inspect.py' in found) - self.assertTrue('CO_NEWLOCALS' in found) + self.assertTrue("inspect.py" in found) + self.assertTrue("CO_NEWLOCALS" in found) # now, test search - msg = quote_plus('inspect.BlockFinder.tokeneater') - send(socket, '@@SEARCH%sEND@@' % msg) + msg = quote_plus("inspect.BlockFinder.tokeneater") + send(socket, "@@SEARCH%sEND@@" % msg) found = self.read_msg() - self.assertTrue('inspect.py' in found) -# self.assertTrue('CO_NEWLOCALS' in found) + self.assertTrue("inspect.py" in found) + # self.assertTrue('CO_NEWLOCALS' in found) # reload modules test -# send(socket, '@@RELOAD_MODULES_END@@') -# ok = self.read_msg() -# self.assertEqual('@@MSG_OK_END@@' , ok) -# this test is not executed because it breaks our current enviroment. + # send(socket, '@@RELOAD_MODULES_END@@') + # ok = self.read_msg() + # self.assertEqual('@@MSG_OK_END@@' , ok) + # this test is not executed because it breaks our current enviroment. finally: try: - sys.stdout.write('succedded...sending kill msg\n') + sys.stdout.write("succedded...sending kill msg\n") self.send_kill_msg(socket) -# while not hasattr(t, 'ended'): -# pass #wait until it receives the message and quits. + # while not hasattr(t, 'ended'): + # pass #wait until it receives the message and quits. socket.close() self.socket.close() @@ -153,4 +159,3 @@ def test_completion_sockets_and_messages(self): def send_kill_msg(self, socket): socket.send(pycompletionserver.MSG_KILL_SERVER) - diff --git a/tests/test_simpleTipper.py b/tests/test_simpleTipper.py index 5a152f868..5719a6346 100644 --- a/tests/test_simpleTipper.py +++ b/tests/test_simpleTipper.py @@ -1,6 +1,6 @@ -''' +""" @author Fabio Zadrozny -''' +""" from _pydev_bundle import _pydev_imports_tipper import inspect import pytest @@ -9,59 +9,59 @@ try: import __builtin__ # @UnusedImport - BUILTIN_MOD = '__builtin__' + + BUILTIN_MOD = "__builtin__" except ImportError: - BUILTIN_MOD = 'builtins' + BUILTIN_MOD = "builtins" -IS_JYTHON = sys.platform.find('java') != -1 +IS_JYTHON = sys.platform.find("java") != -1 HAS_WX = False -@pytest.mark.skipif(IS_JYTHON, reason='CPython related test') +@pytest.mark.skipif(IS_JYTHON, reason="CPython related test") class TestCPython(unittest.TestCase): - def p(self, t): for a in t: - sys.stdout.write('%s\n' % (a,)) + sys.stdout.write("%s\n" % (a,)) def test_imports3(self): - tip = _pydev_imports_tipper.generate_tip('os') - ret = self.assert_in('path', tip) - self.assertEqual('', ret[2]) + tip = _pydev_imports_tipper.generate_tip("os") + ret = self.assert_in("path", tip) + self.assertEqual("", ret[2]) def test_imports2(self): try: - tip = _pydev_imports_tipper.generate_tip('OpenGL.GLUT') - self.assert_in('glutDisplayFunc', tip) - self.assert_in('glutInitDisplayMode', tip) + tip = _pydev_imports_tipper.generate_tip("OpenGL.GLUT") + self.assert_in("glutDisplayFunc", tip) + self.assert_in("glutInitDisplayMode", tip) except ImportError: pass def test_imports4(self): try: - tip = _pydev_imports_tipper.generate_tip('mx.DateTime.mxDateTime.mxDateTime') - self.assert_in('now', tip) + tip = _pydev_imports_tipper.generate_tip("mx.DateTime.mxDateTime.mxDateTime") + self.assert_in("now", tip) except ImportError: pass def test_imports5(self): - tip = _pydev_imports_tipper.generate_tip('%s.list' % BUILTIN_MOD) - s = self.assert_in('sort', tip) + tip = _pydev_imports_tipper.generate_tip("%s.list" % BUILTIN_MOD) + s = self.assert_in("sort", tip) self.check_args( s, - '(cmp=None, key=None, reverse=False)', - '(self, object cmp, object key, bool reverse)', - '(self, cmp: object, key: object, reverse: bool)', - '(key=None, reverse=False)', - '(self, key=None, reverse=False)', - '(self, cmp, key, reverse)', - '(self, key, reverse)', + "(cmp=None, key=None, reverse=False)", + "(self, object cmp, object key, bool reverse)", + "(self, cmp: object, key: object, reverse: bool)", + "(key=None, reverse=False)", + "(self, key=None, reverse=False)", + "(self, cmp, key, reverse)", + "(self, key, reverse)", ) def test_imports2a(self): - tips = _pydev_imports_tipper.generate_tip('%s.RuntimeError' % BUILTIN_MOD) - self.assert_in('__doc__', tips) + tips = _pydev_imports_tipper.generate_tip("%s.RuntimeError" % BUILTIN_MOD) + self.assert_in("__doc__", tips) def test_imports2b(self): try: @@ -69,9 +69,9 @@ def test_imports2b(self): except: pass else: - tips = _pydev_imports_tipper.generate_tip('%s' % BUILTIN_MOD) - t = self.assert_in('file' , tips) - self.assertTrue('->' in t[1].strip() or 'file' in t[1]) + tips = _pydev_imports_tipper.generate_tip("%s" % BUILTIN_MOD) + t = self.assert_in("file", tips) + self.assertTrue("->" in t[1].strip() or "file" in t[1]) def test_imports2c(self): try: @@ -79,113 +79,113 @@ def test_imports2c(self): except: pass else: - tips = _pydev_imports_tipper.generate_tip('%s.file' % BUILTIN_MOD) - t = self.assert_in('readlines' , tips) - self.assertTrue('->' in t[1] or 'sizehint' in t[1]) + tips = _pydev_imports_tipper.generate_tip("%s.file" % BUILTIN_MOD) + t = self.assert_in("readlines", tips) + self.assertTrue("->" in t[1] or "sizehint" in t[1]) def test_imports(self): - ''' + """ You can print_ the results to check... - ''' + """ if HAS_WX: - tip = _pydev_imports_tipper.generate_tip('wxPython.wx') - self.assert_in('wxApp' , tip) + tip = _pydev_imports_tipper.generate_tip("wxPython.wx") + self.assert_in("wxApp", tip) - tip = _pydev_imports_tipper.generate_tip('wxPython.wx.wxApp') + tip = _pydev_imports_tipper.generate_tip("wxPython.wx.wxApp") try: - tip = _pydev_imports_tipper.generate_tip('qt') - self.assert_in('QWidget' , tip) - self.assert_in('QDialog' , tip) + tip = _pydev_imports_tipper.generate_tip("qt") + self.assert_in("QWidget", tip) + self.assert_in("QDialog", tip) - tip = _pydev_imports_tipper.generate_tip('qt.QWidget') - self.assert_in('rect' , tip) - self.assert_in('rect' , tip) - self.assert_in('AltButton' , tip) + tip = _pydev_imports_tipper.generate_tip("qt.QWidget") + self.assert_in("rect", tip) + self.assert_in("rect", tip) + self.assert_in("AltButton", tip) - tip = _pydev_imports_tipper.generate_tip('qt.QWidget.AltButton') - self.assert_in('__xor__' , tip) + tip = _pydev_imports_tipper.generate_tip("qt.QWidget.AltButton") + self.assert_in("__xor__", tip) - tip = _pydev_imports_tipper.generate_tip('qt.QWidget.AltButton.__xor__') - self.assert_in('__class__' , tip) + tip = _pydev_imports_tipper.generate_tip("qt.QWidget.AltButton.__xor__") + self.assert_in("__class__", tip) except ImportError: pass tip = _pydev_imports_tipper.generate_tip(BUILTIN_MOD) -# for t in tip[1]: -# print_ t - self.assert_in('object' , tip) - self.assert_in('tuple' , tip) - self.assert_in('list' , tip) - self.assert_in('RuntimeError' , tip) - self.assert_in('RuntimeWarning' , tip) + # for t in tip[1]: + # print_ t + self.assert_in("object", tip) + self.assert_in("tuple", tip) + self.assert_in("list", tip) + self.assert_in("RuntimeError", tip) + self.assert_in("RuntimeWarning", tip) # Remove cmp as it's not available on py 3 # t = self.assert_in('cmp' , tip) # self.check_args(t, '(x, y)', '(object x, object y)', '(x: object, y: object)') #args - t = self.assert_in('isinstance' , tip) + t = self.assert_in("isinstance", tip) self.check_args( t, - '(object, class_or_type_or_tuple)', - '(object o, type typeinfo)', - '(o: object, typeinfo: type)', - '(obj, class_or_tuple)', - '(obj, klass_or_tuple)', + "(object, class_or_type_or_tuple)", + "(object o, type typeinfo)", + "(o: object, typeinfo: type)", + "(obj, class_or_tuple)", + "(obj, klass_or_tuple)", ) # args - t = self.assert_in('compile' , tip) + t = self.assert_in("compile", tip) self.check_args( t, - '(source, filename, mode)', - '()', - '(o: object, name: str, val: object)', - '(source, filename, mode, flags, dont_inherit, optimize)', - '(source, filename, mode, flags, dont_inherit)', - '(source, filename, mode, flags, dont_inherit, optimize, _feature_version=-1)', - '(source, filename, mode, flags, dont_inherit, optimize, _feature_version)', + "(source, filename, mode)", + "()", + "(o: object, name: str, val: object)", + "(source, filename, mode, flags, dont_inherit, optimize)", + "(source, filename, mode, flags, dont_inherit)", + "(source, filename, mode, flags, dont_inherit, optimize, _feature_version=-1)", + "(source, filename, mode, flags, dont_inherit, optimize, _feature_version)", ) # args - t = self.assert_in('setattr' , tip) + t = self.assert_in("setattr", tip) self.check_args( t, - '(object, name, value)', - '(object o, str name, object val)', - '(o: object, name: str, val: object)', - '(obj, name, value)', - '(object, name, val)', + "(object, name, value)", + "(object o, str name, object val)", + "(o: object, name: str, val: object)", + "(obj, name, value)", + "(object, name, val)", ) # args try: import compiler - compiler_module = 'compiler' + + compiler_module = "compiler" except ImportError: try: import ast - compiler_module = 'ast' + + compiler_module = "ast" except ImportError: compiler_module = None if compiler_module is not None: # Not available in iron python tip = _pydev_imports_tipper.generate_tip(compiler_module) - if compiler_module == 'compiler': - self.assert_args('parse', '(buf, mode)', tip) - self.assert_args('walk', '(tree, visitor, walker, verbose)', tip) - self.assert_in('parseFile' , tip) + if compiler_module == "compiler": + self.assert_args("parse", "(buf, mode)", tip) + self.assert_args("walk", "(tree, visitor, walker, verbose)", tip) + self.assert_in("parseFile", tip) else: - self.assert_args('parse', [ - '(source, filename, mode)', - '(source, filename, mode, type_comments=False, feature_version=None)' - ], tip + self.assert_args( + "parse", ["(source, filename, mode)", "(source, filename, mode, type_comments=False, feature_version=None)"], tip ) - self.assert_args('walk', '(node)', tip) - self.assert_in('parse' , tip) + self.assert_args("walk", "(node)", tip) + self.assert_in("parse", tip) def check_args(self, t, *expected): for x in expected: if x == t[2]: return - self.fail('Found: %s. Expected: %s' % (t[2], expected)) + self.fail("Found: %s. Expected: %s" % (t[2], expected)) def assert_args(self, tok, args, tips): if not isinstance(args, (list, tuple)): @@ -196,33 +196,31 @@ def assert_args(self, tok, args, tips): for arg in args: if arg == a[2]: return - raise AssertionError('%s not in %s', a[2], args) + raise AssertionError("%s not in %s", a[2], args) - raise AssertionError('%s not in %s', tok, tips) + raise AssertionError("%s not in %s", tok, tips) def assert_in(self, tok, tips): for a in tips[1]: if tok == a[0]: return a - raise AssertionError('%s not in %s' % (tok, tips)) + raise AssertionError("%s not in %s" % (tok, tips)) def test_search(self): - s = _pydev_imports_tipper.search_definition('inspect.ismodule') + s = _pydev_imports_tipper.search_definition("inspect.ismodule") (f, line, col), foundAs = s self.assertTrue(line > 0) def test_dot_net_libraries(self): - if sys.platform == 'cli': - tip = _pydev_imports_tipper.generate_tip('System.Drawing') - self.assert_in('Brushes' , tip) + if sys.platform == "cli": + tip = _pydev_imports_tipper.generate_tip("System.Drawing") + self.assert_in("Brushes", tip) - tip = _pydev_imports_tipper.generate_tip('System.Drawing.Brushes') - self.assert_in('Aqua' , tip) + tip = _pydev_imports_tipper.generate_tip("System.Drawing.Brushes") + self.assert_in("Aqua", tip) def test_tips_hasattr_failure(self): - class MyClass(object): - def __getattribute__(self, attr): raise RuntimeError() @@ -231,14 +229,14 @@ def __getattribute__(self, attr): _pydev_imports_tipper.generate_imports_tip_for_module(obj) def test_inspect(self): - class C(object): - def metA(self, a, b): pass obj = C.metA - if inspect.ismethod (obj): + if inspect.ismethod(obj): pass + + # print_ obj.im_func # print_ inspect.getargspec(obj.im_func) diff --git a/tests_mainloop/gui-glut.py b/tests_mainloop/gui-glut.py index 34a16b454..f9373690f 100644 --- a/tests_mainloop/gui-glut.py +++ b/tests_mainloop/gui-glut.py @@ -9,44 +9,41 @@ 4) run: gl.glClearColor(1,1,1,1) """ -if __name__ == '__main__': - +if __name__ == "__main__": #!/usr/bin/env python import sys import OpenGL.GL as gl import OpenGL.GLUT as glut - + def close(): glut.glutDestroyWindow(glut.glutGetWindow()) - + def display(): - gl.glClear (gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) + gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT) glut.glutSwapBuffers() - - def resize(width,height): - gl.glViewport(0, 0, width, height+4) + + def resize(width, height): + gl.glViewport(0, 0, width, height + 4) gl.glMatrixMode(gl.GL_PROJECTION) gl.glLoadIdentity() - gl.glOrtho(0, width, 0, height+4, -1, 1) + gl.glOrtho(0, width, 0, height + 4, -1, 1) gl.glMatrixMode(gl.GL_MODELVIEW) - + if glut.glutGetWindow() > 0: interactive = True glut.glutInit(sys.argv) - glut.glutInitDisplayMode(glut.GLUT_DOUBLE | - glut.GLUT_RGBA | - glut.GLUT_DEPTH) + glut.glutInitDisplayMode(glut.GLUT_DOUBLE | glut.GLUT_RGBA | glut.GLUT_DEPTH) else: interactive = False - - glut.glutCreateWindow('gui-glut') + + glut.glutCreateWindow("gui-glut") glut.glutDisplayFunc(display) glut.glutReshapeFunc(resize) # This is necessary on osx to be able to close the window # (else the close button is disabled) - if sys.platform == 'darwin' and not bool(glut.HAVE_FREEGLUT): + if sys.platform == "darwin" and not bool(glut.HAVE_FREEGLUT): glut.glutWMCloseFunc(close) - gl.glClearColor(0,0,0,1) - + gl.glClearColor(0, 0, 0, 1) + if not interactive: glut.glutMainLoop() diff --git a/tests_mainloop/gui-gtk.py b/tests_mainloop/gui-gtk.py index 6df5c782e..629400401 100644 --- a/tests_mainloop/gui-gtk.py +++ b/tests_mainloop/gui-gtk.py @@ -8,28 +8,27 @@ interactive console """ -if __name__ == '__main__': +if __name__ == "__main__": import pygtk - pygtk.require('2.0') + + pygtk.require("2.0") import gtk - - + def hello_world(wigdet, data=None): print("Hello World") - + def delete_event(widget, event, data=None): return False - + def destroy(widget, data=None): gtk.main_quit() - + window = gtk.Window(gtk.WINDOW_TOPLEVEL) window.connect("delete_event", delete_event) window.connect("destroy", destroy) button = gtk.Button("Hello World") button.connect("clicked", hello_world, None) - + window.add(button) button.show() window.show() - diff --git a/tests_mainloop/gui-gtk3.py b/tests_mainloop/gui-gtk3.py index 6351d5235..4c3b0052b 100644 --- a/tests_mainloop/gui-gtk3.py +++ b/tests_mainloop/gui-gtk3.py @@ -8,26 +8,24 @@ interactive console """ -if __name__ == '__main__': +if __name__ == "__main__": from gi.repository import Gtk - - + def hello_world(wigdet, data=None): print("Hello World") - + def delete_event(widget, event, data=None): return False - + def destroy(widget, data=None): Gtk.main_quit() - + window = Gtk.Window(Gtk.WindowType.TOPLEVEL) window.connect("delete_event", delete_event) window.connect("destroy", destroy) button = Gtk.Button("Hello World") button.connect("clicked", hello_world, None) - + window.add(button) button.show() window.show() - diff --git a/tests_mainloop/gui-pyglet.py b/tests_mainloop/gui-pyglet.py index 70f1a7f64..0bbffe178 100644 --- a/tests_mainloop/gui-pyglet.py +++ b/tests_mainloop/gui-pyglet.py @@ -8,20 +8,24 @@ interactive console """ -if __name__ == '__main__': +if __name__ == "__main__": import pyglet - - + window = pyglet.window.Window() - label = pyglet.text.Label('Hello, world', - font_name='Times New Roman', - font_size=36, - x=window.width//2, y=window.height//2, - anchor_x='center', anchor_y='center') + label = pyglet.text.Label( + "Hello, world", + font_name="Times New Roman", + font_size=36, + x=window.width // 2, + y=window.height // 2, + anchor_x="center", + anchor_y="center", + ) + @window.event def on_close(): window.close() - + @window.event def on_draw(): window.clear() diff --git a/tests_mainloop/gui-qt.py b/tests_mainloop/gui-qt.py index 30fc48d38..8a2a63b52 100644 --- a/tests_mainloop/gui-qt.py +++ b/tests_mainloop/gui-qt.py @@ -10,27 +10,26 @@ Ref: Modified from http://zetcode.com/tutorials/pyqt4/firstprograms/ """ -if __name__ == '__main__': +if __name__ == "__main__": import sys from PyQt4 import QtGui, QtCore - + class SimpleWindow(QtGui.QWidget): def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) - + self.setGeometry(300, 300, 200, 80) - self.setWindowTitle('Hello World') - - quit = QtGui.QPushButton('Close', self) + self.setWindowTitle("Hello World") + + quit = QtGui.QPushButton("Close", self) quit.setGeometry(10, 10, 60, 35) - - self.connect(quit, QtCore.SIGNAL('clicked()'), - self, QtCore.SLOT('close()')) - - if __name__ == '__main__': + + self.connect(quit, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("close()")) + + if __name__ == "__main__": app = QtCore.QCoreApplication.instance() if app is None: app = QtGui.QApplication([]) - + sw = SimpleWindow() sw.show() diff --git a/tests_mainloop/gui-tk.py b/tests_mainloop/gui-tk.py index 4cef45f91..d16e638c9 100644 --- a/tests_mainloop/gui-tk.py +++ b/tests_mainloop/gui-tk.py @@ -8,26 +8,24 @@ interactive console """ -if __name__ == '__main__': - +if __name__ == "__main__": try: from Tkinter import * except: # Python 3 from tkinter import * - + class MyApp: - def __init__(self, root): frame = Frame(root) frame.pack() - + self.button = Button(frame, text="Hello", command=self.hello_world) self.button.pack(side=LEFT) - + def hello_world(self): print("Hello World!") - + root = Tk() - + app = MyApp(root) diff --git a/tests_mainloop/gui-wx.py b/tests_mainloop/gui-wx.py index dfd35d841..5bc54cc33 100644 --- a/tests_mainloop/gui-wx.py +++ b/tests_mainloop/gui-wx.py @@ -11,54 +11,52 @@ Ref: Modified from wxPython source code wxPython/samples/simple/simple.py """ -if __name__ == '__main__': - +if __name__ == "__main__": import wx - - + class MyFrame(wx.Frame): """ This is MyFrame. It just shows a few controls on a wxPanel, and has a simple menu. """ + def __init__(self, parent, title): - wx.Frame.__init__(self, parent, -1, title, - pos=(150, 150), size=(350, 200)) - + wx.Frame.__init__(self, parent, -1, title, pos=(150, 150), size=(350, 200)) + # Create the menubar menuBar = wx.MenuBar() - + # and a menu menu = wx.Menu() - + # add an item to the menu, using \tKeyName automatically # creates an accelerator, the third param is some help text # that will show up in the statusbar menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample") - + # bind the menu event to an event handler self.Bind(wx.EVT_MENU, self.on_time_to_close, id=wx.ID_EXIT) - + # and put the menu on the menubar menuBar.Append(menu, "&File") self.SetMenuBar(menuBar) - + self.CreateStatusBar() - + # Now create the Panel to put the other controls on. panel = wx.Panel(self) - + # and a few controls text = wx.StaticText(panel, -1, "Hello World!") text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)) text.SetSize(text.GetBestSize()) btn = wx.Button(panel, -1, "Close") funbtn = wx.Button(panel, -1, "Just for fun...") - + # bind the button events to handlers self.Bind(wx.EVT_BUTTON, self.on_time_to_close, btn) self.Bind(wx.EVT_BUTTON, self.on_fun_button, funbtn) - + # Use a sizer to layout the controls, stacked vertically and with # a 10 pixel border around each sizer = wx.BoxSizer(wx.VERTICAL) @@ -67,31 +65,27 @@ def __init__(self, parent, title): sizer.Add(funbtn, 0, wx.ALL, 10) panel.SetSizer(sizer) panel.Layout() - - + def on_time_to_close(self, evt): """Event handler for the button click.""" print("See ya later!") self.Close() - + def on_fun_button(self, evt): """Event handler for the button click.""" print("Having fun yet?") - - + class MyApp(wx.App): def OnInit(self): frame = MyFrame(None, "Simple wxPython App") self.SetTopWindow(frame) - + print("Print statements go to this stdout window by default.") - + frame.Show(True) return True - - - if __name__ == '__main__': - + + if __name__ == "__main__": app = wx.GetApp() if app is None: app = MyApp(redirect=False, clearSigInt=False) @@ -100,4 +94,3 @@ def OnInit(self): app.SetTopWindow(frame) print("Print statements go to this stdout window by default.") frame.Show(True) - diff --git a/tests_python/check_debug_python.py b/tests_python/check_debug_python.py index 3027e9a9d..371a8be98 100644 --- a/tests_python/check_debug_python.py +++ b/tests_python/check_debug_python.py @@ -5,14 +5,13 @@ def check(): with pydev_log.log_context(3, sys.stderr): - assert hasattr(sys, 'gettotalrefcount') + assert hasattr(sys, "gettotalrefcount") import pydevd_tracing proceed1 = threading.Event() proceed2 = threading.Event() class SomeThread(threading.Thread): - def run(self): proceed1.set() proceed2.wait() @@ -31,8 +30,8 @@ def some_func(frame, event, arg): lib = pydevd_tracing._load_python_helper_lib() assert lib is None - print('Finished OK') + print("Finished OK") -if __name__ == '__main__': +if __name__ == "__main__": check() diff --git a/tests_python/debug_constants.py b/tests_python/debug_constants.py index ee74a9fe2..18f75692b 100644 --- a/tests_python/debug_constants.py +++ b/tests_python/debug_constants.py @@ -2,15 +2,15 @@ import sys import platform -TEST_CYTHON = os.getenv('PYDEVD_USE_CYTHON', None) == 'YES' -PYDEVD_TEST_VM = os.getenv('PYDEVD_TEST_VM', None) +TEST_CYTHON = os.getenv("PYDEVD_USE_CYTHON", None) == "YES" +PYDEVD_TEST_VM = os.getenv("PYDEVD_TEST_VM", None) IS_PY36_OR_GREATER = sys.version_info[0:2] >= (3, 6) IS_PY311_OR_GREATER = sys.version_info[0:2] >= (3, 11) IS_PY311 = sys.version_info[0:2] == (3, 11) IS_PY312 = sys.version_info[0:2] == (3, 12) -IS_CPYTHON = platform.python_implementation() == 'CPython' -IS_PYPY = platform.python_implementation() == 'PyPy' +IS_CPYTHON = platform.python_implementation() == "CPython" +IS_PYPY = platform.python_implementation() == "PyPy" TODO_PY312 = IS_PY312 # Code which needs to be fixed in 3.12 should use this constant. TODO_PYPY = IS_PYPY # Code which needs to be fixed in pypy. @@ -26,24 +26,28 @@ try: import django + TEST_DJANGO = True except: pass try: import flask + TEST_FLASK = True except: pass try: import cherrypy + TEST_CHERRYPY = True except: pass try: import gevent + TEST_GEVENT = True except: pass diff --git a/tests_python/debugger_fixtures.py b/tests_python/debugger_fixtures.py index aaf1e644f..b3ef16c28 100644 --- a/tests_python/debugger_fixtures.py +++ b/tests_python/debugger_fixtures.py @@ -5,9 +5,18 @@ import pytest from tests_python import debugger_unittest -from tests_python.debugger_unittest import (get_free_port, overrides, IS_CPYTHON, IS_JYTHON, IS_IRONPYTHON, - CMD_ADD_DJANGO_EXCEPTION_BREAK, CMD_REMOVE_DJANGO_EXCEPTION_BREAK, - CMD_ADD_EXCEPTION_BREAK, wait_for_condition, IS_PYPY) +from tests_python.debugger_unittest import ( + get_free_port, + overrides, + IS_CPYTHON, + IS_JYTHON, + IS_IRONPYTHON, + CMD_ADD_DJANGO_EXCEPTION_BREAK, + CMD_REMOVE_DJANGO_EXCEPTION_BREAK, + CMD_ADD_EXCEPTION_BREAK, + wait_for_condition, + IS_PYPY, +) from _pydevd_bundle.pydevd_comm_constants import file_system_encoding import sys @@ -16,90 +25,91 @@ def get_java_location(): from java.lang import System # @UnresolvedImport + jre_dir = System.getProperty("java.home") - for f in [os.path.join(jre_dir, 'bin', 'java.exe'), os.path.join(jre_dir, 'bin', 'java')]: + for f in [os.path.join(jre_dir, "bin", "java.exe"), os.path.join(jre_dir, "bin", "java")]: if os.path.exists(f): return f - raise RuntimeError('Unable to find java executable') + raise RuntimeError("Unable to find java executable") def get_jython_jar(): from java.lang import ClassLoader # @UnresolvedImport + cl = ClassLoader.getSystemClassLoader() paths = map(lambda url: url.getFile(), cl.getURLs()) for p in paths: - if 'jython.jar' in p: + if "jython.jar" in p: return p - raise RuntimeError('Unable to find jython.jar') + raise RuntimeError("Unable to find jython.jar") class _WriterThreadCaseMSwitch(debugger_unittest.AbstractWriterThread): - - TEST_FILE = 'tests_python.resources._debugger_case_m_switch' + TEST_FILE = "tests_python.resources._debugger_case_m_switch" IS_MODULE = True @overrides(debugger_unittest.AbstractWriterThread.get_environ) def get_environ(self): env = os.environ.copy() - curr_pythonpath = env.get('PYTHONPATH', '') + curr_pythonpath = env.get("PYTHONPATH", "") root_dirname = os.path.dirname(os.path.dirname(__file__)) curr_pythonpath += root_dirname + os.pathsep - env['PYTHONPATH'] = curr_pythonpath + env["PYTHONPATH"] = curr_pythonpath return env @overrides(debugger_unittest.AbstractWriterThread.get_main_filename) def get_main_filename(self): - return debugger_unittest._get_debugger_test_file('_debugger_case_m_switch.py') + return debugger_unittest._get_debugger_test_file("_debugger_case_m_switch.py") class _WriterThreadCaseModuleWithEntryPoint(_WriterThreadCaseMSwitch): - - TEST_FILE = 'tests_python.resources._debugger_case_module_entry_point:main' + TEST_FILE = "tests_python.resources._debugger_case_module_entry_point:main" IS_MODULE = True @overrides(_WriterThreadCaseMSwitch.get_main_filename) def get_main_filename(self): - return debugger_unittest._get_debugger_test_file('_debugger_case_module_entry_point.py') + return debugger_unittest._get_debugger_test_file("_debugger_case_module_entry_point.py") class AbstractWriterThreadCaseFlask(debugger_unittest.AbstractWriterThread): - FORCE_KILL_PROCESS_WHEN_FINISHED_OK = True FLASK_FOLDER = None - TEST_FILE = 'flask' + TEST_FILE = "flask" IS_MODULE = True def write_add_breakpoint_jinja2(self, line, func, template): - ''' - @param line: starts at 1 - ''' + """ + @param line: starts at 1 + """ assert self.FLASK_FOLDER is not None breakpoint_id = self.next_breakpoint_id() - template_file = debugger_unittest._get_debugger_test_file(os.path.join(self.FLASK_FOLDER, 'templates', template)) - self.write("111\t%s\t%s\t%s\t%s\t%s\t%s\tNone\tNone" % (self.next_seq(), breakpoint_id, 'jinja2-line', template_file, line, func)) - self.log.append('write_add_breakpoint_jinja: %s line: %s func: %s' % (breakpoint_id, line, func)) + template_file = debugger_unittest._get_debugger_test_file(os.path.join(self.FLASK_FOLDER, "templates", template)) + self.write("111\t%s\t%s\t%s\t%s\t%s\t%s\tNone\tNone" % (self.next_seq(), breakpoint_id, "jinja2-line", template_file, line, func)) + self.log.append("write_add_breakpoint_jinja: %s line: %s func: %s" % (breakpoint_id, line, func)) return breakpoint_id - def write_add_exception_breakpoint_jinja2(self, exception='jinja2-Exception'): - self.write('%s\t%s\t%s\t%s\t%s\t%s' % (CMD_ADD_EXCEPTION_BREAK, self.next_seq(), exception, 2, 0, 0)) + def write_add_exception_breakpoint_jinja2(self, exception="jinja2-Exception"): + self.write("%s\t%s\t%s\t%s\t%s\t%s" % (CMD_ADD_EXCEPTION_BREAK, self.next_seq(), exception, 2, 0, 0)) @overrides(debugger_unittest.AbstractWriterThread.get_environ) def get_environ(self): import platform env = os.environ.copy() - env['FLASK_APP'] = 'app.py' - env['FLASK_ENV'] = 'development' - env['FLASK_DEBUG'] = '0' - if platform.system() != 'Windows': - locale = 'en_US.utf8' if platform.system() == 'Linux' else 'en_US.UTF-8' - env.update({ - 'LC_ALL': locale, - 'LANG': locale, - }) + env["FLASK_APP"] = "app.py" + env["FLASK_ENV"] = "development" + env["FLASK_DEBUG"] = "0" + if platform.system() != "Windows": + locale = "en_US.utf8" if platform.system() == "Linux" else "en_US.UTF-8" + env.update( + { + "LC_ALL": locale, + "LANG": locale, + } + ) return env def get_cwd(self): @@ -110,12 +120,12 @@ def get_command_line_args(self): free_port = get_free_port() self.flask_port = free_port return [ - 'flask', - 'run', - '--no-debugger', - '--no-reload', - '--with-threads', - '--port', + "flask", + "run", + "--no-debugger", + "--no-reload", + "--with-threads", + "--port", str(free_port), ] @@ -123,21 +133,19 @@ def _ignore_stderr_line(self, line): if debugger_unittest.AbstractWriterThread._ignore_stderr_line(self, line): return True - if 'Running on http:' in line: + if "Running on http:" in line: return True - if 'GET / HTTP/' in line: + if "GET / HTTP/" in line: return True return False - def create_request_thread(self, url=''): - return debugger_unittest.AbstractWriterThread.create_request_thread( - self, 'http://127.0.0.1:%s%s' % (self.flask_port, url)) + def create_request_thread(self, url=""): + return debugger_unittest.AbstractWriterThread.create_request_thread(self, "http://127.0.0.1:%s%s" % (self.flask_port, url)) class AbstractWriterThreadCaseDjango(debugger_unittest.AbstractWriterThread): - FORCE_KILL_PROCESS_WHEN_FINISHED_OK = True DJANGO_FOLDER = None @@ -145,7 +153,7 @@ def _ignore_stderr_line(self, line): if debugger_unittest.AbstractWriterThread._ignore_stderr_line(self, line): return True - if 'GET /my_app' in line: + if "GET /my_app" in line: return True return False @@ -155,67 +163,57 @@ def get_command_line_args(self): free_port = get_free_port() self.django_port = free_port return [ - debugger_unittest._get_debugger_test_file(os.path.join(self.DJANGO_FOLDER, 'manage.py')), - 'runserver', - '--noreload', - '--nothreading', + debugger_unittest._get_debugger_test_file(os.path.join(self.DJANGO_FOLDER, "manage.py")), + "runserver", + "--noreload", + "--nothreading", str(free_port), ] def write_add_breakpoint_django(self, line, func, template): - ''' - @param line: starts at 1 - ''' + """ + @param line: starts at 1 + """ assert self.DJANGO_FOLDER is not None breakpoint_id = self.next_breakpoint_id() - template_file = debugger_unittest._get_debugger_test_file(os.path.join(self.DJANGO_FOLDER, 'my_app', 'templates', 'my_app', template)) - self.write("111\t%s\t%s\t%s\t%s\t%s\t%s\tNone\tNone" % (self.next_seq(), breakpoint_id, 'django-line', template_file, line, func)) - self.log.append('write_add_django_breakpoint: %s line: %s func: %s' % (breakpoint_id, line, func)) + template_file = debugger_unittest._get_debugger_test_file( + os.path.join(self.DJANGO_FOLDER, "my_app", "templates", "my_app", template) + ) + self.write("111\t%s\t%s\t%s\t%s\t%s\t%s\tNone\tNone" % (self.next_seq(), breakpoint_id, "django-line", template_file, line, func)) + self.log.append("write_add_django_breakpoint: %s line: %s func: %s" % (breakpoint_id, line, func)) return breakpoint_id - def write_add_exception_breakpoint_django(self, exception='Exception'): - self.write('%s\t%s\t%s' % (CMD_ADD_DJANGO_EXCEPTION_BREAK, self.next_seq(), exception)) + def write_add_exception_breakpoint_django(self, exception="Exception"): + self.write("%s\t%s\t%s" % (CMD_ADD_DJANGO_EXCEPTION_BREAK, self.next_seq(), exception)) - def write_remove_exception_breakpoint_django(self, exception='Exception'): - self.write('%s\t%s\t%s' % (CMD_REMOVE_DJANGO_EXCEPTION_BREAK, self.next_seq(), exception)) + def write_remove_exception_breakpoint_django(self, exception="Exception"): + self.write("%s\t%s\t%s" % (CMD_REMOVE_DJANGO_EXCEPTION_BREAK, self.next_seq(), exception)) - def create_request_thread(self, url=''): - return debugger_unittest.AbstractWriterThread.create_request_thread( - self, 'http://127.0.0.1:%s/%s' % (self.django_port, url)) + def create_request_thread(self, url=""): + return debugger_unittest.AbstractWriterThread.create_request_thread(self, "http://127.0.0.1:%s/%s" % (self.django_port, url)) class DebuggerRunnerSimple(debugger_unittest.DebuggerRunner): - def get_command_line(self): if IS_JYTHON: if sys.executable is not None: # i.e.: we're running with the provided jython.exe return [sys.executable] else: - - return [ - get_java_location(), - '-classpath', - get_jython_jar(), - 'org.python.util.jython' - ] + return [get_java_location(), "-classpath", get_jython_jar(), "org.python.util.jython"] if IS_CPYTHON or IS_PYPY: - return [sys.executable, '-u'] + return [sys.executable, "-u"] if IS_IRONPYTHON: - return [ - sys.executable, - '-X:Frames' - ] + return [sys.executable, "-X:Frames"] - raise RuntimeError('Unable to provide command line') + raise RuntimeError("Unable to provide command line") class DebuggerRunnerRemote(debugger_unittest.DebuggerRunner): - def get_command_line(self): - return [sys.executable, '-u'] + return [sys.executable, "-u"] def add_command_line_args(self, args, dap=False): writer = self.writer @@ -243,27 +241,21 @@ class WriterThread(debugger_unittest.AbstractWriterThread): pass class CaseSetup(object): - check_non_ascii = False - NON_ASCII_CHARS = u'áéíóú汉字' + NON_ASCII_CHARS = "áéíóú汉字" dap = False @contextmanager - def test_file( - self, - filename, - wait_for_port=True, - wait_for_initialization=True, - **kwargs - ): + def test_file(self, filename, wait_for_port=True, wait_for_initialization=True, **kwargs): import shutil + filename = debugger_unittest._get_debugger_test_file(filename) if self.check_non_ascii: basedir = str(tmpdir) if isinstance(basedir, bytes): - basedir = basedir.decode('utf-8') + basedir = basedir.decode("utf-8") if isinstance(filename, bytes): - filename = filename.decode('utf-8') + filename = filename.decode("utf-8") new_dir = os.path.join(basedir, self.NON_ASCII_CHARS) os.makedirs(new_dir) @@ -278,11 +270,8 @@ def test_file( setattr(WriterThread, key, value) with runner.check_case( - WriterThread, - wait_for_port=wait_for_port, - wait_for_initialization=wait_for_initialization, - dap=self.dap - ) as writer: + WriterThread, wait_for_port=wait_for_port, wait_for_initialization=wait_for_initialization, dap=self.dap + ) as writer: yield writer return CaseSetup() @@ -296,21 +285,19 @@ def case_setup_dap(case_setup): @pytest.fixture def case_setup_unhandled_exceptions(case_setup): - original = case_setup.test_file def check_test_suceeded_msg(writer, stdout, stderr): - return 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): # Don't call super as we have an expected exception - if 'ValueError: TEST SUCEEDED' not in stderr: - raise AssertionError('"ValueError: TEST SUCEEDED" not in stderr.\nstdout:\n%s\n\nstderr:\n%s' % ( - stdout, stderr)) + if "ValueError: TEST SUCEEDED" not in stderr: + raise AssertionError('"ValueError: TEST SUCEEDED" not in stderr.\nstdout:\n%s\n\nstderr:\n%s' % (stdout, stderr)) def test_file(*args, **kwargs): - kwargs.setdefault('check_test_suceeded_msg', check_test_suceeded_msg) - kwargs.setdefault('additional_output_checks', additional_output_checks) + kwargs.setdefault("check_test_suceeded_msg", check_test_suceeded_msg) + kwargs.setdefault("additional_output_checks", additional_output_checks) return original(*args, **kwargs) case_setup.test_file = test_file @@ -320,39 +307,30 @@ def test_file(*args, **kwargs): @pytest.fixture def case_setup_remote(debugger_runner_remote): - class WriterThread(debugger_unittest.AbstractWriterThread): pass class CaseSetup(object): - dap = False @contextmanager def test_file( - self, - filename, - wait_for_port=True, - access_token=None, - client_access_token=None, - append_command_line_args=(), - **kwargs - ): - + self, filename, wait_for_port=True, access_token=None, client_access_token=None, append_command_line_args=(), **kwargs + ): def update_command_line_args(writer, args): ret = debugger_unittest.AbstractWriterThread.update_command_line_args(writer, args) - wait_for_condition(lambda: hasattr(writer, 'port')) + wait_for_condition(lambda: hasattr(writer, "port")) ret.append(str(writer.port)) if access_token is not None: - ret.append('--access-token') + ret.append("--access-token") ret.append(access_token) if client_access_token is not None: - ret.append('--client-access-token') + ret.append("--client-access-token") ret.append(client_access_token) if self.dap: - ret.append('--use-dap-mode') + ret.append("--use-dap-mode") ret.extend(append_command_line_args) return ret @@ -377,14 +355,13 @@ def case_setup_remote_dap(case_setup_remote): @pytest.fixture def case_setup_remote_attach_to_dap(debugger_runner_remote): - ''' + """ The difference from this to case_setup_remote is that this one will connect to a server socket started by the debugger and case_setup_remote will create the server socket and wait for a connection from the debugger. - ''' + """ class WriterThread(debugger_unittest.AbstractWriterThread): - @overrides(debugger_unittest.AbstractWriterThread.run) def run(self): # I.e.: don't start socket on start(), rather, the test should call @@ -392,23 +369,17 @@ def run(self): pass class CaseSetup(object): - dap = True @contextmanager - def test_file( - self, - filename, - port, - **kwargs - ): - additional_args = kwargs.pop('additional_args', []) + def test_file(self, filename, port, **kwargs): + additional_args = kwargs.pop("additional_args", []) def update_command_line_args(writer, args): ret = debugger_unittest.AbstractWriterThread.update_command_line_args(writer, args) ret.append(str(port)) if self.dap: - ret.append('--use-dap-mode') + ret.append("--use-dap-mode") ret.extend(additional_args) return ret @@ -426,28 +397,21 @@ def update_command_line_args(writer, args): @pytest.fixture def case_setup_multiprocessing(debugger_runner_simple): - class WriterThread(debugger_unittest.AbstractWriterThread): pass class CaseSetup(object): - dap = False @contextmanager - def test_file( - self, - filename, - **kwargs - ): - + def test_file(self, filename, **kwargs): def update_command_line_args(writer, args): ret = debugger_unittest.AbstractWriterThread.update_command_line_args(writer, args) - ret.insert(ret.index('--client'), '--multiprocess') + ret.insert(ret.index("--client"), "--multiprocess") if self.dap: - ret.insert(ret.index('--client'), '--debug-mode') - ret.insert(ret.index('--client'), 'debugpy-dap') - ret.insert(ret.index('--client'), '--json-dap-http') + ret.insert(ret.index("--client"), "--debug-mode") + ret.insert(ret.index("--client"), "debugpy-dap") + ret.insert(ret.index("--client"), "--json-dap-http") return ret WriterThread.update_command_line_args = update_command_line_args @@ -470,12 +434,10 @@ def case_setup_multiprocessing_dap(case_setup_multiprocessing): @pytest.fixture def case_setup_m_switch(debugger_runner_simple): - class WriterThread(_WriterThreadCaseMSwitch): pass class CaseSetup(object): - @contextmanager def test_file(self, **kwargs): for key, value in kwargs.items(): @@ -489,14 +451,12 @@ def test_file(self, **kwargs): @pytest.fixture def case_setup_m_switch_entry_point(debugger_runner_simple): - runner = debugger_runner_simple class WriterThread(_WriterThreadCaseModuleWithEntryPoint): pass class CaseSetup(object): - @contextmanager def test_file(self, **kwargs): for key, value in kwargs.items(): @@ -510,24 +470,23 @@ def test_file(self, **kwargs): @pytest.fixture def case_setup_django(debugger_runner_simple): - class WriterThread(AbstractWriterThreadCaseDjango): pass class CaseSetup(object): - dap = False @contextmanager def test_file(self, **kwargs): import django - version = [int(x) for x in django.get_version().split('.')][:2] + + version = [int(x) for x in django.get_version().split(".")][:2] if version == [1, 7]: - django_folder = 'my_django_proj_17' + django_folder = "my_django_proj_17" elif version in ([2, 1], [2, 2], [3, 0], [3, 1], [3, 2], [4, 0], [4, 1], [4, 2]): - django_folder = 'my_django_proj_21' + django_folder = "my_django_proj_21" else: - raise AssertionError('Can only check django 1.7 -> 4.2 right now. Found: %s' % (version,)) + raise AssertionError("Can only check django 1.7 -> 4.2 right now. Found: %s" % (version,)) WriterThread.DJANGO_FOLDER = django_folder for key, value in kwargs.items(): @@ -548,17 +507,15 @@ def case_setup_django_dap(case_setup_django): @pytest.fixture def case_setup_flask(debugger_runner_simple): - class WriterThread(AbstractWriterThreadCaseFlask): pass class CaseSetup(object): - dap = False @contextmanager def test_file(self, **kwargs): - WriterThread.FLASK_FOLDER = 'flask1' + WriterThread.FLASK_FOLDER = "flask1" for key, value in kwargs.items(): assert hasattr(WriterThread, key) setattr(WriterThread, key, value) diff --git a/tests_python/debugger_unittest.py b/tests_python/debugger_unittest.py index 1216e1f3b..1725d0507 100644 --- a/tests_python/debugger_unittest.py +++ b/tests_python/debugger_unittest.py @@ -113,24 +113,24 @@ import platform -IS_CPYTHON = platform.python_implementation() == 'CPython' -IS_IRONPYTHON = platform.python_implementation() == 'IronPython' -IS_JYTHON = platform.python_implementation() == 'Jython' -IS_PYPY = platform.python_implementation() == 'PyPy' -IS_APPVEYOR = os.environ.get('APPVEYOR', '') in ('True', 'true', '1') +IS_CPYTHON = platform.python_implementation() == "CPython" +IS_IRONPYTHON = platform.python_implementation() == "IronPython" +IS_JYTHON = platform.python_implementation() == "Jython" +IS_PYPY = platform.python_implementation() == "PyPy" +IS_APPVEYOR = os.environ.get("APPVEYOR", "") in ("True", "true", "1") try: from thread import start_new_thread except ImportError: from _thread import start_new_thread # @UnresolvedImport -Hit = namedtuple('Hit', 'thread_id, frame_id, line, suspend_type, name, file') +Hit = namedtuple("Hit", "thread_id, frame_id, line, suspend_type, name, file") def overrides(method): - ''' + """ Helper to check that one method overrides another (redeclared in unit-tests to avoid importing pydevd). - ''' + """ def wrapper(func): if func.__name__ != method.__name__: @@ -156,15 +156,15 @@ class TimeoutError(RuntimeError): # @ReservedAssignment pass -def wait_for_condition(condition, msg=None, timeout=TIMEOUT, sleep=.05): +def wait_for_condition(condition, msg=None, timeout=TIMEOUT, sleep=0.05): curtime = time.time() while True: if condition(): break if time.time() - curtime > timeout: - error_msg = 'Condition not reached in %s seconds' % (timeout,) + error_msg = "Condition not reached in %s seconds" % (timeout,) if msg is not None: - error_msg += '\n' + error_msg += "\n" if callable(msg): error_msg += msg() else: @@ -178,23 +178,22 @@ class IgnoreFailureError(RuntimeError): pass -#======================================================================================================================= +# ======================================================================================================================= # ReaderThread -#======================================================================================================================= +# ======================================================================================================================= class ReaderThread(threading.Thread): - MESSAGES_TIMEOUT = 10 def __init__(self, sock): threading.Thread.__init__(self) - self.name = 'Test Reader Thread' + self.name = "Test Reader Thread" try: from queue import Queue except ImportError: from Queue import Queue self.daemon = True - self._buffer = b'' + self._buffer = b"" self.sock = sock self._queue = Queue() self._kill = False @@ -211,21 +210,27 @@ def get_next_message(self, context_message, timeout=None): msg = self._queue.get(block=True, timeout=timeout) self.on_message_found(msg) except: - raise TimeoutError('No message was written in %s seconds. Error message:\n%s' % (timeout, context_message,)) + raise TimeoutError( + "No message was written in %s seconds. Error message:\n%s" + % ( + timeout, + context_message, + ) + ) else: frame = sys._getframe().f_back.f_back - frame_info = '' + frame_info = "" while frame: - if not frame.f_code.co_name.startswith('test_'): + if not frame.f_code.co_name.startswith("test_"): frame = frame.f_back continue - if frame.f_code.co_filename.endswith('debugger_unittest.py'): + if frame.f_code.co_filename.endswith("debugger_unittest.py"): frame = frame.f_back continue stack_msg = ' -- File "%s", line %s, in %s\n' % (frame.f_code.co_filename, frame.f_lineno, frame.f_code.co_name) - if 'run' == frame.f_code.co_name: + if "run" == frame.f_code.co_name: frame_info = stack_msg # Ok, found the writer thread 'run' method (show only that). break frame_info += stack_msg @@ -234,11 +239,14 @@ def get_next_message(self, context_message, timeout=None): break frame = None - sys.stdout.write('Message returned in get_next_message(): %s -- ctx: %s, asked at:\n%s\n' % (unquote_plus(unquote_plus(msg)), context_message, frame_info)) + sys.stdout.write( + "Message returned in get_next_message(): %s -- ctx: %s, asked at:\n%s\n" + % (unquote_plus(unquote_plus(msg)), context_message, frame_info) + ) if not self.accept_xml_messages: - if ' size: @@ -256,12 +264,12 @@ def _read(self, size): r = self.sock.recv(max(size - buffer_len, 1024)) if not r: - return b'' + return b"" self._buffer += r def _read_line(self): while True: - i = self._buffer.find(b'\n') + i = self._buffer.find(b"\n") if i != -1: i += 1 # Add the newline to the return ret = self._buffer[:i] @@ -270,7 +278,7 @@ def _read_line(self): else: r = self.sock.recv(1024) if not r: - return b'' + return b"" self._buffer += r def run(self): @@ -285,17 +293,23 @@ def run(self): if SHOW_WRITES_AND_READS: show_line = line - show_line = line.decode('utf-8') - - print('%s Received %s' % (self.name, show_line,)) - - if line.startswith(b'Content-Length:'): - content_len = int(line.strip().split(b':', 1)[1]) + show_line = line.decode("utf-8") + + print( + "%s Received %s" + % ( + self.name, + show_line, + ) + ) + + if line.startswith(b"Content-Length:"): + content_len = int(line.strip().split(b":", 1)[1]) continue if content_len != -1: # If we previously received a content length, read until a '\r\n'. - if line == b'\r\n': + if line == b"\r\n": json_contents = self._read(content_len) content_len = -1 @@ -304,25 +318,25 @@ def run(self): return # Finished communication. msg = json_contents - msg = msg.decode('utf-8') - print('Test Reader Thread Received %s' % (msg,)) + msg = msg.decode("utf-8") + print("Test Reader Thread Received %s" % (msg,)) self._queue.put(msg) continue else: # No content len, regular line-based protocol message (remove trailing new-line). - if line.endswith(b'\n\n'): + if line.endswith(b"\n\n"): line = line[:-2] - elif line.endswith(b'\n'): + elif line.endswith(b"\n"): line = line[:-1] - elif line.endswith(b'\r'): + elif line.endswith(b"\r"): line = line[:-1] msg = line - msg = msg.decode('utf-8') - print('Test Reader Thread Received %s' % (msg,)) + msg = msg.decode("utf-8") + print("Test Reader Thread Received %s" % (msg,)) self._queue.put(msg) except: @@ -341,8 +355,9 @@ def run(self): def do_kill(self): self._kill = True - if hasattr(self, 'sock'): + if hasattr(self, "sock"): from socket import SHUT_RDWR + try: self.sock.shutdown(SHUT_RDWR) except: @@ -351,7 +366,7 @@ def do_kill(self): self.sock.close() except: pass - delattr(self, 'sock') + delattr(self, "sock") def read_process(stream, buffer, debug_stream, stream_name, finish): @@ -360,10 +375,16 @@ def read_process(stream, buffer, debug_stream, stream_name, finish): if not line: break - line = line.decode('utf-8', errors='replace') + line = line.decode("utf-8", errors="replace") if SHOW_STDOUT: - debug_stream.write('%s: %s' % (stream_name, line,)) + debug_stream.write( + "%s: %s" + % ( + stream_name, + line, + ) + ) buffer.append(line) if finish[0]: @@ -377,17 +398,16 @@ def start_in_daemon_thread(target, args): class DebuggerRunner(object): - def __init__(self, tmpdir): if tmpdir is not None: - self.pydevd_debug_file = os.path.join(str(tmpdir), 'pydevd_debug_file_%s.txt' % (os.getpid(),)) + self.pydevd_debug_file = os.path.join(str(tmpdir), "pydevd_debug_file_%s.txt" % (os.getpid(),)) else: self.pydevd_debug_file = None def get_command_line(self): - ''' + """ Returns the base command line (i.e.: ['python.exe', '-u']) - ''' + """ raise NotImplementedError def add_command_line_args(self, args, dap=False): @@ -402,23 +422,23 @@ def add_command_line_args(self, args, dap=False): if not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON: # i.e.: in frame-eval mode we support native threads, whereas # on other cases we need the qt monkeypatch. - ret += ['--qt-support'] + ret += ["--qt-support"] ret += [ - '--client', + "--client", localhost, - '--port', + "--port", str(port), ] if dap: - ret += ['--debug-mode', 'debugpy-dap'] - ret += ['--json-dap-http'] + ret += ["--debug-mode", "debugpy-dap"] + ret += ["--json-dap-http"] if writer.IS_MODULE: - ret += ['--module'] + ret += ["--module"] - ret += ['--file'] + writer.get_command_line_args() + ret += ["--file"] + writer.get_command_line_args() ret = writer.update_command_line_args(ret) # Provide a hook for the writer return args + ret @@ -432,7 +452,7 @@ def check_case(self, writer_class, wait_for_port=True, wait_for_initialization=T try: writer.start() if wait_for_port: - wait_for_condition(lambda: hasattr(writer, 'port')) + wait_for_condition(lambda: hasattr(writer, "port")) self.writer = writer args = self.get_command_line() @@ -440,7 +460,7 @@ def check_case(self, writer_class, wait_for_port=True, wait_for_initialization=T args = self.add_command_line_args(args, dap=dap) if SHOW_OTHER_DEBUG_INFO: - print('executing: %s' % (' '.join(args),)) + print("executing: %s" % (" ".join(args),)) with self.run_process(args, writer) as dct_with_stdout_stder: try: @@ -451,26 +471,29 @@ def check_case(self, writer_class, wait_for_port=True, wait_for_initialization=T elif wait_for_port: wait_for_condition(lambda: writer.finished_initialization) except TimeoutError: - sys.stderr.write('Timed out waiting for initialization\n') - sys.stderr.write('stdout:\n%s\n\nstderr:\n%s\n' % ( - ''.join(dct_with_stdout_stder['stdout']), - ''.join(dct_with_stdout_stder['stderr']), - )) + sys.stderr.write("Timed out waiting for initialization\n") + sys.stderr.write( + "stdout:\n%s\n\nstderr:\n%s\n" + % ( + "".join(dct_with_stdout_stder["stdout"]), + "".join(dct_with_stdout_stder["stderr"]), + ) + ) raise finally: - writer.get_stdout = lambda: ''.join(dct_with_stdout_stder['stdout']) - writer.get_stderr = lambda: ''.join(dct_with_stdout_stder['stderr']) + writer.get_stdout = lambda: "".join(dct_with_stdout_stder["stdout"]) + writer.get_stderr = lambda: "".join(dct_with_stdout_stder["stderr"]) yield writer finally: writer.do_kill() writer.log = [] - stdout = dct_with_stdout_stder['stdout'] - stderr = dct_with_stdout_stder['stderr'] - writer.additional_output_checks(''.join(stdout), ''.join(stderr)) + stdout = dct_with_stdout_stder["stdout"] + stderr = dct_with_stdout_stder["stderr"] + writer.additional_output_checks("".join(stdout), "".join(stderr)) except IgnoreFailureError: - sys.stderr.write('Test finished with ignored failure.\n') + sys.stderr.write("Test finished with ignored failure.\n") return def create_process(self, args, writer): @@ -479,15 +502,15 @@ def create_process(self, args, writer): env = os.environ.copy() if self.pydevd_debug_file: - env['PYDEVD_DEBUG'] = 'True' - env['PYDEVD_DEBUG_FILE'] = self.pydevd_debug_file - print('Logging to: %s' % (self.pydevd_debug_file,)) + env["PYDEVD_DEBUG"] = "True" + env["PYDEVD_DEBUG_FILE"] = self.pydevd_debug_file + print("Logging to: %s" % (self.pydevd_debug_file,)) process = subprocess.Popen( args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE, - cwd=writer.get_cwd() if writer is not None else '.', + cwd=writer.get_cwd() if writer is not None else ".", env=env, ) return process @@ -503,11 +526,11 @@ def run_process(self, args, writer): fail_with_message = False try: - start_in_daemon_thread(read_process, (process.stdout, stdout, sys.stdout, 'stdout', finish)) - start_in_daemon_thread(read_process, (process.stderr, stderr, sys.stderr, 'stderr', finish)) + start_in_daemon_thread(read_process, (process.stdout, stdout, sys.stdout, "stdout", finish)) + start_in_daemon_thread(read_process, (process.stderr, stderr, sys.stderr, "stderr", finish)) if SHOW_OTHER_DEBUG_INFO: - print('Both processes started') + print("Both processes started") # polls can fail (because the process may finish and the thread still not -- so, we give it some more chances to # finish successfully). @@ -515,21 +538,21 @@ def run_process(self, args, writer): shown_intermediate = False dumped_threads = False - dct_with_stdout_stder['stdout'] = stdout - dct_with_stdout_stder['stderr'] = stderr + dct_with_stdout_stder["stdout"] = stdout + dct_with_stdout_stder["stderr"] = stderr try: yield dct_with_stdout_stder except: fail_with_message = True # Let's print the actuayl exception here (it doesn't appear properly on Python 2 and # on Python 3 it's hard to find because pytest output is too verbose). - sys.stderr.write('***********\n') - sys.stderr.write('***********\n') - sys.stderr.write('***********\n') + sys.stderr.write("***********\n") + sys.stderr.write("***********\n") + sys.stderr.write("***********\n") traceback.print_exc() - sys.stderr.write('***********\n') - sys.stderr.write('***********\n') - sys.stderr.write('***********\n') + sys.stderr.write("***********\n") + sys.stderr.write("***********\n") + sys.stderr.write("***********\n") raise if not writer.finished_ok: @@ -537,19 +560,23 @@ def run_process(self, args, writer): "The thread that was doing the tests didn't finish successfully (writer.finished_ok = True not set).", stdout, stderr, - writer + writer, ) while True: if process.poll() is not None: - if writer.EXPECTED_RETURNCODE != 'any': + if writer.EXPECTED_RETURNCODE != "any": expected_returncode = writer.EXPECTED_RETURNCODE if not isinstance(expected_returncode, (list, tuple)): expected_returncode = (expected_returncode,) if process.returncode not in expected_returncode: - self.fail_with_message('Expected process.returncode to be %s. Found: %s' % ( - writer.EXPECTED_RETURNCODE, process.returncode), stdout, stderr, writer) + self.fail_with_message( + "Expected process.returncode to be %s. Found: %s" % (writer.EXPECTED_RETURNCODE, process.returncode), + stdout, + stderr, + writer, + ) break else: if writer is not None: @@ -557,11 +584,14 @@ def run_process(self, args, writer): process.kill() continue - if not shown_intermediate and (time.time() - initial_time > (TIMEOUT / 3.)): # 1/3 of timeout - print('Warning: writer thread exited and process still did not (%.2f seconds elapsed).' % (time.time() - initial_time,)) + if not shown_intermediate and (time.time() - initial_time > (TIMEOUT / 3.0)): # 1/3 of timeout + print( + "Warning: writer thread exited and process still did not (%.2f seconds elapsed)." + % (time.time() - initial_time,) + ) shown_intermediate = True - if time.time() - initial_time > ((TIMEOUT / 3.) * 2.): # 2/3 of timeout + if time.time() - initial_time > ((TIMEOUT / 3.0) * 2.0): # 2/3 of timeout if not dumped_threads: dumped_threads = True # It still didn't finish. Ask for a thread dump @@ -573,33 +603,37 @@ def run_process(self, args, writer): if time.time() - initial_time > TIMEOUT: # timed out process.kill() - time.sleep(.2) + time.sleep(0.2) self.fail_with_message( - "The other process should've exited but still didn't (%.2f seconds timeout for process to exit)." % (time.time() - initial_time,), - stdout, stderr, writer + "The other process should've exited but still didn't (%.2f seconds timeout for process to exit)." + % (time.time() - initial_time,), + stdout, + stderr, + writer, ) - time.sleep(.2) + time.sleep(0.2) if writer is not None: if not writer.FORCE_KILL_PROCESS_WHEN_FINISHED_OK: if stdout is None: self.fail_with_message( - "The other process may still be running -- and didn't give any output.", stdout, stderr, writer) + "The other process may still be running -- and didn't give any output.", stdout, stderr, writer + ) check = 0 while not writer.check_test_suceeded_msg(stdout, stderr): check += 1 if check == 50: self.fail_with_message("TEST SUCEEDED not found.", stdout, stderr, writer) - time.sleep(.1) + time.sleep(0.1) except TimeoutError: - msg = 'TimeoutError' + msg = "TimeoutError" try: writer.write_dump_threads() except: - msg += ' (note: error trying to dump threads on timeout).' - time.sleep(.2) + msg += " (note: error trying to dump threads on timeout)." + time.sleep(0.2) self.fail_with_message(msg, stdout, stderr, writer) except Exception as e: if fail_with_message: @@ -615,17 +649,23 @@ def run_process(self, args, writer): finish[0] = True def fail_with_message(self, msg, stdout, stderr, writerThread): - log_contents = '' + log_contents = "" if self.pydevd_debug_file: for f in pydev_log.list_log_files(self.pydevd_debug_file): if os.path.exists(f): - with open(f, 'r') as stream: - log_contents += '\n-------------------- %s ------------------\n\n' % (f,) + with open(f, "r") as stream: + log_contents += "\n-------------------- %s ------------------\n\n" % (f,) log_contents += stream.read() - msg += ("\n\n===========================\nStdout: \n" + ''.join(stdout) + - "\n\n===========================\nStderr:" + ''.join(stderr) + - "\n\n===========================\nWriter Log:\n" + '\n'.join(getattr(writerThread, 'log', [])) + - "\n\n===========================\nLog:" + log_contents) + msg += ( + "\n\n===========================\nStdout: \n" + + "".join(stdout) + + "\n\n===========================\nStderr:" + + "".join(stderr) + + "\n\n===========================\nWriter Log:\n" + + "\n".join(getattr(writerThread, "log", [])) + + "\n\n===========================\nLog:" + + log_contents + ) if IS_JYTHON: # It seems we have some spurious errors which make Jython tests flaky (on a test run it's @@ -647,16 +687,15 @@ def fail_with_message(self, msg, stdout, stderr, writerThread): # # So, ignore errors in this situation. - if 'error: [Errno -1] Unmapped exception: java.lang.NullPointerException' in msg: + if "error: [Errno -1] Unmapped exception: java.lang.NullPointerException" in msg: raise IgnoreFailureError() raise AssertionError(msg) -#======================================================================================================================= +# ======================================================================================================================= # AbstractWriterThread -#======================================================================================================================= +# ======================================================================================================================= class AbstractWriterThread(threading.Thread): - FORCE_KILL_PROCESS_WHEN_FINISHED_OK = False IS_MODULE = False TEST_FILE = None @@ -675,67 +714,68 @@ def run(self): self.start_socket() def check_test_suceeded_msg(self, stdout, stderr): - return 'TEST SUCEEDED' in ''.join(stdout) + return "TEST SUCEEDED" in "".join(stdout) def update_command_line_args(self, args): return args def _ignore_stderr_line(self, line): - if line.startswith(( - 'debugger: ', - '>>', - '<<', - 'warning: Debugger speedups', - 'pydev debugger: New process is launching', - 'pydev debugger: To debug that process', - '*** Multiprocess', - 'WARNING: This is a development server. Do not use it in a production deployment', - 'Press CTRL+C to quit', - )): + if line.startswith( + ( + "debugger: ", + ">>", + "<<", + "warning: Debugger speedups", + "pydev debugger: New process is launching", + "pydev debugger: To debug that process", + "*** Multiprocess", + "WARNING: This is a development server. Do not use it in a production deployment", + "Press CTRL+C to quit", + ) + ): return True for expected in ( - 'PyDev console: using IPython', - 'Attempting to work in a virtualenv. If you encounter problems, please', - 'Unable to create basic Accelerated OpenGL', # Issue loading qt5 - 'Core Image is now using the software OpenGL', # Issue loading qt5 - 'XDG_RUNTIME_DIR not set', # Issue loading qt5 - ): + "PyDev console: using IPython", + "Attempting to work in a virtualenv. If you encounter problems, please", + "Unable to create basic Accelerated OpenGL", # Issue loading qt5 + "Core Image is now using the software OpenGL", # Issue loading qt5 + "XDG_RUNTIME_DIR not set", # Issue loading qt5 + ): if expected in line: return True - if re.match(r'^(\d+)\t(\d)+', line): + if re.match(r"^(\d+)\t(\d)+", line): return True if IS_JYTHON: for expected in ( - 'org.python.netty.util.concurrent.DefaultPromise', - 'org.python.netty.util.concurrent.SingleThreadEventExecutor', - 'Failed to submit a listener notification task. Event loop shut down?', - 'java.util.concurrent.RejectedExecutionException', - 'An event executor terminated with non-empty task', - 'java.lang.UnsupportedOperationException', + "org.python.netty.util.concurrent.DefaultPromise", + "org.python.netty.util.concurrent.SingleThreadEventExecutor", + "Failed to submit a listener notification task. Event loop shut down?", + "java.util.concurrent.RejectedExecutionException", + "An event executor terminated with non-empty task", + "java.lang.UnsupportedOperationException", "RuntimeWarning: Parent module '_pydevd_bundle' not found while handling absolute import", - 'from _pydevd_bundle.pydevd_additional_thread_info_regular import _current_frames', - 'from _pydevd_bundle.pydevd_additional_thread_info import _current_frames', - 'import org.python.core as PyCore #@UnresolvedImport', - 'from _pydevd_bundle.pydevd_additional_thread_info import set_additional_thread_info', + "from _pydevd_bundle.pydevd_additional_thread_info_regular import _current_frames", + "from _pydevd_bundle.pydevd_additional_thread_info import _current_frames", + "import org.python.core as PyCore #@UnresolvedImport", + "from _pydevd_bundle.pydevd_additional_thread_info import set_additional_thread_info", "RuntimeWarning: Parent module '_pydevd_bundle._debug_adapter' not found while handling absolute import", - 'import json', - + "import json", # Issues with Jython and Java 9. - 'WARNING: Illegal reflective access by org.python.core.PySystemState', - 'WARNING: Please consider reporting this to the maintainers of org.python.core.PySystemState', - 'WARNING: An illegal reflective access operation has occurred', - 'WARNING: Illegal reflective access by jnr.posix.JavaLibCHelper', - 'WARNING: Please consider reporting this to the maintainers of jnr.posix.JavaLibCHelper', - 'WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations', - 'WARNING: All illegal access operations will be denied in a future release', - ): + "WARNING: Illegal reflective access by org.python.core.PySystemState", + "WARNING: Please consider reporting this to the maintainers of org.python.core.PySystemState", + "WARNING: An illegal reflective access operation has occurred", + "WARNING: Illegal reflective access by jnr.posix.JavaLibCHelper", + "WARNING: Please consider reporting this to the maintainers of jnr.posix.JavaLibCHelper", + "WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations", + "WARNING: All illegal access operations will be denied in a future release", + ): if expected in line: return True - if line.strip().startswith('at '): + if line.strip().startswith("at "): return True return False @@ -750,8 +790,9 @@ def additional_output_checks(self, stdout, stderr): lines_with_error.append(line) if lines_with_error: - raise AssertionError('Did not expect to have line(s) in stderr:\n\n%s\n\nFull stderr:\n\n%s' % ( - '\n'.join(lines_with_error), stderr)) + raise AssertionError( + "Did not expect to have line(s) in stderr:\n\n%s\n\nFull stderr:\n\n%s" % ("\n".join(lines_with_error), stderr) + ) def get_environ(self): return None @@ -759,24 +800,24 @@ def get_environ(self): def get_pydevd_file(self): dirname = os.path.dirname(__file__) dirname = os.path.dirname(dirname) - return os.path.abspath(os.path.join(dirname, 'pydevd.py')) + return os.path.abspath(os.path.join(dirname, "pydevd.py")) def get_pydevconsole_file(self): dirname = os.path.dirname(__file__) dirname = os.path.dirname(dirname) - return os.path.abspath(os.path.join(dirname, 'pydevconsole.py')) + return os.path.abspath(os.path.join(dirname, "pydevconsole.py")) def get_line_index_with_content(self, line_content, filename=None): - ''' + """ :return the line index which has the given content (1-based). - ''' + """ if filename is None: filename = self.TEST_FILE - with open(filename, 'r') as stream: + with open(filename, "r") as stream: for i_line, line in enumerate(stream): if line_content in line: return i_line + 1 - raise AssertionError('Did not find: %s in %s' % (line_content, self.TEST_FILE)) + raise AssertionError("Did not find: %s in %s" % (line_content, self.TEST_FILE)) def get_cwd(self): return os.path.dirname(self.get_pydevd_file()) @@ -785,57 +826,71 @@ def get_command_line_args(self): return [self.TEST_FILE] def do_kill(self): - if hasattr(self, 'server_socket'): + if hasattr(self, "server_socket"): self.server_socket.close() - delattr(self, 'server_socket') + delattr(self, "server_socket") - if hasattr(self, 'reader_thread'): + if hasattr(self, "reader_thread"): # if it's not created, it's not there... self.reader_thread.do_kill() - delattr(self, 'reader_thread') + delattr(self, "reader_thread") - if hasattr(self, 'sock'): + if hasattr(self, "sock"): self.sock.close() - delattr(self, 'sock') + delattr(self, "sock") - if hasattr(self, 'port'): - delattr(self, 'port') + if hasattr(self, "port"): + delattr(self, "port") def write_with_content_len(self, msg): - self.log.append('write: %s' % (msg,)) + self.log.append("write: %s" % (msg,)) if SHOW_WRITES_AND_READS: - print('Test Writer Thread Written %s' % (msg,)) + print("Test Writer Thread Written %s" % (msg,)) - if not hasattr(self, 'sock'): - print('%s.sock not available when sending: %s' % (self, msg)) + if not hasattr(self, "sock"): + print("%s.sock not available when sending: %s" % (self, msg)) return if not isinstance(msg, bytes): - msg = msg.encode('utf-8') + msg = msg.encode("utf-8") - self.sock.sendall((u'Content-Length: %s\r\n\r\n' % len(msg)).encode('ascii')) + self.sock.sendall(("Content-Length: %s\r\n\r\n" % len(msg)).encode("ascii")) self.sock.sendall(msg) - _WRITE_LOG_PREFIX = 'write: ' + _WRITE_LOG_PREFIX = "write: " def write(self, s): from _pydevd_bundle.pydevd_comm import ID_TO_MEANING - meaning = ID_TO_MEANING.get(re.search(r'\d+', s).group(), '') - if meaning: - meaning += ': ' - self.log.append(self._WRITE_LOG_PREFIX + '%s%s' % (meaning, s,)) + meaning = ID_TO_MEANING.get(re.search(r"\d+", s).group(), "") + if meaning: + meaning += ": " + + self.log.append( + self._WRITE_LOG_PREFIX + + "%s%s" + % ( + meaning, + s, + ) + ) if SHOW_WRITES_AND_READS: - print('Test Writer Thread Written %s%s' % (meaning, s,)) - msg = s + '\n' + print( + "Test Writer Thread Written %s%s" + % ( + meaning, + s, + ) + ) + msg = s + "\n" - if not hasattr(self, 'sock'): - print('%s.sock not available when sending: %s' % (self, msg)) + if not hasattr(self, "sock"): + print("%s.sock not available when sending: %s" % (self, msg)) return - msg = msg.encode('utf-8') + msg = msg.encode("utf-8") self.sock.send(msg) @@ -843,10 +898,11 @@ def get_next_message(self, context_message, timeout=None): return self.reader_thread.get_next_message(context_message, timeout=timeout) def start_socket(self, port=None): - assert not hasattr(self, 'port'), 'Socket already initialized.' + assert not hasattr(self, "port"), "Socket already initialized." from _pydev_bundle.pydev_localhost import get_socket_name + if SHOW_WRITES_AND_READS: - print('start_socket') + print("start_socket") self._sequence = -1 if port is None: @@ -859,16 +915,16 @@ def start_socket(self, port=None): self.port = socket_name[1] server_socket.listen(1) if SHOW_WRITES_AND_READS: - print('Waiting in socket.accept()') + print("Waiting in socket.accept()") self.server_socket = server_socket new_socket, addr = server_socket.accept() if SHOW_WRITES_AND_READS: - print('Test Writer Thread Socket:', new_socket, addr) + print("Test Writer Thread Socket:", new_socket, addr) self._set_socket(new_socket) def _set_socket(self, new_socket): - curr_socket = getattr(self, 'sock', None) + curr_socket = getattr(self, "sock", None) if curr_socket: try: curr_socket.shutdown(socket.SHUT_WR) @@ -885,7 +941,7 @@ def _set_socket(self, new_socket): # initial command is always the version self.write_version() - self.log.append('start_socket') + self.log.append("start_socket") self.finished_initialization = True def start_socket_client(self, host, port): @@ -901,6 +957,7 @@ def start_socket_client(self, host, port): # and closes the connection after 5 failed ping (TCP_KEEPCNT), or 15 seconds try: from socket import IPPROTO_TCP, SO_KEEPALIVE, TCP_KEEPIDLE, TCP_KEEPINTVL, TCP_KEEPCNT + s.setsockopt(socket.SOL_SOCKET, SO_KEEPALIVE, 1) s.setsockopt(IPPROTO_TCP, TCP_KEEPIDLE, 1) s.setsockopt(IPPROTO_TCP, TCP_KEEPINTVL, 3) @@ -909,14 +966,14 @@ def start_socket_client(self, host, port): pass # May not be available everywhere. # 10 seconds default timeout - timeout = int(os.environ.get('PYDEVD_CONNECT_TIMEOUT', 10)) + timeout = int(os.environ.get("PYDEVD_CONNECT_TIMEOUT", 10)) s.settimeout(timeout) for _i in range(20): try: s.connect((host, port)) break except: - time.sleep(.5) # We may have to wait a bit more and retry (especially on PyPy). + time.sleep(0.5) # We may have to wait a bit more and retry (especially on PyPy). s.settimeout(None) # no timeout after connected if SHOW_WRITES_AND_READS: print("Connected.") @@ -933,9 +990,9 @@ def next_seq(self): def wait_for_new_thread(self): # wait for hit breakpoint - last = '' + last = "" while not ' splitted = last.split('"') @@ -946,14 +1003,14 @@ def wait_for_output(self): # Something as: # while True: - msg = self.get_next_message('wait_output') + msg = self.get_next_message("wait_output") if "' in last: - last = self.get_next_message('wait_for_get_next_statement_targets') + last = "" + while not "" in last: + last = self.get_next_message("wait_for_get_next_statement_targets") matches = re.finditer(r"(([0-9]*)<\/line>)", last, re.IGNORECASE) lines = [] @@ -1048,9 +1104,9 @@ def wait_for_get_next_statement_targets(self): def wait_for_custom_operation(self, expected): # wait for custom operation response, the response is double encoded expected_encoded = quote(quote_plus(expected)) - last = '' + last = "" while not expected_encoded in last: - last = self.get_next_message('wait_for_custom_operation. Expected (encoded): %s' % (expected_encoded,)) + last = self.get_next_message("wait_for_custom_operation. Expected (encoded): %s" % (expected_encoded,)) return True @@ -1078,14 +1134,22 @@ def wait_for_multiple_vars(self, expected_vars): while True: try: - last = self.get_next_message('wait_for_multiple_vars: %s' % (expected_vars,)) + last = self.get_next_message("wait_for_multiple_vars: %s" % (expected_vars,)) except: missing = [] for v in expected_vars: if v not in all_found: missing.append(v) - raise ValueError('Not Found:\n%s\nNot found messages: %s\nFound messages: %s\nExpected messages: %s\nIgnored messages:\n%s' % ( - '\n'.join(str(x) for x in missing), len(missing), len(all_found), len(expected_vars), '\n'.join(str(x) for x in ignored))) + raise ValueError( + "Not Found:\n%s\nNot found messages: %s\nFound messages: %s\nExpected messages: %s\nIgnored messages:\n%s" + % ( + "\n".join(str(x) for x in missing), + len(missing), + len(all_found), + len(expected_vars), + "\n".join(str(x) for x in ignored), + ) + ) was_message_used = False new_expected = [] @@ -1121,7 +1185,7 @@ def wait_for_multiple_vars(self, expected_vars): def write_make_initial_run(self): self.write("101\t%s\t" % self.next_seq()) - self.log.append('write_make_initial_run') + self.log.append("write_make_initial_run") def write_set_protocol(self, protocol): self.write("%s\t%s\t%s" % (CMD_SET_PROTOCOL, self.next_seq(), protocol)) @@ -1130,11 +1194,12 @@ def write_authenticate(self, access_token, client_access_token): msg = "%s\t%s\t%s" % (CMD_AUTHENTICATE, self.next_seq(), access_token) self.write(msg) - self.wait_for_message(lambda msg:client_access_token in msg, expect_xml=False) + self.wait_for_message(lambda msg: client_access_token in msg, expect_xml=False) def write_version(self): from _pydevd_bundle.pydevd_constants import IS_WINDOWS - self.write("%s\t%s\t1.0\t%s\tID" % (CMD_VERSION, self.next_seq(), 'WINDOWS' if IS_WINDOWS else 'UNIX')) + + self.write("%s\t%s\t1.0\t%s\tID" % (CMD_VERSION, self.next_seq(), "WINDOWS" if IS_WINDOWS else "UNIX")) def get_main_filename(self): return self.TEST_FILE @@ -1142,40 +1207,60 @@ def get_main_filename(self): def write_show_return_vars(self, show=1): self.write("%s\t%s\tCMD_SHOW_RETURN_VALUES\t%s" % (CMD_SHOW_RETURN_VALUES, self.next_seq(), show)) - def write_add_breakpoint(self, line, func='None', filename=None, hit_condition=None, is_logpoint=False, suspend_policy=None, condition=None): - ''' + def write_add_breakpoint( + self, line, func="None", filename=None, hit_condition=None, is_logpoint=False, suspend_policy=None, condition=None + ): + """ :param line: starts at 1 :param func: if None, may hit in any context, empty string only top level, otherwise must be method name. - ''' + """ if filename is None: filename = self.get_main_filename() breakpoint_id = self.next_breakpoint_id() if hit_condition is None and not is_logpoint and suspend_policy is None and condition is None: # Format kept for backward compatibility tests - self.write("%s\t%s\t%s\t%s\t%s\t%s\t%s\tNone\tNone" % ( - CMD_SET_BREAK, self.next_seq(), breakpoint_id, 'python-line', filename, line, func)) + self.write( + "%s\t%s\t%s\t%s\t%s\t%s\t%s\tNone\tNone" + % (CMD_SET_BREAK, self.next_seq(), breakpoint_id, "python-line", filename, line, func) + ) else: # Format: breakpoint_id, type, file, line, func_name, condition, expression, hit_condition, is_logpoint, suspend_policy - self.write("%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\tNone\t%s\t%s\t%s" % ( - CMD_SET_BREAK, self.next_seq(), breakpoint_id, 'python-line', filename, line, func, condition, hit_condition, is_logpoint, suspend_policy)) - self.log.append('write_add_breakpoint: %s line: %s func: %s' % (breakpoint_id, line, func)) + self.write( + "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\tNone\t%s\t%s\t%s" + % ( + CMD_SET_BREAK, + self.next_seq(), + breakpoint_id, + "python-line", + filename, + line, + func, + condition, + hit_condition, + is_logpoint, + suspend_policy, + ) + ) + self.log.append("write_add_breakpoint: %s line: %s func: %s" % (breakpoint_id, line, func)) return breakpoint_id def write_multi_threads_single_notification(self, multi_threads_single_notification): - self.write_json_config(dict( - multi_threads_single_notification=multi_threads_single_notification, - )) + self.write_json_config( + dict( + multi_threads_single_notification=multi_threads_single_notification, + ) + ) def write_suspend_on_breakpoint_exception(self, skip_suspend_on_breakpoint_exception, skip_print_breakpoint_exception): - self.write_json_config(dict( - skip_suspend_on_breakpoint_exception=skip_suspend_on_breakpoint_exception, - skip_print_breakpoint_exception=skip_print_breakpoint_exception - )) + self.write_json_config( + dict( + skip_suspend_on_breakpoint_exception=skip_suspend_on_breakpoint_exception, + skip_print_breakpoint_exception=skip_print_breakpoint_exception, + ) + ) def write_json_config(self, config_dict): - self.write("%s\t%s\t%s" % (CMD_PYDEVD_JSON_CONFIG, self.next_seq(), - json.dumps(config_dict) - )) + self.write("%s\t%s\t%s" % (CMD_PYDEVD_JSON_CONFIG, self.next_seq(), json.dumps(config_dict))) def write_stop_on_start(self, stop=True): self.write("%s\t%s\t%s" % (CMD_STOP_ON_START, self.next_seq(), stop)) @@ -1185,132 +1270,256 @@ def write_dump_threads(self): def write_add_exception_breakpoint(self, exception): self.write("%s\t%s\t%s" % (CMD_ADD_EXCEPTION_BREAK, self.next_seq(), exception)) - self.log.append('write_add_exception_breakpoint: %s' % (exception,)) + self.log.append("write_add_exception_breakpoint: %s" % (exception,)) def write_get_current_exception(self, thread_id): self.write("%s\t%s\t%s" % (CMD_GET_EXCEPTION_DETAILS, self.next_seq(), thread_id)) def write_set_py_exception_globals( - self, - break_on_uncaught, - break_on_caught, - skip_on_exceptions_thrown_in_same_context, - ignore_exceptions_thrown_in_lines_with_ignore_exception, - ignore_libraries, - exceptions=() - ): + self, + break_on_uncaught, + break_on_caught, + skip_on_exceptions_thrown_in_same_context, + ignore_exceptions_thrown_in_lines_with_ignore_exception, + ignore_libraries, + exceptions=(), + ): # Only set the globals, others - self.write("131\t%s\t%s" % (self.next_seq(), '%s;%s;%s;%s;%s;%s' % ( - 'true' if break_on_uncaught else 'false', - 'true' if break_on_caught else 'false', - 'true' if skip_on_exceptions_thrown_in_same_context else 'false', - 'true' if ignore_exceptions_thrown_in_lines_with_ignore_exception else 'false', - 'true' if ignore_libraries else 'false', - ';'.join(exceptions) - ))) - self.log.append('write_set_py_exception_globals') + self.write( + "131\t%s\t%s" + % ( + self.next_seq(), + "%s;%s;%s;%s;%s;%s" + % ( + "true" if break_on_uncaught else "false", + "true" if break_on_caught else "false", + "true" if skip_on_exceptions_thrown_in_same_context else "false", + "true" if ignore_exceptions_thrown_in_lines_with_ignore_exception else "false", + "true" if ignore_libraries else "false", + ";".join(exceptions), + ), + ) + ) + self.log.append("write_set_py_exception_globals") def write_start_redirect(self): - self.write("%s\t%s\t%s" % (CMD_REDIRECT_OUTPUT, self.next_seq(), 'STDERR STDOUT')) + self.write("%s\t%s\t%s" % (CMD_REDIRECT_OUTPUT, self.next_seq(), "STDERR STDOUT")) def write_set_project_roots(self, project_roots): - self.write("%s\t%s\t%s" % (CMD_SET_PROJECT_ROOTS, self.next_seq(), '\t'.join(str(x) for x in project_roots))) + self.write("%s\t%s\t%s" % (CMD_SET_PROJECT_ROOTS, self.next_seq(), "\t".join(str(x) for x in project_roots))) def write_add_exception_breakpoint_with_policy( - self, exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries): - self.write("%s\t%s\t%s" % (CMD_ADD_EXCEPTION_BREAK, self.next_seq(), '\t'.join(str(x) for x in [ - exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries]))) - self.log.append('write_add_exception_breakpoint: %s' % (exception,)) + self, exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries + ): + self.write( + "%s\t%s\t%s" + % ( + CMD_ADD_EXCEPTION_BREAK, + self.next_seq(), + "\t".join(str(x) for x in [exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries]), + ) + ) + self.log.append("write_add_exception_breakpoint: %s" % (exception,)) def write_remove_exception_breakpoint(self, exception): - self.write('%s\t%s\t%s' % (CMD_REMOVE_EXCEPTION_BREAK, self.next_seq(), exception)) + self.write("%s\t%s\t%s" % (CMD_REMOVE_EXCEPTION_BREAK, self.next_seq(), exception)) def write_remove_breakpoint(self, breakpoint_id): - self.write("%s\t%s\t%s\t%s\t%s" % ( - CMD_REMOVE_BREAK, self.next_seq(), 'python-line', self.get_main_filename(), breakpoint_id)) + self.write("%s\t%s\t%s\t%s\t%s" % (CMD_REMOVE_BREAK, self.next_seq(), "python-line", self.get_main_filename(), breakpoint_id)) def write_change_variable(self, thread_id, frame_id, varname, value): - self.write("%s\t%s\t%s\t%s\t%s\t%s\t%s" % ( - CMD_CHANGE_VARIABLE, self.next_seq(), thread_id, frame_id, 'FRAME', varname, value)) + self.write("%s\t%s\t%s\t%s\t%s\t%s\t%s" % (CMD_CHANGE_VARIABLE, self.next_seq(), thread_id, frame_id, "FRAME", varname, value)) def write_get_frame(self, thread_id, frame_id): self.write("%s\t%s\t%s\t%s\tFRAME" % (CMD_GET_FRAME, self.next_seq(), thread_id, frame_id)) - self.log.append('write_get_frame') + self.log.append("write_get_frame") def write_get_variable(self, thread_id, frame_id, var_attrs): self.write("%s\t%s\t%s\t%s\tFRAME\t%s" % (CMD_GET_VARIABLE, self.next_seq(), thread_id, frame_id, var_attrs)) def write_step_over(self, thread_id): - self.write("%s\t%s\t%s" % (CMD_STEP_OVER, self.next_seq(), thread_id,)) + self.write( + "%s\t%s\t%s" + % ( + CMD_STEP_OVER, + self.next_seq(), + thread_id, + ) + ) def write_step_in(self, thread_id): - self.write("%s\t%s\t%s" % (CMD_STEP_INTO, self.next_seq(), thread_id,)) + self.write( + "%s\t%s\t%s" + % ( + CMD_STEP_INTO, + self.next_seq(), + thread_id, + ) + ) def write_step_in_my_code(self, thread_id): - self.write("%s\t%s\t%s" % (CMD_STEP_INTO_MY_CODE, self.next_seq(), thread_id,)) + self.write( + "%s\t%s\t%s" + % ( + CMD_STEP_INTO_MY_CODE, + self.next_seq(), + thread_id, + ) + ) def write_step_return(self, thread_id): - self.write("%s\t%s\t%s" % (CMD_STEP_RETURN, self.next_seq(), thread_id,)) + self.write( + "%s\t%s\t%s" + % ( + CMD_STEP_RETURN, + self.next_seq(), + thread_id, + ) + ) def write_step_return_my_code(self, thread_id): - self.write("%s\t%s\t%s" % (CMD_STEP_RETURN_MY_CODE, self.next_seq(), thread_id,)) + self.write( + "%s\t%s\t%s" + % ( + CMD_STEP_RETURN_MY_CODE, + self.next_seq(), + thread_id, + ) + ) def write_step_over_my_code(self, thread_id): - self.write("%s\t%s\t%s" % (CMD_STEP_OVER_MY_CODE, self.next_seq(), thread_id,)) + self.write( + "%s\t%s\t%s" + % ( + CMD_STEP_OVER_MY_CODE, + self.next_seq(), + thread_id, + ) + ) def write_suspend_thread(self, thread_id): - self.write("%s\t%s\t%s" % (CMD_THREAD_SUSPEND, self.next_seq(), thread_id,)) + self.write( + "%s\t%s\t%s" + % ( + CMD_THREAD_SUSPEND, + self.next_seq(), + thread_id, + ) + ) def write_reload(self, module_name): - self.log.append('write_reload') - self.write("%s\t%s\t%s" % (CMD_RELOAD_CODE, self.next_seq(), module_name,)) + self.log.append("write_reload") + self.write( + "%s\t%s\t%s" + % ( + CMD_RELOAD_CODE, + self.next_seq(), + module_name, + ) + ) def write_run_thread(self, thread_id): - self.log.append('write_run_thread') - self.write("%s\t%s\t%s" % (CMD_THREAD_RUN, self.next_seq(), thread_id,)) + self.log.append("write_run_thread") + self.write( + "%s\t%s\t%s" + % ( + CMD_THREAD_RUN, + self.next_seq(), + thread_id, + ) + ) def write_get_thread_stack(self, thread_id): - self.log.append('write_get_thread_stack') - self.write("%s\t%s\t%s" % (CMD_GET_THREAD_STACK, self.next_seq(), thread_id,)) + self.log.append("write_get_thread_stack") + self.write( + "%s\t%s\t%s" + % ( + CMD_GET_THREAD_STACK, + self.next_seq(), + thread_id, + ) + ) def write_load_source(self, filename): - self.log.append('write_load_source') - self.write("%s\t%s\t%s" % (CMD_LOAD_SOURCE, self.next_seq(), filename,)) + self.log.append("write_load_source") + self.write( + "%s\t%s\t%s" + % ( + CMD_LOAD_SOURCE, + self.next_seq(), + filename, + ) + ) def write_load_source_from_frame_id(self, frame_id): from _pydevd_bundle.pydevd_comm_constants import CMD_LOAD_SOURCE_FROM_FRAME_ID - self.log.append('write_load_source_from_frame_id') - self.write("%s\t%s\t%s" % (CMD_LOAD_SOURCE_FROM_FRAME_ID, self.next_seq(), frame_id,)) + + self.log.append("write_load_source_from_frame_id") + self.write( + "%s\t%s\t%s" + % ( + CMD_LOAD_SOURCE_FROM_FRAME_ID, + self.next_seq(), + frame_id, + ) + ) def write_kill_thread(self, thread_id): - self.write("%s\t%s\t%s" % (CMD_THREAD_KILL, self.next_seq(), thread_id,)) + self.write( + "%s\t%s\t%s" + % ( + CMD_THREAD_KILL, + self.next_seq(), + thread_id, + ) + ) def write_set_next_statement(self, thread_id, line, func_name): - self.write("%s\t%s\t%s\t%s\t%s" % (CMD_SET_NEXT_STATEMENT, self.next_seq(), thread_id, line, func_name,)) + self.write( + "%s\t%s\t%s\t%s\t%s" + % ( + CMD_SET_NEXT_STATEMENT, + self.next_seq(), + thread_id, + line, + func_name, + ) + ) def write_smart_step_into(self, thread_id, line, func_name): - self.write("%s\t%s\t%s\t%s\t%s" % (CMD_SMART_STEP_INTO, self.next_seq(), thread_id, line, func_name,)) + self.write( + "%s\t%s\t%s\t%s\t%s" + % ( + CMD_SMART_STEP_INTO, + self.next_seq(), + thread_id, + line, + func_name, + ) + ) def write_debug_console_expression(self, locator): self.write("%s\t%s\t%s" % (CMD_EVALUATE_CONSOLE_EXPRESSION, self.next_seq(), locator)) def write_custom_operation(self, locator, style, codeOrFile, operation_fn_name): - self.write("%s\t%s\t%s||%s\t%s\t%s" % ( - CMD_RUN_CUSTOM_OPERATION, self.next_seq(), locator, style, quote_plus(codeOrFile), operation_fn_name)) + self.write( + "%s\t%s\t%s||%s\t%s\t%s" + % (CMD_RUN_CUSTOM_OPERATION, self.next_seq(), locator, style, quote_plus(codeOrFile), operation_fn_name) + ) def write_evaluate_expression(self, locator, expression): self.write("%s\t%s\t%s\t%s\t1" % (CMD_EVALUATE_EXPRESSION, self.next_seq(), locator, expression)) def write_enable_dont_trace(self, enable): if enable: - enable = 'true' + enable = "true" else: - enable = 'false' + enable = "false" self.write("%s\t%s\t%s" % (CMD_ENABLE_DONT_TRACE, self.next_seq(), enable)) def write_get_next_statement_targets(self, thread_id, frame_id): self.write("201\t%s\t%s\t%s" % (self.next_seq(), thread_id, frame_id)) - self.log.append('write_get_next_statement_targets') + self.log.append("write_get_next_statement_targets") def write_list_threads(self): seq = self.next_seq() @@ -1318,7 +1527,7 @@ def write_list_threads(self): return seq def wait_for_list_threads(self, seq): - return self.wait_for_message('502') + return self.wait_for_message("502") def wait_for_get_thread_stack_message(self): return self.wait_for_message(CMD_GET_THREAD_STACK) @@ -1328,27 +1537,28 @@ def wait_for_curr_exc_stack(self): def wait_for_json_message(self, accept_message, unquote_msg=True, timeout=None): last = self.wait_for_message(accept_message, unquote_msg, expect_xml=False, timeout=timeout) - json_msg = last.split('\t', 2)[-1] # We have something as: CMD\tSEQ\tJSON + json_msg = last.split("\t", 2)[-1] # We have something as: CMD\tSEQ\tJSON if isinstance(json_msg, bytes): - json_msg = json_msg.decode('utf-8') + json_msg = json_msg.decode("utf-8") try: return json.loads(json_msg) except: traceback.print_exc() - raise AssertionError('Unable to parse:\n%s\njson:\n%s' % (last, json_msg)) + raise AssertionError("Unable to parse:\n%s\njson:\n%s" % (last, json_msg)) def wait_for_message(self, accept_message, unquote_msg=True, expect_xml=True, timeout=None, double_unquote=True): if isinstance(accept_message, (str, int)): - msg_starts_with = '%s\t' % (accept_message,) + msg_starts_with = "%s\t" % (accept_message,) def accept_message(msg): return msg.startswith(msg_starts_with) import untangle from io import StringIO + prev = None while True: - last = self.get_next_message('wait_for_message', timeout=timeout) + last = self.get_next_message("wait_for_message", timeout=timeout) if unquote_msg: last = unquote_plus(last) if double_unquote: @@ -1359,22 +1569,22 @@ def accept_message(msg): if accept_message(last): if expect_xml: # Extract xml and return untangled. - xml = '' + xml = "" try: - xml = last[last.index(''):] + xml = last[last.index("") :] if isinstance(xml, bytes): - xml = xml.decode('utf-8') + xml = xml.decode("utf-8") xml = untangle.parse(StringIO(xml)) except: traceback.print_exc() - raise AssertionError('Unable to parse:\n%s\nxml:\n%s' % (last, xml)) + raise AssertionError("Unable to parse:\n%s\nxml:\n%s" % (last, xml)) ret = xml.xml ret.original_xml = last return ret else: return last if prev != last: - sys.stderr.write('Ignored message: %r\n' % (last,)) + sys.stderr.write("Ignored message: %r\n" % (last,)) # Uncomment to know where in the stack it was ignored. # import traceback # traceback.print_stack(limit=7) @@ -1384,33 +1594,34 @@ def accept_message(msg): def wait_for_untangled_message(self, accept_message, timeout=None, double_unquote=False): import untangle from io import StringIO + prev = None while True: - last = self.get_next_message('wait_for_message', timeout=timeout) + last = self.get_next_message("wait_for_message", timeout=timeout) last = unquote_plus(last) if double_unquote: last = unquote_plus(last) # Extract xml with untangled. - xml = '' + xml = "" try: - xml = last[last.index(''):] + xml = last[last.index("") :] except: traceback.print_exc() - raise AssertionError('Unable to find xml in: %s' % (last,)) + raise AssertionError("Unable to find xml in: %s" % (last,)) try: if isinstance(xml, bytes): - xml = xml.decode('utf-8') + xml = xml.decode("utf-8") xml = untangle.parse(StringIO(xml)) except: traceback.print_exc() - raise AssertionError('Unable to parse:\n%s\nxml:\n%s' % (last, xml)) + raise AssertionError("Unable to parse:\n%s\nxml:\n%s" % (last, xml)) untangled = xml.xml - cmd_id = last.split('\t', 1)[0] + cmd_id = last.split("\t", 1)[0] if accept_message(int(cmd_id), untangled): return untangled if prev != last: - print('Ignored message: %r' % (last,)) + print("Ignored message: %r" % (last,)) prev = last @@ -1418,46 +1629,45 @@ def get_frame_names(self, thread_id): self.write_get_thread_stack(thread_id) msg = self.wait_for_message(CMD_GET_THREAD_STACK) if msg.thread.frame: - frame_names = [frame['name'] for frame in msg.thread.frame] + frame_names = [frame["name"] for frame in msg.thread.frame] return frame_names - return [msg.thread.frame['name']] + return [msg.thread.frame["name"]] def get_step_into_variants(self, thread_id, frame_id, start_line, end_line): - self.write("%s\t%s\t%s\t%s\t%s\t%s" % (CMD_GET_SMART_STEP_INTO_VARIANTS, self.next_seq(), thread_id, frame_id, start_line, end_line)) + self.write( + "%s\t%s\t%s\t%s\t%s\t%s" % (CMD_GET_SMART_STEP_INTO_VARIANTS, self.next_seq(), thread_id, frame_id, start_line, end_line) + ) msg = self.wait_for_message(CMD_GET_SMART_STEP_INTO_VARIANTS) if msg.variant: variant_info = [ - (variant['name'], variant['isVisited'], variant['line'], variant['callOrder'], variant['offset'], variant['childOffset']) + (variant["name"], variant["isVisited"], variant["line"], variant["callOrder"], variant["offset"], variant["childOffset"]) for variant in msg.variant ] return variant_info return [] def wait_for_thread_join(self, main_thread_id): - def condition(): return self.get_frame_names(main_thread_id) in ( - ['wait', 'join', ''], - ['_wait_for_tstate_lock', 'join', ''], - ['_wait_for_tstate_lock', 'join', '', '_run_code', '_run_module_code', 'run_path'], + ["wait", "join", ""], + ["_wait_for_tstate_lock", "join", ""], + ["_wait_for_tstate_lock", "join", "", "_run_code", "_run_module_code", "run_path"], ) def msg(): - return 'Found stack: %s' % (self.get_frame_names(main_thread_id),) + return "Found stack: %s" % (self.get_frame_names(main_thread_id),) - wait_for_condition(condition, msg, timeout=5, sleep=.5) + wait_for_condition(condition, msg, timeout=5, sleep=0.5) def create_request_thread(self, full_url): - class T(threading.Thread): - def wait_for_contents(self): for _ in range(10): - if hasattr(self, 'contents'): + if hasattr(self, "contents"): break - time.sleep(.3) + time.sleep(0.3) else: - raise AssertionError('Unable to get contents from server. Url: %s' % (full_url,)) + raise AssertionError("Unable to get contents from server. Url: %s" % (full_url,)) return self.contents def run(self): @@ -1469,7 +1679,7 @@ def run(self): try: stream = urlopen(full_url) contents = stream.read() - contents = contents.decode('utf-8') + contents = contents.decode("utf-8") self.contents = contents break except IOError: @@ -1483,12 +1693,13 @@ def run(self): def _get_debugger_test_file(filename): ret = os.path.abspath(os.path.join(os.path.dirname(__file__), filename)) if not os.path.exists(ret): - ret = os.path.join(os.path.dirname(__file__), 'resources', filename) + ret = os.path.join(os.path.dirname(__file__), "resources", filename) if not os.path.exists(ret): - raise AssertionError('Expected: %s to exist.' % (ret,)) + raise AssertionError("Expected: %s to exist." % (ret,)) return ret def get_free_port(): from _pydev_bundle.pydev_localhost import get_socket_name + return get_socket_name(close=True)[1] diff --git a/tests_python/flask1/app.py b/tests_python/flask1/app.py index 2f4e4a258..9b2b44b6a 100644 --- a/tests_python/flask1/app.py +++ b/tests_python/flask1/app.py @@ -6,55 +6,40 @@ @app.route("/") def home(): - content = 'Flask-Jinja-Test' - return render_template( - "hello.html", - title='Hello', - content=content - ) + content = "Flask-Jinja-Test" + return render_template("hello.html", title="Hello", content=content) @app.route("/handled") def bad_route_handled(): try: - raise ArithmeticError('Hello') + raise ArithmeticError("Hello") except Exception: pass - return render_template( - "hello.html", - title='Hello', - content='Flask-Jinja-Test' - ) + return render_template("hello.html", title="Hello", content="Flask-Jinja-Test") @app.route("/unhandled") def bad_route_unhandled(): - raise ArithmeticError('Hello') - return render_template( - "hello.html", - title='Hello', - content='Flask-Jinja-Test' - ) + raise ArithmeticError("Hello") + return render_template("hello.html", title="Hello", content="Flask-Jinja-Test") @app.route("/bad_template") def bad_template(): - return render_template( - "bad.html", - title='Bad', - content='Flask-Jinja-Test' - ) + return render_template("bad.html", title="Bad", content="Flask-Jinja-Test") @app.route("/exit") def exit_app(): from flask import request - func = request.environ.get('werkzeug.server.shutdown') + + func = request.environ.get("werkzeug.server.shutdown") if func is None: - raise RuntimeError('No shutdown') + raise RuntimeError("No shutdown") func() - return 'Done' + return "Done" -if __name__ == '__main__': +if __name__ == "__main__": app.run() diff --git a/tests_python/my_extensions/pydevd_plugins/__init__.py b/tests_python/my_extensions/pydevd_plugins/__init__.py index bb61062c9..f77af49c2 100644 --- a/tests_python/my_extensions/pydevd_plugins/__init__.py +++ b/tests_python/my_extensions/pydevd_plugins/__init__.py @@ -1,2 +1,3 @@ import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/tests_python/my_extensions/pydevd_plugins/extensions/__init__.py b/tests_python/my_extensions/pydevd_plugins/extensions/__init__.py index bb61062c9..f77af49c2 100644 --- a/tests_python/my_extensions/pydevd_plugins/extensions/__init__.py +++ b/tests_python/my_extensions/pydevd_plugins/extensions/__init__.py @@ -1,2 +1,3 @@ import pkgutil + __path__ = pkgutil.extend_path(__path__, __name__) diff --git a/tests_python/my_extensions/pydevd_plugins/extensions/pydevd_plugin_test_events.py b/tests_python/my_extensions/pydevd_plugins/extensions/pydevd_plugin_test_events.py index 71c1ef9cd..54133f3e7 100644 --- a/tests_python/my_extensions/pydevd_plugins/extensions/pydevd_plugin_test_events.py +++ b/tests_python/my_extensions/pydevd_plugins/extensions/pydevd_plugin_test_events.py @@ -5,13 +5,13 @@ class VerifyEvent(object): def on_debugger_modules_loaded(self, **kwargs): - print ("INITIALIZE EVENT RECEIVED") + print("INITIALIZE EVENT RECEIVED") # check that some core modules are loaded before this callback is invoked - modules_loaded = all(mod in sys.modules for mod in ('pydevd_file_utils', '_pydevd_bundle.pydevd_constants')) + modules_loaded = all(mod in sys.modules for mod in ("pydevd_file_utils", "_pydevd_bundle.pydevd_constants")) if modules_loaded: - print ("TEST SUCEEDED") # incorrect spelling on purpose + print("TEST SUCEEDED") # incorrect spelling on purpose else: - print ("TEST FAILED") + print("TEST FAILED") if os.environ.get("VERIFY_EVENT_TEST"): diff --git a/tests_python/my_extensions/pydevd_plugins/extensions/pydevd_plugin_test_exttype.py b/tests_python/my_extensions/pydevd_plugins/extensions/pydevd_plugin_test_exttype.py index c3a7f7832..40af39147 100644 --- a/tests_python/my_extensions/pydevd_plugins/extensions/pydevd_plugin_test_exttype.py +++ b/tests_python/my_extensions/pydevd_plugins/extensions/pydevd_plugin_test_exttype.py @@ -3,13 +3,13 @@ class RectResolver(TypeResolveProvider): def get_dictionary(self, var): - return {'length': var.length, 'width': var.width, 'area': var.length * var.width} + return {"length": var.length, "width": var.width, "area": var.length * var.width} def resolve(self, var, attribute): - return getattr(var, attribute, None) if attribute != 'area' else var.length * var.width + return getattr(var, attribute, None) if attribute != "area" else var.length * var.width def can_provide(self, type_object, type_name): - return type_name.endswith('Rect') + return type_name.endswith("Rect") class RectToString(StrPresentationProvider): @@ -17,4 +17,4 @@ def get_str(self, val): return "Rectangle[Length: %s, Width: %s , Area: %s]" % (val.length, val.width, val.length * val.width) def can_provide(self, type_object, type_name): - return type_name.endswith('Rect') + return type_name.endswith("Rect") diff --git a/tests_python/performance_check.py b/tests_python/performance_check.py index ef4523244..069775eb1 100644 --- a/tests_python/performance_check.py +++ b/tests_python/performance_check.py @@ -3,17 +3,16 @@ import re import os -CHECK_BASELINE, CHECK_REGULAR, CHECK_CYTHON, CHECK_FRAME_EVAL = 'baseline', 'regular', 'cython', 'frame_eval' +CHECK_BASELINE, CHECK_REGULAR, CHECK_CYTHON, CHECK_FRAME_EVAL = "baseline", "regular", "cython", "frame_eval" pytest_plugins = [ - str('tests_python.debugger_fixtures'), + str("tests_python.debugger_fixtures"), ] RUNS = 5 class PerformanceWriterThread(debugger_unittest.AbstractWriterThread): - CHECK = None debugger_unittest.AbstractWriterThread.get_environ # overrides @@ -21,19 +20,19 @@ class PerformanceWriterThread(debugger_unittest.AbstractWriterThread): def get_environ(self): env = os.environ.copy() if self.CHECK == CHECK_BASELINE: - env['PYTHONPATH'] = r'X:\PyDev.Debugger.baseline' + env["PYTHONPATH"] = r"X:\PyDev.Debugger.baseline" elif self.CHECK == CHECK_CYTHON: - env['PYDEVD_USE_CYTHON'] = 'YES' - env['PYDEVD_USE_FRAME_EVAL'] = 'NO' + env["PYDEVD_USE_CYTHON"] = "YES" + env["PYDEVD_USE_FRAME_EVAL"] = "NO" elif self.CHECK == CHECK_FRAME_EVAL: - env['PYDEVD_USE_CYTHON'] = 'YES' - env['PYDEVD_USE_FRAME_EVAL'] = 'YES' + env["PYDEVD_USE_CYTHON"] = "YES" + env["PYDEVD_USE_FRAME_EVAL"] = "YES" elif self.CHECK == CHECK_REGULAR: - env['PYDEVD_USE_CYTHON'] = 'NO' - env['PYDEVD_USE_FRAME_EVAL'] = 'NO' + env["PYDEVD_USE_CYTHON"] = "NO" + env["PYDEVD_USE_FRAME_EVAL"] = "NO" else: raise AssertionError("Don't know what to check.") @@ -43,24 +42,22 @@ def get_environ(self): def get_pydevd_file(self): if self.CHECK == CHECK_BASELINE: - return os.path.abspath(os.path.join(r'X:\PyDev.Debugger.baseline', 'pydevd.py')) + return os.path.abspath(os.path.join(r"X:\PyDev.Debugger.baseline", "pydevd.py")) dirname = os.path.dirname(__file__) dirname = os.path.dirname(dirname) - return os.path.abspath(os.path.join(dirname, 'pydevd.py')) + return os.path.abspath(os.path.join(dirname, "pydevd.py")) class CheckDebuggerPerformance(debugger_unittest.DebuggerRunner): - def get_command_line(self): return [sys.executable] def _get_time_from_result(self, stdout): - match = re.search(r'TotalTime>>((\d|\.)+)<<', stdout) + match = re.search(r"TotalTime>>((\d|\.)+)<<", stdout) time_taken = match.group(1) return float(time_taken) def obtain_results(self, benchmark_name, filename): - class PerformanceCheck(PerformanceWriterThread): TEST_FILE = debugger_unittest._get_debugger_test_file(filename) BENCHMARK_NAME = benchmark_name @@ -81,7 +78,7 @@ def store_stdout(stdout, stderr): assert len(stdout_ref) == 1 all_times.append(self._get_time_from_result(stdout_ref[0])) - print('partial for: %s: %.3fs' % (writer_thread_class.BENCHMARK_NAME, all_times[-1])) + print("partial for: %s: %.3fs" % (writer_thread_class.BENCHMARK_NAME, all_times[-1])) if len(all_times) > 3: all_times.remove(min(all_times)) all_times.remove(max(all_times)) @@ -92,13 +89,13 @@ def store_stdout(stdout, stderr): # regular_time = self._get_time_from_result(self.run_process(args, writer_thread=None)) # simple_trace_time = self._get_time_from_result(self.run_process(args+['--regular-trace'], writer_thread=None)) - if 'SPEEDTIN_AUTHORIZATION_KEY' in os.environ: - - SPEEDTIN_AUTHORIZATION_KEY = os.environ['SPEEDTIN_AUTHORIZATION_KEY'] + if "SPEEDTIN_AUTHORIZATION_KEY" in os.environ: + SPEEDTIN_AUTHORIZATION_KEY = os.environ["SPEEDTIN_AUTHORIZATION_KEY"] # sys.path.append(r'X:\speedtin\pyspeedtin') import pyspeedtin # If the authorization key is there, pyspeedtin must be available import pydevd + pydevd_cython_project_id, pydevd_pure_python_project_id = 6, 7 if writer_thread_class.CHECK == CHECK_BASELINE: project_ids = (pydevd_cython_project_id, pydevd_pure_python_project_id) @@ -107,17 +104,17 @@ def store_stdout(stdout, stderr): elif writer_thread_class.CHECK == CHECK_CYTHON: project_ids = (pydevd_cython_project_id,) else: - raise AssertionError('Wrong check: %s' % (writer_thread_class.CHECK)) + raise AssertionError("Wrong check: %s" % (writer_thread_class.CHECK)) for project_id in project_ids: api = pyspeedtin.PySpeedTinApi(authorization_key=SPEEDTIN_AUTHORIZATION_KEY, project_id=project_id) benchmark_name = writer_thread_class.BENCHMARK_NAME if writer_thread_class.CHECK == CHECK_BASELINE: - version = '0.0.1_baseline' + version = "0.0.1_baseline" return # No longer commit the baseline (it's immutable right now). else: - version = pydevd.__version__, + version = (pydevd.__version__,) commit_id, branch, commit_date = api.git_commit_id_branch_and_date_from_path(pydevd.__file__) api.add_benchmark(benchmark_name) @@ -132,32 +129,32 @@ def store_stdout(stdout, stderr): ) api.commit() - self.performance_msg = '%s: %.3fs ' % (writer_thread_class.BENCHMARK_NAME, time_when_debugged) + self.performance_msg = "%s: %.3fs " % (writer_thread_class.BENCHMARK_NAME, time_when_debugged) def method_calls_with_breakpoint(self): - for writer in self.obtain_results('method_calls_with_breakpoint', '_performance_1.py'): - writer.write_add_breakpoint(17, 'method') + for writer in self.obtain_results("method_calls_with_breakpoint", "_performance_1.py"): + writer.write_add_breakpoint(17, "method") writer.write_make_initial_run() writer.finished_ok = True return self.performance_msg def method_calls_without_breakpoint(self): - for writer in self.obtain_results('method_calls_without_breakpoint', '_performance_1.py'): + for writer in self.obtain_results("method_calls_without_breakpoint", "_performance_1.py"): writer.write_make_initial_run() writer.finished_ok = True return self.performance_msg def method_calls_with_step_over(self): - for writer in self.obtain_results('method_calls_with_step_over', '_performance_1.py'): + for writer in self.obtain_results("method_calls_with_step_over", "_performance_1.py"): writer.write_add_breakpoint(26, None) writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') + hit = writer.wait_for_breakpoint_hit("111") writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('108') + hit = writer.wait_for_breakpoint_hit("108") writer.write_run_thread(hit.thread_id) writer.finished_ok = True @@ -165,23 +162,23 @@ def method_calls_with_step_over(self): return self.performance_msg def method_calls_with_exception_breakpoint(self): - for writer in self.obtain_results('method_calls_with_exception_breakpoint', '_performance_1.py'): - writer.write_add_exception_breakpoint('ValueError') + for writer in self.obtain_results("method_calls_with_exception_breakpoint", "_performance_1.py"): + writer.write_add_exception_breakpoint("ValueError") writer.write_make_initial_run() writer.finished_ok = True return self.performance_msg def global_scope_1_with_breakpoint(self): - for writer in self.obtain_results('global_scope_1_with_breakpoint', '_performance_2.py'): - writer.write_add_breakpoint(writer.get_line_index_with_content('Breakpoint here'), None) + for writer in self.obtain_results("global_scope_1_with_breakpoint", "_performance_2.py"): + writer.write_add_breakpoint(writer.get_line_index_with_content("Breakpoint here"), None) writer.write_make_initial_run() writer.finished_ok = True return self.performance_msg def global_scope_2_with_breakpoint(self): - for writer in self.obtain_results('global_scope_2_with_breakpoint', '_performance_3.py'): + for writer in self.obtain_results("global_scope_2_with_breakpoint", "_performance_3.py"): writer.write_add_breakpoint(17, None) writer.write_make_initial_run() writer.finished_ok = True @@ -189,7 +186,7 @@ def global_scope_2_with_breakpoint(self): return self.performance_msg -if __name__ == '__main__': +if __name__ == "__main__": # Python 3.10 # Checking: regular # method_calls_with_breakpoint: 0.160s @@ -257,20 +254,21 @@ def global_scope_2_with_breakpoint(self): debugger_unittest.SHOW_STDOUT = False import time + start_time = time.time() tmpdir = None msgs = [] for check in ( - # CHECK_BASELINE, -- Checks against the version checked out at X:\PyDev.Debugger.baseline. - CHECK_REGULAR, - CHECK_CYTHON, - # CHECK_FRAME_EVAL, - ): + # CHECK_BASELINE, -- Checks against the version checked out at X:\PyDev.Debugger.baseline. + CHECK_REGULAR, + CHECK_CYTHON, + # CHECK_FRAME_EVAL, + ): partial_time = time.time() PerformanceWriterThread.CHECK = check - msgs.append('Checking: %s' % (check,)) + msgs.append("Checking: %s" % (check,)) check_debugger_performance = CheckDebuggerPerformance(tmpdir) msgs.append(check_debugger_performance.method_calls_with_breakpoint()) msgs.append(check_debugger_performance.method_calls_without_breakpoint()) @@ -278,9 +276,8 @@ def global_scope_2_with_breakpoint(self): msgs.append(check_debugger_performance.method_calls_with_exception_breakpoint()) msgs.append(check_debugger_performance.global_scope_1_with_breakpoint()) msgs.append(check_debugger_performance.global_scope_2_with_breakpoint()) - msgs.append('Partial profile time: %.2fs' % (time.time() - partial_time,)) + msgs.append("Partial profile time: %.2fs" % (time.time() - partial_time,)) for msg in msgs: print(msg) - print('TotalTime for profile: %.2fs' % (time.time() - start_time,)) - + print("TotalTime for profile: %.2fs" % (time.time() - start_time,)) diff --git a/tests_python/regression_check.py b/tests_python/regression_check.py index a7dc74f8a..8140bf0c4 100644 --- a/tests_python/regression_check.py +++ b/tests_python/regression_check.py @@ -21,6 +21,7 @@ def original_datadir(request): # Method from: https://github.com/gabrielcnr/pytest-datadir # License: MIT import os.path + return Path(os.path.splitext(request.module.__file__)[0]) @@ -29,6 +30,7 @@ def datadir(original_datadir, tmpdir): # Method from: https://github.com/gabrielcnr/pytest-datadir # License: MIT import shutil + result = Path(str(tmpdir.join(original_datadir.stem))) if original_datadir.is_dir(): shutil.copytree(str(original_datadir), str(result)) @@ -153,16 +155,12 @@ def make_location_message(banner, filename, aux_files): dump_fn(source_filename) aux_created = dump_aux_fn(source_filename) - msg = make_location_message( - "File not found in data directory, created:", source_filename, aux_created - ) + msg = make_location_message("File not found in data directory, created:", source_filename, aux_created) pytest.fail(msg) else: if obtained_filename is None: if fullpath: - obtained_filename = (datadir / basename).with_suffix( - ".obtained" + extension - ) + obtained_filename = (datadir / basename).with_suffix(".obtained" + extension) else: obtained_filename = filename.with_suffix(".obtained" + extension) @@ -220,10 +218,10 @@ def dump(filename): s = json.dumps(data_dict, sort_keys=True, indent=4) if isinstance(s, bytes): - s = s.decode('utf-8') + s = s.decode("utf-8") - s = u'\n'.join([line.rstrip() for line in s.splitlines()]) - s = s.encode('utf-8') + s = "\n".join([line.rstrip() for line in s.splitlines()]) + s = s.encode("utf-8") with filename.open("wb") as f: f.write(s) diff --git a/tests_python/resource_path_translation/other.py b/tests_python/resource_path_translation/other.py index 369a9b298..66d530126 100644 --- a/tests_python/resource_path_translation/other.py +++ b/tests_python/resource_path_translation/other.py @@ -1,6 +1,4 @@ - - def call_me_back1(callback): - a = 'other' + a = "other" callback() return a diff --git a/tests_python/test_additional_thread_info.py b/tests_python/test_additional_thread_info.py index 7852b8fe0..12e7d4b97 100644 --- a/tests_python/test_additional_thread_info.py +++ b/tests_python/test_additional_thread_info.py @@ -1,6 +1,7 @@ import sys import os from _pydev_bundle import pydev_monkey + sys.path.insert(0, os.path.split(os.path.split(__file__)[0])[0]) import unittest @@ -11,32 +12,32 @@ import _thread as thread # @UnresolvedImport -#======================================================================================================================= +# ======================================================================================================================= # TestCase -#======================================================================================================================= +# ======================================================================================================================= class TestCase(unittest.TestCase): - def test_start_new_thread(self): pydev_monkey.patch_thread_modules() try: found = {} def function(a, b, *args, **kwargs): - found['a'] = a - found['b'] = b - found['args'] = args - found['kwargs'] = kwargs + found["a"] = a + found["b"] = b + found["args"] = args + found["kwargs"] = kwargs - thread.start_new_thread(function, (1, 2, 3, 4), {'d':1, 'e':2}) + thread.start_new_thread(function, (1, 2, 3, 4), {"d": 1, "e": 2}) import time + for _i in range(20): if len(found) == 4: break - time.sleep(.1) + time.sleep(0.1) else: - raise AssertionError('Could not get to condition before 2 seconds') + raise AssertionError("Could not get to condition before 2 seconds") - self.assertEqual({'a': 1, 'b': 2, 'args': (3, 4), 'kwargs': {'e': 2, 'd': 1}}, found) + self.assertEqual({"a": 1, "b": 2, "args": (3, 4), "kwargs": {"e": 2, "d": 1}}, found) finally: pydev_monkey.undo_patch_thread_modules() @@ -50,33 +51,36 @@ class F(object): def start_it(self): try: - self.start_new_thread(self.function, (1, 2, 3, 4), {'d':1, 'e':2}) + self.start_new_thread(self.function, (1, 2, 3, 4), {"d": 1, "e": 2}) except: - import traceback;traceback.print_exc() + import traceback + + traceback.print_exc() def function(self, a, b, *args, **kwargs): - found['a'] = a - found['b'] = b - found['args'] = args - found['kwargs'] = kwargs + found["a"] = a + found["b"] = b + found["args"] = args + found["kwargs"] = kwargs f = F() f.start_it() import time + for _i in range(20): if len(found) == 4: break - time.sleep(.1) + time.sleep(0.1) else: - raise AssertionError('Could not get to condition before 2 seconds') + raise AssertionError("Could not get to condition before 2 seconds") - self.assertEqual({'a': 1, 'b': 2, 'args': (3, 4), 'kwargs': {'e': 2, 'd': 1}}, found) + self.assertEqual({"a": 1, "b": 2, "args": (3, 4), "kwargs": {"e": 2, "d": 1}}, found) finally: pydev_monkey.undo_patch_thread_modules() -#======================================================================================================================= +# ======================================================================================================================= # main -#======================================================================================================================= -if __name__ == '__main__': +# ======================================================================================================================= +if __name__ == "__main__": unittest.main() diff --git a/tests_python/test_bytecode_manipulation.py b/tests_python/test_bytecode_manipulation.py index 4f5ebb78a..3f1d5e712 100644 --- a/tests_python/test_bytecode_manipulation.py +++ b/tests_python/test_bytecode_manipulation.py @@ -5,19 +5,15 @@ import pytest -from tests_python.debug_constants import IS_PY36_OR_GREATER, IS_CPYTHON, TEST_CYTHON, \ - IS_PY311_OR_GREATER +from tests_python.debug_constants import IS_PY36_OR_GREATER, IS_CPYTHON, TEST_CYTHON, IS_PY311_OR_GREATER import dis pytestmark = pytest.mark.skipif( - not IS_PY36_OR_GREATER or - IS_PY311_OR_GREATER or - not IS_CPYTHON or - not TEST_CYTHON, reason='Requires CPython >= 3.6 < 3.11') + not IS_PY36_OR_GREATER or IS_PY311_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON, reason="Requires CPython >= 3.6 < 3.11" +) class _Tracer(object): - def __init__(self): self.stream = StringIO() self._in_print = False @@ -31,22 +27,24 @@ def tracer_printer(self, frame, event, arg): try: if self.accept_frame is None or self.accept_frame(frame): if arg is not None: - if event == 'exception': + if event == "exception": arg = arg[0].__name__ elif arg is not None: arg = str(arg) if arg is None: - arg = '' + arg = "" self.lines_executed.add(frame.f_lineno) - s = ' '.join(( - str(frame.f_lineno), - frame.f_code.co_name, - os.path.basename(frame.f_code.co_filename), - event.upper() if event != 'line' else event, - arg, - )) + s = " ".join( + ( + str(frame.f_lineno), + frame.f_code.co_name, + os.path.basename(frame.f_code.co_filename), + event.upper() if event != "line" else event, + arg, + ) + ) self.writeln(s) except: traceback.print_exc() @@ -55,11 +53,11 @@ def tracer_printer(self, frame, event, arg): def writeln(self, s): self.write(s) - self.write('\n') + self.write("\n") def write(self, s): if isinstance(s, bytes): - s = s.decode('utf-8') + s = s.decode("utf-8") self.stream.write(s) def call(self, c): @@ -77,8 +75,8 @@ def check( method_to_change=None, stop_at_all_lines=False, has_line_event_optimized_in_original_case=False, - ): - ''' +): + """ :param has_line_event_optimized_in_original_case: If True, we're handling a case where we have a double jump, i.e.: some case where there's a JUMP_FORWARD which points to a JUMP_ABSOLUTE and this is @@ -87,7 +85,7 @@ def check( the initial case but appears when we run after modifying the bytecode in memory. See: https://github.com/microsoft/debugpy/issues/973#issuecomment-1178090731 - ''' + """ from _pydevd_frame_eval.pydevd_modify_bytecode import _get_code_line_info from _pydevd_frame_eval import pydevd_modify_bytecode @@ -137,7 +135,9 @@ def call(): # Now, for each valid line, add a breakpoint and check if the tracing profile is exactly # the same (and if the line where we added the breakpoint was executed, see if our # callback got called). - success, new_code = pydevd_modify_bytecode.insert_pydevd_breaks(code, set([line]), _pydev_needs_stop_at_break=_pydev_needs_stop_at_break) + success, new_code = pydevd_modify_bytecode.insert_pydevd_breaks( + code, set([line]), _pydev_needs_stop_at_break=_pydev_needs_stop_at_break + ) assert success method_to_change.__code__ = new_code @@ -151,27 +151,27 @@ def call(): if has_line_event_optimized_in_original_case: lines = sorted(set(x[1] for x in dis.findlinestarts(new_code))) new_line_contents = [] - last_line = str(max(lines)) + ' ' + last_line = str(max(lines)) + " " for l in contents.splitlines(keepends=True): if not l.strip().startswith(last_line): new_line_contents.append(l) - contents = ''.join(new_line_contents) + contents = "".join(new_line_contents) if line in tracer.lines_executed: assert set([line]) == set(pydev_break_stops) breakpoint_hit_at_least_once = True else: if stop_at_all_lines: - raise AssertionError('Expected the debugger to stop at all lines. Did not stop at line: %s' % (line,)) + raise AssertionError("Expected the debugger to stop at all lines. Did not stop at line: %s" % (line,)) del pydev_break_stops[:] if baseline != contents: - print('------- replacement at line: %s ---------' % (line,)) - print('------- baseline ---------') + print("------- replacement at line: %s ---------" % (line,)) + print("------- baseline ---------") print(baseline) - print('------- contents ---------') + print("------- contents ---------") print(contents) - print('-------- error -----------') + print("-------- error -----------") assert baseline == contents # We must have found a break at least once! @@ -183,50 +183,56 @@ def call(): def test_set_pydevd_break_01(): from tests_python.resources import _bytecode_overflow_example - check('_bytecode_overflow_example.py', _bytecode_overflow_example.Dummy.fun, method_kwargs={'text': 'ing'}, has_line_event_optimized_in_original_case=True) + check( + "_bytecode_overflow_example.py", + _bytecode_overflow_example.Dummy.fun, + method_kwargs={"text": "ing"}, + has_line_event_optimized_in_original_case=True, + ) def test_set_pydevd_break_01a(): from tests_python.resources import _bytecode_overflow_example - check('_bytecode_overflow_example.py', _bytecode_overflow_example.check_backtrack, method_kwargs={'x': 'f'}) + check("_bytecode_overflow_example.py", _bytecode_overflow_example.check_backtrack, method_kwargs={"x": "f"}) def test_set_pydevd_break_02(): from tests_python.resources import _bytecode_many_names_example - check('_bytecode_many_names_example.py', _bytecode_many_names_example.foo) + check("_bytecode_many_names_example.py", _bytecode_many_names_example.foo) def test_set_pydevd_break_03(): from tests_python.resources import _bytecode_big_method - check('_bytecode_big_method.py', _bytecode_big_method.foo) + check("_bytecode_big_method.py", _bytecode_big_method.foo) def test_set_pydevd_break_04(): from tests_python.resources import _debugger_case_yield_from - check('_debugger_case_yield_from.py', _debugger_case_yield_from.method) + check("_debugger_case_yield_from.py", _debugger_case_yield_from.method) def test_set_pydevd_break_05(): from tests_python import debugger_unittest - add_to_pythonpath = debugger_unittest._get_debugger_test_file('wrong_bytecode') + + add_to_pythonpath = debugger_unittest._get_debugger_test_file("wrong_bytecode") sys.path.append(add_to_pythonpath) try: - with open(debugger_unittest._get_debugger_test_file('wrong_bytecode/_debugger_case_wrong_bytecode.py'), 'r') as stream: + with open(debugger_unittest._get_debugger_test_file("wrong_bytecode/_debugger_case_wrong_bytecode.py"), "r") as stream: contents = stream.read() - code = compile(contents, '_my_file_debugger_case_wrong_bytecode.py', 'exec') + code = compile(contents, "_my_file_debugger_case_wrong_bytecode.py", "exec") def method(): pass method.__code__ = code - check('_my_file_debugger_case_wrong_bytecode.py', method, skip_breaks_at_lines=set([1])) + check("_my_file_debugger_case_wrong_bytecode.py", method, skip_breaks_at_lines=set([1])) finally: sys.path.remove(add_to_pythonpath) @@ -234,23 +240,24 @@ def method(): def test_set_pydevd_break_06(pyfile): from tests_python.resources import _bytecode_super - check('_bytecode_super.py', _bytecode_super.B, method_to_change=_bytecode_super.B.__init__, stop_at_all_lines=True) + check("_bytecode_super.py", _bytecode_super.B, method_to_change=_bytecode_super.B.__init__, stop_at_all_lines=True) def test_set_pydevd_break_07(): from tests_python.resources import _bytecode_overflow_example - check('_bytecode_overflow_example.py', _bytecode_overflow_example.offset_overflow, method_kwargs={'stream': StringIO()}) + check("_bytecode_overflow_example.py", _bytecode_overflow_example.offset_overflow, method_kwargs={"stream": StringIO()}) def test_set_pydevd_break_08(): from tests_python.resources import _bytecode_overflow_example - check('_bytecode_overflow_example.py', _bytecode_overflow_example.long_lines, stop_at_all_lines=True) + check("_bytecode_overflow_example.py", _bytecode_overflow_example.long_lines, stop_at_all_lines=True) def test_internal_double_linked_list(): from _pydevd_frame_eval.pydevd_modify_bytecode import _HelperBytecodeList + lst = _HelperBytecodeList() node1 = lst.append(1) assert list(lst) == [1] diff --git a/tests_python/test_code_obj_to_source_code.py b/tests_python/test_code_obj_to_source_code.py index 7516cbf48..5b7882475 100644 --- a/tests_python/test_code_obj_to_source_code.py +++ b/tests_python/test_code_obj_to_source_code.py @@ -9,7 +9,7 @@ def check(obtained, expected, strip_return_none=True): keepends = False obtained_lines = list(obtained.rstrip().splitlines(keepends)) if strip_return_none: - obtained_lines = [x.replace('return None', '') for x in obtained_lines] + obtained_lines = [x.replace("return None", "") for x in obtained_lines] expected_lines = list(expected.rstrip().splitlines(keepends)) @@ -17,79 +17,79 @@ def check(obtained, expected, strip_return_none=True): def test_code_obj_to_source_make_class_and_func(): - code = ''' + code = """ class MyClass(object, other_class): def my_func(self): print(self) -''' - expected = ''' +""" + expected = """ __module__=__name____qualname__=MyClassMyClass=(def MyClass():MyClass,object,other_class,) def MyClass.my_func(self): print(self) -''' +""" - co = compile(code, '', 'exec') + co = compile(code, "", "exec") contents = code_obj_to_source(co) check(contents, expected) def test_code_obj_to_source_lambda(): - code = 'my_func = lambda arg: (2,)' + code = "my_func = lambda arg: (2,)" - co = compile(code, '', 'exec') + co = compile(code, "", "exec") contents = code_obj_to_source(co) - check(contents, 'my_func=(arg):return return (2,)None') + check(contents, "my_func=(arg):return return (2,)None") def test_code_obj_to_source_make_func(): - code = ''' + code = """ def my_func(arg1, arg2=2, arg3=3): some_call(arg1) -''' +""" - co = compile(code, '', 'exec') + co = compile(code, "", "exec") contents = code_obj_to_source(co) check(contents, code) def test_code_obj_to_source_call_func(): - code = 'a=call1(call2(arg1))' + code = "a=call1(call2(arg1))" - co = compile(code, '', 'exec') + co = compile(code, "", "exec") contents = code_obj_to_source(co) check(contents, code) def test_for_list_comp(): - code = '[x for x in range(10)]' + code = "[x for x in range(10)]" - co = compile(code, '', 'exec') + co = compile(code, "", "exec") contents = code_obj_to_source(co) check(contents, code) def test_code_obj_to_source_for(): - code = 'for i in range(10):\n print(i)' + code = "for i in range(10):\n print(i)" - co = compile(code, '', 'exec') + co = compile(code, "", "exec") contents = code_obj_to_source(co) check(contents, code) def test_code_obj_to_source_call_func2(): - code = '''a=call1( + code = """a=call1( call2( arg1)) -''' +""" - co = compile(code, '', 'exec') + co = compile(code, "", "exec") contents = code_obj_to_source(co) check(contents, code) diff --git a/tests_python/test_console.py b/tests_python/test_console.py index 8d2152fca..216690822 100644 --- a/tests_python/test_console.py +++ b/tests_python/test_console.py @@ -4,8 +4,13 @@ from _pydev_bundle.pydev_override import overrides from tests_python.debugger_fixtures import DebuggerRunnerSimple, debugger_runner_simple -from tests_python.debugger_unittest import AbstractWriterThread, SHOW_OTHER_DEBUG_INFO, \ - start_in_daemon_thread, wait_for_condition, IS_JYTHON +from tests_python.debugger_unittest import ( + AbstractWriterThread, + SHOW_OTHER_DEBUG_INFO, + start_in_daemon_thread, + wait_for_condition, + IS_JYTHON, +) from _pydev_bundle.pydev_localhost import get_socket_names, get_socket_name from _pydev_bundle.pydev_imports import xmlrpclib from _pydev_bundle.pydev_imports import _queue as queue @@ -18,23 +23,17 @@ @pytest.fixture def console_setup(tmpdir): - server_queue = queue.Queue() def notify_finished(more): - server_queue.put(('notify_finished', more)) - return '' + server_queue.put(("notify_finished", more)) + return "" class ConsoleRunner(DebuggerRunnerSimple): - @overrides(DebuggerRunnerSimple.add_command_line_args) def add_command_line_args(self, args, dap=False): port, client_port = get_socket_names(2, close=True) - args.extend(( - writer.get_pydevconsole_file(), - str(port[1]), - str(client_port[1]) - )) + args.extend((writer.get_pydevconsole_file(), str(port[1]), str(client_port[1]))) self.port = port self.client_port = client_port @@ -47,13 +46,12 @@ def add_command_line_args(self, args, dap=False): return args class WriterThread(AbstractWriterThread): - if IS_JYTHON: - EXPECTED_RETURNCODE = 'any' + EXPECTED_RETURNCODE = "any" @overrides(AbstractWriterThread.additional_output_checks) def additional_output_checks(self, stdout, stderr): - print('output found: %s - %s' % (stdout, stderr)) + print("output found: %s - %s" % (stdout, stderr)) @overrides(AbstractWriterThread.write_dump_threads) def write_dump_threads(self): @@ -61,17 +59,16 @@ def write_dump_threads(self): def execute_line(self, command, more=False): runner.proxy.execLine(command) - assert server_queue.get(timeout=5.) == ('notify_finished', more) + assert server_queue.get(timeout=5.0) == ("notify_finished", more) def hello(self): - def _hello(): try: - msg = runner.proxy.hello('ignored') + msg = runner.proxy.hello("ignored") if msg is not None: if isinstance(msg, (list, tuple)): msg = next(iter(msg)) - if msg.lower().startswith('hello'): + if msg.lower().startswith("hello"): return True except: # That's ok, communication still not ready. @@ -95,12 +92,8 @@ def connect_to_debugger(self, debugger_port): writer = WriterThread() class CaseSetup(object): - @contextmanager - def check_console( - self, - **kwargs - ): + def check_console(self, **kwargs): for key, value in kwargs.items(): assert hasattr(WriterThread, key) setattr(WriterThread, key, value) @@ -112,11 +105,11 @@ def check_console( args = runner.add_command_line_args(args) if SHOW_OTHER_DEBUG_INFO: - print('executing: %s' % (' '.join(args),)) + print("executing: %s" % (" ".join(args),)) try: with runner.run_process(args, writer) as dct_with_stdout_stder: - writer.get_stdout = lambda: ''.join(dct_with_stdout_stder['stdout']) - writer.get_stderr = lambda: ''.join(dct_with_stdout_stder['stderr']) + writer.get_stdout = lambda: "".join(dct_with_stdout_stder["stdout"]) + writer.get_stderr = lambda: "".join(dct_with_stdout_stder["stderr"]) # Make sure communication is setup. writer.hello() @@ -124,25 +117,23 @@ def check_console( finally: writer.log = [] - stdout = dct_with_stdout_stder['stdout'] - stderr = dct_with_stdout_stder['stderr'] - writer.additional_output_checks(''.join(stdout), ''.join(stderr)) + stdout = dct_with_stdout_stder["stdout"] + stderr = dct_with_stdout_stder["stderr"] + writer.additional_output_checks("".join(stdout), "".join(stderr)) return CaseSetup() def test_console_simple(console_setup): with console_setup.check_console() as writer: - writer.execute_line('a = 10') + writer.execute_line("a = 10") writer.execute_line('print("TEST SUCEEDED")') writer.close() writer.finished_ok = True def test_console_debugger_connected(console_setup): - class _DebuggerWriterThread(AbstractWriterThread): - FORCE_KILL_PROCESS_WHEN_FINISHED_OK = True def __init__(self): @@ -156,38 +147,41 @@ def __init__(self): self.__server_socket = server_socket def run(self): - print('waiting for second process') + print("waiting for second process") self.sock, addr = self.__server_socket.accept() - print('accepted second process') + print("accepted second process") from tests_python.debugger_unittest import ReaderThread + self.reader_thread = ReaderThread(self.sock) self.reader_thread.start() self._sequence = -1 # initial command is always the version self.write_version() - self.log.append('start_socket') + self.log.append("start_socket") self.write_make_initial_run() time.sleep(1) seq = self.write_list_threads() msg = self.wait_for_list_threads(seq) - assert msg.thread['name'] == 'MainThread' - assert msg.thread['id'] == 'console_main' + assert msg.thread["name"] == "MainThread" + assert msg.thread["id"] == "console_main" - self.write_get_frame('console_main', '1') - self.wait_for_vars([ + self.write_get_frame("console_main", "1") + self.wait_for_vars( [ - '') == '' + assert pydevd_file_utils.get_path_with_real_case("") == "" real_case = pydevd_file_utils.get_path_with_real_case(normalized) assert isinstance(real_case, str) # Note test_dir itself cannot be compared with because pytest may @@ -106,15 +108,17 @@ def test_convert_utilities(tmpdir): if i == 2: # Check that we have the expected paths in the cache. - assert pydevd_file_utils._listdir_cache[os.path.dirname(normalized).lower()] == ['Test_Convert_Utilities'] - assert pydevd_file_utils._listdir_cache[(os.path.dirname(normalized).lower(), 'Test_Convert_Utilities'.lower())] == real_case + assert pydevd_file_utils._listdir_cache[os.path.dirname(normalized).lower()] == ["Test_Convert_Utilities"] + assert ( + pydevd_file_utils._listdir_cache[(os.path.dirname(normalized).lower(), "Test_Convert_Utilities".lower())] == real_case + ) # Check that it works with a shortened path. shortened = pydevd_file_utils.convert_to_short_pathname(normalized) - assert '~' in shortened + assert "~" in shortened with_real_case = pydevd_file_utils.get_path_with_real_case(shortened) - assert with_real_case.endswith('Test_Convert_Utilities') - assert '~' not in with_real_case + assert with_real_case.endswith("Test_Convert_Utilities") + assert "~" not in with_real_case elif IS_MAC: assert pydevd_file_utils.normcase(test_dir) == test_dir.lower() @@ -129,45 +133,46 @@ def test_convert_utilities(tmpdir): def test_source_reference(tmpdir): import pydevd_file_utils - pydevd_file_utils.set_ide_os('WINDOWS') + pydevd_file_utils.set_ide_os("WINDOWS") if IS_WINDOWS: # Client and server are on windows. - pydevd_file_utils.setup_client_server_paths([('c:\\foo', 'c:\\bar')]) + pydevd_file_utils.setup_client_server_paths([("c:\\foo", "c:\\bar")]) - assert pydevd_file_utils.map_file_to_client('c:\\bar\\my') == ('c:\\foo\\my', True) - assert pydevd_file_utils.get_client_filename_source_reference('c:\\foo\\my') == 0 + assert pydevd_file_utils.map_file_to_client("c:\\bar\\my") == ("c:\\foo\\my", True) + assert pydevd_file_utils.get_client_filename_source_reference("c:\\foo\\my") == 0 - assert pydevd_file_utils.map_file_to_client('c:\\another\\my') == ('c:\\another\\my', False) - source_reference = pydevd_file_utils.get_client_filename_source_reference('c:\\another\\my') + assert pydevd_file_utils.map_file_to_client("c:\\another\\my") == ("c:\\another\\my", False) + source_reference = pydevd_file_utils.get_client_filename_source_reference("c:\\another\\my") assert source_reference != 0 - assert pydevd_file_utils.get_server_filename_from_source_reference(source_reference) == 'c:\\another\\my' + assert pydevd_file_utils.get_server_filename_from_source_reference(source_reference) == "c:\\another\\my" else: # Client on windows and server on unix - pydevd_file_utils.set_ide_os('WINDOWS') + pydevd_file_utils.set_ide_os("WINDOWS") - pydevd_file_utils.setup_client_server_paths([('c:\\foo', '/bar')]) + pydevd_file_utils.setup_client_server_paths([("c:\\foo", "/bar")]) - assert pydevd_file_utils.map_file_to_client('/bar/my') == ('c:\\foo\\my', True) - assert pydevd_file_utils.get_client_filename_source_reference('c:\\foo\\my') == 0 + assert pydevd_file_utils.map_file_to_client("/bar/my") == ("c:\\foo\\my", True) + assert pydevd_file_utils.get_client_filename_source_reference("c:\\foo\\my") == 0 - assert pydevd_file_utils.map_file_to_client('/another/my') == ('\\another\\my', False) - source_reference = pydevd_file_utils.get_client_filename_source_reference('\\another\\my') + assert pydevd_file_utils.map_file_to_client("/another/my") == ("\\another\\my", False) + source_reference = pydevd_file_utils.get_client_filename_source_reference("\\another\\my") assert source_reference != 0 - assert pydevd_file_utils.get_server_filename_from_source_reference(source_reference) == '/another/my' + assert pydevd_file_utils.get_server_filename_from_source_reference(source_reference) == "/another/my" -@pytest.mark.skipif(sys.platform != 'win32', reason='Windows-only test.') +@pytest.mark.skipif(sys.platform != "win32", reason="Windows-only test.") def test_translate_only_drive(): import pydevd_file_utils - assert pydevd_file_utils.get_path_with_real_case('c:\\') == 'C:\\' + + assert pydevd_file_utils.get_path_with_real_case("c:\\") == "C:\\" def test_to_server_and_to_client(tmpdir): try: def check(obtained, expected): - assert obtained == expected, '%s (%s) != %s (%s)' % (obtained, type(obtained), expected, type(expected)) + assert obtained == expected, "%s (%s) != %s (%s)" % (obtained, type(obtained), expected, type(expected)) if isinstance(obtained, tuple): assert isinstance(obtained[0], str) else: @@ -179,175 +184,162 @@ def check(obtained, expected): assert isinstance(expected, str) import pydevd_file_utils + if IS_WINDOWS: # Check with made-up files - pydevd_file_utils.setup_client_server_paths([('c:\\foo', 'c:\\bar'), ('c:\\foo2', 'c:\\bar2')]) + pydevd_file_utils.setup_client_server_paths([("c:\\foo", "c:\\bar"), ("c:\\foo2", "c:\\bar2")]) stream = io.StringIO() with log_context(0, stream=stream): - pydevd_file_utils.map_file_to_server('y:\\only_exists_in_client_not_in_server') - assert r'pydev debugger: unable to find translation for: "y:\only_exists_in_client_not_in_server" in ["c:\foo\", "c:\foo2\", "c:\foo", "c:\foo2"] (please revise your path mappings).' in stream.getvalue() + pydevd_file_utils.map_file_to_server("y:\\only_exists_in_client_not_in_server") + assert ( + r'pydev debugger: unable to find translation for: "y:\only_exists_in_client_not_in_server" in ["c:\foo\", "c:\foo2\", "c:\foo", "c:\foo2"] (please revise your path mappings).' + in stream.getvalue() + ) # Client and server are on windows. - pydevd_file_utils.set_ide_os('WINDOWS') - for in_eclipse, in_python in ([ - ('c:\\foo', 'c:\\bar'), - ('c:/foo', 'c:\\bar'), - ('c:\\foo', 'c:/bar'), - ('c:\\foo', 'c:\\bar\\'), - ('c:/foo', 'c:\\bar\\'), - ('c:\\foo', 'c:/bar/'), - ('c:\\foo\\', 'c:\\bar'), - ('c:/foo/', 'c:\\bar'), - ('c:\\foo\\', 'c:/bar'), - - ]): - PATHS_FROM_ECLIPSE_TO_PYTHON = [ - (in_eclipse, in_python) - ] + pydevd_file_utils.set_ide_os("WINDOWS") + for in_eclipse, in_python in [ + ("c:\\foo", "c:\\bar"), + ("c:/foo", "c:\\bar"), + ("c:\\foo", "c:/bar"), + ("c:\\foo", "c:\\bar\\"), + ("c:/foo", "c:\\bar\\"), + ("c:\\foo", "c:/bar/"), + ("c:\\foo\\", "c:\\bar"), + ("c:/foo/", "c:\\bar"), + ("c:\\foo\\", "c:/bar"), + ]: + PATHS_FROM_ECLIPSE_TO_PYTHON = [(in_eclipse, in_python)] pydevd_file_utils.setup_client_server_paths(PATHS_FROM_ECLIPSE_TO_PYTHON) - check(pydevd_file_utils.map_file_to_server('c:\\foo\\my'), 'c:\\bar\\my') - check(pydevd_file_utils.map_file_to_server('c:/foo/my'), 'c:\\bar\\my') - check(pydevd_file_utils.map_file_to_server('c:/foo/my/'), 'c:\\bar\\my') - check(pydevd_file_utils.map_file_to_server('c:\\foo\\áéíóú'.upper()), 'c:\\bar' + '\\áéíóú'.upper()) - check(pydevd_file_utils.map_file_to_client('c:\\bar\\my'), ('c:\\foo\\my', True)) + check(pydevd_file_utils.map_file_to_server("c:\\foo\\my"), "c:\\bar\\my") + check(pydevd_file_utils.map_file_to_server("c:/foo/my"), "c:\\bar\\my") + check(pydevd_file_utils.map_file_to_server("c:/foo/my/"), "c:\\bar\\my") + check(pydevd_file_utils.map_file_to_server("c:\\foo\\áéíóú".upper()), "c:\\bar" + "\\áéíóú".upper()) + check(pydevd_file_utils.map_file_to_client("c:\\bar\\my"), ("c:\\foo\\my", True)) # Client on unix and server on windows - pydevd_file_utils.set_ide_os('UNIX') - for in_eclipse, in_python in ([ - ('/foo', 'c:\\bar'), - ('/foo', 'c:/bar'), - ('/foo', 'c:\\bar\\'), - ('/foo', 'c:/bar/'), - ('/foo/', 'c:\\bar'), - ('/foo/', 'c:\\bar\\'), - ]): - - PATHS_FROM_ECLIPSE_TO_PYTHON = [ - (in_eclipse, in_python) - ] + pydevd_file_utils.set_ide_os("UNIX") + for in_eclipse, in_python in [ + ("/foo", "c:\\bar"), + ("/foo", "c:/bar"), + ("/foo", "c:\\bar\\"), + ("/foo", "c:/bar/"), + ("/foo/", "c:\\bar"), + ("/foo/", "c:\\bar\\"), + ]: + PATHS_FROM_ECLIPSE_TO_PYTHON = [(in_eclipse, in_python)] pydevd_file_utils.setup_client_server_paths(PATHS_FROM_ECLIPSE_TO_PYTHON) - check(pydevd_file_utils.map_file_to_server('/foo/my'), 'c:\\bar\\my') - check(pydevd_file_utils.map_file_to_client('c:\\bar\\my'), ('/foo/my', True)) - check(pydevd_file_utils.map_file_to_client('c:\\bar\\my\\'), ('/foo/my', True)) - check(pydevd_file_utils.map_file_to_client('c:/bar/my'), ('/foo/my', True)) - check(pydevd_file_utils.map_file_to_client('c:/bar/my/'), ('/foo/my', True)) + check(pydevd_file_utils.map_file_to_server("/foo/my"), "c:\\bar\\my") + check(pydevd_file_utils.map_file_to_client("c:\\bar\\my"), ("/foo/my", True)) + check(pydevd_file_utils.map_file_to_client("c:\\bar\\my\\"), ("/foo/my", True)) + check(pydevd_file_utils.map_file_to_client("c:/bar/my"), ("/foo/my", True)) + check(pydevd_file_utils.map_file_to_client("c:/bar/my/"), ("/foo/my", True)) # Test with 'real' files # Client and server are on windows. - pydevd_file_utils.set_ide_os('WINDOWS') + pydevd_file_utils.set_ide_os("WINDOWS") test_dir = pydevd_file_utils.get_path_with_real_case(str(tmpdir.mkdir("Foo"))) os.makedirs(os.path.join(test_dir, "Another")) - in_eclipse = os.path.join(os.path.dirname(test_dir), 'Bar') + in_eclipse = os.path.join(os.path.dirname(test_dir), "Bar") in_python = test_dir - PATHS_FROM_ECLIPSE_TO_PYTHON = [ - (in_eclipse, in_python) - ] + PATHS_FROM_ECLIPSE_TO_PYTHON = [(in_eclipse, in_python)] pydevd_file_utils.setup_client_server_paths(PATHS_FROM_ECLIPSE_TO_PYTHON) if pydevd_file_utils.map_file_to_server(in_eclipse) != in_python.lower(): - raise AssertionError('%s != %s\ntmpdir:%s\nin_eclipse: %s\nin_python: %s\ntest_dir: %s' % ( - pydevd_file_utils.map_file_to_server(in_eclipse), in_python.lower(), tmpdir, in_eclipse, in_python, test_dir)) + raise AssertionError( + "%s != %s\ntmpdir:%s\nin_eclipse: %s\nin_python: %s\ntest_dir: %s" + % (pydevd_file_utils.map_file_to_server(in_eclipse), in_python.lower(), tmpdir, in_eclipse, in_python, test_dir) + ) found_in_eclipse = pydevd_file_utils.map_file_to_client(in_python)[0] - assert found_in_eclipse.endswith('Bar') + assert found_in_eclipse.endswith("Bar") - assert pydevd_file_utils.map_file_to_server( - os.path.join(in_eclipse, 'another')) == os.path.join(in_python, 'another').lower() - found_in_eclipse = pydevd_file_utils.map_file_to_client( - os.path.join(in_python, 'another'))[0] - assert found_in_eclipse.endswith('Bar\\Another') + assert pydevd_file_utils.map_file_to_server(os.path.join(in_eclipse, "another")) == os.path.join(in_python, "another").lower() + found_in_eclipse = pydevd_file_utils.map_file_to_client(os.path.join(in_python, "another"))[0] + assert found_in_eclipse.endswith("Bar\\Another") # Client on unix and server on windows - pydevd_file_utils.set_ide_os('UNIX') - in_eclipse = '/foo' + pydevd_file_utils.set_ide_os("UNIX") + in_eclipse = "/foo" in_python = test_dir - PATHS_FROM_ECLIPSE_TO_PYTHON = [ - (in_eclipse, in_python) - ] + PATHS_FROM_ECLIPSE_TO_PYTHON = [(in_eclipse, in_python)] pydevd_file_utils.setup_client_server_paths(PATHS_FROM_ECLIPSE_TO_PYTHON) - assert pydevd_file_utils.map_file_to_server('/foo').lower() == in_python.lower() + assert pydevd_file_utils.map_file_to_server("/foo").lower() == in_python.lower() assert pydevd_file_utils.map_file_to_client(in_python) == (in_eclipse, True) # Test without translation in place (still needs to fix case and separators) - pydevd_file_utils.set_ide_os('WINDOWS') + pydevd_file_utils.set_ide_os("WINDOWS") PATHS_FROM_ECLIPSE_TO_PYTHON = [] pydevd_file_utils.setup_client_server_paths(PATHS_FROM_ECLIPSE_TO_PYTHON) assert pydevd_file_utils.map_file_to_server(test_dir) == test_dir - assert pydevd_file_utils.map_file_to_client(test_dir.lower())[0].endswith('\\Foo') + assert pydevd_file_utils.map_file_to_client(test_dir.lower())[0].endswith("\\Foo") else: # Client on windows and server on unix - pydevd_file_utils.set_ide_os('WINDOWS') + pydevd_file_utils.set_ide_os("WINDOWS") - PATHS_FROM_ECLIPSE_TO_PYTHON = [ - ('c:\\BAR', '/bar') - ] + PATHS_FROM_ECLIPSE_TO_PYTHON = [("c:\\BAR", "/bar")] pydevd_file_utils.setup_client_server_paths(PATHS_FROM_ECLIPSE_TO_PYTHON) - assert pydevd_file_utils.map_file_to_server('c:\\bar\\my') == '/bar/my' - assert pydevd_file_utils.map_file_to_client('/bar/my') == ('c:\\BAR\\my', True) - - for in_eclipse, in_python in ([ - ('c:\\foo', '/báéíóúr'), - ('c:/foo', '/báéíóúr'), - ('c:/foo/', '/báéíóúr'), - ('c:/foo/', '/báéíóúr/'), - ('c:\\foo\\', '/báéíóúr/'), - ]): - - PATHS_FROM_ECLIPSE_TO_PYTHON = [ - (in_eclipse, in_python) - ] + assert pydevd_file_utils.map_file_to_server("c:\\bar\\my") == "/bar/my" + assert pydevd_file_utils.map_file_to_client("/bar/my") == ("c:\\BAR\\my", True) + + for in_eclipse, in_python in [ + ("c:\\foo", "/báéíóúr"), + ("c:/foo", "/báéíóúr"), + ("c:/foo/", "/báéíóúr"), + ("c:/foo/", "/báéíóúr/"), + ("c:\\foo\\", "/báéíóúr/"), + ]: + PATHS_FROM_ECLIPSE_TO_PYTHON = [(in_eclipse, in_python)] pydevd_file_utils.setup_client_server_paths(PATHS_FROM_ECLIPSE_TO_PYTHON) - assert pydevd_file_utils.map_file_to_server('c:\\foo\\my') == '/báéíóúr/my' - assert pydevd_file_utils.map_file_to_server('C:\\foo\\my') == '/báéíóúr/my' - assert pydevd_file_utils.map_file_to_server('C:\\foo\\MY') == '/báéíóúr/MY' - assert pydevd_file_utils.map_file_to_server('C:\\foo\\MY\\') == '/báéíóúr/MY' - assert pydevd_file_utils.map_file_to_server('c:\\foo\\my\\file.py') == '/báéíóúr/my/file.py' - assert pydevd_file_utils.map_file_to_server('c:\\foo\\my\\other\\file.py') == '/báéíóúr/my/other/file.py' - assert pydevd_file_utils.map_file_to_server('c:/foo/my') == '/báéíóúr/my' - assert pydevd_file_utils.map_file_to_server('c:\\foo\\my\\') == '/báéíóúr/my' - assert pydevd_file_utils.map_file_to_server('c:/foo/my/') == '/báéíóúr/my' - - assert pydevd_file_utils.map_file_to_client('/báéíóúr/my') == ('c:\\foo\\my', True) - assert pydevd_file_utils.map_file_to_client('/báéíóúr/my/') == ('c:\\foo\\my', True) + assert pydevd_file_utils.map_file_to_server("c:\\foo\\my") == "/báéíóúr/my" + assert pydevd_file_utils.map_file_to_server("C:\\foo\\my") == "/báéíóúr/my" + assert pydevd_file_utils.map_file_to_server("C:\\foo\\MY") == "/báéíóúr/MY" + assert pydevd_file_utils.map_file_to_server("C:\\foo\\MY\\") == "/báéíóúr/MY" + assert pydevd_file_utils.map_file_to_server("c:\\foo\\my\\file.py") == "/báéíóúr/my/file.py" + assert pydevd_file_utils.map_file_to_server("c:\\foo\\my\\other\\file.py") == "/báéíóúr/my/other/file.py" + assert pydevd_file_utils.map_file_to_server("c:/foo/my") == "/báéíóúr/my" + assert pydevd_file_utils.map_file_to_server("c:\\foo\\my\\") == "/báéíóúr/my" + assert pydevd_file_utils.map_file_to_server("c:/foo/my/") == "/báéíóúr/my" + + assert pydevd_file_utils.map_file_to_client("/báéíóúr/my") == ("c:\\foo\\my", True) + assert pydevd_file_utils.map_file_to_client("/báéíóúr/my/") == ("c:\\foo\\my", True) # Files for which there's no translation have only their separators updated. - assert pydevd_file_utils.map_file_to_client('/usr/bin/x.py') == ('\\usr\\bin\\x.py', False) - assert pydevd_file_utils.map_file_to_client('/usr/bin') == ('\\usr\\bin', False) - assert pydevd_file_utils.map_file_to_client('/usr/bin/') == ('\\usr\\bin', False) - assert pydevd_file_utils.map_file_to_server('\\usr\\bin') == '/usr/bin' - assert pydevd_file_utils.map_file_to_server('\\usr\\bin\\') == '/usr/bin' + assert pydevd_file_utils.map_file_to_client("/usr/bin/x.py") == ("\\usr\\bin\\x.py", False) + assert pydevd_file_utils.map_file_to_client("/usr/bin") == ("\\usr\\bin", False) + assert pydevd_file_utils.map_file_to_client("/usr/bin/") == ("\\usr\\bin", False) + assert pydevd_file_utils.map_file_to_server("\\usr\\bin") == "/usr/bin" + assert pydevd_file_utils.map_file_to_server("\\usr\\bin\\") == "/usr/bin" # When we have a client file and there'd be no translation, and making it absolute would # do something as '$cwd/$file_received' (i.e.: $cwd/c:/another in the case below), # warn the user that it's not correct and the path that should be translated instead # and don't make it absolute. - assert pydevd_file_utils.map_file_to_server('c:\\Another') == 'c:/Another' + assert pydevd_file_utils.map_file_to_server("c:\\Another") == "c:/Another" - assert pydevd_file_utils.map_file_to_server('c:/FoO/my/BAR') == '/báéíóúr/my/BAR' - assert pydevd_file_utils.map_file_to_client('/báéíóúr/my/BAR') == ('c:\\foo\\my\\BAR', True) + assert pydevd_file_utils.map_file_to_server("c:/FoO/my/BAR") == "/báéíóúr/my/BAR" + assert pydevd_file_utils.map_file_to_client("/báéíóúr/my/BAR") == ("c:\\foo\\my\\BAR", True) # Client and server on unix - pydevd_file_utils.set_ide_os('UNIX') - in_eclipse = '/foo' - in_python = '/báéíóúr' - PATHS_FROM_ECLIPSE_TO_PYTHON = [ - (in_eclipse, in_python) - ] + pydevd_file_utils.set_ide_os("UNIX") + in_eclipse = "/foo" + in_python = "/báéíóúr" + PATHS_FROM_ECLIPSE_TO_PYTHON = [(in_eclipse, in_python)] pydevd_file_utils.setup_client_server_paths(PATHS_FROM_ECLIPSE_TO_PYTHON) - assert pydevd_file_utils.map_file_to_server('/foo/my') == '/báéíóúr/my' - assert pydevd_file_utils.map_file_to_client('/báéíóúr/my') == ('/foo/my', True) + assert pydevd_file_utils.map_file_to_server("/foo/my") == "/báéíóúr/my" + assert pydevd_file_utils.map_file_to_client("/báéíóúr/my") == ("/foo/my", True) finally: pydevd_file_utils.setup_client_server_paths([]) def test_relative_paths(tmpdir): - ''' + """ We need to check that we can deal with relative paths. Use cases: @@ -359,31 +351,32 @@ def test_relative_paths(tmpdir): Use case is a cython-generated module which is generated from a .pyx which is distributed. In this case we need to resolve to the real file based on the sys.path entries. - ''' + """ import pydevd_file_utils import sys + sys.path.append(str(tmpdir)) try: pydevd_file_utils.NORM_PATHS_AND_BASE_CONTAINER.clear() pydevd_file_utils.NORM_PATHS_CONTAINER.clear() - abs_path = pydevd_file_utils.get_abs_path_real_path_and_base_from_file('my_dir/my_file.pyx')[0] - assert 'site-packages' in abs_path + abs_path = pydevd_file_utils.get_abs_path_real_path_and_base_from_file("my_dir/my_file.pyx")[0] + assert "site-packages" in abs_path assert os.path.normcase(str(tmpdir)) not in abs_path - assert not pydevd_file_utils.exists('my_dir/my_file.pyx') + assert not pydevd_file_utils.exists("my_dir/my_file.pyx") # If the relative file exists when joined with some entry in the PYTHONPATH we'll consider # that the relative path points to that absolute path. - target_dir = os.path.join(str(tmpdir), 'my_dir') + target_dir = os.path.join(str(tmpdir), "my_dir") os.makedirs(target_dir) - with open(os.path.join(target_dir, 'my_file.pyx'), 'w') as stream: - stream.write('empty') + with open(os.path.join(target_dir, "my_file.pyx"), "w") as stream: + stream.write("empty") pydevd_file_utils.NORM_PATHS_AND_BASE_CONTAINER.clear() pydevd_file_utils.NORM_PATHS_CONTAINER.clear() - abs_path = pydevd_file_utils.get_abs_path_real_path_and_base_from_file('my_dir/my_file.pyx')[0] - assert 'site-packages' not in abs_path + abs_path = pydevd_file_utils.get_abs_path_real_path_and_base_from_file("my_dir/my_file.pyx")[0] + assert "site-packages" not in abs_path assert str(tmpdir) in abs_path - assert pydevd_file_utils.exists('my_dir/my_file.pyx') + assert pydevd_file_utils.exists("my_dir/my_file.pyx") finally: sys.path.remove(str(tmpdir)) @@ -393,20 +386,20 @@ def test_zip_paths(tmpdir): import sys import zipfile - for i, zip_basename in enumerate(('MY1.zip', 'my2.egg!')): + for i, zip_basename in enumerate(("MY1.zip", "my2.egg!")): zipfile_path = str(tmpdir.join(zip_basename)) - zip_file = zipfile.ZipFile(zipfile_path, 'w') - zip_file.writestr('zipped%s/__init__.py' % (i,), '') - zip_file.writestr('zipped%s/zipped_contents.py' % (i,), 'def call_in_zip():\n return 1') + zip_file = zipfile.ZipFile(zipfile_path, "w") + zip_file.writestr("zipped%s/__init__.py" % (i,), "") + zip_file.writestr("zipped%s/zipped_contents.py" % (i,), "def call_in_zip():\n return 1") zip_file.close() sys.path.append(zipfile_path) try: import importlib except ImportError: - __import__('zipped%s' % (i,)) # Py2.6 does not have importlib + __import__("zipped%s" % (i,)) # Py2.6 does not have importlib else: - importlib.import_module('zipped%s' % (i,)) # Check that it's importable. + importlib.import_module("zipped%s" % (i,)) # Check that it's importable. # Check that we can deal with the zip path. assert pydevd_file_utils.exists(zipfile_path) @@ -420,22 +413,23 @@ def test_zip_paths(tmpdir): # Check that we can deal with zip contents. for path in [ - zipfile_path + '/zipped%s/__init__.py' % (i,), - zipfile_path + '/zipped%s/zipped_contents.py' % (i,), - zipfile_path + '\\zipped%s\\__init__.py' % (i,), - zipfile_path + '\\zipped%s\\zipped_contents.py' % (i,), - ]: - assert pydevd_file_utils.exists(path), 'Expected exists to return True for path:\n%s' % (path,) + zipfile_path + "/zipped%s/__init__.py" % (i,), + zipfile_path + "/zipped%s/zipped_contents.py" % (i,), + zipfile_path + "\\zipped%s\\__init__.py" % (i,), + zipfile_path + "\\zipped%s\\zipped_contents.py" % (i,), + ]: + assert pydevd_file_utils.exists(path), "Expected exists to return True for path:\n%s" % (path,) abspath, realpath, basename = pydevd_file_utils.get_abs_path_real_path_and_base_from_file(path) - assert pydevd_file_utils.exists(abspath), 'Expected exists to return True for path:\n%s' % (abspath,) - assert pydevd_file_utils.exists(realpath), 'Expected exists to return True for path:\n%s' % (realpath,) + assert pydevd_file_utils.exists(abspath), "Expected exists to return True for path:\n%s" % (abspath,) + assert pydevd_file_utils.exists(realpath), "Expected exists to return True for path:\n%s" % (realpath,) - assert zipfile_path in pydevd_file_utils._ZIP_SEARCH_CACHE, '%s not in %s' % ( - zipfile_path, '\n'.join(sorted(pydevd_file_utils._ZIP_SEARCH_CACHE.keys()))) + assert zipfile_path in pydevd_file_utils._ZIP_SEARCH_CACHE, "%s not in %s" % ( + zipfile_path, + "\n".join(sorted(pydevd_file_utils._ZIP_SEARCH_CACHE.keys())), + ) def test_source_mapping(): - from _pydevd_bundle.pydevd_source_mapping import SourceMapping, SourceMappingEntry from _pydevd_bundle import pydevd_api @@ -449,28 +443,28 @@ class _DummyPyDB(object): source_mapping = _DummyPyDB.source_mapping mapping = [ - SourceMappingEntry(line=3, end_line=6, runtime_line=5, runtime_source=''), - SourceMappingEntry(line=10, end_line=11, runtime_line=1, runtime_source=''), + SourceMappingEntry(line=3, end_line=6, runtime_line=5, runtime_source=""), + SourceMappingEntry(line=10, end_line=11, runtime_line=1, runtime_source=""), ] api = pydevd_api.PyDevdAPI() py_db = _DummyPyDB() - filename = 'c:\\temp\\bar.py' if IS_WINDOWS else '/temp/bar.py' + filename = "c:\\temp\\bar.py" if IS_WINDOWS else "/temp/bar.py" api.set_source_mapping(py_db, filename, mapping) # Map to server assert source_mapping.map_to_server(filename, 1) == (filename, 1, False) assert source_mapping.map_to_server(filename, 2) == (filename, 2, False) - assert source_mapping.map_to_server(filename, 3) == ('', 5, True) - assert source_mapping.map_to_server(filename, 4) == ('', 6, True) - assert source_mapping.map_to_server(filename, 5) == ('', 7, True) - assert source_mapping.map_to_server(filename, 6) == ('', 8, True) + assert source_mapping.map_to_server(filename, 3) == ("", 5, True) + assert source_mapping.map_to_server(filename, 4) == ("", 6, True) + assert source_mapping.map_to_server(filename, 5) == ("", 7, True) + assert source_mapping.map_to_server(filename, 6) == ("", 8, True) assert source_mapping.map_to_server(filename, 7) == (filename, 7, False) - assert source_mapping.map_to_server(filename, 10) == ('', 1, True) - assert source_mapping.map_to_server(filename, 11) == ('', 2, True) + assert source_mapping.map_to_server(filename, 10) == ("", 1, True) + assert source_mapping.map_to_server(filename, 11) == ("", 2, True) assert source_mapping.map_to_server(filename, 12) == (filename, 12, False) @@ -478,111 +472,82 @@ class _DummyPyDB(object): assert source_mapping.map_to_client(filename, 1) == (filename, 1, False) assert source_mapping.map_to_client(filename, 2) == (filename, 2, False) - assert source_mapping.map_to_client('', 5) == (filename, 3, True) - assert source_mapping.map_to_client('', 6) == (filename, 4, True) - assert source_mapping.map_to_client('', 7) == (filename, 5, True) - assert source_mapping.map_to_client('', 8) == (filename, 6, True) + assert source_mapping.map_to_client("", 5) == (filename, 3, True) + assert source_mapping.map_to_client("", 6) == (filename, 4, True) + assert source_mapping.map_to_client("", 7) == (filename, 5, True) + assert source_mapping.map_to_client("", 8) == (filename, 6, True) assert source_mapping.map_to_client(filename, 7) == (filename, 7, False) - assert source_mapping.map_to_client('', 1) == (filename, 10, True) - assert source_mapping.map_to_client('', 2) == (filename, 11, True) + assert source_mapping.map_to_client("", 1) == (filename, 10, True) + assert source_mapping.map_to_client("", 2) == (filename, 11, True) assert source_mapping.map_to_client(filename, 12) == (filename, 12, False) -@pytest.mark.skipif(IS_WINDOWS, reason='Linux/Mac-only test') +@pytest.mark.skipif(IS_WINDOWS, reason="Linux/Mac-only test") def test_mapping_conflict_to_client(): import pydevd_file_utils path_mappings = [] for pathMapping in _MAPPING_CONFLICT: - localRoot = pathMapping.get('localRoot', '') - remoteRoot = pathMapping.get('remoteRoot', '') - if (localRoot != '') and (remoteRoot != ''): + localRoot = pathMapping.get("localRoot", "") + remoteRoot = pathMapping.get("remoteRoot", "") + if (localRoot != "") and (remoteRoot != ""): path_mappings.append((localRoot, remoteRoot)) pydevd_file_utils.setup_client_server_paths(path_mappings) - assert pydevd_file_utils.map_file_to_client('/opt/pathsomething/foo.py') == \ - ('/var/home/p2/foo.py', True) + assert pydevd_file_utils.map_file_to_client("/opt/pathsomething/foo.py") == ("/var/home/p2/foo.py", True) - assert pydevd_file_utils.map_file_to_client('/opt/v2/pathsomething/foo.py') == \ - ('/var/home/p4/foo.py', True) + assert pydevd_file_utils.map_file_to_client("/opt/v2/pathsomething/foo.py") == ("/var/home/p4/foo.py", True) # This is an odd case, but the user didn't really put a slash in the end, # so, it's possible that this is what the user actually wants. - assert pydevd_file_utils.map_file_to_client('/opt/v2/path_r1/foo.py') == \ - ('/var/home/p3_r1/foo.py', True) + assert pydevd_file_utils.map_file_to_client("/opt/v2/path_r1/foo.py") == ("/var/home/p3_r1/foo.py", True) # The client said both local and remote end with a slash, so, we can only # match it with the slash in the end. - assert pydevd_file_utils.map_file_to_client('/opt/pathsomething_foo.py') == \ - ('/opt/pathsomething_foo.py', False) + assert pydevd_file_utils.map_file_to_client("/opt/pathsomething_foo.py") == ("/opt/pathsomething_foo.py", False) _MAPPING_CONFLICT = [ - { - "localRoot": "/var/home/p1/", - "remoteRoot": "/opt/path/" - }, - { - "localRoot": "/var/home/p2/", - "remoteRoot": "/opt/pathsomething/" - }, - { - "localRoot": "/var/home/p3", - "remoteRoot": "/opt/v2/path" - }, - { - "localRoot": "/var/home/p4", - "remoteRoot": "/opt/v2/pathsomething" - }, + {"localRoot": "/var/home/p1/", "remoteRoot": "/opt/path/"}, + {"localRoot": "/var/home/p2/", "remoteRoot": "/opt/pathsomething/"}, + {"localRoot": "/var/home/p3", "remoteRoot": "/opt/v2/path"}, + {"localRoot": "/var/home/p4", "remoteRoot": "/opt/v2/pathsomething"}, ] -@pytest.mark.skipif(IS_WINDOWS, reason='Linux/Mac-only test') +@pytest.mark.skipif(IS_WINDOWS, reason="Linux/Mac-only test") def test_mapping_conflict_to_server(): import pydevd_file_utils path_mappings = [] for pathMapping in _MAPPING_CONFLICT_TO_SERVER: - localRoot = pathMapping.get('localRoot', '') - remoteRoot = pathMapping.get('remoteRoot', '') - if (localRoot != '') and (remoteRoot != ''): + localRoot = pathMapping.get("localRoot", "") + remoteRoot = pathMapping.get("remoteRoot", "") + if (localRoot != "") and (remoteRoot != ""): path_mappings.append((localRoot, remoteRoot)) pydevd_file_utils.setup_client_server_paths(path_mappings) - assert pydevd_file_utils.map_file_to_server('/opt/pathsomething/foo.py') == '/var/home/p2/foo.py' + assert pydevd_file_utils.map_file_to_server("/opt/pathsomething/foo.py") == "/var/home/p2/foo.py" - assert pydevd_file_utils.map_file_to_server('/opt/v2/pathsomething/foo.py') == '/var/home/p4/foo.py' + assert pydevd_file_utils.map_file_to_server("/opt/v2/pathsomething/foo.py") == "/var/home/p4/foo.py" # This is an odd case, but the user didn't really put a slash in the end, # so, it's possible that this is what the user actually wants. - assert pydevd_file_utils.map_file_to_server('/opt/v2/path_r1/foo.py') == '/var/home/p3_r1/foo.py' + assert pydevd_file_utils.map_file_to_server("/opt/v2/path_r1/foo.py") == "/var/home/p3_r1/foo.py" # The client said both local and remote end with a slash, so, we can only # match it with the slash in the end. - assert pydevd_file_utils.map_file_to_server('/opt/pathsomething_foo.py') == '/opt/pathsomething_foo.py' + assert pydevd_file_utils.map_file_to_server("/opt/pathsomething_foo.py") == "/opt/pathsomething_foo.py" _MAPPING_CONFLICT_TO_SERVER = [ - { - "remoteRoot": "/var/home/p1/", - "localRoot": "/opt/path/" - }, - { - "remoteRoot": "/var/home/p2/", - "localRoot": "/opt/pathsomething/" - }, - { - "remoteRoot": "/var/home/p3", - "localRoot": "/opt/v2/path" - }, - { - "remoteRoot": "/var/home/p4", - "localRoot": "/opt/v2/pathsomething" - }, + {"remoteRoot": "/var/home/p1/", "localRoot": "/opt/path/"}, + {"remoteRoot": "/var/home/p2/", "localRoot": "/opt/pathsomething/"}, + {"remoteRoot": "/var/home/p3", "localRoot": "/opt/v2/path"}, + {"remoteRoot": "/var/home/p4", "localRoot": "/opt/v2/pathsomething"}, ] - diff --git a/tests_python/test_debugger.py b/tests_python/test_debugger.py index ac2639319..bcda03813 100644 --- a/tests_python/test_debugger.py +++ b/tests_python/test_debugger.py @@ -1,29 +1,58 @@ # coding: utf-8 -''' +""" The idea is that we record the commands sent to the debugger and reproduce them from this script (so, this works as the client, which spawns the debugger as a separate process and communicates to it as if it was run from the outside) Note that it's a python script but it'll spawn a process to run as jython, ironpython and as python. -''' +""" import time import pytest from tests_python import debugger_unittest -from tests_python.debugger_unittest import (CMD_SET_PROPERTY_TRACE, REASON_CAUGHT_EXCEPTION, - REASON_UNCAUGHT_EXCEPTION, REASON_STOP_ON_BREAKPOINT, REASON_THREAD_SUSPEND, overrides, CMD_THREAD_CREATE, - CMD_GET_THREAD_STACK, REASON_STEP_INTO_MY_CODE, CMD_GET_EXCEPTION_DETAILS, IS_IRONPYTHON, IS_JYTHON, IS_CPYTHON, - IS_APPVEYOR, wait_for_condition, CMD_GET_FRAME, CMD_GET_BREAKPOINT_EXCEPTION, - CMD_THREAD_SUSPEND, CMD_STEP_OVER, REASON_STEP_OVER, CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, - CMD_THREAD_RESUME_SINGLE_NOTIFICATION, REASON_STEP_RETURN, REASON_STEP_RETURN_MY_CODE, - REASON_STEP_OVER_MY_CODE, REASON_STEP_INTO, CMD_THREAD_KILL, IS_PYPY, REASON_STOP_ON_START, - CMD_SMART_STEP_INTO, CMD_GET_VARIABLE) -from _pydevd_bundle.pydevd_constants import IS_WINDOWS, IS_PY38_OR_GREATER, \ - IS_MAC, PYDEVD_USE_SYS_MONITORING, SUPPORT_ATTACH_TO_PID, \ - IS_PY312_OR_GREATER -from _pydevd_bundle.pydevd_comm_constants import CMD_RELOAD_CODE, CMD_INPUT_REQUESTED, \ - CMD_RUN_CUSTOM_OPERATION +from tests_python.debugger_unittest import ( + CMD_SET_PROPERTY_TRACE, + REASON_CAUGHT_EXCEPTION, + REASON_UNCAUGHT_EXCEPTION, + REASON_STOP_ON_BREAKPOINT, + REASON_THREAD_SUSPEND, + overrides, + CMD_THREAD_CREATE, + CMD_GET_THREAD_STACK, + REASON_STEP_INTO_MY_CODE, + CMD_GET_EXCEPTION_DETAILS, + IS_IRONPYTHON, + IS_JYTHON, + IS_CPYTHON, + IS_APPVEYOR, + wait_for_condition, + CMD_GET_FRAME, + CMD_GET_BREAKPOINT_EXCEPTION, + CMD_THREAD_SUSPEND, + CMD_STEP_OVER, + REASON_STEP_OVER, + CMD_THREAD_SUSPEND_SINGLE_NOTIFICATION, + CMD_THREAD_RESUME_SINGLE_NOTIFICATION, + REASON_STEP_RETURN, + REASON_STEP_RETURN_MY_CODE, + REASON_STEP_OVER_MY_CODE, + REASON_STEP_INTO, + CMD_THREAD_KILL, + IS_PYPY, + REASON_STOP_ON_START, + CMD_SMART_STEP_INTO, + CMD_GET_VARIABLE, +) +from _pydevd_bundle.pydevd_constants import ( + IS_WINDOWS, + IS_PY38_OR_GREATER, + IS_MAC, + PYDEVD_USE_SYS_MONITORING, + SUPPORT_ATTACH_TO_PID, + IS_PY312_OR_GREATER, +) +from _pydevd_bundle.pydevd_comm_constants import CMD_RELOAD_CODE, CMD_INPUT_REQUESTED, CMD_RUN_CUSTOM_OPERATION import json import pydevd_file_utils import subprocess @@ -35,55 +64,55 @@ import sys pytest_plugins = [ - str('tests_python.debugger_fixtures'), + str("tests_python.debugger_fixtures"), ] builtin_qualifier = "builtins" -@pytest.mark.skipif(not IS_CPYTHON, reason='Test needs gc.get_referrers/reference counting to really check anything.') +@pytest.mark.skipif(not IS_CPYTHON, reason="Test needs gc.get_referrers/reference counting to really check anything.") def test_case_referrers(case_setup): - with case_setup.test_file('_debugger_case1.py') as writer: - writer.log.append('writing add breakpoint') - writer.write_add_breakpoint(6, 'set_up') + with case_setup.test_file("_debugger_case1.py") as writer: + writer.log.append("writing add breakpoint") + writer.write_add_breakpoint(6, "set_up") - writer.log.append('making initial run') + writer.log.append("making initial run") writer.write_make_initial_run() - writer.log.append('waiting for breakpoint hit') + writer.log.append("waiting for breakpoint hit") hit = writer.wait_for_breakpoint_hit() thread_id = hit.thread_id frame_id = hit.frame_id - writer.log.append('get frame') + writer.log.append("get frame") writer.write_get_frame(thread_id, frame_id) - writer.log.append('step over') + writer.log.append("step over") writer.write_step_over(thread_id) hit = writer.wait_for_breakpoint_hit(108) thread_id = hit.thread_id frame_id = hit.frame_id - writer.log.append('get frame') + writer.log.append("get frame") writer.write_get_frame(thread_id, frame_id) - writer.log.append('run thread') + writer.log.append("run thread") writer.write_run_thread(thread_id) - writer.log.append('asserting') + writer.log.append("asserting") try: - assert 13 == writer._sequence, 'Expected 13. Had: %s' % writer._sequence + assert 13 == writer._sequence, "Expected 13. Had: %s" % writer._sequence except: - writer.log.append('assert failed!') + writer.log.append("assert failed!") raise - writer.log.append('asserted') + writer.log.append("asserted") writer.finished_ok = True def test_case_2(case_setup): - with case_setup.test_file('_debugger_case2.py') as writer: - writer.write_add_breakpoint(3, 'Call4') # seq = 3 + with case_setup.test_file("_debugger_case2.py") as writer: + writer.write_add_breakpoint(3, "Call4") # seq = 3 writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() @@ -92,7 +121,7 @@ def test_case_2(case_setup): writer.write_get_frame(thread_id, frame_id) # Note: write get frame but not waiting for it to be gotten. - writer.write_add_breakpoint(14, 'Call2') + writer.write_add_breakpoint(14, "Call2") writer.write_run_thread(thread_id) @@ -104,29 +133,28 @@ def test_case_2(case_setup): writer.write_run_thread(thread_id) - writer.log.append('Checking sequence. Found: %s' % (writer._sequence)) - assert 15 == writer._sequence, 'Expected 15. Had: %s' % writer._sequence + writer.log.append("Checking sequence. Found: %s" % (writer._sequence)) + assert 15 == writer._sequence, "Expected 15. Had: %s" % writer._sequence - writer.log.append('Marking finished ok.') + writer.log.append("Marking finished ok.") writer.finished_ok = True @pytest.mark.parametrize( - 'skip_suspend_on_breakpoint_exception, skip_print_breakpoint_exception', + "skip_suspend_on_breakpoint_exception, skip_print_breakpoint_exception", ( - [['NameError'], []], - [['NameError'], ['NameError']], + [["NameError"], []], + [["NameError"], ["NameError"]], [[], []], # Empty means it'll suspend/print in any exception - [[], ['NameError']], - [['ValueError'], ['Exception']], - [['Exception'], ['ValueError']], # ValueError will also suspend/print since we're dealing with a NameError - ) + [[], ["NameError"]], + [["ValueError"], ["Exception"]], + [["Exception"], ["ValueError"]], # ValueError will also suspend/print since we're dealing with a NameError + ), ) def test_case_breakpoint_condition_exc(case_setup, skip_suspend_on_breakpoint_exception, skip_print_breakpoint_exception): - msgs_in_stderr = ( - 'Error while evaluating expression in conditional breakpoint: i > 5', - 'Traceback (most recent call last):', + "Error while evaluating expression in conditional breakpoint: i > 5", + "Traceback (most recent call last):", 'File "", line 1, in ', ) @@ -146,18 +174,16 @@ def _ignore_stderr_line(line): return False - with case_setup.test_file('_debugger_case_breakpoint_condition_exc.py') as writer: - + with case_setup.test_file("_debugger_case_breakpoint_condition_exc.py") as writer: original_ignore_stderr_line = writer._ignore_stderr_line writer._ignore_stderr_line = _ignore_stderr_line writer.write_suspend_on_breakpoint_exception(skip_suspend_on_breakpoint_exception, skip_print_breakpoint_exception) - expect_print = skip_print_breakpoint_exception in ([], ['ValueError']) - expect_suspend = skip_suspend_on_breakpoint_exception in ([], ['ValueError']) + expect_print = skip_print_breakpoint_exception in ([], ["ValueError"]) + expect_suspend = skip_suspend_on_breakpoint_exception in ([], ["ValueError"]) - breakpoint_id = writer.write_add_breakpoint( - writer.get_line_index_with_content('break here'), 'Call', condition='i > 5') + breakpoint_id = writer.write_add_breakpoint(writer.get_line_index_with_content("break here"), "Call", condition="i > 5") if not expect_print: _original = writer.reader_thread.on_message_found @@ -178,18 +204,15 @@ def check_error_msg(stderr): if msg in stderr: break else: - raise AssertionError('Did not find any of: %s in stderr: %s' % ( - msgs_one_in_stderr, stderr)) + raise AssertionError("Did not find any of: %s in stderr: %s" % (msgs_one_in_stderr, stderr)) if expect_print: msg, ctx = writer.wait_for_output() - check_error_msg(msg.replace('>', '>')) + check_error_msg(msg.replace(">", ">")) def wait_for_suspend(): - def accept_message(msg): - if msg.startswith('%s\t' % CMD_GET_BREAKPOINT_EXCEPTION) or \ - ('stop_reason="%s"' % REASON_STOP_ON_BREAKPOINT) in msg: + if msg.startswith("%s\t" % CMD_GET_BREAKPOINT_EXCEPTION) or ('stop_reason="%s"' % REASON_STOP_ON_BREAKPOINT) in msg: return True return False @@ -198,7 +221,7 @@ def accept_message(msg): msg2 = writer.wait_for_message(accept_message) try: hitmsg = msg1 - msg1.thread['stop_reason'] + msg1.thread["stop_reason"] except: hitmsg = msg2 hit = writer._get_stack_as_hit(hitmsg) @@ -220,8 +243,8 @@ def accept_message(msg): msg = writer.wait_for_message(CMD_GET_FRAME) name_to_value = {} for var in msg.var: - name_to_value[var['name']] = var['value'] - assert name_to_value == {'i': 'int: 6', 'last_i': 'int: 6'} + name_to_value[var["name"]] = var["value"] + assert name_to_value == {"i": "int: 6", "last_i": "int: 6"} writer.write_remove_breakpoint(breakpoint_id) @@ -231,8 +254,8 @@ def accept_message(msg): def test_case_remove_breakpoint(case_setup): - with case_setup.test_file('_debugger_case_remove_breakpoint.py') as writer: - breakpoint_id = writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + with case_setup.test_file("_debugger_case_remove_breakpoint.py") as writer: + breakpoint_id = writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() @@ -243,9 +266,8 @@ def test_case_remove_breakpoint(case_setup): def test_case_double_remove_breakpoint(case_setup): - - with case_setup.test_file('_debugger_case_remove_breakpoint.py') as writer: - breakpoint_id = writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + with case_setup.test_file("_debugger_case_remove_breakpoint.py") as writer: + breakpoint_id = writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() @@ -256,12 +278,12 @@ def test_case_double_remove_breakpoint(case_setup): writer.finished_ok = True -@pytest.mark.skipif(IS_IRONPYTHON, reason='This test fails once in a while due to timing issues on IronPython, so, skipping it.') +@pytest.mark.skipif(IS_IRONPYTHON, reason="This test fails once in a while due to timing issues on IronPython, so, skipping it.") def test_case_3(case_setup): - with case_setup.test_file('_debugger_case3.py') as writer: + with case_setup.test_file("_debugger_case3.py") as writer: writer.write_make_initial_run() - time.sleep(.5) - breakpoint_id = writer.write_add_breakpoint(4, '') + time.sleep(0.5) + breakpoint_id = writer.write_add_breakpoint(4, "") hit = writer.wait_for_breakpoint_hit() thread_id = hit.thread_id @@ -285,7 +307,7 @@ def test_case_3(case_setup): def test_case_suspend_thread(case_setup): - with case_setup.test_file('_debugger_case4.py') as writer: + with case_setup.test_file("_debugger_case4.py") as writer: writer.write_make_initial_run() thread_id = writer.wait_for_new_thread() @@ -294,23 +316,25 @@ def test_case_suspend_thread(case_setup): while True: hit = writer.wait_for_breakpoint_hit((REASON_THREAD_SUSPEND, REASON_STOP_ON_BREAKPOINT)) - if hit.name == 'sleep': + if hit.name == "sleep": break # Ok, broke on 'sleep'. else: # i.e.: if it doesn't hit on 'sleep', release and pause again. writer.write_run_thread(thread_id) - time.sleep(.1) + time.sleep(0.1) writer.write_suspend_thread(thread_id) assert hit.thread_id == thread_id - writer.write_evaluate_expression('%s\t%s\t%s' % (hit.thread_id, hit.frame_id, 'LOCAL'), 'exit_while_loop()') - writer.wait_for_evaluation([ + writer.write_evaluate_expression("%s\t%s\t%s" % (hit.thread_id, hit.frame_id, "LOCAL"), "exit_while_loop()") + writer.wait_for_evaluation( [ - '') # no vars at this point + writer.wait_for_vars("") # no vars at this point writer.write_step_over(hit.thread_id) - writer.wait_for_breakpoint_hit('108') + writer.wait_for_breakpoint_hit("108") writer.write_get_frame(hit.thread_id, hit.frame_id) - writer.wait_for_vars([ + writer.wait_for_vars( [ - '%0A'.format(builtin_qualifier), - '%0A'.format( + builtin_qualifier + ), + '%0A%0A'.format(builtin_qualifier), - '%0A%0A', # jython + [ + '%0A%0A'.format( + builtin_qualifier + ), + '%0A%0A', # jython + ] ] - ]) + ) writer.write_run_thread(hit.thread_id) - assert 17 == writer._sequence, 'Expected 17. Had: %s' % writer._sequence + assert 17 == writer._sequence, "Expected 17. Had: %s" % writer._sequence writer.finished_ok = True def test_case_8(case_setup): - with case_setup.test_file('_debugger_case89.py') as writer: - writer.write_add_breakpoint(10, 'Method3') + with case_setup.test_file("_debugger_case89.py") as writer: + writer.write_add_breakpoint(10, "Method3") writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') + hit = writer.wait_for_breakpoint_hit("111") writer.write_step_return(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('109', line=15) + hit = writer.wait_for_breakpoint_hit("109", line=15) writer.write_run_thread(hit.thread_id) - assert 9 == writer._sequence, 'Expected 9. Had: %s' % writer._sequence + assert 9 == writer._sequence, "Expected 9. Had: %s" % writer._sequence writer.finished_ok = True def test_case_9(case_setup): - with case_setup.test_file('_debugger_case89.py') as writer: - writer.write_add_breakpoint(10, 'Method3') + with case_setup.test_file("_debugger_case89.py") as writer: + writer.write_add_breakpoint(10, "Method3") writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') + hit = writer.wait_for_breakpoint_hit("111") # Note: no active exception (should not give an error and should return no # exception details as there's no exception). writer.write_get_current_exception(hit.thread_id) msg = writer.wait_for_message(CMD_GET_EXCEPTION_DETAILS) - assert msg.thread['id'] == hit.thread_id - assert not hasattr(msg.thread, 'frames') # No frames should be found. + assert msg.thread["id"] == hit.thread_id + assert not hasattr(msg.thread, "frames") # No frames should be found. writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('108', line=11) + hit = writer.wait_for_breakpoint_hit("108", line=11) writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('108', line=12) + hit = writer.wait_for_breakpoint_hit("108", line=12) writer.write_run_thread(hit.thread_id) - assert 13 == writer._sequence, 'Expected 13. Had: %s' % writer._sequence + assert 13 == writer._sequence, "Expected 13. Had: %s" % writer._sequence writer.finished_ok = True def test_case_10(case_setup): - with case_setup.test_file('_debugger_case_simple_calls.py') as writer: - writer.write_add_breakpoint(2, 'None') # None or Method should make hit. + with case_setup.test_file("_debugger_case_simple_calls.py") as writer: + writer.write_add_breakpoint(2, "None") # None or Method should make hit. writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') + hit = writer.wait_for_breakpoint_hit("111") writer.write_step_return(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('109', line=11) + hit = writer.wait_for_breakpoint_hit("109", line=11) writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('108', line=12) + hit = writer.wait_for_breakpoint_hit("108", line=12) writer.write_run_thread(hit.thread_id) - assert 11 == writer._sequence, 'Expected 11. Had: %s' % writer._sequence + assert 11 == writer._sequence, "Expected 11. Had: %s" % writer._sequence writer.finished_ok = True def test_case_11(case_setup): - with case_setup.test_file('_debugger_case_simple_calls.py') as writer: - writer.write_add_breakpoint(2, 'Method1') + with case_setup.test_file("_debugger_case_simple_calls.py") as writer: + writer.write_add_breakpoint(2, "Method1") writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_BREAKPOINT, line=2) - assert hit.name == 'Method1' + assert hit.name == "Method1" writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit(REASON_STEP_OVER, line=3) - assert hit.name == 'Method1' + assert hit.name == "Method1" writer.write_step_over(hit.thread_id) if PYDEVD_USE_SYS_MONITORING: hit = writer.wait_for_breakpoint_hit(REASON_STEP_OVER, line=11) # Reverts to step return - assert hit.name == 'Method2' + assert hit.name == "Method2" writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit(REASON_STEP_OVER, line=12) - assert hit.name == 'Method2' + assert hit.name == "Method2" else: hit = writer.wait_for_breakpoint_hit(REASON_STEP_OVER, line=12) # Reverts to step in - assert hit.name == 'Method2' + assert hit.name == "Method2" writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit(REASON_STEP_OVER, line=13) - assert hit.name == 'Method2' + assert hit.name == "Method2" writer.write_step_over(hit.thread_id) if PYDEVD_USE_SYS_MONITORING: hit = writer.wait_for_breakpoint_hit(REASON_STEP_OVER, line=17) # Reverts to step return - assert hit.name == '' + assert hit.name == "" writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit(REASON_STEP_OVER, line=18) - assert hit.name == '' + assert hit.name == "" else: hit = writer.wait_for_breakpoint_hit(REASON_STEP_OVER, line=18) # Reverts to step in - assert hit.name == '' + assert hit.name == "" # Finish with a step over writer.write_step_over(hit.thread_id) @@ -607,31 +635,31 @@ def test_case_12(case_setup): # Note: In CPython we now ignore the function names, so, we'll stop at the breakpoint in line 2 # regardless of the function name (we decide whether to stop in a line or not through the function # lines). - with case_setup.test_file('_debugger_case_simple_calls.py') as writer: - writer.write_add_breakpoint(2, '') # Should not be hit: setting empty function (not None) should only hit global. - writer.write_add_breakpoint(6, 'Method1a') - writer.write_add_breakpoint(11, 'Method2') + with case_setup.test_file("_debugger_case_simple_calls.py") as writer: + writer.write_add_breakpoint(2, "") # Should not be hit: setting empty function (not None) should only hit global. + writer.write_add_breakpoint(6, "Method1a") + writer.write_add_breakpoint(11, "Method2") writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111', line=11) + hit = writer.wait_for_breakpoint_hit("111", line=11) writer.write_step_return(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('111', line=6 if IS_JYTHON else 2) # not a return (it stopped in the other breakpoint) + hit = writer.wait_for_breakpoint_hit("111", line=6 if IS_JYTHON else 2) # not a return (it stopped in the other breakpoint) writer.write_run_thread(hit.thread_id) if not IS_JYTHON: - hit = writer.wait_for_breakpoint_hit('111', line=6) + hit = writer.wait_for_breakpoint_hit("111", line=6) writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.skipif(IS_IRONPYTHON, reason='Failing on IronPython (needs to be investigated).') +@pytest.mark.skipif(IS_IRONPYTHON, reason="Failing on IronPython (needs to be investigated).") def test_case_property_trace_enable_disable(case_setup): - with case_setup.test_file('_debugger_case13.py') as writer: + with case_setup.test_file("_debugger_case13.py") as writer: def _ignore_stderr_line(line): if original_ignore_stderr_line(line): @@ -640,7 +668,8 @@ def _ignore_stderr_line(line): if IS_JYTHON: for expected in ( "RuntimeWarning: Parent module '_pydevd_bundle' not found while handling absolute import", - "import __builtin__"): + "import __builtin__", + ): if expected in line: return True @@ -649,37 +678,37 @@ def _ignore_stderr_line(line): original_ignore_stderr_line = writer._ignore_stderr_line writer._ignore_stderr_line = _ignore_stderr_line - writer.write_add_breakpoint(35, 'main') + writer.write_add_breakpoint(35, "main") writer.write("%s\t%s\t%s" % (CMD_SET_PROPERTY_TRACE, writer.next_seq(), "true;false;false;true")) writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') + hit = writer.wait_for_breakpoint_hit("111") writer.write_get_frame(hit.thread_id, hit.frame_id) writer.write_step_in(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('107', line=25) + hit = writer.wait_for_breakpoint_hit("107", line=25) # Should go inside setter method writer.write_step_in(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('107', line=36) + hit = writer.wait_for_breakpoint_hit("107", line=36) writer.write_step_in(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('107', line=21) + hit = writer.wait_for_breakpoint_hit("107", line=21) # Should go inside getter method writer.write_step_in(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('107') + hit = writer.wait_for_breakpoint_hit("107") # Disable property tracing writer.write("%s\t%s\t%s" % (CMD_SET_PROPERTY_TRACE, writer.next_seq(), "true;true;true;true")) writer.write_step_in(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('107', line=39) + hit = writer.wait_for_breakpoint_hit("107", line=39) # Should Skip step into properties setter # Enable property tracing writer.write("%s\t%s\t%s" % (CMD_SET_PROPERTY_TRACE, writer.next_seq(), "true;false;false;true")) writer.write_step_in(hit.thread_id) - hit = writer.wait_for_breakpoint_hit('107', line=8) + hit = writer.wait_for_breakpoint_hit("107", line=8) # Should go inside getter method writer.write_run_thread(hit.thread_id) @@ -689,56 +718,62 @@ def _ignore_stderr_line(line): def test_case_14(case_setup): # Interactive Debug Console - with case_setup.test_file('_debugger_case14.py') as writer: - writer.write_add_breakpoint(22, 'main') + with case_setup.test_file("_debugger_case14.py") as writer: + writer.write_add_breakpoint(22, "main") writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') - assert hit.thread_id, '%s not valid.' % hit.thread_id - assert hit.frame_id, '%s not valid.' % hit.frame_id + hit = writer.wait_for_breakpoint_hit("111") + assert hit.thread_id, "%s not valid." % hit.thread_id + assert hit.frame_id, "%s not valid." % hit.frame_id # Access some variable writer.write_debug_console_expression("%s\t%s\tEVALUATE\tcarObj.color" % (hit.thread_id, hit.frame_id)) - writer.wait_for_var(['False', '%27Black%27']) - assert 7 == writer._sequence, 'Expected 9. Had: %s' % writer._sequence + writer.wait_for_var(["False", "%27Black%27"]) + assert 7 == writer._sequence, "Expected 9. Had: %s" % writer._sequence # Change some variable writer.write_debug_console_expression("%s\t%s\tEVALUATE\tcarObj.color='Red'" % (hit.thread_id, hit.frame_id)) writer.write_debug_console_expression("%s\t%s\tEVALUATE\tcarObj.color" % (hit.thread_id, hit.frame_id)) - writer.wait_for_var(['False', '%27Red%27']) - assert 11 == writer._sequence, 'Expected 13. Had: %s' % writer._sequence + writer.wait_for_var(["False", "%27Red%27"]) + assert 11 == writer._sequence, "Expected 13. Had: %s" % writer._sequence # Iterate some loop writer.write_debug_console_expression("%s\t%s\tEVALUATE\tfor i in range(3):" % (hit.thread_id, hit.frame_id)) - writer.wait_for_var(['True']) + writer.wait_for_var(["True"]) writer.write_debug_console_expression("%s\t%s\tEVALUATE\t print(i)" % (hit.thread_id, hit.frame_id)) - writer.wait_for_var(['True']) + writer.wait_for_var(["True"]) writer.write_debug_console_expression("%s\t%s\tEVALUATE\t" % (hit.thread_id, hit.frame_id)) writer.wait_for_var( - [ - 'False' ] - ) - assert 17 == writer._sequence, 'Expected 19. Had: %s' % writer._sequence + ['False'] + ) + assert 17 == writer._sequence, "Expected 19. Had: %s" % writer._sequence writer.write_run_thread(hit.thread_id) writer.finished_ok = True def test_case_15(case_setup): - with case_setup.test_file('_debugger_case15.py') as writer: - writer.write_add_breakpoint(22, 'main') + with case_setup.test_file("_debugger_case15.py") as writer: + writer.write_add_breakpoint(22, "main") writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_BREAKPOINT) # Access some variable - writer.write_custom_operation("%s\t%s\tEXPRESSION\tcarObj.color" % (hit.thread_id, hit.frame_id), "EXEC", "f=lambda x: 'val=%s' % x", "f") - writer.wait_for_custom_operation('val=Black') - assert 7 == writer._sequence, 'Expected 7. Had: %s' % writer._sequence - - writer.write_custom_operation("%s\t%s\tEXPRESSION\tcarObj.color" % (hit.thread_id, hit.frame_id), "EXECFILE", debugger_unittest._get_debugger_test_file('_debugger_case15_execfile.py'), "f") - writer.wait_for_custom_operation('val=Black') - assert 9 == writer._sequence, 'Expected 9. Had: %s' % writer._sequence + writer.write_custom_operation( + "%s\t%s\tEXPRESSION\tcarObj.color" % (hit.thread_id, hit.frame_id), "EXEC", "f=lambda x: 'val=%s' % x", "f" + ) + writer.wait_for_custom_operation("val=Black") + assert 7 == writer._sequence, "Expected 7. Had: %s" % writer._sequence + + writer.write_custom_operation( + "%s\t%s\tEXPRESSION\tcarObj.color" % (hit.thread_id, hit.frame_id), + "EXECFILE", + debugger_unittest._get_debugger_test_file("_debugger_case15_execfile.py"), + "f", + ) + writer.wait_for_custom_operation("val=Black") + assert 9 == writer._sequence, "Expected 9. Had: %s" % writer._sequence writer.write_run_thread(hit.thread_id) writer.finished_ok = True @@ -749,9 +784,9 @@ def test_case_16_resolve_numpy_array(case_setup): try: import numpy except ImportError: - pytest.skip('numpy not available') - with case_setup.test_file('_debugger_case16.py') as writer: - writer.write_add_breakpoint(9, 'main') + pytest.skip("numpy not available") + with case_setup.test_file("_debugger_case16.py") as writer: + writer.write_add_breakpoint(9, "main") writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_BREAKPOINT) @@ -761,79 +796,101 @@ def test_case_16_resolve_numpy_array(case_setup): # First pass check is that we have all three expected variables defined writer.write_get_frame(hit.thread_id, hit.frame_id) - writer.wait_for_multiple_vars(( - ( - '', - '' - ), - + writer.wait_for_multiple_vars( ( - '', - '' - ), - - # Any of the ones below will do. - ( - '', - '' + ( + '', + '', + ), + ( + '', + '', + ), + # Any of the ones below will do. + ( + '', + '', + ), ) - )) + ) # For each variable, check each of the resolved (meta data) attributes... - writer.write_get_variable(hit.thread_id, hit.frame_id, 'smallarray') - writer.wait_for_multiple_vars(( - ''.format(builtin_qualifier), - ''.format(builtin_qualifier), - ''.format(builtin_qualifier), - ''.format(builtin_qualifier), - ], - [ - ''.format(builtin_qualifier), - ''.format(builtin_qualifier), - ''.format(builtin_qualifier), - ''.format(builtin_qualifier), - ], - ''.format( + builtin_qualifier + ), + ''.format( + builtin_qualifier + ), + ''.format( + builtin_qualifier + ), + ''.format( + builtin_qualifier + ), + ], + [ + ''.format( + builtin_qualifier + ), + ''.format( + builtin_qualifier + ), + ''.format( + builtin_qualifier + ), + ''.format( + builtin_qualifier + ), + ], + '%0A'.format(builtin_qualifier,)) + writer.write_change_variable(hit.thread_id, hit.frame_id, "a", "40") + writer.wait_for_var( + '%0A'.format( + builtin_qualifier, + ) + ) writer.write_run_thread(hit.thread_id) writer.finished_ok = True @@ -921,28 +982,30 @@ def test_case_18(case_setup): def test_case_19(case_setup): # Check evaluate '__' attributes - with case_setup.test_file('_debugger_case19.py') as writer: + with case_setup.test_file("_debugger_case19.py") as writer: writer.write_add_breakpoint(8, None) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_BREAKPOINT, line=8) - writer.write_evaluate_expression('%s\t%s\t%s' % (hit.thread_id, hit.frame_id, 'LOCAL'), 'a.__var') - writer.wait_for_evaluation([ + writer.write_evaluate_expression("%s\t%s\t%s" % (hit.thread_id, hit.frame_id, "LOCAL"), "a.__var") + writer.wait_for_evaluation( [ - 'Hello' in contents - assert 'Flask-Jinja-Test' in contents + assert "Hello" in contents + assert "Flask-Jinja-Test" in contents writer.finished_ok = True -@pytest.mark.skipif(not TEST_DJANGO, reason='No django available') +@pytest.mark.skipif(not TEST_DJANGO, reason="No django available") def test_case_django_a(case_setup_django): - def get_environ(writer): env = os.environ.copy() - env.update({ - 'PYDEVD_FILTER_LIBRARIES': '1', # Global setting for in project or not - "IDE_PROJECT_ROOTS": debugger_unittest._get_debugger_test_file(writer.DJANGO_FOLDER) - }) + env.update( + { + "PYDEVD_FILTER_LIBRARIES": "1", # Global setting for in project or not + "IDE_PROJECT_ROOTS": debugger_unittest._get_debugger_test_file(writer.DJANGO_FOLDER), + } + ) return env - with case_setup_django.test_file(EXPECTED_RETURNCODE='any', get_environ=get_environ) as writer: + with case_setup_django.test_file(EXPECTED_RETURNCODE="any", get_environ=get_environ) as writer: writer.write_make_initial_run() # Wait for the first request that works... for i in range(4): try: - t = writer.create_request_thread('my_app') + t = writer.create_request_thread("my_app") t.start() contents = t.wait_for_contents() - contents = contents.replace(' ', '').replace('\r', '').replace('\n', '') - assert contents == '
  • v1:v1
  • v2:v2
' + contents = contents.replace(" ", "").replace("\r", "").replace("\n", "") + assert contents == "
  • v1:v1
  • v2:v2
" break except: if i == 3: raise continue - writer.write_add_breakpoint_django(5, None, 'index.html') - t = writer.create_request_thread('my_app') + writer.write_add_breakpoint_django(5, None, "index.html") + t = writer.create_request_thread("my_app") t.start() hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_BREAKPOINT, line=5) - writer.write_get_variable(hit.thread_id, hit.frame_id, 'entry') - writer.wait_for_vars([ - '
  • v1:v1
  • v2:v2
  • ' % (contents,)) + contents = contents.replace(" ", "").replace("\r", "").replace("\n", "") + if contents != "
    • v1:v1
    • v2:v2
    ": + raise AssertionError("%s !=
    • v1:v1
    • v2:v2
    " % (contents,)) writer.finished_ok = True -@pytest.mark.skipif(not TEST_DJANGO, reason='No django available') +@pytest.mark.skipif(not TEST_DJANGO, reason="No django available") def test_case_django_step_next(case_setup_django): - def get_environ(writer): env = os.environ.copy() - env.update({ - 'PYDEVD_FILTER_LIBRARIES': '1', # Global setting for in project or not - "IDE_PROJECT_ROOTS": debugger_unittest._get_debugger_test_file(writer.DJANGO_FOLDER) - }) + env.update( + { + "PYDEVD_FILTER_LIBRARIES": "1", # Global setting for in project or not + "IDE_PROJECT_ROOTS": debugger_unittest._get_debugger_test_file(writer.DJANGO_FOLDER), + } + ) return env - with case_setup_django.test_file(EXPECTED_RETURNCODE='any', get_environ=get_environ) as writer: + with case_setup_django.test_file(EXPECTED_RETURNCODE="any", get_environ=get_environ) as writer: writer.write_make_initial_run() # Wait for the first request that works... for i in range(4): try: - t = writer.create_request_thread('my_app') + t = writer.create_request_thread("my_app") t.start() contents = t.wait_for_contents() - contents = contents.replace(' ', '').replace('\r', '').replace('\n', '') - assert contents == '
    • v1:v1
    • v2:v2
    ' + contents = contents.replace(" ", "").replace("\r", "").replace("\n", "") + assert contents == "
    • v1:v1
    • v2:v2
    " break except: if i == 3: raise continue - writer.write_add_breakpoint_django(3, None, 'index.html') - t = writer.create_request_thread('my_app') + writer.write_add_breakpoint_django(3, None, "index.html") + t = writer.create_request_thread("my_app") t.start() hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_BREAKPOINT, line=3) @@ -1086,22 +1145,22 @@ def get_environ(writer): contents = t.wait_for_contents() - contents = contents.replace(' ', '').replace('\r', '').replace('\n', '') - if contents != '
    • v1:v1
    • v2:v2
    ': - raise AssertionError('%s !=
    • v1:v1
    • v2:v2
    ' % (contents,)) + contents = contents.replace(" ", "").replace("\r", "").replace("\n", "") + if contents != "
    • v1:v1
    • v2:v2
    ": + raise AssertionError("%s !=
    • v1:v1
    • v2:v2
    " % (contents,)) writer.finished_ok = True -@pytest.mark.skipif(not TEST_DJANGO, reason='No django available') +@pytest.mark.skipif(not TEST_DJANGO, reason="No django available") def test_case_django_b(case_setup_django): - with case_setup_django.test_file(EXPECTED_RETURNCODE='any') as writer: - writer.write_add_breakpoint_django(4, None, 'name.html') + with case_setup_django.test_file(EXPECTED_RETURNCODE="any") as writer: + writer.write_add_breakpoint_django(4, None, "name.html") writer.write_add_exception_breakpoint_django() writer.write_remove_exception_breakpoint_django() writer.write_make_initial_run() - t = writer.create_request_thread('my_app/name') + t = writer.create_request_thread("my_app/name") time.sleep(5) # Give django some time to get to startup before requesting the page t.start() @@ -1113,47 +1172,45 @@ def test_case_django_b(case_setup_django): writer.finished_ok = True -@pytest.mark.skipif(not TEST_DJANGO, reason='No django available') +@pytest.mark.skipif(not TEST_DJANGO, reason="No django available") def test_case_django_template_inherits_no_exception(case_setup_django): - with case_setup_django.test_file(EXPECTED_RETURNCODE='any') as writer: - + with case_setup_django.test_file(EXPECTED_RETURNCODE="any") as writer: # Check that it doesn't have issues with inherits + django exception breakpoints. writer.write_add_exception_breakpoint_django() writer.write_make_initial_run() - t = writer.create_request_thread('my_app/inherits') + t = writer.create_request_thread("my_app/inherits") time.sleep(5) # Give django some time to get to startup before requesting the page t.start() contents = t.wait_for_contents() - contents = contents.replace(' ', '').replace('\r', '').replace('\n', '') + contents = contents.replace(" ", "").replace("\r", "").replace("\n", "") assert contents == '''"chat_mode=True""chat_mode=False"''' writer.finished_ok = True -@pytest.mark.skipif(not TEST_DJANGO, reason='No django available') +@pytest.mark.skipif(not TEST_DJANGO, reason="No django available") def test_case_django_no_var_error(case_setup_django): - with case_setup_django.test_file(EXPECTED_RETURNCODE='any') as writer: - + with case_setup_django.test_file(EXPECTED_RETURNCODE="any") as writer: # Check that it doesn't have issues with inherits + django exception breakpoints. writer.write_add_exception_breakpoint_django() writer.write_make_initial_run() - t = writer.create_request_thread('my_app/no_var_error') + t = writer.create_request_thread("my_app/no_var_error") time.sleep(5) # Give django some time to get to startup before requesting the page t.start() contents = t.wait_for_contents() - contents = contents.replace(' ', '').replace('\r', '').replace('\n', '') - assert contents == '''no_pat_name''' + contents = contents.replace(" ", "").replace("\r", "").replace("\n", "") + assert contents == """no_pat_name""" writer.finished_ok = True -@pytest.mark.skipif(not TEST_DJANGO, reason='No django available') +@pytest.mark.skipif(not TEST_DJANGO, reason="No django available") @pytest.mark.parametrize("jmc", [False, True]) def test_case_django_no_attribute_exception_breakpoint(case_setup_django, jmc): kwargs = {} @@ -1161,23 +1218,25 @@ def test_case_django_no_attribute_exception_breakpoint(case_setup_django, jmc): def get_environ(writer): env = os.environ.copy() - env.update({ - 'PYDEVD_FILTER_LIBRARIES': '1', # Global setting for in project or not - }) + env.update( + { + "PYDEVD_FILTER_LIBRARIES": "1", # Global setting for in project or not + } + ) return env - kwargs['get_environ'] = get_environ + kwargs["get_environ"] = get_environ - with case_setup_django.test_file(EXPECTED_RETURNCODE='any', **kwargs) as writer: + with case_setup_django.test_file(EXPECTED_RETURNCODE="any", **kwargs) as writer: writer.write_add_exception_breakpoint_django() writer.write_make_initial_run() - t = writer.create_request_thread('my_app/template_error') + t = writer.create_request_thread("my_app/template_error") time.sleep(5) # Give django some time to get to startup before requesting the page t.start() - hit = writer.wait_for_breakpoint_hit(REASON_CAUGHT_EXCEPTION, line=7, file='template_error.html') + hit = writer.wait_for_breakpoint_hit(REASON_CAUGHT_EXCEPTION, line=7, file="template_error.html") writer.write_get_frame(hit.thread_id, hit.frame_id) writer.wait_for_var('', 'f', ''] + if "generator" in target_file: + expected_frame_names = ["", "f", ""] else: if sys.version_info[:2] >= (3, 12): - expected_frame_names = ['f', ''] + expected_frame_names = ["f", ""] else: - expected_frame_names = ['', 'f', ''] + expected_frame_names = ["", "f", ""] writer.write_get_current_exception(hit.thread_id) - msg = writer.wait_for_message(accept_message=lambda msg:'exc_type="' in msg and 'exc_desc="' in msg, unquote_msg=False) + msg = writer.wait_for_message(accept_message=lambda msg: 'exc_type="' in msg and 'exc_desc="' in msg, unquote_msg=False) - frame_names = [unquote(f['name']).replace('<', '<').replace('>', '>') for f in msg.thread.frame] + frame_names = [unquote(f["name"]).replace("<", "<").replace(">", ">") for f in msg.thread.frame] assert frame_names == expected_frame_names writer.write_run_thread(hit.thread_id) if not unhandled: - if sys.version_info[:2] >= (3, 12) and 'generator' not in target_file: + if sys.version_info[:2] >= (3, 12) and "generator" not in target_file: expected_lines = [ - writer.get_line_index_with_content('# call exc'), + writer.get_line_index_with_content("# call exc"), ] else: expected_lines = [ - writer.get_line_index_with_content('# exc line'), - writer.get_line_index_with_content('# call exc'), + writer.get_line_index_with_content("# exc line"), + writer.get_line_index_with_content("# call exc"), ] for expected_line in expected_lines: @@ -1497,9 +1562,9 @@ def additional_output_checks(writer, stdout, stderr): assert hit.line == expected_line writer.write_get_current_exception(hit.thread_id) - msg = writer.wait_for_message(accept_message=lambda msg:'exc_type="' in msg and 'exc_desc="' in msg, unquote_msg=False) + msg = writer.wait_for_message(accept_message=lambda msg: 'exc_type="' in msg and 'exc_desc="' in msg, unquote_msg=False) - frame_names = [unquote(f['name']).replace('<', '<').replace('>', '>') for f in msg.thread.frame] + frame_names = [unquote(f["name"]).replace("<", "<").replace(">", ">") for f in msg.thread.frame] assert frame_names == expected_frame_names writer.write_run_thread(hit.thread_id) @@ -1507,40 +1572,39 @@ def additional_output_checks(writer, stdout, stderr): writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Failing on Jython -- needs to be investigated).') +@pytest.mark.skipif(IS_JYTHON, reason="Failing on Jython -- needs to be investigated).") def test_unhandled_exceptions_basic(case_setup): - def check_test_suceeded_msg(writer, stdout, stderr): # Don't call super (we have an unhandled exception in the stack trace). - return 'TEST SUCEEDED' in ''.join(stdout) and 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stdout) and "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): - if 'raise Exception' not in stderr: - raise AssertionError('Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s' % ( - stdout, stderr)) + if "raise Exception" not in stderr: + raise AssertionError("Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s" % (stdout, stderr)) with case_setup.test_file( - '_debugger_case_unhandled_exceptions.py', - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks, - EXPECTED_RETURNCODE=1, - ) as writer: - - writer.write_add_exception_breakpoint_with_policy('Exception', "0", "1", "0") + "_debugger_case_unhandled_exceptions.py", + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + EXPECTED_RETURNCODE=1, + ) as writer: + writer.write_add_exception_breakpoint_with_policy("Exception", "0", "1", "0") writer.write_make_initial_run() def check(hit, exc_type, exc_desc): writer.write_get_current_exception(hit.thread_id) - msg = writer.wait_for_message(accept_message=lambda msg:exc_type in msg and 'exc_type="' in msg and 'exc_desc="' in msg, unquote_msg=False) - assert unquote(msg.thread['exc_desc']) == exc_desc - assert unquote(msg.thread['exc_type']) in ( + msg = writer.wait_for_message( + accept_message=lambda msg: exc_type in msg and 'exc_type="' in msg and 'exc_desc="' in msg, unquote_msg=False + ) + assert unquote(msg.thread["exc_desc"]) == exc_desc + assert unquote(msg.thread["exc_type"]) in ( "<type 'exceptions.%s'>" % (exc_type,), # py2 - "<class '%s'>" % (exc_type,) # py3 + "<class '%s'>" % (exc_type,), # py3 ) if len(msg.thread.frame) == 0: - assert unquote(unquote(msg.thread.frame['file'])).endswith('_debugger_case_unhandled_exceptions.py') + assert unquote(unquote(msg.thread.frame["file"])).endswith("_debugger_case_unhandled_exceptions.py") else: - assert unquote(unquote(msg.thread.frame[0]['file'])).endswith('_debugger_case_unhandled_exceptions.py') + assert unquote(unquote(msg.thread.frame[0]["file"])).endswith("_debugger_case_unhandled_exceptions.py") writer.write_run_thread(hit.thread_id) # Will stop in 2 background threads @@ -1550,19 +1614,19 @@ def check(hit, exc_type, exc_desc): hit1 = writer.wait_for_breakpoint_hit(REASON_UNCAUGHT_EXCEPTION) thread_id2 = hit1.thread_id - if hit0.name == 'thread_func2': - check(hit0, 'ValueError', 'in thread 2') - check(hit1, 'Exception', 'in thread 1') + if hit0.name == "thread_func2": + check(hit0, "ValueError", "in thread 2") + check(hit1, "Exception", "in thread 1") else: - check(hit0, 'Exception', 'in thread 1') - check(hit1, 'ValueError', 'in thread 2') + check(hit0, "Exception", "in thread 1") + check(hit1, "ValueError", "in thread 2") writer.write_run_thread(thread_id1) writer.write_run_thread(thread_id2) # Will stop in main thread hit = writer.wait_for_breakpoint_hit(REASON_UNCAUGHT_EXCEPTION) - assert hit.name == '' + assert hit.name == "" thread_id3 = hit.thread_id # Requesting the stack in an unhandled exception should provide the stack of the exception, @@ -1570,84 +1634,76 @@ def check(hit, exc_type, exc_desc): writer.write_get_thread_stack(thread_id3) msg = writer.wait_for_message(CMD_GET_THREAD_STACK) assert len(msg.thread.frame) == 0 # In main thread (must have no back frames). - assert msg.thread.frame['name'] == '' - check(hit, 'IndexError', 'in main') + assert msg.thread.frame["name"] == "" + check(hit, "IndexError", "in main") - writer.log.append('Marking finished ok.') + writer.log.append("Marking finished ok.") writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Failing on Jython -- needs to be investigated).') +@pytest.mark.skipif(IS_JYTHON, reason="Failing on Jython -- needs to be investigated).") def test_unhandled_exceptions_in_top_level1(case_setup_unhandled_exceptions): - with case_setup_unhandled_exceptions.test_file( - '_debugger_case_unhandled_exceptions_on_top_level.py', - EXPECTED_RETURNCODE=1, - ) as writer: - - writer.write_add_exception_breakpoint_with_policy('Exception', "0", "1", "0") + "_debugger_case_unhandled_exceptions_on_top_level.py", + EXPECTED_RETURNCODE=1, + ) as writer: + writer.write_add_exception_breakpoint_with_policy("Exception", "0", "1", "0") writer.write_make_initial_run() # Will stop in main thread hit = writer.wait_for_breakpoint_hit(REASON_UNCAUGHT_EXCEPTION) writer.write_run_thread(hit.thread_id) - writer.log.append('Marking finished ok.') + writer.log.append("Marking finished ok.") writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Failing on Jython -- needs to be investigated).') +@pytest.mark.skipif(IS_JYTHON, reason="Failing on Jython -- needs to be investigated).") def test_unhandled_exceptions_in_top_level2(case_setup_unhandled_exceptions): # Note: expecting unhandled exception to be printed to stderr. def get_environ(writer): env = os.environ.copy() - curr_pythonpath = env.get('PYTHONPATH', '') + curr_pythonpath = env.get("PYTHONPATH", "") pydevd_dirname = os.path.dirname(writer.get_pydevd_file()) curr_pythonpath = pydevd_dirname + os.pathsep + curr_pythonpath - env['PYTHONPATH'] = curr_pythonpath + env["PYTHONPATH"] = curr_pythonpath return env def update_command_line_args(writer, args): # Start pydevd with '-m' to see how it deal with being called with # runpy at the start. - assert args[0].endswith('pydevd.py') - args = ['-m', 'pydevd'] + args[1:] + assert args[0].endswith("pydevd.py") + args = ["-m", "pydevd"] + args[1:] return args with case_setup_unhandled_exceptions.test_file( - '_debugger_case_unhandled_exceptions_on_top_level.py', - get_environ=get_environ, - update_command_line_args=update_command_line_args, - EXPECTED_RETURNCODE='any', - ) as writer: - - writer.write_add_exception_breakpoint_with_policy('Exception', "0", "1", "0") + "_debugger_case_unhandled_exceptions_on_top_level.py", + get_environ=get_environ, + update_command_line_args=update_command_line_args, + EXPECTED_RETURNCODE="any", + ) as writer: + writer.write_add_exception_breakpoint_with_policy("Exception", "0", "1", "0") writer.write_make_initial_run() # Should stop (only once) in the main thread. hit = writer.wait_for_breakpoint_hit(REASON_UNCAUGHT_EXCEPTION) writer.write_run_thread(hit.thread_id) - writer.log.append('Marking finished ok.') + writer.log.append("Marking finished ok.") writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Failing on Jython -- needs to be investigated).') +@pytest.mark.skipif(IS_JYTHON, reason="Failing on Jython -- needs to be investigated).") def test_unhandled_exceptions_in_top_level3(case_setup_unhandled_exceptions): - - with case_setup_unhandled_exceptions.test_file( - '_debugger_case_unhandled_exceptions_on_top_level.py', - EXPECTED_RETURNCODE=1 - ) as writer: - + with case_setup_unhandled_exceptions.test_file("_debugger_case_unhandled_exceptions_on_top_level.py", EXPECTED_RETURNCODE=1) as writer: # Handled and unhandled # PySide2 has a bug in shibokensupport which will try to do: sys._getframe(1). # during the teardown (which will fail as there's no back frame in this case). # So, mark ignore libraries in this case. - writer.write_add_exception_breakpoint_with_policy('Exception', "1", "1", ignore_libraries="1") + writer.write_add_exception_breakpoint_with_policy("Exception", "1", "1", ignore_libraries="1") writer.write_make_initial_run() # Will stop in main thread twice: once one we find that the exception is being @@ -1658,21 +1714,19 @@ def test_unhandled_exceptions_in_top_level3(case_setup_unhandled_exceptions): hit = writer.wait_for_breakpoint_hit(REASON_UNCAUGHT_EXCEPTION) writer.write_run_thread(hit.thread_id) - writer.log.append('Marking finished ok.') + writer.log.append("Marking finished ok.") writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Failing on Jython -- needs to be investigated).') +@pytest.mark.skipif(IS_JYTHON, reason="Failing on Jython -- needs to be investigated).") def test_unhandled_exceptions_in_top_level4(case_setup_unhandled_exceptions): - # Note: expecting unhandled exception to be printed to stderr. with case_setup_unhandled_exceptions.test_file( - '_debugger_case_unhandled_exceptions_on_top_level2.py', - EXPECTED_RETURNCODE=1, - ) as writer: - + "_debugger_case_unhandled_exceptions_on_top_level2.py", + EXPECTED_RETURNCODE=1, + ) as writer: # Handled and unhandled - writer.write_add_exception_breakpoint_with_policy('Exception', "1", "1", "0") + writer.write_add_exception_breakpoint_with_policy("Exception", "1", "1", "0") writer.write_make_initial_run() # We have an exception thrown and handled and another which is thrown and is then unhandled. @@ -1685,33 +1739,32 @@ def test_unhandled_exceptions_in_top_level4(case_setup_unhandled_exceptions): hit = writer.wait_for_breakpoint_hit(REASON_UNCAUGHT_EXCEPTION) writer.write_run_thread(hit.thread_id) - writer.log.append('Marking finished ok.') + writer.log.append("Marking finished ok.") writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='Only for Python.') +@pytest.mark.skipif(not IS_CPYTHON, reason="Only for Python.") def test_case_set_next_statement(case_setup): - - with case_setup.test_file('_debugger_case_set_next_statement.py') as writer: + with case_setup.test_file("_debugger_case_set_next_statement.py") as writer: breakpoint_id = writer.write_add_breakpoint(6, None) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_BREAKPOINT, line=6) # Stop in line a=3 (before setting it) - writer.write_evaluate_expression('%s\t%s\t%s' % (hit.thread_id, hit.frame_id, 'LOCAL'), 'a') + writer.write_evaluate_expression("%s\t%s\t%s" % (hit.thread_id, hit.frame_id, "LOCAL"), "a") writer.wait_for_evaluation('' - assert msg.thread.frame['line'] == str(writer.get_line_index_with_content('break line on unhandled exception')) + assert msg.thread.frame["name"] == "" + assert msg.thread.frame["line"] == str(writer.get_line_index_with_content("break line on unhandled exception")) writer.write_run_thread(hit.thread_id) - writer.log.append('Marking finished ok.') + writer.log.append("Marking finished ok.") writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Requires Python 3.') +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Requires Python 3.") def test_case_throw_exc_reason_xml(case_setup): from _pydevd_bundle.pydevd_comm_constants import CMD_SEND_CURR_EXCEPTION_TRACE def check_test_suceeded_msg(self, stdout, stderr): - return 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): assert "raise RuntimeError('TEST SUCEEDED')" in stderr @@ -1762,18 +1815,16 @@ def additional_output_checks(writer, stdout, stderr): assert "raise Exception('another while handling')" in stderr with case_setup.test_file( - '_debugger_case_raise_with_cause.py', - EXPECTED_RETURNCODE=1, - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks - ) as writer: - - writer.write_add_exception_breakpoint_with_policy('Exception', "0", "1", "0") + "_debugger_case_raise_with_cause.py", + EXPECTED_RETURNCODE=1, + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + ) as writer: + writer.write_add_exception_breakpoint_with_policy("Exception", "0", "1", "0") writer.write_make_initial_run() def accept_message(msg): - if msg.startswith('%s\t' % CMD_SEND_CURR_EXCEPTION_TRACE) or \ - ('stop_reason="%s"' % REASON_UNCAUGHT_EXCEPTION) in msg: + if msg.startswith("%s\t" % CMD_SEND_CURR_EXCEPTION_TRACE) or ('stop_reason="%s"' % REASON_UNCAUGHT_EXCEPTION) in msg: return True return False @@ -1783,7 +1834,7 @@ def accept_message(msg): try: hitmsg = msg1 exctracemsg = msg2 - msg1.thread['stop_reason'] + msg1.thread["stop_reason"] except: hitmsg = msg2 exctracemsg = msg1 @@ -1791,16 +1842,16 @@ def accept_message(msg): name_and_lines = [] for frame in exctracemsg.thread.frame: - name_and_lines.append((frame['name'], frame['line'])) + name_and_lines.append((frame["name"], frame["line"])) assert name_and_lines == [ - ('foobar', '20'), - ('', '23'), - ('[Chained Exc: another while handling] foobar', '18'), - ('[Chained Exc: another while handling] handle', '10'), - ('[Chained Exc: TEST SUCEEDED] foobar', '16'), - ('[Chained Exc: TEST SUCEEDED] method', '6'), - ('[Chained Exc: TEST SUCEEDED] method2', '2'), + ("foobar", "20"), + ("", "23"), + ("[Chained Exc: another while handling] foobar", "18"), + ("[Chained Exc: another while handling] handle", "10"), + ("[Chained Exc: TEST SUCEEDED] foobar", "16"), + ("[Chained Exc: TEST SUCEEDED] method", "6"), + ("[Chained Exc: TEST SUCEEDED] method2", "2"), ] writer.write_get_thread_stack(hit.thread_id) @@ -1810,9 +1861,9 @@ def accept_message(msg): writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='Only for Python.') +@pytest.mark.skipif(not IS_CPYTHON, reason="Only for Python.") def test_case_get_next_statement_targets(case_setup): - with case_setup.test_file('_debugger_case_get_next_statement_targets.py') as writer: + with case_setup.test_file("_debugger_case_get_next_statement_targets.py") as writer: breakpoint_id = writer.write_add_breakpoint(21, None) writer.write_make_initial_run() @@ -1828,7 +1879,7 @@ def test_case_get_next_statement_targets(case_setup): # On Python 3.11 there's now a line 1 (which should be harmless). targets.discard(1) expected = set((2, 3, 5, 8, 9, 10, 12, 13, 14, 15, 17, 18, 19, 21)) - assert targets == expected, 'Expected targets to be %s, was: %s' % (expected, targets) + assert targets == expected, "Expected targets to be %s, was: %s" % (expected, targets) writer.write_remove_breakpoint(breakpoint_id) writer.write_run_thread(hit.thread_id) @@ -1836,7 +1887,7 @@ def test_case_get_next_statement_targets(case_setup): writer.finished_ok = True -@pytest.mark.skipif(IS_IRONPYTHON or IS_JYTHON, reason='Failing on IronPython and Jython (needs to be investigated).') +@pytest.mark.skipif(IS_IRONPYTHON or IS_JYTHON, reason="Failing on IronPython and Jython (needs to be investigated).") def test_case_type_ext(case_setup): # Custom type presentation extensions @@ -1844,144 +1895,143 @@ def get_environ(self): env = os.environ.copy() python_path = env.get("PYTHONPATH", "") - ext_base = debugger_unittest._get_debugger_test_file('my_extensions') - env['PYTHONPATH'] = ext_base + os.pathsep + python_path if python_path else ext_base + ext_base = debugger_unittest._get_debugger_test_file("my_extensions") + env["PYTHONPATH"] = ext_base + os.pathsep + python_path if python_path else ext_base return env - with case_setup.test_file('_debugger_case_type_ext.py', get_environ=get_environ) as writer: + with case_setup.test_file("_debugger_case_type_ext.py", get_environ=get_environ) as writer: writer.get_environ = get_environ writer.write_add_breakpoint(7, None) writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') + hit = writer.wait_for_breakpoint_hit("111") writer.write_get_frame(hit.thread_id, hit.frame_id) - assert writer.wait_for_var([ + assert writer.wait_for_var( [ - r'', - r'', + r''.format(builtin_qualifier)) writer.write_run_thread(hit.thread_id) writer.finished_ok = True def test_case_variable_access(case_setup, pyfile, data_regression): - @pyfile def case_custom(): obj = [ tuple(range(9)), [ tuple(range(5)), - ] + ], ] - print('TEST SUCEEDED') + print("TEST SUCEEDED") with case_setup.test_file(case_custom) as writer: - line = writer.get_line_index_with_content('TEST SUCEEDED') + line = writer.get_line_index_with_content("TEST SUCEEDED") writer.write_add_breakpoint(line) writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') + hit = writer.wait_for_breakpoint_hit("111") writer.write_get_frame(hit.thread_id, hit.frame_id) - frame_vars = writer.wait_for_untangled_message( - accept_message=lambda cmd_id, untangled: cmd_id == CMD_GET_FRAME) + frame_vars = writer.wait_for_untangled_message(accept_message=lambda cmd_id, untangled: cmd_id == CMD_GET_FRAME) - obj_var = [v for v in frame_vars.var if v['name'] == 'obj'][0] - assert obj_var['type'] == 'list' - assert unquote_plus(obj_var['value']) == ": [(0, 1, 2, 3, 4, 5, 6, 7, 8), [(0, 1, 2, 3, 4)]]" - assert obj_var['isContainer'] == "True" + obj_var = [v for v in frame_vars.var if v["name"] == "obj"][0] + assert obj_var["type"] == "list" + assert unquote_plus(obj_var["value"]) == ": [(0, 1, 2, 3, 4, 5, 6, 7, 8), [(0, 1, 2, 3, 4)]]" + assert obj_var["isContainer"] == "True" def _skip_key_in_dict(key): try: int(key) except ValueError: - if 'more' in key or '[' in key: + if "more" in key or "[" in key: return False return True return False def collect_vars(locator, level=0): writer.write("%s\t%s\t%s\t%s" % (CMD_GET_VARIABLE, writer.next_seq(), hit.thread_id, locator)) - obj_vars = writer.wait_for_untangled_message( - accept_message=lambda cmd_id, _untangled: cmd_id == CMD_GET_VARIABLE) + obj_vars = writer.wait_for_untangled_message(accept_message=lambda cmd_id, _untangled: cmd_id == CMD_GET_VARIABLE) for v in obj_vars.var: - if _skip_key_in_dict(v['name']): + if _skip_key_in_dict(v["name"]): continue - new_locator = locator + '\t' + v['name'] + new_locator = locator + "\t" + v["name"] yield level, v, new_locator - if v['isContainer'] == 'True': + if v["isContainer"] == "True": yield from collect_vars(new_locator, level + 1) found = [] - for level, val, _locator in collect_vars('%s\tFRAME\tobj' % hit.frame_id): - found.append(((' ' * level) + val['name'] + ': ' + unquote_plus(val['value']))) + for level, val, _locator in collect_vars("%s\tFRAME\tobj" % hit.frame_id): + found.append(((" " * level) + val["name"] + ": " + unquote_plus(val["value"]))) data_regression.check(found) # Check referrers - full_loc = '%s\t%s\t%s' % (hit.thread_id, hit.frame_id, 'FRAME\tobj\t1\t0') - writer.write_custom_operation(full_loc, 'EXEC', "from _pydevd_bundle.pydevd_referrers import get_referrer_info", "get_referrer_info") + full_loc = "%s\t%s\t%s" % (hit.thread_id, hit.frame_id, "FRAME\tobj\t1\t0") + writer.write_custom_operation( + full_loc, "EXEC", "from _pydevd_bundle.pydevd_referrers import get_referrer_info", "get_referrer_info" + ) msg = writer.wait_for_untangled_message( - double_unquote=True, - accept_message=lambda cmd_id, _untangled: cmd_id == CMD_RUN_CUSTOM_OPERATION) + double_unquote=True, accept_message=lambda cmd_id, _untangled: cmd_id == CMD_RUN_CUSTOM_OPERATION + ) msg_vars = msg.var try: - msg_vars['found_as'] + msg_vars["found_as"] msg_vars = [msg_vars] except: pass # it's a container. for v in msg_vars: - if v['found_as'] == 'list[0]': + if v["found_as"] == "list[0]": # In pypy we may have more than one reference, find out the one - referrer_id = v['id'] + referrer_id = v["id"] assert int(referrer_id) - assert unquote_plus(v['value']) == ": [(0, 1, 2, 3, 4)]" + assert unquote_plus(v["value"]) == ": [(0, 1, 2, 3, 4)]" break else: raise AssertionError("Unable to find ref with list[0]. Found: %s" % (msg_vars,)) found = [] - by_id_locator = '%s\t%s' % (referrer_id, 'BY_ID') + by_id_locator = "%s\t%s" % (referrer_id, "BY_ID") for level, val, _locator in collect_vars(by_id_locator): - found.append(((' ' * level) + val['name'] + ': ' + unquote_plus(val['value']))) + found.append(((" " * level) + val["name"] + ": " + unquote_plus(val["value"]))) - data_regression.check(found, basename='test_case_variable_access_by_id') + data_regression.check(found, basename="test_case_variable_access_by_id") writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.skipif(IS_IRONPYTHON or IS_JYTHON, reason='Failing on IronPython and Jython (needs to be investigated).') +@pytest.mark.skipif(IS_IRONPYTHON or IS_JYTHON, reason="Failing on IronPython and Jython (needs to be investigated).") def test_case_event_ext(case_setup): - def get_environ(self): env = os.environ.copy() python_path = env.get("PYTHONPATH", "") - ext_base = debugger_unittest._get_debugger_test_file('my_extensions') - env['PYTHONPATH'] = ext_base + os.pathsep + python_path if python_path else ext_base + ext_base = debugger_unittest._get_debugger_test_file("my_extensions") + env["PYTHONPATH"] = ext_base + os.pathsep + python_path if python_path else ext_base env["VERIFY_EVENT_TEST"] = "1" return env # Test initialize event for extensions - with case_setup.test_file('_debugger_case_event_ext.py', get_environ=get_environ) as writer: - + with case_setup.test_file("_debugger_case_event_ext.py", get_environ=get_environ) as writer: original_additional_output_checks = writer.additional_output_checks @overrides(writer.additional_output_checks) def additional_output_checks(stdout, stderr): original_additional_output_checks(stdout, stderr) - if 'INITIALIZE EVENT RECEIVED' not in stdout: - raise AssertionError('No initialize event received') + if "INITIALIZE EVENT RECEIVED" not in stdout: + raise AssertionError("No initialize event received") writer.additional_output_checks = additional_output_checks @@ -1989,19 +2039,21 @@ def additional_output_checks(stdout, stderr): writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Jython does not seem to be creating thread started inside tracing (investigate).') +@pytest.mark.skipif(IS_JYTHON, reason="Jython does not seem to be creating thread started inside tracing (investigate).") def test_case_writer_creation_deadlock(case_setup): # check case where there was a deadlock evaluating expressions - with case_setup.test_file('_debugger_case_thread_creation_deadlock.py') as writer: + with case_setup.test_file("_debugger_case_thread_creation_deadlock.py") as writer: writer.write_add_breakpoint(26, None) writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit('111') + hit = writer.wait_for_breakpoint_hit("111") - assert hit.line == 26, 'Expected return to be in line 26, was: %s' % (hit.line,) + assert hit.line == 26, "Expected return to be in line 26, was: %s" % (hit.line,) - writer.write_evaluate_expression('%s\t%s\t%s' % (hit.thread_id, hit.frame_id, 'LOCAL'), 'create_thread()') - writer.wait_for_evaluation('= 3: - binary_junk = binary_junk.decode('utf-8', 'replace') - - return line.startswith(( - 'text', - 'binary', - 'a', - binary_junk, - )) + binary_junk = binary_junk.decode("utf-8", "replace") + + return line.startswith( + ( + "text", + "binary", + "a", + binary_junk, + ) + ) writer._ignore_stderr_line = _ignore_stderr_line # Note: writes to stdout and stderr are now synchronous (so, the order # must always be consistent and there's a message for each write). expected = [ - 'text\n', - 'binary or text\n', - 'ação1\n', + "text\n", + "binary or text\n", + "ação1\n", ] if sys.version_info[0] >= 3: - expected.extend(( - 'binary\n', - 'ação2\n'.encode(encoding='latin1').decode('utf-8', 'replace'), - 'ação3\n', - )) + expected.extend( + ( + "binary\n", + "ação2\n".encode(encoding="latin1").decode("utf-8", "replace"), + "ação3\n", + ) + ) - binary_junk = '\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\n\n' + binary_junk = "\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\n\n" if sys.version_info[0] >= 3: binary_junk = "\ufffd\ufffd\ufffd\ufffd\ufffd\n\n" expected.append(binary_junk) - new_expected = [(x, 'stdout') for x in expected] - new_expected.extend([(x, 'stderr') for x in expected]) + new_expected = [(x, "stdout") for x in expected] + new_expected.extend([(x, "stderr") for x in expected]) writer.write_start_redirect() @@ -2263,11 +2308,11 @@ def _ignore_stderr_line(line): msg = writer.wait_for_output() except AssertionError: for msg in msgs: - sys.stderr.write('Found: %s\n' % (msg,)) + sys.stderr.write("Found: %s\n" % (msg,)) for msg in new_expected: - sys.stderr.write('Expected: %s\n' % (msg,)) + sys.stderr.write("Expected: %s\n" % (msg,)) for msg in ignored: - sys.stderr.write('Ignored: %s\n' % (msg,)) + sys.stderr.write("Ignored: %s\n" % (msg,)) raise if msg not in new_expected: ignored.append(msg) @@ -2287,47 +2332,44 @@ def _path_equals(path1, path2): return path1 == path2 -@pytest.mark.parametrize('mixed_case', [True, False] if sys.platform == 'win32' else [False]) +@pytest.mark.parametrize("mixed_case", [True, False] if sys.platform == "win32" else [False]) def test_path_translation(case_setup, mixed_case): - def get_file_in_client(writer): # Instead of using: test_python/_debugger_case_path_translation.py # we'll set the breakpoints at foo/_debugger_case_path_translation.py file_in_client = os.path.dirname(os.path.dirname(writer.TEST_FILE)) - return os.path.join(os.path.dirname(file_in_client), 'foo', '_debugger_case_path_translation.py') + return os.path.join(os.path.dirname(file_in_client), "foo", "_debugger_case_path_translation.py") def get_environ(writer): import json + env = os.environ.copy() - env["PYTHONIOENCODING"] = 'utf-8' + env["PYTHONIOENCODING"] = "utf-8" - assert writer.TEST_FILE.endswith('_debugger_case_path_translation.py') + assert writer.TEST_FILE.endswith("_debugger_case_path_translation.py") file_in_client = get_file_in_client(writer) if mixed_case: - new_file_in_client = ''.join([file_in_client[i].upper() if i % 2 == 0 else file_in_client[i].lower() for i in range(len(file_in_client))]) - assert _path_equals(file_in_client, new_file_in_client) - env["PATHS_FROM_ECLIPSE_TO_PYTHON"] = json.dumps([ - ( - os.path.dirname(file_in_client), - os.path.dirname(writer.TEST_FILE) + new_file_in_client = "".join( + [file_in_client[i].upper() if i % 2 == 0 else file_in_client[i].lower() for i in range(len(file_in_client))] ) - ]) + assert _path_equals(file_in_client, new_file_in_client) + env["PATHS_FROM_ECLIPSE_TO_PYTHON"] = json.dumps([(os.path.dirname(file_in_client), os.path.dirname(writer.TEST_FILE))]) return env - with case_setup.test_file('_debugger_case_path_translation.py', get_environ=get_environ) as writer: + with case_setup.test_file("_debugger_case_path_translation.py", get_environ=get_environ) as writer: from tests_python.debugger_unittest import CMD_LOAD_SOURCE + writer.write_start_redirect() file_in_client = get_file_in_client(writer) - assert 'tests_python' not in file_in_client - writer.write_add_breakpoint( - writer.get_line_index_with_content('break here'), 'call_this', filename=file_in_client) + assert "tests_python" not in file_in_client + writer.write_add_breakpoint(writer.get_line_index_with_content("break here"), "call_this", filename=file_in_client) writer.write_make_initial_run() - xml = writer.wait_for_message(lambda msg:'stop_reason="111"' in msg) - assert xml.thread.frame[0]['file'] == file_in_client - thread_id = xml.thread['id'] + xml = writer.wait_for_message(lambda msg: 'stop_reason="111"' in msg) + assert xml.thread.frame[0]["file"] == file_in_client + thread_id = xml.thread["id"] # Request a file that exists files_to_match = [file_in_client] @@ -2336,30 +2378,28 @@ def get_environ(writer): for f in files_to_match: writer.write_load_source(f) writer.wait_for_message( - lambda msg: - '%s\t' % CMD_LOAD_SOURCE in msg and \ - "def main():" in msg and \ - "print('break here')" in msg and \ - "print('TEST SUCEEDED!')" in msg - , expect_xml=False) + lambda msg: "%s\t" % CMD_LOAD_SOURCE in msg + and "def main():" in msg + and "print('break here')" in msg + and "print('TEST SUCEEDED!')" in msg, + expect_xml=False, + ) # Request a file that does not exist - writer.write_load_source(file_in_client + 'not_existent.py') - writer.wait_for_message( - lambda msg:'901\t' in msg and ('FileNotFoundError' in msg or 'IOError' in msg), - expect_xml=False) + writer.write_load_source(file_in_client + "not_existent.py") + writer.wait_for_message(lambda msg: "901\t" in msg and ("FileNotFoundError" in msg or "IOError" in msg), expect_xml=False) writer.write_run_thread(thread_id) writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='CPython only test.') +@pytest.mark.skipif(not IS_CPYTHON, reason="CPython only test.") def test_linecache_xml(case_setup, tmpdir): from _pydevd_bundle.pydevd_comm_constants import CMD_LOAD_SOURCE_FROM_FRAME_ID - with case_setup.test_file('_debugger_case_linecache.py') as writer: - writer.write_add_breakpoint(writer.get_line_index_with_content('breakpoint')) + with case_setup.test_file("_debugger_case_linecache.py") as writer: + writer.write_add_breakpoint(writer.get_line_index_with_content("breakpoint")) writer.write_make_initial_run() # First hit is for breakpoint reached via a stack frame that doesn't have source. @@ -2368,32 +2408,31 @@ def test_linecache_xml(case_setup, tmpdir): writer.write_get_thread_stack(hit.thread_id) msg = writer.wait_for_get_thread_stack_message() frame_ids = set() - for frame in msg.thread.frame: - if frame['file'] == '': - frame_ids.add(frame['id']) + for frame in msg.thread.frame: + if frame["file"] == "": + frame_ids.add(frame["id"]) assert len(frame_ids) == 2 for frame_id in frame_ids: writer.write_load_source_from_frame_id(frame_id) writer.wait_for_message( - lambda msg: - '%s\t' % CMD_LOAD_SOURCE_FROM_FRAME_ID in msg and ( - "[x for x in range(10)]" in msg and "def somemethod():" in msg - ) - , expect_xml=False) + lambda msg: "%s\t" % CMD_LOAD_SOURCE_FROM_FRAME_ID in msg + and ("[x for x in range(10)]" in msg and "def somemethod():" in msg), + expect_xml=False, + ) writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='CPython only test.') +@pytest.mark.skipif(not IS_CPYTHON, reason="CPython only test.") def test_show_bytecode_xml(case_setup, tmpdir): from _pydevd_bundle.pydevd_comm_constants import CMD_LOAD_SOURCE_FROM_FRAME_ID - with case_setup.test_file('_debugger_case_show_bytecode.py') as writer: - writer.write_add_breakpoint(writer.get_line_index_with_content('breakpoint')) + with case_setup.test_file("_debugger_case_show_bytecode.py") as writer: + writer.write_add_breakpoint(writer.get_line_index_with_content("breakpoint")) writer.write_make_initial_run() # First hit is for breakpoint reached via a stack frame that doesn't have source. @@ -2402,20 +2441,17 @@ def test_show_bytecode_xml(case_setup, tmpdir): writer.write_get_thread_stack(hit.thread_id) msg = writer.wait_for_get_thread_stack_message() frame_ids = set() - for frame in msg.thread.frame: - if frame['file'] == '': - frame_ids.add(frame['id']) + for frame in msg.thread.frame: + if frame["file"] == "": + frame_ids.add(frame["id"]) assert len(frame_ids) == 2 for frame_id in frame_ids: writer.write_load_source_from_frame_id(frame_id) writer.wait_for_message( - lambda msg: - '%s\t' % CMD_LOAD_SOURCE_FROM_FRAME_ID in msg and ( - "MyClass" in msg or "foo()" in msg - ) - , expect_xml=False) + lambda msg: "%s\t" % CMD_LOAD_SOURCE_FROM_FRAME_ID in msg and ("MyClass" in msg or "foo()" in msg), expect_xml=False + ) writer.write_run_thread(hit.thread_id) @@ -2423,23 +2459,23 @@ def test_show_bytecode_xml(case_setup, tmpdir): def test_evaluate_errors(case_setup): - with case_setup.test_file('_debugger_case_local_variables.py') as writer: - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here'), 'Call') + with case_setup.test_file("_debugger_case_local_variables.py") as writer: + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here"), "Call") writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() thread_id = hit.thread_id frame_id = hit.frame_id - writer.write_evaluate_expression('%s\t%s\t%s' % (thread_id, frame_id, 'LOCAL'), 'name_error') + writer.write_evaluate_expression("%s\t%s\t%s" % (thread_id, frame_id, "LOCAL"), "name_error") writer.wait_for_evaluation('' + assert msg.thread.frame["name"] == "" else: assert len(msg.thread.frame) > 1 # Stopped in threading (must have back frames). - assert msg.thread.frame[0]['name'] == 'method' + assert msg.thread.frame[0]["name"] == "method" writer.write_run_thread(hit.thread_id) @@ -2592,30 +2628,25 @@ def _ignore_stderr_line(line): def test_case_dump_threads_to_stderr(case_setup): - from tests_python.debugger_unittest import wait_for_condition def additional_output_checks(writer, stdout, stderr): assert is_stderr_ok(stderr), make_error_msg(stderr) def make_error_msg(stderr): - return 'Did not find thread dump in stderr. stderr:\n%s' % (stderr,) + return "Did not find thread dump in stderr. stderr:\n%s" % (stderr,) def is_stderr_ok(stderr): - return 'Thread Dump' in stderr and 'Thread pydevd.CommandThread (daemon: True, pydevd thread: True)' in stderr + return "Thread Dump" in stderr and "Thread pydevd.CommandThread (daemon: True, pydevd thread: True)" in stderr - with case_setup.test_file( - '_debugger_case_get_thread_stack.py', additional_output_checks=additional_output_checks) as writer: + with case_setup.test_file("_debugger_case_get_thread_stack.py", additional_output_checks=additional_output_checks) as writer: writer.write_add_breakpoint(12, None) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_BREAKPOINT) writer.write_dump_threads() - wait_for_condition( - lambda: is_stderr_ok(writer.get_stderr()), - lambda: make_error_msg(writer.get_stderr()) - ) + wait_for_condition(lambda: is_stderr_ok(writer.get_stderr()), lambda: make_error_msg(writer.get_stderr())) writer.write_run_thread(hit.thread_id) writer.finished_ok = True @@ -2623,13 +2654,13 @@ def is_stderr_ok(stderr): def test_stop_on_start_regular(case_setup): if TODO_PYPY: - raise pytest.skip('Not ok in pypy') + raise pytest.skip("Not ok in pypy") - with case_setup.test_file('_debugger_case_simple_calls.py') as writer: + with case_setup.test_file("_debugger_case_simple_calls.py") as writer: writer.write_stop_on_start() writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_START, file='_debugger_case_simple_calls.py', line=1) + hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_START, file="_debugger_case_simple_calls.py", line=1) writer.write_run_thread(hit.thread_id) @@ -2639,10 +2670,10 @@ def test_stop_on_start_regular(case_setup): def _get_breakpoint_cases(): if sys.version_info >= (3, 7): # Just check breakpoint() - return ('_debugger_case_breakpoint.py',) + return ("_debugger_case_breakpoint.py",) else: # Check breakpoint() and sys.__breakpointhook__ replacement. - return ('_debugger_case_breakpoint.py', '_debugger_case_breakpoint2.py') + return ("_debugger_case_breakpoint.py", "_debugger_case_breakpoint2.py") @pytest.mark.parametrize("filename", _get_breakpoint_cases()) @@ -2651,7 +2682,7 @@ def test_py_37_breakpoint(case_setup, filename): writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(file=filename) - assert hit.line in (3, 6), 'Expected hit in line 3 or 6. Found at: %s' % (hit.line,) + assert hit.line in (3, 6), "Expected hit in line 3 or 6. Found at: %s" % (hit.line,) writer.write_run_thread(hit.thread_id) @@ -2661,15 +2692,15 @@ def test_py_37_breakpoint(case_setup, filename): def _get_generator_cases(): # On py3 we should check both versions. return ( - '_debugger_case_generator_py2.py', - '_debugger_case_generator_py3.py', + "_debugger_case_generator_py2.py", + "_debugger_case_generator_py3.py", ) @pytest.mark.parametrize("filename", _get_generator_cases()) def test_generator_cases(case_setup, filename): with case_setup.test_file(filename) as writer: - writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() @@ -2681,13 +2712,13 @@ def test_generator_cases(case_setup, filename): def test_stop_on_start_m_switch(case_setup_m_switch): if TODO_PYPY: - raise pytest.skip('Not ok in pypy') + raise pytest.skip("Not ok in pypy") with case_setup_m_switch.test_file() as writer: writer.write_stop_on_start() writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_START, file='_debugger_case_m_switch.py', line=1) + hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_START, file="_debugger_case_m_switch.py", line=1) writer.write_run_thread(hit.thread_id) @@ -2695,83 +2726,76 @@ def test_stop_on_start_m_switch(case_setup_m_switch): def test_stop_on_start_entry_point(case_setup_m_switch_entry_point): - with case_setup_m_switch_entry_point.test_file() as writer: writer.write_stop_on_start() writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_START, file='_debugger_case_module_entry_point.py', line=1) + hit = writer.wait_for_breakpoint_hit(REASON_STOP_ON_START, file="_debugger_case_module_entry_point.py", line=1) writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Not working properly on Jython (needs investigation).') +@pytest.mark.skipif(IS_JYTHON, reason="Not working properly on Jython (needs investigation).") def test_debug_zip_files(case_setup, tmpdir): - def get_environ(writer): env = os.environ.copy() - curr_pythonpath = env.get('PYTHONPATH', '') + curr_pythonpath = env.get("PYTHONPATH", "") - curr_pythonpath = str(tmpdir.join('myzip.zip')) + os.pathsep + curr_pythonpath - curr_pythonpath = str(tmpdir.join('myzip2.egg!')) + os.pathsep + curr_pythonpath - env['PYTHONPATH'] = curr_pythonpath + curr_pythonpath = str(tmpdir.join("myzip.zip")) + os.pathsep + curr_pythonpath + curr_pythonpath = str(tmpdir.join("myzip2.egg!")) + os.pathsep + curr_pythonpath + env["PYTHONPATH"] = curr_pythonpath - env["IDE_PROJECT_ROOTS"] = str(tmpdir.join('myzip.zip')) + env["IDE_PROJECT_ROOTS"] = str(tmpdir.join("myzip.zip")) return env import zipfile - zip_file = zipfile.ZipFile( - str(tmpdir.join('myzip.zip')), 'w') - zip_file.writestr('zipped/__init__.py', '') - zip_file.writestr('zipped/zipped_contents.py', 'def call_in_zip():\n return 1') + + zip_file = zipfile.ZipFile(str(tmpdir.join("myzip.zip")), "w") + zip_file.writestr("zipped/__init__.py", "") + zip_file.writestr("zipped/zipped_contents.py", "def call_in_zip():\n return 1") zip_file.close() - zip_file = zipfile.ZipFile( - str(tmpdir.join('myzip2.egg!')), 'w') - zip_file.writestr('zipped2/__init__.py', '') - zip_file.writestr('zipped2/zipped_contents2.py', 'def call_in_zip2():\n return 1') + zip_file = zipfile.ZipFile(str(tmpdir.join("myzip2.egg!")), "w") + zip_file.writestr("zipped2/__init__.py", "") + zip_file.writestr("zipped2/zipped_contents2.py", "def call_in_zip2():\n return 1") zip_file.close() - with case_setup.test_file('_debugger_case_zip_files.py', get_environ=get_environ) as writer: - writer.write_add_breakpoint( - 2, - 'None', - filename=os.path.join(str(tmpdir.join('myzip.zip')), 'zipped', 'zipped_contents.py') - ) + with case_setup.test_file("_debugger_case_zip_files.py", get_environ=get_environ) as writer: + writer.write_add_breakpoint(2, "None", filename=os.path.join(str(tmpdir.join("myzip.zip")), "zipped", "zipped_contents.py")) - writer.write_add_breakpoint( - 2, - 'None', - filename=os.path.join(str(tmpdir.join('myzip2.egg!')), 'zipped2', 'zipped_contents2.py') - ) + writer.write_add_breakpoint(2, "None", filename=os.path.join(str(tmpdir.join("myzip2.egg!")), "zipped2", "zipped_contents2.py")) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() - assert hit.name == 'call_in_zip' + assert hit.name == "call_in_zip" writer.write_run_thread(hit.thread_id) hit = writer.wait_for_breakpoint_hit() - assert hit.name == 'call_in_zip2' + assert hit.name == "call_in_zip2" writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='CPython only test.') -@pytest.mark.parametrize('file_to_check', [ - '_debugger_case_multiprocessing_2.py', - '_debugger_case_multiprocessing.py', - '_debugger_case_python_c.py', - '_debugger_case_multiprocessing_pool.py' -]) +@pytest.mark.skipif(not IS_CPYTHON, reason="CPython only test.") +@pytest.mark.parametrize( + "file_to_check", + [ + "_debugger_case_multiprocessing_2.py", + "_debugger_case_multiprocessing.py", + "_debugger_case_python_c.py", + "_debugger_case_multiprocessing_pool.py", + ], +) def test_multiprocessing_simple(case_setup_multiprocessing, file_to_check): import threading from tests_python.debugger_unittest import AbstractWriterThread + with case_setup_multiprocessing.test_file(file_to_check) as writer: - break1_line = writer.get_line_index_with_content('break 1 here') - break2_line = writer.get_line_index_with_content('break 2 here') + break1_line = writer.get_line_index_with_content("break 1 here") + break2_line = writer.get_line_index_with_content("break 2 here") writer.write_add_breakpoint(break1_line) writer.write_add_breakpoint(break2_line) @@ -2779,15 +2803,14 @@ def test_multiprocessing_simple(case_setup_multiprocessing, file_to_check): server_socket = writer.server_socket class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread - expected_connections = 2 if sys.platform == 'darwin' else 1 + + expected_connections = 2 if sys.platform == "darwin" else 1 for _ in range(expected_connections): server_socket.listen(1) @@ -2795,7 +2818,7 @@ def run(self): new_sock, addr = server_socket.accept() reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() writer2 = SecondaryProcessWriterThread() @@ -2817,20 +2840,21 @@ def run(self): hit2 = writer.wait_for_breakpoint_hit() secondary_process_thread_communication.join(10) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") writer.write_run_thread(hit2.thread_id) writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='CPython only test.') -@pytest.mark.parametrize('count', range(5)) # Call multiple times to exercise timing issues. +@pytest.mark.skipif(not IS_CPYTHON, reason="CPython only test.") +@pytest.mark.parametrize("count", range(5)) # Call multiple times to exercise timing issues. def test_multiprocessing_with_stopped_breakpoints(case_setup_multiprocessing, count, debugger_runner_simple): import threading from tests_python.debugger_unittest import AbstractWriterThread - with case_setup_multiprocessing.test_file('_debugger_case_multiprocessing_stopped_threads.py') as writer: - break_main_line = writer.get_line_index_with_content('break in main here') - break_thread_line = writer.get_line_index_with_content('break in thread here') - break_process_line = writer.get_line_index_with_content('break in process here') + + with case_setup_multiprocessing.test_file("_debugger_case_multiprocessing_stopped_threads.py") as writer: + break_main_line = writer.get_line_index_with_content("break in main here") + break_thread_line = writer.get_line_index_with_content("break in thread here") + break_process_line = writer.get_line_index_with_content("break in process here") writer.write_add_breakpoint(break_main_line) writer.write_add_breakpoint(break_thread_line) @@ -2840,27 +2864,26 @@ def test_multiprocessing_with_stopped_breakpoints(case_setup_multiprocessing, co listening_event = threading.Event() class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread + server_socket.listen(1) self.server_socket = server_socket listening_event.set() - writer.log.append(' *** Multiprocess waiting on server_socket.accept()') + writer.log.append(" *** Multiprocess waiting on server_socket.accept()") new_sock, addr = server_socket.accept() reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() - writer.log.append(' *** Multiprocess started ReaderThread') + writer.log.append(" *** Multiprocess started ReaderThread") writer2 = SecondaryProcessWriterThread() - writer2._WRITE_LOG_PREFIX = ' *** Multiprocess write: ' + writer2._WRITE_LOG_PREFIX = " *** Multiprocess write: " writer2.log = writer.log writer2.reader_thread = reader_thread @@ -2894,7 +2917,7 @@ def run(self): secondary_process_thread_communication.join(10) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") writer.write_run_thread(hit2.thread_id) writer.write_run_thread(main_hit.thread_id) @@ -2905,27 +2928,23 @@ def run(self): writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='CPython only test.') -@pytest.mark.parametrize('target', [ - '_debugger_case_quoting.py', - '_debugger_case_subprocess_zip.py' -]) +@pytest.mark.skipif(not IS_CPYTHON, reason="CPython only test.") +@pytest.mark.parametrize("target", ["_debugger_case_quoting.py", "_debugger_case_subprocess_zip.py"]) def test_subprocess_quoted_args(case_setup_multiprocessing, target): from tests_python.debugger_unittest import AbstractWriterThread + with case_setup_multiprocessing.test_file(target) as writer: - break_subprocess_line = writer.get_line_index_with_content('break here') + break_subprocess_line = writer.get_line_index_with_content("break here") writer.write_add_breakpoint(break_subprocess_line) server_socket = writer.server_socket class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread # Note: on linux on Python 2 because on Python 2 CPython subprocess.call will actually @@ -2942,7 +2961,7 @@ def run(self): new_sock, addr = server_socket.accept() reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() writer2 = SecondaryProcessWriterThread() @@ -2962,32 +2981,33 @@ def run(self): secondary_process_thread_communication.join(10) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") writer.finished_ok = True def _attach_to_writer_pid(writer): import pydevd + assert writer.process is not None def attach(): - attach_pydevd_file = os.path.join(os.path.dirname(pydevd.__file__), 'pydevd_attach_to_process', 'attach_pydevd.py') - subprocess.call([sys.executable, attach_pydevd_file, '--pid', str(writer.process.pid), '--port', str(writer.port)]) + attach_pydevd_file = os.path.join(os.path.dirname(pydevd.__file__), "pydevd_attach_to_process", "attach_pydevd.py") + subprocess.call([sys.executable, attach_pydevd_file, "--pid", str(writer.process.pid), "--port", str(writer.port)]) threading.Thread(target=attach).start() wait_for_condition(lambda: writer.finished_initialization) -@pytest.mark.skipif(not IS_CPYTHON or IS_MAC or not SUPPORT_ATTACH_TO_PID, reason='CPython only test (brittle on Mac).') -@pytest.mark.parametrize('reattach', [True, False]) +@pytest.mark.skipif(not IS_CPYTHON or IS_MAC or not SUPPORT_ATTACH_TO_PID, reason="CPython only test (brittle on Mac).") +@pytest.mark.parametrize("reattach", [True, False]) def test_attach_to_pid_no_threads(case_setup_remote, reattach): - with case_setup_remote.test_file('_debugger_case_attach_to_pid_simple.py', wait_for_port=False) as writer: + with case_setup_remote.test_file("_debugger_case_attach_to_pid_simple.py", wait_for_port=False) as writer: time.sleep(1) # Give it some time to initialize to get to the while loop. _attach_to_writer_pid(writer) - bp_line = writer.get_line_index_with_content('break here') + bp_line = writer.get_line_index_with_content("break here") bp_id = writer.write_add_breakpoint(bp_line) writer.write_make_initial_run() @@ -3004,11 +3024,11 @@ def test_attach_to_pid_no_threads(case_setup_remote, reattach): t = threading.Thread(target=writer.start_socket) t.start() - wait_for_condition(lambda: hasattr(writer, 'port')) + wait_for_condition(lambda: hasattr(writer, "port")) time.sleep(1) writer.process = writer.process _attach_to_writer_pid(writer) - wait_for_condition(lambda: hasattr(writer, 'reader_thread')) + wait_for_condition(lambda: hasattr(writer, "reader_thread")) time.sleep(1) bp_id = writer.write_add_breakpoint(bp_line) @@ -3016,7 +3036,7 @@ def test_attach_to_pid_no_threads(case_setup_remote, reattach): hit = writer.wait_for_breakpoint_hit(line=bp_line) - writer.write_change_variable(hit.thread_id, hit.frame_id, 'wait', 'False') + writer.write_change_variable(hit.thread_id, hit.frame_id, "wait", "False") writer.wait_for_var('' + assert hit.name == "" writer.write_step_return_my_code(hit.thread_id) writer.finished_ok = True def test_smart_step_into_case1(case_setup): - with case_setup.test_file('_debugger_case_smart_step_into.py') as writer: - line = writer.get_line_index_with_content('break here') + with case_setup.test_file("_debugger_case_smart_step_into.py") as writer: + line = writer.get_line_index_with_content("break here") writer.write_add_breakpoint(line) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(line=line) @@ -3760,29 +3778,25 @@ def test_smart_step_into_case1(case_setup): found_info = [x[:-2] for x in found] if IS_PY311_OR_GREATER: assert found_info == [ - ('bar()', 'false', '14', '1'), - ('foo(bar())', 'false', '14', '1'), - ('call_outer(foo(bar()))', 'false', '14', '1'), + ("bar()", "false", "14", "1"), + ("foo(bar())", "false", "14", "1"), + ("call_outer(foo(bar()))", "false", "14", "1"), ] else: - assert found_info == [ - ('bar', 'false', '14', '1'), - ('foo', 'false', '14', '1'), - ('call_outer', 'false', '14', '1') - ] + assert found_info == [("bar", "false", "14", "1"), ("foo", "false", "14", "1"), ("call_outer", "false", "14", "1")] # Note: this is just using the name, not really taking using the context. - writer.write_smart_step_into(hit.thread_id, line, 'foo') + writer.write_smart_step_into(hit.thread_id, line, "foo") hit = writer.wait_for_breakpoint_hit(reason=CMD_SMART_STEP_INTO) - assert hit.line == writer.get_line_index_with_content('on foo mark') + assert hit.line == writer.get_line_index_with_content("on foo mark") writer.write_run_thread(hit.thread_id) writer.finished_ok = True def test_smart_step_into_case2(case_setup): - with case_setup.test_file('_debugger_case_smart_step_into2.py') as writer: - line = writer.get_line_index_with_content('break here') + with case_setup.test_file("_debugger_case_smart_step_into2.py") as writer: + line = writer.get_line_index_with_content("break here") writer.write_add_breakpoint(line) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(line=line) @@ -3792,25 +3806,27 @@ def test_smart_step_into_case2(case_setup): # Note: we have multiple 'foo' calls, so, we have to differentiate to # know in which one we want to stop. OFFSET_POS = 4 - writer.write_smart_step_into(hit.thread_id, 'offset=' + found[2][OFFSET_POS], 'foo') + writer.write_smart_step_into(hit.thread_id, "offset=" + found[2][OFFSET_POS], "foo") hit = writer.wait_for_breakpoint_hit(reason=CMD_SMART_STEP_INTO) - assert hit.line == writer.get_line_index_with_content('on foo mark') + assert hit.line == writer.get_line_index_with_content("on foo mark") writer.write_get_frame(hit.thread_id, hit.frame_id) - writer.wait_for_var([ - ( - '' + assert hit.name == "" writer.write_step_over_my_code(hit.thread_id) hit = writer.wait_for_breakpoint_hit(reason=REASON_STEP_OVER_MY_CODE) - assert hit.name == '' + assert hit.name == "" writer.write_step_over_my_code(hit.thread_id) writer.finished_ok = True @@ -3867,9 +3883,9 @@ def test_step_over_my_code(case_setup): @pytest.fixture( params=[ - 'step_over', - 'step_return', - 'step_in', + "step_over", + "step_return", + "step_in", ] ) def step_method(request): @@ -3877,109 +3893,102 @@ def step_method(request): def test_sysexit_on_filtered_file(case_setup): - def get_environ(writer): env = os.environ.copy() - env.update({'PYDEVD_FILTERS': json.dumps({'**/_debugger_case_sysexit.py': True})}) + env.update({"PYDEVD_FILTERS": json.dumps({"**/_debugger_case_sysexit.py": True})}) return env - with case_setup.test_file('_debugger_case_sysexit.py', get_environ=get_environ, EXPECTED_RETURNCODE=1) as writer: + with case_setup.test_file("_debugger_case_sysexit.py", get_environ=get_environ, EXPECTED_RETURNCODE=1) as writer: writer.write_add_exception_breakpoint_with_policy( - 'SystemExit', + "SystemExit", notify_on_handled_exceptions=1, # Notify multiple times notify_on_unhandled_exceptions=1, - ignore_libraries=0 + ignore_libraries=0, ) writer.write_make_initial_run() writer.finished_ok = True -@pytest.mark.parametrize("scenario", [ - 'handled_once', - 'handled_multiple', - 'unhandled', -]) +@pytest.mark.parametrize( + "scenario", + [ + "handled_once", + "handled_multiple", + "unhandled", + ], +) def test_exception_not_on_filtered_file(case_setup, scenario): - def get_environ(writer): env = os.environ.copy() - env.update({'PYDEVD_FILTERS': json.dumps({'**/other.py': True})}) + env.update({"PYDEVD_FILTERS": json.dumps({"**/other.py": True})}) return env def check_test_suceeded_msg(writer, stdout, stderr): - return 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): - if 'raise RuntimeError' not in stderr: - raise AssertionError('Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s' % ( - stdout, stderr)) + if "raise RuntimeError" not in stderr: + raise AssertionError("Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s" % (stdout, stderr)) with case_setup.test_file( - 'my_code/my_code_exception.py', - get_environ=get_environ, - EXPECTED_RETURNCODE='any', - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks, - ) as writer: - - if scenario == 'handled_once': + "my_code/my_code_exception.py", + get_environ=get_environ, + EXPECTED_RETURNCODE="any", + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + ) as writer: + if scenario == "handled_once": writer.write_add_exception_breakpoint_with_policy( - 'RuntimeError', + "RuntimeError", notify_on_handled_exceptions=2, # Notify only once notify_on_unhandled_exceptions=0, - ignore_libraries=0 + ignore_libraries=0, ) - elif scenario == 'handled_multiple': + elif scenario == "handled_multiple": writer.write_add_exception_breakpoint_with_policy( - 'RuntimeError', + "RuntimeError", notify_on_handled_exceptions=1, # Notify multiple times notify_on_unhandled_exceptions=0, - ignore_libraries=0 + ignore_libraries=0, ) - elif scenario == 'unhandled': + elif scenario == "unhandled": writer.write_add_exception_breakpoint_with_policy( - 'RuntimeError', - notify_on_handled_exceptions=0, - notify_on_unhandled_exceptions=1, - ignore_libraries=0 + "RuntimeError", notify_on_handled_exceptions=0, notify_on_unhandled_exceptions=1, ignore_libraries=0 ) writer.write_make_initial_run() - for _i in range(3 if scenario == 'handled_multiple' else 1): - hit = writer.wait_for_breakpoint_hit( - REASON_UNCAUGHT_EXCEPTION if scenario == 'unhandled' else REASON_CAUGHT_EXCEPTION) + for _i in range(3 if scenario == "handled_multiple" else 1): + hit = writer.wait_for_breakpoint_hit(REASON_UNCAUGHT_EXCEPTION if scenario == "unhandled" else REASON_CAUGHT_EXCEPTION) writer.write_run_thread(hit.thread_id) writer.finished_ok = True def test_exception_on_filtered_file(case_setup): - def get_environ(writer): env = os.environ.copy() - env.update({'PYDEVD_FILTERS': json.dumps({'**/other.py': True})}) + env.update({"PYDEVD_FILTERS": json.dumps({"**/other.py": True})}) return env def check_test_suceeded_msg(writer, stdout, stderr): - return 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): - if 'raise RuntimeError' not in stderr: - raise AssertionError('Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s' % ( - stdout, stderr)) + if "raise RuntimeError" not in stderr: + raise AssertionError("Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s" % (stdout, stderr)) with case_setup.test_file( - 'my_code/my_code_exception_on_other.py', - get_environ=get_environ, - EXPECTED_RETURNCODE='any', - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks, - ) as writer: + "my_code/my_code_exception_on_other.py", + get_environ=get_environ, + EXPECTED_RETURNCODE="any", + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + ) as writer: writer.write_add_exception_breakpoint_with_policy( - 'RuntimeError', + "RuntimeError", notify_on_handled_exceptions=2, # Notify only once notify_on_unhandled_exceptions=1, - ignore_libraries=0 + ignore_libraries=0, ) writer.write_make_initial_run() @@ -3988,60 +3997,62 @@ def additional_output_checks(writer, stdout, stderr): # should be able to see the frames which are part of the project. hit = writer.wait_for_breakpoint_hit( REASON_UNCAUGHT_EXCEPTION, - file='my_code_exception_on_other.py', - line=writer.get_line_index_with_content('other.raise_exception()') + file="my_code_exception_on_other.py", + line=writer.get_line_index_with_content("other.raise_exception()"), ) writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.parametrize("environ", [ - {'PYDEVD_FILTER_LIBRARIES': '1'}, # Global setting for step over - {'PYDEVD_FILTERS': json.dumps({'**/other.py': True})}, # specify as json - {'PYDEVD_FILTERS': '**/other.py'}, # specify ';' separated list -]) -@pytest.mark.skipif(IS_JYTHON, reason='Flaky on Jython.') +@pytest.mark.parametrize( + "environ", + [ + {"PYDEVD_FILTER_LIBRARIES": "1"}, # Global setting for step over + {"PYDEVD_FILTERS": json.dumps({"**/other.py": True})}, # specify as json + {"PYDEVD_FILTERS": "**/other.py"}, # specify ';' separated list + ], +) +@pytest.mark.skipif(IS_JYTHON, reason="Flaky on Jython.") def test_step_over_my_code_global_settings(case_setup, environ, step_method): - def get_environ(writer): env = os.environ.copy() env.update(environ) return env def do_step(): - if step_method == 'step_over': + if step_method == "step_over": writer.write_step_over(hit.thread_id) return REASON_STEP_OVER # Note: goes from step over to step into - elif step_method == 'step_return': + elif step_method == "step_return": writer.write_step_return(hit.thread_id) return REASON_STEP_RETURN else: - assert step_method == 'step_in' + assert step_method == "step_in" writer.write_step_in(hit.thread_id) return REASON_STEP_INTO - with case_setup.test_file('my_code/my_code.py', get_environ=get_environ) as writer: - writer.write_set_project_roots([debugger_unittest._get_debugger_test_file('my_code')]) - writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + with case_setup.test_file("my_code/my_code.py", get_environ=get_environ) as writer: + writer.write_set_project_roots([debugger_unittest._get_debugger_test_file("my_code")]) + writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() writer.write_step_in(hit.thread_id) hit = writer.wait_for_breakpoint_hit(reason=REASON_STEP_INTO) - assert hit.name == 'callback1' + assert hit.name == "callback1" writer.write_step_in(hit.thread_id) hit = writer.wait_for_breakpoint_hit(reason=REASON_STEP_INTO) - assert hit.name == 'callback2' + assert hit.name == "callback2" stop_reason = do_step() hit = writer.wait_for_breakpoint_hit(reason=stop_reason) - assert hit.name == 'callback1' + assert hit.name == "callback1" stop_reason = do_step() hit = writer.wait_for_breakpoint_hit(reason=stop_reason) - assert hit.name == '' + assert hit.name == "" if IS_JYTHON: # Jython may get to exit functions, so, just resume the thread. @@ -4050,13 +4061,13 @@ def do_step(): else: stop_reason = do_step() - if step_method != 'step_return': + if step_method != "step_return": stop_reason = do_step() - if step_method == 'step_over': + if step_method == "step_over": stop_reason = REASON_STEP_OVER hit = writer.wait_for_breakpoint_hit(reason=stop_reason) - assert hit.name == '' + assert hit.name == "" writer.write_step_over(hit.thread_id) @@ -4064,19 +4075,20 @@ def do_step(): def test_step_over_my_code_global_setting_and_explicit_include(case_setup): - def get_environ(writer): env = os.environ.copy() - env.update({ - 'PYDEVD_FILTER_LIBRARIES': '1', # Global setting for in project or not - # specify as json (force include). - 'PYDEVD_FILTERS': json.dumps({'**/other.py': False}) - }) + env.update( + { + "PYDEVD_FILTER_LIBRARIES": "1", # Global setting for in project or not + # specify as json (force include). + "PYDEVD_FILTERS": json.dumps({"**/other.py": False}), + } + ) return env - with case_setup.test_file('my_code/my_code.py', get_environ=get_environ) as writer: - writer.write_set_project_roots([debugger_unittest._get_debugger_test_file('my_code')]) - writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + with case_setup.test_file("my_code/my_code.py", get_environ=get_environ) as writer: + writer.write_set_project_roots([debugger_unittest._get_debugger_test_file("my_code")]) + writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() @@ -4084,29 +4096,28 @@ def get_environ(writer): hit = writer.wait_for_breakpoint_hit(reason=REASON_STEP_INTO) # Although we filtered out non-project files, other.py is explicitly included. - assert hit.name == 'call_me_back1' + assert hit.name == "call_me_back1" writer.write_run_thread(hit.thread_id) writer.finished_ok = True def test_access_token(case_setup): - def update_command_line_args(self, args): - i = args.index('--client') + i = args.index("--client") assert i > 0 - args.insert(i, '--access-token') - args.insert(i + 1, 'bar123') - args.insert(i, '--client-access-token') - args.insert(i + 1, 'foo234') + args.insert(i, "--access-token") + args.insert(i + 1, "bar123") + args.insert(i, "--client-access-token") + args.insert(i + 1, "foo234") return args - with case_setup.test_file('_debugger_case_print.py', update_command_line_args=update_command_line_args) as writer: - writer.write_add_breakpoint(1, 'None') # I.e.: should not work (not authenticated). + with case_setup.test_file("_debugger_case_print.py", update_command_line_args=update_command_line_args) as writer: + writer.write_add_breakpoint(1, "None") # I.e.: should not work (not authenticated). - writer.wait_for_message(lambda msg:'Client not authenticated.' in msg, expect_xml=False) + writer.wait_for_message(lambda msg: "Client not authenticated." in msg, expect_xml=False) - writer.write_authenticate(access_token='bar123', client_access_token='foo234') + writer.write_authenticate(access_token="bar123", client_access_token="foo234") writer.write_version() @@ -4116,11 +4127,11 @@ def update_command_line_args(self, args): def test_namedtuple(case_setup): - ''' + """ Check that we don't step into in the namedtuple constructor. - ''' - with case_setup.test_file('_debugger_case_namedtuple.py') as writer: - line = writer.get_line_index_with_content('break here') + """ + with case_setup.test_file("_debugger_case_namedtuple.py") as writer: + line = writer.get_line_index_with_content("break here") writer.write_add_breakpoint(line) writer.write_make_initial_run() @@ -4131,8 +4142,7 @@ def test_namedtuple(case_setup): for _ in range(2): expected_line += 1 writer.write_step_in(hit.thread_id) - hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_INTO, file='_debugger_case_namedtuple.py', line=expected_line) + hit = writer.wait_for_breakpoint_hit(reason=REASON_STEP_INTO, file="_debugger_case_namedtuple.py", line=expected_line) writer.write_run_thread(hit.thread_id) writer.finished_ok = True @@ -4146,13 +4156,15 @@ def test_matplotlib_activation(case_setup): def get_environ(writer): env = os.environ.copy() - env.update({ - 'IPYTHONENABLE': 'True', - }) + env.update( + { + "IPYTHONENABLE": "True", + } + ) return env - with case_setup.test_file('_debugger_case_matplotlib.py', get_environ=get_environ) as writer: - writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + with case_setup.test_file("_debugger_case_matplotlib.py", get_environ=get_environ) as writer: + writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) writer.write_make_initial_run() for _ in range(3): hit = writer.wait_for_breakpoint_hit() @@ -4162,17 +4174,17 @@ def get_environ(writer): _GENERATOR_FILES = [ - '_debugger_case_generator3.py', - '_debugger_case_generator.py', - '_debugger_case_generator2.py', + "_debugger_case_generator3.py", + "_debugger_case_generator.py", + "_debugger_case_generator2.py", ] -@pytest.mark.parametrize('target_filename', _GENERATOR_FILES) -@pytest.mark.skipif(IS_JYTHON, reason='We do not detect generator returns on Jython.') +@pytest.mark.parametrize("target_filename", _GENERATOR_FILES) +@pytest.mark.skipif(IS_JYTHON, reason="We do not detect generator returns on Jython.") def test_generator_step_over_basic(case_setup, target_filename): with case_setup.test_file(target_filename) as writer: - line = writer.get_line_index_with_content('break here') + line = writer.get_line_index_with_content("break here") writer.write_add_breakpoint(line) writer.write_make_initial_run() @@ -4181,51 +4193,41 @@ def test_generator_step_over_basic(case_setup, target_filename): # Note: not using for so that we know which step failed in the ci if it fails. writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_OVER, - file=target_filename, - line=writer.get_line_index_with_content('step 1') + reason=REASON_STEP_OVER, file=target_filename, line=writer.get_line_index_with_content("step 1") ) writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_OVER, - file=target_filename, - line=writer.get_line_index_with_content('step 2') + reason=REASON_STEP_OVER, file=target_filename, line=writer.get_line_index_with_content("step 2") ) - if IS_PY38_OR_GREATER and target_filename == '_debugger_case_generator2.py': + if IS_PY38_OR_GREATER and target_filename == "_debugger_case_generator2.py": # On py 3.8 it goes back to the return line. writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_OVER, - file=target_filename, - line=writer.get_line_index_with_content('return \\') + reason=REASON_STEP_OVER, file=target_filename, line=writer.get_line_index_with_content("return \\") ) if PYDEVD_USE_SYS_MONITORING: writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_OVER, - file=target_filename, - line=writer.get_line_index_with_content('generator return') + reason=REASON_STEP_OVER, file=target_filename, line=writer.get_line_index_with_content("generator return") ) writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_OVER, - file=target_filename, - line=writer.get_line_index_with_content('step 3') + reason=REASON_STEP_OVER, file=target_filename, line=writer.get_line_index_with_content("step 3") ) writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.parametrize('target_filename', _GENERATOR_FILES) -@pytest.mark.skipif(IS_JYTHON, reason='We do not detect generator returns on Jython.') +@pytest.mark.parametrize("target_filename", _GENERATOR_FILES) +@pytest.mark.skipif(IS_JYTHON, reason="We do not detect generator returns on Jython.") def test_generator_step_return(case_setup, target_filename): with case_setup.test_file(target_filename) as writer: - line = writer.get_line_index_with_content('break here') + line = writer.get_line_index_with_content("break here") writer.write_add_breakpoint(line) writer.write_make_initial_run() @@ -4234,49 +4236,44 @@ def test_generator_step_return(case_setup, target_filename): # Note: not using for so that we know which step failed in the ci if it fails. writer.write_step_return(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_RETURN, - file=target_filename, - line=writer.get_line_index_with_content('generator return') + reason=REASON_STEP_RETURN, file=target_filename, line=writer.get_line_index_with_content("generator return") ) writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_OVER, - file=target_filename, - line=writer.get_line_index_with_content('step 3') + reason=REASON_STEP_OVER, file=target_filename, line=writer.get_line_index_with_content("step 3") ) writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") def test_stepin_not_my_code_coroutine(case_setup): - def get_environ(writer): - environ = {'PYDEVD_FILTERS': '{"**/not_my_coroutine.py": true}'} + environ = {"PYDEVD_FILTERS": '{"**/not_my_coroutine.py": true}'} env = os.environ.copy() env.update(environ) return env - with case_setup.test_file('my_code/my_code_coroutine.py', get_environ=get_environ) as writer: - writer.write_set_project_roots([debugger_unittest._get_debugger_test_file('my_code')]) - writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + with case_setup.test_file("my_code/my_code_coroutine.py", get_environ=get_environ) as writer: + writer.write_set_project_roots([debugger_unittest._get_debugger_test_file("my_code")]) + writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() writer.write_step_in(hit.thread_id) hit = writer.wait_for_breakpoint_hit(reason=REASON_STEP_INTO) - assert hit.name == 'main' + assert hit.name == "main" writer.write_run_thread(hit.thread_id) writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Flaky on Jython') +@pytest.mark.skipif(IS_JYTHON, reason="Flaky on Jython") def test_generator_step_in(case_setup): - with case_setup.test_file('_debugger_case_generator_step_in.py') as writer: - line = writer.get_line_index_with_content('stop 1') + with case_setup.test_file("_debugger_case_generator_step_in.py") as writer: + line = writer.get_line_index_with_content("stop 1") writer.write_add_breakpoint(line) writer.write_make_initial_run() @@ -4286,28 +4283,24 @@ def test_generator_step_in(case_setup): writer.write_step_in(hit.thread_id) kwargs = {} if not IS_JYTHON: - kwargs['line'] = writer.get_line_index_with_content('stop %s' % (i,)) - hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_INTO, - file='_debugger_case_generator_step_in.py', - **kwargs - ) + kwargs["line"] = writer.get_line_index_with_content("stop %s" % (i,)) + hit = writer.wait_for_breakpoint_hit(reason=REASON_STEP_INTO, file="_debugger_case_generator_step_in.py", **kwargs) writer.write_run_thread(hit.thread_id) writer.finished_ok = True @pytest.mark.parametrize( - 'target_filename', + "target_filename", [ - '_debugger_case_asyncio.py', - '_debugger_case_trio.py', - ] + "_debugger_case_asyncio.py", + "_debugger_case_trio.py", + ], ) -@pytest.mark.skipif(not IS_CPYTHON or not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_CPYTHON or not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") def test_asyncio_step_over_basic(case_setup, target_filename): with case_setup.test_file(target_filename) as writer: - line = writer.get_line_index_with_content('break main') + line = writer.get_line_index_with_content("break main") writer.write_add_breakpoint(line) writer.write_make_initial_run() @@ -4315,9 +4308,7 @@ def test_asyncio_step_over_basic(case_setup, target_filename): writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_OVER, - file=target_filename, - line=writer.get_line_index_with_content('step main') + reason=REASON_STEP_OVER, file=target_filename, line=writer.get_line_index_with_content("step main") ) writer.write_run_thread(hit.thread_id) @@ -4325,25 +4316,25 @@ def test_asyncio_step_over_basic(case_setup, target_filename): @pytest.mark.parametrize( - 'target_filename', + "target_filename", [ - '_debugger_case_asyncio.py', - '_debugger_case_trio.py', - ] + "_debugger_case_asyncio.py", + "_debugger_case_trio.py", + ], ) -@pytest.mark.skipif(not IS_CPYTHON or not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_CPYTHON or not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") def test_asyncio_step_over_end_of_function(case_setup, target_filename): with case_setup.test_file(target_filename) as writer: - line = writer.get_line_index_with_content('break count 2') + line = writer.get_line_index_with_content("break count 2") writer.write_add_breakpoint(line) writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit() writer.write_step_over(hit.thread_id) - names = ('sleep', 'wait_task_rescheduled') + names = ("sleep", "wait_task_rescheduled") if PYDEVD_USE_SYS_MONITORING: - names = ('main',) + names = ("main",) hit = writer.wait_for_breakpoint_hit( reason=REASON_STEP_OVER, name=names, @@ -4353,16 +4344,16 @@ def test_asyncio_step_over_end_of_function(case_setup, target_filename): @pytest.mark.parametrize( - 'target_filename', + "target_filename", [ - '_debugger_case_asyncio.py', - '_debugger_case_trio.py', - ] + "_debugger_case_asyncio.py", + "_debugger_case_trio.py", + ], ) -@pytest.mark.skipif(not IS_CPYTHON or not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_CPYTHON or not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") def test_asyncio_step_in(case_setup, target_filename): with case_setup.test_file(target_filename) as writer: - line = writer.get_line_index_with_content('break count 1') + line = writer.get_line_index_with_content("break count 1") writer.write_add_breakpoint(line) writer.write_make_initial_run() @@ -4370,15 +4361,13 @@ def test_asyncio_step_in(case_setup, target_filename): writer.write_step_return(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_RETURN, - file=target_filename, - line=writer.get_line_index_with_content('break main') + reason=REASON_STEP_RETURN, file=target_filename, line=writer.get_line_index_with_content("break main") ) writer.write_step_in(hit.thread_id) - names = ('sleep', 'wait_task_rescheduled') + names = ("sleep", "wait_task_rescheduled") if PYDEVD_USE_SYS_MONITORING: - names = ('main',) + names = ("main",) hit = writer.wait_for_breakpoint_hit( reason=REASON_STEP_INTO, @@ -4390,16 +4379,16 @@ def test_asyncio_step_in(case_setup, target_filename): @pytest.mark.parametrize( - 'target_filename', + "target_filename", [ - '_debugger_case_asyncio.py', - '_debugger_case_trio.py', - ] + "_debugger_case_asyncio.py", + "_debugger_case_trio.py", + ], ) -@pytest.mark.skipif(not IS_CPYTHON or not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_CPYTHON or not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") def test_asyncio_step_return(case_setup, target_filename): with case_setup.test_file(target_filename) as writer: - line = writer.get_line_index_with_content('break count 1') + line = writer.get_line_index_with_content("break count 1") writer.write_add_breakpoint(line) writer.write_make_initial_run() @@ -4407,9 +4396,7 @@ def test_asyncio_step_return(case_setup, target_filename): writer.write_step_return(hit.thread_id) hit = writer.wait_for_breakpoint_hit( - reason=REASON_STEP_RETURN, - file=target_filename, - line=writer.get_line_index_with_content('break main') + reason=REASON_STEP_RETURN, file=target_filename, line=writer.get_line_index_with_content("break main") ) writer.write_run_thread(hit.thread_id) @@ -4417,249 +4404,257 @@ def test_asyncio_step_return(case_setup, target_filename): def test_notify_stdin(case_setup, pyfile): - @pyfile def case_stdin(): import sys - print('Write something:') + + print("Write something:") contents = sys.stdin.readline() - print('Found: ' + contents) + print("Found: " + contents) - print('TEST SUCEEDED') + print("TEST SUCEEDED") def additional_output_checks(writer, stdout, stderr): - assert 'Found: foo' in stdout + assert "Found: foo" in stdout with case_setup.test_file( - case_stdin, - additional_output_checks=additional_output_checks, - ) as writer: - writer.write_make_initial_run() - msg = writer.wait_for_message(CMD_INPUT_REQUESTED, expect_xml=False) - assert msg.split('\t')[-1] == 'True' - process = writer.process - process.stdin.write(b'foo\n') - process.stdin.flush() - msg = writer.wait_for_message(CMD_INPUT_REQUESTED, expect_xml=False) - assert msg.split('\t')[-1] == 'False' + case_stdin, + additional_output_checks=additional_output_checks, + ) as writer: + writer.write_make_initial_run() + msg = writer.wait_for_message(CMD_INPUT_REQUESTED, expect_xml=False) + assert msg.split("\t")[-1] == "True" + process = writer.process + process.stdin.write(b"foo\n") + process.stdin.flush() + msg = writer.wait_for_message(CMD_INPUT_REQUESTED, expect_xml=False) + assert msg.split("\t")[-1] == "False" - writer.finished_ok = True + writer.finished_ok = True def test_frame_eval_mode_corner_case_01(case_setup): - with case_setup.test_file( - 'wrong_bytecode/_debugger_case_wrong_bytecode.py', - ) as writer: - line = writer.get_line_index_with_content('break here') - writer.write_add_breakpoint(line) - writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit(line=writer.get_line_index_with_content('break here'), file='_debugger_case_wrong_bytecode.py') - writer.write_step_over(hit.thread_id) + "wrong_bytecode/_debugger_case_wrong_bytecode.py", + ) as writer: + line = writer.get_line_index_with_content("break here") + writer.write_add_breakpoint(line) + writer.write_make_initial_run() + hit = writer.wait_for_breakpoint_hit(line=writer.get_line_index_with_content("break here"), file="_debugger_case_wrong_bytecode.py") + writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit(line=writer.get_line_index_with_content('step 1'), file='_debugger_case_wrong_bytecode.py', reason=REASON_STEP_OVER) - writer.write_step_over(hit.thread_id) + hit = writer.wait_for_breakpoint_hit( + line=writer.get_line_index_with_content("step 1"), file="_debugger_case_wrong_bytecode.py", reason=REASON_STEP_OVER + ) + writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit(line=writer.get_line_index_with_content('step 2'), file='_debugger_case_wrong_bytecode.py', reason=REASON_STEP_OVER) - writer.write_step_over(hit.thread_id) + hit = writer.wait_for_breakpoint_hit( + line=writer.get_line_index_with_content("step 2"), file="_debugger_case_wrong_bytecode.py", reason=REASON_STEP_OVER + ) + writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit(line=writer.get_line_index_with_content('step 3'), file='_debugger_case_wrong_bytecode.py', reason=REASON_STEP_OVER) - writer.write_step_over(hit.thread_id) + hit = writer.wait_for_breakpoint_hit( + line=writer.get_line_index_with_content("step 3"), file="_debugger_case_wrong_bytecode.py", reason=REASON_STEP_OVER + ) + writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit(line=writer.get_line_index_with_content('step 4'), file='_debugger_case_wrong_bytecode.py', reason=REASON_STEP_OVER) - writer.write_step_over(hit.thread_id) + hit = writer.wait_for_breakpoint_hit( + line=writer.get_line_index_with_content("step 4"), file="_debugger_case_wrong_bytecode.py", reason=REASON_STEP_OVER + ) + writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit(line=writer.get_line_index_with_content('step 5'), file='_debugger_case_wrong_bytecode.py', reason=REASON_STEP_OVER) - writer.write_run_thread(hit.thread_id) + hit = writer.wait_for_breakpoint_hit( + line=writer.get_line_index_with_content("step 5"), file="_debugger_case_wrong_bytecode.py", reason=REASON_STEP_OVER + ) + writer.write_run_thread(hit.thread_id) - writer.finished_ok = True + writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") def test_frame_eval_mode_corner_case_02(case_setup): - with case_setup.test_file( - '_bytecode_super.py', - ) as writer: - line = writer.get_line_index_with_content('break here') - writer.write_add_breakpoint(line) - writer.write_make_initial_run() + "_bytecode_super.py", + ) as writer: + line = writer.get_line_index_with_content("break here") + writer.write_add_breakpoint(line) + writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit(line=line, file='_bytecode_super.py') + hit = writer.wait_for_breakpoint_hit(line=line, file="_bytecode_super.py") - writer.write_run_thread(hit.thread_id) + writer.write_run_thread(hit.thread_id) - writer.finished_ok = True + writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") def test_frame_eval_mode_corner_case_03(case_setup): - with case_setup.test_file( - '_bytecode_constructs.py', - ) as writer: - line = writer.get_line_index_with_content('break while') - writer.write_add_breakpoint(line) - writer.write_make_initial_run() + "_bytecode_constructs.py", + ) as writer: + line = writer.get_line_index_with_content("break while") + writer.write_add_breakpoint(line) + writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit(line=line) + hit = writer.wait_for_breakpoint_hit(line=line) - writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit(line=line + 1, reason=REASON_STEP_OVER) + writer.write_step_over(hit.thread_id) + hit = writer.wait_for_breakpoint_hit(line=line + 1, reason=REASON_STEP_OVER) - writer.write_step_over(hit.thread_id) # i.e.: check that the jump target is still ok. - hit = writer.wait_for_breakpoint_hit(line=line, reason=REASON_STOP_ON_BREAKPOINT) + writer.write_step_over(hit.thread_id) # i.e.: check that the jump target is still ok. + hit = writer.wait_for_breakpoint_hit(line=line, reason=REASON_STOP_ON_BREAKPOINT) + + writer.write_step_over(hit.thread_id) + hit = writer.wait_for_breakpoint_hit(line=line + 1, reason=REASON_STEP_OVER) + if TODO_PY312: writer.write_step_over(hit.thread_id) hit = writer.wait_for_breakpoint_hit(line=line + 1, reason=REASON_STEP_OVER) - if TODO_PY312: - writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit(line=line + 1, reason=REASON_STEP_OVER) - - writer.write_step_over(hit.thread_id) - hit = writer.wait_for_breakpoint_hit(line=line, reason=REASON_STOP_ON_BREAKPOINT) + writer.write_step_over(hit.thread_id) + hit = writer.wait_for_breakpoint_hit(line=line, reason=REASON_STOP_ON_BREAKPOINT) - writer.write_run_thread(hit.thread_id) + writer.write_run_thread(hit.thread_id) - writer.finished_ok = True + writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") def test_frame_eval_mode_corner_case_04(case_setup): - with case_setup.test_file( - '_bytecode_constructs.py', - ) as writer: - line = writer.get_line_index_with_content('break for') - writer.write_add_breakpoint(line) - writer.write_make_initial_run() + "_bytecode_constructs.py", + ) as writer: + line = writer.get_line_index_with_content("break for") + writer.write_add_breakpoint(line) + writer.write_make_initial_run() - for i in range(3): - hit = writer.wait_for_breakpoint_hit(line=line) - writer.write_run_thread(hit.thread_id) + for i in range(3): + hit = writer.wait_for_breakpoint_hit(line=line) + writer.write_run_thread(hit.thread_id) - writer.finished_ok = True + writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") @pytest.mark.parametrize( - 'break_name', + "break_name", [ - 'break except', - 'break with', - 'break try 1', - 'break try 2', - 'break finally 1', - 'break except 2', - 'break finally 2', - 'break finally 3', - 'break finally 4', - 'break in dict', - 'break else', - ] + "break except", + "break with", + "break try 1", + "break try 2", + "break finally 1", + "break except 2", + "break finally 2", + "break finally 3", + "break finally 4", + "break in dict", + "break else", + ], ) def test_frame_eval_mode_corner_case_many(case_setup, break_name): - if break_name == 'break finally 4' and sys.version_info[:2] == (3, 9): + if break_name == "break finally 4" and sys.version_info[:2] == (3, 9): # This case is currently failing in Python 3.9 return # Check the constructs where we stop only once and proceed. with case_setup.test_file( - '_bytecode_constructs.py', - ) as writer: - line = writer.get_line_index_with_content(break_name) - writer.write_add_breakpoint(line) - writer.write_make_initial_run() + "_bytecode_constructs.py", + ) as writer: + line = writer.get_line_index_with_content(break_name) + writer.write_add_breakpoint(line) + writer.write_make_initial_run() - hit = writer.wait_for_breakpoint_hit(line=line) - writer.write_run_thread(hit.thread_id) + hit = writer.wait_for_breakpoint_hit(line=line) + writer.write_run_thread(hit.thread_id) - if break_name == 'break with': - if sys.version_info[:2] >= (3, 10): - # On Python 3.10 it'll actually backtrack for the - # with and thus will execute the line where the - # 'with' statement was started again. - hit = writer.wait_for_breakpoint_hit(line=line) - writer.write_run_thread(hit.thread_id) + if break_name == "break with": + if sys.version_info[:2] >= (3, 10): + # On Python 3.10 it'll actually backtrack for the + # with and thus will execute the line where the + # 'with' statement was started again. + hit = writer.wait_for_breakpoint_hit(line=line) + writer.write_run_thread(hit.thread_id) - writer.finished_ok = True + writer.finished_ok = True check_shadowed = [ ( - u''' + """ if __name__ == '__main__': import queue print(queue) -''', - 'queue.py', - u'shadowed = True\n' +""", + "queue.py", + "shadowed = True\n", ), - ( - u''' + """ if __name__ == '__main__': import queue print(queue) -''', - 'queue.py', - u'raise AssertionError("error on import")' - ) +""", + "queue.py", + 'raise AssertionError("error on import")', + ), ] -@pytest.mark.parametrize('module_name_and_content', check_shadowed) +@pytest.mark.parametrize("module_name_and_content", check_shadowed) def test_debugger_shadowed_imports(case_setup, tmpdir, module_name_and_content): main_content, module_name, content = module_name_and_content - target = tmpdir.join('main.py') + target = tmpdir.join("main.py") shadowed = tmpdir.join(module_name) - target.write_text(main_content, encoding='utf-8') + target.write_text(main_content, encoding="utf-8") - shadowed.write_text(content, encoding='utf-8') + shadowed.write_text(content, encoding="utf-8") def get_environ(writer): env = os.environ.copy() - env.update({ - 'PYTHONPATH': str(tmpdir), - }) + env.update( + { + "PYTHONPATH": str(tmpdir), + } + ) return env try: with case_setup.test_file( - str(target), - get_environ=get_environ, - wait_for_initialization=False, - ) as writer: + str(target), + get_environ=get_environ, + wait_for_initialization=False, + ) as writer: writer.write_make_initial_run() except AssertionError: pass # This is expected as pydevd didn't start-up. - assert ('the module "%s" could not be imported because it is shadowed by:' % (module_name.split('.')[0])) in writer.get_stderr() + assert ('the module "%s" could not be imported because it is shadowed by:' % (module_name.split(".")[0])) in writer.get_stderr() def test_debugger_hide_pydevd_threads(case_setup, pyfile): if TODO_PYPY: - raise pytest.skip('Not ok in pypy') + raise pytest.skip("Not ok in pypy") @pyfile def target_file(): import threading from _pydevd_bundle import pydevd_constants + found_pydevd_thread = False for t in threading.enumerate(): - if getattr(t, 'is_pydev_daemon_thread', False): + if getattr(t, "is_pydev_daemon_thread", False): found_pydevd_thread = True if pydevd_constants.IS_CPYTHON: assert not found_pydevd_thread else: assert found_pydevd_thread - print('TEST SUCEEDED') + print("TEST SUCEEDED") with case_setup.test_file(target_file) as writer: - line = writer.get_line_index_with_content('TEST SUCEEDED') + line = writer.get_line_index_with_content("TEST SUCEEDED") writer.write_add_breakpoint(line) writer.write_make_initial_run() @@ -4669,35 +4664,35 @@ def target_file(): def test_multiple_threads_same_code(case_setup, pyfile): + with case_setup.test_file("_debugger_case_multiple_threads_same_code.py") as writer: + line = writer.get_line_index_with_content("break on main") + bpid_main = writer.write_add_breakpoint(line) + writer.write_make_initial_run() + hit_main = writer.wait_for_breakpoint_hit(line=line) - with case_setup.test_file('_debugger_case_multiple_threads_same_code.py') as writer: - line = writer.get_line_index_with_content('break on main') - bpid_main = writer.write_add_breakpoint(line) - writer.write_make_initial_run() - hit_main = writer.wait_for_breakpoint_hit(line=line) + line = writer.get_line_index_with_content("break on thread") + bpid_thread = writer.write_add_breakpoint(line) - line = writer.get_line_index_with_content('break on thread') - bpid_thread = writer.write_add_breakpoint(line) + hit_thread = writer.wait_for_breakpoint_hit(line=line) + writer.write_run_thread(hit_thread.thread_id) - hit_thread = writer.wait_for_breakpoint_hit(line=line) - writer.write_run_thread(hit_thread.thread_id) + writer.write_step_return(hit_thread.thread_id) + hit_thread = writer.wait_for_breakpoint_hit(REASON_STEP_RETURN) - writer.write_step_return(hit_thread.thread_id) - hit_thread = writer.wait_for_breakpoint_hit(REASON_STEP_RETURN) + # Multiple steps in that thread. + for _i in range(2): + writer.write_step_over(hit_thread.thread_id) + hit_thread = writer.wait_for_breakpoint_hit((REASON_STEP_OVER, REASON_STOP_ON_BREAKPOINT)) - # Multiple steps in that thread. - for _i in range(2): - writer.write_step_over(hit_thread.thread_id) - hit_thread = writer.wait_for_breakpoint_hit((REASON_STEP_OVER, REASON_STOP_ON_BREAKPOINT)) + # Remove breakpoint from thread so that it can finish cleanly. + writer.write_remove_breakpoint(bpid_thread) + writer.write_run_thread(hit_thread.thread_id) - # Remove breakpoint from thread so that it can finish cleanly. - writer.write_remove_breakpoint(bpid_thread) - writer.write_run_thread(hit_thread.thread_id) + # Ok, resume main + writer.write_run_thread(hit_main.thread_id) - # Ok, resume main - writer.write_run_thread(hit_main.thread_id) + writer.finished_ok = True - writer.finished_ok = True # Jython needs some vars to be set locally. # set JAVA_HOME=c:\bin\jdk1.8.0_172 @@ -4706,5 +4701,5 @@ def test_multiple_threads_same_code(case_setup, pyfile): # c:\bin\jython2.7.0\bin\jython.exe -m py.test tests_python -if __name__ == '__main__': - pytest.main(['-k', 'test_case_12']) +if __name__ == "__main__": + pytest.main(["-k", "test_case_12"]) diff --git a/tests_python/test_debugger_json.py b/tests_python/test_debugger_json.py index 851ea9f0c..b49c7474c 100644 --- a/tests_python/test_debugger_json.py +++ b/tests_python/test_debugger_json.py @@ -11,33 +11,60 @@ from _pydev_bundle.pydev_localhost import get_socket_name from _pydevd_bundle._debug_adapter import pydevd_schema, pydevd_base_schema from _pydevd_bundle._debug_adapter.pydevd_base_schema import from_json -from _pydevd_bundle._debug_adapter.pydevd_schema import (ThreadEvent, ModuleEvent, OutputEvent, - ExceptionOptions, Response, StoppedEvent, ContinuedEvent, ProcessEvent, InitializeRequest, - InitializeRequestArguments, TerminateArguments, TerminateRequest, TerminatedEvent, - FunctionBreakpoint, SetFunctionBreakpointsRequest, SetFunctionBreakpointsArguments, - BreakpointEvent, InitializedEvent, ContinueResponse) +from _pydevd_bundle._debug_adapter.pydevd_schema import ( + ThreadEvent, + ModuleEvent, + OutputEvent, + ExceptionOptions, + Response, + StoppedEvent, + ContinuedEvent, + ProcessEvent, + InitializeRequest, + InitializeRequestArguments, + TerminateArguments, + TerminateRequest, + TerminatedEvent, + FunctionBreakpoint, + SetFunctionBreakpointsRequest, + SetFunctionBreakpointsArguments, + BreakpointEvent, + InitializedEvent, + ContinueResponse, +) from _pydevd_bundle.pydevd_comm_constants import file_system_encoding -from _pydevd_bundle.pydevd_constants import (int_types, IS_64BIT_PROCESS, - PY_VERSION_STR, PY_IMPL_VERSION_STR, PY_IMPL_NAME, IS_PY36_OR_GREATER, - IS_PYPY, GENERATED_LEN_ATTR_NAME, IS_WINDOWS, IS_LINUX, IS_MAC, IS_PY38_OR_GREATER, - IS_PY311_OR_GREATER, PYDEVD_USE_SYS_MONITORING, IS_PY312_OR_GREATER, - SUPPORT_ATTACH_TO_PID) +from _pydevd_bundle.pydevd_constants import ( + int_types, + IS_64BIT_PROCESS, + PY_VERSION_STR, + PY_IMPL_VERSION_STR, + PY_IMPL_NAME, + IS_PY36_OR_GREATER, + IS_PYPY, + GENERATED_LEN_ATTR_NAME, + IS_WINDOWS, + IS_LINUX, + IS_MAC, + IS_PY38_OR_GREATER, + IS_PY311_OR_GREATER, + PYDEVD_USE_SYS_MONITORING, + IS_PY312_OR_GREATER, + SUPPORT_ATTACH_TO_PID, +) from tests_python import debugger_unittest -from tests_python.debug_constants import TEST_CHERRYPY, TEST_DJANGO, TEST_FLASK, \ - IS_CPYTHON, TEST_GEVENT, TEST_CYTHON, IS_PY311 -from tests_python.debugger_unittest import (IS_JYTHON, IS_APPVEYOR, overrides, - get_free_port, wait_for_condition) +from tests_python.debug_constants import TEST_CHERRYPY, TEST_DJANGO, TEST_FLASK, IS_CPYTHON, TEST_GEVENT, TEST_CYTHON, IS_PY311 +from tests_python.debugger_unittest import IS_JYTHON, IS_APPVEYOR, overrides, get_free_port, wait_for_condition from _pydevd_bundle.pydevd_utils import DAPGrouper import pydevd_file_utils from _pydevd_bundle import pydevd_constants pytest_plugins = [ - str('tests_python.debugger_fixtures'), + str("tests_python.debugger_fixtures"), ] -_JsonHit = namedtuple('_JsonHit', 'thread_id, frame_id, stack_trace_response') +_JsonHit = namedtuple("_JsonHit", "thread_id, frame_id, stack_trace_response") -pytestmark = pytest.mark.skipif(IS_JYTHON, reason='Single notification is not OK in Jython (investigate).') +pytestmark = pytest.mark.skipif(IS_JYTHON, reason="Single notification is not OK in Jython (investigate).") # Note: in reality must be < int32, but as it's created sequentially this should be # a reasonable number for tests. @@ -45,21 +72,19 @@ class _MessageWithMark(object): - def __init__(self, msg): self.msg = msg self.marked = False class JsonFacade(object): - def __init__(self, writer): self.writer = writer writer.reader_thread.accept_xml_messages = False self._all_json_messages_found = [] self._sent_launch_or_attach = False - def mark_messages(self, expected_class, accept_message=lambda obj:True): + def mark_messages(self, expected_class, accept_message=lambda obj: True): ret = [] for message_with_mark in self._all_json_messages_found: if not message_with_mark.marked: @@ -69,10 +94,9 @@ def mark_messages(self, expected_class, accept_message=lambda obj:True): ret.append(message_with_mark.msg) return ret - def wait_for_json_message(self, expected_class, accept_message=lambda obj:True): - + def wait_for_json_message(self, expected_class, accept_message=lambda obj: True): def accept_json_message(msg): - if msg.startswith('{'): + if msg.startswith("{"): decoded_msg = from_json(msg) self._all_json_messages_found.append(_MessageWithMark(decoded_msg)) @@ -91,7 +115,7 @@ def build_accept_response(self, request, response_class=None): def accept_message(response): if isinstance(request, dict): - if response.request_seq == request['seq']: + if response.request_seq == request["seq"]: return True else: if response.request_seq == request.seq: @@ -107,7 +131,7 @@ def wait_for_response(self, request, response_class=None): def write_request(self, request): seq = self.writer.next_seq() if isinstance(request, dict): - request['seq'] = seq + request["seq"] = seq self.writer.write_with_content_len(json.dumps(request)) else: request.seq = seq @@ -127,56 +151,60 @@ def write_list_threads(self): def wait_for_terminated(self): return self.wait_for_json_message(TerminatedEvent) - def wait_for_thread_stopped(self, reason='breakpoint', line=None, file=None, name=None, preserve_focus_hint=None): - ''' + def wait_for_thread_stopped(self, reason="breakpoint", line=None, file=None, name=None, preserve_focus_hint=None): + """ :param file: utf-8 bytes encoded file or unicode - ''' + """ stopped_event = self.wait_for_json_message(StoppedEvent) assert stopped_event.body.reason == reason if preserve_focus_hint is not None: assert stopped_event.body.preserveFocusHint == preserve_focus_hint json_hit = self.get_stack_as_json_hit(stopped_event.body.threadId) if file is not None: - path = json_hit.stack_trace_response.body.stackFrames[0]['source']['path'] + path = json_hit.stack_trace_response.body.stackFrames[0]["source"]["path"] if not path.endswith(file): # pytest may give a lowercase tempdir, so, also check with # the real case if possible file = pydevd_file_utils.get_path_with_real_case(file) if not path.endswith(file): - raise AssertionError('Expected path: %s to end with: %s' % (path, file)) + raise AssertionError("Expected path: %s to end with: %s" % (path, file)) if name is not None: - assert json_hit.stack_trace_response.body.stackFrames[0]['name'] == name + assert json_hit.stack_trace_response.body.stackFrames[0]["name"] == name if line is not None: - found_line = json_hit.stack_trace_response.body.stackFrames[0]['line'] - path = json_hit.stack_trace_response.body.stackFrames[0]['source']['path'] + found_line = json_hit.stack_trace_response.body.stackFrames[0]["line"] + path = json_hit.stack_trace_response.body.stackFrames[0]["source"]["path"] if not isinstance(line, (tuple, list)): line = [line] - assert found_line in line, 'Expect to break at line: %s. Found: %s (file: %s)' % (line, found_line, path) + assert found_line in line, "Expect to break at line: %s. Found: %s (file: %s)" % (line, found_line, path) return json_hit - def write_set_function_breakpoints( - self, function_names): - function_breakpoints = [FunctionBreakpoint(name,) for name in function_names] + def write_set_function_breakpoints(self, function_names): + function_breakpoints = [ + FunctionBreakpoint( + name, + ) + for name in function_names + ] arguments = SetFunctionBreakpointsArguments(function_breakpoints) request = SetFunctionBreakpointsRequest(arguments) response = self.wait_for_response(self.write_request(request)) assert response.success def write_set_breakpoints( - self, - lines, - filename=None, - line_to_info=None, - success=True, - verified=True, - send_launch_if_needed=True, - expected_lines_in_response=None, - ): - ''' + self, + lines, + filename=None, + line_to_info=None, + success=True, + verified=True, + send_launch_if_needed=True, + expected_lines_in_response=None, + ): + """ Adds a breakpoint. - ''' + """ if send_launch_if_needed and not self._sent_launch_or_attach: self._auto_write_launch() @@ -191,7 +219,7 @@ def write_set_breakpoints( if isinstance(filename, bytes): filename = filename.decode(file_system_encoding) # file is in the filesystem encoding but protocol needs it in utf-8 - filename = filename.encode('utf-8') + filename = filename.encode("utf-8") source = pydevd_schema.Source(path=filename) breakpoints = [] @@ -202,12 +230,13 @@ def write_set_breakpoints( if line in line_to_info: line_info = line_to_info.get(line) - condition = line_info.get('condition') - hit_condition = line_info.get('hit_condition') - log_message = line_info.get('log_message') + condition = line_info.get("condition") + hit_condition = line_info.get("hit_condition") + log_message = line_info.get("log_message") - breakpoints.append(pydevd_schema.SourceBreakpoint( - line, condition=condition, hitCondition=hit_condition, logMessage=log_message).to_dict()) + breakpoints.append( + pydevd_schema.SourceBreakpoint(line, condition=condition, hitCondition=hit_condition, logMessage=log_message).to_dict() + ) arguments = pydevd_schema.SetBreakpointsArguments(source, breakpoints) request = pydevd_schema.SetBreakpointsRequest(arguments) @@ -221,7 +250,7 @@ def write_set_breakpoints( if success: # : :type body: SetBreakpointsResponseBody assert len(body.breakpoints) == len(lines) - lines_in_response = [b['line'] for b in body.breakpoints] + lines_in_response = [b["line"] for b in body.breakpoints] if expected_lines_in_response is None: expected_lines_in_response = lines @@ -229,25 +258,27 @@ def write_set_breakpoints( for b in body.breakpoints: if isinstance(verified, dict): - if b['verified'] != verified[b['id']]: - raise AssertionError('Expected verified breakpoint to be: %s. Found: %s.\nBreakpoint: %s' % ( - verified, verified[b['id']], b)) - - elif b['verified'] != verified: - raise AssertionError('Expected verified breakpoint to be: %s. Found: %s.\nBreakpoint: %s' % ( - verified, b['verified'], b)) + if b["verified"] != verified[b["id"]]: + raise AssertionError( + "Expected verified breakpoint to be: %s. Found: %s.\nBreakpoint: %s" % (verified, verified[b["id"]], b) + ) + + elif b["verified"] != verified: + raise AssertionError( + "Expected verified breakpoint to be: %s. Found: %s.\nBreakpoint: %s" % (verified, b["verified"], b) + ) return response def write_set_exception_breakpoints(self, filters=None, exception_options=None): - ''' + """ :param list(str) filters: A list with 'raised' or 'uncaught' entries. :param list(ExceptionOptions) exception_options: - ''' + """ filters = filters or [] - assert set(filters).issubset(set(('raised', 'uncaught', 'userUnhandled'))) + assert set(filters).issubset(set(("raised", "uncaught", "userUnhandled"))) exception_options = exception_options or [] exception_options = [exception_option.to_dict() for exception_option in exception_options] @@ -264,21 +295,23 @@ def reset_sent_launch_or_attach(self): def _write_launch_or_attach(self, command, **arguments): assert not self._sent_launch_or_attach self._sent_launch_or_attach = True - arguments['noDebug'] = False - request = {'type': 'request', 'command': command, 'arguments': arguments, 'seq':-1} + arguments["noDebug"] = False + request = {"type": "request", "command": command, "arguments": arguments, "seq": -1} self.wait_for_response(self.write_request(request)) def _auto_write_launch(self): - self.write_launch(variablePresentation={ - "all": "hide", - "protected": "inline", - }) + self.write_launch( + variablePresentation={ + "all": "hide", + "protected": "inline", + } + ) def write_launch(self, **arguments): - return self._write_launch_or_attach('launch', **arguments) + return self._write_launch_or_attach("launch", **arguments) def write_attach(self, **arguments): - return self._write_launch_or_attach('attach', **arguments) + return self._write_launch_or_attach("attach", **arguments) def write_disconnect(self, wait_for_response=True, terminate_debugee=False): assert self._sent_launch_or_attach @@ -290,8 +323,7 @@ def write_disconnect(self, wait_for_response=True, terminate_debugee=False): self.wait_for_response(request) def get_stack_as_json_hit(self, thread_id, no_stack_frame=False): - stack_trace_request = self.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=thread_id))) + stack_trace_request = self.write_request(pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=thread_id))) # : :type stack_trace_response: StackTraceResponse # : :type stack_trace_response_body: StackTraceResponseBody @@ -304,18 +336,18 @@ def get_stack_as_json_hit(self, thread_id, no_stack_frame=False): else: assert len(stack_trace_response_body.stackFrames) > 0 for stack_frame in stack_trace_response_body.stackFrames: - assert stack_frame['id'] < MAX_EXPECTED_ID + assert stack_frame["id"] < MAX_EXPECTED_ID stack_frame = next(iter(stack_trace_response_body.stackFrames)) - frame_id = stack_frame['id'] + frame_id = stack_frame["id"] - return _JsonHit( - thread_id=thread_id, frame_id=frame_id, stack_trace_response=stack_trace_response) + return _JsonHit(thread_id=thread_id, frame_id=frame_id, stack_trace_response=stack_trace_response) def get_variables_response(self, variables_reference, fmt=None, success=True): assert variables_reference < MAX_EXPECTED_ID variables_request = self.write_request( - pydevd_schema.VariablesRequest(pydevd_schema.VariablesArguments(variables_reference, format=fmt))) + pydevd_schema.VariablesRequest(pydevd_schema.VariablesArguments(variables_reference, format=fmt)) + ) variables_response = self.wait_for_response(variables_request) assert variables_response.success == success return variables_response @@ -323,18 +355,18 @@ def get_variables_response(self, variables_reference, fmt=None, success=True): def filter_return_variables(self, variables): ret = [] for variable in variables: - if variable['name'].startswith('(return)'): + if variable["name"].startswith("(return)"): ret.append(variable) return ret def pop_variables_reference(self, lst): - ''' + """ Modifies dicts in-place to remove the variablesReference and returns those (in the same order in which they were received). - ''' + """ references = [] for dct in lst: - reference = dct.pop('variablesReference', None) + reference = dct.pop("variablesReference", None) if reference is not None: assert isinstance(reference, int_types) assert reference < MAX_EXPECTED_ID @@ -352,12 +384,11 @@ def _by_type(self, *msgs): ret[msg.__class__] = msg return ret - def write_continue(self, wait_for_response=True, thread_id='*'): - continue_request = self.write_request( - pydevd_schema.ContinueRequest(pydevd_schema.ContinueArguments(threadId=thread_id))) + def write_continue(self, wait_for_response=True, thread_id="*"): + continue_request = self.write_request(pydevd_schema.ContinueRequest(pydevd_schema.ContinueArguments(threadId=thread_id))) if wait_for_response: - if thread_id != '*': + if thread_id != "*": # event, response may be sent in any order msg1 = self.wait_for_json_message((ContinuedEvent, ContinueResponse)) msg2 = self.wait_for_json_message((ContinuedEvent, ContinueResponse)) @@ -375,8 +406,7 @@ def write_continue(self, wait_for_response=True, thread_id='*'): assert continue_response.body.allThreadsContinued def write_pause(self): - pause_request = self.write_request( - pydevd_schema.PauseRequest(pydevd_schema.PauseArguments('*'))) + pause_request = self.write_request(pydevd_schema.PauseRequest(pydevd_schema.PauseArguments("*"))) pause_response = self.wait_for_response(pause_request) assert pause_response.success @@ -385,48 +415,49 @@ def write_step_in(self, thread_id, target_id=None): self.wait_for_response(self.write_request(pydevd_schema.StepInRequest(arguments))) def write_step_next(self, thread_id, wait_for_response=True): - next_request = self.write_request( - pydevd_schema.NextRequest(pydevd_schema.NextArguments(thread_id))) + next_request = self.write_request(pydevd_schema.NextRequest(pydevd_schema.NextArguments(thread_id))) if wait_for_response: self.wait_for_response(next_request) def write_step_out(self, thread_id, wait_for_response=True): - stepout_request = self.write_request( - pydevd_schema.StepOutRequest(pydevd_schema.StepOutArguments(thread_id))) + stepout_request = self.write_request(pydevd_schema.StepOutRequest(pydevd_schema.StepOutArguments(thread_id))) if wait_for_response: self.wait_for_response(stepout_request) def write_set_variable(self, frame_variables_reference, name, value, success=True): set_variable_request = self.write_request( - pydevd_schema.SetVariableRequest(pydevd_schema.SetVariableArguments( - frame_variables_reference, name, value, - ))) + pydevd_schema.SetVariableRequest( + pydevd_schema.SetVariableArguments( + frame_variables_reference, + name, + value, + ) + ) + ) set_variable_response = self.wait_for_response(set_variable_request) if set_variable_response.success != success: raise AssertionError( - 'Expected %s. Found: %s\nResponse: %s\n' % ( - success, set_variable_response.success, set_variable_response.to_json())) + "Expected %s. Found: %s\nResponse: %s\n" % (success, set_variable_response.success, set_variable_response.to_json()) + ) return set_variable_response def get_name_to_scope(self, frame_id): - scopes_request = self.write_request(pydevd_schema.ScopesRequest( - pydevd_schema.ScopesArguments(frame_id))) + scopes_request = self.write_request(pydevd_schema.ScopesRequest(pydevd_schema.ScopesArguments(frame_id))) scopes_response = self.wait_for_response(scopes_request) scopes = scopes_response.body.scopes - name_to_scopes = dict((scope['name'], pydevd_schema.Scope(**scope)) for scope in scopes) + name_to_scopes = dict((scope["name"], pydevd_schema.Scope(**scope)) for scope in scopes) assert len(scopes) == 2 - assert sorted(name_to_scopes.keys()) == ['Globals', 'Locals'] - assert not name_to_scopes['Locals'].expensive - assert name_to_scopes['Locals'].presentationHint == 'locals' + assert sorted(name_to_scopes.keys()) == ["Globals", "Locals"] + assert not name_to_scopes["Locals"].expensive + assert name_to_scopes["Locals"].presentationHint == "locals" return name_to_scopes def get_step_in_targets(self, frame_id): - request = self.write_request(pydevd_schema.StepInTargetsRequest( - pydevd_schema.StepInTargetsArguments(frame_id))) + request = self.write_request(pydevd_schema.StepInTargetsRequest(pydevd_schema.StepInTargetsArguments(frame_id))) # : :type response: StepInTargetsResponse response = self.wait_for_response(request) @@ -439,17 +470,17 @@ def get_step_in_targets(self, frame_id): def get_name_to_var(self, variables_reference): variables_response = self.get_variables_response(variables_reference) - return dict((variable['name'], pydevd_schema.Variable(**variable)) for variable in variables_response.body.variables) + return dict((variable["name"], pydevd_schema.Variable(**variable)) for variable in variables_response.body.variables) def get_locals_name_to_var(self, frame_id): name_to_scope = self.get_name_to_scope(frame_id) - return self.get_name_to_var(name_to_scope['Locals'].variablesReference) + return self.get_name_to_var(name_to_scope["Locals"].variablesReference) def get_globals_name_to_var(self, frame_id): name_to_scope = self.get_name_to_scope(frame_id) - return self.get_name_to_var(name_to_scope['Globals'].variablesReference) + return self.get_name_to_var(name_to_scope["Globals"].variablesReference) def get_local_var(self, frame_id, var_name): ret = self.get_locals_name_to_var(frame_id)[var_name] @@ -465,51 +496,54 @@ def get_var(self, variables_reference, var_name=None, index=None): if var_name is not None: return self.get_name_to_var(variables_reference)[var_name] else: - assert index is not None, 'Either var_name or index must be passed.' + assert index is not None, "Either var_name or index must be passed." variables_response = self.get_variables_response(variables_reference) return pydevd_schema.Variable(**variables_response.body.variables[index]) def write_set_debugger_property( - self, - dont_trace_start_patterns=None, - dont_trace_end_patterns=None, - multi_threads_single_notification=None, - success=True - ): + self, dont_trace_start_patterns=None, dont_trace_end_patterns=None, multi_threads_single_notification=None, success=True + ): dbg_request = self.write_request( - pydevd_schema.SetDebuggerPropertyRequest(pydevd_schema.SetDebuggerPropertyArguments( - dontTraceStartPatterns=dont_trace_start_patterns, - dontTraceEndPatterns=dont_trace_end_patterns, - multiThreadsSingleNotification=multi_threads_single_notification, - ))) + pydevd_schema.SetDebuggerPropertyRequest( + pydevd_schema.SetDebuggerPropertyArguments( + dontTraceStartPatterns=dont_trace_start_patterns, + dontTraceEndPatterns=dont_trace_end_patterns, + multiThreadsSingleNotification=multi_threads_single_notification, + ) + ) + ) response = self.wait_for_response(dbg_request) assert response.success == success return response def write_set_pydevd_source_map(self, source, pydevd_source_maps, success=True): dbg_request = self.write_request( - pydevd_schema.SetPydevdSourceMapRequest(pydevd_schema.SetPydevdSourceMapArguments( - source=source, - pydevdSourceMaps=pydevd_source_maps, - ))) + pydevd_schema.SetPydevdSourceMapRequest( + pydevd_schema.SetPydevdSourceMapArguments( + source=source, + pydevdSourceMaps=pydevd_source_maps, + ) + ) + ) response = self.wait_for_response(dbg_request) assert response.success == success return response def write_initialize(self, success=True): arguments = InitializeRequestArguments( - adapterID='pydevd_test_case', + adapterID="pydevd_test_case", ) response = self.wait_for_response(self.write_request(InitializeRequest(arguments))) assert response.success == success if success: - process_id = response.body.kwargs['pydevd']['processId'] + process_id = response.body.kwargs["pydevd"]["processId"] assert isinstance(process_id, int) return response def write_authorize(self, access_token, success=True): from _pydevd_bundle._debug_adapter.pydevd_schema import PydevdAuthorizeArguments from _pydevd_bundle._debug_adapter.pydevd_schema import PydevdAuthorizeRequest + arguments = PydevdAuthorizeArguments( debugServerAccessToken=access_token, ) @@ -518,15 +552,15 @@ def write_authorize(self, access_token, success=True): return response def evaluate(self, expression, frameId=None, context=None, fmt=None, success=True, wait_for_response=True): - ''' + """ :param wait_for_response: If True returns the response, otherwise returns the request. :returns EvaluateResponse - ''' + """ eval_request = self.write_request( - pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments( - expression, frameId=frameId, context=context, format=fmt))) + pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments(expression, frameId=frameId, context=context, format=fmt)) + ) if wait_for_response: eval_response = self.wait_for_response(eval_request) assert eval_response.success == success @@ -539,38 +573,29 @@ def write_terminate(self): self.write_request(TerminateRequest(arguments=TerminateArguments())) def write_get_source(self, source_reference, success=True): - response = self.wait_for_response(self.write_request( - pydevd_schema.SourceRequest(pydevd_schema.SourceArguments(source_reference)))) + response = self.wait_for_response(self.write_request(pydevd_schema.SourceRequest(pydevd_schema.SourceArguments(source_reference)))) assert response.success == success return response -@pytest.mark.parametrize('scenario', ['basic', 'condition', 'hitCondition']) +@pytest.mark.parametrize("scenario", ["basic", "condition", "hitCondition"]) def test_case_json_logpoints(case_setup_dap, scenario): - with case_setup_dap.test_file('_debugger_case_change_breaks.py') as writer: + with case_setup_dap.test_file("_debugger_case_change_breaks.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - break_2 = writer.get_line_index_with_content('break 2') - break_3 = writer.get_line_index_with_content('break 3') - if scenario == 'basic': - json_facade.write_set_breakpoints( - [break_2, break_3], - line_to_info={ - break_2: {'log_message': 'var {repr("_a")} is {_a}'} - }) - elif scenario == 'condition': + break_2 = writer.get_line_index_with_content("break 2") + break_3 = writer.get_line_index_with_content("break 3") + if scenario == "basic": + json_facade.write_set_breakpoints([break_2, break_3], line_to_info={break_2: {"log_message": 'var {repr("_a")} is {_a}'}}) + elif scenario == "condition": json_facade.write_set_breakpoints( - [break_2, break_3], - line_to_info={ - break_2: {'log_message': 'var {repr("_a")} is {_a}', 'condition': 'True'} - }) - elif scenario == 'hitCondition': + [break_2, break_3], line_to_info={break_2: {"log_message": 'var {repr("_a")} is {_a}', "condition": "True"}} + ) + elif scenario == "hitCondition": json_facade.write_set_breakpoints( - [break_2, break_3], - line_to_info={ - break_2: {'log_message': 'var {repr("_a")} is {_a}', 'hit_condition': '1'} - }) + [break_2, break_3], line_to_info={break_2: {"log_message": 'var {repr("_a")} is {_a}', "hit_condition": "1"}} + ) json_facade.write_make_initial_run() # Should only print, not stop on logpoints. @@ -583,12 +608,12 @@ def accept_message(output_event): msg = output_event.body.output ctx = output_event.body.category - if ctx == 'stdout': + if ctx == "stdout": msg = msg.strip() return msg == "var '_a' is 2" messages = json_facade.mark_messages(OutputEvent, accept_message) - if scenario == 'hitCondition': + if scenario == "hitCondition": assert len(messages) == 1 else: assert len(messages) == 2 @@ -597,27 +622,25 @@ def accept_message(output_event): def test_case_json_logpoint_and_step_failure_ok(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_hit_count.py') as writer: + with case_setup_dap.test_file("_debugger_case_hit_count.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - before_loop_line = writer.get_line_index_with_content('before loop line') - for_line = writer.get_line_index_with_content('for line') - print_line = writer.get_line_index_with_content('print line') + before_loop_line = writer.get_line_index_with_content("before loop line") + for_line = writer.get_line_index_with_content("for line") + print_line = writer.get_line_index_with_content("print line") json_facade.write_set_breakpoints( - [before_loop_line, print_line], - line_to_info={ - print_line: {'log_message': 'var {repr("_a")} is {_a}'} - }) + [before_loop_line, print_line], line_to_info={print_line: {"log_message": 'var {repr("_a")} is {_a}'}} + ) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped(line=before_loop_line) json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', line=for_line) + json_hit = json_facade.wait_for_thread_stopped("step", line=for_line) json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', line=print_line) + json_hit = json_facade.wait_for_thread_stopped("step", line=print_line) json_facade.write_continue() @@ -625,17 +648,15 @@ def test_case_json_logpoint_and_step_failure_ok(case_setup_dap): def test_case_json_logpoint_and_step_still_prints(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_hit_count.py') as writer: + with case_setup_dap.test_file("_debugger_case_hit_count.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - before_loop_line = writer.get_line_index_with_content('before loop line') - print_line = writer.get_line_index_with_content('print line') + before_loop_line = writer.get_line_index_with_content("before loop line") + print_line = writer.get_line_index_with_content("print line") json_facade.write_set_breakpoints( - [before_loop_line, print_line], - line_to_info={ - print_line: {'log_message': 'var {repr("i")} is {i}'} - }) + [before_loop_line, print_line], line_to_info={print_line: {"log_message": 'var {repr("i")} is {i}'}} + ) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped(line=before_loop_line) @@ -643,7 +664,7 @@ def test_case_json_logpoint_and_step_still_prints(case_setup_dap): for _i in range(4): # I.e.: even when stepping we should have the messages. json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step') + json_hit = json_facade.wait_for_thread_stopped("step") json_facade.write_continue() @@ -661,28 +682,24 @@ def accept_message(output_event): def test_case_json_hit_count_and_step(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_hit_count.py') as writer: + with case_setup_dap.test_file("_debugger_case_hit_count.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - for_line = writer.get_line_index_with_content('for line') - print_line = writer.get_line_index_with_content('print line') - json_facade.write_set_breakpoints( - [print_line], - line_to_info={ - print_line: {'hit_condition': '5'} - }) + for_line = writer.get_line_index_with_content("for line") + print_line = writer.get_line_index_with_content("print line") + json_facade.write_set_breakpoints([print_line], line_to_info={print_line: {"hit_condition": "5"}}) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped(line=print_line) - i_local_var = json_facade.get_local_var(json_hit.frame_id, 'i') # : :type i_local_var: pydevd_schema.Variable - assert i_local_var.value == '4' + i_local_var = json_facade.get_local_var(json_hit.frame_id, "i") # : :type i_local_var: pydevd_schema.Variable + assert i_local_var.value == "4" json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', line=for_line) + json_hit = json_facade.wait_for_thread_stopped("step", line=for_line) json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', line=print_line) + json_hit = json_facade.wait_for_thread_stopped("step", line=print_line) json_facade.write_continue() @@ -690,21 +707,17 @@ def test_case_json_hit_count_and_step(case_setup_dap): def test_case_json_hit_condition_error(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_hit_count.py') as writer: + with case_setup_dap.test_file("_debugger_case_hit_count.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - bp = writer.get_line_index_with_content('before loop line') - json_facade.write_set_breakpoints( - [bp], - line_to_info={ - bp: {'condition': 'range.range.range'} - }) + bp = writer.get_line_index_with_content("before loop line") + json_facade.write_set_breakpoints([bp], line_to_info={bp: {"condition": "range.range.range"}}) json_facade.write_make_initial_run() def accept_message(msg): - if msg.body.category == 'important': - if 'Error while evaluating expression in conditional breakpoint' in msg.body.output: + if msg.body.category == "important": + if "Error while evaluating expression in conditional breakpoint" in msg.body.output: return True return False @@ -718,7 +731,7 @@ def accept_message(msg): def test_case_process_event(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_change_breaks.py') as writer: + with case_setup_dap.test_file("_debugger_case_change_breaks.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() @@ -728,10 +741,10 @@ def test_case_process_event(case_setup_dap): def test_case_json_change_breaks(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_change_breaks.py') as writer: + with case_setup_dap.test_file("_debugger_case_change_breaks.py") as writer: json_facade = JsonFacade(writer) - break1_line = writer.get_line_index_with_content('break 1') + break1_line = writer.get_line_index_with_content("break 1") # Note: we can only write breakpoints after the launch is received. json_facade.write_set_breakpoints(break1_line, success=False, send_launch_if_needed=False) @@ -747,10 +760,10 @@ def test_case_json_change_breaks(case_setup_dap): def test_case_json_suspend_notification(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_change_breaks.py') as writer: + with case_setup_dap.test_file("_debugger_case_change_breaks.py") as writer: json_facade = JsonFacade(writer) json_facade.writer.write_multi_threads_single_notification(False) - break1_line = writer.get_line_index_with_content('break 1') + break1_line = writer.get_line_index_with_content("break 1") json_facade.write_launch() json_facade.write_set_breakpoints(break1_line) json_facade.write_make_initial_run() @@ -765,20 +778,19 @@ def test_case_json_suspend_notification(case_setup_dap): def test_case_handled_exception_no_break_on_generator(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_ignore_exceptions.py') as writer: + with case_setup_dap.test_file("_debugger_case_ignore_exceptions.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_exception_breakpoints(['raised']) + json_facade.write_set_exception_breakpoints(["raised"]) json_facade.write_make_initial_run() writer.finished_ok = True def test_case_throw_exc_reason(case_setup_dap): - def check_test_suceeded_msg(self, stdout, stderr): - return 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): assert "raise RuntimeError('TEST SUCEEDED')" in stderr @@ -786,54 +798,57 @@ def additional_output_checks(writer, stdout, stderr): assert "raise Exception('another while handling')" in stderr with case_setup_dap.test_file( - '_debugger_case_raise_with_cause.py', - EXPECTED_RETURNCODE=1, - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks - ) as writer: + "_debugger_case_raise_with_cause.py", + EXPECTED_RETURNCODE=1, + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_exception_breakpoints(['uncaught']) + json_facade.write_set_exception_breakpoints(["uncaught"]) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped( - reason='exception', line=writer.get_line_index_with_content('raise RuntimeError from e')) + reason="exception", line=writer.get_line_index_with_content("raise RuntimeError from e") + ) exc_info_request = json_facade.write_request( - pydevd_schema.ExceptionInfoRequest(pydevd_schema.ExceptionInfoArguments(json_hit.thread_id))) + pydevd_schema.ExceptionInfoRequest(pydevd_schema.ExceptionInfoArguments(json_hit.thread_id)) + ) exc_info_response = json_facade.wait_for_response(exc_info_request) stack_frames = json_hit.stack_trace_response.body.stackFrames # Note that the additional context doesn't really appear in the stack # frames, only in the details. - assert [x['name'] for x in stack_frames] == [ - 'foobar', - '', - '[Chained Exc: another while handling] foobar', - '[Chained Exc: another while handling] handle', - '[Chained Exc: TEST SUCEEDED] foobar', - '[Chained Exc: TEST SUCEEDED] method', - '[Chained Exc: TEST SUCEEDED] method2', + assert [x["name"] for x in stack_frames] == [ + "foobar", + "", + "[Chained Exc: another while handling] foobar", + "[Chained Exc: another while handling] handle", + "[Chained Exc: TEST SUCEEDED] foobar", + "[Chained Exc: TEST SUCEEDED] method", + "[Chained Exc: TEST SUCEEDED] method2", ] body = exc_info_response.body - assert body.exceptionId.endswith('RuntimeError') - assert body.description == 'another while handling' - assert normcase(body.details.kwargs['source']) == normcase(writer.TEST_FILE) + assert body.exceptionId.endswith("RuntimeError") + assert body.description == "another while handling" + assert normcase(body.details.kwargs["source"]) == normcase(writer.TEST_FILE) # Check that we have all the lines (including the cause/context) in the stack trace. import re - lines_and_names = re.findall(r',\sline\s(\d+),\sin\s(\[Chained Exception\]\s)?([\w|<|>]+)', body.details.stackTrace) + + lines_and_names = re.findall(r",\sline\s(\d+),\sin\s(\[Chained Exception\]\s)?([\w|<|>]+)", body.details.stackTrace) assert lines_and_names == [ - ('16', '', 'foobar'), - ('6', '', 'method'), - ('2', '', 'method2'), - ('18', '', 'foobar'), - ('10', '', 'handle'), - ('20', '', 'foobar'), - ('23', '', ''), - ], 'Did not find the expected names in:\n%s' % (body.details.stackTrace,) + ("16", "", "foobar"), + ("6", "", "method"), + ("2", "", "method2"), + ("18", "", "foobar"), + ("10", "", "handle"), + ("20", "", "foobar"), + ("23", "", ""), + ], "Did not find the expected names in:\n%s" % (body.details.stackTrace,) json_facade.write_continue() @@ -841,9 +856,8 @@ def additional_output_checks(writer, stdout, stderr): def test_case_throw_exc_reason_shown(case_setup_dap): - def check_test_suceeded_msg(self, stdout, stderr): - return 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): assert "raise Exception('TEST SUCEEDED') from e" in stderr @@ -851,40 +865,42 @@ def additional_output_checks(writer, stdout, stderr): assert "KeyError: 'foo'" in stderr with case_setup_dap.test_file( - '_debugger_case_raise_with_cause_msg.py', - EXPECTED_RETURNCODE=1, - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks - ) as writer: + "_debugger_case_raise_with_cause_msg.py", + EXPECTED_RETURNCODE=1, + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_exception_breakpoints(['uncaught']) + json_facade.write_set_exception_breakpoints(["uncaught"]) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped( - reason='exception', line=writer.get_line_index_with_content("raise Exception('TEST SUCEEDED') from e")) + reason="exception", line=writer.get_line_index_with_content("raise Exception('TEST SUCEEDED') from e") + ) exc_info_request = json_facade.write_request( - pydevd_schema.ExceptionInfoRequest(pydevd_schema.ExceptionInfoArguments(json_hit.thread_id))) + pydevd_schema.ExceptionInfoRequest(pydevd_schema.ExceptionInfoArguments(json_hit.thread_id)) + ) exc_info_response = json_facade.wait_for_response(exc_info_request) stack_frames = json_hit.stack_trace_response.body.stackFrames # Note that the additional context doesn't really appear in the stack # frames, only in the details. - assert [x['name'] for x in stack_frames] == [ - 'method', - '', + assert [x["name"] for x in stack_frames] == [ + "method", + "", "[Chained Exc: 'foo'] method", "[Chained Exc: 'foo'] method2", ] body = exc_info_response.body - assert body.exceptionId == 'Exception' - assert body.description == 'TEST SUCEEDED' + assert body.exceptionId == "Exception" + assert body.description == "TEST SUCEEDED" if IS_PY311_OR_GREATER: - assert '^^^^' in body.details.stackTrace - assert normcase(body.details.kwargs['source']) == normcase(writer.TEST_FILE) + assert "^^^^" in body.details.stackTrace + assert normcase(body.details.kwargs["source"]) == normcase(writer.TEST_FILE) # Check that we have the exception cause in the stack trace. assert "KeyError: 'foo'" in body.details.stackTrace @@ -895,19 +911,17 @@ def additional_output_checks(writer, stdout, stderr): def test_case_handled_exception_breaks(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_exceptions.py') as writer: + with case_setup_dap.test_file("_debugger_case_exceptions.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_exception_breakpoints(['raised']) + json_facade.write_set_exception_breakpoints(["raised"]) json_facade.write_make_initial_run() - json_facade.wait_for_thread_stopped( - reason='exception', line=writer.get_line_index_with_content('raise indexerror line')) + json_facade.wait_for_thread_stopped(reason="exception", line=writer.get_line_index_with_content("raise indexerror line")) json_facade.write_continue() - json_facade.wait_for_thread_stopped( - reason='exception', line=writer.get_line_index_with_content('reraise on method2')) + json_facade.wait_for_thread_stopped(reason="exception", line=writer.get_line_index_with_content("reraise on method2")) # Clear so that the last one is not hit. json_facade.write_set_exception_breakpoints([]) @@ -920,109 +934,99 @@ def _check_current_line(json_hit, current_line): if not isinstance(current_line, (list, tuple)): current_line = (current_line,) for frame in json_hit.stack_trace_response.body.stackFrames: - if '(Current frame)' in frame['name']: - if frame['line'] not in current_line: + if "(Current frame)" in frame["name"]: + if frame["line"] not in current_line: rep = json.dumps(json_hit.stack_trace_response.body.stackFrames, indent=4) - raise AssertionError('Expected: %s to be one of: %s\nFrames:\n%s.' % ( - frame['line'], - current_line, - rep - )) + raise AssertionError("Expected: %s to be one of: %s\nFrames:\n%s." % (frame["line"], current_line, rep)) break else: rep = json.dumps(json_hit.stack_trace_response.body.stackFrames, indent=4) - raise AssertionError('Could not find (Current frame) in any frame name in: %s.' % ( - rep)) + raise AssertionError("Could not find (Current frame) in any frame name in: %s." % (rep)) -@pytest.mark.parametrize('stop', [False, True]) +@pytest.mark.parametrize("stop", [False, True]) def test_case_user_unhandled_exception(case_setup_dap, stop): - def get_environ(self): env = os.environ.copy() # Note that we put the working directory in the project roots to check that when expanded # the relative file that doesn't exist is still considered a library file. - env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath('.') + env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath(".") return env if stop: - target = '_debugger_case_user_unhandled.py' + target = "_debugger_case_user_unhandled.py" else: - target = '_debugger_case_user_unhandled2.py' + target = "_debugger_case_user_unhandled2.py" with case_setup_dap.test_file(target, get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_exception_breakpoints(['userUnhandled']) + json_facade.write_set_exception_breakpoints(["userUnhandled"]) json_facade.write_make_initial_run() if stop: json_hit = json_facade.wait_for_thread_stopped( - reason='exception', line=writer.get_line_index_with_content('raise here'), file=target) - _check_current_line(json_hit, writer.get_line_index_with_content('stop here')) + reason="exception", line=writer.get_line_index_with_content("raise here"), file=target + ) + _check_current_line(json_hit, writer.get_line_index_with_content("stop here")) json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Only CPython 3.6 onwards') -@pytest.mark.parametrize('stop', [False, True]) +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Only CPython 3.6 onwards") +@pytest.mark.parametrize("stop", [False, True]) def test_case_user_unhandled_exception_coroutine(case_setup_dap, stop): if stop: - target = 'my_code/my_code_coroutine_user_unhandled.py' + target = "my_code/my_code_coroutine_user_unhandled.py" else: - target = 'my_code/my_code_coroutine_user_unhandled_no_stop.py' + target = "my_code/my_code_coroutine_user_unhandled_no_stop.py" basename = os.path.basename(target) def additional_output_checks(writer, stdout, stderr): if stop: - assert 'raise RuntimeError' in stderr + assert "raise RuntimeError" in stderr else: - assert 'raise RuntimeError' not in stderr + assert "raise RuntimeError" not in stderr with case_setup_dap.test_file( - target, - EXPECTED_RETURNCODE=1 if stop else 0, - additional_output_checks=additional_output_checks - ) as writer: + target, EXPECTED_RETURNCODE=1 if stop else 0, additional_output_checks=additional_output_checks + ) as writer: json_facade = JsonFacade(writer) - not_my_code_dir = debugger_unittest._get_debugger_test_file('not_my_code') + not_my_code_dir = debugger_unittest._get_debugger_test_file("not_my_code") json_facade.write_launch( rules=[ - {'path': not_my_code_dir, 'include':False}, + {"path": not_my_code_dir, "include": False}, ] ) - json_facade.write_set_exception_breakpoints(['userUnhandled']) + json_facade.write_set_exception_breakpoints(["userUnhandled"]) json_facade.write_make_initial_run() if stop: - stop_line = writer.get_line_index_with_content('stop here 1') + stop_line = writer.get_line_index_with_content("stop here 1") current_line = stop_line - json_hit = json_facade.wait_for_thread_stopped( - reason='exception', line=stop_line, file=basename) + json_hit = json_facade.wait_for_thread_stopped(reason="exception", line=stop_line, file=basename) _check_current_line(json_hit, current_line) json_facade.write_continue() - current_line = writer.get_line_index_with_content('stop here 2') - json_hit = json_facade.wait_for_thread_stopped( - reason='exception', line=stop_line, file=basename) + current_line = writer.get_line_index_with_content("stop here 2") + json_hit = json_facade.wait_for_thread_stopped(reason="exception", line=stop_line, file=basename) _check_current_line(json_hit, current_line) json_facade.write_continue() current_line = ( - writer.get_line_index_with_content('stop here 3a'), - writer.get_line_index_with_content('stop here 3b'), + writer.get_line_index_with_content("stop here 3a"), + writer.get_line_index_with_content("stop here 3b"), ) - json_hit = json_facade.wait_for_thread_stopped( - reason='exception', line=stop_line, file=basename) + json_hit = json_facade.wait_for_thread_stopped(reason="exception", line=stop_line, file=basename) _check_current_line(json_hit, current_line) json_facade.write_continue() @@ -1031,30 +1035,28 @@ def additional_output_checks(writer, stdout, stderr): def test_case_user_unhandled_exception_dont_stop(case_setup_dap): - with case_setup_dap.test_file( - 'my_code/my_code_exception_user_unhandled.py',) as writer: + "my_code/my_code_exception_user_unhandled.py", + ) as writer: json_facade = JsonFacade(writer) - not_my_code_dir = debugger_unittest._get_debugger_test_file('not_my_code') + not_my_code_dir = debugger_unittest._get_debugger_test_file("not_my_code") json_facade.write_launch( debugStdLib=True, rules=[ - {'path': not_my_code_dir, 'include':False}, - ] + {"path": not_my_code_dir, "include": False}, + ], ) - json_facade.write_set_exception_breakpoints(['userUnhandled']) + json_facade.write_set_exception_breakpoints(["userUnhandled"]) json_facade.write_make_initial_run() writer.finished_ok = True def test_case_user_unhandled_exception_stop_on_yield(case_setup_dap, pyfile): - @pyfile def case_error_on_yield(): - def on_yield(): yield raise AssertionError() # raise here @@ -1063,7 +1065,7 @@ def on_yield(): for _ in on_yield(): # stop here pass except: - print('TEST SUCEEDED!') + print("TEST SUCEEDED!") raise def get_environ(self): @@ -1071,120 +1073,122 @@ def get_environ(self): # Note that we put the working directory in the project roots to check that when expanded # the relative file that doesn't exist is still considered a library file. - env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath('.') + env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath(".") return env def additional_output_checks(writer, stdout, stderr): - assert 'raise AssertionError' in stderr + assert "raise AssertionError" in stderr with case_setup_dap.test_file( - case_error_on_yield, - get_environ=get_environ, - EXPECTED_RETURNCODE=1, - additional_output_checks=additional_output_checks) as writer: + case_error_on_yield, get_environ=get_environ, EXPECTED_RETURNCODE=1, additional_output_checks=additional_output_checks + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_exception_breakpoints(['userUnhandled']) + json_facade.write_set_exception_breakpoints(["userUnhandled"]) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped( - reason='exception', line=writer.get_line_index_with_content('raise here'), file=case_error_on_yield) - _check_current_line(json_hit, writer.get_line_index_with_content('stop here')) + reason="exception", line=writer.get_line_index_with_content("raise here"), file=case_error_on_yield + ) + _check_current_line(json_hit, writer.get_line_index_with_content("stop here")) json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('target', [ - 'absolute', - 'relative', - ]) -@pytest.mark.parametrize('just_my_code', [ - True, - False, - ]) +@pytest.mark.parametrize( + "target", + [ + "absolute", + "relative", + ], +) +@pytest.mark.parametrize( + "just_my_code", + [ + True, + False, + ], +) def test_case_unhandled_exception_just_my_code(case_setup_dap, target, just_my_code): - def check_test_suceeded_msg(writer, stdout, stderr): # Don't call super (we have an unhandled exception in the stack trace). - return 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): - if 'call_exception_in_exec()' not in stderr: - raise AssertionError('Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s' % ( - stdout, stderr)) + if "call_exception_in_exec()" not in stderr: + raise AssertionError("Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s" % (stdout, stderr)) def get_environ(self): env = os.environ.copy() # Note that we put the working directory in the project roots to check that when expanded # the relative file that doesn't exist is still considered a library file. - env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath('.') + env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath(".") return env def update_command_line_args(writer, args): ret = debugger_unittest.AbstractWriterThread.update_command_line_args(writer, args) - if target == 'absolute': - if sys.platform == 'win32': - ret.append('c:/temp/folder/my_filename.pyx') + if target == "absolute": + if sys.platform == "win32": + ret.append("c:/temp/folder/my_filename.pyx") else: - ret.append('/temp/folder/my_filename.pyx') + ret.append("/temp/folder/my_filename.pyx") - elif target == 'relative': - ret.append('folder/my_filename.pyx') + elif target == "relative": + ret.append("folder/my_filename.pyx") else: - raise AssertionError('Unhandled case: %s' % (target,)) + raise AssertionError("Unhandled case: %s" % (target,)) return args - target_filename = '_debugger_case_unhandled_just_my_code.py' + target_filename = "_debugger_case_unhandled_just_my_code.py" with case_setup_dap.test_file( - target_filename, - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks, - update_command_line_args=update_command_line_args, - get_environ=get_environ, - EXPECTED_RETURNCODE=1, - ) as writer: + target_filename, + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + update_command_line_args=update_command_line_args, + get_environ=get_environ, + EXPECTED_RETURNCODE=1, + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=just_my_code) - json_facade.write_set_exception_breakpoints(['uncaught']) + json_facade.write_set_exception_breakpoints(["uncaught"]) json_facade.write_make_initial_run() - json_hit = json_facade.wait_for_thread_stopped(reason='exception') + json_hit = json_facade.wait_for_thread_stopped(reason="exception") frames = json_hit.stack_trace_response.body.stackFrames if just_my_code: assert len(frames) == 1 - assert frames[0]['source']['path'].endswith(target_filename) + assert frames[0]["source"]["path"].endswith(target_filename) else: assert len(frames) > 1 - assert frames[0]['source']['path'].endswith('my_filename.pyx') + assert frames[0]["source"]["path"].endswith("my_filename.pyx") json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Python 3.6 onwards required for test.') +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Python 3.6 onwards required for test.") def test_case_stop_async_iteration_exception(case_setup_dap): - def get_environ(self): env = os.environ.copy() - env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath('.') + env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath(".") return env with case_setup_dap.test_file( - '_debugger_case_stop_async_iteration.py', - get_environ=get_environ, - ) as writer: + "_debugger_case_stop_async_iteration.py", + get_environ=get_environ, + ) as writer: json_facade = JsonFacade(writer) # We don't want to hit common library exceptions here. json_facade.write_launch(justMyCode=True) - json_facade.write_set_exception_breakpoints(['raised']) + json_facade.write_set_exception_breakpoints(["raised"]) json_facade.write_make_initial_run() # Just making sure that no exception breakpoints are hit. @@ -1192,184 +1196,184 @@ def get_environ(self): writer.finished_ok = True -@pytest.mark.parametrize('target_file', [ - '_debugger_case_unhandled_exceptions.py', - '_debugger_case_unhandled_exceptions_custom.py', - ]) +@pytest.mark.parametrize( + "target_file", + [ + "_debugger_case_unhandled_exceptions.py", + "_debugger_case_unhandled_exceptions_custom.py", + ], +) def test_case_unhandled_exception(case_setup_dap, target_file): - def check_test_suceeded_msg(writer, stdout, stderr): # Don't call super (we have an unhandled exception in the stack trace). - return 'TEST SUCEEDED' in ''.join(stdout) and 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stdout) and "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): - if 'raise MyError' not in stderr and 'raise Exception' not in stderr: - raise AssertionError('Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s' % ( - stdout, stderr)) + if "raise MyError" not in stderr and "raise Exception" not in stderr: + raise AssertionError("Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s" % (stdout, stderr)) with case_setup_dap.test_file( - target_file, - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks, - EXPECTED_RETURNCODE=1, - ) as writer: + target_file, + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + EXPECTED_RETURNCODE=1, + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_exception_breakpoints(['uncaught']) + json_facade.write_set_exception_breakpoints(["uncaught"]) json_facade.write_make_initial_run() - line_in_thread1 = writer.get_line_index_with_content('in thread 1') - line_in_thread2 = writer.get_line_index_with_content('in thread 2') - line_in_main = writer.get_line_index_with_content('in main') - json_facade.wait_for_thread_stopped( - reason='exception', line=(line_in_thread1, line_in_thread2), file=target_file) + line_in_thread1 = writer.get_line_index_with_content("in thread 1") + line_in_thread2 = writer.get_line_index_with_content("in thread 2") + line_in_main = writer.get_line_index_with_content("in main") + json_facade.wait_for_thread_stopped(reason="exception", line=(line_in_thread1, line_in_thread2), file=target_file) json_facade.write_continue() - json_facade.wait_for_thread_stopped( - reason='exception', line=(line_in_thread1, line_in_thread2), file=target_file) + json_facade.wait_for_thread_stopped(reason="exception", line=(line_in_thread1, line_in_thread2), file=target_file) json_facade.write_continue() - json_facade.wait_for_thread_stopped( - reason='exception', line=line_in_main, file=target_file) + json_facade.wait_for_thread_stopped(reason="exception", line=line_in_main, file=target_file) json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('target_file', [ - '_debugger_case_unhandled_exceptions_generator.py', - '_debugger_case_unhandled_exceptions_listcomp.py', - ]) +@pytest.mark.parametrize( + "target_file", + [ + "_debugger_case_unhandled_exceptions_generator.py", + "_debugger_case_unhandled_exceptions_listcomp.py", + ], +) def test_case_unhandled_exception_generator(case_setup_dap, target_file): - def check_test_suceeded_msg(writer, stdout, stderr): # Don't call super (we have an unhandled exception in the stack trace). - return 'TEST SUCEEDED' in ''.join(stdout) and 'TEST SUCEEDED' in ''.join(stderr) + return "TEST SUCEEDED" in "".join(stdout) and "TEST SUCEEDED" in "".join(stderr) def additional_output_checks(writer, stdout, stderr): - if 'ZeroDivisionError' not in stderr: - raise AssertionError('Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s' % ( - stdout, stderr)) + if "ZeroDivisionError" not in stderr: + raise AssertionError("Expected test to have an unhandled exception.\nstdout:\n%s\n\nstderr:\n%s" % (stdout, stderr)) with case_setup_dap.test_file( - target_file, - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks, - EXPECTED_RETURNCODE=1, - ) as writer: + target_file, + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + EXPECTED_RETURNCODE=1, + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_exception_breakpoints(['uncaught']) + json_facade.write_set_exception_breakpoints(["uncaught"]) json_facade.write_make_initial_run() - line_in_main = writer.get_line_index_with_content('exc line') + line_in_main = writer.get_line_index_with_content("exc line") - json_hit = json_facade.wait_for_thread_stopped( - reason='exception', line=line_in_main, file=target_file) + json_hit = json_facade.wait_for_thread_stopped(reason="exception", line=line_in_main, file=target_file) frames = json_hit.stack_trace_response.body.stackFrames json_facade.write_continue() - if 'generator' in target_file: - expected_frame_names = ['', 'f', ''] + if "generator" in target_file: + expected_frame_names = ["", "f", ""] else: if IS_PY312_OR_GREATER: - expected_frame_names = ['f', ''] + expected_frame_names = ["f", ""] else: - expected_frame_names = ['', 'f', ''] + expected_frame_names = ["", "f", ""] - frame_names = [f['name'] for f in frames] + frame_names = [f["name"] for f in frames] assert frame_names == expected_frame_names writer.finished_ok = True def test_case_sys_exit_unhandled_exception(case_setup_dap): - - with case_setup_dap.test_file('_debugger_case_sysexit.py', EXPECTED_RETURNCODE=1) as writer: + with case_setup_dap.test_file("_debugger_case_sysexit.py", EXPECTED_RETURNCODE=1) as writer: json_facade = JsonFacade(writer) - json_facade.write_set_exception_breakpoints(['uncaught']) + json_facade.write_set_exception_breakpoints(["uncaught"]) json_facade.write_make_initial_run() - break_line = writer.get_line_index_with_content('sys.exit(1)') - json_facade.wait_for_thread_stopped( - reason='exception', line=break_line) + break_line = writer.get_line_index_with_content("sys.exit(1)") + json_facade.wait_for_thread_stopped(reason="exception", line=break_line) json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('break_on_system_exit_zero', [True, False]) -@pytest.mark.parametrize('target', ['_debugger_case_sysexit_0.py', '_debugger_case_sysexit_none.py']) +@pytest.mark.parametrize("break_on_system_exit_zero", [True, False]) +@pytest.mark.parametrize("target", ["_debugger_case_sysexit_0.py", "_debugger_case_sysexit_none.py"]) def test_case_sys_exit_0_unhandled_exception(case_setup_dap, break_on_system_exit_zero, target): - with case_setup_dap.test_file(target, EXPECTED_RETURNCODE=0) as writer: json_facade = JsonFacade(writer) kwargs = {} if break_on_system_exit_zero: - kwargs = {'breakOnSystemExitZero': True} + kwargs = {"breakOnSystemExitZero": True} json_facade.write_launch(**kwargs) - json_facade.write_set_exception_breakpoints(['uncaught']) + json_facade.write_set_exception_breakpoints(["uncaught"]) json_facade.write_make_initial_run() - break_line = writer.get_line_index_with_content('sys.exit(') + break_line = writer.get_line_index_with_content("sys.exit(") if break_on_system_exit_zero: - json_facade.wait_for_thread_stopped( - reason='exception', line=break_line) + json_facade.wait_for_thread_stopped(reason="exception", line=break_line) json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('break_on_system_exit_zero', [True, False]) +@pytest.mark.parametrize("break_on_system_exit_zero", [True, False]) def test_case_sys_exit_0_handled_exception(case_setup_dap, break_on_system_exit_zero): - - with case_setup_dap.test_file('_debugger_case_sysexit_0.py', EXPECTED_RETURNCODE=0) as writer: + with case_setup_dap.test_file("_debugger_case_sysexit_0.py", EXPECTED_RETURNCODE=0) as writer: json_facade = JsonFacade(writer) json_facade.write_launch( - debugOptions=['BreakOnSystemExitZero'] if break_on_system_exit_zero else [], + debugOptions=["BreakOnSystemExitZero"] if break_on_system_exit_zero else [], ) - json_facade.write_set_exception_breakpoints(['raised']) + json_facade.write_set_exception_breakpoints(["raised"]) json_facade.write_make_initial_run() - break_line = writer.get_line_index_with_content('sys.exit(0)') - break_main_line = writer.get_line_index_with_content('call_main_line') + break_line = writer.get_line_index_with_content("sys.exit(0)") + break_main_line = writer.get_line_index_with_content("call_main_line") if break_on_system_exit_zero: - json_facade.wait_for_thread_stopped( - reason='exception', line=break_line) + json_facade.wait_for_thread_stopped(reason="exception", line=break_line) json_facade.write_continue() - json_facade.wait_for_thread_stopped( - reason='exception', line=break_main_line) + json_facade.wait_for_thread_stopped(reason="exception", line=break_main_line) json_facade.write_continue() writer.finished_ok = True def test_case_handled_exception_breaks_by_type(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_exceptions.py') as writer: + with case_setup_dap.test_file("_debugger_case_exceptions.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_exception_breakpoints(exception_options=[ - ExceptionOptions(breakMode='always', path=[ - {'names': ['Python Exceptions']}, - {'names': ['IndexError']}, - ]) - ]) + json_facade.write_set_exception_breakpoints( + exception_options=[ + ExceptionOptions( + breakMode="always", + path=[ + {"names": ["Python Exceptions"]}, + {"names": ["IndexError"]}, + ], + ) + ] + ) json_facade.write_make_initial_run() - json_facade.wait_for_thread_stopped( - reason='exception', line=writer.get_line_index_with_content('raise indexerror line')) + json_facade.wait_for_thread_stopped(reason="exception", line=writer.get_line_index_with_content("raise indexerror line")) # Deal only with RuntimeErorr now. - json_facade.write_set_exception_breakpoints(exception_options=[ - ExceptionOptions(breakMode='always', path=[ - {'names': ['Python Exceptions']}, - {'names': ['RuntimeError']}, - ]) - ]) + json_facade.write_set_exception_breakpoints( + exception_options=[ + ExceptionOptions( + breakMode="always", + path=[ + {"names": ["Python Exceptions"]}, + {"names": ["RuntimeError"]}, + ], + ) + ] + ) json_facade.write_continue() @@ -1377,22 +1381,22 @@ def test_case_handled_exception_breaks_by_type(case_setup_dap): def test_case_json_protocol(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_print.py') as writer: + with case_setup_dap.test_file("_debugger_case_print.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - break_line = writer.get_line_index_with_content('Break here') + break_line = writer.get_line_index_with_content("Break here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() - json_facade.wait_for_json_message(ThreadEvent, lambda event: event.body.reason == 'started') + json_facade.wait_for_json_message(ThreadEvent, lambda event: event.body.reason == "started") json_facade.wait_for_thread_stopped(line=break_line) # : :type response: ThreadsResponse response = json_facade.write_list_threads() assert len(response.body.threads) == 1 - assert next(iter(response.body.threads))['name'] == 'MainThread' + assert next(iter(response.body.threads))["name"] == "MainThread" # Removes breakpoints and proceeds running. json_facade.write_disconnect() @@ -1401,18 +1405,18 @@ def test_case_json_protocol(case_setup_dap): def test_case_started_exited_threads_protocol(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_thread_started_exited.py') as writer: + with case_setup_dap.test_file("_debugger_case_thread_started_exited.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - break_line = writer.get_line_index_with_content('Break here') + break_line = writer.get_line_index_with_content("Break here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() _stopped_event = json_facade.wait_for_json_message(StoppedEvent) - started_events = json_facade.mark_messages(ThreadEvent, lambda x: x.body.reason == 'started') - exited_events = json_facade.mark_messages(ThreadEvent, lambda x: x.body.reason == 'exited') + started_events = json_facade.mark_messages(ThreadEvent, lambda x: x.body.reason == "started") + exited_events = json_facade.mark_messages(ThreadEvent, lambda x: x.body.reason == "exited") assert len(started_events) == 4 assert len(exited_events) == 3 # Main is still running. json_facade.write_continue() @@ -1422,11 +1426,12 @@ def test_case_started_exited_threads_protocol(case_setup_dap): def test_case_path_translation_not_skipped(case_setup_dap): import site + sys_folder = None - if hasattr(site, 'getusersitepackages'): + if hasattr(site, "getusersitepackages"): sys_folder = site.getusersitepackages() - if not sys_folder and hasattr(site, 'getsitepackages'): + if not sys_folder and hasattr(site, "getsitepackages"): sys_folder = site.getsitepackages() if not sys_folder: @@ -1435,223 +1440,244 @@ def test_case_path_translation_not_skipped(case_setup_dap): if isinstance(sys_folder, (list, tuple)): sys_folder = next(iter(sys_folder)) - with case_setup_dap.test_file('my_code/my_code.py') as writer: + with case_setup_dap.test_file("my_code/my_code.py") as writer: json_facade = JsonFacade(writer) # We need to set up path mapping to enable source references. - my_code = debugger_unittest._get_debugger_test_file('my_code') + my_code = debugger_unittest._get_debugger_test_file("my_code") json_facade.write_launch( justMyCode=False, - pathMappings=[{ - 'localRoot': sys_folder, - 'remoteRoot': my_code, - }] + pathMappings=[ + { + "localRoot": sys_folder, + "remoteRoot": my_code, + } + ], ) - bp_line = writer.get_line_index_with_content('break here') + bp_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints( bp_line, - filename=os.path.join(sys_folder, 'my_code.py'), + filename=os.path.join(sys_folder, "my_code.py"), ) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped(line=bp_line) stack_frame = json_hit.stack_trace_response.body.stackFrames[-1] - assert stack_frame['source']['path'] == os.path.join(sys_folder, 'my_code.py') + assert stack_frame["source"]["path"] == os.path.join(sys_folder, "my_code.py") for stack_frame in json_hit.stack_trace_response.body.stackFrames: - assert stack_frame['source']['sourceReference'] == 0 + assert stack_frame["source"]["sourceReference"] == 0 json_facade.write_continue() writer.finished_ok = True def test_case_exclude_double_step(case_setup_dap): - with case_setup_dap.test_file('my_code/my_code_double_step.py') as writer: + with case_setup_dap.test_file("my_code/my_code_double_step.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch( justMyCode=False, # i.e.: exclude through rules and not my code rules=[ - {'path': '**/other_noop.py', 'include':False}, - ] + {"path": "**/other_noop.py", "include": False}, + ], ) - break_line = writer.get_line_index_with_content('break here') + break_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped(line=break_line) json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', file='my_code_double_step.py', line=break_line + 1) + json_hit = json_facade.wait_for_thread_stopped("step", file="my_code_double_step.py", line=break_line + 1) json_facade.write_continue() writer.finished_ok = True def test_case_update_rules(case_setup_dap): - with case_setup_dap.test_file('my_code/my_code.py') as writer: + with case_setup_dap.test_file("my_code/my_code.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch( rules=[ - {'path': '**/other.py', 'include':False}, + {"path": "**/other.py", "include": False}, ] ) - break_line = writer.get_line_index_with_content('break here') + break_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() - json_facade.wait_for_json_message(ThreadEvent, lambda event: event.body.reason == 'started') + json_facade.wait_for_json_message(ThreadEvent, lambda event: event.body.reason == "started") json_hit = json_facade.wait_for_thread_stopped(line=break_line) json_facade.reset_sent_launch_or_attach() json_facade.write_launch( rules=[ - {'path': '**/other.py', 'include':True}, + {"path": "**/other.py", "include": True}, ] ) json_facade.write_step_in(json_hit.thread_id) # Not how we stoppen in the file that wasn't initially included. - json_hit = json_facade.wait_for_thread_stopped('step', name='call_me_back1') + json_hit = json_facade.wait_for_thread_stopped("step", name="call_me_back1") json_facade.reset_sent_launch_or_attach() json_facade.write_launch( rules=[ - {'path': '**/other.py', 'include':False}, + {"path": "**/other.py", "include": False}, ] ) json_facade.write_step_in(json_hit.thread_id) # Not how we go back to the callback and not to the `call_me_back1` because # `call_me_back1` is now excluded again. - json_hit = json_facade.wait_for_thread_stopped('step', name='callback1') + json_hit = json_facade.wait_for_thread_stopped("step", name="callback1") json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize("custom_setup", [ - 'set_exclude_launch_module_full', - 'set_exclude_launch_module_prefix', - 'set_exclude_launch_path_match_filename', - 'set_exclude_launch_path_match_folder', - 'set_just_my_code', - 'set_just_my_code_and_include', -]) +@pytest.mark.parametrize( + "custom_setup", + [ + "set_exclude_launch_module_full", + "set_exclude_launch_module_prefix", + "set_exclude_launch_path_match_filename", + "set_exclude_launch_path_match_folder", + "set_just_my_code", + "set_just_my_code_and_include", + ], +) def test_case_skipping_filters(case_setup_dap, custom_setup): - with case_setup_dap.test_file('my_code/my_code.py') as writer: + with case_setup_dap.test_file("my_code/my_code.py") as writer: json_facade = JsonFacade(writer) expect_just_my_code = False - if custom_setup == 'set_exclude_launch_path_match_filename': + if custom_setup == "set_exclude_launch_path_match_filename": json_facade.write_launch( justMyCode=False, rules=[ - {'path': '**/other.py', 'include':False}, - ] + {"path": "**/other.py", "include": False}, + ], ) - elif custom_setup == 'set_exclude_launch_path_match_folder': - not_my_code_dir = debugger_unittest._get_debugger_test_file('not_my_code') + elif custom_setup == "set_exclude_launch_path_match_folder": + not_my_code_dir = debugger_unittest._get_debugger_test_file("not_my_code") json_facade.write_launch( debugStdLib=True, rules=[ - {'path': not_my_code_dir, 'include':False}, - ] + {"path": not_my_code_dir, "include": False}, + ], ) - other_filename = os.path.join(not_my_code_dir, 'other.py') + other_filename = os.path.join(not_my_code_dir, "other.py") response = json_facade.write_set_breakpoints(1, filename=other_filename, verified=False) assert response.body.breakpoints == [ - {'verified': False, 'id': 0, 'message': 'Breakpoint in file excluded by filters.', 'source': {'path': other_filename}, 'line': 1}] + { + "verified": False, + "id": 0, + "message": "Breakpoint in file excluded by filters.", + "source": {"path": other_filename}, + "line": 1, + } + ] # Note: there's actually a use-case where we'd hit that breakpoint even if it was excluded # by filters, so, we must actually clear it afterwards (the use-case is that when we're # stepping into the context with the breakpoint we wouldn't skip it). json_facade.write_set_breakpoints([], filename=other_filename) - other_filename = os.path.join(not_my_code_dir, 'file_that_does_not_exist.py') + other_filename = os.path.join(not_my_code_dir, "file_that_does_not_exist.py") response = json_facade.write_set_breakpoints(1, filename=other_filename, verified=False) assert response.body.breakpoints == [ - {'verified': False, 'id': 1, 'message': 'Breakpoint in file that does not exist.', 'source': {'path': other_filename}, 'line': 1}] + { + "verified": False, + "id": 1, + "message": "Breakpoint in file that does not exist.", + "source": {"path": other_filename}, + "line": 1, + } + ] - elif custom_setup == 'set_exclude_launch_module_full': + elif custom_setup == "set_exclude_launch_module_full": json_facade.write_launch( - debugOptions=['DebugStdLib'], + debugOptions=["DebugStdLib"], rules=[ - {'module': 'not_my_code.other', 'include':False}, - ] + {"module": "not_my_code.other", "include": False}, + ], ) - elif custom_setup == 'set_exclude_launch_module_prefix': + elif custom_setup == "set_exclude_launch_module_prefix": json_facade.write_launch( - debugOptions=['DebugStdLib'], + debugOptions=["DebugStdLib"], rules=[ - {'module': 'not_my_code', 'include':False}, - ] + {"module": "not_my_code", "include": False}, + ], ) - elif custom_setup == 'set_just_my_code': + elif custom_setup == "set_just_my_code": expect_just_my_code = True - writer.write_set_project_roots([debugger_unittest._get_debugger_test_file('my_code')]) + writer.write_set_project_roots([debugger_unittest._get_debugger_test_file("my_code")]) json_facade.write_launch(debugOptions=[]) - not_my_code_dir = debugger_unittest._get_debugger_test_file('not_my_code') - other_filename = os.path.join(not_my_code_dir, 'other.py') - response = json_facade.write_set_breakpoints( - 33, filename=other_filename, verified=False, expected_lines_in_response=[14]) - assert response.body.breakpoints == [{ - 'verified': False, - 'id': 0, - 'message': 'Breakpoint in file excluded by filters.\nNote: may be excluded because of \"justMyCode\" option (default == true).Try setting \"justMyCode\": false in the debug configuration (e.g., launch.json).\n', - 'source': {'path': other_filename}, - 'line': 14 - }] - elif custom_setup == 'set_just_my_code_and_include': + not_my_code_dir = debugger_unittest._get_debugger_test_file("not_my_code") + other_filename = os.path.join(not_my_code_dir, "other.py") + response = json_facade.write_set_breakpoints(33, filename=other_filename, verified=False, expected_lines_in_response=[14]) + assert response.body.breakpoints == [ + { + "verified": False, + "id": 0, + "message": 'Breakpoint in file excluded by filters.\nNote: may be excluded because of "justMyCode" option (default == true).Try setting "justMyCode": false in the debug configuration (e.g., launch.json).\n', + "source": {"path": other_filename}, + "line": 14, + } + ] + elif custom_setup == "set_just_my_code_and_include": expect_just_my_code = True # I.e.: nothing in my_code (add it with rule). - writer.write_set_project_roots([debugger_unittest._get_debugger_test_file('launch')]) + writer.write_set_project_roots([debugger_unittest._get_debugger_test_file("launch")]) json_facade.write_launch( debugOptions=[], rules=[ - {'module': '__main__', 'include':True}, - ] + {"module": "__main__", "include": True}, + ], ) else: - raise AssertionError('Unhandled: %s' % (custom_setup,)) + raise AssertionError("Unhandled: %s" % (custom_setup,)) - break_line = writer.get_line_index_with_content('break here') + break_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() - json_facade.wait_for_json_message(ThreadEvent, lambda event: event.body.reason == 'started') + json_facade.wait_for_json_message(ThreadEvent, lambda event: event.body.reason == "started") json_hit = json_facade.wait_for_thread_stopped(line=break_line) json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='callback1') + json_hit = json_facade.wait_for_thread_stopped("step", name="callback1") messages = json_facade.mark_messages( - OutputEvent, lambda output_event: 'Frame skipped from debugging during step-in.' in output_event.body.output) + OutputEvent, lambda output_event: "Frame skipped from debugging during step-in." in output_event.body.output + ) assert len(messages) == 1 body = next(iter(messages)).body - found_just_my_code = 'Note: may have been skipped because of \"justMyCode\" option (default == true)' in body.output + found_just_my_code = 'Note: may have been skipped because of "justMyCode" option (default == true)' in body.output assert found_just_my_code == expect_just_my_code - assert body.category == 'important' + assert body.category == "important" json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='callback2') + json_hit = json_facade.wait_for_thread_stopped("step", name="callback2") json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='callback1') + json_hit = json_facade.wait_for_thread_stopped("step", name="callback1") json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='') + json_hit = json_facade.wait_for_thread_stopped("step", name="") json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='') + json_hit = json_facade.wait_for_thread_stopped("step", name="") json_facade.write_step_next(json_hit.thread_id) @@ -1659,17 +1685,23 @@ def test_case_skipping_filters(case_setup_dap, custom_setup): json_facade.write_continue() # Check that it's sent only once. - assert len(json_facade.mark_messages( - OutputEvent, lambda output_event: 'Frame skipped from debugging during step-in.' in output_event.body.output)) == 0 + assert ( + len( + json_facade.mark_messages( + OutputEvent, lambda output_event: "Frame skipped from debugging during step-in." in output_event.body.output + ) + ) + == 0 + ) writer.finished_ok = True def test_case_completions_json(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_completions.py') as writer: + with case_setup_dap.test_file("_debugger_case_completions.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() @@ -1681,51 +1713,41 @@ def test_case_completions_json(case_setup_dap): if i == 0: first_hit = json_hit - completions_arguments = pydevd_schema.CompletionsArguments( - 'dict.', 6, frameId=json_hit.frame_id, line=0) - completions_request = json_facade.write_request( - pydevd_schema.CompletionsRequest(completions_arguments)) + completions_arguments = pydevd_schema.CompletionsArguments("dict.", 6, frameId=json_hit.frame_id, line=0) + completions_request = json_facade.write_request(pydevd_schema.CompletionsRequest(completions_arguments)) response = json_facade.wait_for_response(completions_request) assert response.success - labels = [x['label'] for x in response.body.targets] - assert set(labels).issuperset(set(['__contains__', 'items', 'keys', 'values'])) + labels = [x["label"] for x in response.body.targets] + assert set(labels).issuperset(set(["__contains__", "items", "keys", "values"])) - completions_arguments = pydevd_schema.CompletionsArguments( - 'dict.item', 10, frameId=json_hit.frame_id) - completions_request = json_facade.write_request( - pydevd_schema.CompletionsRequest(completions_arguments)) + completions_arguments = pydevd_schema.CompletionsArguments("dict.item", 10, frameId=json_hit.frame_id) + completions_request = json_facade.write_request(pydevd_schema.CompletionsRequest(completions_arguments)) response = json_facade.wait_for_response(completions_request) assert response.success if IS_JYTHON: - assert response.body.targets == [ - {'start': 5, 'length': 4, 'type': 'keyword', 'label': 'items'}] + assert response.body.targets == [{"start": 5, "length": 4, "type": "keyword", "label": "items"}] else: - assert response.body.targets == [ - {'start': 5, 'length': 4, 'type': 'function', 'label': 'items'}] + assert response.body.targets == [{"start": 5, "length": 4, "type": "function", "label": "items"}] if i == 1: # Check with a previously existing frameId. assert first_hit.frame_id != json_hit.frame_id - completions_arguments = pydevd_schema.CompletionsArguments( - 'dict.item', 10, frameId=first_hit.frame_id) - completions_request = json_facade.write_request( - pydevd_schema.CompletionsRequest(completions_arguments)) + completions_arguments = pydevd_schema.CompletionsArguments("dict.item", 10, frameId=first_hit.frame_id) + completions_request = json_facade.write_request(pydevd_schema.CompletionsRequest(completions_arguments)) response = json_facade.wait_for_response(completions_request) assert not response.success - assert response.message == 'Thread to get completions seems to have resumed already.' + assert response.message == "Thread to get completions seems to have resumed already." # Check with a never frameId which never existed. - completions_arguments = pydevd_schema.CompletionsArguments( - 'dict.item', 10, frameId=99999) - completions_request = json_facade.write_request( - pydevd_schema.CompletionsRequest(completions_arguments)) + completions_arguments = pydevd_schema.CompletionsArguments("dict.item", 10, frameId=99999) + completions_request = json_facade.write_request(pydevd_schema.CompletionsRequest(completions_arguments)) response = json_facade.wait_for_response(completions_request) assert not response.success - assert response.message.startswith('Wrong ID sent from the client:') + assert response.message.startswith("Wrong ID sent from the client:") json_facade.write_continue() @@ -1733,39 +1755,37 @@ def test_case_completions_json(case_setup_dap): def test_modules(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_local_variables.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break 2 here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break 2 here")) json_facade.write_make_initial_run() stopped_event = json_facade.wait_for_json_message(StoppedEvent) thread_id = stopped_event.body.threadId - json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=thread_id))) + json_facade.write_request(pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=thread_id))) json_facade.wait_for_json_message(ModuleEvent) # : :type response: ModulesResponse # : :type modules_response_body: ModulesResponseBody - response = json_facade.wait_for_response(json_facade.write_request( - pydevd_schema.ModulesRequest(pydevd_schema.ModulesArguments()))) + response = json_facade.wait_for_response(json_facade.write_request(pydevd_schema.ModulesRequest(pydevd_schema.ModulesArguments()))) modules_response_body = response.body assert len(modules_response_body.modules) == 1 module = next(iter(modules_response_body.modules)) - assert module['name'] == '__main__' - assert module['path'].endswith('_debugger_case_local_variables.py') + assert module["name"] == "__main__" + assert module["path"].endswith("_debugger_case_local_variables.py") json_facade.write_continue() writer.finished_ok = True def test_dict_ordered(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_odict.py') as writer: + with case_setup_dap.test_file("_debugger_case_odict.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -1775,35 +1795,37 @@ def test_dict_ordered(case_setup_dap): variables_references = variables_response.body.variables for dct in variables_references: - if dct['name'] == 'odict': + if dct["name"] == "odict": break else: raise AssertionError('Expected to find "odict".') - ref = dct['variablesReference'] + ref = dct["variablesReference"] assert isinstance(ref, int_types) # : :type variables_response: VariablesResponse variables_response = json_facade.get_variables_response(ref) - assert [(d['name'], d['value']) for d in variables_response.body.variables if (not d['name'].startswith('_OrderedDict')) and (d['name'] not in DAPGrouper.SCOPES_SORTED)] == [ - ('4', "'first'"), ('3', "'second'"), ('2', "'last'"), (GENERATED_LEN_ATTR_NAME, '3')] + assert [ + (d["name"], d["value"]) + for d in variables_response.body.variables + if (not d["name"].startswith("_OrderedDict")) and (d["name"] not in DAPGrouper.SCOPES_SORTED) + ] == [("4", "'first'"), ("3", "'second'"), ("2", "'last'"), (GENERATED_LEN_ATTR_NAME, "3")] json_facade.write_continue() writer.finished_ok = True def test_dict_contents(case_setup_dap, pyfile): - @pyfile def check(): - dct = {'a': 1, '_b_': 2, '__c__': 3} - print('TEST SUCEEDED') # break here + dct = {"a": 1, "_b_": 2, "__c__": 3} + print("TEST SUCEEDED") # break here with case_setup_dap.test_file(check) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -1813,30 +1835,30 @@ def check(): variables_references = variables_response.body.variables for dct in variables_references: - if dct['name'] == 'dct': + if dct["name"] == "dct": break else: raise AssertionError('Expected to find "dct".') - ref = dct['variablesReference'] + ref = dct["variablesReference"] assert isinstance(ref, int_types) # : :type variables_response: VariablesResponse variables_response = json_facade.get_variables_response(ref) - variable_names = set(v['name'] for v in variables_response.body.variables) - for n in ("'a'", "'_b_'", "'__c__'", 'len()'): + variable_names = set(v["name"] for v in variables_response.body.variables) + for n in ("'a'", "'_b_'", "'__c__'", "len()"): assert n in variable_names json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Putting unicode on frame vars does not work on Jython.') +@pytest.mark.skipif(IS_JYTHON, reason="Putting unicode on frame vars does not work on Jython.") def test_stack_and_variables_dict(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_local_variables.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break 2 here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break 2 here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -1850,25 +1872,32 @@ def test_stack_and_variables_dict(case_setup_dap): # : :type variables_response: VariablesResponse expected_unicode = { - 'name': u'\u16A0', - 'value': "'\u16a1'", - 'type': 'str', - 'presentationHint': {'attributes': ['rawString']}, - 'evaluateName': u'\u16A0', + "name": "\u16A0", + "value": "'\u16a1'", + "type": "str", + "presentationHint": {"attributes": ["rawString"]}, + "evaluateName": "\u16A0", } assert variables_response.body.variables == [ - {'name': 'variable_for_test_1', 'value': '10', 'type': 'int', 'evaluateName': 'variable_for_test_1'}, - {'name': 'variable_for_test_2', 'value': '20', 'type': 'int', 'evaluateName': 'variable_for_test_2'}, - {'name': 'variable_for_test_3', 'value': "{'a': 30, 'b': 20}", 'type': 'dict', 'evaluateName': 'variable_for_test_3'}, - expected_unicode + {"name": "variable_for_test_1", "value": "10", "type": "int", "evaluateName": "variable_for_test_1"}, + {"name": "variable_for_test_2", "value": "20", "type": "int", "evaluateName": "variable_for_test_2"}, + {"name": "variable_for_test_3", "value": "{'a': 30, 'b': 20}", "type": "dict", "evaluateName": "variable_for_test_3"}, + expected_unicode, ] variables_response = json_facade.get_variables_response(dict_variable_reference) - check = [x for x in variables_response.body.variables if x['name'] not in DAPGrouper.SCOPES_SORTED] + check = [x for x in variables_response.body.variables if x["name"] not in DAPGrouper.SCOPES_SORTED] assert check == [ - {'name': "'a'", 'value': '30', 'type': 'int', 'evaluateName': "variable_for_test_3['a']", 'variablesReference': 0 }, - {'name': "'b'", 'value': '20', 'type': 'int', 'evaluateName': "variable_for_test_3['b']", 'variablesReference': 0}, - {'name': GENERATED_LEN_ATTR_NAME, 'value': '2', 'type': 'int', 'evaluateName': 'len(variable_for_test_3)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}} + {"name": "'a'", "value": "30", "type": "int", "evaluateName": "variable_for_test_3['a']", "variablesReference": 0}, + {"name": "'b'", "value": "20", "type": "int", "evaluateName": "variable_for_test_3['b']", "variablesReference": 0}, + { + "name": GENERATED_LEN_ATTR_NAME, + "value": "2", + "type": "int", + "evaluateName": "len(variable_for_test_3)", + "variablesReference": 0, + "presentationHint": {"attributes": ["readOnly"]}, + }, ] json_facade.write_continue() @@ -1876,10 +1905,10 @@ def test_stack_and_variables_dict(case_setup_dap): def test_variables_with_same_name(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_variables_with_same_name.py') as writer: + with case_setup_dap.test_file("_debugger_case_variables_with_same_name.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -1893,7 +1922,7 @@ def test_variables_with_same_name(case_setup_dap): # : :type variables_response: VariablesResponse assert variables_response.body.variables == [ - {'name': 'td', 'value': "{foo: 'bar', gad: 'zooks', foo: 'bur'}", 'type': 'dict', 'evaluateName': 'td'} + {"name": "td", "value": "{foo: 'bar', gad: 'zooks', foo: 'bur'}", "type": "dict", "evaluateName": "td"} ] dict_variables_response = json_facade.get_variables_response(dict_variable_reference) @@ -1904,68 +1933,68 @@ def test_variables_with_same_name(case_setup_dap): found_foo = False found_foo_with_id = False for v in variables: - if v['name'].startswith('foo'): + if v["name"].startswith("foo"): if not found_foo: - assert v['name'] == 'foo' + assert v["name"] == "foo" found_foo = True else: - assert v['name'].startswith('foo (id: ') - v['name'] = 'foo' + assert v["name"].startswith("foo (id: ") + v["name"] = "foo" found_foo_with_id = True assert found_foo assert found_foo_with_id def compute_key(entry): - return (entry['name'], entry['value']) + return (entry["name"], entry["value"]) # Sort because the order may be different on Py2/Py3. - assert sorted(variables, key=compute_key) == sorted([ - { - 'name': 'foo', - 'value': "'bar'", - 'type': 'str', - 'variablesReference': 0, - 'presentationHint': {'attributes': ['rawString']} - }, - - { - # 'name': 'foo (id: 2699272929584)', In the code above we changed this - # to 'name': 'foo' for the comparisson. - 'name': 'foo', - 'value': "'bur'", - 'type': 'str', - 'variablesReference': 0, - 'presentationHint': {'attributes': ['rawString']} - }, - - { - 'name': 'gad', - 'value': "'zooks'", - 'type': 'str', - 'variablesReference': 0, - 'presentationHint': {'attributes': ['rawString']} - }, - - { - 'name': 'len()', - 'value': '3', - 'type': 'int', - 'evaluateName': 'len(td)', - 'variablesReference': 0, - 'presentationHint': {'attributes': ['readOnly']} - }, - ], key=compute_key) + assert sorted(variables, key=compute_key) == sorted( + [ + { + "name": "foo", + "value": "'bar'", + "type": "str", + "variablesReference": 0, + "presentationHint": {"attributes": ["rawString"]}, + }, + { + # 'name': 'foo (id: 2699272929584)', In the code above we changed this + # to 'name': 'foo' for the comparisson. + "name": "foo", + "value": "'bur'", + "type": "str", + "variablesReference": 0, + "presentationHint": {"attributes": ["rawString"]}, + }, + { + "name": "gad", + "value": "'zooks'", + "type": "str", + "variablesReference": 0, + "presentationHint": {"attributes": ["rawString"]}, + }, + { + "name": "len()", + "value": "3", + "type": "int", + "evaluateName": "len(td)", + "variablesReference": 0, + "presentationHint": {"attributes": ["readOnly"]}, + }, + ], + key=compute_key, + ) json_facade.write_continue() writer.finished_ok = True def test_hasattr_failure(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_hasattr_crash.py') as writer: + with case_setup_dap.test_file("_debugger_case_hasattr_crash.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -1974,17 +2003,17 @@ def test_hasattr_failure(case_setup_dap): variables_response = json_facade.get_variables_response(json_hit.frame_id) for variable in variables_response.body.variables: - if variable['evaluateName'] == 'obj': + if variable["evaluateName"] == "obj": break else: raise AssertionError('Did not find "obj" in %s' % (variables_response.body.variables,)) - evaluate_response = json_facade.evaluate('obj', json_hit.frame_id, context='hover') + evaluate_response = json_facade.evaluate("obj", json_hit.frame_id, context="hover") evaluate_response_body = evaluate_response.body.to_dict() - assert evaluate_response_body['result'] == 'An exception was raised: RuntimeError()' + assert evaluate_response_body["result"] == "An exception was raised: RuntimeError()" - json_facade.evaluate('not_there', json_hit.frame_id, context='hover', success=False) - json_facade.evaluate('not_there', json_hit.frame_id, context='watch', success=False) + json_facade.evaluate("not_there", json_hit.frame_id, context="hover", success=False) + json_facade.evaluate("not_there", json_hit.frame_id, context="watch", success=False) json_facade.write_continue() @@ -1992,10 +2021,10 @@ def test_hasattr_failure(case_setup_dap): def test_getattr_warning(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_warnings.py') as writer: + with case_setup_dap.test_file("_debugger_case_warnings.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -2004,14 +2033,14 @@ def test_getattr_warning(case_setup_dap): variables_response = json_facade.get_variables_response(json_hit.frame_id) for variable in variables_response.body.variables: - if variable['evaluateName'] == 'obj': + if variable["evaluateName"] == "obj": break else: raise AssertionError('Did not find "obj" in %s' % (variables_response.body.variables,)) - json_facade.evaluate('obj', json_hit.frame_id, context='hover') - json_facade.evaluate('not_there', json_hit.frame_id, context='hover', success=False) - json_facade.evaluate('not_there', json_hit.frame_id, context='watch', success=False) + json_facade.evaluate("obj", json_hit.frame_id, context="hover") + json_facade.evaluate("not_there", json_hit.frame_id, context="hover", success=False) + json_facade.evaluate("not_there", json_hit.frame_id, context="watch", success=False) json_facade.write_continue() @@ -2020,24 +2049,19 @@ def test_getattr_warning(case_setup_dap): def test_warning_on_repl(case_setup_dap): - def additional_output_checks(writer, stdout, stderr): assert "WarningCalledOnRepl" in stderr - with case_setup_dap.test_file( - '_debugger_case_evaluate.py', - additional_output_checks=additional_output_checks - ) as writer: + with case_setup_dap.test_file("_debugger_case_evaluate.py", additional_output_checks=additional_output_checks) as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() # We want warnings from the in evaluate in the repl (but not hover/watch). - json_facade.evaluate( - 'import warnings; warnings.warn("WarningCalledOnRepl")', json_hit.frame_id, context='repl') + json_facade.evaluate('import warnings; warnings.warn("WarningCalledOnRepl")', json_hit.frame_id, context="repl") json_facade.write_continue() @@ -2045,25 +2069,24 @@ def additional_output_checks(writer, stdout, stderr): def test_evaluate_none(case_setup_dap, pyfile): - @pyfile def eval_none(): - print('TEST SUCEEDED') # break here + print("TEST SUCEEDED") # break here with case_setup_dap.test_file(eval_none) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) - evaluate_response = json_facade.evaluate('None', json_hit.frame_id, context='repl') + evaluate_response = json_facade.evaluate("None", json_hit.frame_id, context="repl") assert evaluate_response.body.result is not None - assert evaluate_response.body.result == '' + assert evaluate_response.body.result == "" json_facade.write_continue() @@ -2074,7 +2097,7 @@ def test_evaluate_numpy(case_setup_dap, pyfile): try: import numpy except ImportError: - pytest.skip('numpy not available') + pytest.skip("numpy not available") @pyfile def numpy_small_array_file(): @@ -2082,14 +2105,14 @@ def numpy_small_array_file(): test_array = numpy.array(2) - print('TEST SUCEEDED') # break here + print("TEST SUCEEDED") # break here with case_setup_dap.test_file(numpy_small_array_file) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -2098,33 +2121,19 @@ def numpy_small_array_file(): variables_response = json_facade.get_variables_response(json_hit.frame_id) for variable in variables_response.body.variables: - if variable['evaluateName'] == 'test_array': + if variable["evaluateName"] == "test_array": break else: raise AssertionError('Did not find "test_array" in %s' % (variables_response.body.variables,)) - evaluate_response = json_facade.evaluate('test_array', json_hit.frame_id, context='repl') + evaluate_response = json_facade.evaluate("test_array", json_hit.frame_id, context="repl") variables_response = json_facade.get_variables_response(evaluate_response.body.variablesReference) - check = [dict([(variable['name'], variable['value'])]) for variable in variables_response.body.variables] + check = [dict([(variable["name"], variable["value"])]) for variable in variables_response.body.variables] assert check in ( - [ - {'special variables': ''}, - {'dtype': "dtype('int32')"}, - {'max': '2'}, - {'min': '2'}, - {'shape': '()'}, - {'size': '1'} - ], - [ - {'special variables': ''}, - {'dtype': "dtype('int64')"}, - {'max': '2'}, - {'min': '2'}, - {'shape': '()'}, - {'size': '1'} - ], + [{"special variables": ""}, {"dtype": "dtype('int32')"}, {"max": "2"}, {"min": "2"}, {"shape": "()"}, {"size": "1"}], + [{"special variables": ""}, {"dtype": "dtype('int64')"}, {"max": "2"}, {"min": "2"}, {"shape": "()"}, {"size": "1"}], ) json_facade.write_continue() @@ -2133,24 +2142,21 @@ def numpy_small_array_file(): def test_evaluate_name_mangling(case_setup_dap, pyfile): - @pyfile def target(): - class SomeObj(object): - def __init__(self): self.__value = 10 - print('here') # Break here + print("here") # Break here SomeObj() - print('TEST SUCEEDED') + print("TEST SUCEEDED") with case_setup_dap.test_file(target) as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_launch(justMyCode=False) json_facade.write_make_initial_run() @@ -2159,46 +2165,40 @@ def __init__(self): # Check eval with a properly indented block evaluate_response = json_facade.evaluate( - 'self.__value', + "self.__value", frameId=json_hit.frame_id, context="repl", ) - assert evaluate_response.body.result == '10' + assert evaluate_response.body.result == "10" json_facade.write_continue() writer.finished_ok = True def test_evaluate_no_name_mangling(case_setup_dap): - - with case_setup_dap.test_file('_debugger_case_local_variables2.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables2.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) # Check eval with a properly indented block - evaluate_response = json_facade.evaluate( - 'x = "_"', frameId=json_hit.frame_id, context="repl") + evaluate_response = json_facade.evaluate('x = "_"', frameId=json_hit.frame_id, context="repl") assert not evaluate_response.body.result - evaluate_response = json_facade.evaluate( - 'x', frameId=json_hit.frame_id, context="repl") + evaluate_response = json_facade.evaluate("x", frameId=json_hit.frame_id, context="repl") assert evaluate_response.body.result == "'_'" - evaluate_response = json_facade.evaluate( - 'y = "__"', frameId=json_hit.frame_id, context="repl") + evaluate_response = json_facade.evaluate('y = "__"', frameId=json_hit.frame_id, context="repl") assert not evaluate_response.body.result - evaluate_response = json_facade.evaluate( - 'y', frameId=json_hit.frame_id, context="repl") + evaluate_response = json_facade.evaluate("y", frameId=json_hit.frame_id, context="repl") assert evaluate_response.body.result == "'__'" - evaluate_response = json_facade.evaluate( - 'None', json_hit.frame_id, context='repl') + evaluate_response = json_facade.evaluate("None", json_hit.frame_id, context="repl") assert not evaluate_response.body.result json_facade.write_continue() @@ -2206,11 +2206,10 @@ def test_evaluate_no_name_mangling(case_setup_dap): def test_evaluate_block_repl(case_setup_dap): - - with case_setup_dap.test_file('_debugger_case_local_variables2.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables2.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -2223,11 +2222,9 @@ def test_evaluate_block_repl(case_setup_dap): context="repl", ) - messages = json_facade.mark_messages( - OutputEvent, lambda output_event: u'var0' in output_event.body.output) + messages = json_facade.mark_messages(OutputEvent, lambda output_event: "var0" in output_event.body.output) assert len(messages) == 1 - messages = json_facade.mark_messages( - OutputEvent, lambda output_event: u'var1' in output_event.body.output) + messages = json_facade.mark_messages(OutputEvent, lambda output_event: "var1" in output_event.body.output) assert len(messages) == 1 # Check eval with a block that needs to be dedented @@ -2237,11 +2234,9 @@ def test_evaluate_block_repl(case_setup_dap): context="repl", ) - messages = json_facade.mark_messages( - OutputEvent, lambda output_event: u'foo0' in output_event.body.output) + messages = json_facade.mark_messages(OutputEvent, lambda output_event: "foo0" in output_event.body.output) assert len(messages) == 1 - messages = json_facade.mark_messages( - OutputEvent, lambda output_event: u'foo1' in output_event.body.output) + messages = json_facade.mark_messages(OutputEvent, lambda output_event: "foo1" in output_event.body.output) assert len(messages) == 1 json_facade.write_continue() @@ -2249,58 +2244,51 @@ def test_evaluate_block_repl(case_setup_dap): def test_evaluate_block_clipboard(case_setup_dap, pyfile): - @pyfile def target(): MAX_LIMIT = 65538 class SomeObj(object): - def __str__(self): return var1 __repr__ = __str__ - var1 = 'a' * 80000 + var1 = "a" * 80000 var2 = 20000 var3 = SomeObj() - print('TEST SUCEEDED') # Break here + print("TEST SUCEEDED") # Break here def verify(evaluate_response): # : :type evaluate_response: EvaluateResponse assert len(evaluate_response.body.result) >= 80000 - assert '...' not in evaluate_response.body.result - assert set(evaluate_response.body.result).issubset(set(['a', "'"])) + assert "..." not in evaluate_response.body.result + assert set(evaluate_response.body.result).issubset(set(["a", "'"])) with case_setup_dap.test_file(target) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) evaluate_response = json_facade.evaluate( - 'var1', + "var1", frameId=json_hit.frame_id, - context='clipboard', + context="clipboard", ) verify(evaluate_response) - evaluate_response = json_facade.evaluate( - 'var2', - frameId=json_hit.frame_id, - context='clipboard', - fmt={'hex': True} - ) + evaluate_response = json_facade.evaluate("var2", frameId=json_hit.frame_id, context="clipboard", fmt={"hex": True}) assert evaluate_response.body.result == "0x4e20" evaluate_response = json_facade.evaluate( - 'var3', + "var3", frameId=json_hit.frame_id, - context='clipboard', + context="clipboard", ) verify(evaluate_response) @@ -2309,10 +2297,10 @@ def verify(evaluate_response): def test_exception_on_dir(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_dir_exception.py') as writer: + with case_setup_dap.test_file("_debugger_case_dir_exception.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -2323,70 +2311,76 @@ def test_exception_on_dir(case_setup_dap): variables_references = json_facade.pop_variables_reference(variables_response.body.variables) variables_response = json_facade.get_variables_response(variables_references[0]) assert variables_response.body.variables == [ - {'variablesReference': 0, 'type': 'int', 'evaluateName': 'self.__dict__[var1]', 'name': 'var1', 'value': '10'}] + {"variablesReference": 0, "type": "int", "evaluateName": "self.__dict__[var1]", "name": "var1", "value": "10"} + ] json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('scenario', [ - 'step_in', - 'step_next', - 'step_out', -]) -@pytest.mark.parametrize('asyncio', [True, False]) +@pytest.mark.parametrize( + "scenario", + [ + "step_in", + "step_next", + "step_out", + ], +) +@pytest.mark.parametrize("asyncio", [True, False]) def test_return_value_regular(case_setup_dap, scenario, asyncio): - with case_setup_dap.test_file('_debugger_case_return_value.py' if not asyncio else '_debugger_case_return_value_asyncio.py') as writer: + with case_setup_dap.test_file("_debugger_case_return_value.py" if not asyncio else "_debugger_case_return_value_asyncio.py") as writer: json_facade = JsonFacade(writer) - break_line = writer.get_line_index_with_content('break here') - json_facade.write_launch(debugOptions=['ShowReturnValue']) + break_line = writer.get_line_index_with_content("break here") + json_facade.write_launch(debugOptions=["ShowReturnValue"]) json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() - if scenario == 'step_next': + if scenario == "step_next": json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='main', line=break_line + 1) + json_hit = json_facade.wait_for_thread_stopped("step", name="main", line=break_line + 1) - elif scenario == 'step_in': + elif scenario == "step_in": json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='method1') + json_hit = json_facade.wait_for_thread_stopped("step", name="method1") json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='main') + json_hit = json_facade.wait_for_thread_stopped("step", name="main") - elif scenario == 'step_out': + elif scenario == "step_out": json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='method1') + json_hit = json_facade.wait_for_thread_stopped("step", name="method1") json_facade.write_step_out(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='main') + json_hit = json_facade.wait_for_thread_stopped("step", name="main") else: - raise AssertionError('unhandled scenario: %s' % (scenario,)) + raise AssertionError("unhandled scenario: %s" % (scenario,)) variables_response = json_facade.get_variables_response(json_hit.frame_id) return_variables = json_facade.filter_return_variables(variables_response.body.variables) - assert return_variables == [{ - 'name': '(return) method1', - 'value': '1', - 'type': 'int', - 'evaluateName': "__pydevd_ret_val_dict['method1']", - 'presentationHint': {'attributes': ['readOnly']}, - 'variablesReference': 0, - }] + assert return_variables == [ + { + "name": "(return) method1", + "value": "1", + "type": "int", + "evaluateName": "__pydevd_ret_val_dict['method1']", + "presentationHint": {"attributes": ["readOnly"]}, + "variablesReference": 0, + } + ] json_facade.write_continue() writer.finished_ok = True def test_stack_and_variables_set_and_list(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_local_variables2.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables2.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -2396,8 +2390,8 @@ def test_stack_and_variables_set_and_list(case_setup_dap): variables_references = json_facade.pop_variables_reference(variables_response.body.variables) expected_set = "{'a'}" assert variables_response.body.variables == [ - {'type': 'list', 'evaluateName': 'variable_for_test_1', 'name': 'variable_for_test_1', 'value': "['a', 'b']"}, - {'type': 'set', 'evaluateName': 'variable_for_test_2', 'name': 'variable_for_test_2', 'value': expected_set} + {"type": "list", "evaluateName": "variable_for_test_1", "name": "variable_for_test_1", "value": "['a', 'b']"}, + {"type": "set", "evaluateName": "variable_for_test_2", "name": "variable_for_test_2", "value": expected_set}, ] variables_response = json_facade.get_variables_response(variables_references[0]) @@ -2407,45 +2401,47 @@ def test_stack_and_variables_set_and_list(case_setup_dap): assert cleaned_vars.groups_found == set([DAPGrouper.SCOPE_SPECIAL_VARS]) else: assert cleaned_vars.groups_found == set([DAPGrouper.SCOPE_SPECIAL_VARS, DAPGrouper.SCOPE_FUNCTION_VARS]) - assert cleaned_vars.variables == [{ - u'name': u'0', - u'type': u'str', - u'value': u"'a'", - u'presentationHint': {u'attributes': [u'rawString']}, - u'evaluateName': u'variable_for_test_1[0]', - u'variablesReference': 0, - }, - { - u'name': u'1', - u'type': u'str', - u'value': u"'b'", - u'presentationHint': {u'attributes': [u'rawString']}, - u'evaluateName': u'variable_for_test_1[1]', - u'variablesReference': 0, - }, - { - u'name': GENERATED_LEN_ATTR_NAME, - u'type': u'int', - u'value': u'2', - u'evaluateName': u'len(variable_for_test_1)', - u'variablesReference': 0, - u'presentationHint': {'attributes': ['readOnly']}, - }] + assert cleaned_vars.variables == [ + { + "name": "0", + "type": "str", + "value": "'a'", + "presentationHint": {"attributes": ["rawString"]}, + "evaluateName": "variable_for_test_1[0]", + "variablesReference": 0, + }, + { + "name": "1", + "type": "str", + "value": "'b'", + "presentationHint": {"attributes": ["rawString"]}, + "evaluateName": "variable_for_test_1[1]", + "variablesReference": 0, + }, + { + "name": GENERATED_LEN_ATTR_NAME, + "type": "int", + "value": "2", + "evaluateName": "len(variable_for_test_1)", + "variablesReference": 0, + "presentationHint": {"attributes": ["readOnly"]}, + }, + ] json_facade.write_continue() writer.finished_ok = True -_CleanedVars = namedtuple('_CleanedVars', 'variables, groups_found') +_CleanedVars = namedtuple("_CleanedVars", "variables, groups_found") def _clear_groups(variables): groups_found = set() new_variables = [] for v in variables: - if v['name'] in DAPGrouper.SCOPES_SORTED: - groups_found.add(v['name']) - assert not v['type'] + if v["name"] in DAPGrouper.SCOPES_SORTED: + groups_found.add(v["name"]) + assert not v["type"] continue else: @@ -2454,26 +2450,26 @@ def _clear_groups(variables): return _CleanedVars(new_variables, groups_found) -@pytest.mark.skipif(IS_JYTHON, reason='Putting unicode on frame vars does not work on Jython.') +@pytest.mark.skipif(IS_JYTHON, reason="Putting unicode on frame vars does not work on Jython.") def test_evaluate_unicode(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_local_variables.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break 2 here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break 2 here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) - evaluate_response = json_facade.evaluate(u'\u16A0', json_hit.frame_id) + evaluate_response = json_facade.evaluate("\u16A0", json_hit.frame_id) evaluate_response_body = evaluate_response.body.to_dict() assert evaluate_response_body == { - 'result': "'\u16a1'", - 'type': 'str', - 'variablesReference': 0, - 'presentationHint': {'attributes': ['rawString']}, + "result": "'\u16a1'", + "type": "str", + "variablesReference": 0, + "presentationHint": {"attributes": ["rawString"]}, } json_facade.write_continue() @@ -2481,18 +2477,17 @@ def test_evaluate_unicode(case_setup_dap): def test_evaluate_exec_unicode(case_setup_dap): - def get_environ(writer): env = os.environ.copy() - env["PYTHONIOENCODING"] = 'utf-8' + env["PYTHONIOENCODING"] = "utf-8" return env - with case_setup_dap.test_file('_debugger_case_local_variables2.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_local_variables2.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) writer.write_start_redirect() - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -2506,7 +2501,8 @@ def get_environ(writer): ) messages = json_facade.mark_messages( - OutputEvent, lambda output_event: (u'中' in output_event.body.output) and ('pydevd warning' not in output_event.body.output)) + OutputEvent, lambda output_event: ("中" in output_event.body.output) and ("pydevd warning" not in output_event.body.output) + ) assert len(messages) == 1 # Check exec @@ -2517,7 +2513,8 @@ def get_environ(writer): ) messages = json_facade.mark_messages( - OutputEvent, lambda output_event: (u'中' in output_event.body.output) and ('pydevd warning' not in output_event.body.output)) + OutputEvent, lambda output_event: ("中" in output_event.body.output) and ("pydevd warning" not in output_event.body.output) + ) assert len(messages) == 1 response = json_facade.evaluate( @@ -2528,7 +2525,8 @@ def get_environ(writer): assert response.body.result in ("u'\\u4e2d'", "'\u4e2d'") # py2 or py3 messages = json_facade.mark_messages( - OutputEvent, lambda output_event: (u'中' in output_event.body.output) and ('pydevd warning' not in output_event.body.output)) + OutputEvent, lambda output_event: ("中" in output_event.body.output) and ("pydevd warning" not in output_event.body.output) + ) assert len(messages) == 0 # i.e.: we don't print in this case. json_facade.write_continue() @@ -2536,11 +2534,10 @@ def get_environ(writer): def test_evaluate_repl_redirect(case_setup_dap): - - with case_setup_dap.test_file('_debugger_case_local_variables2.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables2.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -2553,8 +2550,7 @@ def test_evaluate_repl_redirect(case_setup_dap): context="repl", ) - messages = json_facade.mark_messages( - OutputEvent, lambda output_event: u'var' in output_event.body.output) + messages = json_facade.mark_messages(OutputEvent, lambda output_event: "var" in output_event.body.output) assert len(messages) == 1 json_facade.write_continue() @@ -2562,21 +2558,19 @@ def test_evaluate_repl_redirect(case_setup_dap): def test_evaluate_no_double_exec(case_setup_dap, pyfile): - @pyfile def exec_code(): - def print_and_raise(): - print('Something') + print("Something") raise RuntimeError() - print('Break here') - print('TEST SUCEEDED!') + print("Break here") + print("TEST SUCEEDED!") with case_setup_dap.test_file(exec_code) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -2589,8 +2583,7 @@ def print_and_raise(): success=False, ) - messages = json_facade.mark_messages( - OutputEvent, lambda output_event: u'Something' in output_event.body.output) + messages = json_facade.mark_messages(OutputEvent, lambda output_event: "Something" in output_event.body.output) assert len(messages) == 1 json_facade.write_continue() @@ -2600,51 +2593,53 @@ def print_and_raise(): def test_evaluate_variable_references(case_setup_dap): from _pydevd_bundle._debug_adapter.pydevd_schema import EvaluateRequest from _pydevd_bundle._debug_adapter.pydevd_schema import EvaluateArguments - with case_setup_dap.test_file('_debugger_case_local_variables2.py') as writer: + + with case_setup_dap.test_file("_debugger_case_local_variables2.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) evaluate_response = json_facade.wait_for_response( - json_facade.write_request(EvaluateRequest(EvaluateArguments('variable_for_test_2', json_hit.frame_id)))) + json_facade.write_request(EvaluateRequest(EvaluateArguments("variable_for_test_2", json_hit.frame_id))) + ) evaluate_response_body = evaluate_response.body.to_dict() variables_reference = json_facade.pop_variables_reference([evaluate_response_body]) assert evaluate_response_body == { - 'type': 'set', - 'result': "{'a'}", - 'presentationHint': {}, + "type": "set", + "result": "{'a'}", + "presentationHint": {}, } assert len(variables_reference) == 1 reference = variables_reference[0] assert reference > 0 variables_response = json_facade.get_variables_response(reference) - child_variables = variables_response.to_dict()['body']['variables'] + child_variables = variables_response.to_dict()["body"]["variables"] # The name for a reference in a set is the id() of the variable and can change at each run. - del child_variables[0]['name'] + del child_variables[0]["name"] assert child_variables == [ { - 'type': 'str', - 'value': "'a'", - 'presentationHint': {'attributes': ['rawString']}, - 'variablesReference': 0, + "type": "str", + "value": "'a'", + "presentationHint": {"attributes": ["rawString"]}, + "variablesReference": 0, }, { - 'name': GENERATED_LEN_ATTR_NAME, - 'type': 'int', - 'value': '1', - 'presentationHint': {'attributes': ['readOnly']}, - 'evaluateName': 'len(variable_for_test_2)', - 'variablesReference': 0, - } + "name": GENERATED_LEN_ATTR_NAME, + "type": "int", + "value": "1", + "presentationHint": {"attributes": ["readOnly"]}, + "evaluateName": "len(variable_for_test_2)", + "variablesReference": 0, + }, ] json_facade.write_continue() @@ -2654,24 +2649,25 @@ def test_evaluate_variable_references(case_setup_dap): def test_set_expression(case_setup_dap): from _pydevd_bundle._debug_adapter.pydevd_schema import SetExpressionRequest from _pydevd_bundle._debug_adapter.pydevd_schema import SetExpressionArguments - with case_setup_dap.test_file('_debugger_case_local_variables2.py') as writer: + + with case_setup_dap.test_file("_debugger_case_local_variables2.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) set_expression_response = json_facade.wait_for_response( - json_facade.write_request(SetExpressionRequest( - SetExpressionArguments('bb', '20', frameId=json_hit.frame_id)))) - assert set_expression_response.to_dict()['body'] == { - 'value': '20', 'type': 'int', 'presentationHint': {}, 'variablesReference': 0} + json_facade.write_request(SetExpressionRequest(SetExpressionArguments("bb", "20", frameId=json_hit.frame_id))) + ) + assert set_expression_response.to_dict()["body"] == {"value": "20", "type": "int", "presentationHint": {}, "variablesReference": 0} variables_response = json_facade.get_variables_response(json_hit.frame_id) - assert {'name': 'bb', 'value': '20', 'type': 'int', 'evaluateName': 'bb', 'variablesReference': 0} in \ - variables_response.to_dict()['body']['variables'] + assert {"name": "bb", "value": "20", "type": "int", "evaluateName": "bb", "variablesReference": 0} in variables_response.to_dict()[ + "body" + ]["variables"] json_facade.write_continue() writer.finished_ok = True @@ -2681,10 +2677,10 @@ def test_set_expression_failures(case_setup_dap): from _pydevd_bundle._debug_adapter.pydevd_schema import SetExpressionRequest from _pydevd_bundle._debug_adapter.pydevd_schema import SetExpressionArguments - with case_setup_dap.test_file('_debugger_case_local_variables2.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables2.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() @@ -2692,10 +2688,10 @@ def test_set_expression_failures(case_setup_dap): json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) set_expression_response = json_facade.wait_for_response( - json_facade.write_request(SetExpressionRequest( - SetExpressionArguments('frame_not_there', '10', frameId=0)))) + json_facade.write_request(SetExpressionRequest(SetExpressionArguments("frame_not_there", "10", frameId=0))) + ) assert not set_expression_response.success - assert set_expression_response.message == 'Unable to find thread to set expression.' + assert set_expression_response.message == "Unable to find thread to set expression." json_facade.write_continue() @@ -2703,17 +2699,17 @@ def test_set_expression_failures(case_setup_dap): def test_get_variable_errors(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_completions.py') as writer: + with case_setup_dap.test_file("_debugger_case_completions.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() # First, try with wrong id. response = json_facade.get_variables_response(9999, success=False) - assert response.message == 'Wrong ID sent from the client: 9999' + assert response.message == "Wrong ID sent from the client: 9999" first_hit = None for i in range(2): @@ -2724,7 +2720,7 @@ def test_get_variable_errors(case_setup_dap): if i == 1: # Now, check with a previously existing frameId. response = json_facade.get_variables_response(first_hit.frame_id, success=False) - assert response.message == 'Unable to find thread to evaluate variable reference.' + assert response.message == "Unable to find thread to evaluate variable reference." json_facade.write_continue(wait_for_response=i == 0) if i == 0: @@ -2734,19 +2730,19 @@ def test_get_variable_errors(case_setup_dap): def test_set_variable_failure(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_local_variables2.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables2.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped() # Wrong frame - set_variable_response = json_facade.write_set_variable(0, 'invalid_reference', 'invalid_reference', success=False) + set_variable_response = json_facade.write_set_variable(0, "invalid_reference", "invalid_reference", success=False) assert not set_variable_response.success - assert set_variable_response.message == 'Unable to find thread to evaluate variable reference.' + assert set_variable_response.message == "Unable to find thread to evaluate variable reference." json_facade.write_continue() @@ -2754,121 +2750,122 @@ def test_set_variable_failure(case_setup_dap): def _check_list(json_facade, json_hit): - - variable = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_1') + variable = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_1") assert variable.value == "['a', 'b', self.var1: 11]" - var0 = json_facade.get_var(variable.variablesReference, '0') + var0 = json_facade.get_var(variable.variablesReference, "0") - json_facade.write_set_variable(variable.variablesReference, var0.name, '1') + json_facade.write_set_variable(variable.variablesReference, var0.name, "1") # Check that it was actually changed. - variable = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_1') + variable = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_1") assert variable.value == "[1, 'b', self.var1: 11]" - var1 = json_facade.get_var(variable.variablesReference, 'var1') + var1 = json_facade.get_var(variable.variablesReference, "var1") - json_facade.write_set_variable(variable.variablesReference, var1.name, '2') + json_facade.write_set_variable(variable.variablesReference, var1.name, "2") - variable = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_1') + variable = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_1") assert variable.value == "[1, 'b', self.var1: 2]" def _check_tuple(json_facade, json_hit): - - variable = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_4') + variable = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_4") assert variable.value == "tuple('a', 1, self.var1: 13)" - var0 = json_facade.get_var(variable.variablesReference, '0') + var0 = json_facade.get_var(variable.variablesReference, "0") - response = json_facade.write_set_variable(variable.variablesReference, var0.name, '1', success=False) + response = json_facade.write_set_variable(variable.variablesReference, var0.name, "1", success=False) assert response.message.startswith("Unable to change: ") - var1 = json_facade.get_var(variable.variablesReference, 'var1') - json_facade.write_set_variable(variable.variablesReference, var1.name, '2') + var1 = json_facade.get_var(variable.variablesReference, "var1") + json_facade.write_set_variable(variable.variablesReference, var1.name, "2") - variable = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_4') + variable = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_4") assert variable.value == "tuple('a', 1, self.var1: 2)" def _check_dict_subclass(json_facade, json_hit): - variable = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_3') + variable = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_3") assert variable.value == "{in_dct: 20; self.var1: 10}" - var1 = json_facade.get_var(variable.variablesReference, 'var1') + var1 = json_facade.get_var(variable.variablesReference, "var1") - json_facade.write_set_variable(variable.variablesReference, var1.name, '2') + json_facade.write_set_variable(variable.variablesReference, var1.name, "2") # Check that it was actually changed. - variable = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_3') + variable = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_3") assert variable.value == "{in_dct: 20; self.var1: 2}" var_in_dct = json_facade.get_var(variable.variablesReference, "'in_dct'") - json_facade.write_set_variable(variable.variablesReference, var_in_dct.name, '5') + json_facade.write_set_variable(variable.variablesReference, var_in_dct.name, "5") # Check that it was actually changed. - variable = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_3') + variable = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_3") assert variable.value == "{in_dct: 5; self.var1: 2}" def _check_set(json_facade, json_hit): - set_var = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_2') + set_var = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_2") assert set_var.value == "set(['a', self.var1: 12])" var_in_set = json_facade.get_var(set_var.variablesReference, index=1) - assert var_in_set.name != 'var1' + assert var_in_set.name != "var1" - set_variables_response = json_facade.write_set_variable(set_var.variablesReference, var_in_set.name, '1') + set_variables_response = json_facade.write_set_variable(set_var.variablesReference, var_in_set.name, "1") assert set_variables_response.body.type == "int" assert set_variables_response.body.value == "1" # Check that it was actually changed (which for a set means removing the existing entry # and adding a new one). - set_var = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_2') + set_var = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_2") assert set_var.value == "set([1, self.var1: 12])" # Check that it can be changed again. var_in_set = json_facade.get_var(set_var.variablesReference, index=1) # Check that adding a mutable object to the set does not work. - response = json_facade.write_set_variable(set_var.variablesReference, var_in_set.name, '[22]', success=False) - assert response.message.startswith('Unable to change: ') + response = json_facade.write_set_variable(set_var.variablesReference, var_in_set.name, "[22]", success=False) + assert response.message.startswith("Unable to change: ") # Check that it's still the same (the existing entry was not removed). - assert json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_2').value == "set([1, self.var1: 12])" + assert json_facade.get_local_var(json_hit.frame_id, "variable_for_test_2").value == "set([1, self.var1: 12])" - set_variables_response = json_facade.write_set_variable(set_var.variablesReference, var_in_set.name, '(22,)') + set_variables_response = json_facade.write_set_variable(set_var.variablesReference, var_in_set.name, "(22,)") assert set_variables_response.body.type == "tuple" assert set_variables_response.body.value == "(22,)" # Check that the tuple created can be accessed and is correct in the response. - var_in_tuple_in_set = json_facade.get_var(set_variables_response.body.variablesReference, '0') - assert var_in_tuple_in_set.name == '0' - assert var_in_tuple_in_set.value == '22' + var_in_tuple_in_set = json_facade.get_var(set_variables_response.body.variablesReference, "0") + assert var_in_tuple_in_set.name == "0" + assert var_in_tuple_in_set.value == "22" # Check that we can change the variable in the instance. - var1 = json_facade.get_var(set_var.variablesReference, 'var1') + var1 = json_facade.get_var(set_var.variablesReference, "var1") - json_facade.write_set_variable(set_var.variablesReference, var1.name, '2') + json_facade.write_set_variable(set_var.variablesReference, var1.name, "2") # Check that it was actually changed. - set_var = json_facade.get_local_var(json_hit.frame_id, 'variable_for_test_2') + set_var = json_facade.get_local_var(json_hit.frame_id, "variable_for_test_2") assert set_var.value == "set([(22,), self.var1: 2])" -@pytest.mark.parametrize('_check_func', [ - _check_tuple, - _check_set, - _check_list, - _check_dict_subclass, -]) +@pytest.mark.parametrize( + "_check_func", + [ + _check_tuple, + _check_set, + _check_list, + _check_dict_subclass, + ], +) def test_set_variable_multiple_cases(case_setup_dap, _check_func): - with case_setup_dap.test_file('_debugger_case_local_variables3.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables3.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() @@ -2882,12 +2879,10 @@ def test_set_variable_multiple_cases(case_setup_dap, _check_func): def test_get_variables_corner_case(case_setup_dap, pyfile): - @pyfile def case_with_class_as_object(): - class ClassField(object): - __name__ = 'name?' + __name__ = "name?" def __hash__(self): raise RuntimeError() @@ -2896,32 +2891,31 @@ class SomeClass(object): __class__ = ClassField() some_class = SomeClass() - print('TEST SUCEEDED') # Break here + print("TEST SUCEEDED") # Break here with case_setup_dap.test_file(case_with_class_as_object) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() - set_var = json_facade.get_local_var(json_hit.frame_id, 'some_class') - assert '__main__.SomeClass' in set_var.value + set_var = json_facade.get_local_var(json_hit.frame_id, "some_class") + assert "__main__.SomeClass" in set_var.value json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Putting unicode on frame vars does not work on Jython.') +@pytest.mark.skipif(IS_JYTHON, reason="Putting unicode on frame vars does not work on Jython.") def test_stack_and_variables(case_setup_dap): - - with case_setup_dap.test_file('_debugger_case_local_variables.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() @@ -2933,14 +2927,14 @@ def test_stack_and_variables(case_setup_dap): # Check stack trace format. stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments( - threadId=json_hit.thread_id, - format={'module': True, 'line': True} - ))) + pydevd_schema.StackTraceRequest( + pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id, format={"module": True, "line": True}) + ) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_trace_response_body = stack_trace_response.body stack_frame = next(iter(stack_trace_response_body.stackFrames)) - assert stack_frame['name'] == '__main__.Call : 4' + assert stack_frame["name"] == "__main__.Call : 4" # Regular stack trace request (no format). json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) @@ -2948,11 +2942,11 @@ def test_stack_and_variables(case_setup_dap): stack_trace_response_body = stack_trace_response.body assert len(stack_trace_response_body.stackFrames) == 2 stack_frame = next(iter(stack_trace_response_body.stackFrames)) - assert stack_frame['name'] == 'Call' - assert stack_frame['source']['path'].endswith('_debugger_case_local_variables.py') + assert stack_frame["name"] == "Call" + assert stack_frame["source"]["path"].endswith("_debugger_case_local_variables.py") - name_to_scope = json_facade.get_name_to_scope(stack_frame['id']) - scope = name_to_scope['Locals'] + name_to_scope = json_facade.get_name_to_scope(stack_frame["id"]) + scope = name_to_scope["Locals"] frame_variables_reference = scope.variablesReference assert isinstance(frame_variables_reference, int) @@ -2961,28 +2955,32 @@ def test_stack_and_variables(case_setup_dap): assert len(variables_response.body.variables) == 0 # No variables expected here json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step') + json_hit = json_facade.wait_for_thread_stopped("step") variables_response = json_facade.get_variables_response(frame_variables_reference) # : :type variables_response: VariablesResponse - assert variables_response.body.variables == [{ - 'name': 'variable_for_test_1', - 'value': '10', - 'type': 'int', - 'evaluateName': 'variable_for_test_1', - 'variablesReference': 0, - }] + assert variables_response.body.variables == [ + { + "name": "variable_for_test_1", + "value": "10", + "type": "int", + "evaluateName": "variable_for_test_1", + "variablesReference": 0, + } + ] # Same thing with hex format - variables_response = json_facade.get_variables_response(frame_variables_reference, fmt={'hex': True}) + variables_response = json_facade.get_variables_response(frame_variables_reference, fmt={"hex": True}) # : :type variables_response: VariablesResponse - assert variables_response.body.variables == [{ - 'name': 'variable_for_test_1', - 'value': '0xa', - 'type': 'int', - 'evaluateName': 'variable_for_test_1', - 'variablesReference': 0, - }] + assert variables_response.body.variables == [ + { + "name": "variable_for_test_1", + "value": "0xa", + "type": "int", + "evaluateName": "variable_for_test_1", + "variablesReference": 0, + } + ] # Note: besides the scope/stack/variables we can also have references when: # - setting variable @@ -2994,13 +2992,12 @@ def test_stack_and_variables(case_setup_dap): # Reference is for parent (in this case the frame). # We'll change `variable_for_test_1` from 10 to [1]. - set_variable_response = json_facade.write_set_variable( - frame_variables_reference, 'variable_for_test_1', '[1]') - set_variable_response_as_dict = set_variable_response.to_dict()['body'] + set_variable_response = json_facade.write_set_variable(frame_variables_reference, "variable_for_test_1", "[1]") + set_variable_response_as_dict = set_variable_response.to_dict()["body"] if not IS_JYTHON: # Not properly changing var on Jython. - assert isinstance(set_variable_response_as_dict.pop('variablesReference'), int) - assert set_variable_response_as_dict == {'value': "[1]", 'type': 'list'} + assert isinstance(set_variable_response_as_dict.pop("variablesReference"), int) + assert set_variable_response_as_dict == {"value": "[1]", "type": "list"} variables_response = json_facade.get_variables_response(frame_variables_reference) # : :type variables_response: VariablesResponse @@ -3009,12 +3006,12 @@ def test_stack_and_variables(case_setup_dap): var_as_dict = next(iter(variables)) if not IS_JYTHON: # Not properly changing var on Jython. - assert isinstance(var_as_dict.pop('variablesReference'), int) + assert isinstance(var_as_dict.pop("variablesReference"), int) assert var_as_dict == { - 'name': 'variable_for_test_1', - 'value': "[1]", - 'type': 'list', - 'evaluateName': 'variable_for_test_1', + "name": "variable_for_test_1", + "value": "[1]", + "type": "list", + "evaluateName": "variable_for_test_1", } json_facade.write_continue() @@ -3023,10 +3020,10 @@ def test_stack_and_variables(case_setup_dap): def test_hex_variables(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_local_variables_hex.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables_hex.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() @@ -3036,59 +3033,61 @@ def test_hex_variables(case_setup_dap): # : :type stack_trace_response_body: StackTraceResponseBody # : :type stack_frame: StackFrame stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id))) + pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id)) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_trace_response_body = stack_trace_response.body assert len(stack_trace_response_body.stackFrames) == 2 stack_frame = next(iter(stack_trace_response_body.stackFrames)) - assert stack_frame['name'] == 'Call' - assert stack_frame['source']['path'].endswith('_debugger_case_local_variables_hex.py') + assert stack_frame["name"] == "Call" + assert stack_frame["source"]["path"].endswith("_debugger_case_local_variables_hex.py") - name_to_scope = json_facade.get_name_to_scope(stack_frame['id']) + name_to_scope = json_facade.get_name_to_scope(stack_frame["id"]) - scope = name_to_scope['Locals'] + scope = name_to_scope["Locals"] frame_variables_reference = scope.variablesReference assert isinstance(frame_variables_reference, int) - fmt = {'hex': True} + fmt = {"hex": True} variables_request = json_facade.write_request( - pydevd_schema.VariablesRequest(pydevd_schema.VariablesArguments(frame_variables_reference, format=fmt))) + pydevd_schema.VariablesRequest(pydevd_schema.VariablesArguments(frame_variables_reference, format=fmt)) + ) variables_response = json_facade.wait_for_response(variables_request) # : :type variables_response: VariablesResponse - variable_for_test_1, variable_for_test_2, variable_for_test_3, variable_for_test_4 = sorted(list( - v for v in variables_response.body.variables if v['name'].startswith('variables_for_test') - ), key=lambda v: v['name']) + variable_for_test_1, variable_for_test_2, variable_for_test_3, variable_for_test_4 = sorted( + list(v for v in variables_response.body.variables if v["name"].startswith("variables_for_test")), key=lambda v: v["name"] + ) assert variable_for_test_1 == { - 'name': 'variables_for_test_1', - 'value': "0x64", - 'type': 'int', - 'evaluateName': 'variables_for_test_1', - 'variablesReference': 0, + "name": "variables_for_test_1", + "value": "0x64", + "type": "int", + "evaluateName": "variables_for_test_1", + "variablesReference": 0, } - assert isinstance(variable_for_test_2.pop('variablesReference'), int) + assert isinstance(variable_for_test_2.pop("variablesReference"), int) assert variable_for_test_2 == { - 'name': 'variables_for_test_2', - 'value': "[0x1, 0xa, 0x64]", - 'type': 'list', - 'evaluateName': 'variables_for_test_2' + "name": "variables_for_test_2", + "value": "[0x1, 0xa, 0x64]", + "type": "list", + "evaluateName": "variables_for_test_2", } - assert isinstance(variable_for_test_3.pop('variablesReference'), int) + assert isinstance(variable_for_test_3.pop("variablesReference"), int) assert variable_for_test_3 == { - 'name': 'variables_for_test_3', - 'value': '{0xa: 0xa, 0x64: 0x64, 0x3e8: 0x3e8}', - 'type': 'dict', - 'evaluateName': 'variables_for_test_3' + "name": "variables_for_test_3", + "value": "{0xa: 0xa, 0x64: 0x64, 0x3e8: 0x3e8}", + "type": "dict", + "evaluateName": "variables_for_test_3", } - assert isinstance(variable_for_test_4.pop('variablesReference'), int) + assert isinstance(variable_for_test_4.pop("variablesReference"), int) assert variable_for_test_4 == { - 'name': 'variables_for_test_4', - 'value': '{(0x1, 0xa, 0x64): (0x2710, 0x186a0, 0x186a0)}', - 'type': 'dict', - 'evaluateName': 'variables_for_test_4' + "name": "variables_for_test_4", + "value": "{(0x1, 0xa, 0x64): (0x2710, 0x186a0, 0x186a0)}", + "type": "dict", + "evaluateName": "variables_for_test_4", } json_facade.write_continue() @@ -3097,10 +3096,10 @@ def test_hex_variables(case_setup_dap): def test_stopped_event(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_print.py') as writer: + with case_setup_dap.test_file("_debugger_case_print.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() @@ -3112,12 +3111,12 @@ def test_stopped_event(case_setup_dap): writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Not Jython compatible (fails on set variable).') +@pytest.mark.skipif(IS_JYTHON, reason="Not Jython compatible (fails on set variable).") def test_pause_and_continue(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_pause_continue.py') as writer: + with case_setup_dap.test_file("_debugger_case_pause_continue.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() @@ -3131,27 +3130,29 @@ def test_pause_and_continue(case_setup_dap): stack_frame = next(iter(json_hit.stack_trace_response.body.stackFrames)) - name_to_scope = json_facade.get_name_to_scope(stack_frame['id']) - frame_variables_reference = name_to_scope['Locals'].variablesReference + name_to_scope = json_facade.get_name_to_scope(stack_frame["id"]) + frame_variables_reference = name_to_scope["Locals"].variablesReference - set_variable_response = json_facade.write_set_variable(frame_variables_reference, 'loop', 'False') - set_variable_response_as_dict = set_variable_response.to_dict()['body'] - assert set_variable_response_as_dict == {'value': "False", 'type': 'bool', 'variablesReference': 0} + set_variable_response = json_facade.write_set_variable(frame_variables_reference, "loop", "False") + set_variable_response_as_dict = set_variable_response.to_dict()["body"] + assert set_variable_response_as_dict == {"value": "False", "type": "bool", "variablesReference": 0} json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('stepping_resumes_all_threads', [False, True]) +@pytest.mark.parametrize("stepping_resumes_all_threads", [False, True]) def test_step_out_multi_threads(case_setup_dap, stepping_resumes_all_threads): - with case_setup_dap.test_file('_debugger_case_multi_threads_stepping.py') as writer: + with case_setup_dap.test_file("_debugger_case_multi_threads_stepping.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(steppingResumesAllThreads=stepping_resumes_all_threads) - json_facade.write_set_breakpoints([ - writer.get_line_index_with_content('Break thread 1'), - ]) + json_facade.write_set_breakpoints( + [ + writer.get_line_index_with_content("Break thread 1"), + ] + ) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -3159,42 +3160,44 @@ def test_step_out_multi_threads(case_setup_dap, stepping_resumes_all_threads): response = json_facade.write_list_threads() assert len(response.body.threads) == 3 - thread_name_to_id = dict((t['name'], t['id']) for t in response.body.threads) - assert json_hit.thread_id == thread_name_to_id['thread1'] + thread_name_to_id = dict((t["name"], t["id"]) for t in response.body.threads) + assert json_hit.thread_id == thread_name_to_id["thread1"] if stepping_resumes_all_threads: # If we're stepping with multiple threads, we'll exit here. - json_facade.write_step_out(thread_name_to_id['thread1']) + json_facade.write_step_out(thread_name_to_id["thread1"]) else: - json_facade.write_step_out(thread_name_to_id['thread1']) + json_facade.write_step_out(thread_name_to_id["thread1"]) # Timeout is expected... make it shorter. writer.reader_thread.set_messages_timeout(2) try: - json_hit = json_facade.wait_for_thread_stopped('step') - raise AssertionError('Expected timeout!') + json_hit = json_facade.wait_for_thread_stopped("step") + raise AssertionError("Expected timeout!") except debugger_unittest.TimeoutError: pass - json_facade.write_step_out(thread_name_to_id['thread2']) - json_facade.write_step_next(thread_name_to_id['MainThread']) - json_hit = json_facade.wait_for_thread_stopped('step') - assert json_hit.thread_id == thread_name_to_id['MainThread'] + json_facade.write_step_out(thread_name_to_id["thread2"]) + json_facade.write_step_next(thread_name_to_id["MainThread"]) + json_hit = json_facade.wait_for_thread_stopped("step") + assert json_hit.thread_id == thread_name_to_id["MainThread"] json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('stepping_resumes_all_threads', [True, False]) -@pytest.mark.parametrize('step_mode', ['step_next', 'step_in']) +@pytest.mark.parametrize("stepping_resumes_all_threads", [True, False]) +@pytest.mark.parametrize("step_mode", ["step_next", "step_in"]) def test_step_next_step_in_multi_threads(case_setup_dap, stepping_resumes_all_threads, step_mode): - with case_setup_dap.test_file('_debugger_case_multi_threads_stepping.py') as writer: + with case_setup_dap.test_file("_debugger_case_multi_threads_stepping.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(steppingResumesAllThreads=stepping_resumes_all_threads) - json_facade.write_set_breakpoints([ - writer.get_line_index_with_content('Break thread 1'), - ]) + json_facade.write_set_breakpoints( + [ + writer.get_line_index_with_content("Break thread 1"), + ] + ) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -3202,35 +3205,35 @@ def test_step_next_step_in_multi_threads(case_setup_dap, stepping_resumes_all_th response = json_facade.write_list_threads() assert len(response.body.threads) == 3 - thread_name_to_id = dict((t['name'], t['id']) for t in response.body.threads) - assert json_hit.thread_id == thread_name_to_id['thread1'] + thread_name_to_id = dict((t["name"], t["id"]) for t in response.body.threads) + assert json_hit.thread_id == thread_name_to_id["thread1"] for _i in range(20): - if step_mode == 'step_next': - json_facade.write_step_next(thread_name_to_id['thread1']) + if step_mode == "step_next": + json_facade.write_step_next(thread_name_to_id["thread1"]) - elif step_mode == 'step_in': - json_facade.write_step_in(thread_name_to_id['thread1']) + elif step_mode == "step_in": + json_facade.write_step_in(thread_name_to_id["thread1"]) else: - raise AssertionError('Unexpected step_mode: %s' % (step_mode,)) + raise AssertionError("Unexpected step_mode: %s" % (step_mode,)) - json_hit = json_facade.wait_for_thread_stopped('step') - assert json_hit.thread_id == thread_name_to_id['thread1'] - local_var = json_facade.get_local_var(json_hit.frame_id, '_event2_set') + json_hit = json_facade.wait_for_thread_stopped("step") + assert json_hit.thread_id == thread_name_to_id["thread1"] + local_var = json_facade.get_local_var(json_hit.frame_id, "_event2_set") # We're stepping in a single thread which depends on events being set in # another thread, so, we can only get here if the other thread was also released. - if local_var.value == 'True': + if local_var.value == "True": if stepping_resumes_all_threads: break else: - raise AssertionError('Did not expect _event2_set to be set when not resuming other threads on step.') + raise AssertionError("Did not expect _event2_set to be set when not resuming other threads on step.") - time.sleep(.01) + time.sleep(0.01) else: if stepping_resumes_all_threads: - raise AssertionError('Expected _event2_set to be set already.') + raise AssertionError("Expected _event2_set to be set already.") else: # That's correct, we should never reach the condition where _event2_set is set if # we're not resuming other threads on step. @@ -3242,14 +3245,13 @@ def test_step_next_step_in_multi_threads(case_setup_dap, stepping_resumes_all_th def test_stepping(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_stepping.py') as writer: + with case_setup_dap.test_file("_debugger_case_stepping.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints([ - writer.get_line_index_with_content('Break here 1'), - writer.get_line_index_with_content('Break here 2') - ]) + json_facade.write_set_breakpoints( + [writer.get_line_index_with_content("Break here 1"), writer.get_line_index_with_content("Break here 2")] + ) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -3257,24 +3259,24 @@ def test_stepping(case_setup_dap): # Test Step-Over or 'next' stack_trace_response = json_hit.stack_trace_response for stack_frame in stack_trace_response.body.stackFrames: - assert stack_frame['source']['sourceReference'] == 0 + assert stack_frame["source"]["sourceReference"] == 0 stack_frame = next(iter(stack_trace_response.body.stackFrames)) - before_step_over_line = stack_frame['line'] + before_step_over_line = stack_frame["line"] json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', line=before_step_over_line + 1) + json_hit = json_facade.wait_for_thread_stopped("step", line=before_step_over_line + 1) # Test step into or 'stepIn' json_facade.write_step_in(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='step_into') + json_hit = json_facade.wait_for_thread_stopped("step", name="step_into") # Test step return or 'stepOut' json_facade.write_continue() - json_hit = json_facade.wait_for_thread_stopped(name='step_out') + json_hit = json_facade.wait_for_thread_stopped(name="step_out") json_facade.write_step_out(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', name='Call') + json_hit = json_facade.wait_for_thread_stopped("step", name="Call") json_facade.write_continue() @@ -3282,56 +3284,55 @@ def test_stepping(case_setup_dap): def test_evaluate(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_evaluate.py') as writer: + with case_setup_dap.test_file("_debugger_case_evaluate.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id))) + pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id)) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_frame = next(iter(stack_trace_response.body.stackFrames)) - stack_frame_id = stack_frame['id'] + stack_frame_id = stack_frame["id"] # Check that evaluating variable that does not exist in hover returns success == False. - json_facade.evaluate( - 'var_does_not_exist', frameId=stack_frame_id, context='hover', success=False) + json_facade.evaluate("var_does_not_exist", frameId=stack_frame_id, context="hover", success=False) # Test evaluate request that results in 'eval' - eval_response = json_facade.evaluate('var_1', frameId=stack_frame_id, context='repl') - assert eval_response.body.result == '5' - assert eval_response.body.type == 'int' + eval_response = json_facade.evaluate("var_1", frameId=stack_frame_id, context="repl") + assert eval_response.body.result == "5" + assert eval_response.body.type == "int" # Test evaluate request that results in 'exec' - exec_response = json_facade.evaluate('var_1 = 6', frameId=stack_frame_id, context='repl') - assert exec_response.body.result == '' + exec_response = json_facade.evaluate("var_1 = 6", frameId=stack_frame_id, context="repl") + assert exec_response.body.result == "" # Test evaluate request that results in 'exec' but fails - exec_response = json_facade.evaluate( - 'var_1 = "abc"/6', frameId=stack_frame_id, context='repl', success=False) - assert 'TypeError' in exec_response.body.result - assert 'TypeError' in exec_response.message + exec_response = json_facade.evaluate('var_1 = "abc"/6', frameId=stack_frame_id, context="repl", success=False) + assert "TypeError" in exec_response.body.result + assert "TypeError" in exec_response.message # Evaluate without a frameId. # Error because 'foo_value' is not set in 'sys'. - exec_response = json_facade.evaluate('import email;email.foo_value', success=False) - assert 'AttributeError' in exec_response.body.result - assert 'AttributeError' in exec_response.message + exec_response = json_facade.evaluate("import email;email.foo_value", success=False) + assert "AttributeError" in exec_response.body.result + assert "AttributeError" in exec_response.message # Reading foo_value didn't work, but 'email' should be in the namespace now. - json_facade.evaluate('email.foo_value=True') + json_facade.evaluate("email.foo_value=True") # Ok, 'foo_value' is now set in 'email' module. - exec_response = json_facade.evaluate('email.foo_value') + exec_response = json_facade.evaluate("email.foo_value") # We don't actually get variables without a frameId, we can just evaluate and observe side effects # (so, the result is always empty -- or an error). - assert exec_response.body.result == '' + assert exec_response.body.result == "" json_facade.write_continue() @@ -3339,20 +3340,21 @@ def test_evaluate(case_setup_dap): def test_evaluate_failures(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_completions.py') as writer: + with case_setup_dap.test_file("_debugger_case_completions.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() # First, try with wrong id. exec_request = json_facade.write_request( - pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments('a = 10', frameId=9999, context='repl'))) + pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments("a = 10", frameId=9999, context="repl")) + ) exec_response = json_facade.wait_for_response(exec_request) assert exec_response.success == False - assert exec_response.message == 'Wrong ID sent from the client: 9999' + assert exec_response.message == "Wrong ID sent from the client: 9999" first_hit = None for i in range(2): @@ -3360,16 +3362,16 @@ def test_evaluate_failures(case_setup_dap): if i == 0: first_hit = json_hit # Check that watch exceptions are shown as string/failure. - response = json_facade.evaluate( - 'invalid_var', frameId=first_hit.frame_id, context='watch', success=False) + response = json_facade.evaluate("invalid_var", frameId=first_hit.frame_id, context="watch", success=False) assert response.body.result == "NameError: name 'invalid_var' is not defined" if i == 1: # Now, check with a previously existing frameId. exec_request = json_facade.write_request( - pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments('a = 10', frameId=first_hit.frame_id, context='repl'))) + pydevd_schema.EvaluateRequest(pydevd_schema.EvaluateArguments("a = 10", frameId=first_hit.frame_id, context="repl")) + ) exec_response = json_facade.wait_for_response(exec_request) assert exec_response.success == False - assert exec_response.message == 'Unable to find thread for evaluation.' + assert exec_response.message == "Unable to find thread for evaluation." json_facade.write_continue(wait_for_response=i == 0) if i == 0: @@ -3379,12 +3381,9 @@ def test_evaluate_failures(case_setup_dap): def test_evaluate_exception_trace(case_setup_dap, pyfile): - @pyfile def exception_trace_file(): - class A(object): - def __init__(self, a): pass @@ -3397,43 +3396,43 @@ def method2(): def method3(): method2() - print('TEST SUCEEDED') # Break here + print("TEST SUCEEDED") # Break here with case_setup_dap.test_file(exception_trace_file) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() - exec_response = json_facade.evaluate('method3()', json_hit.frame_id, 'repl', success=False) - assert 'pydevd' not in exec_response.message # i.e.: don't show pydevd in the trace - assert 'method3' in exec_response.message - assert 'method2' in exec_response.message + exec_response = json_facade.evaluate("method3()", json_hit.frame_id, "repl", success=False) + assert "pydevd" not in exec_response.message # i.e.: don't show pydevd in the trace + assert "method3" in exec_response.message + assert "method2" in exec_response.message - exec_response = json_facade.evaluate('method2()', json_hit.frame_id, 'repl', success=False) - assert 'pydevd' not in exec_response.message - assert 'method3' not in exec_response.message - assert 'method2' in exec_response.message + exec_response = json_facade.evaluate("method2()", json_hit.frame_id, "repl", success=False) + assert "pydevd" not in exec_response.message + assert "method3" not in exec_response.message + assert "method2" in exec_response.message json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('max_frames', ['default', 'all', 10]) # -1 = default, 0 = all, 10 = 10 frames +@pytest.mark.parametrize("max_frames", ["default", "all", 10]) # -1 = default, 0 = all, 10 = 10 frames def test_exception_details(case_setup_dap, max_frames): - with case_setup_dap.test_file('_debugger_case_large_exception_stack.py') as writer: + with case_setup_dap.test_file("_debugger_case_large_exception_stack.py") as writer: json_facade = JsonFacade(writer) - if max_frames == 'all': + if max_frames == "all": json_facade.write_launch(maxExceptionStackFrames=0) # trace back compresses repeated text min_expected_lines = 100 max_expected_lines = 220 - elif max_frames == 'default': + elif max_frames == "default": json_facade.write_launch() # default is all frames # trace back compresses repeated text @@ -3444,26 +3443,27 @@ def test_exception_details(case_setup_dap, max_frames): min_expected_lines = 10 max_expected_lines = 22 - json_facade.write_set_exception_breakpoints(['raised']) + json_facade.write_set_exception_breakpoints(["raised"]) json_facade.write_make_initial_run() - json_hit = json_facade.wait_for_thread_stopped('exception') + json_hit = json_facade.wait_for_thread_stopped("exception") exc_info_request = json_facade.write_request( - pydevd_schema.ExceptionInfoRequest(pydevd_schema.ExceptionInfoArguments(json_hit.thread_id))) + pydevd_schema.ExceptionInfoRequest(pydevd_schema.ExceptionInfoArguments(json_hit.thread_id)) + ) exc_info_response = json_facade.wait_for_response(exc_info_request) stack_frames = json_hit.stack_trace_response.body.stackFrames assert 100 <= len(stack_frames) <= 104 - assert stack_frames[-1]['name'] == '' - assert stack_frames[0]['name'] == 'method1' + assert stack_frames[-1]["name"] == "" + assert stack_frames[0]["name"] == "method1" body = exc_info_response.body - assert body.exceptionId.endswith('IndexError') - assert body.description == 'foo' - assert normcase(body.details.kwargs['source']) == normcase(writer.TEST_FILE) - stack_line_count = len(body.details.stackTrace.split('\n')) - assert min_expected_lines <= stack_line_count <= max_expected_lines + assert body.exceptionId.endswith("IndexError") + assert body.description == "foo" + assert normcase(body.details.kwargs["source"]) == normcase(writer.TEST_FILE) + stack_line_count = len(body.details.stackTrace.split("\n")) + assert min_expected_lines <= stack_line_count <= max_expected_lines json_facade.write_set_exception_breakpoints([]) # Don't stop on reraises. json_facade.write_continue() @@ -3472,17 +3472,18 @@ def test_exception_details(case_setup_dap, max_frames): def test_stack_levels(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_deep_stacks.py') as writer: + with case_setup_dap.test_file("_debugger_case_deep_stacks.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() # get full stack stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id))) + pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id)) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) full_stack_frames = stack_trace_response.body.stackFrames total_frames = stack_trace_response.body.totalFrames @@ -3492,10 +3493,10 @@ def test_stack_levels(case_setup_dap): received_frames = [] while startFrame < total_frames: stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments( - threadId=json_hit.thread_id, - startFrame=startFrame, - levels=20))) + pydevd_schema.StackTraceRequest( + pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id, startFrame=startFrame, levels=20) + ) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) received_frames += stack_trace_response.body.stackFrames startFrame += levels @@ -3508,45 +3509,49 @@ def test_stack_levels(case_setup_dap): def test_breakpoint_adjustment(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_adjust_breakpoint.py') as writer: + with case_setup_dap.test_file("_debugger_case_adjust_breakpoint.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - bp_requested = writer.get_line_index_with_content('requested') - bp_expected = writer.get_line_index_with_content('expected') + bp_requested = writer.get_line_index_with_content("requested") + bp_expected = writer.get_line_index_with_content("expected") set_bp_request = json_facade.write_request( - pydevd_schema.SetBreakpointsRequest(pydevd_schema.SetBreakpointsArguments( - source=pydevd_schema.Source(path=writer.TEST_FILE, sourceReference=0), - breakpoints=[pydevd_schema.SourceBreakpoint(bp_requested).to_dict()])) + pydevd_schema.SetBreakpointsRequest( + pydevd_schema.SetBreakpointsArguments( + source=pydevd_schema.Source(path=writer.TEST_FILE, sourceReference=0), + breakpoints=[pydevd_schema.SourceBreakpoint(bp_requested).to_dict()], + ) + ) ) set_bp_response = json_facade.wait_for_response(set_bp_request) assert set_bp_response.success - assert set_bp_response.body.breakpoints[0]['line'] == bp_expected + assert set_bp_response.body.breakpoints[0]["line"] == bp_expected json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id))) + pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id)) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_frame = next(iter(stack_trace_response.body.stackFrames)) - assert stack_frame['line'] == bp_expected + assert stack_frame["line"] == bp_expected json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='No goto on Jython.') +@pytest.mark.skipif(IS_JYTHON, reason="No goto on Jython.") def test_goto(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_set_next_statement.py') as writer: + with case_setup_dap.test_file("_debugger_case_set_next_statement.py") as writer: json_facade = JsonFacade(writer) - break_line = writer.get_line_index_with_content('Break here') - step_line = writer.get_line_index_with_content('Step here') + break_line = writer.get_line_index_with_content("Break here") + step_line = writer.get_line_index_with_content("Step here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() @@ -3554,38 +3559,39 @@ def test_goto(case_setup_dap): json_hit = json_facade.wait_for_thread_stopped() stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id))) + pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id)) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_frame = next(iter(stack_trace_response.body.stackFrames)) - assert stack_frame['line'] == break_line + assert stack_frame["line"] == break_line goto_targets_request = json_facade.write_request( - pydevd_schema.GotoTargetsRequest(pydevd_schema.GotoTargetsArguments( - source=pydevd_schema.Source(path=writer.TEST_FILE, sourceReference=0), - line=step_line))) + pydevd_schema.GotoTargetsRequest( + pydevd_schema.GotoTargetsArguments(source=pydevd_schema.Source(path=writer.TEST_FILE, sourceReference=0), line=step_line) + ) + ) goto_targets_response = json_facade.wait_for_response(goto_targets_request) - target_id = goto_targets_response.body.targets[0]['id'] + target_id = goto_targets_response.body.targets[0]["id"] goto_request = json_facade.write_request( - pydevd_schema.GotoRequest(pydevd_schema.GotoArguments( - threadId=json_hit.thread_id, - targetId=12345))) + pydevd_schema.GotoRequest(pydevd_schema.GotoArguments(threadId=json_hit.thread_id, targetId=12345)) + ) goto_response = json_facade.wait_for_response(goto_request) assert not goto_response.success goto_request = json_facade.write_request( - pydevd_schema.GotoRequest(pydevd_schema.GotoArguments( - threadId=json_hit.thread_id, - targetId=target_id))) + pydevd_schema.GotoRequest(pydevd_schema.GotoArguments(threadId=json_hit.thread_id, targetId=target_id)) + ) goto_response = json_facade.wait_for_response(goto_request) - json_hit = json_facade.wait_for_thread_stopped('goto') + json_hit = json_facade.wait_for_thread_stopped("goto") stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id))) + pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id)) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_frame = next(iter(stack_trace_response.body.stackFrames)) - assert stack_frame['line'] == step_line + assert stack_frame["line"] == step_line json_facade.write_continue() @@ -3598,67 +3604,60 @@ def test_goto(case_setup_dap): def _collect_stack_frames_ending_with(json_hit, end_with_pattern): stack_trace_response = json_hit.stack_trace_response - dont_trace_frames = list(frame for frame in stack_trace_response.body.stackFrames - if frame['source']['path'].endswith(end_with_pattern)) + dont_trace_frames = list(frame for frame in stack_trace_response.body.stackFrames if frame["source"]["path"].endswith(end_with_pattern)) return dont_trace_frames def _check_dont_trace_filtered_out(json_hit): - assert _collect_stack_frames_ending_with(json_hit, 'dont_trace.py') == [] + assert _collect_stack_frames_ending_with(json_hit, "dont_trace.py") == [] def _check_dont_trace_not_filtered_out(json_hit): - assert len(_collect_stack_frames_ending_with(json_hit, 'dont_trace.py')) == 1 + assert len(_collect_stack_frames_ending_with(json_hit, "dont_trace.py")) == 1 -@pytest.mark.parametrize('dbg_property', [ - 'dont_trace', - 'trace', - 'change_pattern', - 'dont_trace_after_start' -]) +@pytest.mark.parametrize("dbg_property", ["dont_trace", "trace", "change_pattern", "dont_trace_after_start"]) def test_set_debugger_property(case_setup_dap, dbg_property): - kwargs = {} - with case_setup_dap.test_file('_debugger_case_dont_trace_test.py', **kwargs) as writer: + with case_setup_dap.test_file("_debugger_case_dont_trace_test.py", **kwargs) as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) - if dbg_property in ('dont_trace', 'change_pattern', 'dont_trace_after_start'): - json_facade.write_set_debugger_property([], ['dont_trace.py'] if not IS_WINDOWS else ['Dont_Trace.py']) + if dbg_property in ("dont_trace", "change_pattern", "dont_trace_after_start"): + json_facade.write_set_debugger_property([], ["dont_trace.py"] if not IS_WINDOWS else ["Dont_Trace.py"]) - if dbg_property == 'change_pattern': - json_facade.write_set_debugger_property([], ['something_else.py']) + if dbg_property == "change_pattern": + json_facade.write_set_debugger_property([], ["something_else.py"]) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() - if dbg_property in ('dont_trace', 'dont_trace_after_start'): + if dbg_property in ("dont_trace", "dont_trace_after_start"): _check_dont_trace_filtered_out(json_hit) - elif dbg_property in ('change_pattern', 'trace'): + elif dbg_property in ("change_pattern", "trace"): _check_dont_trace_not_filtered_out(json_hit) else: - raise AssertionError('Unexpected: %s' % (dbg_property,)) + raise AssertionError("Unexpected: %s" % (dbg_property,)) - if dbg_property == 'dont_trace_after_start': - json_facade.write_set_debugger_property([], ['something_else.py']) + if dbg_property == "dont_trace_after_start": + json_facade.write_set_debugger_property([], ["something_else.py"]) json_facade.write_continue() json_hit = json_facade.wait_for_thread_stopped() - if dbg_property in ('dont_trace',): + if dbg_property in ("dont_trace",): _check_dont_trace_filtered_out(json_hit) - elif dbg_property in ('change_pattern', 'trace', 'dont_trace_after_start'): + elif dbg_property in ("change_pattern", "trace", "dont_trace_after_start"): _check_dont_trace_not_filtered_out(json_hit) else: - raise AssertionError('Unexpected: %s' % (dbg_property,)) + raise AssertionError("Unexpected: %s" % (dbg_property,)) json_facade.write_continue() @@ -3669,17 +3668,15 @@ def test_source_mapping_errors(case_setup_dap): from _pydevd_bundle._debug_adapter.pydevd_schema import Source from _pydevd_bundle._debug_adapter.pydevd_schema import PydevdSourceMap - with case_setup_dap.test_file('_debugger_case_source_mapping.py') as writer: + with case_setup_dap.test_file("_debugger_case_source_mapping.py") as writer: json_facade = JsonFacade(writer) - map_to_cell_1_line2 = writer.get_line_index_with_content('map to cEll1, line 2') - map_to_cell_2_line2 = writer.get_line_index_with_content('map to cEll2, line 2') + map_to_cell_1_line2 = writer.get_line_index_with_content("map to cEll1, line 2") + map_to_cell_2_line2 = writer.get_line_index_with_content("map to cEll2, line 2") - cell1_map = PydevdSourceMap(map_to_cell_1_line2, map_to_cell_1_line2 + 1, Source(path=''), 2) - cell2_map = PydevdSourceMap(map_to_cell_2_line2, map_to_cell_2_line2 + 1, Source(path=''), 2) - pydevd_source_maps = [ - cell1_map, cell2_map - ] + cell1_map = PydevdSourceMap(map_to_cell_1_line2, map_to_cell_1_line2 + 1, Source(path=""), 2) + cell2_map = PydevdSourceMap(map_to_cell_2_line2, map_to_cell_2_line2 + 1, Source(path=""), 2) + pydevd_source_maps = [cell1_map, cell2_map] json_facade.write_set_pydevd_source_map( Source(path=writer.TEST_FILE), @@ -3691,7 +3688,7 @@ def test_source_mapping_errors(case_setup_dap): # set to a file (so, any file matching that breakpoint can be removed instead of needing to check # which lines are corresponding to that file). json_facade.write_set_pydevd_source_map( - Source(path=os.path.join(os.path.dirname(writer.TEST_FILE), 'foo.py')), + Source(path=os.path.join(os.path.dirname(writer.TEST_FILE), "foo.py")), pydevd_source_maps=pydevd_source_maps, success=False, ) @@ -3700,11 +3697,8 @@ def test_source_mapping_errors(case_setup_dap): writer.finished_ok = True -@pytest.mark.parametrize( - 'target', - ['_debugger_case_source_mapping.py', '_debugger_case_source_mapping_and_reference.py'] -) -@pytest.mark.parametrize('jmc', [True, False]) +@pytest.mark.parametrize("target", ["_debugger_case_source_mapping.py", "_debugger_case_source_mapping_and_reference.py"]) +@pytest.mark.parametrize("jmc", [True, False]) def test_source_mapping_base(case_setup_dap, target, jmc): from _pydevd_bundle._debug_adapter.pydevd_schema import Source from _pydevd_bundle._debug_adapter.pydevd_schema import PydevdSourceMap @@ -3713,7 +3707,7 @@ def test_source_mapping_base(case_setup_dap, target, jmc): def get_environ(self): env = os.environ.copy() - env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath('.') + env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath(".") return env with case_setup_dap.test_file(target, get_environ=get_environ) as writer: @@ -3721,13 +3715,15 @@ def get_environ(self): json_facade.write_launch(justMyCode=jmc) - map_to_cell_1_line2 = writer.get_line_index_with_content('map to cEll1, line 2') - map_to_cell_2_line2 = writer.get_line_index_with_content('map to cEll2, line 2') + map_to_cell_1_line2 = writer.get_line_index_with_content("map to cEll1, line 2") + map_to_cell_2_line2 = writer.get_line_index_with_content("map to cEll2, line 2") - cell1_map = PydevdSourceMap(map_to_cell_1_line2, map_to_cell_1_line2 + 1, Source(path=''), 2) - cell2_map = PydevdSourceMap(map_to_cell_2_line2, map_to_cell_2_line2 + 1, Source(path=''), 2) + cell1_map = PydevdSourceMap(map_to_cell_1_line2, map_to_cell_1_line2 + 1, Source(path=""), 2) + cell2_map = PydevdSourceMap(map_to_cell_2_line2, map_to_cell_2_line2 + 1, Source(path=""), 2) pydevd_source_maps = [ - cell1_map, cell2_map, cell2_map, # The one repeated should be ignored. + cell1_map, + cell2_map, + cell2_map, # The one repeated should be ignored. ] # Set breakpoints before setting the source map (check that we reapply them). @@ -3737,7 +3733,7 @@ def get_environ(self): if isinstance(test_file, bytes): # file is in the filesystem encoding (needed for launch) but protocol needs it in utf-8 test_file = test_file.decode(file_system_encoding) - test_file = test_file.encode('utf-8') + test_file = test_file.encode("utf-8") json_facade.write_set_pydevd_source_map( Source(path=test_file), @@ -3748,13 +3744,13 @@ def get_environ(self): json_hit = json_facade.wait_for_thread_stopped(line=map_to_cell_1_line2, file=os.path.basename(test_file)) for stack_frame in json_hit.stack_trace_response.body.stackFrames: - assert stack_frame['source']['sourceReference'] == 0 + assert stack_frame["source"]["sourceReference"] == 0 # Check that we no longer stop at the cEll1 breakpoint (its mapping should be removed when # the new one is added and we should only stop at cEll2). json_facade.write_set_breakpoints(map_to_cell_2_line2) for stack_frame in json_hit.stack_trace_response.body.stackFrames: - assert stack_frame['source']['sourceReference'] == 0 + assert stack_frame["source"]["sourceReference"] == 0 json_facade.write_continue() json_hit = json_facade.wait_for_thread_stopped(line=map_to_cell_2_line2, file=os.path.basename(test_file)) @@ -3772,19 +3768,19 @@ def test_source_mapping_just_my_code(case_setup_dap): def get_environ(self): env = os.environ.copy() - env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath('.') + env["IDE_PROJECT_ROOTS"] = os.path.dirname(self.TEST_FILE) + os.pathsep + os.path.abspath(".") return env - with case_setup_dap.test_file('_debugger_case_source_mapping_jmc.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_source_mapping_jmc.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=True) - map_to_cell_1_line1 = writer.get_line_index_with_content('map to cEll1, line 1') - map_to_cell_1_line6 = writer.get_line_index_with_content('map to cEll1, line 6') - map_to_cell_1_line7 = writer.get_line_index_with_content('map to cEll1, line 7') + map_to_cell_1_line1 = writer.get_line_index_with_content("map to cEll1, line 1") + map_to_cell_1_line6 = writer.get_line_index_with_content("map to cEll1, line 6") + map_to_cell_1_line7 = writer.get_line_index_with_content("map to cEll1, line 7") - cell1_map = PydevdSourceMap(map_to_cell_1_line1, map_to_cell_1_line7, Source(path=''), 1) + cell1_map = PydevdSourceMap(map_to_cell_1_line1, map_to_cell_1_line7, Source(path=""), 1) pydevd_source_maps = [cell1_map] # Set breakpoints before setting the source map (check that we reapply them). @@ -3794,7 +3790,7 @@ def get_environ(self): if isinstance(test_file, bytes): # file is in the filesystem encoding (needed for launch) but protocol needs it in utf-8 test_file = test_file.decode(file_system_encoding) - test_file = test_file.encode('utf-8') + test_file = test_file.encode("utf-8") json_facade.write_set_pydevd_source_map( Source(path=test_file), @@ -3805,7 +3801,7 @@ def get_environ(self): json_hit = json_facade.wait_for_thread_stopped(line=map_to_cell_1_line6, file=os.path.basename(test_file)) for stack_frame in json_hit.stack_trace_response.body.stackFrames: - assert stack_frame['source']['sourceReference'] == 0 + assert stack_frame["source"]["sourceReference"] == 0 # i.e.: Remove the source maps json_facade.write_set_pydevd_source_map( @@ -3823,25 +3819,25 @@ def test_source_mapping_goto_target(case_setup_dap): from _pydevd_bundle._debug_adapter.pydevd_schema import PydevdSourceMap def additional_output_checks(writer, stdout, stderr): - assert 'Skip this print' not in stdout - assert 'TEST SUCEEDED' in stdout + assert "Skip this print" not in stdout + assert "TEST SUCEEDED" in stdout - with case_setup_dap.test_file('_debugger_case_source_map_goto_target.py', additional_output_checks=additional_output_checks) as writer: + with case_setup_dap.test_file("_debugger_case_source_map_goto_target.py", additional_output_checks=additional_output_checks) as writer: test_file = writer.TEST_FILE if isinstance(test_file, bytes): # file is in the filesystem encoding (needed for launch) but protocol needs it in utf-8 test_file = test_file.decode(file_system_encoding) - test_file = test_file.encode('utf-8') + test_file = test_file.encode("utf-8") json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - map_to_cell_1_line1 = writer.get_line_index_with_content('map to Cell1, line 1') - map_to_cell_1_line2 = writer.get_line_index_with_content('map to Cell1, line 2') - map_to_cell_1_line4 = writer.get_line_index_with_content('map to Cell1, line 4') - map_to_cell_1_line5 = writer.get_line_index_with_content('map to Cell1, line 5') + map_to_cell_1_line1 = writer.get_line_index_with_content("map to Cell1, line 1") + map_to_cell_1_line2 = writer.get_line_index_with_content("map to Cell1, line 2") + map_to_cell_1_line4 = writer.get_line_index_with_content("map to Cell1, line 4") + map_to_cell_1_line5 = writer.get_line_index_with_content("map to Cell1, line 5") - cell1_map = PydevdSourceMap(map_to_cell_1_line1, map_to_cell_1_line5, Source(path=''), 1) + cell1_map = PydevdSourceMap(map_to_cell_1_line1, map_to_cell_1_line5, Source(path=""), 1) pydevd_source_maps = [cell1_map] json_facade.write_set_pydevd_source_map( Source(path=test_file), @@ -3853,43 +3849,45 @@ def additional_output_checks(writer, stdout, stderr): json_hit = json_facade.wait_for_thread_stopped(line=map_to_cell_1_line2, file=os.path.basename(test_file)) for stack_frame in json_hit.stack_trace_response.body.stackFrames: - assert stack_frame['source']['sourceReference'] == 0 + assert stack_frame["source"]["sourceReference"] == 0 goto_targets_request = json_facade.write_request( - pydevd_schema.GotoTargetsRequest(pydevd_schema.GotoTargetsArguments( - source=pydevd_schema.Source(path=writer.TEST_FILE, sourceReference=0), - line=map_to_cell_1_line4))) + pydevd_schema.GotoTargetsRequest( + pydevd_schema.GotoTargetsArguments( + source=pydevd_schema.Source(path=writer.TEST_FILE, sourceReference=0), line=map_to_cell_1_line4 + ) + ) + ) goto_targets_response = json_facade.wait_for_response(goto_targets_request) - target_id = goto_targets_response.body.targets[0]['id'] + target_id = goto_targets_response.body.targets[0]["id"] goto_request = json_facade.write_request( - pydevd_schema.GotoRequest(pydevd_schema.GotoArguments( - threadId=json_hit.thread_id, - targetId=target_id))) + pydevd_schema.GotoRequest(pydevd_schema.GotoArguments(threadId=json_hit.thread_id, targetId=target_id)) + ) goto_response = json_facade.wait_for_response(goto_request) assert goto_response.success - json_hit = json_facade.wait_for_thread_stopped('goto') + json_hit = json_facade.wait_for_thread_stopped("goto") json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not TEST_CHERRYPY or IS_WINDOWS, reason='No CherryPy available / not ok in Windows.') +@pytest.mark.skipif(not TEST_CHERRYPY or IS_WINDOWS, reason="No CherryPy available / not ok in Windows.") def test_process_autoreload_cherrypy(case_setup_multiprocessing_dap, tmpdir): - ''' + """ CherryPy does an os.execv(...) which will kill the running process and replace it with a new process when a reload takes place, so, it mostly works as a new process connection (everything is the same except that the existing process is stopped). - ''' - raise pytest.skip('This is failing with the latest cherrypy -- needs investigation.') + """ + raise pytest.skip("This is failing with the latest cherrypy -- needs investigation.") port = get_free_port() # We write a temp file because we'll change it to autoreload later on. - f = tmpdir.join('_debugger_case_cherrypy.py') + f = tmpdir.join("_debugger_case_cherrypy.py") - tmplt = ''' + tmplt = """ import cherrypy cherrypy.config.update({ 'engine.autoreload.on': True, @@ -3907,37 +3905,37 @@ def exit(self): cherrypy.engine.exit() cherrypy.quickstart(HelloWorld()) -''' +""" - f.write(tmplt % dict(port=port, str='INITIAL')) + f.write(tmplt % dict(port=port, str="INITIAL")) file_to_check = str(f) def get_environ(writer): env = os.environ.copy() - env["PYTHONIOENCODING"] = 'utf-8' + env["PYTHONIOENCODING"] = "utf-8" env["PYTHONPATH"] = str(tmpdir) return env import threading from tests_python.debugger_unittest import AbstractWriterThread - with case_setup_multiprocessing_dap.test_file(file_to_check, get_environ=get_environ) as writer: + with case_setup_multiprocessing_dap.test_file(file_to_check, get_environ=get_environ) as writer: original_ignore_stderr_line = writer._ignore_stderr_line @overrides(writer._ignore_stderr_line) def _ignore_stderr_line(line): if original_ignore_stderr_line(line): return True - return 'ENGINE ' in line or 'CherryPy Checker' in line or 'has an empty config' in line + return "ENGINE " in line or "CherryPy Checker" in line or "has an empty config" in line writer._ignore_stderr_line = _ignore_stderr_line json_facade = JsonFacade(writer) - json_facade.write_launch(debugOptions=['DebugStdLib']) + json_facade.write_launch(debugOptions=["DebugStdLib"]) - break1_line = writer.get_line_index_with_content('break here') + break1_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break1_line) server_socket = writer.server_socket @@ -3946,15 +3944,14 @@ def _ignore_stderr_line(line): secondary_thread_errors = [] class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): try: from tests_python.debugger_unittest import ReaderThread + expected_connections = 1 for _ in range(expected_connections): server_socket.listen(1) @@ -3962,7 +3959,7 @@ def run(self): new_sock, addr = server_socket.accept() reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() writer2 = SecondaryProcessWriterThread() @@ -3974,26 +3971,26 @@ def run(self): writer2.write_add_breakpoint(break1_line) writer2.write_make_initial_run() - secondary_thread_log.append('Initial run') + secondary_thread_log.append("Initial run") # Give it some time to startup time.sleep(2) - t = writer.create_request_thread('http://127.0.0.1:%s/' % (port,)) + t = writer.create_request_thread("http://127.0.0.1:%s/" % (port,)) t.start() - secondary_thread_log.append('Waiting for first breakpoint') + secondary_thread_log.append("Waiting for first breakpoint") hit = writer2.wait_for_breakpoint_hit() - secondary_thread_log.append('Hit first breakpoint') + secondary_thread_log.append("Hit first breakpoint") writer2.write_run_thread(hit.thread_id) contents = t.wait_for_contents() - assert 'Hello World NEW!' in contents + assert "Hello World NEW!" in contents - secondary_thread_log.append('Requesting exit.') - t = writer.create_request_thread('http://127.0.0.1:%s/exit' % (port,)) + secondary_thread_log.append("Requesting exit.") + t = writer.create_request_thread("http://127.0.0.1:%s/exit" % (port,)) t.start() except Exception as e: - secondary_thread_errors.append('Error from secondary thread: %s' % (e,)) + secondary_thread_errors.append("Error from secondary thread: %s" % (e,)) raise secondary_process_thread_communication = SecondaryProcessThreadCommunication() @@ -4003,30 +4000,32 @@ def run(self): # Give it some time to startup time.sleep(2) - t = writer.create_request_thread('http://127.0.0.1:%s/' % (port,)) + t = writer.create_request_thread("http://127.0.0.1:%s/" % (port,)) t.start() json_facade.wait_for_thread_stopped() json_facade.write_continue() contents = t.wait_for_contents() - assert 'Hello World INITIAL!' in contents + assert "Hello World INITIAL!" in contents # Sleep a bit more to make sure that the initial timestamp was gotten in the # CherryPy background thread. time.sleep(2) - f.write(tmplt % dict(port=port, str='NEW')) + f.write(tmplt % dict(port=port, str="NEW")) def check_condition(): return not secondary_process_thread_communication.is_alive() def create_msg(): - return 'Expected secondary thread to finish before timeout.\nSecondary thread log:\n%s\nSecondary thread errors:\n%s\n' % ( - '\n'.join(secondary_thread_log), '\n'.join(secondary_thread_errors)) + return "Expected secondary thread to finish before timeout.\nSecondary thread log:\n%s\nSecondary thread errors:\n%s\n" % ( + "\n".join(secondary_thread_log), + "\n".join(secondary_thread_errors), + ) wait_for_condition(check_condition, msg=create_msg) if secondary_thread_errors: - raise AssertionError('Found errors in secondary thread: %s' % (secondary_thread_errors,)) + raise AssertionError("Found errors in secondary thread: %s" % (secondary_thread_errors,)) writer.finished_ok = True @@ -4034,14 +4033,14 @@ def create_msg(): def test_wait_for_attach_debugpy_mode(case_setup_remote_attach_to_dap): host_port = get_socket_name(close=True) - with case_setup_remote_attach_to_dap.test_file('_debugger_case_wait_for_attach_debugpy_mode.py', host_port[1]) as writer: + with case_setup_remote_attach_to_dap.test_file("_debugger_case_wait_for_attach_debugpy_mode.py", host_port[1]) as writer: time.sleep(1) # Give some time for it to pass the first breakpoint and wait in 'wait_for_attach'. writer.start_socket_client(*host_port) # We don't send initial messages because everything should be pre-configured to # the DAP mode already (i.e.: making sure it works). json_facade = JsonFacade(writer) - break2_line = writer.get_line_index_with_content('Break 2') + break2_line = writer.get_line_index_with_content("Break 2") json_facade.write_attach() # Make sure we also received the initialized in the attach. @@ -4061,39 +4060,39 @@ def test_wait_for_attach(case_setup_remote_attach_to_dap): def check_thread_events(json_facade): json_facade.write_list_threads() # Check that we have the started thread event (whenever we reconnect). - started_events = json_facade.mark_messages(ThreadEvent, lambda x: x.body.reason == 'started') + started_events = json_facade.mark_messages(ThreadEvent, lambda x: x.body.reason == "started") assert len(started_events) == 1 def check_process_event(json_facade, start_method): - if start_method == 'attach': + if start_method == "attach": json_facade.write_attach() - elif start_method == 'launch': + elif start_method == "launch": json_facade.write_launch() else: - raise AssertionError('Unexpected: %s' % (start_method,)) + raise AssertionError("Unexpected: %s" % (start_method,)) process_events = json_facade.mark_messages(ProcessEvent) assert len(process_events) == 1 assert next(iter(process_events)).body.startMethod == start_method - with case_setup_remote_attach_to_dap.test_file('_debugger_case_wait_for_attach.py', host_port[1]) as writer: - writer.TEST_FILE = debugger_unittest._get_debugger_test_file('_debugger_case_wait_for_attach_impl.py') + with case_setup_remote_attach_to_dap.test_file("_debugger_case_wait_for_attach.py", host_port[1]) as writer: + writer.TEST_FILE = debugger_unittest._get_debugger_test_file("_debugger_case_wait_for_attach_impl.py") time.sleep(1) # Give some time for it to pass the first breakpoint and wait in 'wait_for_attach'. writer.start_socket_client(*host_port) json_facade = JsonFacade(writer) check_thread_events(json_facade) - break1_line = writer.get_line_index_with_content('Break 1') - break2_line = writer.get_line_index_with_content('Break 2') - break3_line = writer.get_line_index_with_content('Break 3') + break1_line = writer.get_line_index_with_content("Break 1") + break2_line = writer.get_line_index_with_content("Break 2") + break3_line = writer.get_line_index_with_content("Break 3") - pause1_line = writer.get_line_index_with_content('Pause 1') - pause2_line = writer.get_line_index_with_content('Pause 2') + pause1_line = writer.get_line_index_with_content("Pause 1") + pause2_line = writer.get_line_index_with_content("Pause 2") - check_process_event(json_facade, start_method='launch') + check_process_event(json_facade, start_method="launch") json_facade.write_set_breakpoints([break1_line, break2_line, break3_line]) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped(line=break2_line) @@ -4105,7 +4104,7 @@ def check_process_event(json_facade, start_method): writer.start_socket_client(*host_port) json_facade = JsonFacade(writer) check_thread_events(json_facade) - check_process_event(json_facade, start_method='attach') + check_process_event(json_facade, start_method="attach") json_facade.write_set_breakpoints([break1_line, break2_line, break3_line]) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped(line=break3_line) @@ -4117,50 +4116,52 @@ def check_process_event(json_facade, start_method): writer.start_socket_client(*host_port) json_facade = JsonFacade(writer) check_thread_events(json_facade) - check_process_event(json_facade, start_method='attach') + check_process_event(json_facade, start_method="attach") json_facade.write_make_initial_run() # Connect back without a disconnect (auto-disconnects previous and connects new client). writer.start_socket_client(*host_port) json_facade = JsonFacade(writer) check_thread_events(json_facade) - check_process_event(json_facade, start_method='attach') + check_process_event(json_facade, start_method="attach") json_facade.write_make_initial_run() json_facade.write_pause() - json_hit = json_facade.wait_for_thread_stopped(reason='pause', line=[pause1_line, pause2_line]) + json_hit = json_facade.wait_for_thread_stopped(reason="pause", line=[pause1_line, pause2_line]) # Change value of 'a' for test to finish. - json_facade.write_set_variable(json_hit.frame_id, 'a', '10') + json_facade.write_set_variable(json_hit.frame_id, "a", "10") json_facade.write_disconnect() writer.finished_ok = True -@pytest.mark.skipif(not TEST_GEVENT, reason='Gevent not installed.') +@pytest.mark.skipif(not TEST_GEVENT, reason="Gevent not installed.") def test_wait_for_attach_gevent(case_setup_remote_attach_to_dap): host_port = get_socket_name(close=True) def get_environ(writer): env = os.environ.copy() - env['GEVENT_SUPPORT'] = 'True' + env["GEVENT_SUPPORT"] = "True" return env def check_thread_events(json_facade): json_facade.write_list_threads() # Check that we have the started thread event (whenever we reconnect). - started_events = json_facade.mark_messages(ThreadEvent, lambda x: x.body.reason == 'started') + started_events = json_facade.mark_messages(ThreadEvent, lambda x: x.body.reason == "started") assert len(started_events) == 1 - with case_setup_remote_attach_to_dap.test_file('_debugger_case_gevent.py', host_port[1], additional_args=['remote', 'as-server'], get_environ=get_environ) as writer: - writer.TEST_FILE = debugger_unittest._get_debugger_test_file('_debugger_case_gevent.py') - time.sleep(.5) # Give some time for it to pass the first breakpoint and wait. + with case_setup_remote_attach_to_dap.test_file( + "_debugger_case_gevent.py", host_port[1], additional_args=["remote", "as-server"], get_environ=get_environ + ) as writer: + writer.TEST_FILE = debugger_unittest._get_debugger_test_file("_debugger_case_gevent.py") + time.sleep(0.5) # Give some time for it to pass the first breakpoint and wait. writer.start_socket_client(*host_port) json_facade = JsonFacade(writer) check_thread_events(json_facade) - break1_line = writer.get_line_index_with_content('break here') + break1_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break1_line) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped(line=break1_line) @@ -4169,23 +4170,22 @@ def check_thread_events(json_facade): writer.finished_ok = True -@pytest.mark.skipif(not TEST_GEVENT, reason='Gevent not installed.') -@pytest.mark.parametrize('show', [True, False]) +@pytest.mark.skipif(not TEST_GEVENT, reason="Gevent not installed.") +@pytest.mark.parametrize("show", [True, False]) def test_gevent_show_paused_greenlets(case_setup_dap, show): - def get_environ(writer): env = os.environ.copy() - env['GEVENT_SUPPORT'] = 'True' + env["GEVENT_SUPPORT"] = "True" if show: - env['GEVENT_SHOW_PAUSED_GREENLETS'] = 'True' + env["GEVENT_SHOW_PAUSED_GREENLETS"] = "True" else: - env['GEVENT_SHOW_PAUSED_GREENLETS'] = 'False' + env["GEVENT_SHOW_PAUSED_GREENLETS"] = "False" return env - with case_setup_dap.test_file('_debugger_case_gevent_simple.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_gevent_simple.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) - break1_line = writer.get_line_index_with_content('break here') + break1_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break1_line) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped(line=break1_line) @@ -4194,19 +4194,18 @@ def get_environ(writer): if show: assert len(response.body.threads) > 1 - thread_name_to_id = dict((t['name'], t['id']) for t in response.body.threads) - assert set(thread_name_to_id.keys()) == set(( - 'MainThread', - 'greenlet: - _debugger_case_gevent_simple.py', - 'Greenlet: foo - _debugger_case_gevent_simple.py', - 'Hub: run - hub.py' - )) + thread_name_to_id = dict((t["name"], t["id"]) for t in response.body.threads) + assert set(thread_name_to_id.keys()) == set( + ( + "MainThread", + "greenlet: - _debugger_case_gevent_simple.py", + "Greenlet: foo - _debugger_case_gevent_simple.py", + "Hub: run - hub.py", + ) + ) for tname, tid in thread_name_to_id.items(): - stack = json_facade.get_stack_as_json_hit( - tid, - no_stack_frame=tname == 'Hub: run - hub.py' - ) + stack = json_facade.get_stack_as_json_hit(tid, no_stack_frame=tname == "Hub: run - hub.py") assert stack else: @@ -4216,17 +4215,16 @@ def get_environ(writer): writer.finished_ok = True -@pytest.mark.skipif(not TEST_GEVENT, reason='Gevent not installed.') -@pytest.mark.skipif(sys.platform == 'win32', reason='tput requires Linux.') +@pytest.mark.skipif(not TEST_GEVENT, reason="Gevent not installed.") +@pytest.mark.skipif(sys.platform == "win32", reason="tput requires Linux.") def test_gevent_subprocess_not_python(case_setup_dap): - def get_environ(writer): env = os.environ.copy() - env['GEVENT_SUPPORT'] = 'True' - env['CALL_PYTHON_SUB'] = '0' + env["GEVENT_SUPPORT"] = "True" + env["CALL_PYTHON_SUB"] = "0" return env - with case_setup_dap.test_file('_debugger_case_gevent_subprocess.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_gevent_subprocess.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) break1_line = writer.get_line_index_with_content("print('TEST SUCEEDED')") @@ -4238,21 +4236,21 @@ def get_environ(writer): writer.finished_ok = True -@pytest.mark.skipif(not TEST_GEVENT, reason='Gevent not installed.') +@pytest.mark.skipif(not TEST_GEVENT, reason="Gevent not installed.") def test_gevent_subprocess_python(case_setup_multiprocessing_dap): import threading from tests_python.debugger_unittest import AbstractWriterThread def get_environ(writer): env = os.environ.copy() - env['GEVENT_SUPPORT'] = 'True' - env['CALL_PYTHON_SUB'] = '1' + env["GEVENT_SUPPORT"] = "True" + env["CALL_PYTHON_SUB"] = "1" return env with case_setup_multiprocessing_dap.test_file( - '_debugger_case_gevent_subprocess.py', - get_environ=get_environ, - ) as writer: + "_debugger_case_gevent_subprocess.py", + get_environ=get_environ, + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() @@ -4263,20 +4261,19 @@ def get_environ(writer): secondary_finished_ok = [False] class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread + server_socket.listen(1) self.server_socket = server_socket new_sock, addr = server_socket.accept() reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() writer2 = SecondaryProcessWriterThread() @@ -4284,7 +4281,11 @@ def run(self): writer2.sock = new_sock json_facade2 = JsonFacade(writer2) - json_facade2.write_set_breakpoints([break1_line, ]) + json_facade2.write_set_breakpoints( + [ + break1_line, + ] + ) json_facade2.write_make_initial_run() json_facade2.wait_for_thread_stopped() @@ -4293,12 +4294,12 @@ def run(self): secondary_process_thread_communication = SecondaryProcessThreadCommunication() secondary_process_thread_communication.start() - time.sleep(.1) + time.sleep(0.1) json_facade.write_make_initial_run() secondary_process_thread_communication.join(10) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") assert secondary_finished_ok[0] writer.finished_ok = True @@ -4306,65 +4307,65 @@ def run(self): @pytest.mark.skipif( not TEST_GEVENT or IS_WINDOWS, - reason='Gevent not installed / Sometimes the debugger crashes on Windows as the compiled extensions conflict with gevent.' + reason="Gevent not installed / Sometimes the debugger crashes on Windows as the compiled extensions conflict with gevent.", ) def test_notify_gevent(case_setup_dap, pyfile): - def get_environ(writer): # I.e.: Make sure that gevent support is disabled env = os.environ.copy() - env['GEVENT_SUPPORT'] = '' + env["GEVENT_SUPPORT"] = "" return env @pyfile def case_gevent(): from gevent import monkey import os + monkey.patch_all() - print('TEST SUCEEDED') # Break here + print("TEST SUCEEDED") # Break here os._exit(0) def additional_output_checks(writer, stdout, stderr): - assert 'environment variable' in stderr - assert 'GEVENT_SUPPORT=True' in stderr + assert "environment variable" in stderr + assert "GEVENT_SUPPORT=True" in stderr with case_setup_dap.test_file( - case_gevent, - get_environ=get_environ, - additional_output_checks=additional_output_checks, - EXPECTED_RETURNCODE='any', - FORCE_KILL_PROCESS_WHEN_FINISHED_OK=True - ) as writer: + case_gevent, + get_environ=get_environ, + additional_output_checks=additional_output_checks, + EXPECTED_RETURNCODE="any", + FORCE_KILL_PROCESS_WHEN_FINISHED_OK=True, + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped() json_facade.write_continue(wait_for_response=False) - wait_for_condition(lambda: 'GEVENT_SUPPORT=True' in writer.get_stderr()) + wait_for_condition(lambda: "GEVENT_SUPPORT=True" in writer.get_stderr()) writer.finished_ok = True def test_ppid(case_setup_dap, pyfile): - @pyfile def case_ppid(): from pydevd import get_global_debugger + assert get_global_debugger().get_arg_ppid() == 22 - print('TEST SUCEEDED') + print("TEST SUCEEDED") def update_command_line_args(writer, args): ret = debugger_unittest.AbstractWriterThread.update_command_line_args(writer, args) - ret.insert(ret.index('--client'), '--ppid') - ret.insert(ret.index('--client'), '22') + ret.insert(ret.index("--client"), "--ppid") + ret.insert(ret.index("--client"), "22") return ret with case_setup_dap.test_file( - case_ppid, - update_command_line_args=update_command_line_args, - ) as writer: + case_ppid, + update_command_line_args=update_command_line_args, + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() json_facade.write_make_initial_run() @@ -4372,37 +4373,40 @@ def update_command_line_args(writer, args): writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Flaky on Jython.') +@pytest.mark.skipif(IS_JYTHON, reason="Flaky on Jython.") def test_path_translation_and_source_reference(case_setup_dap): - - translated_dir_not_ascii = u'áéíóú汉字' + translated_dir_not_ascii = "áéíóú汉字" def get_file_in_client(writer): # Instead of using: test_python/_debugger_case_path_translation.py # we'll set the breakpoints at foo/_debugger_case_path_translation.py file_in_client = os.path.dirname(os.path.dirname(writer.TEST_FILE)) - return os.path.join(os.path.dirname(file_in_client), translated_dir_not_ascii, '_debugger_case_path_translation.py') + return os.path.join(os.path.dirname(file_in_client), translated_dir_not_ascii, "_debugger_case_path_translation.py") def get_environ(writer): env = os.environ.copy() - env["PYTHONIOENCODING"] = 'utf-8' + env["PYTHONIOENCODING"] = "utf-8" return env - with case_setup_dap.test_file('_debugger_case_path_translation.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_path_translation.py", get_environ=get_environ) as writer: file_in_client = get_file_in_client(writer) - assert 'tests_python' not in file_in_client + assert "tests_python" not in file_in_client assert translated_dir_not_ascii in file_in_client json_facade = JsonFacade(writer) - bp_line = writer.get_line_index_with_content('break here') - assert writer.TEST_FILE.endswith('_debugger_case_path_translation.py') + bp_line = writer.get_line_index_with_content("break here") + assert writer.TEST_FILE.endswith("_debugger_case_path_translation.py") local_root = os.path.dirname(get_file_in_client(writer)) - json_facade.write_launch(pathMappings=[{ - 'localRoot': local_root, - 'remoteRoot': os.path.dirname(writer.TEST_FILE), - }]) + json_facade.write_launch( + pathMappings=[ + { + "localRoot": local_root, + "remoteRoot": os.path.dirname(writer.TEST_FILE), + } + ] + ) json_facade.write_set_breakpoints(bp_line, filename=file_in_client) json_facade.write_make_initial_run() @@ -4414,29 +4418,28 @@ def get_environ(writer): # Check stack trace format. stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments( - threadId=json_hit.thread_id, - format={'module': True, 'line': True} - ))) + pydevd_schema.StackTraceRequest( + pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id, format={"module": True, "line": True}) + ) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_trace_response_body = stack_trace_response.body stack_frame = stack_trace_response_body.stackFrames[0] - assert stack_frame['name'] == '__main__.call_this : %s' % (bp_line,) + assert stack_frame["name"] == "__main__.call_this : %s" % (bp_line,) - path = stack_frame['source']['path'] + path = stack_frame["source"]["path"] file_in_client_unicode = file_in_client assert path == file_in_client_unicode - source_reference = stack_frame['source']['sourceReference'] + source_reference = stack_frame["source"]["sourceReference"] assert source_reference == 0 # When it's translated the source reference must be == 0 stack_frame_not_path_translated = stack_trace_response_body.stackFrames[1] - if not stack_frame_not_path_translated['name'].startswith( - 'tests_python.resource_path_translation.other.call_me_back1 :'): - raise AssertionError('Error. Found: >>%s<<.' % (stack_frame_not_path_translated['name'],)) + if not stack_frame_not_path_translated["name"].startswith("tests_python.resource_path_translation.other.call_me_back1 :"): + raise AssertionError("Error. Found: >>%s<<." % (stack_frame_not_path_translated["name"],)) - assert stack_frame_not_path_translated['source']['path'].endswith('other.py') - source_reference = stack_frame_not_path_translated['source']['sourceReference'] + assert stack_frame_not_path_translated["source"]["path"].endswith("other.py") + source_reference = stack_frame_not_path_translated["source"]["sourceReference"] assert source_reference != 0 # Not translated response = json_facade.write_get_source(source_reference) @@ -4447,35 +4450,37 @@ def get_environ(writer): writer.finished_ok = True -@pytest.mark.skipif(IS_JYTHON, reason='Flaky on Jython.') +@pytest.mark.skipif(IS_JYTHON, reason="Flaky on Jython.") def test_source_reference_no_file(case_setup_dap, tmpdir): - - with case_setup_dap.test_file('_debugger_case_source_reference.py') as writer: + with case_setup_dap.test_file("_debugger_case_source_reference.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch( - debugOptions=['DebugStdLib'], - pathMappings=[{ - 'localRoot': os.path.dirname(writer.TEST_FILE), - 'remoteRoot': os.path.dirname(writer.TEST_FILE), - }]) + debugOptions=["DebugStdLib"], + pathMappings=[ + { + "localRoot": os.path.dirname(writer.TEST_FILE), + "remoteRoot": os.path.dirname(writer.TEST_FILE), + } + ], + ) - writer.write_add_breakpoint(writer.get_line_index_with_content('breakpoint')) + writer.write_add_breakpoint(writer.get_line_index_with_content("breakpoint")) json_facade.write_make_initial_run() # First hit is for breakpoint reached via a stack frame that doesn't have source. json_hit = json_facade.wait_for_thread_stopped() stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments( - threadId=json_hit.thread_id, - format={'module': True, 'line': True} - ))) + pydevd_schema.StackTraceRequest( + pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id, format={"module": True, "line": True}) + ) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_trace_response_body = stack_trace_response.body stack_frame = stack_trace_response_body.stackFrames[1] - assert stack_frame['source']['path'] == '' - source_reference = stack_frame['source']['sourceReference'] + assert stack_frame["source"]["path"] == "" + source_reference = stack_frame["source"]["sourceReference"] assert source_reference != 0 json_facade.write_get_source(source_reference, success=False) @@ -4487,57 +4492,55 @@ def test_source_reference_no_file(case_setup_dap, tmpdir): json_hit = json_facade.wait_for_thread_stopped() stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments( - threadId=json_hit.thread_id, - format={'module': True, 'line': True} - ))) + pydevd_schema.StackTraceRequest( + pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id, format={"module": True, "line": True}) + ) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_trace_response_body = stack_trace_response.body stack_frame = stack_trace_response_body.stackFrames[1] - print(stack_frame['source']['path']) - assert stack_frame['source']['path'] == '' - source_reference = stack_frame['source']['sourceReference'] + print(stack_frame["source"]["path"]) + assert stack_frame["source"]["path"] == "" + source_reference = stack_frame["source"]["sourceReference"] assert source_reference != 0 response = json_facade.write_get_source(source_reference) - assert response.body.content == 'foo()\n' + assert response.body.content == "foo()\n" json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='CPython only test.') +@pytest.mark.skipif(not IS_CPYTHON, reason="CPython only test.") def test_linecache_json_existing_file(case_setup_dap, tmpdir): - - with case_setup_dap.test_file('_debugger_case_linecache_existing_file.py') as writer: + with case_setup_dap.test_file("_debugger_case_linecache_existing_file.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - debugger_case_stepping_filename = debugger_unittest._get_debugger_test_file('_debugger_case_stepping.py') - bp_line = writer.get_line_index_with_content('Break here 1', filename=debugger_case_stepping_filename) + debugger_case_stepping_filename = debugger_unittest._get_debugger_test_file("_debugger_case_stepping.py") + bp_line = writer.get_line_index_with_content("Break here 1", filename=debugger_case_stepping_filename) json_facade.write_set_breakpoints(bp_line, filename=debugger_case_stepping_filename) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() stack_trace_response_body = json_hit.stack_trace_response.body for stack_frame in stack_trace_response_body.stackFrames: - source_reference = stack_frame['source']['sourceReference'] + source_reference = stack_frame["source"]["sourceReference"] assert source_reference == 0 json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='CPython only test.') +@pytest.mark.skipif(not IS_CPYTHON, reason="CPython only test.") def test_linecache_json(case_setup_dap, tmpdir): - - with case_setup_dap.test_file('_debugger_case_linecache.py') as writer: + with case_setup_dap.test_file("_debugger_case_linecache.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - writer.write_add_breakpoint(writer.get_line_index_with_content('breakpoint')) + writer.write_add_breakpoint(writer.get_line_index_with_content("breakpoint")) json_facade.write_make_initial_run() # First hit is for breakpoint reached via a stack frame that doesn't have source. @@ -4546,8 +4549,8 @@ def test_linecache_json(case_setup_dap, tmpdir): stack_trace_response_body = json_hit.stack_trace_response.body source_references = [] for stack_frame in stack_trace_response_body.stackFrames: - if stack_frame['source']['path'] == '': - source_reference = stack_frame['source']['sourceReference'] + if stack_frame["source"]["path"] == "": + source_reference = stack_frame["source"]["sourceReference"] assert source_reference != 0 source_references.append(source_reference) @@ -4556,23 +4559,22 @@ def test_linecache_json(case_setup_dap, tmpdir): for source_reference in source_references: response = json_facade.write_get_source(source_reference) - assert 'def somemethod():' in response.body.content - assert ' foo()' in response.body.content - assert '[x for x in range(10)]' in response.body.content + assert "def somemethod():" in response.body.content + assert " foo()" in response.body.content + assert "[x for x in range(10)]" in response.body.content json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not IS_CPYTHON, reason='CPython only test.') +@pytest.mark.skipif(not IS_CPYTHON, reason="CPython only test.") def test_show_bytecode_json(case_setup_dap, tmpdir): - - with case_setup_dap.test_file('_debugger_case_show_bytecode.py') as writer: + with case_setup_dap.test_file("_debugger_case_show_bytecode.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - writer.write_add_breakpoint(writer.get_line_index_with_content('breakpoint')) + writer.write_add_breakpoint(writer.get_line_index_with_content("breakpoint")) json_facade.write_make_initial_run() # First hit is for breakpoint reached via a stack frame that doesn't have source. @@ -4581,8 +4583,8 @@ def test_show_bytecode_json(case_setup_dap, tmpdir): stack_trace_response_body = json_hit.stack_trace_response.body source_references = [] for stack_frame in stack_trace_response_body.stackFrames: - if stack_frame['source']['path'] == '': - source_reference = stack_frame['source']['sourceReference'] + if stack_frame["source"]["path"] == "": + source_reference = stack_frame["source"]["sourceReference"] assert source_reference != 0 source_references.append(source_reference) @@ -4591,92 +4593,121 @@ def test_show_bytecode_json(case_setup_dap, tmpdir): for source_reference in source_references: response = json_facade.write_get_source(source_reference) - assert 'MyClass' in response.body.content or 'foo()' in response.body.content + assert "MyClass" in response.body.content or "foo()" in response.body.content json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not TEST_DJANGO, reason='No django available') +@pytest.mark.skipif(not TEST_DJANGO, reason="No django available") @pytest.mark.parametrize("jmc", [False, True]) def test_case_django_no_attribute_exception_breakpoint(case_setup_django_dap, jmc): import django # noqa (may not be there if TEST_DJANGO == False) - django_version = [int(x) for x in django.get_version().split('.')][:2] + + django_version = [int(x) for x in django.get_version().split(".")][:2] if django_version < [2, 1]: - pytest.skip('Template exceptions only supporting Django 2.1 onwards.') + pytest.skip("Template exceptions only supporting Django 2.1 onwards.") - with case_setup_django_dap.test_file(EXPECTED_RETURNCODE='any') as writer: + with case_setup_django_dap.test_file(EXPECTED_RETURNCODE="any") as writer: json_facade = JsonFacade(writer) if jmc: - writer.write_set_project_roots([debugger_unittest._get_debugger_test_file('my_code')]) - json_facade.write_launch(debugOptions=['Django'], variablePresentation={ - "all": "hide", - "protected": "inline", - }) - json_facade.write_set_exception_breakpoints(['raised']) + writer.write_set_project_roots([debugger_unittest._get_debugger_test_file("my_code")]) + json_facade.write_launch( + debugOptions=["Django"], + variablePresentation={ + "all": "hide", + "protected": "inline", + }, + ) + json_facade.write_set_exception_breakpoints(["raised"]) else: - json_facade.write_launch(debugOptions=['DebugStdLib', 'Django'], variablePresentation={ - "all": "hide", - "protected": "inline", - }) + json_facade.write_launch( + debugOptions=["DebugStdLib", "Django"], + variablePresentation={ + "all": "hide", + "protected": "inline", + }, + ) # Don't set to all 'raised' because we'd stop on standard library exceptions here # (which is not something we want). - json_facade.write_set_exception_breakpoints(exception_options=[ - ExceptionOptions(breakMode='always', path=[ - {'names': ['Python Exceptions']}, - {'names': ['AssertionError']}, - ]) - ]) + json_facade.write_set_exception_breakpoints( + exception_options=[ + ExceptionOptions( + breakMode="always", + path=[ + {"names": ["Python Exceptions"]}, + {"names": ["AssertionError"]}, + ], + ) + ] + ) writer.write_make_initial_run() - t = writer.create_request_thread('my_app/template_error') + t = writer.create_request_thread("my_app/template_error") time.sleep(5) # Give django some time to get to startup before requesting the page t.start() - json_hit = json_facade.wait_for_thread_stopped('exception', line=7, file='template_error.html') + json_hit = json_facade.wait_for_thread_stopped("exception", line=7, file="template_error.html") stack_trace_request = json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments( - threadId=json_hit.thread_id, - format={'module': True, 'line': True} - ))) + pydevd_schema.StackTraceRequest( + pydevd_schema.StackTraceArguments(threadId=json_hit.thread_id, format={"module": True, "line": True}) + ) + ) stack_trace_response = json_facade.wait_for_response(stack_trace_request) stack_trace_response_body = stack_trace_response.body stack_frame = next(iter(stack_trace_response_body.stackFrames)) - assert stack_frame['source']['path'].endswith('template_error.html') + assert stack_frame["source"]["path"].endswith("template_error.html") json_hit = json_facade.get_stack_as_json_hit(json_hit.thread_id) variables_response = json_facade.get_variables_response(json_hit.frame_id) - entries = [x for x in variables_response.to_dict()['body']['variables'] if x['name'] == 'entry'] + entries = [x for x in variables_response.to_dict()["body"]["variables"] if x["name"] == "entry"] assert len(entries) == 1 - variables_response = json_facade.get_variables_response(entries[0]['variablesReference']) - assert variables_response.to_dict()['body']['variables'] == [ - {'name': 'key', 'value': "'v1'", 'type': 'str', 'evaluateName': 'entry.key', 'presentationHint': {'attributes': ['rawString']}, 'variablesReference': 0}, - {'name': 'val', 'value': "'v1'", 'type': 'str', 'evaluateName': 'entry.val', 'presentationHint': {'attributes': ['rawString']}, 'variablesReference': 0} + variables_response = json_facade.get_variables_response(entries[0]["variablesReference"]) + assert variables_response.to_dict()["body"]["variables"] == [ + { + "name": "key", + "value": "'v1'", + "type": "str", + "evaluateName": "entry.key", + "presentationHint": {"attributes": ["rawString"]}, + "variablesReference": 0, + }, + { + "name": "val", + "value": "'v1'", + "type": "str", + "evaluateName": "entry.val", + "presentationHint": {"attributes": ["rawString"]}, + "variablesReference": 0, + }, ] json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not TEST_DJANGO, reason='No django available') +@pytest.mark.skipif(not TEST_DJANGO, reason="No django available") def test_case_django_line_validation(case_setup_django_dap): import django # noqa (may not be there if TEST_DJANGO == False) - django_version = [int(x) for x in django.get_version().split('.')][:2] + + django_version = [int(x) for x in django.get_version().split(".")][:2] support_lazy_line_validation = django_version >= [1, 9] import django # noqa (may not be there if TEST_DJANGO == False) - with case_setup_django_dap.test_file(EXPECTED_RETURNCODE='any') as writer: + with case_setup_django_dap.test_file(EXPECTED_RETURNCODE="any") as writer: json_facade = JsonFacade(writer) - json_facade.write_launch(debugOptions=['DebugStdLib', 'Django']) - template_file = debugger_unittest._get_debugger_test_file(os.path.join(writer.DJANGO_FOLDER, 'my_app', 'templates', 'my_app', 'index.html')) - file_doesnt_exist = os.path.join(os.path.dirname(template_file), 'this_does_not_exist.html') + json_facade.write_launch(debugOptions=["DebugStdLib", "Django"]) + template_file = debugger_unittest._get_debugger_test_file( + os.path.join(writer.DJANGO_FOLDER, "my_app", "templates", "my_app", "index.html") + ) + file_doesnt_exist = os.path.join(os.path.dirname(template_file), "this_does_not_exist.html") # At this point, breakpoints will still not be verified (that'll happen when we # actually load the template). @@ -4687,7 +4718,7 @@ def test_case_django_line_validation(case_setup_django_dap): writer.write_make_initial_run() - t = writer.create_request_thread('my_app') + t = writer.create_request_thread("my_app") time.sleep(5) # Give django some time to get to startup before requesting the page t.start() @@ -4716,12 +4747,14 @@ def test_case_django_line_validation(case_setup_django_dap): # know about the template validation. if support_lazy_line_validation: json_facade.write_set_breakpoints( - [1, 2, 8], template_file, expected_lines_in_response=set((1, 2, 7)), + [1, 2, 8], + template_file, + expected_lines_in_response=set((1, 2, 7)), # i.e.: breakpoint id to whether it's verified. - verified={3: True, 4: False, 5: True}) + verified={3: True, 4: False, 5: True}, + ) else: - json_facade.write_set_breakpoints( - [1, 2, 7], template_file, verified=True) + json_facade.write_set_breakpoints([1, 2, 7], template_file, verified=True) json_facade.write_continue() json_facade.wait_for_thread_stopped(line=7) @@ -4732,21 +4765,21 @@ def test_case_django_line_validation(case_setup_django_dap): # To finish, check that setting on a file that doesn't exist is not verified. response = json_facade.write_set_breakpoints([1], file_doesnt_exist, verified=False) for bp in response.body.breakpoints: - assert 'Breakpoint in file that does not exist' in bp['message'] + assert "Breakpoint in file that does not exist" in bp["message"] json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not TEST_FLASK, reason='No flask available') +@pytest.mark.skipif(not TEST_FLASK, reason="No flask available") def test_case_flask_line_validation(case_setup_flask_dap): - with case_setup_flask_dap.test_file(EXPECTED_RETURNCODE='any') as writer: + with case_setup_flask_dap.test_file(EXPECTED_RETURNCODE="any") as writer: json_facade = JsonFacade(writer) - writer.write_set_project_roots([debugger_unittest._get_debugger_test_file('flask1')]) - json_facade.write_launch(debugOptions=['Jinja']) + writer.write_set_project_roots([debugger_unittest._get_debugger_test_file("flask1")]) + json_facade.write_launch(debugOptions=["Jinja"]) json_facade.write_make_initial_run() - template_file = debugger_unittest._get_debugger_test_file(os.path.join('flask1', 'templates', 'hello.html')) + template_file = debugger_unittest._get_debugger_test_file(os.path.join("flask1", "templates", "hello.html")) # At this point, breakpoints will still not be verified (that'll happen when we # actually load the template). @@ -4785,62 +4818,66 @@ def test_case_flask_line_validation(case_setup_flask_dap): writer.finished_ok = True -@pytest.mark.skipif(not TEST_FLASK, reason='No flask available') +@pytest.mark.skipif(not TEST_FLASK, reason="No flask available") @pytest.mark.parametrize("jmc", [False, True]) def test_case_flask_exceptions(case_setup_flask_dap, jmc): - with case_setup_flask_dap.test_file(EXPECTED_RETURNCODE='any') as writer: + with case_setup_flask_dap.test_file(EXPECTED_RETURNCODE="any") as writer: json_facade = JsonFacade(writer) if jmc: ignore_py_exceptions = False - writer.write_set_project_roots([debugger_unittest._get_debugger_test_file('my_code')]) - json_facade.write_launch(debugOptions=['Jinja']) - json_facade.write_set_exception_breakpoints(['raised']) + writer.write_set_project_roots([debugger_unittest._get_debugger_test_file("my_code")]) + json_facade.write_launch(debugOptions=["Jinja"]) + json_facade.write_set_exception_breakpoints(["raised"]) else: ignore_py_exceptions = True - json_facade.write_launch(debugOptions=['DebugStdLib', 'Jinja']) + json_facade.write_launch(debugOptions=["DebugStdLib", "Jinja"]) # Don't set to all 'raised' because we'd stop on standard library exceptions here # (which is not something we want). - json_facade.write_set_exception_breakpoints(exception_options=[ - ExceptionOptions(breakMode='always', path=[ - {'names': ['Python Exceptions']}, - {'names': ['IndexError']}, - ]) - ]) + json_facade.write_set_exception_breakpoints( + exception_options=[ + ExceptionOptions( + breakMode="always", + path=[ + {"names": ["Python Exceptions"]}, + {"names": ["IndexError"]}, + ], + ) + ] + ) json_facade.write_make_initial_run() - t = writer.create_request_thread('/bad_template') + t = writer.create_request_thread("/bad_template") time.sleep(2) # Give flask some time to get to startup before requesting the page t.start() while True: - json_hit = json_facade.wait_for_thread_stopped('exception') - path = json_hit.stack_trace_response.body.stackFrames[0]['source']['path'] - found_line = json_hit.stack_trace_response.body.stackFrames[0]['line'] - if path.endswith('bad.html'): + json_hit = json_facade.wait_for_thread_stopped("exception") + path = json_hit.stack_trace_response.body.stackFrames[0]["source"]["path"] + found_line = json_hit.stack_trace_response.body.stackFrames[0]["line"] + if path.endswith("bad.html"): assert found_line == 8 json_facade.write_continue() break - if ignore_py_exceptions and path.endswith('.py'): + if ignore_py_exceptions and path.endswith(".py"): json_facade.write_continue() continue - raise AssertionError('Unexpected thread stop: at %s, %s' % (path, found_line)) + raise AssertionError("Unexpected thread stop: at %s, %s" % (path, found_line)) writer.finished_ok = True -@pytest.mark.skipif(IS_APPVEYOR or IS_JYTHON, reason='Flaky on appveyor / Jython encoding issues (needs investigation).') +@pytest.mark.skipif(IS_APPVEYOR or IS_JYTHON, reason="Flaky on appveyor / Jython encoding issues (needs investigation).") def test_redirect_output(case_setup_dap): - def get_environ(writer): env = os.environ.copy() - env["PYTHONIOENCODING"] = 'utf-8' + env["PYTHONIOENCODING"] = "utf-8" return env - with case_setup_dap.test_file('_debugger_case_redirect.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_redirect.py", get_environ=get_environ) as writer: original_ignore_stderr_line = writer._ignore_stderr_line json_facade = JsonFacade(writer) @@ -4850,16 +4887,18 @@ def _ignore_stderr_line(line): if original_ignore_stderr_line(line): return True - binary_junk = b'\xe8\xF0\x80\x80\x80' + binary_junk = b"\xe8\xF0\x80\x80\x80" if sys.version_info[0] >= 3: - binary_junk = binary_junk.decode('utf-8', 'replace') - - return line.startswith(( - 'text', - 'binary', - 'a', - binary_junk, - )) + binary_junk = binary_junk.decode("utf-8", "replace") + + return line.startswith( + ( + "text", + "binary", + "a", + binary_junk, + ) + ) writer._ignore_stderr_line = _ignore_stderr_line @@ -4867,25 +4906,27 @@ def _ignore_stderr_line(line): # must always be consistent and there's a message for each write). expected = [ - 'text\n', - 'binary or text\n', - 'ação1\n', + "text\n", + "binary or text\n", + "ação1\n", ] if sys.version_info[0] >= 3: - expected.extend(( - 'binary\n', - 'ação2\n'.encode(encoding='latin1').decode('utf-8', 'replace'), - 'ação3\n', - )) + expected.extend( + ( + "binary\n", + "ação2\n".encode(encoding="latin1").decode("utf-8", "replace"), + "ação3\n", + ) + ) - binary_junk = '\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\n\n' + binary_junk = "\xef\xbf\xbd\xef\xbf\xbd\xef\xbf\xbd\n\n" if sys.version_info[0] >= 3: binary_junk = "\ufffd\ufffd\ufffd\ufffd\ufffd\n\n" expected.append(binary_junk) - new_expected = [(x, 'stdout') for x in expected] - new_expected.extend([(x, 'stderr') for x in expected]) + new_expected = [(x, "stdout") for x in expected] + new_expected.extend([(x, "stderr") for x in expected]) writer.write_start_redirect() @@ -4900,11 +4941,11 @@ def _ignore_stderr_line(line): msg = (output, category) except Exception: for msg in msgs: - sys.stderr.write('Found: %s\n' % (msg,)) + sys.stderr.write("Found: %s\n" % (msg,)) for msg in new_expected: - sys.stderr.write('Expected: %s\n' % (msg,)) + sys.stderr.write("Expected: %s\n" % (msg,)) for msg in ignored: - sys.stderr.write('Ignored: %s\n' % (msg,)) + sys.stderr.write("Ignored: %s\n" % (msg,)) raise if msg not in new_expected: ignored.append(msg) @@ -4919,12 +4960,13 @@ def _ignore_stderr_line(line): def test_listen_dap_messages(case_setup_dap): - - with case_setup_dap.test_file('_debugger_case_listen_dap_messages.py') as writer: + with case_setup_dap.test_file("_debugger_case_listen_dap_messages.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_launch(debugOptions=['RedirectOutput'],) + json_facade.write_launch( + debugOptions=["RedirectOutput"], + ) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped() @@ -4941,26 +4983,39 @@ def _attach_to_writer_pid(writer): assert writer.process is not None def attach(): - attach_pydevd_file = os.path.join(os.path.dirname(pydevd.__file__), 'pydevd_attach_to_process', 'attach_pydevd.py') - subprocess.call([sys.executable, attach_pydevd_file, '--pid', str(writer.process.pid), '--port', str(writer.port), '--protocol', 'http_json', '--debug-mode', 'debugpy-dap']) + attach_pydevd_file = os.path.join(os.path.dirname(pydevd.__file__), "pydevd_attach_to_process", "attach_pydevd.py") + subprocess.call( + [ + sys.executable, + attach_pydevd_file, + "--pid", + str(writer.process.pid), + "--port", + str(writer.port), + "--protocol", + "http_json", + "--debug-mode", + "debugpy-dap", + ] + ) threading.Thread(target=attach).start() wait_for_condition(lambda: writer.finished_initialization) -@pytest.mark.parametrize('reattach', [True, False]) -@pytest.mark.skipif(not IS_CPYTHON or IS_MAC, reason='Attach to pid only available in CPython (brittle on Mac).') -@pytest.mark.skipif(not SUPPORT_ATTACH_TO_PID, reason='Attach to pid not supported.') +@pytest.mark.parametrize("reattach", [True, False]) +@pytest.mark.skipif(not IS_CPYTHON or IS_MAC, reason="Attach to pid only available in CPython (brittle on Mac).") +@pytest.mark.skipif(not SUPPORT_ATTACH_TO_PID, reason="Attach to pid not supported.") def test_attach_to_pid(case_setup_remote, reattach): import threading - with case_setup_remote.test_file('_debugger_case_attach_to_pid_simple.py', wait_for_port=False) as writer: + with case_setup_remote.test_file("_debugger_case_attach_to_pid_simple.py", wait_for_port=False) as writer: time.sleep(1) # Give it some time to initialize to get to the while loop. _attach_to_writer_pid(writer) json_facade = JsonFacade(writer) - bp_line = writer.get_line_index_with_content('break here') + bp_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(bp_line) json_facade.write_make_initial_run() @@ -4977,11 +5032,11 @@ def test_attach_to_pid(case_setup_remote, reattach): t = threading.Thread(target=writer.start_socket) t.start() - wait_for_condition(lambda: hasattr(writer, 'port')) + wait_for_condition(lambda: hasattr(writer, "port")) time.sleep(1) writer.process = writer.process _attach_to_writer_pid(writer) - wait_for_condition(lambda: hasattr(writer, 'reader_thread')) + wait_for_condition(lambda: hasattr(writer, "reader_thread")) time.sleep(1) json_facade = JsonFacade(writer) @@ -4990,7 +5045,7 @@ def test_attach_to_pid(case_setup_remote, reattach): json_hit = json_facade.wait_for_thread_stopped(line=bp_line) - json_facade.write_set_variable(json_hit.frame_id, 'wait', '0') + json_facade.write_set_variable(json_hit.frame_id, "wait", "0") json_facade.write_continue() @@ -4998,7 +5053,7 @@ def test_attach_to_pid(case_setup_remote, reattach): def test_remote_debugger_basic(case_setup_remote_dap): - with case_setup_remote_dap.test_file('_debugger_case_remote.py') as writer: + with case_setup_remote_dap.test_file("_debugger_case_remote.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() json_facade.write_make_initial_run() @@ -5008,55 +5063,54 @@ def test_remote_debugger_basic(case_setup_remote_dap): writer.finished_ok = True -PYDEVD_CUSTOMIZATION_COMMAND_LINE_ARGS = ['', '--use-c-switch'] -if hasattr(os, 'posix_spawn'): - PYDEVD_CUSTOMIZATION_COMMAND_LINE_ARGS.append('--posix-spawn') +PYDEVD_CUSTOMIZATION_COMMAND_LINE_ARGS = ["", "--use-c-switch"] +if hasattr(os, "posix_spawn"): + PYDEVD_CUSTOMIZATION_COMMAND_LINE_ARGS.append("--posix-spawn") -@pytest.mark.parametrize('command_line_args', PYDEVD_CUSTOMIZATION_COMMAND_LINE_ARGS) +@pytest.mark.parametrize("command_line_args", PYDEVD_CUSTOMIZATION_COMMAND_LINE_ARGS) def test_subprocess_pydevd_customization(case_setup_remote_dap, command_line_args): import threading from tests_python.debugger_unittest import AbstractWriterThread with case_setup_remote_dap.test_file( - '_debugger_case_pydevd_customization.py', - append_command_line_args=command_line_args if command_line_args else [], - ) as writer: + "_debugger_case_pydevd_customization.py", + append_command_line_args=command_line_args if command_line_args else [], + ) as writer: json_facade = JsonFacade(writer) json_facade.writer.write_multi_threads_single_notification(True) json_facade.write_launch() - break1_line = writer.get_line_index_with_content('break 1 here') - break2_line = writer.get_line_index_with_content('break 2 here') + break1_line = writer.get_line_index_with_content("break 1 here") + break2_line = writer.get_line_index_with_content("break 2 here") json_facade.write_set_breakpoints([break1_line, break2_line]) server_socket = writer.server_socket class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread + expected_connections = 1 for _ in range(expected_connections): server_socket.listen(1) self.server_socket = server_socket - writer.log.append(' *** Multiprocess waiting on server_socket.accept()') + writer.log.append(" *** Multiprocess waiting on server_socket.accept()") new_sock, addr = server_socket.accept() - writer.log.append(' *** Multiprocess completed server_socket.accept()') + writer.log.append(" *** Multiprocess completed server_socket.accept()") reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() - writer.log.append(' *** Multiprocess started ReaderThread') + writer.log.append(" *** Multiprocess started ReaderThread") writer2 = SecondaryProcessWriterThread() - writer2._WRITE_LOG_PREFIX = ' *** Multiprocess write: ' + writer2._WRITE_LOG_PREFIX = " *** Multiprocess write: " writer2.reader_thread = reader_thread writer2.sock = new_sock json_facade2 = JsonFacade(writer2) @@ -5070,7 +5124,7 @@ def run(self): secondary_process_thread_communication = SecondaryProcessThreadCommunication() secondary_process_thread_communication.start() - time.sleep(.1) + time.sleep(0.1) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped() @@ -5081,7 +5135,7 @@ def run(self): secondary_process_thread_communication.join(5) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") writer.finished_ok = True @@ -5089,22 +5143,20 @@ def test_subprocess_then_fork(case_setup_multiprocessing_dap): import threading from tests_python.debugger_unittest import AbstractWriterThread - with case_setup_multiprocessing_dap.test_file('_debugger_case_subprocess_and_fork.py') as writer: + with case_setup_multiprocessing_dap.test_file("_debugger_case_subprocess_and_fork.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - break_line = writer.get_line_index_with_content('break here') + break_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints([break_line]) server_socket = writer.server_socket class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread @@ -5113,44 +5165,44 @@ def run(self): for i in range(2): server_socket.listen(1) self.server_socket = server_socket - writer.log.append(' *** Multiprocess %s waiting on server_socket.accept()' % (i,)) + writer.log.append(" *** Multiprocess %s waiting on server_socket.accept()" % (i,)) new_sock, addr = server_socket.accept() - writer.log.append(' *** Multiprocess %s completed server_socket.accept()' % (i,)) + writer.log.append(" *** Multiprocess %s completed server_socket.accept()" % (i,)) reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess %s Reader Thread' % i + reader_thread.name = " *** Multiprocess %s Reader Thread" % i reader_thread.start() - writer.log.append(' *** Multiprocess %s started ReaderThread' % (i,)) + writer.log.append(" *** Multiprocess %s started ReaderThread" % (i,)) writer2 = SecondaryProcessWriterThread() - writer2._WRITE_LOG_PREFIX = ' *** Multiprocess %s write: ' % i + writer2._WRITE_LOG_PREFIX = " *** Multiprocess %s write: " % i writer2.reader_thread = reader_thread writer2.sock = new_sock json_facade2 = JsonFacade(writer2) json_facade2.writer.write_multi_threads_single_notification(True) - writer.log.append(' *** Multiprocess %s write attachThread' % (i,)) + writer.log.append(" *** Multiprocess %s write attachThread" % (i,)) json_facade2.write_attach(justMyCode=False) - writer.log.append(' *** Multiprocess %s write set breakpoints' % (i,)) + writer.log.append(" *** Multiprocess %s write set breakpoints" % (i,)) json_facade2.write_set_breakpoints([break_line]) - writer.log.append(' *** Multiprocess %s write make initial run' % (i,)) + writer.log.append(" *** Multiprocess %s write make initial run" % (i,)) json_facade2.write_make_initial_run() json_facades.append(json_facade2) for i, json_facade3 in enumerate(json_facades): - writer.log.append(' *** Multiprocess %s wait for thread stopped' % (i,)) + writer.log.append(" *** Multiprocess %s wait for thread stopped" % (i,)) json_facade3.wait_for_thread_stopped(line=break_line) - writer.log.append(' *** Multiprocess %s continue' % (i,)) + writer.log.append(" *** Multiprocess %s continue" % (i,)) json_facade3.write_continue() secondary_process_thread_communication = SecondaryProcessThreadCommunication() secondary_process_thread_communication.start() - time.sleep(.1) + time.sleep(0.1) json_facade.write_make_initial_run() secondary_process_thread_communication.join(20) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") json_facade.wait_for_thread_stopped(line=break_line) json_facade.write_continue() @@ -5158,44 +5210,42 @@ def run(self): writer.finished_ok = True -@pytest.mark.parametrize('apply_multiprocessing_patch', [True]) +@pytest.mark.parametrize("apply_multiprocessing_patch", [True]) def test_no_subprocess_patching(case_setup_multiprocessing_dap, apply_multiprocessing_patch): import threading from tests_python.debugger_unittest import AbstractWriterThread def update_command_line_args(writer, args): ret = debugger_unittest.AbstractWriterThread.update_command_line_args(writer, args) - ret.insert(ret.index('--client'), '--multiprocess') - ret.insert(ret.index('--client'), '--debug-mode') - ret.insert(ret.index('--client'), 'debugpy-dap') - ret.insert(ret.index('--client'), '--json-dap-http') + ret.insert(ret.index("--client"), "--multiprocess") + ret.insert(ret.index("--client"), "--debug-mode") + ret.insert(ret.index("--client"), "debugpy-dap") + ret.insert(ret.index("--client"), "--json-dap-http") if apply_multiprocessing_patch: - ret.append('apply-multiprocessing-patch') + ret.append("apply-multiprocessing-patch") return ret with case_setup_multiprocessing_dap.test_file( - '_debugger_case_no_subprocess_patching.py', - update_command_line_args=update_command_line_args - ) as writer: + "_debugger_case_no_subprocess_patching.py", update_command_line_args=update_command_line_args + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - break1_line = writer.get_line_index_with_content('break 1 here') - break2_line = writer.get_line_index_with_content('break 2 here') + break1_line = writer.get_line_index_with_content("break 1 here") + break2_line = writer.get_line_index_with_content("break 2 here") json_facade.write_set_breakpoints([break1_line, break2_line]) server_socket = writer.server_socket class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread + expected_connections = 1 for _ in range(expected_connections): @@ -5204,7 +5254,7 @@ def run(self): new_sock, addr = server_socket.accept() reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() writer2 = SecondaryProcessWriterThread() @@ -5221,7 +5271,7 @@ def run(self): if apply_multiprocessing_patch: secondary_process_thread_communication = SecondaryProcessThreadCommunication() secondary_process_thread_communication.start() - time.sleep(.1) + time.sleep(0.1) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped() @@ -5230,28 +5280,27 @@ def run(self): if apply_multiprocessing_patch: secondary_process_thread_communication.join(10) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") writer.finished_ok = True def test_module_crash(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_module.py') as writer: + with case_setup_dap.test_file("_debugger_case_module.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() stopped_event = json_facade.wait_for_json_message(StoppedEvent) thread_id = stopped_event.body.threadId - json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=thread_id))) + json_facade.write_request(pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=thread_id))) module_event = json_facade.wait_for_json_message(ModuleEvent) # : :type module_event: ModuleEvent - assert 'MyName' in module_event.body.module.name - assert 'MyVersion' in module_event.body.module.version - assert 'MyPackage' in module_event.body.module.kwargs['package'] + assert "MyName" in module_event.body.module.name + assert "MyVersion" in module_event.body.module.version + assert "MyPackage" in module_event.body.module.kwargs["package"] json_facade.write_continue() @@ -5259,89 +5308,85 @@ def test_module_crash(case_setup_dap): def test_pydevd_systeminfo(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_print.py') as writer: + with case_setup_dap.test_file("_debugger_case_print.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() assert json_hit.thread_id - info_request = json_facade.write_request( - pydevd_schema.PydevdSystemInfoRequest( - pydevd_schema.PydevdSystemInfoArguments() - ) - ) + info_request = json_facade.write_request(pydevd_schema.PydevdSystemInfoRequest(pydevd_schema.PydevdSystemInfoArguments())) info_response = json_facade.wait_for_response(info_request) - body = info_response.to_dict()['body'] + body = info_response.to_dict()["body"] - assert body['python']['version'] == PY_VERSION_STR - assert body['python']['implementation']['name'] == PY_IMPL_NAME - assert body['python']['implementation']['version'] == PY_IMPL_VERSION_STR - assert 'description' in body['python']['implementation'] + assert body["python"]["version"] == PY_VERSION_STR + assert body["python"]["implementation"]["name"] == PY_IMPL_NAME + assert body["python"]["implementation"]["version"] == PY_IMPL_VERSION_STR + assert "description" in body["python"]["implementation"] - assert body['platform'] == {'name': sys.platform} + assert body["platform"] == {"name": sys.platform} - assert 'pid' in body['process'] - assert 'ppid' in body['process'] - assert body['process']['executable'] == sys.executable - assert body['process']['bitness'] == 64 if IS_64BIT_PROCESS else 32 + assert "pid" in body["process"] + assert "ppid" in body["process"] + assert body["process"]["executable"] == sys.executable + assert body["process"]["bitness"] == 64 if IS_64BIT_PROCESS else 32 - assert 'usingCython' in body['pydevd'] - assert 'usingFrameEval' in body['pydevd'] + assert "usingCython" in body["pydevd"] + assert "usingFrameEval" in body["pydevd"] - use_cython = os.getenv('PYDEVD_USE_CYTHON') + use_cython = os.getenv("PYDEVD_USE_CYTHON") if use_cython is not None: - using_cython = use_cython == 'YES' - assert body['pydevd']['usingCython'] == using_cython - assert body['pydevd']['usingFrameEval'] == (using_cython and IS_PY36_OR_GREATER and not IS_PY311_OR_GREATER) + using_cython = use_cython == "YES" + assert body["pydevd"]["usingCython"] == using_cython + assert body["pydevd"]["usingFrameEval"] == (using_cython and IS_PY36_OR_GREATER and not IS_PY311_OR_GREATER) json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('scenario', [ - 'terminate_request', - 'terminate_debugee' -]) -@pytest.mark.parametrize('check_subprocesses', [ - 'no_subprocesses', - 'kill_subprocesses', - 'kill_subprocesses_ignore_pid', - 'dont_kill_subprocesses', -]) +@pytest.mark.parametrize("scenario", ["terminate_request", "terminate_debugee"]) +@pytest.mark.parametrize( + "check_subprocesses", + [ + "no_subprocesses", + "kill_subprocesses", + "kill_subprocesses_ignore_pid", + "dont_kill_subprocesses", + ], +) def test_terminate(case_setup_dap, scenario, check_subprocesses): import psutil def check_test_suceeded_msg(writer, stdout, stderr): - return 'TEST SUCEEDED' not in ''.join(stdout) + return "TEST SUCEEDED" not in "".join(stdout) def update_command_line_args(writer, args): ret = debugger_unittest.AbstractWriterThread.update_command_line_args(writer, args) - if check_subprocesses in ('kill_subprocesses', 'dont_kill_subprocesses'): - ret.append('check-subprocesses') - if check_subprocesses in ('kill_subprocesses_ignore_pid',): - ret.append('check-subprocesses-ignore-pid') + if check_subprocesses in ("kill_subprocesses", "dont_kill_subprocesses"): + ret.append("check-subprocesses") + if check_subprocesses in ("kill_subprocesses_ignore_pid",): + ret.append("check-subprocesses-ignore-pid") return ret with case_setup_dap.test_file( - '_debugger_case_terminate.py', + "_debugger_case_terminate.py", check_test_suceeded_msg=check_test_suceeded_msg, update_command_line_args=update_command_line_args, - EXPECTED_RETURNCODE='any' if check_subprocesses == 'kill_subprocesses_ignore_pid' else 0, - ) as writer: + EXPECTED_RETURNCODE="any" if check_subprocesses == "kill_subprocesses_ignore_pid" else 0, + ) as writer: json_facade = JsonFacade(writer) - if check_subprocesses == 'dont_kill_subprocesses': + if check_subprocesses == "dont_kill_subprocesses": json_facade.write_launch(terminateChildProcesses=False) json_facade.write_make_initial_run() response = json_facade.write_initialize() - pid = response.to_dict()['body']['pydevd']['processId'] + pid = response.to_dict()["body"]["pydevd"]["processId"] - if check_subprocesses in ('kill_subprocesses', 'dont_kill_subprocesses', 'kill_subprocesses_ignore_pid'): + if check_subprocesses in ("kill_subprocesses", "dont_kill_subprocesses", "kill_subprocesses_ignore_pid"): process_ids_to_check = [pid] p = psutil.Process(pid) @@ -5355,15 +5400,15 @@ def wait_for_child_processes(): wait_for_condition(wait_for_child_processes) - if scenario == 'terminate_request': + if scenario == "terminate_request": json_facade.write_terminate() - elif scenario == 'terminate_debugee': + elif scenario == "terminate_debugee": json_facade.write_disconnect(terminate_debugee=True) else: - raise AssertionError('Unexpected: %s' % (scenario,)) + raise AssertionError("Unexpected: %s" % (scenario,)) json_facade.wait_for_terminated() - if check_subprocesses in ('kill_subprocesses', 'dont_kill_subprocesses', 'kill_subprocesses_ignore_pid'): + if check_subprocesses in ("kill_subprocesses", "dont_kill_subprocesses", "kill_subprocesses_ignore_pid"): def is_pid_alive(pid): # Note: the process may be a zombie process in Linux @@ -5380,7 +5425,7 @@ def is_pid_alive(pid): def get_live_pids(): return [pid for pid in process_ids_to_check if is_pid_alive(pid)] - if check_subprocesses == 'kill_subprocesses': + if check_subprocesses == "kill_subprocesses": def all_pids_exited(): live_pids = get_live_pids() @@ -5391,7 +5436,7 @@ def all_pids_exited(): wait_for_condition(all_pids_exited) - elif check_subprocesses == 'kill_subprocesses_ignore_pid': + elif check_subprocesses == "kill_subprocesses_ignore_pid": def all_pids_exited(): live_pids = get_live_pids() @@ -5428,57 +5473,56 @@ def only_main_pid_exited(): def test_access_token(case_setup_dap): - def update_command_line_args(self, args): - args.insert(1, '--json-dap-http') - args.insert(2, '--access-token') - args.insert(3, 'bar123') - args.insert(4, '--client-access-token') - args.insert(5, 'foo321') + args.insert(1, "--json-dap-http") + args.insert(2, "--access-token") + args.insert(3, "bar123") + args.insert(4, "--client-access-token") + args.insert(5, "foo321") return args - with case_setup_dap.test_file('_debugger_case_pause_continue.py', update_command_line_args=update_command_line_args) as writer: + with case_setup_dap.test_file("_debugger_case_pause_continue.py", update_command_line_args=update_command_line_args) as writer: json_facade = JsonFacade(writer) response = json_facade.write_set_debugger_property(multi_threads_single_notification=True, success=False) assert response.message == "Client not authenticated." - response = json_facade.write_authorize(access_token='wrong', success=False) + response = json_facade.write_authorize(access_token="wrong", success=False) assert response.message == "Client not authenticated." response = json_facade.write_set_debugger_property(multi_threads_single_notification=True, success=False) assert response.message == "Client not authenticated." - authorize_response = json_facade.write_authorize(access_token='bar123', success=True) + authorize_response = json_facade.write_authorize(access_token="bar123", success=True) # : :type authorize_response:PydevdAuthorizeResponse - assert authorize_response.body.clientAccessToken == 'foo321' + assert authorize_response.body.clientAccessToken == "foo321" json_facade.write_set_debugger_property(multi_threads_single_notification=True) json_facade.write_launch() - break_line = writer.get_line_index_with_content('Pause here and change loop to False') + break_line = writer.get_line_index_with_content("Pause here and change loop to False") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() - json_facade.wait_for_json_message(ThreadEvent, lambda event: event.body.reason == 'started') + json_facade.wait_for_json_message(ThreadEvent, lambda event: event.body.reason == "started") json_facade.wait_for_thread_stopped(line=break_line) # : :type response: ThreadsResponse response = json_facade.write_list_threads() assert len(response.body.threads) == 1 - assert next(iter(response.body.threads))['name'] == 'MainThread' + assert next(iter(response.body.threads))["name"] == "MainThread" json_facade.write_disconnect() - response = json_facade.write_authorize(access_token='wrong', success=False) + response = json_facade.write_authorize(access_token="wrong", success=False) assert response.message == "Client not authenticated." - authorize_response = json_facade.write_authorize(access_token='bar123') - assert authorize_response.body.clientAccessToken == 'foo321' + authorize_response = json_facade.write_authorize(access_token="bar123") + assert authorize_response.body.clientAccessToken == "foo321" json_facade.write_set_breakpoints(break_line) json_hit = json_facade.wait_for_thread_stopped(line=break_line) - json_facade.write_set_variable(json_hit.frame_id, 'loop', 'False') + json_facade.write_set_variable(json_hit.frame_id, "loop", "False") json_facade.write_continue() json_facade.wait_for_terminated() @@ -5486,62 +5530,59 @@ def update_command_line_args(self, args): def test_stop_on_entry(case_setup_dap): - with case_setup_dap.test_file('not_my_code/main_on_entry.py') as writer: + with case_setup_dap.test_file("not_my_code/main_on_entry.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch( justMyCode=False, stopOnEntry=True, rules=[ - {'path': '**/not_my_code/**', 'include':False}, - ] + {"path": "**/not_my_code/**", "include": False}, + ], ) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped( - 'entry', + "entry", file=( # We need to match the end with the proper slash. - 'my_code/__init__.py', - 'my_code\\__init__.py' - ) + "my_code/__init__.py", + "my_code\\__init__.py", + ), ) json_facade.write_continue() writer.finished_ok = True def test_stop_on_entry2(case_setup_dap): - with case_setup_dap.test_file('not_my_code/main_on_entry2.py') as writer: + with case_setup_dap.test_file("not_my_code/main_on_entry2.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch( justMyCode=False, stopOnEntry=True, showReturnValue=True, rules=[ - {'path': '**/main_on_entry2.py', 'include':False}, - ] + {"path": "**/main_on_entry2.py", "include": False}, + ], ) json_facade.write_make_initial_run() - json_facade.wait_for_thread_stopped( - 'entry', - file='empty_file.py' - ) + json_facade.wait_for_thread_stopped("entry", file="empty_file.py") json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('val', [True, False]) +@pytest.mark.parametrize("val", [True, False]) def test_debug_options(case_setup_dap, val): - with case_setup_dap.test_file('_debugger_case_debug_options.py') as writer: + with case_setup_dap.test_file("_debugger_case_debug_options.py") as writer: json_facade = JsonFacade(writer) - gui_event_loop = 'matplotlib' + gui_event_loop = "matplotlib" if val: try: import PySide2.QtCore except ImportError: pass else: - gui_event_loop = 'pyside2' + gui_event_loop = "pyside2" args = dict( justMyCode=val, redirectOutput=True, # Always redirect the output regardless of other values. @@ -5552,31 +5593,32 @@ def test_debug_options(case_setup_dap, val): stopOnEntry=val, maxExceptionStackFrames=4 if val else 5, guiEventLoop=gui_event_loop, - clientOS='UNIX' if val else 'WINDOWS' + clientOS="UNIX" if val else "WINDOWS", ) json_facade.write_launch(**args) json_facade.write_make_initial_run() - if args['stopOnEntry']: - json_facade.wait_for_thread_stopped('entry') + if args["stopOnEntry"]: + json_facade.wait_for_thread_stopped("entry") json_facade.write_continue() output = json_facade.wait_for_json_message( - OutputEvent, lambda msg: msg.body.category == 'stdout' and msg.body.output.startswith('{')and msg.body.output.endswith('}')) + OutputEvent, lambda msg: msg.body.category == "stdout" and msg.body.output.startswith("{") and msg.body.output.endswith("}") + ) # The values printed are internal values from _pydevd_bundle.pydevd_json_debug_options.DebugOptions, # not the parameters we passed. translation = { - 'django': 'django_debug', - 'flask': 'flask_debug', - 'justMyCode': 'just_my_code', - 'redirectOutput': 'redirect_output', - 'showReturnValue': 'show_return_value', - 'breakOnSystemExitZero': 'break_system_exit_zero', - 'stopOnEntry': 'stop_on_entry', - 'maxExceptionStackFrames': 'max_exception_stack_frames', - 'guiEventLoop': 'gui_event_loop', - 'clientOS': 'client_os', + "django": "django_debug", + "flask": "flask_debug", + "justMyCode": "just_my_code", + "redirectOutput": "redirect_output", + "showReturnValue": "show_return_value", + "breakOnSystemExitZero": "break_system_exit_zero", + "stopOnEntry": "stop_on_entry", + "maxExceptionStackFrames": "max_exception_stack_frames", + "guiEventLoop": "gui_event_loop", + "clientOS": "client_os", } assert json.loads(output.body.output) == dict((translation[key], val) for key, val in args.items()) @@ -5585,17 +5627,16 @@ def test_debug_options(case_setup_dap, val): def test_gui_event_loop_custom(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_gui_event_loop.py') as writer: + with case_setup_dap.test_file("_debugger_case_gui_event_loop.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_launch(guiEventLoop='__main__.LoopHolder.gui_loop', redirectOutput=True) - break_line = writer.get_line_index_with_content('break here') + json_facade.write_launch(guiEventLoop="__main__.LoopHolder.gui_loop", redirectOutput=True) + break_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() json_facade.wait_for_thread_stopped() - json_facade.wait_for_json_message( - OutputEvent, lambda msg: msg.body.category == 'stdout' and 'gui_loop() called' in msg.body.output) + json_facade.wait_for_json_message(OutputEvent, lambda msg: msg.body.category == "stdout" and "gui_loop() called" in msg.body.output) json_facade.write_continue() json_facade.wait_for_terminated() @@ -5606,12 +5647,12 @@ def test_gui_event_loop_qt5(case_setup_dap): try: from PySide2 import QtCore except ImportError: - pytest.skip('PySide2 not available') + pytest.skip("PySide2 not available") - with case_setup_dap.test_file('_debugger_case_gui_event_loop_qt5.py') as writer: + with case_setup_dap.test_file("_debugger_case_gui_event_loop_qt5.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_launch(guiEventLoop='qt5', redirectOutput=True) - break_line = writer.get_line_index_with_content('break here') + json_facade.write_launch(guiEventLoop="qt5", redirectOutput=True) + break_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() @@ -5621,78 +5662,78 @@ def test_gui_event_loop_qt5(case_setup_dap): # output is not shown (as the QTimer timeout wouldn't be executed). for _i in range(3): json_facade.wait_for_json_message( - OutputEvent, lambda msg: msg.body.category == 'stdout' and 'on_timeout() called' in msg.body.output) + OutputEvent, lambda msg: msg.body.category == "stdout" and "on_timeout() called" in msg.body.output + ) json_facade.write_continue() json_facade.wait_for_terminated() writer.finished_ok = True -@pytest.mark.parametrize('debug_stdlib', [True, False]) +@pytest.mark.parametrize("debug_stdlib", [True, False]) def test_just_my_code_debug_option_deprecated(case_setup_dap, debug_stdlib, debugger_runner_simple): from _pydev_bundle import pydev_log - with case_setup_dap.test_file('_debugger_case_debug_options.py') as writer: + + with case_setup_dap.test_file("_debugger_case_debug_options.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch( redirectOutput=True, # Always redirect the output regardless of other values. - debugStdLib=debug_stdlib + debugStdLib=debug_stdlib, ) json_facade.write_make_initial_run() output = json_facade.wait_for_json_message( - OutputEvent, lambda msg: msg.body.category == 'stdout' and msg.body.output.startswith('{')and msg.body.output.endswith('}')) + OutputEvent, lambda msg: msg.body.category == "stdout" and msg.body.output.startswith("{") and msg.body.output.endswith("}") + ) settings = json.loads(output.body.output) # Note: the internal attribute is just_my_code. - assert settings['just_my_code'] == (not debug_stdlib) + assert settings["just_my_code"] == (not debug_stdlib) json_facade.wait_for_terminated() contents = [] for f in pydev_log.list_log_files(debugger_runner_simple.pydevd_debug_file): if os.path.exists(f): - with open(f, 'r') as stream: + with open(f, "r") as stream: contents.append(stream.read()) writer.finished_ok = True def test_send_invalid_messages(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_local_variables.py') as writer: + with case_setup_dap.test_file("_debugger_case_local_variables.py") as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break 2 here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break 2 here")) json_facade.write_make_initial_run() stopped_event = json_facade.wait_for_json_message(StoppedEvent) thread_id = stopped_event.body.threadId - json_facade.write_request( - pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=thread_id))) + json_facade.write_request(pydevd_schema.StackTraceRequest(pydevd_schema.StackTraceArguments(threadId=thread_id))) # : :type response: ModulesResponse # : :type modules_response_body: ModulesResponseBody # *** Check that we accept an invalid modules request (i.e.: without arguments). - response = json_facade.wait_for_response(json_facade.write_request( - {'type': 'request', 'command': 'modules'})) + response = json_facade.wait_for_response(json_facade.write_request({"type": "request", "command": "modules"})) modules_response_body = response.body assert len(modules_response_body.modules) == 1 module = next(iter(modules_response_body.modules)) - assert module['name'] == '__main__' - assert module['path'].endswith('_debugger_case_local_variables.py') + assert module["name"] == "__main__" + assert module["path"].endswith("_debugger_case_local_variables.py") # *** Check that we don't fail on request without command. - request = json_facade.write_request({'type': 'request'}) + request = json_facade.write_request({"type": "request"}) response = json_facade.wait_for_response(request, Response) assert not response.success - assert response.command == '' + assert response.command == "" # *** Check that we don't crash if we can't decode message. - json_facade.writer.write_with_content_len('invalid json here') + json_facade.writer.write_with_content_len("invalid json here") # *** Check that we get a failure from a completions without arguments. - response = json_facade.wait_for_response(json_facade.write_request( - {'type': 'request', 'command': 'completions'})) + response = json_facade.wait_for_response(json_facade.write_request({"type": "request", "command": "completions"})) assert not response.success json_facade.write_continue() @@ -5700,32 +5741,31 @@ def test_send_invalid_messages(case_setup_dap): def test_send_json_message(case_setup_dap): - - with case_setup_dap.test_file('_debugger_case_custom_message.py') as writer: + with case_setup_dap.test_file("_debugger_case_custom_message.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch() json_facade.write_make_initial_run() - json_facade.wait_for_json_message( - OutputEvent, lambda msg: msg.body.category == 'my_category' and msg.body.output == 'some output') + json_facade.wait_for_json_message(OutputEvent, lambda msg: msg.body.category == "my_category" and msg.body.output == "some output") json_facade.wait_for_json_message( - OutputEvent, lambda msg: msg.body.category == 'my_category2' and msg.body.output == 'some output 2') + OutputEvent, lambda msg: msg.body.category == "my_category2" and msg.body.output == "some output 2" + ) writer.finished_ok = True def test_global_scope(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_globals.py') as writer: + with case_setup_dap.test_file("_debugger_case_globals.py") as writer: json_facade = JsonFacade(writer) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('breakpoint here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("breakpoint here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() - local_var = json_facade.get_global_var(json_hit.frame_id, 'in_global_scope') + local_var = json_facade.get_global_var(json_hit.frame_id, "in_global_scope") assert local_var.value == "'in_global_scope_value'" json_facade.write_continue() @@ -5733,40 +5773,43 @@ def test_global_scope(case_setup_dap): def _check_inline_var_presentation(json_facade, json_hit, variables_response): - var_names = [v['name'] for v in variables_response.body.variables] - assert var_names[:3] == ['SomeClass', 'in_global_scope', '__builtins__'] + var_names = [v["name"] for v in variables_response.body.variables] + assert var_names[:3] == ["SomeClass", "in_global_scope", "__builtins__"] def _check_hide_var_presentation(json_facade, json_hit, variables_response): - var_names = [v['name'] for v in variables_response.body.variables] - assert var_names == ['in_global_scope'] + var_names = [v["name"] for v in variables_response.body.variables] + assert var_names == ["in_global_scope"] def _check_class_group_special_inline_presentation(json_facade, json_hit, variables_response): - var_names = [v['name'] for v in variables_response.body.variables] - assert var_names[:3] == ['class variables', 'in_global_scope', '__builtins__'] + var_names = [v["name"] for v in variables_response.body.variables] + assert var_names[:3] == ["class variables", "in_global_scope", "__builtins__"] - variables_response = json_facade.get_variables_response(variables_response.body.variables[0]['variablesReference']) - var_names = [v['name'] for v in variables_response.body.variables] - assert var_names == ['SomeClass'] + variables_response = json_facade.get_variables_response(variables_response.body.variables[0]["variablesReference"]) + var_names = [v["name"] for v in variables_response.body.variables] + assert var_names == ["SomeClass"] -@pytest.mark.parametrize('var_presentation, check_func', [ - ({"all": "inline"}, _check_inline_var_presentation), - ({"all": "hide"}, _check_hide_var_presentation), - ({"class": "group", "special": "inline"}, _check_class_group_special_inline_presentation), -]) +@pytest.mark.parametrize( + "var_presentation, check_func", + [ + ({"all": "inline"}, _check_inline_var_presentation), + ({"all": "hide"}, _check_hide_var_presentation), + ({"class": "group", "special": "inline"}, _check_class_group_special_inline_presentation), + ], +) def test_variable_presentation(case_setup_dap, var_presentation, check_func): - with case_setup_dap.test_file('_debugger_case_globals.py') as writer: + with case_setup_dap.test_file("_debugger_case_globals.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(variablePresentation=var_presentation) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('breakpoint here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("breakpoint here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() name_to_scope = json_facade.get_name_to_scope(json_hit.frame_id) - variables_response = json_facade.get_variables_response(name_to_scope['Globals'].variablesReference) + variables_response = json_facade.get_variables_response(name_to_scope["Globals"].variablesReference) check_func(json_facade, json_hit, variables_response) json_facade.write_continue() @@ -5775,16 +5818,15 @@ def test_variable_presentation(case_setup_dap, var_presentation, check_func): def test_debugger_case_deadlock_thread_eval(case_setup_dap): - def get_environ(self): env = os.environ.copy() - env['PYDEVD_UNBLOCK_THREADS_TIMEOUT'] = '0.5' + env["PYDEVD_UNBLOCK_THREADS_TIMEOUT"] = "0.5" return env - with case_setup_dap.test_file('_debugger_case_deadlock_thread_eval.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_deadlock_thread_eval.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here 1')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here 1")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() @@ -5798,27 +5840,25 @@ def get_environ(self): def test_debugger_case_breakpoint_on_unblock_thread_eval(case_setup_dap): - from _pydevd_bundle._debug_adapter.pydevd_schema import EvaluateResponse def get_environ(self): env = os.environ.copy() - env['PYDEVD_UNBLOCK_THREADS_TIMEOUT'] = '0.5' + env["PYDEVD_UNBLOCK_THREADS_TIMEOUT"] = "0.5" return env - with case_setup_dap.test_file('_debugger_case_deadlock_thread_eval.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_deadlock_thread_eval.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - break1 = writer.get_line_index_with_content('Break here 1') - break2 = writer.get_line_index_with_content('Break here 2') + break1 = writer.get_line_index_with_content("Break here 1") + break2 = writer.get_line_index_with_content("Break here 2") json_facade.write_set_breakpoints([break1, break2]) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped(line=break1) # If threads aren't resumed, this will deadlock. - evaluate_request = json_facade.evaluate( - 'processor.process("process in evaluate")', json_hit.frame_id, wait_for_response=False) + evaluate_request = json_facade.evaluate('processor.process("process in evaluate")', json_hit.frame_id, wait_for_response=False) # We'll hit another breakpoint during that evaluation. json_hit = json_facade.wait_for_thread_stopped(line=break2) @@ -5830,141 +5870,135 @@ def get_environ(self): # Check that we got the evaluate responses. messages = json_facade.mark_messages( - EvaluateResponse, lambda evaluate_response: evaluate_response.request_seq == evaluate_request.seq) + EvaluateResponse, lambda evaluate_response: evaluate_response.request_seq == evaluate_request.seq + ) assert len(messages) == 1 writer.finished_ok = True def test_debugger_case_unblock_manually(case_setup_dap): - from _pydevd_bundle._debug_adapter.pydevd_schema import EvaluateResponse def get_environ(self): env = os.environ.copy() - env['PYDEVD_WARN_EVALUATION_TIMEOUT'] = '0.5' + env["PYDEVD_WARN_EVALUATION_TIMEOUT"] = "0.5" return env - with case_setup_dap.test_file('_debugger_case_deadlock_thread_eval.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_deadlock_thread_eval.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() - break1 = writer.get_line_index_with_content('Break here 1') + break1 = writer.get_line_index_with_content("Break here 1") json_facade.write_set_breakpoints([break1]) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped(line=break1) # If threads aren't resumed, this will deadlock. - evaluate_request = json_facade.evaluate( - 'processor.process("process in evaluate")', json_hit.frame_id, wait_for_response=False) + evaluate_request = json_facade.evaluate('processor.process("process in evaluate")', json_hit.frame_id, wait_for_response=False) - json_facade.wait_for_json_message( - OutputEvent, lambda output_event: 'did not finish after' in output_event.body.output) + json_facade.wait_for_json_message(OutputEvent, lambda output_event: "did not finish after" in output_event.body.output) # User may manually resume it. json_facade.write_continue() # Check that we got the evaluate responses. - json_facade.wait_for_json_message( - EvaluateResponse, lambda evaluate_response: evaluate_response.request_seq == evaluate_request.seq) + json_facade.wait_for_json_message(EvaluateResponse, lambda evaluate_response: evaluate_response.request_seq == evaluate_request.seq) writer.finished_ok = True def test_debugger_case_deadlock_notify_evaluate_timeout(case_setup_dap, pyfile): - @pyfile def case_slow_evaluate(): - def slow_evaluate(): import time + time.sleep(2) - print('TEST SUCEEDED!') # Break here + print("TEST SUCEEDED!") # Break here def get_environ(self): env = os.environ.copy() - env['PYDEVD_WARN_EVALUATION_TIMEOUT'] = '0.5' + env["PYDEVD_WARN_EVALUATION_TIMEOUT"] = "0.5" return env with case_setup_dap.test_file(case_slow_evaluate, get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() # If threads aren't resumed, this will deadlock. - json_facade.evaluate('slow_evaluate()', json_hit.frame_id) + json_facade.evaluate("slow_evaluate()", json_hit.frame_id) json_facade.write_continue() - messages = json_facade.mark_messages( - OutputEvent, lambda output_event: 'did not finish after' in output_event.body.output) + messages = json_facade.mark_messages(OutputEvent, lambda output_event: "did not finish after" in output_event.body.output) assert len(messages) == 1 writer.finished_ok = True def test_debugger_case_deadlock_interrupt_thread(case_setup_dap, pyfile): - @pyfile def case_infinite_evaluate(): - def infinite_evaluate(): import time + while True: - time.sleep(.1) + time.sleep(0.1) - print('TEST SUCEEDED!') # Break here + print("TEST SUCEEDED!") # Break here def get_environ(self): env = os.environ.copy() - env['PYDEVD_INTERRUPT_THREAD_TIMEOUT'] = '0.5' + env["PYDEVD_INTERRUPT_THREAD_TIMEOUT"] = "0.5" return env # Sometimes we end up with a different return code on Linux when interrupting (even # though we go through completion and print the 'TEST SUCEEDED' msg). - with case_setup_dap.test_file( - case_infinite_evaluate, get_environ=get_environ, EXPECTED_RETURNCODE='any') as writer: + with case_setup_dap.test_file(case_infinite_evaluate, get_environ=get_environ, EXPECTED_RETURNCODE="any") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() # If threads aren't resumed, this will deadlock. - json_facade.evaluate('infinite_evaluate()', json_hit.frame_id, wait_for_response=False) + json_facade.evaluate("infinite_evaluate()", json_hit.frame_id, wait_for_response=False) json_facade.write_continue() writer.finished_ok = True -@pytest.mark.parametrize('launch_through_link', [True, False]) -@pytest.mark.parametrize('breakpoints_through_link', [True, False]) +@pytest.mark.parametrize("launch_through_link", [True, False]) +@pytest.mark.parametrize("breakpoints_through_link", [True, False]) def test_debugger_case_symlink(case_setup_dap, tmpdir, launch_through_link, breakpoints_through_link): - ''' + """ Test that even if we resolve links internally, externally the contents will be related to the version launched. - ''' + """ from tests_python.debugger_unittest import _get_debugger_test_file - original_filename = _get_debugger_test_file('_debugger_case2.py') - target_link = str(tmpdir.join('resources_link')) + original_filename = _get_debugger_test_file("_debugger_case2.py") + + target_link = str(tmpdir.join("resources_link")) if pydevd_constants.IS_WINDOWS and not pydevd_constants.IS_PY38_OR_GREATER: - pytest.skip('Symlink support not available.') + pytest.skip("Symlink support not available.") try: os.symlink(os.path.dirname(original_filename), target_link, target_is_directory=True) except (OSError, TypeError, AttributeError): - pytest.skip('Symlink support not available.') + pytest.skip("Symlink support not available.") try: - target_filename_in_link = os.path.join(target_link, '_debugger_case2.py') + target_filename_in_link = os.path.join(target_link, "_debugger_case2.py") with case_setup_dap.test_file(target_filename_in_link if launch_through_link else original_filename) as writer: json_facade = JsonFacade(writer) @@ -5975,12 +6009,12 @@ def test_debugger_case_symlink(case_setup_dap, tmpdir, launch_through_link, brea # link or the real path. json_facade.write_set_breakpoints( writer.get_line_index_with_content("print('Start Call1')"), - filename=target_filename_in_link if breakpoints_through_link else original_filename + filename=target_filename_in_link if breakpoints_through_link else original_filename, ) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() - path = json_hit.stack_trace_response.body.stackFrames[0]['source']['path'] + path = json_hit.stack_trace_response.body.stackFrames[0]["source"]["path"] # Regardless of how it was hit, what's shown is what was launched. assert path == target_filename_in_link if launch_through_link else original_filename @@ -5994,23 +6028,25 @@ def test_debugger_case_symlink(case_setup_dap, tmpdir, launch_through_link, brea os.unlink(target_link) -@pytest.mark.skipif(not IS_LINUX, reason='Linux only test.') +@pytest.mark.skipif(not IS_LINUX, reason="Linux only test.") def test_debugger_case_sensitive(case_setup_dap, tmpdir): - path = os.path.abspath(str(tmpdir.join('Path1').join('PaTh2'))) + path = os.path.abspath(str(tmpdir.join("Path1").join("PaTh2"))) os.makedirs(path) - target = os.path.join(path, 'myFile.py') - with open(target, 'w') as stream: - stream.write(''' + target = os.path.join(path, "myFile.py") + with open(target, "w") as stream: + stream.write( + """ print('current file', __file__) # Break here print('TEST SUCEEDED') -''') +""" + ) assert not os.path.exists(target.lower()) assert os.path.exists(target) def get_environ(self): env = os.environ.copy() # Force to normalize by doing filename.lower(). - env['PYDEVD_FILENAME_NORMALIZATION'] = 'lower' + env["PYDEVD_FILENAME_NORMALIZATION"] = "lower" return env # Sometimes we end up with a different return code on Linux when interrupting (even @@ -6018,11 +6054,11 @@ def get_environ(self): with case_setup_dap.test_file(target, get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - json_facade.write_set_breakpoints(writer.get_line_index_with_content('Break here')) + json_facade.write_set_breakpoints(writer.get_line_index_with_content("Break here")) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() - path = json_hit.stack_trace_response.body.stackFrames[0]['source']['path'] + path = json_hit.stack_trace_response.body.stackFrames[0]["source"]["path"] assert path == target json_facade.write_continue() @@ -6031,15 +6067,15 @@ def get_environ(self): @pytest.mark.skipif( - not IS_WINDOWS or - not IS_PY36_OR_GREATER or - not IS_CPYTHON or - not TEST_CYTHON or - IS_PY311, # Requires frame-eval mode (not available for Python 3.11). + not IS_WINDOWS + or not IS_PY36_OR_GREATER + or not IS_CPYTHON + or not TEST_CYTHON + or IS_PY311, # Requires frame-eval mode (not available for Python 3.11). # Note that this works in Python 3.12 as it uses sys.monitoring. - reason='Windows only test and only Python 3.6 onwards.') + reason="Windows only test and only Python 3.6 onwards.", +) def test_native_threads(case_setup_dap, pyfile): - @pyfile def case_native_thread(): from ctypes import windll, WINFUNCTYPE, c_uint32, c_void_p, c_size_t @@ -6056,14 +6092,14 @@ def method(_): windll.kernel32.CreateThread(None, c_size_t(0), method, None, c_uint32(0), None) while not entered_thread[0]: - time.sleep(.1) + time.sleep(0.1) - print('TEST SUCEEDED') + print("TEST SUCEEDED") with case_setup_dap.test_file(case_native_thread) as writer: json_facade = JsonFacade(writer) - line = writer.get_line_index_with_content('Break here') + line = writer.get_line_index_with_content("Break here") json_facade.write_launch(justMyCode=False) json_facade.write_set_breakpoints(line) json_facade.write_make_initial_run() @@ -6075,34 +6111,33 @@ def method(_): def test_code_reload(case_setup_dap, pyfile): - @pyfile def mod1(): import mod2 import time + finish = False for _ in range(50): finish = mod2.do_something() if finish: break - time.sleep(.1) # Break 1 + time.sleep(0.1) # Break 1 else: - raise AssertionError('It seems the reload was not done in the available amount of time.') + raise AssertionError("It seems the reload was not done in the available amount of time.") - print('TEST SUCEEDED') # Break 2 + print("TEST SUCEEDED") # Break 2 @pyfile def mod2(): - def do_something(): return False with case_setup_dap.test_file(mod1) as writer: json_facade = JsonFacade(writer) - line1 = writer.get_line_index_with_content('Break 1') - line2 = writer.get_line_index_with_content('Break 2') - json_facade.write_launch(justMyCode=False, autoReload={'pollingInterval': 0, 'enable': True}) + line1 = writer.get_line_index_with_content("Break 1") + line2 = writer.get_line_index_with_content("Break 2") + json_facade.write_launch(justMyCode=False, autoReload={"pollingInterval": 0, "enable": True}) json_facade.write_set_breakpoints([line1, line2]) json_facade.write_make_initial_run() @@ -6110,11 +6145,13 @@ def do_something(): json_facade.wait_for_thread_stopped(line=line1) json_facade.write_set_breakpoints(line2) - with open(mod2, 'w') as stream: - stream.write(''' + with open(mod2, "w") as stream: + stream.write( + """ def do_something(): return True -''') +""" + ) json_facade.write_continue() json_facade.wait_for_thread_stopped(line=line2) @@ -6124,10 +6161,10 @@ def do_something(): def test_step_into_target_basic(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_smart_step_into.py') as writer: + with case_setup_dap.test_file("_debugger_case_smart_step_into.py") as writer: json_facade = JsonFacade(writer) - bp = writer.get_line_index_with_content('break here') + bp = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints([bp]) json_facade.write_make_initial_run() @@ -6136,27 +6173,27 @@ def test_step_into_target_basic(case_setup_dap): # : :type step_in_targets: List[StepInTarget] step_in_targets = json_facade.get_step_in_targets(hit.frame_id) - label_to_id = dict((target['label'], target['id']) for target in step_in_targets) + label_to_id = dict((target["label"], target["id"]) for target in step_in_targets) if IS_PY311_OR_GREATER: - assert set(label_to_id.keys()) == {'call_outer(foo(bar()))', 'foo(bar())', 'bar()'} - target = 'foo(bar())' + assert set(label_to_id.keys()) == {"call_outer(foo(bar()))", "foo(bar())", "bar()"} + target = "foo(bar())" else: - assert set(label_to_id.keys()) == {'bar', 'foo', 'call_outer'} - target = 'foo' + assert set(label_to_id.keys()) == {"bar", "foo", "call_outer"} + target = "foo" json_facade.write_step_in(hit.thread_id, target_id=label_to_id[target]) - on_foo_mark_line = writer.get_line_index_with_content('on foo mark') - hit = json_facade.wait_for_thread_stopped(reason='step', line=on_foo_mark_line) + on_foo_mark_line = writer.get_line_index_with_content("on foo mark") + hit = json_facade.wait_for_thread_stopped(reason="step", line=on_foo_mark_line) json_facade.write_continue() writer.finished_ok = True def test_step_into_target_multiple(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_smart_step_into2.py') as writer: + with case_setup_dap.test_file("_debugger_case_smart_step_into2.py") as writer: json_facade = JsonFacade(writer) - bp = writer.get_line_index_with_content('break here') + bp = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints([bp]) json_facade.write_make_initial_run() @@ -6165,27 +6202,27 @@ def test_step_into_target_multiple(case_setup_dap): # : :type step_in_targets: List[StepInTarget] step_in_targets = json_facade.get_step_in_targets(hit.frame_id) - label_to_id = dict((target['label'], target['id']) for target in step_in_targets) + label_to_id = dict((target["label"], target["id"]) for target in step_in_targets) if IS_PY311_OR_GREATER: - assert set(label_to_id.keys()) == {'foo(foo(foo(foo(1))))', 'foo(foo(foo(1)))', 'foo(foo(1))', 'foo(1)'} - target = 'foo(foo(1))' + assert set(label_to_id.keys()) == {"foo(foo(foo(foo(1))))", "foo(foo(foo(1)))", "foo(foo(1))", "foo(1)"} + target = "foo(foo(1))" else: - assert set(label_to_id.keys()) == {'foo', 'foo (call 2)', 'foo (call 3)', 'foo (call 4)'} - target = 'foo (call 2)' + assert set(label_to_id.keys()) == {"foo", "foo (call 2)", "foo (call 3)", "foo (call 4)"} + target = "foo (call 2)" json_facade.write_step_in(hit.thread_id, target_id=label_to_id[target]) - on_foo_mark_line = writer.get_line_index_with_content('on foo mark') - hit = json_facade.wait_for_thread_stopped(reason='step', line=on_foo_mark_line) + on_foo_mark_line = writer.get_line_index_with_content("on foo mark") + hit = json_facade.wait_for_thread_stopped(reason="step", line=on_foo_mark_line) json_facade.write_continue() writer.finished_ok = True def test_step_into_target_genexpr(case_setup_dap): - with case_setup_dap.test_file('_debugger_case_smart_step_into3.py') as writer: + with case_setup_dap.test_file("_debugger_case_smart_step_into3.py") as writer: json_facade = JsonFacade(writer) - bp = writer.get_line_index_with_content('break here') + bp = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints([bp]) json_facade.write_make_initial_run() @@ -6194,58 +6231,53 @@ def test_step_into_target_genexpr(case_setup_dap): # : :type step_in_targets: List[StepInTarget] step_in_targets = json_facade.get_step_in_targets(hit.frame_id) - label_to_id = dict((target['label'], target['id']) for target in step_in_targets) + label_to_id = dict((target["label"], target["id"]) for target in step_in_targets) if IS_PY311_OR_GREATER: - assert set(label_to_id) == {'foo(arg)', 'list(gen)'} - json_facade.write_step_in(hit.thread_id, target_id=label_to_id['foo(arg)']) + assert set(label_to_id) == {"foo(arg)", "list(gen)"} + json_facade.write_step_in(hit.thread_id, target_id=label_to_id["foo(arg)"]) else: - assert set(label_to_id) == {'foo', 'list'} - json_facade.write_step_in(hit.thread_id, target_id=label_to_id['foo']) + assert set(label_to_id) == {"foo", "list"} + json_facade.write_step_in(hit.thread_id, target_id=label_to_id["foo"]) - on_foo_mark_line = writer.get_line_index_with_content('on foo mark') - hit = json_facade.wait_for_thread_stopped(reason='step', line=on_foo_mark_line) + on_foo_mark_line = writer.get_line_index_with_content("on foo mark") + hit = json_facade.wait_for_thread_stopped(reason="step", line=on_foo_mark_line) json_facade.write_continue() writer.finished_ok = True def test_function_breakpoints_basic(case_setup_dap, pyfile): - @pyfile def module(): - def do_something(): # break here - print('TEST SUCEEDED') + print("TEST SUCEEDED") - if __name__ == '__main__': + if __name__ == "__main__": do_something() with case_setup_dap.test_file(module) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - bp = writer.get_line_index_with_content('break here') - json_facade.write_set_function_breakpoints(['do_something']) + bp = writer.get_line_index_with_content("break here") + json_facade.write_set_function_breakpoints(["do_something"]) json_facade.write_make_initial_run() - json_facade.wait_for_thread_stopped( - 'function breakpoint', line=bp, preserve_focus_hint=False) + json_facade.wait_for_thread_stopped("function breakpoint", line=bp, preserve_focus_hint=False) json_facade.write_continue() writer.finished_ok = True -@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason='Python 3.6 onwards required for test.') +@pytest.mark.skipif(not IS_PY36_OR_GREATER, reason="Python 3.6 onwards required for test.") def test_function_breakpoints_async(case_setup_dap): - - with case_setup_dap.test_file('_debugger_case_stop_async_iteration.py') as writer: + with case_setup_dap.test_file("_debugger_case_stop_async_iteration.py") as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - bp = writer.get_line_index_with_content('async def gen():') - json_facade.write_set_function_breakpoints(['gen']) + bp = writer.get_line_index_with_content("async def gen():") + json_facade.write_set_function_breakpoints(["gen"]) json_facade.write_make_initial_run() - json_facade.wait_for_thread_stopped( - 'function breakpoint', line=bp, preserve_focus_hint=False) + json_facade.wait_for_thread_stopped("function breakpoint", line=bp, preserve_focus_hint=False) json_facade.write_continue() writer.finished_ok = True @@ -6257,9 +6289,8 @@ def test_function_breakpoints_async(case_setup_dap): pandas = None -@pytest.mark.skipif(pandas is None, reason='Pandas not installed.') +@pytest.mark.skipif(pandas is None, reason="Pandas not installed.") def test_pandas(case_setup_dap, pyfile): - @pyfile def pandas_mod(): import pandas as pd @@ -6269,21 +6300,21 @@ def pandas_mod(): cols = 50 # i.e.: even with these setting our repr will print at most 300 lines/cols by default. - pd.set_option('display.max_columns', None) - pd.set_option('display.max_rows', None) + pd.set_option("display.max_columns", None) + pd.set_option("display.max_rows", None) items = rows * cols - df = pd.DataFrame(np.arange(items).reshape(rows, cols)).map(lambda x: 'Test String') + df = pd.DataFrame(np.arange(items).reshape(rows, cols)).map(lambda x: "Test String") series = df._series[0] styler = df.style - print('TEST SUCEEDED') # Break here + print("TEST SUCEEDED") # Break here with case_setup_dap.test_file(pandas_mod) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - bp = writer.get_line_index_with_content('Break here') + bp = writer.get_line_index_with_content("Break here") json_facade.write_set_breakpoints([bp]) json_facade.write_make_initial_run() @@ -6293,41 +6324,41 @@ def pandas_mod(): name_to_var = json_facade.get_locals_name_to_var(json_hit.frame_id) # Check the custom repr(DataFrame) - assert name_to_var['df'].value.count('\n') <= 63 - assert '...' in name_to_var['df'].value + assert name_to_var["df"].value.count("\n") <= 63 + assert "..." in name_to_var["df"].value - evaluate_response = json_facade.evaluate('df', json_hit.frame_id, context='repl') + evaluate_response = json_facade.evaluate("df", json_hit.frame_id, context="repl") evaluate_response_body = evaluate_response.body.to_dict() - assert '...' not in evaluate_response_body['result'] - assert evaluate_response_body['result'].count('\n') > 4999 + assert "..." not in evaluate_response_body["result"] + assert evaluate_response_body["result"].count("\n") > 4999 # Check the custom repr(Series) - assert name_to_var['series'].value.count('\n') <= 60 - assert '...' in name_to_var['series'].value + assert name_to_var["series"].value.count("\n") <= 60 + assert "..." in name_to_var["series"].value # Check custom listing (DataFrame) - df_variables_response = json_facade.get_variables_response(name_to_var['df'].variablesReference) + df_variables_response = json_facade.get_variables_response(name_to_var["df"].variablesReference) for v in df_variables_response.body.variables: - if v['name'] == 'T': - assert v['value'] == "''" + if v["name"] == "T": + assert v["value"] == "''" break else: raise AssertionError('Did not find variable "T".') # Check custom listing (Series) - df_variables_response = json_facade.get_variables_response(name_to_var['series'].variablesReference) + df_variables_response = json_facade.get_variables_response(name_to_var["series"].variablesReference) for v in df_variables_response.body.variables: - if v['name'] == 'T': - assert v['value'] == "''" + if v["name"] == "T": + assert v["value"] == "''" break else: raise AssertionError('Did not find variable "T".') # Check custom listing (Styler) - df_variables_response = json_facade.get_variables_response(name_to_var['styler'].variablesReference) + df_variables_response = json_facade.get_variables_response(name_to_var["styler"].variablesReference) for v in df_variables_response.body.variables: - if v['name'] == 'data': - assert v['value'] == "''" + if v["name"] == "data": + assert v["value"] == "''" break else: raise AssertionError('Did not find variable "data".') @@ -6336,28 +6367,30 @@ def pandas_mod(): writer.finished_ok = True -@pytest.mark.skipif(not IS_PY38_OR_GREATER, reason='Python 3.8 onwards required for test.') +@pytest.mark.skipif(not IS_PY38_OR_GREATER, reason="Python 3.8 onwards required for test.") def test_same_lineno_and_filename(case_setup_dap, pyfile): - @pyfile def target(): - def some_code(): - print('1') # Break here + print("1") # Break here - code_obj = compile(''' + code_obj = compile( + """ func() - ''', __file__, 'exec') + """, + __file__, + "exec", + ) code_obj = code_obj.replace(co_name=some_code.__code__.co_name, co_firstlineno=some_code.__code__.co_firstlineno) - exec(code_obj, {'func': some_code}) + exec(code_obj, {"func": some_code}) - print('TEST SUCEEDED') + print("TEST SUCEEDED") with case_setup_dap.test_file(target) as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here')) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here")) json_facade.write_launch(justMyCode=False) json_facade.write_make_initial_run() @@ -6373,15 +6406,15 @@ def some_code(): writer.finished_ok = True -@pytest.mark.skipif(sys.platform == 'win32', reason='Windows does not have execvp.') +@pytest.mark.skipif(sys.platform == "win32", reason="Windows does not have execvp.") def test_replace_process(case_setup_multiprocessing_dap): import threading from tests_python.debugger_unittest import AbstractWriterThread from _pydevd_bundle._debug_adapter.pydevd_schema import ExitedEvent with case_setup_multiprocessing_dap.test_file( - '_debugger_case_replace_process.py', - ) as writer: + "_debugger_case_replace_process.py", + ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() @@ -6392,20 +6425,19 @@ def test_replace_process(case_setup_multiprocessing_dap): secondary_finished_ok = [False] class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread + server_socket.listen(1) self.server_socket = server_socket new_sock, addr = server_socket.accept() reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() writer2 = SecondaryProcessWriterThread() @@ -6413,7 +6445,11 @@ def run(self): writer2.sock = new_sock json_facade2 = JsonFacade(writer2) - json_facade2.write_set_breakpoints([break1_line, ]) + json_facade2.write_set_breakpoints( + [ + break1_line, + ] + ) json_facade2.write_make_initial_run() json_facade2.wait_for_thread_stopped() @@ -6422,36 +6458,38 @@ def run(self): secondary_process_thread_communication = SecondaryProcessThreadCommunication() secondary_process_thread_communication.start() - time.sleep(.1) + time.sleep(0.1) json_facade.write_make_initial_run() exited_event = json_facade.wait_for_json_message(ExitedEvent) - assert exited_event.body.kwargs['pydevdReason'] == "processReplaced" + assert exited_event.body.kwargs["pydevdReason"] == "processReplaced" secondary_process_thread_communication.join(10) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") assert secondary_finished_ok[0] writer.finished_ok = True -@pytest.mark.parametrize('resolve_symlinks', [True, False]) +@pytest.mark.parametrize("resolve_symlinks", [True, False]) def test_use_real_path_and_not_links(case_setup_dap, tmpdir, resolve_symlinks): - dira = tmpdir.join('dira') + dira = tmpdir.join("dira") dira.mkdir() - dirb = tmpdir.join('dirb') + dirb = tmpdir.join("dirb") dirb.mkdir() - original_file = dira.join('test.py') - original_file.write(''' + original_file = dira.join("test.py") + original_file.write( + """ print('p1') # Break here print('p2') print('TEST SUCEEDED') -''') +""" + ) - symlinked_file = dirb.join('testit.py') + symlinked_file = dirb.join("testit.py") os.symlink(str(original_file), str(symlinked_file)) # I.e.: we're launching the symlinked file but we're actually @@ -6459,12 +6497,12 @@ def test_use_real_path_and_not_links(case_setup_dap, tmpdir, resolve_symlinks): with case_setup_dap.test_file(str(symlinked_file)) as writer: json_facade = JsonFacade(writer) - writer.write_add_breakpoint(writer.get_line_index_with_content('Break here'), filename=str(original_file)) + writer.write_add_breakpoint(writer.get_line_index_with_content("Break here"), filename=str(original_file)) json_facade.write_launch(justMyCode=False, resolveSymlinks=resolve_symlinks) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped() - filename = json_hit.stack_trace_response.body.stackFrames[0]['source']['path'] + filename = json_hit.stack_trace_response.body.stackFrames[0]["source"]["path"] if resolve_symlinks: assert filename == str(original_file) else: @@ -6476,6 +6514,7 @@ def test_use_real_path_and_not_links(case_setup_dap, tmpdir, resolve_symlinks): _TOP_LEVEL_AWAIT_AVAILABLE = False try: from ast import PyCF_ONLY_AST, PyCF_ALLOW_TOP_LEVEL_AWAIT + _TOP_LEVEL_AWAIT_AVAILABLE = True except ImportError: pass @@ -6483,34 +6522,33 @@ def test_use_real_path_and_not_links(case_setup_dap, tmpdir, resolve_symlinks): @pytest.mark.skipif(not _TOP_LEVEL_AWAIT_AVAILABLE, reason="Top-level await required.") def test_ipython_stepping_basic(case_setup_dap): - def get_environ(self): env = os.environ.copy() # Test setup - env["SCOPED_STEPPING_TARGET"] = '_debugger_case_scoped_stepping_target.py' + env["SCOPED_STEPPING_TARGET"] = "_debugger_case_scoped_stepping_target.py" # Actually setup the debugging env["PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING"] = "1" - env["PYDEVD_IPYTHON_CONTEXT"] = '_debugger_case_scoped_stepping.py, run_code, run_ast_nodes' + env["PYDEVD_IPYTHON_CONTEXT"] = "_debugger_case_scoped_stepping.py, run_code, run_ast_nodes" return env - with case_setup_dap.test_file('_debugger_case_scoped_stepping.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_scoped_stepping.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - target_file = debugger_unittest._get_debugger_test_file('_debugger_case_scoped_stepping_target.py') - break_line = writer.get_line_index_with_content('a = 1', filename=target_file) + target_file = debugger_unittest._get_debugger_test_file("_debugger_case_scoped_stepping_target.py") + break_line = writer.get_line_index_with_content("a = 1", filename=target_file) assert break_line == 1 json_facade.write_set_breakpoints(break_line, filename=target_file) json_facade.write_make_initial_run() - json_hit = json_facade.wait_for_thread_stopped(line=break_line, file='_debugger_case_scoped_stepping_target.py') + json_hit = json_facade.wait_for_thread_stopped(line=break_line, file="_debugger_case_scoped_stepping_target.py") json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', line=break_line + 1, file='_debugger_case_scoped_stepping_target.py') + json_hit = json_facade.wait_for_thread_stopped("step", line=break_line + 1, file="_debugger_case_scoped_stepping_target.py") json_facade.write_step_next(json_hit.thread_id) - json_hit = json_facade.wait_for_thread_stopped('step', line=break_line + 2, file='_debugger_case_scoped_stepping_target.py') + json_hit = json_facade.wait_for_thread_stopped("step", line=break_line + 2, file="_debugger_case_scoped_stepping_target.py") json_facade.write_continue() writer.finished_ok = True @@ -6518,39 +6556,38 @@ def get_environ(self): @pytest.mark.skipif(not _TOP_LEVEL_AWAIT_AVAILABLE, reason="Top-level await required.") def test_ipython_stepping_step_in(case_setup_dap): - def get_environ(self): env = os.environ.copy() # Test setup - env["SCOPED_STEPPING_TARGET"] = '_debugger_case_scoped_stepping_target2.py' + env["SCOPED_STEPPING_TARGET"] = "_debugger_case_scoped_stepping_target2.py" # Actually setup the debugging env["PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING"] = "1" - env["PYDEVD_IPYTHON_CONTEXT"] = '_debugger_case_scoped_stepping.py, run_code, run_ast_nodes' + env["PYDEVD_IPYTHON_CONTEXT"] = "_debugger_case_scoped_stepping.py, run_code, run_ast_nodes" return env - with case_setup_dap.test_file('_debugger_case_scoped_stepping.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_scoped_stepping.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=False) - target_file = debugger_unittest._get_debugger_test_file('_debugger_case_scoped_stepping_target2.py') - break_line = writer.get_line_index_with_content('break here', filename=target_file) + target_file = debugger_unittest._get_debugger_test_file("_debugger_case_scoped_stepping_target2.py") + break_line = writer.get_line_index_with_content("break here", filename=target_file) json_facade.write_set_breakpoints(break_line, filename=target_file) json_facade.write_make_initial_run() - json_hit = json_facade.wait_for_thread_stopped(line=break_line, file='_debugger_case_scoped_stepping_target2.py') + json_hit = json_facade.wait_for_thread_stopped(line=break_line, file="_debugger_case_scoped_stepping_target2.py") json_facade.write_step_in(json_hit.thread_id) - stop_at = writer.get_line_index_with_content('b = 2', filename=target_file) - json_hit = json_facade.wait_for_thread_stopped('step', line=stop_at, file='_debugger_case_scoped_stepping_target2.py') + stop_at = writer.get_line_index_with_content("b = 2", filename=target_file) + json_hit = json_facade.wait_for_thread_stopped("step", line=stop_at, file="_debugger_case_scoped_stepping_target2.py") json_facade.write_step_in(json_hit.thread_id) - stop_at = writer.get_line_index_with_content('method() # break here', filename=target_file) - json_hit = json_facade.wait_for_thread_stopped('step', line=stop_at, file='_debugger_case_scoped_stepping_target2.py') + stop_at = writer.get_line_index_with_content("method() # break here", filename=target_file) + json_hit = json_facade.wait_for_thread_stopped("step", line=stop_at, file="_debugger_case_scoped_stepping_target2.py") json_facade.write_step_in(json_hit.thread_id) - stop_at = writer.get_line_index_with_content('c = 3', filename=target_file) - json_hit = json_facade.wait_for_thread_stopped('step', line=stop_at, file='_debugger_case_scoped_stepping_target2.py') + stop_at = writer.get_line_index_with_content("c = 3", filename=target_file) + json_hit = json_facade.wait_for_thread_stopped("step", line=stop_at, file="_debugger_case_scoped_stepping_target2.py") json_facade.write_continue() writer.finished_ok = True @@ -6558,39 +6595,38 @@ def get_environ(self): @pytest.mark.skipif(not _TOP_LEVEL_AWAIT_AVAILABLE, reason="Top-level await required.") def test_ipython_stepping_step_in_justmycode(case_setup_dap): - def get_environ(self): env = os.environ.copy() # Test setup - env["SCOPED_STEPPING_TARGET"] = '_debugger_case_scoped_stepping_print.py' + env["SCOPED_STEPPING_TARGET"] = "_debugger_case_scoped_stepping_print.py" # Actually setup the debugging env["PYDEVD_IPYTHON_COMPATIBLE_DEBUGGING"] = "1" - env["PYDEVD_IPYTHON_CONTEXT"] = '_debugger_case_scoped_stepping.py, run_code, run_ast_nodes' + env["PYDEVD_IPYTHON_CONTEXT"] = "_debugger_case_scoped_stepping.py, run_code, run_ast_nodes" return env - with case_setup_dap.test_file('_debugger_case_scoped_stepping.py', get_environ=get_environ) as writer: + with case_setup_dap.test_file("_debugger_case_scoped_stepping.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch(justMyCode=True) - target_file = debugger_unittest._get_debugger_test_file('_debugger_case_scoped_stepping_print.py') - break_line = writer.get_line_index_with_content('break here', filename=target_file) + target_file = debugger_unittest._get_debugger_test_file("_debugger_case_scoped_stepping_print.py") + break_line = writer.get_line_index_with_content("break here", filename=target_file) json_facade.write_set_breakpoints(break_line, filename=target_file) json_facade.write_make_initial_run() - json_hit = json_facade.wait_for_thread_stopped(line=break_line, file='_debugger_case_scoped_stepping_print.py') + json_hit = json_facade.wait_for_thread_stopped(line=break_line, file="_debugger_case_scoped_stepping_print.py") json_facade.write_step_in(json_hit.thread_id) - stop_at = writer.get_line_index_with_content('pause 1', filename=target_file) - json_hit = json_facade.wait_for_thread_stopped('step', line=stop_at, file='_debugger_case_scoped_stepping_print.py') + stop_at = writer.get_line_index_with_content("pause 1", filename=target_file) + json_hit = json_facade.wait_for_thread_stopped("step", line=stop_at, file="_debugger_case_scoped_stepping_print.py") json_facade.write_step_in(json_hit.thread_id) - stop_at = writer.get_line_index_with_content('pause 2', filename=target_file) - json_hit = json_facade.wait_for_thread_stopped('step', line=stop_at, file='_debugger_case_scoped_stepping_print.py') + stop_at = writer.get_line_index_with_content("pause 2", filename=target_file) + json_hit = json_facade.wait_for_thread_stopped("step", line=stop_at, file="_debugger_case_scoped_stepping_print.py") json_facade.write_step_in(json_hit.thread_id) - stop_at = writer.get_line_index_with_content('pause 3', filename=target_file) - json_hit = json_facade.wait_for_thread_stopped('step', line=stop_at, file='_debugger_case_scoped_stepping_print.py') + stop_at = writer.get_line_index_with_content("pause 3", filename=target_file) + json_hit = json_facade.wait_for_thread_stopped("step", line=stop_at, file="_debugger_case_scoped_stepping_print.py") json_facade.write_continue() writer.finished_ok = True @@ -6600,17 +6636,14 @@ def test_logging_api(case_setup_multiprocessing_dap, tmpdir): import threading from tests_python.debugger_unittest import AbstractWriterThread - log_file = str(tmpdir.join('pydevd_in_test_logging.log')) + log_file = str(tmpdir.join("pydevd_in_test_logging.log")) def get_environ(self): env = os.environ.copy() env["TARGET_LOG_FILE"] = log_file return env - with case_setup_multiprocessing_dap.test_file( - '_debugger_case_logging.py', - get_environ=get_environ - ) as writer: + with case_setup_multiprocessing_dap.test_file("_debugger_case_logging.py", get_environ=get_environ) as writer: json_facade = JsonFacade(writer) json_facade.write_launch() @@ -6621,20 +6654,19 @@ def get_environ(self): secondary_finished_ok = [False] class SecondaryProcessWriterThread(AbstractWriterThread): - TEST_FILE = writer.get_main_filename() _sequence = -1 class SecondaryProcessThreadCommunication(threading.Thread): - def run(self): from tests_python.debugger_unittest import ReaderThread + server_socket.listen(1) self.server_socket = server_socket new_sock, addr = server_socket.accept() reader_thread = ReaderThread(new_sock) - reader_thread.name = ' *** Multiprocess Reader Thread' + reader_thread.name = " *** Multiprocess Reader Thread" reader_thread.start() writer2 = SecondaryProcessWriterThread() @@ -6642,7 +6674,11 @@ def run(self): writer2.sock = new_sock json_facade2 = JsonFacade(writer2) - json_facade2.write_set_breakpoints([break1_line, ]) + json_facade2.write_set_breakpoints( + [ + break1_line, + ] + ) json_facade2.write_make_initial_run() json_facade2.wait_for_thread_stopped() @@ -6651,39 +6687,39 @@ def run(self): secondary_process_thread_communication = SecondaryProcessThreadCommunication() secondary_process_thread_communication.start() - time.sleep(.1) + time.sleep(0.1) json_facade.write_make_initial_run() secondary_process_thread_communication.join(10) if secondary_process_thread_communication.is_alive(): - raise AssertionError('The SecondaryProcessThreadCommunication did not finish') + raise AssertionError("The SecondaryProcessThreadCommunication did not finish") assert secondary_finished_ok[0] writer.finished_ok = True -@pytest.mark.parametrize('soft_kill', [False, True]) +@pytest.mark.parametrize("soft_kill", [False, True]) def test_soft_terminate(case_setup_dap, pyfile, soft_kill): - if soft_kill and PYDEVD_USE_SYS_MONITORING: - pytest.skip('Right now when using sys.monitoring exceptions are be handled in callbacks.') + pytest.skip("Right now when using sys.monitoring exceptions are be handled in callbacks.") @pyfile def target(): import time + try: while True: - time.sleep(.2) # break here + time.sleep(0.2) # break here except KeyboardInterrupt: # i.e.: The test succeeds if a keyboard interrupt is received. - print('TEST SUCEEDED!') + print("TEST SUCEEDED!") raise def check_test_suceeded_msg(self, stdout, stderr): if soft_kill: - return 'TEST SUCEEDED' in ''.join(stdout) + return "TEST SUCEEDED" in "".join(stdout) else: - return 'TEST SUCEEDED' not in ''.join(stdout) + return "TEST SUCEEDED" not in "".join(stdout) def additional_output_checks(writer, stdout, stderr): if soft_kill: @@ -6692,18 +6728,15 @@ def additional_output_checks(writer, stdout, stderr): assert not stderr with case_setup_dap.test_file( - target, - EXPECTED_RETURNCODE='any', - check_test_suceeded_msg=check_test_suceeded_msg, - additional_output_checks=additional_output_checks, - ) as writer: + target, + EXPECTED_RETURNCODE="any", + check_test_suceeded_msg=check_test_suceeded_msg, + additional_output_checks=additional_output_checks, + ) as writer: json_facade = JsonFacade(writer) - json_facade.write_launch( - onTerminate="KeyboardInterrupt" if soft_kill else "kill", - justMyCode=False - ) + json_facade.write_launch(onTerminate="KeyboardInterrupt" if soft_kill else "kill", justMyCode=False) - break_line = writer.get_line_index_with_content('break here') + break_line = writer.get_line_index_with_content("break here") json_facade.write_set_breakpoints(break_line) json_facade.write_make_initial_run() json_hit = json_facade.wait_for_thread_stopped(line=break_line) @@ -6716,11 +6749,11 @@ def additional_output_checks(writer, stdout, stderr): if soft_kill: json_facade.wait_for_json_message( - OutputEvent, lambda output_event: 'raised from within the callback set' in output_event.body.output) + OutputEvent, lambda output_event: "raised from within the callback set" in output_event.body.output + ) writer.finished_ok = True -if __name__ == '__main__': - pytest.main(['-k', 'test_replace_process', '-s']) - +if __name__ == "__main__": + pytest.main(["-k", "test_replace_process", "-s"]) diff --git a/tests_python/test_dump_threads.py b/tests_python/test_dump_threads.py index b619f6198..bd4a855d9 100644 --- a/tests_python/test_dump_threads.py +++ b/tests_python/test_dump_threads.py @@ -1,8 +1,9 @@ def test_dump_threads(): import pydevd from io import StringIO + stream = StringIO() pydevd.dump_threads(stream=stream) contents = stream.getvalue() - assert 'Thread MainThread (daemon: False, pydevd thread: False)' in contents - assert 'test_dump_threads' in contents + assert "Thread MainThread (daemon: False, pydevd thread: False)" in contents + assert "test_dump_threads" in contents diff --git a/tests_python/test_evaluate_expression.py b/tests_python/test_evaluate_expression.py index 123fb6394..e8cd62ec2 100644 --- a/tests_python/test_evaluate_expression.py +++ b/tests_python/test_evaluate_expression.py @@ -21,6 +21,7 @@ def disable_critical_log(): # We want to hide the logging related to _evaluate_with_timeouts not receiving the py_db. from _pydev_bundle.pydev_log import log_context import io + stream = io.StringIO() with log_context(0, stream): yield @@ -30,45 +31,45 @@ def test_evaluate_expression_basic(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - evaluate_expression(None, frame, 'some_var = 1', is_exec=True) + evaluate_expression(None, frame, "some_var = 1", is_exec=True) - assert frame.f_locals['some_var'] == 1 + assert frame.f_locals["some_var"] == 1 check(next(iter(obtain_frame()))) - assert 'some_var' not in sys._getframe().f_globals + assert "some_var" not in sys._getframe().f_globals # as locals == globals, this will also change the current globals check(global_frame) - assert 'some_var' in sys._getframe().f_globals - del sys._getframe().f_globals['some_var'] - assert 'some_var' not in sys._getframe().f_globals + assert "some_var" in sys._getframe().f_globals + del sys._getframe().f_globals["some_var"] + assert "some_var" not in sys._getframe().f_globals def test_evaluate_expression_1(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - eval_txt = ''' + eval_txt = """ container = ["abc","efg"] results = [] for s in container: result = [s[i] for i in range(3)] results.append(result) -''' +""" evaluate_expression(None, frame, eval_txt, is_exec=True) - assert frame.f_locals['results'] == [['a', 'b', 'c'], ['e', 'f', 'g']] - assert frame.f_locals['s'] == "efg" + assert frame.f_locals["results"] == [["a", "b", "c"], ["e", "f", "g"]] + assert frame.f_locals["s"] == "efg" check(next(iter(obtain_frame()))) - for varname in ['container', 'results', 's']: + for varname in ["container", "results", "s"]: assert varname not in sys._getframe().f_globals check(global_frame) - for varname in ['container', 'results', 's']: + for varname in ["container", "results", "s"]: assert varname in sys._getframe().f_globals - for varname in ['container', 'results', 's']: + for varname in ["container", "results", "s"]: del sys._getframe().f_globals[varname] @@ -76,7 +77,7 @@ def test_evaluate_expression_2(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - eval_txt = 'all((x in (BAR, FOO) for x in SOME_LST))' + eval_txt = "all((x in (BAR, FOO) for x in SOME_LST))" assert evaluate_expression(None, frame, eval_txt, is_exec=False) check(next(iter(obtain_frame()))) @@ -90,60 +91,60 @@ def test_evaluate_expression_3(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - eval_txt = '''11 if (some_var := 22) else 33''' + eval_txt = """11 if (some_var := 22) else 33""" assert evaluate_expression(None, frame, eval_txt, is_exec=False) == 11 check(next(iter(obtain_frame()))) - assert 'some_var' not in sys._getframe().f_globals + assert "some_var" not in sys._getframe().f_globals # as locals == globals, this will also change the current globals check(global_frame) - assert 'some_var' in sys._getframe().f_globals - del sys._getframe().f_globals['some_var'] - assert 'some_var' not in sys._getframe().f_globals + assert "some_var" in sys._getframe().f_globals + del sys._getframe().f_globals["some_var"] + assert "some_var" not in sys._getframe().f_globals def test_evaluate_expression_4(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - eval_txt = '''import email;email.foo_value''' + eval_txt = """import email;email.foo_value""" with pytest.raises(AttributeError): evaluate_expression(None, frame, eval_txt, is_exec=True) - assert 'email' in frame.f_locals + assert "email" in frame.f_locals check(next(iter(obtain_frame()))) - assert 'email' not in sys._getframe().f_globals + assert "email" not in sys._getframe().f_globals # as locals == globals, this will also change the current globals check(global_frame) - assert 'email' in sys._getframe().f_globals - del sys._getframe().f_globals['email'] - assert 'email' not in sys._getframe().f_globals + assert "email" in sys._getframe().f_globals + del sys._getframe().f_globals["email"] + assert "email" not in sys._getframe().f_globals def test_evaluate_expression_access_globals(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - eval_txt = '''globals()['global_variable'] = 22''' + eval_txt = """globals()['global_variable'] = 22""" evaluate_expression(None, frame, eval_txt, is_exec=True) - assert 'global_variable' not in frame.f_locals - assert 'global_variable' in frame.f_globals + assert "global_variable" not in frame.f_locals + assert "global_variable" in frame.f_globals check(next(iter(obtain_frame()))) - assert 'global_variable' in sys._getframe().f_globals - assert 'global_variable' not in sys._getframe().f_locals + assert "global_variable" in sys._getframe().f_globals + assert "global_variable" not in sys._getframe().f_locals def test_evaluate_expression_create_none(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - eval_txt = 'x = None' + eval_txt = "x = None" evaluate_expression(None, frame, eval_txt, is_exec=True) - assert 'x' in frame.f_locals - assert 'x' not in frame.f_globals + assert "x" in frame.f_locals + assert "x" not in frame.f_globals check(next(iter(obtain_frame()))) @@ -152,13 +153,13 @@ def test_evaluate_expression_delete_var(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - eval_txt = 'x = 22' + eval_txt = "x = 22" evaluate_expression(None, frame, eval_txt, is_exec=True) - assert 'x' in frame.f_locals + assert "x" in frame.f_locals - eval_txt = 'del x' + eval_txt = "del x" evaluate_expression(None, frame, eval_txt, is_exec=True) - assert 'x' not in frame.f_locals + assert "x" not in frame.f_locals check(next(iter(obtain_frame()))) @@ -167,16 +168,15 @@ def test_evaluate_expression_5(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression def check(frame): - eval_txt = 'A, B = 5, 6' + eval_txt = "A, B = 5, 6" evaluate_expression(None, frame, eval_txt, is_exec=True) - assert frame.f_locals['A'] == 5 - assert frame.f_locals['B'] == 6 + assert frame.f_locals["A"] == 5 + assert frame.f_locals["B"] == 6 check(next(iter(obtain_frame()))) class _DummyPyDB(object): - def __init__(self): self.created_pydb_daemon_threads = {} self.timeout_tracker = NULL @@ -185,12 +185,13 @@ def __init__(self): try: from ast import PyCF_ALLOW_TOP_LEVEL_AWAIT # @UnusedImport + CAN_EVALUATE_TOP_LEVEL_ASYNC = True except: CAN_EVALUATE_TOP_LEVEL_ASYNC = False -@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason='Requires top-level async evaluation.') +@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason="Requires top-level async evaluation.") def test_evaluate_expression_async_exec(disable_critical_log): py_db = _DummyPyDB() @@ -199,18 +200,20 @@ async def async_call(a): async def main(): from _pydevd_bundle.pydevd_vars import evaluate_expression + a = 10 assert async_call is not None # Make sure it's in the locals. frame = sys._getframe() - eval_txt = 'y = await async_call(a)' + eval_txt = "y = await async_call(a)" evaluate_expression(py_db, frame, eval_txt, is_exec=True) - assert frame.f_locals['y'] == a + assert frame.f_locals["y"] == a import asyncio + asyncio.run(main()) -@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason='Requires top-level async evaluation.') +@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason="Requires top-level async evaluation.") def test_evaluate_expression_async_exec_as_eval(disable_critical_log): py_db = _DummyPyDB() @@ -219,10 +222,12 @@ async def async_call(a): async def main(): from _pydevd_bundle.pydevd_vars import evaluate_expression + assert async_call is not None # Make sure it's in the locals. frame = sys._getframe() - eval_txt = 'await async_call(10)' + eval_txt = "await async_call(10)" from io import StringIO + _original_stdout = sys.stdout try: stringio = sys.stdout = StringIO() @@ -231,34 +236,37 @@ async def main(): sys.stdout = _original_stdout # I.e.: Check that we printed the value obtained in the exec. - assert '10\n' in stringio.getvalue() + assert "10\n" in stringio.getvalue() import asyncio + asyncio.run(main()) -@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason='Requires top-level async evaluation.') +@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason="Requires top-level async evaluation.") def test_evaluate_expression_async_exec_error(disable_critical_log): py_db = _DummyPyDB() async def async_call(a): - raise RuntimeError('foobar') + raise RuntimeError("foobar") async def main(): from _pydevd_bundle.pydevd_vars import evaluate_expression + assert async_call is not None # Make sure it's in the locals. frame = sys._getframe() - eval_txt = 'y = await async_call(10)' + eval_txt = "y = await async_call(10)" with pytest.raises(RuntimeError) as e: evaluate_expression(py_db, frame, eval_txt, is_exec=True) - assert 'foobar' in str(e) - assert 'y' not in frame.f_locals + assert "foobar" in str(e) + assert "y" not in frame.f_locals import asyncio + asyncio.run(main()) -@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason='Requires top-level async evaluation.') +@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason="Requires top-level async evaluation.") def test_evaluate_expression_async_eval(disable_critical_log): py_db = _DummyPyDB() @@ -267,37 +275,41 @@ async def async_call(a): async def main(): from _pydevd_bundle.pydevd_vars import evaluate_expression + a = 10 assert async_call is not None # Make sure it's in the locals. frame = sys._getframe() - eval_txt = 'await async_call(a)' + eval_txt = "await async_call(a)" v = evaluate_expression(py_db, frame, eval_txt, is_exec=False) if isinstance(v, ExceptionOnEvaluate): raise v.result.with_traceback(v.tb) assert v == a import asyncio + asyncio.run(main()) -@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason='Requires top-level async evaluation.') +@pytest.mark.skipif(not CAN_EVALUATE_TOP_LEVEL_ASYNC, reason="Requires top-level async evaluation.") def test_evaluate_expression_async_eval_error(disable_critical_log): py_db = _DummyPyDB() async def async_call(a): - raise RuntimeError('foobar') + raise RuntimeError("foobar") async def main(): from _pydevd_bundle.pydevd_vars import evaluate_expression + a = 10 assert async_call is not None # Make sure it's in the locals. frame = sys._getframe() - eval_txt = 'await async_call(a)' + eval_txt = "await async_call(a)" v = evaluate_expression(py_db, frame, eval_txt, is_exec=False) assert isinstance(v, ExceptionOnEvaluate) - assert 'foobar' in str(v.result) + assert "foobar" in str(v.result) import asyncio + asyncio.run(main()) @@ -305,7 +317,6 @@ def test_evaluate_expression_name_mangling(disable_critical_log): from _pydevd_bundle.pydevd_vars import evaluate_expression class SomeObj(object): - def __init__(self): self.__value = 10 self.frame = sys._getframe() @@ -313,7 +324,7 @@ def __init__(self): obj = SomeObj() frame = obj.frame - eval_txt = '''self.__value''' + eval_txt = """self.__value""" v = evaluate_expression(None, frame, eval_txt, is_exec=False) if isinstance(v, ExceptionOnEvaluate): raise v.result.with_traceback(v.tb) diff --git a/tests_python/test_extract_token.py b/tests_python/test_extract_token.py index 94ca7272e..e58692c44 100644 --- a/tests_python/test_extract_token.py +++ b/tests_python/test_extract_token.py @@ -1,49 +1,47 @@ # coding: utf-8 from __future__ import unicode_literals -from _pydev_bundle._pydev_completer import (isidentifier, extract_token_and_qualifier, - TokenAndQualifier) +from _pydev_bundle._pydev_completer import isidentifier, extract_token_and_qualifier, TokenAndQualifier def test_isidentifier(): - assert isidentifier('abc') - assert not isidentifier('<') - assert not isidentifier('') - assert isidentifier('áéíóú') + assert isidentifier("abc") + assert not isidentifier("<") + assert not isidentifier("") + assert isidentifier("áéíóú") def test_extract_token_and_qualifier(): - - assert extract_token_and_qualifier('tok', 0, 0) == TokenAndQualifier('', '') - assert extract_token_and_qualifier('tok', 0, 1) == TokenAndQualifier('', 't') - assert extract_token_and_qualifier('tok', 0, 2) == TokenAndQualifier('', 'to') - assert extract_token_and_qualifier('tok', 0, 3) == TokenAndQualifier('', 'tok') - assert extract_token_and_qualifier('tok', 0, 4) == TokenAndQualifier('', 'tok') - - assert extract_token_and_qualifier('tok.qual', 0, 0) == TokenAndQualifier('', '') - assert extract_token_and_qualifier('tok.qual', 0, 1) == TokenAndQualifier('', 't') - assert extract_token_and_qualifier('tok.qual', 0, 2) == TokenAndQualifier('', 'to') - assert extract_token_and_qualifier('tok.qual', 0, 3) == TokenAndQualifier('', 'tok') - - assert extract_token_and_qualifier('tok.qual', 0, 4) == TokenAndQualifier('tok', '') - assert extract_token_and_qualifier('tok.qual', 0, 5) == TokenAndQualifier('tok', 'q') - assert extract_token_and_qualifier('tok.qual', 0, 6) == TokenAndQualifier('tok', 'qu') - assert extract_token_and_qualifier('tok.qual', 0, 7) == TokenAndQualifier('tok', 'qua') - assert extract_token_and_qualifier('tok.qual', 0, 8) == TokenAndQualifier('tok', 'qual') + assert extract_token_and_qualifier("tok", 0, 0) == TokenAndQualifier("", "") + assert extract_token_and_qualifier("tok", 0, 1) == TokenAndQualifier("", "t") + assert extract_token_and_qualifier("tok", 0, 2) == TokenAndQualifier("", "to") + assert extract_token_and_qualifier("tok", 0, 3) == TokenAndQualifier("", "tok") + assert extract_token_and_qualifier("tok", 0, 4) == TokenAndQualifier("", "tok") + + assert extract_token_and_qualifier("tok.qual", 0, 0) == TokenAndQualifier("", "") + assert extract_token_and_qualifier("tok.qual", 0, 1) == TokenAndQualifier("", "t") + assert extract_token_and_qualifier("tok.qual", 0, 2) == TokenAndQualifier("", "to") + assert extract_token_and_qualifier("tok.qual", 0, 3) == TokenAndQualifier("", "tok") + + assert extract_token_and_qualifier("tok.qual", 0, 4) == TokenAndQualifier("tok", "") + assert extract_token_and_qualifier("tok.qual", 0, 5) == TokenAndQualifier("tok", "q") + assert extract_token_and_qualifier("tok.qual", 0, 6) == TokenAndQualifier("tok", "qu") + assert extract_token_and_qualifier("tok.qual", 0, 7) == TokenAndQualifier("tok", "qua") + assert extract_token_and_qualifier("tok.qual", 0, 8) == TokenAndQualifier("tok", "qual") # out of range (column) - assert extract_token_and_qualifier('tok.qual.qual2', 0, 100) == TokenAndQualifier('tok.qual', 'qual2') + assert extract_token_and_qualifier("tok.qual.qual2", 0, 100) == TokenAndQualifier("tok.qual", "qual2") - assert extract_token_and_qualifier('t' + assert hit.name == "" writer.write_run_thread(hit.thread_id) @@ -271,11 +271,11 @@ def test_frame_eval_whitebox_test(case_setup_force_frame_eval): def test_frame_eval_change_breakpoints(case_setup_force_frame_eval): - with case_setup_force_frame_eval.test_file('_debugger_case_change_breaks.py') as writer: - break1_line = writer.get_line_index_with_content('break 1') - break2_line = writer.get_line_index_with_content('break 2') + with case_setup_force_frame_eval.test_file("_debugger_case_change_breaks.py") as writer: + break1_line = writer.get_line_index_with_content("break 1") + break2_line = writer.get_line_index_with_content("break 2") - break2_id = writer.write_add_breakpoint(break2_line, 'None') + break2_id = writer.write_add_breakpoint(break2_line, "None") writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(line=break2_line) @@ -287,7 +287,7 @@ def test_frame_eval_change_breakpoints(case_setup_force_frame_eval): assert hit.suspend_type == "frame_eval" writer.write_remove_breakpoint(break2_id) - writer.write_add_breakpoint(break1_line, 'None') + writer.write_add_breakpoint(break1_line, "None") writer.write_run_thread(hit.thread_id) hit = writer.wait_for_breakpoint_hit(line=break1_line) @@ -297,11 +297,10 @@ def test_frame_eval_change_breakpoints(case_setup_force_frame_eval): def test_generator_code_cache(case_setup_force_frame_eval): - - with case_setup_force_frame_eval.test_file('_debugger_case_yield_from.py') as writer: - break1_line = writer.get_line_index_with_content('break1') + with case_setup_force_frame_eval.test_file("_debugger_case_yield_from.py") as writer: + break1_line = writer.get_line_index_with_content("break1") writer.write_add_breakpoint(break1_line) - break2_line = writer.get_line_index_with_content('break2') + break2_line = writer.get_line_index_with_content("break2") writer.write_add_breakpoint(break2_line) writer.write_make_initial_run() @@ -327,9 +326,9 @@ def test_generator_code_cache(case_setup_force_frame_eval): def test_break_line_1(case_setup_force_frame_eval): - with case_setup_force_frame_eval.test_file('_debugger_case_yield_from.py') as writer: + with case_setup_force_frame_eval.test_file("_debugger_case_yield_from.py") as writer: break1_line = 1 - break1_id = writer.write_add_breakpoint(break1_line, 'None') + break1_id = writer.write_add_breakpoint(break1_line, "None") writer.write_make_initial_run() hit = writer.wait_for_breakpoint_hit(line=break1_line) diff --git a/tests_python/test_frame_evaluator.py b/tests_python/test_frame_evaluator.py index 472d04ab6..f8c7cf252 100644 --- a/tests_python/test_frame_evaluator.py +++ b/tests_python/test_frame_evaluator.py @@ -5,7 +5,9 @@ from tests_python.debug_constants import TEST_CYTHON from _pydevd_bundle.pydevd_constants import IS_PY311_OR_GREATER -pytestmark = pytest.mark.skipif(not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON or IS_PY311_OR_GREATER, reason='Requires CPython >= 3.6 < 3.11') +pytestmark = pytest.mark.skipif( + not IS_PY36_OR_GREATER or not IS_CPYTHON or not TEST_CYTHON or IS_PY311_OR_GREATER, reason="Requires CPython >= 3.6 < 3.11" +) def get_foo_frame(): @@ -14,14 +16,14 @@ def get_foo_frame(): class CheckClass(object): - def collect_info(self): from _pydevd_frame_eval import pydevd_frame_evaluator + thread_info = pydevd_frame_evaluator.get_thread_info_py() self.thread_info = thread_info -@pytest.mark.parametrize('_times', range(2)) +@pytest.mark.parametrize("_times", range(2)) def test_thread_info(_times): obj = CheckClass() obj.collect_info() @@ -49,15 +51,17 @@ def method(): def _custom_global_dbg(): from _pydevd_bundle.pydevd_constants import GlobalDebuggerHolder from pydevd import PyDB + curr = GlobalDebuggerHolder.global_dbg PyDB() # Will make itself current yield GlobalDebuggerHolder.global_dbg = curr -@pytest.mark.parametrize('_times', range(2)) +@pytest.mark.parametrize("_times", range(2)) def test_func_code_info(_times, _custom_global_dbg): from _pydevd_frame_eval import pydevd_frame_evaluator + # Must be called before get_func_code_info_py to initialize the _code_extra_index. thread_info = pydevd_frame_evaluator.get_thread_info_py() @@ -66,12 +70,12 @@ def test_func_code_info(_times, _custom_global_dbg): func_info2 = pydevd_frame_evaluator.get_func_code_info_py(thread_info, method(), method.__code__) assert func_info is func_info2 - some_func = eval('lambda:sys._getframe()') + some_func = eval("lambda:sys._getframe()") func_info3 = pydevd_frame_evaluator.get_func_code_info_py(thread_info, some_func(), some_func.__code__) del some_func del func_info3 - some_func = eval('lambda:sys._getframe()') + some_func = eval("lambda:sys._getframe()") pydevd_frame_evaluator.get_func_code_info_py(thread_info, some_func(), some_func.__code__) func_info = pydevd_frame_evaluator.get_func_code_info_py(thread_info, some_func(), some_func.__code__) assert pydevd_frame_evaluator.get_func_code_info_py(thread_info, some_func(), some_func.__code__) is func_info @@ -90,43 +94,43 @@ def method(): a = 3 breakpoint_found, new_code = generate_code_with_breakpoints_py( - method.__code__, - create_breakpoints_dict([method.__code__.co_firstlineno + 1, method.__code__.co_firstlineno + 2]) + method.__code__, create_breakpoints_dict([method.__code__.co_firstlineno + 1, method.__code__.co_firstlineno + 2]) ) assert breakpoint_found with pytest.raises(AssertionError): # We must use the cached one directly (in the real-world, this would indicate a reuse # of the code object -- which is related to generator handling). - generate_code_with_breakpoints_py( - new_code, - create_breakpoints_dict([method.__code__.co_firstlineno + 1]) - ) + generate_code_with_breakpoints_py(new_code, create_breakpoints_dict([method.__code__.co_firstlineno + 1])) cached_value = get_cached_code_obj_info_py(new_code) breakpoint_found, force_stay_in_untraced_mode = cached_value.compute_force_stay_in_untraced_mode( - create_breakpoints_dict([method.__code__.co_firstlineno + 1])) + create_breakpoints_dict([method.__code__.co_firstlineno + 1]) + ) assert breakpoint_found assert force_stay_in_untraced_mode # i.e.: no breakpoints match (stay in untraced mode) breakpoint_found, force_stay_in_untraced_mode = cached_value.compute_force_stay_in_untraced_mode( - create_breakpoints_dict([method.__code__.co_firstlineno + 10])) + create_breakpoints_dict([method.__code__.co_firstlineno + 10]) + ) assert not breakpoint_found assert force_stay_in_untraced_mode # i.e.: one of the breakpoints match (stay in untraced mode) breakpoint_found, force_stay_in_untraced_mode = cached_value.compute_force_stay_in_untraced_mode( - create_breakpoints_dict([method.__code__.co_firstlineno + 2])) + create_breakpoints_dict([method.__code__.co_firstlineno + 2]) + ) assert breakpoint_found assert force_stay_in_untraced_mode # i.e.: one of the breakpoints doesn't match (leave untraced mode) breakpoint_found, force_stay_in_untraced_mode = cached_value.compute_force_stay_in_untraced_mode( - create_breakpoints_dict([method.__code__.co_firstlineno + 3])) + create_breakpoints_dict([method.__code__.co_firstlineno + 3]) + ) assert breakpoint_found assert not force_stay_in_untraced_mode diff --git a/tests_python/test_frame_utils.py b/tests_python/test_frame_utils.py index afac45452..289bfc7bc 100644 --- a/tests_python/test_frame_utils.py +++ b/tests_python/test_frame_utils.py @@ -6,21 +6,20 @@ def test_create_frames_list_from_traceback(): - def method(): - raise RuntimeError('first') + raise RuntimeError("first") def method1(): try: method() except Exception as e: - raise RuntimeError('second') from e + raise RuntimeError("second") from e def method2(): try: method1() except Exception as e: - raise RuntimeError('third') from e + raise RuntimeError("third") from e try: method2() @@ -29,16 +28,18 @@ def method2(): frame = sys._getframe() from _pydevd_bundle.pydevd_frame_utils import create_frames_list_from_traceback + frames_list = create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, exception_type=EXCEPTION_TYPE_USER_UNHANDLED) - assert str(frames_list.exc_desc) == 'third' - assert str(frames_list.chained_frames_list.exc_desc) == 'second' - assert str(frames_list.chained_frames_list.chained_frames_list.exc_desc) == 'first' + assert str(frames_list.exc_desc) == "third" + assert str(frames_list.chained_frames_list.exc_desc) == "second" + assert str(frames_list.chained_frames_list.chained_frames_list.exc_desc) == "first" assert frames_list.chained_frames_list.chained_frames_list.chained_frames_list is None if IS_PY311_OR_GREATER: import traceback - _byte_offset_to_character_offset = getattr(traceback, '_byte_offset_to_character_offset', None) + + _byte_offset_to_character_offset = getattr(traceback, "_byte_offset_to_character_offset", None) if _byte_offset_to_character_offset is not None: _original = traceback._byte_offset_to_character_offset @@ -46,54 +47,37 @@ def _byte_offset_to_character_offset(*args, **kwargs): try: return _original(*args, **kwargs) except: - # Replacement to deal with the buggy version released on Python 3.11.0. def replacement(str, offset): - as_utf8 = str.encode('utf-8') + as_utf8 = str.encode("utf-8") if offset > len(as_utf8): offset = len(as_utf8) - return len(as_utf8[:offset + 1].decode("utf-8", 'replace')) + return len(as_utf8[: offset + 1].decode("utf-8", "replace")) - return replacement(*args , **kwargs) + return replacement(*args, **kwargs) traceback._byte_offset_to_character_offset = _byte_offset_to_character_offset _USE_UNICODE = [False, True] -@pytest.mark.parametrize('use_unicode', _USE_UNICODE) -@pytest.mark.skipif(not IS_PY311_OR_GREATER, reason='Python 3.11 required.') +@pytest.mark.parametrize("use_unicode", _USE_UNICODE) +@pytest.mark.skipif(not IS_PY311_OR_GREATER, reason="Python 3.11 required.") def test_collect_anchors_subscript(use_unicode): from _pydevd_bundle.pydevd_frame_utils import create_frames_list_from_traceback if use_unicode: def method(): - d = { - "x": { - "á": { - "í": { - "theta": 1 - } - } - } - } + d = {"x": {"á": {"í": {"theta": 1}}}} result = d["x"]["á"]["í"]["beta"] else: def method(): - d = { - "x": { - "y": { - "i": { - "theta": 1 - } - } - } - } + d = {"x": {"y": {"i": {"theta": 1}}}} result = d["x"]["y"]["i"]["beta"] @@ -106,7 +90,7 @@ def method(): frames_list = create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, memo) iter_in = iter(frames_list) f = next(iter_in) - assert f.f_code.co_name == 'method' + assert f.f_code.co_name == "method" line_col_info = frames_list.frame_id_to_line_col_info[id(f)] if use_unicode: @@ -135,8 +119,8 @@ def method(): assert endcol == len(line) -@pytest.mark.parametrize('use_unicode', _USE_UNICODE) -@pytest.mark.skipif(not IS_PY311_OR_GREATER, reason='Python 3.11 required.') +@pytest.mark.parametrize("use_unicode", _USE_UNICODE) +@pytest.mark.skipif(not IS_PY311_OR_GREATER, reason="Python 3.11 required.") def test_collect_anchors_binop_1(use_unicode): from _pydevd_bundle.pydevd_frame_utils import create_frames_list_from_traceback @@ -167,15 +151,15 @@ def method(): frames_list = create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, memo) iter_in = iter(frames_list) f = next(iter_in) - assert f.f_code.co_name == 'method' + assert f.f_code.co_name == "method" line_col_info = frames_list.frame_id_to_line_col_info[id(f)] if use_unicode: - line = ' result = á + í + c' - expected_index = line.index('á + í') + line = " result = á + í + c" + expected_index = line.index("á + í") else: - line = ' result = a + b + c' - expected_index = line.index('a + b') + line = " result = a + b + c" + expected_index = line.index("a + b") assert line_col_info.colno == expected_index @@ -188,12 +172,12 @@ def method(): original_line = line col, endcol = line_col_info.map_columns_to_line(original_line) - assert col == line.index('+ c') + assert col == line.index("+ c") assert endcol == col + 1 -@pytest.mark.parametrize('use_unicode', _USE_UNICODE) -@pytest.mark.skipif(not IS_PY311_OR_GREATER, reason='Python 3.11 required.') +@pytest.mark.parametrize("use_unicode", _USE_UNICODE) +@pytest.mark.skipif(not IS_PY311_OR_GREATER, reason="Python 3.11 required.") def test_collect_anchors_binop_2(use_unicode): from _pydevd_bundle.pydevd_frame_utils import create_frames_list_from_traceback @@ -224,28 +208,28 @@ def method(): frames_list = create_frames_list_from_traceback(trace_obj, frame, exc_type, exc_desc, memo) iter_in = iter(frames_list) f = next(iter_in) - assert f.f_code.co_name == 'method' + assert f.f_code.co_name == "method" line_col_info = frames_list.frame_id_to_line_col_info[id(f)] if use_unicode: - line = ' result = á + c + í' - expected_index = line.index('á + c') + line = " result = á + c + í" + expected_index = line.index("á + c") else: - line = ' result = a + c + b' - expected_index = line.index('a + c') + line = " result = a + c + b" + expected_index = line.index("a + c") assert line_col_info.colno == expected_index # It's +2 here due to the á and í unicode chars (we need to convert from the bytes # index to the actual character in the string to get the actual col). if use_unicode: - assert line_col_info.end_colno == line.index('c + í') + 2 + assert line_col_info.end_colno == line.index("c + í") + 2 else: - assert line_col_info.end_colno == line.index('c + b') + 1 + assert line_col_info.end_colno == line.index("c + b") + 1 original_line = line col, endcol = line_col_info.map_columns_to_line(original_line) assert col == 23 assert endcol == 24 - assert col == line.index('+ c') + assert col == line.index("+ c") assert endcol == col + 1 diff --git a/tests_python/test_null.py b/tests_python/test_null.py index f09da7b71..54c2ce4fc 100644 --- a/tests_python/test_null.py +++ b/tests_python/test_null.py @@ -1,8 +1,9 @@ def test_null(): from _pydevd_bundle.pydevd_constants import Null + null = Null() assert not null assert len(null) == 0 - + with null as n: - n.write('foo') \ No newline at end of file + n.write("foo") diff --git a/tests_python/test_process_command_line.py b/tests_python/test_process_command_line.py index 8932630a6..4f4656ea7 100644 --- a/tests_python/test_process_command_line.py +++ b/tests_python/test_process_command_line.py @@ -1,28 +1,30 @@ import unittest -class Test(unittest.TestCase): +class Test(unittest.TestCase): 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'] + + 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') or argv[0].endswith('pydevd$py.class'), 'Expected: %s to end with pydevd.py' % (argv[0],) + assert argv[0].endswith("pydevd.py") or argv[0].endswith("pydevd$py.class"), "Expected: %s to end with pydevd.py" % (argv[0],) argv = argv[1:] - assert argv == ['--port', '1', '--save-threading'] + assert argv == ["--port", "1", "--save-threading"] def testProcessCommandLine2(self): from _pydevd_bundle.pydevd_command_line_handling import process_command_line, setup_to_argv - setup = process_command_line(['pydevd.py', '--port', '1', '--qt-support=auto']) - assert setup['qt-support'] == 'auto' - setup = process_command_line(['pydevd.py', '--port', '1', '--qt-support']) - assert setup['qt-support'] == 'auto' + setup = process_command_line(["pydevd.py", "--port", "1", "--qt-support=auto"]) + assert setup["qt-support"] == "auto" + + setup = process_command_line(["pydevd.py", "--port", "1", "--qt-support"]) + assert setup["qt-support"] == "auto" - setup = process_command_line(['pydevd.py', '--port', '1', '--qt-support=pyqt4']) - assert setup['qt-support'] == 'pyqt4' + setup = process_command_line(["pydevd.py", "--port", "1", "--qt-support=pyqt4"]) + assert setup["qt-support"] == "pyqt4" - self.assertRaises(ValueError, process_command_line, ['pydevd.py', '--port', '1', '--qt-support=wrong']) + self.assertRaises(ValueError, process_command_line, ["pydevd.py", "--port", "1", "--qt-support=wrong"]) diff --git a/tests_python/test_pydev_monkey.py b/tests_python/test_pydev_monkey.py index db3b2068e..b87e66ccb 100644 --- a/tests_python/test_pydev_monkey.py +++ b/tests_python/test_pydev_monkey.py @@ -23,29 +23,30 @@ def save_setup_holder(): def test_monkey(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True} - check = '''C:\\bin\\python.exe -u -c connect(\\"127.0.0.1\\")''' + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True} + check = """C:\\bin\\python.exe -u -c connect(\\"127.0.0.1\\")""" debug_command = ( - 'import sys; ' - 'sys.path.insert(0, r\'%s\'); ' + "import sys; " + "sys.path.insert(0, r'%s'); " "import pydevd; pydevd.config('quoted-line', ''); " "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, " - 'trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command - assert 'C:\\bin\\python.exe -u -c %s' % debug_command == pydev_monkey.patch_arg_str_win(check) + assert "C:\\bin\\python.exe -u -c %s" % debug_command == pydev_monkey.patch_arg_str_win(check) def test_str_to_args_windows(): - assert ['a', 'b'] == pydev_monkey.str_to_args_windows('a "b"') + assert ["a", "b"] == pydev_monkey.str_to_args_windows('a "b"') def test_monkey_patch_return_original_args(): - check = ['echo', '"my"', '"args"'] + check = ["echo", '"my"', '"args"'] res = pydev_monkey.patch_args(check[:]) assert res == check @@ -54,9 +55,9 @@ def test_monkey_patch_pathlib_args(): try: import pathlib except ImportError: - pytest.skip('pathlib not available.') + pytest.skip("pathlib not available.") - check = [pathlib.Path('echo'), '"my"', '"args"'] + check = [pathlib.Path("echo"), '"my"', '"args"'] res = pydev_monkey.patch_args(check[:]) assert res == check @@ -68,7 +69,7 @@ def test_monkey_patch_wrong_object_type(): def test_monkey_patch_wrong_object_type_2(): - check = ['C:\\bin\\python.exe', '-u', 1, '-qcconnect("127.0.0.1")'] + check = ["C:\\bin\\python.exe", "-u", 1, '-qcconnect("127.0.0.1")'] res = pydev_monkey.patch_args(check[:]) assert res == check @@ -77,450 +78,413 @@ def test_monkey_patch_args_module_subprocess_pathlib(): try: import pathlib except ImportError: - pytest.skip('pathlib not available.') + pytest.skip("pathlib not available.") - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True} - if sys.platform == 'win32': - python_path = 'C:\\bin\\python.exe' + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "multiprocess": True} + if sys.platform == "win32": + python_path = "C:\\bin\\python.exe" else: - python_path = '/bin/python' - check = [pathlib.Path(python_path), '-mtest', pathlib.Path('bar')] + python_path = "/bin/python" + check = [pathlib.Path(python_path), "-mtest", pathlib.Path("bar")] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file + assert pydev_monkey.patch_args(check) == [ python_path, get_pydevd_file(), - '--module', - '--port', - '0', - '--ppid', + "--module", + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--multiprocess', - '--protocol-quoted-line', - '--file', - 'test', - 'bar', + "--client", + "127.0.0.1", + "--multiprocess", + "--protocol-quoted-line", + "--file", + "test", + "bar", ] def test_monkey_patch_args_indc(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-u', '-c', 'connect("127.0.0.1")'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-u", "-c", 'connect("127.0.0.1")'] debug_command = ( - "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-u', - '-c', - debug_command - ] + assert res == ["C:\\bin\\python.exe", "-u", "-c", debug_command] def test_separate_future_imports(): - found = pydev_monkey._separate_future_imports('''from __future__ import print_function\nprint(1)''') - assert found == ('from __future__ import print_function;', '\nprint(1)') + found = pydev_monkey._separate_future_imports("""from __future__ import print_function\nprint(1)""") + assert found == ("from __future__ import print_function;", "\nprint(1)") - found = pydev_monkey._separate_future_imports('''from __future__ import print_function;print(1)''') - assert found == ('from __future__ import print_function;', 'print(1)') + found = pydev_monkey._separate_future_imports("""from __future__ import print_function;print(1)""") + assert found == ("from __future__ import print_function;", "print(1)") - found = pydev_monkey._separate_future_imports('''from __future__ import (\nprint_function);print(1)''') - assert found == ('from __future__ import (\nprint_function);', 'print(1)') + found = pydev_monkey._separate_future_imports("""from __future__ import (\nprint_function);print(1)""") + assert found == ("from __future__ import (\nprint_function);", "print(1)") - found = pydev_monkey._separate_future_imports('''"line";from __future__ import (\n\nprint_function, absolute_imports\n);print(1)''') - assert found == ('"line";from __future__ import (\n\nprint_function, absolute_imports\n);', 'print(1)') + found = pydev_monkey._separate_future_imports(""""line";from __future__ import (\n\nprint_function, absolute_imports\n);print(1)""") + assert found == ('"line";from __future__ import (\n\nprint_function, absolute_imports\n);', "print(1)") - found = pydev_monkey._separate_future_imports('''from __future__ import bar\nfrom __future__ import (\n\nprint_function, absolute_imports\n);print(1)''') - assert found == ('from __future__ import bar\nfrom __future__ import (\n\nprint_function, absolute_imports\n);', 'print(1)') + found = pydev_monkey._separate_future_imports( + """from __future__ import bar\nfrom __future__ import (\n\nprint_function, absolute_imports\n);print(1)""" + ) + assert found == ("from __future__ import bar\nfrom __future__ import (\n\nprint_function, absolute_imports\n);", "print(1)") def test_monkey_patch_args_indc_future_import(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-u', '-c', 'from __future__ import print_function;connect("127.0.0.1")'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-u", "-c", 'from __future__ import print_function;connect("127.0.0.1")'] debug_command = ( - "from __future__ import print_function;import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "from __future__ import print_function;import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-u', - '-c', - debug_command - ] + assert res == ["C:\\bin\\python.exe", "-u", "-c", debug_command] def test_monkey_patch_args_indc_future_import2(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-u', '-c', 'from __future__ import print_function\nconnect("127.0.0.1")'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-u", "-c", 'from __future__ import print_function\nconnect("127.0.0.1")'] debug_command = ( - "from __future__ import print_function;import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - '\nconnect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "from __future__ import print_function;import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + '\nconnect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-u', - '-c', - debug_command - ] + assert res == ["C:\\bin\\python.exe", "-u", "-c", debug_command] def test_monkey_patch_args_indc2(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-u', '-qcconnect("127.0.0.1")'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-u", '-qcconnect("127.0.0.1")'] debug_command = ( - "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-u', - '-qc', - debug_command - ] + assert res == ["C:\\bin\\python.exe", "-u", "-qc", debug_command] def test_monkey_patch_args_x_flag(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-X', 'faulthandler', '-c', 'connect("127.0.0.1")'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-X", "faulthandler", "-c", 'connect("127.0.0.1")'] debug_command = ( - "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-X', - 'faulthandler', - '-c', - debug_command - ] + assert res == ["C:\\bin\\python.exe", "-X", "faulthandler", "-c", debug_command] def test_monkey_patch_args_flag_in_single_arg_1(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-qX', 'faulthandler', '-c', 'connect("127.0.0.1")'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-qX", "faulthandler", "-c", 'connect("127.0.0.1")'] debug_command = ( - "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-qX', - 'faulthandler', - '-c', - debug_command - ] + assert res == ["C:\\bin\\python.exe", "-qX", "faulthandler", "-c", debug_command] def test_monkey_patch_args_flag_in_single_arg_2(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-qX', 'faulthandler', '-c', 'connect("127.0.0.1")'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-qX", "faulthandler", "-c", 'connect("127.0.0.1")'] debug_command = ( - "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-qX', - 'faulthandler', - '-c', - debug_command - ] + assert res == ["C:\\bin\\python.exe", "-qX", "faulthandler", "-c", debug_command] def test_monkey_patch_args_flag_in_single_arg_3(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-qc', 'connect("127.0.0.1")'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-qc", 'connect("127.0.0.1")'] debug_command = ( - "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-qc', - debug_command - ] + assert res == ["C:\\bin\\python.exe", "-qc", debug_command] def test_monkey_patch_args_x_flag_inline(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-Xfaulthandler', '-c', 'connect("127.0.0.1")', 'arg1'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-Xfaulthandler", "-c", 'connect("127.0.0.1")', "arg1"] debug_command = ( - "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-Xfaulthandler', - '-c', - debug_command, - 'arg1' - ] + assert res == ["C:\\bin\\python.exe", "-Xfaulthandler", "-c", debug_command, "arg1"] def test_monkey_patch_args_c_flag_inline(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'ppid': os.getpid(), 'protocol-quoted-line': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-X', 'faulthandler', '-cconnect("127.0.0.1")', 'arg1'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "ppid": os.getpid(), "protocol-quoted-line": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-X", "faulthandler", '-cconnect("127.0.0.1")', "arg1"] debug_command = ( - "import sys; sys.path.insert(0, r\'%s\'); import pydevd; pydevd.config('quoted-line', ''); " - 'pydevd.settrace(host=\'127.0.0.1\', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); ' - '' - 'connect("127.0.0.1")') % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) + "import sys; sys.path.insert(0, r'%s'); import pydevd; pydevd.config('quoted-line', ''); " + "pydevd.settrace(host='127.0.0.1', port=0, suspend=False, trace_only_current_thread=False, patch_multiprocessing=True, access_token=None, client_access_token=None, __setup_holder__=%s); " + "" + 'connect("127.0.0.1")' + ) % (pydev_src_dir, sorted_dict_repr(SetupHolder.setup)) if sys.platform == "win32": debug_command = debug_command.replace('"', '\\"') debug_command = '"%s"' % debug_command res = pydev_monkey.patch_args(check) - assert res == [ - 'C:\\bin\\python.exe', - '-X', - 'faulthandler', - '-c', - debug_command, - 'arg1' - ] + assert res == ["C:\\bin\\python.exe", "-X", "faulthandler", "-c", debug_command, "arg1"] def test_monkey_patch_args_module(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-m', 'test'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "multiprocess": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-m", "test"] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file + assert pydev_monkey.patch_args(check) == [ - 'C:\\bin\\python.exe', + "C:\\bin\\python.exe", get_pydevd_file(), - '--module', - '--port', - '0', - '--ppid', + "--module", + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--multiprocess', - '--skip-notify-stdin', - '--protocol-quoted-line', - '--file', - 'test', + "--client", + "127.0.0.1", + "--multiprocess", + "--skip-notify-stdin", + "--protocol-quoted-line", + "--file", + "test", ] def test_monkey_patch_args_unbuffered_module(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-u', '-m', 'test'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "multiprocess": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-u", "-m", "test"] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file + assert pydev_monkey.patch_args(check) == [ - 'C:\\bin\\python.exe', - '-u', + "C:\\bin\\python.exe", + "-u", get_pydevd_file(), - '--module', - '--port', - '0', - '--ppid', + "--module", + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--multiprocess', - '--skip-notify-stdin', - '--protocol-quoted-line', - '--file', - 'test', + "--client", + "127.0.0.1", + "--multiprocess", + "--skip-notify-stdin", + "--protocol-quoted-line", + "--file", + "test", ] def test_monkey_patch_args_module_inline(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-qOmtest'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "multiprocess": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-qOmtest"] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file + assert pydev_monkey.patch_args(check) == [ - 'C:\\bin\\python.exe', - '-qO', + "C:\\bin\\python.exe", + "-qO", get_pydevd_file(), - '--module', - '--port', - '0', - '--ppid', + "--module", + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--multiprocess', - '--skip-notify-stdin', - '--protocol-quoted-line', - '--file', - 'test', + "--client", + "127.0.0.1", + "--multiprocess", + "--skip-notify-stdin", + "--protocol-quoted-line", + "--file", + "test", ] def test_monkey_patch_args_module_inline2(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True, 'skip-notify-stdin': True} - check = ['C:\\bin\\python.exe', '-qOm', 'test'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "multiprocess": True, "skip-notify-stdin": True} + check = ["C:\\bin\\python.exe", "-qOm", "test"] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file + assert pydev_monkey.patch_args(check) == [ - 'C:\\bin\\python.exe', - '-qO', + "C:\\bin\\python.exe", + "-qO", get_pydevd_file(), - '--module', - '--port', - '0', - '--ppid', + "--module", + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--multiprocess', - '--skip-notify-stdin', - '--protocol-quoted-line', - '--file', - 'test', + "--client", + "127.0.0.1", + "--multiprocess", + "--skip-notify-stdin", + "--protocol-quoted-line", + "--file", + "test", ] def test_monkey_patch_args_no_indc(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0'} - check = ['C:\\bin\\python.exe', 'connect(\\"127.0.0.1\\")', 'with spaces'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0"} + check = ["C:\\bin\\python.exe", 'connect(\\"127.0.0.1\\")', "with spaces"] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file + assert pydev_monkey.patch_args(check) == [ - 'C:\\bin\\python.exe', + "C:\\bin\\python.exe", get_pydevd_file(), - '--port', - '0', - '--ppid', + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--protocol-quoted-line', - '--file', - '"connect(\\\\\\"127.0.0.1\\\\\\")"' if sys.platform == 'win32' else 'connect(\\"127.0.0.1\\")', - '"with spaces"' if sys.platform == 'win32' else 'with spaces', + "--client", + "127.0.0.1", + "--protocol-quoted-line", + "--file", + '"connect(\\\\\\"127.0.0.1\\\\\\")"' if sys.platform == "win32" else 'connect(\\"127.0.0.1\\")', + '"with spaces"' if sys.platform == "win32" else "with spaces", ] def test_monkey_patch_args_no_indc_with_pydevd(): - 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"] - assert pydev_monkey.patch_args(check) == [ - 'C:\\bin\\python.exe', 'pydevd.py', 'connect(\\"127.0.0.1\\")', 'bar'] + assert pydev_monkey.patch_args(check) == ["C:\\bin\\python.exe", "pydevd.py", 'connect(\\"127.0.0.1\\")', "bar"] def test_monkey_patch_args_no_indc_without_pydevd(): from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file - 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"] assert pydev_monkey.patch_args(check) == [ - 'C:\\bin\\python.exe', + "C:\\bin\\python.exe", get_pydevd_file(), - '--port', - '0', - '--ppid', + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--protocol-quoted-line', - '--file', - 'target.py', - '"connect(\\\\\\"127.0.0.1\\\\\\")"' if sys.platform == 'win32' else 'connect(\\"127.0.0.1\\")', - 'bar', + "--client", + "127.0.0.1", + "--protocol-quoted-line", + "--file", + "target.py", + '"connect(\\\\\\"127.0.0.1\\\\\\")"' if sys.platform == "win32" else 'connect(\\"127.0.0.1\\")', + "bar", ] -@pytest.mark.parametrize('use_bytes', [True, False]) +@pytest.mark.parametrize("use_bytes", [True, False]) def test_monkey_patch_c_program_arg(use_bytes): from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'module': 'ignore.this'} - check = ['C:\\bin\\python.exe', '-u', 'target.py', '-c', '-áéíóú'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "module": "ignore.this"} + check = ["C:\\bin\\python.exe", "-u", "target.py", "-c", "-áéíóú"] - encode = lambda s:s + encode = lambda s: s if use_bytes: - check = [c.encode('utf-8') for c in check] - encode = lambda s:s.encode('utf-8') + check = [c.encode("utf-8") for c in check] + encode = lambda s: s.encode("utf-8") assert pydev_monkey.patch_args(check) == [ - encode('C:\\bin\\python.exe'), - encode('-u'), + encode("C:\\bin\\python.exe"), + encode("-u"), get_pydevd_file(), - '--port', - '0', - '--ppid', + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--protocol-quoted-line', - '--file', - encode('target.py'), - encode('-c'), - encode('-áéíóú') + "--client", + "127.0.0.1", + "--protocol-quoted-line", + "--file", + encode("target.py"), + encode("-c"), + encode("-áéíóú"), ] def test_monkey_patch_args_module_single_arg(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True, 'module': 'ignore.this'} - check = ['C:\\bin\\python.exe', '-mtest', 'bar'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "multiprocess": True, "module": "ignore.this"} + check = ["C:\\bin\\python.exe", "-mtest", "bar"] from _pydevd_bundle.pydevd_command_line_handling import get_pydevd_file + assert pydev_monkey.patch_args(check) == [ - 'C:\\bin\\python.exe', + "C:\\bin\\python.exe", get_pydevd_file(), - '--module', - '--port', - '0', - '--ppid', + "--module", + "--port", + "0", + "--ppid", str(os.getpid()), - '--client', - '127.0.0.1', - '--multiprocess', - '--protocol-quoted-line', - '--file', - 'test', - 'bar', + "--client", + "127.0.0.1", + "--multiprocess", + "--protocol-quoted-line", + "--file", + "test", + "bar", ] def test_monkey_patch_args_stdin(): - SetupHolder.setup = {'client': '127.0.0.1', 'port': '0', 'multiprocess': True, 'module': 'ignore.this'} - check = ['C:\\bin\\python.exe', '-Xfaulthandler' , '-'] + SetupHolder.setup = {"client": "127.0.0.1", "port": "0", "multiprocess": True, "module": "ignore.this"} + check = ["C:\\bin\\python.exe", "-Xfaulthandler", "-"] # i.e.: we don't deal with the stdin. assert pydev_monkey.patch_args(check) == check diff --git a/tests_python/test_pydevcoverage.py b/tests_python/test_pydevcoverage.py index 353027d0a..40865b7c7 100644 --- a/tests_python/test_pydevcoverage.py +++ b/tests_python/test_pydevcoverage.py @@ -6,9 +6,9 @@ import unittest -#======================================================================================================================= +# ======================================================================================================================= # Test -#======================================================================================================================= +# ======================================================================================================================= class Test(unittest.TestCase): """ Unittest for pydev_coverage.py. @@ -26,20 +26,19 @@ def setUp(self): def _do_analyze(self, files): invalid_files = [] - p = subprocess.Popen([sys.executable, self._coverage_file, "--pydev-analyze"], - stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) + p = subprocess.Popen( + [sys.executable, self._coverage_file, "--pydev-analyze"], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE + ) __, stderrdata = p.communicate("|".join(files).encode()) if stderrdata: - match = re.search("Invalid files not passed to coverage: (.*?)$", - stderrdata.decode(), re.M) # @UndefinedVariable + match = re.search("Invalid files not passed to coverage: (.*?)$", stderrdata.decode(), re.M) # @UndefinedVariable if match: invalid_files = [f.strip() for f in match.group(1).split(",")] return invalid_files def test_pydev_analyze_ok(self): - ref_valid_files = [__file__, - os.path.join(self._resources_path, "_debugger_case18.py")] + ref_valid_files = [__file__, os.path.join(self._resources_path, "_debugger_case18.py")] ref_invalid_files = [] invalid_files = self._do_analyze(ref_valid_files) @@ -47,9 +46,7 @@ def test_pydev_analyze_ok(self): self.assertEqual(ref_invalid_files, invalid_files) def test_pydev_analyse_non_standard_encoding(self): - ref_valid_files = [os.path.join(self._resources_path, - "_pydev_coverage_cyrillic_encoding_py%i.py" - % sys.version_info[0])] + ref_valid_files = [os.path.join(self._resources_path, "_pydev_coverage_cyrillic_encoding_py%i.py" % sys.version_info[0])] ref_invalid_files = [] invalid_files = self._do_analyze(ref_valid_files + ref_invalid_files) @@ -59,9 +56,7 @@ def test_pydev_analyse_non_standard_encoding(self): def test_pydev_analyse_invalid_files(self): with tempfile.NamedTemporaryFile(suffix=".pyx") as pyx_file: ref_valid_files = [] - ref_invalid_files = [os.path.join(self._resources_path, - "_pydev_coverage_syntax_error.py"), - pyx_file.name] + ref_invalid_files = [os.path.join(self._resources_path, "_pydev_coverage_syntax_error.py"), pyx_file.name] invalid_files = self._do_analyze(ref_valid_files + ref_invalid_files) diff --git a/tests_python/test_pydevd_api.py b/tests_python/test_pydevd_api.py index 2f27530bd..92f70907b 100644 --- a/tests_python/test_pydevd_api.py +++ b/tests_python/test_pydevd_api.py @@ -2,34 +2,58 @@ import sys -@pytest.mark.skipif(sys.platform != 'win32', reason='Windows-only test.') +@pytest.mark.skipif(sys.platform != "win32", reason="Windows-only test.") def test_pydevd_api_breakpoints(tmpdir): from _pydevd_bundle.pydevd_api import PyDevdAPI from pydevd import PyDB import pydevd_file_utils + api = PyDevdAPI() py_db = PyDB(set_as_global=False) - dira = tmpdir.join('DirA') + dira = tmpdir.join("DirA") dira.mkdir() - f = dira.join('filE.py') - f.write_text(''' + f = dira.join("filE.py") + f.write_text( + """ a = 1 b = 2 c = 3 -''', 'utf-8') +""", + "utf-8", + ) filename = str(f) result = api.add_breakpoint( - py_db, filename, breakpoint_type='python-line', breakpoint_id=0, line=1, condition=None, func_name='None', - expression=None, suspend_policy="NONE", hit_condition='', is_logpoint=False) + py_db, + filename, + breakpoint_type="python-line", + breakpoint_id=0, + line=1, + condition=None, + func_name="None", + expression=None, + suspend_policy="NONE", + hit_condition="", + is_logpoint=False, + ) assert not result.error_code result = api.add_breakpoint( - py_db, filename, breakpoint_type='python-line', breakpoint_id=1, line=2, condition=None, func_name='None', - expression=None, suspend_policy="NONE", hit_condition='', is_logpoint=False) + py_db, + filename, + breakpoint_type="python-line", + breakpoint_id=1, + line=2, + condition=None, + func_name="None", + expression=None, + suspend_policy="NONE", + hit_condition="", + is_logpoint=False, + ) assert not result.error_code canonical_path = pydevd_file_utils.canonical_normalized_path(filename) @@ -37,7 +61,7 @@ def test_pydevd_api_breakpoints(tmpdir): assert len(py_db.breakpoints[canonical_path]) == 2 assert len(py_db.file_to_id_to_line_breakpoint[canonical_path]) == 2 - filename_replaced = filename.replace('DirA', 'dira') + filename_replaced = filename.replace("DirA", "dira") api.remove_all_breakpoints(py_db, filename_replaced) assert not py_db.breakpoints assert not py_db.file_to_id_to_line_breakpoint diff --git a/tests_python/test_pydevd_filtering.py b/tests_python/test_pydevd_filtering.py index 6bf57721f..460dfa8a0 100644 --- a/tests_python/test_pydevd_filtering.py +++ b/tests_python/test_pydevd_filtering.py @@ -3,62 +3,62 @@ def test_in_project_roots_prefix_01(tmpdir): from _pydevd_bundle.pydevd_filtering import FilesFiltering + files_filtering = FilesFiltering() - another = str(tmpdir.join('another')) - assert not another.endswith('/') and not another.endswith('\\') + another = str(tmpdir.join("another")) + assert not another.endswith("/") and not another.endswith("\\") files_filtering.set_library_roots([another]) files_filtering.set_project_roots([]) - assert not files_filtering.in_project_roots(another + '/f.py') + assert not files_filtering.in_project_roots(another + "/f.py") if IS_WINDOWS: - assert not files_filtering.in_project_roots(another + '\\f.py') + assert not files_filtering.in_project_roots(another + "\\f.py") else: - assert files_filtering.in_project_roots(another + '\\f.py') + assert files_filtering.in_project_roots(another + "\\f.py") - assert files_filtering.in_project_roots(another + 'f.py') + assert files_filtering.in_project_roots(another + "f.py") def test_in_project_roots_prefix_02(tmpdir): from _pydevd_bundle.pydevd_filtering import FilesFiltering + files_filtering = FilesFiltering() - another = str(tmpdir.join('another')) - assert not another.endswith('/') and not another.endswith('\\') + another = str(tmpdir.join("another")) + assert not another.endswith("/") and not another.endswith("\\") files_filtering.set_library_roots([]) files_filtering.set_project_roots([another]) - assert files_filtering.in_project_roots(another + '/f.py') + assert files_filtering.in_project_roots(another + "/f.py") if IS_WINDOWS: - assert files_filtering.in_project_roots(another + '\\f.py') + assert files_filtering.in_project_roots(another + "\\f.py") else: - assert not files_filtering.in_project_roots(another + '\\f.py') + assert not files_filtering.in_project_roots(another + "\\f.py") - assert not files_filtering.in_project_roots(another + 'f.py') + assert not files_filtering.in_project_roots(another + "f.py") def test_in_project_roots(tmpdir): from _pydevd_bundle.pydevd_filtering import FilesFiltering + files_filtering = FilesFiltering() import os.path import sys if IS_WINDOWS: - assert files_filtering._get_library_roots() == [ - os.path.normcase(x) + '\\' for x in files_filtering._get_default_library_roots()] + assert files_filtering._get_library_roots() == [os.path.normcase(x) + "\\" for x in files_filtering._get_default_library_roots()] elif IS_MAC: - assert files_filtering._get_library_roots() == [ - x.lower() + '/' for x in files_filtering._get_default_library_roots()] + assert files_filtering._get_library_roots() == [x.lower() + "/" for x in files_filtering._get_default_library_roots()] else: - assert files_filtering._get_library_roots() == [ - os.path.normcase(x) + '/' for x in files_filtering._get_default_library_roots()] + assert files_filtering._get_library_roots() == [os.path.normcase(x) + "/" for x in files_filtering._get_default_library_roots()] - site_packages = tmpdir.mkdir('site-packages') - project_dir = tmpdir.mkdir('project') + site_packages = tmpdir.mkdir("site-packages") + project_dir = tmpdir.mkdir("project") - project_dir_inside_site_packages = str(site_packages.mkdir('project')) - site_packages_inside_project_dir = str(project_dir.mkdir('site-packages')) + project_dir_inside_site_packages = str(site_packages.mkdir("project")) + site_packages_inside_project_dir = str(project_dir.mkdir("site-packages")) # Convert from pytest paths to str. site_packages = str(site_packages) @@ -76,9 +76,9 @@ def test_in_project_roots(tmpdir): (project_dir, True), (project_dir_inside_site_packages, True), ] - for (check_path, find) in check[:]: - filename_inside = os.path.join(check_path, 'a.py') - with open(filename_inside, 'w') as stream: + for check_path, find in check[:]: + filename_inside = os.path.join(check_path, "a.py") + with open(filename_inside, "w") as stream: # Note: on Github actions, tmpdir may be something as: # c:\\users\\runner~1\\appdata\\local\\temp\\pytest-of-runneradmin\\pytest-0\\test_in_project_roots0 # internally this may be set as: @@ -86,20 +86,22 @@ def test_in_project_roots(tmpdir): # So, when getting the absolute path, `runner~1` will be properly expanded to `runneradmin` if the # file exists, but if it doesn't it's not (which may make the test fail), so, make sure # that we actually create the file so that things work as expected. - stream.write('...') + stream.write("...") check.append((filename_inside, find)) for check_path, find in check: if files_filtering.in_project_roots(check_path) != find: if find: - msg = 'Expected %s to be in the project roots.\nProject roots: %s\nLibrary roots: %s\n' + msg = "Expected %s to be in the project roots.\nProject roots: %s\nLibrary roots: %s\n" else: - msg = 'Expected %s NOT to be in the project roots.\nProject roots: %s\nLibrary roots: %s\n' - - raise AssertionError(msg % ( - check_path, - files_filtering._get_project_roots(), - files_filtering._get_library_roots(), + msg = "Expected %s NOT to be in the project roots.\nProject roots: %s\nLibrary roots: %s\n" + + raise AssertionError( + msg + % ( + check_path, + files_filtering._get_project_roots(), + files_filtering._get_library_roots(), ) ) @@ -115,24 +117,24 @@ def test_in_project_roots(tmpdir): (site_packages_inside_project_dir, False), (project_dir, True), (project_dir_inside_site_packages, False), - ('', False), - ('', True), - ('', False), + ("", False), + ("", True), + ("", False), ] for check_path, find in check: - assert files_filtering.in_project_roots(check_path) == find, \ - 'Expected: %s to be a part of the project: %s' % (check_path, find) + assert files_filtering.in_project_roots(check_path) == find, "Expected: %s to be a part of the project: %s" % (check_path, find) sys.path.append(str(site_packages)) try: default_library_roots = files_filtering._get_default_library_roots() - assert len(set(default_library_roots)) == len(default_library_roots), \ - 'Duplicated library roots found in: %s' % (default_library_roots,) + assert len(set(default_library_roots)) == len(default_library_roots), "Duplicated library roots found in: %s" % ( + default_library_roots, + ) assert str(site_packages) in default_library_roots for path in sys.path: - if os.path.exists(path) and path.endswith('site-packages'): + if os.path.exists(path) and path.endswith("site-packages"): assert path in default_library_roots finally: sys.path.remove(str(site_packages)) @@ -141,126 +143,130 @@ def test_in_project_roots(tmpdir): def test_filtering(tmpdir): from _pydevd_bundle.pydevd_filtering import FilesFiltering from _pydevd_bundle.pydevd_filtering import ExcludeFilter + files_filtering = FilesFiltering() - site_packages = tmpdir.mkdir('site-packages') - project_dir = tmpdir.mkdir('project') + site_packages = tmpdir.mkdir("site-packages") + project_dir = tmpdir.mkdir("project") - project_dir_inside_site_packages = str(site_packages.mkdir('project')) - site_packages_inside_project_dir = str(project_dir.mkdir('site-packages')) + project_dir_inside_site_packages = str(site_packages.mkdir("project")) + site_packages_inside_project_dir = str(project_dir.mkdir("site-packages")) - files_filtering.set_exclude_filters([ - ExcludeFilter('**/project*', True, True), - ExcludeFilter('**/bar*', False, True), - ]) - assert files_filtering.exclude_by_filter('/foo/project', None) is True - assert files_filtering.exclude_by_filter('/foo/unmatched', None) is None - assert files_filtering.exclude_by_filter('/foo/bar', None) is False + files_filtering.set_exclude_filters( + [ + ExcludeFilter("**/project*", True, True), + ExcludeFilter("**/bar*", False, True), + ] + ) + assert files_filtering.exclude_by_filter("/foo/project", None) is True + assert files_filtering.exclude_by_filter("/foo/unmatched", None) is None + assert files_filtering.exclude_by_filter("/foo/bar", None) is False def test_glob_matching(): from _pydevd_bundle.pydevd_filtering import glob_matches_path # Linux - for sep, altsep in (('\\', '/'), ('/', None)): + for sep, altsep in (("\\", "/"), ("/", None)): def build(path): - if sep == '/': + if sep == "/": return path else: - return ('c:' + path).replace('/', '\\') + return ("c:" + path).replace("/", "\\") - assert glob_matches_path(build('/a'), r'*', sep, altsep) + assert glob_matches_path(build("/a"), r"*", sep, altsep) - assert not glob_matches_path(build('/a/b/c/some.py'), '/a/**/c/so?.py', sep, altsep) + assert not glob_matches_path(build("/a/b/c/some.py"), "/a/**/c/so?.py", sep, altsep) - assert glob_matches_path('/a/b/c', '/a/b/*') - assert not glob_matches_path('/a/b', '/*') - assert glob_matches_path('/a/b', '/*/b') - assert glob_matches_path('/a/b', '**/*') - assert not glob_matches_path('/a/b', '**/a') + assert glob_matches_path("/a/b/c", "/a/b/*") + assert not glob_matches_path("/a/b", "/*") + assert glob_matches_path("/a/b", "/*/b") + assert glob_matches_path("/a/b", "**/*") + assert not glob_matches_path("/a/b", "**/a") - assert glob_matches_path(build('/a/b/c/d'), '**/d', sep, altsep) - assert not glob_matches_path(build('/a/b/c/d'), '**/c', sep, altsep) - assert glob_matches_path(build('/a/b/c/d'), '**/c/d', sep, altsep) - assert glob_matches_path(build('/a/b/c/d'), '**/b/c/d', sep, altsep) - assert glob_matches_path(build('/a/b/c/d'), '/*/b/*/d', sep, altsep) - assert glob_matches_path(build('/a/b/c/d'), '**/c/*', sep, altsep) - assert glob_matches_path(build('/a/b/c/d'), '/a/**/c/*', sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), "**/d", sep, altsep) + assert not glob_matches_path(build("/a/b/c/d"), "**/c", sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), "**/c/d", sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), "**/b/c/d", sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), "/*/b/*/d", sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), "**/c/*", sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), "/a/**/c/*", sep, altsep) # I.e. directories are expected to end with '/', so, it'll match # something as **/directory/** - assert glob_matches_path(build('/a/b/c/'), '**/c/**', sep, altsep) - assert glob_matches_path(build('/a/b/c/'), '**/c/', sep, altsep) + assert glob_matches_path(build("/a/b/c/"), "**/c/**", sep, altsep) + assert glob_matches_path(build("/a/b/c/"), "**/c/", sep, altsep) # But not something as **/directory (that'd be a file match). - assert not glob_matches_path(build('/a/b/c/'), '**/c', sep, altsep) - assert not glob_matches_path(build('/a/b/c'), '**/c/', sep, altsep) - - assert glob_matches_path(build('/a/b/c/d.py'), '/a/**/c/*', sep, altsep) - assert glob_matches_path(build('/a/b/c/d.py'), '/a/**/c/*.py', sep, altsep) - assert glob_matches_path(build('/a/b/c/some.py'), '/a/**/c/so*.py', sep, altsep) - assert glob_matches_path(build('/a/b/c/some.py'), '/a/**/c/som?.py', sep, altsep) - assert glob_matches_path(build('/a/b/c/d'), '/**', sep, altsep) - assert glob_matches_path(build('/a/b/c/d'), '/**/d', sep, altsep) - assert glob_matches_path(build('/a/b/c/d.py'), '/**/*.py', sep, altsep) - assert glob_matches_path(build('/a/b/c/d.py'), '**/c/*.py', sep, altsep) + assert not glob_matches_path(build("/a/b/c/"), "**/c", sep, altsep) + assert not glob_matches_path(build("/a/b/c"), "**/c/", sep, altsep) + + assert glob_matches_path(build("/a/b/c/d.py"), "/a/**/c/*", sep, altsep) + assert glob_matches_path(build("/a/b/c/d.py"), "/a/**/c/*.py", sep, altsep) + assert glob_matches_path(build("/a/b/c/some.py"), "/a/**/c/so*.py", sep, altsep) + assert glob_matches_path(build("/a/b/c/some.py"), "/a/**/c/som?.py", sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), "/**", sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), "/**/d", sep, altsep) + assert glob_matches_path(build("/a/b/c/d.py"), "/**/*.py", sep, altsep) + assert glob_matches_path(build("/a/b/c/d.py"), "**/c/*.py", sep, altsep) if IS_WINDOWS: - assert glob_matches_path(build('/a/b/c/d.py'), '**/C/*.py', sep, altsep) - assert glob_matches_path(build('/a/b/C/d.py'), '**/c/*.py', sep, altsep) + assert glob_matches_path(build("/a/b/c/d.py"), "**/C/*.py", sep, altsep) + assert glob_matches_path(build("/a/b/C/d.py"), "**/c/*.py", sep, altsep) # Expected not to match. - assert not glob_matches_path(build('/a/b/c/d'), '/**/d.py', sep, altsep) - assert not glob_matches_path(build('/a/b/c/d.pyx'), '/a/**/c/*.py', sep, altsep) - assert not glob_matches_path(build('/a/b/c/d'), '/*/d', sep, altsep) + assert not glob_matches_path(build("/a/b/c/d"), "/**/d.py", sep, altsep) + assert not glob_matches_path(build("/a/b/c/d.pyx"), "/a/**/c/*.py", sep, altsep) + assert not glob_matches_path(build("/a/b/c/d"), "/*/d", sep, altsep) - if sep == '/': - assert not glob_matches_path(build('/a/b/c/d'), r'**\d', sep, altsep) # Match with \ doesn't work on linux... - assert not glob_matches_path(build('/a/b/c/d'), r'c:\**\d', sep, altsep) # Match with drive doesn't work on linux... + if sep == "/": + assert not glob_matches_path(build("/a/b/c/d"), r"**\d", sep, altsep) # Match with \ doesn't work on linux... + assert not glob_matches_path(build("/a/b/c/d"), r"c:\**\d", sep, altsep) # Match with drive doesn't work on linux... else: # Works in Windows. - assert glob_matches_path(build('/a/b/c/d'), r'**\d', sep, altsep) - assert glob_matches_path(build('/a/b/c/d'), r'c:\**\d', sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), r"**\d", sep, altsep) + assert glob_matches_path(build("/a/b/c/d"), r"c:\**\d", sep, altsep) # Corner cases - assert not glob_matches_path(build('/'), r'', sep, altsep) - assert glob_matches_path(build(''), r'', sep, altsep) - assert not glob_matches_path(build(''), r'**', sep, altsep) - assert glob_matches_path(build('/'), r'**', sep, altsep) - assert glob_matches_path(build('/'), r'*', sep, altsep) + assert not glob_matches_path(build("/"), r"", sep, altsep) + assert glob_matches_path(build(""), r"", sep, altsep) + assert not glob_matches_path(build(""), r"**", sep, altsep) + assert glob_matches_path(build("/"), r"**", sep, altsep) + assert glob_matches_path(build("/"), r"*", sep, altsep) def test_rules_to_exclude_filter(tmpdir): from _pydevd_bundle.pydevd_process_net_command_json import _convert_rules_to_exclude_filters from _pydevd_bundle.pydevd_filtering import ExcludeFilter from random import shuffle - dira = tmpdir.mkdir('a') - dirb = dira.mkdir('b') - fileb = dirb.join('fileb.py') - fileb2 = dirb.join('fileb2.py') - with fileb.open('w') as stream: - stream.write('') + + dira = tmpdir.mkdir("a") + dirb = dira.mkdir("b") + fileb = dirb.join("fileb.py") + fileb2 = dirb.join("fileb2.py") + with fileb.open("w") as stream: + stream.write("") def on_error(msg): raise AssertionError(msg) rules = [ - {'path': str(dira), 'include': False}, - {'path': str(dirb), 'include': True}, - {'path': str(fileb), 'include': True}, - {'path': str(fileb2), 'include': True}, - {'path': '**/foo/*.py', 'include': True}, - {'module': 'bar', 'include': False}, - {'module': 'bar.foo', 'include': True}, + {"path": str(dira), "include": False}, + {"path": str(dirb), "include": True}, + {"path": str(fileb), "include": True}, + {"path": str(fileb2), "include": True}, + {"path": "**/foo/*.py", "include": True}, + {"module": "bar", "include": False}, + {"module": "bar.foo", "include": True}, ] shuffle(rules) exclude_filters = _convert_rules_to_exclude_filters(rules, on_error) assert exclude_filters == [ ExcludeFilter(name=str(fileb2), exclude=False, is_path=True), ExcludeFilter(name=str(fileb), exclude=False, is_path=True), - ExcludeFilter(name=str(dirb) + '/**', exclude=False, is_path=True), - ExcludeFilter(name=str(dira) + '/**', exclude=True, is_path=True), - ExcludeFilter(name='**/foo/*.py', exclude=False, is_path=True), - ExcludeFilter(name='bar.foo', exclude=False, is_path=False), - ExcludeFilter(name='bar', exclude=True, is_path=False), + ExcludeFilter(name=str(dirb) + "/**", exclude=False, is_path=True), + ExcludeFilter(name=str(dira) + "/**", exclude=True, is_path=True), + ExcludeFilter(name="**/foo/*.py", exclude=False, is_path=True), + ExcludeFilter(name="bar.foo", exclude=False, is_path=False), + ExcludeFilter(name="bar", exclude=True, is_path=False), ] diff --git a/tests_python/test_pydevd_io.py b/tests_python/test_pydevd_io.py index b8608ef91..3f3b157e3 100644 --- a/tests_python/test_pydevd_io.py +++ b/tests_python/test_pydevd_io.py @@ -5,9 +5,8 @@ def test_io_redirector(): - class MyRedirection1(object): - encoding = 'foo' + encoding = "foo" class MyRedirection2(object): pass @@ -15,25 +14,24 @@ class MyRedirection2(object): my_redirector = IORedirector(MyRedirection1(), MyRedirection2(), wrap_buffer=True) none_redirector = IORedirector(None, None, wrap_buffer=True) - assert my_redirector.encoding == 'foo' + assert my_redirector.encoding == "foo" with pytest.raises(AttributeError): none_redirector.encoding # Check that we don't fail creating the IORedirector if the original # doesn't have a 'buffer'. for redirector in ( - my_redirector, - none_redirector, - ): - redirector.write('test') + my_redirector, + none_redirector, + ): + redirector.write("test") redirector.flush() assert not redirector.isatty() class _DummyWriter(object): - - __slots__ = ['commands', 'command_meanings'] + __slots__ = ["commands", "command_meanings"] def __init__(self): self.commands = [] @@ -41,13 +39,13 @@ def __init__(self): def add_command(self, cmd): from _pydevd_bundle.pydevd_comm import ID_TO_MEANING + meaning = ID_TO_MEANING[str(cmd.id)] self.command_meanings.append(meaning) self.commands.append(cmd) class _DummyPyDb(object): - def __init__(self): self.cmd_factory = NetCommandFactory() self.writer = _DummyWriter() @@ -64,18 +62,17 @@ class _Stub(object): actions = [] class OriginalStdin(object): - def readline(self): # On a readline we keep the patched version. assert sys_mod.stdin is not original_stdin - actions.append('readline') - return 'read' + actions.append("readline") + return "read" def getpass_stub(*args, **kwargs): # On getpass we need to revert to the original version. - actions.append('getpass') + actions.append("getpass") assert sys_mod.stdin is original_stdin - return 'pass' + return "pass" sys_mod = _Stub() original_stdin = sys_mod.stdin = OriginalStdin() @@ -85,15 +82,15 @@ def getpass_stub(*args, **kwargs): _internal_patch_stdin(py_db, sys_mod, getpass_mod) - assert sys_mod.stdin.readline() == 'read' + assert sys_mod.stdin.readline() == "read" - assert py_db.writer.command_meanings == ['CMD_INPUT_REQUESTED', 'CMD_INPUT_REQUESTED'] + assert py_db.writer.command_meanings == ["CMD_INPUT_REQUESTED", "CMD_INPUT_REQUESTED"] del py_db.writer.command_meanings[:] - assert actions == ['readline'] + assert actions == ["readline"] del actions[:] - assert getpass_mod.getpass() == 'pass' - assert py_db.writer.command_meanings == ['CMD_INPUT_REQUESTED', 'CMD_INPUT_REQUESTED'] + assert getpass_mod.getpass() == "pass" + assert py_db.writer.command_meanings == ["CMD_INPUT_REQUESTED", "CMD_INPUT_REQUESTED"] del py_db.writer.command_meanings[:] @@ -101,29 +98,29 @@ def test_debug_console(): from _pydev_bundle.pydev_console_utils import DebugConsoleStdIn class OriginalStdin(object): - def readline(self): - return 'read' + return "read" original_stdin = OriginalStdin() py_db = _DummyPyDb() debug_console_std_in = DebugConsoleStdIn(py_db, original_stdin) - assert debug_console_std_in.readline() == 'read' + assert debug_console_std_in.readline() == "read" - assert py_db.writer.command_meanings == ['CMD_INPUT_REQUESTED', 'CMD_INPUT_REQUESTED'] + assert py_db.writer.command_meanings == ["CMD_INPUT_REQUESTED", "CMD_INPUT_REQUESTED"] del py_db.writer.command_meanings[:] with debug_console_std_in.notify_input_requested(): with debug_console_std_in.notify_input_requested(): pass - assert py_db.writer.command_meanings == ['CMD_INPUT_REQUESTED', 'CMD_INPUT_REQUESTED'] + assert py_db.writer.command_meanings == ["CMD_INPUT_REQUESTED", "CMD_INPUT_REQUESTED"] @pytest.yield_fixture def _redirect_context(): from _pydevd_bundle.pydevd_io import RedirectToPyDBIoMessages from _pydevd_bundle.pydevd_io import _RedirectionsHolder + py_db = _DummyPyDb() _original_get_pydb = RedirectToPyDBIoMessages.get_pydb @@ -141,7 +138,7 @@ def _redirect_context(): original_stdout = sys.stdout original_stderr = sys.stderr - yield {'py_db': py_db} + yield {"py_db": py_db} sys.stdout = original_stdout sys.stderr = original_stderr @@ -159,44 +156,44 @@ def test_redirect_to_pyd_io_messages_basic(_redirect_context): from _pydevd_bundle.pydevd_io import stop_redirect_stream_to_pydb_io_messages from _pydevd_bundle.pydevd_io import _RedirectionsHolder - py_db = _redirect_context['py_db'] + py_db = _redirect_context["py_db"] - redirect_stream_to_pydb_io_messages(std='stdout') + redirect_stream_to_pydb_io_messages(std="stdout") assert len(_RedirectionsHolder._stack_stdout) == 1 assert _RedirectionsHolder._pydevd_stdout_redirect_ is not None - sys.stdout.write('aaa') - assert py_db.writer.command_meanings == ['CMD_WRITE_TO_CONSOLE'] + sys.stdout.write("aaa") + assert py_db.writer.command_meanings == ["CMD_WRITE_TO_CONSOLE"] with redirect_stream_to_pydb_io_messages_context(): assert len(_RedirectionsHolder._stack_stdout) == 1 assert _RedirectionsHolder._pydevd_stdout_redirect_ is not None - sys.stdout.write('bbb') + sys.stdout.write("bbb") - assert py_db.writer.command_meanings == ['CMD_WRITE_TO_CONSOLE', 'CMD_WRITE_TO_CONSOLE'] + assert py_db.writer.command_meanings == ["CMD_WRITE_TO_CONSOLE", "CMD_WRITE_TO_CONSOLE"] assert len(_RedirectionsHolder._stack_stdout) == 1 assert _RedirectionsHolder._pydevd_stdout_redirect_ is not None - sys.stdout.write('ccc') - assert py_db.writer.command_meanings == ['CMD_WRITE_TO_CONSOLE', 'CMD_WRITE_TO_CONSOLE', 'CMD_WRITE_TO_CONSOLE'] + sys.stdout.write("ccc") + assert py_db.writer.command_meanings == ["CMD_WRITE_TO_CONSOLE", "CMD_WRITE_TO_CONSOLE", "CMD_WRITE_TO_CONSOLE"] - stop_redirect_stream_to_pydb_io_messages(std='stdout') + stop_redirect_stream_to_pydb_io_messages(std="stdout") assert len(_RedirectionsHolder._stack_stdout) == 0 assert _RedirectionsHolder._pydevd_stdout_redirect_ is None - sys.stdout.write('ddd') - assert py_db.writer.command_meanings == ['CMD_WRITE_TO_CONSOLE', 'CMD_WRITE_TO_CONSOLE', 'CMD_WRITE_TO_CONSOLE'] + sys.stdout.write("ddd") + assert py_db.writer.command_meanings == ["CMD_WRITE_TO_CONSOLE", "CMD_WRITE_TO_CONSOLE", "CMD_WRITE_TO_CONSOLE"] -@pytest.mark.parametrize('std', ['stderr', 'stdout']) +@pytest.mark.parametrize("std", ["stderr", "stdout"]) def test_redirect_to_pyd_io_messages_user_change_stdout(_redirect_context, std): from _pydevd_bundle.pydevd_io import redirect_stream_to_pydb_io_messages from _pydevd_bundle.pydevd_io import stop_redirect_stream_to_pydb_io_messages from _pydevd_bundle.pydevd_io import _RedirectionsHolder - py_db = _redirect_context['py_db'] - stack = getattr(_RedirectionsHolder, '_stack_%s' % (std,)) + py_db = _redirect_context["py_db"] + stack = getattr(_RedirectionsHolder, "_stack_%s" % (std,)) def get_redirect(): - return getattr(_RedirectionsHolder, '_pydevd_%s_redirect_' % (std,)) + return getattr(_RedirectionsHolder, "_pydevd_%s_redirect_" % (std,)) def write(s): getattr(sys, std).write(s) @@ -204,22 +201,22 @@ def write(s): redirect_stream_to_pydb_io_messages(std=std) assert len(stack) == 1 assert get_redirect() is not None - write('aaa') - assert py_db.writer.command_meanings == ['CMD_WRITE_TO_CONSOLE'] + write("aaa") + assert py_db.writer.command_meanings == ["CMD_WRITE_TO_CONSOLE"] from io import StringIO + stream = StringIO() setattr(sys, std, stream) - write(u'bbb') - assert py_db.writer.command_meanings == ['CMD_WRITE_TO_CONSOLE'] - assert stream.getvalue() == u'bbb' + write("bbb") + assert py_db.writer.command_meanings == ["CMD_WRITE_TO_CONSOLE"] + assert stream.getvalue() == "bbb" # i.e.: because the user changed the sys.stdout, we cannot change it to our previous version. stop_redirect_stream_to_pydb_io_messages(std=std) assert len(stack) == 0 assert get_redirect() is None - write(u'ccc') - assert py_db.writer.command_meanings == ['CMD_WRITE_TO_CONSOLE'] - assert stream.getvalue() == u'bbbccc' - + write("ccc") + assert py_db.writer.command_meanings == ["CMD_WRITE_TO_CONSOLE"] + assert stream.getvalue() == "bbbccc" diff --git a/tests_python/test_resolvers.py b/tests_python/test_resolvers.py index 1e6b41349..616500124 100644 --- a/tests_python/test_resolvers.py +++ b/tests_python/test_resolvers.py @@ -7,93 +7,95 @@ def check_len_entry(len_entry, first_2_params): assert len_entry[:2] == first_2_params assert callable(len_entry[2]) - assert len_entry[2]('check') == 'len(check)' + assert len_entry[2]("check") == "len(check)" def test_dict_resolver(): from _pydevd_bundle.pydevd_resolver import DictResolver + dict_resolver = DictResolver() - dct = {(1, 2): 2, u'22': 22} + dct = {(1, 2): 2, "22": 22} contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(dict_resolver.get_contents_debug_adapter_protocol(dct)) len_entry = contents_debug_adapter_protocol.pop(-1) check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 2)) if IS_PY36_OR_GREATER: - assert contents_debug_adapter_protocol == [ - ('(1, 2)', 2, '[(1, 2)]'), ("'22'", 22, "['22']")] + assert contents_debug_adapter_protocol == [("(1, 2)", 2, "[(1, 2)]"), ("'22'", 22, "['22']")] else: - assert contents_debug_adapter_protocol == [ - ("'22'", 22, "['22']"), ('(1, 2)', 2, '[(1, 2)]')] + assert contents_debug_adapter_protocol == [("'22'", 22, "['22']"), ("(1, 2)", 2, "[(1, 2)]")] def test_dict_resolver_hex(): from _pydevd_bundle.pydevd_resolver import DictResolver + dict_resolver = DictResolver() dct = {(1, 10, 100): (10000, 100000, 100000)} contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol( - dict_resolver.get_contents_debug_adapter_protocol(dct, fmt={'hex': True})) + dict_resolver.get_contents_debug_adapter_protocol(dct, fmt={"hex": True}) + ) len_entry = contents_debug_adapter_protocol.pop(-1) check_len_entry(len_entry, (GENERATED_LEN_ATTR_NAME, 1)) assert contents_debug_adapter_protocol == [ - ('(0x1, 0xa, 0x64)', (10000, 100000, 100000), '[(1, 10, 100)]'), ] + ("(0x1, 0xa, 0x64)", (10000, 100000, 100000), "[(1, 10, 100)]"), + ] def test_object_resolver_simple(): from _pydevd_bundle.pydevd_resolver import DefaultResolver + default_resolver = DefaultResolver() class MyObject(object): - def __init__(self): self.a = 10 self.b = 20 obj = MyObject() dictionary = clear_contents_dictionary(default_resolver.get_dictionary(obj)) - assert dictionary == {'a': 10, 'b': 20} + assert dictionary == {"a": 10, "b": 20} contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(default_resolver.get_contents_debug_adapter_protocol(obj)) - assert contents_debug_adapter_protocol == [('a', 10, '.a'), ('b', 20, '.b')] + assert contents_debug_adapter_protocol == [("a", 10, ".a"), ("b", 20, ".b")] def test_object_resolver_error(): from _pydevd_bundle.pydevd_resolver import DefaultResolver + default_resolver = DefaultResolver() class MyObject(object): - def __init__(self): self.a = 10 def __dir__(self): - return ['a', 'b'] + return ["a", "b"] def __getattribute__(self, attr_name): - if attr_name == 'b': - raise RuntimeError('unavailable') + if attr_name == "b": + raise RuntimeError("unavailable") return object.__getattribute__(self, attr_name) obj = MyObject() dictionary = default_resolver.get_dictionary(obj) - b_value = dictionary.pop('b') - assert dictionary == {'a': 10} - assert "raise RuntimeError('unavailable')" in b_value + b_value = dictionary.pop("b") + assert dictionary == {"a": 10} + assert "raise RuntimeError(\"unavailable\")" in b_value contents_debug_adapter_protocol = default_resolver.get_contents_debug_adapter_protocol(obj) b_value = contents_debug_adapter_protocol.pop(-1) - assert contents_debug_adapter_protocol == [('a', 10, '.a')] - assert b_value[0] == 'b' - assert "raise RuntimeError('unavailable')" in b_value[1] - assert b_value[2] == '.b' + assert contents_debug_adapter_protocol == [("a", 10, ".a")] + assert b_value[0] == "b" + assert "raise RuntimeError(\"unavailable\")" in b_value[1] + assert b_value[2] == ".b" def test_object_resolver_hasattr_error(): from _pydevd_bundle.pydevd_resolver import DefaultResolver from _pydevd_bundle.pydevd_xml import get_type + default_resolver = DefaultResolver() class MyObject(object): - def __getattribute__(self, attr_name): raise RuntimeError() @@ -102,53 +104,51 @@ def __getattribute__(self, attr_name): assert dictionary == {} _type_object, type_name, _resolver = get_type(obj) - assert type_name == 'MyObject' + assert type_name == "MyObject" def test_object_resolver__dict__non_strings(): from _pydevd_bundle.pydevd_resolver import DefaultResolver + default_resolver = DefaultResolver() class MyObject(object): - def __init__(self): self.__dict__[(1, 2)] = (3, 4) obj = MyObject() dictionary = clear_contents_dictionary(default_resolver.get_dictionary(obj)) - assert dictionary == {'(1, 2)': (3, 4)} + assert dictionary == {"(1, 2)": (3, 4)} - contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol( - default_resolver.get_contents_debug_adapter_protocol(obj)) - assert contents_debug_adapter_protocol == [('(1, 2)', (3, 4), '.__dict__[(1, 2)]')] + contents_debug_adapter_protocol = clear_contents_debug_adapter_protocol(default_resolver.get_contents_debug_adapter_protocol(obj)) + assert contents_debug_adapter_protocol == [("(1, 2)", (3, 4), ".__dict__[(1, 2)]")] def test_django_forms_resolver(): from _pydevd_bundle.pydevd_resolver import DjangoFormResolver + django_form_resolver = DjangoFormResolver() class MyObject(object): - def __init__(self): self.__dict__[(1, 2)] = (3, 4) - self.__dict__['errors'] = 'foo' + self.__dict__["errors"] = "foo" obj = MyObject() dictionary = clear_contents_dictionary(django_form_resolver.get_dictionary(obj)) - assert dictionary == {'(1, 2)': (3, 4), 'errors': None} + assert dictionary == {"(1, 2)": (3, 4), "errors": None} - obj._errors = 'bar' + obj._errors = "bar" dictionary = clear_contents_dictionary(django_form_resolver.get_dictionary(obj)) - assert dictionary == {'(1, 2)': (3, 4), 'errors': 'bar', '_errors': 'bar'} + assert dictionary == {"(1, 2)": (3, 4), "errors": "bar", "_errors": "bar"} def clear_contents_debug_adapter_protocol(contents_debug_adapter_protocol): lst = [] for x in contents_debug_adapter_protocol: - if not x[0].startswith('__'): - - if '= 7: +if hasattr(pytest, "version_tuple") and pytest.version_tuple[0] >= 7: @pytest.fixture def testdir_or_pytester(pytester): @@ -29,34 +28,49 @@ def test_run(testdir_or_pytester): import sys import os - foo_dir = debugger_unittest._get_debugger_test_file(os.path.join('resources', 'launch', 'foo')) - foo_module = 'tests_python.resources.launch.foo' + foo_dir = debugger_unittest._get_debugger_test_file(os.path.join("resources", "launch", "foo")) + foo_module = "tests_python.resources.launch.foo" pydevd_dir = os.path.dirname(os.path.dirname(__file__)) - assert os.path.exists(os.path.join(pydevd_dir, 'pydevd.py')) + assert os.path.exists(os.path.join(pydevd_dir, "pydevd.py")) - _run_and_check(testdir_or_pytester, testdir_or_pytester.makepyfile(''' + _run_and_check( + testdir_or_pytester, + testdir_or_pytester.makepyfile( + """ import sys sys.path.append(%(pydevd_dir)r) import pydevd py_db = pydevd.PyDB() py_db.ready_to_run = True py_db.run(%(foo_dir)r) -''' % locals())) - - _run_and_check(testdir_or_pytester, testdir_or_pytester.makepyfile(''' +""" + % locals() + ), + ) + + _run_and_check( + testdir_or_pytester, + testdir_or_pytester.makepyfile( + """ import sys sys.path.append(%(pydevd_dir)r) import pydevd py_db = pydevd.PyDB() py_db.run(%(foo_dir)r, set_trace=False) -''' % locals())) +""" + % locals() + ), + ) if sys.version_info[0:2] == (2, 6): # Not valid for Python 2.6 return - _run_and_check(testdir_or_pytester, testdir_or_pytester.makepyfile(''' + _run_and_check( + testdir_or_pytester, + testdir_or_pytester.makepyfile( + """ import sys sys.path.append(%(pydevd_dir)r) sys.argv.append('--as-module') @@ -64,16 +78,25 @@ def test_run(testdir_or_pytester): py_db = pydevd.PyDB() py_db.ready_to_run = True py_db.run(%(foo_module)r, is_module=True) -''' % locals())) - - _run_and_check(testdir_or_pytester, testdir_or_pytester.makepyfile(''' +""" + % locals() + ), + ) + + _run_and_check( + testdir_or_pytester, + testdir_or_pytester.makepyfile( + """ import sys sys.argv.append('--as-module') sys.path.append(%(pydevd_dir)r) import pydevd py_db = pydevd.PyDB() py_db.run(%(foo_module)r, is_module=True, set_trace=False) -''' % locals())) +""" + % locals() + ), + ) def test_run_on_local_module_without_adding_to_pythonpath(testdir_or_pytester): @@ -81,13 +104,16 @@ def test_run_on_local_module_without_adding_to_pythonpath(testdir_or_pytester): import os pydevd_dir = os.path.dirname(os.path.dirname(__file__)) - assert os.path.exists(os.path.join(pydevd_dir, 'pydevd.py')) + assert os.path.exists(os.path.join(pydevd_dir, "pydevd.py")) - foo_module = 'local_foo' - with open(os.path.join(os.getcwd(), 'local_foo.py'), 'w') as stream: + foo_module = "local_foo" + with open(os.path.join(os.getcwd(), "local_foo.py"), "w") as stream: stream.write('print("WorkedLocalFoo")') - _run_and_check(testdir_or_pytester, testdir_or_pytester.makepyfile(''' + _run_and_check( + testdir_or_pytester, + testdir_or_pytester.makepyfile( + """ import sys import os sys.path.append(%(pydevd_dir)r) @@ -99,9 +125,16 @@ def test_run_on_local_module_without_adding_to_pythonpath(testdir_or_pytester): py_db = pydevd.PyDB() py_db.ready_to_run = True py_db.run(%(foo_module)r, is_module=True) -''' % locals()), check_for='WorkedLocalFoo') - - _run_and_check(testdir_or_pytester, testdir_or_pytester.makepyfile(''' +""" + % locals() + ), + check_for="WorkedLocalFoo", + ) + + _run_and_check( + testdir_or_pytester, + testdir_or_pytester.makepyfile( + """ import sys import os sys.argv.append('--as-module') @@ -112,4 +145,8 @@ def test_run_on_local_module_without_adding_to_pythonpath(testdir_or_pytester): import pydevd py_db = pydevd.PyDB() py_db.run(%(foo_module)r, is_module=True, set_trace=False) -''' % locals()), check_for='WorkedLocalFoo') +""" + % locals() + ), + check_for="WorkedLocalFoo", + ) diff --git a/tests_python/test_safe_repr.py b/tests_python/test_safe_repr.py index 9356e40fb..ea04c75f1 100644 --- a/tests_python/test_safe_repr.py +++ b/tests_python/test_safe_repr.py @@ -18,15 +18,21 @@ class SafeReprTestBase(object): - saferepr = SafeRepr() def assert_saferepr(self, value, expected): safe = self.saferepr(value) if len(safe) != len(expected): - raise AssertionError('Expected:\n%s\nFound:\n%s\n Expected len: %s Found len: %s' % ( - expected, safe, len(expected), len(safe),)) + raise AssertionError( + "Expected:\n%s\nFound:\n%s\n Expected len: %s Found len: %s" + % ( + expected, + safe, + len(expected), + len(safe), + ) + ) assert safe == expected return safe @@ -62,7 +68,6 @@ def assert_shortened_regex(self, value, expected): class TestSafeRepr(SafeReprTestBase): - def test_collection_types(self): colltypes = [t for t, _, _, _ in SafeRepr.collection_types] @@ -77,7 +82,7 @@ def test_collection_types(self): def test_largest_repr(self): # Find the largest possible repr and ensure it is below our arbitrary # limit (8KB). - coll = '-' * (SafeRepr.maxstring_outer * 2) + coll = "-" * (SafeRepr.maxstring_outer * 2) for limit in reversed(SafeRepr.maxcollection[1:]): coll = [coll] * (limit * 2) dcoll = {} @@ -96,69 +101,64 @@ def test_largest_repr(self): class TestStrings(SafeReprTestBase): - def test_str_small(self): - value = 'A' * 5 + value = "A" * 5 self.assert_unchanged(value, "'AAAAA'") self.assert_unchanged([value], "['AAAAA']") def test_str_large(self): - value = 'A' * (SafeRepr.maxstring_outer + 10) + value = "A" * (SafeRepr.maxstring_outer + 10) - self.assert_shortened(value, - "'" + 'A' * 43690 + "..." + 'A' * 21845 + "'") + self.assert_shortened(value, "'" + "A" * 43690 + "..." + "A" * 21845 + "'") self.assert_shortened([value], "['AAAAAAAAAAAAAAAAAAAA...AAAAAAAAAA']") def test_str_largest_unchanged(self): - value = 'A' * (SafeRepr.maxstring_outer) + value = "A" * (SafeRepr.maxstring_outer) - self.assert_unchanged(value, "'" + 'A' * 65536 + "'") + self.assert_unchanged(value, "'" + "A" * 65536 + "'") def test_str_smallest_changed(self): - value = 'A' * (SafeRepr.maxstring_outer + 1) + value = "A" * (SafeRepr.maxstring_outer + 1) - self.assert_shortened(value, - "'" + 'A' * 43690 + "..." + 'A' * 21845 + "'") + self.assert_shortened(value, "'" + "A" * 43690 + "..." + "A" * 21845 + "'") def test_str_list_largest_unchanged(self): - value = 'A' * (SafeRepr.maxstring_inner) + value = "A" * (SafeRepr.maxstring_inner) self.assert_unchanged([value], "['AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA']") def test_str_list_smallest_changed(self): - value = 'A' * (SafeRepr.maxstring_inner + 1) + value = "A" * (SafeRepr.maxstring_inner + 1) self.assert_shortened([value], "['AAAAAAAAAAAAAAAAAAAA...AAAAAAAAAA']") - @pytest.mark.skipif(sys.version_info > (3, 0), reason='Py2 specific test') + @pytest.mark.skipif(sys.version_info > (3, 0), reason="Py2 specific test") def test_unicode_small(self): - value = u'A' * 5 + value = "A" * 5 self.assert_unchanged(value, "u'AAAAA'") self.assert_unchanged([value], "[u'AAAAA']") - @pytest.mark.skipif(sys.version_info > (3, 0), reason='Py2 specific test') + @pytest.mark.skipif(sys.version_info > (3, 0), reason="Py2 specific test") def test_unicode_large(self): - value = u'A' * (SafeRepr.maxstring_outer + 10) + value = "A" * (SafeRepr.maxstring_outer + 10) - self.assert_shortened(value, - "u'" + 'A' * 43690 + "..." + 'A' * 21845 + "'") + self.assert_shortened(value, "u'" + "A" * 43690 + "..." + "A" * 21845 + "'") self.assert_shortened([value], "[u'AAAAAAAAAAAAAAAAAAAA...AAAAAAAAAA']") - @pytest.mark.skipif(sys.version_info < (3, 0), reason='Py3 specific test') + @pytest.mark.skipif(sys.version_info < (3, 0), reason="Py3 specific test") def test_bytes_small(self): - value = b'A' * 5 + value = b"A" * 5 self.assert_unchanged(value, "b'AAAAA'") self.assert_unchanged([value], "[b'AAAAA']") - @pytest.mark.skipif(sys.version_info < (3, 0), reason='Py3 specific test') + @pytest.mark.skipif(sys.version_info < (3, 0), reason="Py3 specific test") def test_bytes_large(self): - value = b'A' * (SafeRepr.maxstring_outer + 10) + value = b"A" * (SafeRepr.maxstring_outer + 10) - self.assert_shortened(value, - "b'" + 'A' * 43690 + "..." + 'A' * 21845 + "'") + self.assert_shortened(value, "b'" + "A" * 43690 + "..." + "A" * 21845 + "'") self.assert_shortened([value], "[b'AAAAAAAAAAAAAAAAAAAA...AAAAAAAAAA']") # @pytest.mark.skip(reason='not written') # TODO: finish! @@ -171,22 +171,22 @@ def test_bytes_large(self): class RawValueTests(SafeReprTestBase): - def setUp(self): super(RawValueTests, self).setUp() self.saferepr.raw_value = True def test_unicode_raw(self): - value = u'A\u2000' * 10000 + value = "A\u2000" * 10000 self.assert_saferepr(value, value) def test_bytes_raw(self): - value = b'A' * 10000 - self.assert_saferepr(value, value.decode('ascii')) + value = b"A" * 10000 + self.assert_saferepr(value, value.decode("ascii")) def test_bytearray_raw(self): - value = bytearray(b'A' * 5) - self.assert_saferepr(value, value.decode('ascii')) + value = bytearray(b"A" * 5) + self.assert_saferepr(value, value.decode("ascii")) + # class TestNumbers(SafeReprTestBase): # @@ -204,7 +204,6 @@ def test_bytearray_raw(self): class ContainerBase(object): - CLASS = None LEFT = None RIGHT = None @@ -220,17 +219,17 @@ def info(self): type(self)._info = info return info else: - raise TypeError('unsupported') + raise TypeError("unsupported") def _combine(self, items, prefix, suffix, large): - contents = ', '.join(str(item) for item in items) + contents = ", ".join(str(item) for item in items) if large: - contents += ', ...' + contents += ", ..." return prefix + contents + suffix def combine(self, items, large=False): if self.LEFT is None: - pytest.skip('unsupported') + pytest.skip("unsupported") return self._combine(items, self.LEFT, self.RIGHT, large=large) def combine_nested(self, depth, items, large=False): @@ -306,76 +305,71 @@ def test_nested(self): class TestTuples(ContainerBase, SafeReprTestBase): - CLASS = tuple - LEFT = '(' - RIGHT = ')' + LEFT = "(" + RIGHT = ")" class TestLists(ContainerBase, SafeReprTestBase): - CLASS = list - LEFT = '[' - RIGHT = ']' + LEFT = "[" + RIGHT = "]" def test_directly_recursive(self): value = [1, 2] value.append(value) - self.assert_unchanged(value, '[1, 2, [...]]') + self.assert_unchanged(value, "[1, 2, [...]]") def test_indirectly_recursive(self): value = [1, 2] value.append([value]) - self.assert_unchanged(value, '[1, 2, [[...]]]') + self.assert_unchanged(value, "[1, 2, [[...]]]") class TestFrozensets(ContainerBase, SafeReprTestBase): - CLASS = frozenset class TestSets(ContainerBase, SafeReprTestBase): - CLASS = set if PY_VER != 2: - LEFT = '{' - RIGHT = '}' + LEFT = "{" + RIGHT = "}" def test_nested(self): - pytest.skip('unsupported') + pytest.skip("unsupported") def test_large_nested(self): - pytest.skip('unsupported') + pytest.skip("unsupported") class TestDicts(SafeReprTestBase): - def test_large_key(self): value = { - 'a' * SafeRepr.maxstring_inner * 3: '', + "a" * SafeRepr.maxstring_inner * 3: "", } self.assert_shortened_regex(value, r"{'a+\.\.\.a+': ''}") def test_large_value(self): value = { - '': 'a' * SafeRepr.maxstring_inner * 2, + "": "a" * SafeRepr.maxstring_inner * 2, } self.assert_shortened_regex(value, r"{'': 'a+\.\.\.a+'}") def test_large_both(self): value = {} - key = 'a' * SafeRepr.maxstring_inner * 2 + key = "a" * SafeRepr.maxstring_inner * 2 value[key] = key self.assert_shortened_regex(value, r"{'a+\.\.\.a+': 'a+\.\.\.a+'}") def test_nested_value(self): d1 = {} - d1_key = 'a' * SafeRepr.maxstring_inner * 2 + d1_key = "a" * SafeRepr.maxstring_inner * 2 d1[d1_key] = d1_key d2 = {d1_key: d1} d3 = {d1_key: d2} @@ -388,20 +382,20 @@ def test_nested_value(self): def test_empty(self): # Ensure empty dicts work - self.assert_unchanged({}, '{}') + self.assert_unchanged({}, "{}") def test_sorted(self): # Ensure dict keys are sorted d1 = {} - d1['c'] = None - d1['b'] = None - d1['a'] = None + d1["c"] = None + d1["b"] = None + d1["a"] = None if IS_PY36_OR_GREATER: self.assert_saferepr(d1, "{'c': None, 'b': None, 'a': None}") else: self.assert_saferepr(d1, "{'a': None, 'b': None, 'c': None}") - @pytest.mark.skipif(sys.version_info < (3, 0), reason='Py3 specific test') + @pytest.mark.skipif(sys.version_info < (3, 0), reason="Py3 specific test") def test_unsortable_keys(self): # Ensure dicts with unsortable keys do not crash d1 = {} @@ -415,13 +409,13 @@ def test_directly_recursive(self): value = {1: None} value[2] = value - self.assert_unchanged(value, '{1: None, 2: {...}}') + self.assert_unchanged(value, "{1: None, 2: {...}}") def test_indirectly_recursive(self): value = {1: None} value[2] = {3: value} - self.assert_unchanged(value, '{1: None, 2: {3: {...}}}') + self.assert_unchanged(value, "{1: None, 2: {3: {...}}}") class TestOtherPythonTypes(SafeReprTestBase): @@ -448,24 +442,22 @@ def test_range_small(self): range_name = range.__name__ value = range(1, 42) - self.assert_unchanged(value, '%s(1, 42)' % (range_name,)) + self.assert_unchanged(value, "%s(1, 42)" % (range_name,)) - @pytest.mark.skipif(sys.version_info < (3, 0), reason='Py3 specific test') + @pytest.mark.skipif(sys.version_info < (3, 0), reason="Py3 specific test") def test_range_large_stop_only(self): range_name = range.__name__ stop = SafeRepr.maxcollection[0] value = range(stop) - self.assert_unchanged(value, - '%s(0, %s)' % (range_name, stop)) + self.assert_unchanged(value, "%s(0, %s)" % (range_name, stop)) def test_range_large_with_start(self): range_name = range.__name__ stop = SafeRepr.maxcollection[0] + 1 value = range(1, stop) - self.assert_unchanged(value, - '%s(1, %s)' % (range_name, stop)) + self.assert_unchanged(value, "%s(1, %s)" % (range_name, stop)) # @pytest.mark.skip(reason='not written') # TODO: finish! # def test_named_struct(self): @@ -483,11 +475,8 @@ def test_range_large_with_start(self): class TestUserDefinedObjects(SafeReprTestBase): - def test_broken_repr(self): - class TestClass(object): - def __repr__(self): raise NameError @@ -498,18 +487,15 @@ def __repr__(self): self.assert_saferepr(value, object.__repr__(value)) def test_large(self): - class TestClass(object): - def __repr__(self): - return '<' + 'A' * SafeRepr.maxother_outer * 2 + '>' + return "<" + "A" * SafeRepr.maxother_outer * 2 + ">" value = TestClass() - self.assert_shortened_regex(value, r'\') + self.assert_shortened_regex(value, r"\") def test_inherit_repr(self): - class TestClass(dict): pass @@ -520,66 +506,59 @@ class TestClass2(list): value_list = TestClass2() - self.assert_unchanged(value_dict, '{}') - self.assert_unchanged(value_list, '[]') + self.assert_unchanged(value_dict, "{}") + self.assert_unchanged(value_list, "[]") def test_custom_repr(self): - class TestClass(dict): - def __repr__(self): - return 'MyRepr' + return "MyRepr" value1 = TestClass() class TestClass2(list): - def __repr__(self): - return 'MyRepr' + return "MyRepr" value2 = TestClass2() - self.assert_unchanged(value1, 'MyRepr') - self.assert_unchanged(value2, 'MyRepr') + self.assert_unchanged(value1, "MyRepr") + self.assert_unchanged(value2, "MyRepr") def test_custom_repr_many_items(self): - class TestClass(list): - def __init__(self, it=()): list.__init__(self, it) def __repr__(self): - return 'MyRepr' + return "MyRepr" value1 = TestClass(range(0, 15)) value2 = TestClass(range(0, 16)) value3 = TestClass([TestClass(range(0, 10))]) value4 = TestClass([TestClass(range(0, 11))]) - self.assert_unchanged(value1, 'MyRepr') - self.assert_shortened(value2, '') - self.assert_unchanged(value3, 'MyRepr') - self.assert_shortened(value4, '') + self.assert_unchanged(value1, "MyRepr") + self.assert_shortened(value2, "") + self.assert_unchanged(value3, "MyRepr") + self.assert_shortened(value4, "") def test_custom_repr_large_item(self): - class TestClass(list): - def __init__(self, it=()): list.__init__(self, it) def __repr__(self): - return 'MyRepr' + return "MyRepr" - value1 = TestClass(['a' * (SafeRepr.maxcollection[1] + 1)]) - value2 = TestClass(['a' * (SafeRepr.maxstring_inner + 1)]) + value1 = TestClass(["a" * (SafeRepr.maxcollection[1] + 1)]) + value2 = TestClass(["a" * (SafeRepr.maxstring_inner + 1)]) - self.assert_unchanged(value1, 'MyRepr') - self.assert_shortened(value2, '') + self.assert_unchanged(value1, "MyRepr") + self.assert_shortened(value2, "") -@pytest.mark.skipif(np is None, reason='could not import numpy') +@pytest.mark.skipif(np is None, reason="could not import numpy") class TestNumpy(SafeReprTestBase): # numpy types should all use their native reprs, even arrays # exceeding limits. @@ -600,33 +579,34 @@ def test_zeros(self): self.assert_unchanged(value, repr(value)) -@pytest.mark.parametrize('params', [ - {'maxother_outer': 20, 'input': "😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄FFFFFFFF", 'output': '😄😄😄😄😄😄😄😄😄😄😄😄😄...FFFFFF'}, - {'maxother_outer': 10, 'input': "😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄FFFFFFFF", 'output': '😄😄😄😄😄😄...FFF'}, - {'maxother_outer': 10, 'input': u"������������FFFFFFFF", 'output': u"������...FFF"}, - - # Because we can't return bytes, byte-related tests aren't needed (and str works as it should). -]) -@pytest.mark.parametrize('use_str', [True, False]) +@pytest.mark.parametrize( + "params", + [ + {"maxother_outer": 20, "input": "😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄FFFFFFFF", "output": "😄😄😄😄😄😄😄😄😄😄😄😄😄...FFFFFF"}, + {"maxother_outer": 10, "input": "😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄😄FFFFFFFF", "output": "😄😄😄😄😄😄...FFF"}, + {"maxother_outer": 10, "input": "������������FFFFFFFF", "output": "������...FFF"}, + # Because we can't return bytes, byte-related tests aren't needed (and str works as it should). + ], +) +@pytest.mark.parametrize("use_str", [True, False]) def test_py3_str_slicing(params, use_str): # Note: much simpler in python because __repr__ is required to return str safe_repr = SafeRepr() - safe_repr.locale_preferred_encoding = 'ascii' - safe_repr.sys_stdout_encoding = params.get('sys_stdout_encoding', 'ascii') + safe_repr.locale_preferred_encoding = "ascii" + safe_repr.sys_stdout_encoding = params.get("sys_stdout_encoding", "ascii") - safe_repr.maxother_outer = params['maxother_outer'] + safe_repr.maxother_outer = params["maxother_outer"] if not use_str: class MyObj(object): - def __repr__(self): - return params['input'] + return params["input"] safe_repr_input = MyObj() else: - safe_repr_input = params['input'] - expected_output = params['output'] + safe_repr_input = params["input"] + expected_output = params["output"] computed = safe_repr(safe_repr_input) expected = repr(expected_output) if use_str: @@ -640,25 +620,23 @@ def __repr__(self): def test_raw_bytes(): safe_repr = SafeRepr() safe_repr.raw_value = True - obj = b'\xed\xbd\xbf\xff\xfe\xfa\xfd' + obj = b"\xed\xbd\xbf\xff\xfe\xfa\xfd" raw_value_repr = safe_repr(obj) assert isinstance(raw_value_repr, str) # bytes on py2, str on py3 - assert raw_value_repr == obj.decode('latin1') + assert raw_value_repr == obj.decode("latin1") def test_raw_unicode(): safe_repr = SafeRepr() safe_repr.raw_value = True - obj = u'\xed\xbd\xbf\xff\xfe\xfa\xfd' + obj = "\xed\xbd\xbf\xff\xfe\xfa\xfd" raw_value_repr = safe_repr(obj) assert isinstance(raw_value_repr, str) # bytes on py2, str on py3 assert raw_value_repr == obj def test_no_repr(): - class MyBytes(object): - def __init__(self, contents): self.contents = contents self.errored = None @@ -667,12 +645,12 @@ def __iter__(self): return iter(self.contents) def decode(self, encoding): - self.errored = 'decode called' - raise RuntimeError('Should not be called.') + self.errored = "decode called" + raise RuntimeError("Should not be called.") def __repr__(self): - self.errored = '__repr__ called' - raise RuntimeError('Should not be called.') + self.errored = "__repr__ called" + raise RuntimeError("Should not be called.") def __getitem__(self, *args): return self.contents.__getitem__(*args) @@ -683,8 +661,7 @@ def __len__(self): safe_repr = SafeRepr() safe_repr.string_types = (MyBytes,) safe_repr.bytes = MyBytes - obj = b'f' * (safe_repr.maxstring_outer * 10) + obj = b"f" * (safe_repr.maxstring_outer * 10) my_bytes = MyBytes(obj) raw_value_repr = safe_repr(my_bytes) assert not my_bytes.errored - diff --git a/tests_python/test_save_locals.py b/tests_python/test_save_locals.py index ed4bd2c4e..93f78abed 100644 --- a/tests_python/test_save_locals.py +++ b/tests_python/test_save_locals.py @@ -25,13 +25,12 @@ def check_method(fn): x = 1 # The method 'fn' should attempt to set x = 2 in the current frame. - fn('x', 2) + fn("x", 2) return x - -@pytest.mark.skipif(IS_JYTHON or IS_IRONPYTHON, reason='CPython/pypy only') +@pytest.mark.skipif(IS_JYTHON or IS_IRONPYTHON, reason="CPython/pypy only") class TestSetLocals(unittest.TestCase): """ Test setting locals in one function from another function using several approaches. @@ -41,61 +40,56 @@ def test_set_locals_using_save_locals(self): x = check_method(use_save_locals) self.assertEqual(x, 2) # Expected to succeed - def test_frame_simple_change(self): frame = sys._getframe() a = 20 - frame.f_locals['a'] = 50 + frame.f_locals["a"] = 50 save_locals(frame) self.assertEqual(50, a) - def test_frame_co_freevars(self): - outer_var = 20 def func(): frame = sys._getframe() - frame.f_locals['outer_var'] = 50 + frame.f_locals["outer_var"] = 50 save_locals(frame) self.assertEqual(50, outer_var) func() def test_frame_co_cellvars(self): - def check_co_vars(a): frame = sys._getframe() + def function2(): print(a) - assert 'a' in frame.f_code.co_cellvars + assert "a" in frame.f_code.co_cellvars frame = sys._getframe() - frame.f_locals['a'] = 50 + frame.f_locals["a"] = 50 save_locals(frame) self.assertEqual(50, a) check_co_vars(1) - def test_frame_change_in_inner_frame(self): def change(f): self.assertTrue(f is not sys._getframe()) - f.f_locals['a']= 50 + f.f_locals["a"] = 50 save_locals(f) - frame = sys._getframe() a = 20 change(frame) self.assertEqual(50, a) -if __name__ == '__main__': +if __name__ == "__main__": suite = unittest.TestSuite() -# suite.addTest(TestSetLocals('test_set_locals_using_dict')) -# #suite.addTest(Test('testCase10a')) -# unittest.TextTestRunner(verbosity=3).run(suite) + # suite.addTest(TestSetLocals('test_set_locals_using_dict')) + # #suite.addTest(Test('testCase10a')) + # unittest.TextTestRunner(verbosity=3).run(suite) suite = unittest.makeSuite(TestSetLocals) unittest.TextTestRunner(verbosity=3).run(suite) diff --git a/tests_python/test_schema.py b/tests_python/test_schema.py index 54700769b..d146a95e4 100644 --- a/tests_python/test_schema.py +++ b/tests_python/test_schema.py @@ -1,12 +1,10 @@ -from _pydevd_bundle._debug_adapter.pydevd_schema import InitializeRequest, \ - InitializeRequestArguments, InitializeResponse, Capabilities +from _pydevd_bundle._debug_adapter.pydevd_schema import InitializeRequest, InitializeRequestArguments, InitializeResponse, Capabilities from _pydevd_bundle._debug_adapter import pydevd_schema, pydevd_base_schema from _pydevd_bundle._debug_adapter.pydevd_schema import ThreadsResponse def test_schema(): - - json_msg = ''' + json_msg = """ { "arguments": { "adapterID": "pydevd", @@ -23,49 +21,38 @@ def test_schema(): "command": "initialize", "seq": 1, "type": "request" -}''' +}""" initialize_request = pydevd_base_schema.from_json(json_msg) assert initialize_request.__class__ == InitializeRequest assert initialize_request.arguments.__class__ == InitializeRequestArguments - assert initialize_request.arguments.adapterID == 'pydevd' - assert initialize_request.command == 'initialize' - assert initialize_request.type == 'request' + assert initialize_request.arguments.adapterID == "pydevd" + assert initialize_request.command == "initialize" + assert initialize_request.type == "request" assert initialize_request.seq == 1 response = pydevd_base_schema.build_response(initialize_request) assert response.__class__ == InitializeResponse assert response.seq == -1 # Must be set before sending - assert response.command == 'initialize' - assert response.type == 'response' + assert response.command == "initialize" + assert response.type == "response" assert response.body.__class__ == Capabilities - assert response.to_dict() == { - "seq":-1, - "type": "response", - "request_seq": 1, - "success": True, - "command": "initialize", - "body": {} - } + assert response.to_dict() == {"seq": -1, "type": "response", "request_seq": 1, "success": True, "command": "initialize", "body": {}} capabilities = response.body # : :type capabilities: Capabilities capabilities.supportsCompletionsRequest = True assert response.to_dict() == { - "seq":-1, + "seq": -1, "type": "response", "request_seq": 1, "success": True, "command": "initialize", - "body": {'supportsCompletionsRequest':True} + "body": {"supportsCompletionsRequest": True}, } initialize_event = pydevd_schema.InitializedEvent() - assert initialize_event.to_dict() == { - "seq":-1, - "type": "event", - "event": "initialized" - } + assert initialize_event.to_dict() == {"seq": -1, "type": "event", "event": "initialized"} def test_schema_translation_frame(): @@ -74,69 +61,75 @@ def test_schema_translation_frame(): stack_trace_request = pydevd_schema.StackTraceRequest(stack_trace_arguments) stackFrames = [ - pydevd_schema.StackFrame(id=2 ** 45, name='foo', line=1, column=1).to_dict(), - pydevd_schema.StackFrame(id=2 ** 46, name='bar', line=1, column=1).to_dict(), + pydevd_schema.StackFrame(id=2**45, name="foo", line=1, column=1).to_dict(), + pydevd_schema.StackFrame(id=2**46, name="bar", line=1, column=1).to_dict(), ] body = pydevd_schema.StackTraceResponseBody(stackFrames) stack_trace_response = pydevd_base_schema.build_response(stack_trace_request, kwargs=dict(body=body)) as_dict = stack_trace_response.to_dict(update_ids_to_dap=True) assert as_dict == { - 'type': 'response', - 'request_seq':-1, - 'success': True, - 'command': 'stackTrace', - 'body': {'stackFrames': [ - {'id': 1, 'name': 'foo', 'line': 1, 'column': 1, 'source': {}}, - {'id': 2, 'name': 'bar', 'line': 1, 'column': 1, 'source': {}}, - ]}, - 'seq':-1} + "type": "response", + "request_seq": -1, + "success": True, + "command": "stackTrace", + "body": { + "stackFrames": [ + {"id": 1, "name": "foo", "line": 1, "column": 1, "source": {}}, + {"id": 2, "name": "bar", "line": 1, "column": 1, "source": {}}, + ] + }, + "seq": -1, + } reconstructed = pydevd_base_schema.from_dict(as_dict, update_ids_from_dap=True) assert reconstructed.to_dict() == { - 'type': 'response', - 'request_seq':-1, - 'success': True, - 'command': 'stackTrace', - 'body': {'stackFrames': [ - {'id': 2 ** 45, 'name': 'foo', 'line': 1, 'column': 1, 'source': {}}, - {'id': 2 ** 46, 'name': 'bar', 'line': 1, 'column': 1, 'source': {}} - ]}, - 'seq':-1 + "type": "response", + "request_seq": -1, + "success": True, + "command": "stackTrace", + "body": { + "stackFrames": [ + {"id": 2**45, "name": "foo", "line": 1, "column": 1, "source": {}}, + {"id": 2**46, "name": "bar", "line": 1, "column": 1, "source": {}}, + ] + }, + "seq": -1, } def test_schema_translation_thread(): from _pydevd_bundle._debug_adapter.pydevd_schema import ThreadsRequest + pydevd_base_schema.BaseSchema.initialize_ids_translation() threads = [ - pydevd_schema.Thread(id=2 ** 45, name='foo').to_dict(), - pydevd_schema.Thread(id=2 ** 46, name='bar').to_dict(), + pydevd_schema.Thread(id=2**45, name="foo").to_dict(), + pydevd_schema.Thread(id=2**46, name="bar").to_dict(), ] body = pydevd_schema.ThreadsResponseBody(threads) threads_request = ThreadsRequest() threads_response = pydevd_base_schema.build_response(threads_request, kwargs=dict(body=body)) as_dict = threads_response.to_dict(update_ids_to_dap=True) assert as_dict == { - 'type': 'response', - 'request_seq':-1, - 'success': True, - 'command': 'threads', - 'body': {'threads': [ - {'id': 1, 'name': 'foo'}, - {'id': 2, 'name': 'bar'}, - ]}, - 'seq':-1} + "type": "response", + "request_seq": -1, + "success": True, + "command": "threads", + "body": { + "threads": [ + {"id": 1, "name": "foo"}, + {"id": 2, "name": "bar"}, + ] + }, + "seq": -1, + } reconstructed = pydevd_base_schema.from_dict(as_dict, update_ids_from_dap=True) assert reconstructed.to_dict() == { - 'type': 'response', - 'request_seq':-1, - 'success': True, - 'command': 'threads', - 'body': {'threads': [ - {'id': 2 ** 45, 'name': 'foo'}, - {'id': 2 ** 46, 'name': 'bar'} - ]}, - 'seq':-1 + "type": "response", + "request_seq": -1, + "success": True, + "command": "threads", + "body": {"threads": [{"id": 2**45, "name": "foo"}, {"id": 2**46, "name": "bar"}]}, + "seq": -1, } diff --git a/tests_python/test_single_notification.py b/tests_python/test_single_notification.py index 02c48cbc5..d96994e6f 100644 --- a/tests_python/test_single_notification.py +++ b/tests_python/test_single_notification.py @@ -15,7 +15,6 @@ class _ThreadInfo(object): - next_thread_id = partial(next, itertools.count()) def __init__(self): @@ -25,10 +24,9 @@ def __init__(self): class _CustomSingleNotificationBehavior(AbstractSingleNotificationBehavior): + NOTIFY_OF_PAUSE_TIMEOUT = 0.01 - NOTIFY_OF_PAUSE_TIMEOUT = .01 - - __slots__ = AbstractSingleNotificationBehavior.__slots__ + ['notification_queue'] + __slots__ = AbstractSingleNotificationBehavior.__slots__ + ["notification_queue"] def __init__(self, py_db): try: @@ -41,17 +39,17 @@ def __init__(self, py_db): @overrides(AbstractSingleNotificationBehavior.send_resume_notification) def send_resume_notification(self, *args, **kwargs): # print('put resume', threading.current_thread()) - self.notification_queue.put('resume') + self.notification_queue.put("resume") @overrides(AbstractSingleNotificationBehavior.send_suspend_notification) def send_suspend_notification(self, *args, **kwargs): # print('put suspend', threading.current_thread()) - self.notification_queue.put('suspend') + self.notification_queue.put("suspend") def do_wait_suspend(self, thread_info, stop_reason): with self.notify_thread_suspended(thread_info.thread_id, thread_info.thread, stop_reason=stop_reason): while thread_info.state == STATE_SUSPEND: - time.sleep(.1) + time.sleep(0.1) @pytest.fixture @@ -60,15 +58,15 @@ def _dummy_pydb(): @pytest.fixture( - name='single_notification_behavior', -# params=range(50) # uncomment to run the tests many times. + name="single_notification_behavior", + # params=range(50) # uncomment to run the tests many times. ) def _single_notification_behavior(_dummy_pydb): single_notification_behavior = _CustomSingleNotificationBehavior(_dummy_pydb) return single_notification_behavior -@pytest.fixture(name='notification_queue') +@pytest.fixture(name="notification_queue") def _notification_queue(single_notification_behavior): return single_notification_behavior.notification_queue @@ -83,25 +81,25 @@ def wait_for_notification(notification_queue, msg): found = notification_queue.get(timeout=2) assert found == msg except Empty: - raise AssertionError('Timed out while waiting for %s notification.' % (msg,)) + raise AssertionError("Timed out while waiting for %s notification." % (msg,)) def join_thread(t): __tracebackhide__ = True t.join(2) - assert not t.is_alive(), 'Thread still alive after timeout.s' + assert not t.is_alive(), "Thread still alive after timeout.s" class _DummyPyDB(object): - def __init__(self): from _pydevd_bundle.pydevd_timeout import TimeoutTracker + self.created_pydb_daemon_threads = {} self.timeout_tracker = TimeoutTracker(self) def test_single_notification_1(single_notification_behavior, notification_queue): - ''' + """ 1. Resume before pausing 2nd thread - user pauses all (2) threads @@ -109,7 +107,7 @@ def test_single_notification_1(single_notification_behavior, notification_queue) - user presses continue all before second is paused - 2nd should not pause nor send notification - resume all notification should be sent - ''' + """ thread_info1 = _ThreadInfo() thread_info2 = _ThreadInfo() @@ -128,8 +126,8 @@ def test_single_notification_1(single_notification_behavior, notification_queue) t.join() assert notification_queue.qsize() == 2 - assert notification_queue.get() == 'suspend' - assert notification_queue.get() == 'resume' + assert notification_queue.get() == "suspend" + assert notification_queue.get() == "resume" assert notification_queue.qsize() == 0 # Run thread 2 only now (no additional notification). @@ -140,7 +138,7 @@ def test_single_notification_1(single_notification_behavior, notification_queue) def test_single_notification_2(single_notification_behavior, notification_queue): - ''' + """ 2. Pausing all then stepping - user pauses all (2) threads @@ -148,7 +146,7 @@ def test_single_notification_2(single_notification_behavior, notification_queue) - break second (no notification) - user steps in second - suspend in second -> send resume/pause notification on step - ''' + """ thread_info1 = _ThreadInfo() thread_info2 = _ThreadInfo() @@ -162,7 +160,7 @@ def test_single_notification_2(single_notification_behavior, notification_queue) # Leave both in break mode t1 = run_as_pydevd_daemon_thread(dummy_py_db, single_notification_behavior.do_wait_suspend, thread_info1, CMD_THREAD_SUSPEND) - wait_for_notification(notification_queue, 'suspend') + wait_for_notification(notification_queue, "suspend") t2 = run_as_pydevd_daemon_thread(dummy_py_db, single_notification_behavior.do_wait_suspend, thread_info2, CMD_THREAD_SUSPEND) @@ -171,17 +169,17 @@ def test_single_notification_2(single_notification_behavior, notification_queue) # the step mode). thread_info2.state = STATE_RUN join_thread(t2) - wait_for_notification(notification_queue, 'resume') + wait_for_notification(notification_queue, "resume") single_notification_behavior.increment_suspend_time() thread_info2.state = STATE_SUSPEND t2 = run_as_pydevd_daemon_thread(dummy_py_db, single_notification_behavior.do_wait_suspend, thread_info2, CMD_STEP_OVER) - wait_for_notification(notification_queue, 'suspend') + wait_for_notification(notification_queue, "suspend") thread_info1.state = STATE_RUN thread_info2.state = STATE_RUN # First does a resume notification, the other remains quiet. - wait_for_notification(notification_queue, 'resume') + wait_for_notification(notification_queue, "resume") join_thread(t2) join_thread(t1) @@ -189,7 +187,7 @@ def test_single_notification_2(single_notification_behavior, notification_queue) def test_single_notification_3(single_notification_behavior, notification_queue, _dummy_pydb): - ''' + """ 3. Deadlocked thread - user adds breakpoint in thread.join() -- just before threads becomes deadlocked @@ -201,7 +199,7 @@ def test_single_notification_3(single_notification_behavior, notification_queue, - send notification regarding 2nd thread (still stopped). - leave both threads running: no suspend should be shown as there are no stopped threads - when thread is paused, show suspend notification - ''' + """ # i.e.: stopping at breakpoint thread_info1 = _ThreadInfo() @@ -214,11 +212,11 @@ def test_single_notification_3(single_notification_behavior, notification_queue, thread_info2.state = STATE_SUSPEND t2 = run_as_pydevd_daemon_thread(_dummy_pydb, single_notification_behavior.do_wait_suspend, thread_info2, CMD_SET_BREAK) - wait_for_notification(notification_queue, 'suspend') + wait_for_notification(notification_queue, "suspend") # i.e.: step over (thread 2 is still suspended and this one never completes) thread_info1.state = STATE_RUN - wait_for_notification(notification_queue, 'resume') + wait_for_notification(notification_queue, "resume") join_thread(t1) @@ -227,10 +225,10 @@ def test_single_notification_3(single_notification_behavior, notification_queue, single_notification_behavior.on_pause() thread_info1.state = STATE_SUSPEND thread_info2.state = STATE_SUSPEND - wait_for_notification(notification_queue, 'suspend') + wait_for_notification(notification_queue, "suspend") thread_info2.state = STATE_RUN - wait_for_notification(notification_queue, 'resume') + wait_for_notification(notification_queue, "resume") join_thread(t2) assert notification_queue.qsize() == 0 @@ -249,15 +247,15 @@ def test_single_notification_3(single_notification_behavior, notification_queue, assert notification_queue.qsize() == 0 t1 = run_as_pydevd_daemon_thread(_dummy_pydb, single_notification_behavior.do_wait_suspend, thread_info1, CMD_THREAD_SUSPEND) - wait_for_notification(notification_queue, 'suspend') + wait_for_notification(notification_queue, "suspend") thread_info1.state = STATE_RUN - wait_for_notification(notification_queue, 'resume') + wait_for_notification(notification_queue, "resume") join_thread(t1) assert notification_queue.qsize() == 0 def test_single_notification_4(single_notification_behavior, notification_queue, _dummy_pydb): - ''' + """ 4. Delayed stop - user presses pause @@ -265,7 +263,7 @@ def test_single_notification_4(single_notification_behavior, notification_queue, - user steps on first - 2nd hits before first ends step (should not send any notification) - when step finishes send notification - ''' + """ thread_info1 = _ThreadInfo() thread_info2 = _ThreadInfo() @@ -275,23 +273,22 @@ def test_single_notification_4(single_notification_behavior, notification_queue, thread_info2.state = STATE_SUSPEND t1 = run_as_pydevd_daemon_thread(_dummy_pydb, single_notification_behavior.do_wait_suspend, thread_info1, CMD_THREAD_SUSPEND) - wait_for_notification(notification_queue, 'suspend') + wait_for_notification(notification_queue, "suspend") thread_info1.state = STATE_RUN - wait_for_notification(notification_queue, 'resume') + wait_for_notification(notification_queue, "resume") join_thread(t1) t2 = run_as_pydevd_daemon_thread(_dummy_pydb, single_notification_behavior.do_wait_suspend, thread_info1, CMD_THREAD_SUSPEND) - time.sleep(.1) + time.sleep(0.1) assert notification_queue.qsize() == 0 single_notification_behavior.increment_suspend_time() thread_info1.state = STATE_SUSPEND t1 = run_as_pydevd_daemon_thread(_dummy_pydb, single_notification_behavior.do_wait_suspend, thread_info1, CMD_STEP_OVER) - wait_for_notification(notification_queue, 'suspend') + wait_for_notification(notification_queue, "suspend") thread_info2.state = STATE_RUN thread_info1.state = STATE_RUN join_thread(t1) join_thread(t2) - wait_for_notification(notification_queue, 'resume') + wait_for_notification(notification_queue, "resume") assert notification_queue.qsize() == 0 - diff --git a/tests_python/test_suspended_frames_manager.py b/tests_python/test_suspended_frames_manager.py index 5b63c603d..9aa3793aa 100644 --- a/tests_python/test_suspended_frames_manager.py +++ b/tests_python/test_suspended_frames_manager.py @@ -18,20 +18,21 @@ def check_vars_dict_expected(as_dict, expected): class _DummyPyDB(object): - def __init__(self): from _pydevd_bundle.pydevd_api import PyDevdAPI + self.variable_presentation = PyDevdAPI.VariablePresentation() def test_suspended_frames_manager(): from _pydevd_bundle.pydevd_suspended_frames import SuspendedFramesManager from _pydevd_bundle.pydevd_utils import DAPGrouper + suspended_frames_manager = SuspendedFramesManager() py_db = _DummyPyDB() with suspended_frames_manager.track_frames(py_db) as tracker: # : :type tracker: _FramesTracker - thread_id = 'thread1' + thread_id = "thread1" frame = get_frame() tracker.track(thread_id, pydevd_frame_utils.create_frames_list_from_frame(frame)) @@ -40,54 +41,77 @@ def test_suspended_frames_manager(): variable = suspended_frames_manager.get_variable(id(frame)) # Should be properly sorted. - assert ['var1', 'var2', 'var3'] == [x.get_name()for x in variable.get_children_variables()] + assert ["var1", "var2", "var3"] == [x.get_name() for x in variable.get_children_variables()] as_dict = dict((x.get_name(), x.get_var_data()) for x in variable.get_children_variables()) - var_reference = as_dict['var2'].pop('variablesReference') + var_reference = as_dict["var2"].pop("variablesReference") assert isinstance(var_reference, int_types) # The variable reference is always a new int. - assert isinstance(as_dict['var3'].pop('variablesReference'), int_types) # The variable reference is always a new int. + assert isinstance(as_dict["var3"].pop("variablesReference"), int_types) # The variable reference is always a new int. - check_vars_dict_expected(as_dict, { - 'var1': {'name': 'var1', 'value': '1', 'type': 'int', 'evaluateName': 'var1', 'variablesReference': 0}, - 'var2': {'name': 'var2', 'value': '[1]', 'type': 'list', 'evaluateName': 'var2'}, - 'var3': {'name': 'var3', 'value': '{33: [1]}', 'type': 'dict', 'evaluateName': 'var3'} - }) + check_vars_dict_expected( + as_dict, + { + "var1": {"name": "var1", "value": "1", "type": "int", "evaluateName": "var1", "variablesReference": 0}, + "var2": {"name": "var2", "value": "[1]", "type": "list", "evaluateName": "var2"}, + "var3": {"name": "var3", "value": "{33: [1]}", "type": "dict", "evaluateName": "var3"}, + }, + ) # Now, same thing with a different format. - as_dict = dict((x.get_name(), x.get_var_data(fmt={'hex': True})) for x in variable.get_children_variables()) - var_reference = as_dict['var2'].pop('variablesReference') + as_dict = dict((x.get_name(), x.get_var_data(fmt={"hex": True})) for x in variable.get_children_variables()) + var_reference = as_dict["var2"].pop("variablesReference") assert isinstance(var_reference, int_types) # The variable reference is always a new int. - assert isinstance(as_dict['var3'].pop('variablesReference'), int_types) # The variable reference is always a new int. - - check_vars_dict_expected(as_dict, { - 'var1': {'name': 'var1', 'value': '0x1', 'type': 'int', 'evaluateName': 'var1', 'variablesReference': 0}, - 'var2': {'name': 'var2', 'value': '[0x1]', 'type': 'list', 'evaluateName': 'var2'}, - 'var3': {'name': 'var3', 'value': '{0x21: [0x1]}', 'type': 'dict', 'evaluateName': 'var3'} - }) - - var2 = dict((x.get_name(), x) for x in variable.get_children_variables())['var2'] + assert isinstance(as_dict["var3"].pop("variablesReference"), int_types) # The variable reference is always a new int. + + check_vars_dict_expected( + as_dict, + { + "var1": {"name": "var1", "value": "0x1", "type": "int", "evaluateName": "var1", "variablesReference": 0}, + "var2": {"name": "var2", "value": "[0x1]", "type": "list", "evaluateName": "var2"}, + "var3": {"name": "var3", "value": "{0x21: [0x1]}", "type": "dict", "evaluateName": "var3"}, + }, + ) + + var2 = dict((x.get_name(), x) for x in variable.get_children_variables())["var2"] children_vars = var2.get_children_variables() - as_dict = (dict([x.get_name(), x.get_var_data()] for x in children_vars if x.get_name() not in DAPGrouper.SCOPES_SORTED)) + as_dict = dict([x.get_name(), x.get_var_data()] for x in children_vars if x.get_name() not in DAPGrouper.SCOPES_SORTED) assert as_dict == { - '0': {'name': '0', 'value': '1', 'type': 'int', 'evaluateName': 'var2[0]', 'variablesReference': 0 }, - GENERATED_LEN_ATTR_NAME: {'name': GENERATED_LEN_ATTR_NAME, 'value': '1', 'type': 'int', 'evaluateName': 'len(var2)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}, }, + "0": {"name": "0", "value": "1", "type": "int", "evaluateName": "var2[0]", "variablesReference": 0}, + GENERATED_LEN_ATTR_NAME: { + "name": GENERATED_LEN_ATTR_NAME, + "value": "1", + "type": "int", + "evaluateName": "len(var2)", + "variablesReference": 0, + "presentationHint": {"attributes": ["readOnly"]}, + }, } - var3 = dict((x.get_name(), x) for x in variable.get_children_variables())['var3'] + var3 = dict((x.get_name(), x) for x in variable.get_children_variables())["var3"] children_vars = var3.get_children_variables() - as_dict = (dict([x.get_name(), x.get_var_data()] for x in children_vars if x.get_name() not in DAPGrouper.SCOPES_SORTED)) - assert isinstance(as_dict['33'].pop('variablesReference'), int_types) # The variable reference is always a new int. - - check_vars_dict_expected(as_dict, { - '33': {'name': '33', 'value': "[1]", 'type': 'list', 'evaluateName': 'var3[33]'}, - GENERATED_LEN_ATTR_NAME: {'name': GENERATED_LEN_ATTR_NAME, 'value': '1', 'type': 'int', 'evaluateName': 'len(var3)', 'variablesReference': 0, 'presentationHint': {'attributes': ['readOnly']}, } - }) + as_dict = dict([x.get_name(), x.get_var_data()] for x in children_vars if x.get_name() not in DAPGrouper.SCOPES_SORTED) + assert isinstance(as_dict["33"].pop("variablesReference"), int_types) # The variable reference is always a new int. + + check_vars_dict_expected( + as_dict, + { + "33": {"name": "33", "value": "[1]", "type": "list", "evaluateName": "var3[33]"}, + GENERATED_LEN_ATTR_NAME: { + "name": GENERATED_LEN_ATTR_NAME, + "value": "1", + "type": "int", + "evaluateName": "len(var3)", + "variablesReference": 0, + "presentationHint": {"attributes": ["readOnly"]}, + }, + }, + ) def get_dict_large_frame(): obj = {} for idx in range(pydevd_constants.PYDEVD_CONTAINER_RANDOM_ACCESS_MAX_ITEMS + +300): - obj[idx] = (1) + obj[idx] = 1 return sys._getframe() @@ -100,35 +124,35 @@ def get_set_large_frame(): def test_get_child_variables(): from _pydevd_bundle.pydevd_suspended_frames import SuspendedFramesManager + suspended_frames_manager = SuspendedFramesManager() py_db = _DummyPyDB() for frame in ( get_dict_large_frame(), get_set_large_frame(), - ): + ): with suspended_frames_manager.track_frames(py_db) as tracker: # : :type tracker: _FramesTracker - thread_id = 'thread1' + thread_id = "thread1" tracker.track(thread_id, pydevd_frame_utils.create_frames_list_from_frame(frame)) assert suspended_frames_manager.get_thread_id_for_variable_reference(id(frame)) == thread_id variable = suspended_frames_manager.get_variable(id(frame)) - children_variables = variable.get_child_variable_named('obj').get_children_variables() + children_variables = variable.get_child_variable_named("obj").get_children_variables() found_too_large = False found_len = False for x in children_variables: if x.name == TOO_LARGE_ATTR: var_data = x.get_var_data() - assert 'readOnly' in var_data['presentationHint']['attributes'] + assert "readOnly" in var_data["presentationHint"]["attributes"] found_too_large = True elif x.name == GENERATED_LEN_ATTR_NAME: found_len = True if not found_too_large: - raise AssertionError('Expected to find variable named: %s' % (TOO_LARGE_ATTR,)) + raise AssertionError("Expected to find variable named: %s" % (TOO_LARGE_ATTR,)) if not found_len: - raise AssertionError('Expected to find variable named: len()') - + raise AssertionError("Expected to find variable named: len()") diff --git a/tests_python/test_sys_monitoring.py b/tests_python/test_sys_monitoring.py index 90351a940..df96bb662 100644 --- a/tests_python/test_sys_monitoring.py +++ b/tests_python/test_sys_monitoring.py @@ -2,17 +2,17 @@ import pytest import threading -pytestmark = pytest.mark.skipif(not hasattr(sys, 'monitoring'), reason='Requires sys.monitoring') +pytestmark = pytest.mark.skipif(not hasattr(sys, "monitoring"), reason="Requires sys.monitoring") -if hasattr(sys, 'monitoring'): +if hasattr(sys, "monitoring"): DEBUGGER_ID = sys.monitoring.DEBUGGER_ID monitor = sys.monitoring def _disable_monitoring(): - if monitor.get_tool(DEBUGGER_ID) == 'pydevd': + if monitor.get_tool(DEBUGGER_ID) == "pydevd": sys.monitoring.set_events(sys.monitoring.DEBUGGER_ID, 0) - monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START , None) + monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, None) monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RESUME, None) monitor.register_callback(DEBUGGER_ID, monitor.events.LINE, None) monitor.register_callback(DEBUGGER_ID, monitor.events.RAISE, None) @@ -23,7 +23,7 @@ def _disable_monitoring(): @pytest.fixture def with_monitoring(): - monitor.use_tool_id(DEBUGGER_ID, 'pydevd') + monitor.use_tool_id(DEBUGGER_ID, "pydevd") yield _disable_monitoring() @@ -34,18 +34,18 @@ def test_exceptions(with_monitoring): found = [] def _on_raise(code, instruction_offset, exc): - if code.co_filename.endswith('sys_monitoring.py'): - found.append(('raise', code.co_name, str(exc), sys._getframe(1).f_lineno)) + if code.co_filename.endswith("sys_monitoring.py"): + found.append(("raise", code.co_name, str(exc), sys._getframe(1).f_lineno)) def _on_reraise(code, instruction_offset, exc): - if code.co_filename.endswith('sys_monitoring.py'): - found.append(('reraise', code.co_name, str(exc), sys._getframe(1).f_lineno)) + if code.co_filename.endswith("sys_monitoring.py"): + found.append(("reraise", code.co_name, str(exc), sys._getframe(1).f_lineno)) - monitor.register_callback(DEBUGGER_ID, monitor.events.RAISE , _on_raise) - monitor.register_callback(DEBUGGER_ID, monitor.events.RERAISE , _on_reraise) + monitor.register_callback(DEBUGGER_ID, monitor.events.RAISE, _on_raise) + monitor.register_callback(DEBUGGER_ID, monitor.events.RERAISE, _on_reraise) def method_raise(): - raise RuntimeError('err1') + raise RuntimeError("err1") def method_2(): try: @@ -61,13 +61,13 @@ def method(): method() assert found == [ - ('raise', 'method_raise', 'err1', method_raise.__code__.co_firstlineno + 1), - ('raise', 'method_2', 'err1', method_2.__code__.co_firstlineno + 2), + ("raise", "method_raise", "err1", method_raise.__code__.co_firstlineno + 1), + ("raise", "method_2", "err1", method_2.__code__.co_firstlineno + 2), # This will be very tricky to handle. # See: https://github.com/python/cpython/issues/112086 - ('reraise', 'method_2', 'err1', method_2.__code__.co_firstlineno + 4), - ('reraise', 'method_2', 'err1', method_2.__code__.co_firstlineno + 4), - ('raise', 'method', 'err1', method.__code__.co_firstlineno + 2), + ("reraise", "method_2", "err1", method_2.__code__.co_firstlineno + 4), + ("reraise", "method_2", "err1", method_2.__code__.co_firstlineno + 4), + ("raise", "method", "err1", method.__code__.co_firstlineno + 2), ] @@ -77,23 +77,23 @@ def test_exceptions_and_return(with_monitoring): found = [] def _on_raise(code, instruction_offset, exc): - if code.co_filename.endswith('sys_monitoring.py'): - found.append(('raise', code.co_name, str(exc), sys._getframe(1).f_lineno)) + if code.co_filename.endswith("sys_monitoring.py"): + found.append(("raise", code.co_name, str(exc), sys._getframe(1).f_lineno)) def _on_return(code, instruction_offset, val): - if code.co_filename.endswith('sys_monitoring.py'): - found.append(('return', code.co_name, str(val), sys._getframe(1).f_lineno)) + if code.co_filename.endswith("sys_monitoring.py"): + found.append(("return", code.co_name, str(val), sys._getframe(1).f_lineno)) def _on_unwind(code, instruction_offset, val): - if code.co_filename.endswith('sys_monitoring.py'): - found.append(('unwind', code.co_name, str(val), sys._getframe(1).f_lineno)) + if code.co_filename.endswith("sys_monitoring.py"): + found.append(("unwind", code.co_name, str(val), sys._getframe(1).f_lineno)) - monitor.register_callback(DEBUGGER_ID, monitor.events.RAISE , _on_raise) - monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RETURN , _on_return) - monitor.register_callback(DEBUGGER_ID, monitor.events.PY_UNWIND , _on_unwind) + monitor.register_callback(DEBUGGER_ID, monitor.events.RAISE, _on_raise) + monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RETURN, _on_return) + monitor.register_callback(DEBUGGER_ID, monitor.events.PY_UNWIND, _on_unwind) def method_raise(): - raise RuntimeError('err1') + raise RuntimeError("err1") def method_2(): try: @@ -110,12 +110,12 @@ def method(): method() assert found == [ - ('raise', 'method_raise', 'err1', 96), - ('unwind', 'method_raise', 'err1', 96), - ('raise', 'method_2', 'err1', 100), - ('unwind', 'method_2', 'err1', 102), # This will be helpful for unhandled exceptions! - ('raise', 'method', 'err1', 106), - ('return', 'method', 'None', 108), + ("raise", "method_raise", "err1", 96), + ("unwind", "method_raise", "err1", 96), + ("raise", "method_2", "err1", 100), + ("unwind", "method_2", "err1", 102), # This will be helpful for unhandled exceptions! + ("raise", "method", "err1", 106), + ("return", "method", "None", 108), ] @@ -125,11 +125,11 @@ def test_variables_on_call(with_monitoring): found = [] def _start_method(code, offset): - if code.co_name == 'method': + if code.co_name == "method": frame = sys._getframe(1) - found.append(frame.f_locals['arg1']) + found.append(frame.f_locals["arg1"]) - monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START , _start_method) + monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, _start_method) def method(arg1): pass @@ -139,23 +139,22 @@ def method(arg1): def test_disabling_code(with_monitoring): - executed = [] def _start_method(code, offset): - if code.co_name == 'method': - executed.append(('start', code.co_name, offset)) + if code.co_name == "method": + executed.append(("start", code.co_name, offset)) monitor.set_local_events(DEBUGGER_ID, code, monitor.events.LINE) return monitor.DISABLE def _on_line(code, offset): - if code.co_name == 'method': - executed.append(('line', code.co_name, offset)) + if code.co_name == "method": + executed.append(("line", code.co_name, offset)) return monitor.DISABLE monitor.set_events(DEBUGGER_ID, monitor.events.PY_START | monitor.events.PY_RESUME) - monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START , _start_method) + monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, _start_method) monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RESUME, _start_method) monitor.register_callback(DEBUGGER_ID, monitor.events.LINE, _on_line) @@ -164,7 +163,7 @@ def method(): method() method() - assert executed == [('start', 'method', 0), ('line', 'method', method.__code__.co_firstlineno + 1)] + assert executed == [("start", "method", 0), ("line", "method", method.__code__.co_firstlineno + 1)] del executed[:] @@ -180,7 +179,7 @@ def method(): t = threading.Thread(target=method) t.start() t.join() - assert executed == [('start', 'method', 0), ('line', 'method', method.__code__.co_firstlineno + 1)] + assert executed == [("start", "method", 0), ("line", "method", method.__code__.co_firstlineno + 1)] def test_change_line_during_trace(with_monitoring): @@ -203,30 +202,28 @@ def _on_line(code, line): monitor.set_events(DEBUGGER_ID, monitor.events.PY_START | monitor.events.PY_RESUME) - monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START , _start_method) + monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, _start_method) monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RESUME, _start_method) monitor.register_callback(DEBUGGER_ID, monitor.events.LINE, _on_line) def method1(): # code.co_firstlineno a = 1 # code.co_firstlineno + 1 - lines_traced.append('before a=2') # code.co_firstlineno + 2 + lines_traced.append("before a=2") # code.co_firstlineno + 2 a = 2 # code.co_firstlineno + 3 - lines_traced.append('before a=3') # code.co_firstlineno + 4 + lines_traced.append("before a=3") # code.co_firstlineno + 4 # a = 3 # code.co_firstlineno + 5 for _i in range(3): method1() assert lines_traced == [ - 'before a=2', - 'before a=3', - - 'before a=2', - 'before a=2', - - 'before a=3', - 'before a=2', - 'before a=3', + "before a=2", + "before a=3", + "before a=2", + "before a=2", + "before a=3", + "before a=2", + "before a=3", ] @@ -245,7 +242,7 @@ def b(): # line 4 print(j) # line 9 def tracefunc(frame, event, arg): - if 'test_sys_monitoring.py' in frame.f_code.co_filename: + if "test_sys_monitoring.py" in frame.f_code.co_filename: print(frame.f_code.co_name, event, frame.f_lineno - frame.f_code.co_firstlineno) return tracefunc @@ -255,29 +252,28 @@ def tracefunc(frame, event, arg): def test_lines_with_yield(with_monitoring): - def _start_method(code, offset): - if 'test_sys_monitoring.py' in code.co_filename: - print('start ', code.co_name) + if "test_sys_monitoring.py" in code.co_filename: + print("start ", code.co_name) monitor.set_local_events(DEBUGGER_ID, code, monitor.events.LINE | monitor.events.JUMP | monitor.events.PY_YIELD) def _on_line(code, line): - if 'test_sys_monitoring.py' in code.co_filename: - print('on line', code.co_name, line - code.co_firstlineno) + if "test_sys_monitoring.py" in code.co_filename: + print("on line", code.co_name, line - code.co_firstlineno) def _on_jump(code, from_offset, to_offset): - if 'test_sys_monitoring.py' in code.co_filename: + if "test_sys_monitoring.py" in code.co_filename: frame = sys._getframe().f_back - print('on jump', code.co_name, frame.f_lineno - code.co_firstlineno) + print("on jump", code.co_name, frame.f_lineno - code.co_firstlineno) def _yield_method(code, offset, retval): - if 'test_sys_monitoring.py' in code.co_filename: + if "test_sys_monitoring.py" in code.co_filename: frame = sys._getframe().f_back - print('on yield', code.co_name, frame.f_lineno - code.co_firstlineno) + print("on yield", code.co_name, frame.f_lineno - code.co_firstlineno) monitor.set_events(DEBUGGER_ID, monitor.events.PY_START | monitor.events.PY_RESUME) - monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START , _start_method) + monitor.register_callback(DEBUGGER_ID, monitor.events.PY_START, _start_method) monitor.register_callback(DEBUGGER_ID, monitor.events.PY_RESUME, _start_method) monitor.register_callback(DEBUGGER_ID, monitor.events.PY_YIELD, _yield_method) monitor.register_callback(DEBUGGER_ID, monitor.events.LINE, _on_line) diff --git a/tests_python/test_timeout_tracker.py b/tests_python/test_timeout_tracker.py index 388f11979..ad8b0d136 100644 --- a/tests_python/test_timeout_tracker.py +++ b/tests_python/test_timeout_tracker.py @@ -16,9 +16,7 @@ def _enable_debug_msgs(): def test_timeout(): - class _DummyPyDb(object): - def __init__(self): self.created_pydb_daemon_threads = {} @@ -35,16 +33,14 @@ def on_timeout(arg): timeout = 2 else: timeout = 20 - with timeout_tracker.call_on_timeout(1, on_timeout, kwargs={'arg': 1}): + with timeout_tracker.call_on_timeout(1, on_timeout, kwargs={"arg": 1}): time.sleep(timeout) except KeyboardInterrupt: pass def test_timeout_0_time(): - class _DummyPyDb(object): - def __init__(self): self.created_pydb_daemon_threads = {} @@ -57,17 +53,15 @@ def on_timeout(arg): py_db = _DummyPyDb() timeout_tracker = pydevd_timeout.TimeoutTracker(py_db) try: - with timeout_tracker.call_on_timeout(0, on_timeout, kwargs={'arg': 1}): + with timeout_tracker.call_on_timeout(0, on_timeout, kwargs={"arg": 1}): time.sleep(1) except KeyboardInterrupt: pass -@pytest.mark.skipif(not IS_CPYTHON, reason='This only works in CPython.') +@pytest.mark.skipif(not IS_CPYTHON, reason="This only works in CPython.") def test_create_interrupt_this_thread_callback(): - class MyThread(threading.Thread): - def __init__(self): threading.Thread.__init__(self) self.finished = False @@ -79,7 +73,7 @@ def run(self): try: self.interrupt_thread = create_interrupt_this_thread_callback() while True: - time.sleep(.2) + time.sleep(0.2) except KeyboardInterrupt: self.interrupted = True finally: @@ -96,19 +90,17 @@ def run(self): assert t.interrupted -@pytest.mark.skipif(True, reason='Skipping because running this test can interrupt the test suite execution.') +@pytest.mark.skipif(True, reason="Skipping because running this test can interrupt the test suite execution.") def test_interrupt_main_thread(): - from _pydevd_bundle.pydevd_constants import IS_PY39_OR_GREATER class MyThread(threading.Thread): - def __init__(self, interrupt_thread_callback): threading.Thread.__init__(self) self.interrupt_thread_callback = interrupt_thread_callback def run(self): - time.sleep(.5) + time.sleep(0.5) self.interrupt_thread_callback() initial_time = time.time() @@ -125,4 +117,4 @@ def run(self): if not interrupt_only_on_callback: assert time.time() - initial_time < timeout else: - raise AssertionError('Expected main thread to be interrupted.') + raise AssertionError("Expected main thread to be interrupted.") diff --git a/tests_python/test_tracing_gotchas.py b/tests_python/test_tracing_gotchas.py index 66204021d..bafe99ba8 100644 --- a/tests_python/test_tracing_gotchas.py +++ b/tests_python/test_tracing_gotchas.py @@ -5,17 +5,16 @@ class Tracer(object): - def __init__(self): self.call_calls = 0 self.line_calls = 0 def trace_func(self, frame, event, arg): - if event == 'call': + if event == "call": self.call_calls += 1 return self.on_call() - elif event == 'line': + elif event == "line": self.line_calls += 1 # Should disable tracing when None is returned (but doesn't). return self.on_line(frame, event, arg) @@ -31,14 +30,12 @@ def on_line(self, frame, event, arg): class TracerSettingNone(Tracer): - def on_line(self, frame, event, arg): frame.f_trace = NO_FTRACE return NO_FTRACE class TracerChangeToOtherTracing(Tracer): - def on_line(self, frame, event, arg): return self._no_trace @@ -47,13 +44,12 @@ def _no_trace(self, frame, event, arg): class TracerDisableOnCall(Tracer): - def on_call(self): return None def test_tracing_gotchas(): - ''' + """ Summary of the gotchas tested: If 'call' is used, a None return value is used for the tracing. Afterwards the return may or may @@ -68,7 +64,7 @@ def test_tracing_gotchas(): does not follow the spec (but we have to work with it nonetheless). Note: Jython seems to do what's written in the docs. - ''' + """ def method(): _a = 1 @@ -81,7 +77,7 @@ def method(): (TracerSettingNone(), 1), (TracerChangeToOtherTracing(), 1), (TracerDisableOnCall(), 0), - ): + ): curr_trace_func = sys.gettrace() try: sys.settrace(tracer.trace_func) @@ -89,13 +85,13 @@ def method(): method() if tracer.call_calls != 1: - pytest.fail('Expected a single call event. Found: %s' % (tracer.call_calls)) + pytest.fail("Expected a single call event. Found: %s" % (tracer.call_calls)) if tracer.line_calls != line_events: - pytest.fail('Expected %s line events. Found: %s. Tracer: %s' % (line_events, tracer.line_calls, tracer)) + pytest.fail("Expected %s line events. Found: %s. Tracer: %s" % (line_events, tracer.line_calls, tracer)) finally: sys.settrace(curr_trace_func) -if __name__ == '__main__': - pytest.main(['-k', 'test_tracing_gotchas']) +if __name__ == "__main__": + pytest.main(["-k", "test_tracing_gotchas"]) diff --git a/tests_python/test_tracing_on_top_level.py b/tests_python/test_tracing_on_top_level.py index 891b466c4..59530336c 100644 --- a/tests_python/test_tracing_on_top_level.py +++ b/tests_python/test_tracing_on_top_level.py @@ -6,12 +6,11 @@ DEBUG = False -pytestmark = pytest.mark.skipif(PYDEVD_USE_SYS_MONITORING, reason='The tests in this module requires tracing.') +pytestmark = pytest.mark.skipif(PYDEVD_USE_SYS_MONITORING, reason="The tests in this module requires tracing.") class DummyTopLevelFrame(object): - - __slots__ = ['f_code', 'f_back', 'f_lineno', 'f_trace'] + __slots__ = ["f_code", "f_back", "f_lineno", "f_trace"] def __init__(self, method): self.f_code = method.__code__ @@ -20,8 +19,7 @@ def __init__(self, method): class DummyWriter(object): - - __slots__ = ['commands', 'command_meanings'] + __slots__ = ["commands", "command_meanings"] def __init__(self): self.commands = [] @@ -29,23 +27,23 @@ def __init__(self): def add_command(self, cmd): from _pydevd_bundle.pydevd_comm import ID_TO_MEANING + meaning = ID_TO_MEANING[str(cmd.id)] if DEBUG: print(meaning) self.command_meanings.append(meaning) if DEBUG: - print(cmd._as_bytes.decode('utf-8')) + print(cmd._as_bytes.decode("utf-8")) self.commands.append(cmd) class DummyPyDb(PyDB): - def __init__(self): PyDB.__init__(self, set_as_global=False) - def do_wait_suspend( - self, thread, frame, event, arg, *args, **kwargs): + def do_wait_suspend(self, thread, frame, event, arg, *args, **kwargs): from _pydevd_bundle.pydevd_constants import STATE_RUN + info = thread.additional_info info.pydev_original_step_cmd = -1 info.pydev_step_cmd = -1 @@ -56,7 +54,6 @@ def do_wait_suspend( class _TraceTopLevel(object): - def __init__(self): self.py_db = DummyPyDb() self.py_db.writer = DummyWriter() @@ -67,6 +64,7 @@ def set_target_func(self, target_func): def get_exception_arg(self): import sys + try: raise AssertionError() except: @@ -74,23 +72,24 @@ def get_exception_arg(self): return arg def create_add_exception_breakpoint_with_policy( - self, exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries): - return '\t'.join(str(x) for x in [ - exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries]) + self, exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries + ): + return "\t".join(str(x) for x in [exception, notify_on_handled_exceptions, notify_on_unhandled_exceptions, ignore_libraries]) def add_unhandled_exception_breakpoint(self): from _pydevd_bundle.pydevd_process_net_command import process_net_command from tests_python.debugger_unittest import CMD_ADD_EXCEPTION_BREAK - for exc_name in ('AssertionError', 'RuntimeError'): + + for exc_name in ("AssertionError", "RuntimeError"): process_net_command( self.py_db, CMD_ADD_EXCEPTION_BREAK, 1, - self.create_add_exception_breakpoint_with_policy(exc_name, '0', '1', '0'), + self.create_add_exception_breakpoint_with_policy(exc_name, "0", "1", "0"), ) def assert_last_commands(self, *commands): - assert self.py_db.writer.command_meanings[-len(commands):] == list(commands) + assert self.py_db.writer.command_meanings[-len(commands) :] == list(commands) def assert_no_commands(self, *commands): for command in commands: @@ -104,21 +103,21 @@ def trace_dispatch(self, event, arg): def call_trace_dispatch(self, line): self.frame.f_lineno = line - return self.trace_dispatch('call', None) + return self.trace_dispatch("call", None) def exception_trace_dispatch(self, line, arg): self.frame.f_lineno = line - self.new_trace_func = self.new_trace_func(self.frame, 'exception', arg) + self.new_trace_func = self.new_trace_func(self.frame, "exception", arg) def return_trace_dispatch(self, line): self.frame.f_lineno = line - self.new_trace_func = self.new_trace_func(self.frame, 'return', None) + self.new_trace_func = self.new_trace_func(self.frame, "return", None) def assert_paused(self): - self.assert_last_commands('CMD_THREAD_SUSPEND', 'CMD_THREAD_RUN') + self.assert_last_commands("CMD_THREAD_SUSPEND", "CMD_THREAD_RUN") def assert_not_paused(self): - self.assert_no_commands('CMD_THREAD_SUSPEND', 'CMD_THREAD_RUN') + self.assert_no_commands("CMD_THREAD_SUSPEND", "CMD_THREAD_RUN") @pytest.fixture @@ -151,7 +150,7 @@ def mark_unhandled(func): return func -#------------------------------------------------------------------------------------------- Handled +# ------------------------------------------------------------------------------------------- Handled @mark_handled def raise_handled_exception(): try: @@ -197,9 +196,7 @@ def raise_handled_exception4(): raise AssertionError() except RuntimeError: pass - except ( - RuntimeError, - AssertionError): + except (RuntimeError, AssertionError): pass @@ -210,9 +207,7 @@ def raise_handled(): raise AssertionError() except RuntimeError: pass - except ( - RuntimeError, - AssertionError): + except (RuntimeError, AssertionError): pass @@ -220,16 +215,12 @@ def raise_handled(): def raise_handled2(): try: raise AssertionError() - except ( - RuntimeError, - AssertionError): + except (RuntimeError, AssertionError): pass try: raise RuntimeError() - except ( - RuntimeError, - AssertionError): + except (RuntimeError, AssertionError): pass @@ -260,7 +251,8 @@ def raise_handled10(): _foo = 10 -#----------------------------------------------------------------------------------------- Unhandled + +# ----------------------------------------------------------------------------------------- Unhandled @mark_unhandled @@ -283,9 +275,7 @@ def raise_unhandled(): raise AssertionError() except RuntimeError: pass - except ( - RuntimeError, - AssertionError): + except (RuntimeError, AssertionError): raise @@ -328,10 +318,7 @@ def raise_unhandled6(): try: raise AssertionError() finally: - raise RuntimeError( - 'in another' - 'line' - ) + raise RuntimeError("in another" "line") @mark_unhandled @@ -430,11 +417,14 @@ def events_collector(frame, event, arg): return events_collector import sys + sys.settrace(events_collector) try: func() except: - import traceback;traceback.print_exc() + import traceback + + traceback.print_exc() finally: sys.settrace(None) return collected @@ -442,38 +432,38 @@ def events_collector(frame, event, arg): def _replay_events(collected, trace_top_level_unhandled): for event, lineno, arg in collected: - if event == 'call': + if event == "call": # Notify only unhandled new_trace_func = trace_top_level_unhandled.call_trace_dispatch(lineno) # Check that it's dealing with the top-level event. - if hasattr(new_trace_func, 'get_method_object'): + if hasattr(new_trace_func, "get_method_object"): new_trace_func = new_trace_func.get_method_object() - assert new_trace_func.__name__ == 'trace_dispatch_and_unhandled_exceptions' - elif event == 'exception': + assert new_trace_func.__name__ == "trace_dispatch_and_unhandled_exceptions" + elif event == "exception": trace_top_level_unhandled.exception_trace_dispatch(lineno, arg) - elif event == 'return': + elif event == "return": trace_top_level_unhandled.return_trace_dispatch(lineno) - elif event == 'line': + elif event == "line": pass else: - raise AssertionError('Unexpected: %s' % (event,)) + raise AssertionError("Unexpected: %s" % (event,)) def _collect_target_functions(): -# return [raise_unhandled10] + # return [raise_unhandled10] ret = [] for _key, method in sorted(dict(globals()).items()): - if hasattr(method, '__handled__'): + if hasattr(method, "__handled__"): ret.append(method) assert len(ret) == _expected_functions_to_test return ret -@pytest.mark.skipif(not IS_CPYTHON, reason='try..except info only available on CPython') +@pytest.mark.skipif(not IS_CPYTHON, reason="try..except info only available on CPython") @pytest.mark.parametrize("func", _collect_target_functions()) def test_tracing_on_top_level_unhandled(trace_top_level_unhandled, func): trace_top_level_unhandled.set_target_func(func) diff --git a/tests_python/test_utilities.py b/tests_python/test_utilities.py index 88499bd8f..ac44a971a 100644 --- a/tests_python/test_utilities.py +++ b/tests_python/test_utilities.py @@ -3,8 +3,7 @@ from _pydevd_bundle.pydevd_utils import convert_dap_log_message_to_expression from tests_python.debug_constants import TEST_GEVENT, IS_CPYTHON import sys -from _pydevd_bundle.pydevd_constants import IS_WINDOWS, IS_PYPY, IS_JYTHON, \ - PYDEVD_USE_SYS_MONITORING +from _pydevd_bundle.pydevd_constants import IS_WINDOWS, IS_PYPY, IS_JYTHON, PYDEVD_USE_SYS_MONITORING import pytest import os from _pydevd_bundle.pydevd_thread_lifecycle import pydevd_find_thread_by_id @@ -13,88 +12,91 @@ def test_expression_to_evaluate(): from _pydevd_bundle.pydevd_vars import _expression_to_evaluate - assert _expression_to_evaluate(b'expr') == b'expr' - assert _expression_to_evaluate(b' expr') == b'expr' - assert _expression_to_evaluate(b'for a in b:\n foo') == b'for a in b:\n foo' - assert _expression_to_evaluate(b' for a in b:\n foo') == b'for a in b:\nfoo' - assert _expression_to_evaluate(b' for a in b:\nfoo') == b' for a in b:\nfoo' - assert _expression_to_evaluate(b'\tfor a in b:\n\t\tfoo') == b'for a in b:\n\tfoo' - assert _expression_to_evaluate(u' expr') == u'expr' - assert _expression_to_evaluate(u' for a in expr:\n pass') == u'for a in expr:\npass' + assert _expression_to_evaluate(b"expr") == b"expr" + assert _expression_to_evaluate(b" expr") == b"expr" + assert _expression_to_evaluate(b"for a in b:\n foo") == b"for a in b:\n foo" + assert _expression_to_evaluate(b" for a in b:\n foo") == b"for a in b:\nfoo" + assert _expression_to_evaluate(b" for a in b:\nfoo") == b" for a in b:\nfoo" + assert _expression_to_evaluate(b"\tfor a in b:\n\t\tfoo") == b"for a in b:\n\tfoo" + assert _expression_to_evaluate(" expr") == "expr" + assert _expression_to_evaluate(" for a in expr:\n pass") == "for a in expr:\npass" -@pytest.mark.skipif(IS_WINDOWS, reason='Brittle on Windows.') -def test_is_main_thread(): - ''' - This is now skipped due to it failing sometimes (only on Windows). - - I (fabioz) am not 100% sure on why this happens, but when this happens the initial thread for - the tests seems to be a non main thread. - - i.e.: With an autouse fixture with a scope='session' with the code and error message below, it's - possible to see that at even at the `conftest` import (where indent_at_import is assigned) the - current thread is already not the main thread. - As far as I know this seems to be an issue in how pytest-xdist is running the tests (i.e.: - I couldn't reproduce this without running with `python -m pytest -n 0 ...`). - - -------- Code to check error / error output ---------- - - from _pydevd_bundle.pydevd_utils import is_current_thread_main_thread - import threading - indent_at_import = threading.get_ident() - - @pytest.yield_fixture(autouse=True, scope='session') - def check_main_thread_session(request): - if not is_current_thread_main_thread(): - error_msg = 'Current thread does not seem to be a main thread at the start of the session. Details:\n' - current_thread = threading.current_thread() - error_msg += 'Current thread: %s\n' % (current_thread,) - error_msg += 'Current thread ident: %s\n' % (current_thread.ident,) - error_msg += 'ident at import: %s\n' % (indent_at_import,) - error_msg += 'curr ident: %s\n' % (threading.get_ident(),) - - if hasattr(threading, 'main_thread'): - error_msg += 'Main thread found: %s\n' % (threading.main_thread(),) - error_msg += 'Main thread id: %s\n' % (threading.main_thread().ident,) - else: - error_msg += 'Current main thread not instance of: %s (%s)\n' % ( - threading._MainThread, current_thread.__class__.__mro__,) - -> raise AssertionError(error_msg) -E AssertionError: Current thread does not seem to be a main thread at the start of the session. Details: -E Current thread: <_DummyThread(Dummy-2, started daemon 7072)> -E Current thread ident: 7072 -E ident at import: 7072 -E curr ident: 7072 -E Main thread found: <_MainThread(MainThread, started 5924)> -E Main thread id: 5924 - -conftest.py:67: AssertionError - ''' +@pytest.mark.skipif(IS_WINDOWS, reason="Brittle on Windows.") +def test_is_main_thread(): + """ + This is now skipped due to it failing sometimes (only on Windows). + + I (fabioz) am not 100% sure on why this happens, but when this happens the initial thread for + the tests seems to be a non main thread. + + i.e.: With an autouse fixture with a scope='session' with the code and error message below, it's + possible to see that at even at the `conftest` import (where indent_at_import is assigned) the + current thread is already not the main thread. + + As far as I know this seems to be an issue in how pytest-xdist is running the tests (i.e.: + I couldn't reproduce this without running with `python -m pytest -n 0 ...`). + + -------- Code to check error / error output ---------- + + from _pydevd_bundle.pydevd_utils import is_current_thread_main_thread + import threading + indent_at_import = threading.get_ident() + + @pytest.yield_fixture(autouse=True, scope='session') + def check_main_thread_session(request): + if not is_current_thread_main_thread(): + error_msg = 'Current thread does not seem to be a main thread at the start of the session. Details:\n' + current_thread = threading.current_thread() + error_msg += 'Current thread: %s\n' % (current_thread,) + error_msg += 'Current thread ident: %s\n' % (current_thread.ident,) + error_msg += 'ident at import: %s\n' % (indent_at_import,) + error_msg += 'curr ident: %s\n' % (threading.get_ident(),) + + if hasattr(threading, 'main_thread'): + error_msg += 'Main thread found: %s\n' % (threading.main_thread(),) + error_msg += 'Main thread id: %s\n' % (threading.main_thread().ident,) + else: + error_msg += 'Current main thread not instance of: %s (%s)\n' % ( + threading._MainThread, current_thread.__class__.__mro__,) + + > raise AssertionError(error_msg) + E AssertionError: Current thread does not seem to be a main thread at the start of the session. Details: + E Current thread: <_DummyThread(Dummy-2, started daemon 7072)> + E Current thread ident: 7072 + E ident at import: 7072 + E curr ident: 7072 + E Main thread found: <_MainThread(MainThread, started 5924)> + E Main thread id: 5924 + + conftest.py:67: AssertionError + """ from _pydevd_bundle.pydevd_utils import is_current_thread_main_thread from _pydevd_bundle.pydevd_utils import dump_threads + if not is_current_thread_main_thread(): - error_msg = 'Current thread does not seem to be a main thread. Details:\n' + error_msg = "Current thread does not seem to be a main thread. Details:\n" current_thread = threading.current_thread() - error_msg += 'Current thread: %s\n' % (current_thread,) + error_msg += "Current thread: %s\n" % (current_thread,) - if hasattr(threading, 'main_thread'): - error_msg += 'Main thread found: %s\n' % (threading.main_thread(),) + if hasattr(threading, "main_thread"): + error_msg += "Main thread found: %s\n" % (threading.main_thread(),) else: - error_msg += 'Current main thread not instance of: %s (%s)' % ( - threading._MainThread, current_thread.__class__.__mro__,) + error_msg += "Current main thread not instance of: %s (%s)" % ( + threading._MainThread, + current_thread.__class__.__mro__, + ) from io import StringIO stream = StringIO() dump_threads(stream=stream) - error_msg += '\n\n' + stream.getvalue() + error_msg += "\n\n" + stream.getvalue() raise AssertionError(error_msg) class NonMainThread(threading.Thread): - def run(self): self.is_main_thread = is_current_thread_main_thread() @@ -106,10 +108,10 @@ def run(self): def test_find_thread(): from _pydevd_bundle.pydevd_constants import get_current_thread_id - assert pydevd_find_thread_by_id('123') is None - assert pydevd_find_thread_by_id( - get_current_thread_id(threading.current_thread())) is threading.current_thread() + assert pydevd_find_thread_by_id("123") is None + + assert pydevd_find_thread_by_id(get_current_thread_id(threading.current_thread())) is threading.current_thread() def check_dap_log_message(log_message, expected, evaluated, eval_locals=None): @@ -121,54 +123,25 @@ def check_dap_log_message(log_message, expected, evaluated, eval_locals=None): def test_convert_dap_log_message_to_expression(): assert check_dap_log_message( - 'a', + "a", "'a'", - 'a', + "a", ) + assert check_dap_log_message("a {a}", "'a %s' % (a,)", "a value", {"a": "value"}) + assert check_dap_log_message("a {1}", "'a %s' % (1,)", "a 1") + assert check_dap_log_message("a { }", "'a '", "a ") assert check_dap_log_message( - 'a {a}', - "'a %s' % (a,)", - 'a value', - {'a': 'value'} - ) - assert check_dap_log_message( - 'a {1}', - "'a %s' % (1,)", - 'a 1' - ) - assert check_dap_log_message( - 'a { }', - "'a '", - 'a ' - ) - assert check_dap_log_message( - 'a {1} {2}', + "a {1} {2}", "'a %s %s' % (1, 2,)", - 'a 1 2', - ) - assert check_dap_log_message( - 'a {{22:22}} {2}', - "'a %s %s' % ({22:22}, 2,)", - 'a {22: 22} 2' - ) - assert check_dap_log_message( - 'a {(22,33)}} {2}', - "'a %s} %s' % ((22,33), 2,)", - 'a (22, 33)} 2' + "a 1 2", ) + assert check_dap_log_message("a {{22:22}} {2}", "'a %s %s' % ({22:22}, 2,)", "a {22: 22} 2") + assert check_dap_log_message("a {(22,33)}} {2}", "'a %s} %s' % ((22,33), 2,)", "a (22, 33)} 2") - assert check_dap_log_message( - 'a {{1: {1}}}', - "'a %s' % ({1: {1}},)", - 'a {1: {1}}' - ) + assert check_dap_log_message("a {{1: {1}}}", "'a %s' % ({1: {1}},)", "a {1: {1}}") # Error condition. - assert check_dap_log_message( - 'a {{22:22} {2}', - "'Unbalanced braces in: a {{22:22} {2}'", - 'Unbalanced braces in: a {{22:22} {2}' - ) + assert check_dap_log_message("a {{22:22} {2}", "'Unbalanced braces in: a {{22:22} {2}'", "Unbalanced braces in: a {{22:22} {2}") def test_pydevd_log(): @@ -178,52 +151,52 @@ def test_pydevd_log(): stream = io.StringIO() with log_context(0, stream=stream): - pydev_log.critical('always') - pydev_log.info('never') + pydev_log.critical("always") + pydev_log.info("never") - assert stream.getvalue().endswith('always\n') + assert stream.getvalue().endswith("always\n") stream = io.StringIO() with log_context(1, stream=stream): - pydev_log.critical('always') - pydev_log.info('this too') - assert stream.getvalue().endswith('always\n0.00s - this too\n') + pydev_log.critical("always") + pydev_log.info("this too") + assert stream.getvalue().endswith("always\n0.00s - this too\n") stream = io.StringIO() with log_context(0, stream=stream): - pydev_log.critical('always %s', 1) + pydev_log.critical("always %s", 1) - assert stream.getvalue().endswith('always 1\n') + assert stream.getvalue().endswith("always 1\n") stream = io.StringIO() with log_context(0, stream=stream): - pydev_log.critical('always %s %s', 1, 2) + pydev_log.critical("always %s %s", 1, 2) - assert stream.getvalue().endswith('always 1 2\n') + assert stream.getvalue().endswith("always 1 2\n") stream = io.StringIO() with log_context(0, stream=stream): - pydev_log.critical('always %s %s', 1) + pydev_log.critical("always %s %s", 1) # Even if there's an error in the formatting, don't fail, just print the message and args. - assert stream.getvalue().endswith('always %s %s - (1,)\n') + assert stream.getvalue().endswith("always %s %s - (1,)\n") stream = io.StringIO() with log_context(0, stream=stream): try: raise RuntimeError() except: - pydev_log.exception('foo') + pydev_log.exception("foo") - assert 'foo\n' in stream.getvalue() - assert 'raise RuntimeError()' in stream.getvalue() + assert "foo\n" in stream.getvalue() + assert "raise RuntimeError()" in stream.getvalue() stream = io.StringIO() with log_context(0, stream=stream): - pydev_log.error_once('always %s %s', 1) + pydev_log.error_once("always %s %s", 1) # Even if there's an error in the formatting, don't fail, just print the message and args. - assert stream.getvalue().endswith('always %s %s - (1,)\n') + assert stream.getvalue().endswith("always %s %s - (1,)\n") def test_pydevd_logging_files(tmpdir): @@ -237,20 +210,20 @@ def test_pydevd_logging_files(tmpdir): stream = io.StringIO() with log_context(0, stream=stream): - d1 = str(tmpdir.join('d1')) - d2 = str(tmpdir.join('d2')) + d1 = str(tmpdir.join("d1")) + d2 = str(tmpdir.join("d2")) for d in (d1, d2): - DebugInfoHolder.PYDEVD_DEBUG_FILE = os.path.join(d, 'file.txt') + DebugInfoHolder.PYDEVD_DEBUG_FILE = os.path.join(d, "file.txt") pydev_log.initialize_debug_stream(reinitialize=True) - assert os.path.normpath(_LoggingGlobals._debug_stream_filename) == \ - os.path.normpath(os.path.join(d, 'file.%s.txt' % os.getpid())) + assert os.path.normpath(_LoggingGlobals._debug_stream_filename) == os.path.normpath( + os.path.join(d, "file.%s.txt" % os.getpid()) + ) assert os.path.exists(_LoggingGlobals._debug_stream_filename) - assert pydev_log.list_log_files(DebugInfoHolder.PYDEVD_DEBUG_FILE) == [ - _LoggingGlobals._debug_stream_filename] + assert pydev_log.list_log_files(DebugInfoHolder.PYDEVD_DEBUG_FILE) == [_LoggingGlobals._debug_stream_filename] def _check_tracing_other_threads(): @@ -264,9 +237,11 @@ def _check_tracing_other_threads(): def dump_threads_and_kill_on_timeout(): time.sleep(10) from _pydevd_bundle import pydevd_utils + pydevd_utils.dump_threads() time.sleep(1) import os + os._exit(77) _thread.start_new_thread(dump_threads_and_kill_on_timeout, ()) @@ -277,7 +252,7 @@ def method(): if trace_func: threading.current_thread().trace_func = trace_func break - time.sleep(.01) + time.sleep(0.01) def dummy_thread_method(): threads.append(threading.current_thread()) @@ -289,7 +264,7 @@ def dummy_thread_method(): threads[-1].start() _thread.start_new_thread(dummy_thread_method, ()) - wait_for_condition(lambda: len(threads) == 2, msg=lambda:'Found threads: %s' % (threads,)) + wait_for_condition(lambda: len(threads) == 2, msg=lambda: "Found threads: %s" % (threads,)) def tracing_func(frame, event, args): return tracing_func @@ -298,7 +273,7 @@ def tracing_func(frame, event, args): def check_threads_tracing_func(): for t in threads: - if getattr(t, 'trace_func', None) != tracing_func: + if getattr(t, "trace_func", None) != tracing_func: return False return True @@ -315,45 +290,52 @@ def _build_launch_env(): cwd = os.path.abspath(os.path.dirname(__file__)) assert os.path.isdir(cwd) - resources_dir = os.path.join(os.path.dirname(pydevd.__file__), 'tests_python', 'resources') + resources_dir = os.path.join(os.path.dirname(pydevd.__file__), "tests_python", "resources") assert os.path.isdir(resources_dir) - attach_to_process_dir = os.path.join(os.path.dirname(pydevd.__file__), 'pydevd_attach_to_process') + attach_to_process_dir = os.path.join(os.path.dirname(pydevd.__file__), "pydevd_attach_to_process") assert os.path.isdir(attach_to_process_dir) pydevd_dir = os.path.dirname(pydevd.__file__) assert os.path.isdir(pydevd_dir) - environ['PYTHONPATH'] = ( - cwd + os.pathsep + - resources_dir + os.pathsep + - attach_to_process_dir + os.pathsep + - pydevd_dir + os.pathsep + - environ.get('PYTHONPATH', '') + environ["PYTHONPATH"] = ( + cwd + + os.pathsep + + resources_dir + + os.pathsep + + attach_to_process_dir + + os.pathsep + + pydevd_dir + + os.pathsep + + environ.get("PYTHONPATH", "") ) return cwd, environ -def _check_in_separate_process(method_name, module_name='test_utilities', update_env={}): +def _check_in_separate_process(method_name, module_name="test_utilities", update_env={}): import subprocess + cwd, environ = _build_launch_env() environ.update(update_env) subprocess.check_call( - [sys.executable, '-c', 'import %(module_name)s;%(module_name)s.%(method_name)s()' % dict( - method_name=method_name, module_name=module_name)], + [ + sys.executable, + "-c", + "import %(module_name)s;%(module_name)s.%(method_name)s()" % dict(method_name=method_name, module_name=module_name), + ], env=environ, - cwd=cwd + cwd=cwd, ) -@pytest.mark.skipif(not IS_CPYTHON, reason='Functionality to trace other threads requires CPython.') -@pytest.mark.skipif(PYDEVD_USE_SYS_MONITORING, reason='Tracing is not used with sys.monitoring.') +@pytest.mark.skipif(not IS_CPYTHON, reason="Functionality to trace other threads requires CPython.") +@pytest.mark.skipif(PYDEVD_USE_SYS_MONITORING, reason="Tracing is not used with sys.monitoring.") def test_tracing_other_threads(): - # Note: run this test in a separate process so that it doesn't mess with any current tracing # in our current process. - _check_in_separate_process('_check_tracing_other_threads') + _check_in_separate_process("_check_tracing_other_threads") def _check_basic_tracing(): @@ -376,43 +358,37 @@ def foo(): assert called[0] > 2 -@pytest.mark.skipif(not IS_CPYTHON, reason='Functionality to trace other threads requires CPython.') -@pytest.mark.skipif(PYDEVD_USE_SYS_MONITORING, reason='Tracing is not used with sys.monitoring.') +@pytest.mark.skipif(not IS_CPYTHON, reason="Functionality to trace other threads requires CPython.") +@pytest.mark.skipif(PYDEVD_USE_SYS_MONITORING, reason="Tracing is not used with sys.monitoring.") def test_tracing_basic(): - _check_in_separate_process('_check_basic_tracing') + _check_in_separate_process("_check_basic_tracing") -@pytest.mark.skipif(not IS_CPYTHON, reason='Functionality to trace other threads requires CPython.') +@pytest.mark.skipif(not IS_CPYTHON, reason="Functionality to trace other threads requires CPython.") def test_find_main_thread_id(): # Note: run the checks below in a separate process because they rely heavily on what's available # in the env (such as threads or having threading imported). - _check_in_separate_process('check_main_thread_id_simple', '_pydevd_test_find_main_thread_id') - _check_in_separate_process('check_main_thread_id_multiple_threads', '_pydevd_test_find_main_thread_id') - _check_in_separate_process('check_win_threads', '_pydevd_test_find_main_thread_id') - _check_in_separate_process('check_fix_main_thread_id_multiple_threads', '_pydevd_test_find_main_thread_id') + _check_in_separate_process("check_main_thread_id_simple", "_pydevd_test_find_main_thread_id") + _check_in_separate_process("check_main_thread_id_multiple_threads", "_pydevd_test_find_main_thread_id") + _check_in_separate_process("check_win_threads", "_pydevd_test_find_main_thread_id") + _check_in_separate_process("check_fix_main_thread_id_multiple_threads", "_pydevd_test_find_main_thread_id") import subprocess import pydevd + cwd, environ = _build_launch_env() - subprocess.check_call( - [sys.executable, '-m', '_pydevd_test_find_main_thread_id'], - env=environ, - cwd=cwd - ) + subprocess.check_call([sys.executable, "-m", "_pydevd_test_find_main_thread_id"], env=environ, cwd=cwd) - resources_dir = os.path.join(os.path.dirname(pydevd.__file__), 'tests_python', 'resources') + resources_dir = os.path.join(os.path.dirname(pydevd.__file__), "tests_python", "resources") - subprocess.check_call( - [sys.executable, os.path.join(resources_dir, '_pydevd_test_find_main_thread_id.py') ], - env=environ, - cwd=cwd - ) + subprocess.check_call([sys.executable, os.path.join(resources_dir, "_pydevd_test_find_main_thread_id.py")], env=environ, cwd=cwd) -@pytest.mark.skipif(not IS_WINDOWS or IS_JYTHON, reason='Windows-only test.') +@pytest.mark.skipif(not IS_WINDOWS or IS_JYTHON, reason="Windows-only test.") def test_get_ppid(): from _pydevd_bundle.pydevd_api import PyDevdAPI + api = PyDevdAPI() # On python 3 we can check that our internal api which is used for Python 2 gives the # same result as os.getppid. @@ -422,10 +398,13 @@ def test_get_ppid(): def _check_gevent(expect_msg): from _pydevd_bundle.pydevd_utils import notify_about_gevent_if_needed + assert not notify_about_gevent_if_needed() import gevent + assert not notify_about_gevent_if_needed() import gevent.monkey + assert not notify_about_gevent_if_needed() gevent.monkey.patch_all() assert notify_about_gevent_if_needed() == expect_msg @@ -439,13 +418,13 @@ def check_dont_notify_on_gevent_loaded(): _check_gevent(False) -@pytest.mark.skipif(not TEST_GEVENT, reason='Gevent not installed.') +@pytest.mark.skipif(not TEST_GEVENT, reason="Gevent not installed.") def test_gevent_notify(): - _check_in_separate_process('check_notify_on_gevent_loaded', update_env={'GEVENT_SUPPORT': ''}) - _check_in_separate_process('check_dont_notify_on_gevent_loaded', update_env={'GEVENT_SUPPORT': 'True'}) + _check_in_separate_process("check_notify_on_gevent_loaded", update_env={"GEVENT_SUPPORT": ""}) + _check_in_separate_process("check_dont_notify_on_gevent_loaded", update_env={"GEVENT_SUPPORT": "True"}) -@pytest.mark.skipif(True, reason='Skipping because running this test can interrupt the test suite execution.') +@pytest.mark.skipif(True, reason="Skipping because running this test can interrupt the test suite execution.") def test_interrupt_main_thread(): from _pydevd_bundle.pydevd_utils import interrupt_main_thread import time @@ -477,20 +456,19 @@ def interrupt(): actual_timeout = time.time() - initial_time # If this fails it means that although we interrupted Python actually waited for the next # instruction to send the event and didn't really interrupt the thread. - assert actual_timeout < timeout, 'Expected the actual timeout (%s) to be < than the timeout (%s)' % ( - actual_timeout, timeout) + assert actual_timeout < timeout, "Expected the actual timeout (%s) to be < than the timeout (%s)" % (actual_timeout, timeout) else: - raise AssertionError('KeyboardInterrupt not generated in main thread.') + raise AssertionError("KeyboardInterrupt not generated in main thread.") -@pytest.mark.skipif(sys.version_info[0] < 3, reason='Only available for Python 3.') +@pytest.mark.skipif(sys.version_info[0] < 3, reason="Only available for Python 3.") def test_get_smart_step_into_variant_from_frame_offset(): from _pydevd_bundle.pydevd_bytecode_utils import get_smart_step_into_variant_from_frame_offset + variants = [] assert get_smart_step_into_variant_from_frame_offset(0, variants) is None class DummyVariant(object): - def __init__(self, offset): self.offset = offset @@ -508,11 +486,10 @@ def __init__(self, offset): def test_threading_hide_pydevd(): - class T(threading.Thread): - def __init__(self, is_pydev_daemon_thread): from _pydevd_bundle.pydevd_daemon_thread import mark_as_pydevd_daemon_thread + threading.Thread.__init__(self) if is_pydev_daemon_thread: mark_as_pydevd_daemon_thread(self) @@ -546,11 +523,10 @@ def test_import_token_from_module(): from _pydevd_bundle.pydevd_utils import import_attr_from_module with pytest.raises(ImportError): - import_attr_from_module('sys') + import_attr_from_module("sys") with pytest.raises(ImportError): - import_attr_from_module('sys.settrace.foo') - - assert import_attr_from_module('sys.settrace') == sys.settrace - assert import_attr_from_module('threading.Thread.start') == threading.Thread.start + import_attr_from_module("sys.settrace.foo") + assert import_attr_from_module("sys.settrace") == sys.settrace + assert import_attr_from_module("threading.Thread.start") == threading.Thread.start diff --git a/tests_runfiles/samples/nested_dir/nested2/deep_nest_test.py b/tests_runfiles/samples/nested_dir/nested2/deep_nest_test.py index 7b1972b89..d662e4a99 100644 --- a/tests_runfiles/samples/nested_dir/nested2/deep_nest_test.py +++ b/tests_runfiles/samples/nested_dir/nested2/deep_nest_test.py @@ -1,7 +1,7 @@ import unittest + class SampleTest(unittest.TestCase): - def setUp(self): return @@ -18,5 +18,5 @@ def test_i_am_a_unique_test_name(self): pass -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests_runfiles/samples/nested_dir/nested2/non_test_file.py b/tests_runfiles/samples/nested_dir/nested2/non_test_file.py index 470c65046..052cac64d 100644 --- a/tests_runfiles/samples/nested_dir/nested2/non_test_file.py +++ b/tests_runfiles/samples/nested_dir/nested2/non_test_file.py @@ -1,3 +1,2 @@ - """ i am a python file with no tests """ pass diff --git a/tests_runfiles/samples/nested_dir/nested3/non_test_file.py b/tests_runfiles/samples/nested_dir/nested3/non_test_file.py index 470c65046..052cac64d 100644 --- a/tests_runfiles/samples/nested_dir/nested3/non_test_file.py +++ b/tests_runfiles/samples/nested_dir/nested3/non_test_file.py @@ -1,3 +1,2 @@ - """ i am a python file with no tests """ pass diff --git a/tests_runfiles/samples/nested_dir/non_test_file.py b/tests_runfiles/samples/nested_dir/non_test_file.py index 470c65046..052cac64d 100644 --- a/tests_runfiles/samples/nested_dir/non_test_file.py +++ b/tests_runfiles/samples/nested_dir/non_test_file.py @@ -1,3 +1,2 @@ - """ i am a python file with no tests """ pass diff --git a/tests_runfiles/samples/nested_dir/simple4_test.py b/tests_runfiles/samples/nested_dir/simple4_test.py index ba5d45f1a..69f1a35a1 100644 --- a/tests_runfiles/samples/nested_dir/simple4_test.py +++ b/tests_runfiles/samples/nested_dir/simple4_test.py @@ -1,7 +1,7 @@ import unittest + class NestedSampleTest(unittest.TestCase): - def setUp(self): return @@ -12,5 +12,5 @@ def test_non_unique_name(self): pass -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests_runfiles/samples/non_test_file.py b/tests_runfiles/samples/non_test_file.py index 470c65046..052cac64d 100644 --- a/tests_runfiles/samples/non_test_file.py +++ b/tests_runfiles/samples/non_test_file.py @@ -1,3 +1,2 @@ - """ i am a python file with no tests """ pass diff --git a/tests_runfiles/samples/simple2_test.py b/tests_runfiles/samples/simple2_test.py index d46468ede..52acfcc02 100644 --- a/tests_runfiles/samples/simple2_test.py +++ b/tests_runfiles/samples/simple2_test.py @@ -1,7 +1,7 @@ import unittest + class YetAnotherSampleTest(unittest.TestCase): - def setUp(self): return @@ -12,5 +12,5 @@ def test_abc(self): pass -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests_runfiles/samples/simple3_test.py b/tests_runfiles/samples/simple3_test.py index da1ccbfba..cb9249d7b 100644 --- a/tests_runfiles/samples/simple3_test.py +++ b/tests_runfiles/samples/simple3_test.py @@ -1,7 +1,7 @@ import unittest + class StillYetAnotherSampleTest(unittest.TestCase): - def setUp(self): return @@ -12,5 +12,5 @@ def test_non_unique_name(self): pass -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests_runfiles/samples/simpleClass_test.py b/tests_runfiles/samples/simpleClass_test.py index 3a9c900e2..4c25d8329 100644 --- a/tests_runfiles/samples/simpleClass_test.py +++ b/tests_runfiles/samples/simpleClass_test.py @@ -1,7 +1,7 @@ import unittest -class SetUpClassTest(unittest.TestCase): +class SetUpClassTest(unittest.TestCase): @classmethod def setUpClass(cls): raise ValueError("This is an INTENTIONAL value error in setUpClass.") @@ -10,5 +10,5 @@ def test_blank(self): pass -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests_runfiles/samples/simpleModule_test.py b/tests_runfiles/samples/simpleModule_test.py index fdde67e4a..94470534b 100644 --- a/tests_runfiles/samples/simpleModule_test.py +++ b/tests_runfiles/samples/simpleModule_test.py @@ -1,10 +1,11 @@ import unittest + def setUpModule(): raise ValueError("This is an INTENTIONAL value error in setUpModule.") + class SetUpModuleTest(unittest.TestCase): - def setUp(cls): pass @@ -12,5 +13,5 @@ def test_blank(self): pass -if __name__ == '__main__': +if __name__ == "__main__": unittest.main() diff --git a/tests_runfiles/samples/simple_test.py b/tests_runfiles/samples/simple_test.py index 619df7c82..177b055d5 100644 --- a/tests_runfiles/samples/simple_test.py +++ b/tests_runfiles/samples/simple_test.py @@ -1,7 +1,7 @@ import unittest + class SampleTest(unittest.TestCase): - def setUp(self): pass @@ -9,15 +9,19 @@ def tearDown(self): pass def test_xxxxxx1(self): - self.fail('Fail test 2') + self.fail("Fail test 2") + def test_xxxxxx2(self): pass + def test_xxxxxx3(self): pass + def test_xxxxxx4(self): pass + def test_non_unique_name(self): - print('non unique name ran') + print("non unique name ran") class AnotherSampleTest(unittest.TestCase): @@ -29,17 +33,19 @@ def tearDown(self): def test_1(self): pass + def test_2(self): - """ im a doc string""" + """im a doc string""" pass + def todo_not_tested(self): - ''' + """ Not there by default! - ''' + """ -if __name__ == '__main__': -# suite = unittest.makeSuite(SampleTest, 'test') -# runner = unittest.TextTestRunner( verbosity=3 ) -# runner.run(suite) +if __name__ == "__main__": + # suite = unittest.makeSuite(SampleTest, 'test') + # runner = unittest.TextTestRunner( verbosity=3 ) + # runner.run(suite) unittest.main() diff --git a/tests_runfiles/test_pydevd_property.py b/tests_runfiles/test_pydevd_property.py index aa1d01084..e89d8e896 100644 --- a/tests_runfiles/test_pydevd_property.py +++ b/tests_runfiles/test_pydevd_property.py @@ -1,41 +1,40 @@ -''' +""" Created on Aug 22, 2011 @author: hussain.bohra @author: fabioz -''' +""" import os import sys import unittest -#======================================================================================================================= + +# ======================================================================================================================= # Test -#======================================================================================================================= +# ======================================================================================================================= class Test(unittest.TestCase): - """Test cases to validate custom property implementation in pydevd - """ + """Test cases to validate custom property implementation in pydevd""" def setUp(self, nused=None): self.tempdir = os.path.join(os.path.dirname(os.path.dirname(__file__))) sys.path.insert(0, self.tempdir) from _pydevd_bundle import pydevd_traceproperty - self.old = pydevd_traceproperty.replace_builtin_property() + self.old = pydevd_traceproperty.replace_builtin_property() def tearDown(self, unused=None): from _pydevd_bundle import pydevd_traceproperty + pydevd_traceproperty.replace_builtin_property(self.old) sys.path.remove(self.tempdir) - def test_property(self): - """Test case to validate custom property - """ + """Test case to validate custom property""" from _pydevd_bundle import pydevd_traceproperty - class TestProperty(object): + class TestProperty(object): def __init__(self): self._get = 0 self._set = 0 @@ -52,19 +51,17 @@ def set_name(self, value): def del_name(self): self._del += 1 del self.__name + name = property(get_name, set_name, del_name, "name's docstring") self.assertEqual(name.__class__, pydevd_traceproperty.DebugProperty) testObj = TestProperty() self._check(testObj) - def test_property2(self): - """Test case to validate custom property - """ + """Test case to validate custom property""" class TestProperty(object): - def __init__(self): self._get = 0 self._set = 0 @@ -73,39 +70,39 @@ def __init__(self): def name(self): self._get += 1 return self.__name + name = property(name) def set_name(self, value): self._set += 1 self.__name = value + name.setter(set_name) def del_name(self): self._del += 1 del self.__name + name.deleter(del_name) testObj = TestProperty() self._check(testObj) - def test_property3(self): - """Test case to validate custom property - """ + """Test case to validate custom property""" class TestProperty(object): - def __init__(self): - self._name = 'foo' + self._name = "foo" def name(self): return self._name + name = property(name) testObj = TestProperty() - self.assertRaises(AttributeError, setattr, testObj, 'name', 'bar') - self.assertRaises(AttributeError, delattr, testObj, 'name') - + self.assertRaises(AttributeError, setattr, testObj, "name", "bar") + self.assertRaises(AttributeError, delattr, testObj, "name") def _check(self, testObj): testObj.name = "Custom" @@ -114,11 +111,10 @@ def _check(self, testObj): self.assertEqual(testObj.name, "Custom") self.assertEqual(1, testObj._get) - self.assertTrue(hasattr(testObj, 'name')) + self.assertTrue(hasattr(testObj, "name")) del testObj.name self.assertEqual(1, testObj._del) - self.assertTrue(not hasattr(testObj, 'name')) + self.assertTrue(not hasattr(testObj, "name")) testObj.name = "Custom2" self.assertEqual(testObj.name, "Custom2") - diff --git a/tests_runfiles/test_pydevdio.py b/tests_runfiles/test_pydevdio.py index 3d0b007d6..2e0aab4b5 100644 --- a/tests_runfiles/test_pydevdio.py +++ b/tests_runfiles/test_pydevdio.py @@ -4,33 +4,34 @@ import unittest -class Test(unittest.TestCase): +class Test(unittest.TestCase): def test_it(self): - #make it as if we were executing from the directory above this one (so that we can use jycompletionserver - #without the need for it being in the pythonpath) - #(twice the dirname to get the previous level from this file.) - import test_pydevdio #@UnresolvedImport - importing itself + # make it as if we were executing from the directory above this one (so that we can use jycompletionserver + # without the need for it being in the pythonpath) + # (twice the dirname to get the previous level from this file.) + import test_pydevdio # @UnresolvedImport - importing itself + ADD_TO_PYTHONPATH = os.path.join(os.path.dirname(os.path.dirname(test_pydevdio.__file__))) sys.path.insert(0, ADD_TO_PYTHONPATH) try: from _pydevd_bundle import pydevd_io + original = sys.stdout try: sys.stdout = pydevd_io.IOBuf() - print('foo') - print('bar') + print("foo") + print("bar") - self.assertEqual('foo\nbar\n', sys.stdout.getvalue()) #@UndefinedVariable + self.assertEqual("foo\nbar\n", sys.stdout.getvalue()) # @UndefinedVariable - print('ww') - print('xx') - self.assertEqual('ww\nxx\n', sys.stdout.getvalue()) #@UndefinedVariable + print("ww") + print("xx") + self.assertEqual("ww\nxx\n", sys.stdout.getvalue()) # @UndefinedVariable finally: sys.stdout = original finally: - #remove it to leave it ok for other tests + # remove it to leave it ok for other tests sys.path.remove(ADD_TO_PYTHONPATH) - diff --git a/tests_runfiles/test_runfiles.py b/tests_runfiles/test_runfiles.py index d20b002b3..91997b9d5 100644 --- a/tests_runfiles/test_runfiles.py +++ b/tests_runfiles/test_runfiles.py @@ -1,13 +1,14 @@ import os.path import sys -IS_JYTHON = sys.platform.find('java') != -1 +IS_JYTHON = sys.platform.find("java") != -1 try: this_file_name = __file__ except NameError: # stupid jython. plain old __file__ isnt working for some reason import test_runfiles # @UnresolvedImport - importing the module itself + this_file_name = test_runfiles.__file__ desired_runfiles_path = os.path.normpath(os.path.dirname(this_file_name) + "/..") @@ -18,10 +19,10 @@ from _pydevd_bundle import pydevd_io # remove existing pydev_runfiles from modules (if any), so that we can be sure we have the correct version -if 'pydev_runfiles' in sys.modules: - del sys.modules['pydev_runfiles'] -if '_pydev_runfiles.pydev_runfiles' in sys.modules: - del sys.modules['_pydev_runfiles.pydev_runfiles'] +if "pydev_runfiles" in sys.modules: + del sys.modules["pydev_runfiles"] +if "_pydev_runfiles.pydev_runfiles" in sys.modules: + del sys.modules["_pydev_runfiles.pydev_runfiles"] from _pydev_runfiles import pydev_runfiles import unittest @@ -46,7 +47,6 @@ class RunfilesTest(unittest.TestCase): - def _setup_scenario( self, path, @@ -56,7 +56,7 @@ def _setup_scenario( exclude_files=None, exclude_tests=None, include_files=None, - ): + ): self.MyTestRunner = pydev_runfiles.PydevTestRunner( pydev_runfiles.Configuration( files_or_dirs=path, @@ -75,7 +75,7 @@ def _setup_scenario( self.filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) def setUp(self): - self.file_dir = [os.path.abspath(os.path.join(desired_runfiles_path, 'tests_runfiles/samples'))] + self.file_dir = [os.path.abspath(os.path.join(desired_runfiles_path, "tests_runfiles/samples"))] self._setup_scenario(self.file_dir, None) def test_suite_used(self): @@ -107,11 +107,13 @@ def test_parse_cmdline(self): sys.argv = "pydev_runfiles.py --include_tests Abc.test_def,Mod.test_abc c:/junk/".split() configuration = pydev_runfiles.parse_cmdline() self.assertEqual([sys.argv[-1]], configuration.files_or_dirs) - self.assertEqual(sys.argv[2].split(','), configuration.include_tests) + self.assertEqual(sys.argv[2].split(","), configuration.include_tests) - sys.argv = ('C:\\eclipse-SDK-3.2-win32\\eclipse\\plugins\\org.python.pydev.debug_1.2.2\\pysrc\\pydev_runfiles.py ' + - '--verbosity 1 ' + - 'C:\\workspace_eclipse\\fronttpa\\tests\\gui_tests\\calendar_popup_control_test.py ').split() + sys.argv = ( + "C:\\eclipse-SDK-3.2-win32\\eclipse\\plugins\\org.python.pydev.debug_1.2.2\\pysrc\\pydev_runfiles.py " + + "--verbosity 1 " + + "C:\\workspace_eclipse\\fronttpa\\tests\\gui_tests\\calendar_popup_control_test.py " + ).split() configuration = pydev_runfiles.parse_cmdline() self.assertEqual([sys.argv[-1]], configuration.files_or_dirs) self.assertEqual(1, configuration.verbosity) @@ -124,11 +126,11 @@ def test_parse_cmdline(self): sys.argv = "pydev_runfiles.py --exclude_files=*.txt,a*.py".split() configuration = pydev_runfiles.parse_cmdline() - self.assertEqual(['*.txt', 'a*.py'], configuration.exclude_files) + self.assertEqual(["*.txt", "a*.py"], configuration.exclude_files) sys.argv = "pydev_runfiles.py --exclude_tests=*__todo,test*bar".split() configuration = pydev_runfiles.parse_cmdline() - self.assertEqual(['*__todo', 'test*bar'], configuration.exclude_tests) + self.assertEqual(["*__todo", "test*bar"], configuration.exclude_tests) def test___adjust_python_path_works_for_directories(self): orig_syspath = sys.path @@ -147,7 +149,7 @@ def test___is_valid_py_file(self): def test___unixify(self): unixify = self.MyTestRunner._PydevTestRunner__unixify - self.assertEqual("c:/temp/junk/asdf.py", unixify("c:SEPtempSEPjunkSEPasdf.py".replace('SEP', os.sep))) + self.assertEqual("c:/temp/junk/asdf.py", unixify("c:SEPtempSEPjunkSEPasdf.py".replace("SEP", os.sep))) def test___importify(self): importify = self.MyTestRunner._PydevTestRunner__importify @@ -172,9 +174,10 @@ def test_finding_files_in_dir_from_file_system(self): def test___get_module_from_str(self): my_importer = self.MyTestRunner._PydevTestRunner__get_module_from_str - my_os_path = my_importer("os.path", True, 'unused') + my_os_path = my_importer("os.path", True, "unused") from os import path import os.path as path2 + self.assertEqual(path, my_os_path) self.assertEqual(path2, my_os_path) self.assertNotEqual(__import__("os.path"), my_os_path) @@ -242,84 +245,88 @@ def test_finding_tests_with_regex_filters(self): self.assertEqual(0, self.count_suite(filtered_tests)) def test_matching_tests(self): - self._setup_scenario(self.file_dir, None, ['StillYetAnotherSampleTest']) + self._setup_scenario(self.file_dir, None, ["StillYetAnotherSampleTest"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) self.assertEqual(1, self.count_suite(filtered_tests)) - self._setup_scenario(self.file_dir, None, ['SampleTest.test_xxxxxx1']) + self._setup_scenario(self.file_dir, None, ["SampleTest.test_xxxxxx1"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) self.assertEqual(1, self.count_suite(filtered_tests)) - self._setup_scenario(self.file_dir, None, ['SampleTest']) + self._setup_scenario(self.file_dir, None, ["SampleTest"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) self.assertEqual(8, self.count_suite(filtered_tests)) - self._setup_scenario(self.file_dir, None, ['AnotherSampleTest.todo_not_tested']) + self._setup_scenario(self.file_dir, None, ["AnotherSampleTest.todo_not_tested"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) self.assertEqual(1, self.count_suite(filtered_tests)) - self._setup_scenario(self.file_dir, None, ['StillYetAnotherSampleTest', 'SampleTest.test_xxxxxx1']) + self._setup_scenario(self.file_dir, None, ["StillYetAnotherSampleTest", "SampleTest.test_xxxxxx1"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) self.assertEqual(2, self.count_suite(filtered_tests)) - self._setup_scenario(self.file_dir, None, exclude_tests=['*']) + self._setup_scenario(self.file_dir, None, exclude_tests=["*"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) self.assertEqual(self.count_suite(filtered_tests), 0) - self._setup_scenario(self.file_dir, None, exclude_tests=['*a*']) + self._setup_scenario(self.file_dir, None, exclude_tests=["*a*"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) self.assertEqual(self.count_suite(filtered_tests), 6) self.assertEqual( set(self.MyTestRunner.list_test_names(filtered_tests)), - set(['test_1', 'test_2', 'test_xxxxxx1', 'test_xxxxxx2', 'test_xxxxxx3', 'test_xxxxxx4']) + set(["test_1", "test_2", "test_xxxxxx1", "test_xxxxxx2", "test_xxxxxx3", "test_xxxxxx4"]), ) - self._setup_scenario(self.file_dir, None, exclude_tests=['*a*', '*x*']) + self._setup_scenario(self.file_dir, None, exclude_tests=["*a*", "*x*"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) self.assertEqual(self.count_suite(filtered_tests), 2) - self.assertEqual( - set(self.MyTestRunner.list_test_names(filtered_tests)), - set(['test_1', 'test_2']) - ) + self.assertEqual(set(self.MyTestRunner.list_test_names(filtered_tests)), set(["test_1", "test_2"])) - self._setup_scenario(self.file_dir, None, exclude_files=['simple_test.py']) + self._setup_scenario(self.file_dir, None, exclude_files=["simple_test.py"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) names = self.MyTestRunner.list_test_names(filtered_tests) - self.assertTrue('test_xxxxxx1' not in names, 'Found: %s' % (names,)) + self.assertTrue("test_xxxxxx1" not in names, "Found: %s" % (names,)) self.assertEqual( - set(['test_abc', 'test_non_unique_name', 'test_non_unique_name', 'test_asdf2', 'test_i_am_a_unique_test_name', 'test_non_unique_name', 'test_blank']), - set(names) + set( + [ + "test_abc", + "test_non_unique_name", + "test_non_unique_name", + "test_asdf2", + "test_i_am_a_unique_test_name", + "test_non_unique_name", + "test_blank", + ] + ), + set(names), ) - self._setup_scenario(self.file_dir, None, include_files=['simple3_test.py']) + self._setup_scenario(self.file_dir, None, include_files=["simple3_test.py"]) filtered_tests = self.MyTestRunner.filter_tests(self.all_tests) names = self.MyTestRunner.list_test_names(filtered_tests) - self.assertTrue('test_xxxxxx1' not in names, 'Found: %s' % (names,)) + self.assertTrue("test_xxxxxx1" not in names, "Found: %s" % (names,)) - self.assertEqual( - set(['test_non_unique_name']), - set(names) - ) + self.assertEqual(set(["test_non_unique_name"]), set(names)) def test_xml_rpc_communication(self): import sys - sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'samples')) + + sys.path.insert(0, os.path.join(os.path.dirname(__file__), "samples")) notifications = [] class Server: - def __init__(self, notifications): self.notifications = notifications def notifyConnected(self): # This method is called at the very start (in runfiles.py), and we do not check this here - raise AssertionError('Should not be called from the run tests.') + raise AssertionError("Should not be called from the run tests.") def notifyTestsCollected(self, number_of_tests): - self.notifications.append(('notifyTestsCollected', number_of_tests)) + self.notifications.append(("notifyTestsCollected", number_of_tests)) def notifyStartTest(self, file, test): pass @@ -337,25 +344,25 @@ def notifyTest(self, cond, captured_output, error_contents, file, test, time): pass if error_contents: error_contents = error_contents.splitlines()[-1].strip() - self.notifications.append(('notifyTest', cond, captured_output.strip(), error_contents, file, test)) + self.notifications.append(("notifyTest", cond, captured_output.strip(), error_contents, file, test)) def notifyTestRunFinished(self, total_time): - self.notifications.append(('notifyTestRunFinished',)) + self.notifications.append(("notifyTestRunFinished",)) server = Server(notifications) pydev_runfiles_xml_rpc.set_server(server) - simple_test = os.path.join(self.file_dir[0], 'simple_test.py') - simple_test2 = os.path.join(self.file_dir[0], 'simple2_test.py') - simpleClass_test = os.path.join(self.file_dir[0], 'simpleClass_test.py') - simpleModule_test = os.path.join(self.file_dir[0], 'simpleModule_test.py') + simple_test = os.path.join(self.file_dir[0], "simple_test.py") + simple_test2 = os.path.join(self.file_dir[0], "simple2_test.py") + simpleClass_test = os.path.join(self.file_dir[0], "simpleClass_test.py") + simpleModule_test = os.path.join(self.file_dir[0], "simpleModule_test.py") files_to_tests = {} - files_to_tests.setdefault(simple_test , []).append('SampleTest.test_xxxxxx1') - files_to_tests.setdefault(simple_test , []).append('SampleTest.test_xxxxxx2') - files_to_tests.setdefault(simple_test , []).append('SampleTest.test_non_unique_name') - files_to_tests.setdefault(simple_test2, []).append('YetAnotherSampleTest.test_abc') - files_to_tests.setdefault(simpleClass_test, []).append('SetUpClassTest.test_blank') - files_to_tests.setdefault(simpleModule_test, []).append('SetUpModuleTest.test_blank') + files_to_tests.setdefault(simple_test, []).append("SampleTest.test_xxxxxx1") + files_to_tests.setdefault(simple_test, []).append("SampleTest.test_xxxxxx2") + files_to_tests.setdefault(simple_test, []).append("SampleTest.test_non_unique_name") + files_to_tests.setdefault(simple_test2, []).append("YetAnotherSampleTest.test_abc") + files_to_tests.setdefault(simpleClass_test, []).append("SetUpClassTest.test_blank") + files_to_tests.setdefault(simpleModule_test, []).append("SetUpModuleTest.test_blank") self._setup_scenario(None, files_to_tests=files_to_tests) self.MyTestRunner.verbosity = 2 @@ -367,40 +374,72 @@ def notifyTestRunFinished(self, total_time): if sys.version_info[:2] <= (2, 6): # The setUpClass is not supported in Python 2.6 (thus we have no collection error). expected = [ - ('notifyTest', 'fail', '', 'AssertionError: Fail test 2', simple_test, 'SampleTest.test_xxxxxx1'), - ('notifyTest', 'ok', '', '', simple_test2, 'YetAnotherSampleTest.test_abc'), - ('notifyTest', 'ok', '', '', simpleClass_test, 'SetUpClassTest.test_blank'), - ('notifyTest', 'ok', '', '', simpleModule_test, 'SetUpModuleTest.test_blank'), - ('notifyTest', 'ok', '', '', simple_test, 'SampleTest.test_xxxxxx2'), - ('notifyTest', 'ok', 'non unique name ran', '', simple_test, 'SampleTest.test_non_unique_name'), - ('notifyTestRunFinished',), - ('notifyTestsCollected', 6) + ("notifyTest", "fail", "", "AssertionError: Fail test 2", simple_test, "SampleTest.test_xxxxxx1"), + ("notifyTest", "ok", "", "", simple_test2, "YetAnotherSampleTest.test_abc"), + ("notifyTest", "ok", "", "", simpleClass_test, "SetUpClassTest.test_blank"), + ("notifyTest", "ok", "", "", simpleModule_test, "SetUpModuleTest.test_blank"), + ("notifyTest", "ok", "", "", simple_test, "SampleTest.test_xxxxxx2"), + ("notifyTest", "ok", "non unique name ran", "", simple_test, "SampleTest.test_non_unique_name"), + ("notifyTestRunFinished",), + ("notifyTestsCollected", 6), ] else: expected = [ - ('notifyTestsCollected', 6), - ('notifyTest', 'ok', 'non unique name ran', '', simple_test, 'SampleTest.test_non_unique_name'), - ('notifyTest', 'fail', '', 'AssertionError: Fail test 2', simple_test, 'SampleTest.test_xxxxxx1'), - ('notifyTest', 'ok', '', '', simple_test, 'SampleTest.test_xxxxxx2'), - ('notifyTest', 'ok', '', '', simple_test2, 'YetAnotherSampleTest.test_abc'), - ] + ("notifyTestsCollected", 6), + ("notifyTest", "ok", "non unique name ran", "", simple_test, "SampleTest.test_non_unique_name"), + ("notifyTest", "fail", "", "AssertionError: Fail test 2", simple_test, "SampleTest.test_xxxxxx1"), + ("notifyTest", "ok", "", "", simple_test, "SampleTest.test_xxxxxx2"), + ("notifyTest", "ok", "", "", simple_test2, "YetAnotherSampleTest.test_abc"), + ] if not IS_JYTHON: - if 'samples.simpleClass_test' in str(notifications): - expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpClass.', - simpleClass_test.replace('/', os.path.sep), 'samples.simpleClass_test.SetUpClassTest ')) - expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpModule.', - simpleModule_test.replace('/', os.path.sep), 'samples.simpleModule_test ')) + if "samples.simpleClass_test" in str(notifications): + expected.append( + ( + "notifyTest", + "error", + "", + "ValueError: This is an INTENTIONAL value error in setUpClass.", + simpleClass_test.replace("/", os.path.sep), + "samples.simpleClass_test.SetUpClassTest ", + ) + ) + expected.append( + ( + "notifyTest", + "error", + "", + "ValueError: This is an INTENTIONAL value error in setUpModule.", + simpleModule_test.replace("/", os.path.sep), + "samples.simpleModule_test ", + ) + ) else: - expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpClass.', - simpleClass_test.replace('/', os.path.sep), 'simpleClass_test.SetUpClassTest ')) - expected.append(('notifyTest', 'error', '', 'ValueError: This is an INTENTIONAL value error in setUpModule.', - simpleModule_test.replace('/', os.path.sep), 'simpleModule_test ')) + expected.append( + ( + "notifyTest", + "error", + "", + "ValueError: This is an INTENTIONAL value error in setUpClass.", + simpleClass_test.replace("/", os.path.sep), + "simpleClass_test.SetUpClassTest ", + ) + ) + expected.append( + ( + "notifyTest", + "error", + "", + "ValueError: This is an INTENTIONAL value error in setUpModule.", + simpleModule_test.replace("/", os.path.sep), + "simpleModule_test ", + ) + ) else: - expected.append(('notifyTest', 'ok', '', '', simpleClass_test, 'SetUpClassTest.test_blank')) - expected.append(('notifyTest', 'ok', '', '', simpleModule_test, 'SetUpModuleTest.test_blank')) + expected.append(("notifyTest", "ok", "", "", simpleClass_test, "SetUpClassTest.test_blank")) + expected.append(("notifyTest", "ok", "", "", simpleModule_test, "SetUpModuleTest.test_blank")) - expected.append(('notifyTestRunFinished',)) + expected.append(("notifyTestRunFinished",)) expected.sort() new_notifications = [] @@ -408,14 +447,16 @@ def notifyTestRunFinished(self, total_time): try: if len(notification) == 6: # Some are binary on Py3. - new_notifications.append(( - notification[0], - notification[1], - notification[2].encode('latin1'), - notification[3].encode('latin1'), - notification[4], - notification[5], - )) + new_notifications.append( + ( + notification[0], + notification[1], + notification[2].encode("latin1"), + notification[3].encode("latin1"), + notification[4], + notification[5], + ) + ) else: new_notifications.append(notification) except: @@ -424,14 +465,11 @@ def notifyTestRunFinished(self, total_time): notifications.sort() if not IS_JYTHON: - self.assertEqual( - expected, - notifications - ) + self.assertEqual(expected, notifications) finally: pydevd_io.end_redirect() b = buf.getvalue() if sys.version_info[:2] > (2, 6): - self.assertTrue(b.find('Ran 4 tests in ') != -1, 'Found: ' + b) + self.assertTrue(b.find("Ran 4 tests in ") != -1, "Found: " + b) else: - self.assertTrue(b.find('Ran 6 tests in ') != -1, 'Found: ' + b) + self.assertTrue(b.find("Ran 6 tests in ") != -1, "Found: " + b) diff --git a/third_party/cython_json.py b/third_party/cython_json.py index 6478c1c6d..e4644e7d0 100644 --- a/third_party/cython_json.py +++ b/third_party/cython_json.py @@ -8,7 +8,8 @@ try: from Cython.Compiler import Errors - Errors.init_thread() # This is needed in Cython 3.0.0 (otherwise reporting errors will throw exception). + + Errors.init_thread() # This is needed in Cython 3.0.0 (otherwise reporting errors will throw exception). except Exception: pass @@ -16,9 +17,7 @@ # Note: Cython has some recursive structures in some classes, so, parsing only what we really # expect may be a bit better (although our recursion check should get that too). -accepted_info = { - 'PyClassDef': set(['name', 'doc', 'body', 'bases', 'decorators', 'pos']) -} +accepted_info = {"PyClassDef": set(["name", "doc", "body", "bases", "decorators", "pos"])} def node_to_dict(node, _recurse_level=0, memo=None): @@ -40,7 +39,7 @@ def node_to_dict(node, _recurse_level=0, memo=None): node_name = node_name[:-4] data = {"__node__": node_name} if _recurse_level == 1: - data['__version__'] = Cython.__version__ + data["__version__"] = Cython.__version__ dct = node.__dict__ accepted = accepted_info.get(node_name) @@ -71,8 +70,8 @@ def node_to_dict(node, _recurse_level=0, memo=None): elif isinstance(x, (bytes, str)): lst.append(x) - elif hasattr(x, 'encode'): - lst.append(x.encode('utf-8', 'replace')) + elif hasattr(x, "encode"): + lst.append(x.encode("utf-8", "replace")) elif isinstance(x, (list, tuple)): tup = [] @@ -97,11 +96,11 @@ def node_to_dict(node, _recurse_level=0, memo=None): def source_to_dict(source, name=None): from Cython.Compiler.TreeFragment import parse_from_strings, StatListNode + # Right now we don't collect errors, but leave the API compatible already. collected_errors = [] try: - # Note: we don't use TreeFragment because it formats the code removing empty lines # (which ends up creating an AST with wrong lines). if not name: @@ -113,35 +112,30 @@ def source_to_dict(source, name=None): t = StatListNode(pos=mod.pos, stats=[t]) root = t except CompileError as e: - return { - 'ast': None, - 'errors': [node_to_dict(e)] - } + return {"ast": None, "errors": [node_to_dict(e)]} except BaseException as e: - as_dict = { - 'ast': None, - 'errors': [{ - '__node__': 'CompileError', 'line': 1, 'col': 1, 'message_only': str(e) - }] - } + as_dict = {"ast": None, "errors": [{"__node__": "CompileError", "line": 1, "col": 1, "message_only": str(e)}]} return as_dict - result = {'ast': node_to_dict(root), 'errors': [node_to_dict(e) for e in collected_errors]} + result = {"ast": node_to_dict(root), "errors": [node_to_dict(e) for e in collected_errors]} return result from _pydev_bundle import pydev_localhost + HOST = pydev_localhost.get_localhost() # Symbolic name meaning the local host def dbg(s): - sys.stderr.write('%s\n' % (s,)) + sys.stderr.write("%s\n" % (s,)) + + # f = open('c:/temp/test.txt', 'a') # print_ >> f, s # f.close() -SERVER_NAME = 'CythonJson' +SERVER_NAME = "CythonJson" class Exit(Exception): @@ -149,17 +143,16 @@ class Exit(Exception): class CythonJsonServer(object): - def __init__(self, port): self.ended = False - self._buffer = b'' + self._buffer = b"" self.port = port self.socket = None # socket to send messages. self.exit_process_on_kill = True def send(self, msg): if not isinstance(msg, bytes): - msg = msg.encode('utf-8', 'replace') + msg = msg.encode("utf-8", "replace") self.socket.sendall(msg) @@ -170,7 +163,7 @@ def connect_to_server(self): try: s.connect((HOST, self.port)) except: - sys.stderr.write('Error on connect_to_server with parameters: host: %s port: %s\n' % (HOST, self.port)) + sys.stderr.write("Error on connect_to_server with parameters: host: %s port: %s\n" % (HOST, self.port)) raise def _read(self, size): @@ -178,7 +171,7 @@ def _read(self, size): buffer_len = len(self._buffer) if buffer_len == size: ret = self._buffer - self._buffer = b'' + self._buffer = b"" return ret if buffer_len > size: @@ -189,14 +182,14 @@ def _read(self, size): try: r = self.socket.recv(max(size - buffer_len, 1024)) except OSError: - return b'' + return b"" if not r: - return b'' + return b"" self._buffer += r def _read_line(self): while True: - i = self._buffer.find(b'\n') + i = self._buffer.find(b"\n") if i != -1: i += 1 # Add the newline to the return ret = self._buffer[:i] @@ -206,68 +199,69 @@ def _read_line(self): try: r = self.socket.recv(1024) except OSError: - return b'' + return b"" if not r: - return b'' + return b"" self._buffer += r def process_command(self, json_contents): try: as_dict = json.loads(json_contents) - if as_dict['command'] == 'cython_to_json_ast': - contents = as_dict['contents'] + if as_dict["command"] == "cython_to_json_ast": + contents = as_dict["contents"] as_dict = source_to_dict(contents) result = as_dict else: - result = {'command': '', 'received': json_contents} + result = {"command": "", "received": json_contents} except: from io import StringIO + s = StringIO() traceback.print_exc(file=s) - result = {'command': '', 'error': s.getvalue()} + result = {"command": "", "error": s.getvalue()} return json.dumps(result) def run(self): # Echo server program try: - dbg(SERVER_NAME + ' connecting to java server on %s (%s)' % (HOST, self.port)) + dbg(SERVER_NAME + " connecting to java server on %s (%s)" % (HOST, self.port)) # after being connected, create a socket as a client. self.connect_to_server() - dbg(SERVER_NAME + ' Connected to java server') + dbg(SERVER_NAME + " Connected to java server") content_len = -1 while True: - dbg('Will read line...') + dbg("Will read line...") line = self._read_line() - dbg('Read: %s' % (line,)) + dbg("Read: %s" % (line,)) if not line: raise Exit() - if line.startswith(b'Content-Length:'): - content_len = int(line.strip().split(b':', 1)[1]) - dbg('Found content len: %s' % (content_len,)) + if line.startswith(b"Content-Length:"): + content_len = int(line.strip().split(b":", 1)[1]) + dbg("Found content len: %s" % (content_len,)) continue if content_len != -1: # If we previously received a content length, read until a '\r\n'. - if line == b'\r\n': - dbg('Will read contents (%s)...' % (content_len,)) + if line == b"\r\n": + dbg("Will read contents (%s)..." % (content_len,)) json_contents = self._read(content_len) - dbg('Read: %s' % (json_contents,)) + dbg("Read: %s" % (json_contents,)) content_len = -1 if len(json_contents) == 0: raise Exit() # We just received a json message, let's process it. - dbg('Will process...') + dbg("Will process...") output = self.process_command(json_contents) if not isinstance(output, bytes): - output = output.encode('utf-8', 'replace') + output = output.encode("utf-8", "replace") - self.send('Content-Length: %s\r\n\r\n' % (len(output),)) + self.send("Content-Length: %s\r\n\r\n" % (len(output),)) self.send(output) continue @@ -279,9 +273,9 @@ def run(self): raise -if __name__ == '__main__': +if __name__ == "__main__": args = sys.argv[1:] - if args == ['-']: + if args == ["-"]: # Read from stdin/dump to stdout if sys.version_info < (3,): stdin_get_value = sys.stdin.read @@ -290,7 +284,7 @@ def run(self): source = stdin_get_value() # After reading, convert to unicode (use the stdout encoding) - source = source.decode(sys.stdout.encoding, 'replace') + source = source.decode(sys.stdout.encoding, "replace") as_dict = source_to_dict(source) print(json.dumps(as_dict, indent=4)) sys.stdout.flush() @@ -299,6 +293,5 @@ def run(self): port = int(sys.argv[1]) # this is from where we want to receive messages. t = CythonJsonServer(port) - dbg(SERVER_NAME + ' will start') + dbg(SERVER_NAME + " will start") t.run() - diff --git a/third_party/pep8/autopep8.py b/third_party/pep8/autopep8.py index caa8b1a47..b57f0683a 100644 --- a/third_party/pep8/autopep8.py +++ b/third_party/pep8/autopep8.py @@ -83,6 +83,7 @@ class documentation for more information. import tokenize import warnings import ast + try: from configparser import ConfigParser as SafeConfigParser from configparser import Error @@ -98,21 +99,21 @@ class documentation for more information. except NameError: unicode = str -__version__ = '1.6.0' +__version__ = "1.6.0" -CR = '\r' -LF = '\n' -CRLF = '\r\n' +CR = "\r" +LF = "\n" +CRLF = "\r\n" -PYTHON_SHEBANG_REGEX = re.compile(r'^#!.*\bpython[23]?\b\s*$') -LAMBDA_REGEX = re.compile(r'([\w.]+)\s=\slambda\s*([)(=\w,\s.]*):') -COMPARE_NEGATIVE_REGEX = re.compile(r'\b(not)\s+([^][)(}{]+?)\s+(in|is)\s') -COMPARE_NEGATIVE_REGEX_THROUGH = re.compile(r'\b(not\s+in|is\s+not)\s') -BARE_EXCEPT_REGEX = re.compile(r'except\s*:') -STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)\s.*\):') +PYTHON_SHEBANG_REGEX = re.compile(r"^#!.*\bpython[23]?\b\s*$") +LAMBDA_REGEX = re.compile(r"([\w.]+)\s=\slambda\s*([)(=\w,\s.]*):") +COMPARE_NEGATIVE_REGEX = re.compile(r"\b(not)\s+([^][)(}{]+?)\s+(in|is)\s") +COMPARE_NEGATIVE_REGEX_THROUGH = re.compile(r"\b(not\s+in|is\s+not)\s") +BARE_EXCEPT_REGEX = re.compile(r"except\s*:") +STARTSWITH_DEF_REGEX = re.compile(r"^(async\s+def|def)\s.*\):") DOCSTRING_START_REGEX = re.compile(r'^u?r?(?P["\']{3})') -ENABLE_REGEX = re.compile(r'# *(fmt|autopep8): *on') -DISABLE_REGEX = re.compile(r'# *(fmt|autopep8): *off') +ENABLE_REGEX = re.compile(r"# *(fmt|autopep8): *on") +DISABLE_REGEX = re.compile(r"# *(fmt|autopep8): *off") EXIT_CODE_OK = 0 EXIT_CODE_ERROR = 1 @@ -120,75 +121,80 @@ class documentation for more information. EXIT_CODE_ARGPARSE_ERROR = 99 # For generating line shortening candidates. -SHORTEN_OPERATOR_GROUPS = frozenset([ - frozenset([',']), - frozenset(['%']), - frozenset([',', '(', '[', '{']), - frozenset(['%', '(', '[', '{']), - frozenset([',', '(', '[', '{', '%', '+', '-', '*', '/', '//']), - frozenset(['%', '+', '-', '*', '/', '//']), -]) - -DEFAULT_IGNORE = 'E226,E24,W50,W690' # TODO: use pycodestyle.DEFAULT_IGNORE +SHORTEN_OPERATOR_GROUPS = frozenset( + [ + frozenset([","]), + frozenset(["%"]), + frozenset([",", "(", "[", "{"]), + frozenset(["%", "(", "[", "{"]), + frozenset([",", "(", "[", "{", "%", "+", "-", "*", "/", "//"]), + frozenset(["%", "+", "-", "*", "/", "//"]), + ] +) + +DEFAULT_IGNORE = "E226,E24,W50,W690" # TODO: use pycodestyle.DEFAULT_IGNORE DEFAULT_INDENT_SIZE = 4 # these fixes conflict with each other, if the `--ignore` setting causes both # to be enabled, disable both of them -CONFLICTING_CODES = ('W503', 'W504') +CONFLICTING_CODES = ("W503", "W504") -SELECTED_GLOBAL_FIXED_METHOD_CODES = ['W602', ] +SELECTED_GLOBAL_FIXED_METHOD_CODES = [ + "W602", +] # W602 is handled separately due to the need to avoid "with_traceback". CODE_TO_2TO3 = { - 'E231': ['ws_comma'], - 'E721': ['idioms'], - 'W601': ['has_key'], - 'W603': ['ne'], - 'W604': ['repr'], - 'W690': ['apply', - 'except', - 'exitfunc', - 'numliterals', - 'operator', - 'paren', - 'reduce', - 'renames', - 'standarderror', - 'sys_exc', - 'throw', - 'tuple_params', - 'xreadlines']} - -if sys.platform == 'win32': # pragma: no cover - DEFAULT_CONFIG = os.path.expanduser(r'~\.pycodestyle') + "E231": ["ws_comma"], + "E721": ["idioms"], + "W601": ["has_key"], + "W603": ["ne"], + "W604": ["repr"], + "W690": [ + "apply", + "except", + "exitfunc", + "numliterals", + "operator", + "paren", + "reduce", + "renames", + "standarderror", + "sys_exc", + "throw", + "tuple_params", + "xreadlines", + ], +} + +if sys.platform == "win32": # pragma: no cover + DEFAULT_CONFIG = os.path.expanduser(r"~\.pycodestyle") else: - DEFAULT_CONFIG = os.path.join(os.getenv('XDG_CONFIG_HOME') or - os.path.expanduser('~/.config'), - 'pycodestyle') + DEFAULT_CONFIG = os.path.join(os.getenv("XDG_CONFIG_HOME") or os.path.expanduser("~/.config"), "pycodestyle") # fallback, use .pep8 if not os.path.exists(DEFAULT_CONFIG): # pragma: no cover - if sys.platform == 'win32': - DEFAULT_CONFIG = os.path.expanduser(r'~\.pep8') + if sys.platform == "win32": + DEFAULT_CONFIG = os.path.expanduser(r"~\.pep8") else: - DEFAULT_CONFIG = os.path.join(os.path.expanduser('~/.config'), 'pep8') -PROJECT_CONFIG = ('setup.cfg', 'tox.ini', '.pep8', '.flake8') + DEFAULT_CONFIG = os.path.join(os.path.expanduser("~/.config"), "pep8") +PROJECT_CONFIG = ("setup.cfg", "tox.ini", ".pep8", ".flake8") MAX_PYTHON_FILE_DETECTION_BYTES = 1024 -def open_with_encoding(filename, mode='r', encoding=None, limit_byte_check=-1): +def open_with_encoding(filename, mode="r", encoding=None, limit_byte_check=-1): """Return opened file with a specific encoding.""" if not encoding: encoding = detect_encoding(filename, limit_byte_check=limit_byte_check) - return io.open(filename, mode=mode, encoding=encoding, - newline='') # Preserve line endings + return io.open(filename, mode=mode, encoding=encoding, newline="") # Preserve line endings def detect_encoding(filename, limit_byte_check=-1): """Return file encoding.""" try: - with open(filename, 'rb') as input_file: + with open(filename, "rb") as input_file: from lib2to3.pgen2 import tokenize as lib2to3_tokenize + encoding = lib2to3_tokenize.detect_encoding(input_file.readline)[0] with open_with_encoding(filename, encoding=encoding) as test_file: @@ -196,7 +202,7 @@ def detect_encoding(filename, limit_byte_check=-1): return encoding except (LookupError, SyntaxError, UnicodeDecodeError): - return 'latin-1' + return "latin-1" def readlines_from_file(filename): @@ -205,32 +211,21 @@ def readlines_from_file(filename): return input_file.readlines() -def extended_blank_lines(logical_line, - blank_lines, - blank_before, - indent_level, - previous_logical): +def extended_blank_lines(logical_line, blank_lines, blank_before, indent_level, previous_logical): """Check for missing blank lines after class declaration.""" - if previous_logical.startswith('def '): + if previous_logical.startswith("def "): if blank_lines and pycodestyle.DOCSTRING_REGEX.match(logical_line): - yield (0, 'E303 too many blank lines ({})'.format(blank_lines)) + yield (0, "E303 too many blank lines ({})".format(blank_lines)) elif pycodestyle.DOCSTRING_REGEX.match(previous_logical): # Missing blank line between class docstring and method declaration. - if ( - indent_level and - not blank_lines and - not blank_before and - logical_line.startswith(('def ')) and - '(self' in logical_line - ): - yield (0, 'E301 expected 1 blank line, found 0') + if indent_level and not blank_lines and not blank_before and logical_line.startswith(("def ")) and "(self" in logical_line: + yield (0, "E301 expected 1 blank line, found 0") pycodestyle.register_check(extended_blank_lines) -def continued_indentation(logical_line, tokens, indent_level, hang_closing, - indent_char, noqa): +def continued_indentation(logical_line, tokens, indent_level, hang_closing, indent_char, noqa): """Override pycodestyle's function to provide indentation information.""" first_row = tokens[0][2][0] nrows = 1 + tokens[-1][2][0] - first_row @@ -241,14 +236,10 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, # that it is indented by 4 spaces, then we should not allow 4-space # indents on the final continuation line. In turn, some other # indents are allowed to have an extra 4 spaces. - indent_next = logical_line.endswith(':') + indent_next = logical_line.endswith(":") row = depth = 0 - valid_hangs = ( - (DEFAULT_INDENT_SIZE,) - if indent_char != '\t' else (DEFAULT_INDENT_SIZE, - 2 * DEFAULT_INDENT_SIZE) - ) + valid_hangs = (DEFAULT_INDENT_SIZE,) if indent_char != "\t" else (DEFAULT_INDENT_SIZE, 2 * DEFAULT_INDENT_SIZE) # Remember how many brackets were opened on each line. parens = [0] * nrows @@ -268,15 +259,13 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, last_token_multiline = None line = None - last_line = '' + last_line = "" last_line_begins_with_multiline = False for token_type, text, start, end, line in tokens: - newline = row < start[0] - first_row if newline: row = start[0] - first_row - newline = (not last_token_multiline and - token_type not in (tokenize.NL, tokenize.NEWLINE)) + newline = not last_token_multiline and token_type not in (tokenize.NL, tokenize.NEWLINE) last_line_begins_with_multiline = last_token_multiline if newline: @@ -287,7 +276,7 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, rel_indent[row] = pycodestyle.expand_indent(line) - indent_level # Identify closing bracket. - close_bracket = (token_type == tokenize.OP and text in ']})') + close_bracket = token_type == tokenize.OP and text in "]})" # Is the indent relative to an opening bracket line? for open_row in reversed(open_rows[depth]): @@ -296,30 +285,26 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, if hanging_indent: break if hangs[depth]: - hanging_indent = (hang == hangs[depth]) + hanging_indent = hang == hangs[depth] - visual_indent = (not close_bracket and hang > 0 and - indent_chances.get(start[1])) + visual_indent = not close_bracket and hang > 0 and indent_chances.get(start[1]) if close_bracket and indent[depth]: # Closing bracket for visual indent. if start[1] != indent[depth]: - yield (start, 'E124 {}'.format(indent[depth])) + yield (start, "E124 {}".format(indent[depth])) elif close_bracket and not hang: # closing bracket matches indentation of opening bracket's line if hang_closing: - yield (start, 'E133 {}'.format(indent[depth])) + yield (start, "E133 {}".format(indent[depth])) elif indent[depth] and start[1] < indent[depth]: if visual_indent is not True: # Visual indent is broken. - yield (start, 'E128 {}'.format(indent[depth])) - elif (hanging_indent or - (indent_next and - rel_indent[row] == 2 * DEFAULT_INDENT_SIZE)): + yield (start, "E128 {}".format(indent[depth])) + elif hanging_indent or (indent_next and rel_indent[row] == 2 * DEFAULT_INDENT_SIZE): # Hanging indent is verified. if close_bracket and not hang_closing: - yield (start, 'E123 {}'.format(indent_level + - rel_indent[open_row])) + yield (start, "E123 {}".format(indent_level + rel_indent[open_row])) hangs[depth] = hang elif visual_indent is True: # Visual indent is verified. @@ -328,45 +313,39 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, # Ignore token lined up with matching one from a previous line. pass else: - one_indented = (indent_level + rel_indent[open_row] + - DEFAULT_INDENT_SIZE) + one_indented = indent_level + rel_indent[open_row] + DEFAULT_INDENT_SIZE # Indent is broken. if hang <= 0: - error = ('E122', one_indented) + error = ("E122", one_indented) elif indent[depth]: - error = ('E127', indent[depth]) + error = ("E127", indent[depth]) elif not close_bracket and hangs[depth]: - error = ('E131', one_indented) + error = ("E131", one_indented) elif hang > DEFAULT_INDENT_SIZE: - error = ('E126', one_indented) + error = ("E126", one_indented) else: hangs[depth] = hang - error = ('E121', one_indented) + error = ("E121", one_indented) - yield (start, '{} {}'.format(*error)) + yield (start, "{} {}".format(*error)) # Look for visual indenting. - if ( - parens[row] and - token_type not in (tokenize.NL, tokenize.COMMENT) and - not indent[depth] - ): + if parens[row] and token_type not in (tokenize.NL, tokenize.COMMENT) and not indent[depth]: indent[depth] = start[1] indent_chances[start[1]] = True # Deal with implicit string concatenation. - elif (token_type in (tokenize.STRING, tokenize.COMMENT) or - text in ('u', 'ur', 'b', 'br')): + elif token_type in (tokenize.STRING, tokenize.COMMENT) or text in ("u", "ur", "b", "br"): indent_chances[start[1]] = unicode # Special case for the "if" statement because len("if (") is equal to # 4. - elif not indent_chances and not row and not depth and text == 'if': + elif not indent_chances and not row and not depth and text == "if": indent_chances[end[1] + 1] = True - elif text == ':' and line[end[1]:].isspace(): + elif text == ":" and line[end[1] :].isspace(): open_rows[depth].append(row) # Keep track of bracket depth. if token_type == tokenize.OP: - if text in '([{': + if text in "([{": depth += 1 indent.append(0) hangs.append(None) @@ -374,7 +353,7 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, open_rows.append([]) open_rows[depth].append(row) parens[row] += 1 - elif text in ')]}' and depth > 0: + elif text in ")]}" and depth > 0: # Parent indents should not be more than this one. prev_indent = indent.pop() or last_indent[1] hangs.pop() @@ -384,7 +363,7 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, for ind in list(indent_chances): if ind >= prev_indent: del indent_chances[ind] - del open_rows[depth + 1:] + del open_rows[depth + 1 :] depth -= 1 if depth: indent_chances[indent[depth]] = True @@ -394,33 +373,30 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, break assert len(indent) == depth + 1 if ( - start[1] not in indent_chances and + start[1] not in indent_chances + and # This is for purposes of speeding up E121 (GitHub #90). - not last_line.rstrip().endswith(',') + not last_line.rstrip().endswith(",") ): # Allow to line up tokens. indent_chances[start[1]] = text - last_token_multiline = (start[0] != end[0]) + last_token_multiline = start[0] != end[0] if last_token_multiline: rel_indent[end[0] - first_row] = rel_indent[row] last_line = line - if ( - indent_next and - not last_line_begins_with_multiline and - pycodestyle.expand_indent(line) == indent_level + DEFAULT_INDENT_SIZE - ): + if indent_next and not last_line_begins_with_multiline and pycodestyle.expand_indent(line) == indent_level + DEFAULT_INDENT_SIZE: pos = (start[0], indent[0] + 4) desired_indent = indent_level + 2 * DEFAULT_INDENT_SIZE if visual_indent: - yield (pos, 'E129 {}'.format(desired_indent)) + yield (pos, "E129 {}".format(desired_indent)) else: - yield (pos, 'E125 {}'.format(desired_indent)) + yield (pos, "E125 {}".format(desired_indent)) -del pycodestyle._checks['logical_line'][pycodestyle.continued_indentation] +del pycodestyle._checks["logical_line"][pycodestyle.continued_indentation] pycodestyle.register_check(continued_indentation) @@ -465,10 +441,7 @@ class FixPEP8(object): """ - def __init__(self, filename, - options, - contents=None, - long_line_ignore_cache=None): + def __init__(self, filename, options, contents=None, long_line_ignore_cache=None): self.filename = filename if contents is None: self.source = readlines_from_file(filename) @@ -476,19 +449,16 @@ def __init__(self, filename, sio = io.StringIO(contents) self.source = sio.readlines() self.options = options - self.indent_word = _get_indentword(''.join(self.source)) + self.indent_word = _get_indentword("".join(self.source)) # collect imports line self.imports = {} for i, line in enumerate(self.source): - if (line.find("import ") == 0 or line.find("from ") == 0) and \ - line not in self.imports: + if (line.find("import ") == 0 or line.find("from ") == 0) and line not in self.imports: # collect only import statements that first appeared self.imports[line] = i - self.long_line_ignore_cache = ( - set() if long_line_ignore_cache is None - else long_line_ignore_cache) + self.long_line_ignore_cache = set() if long_line_ignore_cache is None else long_line_ignore_cache # Many fixers are the same even though pycodestyle categorizes them # differently. @@ -520,9 +490,8 @@ def __init__(self, filename, self.fix_e274 = self.fix_e271 self.fix_e306 = self.fix_e301 self.fix_e501 = ( - self.fix_long_line_logically if - options and (options.aggressive >= 2 or options.experimental) else - self.fix_long_line_physically) + self.fix_long_line_logically if options and (options.aggressive >= 2 or options.experimental) else self.fix_long_line_physically + ) self.fix_e703 = self.fix_e702 self.fix_w292 = self.fix_w291 self.fix_w293 = self.fix_w291 @@ -536,28 +505,22 @@ def _fix_source(self, results): completed_lines = set() for result in sorted(results, key=_priority_key): - if result['line'] in completed_lines: + if result["line"] in completed_lines: continue - fixed_methodname = 'fix_' + result['id'].lower() + fixed_methodname = "fix_" + result["id"].lower() if hasattr(self, fixed_methodname): fix = getattr(self, fixed_methodname) - line_index = result['line'] - 1 + line_index = result["line"] - 1 original_line = self.source[line_index] is_logical_fix = len(_get_parameters(fix)) > 2 if is_logical_fix: logical = None if logical_support: - logical = _get_logical(self.source, - result, - logical_start, - logical_end) - if logical and set(range( - logical[0][0] + 1, - logical[1][0] + 1)).intersection( - completed_lines): + logical = _get_logical(self.source, result, logical_start, logical_end) + if logical and set(range(logical[0][0] + 1, logical[1][0] + 1)).intersection(completed_lines): continue modified_lines = fix(result, logical) @@ -575,60 +538,46 @@ def _fix_source(self, results): completed_lines.update(modified_lines) elif modified_lines == []: # Empty list means no fix if self.options.verbose >= 2: - print( - '---> Not fixing {error} on line {line}'.format( - error=result['id'], line=result['line']), - file=sys.stderr) + print("---> Not fixing {error} on line {line}".format(error=result["id"], line=result["line"]), file=sys.stderr) else: # We assume one-line fix when None. - completed_lines.add(result['line']) + completed_lines.add(result["line"]) else: if self.options.verbose >= 3: - print( - "---> '{}' is not defined.".format(fixed_methodname), - file=sys.stderr) + print("---> '{}' is not defined.".format(fixed_methodname), file=sys.stderr) - info = result['info'].strip() - print('---> {}:{}:{}:{}'.format(self.filename, - result['line'], - result['column'], - info), - file=sys.stderr) + info = result["info"].strip() + print("---> {}:{}:{}:{}".format(self.filename, result["line"], result["column"], info), file=sys.stderr) def fix(self): """Return a version of the source code with PEP 8 violations fixed.""" pep8_options = { - 'ignore': self.options.ignore, - 'select': self.options.select, - 'max_line_length': self.options.max_line_length, - 'hang_closing': self.options.hang_closing, + "ignore": self.options.ignore, + "select": self.options.select, + "max_line_length": self.options.max_line_length, + "hang_closing": self.options.hang_closing, } results = _execute_pep8(pep8_options, self.source) if self.options.verbose: progress = {} for r in results: - if r['id'] not in progress: - progress[r['id']] = set() - progress[r['id']].add(r['line']) - print('---> {n} issue(s) to fix {progress}'.format( - n=len(results), progress=progress), file=sys.stderr) + if r["id"] not in progress: + progress[r["id"]] = set() + progress[r["id"]].add(r["line"]) + print("---> {n} issue(s) to fix {progress}".format(n=len(results), progress=progress), file=sys.stderr) if self.options.line_range: start, end = self.options.line_range - results = [r for r in results - if start <= r['line'] <= end] + results = [r for r in results if start <= r["line"] <= end] - self._fix_source(filter_results(source=''.join(self.source), - results=results, - aggressive=self.options.aggressive)) + self._fix_source(filter_results(source="".join(self.source), results=results, aggressive=self.options.aggressive)) if self.options.line_range: # If number of lines has changed then change line_range. - count = sum(sline.count('\n') - for sline in self.source[start - 1:end]) + count = sum(sline.count("\n") for sline in self.source[start - 1 : end]) self.options.line_range[1] = start + count - 1 - return ''.join(self.source) + return "".join(self.source) def _fix_reindent(self, result): """Fix a badly indented line. @@ -636,18 +585,18 @@ def _fix_reindent(self, result): This is done by adding or removing from its initial indent only. """ - num_indent_spaces = int(result['info'].split()[1]) - line_index = result['line'] - 1 + num_indent_spaces = int(result["info"].split()[1]) + line_index = result["line"] - 1 target = self.source[line_index] - self.source[line_index] = ' ' * num_indent_spaces + target.lstrip() + self.source[line_index] = " " * num_indent_spaces + target.lstrip() def fix_e112(self, result): """Fix under-indented comments.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] - if not target.lstrip().startswith('#'): + if not target.lstrip().startswith("#"): # Don't screw with invalid syntax. return [] @@ -655,7 +604,7 @@ def fix_e112(self, result): def fix_e113(self, result): """Fix unexpected indentation.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] indent = _get_indentation(target) stripped = target.lstrip() @@ -663,13 +612,13 @@ def fix_e113(self, result): def fix_e116(self, result): """Fix over-indented comments.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] indent = _get_indentation(target) stripped = target.lstrip() - if not stripped.startswith('#'): + if not stripped.startswith("#"): # Don't screw with invalid syntax. return [] @@ -677,11 +626,11 @@ def fix_e116(self, result): def fix_e117(self, result): """Fix over-indented.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] indent = _get_indentation(target) - if indent == '\t': + if indent == "\t": return [] stripped = target.lstrip() @@ -690,8 +639,8 @@ def fix_e117(self, result): def fix_e125(self, result): """Fix indentation undistinguish from the next logical line.""" - num_indent_spaces = int(result['info'].split()[1]) - line_index = result['line'] - 1 + num_indent_spaces = int(result["info"].split()[1]) + line_index = result["line"] - 1 target = self.source[line_index] spaces_to_add = num_indent_spaces - len(_get_indentation(target)) @@ -699,8 +648,7 @@ def fix_e125(self, result): modified_lines = [] while len(_get_indentation(self.source[line_index])) >= indent: - self.source[line_index] = (' ' * spaces_to_add + - self.source[line_index]) + self.source[line_index] = " " * spaces_to_add + self.source[line_index] modified_lines.append(1 + line_index) # Line indexed at 1. line_index -= 1 @@ -708,8 +656,8 @@ def fix_e125(self, result): def fix_e131(self, result): """Fix indentation undistinguish from the next logical line.""" - num_indent_spaces = int(result['info'].split()[1]) - line_index = result['line'] - 1 + num_indent_spaces = int(result["info"].split()[1]) + line_index = result["line"] - 1 target = self.source[line_index] spaces_to_add = num_indent_spaces - len(_get_indentation(target)) @@ -720,80 +668,72 @@ def fix_e131(self, result): spaces_to_add = 4 if spaces_to_add >= 0: - self.source[line_index] = (' ' * spaces_to_add + - self.source[line_index]) + self.source[line_index] = " " * spaces_to_add + self.source[line_index] else: offset = abs(spaces_to_add) self.source[line_index] = self.source[line_index][offset:] def fix_e201(self, result): """Remove extraneous whitespace.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] - offset = result['column'] - 1 + offset = result["column"] - 1 - fixed = fix_whitespace(target, - offset=offset, - replacement='') + fixed = fix_whitespace(target, offset=offset, replacement="") self.source[line_index] = fixed def fix_e224(self, result): """Remove extraneous whitespace around operator.""" - target = self.source[result['line'] - 1] - offset = result['column'] - 1 - fixed = target[:offset] + target[offset:].replace('\t', ' ') - self.source[result['line'] - 1] = fixed + target = self.source[result["line"] - 1] + offset = result["column"] - 1 + fixed = target[:offset] + target[offset:].replace("\t", " ") + self.source[result["line"] - 1] = fixed def fix_e225(self, result): """Fix missing whitespace around operator.""" - target = self.source[result['line'] - 1] - offset = result['column'] - 1 - fixed = target[:offset] + ' ' + target[offset:] + target = self.source[result["line"] - 1] + offset = result["column"] - 1 + fixed = target[:offset] + " " + target[offset:] # Only proceed if non-whitespace characters match. # And make sure we don't break the indentation. - if ( - fixed.replace(' ', '') == target.replace(' ', '') and - _get_indentation(fixed) == _get_indentation(target) - ): - self.source[result['line'] - 1] = fixed - error_code = result.get('id', 0) + if fixed.replace(" ", "") == target.replace(" ", "") and _get_indentation(fixed) == _get_indentation(target): + self.source[result["line"] - 1] = fixed + error_code = result.get("id", 0) try: ts = generate_tokens(fixed) except (SyntaxError, tokenize.TokenError): return if not check_syntax(fixed.lstrip()): return - errors = list( - pycodestyle.missing_whitespace_around_operator(fixed, ts)) + errors = list(pycodestyle.missing_whitespace_around_operator(fixed, ts)) for e in reversed(errors): if error_code != e[1].split()[0]: continue offset = e[0][1] - fixed = fixed[:offset] + ' ' + fixed[offset:] - self.source[result['line'] - 1] = fixed + fixed = fixed[:offset] + " " + fixed[offset:] + self.source[result["line"] - 1] = fixed else: return [] def fix_e231(self, result): """Add missing whitespace.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] - offset = result['column'] - fixed = target[:offset].rstrip() + ' ' + target[offset:].lstrip() + offset = result["column"] + fixed = target[:offset].rstrip() + " " + target[offset:].lstrip() self.source[line_index] = fixed def fix_e251(self, result): """Remove whitespace around parameter '=' sign.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] # This is necessary since pycodestyle sometimes reports columns that # goes past the end of the physical line. This happens in cases like, # foo(bar\n=None) - c = min(result['column'] - 1, - len(target) - 1) + c = min(result["column"] - 1, len(target) - 1) if target[c].strip(): fixed = target @@ -804,34 +744,32 @@ def fix_e251(self, result): # # def foo(a=\ # 1) - if fixed.endswith(('=\\\n', '=\\\r\n', '=\\\r')): - self.source[line_index] = fixed.rstrip('\n\r \t\\') + if fixed.endswith(("=\\\n", "=\\\r\n", "=\\\r")): + self.source[line_index] = fixed.rstrip("\n\r \t\\") self.source[line_index + 1] = self.source[line_index + 1].lstrip() return [line_index + 1, line_index + 2] # Line indexed at 1 - self.source[result['line'] - 1] = fixed + self.source[result["line"] - 1] = fixed def fix_e262(self, result): """Fix spacing after comment hash.""" - target = self.source[result['line'] - 1] - offset = result['column'] + target = self.source[result["line"] - 1] + offset = result["column"] - code = target[:offset].rstrip(' \t#') - comment = target[offset:].lstrip(' \t#') + code = target[:offset].rstrip(" \t#") + comment = target[offset:].lstrip(" \t#") - fixed = code + (' # ' + comment if comment.strip() else '\n') + fixed = code + (" # " + comment if comment.strip() else "\n") - self.source[result['line'] - 1] = fixed + self.source[result["line"] - 1] = fixed def fix_e271(self, result): """Fix extraneous whitespace around keywords.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] - offset = result['column'] - 1 + offset = result["column"] - 1 - fixed = fix_whitespace(target, - offset=offset, - replacement=' ') + fixed = fix_whitespace(target, offset=offset, replacement=" ") if fixed == target: return [] @@ -840,33 +778,31 @@ def fix_e271(self, result): def fix_e301(self, result): """Add missing blank line.""" - cr = '\n' - self.source[result['line'] - 1] = cr + self.source[result['line'] - 1] + cr = "\n" + self.source[result["line"] - 1] = cr + self.source[result["line"] - 1] def fix_e302(self, result): """Add missing 2 blank lines.""" - add_linenum = 2 - int(result['info'].split()[-1]) + add_linenum = 2 - int(result["info"].split()[-1]) offset = 1 - if self.source[result['line'] - 2].strip() == "\\": + if self.source[result["line"] - 2].strip() == "\\": offset = 2 - cr = '\n' * add_linenum - self.source[result['line'] - offset] = ( - cr + self.source[result['line'] - offset] - ) + cr = "\n" * add_linenum + self.source[result["line"] - offset] = cr + self.source[result["line"] - offset] def fix_e303(self, result): """Remove extra blank lines.""" - delete_linenum = int(result['info'].split('(')[1].split(')')[0]) - 2 + delete_linenum = int(result["info"].split("(")[1].split(")")[0]) - 2 delete_linenum = max(1, delete_linenum) # We need to count because pycodestyle reports an offset line number if # there are comments. cnt = 0 - line = result['line'] - 2 + line = result["line"] - 2 modified_lines = [] while cnt < delete_linenum and line >= 0: if not self.source[line].strip(): - self.source[line] = '' + self.source[line] = "" modified_lines.append(1 + line) # Line indexed at 1 cnt += 1 line -= 1 @@ -875,28 +811,28 @@ def fix_e303(self, result): def fix_e304(self, result): """Remove blank line following function decorator.""" - line = result['line'] - 2 + line = result["line"] - 2 if not self.source[line].strip(): - self.source[line] = '' + self.source[line] = "" def fix_e305(self, result): """Add missing 2 blank lines after end of function or class.""" - add_delete_linenum = 2 - int(result['info'].split()[-1]) + add_delete_linenum = 2 - int(result["info"].split()[-1]) cnt = 0 - offset = result['line'] - 2 + offset = result["line"] - 2 modified_lines = [] if add_delete_linenum < 0: # delete cr add_delete_linenum = abs(add_delete_linenum) while cnt < add_delete_linenum and offset >= 0: if not self.source[offset].strip(): - self.source[offset] = '' + self.source[offset] = "" modified_lines.append(1 + offset) # Line indexed at 1 cnt += 1 offset -= 1 else: # add cr - cr = '\n' + cr = "\n" # check comment line while True: if offset < 0: @@ -904,7 +840,7 @@ def fix_e305(self, result): line = self.source[offset].lstrip() if not line: break - if line[0] != '#': + if line[0] != "#": break offset -= 1 offset += 1 @@ -914,66 +850,56 @@ def fix_e305(self, result): def fix_e401(self, result): """Put imports on separate lines.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] - offset = result['column'] - 1 + offset = result["column"] - 1 - if not target.lstrip().startswith('import'): + if not target.lstrip().startswith("import"): return [] - indentation = re.split(pattern=r'\bimport\b', - string=target, maxsplit=1)[0] - fixed = (target[:offset].rstrip('\t ,') + '\n' + - indentation + 'import ' + target[offset:].lstrip('\t ,')) + indentation = re.split(pattern=r"\bimport\b", string=target, maxsplit=1)[0] + fixed = target[:offset].rstrip("\t ,") + "\n" + indentation + "import " + target[offset:].lstrip("\t ,") self.source[line_index] = fixed def fix_e402(self, result): - (line_index, offset, target) = get_index_offset_contents(result, - self.source) + (line_index, offset, target) = get_index_offset_contents(result, self.source) for i in range(1, 100): - line = "".join(self.source[line_index:line_index + i]) + line = "".join(self.source[line_index : line_index + i]) try: generate_tokens("".join(line)) except (SyntaxError, tokenize.TokenError): continue break if not (target in self.imports and self.imports[target] != line_index): - mod_offset = get_module_imports_on_top_of_file(self.source, - line_index) + mod_offset = get_module_imports_on_top_of_file(self.source, line_index) self.source[mod_offset] = line + self.source[mod_offset] for offset in range(i): - self.source[line_index + offset] = '' + self.source[line_index + offset] = "" def fix_long_line_logically(self, result, logical): """Try to make lines fit within --max-line-length characters.""" - if ( - not logical or - len(logical[2]) == 1 or - self.source[result['line'] - 1].lstrip().startswith('#') - ): + if not logical or len(logical[2]) == 1 or self.source[result["line"] - 1].lstrip().startswith("#"): return self.fix_long_line_physically(result) start_line_index = logical[0][0] end_line_index = logical[1][0] logical_lines = logical[2] - previous_line = get_item(self.source, start_line_index - 1, default='') - next_line = get_item(self.source, end_line_index + 1, default='') + previous_line = get_item(self.source, start_line_index - 1, default="") + next_line = get_item(self.source, end_line_index + 1, default="") - single_line = join_logical_line(''.join(logical_lines)) + single_line = join_logical_line("".join(logical_lines)) try: fixed = self.fix_long_line( - target=single_line, - previous_line=previous_line, - next_line=next_line, - original=''.join(logical_lines)) + target=single_line, previous_line=previous_line, next_line=next_line, original="".join(logical_lines) + ) except (SyntaxError, tokenize.TokenError): return self.fix_long_line_physically(result) if fixed: for line_index in range(start_line_index, end_line_index + 1): - self.source[line_index] = '' + self.source[line_index] = "" self.source[start_line_index] = fixed return range(start_line_index + 1, end_line_index + 1) @@ -981,18 +907,14 @@ def fix_long_line_logically(self, result, logical): def fix_long_line_physically(self, result): """Try to make lines fit within --max-line-length characters.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] - previous_line = get_item(self.source, line_index - 1, default='') - next_line = get_item(self.source, line_index + 1, default='') + previous_line = get_item(self.source, line_index - 1, default="") + next_line = get_item(self.source, line_index + 1, default="") try: - fixed = self.fix_long_line( - target=target, - previous_line=previous_line, - next_line=next_line, - original=target) + fixed = self.fix_long_line(target=target, previous_line=previous_line, next_line=next_line, original=target) except (SyntaxError, tokenize.TokenError): return [] @@ -1002,19 +924,17 @@ def fix_long_line_physically(self, result): return [] - def fix_long_line(self, target, previous_line, - next_line, original): + def fix_long_line(self, target, previous_line, next_line, original): cache_entry = (target, previous_line, next_line) if cache_entry in self.long_line_ignore_cache: return [] - if target.lstrip().startswith('#'): + if target.lstrip().startswith("#"): if self.options.aggressive: # Wrap commented lines. return shorten_comment( - line=target, - max_line_length=self.options.max_line_length, - last_comment=not next_line.lstrip().startswith('#')) + line=target, max_line_length=self.options.max_line_length, last_comment=not next_line.lstrip().startswith("#") + ) return [] fixed = get_fixed_long_line( @@ -1025,7 +945,8 @@ def fix_long_line(self, target, previous_line, max_line_length=self.options.max_line_length, aggressive=self.options.aggressive, experimental=self.options.experimental, - verbose=self.options.verbose) + verbose=self.options.verbose, + ) if fixed and not code_almost_equal(original, fixed): return fixed @@ -1035,21 +956,18 @@ def fix_long_line(self, target, previous_line, def fix_e502(self, result): """Remove extraneous escape of newline.""" - (line_index, _, target) = get_index_offset_contents(result, - self.source) - self.source[line_index] = target.rstrip('\n\r \t\\') + '\n' + (line_index, _, target) = get_index_offset_contents(result, self.source) + self.source[line_index] = target.rstrip("\n\r \t\\") + "\n" def fix_e701(self, result): """Put colon-separated compound statement on separate lines.""" - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] - c = result['column'] + c = result["column"] - fixed_source = (target[:c] + '\n' + - _get_indentation(target) + self.indent_word + - target[c:].lstrip('\n\r \t\\')) - self.source[result['line'] - 1] = fixed_source - return [result['line'], result['line'] + 1] + fixed_source = target[:c] + "\n" + _get_indentation(target) + self.indent_word + target[c:].lstrip("\n\r \t\\") + self.source[result["line"] - 1] = fixed_source + return [result["line"], result["line"] + 1] def fix_e702(self, result, logical): """Put semicolon-separated compound statement on separate lines.""" @@ -1060,60 +978,51 @@ def fix_e702(self, result, logical): # Avoid applying this when indented. # https://docs.python.org/reference/compound_stmts.html for line in logical_lines: - if (result['id'] == 'E702' and ':' in line - and STARTSWITH_INDENT_STATEMENT_REGEX.match(line)): + if result["id"] == "E702" and ":" in line and STARTSWITH_INDENT_STATEMENT_REGEX.match(line): if self.options.verbose: - print( - '---> avoid fixing {error} with ' - 'other compound statements'.format(error=result['id']), - file=sys.stderr - ) + print("---> avoid fixing {error} with " "other compound statements".format(error=result["id"]), file=sys.stderr) return [] - line_index = result['line'] - 1 + line_index = result["line"] - 1 target = self.source[line_index] - if target.rstrip().endswith('\\'): + if target.rstrip().endswith("\\"): # Normalize '1; \\\n2' into '1; 2'. - self.source[line_index] = target.rstrip('\n \r\t\\') + self.source[line_index] = target.rstrip("\n \r\t\\") self.source[line_index + 1] = self.source[line_index + 1].lstrip() return [line_index + 1, line_index + 2] - if target.rstrip().endswith(';'): - self.source[line_index] = target.rstrip('\n \r\t;') + '\n' + if target.rstrip().endswith(";"): + self.source[line_index] = target.rstrip("\n \r\t;") + "\n" return [line_index + 1] - offset = result['column'] - 1 - first = target[:offset].rstrip(';').rstrip() - second = (_get_indentation(logical_lines[0]) + - target[offset:].lstrip(';').lstrip()) + offset = result["column"] - 1 + first = target[:offset].rstrip(";").rstrip() + second = _get_indentation(logical_lines[0]) + target[offset:].lstrip(";").lstrip() # Find inline comment. inline_comment = None - if target[offset:].lstrip(';').lstrip()[:2] == '# ': - inline_comment = target[offset:].lstrip(';') + if target[offset:].lstrip(";").lstrip()[:2] == "# ": + inline_comment = target[offset:].lstrip(";") if inline_comment: self.source[line_index] = first + inline_comment else: - self.source[line_index] = first + '\n' + second + self.source[line_index] = first + "\n" + second return [line_index + 1] def fix_e704(self, result): """Fix multiple statements on one line def""" - (line_index, _, target) = get_index_offset_contents(result, - self.source) + (line_index, _, target) = get_index_offset_contents(result, self.source) match = STARTSWITH_DEF_REGEX.match(target) if match: - self.source[line_index] = '{}\n{}{}'.format( - match.group(0), - _get_indentation(target) + self.indent_word, - target[match.end(0):].lstrip()) + self.source[line_index] = "{}\n{}{}".format( + match.group(0), _get_indentation(target) + self.indent_word, target[match.end(0) :].lstrip() + ) def fix_e711(self, result): """Fix comparison with None.""" - (line_index, offset, target) = get_index_offset_contents(result, - self.source) + (line_index, offset, target) = get_index_offset_contents(result, self.source) right_offset = offset + 2 if right_offset >= len(target): @@ -1123,27 +1032,24 @@ def fix_e711(self, result): center = target[offset:right_offset] right = target[right_offset:].lstrip() - if center.strip() == '==': - new_center = 'is' - elif center.strip() == '!=': - new_center = 'is not' + if center.strip() == "==": + new_center = "is" + elif center.strip() == "!=": + new_center = "is not" else: return [] - self.source[line_index] = ' '.join([left, new_center, right]) + self.source[line_index] = " ".join([left, new_center, right]) def fix_e712(self, result): """Fix (trivial case of) comparison with boolean.""" - (line_index, offset, target) = get_index_offset_contents(result, - self.source) + (line_index, offset, target) = get_index_offset_contents(result, self.source) # Handle very easy "not" special cases. if re.match(r'^\s*if [\w."\'\[\]]+ == False:$', target): - self.source[line_index] = re.sub(r'if ([\w."\'\[\]]+) == False:', - r'if not \1:', target, count=1) + self.source[line_index] = re.sub(r'if ([\w."\'\[\]]+) == False:', r"if not \1:", target, count=1) elif re.match(r'^\s*if [\w."\'\[\]]+ != True:$', target): - self.source[line_index] = re.sub(r'if ([\w."\'\[\]]+) != True:', - r'if not \1:', target, count=1) + self.source[line_index] = re.sub(r'if ([\w."\'\[\]]+) != True:', r"if not \1:", target, count=1) else: right_offset = offset + 2 if right_offset >= len(target): @@ -1155,25 +1061,24 @@ def fix_e712(self, result): # Handle simple cases only. new_right = None - if center.strip() == '==': - if re.match(r'\bTrue\b', right): - new_right = re.sub(r'\bTrue\b *', '', right, count=1) - elif center.strip() == '!=': - if re.match(r'\bFalse\b', right): - new_right = re.sub(r'\bFalse\b *', '', right, count=1) + if center.strip() == "==": + if re.match(r"\bTrue\b", right): + new_right = re.sub(r"\bTrue\b *", "", right, count=1) + elif center.strip() == "!=": + if re.match(r"\bFalse\b", right): + new_right = re.sub(r"\bFalse\b *", "", right, count=1) if new_right is None: return [] if new_right[0].isalnum(): - new_right = ' ' + new_right + new_right = " " + new_right self.source[line_index] = left + new_right def fix_e713(self, result): """Fix (trivial case of) non-membership check.""" - (line_index, offset, target) = get_index_offset_contents(result, - self.source) + (line_index, offset, target) = get_index_offset_contents(result, self.source) # to convert once 'not in' -> 'in' before_target = target[:offset] @@ -1183,29 +1088,26 @@ def fix_e713(self, result): if match_notin: notin_pos_start = match_notin.start(1) notin_pos_end = match_notin.end() - target = '{}{} {}'.format( - target[:notin_pos_start], 'in', target[notin_pos_end:]) + target = "{}{} {}".format(target[:notin_pos_start], "in", target[notin_pos_end:]) # fix 'not in' match = COMPARE_NEGATIVE_REGEX.search(target) if match: - if match.group(3) == 'in': + if match.group(3) == "in": pos_start = match.start(1) - new_target = '{5}{0}{1} {2} {3} {4}'.format( - target[:pos_start], match.group(2), match.group(1), - match.group(3), target[match.end():], before_target) + new_target = "{5}{0}{1} {2} {3} {4}".format( + target[:pos_start], match.group(2), match.group(1), match.group(3), target[match.end() :], before_target + ) if match_notin: # revert 'in' -> 'not in' pos_start = notin_pos_start + offset pos_end = notin_pos_end + offset - 4 # len('not ') - new_target = '{}{} {}'.format( - new_target[:pos_start], 'not in', new_target[pos_end:]) + new_target = "{}{} {}".format(new_target[:pos_start], "not in", new_target[pos_end:]) self.source[line_index] = new_target def fix_e714(self, result): """Fix object identity should be 'is not' case.""" - (line_index, offset, target) = get_index_offset_contents(result, - self.source) + (line_index, offset, target) = get_index_offset_contents(result, self.source) # to convert once 'is not' -> 'is' before_target = target[:offset] @@ -1215,49 +1117,43 @@ def fix_e714(self, result): if match_isnot: isnot_pos_start = match_isnot.start(1) isnot_pos_end = match_isnot.end() - target = '{}{} {}'.format( - target[:isnot_pos_start], 'in', target[isnot_pos_end:]) + target = "{}{} {}".format(target[:isnot_pos_start], "in", target[isnot_pos_end:]) match = COMPARE_NEGATIVE_REGEX.search(target) if match: - if match.group(3).startswith('is'): + if match.group(3).startswith("is"): pos_start = match.start(1) - new_target = '{5}{0}{1} {2} {3} {4}'.format( - target[:pos_start], match.group(2), match.group(3), - match.group(1), target[match.end():], before_target) + new_target = "{5}{0}{1} {2} {3} {4}".format( + target[:pos_start], match.group(2), match.group(3), match.group(1), target[match.end() :], before_target + ) if match_isnot: # revert 'is' -> 'is not' pos_start = isnot_pos_start + offset pos_end = isnot_pos_end + offset - 4 # len('not ') - new_target = '{}{} {}'.format( - new_target[:pos_start], 'is not', new_target[pos_end:]) + new_target = "{}{} {}".format(new_target[:pos_start], "is not", new_target[pos_end:]) self.source[line_index] = new_target def fix_e722(self, result): """fix bare except""" - (line_index, _, target) = get_index_offset_contents(result, - self.source) + (line_index, _, target) = get_index_offset_contents(result, self.source) match = BARE_EXCEPT_REGEX.search(target) if match: - self.source[line_index] = '{}{}{}'.format( - target[:result['column'] - 1], "except BaseException:", - target[match.end():]) + self.source[line_index] = "{}{}{}".format(target[: result["column"] - 1], "except BaseException:", target[match.end() :]) def fix_e731(self, result): """Fix do not assign a lambda expression check.""" - (line_index, _, target) = get_index_offset_contents(result, - self.source) + (line_index, _, target) = get_index_offset_contents(result, self.source) match = LAMBDA_REGEX.search(target) if match: end = match.end() - self.source[line_index] = '{}def {}({}): return {}'.format( - target[:match.start(0)], match.group(1), match.group(2), - target[end:].lstrip()) + self.source[line_index] = "{}def {}({}): return {}".format( + target[: match.start(0)], match.group(1), match.group(2), target[end:].lstrip() + ) def fix_w291(self, result): """Remove trailing whitespace.""" - fixed_line = self.source[result['line'] - 1].rstrip() - self.source[result['line'] - 1] = fixed_line + '\n' + fixed_line = self.source[result["line"] - 1].rstrip() + self.source[result["line"] - 1] = fixed_line + "\n" def fix_w391(self, _): """Remove trailing blank lines.""" @@ -1270,12 +1166,11 @@ def fix_w391(self, _): blank_count += 1 original_length = len(self.source) - self.source = self.source[:original_length - blank_count] + self.source = self.source[: original_length - blank_count] return range(1, 1 + original_length) def fix_w503(self, result): - (line_index, _, target) = get_index_offset_contents(result, - self.source) + (line_index, _, target) = get_index_offset_contents(result, self.source) one_string_token = target.split()[0] try: ts = generate_tokens(one_string_token) @@ -1296,10 +1191,7 @@ def fix_w503(self, result): break to_index = line_index + 1 strip_line = self.source[from_index].lstrip() - if ( - not found_not_comment_only_line and - strip_line and strip_line[0] == '#' - ): + if not found_not_comment_only_line and strip_line and strip_line[0] == "#": comment_only_linenum += 1 continue found_not_comment_only_line = True @@ -1314,7 +1206,7 @@ def fix_w503(self, result): newline_index.append(index) newline_count += 1 if newline_count > 2: - tts = ts[newline_index[-3]:] + tts = ts[newline_index[-3] :] else: tts = ts old = [] @@ -1330,28 +1222,24 @@ def fix_w503(self, result): break i = target.index(one_string_token) fix_target_line = line_index - 1 - comment_only_linenum - self.source[line_index] = '{}{}'.format( - target[:i], target[i + len(one_string_token):].lstrip()) + self.source[line_index] = "{}{}".format(target[:i], target[i + len(one_string_token) :].lstrip()) nl = find_newline(self.source[fix_target_line:line_index]) before_line = self.source[fix_target_line] bl = before_line.index(nl) if comment_index: - self.source[fix_target_line] = '{} {} {}'.format( - before_line[:comment_index], one_string_token, - before_line[comment_index + 1:]) + self.source[fix_target_line] = "{} {} {}".format( + before_line[:comment_index], one_string_token, before_line[comment_index + 1 :] + ) else: if before_line[:bl].endswith("#"): # special case # see: https://github.com/hhatto/autopep8/issues/503 - self.source[fix_target_line] = '{}{} {}'.format( - before_line[:bl - 2], one_string_token, before_line[bl - 2:]) + self.source[fix_target_line] = "{}{} {}".format(before_line[: bl - 2], one_string_token, before_line[bl - 2 :]) else: - self.source[fix_target_line] = '{} {}{}'.format( - before_line[:bl], one_string_token, before_line[bl:]) + self.source[fix_target_line] = "{} {}{}".format(before_line[:bl], one_string_token, before_line[bl:]) def fix_w504(self, result): - (line_index, _, target) = get_index_offset_contents(result, - self.source) + (line_index, _, target) = get_index_offset_contents(result, self.source) # NOTE: is not collect pointed out in pycodestyle==2.4.0 comment_index = 0 operator_position = None # (start_position, end_position) @@ -1374,7 +1262,7 @@ def fix_w504(self, result): newline_index.append(index) newline_count += 1 if newline_count > 2: - tts = ts[:newline_index[-3]] + tts = ts[: newline_index[-3]] else: tts = ts old = [] @@ -1386,32 +1274,25 @@ def fix_w504(self, result): break if not operator_position: return - target_operator = target[operator_position[0]:operator_position[1]] + target_operator = target[operator_position[0] : operator_position[1]] if comment_index and comment_row == 1: - self.source[line_index] = '{}{}'.format( - target[:operator_position[0]].rstrip(), - target[comment_index:]) + self.source[line_index] = "{}{}".format(target[: operator_position[0]].rstrip(), target[comment_index:]) else: - self.source[line_index] = '{}{}{}'.format( - target[:operator_position[0]].rstrip(), - target[operator_position[1]:].lstrip(), - target[operator_position[1]:]) + self.source[line_index] = "{}{}{}".format( + target[: operator_position[0]].rstrip(), target[operator_position[1] :].lstrip(), target[operator_position[1] :] + ) next_line = self.source[line_index + 1] next_line_indent = 0 - m = re.match(r'\s*', next_line) + m = re.match(r"\s*", next_line) if m: next_line_indent = m.span()[1] - self.source[line_index + 1] = '{}{} {}'.format( - next_line[:next_line_indent], target_operator, - next_line[next_line_indent:]) + self.source[line_index + 1] = "{}{} {}".format(next_line[:next_line_indent], target_operator, next_line[next_line_indent:]) def fix_w605(self, result): - (line_index, offset, target) = get_index_offset_contents(result, - self.source) - self.source[line_index] = '{}\\{}'.format( - target[:offset + 1], target[offset + 1:]) + (line_index, offset, target) = get_index_offset_contents(result, self.source) + self.source[line_index] = "{}\\{}".format(target[: offset + 1], target[offset + 1 :]) def get_module_imports_on_top_of_file(source, import_line_index): @@ -1425,22 +1306,22 @@ def get_module_imports_on_top_of_file(source, import_line_index): """ def is_string_literal(line): - if line[0] in 'uUbB': + if line[0] in "uUbB": line = line[1:] - if line and line[0] in 'rR': + if line and line[0] in "rR": line = line[1:] return line and (line[0] == '"' or line[0] == "'") def is_future_import(line): nodes = ast.parse(line) for n in nodes.body: - if isinstance(n, ast.ImportFrom) and n.module == '__future__': + if isinstance(n, ast.ImportFrom) and n.module == "__future__": return True return False def has_future_import(source): offset = 0 - line = '' + line = "" for _, next_line in source: for line_part in next_line.strip().splitlines(True): line = line + line_part @@ -1451,7 +1332,7 @@ def has_future_import(source): offset += 1 return False, offset - allowed_try_keywords = ('try', 'except', 'else', 'finally') + allowed_try_keywords = ("try", "except", "else", "finally") in_docstring = False docstring_kind = '"""' source_stream = iter(enumerate(source)) @@ -1460,8 +1341,8 @@ def has_future_import(source): m = DOCSTRING_START_REGEX.match(line.lstrip()) if m is not None: in_docstring = True - docstring_kind = m.group('kind') - remain = line[m.end(): m.endpos].rstrip() + docstring_kind = m.group("kind") + remain = line[m.end() : m.endpos].rstrip() if remain[-3:] == docstring_kind: # one line doc in_docstring = False continue @@ -1472,19 +1353,17 @@ def has_future_import(source): if not line.rstrip(): continue - elif line.startswith('#'): + elif line.startswith("#"): continue - if line.startswith('import '): + if line.startswith("import "): if cnt == import_line_index: continue return cnt - elif line.startswith('from '): + elif line.startswith("from "): if cnt == import_line_index: continue - hit, offset = has_future_import( - itertools.chain([(cnt, line)], source_stream) - ) + hit, offset = has_future_import(itertools.chain([(cnt, line)], source_stream)) if hit: # move to the back return cnt + offset + 1 @@ -1502,15 +1381,13 @@ def has_future_import(source): def get_index_offset_contents(result, source): """Return (line_index, column_offset, line_contents).""" - line_index = result['line'] - 1 - return (line_index, - result['column'] - 1, - source[line_index]) + line_index = result["line"] - 1 + return (line_index, result["column"] - 1, source[line_index]) -def get_fixed_long_line(target, previous_line, original, - indent_word=' ', max_line_length=79, - aggressive=False, experimental=False, verbose=False): +def get_fixed_long_line( + target, previous_line, original, indent_word=" ", max_line_length=79, aggressive=False, experimental=False, verbose=False +): """Break up long line and return result. Do this by generating multiple reformatted candidates and then @@ -1518,33 +1395,25 @@ def get_fixed_long_line(target, previous_line, original, """ indent = _get_indentation(target) - source = target[len(indent):] + source = target[len(indent) :] assert source.lstrip() == source - assert not target.lstrip().startswith('#') + assert not target.lstrip().startswith("#") # Check for partial multiline. tokens = list(generate_tokens(source)) candidates = shorten_line( - tokens, source, indent, - indent_word, - max_line_length, - aggressive=aggressive, - experimental=experimental, - previous_line=previous_line) + tokens, source, indent, indent_word, max_line_length, aggressive=aggressive, experimental=experimental, previous_line=previous_line + ) # Also sort alphabetically as a tie breaker (for determinism). candidates = sorted( sorted(set(candidates).union([target, original])), - key=lambda x: line_shortening_rank( - x, - indent_word, - max_line_length, - experimental=experimental)) + key=lambda x: line_shortening_rank(x, indent_word, max_line_length, experimental=experimental), + ) if verbose >= 4: - print(('-' * 79 + '\n').join([''] + candidates + ['']), - file=wrap_output(sys.stderr, 'utf-8')) + print(("-" * 79 + "\n").join([""] + candidates + [""]), file=wrap_output(sys.stderr, "utf-8")) if candidates: best_candidate = candidates[0] @@ -1567,13 +1436,12 @@ def join_logical_line(logical_line): """Return single line based on logical line input.""" indentation = _get_indentation(logical_line) - return indentation + untokenize_without_newlines( - generate_tokens(logical_line.lstrip())) + '\n' + return indentation + untokenize_without_newlines(generate_tokens(logical_line.lstrip())) + "\n" def untokenize_without_newlines(tokens): """Return source code based on tokens.""" - text = '' + text = "" last_row = 0 last_column = -1 @@ -1584,13 +1452,10 @@ def untokenize_without_newlines(tokens): if start_row > last_row: last_column = 0 - if ( - (start_column > last_column or token_string == '\n') and - not text.endswith(' ') - ): - text += ' ' + if (start_column > last_column or token_string == "\n") and not text.endswith(" "): + text += " " - if token_string != '\n': + if token_string != "\n": text += token_string last_row = end_row @@ -1605,10 +1470,8 @@ def _find_logical(source_lines): logical_end = [] last_newline = True parens = 0 - for t in generate_tokens(''.join(source_lines)): - if t[0] in [tokenize.COMMENT, tokenize.DEDENT, - tokenize.INDENT, tokenize.NL, - tokenize.ENDMARKER]: + for t in generate_tokens("".join(source_lines)): + if t[0] in [tokenize.COMMENT, tokenize.DEDENT, tokenize.INDENT, tokenize.NL, tokenize.ENDMARKER]: continue if not parens and t[0] in [tokenize.NEWLINE, tokenize.SEMI]: last_newline = True @@ -1618,9 +1481,9 @@ def _find_logical(source_lines): logical_start.append((t[2][0] - 1, t[2][1])) last_newline = False if t[0] == tokenize.OP: - if t[1] in '([{': + if t[1] in "([{": parens += 1 - elif t[1] in '}])': + elif t[1] in "}])": parens -= 1 return (logical_start, logical_end) @@ -1631,8 +1494,8 @@ def _get_logical(source_lines, result, logical_start, logical_end): Assumes input is already E702-clean. """ - row = result['line'] - 1 - col = result['column'] - 1 + row = result["line"] - 1 + col = result["column"] - 1 ls = None le = None for i in range(0, len(logical_start), 1): @@ -1644,7 +1507,7 @@ def _get_logical(source_lines, result, logical_start, logical_end): break if ls is None: return None - original = source_lines[ls[0]:le[0] + 1] + original = source_lines[ls[0] : le[0] + 1] return ls, le, original @@ -1673,8 +1536,8 @@ def code_almost_equal(a, b): if len(split_a) != len(split_b): return False - for (index, _) in enumerate(split_a): - if ''.join(split_a[index].split()) != ''.join(split_b[index].split()): + for index, _ in enumerate(split_a): + if "".join(split_a[index].split()) != "".join(split_b[index].split()): return False return True @@ -1691,47 +1554,40 @@ def split_and_strip_non_empty_lines(text): def fix_e265(source, aggressive=False): # pylint: disable=unused-argument """Format block comments.""" - if '#' not in source: + if "#" not in source: # Optimization. return source - ignored_line_numbers = multiline_string_lines( - source, - include_docstrings=True) | set(commented_out_code_lines(source)) + ignored_line_numbers = multiline_string_lines(source, include_docstrings=True) | set(commented_out_code_lines(source)) fixed_lines = [] sio = io.StringIO(source) - for (line_number, line) in enumerate(sio.readlines(), start=1): - if ( - line.lstrip().startswith('#') and - line_number not in ignored_line_numbers and - not pycodestyle.noqa(line) - ): + for line_number, line in enumerate(sio.readlines(), start=1): + if line.lstrip().startswith("#") and line_number not in ignored_line_numbers and not pycodestyle.noqa(line): indentation = _get_indentation(line) line = line.lstrip() # Normalize beginning if not a shebang. if len(line) > 1: - pos = next((index for index, c in enumerate(line) - if c != '#')) + pos = next((index for index, c in enumerate(line) if c != "#")) if ( # Leave multiple spaces like '# ' alone. - (line[:pos].count('#') > 1 or line[1].isalnum() or - not line[1].isspace()) and - line[1] not in ':!' and + (line[:pos].count("#") > 1 or line[1].isalnum() or not line[1].isspace()) + and line[1] not in ":!" + and # Leave stylistic outlined blocks alone. - not line.rstrip().endswith('#') + not line.rstrip().endswith("#") ): - line = '# ' + line.lstrip('# \t') + line = "# " + line.lstrip("# \t") fixed_lines.append(indentation + line) else: fixed_lines.append(line) - return ''.join(fixed_lines) + return "".join(fixed_lines) -def refactor(source, fixer_names, ignore=None, filename=''): +def refactor(source, fixer_names, ignore=None, filename=""): """Return refactored code using lib2to3. Skip if ignore string is produced in the refactored code. @@ -1744,14 +1600,10 @@ def refactor(source, fixer_names, ignore=None, filename=''): input_source = source from lib2to3 import pgen2 + try: - new_text = refactor_with_2to3(input_source, - fixer_names=fixer_names, - filename=filename) - except (pgen2.parse.ParseError, - SyntaxError, - UnicodeDecodeError, - UnicodeEncodeError): + new_text = refactor_with_2to3(input_source, fixer_names=fixer_names, filename=filename) + except (pgen2.parse.ParseError, SyntaxError, UnicodeDecodeError, UnicodeEncodeError): return source if ignore: @@ -1764,21 +1616,17 @@ def refactor(source, fixer_names, ignore=None, filename=''): return new_text -def code_to_2to3(select, ignore, where='', verbose=False): +def code_to_2to3(select, ignore, where="", verbose=False): fixes = set() for code, fix in CODE_TO_2TO3.items(): if code_match(code, select=select, ignore=ignore): if verbose: - print('---> Applying {} fix for {}'.format(where, - code.upper()), - file=sys.stderr) + print("---> Applying {} fix for {}".format(where, code.upper()), file=sys.stderr) fixes |= set(fix) return fixes -def fix_2to3(source, - aggressive=True, select=None, ignore=None, filename='', - where='global', verbose=False): +def fix_2to3(source, aggressive=True, select=None, ignore=None, filename="", where="global", verbose=False): """Fix various deprecated code (via lib2to3).""" if not aggressive: return source @@ -1786,12 +1634,7 @@ def fix_2to3(source, select = select or [] ignore = ignore or [] - return refactor(source, - code_to_2to3(select=select, - ignore=ignore, - where=where, - verbose=verbose), - filename=filename) + return refactor(source, code_to_2to3(select=select, ignore=ignore, where=where, verbose=verbose), filename=filename) def fix_w602(source, aggressive=True): @@ -1799,7 +1642,7 @@ def fix_w602(source, aggressive=True): if not aggressive: return source - return refactor(source, ['raise'], ignore='with_traceback') + return refactor(source, ["raise"], ignore="with_traceback") def find_newline(source): @@ -1824,7 +1667,7 @@ def find_newline(source): def _get_indentword(source): """Return indentation type.""" - indent_word = ' ' # Default in case source has no indentation + indent_word = " " # Default in case source has no indentation try: for t in generate_tokens(source): if t[0] == token.INDENT: @@ -1841,25 +1684,21 @@ def _get_indentation(line): non_whitespace_index = len(line) - len(line.lstrip()) return line[:non_whitespace_index] - return '' + return "" def get_diff_text(old, new, filename): """Return text of unified diff between old and new.""" - newline = '\n' - diff = difflib.unified_diff( - old, new, - 'original/' + filename, - 'fixed/' + filename, - lineterm=newline) - - text = '' + newline = "\n" + diff = difflib.unified_diff(old, new, "original/" + filename, "fixed/" + filename, lineterm=newline) + + text = "" for line in diff: text += line # Work around missing newline (http://bugs.python.org/issue2142). if text and not line.endswith(newline): - text += newline + r'\ No newline at end of file' + newline + text += newline + r"\ No newline at end of file" + newline return text @@ -1873,23 +1712,24 @@ def _priority_key(pep8_result): """ priority = [ # Fix multiline colon-based before semicolon based. - 'e701', + "e701", # Break multiline statements early. - 'e702', + "e702", # Things that make lines longer. - 'e225', 'e231', + "e225", + "e231", # Remove extraneous whitespace before breaking lines. - 'e201', + "e201", # Shorten whitespace in comment before resorting to wrapping. - 'e262' + "e262", ] middle_index = 10000 lowest_priority = [ # We need to shorten lines last since the logical fixer can get in a # loop, which causes us to exit early. - 'e501', + "e501", ] - key = pep8_result['id'].lower() + key = pep8_result["id"].lower() try: return priority.index(key) except ValueError: @@ -1899,19 +1739,15 @@ def _priority_key(pep8_result): return middle_index -def shorten_line(tokens, source, indentation, indent_word, max_line_length, - aggressive=False, experimental=False, previous_line=''): +def shorten_line(tokens, source, indentation, indent_word, max_line_length, aggressive=False, experimental=False, previous_line=""): """Separate line at OPERATOR. Multiple candidates will be yielded. """ - for candidate in _shorten_line(tokens=tokens, - source=source, - indentation=indentation, - indent_word=indent_word, - aggressive=aggressive, - previous_line=previous_line): + for candidate in _shorten_line( + tokens=tokens, source=source, indentation=indentation, indent_word=indent_word, aggressive=aggressive, previous_line=previous_line + ): yield candidate if aggressive: @@ -1922,23 +1758,20 @@ def shorten_line(tokens, source, indentation, indent_word, max_line_length, indentation=indentation, indent_word=indent_word, key_token_strings=key_token_strings, - aggressive=aggressive) + aggressive=aggressive, + ) if shortened is not None and shortened != source: yield shortened if experimental: for shortened in _shorten_line_at_tokens_new( - tokens=tokens, - source=source, - indentation=indentation, - max_line_length=max_line_length): - + tokens=tokens, source=source, indentation=indentation, max_line_length=max_line_length + ): yield shortened -def _shorten_line(tokens, source, indentation, indent_word, - aggressive=False, previous_line=''): +def _shorten_line(tokens, source, indentation, indent_word, aggressive=False, previous_line=""): """Separate line at OPERATOR. The input is expected to be free of newlines except for inside multiline @@ -1947,24 +1780,18 @@ def _shorten_line(tokens, source, indentation, indent_word, Multiple candidates will be yielded. """ - for (token_type, - token_string, - start_offset, - end_offset) in token_offsets(tokens): - + for token_type, token_string, start_offset, end_offset in token_offsets(tokens): if ( - token_type == tokenize.COMMENT and - not is_probably_part_of_multiline(previous_line) and - not is_probably_part_of_multiline(source) and - not source[start_offset + 1:].strip().lower().startswith( - ('noqa', 'pragma:', 'pylint:')) + token_type == tokenize.COMMENT + and not is_probably_part_of_multiline(previous_line) + and not is_probably_part_of_multiline(source) + and not source[start_offset + 1 :].strip().lower().startswith(("noqa", "pragma:", "pylint:")) ): # Move inline comments to previous line. first = source[:start_offset] second = source[start_offset:] - yield (indentation + second.strip() + '\n' + - indentation + first.strip() + '\n') - elif token_type == token.OP and token_string != '=': + yield (indentation + second.strip() + "\n" + indentation + first.strip() + "\n") + elif token_type == token.OP and token_string != "=": # Don't break on '=' after keyword as this violates PEP 8. assert token_type != token.INDENT @@ -1972,48 +1799,41 @@ def _shorten_line(tokens, source, indentation, indent_word, first = source[:end_offset] second_indent = indentation - if (first.rstrip().endswith('(') and - source[end_offset:].lstrip().startswith(')')): + if first.rstrip().endswith("(") and source[end_offset:].lstrip().startswith(")"): pass - elif first.rstrip().endswith('('): + elif first.rstrip().endswith("("): second_indent += indent_word - elif '(' in first: - second_indent += ' ' * (1 + first.find('(')) + elif "(" in first: + second_indent += " " * (1 + first.find("(")) else: second_indent += indent_word - second = (second_indent + source[end_offset:].lstrip()) - if ( - not second.strip() or - second.lstrip().startswith('#') - ): + second = second_indent + source[end_offset:].lstrip() + if not second.strip() or second.lstrip().startswith("#"): continue # Do not begin a line with a comma - if second.lstrip().startswith(','): + if second.lstrip().startswith(","): continue # Do end a line with a dot - if first.rstrip().endswith('.'): + if first.rstrip().endswith("."): continue - if token_string in '+-*/': - fixed = first + ' \\' + '\n' + second + if token_string in "+-*/": + fixed = first + " \\" + "\n" + second else: - fixed = first + '\n' + second + fixed = first + "\n" + second # Only fix if syntax is okay. - if check_syntax(normalize_multiline(fixed) - if aggressive else fixed): + if check_syntax(normalize_multiline(fixed) if aggressive else fixed): yield indentation + fixed def _is_binary_operator(token_type, text): - return ((token_type == tokenize.OP or text in ['and', 'or']) and - text not in '()[]{},:.;@=%~') + return (token_type == tokenize.OP or text in ["and", "or"]) and text not in "()[]{},:.;@=%~" # A convenient way to handle tokens. -Token = collections.namedtuple('Token', ['token_type', 'token_string', - 'spos', 'epos', 'line']) +Token = collections.namedtuple("Token", ["token_type", "token_string", "spos", "epos", "line"]) class ReformattedLines(object): @@ -2036,7 +1856,7 @@ def __init__(self, indent_amt): self._indent_amt = indent_amt def emit(self): - return ' ' * self._indent_amt + return " " * self._indent_amt @property def size(self): @@ -2047,7 +1867,7 @@ class _Space(object): """Represent a space in the atom stream.""" def emit(self): - return ' ' + return " " @property def size(self): @@ -2058,7 +1878,7 @@ class _LineBreak(object): """Represent a line break in the atom stream.""" def emit(self): - return '\n' + return "\n" @property def size(self): @@ -2110,48 +1930,49 @@ def add_line_break_at(self, index, indent_amt): self._lines.insert(index + 1, self._Indent(indent_amt)) def add_space_if_needed(self, curr_text, equal=False): - if ( - not self._lines or isinstance( - self._lines[-1], (self._LineBreak, self._Indent, self._Space)) - ): + if not self._lines or isinstance(self._lines[-1], (self._LineBreak, self._Indent, self._Space)): return prev_text = unicode(self._prev_item) - prev_prev_text = ( - unicode(self._prev_prev_item) if self._prev_prev_item else '') + prev_prev_text = unicode(self._prev_prev_item) if self._prev_prev_item else "" if ( # The previous item was a keyword or identifier and the current # item isn't an operator that doesn't require a space. - ((self._prev_item.is_keyword or self._prev_item.is_string or - self._prev_item.is_name or self._prev_item.is_number) and - (curr_text[0] not in '([{.,:}])' or - (curr_text[0] == '=' and equal))) or - + ( + (self._prev_item.is_keyword or self._prev_item.is_string or self._prev_item.is_name or self._prev_item.is_number) + and (curr_text[0] not in "([{.,:}])" or (curr_text[0] == "=" and equal)) + ) + or # Don't place spaces around a '.', unless it's in an 'import' # statement. - ((prev_prev_text != 'from' and prev_text[-1] != '.' and - curr_text != 'import') and - - # Don't place a space before a colon. - curr_text[0] != ':' and - - # Don't split up ending brackets by spaces. - ((prev_text[-1] in '}])' and curr_text[0] not in '.,}])') or - - # Put a space after a colon or comma. - prev_text[-1] in ':,' or - - # Put space around '=' if asked to. - (equal and prev_text == '=') or - - # Put spaces around non-unary arithmetic operators. - ((self._prev_prev_item and - (prev_text not in '+-' and - (self._prev_prev_item.is_name or - self._prev_prev_item.is_number or - self._prev_prev_item.is_string)) and - prev_text in ('+', '-', '%', '*', '/', '//', '**', 'in'))))) + ( + (prev_prev_text != "from" and prev_text[-1] != "." and curr_text != "import") + and + # Don't place a space before a colon. + curr_text[0] != ":" + and + # Don't split up ending brackets by spaces. + ( + (prev_text[-1] in "}])" and curr_text[0] not in ".,}])") + or + # Put a space after a colon or comma. + prev_text[-1] in ":," + or + # Put space around '=' if asked to. + (equal and prev_text == "=") + or + # Put spaces around non-unary arithmetic operators. + ( + self._prev_prev_item + and ( + prev_text not in "+-" + and (self._prev_prev_item.is_name or self._prev_prev_item.is_number or self._prev_prev_item.is_string) + ) + and prev_text in ("+", "-", "%", "*", "/", "//", "**", "in") + ) + ) + ) ): self._lines.append(self._Space()) @@ -2173,18 +1994,16 @@ def current_size(self): return size def line_empty(self): - return (self._lines and - isinstance(self._lines[-1], - (self._LineBreak, self._Indent))) + return self._lines and isinstance(self._lines[-1], (self._LineBreak, self._Indent)) def emit(self): - string = '' + string = "" for item in self._lines: if isinstance(item, self._LineBreak): string = string.rstrip() string += item.emit() - return string.rstrip() + '\n' + return string.rstrip() + "\n" ########################################################################### # Private Methods @@ -2207,7 +2026,7 @@ def _add_item(self, item, indent_amt): # Adding the item into a container. self._prevent_default_initializer_splitting(item, indent_amt) - if item_text in '.,)]}': + if item_text in ".,)]}": self._split_after_delimiter(item, indent_amt) elif self._lines and not self.line_empty(): @@ -2223,10 +2042,10 @@ def _add_item(self, item, indent_amt): self._lines.append(item) self._prev_item, self._prev_prev_item = item, self._prev_item - if item_text in '([{': + if item_text in "([{": self._bracket_depth += 1 - elif item_text in '}])': + elif item_text in "}])": self._bracket_depth -= 1 assert self._bracket_depth >= 0 @@ -2234,20 +2053,15 @@ def _add_container(self, container, indent_amt, break_after_open_bracket): actual_indent = indent_amt + 1 if ( - unicode(self._prev_item) != '=' and - not self.line_empty() and - not self.fits_on_current_line( - container.size + self._bracket_depth + 2) + unicode(self._prev_item) != "=" + and not self.line_empty() + and not self.fits_on_current_line(container.size + self._bracket_depth + 2) ): - - if unicode(container)[0] == '(' and self._prev_item.is_name: + if unicode(container)[0] == "(" and self._prev_item.is_name: # Don't split before the opening bracket of a call. break_after_open_bracket = True actual_indent = indent_amt + 4 - elif ( - break_after_open_bracket or - unicode(self._prev_item) not in '([{' - ): + elif break_after_open_bracket or unicode(self._prev_item) not in "([{": # If the container doesn't fit on the current line and the # current line isn't empty, place the container on the next # line. @@ -2263,8 +2077,7 @@ def _add_container(self, container, indent_amt, break_after_open_bracket): # Increase the continued indentation only if recursing on a # container. - container.reflow(self, ' ' * actual_indent, - break_after_open_bracket=break_after_open_bracket) + container.reflow(self, " " * actual_indent, break_after_open_bracket=break_after_open_bracket) def _prevent_default_initializer_splitting(self, item, indent_amt): """Prevent splitting between a default initializer. @@ -2277,23 +2090,19 @@ def _prevent_default_initializer_splitting(self, item, indent_amt): break/indent before it if needed. """ - if unicode(item) == '=': + if unicode(item) == "=": # This is the assignment in the initializer. Just remove spaces for # now. self._delete_whitespace() return - if (not self._prev_item or not self._prev_prev_item or - unicode(self._prev_item) != '='): + if not self._prev_item or not self._prev_prev_item or unicode(self._prev_item) != "=": return self._delete_whitespace() prev_prev_index = self._lines.index(self._prev_prev_item) - if ( - isinstance(self._lines[prev_prev_index - 1], self._Indent) or - self.fits_on_current_line(item.size + 1) - ): + if isinstance(self._lines[prev_prev_index - 1], self._Indent) or self.fits_on_current_line(item.size + 1): # The default initializer is already the only item on this line. # Don't insert a newline here. return @@ -2302,8 +2111,7 @@ def _prevent_default_initializer_splitting(self, item, indent_amt): if isinstance(self._lines[prev_prev_index - 1], self._Space): del self._lines[prev_prev_index - 1] - self.add_line_break_at(self._lines.index(self._prev_prev_item), - indent_amt) + self.add_line_break_at(self._lines.index(self._prev_prev_item), indent_amt) def _split_after_delimiter(self, item, indent_amt): """Split the line only after a delimiter.""" @@ -2314,11 +2122,7 @@ def _split_after_delimiter(self, item, indent_amt): last_space = None for current_item in reversed(self._lines): - if ( - last_space and - (not isinstance(current_item, Atom) or - not current_item.is_colon) - ): + if last_space and (not isinstance(current_item, Atom) or not current_item.is_colon): break else: last_space = None @@ -2339,8 +2143,7 @@ def _enforce_space(self, item): wouldn't put one. This just enforces the addition of a space. """ - if isinstance(self._lines[-1], - (self._Space, self._LineBreak, self._Indent)): + if isinstance(self._lines[-1], (self._Space, self._LineBreak, self._Indent)): return if not self._prev_item: @@ -2352,16 +2155,15 @@ def _enforce_space(self, item): # Prefer a space around a '.' in an import statement, and between the # 'import' and '('. if ( - (item_text == '.' and prev_text == 'from') or - (item_text == 'import' and prev_text == '.') or - (item_text == '(' and prev_text == 'import') + (item_text == "." and prev_text == "from") + or (item_text == "import" and prev_text == ".") + or (item_text == "(" and prev_text == "import") ): self._lines.append(self._Space()) def _delete_whitespace(self): """Delete all whitespace from the end of the line.""" - while isinstance(self._lines[-1], (self._Space, self._LineBreak, - self._Indent)): + while isinstance(self._lines[-1], (self._Space, self._LineBreak, self._Indent)): del self._lines[-1] @@ -2379,10 +2181,7 @@ def __len__(self): return self.size def reflow( - self, reflowed_lines, continued_indent, extent, - break_after_open_bracket=False, - is_list_comp_or_if_expr=False, - next_is_dot=False + self, reflowed_lines, continued_indent, extent, break_after_open_bracket=False, is_list_comp_or_if_expr=False, next_is_dot=False ): if self._atom.token_type == tokenize.COMMENT: reflowed_lines.add_comment(self) @@ -2390,20 +2189,18 @@ def reflow( total_size = extent if extent else self.size - if self._atom.token_string not in ',:([{}])': + if self._atom.token_string not in ",:([{}])": # Some atoms will need an extra 1-sized space token after them. total_size += 1 prev_item = reflowed_lines.previous_item() if ( - not is_list_comp_or_if_expr and - not reflowed_lines.fits_on_current_line(total_size) and - not (next_is_dot and - reflowed_lines.fits_on_current_line(self.size + 1)) and - not reflowed_lines.line_empty() and - not self.is_colon and - not (prev_item and prev_item.is_name and - unicode(self) == '(') + not is_list_comp_or_if_expr + and not reflowed_lines.fits_on_current_line(total_size) + and not (next_is_dot and reflowed_lines.fits_on_current_line(self.size + 1)) + and not reflowed_lines.line_empty() + and not self.is_colon + and not (prev_item and prev_item.is_name and unicode(self) == "(") ): # Start a new line if there is already something on the line and # adding this atom would make it go over the max line length. @@ -2411,8 +2208,7 @@ def reflow( else: reflowed_lines.add_space_if_needed(unicode(self)) - reflowed_lines.add(self, len(continued_indent), - break_after_open_bracket) + reflowed_lines.add(self, len(continued_indent), break_after_open_bracket) def emit(self): return self.__repr__() @@ -2435,11 +2231,11 @@ def is_number(self): @property def is_comma(self): - return self._atom.token_string == ',' + return self._atom.token_string == "," @property def is_colon(self): - return self._atom.token_string == ':' + return self._atom.token_string == ":" @property def size(self): @@ -2454,23 +2250,20 @@ def __init__(self, items): self._items = items def __repr__(self): - string = '' + string = "" last_was_keyword = False for item in self._items: if item.is_comma: - string += ', ' + string += ", " elif item.is_colon: - string += ': ' + string += ": " else: item_string = unicode(item) - if ( - string and - (last_was_keyword or - (not string.endswith(tuple('([{,.:}]) ')) and - not item_string.startswith(tuple('([{,.:}])')))) + if string and ( + last_was_keyword or (not string.endswith(tuple("([{,.:}]) ")) and not item_string.startswith(tuple("([{,.:}])"))) ): - string += ' ' + string += " " string += item_string last_was_keyword = item.is_keyword @@ -2483,50 +2276,50 @@ def __iter__(self): def __getitem__(self, idx): return self._items[idx] - def reflow(self, reflowed_lines, continued_indent, - break_after_open_bracket=False): + def reflow(self, reflowed_lines, continued_indent, break_after_open_bracket=False): last_was_container = False - for (index, item) in enumerate(self._items): + for index, item in enumerate(self._items): next_item = get_item(self._items, index + 1) if isinstance(item, Atom): - is_list_comp_or_if_expr = ( - isinstance(self, (ListComprehension, IfExpression))) - item.reflow(reflowed_lines, continued_indent, - self._get_extent(index), - is_list_comp_or_if_expr=is_list_comp_or_if_expr, - next_is_dot=(next_item and - unicode(next_item) == '.')) + is_list_comp_or_if_expr = isinstance(self, (ListComprehension, IfExpression)) + item.reflow( + reflowed_lines, + continued_indent, + self._get_extent(index), + is_list_comp_or_if_expr=is_list_comp_or_if_expr, + next_is_dot=(next_item and unicode(next_item) == "."), + ) if last_was_container and item.is_comma: reflowed_lines.add_line_break(continued_indent) last_was_container = False else: # isinstance(item, Container) - reflowed_lines.add(item, len(continued_indent), - break_after_open_bracket) - last_was_container = not isinstance(item, (ListComprehension, - IfExpression)) + reflowed_lines.add(item, len(continued_indent), break_after_open_bracket) + last_was_container = not isinstance(item, (ListComprehension, IfExpression)) if ( - break_after_open_bracket and index == 0 and + break_after_open_bracket + and index == 0 + and # Prefer to keep empty containers together instead of # separating them. - unicode(item) == self.open_bracket and - (not next_item or unicode(next_item) != self.close_bracket) and - (len(self._items) != 3 or not isinstance(next_item, Atom)) + unicode(item) == self.open_bracket + and (not next_item or unicode(next_item) != self.close_bracket) + and (len(self._items) != 3 or not isinstance(next_item, Atom)) ): reflowed_lines.add_line_break(continued_indent) break_after_open_bracket = False else: next_next_item = get_item(self._items, index + 2) if ( - unicode(item) not in ['.', '%', 'in'] and - next_item and not isinstance(next_item, Container) and - unicode(next_item) != ':' and - next_next_item and (not isinstance(next_next_item, Atom) or - unicode(next_item) == 'not') and - not reflowed_lines.line_empty() and - not reflowed_lines.fits_on_current_line( - self._get_extent(index + 1) + 2) + unicode(item) not in [".", "%", "in"] + and next_item + and not isinstance(next_item, Container) + and unicode(next_item) != ":" + and next_next_item + and (not isinstance(next_next_item, Atom) or unicode(next_item) == "not") + and not reflowed_lines.line_empty() + and not reflowed_lines.fits_on_current_line(self._get_extent(index + 1) + 2) ): reflowed_lines.add_line_break(continued_indent) @@ -2538,7 +2331,7 @@ def _get_extent(self, index): """ extent = 0 prev_item = get_item(self._items, index - 1) - seen_dot = prev_item and unicode(prev_item) == '.' + seen_dot = prev_item and unicode(prev_item) == "." while index < len(self._items): item = get_item(self._items, index) index += 1 @@ -2555,11 +2348,10 @@ def _get_extent(self, index): prev_item = item continue - elif (unicode(item) not in ['.', '=', ':', 'not'] and - not item.is_name and not item.is_string): + elif unicode(item) not in [".", "=", ":", "not"] and not item.is_name and not item.is_string: break - if unicode(item) == '.': + if unicode(item) == ".": seen_dot = True extent += item.size @@ -2606,11 +2398,11 @@ class Tuple(Container): @property def open_bracket(self): - return '(' + return "(" @property def close_bracket(self): - return ')' + return ")" class List(Container): @@ -2619,11 +2411,11 @@ class List(Container): @property def open_bracket(self): - return '[' + return "[" @property def close_bracket(self): - return ']' + return "]" class DictOrSet(Container): @@ -2632,11 +2424,11 @@ class DictOrSet(Container): @property def open_bracket(self): - return '{' + return "{" @property def close_bracket(self): - return '}' + return "}" class ListComprehension(Container): @@ -2669,44 +2461,44 @@ def _parse_container(tokens, index, for_or_if=None): while index < num_tokens: tok = Token(*tokens[index]) - if tok.token_string in ',)]}': + if tok.token_string in ",)]}": # First check if we're at the end of a list comprehension or # if-expression. Don't add the ending token as part of the list # comprehension or if-expression, because they aren't part of those # constructs. - if for_or_if == 'for': + if for_or_if == "for": return (ListComprehension(items), index - 1) - elif for_or_if == 'if': + elif for_or_if == "if": return (IfExpression(items), index - 1) # We've reached the end of a container. items.append(Atom(tok)) # If not, then we are at the end of a container. - if tok.token_string == ')': + if tok.token_string == ")": # The end of a tuple. return (Tuple(items), index) - elif tok.token_string == ']': + elif tok.token_string == "]": # The end of a list. return (List(items), index) - elif tok.token_string == '}': + elif tok.token_string == "}": # The end of a dictionary or set. return (DictOrSet(items), index) - elif tok.token_string in '([{': + elif tok.token_string in "([{": # A sub-container is being defined. (container, index) = _parse_container(tokens, index) items.append(container) - elif tok.token_string == 'for': - (container, index) = _parse_container(tokens, index, 'for') + elif tok.token_string == "for": + (container, index) = _parse_container(tokens, index, "for") items.append(container) - elif tok.token_string == 'if': - (container, index) = _parse_container(tokens, index, 'if') + elif tok.token_string == "if": + (container, index) = _parse_container(tokens, index, "if") items.append(container) else: @@ -2737,7 +2529,7 @@ def _parse_tokens(tokens): # There's only one newline and it's at the end. break - if tok.token_string in '([{': + if tok.token_string in "([{": (container, index) = _parse_container(tokens, index) if not container: return None @@ -2750,20 +2542,19 @@ def _parse_tokens(tokens): return parsed_tokens -def _reflow_lines(parsed_tokens, indentation, max_line_length, - start_on_prefix_line): +def _reflow_lines(parsed_tokens, indentation, max_line_length, start_on_prefix_line): """Reflow the lines so that it looks nice.""" - if unicode(parsed_tokens[0]) == 'def': + if unicode(parsed_tokens[0]) == "def": # A function definition gets indented a bit more. - continued_indent = indentation + ' ' * 2 * DEFAULT_INDENT_SIZE + continued_indent = indentation + " " * 2 * DEFAULT_INDENT_SIZE else: - continued_indent = indentation + ' ' * DEFAULT_INDENT_SIZE + continued_indent = indentation + " " * DEFAULT_INDENT_SIZE break_after_open_bracket = not start_on_prefix_line lines = ReformattedLines(max_line_length) - lines.add_indent(len(indentation.lstrip('\r\n'))) + lines.add_indent(len(indentation.lstrip("\r\n"))) if not start_on_prefix_line: # If splitting after the opening bracket will cause the first element @@ -2772,9 +2563,10 @@ def _reflow_lines(parsed_tokens, indentation, max_line_length, second_token = get_item(parsed_tokens, 1) if ( - first_token and second_token and - unicode(second_token)[0] == '(' and - len(indentation) + len(first_token) + 1 == len(continued_indent) + first_token + and second_token + and unicode(second_token)[0] == "(" + and len(indentation) + len(first_token) + 1 == len(continued_indent) ): return None @@ -2784,7 +2576,7 @@ def _reflow_lines(parsed_tokens, indentation, max_line_length, save_continued_indent = continued_indent if start_on_prefix_line and isinstance(item, Container): start_on_prefix_line = False - continued_indent = ' ' * (lines.current_size() + 1) + continued_indent = " " * (lines.current_size() + 1) item.reflow(lines, continued_indent, break_after_open_bracket) continued_indent = save_continued_indent @@ -2792,8 +2584,7 @@ def _reflow_lines(parsed_tokens, indentation, max_line_length, return lines.emit() -def _shorten_line_at_tokens_new(tokens, source, indentation, - max_line_length): +def _shorten_line_at_tokens_new(tokens, source, indentation, max_line_length): """Shorten the line taking its length into account. The input is expected to be free of newlines except for inside @@ -2809,19 +2600,16 @@ def _shorten_line_at_tokens_new(tokens, source, indentation, if parsed_tokens: # Perform two reflows. The first one starts on the same line as the # prefix. The second starts on the line after the prefix. - fixed = _reflow_lines(parsed_tokens, indentation, max_line_length, - start_on_prefix_line=True) + fixed = _reflow_lines(parsed_tokens, indentation, max_line_length, start_on_prefix_line=True) if fixed and check_syntax(normalize_multiline(fixed.lstrip())): yield fixed - fixed = _reflow_lines(parsed_tokens, indentation, max_line_length, - start_on_prefix_line=False) + fixed = _reflow_lines(parsed_tokens, indentation, max_line_length, start_on_prefix_line=False) if fixed and check_syntax(normalize_multiline(fixed.lstrip())): yield fixed -def _shorten_line_at_tokens(tokens, source, indentation, indent_word, - key_token_strings, aggressive): +def _shorten_line_at_tokens(tokens, source, indentation, indent_word, key_token_strings, aggressive): """Separate line by breaking at tokens in key_token_strings. The input is expected to be free of newlines except for inside @@ -2829,35 +2617,22 @@ def _shorten_line_at_tokens(tokens, source, indentation, indent_word, """ offsets = [] - for (index, _t) in enumerate(token_offsets(tokens)): - (token_type, - token_string, - start_offset, - end_offset) = _t + for index, _t in enumerate(token_offsets(tokens)): + (token_type, token_string, start_offset, end_offset) = _t assert token_type != token.INDENT if token_string in key_token_strings: # Do not break in containers with zero or one items. - unwanted_next_token = { - '(': ')', - '[': ']', - '{': '}'}.get(token_string) + unwanted_next_token = {"(": ")", "[": "]", "{": "}"}.get(token_string) if unwanted_next_token: if ( - get_item(tokens, - index + 1, - default=[None, None])[1] == unwanted_next_token or - get_item(tokens, - index + 2, - default=[None, None])[1] == unwanted_next_token + get_item(tokens, index + 1, default=[None, None])[1] == unwanted_next_token + or get_item(tokens, index + 2, default=[None, None])[1] == unwanted_next_token ): continue - if ( - index > 2 and token_string == '(' and - tokens[index - 1][1] in ',(%[' - ): + if index > 2 and token_string == "(" and tokens[index - 1][1] in ",(%[": # Don't split after a tuple start, or before a tuple start if # the tuple is in a list. continue @@ -2869,19 +2644,16 @@ def _shorten_line_at_tokens(tokens, source, indentation, indent_word, # Break at adjacent strings. These were probably meant to be on # separate lines in the first place. previous_token = get_item(tokens, index - 1) - if ( - token_type == tokenize.STRING and - previous_token and previous_token[0] == tokenize.STRING - ): + if token_type == tokenize.STRING and previous_token and previous_token[0] == tokenize.STRING: offsets.append(start_offset) current_indent = None fixed = None for line in split_at_offsets(source, offsets): if fixed: - fixed += '\n' + current_indent + line + fixed += "\n" + current_indent + line - for symbol in '([{': + for symbol in "([{": if line.endswith(symbol): current_indent += indent_word else: @@ -2892,8 +2664,7 @@ def _shorten_line_at_tokens(tokens, source, indentation, indent_word, assert fixed is not None - if check_syntax(normalize_multiline(fixed) - if aggressive > 1 else fixed): + if check_syntax(normalize_multiline(fixed) if aggressive > 1 else fixed): return indentation + fixed return None @@ -2921,10 +2692,7 @@ def token_offsets(tokens): # Account for the length of the token itself. end_offset += len(token_string) - yield (token_type, - token_string, - start_offset, - end_offset) + yield (token_type, token_string, start_offset, end_offset) previous_end_row = end_row previous_end_column = end_column @@ -2936,16 +2704,16 @@ def normalize_multiline(line): This is for purposes of checking syntax. """ - if line.startswith('def ') and line.rstrip().endswith(':'): - return line + ' pass' - elif line.startswith('return '): - return 'def _(): ' + line - elif line.startswith('@'): - return line + 'def _(): pass' - elif line.startswith('class '): - return line + ' pass' - elif line.startswith(('if ', 'elif ', 'for ', 'while ')): - return line + ' pass' + if line.startswith("def ") and line.rstrip().endswith(":"): + return line + " pass" + elif line.startswith("return "): + return "def _(): " + line + elif line.startswith("@"): + return line + "def _(): pass" + elif line.startswith("class "): + return line + " pass" + elif line.startswith(("if ", "elif ", "for ", "while ")): + return line + " pass" return line @@ -2953,9 +2721,9 @@ def normalize_multiline(line): def fix_whitespace(line, offset, replacement): """Replace whitespace at offset and return fixed line.""" # Replace escaped newlines too - left = line[:offset].rstrip('\n\r \t\\') - right = line[offset:].lstrip('\n\r \t\\') - if right.startswith('#'): + left = line[:offset].rstrip("\n\r \t\\") + right = line[offset:].lstrip("\n\r \t\\") + if right.startswith("#"): return line return left + replacement + right @@ -2974,16 +2742,9 @@ def __init__(self, options): def error(self, line_number, offset, text, check): """Collect errors.""" - code = super(QuietReport, self).error(line_number, - offset, - text, - check) + code = super(QuietReport, self).error(line_number, offset, text, check) if code: - self.__full_error_results.append( - {'id': code, - 'line': line_number, - 'column': offset + 1, - 'info': text}) + self.__full_error_results.append({"id": code, "line": line_number, "column": offset + 1, "info": text}) def full_error_results(self): """Return error results in detail. @@ -2994,8 +2755,7 @@ def full_error_results(self): """ return self.__full_error_results - checker = pycodestyle.Checker('', lines=source, reporter=QuietReport, - **pep8_options) + checker = pycodestyle.Checker("", lines=source, reporter=QuietReport, **pep8_options) checker.check_all() return checker.report.full_error_results() @@ -3003,8 +2763,8 @@ def full_error_results(self): def _remove_leading_and_normalize(line, with_rstrip=True): # ignore FF in first lstrip() if with_rstrip: - return line.lstrip(' \t\v').rstrip(CR + LF) + '\n' - return line.lstrip(' \t\v') + return line.lstrip(" \t\v").rstrip(CR + LF) + "\n" + return line.lstrip(" \t\v") class Reindenter(object): @@ -3032,10 +2792,7 @@ def __init__(self, input_text): else: # Only expand leading tabs. with_rstrip = line_number != len(source_lines) - self.lines.append( - _get_indentation(line).expandtabs() + - _remove_leading_and_normalize(line, with_rstrip) - ) + self.lines.append(_get_indentation(line).expandtabs() + _remove_leading_and_normalize(line, with_rstrip)) self.lines.insert(0, None) self.index = 1 # index into self.lines of next line @@ -3093,9 +2850,7 @@ def run(self, indent_size=DEFAULT_INDENT_SIZE): for j in range(i - 1, -1, -1): jline, jlevel = stats[j] if jlevel >= 0: - want = (have + _leading_space_count( - after[jline - 1]) - - _leading_space_count(lines[jline])) + want = have + _leading_space_count(after[jline - 1]) - _leading_space_count(lines[jline]) break if want < 0: # Still no luck -- leave it alone. @@ -3108,25 +2863,24 @@ def run(self, indent_size=DEFAULT_INDENT_SIZE): if diff == 0 or have == 0: after.extend(lines[thisstmt:nextstmt]) else: - for line_number, line in enumerate(lines[thisstmt:nextstmt], - start=thisstmt): + for line_number, line in enumerate(lines[thisstmt:nextstmt], start=thisstmt): if line_number in self.string_content_line_numbers: after.append(line) elif diff > 0: - if line == '\n': + if line == "\n": after.append(line) else: - after.append(' ' * diff + line) + after.append(" " * diff + line) else: remove = min(_leading_space_count(line), -diff) after.append(line[remove:]) - return ''.join(after) + return "".join(after) def getline(self): """Line-getter for tokenize.""" if self.index >= len(self.lines): - line = '' + line = "" else: line = self.lines[self.index] self.index += 1 @@ -3187,22 +2941,24 @@ def _reindent_stats(tokens): def _leading_space_count(line): """Return number of leading spaces in line.""" i = 0 - while i < len(line) and line[i] == ' ': + while i < len(line) and line[i] == " ": i += 1 return i -def refactor_with_2to3(source_text, fixer_names, filename=''): +def refactor_with_2to3(source_text, fixer_names, filename=""): """Use lib2to3 to refactor the source. Return the refactored source code. """ from lib2to3.refactor import RefactoringTool - fixers = ['lib2to3.fixes.fix_' + name for name in fixer_names] + + fixers = ["lib2to3.fixes.fix_" + name for name in fixer_names] tool = RefactoringTool(fixer_names=fixers, explicit=fixers) from lib2to3.pgen2 import tokenize as lib2to3_tokenize + try: # The name parameter is necessary particularly for the "import" fixer. return unicode(tool.refactor_string(source_text, name=filename)) @@ -3213,7 +2969,7 @@ def refactor_with_2to3(source_text, fixer_names, filename=''): def check_syntax(code): """Return True if syntax is okay.""" try: - return compile(code, '', 'exec', dont_inherit=True) + return compile(code, "", "exec", dont_inherit=True) except (SyntaxError, TypeError, ValueError): return False @@ -3230,10 +2986,8 @@ def find_with_line_numbers(pattern, contents): end = matches[-1].start() # -1 so a failed `rfind` maps to the first line. - newline_offsets = { - -1: 0 - } - for line_num, m in enumerate(re.finditer(r'\n', contents), 1): + newline_offsets = {-1: 0} + for line_num, m in enumerate(re.finditer(r"\n", contents), 1): offset = m.start() if offset > end: break @@ -3245,7 +2999,7 @@ def get_line_num(match, contents): Failing to find the newline is OK, -1 maps to 0 """ - newline_offset = contents.rfind('\n', 0, match.start()) + newline_offset = contents.rfind("\n", 0, match.start()) return newline_offsets[newline_offset] return [get_line_num(match, contents) + 1 for match in matches] @@ -3286,10 +3040,8 @@ def get_disabled_ranges(source): def filter_disabled_results(result, disabled_ranges): - """Filter out reports based on tuple of disabled ranges. - - """ - line = result['line'] + """Filter out reports based on tuple of disabled ranges.""" + line = result["line"] for disabled_range in disabled_ranges: if disabled_range[0] <= line <= disabled_range[1]: return False @@ -3302,10 +3054,8 @@ def filter_results(source, results, aggressive): If aggressive is True, we allow possibly unsafe fixes (E711, E712). """ - non_docstring_string_line_numbers = multiline_string_lines( - source, include_docstrings=False) - all_string_line_numbers = multiline_string_lines( - source, include_docstrings=True) + non_docstring_string_line_numbers = multiline_string_lines(source, include_docstrings=False) + all_string_line_numbers = multiline_string_lines(source, include_docstrings=True) commented_out_code_line_numbers = commented_out_code_lines(source) @@ -3313,54 +3063,56 @@ def filter_results(source, results, aggressive): disabled_ranges = get_disabled_ranges(source) if disabled_ranges: results = [ - result for result in results if filter_disabled_results( + result + for result in results + if filter_disabled_results( result, disabled_ranges, ) ] - has_e901 = any(result['id'].lower() == 'e901' for result in results) + has_e901 = any(result["id"].lower() == "e901" for result in results) for r in results: - issue_id = r['id'].lower() + issue_id = r["id"].lower() - if r['line'] in non_docstring_string_line_numbers: - if issue_id.startswith(('e1', 'e501', 'w191')): + if r["line"] in non_docstring_string_line_numbers: + if issue_id.startswith(("e1", "e501", "w191")): continue - if r['line'] in all_string_line_numbers: - if issue_id in ['e501']: + if r["line"] in all_string_line_numbers: + if issue_id in ["e501"]: continue # We must offset by 1 for lines that contain the trailing contents of # multiline strings. - if not aggressive and (r['line'] + 1) in all_string_line_numbers: + if not aggressive and (r["line"] + 1) in all_string_line_numbers: # Do not modify multiline strings in non-aggressive mode. Remove # trailing whitespace could break doctests. - if issue_id.startswith(('w29', 'w39')): + if issue_id.startswith(("w29", "w39")): continue if aggressive <= 0: - if issue_id.startswith(('e711', 'e72', 'w6')): + if issue_id.startswith(("e711", "e72", "w6")): continue if aggressive <= 1: - if issue_id.startswith(('e712', 'e713', 'e714')): + if issue_id.startswith(("e712", "e713", "e714")): continue if aggressive <= 2: - if issue_id.startswith(('e704')): + if issue_id.startswith(("e704")): continue - if r['line'] in commented_out_code_line_numbers: - if issue_id.startswith(('e26', 'e501')): + if r["line"] in commented_out_code_line_numbers: + if issue_id.startswith(("e26", "e501")): continue # Do not touch indentation if there is a token error caused by # incomplete multi-line statement. Otherwise, we risk screwing up the # indentation. if has_e901: - if issue_id.startswith(('e1', 'e7')): + if issue_id.startswith(("e1", "e7")): continue yield r @@ -3375,7 +3127,7 @@ def multiline_string_lines(source, include_docstrings=False): """ line_numbers = set() - previous_token_type = '' + previous_token_type = "" try: for t in generate_tokens(source): token_type = t[0] @@ -3383,10 +3135,7 @@ def multiline_string_lines(source, include_docstrings=False): end_row = t[3][0] if token_type == tokenize.STRING and start_row != end_row: - if ( - include_docstrings or - previous_token_type != tokenize.INDENT - ): + if include_docstrings or previous_token_type != tokenize.INDENT: # We increment by one since we want the contents of the # string. line_numbers |= set(range(1 + start_row, 1 + end_row)) @@ -3414,22 +3163,18 @@ def commented_out_code_lines(source): line = t[4] # Ignore inline comments. - if not line.lstrip().startswith('#'): + if not line.lstrip().startswith("#"): continue if token_type == tokenize.COMMENT: - stripped_line = token_string.lstrip('#').strip() + stripped_line = token_string.lstrip("#").strip() with warnings.catch_warnings(): # ignore SyntaxWarning in Python3.8+ # refs: # https://bugs.python.org/issue15248 # https://docs.python.org/3.8/whatsnew/3.8.html#other-language-changes warnings.filterwarnings("ignore", category=SyntaxWarning) - if ( - ' ' in stripped_line and - '#' not in stripped_line and - check_syntax(stripped_line) - ): + if " " in stripped_line and "#" not in stripped_line and check_syntax(stripped_line): line_numbers.append(start_row) except (SyntaxError, tokenize.TokenError): pass @@ -3449,27 +3194,25 @@ def shorten_comment(line, max_line_length, last_comment=False): line = line.rstrip() # PEP 8 recommends 72 characters for comment text. - indentation = _get_indentation(line) + '# ' - max_line_length = min(max_line_length, - len(indentation) + 72) + indentation = _get_indentation(line) + "# " + max_line_length = min(max_line_length, len(indentation) + 72) MIN_CHARACTER_REPEAT = 5 - if ( - len(line) - len(line.rstrip(line[-1])) >= MIN_CHARACTER_REPEAT and - not line[-1].isalnum() - ): + if len(line) - len(line.rstrip(line[-1])) >= MIN_CHARACTER_REPEAT and not line[-1].isalnum(): # Trim comments that end with things like --------- - return line[:max_line_length] + '\n' - elif last_comment and re.match(r'\s*#+\s*\w+', line): - split_lines = textwrap.wrap(line.lstrip(' \t#'), - initial_indent=indentation, - subsequent_indent=indentation, - width=max_line_length, - break_long_words=False, - break_on_hyphens=False) - return '\n'.join(split_lines) + '\n' + return line[:max_line_length] + "\n" + elif last_comment and re.match(r"\s*#+\s*\w+", line): + split_lines = textwrap.wrap( + line.lstrip(" \t#"), + initial_indent=indentation, + subsequent_indent=indentation, + width=max_line_length, + break_long_words=False, + break_on_hyphens=False, + ) + return "\n".join(split_lines) + "\n" - return line + '\n' + return line + "\n" def normalize_line_endings(lines, newline): @@ -3477,9 +3220,9 @@ def normalize_line_endings(lines, newline): All lines will be modified to use the most common line ending. """ - line = [line.rstrip('\n\r') + newline for line in lines] - if line and lines[-1] == lines[-1].rstrip('\n\r'): - line[-1] = line[-1].rstrip('\n\r') + line = [line.rstrip("\n\r") + newline for line in lines] + if line and lines[-1] == lines[-1].rstrip("\n\r"): + line[-1] = line[-1].rstrip("\n\r") return line @@ -3522,10 +3265,10 @@ def fix_code(source, options=None, encoding=None, apply_config=False): def _get_options(raw_options, apply_config): """Return parsed options.""" if not raw_options: - return parse_args([''], apply_config=apply_config) + return parse_args([""], apply_config=apply_config) if isinstance(raw_options, dict): - options = parse_args([''], apply_config=apply_config) + options = parse_args([""], apply_config=apply_config) for name, value in raw_options.items(): if not hasattr(options, name): raise ValueError("No such option '{}'".format(name)) @@ -3534,8 +3277,7 @@ def _get_options(raw_options, apply_config): expected_type = type(getattr(options, name)) if not isinstance(expected_type, (str, unicode)): if isinstance(value, (str, unicode)): - raise ValueError( - "Option '{}' should not be a string".format(name)) + raise ValueError("Option '{}' should not be a string".format(name)) setattr(options, name, value) else: options = raw_options @@ -3543,12 +3285,12 @@ def _get_options(raw_options, apply_config): return options -def fix_lines(source_lines, options, filename=''): +def fix_lines(source_lines, options, filename=""): """Return fixed source code.""" # Transform everything to line feed. Then change them back to original # before returning fixed source code. original_newline = find_newline(source_lines) - tmp_source = ''.join(normalize_line_endings(source_lines, '\n')) + tmp_source = "".join(normalize_line_endings(source_lines, "\n")) # Keep a history to break out of cycles. previous_hashes = set() @@ -3558,21 +3300,17 @@ def fix_lines(source_lines, options, filename=''): fixed_source = tmp_source else: pep8_options = { - 'ignore': options.ignore, - 'select': options.select, - 'max_line_length': options.max_line_length, - 'hang_closing': options.hang_closing, + "ignore": options.ignore, + "select": options.select, + "max_line_length": options.max_line_length, + "hang_closing": options.hang_closing, } sio = io.StringIO(tmp_source) contents = sio.readlines() results = _execute_pep8(pep8_options, contents) - codes = {result['id'] for result in results - if result['id'] in SELECTED_GLOBAL_FIXED_METHOD_CODES} + codes = {result["id"] for result in results if result["id"] in SELECTED_GLOBAL_FIXED_METHOD_CODES} # Apply global fixes only once (for efficiency). - fixed_source = apply_global_fixes(tmp_source, - options, - filename=filename, - codes=codes) + fixed_source = apply_global_fixes(tmp_source, options, filename=filename, codes=codes) passes = 0 long_line_ignore_cache = set() @@ -3585,16 +3323,12 @@ def fix_lines(source_lines, options, filename=''): tmp_source = copy.copy(fixed_source) - fix = FixPEP8( - filename, - options, - contents=tmp_source, - long_line_ignore_cache=long_line_ignore_cache) + fix = FixPEP8(filename, options, contents=tmp_source, long_line_ignore_cache=long_line_ignore_cache) fixed_source = fix.fix() sio = io.StringIO(fixed_source) - return ''.join(normalize_line_endings(sio.readlines(), original_newline)) + return "".join(normalize_line_endings(sio.readlines(), original_newline)) def fix_file(filename, options=None, output=None, apply_config=False): @@ -3626,14 +3360,10 @@ def fix_file(filename, options=None, output=None, apply_config=False): elif options.in_place: original = "".join(original_source).splitlines() fixed = fixed_source.splitlines() - original_source_last_line = ( - original_source[-1].split("\n")[-1] if original_source else "" - ) + original_source_last_line = original_source[-1].split("\n")[-1] if original_source else "" fixed_source_last_line = fixed_source.split("\n")[-1] - if original != fixed or ( - original_source_last_line != fixed_source_last_line - ): - with open_with_encoding(filename, 'w', encoding=encoding) as fp: + if original != fixed or (original_source_last_line != fixed_source_last_line): + with open_with_encoding(filename, "w", encoding=encoding) as fp: fp.write(fixed_source) return fixed_source return None @@ -3649,7 +3379,7 @@ def global_fixes(): for function in list(globals().values()): if inspect.isfunction(function): arguments = _get_parameters(function) - if arguments[:1] != ['source']: + if arguments[:1] != ["source"]: continue code = extract_code_from_function(function) @@ -3671,8 +3401,7 @@ def _get_parameters(function): return inspect.getargspec(function)[0] -def apply_global_fixes(source, options, where='global', filename='', - codes=None): +def apply_global_fixes(source, options, where="global", filename="", codes=None): """Run global fixes on source code. These are fixes that only need be done once (unlike those in @@ -3681,40 +3410,36 @@ def apply_global_fixes(source, options, where='global', filename='', """ if codes is None: codes = [] - if any(code_match(code, select=options.select, ignore=options.ignore) - for code in ['E101', 'E111']): - source = reindent(source, - indent_size=options.indent_size) - - for (code, function) in global_fixes(): - if code.upper() in SELECTED_GLOBAL_FIXED_METHOD_CODES \ - and code.upper() not in codes: + if any(code_match(code, select=options.select, ignore=options.ignore) for code in ["E101", "E111"]): + source = reindent(source, indent_size=options.indent_size) + + for code, function in global_fixes(): + if code.upper() in SELECTED_GLOBAL_FIXED_METHOD_CODES and code.upper() not in codes: continue if code_match(code, select=options.select, ignore=options.ignore): if options.verbose: - print('---> Applying {} fix for {}'.format(where, - code.upper()), - file=sys.stderr) - source = function(source, - aggressive=options.aggressive) - - source = fix_2to3(source, - aggressive=options.aggressive, - select=options.select, - ignore=options.ignore, - filename=filename, - where=where, - verbose=options.verbose) + print("---> Applying {} fix for {}".format(where, code.upper()), file=sys.stderr) + source = function(source, aggressive=options.aggressive) + + source = fix_2to3( + source, + aggressive=options.aggressive, + select=options.select, + ignore=options.ignore, + filename=filename, + where=where, + verbose=options.verbose, + ) return source def extract_code_from_function(function): """Return code handled by function.""" - if not function.__name__.startswith('fix_'): + if not function.__name__.startswith("fix_"): return None - code = re.sub('^fix_', '', function.__name__) + code = re.sub("^fix_", "", function.__name__) if not code: return None @@ -3733,73 +3458,74 @@ def _get_package_version(): def create_parser(): """Return command-line parser.""" - parser = argparse.ArgumentParser(description=docstring_summary(__doc__), - prog='autopep8') - parser.add_argument('--version', action='version', - version='%(prog)s {} ({})'.format( - __version__, _get_package_version())) - parser.add_argument('-v', '--verbose', action='count', - default=0, - help='print verbose messages; ' - 'multiple -v result in more verbose messages') - parser.add_argument('-d', '--diff', action='store_true', - help='print the diff for the fixed source') - parser.add_argument('-i', '--in-place', action='store_true', - help='make changes to files in place') - parser.add_argument('--global-config', metavar='filename', - default=DEFAULT_CONFIG, - help='path to a global pep8 config file; if this file ' - 'does not exist then this is ignored ' - '(default: {})'.format(DEFAULT_CONFIG)) - parser.add_argument('--ignore-local-config', action='store_true', - help="don't look for and apply local config files; " - 'if not passed, defaults are updated with any ' - "config files in the project's root directory") - parser.add_argument('-r', '--recursive', action='store_true', - help='run recursively over directories; ' - 'must be used with --in-place or --diff') - parser.add_argument('-j', '--jobs', type=int, metavar='n', default=1, - help='number of parallel jobs; ' - 'match CPU count if value is less than 1') - parser.add_argument('-p', '--pep8-passes', metavar='n', - default=-1, type=int, - help='maximum number of additional pep8 passes ' - '(default: infinite)') - parser.add_argument('-a', '--aggressive', action='count', default=0, - help='enable non-whitespace changes; ' - 'multiple -a result in more aggressive changes') - parser.add_argument('--experimental', action='store_true', - help='enable experimental fixes') - parser.add_argument('--exclude', metavar='globs', - help='exclude file/directory names that match these ' - 'comma-separated globs') - parser.add_argument('--list-fixes', action='store_true', - help='list codes for fixes; ' - 'used by --ignore and --select') - parser.add_argument('--ignore', metavar='errors', default='', - help='do not fix these errors/warnings ' - '(default: {})'.format(DEFAULT_IGNORE)) - parser.add_argument('--select', metavar='errors', default='', - help='fix only these errors/warnings (e.g. E4,W)') - parser.add_argument('--max-line-length', metavar='n', default=79, type=int, - help='set maximum allowed line length ' - '(default: %(default)s)') - parser.add_argument('--line-range', '--range', metavar='line', - default=None, type=int, nargs=2, - help='only fix errors found within this inclusive ' - 'range of line numbers (e.g. 1 99); ' - 'line numbers are indexed at 1') - parser.add_argument('--indent-size', default=DEFAULT_INDENT_SIZE, - type=int, help=argparse.SUPPRESS) - parser.add_argument('--hang-closing', action='store_true', - help='hang-closing option passed to pycodestyle') - parser.add_argument('--exit-code', action='store_true', - help='change to behavior of exit code.' - ' default behavior of return value, 0 is no ' - 'differences, 1 is error exit. return 2 when' - ' add this option. 2 is exists differences.') - parser.add_argument('files', nargs='*', - help="files to format or '-' for standard in") + parser = argparse.ArgumentParser(description=docstring_summary(__doc__), prog="autopep8") + parser.add_argument("--version", action="version", version="%(prog)s {} ({})".format(__version__, _get_package_version())) + parser.add_argument( + "-v", "--verbose", action="count", default=0, help="print verbose messages; " "multiple -v result in more verbose messages" + ) + parser.add_argument("-d", "--diff", action="store_true", help="print the diff for the fixed source") + parser.add_argument("-i", "--in-place", action="store_true", help="make changes to files in place") + parser.add_argument( + "--global-config", + metavar="filename", + default=DEFAULT_CONFIG, + help="path to a global pep8 config file; if this file " "does not exist then this is ignored " "(default: {})".format( + DEFAULT_CONFIG + ), + ) + parser.add_argument( + "--ignore-local-config", + action="store_true", + help="don't look for and apply local config files; " + "if not passed, defaults are updated with any " + "config files in the project's root directory", + ) + parser.add_argument( + "-r", "--recursive", action="store_true", help="run recursively over directories; " "must be used with --in-place or --diff" + ) + parser.add_argument( + "-j", "--jobs", type=int, metavar="n", default=1, help="number of parallel jobs; " "match CPU count if value is less than 1" + ) + parser.add_argument( + "-p", "--pep8-passes", metavar="n", default=-1, type=int, help="maximum number of additional pep8 passes " "(default: infinite)" + ) + parser.add_argument( + "-a", + "--aggressive", + action="count", + default=0, + help="enable non-whitespace changes; " "multiple -a result in more aggressive changes", + ) + parser.add_argument("--experimental", action="store_true", help="enable experimental fixes") + parser.add_argument("--exclude", metavar="globs", help="exclude file/directory names that match these " "comma-separated globs") + parser.add_argument("--list-fixes", action="store_true", help="list codes for fixes; " "used by --ignore and --select") + parser.add_argument( + "--ignore", metavar="errors", default="", help="do not fix these errors/warnings " "(default: {})".format(DEFAULT_IGNORE) + ) + parser.add_argument("--select", metavar="errors", default="", help="fix only these errors/warnings (e.g. E4,W)") + parser.add_argument( + "--max-line-length", metavar="n", default=79, type=int, help="set maximum allowed line length " "(default: %(default)s)" + ) + parser.add_argument( + "--line-range", + "--range", + metavar="line", + default=None, + type=int, + nargs=2, + help="only fix errors found within this inclusive " "range of line numbers (e.g. 1 99); " "line numbers are indexed at 1", + ) + parser.add_argument("--indent-size", default=DEFAULT_INDENT_SIZE, type=int, help=argparse.SUPPRESS) + parser.add_argument("--hang-closing", action="store_true", help="hang-closing option passed to pycodestyle") + parser.add_argument( + "--exit-code", + action="store_true", + help="change to behavior of exit code." + " default behavior of return value, 0 is no " + "differences, 1 is error exit. return 2 when" + " add this option. 2 is exists differences.", + ) + parser.add_argument("files", nargs="*", help="files to format or '-' for standard in") return parser @@ -3809,13 +3535,7 @@ def _expand_codes(codes, ignore_codes): ret = set() is_conflict = False - if all( - any( - conflicting_code.startswith(code) - for code in codes - ) - for conflicting_code in CONFLICTING_CODES - ): + if all(any(conflicting_code.startswith(code) for code in codes) for conflicting_code in CONFLICTING_CODES): is_conflict = True is_ignore_w503 = "W503" in ignore_codes @@ -3848,7 +3568,7 @@ def parse_args(arguments, apply_config=False): args = parser.parse_args(arguments) if not args.files and not args.list_fixes: - parser.exit(EXIT_CODE_ARGPARSE_ERROR, 'incorrect number of arguments') + parser.exit(EXIT_CODE_ARGPARSE_ERROR, "incorrect number of arguments") args.files = [decode_filename(name) for name in args.files] @@ -3864,82 +3584,72 @@ def parse_args(arguments, apply_config=False): args = parser.parse_args(arguments) args.files = [decode_filename(name) for name in args.files] - if '-' in args.files: + if "-" in args.files: if len(args.files) > 1: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - 'cannot mix stdin and regular files', + "cannot mix stdin and regular files", ) if args.diff: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - '--diff cannot be used with standard input', + "--diff cannot be used with standard input", ) if args.in_place: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - '--in-place cannot be used with standard input', + "--in-place cannot be used with standard input", ) if args.recursive: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - '--recursive cannot be used with standard input', + "--recursive cannot be used with standard input", ) if len(args.files) > 1 and not (args.in_place or args.diff): parser.exit( EXIT_CODE_ARGPARSE_ERROR, - 'autopep8 only takes one filename as argument ' - 'unless the "--in-place" or "--diff" args are used', + "autopep8 only takes one filename as argument " 'unless the "--in-place" or "--diff" args are used', ) if args.recursive and not (args.in_place or args.diff): parser.exit( EXIT_CODE_ARGPARSE_ERROR, - '--recursive must be used with --in-place or --diff', + "--recursive must be used with --in-place or --diff", ) if args.in_place and args.diff: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - '--in-place and --diff are mutually exclusive', + "--in-place and --diff are mutually exclusive", ) if args.max_line_length <= 0: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - '--max-line-length must be greater than 0', + "--max-line-length must be greater than 0", ) if args.indent_size <= 0: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - '--indent-size must be greater than 0', + "--indent-size must be greater than 0", ) if args.select: - args.select = _expand_codes( - _split_comma_separated(args.select), - (_split_comma_separated(args.ignore) if args.ignore else []) - ) + args.select = _expand_codes(_split_comma_separated(args.select), (_split_comma_separated(args.ignore) if args.ignore else [])) if args.ignore: args.ignore = _split_comma_separated(args.ignore) - if all( - not any( - conflicting_code.startswith(ignore_code) - for ignore_code in args.ignore - ) - for conflicting_code in CONFLICTING_CODES - ): + if all(not any(conflicting_code.startswith(ignore_code) for ignore_code in args.ignore) for conflicting_code in CONFLICTING_CODES): args.ignore.update(CONFLICTING_CODES) elif not args.select: if args.aggressive: # Enable everything by default if aggressive. - args.select = {'E', 'W1', 'W2', 'W3', 'W6'} + args.select = {"E", "W1", "W2", "W3", "W6"} else: args.ignore = _split_comma_separated(DEFAULT_IGNORE) @@ -3952,33 +3662,33 @@ def parse_args(arguments, apply_config=False): # Do not import multiprocessing globally in case it is not supported # on the platform. import multiprocessing + args.jobs = multiprocessing.cpu_count() if args.jobs > 1 and not (args.in_place or args.diff): parser.exit( EXIT_CODE_ARGPARSE_ERROR, - 'parallel jobs requires --in-place', + "parallel jobs requires --in-place", ) if args.line_range: if args.line_range[0] <= 0: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - '--range must be positive numbers', + "--range must be positive numbers", ) if args.line_range[0] > args.line_range[1]: parser.exit( EXIT_CODE_ARGPARSE_ERROR, - 'First value of --range should be less than or equal ' - 'to the second', + "First value of --range should be less than or equal " "to the second", ) return args def _get_normalize_options(config, section, option_list): - for (k, _) in config.items(section): - norm_opt = k.lstrip('-').replace('-', '_') + for k, _ in config.items(section): + norm_opt = k.lstrip("-").replace("-", "_") if not option_list.get(norm_opt): continue opt_type = option_list[norm_opt] @@ -4001,36 +3711,27 @@ def read_config(args, parser): config.read(args.global_config) if not args.ignore_local_config: - parent = tail = args.files and os.path.abspath( - os.path.commonprefix(args.files)) + parent = tail = args.files and os.path.abspath(os.path.commonprefix(args.files)) while tail: - if config.read([os.path.join(parent, fn) - for fn in PROJECT_CONFIG]): + if config.read([os.path.join(parent, fn) for fn in PROJECT_CONFIG]): if args.verbose: for fn in PROJECT_CONFIG: config_file = os.path.join(parent, fn) if not os.path.exists(config_file): continue - print( - "read config path: {}".format( - os.path.join(parent, fn) - ) - ) + print("read config path: {}".format(os.path.join(parent, fn))) break (parent, tail) = os.path.split(parent) defaults = {} - option_list = {o.dest: o.type or type(o.default) - for o in parser._actions} + option_list = {o.dest: o.type or type(o.default) for o in parser._actions} - for section in ['pep8', 'pycodestyle', 'flake8']: + for section in ["pep8", "pycodestyle", "flake8"]: if not config.has_section(section): continue - for norm_opt, k, value in _get_normalize_options(config, section, - option_list): + for norm_opt, k, value in _get_normalize_options(config, section, option_list): if args.verbose: - print("enable config: section={}, key={}, value={}".format( - section, k, value)) + print("enable config: section={}, key={}, value={}".format(section, k, value)) defaults[norm_opt] = value parser.set_defaults(**defaults) @@ -4052,8 +3753,7 @@ def read_pyproject_toml(args, parser): config = toml.load(fp) if not args.ignore_local_config: - parent = tail = args.files and os.path.abspath( - os.path.commonprefix(args.files)) + parent = tail = args.files and os.path.abspath(os.path.commonprefix(args.files)) while tail: pyproject_toml = os.path.join(parent, "pyproject.toml") if os.path.exists(pyproject_toml): @@ -4071,12 +3771,11 @@ def read_pyproject_toml(args, parser): config = config.get("tool").get("autopep8") defaults = {} - option_list = {o.dest: o.type or type(o.default) - for o in parser._actions} + option_list = {o.dest: o.type or type(o.default) for o in parser._actions} TUPLED_OPTIONS = ("ignore", "select") - for (k, v) in config.items(): - norm_opt = k.lstrip('-').replace('-', '_') + for k, v in config.items(): + norm_opt = k.lstrip("-").replace("-", "_") if not option_list.get(norm_opt): continue if type(v) in (list, tuple) and norm_opt in TUPLED_OPTIONS: @@ -4084,8 +3783,7 @@ def read_pyproject_toml(args, parser): else: value = v if args.verbose: - print("enable pyproject.toml config: " - "key={}, value={}".format(k, value)) + print("enable pyproject.toml config: " "key={}, value={}".format(k, value)) defaults[norm_opt] = value if defaults: @@ -4097,7 +3795,7 @@ def read_pyproject_toml(args, parser): def _split_comma_separated(string): """Return a set of strings.""" - return {text.strip() for text in string.split(',') if text.strip()} + return {text.strip() for text in string.split(",") if text.strip()} def decode_filename(filename): @@ -4115,34 +3813,27 @@ def supported_fixes(): description. """ - yield ('E101', docstring_summary(reindent.__doc__)) + yield ("E101", docstring_summary(reindent.__doc__)) - instance = FixPEP8(filename=None, options=None, contents='') + instance = FixPEP8(filename=None, options=None, contents="") for attribute in dir(instance): - code = re.match('fix_([ew][0-9][0-9][0-9])', attribute) + code = re.match("fix_([ew][0-9][0-9][0-9])", attribute) if code: - yield ( - code.group(1).upper(), - re.sub(r'\s+', ' ', - docstring_summary(getattr(instance, attribute).__doc__)) - ) + yield (code.group(1).upper(), re.sub(r"\s+", " ", docstring_summary(getattr(instance, attribute).__doc__))) - for (code, function) in sorted(global_fixes()): - yield (code.upper() + (4 - len(code)) * ' ', - re.sub(r'\s+', ' ', docstring_summary(function.__doc__))) + for code, function in sorted(global_fixes()): + yield (code.upper() + (4 - len(code)) * " ", re.sub(r"\s+", " ", docstring_summary(function.__doc__))) for code in sorted(CODE_TO_2TO3): - yield (code.upper() + (4 - len(code)) * ' ', - re.sub(r'\s+', ' ', docstring_summary(fix_2to3.__doc__))) + yield (code.upper() + (4 - len(code)) * " ", re.sub(r"\s+", " ", docstring_summary(fix_2to3.__doc__))) def docstring_summary(docstring): """Return summary of docstring.""" - return docstring.split('\n')[0] if docstring else '' + return docstring.split("\n")[0] if docstring else "" -def line_shortening_rank(candidate, indent_word, max_line_length, - experimental=False): +def line_shortening_rank(candidate, indent_word, max_line_length, experimental=False): """Return rank of candidate. This is for sorting candidates. @@ -4152,14 +3843,11 @@ def line_shortening_rank(candidate, indent_word, max_line_length, return 0 rank = 0 - lines = candidate.rstrip().split('\n') + lines = candidate.rstrip().split("\n") offset = 0 - if ( - not lines[0].lstrip().startswith('#') and - lines[0].rstrip()[-1] not in '([{' - ): - for (opening, closing) in ('()', '[]', '{}'): + if not lines[0].lstrip().startswith("#") and lines[0].rstrip()[-1] not in "([{": + for opening, closing in ("()", "[]", "{}"): # Don't penalize empty containers that aren't split up. Things like # this "foo(\n )" aren't particularly good. opening_loc = lines[0].find(opening) @@ -4177,25 +3865,19 @@ def line_shortening_rank(candidate, indent_word, max_line_length, # Too much variation in line length is ugly. rank += 2 * standard_deviation(len(line) for line in lines) - bad_staring_symbol = { - '(': ')', - '[': ']', - '{': '}'}.get(lines[0][-1]) + bad_staring_symbol = {"(": ")", "[": "]", "{": "}"}.get(lines[0][-1]) if len(lines) > 1: - if ( - bad_staring_symbol and - lines[1].lstrip().startswith(bad_staring_symbol) - ): + if bad_staring_symbol and lines[1].lstrip().startswith(bad_staring_symbol): rank += 20 for lineno, current_line in enumerate(lines): current_line = current_line.strip() - if current_line.startswith('#'): + if current_line.startswith("#"): continue - for bad_start in ['.', '%', '+', '-', '/']: + for bad_start in [".", "%", "+", "-", "/"]: if current_line.startswith(bad_start): rank += 100 @@ -4203,54 +3885,44 @@ def line_shortening_rank(candidate, indent_word, max_line_length, if current_line == bad_start: rank += 1000 - if ( - current_line.endswith(('.', '%', '+', '-', '/')) and - "': " in current_line - ): + if current_line.endswith((".", "%", "+", "-", "/")) and "': " in current_line: rank += 1000 - if current_line.endswith(('(', '[', '{', '.')): + if current_line.endswith(("(", "[", "{", ".")): # Avoid lonely opening. They result in longer lines. if len(current_line) <= len(indent_word): rank += 100 # Avoid the ugliness of ", (\n". - if ( - current_line.endswith('(') and - current_line[:-1].rstrip().endswith(',') - ): + if current_line.endswith("(") and current_line[:-1].rstrip().endswith(","): rank += 100 # Avoid the ugliness of "something[\n" and something[index][\n. - if ( - current_line.endswith('[') and - len(current_line) > 1 and - (current_line[-2].isalnum() or current_line[-2] in ']') - ): + if current_line.endswith("[") and len(current_line) > 1 and (current_line[-2].isalnum() or current_line[-2] in "]"): rank += 300 # Also avoid the ugliness of "foo.\nbar" - if current_line.endswith('.'): + if current_line.endswith("."): rank += 100 if has_arithmetic_operator(current_line): rank += 100 # Avoid breaking at unary operators. - if re.match(r'.*[(\[{]\s*[\-\+~]$', current_line.rstrip('\\ ')): + if re.match(r".*[(\[{]\s*[\-\+~]$", current_line.rstrip("\\ ")): rank += 1000 - if re.match(r'.*lambda\s*\*$', current_line.rstrip('\\ ')): + if re.match(r".*lambda\s*\*$", current_line.rstrip("\\ ")): rank += 1000 - if current_line.endswith(('%', '(', '[', '{')): + if current_line.endswith(("%", "(", "[", "{")): rank -= 20 # Try to break list comprehensions at the "for". - if current_line.startswith('for '): + if current_line.startswith("for "): rank -= 50 - if current_line.endswith('\\'): + if current_line.endswith("\\"): # If a line ends in \-newline, it may be part of a # multiline string. In that case, we would like to know # how long that line is without the \-newline. If it's @@ -4262,11 +3934,11 @@ def line_shortening_rank(candidate, indent_word, max_line_length, while lineno < len(lines): total_len += len(lines[lineno]) - if lines[lineno].lstrip().startswith('#'): + if lines[lineno].lstrip().startswith("#"): total_len = max_line_length break - if not lines[lineno].endswith('\\'): + if not lines[lineno].endswith("\\"): break lineno += 1 @@ -4277,11 +3949,11 @@ def line_shortening_rank(candidate, indent_word, max_line_length, rank += 100 if experimental else 1 # Prefer breaking at commas rather than colon. - if ',' in current_line and current_line.endswith(':'): + if "," in current_line and current_line.endswith(":"): rank += 10 # Avoid splitting dictionaries between key and value. - if current_line.endswith(':'): + if current_line.endswith(":"): rank += 100 rank += 10 * count_unbalanced_brackets(current_line) @@ -4295,8 +3967,7 @@ def standard_deviation(numbers): if not numbers: return 0 mean = sum(numbers) / len(numbers) - return (sum((n - mean) ** 2 for n in numbers) / - len(numbers)) ** .5 + return (sum((n - mean) ** 2 for n in numbers) / len(numbers)) ** 0.5 def has_arithmetic_operator(line): @@ -4311,7 +3982,7 @@ def has_arithmetic_operator(line): def count_unbalanced_brackets(line): """Return number of unmatched open/close brackets.""" count = 0 - for opening, closing in ['()', '[]', '{}']: + for opening, closing in ["()", "[]", "{}"]: count += abs(line.count(opening) - line.count(closing)) return count @@ -4350,7 +4021,7 @@ def __init__(self, output): self.__output = output def write(self, s): - self.__output.write(s.replace('\r\n', '\n').replace('\r', '\n')) + self.__output.write(s.replace("\r\n", "\n").replace("\r", "\n")) def flush(self): self.__output.flush() @@ -4360,7 +4031,7 @@ def match_file(filename, exclude): """Return True if file is okay for modifying/recursing.""" base_name = os.path.basename(filename) - if base_name.startswith('.'): + if base_name.startswith("."): return False for pattern in exclude: @@ -4381,12 +4052,8 @@ def find_files(filenames, recursive, exclude): name = filenames.pop(0) if recursive and os.path.isdir(name): for root, directories, children in os.walk(name): - filenames += [os.path.join(root, f) for f in children - if match_file(os.path.join(root, f), - exclude)] - directories[:] = [d for d in directories - if match_file(os.path.join(root, d), - exclude)] + filenames += [os.path.join(root, f) for f in children if match_file(os.path.join(root, f), exclude)] + directories[:] = [d for d in directories if match_file(os.path.join(root, d), exclude)] else: is_exclude_match = False for pattern in exclude: @@ -4400,7 +4067,7 @@ def find_files(filenames, recursive, exclude): def _fix_file(parameters): """Helper function for optionally running fix_file() in parallel.""" if parameters[1].verbose: - print('[file:{}]'.format(parameters[0]), file=sys.stderr) + print("[file:{}]".format(parameters[0]), file=sys.stderr) try: return fix_file(*parameters) except IOError as error: @@ -4418,6 +4085,7 @@ def fix_multiple_files(filenames, options, output=None): filenames = find_files(filenames, options.recursive, options.exclude) if options.jobs > 1: import multiprocessing + pool = multiprocessing.Pool(options.jobs) rets = [] for name in filenames: @@ -4436,7 +4104,7 @@ def fix_multiple_files(filenames, options, output=None): if ret is None: continue if options.diff: - if ret != '': + if ret != "": results.append(ret) elif options.in_place: results.append(ret) @@ -4449,13 +4117,11 @@ def fix_multiple_files(filenames, options, output=None): def is_python_file(filename): """Return True if filename is Python file.""" - if filename.endswith('.py'): + if filename.endswith(".py"): return True try: - with open_with_encoding( - filename, - limit_byte_check=MAX_PYTHON_FILE_DETECTION_BYTES) as f: + with open_with_encoding(filename, limit_byte_check=MAX_PYTHON_FILE_DETECTION_BYTES) as f: text = f.read(MAX_PYTHON_FILE_DETECTION_BYTES) if not text: return False @@ -4476,18 +4142,12 @@ def is_probably_part_of_multiline(line): at the start of the multiline string, which doesn't work for us. """ - return ( - '"""' in line or - "'''" in line or - line.rstrip().endswith('\\') - ) + return '"""' in line or "'''" in line or line.rstrip().endswith("\\") def wrap_output(output, encoding): """Return output with specified encoding.""" - return codecs.getwriter(encoding)(output.buffer - if hasattr(output, 'buffer') - else output) + return codecs.getwriter(encoding)(output.buffer if hasattr(output, "buffer") else output) def get_encoding(): @@ -4512,11 +4172,10 @@ def main(argv=None, apply_config=True): if args.list_fixes: for code, description in sorted(supported_fixes()): - print('{code} - {description}'.format( - code=code, description=description)) + print("{code} - {description}".format(code=code, description=description)) return EXIT_CODE_OK - if args.files == ['-']: + if args.files == ["-"]: assert not args.in_place encoding = sys.stdin.encoding or get_encoding() @@ -4567,9 +4226,7 @@ def generate_tokens(self, text): """A stand-in for tokenize.generate_tokens().""" if text != self.last_text: string_io = io.StringIO(text) - self.last_tokens = list( - tokenize.generate_tokens(string_io.readline) - ) + self.last_tokens = list(tokenize.generate_tokens(string_io.readline)) self.last_text = text return self.last_tokens @@ -4577,5 +4234,5 @@ def generate_tokens(self, text): _cached_tokenizer = CachedTokenizer() generate_tokens = _cached_tokenizer.generate_tokens -if __name__ == '__main__': +if __name__ == "__main__": sys.exit(main()) diff --git a/third_party/pep8/pycodestyle.py b/third_party/pep8/pycodestyle.py index a4b11fe63..97a1f9a38 100644 --- a/third_party/pep8/pycodestyle.py +++ b/third_party/pep8/pycodestyle.py @@ -66,79 +66,86 @@ except ImportError: from ConfigParser import RawConfigParser -__version__ = '2.3.1' +__version__ = "2.3.1" -DEFAULT_EXCLUDE = '.svn,CVS,.bzr,.hg,.git,__pycache__,.tox' -DEFAULT_IGNORE = 'E121,E123,E126,E226,E24,E704,W503' +DEFAULT_EXCLUDE = ".svn,CVS,.bzr,.hg,.git,__pycache__,.tox" +DEFAULT_IGNORE = "E121,E123,E126,E226,E24,E704,W503" try: - if sys.platform == 'win32': - USER_CONFIG = os.path.expanduser(r'~\.pycodestyle') + if sys.platform == "win32": + USER_CONFIG = os.path.expanduser(r"~\.pycodestyle") else: - USER_CONFIG = os.path.join( - os.getenv('XDG_CONFIG_HOME') or os.path.expanduser('~/.config'), - 'pycodestyle' - ) + USER_CONFIG = os.path.join(os.getenv("XDG_CONFIG_HOME") or os.path.expanduser("~/.config"), "pycodestyle") except ImportError: USER_CONFIG = None -PROJECT_CONFIG = ('setup.cfg', 'tox.ini') -TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), 'testsuite') +PROJECT_CONFIG = ("setup.cfg", "tox.ini") +TESTSUITE_PATH = os.path.join(os.path.dirname(__file__), "testsuite") MAX_LINE_LENGTH = 79 REPORT_FORMAT = { - 'default': '%(path)s:%(row)d:%(col)d: %(code)s %(text)s', - 'pylint': '%(path)s:%(row)d: [%(code)s] %(text)s', + "default": "%(path)s:%(row)d:%(col)d: %(code)s %(text)s", + "pylint": "%(path)s:%(row)d: [%(code)s] %(text)s", } PyCF_ONLY_AST = 1024 -SINGLETONS = frozenset(['False', 'None', 'True']) -KEYWORDS = frozenset(keyword.kwlist + ['print']) - SINGLETONS -UNARY_OPERATORS = frozenset(['>>', '**', '*', '+', '-']) -ARITHMETIC_OP = frozenset(['**', '*', '/', '//', '+', '-']) -WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(['^', '&', '|', '<<', '>>', '%']) -WS_NEEDED_OPERATORS = frozenset([ - '**=', '*=', '/=', '//=', '+=', '-=', '!=', '<>', '<', '>', - '%=', '^=', '&=', '|=', '==', '<=', '>=', '<<=', '>>=', '=']) -WHITESPACE = frozenset(' \t') +SINGLETONS = frozenset(["False", "None", "True"]) +KEYWORDS = frozenset(keyword.kwlist + ["print"]) - SINGLETONS +UNARY_OPERATORS = frozenset([">>", "**", "*", "+", "-"]) +ARITHMETIC_OP = frozenset(["**", "*", "/", "//", "+", "-"]) +WS_OPTIONAL_OPERATORS = ARITHMETIC_OP.union(["^", "&", "|", "<<", ">>", "%"]) +WS_NEEDED_OPERATORS = frozenset( + ["**=", "*=", "/=", "//=", "+=", "-=", "!=", "<>", "<", ">", "%=", "^=", "&=", "|=", "==", "<=", ">=", "<<=", ">>=", "="] +) +WHITESPACE = frozenset(" \t") NEWLINE = frozenset([tokenize.NL, tokenize.NEWLINE]) SKIP_TOKENS = NEWLINE.union([tokenize.INDENT, tokenize.DEDENT]) # ERRORTOKEN is triggered by backticks in Python 3 SKIP_COMMENTS = SKIP_TOKENS.union([tokenize.COMMENT, tokenize.ERRORTOKEN]) -BENCHMARK_KEYS = ['directories', 'files', 'logical lines', 'physical lines'] +BENCHMARK_KEYS = ["directories", "files", "logical lines", "physical lines"] -INDENT_REGEX = re.compile(r'([ \t]*)') -RAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,') -RERAISE_COMMA_REGEX = re.compile(r'raise\s+\w+\s*,.*,\s*\w+\s*$') -ERRORCODE_REGEX = re.compile(r'\b[A-Z]\d{3}\b') +INDENT_REGEX = re.compile(r"([ \t]*)") +RAISE_COMMA_REGEX = re.compile(r"raise\s+\w+\s*,") +RERAISE_COMMA_REGEX = re.compile(r"raise\s+\w+\s*,.*,\s*\w+\s*$") +ERRORCODE_REGEX = re.compile(r"\b[A-Z]\d{3}\b") DOCSTRING_REGEX = re.compile(r'u?r?["\']') -EXTRANEOUS_WHITESPACE_REGEX = re.compile(r'[[({] | []}),;:]') -WHITESPACE_AFTER_COMMA_REGEX = re.compile(r'[,;:]\s*(?: |\t)') -COMPARE_SINGLETON_REGEX = re.compile(r'(\bNone|\bFalse|\bTrue)?\s*([=!]=)' - r'\s*(?(1)|(None|False|True))\b') -COMPARE_NEGATIVE_REGEX = re.compile(r'\b(not)\s+[^][)(}{ ]+\s+(in|is)\s') -COMPARE_TYPE_REGEX = re.compile(r'(?:[=!]=|is(?:\s+not)?)\s*type(?:s.\w+Type' - r'|\s*\(\s*([^)]*[^ )])\s*\))') -KEYWORD_REGEX = re.compile(r'(\s*)\b(?:%s)\b(\s*)' % r'|'.join(KEYWORDS)) -OPERATOR_REGEX = re.compile(r'(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)') -LAMBDA_REGEX = re.compile(r'\blambda\b') -HUNK_REGEX = re.compile(r'^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$') -STARTSWITH_DEF_REGEX = re.compile(r'^(async\s+def|def)') -STARTSWITH_TOP_LEVEL_REGEX = re.compile(r'^(async\s+def\s+|def\s+|class\s+|@)') +EXTRANEOUS_WHITESPACE_REGEX = re.compile(r"[[({] | []}),;:]") +WHITESPACE_AFTER_COMMA_REGEX = re.compile(r"[,;:]\s*(?: |\t)") +COMPARE_SINGLETON_REGEX = re.compile(r"(\bNone|\bFalse|\bTrue)?\s*([=!]=)" r"\s*(?(1)|(None|False|True))\b") +COMPARE_NEGATIVE_REGEX = re.compile(r"\b(not)\s+[^][)(}{ ]+\s+(in|is)\s") +COMPARE_TYPE_REGEX = re.compile(r"(?:[=!]=|is(?:\s+not)?)\s*type(?:s.\w+Type" r"|\s*\(\s*([^)]*[^ )])\s*\))") +KEYWORD_REGEX = re.compile(r"(\s*)\b(?:%s)\b(\s*)" % r"|".join(KEYWORDS)) +OPERATOR_REGEX = re.compile(r"(?:[^,\s])(\s*)(?:[-+*/|!<=>%&^]+)(\s*)") +LAMBDA_REGEX = re.compile(r"\blambda\b") +HUNK_REGEX = re.compile(r"^@@ -\d+(?:,\d+)? \+(\d+)(?:,(\d+))? @@.*$") +STARTSWITH_DEF_REGEX = re.compile(r"^(async\s+def|def)") +STARTSWITH_TOP_LEVEL_REGEX = re.compile(r"^(async\s+def\s+|def\s+|class\s+|@)") STARTSWITH_INDENT_STATEMENT_REGEX = re.compile( - r'^\s*({0})'.format('|'.join(s.replace(' ', '\s+') for s in ( - 'def', 'async def', - 'for', 'async for', - 'if', 'elif', 'else', - 'try', 'except', 'finally', - 'with', 'async with', - 'class', - 'while', - ))) + r"^\s*({0})".format( + "|".join( + s.replace(" ", "\s+") + for s in ( + "def", + "async def", + "for", + "async for", + "if", + "elif", + "else", + "try", + "except", + "finally", + "with", + "async with", + "class", + "while", + ) + ) + ) ) -DUNDER_REGEX = re.compile(r'^__([^\s]+)__ = ') +DUNDER_REGEX = re.compile(r"^__([^\s]+)__ = ") # Work around Python < 2.6 behaviour, which does not generate NL after # a comment which is on a line by itself. -COMMENT_WITH_NL = tokenize.generate_tokens(['#\n'].pop).send(None)[1] == '#\n' +COMMENT_WITH_NL = tokenize.generate_tokens(["#\n"].pop).send(None)[1] == "#\n" ############################################################################## @@ -172,8 +179,8 @@ def tabs_obsolete(physical_line): W191: if True:\n\treturn """ indent = INDENT_REGEX.match(physical_line).group(1) - if '\t' in indent: - return indent.index('\t'), "W191 indentation contains tabs" + if "\t" in indent: + return indent.index("\t"), "W191 indentation contains tabs" def trailing_whitespace(physical_line): @@ -186,10 +193,10 @@ def trailing_whitespace(physical_line): W291: spam(1) \n# W293: class Foo(object):\n \n bang = 12 """ - physical_line = physical_line.rstrip('\n') # chr(10), newline - physical_line = physical_line.rstrip('\r') # chr(13), carriage return - physical_line = physical_line.rstrip('\x0c') # chr(12), form feed, ^L - stripped = physical_line.rstrip(' \t\v') + physical_line = physical_line.rstrip("\n") # chr(10), newline + physical_line = physical_line.rstrip("\r") # chr(13), carriage return + physical_line = physical_line.rstrip("\x0c") # chr(12), form feed, ^L + stripped = physical_line.rstrip(" \t\v") if physical_line != stripped: if stripped: return len(stripped), "W291 trailing whitespace" @@ -231,19 +238,18 @@ def maximum_line_length(physical_line, max_line_length, multiline, noqa): # Special case for long URLs in multi-line docstrings or comments, # but still report the error when the 72 first chars are whitespaces. chunks = line.split() - if ((len(chunks) == 1 and multiline) or - (len(chunks) == 2 and chunks[0] == '#')) and \ - len(line) - len(chunks[-1]) < max_line_length - 7: + if ((len(chunks) == 1 and multiline) or (len(chunks) == 2 and chunks[0] == "#")) and len(line) - len( + chunks[-1] + ) < max_line_length - 7: return - if hasattr(line, 'decode'): # Python 2 + if hasattr(line, "decode"): # Python 2 # The line could contain multi-byte characters try: - length = len(line.decode('utf-8')) + length = len(line.decode("utf-8")) except UnicodeError: pass if length > max_line_length: - return (max_line_length, "E501 line too long " - "(%d > %d characters)" % (length, max_line_length)) + return (max_line_length, "E501 line too long " "(%d > %d characters)" % (length, max_line_length)) ############################################################################## @@ -251,10 +257,17 @@ def maximum_line_length(physical_line, max_line_length, multiline, noqa): ############################################################################## -def blank_lines(logical_line, blank_lines, indent_level, line_number, - blank_before, previous_logical, - previous_unindented_logical_line, previous_indent_level, - lines): +def blank_lines( + logical_line, + blank_lines, + indent_level, + line_number, + blank_before, + previous_logical, + previous_unindented_logical_line, + previous_indent_level, + lines, +): r"""Separate top-level function and class definitions with two blank lines. Method definitions inside a class are separated by a single blank line. @@ -282,35 +295,31 @@ def blank_lines(logical_line, blank_lines, indent_level, line_number, """ if line_number < 3 and not previous_logical: return # Don't expect blank lines before the first line - if previous_logical.startswith('@'): + if previous_logical.startswith("@"): if blank_lines: yield 0, "E304 blank lines found after function decorator" elif blank_lines > 2 or (indent_level and blank_lines == 2): yield 0, "E303 too many blank lines (%d)" % blank_lines elif STARTSWITH_TOP_LEVEL_REGEX.match(logical_line): if indent_level: - if not (blank_before or previous_indent_level < indent_level or - DOCSTRING_REGEX.match(previous_logical)): + if not (blank_before or previous_indent_level < indent_level or DOCSTRING_REGEX.match(previous_logical)): ancestor_level = indent_level nested = False # Search backwards for a def ancestor or tree root (top level). - for line in lines[line_number - 2::-1]: + for line in lines[line_number - 2 :: -1]: if line.strip() and expand_indent(line) < ancestor_level: ancestor_level = expand_indent(line) - nested = line.lstrip().startswith('def ') + nested = line.lstrip().startswith("def ") if nested or ancestor_level == 0: break if nested: - yield 0, "E306 expected 1 blank line before a " \ - "nested definition, found 0" + yield 0, "E306 expected 1 blank line before a " "nested definition, found 0" else: yield 0, "E301 expected 1 blank line, found 0" elif blank_before != 2: yield 0, "E302 expected 2 blank lines, found %d" % blank_before - elif (logical_line and not indent_level and blank_before != 2 and - previous_unindented_logical_line.startswith(('def ', 'class '))): - yield 0, "E305 expected 2 blank lines after " \ - "class or function definition, found %d" % blank_before + elif logical_line and not indent_level and blank_before != 2 and previous_unindented_logical_line.startswith(("def ", "class ")): + yield 0, "E305 expected 2 blank lines after " "class or function definition, found %d" % blank_before def extraneous_whitespace(logical_line): @@ -337,11 +346,11 @@ def extraneous_whitespace(logical_line): text = match.group() char = text.strip() found = match.start() - if text == char + ' ': + if text == char + " ": # assert char in '([{' yield found + 1, "E201 whitespace after '%s'" % char - elif line[found - 1] != ',': - code = ('E202' if char in '}])' else 'E203') # if char in ',;:' + elif line[found - 1] != ",": + code = "E202" if char in "}])" else "E203" # if char in ',;:' yield found, "%s whitespace before '%s'" % (code, char) @@ -357,12 +366,12 @@ def whitespace_around_keywords(logical_line): for match in KEYWORD_REGEX.finditer(logical_line): before, after = match.groups() - if '\t' in before: + if "\t" in before: yield match.start(1), "E274 tab before keyword" elif len(before) > 1: yield match.start(1), "E272 multiple spaces before keyword" - if '\t' in after: + if "\t" in after: yield match.start(2), "E273 tab after keyword" elif len(after) > 1: yield match.start(2), "E271 multiple spaces after keyword" @@ -377,8 +386,8 @@ def missing_whitespace_after_import_keyword(logical_line): E275: from importable.module import(bar, baz) """ line = logical_line - indicator = ' import(' - if line.startswith('from '): + indicator = " import(" + if line.startswith("from "): found = line.find(indicator) if -1 < found: pos = found + len(indicator) - 1 @@ -401,18 +410,16 @@ def missing_whitespace(logical_line): line = logical_line for index in range(len(line) - 1): char = line[index] - if char in ',;:' and line[index + 1] not in WHITESPACE: + if char in ",;:" and line[index + 1] not in WHITESPACE: before = line[:index] - if char == ':' and before.count('[') > before.count(']') and \ - before.rfind('{') < before.rfind('['): + if char == ":" and before.count("[") > before.count("]") and before.rfind("{") < before.rfind("["): continue # Slice syntax, no space required - if char == ',' and line[index + 1] == ')': + if char == "," and line[index + 1] == ")": continue # Allow tuple with only one element: (3,) yield index, "E231 missing whitespace after '%s'" % char -def indentation(logical_line, previous_logical, indent_char, - indent_level, previous_indent_level): +def indentation(logical_line, previous_logical, indent_char, indent_level, previous_indent_level): r"""Use 4 spaces per indentation level. For really old code that you don't want to mess up, you can continue to @@ -435,15 +442,14 @@ def indentation(logical_line, previous_logical, indent_char, tmpl = "E11%d %s" if logical_line else "E11%d %s (comment)" if indent_level % 4: yield 0, tmpl % (1 + c, "indentation is not a multiple of four") - indent_expect = previous_logical.endswith(':') + indent_expect = previous_logical.endswith(":") if indent_expect and indent_level <= previous_indent_level: yield 0, tmpl % (2 + c, "expected an indented block") elif not indent_expect and indent_level > previous_indent_level: yield 0, tmpl % (3 + c, "unexpected indentation") -def continued_indentation(logical_line, tokens, indent_level, hang_closing, - indent_char, noqa, verbose): +def continued_indentation(logical_line, tokens, indent_level, hang_closing, indent_char, noqa, verbose): r"""Continuation lines indentation. Continuation lines should align wrapped elements either vertically @@ -479,10 +485,10 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, # that it is indented by 4 spaces, then we should not allow 4-space # indents on the final continuation line; in turn, some other # indents are allowed to have an extra 4 spaces. - indent_next = logical_line.endswith(':') + indent_next = logical_line.endswith(":") row = depth = 0 - valid_hangs = (4,) if indent_char != '\t' else (4, 8) + valid_hangs = (4,) if indent_char != "\t" else (4, 8) # remember how many brackets were opened on each line parens = [0] * nrows # relative indents of physical lines @@ -502,7 +508,6 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, print(">>> " + tokens[0][4].rstrip()) for token_type, text, start, end, line in tokens: - newline = row < start[0] - first_row if newline: row = start[0] - first_row @@ -518,7 +523,7 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, rel_indent[row] = expand_indent(line) - indent_level # identify closing bracket - close_bracket = (token_type == tokenize.OP and text in ']})') + close_bracket = token_type == tokenize.OP and text in "]})" # is the indent relative to an opening bracket line? for open_row in reversed(open_rows[depth]): @@ -527,16 +532,14 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, if hanging_indent: break if hangs[depth]: - hanging_indent = (hang == hangs[depth]) + hanging_indent = hang == hangs[depth] # is there any chance of visual indent? - visual_indent = (not close_bracket and hang > 0 and - indent_chances.get(start[1])) + visual_indent = not close_bracket and hang > 0 and indent_chances.get(start[1]) if close_bracket and indent[depth]: # closing bracket for visual indent if start[1] != indent[depth]: - yield (start, "E124 closing bracket does not match " - "visual indentation") + yield (start, "E124 closing bracket does not match " "visual indentation") elif close_bracket and not hang: # closing bracket matches indentation of opening bracket's line if hang_closing: @@ -544,13 +547,11 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, elif indent[depth] and start[1] < indent[depth]: if visual_indent is not True: # visual indent is broken - yield (start, "E128 continuation line " - "under-indented for visual indent") + yield (start, "E128 continuation line " "under-indented for visual indent") elif hanging_indent or (indent_next and rel_indent[row] == 8): # hanging indent is verified if close_bracket and not hang_closing: - yield (start, "E123 closing bracket does not match " - "indentation of opening bracket's line") + yield (start, "E123 closing bracket does not match " "indentation of opening bracket's line") hangs[depth] = hang elif visual_indent is True: # visual indent is verified @@ -575,26 +576,23 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, yield start, "%s continuation line %s" % error # look for visual indenting - if (parens[row] and - token_type not in (tokenize.NL, tokenize.COMMENT) and - not indent[depth]): + if parens[row] and token_type not in (tokenize.NL, tokenize.COMMENT) and not indent[depth]: indent[depth] = start[1] indent_chances[start[1]] = True if verbose >= 4: print("bracket depth %s indent to %s" % (depth, start[1])) # deal with implicit string concatenation - elif (token_type in (tokenize.STRING, tokenize.COMMENT) or - text in ('u', 'ur', 'b', 'br')): + elif token_type in (tokenize.STRING, tokenize.COMMENT) or text in ("u", "ur", "b", "br"): indent_chances[start[1]] = str # special case for the "if" statement because len("if (") == 4 - elif not indent_chances and not row and not depth and text == 'if': + elif not indent_chances and not row and not depth and text == "if": indent_chances[end[1] + 1] = True - elif text == ':' and line[end[1]:].isspace(): + elif text == ":" and line[end[1] :].isspace(): open_rows[depth].append(row) # keep track of bracket depth if token_type == tokenize.OP: - if text in '([{': + if text in "([{": depth += 1 indent.append(0) hangs.append(None) @@ -603,9 +601,8 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, open_rows[depth].append(row) parens[row] += 1 if verbose >= 4: - print("bracket depth %s seen, col %s, visual min = %s" % - (depth, start[1], indent[depth])) - elif text in ')]}' and depth > 0: + print("bracket depth %s seen, col %s, visual min = %s" % (depth, start[1], indent[depth])) + elif text in ")]}" and depth > 0: # parent indents should not be more than this one prev_indent = indent.pop() or last_indent[1] hangs.pop() @@ -615,7 +612,7 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, for ind in list(indent_chances): if ind >= prev_indent: del indent_chances[ind] - del open_rows[depth + 1:] + del open_rows[depth + 1 :] depth -= 1 if depth: indent_chances[indent[depth]] = True @@ -628,7 +625,7 @@ def continued_indentation(logical_line, tokens, indent_level, hang_closing, # allow lining up tokens indent_chances[start[1]] = text - last_token_multiline = (start[0] != end[0]) + last_token_multiline = start[0] != end[0] if last_token_multiline: rel_indent[end[0] - first_row] = rel_indent[row] @@ -659,14 +656,18 @@ def whitespace_before_parameters(logical_line, tokens): prev_type, prev_text, __, prev_end, __ = tokens[0] for index in range(1, len(tokens)): token_type, text, start, end, __ = tokens[index] - if (token_type == tokenize.OP and - text in '([' and - start != prev_end and - (prev_type == tokenize.NAME or prev_text in '}])') and + if ( + token_type == tokenize.OP + and text in "([" + and start != prev_end + and (prev_type == tokenize.NAME or prev_text in "}])") + and # Syntax "class A (B):" is allowed, but avoid it - (index < 2 or tokens[index - 2][1] != 'class') and - # Allow "return (a.foo for a in range(5))" - not keyword.iskeyword(prev_text)): + (index < 2 or tokens[index - 2][1] != "class") + and + # Allow "return (a.foo for a in range(5))" + not keyword.iskeyword(prev_text) + ): yield prev_end, "E211 whitespace before '%s'" % text prev_type = token_type prev_text = text @@ -685,12 +686,12 @@ def whitespace_around_operator(logical_line): for match in OPERATOR_REGEX.finditer(logical_line): before, after = match.groups() - if '\t' in before: + if "\t" in before: yield match.start(1), "E223 tab before operator" elif len(before) > 1: yield match.start(1), "E221 multiple spaces before operator" - if '\t' in after: + if "\t" in after: yield match.start(2), "E224 tab after operator" elif len(after) > 1: yield match.start(2), "E222 multiple spaces after operator" @@ -731,18 +732,17 @@ def missing_whitespace_around_operator(logical_line, tokens): for token_type, text, start, end, line in tokens: if token_type in SKIP_COMMENTS: continue - if text in ('(', 'lambda'): + if text in ("(", "lambda"): parens += 1 - elif text == ')': + elif text == ")": parens -= 1 if need_space: if start != prev_end: # Found a (probably) needed space if need_space is not True and not need_space[1]: - yield (need_space[0], - "E225 missing whitespace around operator") + yield (need_space[0], "E225 missing whitespace around operator") need_space = False - elif text == '>' and prev_text in ('<', '-'): + elif text == ">" and prev_text in ("<", "-"): # Tolerate the "<>" operator, even if running Python 3 # Deal with Python 3's annotated return value "->" pass @@ -750,17 +750,16 @@ def missing_whitespace_around_operator(logical_line, tokens): if need_space is True or need_space[1]: # A needed trailing space was not found yield prev_end, "E225 missing whitespace around operator" - elif prev_text != '**': - code, optype = 'E226', 'arithmetic' - if prev_text == '%': - code, optype = 'E228', 'modulo' + elif prev_text != "**": + code, optype = "E226", "arithmetic" + if prev_text == "%": + code, optype = "E228", "modulo" elif prev_text not in ARITHMETIC_OP: - code, optype = 'E227', 'bitwise or shift' - yield (need_space[0], "%s missing whitespace " - "around %s operator" % (code, optype)) + code, optype = "E227", "bitwise or shift" + yield (need_space[0], "%s missing whitespace " "around %s operator" % (code, optype)) need_space = False elif token_type == tokenize.OP and prev_end is not None: - if text == '=' and parens: + if text == "=" and parens: # Allow keyword args or defaults: foo(bar=None). pass elif text in WS_NEEDED_OPERATORS: @@ -769,8 +768,7 @@ def missing_whitespace_around_operator(logical_line, tokens): # Check if the operator is being used as a binary operator # Allow unary operators: -123, -x, +1. # Allow argument unpacking: foo(*args, **kwargs). - if (prev_text in '}])' if prev_type == tokenize.OP - else prev_text not in KEYWORDS): + if prev_text in "}])" if prev_type == tokenize.OP else prev_text not in KEYWORDS: need_space = None elif text in WS_OPTIONAL_OPERATORS: need_space = None @@ -800,7 +798,7 @@ def whitespace_around_comma(logical_line): line = logical_line for m in WHITESPACE_AFTER_COMMA_REGEX.finditer(line): found = m.start() + 1 - if '\t' in m.group(): + if "\t" in m.group(): yield found, "E242 tab after '%s'" % m.group()[0] else: yield found, "E241 multiple spaces after '%s'" % m.group()[0] @@ -838,15 +836,15 @@ def whitespace_around_named_parameter_equals(logical_line, tokens): if start != prev_end: yield (prev_end, message) if token_type == tokenize.OP: - if text in '([': + if text in "([": parens += 1 - elif text in ')]': + elif text in ")]": parens -= 1 - elif in_def and text == ':' and parens == 1: + elif in_def and text == ":" and parens == 1: annotated_func_arg = True - elif parens and text == ',' and parens == 1: + elif parens and text == "," and parens == 1: annotated_func_arg = False - elif parens and text == '=' and not annotated_func_arg: + elif parens and text == "=" and not annotated_func_arg: no_space = True if start != prev_end: yield (prev_end, message) @@ -878,18 +876,17 @@ def whitespace_before_comment(logical_line, tokens): prev_end = (0, 0) for token_type, text, start, end, line in tokens: if token_type == tokenize.COMMENT: - inline_comment = line[:start[1]].strip() + inline_comment = line[: start[1]].strip() if inline_comment: if prev_end[0] == start[0] and start[1] < prev_end[1] + 2: - yield (prev_end, - "E261 at least two spaces before inline comment") - symbol, sp, comment = text.partition(' ') - bad_prefix = symbol not in '#:' and (symbol.lstrip('#')[:1] or '#') + yield (prev_end, "E261 at least two spaces before inline comment") + symbol, sp, comment = text.partition(" ") + bad_prefix = symbol not in "#:" and (symbol.lstrip("#")[:1] or "#") if inline_comment: if bad_prefix or comment[:1] in WHITESPACE: yield start, "E262 inline comment should start with '# '" - elif bad_prefix and (bad_prefix != '!' or start[0] > 1): - if bad_prefix != '#': + elif bad_prefix and (bad_prefix != "!" or start[0] > 1): + if bad_prefix != "#": yield start, "E265 block comment should start with '# '" elif comment: yield start, "E266 too many leading '#' for block comment" @@ -910,14 +907,13 @@ def imports_on_separate_lines(logical_line): Okay: import foo.bar.yourclass """ line = logical_line - if line.startswith('import '): - found = line.find(',') - if -1 < found and ';' not in line[:found]: + if line.startswith("import "): + found = line.find(",") + if -1 < found and ";" not in line[:found]: yield found, "E401 multiple imports on one line" -def module_imports_on_top_of_file( - logical_line, indent_level, checker_state, noqa): +def module_imports_on_top_of_file(logical_line, indent_level, checker_state, noqa): r"""Place imports at the top of the file. Always put imports at the top of the file, just after any module comments @@ -937,14 +933,15 @@ def module_imports_on_top_of_file( Okay: if x:\n import os """ + def is_string_literal(line): - if line[0] in 'uUbB': + if line[0] in "uUbB": line = line[1:] - if line and line[0] in 'rR': + if line and line[0] in "rR": line = line[1:] return line and (line[0] == '"' or line[0] == "'") - allowed_try_keywords = ('try', 'except', 'else', 'finally') + allowed_try_keywords = ("try", "except", "else", "finally") if indent_level: # Allow imports in conditional statements or functions return @@ -953,8 +950,8 @@ def is_string_literal(line): if noqa: return line = logical_line - if line.startswith('import ') or line.startswith('from '): - if checker_state.get('seen_non_imports', False): + if line.startswith("import ") or line.startswith("from "): + if checker_state.get("seen_non_imports", False): yield 0, "E402 module level import not at top of file" elif re.match(DUNDER_REGEX, line): return @@ -964,12 +961,12 @@ def is_string_literal(line): return elif is_string_literal(line): # The first literal is a docstring, allow it. Otherwise, report error. - if checker_state.get('seen_docstring', False): - checker_state['seen_non_imports'] = True + if checker_state.get("seen_docstring", False): + checker_state["seen_non_imports"] = True else: - checker_state['seen_docstring'] = True + checker_state["seen_docstring"] = True else: - checker_state['seen_non_imports'] = True + checker_state["seen_non_imports"] = True def compound_statements(logical_line): @@ -1002,34 +999,35 @@ def compound_statements(logical_line): """ line = logical_line last_char = len(line) - 1 - found = line.find(':') + found = line.find(":") prev_found = 0 - counts = dict((char, 0) for char in '{}[]()') + counts = dict((char, 0) for char in "{}[]()") while -1 < found < last_char: update_counts(line[prev_found:found], counts) - if ((counts['{'] <= counts['}'] and # {'a': 1} (dict) - counts['['] <= counts[']'] and # [1:2] (slice) - counts['('] <= counts[')'])): # (annotation) + if ( + counts["{"] <= counts["}"] # {'a': 1} (dict) + and counts["["] <= counts["]"] # [1:2] (slice) + and counts["("] <= counts[")"] + ): # (annotation) lambda_kw = LAMBDA_REGEX.search(line, 0, found) if lambda_kw: - before = line[:lambda_kw.start()].rstrip() - if before[-1:] == '=' and isidentifier(before[:-1].strip()): - yield 0, ("E731 do not assign a lambda expression, use a " - "def") + before = line[: lambda_kw.start()].rstrip() + if before[-1:] == "=" and isidentifier(before[:-1].strip()): + yield 0, ("E731 do not assign a lambda expression, use a " "def") break if STARTSWITH_DEF_REGEX.match(line): yield 0, "E704 multiple statements on one line (def)" elif STARTSWITH_INDENT_STATEMENT_REGEX.match(line): yield found, "E701 multiple statements on one line (colon)" prev_found = found - found = line.find(':', found + 1) - found = line.find(';') + found = line.find(":", found + 1) + found = line.find(";") while -1 < found: if found < last_char: yield found, "E702 multiple statements on one line (semicolon)" else: yield found, "E703 statement ends with a semicolon" - found = line.find(';', found + 1) + found = line.find(";", found + 1) def explicit_line_join(logical_line, tokens): @@ -1057,7 +1055,7 @@ def explicit_line_join(logical_line, tokens): if start[0] != prev_start and parens and backslash and not comment: yield backslash, "E502 the backslash is redundant between brackets" if end[0] != prev_end: - if line.rstrip('\r\n').endswith('\\'): + if line.rstrip("\r\n").endswith("\\"): backslash = (end[0], len(line.splitlines()[-1]) - 1) else: backslash = None @@ -1065,9 +1063,9 @@ def explicit_line_join(logical_line, tokens): else: prev_start = start[0] if token_type == tokenize.OP: - if text in '([{': + if text in "([{": parens += 1 - elif text in ')]}': + elif text in ")]}": parens -= 1 @@ -1091,12 +1089,12 @@ def break_around_binary_operator(logical_line, tokens): Okay: var = (1 /\n -2) Okay: var = (1 +\n -1 +\n -2) """ + def is_binary_operator(token_type, text): # The % character is strictly speaking a binary operator, but the # common usage seems to be to put it next to the format parameters, # after a line break. - return ((token_type == tokenize.OP or text in ['and', 'or']) and - text not in "()[]{},:.;@=%~") + return (token_type == tokenize.OP or text in ["and", "or"]) and text not in "()[]{},:.;@=%~" line_break = False unary_context = True @@ -1106,15 +1104,17 @@ def is_binary_operator(token_type, text): for token_type, text, start, end, line in tokens: if token_type == tokenize.COMMENT: continue - if ('\n' in text or '\r' in text) and token_type != tokenize.STRING: + if ("\n" in text or "\r" in text) and token_type != tokenize.STRING: line_break = True else: - if (is_binary_operator(token_type, text) and line_break and - not unary_context and - not is_binary_operator(previous_token_type, - previous_text)): + if ( + is_binary_operator(token_type, text) + and line_break + and not unary_context + and not is_binary_operator(previous_token_type, previous_text) + ): yield start, "W503 line break before binary operator" - unary_context = text in '([{,;' + unary_context = text in "([{,;" line_break = False previous_token_type = token_type previous_text = text @@ -1140,18 +1140,16 @@ def comparison_to_singleton(logical_line, noqa): match = not noqa and COMPARE_SINGLETON_REGEX.search(logical_line) if match: singleton = match.group(1) or match.group(3) - same = (match.group(2) == '==') + same = match.group(2) == "==" - msg = "'if cond is %s:'" % (('' if same else 'not ') + singleton) - if singleton in ('None',): - code = 'E711' + msg = "'if cond is %s:'" % (("" if same else "not ") + singleton) + if singleton in ("None",): + code = "E711" else: - code = 'E712' - nonzero = ((singleton == 'True' and same) or - (singleton == 'False' and not same)) - msg += " or 'if %scond:'" % ('' if nonzero else 'not ') - yield match.start(2), ("%s comparison to %s should be %s" % - (code, singleton, msg)) + code = "E712" + nonzero = (singleton == "True" and same) or (singleton == "False" and not same) + msg += " or 'if %scond:'" % ("" if nonzero else "not ") + yield match.start(2), ("%s comparison to %s should be %s" % (code, singleton, msg)) def comparison_negative(logical_line): @@ -1169,7 +1167,7 @@ def comparison_negative(logical_line): match = COMPARE_NEGATIVE_REGEX.search(logical_line) if match: pos = match.start(1) - if match.group(2) == 'in': + if match.group(2) == "in": yield pos, "E713 test for membership should be 'not in'" else: yield pos, "E714 test for object identity should be 'is not'" @@ -1240,24 +1238,24 @@ def ambiguous_identifier(logical_line, tokens): E742: class I(object): E743: def l(x): """ - idents_to_avoid = ('l', 'O', 'I') + idents_to_avoid = ("l", "O", "I") prev_type, prev_text, prev_start, prev_end, __ = tokens[0] for token_type, text, start, end, line in tokens[1:]: ident = pos = None # identifiers on the lhs of an assignment operator - if token_type == tokenize.OP and '=' in text: + if token_type == tokenize.OP and "=" in text: if prev_text in idents_to_avoid: ident = prev_text pos = prev_start # identifiers bound to a value with 'as', 'global', or 'nonlocal' - if prev_text in ('as', 'global', 'nonlocal'): + if prev_text in ("as", "global", "nonlocal"): if text in idents_to_avoid: ident = text pos = start - if prev_text == 'class': + if prev_text == "class": if text in idents_to_avoid: yield start, "E742 ambiguous class definition '%s'" % text - if prev_text == 'def': + if prev_text == "def": if text in idents_to_avoid: yield start, "E743 ambiguous function definition '%s'" % text if ident: @@ -1272,7 +1270,7 @@ def python_3000_has_key(logical_line, noqa): Okay: if "alph" in d:\n print d["alph"] W601: assert d.has_key('alph') """ - pos = logical_line.find('.has_key(') + pos = logical_line.find(".has_key(") if pos > -1 and not noqa: yield pos, "W601 .has_key() is deprecated, use 'in'" @@ -1298,7 +1296,7 @@ def python_3000_not_equal(logical_line): Okay: if a != 'no': W603: if a <> 'no': """ - pos = logical_line.find('<>') + pos = logical_line.find("<>") if pos > -1: yield pos, "W603 '<>' is deprecated, use '!='" @@ -1309,7 +1307,7 @@ def python_3000_backticks(logical_line): Okay: val = repr(1 + 2) W604: val = `1 + 2` """ - pos = logical_line.find('`') + pos = logical_line.find("`") if pos > -1: yield pos, "W604 backticks are deprecated, use 'repr()'" @@ -1323,28 +1321,30 @@ def python_3000_backticks(logical_line): # Python 2: implicit encoding. def readlines(filename): """Read the source code.""" - with open(filename, 'rU') as f: + with open(filename, "rU") as f: return f.readlines() - isidentifier = re.compile(r'[a-zA-Z_]\w*$').match + + isidentifier = re.compile(r"[a-zA-Z_]\w*$").match stdin_get_value = sys.stdin.read else: # Python 3 def readlines(filename): """Read the source code.""" try: - with open(filename, 'rb') as f: + with open(filename, "rb") as f: (coding, lines) = tokenize.detect_encoding(f.readline) f = TextIOWrapper(f, coding, line_buffering=True) return [line.decode(coding) for line in lines] + f.readlines() except (LookupError, SyntaxError, UnicodeError): # Fall back if file encoding is improperly declared - with open(filename, encoding='latin-1') as f: + with open(filename, encoding="latin-1") as f: return f.readlines() + isidentifier = str.isidentifier stdin_get_value = sys.stdin.read -noqa = re.compile(r'# no(?:qa|pep8)\b', re.I).search +noqa = re.compile(r"# no(?:qa|pep8)\b", re.I).search def expand_indent(line): @@ -1361,13 +1361,13 @@ def expand_indent(line): >>> expand_indent(' \t') 16 """ - if '\t' not in line: + if "\t" not in line: return len(line) - len(line.lstrip()) result = 0 for char in line: - if char == '\t': + if char == "\t": result = result // 8 * 8 + 8 - elif char == ' ': + elif char == " ": result += 1 else: break @@ -1391,10 +1391,10 @@ def mute_string(text): if text[-3:] in ('"""', "'''"): start += 2 end -= 2 - return text[:start] + 'x' * (end - start) + text[end:] + return text[:start] + "x" * (end - start) + text[end:] -def parse_udiff(diff, patterns=None, parent='.'): +def parse_udiff(diff, patterns=None, parent="."): """Return a dictionary of matching lines.""" # For each file of the diff, the entry key is the filename, # and the value is a set of row numbers to consider. @@ -1402,21 +1402,19 @@ def parse_udiff(diff, patterns=None, parent='.'): path = nrows = None for line in diff.splitlines(): if nrows: - if line[:1] != '-': + if line[:1] != "-": nrows -= 1 continue - if line[:3] == '@@ ': + if line[:3] == "@@ ": hunk_match = HUNK_REGEX.match(line) - (row, nrows) = [int(g or '1') for g in hunk_match.groups()] + (row, nrows) = [int(g or "1") for g in hunk_match.groups()] rv[path].update(range(row, row + nrows)) - elif line[:3] == '+++': - path = line[4:].split('\t', 1)[0] - if path[:2] == 'b/': + elif line[:3] == "+++": + path = line[4:].split("\t", 1)[0] + if path[:2] == "b/": path = path[2:] rv[path] = set() - return dict([(os.path.join(parent, path), rows) - for (path, rows) in rv.items() - if rows and filename_match(path, patterns)]) + return dict([(os.path.join(parent, path), rows) for (path, rows) in rv.items() if rows and filename_match(path, patterns)]) def normalize_paths(value, parent=os.curdir): @@ -1429,11 +1427,11 @@ def normalize_paths(value, parent=os.curdir): if isinstance(value, list): return value paths = [] - for path in value.split(','): + for path in value.split(","): path = path.strip() - if '/' in path: + if "/" in path: path = os.path.abspath(os.path.join(parent, path)) - paths.append(path.rstrip('/')) + paths.append(path.rstrip("/")) return paths @@ -1449,55 +1447,58 @@ def filename_match(filename, patterns, default=True): def update_counts(s, counts): r"""Adds one to the counts of each appearance of characters in s, - for characters in counts""" + for characters in counts""" for char in s: if char in counts: counts[char] += 1 def _is_eol_token(token): - return token[0] in NEWLINE or token[4][token[3][1]:].lstrip() == '\\\n' + return token[0] in NEWLINE or token[4][token[3][1] :].lstrip() == "\\\n" if COMMENT_WITH_NL: + def _is_eol_token(token, _eol_token=_is_eol_token): - return _eol_token(token) or (token[0] == tokenize.COMMENT and - token[1] == token[4]) + return _eol_token(token) or (token[0] == tokenize.COMMENT and token[1] == token[4]) ############################################################################## # Framework to run all checks ############################################################################## -_checks = {'physical_line': {}, 'logical_line': {}, 'tree': {}} +_checks = {"physical_line": {}, "logical_line": {}, "tree": {}} def _get_parameters(function): if sys.version_info >= (3, 3): - return [parameter.name - for parameter - in inspect.signature(function).parameters.values() - if parameter.kind == parameter.POSITIONAL_OR_KEYWORD] + return [ + parameter.name + for parameter in inspect.signature(function).parameters.values() + if parameter.kind == parameter.POSITIONAL_OR_KEYWORD + ] else: return inspect.getargspec(function)[0] def register_check(check, codes=None): """Register a new check object.""" + def _add_check(check, kind, codes, args): if check in _checks[kind]: _checks[kind][check][0].extend(codes or []) else: - _checks[kind][check] = (codes or [''], args) + _checks[kind][check] = (codes or [""], args) + if inspect.isfunction(check): args = _get_parameters(check) - if args and args[0] in ('physical_line', 'logical_line'): + if args and args[0] in ("physical_line", "logical_line"): if codes is None: - codes = ERRORCODE_REGEX.findall(check.__doc__ or '') + codes = ERRORCODE_REGEX.findall(check.__doc__ or "") _add_check(check, args[0], codes, args) elif inspect.isclass(check): - if _get_parameters(check.__init__)[:2] == ['self', 'tree']: - _add_check(check, 'tree', codes, None) + if _get_parameters(check.__init__)[:2] == ["self", "tree"]: + _add_check(check, "tree", codes, None) def init_checks_registry(): @@ -1506,7 +1507,7 @@ def init_checks_registry(): The first argument name is either 'physical_line' or 'logical_line'. """ mod = inspect.getmodule(register_check) - for (name, function) in inspect.getmembers(mod, inspect.isfunction): + for name, function in inspect.getmembers(mod, inspect.isfunction): register_check(function) @@ -1516,8 +1517,7 @@ def init_checks_registry(): class Checker(object): """Load a Python source file, tokenize it, check coding style.""" - def __init__(self, filename=None, lines=None, - options=None, report=None, **kwargs): + def __init__(self, filename=None, lines=None, options=None, report=None, **kwargs): if options is None: options = StyleGuide(kwargs).options else: @@ -1534,26 +1534,26 @@ def __init__(self, filename=None, lines=None, # Dictionary where a checker can store its custom state. self._checker_states = {} if filename is None: - self.filename = 'stdin' + self.filename = "stdin" self.lines = lines or [] - elif filename == '-': - self.filename = 'stdin' + elif filename == "-": + self.filename = "stdin" self.lines = stdin_get_value().splitlines(True) elif lines is None: try: self.lines = readlines(filename) except IOError: (exc_type, exc) = sys.exc_info()[:2] - self._io_error = '%s: %s' % (exc_type.__name__, exc) + self._io_error = "%s: %s" % (exc_type.__name__, exc) self.lines = [] else: self.lines = lines if self.lines: ord0 = ord(self.lines[0][0]) - if ord0 in (0xef, 0xfeff): # Strip the UTF-8 BOM - if ord0 == 0xfeff: + if ord0 in (0xEF, 0xFEFF): # Strip the UTF-8 BOM + if ord0 == 0xFEFF: self.lines[0] = self.lines[0][1:] - elif self.lines[0][:3] == '\xef\xbb\xbf': + elif self.lines[0][:3] == "\xef\xbb\xbf": self.lines[0] = self.lines[0][3:] self.report = report or options.report self.report_error = self.report.error @@ -1568,14 +1568,12 @@ def report_invalid_syntax(self): offset = offset[1:3] else: offset = (1, 0) - self.report_error(offset[0], offset[1] or 0, - 'E901 %s: %s' % (exc_type.__name__, exc.args[0]), - self.report_invalid_syntax) + self.report_error(offset[0], offset[1] or 0, "E901 %s: %s" % (exc_type.__name__, exc.args[0]), self.report_invalid_syntax) def readline(self): """Get the next line from the input buffer.""" if self.line_number >= self.total_lines: - return '' + return "" line = self.lines[self.line_number] self.line_number += 1 if self.indent_char is None and line[:1] in WHITESPACE: @@ -1591,7 +1589,7 @@ def run_check(self, check, argument_names): def init_checker_state(self, name, argument_names): """Prepare custom state for the specific checker plugin.""" - if 'checker_state' in argument_names: + if "checker_state" in argument_names: self.checker_state = self._checker_states.setdefault(name, {}) def check_physical(self, line): @@ -1603,7 +1601,7 @@ def check_physical(self, line): if result is not None: (offset, text) = result self.report_error(self.line_number, offset, text, check) - if text[:4] == 'E101': + if text[:4] == "E101": self.indent_char = line[0] def build_tokens_line(self): @@ -1624,19 +1622,18 @@ def build_tokens_line(self): text = mute_string(text) if prev_row: (start_row, start_col) = start - if prev_row != start_row: # different row + if prev_row != start_row: # different row prev_text = self.lines[prev_row - 1][prev_col - 1] - if prev_text == ',' or (prev_text not in '{[(' and - text not in '}])'): - text = ' ' + text + if prev_text == "," or (prev_text not in "{[(" and text not in "}])"): + text = " " + text elif prev_col != start_col: # different column text = line[prev_col:start_col] + text logical.append(text) length += len(text) mapping.append((length, end)) (prev_row, prev_col) = end - self.logical_line = ''.join(logical) - self.noqa = comments and noqa(''.join(comments)) + self.logical_line = "".join(logical) + self.noqa = comments and noqa("".join(comments)) return mapping def check_logical(self): @@ -1656,7 +1653,7 @@ def check_logical(self): print(self.logical_line[:80].rstrip()) for name, check, argument_names in self._logical_checks: if self.verbose >= 4: - print(' ' + name) + print(" " + name) self.init_checker_state(name, argument_names) for offset, text in self.run_check(check, argument_names) or (): if not isinstance(offset, tuple): @@ -1676,7 +1673,7 @@ def check_logical(self): def check_ast(self): """Build the file's AST and run all AST checks.""" try: - tree = compile(''.join(self.lines), '', 'exec', PyCF_ONLY_AST) + tree = compile("".join(self.lines), "", "exec", PyCF_ONLY_AST) except (ValueError, SyntaxError, TypeError): return self.report_invalid_syntax() for name, cls, __ in self._ast_checks: @@ -1688,7 +1685,7 @@ def check_ast(self): def generate_tokens(self): """Tokenize the file, run physical line checks and yield tokens.""" if self._io_error: - self.report_error(1, 0, 'E902 %s' % self._io_error, readlines) + self.report_error(1, 0, "E902 %s" % self._io_error, readlines) tokengen = tokenize.generate_tokens(self.readline) try: for token in tokengen: @@ -1706,7 +1703,7 @@ def maybe_check_physical(self, token): if _is_eol_token(token): # Obviously, a newline token ends a single physical line. self.check_physical(token[4]) - elif token[0] == tokenize.STRING and '\n' in token[1]: + elif token[0] == tokenize.STRING and "\n" in token[1]: # Less obviously, a string that contains newlines is a # multiline string, either triple-quoted or with internal # newlines backslash-escaped. Check every physical line in the @@ -1725,8 +1722,8 @@ def maybe_check_physical(self, token): return self.multiline = True self.line_number = token[2][0] - for line in token[1].split('\n')[:-1]: - self.check_physical(line + '\n') + for line in token[1].split("\n")[:-1]: + self.check_physical(line + "\n") self.line_number += 1 self.multiline = False @@ -1739,8 +1736,8 @@ def check_all(self, expected=None, line_offset=0): self.line_number = 0 self.indent_char = None self.indent_level = self.previous_indent_level = 0 - self.previous_logical = '' - self.previous_unindented_logical_line = '' + self.previous_logical = "" + self.previous_unindented_logical_line = "" self.tokens = [] self.blank_lines = self.blank_before = 0 parens = 0 @@ -1749,15 +1746,14 @@ def check_all(self, expected=None, line_offset=0): token_type, text = token[0:2] if self.verbose >= 3: if token[2][0] == token[3][0]: - pos = '[%s:%s]' % (token[2][1] or '', token[3][1]) + pos = "[%s:%s]" % (token[2][1] or "", token[3][1]) else: - pos = 'l.%s' % token[3][0] - print('l.%s\t%s\t%s\t%r' % - (token[2][0], pos, tokenize.tok_name[token[0]], text)) + pos = "l.%s" % token[3][0] + print("l.%s\t%s\t%s\t%r" % (token[2][0], pos, tokenize.tok_name[token[0]], text)) if token_type == tokenize.OP: - if text in '([{': + if text in "([{": parens += 1 - elif text in '}])': + elif text in "}])": parens -= 1 elif not parens: if token_type in NEWLINE: @@ -1774,7 +1770,7 @@ def check_all(self, expected=None, line_offset=0): if len(self.tokens) == 1: # The comment also ends a physical line token = list(token) - token[1] = text.rstrip('\r\n') + token[1] = text.rstrip("\r\n") token[3] = (token[2][0], token[2][1] + len(token[1])) self.tokens = [tuple(token)] self.check_logical() @@ -1813,12 +1809,12 @@ def init_file(self, filename, lines, expected, line_offset): self.expected = expected or () self.line_offset = line_offset self.file_errors = 0 - self.counters['files'] += 1 - self.counters['physical lines'] += len(lines) + self.counters["files"] += 1 + self.counters["physical lines"] += len(lines) def increment_logical_line(self): """Signal a new logical line.""" - self.counters['logical lines'] += 1 + self.counters["logical lines"] += 1 def error(self, line_number, offset, text, check): """Report an error, according to options.""" @@ -1843,12 +1839,11 @@ def get_file_results(self): """Return the count of errors and warnings for this file.""" return self.file_errors - def get_count(self, prefix=''): + def get_count(self, prefix=""): """Return the total count of errors and warnings.""" - return sum([self.counters[key] - for key in self.messages if key.startswith(prefix)]) + return sum([self.counters[key] for key in self.messages if key.startswith(prefix)]) - def get_statistics(self, prefix=''): + def get_statistics(self, prefix=""): """Get statistics for message codes that start with the prefix. prefix='' matches all errors and warnings @@ -1856,22 +1851,19 @@ def get_statistics(self, prefix=''): prefix='W' matches all warnings prefix='E4' matches all errors that have to do with imports """ - return ['%-7s %s %s' % (self.counters[key], key, self.messages[key]) - for key in sorted(self.messages) if key.startswith(prefix)] + return ["%-7s %s %s" % (self.counters[key], key, self.messages[key]) for key in sorted(self.messages) if key.startswith(prefix)] - def print_statistics(self, prefix=''): + def print_statistics(self, prefix=""): """Print overall statistics (number of errors and warnings).""" for line in self.get_statistics(prefix): print(line) def print_benchmark(self): """Print benchmark numbers.""" - print('%-7.2f %s' % (self.elapsed, 'seconds elapsed')) + print("%-7.2f %s" % (self.elapsed, "seconds elapsed")) if self.elapsed: for key in self._benchmark_keys: - print('%-7d %s per second (%d total)' % - (self.counters[key] / self.elapsed, key, - self.counters[key])) + print("%-7d %s per second (%d total)" % (self.counters[key] / self.elapsed, key, self.counters[key])) class FileReport(BaseReport): @@ -1885,8 +1877,7 @@ class StandardReport(BaseReport): def __init__(self, options): super(StandardReport, self).__init__(options) - self._fmt = REPORT_FORMAT.get(options.format.lower(), - options.format) + self._fmt = REPORT_FORMAT.get(options.format.lower(), options.format) self._repeat = options.repeat self._show_source = options.show_source self._show_pep8 = options.show_pep8 @@ -1894,36 +1885,38 @@ def __init__(self, options): def init_file(self, filename, lines, expected, line_offset): """Signal a new file.""" self._deferred_print = [] - return super(StandardReport, self).init_file( - filename, lines, expected, line_offset) + return super(StandardReport, self).init_file(filename, lines, expected, line_offset) def error(self, line_number, offset, text, check): """Report an error, according to options.""" - code = super(StandardReport, self).error(line_number, offset, - text, check) + code = super(StandardReport, self).error(line_number, offset, text, check) if code and (self.counters[code] == 1 or self._repeat): - self._deferred_print.append( - (line_number, offset, code, text[5:], check.__doc__)) + self._deferred_print.append((line_number, offset, code, text[5:], check.__doc__)) return code def get_file_results(self): """Print the result and return the overall count for this file.""" self._deferred_print.sort() for line_number, offset, code, text, doc in self._deferred_print: - print(self._fmt % { - 'path': self.filename, - 'row': self.line_offset + line_number, 'col': offset + 1, - 'code': code, 'text': text, - }) + print( + self._fmt + % { + "path": self.filename, + "row": self.line_offset + line_number, + "col": offset + 1, + "code": code, + "text": text, + } + ) if self._show_source: if line_number > len(self.lines): - line = '' + line = "" else: line = self.lines[line_number - 1] print(line.rstrip()) - print(re.sub(r'\S', ' ', line[:offset]) + '^') + print(re.sub(r"\S", " ", line[:offset]) + "^") if self._show_pep8 and doc: - print(' ' + doc.strip()) + print(" " + doc.strip()) # stdout is block buffered when not stdout.isatty(). # line can be broken where buffer boundary since other processes @@ -1953,19 +1946,18 @@ class StyleGuide(object): def __init__(self, *args, **kwargs): # build options from the command line - self.checker_class = kwargs.pop('checker_class', Checker) - parse_argv = kwargs.pop('parse_argv', False) - config_file = kwargs.pop('config_file', False) - parser = kwargs.pop('parser', None) + self.checker_class = kwargs.pop("checker_class", Checker) + parse_argv = kwargs.pop("parse_argv", False) + config_file = kwargs.pop("config_file", False) + parser = kwargs.pop("parser", None) # build options from dict options_dict = dict(*args, **kwargs) - arglist = None if parse_argv else options_dict.get('paths', None) - options, self.paths = process_options( - arglist, parse_argv, config_file, parser) + arglist = None if parse_argv else options_dict.get("paths", None) + options, self.paths = process_options(arglist, parse_argv, config_file, parser) if options_dict: options.__dict__.update(options_dict) - if 'paths' in options_dict: - self.paths = options_dict['paths'] + if "paths" in options_dict: + self.paths = options_dict["paths"] self.runner = self.input_file self.options = options @@ -1974,18 +1966,17 @@ def __init__(self, *args, **kwargs): options.reporter = BaseReport if options.quiet else StandardReport options.select = tuple(options.select or ()) - if not (options.select or options.ignore or - options.testsuite or options.doctest) and DEFAULT_IGNORE: + if not (options.select or options.ignore or options.testsuite or options.doctest) and DEFAULT_IGNORE: # The default choice: ignore controversial checks - options.ignore = tuple(DEFAULT_IGNORE.split(',')) + options.ignore = tuple(DEFAULT_IGNORE.split(",")) else: # Ignore all checks which are not explicitly selected - options.ignore = ('',) if options.select else tuple(options.ignore) + options.ignore = ("",) if options.select else tuple(options.ignore) options.benchmark_keys = BENCHMARK_KEYS[:] options.ignore_code = self.ignore_code - options.physical_checks = self.get_checks('physical_line') - options.logical_checks = self.get_checks('logical_line') - options.ast_checks = self.get_checks('tree') + options.physical_checks = self.get_checks("physical_line") + options.logical_checks = self.get_checks("logical_line") + options.ast_checks = self.get_checks("tree") self.init_report() def init_report(self, reporter=None): @@ -2007,21 +1998,20 @@ def check_files(self, paths=None): elif not self.excluded(path): runner(path) except KeyboardInterrupt: - print('... stopped') + print("... stopped") report.stop() return report def input_file(self, filename, lines=None, expected=None, line_offset=0): """Run all checks on a Python source file.""" if self.options.verbose: - print('checking %s' % filename) - fchecker = self.checker_class( - filename, lines=lines, options=self.options) + print("checking %s" % filename) + fchecker = self.checker_class(filename, lines=lines, options=self.options) return fchecker.check_all(expected=expected, line_offset=line_offset) def input_dir(self, dirname): """Check all files in this directory and all subdirectories.""" - dirname = dirname.rstrip('/') + dirname = dirname.rstrip("/") if self.excluded(dirname): return 0 counters = self.options.report.counters @@ -2030,15 +2020,14 @@ def input_dir(self, dirname): runner = self.runner for root, dirs, files in os.walk(dirname): if verbose: - print('directory ' + root) - counters['directories'] += 1 + print("directory " + root) + counters["directories"] += 1 for subdir in sorted(dirs): if self.excluded(subdir, root): dirs.remove(subdir) for filename in sorted(files): # contain a pattern that matches? - if ((filename_match(filename, filepatterns) and - not self.excluded(filename, root))): + if filename_match(filename, filepatterns) and not self.excluded(filename, root): runner(os.path.join(root, filename)) def excluded(self, filename, parent=None): @@ -2063,11 +2052,9 @@ def ignore_code(self, code): return False. Else, if 'options.ignore' contains a prefix of the error code, return True. """ - if len(code) < 4 and any(s.startswith(code) - for s in self.options.select): + if len(code) < 4 and any(s.startswith(code) for s in self.options.select): return False - return (code.startswith(self.options.ignore) and - not code.startswith(self.options.select)) + return code.startswith(self.options.ignore) and not code.startswith(self.options.select) def get_checks(self, argument_name): """Get all the checks for this category. @@ -2083,65 +2070,67 @@ def get_checks(self, argument_name): return sorted(checks) -def get_parser(prog='pycodestyle', version=__version__): +def get_parser(prog="pycodestyle", version=__version__): """Create the parser for the program.""" - parser = OptionParser(prog=prog, version=version, - usage="%prog [options] input ...") + parser = OptionParser(prog=prog, version=version, usage="%prog [options] input ...") parser.config_options = [ - 'exclude', 'filename', 'select', 'ignore', 'max-line-length', - 'hang-closing', 'count', 'format', 'quiet', 'show-pep8', - 'show-source', 'statistics', 'verbose'] - parser.add_option('-v', '--verbose', default=0, action='count', - help="print status messages, or debug with -vv") - parser.add_option('-q', '--quiet', default=0, action='count', - help="report only file names, or nothing with -qq") - parser.add_option('-r', '--repeat', default=True, action='store_true', - help="(obsolete) show all occurrences of the same error") - parser.add_option('--first', action='store_false', dest='repeat', - help="show first occurrence of each error") - parser.add_option('--exclude', metavar='patterns', default=DEFAULT_EXCLUDE, - help="exclude files or directories which match these " - "comma separated patterns (default: %default)") - parser.add_option('--filename', metavar='patterns', default='*.py', - help="when parsing directories, only check filenames " - "matching these comma separated patterns " - "(default: %default)") - parser.add_option('--select', metavar='errors', default='', - help="select errors and warnings (e.g. E,W6)") - parser.add_option('--ignore', metavar='errors', default='', - help="skip errors and warnings (e.g. E4,W) " - "(default: %s)" % DEFAULT_IGNORE) - parser.add_option('--show-source', action='store_true', - help="show source code for each error") - parser.add_option('--show-pep8', action='store_true', - help="show text of PEP 8 for each error " - "(implies --first)") - parser.add_option('--statistics', action='store_true', - help="count errors and warnings") - parser.add_option('--count', action='store_true', - help="print total number of errors and warnings " - "to standard error and set exit code to 1 if " - "total is not null") - parser.add_option('--max-line-length', type='int', metavar='n', - default=MAX_LINE_LENGTH, - help="set maximum allowed line length " - "(default: %default)") - parser.add_option('--hang-closing', action='store_true', - help="hang closing bracket instead of matching " - "indentation of opening bracket's line") - parser.add_option('--format', metavar='format', default='default', - help="set the error format [default|pylint|]") - parser.add_option('--diff', action='store_true', - help="report changes only within line number ranges in " - "the unified diff received on STDIN") + "exclude", + "filename", + "select", + "ignore", + "max-line-length", + "hang-closing", + "count", + "format", + "quiet", + "show-pep8", + "show-source", + "statistics", + "verbose", + ] + parser.add_option("-v", "--verbose", default=0, action="count", help="print status messages, or debug with -vv") + parser.add_option("-q", "--quiet", default=0, action="count", help="report only file names, or nothing with -qq") + parser.add_option("-r", "--repeat", default=True, action="store_true", help="(obsolete) show all occurrences of the same error") + parser.add_option("--first", action="store_false", dest="repeat", help="show first occurrence of each error") + parser.add_option( + "--exclude", + metavar="patterns", + default=DEFAULT_EXCLUDE, + help="exclude files or directories which match these " "comma separated patterns (default: %default)", + ) + parser.add_option( + "--filename", + metavar="patterns", + default="*.py", + help="when parsing directories, only check filenames " "matching these comma separated patterns " "(default: %default)", + ) + parser.add_option("--select", metavar="errors", default="", help="select errors and warnings (e.g. E,W6)") + parser.add_option( + "--ignore", metavar="errors", default="", help="skip errors and warnings (e.g. E4,W) " "(default: %s)" % DEFAULT_IGNORE + ) + parser.add_option("--show-source", action="store_true", help="show source code for each error") + parser.add_option("--show-pep8", action="store_true", help="show text of PEP 8 for each error " "(implies --first)") + parser.add_option("--statistics", action="store_true", help="count errors and warnings") + parser.add_option( + "--count", + action="store_true", + help="print total number of errors and warnings " "to standard error and set exit code to 1 if " "total is not null", + ) + parser.add_option( + "--max-line-length", type="int", metavar="n", default=MAX_LINE_LENGTH, help="set maximum allowed line length " "(default: %default)" + ) + parser.add_option( + "--hang-closing", action="store_true", help="hang closing bracket instead of matching " "indentation of opening bracket's line" + ) + parser.add_option("--format", metavar="format", default="default", help="set the error format [default|pylint|]") + parser.add_option( + "--diff", action="store_true", help="report changes only within line number ranges in " "the unified diff received on STDIN" + ) group = parser.add_option_group("Testing Options") if os.path.exists(TESTSUITE_PATH): - group.add_option('--testsuite', metavar='dir', - help="run regression tests from dir") - group.add_option('--doctest', action='store_true', - help="run doctest on myself") - group.add_option('--benchmark', action='store_true', - help="measure processing speed") + group.add_option("--testsuite", metavar="dir", help="run regression tests from dir") + group.add_option("--doctest", action="store_true", help="run doctest on myself") + group.add_option("--benchmark", action="store_true", help="measure processing speed") return parser @@ -2163,7 +2152,7 @@ def read_config(options, args, arglist, parser): if USER_CONFIG and os.path.isfile(USER_CONFIG): if options.verbose: - print('user configuration: %s' % USER_CONFIG) + print("user configuration: %s" % USER_CONFIG) config.read(USER_CONFIG) parent = tail = args and os.path.abspath(os.path.commonprefix(args)) @@ -2171,46 +2160,44 @@ def read_config(options, args, arglist, parser): if config.read(os.path.join(parent, fn) for fn in PROJECT_CONFIG): local_dir = parent if options.verbose: - print('local configuration: in %s' % parent) + print("local configuration: in %s" % parent) break (parent, tail) = os.path.split(parent) if cli_conf and os.path.isfile(cli_conf): if options.verbose: - print('cli configuration: %s' % cli_conf) + print("cli configuration: %s" % cli_conf) config.read(cli_conf) pycodestyle_section = None if config.has_section(parser.prog): pycodestyle_section = parser.prog - elif config.has_section('pep8'): - pycodestyle_section = 'pep8' # Deprecated - warnings.warn('[pep8] section is deprecated. Use [pycodestyle].') + elif config.has_section("pep8"): + pycodestyle_section = "pep8" # Deprecated + warnings.warn("[pep8] section is deprecated. Use [pycodestyle].") if pycodestyle_section: - option_list = dict([(o.dest, o.type or o.action) - for o in parser.option_list]) + option_list = dict([(o.dest, o.type or o.action) for o in parser.option_list]) # First, read the default values (new_options, __) = parser.parse_args([]) # Second, parse the configuration for opt in config.options(pycodestyle_section): - if opt.replace('_', '-') not in parser.config_options: + if opt.replace("_", "-") not in parser.config_options: print(" unknown option '%s' ignored" % opt) continue if options.verbose > 1: - print(" %s = %s" % (opt, - config.get(pycodestyle_section, opt))) - normalized_opt = opt.replace('-', '_') + print(" %s = %s" % (opt, config.get(pycodestyle_section, opt))) + normalized_opt = opt.replace("-", "_") opt_type = option_list[normalized_opt] - if opt_type in ('int', 'count'): + if opt_type in ("int", "count"): value = config.getint(pycodestyle_section, opt) - elif opt_type in ('store_true', 'store_false'): + elif opt_type in ("store_true", "store_false"): value = config.getboolean(pycodestyle_section, opt) else: value = config.get(pycodestyle_section, opt) - if normalized_opt == 'exclude': + if normalized_opt == "exclude": value = normalize_paths(value, local_dir) setattr(new_options, normalized_opt, value) @@ -2220,8 +2207,7 @@ def read_config(options, args, arglist, parser): return options -def process_options(arglist=None, parse_argv=False, config_file=None, - parser=None): +def process_options(arglist=None, parse_argv=False, config_file=None, parser=None): """Process options passed either via arglist or via command line args. Passing in the ``config_file`` parameter allows other tools, such as flake8 @@ -2229,14 +2215,16 @@ def process_options(arglist=None, parse_argv=False, config_file=None, """ if not parser: parser = get_parser() - if not parser.has_option('--config'): - group = parser.add_option_group("Configuration", description=( - "The project options are read from the [%s] section of the " - "tox.ini file or the setup.cfg file located in any parent folder " - "of the path(s) being processed. Allowed options are: %s." % - (parser.prog, ', '.join(parser.config_options)))) - group.add_option('--config', metavar='path', default=config_file, - help="user config file location") + if not parser.has_option("--config"): + group = parser.add_option_group( + "Configuration", + description=( + "The project options are read from the [%s] section of the " + "tox.ini file or the setup.cfg file located in any parent folder " + "of the path(s) being processed. Allowed options are: %s." % (parser.prog, ", ".join(parser.config_options)) + ), + ) + group.add_option("--config", metavar="path", default=config_file, help="user config file location") # Don't read the command line if the module is used as a library. if not arglist and not parse_argv: arglist = [] @@ -2245,15 +2233,14 @@ def process_options(arglist=None, parse_argv=False, config_file=None, (options, args) = parser.parse_args(arglist) options.reporter = None - if options.ensure_value('testsuite', False): + if options.ensure_value("testsuite", False): args.append(options.testsuite) - elif not options.ensure_value('doctest', False): + elif not options.ensure_value("doctest", False): if parse_argv and not args: - if options.diff or any(os.path.exists(name) - for name in PROJECT_CONFIG): - args = ['.'] + if options.diff or any(os.path.exists(name) for name in PROJECT_CONFIG): + args = ["."] else: - parser.error('input not specified') + parser.error("input not specified") options = read_config(options, args, arglist, parser) options.reporter = parse_argv and options.quiet == 1 and FileReport @@ -2271,7 +2258,7 @@ def process_options(arglist=None, parse_argv=False, config_file=None, return options, args -def _parse_multi_options(options, split_token=','): +def _parse_multi_options(options, split_token=","): r"""Split and strip and discard empties. Turns the following: @@ -2295,13 +2282,14 @@ def _main(): try: signal.signal(signal.SIGPIPE, lambda signum, frame: sys.exit(1)) except AttributeError: - pass # not supported on Windows + pass # not supported on Windows style_guide = StyleGuide(parse_argv=True) options = style_guide.options if options.doctest or options.testsuite: from testsuite.support import run_tests + report = run_tests(style_guide) else: report = style_guide.check_files() @@ -2317,9 +2305,9 @@ def _main(): if report.total_errors: if options.count: - sys.stderr.write(str(report.total_errors) + '\n') + sys.stderr.write(str(report.total_errors) + "\n") sys.exit(1) -if __name__ == '__main__': +if __name__ == "__main__": _main() diff --git a/third_party/tests_cython_json.py b/third_party/tests_cython_json.py index 4c1916691..ff6ae49c5 100644 --- a/third_party/tests_cython_json.py +++ b/third_party/tests_cython_json.py @@ -5,50 +5,54 @@ def test_dump_ast_error(): - as_dict = source_to_dict(u"x = [a 10]") - errors = as_dict['errors'] + as_dict = source_to_dict("x = [a 10]") + errors = as_dict["errors"] assert len(errors) == 1 error = errors[0] - assert error['__node__'] == 'CompileError' - assert error['line'] == 1 - assert error['col'] == 8 - assert 'Expected' in error['message_only'] + assert error["__node__"] == "CompileError" + assert error["line"] == 1 + assert error["col"] == 8 + assert "Expected" in error["message_only"] def test_dump_error(): - contents = u''' + contents = """ from distutils import sysconfig -''' +""" if isinstance(contents, bytes): - contents = contents.decode('utf-8') + contents = contents.decode("utf-8") source_to_dict(contents) + def test_dump_class(): - contents = u''' + contents = """ class A:pass -''' +""" if isinstance(contents, bytes): - contents = contents.decode('utf-8') + contents = contents.decode("utf-8") source_to_dict(contents) + def test_comp(): - contents = u''' + contents = """ {i: j for i, j in a} -''' +""" if isinstance(contents, bytes): - contents = contents.decode('utf-8') + contents = contents.decode("utf-8") source_to_dict(contents) + def test_global(): - contents = u''' + contents = """ def method(): global b b = 10 -''' +""" if isinstance(contents, bytes): - contents = contents.decode('utf-8') + contents = contents.decode("utf-8") source_to_dict(contents) + # def test_dump_custom(): # with open(r'X:\cython\tests\compile\buildenv.pyx', 'r') as stream: # contents = stream.read().decode('utf-8') @@ -56,21 +60,16 @@ def method(): def test_dump_ast(): - data = source_to_dict(u"x = [a, 10]") - assert not data['errors'] - assert data['ast']['stats'] == [ + data = source_to_dict("x = [a, 10]") + assert not data["errors"] + assert data["ast"]["stats"] == [ { "__node__": "SingleAssignment", "rhs": { "__node__": "List", "line": 1, "args": [ - { - "__node__": "Name", - "line": 1, - "col": 5, - "name": "a" - }, + {"__node__": "Name", "line": 1, "col": 5, "name": "a"}, { "is_c_literal": "None", "unsigned": "", @@ -80,22 +79,17 @@ def test_dump_ast(): "line": 1, "type": "long", "col": 8, - "longness": "" - } + "longness": "", + }, ], - "col": 4 - }, - "lhs": { - "__node__": "Name", - "line": 1, - "col": 0, - "name": "x" + "col": 4, }, + "lhs": {"__node__": "Name", "line": 1, "col": 0, "name": "x"}, "line": 1, - "col": 4 + "col": 4, } ] -if __name__ == '__main__': +if __name__ == "__main__": pytest.main()