From e5e94e8702cbd993aaa4b67559f576dde7ef7adc Mon Sep 17 00:00:00 2001 From: anthony sottile Date: Sat, 9 Aug 2025 15:27:15 -0400 Subject: [PATCH 01/12] what year is it? --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8038ead..522925e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -6.0.0 - 2024-08-09 +6.0.0 - 2025-08-09 ================== ## Fixes From 0925e7a9d1bb15912e38bb59515ea89d5cbbbdbd Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Sep 2025 20:23:54 +0000 Subject: [PATCH 02/12] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.17.1 → v1.18.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.17.1...v1.18.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c6d25f8..c213e77 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,6 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.17.1 + rev: v1.18.1 hooks: - id: mypy From 9148219126558a76bb267b7ce0eccd254b13822c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Sep 2025 20:44:07 +0000 Subject: [PATCH 03/12] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.18.1 → v1.18.2](https://github.com/pre-commit/mirrors-mypy/compare/v1.18.1...v1.18.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c213e77..7e9bbc8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,6 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.18.1 + rev: v1.18.2 hooks: - id: mypy From 34110683913ca25e8bc2f4a070955f1dbe2c394f Mon Sep 17 00:00:00 2001 From: anthony sottile Date: Thu, 9 Oct 2025 17:44:52 -0400 Subject: [PATCH 04/12] py310+ Committed via https://github.com/asottile/all-repos --- .github/workflows/main.yml | 4 ++-- .pre-commit-config.yaml | 4 ++-- pre_commit_hooks/file_contents_sorter.py | 2 +- setup.cfg | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 118cdc9..8b87a27 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -10,10 +10,10 @@ jobs: main-windows: uses: asottile/workflows/.github/workflows/tox.yml@v1.8.1 with: - env: '["py39"]' + env: '["py310"]' os: windows-latest main-linux: uses: asottile/workflows/.github/workflows/tox.yml@v1.8.1 with: - env: '["py39", "py310", "py311", "py312"]' + env: '["py310", "py311", "py312", "py313"]' os: ubuntu-latest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 7e9bbc8..e2b0126 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: rev: v3.15.0 hooks: - id: reorder-python-imports - args: [--py39-plus, --add-import, 'from __future__ import annotations'] + args: [--py310-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma rev: v3.2.0 hooks: @@ -26,7 +26,7 @@ repos: rev: v3.20.0 hooks: - id: pyupgrade - args: [--py39-plus] + args: [--py310-plus] - repo: https://github.com/hhatto/autopep8 rev: v2.3.2 hooks: diff --git a/pre_commit_hooks/file_contents_sorter.py b/pre_commit_hooks/file_contents_sorter.py index 4435d6a..ee26d92 100644 --- a/pre_commit_hooks/file_contents_sorter.py +++ b/pre_commit_hooks/file_contents_sorter.py @@ -12,10 +12,10 @@ conflicts and keep the file nicely ordered. from __future__ import annotations import argparse +from collections.abc import Callable from collections.abc import Iterable from collections.abc import Sequence from typing import Any -from typing import Callable from typing import IO PASS = 0 diff --git a/setup.cfg b/setup.cfg index 14f7a91..d91f439 100644 --- a/setup.cfg +++ b/setup.cfg @@ -20,7 +20,7 @@ packages = find: install_requires = ruamel.yaml>=0.15 tomli>=1.1.0;python_version<"3.11" -python_requires = >=3.9 +python_requires = >=3.10 [options.packages.find] exclude = From b51ca9188926be052ebfca906dc2a01837238703 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 13 Oct 2025 20:38:50 +0000 Subject: [PATCH 05/12] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v2.8.0 → v3.1.0](https://github.com/asottile/setup-cfg-fmt/compare/v2.8.0...v3.1.0) - [github.com/asottile/reorder-python-imports: v3.15.0 → v3.16.0](https://github.com/asottile/reorder-python-imports/compare/v3.15.0...v3.16.0) - [github.com/asottile/add-trailing-comma: v3.2.0 → v4.0.0](https://github.com/asottile/add-trailing-comma/compare/v3.2.0...v4.0.0) - [github.com/asottile/pyupgrade: v3.20.0 → v3.21.0](https://github.com/asottile/pyupgrade/compare/v3.20.0...v3.21.0) --- .pre-commit-config.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e2b0126..c252f41 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,20 +10,20 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v2.8.0 + rev: v3.1.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder-python-imports - rev: v3.15.0 + rev: v3.16.0 hooks: - id: reorder-python-imports args: [--py310-plus, --add-import, 'from __future__ import annotations'] - repo: https://github.com/asottile/add-trailing-comma - rev: v3.2.0 + rev: v4.0.0 hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.20.0 + rev: v3.21.0 hooks: - id: pyupgrade args: [--py310-plus] From a804ba5239baa6714cff4c89506bd7e0ae714869 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Thu, 16 Oct 2025 09:30:42 -0400 Subject: [PATCH 06/12] fix nested calls for check-builtin-literals --- pre_commit_hooks/check_builtin_literals.py | 29 +++++++++++----------- tests/check_builtin_literals_test.py | 16 ++++++------ 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/pre_commit_hooks/check_builtin_literals.py b/pre_commit_hooks/check_builtin_literals.py index 16d59b5..e128eea 100644 --- a/pre_commit_hooks/check_builtin_literals.py +++ b/pre_commit_hooks/check_builtin_literals.py @@ -26,36 +26,37 @@ class Call(NamedTuple): class Visitor(ast.NodeVisitor): def __init__( self, - ignore: Sequence[str] | None = None, + ignore: set[str], allow_dict_kwargs: bool = True, ) -> None: self.builtin_type_calls: list[Call] = [] - self.ignore = set(ignore) if ignore else set() self.allow_dict_kwargs = allow_dict_kwargs + self._disallowed = BUILTIN_TYPES.keys() - ignore def _check_dict_call(self, node: ast.Call) -> bool: return self.allow_dict_kwargs and bool(node.keywords) def visit_Call(self, node: ast.Call) -> None: - if not isinstance(node.func, ast.Name): + if ( # Ignore functions that are object attributes (`foo.bar()`). # Assume that if the user calls `builtins.list()`, they know what # they're doing. - return - if node.func.id not in set(BUILTIN_TYPES).difference(self.ignore): - return - if node.func.id == 'dict' and self._check_dict_call(node): - return - elif node.args: - return - self.builtin_type_calls.append( - Call(node.func.id, node.lineno, node.col_offset), - ) + isinstance(node.func, ast.Name) and + node.func.id in self._disallowed and + (node.func.id != 'dict' or not self._check_dict_call(node)) and + not node.args + ): + self.builtin_type_calls.append( + Call(node.func.id, node.lineno, node.col_offset), + ) + + self.generic_visit(node) def check_file( filename: str, - ignore: Sequence[str] | None = None, + *, + ignore: set[str], allow_dict_kwargs: bool = True, ) -> list[Call]: with open(filename, 'rb') as f: diff --git a/tests/check_builtin_literals_test.py b/tests/check_builtin_literals_test.py index 1b18257..de29063 100644 --- a/tests/check_builtin_literals_test.py +++ b/tests/check_builtin_literals_test.py @@ -38,11 +38,6 @@ t1 = () ''' -@pytest.fixture -def visitor(): - return Visitor() - - @pytest.mark.parametrize( ('expression', 'calls'), [ @@ -85,7 +80,8 @@ def visitor(): ('builtins.tuple()', []), ], ) -def test_non_dict_exprs(visitor, expression, calls): +def test_non_dict_exprs(expression, calls): + visitor = Visitor(ignore=set()) visitor.visit(ast.parse(expression)) assert visitor.builtin_type_calls == calls @@ -102,7 +98,8 @@ def test_non_dict_exprs(visitor, expression, calls): ('builtins.dict()', []), ], ) -def test_dict_allow_kwargs_exprs(visitor, expression, calls): +def test_dict_allow_kwargs_exprs(expression, calls): + visitor = Visitor(ignore=set()) visitor.visit(ast.parse(expression)) assert visitor.builtin_type_calls == calls @@ -114,17 +111,18 @@ def test_dict_allow_kwargs_exprs(visitor, expression, calls): ('dict(a=1, b=2, c=3)', [Call('dict', 1, 0)]), ("dict(**{'a': 1, 'b': 2, 'c': 3})", [Call('dict', 1, 0)]), ('builtins.dict()', []), + pytest.param('f(dict())', [Call('dict', 1, 2)], id='nested'), ], ) def test_dict_no_allow_kwargs_exprs(expression, calls): - visitor = Visitor(allow_dict_kwargs=False) + visitor = Visitor(ignore=set(), allow_dict_kwargs=False) visitor.visit(ast.parse(expression)) assert visitor.builtin_type_calls == calls def test_ignore_constructors(): visitor = Visitor( - ignore=('complex', 'dict', 'float', 'int', 'list', 'str', 'tuple'), + ignore={'complex', 'dict', 'float', 'int', 'list', 'str', 'tuple'}, ) visitor.visit(ast.parse(BUILTIN_CONSTRUCTORS)) assert visitor.builtin_type_calls == [] From 1592578eeb1947e56d2f52d3d039ebf28e1c1c0f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 10 Nov 2025 20:59:49 +0000 Subject: [PATCH 07/12] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.21.0 → v3.21.1](https://github.com/asottile/pyupgrade/compare/v3.21.0...v3.21.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c252f41..3faf2c6 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.21.0 + rev: v3.21.1 hooks: - id: pyupgrade args: [--py310-plus] From d2cf95b9cf90d4d8239e18a83aca19b8a6c8c345 Mon Sep 17 00:00:00 2001 From: anthony sottile Date: Sat, 22 Nov 2025 15:09:09 -0500 Subject: [PATCH 08/12] deprecate check-docstring-first without replacement this hook has unfixable false positives and is not that useful perhaps someone can write a flake8 plugin to replace the functionality --- .pre-commit-hooks.yaml | 2 +- README.md | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.pre-commit-hooks.yaml b/.pre-commit-hooks.yaml index a98a1e5..275605e 100644 --- a/.pre-commit-hooks.yaml +++ b/.pre-commit-hooks.yaml @@ -29,7 +29,7 @@ entry: check-case-conflict language: python - id: check-docstring-first - name: check docstring is first + name: check docstring is first (deprecated) description: checks a common error of defining a docstring after code. entry: check-docstring-first language: python diff --git a/README.md b/README.md index 9ee1677..8432455 100644 --- a/README.md +++ b/README.md @@ -45,9 +45,6 @@ Require literal syntax when initializing empty or zero Python builtin types. #### `check-case-conflict` Check for files with names that would conflict on a case-insensitive filesystem like MacOS HFS+ or Windows FAT. -#### `check-docstring-first` -Checks for a common error of placing code before the docstring. - #### `check-executables-have-shebangs` Checks that non-binary executables have a proper shebang. @@ -207,6 +204,8 @@ Trims trailing whitespace. - `check-byte-order-marker`: instead use fix-byte-order-marker - `fix-encoding-pragma`: instead use [`pyupgrade`](https://github.com/asottile/pyupgrade) +- `check-docstring-first`: fundamentally flawed, deprecated without replacement. + ### As a standalone package From ce6aed3bbe777fa731e35de5359c35e8d6482c30 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 20:53:37 +0000 Subject: [PATCH 09/12] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/pyupgrade: v3.21.1 → v3.21.2](https://github.com/asottile/pyupgrade/compare/v3.21.1...v3.21.2) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3faf2c6..af16031 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -23,7 +23,7 @@ repos: hooks: - id: add-trailing-comma - repo: https://github.com/asottile/pyupgrade - rev: v3.21.1 + rev: v3.21.2 hooks: - id: pyupgrade args: [--py310-plus] From 401fb65f5434ed3abe05890665710639781d2d7f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 1 Dec 2025 21:05:20 +0000 Subject: [PATCH 10/12] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.18.2 → v1.19.0](https://github.com/pre-commit/mirrors-mypy/compare/v1.18.2...v1.19.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index af16031..58ff678 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,6 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.18.2 + rev: v1.19.0 hooks: - id: mypy From a780519d03bf571963db96d8a106c70f7249b607 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 15 Dec 2025 20:48:45 +0000 Subject: [PATCH 11/12] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/pre-commit/mirrors-mypy: v1.19.0 → v1.19.1](https://github.com/pre-commit/mirrors-mypy/compare/v1.19.0...v1.19.1) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 58ff678..239aa5c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -36,6 +36,6 @@ repos: hooks: - id: flake8 - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.19.0 + rev: v1.19.1 hooks: - id: mypy From a77d5edb63abc7b9a6537f80c2b6e44459f1496d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 22 Dec 2025 20:26:27 +0000 Subject: [PATCH 12/12] [pre-commit.ci] pre-commit autoupdate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit updates: - [github.com/asottile/setup-cfg-fmt: v3.1.0 → v3.2.0](https://github.com/asottile/setup-cfg-fmt/compare/v3.1.0...v3.2.0) --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 239aa5c..e4808c9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -10,7 +10,7 @@ repos: - id: name-tests-test - id: requirements-txt-fixer - repo: https://github.com/asottile/setup-cfg-fmt - rev: v3.1.0 + rev: v3.2.0 hooks: - id: setup-cfg-fmt - repo: https://github.com/asottile/reorder-python-imports