From e978055940d8f79fd5a41abf2821579239593367 Mon Sep 17 00:00:00 2001 From: Roman Podoliaka Date: Sun, 9 Aug 2026 15:01:04 +0100 Subject: [PATCH] Make ruff linter happy --- cpython_lldb.py | 87 +++++++++---------- tests/conftest.py | 11 ++- .../test_extension/test_extension/__init__.py | 2 +- tests/test_pretty_printer.py | 9 +- tests/test_py_bt.py | 4 +- tests/test_py_list.py | 1 - tests/test_py_locals.py | 25 +++--- tests/test_py_up_down.py | 1 - 8 files changed, 63 insertions(+), 77 deletions(-) diff --git a/cpython_lldb.py b/cpython_lldb.py index 34c3bb4..758f493 100644 --- a/cpython_lldb.py +++ b/cpython_lldb.py @@ -1,21 +1,19 @@ import abc import argparse import collections -import io import re import shlex import struct import lldb - ENCODING_RE = re.compile(r"^[ \t\f]*#.*?coding[:=][ \t]*([-_.a-zA-Z0-9]+)") # Objects -class PyObject(object): +class PyObject: def __init__(self, lldb_value): self.lldb_value = lldb_value @@ -41,20 +39,22 @@ def from_value(cls, v): @staticmethod def typename_of(v): + addr = ( + v.GetChildMemberWithName("ob_type") + .GetChildMemberWithName("tp_name") + .unsigned + ) + if not addr: + return + try: - addr = ( - v.GetChildMemberWithName("ob_type") - .GetChildMemberWithName("tp_name") - .unsigned - ) - if not addr: - return + status = lldb.SBError() + cstring = v.GetProcess().ReadCStringFromMemory(addr, 256, status) - process = v.GetProcess() - return process.ReadCStringFromMemory(addr, 256, lldb.SBError()) - except Exception: - # if we fail to read tp_name, then it's likely not a PyObject - pass + return cstring if status.Success() else None + except Exception: # noqa + # If we fail to read tp_name, then it's likely not a PyObject. + return @property def typename(self): @@ -111,7 +111,7 @@ def value(self): digits = value.GetChildMemberWithName("ob_digit") abs_value = sum( digits.GetChildAtIndex(i, 0, True).unsigned * 2 ** (shift * i) - for i in range(0, abs(size)) + for i in range(abs(size)) ) return abs_value if size > 0 else -abs_value @@ -181,7 +181,7 @@ def _get_encoding(kind): elif kind == PyUnicodeObject.U_4BYTE_KIND: return "utf-32" else: - raise ValueError("Unsupported PyUnicodeObject kind: {}".format(kind)) + raise ValueError(f"Unsupported PyUnicodeObject kind: {kind}") @staticmethod def _read_string_from_memory(process, addr, length, kind): @@ -252,7 +252,7 @@ class PyNoneObject(PyObject): value = None -class _PySequence(object): +class _PySequence: @property def value(self): value = self.lldb_value.Cast(self.lldb_type.GetPointerType()) @@ -288,7 +288,7 @@ def lldb_type(self): return self.target.FindFirstType(self.cpython_struct) -class _PySetObject(object): +class _PySetObject: cpython_struct = "PySetObject" @property @@ -324,10 +324,10 @@ class PyFrozenSetObject(_PySetObject, PyObject): @property def value(self): - return frozenset(super(PyFrozenSetObject, self).value) + return frozenset(super().value) -class _PyDictObject(object): +class _PyDictObject: DICT_KEYS_GENERAL = 0 DICT_KEYS_UNICODE = 1 DICT_KEYS_SPLIT = 2 @@ -457,7 +457,7 @@ def value(self): return PyDictObject(value.GetChildMemberWithName("dict").AddressOf()).value -class _CollectionsUserObject(object): +class _CollectionsUserObject: @property def value(self): # UserDict, UserString, and UserList all have a single instance variable @@ -513,7 +513,7 @@ class UserString(_CollectionsUserObject, PyObject): typename = "UserString" -class PyCodeAddressRange(object): +class PyCodeAddressRange: """A class for parsing the line number table implemented in PEP 626. The format of the line number table is not part of CPython's API and may @@ -662,7 +662,7 @@ class PyFrameObject(PyObject): typename = "frame" def __init__(self, lldb_value): - super(PyFrameObject, self).__init__(lldb_value) + super().__init__(lldb_value) self.co = PyCodeObject(self.child("f_code")) @classmethod @@ -790,17 +790,13 @@ def line(self): return source_file_lines( self.filename, self.line_number, self.line_number + 1, encoding=encoding )[0] - except (IOError, IndexError): + except (OSError, IndexError): return "" def to_pythonlike_string(self): lineno = self.line_number co_name = PyObject.from_value(self.co.child("co_name")).value - return 'File "{filename}", line {lineno}, in {co_name}'.format( - filename=self.filename, - co_name=co_name, - lineno=lineno, - ) + return f'File "{self.filename}", line {lineno}, in {co_name}' # Commands @@ -831,8 +827,8 @@ def __call__(self, debugger, command, exe_ctx, result): try: args = self.argument_parser.parse_args(shlex.split(command)) self.execute(debugger, args, result) - except Exception as e: - msg = "Failed to execute command `{}`: {}".format(self.command, e) + except Exception as e: # noqa + msg = f"Failed to execute command `{self.command}`: {e}" result.SetError(msg) @@ -933,7 +929,7 @@ class PyList(Command): @property def argument_parser(self): - parser = super(PyList, self).argument_parser + parser = super().argument_parser parser.add_argument("linenum", nargs="*", type=int, default=[0, 0]) @@ -982,12 +978,12 @@ def execute(self, debugger, args, result): for i, line in enumerate(lines, start): # highlight the current line if i == current_line_num: - prefix = ">{}".format(i) + prefix = f">{i}" else: - prefix = "{}".format(i) + prefix = f"{i}" - write_line(result, "{:>5} {}".format(prefix, line.rstrip())) - except IOError: + write_line(result, f"{prefix:>5} {line.rstrip()}") + except OSError: write_line(result, "") @@ -1054,13 +1050,13 @@ def execute(self, debugger, args, result): merged_locals.pop(name, None) for name in sorted(merged_locals.keys()): - write_line(result, "{} = {}".format(name, repr(merged_locals[name]))) + write_line(result, f"{name} = {merged_locals[name]!r}") # Helpers -class Direction(object): +class Direction: DOWN = -1 UP = 1 @@ -1096,7 +1092,7 @@ def move_python_frame(debugger, direction): if direction == Direction.UP: index_range = range(current_frame.idx + 1, thread.num_frames) else: - index_range = reversed(range(0, current_frame.idx)) + index_range = reversed(range(current_frame.idx)) for index in index_range: python_frame = PyFrameObject.from_frame(thread.GetFrameAtIndex(index)) @@ -1112,7 +1108,7 @@ def write_line(result, string): def source_file_encoding(filename): """Determine the text encoding of a Python source file.""" - with io.open(filename, "rt", encoding="latin-1") as f: + with open(filename, "rt", encoding="latin-1") as f: # according to PEP-263 the magic comment must be placed on one of the first two lines for _ in range(2): line = f.readline() @@ -1131,7 +1127,7 @@ def source_file_lines(filename, start, end, encoding="utf-8"): """ lines = [] - with io.open(filename, "rt", encoding=encoding) as f: + with open(filename, "rt", encoding=encoding) as f: for line_num, line in enumerate(f, 1): if start <= line_num < end: lines.append(line) @@ -1160,10 +1156,7 @@ def general_purpose_registers(frame): def register_commands(debugger): for cls in Command.__subclasses__(): debugger.HandleCommand( - "command script add -c cpython_lldb.{cls} {command}".format( - cls=cls.__name__, - command=cls.command, - ) + f"command script add -c cpython_lldb.{cls.__name__} {cls.command}" ) @@ -1200,7 +1193,7 @@ def register_summaries(debugger): } for type_ in cpython_structs: debugger.HandleCommand( - "type summary add -F cpython_lldb.pretty_printer {}".format(type_) + f"type summary add -F cpython_lldb.pretty_printer {type_}" ) # cache the result of the lookup, so that we do not need to repeat that at runtime diff --git a/tests/conftest.py b/tests/conftest.py index 1e19e1a..7a4d700 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,7 +1,6 @@ import contextlib -import io -import re import os +import re import subprocess import sys @@ -51,7 +50,7 @@ def lldb_no_symbols_session(tmpdir_factory): with tmpdir.as_cwd(): libpython = ( subprocess.check_output( - "ldd %s | grep libpython | awk '{print $3}'" % (sys.executable), + f"ldd {sys.executable} | grep libpython | awk '{{print $3}}'", shell=True, ) .decode("utf-8") @@ -138,13 +137,13 @@ def run_lldb(lldb_manager, code, breakpoint, commands): outputs = [] with lldb_manager() as lldb: - with io.open("test.py", "wb") as fp: + with open("test.py", "wb") as fp: if isinstance(code, str): code = code.encode("utf-8") fp.write(code) - lldb.sendline("breakpoint set -r %s" % breakpoint) + lldb.sendline(f"breakpoint set -r {breakpoint}") lldb.expect(r"Breakpoint \d+") lldb.expect(re.escape("(lldb) ")) lldb.sendline("run test.py") @@ -153,7 +152,7 @@ def run_lldb(lldb_manager, code, breakpoint, commands): for command in commands: lldb.sendline(command) - lldb.expect(re.escape("%s\r\n" % command)) + lldb.expect(re.escape(f"{command}\r\n")) lldb.expect(re.escape("(lldb) ")) outputs.append(normalize_stacktrace(lldb.before.replace("\r\n", "\n"))) diff --git a/tests/test_extension/test_extension/__init__.py b/tests/test_extension/test_extension/__init__.py index 2c89d59..3cc08d3 100644 --- a/tests/test_extension/test_extension/__init__.py +++ b/tests/test_extension/test_extension/__init__.py @@ -1,3 +1,3 @@ -from ._test_extension import spam as spam from ._test_extension import eggs as eggs from ._test_extension import identity as identity +from ._test_extension import spam as spam diff --git a/tests/test_pretty_printer.py b/tests/test_pretty_printer.py index 170bcb5..0adeb3e 100644 --- a/tests/test_pretty_printer.py +++ b/tests/test_pretty_printer.py @@ -47,9 +47,8 @@ def assert_lldb_repr(lldb_manager, value, expected, code_value=None): # for other data types we can do an exact string match using # a regular expression (e.g. to account for optional 'u' and 'b' # in unicode / bytes literals, etc) - assert re.match(expected, match.group(1)), "Expected: %s\nActual: %s" % ( - expected, - match.group(1), + assert re.match(expected, match.group(1)), ( + f"Expected: {expected}\nActual: {match.group(1)}" ) @@ -122,10 +121,10 @@ def test_tuple(lldb): def test_set(lldb): assert_lldb_repr(lldb, set(), r"set\(\[\]\)") - assert_lldb_repr(lldb, set([1, 2, 3]), r"set\(\[1, 2, 3\]\)") + assert_lldb_repr(lldb, {1, 2, 3}, r"set\(\[1, 2, 3\]\)") assert_lldb_repr( lldb, - set([1, 3.14159, "hello", False, None]), + {1, 3.14159, "hello", False, None}, r"set\(\[False, 1, 3.14159, None, u\'hello\'\]\)", ) assert_lldb_repr( diff --git a/tests/test_py_bt.py b/tests/test_py_bt.py index 0c7d45d..75ec1da 100644 --- a/tests/test_py_bt.py +++ b/tests/test_py_bt.py @@ -85,7 +85,7 @@ def fc(): lldb, code=code, breakpoint="builtin_abs", - commands=["frame select %d" % int(pyframes[2][0]), "py-bt"], + commands=[f"frame select {int(pyframes[2][0])}", "py-bt"], )[-1] actual = response.rstrip() assert actual == backtrace @@ -126,7 +126,7 @@ def fc(): lldb, code=code, breakpoint="builtin_abs", - commands=["frame select %d" % (int(pyframes[-1][0]) + 1), "py-bt"], + commands=[f"frame select {int(pyframes[-1][0]) + 1}", "py-bt"], )[-1] actual = response.rstrip() assert actual == backtrace diff --git a/tests/test_py_list.py b/tests/test_py_list.py index d5804f0..478dcf6 100644 --- a/tests/test_py_list.py +++ b/tests/test_py_list.py @@ -1,6 +1,5 @@ from .conftest import run_lldb - CODE = """ SOME_CONST = u'тест' diff --git a/tests/test_py_locals.py b/tests/test_py_locals.py index f5ae0da..f205de2 100644 --- a/tests/test_py_locals.py +++ b/tests/test_py_locals.py @@ -1,6 +1,5 @@ from .conftest import run_lldb - CODE = """\ def fa(): abs(1) @@ -56,19 +55,17 @@ def test_globals(lldb): )[-1] actual = response.rstrip() - actual_keys = set(line.split("=")[0].strip() for line in actual.split("\n") if line) - expected_keys = set( - [ - "__builtins__", - "__package__", - "__name__", - "__doc__", - "__file__", - "fa", - "fb", - "fc", - ] - ) + actual_keys = {line.split("=")[0].strip() for line in actual.split("\n") if line} + expected_keys = { + "__builtins__", + "__package__", + "__name__", + "__doc__", + "__file__", + "fa", + "fb", + "fc", + } assert (expected_keys & actual_keys) == expected_keys diff --git a/tests/test_py_up_down.py b/tests/test_py_up_down.py index a0b1811..1b96777 100644 --- a/tests/test_py_up_down.py +++ b/tests/test_py_up_down.py @@ -1,6 +1,5 @@ from .conftest import run_lldb - CODE = """ SOME_CONST = u'тест'