From 13a8e252f008ab737f51e79b74117cbfad6fe53b Mon Sep 17 00:00:00 2001 From: Willi Ballenthin Date: Thu, 6 Jul 2023 20:04:27 +0200 Subject: [PATCH] introduce flake8-comprehensions --- capa/features/common.py | 4 ++-- capa/features/extractors/elf.py | 4 ++-- capa/features/extractors/ida/insn.py | 4 ++-- .../features/extractors/viv/indirect_calls.py | 2 +- capa/ida/helpers.py | 6 +++--- capa/ida/plugin/model.py | 2 +- capa/ida/plugin/view.py | 4 ++-- capa/main.py | 21 +++++++++---------- capa/render/default.py | 2 +- capa/render/proto/__init__.py | 2 +- capa/render/result_document.py | 4 ++-- capa/render/utils.py | 2 +- capa/render/verbose.py | 5 ++--- capa/render/vverbose.py | 8 +++---- capa/rules/__init__.py | 16 +++++++------- capa/rules/cache.py | 2 +- scripts/capa_as_library.py | 12 +++++------ scripts/detect_duplicate_features.py | 2 +- scripts/lint.py | 2 +- tests/test_freeze.py | 12 +++++------ tests/test_main.py | 10 ++++----- tests/test_rules.py | 4 ++-- 22 files changed, 64 insertions(+), 66 deletions(-) diff --git a/capa/features/common.py b/capa/features/common.py index 3bca4ba5..9b2dbcaf 100644 --- a/capa/features/common.py +++ b/capa/features/common.py @@ -270,7 +270,7 @@ class _MatchedSubstring(Substring): self.matches = matches def __str__(self): - matches = ", ".join(map(lambda s: '"' + s + '"', (self.matches or {}).keys())) + matches = ", ".join(f'"{s}"' for s in (self.matches or {}).keys()) assert isinstance(self.value, str) return f'substring("{self.value}", matches = {matches})' @@ -362,7 +362,7 @@ class _MatchedRegex(Regex): self.matches = matches def __str__(self): - matches = ", ".join(map(lambda s: '"' + s + '"', (self.matches or {}).keys())) + matches = ", ".join(f'"{s}"' for s in (self.matches or {}).keys()) assert isinstance(self.value, str) return f"regex(string =~ {self.value}, matches = {matches})" diff --git a/capa/features/extractors/elf.py b/capa/features/extractors/elf.py index 6436902d..b5960866 100644 --- a/capa/features/extractors/elf.py +++ b/capa/features/extractors/elf.py @@ -824,7 +824,7 @@ def guess_os_from_abi_versions_needed(elf: ELF) -> Optional[OS]: # this will let us guess about linux/hurd in some cases. versions_needed = elf.versions_needed - if any(map(lambda abi: abi.startswith("GLIBC"), itertools.chain(*versions_needed.values()))): + if any(abi.startswith("GLIBC") for abi in itertools.chain(*versions_needed.values())): # there are any GLIBC versions needed if elf.e_machine != "i386": @@ -881,7 +881,7 @@ def guess_os_from_symtab(elf: ELF) -> Optional[OS]: sym_name = symtab.get_name(symbol) for os, hints in keywords.items(): - if any(map(lambda x: x in sym_name, hints)): + if any(hint in sym_name for hint in hints): return os return None diff --git a/capa/features/extractors/ida/insn.py b/capa/features/extractors/ida/insn.py index 7acae816..7e3b6b40 100644 --- a/capa/features/extractors/ida/insn.py +++ b/capa/features/extractors/ida/insn.py @@ -398,7 +398,7 @@ def extract_insn_peb_access_characteristic_features( if insn.itype not in (idaapi.NN_push, idaapi.NN_mov): return - if all(map(lambda op: op.type != idaapi.o_mem, insn.ops)): + if all(op.type != idaapi.o_mem for op in insn.ops): # try to optimize for only memory references return @@ -419,7 +419,7 @@ def extract_insn_segment_access_features( """ insn: idaapi.insn_t = ih.inner - if all(map(lambda op: op.type != idaapi.o_mem, insn.ops)): + if all(op.type != idaapi.o_mem for op in insn.ops): # try to optimize for only memory references return diff --git a/capa/features/extractors/viv/indirect_calls.py b/capa/features/extractors/viv/indirect_calls.py index 0855d56f..896da807 100644 --- a/capa/features/extractors/viv/indirect_calls.py +++ b/capa/features/extractors/viv/indirect_calls.py @@ -88,7 +88,7 @@ def find_definition(vw: VivWorkspace, va: int, reg: int) -> Tuple[int, Union[int NotFoundError: when the definition cannot be found. """ q: Deque[int] = collections.deque() - seen: Set[int] = set([]) + seen: Set[int] = set() q.extend(get_previous_instructions(vw, va)) while q: diff --git a/capa/ida/helpers.py b/capa/ida/helpers.py index d66bfdd0..48340fc4 100644 --- a/capa/ida/helpers.py +++ b/capa/ida/helpers.py @@ -159,15 +159,15 @@ def collect_metadata(rules): rules=rules, base_address=capa.features.freeze.Address.from_capa(idaapi.get_imagebase()), layout=rdoc.Layout( - functions=tuple() + functions=(), # this is updated after capabilities have been collected. # will look like: # # "functions": { 0x401000: { "matched_basic_blocks": [ 0x401000, 0x401005, ... ] }, ... } ), # ignore these for now - not used by IDA plugin. - feature_counts=rdoc.FeatureCounts(file=0, functions=tuple()), - library_functions=tuple(), + feature_counts=rdoc.FeatureCounts(file=0, functions=()), + library_functions=(), ), ) diff --git a/capa/ida/plugin/model.py b/capa/ida/plugin/model.py index b53007ae..5f18d2c8 100644 --- a/capa/ida/plugin/model.py +++ b/capa/ida/plugin/model.py @@ -426,7 +426,7 @@ class CapaExplorerDataModel(QtCore.QAbstractItemModel): # optional statement with no successful children is empty if isinstance(match.node, rd.StatementNode) and match.node.statement.type == rd.CompoundStatementType.OPTIONAL: - if not any(map(lambda m: m.success, match.children)): + if not any(m.success for m in match.children): return if isinstance(match.node, rd.StatementNode): diff --git a/capa/ida/plugin/view.py b/capa/ida/plugin/view.py index 680abf2a..bb4f1f07 100644 --- a/capa/ida/plugin/view.py +++ b/capa/ida/plugin/view.py @@ -64,7 +64,7 @@ def parse_yaml_line(feature): feature, _, comment = feature.partition("#") feature, _, description = feature.partition("=") - return map(lambda o: o.strip(), (feature, description, comment)) + return (o.strip() for o in (feature, description, comment)) def parse_node_for_feature(feature, description, comment, depth): @@ -499,7 +499,7 @@ class CapaExplorerRulegenEditor(QtWidgets.QTreeWidget): rule_text += "\n features:\n" for o in iterate_tree(self): - feature, description, comment = map(lambda o: o.strip(), tuple(o.text(i) for i in range(3))) + feature, description, comment = (o.strip() for o in tuple(o.text(i) for i in range(3))) rule_text += parse_node_for_feature(feature, description, comment, calc_item_depth(o)) # FIXME we avoid circular update by disabling signals when updating diff --git a/capa/main.py b/capa/main.py index 0b1e046d..37765c9a 100644 --- a/capa/main.py +++ b/capa/main.py @@ -249,8 +249,8 @@ def find_capabilities(ruleset: RuleSet, extractor: FeatureExtractor, disable_pro all_bb_matches = collections.defaultdict(list) # type: MatchResults all_insn_matches = collections.defaultdict(list) # type: MatchResults - feature_counts = rdoc.FeatureCounts(file=0, functions=tuple()) - library_functions: Tuple[rdoc.LibraryFunction, ...] = tuple() + feature_counts = rdoc.FeatureCounts(file=0, functions=()) + library_functions: Tuple[rdoc.LibraryFunction, ...] = () with redirecting_print_to_tqdm(disable_progress): with tqdm.contrib.logging.logging_redirect_tqdm(): @@ -299,16 +299,15 @@ def find_capabilities(ruleset: RuleSet, extractor: FeatureExtractor, disable_pro for rule_name, results in itertools.chain( all_function_matches.items(), all_bb_matches.items(), all_insn_matches.items() ): - locations = set(map(lambda p: p[0], results)) + locations = {p[0] for p in results} rule = ruleset[rule_name] capa.engine.index_rule_matches(function_and_lower_features, rule, locations) all_file_matches, feature_count = find_file_capabilities(ruleset, extractor, function_and_lower_features) feature_counts.file = feature_count - matches = { - rule_name: results - for rule_name, results in itertools.chain( + matches = dict( + itertools.chain( # each rule exists in exactly one scope, # so there won't be any overlap among these following MatchResults, # and we can merge the dictionaries naively. @@ -317,7 +316,7 @@ def find_capabilities(ruleset: RuleSet, extractor: FeatureExtractor, disable_pro all_function_matches.items(), all_file_matches.items(), ) - } + ) meta = { "feature_counts": feature_counts, @@ -589,7 +588,7 @@ def get_extractor( def get_file_extractors(sample: str, format_: str) -> List[FeatureExtractor]: - file_extractors: List[FeatureExtractor] = list() + file_extractors: List[FeatureExtractor] = [] if format_ == FORMAT_PE: file_extractors.append(capa.features.extractors.pefile.PefileFeatureExtractor(sample)) @@ -785,14 +784,14 @@ def collect_metadata( rules=tuple(rules_path), base_address=frz.Address.from_capa(extractor.get_base_address()), layout=rdoc.Layout( - functions=tuple(), + functions=(), # this is updated after capabilities have been collected. # will look like: # # "functions": { 0x401000: { "matched_basic_blocks": [ 0x401000, 0x401005, ... ] }, ... } ), - feature_counts=rdoc.FeatureCounts(file=0, functions=tuple()), - library_functions=tuple(), + feature_counts=rdoc.FeatureCounts(file=0, functions=()), + library_functions=(), ), ) diff --git a/capa/render/default.py b/capa/render/default.py index 21b0104b..556c82a4 100644 --- a/capa/render/default.py +++ b/capa/render/default.py @@ -48,7 +48,7 @@ def find_subrule_matches(doc: rd.ResultDocument): collect the rule names that have been matched as a subrule match. this way we can avoid displaying entries for things that are too specific. """ - matches = set([]) + matches = set() def rec(match: rd.Match): if not match.success: diff --git a/capa/render/proto/__init__.py b/capa/render/proto/__init__.py index e895ae94..b55622a9 100644 --- a/capa/render/proto/__init__.py +++ b/capa/render/proto/__init__.py @@ -39,7 +39,7 @@ from capa.features.freeze import AddressType def dict_tuple_to_list_values(d: Dict) -> Dict: - o = dict() + o = {} for k, v in d.items(): if isinstance(v, tuple): o[k] = list(v) diff --git a/capa/render/result_document.py b/capa/render/result_document.py index 944365e6..00c3eb9b 100644 --- a/capa/render/result_document.py +++ b/capa/render/result_document.py @@ -302,7 +302,7 @@ class Match(FrozenModel): # pull matches from the referenced rule into our tree here. rule_name = name rule = rules[rule_name] - rule_matches = {address: result for (address, result) in capabilities[rule_name]} + rule_matches = dict(capabilities[rule_name]) if rule.is_subscope_rule(): # for a subscope rule, fixup the node to be a scope node, rather than a match feature node. @@ -347,7 +347,7 @@ class Match(FrozenModel): # we could introduce an intermediate node here. # this would be a breaking change and require updates to the renderers. # in the meantime, the above might be sufficient. - rule_matches = {address: result for (address, result) in capabilities[rule.name]} + rule_matches = dict(capabilities[rule.name]) for location in result.locations: # doc[locations] contains all matches for the given namespace. # for example, the feature might be `match: anti-analysis/packer` diff --git a/capa/render/utils.py b/capa/render/utils.py index 20a817d7..d9cb9308 100644 --- a/capa/render/utils.py +++ b/capa/render/utils.py @@ -37,7 +37,7 @@ def format_parts_id(data: Union[rd.AttackSpec, rd.MBCSpec]): def capability_rules(doc: rd.ResultDocument) -> Iterator[rd.RuleMatches]: """enumerate the rules in (namespace, name) order that are 'capability' rules (not lib/subscope/disposition/etc).""" - for _, _, rule in sorted(map(lambda rule: (rule.meta.namespace or "", rule.meta.name, rule), doc.rules.values())): + for _, _, rule in sorted((rule.meta.namespace or "", rule.meta.name, rule) for rule in doc.rules.values()): if rule.meta.lib: continue if rule.meta.is_subscope_rule: diff --git a/capa/render/verbose.py b/capa/render/verbose.py index 536e7242..227c5fc7 100644 --- a/capa/render/verbose.py +++ b/capa/render/verbose.py @@ -96,8 +96,7 @@ def render_meta(ostream, doc: rd.ResultDocument): ("library function count", len(doc.meta.analysis.library_functions)), ( "total feature count", - doc.meta.analysis.feature_counts.file - + sum(map(lambda f: f.count, doc.meta.analysis.feature_counts.functions)), + doc.meta.analysis.feature_counts.file + sum(f.count for f in doc.meta.analysis.feature_counts.functions), ), ] @@ -141,7 +140,7 @@ def render_rules(ostream, doc: rd.ResultDocument): rows.append((key, v)) if rule.meta.scope != capa.rules.FILE_SCOPE: - locations = list(map(lambda m: m[0], doc.rules[rule.meta.name].matches)) + locations = [m[0] for m in doc.rules[rule.meta.name].matches] rows.append(("matches", "\n".join(map(format_address, locations)))) ostream.writeln(tabulate.tabulate(rows, tablefmt="plain")) diff --git a/capa/render/vverbose.py b/capa/render/vverbose.py index 0c782853..ba90f76a 100644 --- a/capa/render/vverbose.py +++ b/capa/render/vverbose.py @@ -29,7 +29,7 @@ def render_locations(ostream, locations: Iterable[frz.Address]): # its possible to have an empty locations array here, # such as when we're in MODE_FAILURE and showing the logic # under a `not` statement (which will have no matched locations). - locations = list(sorted(locations)) + locations = sorted(locations) if len(locations) == 0: return @@ -222,7 +222,7 @@ def render_match(ostream, match: rd.Match, indent=0, mode=MODE_SUCCESS): # optional statement with no successful children is empty if isinstance(match.node, rd.StatementNode) and match.node.statement.type == rd.CompoundStatementType.OPTIONAL: - if not any(map(lambda m: m.success, match.children)): + if not any(m.success for m in match.children): return # not statement, so invert the child mode to show failed evaluations @@ -236,7 +236,7 @@ def render_match(ostream, match: rd.Match, indent=0, mode=MODE_SUCCESS): # optional statement with successful children is not relevant if isinstance(match.node, rd.StatementNode) and match.node.statement.type == rd.CompoundStatementType.OPTIONAL: - if any(map(lambda m: m.success, match.children)): + if any(m.success for m in match.children): return # not statement, so invert the child mode to show successful evaluations @@ -277,7 +277,7 @@ def render_rules(ostream, doc: rd.ResultDocument): had_match = False - for _, _, rule in sorted(map(lambda rule: (rule.meta.namespace or "", rule.meta.name, rule), doc.rules.values())): + for _, _, rule in sorted((rule.meta.namespace or "", rule.meta.name, rule) for rule in doc.rules.values()): # default scope hides things like lib rules, malware-category rules, etc. # but in vverbose mode, we really want to show everything. # diff --git a/capa/rules/__init__.py b/capa/rules/__init__.py index 0f2184a7..cfe11d1a 100644 --- a/capa/rules/__init__.py +++ b/capa/rules/__init__.py @@ -634,7 +634,7 @@ class Rule: Returns: List[str]: names of rules upon which this rule depends. """ - deps: Set[str] = set([]) + deps: Set[str] = set() def rec(statement): if isinstance(statement, capa.features.common.MatchedRule): @@ -648,7 +648,7 @@ class Rule: # but, namespaces tend to use `-` while rule names use ` `. so, unlikely, but possible. if statement.value in namespaces: # matches a namespace, so take precedence and don't even check rule names. - deps.update(map(lambda r: r.name, namespaces[statement.value])) + deps.update(r.name for r in namespaces[statement.value]) else: # not a namespace, assume its a rule name. assert isinstance(statement.value, str) @@ -950,7 +950,7 @@ def get_rules_with_scope(rules, scope) -> List[Rule]: from the given collection of rules, select those with the given scope. `scope` is one of the capa.rules.*_SCOPE constants. """ - return list(rule for rule in rules if rule.scope == scope) + return [rule for rule in rules if rule.scope == scope] def get_rules_and_dependencies(rules: List[Rule], rule_name: str) -> Iterator[Rule]: @@ -961,7 +961,7 @@ def get_rules_and_dependencies(rules: List[Rule], rule_name: str) -> Iterator[Ru rules = list(rules) namespaces = index_rules_by_namespace(rules) rules_by_name = {rule.name: rule for rule in rules} - wanted = set([rule_name]) + wanted = {rule_name} def rec(rule): wanted.add(rule.name) @@ -976,7 +976,7 @@ def get_rules_and_dependencies(rules: List[Rule], rule_name: str) -> Iterator[Ru def ensure_rules_are_unique(rules: List[Rule]) -> None: - seen = set([]) + seen = set() for rule in rules: if rule.name in seen: raise InvalidRule("duplicate rule name: " + rule.name) @@ -1041,7 +1041,7 @@ def topologically_order_rules(rules: List[Rule]) -> List[Rule]: rules = list(rules) namespaces = index_rules_by_namespace(rules) rules_by_name = {rule.name: rule for rule in rules} - seen = set([]) + seen = set() ret = [] def rec(rule): @@ -1284,7 +1284,7 @@ class RuleSet: don't include auto-generated "subscope" rules. we want to include general "lib" rules here - even if they are not dependencies of other rules, see #398 """ - scope_rules: Set[Rule] = set([]) + scope_rules: Set[Rule] = set() # we need to process all rules, not just rules with the given scope. # this is because rules with a higher scope, e.g. file scope, may have subscope rules @@ -1329,7 +1329,7 @@ class RuleSet: TODO support -t=metafield """ rules = list(self.rules.values()) - rules_filtered = set([]) + rules_filtered = set() for rule in rules: for k, v in rule.meta.items(): if isinstance(v, str) and tag in v: diff --git a/capa/rules/cache.py b/capa/rules/cache.py index e2bdfc70..110574d7 100644 --- a/capa/rules/cache.py +++ b/capa/rules/cache.py @@ -28,7 +28,7 @@ def compute_cache_identifier(rule_content: List[bytes]) -> CacheIdentifier: hash.update(version.encode("utf-8")) hash.update(b"\x00") - rule_hashes = list(sorted([hashlib.sha256(buf).hexdigest() for buf in rule_content])) + rule_hashes = sorted([hashlib.sha256(buf).hexdigest() for buf in rule_content]) for rule_hash in rule_hashes: hash.update(rule_hash.encode("ascii")) hash.update(b"\x00") diff --git a/scripts/capa_as_library.py b/scripts/capa_as_library.py index 8d55100b..8150a1ac 100644 --- a/scripts/capa_as_library.py +++ b/scripts/capa_as_library.py @@ -29,7 +29,7 @@ def find_subrule_matches(doc: rd.ResultDocument) -> Set[str]: collect the rule names that have been matched as a subrule match. this way we can avoid displaying entries for things that are too specific. """ - matches = set([]) + matches = set() def rec(node: rd.Match): if not node.success: @@ -65,7 +65,7 @@ def render_capabilities(doc: rd.ResultDocument, result): """ subrule_matches = find_subrule_matches(doc) - result["CAPABILITY"] = dict() + result["CAPABILITY"] = {} for rule in rutils.capability_rules(doc): if rule.meta.name in subrule_matches: # rules that are also matched by other rules should not get rendered by default. @@ -79,7 +79,7 @@ def render_capabilities(doc: rd.ResultDocument, result): else: capability = f"{rule.meta.name} ({count} matches)" - result["CAPABILITY"].setdefault(rule.meta.namespace, list()) + result["CAPABILITY"].setdefault(rule.meta.namespace, []) result["CAPABILITY"][rule.meta.namespace].append(capability) @@ -96,7 +96,7 @@ def render_attack(doc, result): 'EXECUTION': ['Shared Modules [T1129]']} } """ - result["ATTCK"] = dict() + result["ATTCK"] = {} tactics = collections.defaultdict(set) for rule in rutils.capability_rules(doc): if not rule.meta.attack: @@ -129,7 +129,7 @@ def render_mbc(doc, result): '[C0021.004]']} } """ - result["MBC"] = dict() + result["MBC"] = {} objectives = collections.defaultdict(set) for rule in rutils.capability_rules(doc): if not rule.meta.mbc: @@ -149,7 +149,7 @@ def render_mbc(doc, result): def render_dictionary(doc: rd.ResultDocument) -> Dict[str, Any]: - result: Dict[str, Any] = dict() + result: Dict[str, Any] = {} render_meta(doc, result) render_attack(doc, result) render_mbc(doc, result) diff --git a/scripts/detect_duplicate_features.py b/scripts/detect_duplicate_features.py index 7d96f564..221ca59b 100644 --- a/scripts/detect_duplicate_features.py +++ b/scripts/detect_duplicate_features.py @@ -73,7 +73,7 @@ def find_overlapping_rules(new_rule_path, rules_path): continue count += 1 # Checks if any features match between existing and new rule. - if any([feature in rule_features for feature in new_rule_features]): + if any(feature in rule_features for feature in new_rule_features): overlapping_rules.append(rule_name) result = {"overlapping_rules": overlapping_rules, "count": count} diff --git a/scripts/lint.py b/scripts/lint.py index 3ba073d9..7718c143 100644 --- a/scripts/lint.py +++ b/scripts/lint.py @@ -825,7 +825,7 @@ def lint_rule(ctx: Context, rule: Rule): print("") if is_nursery_rule(rule): - has_examples = not any(map(lambda v: v.level == Lint.FAIL and v.name == "missing examples", violations)) + has_examples = not any(v.level == Lint.FAIL and v.name == "missing examples" for v in violations) lints_failed = len( tuple( filter( diff --git a/tests/test_freeze.py b/tests/test_freeze.py index 042ae66f..62a1aacd 100644 --- a/tests/test_freeze.py +++ b/tests/test_freeze.py @@ -61,7 +61,7 @@ EXTRACTOR = capa.features.extractors.null.NullFeatureExtractor( def addresses(s) -> List[Address]: - return list(sorted(map(lambda i: i.address, s))) + return sorted(i.address for i in s) def test_null_feature_extractor(): @@ -104,17 +104,17 @@ def compare_extractors(a, b): assert addresses(a.get_functions()) == addresses(b.get_functions()) for f in a.get_functions(): assert addresses(a.get_basic_blocks(f)) == addresses(b.get_basic_blocks(f)) - assert list(sorted(set(a.extract_function_features(f)))) == list(sorted(set(b.extract_function_features(f)))) + assert sorted(set(a.extract_function_features(f))) == sorted(set(b.extract_function_features(f))) for bb in a.get_basic_blocks(f): assert addresses(a.get_instructions(f, bb)) == addresses(b.get_instructions(f, bb)) - assert list(sorted(set(a.extract_basic_block_features(f, bb)))) == list( - sorted(set(b.extract_basic_block_features(f, bb))) + assert sorted(set(a.extract_basic_block_features(f, bb))) == sorted( + set(b.extract_basic_block_features(f, bb)) ) for insn in a.get_instructions(f, bb): - assert list(sorted(set(a.extract_insn_features(f, bb, insn)))) == list( - sorted(set(b.extract_insn_features(f, bb, insn))) + assert sorted(set(a.extract_insn_features(f, bb, insn))) == sorted( + set(b.extract_insn_features(f, bb, insn)) ) diff --git a/tests/test_main.py b/tests/test_main.py index bda9271b..f6325d2f 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -359,7 +359,7 @@ def test_instruction_scope(z9324d_extractor): ) capabilities, meta = capa.main.find_capabilities(rules, z9324d_extractor) assert "push 1000" in capabilities - assert 0x4071A4 in set(map(lambda result: result[0], capabilities["push 1000"])) + assert 0x4071A4 in {result[0] for result in capabilities["push 1000"]} def test_instruction_subscope(z9324d_extractor): @@ -389,7 +389,7 @@ def test_instruction_subscope(z9324d_extractor): ) capabilities, meta = capa.main.find_capabilities(rules, z9324d_extractor) assert "push 1000 on i386" in capabilities - assert 0x406F60 in set(map(lambda result: result[0], capabilities["push 1000 on i386"])) + assert 0x406F60 in {result[0] for result in capabilities["push 1000 on i386"]} def test_fix262(pma16_01_extractor, capsys): @@ -433,9 +433,9 @@ def test_json_meta(capsys): std = capsys.readouterr() std_json = json.loads(std.out) - assert {"type": "absolute", "value": 0x10001010} in list( - map(lambda f: f["address"], std_json["meta"]["analysis"]["layout"]["functions"]) - ) + assert {"type": "absolute", "value": 0x10001010} in [ + f["address"] for f in std_json["meta"]["analysis"]["layout"]["functions"] + ] for addr, info in std_json["meta"]["analysis"]["layout"]["functions"]: if addr == ["absolute", 0x10001010]: diff --git a/tests/test_rules.py b/tests/test_rules.py index 69875508..afd9c012 100644 --- a/tests/test_rules.py +++ b/tests/test_rules.py @@ -874,12 +874,12 @@ def test_rules_namespace_dependencies(): ), ] - r3 = set(map(lambda r: r.name, capa.rules.get_rules_and_dependencies(rules, "rule 3"))) + r3 = {r.name for r in capa.rules.get_rules_and_dependencies(rules, "rule 3")} assert "rule 1" in r3 assert "rule 2" not in r3 assert "rule 4" not in r3 - r4 = set(map(lambda r: r.name, capa.rules.get_rules_and_dependencies(rules, "rule 4"))) + r4 = {r.name for r in capa.rules.get_rules_and_dependencies(rules, "rule 4")} assert "rule 1" in r4 assert "rule 2" in r4 assert "rule 3" not in r4