Commit b7066b2892 for bind

commit b7066b2892f609406bc2e369e2f26b732bfc6e28
Author: Štěpán Balážik <stepan@isc.org>
Date:   Tue Sep 8 14:45:09 2026 +0200

    Import asyncserver names from the modules defining them

    The package re-exported everything, so a server's imports did not say
    which part of the framework it used.  The root now states its API in
    `__all__`: the architecture and the query context.

    QueryContext is the exception, still imported from the root as
    practically every server needs it next to its server, and DnsProtocol
    follows it; context.py exists only so that the coming matchers, which
    read the context, can sit between it and the root.

    Assisted-by: Claude:claude-fable-5

diff --git a/bin/tests/system/README.md b/bin/tests/system/README.md
index f3e1c031aa..d803b33400 100644
--- a/bin/tests/system/README.md
+++ b/bin/tests/system/README.md
@@ -472,12 +472,9 @@ from collections.abc import AsyncGenerator

 import dns.flags

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QueryContext,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler


 class TruncateHandler(DomainHandler):
diff --git a/bin/tests/system/bailiwick/ans1/ans.py b/bin/tests/system/bailiwick/ans1/ans.py
index 3f76b9d842..aebd3fe4d2 100644
--- a/bin/tests/system/bailiwick/ans1/ans.py
+++ b/bin/tests/system/bailiwick/ans1/ans.py
@@ -14,7 +14,8 @@ from collections.abc import AsyncGenerator
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend

 from ..bailiwick_ans import ResponseSpoofer, spoofing_server

diff --git a/bin/tests/system/bailiwick/ans2/ans.py b/bin/tests/system/bailiwick/ans2/ans.py
index d332b83e70..0b59dffc98 100644
--- a/bin/tests/system/bailiwick/ans2/ans.py
+++ b/bin/tests/system/bailiwick/ans2/ans.py
@@ -14,7 +14,8 @@ from collections.abc import AsyncGenerator
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend

 from ..bailiwick_ans import ResponseSpoofer, spoofing_server

diff --git a/bin/tests/system/chain/ans3/ans.py b/bin/tests/system/chain/ans3/ans.py
index 615d2df4eb..4e06df3551 100644
--- a/bin/tests/system/chain/ans3/ans.py
+++ b/bin/tests/system/chain/ans3/ans.py
@@ -18,12 +18,9 @@ import dns.rdatatype
 import dns.rrset
 import dns.zone

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QueryContext,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler


 def get_dname_rrset_at_name(
diff --git a/bin/tests/system/chain/ans4/ans.py b/bin/tests/system/chain/ans4/ans.py
index 0ecf3e2a68..b9771b03f8 100644
--- a/bin/tests/system/chain/ans4/ans.py
+++ b/bin/tests/system/chain/ans4/ans.py
@@ -23,13 +23,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    ControlCommand,
-    ControllableAsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QueryContext,
-)
+from isctest.asyncserver import ControlCommand, ControllableAsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler


 class ChainNameGenerator:
diff --git a/bin/tests/system/cookie/cookie_ans.py b/bin/tests/system/cookie/cookie_ans.py
index a1ed546690..e1326d1466 100644
--- a/bin/tests/system/cookie/cookie_ans.py
+++ b/bin/tests/system/cookie/cookie_ans.py
@@ -21,10 +21,10 @@ import dns.tsigkeyring
 from isctest.asyncserver import (
     AsyncDnsServer,
     DnsProtocol,
-    DnsResponseSend,
     QueryContext,
     ResponseHandler,
 )
+from isctest.asyncserver.actions import DnsResponseSend
 from isctest.name import prepend_label
 from isctest.vars.algorithms import ALG_VARS

