mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-03-29 18:16:52 +00:00
Compare commits
23 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1dff44d3a | ||
|
|
a77d5edb63 | ||
|
|
5dcc56558c | ||
|
|
a780519d03 | ||
|
|
6e513a2e71 | ||
|
|
401fb65f54 | ||
|
|
e59bbe6db7 | ||
|
|
ce6aed3bbe | ||
|
|
459b301556 | ||
|
|
d2cf95b9cf | ||
|
|
f4e025486b | ||
|
|
1592578eeb | ||
|
|
3fed74c572 | ||
|
|
a804ba5239 | ||
|
|
9ba250d7b3 | ||
|
|
b51ca91889 | ||
|
|
8e6ea961b7 | ||
|
|
3411068391 | ||
|
|
a2cdab0afe | ||
|
|
9148219126 | ||
|
|
3ab664f766 | ||
|
|
0925e7a9d1 | ||
|
|
e5e94e8702 |
9 changed files with 37 additions and 39 deletions
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -10,23 +10,23 @@ repos:
|
|||
- id: name-tests-test
|
||||
- id: requirements-txt-fixer
|
||||
- repo: https://github.com/asottile/setup-cfg-fmt
|
||||
rev: v2.8.0
|
||||
rev: v3.2.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: [--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
|
||||
rev: v4.0.0
|
||||
hooks:
|
||||
- id: add-trailing-comma
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.20.0
|
||||
rev: v3.21.2
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py39-plus]
|
||||
args: [--py310-plus]
|
||||
- repo: https://github.com/hhatto/autopep8
|
||||
rev: v2.3.2
|
||||
hooks:
|
||||
|
|
@ -36,6 +36,6 @@ repos:
|
|||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.17.1
|
||||
rev: v1.19.1
|
||||
hooks:
|
||||
- id: mypy
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
6.0.0 - 2024-08-09
|
||||
6.0.0 - 2025-08-09
|
||||
==================
|
||||
|
||||
## Fixes
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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 == []
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue