Skip to content

Commit e645712

Browse files
committed
fix with tree-sitter 0.23
Once again they broke the API, this time around the .captures() call. They changed it by a lot, returning a dict of capture names to captures. Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
1 parent bd21cbc commit e645712

7 files changed

Lines changed: 53 additions & 56 deletions

File tree

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ requires = [
66
"lazy-object-proxy",
77
"lxml",
88
"pathspec",
9-
"tree-sitter>=0.21.0",
9+
"tree-sitter>=0.23.0",
1010
"tree-sitter-bash>=0.21.0",
1111
"snakeoil~=0.10.8",
1212
"pkgcore~=0.12.25",
@@ -46,7 +46,7 @@ dependencies = [
4646
"lazy-object-proxy",
4747
"lxml",
4848
"pathspec",
49-
"tree-sitter>=0.22.2",
49+
"tree-sitter>=0.23.2",
5050
"tree-sitter-bash>=0.21.0",
5151
"snakeoil~=0.10.8",
5252
"pkgcore~=0.12.25",

src/pkgcheck/bash/__init__.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""bash parsing support"""
22

3+
from itertools import chain
4+
35
import tree_sitter_bash
46
from tree_sitter import Language, Parser, Query
57

@@ -31,13 +33,11 @@ def global_query(self, query: Query):
3133
for x in self.tree.root_node.children:
3234
# skip nodes in function scope
3335
if x.type != "function_definition":
34-
for node, _ in query.captures(x):
35-
yield node
36+
yield from chain.from_iterable(query.captures(x).values())
3637

3738
def func_query(self, query: Query):
3839
"""Run a given parse tree query returning only those nodes in function scope."""
3940
for x in self.tree.root_node.children:
4041
# only return nodes in function scope
4142
if x.type == "function_definition":
42-
for node, _ in query.captures(x):
43-
yield node
43+
yield from chain.from_iterable(query.captures(x).values())

src/pkgcheck/checks/codingstyle.py

Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ class BadCommandsCheck(Check):
8989
)
9090

9191
def feed(self, pkg):
92-
for func_node, _ in bash.func_query.captures(pkg.tree.root_node):
93-
for node, _ in bash.cmd_query.captures(func_node):
92+
for func_node in bash.func_query.captures(pkg.tree.root_node).get("func", ()):
93+
for node in bash.cmd_query.captures(func_node).get("call", ()):
9494
call = pkg.node_str(node)
9595
name = pkg.node_str(node.child_by_field_name("name"))
9696
lineno, _colno = node.start_point
@@ -134,8 +134,8 @@ class EendMissingArgCheck(Check):
134134
known_results = frozenset([EendMissingArg])
135135

136136
def feed(self, pkg):
137-
for func_node, _ in bash.func_query.captures(pkg.tree.root_node):
138-
for node, _ in bash.cmd_query.captures(func_node):
137+
for func_node in bash.func_query.captures(pkg.tree.root_node).get("func", ()):
138+
for node in bash.cmd_query.captures(func_node).get("call", ()):
139139
line = pkg.node_str(node)
140140
if line == "eend":
141141
lineno, _ = node.start_point
@@ -639,15 +639,15 @@ class MetadataVarCheck(Check):
639639
@verify_vars("HOMEPAGE", "KEYWORDS")
640640
def _raw_text(self, var, node, value, pkg):
641641
matches = []
642-
for var_node, _ in bash.var_query.captures(node):
642+
for var_node in bash.var_query.captures(node).get("var", ()):
643643
matches.append(pkg.node_str(var_node.parent))
644644
if matches:
645645
yield ReferenceInMetadataVar(var, stable_unique(matches), pkg=pkg)
646646

647647
@verify_vars("LICENSE")
648648
def _raw_text_license(self, var, node, value, pkg):
649649
matches = []
650-
for var_node, _ in bash.var_query.captures(node):
650+
for var_node in bash.var_query.captures(node).get("var", ()):
651651
var_str = pkg.node_str(var_node.parent).strip()
652652
if var_str in ["$LICENSE", "${LICENSE}"]:
653653
continue # LICENSE in LICENSE is ok
@@ -718,7 +718,7 @@ def feed(self, pkg):
718718
line=pkg.node_str(node), lineno=lineno + 1, pkg=pkg
719719
)
720720
elif pkg.node_str(value_node.prev_sibling) == "=":
721-
for var_node, _ in bash.var_query.captures(value_node):
721+
for var_node in bash.var_query.captures(value_node).get("var", ()):
722722
if (
723723
pkg.node_str(var_node) == name
724724
and self.canonicalize_assign(pkg.node_str(var_node.parent)) == value_str
@@ -878,12 +878,12 @@ def feed(self, pkg):
878878
# collect globally defined functions in ebuild
879879
defined_funcs = {
880880
pkg.node_str(func_node.child_by_field_name("name"))
881-
for func_node, _ in bash.func_query.captures(pkg.tree.root_node)
881+
for func_node in bash.func_query.captures(pkg.tree.root_node).get("func", ())
882882
}
883883

884884
# register variables assigned in ebuilds
885885
assigned_vars = dict()
886-
for node, _ in bash.var_assign_query.captures(pkg.tree.root_node):
886+
for node in bash.var_assign_query.captures(pkg.tree.root_node).get("assign", ()):
887887
name = pkg.node_str(node.child_by_field_name("name"))
888888
if eclass := self.get_eclass(name, pkg):
889889
assigned_vars[name] = eclass
@@ -892,7 +892,7 @@ def feed(self, pkg):
892892
weak_used_eclasses = set()
893893
# match captured commands with eclasses
894894
used = defaultdict(list)
895-
for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
895+
for node in bash.cmd_query.captures(pkg.tree.root_node).get("call", ()):
896896
call = pkg.node_str(node)
897897
name = pkg.node_str(node.child_by_field_name("name"))
898898
if name == "inherit":
@@ -914,7 +914,7 @@ def feed(self, pkg):
914914
weak_used_eclasses.add(eclass)
915915

916916
# match captured variables with eclasses
917-
for node, _ in bash.var_query.captures(pkg.tree.root_node):
917+
for node in bash.var_query.captures(pkg.tree.root_node).get("var", ()):
918918
name = pkg.node_str(node)
919919
if node.parent.type == "unset_command":
920920
continue
@@ -1114,12 +1114,12 @@ class VariableScopeCheck(Check):
11141114
scoped_vars.setdefault(eapi, {}).setdefault(phase, set()).add(variable)
11151115
scoped_vars = ImmutableDict(scoped_vars)
11161116

1117-
def feed(self, pkg):
1118-
for func_node, _ in bash.func_query.captures(pkg.tree.root_node):
1117+
def feed(self, pkg: bash.ParseTree):
1118+
for func_node in bash.func_query.captures(pkg.tree.root_node).get("func", ()):
11191119
func_name = pkg.node_str(func_node.child_by_field_name("name"))
11201120
if variables := self.scoped_vars[pkg.eapi].get(func_name):
11211121
usage = defaultdict(set)
1122-
for var_node, _ in bash.var_query.captures(func_node):
1122+
for var_node in bash.var_query.captures(func_node).get("var", ()):
11231123
var_name = pkg.node_str(var_node)
11241124
if var_name in variables:
11251125
lineno, _colno = var_node.start_point
@@ -1130,7 +1130,7 @@ def feed(self, pkg):
11301130
global_usage = defaultdict(set)
11311131
for global_node in pkg.tree.root_node.children:
11321132
if global_node.type not in ("function_definition", "ERROR"):
1133-
for var_node, _ in bash.var_query.captures(global_node):
1133+
for var_node in bash.var_query.captures(global_node).get("var", ()):
11341134
var_name = pkg.node_str(var_node)
11351135
if var_name in self.not_global_scope:
11361136
lineno, _colno = var_node.start_point
@@ -1271,14 +1271,14 @@ def _var_needs_quotes(self, pkg, node):
12711271
# Default: The variable should be quoted
12721272
return True
12731273

1274-
def _feed(self, item):
1274+
def _feed(self, item: bash.ParseTree):
12751275
if item.tree.root_node.has_error:
12761276
# Do not run this check if the parse tree contains errors, as it
12771277
# might result in false positives. This check appears to be quite
12781278
# expensive though...
12791279
return
12801280
hits = defaultdict(set)
1281-
for var_node, _ in bash.var_query.captures(item.tree.root_node):
1281+
for var_node in bash.var_query.captures(item.tree.root_node).get("var", ()):
12821282
var_name = item.node_str(var_node)
12831283
if var_name in self.var_names:
12841284
if self._var_needs_quotes(item, var_node):
@@ -1390,7 +1390,7 @@ class DoCompressedFilesCheck(Check):
13901390
)
13911391

13921392
def feed(self, pkg):
1393-
for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
1393+
for node in bash.cmd_query.captures(pkg.tree.root_node).get("call", ()):
13941394
call_name = pkg.node_str(node.child_by_field_name("name"))
13951395
if call_name not in self.functions:
13961396
continue
@@ -1446,7 +1446,7 @@ def check_head_tail(self, pkg, call_node, call_name):
14461446
prev_arg = arg
14471447

14481448
def feed(self, pkg):
1449-
for call_node, _ in bash.cmd_query.captures(pkg.tree.root_node):
1449+
for call_node in bash.cmd_query.captures(pkg.tree.root_node).get("call", ()):
14501450
call_name = pkg.node_str(call_node.child_by_field_name("name"))
14511451
if call_name in ("head", "tail"):
14521452
yield from self.check_head_tail(pkg, call_node, call_name)
@@ -1476,14 +1476,13 @@ def __init__(self, options, **kwargs):
14761476
self.glob_query = bash.query('(concatenation (word) @word (.match? @word "[*?]")) @usage')
14771477

14781478
def feed(self, pkg):
1479-
for node, capture in self.glob_query.captures(pkg.tree.root_node):
1480-
if capture == "usage":
1481-
for var_node, _ in bash.var_query.captures(node):
1482-
var_name = pkg.node_str(var_node)
1483-
if var_name == "DISTDIR":
1484-
lineno, _colno = node.start_point
1485-
yield GlobDistdir(line=pkg.node_str(node), lineno=lineno + 1, pkg=pkg)
1486-
break
1479+
for node in self.glob_query.captures(pkg.tree.root_node).get("usage", ()):
1480+
for var_node in bash.var_query.captures(node).get("var", ()):
1481+
var_name = pkg.node_str(var_node)
1482+
if var_name == "DISTDIR":
1483+
lineno, _colno = node.start_point
1484+
yield GlobDistdir(line=pkg.node_str(node), lineno=lineno + 1, pkg=pkg)
1485+
break
14871486

14881487

14891488
class VariableShadowed(results.LinesResult, results.Warning):
@@ -1528,7 +1527,7 @@ def feed(self, pkg: bash.ParseTree):
15281527
if value_node := node.child_by_field_name("value"):
15291528
if any(
15301529
pkg.node_str(node) == used_name
1531-
for node, _ in bash.var_query.captures(value_node)
1530+
for node in bash.var_query.captures(value_node).get("var", ())
15321531
):
15331532
continue
15341533
var_assigns[used_name].append(node)
@@ -1570,7 +1569,7 @@ class SandboxCallCheck(Check):
15701569
functions = frozenset({"addread", "addwrite", "adddeny", "addpredict"})
15711570

15721571
def feed(self, pkg: bash.ParseTree):
1573-
for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
1572+
for node in bash.cmd_query.captures(pkg.tree.root_node).get("call", ()):
15741573
name = pkg.node_str(node.child_by_field_name("name"))
15751574
if name in self.functions:
15761575
args = node.children_by_field_name("argument")

src/pkgcheck/checks/eclass.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ def check_pre_inherits(self, pkg, inherits: list[tuple[list[str], int]]):
164164

165165
# scan for any misplaced @PRE_INHERIT variables
166166
if pre_inherits:
167-
for node, _ in bash.var_assign_query.captures(pkg.tree.root_node):
167+
for node in bash.var_assign_query.captures(pkg.tree.root_node).get("assign", ()):
168168
var_name = pkg.node_str(node.child_by_field_name("name"))
169169
lineno, _colno = node.start_point
170170
if var_name in pre_inherits and lineno > pre_inherits[var_name]:
@@ -184,7 +184,7 @@ def check_user_variables(self, pkg: bash.ParseTree, inherits: list[tuple[list[st
184184

185185
# scan for usage of @USER_VARIABLE variables
186186
if user_variables:
187-
for node, _ in bash.var_assign_query.captures(pkg.tree.root_node):
187+
for node in bash.var_assign_query.captures(pkg.tree.root_node).get("assign", ()):
188188
var_name = pkg.node_str(node.child_by_field_name("name"))
189189
if var_name in user_variables:
190190
lineno, _colno = node.start_point
@@ -205,7 +205,7 @@ def check_deprecated_variables(self, pkg, inherits: list[tuple[list[str], int]])
205205

206206
# scan for usage of @DEPRECATED variables
207207
if deprecated:
208-
for node, _ in bash.var_query.captures(pkg.tree.root_node):
208+
for node in bash.var_query.captures(pkg.tree.root_node).get("var", ()):
209209
var_name = pkg.node_str(node)
210210
if var_name in deprecated:
211211
lineno, _colno = node.start_point
@@ -230,7 +230,7 @@ def check_deprecated_functions(self, pkg, inherits: list[tuple[list[str], int]])
230230

231231
# scan for usage of @DEPRECATED functions
232232
if deprecated:
233-
for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
233+
for node in bash.cmd_query.captures(pkg.tree.root_node).get("call", ()):
234234
func_name = pkg.node_str(node.child_by_field_name("name"))
235235
if func_name in deprecated:
236236
lineno, _colno = node.start_point
@@ -258,7 +258,7 @@ def feed(self, pkg):
258258
if pkg.inherit:
259259
inherited: set[str] = set()
260260
inherits: list[tuple[list[str], int]] = []
261-
for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
261+
for node in bash.cmd_query.captures(pkg.tree.root_node).get("call", ()):
262262
name = pkg.node_str(node.child_by_field_name("name"))
263263
if name == "inherit":
264264
call = pkg.node_str(node)
@@ -342,14 +342,14 @@ def eclass_phase_vars(self, eclass, phase):
342342

343343
def feed(self, eclass):
344344
func_prefix = f"{eclass.name}_"
345-
for func_node, _ in bash.func_query.captures(eclass.tree.root_node):
345+
for func_node in bash.func_query.captures(eclass.tree.root_node).get("func", ()):
346346
func_name = eclass.node_str(func_node.child_by_field_name("name"))
347347
if not func_name.startswith(func_prefix):
348348
continue
349349
phase = func_name[len(func_prefix) :]
350350
if variables := self.eclass_phase_vars(eclass, phase):
351351
usage = defaultdict(set)
352-
for var_node, _ in bash.var_query.captures(func_node):
352+
for var_node in bash.var_query.captures(func_node).get("var", ()):
353353
var_name = eclass.node_str(var_node)
354354
if var_name in variables:
355355
lineno, _colno = var_node.start_point

src/pkgcheck/checks/python.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
import itertools
21
import re
32
import typing
43
from collections import defaultdict
4+
from itertools import takewhile
55
from operator import attrgetter
66

77
from pkgcore import fetch
@@ -358,7 +358,7 @@ def check_pep517(self, pkg):
358358
uses_setuptools_scm = False
359359
pep517_value = None
360360

361-
for var_node, _ in bash.var_assign_query.captures(pkg.tree.root_node):
361+
for var_node in bash.var_assign_query.captures(pkg.tree.root_node).get("assign", ()):
362362
var_name = pkg.node_str(var_node.child_by_field_name("name"))
363363

364364
if var_name == "DISTUTILS_OPTIONAL":
@@ -407,7 +407,7 @@ def build_python_gen_any_dep_calls(self, pkg, any_dep_func):
407407
for var_node in pkg.global_query(bash.var_assign_query):
408408
name = pkg.node_str(var_node.child_by_field_name("name"))
409409
if name in {"DEPEND", "BDEPEND"}:
410-
for call_node, _ in bash.cmd_query.captures(var_node):
410+
for call_node in bash.cmd_query.captures(var_node).get("call", ()):
411411
call_name = pkg.node_str(call_node.child_by_field_name("name"))
412412
if call_name == any_dep_func and len(call_node.children) > 1:
413413
check_deps[name].update(
@@ -457,7 +457,7 @@ def _prepare_dep_type(pkg, dep_type: str) -> str:
457457
def check_python_check_deps(self, pkg, func_node, python_check_deps, any_dep_func):
458458
has_version_checked_deps = defaultdict(set)
459459
has_version_lines = set()
460-
for node, _ in bash.cmd_query.captures(func_node):
460+
for node in bash.cmd_query.captures(func_node).get("call", ()):
461461
call_name = pkg.node_str(node.child_by_field_name("name"))
462462
if call_name == "has_version":
463463
lineno, _ = node.start_point
@@ -548,7 +548,7 @@ def feed(self, pkg):
548548

549549
any_dep_func = self.eclass_any_dep_func[eclass]
550550
python_check_deps = self.build_python_gen_any_dep_calls(pkg, any_dep_func)
551-
for func_node, _ in bash.func_query.captures(pkg.tree.root_node):
551+
for func_node in bash.func_query.captures(pkg.tree.root_node).get("func", ()):
552552
func_name = pkg.node_str(func_node.child_by_field_name("name"))
553553
if func_name == "python_check_deps":
554554
yield from self.check_python_check_deps(
@@ -664,9 +664,7 @@ def feed(self, pkg):
664664
return
665665

666666
# determine python impls to target
667-
targets = set(
668-
itertools.takewhile(lambda x: x != latest_target, reversed(available_targets))
669-
)
667+
targets = set(takewhile(lambda x: x != latest_target, reversed(available_targets)))
670668

671669
if targets:
672670
try:

src/pkgcheck/checks/reserved.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ def _feed(self, item: bash.ParseTree):
4242
"function",
4343
{
4444
item.node_str(node.child_by_field_name("name")): node.start_point
45-
for node, _ in bash.func_query.captures(item.tree.root_node)
45+
for node in bash.func_query.captures(item.tree.root_node).get("func", ())
4646
},
4747
)
4848
used_variables = {
4949
item.node_str(node.child_by_field_name("name")): node.start_point
50-
for node, _ in bash.var_assign_query.captures(item.tree.root_node)
50+
for node in bash.var_assign_query.captures(item.tree.root_node).get("assign", ())
5151
}
52-
for node, _ in bash.var_query.captures(item.tree.root_node):
52+
for node in bash.var_query.captures(item.tree.root_node).get("var", ()):
5353
if (name := item.node_str(node)) not in self.variables_usage_whitelist:
5454
used_variables.setdefault(name, node.start_point)
5555
yield from self._check("variable", used_variables)
@@ -144,7 +144,7 @@ def feed(self, pkg: sources._ParsedPkg):
144144
for used_name, *args, lineno in self._feed(pkg):
145145
yield EbuildReservedName(*args, lineno=lineno, line=used_name, pkg=pkg)
146146

147-
for node, _ in bash.func_query.captures(pkg.tree.root_node):
147+
for node in bash.func_query.captures(pkg.tree.root_node).get("func", ()):
148148
used_name = pkg.node_str(node.child_by_field_name("name"))
149149
if used_name in self.phases_hooks[str(pkg.eapi)]:
150150
lineno, _ = node.start_point

src/pkgcheck/checks/rust.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def _verify_crates(self, pkg: bash.ParseTree):
6060
return
6161

6262
def _verify_cargo_crate_uris(self, pkg: bash.ParseTree):
63-
for node, _ in bash.cmd_query.captures(pkg.tree.root_node):
63+
for node in bash.cmd_query.captures(pkg.tree.root_node).get("call", ()):
6464
call_name = pkg.node_str(node.child_by_field_name("name"))
6565
if call_name == "cargo_crate_uris":
6666
row, _ = node.start_point
@@ -69,7 +69,7 @@ def _verify_cargo_crate_uris(self, pkg: bash.ParseTree):
6969
node.child_count == 2
7070
and any(
7171
pkg.node_str(var_node) == "CRATES"
72-
for var_node, _ in bash.var_query.captures(node.children[1])
72+
for var_node in bash.var_query.captures(node.children[1]).get("var", ())
7373
)
7474
):
7575
yield SuboptimalCratesURICall(

0 commit comments

Comments
 (0)