]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Remove compatibility hacks for dnspython<2.7.0
authorNicki Křížek <nicki@isc.org>
Tue, 30 Dec 2025 13:29:51 +0000 (14:29 +0100)
committerNicki Křížek <nicki@isc.org>
Wed, 21 Jan 2026 15:34:30 +0000 (16:34 +0100)
The minimum required dnspython version is now 2.7.0 and those
compatibility hacks can be dropped.

(cherry picked from commit ce385d8100b9dfc14b6233453ea7dbcf0db56b3b)

27 files changed:
bin/tests/system/bailiwick/tests_bailiwick.py
bin/tests/system/checkds/tests_checkds.py
bin/tests/system/dispatch/tests_connreset.py
bin/tests/system/dnssec-malformed-dnskey/tests_malformed_dnskey.py
bin/tests/system/dnstap/tests_dnstap.py
bin/tests/system/doth/tests_gnutls.py
bin/tests/system/glue/tests_glue.py
bin/tests/system/isctest/asyncserver.py
bin/tests/system/isctest/check.py
bin/tests/system/isctest/compat.py [deleted file]
bin/tests/system/isctest/hypothesis/strategies.py
bin/tests/system/isctest/name.py
bin/tests/system/isctest/query.py
bin/tests/system/isctest/run.py
bin/tests/system/limits/tests_limits.py
bin/tests/system/names/tests_names.py
bin/tests/system/nsec3-answer/tests_nsec3.py
bin/tests/system/optout/tests_optout.py
bin/tests/system/rpzextra/tests_rpzextra.py
bin/tests/system/shutdown/tests_shutdown.py
bin/tests/system/statschannel/tests_json.py
bin/tests/system/statschannel/tests_xml.py
bin/tests/system/tcp/tests_tcp.py
bin/tests/system/timeouts/tests_tcp_timeouts.py
bin/tests/system/tsig/tests_tsig_hypothesis.py
bin/tests/system/tsiggss/tests_isc_spnego_flaws.py
bin/tests/system/wildcard/tests_wildcard.py

index d0313346d4d56806f62d87216537b8be2aa995f9..76540008db09d2a0a67b6228555a5a45d5ad80a9 100644 (file)
@@ -17,9 +17,6 @@ import dns.message
 
 import pytest
 
-# isctest.asyncserver requires dnspython >= 2.0.0
-pytest.importorskip("dns", minversion="2.0.0")
-
 import isctest
 from isctest.instance import NamedInstance
 
index 8e6660a6ef201d866d57d3cab63cb0e0cf01e6cd..50dc2c0222c5067d9bcb810cbd94e33caf0d2481 100755 (executable)
@@ -21,7 +21,6 @@ import time
 import isctest
 import pytest
 
-pytest.importorskip("dns", minversion="2.0.0")
 import dns.exception
 import dns.message
 import dns.name
index 0b78fb8e0a6bb8b9c00e4dedf1f5111d9c7826b2..01a1bbc5c09b704f886b359694b6f6c81edab76a 100644 (file)
@@ -14,7 +14,6 @@
 import pytest
 import isctest
 
