]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Checkpoint immutable rdata. 434/head
authorBrian Wellington <bwelling@xbill.org>
Tue, 31 Mar 2020 19:38:31 +0000 (12:38 -0700)
committerBrian Wellington <bwelling@xbill.org>
Tue, 31 Mar 2020 19:38:31 +0000 (12:38 -0700)
38 files changed:
dns/name.py
dns/rdata.py
dns/rdtypes/ANY/CAA.py
dns/rdtypes/ANY/CERT.py
dns/rdtypes/ANY/CSYNC.py
dns/rdtypes/ANY/GPOS.py
dns/rdtypes/ANY/HINFO.py
dns/rdtypes/ANY/HIP.py
dns/rdtypes/ANY/ISDN.py
dns/rdtypes/ANY/LOC.py
dns/rdtypes/ANY/NSEC.py
dns/rdtypes/ANY/NSEC3.py
dns/rdtypes/ANY/NSEC3PARAM.py
dns/rdtypes/ANY/OPENPGPKEY.py
dns/rdtypes/ANY/RP.py
dns/rdtypes/ANY/RRSIG.py
dns/rdtypes/ANY/SOA.py
dns/rdtypes/ANY/SSHFP.py
dns/rdtypes/ANY/TLSA.py
dns/rdtypes/ANY/URI.py
dns/rdtypes/ANY/X25.py
dns/rdtypes/CH/A.py
dns/rdtypes/IN/A.py
dns/rdtypes/IN/AAAA.py
dns/rdtypes/IN/APL.py
dns/rdtypes/IN/DHCID.py
dns/rdtypes/IN/IPSECKEY.py
dns/rdtypes/IN/NAPTR.py
dns/rdtypes/IN/NSAP.py
dns/rdtypes/IN/PX.py
dns/rdtypes/IN/SRV.py
dns/rdtypes/IN/WKS.py
dns/rdtypes/dnskeybase.py
dns/rdtypes/dsbase.py
dns/rdtypes/euibase.py
dns/rdtypes/mxbase.py
dns/rdtypes/nsbase.py
dns/rdtypes/txtbase.py

index 0d45ac17f105f4ab203321a7c19ff2defebff844..cd4b4468d2556142c780cac4e66cc663e568ccb1 100644 (file)
@@ -329,6 +329,10 @@ class Name(object):
         # Names are immutable
         raise TypeError("object doesn't support attribute assignment")
 
+    def __delattr__(self, name):
+        # Names are immutable
+        raise TypeError("object doesn't support attribute deletion")
+
     def __copy__(self):
         return Name(self.labels)
 
index 640f731559119d1a23af380cd983e2f4a48eb9a6..51c5f0ed76fabeac26e266866855d8d229d12a89 100644 (file)
@@ -90,6 +90,21 @@ def _truncate_bitmap(what):
             return what[0: i + 1]
     return what[0:1]
 
+def _constify(o):
+    """
+    Convert mutable types to immutable types.
+    """
+    if type(o) == bytearray:
+        return bytes(o)
+    if type(o) == tuple:
+        try:
+            hash(o)
+            return o
+        except:
+            return tuple(_constify(elt) for elt in o)
+    if type(o) == list:
+        return tuple(_constify(elt) for elt in o)
+    return o
 
 class Rdata(object):
     """Base class for all DNS rdata types."""
@@ -103,8 +118,16 @@ class Rdata(object):
         *rdtype*, an ``int`` is the rdatatype of the Rdata.
         """
 
-        self.rdclass = rdclass
-        self.rdtype = rdtype
+        object.__setattr__(self, 'rdclass', rdclass)
+        object.__setattr__(self, 'rdtype', rdtype)
+
+    def __setattr__(self, name, value):
+        # Rdatas are immutable
+        raise TypeError("object doesn't support attribute assignment")
+
+    def __delattr__(self, name):
+        # Rdatas are immutable
+        raise TypeError("object doesn't support attribute deletion")
 
     def covers(self):
         """Return the type a Rdata covers.
@@ -270,7 +293,7 @@ class GenericRdata(Rdata):
 
     def __init__(self, rdclass, rdtype, data):
         super(GenericRdata, self).__init__(rdclass, rdtype)
