diff options
| author | Bob Halley <halley@dnspython.org> | 2020-08-19 16:05:09 -0700 |
|---|---|---|
| committer | Bob Halley <halley@dnspython.org> | 2020-08-19 16:05:09 -0700 |
| commit | ca8c5c25817d52b68d6c0faa436d502fda30ce6e (patch) | |
| tree | 6a1354a56bf3f220bd7828581326e7c99e2d7f1f /dns | |
| parent | a9326311ba4e69984c6acc7f7376c16637ec98ca (diff) | |
| parent | bee23ec15fdde8f0303b0a3699669599c5abf8cb (diff) | |
| download | dnspython-ca8c5c25817d52b68d6c0faa436d502fda30ce6e.tar.gz | |
Merge branch 'more-immut' into master
This add the immutable decorator to names and rdata, and prepares rdata
for further checking and type conversions in the constructor.
Diffstat (limited to 'dns')
65 files changed, 309 insertions, 175 deletions
diff --git a/dns/name.py b/dns/name.py index 8775e0b..8905d70 100644 --- a/dns/name.py +++ b/dns/name.py @@ -30,6 +30,7 @@ except ImportError: # pragma: no cover import dns.wire import dns.exception +import dns.immutable # fullcompare() result values @@ -305,6 +306,7 @@ def _maybe_convert_to_binary(label): raise ValueError # pragma: no cover +@dns.immutable.immutable class Name: """A DNS name. @@ -321,17 +323,9 @@ class Name: """ labels = [_maybe_convert_to_binary(x) for x in labels] - super().__setattr__('labels', tuple(labels)) + self.labels = tuple(labels) _validate_labels(self.labels) - def __setattr__(self, name, value): - # 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) diff --git a/dns/rdata.py b/dns/rdata.py index 3f0b6d2..0d8f881 100644 --- a/dns/rdata.py +++ b/dns/rdata.py @@ -97,6 +97,7 @@ def _truncate_bitmap(what): _constify = dns.immutable.constify +@dns.immutable.immutable class Rdata: """Base class for all DNS rdata types.""" @@ -110,17 +111,9 @@ class Rdata: *rdtype*, an ``int`` is the rdatatype of the Rdata. """ - object.__setattr__(self, 'rdclass', rdclass) - object.__setattr__(self, 'rdtype', rdtype) - object.__setattr__(self, 'rdcomment', None) - - 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") + self.rdclass = rdclass + self.rdtype = rdtype + self.rdcomment = None def _get_all_slots(self): return itertools.chain.from_iterable(getattr(cls, '__slots__', []) @@ -339,6 +332,11 @@ class Rdata: object.__setattr__(rd, 'rdcomment', rdcomment) return rd + def as_value(self, value): + # This is the "additional type checking" placeholder that actually + # doesn't do any additional checking. + return value + class GenericRdata(Rdata): diff --git a/dns/rdtypes/ANY/AFSDB.py b/dns/rdtypes/ANY/AFSDB.py index 4087890..d7838e7 100644 --- a/dns/rdtypes/ANY/AFSDB.py +++ b/dns/rdtypes/ANY/AFSDB.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.mxbase +import dns.immutable +@dns.immutable.immutable class AFSDB(dns.rdtypes.mxbase.UncompressedDowncasingMX): """AFSDB record""" diff --git a/dns/rdtypes/ANY/AMTRELAY.py b/dns/rdtypes/ANY/AMTRELAY.py index 4e012a2..de6e99e 100644 --- a/dns/rdtypes/ANY/AMTRELAY.py +++ b/dns/rdtypes/ANY/AMTRELAY.py @@ -18,12 +18,14 @@ import struct import dns.exception +import dns.immutable import dns.rdtypes.util class Relay(dns.rdtypes.util.Gateway): name = 'AMTRELAY relay' +@dns.immutable.immutable class AMTRELAY(dns.rdata.Rdata): """AMTRELAY record""" @@ -36,10 +38,10 @@ class AMTRELAY(dns.rdata.Rdata): relay_type, relay): super().__init__(rdclass, rdtype) Relay(relay_type, relay).check() - object.__setattr__(self, 'precedence', precedence) - object.__setattr__(self, 'discovery_optional', discovery_optional) - object.__setattr__(self, 'relay_type', relay_type) - object.__setattr__(self, 'relay', relay) + self.precedence = self.as_value(precedence) + self.discovery_optional = self.as_value(discovery_optional) + self.relay_type = self.as_value(relay_type) + self.relay = self.as_value(relay) def to_text(self, origin=None, relativize=True, **kw): relay = Relay(self.relay_type, self.relay).to_text(origin, relativize) diff --git a/dns/rdtypes/ANY/AVC.py b/dns/rdtypes/ANY/AVC.py index 1fa5ecf..11e026d 100644 --- a/dns/rdtypes/ANY/AVC.py +++ b/dns/rdtypes/ANY/AVC.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.txtbase +import dns.immutable +@dns.immutable.immutable class AVC(dns.rdtypes.txtbase.TXTBase): """AVC record""" diff --git a/dns/rdtypes/ANY/CAA.py b/dns/rdtypes/ANY/CAA.py index b7edae8..7c6dd01 100644 --- a/dns/rdtypes/ANY/CAA.py +++ b/dns/rdtypes/ANY/CAA.py @@ -18,10 +18,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.tokenizer +@dns.immutable.immutable class CAA(dns.rdata.Rdata): """CAA (Certification Authority Authorization) record""" @@ -32,9 +34,9 @@ class CAA(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, flags, tag, value): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'flags', flags) - object.__setattr__(self, 'tag', tag) - object.__setattr__(self, 'value', value) + self.flags = self.as_value(flags) + self.tag = self.as_value(tag) + self.value = self.as_value(value) def to_text(self, origin=None, relativize=True, **kw): return '%u %s "%s"' % (self.flags, diff --git a/dns/rdtypes/ANY/CDNSKEY.py b/dns/rdtypes/ANY/CDNSKEY.py index a8b1d8b..14b1941 100644 --- a/dns/rdtypes/ANY/CDNSKEY.py +++ b/dns/rdtypes/ANY/CDNSKEY.py @@ -16,11 +16,13 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.dnskeybase +import dns.immutable # pylint: disable=unused-import from dns.rdtypes.dnskeybase import SEP, REVOKE, ZONE # noqa: F401 # pylint: enable=unused-import +@dns.immutable.immutable class CDNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase): """CDNSKEY record""" diff --git a/dns/rdtypes/ANY/CDS.py b/dns/rdtypes/ANY/CDS.py index a63041d..39e3556 100644 --- a/dns/rdtypes/ANY/CDS.py +++ b/dns/rdtypes/ANY/CDS.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.dsbase +import dns.immutable +@dns.immutable.immutable class CDS(dns.rdtypes.dsbase.DSBase): """CDS record""" diff --git a/dns/rdtypes/ANY/CERT.py b/dns/rdtypes/ANY/CERT.py index 3fce95b..c78322a 100644 --- a/dns/rdtypes/ANY/CERT.py +++ b/dns/rdtypes/ANY/CERT.py @@ -19,6 +19,7 @@ import struct import base64 import dns.exception +import dns.immutable import dns.dnssec import dns.rdata import dns.tokenizer @@ -54,6 +55,7 @@ def _ctype_to_text(what): return str(what) +@dns.immutable.immutable class CERT(dns.rdata.Rdata): """CERT record""" @@ -65,10 +67,10 @@ class CERT(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, certificate_type, key_tag, algorithm, 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) + self.certificate_type = self.as_value(certificate_type) + self.key_tag = self.as_value(key_tag) + self.algorithm = self.as_value(algorithm) + self.certificate = self.as_value(certificate) def to_text(self, origin=None, relativize=True, **kw): certificate_type = _ctype_to_text(self.certificate_type) diff --git a/dns/rdtypes/ANY/CNAME.py b/dns/rdtypes/ANY/CNAME.py index 11d42aa..a4fcfa8 100644 --- a/dns/rdtypes/ANY/CNAME.py +++ b/dns/rdtypes/ANY/CNAME.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.nsbase +import dns.immutable +@dns.immutable.immutable class CNAME(dns.rdtypes.nsbase.NSBase): """CNAME record diff --git a/dns/rdtypes/ANY/CSYNC.py b/dns/rdtypes/ANY/CSYNC.py index 9cba5fa..0f626a9 100644 --- a/dns/rdtypes/ANY/CSYNC.py +++ b/dns/rdtypes/ANY/CSYNC.py @@ -18,16 +18,19 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.rdatatype import dns.name import dns.rdtypes.util +@dns.immutable.immutable class Bitmap(dns.rdtypes.util.Bitmap): type_name = 'CSYNC' +@dns.immutable.immutable class CSYNC(dns.rdata.Rdata): """CSYNC record""" @@ -36,9 +39,9 @@ class CSYNC(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, serial, flags, windows): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'serial', serial) - object.__setattr__(self, 'flags', flags) - object.__setattr__(self, 'windows', dns.rdata._constify(windows)) + self.serial = self.as_value(serial) + self.flags = self.as_value(flags) + self.windows = self.as_value(dns.rdata._constify(windows)) def to_text(self, origin=None, relativize=True, **kw): text = Bitmap(self.windows).to_text() diff --git a/dns/rdtypes/ANY/DLV.py b/dns/rdtypes/ANY/DLV.py index 1635212..947dc42 100644 --- a/dns/rdtypes/ANY/DLV.py +++ b/dns/rdtypes/ANY/DLV.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.dsbase +import dns.immutable +@dns.immutable.immutable class DLV(dns.rdtypes.dsbase.DSBase): """DLV record""" diff --git a/dns/rdtypes/ANY/DNAME.py b/dns/rdtypes/ANY/DNAME.py index 2000d9b..f4984b5 100644 --- a/dns/rdtypes/ANY/DNAME.py +++ b/dns/rdtypes/ANY/DNAME.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.nsbase +import dns.immutable +@dns.immutable.immutable class DNAME(dns.rdtypes.nsbase.UncompressedNS): """DNAME record""" diff --git a/dns/rdtypes/ANY/DNSKEY.py b/dns/rdtypes/ANY/DNSKEY.py index 7173b41..e69a7c1 100644 --- a/dns/rdtypes/ANY/DNSKEY.py +++ b/dns/rdtypes/ANY/DNSKEY.py @@ -16,11 +16,13 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.dnskeybase +import dns.immutable # pylint: disable=unused-import from dns.rdtypes.dnskeybase import SEP, REVOKE, ZONE # noqa: F401 # pylint: enable=unused-import +@dns.immutable.immutable class DNSKEY(dns.rdtypes.dnskeybase.DNSKEYBase): """DNSKEY record""" diff --git a/dns/rdtypes/ANY/DS.py b/dns/rdtypes/ANY/DS.py index 7d457b2..3f6c3ee 100644 --- a/dns/rdtypes/ANY/DS.py +++ b/dns/rdtypes/ANY/DS.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.dsbase +import dns.immutable +@dns.immutable.immutable class DS(dns.rdtypes.dsbase.DSBase): """DS record""" diff --git a/dns/rdtypes/ANY/EUI48.py b/dns/rdtypes/ANY/EUI48.py index b16e81f..0ab88ad 100644 --- a/dns/rdtypes/ANY/EUI48.py +++ b/dns/rdtypes/ANY/EUI48.py @@ -17,8 +17,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.euibase +import dns.immutable +@dns.immutable.immutable class EUI48(dns.rdtypes.euibase.EUIBase): """EUI48 record""" diff --git a/dns/rdtypes/ANY/EUI64.py b/dns/rdtypes/ANY/EUI64.py index cc08076..c42957e 100644 --- a/dns/rdtypes/ANY/EUI64.py +++ b/dns/rdtypes/ANY/EUI64.py @@ -17,8 +17,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.euibase +import dns.immutable +@dns.immutable.immutable class EUI64(dns.rdtypes.euibase.EUIBase): """EUI64 record""" diff --git a/dns/rdtypes/ANY/GPOS.py b/dns/rdtypes/ANY/GPOS.py index 8285b3f..f9e3ed8 100644 --- a/dns/rdtypes/ANY/GPOS.py +++ b/dns/rdtypes/ANY/GPOS.py @@ -18,6 +18,7 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.tokenizer @@ -47,6 +48,7 @@ def _sanitize(value): return value +@dns.immutable.immutable class GPOS(dns.rdata.Rdata): """GPOS record""" @@ -72,9 +74,9 @@ class GPOS(dns.rdata.Rdata): _validate_float_string(latitude) _validate_float_string(longitude) _validate_float_string(altitude) - object.__setattr__(self, 'latitude', latitude) - object.__setattr__(self, 'longitude', longitude) - object.__setattr__(self, 'altitude', altitude) + self.latitude = self.as_value(latitude) + self.longitude = self.as_value(longitude) + self.altitude = self.as_value(altitude) flat = self.float_latitude if flat < -90.0 or flat > 90.0: raise dns.exception.FormError('bad latitude') diff --git a/dns/rdtypes/ANY/HINFO.py b/dns/rdtypes/ANY/HINFO.py index 6c1ccfa..b254330 100644 --- a/dns/rdtypes/ANY/HINFO.py +++ b/dns/rdtypes/ANY/HINFO.py @@ -18,10 +18,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.tokenizer +@dns.immutable.immutable class HINFO(dns.rdata.Rdata): """HINFO record""" @@ -33,13 +35,13 @@ class HINFO(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, cpu, os): super().__init__(rdclass, rdtype) if isinstance(cpu, str): - object.__setattr__(self, 'cpu', cpu.encode()) + self.cpu = self.as_value(cpu.encode()) else: - object.__setattr__(self, 'cpu', cpu) + self.cpu = self.as_value(cpu) if isinstance(os, str): - object.__setattr__(self, 'os', os.encode()) + self.os = self.as_value(os.encode()) else: - object.__setattr__(self, 'os', os) + self.os = self.as_value(os) def to_text(self, origin=None, relativize=True, **kw): return '"{}" "{}"'.format(dns.rdata._escapify(self.cpu), diff --git a/dns/rdtypes/ANY/HIP.py b/dns/rdtypes/ANY/HIP.py index 437ee73..4ed3507 100644 --- a/dns/rdtypes/ANY/HIP.py +++ b/dns/rdtypes/ANY/HIP.py @@ -20,10 +20,12 @@ import base64 import binascii import dns.exception +import dns.immutable import dns.rdata import dns.rdatatype +@dns.immutable.immutable class HIP(dns.rdata.Rdata): """HIP record""" @@ -34,10 +36,10 @@ class HIP(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, hit, algorithm, key, 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)) + self.hit = self.as_value(hit) + self.algorithm = self.as_value(algorithm) + self.key = self.as_value(key) + self.servers = self.as_value(dns.rdata._constify(servers)) def to_text(self, origin=None, relativize=True, **kw): hit = binascii.hexlify(self.hit).decode() diff --git a/dns/rdtypes/ANY/ISDN.py b/dns/rdtypes/ANY/ISDN.py index b07594f..2a6ff6f 100644 --- a/dns/rdtypes/ANY/ISDN.py +++ b/dns/rdtypes/ANY/ISDN.py @@ -18,10 +18,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.tokenizer +@dns.immutable.immutable class ISDN(dns.rdata.Rdata): """ISDN record""" @@ -33,13 +35,13 @@ class ISDN(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, address, subaddress): super().__init__(rdclass, rdtype) if isinstance(address, str): - object.__setattr__(self, 'address', address.encode()) + self.address = self.as_value(address.encode()) else: - object.__setattr__(self, 'address', address) + self.address = self.as_value(address) if isinstance(address, str): - object.__setattr__(self, 'subaddress', subaddress.encode()) + self.subaddress = self.as_value(subaddress.encode()) else: - object.__setattr__(self, 'subaddress', subaddress) + self.subaddress = self.as_value(subaddress) def to_text(self, origin=None, relativize=True, **kw): if self.subaddress: diff --git a/dns/rdtypes/ANY/LOC.py b/dns/rdtypes/ANY/LOC.py index c9e985b..d2a7783 100644 --- a/dns/rdtypes/ANY/LOC.py +++ b/dns/rdtypes/ANY/LOC.py @@ -18,6 +18,7 @@ import struct import dns.exception +import dns.immutable import dns.rdata @@ -90,6 +91,7 @@ def _decode_size(what, desc): return base * pow(10, exponent) +@dns.immutable.immutable class LOC(dns.rdata.Rdata): """LOC record""" @@ -115,16 +117,16 @@ class LOC(dns.rdata.Rdata): latitude = float(latitude) if isinstance(latitude, float): latitude = _float_to_tuple(latitude) - object.__setattr__(self, 'latitude', dns.rdata._constify(latitude)) + self.latitude = self.as_value(dns.rdata._constify(latitude)) if isinstance(longitude, int): longitude = float(longitude) if isinstance(longitude, float): longitude = _float_to_tuple(longitude) - 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)) + self.longitude = self.as_value(dns.rdata._constify(longitude)) + self.altitude = self.as_value(float(altitude)) + self.size = self.as_value(float(size)) + self.horizontal_precision = self.as_value(float(hprec)) + self.vertical_precision = self.as_value(float(vprec)) def to_text(self, origin=None, relativize=True, **kw): if self.latitude[4] > 0: diff --git a/dns/rdtypes/ANY/MX.py b/dns/rdtypes/ANY/MX.py index 0a06494..a697ea4 100644 --- a/dns/rdtypes/ANY/MX.py +++ b/dns/rdtypes/ANY/MX.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.mxbase +import dns.immutable +@dns.immutable.immutable class MX(dns.rdtypes.mxbase.MXBase): """MX record""" diff --git a/dns/rdtypes/ANY/NINFO.py b/dns/rdtypes/ANY/NINFO.py index d4c8572..d53e967 100644 --- a/dns/rdtypes/ANY/NINFO.py +++ b/dns/rdtypes/ANY/NINFO.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.txtbase +import dns.immutable +@dns.immutable.immutable class NINFO(dns.rdtypes.txtbase.TXTBase): """NINFO record""" diff --git a/dns/rdtypes/ANY/NS.py b/dns/rdtypes/ANY/NS.py index f9fcf63..a0cc232 100644 --- a/dns/rdtypes/ANY/NS.py +++ b/dns/rdtypes/ANY/NS.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.nsbase +import dns.immutable +@dns.immutable.immutable class NS(dns.rdtypes.nsbase.NSBase): """NS record""" diff --git a/dns/rdtypes/ANY/NSEC.py b/dns/rdtypes/ANY/NSEC.py index 626d339..c7bde1c 100644 --- a/dns/rdtypes/ANY/NSEC.py +++ b/dns/rdtypes/ANY/NSEC.py @@ -16,16 +16,19 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.exception +import dns.immutable import dns.rdata import dns.rdatatype import dns.name import dns.rdtypes.util +@dns.immutable.immutable class Bitmap(dns.rdtypes.util.Bitmap): type_name = 'NSEC' +@dns.immutable.immutable class NSEC(dns.rdata.Rdata): """NSEC record""" @@ -34,8 +37,8 @@ class NSEC(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, next, windows): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'next', next) - object.__setattr__(self, 'windows', dns.rdata._constify(windows)) + self.next = self.as_value(next) + self.windows = self.as_value(dns.rdata._constify(windows)) def to_text(self, origin=None, relativize=True, **kw): next = self.next.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/ANY/NSEC3.py b/dns/rdtypes/ANY/NSEC3.py index 91471f0..8c9a66b 100644 --- a/dns/rdtypes/ANY/NSEC3.py +++ b/dns/rdtypes/ANY/NSEC3.py @@ -20,6 +20,7 @@ import binascii import struct import dns.exception +import dns.immutable import dns.rdata import dns.rdatatype import dns.rdtypes.util @@ -37,10 +38,12 @@ SHA1 = 1 OPTOUT = 1 +@dns.immutable.immutable class Bitmap(dns.rdtypes.util.Bitmap): type_name = 'NSEC3' +@dns.immutable.immutable class NSEC3(dns.rdata.Rdata): """NSEC3 record""" @@ -50,15 +53,15 @@ class NSEC3(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt, next, windows): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'algorithm', algorithm) - object.__setattr__(self, 'flags', flags) - object.__setattr__(self, 'iterations', iterations) + self.algorithm = self.as_value(algorithm) + self.flags = self.as_value(flags) + self.iterations = self.as_value(iterations) if isinstance(salt, str): - object.__setattr__(self, 'salt', salt.encode()) + self.salt = self.as_value(salt.encode()) else: - object.__setattr__(self, 'salt', salt) - object.__setattr__(self, 'next', next) - object.__setattr__(self, 'windows', dns.rdata._constify(windows)) + self.salt = self.as_value(salt) + self.next = self.as_value(next) + self.windows = self.as_value(dns.rdata._constify(windows)) def to_text(self, origin=None, relativize=True, **kw): next = base64.b32encode(self.next).translate( diff --git a/dns/rdtypes/ANY/NSEC3PARAM.py b/dns/rdtypes/ANY/NSEC3PARAM.py index 31ab8b7..d31116f 100644 --- a/dns/rdtypes/ANY/NSEC3PARAM.py +++ b/dns/rdtypes/ANY/NSEC3PARAM.py @@ -19,9 +19,11 @@ import struct import binascii import dns.exception +import dns.immutable import dns.rdata +@dns.immutable.immutable class NSEC3PARAM(dns.rdata.Rdata): """NSEC3PARAM record""" @@ -30,13 +32,13 @@ class NSEC3PARAM(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'algorithm', algorithm) - object.__setattr__(self, 'flags', flags) - object.__setattr__(self, 'iterations', iterations) + self.algorithm = self.as_value(algorithm) + self.flags = self.as_value(flags) + self.iterations = self.as_value(iterations) if isinstance(salt, str): - object.__setattr__(self, 'salt', salt.encode()) + self.salt = self.as_value(salt.encode()) else: - object.__setattr__(self, 'salt', salt) + self.salt = self.as_value(salt) def to_text(self, origin=None, relativize=True, **kw): if self.salt == b'': diff --git a/dns/rdtypes/ANY/OPENPGPKEY.py b/dns/rdtypes/ANY/OPENPGPKEY.py index f632132..44b6087 100644 --- a/dns/rdtypes/ANY/OPENPGPKEY.py +++ b/dns/rdtypes/ANY/OPENPGPKEY.py @@ -18,9 +18,11 @@ import base64 import dns.exception +import dns.immutable import dns.rdata import dns.tokenizer +@dns.immutable.immutable class OPENPGPKEY(dns.rdata.Rdata): """OPENPGPKEY record""" @@ -29,7 +31,7 @@ class OPENPGPKEY(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, key): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'key', key) + self.key = self.as_value(key) def to_text(self, origin=None, relativize=True, **kw): return dns.rdata._base64ify(self.key) diff --git a/dns/rdtypes/ANY/OPT.py b/dns/rdtypes/ANY/OPT.py index 5d86d82..d962689 100644 --- a/dns/rdtypes/ANY/OPT.py +++ b/dns/rdtypes/ANY/OPT.py @@ -18,6 +18,7 @@ import struct import dns.edns +import dns.immutable import dns.exception import dns.rdata @@ -25,6 +26,7 @@ import dns.rdata # We don't implement from_text, and that's ok. # pylint: disable=abstract-method +@dns.immutable.immutable class OPT(dns.rdata.Rdata): """OPT record""" @@ -43,7 +45,7 @@ class OPT(dns.rdata.Rdata): """ super().__init__(rdclass, rdtype) - object.__setattr__(self, 'options', dns.rdata._constify(options)) + self.options = self.as_value(dns.rdata._constify(options)) def _to_wire(self, file, compress=None, origin=None, canonicalize=False): for opt in self.options: diff --git a/dns/rdtypes/ANY/PTR.py b/dns/rdtypes/ANY/PTR.py index 20cd507..265bed0 100644 --- a/dns/rdtypes/ANY/PTR.py +++ b/dns/rdtypes/ANY/PTR.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.nsbase +import dns.immutable +@dns.immutable.immutable class PTR(dns.rdtypes.nsbase.NSBase): """PTR record""" diff --git a/dns/rdtypes/ANY/RP.py b/dns/rdtypes/ANY/RP.py index a6054da..d872727 100644 --- a/dns/rdtypes/ANY/RP.py +++ b/dns/rdtypes/ANY/RP.py @@ -16,10 +16,12 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.exception +import dns.immutable import dns.rdata import dns.name +@dns.immutable.immutable class RP(dns.rdata.Rdata): """RP record""" @@ -30,8 +32,8 @@ class RP(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, mbox, txt): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'mbox', mbox) - object.__setattr__(self, 'txt', txt) + self.mbox = self.as_value(mbox) + self.txt = self.as_value(txt) def to_text(self, origin=None, relativize=True, **kw): mbox = self.mbox.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/ANY/RRSIG.py b/dns/rdtypes/ANY/RRSIG.py index 2077d90..53cc55a 100644 --- a/dns/rdtypes/ANY/RRSIG.py +++ b/dns/rdtypes/ANY/RRSIG.py @@ -21,6 +21,7 @@ import struct import time import dns.dnssec +import dns.immutable import dns.exception import dns.rdata import dns.rdatatype @@ -50,6 +51,7 @@ def posixtime_to_sigtime(what): return time.strftime('%Y%m%d%H%M%S', time.gmtime(what)) +@dns.immutable.immutable class RRSIG(dns.rdata.Rdata): """RRSIG record""" @@ -62,15 +64,15 @@ class RRSIG(dns.rdata.Rdata): original_ttl, expiration, inception, key_tag, signer, 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) + self.type_covered = self.as_value(type_covered) + self.algorithm = self.as_value(algorithm) + self.labels = self.as_value(labels) + self.original_ttl = self.as_value(original_ttl) + self.expiration = self.as_value(expiration) + self.inception = self.as_value(inception) + self.key_tag = self.as_value(key_tag) + self.signer = self.as_value(signer) + self.signature = self.as_value(signature) def covers(self): return self.type_covered diff --git a/dns/rdtypes/ANY/RT.py b/dns/rdtypes/ANY/RT.py index d0feb79..8d9c6bd 100644 --- a/dns/rdtypes/ANY/RT.py +++ b/dns/rdtypes/ANY/RT.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.mxbase +import dns.immutable +@dns.immutable.immutable class RT(dns.rdtypes.mxbase.UncompressedDowncasingMX): """RT record""" diff --git a/dns/rdtypes/ANY/SOA.py b/dns/rdtypes/ANY/SOA.py index 32b0a86..e569384 100644 --- a/dns/rdtypes/ANY/SOA.py +++ b/dns/rdtypes/ANY/SOA.py @@ -18,10 +18,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.name +@dns.immutable.immutable class SOA(dns.rdata.Rdata): """SOA record""" @@ -34,13 +36,13 @@ class SOA(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry, expire, 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) + self.mname = self.as_value(mname) + self.rname = self.as_value(rname) + self.serial = self.as_value(serial) + self.refresh = self.as_value(refresh) + self.retry = self.as_value(retry) + self.expire = self.as_value(expire) + self.minimum = self.as_value(minimum) def to_text(self, origin=None, relativize=True, **kw): mname = self.mname.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/ANY/SPF.py b/dns/rdtypes/ANY/SPF.py index f1f6834..1190e0d 100644 --- a/dns/rdtypes/ANY/SPF.py +++ b/dns/rdtypes/ANY/SPF.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.txtbase +import dns.immutable +@dns.immutable.immutable class SPF(dns.rdtypes.txtbase.TXTBase): """SPF record""" diff --git a/dns/rdtypes/ANY/SSHFP.py b/dns/rdtypes/ANY/SSHFP.py index a3cc003..dd222b4 100644 --- a/dns/rdtypes/ANY/SSHFP.py +++ b/dns/rdtypes/ANY/SSHFP.py @@ -19,9 +19,11 @@ import struct import binascii import dns.rdata +import dns.immutable import dns.rdatatype +@dns.immutable.immutable class SSHFP(dns.rdata.Rdata): """SSHFP record""" @@ -33,9 +35,9 @@ class SSHFP(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, algorithm, fp_type, fingerprint): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'algorithm', algorithm) - object.__setattr__(self, 'fp_type', fp_type) - object.__setattr__(self, 'fingerprint', fingerprint) + self.algorithm = self.as_value(algorithm) + self.fp_type = self.as_value(fp_type) + self.fingerprint = self.as_value(fingerprint) def to_text(self, origin=None, relativize=True, **kw): return '%d %d %s' % (self.algorithm, diff --git a/dns/rdtypes/ANY/TKEY.py b/dns/rdtypes/ANY/TKEY.py index 70bac63..871578a 100644 --- a/dns/rdtypes/ANY/TKEY.py +++ b/dns/rdtypes/ANY/TKEY.py @@ -19,10 +19,12 @@ import base64 import struct import dns.dnssec +import dns.immutable import dns.exception import dns.rdata +@dns.immutable.immutable class TKEY(dns.rdata.Rdata): """TKEY Record""" @@ -33,13 +35,13 @@ class TKEY(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, algorithm, inception, expiration, mode, error, key, other=b''): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'algorithm', algorithm) - object.__setattr__(self, 'inception', inception) - object.__setattr__(self, 'expiration', expiration) - object.__setattr__(self, 'mode', mode) - object.__setattr__(self, 'error', error) - object.__setattr__(self, 'key', dns.rdata._constify(key)) - object.__setattr__(self, 'other', dns.rdata._constify(other)) + self.algorithm = self.as_value(algorithm) + self.inception = self.as_value(inception) + self.expiration = self.as_value(expiration) + self.mode = self.as_value(mode) + self.error = self.as_value(error) + self.key = self.as_value(dns.rdata._constify(key)) + self.other = self.as_value(dns.rdata._constify(other)) def to_text(self, origin=None, relativize=True, **kw): _algorithm = self.algorithm.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/ANY/TLSA.py b/dns/rdtypes/ANY/TLSA.py index 9c9c866..5e7dc19 100644 --- a/dns/rdtypes/ANY/TLSA.py +++ b/dns/rdtypes/ANY/TLSA.py @@ -19,9 +19,11 @@ import struct import binascii import dns.rdata +import dns.immutable import dns.rdatatype +@dns.immutable.immutable class TLSA(dns.rdata.Rdata): """TLSA record""" @@ -33,10 +35,10 @@ class TLSA(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, usage, selector, mtype, 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) + self.usage = self.as_value(usage) + self.selector = self.as_value(selector) + self.mtype = self.as_value(mtype) + self.cert = self.as_value(cert) def to_text(self, origin=None, relativize=True, **kw): return '%d %d %d %s' % (self.usage, diff --git a/dns/rdtypes/ANY/TSIG.py b/dns/rdtypes/ANY/TSIG.py index 85b80be..e179d62 100644 --- a/dns/rdtypes/ANY/TSIG.py +++ b/dns/rdtypes/ANY/TSIG.py @@ -19,9 +19,11 @@ import base64 import struct import dns.exception +import dns.immutable import dns.rdata +@dns.immutable.immutable class TSIG(dns.rdata.Rdata): """TSIG record""" @@ -53,13 +55,13 @@ class TSIG(dns.rdata.Rdata): """ super().__init__(rdclass, rdtype) - object.__setattr__(self, 'algorithm', algorithm) - object.__setattr__(self, 'time_signed', time_signed) - object.__setattr__(self, 'fudge', fudge) - object.__setattr__(self, 'mac', dns.rdata._constify(mac)) - object.__setattr__(self, 'original_id', original_id) - object.__setattr__(self, 'error', error) - object.__setattr__(self, 'other', dns.rdata._constify(other)) + self.algorithm = self.as_value(algorithm) + self.time_signed = self.as_value(time_signed) + self.fudge = self.as_value(fudge) + self.mac = self.as_value(dns.rdata._constify(mac)) + self.original_id = self.as_value(original_id) + self.error = self.as_value(error) + self.other = self.as_value(dns.rdata._constify(other)) def to_text(self, origin=None, relativize=True, **kw): algorithm = self.algorithm.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/ANY/TXT.py b/dns/rdtypes/ANY/TXT.py index c5ae919..cc4b661 100644 --- a/dns/rdtypes/ANY/TXT.py +++ b/dns/rdtypes/ANY/TXT.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.txtbase +import dns.immutable +@dns.immutable.immutable class TXT(dns.rdtypes.txtbase.TXTBase): """TXT record""" diff --git a/dns/rdtypes/ANY/URI.py b/dns/rdtypes/ANY/URI.py index 7d6d068..0892bd8 100644 --- a/dns/rdtypes/ANY/URI.py +++ b/dns/rdtypes/ANY/URI.py @@ -19,10 +19,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.name +@dns.immutable.immutable class URI(dns.rdata.Rdata): """URI record""" @@ -33,14 +35,14 @@ class URI(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, priority, weight, target): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'priority', priority) - object.__setattr__(self, 'weight', weight) + self.priority = self.as_value(priority) + self.weight = self.as_value(weight) if len(target) < 1: raise dns.exception.SyntaxError("URI target cannot be empty") if isinstance(target, str): - object.__setattr__(self, 'target', target.encode()) + self.target = self.as_value(target.encode()) else: - object.__setattr__(self, 'target', target) + self.target = self.as_value(target) def to_text(self, origin=None, relativize=True, **kw): return '%d %d "%s"' % (self.priority, self.weight, diff --git a/dns/rdtypes/ANY/X25.py b/dns/rdtypes/ANY/X25.py index 29b9c4d..ec25508 100644 --- a/dns/rdtypes/ANY/X25.py +++ b/dns/rdtypes/ANY/X25.py @@ -18,10 +18,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.tokenizer +@dns.immutable.immutable class X25(dns.rdata.Rdata): """X25 record""" @@ -33,9 +35,9 @@ class X25(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, address): super().__init__(rdclass, rdtype) if isinstance(address, str): - object.__setattr__(self, 'address', address.encode()) + self.address = self.as_value(address.encode()) else: - object.__setattr__(self, 'address', address) + self.address = self.as_value(address) def to_text(self, origin=None, relativize=True, **kw): return '"%s"' % dns.rdata._escapify(self.address) diff --git a/dns/rdtypes/CH/A.py b/dns/rdtypes/CH/A.py index 0cb89e2..6bc3afb 100644 --- a/dns/rdtypes/CH/A.py +++ b/dns/rdtypes/CH/A.py @@ -18,7 +18,9 @@ import struct import dns.rdtypes.mxbase +import dns.immutable +@dns.immutable.immutable class A(dns.rdata.Rdata): """A record for Chaosnet""" @@ -30,8 +32,8 @@ class A(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, domain, address): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'domain', domain) - object.__setattr__(self, 'address', address) + self.domain = self.as_value(domain) + self.address = self.as_value(address) def to_text(self, origin=None, relativize=True, **kw): domain = self.domain.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/IN/A.py b/dns/rdtypes/IN/A.py index 35ec46f..d5870cd 100644 --- a/dns/rdtypes/IN/A.py +++ b/dns/rdtypes/IN/A.py @@ -16,11 +16,13 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.exception +import dns.immutable import dns.ipv4 import dns.rdata import dns.tokenizer +@dns.immutable.immutable class A(dns.rdata.Rdata): """A record.""" @@ -31,7 +33,7 @@ class A(dns.rdata.Rdata): super().__init__(rdclass, rdtype) # check that it's OK dns.ipv4.inet_aton(address) - object.__setattr__(self, 'address', address) + self.address = self.as_value(address) def to_text(self, origin=None, relativize=True, **kw): return self.address diff --git a/dns/rdtypes/IN/AAAA.py b/dns/rdtypes/IN/AAAA.py index c37b82a..174b8a6 100644 --- a/dns/rdtypes/IN/AAAA.py +++ b/dns/rdtypes/IN/AAAA.py @@ -16,11 +16,13 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.exception +import dns.immutable import dns.ipv6 import dns.rdata import dns.tokenizer +@dns.immutable.immutable class AAAA(dns.rdata.Rdata): """AAAA record.""" @@ -31,7 +33,7 @@ class AAAA(dns.rdata.Rdata): super().__init__(rdclass, rdtype) # check that it's OK dns.ipv6.inet_aton(address) - object.__setattr__(self, 'address', address) + self.address = self.as_value(address) def to_text(self, origin=None, relativize=True, **kw): return self.address diff --git a/dns/rdtypes/IN/APL.py b/dns/rdtypes/IN/APL.py index 3b1b8d1..8c3f2ce 100644 --- a/dns/rdtypes/IN/APL.py +++ b/dns/rdtypes/IN/APL.py @@ -20,11 +20,13 @@ import codecs import struct import dns.exception +import dns.immutable import dns.ipv4 import dns.ipv6 import dns.rdata import dns.tokenizer +@dns.immutable.immutable class APLItem: """An APL list item.""" @@ -68,6 +70,7 @@ class APLItem: file.write(address) +@dns.immutable.immutable class APL(dns.rdata.Rdata): """APL record.""" @@ -78,7 +81,7 @@ class APL(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, items): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'items', dns.rdata._constify(items)) + self.items = self.as_value(dns.rdata._constify(items)) def to_text(self, origin=None, relativize=True, **kw): return ' '.join(map(str, self.items)) diff --git a/dns/rdtypes/IN/DHCID.py b/dns/rdtypes/IN/DHCID.py index 6f66eb8..d3620fe 100644 --- a/dns/rdtypes/IN/DHCID.py +++ b/dns/rdtypes/IN/DHCID.py @@ -18,8 +18,10 @@ import base64 import dns.exception +import dns.immutable +@dns.immutable.immutable class DHCID(dns.rdata.Rdata): """DHCID record""" @@ -30,7 +32,7 @@ class DHCID(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, data): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'data', data) + self.data = self.as_value(data) def to_text(self, origin=None, relativize=True, **kw): return dns.rdata._base64ify(self.data) diff --git a/dns/rdtypes/IN/HTTPS.py b/dns/rdtypes/IN/HTTPS.py index ad67897..6a67e8e 100644 --- a/dns/rdtypes/IN/HTTPS.py +++ b/dns/rdtypes/IN/HTTPS.py @@ -1,6 +1,8 @@ # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license import dns.rdtypes.svcbbase +import dns.immutable +@dns.immutable.immutable class HTTPS(dns.rdtypes.svcbbase.SVCBBase): """HTTPS record""" diff --git a/dns/rdtypes/IN/IPSECKEY.py b/dns/rdtypes/IN/IPSECKEY.py index 182ad2c..a18e40e 100644 --- a/dns/rdtypes/IN/IPSECKEY.py +++ b/dns/rdtypes/IN/IPSECKEY.py @@ -19,12 +19,14 @@ import struct import base64 import dns.exception +import dns.immutable import dns.rdtypes.util class Gateway(dns.rdtypes.util.Gateway): name = 'IPSECKEY gateway' +@dns.immutable.immutable class IPSECKEY(dns.rdata.Rdata): """IPSECKEY record""" @@ -37,11 +39,11 @@ class IPSECKEY(dns.rdata.Rdata): gateway, key): super().__init__(rdclass, rdtype) Gateway(gateway_type, gateway).check() - 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) + self.precedence = self.as_value(precedence) + self.gateway_type = self.as_value(gateway_type) + self.algorithm = self.as_value(algorithm) + self.gateway = self.as_value(gateway) + self.key = self.as_value(key) def to_text(self, origin=None, relativize=True, **kw): gateway = Gateway(self.gateway_type, self.gateway).to_text(origin, diff --git a/dns/rdtypes/IN/KX.py b/dns/rdtypes/IN/KX.py index ebf8fd7..c27e921 100644 --- a/dns/rdtypes/IN/KX.py +++ b/dns/rdtypes/IN/KX.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.mxbase +import dns.immutable +@dns.immutable.immutable class KX(dns.rdtypes.mxbase.UncompressedDowncasingMX): """KX record""" diff --git a/dns/rdtypes/IN/NAPTR.py b/dns/rdtypes/IN/NAPTR.py index f45262c..f496b3f 100644 --- a/dns/rdtypes/IN/NAPTR.py +++ b/dns/rdtypes/IN/NAPTR.py @@ -18,6 +18,7 @@ import struct import dns.exception +import dns.immutable import dns.name import dns.rdata @@ -35,6 +36,7 @@ def _sanitize(value): return value +@dns.immutable.immutable class NAPTR(dns.rdata.Rdata): """NAPTR record""" @@ -47,12 +49,12 @@ class NAPTR(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, order, preference, flags, service, regexp, 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) + self.flags = self.as_value(_sanitize(flags)) + self.service = self.as_value(_sanitize(service)) + self.regexp = self.as_value(_sanitize(regexp)) + self.order = self.as_value(order) + self.preference = self.as_value(preference) + self.replacement = self.as_value(replacement) def to_text(self, origin=None, relativize=True, **kw): replacement = self.replacement.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/IN/NSAP.py b/dns/rdtypes/IN/NSAP.py index 78730a1..76dd2f8 100644 --- a/dns/rdtypes/IN/NSAP.py +++ b/dns/rdtypes/IN/NSAP.py @@ -18,10 +18,12 @@ import binascii import dns.exception +import dns.immutable import dns.rdata import dns.tokenizer +@dns.immutable.immutable class NSAP(dns.rdata.Rdata): """NSAP record.""" @@ -32,7 +34,7 @@ class NSAP(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, address): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'address', address) + self.address = self.as_value(address) def to_text(self, origin=None, relativize=True, **kw): return "0x%s" % binascii.hexlify(self.address).decode() diff --git a/dns/rdtypes/IN/NSAP_PTR.py b/dns/rdtypes/IN/NSAP_PTR.py index a5b66c8..57dadd4 100644 --- a/dns/rdtypes/IN/NSAP_PTR.py +++ b/dns/rdtypes/IN/NSAP_PTR.py @@ -16,8 +16,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import dns.rdtypes.nsbase +import dns.immutable +@dns.immutable.immutable class NSAP_PTR(dns.rdtypes.nsbase.UncompressedNS): """NSAP-PTR record""" diff --git a/dns/rdtypes/IN/PX.py b/dns/rdtypes/IN/PX.py index 288bb12..9e7d24d 100644 --- a/dns/rdtypes/IN/PX.py +++ b/dns/rdtypes/IN/PX.py @@ -18,10 +18,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.name +@dns.immutable.immutable class PX(dns.rdata.Rdata): """PX record.""" @@ -32,9 +34,9 @@ class PX(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, preference, map822, mapx400): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'preference', preference) - object.__setattr__(self, 'map822', map822) - object.__setattr__(self, 'mapx400', mapx400) + self.preference = self.as_value(preference) + self.map822 = self.as_value(map822) + self.mapx400 = self.as_value(mapx400) def to_text(self, origin=None, relativize=True, **kw): map822 = self.map822.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/IN/SRV.py b/dns/rdtypes/IN/SRV.py index a3debab..c3c3b99 100644 --- a/dns/rdtypes/IN/SRV.py +++ b/dns/rdtypes/IN/SRV.py @@ -18,10 +18,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.name +@dns.immutable.immutable class SRV(dns.rdata.Rdata): """SRV record""" @@ -32,10 +34,10 @@ class SRV(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, priority, weight, port, 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) + self.priority = self.as_value(priority) + self.weight = self.as_value(weight) + self.port = self.as_value(port) + self.target = self.as_value(target) def to_text(self, origin=None, relativize=True, **kw): target = self.target.choose_relativity(origin, relativize) diff --git a/dns/rdtypes/IN/SVCB.py b/dns/rdtypes/IN/SVCB.py index 8effeb8..14838e1 100644 --- a/dns/rdtypes/IN/SVCB.py +++ b/dns/rdtypes/IN/SVCB.py @@ -1,6 +1,8 @@ # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license import dns.rdtypes.svcbbase +import dns.immutable +@dns.immutable.immutable class SVCB(dns.rdtypes.svcbbase.SVCBBase): """SVCB record""" diff --git a/dns/rdtypes/IN/WKS.py b/dns/rdtypes/IN/WKS.py index 75444fb..ba42283 100644 --- a/dns/rdtypes/IN/WKS.py +++ b/dns/rdtypes/IN/WKS.py @@ -19,12 +19,14 @@ import socket import struct import dns.ipv4 +import dns.immutable import dns.rdata _proto_tcp = socket.getprotobyname('tcp') _proto_udp = socket.getprotobyname('udp') +@dns.immutable.immutable class WKS(dns.rdata.Rdata): """WKS record""" @@ -35,9 +37,9 @@ class WKS(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, address, protocol, bitmap): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'address', address) - object.__setattr__(self, 'protocol', protocol) - object.__setattr__(self, 'bitmap', dns.rdata._constify(bitmap)) + self.address = self.as_value(address) + self.protocol = self.as_value(protocol) + self.bitmap = self.as_value(dns.rdata._constify(bitmap)) def to_text(self, origin=None, relativize=True, **kw): bits = [] diff --git a/dns/rdtypes/dnskeybase.py b/dns/rdtypes/dnskeybase.py index 935ebeb..6686f8d 100644 --- a/dns/rdtypes/dnskeybase.py +++ b/dns/rdtypes/dnskeybase.py @@ -20,6 +20,7 @@ import enum import struct import dns.exception +import dns.immutable import dns.dnssec import dns.rdata @@ -32,6 +33,7 @@ class Flag(enum.IntFlag): ZONE = 0x0100 +@dns.immutable.immutable class DNSKEYBase(dns.rdata.Rdata): """Base class for rdata that is like a DNSKEY record""" @@ -40,10 +42,10 @@ class DNSKEYBase(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, flags, protocol, algorithm, 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) + self.flags = self.as_value(flags) + self.protocol = self.as_value(protocol) + self.algorithm = self.as_value(algorithm) + self.key = self.as_value(key) def to_text(self, origin=None, relativize=True, **kw): return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm, diff --git a/dns/rdtypes/dsbase.py b/dns/rdtypes/dsbase.py index d7850be..baa9e87 100644 --- a/dns/rdtypes/dsbase.py +++ b/dns/rdtypes/dsbase.py @@ -19,10 +19,12 @@ import struct import binascii import dns.dnssec +import dns.immutable import dns.rdata import dns.rdatatype +@dns.immutable.immutable class DSBase(dns.rdata.Rdata): """Base class for rdata that is like a DS record""" @@ -32,10 +34,10 @@ class DSBase(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type, 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) + self.key_tag = self.as_value(key_tag) + self.algorithm = self.as_value(algorithm) + self.digest_type = self.as_value(digest_type) + self.digest = self.as_value(digest) def to_text(self, origin=None, relativize=True, **kw): return '%d %d %d %s' % (self.key_tag, self.algorithm, diff --git a/dns/rdtypes/euibase.py b/dns/rdtypes/euibase.py index ba44571..d71e5c2 100644 --- a/dns/rdtypes/euibase.py +++ b/dns/rdtypes/euibase.py @@ -17,8 +17,10 @@ import binascii import dns.rdata +import dns.immutable +@dns.immutable.immutable class EUIBase(dns.rdata.Rdata): """EUIxx record""" @@ -35,7 +37,7 @@ class EUIBase(dns.rdata.Rdata): 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)) - object.__setattr__(self, 'eui', eui) + self.eui = self.as_value(eui) def to_text(self, origin=None, relativize=True, **kw): return dns.rdata._hexify(self.eui, chunksize=2).replace(' ', '-') diff --git a/dns/rdtypes/mxbase.py b/dns/rdtypes/mxbase.py index 723b762..525a717 100644 --- a/dns/rdtypes/mxbase.py +++ b/dns/rdtypes/mxbase.py @@ -20,10 +20,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.name +@dns.immutable.immutable class MXBase(dns.rdata.Rdata): """Base class for rdata that is like an MX record.""" @@ -32,8 +34,8 @@ class MXBase(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, preference, exchange): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'preference', preference) - object.__setattr__(self, 'exchange', exchange) + self.preference = self.as_value(preference) + self.exchange = self.as_value(exchange) def to_text(self, origin=None, relativize=True, **kw): exchange = self.exchange.choose_relativity(origin, relativize) @@ -58,6 +60,7 @@ class MXBase(dns.rdata.Rdata): return cls(rdclass, rdtype, preference, exchange) +@dns.immutable.immutable class UncompressedMX(MXBase): """Base class for rdata that is like an MX record, but whose name @@ -68,6 +71,7 @@ class UncompressedMX(MXBase): super()._to_wire(file, None, origin, False) +@dns.immutable.immutable class UncompressedDowncasingMX(MXBase): """Base class for rdata that is like an MX record, but whose name diff --git a/dns/rdtypes/nsbase.py b/dns/rdtypes/nsbase.py index 212f8c0..e4d9ac5 100644 --- a/dns/rdtypes/nsbase.py +++ b/dns/rdtypes/nsbase.py @@ -18,10 +18,12 @@ """NS-like base classes.""" import dns.exception +import dns.immutable import dns.rdata import dns.name +@dns.immutable.immutable class NSBase(dns.rdata.Rdata): """Base class for rdata that is like an NS record.""" @@ -30,7 +32,7 @@ class NSBase(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, target): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'target', target) + self.target = self.as_value(target) def to_text(self, origin=None, relativize=True, **kw): target = self.target.choose_relativity(origin, relativize) @@ -51,6 +53,7 @@ class NSBase(dns.rdata.Rdata): return cls(rdclass, rdtype, target) +@dns.immutable.immutable class UncompressedNS(NSBase): """Base class for rdata that is like an NS record, but whose name diff --git a/dns/rdtypes/svcbbase.py b/dns/rdtypes/svcbbase.py index 9bb8354..6dcb1c6 100644 --- a/dns/rdtypes/svcbbase.py +++ b/dns/rdtypes/svcbbase.py @@ -6,6 +6,7 @@ import io import struct import dns.enum +import dns.immutable import dns.exception import dns.immutable import dns.ipv4 @@ -141,26 +142,26 @@ def _unescape(value, list_mode=False): return items[0] +@dns.immutable.immutable class Param: """Abstract base class for SVCB parameters""" - def __setattr__(self, name, value): - # Params are immutable - raise TypeError("object doesn't support attribute assignment") - - def __delattr__(self, name): - # Params are immutable - raise TypeError("object doesn't support attribute deletion") - @classmethod def emptiness(cls): return Emptiness.NEVER + def as_value(self, value): + # This is the "additional type checking" placeholder that actually + # doesn't do any additional checking. + return value + + +@dns.immutable.immutable class GenericParam(Param): """Generic SVCB parameter """ def __init__(self, value): - object.__setattr__(self, 'value', value) + self.value = self.as_value(value) @classmethod def emptiness(cls): @@ -188,6 +189,7 @@ class GenericParam(Param): file.write(self.value) +@dns.immutable.immutable class MandatoryParam(Param): def __init__(self, keys): # check for duplicates @@ -200,7 +202,7 @@ class MandatoryParam(Param): if k == ParamKey.MANDATORY: raise ValueError('listed the mandatory key as mandatory') keys = dns.immutable.constify(keys) - object.__setattr__(self, 'keys', keys) + self.keys = self.as_value(keys) @classmethod def from_value(cls, value): @@ -226,6 +228,8 @@ class MandatoryParam(Param): for key in self.keys: file.write(struct.pack('!H', key)) + +@dns.immutable.immutable class ALPNParam(Param): def __init__(self, ids): for id in ids: @@ -233,7 +237,7 @@ class ALPNParam(Param): raise dns.exception.FormError('empty ALPN') if len(id) > 255: raise ValueError('ALPN id too long') - object.__setattr__(self, 'ids', dns.immutable.constify(ids)) + self.ids = self.as_value(dns.immutable.constify(ids)) @classmethod def from_value(cls, value): @@ -255,6 +259,8 @@ class ALPNParam(Param): file.write(struct.pack('!B', len(id))) file.write(id) + +@dns.immutable.immutable class NoDefaultALPNParam(Param): # We don't ever expect to instantiate this class, but we need # a from_value() and a from_wire_parser(), so we just return None @@ -284,11 +290,12 @@ class NoDefaultALPNParam(Param): raise NotImplementedError # pragma: no cover +@dns.immutable.immutable class PortParam(Param): def __init__(self, port): if port < 0 or port > 65535: raise ValueError('port out-of-range') - object.__setattr__(self, 'port', port) + self.port = self.as_value(port) @classmethod def from_value(cls, value): @@ -307,12 +314,13 @@ class PortParam(Param): file.write(struct.pack('!H', self.port)) +@dns.immutable.immutable class IPv4HintParam(Param): def __init__(self, addresses): for address in addresses: # check validity dns.ipv4.inet_aton(address) - object.__setattr__(self, 'addresses', dns.immutable.constify(addresses)) + self.addresses = self.as_value(dns.immutable.constify(addresses)) @classmethod def from_value(cls, value): @@ -335,12 +343,13 @@ class IPv4HintParam(Param): file.write(dns.ipv4.inet_aton(address)) +@dns.immutable.immutable class IPv6HintParam(Param): def __init__(self, addresses): for address in addresses: # check validity dns.ipv6.inet_aton(address) - object.__setattr__(self, 'addresses', dns.immutable.constify(addresses)) + self.addresses = self.as_value(dns.immutable.constify(addresses)) @classmethod def from_value(cls, value): @@ -363,9 +372,10 @@ class IPv6HintParam(Param): file.write(dns.ipv6.inet_aton(address)) +@dns.immutable.immutable class ECHConfigParam(Param): def __init__(self, echconfig): - object.__setattr__(self, 'echconfig', echconfig) + self.echconfig = self.as_value(echconfig) @classmethod def from_value(cls, value): @@ -416,6 +426,7 @@ def _validate_and_define(params, key, value): params[key] = value +@dns.immutable.immutable class SVCBBase(dns.rdata.Rdata): """Base class for SVCB-like records""" @@ -426,9 +437,9 @@ class SVCBBase(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, priority, target, params): super().__init__(rdclass, rdtype) - object.__setattr__(self, 'priority', priority) - object.__setattr__(self, 'target', target) - object.__setattr__(self, 'params', dns.immutable.constify(params)) + self.priority = self.as_value(priority) + self.target = self.as_value(target) + self.params = self.as_value(dns.immutable.constify(params)) # Make sure any paramater listed as mandatory is present in the # record. mandatory = params.get(ParamKey.MANDATORY) diff --git a/dns/rdtypes/txtbase.py b/dns/rdtypes/txtbase.py index 6d0b6ab..6539c5a 100644 --- a/dns/rdtypes/txtbase.py +++ b/dns/rdtypes/txtbase.py @@ -20,10 +20,12 @@ import struct import dns.exception +import dns.immutable import dns.rdata import dns.tokenizer +@dns.immutable.immutable class TXTBase(dns.rdata.Rdata): """Base class for rdata that is like a TXT record (see RFC 1035).""" @@ -49,7 +51,7 @@ class TXTBase(dns.rdata.Rdata): else: string = dns.rdata._constify(string) encoded_strings.append(string) - object.__setattr__(self, 'strings', tuple(encoded_strings)) + self.strings = self.as_value(tuple(encoded_strings)) def to_text(self, origin=None, relativize=True, **kw): txt = '' |