diff --git a/bin/tests/system/cyclic_glue/ans5/ans.py b/bin/tests/system/cyclic_glue/ans5/ans.py
index 5874d96633..0d5867ef92 100644
--- a/bin/tests/system/cyclic_glue/ans5/ans.py
+++ b/bin/tests/system/cyclic_glue/ans5/ans.py
@@ -15,7 +15,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import AsyncDnsServer, QnameQtypeHandler, StaticResponseHandler
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import QnameQtypeHandler, StaticResponseHandler


 def rrset(
diff --git a/bin/tests/system/digdelv/ans4/ans.py b/bin/tests/system/digdelv/ans4/ans.py
index daa49c6792..78d5e7855b 100644
--- a/bin/tests/system/digdelv/ans4/ans.py
+++ b/bin/tests/system/digdelv/ans4/ans.py
@@ -9,7 +9,8 @@
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.

-from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import IgnoreAllQueries


 def main() -> None:
diff --git a/bin/tests/system/digdelv/ans5/ans.py b/bin/tests/system/digdelv/ans5/ans.py
index 2314d37361..5f07fd1d6c 100644
--- a/bin/tests/system/digdelv/ans5/ans.py
+++ b/bin/tests/system/digdelv/ans5/ans.py
@@ -18,13 +18,12 @@ import dns.rdatatype
 import dns.rrset

 from isctest.asyncserver import (
-    CloseConnection,
     ControlCommand,
     ControllableAsyncDnsServer,
-    DnsResponseSend,
     QueryContext,
     ResponseHandler,
 )
+from isctest.asyncserver.actions import CloseConnection, DnsResponseSend


 class ErraticAxfrHandler(ResponseHandler):
diff --git a/bin/tests/system/digdelv/ans6/ans.py b/bin/tests/system/digdelv/ans6/ans.py
index f1f59aea72..21c5704e6c 100644
--- a/bin/tests/system/digdelv/ans6/ans.py
+++ b/bin/tests/system/digdelv/ans6/ans.py
@@ -14,12 +14,8 @@ from collections.abc import AsyncGenerator
 import dns.opcode
 import dns.rcode

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend


 class ReplyUpdateHandler(ResponseHandler):
diff --git a/bin/tests/system/digdelv/ans7/ans.py b/bin/tests/system/digdelv/ans7/ans.py
index e7f3b49ffd..63c8f8ac4d 100644
--- a/bin/tests/system/digdelv/ans7/ans.py
+++ b/bin/tests/system/digdelv/ans7/ans.py
@@ -13,15 +13,9 @@ from collections.abc import AsyncGenerator

 import dns.rcode

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    CloseConnection,
-    DnsResponseSend,
-    DomainHandler,
-    IgnoreAllQueries,
-    QueryContext,
-    ResponseDrop,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import CloseConnection, DnsResponseSend, ResponseDrop
+from isctest.asyncserver.handlers import DomainHandler, IgnoreAllQueries


 class SilentHandler(DomainHandler, IgnoreAllQueries):
diff --git a/bin/tests/system/dispatch/ans3/ans.py b/bin/tests/system/dispatch/ans3/ans.py
index b0ef86350a..dc2c229625 100644
--- a/bin/tests/system/dispatch/ans3/ans.py
+++ b/bin/tests/system/dispatch/ans3/ans.py
@@ -16,12 +16,12 @@ import dns.rcode

 from isctest.asyncserver import (
     AsyncDnsServer,
-    ConnectionReset,
     DnsProtocol,
-    DnsResponseSend,
     QueryContext,
     ResponseHandler,
 )
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import ConnectionReset


 class TruncateOnUdpHandler(ResponseHandler):
diff --git a/bin/tests/system/dispatch/ans4/ans.py b/bin/tests/system/dispatch/ans4/ans.py
index e640873eb3..f85bdae7f0 100644
--- a/bin/tests/system/dispatch/ans4/ans.py
+++ b/bin/tests/system/dispatch/ans4/ans.py
@@ -14,11 +14,10 @@ from collections.abc import AsyncGenerator
 from isctest.asyncserver import (
     AsyncDnsServer,
     DnsProtocol,
-    DnsResponseSend,
     QueryContext,
-    ResponseDrop,
     ResponseHandler,
 )
+from isctest.asyncserver.actions import DnsResponseSend, ResponseDrop


 class DropUdpHandler(ResponseHandler):
diff --git a/bin/tests/system/dnssec/ans10/ans.py b/bin/tests/system/dnssec/ans10/ans.py
index 45494cf261..246701be3a 100644
--- a/bin/tests/system/dnssec/ans10/ans.py
+++ b/bin/tests/system/dnssec/ans10/ans.py
@@ -14,12 +14,8 @@ from collections.abc import AsyncGenerator
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend


 class AddRrsigToAHandler(ResponseHandler):
diff --git a/bin/tests/system/dnssec_cname_response/ans2/ans.py b/bin/tests/system/dnssec_cname_response/ans2/ans.py
index d5f53e3453..11bbc207e5 100644
--- a/bin/tests/system/dnssec_cname_response/ans2/ans.py
+++ b/bin/tests/system/dnssec_cname_response/ans2/ans.py
@@ -19,13 +19,9 @@ import dns.rdatatype
 import dns.rrset
 import dns.zone

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 # 'example.' answers DNSKEY/NSEC/NSEC3/RRSIG queries with a CNAME (the
 # meta-types whose CNAME answer the resolver and validator must cope with).
diff --git a/bin/tests/system/dnssec_nsec3/ans1/f025.py b/bin/tests/system/dnssec_nsec3/ans1/f025.py
index 70ea3e7075..7149172fde 100644
--- a/bin/tests/system/dnssec_nsec3/ans1/f025.py
+++ b/bin/tests/system/dnssec_nsec3/ans1/f025.py
@@ -31,7 +31,9 @@ from dnssec_nsec3.ans1.common import (
     rrset_from_rdata,
     soa_rrset,
 )
-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 TTL = 300
 PARENT = "f025.test."
diff --git a/bin/tests/system/dnssec_nsec3/ans1/f055.py b/bin/tests/system/dnssec_nsec3/ans1/f055.py
index bc636678ca..2a79d84ea3 100644
--- a/bin/tests/system/dnssec_nsec3/ans1/f055.py
+++ b/bin/tests/system/dnssec_nsec3/ans1/f055.py
@@ -34,7 +34,9 @@ from dnssec_nsec3.ans1.common import (
     rrset_from_rdata,
     soa_rrset,
 )
-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 TTL = 300
 F055_ZONE = "f055.test."
diff --git a/bin/tests/system/dnssec_parent_rrsig/ans1/ans.py b/bin/tests/system/dnssec_parent_rrsig/ans1/ans.py
index 0bdf6a8c2b..2912e436e7 100644
--- a/bin/tests/system/dnssec_parent_rrsig/ans1/ans.py
+++ b/bin/tests/system/dnssec_parent_rrsig/ans1/ans.py
@@ -27,12 +27,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend

 TTL = 300
 PARENT = "f044.test."
diff --git a/bin/tests/system/dnssec_py/ans4/delegationtrap_ans.py b/bin/tests/system/dnssec_py/ans4/delegationtrap_ans.py
index 294fc0a5b6..95cd72ed0a 100644
--- a/bin/tests/system/dnssec_py/ans4/delegationtrap_ans.py
+++ b/bin/tests/system/dnssec_py/ans4/delegationtrap_ans.py
@@ -54,7 +54,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 ZONE_NAME = "attack.delegationtrap."
 SERVER_IP = "10.53.0.4"
diff --git a/bin/tests/system/dnssec_py/ans4/noqname_mismatch.py b/bin/tests/system/dnssec_py/ans4/noqname_mismatch.py
index 8ab55fa511..e5c53f0277 100644
--- a/bin/tests/system/dnssec_py/ans4/noqname_mismatch.py
+++ b/bin/tests/system/dnssec_py/ans4/noqname_mismatch.py
@@ -36,7 +36,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 TTL = 300
 ZONE = "f217.test."
diff --git a/bin/tests/system/dnssec_py/ans4/rrsig_labels_signer_ans.py b/bin/tests/system/dnssec_py/ans4/rrsig_labels_signer_ans.py
index 4c100420e9..ae04cd8833 100644
--- a/bin/tests/system/dnssec_py/ans4/rrsig_labels_signer_ans.py
+++ b/bin/tests/system/dnssec_py/ans4/rrsig_labels_signer_ans.py
@@ -53,7 +53,9 @@ import dns.rdatatype
 import dns.rdtypes.ANY.NSEC3
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 ZONE_NAME = "attacker.rrsig-labels-signer."
 PARENT_ZONE_NAME = "rrsig-labels-signer."
diff --git a/bin/tests/system/dnssec_py/ans4/sibling_ds_ans.py b/bin/tests/system/dnssec_py/ans4/sibling_ds_ans.py
index a1c5967e9e..b1e1348ee0 100644
--- a/bin/tests/system/dnssec_py/ans4/sibling_ds_ans.py
+++ b/bin/tests/system/dnssec_py/ans4/sibling_ds_ans.py
@@ -23,7 +23,9 @@ from collections.abc import AsyncGenerator
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler


 class SiblingDsInjectionHandler(DomainHandler):
diff --git a/bin/tests/system/dnssec_wildcard/ans1/ans.py b/bin/tests/system/dnssec_wildcard/ans1/ans.py
index 812a23281a..843d1935dd 100644
--- a/bin/tests/system/dnssec_wildcard/ans1/ans.py
+++ b/bin/tests/system/dnssec_wildcard/ans1/ans.py
@@ -15,12 +15,9 @@ import dns.name
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QnameQtypeHandler,
-    QueryContext,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import QnameQtypeHandler


 def append_forged_a_rrset_to_additional(qctx: QueryContext, owner_name: str) -> None:
diff --git a/bin/tests/system/fetchlimit/ans4/ans.py b/bin/tests/system/fetchlimit/ans4/ans.py
index a6d5a9a07b..6fbafcffaa 100644
--- a/bin/tests/system/fetchlimit/ans4/ans.py
+++ b/bin/tests/system/fetchlimit/ans4/ans.py
@@ -17,11 +17,11 @@ import dns.rrset

 from isctest.asyncserver import (
     ControllableAsyncDnsServer,
-    DnsResponseSend,
     QueryContext,
     ResponseHandler,
-    ToggleResponsesCommand,
 )
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.commands import ToggleResponsesCommand


 class MaybeDelayedAddressAnswerHandler(ResponseHandler):
diff --git a/bin/tests/system/filters/ans6/ans.py b/bin/tests/system/filters/ans6/ans.py
index 6731aba1bc..f2cacb3171 100644
--- a/bin/tests/system/filters/ans6/ans.py
+++ b/bin/tests/system/filters/ans6/ans.py
@@ -14,12 +14,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    QnameQtypeHandler,
-    QueryContext,
-    StaticResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.handlers import QnameQtypeHandler, StaticResponseHandler

 DNS64_TRIGGER = "nodata.test."

diff --git a/bin/tests/system/forward/ans11/ans.py b/bin/tests/system/forward/ans11/ans.py
index 06a7ddc96c..dec74dac7e 100644
--- a/bin/tests/system/forward/ans11/ans.py
+++ b/bin/tests/system/forward/ans11/ans.py
@@ -14,13 +14,10 @@ from collections.abc import AsyncGenerator
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    ControllableAsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QueryContext,
-    ToggleResponsesCommand,
-)
+from isctest.asyncserver import ControllableAsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.commands import ToggleResponsesCommand
+from isctest.asyncserver.handlers import DomainHandler


 class ExtraAnswersHandler(DomainHandler):
