Commit 8976c6867c for bind
commit 8976c6867c4d63d8c437b32ccf884c671f95a846
Author: Štěpán Balážik <stepan@isc.org>
Date: Tue Sep 8 14:22:21 2026 +0200
Let response handlers declare a matcher
A handler declares the queries it handles in its `matcher`, which the
default match() defers to. A handler overriding match() silently
takes precedence for the time being, so that the existing handlers
keep working while they are converted one by one, until match()
itself goes.
Assisted-by: Claude:claude-fable-5
diff --git a/bin/tests/system/isctest/asyncserver/__init__.py b/bin/tests/system/isctest/asyncserver/__init__.py
index e2a81779c8..3f5673f41a 100644
--- a/bin/tests/system/isctest/asyncserver/__init__.py
+++ b/bin/tests/system/isctest/asyncserver/__init__.py
@@ -46,6 +46,7 @@ import isctest.zone
from .context import DnsProtocol, Peer, QueryContext
from .dnssec import SigningKey
+from .matchers import Always, Matcher
__all__ = [
"AsyncDnsServer",
@@ -264,20 +265,23 @@ class ResponseHandler(abc.ABC):
"""
Base class for generic response handlers.
- If a query passes the `match()` function logic, then it is handled by this
- response handler and response(s) may be generated by the `get_responses()`
- method.
+ The queries a handler handles are declared in its `matcher`; the first
+ handler whose matcher matches a query handles it, and response(s) may be
+ generated by its `get_responses()` method. The default matcher handles
+ every query.
"""
- # pylint: disable=unused-argument
+ matcher: Matcher = Always()
+
def match(self, qctx: QueryContext) -> bool:
"""
- Matching logic - the first handler whose `match()` method returns True
- is used for handling the query.
+ Whether this handler handles the query in `qctx`.
- The default for each handler is to handle all queries.
+ The default implementation defers to `matcher`, which is how handlers
+ are expected to declare what they handle. A handler overriding this
+ method still takes precedence, silently, for the time being.
"""
- return True
+ return self.matcher.match(qctx)
@abc.abstractmethod
async def get_responses(
@@ -293,7 +297,9 @@ class ResponseHandler(abc.ABC):
yield # pylint: disable=unreachable
def __str__(self) -> str:
- return self.__class__.__name__
+ if isinstance(self.matcher, Always):
+ return self.__class__.__name__
+ return f"{self.__class__.__name__} matching {self.matcher}"
@dataclass