From 5a79b36f5677604068a0a4e17cb8b69917a3529f Mon Sep 17 00:00:00 2001 From: James Addison Date: Sun, 25 Feb 2024 21:10:36 +0000 Subject: [PATCH 1/2] Preserve de-duplicated tag order in documentation The 'set' datatype in Python does not provide iteration-order guarantees related to insertion-order. That means that its usage in the 'split_csv' helper function during documentation build can produce nondeterministic results. That is non-desirable for two reasons: it means that the documentation output may appear to vary unnecessarily between builds, and secondly there could be loss-of-information in cases where tag order in the source documentation is significant. This patch implements order-preserving de-duplication of tags, allowing authors to specify tags using intentional priority ordering, while also removing tags that appear more than once. --- doc/arm/_ext/iscconf.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/doc/arm/_ext/iscconf.py b/doc/arm/_ext/iscconf.py index b5bd966e2a..32bbec2bf2 100644 --- a/doc/arm/_ext/iscconf.py +++ b/doc/arm/_ext/iscconf.py @@ -41,12 +41,18 @@ logger = logging.getLogger(__name__) def split_csv(argument, required): argument = argument or "" - outlist = list(filter(len, (s.strip() for s in argument.split(",")))) - if required and not outlist: + values = list(filter(len, (s.strip() for s in argument.split(",")))) + if required and not values: raise ValueError( "a non-empty list required; provide at least one value or remove" " this option" ) + # Order-preserving de-duplication + outlist, seen = list(), set() # pylint: disable=use-list-literal + for value in values: + if value not in seen: + seen.add(value) + outlist.append(value) return outlist @@ -73,10 +79,8 @@ def domain_factory(domainname, domainlabel, todolist, grammar): def run(self): placeholder = todolist("") - placeholder["isc_filter_tags"] = set(self.options.get("filter_tags", [])) - placeholder["isc_filter_blocks"] = set( - self.options.get("filter_blocks", []) - ) + placeholder["isc_filter_tags"] = self.options.get("filter_tags", []) + placeholder["isc_filter_blocks"] = self.options.get("filter_blocks", []) return [placeholder] class ISCConfDomain(Domain): @@ -127,7 +131,7 @@ def domain_factory(domainname, domainlabel, todolist, grammar): @property def isc_tags(self): - return set(self.options.get("tags", [])) + return self.options.get("tags", []) @property def isc_short(self): @@ -475,11 +479,11 @@ def domain_factory(domainname, domainlabel, todolist, grammar): lambda item: ( ( not acceptable_tags - or item["tags"].intersection(acceptable_tags) + or set(item["tags"]).intersection(acceptable_tags) ) and ( not acceptable_blocks - or item["block_names"].intersection( + or set(item["block_names"]).intersection( acceptable_blocks ) ) From 5b832126b32886145028405281a9b1a937dd2434 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C5=A0pa=C4=8Dek?= Date: Fri, 23 Aug 2024 15:23:10 +0200 Subject: [PATCH 2/2] Disallow duplicate statement tags in docs I can't think of a use-case for them, so let's simplify code and treat them as an invalid input. --- doc/arm/_ext/iscconf.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/doc/arm/_ext/iscconf.py b/doc/arm/_ext/iscconf.py index 32bbec2bf2..1ecd37cb8b 100644 --- a/doc/arm/_ext/iscconf.py +++ b/doc/arm/_ext/iscconf.py @@ -41,18 +41,14 @@ logger = logging.getLogger(__name__) def split_csv(argument, required): argument = argument or "" - values = list(filter(len, (s.strip() for s in argument.split(",")))) - if required and not values: + outlist = list(filter(len, (s.strip() for s in argument.split(",")))) + if required and not outlist: raise ValueError( "a non-empty list required; provide at least one value or remove" " this option" ) - # Order-preserving de-duplication - outlist, seen = list(), set() # pylint: disable=use-list-literal - for value in values: - if value not in seen: - seen.add(value) - outlist.append(value) + if not len(outlist) == len(set(outlist)): + raise ValueError("duplicate value detected") return outlist