Skip to content

Commit

Permalink
ENH: automatically update pyright hook (#326)
Browse files Browse the repository at this point in the history
* MAINT: write unit tests for `pyright` module
  • Loading branch information
redeboer authored Mar 13, 2024
1 parent d7f772b commit 7133ea5
Show file tree
Hide file tree
Showing 10 changed files with 140 additions and 9 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@
"prettierrc",
"pyenv",
"pyright",
"pyrightconfig",
"pyupgrade",
"redeboer",
"repos",
Expand Down
4 changes: 3 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@
"src/compwa_policy/.github/workflows/release-drafter.yml": true,
"src/compwa_policy/.template/.gitpod.yml": true,
"src/compwa_policy/.template/.prettierrc": true,
"tests/**/.pre-commit-config*.yaml": true
"tests/**/.pre-commit-config*.yaml": true,
"tests/**/pyproject*.toml": true,
"tests/**/pyrightconfig*.json": true
},
"telemetry.telemetryLevel": "off",
"yaml.schemas": {
Expand Down
2 changes: 1 addition & 1 deletion src/compwa_policy/check_dev_files/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def main(argv: Sequence[str] | None = None) -> int:
github_pages=args.github_pages,
)
do(mypy.main)
do(pyright.main)
do(pyright.main, precommit_config)
do(pytest.main)
do(pyupgrade.main, precommit_config, args.no_ruff)
if not args.no_ruff:
Expand Down
45 changes: 38 additions & 7 deletions src/compwa_policy/check_dev_files/pyright.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,34 @@

import json
import os
from pathlib import Path
from typing import TYPE_CHECKING

from compwa_policy.utilities.pyproject import ModifiablePyproject, complies_with_subset
from compwa_policy.utilities.precommit.struct import Hook, Repo
from compwa_policy.utilities.pyproject import (
ModifiablePyproject,
Pyproject,
complies_with_subset,
)
from compwa_policy.utilities.toml import to_toml_array

if TYPE_CHECKING:
from compwa_policy.utilities.precommit import ModifiablePrecommit

def main() -> None:

def main(precommit: ModifiablePrecommit) -> None:
with ModifiablePyproject.load() as pyproject:
_merge_config_into_pyproject(pyproject)
_update_precommit(precommit, pyproject)
_update_settings(pyproject)


def _merge_config_into_pyproject(pyproject: ModifiablePyproject) -> None:
old_config_path = "pyrightconfig.json" # cspell:ignore pyrightconfig
def _merge_config_into_pyproject(
pyproject: ModifiablePyproject,
path: Path = Path("pyrightconfig.json"),
remove: bool = True,
) -> None:
old_config_path = path
if not os.path.exists(old_config_path):
return
with open(old_config_path) as stream:
Expand All @@ -26,14 +41,25 @@ def _merge_config_into_pyproject(pyproject: ModifiablePyproject) -> None:
existing_config[key] = to_toml_array(sorted(value))
tool_table = pyproject.get_table("tool.pyright", create=True)
tool_table.update(existing_config)
os.remove(old_config_path)
if remove:
os.remove(old_config_path)
msg = f"Imported pyright configuration from {old_config_path}"
pyproject.append_to_changelog(msg)


def _update_precommit(precommit: ModifiablePrecommit, pyproject: Pyproject) -> None:
if not __has_pyright(pyproject):
return
repo = Repo(
repo="https://github.com/ComPWA/mirrors-pyright",
rev="",
hooks=[Hook(id="pyright")],
)
precommit.update_single_hook_repo(repo)


def _update_settings(pyproject: ModifiablePyproject) -> None:
table_key = "tool.pyright"
if not pyproject.has_table(table_key):
if not __has_pyright(pyproject):
return
pyright_settings = pyproject.get_table("tool.pyright")
minimal_settings = {
Expand All @@ -43,3 +69,8 @@ def _update_settings(pyproject: ModifiablePyproject) -> None:
pyright_settings.update(minimal_settings)
msg = "Updated pyright configuration"
pyproject.append_to_changelog(msg)


def __has_pyright(pyproject: Pyproject) -> bool:
table_key = "tool.pyright"
return pyproject.has_table(table_key)
4 changes: 4 additions & 0 deletions tests/check_dev_files/pyright/.pre-commit-config-bad.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
repos:
- repo: meta
hooks:
- id: check-hooks-apply
9 changes: 9 additions & 0 deletions tests/check_dev_files/pyright/.pre-commit-config-good.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
repos:
- repo: meta
hooks:
- id: check-hooks-apply

- repo: https://github.com/ComPWA/mirrors-pyright
rev: PLEASE-UPDATE
hooks:
- id: pyright
Empty file.
3 changes: 3 additions & 0 deletions tests/check_dev_files/pyright/pyproject-bad.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[tool.pyright]
include = ["**/*.py"]
reportUnusedImport = true
7 changes: 7 additions & 0 deletions tests/check_dev_files/pyright/pyrightconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"include": ["src/**/*.py"],
"exclude": ["tests/**/*.py"],
"pythonVersion": "3.9",
"reportMissingTypeStubs": false,
"reportMissingImports": true
}
74 changes: 74 additions & 0 deletions tests/check_dev_files/pyright/test_pyright.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import io
import re
from pathlib import Path
from textwrap import dedent

import pytest

from compwa_policy.check_dev_files.pyright import (
_merge_config_into_pyproject,
_update_precommit,
_update_settings,
)
from compwa_policy.errors import PrecommitError
from compwa_policy.utilities.precommit import ModifiablePrecommit
from compwa_policy.utilities.pyproject import ModifiablePyproject, Pyproject


@pytest.fixture
def this_dir() -> Path:
return Path(__file__).parent


def test_merge_config_into_pyproject(this_dir: Path):
input_stream = io.StringIO()
old_config_path = this_dir / "pyrightconfig.json"
with pytest.raises(
PrecommitError,
match=re.escape(f"Imported pyright configuration from {old_config_path}"),
), ModifiablePyproject.load(input_stream) as pyproject:
_merge_config_into_pyproject(pyproject, old_config_path, remove=False)

result = input_stream.getvalue()
expected_result = dedent("""
[tool.pyright]
include = ["src/**/*.py"]
exclude = ["tests/**/*.py"]
pythonVersion = "3.9"
reportMissingTypeStubs = false
reportMissingImports = true
""")
assert result.strip() == expected_result.strip()


def test_update_precommit(this_dir: Path):
pyproject = Pyproject.load(this_dir / "pyproject-bad.toml")
with open(this_dir / ".pre-commit-config-bad.yaml") as stream:
input_stream = io.StringIO(stream.read())
with pytest.raises(PrecommitError), ModifiablePrecommit.load(
input_stream
) as precommit:
_update_precommit(precommit, pyproject)

result = input_stream.getvalue()
with open(this_dir / ".pre-commit-config-good.yaml") as stream:
expected_result = stream.read()
assert result.strip() == expected_result.strip()


def test_update_settings(this_dir: Path):
with open(this_dir / "pyproject-bad.toml") as stream:
input_stream = io.StringIO(stream.read())
with pytest.raises(
PrecommitError, match=r"Updated pyright configuration"
), ModifiablePyproject.load(input_stream) as pyproject:
_update_settings(pyproject)

result = input_stream.getvalue()
expected_result = dedent("""
[tool.pyright]
include = ["**/*.py"]
reportUnusedImport = true
typeCheckingMode = "strict"
""")
assert result.strip() == expected_result.strip()

0 comments on commit 7133ea5

Please sign in to comment.