diff --git a/.circleci/prepare.sh b/.circleci/prepare.sh index 9e18a7de..991f0202 100644 --- a/.circleci/prepare.sh +++ b/.circleci/prepare.sh @@ -1,9 +1,10 @@ +#!/usr/bin/env bash set -o errexit set -o xtrace $PYTHON --version $PYTHON -m pip --version -$PYTHON -m virtualenv -p $PYTHON venv +$PYTHON -m virtualenv -p "$PYTHON" venv venv/bin/python -m pip install -e ".[dev]" venv/bin/python -m pip freeze venv/bin/python --version diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8d039f8b..097b20d7 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -52,32 +52,51 @@ repos: hooks: - id: mypy exclude: ^(bin|cibuildwheel/resources|docs)/.*py$ - args: ["--python-version=3.6", "--scripts-are-modules"] - additional_dependencies: - - packaging - - types-jinja2 - - types-certifi - - types-toml + args: ["--python-version=3.6", "--scripts-are-modules", "--show-error-codes"] + additional_dependencies: &mypy-dependencies + - packaging>=21.0 + - rich - tomli + - types-certifi + - types-click + - types-jinja2 + - types-pyyaml + - types-requests - id: mypy name: mypy 3.7+ on bin/ files: ^((bin|docs)/.*py|noxfile.py)$ - args: ["--python-version=3.7", "--scripts-are-modules"] - additional_dependencies: - - packaging>=21.0 - - rich - - types-jinja2 - - types-pyyaml - - types-click - - types-requests - - tomli + args: ["--python-version=3.7", "--scripts-are-modules", "--show-error-codes"] + additional_dependencies: *mypy-dependencies + +- repo: https://github.com/asottile/yesqa + rev: v1.2.3 + hooks: + - id: yesqa + additional_dependencies: &flake8-dependencies + - flake8-bugbear - repo: https://github.com/PyCQA/flake8 rev: 4.0.1 hooks: - id: flake8 exclude: cibuildwheel/resources/ - additional_dependencies: [flake8-bugbear] + additional_dependencies: *flake8-dependencies + +- repo: https://github.com/pre-commit/pygrep-hooks + rev: v1.9.0 + hooks: + - id: python-check-blanket-noqa + stages: [manual] + - id: python-check-blanket-type-ignore + stages: [manual] + - id: python-no-log-warn + - id: python-no-eval + - id: python-use-type-annotations + +- repo: https://github.com/shellcheck-py/shellcheck-py + rev: v0.7.2.1 + hooks: + - id: shellcheck - repo: local hooks: diff --git a/bin/bump_version.py b/bin/bump_version.py index b252bd20..30835fc1 100755 --- a/bin/bump_version.py +++ b/bin/bump_version.py @@ -68,7 +68,7 @@ def bump_version() -> None: sys.exit(1) # fmt: off - print( 'Current version:', current_version) # noqa + print( 'Current version:', current_version) # noqa: E201 whitespace new_version = input(' New version: ').strip() # fmt: on diff --git a/bin/inspect_all_known_projects.py b/bin/inspect_all_known_projects.py index faf3bab0..ccbc9404 100755 --- a/bin/inspect_all_known_projects.py +++ b/bin/inspect_all_known_projects.py @@ -7,7 +7,7 @@ from typing import Iterator import click import yaml -from ghapi.core import GhApi, HTTP404NotFoundError # type: ignore +from ghapi.core import GhApi, HTTP404NotFoundError # type: ignore[import] from rich import print from cibuildwheel.projectfiles import Analyzer diff --git a/bin/update_pythons.py b/bin/update_pythons.py index b1b2c95a..488ccbc1 100755 --- a/bin/update_pythons.py +++ b/bin/update_pythons.py @@ -131,7 +131,7 @@ class PyPyVersions: def update_version_windows(self, spec: Specifier) -> ConfigWinCP: releases = [r for r in self.releases if spec.contains(r["python_version"])] - releases = sorted(releases, key=lambda r: r["pypy_version"]) # type: ignore + releases = sorted(releases, key=lambda r: r["pypy_version"]) # type: ignore[no-any-return] releases = [r for r in releases if self.get_arch_file(r)] if not releases: @@ -156,7 +156,7 @@ class PyPyVersions: raise RuntimeError("Other archs not supported yet on macOS") releases = [r for r in self.releases if spec.contains(r["python_version"])] - releases = sorted(releases, key=lambda r: r["pypy_version"]) # type: ignore + releases = sorted(releases, key=lambda r: r["pypy_version"]) # type: ignore[no-any-return] if not releases: raise RuntimeError(f"PyPy macOS {self.arch} not found for {spec}!") diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 2c123c36..0623624d 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -166,7 +166,7 @@ def main() -> None: os.environ["CIBUILDWHEEL"] = "1" # Python is buffering by default when running on the CI platforms, giving problems interleaving subprocess call output with unflushed calls to 'print' - sys.stdout = Unbuffered(sys.stdout) # type: ignore + sys.stdout = Unbuffered(sys.stdout) # type: ignore[no-untyped-call,assignment] print_preamble(platform, build_options) diff --git a/cibuildwheel/options.py b/cibuildwheel/options.py index 6a1c19e3..6e6d1984 100644 --- a/cibuildwheel/options.py +++ b/cibuildwheel/options.py @@ -180,7 +180,7 @@ class ConfigOptions: # get the option from the environment, then the config file, then finally the default. # platform-specific options are preferred, if they're allowed. result = _dig_first( - (os.environ if env_plat else {}, plat_envvar), # type: ignore + (os.environ if env_plat else {}, plat_envvar), # type: ignore[arg-type] (os.environ, envvar), (self.config_platform_options, name), (self.config_options, name), diff --git a/cibuildwheel/projectfiles.py b/cibuildwheel/projectfiles.py index 6dda6582..7b106d12 100644 --- a/cibuildwheel/projectfiles.py +++ b/cibuildwheel/projectfiles.py @@ -27,7 +27,7 @@ class Analyzer(ast.NodeVisitor): def visit(self, content: ast.AST) -> None: for node in ast.walk(content): for child in ast.iter_child_nodes(node): - child.parent = node # type: ignore + child.parent = node # type: ignore[attr-defined] super().visit(content) def visit_keyword(self, node: ast.keyword) -> None: @@ -35,7 +35,7 @@ class Analyzer(ast.NodeVisitor): if node.arg == "python_requires": # Must not be nested in an if or other structure # This will be Module -> Expr -> Call -> keyword - if not hasattr(node.parent.parent.parent, "parent") and isinstance( # type: ignore + if not hasattr(node.parent.parent.parent, "parent") and isinstance( # type: ignore[attr-defined] node.value, Constant ): self.requires_python = get_constant(node.value) diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index 016d559d..30b8ed54 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -157,18 +157,18 @@ class TestSelector(IdentifierSelector): # Taken from https://stackoverflow.com/a/107717 class Unbuffered: - def __init__(self, stream): # type: ignore + def __init__(self, stream): # type: ignore[no-untyped-def] self.stream = stream - def write(self, data): # type: ignore + def write(self, data): # type: ignore[no-untyped-def] self.stream.write(data) self.stream.flush() - def writelines(self, data): # type: ignore + def writelines(self, data): # type: ignore[no-untyped-def] self.stream.writelines(data) self.stream.flush() - def __getattr__(self, attr): # type: ignore + def __getattr__(self, attr): # type: ignore[no-untyped-def] return getattr(self.stream, attr) diff --git a/test/conftest.py b/test/conftest.py index 6e3293b2..d8ff2f62 100644 --- a/test/conftest.py +++ b/test/conftest.py @@ -27,4 +27,4 @@ def pytest_collection_modifyitems(config, items) -> None: params=[{"CIBW_BUILD_FRONTEND": "pip"}, {"CIBW_BUILD_FRONTEND": "build"}], ids=["pip", "build"] ) def build_frontend_env(request) -> Dict[str, str]: - return request.param # type: ignore + return request.param # type: ignore[no-any-return]