about summary refs log tree commit diff
path: root/.venv/lib/python3.12/site-packages/dns/set.py
diff options
context:
space:
mode:
authorS. Solomon Darnell2025-03-28 21:52:21 -0500
committerS. Solomon Darnell2025-03-28 21:52:21 -0500
commit4a52a71956a8d46fcb7294ac71734504bb09bcc2 (patch)
treeee3dc5af3b6313e921cd920906356f5d4febc4ed /.venv/lib/python3.12/site-packages/dns/set.py
parentcc961e04ba734dd72309fb548a2f97d67d578813 (diff)
downloadgn-ai-4a52a71956a8d46fcb7294ac71734504bb09bcc2.tar.gz
two version of R2R are here HEAD master
Diffstat (limited to '.venv/lib/python3.12/site-packages/dns/set.py')
-rw-r--r--.venv/lib/python3.12/site-packages/dns/set.py308
1 files changed, 308 insertions, 0 deletions
diff --git a/.venv/lib/python3.12/site-packages/dns/set.py b/.venv/lib/python3.12/site-packages/dns/set.py
new file mode 100644
index 00000000..ae8f0dd5
--- /dev/null
+++ b/.venv/lib/python3.12/site-packages/dns/set.py
@@ -0,0 +1,308 @@
+# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
+
+# Copyright (C) 2003-2017 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+import itertools
+
+
+class Set:
+    """A simple set class.
+
+    This class was originally used to deal with python not having a set class, and
+    originally the class used lists in its implementation.  The ordered and indexable
+    nature of RRsets and Rdatasets is unfortunately widely used in dnspython
+    applications, so for backwards compatibility sets continue to be a custom class, now
+    based on an ordered dictionary.
+    """
+
+    __slots__ = ["items"]
+
+    def __init__(self, items=None):
+        """Initialize the set.
+
+        *items*, an iterable or ``None``, the initial set of items.
+        """
+
+        self.items = dict()
+        if items is not None:
+            for item in items:
+                # This is safe for how we use set, but if other code
+                # subclasses it could be a legitimate issue.
+                self.add(item)  # lgtm[py/init-calls-subclass]
+
+    def __repr__(self):
+        return f"dns.set.Set({repr(list(self.items.keys()))})"  # pragma: no cover
+
+    def add(self, item):
+        """Add an item to the set."""
+
+        if item not in self.items:
+            self.items[item] = None
+
+    def remove(self, item):
+        """Remove an item from the set."""
+
+        try:
+            del self.items[item]
+        except KeyError:
+            raise ValueError
+
+    def discard(self, item):
+        """Remove an item from the set if present."""
+
+        self.items.pop(item, None)
+
+    def pop(self):
+        """Remove an arbitrary item from the set."""
+        (k, _) = self.items.popitem()
+        return k
+
+    def _clone(self) -> "Set":
+        """Make a (shallow) copy of the set.
+
+        There is a 'clone protocol' that subclasses of this class
+        should use.  To make a copy, first call your super's _clone()
+        method, and use the object returned as the new instance.  Then
+        make shallow copies of the attributes defined in the subclass.
+
+        This protocol allows us to write the set algorithms that
+        return new instances (e.g. union) once, and keep using them in
+        subclasses.
+        """
+
+        if hasattr(self, "_clone_class"):
+            cls = self._clone_class  # type: ignore
+        else:
+            cls = self.__class__
+        obj = cls.__new__(cls)
+        obj.items = dict()
+        obj.items.update(self.items)
+        return obj
+
+    def __copy__(self):
+        """Make a (shallow) copy of the set."""
+
+        return self._clone()
+
+    def copy(self):
+        """Make a (shallow) copy of the set."""
+
+        return self._clone()
+
+    def union_update(self, other):
+        """Update the set, adding any elements from other which are not
+        already in the set.
+        """
+
+        if not isinstance(other, Set):
+            raise ValueError("other must be a Set instance")
+        if self is other:  # lgtm[py/comparison-using-is]
+            return
+        for item in other.items:
+            self.add(item)
+
+    def intersection_update(self, other):
+        """Update the set, removing any elements from other which are not
+        in both sets.
+        """
+
+        if not isinstance(other, Set):
+            raise ValueError("other must be a Set instance")
+        if self is other:  # lgtm[py/comparison-using-is]
+            return
+        # we make a copy of the list so that we can remove items from
+        # the list without breaking the iterator.
+        for item in list(self.items):
+            if item not in other.items:
+                del self.items[item]
+
+    def difference_update(self, other):
+        """Update the set, removing any elements from other which are in
+        the set.
+        """
+
+        if not isinstance(other, Set):
+            raise ValueError("other must be a Set instance")
+        if self is other:  # lgtm[py/comparison-using-is]
+            self.items.clear()
+        else:
+            for item in other.items:
+                self.discard(item)
+
+    def symmetric_difference_update(self, other):
+        """Update the set, retaining only elements unique to both sets."""
+
+        if not isinstance(other, Set):
+            raise ValueError("other must be a Set instance")
+        if self is other:  # lgtm[py/comparison-using-is]
+            self.items.clear()
+        else:
+            overlap = self.intersection(other)
+            self.union_update(other)
+            self.difference_update(overlap)
+
+    def union(self, other):
+        """Return a new set which is the union of ``self`` and ``other``.
+
+        Returns the same Set type as this set.
+        """
+
+        obj = self._clone()
+        obj.union_update(other)
+        return obj
+
+    def intersection(self, other):
+        """Return a new set which is the intersection of ``self`` and
+        ``other``.
+
+        Returns the same Set type as this set.
+        """
+
+        obj = self._clone()
+        obj.intersection_update(other)
+        return obj
+
+    def difference(self, other):
+        """Return a new set which ``self`` - ``other``, i.e. the items
+        in ``self`` which are not also in ``other``.
+
+        Returns the same Set type as this set.
+        """
+
+        obj = self._clone()
+        obj.difference_update(other)
+        return obj
+
+    def symmetric_difference(self, other):
+        """Return a new set which (``self`` - ``other``) | (``other``
+        - ``self), ie: the items in either ``self`` or ``other`` which
+        are not contained in their intersection.
+
+        Returns the same Set type as this set.
+        """
+
+        obj = self._clone()
+        obj.symmetric_difference_update(other)
+        return obj
+
+    def __or__(self, other):
+        return self.union(other)
+
+    def __and__(self, other):
+        return self.intersection(other)
+
+    def __add__(self, other):
+        return self.union(other)
+
+    def __sub__(self, other):
+        return self.difference(other)
+
+    def __xor__(self, other):
+        return self.symmetric_difference(other)
+
+    def __ior__(self, other):
+        self.union_update(other)
+        return self
+
+    def __iand__(self, other):
+        self.intersection_update(other)
+        return self
+
+    def __iadd__(self, other):
+        self.union_update(other)
+        return self
+
+    def __isub__(self, other):
+        self.difference_update(other)
+        return self
+
+    def __ixor__(self, other):
+        self.symmetric_difference_update(other)
+        return self
+
+    def update(self, other):
+        """Update the set, adding any elements from other which are not
+        already in the set.
+
+        *other*, the collection of items with which to update the set, which
+        may be any iterable type.
+        """
+
+        for item in other:
+            self.add(item)
+
+    def clear(self):
+        """Make the set empty."""
+        self.items.clear()
+
+    def __eq__(self, other):
+        return self.items == other.items
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+
+    def __len__(self):
+        return len(self.items)
+
+    def __iter__(self):
+        return iter(self.items)
+
+    def __getitem__(self, i):
+        if isinstance(i, slice):
+            return list(itertools.islice(self.items, i.start, i.stop, i.step))
+        else:
+            return next(itertools.islice(self.items, i, i + 1))
+
+    def __delitem__(self, i):
+        if isinstance(i, slice):
+            for elt in list(self[i]):
+                del self.items[elt]
+        else:
+            del self.items[self[i]]
+
+    def issubset(self, other):
+        """Is this set a subset of *other*?
+
+        Returns a ``bool``.
+        """
+
+        if not isinstance(other, Set):
+            raise ValueError("other must be a Set instance")
+        for item in self.items:
+            if item not in other.items:
+                return False
+        return True
+
+    def issuperset(self, other):
+        """Is this set a superset of *other*?
+
+        Returns a ``bool``.
+        """
+
+        if not isinstance(other, Set):
+            raise ValueError("other must be a Set instance")
+        for item in other.items:
+            if item not in self.items:
+                return False
+        return True
+
+    def isdisjoint(self, other):
+        if not isinstance(other, Set):
+            raise ValueError("other must be a Set instance")
+        for item in other.items:
+            if item in self.items:
+                return False
+        return True