Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ruff fast linter and formatter #1336

Merged
merged 5 commits into from
Oct 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
240 changes: 139 additions & 101 deletions .github/CONTRIBUTING.md

Large diffs are not rendered by default.

14 changes: 6 additions & 8 deletions .github/workflows/format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
name: Format

on: [push, pull_request]
on: [ push, pull_request ]

permissions:
contents: read
Expand All @@ -11,8 +11,8 @@ jobs:
lint:
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.12"]
os: [ ubuntu-latest ]
python-version: [ "3.12" ]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -26,8 +26,6 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install python prerequisites
run: pip install -U --user pip setuptools setuptools-scm black isort
- name: Black
run: python -m black --check --diff .
- name: isort
run: python -m isort --check-only .
run: pip install -U --user ruff
- name: Ruff format
run: ruff format --check
12 changes: 6 additions & 6 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions
name: Lint

on: [push, pull_request]
on: [ push, pull_request ]

permissions:
contents: read
Expand All @@ -11,8 +11,8 @@ jobs:
lint:
strategy:
matrix:
os: [ubuntu-latest]
python-version: ["3.12"]
os: [ ubuntu-latest ]
python-version: [ "3.12" ]
fail-fast: false
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -26,6 +26,6 @@ jobs:
with:
python-version: ${{ matrix.python-version }}
- name: Install python prerequisites
run: pip install -U --user pip setuptools setuptools-scm nox
- name: Lint
run: python -m nox --non-interactive --session validate-${{ matrix.python-version }} -k flake8
run: pip install -U --user ruff
- name: Ruff lint
run: ruff check
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,6 @@ Pipfile.lock

# pyenv version file
.python-version

# uv
uv.lock
11 changes: 4 additions & 7 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@ setuptools = ">=34.4"
wcwidth = ">=0.1.7"

[dev-packages]
black = "*"
cmd2 = {editable = true,path = "."}
cmd2_ext_test = {editable = true,path = "plugins/ext_test"}
cmd2 = { editable = true, path = "." }
cmd2_ext_test = { editable = true, path = "plugins/ext_test" }
codecov = "*"
doc8 = "*"
flake8 = "*"
gnureadline = {version = "*",sys_platform = "== 'darwin'"}
gnureadline = { version = "*", sys_platform = "== 'darwin'" }
invoke = "*"
ipython = "*"
isort = "*"
mypy = "*"
pyreadline3 = {version = ">=3.4",sys_platform = "== 'win32'"}
pyreadline3 = { version = ">=3.4", sys_platform = "== 'win32'" }
pytest = "*"
pytest-cov = "*"
pytest-mock = "*"
Expand Down
17 changes: 9 additions & 8 deletions cmd2/ansi.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"""
Support for ANSI escape sequences which are used for things like applying style to text,
setting the window title, and asynchronous alerts.
"""
"""

import functools
import re
from enum import (
Expand Down Expand Up @@ -62,25 +63,25 @@ def __repr__(self) -> str:
"""

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

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

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

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

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

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

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


def strip_style(text: str) -> str:
Expand Down
2 changes: 1 addition & 1 deletion cmd2/argparse_completer.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def _looks_like_flag(token: str, parser: argparse.ArgumentParser) -> bool:
return False

# Flags have to start with a prefix character
if not token[0] in parser.prefix_chars:
if token[0] not in parser.prefix_chars:
return False

# If it looks like a negative number, it is not a flag unless there are negative-number-like flags
Expand Down
1 change: 1 addition & 0 deletions cmd2/clipboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
This module provides basic ability to copy from and paste to the clipboard/pastebuffer.
"""

import typing

import pyperclip # type: ignore[import]
Expand Down
8 changes: 4 additions & 4 deletions cmd2/cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

Git repository on GitHub at https://github.com/python-cmd2/cmd2
"""