-pytest.importorskip("dns")
 import dns.message
 
 pytestmark = pytest.mark.extra_artifacts(
index c028b5259b9be64af3d6c24dc2186d461ba6091e..05545c1ef40f6d1887ddf500e28b71b777068194 100644 (file)
@@ -16,9 +16,6 @@ import os
 import pytest
 
 pytest.importorskip("cryptography")
-pytest.importorskip(
-    "dns", minversion="2.7.0"
-)  # dns.dnssec.sign_zone(deterministic=...) needed
 
 from cryptography.hazmat.primitives.asymmetric import ec
 
index 3c179c282509dd8153b9af466938ec3cc905a0f0..bd254a1a86a492f24a9556fc081613bf44a0e040 100644 (file)
@@ -17,7 +17,6 @@ import re
 import isctest
 import pytest
 
-pytest.importorskip("dns", minversion="2.0.0")
 import dns.rrset
 
 pytestmark = pytest.mark.extra_artifacts(
index 9c897714efe473f92bbbe7ca49fe89a8e613e184..42ef3f6973e61dff154c368fcaf501437e8858bb 100644 (file)
@@ -18,7 +18,7 @@ import time
 
 import pytest
 
-pytest.importorskip("dns")
+import dns
 import dns.exception
 import dns.name
 import dns.rdataclass
index faf251367da7cdcf2ab33f48b623387395347e72..612e6bef99638732e3e73be1441b6737d3d235d8 100644 (file)
 
 import dns.flags
 import dns.message
-import pytest
 
 import isctest
 
-pytest.importorskip("dns", minversion="2.0.0")
-
 
 def test_glue_full_glue_set():
     """test that a ccTLD referral gets a full glue set from the root zone"""
index d2b22d7c129d2b5fdbad2f269d9d426613a07f2b..eeca1b88eced25c97f60cac4629a9649918f8680 100644 (file)
@@ -113,7 +113,6 @@ class AsyncServer:
         tcp_handler: Optional[_TcpHandler],
         pidfile: Optional[str] = None,
     ) -> None:
-        self._abort_if_on_dnspython_version_less_than_2_0_0()
         logging.basicConfig(
             format="%(asctime)s %(levelname)8s  %(message)s",
             level=os.environ.get("ANS_LOG_LEVEL", "INFO").upper(),
@@ -141,14 +140,6 @@ class AsyncServer:
         self._pidfile: Optional[str] = pidfile
         self._work_done: Optional[asyncio.Future] = None
 
-    @classmethod
-    def _abort_if_on_dnspython_version_less_than_2_0_0(cls) -> None:
-        if dns.version.MAJOR < 2:
-            error = f"Using {cls.__name__} requires dnspython >= 2.0.0; "
-            error += 'add `pytest.importorskip("dns", minversion="2.0.0")` '
-            error += "to the test module to skip this test."
-            raise RuntimeError(error)
-
     def _get_ipv4_address_from_directory_name(self) -> str:
         containing_directory = pathlib.Path().absolute().stem
         match_result = re.match(r"ans(?P<index>\d+)", containing_directory)
index e7187b88533a4e0b90e7d7a91ab8cbef09a47006..0a3b199ea407e6142a0bd9b0d11e6f4d0d8ca19f 100644 (file)
@@ -13,13 +13,13 @@ import shutil
 from typing import cast, List, Optional
 
 import dns.edns
+from dns.edns import EDECode, EDEOption
 import dns.flags
 import dns.message
 import dns.rcode
 import dns.zone
 
 import isctest.log
-from isctest.compat import dns_rcode, EDECode, EDEOption
 
 
 def rcode(message: dns.message.Message, expected_rcode) -> None:
@@ -27,19 +27,19 @@ def rcode(message: dns.message.Message, expected_rcode) -> None:
 
 
 def noerror(message: dns.message.Message) -> None:
-    rcode(message, dns_rcode.NOERROR)
+    rcode(message, dns.rcode.NOERROR)
 
 
 def notimp(message: dns.message.Message) -> None:
-    rcode(message, dns_rcode.NOTIMP)
+    rcode(message, dns.rcode.NOTIMP)
 
 
 def refused(message: dns.message.Message) -> None:
-    rcode(message, dns_rcode.REFUSED)
+    rcode(message, dns.rcode.REFUSED)
 
 
 def servfail(message: dns.message.Message) -> None:
-    rcode(message, dns_rcode.SERVFAIL)
+    rcode(message, dns.rcode.SERVFAIL)
 
 
 def adflag(message: dns.message.Message) -> None:
@@ -82,10 +82,6 @@ def _extract_ede_options(
 
 def noede(message: dns.message.Message) -> None:
     """Check that message contains no EDE option."""
-    if not hasattr(dns.edns, "EDECode"):
-        # dnspython<2.2.0 doesn't support EDE, skip check
-        return
-
     ede_options = _extract_ede_options(message)
     assert not ede_options, f"unexpected EDE options {ede_options} in {message}"
 
@@ -94,10 +90,6 @@ def ede(
     message: dns.message.Message, code: EDECode, text: Optional[str] = None
 ) -> None:
     """Check if message contains expected EDE code (and its text)."""
-    if not hasattr(dns.edns, "EDECode"):
-        # dnspython<2.2.0 doesn't support EDE, skip check
-        return
-
     msg_opts = _extract_ede_options(message)
     matching_opts = [opt for opt in msg_opts if opt.code == code]
 
@@ -204,7 +196,7 @@ def is_executable(cmd: str, errmsg: str) -> None:
 def named_alive(named_proc, resolver_ip):
     assert named_proc.poll() is None, "named isn't running"
     msg = isctest.query.create("version.bind", "TXT", "CH")
-    isctest.query.tcp(msg, resolver_ip, expected_rcode=dns_rcode.NOERROR)
+    isctest.query.tcp(msg, resolver_ip, expected_rcode=dns.rcode.NOERROR)
 
 
 def notauth(message: dns.message.Message) -> None:
diff --git a/bin/tests/system/isctest/compat.py b/bin/tests/system/isctest/compat.py
deleted file mode 100644 (file)
index 3dc5810..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
-#
-# SPDX-License-Identifier: MPL-2.0
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0.  If a copy of the MPL was not distributed with this
-# file, you can obtain one at https://mozilla.org/MPL/2.0/.
-#
-# See the COPYRIGHT file distributed with this work for additional
-# information regarding copyright ownership.
-
-from typing import Any, TYPE_CHECKING
-
-import dns.edns
-import dns.rcode
-
-# compatiblity with dnspython<2.0.0
-try:
-    # In dnspython>=2.0.0, dns.rcode.Rcode class is available
-    # pylint: disable=invalid-name
-    dns_rcode = dns.rcode.Rcode  # type: Any
-except AttributeError:
-    # In dnspython<2.0.0, selected rcodes are available as integers directly
-    # from dns.rcode
-    dns_rcode = dns.rcode
-
-
-if TYPE_CHECKING:
-    EDECode = dns.edns.EDECode
-    EDEOption = dns.edns.EDEOption
-else:
-    try:  # compatiblity with dnspython<2.2.0
-        EDECode = dns.edns.EDECode
-    except AttributeError:
-        # In dnspython<2.2.0, the dns.edns.EDECode doesn't exist.
-        #
-        # The primary use-case is for us to use existing EDECode objects from the
-        # class, e.g. EDECode.FILTERED. To mimick this behavior, use a string
-        # factory that just turns the attribute name into a string.
-        #
-        # The used compatibility hack doesn't really matter (as long as EDECode.xxx
-        # doesn't raise exception), as with dnspython versions prior to 2.2.0, any
-        # EDE checking will be skipped anyway.
-        class _CompatEDECode:
-            def __getattr__(self, name: str) -> str:
-                return name
-
-        EDECode = _CompatEDECode()
-    try:
-        EDEOption = dns.edns.EDEOption
-    except AttributeError:
-        # In dnspython<2.2.0, the dns.edns.EDEOption doesn't exist, so we stub it to be
-        # able to use it in type annotations.
-        class EDEOption:
-            def __new__(cls, *args, **kwargs):
-                raise RuntimeError("Using EDEOption requires dnspython>=2.2.0")
index a3f9eac2b27c47f91ed92a5c72d94430f443a03f..e8badc6802b955ae0a17978248be7d630a6f944a 100644 (file)
@@ -143,13 +143,8 @@ def dns_names(
 
 
 RDATACLASS_MAX = RDATATYPE_MAX = 65535
-try:
-    dns_rdataclasses = builds(dns.rdataclass.RdataClass, integers(0, RDATACLASS_MAX))
-    dns_rdatatypes = builds(dns.rdatatype.RdataType, integers(0, RDATATYPE_MAX))
-except AttributeError:
-    # In old dnspython versions, RDataTypes and RDataClasses are int and not enums.
-    dns_rdataclasses = integers(0, RDATACLASS_MAX)  # type: ignore
-    dns_rdatatypes = integers(0, RDATATYPE_MAX)  # type: ignore
+dns_rdataclasses = builds(dns.rdataclass.RdataClass, integers(0, RDATACLASS_MAX))
+dns_rdatatypes = builds(dns.rdatatype.RdataType, integers(0, RDATATYPE_MAX))
 dns_rdataclasses_without_meta = dns_rdataclasses.filter(dns.rdataclass.is_metaclass)
 
 # NOTE: This should really be `dns_rdatatypes_without_meta = dns_rdatatypes_without_meta.filter(dns.rdatatype.is_metatype()`,
index 7cf3e8d696c8c20c19f652b54e5be6884481adba..374eb8ba60fa890651553cf5a8cb723fd29995e1 100644 (file)
@@ -11,9 +11,6 @@
 
 from typing import Container, Iterable, FrozenSet
 
-import pytest
-
-pytest.importorskip("dns", minversion="2.3.0")  # NameRelation
 from dns.name import Name, NameRelation
 import dns.zone
 import dns.rdatatype
index b11b165f8567c348be6680d62872978bdac29a38..f0c782c1cbd75a6d7f67db5a67e5f91be5d184bf 100644 (file)
@@ -17,7 +17,6 @@ import dns.query
 import dns.message
 
 import isctest.log
-from isctest.compat import dns_rcode
 
 QUERY_TIMEOUT = 10
 
@@ -30,7 +29,7 @@ def generic_query(
     source: Optional[str] = None,
     timeout: int = QUERY_TIMEOUT,
     attempts: int = 10,
-    expected_rcode: dns_rcode = None,
+    expected_rcode: Optional[dns.rcode.Rcode] = None,
     log_query: bool = True,
     log_response: bool = True,
 ) -> Any:
@@ -61,9 +60,9 @@ def generic_query(
                 return res
         time.sleep(1)
     if expected_rcode is not None:
-        last_rcode = dns_rcode.to_text(res.rcode()) if res else None
+        last_rcode = dns.rcode.to_text(res.rcode()) if res else None
         isctest.log.debug(
-            f"isc.query.{query_func.__name__}(): expected rcode={dns_rcode.to_text(expected_rcode)}, last rcode={last_rcode}"
+            f"isc.query.{query_func.__name__}(): expected rcode={dns.rcode.to_text(expected_rcode)}, last rcode={last_rcode}"
         )
     raise dns.exception.Timeout
 
index 3fbc6ac34112e6a86c08a839c911939eaf3f0b33..6bc77672c70e749323ccdda17962fbd73c9a0661 100644 (file)
@@ -16,9 +16,9 @@ from typing import Optional
 
 import isctest.log
 import isctest.text
-from isctest.compat import dns_rcode
 
 import dns.message
+import dns.rcode
 
 
 class CmdResult:
@@ -149,4 +149,4 @@ def get_custom_named_instance(assumed_ns, ports):
 def assert_custom_named_is_alive(named_proc, resolver_ip):
     assert named_proc.poll() is None, "named isn't running"
     msg = dns.message.make_query("version.bind", "TXT", "CH")
-    isctest.query.tcp(msg, resolver_ip, expected_rcode=dns_rcode.NOERROR)
+    isctest.query.tcp(msg, resolver_ip, expected_rcode=dns.rcode.NOERROR)
index ca7214a9de4f64b1a2f2d5caeb38d2ebd5db2596..6949838ec74fc5f1f185c7808a889765c5337571 100644 (file)
@@ -14,9 +14,6 @@ import itertools
 import isctest
 import pytest
 
-# Everything from getting a big answer to creating an RR set with thousands
-# of records takes minutes of CPU and real time with dnspython < 2.0.0.
-pytest.importorskip("dns", minversion="2.0.0")
 import dns.rrset
 
 
index b72fcbec980fe1e1ac73791d40c825eab95a2039..38fc983d089705004153a153fdeb5fc980cc067b 100644 (file)
@@ -9,10 +9,6 @@
 # See the COPYRIGHT file distributed with this work for additional
 # information regarding copyright ownership.
 
-import pytest
-
-pytest.importorskip("dns", minversion="2.7.0")
-
 import isctest
 
 
index 2ee8a4fa494336a979a21022edbcf49584feec37..da74a599ffdd50e88706a2a729f15a031a123032 100755 (executable)
@@ -18,7 +18,6 @@ from typing import Optional, Set, Tuple
 
 import pytest
 
-pytest.importorskip("dns", minversion="2.5.0")
 import dns.dnssec
 import dns.message
 import dns.name
index 08114af51197801bd127a3191e76eaa3f00d719c..ce5071ffa79cf56dd5defc5bab779102a539bac6 100755 (executable)
@@ -19,7 +19,7 @@ import sys
 import isctest
 import pytest
 
-pytest.importorskip("dns", minversion="2.0.0")
+import dns
 import dns.exception
 import dns.message
 import dns.name
index e918fa832e247231e3691fc52167ea966f4dbb96..e6a83249424714147dc7f72c7504b0d62a8123af 100644 (file)
@@ -15,12 +15,11 @@ import os
 
 import pytest
 
-pytest.importorskip("dns", minversion="2.0.0")
+import dns
 import dns.rcode
 import dns.rrset
 
 import isctest
-from isctest.compat import dns_rcode
 
 
 pytestmark = pytest.mark.extra_artifacts(
@@ -78,13 +77,13 @@ def test_rpz_multiple_views(qname, source, rcode):
         msg,
         ip="10.53.0.3",
         source="10.53.0.2",
-        expected_rcode=dns_rcode.NOERROR,
+        expected_rcode=dns.rcode.NOERROR,
     )
     isctest.query.tcp(
         msg,
         ip="10.53.0.3",
         source="10.53.0.5",
-        expected_rcode=dns_rcode.NOERROR,
+        expected_rcode=dns.rcode.NOERROR,
     )
 
     msg = isctest.query.create(qname, "A")
index 52e574543e2691845f4046b2194ca7ccf6f77c8d..71f6826bf5491fa01de8d4808818a1953b3a8069 100755 (executable)
@@ -21,7 +21,7 @@ import time
 
 import pytest
 
-pytest.importorskip("dns", minversion="2.0.0")
+import dns
 import dns.exception
 
 import isctest
index 105e10d445fde1be34fa1251d2b7d9a5f7ac817c..9e9a2dc405f7b2c7cc875edd166082b9fdb9ee55 100755 (executable)
 from datetime import datetime
 
 import pytest
+import requests
 
 import isctest.mark
 
 pytest.register_assert_rewrite("generic")
 import generic
 
-requests = pytest.importorskip("requests")
 
 pytestmark = [
     isctest.mark.have_json_c,
index 94c0cc1fcc9587a6112bf16fe354274c64f1e94e..d41fc4fc766a35360f3e3c105c483700f527fe67 100755 (executable)
@@ -15,13 +15,13 @@ from datetime import datetime
 import xml.etree.ElementTree as ET
 
 import pytest
+import requests
 
 import isctest.mark
 
 pytest.register_assert_rewrite("generic")
 import generic
 
-requests = pytest.importorskip("requests")
 
 pytestmark = [
     isctest.mark.have_libxml2,
index 8e235596c78783e3f7d2bb4496513ddb381868b4..399eaf2049515d7d17d8e9bf6db9fa06074488b3 100644 (file)
@@ -19,7 +19,7 @@ import time
 
 import pytest
 
-pytest.importorskip("dns", minversion="2.0.0")
+import dns
 import dns.message
 import dns.query
 
index cb8defa71effd129710d958e52991af3a70f2560..e25bba5a042966ba180e2a037d978f773d44455e 100644 (file)
@@ -18,7 +18,7 @@ import time
 
 import pytest
 
-pytest.importorskip("dns", minversion="2.0.0")
+import dns
 import dns.edns
 import dns.message
 import dns.name
index 9ea5b42643440765e725d9570d6fa55d73bcc944..3a1c05d1d1114a253a6785bf3490c1d75b9a5593 100644 (file)
@@ -15,8 +15,6 @@ import time
 
 import pytest
 
-pytest.importorskip("dns", minversion="2.7.0")  # TSIG parsing without validation
-
 import dns.exception
 import dns.message
 import dns.name
index 38b424d4c59bc1efa768938dc170b6e4ecbaef99..7e960ba6e1c26d51e2bdd99de05649d1a543987f 100755 (executable)
@@ -24,7 +24,7 @@ import pytest
 
 import isctest
 
-pytest.importorskip("dns")
+import dns
 import dns.message
 import dns.name
 import dns.rdata
index 459e3397b35ad8a5e7222fba00ae56d3a7dff15e..b086fc0d136ccd117553e563017244d27639cc5d 100755 (executable)
@@ -29,7 +29,7 @@ Limitations - untested properties:
 
 import pytest
 
-pytest.importorskip("dns", minversion="2.0.0")
+import dns
 import dns.message
 import dns.name
 import dns.query