]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Remove 3.6-specific code.
authorBob Halley <halley@dnspython.org>
Sat, 5 Mar 2022 21:32:36 +0000 (13:32 -0800)
committerBob Halley <halley@dnspython.org>
Sat, 5 Mar 2022 21:32:36 +0000 (13:32 -0800)
We still have to add AsyncExitStacks, and this requires making
the associated socket wrappers async context managers.

dns/_immutable_attr.py [deleted file]
dns/asyncbackend.py
dns/asyncquery.py
dns/immutable.py
dns/query.py
dns/set.py
tests/test_async.py
tests/test_doh.py
tests/test_immutable.py
tests/test_xfr.py

diff --git a/dns/_immutable_attr.py b/dns/_immutable_attr.py
deleted file mode 100644 (file)
index 4d89be9..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
-
-# This implementation of the immutable decorator is for python 3.6,
-# which doesn't have Context Variables.  This implementation is somewhat
-# costly for classes with slots, as it adds a __dict__ to them.
-
-
-import inspect
-
-
-class _Immutable:
-    """Immutable mixin class"""
-
-    # Note we MUST NOT have __slots__ as that causes
-    #
-    #    TypeError: multiple bases have instance lay-out conflict
-    #
-    # when we get mixed in with another class with slots.  When we
-    # get mixed into something with slots, it effectively adds __dict__ to
-    # the slots of the other class, which allows attribute setting to work,
-    # albeit at the cost of the dictionary.
-
-    def __setattr__(self, name, value):
-        if not hasattr(self, '_immutable_init') or \
-           self._immutable_init is not self:
-            raise TypeError("object doesn't support attribute assignment")
-        else:
-            super().__setattr__(name, value)
-
-    def __delattr__(self, name):
-        if not hasattr(self, '_immutable_init') or \
-           self._immutable_init is not self:
-            raise TypeError("object doesn't support attribute assignment")
-        else:
-            super().__delattr__(name)
-
-
-def _immutable_init(f):
-    def nf(*args, **kwargs):
-        try:
-            # Are we already initializing an immutable class?
-            previous = args[0]._immutable_init
-        except AttributeError:
-            # We are the first!
-            previous = None
-            object.__setattr__(args[0], '_immutable_init', args[0])
-        try:
-            # call the actual __init__
-            f(*args, **kwargs)
-        finally:
-            if not previous:
-                # If we started the initialization, establish immutability
-                # by removing the attribute that allows mutation
-                object.__delattr__(args[0], '_immutable_init')
-    nf.__signature__ = inspect.signature(f)
-    return nf
-
-
-def immutable(cls):
-    if _Immutable in cls.__mro__:
-        # Some ancestor already has the mixin, so just make sure we keep
-        # following the __init__ protocol.
-        cls.__init__ = _immutable_init(cls.__init__)
-        if hasattr(cls, '__setstate__'):
-            cls.__setstate__ = _immutable_init(cls.__setstate__)
-        ncls = cls
-    else:
-        # Mixin the Immutable class and follow the __init__ protocol.
-        class ncls(_Immutable, cls):
-
-            @_immutable_init
-            def __init__(self, *args, **kwargs):
-                super().__init__(*args, **kwargs)
-
-            if hasattr(cls, '__setstate__'):
-                @_immutable_init
-                def __setstate__(self, *args, **kwargs):
-                    super().__setstate__(*args, **kwargs)
-
-        # make ncls have the same name and module as cls
-        ncls.__name__ = cls.__name__
-        ncls.__qualname__ = cls.__qualname__
-        ncls.__module__ = cls.__module__
-    return ncls
index a8f794ac6fe80c76ef687fde0000ec5a7edd89fa..0c6fc0ae4e023f8abace4bf341a016534b0de9c1 100644 (file)
@@ -72,12 +72,6 @@ def sniff() -> str:
             return 'asyncio'
         except RuntimeError:
             raise AsyncLibraryNotFoundError('no async library detected')
-        except AttributeError:  # pragma: no cover
-            # we have to check current_task on 3.6; we ignore for mypy
-            # purposes at it is otherwise unhappy on >= 3.7
-            if not asyncio.Task.current_task():  # type: ignore
-                raise AsyncLibraryNotFoundError('no async library detected')
-            return 'asyncio'
 
 
 def get_default_backend() -> Backend:
