Add some ruff autofixes to CI (#10458)

This commit is contained in:
Alex Waygood
2023-07-20 13:41:52 +01:00
committed by GitHub
parent a04cb3b058
commit 79e092e133
8 changed files with 62 additions and 6 deletions

View File

@@ -26,6 +26,11 @@ repos:
hooks:
- id: isort
name: isort (python)
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.0.278 # must match requirements-tests.txt
hooks:
- id: ruff
args: [--exit-non-zero-on-fix]
- repo: https://github.com/pycqa/flake8
rev: 6.0.0 # must match requirements-tests.txt
hooks:

View File

@@ -29,7 +29,7 @@ it takes a bit longer. For more details, read below.
Typeshed runs continuous integration (CI) on all pull requests. This means that
if you file a pull request (PR), our full test suite -- including our linter,
`flake8` -- is run on your PR. It also means that bots will automatically apply
changes to your PR (using `pycln`, `black` and `isort`) to fix any formatting issues.
changes to your PR (using `pycln`, `black`, `isort` and `ruff`) to fix any formatting issues.
This frees you up to ignore all local setup on your side, focus on the
code and rely on the CI to fix everything, or point you to the places that
need fixing.
@@ -85,7 +85,7 @@ terminal to install all non-pytype requirements:
## Code formatting
The code is formatted using `black` and `isort`. Unused imports are also
auto-removed using `pycln`.
auto-removed using `pycln`, and various other autofixes are performed by `ruff`.
The repository is equipped with a [`pre-commit.ci`](https://pre-commit.ci/)
configuration file. This means that you don't *need* to do anything yourself to
@@ -93,11 +93,12 @@ run the code formatters. When you push a commit, a bot will run those for you
right away and add a commit to your PR.
That being said, if you *want* to run the checks locally when you commit,
you're free to do so. Either run `pycln`, `black` and `isort` manually...
you're free to do so. Either run `pycln`, `isort`, `black` and `ruff` manually...
```bash
$ pycln --config=pyproject.toml .
$ isort .
$ ruff .
$ black .
```

View File

@@ -57,6 +57,44 @@ extra_standard_library = [
]
known_first_party = ["utils", "parse_metadata"]
[tool.ruff]
line-length = 130
target-version = "py37"
fix = true
exclude = [
# We're only interested in autofixes for our stubs
"*.py",
# Ignore generated protobuf stubs
"*_pb2.pyi",
# virtual environment, cache directories, etc.:
"env",
".env",
".venv",
".git",
".mypy_cache",
".pytype",
]
# Only enable rules that have safe autofixes;
# only enable rules that are relevant to stubs
select = [
"UP004", # Remove explicit `object` inheritance
"UP006", # PEP-585 autofixes
"UP007", # PEP-604 autofixes
"UP013", # Class-based syntax for TypedDicts
"UP014", # Class-based syntax for NamedTuples
"UP019", # Use str over typing.Text
"UP035", # import from typing, not typing_extensions, wherever possible
"UP039", # don't use parens after a class definition with no bases
"PYI009", # use `...`, not `pass`, in empty class bodies
"PYI010", # function bodies must be empty
"PYI012", # class bodies must not contain `pass`
"PYI013", # non-empty class bodies must not contain `...`
"PYI020", # quoted annotations are always unnecessary in stubs
"PYI025", # always alias `collections.abc.Set` as `AbstractSet` when importing it
"PYI032", # use `object`, not `Any`, as the second parameter to `__eq__`
]
[tool.pycln]
all = true
disable_all_dunder_policy = true

View File

@@ -11,6 +11,7 @@ mypy==1.4.1
pre-commit-hooks==4.4.0 # must match .pre-commit-config.yaml
pycln==2.1.5 # must match .pre-commit-config.yaml
pytype==2023.6.16; platform_system != "Windows" and python_version < "3.11"
ruff==0.0.278 # must match .pre-commit-config.yaml
# Libraries used by our various scripts.
aiohttp==3.8.4; python_version < "3.12" # aiohttp can't be installed on 3.12 yet

View File

@@ -65,6 +65,11 @@ def run_isort(stub_dir: str) -> None:
subprocess.run([sys.executable, "-m", "isort", stub_dir])
def run_ruff(stub_dir: str) -> None:
print(f"Running ruff: ruff {stub_dir}")
subprocess.run([sys.executable, "-m", "ruff", stub_dir])
def create_metadata(stub_dir: str, version: str) -> None:
"""Create a METADATA.toml file."""
match = re.match(r"[0-9]+.[0-9]+", version)
@@ -110,7 +115,7 @@ def add_pyright_exclusion(stub_dir: str) -> None:
def main() -> None:
parser = argparse.ArgumentParser(
description="""Generate baseline stubs automatically for an installed pip package
using stubgen. Also run black and isort. If the name of
using stubgen. Also run black, isort and ruff. If the name of
the project is different from the runtime Python package name, you may
need to use --package (example: --package yaml PyYAML)."""
)
@@ -159,6 +164,7 @@ def main() -> None:
run_stubgen(package, stub_dir)
run_stubdefaulter(stub_dir)
run_ruff(stub_dir)
run_isort(stub_dir)
run_black(stub_dir)

View File

@@ -77,6 +77,8 @@ def main() -> None:
# Run formatters first. Order matters.
print("\nRunning pycln...")
subprocess.run([sys.executable, "-m", "pycln", path, "--config=pyproject.toml"])
print("\nRunning ruff...")
subprocess.run([sys.executable, "-m", "ruff", path])
print("\nRunning isort...")
subprocess.run([sys.executable, "-m", "isort", path])
print("\nRunning Black...")

View File

@@ -113,7 +113,7 @@ __all__ = [
_T = typing.TypeVar("_T")
_F = typing.TypeVar("_F", bound=Callable[..., Any])
_TC = typing.TypeVar("_TC", bound=Type[object])
_TC = typing.TypeVar("_TC", bound=type[object])
# unfortunately we have to duplicate this class definition from typing.pyi or we break pytype
class _SpecialForm:

View File

@@ -23,7 +23,7 @@ extension_descriptions = {".pyi": "stub", ".py": ".py"}
# These type checkers and linters must have exact versions in the requirements file to ensure
# consistent CI runs.
linters = {"black", "flake8", "flake8-bugbear", "flake8-noqa", "flake8-pyi", "isort", "mypy", "pycln", "pytype"}
linters = {"black", "flake8", "flake8-bugbear", "flake8-noqa", "flake8-pyi", "isort", "ruff", "mypy", "pycln", "pytype"}
def assert_consistent_filetypes(
@@ -191,6 +191,9 @@ def check_precommit_requirements() -> None:
precommit_requirements = get_precommit_requirements()
no_txt_entry_msg = "All pre-commit requirements must also be listed in `requirements-tests.txt` (missing {requirement!r})"
for requirement, specifier in precommit_requirements.items():
# annoying: the ruff repo for pre-commit is different to the name in requirements-tests.txt
if requirement == "ruff-pre-commit":
requirement = "ruff"
assert requirement in requirements_txt_requirements, no_txt_entry_msg.format(requirement=requirement)
specifier_mismatch = (
f'Specifier "{specifier}" for {requirement!r} in `.pre-commit-config.yaml` '