Skip to content

Commit 28bb96c

Browse files
authored
Add ruff fast linter and formatter (#1336)
* Add ruff fast linter and formatter in preparation for using it to replace black, isort, and flake8 * Fix mypy issue * Replace black, isort, and flake8 with ruff and remove former three * Fix typo in ruff linting * Removed a couple empty .format() calls
1 parent 3062aaa commit 28bb96c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+472
-258
lines changed

.github/CONTRIBUTING.md

Lines changed: 139 additions & 101 deletions
Large diffs are not rendered by default.

.github/workflows/format.yml

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
33
name: Format
44

5-
on: [push, pull_request]
5+
on: [ push, pull_request ]
66

77
permissions:
88
contents: read
@@ -11,8 +11,8 @@ jobs:
1111
lint:
1212
strategy:
1313
matrix:
14-
os: [ubuntu-latest]
15-
python-version: ["3.12"]
14+
os: [ ubuntu-latest ]
15+
python-version: [ "3.12" ]
1616
fail-fast: false
1717
runs-on: ${{ matrix.os }}
1818
steps:
@@ -26,8 +26,6 @@ jobs:
2626
with:
2727
python-version: ${{ matrix.python-version }}
2828
- name: Install python prerequisites
29-
run: pip install -U --user pip setuptools setuptools-scm black isort
30-
- name: Black
31-
run: python -m black --check --diff .
32-
- name: isort
33-
run: python -m isort --check-only .
29+
run: pip install -U --user ruff
30+
- name: Ruff format
31+
run: ruff format --check

.github/workflows/lint.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
33
name: Lint
44

5-
on: [push, pull_request]
5+
on: [ push, pull_request ]
66

77
permissions:
88
contents: read
@@ -11,8 +11,8 @@ jobs:
1111
lint:
1212
strategy:
1313
matrix:
14-
os: [ubuntu-latest]
15-
python-version: ["3.12"]
14+
os: [ ubuntu-latest ]
15+
python-version: [ "3.12" ]
1616
fail-fast: false
1717
runs-on: ${{ matrix.os }}
1818
steps:
@@ -26,6 +26,6 @@ jobs:
2626
with:
2727
python-version: ${{ matrix.python-version }}
2828
- name: Install python prerequisites
29-
run: pip install -U --user pip setuptools setuptools-scm nox
30-
- name: Lint
31-
run: python -m nox --non-interactive --session validate-${{ matrix.python-version }} -k flake8
29+
run: pip install -U --user ruff
30+
- name: Ruff lint
31+
run: ruff check

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,6 @@ Pipfile.lock
4343

4444
# pyenv version file
4545
.python-version
46+
47+
# uv
48+
uv.lock

Pipfile

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,15 @@ setuptools = ">=34.4"
99
wcwidth = ">=0.1.7"
1010

1111
[dev-packages]
12-
black = "*"
13-
cmd2 = {editable = true,path = "."}
14-
cmd2_ext_test = {editable = true,path = "plugins/ext_test"}
12+
cmd2 = { editable = true, path = "." }
13+
cmd2_ext_test = { editable = true, path = "plugins/ext_test" }
1514
codecov = "*"
1615
doc8 = "*"
17-
flake8 = "*"
18-
gnureadline = {version = "*",sys_platform = "== 'darwin'"}
16+
gnureadline = { version = "*", sys_platform = "== 'darwin'" }
1917
invoke = "*"
2018
ipython = "*"
21-
isort = "*"
2219
mypy = "*"
23-
pyreadline3 = {version = ">=3.4",sys_platform = "== 'win32'"}
20+
pyreadline3 = { version = ">=3.4", sys_platform = "== 'win32'" }
2421
pytest = "*"
2522
pytest-cov = "*"
2623
pytest-mock = "*"

cmd2/ansi.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
"""
33
Support for ANSI escape sequences which are used for things like applying style to text,
44
setting the window title, and asynchronous alerts.
5-
"""
5+
"""
6+
67
import functools
78
import re
89
from enum import (
@@ -62,25 +63,25 @@ def __repr__(self) -> str:
6263
"""
6364

6465
# Regular expression to match ANSI style sequence
65-
ANSI_STYLE_RE = re.compile(fr'{ESC}\[[^m]*m')
66+
ANSI_STYLE_RE = re.compile(rf'{ESC}\[[^m]*m')
6667

6768
# Matches standard foreground colors: CSI(30-37|90-97|39)m
68-
STD_FG_RE = re.compile(fr'{ESC}\[(?:[39][0-7]|39)m')
69+
STD_FG_RE = re.compile(rf'{ESC}\[(?:[39][0-7]|39)m')
6970

7071
# Matches standard background colors: CSI(40-47|100-107|49)m
71-
STD_BG_RE = re.compile(fr'{ESC}\[(?:(?:4|10)[0-7]|49)m')
72+
STD_BG_RE = re.compile(rf'{ESC}\[(?:(?:4|10)[0-7]|49)m')
7273

7374
# Matches eight-bit foreground colors: CSI38;5;(0-255)m
74-
EIGHT_BIT_FG_RE = re.compile(fr'{ESC}\[38;5;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])m')
75+
EIGHT_BIT_FG_RE = re.compile(rf'{ESC}\[38;5;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])m')
7576

7677
# Matches eight-bit background colors: CSI48;5;(0-255)m
77-
EIGHT_BIT_BG_RE = re.compile(fr'{ESC}\[48;5;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])m')
78+
EIGHT_BIT_BG_RE = re.compile(rf'{ESC}\[48;5;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])m')
7879

7980
# Matches RGB foreground colors: CSI38;2;(0-255);(0-255);(0-255)m
80-
RGB_FG_RE = re.compile(fr'{ESC}\[38;2(?:;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])){{3}}m')
81+
RGB_FG_RE = re.compile(rf'{ESC}\[38;2(?:;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])){{3}}m')
8182

8283
# Matches RGB background colors: CSI48;2;(0-255);(0-255);(0-255)m
83-
RGB_BG_RE = re.compile(fr'{ESC}\[48;2(?:;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])){{3}}m')
84+
RGB_BG_RE = re.compile(rf'{ESC}\[48;2(?:;(?:1?[0-9]?[0-9]?|2[0-4][0-9]|25[0-5])){{3}}m')
8485

8586

8687
def strip_style(text: str) -> str:

cmd2/argparse_completer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def _looks_like_flag(token: str, parser: argparse.ArgumentParser) -> bool:
9292
return False
9393

9494
# Flags have to start with a prefix character
95-
if not token[0] in parser.prefix_chars:
95+
if token[0] not in parser.prefix_chars:
9696
return False
9797

9898
# If it looks like a negative number, it is not a flag unless there are negative-number-like flags

cmd2/clipboard.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""
33
This module provides basic ability to copy from and paste to the clipboard/pastebuffer.
44
"""
5+
56
import typing
67

78
import pyperclip # type: ignore[import]

cmd2/cmd2.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
2222
Git repository on GitHub at https://github.com/python-cmd2/cmd2
2323
"""
24+
2425
# This module has many imports, quite a few of which are only
2526
# infrequently utilized. To reduce the initial overhead of
2627
# import this module, many of these imports are lazy-loaded
@@ -2019,9 +2020,8 @@ def _determine_ap_completer_type(parser: argparse.ArgumentParser) -> Type[argpar
20192020
:param parser: the parser to examine
20202021
:return: type of ArgparseCompleter
20212022
"""
2022-
completer_type: Optional[
2023-
Type[argparse_completer.ArgparseCompleter]
2024-
] = parser.get_ap_completer_type() # type: ignore[attr-defined]
2023+
Completer = Optional[Type[argparse_completer.ArgparseCompleter]]
2024+
completer_type: Completer = parser.get_ap_completer_type() # type: ignore[attr-defined]
20252025

20262026
if completer_type is None:
20272027
completer_type = argparse_completer.DEFAULT_AP_COMPLETER
@@ -5537,7 +5537,7 @@ def cmdloop(self, intro: Optional[str] = None) -> int: # type: ignore[override]
55375537
"""
55385538
# cmdloop() expects to be run in the main thread to support extensive use of KeyboardInterrupts throughout the
55395539
# other built-in functions. You are free to override cmdloop, but much of cmd2's features will be limited.
5540-
if not threading.current_thread() is threading.main_thread():
5540+
if threading.current_thread() is not threading.main_thread():
55415541
raise RuntimeError("cmdloop must be run in the main thread")
55425542

55435543
# Register signal handlers

cmd2/command_definition.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""
33
Supports the definition of commands in separate classes to be composed into cmd2.Cmd
44
"""
5+
56
from typing import (
67
TYPE_CHECKING,
78
Callable,

cmd2/decorators.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# coding=utf-8
22
"""Decorators for ``cmd2`` commands"""
3+
34
import argparse
45
from typing import (
56
TYPE_CHECKING,

cmd2/plugin.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#
22
# coding=utf-8
33
"""Classes for the cmd2 plugin system"""
4+
45
from dataclasses import (
56
dataclass,
67
)

cmd2/rl_utils.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""
33
Imports the proper Readline for the platform and provides utility functions for it
44
"""
5+
56
import sys
67
from enum import (
78
Enum,

cmd2/table_creator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
The general use case is to inherit from TableCreator to create a table class with custom formatting options.
66
There are already implemented and ready-to-use examples of this below TableCreator's code.
77
"""
8+
89
import copy
910
import io
1011
from collections import (

cmd2/transcript.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
This file contains the class necessary to make that work. This
1010
class is used in cmd2.py::run_transcript_tests()
1111
"""
12+
1213
import re
1314
import unittest
1415
from typing import (

cmd2/utils.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# coding=utf-8
22
"""Shared utility functions"""
3+
34
import argparse
45
import collections
56
import functools
@@ -157,7 +158,7 @@ def __init__(
157158
:param choices_provider: function that provides choices for this argument
158159
:param completer: tab completion function that provides choices for this argument
159160
"""
160-
if val_type == bool:
161+
if val_type is bool:
161162

162163
def get_bool_choices(_) -> List[str]: # type: ignore[no-untyped-def]
163164
"""Used to tab complete lowercase boolean values"""
@@ -1189,9 +1190,7 @@ def get_defining_class(meth: Callable[..., Any]) -> Optional[Type[Any]]:
11891190
if isinstance(meth, functools.partial):
11901191
return get_defining_class(meth.func)
11911192
if inspect.ismethod(meth) or (
1192-
inspect.isbuiltin(meth)
1193-
and getattr(meth, '__self__') is not None
1194-
and getattr(meth.__self__, '__class__') # type: ignore[attr-defined]
1193+
inspect.isbuiltin(meth) and getattr(meth, '__self__') is not None and getattr(meth.__self__, '__class__')
11951194
):
11961195
for cls in inspect.getmro(meth.__self__.__class__): # type: ignore[attr-defined]
11971196
if meth.__name__ in cls.__dict__:

examples/alias_startup.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
#!/usr/bin/env python
22
# coding=utf-8
33
"""A simple example demonstrating the following:
4-
1) How to add custom command aliases using the alias command
5-
2) How to run an initialization script at startup
4+
1) How to add custom command aliases using the alias command
5+
2) How to run an initialization script at startup
66
"""
7+
78
import os
89

910
import cmd2

examples/arg_decorators.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22
# coding=utf-8
33
"""An example demonstrating how use one of cmd2's argument parsing decorators"""
4+
45
import argparse
56
import os
67

examples/argparse_completion.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
A simple example demonstrating how to integrate tab completion with argparse-based commands.
55
"""
6+
67
import argparse
78
from typing import (
89
Dict,

examples/async_printing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
A simple example demonstrating an application that asynchronously prints alerts, updates the prompt
55
and changes the window title
66
"""
7+
78
import random
89
import threading
910
import time

examples/basic.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
#!/usr/bin/env python3
22
# coding=utf-8
33
"""A simple example demonstrating the following:
4-
1) How to add a command
5-
2) How to add help for that command
6-
3) Persistent history
7-
4) How to run an initialization script at startup
8-
5) How to add custom command aliases using the alias command
9-
6) Shell-like capabilities
4+
1) How to add a command
5+
2) How to add help for that command
6+
3) Persistent history
7+
4) How to run an initialization script at startup
8+
5) How to add custom command aliases using the alias command
9+
6) Shell-like capabilities
1010
"""
11+
1112
import cmd2
1213
from cmd2 import (
1314
Bg,

examples/basic_completion.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
familiar with argparse. The recommended approach for tab completing positional tokens and flags is to use
1313
argparse-based completion. For an example integrating tab completion with argparse, see argparse_completion.py
1414
"""
15+
1516
import functools
1617
from typing import (
1718
List,

examples/custom_parser.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"""
33
Defines the CustomParser used with override_parser.py example
44
"""
5+
56
import sys
67

78
from cmd2 import (

examples/decorator_example.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
all the commands in the transcript against decorator_example.py,
1111
verifying that the output produced matches the transcript.
1212
"""
13+
1314
import argparse
1415
from typing import (
1516
List,

examples/dynamic_commands.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python3
22
# coding=utf-8
3-
"""A simple example demonstrating how do_* commands can be created in a loop.
4-
"""
3+
"""A simple example demonstrating how do_* commands can be created in a loop."""
4+
55
import functools
66

77
import cmd2

examples/environment.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
A sample application for cmd2 demonstrating customized environment parameters
55
"""
6+
67
import cmd2
78

89

examples/event_loops.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
77
This opens up the possibility of registering cmd2 input with event loops, like asyncio, without occupying the main loop.
88
"""
9+
910
import cmd2
1011

1112

examples/example.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
the transcript against example.py, verifying that the output produced matches
1111
the transcript.
1212
"""
13+
1314
import random
1415

1516
import cmd2

examples/exit_code.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22
# coding=utf-8
3-
"""A simple example demonstrating the following how to emit a non-zero exit code in your cmd2 application.
4-
"""
3+
"""A simple example demonstrating the following how to emit a non-zero exit code in your cmd2 application."""
4+
55
from typing import (
66
List,
77
)

examples/hello_cmd2.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"""
44
This is intended to be a completely bare-bones cmd2 application suitable for rapid testing and debugging.
55
"""
6+
67
from cmd2 import (
78
cmd2,
89
)

examples/help_categories.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
66
It also demonstrates the effects of decorator order when it comes to argparse errors occurring.
77
"""
8+
89
import functools
910

1011
import cmd2

0 commit comments

Comments
 (0)