index 8c35d1aabc8cde308edab1e21281964503047874..3ac48dc33836c6a0115866c65a0f1f7389731ac6 100644 (file)
@@ -356,10 +356,7 @@ async def tls(q: dns.message.Message, where: str, timeout: Optional[float]=None,
         if ssl_context is None:
             # See the comment about ssl.create_default_context() in query.py
             ssl_context = ssl.create_default_context()  # lgtm[py/insecure-protocol]
-            if sys.version_info >= (3, 7):
-                ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
-            else:
-                ssl_context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
+            ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
             if server_hostname is None:
                 ssl_context.check_hostname = False
         else:
index 672be59847d0601eb3b94856c03eb77ac6522920..17515b1f7e43d86e0383a4ec395da2be52f8ea30 100644 (file)
@@ -3,15 +3,7 @@
 import collections.abc
 import sys
 
-# pylint: disable=unused-import
-if sys.version_info >= (3, 7):
-    odict = dict
-    from dns._immutable_ctx import immutable
-else:
-    # pragma: no cover
-    from collections import OrderedDict as odict
-    from dns._immutable_attr import immutable  # noqa
-# pylint: enable=unused-import
+from dns._immutable_ctx import immutable
 
 
 @immutable
@@ -23,10 +15,10 @@ class Dict(collections.abc.Mapping):  # lgtm[py/missing-equals]
         of copied.  Only set this if you are sure there will be no external
         references to the dictionary.
         """
-        if no_copy and isinstance(dictionary, odict):
+        if no_copy and isinstance(dictionary, dict):
             self._odict = dictionary
         else:
-            self._odict = odict(dictionary)
+            self._odict = dict(dictionary)
         self._hash = None
 
     def __getitem__(self, key):
@@ -63,7 +55,7 @@ def constify(o):
     if isinstance(o, list):
         return tuple(constify(elt) for elt in o)
     if isinstance(o, dict):
-        cdict = odict()
+        cdict = dict()
         for k, v in o.items():
             cdict[k] = constify(v)
         return Dict(cdict, True)
index e2dca20dcadcbd22f463e590ae67c23451f98c27..9588621b98a9b91d3c0245c3152ec72a139ff577 100644 (file)
@@ -892,10 +892,7 @@ def tls(q: dns.message.Message, where: str, timeout: Optional[float]=None,
         # can, even though this might require a future dnspython release if that
         # version becomes deprecated.
         ssl_context = ssl.create_default_context()  # lgtm[py/insecure-protocol]
-        if sys.version_info >= (3, 7):
-            ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
-        else:
-            ssl_context.options |= ssl.OP_NO_TLSv1 | ssl.OP_NO_TLSv1_1
+        ssl_context.minimum_version = ssl.TLSVersion.TLSv1_2
         if server_hostname is None:
             ssl_context.check_hostname = False
 
index 32b50a73686567c2dc612e737891307cfff25424..40583549800f603a25ed080e89400bafa9028dcb 100644 (file)
 import itertools
 import sys
 
-if sys.version_info >= (3, 7):
-    odict = dict
-else:
-    from collections import OrderedDict as odict  # pragma: no cover
 
 class Set:
 
@@ -41,7 +37,7 @@ class Set:
         *items*, an iterable or ``None``, the initial set of items.
         """
 
-        self.items = odict()
+        self.items = dict()
         if items is not None:
             for item in items:
                 # This is safe for how we use set, but if other code
@@ -96,7 +92,7 @@ class Set:
         else:
             cls = self.__class__
         obj = cls.__new__(cls)
-        obj.items = odict()
+        obj.items = dict()
         obj.items.update(self.items)
         return obj
 
@@ -259,13 +255,7 @@ class Set:
         self.items.clear()
 
     def __eq__(self, other):
-        if odict == dict:
-            return self.items == other.items
-        else:
-            # We don't want an ordered comparison.
-            if len(self.items) != len(other.items):
-                return False
-            return all(elt in other.items for elt in self.items)
+        return self.items == other.items
 
     def __ne__(self, other):
         return not self.__eq__(other)
index 4759b029c2dee07d7adeba9aef6a69f6b6e63995..ce0caa143d2b0e632824278d0304755c7c72e175 100644 (file)
@@ -85,15 +85,7 @@ class AsyncDetectionTests(unittest.TestCase):
     sniff_result = 'asyncio'
 
     def async_run(self, afunc):
-        try:
-            runner = asyncio.run
-        except AttributeError:
-            # this is only needed for 3.6
-            def old_runner(awaitable):
-                loop = asyncio.get_event_loop()
-                return loop.run_until_complete(awaitable)
-            runner = old_runner
-        return runner(afunc())
+        return asyncio.run(afunc())
 
     def test_sniff(self):
         dns.asyncbackend._default_backend = None
@@ -177,15 +169,7 @@ class AsyncTests(unittest.TestCase):
         self.backend = dns.asyncbackend.set_default_backend('asyncio')
 
     def async_run(self, afunc):
-        try:
-            runner = asyncio.run
-        except AttributeError:
-            # this is only needed for 3.6
-            def old_runner(awaitable):
-                loop = asyncio.get_event_loop()
-                return loop.run_until_complete(awaitable)
-            runner = old_runner
-        return runner(afunc())
+        return asyncio.run(afunc())
 
     def testResolve(self):
         async def run():
index 6be7d2111bc6ba99811cb2788c93c66cd0f472a0..bc02e95289c267908c96a8987099bde52aa7b900 100644 (file)
@@ -211,9 +211,8 @@ class DNSOverHTTPSTestCaseHttpx(unittest.TestCase):
             valid_tls_url = 'https://doh.cleanbrowsing.org/doh/family-filter/'
             q = dns.message.make_query('example.com.', dns.rdatatype.A)
             # make sure CleanBrowsing's IP address will fail TLS certificate
-            # check.  On 3.6 we get ssl.CertificateError instead of
-            # httpx.ConnectError.
-            with self.assertRaises((httpx.ConnectError, ssl.CertificateError)):
+            # check.
+            with self.assertRaises(httpx.ConnectError):
                 dns.query.https(q, invalid_tls_url, session=self.session,
                                 timeout=4)
             # We can't do the Host header and SNI magic with httpx, but
index 1a70e3d41147d895ffecd71aaef4cac25b4755b0..8ab145ea1a27456b17d7bb235d9f521a3abd8e9d 100644 (file)
@@ -3,16 +3,7 @@
 import unittest
 
 import dns.immutable
-import dns._immutable_attr
-
-try:
-    import dns._immutable_ctx as immutable_ctx
-    _have_contextvars = True
-except ImportError:
-    _have_contextvars = False
-
-    class immutable_ctx:
-        pass
+import dns._immutable_ctx
 
 
 class ImmutableTestCase(unittest.TestCase):
@@ -52,7 +43,7 @@ class ImmutableTestCase(unittest.TestCase):
 
 class DecoratorTestCase(unittest.TestCase):
 
-    immutable_module = dns._immutable_attr
+    immutable_module = dns._immutable_ctx
 
     def make_classes(self):
         class A:
@@ -152,9 +143,3 @@ class DecoratorTestCase(unittest.TestCase):
         with self.assertRaises(TypeError):
             B(a, 20)
         self.assertEqual(a.a, 10)
-
-
-@unittest.skipIf(not _have_contextvars, "contextvars not available")
-class CtxDecoratorTestCase(DecoratorTestCase):
-
-    immutable_module = immutable_ctx
index 462e3a057c31859ce21f5cc1c6b3adaa03d89dd5..3cf4c9136082fcf3e36da0d733c6b56dd811e90f 100644 (file)
@@ -676,15 +676,7 @@ def test_asyncio_inbound_xfr():
     dns.asyncbackend.set_default_backend('asyncio')
     async def run():
         await async_inbound_xfr()
-    try:
-        runner = asyncio.run
-    except AttributeError:
-        # this is only needed for 3.6
-        def old_runner(awaitable):
-            loop = asyncio.get_event_loop()
-            return loop.run_until_complete(awaitable)
-        runner = old_runner
-    runner(run())
+    asyncio.run(run())
 
 #
 # We don't need to do this as it's all generic code, but