-        self.data = data
+        object.__setattr__(self, 'data', data)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return r'\# %d ' % len(self.data) + _hexify(self.data)
index 254bdc6249a4f56b4de2f62db55f4e76e218a379..9b202e37485d78ff229ce0017cdf5f553dcd847d 100644 (file)
@@ -37,10 +37,10 @@ class CAA(dns.rdata.Rdata):
     __slots__ = ['flags', 'tag', 'value']
 
     def __init__(self, rdclass, rdtype, flags, tag, value):
-        super(CAA, self).__init__(rdclass, rdtype)
-        self.flags = flags
-        self.tag = tag
-        self.value = value
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'flags', flags)
+        object.__setattr__(self, 'tag', tag)
+        object.__setattr__(self, 'value', value)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '%u %s "%s"' % (self.flags,
index 79517755575f2eed2e4db56924583ec2512df0b0..ab937da600dcf294e05877f66a2431ab4816e088 100644 (file)
@@ -72,11 +72,11 @@ class CERT(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, certificate_type, key_tag, algorithm,
                  certificate):
-        super(CERT, self).__init__(rdclass, rdtype)
-        self.certificate_type = certificate_type
-        self.key_tag = key_tag
-        self.algorithm = algorithm
-        self.certificate = certificate
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'certificate_type', certificate_type)
+        object.__setattr__(self, 'key_tag', key_tag)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'certificate', certificate)
 
     def to_text(self, origin=None, relativize=True, **kw):
         certificate_type = _ctype_to_text(self.certificate_type)
index 26508b56b83365b695df75e71143edb9d2c83f95..1579284b2a1f3e24a7bec2ee1e11e80e3f049252 100644 (file)
@@ -36,10 +36,10 @@ class CSYNC(dns.rdata.Rdata):
     __slots__ = ['serial', 'flags', 'windows']
 
     def __init__(self, rdclass, rdtype, serial, flags, windows):
-        super(CSYNC, self).__init__(rdclass, rdtype)
-        self.serial = serial
-        self.flags = flags
-        self.windows = windows
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'serial', serial)
+        object.__setattr__(self, 'flags', flags)
+        object.__setattr__(self, 'windows', dns.rdata._constify(windows))
 
     def to_text(self, origin=None, relativize=True, **kw):
         text = ''
index 5db2ddbe8034ae8bb6abba02314ff2a4c1afe1ef..d64b1ee88ed732e93073d043655d48a7aa5f0aab 100644 (file)
@@ -57,7 +57,7 @@ class GPOS(dns.rdata.Rdata):
     __slots__ = ['latitude', 'longitude', 'altitude']
 
     def __init__(self, rdclass, rdtype, latitude, longitude, altitude):
