From d6cae6068bb4186a3f821e104f381a98fe831396 Mon Sep 17 00:00:00 2001 From: "@Antelox" Date: Wed, 16 Aug 2023 13:16:04 +0200 Subject: [PATCH 1/4] Refactoring matches_filters method to fix the matching logic --- karton/core/task.py | 58 +++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 26 deletions(-) diff --git a/karton/core/task.py b/karton/core/task.py index b50399a..1186fb6 100644 --- a/karton/core/task.py +++ b/karton/core/task.py @@ -212,32 +212,38 @@ def matches_filters(self, filters: List[Dict[str, Any]]) -> bool: :meta private: """ - def value_compare(filter_value: Any, header_value: Any) -> bool: - # Coerce to string for comparison - filter_value_str = str(filter_value) - header_value_str = str(header_value) - - negated = False - if filter_value_str.startswith("!"): - negated = True - filter_value_str = filter_value_str[1:] - - if header_value is None: - return negated - - # fnmatch is great for handling simple wildcard patterns (?, *, [abc]) - # If negated: match result should not be True (XOR) - return fnmatch.fnmatchcase(header_value_str, filter_value_str) != negated - - return any( - # If any of consumer filters matches the header - all( - # Match: all consumer filter fields match the task header - value_compare(filter_value, self.headers.get(filter_key)) - for filter_key, filter_value in task_filter.items() - ) - for task_filter in filters - ) + matches = False + for task_filter in filters: + matched = [] + for filter_key, filter_value in task_filter.items(): + # Coerce to string for comparison + header_value = self.headers.get(filter_key) + filter_value_str = str(filter_value) + header_value_str = str(header_value) + + negated = False + if filter_value_str.startswith("!"): + negated = True + filter_value_str = filter_value_str[1:] + + if header_value is None: + matched.append(negated) + continue + + # fnmatch is great for handling simple wildcard patterns (?, *, [abc]) + match = fnmatch.fnmatchcase(header_value_str, filter_value_str) + # if matches, but it's negated then we can return straight away since no matter the other filters + if match and negated: + return False + + # else, apply a XOR logic to take care of negation matching + matched.append(match != negated) + + # set the flag if all consumer filter fields match the task header. + # It wil be set to True only if at least one filter matches the header + matches |= all(m for m in matched) + + return matches def set_task_parent(self, parent: "Task"): """ From 7079c8f3655d50df4048c9fd0c6ea2de3dbe017c Mon Sep 17 00:00:00 2001 From: "@Antelox" Date: Wed, 16 Aug 2023 13:27:04 +0200 Subject: [PATCH 2/4] Adding one more negated filter to the test_negated_filter unittest --- tests/test_task_filters.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_task_filters.py b/tests/test_task_filters.py index d8c5798..035b5ae 100644 --- a/tests/test_task_filters.py +++ b/tests/test_task_filters.py @@ -59,6 +59,10 @@ def test_catch_all_filter(self): def test_negated_filter(self): filters = [ + { + "type": "sample", + "platform": "!macos" + }, { "type": "sample", "platform": "!win*" From dfd6facbf0ee076a5a26e09f6553ad9a24f8a23e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Srokosz?= Date: Fri, 1 Sep 2023 13:53:20 +0200 Subject: [PATCH 3/4] Split comment to satisfy linter --- karton/core/task.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/karton/core/task.py b/karton/core/task.py index 1186fb6..53a6c7c 100644 --- a/karton/core/task.py +++ b/karton/core/task.py @@ -232,7 +232,8 @@ def matches_filters(self, filters: List[Dict[str, Any]]) -> bool: # fnmatch is great for handling simple wildcard patterns (?, *, [abc]) match = fnmatch.fnmatchcase(header_value_str, filter_value_str) - # if matches, but it's negated then we can return straight away since no matter the other filters + # if matches, but it's negated then we can return straight away + # since no matter the other filters if match and negated: return False From 65646b17be42b7cf42835ff7e54dabf1c626c517 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Srokosz?= Date: Fri, 1 Sep 2023 13:53:43 +0200 Subject: [PATCH 4/4] Fix comment typo --- karton/core/task.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/karton/core/task.py b/karton/core/task.py index 53a6c7c..f24824a 100644 --- a/karton/core/task.py +++ b/karton/core/task.py @@ -241,7 +241,7 @@ def matches_filters(self, filters: List[Dict[str, Any]]) -> bool: matched.append(match != negated) # set the flag if all consumer filter fields match the task header. - # It wil be set to True only if at least one filter matches the header + # It will be set to True only if at least one filter matches the header matches |= all(m for m in matched) return matches