From c3f447adda027759828c28b69b0d5b0a89cbf701 Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner Date: Thu, 11 Jul 2024 09:36:48 -0500 Subject: [PATCH] Switch to ruff, fix issues --- .github/workflows/ci.yml | 13 +++------ .gitlab-ci.yml | 8 +++--- debug_me.py | 27 +++++++++++------- doc/conf.py | 1 + examples/mpi4py-debug.py | 1 + examples/remote-debug.py | 2 ++ examples/shell.py | 7 +++-- examples/stringifier.py | 15 ++++++---- examples/theme.py | 4 +-- manual-tests/test-api.py | 5 +++- manual-tests/test-encoding.py | 5 ---- manual-tests/test-postmortem.py | 5 ++-- pudb/__init__.py | 18 ++++++++---- pudb/debugger.py | 37 +++++++++++++++---------- pudb/forked.py | 2 +- pudb/ipython.py | 4 +-- pudb/lowlevel.py | 15 ++++++---- pudb/remote.py | 7 +++-- pudb/run.py | 2 +- pudb/settings.py | 10 +++---- pudb/shell.py | 14 ++++++---- pudb/source_view.py | 4 +-- pudb/test/test_lowlevel.py | 2 +- pudb/test/test_run.py | 1 + pudb/test/test_settings.py | 2 +- pudb/test/test_source_code_providers.py | 5 +++- pudb/test/test_var_view.py | 8 +++--- pudb/theme.py | 8 +++--- pudb/themes/__init__.py | 5 ++-- pudb/themes/agr_256.py | 1 + pudb/themes/classic.py | 1 + pudb/themes/dark_vim.py | 1 + pudb/themes/gray_light_256.py | 1 + pudb/themes/midnight.py | 1 + pudb/themes/monokai.py | 1 + pudb/themes/monokai_256.py | 1 + pudb/themes/nord_dark_256.py | 1 + pudb/themes/solarized.py | 1 + pudb/themes/vim.py | 1 + pudb/ui_tools.py | 4 +-- pudb/var_view.py | 12 ++++---- pyproject.toml | 36 ++++++++++++++++++++++++ setup.cfg | 18 ------------ setup.py | 2 ++ 44 files changed, 193 insertions(+), 126 deletions(-) delete mode 100644 manual-tests/test-encoding.py delete mode 100644 setup.cfg diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fa574b22..0f99a3f3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,20 +10,15 @@ on: - cron: '17 3 * * 0' jobs: - flake8: - name: Flake8 + ruff: + name: Ruff runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - - uses: actions/setup-python@v5 - with: - # matches compat target in setup.py - python-version: '3.8' - name: "Main Script" run: | - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/main/prepare-and-run-flake8.sh - . ./prepare-and-run-flake8.sh ./pudb + pipx install ruff + ruff check pylint: name: Pylint diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 56f9f759..aa417d27 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -14,12 +14,12 @@ Python 3: reports: junit: test/pytest.xml -Flake8: +ruff: script: - - curl -L -O -k https://gitlab.tiker.net/inducer/ci-support/raw/main/prepare-and-run-flake8.sh - - ". ./prepare-and-run-flake8.sh pudb" + - pipx install ruff + - ruff check tags: - - python3 + - docker-runner except: - tags diff --git a/debug_me.py b/debug_me.py index 286411ca..dfa1c333 100644 --- a/debug_me.py +++ b/debug_me.py @@ -1,6 +1,7 @@ from collections import namedtuple -Color = namedtuple('Color', ['red', 'green', 'blue', 'alpha']) + +Color = namedtuple("Color", ["red", "green", "blue", "alpha"]) class MyClass(object): @@ -9,30 +10,35 @@ def __init__(self, a, b): self.b = b self._b = [b] + mc = MyClass(15, MyClass(12, None)) -from pudb import set_trace; set_trace() +from pudb import set_trace + + +set_trace() + def simple_func(x): x += 1 s = range(20) - z = None - w = () + z = None # noqa: F841 + w = () # noqa: F841 - y = dict((i, i**2) for i in s) + y = {i: i**2 for i in s} # noqa: F841 - k = set(range(5, 99)) - c = Color(137, 214, 56, 88) + k = set(range(5, 99)) # noqa: F841 + c = Color(137, 214, 56, 88) # noqa: F841 try: - x.invalid + x.invalid # noqa: B018 except AttributeError: pass - #import sys - #sys.exit(1) + # import sys + # sys.exit(1) return 2*x @@ -52,6 +58,7 @@ def fermat(n): if x**n + y**n == z**n: yield x, y, z + print("SF %s" % simple_func(10)) for i in fermat(2): diff --git a/doc/conf.py b/doc/conf.py index 623513fc..00d22ef1 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -2,6 +2,7 @@ import sys from urllib.request import urlopen + _conf_url = \ "https://raw.githubusercontent.com/inducer/sphinxconfig/main/sphinxconfig.py" with urlopen(_conf_url) as _inf: diff --git a/examples/mpi4py-debug.py b/examples/mpi4py-debug.py index f3c7b396..82e97959 100644 --- a/examples/mpi4py-debug.py +++ b/examples/mpi4py-debug.py @@ -6,6 +6,7 @@ # (when using the default pudb configuration) in another terminal. from mpi4py import MPI + from pudb.remote import debug_remote_on_single_rank diff --git a/examples/remote-debug.py b/examples/remote-debug.py index a57cb1e9..9abdfe8d 100644 --- a/examples/remote-debug.py +++ b/examples/remote-debug.py @@ -4,5 +4,7 @@ def debugged_function(x): from pudb.remote import debugger + + dbg = debugger() dbg.runcall(debugged_function, 5) diff --git a/examples/shell.py b/examples/shell.py index ec45ac80..73ec439f 100644 --- a/examples/shell.py +++ b/examples/shell.py @@ -14,6 +14,7 @@ """ + # Define this a function with this name and signature at the module level. def pudb_shell(_globals, _locals): """ @@ -33,11 +34,11 @@ def pudb_shell(_globals, _locals): try: import readline import rlcompleter - HAVE_READLINE = True + have_readline = True except ImportError: - HAVE_READLINE = False + have_readline = False - if HAVE_READLINE: + if have_readline: readline.set_completer( rlcompleter.Completer(ns).complete) readline.parse_and_bind("tab: complete") diff --git a/examples/stringifier.py b/examples/stringifier.py index 2cf4cce1..41719205 100644 --- a/examples/stringifier.py +++ b/examples/stringifier.py @@ -38,17 +38,18 @@ a handful of "safe" types for which it is guaranteed to be fast and not to fail. """ -import time import signal -import sys -import math +import time + class TimeOutError(Exception): pass + def timeout(signum, frame, time): raise TimeOutError("Timed out after %d seconds" % time) + def run_with_timeout(code, time, globals=None): """ Evaluate ``code``, timing out after ``time`` seconds. @@ -63,6 +64,7 @@ def run_with_timeout(code, time, globals=None): signal.alarm(0) # Disable the alarm return r + def pudb_stringifier(obj): """ This is the custom stringifier. @@ -71,21 +73,24 @@ def pudb_stringifier(obj): in which case it falls back to type(obj). """ try: - return run_with_timeout("str(obj)", 0.5, {'obj':obj}) + return run_with_timeout("str(obj)", 0.5, {"obj": obj}) except TimeOutError: return (type(obj), "(str too slow to compute)") # Example usage + class FastString(object): def __str__(self): return "This was fast to compute." + class SlowString(object): def __str__(self): - time.sleep(10) # Return the string value after ten seconds + time.sleep(10) # Return the string value after ten seconds return "This was slow to compute." + fast = FastString() slow = SlowString() diff --git a/examples/theme.py b/examples/theme.py index e6050dfa..6c12e079 100644 --- a/examples/theme.py +++ b/examples/theme.py @@ -21,7 +21,7 @@ # Note, be sure to test your theme in both curses and raw mode (see the bottom # of the preferences window). Curses mode will be used with screen or tmux. -palette.update({ - "source": (add_setting("black", "underline"), "dark green"), +palette.update({ # noqa: F821 + "source": (add_setting("black", "underline"), "dark green"), # noqa: F821 "comment": ("h250", "default") }) diff --git a/manual-tests/test-api.py b/manual-tests/test-api.py index 472a94ea..c157c290 100644 --- a/manual-tests/test-api.py +++ b/manual-tests/test-api.py @@ -1,5 +1,8 @@ def f(): - fail + fail # noqa: B018, F821 + from pudb import runcall + + runcall(f) diff --git a/manual-tests/test-encoding.py b/manual-tests/test-encoding.py deleted file mode 100644 index f5f7e51a..00000000 --- a/manual-tests/test-encoding.py +++ /dev/null @@ -1,5 +0,0 @@ -def f(encoding=None): - print 'ENCODING:', encoding - -from pudb import runcall -runcall(f) diff --git a/manual-tests/test-postmortem.py b/manual-tests/test-postmortem.py index a8780473..363ee2c4 100644 --- a/manual-tests/test-postmortem.py +++ b/manual-tests/test-postmortem.py @@ -1,8 +1,9 @@ def f(): - fail + fail # noqa: B018, F821 + try: f() -except: +except Exception: from pudb import post_mortem post_mortem() diff --git a/pudb/__init__.py b/pudb/__init__.py index d1f6c1b0..ea22e327 100644 --- a/pudb/__init__.py +++ b/pudb/__init__.py @@ -24,9 +24,10 @@ """ -from pudb.settings import load_config import sys +from pudb.settings import load_config + NUM_VERSION = (2024, 1, 1) VERSION = ".".join(str(nv) for nv in NUM_VERSION) @@ -54,6 +55,8 @@ def go(self): import builtins + + builtins.__dict__["pu"] = PudbShortcuts() @@ -292,23 +295,26 @@ def set_interrupt_handler(interrupt_signal=None): old_handler = "not installed from python" return warn("A non-default handler for signal %d is already installed (%s). " "Skipping pudb interrupt support." - % (interrupt_signal, old_handler)) + % (interrupt_signal, old_handler), + stacklevel=2) import threading if not isinstance(threading.current_thread(), threading._MainThread): from warnings import warn # Setting signals from a non-main thread will not work return warn("Setting the interrupt handler can only be done on the main " - "thread. The interrupt handler was NOT installed.") + "thread. The interrupt handler was NOT installed.", + stacklevel=2) try: signal.signal(interrupt_signal, _interrupt_handler) except ValueError: - from traceback import format_exception import sys + from traceback import format_exception from warnings import warn warn("setting interrupt handler on signal %d failed: %s" - % (interrupt_signal, "".join(format_exception(*sys.exc_info())))) + % (interrupt_signal, "".join(format_exception(*sys.exc_info()))), + stacklevel=2) def post_mortem(tb=None, e_type=None, e_value=None): @@ -325,7 +331,7 @@ def post_mortem(tb=None, e_type=None, e_value=None): def pm(): import sys - exc_type, exc_val, tb = sys.exc_info() + exc_type, _exc_val, _tb = sys.exc_info() if exc_type is None: # No exception on record. Do nothing. diff --git a/pudb/debugger.py b/pudb/debugger.py index dc48defc..a9f808f9 100644 --- a/pudb/debugger.py +++ b/pudb/debugger.py @@ -24,19 +24,20 @@ """ -import urwid import bdb import gc import os import sys - -from itertools import count -from functools import partial from collections import deque +from functools import partial +from itertools import count from types import TracebackType +import urwid + from pudb.lowlevel import decode_lines, ui_log -from pudb.settings import load_config, save_config, get_save_config_path +from pudb.settings import get_save_config_path, load_config, save_config + CONFIG = load_config() save_config(CONFIG) @@ -273,7 +274,7 @@ def set_trace(self, frame=None, as_breakpoint=None, paused=True): thisframe = frame # See pudb issue #52. If this works well enough we should upstream to # stdlib bdb.py. - #self.reset() + # self.reset() while frame: frame.f_trace = self.trace_dispatch @@ -537,7 +538,7 @@ def _runmodule(self, module_name): # This is basically stolen from the pdb._runmodule from CPython 3.8 # https://github.com/python/cpython/blob/a1d3be4623c8ec7069bd34ccdce336be9cdeb644/Lib/pdb.py#L1530 import runpy - mod_name, mod_spec, code = runpy._get_module_details(module_name) + _mod_name, mod_spec, code = runpy._get_module_details(module_name) self.mainpyfile = self.canonic(code.co_filename) import __main__ @@ -587,10 +588,14 @@ def runcall(self, *args, **kwargs): # UI stuff -------------------------------------------------------------------- from pudb.ui_tools import ( - make_hotkey_markup, labelled_value, - focus_widget_in_container, - SelectableText, SignalWrap, StackFrame, BreakpointFrame) - + BreakpointFrame, + SelectableText, + SignalWrap, + StackFrame, + focus_widget_in_container, + labelled_value, + make_hotkey_markup, +) from pudb.var_view import FrameVarInfoKeeper @@ -603,6 +608,8 @@ def runcall(self, *args, **kwargs): from urwid.display.raw import Screen as RawScreen + + try: from urwid.display.curses import Screen as CursesScreen except ImportError: @@ -1611,9 +1618,8 @@ def toggle_breakpoint(w, size, key): "(perhaps this is generated code)") def pick_module(w, size, key): - from os.path import splitext - import sys + from os.path import splitext def mod_exists(mod): if not hasattr(mod, "__file__"): @@ -1790,7 +1796,7 @@ def cmdline_tab_complete(w, size, key): return try: - from packaging.version import parse as LooseVersion # noqa: N812 + from packaging.version import parse as LooseVersion # noqa: N812 except ImportError: from distutils.version import LooseVersion @@ -2462,6 +2468,7 @@ def show_internal_exc_dlg(self, exc_tuple): def _show_internal_exc_dlg(self, exc_tuple): from traceback import format_exception + from pudb import VERSION desc = ( @@ -2949,7 +2956,7 @@ def _get_bp_list(self): if not bp.temporary] def _format_fname(self, fname): - from os.path import dirname, basename + from os.path import basename, dirname name = basename(fname) if name == "__init__.py": diff --git a/pudb/forked.py b/pudb/forked.py index d8ac88ad..725d7447 100644 --- a/pudb/forked.py +++ b/pudb/forked.py @@ -1,5 +1,5 @@ -import sys import os +import sys from pudb.debugger import Debugger diff --git a/pudb/ipython.py b/pudb/ipython.py index 0b7ff545..40929193 100644 --- a/pudb/ipython.py +++ b/pudb/ipython.py @@ -1,8 +1,8 @@ -import sys import os +import sys -from IPython.core.magic import register_line_magic from IPython import get_ipython +from IPython.core.magic import register_line_magic def pudb(line): diff --git a/pudb/lowlevel.py b/pudb/lowlevel.py index f13886f6..8064fb0b 100644 --- a/pudb/lowlevel.py +++ b/pudb/lowlevel.py @@ -24,10 +24,11 @@ """ -import sys import logging +import sys from datetime import datetime + logfile = [None] @@ -50,7 +51,7 @@ class TerminalOrStreamHandler(logging.StreamHandler): stderr, depending on whether the debugger is active. """ def emit(self, record): - from pudb import _have_debugger, _get_debugger + from pudb import _get_debugger, _have_debugger logfile = getlogfile() self.acquire() @@ -171,7 +172,7 @@ def lookup_module(filename): f = os.path.join(sys.path[0], filename) if os.path.exists(f): # and self.canonic(f) == self.mainpyfile: return f - root, ext = os.path.splitext(filename) + _root, ext = os.path.splitext(filename) if ext == "": filename = filename + ".py" if os.path.isabs(filename): @@ -191,8 +192,10 @@ def lookup_module(filename): # the main idea stolen from Python 3.1's tokenize.py, by Ka-Ping Yee import re + + cookie_re = re.compile(br"^\s*#.*coding[:=]\s*([-\w.]+)") -from codecs import lookup, BOM_UTF8 +from codecs import BOM_UTF8, lookup def detect_encoding(line_iter): @@ -232,9 +235,9 @@ def find_cookie(line): encoding = matches[0].decode() try: codec = lookup(encoding) - except LookupError: + except LookupError as err: # This behaviour mimics the Python interpreter - raise SyntaxError("unknown encoding: " + encoding) + raise SyntaxError("unknown encoding: " + encoding) from err if bom_found and codec.name != "utf-8": # This behaviour mimics the Python interpreter diff --git a/pudb/remote.py b/pudb/remote.py index 5602e45a..170cd0f0 100644 --- a/pudb/remote.py +++ b/pudb/remote.py @@ -36,15 +36,16 @@ # mostly stolen from celery.contrib.rdb +import atexit import errno import os import socket import sys -import atexit -from typing import Callable, Any +from typing import Any, Callable from pudb.debugger import Debugger + __all__ = ["PUDB_RDB_HOST", "PUDB_RDB_PORT", "PUDB_RDB_REVERSE", "default_port", "debugger", "set_trace", "debug_remote_on_single_rank"] @@ -208,7 +209,7 @@ def get_reverse_socket_client(self, host, port): _sock.setblocking(1) except OSError as exc: if exc.errno == errno.ECONNREFUSED: - raise ValueError(CONN_REFUSED.format(self=self)) + raise ValueError(CONN_REFUSED.format(self=self)) from exc raise exc return _sock, _sock.getpeername() diff --git a/pudb/run.py b/pudb/run.py index a632d42a..7eb5c5af 100644 --- a/pudb/run.py +++ b/pudb/run.py @@ -19,9 +19,9 @@ def get_argparse_parser(): + import argparse import os import sys - import argparse try: import shtab except ImportError: diff --git a/pudb/settings.py b/pudb/settings.py index d4ab9923..a0be468a 100644 --- a/pudb/settings.py +++ b/pudb/settings.py @@ -25,10 +25,10 @@ import os import sys - from configparser import ConfigParser -from pudb.lowlevel import (lookup_module, get_breakpoint_invalid_reason, - settings_log) + +from pudb.lowlevel import get_breakpoint_invalid_reason, lookup_module, settings_log + # see https://github.com/inducer/pudb/pull/453 for context _home = os.environ.get("HOME", os.path.expanduser("~")) @@ -71,7 +71,7 @@ def load_config(): if _config_[0] is not None: return _config_[0] - from os.path import join, isdir + from os.path import isdir, join cparser = ConfigParser() @@ -574,7 +574,7 @@ def load_breakpoints(): Loads and check saved breakpoints out from files Returns: list of tuples """ - from os.path import join, isdir + from os.path import isdir, join file_names = [] for cdir in XDG_CONFIG_DIRS: diff --git a/pudb/shell.py b/pudb/shell.py index 6df6eec9..8da549be 100644 --- a/pudb/shell.py +++ b/pudb/shell.py @@ -3,7 +3,7 @@ # Access a property to verify module exists in case # there's a demand loader wrapping module imports # See https://github.com/inducer/pudb/issues/177 - bpython.__version__ + bpython.__version__ # noqa: B018 except ImportError: HAVE_BPYTHON = False else: @@ -78,8 +78,9 @@ def run_classic_shell(globals, locals, message=""): ns = SetPropagatingDict([locals, globals], locals) - from pudb.settings import get_save_config_path from os.path import join + + from pudb.settings import get_save_config_path hist_file = join( get_save_config_path(), "shell-history") @@ -130,7 +131,7 @@ def have_ipython(): # Access a property to verify module exists in case # there's a demand loader wrapping module imports # See https://github.com/inducer/pudb/issues/177 - IPython.core + IPython.core # noqa: B018 except (ImportError, ValueError): # Old IPythons versions (0.12?) may fail to import with # ValueError: fallback required, but not specified @@ -199,8 +200,7 @@ def run_ipython_shell_v11(globals, locals): from IPython.terminal.interactiveshell import TerminalInteractiveShell from IPython.terminal.ipapp import load_default_config except ImportError: - from IPython.frontend.terminal.interactiveshell import \ - TerminalInteractiveShell + from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell from IPython.frontend.terminal.ipapp import load_default_config # XXX: in the future it could be useful to load a 'pudb' config for the # user (if it exists) that could contain the user's macros and other @@ -262,8 +262,10 @@ class DummyMod: def get_ptpython_history_file(): from argparse import ArgumentParser + from ptpython.entry_points.run_ptpython import ( # pylint: disable=import-error - get_config_and_history_file) + get_config_and_history_file, + ) parser = ArgumentParser() parser.add_argument("--history_file") parser.add_argument("--config_file") diff --git a/pudb/source_view.py b/pudb/source_view.py index 4c255154..026ddfef 100644 --- a/pudb/source_view.py +++ b/pudb/source_view.py @@ -224,10 +224,10 @@ def format_source(debugger_ui, lines, breakpoints): for i, line in enumerate(lines) ] else: + import pygments.token as t from pygments import highlight - from pygments.lexers import PythonLexer from pygments.formatter import Formatter - import pygments.token as t + from pygments.lexers import PythonLexer argument_parser = ArgumentParser(t) diff --git a/pudb/test/test_lowlevel.py b/pudb/test/test_lowlevel.py index d6233a18..f7b0a278 100644 --- a/pudb/test/test_lowlevel.py +++ b/pudb/test/test_lowlevel.py @@ -1,6 +1,6 @@ import sys -from pudb.lowlevel import detect_encoding, decode_lines +from pudb.lowlevel import decode_lines, detect_encoding def test_detect_encoding_nocookie(): diff --git a/pudb/test/test_run.py b/pudb/test/test_run.py index 8ae6cd92..ddbb0c44 100644 --- a/pudb/test/test_run.py +++ b/pudb/test/test_run.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 import os + import pytest from pudb.run import main diff --git a/pudb/test/test_settings.py b/pudb/test/test_settings.py index a29a9561..ada5d244 100644 --- a/pudb/test/test_settings.py +++ b/pudb/test/test_settings.py @@ -1,5 +1,5 @@ -import collections import builtins +import collections import pytest # noqa: F401 diff --git a/pudb/test/test_source_code_providers.py b/pudb/test/test_source_code_providers.py index c1bb06d5..f154e495 100644 --- a/pudb/test/test_source_code_providers.py +++ b/pudb/test/test_source_code_providers.py @@ -1,7 +1,10 @@ import pytest # noqa: F401 from pudb.debugger import ( - NullSourceCodeProvider, FileSourceCodeProvider, DirectSourceCodeProvider) + DirectSourceCodeProvider, + FileSourceCodeProvider, + NullSourceCodeProvider, +) from pudb.source_view import SourceLine diff --git a/pudb/test/test_var_view.py b/pudb/test/test_var_view.py index e263a3a9..fe308f94 100644 --- a/pudb/test/test_var_view.py +++ b/pudb/test/test_var_view.py @@ -4,13 +4,13 @@ import unittest from pudb.var_view import ( + STRINGIFIERS, BasicValueWalker, FrameVarInfo, InspectInfo, PudbCollection, PudbMapping, PudbSequence, - STRINGIFIERS, ValueWalker, get_stringifier, ui_log, @@ -102,7 +102,7 @@ def method(self, *args, **kwargs): # sort of case. Frustrating, I know. if (method_name == "__getitem__" and args and isinstance(args[0], int)): - raise IndexError + raise IndexError from None raise return method @@ -324,8 +324,8 @@ def test_dict(self): self.assert_walks_contents({ 0: 42, "a": "foo", - "": None, - True: False, + "": None, + True: False, frozenset(range(3)): "abc", (): "empty tuple", (1, 2, "c", ()): "tuple", diff --git a/pudb/theme.py b/pudb/theme.py index 7bfa356c..54365fc7 100644 --- a/pudb/theme.py +++ b/pudb/theme.py @@ -76,11 +76,11 @@ def handle_256_colors(self): # {{{ style inheritance BASE_STYLES = { - "background": None, - "selectable": None, + "background": None, + "selectable": None, "focused selectable": None, - "highlighted": None, - "hotkey": None, + "highlighted": None, + "hotkey": None, } diff --git a/pudb/themes/__init__.py b/pudb/themes/__init__.py index eb462eb8..b395ff3d 100644 --- a/pudb/themes/__init__.py +++ b/pudb/themes/__init__.py @@ -1,6 +1,5 @@ -from .classic import palette_dict as classic from .agr_256 import palette_dict as agr256 -from .solarized import palette_dict as solarized +from .classic import palette_dict as classic from .dark_vim import palette_dict as darkvim from .gray_light_256 import palette_dict as graylight256 from .midnight import palette_dict as midnight @@ -8,8 +7,10 @@ from .monokai import palette_dict as monokai from .monokai_256 import palette_dict as monokai256 from .nord_dark_256 import palette_dict as norddark256 +from .solarized import palette_dict as solarized from .vim import palette_dict as vim + THEMES = { "classic": classic, "vim": vim, diff --git a/pudb/themes/agr_256.py b/pudb/themes/agr_256.py index e16cc67b..17f89734 100644 --- a/pudb/themes/agr_256.py +++ b/pudb/themes/agr_256.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting, link + # Give the colors some comprehensible names black = "h235" blacker = "h233" diff --git a/pudb/themes/classic.py b/pudb/themes/classic.py index b1c584e8..e0d25aa7 100644 --- a/pudb/themes/classic.py +++ b/pudb/themes/classic.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting, link + link("current breakpoint", "current frame name") link("focused current breakpoint", "focused current frame name") diff --git a/pudb/themes/dark_vim.py b/pudb/themes/dark_vim.py index bc403da6..aca209f2 100644 --- a/pudb/themes/dark_vim.py +++ b/pudb/themes/dark_vim.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting, link + link("current breakpoint", "current frame name") link("focused current breakpoint", "focused current frame name") diff --git a/pudb/themes/gray_light_256.py b/pudb/themes/gray_light_256.py index 13f4468c..94225806 100644 --- a/pudb/themes/gray_light_256.py +++ b/pudb/themes/gray_light_256.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting + palette_dict = { # {{{ base styles "background": ("h232", "h248"), diff --git a/pudb/themes/midnight.py b/pudb/themes/midnight.py index 944ea171..02f548a7 100644 --- a/pudb/themes/midnight.py +++ b/pudb/themes/midnight.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting, link + # Based on XCode's midnight theme # Looks best in a console with green text against black background link("current breakpoint", "current frame name") diff --git a/pudb/themes/monokai.py b/pudb/themes/monokai.py index 13caeb36..57c21b87 100644 --- a/pudb/themes/monokai.py +++ b/pudb/themes/monokai.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting, link + link("current breakpoint", "current frame name") link("focused current breakpoint", "focused current frame name") diff --git a/pudb/themes/monokai_256.py b/pudb/themes/monokai_256.py index 3dac7dbf..8a963647 100644 --- a/pudb/themes/monokai_256.py +++ b/pudb/themes/monokai_256.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting, link + # Give the colors some comprehensible names black = "h236" blacker = "h234" diff --git a/pudb/themes/nord_dark_256.py b/pudb/themes/nord_dark_256.py index 430b5391..b68b7c5e 100644 --- a/pudb/themes/nord_dark_256.py +++ b/pudb/themes/nord_dark_256.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting, link + # ------------------------------------------------------------------------------ # Colors are approximations of https://www.nordtheme.com/docs/colors-and-palettes # ------------------------------------------------------------------------------ diff --git a/pudb/themes/solarized.py b/pudb/themes/solarized.py index 1e6aa8f6..e1e6c1d0 100644 --- a/pudb/themes/solarized.py +++ b/pudb/themes/solarized.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting + palette_dict = { # {{{ base styles "background": ("light green", "light gray"), diff --git a/pudb/themes/vim.py b/pudb/themes/vim.py index f154d4a4..6186b89a 100644 --- a/pudb/themes/vim.py +++ b/pudb/themes/vim.py @@ -1,5 +1,6 @@ from pudb.themes.utils import add_setting, link + link("current breakpoint", "current frame name") link("focused current breakpoint", "focused current frame name") diff --git a/pudb/ui_tools.py b/pudb/ui_tools.py index 1b75a3b9..4bb90e2b 100644 --- a/pudb/ui_tools.py +++ b/pudb/ui_tools.py @@ -1,5 +1,5 @@ import urwid -from urwid import calc_width, calc_text_pos +from urwid import calc_text_pos, calc_width # generic urwid helpers ------------------------------------------------------- @@ -35,7 +35,7 @@ def make_canvas(txt, attr, maxcol, fill_attr=None): for line, line_attr in zip(txt, attr): # filter out zero-length attrs - line_attr = [(aname, l) for aname, l in line_attr if l > 0] + line_attr = [(aname, la) for aname, la in line_attr if la > 0] diff = maxcol - text_width(line) if diff > 0: diff --git a/pudb/var_view.py b/pudb/var_view.py index d330da3d..4048ed8c 100644 --- a/pudb/var_view.py +++ b/pudb/var_view.py @@ -26,16 +26,18 @@ # {{{ constants and imports -import urwid import inspect import warnings - from abc import ABC, abstractmethod from collections.abc import Callable, Sized -from typing import Tuple, List +from typing import List, Tuple + +import urwid + from pudb.lowlevel import ui_log from pudb.ui_tools import text_width + try: import numpy HAVE_NUMPY = 1 @@ -298,7 +300,7 @@ def render(self, size: Tuple[int], focus: bool = False) -> urwid.Canvas: extralabel_full, extralabel_rem = divmod( text_width(var_label[maxcol:]), maxcol) - totallen = sum([text_width(i) for i in text]) + totallen = sum(text_width(i) for i in text) labellen = ( len(self.prefix) # Padding of first line @@ -353,7 +355,7 @@ def render(self, size: Tuple[int], focus: bool = False) -> urwid.Canvas: attr = [[(apfx+"label", lprefix + text_width(self.var_label)), ]] # Ellipses to show text was cut off - #encoding = urwid.util.detected_encoding + # encoding = urwid.util.detected_encoding for i in range(len(text)): if text_width(text[i]) > maxcol: diff --git a/pyproject.toml b/pyproject.toml index c7dd997b..176f2b77 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,3 +1,39 @@ +[tool.ruff] +preview = true + +[tool.ruff.lint] +extend-select = [ + "B", # flake8-bugbear + "C", # flake8-comprehensions + "E", # pycodestyle + "F", # pyflakes + "I", # flake8-isort + "N", # pep8-naming + "NPY", # numpy + "Q", # flake8-quotes + "W", # pycodestyle +] +extend-ignore = [ + "C90", # McCabe complexity + "E221", # multiple spaces before operator + "E226", # missing whitespace around arithmetic operator + "E241", # multiple spaces after comma + "E242", # tab after comma + "E402", # module level import not at the top of file + "N818", # error suffix in exception names +] +[tool.ruff.lint.flake8-quotes] +docstring-quotes = "double" +inline-quotes = "double" +multiline-quotes = "double" + +[tool.ruff.lint.isort] +combine-as-imports = true +known-local-folder = [ + "pudb", +] +lines-after-imports = 2 + [tool.pytest.ini_options] addopts = [ diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 4bfbb113..00000000 --- a/setup.cfg +++ /dev/null @@ -1,18 +0,0 @@ -[metadata] -project_urls = - Homepage=https://documen.tician.de/pudb/ - Source=https://github.com/inducer/pudb - Tracker=https://github.com/inducer/pudb/issues - -[flake8] -ignore = E126,E127,E128,E123,E226,E241,E242,E265,W503,E402 -max-line-length=85 - -inline-quotes = " -docstring-quotes = """ -multiline-quotes = """ - -# enable-flake8-bugbear - -[wheel] -universal = 0 diff --git a/setup.py b/setup.py index df3584f3..f79fe20f 100644 --- a/setup.py +++ b/setup.py @@ -1,8 +1,10 @@ #!/usr/bin/env python from setuptools import find_packages, setup + from pudb import VERSION + with open("README.rst") as readme: long_description = str(readme.read())