-        super(GPOS, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         if isinstance(latitude, float) or \
            isinstance(latitude, int):
             latitude = str(latitude)
@@ -73,9 +73,9 @@ class GPOS(dns.rdata.Rdata):
         _validate_float_string(latitude)
         _validate_float_string(longitude)
         _validate_float_string(altitude)
-        self.latitude = latitude
-        self.longitude = longitude
-        self.altitude = altitude
+        object.__setattr__(self, 'latitude', latitude)
+        object.__setattr__(self, 'longitude', longitude)
+        object.__setattr__(self, 'altitude', altitude)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '{} {} {}'.format(self.latitude.decode(),
index d68230f23a264101a7498dace2af269ea3affad7..85eef5809b6fb9e91fce45fdd55272ff3532a028 100644 (file)
@@ -35,15 +35,15 @@ class HINFO(dns.rdata.Rdata):
     __slots__ = ['cpu', 'os']
 
     def __init__(self, rdclass, rdtype, cpu, os):
-        super(HINFO, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         if isinstance(cpu, str):
-            self.cpu = cpu.encode()
+            object.__setattr__(self, 'cpu', cpu.encode())
         else:
-            self.cpu = cpu
+            object.__setattr__(self, 'cpu', cpu)
         if isinstance(os, str):
-            self.os = os.encode()
+            object.__setattr__(self, 'os', os.encode())
         else:
-            self.os = os
+            object.__setattr__(self, 'os', os)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '"{}" "{}"'.format(dns.rdata._escapify(self.cpu),
index 0b3dfb0de1b4d5904552c649514ac7e39d83a4ac..4f26bde1c3936bcfe97fb2135cb7a68249ae2b97 100644 (file)
@@ -41,11 +41,11 @@ class HIP(dns.rdata.Rdata):
     __slots__ = ['hit', 'algorithm', 'key', 'servers']
 
     def __init__(self, rdclass, rdtype, hit, algorithm, key, servers):
-        super(HIP, self).__init__(rdclass, rdtype)
-        self.hit = hit
-        self.algorithm = algorithm
-        self.key = key
-        self.servers = servers
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'hit', hit)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'key', key)
+        object.__setattr__(self, 'servers', dns.rdata._constify(servers))
 
     def to_text(self, origin=None, relativize=True, **kw):
         hit = binascii.hexlify(self.hit).decode()
index eeb51b06c2ba033c2ce7d63930a4f482d300dd6d..467eeed5fdda7eb3006ba97af38607f8f8331c33 100644 (file)
@@ -35,15 +35,15 @@ class ISDN(dns.rdata.Rdata):
     __slots__ = ['address', 'subaddress']
 
     def __init__(self, rdclass, rdtype, address, subaddress):
-        super(ISDN, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         if isinstance(address, str):
-            self.address = address.encode()
+            object.__setattr__(self, 'address', address.encode())
         else:
-            self.address = address
+            object.__setattr__(self, 'address', address)
         if isinstance(address, str):
-            self.subaddress = subaddress.encode()
+            object.__setattr__(self, 'subaddress', subaddress.encode())
         else:
-            self.subaddress = subaddress
+            object.__setattr__(self, 'subaddress', subaddress)
 
     def to_text(self, origin=None, relativize=True, **kw):
         if self.subaddress:
index 9d6f046347f733bafb4b6175e9bb4108cfd30e76..f6f3efcf73dfeab0254f3d9cd7e2baadb05a9549 100644 (file)
@@ -120,21 +120,21 @@ class LOC(dns.rdata.Rdata):
         degrees. The other parameters are floats. Size, horizontal precision,
         and vertical precision are specified in centimeters."""
 
-        super(LOC, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         if isinstance(latitude, int):
             latitude = float(latitude)
         if isinstance(latitude, float):
             latitude = _float_to_tuple(latitude)
-        self.latitude = latitude
+        object.__setattr__(self, 'latitude', dns.rdata._constify(latitude))
         if isinstance(longitude, int):
             longitude = float(longitude)
         if isinstance(longitude, float):
             longitude = _float_to_tuple(longitude)
-        self.longitude = longitude
-        self.altitude = float(altitude)
-        self.size = float(size)
-        self.horizontal_precision = float(hprec)
-        self.vertical_precision = float(vprec)
+        object.__setattr__(self, 'longitude', dns.rdata._constify(longitude))
+        object.__setattr__(self, 'altitude', float(altitude))
+        object.__setattr__(self, 'size', float(size))
+        object.__setattr__(self, 'horizontal_precision', float(hprec))
+        object.__setattr__(self, 'vertical_precision', float(vprec))
 
     def to_text(self, origin=None, relativize=True, **kw):
         if self.latitude[4] > 0:
index 2b7bc6c4bc0027b5549b77d45df94228cc82d683..fc6d0754ba66638e0028c36bf8c6358811bb9aff 100644 (file)
@@ -35,9 +35,9 @@ class NSEC(dns.rdata.Rdata):
     __slots__ = ['next', 'windows']
 
     def __init__(self, rdclass, rdtype, next, windows):
-        super(NSEC, self).__init__(rdclass, rdtype)
-        self.next = next
-        self.windows = windows
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'next', next)
+        object.__setattr__(self, 'windows', dns.rdata._constify(windows))
 
     def to_text(self, origin=None, relativize=True, **kw):
         next = self.next.choose_relativity(origin, relativize)
index 086f526292b88ad2be7932d0c7c10878620cd1eb..fbb25556d3e986e211ebbec8c4f8bf5ae92f5be3 100644 (file)
@@ -57,16 +57,16 @@ class NSEC3(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt,
                  next, windows):
-        super(NSEC3, self).__init__(rdclass, rdtype)
-        self.algorithm = algorithm
-        self.flags = flags
-        self.iterations = iterations
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'flags', flags)
+        object.__setattr__(self, 'iterations', iterations)
         if isinstance(salt, str):
-            self.salt = salt.encode()
+            object.__setattr__(self, 'salt', salt.encode())
         else:
-            self.salt = salt
-        self.next = next
-        self.windows = windows
+            object.__setattr__(self, 'salt', salt)
+        object.__setattr__(self, 'next', next)
+        object.__setattr__(self, 'windows', dns.rdata._constify(windows))
 
     def to_text(self, origin=None, relativize=True, **kw):
         next = base64.b32encode(self.next).translate(
index 8f21657ba68fe96ebff3375d7cbc19076ca5fcc0..d317b6c5d5341f423813800834f1359250e03deb 100644 (file)
@@ -38,14 +38,14 @@ class NSEC3PARAM(dns.rdata.Rdata):
     __slots__ = ['algorithm', 'flags', 'iterations', 'salt']
 
     def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt):
-        super(NSEC3PARAM, self).__init__(rdclass, rdtype)
-        self.algorithm = algorithm
-        self.flags = flags
-        self.iterations = iterations
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'flags', flags)
+        object.__setattr__(self, 'iterations', iterations)
         if isinstance(salt, str):
-            self.salt = salt.encode()
+            object.__setattr__(self, 'salt', salt.encode())
         else:
-            self.salt = salt
+            object.__setattr__(self, 'salt', salt)
 
     def to_text(self, origin=None, relativize=True, **kw):
         if self.salt == b'':
index 5bce444c039369cb0be32114377822f0b629ae01..e9b43095cf1320801ccdae88e246ebeacbfec7bf 100644 (file)
@@ -31,8 +31,8 @@ class OPENPGPKEY(dns.rdata.Rdata):
     """
 
     def __init__(self, rdclass, rdtype, key):
-        super(OPENPGPKEY, self).__init__(rdclass, rdtype)
-        self.key = key
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'key', key)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return dns.rdata._base64ify(self.key)
index 1c8afe232a04a84219d139c214b08a4df04b7fcc..71a4bb782c73dc827680076117b410547d88e4cf 100644 (file)
@@ -35,8 +35,8 @@ class RP(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, mbox, txt):
         super(RP, self).__init__(rdclass, rdtype)
-        self.mbox = mbox
-        self.txt = txt
+        object.__setattr__(self, 'mbox', mbox)
+        object.__setattr__(self, 'txt', txt)
 
     def to_text(self, origin=None, relativize=True, **kw):
         mbox = self.mbox.choose_relativity(origin, relativize)
index cef60007f36ac2694b2cb309823c708de556e88e..206a37b6e3b18ae8c0f11970462c7f6cfa0d05cc 100644 (file)
@@ -80,16 +80,16 @@ class RRSIG(dns.rdata.Rdata):
     def __init__(self, rdclass, rdtype, type_covered, algorithm, labels,
                  original_ttl, expiration, inception, key_tag, signer,
                  signature):
-        super(RRSIG, self).__init__(rdclass, rdtype)
-        self.type_covered = type_covered
-        self.algorithm = algorithm
-        self.labels = labels
-        self.original_ttl = original_ttl
-        self.expiration = expiration
-        self.inception = inception
-        self.key_tag = key_tag
-        self.signer = signer
-        self.signature = signature
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'type_covered', type_covered)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'labels', labels)
+        object.__setattr__(self, 'original_ttl', original_ttl)
+        object.__setattr__(self, 'expiration', expiration)
+        object.__setattr__(self, 'inception', inception)
+        object.__setattr__(self, 'key_tag', key_tag)
+        object.__setattr__(self, 'signer', signer)
+        object.__setattr__(self, 'signature', signature)
 
     def covers(self):
         return self.type_covered