diff --git a/bin/tests/system/forward/ans6/ans.py b/bin/tests/system/forward/ans6/ans.py
index af7a37bbe6..cdff896a69 100644
--- a/bin/tests/system/forward/ans6/ans.py
+++ b/bin/tests/system/forward/ans6/ans.py
@@ -19,13 +19,15 @@ import dns.rrset

 from isctest.asyncserver import (
     ControllableAsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QnameQtypeHandler,
     QueryContext,
     ResponseHandler,
+)
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.commands import ToggleResponsesCommand
+from isctest.asyncserver.handlers import (
+    DomainHandler,
+    QnameQtypeHandler,
     StaticResponseHandler,
-    ToggleResponsesCommand,
 )

 SLD = "sld.tld."
diff --git a/bin/tests/system/fwdfirst/ans2/ans.py b/bin/tests/system/fwdfirst/ans2/ans.py
index c846275d50..497cac9618 100644
--- a/bin/tests/system/fwdfirst/ans2/ans.py
+++ b/bin/tests/system/fwdfirst/ans2/ans.py
@@ -14,7 +14,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import AsyncDnsServer, DomainHandler, StaticResponseHandler
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import DomainHandler, StaticResponseHandler


 class PoisonReferralForwarder(DomainHandler, StaticResponseHandler):
diff --git a/bin/tests/system/fwdfirst/ans3/ans.py b/bin/tests/system/fwdfirst/ans3/ans.py
index e05d37206f..da2624995f 100644
--- a/bin/tests/system/fwdfirst/ans3/ans.py
+++ b/bin/tests/system/fwdfirst/ans3/ans.py
@@ -14,7 +14,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import AsyncDnsServer, QnameQtypeHandler, StaticResponseHandler
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import QnameQtypeHandler, StaticResponseHandler

 VICTIM = "victim.sibling.hack."
 POISON_ADDRESS = "6.6.6.6"
