# 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)
return what[0: i + 1]
return what[0:1]
+def _constify(o):
+ """
+ Convert mutable types to immutable types.
+ """
+ if type(o) == bytearray:
+ return bytes(o)
+ if type(o) == tuple:
+ try:
+ hash(o)
+ return o
+ except:
+ return tuple(_constify(elt) for elt in o)
+ if type(o) == list:
+ return tuple(_constify(elt) for elt in o)
+ return o
class Rdata(object):
"""Base class for all DNS rdata types."""
*rdtype*, an ``int`` is the rdatatype of the Rdata.
"""
- self.rdclass = rdclass
- self.rdtype = rdtype
+ object.__setattr__(self, 'rdclass', rdclass)
+ object.__setattr__(self, 'rdtype', rdtype)
+
+ def __setattr__(self, name, value):
+ # Rdatas are immutable
+ raise TypeError("object doesn't support attribute assignment")
+
+ def __delattr__(self, name):
+ # Rdatas are immutable
+ raise TypeError("object doesn't support attribute deletion")
def covers(self):
"""Return the type a Rdata covers.
def __init__(self, rdclass, rdtype, data):
super(GenericRdata, self).__init__(rdclass, rdtype)
- self.data = data
+ object.__setattr__(self, 'data', data)
def to_text(self, origin=None, relativize=True, **kw):
return r'\# %d ' % len(self.data) + _hexify(self.data)
__slots__ = ['flags', 'tag', 'value']
def __init__(self, rdclass, rdtype, flags, tag, value):
- super(CAA, self).__init__(rdclass, rdtype)
- self.flags = flags
- self.tag = tag
- self.value = value
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'flags', flags)
+ object.__setattr__(self, 'tag', tag)
+ object.__setattr__(self, 'value', value)
def to_text(self, origin=None, relativize=True, **kw):
return '%u %s "%s"' % (self.flags,
def __init__(self, rdclass, rdtype, certificate_type, key_tag, algorithm,
certificate):
- super(CERT, self).__init__(rdclass, rdtype)
- self.certificate_type = certificate_type
- self.key_tag = key_tag
- self.algorithm = algorithm
- self.certificate = certificate
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'certificate_type', certificate_type)
+ object.__setattr__(self, 'key_tag', key_tag)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'certificate', certificate)
def to_text(self, origin=None, relativize=True, **kw):
certificate_type = _ctype_to_text(self.certificate_type)
__slots__ = ['serial', 'flags', 'windows']
def __init__(self, rdclass, rdtype, serial, flags, windows):
- super(CSYNC, self).__init__(rdclass, rdtype)
- self.serial = serial
- self.flags = flags
- self.windows = windows
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'serial', serial)
+ object.__setattr__(self, 'flags', flags)
+ object.__setattr__(self, 'windows', dns.rdata._constify(windows))
def to_text(self, origin=None, relativize=True, **kw):
text = ''
__slots__ = ['latitude', 'longitude', 'altitude']
def __init__(self, rdclass, rdtype, latitude, longitude, altitude):
- super(GPOS, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
if isinstance(latitude, float) or \
isinstance(latitude, int):
latitude = str(latitude)
_validate_float_string(latitude)
_validate_float_string(longitude)
_validate_float_string(altitude)
- self.latitude = latitude
- self.longitude = longitude
- self.altitude = altitude
+ object.__setattr__(self, 'latitude', latitude)
+ object.__setattr__(self, 'longitude', longitude)
+ object.__setattr__(self, 'altitude', altitude)
def to_text(self, origin=None, relativize=True, **kw):
return '{} {} {}'.format(self.latitude.decode(),
__slots__ = ['cpu', 'os']
def __init__(self, rdclass, rdtype, cpu, os):
- super(HINFO, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
if isinstance(cpu, str):
- self.cpu = cpu.encode()
+ object.__setattr__(self, 'cpu', cpu.encode())
else:
- self.cpu = cpu
+ object.__setattr__(self, 'cpu', cpu)
if isinstance(os, str):
- self.os = os.encode()
+ object.__setattr__(self, 'os', os.encode())
else:
- self.os = os
+ object.__setattr__(self, 'os', os)
def to_text(self, origin=None, relativize=True, **kw):
return '"{}" "{}"'.format(dns.rdata._escapify(self.cpu),
__slots__ = ['hit', 'algorithm', 'key', 'servers']
def __init__(self, rdclass, rdtype, hit, algorithm, key, servers):
- super(HIP, self).__init__(rdclass, rdtype)
- self.hit = hit
- self.algorithm = algorithm
- self.key = key
- self.servers = servers
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'hit', hit)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'key', key)
+ object.__setattr__(self, 'servers', dns.rdata._constify(servers))
def to_text(self, origin=None, relativize=True, **kw):
hit = binascii.hexlify(self.hit).decode()
__slots__ = ['address', 'subaddress']
def __init__(self, rdclass, rdtype, address, subaddress):
- super(ISDN, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
if isinstance(address, str):
- self.address = address.encode()
+ object.__setattr__(self, 'address', address.encode())
else:
- self.address = address
+ object.__setattr__(self, 'address', address)
if isinstance(address, str):
- self.subaddress = subaddress.encode()
+ object.__setattr__(self, 'subaddress', subaddress.encode())
else:
- self.subaddress = subaddress
+ object.__setattr__(self, 'subaddress', subaddress)
def to_text(self, origin=None, relativize=True, **kw):
if self.subaddress:
degrees. The other parameters are floats. Size, horizontal precision,
and vertical precision are specified in centimeters."""
- super(LOC, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
if isinstance(latitude, int):
latitude = float(latitude)
if isinstance(latitude, float):
latitude = _float_to_tuple(latitude)
- self.latitude = latitude
+ object.__setattr__(self, 'latitude', dns.rdata._constify(latitude))
if isinstance(longitude, int):
longitude = float(longitude)
if isinstance(longitude, float):
longitude = _float_to_tuple(longitude)
- self.longitude = longitude
- self.altitude = float(altitude)
- self.size = float(size)
- self.horizontal_precision = float(hprec)
- self.vertical_precision = float(vprec)
+ object.__setattr__(self, 'longitude', dns.rdata._constify(longitude))
+ object.__setattr__(self, 'altitude', float(altitude))
+ object.__setattr__(self, 'size', float(size))
+ object.__setattr__(self, 'horizontal_precision', float(hprec))
+ object.__setattr__(self, 'vertical_precision', float(vprec))
def to_text(self, origin=None, relativize=True, **kw):
if self.latitude[4] > 0:
__slots__ = ['next', 'windows']
def __init__(self, rdclass, rdtype, next, windows):
- super(NSEC, self).__init__(rdclass, rdtype)
- self.next = next
- self.windows = windows
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'next', next)
+ object.__setattr__(self, 'windows', dns.rdata._constify(windows))
def to_text(self, origin=None, relativize=True, **kw):
next = self.next.choose_relativity(origin, relativize)
def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt,
next, windows):
- super(NSEC3, self).__init__(rdclass, rdtype)
- self.algorithm = algorithm
- self.flags = flags
- self.iterations = iterations
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'flags', flags)
+ object.__setattr__(self, 'iterations', iterations)
if isinstance(salt, str):
- self.salt = salt.encode()
+ object.__setattr__(self, 'salt', salt.encode())
else:
- self.salt = salt
- self.next = next
- self.windows = windows
+ object.__setattr__(self, 'salt', salt)
+ object.__setattr__(self, 'next', next)
+ object.__setattr__(self, 'windows', dns.rdata._constify(windows))
def to_text(self, origin=None, relativize=True, **kw):
next = base64.b32encode(self.next).translate(
__slots__ = ['algorithm', 'flags', 'iterations', 'salt']
def __init__(self, rdclass, rdtype, algorithm, flags, iterations, salt):
- super(NSEC3PARAM, self).__init__(rdclass, rdtype)
- self.algorithm = algorithm
- self.flags = flags
- self.iterations = iterations
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'flags', flags)
+ object.__setattr__(self, 'iterations', iterations)
if isinstance(salt, str):
- self.salt = salt.encode()
+ object.__setattr__(self, 'salt', salt.encode())
else:
- self.salt = salt
+ object.__setattr__(self, 'salt', salt)
def to_text(self, origin=None, relativize=True, **kw):
if self.salt == b'':
"""
def __init__(self, rdclass, rdtype, key):
- super(OPENPGPKEY, self).__init__(rdclass, rdtype)
- self.key = key
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'key', key)
def to_text(self, origin=None, relativize=True, **kw):
return dns.rdata._base64ify(self.key)
def __init__(self, rdclass, rdtype, mbox, txt):
super(RP, self).__init__(rdclass, rdtype)
- self.mbox = mbox
- self.txt = txt
+ object.__setattr__(self, 'mbox', mbox)
+ object.__setattr__(self, 'txt', txt)
def to_text(self, origin=None, relativize=True, **kw):
mbox = self.mbox.choose_relativity(origin, relativize)
def __init__(self, rdclass, rdtype, type_covered, algorithm, labels,
original_ttl, expiration, inception, key_tag, signer,
signature):
- super(RRSIG, self).__init__(rdclass, rdtype)
- self.type_covered = type_covered
- self.algorithm = algorithm
- self.labels = labels
- self.original_ttl = original_ttl
- self.expiration = expiration
- self.inception = inception
- self.key_tag = key_tag
- self.signer = signer
- self.signature = signature
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'type_covered', type_covered)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'labels', labels)
+ object.__setattr__(self, 'original_ttl', original_ttl)
+ object.__setattr__(self, 'expiration', expiration)
+ object.__setattr__(self, 'inception', inception)
+ object.__setattr__(self, 'key_tag', key_tag)
+ object.__setattr__(self, 'signer', signer)
+ object.__setattr__(self, 'signature', signature)
def covers(self):
return self.type_covered
def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry,
expire, minimum):
- super(SOA, self).__init__(rdclass, rdtype)
- self.mname = mname
- self.rname = rname
- self.serial = serial
- self.refresh = refresh
- self.retry = retry
- self.expire = expire
- self.minimum = minimum
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'mname', mname)
+ object.__setattr__(self, 'rname', rname)
+ object.__setattr__(self, 'serial', serial)
+ object.__setattr__(self, 'refresh', refresh)
+ object.__setattr__(self, 'retry', retry)
+ object.__setattr__(self, 'expire', expire)
+ object.__setattr__(self, 'minimum', minimum)
def to_text(self, origin=None, relativize=True, **kw):
mname = self.mname.choose_relativity(origin, relativize)
def __init__(self, rdclass, rdtype, algorithm, fp_type,
fingerprint):
- super(SSHFP, self).__init__(rdclass, rdtype)
- self.algorithm = algorithm
- self.fp_type = fp_type
- self.fingerprint = fingerprint
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'fp_type', fp_type)
+ object.__setattr__(self, 'fingerprint', fingerprint)
def to_text(self, origin=None, relativize=True, **kw):
return '%d %d %s' % (self.algorithm,
def __init__(self, rdclass, rdtype, usage, selector,
mtype, cert):
- super(TLSA, self).__init__(rdclass, rdtype)
- self.usage = usage
- self.selector = selector
- self.mtype = mtype
- self.cert = cert
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'usage', usage)
+ object.__setattr__(self, 'selector', selector)
+ object.__setattr__(self, 'mtype', mtype)
+ object.__setattr__(self, 'cert', cert)
def to_text(self, origin=None, relativize=True, **kw):
return '%d %d %d %s' % (self.usage,
__slots__ = ['priority', 'weight', 'target']
def __init__(self, rdclass, rdtype, priority, weight, target):
- super(URI, self).__init__(rdclass, rdtype)
- self.priority = priority
- self.weight = weight
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'priority', priority)
+ object.__setattr__(self, 'weight', weight)
if len(target) < 1:
raise dns.exception.SyntaxError("URI target cannot be empty")
if isinstance(target, str):
- self.target = target.encode()
+ object.__setattr__(self, 'target', target.encode())
else:
- self.target = target
+ object.__setattr__(self, 'target', target)
def to_text(self, origin=None, relativize=True, **kw):
return '%d %d "%s"' % (self.priority, self.weight,
__slots__ = ['address']
def __init__(self, rdclass, rdtype, address):
- super(X25, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
if isinstance(address, str):
- self.address = address.encode()
+ object.__setattr__(self, 'address', address.encode())
else:
- self.address = address
+ object.__setattr__(self, 'address', address)
def to_text(self, origin=None, relativize=True, **kw):
return '"%s"' % dns.rdata._escapify(self.address)
def __init__(self, rdclass, rdtype, address, domain):
super(A, self).__init__(rdclass, rdtype, address, domain)
- self.domain = domain
- self.address = address
+ object.__setattr__(self, 'domain', domain)
+ object.__setattr__(self, 'address', address)
def to_text(self, origin=None, relativize=True, **kw):
domain = self.domain.choose_relativity(origin, relativize)
__slots__ = ['address']
def __init__(self, rdclass, rdtype, address):
- super(A, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
# check that it's OK
dns.ipv4.inet_aton(address)
- self.address = address
+ object.__setattr__(self, 'address', address)
def to_text(self, origin=None, relativize=True, **kw):
return self.address
__slots__ = ['address']
def __init__(self, rdclass, rdtype, address):
- super(AAAA, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
# check that it's OK
dns.inet.inet_pton(dns.inet.AF_INET6, address)
- self.address = address
+ object.__setattr__(self, 'address', address)
def to_text(self, origin=None, relativize=True, **kw):
return self.address
__slots__ = ['items']
def __init__(self, rdclass, rdtype, items):
- super(APL, self).__init__(rdclass, rdtype)
- self.items = items
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'items', dns.rdata._constify(items))
def to_text(self, origin=None, relativize=True, **kw):
return ' '.join(map(str, self.items))
__slots__ = ['data']
def __init__(self, rdclass, rdtype, data):
- super(DHCID, self).__init__(rdclass, rdtype)
- self.data = data
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'data', data)
def to_text(self, origin=None, relativize=True, **kw):
return dns.rdata._base64ify(self.data)
def __init__(self, rdclass, rdtype, precedence, gateway_type, algorithm,
gateway, key):
- super(IPSECKEY, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
if gateway_type == 0:
if gateway != '.' and gateway is not None:
raise SyntaxError('invalid gateway for gateway type 0')
else:
raise SyntaxError(
'invalid IPSECKEY gateway type: %d' % gateway_type)
- self.precedence = precedence
- self.gateway_type = gateway_type
- self.algorithm = algorithm
- self.gateway = gateway
- self.key = key
+ object.__setattr__(self, 'precedence', precedence)
+ object.__setattr__(self, 'gateway_type', gateway_type)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'gateway', gateway)
+ object.__setattr__(self, 'key', key)
def to_text(self, origin=None, relativize=True, **kw):
if self.gateway_type == 0:
def __init__(self, rdclass, rdtype, order, preference, flags, service,
regexp, replacement):
- super(NAPTR, self).__init__(rdclass, rdtype)
- self.flags = _sanitize(flags)
- self.service = _sanitize(service)
- self.regexp = _sanitize(regexp)
- self.order = order
- self.preference = preference
- self.replacement = replacement
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'flags', _sanitize(flags))
+ object.__setattr__(self, 'service', _sanitize(service))
+ object.__setattr__(self, 'regexp', _sanitize(regexp))
+ object.__setattr__(self, 'order', order)
+ object.__setattr__(self, 'preference', preference)
+ object.__setattr__(self, 'replacement', replacement)
def to_text(self, origin=None, relativize=True, **kw):
replacement = self.replacement.choose_relativity(origin, relativize)
__slots__ = ['address']
def __init__(self, rdclass, rdtype, address):
- super(NSAP, self).__init__(rdclass, rdtype)
- self.address = address
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'address', address)
def to_text(self, origin=None, relativize=True, **kw):
return "0x%s" % binascii.hexlify(self.address).decode()
__slots__ = ['preference', 'map822', 'mapx400']
def __init__(self, rdclass, rdtype, preference, map822, mapx400):
- super(PX, self).__init__(rdclass, rdtype)
- self.preference = preference
- self.map822 = map822
- self.mapx400 = mapx400
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'preference', preference)
+ object.__setattr__(self, 'map822', map822)
+ object.__setattr__(self, 'mapx400', mapx400)
def to_text(self, origin=None, relativize=True, **kw):
map822 = self.map822.choose_relativity(origin, relativize)
__slots__ = ['priority', 'weight', 'port', 'target']
def __init__(self, rdclass, rdtype, priority, weight, port, target):
- super(SRV, self).__init__(rdclass, rdtype)
- self.priority = priority
- self.weight = weight
- self.port = port
- self.target = target
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'priority', priority)
+ object.__setattr__(self, 'weight', weight)
+ object.__setattr__(self, 'port', port)
+ object.__setattr__(self, 'target', target)
def to_text(self, origin=None, relativize=True, **kw):
target = self.target.choose_relativity(origin, relativize)
__slots__ = ['address', 'protocol', 'bitmap']
def __init__(self, rdclass, rdtype, address, protocol, bitmap):
- super(WKS, self).__init__(rdclass, rdtype)
- self.address = address
- self.protocol = protocol
- if not isinstance(bitmap, bytearray):
- self.bitmap = bytearray(bitmap)
- else:
- self.bitmap = bitmap
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'address', address)
+ object.__setattr__(self, 'protocol', protocol)
+ object.__setattr__(self, 'bitmap', dns.rdata._constify(bitmap))
def to_text(self, origin=None, relativize=True, **kw):
bits = []
__slots__ = ['flags', 'protocol', 'algorithm', 'key']
def __init__(self, rdclass, rdtype, flags, protocol, algorithm, key):
- super(DNSKEYBase, self).__init__(rdclass, rdtype)
- self.flags = flags
- self.protocol = protocol
- self.algorithm = algorithm
- self.key = key
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'flags', flags)
+ object.__setattr__(self, 'protocol', protocol)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'key', key)
def to_text(self, origin=None, relativize=True, **kw):
return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm,
def __init__(self, rdclass, rdtype, key_tag, algorithm, digest_type,
digest):
- super(DSBase, self).__init__(rdclass, rdtype)
- self.key_tag = key_tag
- self.algorithm = algorithm
- self.digest_type = digest_type
- self.digest = digest
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'key_tag', key_tag)
+ object.__setattr__(self, 'algorithm', algorithm)
+ object.__setattr__(self, 'digest_type', digest_type)
+ object.__setattr__(self, 'digest', digest)
def to_text(self, origin=None, relativize=True, **kw):
return '%d %d %d %s' % (self.key_tag, self.algorithm,
# text_len = byte_len * 3 - 1 # 01-23-45-67-89-ab
def __init__(self, rdclass, rdtype, eui):
- super(EUIBase, self).__init__(rdclass, rdtype)
+ super().__init__(rdclass, rdtype)
if len(eui) != self.byte_len:
raise dns.exception.FormError('EUI%s rdata has to have %s bytes'
% (self.byte_len * 8, self.byte_len))
- self.eui = eui
+ object.__setattr__(self, 'eui', eui)
def to_text(self, origin=None, relativize=True, **kw):
return dns.rdata._hexify(self.eui, chunksize=2).replace(' ', '-')
__slots__ = ['preference', 'exchange']
def __init__(self, rdclass, rdtype, preference, exchange):
- super(MXBase, self).__init__(rdclass, rdtype)
- self.preference = preference
- self.exchange = exchange
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'preference', preference)
+ object.__setattr__(self, 'exchange', exchange)
def to_text(self, origin=None, relativize=True, **kw):
exchange = self.exchange.choose_relativity(origin, relativize)
__slots__ = ['target']
def __init__(self, rdclass, rdtype, target):
- super(NSBase, self).__init__(rdclass, rdtype)
- self.target = target
+ super().__init__(rdclass, rdtype)
+ object.__setattr__(self, 'target', target)
def to_text(self, origin=None, relativize=True, **kw):
target = self.target.choose_relativity(origin, relativize)
__slots__ = ['strings']
def __init__(self, rdclass, rdtype, strings):
- super(TXTBase, self).__init__(rdclass, rdtype)
- if isinstance(strings, bytes) or \
- isinstance(strings, str):
- strings = [strings]
- self.strings = []
+ super().__init__(rdclass, rdtype)
+ if isinstance(strings, (bytes, str)):
+ strings = (strings,)
+ encoded_strings = []
for string in strings:
if isinstance(string, str):
string = string.encode()
- self.strings.append(string)
+ else:
+ string = dns.rdata._constify(string)
+ encoded_strings.append(string)
+ object.__setattr__(self, 'strings', tuple(encoded_strings))
def to_text(self, origin=None, relativize=True, **kw):
txt = ''