index 58a65f64dad313feb206625dd0b9956dbdb13ff3..a859557dd000c2a4a218f695a07b53c33be24cf1 100644 (file)
@@ -48,14 +48,14 @@ class SOA(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry,
                  expire, minimum):
-        super(SOA, self).__init__(rdclass, rdtype)
-        self.mname = mname
-        self.rname = rname
-        self.serial = serial
-        self.refresh = refresh
-        self.retry = retry
-        self.expire = expire
-        self.minimum = minimum
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'mname', mname)
+        object.__setattr__(self, 'rname', rname)
+        object.__setattr__(self, 'serial', serial)
+        object.__setattr__(self, 'refresh', refresh)
+        object.__setattr__(self, 'retry', retry)
+        object.__setattr__(self, 'expire', expire)
+        object.__setattr__(self, 'minimum', minimum)
 
     def to_text(self, origin=None, relativize=True, **kw):
         mname = self.mname.choose_relativity(origin, relativize)
index 7c27ccba650c0edeac1da2b30e16f1613cf41b0b..0c06607fc7fe51fd4aec9e90e264ec98d3e92ae8 100644 (file)
@@ -38,10 +38,10 @@ class SSHFP(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, algorithm, fp_type,
                  fingerprint):
-        super(SSHFP, self).__init__(rdclass, rdtype)
-        self.algorithm = algorithm
-        self.fp_type = fp_type
-        self.fingerprint = fingerprint
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'fp_type', fp_type)
+        object.__setattr__(self, 'fingerprint', fingerprint)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '%d %d %s' % (self.algorithm,
index 83e4d6357d4a0890e6f4d14e2bd0e3663b465857..ac2b3261504125d787e583f5371d4d1e60268bc4 100644 (file)
@@ -40,11 +40,11 @@ class TLSA(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, usage, selector,
                  mtype, cert):
-        super(TLSA, self).__init__(rdclass, rdtype)
-        self.usage = usage
-        self.selector = selector
-        self.mtype = mtype
-        self.cert = cert
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'usage', usage)
+        object.__setattr__(self, 'selector', selector)
+        object.__setattr__(self, 'mtype', mtype)
+        object.__setattr__(self, 'cert', cert)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '%d %d %d %s' % (self.usage,
index 576344e1ffddd517b4330c1d8c268ad22d14d1d5..4e9d93613cd0df80470e33a3a82cfdd83ca33a20 100644 (file)
@@ -38,15 +38,15 @@ class URI(dns.rdata.Rdata):
     __slots__ = ['priority', 'weight', 'target']
 
     def __init__(self, rdclass, rdtype, priority, weight, target):
-        super(URI, self).__init__(rdclass, rdtype)
-        self.priority = priority
-        self.weight = weight
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'priority', priority)
+        object.__setattr__(self, 'weight', weight)
         if len(target) < 1:
             raise dns.exception.SyntaxError("URI target cannot be empty")
         if isinstance(target, str):