diff --git a/bin/tests/system/isctest/asyncserver/__init__.py b/bin/tests/system/isctest/asyncserver/__init__.py
index 85efd5f561..e2a81779c8 100644
--- a/bin/tests/system/isctest/asyncserver/__init__.py
+++ b/bin/tests/system/isctest/asyncserver/__init__.py
@@ -47,6 +47,18 @@ import isctest.zone
 from .context import DnsProtocol, Peer, QueryContext
 from .dnssec import SigningKey

+__all__ = [
+    "AsyncDnsServer",
+    "AsyncServer",
+    "ConnectionHandler",
+    "ControlCommand",
+    "ControllableAsyncDnsServer",
+    "DnsProtocol",
+    "QueryContext",
+    "ResponseAction",
+    "ResponseHandler",
+]
+
 _UdpHandler = Callable[
     [bytes, tuple[str, int], asyncio.DatagramTransport], Coroutine[Any, Any, None]
 ]
@@ -1173,65 +1185,3 @@ class ControlCommand(abc.ABC):

     def __str__(self) -> str:
         return self.__class__.__name__
-
-
-# The concrete handlers, actions, commands and provers are re-exported here, so
-# that the custom servers keep importing everything from the package.  They
-# import the architecture above from the package in turn, hence the position.
-# pylint: disable=wrong-import-position,cyclic-import
-from .actions import BytesResponseSend, CloseConnection, DnsResponseSend, ResponseDrop
-from .commands import SwitchControlCommand, ToggleResponsesCommand
-from .dnssec import (
-    NonExistenceException,
-    NonExistenceProver,
-    Nsec3NonExistenceProver,
-    NsecNonExistenceProver,
-)
-from .handlers import (
-    AxfrHandler,
-    ConnectionReset,
-    DomainHandler,
-    ForwarderHandler,
-    IgnoreAllConnections,
-    IgnoreAllQueries,
-    QnameHandler,
-    QnameQtypeHandler,
-    ResponseHandlerWrapper,
-    StaticResponseHandler,
-    block_reading,
-)
-
-__all__ = [
-    "AsyncDnsServer",
-    "AsyncServer",
-    "AxfrHandler",
-    "BytesResponseSend",
-    "CloseConnection",
-    "ConnectionHandler",
-    "ConnectionReset",
-    "ControlCommand",
-    "ControllableAsyncDnsServer",
-    "DnsProtocol",
-    "DnsResponseSend",
-    "DomainHandler",
-    "ForwarderHandler",
-    "IgnoreAllConnections",
-    "IgnoreAllQueries",
-    "NonExistenceException",
-    "NonExistenceProver",
-    "Nsec3NonExistenceProver",
-    "NsecNonExistenceProver",
-    "Peer",
-    "QnameHandler",
-    "QnameQtypeHandler",
-    "QueryContext",
-    "ResponseAction",
-    "ResponseDrop",
-    "ResponseHandler",
-    "ResponseHandlerWrapper",
-    "SigningKey",
-    "StaticResponseHandler",
-    "SwitchControlCommand",
-    "ToggleResponsesCommand",
-    "block_reading",
-]
diff --git a/bin/tests/system/ixfr/ans2/ans.py b/bin/tests/system/ixfr/ans2/ans.py
index 4878d4ed72..a1234f91e9 100644
--- a/bin/tests/system/ixfr/ans2/ans.py
+++ b/bin/tests/system/ixfr/ans2/ans.py
@@ -19,13 +19,13 @@ import dns.rdatatype
 import dns.rrset

 from isctest.asyncserver import (
-    AxfrHandler,
     ControllableAsyncDnsServer,
-    DnsResponseSend,
     QueryContext,
     ResponseHandler,
-    SwitchControlCommand,
 )
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.commands import SwitchControlCommand
+from isctest.asyncserver.handlers import AxfrHandler


 def rrset(owner: str, rdtype: dns.rdatatype.RdataType, rdata: str) -> dns.rrset.RRset:
diff --git a/bin/tests/system/mismatchtcp/ans2/ans.py b/bin/tests/system/mismatchtcp/ans2/ans.py
index 4b392233be..650b209f7d 100644
--- a/bin/tests/system/mismatchtcp/ans2/ans.py
+++ b/bin/tests/system/mismatchtcp/ans2/ans.py
@@ -13,13 +13,9 @@ from collections.abc import AsyncGenerator

 import dns.rdatatype

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsProtocol,
-    DnsResponseSend,
-    QnameQtypeHandler,
-    QueryContext,
-)
+from isctest.asyncserver import AsyncDnsServer, DnsProtocol, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import QnameQtypeHandler


 class MismatchedIdOnUdpHandler(QnameQtypeHandler):
diff --git a/bin/tests/system/nsec3/ans7/ans.py b/bin/tests/system/nsec3/ans7/ans.py
index 1eb4a356a7..08ba3e4b22 100644
--- a/bin/tests/system/nsec3/ans7/ans.py
+++ b/bin/tests/system/nsec3/ans7/ans.py
@@ -31,14 +31,9 @@ import dns.rrset
 import dns.tokenizer
 import dns.zone

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    ForwarderHandler,
-    QueryContext,
-    ResponseAction,
-    ResponseHandlerWrapper,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseAction
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import ForwarderHandler, ResponseHandlerWrapper
 from isctest.zone import FileZoneKey

 # The malicious proxy relays every query to the real signed authoritative
diff --git a/bin/tests/system/nsec3_impersonation/ans1/ans.py b/bin/tests/system/nsec3_impersonation/ans1/ans.py
index c9490a100d..6cd2986368 100644
--- a/bin/tests/system/nsec3_impersonation/ans1/ans.py
+++ b/bin/tests/system/nsec3_impersonation/ans1/ans.py
@@ -27,12 +27,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend

 TTL = 300
 TLD = "tld.test."