# This module has many imports, quite a few of which are only
# infrequently utilized. To reduce the initial overhead of
# import this module, many of these imports are lazy-loaded
Expand Down Expand Up @@ -2019,9 +2020,8 @@ def _determine_ap_completer_type(parser: argparse.ArgumentParser) -> Type[argpar
:param parser: the parser to examine
:return: type of ArgparseCompleter
"""
completer_type: Optional[
Type[argparse_completer.ArgparseCompleter]
] = parser.get_ap_completer_type() # type: ignore[attr-defined]
Completer = Optional[Type[argparse_completer.ArgparseCompleter]]
completer_type: Completer = parser.get_ap_completer_type() # type: ignore[attr-defined]

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

# Register signal handlers
Expand Down
1 change: 1 addition & 0 deletions cmd2/command_definition.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
Supports the definition of commands in separate classes to be composed into cmd2.Cmd
"""

from typing import (
TYPE_CHECKING,
Callable,
Expand Down
1 change: 1 addition & 0 deletions cmd2/decorators.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# coding=utf-8
"""Decorators for ``cmd2`` commands"""

import argparse
from typing import (
TYPE_CHECKING,
Expand Down
1 change: 1 addition & 0 deletions cmd2/plugin.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#
# coding=utf-8
"""Classes for the cmd2 plugin system"""

from dataclasses import (
dataclass,
)
Expand Down
1 change: 1 addition & 0 deletions cmd2/rl_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
Imports the proper Readline for the platform and provides utility functions for it
"""

import sys
from enum import (
Enum,
Expand Down
1 change: 1 addition & 0 deletions cmd2/table_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
The general use case is to inherit from TableCreator to create a table class with custom formatting options.
There are already implemented and ready-to-use examples of this below TableCreator's code.
"""

import copy
import io
from collections import (
Expand Down
1 change: 1 addition & 0 deletions cmd2/transcript.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
This file contains the class necessary to make that work. This
class is used in cmd2.py::run_transcript_tests()
"""

import re
import unittest
from typing import (
Expand Down
7 changes: 3 additions & 4 deletions cmd2/utils.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# coding=utf-8
"""Shared utility functions"""

import argparse
import collections
import functools
Expand Down Expand Up @@ -157,7 +158,7 @@ def __init__(
:param choices_provider: function that provides choices for this argument
:param completer: tab completion function that provides choices for this argument
"""
if val_type == bool:
if val_type is bool:

def get_bool_choices(_) -> List[str]: # type: ignore[no-untyped-def]
"""Used to tab complete lowercase boolean values"""
Expand Down Expand Up @@ -1189,9 +1190,7 @@ def get_defining_class(meth: Callable[..., Any]) -> Optional[Type[Any]]:
if isinstance(meth, functools.partial):
return get_defining_class(meth.func)
if inspect.ismethod(meth) or (
inspect.isbuiltin(meth)
and getattr(meth, '__self__') is not None
and getattr(meth.__self__, '__class__') # type: ignore[attr-defined]
inspect.isbuiltin(meth) and getattr(meth, '__self__') is not None and getattr(meth.__self__, '__class__')
):
for cls in inspect.getmro(meth.__self__.__class__): # type: ignore[attr-defined]
if meth.__name__ in cls.__dict__:
Expand Down
5 changes: 3 additions & 2 deletions examples/alias_startup.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/usr/bin/env python
# coding=utf-8
"""A simple example demonstrating the following:
1) How to add custom command aliases using the alias command
2) How to run an initialization script at startup
1) How to add custom command aliases using the alias command
2) How to run an initialization script at startup
"""

import os

import cmd2
Expand Down
1 change: 1 addition & 0 deletions examples/arg_decorators.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
# coding=utf-8
"""An example demonstrating how use one of cmd2's argument parsing decorators"""

import argparse
import os

Expand Down
1 change: 1 addition & 0 deletions examples/argparse_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
A simple example demonstrating how to integrate tab completion with argparse-based commands.
"""

import argparse
from typing import (
Dict,
Expand Down
1 change: 1 addition & 0 deletions examples/async_printing.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
A simple example demonstrating an application that asynchronously prints alerts, updates the prompt
and changes the window title
"""

import random
import threading
import time
Expand Down
13 changes: 7 additions & 6 deletions examples/basic.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#!/usr/bin/env python3
# coding=utf-8
"""A simple example demonstrating the following:
1) How to add a command
2) How to add help for that command
3) Persistent history
4) How to run an initialization script at startup
5) How to add custom command aliases using the alias command
6) Shell-like capabilities
1) How to add a command
2) How to add help for that command
3) Persistent history
4) How to run an initialization script at startup
5) How to add custom command aliases using the alias command
6) Shell-like capabilities
"""

import cmd2
from cmd2 import (
Bg,
Expand Down
1 change: 1 addition & 0 deletions examples/basic_completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
familiar with argparse. The recommended approach for tab completing positional tokens and flags is to use
argparse-based completion. For an example integrating tab completion with argparse, see argparse_completion.py
"""

import functools
from typing import (
List,
Expand Down
1 change: 1 addition & 0 deletions examples/custom_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"""
Defines the CustomParser used with override_parser.py example
"""

import sys

from cmd2 import (
Expand Down
1 change: 1 addition & 0 deletions examples/decorator_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
all the commands in the transcript against decorator_example.py,
verifying that the output produced matches the transcript.
"""

import argparse
from typing import (
List,
Expand Down
4 changes: 2 additions & 2 deletions examples/dynamic_commands.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# coding=utf-8
"""A simple example demonstrating how do_* commands can be created in a loop.
"""
"""A simple example demonstrating how do_* commands can be created in a loop."""

import functools

import cmd2
Expand Down
1 change: 1 addition & 0 deletions examples/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
A sample application for cmd2 demonstrating customized environment parameters
"""

import cmd2


Expand Down
1 change: 1 addition & 0 deletions examples/event_loops.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

This opens up the possibility of registering cmd2 input with event loops, like asyncio, without occupying the main loop.
"""

import cmd2


Expand Down
1 change: 1 addition & 0 deletions examples/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
the transcript against example.py, verifying that the output produced matches
the transcript.
"""

import random

import cmd2
Expand Down
4 changes: 2 additions & 2 deletions examples/exit_code.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python
# coding=utf-8
"""A simple example demonstrating the following how to emit a non-zero exit code in your cmd2 application.
"""
"""A simple example demonstrating the following how to emit a non-zero exit code in your cmd2 application."""

from typing import (
List,
)
Expand Down
1 change: 1 addition & 0 deletions examples/hello_cmd2.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
This is intended to be a completely bare-bones cmd2 application suitable for rapid testing and debugging.
"""

from cmd2 import (
cmd2,
)
Expand Down
1 change: 1 addition & 0 deletions examples/help_categories.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

It also demonstrates the effects of decorator order when it comes to argparse errors occurring.
"""

import functools

import cmd2
Expand Down
Loading
Loading