-            self.target = target.encode()
+            object.__setattr__(self, 'target', target.encode())
         else:
-            self.target = target
+            object.__setattr__(self, 'target', target)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '%d %d "%s"' % (self.priority, self.weight,
index 7c7d25b7d717134003492b5ae6e4c07008c0db2e..dfae3d4d213e01ff4b49cb79e523c4af3263ca12 100644 (file)
@@ -33,11 +33,11 @@ class X25(dns.rdata.Rdata):
     __slots__ = ['address']
 
     def __init__(self, rdclass, rdtype, address):
-        super(X25, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         if isinstance(address, str):
-            self.address = address.encode()
+            object.__setattr__(self, 'address', address.encode())
         else:
-            self.address = address
+            object.__setattr__(self, 'address', address)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '"%s"' % dns.rdata._escapify(self.address)
index 34d432c8054864f643e7c92fa78c8046751393f2..14afbc1e1bc318b3c83cb0f1d1cd014e03f7d074 100644 (file)
@@ -30,8 +30,8 @@ class A(dns.rdtypes.mxbase.MXBase):
 
     def __init__(self, rdclass, rdtype, address, domain):
         super(A, self).__init__(rdclass, rdtype, address, domain)
-        self.domain = domain
-        self.address = address
+        object.__setattr__(self, 'domain', domain)
+        object.__setattr__(self, 'address', address)
 
     def to_text(self, origin=None, relativize=True, **kw):
         domain = self.domain.choose_relativity(origin, relativize)
index 84e54ab99dc76bd38cf3a8b1b526615d72a6871a..a489d3c7341a90d7013f517f6873f3dff0f6cf63 100644 (file)
@@ -31,10 +31,10 @@ class A(dns.rdata.Rdata):
     __slots__ = ['address']
 
     def __init__(self, rdclass, rdtype, address):
-        super(A, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         # check that it's OK
         dns.ipv4.inet_aton(address)
-        self.address = address
+        object.__setattr__(self, 'address', address)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return self.address
index b6b13baf47f682e6065a046340c3daee585eadee..46ff6159877dca787920fd28b095d4aa0e7af6e7 100644 (file)
@@ -31,10 +31,10 @@ class AAAA(dns.rdata.Rdata):
     __slots__ = ['address']
 
     def __init__(self, rdclass, rdtype, address):
-        super(AAAA, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         # check that it's OK
         dns.inet.inet_pton(dns.inet.AF_INET6, address)
-        self.address = address
+        object.__setattr__(self, 'address', address)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return self.address
index f82449854d09e94731cd835759dd5ada44b093e6..be9397bf9aba242f177dfe92770afb032f9aa46f 100644 (file)
@@ -88,8 +88,8 @@ class APL(dns.rdata.Rdata):
     __slots__ = ['items']
 
     def __init__(self, rdclass, rdtype, items):
-        super(APL, self).__init__(rdclass, rdtype)
-        self.items = items
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'items', dns.rdata._constify(items))
 
     def to_text(self, origin=None, relativize=True, **kw):
         return ' '.join(map(str, self.items))
index 1cc50ff6c9c89a6baba6350f7fe4ebacfcb8335c..e9079f67b2990e6f31213803d2f1883181acfc2b 100644 (file)
@@ -32,8 +32,8 @@ class DHCID(dns.rdata.Rdata):
     __slots__ = ['data']
 
     def __init__(self, rdclass, rdtype, data):
-        super(DHCID, self).__init__(rdclass, rdtype)
-        self.data = data
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'data', data)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return dns.rdata._base64ify(self.data)
index 4a81d9814a64ec9afc545b236dd0b9f3cf0ef213..96ab54800ad2e997749268642279c63b730d1469 100644 (file)
@@ -43,7 +43,7 @@ class IPSECKEY(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, precedence, gateway_type, algorithm,
                  gateway, key):
-        super(IPSECKEY, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         if gateway_type == 0:
             if gateway != '.' and gateway is not None:
                 raise SyntaxError('invalid gateway for gateway type 0')
@@ -59,11 +59,11 @@ class IPSECKEY(dns.rdata.Rdata):
         else:
             raise SyntaxError(
                 'invalid IPSECKEY gateway type: %d' % gateway_type)
-        self.precedence = precedence
-        self.gateway_type = gateway_type
-        self.algorithm = algorithm
-        self.gateway = gateway
-        self.key = key
+        object.__setattr__(self, 'precedence', precedence)
+        object.__setattr__(self, 'gateway_type', gateway_type)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'gateway', gateway)
+        object.__setattr__(self, 'key', key)
 
     def to_text(self, origin=None, relativize=True, **kw):
         if self.gateway_type == 0:
index 69c988cdad026db613d923f945b8e61350e4e07e..8b144bdfb79dae1729385e9c5f06fcb36bbb7117 100644 (file)
@@ -58,13 +58,13 @@ class NAPTR(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, order, preference, flags, service,
                  regexp, replacement):
-        super(NAPTR, self).__init__(rdclass, rdtype)
-        self.flags = _sanitize(flags)
-        self.service = _sanitize(service)
-        self.regexp = _sanitize(regexp)
-        self.order = order
-        self.preference = preference
-        self.replacement = replacement
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'flags', _sanitize(flags))
+        object.__setattr__(self, 'service', _sanitize(service))
+        object.__setattr__(self, 'regexp', _sanitize(regexp))
+        object.__setattr__(self, 'order', order)
+        object.__setattr__(self, 'preference', preference)
+        object.__setattr__(self, 'replacement', replacement)
 
     def to_text(self, origin=None, relativize=True, **kw):
         replacement = self.replacement.choose_relativity(origin, relativize)
index c4df595088eead10ae7e60c93b51049c108b8790..8f4022be34e7269bdf579c4c587a4710541449af 100644 (file)
@@ -33,8 +33,8 @@ class NSAP(dns.rdata.Rdata):
     __slots__ = ['address']
 
     def __init__(self, rdclass, rdtype, address):
-        super(NSAP, self).__init__(rdclass, rdtype)
-        self.address = address
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'address', address)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return "0x%s" % binascii.hexlify(self.address).decode()
index 86f8613815a39332aad59815d726f173ceff20a5..9ddbfda37a30c5dc11b5bdb609b6d02c98225065 100644 (file)
@@ -37,10 +37,10 @@ class PX(dns.rdata.Rdata):
     __slots__ = ['preference', 'map822', 'mapx400']
 
     def __init__(self, rdclass, rdtype, preference, map822, mapx400):
