From bee23ec15fdde8f0303b0a3699669599c5abf8cb Mon Sep 17 00:00:00 2001 From: Bob Halley Date: Wed, 19 Aug 2020 05:30:30 -0700 Subject: make name and rdata use the immutable decorator --- dns/name.py | 12 +++-------- dns/rdata.py | 20 +++++++++--------- dns/rdtypes/ANY/AFSDB.py | 2 ++ dns/rdtypes/ANY/AMTRELAY.py | 10 +++++---- dns/rdtypes/ANY/AVC.py | 2 ++ dns/rdtypes/ANY/CAA.py | 8 +++++--- dns/rdtypes/ANY/CDNSKEY.py | 2 ++ dns/rdtypes/ANY/CDS.py | 2 ++ dns/rdtypes/ANY/CERT.py | 10 +++++---- dns/rdtypes/ANY/CNAME.py | 2 ++ dns/rdtypes/ANY/CSYNC.py | 9 ++++++--- dns/rdtypes/ANY/DLV.py | 2 ++ dns/rdtypes/ANY/DNAME.py | 2 ++ dns/rdtypes/ANY/DNSKEY.py | 2 ++ dns/rdtypes/ANY/DS.py | 2 ++ dns/rdtypes/ANY/EUI48.py | 2 ++ dns/rdtypes/ANY/EUI64.py | 2 ++ dns/rdtypes/ANY/GPOS.py | 8 +++++--- dns/rdtypes/ANY/HINFO.py | 10 +++++---- dns/rdtypes/ANY/HIP.py | 10 +++++---- dns/rdtypes/ANY/ISDN.py | 10 +++++---- dns/rdtypes/ANY/LOC.py | 14 +++++++------ dns/rdtypes/ANY/MX.py | 2 ++ dns/rdtypes/ANY/NINFO.py | 2 ++ dns/rdtypes/ANY/NS.py | 2 ++ dns/rdtypes/ANY/NSEC.py | 7 +++++-- dns/rdtypes/ANY/NSEC3.py | 17 +++++++++------- dns/rdtypes/ANY/NSEC3PARAM.py | 12 ++++++----- dns/rdtypes/ANY/OPENPGPKEY.py | 4 +++- dns/rdtypes/ANY/OPT.py | 4 +++- dns/rdtypes/ANY/PTR.py | 2 ++ dns/rdtypes/ANY/RP.py | 6 ++++-- dns/rdtypes/ANY/RRSIG.py | 20 +++++++++--------- dns/rdtypes/ANY/RT.py | 2 ++ dns/rdtypes/ANY/SOA.py | 16 ++++++++------- dns/rdtypes/ANY/SPF.py | 2 ++ dns/rdtypes/ANY/SSHFP.py | 8 +++++--- dns/rdtypes/ANY/TKEY.py | 16 ++++++++------- dns/rdtypes/ANY/TLSA.py | 10 +++++---- dns/rdtypes/ANY/TSIG.py | 16 ++++++++------- dns/rdtypes/ANY/TXT.py | 2 ++ dns/rdtypes/ANY/URI.py | 10 +++++---- dns/rdtypes/ANY/X25.py | 6 ++++-- dns/rdtypes/CH/A.py | 6 ++++-- dns/rdtypes/IN/A.py | 4 +++- dns/rdtypes/IN/AAAA.py | 4 +++- dns/rdtypes/IN/APL.py | 5 ++++- dns/rdtypes/IN/DHCID.py | 4 +++- dns/rdtypes/IN/HTTPS.py | 2 ++ dns/rdtypes/IN/IPSECKEY.py | 12 ++++++----- dns/rdtypes/IN/KX.py | 2 ++ dns/rdtypes/IN/NAPTR.py | 14 +++++++------ dns/rdtypes/IN/NSAP.py | 4 +++- dns/rdtypes/IN/NSAP_PTR.py | 2 ++ dns/rdtypes/IN/PX.py | 8 +++++--- dns/rdtypes/IN/SRV.py | 10 +++++---- dns/rdtypes/IN/SVCB.py | 2 ++ dns/rdtypes/IN/WKS.py | 8 +++++--- dns/rdtypes/dnskeybase.py | 10 +++++---- dns/rdtypes/dsbase.py | 10 +++++---- dns/rdtypes/euibase.py | 4 +++- dns/rdtypes/mxbase.py | 8 ++++++-- dns/rdtypes/nsbase.py | 5 ++++- dns/rdtypes/svcbbase.py | 47 ++++++++++++++++++++++++++----------------- dns/rdtypes/txtbase.py | 4 +++- 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 = '' -- cgit v1.2.1