diff --git a/bin/tests/system/nsec_grandparent/ans1/ans.py b/bin/tests/system/nsec_grandparent/ans1/ans.py
index 590b42bcbc..712b8577d0 100644
--- a/bin/tests/system/nsec_grandparent/ans1/ans.py
+++ b/bin/tests/system/nsec_grandparent/ans1/ans.py
@@ -27,12 +27,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend

 TTL = 300
 PARENT = "p031.test."
diff --git a/bin/tests/system/nsec_piggyback/ans1/ans.py b/bin/tests/system/nsec_piggyback/ans1/ans.py
index 6882210eab..f13518c017 100644
--- a/bin/tests/system/nsec_piggyback/ans1/ans.py
+++ b/bin/tests/system/nsec_piggyback/ans1/ans.py
@@ -28,12 +28,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend

 TTL = 300
 PARENT = "p22.hack."
diff --git a/bin/tests/system/nsec_synthesis/ans1/f004.py b/bin/tests/system/nsec_synthesis/ans1/f004.py
index c4dc0eb2a3..497c745721 100644
--- a/bin/tests/system/nsec_synthesis/ans1/f004.py
+++ b/bin/tests/system/nsec_synthesis/ans1/f004.py
@@ -21,7 +21,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler
 from nsec_synthesis.ans1.common import (
     Key,
     add_signed,
diff --git a/bin/tests/system/nsec_synthesis/ans1/f023.py b/bin/tests/system/nsec_synthesis/ans1/f023.py
index a2caa9c2d5..af66ac875c 100644
--- a/bin/tests/system/nsec_synthesis/ans1/f023.py
+++ b/bin/tests/system/nsec_synthesis/ans1/f023.py
@@ -21,7 +21,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler
 from nsec_synthesis.ans1.common import (
     Key,
     add_signed,
diff --git a/bin/tests/system/nsec_wildcard_wrong_zone/ans1/ans.py b/bin/tests/system/nsec_wildcard_wrong_zone/ans1/ans.py
index 45c94b1f3d..b7dc752c2d 100644
--- a/bin/tests/system/nsec_wildcard_wrong_zone/ans1/ans.py
+++ b/bin/tests/system/nsec_wildcard_wrong_zone/ans1/ans.py
@@ -26,12 +26,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QueryContext,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 TTL = 300
 VICTIM = "victim.example."
diff --git a/bin/tests/system/nsupdate/ans11/ans.py b/bin/tests/system/nsupdate/ans11/ans.py
index acfca79490..114b518cda 100644
--- a/bin/tests/system/nsupdate/ans11/ans.py
+++ b/bin/tests/system/nsupdate/ans11/ans.py
@@ -15,8 +15,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import (
     AxfrHandler,
     QnameQtypeHandler,
     StaticResponseHandler,
diff --git a/bin/tests/system/nsupdate/ans4/ans.py b/bin/tests/system/nsupdate/ans4/ans.py
index cb16548618..fc6c9a807e 100644
--- a/bin/tests/system/nsupdate/ans4/ans.py
+++ b/bin/tests/system/nsupdate/ans4/ans.py
@@ -9,7 +9,8 @@
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.

-from isctest.asyncserver import AsyncDnsServer, IgnoreAllConnections, IgnoreAllQueries
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import IgnoreAllConnections, IgnoreAllQueries


 def main() -> None:
diff --git a/bin/tests/system/pipelined/ans5/ans.py b/bin/tests/system/pipelined/ans5/ans.py
index f62f4d5b2f..3bb6f9e4e4 100644
--- a/bin/tests/system/pipelined/ans5/ans.py
+++ b/bin/tests/system/pipelined/ans5/ans.py
@@ -9,7 +9,8 @@
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.

-from isctest.asyncserver import AsyncDnsServer, ForwarderHandler
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import ForwarderHandler


 class ForwardToNs2(ForwarderHandler):
diff --git a/bin/tests/system/qmin/ans2/ans.py b/bin/tests/system/qmin/ans2/ans.py
index 283abce657..b1a4fb90f0 100644
--- a/bin/tests/system/qmin/ans2/ans.py
+++ b/bin/tests/system/qmin/ans2/ans.py
@@ -16,12 +16,9 @@ import dns.rcode
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QueryContext,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 from ..qmin_ans import (
     DelayedResponseHandler,
diff --git a/bin/tests/system/qmin/ans4/ans.py b/bin/tests/system/qmin/ans4/ans.py
index df7f271744..024e22c3fe 100644
--- a/bin/tests/system/qmin/ans4/ans.py
+++ b/bin/tests/system/qmin/ans4/ans.py
@@ -14,12 +14,9 @@ from collections.abc import AsyncGenerator
 import dns.rcode
 import dns.rdatatype

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    DomainHandler,
-    QueryContext,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler

 from ..qmin_ans import (
     DelayedResponseHandler,
diff --git a/bin/tests/system/qmin/qmin_ans.py b/bin/tests/system/qmin/qmin_ans.py
index 9eaa50022d..285578e332 100644
--- a/bin/tests/system/qmin/qmin_ans.py
+++ b/bin/tests/system/qmin/qmin_ans.py
@@ -16,7 +16,9 @@ import abc
 import dns.rcode
 import dns.rdatatype

-from isctest.asyncserver import DnsResponseSend, DomainHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler


 def log_query(qctx: QueryContext) -> None:
diff --git a/bin/tests/system/qpcache_rrsig_any/ans3/ans.py b/bin/tests/system/qpcache_rrsig_any/ans3/ans.py
index 8360baf160..8f47757163 100644
--- a/bin/tests/system/qpcache_rrsig_any/ans3/ans.py
+++ b/bin/tests/system/qpcache_rrsig_any/ans3/ans.py
@@ -17,14 +17,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QnameHandler,
-    QueryContext,
-    ResponseHandler,
-    StaticResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import QnameHandler, StaticResponseHandler


 def rrsig_covering(
diff --git a/bin/tests/system/reclimit/ans2/ans.py b/bin/tests/system/reclimit/ans2/ans.py
index c320722f3d..6b6d9ca217 100644
--- a/bin/tests/system/reclimit/ans2/ans.py
+++ b/bin/tests/system/reclimit/ans2/ans.py
@@ -13,11 +13,8 @@ from collections.abc import AsyncGenerator

 import dns.rcode

-from isctest.asyncserver import (
-    ControllableAsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-)
+from isctest.asyncserver import ControllableAsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend

 from ..reclimit_ans import (
     DirectExampleHandler,
diff --git a/bin/tests/system/reclimit/ans7/ans.py b/bin/tests/system/reclimit/ans7/ans.py
index 79a2c4bbd0..ab36942ac9 100644
--- a/bin/tests/system/reclimit/ans7/ans.py
+++ b/bin/tests/system/reclimit/ans7/ans.py
@@ -13,7 +13,8 @@ from collections.abc import AsyncGenerator

 import dns.rcode

-from isctest.asyncserver import AsyncDnsServer, DnsResponseSend, QueryContext
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend

 from ..reclimit_ans import ReclimitHandler, ReclimitStateHandler

diff --git a/bin/tests/system/reclimit/reclimit_ans.py b/bin/tests/system/reclimit/reclimit_ans.py
index 1e9eaac30a..3c35d0b489 100644
--- a/bin/tests/system/reclimit/reclimit_ans.py
+++ b/bin/tests/system/reclimit/reclimit_ans.py
@@ -25,11 +25,11 @@ import dns.rrset
 from isctest.asyncserver import (
     ControlCommand,
     ControllableAsyncDnsServer,
-    DnsResponseSend,
-    QnameHandler,
     QueryContext,
     ResponseHandler,
 )
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import QnameHandler


 class ReclimitStateHandler(QnameHandler):
diff --git a/bin/tests/system/resend_loop/ans3/ans.py b/bin/tests/system/resend_loop/ans3/ans.py
index 3e9369393a..393ba43d99 100644
--- a/bin/tests/system/resend_loop/ans3/ans.py
+++ b/bin/tests/system/resend_loop/ans3/ans.py
@@ -18,13 +18,12 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
+from isctest.asyncserver import AsyncDnsServer, QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import (
     DomainHandler,
     QnameHandler,
     QnameQtypeHandler,
-    QueryContext,
     StaticResponseHandler,
 )

diff --git a/bin/tests/system/resolver/ans10/ans.py b/bin/tests/system/resolver/ans10/ans.py
index 8361a97fa2..c54412e5de 100644
--- a/bin/tests/system/resolver/ans10/ans.py
+++ b/bin/tests/system/resolver/ans10/ans.py
@@ -14,12 +14,8 @@ from collections.abc import AsyncGenerator
 import dns.rcode
 import dns.rdatatype

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend

 from ..resolver_ans import rrset, soa_rrset

diff --git a/bin/tests/system/resolver/ans2/ans.py b/bin/tests/system/resolver/ans2/ans.py
index 08bb529583..1c9aebe22a 100644
--- a/bin/tests/system/resolver/ans2/ans.py
+++ b/bin/tests/system/resolver/ans2/ans.py
@@ -17,15 +17,13 @@ import dns.rcode
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import (
     DomainHandler,
     IgnoreAllQueries,
     QnameHandler,
     QnameQtypeHandler,
-    QueryContext,
-    ResponseHandler,
     StaticResponseHandler,
 )

diff --git a/bin/tests/system/resolver/ans3/ans.py b/bin/tests/system/resolver/ans3/ans.py
index 0ef4a815f0..e4c92b1fa0 100644
--- a/bin/tests/system/resolver/ans3/ans.py
+++ b/bin/tests/system/resolver/ans3/ans.py
@@ -15,15 +15,13 @@ import dns.name
 import dns.rcode
 import dns.rdatatype

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import (
     DomainHandler,
     IgnoreAllQueries,
     QnameHandler,
     QnameQtypeHandler,
-    QueryContext,
-    ResponseHandler,
     StaticResponseHandler,
 )

diff --git a/bin/tests/system/resolver/ans8/ans.py b/bin/tests/system/resolver/ans8/ans.py
index 08e870e8a7..446aa428ed 100644
--- a/bin/tests/system/resolver/ans8/ans.py
+++ b/bin/tests/system/resolver/ans8/ans.py
@@ -21,12 +21,14 @@ import dns.rdatatype
 from isctest.asyncserver import (
     AsyncDnsServer,
     DnsProtocol,
-    DnsResponseSend,
+    QueryContext,
+    ResponseHandler,
+)
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import (
     DomainHandler,
     QnameHandler,
     QnameQtypeHandler,
-    QueryContext,
-    ResponseHandler,
     StaticResponseHandler,
 )

diff --git a/bin/tests/system/resolver/resolver_ans.py b/bin/tests/system/resolver/resolver_ans.py
index 853c04f845..d81a67e0d6 100644
--- a/bin/tests/system/resolver/resolver_ans.py
+++ b/bin/tests/system/resolver/resolver_ans.py
@@ -19,12 +19,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    DnsResponseSend,
-    DomainHandler,
-    QnameHandler,
-    QueryContext,
-)
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import DomainHandler, QnameHandler


 def rrset(
diff --git a/bin/tests/system/rpzrecurse/ans5/ans.py b/bin/tests/system/rpzrecurse/ans5/ans.py
index 514a30d78d..bc1b2a9f9c 100644
--- a/bin/tests/system/rpzrecurse/ans5/ans.py
+++ b/bin/tests/system/rpzrecurse/ans5/ans.py
@@ -15,12 +15,8 @@ import dns.rcode
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend


 class ReplyA(ResponseHandler):
diff --git a/bin/tests/system/rpzrecurse/ans6/ans.py b/bin/tests/system/rpzrecurse/ans6/ans.py
index e1b1bd669a..434ee2bc22 100644
--- a/bin/tests/system/rpzrecurse/ans6/ans.py
+++ b/bin/tests/system/rpzrecurse/ans6/ans.py
@@ -15,12 +15,8 @@ import dns.rcode
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend


 class ReplyA(ResponseHandler):
diff --git a/bin/tests/system/serve_stale/ans2/ans.py b/bin/tests/system/serve_stale/ans2/ans.py
index 1fbb0a951d..add5b14d9e 100644
--- a/bin/tests/system/serve_stale/ans2/ans.py
+++ b/bin/tests/system/serve_stale/ans2/ans.py
@@ -12,13 +12,12 @@
 import dns.rcode
 import dns.rdatatype

-from isctest.asyncserver import (
-    ControllableAsyncDnsServer,
+from isctest.asyncserver import ControllableAsyncDnsServer, ResponseHandler
+from isctest.asyncserver.commands import ToggleResponsesCommand
+from isctest.asyncserver.handlers import (
     QnameHandler,
     QnameQtypeHandler,
-    ResponseHandler,
     StaticResponseHandler,
-    ToggleResponsesCommand,
 )

 from ..serve_stale_ans import (
diff --git a/bin/tests/system/serve_stale/ans8/ans.py b/bin/tests/system/serve_stale/ans8/ans.py
index 5665f161dd..1573dee6d6 100644
--- a/bin/tests/system/serve_stale/ans8/ans.py
+++ b/bin/tests/system/serve_stale/ans8/ans.py
@@ -11,13 +11,9 @@

 import dns.rcode

-from isctest.asyncserver import (
-    ControllableAsyncDnsServer,
-    QnameHandler,
-    ResponseHandler,
-    StaticResponseHandler,
-    SwitchControlCommand,
-)
+from isctest.asyncserver import ControllableAsyncDnsServer, ResponseHandler
+from isctest.asyncserver.commands import SwitchControlCommand
+from isctest.asyncserver.handlers import QnameHandler, StaticResponseHandler

 from ..serve_stale_ans import (
     a_handler,
diff --git a/bin/tests/system/serve_stale/serve_stale_ans.py b/bin/tests/system/serve_stale/serve_stale_ans.py
index c01fe7ea17..983b92df8a 100644
--- a/bin/tests/system/serve_stale/serve_stale_ans.py
+++ b/bin/tests/system/serve_stale/serve_stale_ans.py
@@ -17,7 +17,8 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import QueryContext, ResponseHandler, StaticResponseHandler
+from isctest.asyncserver import QueryContext, ResponseHandler
+from isctest.asyncserver.handlers import StaticResponseHandler


 def rrset(
diff --git a/bin/tests/system/srtt/ans2/ans.py b/bin/tests/system/srtt/ans2/ans.py
index d92f49383f..ea43f567c8 100644
--- a/bin/tests/system/srtt/ans2/ans.py
+++ b/bin/tests/system/srtt/ans2/ans.py
@@ -11,7 +11,8 @@

 import dns.rcode

-from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import IgnoreAllQueries

 from ..srtt_ans import DelayedQnameRangeHandler

diff --git a/bin/tests/system/srtt/ans3/ans.py b/bin/tests/system/srtt/ans3/ans.py
index 7c339461d2..98c35ef60a 100644
--- a/bin/tests/system/srtt/ans3/ans.py
+++ b/bin/tests/system/srtt/ans3/ans.py
@@ -11,7 +11,8 @@

 import dns.rcode

-from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import IgnoreAllQueries

 from ..srtt_ans import DelayedQnameRangeHandler

diff --git a/bin/tests/system/srtt/ans4/ans.py b/bin/tests/system/srtt/ans4/ans.py
index ac8ea61bf8..2307d92eef 100644
--- a/bin/tests/system/srtt/ans4/ans.py
+++ b/bin/tests/system/srtt/ans4/ans.py
@@ -11,7 +11,8 @@

 import dns.rcode

-from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import IgnoreAllQueries

 from ..srtt_ans import DelayedQnameRangeHandler

diff --git a/bin/tests/system/srtt/ans5/ans.py b/bin/tests/system/srtt/ans5/ans.py
index 40d97afe4d..0c12a07b35 100644
--- a/bin/tests/system/srtt/ans5/ans.py
+++ b/bin/tests/system/srtt/ans5/ans.py
@@ -11,7 +11,8 @@

 import dns.rcode

-from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import IgnoreAllQueries

 from ..srtt_ans import DelayedQnameRangeHandler

diff --git a/bin/tests/system/srtt/srtt_ans.py b/bin/tests/system/srtt/srtt_ans.py
index fae6eb53b2..0433604e64 100644
--- a/bin/tests/system/srtt/srtt_ans.py
+++ b/bin/tests/system/srtt/srtt_ans.py
@@ -17,7 +17,9 @@ import dns.rdataclass
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import DnsResponseSend, QnameQtypeHandler, QueryContext
+from isctest.asyncserver import QueryContext
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import QnameQtypeHandler


 class DelayedQnameRangeHandler(QnameQtypeHandler):
diff --git a/bin/tests/system/statistics/ans4/ans.py b/bin/tests/system/statistics/ans4/ans.py
index be5f3bb0d4..37fea5fcd5 100644
--- a/bin/tests/system/statistics/ans4/ans.py
+++ b/bin/tests/system/statistics/ans4/ans.py
@@ -15,14 +15,9 @@ import dns.rcode
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    IgnoreAllQueries,
-    QnameHandler,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import IgnoreAllQueries, QnameHandler


 class FooInfoHandler(QnameHandler, IgnoreAllQueries):
diff --git a/bin/tests/system/statschannel/ans5/ans.py b/bin/tests/system/statschannel/ans5/ans.py
index f2824df2e0..c0197f7944 100644
--- a/bin/tests/system/statschannel/ans5/ans.py
+++ b/bin/tests/system/statschannel/ans5/ans.py
@@ -17,10 +17,10 @@ import dns.rrset

 from isctest.asyncserver import (
     ControllableAsyncDnsServer,
-    DnsResponseSend,
     QueryContext,
     ResponseHandler,
 )
+from isctest.asyncserver.actions import DnsResponseSend


 class DelayedAddressAnswerHandler(ResponseHandler):
diff --git a/bin/tests/system/tsig/ans2/ans.py b/bin/tests/system/tsig/ans2/ans.py
index 552de52e21..0f88185785 100644
--- a/bin/tests/system/tsig/ans2/ans.py
+++ b/bin/tests/system/tsig/ans2/ans.py
@@ -13,12 +13,8 @@ from collections.abc import AsyncGenerator

 import dns.flags

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    BytesResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import BytesResponseSend


 class TruncatedWithLastByteDroppedHandler(ResponseHandler):
diff --git a/bin/tests/system/upforwd/ans4/ans.py b/bin/tests/system/upforwd/ans4/ans.py
index daa49c6792..78d5e7855b 100644
--- a/bin/tests/system/upforwd/ans4/ans.py
+++ b/bin/tests/system/upforwd/ans4/ans.py
@@ -9,7 +9,8 @@
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.

-from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import IgnoreAllQueries


 def main() -> None:
diff --git a/bin/tests/system/xfer/ans10/ans.py b/bin/tests/system/xfer/ans10/ans.py
index daa49c6792..78d5e7855b 100644
--- a/bin/tests/system/xfer/ans10/ans.py
+++ b/bin/tests/system/xfer/ans10/ans.py
@@ -9,7 +9,8 @@
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.

-from isctest.asyncserver import AsyncDnsServer, IgnoreAllQueries
+from isctest.asyncserver import AsyncDnsServer
+from isctest.asyncserver.handlers import IgnoreAllQueries


 def main() -> None:
diff --git a/bin/tests/system/xfer/ans11/ans.py b/bin/tests/system/xfer/ans11/ans.py
index fbaeef1e7e..41d9009bac 100644
--- a/bin/tests/system/xfer/ans11/ans.py
+++ b/bin/tests/system/xfer/ans11/ans.py
@@ -19,13 +19,12 @@ import dns.rrset

 from isctest.asyncserver import (
     AsyncDnsServer,
-    AxfrHandler,
     DnsProtocol,
-    DnsResponseSend,
     QueryContext,
     ResponseHandler,
-    StaticResponseHandler,
 )
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.handlers import AxfrHandler, StaticResponseHandler

 ZONE = "ixfr-race."
 NS_NAME = f"ns.{ZONE}"
diff --git a/bin/tests/system/xfer/ans5/ans.py b/bin/tests/system/xfer/ans5/ans.py
index 0521b3bbd4..be83dec455 100644
--- a/bin/tests/system/xfer/ans5/ans.py
+++ b/bin/tests/system/xfer/ans5/ans.py
@@ -20,16 +20,15 @@ import dns.rrset
 import dns.tsig

 from isctest.asyncserver import (
-    AxfrHandler,
     ControllableAsyncDnsServer,
     DnsProtocol,
-    DnsResponseSend,
     QueryContext,
     ResponseAction,
     ResponseHandler,
-    ResponseHandlerWrapper,
-    SwitchControlCommand,
 )
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.commands import SwitchControlCommand
+from isctest.asyncserver.handlers import AxfrHandler, ResponseHandlerWrapper
 from isctest.vars.algorithms import ALG_VARS

 GOOD_KEY_DATA = "LSAnCU+Z"
diff --git a/bin/tests/system/xfer/ans9/ans.py b/bin/tests/system/xfer/ans9/ans.py
index 28e7bebd7d..675d53de4f 100644
--- a/bin/tests/system/xfer/ans9/ans.py
+++ b/bin/tests/system/xfer/ans9/ans.py
@@ -18,13 +18,13 @@ import dns.rdatatype
 import dns.rrset

 from isctest.asyncserver import (
-    AxfrHandler,
     ControllableAsyncDnsServer,
-    DnsResponseSend,
     QueryContext,
     ResponseHandler,
-    ToggleResponsesCommand,
 )
+from isctest.asyncserver.actions import DnsResponseSend
+from isctest.asyncserver.commands import ToggleResponsesCommand
+from isctest.asyncserver.handlers import AxfrHandler

 TTL = 300

diff --git a/bin/tests/system/zero/ans5/ans.py b/bin/tests/system/zero/ans5/ans.py
index 4b91090058..3be2928da4 100644
--- a/bin/tests/system/zero/ans5/ans.py
+++ b/bin/tests/system/zero/ans5/ans.py
@@ -17,12 +17,8 @@ import dns.rcode
 import dns.rdatatype
 import dns.rrset

-from isctest.asyncserver import (
-    AsyncDnsServer,
-    DnsResponseSend,
-    QueryContext,
-    ResponseHandler,
-)
+from isctest.asyncserver import AsyncDnsServer, QueryContext, ResponseHandler
+from isctest.asyncserver.actions import DnsResponseSend


 class IncrementARecordHandler(ResponseHandler):