-        super(PX, self).__init__(rdclass, rdtype)
-        self.preference = preference
-        self.map822 = map822
-        self.mapx400 = mapx400
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'preference', preference)
+        object.__setattr__(self, 'map822', map822)
+        object.__setattr__(self, 'mapx400', mapx400)
 
     def to_text(self, origin=None, relativize=True, **kw):
         map822 = self.map822.choose_relativity(origin, relativize)
index 87c047116b3627dbdf7d2450423a73e17bf3a8ee..7603ce77005f7345ea4771af359b6f5037f9ea42 100644 (file)
@@ -39,11 +39,11 @@ class SRV(dns.rdata.Rdata):
     __slots__ = ['priority', 'weight', 'port', 'target']
 
     def __init__(self, rdclass, rdtype, priority, weight, port, target):
-        super(SRV, self).__init__(rdclass, rdtype)
-        self.priority = priority
-        self.weight = weight
-        self.port = port
-        self.target = target
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'priority', priority)
+        object.__setattr__(self, 'weight', weight)
+        object.__setattr__(self, 'port', port)
+        object.__setattr__(self, 'target', target)
 
     def to_text(self, origin=None, relativize=True, **kw):
         target = self.target.choose_relativity(origin, relativize)
index ac0e9c85c4b65690fba2f50465879f21e07e69ab..d7b748fcba5d21dcec6b0b5aa2afab3692e752ec 100644 (file)
@@ -40,13 +40,10 @@ class WKS(dns.rdata.Rdata):
     __slots__ = ['address', 'protocol', 'bitmap']
 
     def __init__(self, rdclass, rdtype, address, protocol, bitmap):
