From 04be5d2a8f2283fe2ba725c8a8fdc29f1b94e190 Mon Sep 17 00:00:00 2001 From: liuzhilin Date: Mon, 1 Dec 2025 14:41:06 +0800 Subject: [PATCH] backport upstream patch --- ...ted-calls-for-check-builtin-literals.patch | 123 ++++++++++++++++++ python-pre_commit_hooks.spec | 8 +- 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 backport-fix-nested-calls-for-check-builtin-literals.patch diff --git a/backport-fix-nested-calls-for-check-builtin-literals.patch b/backport-fix-nested-calls-for-check-builtin-literals.patch new file mode 100644 index 0000000..cf4da29 --- /dev/null +++ b/backport-fix-nested-calls-for-check-builtin-literals.patch @@ -0,0 +1,123 @@ +From a804ba5239baa6714cff4c89506bd7e0ae714869 Mon Sep 17 00:00:00 2001 +From: Anthony Sottile +Date: Thu, 16 Oct 2025 09:30:42 -0400 +Subject: [PATCH] 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 16d59b52..e128eeaa 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 1b182573..de29063f 100644 +--- a/tests/check_builtin_literals_test.py ++++ b/tests/check_builtin_literals_test.py +@@ -38,11 +38,6 @@ + ''' + + +-@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 == [] diff --git a/python-pre_commit_hooks.spec b/python-pre_commit_hooks.spec index 59f286d..93ef50b 100644 --- a/python-pre_commit_hooks.spec +++ b/python-pre_commit_hooks.spec @@ -7,13 +7,16 @@ Some out-of-the-box hooks for pre-commit.} Name: python-%{pypi_name} Version: 6.0.0 -Release: 1 +Release: 2 Summary: Some out-of-the-box hooks for pre-commit. License: MIT URL: https://github.com/pre-commit/pre-commit-hooks Source0: https://files.pythonhosted.org/packages/36/4d/93e63e48f8fd16d6c1e4cef5dabadcade4d1325c7fd6f29f075a4d2284f3/pre-commit-hooks-6.0.0.tar.gz BuildArch: noarch +#backport upstream patch +Patch6001: backport-fix-nested-calls-for-check-builtin-literals.patch + BuildRequires: python3-devel BuildRequires: python3-pip BuildRequires: python3-wheel @@ -44,6 +47,9 @@ Summary: Some out-of-the-box hooks for pre-commit. %license LICENSE %changelog +* Mon Dec 01 2025 liuzhilin - 6.0.0-2 +- fix nested calls for check-builtin-literals + * Wed Sep 17 2025 lvfei - 6.0.0-1 - Update package with version 6.0.0 heck-shebang-scripts-are-executable improve error message -- Gitee