Skip to content

Commit

Permalink
Upgrade list of linters (#115)
Browse files Browse the repository at this point in the history
  • Loading branch information
ssbarnea authored Nov 18, 2024
1 parent f3fc277 commit ea9bb0f
Show file tree
Hide file tree
Showing 9 changed files with 153 additions and 99 deletions.
9 changes: 0 additions & 9 deletions .flake8

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,4 @@ dmypy.json

# Pyre type checker
.pyre/
src/tox_extra/_version.py
45 changes: 22 additions & 23 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,46 +1,45 @@
default_language_version:
# pylint is not yet compatible with py311
python: python3.10
repos:
- repo: https://github.com/pappasam/toml-sort
rev: v0.23.1
hooks:
- id: toml-sort-fix
- repo: https://github.com/pre-commit/mirrors-prettier
# keep it before markdownlint and eslint
rev: "v4.0.0-alpha.8"
hooks:
- id: prettier
- repo: https://github.com/PyCQA/isort
rev: 5.13.2
hooks:
- id: isort
- repo: https://github.com/psf/black
rev: 24.10.0
hooks:
- id: black
language_version: python3
- repo: https://github.com/pre-commit/pre-commit-hooks.git
rev: v5.0.0
hooks:
- id: end-of-file-fixer
- id: trailing-whitespace
- id: mixed-line-ending
- id: check-byte-order-marker
- id: fix-byte-order-marker
- id: check-executables-have-shebangs
- id: check-merge-conflict
- id: debug-statements
- repo: https://github.com/PyCQA/flake8
rev: 7.1.1
hooks:
- id: flake8

- repo: https://github.com/adrienverge/yamllint.git
rev: v1.35.1
hooks:
- id: yamllint
files: \.(yaml|yml)$
types: [file, yaml]
entry: yamllint --strict
- repo: https://github.com/pappasam/toml-sort
rev: v0.23.1
hooks:
- id: toml-sort-fix
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.7.3
hooks:
- id: ruff
args:
- --fix
- --exit-non-zero-on-fix
types_or: [python, pyi]
- id: ruff-format # must be after ruff
types_or: [python, pyi]
- repo: https://github.com/psf/black # must be after ruff
rev: 24.10.0
hooks:
- id: black
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.13.0
hooks:
Expand All @@ -54,8 +53,8 @@ repos:
- packaging
- py>=1.9.0
- tox>=4.23.2
- repo: https://github.com/pre-commit/mirrors-pylint
rev: v3.0.0a5
- repo: https://github.com/pycqa/pylint
rev: v3.3.1
hooks:
- id: pylint
additional_dependencies:
Expand Down
120 changes: 95 additions & 25 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
[build-system]
build-backend = "setuptools.build_meta"
requires = [
"setuptools >= 61.0",
"setuptools_scm[toml] >= 7.0.0"
"setuptools >= 65.3.0", # required by pyproject+setuptools_scm integration and editable installs
"setuptools_scm[toml] >= 7.0.5" # required for "no-local-version" scheme
]
build-backend = "setuptools.build_meta"

[project]
# https://peps.python.org/pep-0621/#readme
requires-python = ">=3.9"
dynamic = ["version"]
name = "tox-extra"
description = "Performs extra checks before or after running"
readme = "README.md"
authors = [
{"name" = "Sorin Sbarnea", "email" = "[email protected]"}
{"email" = "[email protected]", "name" = "Sorin Sbarnea"}
]
maintainers = [
{"name" = "Sorin Sbarnea", "email" = "[email protected]"}
]
license = {text = "MIT"}
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
Expand All @@ -33,13 +23,23 @@ classifiers = [
"Programming Language :: Python :: 3.13",
"Topic :: Software Development :: Testing"
]
keywords = ["git", "tox", "tox-plugin"]
dependencies = [
"bindep>2.8.1",
"gitpython",
"packaging",
"tox"
]
description = "Performs extra checks before or after running"
dynamic = ["version"]
keywords = ["git", "tox", "tox-plugin"]
license = {text = "MIT"}
maintainers = [
{"email" = "[email protected]", "name" = "Sorin Sbarnea"}
]
name = "tox-extra"
readme = "README.md"
# https://peps.python.org/pep-0621/#readme
requires-python = ">=3.9"

[project.entry-points.tox]
extra = "tox_extra.hooks"
Expand All @@ -53,37 +53,107 @@ test = [
]

[project.urls]
changelog = "https://github.com/tox-dev/tox-extra/releases"
homepage = "https://github.com/tox-dev/tox-extra"
issues = "https://github.com/tox-dev/tox-extra/issues"
repository = "https://github.com/tox-dev/tox-extra"
changelog = "https://github.com/tox-dev/tox-extra/releases"

[tool.coverage.paths]
source = ["src"]

[tool.coverage.report]
omit = [".tox/*/lib/python*/site-packages/*"]
fail_under = 92.0
include = ["src/*"]
fail_under = 100.0
skip_covered = true
omit = [".tox/*/lib/python*/site-packages/*", "src/*/_version.py"]
show_missing = true
skip_covered = true
skip_empty = true

[tool.coverage.run]
concurrency = ["multiprocessing", "thread"]
# Do not use branch until bug is fixes:
# https://github.com/nedbat/coveragepy/issues/605
# branch = true
parallel = true

[tool.isort]
profile = "black"
source = ["src"]

[tool.mypy]
python_version = 3.9
color_output = true
error_summary = true
disallow_any_generics = true
disallow_untyped_calls = true
disallow_untyped_defs = true
disallow_any_generics = true
error_summary = true
python_version = 3.9

[tool.pytest.ini_options]
# do not add options here as this will likely break either console runs or IDE
# integration like vscode or pycharm
addopts = "-ra --showlocals"

[tool.ruff]
cache-dir = "./.cache/.ruff"
fix = true
# Same as Black.
line-length = 88

[tool.ruff.lint]
ignore = [
"COM812", # conflicts with ISC001 on format
"D203", # incompatible with D211
"D213", # incompatible with D212
"E501", # we use black
"ERA001", # auto-removal of commented out code affects development and vscode integration
"INP001", # "is part of an implicit namespace package", all false positives
"ISC001", # conflicts with COM812 on format
"PLW2901", # PLW2901: Redefined loop variable
"RET504", # Unnecessary variable assignment before `return` statement
# temporary disabled until we fix them:
"ANN",
"ARG001",
"PTH109",
"PTH112",
"PTH113",
"PTH123",
"S603",
"S605",
"S607",
"SIM117",
"T201",
"UP022"
]
select = ["ALL"]

[tool.ruff.lint.flake8-builtins]
builtins-ignorelist = ["id"]

[tool.ruff.lint.flake8-pytest-style]
parametrize-values-type = "tuple"

[tool.ruff.lint.isort]
known-first-party = ["src"]

[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S"]

[tool.ruff.lint.pydocstyle]
convention = "google"

[tool.setuptools_scm]
# To prevent accidental pick of mobile version tags such 'v6'
git_describe_command = [
"git",
"describe",
"--dirty",
"--long",
"--tags",
"--match",
"v*.*"
]
local_scheme = "no-local-version"
tag_regex = "^(?P<prefix>v)?(?P<version>[0-9.]+)(?P<suffix>.*)?$"
write_to = "src/tox_extra/_version.py"

[tool.tomlsort]
in_place = true
sort_inline_tables = true
sort_table_keys = true
1 change: 1 addition & 0 deletions src/tox_extra/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"""Module docstring."""
37 changes: 9 additions & 28 deletions src/tox_extra/bindep.py
Original file line number Diff line number Diff line change
@@ -1,59 +1,40 @@
"""Bindep check feature implementations."""

from __future__ import print_function
from __future__ import annotations

import os
import subprocess
import sys
from functools import lru_cache
from pathlib import Path
from typing import Iterable, Optional
from functools import cache
from typing import TYPE_CHECKING

if sys.version_info >= (3, 9): # pragma: no cover
from functools import cache
else: # pragma: no cover
cache = lru_cache(maxsize=None)
if TYPE_CHECKING:
from collections.abc import Iterable
from pathlib import Path


@cache
def check_bindep(path: Path, profiles: Optional[Iterable[str]] = None) -> None:
def check_bindep(path: Path, profiles: Iterable[str] | None = None) -> None:
"""Check bindeps requirements or exit."""
if profiles is None: # pragma: no cover
profiles = []
if os.path.isfile(path / "bindep.txt"):
# as 'bindep --profiles' does not show user defined profiles like 'test'
# it makes no sense to list them.
cmd = [sys.executable, "-m", "bindep", "-b", *sorted(profiles)]
# # determine profiles
# result = subprocess.run(
# [sys.executable, "-m", "bindep", "--profiles"],
# check=False,
# universal_newlines=True,
# stdout=subprocess.PIPE,
# )
# if result.returncode:
# print("Bindep failed to list profiles: %s", result.stdout)
# sys.exit(result.returncode)
# lines = result.stdout.splitlines()
# try:
# profiles = lines[lines.index("Configuration profiles:") + 1 :]
# if "test" in profiles:
# cmd.append("test")
# except ValueError:
# pass

result = subprocess.run(
cmd,
check=False,
universal_newlines=True,
text=True,
stderr=subprocess.PIPE,
stdout=subprocess.PIPE,
cwd=path,
)
if result.returncode:
print(
f"Running '{' '.join(cmd)}' returned {result.returncode}, "
"likely missing system dependencies."
"likely missing system dependencies.",
)
if result.stdout:
print(result.stdout)
Expand Down
27 changes: 19 additions & 8 deletions src/tox_extra/hooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@
import os
import pathlib
import sys
from argparse import ArgumentParser
from typing import Any, List
from typing import TYPE_CHECKING, Any

import git
from tox.execute import Outcome
from tox.plugin import impl
from tox.tox_env.api import ToxEnv
from tox.tox_env.errors import Fail
from tox.tox_env.python.api import Python

from tox_extra.bindep import check_bindep

if TYPE_CHECKING:
from argparse import ArgumentParser

from tox.execute import Outcome
from tox.tox_env.api import ToxEnv


MSG_GIT_DIRTY = (
"exit code 1 due to 'git status -s' reporting dirty. "
"That should not happen regardless if status is passed, failed or aborted. "
Expand Down Expand Up @@ -57,7 +61,12 @@ def tox_add_option(parser: ArgumentParser) -> None:

@impl
# pylint: disable=unused-argument
def tox_on_install(tox_env: ToxEnv, arguments: Any, section: str, of_type: str) -> None:
def tox_on_install(
tox_env: ToxEnv,
arguments: Any,
section: str,
of_type: str,
) -> None:
"""Runs just before installing package."""
if os.environ.get("TOX_EXTRA_BINDEP", "1") != "0":
profiles = {
Expand All @@ -68,16 +77,18 @@ def tox_on_install(tox_env: ToxEnv, arguments: Any, section: str, of_type: str)
if isinstance(tox_env, Python):
profiles.add(f"python{tox_env.py_dot_ver()}") # python3.12 like profile
profiles.add(
f"py{tox_env.py_dot_ver().replace('.', '')}"
) # py312 like profile # type: ignore
f"py{tox_env.py_dot_ver().replace('.', '')}",
) # py312 like profile

check_bindep(path=pathlib.Path.cwd(), profiles=frozenset(profiles))


@impl
# pylint: disable=unused-argument
def tox_after_run_commands(
tox_env: ToxEnv, exit_code: int, outcomes: List[Outcome]
tox_env: ToxEnv,
exit_code: int,
outcomes: list[Outcome],
) -> None:
"""Hook that runs after test commands."""
allow_dirty = getattr(tox_env.options, "allow_dirty", False)
Expand Down
Loading

0 comments on commit ea9bb0f

Please sign in to comment.