-        super(WKS, self).__init__(rdclass, rdtype)
-        self.address = address
-        self.protocol = protocol
-        if not isinstance(bitmap, bytearray):
-            self.bitmap = bytearray(bitmap)
-        else:
-            self.bitmap = bitmap
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'address', address)
+        object.__setattr__(self, 'protocol', protocol)
+        object.__setattr__(self, 'bitmap', dns.rdata._constify(bitmap))
 
     def to_text(self, origin=None, relativize=True, **kw):
         bits = []
index ea8f19156cf866bd033bfbdc8366de95655e39ed..48ff6acd2a2c6c28821f02b2d4581fd513e0b30e 100644 (file)
@@ -89,11 +89,11 @@ class DNSKEYBase(dns.rdata.Rdata):
     __slots__ = ['flags', 'protocol', 'algorithm', 'key']
 
     def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key):
-        super(DNSKEYBase, self).__init__(rdclass, rdtype)
-        self.flags = flags
-        self.protocol = protocol
-        self.algorithm = algorithm
-        self.key = key
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'flags', flags)
+        object.__setattr__(self, 'protocol', protocol)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'key', key)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm,
index ac5904d924b3ca60714e7bc7371256236f2fd167..22df9240a214e46cdef0d76649e89a8f86c0e575 100644 (file)
@@ -40,11 +40,11 @@ class DSBase(dns.rdata.Rdata):
 
     def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type,
                  digest):
-        super(DSBase, self).__init__(rdclass, rdtype)
-        self.key_tag = key_tag
-        self.algorithm = algorithm
-        self.digest_type = digest_type
-        self.digest = digest
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'key_tag', key_tag)
+        object.__setattr__(self, 'algorithm', algorithm)
+        object.__setattr__(self, 'digest_type', digest_type)
+        object.__setattr__(self, 'digest', digest)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '%d %d %d %s' % (self.key_tag, self.algorithm,
index 9ac8bc01b45462cedaedc39a904159be0625a023..fdb20af3b56feb5026c02a3cebd7ee0a484a8f2e 100644 (file)
@@ -33,11 +33,11 @@ class EUIBase(dns.rdata.Rdata):
     # text_len = byte_len * 3 - 1  # 01-23-45-67-89-ab
 
     def __init__(self, rdclass, rdtype, eui):
-        super(EUIBase, self).__init__(rdclass, rdtype)
+        super().__init__(rdclass, rdtype)
         if len(eui) != self.byte_len:
             raise dns.exception.FormError('EUI%s rdata has to have %s bytes'
                                           % (self.byte_len * 8, self.byte_len))
-        self.eui = eui
+        object.__setattr__(self, 'eui', eui)
 
     def to_text(self, origin=None, relativize=True, **kw):
         return dns.rdata._hexify(self.eui, chunksize=2).replace(' ', '-')
index 7ed97f57da2adbc93de026552ce5a413bbdf0d79..435b51f5bcdba26563561af5d3a30be1d9ab8476 100644 (file)
@@ -37,9 +37,9 @@ class MXBase(dns.rdata.Rdata):
     __slots__ = ['preference', 'exchange']
 
     def __init__(self, rdclass, rdtype, preference, exchange):
-        super(MXBase, self).__init__(rdclass, rdtype)
-        self.preference = preference
-        self.exchange = exchange
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'preference', preference)
+        object.__setattr__(self, 'exchange', exchange)
 
     def to_text(self, origin=None, relativize=True, **kw):
         exchange = self.exchange.choose_relativity(origin, relativize)
index b55a7f2e0097749b1dfc714d4a138ec4f5724471..9e336c9eb5d000959b99f14cc3c38389f75a8922 100644 (file)
@@ -34,8 +34,8 @@ class NSBase(dns.rdata.Rdata):
     __slots__ = ['target']
 
     def __init__(self, rdclass, rdtype, target):
-        super(NSBase, self).__init__(rdclass, rdtype)
-        self.target = target
+        super().__init__(rdclass, rdtype)
+        object.__setattr__(self, 'target', target)
 
     def to_text(self, origin=None, relativize=True, **kw):
         target = self.target.choose_relativity(origin, relativize)
index 0988052721237bfd2e5a32a4ac3672dc5a72d35b..9c13ed9849d5bb300a57c84e0e844fcc4be79bce 100644 (file)
@@ -35,15 +35,17 @@ class TXTBase(dns.rdata.Rdata):
     __slots__ = ['strings']
 
     def __init__(self, rdclass, rdtype, strings):
-        super(TXTBase, self).__init__(rdclass, rdtype)
-        if isinstance(strings, bytes) or \
-           isinstance(strings, str):
-            strings = [strings]
-        self.strings = []
+        super().__init__(rdclass, rdtype)
+        if isinstance(strings, (bytes, str)):
+            strings = (strings,)
+        encoded_strings = []
         for string in strings:
             if isinstance(string, str):
                 string = string.encode()
-            self.strings.append(string)
+            else:
+                string = dns.rdata._constify(string)
+            encoded_strings.append(string)
+        object.__setattr__(self, 'strings', tuple(encoded_strings))
 
     def to_text(self, origin=None, relativize=True, **kw):
         txt = ''