Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
python-dnspython
py3_fixes.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File py3_fixes.patch of Package python-dnspython
Index: dnspython-1.12.0/dns/_compat.py =================================================================== --- /dev/null +++ dnspython-1.12.0/dns/_compat.py @@ -0,0 +1,26 @@ +import sys + + +if sys.version_info > (3,): + long = int + xrange = range +else: + long = long + xrange = xrange + +# unicode / binary types +if sys.version_info > (3,): + text_type = str + binary_type = bytes + string_types = (str,) + def xcmp(a, b): + if isinstance(a, str): + a = a.encode() + if isinstance(b, str): + b = b.encode() + return (a > b) - (a < b) +else: + text_type = unicode + binary_type = str + string_types = (basestring,) + xcmp = cmp Index: dnspython-1.12.0/dns/dnssec.py =================================================================== --- dnspython-1.12.0.orig/dns/dnssec.py +++ dnspython-1.12.0/dns/dnssec.py @@ -15,7 +15,7 @@ """Common DNSSEC-related functions and constants.""" -import cStringIO +from io import BytesIO import struct import time @@ -27,6 +27,7 @@ import dns.rdataset import dns.rdata import dns.rdatatype import dns.rdataclass +from ._compat import string_types class UnsupportedAlgorithm(dns.exception.DNSException): """Raised if an algorithm is not supported.""" @@ -52,27 +53,28 @@ PRIVATEDNS = 253 PRIVATEOID = 254 _algorithm_by_text = { - 'RSAMD5' : RSAMD5, - 'DH' : DH, - 'DSA' : DSA, - 'ECC' : ECC, - 'RSASHA1' : RSASHA1, - 'DSANSEC3SHA1' : DSANSEC3SHA1, - 'RSASHA1NSEC3SHA1' : RSASHA1NSEC3SHA1, - 'RSASHA256' : RSASHA256, - 'RSASHA512' : RSASHA512, - 'INDIRECT' : INDIRECT, - 'ECDSAP256SHA256' : ECDSAP256SHA256, - 'ECDSAP384SHA384' : ECDSAP384SHA384, - 'PRIVATEDNS' : PRIVATEDNS, - 'PRIVATEOID' : PRIVATEOID, - } + 'RSAMD5': RSAMD5, + 'DH': DH, + 'DSA': DSA, + 'ECC': ECC, + 'RSASHA1': RSASHA1, + 'DSANSEC3SHA1': DSANSEC3SHA1, + 'RSASHA1NSEC3SHA1': RSASHA1NSEC3SHA1, + 'RSASHA256': RSASHA256, + 'RSASHA512': RSASHA512, + 'INDIRECT': INDIRECT, + 'ECDSAP256SHA256': ECDSAP256SHA256, + 'ECDSAP384SHA384': ECDSAP384SHA384, + 'PRIVATEDNS': PRIVATEDNS, + 'PRIVATEOID': PRIVATEOID, +} # We construct the inverse mapping programmatically to ensure that we # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that # would cause the mapping not to be true inverse. -_algorithm_by_value = dict([(y, x) for x, y in _algorithm_by_text.iteritems()]) +_algorithm_by_value = dict((y, x) for x, y in _algorithm_by_text.items()) + def algorithm_from_text(text): """Convert text into a DNSSEC algorithm value @@ -83,6 +85,7 @@ def algorithm_from_text(text): value = int(text) return value + def algorithm_to_text(value): """Convert a DNSSEC algorithm value to text @rtype: string""" @@ -92,35 +95,40 @@ def algorithm_to_text(value): text = str(value) return text + def _to_rdata(record, origin): - s = cStringIO.StringIO() + s = BytesIO() record.to_wire(s, origin=origin) return s.getvalue() + def key_id(key, origin=None): rdata = _to_rdata(key, origin) + rdata = bytearray(rdata) if key.algorithm == RSAMD5: - return (ord(rdata[-3]) << 8) + ord(rdata[-2]) + return (rdata[-3] << 8) + rdata[-2] else: total = 0 for i in range(len(rdata) // 2): - total += (ord(rdata[2 * i]) << 8) + ord(rdata[2 * i + 1]) + total += (rdata[2 * i] << 8) + \ + rdata[2 * i + 1] if len(rdata) % 2 != 0: - total += ord(rdata[len(rdata) - 1]) << 8 - total += ((total >> 16) & 0xffff); + total += rdata[len(rdata) - 1] << 8 + total += ((total >> 16) & 0xffff) return total & 0xffff + def make_ds(name, key, algorithm, origin=None): if algorithm.upper() == 'SHA1': dsalg = 1 - hash = dns.hash.get('SHA1')() + hash = dns.hash.hashes['SHA1']() elif algorithm.upper() == 'SHA256': dsalg = 2 - hash = dns.hash.get('SHA256')() + hash = dns.hash.hashes['SHA256']() else: - raise UnsupportedAlgorithm, 'unsupported algorithm "%s"' % algorithm + raise UnsupportedAlgorithm('unsupported algorithm "%s"' % algorithm) - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, origin) hash.update(name.canonicalize().to_wire()) hash.update(_to_rdata(key, origin)) @@ -130,8 +138,9 @@ def make_ds(name, key, algorithm, origin return dns.rdata.from_wire(dns.rdataclass.IN, dns.rdatatype.DS, dsrdata, 0, len(dsrdata)) + def _find_candidate_keys(keys, rrsig): - candidate_keys=[] + candidate_keys = [] value = keys.get(rrsig.signer) if value is None: return None @@ -145,49 +154,59 @@ def _find_candidate_keys(keys, rrsig): rdataset = value for rdata in rdataset: if rdata.algorithm == rrsig.algorithm and \ - key_id(rdata) == rrsig.key_tag: + key_id(rdata) == rrsig.key_tag: candidate_keys.append(rdata) return candidate_keys + def _is_rsa(algorithm): return algorithm in (RSAMD5, RSASHA1, RSASHA1NSEC3SHA1, RSASHA256, RSASHA512) + def _is_dsa(algorithm): return algorithm in (DSA, DSANSEC3SHA1) + def _is_ecdsa(algorithm): return _have_ecdsa and (algorithm in (ECDSAP256SHA256, ECDSAP384SHA384)) + def _is_md5(algorithm): return algorithm == RSAMD5 + def _is_sha1(algorithm): return algorithm in (DSA, RSASHA1, DSANSEC3SHA1, RSASHA1NSEC3SHA1) + def _is_sha256(algorithm): return algorithm in (RSASHA256, ECDSAP256SHA256) + def _is_sha384(algorithm): return algorithm == ECDSAP384SHA384 + def _is_sha512(algorithm): return algorithm == RSASHA512 + def _make_hash(algorithm): if _is_md5(algorithm): - return dns.hash.get('MD5')() + return dns.hash.hashes['MD5']() if _is_sha1(algorithm): - return dns.hash.get('SHA1')() + return dns.hash.hashes['SHA1']() if _is_sha256(algorithm): - return dns.hash.get('SHA256')() + return dns.hash.hashes['SHA256']() if _is_sha384(algorithm): - return dns.hash.get('SHA384')() + return dns.hash.hashes['SHA384']() if _is_sha512(algorithm): - return dns.hash.get('SHA512')() - raise ValidationFailure, 'unknown hash for algorithm %u' % algorithm + return dns.hash.hashes['SHA512']() + raise ValidationFailure('unknown hash for algorithm %u' % algorithm) + def _make_algorithm_id(algorithm): if _is_md5(algorithm): @@ -199,13 +218,14 @@ def _make_algorithm_id(algorithm): elif _is_sha512(algorithm): oid = [0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03] else: - raise ValidationFailure, 'unknown algorithm %u' % algorithm + raise ValidationFailure('unknown algorithm %u' % algorithm) olen = len(oid) dlen = _make_hash(algorithm).digest_size idbytes = [0x30] + [8 + olen + dlen] + \ [0x30, olen + 4] + [0x06, olen] + oid + \ [0x05, 0x00] + [0x04, dlen] - return ''.join(map(chr, idbytes)) + return struct.pack('!%dB' % len(idbytes), *idbytes) + def _validate_rrsig(rrset, rrsig, keys, origin=None, now=None): """Validate an RRset against a single signature rdata @@ -219,7 +239,8 @@ def _validate_rrsig(rrset, rrsig, keys, @param rrsig: The signature rdata @type rrsig: dns.rrset.Rdata @param keys: The key dictionary. - @type keys: a dictionary keyed by dns.name.Name with node or rdataset values + @type keys: a dictionary keyed by dns.name.Name with node or rdataset + values @param origin: The origin to use for relative names @type origin: dns.name.Name or None @param now: The time to use when validating the signatures. The default @@ -227,15 +248,15 @@ def _validate_rrsig(rrset, rrsig, keys, @type now: int """ - if isinstance(origin, (str, unicode)): + if isinstance(origin, string_types): origin = dns.name.from_text(origin, dns.name.root) for candidate_key in _find_candidate_keys(keys, rrsig): if not candidate_key: - raise ValidationFailure, 'unknown key' + raise ValidationFailure('unknown key') - # For convenience, allow the rrset to be specified as a (name, rdataset) - # tuple as well as a proper rrset + # For convenience, allow the rrset to be specified as a (name, + # rdataset) tuple as well as a proper rrset if isinstance(rrset, tuple): rrname = rrset[0] rdataset = rrset[1] @@ -246,21 +267,21 @@ def _validate_rrsig(rrset, rrsig, keys, if now is None: now = time.time() if rrsig.expiration < now: - raise ValidationFailure, 'expired' + raise ValidationFailure('expired') if rrsig.inception > now: - raise ValidationFailure, 'not yet valid' + raise ValidationFailure('not yet valid') hash = _make_hash(rrsig.algorithm) if _is_rsa(rrsig.algorithm): keyptr = candidate_key.key - (bytes,) = struct.unpack('!B', keyptr[0:1]) + (bytes_,) = struct.unpack('!B', keyptr[0:1]) keyptr = keyptr[1:] - if bytes == 0: - (bytes,) = struct.unpack('!H', keyptr[0:2]) + if bytes_ == 0: + (bytes_,) = struct.unpack('!H', keyptr[0:2]) keyptr = keyptr[2:] - rsa_e = keyptr[0:bytes] - rsa_n = keyptr[bytes:] + rsa_e = keyptr[0:bytes_] + rsa_n = keyptr[bytes_:] keylen = len(rsa_n) * 8 pubkey = Crypto.PublicKey.RSA.construct( (Crypto.Util.number.bytes_to_long(rsa_n), @@ -290,14 +311,12 @@ def _validate_rrsig(rrset, rrsig, keys, if rrsig.algorithm == ECDSAP256SHA256: curve = ecdsa.curves.NIST256p key_len = 32 - digest_len = 32 elif rrsig.algorithm == ECDSAP384SHA384: curve = ecdsa.curves.NIST384p key_len = 48 - digest_len = 48 else: # shouldn't happen - raise ValidationFailure, 'unknown ECDSA curve' + raise ValidationFailure('unknown ECDSA curve') keyptr = candidate_key.key x = Crypto.Util.number.bytes_to_long(keyptr[0:key_len]) y = Crypto.Util.number.bytes_to_long(keyptr[key_len:key_len * 2]) @@ -311,7 +330,7 @@ def _validate_rrsig(rrset, rrsig, keys, sig = ecdsa.ecdsa.Signature(Crypto.Util.number.bytes_to_long(r), Crypto.Util.number.bytes_to_long(s)) else: - raise ValidationFailure, 'unknown algorithm %u' % rrsig.algorithm + raise ValidationFailure('unknown algorithm %u' % rrsig.algorithm) hash.update(_to_rdata(rrsig, origin)[:18]) hash.update(rrsig.signer.to_digestable(origin)) @@ -322,7 +341,7 @@ def _validate_rrsig(rrset, rrsig, keys, rrnamebuf = rrname.to_digestable(origin) rrfixed = struct.pack('!HHI', rdataset.rdtype, rdataset.rdclass, rrsig.original_ttl) - rrlist = sorted(rdataset); + rrlist = sorted(rdataset) for rr in rrlist: hash.update(rrnamebuf) hash.update(rrfixed) @@ -337,18 +356,20 @@ def _validate_rrsig(rrset, rrsig, keys, # PKCS1 algorithm identifier goop digest = _make_algorithm_id(rrsig.algorithm) + digest padlen = keylen // 8 - len(digest) - 3 - digest = chr(0) + chr(1) + chr(0xFF) * padlen + chr(0) + digest + digest = struct.pack('!%dB' % (2 + padlen + 1), + *([0, 1] + [0xFF] * padlen + [0])) + digest elif _is_dsa(rrsig.algorithm) or _is_ecdsa(rrsig.algorithm): pass else: # Raise here for code clarity; this won't actually ever happen # since if the algorithm is really unknown we'd already have # raised an exception above - raise ValidationFailure, 'unknown algorithm %u' % rrsig.algorithm + raise ValidationFailure('unknown algorithm %u' % rrsig.algorithm) if pubkey.verify(digest, sig): return - raise ValidationFailure, 'verify failure' + raise ValidationFailure('verify failure') + def _validate(rrset, rrsigset, keys, origin=None, now=None): """Validate an RRset @@ -360,7 +381,8 @@ def _validate(rrset, rrsigset, keys, ori @type rrsigset: dns.rrset.RRset or (dns.name.Name, dns.rdataset.Rdataset) tuple @param keys: The key dictionary. - @type keys: a dictionary keyed by dns.name.Name with node or rdataset values + @type keys: a dictionary keyed by dns.name.Name with node or rdataset + values @param origin: The origin to use for relative names @type origin: dns.name.Name or None @param now: The time to use when validating the signatures. The default @@ -368,7 +390,7 @@ def _validate(rrset, rrsigset, keys, ori @type now: int """ - if isinstance(origin, (str, unicode)): + if isinstance(origin, string_types): origin = dns.name.from_text(origin, dns.name.root) if isinstance(rrset, tuple): @@ -386,18 +408,19 @@ def _validate(rrset, rrsigset, keys, ori rrname = rrname.choose_relativity(origin) rrsigname = rrname.choose_relativity(origin) if rrname != rrsigname: - raise ValidationFailure, "owner names do not match" + raise ValidationFailure("owner names do not match") for rrsig in rrsigrdataset: try: _validate_rrsig(rrset, rrsig, keys, origin, now) return - except ValidationFailure, e: + except ValidationFailure: pass - raise ValidationFailure, "no RRSIGs validated" + raise ValidationFailure("no RRSIGs validated") + def _need_pycrypto(*args, **kwargs): - raise NotImplementedError, "DNSSEC validation requires pycrypto" + raise NotImplementedError("DNSSEC validation requires pycrypto") try: import Crypto.PublicKey.RSA @@ -419,9 +442,11 @@ try: _have_ecdsa = True class ECKeyWrapper(object): + def __init__(self, key, key_len): self.key = key self.key_len = key_len + def verify(self, digest, sig): diglong = Crypto.Util.number.bytes_to_long(digest) return self.key.pubkey.verifies(diglong, sig) Index: dnspython-1.12.0/dns/e164.py =================================================================== --- dnspython-1.12.0.orig/dns/e164.py +++ dnspython-1.12.0/dns/e164.py @@ -19,12 +19,15 @@ @type public_enum_domain: dns.name.Name object """ + import dns.exception import dns.name import dns.resolver +from ._compat import string_types public_enum_domain = dns.name.from_text('e164.arpa.') + def from_e164(text, origin=public_enum_domain): """Convert an E.164 number in textual form into a Name object whose value is the ENUM domain name for that number. @@ -39,6 +42,7 @@ def from_e164(text, origin=public_enum_d parts.reverse() return dns.name.from_text('.'.join(parts), origin=origin) + def to_e164(name, origin=public_enum_domain, want_plus_prefix=True): """Convert an ENUM domain name into an E.164 number. @param name: the ENUM domain name. @@ -50,17 +54,18 @@ def to_e164(name, origin=public_enum_dom returned number. @rtype: str """ - if not origin is None: + if origin is not None: name = name.relativize(origin) dlabels = [d for d in name.labels if (d.isdigit() and len(d) == 1)] if len(dlabels) != len(name.labels): raise dns.exception.SyntaxError('non-digit labels in ENUM domain name') dlabels.reverse() - text = ''.join(dlabels) + text = b''.join(dlabels) if want_plus_prefix: - text = '+' + text + text = b'+' + text return text + def query(number, domains, resolver=None): """Look for NAPTR RRs for the specified number in the specified domains. @@ -69,7 +74,7 @@ def query(number, domains, resolver=None if resolver is None: resolver = dns.resolver.get_default_resolver() for domain in domains: - if isinstance(domain, (str, unicode)): + if isinstance(domain, string_types): domain = dns.name.from_text(domain) qname = dns.e164.from_e164(number, domain) try: Index: dnspython-1.12.0/dns/edns.py =================================================================== --- dnspython-1.12.0.orig/dns/edns.py +++ dnspython-1.12.0/dns/edns.py @@ -14,10 +14,12 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """EDNS Options""" - +from dns._compat import xcmp NSID = 3 + class Option(object): + """Base class for all EDNS option types. """ @@ -33,6 +35,7 @@ class Option(object): """ raise NotImplementedError + @classmethod def from_wire(cls, otype, wire, current, olen): """Build an EDNS option object from wire format @@ -47,11 +50,10 @@ class Option(object): @rtype: dns.edns.Option instance""" raise NotImplementedError - from_wire = classmethod(from_wire) - def _cmp(self, other): """Compare an EDNS option with another option of the same type. - Return < 0 if self < other, 0 if self == other, and > 0 if self > other. + Return < 0 if self < other, 0 if self == other, + and > 0 if self > other. """ raise NotImplementedError @@ -71,30 +73,31 @@ class Option(object): def __lt__(self, other): if not isinstance(other, Option) or \ - self.otype != other.otype: + self.otype != other.otype: return NotImplemented return self._cmp(other) < 0 def __le__(self, other): if not isinstance(other, Option) or \ - self.otype != other.otype: + self.otype != other.otype: return NotImplemented return self._cmp(other) <= 0 def __ge__(self, other): if not isinstance(other, Option) or \ - self.otype != other.otype: + self.otype != other.otype: return NotImplemented return self._cmp(other) >= 0 def __gt__(self, other): if not isinstance(other, Option) or \ - self.otype != other.otype: + self.otype != other.otype: return NotImplemented return self._cmp(other) > 0 class GenericOption(Option): + """Generate Rdata Class This class is used for EDNS option types for which we have no better @@ -108,13 +111,12 @@ class GenericOption(Option): def to_wire(self, file): file.write(self.data) + @classmethod def from_wire(cls, otype, wire, current, olen): return cls(otype, wire[current : current + olen]) - from_wire = classmethod(from_wire) - def _cmp(self, other): - return cmp(self.data, other.data) + return xcmp(self.data, other.data) _type_to_class = { } Index: dnspython-1.12.0/dns/entropy.py =================================================================== --- dnspython-1.12.0.orig/dns/entropy.py +++ dnspython-1.12.0/dns/entropy.py @@ -15,12 +15,15 @@ import os import time +from ._compat import long, binary_type try: import threading as _threading except ImportError: import dummy_threading as _threading + class EntropyPool(object): + def __init__(self, seed=None): self.pool_index = 0 self.digest = None @@ -39,9 +42,9 @@ class EntropyPool(object): import md5 self.hash = md5.new() self.hash_len = 16 - self.pool = '\0' * self.hash_len - if not seed is None: - self.stir(seed) + self.pool = bytearray(b'\0' * self.hash_len) + if seed is not None: + self.stir(bytearray(seed)) self.seeded = True else: self.seeded = False @@ -50,14 +53,12 @@ class EntropyPool(object): if not already_locked: self.lock.acquire() try: - bytes = [ord(c) for c in self.pool] for c in entropy: if self.pool_index == self.hash_len: self.pool_index = 0 - b = ord(c) & 0xff - bytes[self.pool_index] ^= b + b = c & 0xff + self.pool[self.pool_index] ^= b self.pool_index += 1 - self.pool = ''.join([chr(c) for c in bytes]) finally: if not already_locked: self.lock.release() @@ -68,7 +69,7 @@ class EntropyPool(object): seed = os.urandom(16) except: try: - r = file('/dev/urandom', 'r', 0) + r = open('/dev/urandom', 'rb', 0) try: seed = r.read(16) finally: @@ -76,18 +77,19 @@ class EntropyPool(object): except: seed = str(time.time()) self.seeded = True + seed = bytearray(seed) self.stir(seed, True) def random_8(self): self.lock.acquire() - self._maybe_seed() try: + self._maybe_seed() if self.digest is None or self.next_byte == self.hash_len: - self.hash.update(self.pool) - self.digest = self.hash.digest() + self.hash.update(binary_type(self.pool)) + self.digest = bytearray(self.hash.digest()) self.stir(self.digest, True) self.next_byte = 0 - value = ord(self.digest[self.next_byte]) + value = self.digest[self.next_byte] self.next_byte += 1 finally: self.lock.release() @@ -101,23 +103,25 @@ class EntropyPool(object): def random_between(self, first, last): size = last - first + 1 - if size > 4294967296L: + if size > long(4294967296): raise ValueError('too big') if size > 65536: rand = self.random_32 - max = 4294967295L + max = long(4294967295) elif size > 256: rand = self.random_16 max = 65535 else: rand = self.random_8 max = 255 - return (first + size * rand() // (max + 1)) + return (first + size * rand() // (max + 1)) pool = EntropyPool() + def random_16(): return pool.random_16() + def between(first, last): return pool.random_between(first, last) Index: dnspython-1.12.0/dns/flags.py =================================================================== --- dnspython-1.12.0.orig/dns/flags.py +++ dnspython-1.12.0/dns/flags.py @@ -30,17 +30,17 @@ CD = 0x0010 DO = 0x8000 _by_text = { - 'QR' : QR, - 'AA' : AA, - 'TC' : TC, - 'RD' : RD, - 'RA' : RA, - 'AD' : AD, - 'CD' : CD + 'QR': QR, + 'AA': AA, + 'TC': TC, + 'RD': RD, + 'RA': RA, + 'AD': AD, + 'CD': CD } _edns_by_text = { - 'DO' : DO + 'DO': DO } @@ -48,12 +48,13 @@ _edns_by_text = { # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that # would cause the mappings not to be true inverses. -_by_value = dict([(y, x) for x, y in _by_text.iteritems()]) +_by_value = dict((y, x) for x, y in _by_text.items()) + +_edns_by_value = dict((y, x) for x, y in _edns_by_text.items()) -_edns_by_value = dict([(y, x) for x, y in _edns_by_text.iteritems()]) def _order_flags(table): - order = list(table.iteritems()) + order = list(table.items()) order.sort() order.reverse() return order @@ -62,6 +63,7 @@ _flags_order = _order_flags(_by_value) _edns_flags_order = _order_flags(_edns_by_value) + def _from_text(text, table): flags = 0 tokens = text.split() @@ -69,6 +71,7 @@ def _from_text(text, table): flags = flags | table[t.upper()] return flags + def _to_text(flags, table, order): text_flags = [] for k, v in order: @@ -76,6 +79,7 @@ def _to_text(flags, table, order): text_flags.append(v) return ' '.join(text_flags) + def from_text(text): """Convert a space-separated list of flag text values into a flags value. @@ -83,13 +87,14 @@ def from_text(text): return _from_text(text, _by_text) + def to_text(flags): """Convert a flags value into a space-separated list of flag text values. @rtype: string""" return _to_text(flags, _by_value, _flags_order) - + def edns_from_text(text): """Convert a space-separated list of EDNS flag text values into a EDNS @@ -98,6 +103,7 @@ def edns_from_text(text): return _from_text(text, _edns_by_text) + def edns_to_text(flags): """Convert an EDNS flags value into a space-separated list of EDNS flag text values. Index: dnspython-1.12.0/dns/grange.py =================================================================== --- dnspython-1.12.0.orig/dns/grange.py +++ dnspython-1.12.0/dns/grange.py @@ -17,6 +17,7 @@ import dns + def from_text(text): """Convert the text form of a range in a GENERATE statement to an integer. @@ -28,7 +29,6 @@ def from_text(text): """ # TODO, figure out the bounds on start, stop and step. - import pdb step = 1 cur = '' state = 0 Index: dnspython-1.12.0/dns/hash.py =================================================================== --- dnspython-1.12.0.orig/dns/hash.py +++ dnspython-1.12.0/dns/hash.py @@ -16,52 +16,17 @@ """Hashing backwards compatibility wrapper""" import sys +import hashlib -_hashes = None -def _need_later_python(alg): - def func(*args, **kwargs): - raise NotImplementedError("TSIG algorithm " + alg + - " requires Python 2.5.2 or later") - return func +hashes = {} +hashes['MD5'] = hashlib.md5 +hashes['SHA1'] = hashlib.sha1 +hashes['SHA224'] = hashlib.sha224 +hashes['SHA256'] = hashlib.sha256 +hashes['SHA384'] = hashlib.sha384 +hashes['SHA512'] = hashlib.sha512 -def _setup(): - global _hashes - _hashes = {} - try: - import hashlib - _hashes['MD5'] = hashlib.md5 - _hashes['SHA1'] = hashlib.sha1 - _hashes['SHA224'] = hashlib.sha224 - _hashes['SHA256'] = hashlib.sha256 - if sys.hexversion >= 0x02050200: - _hashes['SHA384'] = hashlib.sha384 - _hashes['SHA512'] = hashlib.sha512 - else: - _hashes['SHA384'] = _need_later_python('SHA384') - _hashes['SHA512'] = _need_later_python('SHA512') - - if sys.hexversion < 0x02050000: - # hashlib doesn't conform to PEP 247: API for - # Cryptographic Hash Functions, which hmac before python - # 2.5 requires, so add the necessary items. - class HashlibWrapper: - def __init__(self, basehash): - self.basehash = basehash - self.digest_size = self.basehash().digest_size - - def new(self, *args, **kwargs): - return self.basehash(*args, **kwargs) - - for name in _hashes: - _hashes[name] = HashlibWrapper(_hashes[name]) - - except ImportError: - import md5, sha - _hashes['MD5'] = md5 - _hashes['SHA1'] = sha def get(algorithm): - if _hashes is None: - _setup() - return _hashes[algorithm.upper()] + return hashes[algorithm.upper()] Index: dnspython-1.12.0/dns/inet.py =================================================================== --- dnspython-1.12.0.orig/dns/inet.py +++ dnspython-1.12.0/dns/inet.py @@ -34,6 +34,7 @@ try: except AttributeError: AF_INET6 = 9999 + def inet_pton(family, text): """Convert the textual form of a network address into its binary form. @@ -45,7 +46,7 @@ def inet_pton(family, text): implemented. @rtype: string """ - + if family == AF_INET: return dns.ipv4.inet_aton(text) elif family == AF_INET6: @@ -53,6 +54,7 @@ def inet_pton(family, text): else: raise NotImplementedError + def inet_ntop(family, address): """Convert the binary form of a network address into its textual form. @@ -71,6 +73,7 @@ def inet_ntop(family, address): else: raise NotImplementedError + def af_for_address(text): """Determine the address family of a textual-form network address. @@ -80,15 +83,16 @@ def af_for_address(text): @rtype: int """ try: - junk = dns.ipv4.inet_aton(text) + dns.ipv4.inet_aton(text) return AF_INET except: try: - junk = dns.ipv6.inet_aton(text) + dns.ipv6.inet_aton(text) return AF_INET6 except: raise ValueError + def is_multicast(text): """Is the textual-form network address a multicast address? @@ -105,4 +109,3 @@ def is_multicast(text): return (first == 255) except: raise ValueError - Index: dnspython-1.12.0/dns/ipv4.py =================================================================== --- dnspython-1.12.0.orig/dns/ipv4.py +++ dnspython-1.12.0/dns/ipv4.py @@ -18,6 +18,7 @@ import struct import dns.exception +from ._compat import binary_type def inet_ntoa(address): """Convert an IPv4 address in network form to text form. @@ -28,8 +29,10 @@ def inet_ntoa(address): """ if len(address) != 4: raise dns.exception.SyntaxError - return '%u.%u.%u.%u' % (ord(address[0]), ord(address[1]), - ord(address[2]), ord(address[3])) + if not isinstance(address, bytearray): + address = bytearray(address) + return (u'%u.%u.%u.%u' % (address[0], address[1], + address[2], address[3])).encode() def inet_aton(text): """Convert an IPv4 address in text form to network form. @@ -38,7 +41,9 @@ def inet_aton(text): @type text: string @returns: string """ - parts = text.split('.') + if not isinstance(text, binary_type): + text = text.encode() + parts = text.split(b'.') if len(parts) != 4: raise dns.exception.SyntaxError for part in parts: Index: dnspython-1.12.0/dns/ipv6.py =================================================================== --- dnspython-1.12.0.orig/dns/ipv6.py +++ dnspython-1.12.0/dns/ipv6.py @@ -16,11 +16,13 @@ """IPv6 helper functions.""" import re +import binascii import dns.exception import dns.ipv4 +from ._compat import xrange, binary_type -_leading_zero = re.compile(r'0+([0-9a-f]+)') +_leading_zero = re.compile(b'0+([0-9a-f]+)') def inet_ntoa(address): """Convert a network format IPv6 address into text. @@ -33,7 +35,7 @@ def inet_ntoa(address): if len(address) != 16: raise ValueError("IPv6 addresses are 16 bytes long") - hex = address.encode('hex_codec') + hex = binascii.hexlify(address) chunks = [] i = 0 l = len(hex) @@ -55,7 +57,7 @@ def inet_ntoa(address): start = -1 last_was_zero = False for i in xrange(8): - if chunks[i] != '0': + if chunks[i] != b'0': if last_was_zero: end = i current_len = end - start @@ -75,23 +77,23 @@ def inet_ntoa(address): if best_len > 1: if best_start == 0 and \ (best_len == 6 or - best_len == 5 and chunks[5] == 'ffff'): + best_len == 5 and chunks[5] == b'ffff'): # We have an embedded IPv4 address if best_len == 6: - prefix = '::' + prefix = b'::' else: - prefix = '::ffff:' + prefix = b'::ffff:' hex = prefix + dns.ipv4.inet_ntoa(address[12:]) else: - hex = ':'.join(chunks[:best_start]) + '::' + \ - ':'.join(chunks[best_start + best_len:]) + hex = b':'.join(chunks[:best_start]) + b'::' + \ + b':'.join(chunks[best_start + best_len:]) else: - hex = ':'.join(chunks) + hex = b':'.join(chunks) return hex -_v4_ending = re.compile(r'(.*):(\d+\.\d+\.\d+\.\d+)$') -_colon_colon_start = re.compile(r'::.*') -_colon_colon_end = re.compile(r'.*::$') +_v4_ending = re.compile(b'(.*):(\d+\.\d+\.\d+\.\d+)$') +_colon_colon_start = re.compile(b'::.*') +_colon_colon_end = re.compile(b'.*::$') def inet_aton(text): """Convert a text format IPv6 address into network format. @@ -105,17 +107,19 @@ def inet_aton(text): # # Our aim here is not something fast; we just want something that works. # + if not isinstance(text, binary_type): + text = text.encode() - if text == '::': - text = '0::' + if text == b'::': + text = b'0::' # # Get rid of the icky dot-quad syntax if we have it. # m = _v4_ending.match(text) if not m is None: - b = dns.ipv4.inet_aton(m.group(2)) - text = "%s:%02x%02x:%02x%02x" % (m.group(1), ord(b[0]), ord(b[1]), - ord(b[2]), ord(b[3])) + b = bytearray(dns.ipv4.inet_aton(m.group(2))) + text = (u"%s:%02x%02x:%02x%02x" % (m.group(1).decode(), b[0], b[1], + b[2], b[3])).encode() # # Try to turn '::<whatever>' into ':<whatever>'; if no match try to # turn '<whatever>::' into '<whatever>:' @@ -130,39 +134,39 @@ def inet_aton(text): # # Now canonicalize into 8 chunks of 4 hex digits each # - chunks = text.split(':') + chunks = text.split(b':') l = len(chunks) if l > 8: raise dns.exception.SyntaxError seen_empty = False canonical = [] for c in chunks: - if c == '': + if c == b'': if seen_empty: raise dns.exception.SyntaxError seen_empty = True for i in xrange(0, 8 - l + 1): - canonical.append('0000') + canonical.append(b'0000') else: lc = len(c) if lc > 4: raise dns.exception.SyntaxError if lc != 4: - c = ('0' * (4 - lc)) + c + c = (b'0' * (4 - lc)) + c canonical.append(c) if l < 8 and not seen_empty: raise dns.exception.SyntaxError - text = ''.join(canonical) + text = b''.join(canonical) # # Finally we can go to binary. # try: - return text.decode('hex_codec') - except TypeError: + return binascii.unhexlify(text) + except (binascii.Error, TypeError): raise dns.exception.SyntaxError -_mapped_prefix = '\x00' * 10 + '\xff\xff' +_mapped_prefix = b'\x00' * 10 + b'\xff\xff' def is_mapped(address): return address.startswith(_mapped_prefix) Index: dnspython-1.12.0/dns/message.py =================================================================== --- dnspython-1.12.0.orig/dns/message.py +++ dnspython-1.12.0/dns/message.py @@ -15,8 +15,9 @@ """DNS Messages""" -import cStringIO -import random +from __future__ import absolute_import + +from io import StringIO import struct import sys import time @@ -36,6 +37,8 @@ import dns.renderer import dns.tsig import dns.wiredata +from ._compat import long, xrange, string_types + class ShortHeader(dns.exception.FormError): """Raised if the DNS packet passed to from_wire() is too short.""" pass @@ -173,7 +176,7 @@ class Message(object): self.index = {} def __repr__(self): - return '<DNS message, ID ' + `self.id` + '>' + return '<DNS message, ID ' + repr(self.id) + '>' def __str__(self): return self.to_text() @@ -187,41 +190,45 @@ class Message(object): @rtype: string """ - s = cStringIO.StringIO() - print >> s, 'id %d' % self.id - print >> s, 'opcode %s' % \ - dns.opcode.to_text(dns.opcode.from_flags(self.flags)) + s = StringIO() + s.write(u'id %d\n' % self.id) + s.write(u'opcode %s\n' % + dns.opcode.to_text(dns.opcode.from_flags(self.flags))) rc = dns.rcode.from_flags(self.flags, self.ednsflags) - print >> s, 'rcode %s' % dns.rcode.to_text(rc) - print >> s, 'flags %s' % dns.flags.to_text(self.flags) + s.write(u'rcode %s\n' % dns.rcode.to_text(rc)) + s.write(u'flags %s\n' % dns.flags.to_text(self.flags)) if self.edns >= 0: - print >> s, 'edns %s' % self.edns + s.write(u'edns %s\n' % self.edns) if self.ednsflags != 0: - print >> s, 'eflags %s' % \ - dns.flags.edns_to_text(self.ednsflags) - print >> s, 'payload', self.payload + s.write(u'eflags %s\n' % + dns.flags.edns_to_text(self.ednsflags)) + s.write(u'payload %d\n' % self.payload) is_update = dns.opcode.is_update(self.flags) if is_update: - print >> s, ';ZONE' + s.write(u';ZONE\n') else: - print >> s, ';QUESTION' + s.write(u';QUESTION\n') for rrset in self.question: - print >> s, rrset.to_text(origin, relativize, **kw) + s.write(rrset.to_text(origin, relativize, **kw)) + s.write(u'\n') if is_update: - print >> s, ';PREREQ' + s.write(u';PREREQ\n') else: - print >> s, ';ANSWER' + s.write(u';ANSWER\n') for rrset in self.answer: - print >> s, rrset.to_text(origin, relativize, **kw) + s.write(rrset.to_text(origin, relativize, **kw)) + s.write(u'\n') if is_update: - print >> s, ';UPDATE' + s.write(u';UPDATE\n') else: - print >> s, ';AUTHORITY' + s.write(u';AUTHORITY\n') for rrset in self.authority: - print >> s, rrset.to_text(origin, relativize, **kw) - print >> s, ';ADDITIONAL' + s.write(rrset.to_text(origin, relativize, **kw)) + s.write(u'\n') + s.write(u';ADDITIONAL\n') for rrset in self.additional: - print >> s, rrset.to_text(origin, relativize, **kw) + s.write(rrset.to_text(origin, relativize, **kw)) + s.write(u'\n') # # We strip off the final \n so the caller can print the result without # doing weird things to get around eccentricities in Python print @@ -273,7 +280,7 @@ class Message(object): dns.opcode.from_flags(other.flags): return False if dns.rcode.from_flags(other.flags, other.ednsflags) != \ - dns.rcode.NOERROR: + dns.rcode.NOERROR: return True if dns.opcode.is_update(self.flags): return True @@ -327,9 +334,9 @@ class Message(object): key = (self.section_number(section), name, rdclass, rdtype, covers, deleting) if not force_unique: - if not self.index is None: + if self.index is not None: rrset = self.index.get(key) - if not rrset is None: + if rrset is not None: return rrset else: for rrset in section: @@ -339,7 +346,7 @@ class Message(object): raise KeyError rrset = dns.rrset.RRset(name, rdclass, rdtype, covers, deleting) section.append(rrset) - if not self.index is None: + if self.index is not None: self.index[key] = rrset return rrset @@ -416,7 +423,7 @@ class Message(object): for rrset in self.additional: r.add_rrset(dns.renderer.ADDITIONAL, rrset, **kw) r.write_header() - if not self.keyname is None: + if self.keyname is not None: r.add_tsig(self.keyname, self.keyring[self.keyname], self.fudge, self.original_id, self.tsig_error, self.other_data, self.request_mac, @@ -455,7 +462,7 @@ class Message(object): if keyname is None: self.keyname = self.keyring.keys()[0] else: - if isinstance(keyname, (str, unicode)): + if isinstance(keyname, string_types): keyname = dns.name.from_text(keyname) self.keyname = keyname self.keyalgorithm = algorithm @@ -467,7 +474,8 @@ class Message(object): self.tsig_error = tsig_error self.other_data = other_data - def use_edns(self, edns=0, ednsflags=0, payload=1280, request_payload=None, options=None): + def use_edns(self, edns=0, ednsflags=0, payload=1280, request_payload=None, + options=None): """Configure EDNS behavior. @param edns: The EDNS level to use. Specifying None, False, or -1 means 'do not use EDNS', and in this case the other parameters are @@ -499,7 +507,7 @@ class Message(object): options = [] else: # make sure the EDNS version in ednsflags agrees with edns - ednsflags &= 0xFF00FFFFL + ednsflags &= long(0xFF00FFFF) ednsflags |= (edns << 16) if options is None: options = [] @@ -537,7 +545,7 @@ class Message(object): (value, evalue) = dns.rcode.to_flags(rcode) self.flags &= 0xFFF0 self.flags |= value - self.ednsflags &= 0x00FFFFFFL + self.ednsflags &= long(0x00FFFFFF) self.ednsflags |= evalue if self.ednsflags != 0 and self.edns < 0: self.edns = 0 @@ -556,7 +564,9 @@ class Message(object): self.flags &= 0x87FF self.flags |= dns.opcode.to_flags(opcode) + class _WireReader(object): + """Wire format reader. @ivar wire: the wire-format message. @@ -600,12 +610,12 @@ class _WireReader(object): for i in xrange(0, qcount): (qname, used) = dns.name.from_wire(self.wire, self.current) - if not self.message.origin is None: + if self.message.origin is not None: qname = qname.relativize(self.message.origin) self.current = self.current + used (rdtype, rdclass) = \ - struct.unpack('!HH', - self.wire[self.current:self.current + 4]) + struct.unpack('!HH', + self.wire[self.current:self.current + 4]) self.current = self.current + 4 self.message.find_rrset(self.message.question, qname, rdclass, rdtype, create=True, @@ -630,15 +640,15 @@ class _WireReader(object): rr_start = self.current (name, used) = dns.name.from_wire(self.wire, self.current) absolute_name = name - if not self.message.origin is None: + if self.message.origin is not None: name = name.relativize(self.message.origin) self.current = self.current + used (rdtype, rdclass, ttl, rdlen) = \ - struct.unpack('!HHIH', - self.wire[self.current:self.current + 10]) + struct.unpack('!HHIH', + self.wire[self.current:self.current + 10]) self.current = self.current + 10 if rdtype == dns.rdatatype.OPT: - if not section is self.message.additional or seen_opt: + if section is not self.message.additional or seen_opt: raise BadEDNS self.message.payload = rdclass self.message.ednsflags = ttl @@ -648,10 +658,11 @@ class _WireReader(object): optslen = rdlen while optslen > 0: (otype, olen) = \ - struct.unpack('!HH', - self.wire[current:current + 4]) + struct.unpack('!HH', + self.wire[current:current + 4]) current = current + 4 - opt = dns.edns.option_from_wire(otype, self.wire, current, olen) + opt = dns.edns.option_from_wire( + otype, self.wire, current, olen) self.message.options.append(opt) current = current + olen optslen = optslen - 4 - olen @@ -670,31 +681,31 @@ class _WireReader(object): dns.tsig.get_algorithm_and_mac(self.wire, self.current, rdlen) self.message.tsig_ctx = \ - dns.tsig.validate(self.wire, - absolute_name, - secret, - int(time.time()), - self.message.request_mac, - rr_start, - self.current, - rdlen, - self.message.tsig_ctx, - self.message.multi, - self.message.first) + dns.tsig.validate(self.wire, + absolute_name, + secret, + int(time.time()), + self.message.request_mac, + rr_start, + self.current, + rdlen, + self.message.tsig_ctx, + self.message.multi, + self.message.first) self.message.had_tsig = True else: if ttl < 0: ttl = 0 if self.updating and \ (rdclass == dns.rdataclass.ANY or - rdclass == dns.rdataclass.NONE): + rdclass == dns.rdataclass.NONE): deleting = rdclass rdclass = self.zone_rdclass else: deleting = None if deleting == dns.rdataclass.ANY or \ - (deleting == dns.rdataclass.NONE and \ - section is self.message.answer): + (deleting == dns.rdataclass.NONE and + section is self.message.answer): covers = dns.rdatatype.NONE rd = None else: @@ -707,7 +718,7 @@ class _WireReader(object): rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, force_unique) - if not rd is None: + if rd is not None: rrset.add(rd, ttl) self.current = self.current + rdlen @@ -732,14 +743,14 @@ class _WireReader(object): if not self.ignore_trailing and self.current != l: raise TrailingJunk if self.message.multi and self.message.tsig_ctx and \ - not self.message.had_tsig: + not self.message.had_tsig: self.message.tsig_ctx.update(self.wire) def from_wire(wire, keyring=None, request_mac='', xfr=False, origin=None, - tsig_ctx = None, multi = False, first = True, - question_only = False, one_rr_per_rrset = False, - ignore_trailing = False): + tsig_ctx=None, multi=False, first=True, + question_only=False, one_rr_per_rrset=False, + ignore_trailing=False): """Convert a DNS wire format message into a message object. @@ -793,6 +804,7 @@ def from_wire(wire, keyring=None, reques class _TextReader(object): + """Text format reader. @ivar tok: the tokenizer @@ -830,13 +842,13 @@ class _TextReader(object): self.tok.unget(token) break self.message.flags = self.message.flags | \ - dns.flags.from_text(token.value) + dns.flags.from_text(token.value) if dns.opcode.is_update(self.message.flags): self.updating = True elif what == 'edns': self.message.edns = self.tok.get_int() self.message.ednsflags = self.message.ednsflags | \ - (self.message.edns << 16) + (self.message.edns << 16) elif what == 'eflags': if self.message.edns < 0: self.message.edns = 0 @@ -846,7 +858,7 @@ class _TextReader(object): self.tok.unget(token) break self.message.ednsflags = self.message.ednsflags | \ - dns.flags.edns_from_text(token.value) + dns.flags.edns_from_text(token.value) elif what == 'payload': self.message.payload = self.tok.get_int() if self.message.edns < 0: @@ -854,7 +866,7 @@ class _TextReader(object): elif what == 'opcode': text = self.tok.get_string() self.message.flags = self.message.flags | \ - dns.opcode.to_flags(dns.opcode.from_text(text)) + dns.opcode.to_flags(dns.opcode.from_text(text)) elif what == 'rcode': text = self.tok.get_string() self.message.set_rcode(dns.rcode.from_text(text)) @@ -865,7 +877,7 @@ class _TextReader(object): def _question_line(self, section): """Process one line from the text format question section.""" - token = self.tok.get(want_leading = True) + token = self.tok.get(want_leading=True) if not token.is_whitespace(): self.last_name = dns.name.from_text(token.value, None) name = self.last_name @@ -898,7 +910,7 @@ class _TextReader(object): deleting = None # Name - token = self.tok.get(want_leading = True) + token = self.tok.get(want_leading=True) if not token.is_whitespace(): self.last_name = dns.name.from_text(token.value, None) name = self.last_name @@ -941,7 +953,7 @@ class _TextReader(object): rrset = self.message.find_rrset(section, name, rdclass, rdtype, covers, deleting, True, self.updating) - if not rd is None: + if rd is not None: rrset.add(rd, ttl) def read(self): @@ -996,6 +1008,7 @@ def from_text(text): return m + def from_file(f): """Read the next text format message from the specified file. @@ -1005,15 +1018,11 @@ def from_file(f): @raises dns.exception.SyntaxError: @rtype: dns.message.Message object""" - if sys.hexversion >= 0x02030000: - # allow Unicode filenames; turn on universal newline support - str_type = basestring - opts = 'rU' - else: - str_type = str - opts = 'r' + str_type = string_types + opts = 'rU' + if isinstance(f, str_type): - f = file(f, opts) + f = open(f, opts) want_close = True else: want_close = False @@ -1025,7 +1034,8 @@ def from_file(f): f.close() return m -def make_query(qname, rdtype, rdclass = dns.rdataclass.IN, use_edns=None, + +def make_query(qname, rdtype, rdclass=dns.rdataclass.IN, use_edns=None, want_dnssec=False, ednsflags=0, payload=1280, request_payload=None, options=None): """Make a query message. @@ -1061,11 +1071,11 @@ def make_query(qname, rdtype, rdclass = @see: RFC 2671 @rtype: dns.message.Message object""" - if isinstance(qname, (str, unicode)): + if isinstance(qname, string_types): qname = dns.name.from_text(qname) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) - if isinstance(rdclass, (str, unicode)): + if isinstance(rdclass, string_types): rdclass = dns.rdataclass.from_text(rdclass) m = Message() m.flags |= dns.flags.RD @@ -1075,6 +1085,7 @@ def make_query(qname, rdtype, rdclass = m.want_dnssec(want_dnssec) return m + def make_response(query, recursion_available=False, our_payload=8192, fudge=300): """Make a message which is a response for the specified query. Index: dnspython-1.12.0/dns/name.py =================================================================== --- dnspython-1.12.0.orig/dns/name.py +++ dnspython-1.12.0/dns/name.py @@ -21,17 +21,23 @@ @type empty: dns.name.Name object """ -import cStringIO +from io import BytesIO import struct import sys import copy -if sys.hexversion >= 0x02030000: - import encodings.idna +import encodings.idna import dns.exception import dns.wiredata +from ._compat import long, binary_type, text_type + +try: + maxint = sys.maxint +except: + maxint = (1 << (8 * struct.calcsize("P"))) / 2 - 1 + NAMERELN_NONE = 0 NAMERELN_SUPERDOMAIN = 1 NAMERELN_SUBDOMAIN = 2 @@ -77,16 +83,7 @@ class NoParent(dns.exception.DNSExceptio or the empty name.""" pass -_escaped = { - '"' : True, - '(' : True, - ')' : True, - '.' : True, - ';' : True, - '\\' : True, - '@' : True, - '$' : True - } +_escaped = bytearray(b'"().;\\@$') def _escapify(label, unicode_mode=False): """Escape the characters in label which need it. @@ -94,24 +91,38 @@ def _escapify(label, unicode_mode=False) characters @returns: the escaped string @rtype: string""" - text = '' + if not unicode_mode: + text = '' + if isinstance(label, text_type): + label = label.encode() + for c in bytearray(label): + packed = struct.pack('!B', c).decode() + if c in _escaped: + text += '\\' + packed + elif c > 0x20 and c < 0x7F: + text += packed + else: + text += '\\%03d' % c + return text.encode() + + text = u'' + if isinstance(label, binary_type): + label = label.decode() for c in label: - if c in _escaped: - text += '\\' + c - elif ord(c) > 0x20 and ord(c) < 0x7F: + if c > u'\x20' and c < u'\x7f': text += c else: - if unicode_mode and ord(c) >= 0x7F: + if c >= u'\x7f': text += c else: - text += '\\%03d' % ord(c) + text += u'\\%03d' % c return text + def _validate_labels(labels): """Check for empty labels in the middle of a label sequence, labels that are too long, and for too many labels. @raises NameTooLong: the name as a whole is too long - @raises LabelTooLong: an individual label is too long @raises EmptyLabel: a label is empty (i.e. the root label) and appears in a position other than the end of the label sequence""" @@ -124,7 +135,7 @@ def _validate_labels(labels): total += ll + 1 if ll > 63: raise LabelTooLong - if i < 0 and label == '': + if i < 0 and label == b'': i = j j += 1 if total > 255: @@ -132,7 +143,17 @@ def _validate_labels(labels): if i >= 0 and i != l - 1: raise EmptyLabel + +def _ensure_bytes(label): + if isinstance(label, binary_type): + return label + if isinstance(label, text_type): + return label.encode() + raise ValueError + + class Name(object): + """A DNS name. The dns.name.Name class represents a DNS name as a tuple of labels. @@ -148,7 +169,7 @@ class Name(object): @param labels: the labels @type labels: any iterable whose values are strings """ - + labels = [_ensure_bytes(x) for x in labels] super(Name, self).__setattr__('labels', tuple(labels)) _validate_labels(self.labels) @@ -166,25 +187,25 @@ class Name(object): @rtype: bool """ - return len(self.labels) > 0 and self.labels[-1] == '' + return len(self.labels) > 0 and self.labels[-1] == b'' def is_wild(self): """Is this name wild? (I.e. Is the least significant label '*'?) @rtype: bool """ - return len(self.labels) > 0 and self.labels[0] == '*' + return len(self.labels) > 0 and self.labels[0] == b'*' def __hash__(self): """Return a case-insensitive hash of the name. @rtype: int """ - h = 0L + h = long(0) for label in self.labels: - for c in label: - h += ( h << 3 ) + ord(c.lower()) - return int(h % sys.maxint) + for c in bytearray(label.lower()): + h += (h << 3) + c + return int(h % maxint) def fullcompare(self, other): """Compare two names, returning a 3-tuple (relation, order, nlabels). @@ -319,9 +340,9 @@ class Name(object): return '<DNS name ' + self.__str__() + '>' def __str__(self): - return self.to_text(False) + return self.to_text(False).decode() - def to_text(self, omit_final_dot = False): + def to_text(self, omit_final_dot=False): """Convert name to text format. @param omit_final_dot: If True, don't emit the final dot (denoting the root label) for absolute names. The default is False. @@ -329,17 +350,17 @@ class Name(object): """ if len(self.labels) == 0: - return '@' - if len(self.labels) == 1 and self.labels[0] == '': - return '.' + return b'@' + if len(self.labels) == 1 and self.labels[0] == b'': + return b'.' if omit_final_dot and self.is_absolute(): l = self.labels[:-1] else: l = self.labels - s = '.'.join(map(_escapify, l)) + s = b'.'.join(map(_escapify, l)) return s - def to_unicode(self, omit_final_dot = False): + def to_unicode(self, omit_final_dot=False): """Convert name to Unicode text format. IDN ACE lables are converted to Unicode. @@ -357,7 +378,8 @@ class Name(object): l = self.labels[:-1] else: l = self.labels - s = u'.'.join([_escapify(encodings.idna.ToUnicode(x), True) for x in l]) + s = u'.'.join([_escapify(encodings.idna.ToUnicode(x), True) + for x in l]) return s def to_digestable(self, origin=None): @@ -381,14 +403,15 @@ class Name(object): labels.extend(list(origin.labels)) else: labels = self.labels - dlabels = ["%s%s" % (chr(len(x)), x.lower()) for x in labels] - return ''.join(dlabels) + dlabels = [struct.pack('!B%ds' % len(x), len(x), x.lower()) + for x in labels] + return b''.join(dlabels) - def to_wire(self, file = None, compress = None, origin = None): + def to_wire(self, file=None, compress=None, origin=None): """Convert name to wire format, possibly compressing it. @param file: the file where the name is emitted (typically - a cStringIO file). If None, a string containing the wire name + a BytesIO file). If None, a string containing the wire name will be returned. @type file: file or None @param compress: The compression table. If None (the default) names @@ -403,7 +426,7 @@ class Name(object): """ if file is None: - file = cStringIO.StringIO() + file = BytesIO() want_return = True else: want_return = False @@ -419,22 +442,22 @@ class Name(object): for label in labels: n = Name(labels[i:]) i += 1 - if not compress is None: + if compress is not None: pos = compress.get(n) else: pos = None - if not pos is None: + if pos is not None: value = 0xc000 + pos s = struct.pack('!H', value) file.write(s) break else: - if not compress is None and len(n) > 1: + if compress is not None and len(n) > 1: pos = file.tell() if pos <= 0x3fff: compress[n] = pos l = len(label) - file.write(chr(l)) + file.write(struct.pack('!B', l)) if l > 0: file.write(label) if want_return: @@ -476,8 +499,9 @@ class Name(object): elif depth == l: return (dns.name.empty, self) elif depth < 0 or depth > l: - raise ValueError('depth must be >= 0 and <= the length of the name') - return (Name(self[: -depth]), Name(self[-depth :])) + raise ValueError( + 'depth must be >= 0 and <= the length of the name') + return (Name(self[: -depth]), Name(self[-depth:])) def concatenate(self, other): """Return a new name which is the concatenation of self and other. @@ -498,7 +522,7 @@ class Name(object): @rtype: dns.name.Name object """ - if not origin is None and self.is_subdomain(origin): + if origin is not None and self.is_subdomain(origin): return Name(self[: -len(origin)]) else: return self @@ -540,10 +564,11 @@ class Name(object): raise NoParent return Name(self.labels[1:]) -root = Name(['']) +root = Name([b'']) empty = Name([]) -def from_unicode(text, origin = root): + +def from_unicode(text, origin=root): """Convert unicode text into a Name object. Lables are encoded in IDN ACE form. @@ -551,7 +576,7 @@ def from_unicode(text, origin = root): @rtype: dns.name.Name object """ - if not isinstance(text, unicode): + if not isinstance(text, text_type): raise ValueError("input to from_unicode() must be a unicode string") if not (origin is None or isinstance(origin, Name)): raise ValueError("origin must be a Name or None") @@ -564,7 +589,7 @@ def from_unicode(text, origin = root): text = u'' if text: if text == u'.': - return Name(['']) # no Unicode "u" on this constant! + return Name([b'']) # no Unicode "u" on this constant! for c in text: if escaping: if edigits == 0: @@ -583,8 +608,7 @@ def from_unicode(text, origin = root): if edigits == 3: escaping = False label += chr(total) - elif c == u'.' or c == u'\u3002' or \ - c == u'\uff0e' or c == u'\uff61': + elif c in [u'.', u'\u3002', u'\uff0e', u'\uff61']: if len(label) == 0: raise EmptyLabel labels.append(encodings.idna.ToASCII(label)) @@ -600,72 +624,75 @@ def from_unicode(text, origin = root): if len(label) > 0: labels.append(encodings.idna.ToASCII(label)) else: - labels.append('') - if (len(labels) == 0 or labels[-1] != '') and not origin is None: + labels.append(b'') + + if (len(labels) == 0 or labels[-1] != b'') and origin is not None: labels.extend(list(origin.labels)) return Name(labels) -def from_text(text, origin = root): + +def from_text(text, origin=root): """Convert text into a Name object. @rtype: dns.name.Name object """ - if not isinstance(text, str): - if isinstance(text, unicode) and sys.hexversion >= 0x02030000: - return from_unicode(text, origin) - else: - raise ValueError("input to from_text() must be a string") + if isinstance(text, text_type): + return from_unicode(text, origin) + if not isinstance(text, binary_type): + raise ValueError("input to from_text() must be a string") if not (origin is None or isinstance(origin, Name)): raise ValueError("origin must be a Name or None") labels = [] - label = '' + label = b'' escaping = False edigits = 0 total = 0 - if text == '@': - text = '' + if text == b'@': + text = b'' if text: - if text == '.': - return Name(['']) - for c in text: + if text == b'.': + return Name([b'']) + for c in bytearray(text): + byte_ = struct.pack('!B', c) if escaping: if edigits == 0: - if c.isdigit(): - total = int(c) + if byte_.isdigit(): + total = int(byte_) edigits += 1 else: - label += c + label += byte_ escaping = False else: - if not c.isdigit(): + if not byte_.isdigit(): raise BadEscape total *= 10 - total += int(c) + total += int(byte_) edigits += 1 if edigits == 3: escaping = False - label += chr(total) - elif c == '.': + label += struct.pack('!B', total) + elif byte_ == b'.': if len(label) == 0: raise EmptyLabel labels.append(label) - label = '' - elif c == '\\': + label = b'' + elif byte_ == b'\\': escaping = True edigits = 0 total = 0 else: - label += c + label += byte_ if escaping: raise BadEscape if len(label) > 0: labels.append(label) else: - labels.append('') - if (len(labels) == 0 or labels[-1] != '') and not origin is None: + labels.append(b'') + if (len(labels) == 0 or labels[-1] != b'') and origin is not None: labels.extend(list(origin.labels)) return Name(labels) + def from_wire(message, current): """Convert possibly compressed wire format into a Name. @param message: the entire DNS message @@ -681,23 +708,23 @@ def from_wire(message, current): @rtype: (dns.name.Name object, int) tuple """ - if not isinstance(message, str): + if not isinstance(message, binary_type): raise ValueError("input to from_wire() must be a byte string") message = dns.wiredata.maybe_wrap(message) labels = [] biggest_pointer = current hops = 0 - count = ord(message[current]) + count = message[current] current += 1 cused = 1 while count != 0: if count < 64: - labels.append(message[current : current + count].unwrap()) + labels.append(message[current: current + count].unwrap()) current += count if hops == 0: cused += count elif count >= 192: - current = (count & 0x3f) * 256 + ord(message[current]) + current = (count & 0x3f) * 256 + message[current] if hops == 0: cused += 1 if current >= biggest_pointer: @@ -706,7 +733,7 @@ def from_wire(message, current): hops += 1 else: raise BadLabelType - count = ord(message[current]) + count = message[current] current += 1 if hops == 0: cused += 1 Index: dnspython-1.12.0/dns/namedict.py =================================================================== --- dnspython-1.12.0.orig/dns/namedict.py +++ dnspython-1.12.0/dns/namedict.py @@ -16,6 +16,7 @@ """DNS name dictionary""" import dns.name +from ._compat import xrange class NameDict(dict): @@ -53,7 +54,10 @@ class NameDict(dict): depth = self.max_depth for i in xrange(-depth, 0): n = dns.name.Name(name[i:]) - if self.has_key(n): + if n in self: return (n, self[n]) v = self[dns.name.empty] return (dns.name.empty, v) + + def has_key(self, key): + return key in self Index: dnspython-1.12.0/dns/node.py =================================================================== --- dnspython-1.12.0.orig/dns/node.py +++ dnspython-1.12.0/dns/node.py @@ -15,13 +15,15 @@ """DNS nodes. A node is a set of rdatasets.""" -import StringIO +from io import StringIO import dns.rdataset import dns.rdatatype import dns.renderer + class Node(object): + """A DNS node. A node is a set of rdatasets @@ -35,7 +37,7 @@ class Node(object): """Initialize a DNS node. """ - self.rdatasets = []; + self.rdatasets = [] def to_text(self, name, **kw): """Convert a node to text format. @@ -47,10 +49,11 @@ class Node(object): @rtype: string """ - s = StringIO.StringIO() + s = StringIO() for rds in self.rdatasets: if len(rds) > 0: - print >> s, rds.to_text(name, **kw) + s.write(rds.to_text(name, **kw)) + s.write(u'\n') return s.getvalue()[:-1] def __repr__(self): @@ -155,7 +158,7 @@ class Node(object): """ rds = self.get_rdataset(rdclass, rdtype, covers) - if not rds is None: + if rds is not None: self.rdatasets.remove(rds) def replace_rdataset(self, replacement): @@ -169,7 +172,7 @@ class Node(object): """ if not isinstance(replacement, dns.rdataset.Rdataset): - raise ValueError, 'replacement is not an rdataset' + raise ValueError('replacement is not an rdataset') self.delete_rdataset(replacement.rdclass, replacement.rdtype, replacement.covers) self.rdatasets.append(replacement) Index: dnspython-1.12.0/dns/opcode.py =================================================================== --- dnspython-1.12.0.orig/dns/opcode.py +++ dnspython-1.12.0/dns/opcode.py @@ -35,7 +35,7 @@ _by_text = { # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that # would cause the mapping not to be true inverse. -_by_value = dict([(y, x) for x, y in _by_text.iteritems()]) +_by_value = dict((y, x) for x, y in _by_text.items()) class UnknownOpcode(dns.exception.DNSException): @@ -60,23 +60,26 @@ def from_text(text): raise UnknownOpcode return value + def from_flags(flags): """Extract an opcode from DNS message flags. @param flags: int @rtype: int """ - + return (flags & 0x7800) >> 11 + def to_flags(value): """Convert an opcode to a value suitable for ORing into DNS message flags. @rtype: int """ - + return (value << 11) & 0x7800 - + + def to_text(value): """Convert an opcode to text. @@ -85,12 +88,13 @@ def to_text(value): @raises UnknownOpcode: the opcode is unknown @rtype: string """ - + text = _by_value.get(value) if text is None: text = str(value) return text + def is_update(flags): """True if the opcode in flags is UPDATE. @@ -98,7 +102,7 @@ def is_update(flags): @type flags: int @rtype: bool """ - + if (from_flags(flags) == UPDATE): return True return False Index: dnspython-1.12.0/dns/query.py =================================================================== --- dnspython-1.12.0.orig/dns/query.py +++ dnspython-1.12.0/dns/query.py @@ -31,6 +31,13 @@ import dns.message import dns.rdataclass import dns.rdatatype +from ._compat import long, string_types + +if sys.version_info > (3,): + select_error = OSError +else: + select_error = select.error + class UnexpectedSource(dns.exception.DNSException): """Raised if a query response comes from an unexpected address or port.""" pass @@ -75,6 +82,7 @@ def _poll_for(fd, readable, writable, er return bool(event_list) + def _select_for(fd, readable, writable, error, timeout): """Select polling backend. @param fd: File descriptor @@ -103,6 +111,7 @@ def _select_for(fd, readable, writable, return bool((rcount or wcount or xcount)) + def _wait_for(fd, readable, writable, error, expiration): done = False while not done: @@ -115,11 +124,12 @@ def _wait_for(fd, readable, writable, er try: if not _polling_backend(fd, readable, writable, error, timeout): raise dns.exception.Timeout - except select.error, e: + except select_error as e: if e.args[0] != errno.EINTR: raise e done = True + def _set_polling_backend(fn): """ Internal API. Do not use. @@ -136,12 +146,15 @@ if hasattr(select, 'poll'): else: _polling_backend = _select_for + def _wait_for_readable(s, expiration): _wait_for(s, True, False, True, expiration) + def _wait_for_writable(s, expiration): _wait_for(s, False, True, True, expiration) + def _addresses_equal(af, a1, a2): # Convert the first value of the tuple, which is a textual format # address into binary form, so that we are not confused by different @@ -150,6 +163,7 @@ def _addresses_equal(af, a1, a2): n2 = dns.inet.inet_pton(af, a2[0]) return n1 == n2 and a1[1:] == a2[1:] + def _destination_and_source(af, where, port, source, source_port): # Apply defaults and compute destination and source tuples # suitable for use in connect(), sendto(), or bind(). @@ -172,6 +186,7 @@ def _destination_and_source(af, where, p source = (source, source_port, 0, 0) return (af, destination, source) + def udp(q, where, timeout=None, port=53, af=None, source=None, source_port=0, ignore_unexpected=False, one_rr_per_rrset=False): """Return the response obtained after sending a query via UDP. @@ -203,8 +218,8 @@ def udp(q, where, timeout=None, port=53, """ wire = q.to_wire() - (af, destination, source) = _destination_and_source(af, where, port, source, - source_port) + (af, destination, source) = _destination_and_source(af, where, port, + source, source_port) s = socket.socket(af, socket.SOCK_DGRAM, 0) try: expiration = _compute_expiration(timeout) @@ -217,8 +232,8 @@ def udp(q, where, timeout=None, port=53, _wait_for_readable(s, expiration) (wire, from_address) = s.recvfrom(65535) if _addresses_equal(af, from_address, destination) or \ - (dns.inet.is_multicast(where) and \ - from_address[1:] == destination[1:]): + (dns.inet.is_multicast(where) and + from_address[1:] == destination[1:]): break if not ignore_unexpected: raise UnexpectedSource('got a response from ' @@ -232,6 +247,7 @@ def udp(q, where, timeout=None, port=53, raise BadResponse return r + def _net_read(sock, count, expiration): """Read the specified number of bytes from sock. Keep trying until we either get the desired amount, or we hit EOF. @@ -248,6 +264,7 @@ def _net_read(sock, count, expiration): s = s + n return s + def _net_write(sock, data, expiration): """Write the specified data to the socket. A Timeout exception will be raised if the operation is not completed @@ -259,16 +276,18 @@ def _net_write(sock, data, expiration): _wait_for_writable(sock, expiration) current += sock.send(data[current:]) + def _connect(s, address): try: s.connect(address) except socket.error: (ty, v) = sys.exc_info()[:2] if v[0] != errno.EINPROGRESS and \ - v[0] != errno.EWOULDBLOCK and \ - v[0] != errno.EALREADY: + v[0] != errno.EWOULDBLOCK and \ + v[0] != errno.EALREADY: raise v + def tcp(q, where, timeout=None, port=53, af=None, source=None, source_port=0, one_rr_per_rrset=False): """Return the response obtained after sending a query via TCP. @@ -297,8 +316,8 @@ def tcp(q, where, timeout=None, port=53, """ wire = q.to_wire() - (af, destination, source) = _destination_and_source(af, where, port, source, - source_port) + (af, destination, source) = _destination_and_source(af, where, port, + source, source_port) s = socket.socket(af, socket.SOCK_STREAM, 0) try: expiration = _compute_expiration(timeout) @@ -325,6 +344,7 @@ def tcp(q, where, timeout=None, port=53, raise BadResponse return r + def xfr(where, zone, rdtype=dns.rdatatype.AXFR, rdclass=dns.rdataclass.IN, timeout=None, port=53, keyring=None, keyname=None, relativize=True, af=None, lifetime=None, source=None, source_port=0, serial=0, @@ -378,20 +398,20 @@ def xfr(where, zone, rdtype=dns.rdatatyp @type keyalgorithm: string """ - if isinstance(zone, (str, unicode)): + if isinstance(zone, string_types): zone = dns.name.from_text(zone) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) q = dns.message.make_query(zone, rdtype, rdclass) if rdtype == dns.rdatatype.IXFR: rrset = dns.rrset.from_text(zone, 0, 'IN', 'SOA', '. . %u 0 0 0 0' % serial) q.authority.append(rrset) - if not keyring is None: + if keyring is not None: q.use_tsig(keyring, keyname, algorithm=keyalgorithm) wire = q.to_wire() - (af, destination, source) = _destination_and_source(af, where, port, source, - source_port) + (af, destination, source) = _destination_and_source(af, where, port, + source, source_port) if use_udp: if rdtype != dns.rdatatype.IXFR: raise ValueError('cannot do a UDP AXFR') @@ -414,7 +434,6 @@ def xfr(where, zone, rdtype=dns.rdatatyp delete_mode = True expecting_SOA = False soa_rrset = None - soa_count = 0 if relativize: origin = zone oname = dns.name.empty @@ -434,16 +453,18 @@ def xfr(where, zone, rdtype=dns.rdatatyp ldata = _net_read(s, 2, mexpiration) (l,) = struct.unpack("!H", ldata) wire = _net_read(s, l, mexpiration) + is_ixfr = (rdtype == dns.rdatatype.IXFR) r = dns.message.from_wire(wire, keyring=q.keyring, request_mac=q.mac, xfr=True, origin=origin, tsig_ctx=tsig_ctx, multi=True, first=first, - one_rr_per_rrset=(rdtype==dns.rdatatype.IXFR)) + one_rr_per_rrset=is_ixfr) tsig_ctx = r.tsig_ctx first = False answer_index = 0 if soa_rrset is None: if not r.answer or r.answer[0].name != oname: - raise dns.exception.FormError("No answer or RRset not for qname") + raise dns.exception.FormError( + "No answer or RRset not for qname") rrset = r.answer[0] if rrset.rdtype != dns.rdatatype.SOA: raise dns.exception.FormError("first RRset is not an SOA") @@ -467,7 +488,8 @@ def xfr(where, zone, rdtype=dns.rdatatyp if rrset.rdtype == dns.rdatatype.SOA and rrset.name == oname: if expecting_SOA: if rrset[0].serial != serial: - raise dns.exception.FormError("IXFR base serial mismatch") + raise dns.exception.FormError( + "IXFR base serial mismatch") expecting_SOA = False elif rdtype == dns.rdatatype.IXFR: delete_mode = not delete_mode @@ -477,8 +499,8 @@ def xfr(where, zone, rdtype=dns.rdatatyp # the record in the expected part of the response. # if rrset == soa_rrset and \ - (rdtype == dns.rdatatype.AXFR or \ - (rdtype == dns.rdatatype.IXFR and delete_mode)): + (rdtype == dns.rdatatype.AXFR or + (rdtype == dns.rdatatype.IXFR and delete_mode)): done = True elif expecting_SOA: # Index: dnspython-1.12.0/dns/rcode.py =================================================================== --- dnspython-1.12.0.orig/dns/rcode.py +++ dnspython-1.12.0/dns/rcode.py @@ -16,6 +16,8 @@ """DNS Result Codes.""" import dns.exception +from ._compat import long + NOERROR = 0 FORMERR = 1 @@ -49,7 +51,7 @@ _by_text = { # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that # would cause the mapping not to be a true inverse. -_by_value = dict([(y, x) for x, y in _by_text.iteritems()]) +_by_value = dict((y, x) for x, y in _by_text.items()) class UnknownRcode(dns.exception.DNSException): @@ -74,6 +76,7 @@ def from_text(text): raise UnknownRcode return v + def from_flags(flags, ednsflags): """Return the rcode value encoded by flags and ednsflags. @@ -90,6 +93,7 @@ def from_flags(flags, ednsflags): raise ValueError('rcode must be >= 0 and <= 4095') return value + def to_flags(value): """Return a (flags, ednsflags) tuple which encodes the rcode. @@ -105,6 +109,7 @@ def to_flags(value): ev = long(value & 0xff0) << 20 return (v, ev) + def to_text(value): """Convert rcode into text. Index: dnspython-1.12.0/dns/rdata.py =================================================================== --- dnspython-1.12.0.orig/dns/rdata.py +++ dnspython-1.12.0/dns/rdata.py @@ -25,7 +25,10 @@ default is 'dns.rdtypes'. Changing this chunk of hexstring that _hexify() produces before whitespace occurs. @type _hex_chunk: int""" -import cStringIO +from io import BytesIO +import base64 +import binascii +import struct import dns.exception import dns.name @@ -33,10 +36,14 @@ import dns.rdataclass import dns.rdatatype import dns.tokenizer import dns.wiredata +from ._compat import xrange, string_types, text_type, binary_type + +from ._compat import xcmp _hex_chunksize = 32 -def _hexify(data, chunksize=None): + +def _hexify(data, chunksize=_hex_chunksize): """Convert a binary string into its hex encoding, broken up into chunks of I{chunksize} characters separated by a space. @@ -46,22 +53,15 @@ def _hexify(data, chunksize=None): @rtype: string """ - if chunksize is None: - chunksize = _hex_chunksize - hex = data.encode('hex_codec') - l = len(hex) - if l > chunksize: - chunks = [] - i = 0 - while i < l: - chunks.append(hex[i : i + chunksize]) - i += chunksize - hex = ' '.join(chunks) - return hex + line = binascii.hexlify(data) + return b' '.join([line[i:i + chunksize] + for i + in range(0, len(line), chunksize)]).decode() _base64_chunksize = 32 -def _base64ify(data, chunksize=None): + +def _base64ify(data, chunksize=_base64_chunksize): """Convert a binary string into its base64 encoding, broken up into chunks of I{chunksize} characters separated by a space. @@ -72,24 +72,16 @@ def _base64ify(data, chunksize=None): @rtype: string """ - if chunksize is None: - chunksize = _base64_chunksize - b64 = data.encode('base64_codec') - b64 = b64.replace('\n', '') - l = len(b64) - if l > chunksize: - chunks = [] - i = 0 - while i < l: - chunks.append(b64[i : i + chunksize]) - i += chunksize - b64 = ' '.join(chunks) - return b64 + line = base64.b64encode(data) + return b' '.join([line[i:i + chunksize] + for i + in range(0, len(line), chunksize)]).decode() __escaped = { - '"' : True, - '\\' : True, - } + '"': True, + '\\': True, +} + def _escapify(qstring): """Escape the characters in a quoted string which need it. @@ -100,16 +92,23 @@ def _escapify(qstring): @rtype: string """ + if isinstance(qstring, text_type): + qstring = qstring.encode() + if not isinstance(qstring, bytearray): + qstring = bytearray(qstring) + text = '' for c in qstring: - if c in __escaped: - text += '\\' + c - elif ord(c) >= 0x20 and ord(c) < 0x7F: - text += c + packed = struct.pack('!B', c).decode() + if packed in __escaped: + text += '\\' + packed + elif c >= 0x20 and c < 0x7F: + text += packed else: - text += '\\%03d' % ord(c) + text += '\\%03d' % c return text + def _truncate_bitmap(what): """Determine the index of greatest byte that isn't all zeros, and return the bitmap that contains all the bytes less than that index. @@ -120,11 +119,13 @@ def _truncate_bitmap(what): """ for i in xrange(len(what) - 1, -1, -1): - if what[i] != '\x00': + if what[i] != 0: break - return ''.join(what[0 : i + 1]) + return what[0: i + 1] + class Rdata(object): + """Base class for all DNS rdata types. """ @@ -167,17 +168,17 @@ class Rdata(object): """ raise NotImplementedError - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): """Convert an rdata to wire format. @rtype: string """ raise NotImplementedError - def to_digestable(self, origin = None): + def to_digestable(self, origin=None): """Convert rdata to a format suitable for digesting in hashes. This is also the DNSSEC canonical form.""" - f = cStringIO.StringIO() + f = BytesIO() self.to_wire(f, None, origin) return f.getvalue() @@ -264,11 +265,11 @@ class Rdata(object): # We specifiy an arbitrary origin of '.' when doing the # comparison, since the rdata may have relative names and we # can't convert a relative name to wire without an origin. - b1 = cStringIO.StringIO() + b1 = BytesIO() self.to_wire(b1, None, dns.name.root) - b2 = cStringIO.StringIO() + b2 = BytesIO() other.to_wire(b2, None, dns.name.root) - return cmp(b1.getvalue(), b2.getvalue()) + return xcmp(b1.getvalue(), b2.getvalue()) def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): """Build an rdata object from text format. @@ -288,9 +289,8 @@ class Rdata(object): raise NotImplementedError - from_text = classmethod(from_text) - - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): """Build an rdata object from wire format @param rdclass: The rdata class @@ -310,9 +310,7 @@ class Rdata(object): raise NotImplementedError - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): """Convert any domain names in the rdata to the specified relativization. """ @@ -321,6 +319,7 @@ class Rdata(object): class GenericRdata(Rdata): + """Generate Rdata Class This class is used for rdata types for which we have no better @@ -336,6 +335,7 @@ class GenericRdata(Rdata): def to_text(self, origin=None, relativize=True, **kw): return r'\# %d ' % len(self.data) + _hexify(self.data) + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): token = tok.get() if not token.is_identifier() or token.value != '\#': @@ -346,25 +346,22 @@ class GenericRdata(Rdata): token = tok.get() if token.is_eol_or_eof(): break - chunks.append(token.value) - hex = ''.join(chunks) - data = hex.decode('hex_codec') + chunks.append(token.value.encode()) + hex = b''.join(chunks) + data = binascii.unhexlify(hex) if len(data) != length: raise dns.exception.SyntaxError('generic rdata hex data has wrong length') return cls(rdclass, rdtype, data) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): file.write(self.data) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): return cls(rdclass, rdtype, wire[current : current + rdlen]) - from_wire = classmethod(from_wire) - def _cmp(self, other): - return cmp(self.data, other.data) + return xcmp(self.data, other.data) _rdata_modules = {} _module_prefix = 'dns.rdtypes' @@ -402,7 +399,8 @@ def get_rdata_class(rdclass, rdtype): cls = GenericRdata return cls -def from_text(rdclass, rdtype, tok, origin = None, relativize = True): + +def from_text(rdclass, rdtype, tok, origin=None, relativize=True): """Build an rdata object from text format. This function attempts to dynamically load a class which @@ -428,7 +426,7 @@ def from_text(rdclass, rdtype, tok, orig @type relativize: bool @rtype: dns.rdata.Rdata instance""" - if isinstance(tok, str): + if isinstance(tok, (text_type, binary_type)): tok = dns.tokenizer.Tokenizer(tok) cls = get_rdata_class(rdclass, rdtype) if cls != GenericRdata: @@ -448,7 +446,8 @@ def from_text(rdclass, rdtype, tok, orig origin) return cls.from_text(rdclass, rdtype, tok, origin, relativize) -def from_wire(rdclass, rdtype, wire, current, rdlen, origin = None): + +def from_wire(rdclass, rdtype, wire, current, rdlen, origin=None): """Build an rdata object from wire format This function attempts to dynamically load a class which Index: dnspython-1.12.0/dns/rdataclass.py =================================================================== --- dnspython-1.12.0.orig/dns/rdataclass.py +++ dnspython-1.12.0/dns/rdataclass.py @@ -47,7 +47,7 @@ _by_text = { # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that # would cause the mapping not to be true inverse. -_by_value = dict([(y, x) for x, y in _by_text.iteritems()]) +_by_value = dict((y, x) for x, y in _by_text.items()) # Now that we've built the inverse map, we can add class aliases to # the _by_text mapping. @@ -81,13 +81,14 @@ def from_text(text): value = _by_text.get(text.upper()) if value is None: match = _unknown_class_pattern.match(text) - if match == None: + if match is None: raise UnknownRdataclass value = int(match.group(1)) if value < 0 or value > 65535: raise ValueError("class must be between >= 0 and <= 65535") return value + def to_text(value): """Convert a DNS rdata class to text. @param value: the rdata class value @@ -100,15 +101,16 @@ def to_text(value): raise ValueError("class must be between >= 0 and <= 65535") text = _by_value.get(value) if text is None: - text = 'CLASS' + `value` + text = 'CLASS' + repr(value) return text + def is_metaclass(rdclass): """True if the class is a metaclass. @param rdclass: the rdata class @type rdclass: int @rtype: bool""" - if _metaclasses.has_key(rdclass): + if rdclass in _metaclasses: return True return False Index: dnspython-1.12.0/dns/rdataset.py =================================================================== --- dnspython-1.12.0.orig/dns/rdataset.py +++ dnspython-1.12.0/dns/rdataset.py @@ -16,7 +16,7 @@ """DNS rdatasets (an rdataset is a set of rdatas of a given type and class)""" import random -import StringIO +from io import StringIO import struct import dns.exception @@ -24,6 +24,7 @@ import dns.rdatatype import dns.rdataclass import dns.rdata import dns.set +from ._compat import string_types # define SimpleSet here for backwards compatibility SimpleSet = dns.set.Set @@ -110,7 +111,7 @@ class Rdataset(dns.set.Set): # if self.rdclass != rd.rdclass or self.rdtype != rd.rdtype: raise IncompatibleTypes - if not ttl is None: + if ttl is not None: self.update_ttl(ttl) if self.rdtype == dns.rdatatype.RRSIG or \ self.rdtype == dns.rdatatype.SIG: @@ -185,15 +186,15 @@ class Rdataset(dns.set.Set): @type origin: dns.name.Name object @param relativize: True if names should names be relativized @type relativize: bool""" - if not name is None: + if name is not None: name = name.choose_relativity(origin, relativize) ntext = str(name) pad = ' ' else: ntext = '' pad = '' - s = StringIO.StringIO() - if not override_rdclass is None: + s = StringIO() + if override_rdclass is not None: rdclass = override_rdclass else: rdclass = self.rdclass @@ -203,15 +204,16 @@ class Rdataset(dns.set.Set): # some dynamic updates, so we don't need to print out the TTL # (which is meaningless anyway). # - print >> s, '%s%s%s %s' % (ntext, pad, - dns.rdataclass.to_text(rdclass), - dns.rdatatype.to_text(self.rdtype)) + s.write(u'%s%s%s %s\n' % (ntext, pad, + dns.rdataclass.to_text(rdclass), + dns.rdatatype.to_text(self.rdtype))) else: for rd in self: - print >> s, '%s%s%d %s %s %s' % \ - (ntext, pad, self.ttl, dns.rdataclass.to_text(rdclass), - dns.rdatatype.to_text(self.rdtype), - rd.to_text(origin=origin, relativize=relativize, **kw)) + s.write(u'%s%s%d %s %s %s\n' % + (ntext, pad, self.ttl, dns.rdataclass.to_text(rdclass), + dns.rdatatype.to_text(self.rdtype), + rd.to_text(origin=origin, relativize=relativize, + **kw))) # # We strip off the final \n for the caller's convenience in printing # @@ -233,8 +235,8 @@ class Rdataset(dns.set.Set): @rtype: int """ - if not override_rdclass is None: - rdclass = override_rdclass + if override_rdclass is not None: + rdclass = override_rdclass want_shuffle = False else: rdclass = self.rdclass @@ -274,6 +276,7 @@ class Rdataset(dns.set.Set): return True return False + def from_text_list(rdclass, rdtype, ttl, text_rdatas): """Create an rdataset with the specified class, type, and TTL, and with the specified list of rdatas in text format. @@ -281,9 +284,9 @@ def from_text_list(rdclass, rdtype, ttl, @rtype: dns.rdataset.Rdataset object """ - if isinstance(rdclass, (str, unicode)): + if isinstance(rdclass, string_types): rdclass = dns.rdataclass.from_text(rdclass) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) r = Rdataset(rdclass, rdtype) r.update_ttl(ttl) @@ -292,6 +295,7 @@ def from_text_list(rdclass, rdtype, ttl, r.add(rd) return r + def from_text(rdclass, rdtype, ttl, *text_rdatas): """Create an rdataset with the specified class, type, and TTL, and with the specified rdatas in text format. @@ -301,6 +305,7 @@ def from_text(rdclass, rdtype, ttl, *tex return from_text_list(rdclass, rdtype, ttl, text_rdatas) + def from_rdata_list(ttl, rdatas): """Create an rdataset with the specified TTL, and with the specified list of rdata objects. @@ -315,10 +320,10 @@ def from_rdata_list(ttl, rdatas): if r is None: r = Rdataset(rd.rdclass, rd.rdtype) r.update_ttl(ttl) - first_time = False r.add(rd) return r + def from_rdata(ttl, *rdatas): """Create an rdataset with the specified TTL, and with the specified rdata objects. Index: dnspython-1.12.0/dns/rdatatype.py =================================================================== --- dnspython-1.12.0.orig/dns/rdatatype.py +++ dnspython-1.12.0/dns/rdatatype.py @@ -160,7 +160,7 @@ _by_text = { # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that # would cause the mapping not to be true inverse. -_by_value = dict([(y, x) for x, y in _by_text.iteritems()]) +_by_value = dict((y, x) for x, y in _by_text.items()) _metatypes = { @@ -192,13 +192,14 @@ def from_text(text): value = _by_text.get(text.upper()) if value is None: match = _unknown_type_pattern.match(text) - if match == None: + if match is None: raise UnknownRdatatype value = int(match.group(1)) if value < 0 or value > 65535: raise ValueError("type must be between >= 0 and <= 65535") return value + def to_text(value): """Convert a DNS rdata type to text. @param value: the rdata type value @@ -210,25 +211,27 @@ def to_text(value): raise ValueError("type must be between >= 0 and <= 65535") text = _by_value.get(value) if text is None: - text = 'TYPE' + `value` + text = 'TYPE' + repr(value) return text + def is_metatype(rdtype): """True if the type is a metatype. @param rdtype: the type @type rdtype: int @rtype: bool""" - if rdtype >= TKEY and rdtype <= ANY or _metatypes.has_key(rdtype): + if rdtype >= TKEY and rdtype <= ANY or rdtype in _metatypes: return True return False + def is_singleton(rdtype): """True if the type is a singleton. @param rdtype: the type @type rdtype: int @rtype: bool""" - if _singletons.has_key(rdtype): + if rdtype in _singletons: return True return False Index: dnspython-1.12.0/dns/rdtypes/ANY/AFSDB.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/AFSDB.py +++ dnspython-1.12.0/dns/rdtypes/ANY/AFSDB.py @@ -15,7 +15,9 @@ import dns.rdtypes.mxbase + class AFSDB(dns.rdtypes.mxbase.UncompressedDowncasingMX): + """AFSDB record @ivar subtype: the subtype value Index: dnspython-1.12.0/dns/rdtypes/ANY/CERT.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/CERT.py +++ dnspython-1.12.0/dns/rdtypes/ANY/CERT.py @@ -13,43 +13,49 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO import struct +import base64 import dns.exception import dns.dnssec import dns.rdata import dns.tokenizer +from io import BytesIO +from dns._compat import xcmp _ctype_by_value = { - 1 : 'PKIX', - 2 : 'SPKI', - 3 : 'PGP', - 253 : 'URI', - 254 : 'OID', - } + 1: 'PKIX', + 2: 'SPKI', + 3: 'PGP', + 253: 'URI', + 254: 'OID', +} _ctype_by_name = { - 'PKIX' : 1, - 'SPKI' : 2, - 'PGP' : 3, - 'URI' : 253, - 'OID' : 254, - } + 'PKIX': 1, + 'SPKI': 2, + 'PGP': 3, + 'URI': 253, + 'OID': 254, +} + def _ctype_from_text(what): v = _ctype_by_name.get(what) - if not v is None: + if v is not None: return v return int(what) + def _ctype_to_text(what): v = _ctype_by_value.get(what) - if not v is None: + if v is not None: return v return str(what) + class CERT(dns.rdata.Rdata): + """CERT record @ivar certificate_type: certificate type @@ -78,7 +84,8 @@ class CERT(dns.rdata.Rdata): dns.dnssec.algorithm_to_text(self.algorithm), dns.rdata._base64ify(self.certificate)) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): certificate_type = _ctype_from_text(tok.get_string()) key_tag = tok.get_uint16() algorithm = dns.dnssec.algorithm_from_text(tok.get_string()) @@ -91,35 +98,32 @@ class CERT(dns.rdata.Rdata): break if not t.is_identifier(): raise dns.exception.SyntaxError - chunks.append(t.value) - b64 = ''.join(chunks) - certificate = b64.decode('base64_codec') + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + certificate = base64.b64decode(b64) return cls(rdclass, rdtype, certificate_type, key_tag, algorithm, certificate) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): prefix = struct.pack("!HHB", self.certificate_type, self.key_tag, self.algorithm) file.write(prefix) file.write(self.certificate) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - prefix = wire[current : current + 5].unwrap() + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + prefix = wire[current: current + 5].unwrap() current += 5 rdlen -= 5 if rdlen < 0: raise dns.exception.FormError (certificate_type, key_tag, algorithm) = struct.unpack("!HHB", prefix) - certificate = wire[current : current + rdlen].unwrap() + certificate = wire[current: current + rdlen].unwrap() return cls(rdclass, rdtype, certificate_type, key_tag, algorithm, certificate) - from_wire = classmethod(from_wire) - def _cmp(self, other): - f = cStringIO.StringIO() + f = BytesIO() self.to_wire(f) wire1 = f.getvalue() f.seek(0) @@ -128,4 +132,4 @@ class CERT(dns.rdata.Rdata): wire2 = f.getvalue() f.close() - return cmp(wire1, wire2) + return xcmp(wire1, wire2) Index: dnspython-1.12.0/dns/rdtypes/ANY/CNAME.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/CNAME.py +++ dnspython-1.12.0/dns/rdtypes/ANY/CNAME.py @@ -15,7 +15,9 @@ import dns.rdtypes.nsbase + class CNAME(dns.rdtypes.nsbase.NSBase): + """CNAME record Note: although CNAME is officially a singleton type, dnspython allows Index: dnspython-1.12.0/dns/rdtypes/ANY/DLV.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/DLV.py +++ dnspython-1.12.0/dns/rdtypes/ANY/DLV.py @@ -15,6 +15,8 @@ import dns.rdtypes.dsbase + class DLV(dns.rdtypes.dsbase.DSBase): + """DLV record""" pass Index: dnspython-1.12.0/dns/rdtypes/ANY/DNAME.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/DNAME.py +++ dnspython-1.12.0/dns/rdtypes/ANY/DNAME.py @@ -15,7 +15,10 @@ import dns.rdtypes.nsbase + class DNAME(dns.rdtypes.nsbase.UncompressedNS): + """DNAME record""" - def to_digestable(self, origin = None): + + def to_digestable(self, origin=None): return self.target.to_digestable(origin) Index: dnspython-1.12.0/dns/rdtypes/ANY/DNSKEY.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/DNSKEY.py +++ dnspython-1.12.0/dns/rdtypes/ANY/DNSKEY.py @@ -20,6 +20,9 @@ import dns.exception import dns.dnssec import dns.rdata +import base64 +from dns._compat import xcmp + # flag constants SEP = 0x0001 @@ -35,7 +38,7 @@ _flag_by_text = { # We construct the inverse mapping programmatically to ensure that we # cannot make any mistakes (e.g. omissions, cut-and-paste errors) that # would cause the mapping not to be true inverse. -_flag_by_value = dict([(y, x) for x, y in _flag_by_text.iteritems()]) +_flag_by_value = dict([(y, x) for x, y in _flag_by_text.items()]) def flags_to_text_set(flags): @@ -93,6 +96,7 @@ class DNSKEY(dns.rdata.Rdata): return '%d %d %d %s' % (self.flags, self.protocol, self.algorithm, dns.rdata._base64ify(self.key)) + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): flags = tok.get_uint16() protocol = tok.get_uint8() @@ -104,18 +108,17 @@ class DNSKEY(dns.rdata.Rdata): break if not t.is_identifier(): raise dns.exception.SyntaxError - chunks.append(t.value) - b64 = ''.join(chunks) - key = b64.decode('base64_codec') + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + key = base64.b64decode(b64) return cls(rdclass, rdtype, flags, protocol, algorithm, key) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): header = struct.pack("!HBB", self.flags, self.protocol, self.algorithm) file.write(header) file.write(self.key) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): if rdlen < 4: raise dns.exception.FormError @@ -126,14 +129,12 @@ class DNSKEY(dns.rdata.Rdata): return cls(rdclass, rdtype, header[0], header[1], header[2], key) - from_wire = classmethod(from_wire) - def _cmp(self, other): hs = struct.pack("!HBB", self.flags, self.protocol, self.algorithm) ho = struct.pack("!HBB", other.flags, other.protocol, other.algorithm) - v = cmp(hs, ho) + v = xcmp(hs, ho) if v == 0: - v = cmp(self.key, other.key) + v = xcmp(self.key, other.key) return v def flags_to_text_set(self): Index: dnspython-1.12.0/dns/rdtypes/ANY/DS.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/DS.py +++ dnspython-1.12.0/dns/rdtypes/ANY/DS.py @@ -15,6 +15,8 @@ import dns.rdtypes.dsbase + class DS(dns.rdtypes.dsbase.DSBase): + """DS record""" pass Index: dnspython-1.12.0/dns/rdtypes/ANY/GPOS.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/GPOS.py +++ dnspython-1.12.0/dns/rdtypes/ANY/GPOS.py @@ -13,24 +13,37 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import struct + import dns.exception import dns.rdata import dns.tokenizer +from dns._compat import long, text_type +from dns._compat import xcmp + def _validate_float_string(what): - if what[0] == '-' or what[0] == '+': + if what[0] == b'-'[0] or what[0] == b'+'[0]: what = what[1:] if what.isdigit(): return - (left, right) = what.split('.') - if left == '' and right == '': + (left, right) = what.split(b'.') + if left == b'' and right == b'': raise dns.exception.FormError - if not left == '' and not left.isdigit(): + if not left == b'' and not left.decode().isdigit(): raise dns.exception.FormError - if not right == '' and not right.isdigit(): + if not right == b'' and not right.decode().isdigit(): raise dns.exception.FormError + +def _sanitize(value): + if isinstance(value, text_type): + return value.encode() + return value + + class GPOS(dns.rdata.Rdata): + """GPOS record @ivar latitude: latitude @@ -57,6 +70,9 @@ class GPOS(dns.rdata.Rdata): isinstance(altitude, int) or \ isinstance(altitude, long): altitude = str(altitude) + latitude = _sanitize(latitude) + longitude = _sanitize(longitude) + altitude = _sanitize(altitude) _validate_float_string(latitude) _validate_float_string(longitude) _validate_float_string(altitude) @@ -65,8 +81,11 @@ class GPOS(dns.rdata.Rdata): self.altitude = altitude def to_text(self, origin=None, relativize=True, **kw): - return '%s %s %s' % (self.latitude, self.longitude, self.altitude) + return '%s %s %s' % (self.latitude.decode(), + self.longitude.decode(), + self.altitude.decode()) + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): latitude = tok.get_string() longitude = tok.get_string() @@ -74,27 +93,23 @@ class GPOS(dns.rdata.Rdata): tok.get_eol() return cls(rdclass, rdtype, latitude, longitude, altitude) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): l = len(self.latitude) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(self.latitude) l = len(self.longitude) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(self.longitude) l = len(self.altitude) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(self.altitude) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l > rdlen: @@ -102,7 +117,7 @@ class GPOS(dns.rdata.Rdata): latitude = wire[current : current + l].unwrap() current += l rdlen -= l - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l > rdlen: @@ -110,7 +125,7 @@ class GPOS(dns.rdata.Rdata): longitude = wire[current : current + l].unwrap() current += l rdlen -= l - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l != rdlen: @@ -118,14 +133,12 @@ class GPOS(dns.rdata.Rdata): altitude = wire[current : current + l].unwrap() return cls(rdclass, rdtype, latitude, longitude, altitude) - from_wire = classmethod(from_wire) - def _cmp(self, other): - v = cmp(self.latitude, other.latitude) + v = xcmp(self.latitude, other.latitude) if v == 0: - v = cmp(self.longitude, other.longitude) + v = xcmp(self.longitude, other.longitude) if v == 0: - v = cmp(self.altitude, other.altitude) + v = xcmp(self.altitude, other.altitude) return v def _get_float_latitude(self): Index: dnspython-1.12.0/dns/rdtypes/ANY/HINFO.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/HINFO.py +++ dnspython-1.12.0/dns/rdtypes/ANY/HINFO.py @@ -13,11 +13,17 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import struct + import dns.exception import dns.rdata import dns.tokenizer +from dns._compat import text_type +from dns._compat import xcmp + class HINFO(dns.rdata.Rdata): + """HINFO record @ivar cpu: the CPU type @@ -30,35 +36,39 @@ class HINFO(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, cpu, os): super(HINFO, self).__init__(rdclass, rdtype) - self.cpu = cpu - self.os = os + if isinstance(cpu, text_type): + self.cpu = cpu.encode() + else: + self.cpu = cpu + if isinstance(os, text_type): + self.os = os.encode() + else: + self.os = os def to_text(self, origin=None, relativize=True, **kw): return '"%s" "%s"' % (dns.rdata._escapify(self.cpu), dns.rdata._escapify(self.os)) + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): cpu = tok.get_string() os = tok.get_string() tok.get_eol() return cls(rdclass, rdtype, cpu, os) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): l = len(self.cpu) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(self.cpu) l = len(self.os) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(self.os) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l > rdlen: @@ -66,7 +76,7 @@ class HINFO(dns.rdata.Rdata): cpu = wire[current : current + l].unwrap() current += l rdlen -= l - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l != rdlen: @@ -74,10 +84,8 @@ class HINFO(dns.rdata.Rdata): os = wire[current : current + l].unwrap() return cls(rdclass, rdtype, cpu, os) - from_wire = classmethod(from_wire) - def _cmp(self, other): - v = cmp(self.cpu, other.cpu) + v = xcmp(self.cpu, other.cpu) if v == 0: - v = cmp(self.os, other.os) + v = xcmp(self.os, other.os) return v Index: dnspython-1.12.0/dns/rdtypes/ANY/HIP.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/HIP.py +++ dnspython-1.12.0/dns/rdtypes/ANY/HIP.py @@ -13,15 +13,19 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO -import string import struct +import base64 +import binascii import dns.exception import dns.rdata import dns.rdatatype +from io import BytesIO +from dns._compat import xcmp + class HIP(dns.rdata.Rdata): + """HIP record @ivar hit: the host identity tag @@ -44,22 +48,23 @@ class HIP(dns.rdata.Rdata): self.servers = servers def to_text(self, origin=None, relativize=True, **kw): - hit = self.hit.encode('hex-codec') - key = self.key.encode('base64-codec').replace('\n', '') - text = '' + hit = binascii.hexlify(self.hit).decode() + key = base64.b64encode(self.key).replace(b'\n', b'').decode() + text = u'' servers = [] for server in self.servers: - servers.append(str(server.choose_relativity(origin, relativize))) + servers.append(server.choose_relativity(origin, relativize)) if len(servers) > 0: - text += (' ' + ' '.join(servers)) - return '%u %s %s%s' % (self.algorithm, hit, key, text) + text += (u' ' + u' '.join(map(lambda x: x.to_unicode(), servers))) + return u'%u %s %s%s' % (self.algorithm, hit, key, text) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): algorithm = tok.get_uint8() - hit = tok.get_string().decode('hex-codec') + hit = binascii.unhexlify(tok.get_string().encode()) if len(hit) > 255: raise dns.exception.SyntaxError("HIT too long") - key = tok.get_string().decode('base64-codec') + key = base64.b64decode(tok.get_string().encode()) servers = [] while 1: token = tok.get() @@ -70,9 +75,7 @@ class HIP(dns.rdata.Rdata): servers.append(server) return cls(rdclass, rdtype, hit, algorithm, key, servers) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): lh = len(self.hit) lk = len(self.key) file.write(struct.pack("!BBH", lh, self.algorithm, lk)) @@ -81,15 +84,16 @@ class HIP(dns.rdata.Rdata): for server in self.servers: server.to_wire(file, None, origin) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (lh, algorithm, lk) = struct.unpack('!BBH', - wire[current : current + 4]) + wire[current: current + 4]) current += 4 rdlen -= 4 - hit = wire[current : current + lh].unwrap() + hit = wire[current: current + lh].unwrap() current += lh rdlen -= lh - key = wire[current : current + lk].unwrap() + key = wire[current: current + lk].unwrap() current += lk rdlen -= lk servers = [] @@ -98,14 +102,12 @@ class HIP(dns.rdata.Rdata): current) current += cused rdlen -= cused - if not origin is None: + if origin is not None: server = server.relativize(origin) servers.append(server) return cls(rdclass, rdtype, hit, algorithm, key, servers) - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): servers = [] for server in self.servers: server = server.choose_relativity(origin, relativize) @@ -113,19 +115,19 @@ class HIP(dns.rdata.Rdata): self.servers = servers def _cmp(self, other): - b1 = cStringIO.StringIO() + b1 = BytesIO() lh = len(self.hit) lk = len(self.key) b1.write(struct.pack("!BBH", lh, self.algorithm, lk)) b1.write(self.hit) b1.write(self.key) - b2 = cStringIO.StringIO() + b2 = BytesIO() lh = len(other.hit) lk = len(other.key) b2.write(struct.pack("!BBH", lh, other.algorithm, lk)) b2.write(other.hit) b2.write(other.key) - v = cmp(b1.getvalue(), b2.getvalue()) + v = xcmp(b1.getvalue(), b2.getvalue()) if v != 0: return v ls = len(self.servers) @@ -133,7 +135,7 @@ class HIP(dns.rdata.Rdata): count = min(ls, lo) i = 0 while i < count: - v = cmp(self.servers[i], other.servers[i]) + v = xcmp(self.servers[i], other.servers[i]) if v != 0: return v i += 1 Index: dnspython-1.12.0/dns/rdtypes/ANY/ISDN.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/ISDN.py +++ dnspython-1.12.0/dns/rdtypes/ANY/ISDN.py @@ -13,11 +13,17 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import struct + import dns.exception import dns.rdata import dns.tokenizer +from dns._compat import text_type +from dns._compat import xcmp + class ISDN(dns.rdata.Rdata): + """ISDN record @ivar address: the ISDN address @@ -30,8 +36,14 @@ class ISDN(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, address, subaddress): super(ISDN, self).__init__(rdclass, rdtype) - self.address = address - self.subaddress = subaddress + if isinstance(address, text_type): + self.address = address.encode() + else: + self.address = address + if isinstance(address, text_type): + self.subaddress = subaddress.encode() + else: + self.subaddress = subaddress def to_text(self, origin=None, relativize=True, **kw): if self.subaddress: @@ -40,7 +52,8 @@ class ISDN(dns.rdata.Rdata): else: return '"%s"' % dns.rdata._escapify(self.address) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): address = tok.get_string() t = tok.get() if not t.is_eol_or_eof(): @@ -52,23 +65,20 @@ class ISDN(dns.rdata.Rdata): tok.get_eol() return cls(rdclass, rdtype, address, subaddress) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): l = len(self.address) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(self.address) l = len(self.subaddress) if l > 0: assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(self.subaddress) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l > rdlen: @@ -77,7 +87,7 @@ class ISDN(dns.rdata.Rdata): current += l rdlen -= l if rdlen > 0: - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l != rdlen: @@ -87,10 +97,8 @@ class ISDN(dns.rdata.Rdata): subaddress = '' return cls(rdclass, rdtype, address, subaddress) - from_wire = classmethod(from_wire) - def _cmp(self, other): - v = cmp(self.address, other.address) + v = xcmp(self.address, other.address) if v == 0: - v = cmp(self.subaddress, other.subaddress) + v = xcmp(self.subaddress, other.subaddress) return v Index: dnspython-1.12.0/dns/rdtypes/ANY/LOC.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/LOC.py +++ dnspython-1.12.0/dns/rdtypes/ANY/LOC.py @@ -13,32 +13,36 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO import struct import dns.exception import dns.rdata +from dns._compat import long, xrange +from io import BytesIO +from dns._compat import xcmp -_pows = (1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L, - 100000000L, 1000000000L, 10000000000L) + +_pows = tuple(long(10**i) for i in range(0, 11)) # default values are in centimeters _default_size = 100.0 _default_hprec = 1000000.0 _default_vprec = 1000.0 + def _exponent_of(what, desc): if what == 0: return 0 exp = None for i in xrange(len(_pows)): - if what // _pows[i] == 0L: + if what // _pows[i] == long(0): exp = i - 1 break if exp is None or exp < 0: raise dns.exception.SyntaxError("%s value out of bounds" % desc) return exp + def _float_to_tuple(what): if what < 0: sign = -1 @@ -55,6 +59,7 @@ def _float_to_tuple(what): what = int(what) return (degrees * sign, minutes, seconds, what) + def _tuple_to_float(what): if what[0] < 0: sign = -1 @@ -67,12 +72,14 @@ def _tuple_to_float(what): value += float(what[3]) / 3600000.0 return sign * value + def _encode_size(what, desc): - what = long(what); + what = long(what) exponent = _exponent_of(what, desc) & 0xF base = what // pow(10, exponent) & 0xF return base * 16 + exponent + def _decode_size(what, desc): exponent = what & 0x0F if exponent > 9: @@ -82,7 +89,9 @@ def _decode_size(what, desc): raise dns.exception.SyntaxError("bad %s base" % desc) return long(base) * pow(10, exponent) + class LOC(dns.rdata.Rdata): + """LOC record @ivar latitude: latitude @@ -105,7 +114,8 @@ class LOC(dns.rdata.Rdata): 'horizontal_precision', 'vertical_precision'] def __init__(self, rdclass, rdtype, latitude, longitude, altitude, - size=_default_size, hprec=_default_hprec, vprec=_default_vprec): + size=_default_size, hprec=_default_hprec, + vprec=_default_vprec): """Initialize a LOC record instance. The parameters I{latitude} and I{longitude} may be either a 4-tuple @@ -147,19 +157,20 @@ class LOC(dns.rdata.Rdata): lat_degrees, self.latitude[1], self.latitude[2], self.latitude[3], lat_hemisphere, long_degrees, self.longitude[1], self.longitude[2], self.longitude[3], long_hemisphere, self.altitude / 100.0 - ) + ) # do not print default values if self.size != _default_size or \ self.horizontal_precision != _default_hprec or \ - self.vertical_precision != _default_vprec: + self.vertical_precision != _default_vprec: text += " %0.2fm %0.2fm %0.2fm" % ( self.size / 100.0, self.horizontal_precision / 100.0, self.vertical_precision / 100.0 ) return text - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): latitude = [0, 0, 0, 0] longitude = [0, 0, 0, 0] size = _default_size @@ -174,13 +185,15 @@ class LOC(dns.rdata.Rdata): if '.' in t: (seconds, milliseconds) = t.split('.') if not seconds.isdigit(): - raise dns.exception.SyntaxError('bad latitude seconds value') + raise dns.exception.SyntaxError( + 'bad latitude seconds value') latitude[2] = int(seconds) if latitude[2] >= 60: raise dns.exception.SyntaxError('latitude seconds >= 60') l = len(milliseconds) if l == 0 or l > 3 or not milliseconds.isdigit(): - raise dns.exception.SyntaxError('bad latitude milliseconds value') + raise dns.exception.SyntaxError( + 'bad latitude milliseconds value') if l == 1: m = 100 elif l == 2: @@ -205,13 +218,15 @@ class LOC(dns.rdata.Rdata): if '.' in t: (seconds, milliseconds) = t.split('.') if not seconds.isdigit(): - raise dns.exception.SyntaxError('bad longitude seconds value') + raise dns.exception.SyntaxError( + 'bad longitude seconds value') longitude[2] = int(seconds) if longitude[2] >= 60: raise dns.exception.SyntaxError('longitude seconds >= 60') l = len(milliseconds) if l == 0 or l > 3 or not milliseconds.isdigit(): - raise dns.exception.SyntaxError('bad longitude milliseconds value') + raise dns.exception.SyntaxError( + 'bad longitude milliseconds value') if l == 1: m = 100 elif l == 2: @@ -256,7 +271,6 @@ class LOC(dns.rdata.Rdata): return cls(rdclass, rdtype, latitude, longitude, altitude, size, hprec, vprec) - from_text = classmethod(from_text) def to_wire(self, file, compress = None, origin = None): if self.latitude[0] < 0: @@ -269,7 +283,7 @@ class LOC(dns.rdata.Rdata): self.latitude[1] * 60000 + self.latitude[2] * 1000 + self.latitude[3]) * sign - latitude = 0x80000000L + milliseconds + latitude = long(0x80000000) + milliseconds if self.longitude[0] < 0: sign = -1 degrees = long(-1 * self.longitude[0]) @@ -280,8 +294,8 @@ class LOC(dns.rdata.Rdata): self.longitude[1] * 60000 + self.longitude[2] * 1000 + self.longitude[3]) * sign - longitude = 0x80000000L + milliseconds - altitude = long(self.altitude) + 10000000L + longitude = long(0x80000000) + milliseconds + altitude = long(self.altitude) + long(10000000) size = _encode_size(self.size, "size") hprec = _encode_size(self.horizontal_precision, "horizontal precision") vprec = _encode_size(self.vertical_precision, "vertical precision") @@ -289,19 +303,20 @@ class LOC(dns.rdata.Rdata): longitude, altitude) file.write(wire) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (version, size, hprec, vprec, latitude, longitude, altitude) = \ - struct.unpack("!BBBBIII", wire[current : current + rdlen]) - if latitude > 0x80000000L: - latitude = float(latitude - 0x80000000L) / 3600000 + struct.unpack("!BBBBIII", wire[current: current + rdlen]) + if latitude > long(0x80000000): + latitude = float(latitude - long(0x80000000)) / 3600000 else: - latitude = -1 * float(0x80000000L - latitude) / 3600000 + latitude = -1 * float(long(0x80000000) - latitude) / 3600000 if latitude < -90.0 or latitude > 90.0: raise dns.exception.FormError("bad latitude") - if longitude > 0x80000000L: - longitude = float(longitude - 0x80000000L) / 3600000 + if longitude > long(0x80000000): + longitude = float(longitude - long(0x80000000)) / 3600000 else: - longitude = -1 * float(0x80000000L - longitude) / 3600000 + longitude = -1 * float(long(0x80000000) - longitude) / 3600000 if longitude < -180.0 or longitude > 180.0: raise dns.exception.FormError("bad longitude") altitude = float(altitude) - 10000000.0 @@ -311,10 +326,8 @@ class LOC(dns.rdata.Rdata): return cls(rdclass, rdtype, latitude, longitude, altitude, size, hprec, vprec) - from_wire = classmethod(from_wire) - def _cmp(self, other): - f = cStringIO.StringIO() + f = BytesIO() self.to_wire(f) wire1 = f.getvalue() f.seek(0) @@ -323,7 +336,7 @@ class LOC(dns.rdata.Rdata): wire2 = f.getvalue() f.close() - return cmp(wire1, wire2) + return xcmp(wire1, wire2) def _get_float_latitude(self): return _tuple_to_float(self.latitude) Index: dnspython-1.12.0/dns/rdtypes/ANY/MX.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/MX.py +++ dnspython-1.12.0/dns/rdtypes/ANY/MX.py @@ -15,6 +15,8 @@ import dns.rdtypes.mxbase + class MX(dns.rdtypes.mxbase.MXBase): + """MX record""" pass Index: dnspython-1.12.0/dns/rdtypes/ANY/NS.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/NS.py +++ dnspython-1.12.0/dns/rdtypes/ANY/NS.py @@ -15,6 +15,8 @@ import dns.rdtypes.nsbase + class NS(dns.rdtypes.nsbase.NSBase): + """NS record""" pass Index: dnspython-1.12.0/dns/rdtypes/ANY/NSEC.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/NSEC.py +++ dnspython-1.12.0/dns/rdtypes/ANY/NSEC.py @@ -13,14 +13,17 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO +import struct import dns.exception import dns.rdata import dns.rdatatype import dns.name +from dns._compat import xrange + class NSEC(dns.rdata.Rdata): + """NSEC record @ivar next: the next name @@ -41,15 +44,16 @@ class NSEC(dns.rdata.Rdata): for (window, bitmap) in self.windows: bits = [] for i in xrange(0, len(bitmap)): - byte = ord(bitmap[i]) + byte = bitmap[i] for j in xrange(0, 8): if byte & (0x80 >> j): - bits.append(dns.rdatatype.to_text(window * 256 + \ + bits.append(dns.rdatatype.to_text(window * 256 + i * 8 + j)) text += (' ' + ' '.join(bits)) return '%s%s' % (next, text) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): next = tok.get_name() next = next.choose_relativity(origin, relativize) rdtypes = [] @@ -67,7 +71,7 @@ class NSEC(dns.rdata.Rdata): window = 0 octets = 0 prior_rdtype = 0 - bitmap = ['\0'] * 32 + bitmap = bytearray(b'\0' * 32) windows = [] for nrdtype in rdtypes: if nrdtype == prior_rdtype: @@ -75,27 +79,26 @@ class NSEC(dns.rdata.Rdata): prior_rdtype = nrdtype new_window = nrdtype // 256 if new_window != window: - windows.append((window, ''.join(bitmap[0:octets]))) - bitmap = ['\0'] * 32 + windows.append((window, bitmap[0:octets])) + bitmap = bytearray(b'\0' * 32) window = new_window offset = nrdtype % 256 byte = offset // 8 bit = offset % 8 octets = byte + 1 - bitmap[byte] = chr(ord(bitmap[byte]) | (0x80 >> bit)) - windows.append((window, ''.join(bitmap[0:octets]))) - return cls(rdclass, rdtype, next, windows) + bitmap[byte] = bitmap[byte] | (0x80 >> bit) - from_text = classmethod(from_text) + windows.append((window, bitmap[0:octets])) + return cls(rdclass, rdtype, next, windows) - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): self.next.to_wire(file, None, origin) for (window, bitmap) in self.windows: - file.write(chr(window)) - file.write(chr(len(bitmap))) + file.write(struct.pack('!BB', window, len(bitmap))) file.write(bitmap) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (next, cused) = dns.name.from_wire(wire[: current + rdlen], current) current += cused rdlen -= cused @@ -103,25 +106,23 @@ class NSEC(dns.rdata.Rdata): while rdlen > 0: if rdlen < 3: raise dns.exception.FormError("NSEC too short") - window = ord(wire[current]) - octets = ord(wire[current + 1]) + window = wire[current] + octets = wire[current + 1] if octets == 0 or octets > 32: raise dns.exception.FormError("bad NSEC octets") current += 2 rdlen -= 2 if rdlen < octets: raise dns.exception.FormError("bad NSEC bitmap length") - bitmap = wire[current : current + octets].unwrap() + bitmap = bytearray(wire[current: current + octets].unwrap()) current += octets rdlen -= octets windows.append((window, bitmap)) - if not origin is None: + if origin is not None: next = next.relativize(origin) return cls(rdclass, rdtype, next, windows) - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): self.next = self.next.choose_relativity(origin, relativize) def _cmp(self, other): Index: dnspython-1.12.0/dns/rdtypes/ANY/NSEC3.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/NSEC3.py +++ dnspython-1.12.0/dns/rdtypes/ANY/NSEC3.py @@ -13,19 +13,28 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +from io import BytesIO import base64 -import cStringIO +import binascii import string import struct import dns.exception import dns.rdata import dns.rdatatype +from dns._compat import xrange, text_type +from dns._compat import xcmp -b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV', - 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567') -b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', - '0123456789ABCDEFGHIJKLMNOPQRSTUV') +try: + b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV', + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567') + b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', + '0123456789ABCDEFGHIJKLMNOPQRSTUV') +except AttributeError: + b32_hex_to_normal = bytes.maketrans(b'0123456789ABCDEFGHIJKLMNOPQRSTUV', + b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567') + b32_normal_to_hex = bytes.maketrans(b'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567', + b'0123456789ABCDEFGHIJKLMNOPQRSTUV') # hash algorithm constants SHA1 = 1 @@ -33,7 +42,9 @@ SHA1 = 1 # flag constants OPTOUT = 1 + class NSEC3(dns.rdata.Rdata): + """NSEC3 record @ivar algorithm: the hash algorithm number @@ -57,39 +68,45 @@ class NSEC3(dns.rdata.Rdata): self.algorithm = algorithm self.flags = flags self.iterations = iterations - self.salt = salt + if isinstance(salt, text_type): + self.salt = salt.encode() + else: + self.salt = salt self.next = next self.windows = windows def to_text(self, origin=None, relativize=True, **kw): - next = base64.b32encode(self.next).translate(b32_normal_to_hex).lower() - if self.salt == '': + next = base64.b32encode(self.next).translate( + b32_normal_to_hex).lower().decode() + if self.salt == b'': salt = '-' else: - salt = self.salt.encode('hex-codec') - text = '' + salt = binascii.hexlify(self.salt).decode() + text = u'' for (window, bitmap) in self.windows: bits = [] for i in xrange(0, len(bitmap)): - byte = ord(bitmap[i]) + byte = bitmap[i] for j in xrange(0, 8): if byte & (0x80 >> j): - bits.append(dns.rdatatype.to_text(window * 256 + \ + bits.append(dns.rdatatype.to_text(window * 256 + i * 8 + j)) - text += (' ' + ' '.join(bits)) - return '%u %u %u %s %s%s' % (self.algorithm, self.flags, self.iterations, - salt, next, text) + text += (u' ' + u' '.join(bits)) + return u'%u %u %u %s %s%s' % (self.algorithm, self.flags, + self.iterations, salt, next, text) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): algorithm = tok.get_uint8() flags = tok.get_uint8() iterations = tok.get_uint16() salt = tok.get_string() - if salt == '-': - salt = '' + if salt == u'-': + salt = b'' else: - salt = salt.decode('hex-codec') - next = tok.get_string().upper().translate(b32_hex_to_normal) + salt = binascii.unhexlify(salt.encode('ascii')) + next = tok.get_string().encode( + 'ascii').upper().translate(b32_hex_to_normal) next = base64.b32decode(next) rdtypes = [] while 1: @@ -106,7 +123,7 @@ class NSEC3(dns.rdata.Rdata): window = 0 octets = 0 prior_rdtype = 0 - bitmap = ['\0'] * 32 + bitmap = bytearray(b'\0' * 32) windows = [] for nrdtype in rdtypes: if nrdtype == prior_rdtype: @@ -116,20 +133,19 @@ class NSEC3(dns.rdata.Rdata): if new_window != window: if octets != 0: windows.append((window, ''.join(bitmap[0:octets]))) - bitmap = ['\0'] * 32 + bitmap = bytearray(b'\0' * 32) window = new_window offset = nrdtype % 256 byte = offset // 8 bit = offset % 8 octets = byte + 1 - bitmap[byte] = chr(ord(bitmap[byte]) | (0x80 >> bit)) + bitmap[byte] = bitmap[byte] | (0x80 >> bit) if octets != 0: - windows.append((window, ''.join(bitmap[0:octets]))) - return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows) - - from_text = classmethod(from_text) + windows.append((window, bitmap[0:octets])) + return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, + windows) - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): l = len(self.salt) file.write(struct.pack("!BBHB", self.algorithm, self.flags, self.iterations, l)) @@ -138,19 +154,19 @@ class NSEC3(dns.rdata.Rdata): file.write(struct.pack("!B", l)) file.write(self.next) for (window, bitmap) in self.windows: - file.write(chr(window)) - file.write(chr(len(bitmap))) + file.write(struct.pack("!BB", window, len(bitmap))) file.write(bitmap) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - (algorithm, flags, iterations, slen) = struct.unpack('!BBHB', - wire[current : current + 5]) + (algorithm, flags, iterations, slen) = \ + struct.unpack('!BBHB', wire[current: current + 5]) current += 5 rdlen -= 5 salt = wire[current : current + slen].unwrap() current += slen rdlen -= slen - (nlen, ) = struct.unpack('!B', wire[current]) + nlen = wire[current] current += 1 rdlen -= 1 next = wire[current : current + nlen].unwrap() @@ -160,25 +176,23 @@ class NSEC3(dns.rdata.Rdata): while rdlen > 0: if rdlen < 3: raise dns.exception.FormError("NSEC3 too short") - window = ord(wire[current]) - octets = ord(wire[current + 1]) + window = wire[current] + octets = wire[current + 1] if octets == 0 or octets > 32: raise dns.exception.FormError("bad NSEC3 octets") current += 2 rdlen -= 2 if rdlen < octets: raise dns.exception.FormError("bad NSEC3 bitmap length") - bitmap = wire[current : current + octets].unwrap() + bitmap = bytearray(wire[current: current + octets].unwrap()) current += octets rdlen -= octets windows.append((window, bitmap)) return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows) - from_wire = classmethod(from_wire) - def _cmp(self, other): - b1 = cStringIO.StringIO() + b1 = BytesIO() self.to_wire(b1) - b2 = cStringIO.StringIO() + b2 = BytesIO() other.to_wire(b2) - return cmp(b1.getvalue(), b2.getvalue()) + return xcmp(b1.getvalue(), b2.getvalue()) Index: dnspython-1.12.0/dns/rdtypes/ANY/NSEC3PARAM.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/NSEC3PARAM.py +++ dnspython-1.12.0/dns/rdtypes/ANY/NSEC3PARAM.py @@ -13,13 +13,18 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO +from io import BytesIO import struct +import binascii import dns.exception import dns.rdata +from dns._compat import text_type +from dns._compat import xcmp + class NSEC3PARAM(dns.rdata.Rdata): + """NSEC3PARAM record @ivar algorithm: the hash algorithm number @@ -38,16 +43,21 @@ class NSEC3PARAM(dns.rdata.Rdata): self.algorithm = algorithm self.flags = flags self.iterations = iterations - self.salt = salt + if isinstance(salt, text_type): + self.salt = salt.encode() + else: + self.salt = salt def to_text(self, origin=None, relativize=True, **kw): - if self.salt == '': + if self.salt == b'': salt = '-' else: - salt = self.salt.encode('hex-codec') - return '%u %u %u %s' % (self.algorithm, self.flags, self.iterations, salt) + salt = binascii.hexlify(self.salt).decode() + return '%u %u %u %s' % (self.algorithm, self.flags, self.iterations, + salt) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): algorithm = tok.get_uint8() flags = tok.get_uint8() iterations = tok.get_uint16() @@ -55,21 +65,21 @@ class NSEC3PARAM(dns.rdata.Rdata): if salt == '-': salt = '' else: - salt = salt.decode('hex-codec') + salt = binascii.unhexlify(salt.encode()) tok.get_eol() return cls(rdclass, rdtype, algorithm, flags, iterations, salt) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): l = len(self.salt) file.write(struct.pack("!BBHB", self.algorithm, self.flags, self.iterations, l)) file.write(self.salt) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - (algorithm, flags, iterations, slen) = struct.unpack('!BBHB', - wire[current : current + 5]) + (algorithm, flags, iterations, slen) = \ + struct.unpack('!BBHB', + wire[current: current + 5]) current += 5 rdlen -= 5 salt = wire[current : current + slen].unwrap() @@ -79,11 +89,9 @@ class NSEC3PARAM(dns.rdata.Rdata): raise dns.exception.FormError return cls(rdclass, rdtype, algorithm, flags, iterations, salt) - from_wire = classmethod(from_wire) - def _cmp(self, other): - b1 = cStringIO.StringIO() + b1 = BytesIO() self.to_wire(b1) - b2 = cStringIO.StringIO() + b2 = BytesIO() other.to_wire(b2) - return cmp(b1.getvalue(), b2.getvalue()) + return xcmp(b1.getvalue(), b2.getvalue()) Index: dnspython-1.12.0/dns/rdtypes/ANY/PTR.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/PTR.py +++ dnspython-1.12.0/dns/rdtypes/ANY/PTR.py @@ -15,6 +15,8 @@ import dns.rdtypes.nsbase + class PTR(dns.rdtypes.nsbase.NSBase): + """PTR record""" pass Index: dnspython-1.12.0/dns/rdtypes/ANY/RP.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/RP.py +++ dnspython-1.12.0/dns/rdtypes/ANY/RP.py @@ -16,8 +16,11 @@ import dns.exception import dns.rdata import dns.name +from dns._compat import xcmp + class RP(dns.rdata.Rdata): + """RP record @ivar mbox: The responsible person's mailbox @@ -39,7 +42,8 @@ class RP(dns.rdata.Rdata): txt = self.txt.choose_relativity(origin, relativize) return "%s %s" % (str(mbox), str(txt)) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): mbox = tok.get_name() txt = tok.get_name() mbox = mbox.choose_relativity(origin, relativize) @@ -47,17 +51,16 @@ class RP(dns.rdata.Rdata): tok.get_eol() return cls(rdclass, rdtype, mbox, txt) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): self.mbox.to_wire(file, None, origin) self.txt.to_wire(file, None, origin) - def to_digestable(self, origin = None): + def to_digestable(self, origin=None): return self.mbox.to_digestable(origin) + \ self.txt.to_digestable(origin) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (mbox, cused) = dns.name.from_wire(wire[: current + rdlen], current) current += cused @@ -68,19 +71,17 @@ class RP(dns.rdata.Rdata): current) if cused != rdlen: raise dns.exception.FormError - if not origin is None: + if origin is not None: mbox = mbox.relativize(origin) txt = txt.relativize(origin) return cls(rdclass, rdtype, mbox, txt) - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): self.mbox = self.mbox.choose_relativity(origin, relativize) self.txt = self.txt.choose_relativity(origin, relativize) def _cmp(self, other): - v = cmp(self.mbox, other.mbox) + v = xcmp(self.mbox, other.mbox) if v == 0: - v = cmp(self.txt, other.txt) + v = xcmp(self.txt, other.txt) return v Index: dnspython-1.12.0/dns/rdtypes/ANY/RRSIG.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/RRSIG.py +++ dnspython-1.12.0/dns/rdtypes/ANY/RRSIG.py @@ -13,6 +13,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import base64 import calendar import struct import time @@ -38,10 +39,13 @@ def sigtime_to_posixtime(what): return calendar.timegm((year, month, day, hour, minute, second, 0, 0, 0)) + def posixtime_to_sigtime(what): return time.strftime('%Y%m%d%H%M%S', time.gmtime(what)) + class RRSIG(dns.rdata.Rdata): + """RRSIG record @ivar type_covered: the rdata type this signature covers @@ -95,9 +99,10 @@ class RRSIG(dns.rdata.Rdata): self.key_tag, self.signer.choose_relativity(origin, relativize), dns.rdata._base64ify(self.signature) - ) + ) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): type_covered = dns.rdatatype.from_text(tok.get_string()) algorithm = dns.dnssec.algorithm_from_text(tok.get_string()) labels = tok.get_int() @@ -114,16 +119,14 @@ class RRSIG(dns.rdata.Rdata): break if not t.is_identifier(): raise dns.exception.SyntaxError - chunks.append(t.value) - b64 = ''.join(chunks) - signature = b64.decode('base64_codec') + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + signature = base64.b64decode(b64) return cls(rdclass, rdtype, type_covered, algorithm, labels, original_ttl, expiration, inception, key_tag, signer, signature) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): header = struct.pack('!HBBIIIH', self.type_covered, self.algorithm, self.labels, self.original_ttl, self.expiration, @@ -132,23 +135,22 @@ class RRSIG(dns.rdata.Rdata): self.signer.to_wire(file, None, origin) file.write(self.signature) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - header = struct.unpack('!HBBIIIH', wire[current : current + 18]) + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + header = struct.unpack('!HBBIIIH', wire[current: current + 18]) current += 18 rdlen -= 18 (signer, cused) = dns.name.from_wire(wire[: current + rdlen], current) current += cused rdlen -= cused - if not origin is None: + if origin is not None: signer = signer.relativize(origin) - signature = wire[current : current + rdlen].unwrap() + signature = wire[current: current + rdlen].unwrap() return cls(rdclass, rdtype, header[0], header[1], header[2], header[3], header[4], header[5], header[6], signer, signature) - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): self.signer = self.signer.choose_relativity(origin, relativize) def _cmp(self, other): Index: dnspython-1.12.0/dns/rdtypes/ANY/RT.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/RT.py +++ dnspython-1.12.0/dns/rdtypes/ANY/RT.py @@ -15,6 +15,8 @@ import dns.rdtypes.mxbase + class RT(dns.rdtypes.mxbase.UncompressedDowncasingMX): + """RT record""" pass Index: dnspython-1.12.0/dns/rdtypes/ANY/SOA.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/SOA.py +++ dnspython-1.12.0/dns/rdtypes/ANY/SOA.py @@ -18,8 +18,11 @@ import struct import dns.exception import dns.rdata import dns.name +from dns._compat import xcmp + class SOA(dns.rdata.Rdata): + """SOA record @ivar mname: the SOA MNAME (master name) field @@ -58,9 +61,10 @@ class SOA(dns.rdata.Rdata): rname = self.rname.choose_relativity(origin, relativize) return '%s %s %d %d %d %d %d' % ( mname, rname, self.serial, self.refresh, self.retry, - self.expire, self.minimum ) + self.expire, self.minimum) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): mname = tok.get_name() rname = tok.get_name() mname = mname.choose_relativity(origin, relativize) @@ -72,24 +76,23 @@ class SOA(dns.rdata.Rdata): minimum = tok.get_ttl() tok.get_eol() return cls(rdclass, rdtype, mname, rname, serial, refresh, retry, - expire, minimum ) + expire, minimum) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): self.mname.to_wire(file, compress, origin) self.rname.to_wire(file, compress, origin) five_ints = struct.pack('!IIIII', self.serial, self.refresh, self.retry, self.expire, self.minimum) file.write(five_ints) - def to_digestable(self, origin = None): + def to_digestable(self, origin=None): return self.mname.to_digestable(origin) + \ self.rname.to_digestable(origin) + \ struct.pack('!IIIII', self.serial, self.refresh, self.retry, self.expire, self.minimum) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (mname, cused) = dns.name.from_wire(wire[: current + rdlen], current) current += cused rdlen -= cused @@ -99,29 +102,27 @@ class SOA(dns.rdata.Rdata): if rdlen != 20: raise dns.exception.FormError five_ints = struct.unpack('!IIIII', - wire[current : current + rdlen]) - if not origin is None: + wire[current: current + rdlen]) + if origin is not None: mname = mname.relativize(origin) rname = rname.relativize(origin) return cls(rdclass, rdtype, mname, rname, five_ints[0], five_ints[1], five_ints[2], five_ints[3], five_ints[4]) - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): self.mname = self.mname.choose_relativity(origin, relativize) self.rname = self.rname.choose_relativity(origin, relativize) def _cmp(self, other): - v = cmp(self.mname, other.mname) + v = xcmp(self.mname, other.mname) if v == 0: - v = cmp(self.rname, other.rname) + v = xcmp(self.rname, other.rname) if v == 0: self_ints = struct.pack('!IIIII', self.serial, self.refresh, self.retry, self.expire, self.minimum) other_ints = struct.pack('!IIIII', other.serial, other.refresh, other.retry, other.expire, other.minimum) - v = cmp(self_ints, other_ints) + v = xcmp(self_ints, other_ints) return v Index: dnspython-1.12.0/dns/rdtypes/ANY/SPF.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/SPF.py +++ dnspython-1.12.0/dns/rdtypes/ANY/SPF.py @@ -15,7 +15,9 @@ import dns.rdtypes.txtbase + class SPF(dns.rdtypes.txtbase.TXTBase): + """SPF record @see: RFC 4408""" Index: dnspython-1.12.0/dns/rdtypes/ANY/SSHFP.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/SSHFP.py +++ dnspython-1.12.0/dns/rdtypes/ANY/SSHFP.py @@ -14,11 +14,15 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import struct +import binascii import dns.rdata import dns.rdatatype +from dns._compat import xcmp + class SSHFP(dns.rdata.Rdata): + """SSHFP record @ivar algorithm: the algorithm @@ -44,7 +48,8 @@ class SSHFP(dns.rdata.Rdata): dns.rdata._hexify(self.fingerprint, chunksize=128)) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): algorithm = tok.get_uint8() fp_type = tok.get_uint8() chunks = [] @@ -54,18 +59,17 @@ class SSHFP(dns.rdata.Rdata): break if not t.is_identifier(): raise dns.exception.SyntaxError - chunks.append(t.value) - fingerprint = ''.join(chunks) - fingerprint = fingerprint.decode('hex_codec') + chunks.append(t.value.encode()) + fingerprint = b''.join(chunks) + fingerprint = binascii.unhexlify(fingerprint) return cls(rdclass, rdtype, algorithm, fp_type, fingerprint) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): header = struct.pack("!BB", self.algorithm, self.fp_type) file.write(header) file.write(self.fingerprint) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): header = struct.unpack("!BB", wire[current : current + 2]) current += 2 @@ -73,12 +77,10 @@ class SSHFP(dns.rdata.Rdata): fingerprint = wire[current : current + rdlen].unwrap() return cls(rdclass, rdtype, header[0], header[1], fingerprint) - from_wire = classmethod(from_wire) - def _cmp(self, other): hs = struct.pack("!BB", self.algorithm, self.fp_type) ho = struct.pack("!BB", other.algorithm, other.fp_type) - v = cmp(hs, ho) + v = xcmp(hs, ho) if v == 0: - v = cmp(self.fingerprint, other.fingerprint) + v = xcmp(self.fingerprint, other.fingerprint) return v Index: dnspython-1.12.0/dns/rdtypes/ANY/TLSA.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/TLSA.py +++ dnspython-1.12.0/dns/rdtypes/ANY/TLSA.py @@ -14,11 +14,15 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import struct +import binascii import dns.rdata import dns.rdatatype +from dns._compat import xcmp + class TLSA(dns.rdata.Rdata): + """TLSA record @ivar usage: The certificate usage @@ -46,9 +50,10 @@ class TLSA(dns.rdata.Rdata): self.selector, self.mtype, dns.rdata._hexify(self.cert, - chunksize=128)) + chunksize=128)) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): usage = tok.get_uint8() selector = tok.get_uint8() mtype = tok.get_uint8() @@ -59,18 +64,17 @@ class TLSA(dns.rdata.Rdata): break if not t.is_identifier(): raise dns.exception.SyntaxError - cert_chunks.append(t.value) - cert = ''.join(cert_chunks) - cert = cert.decode('hex_codec') + cert_chunks.append(t.value.encode()) + cert = b''.join(cert_chunks) + cert = binascii.unhexlify(cert) return cls(rdclass, rdtype, usage, selector, mtype, cert) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): header = struct.pack("!BBB", self.usage, self.selector, self.mtype) file.write(header) file.write(self.cert) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): header = struct.unpack("!BBB", wire[current : current + 3]) current += 3 @@ -78,12 +82,10 @@ class TLSA(dns.rdata.Rdata): cert = wire[current : current + rdlen].unwrap() return cls(rdclass, rdtype, header[0], header[1], header[2], cert) - from_wire = classmethod(from_wire) - def _cmp(self, other): hs = struct.pack("!BBB", self.usage, self.selector, self.mtype) ho = struct.pack("!BBB", other.usage, other.selector, other.mtype) - v = cmp(hs, ho) + v = xcmp(hs, ho) if v == 0: - v = cmp(self.cert, other.cert) + v = xcmp(self.cert, other.cert) return v Index: dnspython-1.12.0/dns/rdtypes/ANY/TXT.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/TXT.py +++ dnspython-1.12.0/dns/rdtypes/ANY/TXT.py @@ -15,6 +15,8 @@ import dns.rdtypes.txtbase + class TXT(dns.rdtypes.txtbase.TXTBase): + """TXT record""" pass Index: dnspython-1.12.0/dns/rdtypes/ANY/X25.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/ANY/X25.py +++ dnspython-1.12.0/dns/rdtypes/ANY/X25.py @@ -13,11 +13,17 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import struct + import dns.exception import dns.rdata import dns.tokenizer +from dns._compat import text_type +from dns._compat import xcmp + class X25(dns.rdata.Rdata): + """X25 record @ivar address: the PSDN address @@ -28,27 +34,28 @@ class X25(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, address): super(X25, self).__init__(rdclass, rdtype) - self.address = address + if isinstance(address, text_type): + self.address = address.encode() + else: + self.address = address def to_text(self, origin=None, relativize=True, **kw): return '"%s"' % dns.rdata._escapify(self.address) + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): address = tok.get_string() tok.get_eol() return cls(rdclass, rdtype, address) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): l = len(self.address) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(self.address) def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l != rdlen: @@ -59,4 +66,4 @@ class X25(dns.rdata.Rdata): from_wire = classmethod(from_wire) def _cmp(self, other): - return cmp(self.address, other.address) + return xcmp(self.address, other.address) Index: dnspython-1.12.0/dns/rdtypes/IN/A.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/A.py +++ dnspython-1.12.0/dns/rdtypes/IN/A.py @@ -17,8 +17,11 @@ import dns.exception import dns.ipv4 import dns.rdata import dns.tokenizer +from dns._compat import xcmp + class A(dns.rdata.Rdata): + """A record. @ivar address: an IPv4 address @@ -29,29 +32,27 @@ class A(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, address): super(A, self).__init__(rdclass, rdtype) # check that it's OK - junk = dns.ipv4.inet_aton(address) + dns.ipv4.inet_aton(address) self.address = address def to_text(self, origin=None, relativize=True, **kw): return self.address + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): address = tok.get_identifier() tok.get_eol() return cls(rdclass, rdtype, address) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): file.write(dns.ipv4.inet_aton(self.address)) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - address = dns.ipv4.inet_ntoa(wire[current : current + rdlen]) + address = dns.ipv4.inet_ntoa(wire[current : current + rdlen]).decode() return cls(rdclass, rdtype, address) - from_wire = classmethod(from_wire) - def _cmp(self, other): sa = dns.ipv4.inet_aton(self.address) oa = dns.ipv4.inet_aton(other.address) - return cmp(sa, oa) + return xcmp(sa, oa) Index: dnspython-1.12.0/dns/rdtypes/IN/AAAA.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/AAAA.py +++ dnspython-1.12.0/dns/rdtypes/IN/AAAA.py @@ -18,7 +18,11 @@ import dns.inet import dns.rdata import dns.tokenizer +from dns._compat import xcmp + + class AAAA(dns.rdata.Rdata): + """AAAA record. @ivar address: an IPv6 address @@ -35,24 +39,22 @@ class AAAA(dns.rdata.Rdata): def to_text(self, origin=None, relativize=True, **kw): return self.address + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): address = tok.get_identifier() tok.get_eol() return cls(rdclass, rdtype, address) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): file.write(dns.inet.inet_pton(dns.inet.AF_INET6, self.address)) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): address = dns.inet.inet_ntop(dns.inet.AF_INET6, wire[current : current + rdlen]) return cls(rdclass, rdtype, address) - from_wire = classmethod(from_wire) - def _cmp(self, other): sa = dns.inet.inet_pton(dns.inet.AF_INET6, self.address) oa = dns.inet.inet_pton(dns.inet.AF_INET6, other.address) - return cmp(sa, oa) + return xcmp(sa, oa) Index: dnspython-1.12.0/dns/rdtypes/IN/APL.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/APL.py +++ dnspython-1.12.0/dns/rdtypes/IN/APL.py @@ -13,15 +13,20 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO +from io import BytesIO import struct +import binascii import dns.exception import dns.inet import dns.rdata import dns.tokenizer +from dns._compat import xrange +from dns._compat import xcmp + class APLItem(object): + """An APL list item. @ivar family: the address family (IANA address family registry) @@ -54,7 +59,7 @@ class APLItem(object): elif self.family == 2: address = dns.inet.inet_pton(dns.inet.AF_INET6, self.address) else: - address = self.address.decode('hex_codec') + address = binascii.unhexlify(self.address) # # Truncate least significant zero bytes. # @@ -63,7 +68,7 @@ class APLItem(object): if address[i] != chr(0): last = i + 1 break - address = address[0 : last] + address = address[0: last] l = len(address) assert l < 128 if self.negation: @@ -72,7 +77,9 @@ class APLItem(object): file.write(header) file.write(address) + class APL(dns.rdata.Rdata): + """APL record. @ivar items: a list of APL items @@ -88,7 +95,8 @@ class APL(dns.rdata.Rdata): def to_text(self, origin=None, relativize=True, **kw): return ' '.join(map(lambda x: str(x), self.items)) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): items = [] while 1: token = tok.get().unescape() @@ -109,20 +117,19 @@ class APL(dns.rdata.Rdata): return cls(rdclass, rdtype, items) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): for item in self.items: item.to_wire(file) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): items = [] while 1: if rdlen == 0: break if rdlen < 4: raise dns.exception.FormError - header = struct.unpack('!HBB', wire[current : current + 4]) + header = struct.unpack('!HBB', wire[current: current + 4]) afdlen = header[2] if afdlen > 127: negation = True @@ -133,7 +140,7 @@ class APL(dns.rdata.Rdata): rdlen -= 4 if rdlen < afdlen: raise dns.exception.FormError - address = wire[current : current + afdlen].unwrap() + address = wire[current: current + afdlen].unwrap() l = len(address) if header[0] == 1: if l < 4: @@ -155,10 +162,8 @@ class APL(dns.rdata.Rdata): items.append(item) return cls(rdclass, rdtype, items) - from_wire = classmethod(from_wire) - def _cmp(self, other): - f = cStringIO.StringIO() + f = BytesIO() self.to_wire(f) wire1 = f.getvalue() f.seek(0) @@ -167,4 +172,4 @@ class APL(dns.rdata.Rdata): wire2 = f.getvalue() f.close() - return cmp(wire1, wire2) + return xcmp(wire1, wire2) Index: dnspython-1.12.0/dns/rdtypes/IN/DHCID.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/DHCID.py +++ dnspython-1.12.0/dns/rdtypes/IN/DHCID.py @@ -13,9 +13,14 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import base64 + import dns.exception +from dns._compat import xcmp + class DHCID(dns.rdata.Rdata): + """DHCID record @ivar data: the data (the content of the RR is opaque as far as the @@ -32,7 +37,8 @@ class DHCID(dns.rdata.Rdata): def to_text(self, origin=None, relativize=True, **kw): return dns.rdata._base64ify(self.data) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): chunks = [] while 1: t = tok.get().unescape() @@ -40,21 +46,18 @@ class DHCID(dns.rdata.Rdata): break if not t.is_identifier(): raise dns.exception.SyntaxError - chunks.append(t.value) - b64 = ''.join(chunks) - data = b64.decode('base64_codec') + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + data = base64.b64decode(b64) return cls(rdclass, rdtype, data) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): file.write(self.data) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): data = wire[current : current + rdlen].unwrap() return cls(rdclass, rdtype, data) - from_wire = classmethod(from_wire) - def _cmp(self, other): - return cmp(self.data, other.data) + return xcmp(self.data, other.data) Index: dnspython-1.12.0/dns/rdtypes/IN/IPSECKEY.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/IPSECKEY.py +++ dnspython-1.12.0/dns/rdtypes/IN/IPSECKEY.py @@ -13,14 +13,18 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO +from io import BytesIO import struct +import base64 import dns.exception import dns.inet import dns.name +from dns._compat import xcmp + class IPSECKEY(dns.rdata.Rdata): + """IPSECKEY record @ivar precedence: the precedence for this key data @@ -41,19 +45,20 @@ class IPSECKEY(dns.rdata.Rdata): gateway, key): super(IPSECKEY, self).__init__(rdclass, rdtype) if gateway_type == 0: - if gateway != '.' and not gateway is None: + if gateway != '.' and gateway is not None: raise SyntaxError('invalid gateway for gateway type 0') gateway = None elif gateway_type == 1: # check that it's OK - junk = dns.inet.inet_pton(dns.inet.AF_INET, gateway) + dns.inet.inet_pton(dns.inet.AF_INET, gateway) elif gateway_type == 2: # check that it's OK - junk = dns.inet.inet_pton(dns.inet.AF_INET6, gateway) + dns.inet.inet_pton(dns.inet.AF_INET6, gateway) elif gateway_type == 3: pass else: - raise SyntaxError('invalid IPSECKEY gateway type: %d' % gateway_type) + raise SyntaxError( + 'invalid IPSECKEY gateway type: %d' % gateway_type) self.precedence = precedence self.gateway_type = gateway_type self.algorithm = algorithm @@ -75,7 +80,8 @@ class IPSECKEY(dns.rdata.Rdata): self.algorithm, gateway, dns.rdata._base64ify(self.key)) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): precedence = tok.get_uint8() gateway_type = tok.get_uint8() algorithm = tok.get_uint8() @@ -90,15 +96,13 @@ class IPSECKEY(dns.rdata.Rdata): break if not t.is_identifier(): raise dns.exception.SyntaxError - chunks.append(t.value) - b64 = ''.join(chunks) - key = b64.decode('base64_codec') + chunks.append(t.value.encode()) + b64 = b''.join(chunks) + key = base64.b64decode(b64) return cls(rdclass, rdtype, precedence, gateway_type, algorithm, gateway, key) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): header = struct.pack("!BBB", self.precedence, self.gateway_type, self.algorithm) file.write(header) @@ -114,10 +118,11 @@ class IPSECKEY(dns.rdata.Rdata): raise ValueError('invalid gateway type') file.write(self.key) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): if rdlen < 3: raise dns.exception.FormError - header = struct.unpack('!BBB', wire[current : current + 3]) + header = struct.unpack('!BBB', wire[current: current + 3]) gateway_type = header[1] current += 3 rdlen -= 3 @@ -125,12 +130,12 @@ class IPSECKEY(dns.rdata.Rdata): gateway = None elif gateway_type == 1: gateway = dns.inet.inet_ntop(dns.inet.AF_INET, - wire[current : current + 4]) + wire[current: current + 4]) current += 4 rdlen -= 4 elif gateway_type == 2: gateway = dns.inet.inet_ntop(dns.inet.AF_INET6, - wire[current : current + 16]) + wire[current: current + 16]) current += 16 rdlen -= 16 elif gateway_type == 3: @@ -144,10 +149,8 @@ class IPSECKEY(dns.rdata.Rdata): return cls(rdclass, rdtype, header[0], gateway_type, header[2], gateway, key) - from_wire = classmethod(from_wire) - def _cmp(self, other): - f = cStringIO.StringIO() + f = BytesIO() self.to_wire(f) wire1 = f.getvalue() f.seek(0) @@ -156,4 +159,4 @@ class IPSECKEY(dns.rdata.Rdata): wire2 = f.getvalue() f.close() - return cmp(wire1, wire2) + return xcmp(wire1, wire2) Index: dnspython-1.12.0/dns/rdtypes/IN/KX.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/KX.py +++ dnspython-1.12.0/dns/rdtypes/IN/KX.py @@ -15,6 +15,8 @@ import dns.rdtypes.mxbase + class KX(dns.rdtypes.mxbase.UncompressedMX): + """KX record""" pass Index: dnspython-1.12.0/dns/rdtypes/IN/NAPTR.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/NAPTR.py +++ dnspython-1.12.0/dns/rdtypes/IN/NAPTR.py @@ -18,15 +18,25 @@ import struct import dns.exception import dns.name import dns.rdata +from dns._compat import xrange, text_type +from dns._compat import xcmp + def _write_string(file, s): l = len(s) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(s) + +def _sanitize(value): + if isinstance(value, text_type): + return value.encode() + return value + + class NAPTR(dns.rdata.Rdata): + """NAPTR record @ivar order: order @@ -49,11 +59,11 @@ class NAPTR(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, order, preference, flags, service, regexp, replacement): super(NAPTR, self).__init__(rdclass, rdtype) + self.flags = _sanitize(flags) + self.service = _sanitize(service) + self.regexp = _sanitize(regexp) self.order = order self.preference = preference - self.flags = flags - self.service = service - self.regexp = regexp self.replacement = replacement def to_text(self, origin=None, relativize=True, **kw): @@ -63,9 +73,10 @@ class NAPTR(dns.rdata.Rdata): dns.rdata._escapify(self.flags), dns.rdata._escapify(self.service), dns.rdata._escapify(self.regexp), - self.replacement) + replacement) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): order = tok.get_uint16() preference = tok.get_uint16() flags = tok.get_string() @@ -77,9 +88,7 @@ class NAPTR(dns.rdata.Rdata): return cls(rdclass, rdtype, order, preference, flags, service, regexp, replacement) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): two_ints = struct.pack("!HH", self.order, self.preference) file.write(two_ints) _write_string(file, self.flags) @@ -87,18 +96,19 @@ class NAPTR(dns.rdata.Rdata): _write_string(file, self.regexp) self.replacement.to_wire(file, compress, origin) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - (order, preference) = struct.unpack('!HH', wire[current : current + 4]) + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (order, preference) = struct.unpack('!HH', wire[current: current + 4]) current += 4 rdlen -= 4 strings = [] for i in xrange(3): - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l > rdlen or rdlen < 0: raise dns.exception.FormError - s = wire[current : current + l].unwrap() + s = wire[current: current + l].unwrap() current += l rdlen -= l strings.append(s) @@ -106,27 +116,25 @@ class NAPTR(dns.rdata.Rdata): current) if cused != rdlen: raise dns.exception.FormError - if not origin is None: + if origin is not None: replacement = replacement.relativize(origin) return cls(rdclass, rdtype, order, preference, strings[0], strings[1], strings[2], replacement) - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): self.replacement = self.replacement.choose_relativity(origin, relativize) def _cmp(self, other): sp = struct.pack("!HH", self.order, self.preference) op = struct.pack("!HH", other.order, other.preference) - v = cmp(sp, op) + v = xcmp(sp, op) if v == 0: - v = cmp(self.flags, other.flags) + v = xcmp(self.flags, other.flags) if v == 0: - v = cmp(self.service, other.service) + v = xcmp(self.service, other.service) if v == 0: - v = cmp(self.regexp, other.regexp) + v = xcmp(self.regexp, other.regexp) if v == 0: - v = cmp(self.replacement, other.replacement) + v = xcmp(self.replacement, other.replacement) return v Index: dnspython-1.12.0/dns/rdtypes/IN/NSAP.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/NSAP.py +++ dnspython-1.12.0/dns/rdtypes/IN/NSAP.py @@ -13,11 +13,16 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +import binascii + import dns.exception import dns.rdata import dns.tokenizer +from dns._compat import xcmp + class NSAP(dns.rdata.Rdata): + """NSAP record. @ivar address: a NASP @@ -31,8 +36,9 @@ class NSAP(dns.rdata.Rdata): self.address = address def to_text(self, origin=None, relativize=True, **kw): - return "0x%s" % self.address.encode('hex_codec') + return "0x%s" % binascii.hexlify(self.address).decode() + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): address = tok.get_string() t = tok.get_eol() @@ -41,19 +47,16 @@ class NSAP(dns.rdata.Rdata): address = address[2:].replace('.', '') if len(address) % 2 != 0: raise dns.exception.SyntaxError('hexstring has odd length') - address = address.decode('hex_codec') + address = binascii.unhexlify(address.encode()) return cls(rdclass, rdtype, address) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): file.write(self.address) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): address = wire[current : current + rdlen].unwrap() return cls(rdclass, rdtype, address) - from_wire = classmethod(from_wire) - def _cmp(self, other): - return cmp(self.address, other.address) + return xcmp(self.address, other.address) Index: dnspython-1.12.0/dns/rdtypes/IN/NSAP_PTR.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/NSAP_PTR.py +++ dnspython-1.12.0/dns/rdtypes/IN/NSAP_PTR.py @@ -15,6 +15,8 @@ import dns.rdtypes.nsbase + class NSAP_PTR(dns.rdtypes.nsbase.UncompressedNS): + """NSAP-PTR record""" pass Index: dnspython-1.12.0/dns/rdtypes/IN/PX.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/PX.py +++ dnspython-1.12.0/dns/rdtypes/IN/PX.py @@ -18,8 +18,11 @@ import struct import dns.exception import dns.rdata import dns.name +from dns._compat import xcmp + class PX(dns.rdata.Rdata): + """PX record. @ivar preference: the preference value @@ -43,7 +46,8 @@ class PX(dns.rdata.Rdata): mapx400 = self.mapx400.choose_relativity(origin, relativize) return '%d %s %s' % (self.preference, map822, mapx400) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): preference = tok.get_uint16() map822 = tok.get_name() map822 = map822.choose_relativity(origin, relativize) @@ -52,46 +56,43 @@ class PX(dns.rdata.Rdata): tok.get_eol() return cls(rdclass, rdtype, preference, map822, mapx400) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): pref = struct.pack("!H", self.preference) file.write(pref) self.map822.to_wire(file, None, origin) self.mapx400.to_wire(file, None, origin) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): - (preference, ) = struct.unpack('!H', wire[current : current + 2]) + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): + (preference, ) = struct.unpack('!H', wire[current: current + 2]) current += 2 rdlen -= 2 (map822, cused) = dns.name.from_wire(wire[: current + rdlen], - current) + current) if cused > rdlen: raise dns.exception.FormError current += cused rdlen -= cused - if not origin is None: + if origin is not None: map822 = map822.relativize(origin) (mapx400, cused) = dns.name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise dns.exception.FormError - if not origin is None: + if origin is not None: mapx400 = mapx400.relativize(origin) return cls(rdclass, rdtype, preference, map822, mapx400) - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): self.map822 = self.map822.choose_relativity(origin, relativize) self.mapx400 = self.mapx400.choose_relativity(origin, relativize) def _cmp(self, other): sp = struct.pack("!H", self.preference) op = struct.pack("!H", other.preference) - v = cmp(sp, op) + v = xcmp(sp, op) if v == 0: - v = cmp(self.map822, other.map822) + v = xcmp(self.map822, other.map822) if v == 0: - v = cmp(self.mapx400, other.mapx400) + v = xcmp(self.mapx400, other.mapx400) return v Index: dnspython-1.12.0/dns/rdtypes/IN/SRV.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/SRV.py +++ dnspython-1.12.0/dns/rdtypes/IN/SRV.py @@ -18,8 +18,11 @@ import struct import dns.exception import dns.rdata import dns.name +from dns._compat import xcmp + class SRV(dns.rdata.Rdata): + """SRV record @ivar priority: the priority @@ -46,7 +49,8 @@ class SRV(dns.rdata.Rdata): return '%d %d %d %s' % (self.priority, self.weight, self.port, target) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): priority = tok.get_uint16() weight = tok.get_uint16() port = tok.get_uint16() @@ -55,35 +59,32 @@ class SRV(dns.rdata.Rdata): tok.get_eol() return cls(rdclass, rdtype, priority, weight, port, target) - from_text = classmethod(from_text) - - def to_wire(self, file, compress = None, origin = None): + def to_wire(self, file, compress=None, origin=None): three_ints = struct.pack("!HHH", self.priority, self.weight, self.port) file.write(three_ints) self.target.to_wire(file, compress, origin) - def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): + @classmethod + def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin=None): (priority, weight, port) = struct.unpack('!HHH', - wire[current : current + 6]) + wire[current: current + 6]) current += 6 rdlen -= 6 (target, cused) = dns.name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise dns.exception.FormError - if not origin is None: + if origin is not None: target = target.relativize(origin) return cls(rdclass, rdtype, priority, weight, port, target) - from_wire = classmethod(from_wire) - - def choose_relativity(self, origin = None, relativize = True): + def choose_relativity(self, origin=None, relativize=True): self.target = self.target.choose_relativity(origin, relativize) def _cmp(self, other): sp = struct.pack("!HHH", self.priority, self.weight, self.port) op = struct.pack("!HHH", other.priority, other.weight, other.port) - v = cmp(sp, op) + v = xcmp(sp, op) if v == 0: - v = cmp(self.target, other.target) + v = xcmp(self.target, other.target) return v Index: dnspython-1.12.0/dns/rdtypes/IN/WKS.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/IN/WKS.py +++ dnspython-1.12.0/dns/rdtypes/IN/WKS.py @@ -18,11 +18,15 @@ import struct import dns.ipv4 import dns.rdata +from dns._compat import xrange +from dns._compat import xcmp _proto_tcp = socket.getprotobyname('tcp') _proto_udp = socket.getprotobyname('udp') + class WKS(dns.rdata.Rdata): + """WKS record @ivar address: the address @@ -39,26 +43,30 @@ class WKS(dns.rdata.Rdata): super(WKS, self).__init__(rdclass, rdtype) self.address = address self.protocol = protocol - self.bitmap = bitmap + if not isinstance(bitmap, bytearray): + self.bitmap = bytearray(bitmap) + else: + self.bitmap = bitmap def to_text(self, origin=None, relativize=True, **kw): bits = [] for i in xrange(0, len(self.bitmap)): - byte = ord(self.bitmap[i]) + byte = self.bitmap[i] for j in xrange(0, 8): if byte & (0x80 >> j): bits.append(str(i * 8 + j)) text = ' '.join(bits) return '%s %d %s' % (self.address, self.protocol, text) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): address = tok.get_string() protocol = tok.get_string() if protocol.isdigit(): protocol = int(protocol) else: protocol = socket.getprotobyname(protocol) - bitmap = [] + bitmap = bytearray() while 1: token = tok.get().unescape() if token.is_eol_or_eof(): @@ -77,19 +85,18 @@ class WKS(dns.rdata.Rdata): l = len(bitmap) if l < i + 1: for j in xrange(l, i + 1): - bitmap.append('\x00') - bitmap[i] = chr(ord(bitmap[i]) | (0x80 >> (serv % 8))) + bitmap.append(0) + bitmap[i] = bitmap[i] | (0x80 >> (serv % 8)) bitmap = dns.rdata._truncate_bitmap(bitmap) return cls(rdclass, rdtype, address, protocol, bitmap) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): file.write(dns.ipv4.inet_aton(self.address)) protocol = struct.pack('!B', self.protocol) file.write(protocol) file.write(self.bitmap) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): address = dns.ipv4.inet_ntoa(wire[current : current + 4]) protocol, = struct.unpack('!B', wire[current + 4 : current + 5]) @@ -98,16 +105,14 @@ class WKS(dns.rdata.Rdata): bitmap = wire[current : current + rdlen].unwrap() return cls(rdclass, rdtype, address, protocol, bitmap) - from_wire = classmethod(from_wire) - def _cmp(self, other): sa = dns.ipv4.inet_aton(self.address) oa = dns.ipv4.inet_aton(other.address) - v = cmp(sa, oa) + v = xcmp(sa, oa) if v == 0: sp = struct.pack('!B', self.protocol) op = struct.pack('!B', other.protocol) - v = cmp(sp, op) + v = xcmp(sp, op) if v == 0: - v = cmp(self.bitmap, other.bitmap) + v = xcmp(self.bitmap, other.bitmap) return v Index: dnspython-1.12.0/dns/rdtypes/dsbase.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/dsbase.py +++ dnspython-1.12.0/dns/rdtypes/dsbase.py @@ -14,11 +14,15 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import struct +import binascii import dns.rdata import dns.rdatatype +from dns._compat import xcmp + class DSBase(dns.rdata.Rdata): + """Base class for rdata that is like a DS record @ivar key_tag: the key tag @@ -47,7 +51,8 @@ class DSBase(dns.rdata.Rdata): dns.rdata._hexify(self.digest, chunksize=128)) - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): key_tag = tok.get_uint16() algorithm = tok.get_uint8() digest_type = tok.get_uint8() @@ -58,20 +63,19 @@ class DSBase(dns.rdata.Rdata): break if not t.is_identifier(): raise dns.exception.SyntaxError - chunks.append(t.value) - digest = ''.join(chunks) - digest = digest.decode('hex_codec') + chunks.append(t.value.encode()) + digest = b''.join(chunks) + digest = binascii.unhexlify(digest) return cls(rdclass, rdtype, key_tag, algorithm, digest_type, digest) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): header = struct.pack("!HBB", self.key_tag, self.algorithm, self.digest_type) file.write(header) file.write(self.digest) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): header = struct.unpack("!HBB", wire[current : current + 4]) current += 4 @@ -79,14 +83,12 @@ class DSBase(dns.rdata.Rdata): digest = wire[current : current + rdlen].unwrap() return cls(rdclass, rdtype, header[0], header[1], header[2], digest) - from_wire = classmethod(from_wire) - def _cmp(self, other): hs = struct.pack("!HBB", self.key_tag, self.algorithm, self.digest_type) ho = struct.pack("!HBB", other.key_tag, other.algorithm, other.digest_type) - v = cmp(hs, ho) + v = xcmp(hs, ho) if v == 0: - v = cmp(self.digest, other.digest) + v = xcmp(self.digest, other.digest) return v Index: dnspython-1.12.0/dns/rdtypes/mxbase.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/mxbase.py +++ dnspython-1.12.0/dns/rdtypes/mxbase.py @@ -15,14 +15,17 @@ """MX-like base classes.""" -import cStringIO +from io import BytesIO import struct import dns.exception import dns.rdata import dns.name +from dns._compat import xcmp + class MXBase(dns.rdata.Rdata): + """Base class for rdata that is like an MX record. @ivar preference: the preference value @@ -41,6 +44,7 @@ class MXBase(dns.rdata.Rdata): exchange = self.exchange.choose_relativity(origin, relativize) return '%d %s' % (self.preference, exchange) + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): preference = tok.get_uint16() exchange = tok.get_name() @@ -48,8 +52,6 @@ class MXBase(dns.rdata.Rdata): tok.get_eol() return cls(rdclass, rdtype, preference, exchange) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): pref = struct.pack("!H", self.preference) file.write(pref) @@ -59,6 +61,7 @@ class MXBase(dns.rdata.Rdata): return struct.pack("!H", self.preference) + \ self.exchange.to_digestable(origin) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): (preference, ) = struct.unpack('!H', wire[current : current + 2]) current += 2 @@ -67,21 +70,19 @@ class MXBase(dns.rdata.Rdata): current) if cused != rdlen: raise dns.exception.FormError - if not origin is None: + if origin is not None: exchange = exchange.relativize(origin) return cls(rdclass, rdtype, preference, exchange) - from_wire = classmethod(from_wire) - def choose_relativity(self, origin = None, relativize = True): self.exchange = self.exchange.choose_relativity(origin, relativize) def _cmp(self, other): sp = struct.pack("!H", self.preference) op = struct.pack("!H", other.preference) - v = cmp(sp, op) + v = xcmp(sp, op) if v == 0: - v = cmp(self.exchange, other.exchange) + v = xcmp(self.exchange, other.exchange) return v class UncompressedMX(MXBase): @@ -93,7 +94,7 @@ class UncompressedMX(MXBase): super(UncompressedMX, self).to_wire(file, None, origin) def to_digestable(self, origin = None): - f = cStringIO.StringIO() + f = BytesIO() self.to_wire(f, None, origin) return f.getvalue() Index: dnspython-1.12.0/dns/rdtypes/nsbase.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/nsbase.py +++ dnspython-1.12.0/dns/rdtypes/nsbase.py @@ -15,13 +15,16 @@ """NS-like base classes.""" -import cStringIO +from io import BytesIO import dns.exception import dns.rdata import dns.name +from dns._compat import xcmp + class NSBase(dns.rdata.Rdata): + """Base class for rdata that is like an NS record. @ivar target: the target name of the rdata @@ -37,36 +40,34 @@ class NSBase(dns.rdata.Rdata): target = self.target.choose_relativity(origin, relativize) return str(target) + @classmethod def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): target = tok.get_name() target = target.choose_relativity(origin, relativize) tok.get_eol() return cls(rdclass, rdtype, target) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): self.target.to_wire(file, compress, origin) def to_digestable(self, origin = None): return self.target.to_digestable(origin) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): (target, cused) = dns.name.from_wire(wire[: current + rdlen], current) if cused != rdlen: raise dns.exception.FormError - if not origin is None: + if origin is not None: target = target.relativize(origin) return cls(rdclass, rdtype, target) - from_wire = classmethod(from_wire) - def choose_relativity(self, origin = None, relativize = True): self.target = self.target.choose_relativity(origin, relativize) def _cmp(self, other): - return cmp(self.target, other.target) + return xcmp(self.target, other.target) class UncompressedNS(NSBase): """Base class for rdata that is like an NS record, but whose name @@ -76,7 +77,7 @@ class UncompressedNS(NSBase): def to_wire(self, file, compress = None, origin = None): super(UncompressedNS, self).to_wire(file, None, origin) - def to_digestable(self, origin = None): - f = cStringIO.StringIO() + def to_digestable(self, origin=None): + f = BytesIO() self.to_wire(f, None, origin) return f.getvalue() Index: dnspython-1.12.0/dns/rdtypes/txtbase.py =================================================================== --- dnspython-1.12.0.orig/dns/rdtypes/txtbase.py +++ dnspython-1.12.0/dns/rdtypes/txtbase.py @@ -15,11 +15,17 @@ """TXT-like base class.""" +import struct + import dns.exception import dns.rdata import dns.tokenizer +from dns._compat import binary_type, text_type +from dns._compat import xcmp + class TXTBase(dns.rdata.Rdata): + """Base class for rdata that is like a TXT record @ivar strings: the text strings @@ -30,8 +36,8 @@ class TXTBase(dns.rdata.Rdata): def __init__(self, rdclass, rdtype, strings): super(TXTBase, self).__init__(rdclass, rdtype) - if isinstance(strings, str): - strings = [ strings ] + if isinstance(strings, text_type): + strings = [strings] self.strings = strings[:] def to_text(self, origin=None, relativize=True, **kw): @@ -42,7 +48,8 @@ class TXTBase(dns.rdata.Rdata): prefix = ' ' return txt - def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True): + @classmethod + def from_text(cls, rdclass, rdtype, tok, origin=None, relativize=True): strings = [] while 1: token = tok.get().unescape() @@ -52,25 +59,27 @@ class TXTBase(dns.rdata.Rdata): raise dns.exception.SyntaxError("expected a string") if len(token.value) > 255: raise dns.exception.SyntaxError("string too long") - strings.append(token.value) + value = token.value + if isinstance(value, binary_type): + strings.append(value) + else: + strings.append(value.encode()) if len(strings) == 0: raise dns.exception.UnexpectedEnd return cls(rdclass, rdtype, strings) - from_text = classmethod(from_text) - def to_wire(self, file, compress = None, origin = None): for s in self.strings: l = len(s) assert l < 256 - byte = chr(l) - file.write(byte) + file.write(struct.pack('!B', l)) file.write(s) + @classmethod def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None): strings = [] while rdlen > 0: - l = ord(wire[current]) + l = wire[current] current += 1 rdlen -= 1 if l > rdlen: @@ -81,7 +90,5 @@ class TXTBase(dns.rdata.Rdata): strings.append(s) return cls(rdclass, rdtype, strings) - from_wire = classmethod(from_wire) - def _cmp(self, other): - return cmp(self.strings, other.strings) + return xcmp(self.strings, other.strings) Index: dnspython-1.12.0/dns/renderer.py =================================================================== --- dnspython-1.12.0.orig/dns/renderer.py +++ dnspython-1.12.0/dns/renderer.py @@ -15,20 +15,25 @@ """Help for building DNS wire format messages""" -import cStringIO +from io import BytesIO import struct import random import time +import sys import dns.exception import dns.tsig +from ._compat import long + QUESTION = 0 ANSWER = 1 AUTHORITY = 2 ADDITIONAL = 3 + class Renderer(object): + """Helper class for building DNS wire-format messages. Most applications can use the higher-level L{dns.message.Message} @@ -51,7 +56,7 @@ class Renderer(object): wire = r.get_wire() @ivar output: where rendering is written - @type output: cStringIO.StringIO object + @type output: BytesIO object @ivar id: the message id @type id: int @ivar flags: the message flags @@ -86,7 +91,7 @@ class Renderer(object): @type origin: dns.name.Namem or None. """ - self.output = cStringIO.StringIO() + self.output = BytesIO() if id is None: self.id = random.randint(0, 65535) else: @@ -97,7 +102,7 @@ class Renderer(object): self.compress = {} self.section = QUESTION self.counts = [0, 0, 0, 0] - self.output.write('\x00' * 12) + self.output.write(b'\x00' * 12) self.mac = '' def _rollback(self, where): @@ -112,7 +117,7 @@ class Renderer(object): self.output.seek(where) self.output.truncate() keys_to_delete = [] - for k, v in self.compress.iteritems(): + for k, v in self.compress.items(): if v >= where: keys_to_delete.append(k) for k in keys_to_delete: @@ -218,13 +223,13 @@ class Renderer(object): """ # make sure the EDNS version in ednsflags agrees with edns - ednsflags &= 0xFF00FFFFL + ednsflags &= long(0xFF00FFFF) ednsflags |= (edns << 16) self._set_section(ADDITIONAL) before = self.output.tell() self.output.write(struct.pack('!BHHIH', 0, dns.rdatatype.OPT, payload, ednsflags, 0)) - if not options is None: + if options is not None: lstart = self.output.tell() for opt in options: stuff = struct.pack("!HH", opt.otype, 0) Index: dnspython-1.12.0/dns/resolver.py =================================================================== --- dnspython-1.12.0.orig/dns/resolver.py +++ dnspython-1.12.0/dns/resolver.py @@ -40,6 +40,8 @@ import dns.rdataclass import dns.rdatatype import dns.reversename +from ._compat import xrange, string_types + if sys.platform == 'win32': import _winreg @@ -110,6 +112,7 @@ class Answer(object): @ivar canonical_name: The canonical name of the query name @type canonical_name: dns.name.Name object """ + def __init__(self, qname, rdtype, rdclass, response, raise_on_no_answer=True): self.qname = qname @@ -153,7 +156,7 @@ class Answer(object): # of qname. try: srrset = response.find_rrset(response.authority, qname, - rdclass, dns.rdatatype.SOA) + rdclass, dns.rdatatype.SOA) if min_ttl == -1 or srrset.ttl < min_ttl: min_ttl = srrset.ttl if srrset[0].minimum < min_ttl: @@ -198,7 +201,9 @@ class Answer(object): def __delslice__(self, i, j): del self.rrset[i:j] + class Cache(object): + """Simple DNS answer cache. @ivar data: A dictionary of cached data @@ -230,7 +235,7 @@ class Cache(object): now = time.time() if self.next_cleaning <= now: keys_to_delete = [] - for (k, v) in self.data.iteritems(): + for (k, v) in self.data.items(): if v.expiration <= now: keys_to_delete.append(k) for k in keys_to_delete: @@ -285,8 +290,8 @@ class Cache(object): try: self.lock.acquire() - if not key is None: - if self.data.has_key(key): + if key is not None: + if key in self.data: del self.data[key] else: self.data = {} @@ -294,9 +299,12 @@ class Cache(object): finally: self.lock.release() + class LRUCacheNode(object): + """LRUCache node. """ + def __init__(self, key, value): self.key = key self.value = value @@ -319,7 +327,9 @@ class LRUCacheNode(object): self.next.prev = self.prev self.prev.next = self.next + class LRUCache(object): + """Bounded least-recently-used DNS answer cache. This cache is better than the simple cache (above) if you're @@ -339,7 +349,8 @@ class LRUCache(object): def __init__(self, max_size=100000): """Initialize a DNS cache. - @param max_size: The maximum number of nodes to cache; the default is 100000. Must be > 1. + @param max_size: The maximum number of nodes to cache; the default is + 100000. Must be > 1. @type max_size: int """ self.data = {} @@ -387,7 +398,7 @@ class LRUCache(object): try: self.lock.acquire() node = self.data.get(key) - if not node is None: + if node is not None: node.unlink() del self.data[node.key] while len(self.data) >= self.max_size: @@ -411,9 +422,9 @@ class LRUCache(object): """ try: self.lock.acquire() - if not key is None: + if key is not None: node = self.data.get(key) - if not node is None: + if node is not None: node.unlink() del self.data[node.key] else: @@ -427,7 +438,9 @@ class LRUCache(object): finally: self.lock.release() + class Resolver(object): + """DNS stub resolver @ivar domain: The domain of this host @@ -461,7 +474,8 @@ class Resolver(object): @type ednsflags: int @ivar payload: The EDNS payload size. The default is 0. @type payload: int - @ivar flags: The message flags to use. The default is None (i.e. not overwritten) + @ivar flags: The message flags to use. The default is None (i.e. not + overwritten) @type flags: int @ivar cache: The cache to use. The default is None. @type cache: dns.resolver.Cache object @@ -469,6 +483,7 @@ class Resolver(object): The default is 'false'. @type retry_servfail: bool """ + def __init__(self, filename='/etc/resolv.conf', configure=True): """Initialize a resolver instance. @@ -515,7 +530,7 @@ class Resolver(object): """Process f as a file in the /etc/resolv.conf format. If f is a string, it is used as the name of the file to open; otherwise it is treated as the file itself.""" - if isinstance(f, str) or isinstance(f, unicode): + if isinstance(f, string_types): try: f = open(f, 'r') except IOError: @@ -571,7 +586,7 @@ class Resolver(object): split_char = self._determine_split_char(nameservers) ns_list = nameservers.split(split_char) for ns in ns_list: - if not ns in self.nameservers: + if ns not in self.nameservers: self.nameservers.append(ns) def _config_win32_domain(self, domain): @@ -586,7 +601,7 @@ class Resolver(object): split_char = self._determine_split_char(search) search_list = search.split(split_char) for s in search_list: - if not s in self.search: + if s not in self.search: self.search.append(dns.name.from_text(s)) def _config_win32_fromkey(self, key): @@ -669,59 +684,59 @@ class Resolver(object): lm.Close() def _win32_is_nic_enabled(self, lm, guid, interface_key): - # Look in the Windows Registry to determine whether the network - # interface corresponding to the given guid is enabled. - # - # (Code contributed by Paul Marks, thanks!) - # - try: - # This hard-coded location seems to be consistent, at least - # from Windows 2000 through Vista. - connection_key = _winreg.OpenKey( - lm, - r'SYSTEM\CurrentControlSet\Control\Network' - r'\{4D36E972-E325-11CE-BFC1-08002BE10318}' - r'\%s\Connection' % guid) - - try: - # The PnpInstanceID points to a key inside Enum - (pnp_id, ttype) = _winreg.QueryValueEx( - connection_key, 'PnpInstanceID') - - if ttype != _winreg.REG_SZ: - raise ValueError - - device_key = _winreg.OpenKey( - lm, r'SYSTEM\CurrentControlSet\Enum\%s' % pnp_id) - - try: - # Get ConfigFlags for this device - (flags, ttype) = _winreg.QueryValueEx( - device_key, 'ConfigFlags') - - if ttype != _winreg.REG_DWORD: - raise ValueError - - # Based on experimentation, bit 0x1 indicates that the - # device is disabled. - return not (flags & 0x1) - - finally: - device_key.Close() - finally: - connection_key.Close() - except (EnvironmentError, ValueError): - # Pre-vista, enabled interfaces seem to have a non-empty - # NTEContextList; this was how dnspython detected enabled - # nics before the code above was contributed. We've retained - # the old method since we don't know if the code above works - # on Windows 95/98/ME. - try: - (nte, ttype) = _winreg.QueryValueEx(interface_key, - 'NTEContextList') - return nte is not None - except WindowsError: - return False + # Look in the Windows Registry to determine whether the network + # interface corresponding to the given guid is enabled. + # + # (Code contributed by Paul Marks, thanks!) + # + try: + # This hard-coded location seems to be consistent, at least + # from Windows 2000 through Vista. + connection_key = _winreg.OpenKey( + lm, + r'SYSTEM\CurrentControlSet\Control\Network' + r'\{4D36E972-E325-11CE-BFC1-08002BE10318}' + r'\%s\Connection' % guid) + + try: + # The PnpInstanceID points to a key inside Enum + (pnp_id, ttype) = _winreg.QueryValueEx( + connection_key, 'PnpInstanceID') + + if ttype != _winreg.REG_SZ: + raise ValueError + + device_key = _winreg.OpenKey( + lm, r'SYSTEM\CurrentControlSet\Enum\%s' % pnp_id) + + try: + # Get ConfigFlags for this device + (flags, ttype) = _winreg.QueryValueEx( + device_key, 'ConfigFlags') + + if ttype != _winreg.REG_DWORD: + raise ValueError + + # Based on experimentation, bit 0x1 indicates that the + # device is disabled. + return not (flags & 0x1) + + finally: + device_key.Close() + finally: + connection_key.Close() + except (EnvironmentError, ValueError): + # Pre-vista, enabled interfaces seem to have a non-empty + # NTEContextList; this was how dnspython detected enabled + # nics before the code above was contributed. We've retained + # the old method since we don't know if the code above works + # on Windows 95/98/ME. + try: + (nte, ttype) = _winreg.QueryValueEx(interface_key, + 'NTEContextList') + return nte is not None + except WindowsError: + return False def _compute_timeout(self, start): now = time.time() @@ -756,7 +771,8 @@ class Resolver(object): @type rdclass: int or string @param tcp: use TCP to make the query (default is False). @type tcp: bool - @param source: bind to this IP address (defaults to machine default IP). + @param source: bind to this IP address (defaults to machine default + IP). @type source: IP address in dotted quad notation @param raise_on_no_answer: raise NoAnswer if there's no answer (defaults is True). @@ -773,13 +789,13 @@ class Resolver(object): @raises NoNameservers: no non-broken nameservers are available to answer the question.""" - if isinstance(qname, (str, unicode)): + if isinstance(qname, string_types): qname = dns.name.from_text(qname, None) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) if dns.rdatatype.is_metatype(rdtype): raise NoMetaqueries - if isinstance(rdclass, (str, unicode)): + if isinstance(rdclass, string_types): rdclass = dns.rdataclass.from_text(rdclass) if dns.rdataclass.is_metaclass(rdclass): raise NoMetaqueries @@ -799,13 +815,13 @@ class Resolver(object): for qname in qnames_to_try: if self.cache: answer = self.cache.get((qname, rdtype, rdclass)) - if not answer is None: + if answer is not None: if answer.rrset is None and raise_on_no_answer: raise NoAnswer else: return answer request = dns.message.make_query(qname, rdtype, rdclass) - if not self.keyname is None: + if self.keyname is not None: request.use_tsig(self.keyring, self.keyname, algorithm=self.keyalgorithm) request.use_edns(self.edns, self.ednsflags, self.payload) @@ -878,7 +894,7 @@ class Resolver(object): if rcode == dns.rcode.YXDOMAIN: raise YXDOMAIN if rcode == dns.rcode.NOERROR or \ - rcode == dns.rcode.NXDOMAIN: + rcode == dns.rcode.NXDOMAIN: break # # We got a response, but we're not happy with the @@ -888,7 +904,7 @@ class Resolver(object): if rcode != dns.rcode.SERVFAIL or not self.retry_servfail: nameservers.remove(nameserver) response = None - if not response is None: + if response is not None: break # # All nameservers failed! @@ -961,6 +977,7 @@ class Resolver(object): default_resolver = None + def get_default_resolver(): """Get the default resolver, initializing it if necessary.""" global default_resolver @@ -968,6 +985,7 @@ def get_default_resolver(): default_resolver = Resolver() return default_resolver + def query(qname, rdtype=dns.rdatatype.A, rdclass=dns.rdataclass.IN, tcp=False, source=None, raise_on_no_answer=True, source_port=0): @@ -980,6 +998,7 @@ def query(qname, rdtype=dns.rdatatype.A, return get_default_resolver().query(qname, rdtype, rdclass, tcp, source, raise_on_no_answer, source_port) + def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None): """Find the name of the zone which contains the specified name. @@ -993,7 +1012,7 @@ def zone_for_name(name, rdclass=dns.rdat @type resolver: dns.resolver.Resolver object or None @rtype: dns.name.Name""" - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, dns.name.root) if resolver is None: resolver = get_default_resolver() @@ -1018,9 +1037,9 @@ def zone_for_name(name, rdclass=dns.rdat # _protocols_for_socktype = { - socket.SOCK_DGRAM : [socket.SOL_UDP], - socket.SOCK_STREAM : [socket.SOL_TCP], - } + socket.SOCK_DGRAM: [socket.SOL_UDP], + socket.SOCK_STREAM: [socket.SOL_TCP], +} _resolver = None _original_getaddrinfo = socket.getaddrinfo @@ -1030,9 +1049,10 @@ _original_gethostbyname = socket.gethost _original_gethostbyname_ex = socket.gethostbyname_ex _original_gethostbyaddr = socket.gethostbyaddr + def _getaddrinfo(host=None, service=None, family=socket.AF_UNSPEC, socktype=0, proto=0, flags=0): - if flags & (socket.AI_ADDRCONFIG|socket.AI_V4MAPPED) != 0: + if flags & (socket.AI_ADDRCONFIG | socket.AI_V4MAPPED) != 0: raise NotImplementedError if host is None and service is None: raise socket.gaierror(socket.EAI_NONAME) @@ -1067,7 +1087,6 @@ def _getaddrinfo(host=None, service=None except: if flags & socket.AI_NUMERICHOST == 0: try: - qname = None if family == socket.AF_INET6 or family == socket.AF_UNSPEC: v6 = _resolver.query(host, dns.rdatatype.AAAA, raise_on_no_answer=False) @@ -1130,6 +1149,7 @@ def _getaddrinfo(host=None, service=None raise socket.gaierror(socket.EAI_NONAME) return tuples + def _getnameinfo(sockaddr, flags=0): host = sockaddr[0] port = sockaddr[1] @@ -1169,28 +1189,32 @@ def _getnameinfo(sockaddr, flags=0): service = socket.getservbyport(port, pname) return (hostname, service) + def _getfqdn(name=None): if name is None: name = socket.gethostname() return _getnameinfo(_getaddrinfo(name, 80)[0][4])[0] + def _gethostbyname(name): return _gethostbyname_ex(name)[2][0] + def _gethostbyname_ex(name): aliases = [] addresses = [] tuples = _getaddrinfo(name, 0, socket.AF_INET, socket.SOCK_STREAM, - socket.SOL_TCP, socket.AI_CANONNAME) + socket.SOL_TCP, socket.AI_CANONNAME) canonical = tuples[0][3] for item in tuples: addresses.append(item[4][0]) # XXX we just ignore aliases return (canonical, aliases, addresses) + def _gethostbyaddr(ip): try: - addr = dns.ipv6.inet_aton(ip) + dns.ipv6.inet_aton(ip) sockaddr = (ip, 80, 0, 0) family = socket.AF_INET6 except: @@ -1207,6 +1231,7 @@ def _gethostbyaddr(ip): # XXX we just ignore aliases return (canonical, aliases, addresses) + def override_system_resolver(resolver=None): """Override the system resolver routines in the socket module with versions which use dnspython's resolver. @@ -1232,6 +1257,7 @@ def override_system_resolver(resolver=No socket.gethostbyname_ex = _gethostbyname_ex socket.gethostbyaddr = _gethostbyaddr + def restore_system_resolver(): """Undo the effects of override_system_resolver(). """ Index: dnspython-1.12.0/dns/reversename.py =================================================================== --- dnspython-1.12.0.orig/dns/reversename.py +++ dnspython-1.12.0/dns/reversename.py @@ -21,6 +21,9 @@ @type ipv6_reverse_domain: dns.name.Name object """ +import binascii +import sys + import dns.name import dns.ipv6 import dns.ipv4 @@ -28,6 +31,7 @@ import dns.ipv4 ipv4_reverse_domain = dns.name.from_text('in-addr.arpa.') ipv6_reverse_domain = dns.name.from_text('ip6.arpa.') + def from_address(text): """Convert an IPv4 or IPv6 address in textual form into a Name object whose value is the reverse-map domain name of the address. @@ -39,17 +43,22 @@ def from_address(text): try: v6 = dns.ipv6.inet_aton(text) if dns.ipv6.is_mapped(v6): - parts = ['%d' % ord(byte) for byte in v6[12:]] + if sys.version_info >= (3,): + parts = ['%d' % byte for byte in v6[12:]] + else: + parts = ['%d' % ord(byte) for byte in v6[12:]] origin = ipv4_reverse_domain else: - parts = list(v6.encode('hex_codec')) + parts = [x for x in str(binascii.hexlify(v6).decode())] origin = ipv6_reverse_domain except: - parts = ['%d' % ord(byte) for byte in dns.ipv4.inet_aton(text)] + parts = ['%d' % + byte for byte in bytearray(dns.ipv4.inet_aton(text))] origin = ipv4_reverse_domain parts.reverse() return dns.name.from_text('.'.join(parts), origin=origin) + def to_address(name): """Convert a reverse map domain name into textual address form. @param name: an IPv4 or IPv6 address in reverse-map form. @@ -60,7 +69,7 @@ def to_address(name): name = name.relativize(ipv4_reverse_domain) labels = list(name.labels) labels.reverse() - text = '.'.join(labels) + text = b'.'.join(labels) # run through inet_aton() to check syntax and make pretty. return dns.ipv4.inet_ntoa(dns.ipv4.inet_aton(text)) elif name.is_subdomain(ipv6_reverse_domain): @@ -71,9 +80,9 @@ def to_address(name): i = 0 l = len(labels) while i < l: - parts.append(''.join(labels[i:i+4])) + parts.append(b''.join(labels[i:i + 4])) i += 4 - text = ':'.join(parts) + text = b':'.join(parts) # run through inet_aton() to check syntax and make pretty. return dns.ipv6.inet_ntoa(dns.ipv6.inet_aton(text)) else: Index: dnspython-1.12.0/dns/rrset.py =================================================================== --- dnspython-1.12.0.orig/dns/rrset.py +++ dnspython-1.12.0/dns/rrset.py @@ -15,12 +15,16 @@ """DNS RRsets (an RRset is a named rdataset)""" + import dns.name import dns.rdataset import dns.rdataclass import dns.renderer +from ._compat import string_types + class RRset(dns.rdataset.Rdataset): + """A DNS RRset (named rdataset). RRset inherits from Rdataset, and RRsets can be treated as @@ -51,7 +55,7 @@ class RRset(dns.rdataset.Rdataset): ctext = '' else: ctext = '(' + dns.rdatatype.to_text(self.covers) + ')' - if not self.deleting is None: + if self.deleting is not None: dtext = ' delete=' + dns.rdataclass.to_text(self.deleting) else: dtext = '' @@ -122,11 +126,11 @@ def from_text_list(name, ttl, rdclass, r @rtype: dns.rrset.RRset object """ - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, None) - if isinstance(rdclass, (str, unicode)): + if isinstance(rdclass, string_types): rdclass = dns.rdataclass.from_text(rdclass) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) r = RRset(name, rdclass, rdtype) r.update_ttl(ttl) @@ -135,6 +139,7 @@ def from_text_list(name, ttl, rdclass, r r.add(rd) return r + def from_text(name, ttl, rdclass, rdtype, *text_rdatas): """Create an RRset with the specified name, TTL, class, and type and with the specified rdatas in text format. @@ -144,6 +149,7 @@ def from_text(name, ttl, rdclass, rdtype return from_text_list(name, ttl, rdclass, rdtype, text_rdatas) + def from_rdata_list(name, ttl, rdatas): """Create an RRset with the specified name and TTL, and with the specified list of rdata objects. @@ -151,7 +157,7 @@ def from_rdata_list(name, ttl, rdatas): @rtype: dns.rrset.RRset object """ - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, None) if len(rdatas) == 0: @@ -161,10 +167,10 @@ def from_rdata_list(name, ttl, rdatas): if r is None: r = RRset(name, rd.rdclass, rd.rdtype) r.update_ttl(ttl) - first_time = False r.add(rd) return r + def from_rdata(name, ttl, *rdatas): """Create an RRset with the specified name and TTL, and with the specified rdata objects. Index: dnspython-1.12.0/dns/set.py =================================================================== --- dnspython-1.12.0.orig/dns/set.py +++ dnspython-1.12.0/dns/set.py @@ -15,7 +15,9 @@ """A simple Set class.""" + class Set(object): + """A simple set class. Sets are not in Python until 2.3, and rdata are not immutable so @@ -35,7 +37,7 @@ class Set(object): """ self.items = [] - if not items is None: + if items is not None: for item in items: self.add(item) @@ -44,7 +46,7 @@ class Set(object): def add(self, item): """Add an item to the set.""" - if not item in self.items: + if item not in self.items: self.items.append(item) def remove(self, item): @@ -208,10 +210,10 @@ class Set(object): # Yes, this is inefficient but the sets we're dealing with are # usually quite small, so it shouldn't hurt too much. for item in self.items: - if not item in other.items: + if item not in other.items: return False for item in other.items: - if not item in self.items: + if item not in self.items: return False return True @@ -245,7 +247,7 @@ class Set(object): if not isinstance(other, Set): raise ValueError('other must be a Set instance') for item in self.items: - if not item in other.items: + if item not in other.items: return False return True @@ -258,6 +260,6 @@ class Set(object): if not isinstance(other, Set): raise ValueError('other must be a Set instance') for item in other.items: - if not item in self.items: + if item not in self.items: return False return True Index: dnspython-1.12.0/dns/tokenizer.py =================================================================== --- dnspython-1.12.0.orig/dns/tokenizer.py +++ dnspython-1.12.0/dns/tokenizer.py @@ -15,23 +15,24 @@ """Tokenize DNS master file format""" -import cStringIO +from io import StringIO import sys import dns.exception import dns.name import dns.ttl +from ._compat import long, text_type, binary_type _DELIMITERS = { - ' ' : True, - '\t' : True, - '\n' : True, - ';' : True, - '(' : True, - ')' : True, - '"' : True } + ' ': True, + '\t': True, + '\n': True, + ';': True, + '(': True, + ')': True, + '"': True} -_QUOTING_DELIMITERS = { '"' : True } +_QUOTING_DELIMITERS = {'"': True} EOF = 0 EOL = 1 @@ -155,7 +156,9 @@ class Token(object): else: raise IndexError + class Tokenizer(object): + """A DNS master file format tokenizer. A token is a (type, value) tuple, where I{type} is an int, and @@ -197,8 +200,12 @@ class Tokenizer(object): @type filename: string """ - if isinstance(f, str): - f = cStringIO.StringIO(f) + if isinstance(f, text_type): + f = StringIO(f) + if filename is None: + filename = '<string>' + elif isinstance(f, binary_type): + f = StringIO(f.decode()) if filename is None: filename = '<string>' else: @@ -257,7 +264,7 @@ class Tokenizer(object): @raises UngetBufferFull: there is already an ungotten char """ - if not self.ungotten_char is None: + if self.ungotten_char is not None: raise UngetBufferFull self.ungotten_char = c @@ -281,7 +288,7 @@ class Tokenizer(object): return skipped skipped += 1 - def get(self, want_leading = False, want_comment = False): + def get(self, want_leading=False, want_comment=False): """Get the next token. @param want_leading: If True, return a WHITESPACE token if the @@ -295,7 +302,7 @@ class Tokenizer(object): @raises dns.exception.SyntaxError: input was badly formed """ - if not self.ungotten_token is None: + if self.ungotten_token is not None: token = self.ungotten_token self.ungotten_token = None if token.is_whitespace(): @@ -352,7 +359,8 @@ class Tokenizer(object): return Token(COMMENT, token) elif c == '': if self.multiline: - raise dns.exception.SyntaxError('unbalanced parentheses') + raise dns.exception.SyntaxError( + 'unbalanced parentheses') return Token(EOF) elif self.multiline: self.skip_whitespace() @@ -415,7 +423,7 @@ class Tokenizer(object): @raises UngetBufferFull: there is already an ungotten token """ - if not self.ungotten_token is None: + if self.ungotten_token is not None: raise UngetBufferFull self.ungotten_token = token @@ -429,6 +437,8 @@ class Tokenizer(object): raise StopIteration return token + __next__ = next + def __iter__(self): return self @@ -458,7 +468,8 @@ class Tokenizer(object): value = self.get_int() if value < 0 or value > 255: - raise dns.exception.SyntaxError('%d is not an unsigned 8-bit integer' % value) + raise dns.exception.SyntaxError( + '%d is not an unsigned 8-bit integer' % value) return value def get_uint16(self): @@ -471,7 +482,8 @@ class Tokenizer(object): value = self.get_int() if value < 0 or value > 65535: - raise dns.exception.SyntaxError('%d is not an unsigned 16-bit integer' % value) + raise dns.exception.SyntaxError( + '%d is not an unsigned 16-bit integer' % value) return value def get_uint32(self): @@ -488,8 +500,9 @@ class Tokenizer(object): if not token.value.isdigit(): raise dns.exception.SyntaxError('expecting an integer') value = long(token.value) - if value < 0 or value > 4294967296L: - raise dns.exception.SyntaxError('%d is not an unsigned 32-bit integer' % value) + if value < 0 or value > long(4294967296): + raise dns.exception.SyntaxError( + '%d is not an unsigned 32-bit integer' % value) return value def get_string(self, origin=None): @@ -537,7 +550,9 @@ class Tokenizer(object): token = self.get() if not token.is_eol_or_eof(): - raise dns.exception.SyntaxError('expected EOL or EOF, got %d "%s"' % (token.ttype, token.value)) + raise dns.exception.SyntaxError( + 'expected EOL or EOF, got %d "%s"' % (token.ttype, + token.value)) return token.value def get_ttl(self): Index: dnspython-1.12.0/dns/tsig.py =================================================================== --- dnspython-1.12.0.orig/dns/tsig.py +++ dnspython-1.12.0/dns/tsig.py @@ -23,6 +23,7 @@ import dns.exception import dns.hash import dns.rdataclass import dns.name +from ._compat import long, string_types class BadTime(dns.exception.DNSException): """Raised if the current time is not within the TSIG's validity time.""" @@ -68,6 +69,7 @@ BADKEY = 17 BADTIME = 18 BADTRUNC = 22 + def sign(wire, keyname, secret, time, fudge, original_id, error, other_data, request_mac, ctx=None, multi=False, first=True, algorithm=default_algorithm): @@ -93,9 +95,9 @@ def sign(wire, keyname, secret, time, fu ctx.update(keyname.to_digestable()) ctx.update(struct.pack('!H', dns.rdataclass.ANY)) ctx.update(struct.pack('!I', 0)) - long_time = time + 0L - upper_time = (long_time >> 32) & 0xffffL - lower_time = long_time & 0xffffffffL + long_time = time + long(0) + upper_time = (long_time >> 32) & long(0xffff) + lower_time = long_time & long(0xffffffff) time_mac = struct.pack('!HIH', upper_time, lower_time, fudge) pre_mac = algorithm_name + time_mac ol = len(other_data) @@ -119,12 +121,14 @@ def sign(wire, keyname, secret, time, fu ctx = None return (tsig_rdata, mac, ctx) + def hmac_md5(wire, keyname, secret, time, fudge, original_id, error, other_data, request_mac, ctx=None, multi=False, first=True, algorithm=default_algorithm): return sign(wire, keyname, secret, time, fudge, original_id, error, other_data, request_mac, ctx, multi, first, algorithm) + def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata, tsig_rdlen, ctx=None, multi=False, first=True): """Validate the specified TSIG rdata against the other input parameters. @@ -144,13 +148,13 @@ def validate(wire, keyname, secret, now, (aname, used) = dns.name.from_wire(wire, current) current = current + used (upper_time, lower_time, fudge, mac_size) = \ - struct.unpack("!HIHH", wire[current:current + 10]) - time = ((upper_time + 0L) << 32) + (lower_time + 0L) + struct.unpack("!HIHH", wire[current:current + 10]) + time = ((upper_time + long(0)) << 32) + (lower_time + long(0)) current += 10 mac = wire[current:current + mac_size] current += mac_size (original_id, error, other_size) = \ - struct.unpack("!HHH", wire[current:current + 6]) + struct.unpack("!HHH", wire[current:current + 6]) current += 6 other_data = wire[current:current + other_size] current += other_size @@ -178,23 +182,6 @@ def validate(wire, keyname, secret, now, raise BadSignature return ctx -_hashes = None - -def _maybe_add_hash(tsig_alg, hash_alg): - try: - _hashes[tsig_alg] = dns.hash.get(hash_alg) - except KeyError: - pass - -def _setup_hashes(): - global _hashes - _hashes = {} - _maybe_add_hash(HMAC_SHA224, 'SHA224') - _maybe_add_hash(HMAC_SHA256, 'SHA256') - _maybe_add_hash(HMAC_SHA384, 'SHA384') - _maybe_add_hash(HMAC_SHA512, 'SHA512') - _maybe_add_hash(HMAC_SHA1, 'SHA1') - _maybe_add_hash(HMAC_MD5, 'MD5') def get_algorithm(algorithm): """Returns the wire format string and the hash module to use for the @@ -204,24 +191,16 @@ def get_algorithm(algorithm): @raises NotImplementedError: I{algorithm} is not supported """ - global _hashes - if _hashes is None: - _setup_hashes() - - if isinstance(algorithm, (str, unicode)): + if isinstance(algorithm, string_types): algorithm = dns.name.from_text(algorithm) - if sys.hexversion < 0x02050200 and \ - (algorithm == HMAC_SHA384 or algorithm == HMAC_SHA512): - raise NotImplementedError("TSIG algorithm " + str(algorithm) + - " requires Python 2.5.2 or later") - try: - return (algorithm.to_digestable(), _hashes[algorithm]) + return (algorithm.to_digestable(), dns.hash.hashes[algorithm]) except KeyError: raise NotImplementedError("TSIG algorithm " + str(algorithm) + " is not supported") + def get_algorithm_and_mac(wire, tsig_rdata, tsig_rdlen): """Return the tsig algorithm for the specified tsig_rdata @raises FormError: The TSIG is badly formed. @@ -230,7 +209,7 @@ def get_algorithm_and_mac(wire, tsig_rda (aname, used) = dns.name.from_wire(wire, current) current = current + used (upper_time, lower_time, fudge, mac_size) = \ - struct.unpack("!HIHH", wire[current:current + 10]) + struct.unpack("!HIHH", wire[current:current + 10]) current += 10 mac = wire[current:current + mac_size] current += mac_size Index: dnspython-1.12.0/dns/tsigkeyring.py =================================================================== --- dnspython-1.12.0.orig/dns/tsigkeyring.py +++ dnspython-1.12.0/dns/tsigkeyring.py @@ -19,11 +19,12 @@ import base64 import dns.name + def from_text(textring): """Convert a dictionary containing (textual DNS name, base64 secret) pairs into a binary keyring which has (dns.name.Name, binary secret) pairs. @rtype: dict""" - + keyring = {} for keytext in textring: keyname = dns.name.from_text(keytext) @@ -31,11 +32,12 @@ def from_text(textring): keyring[keyname] = secret return keyring + def to_text(keyring): """Convert a dictionary containing (dns.name.Name, binary secret) pairs into a text keyring which has (textual DNS name, base64 secret) pairs. @rtype: dict""" - + textring = {} for keyname in keyring: keytext = keyname.to_text() Index: dnspython-1.12.0/dns/ttl.py =================================================================== --- dnspython-1.12.0.orig/dns/ttl.py +++ dnspython-1.12.0/dns/ttl.py @@ -16,6 +16,7 @@ """DNS TTL conversion.""" import dns.exception +from ._compat import long class BadTTL(dns.exception.SyntaxError): pass @@ -36,8 +37,8 @@ def from_text(text): else: if not text[0].isdigit(): raise BadTTL - total = 0L - current = 0L + total = long(0) + current = long(0) for c in text: if c.isdigit(): current *= 10 @@ -45,13 +46,13 @@ def from_text(text): else: c = c.lower() if c == 'w': - total += current * 604800L + total += current * long(604800) elif c == 'd': - total += current * 86400L + total += current * long(86400) elif c == 'h': - total += current * 3600L + total += current * long(3600) elif c == 'm': - total += current * 60L + total += current * long(60) elif c == 's': total += current else: @@ -59,6 +60,6 @@ def from_text(text): current = 0 if not current == 0: raise BadTTL("trailing integer") - if total < 0L or total > 2147483647L: + if total < long(0) or total > long(2147483647): raise BadTTL("TTL should be between 0 and 2^31 - 1 (inclusive)") return total Index: dnspython-1.12.0/dns/update.py =================================================================== --- dnspython-1.12.0.orig/dns/update.py +++ dnspython-1.12.0/dns/update.py @@ -15,6 +15,7 @@ """DNS Dynamic Update Support""" + import dns.message import dns.name import dns.opcode @@ -22,8 +23,11 @@ import dns.rdata import dns.rdataclass import dns.rdataset import dns.tsig +from ._compat import string_types + class Update(dns.message.Message): + def __init__(self, zone, rdclass=dns.rdataclass.IN, keyring=None, keyname=None, keyalgorithm=dns.tsig.default_algorithm): """Initialize a new DNS Update object. @@ -51,7 +55,7 @@ class Update(dns.message.Message): """ super(Update, self).__init__() self.flags |= dns.opcode.to_flags(dns.opcode.UPDATE) - if isinstance(zone, (str, unicode)): + if isinstance(zone, string_types): zone = dns.name.from_text(zone) self.origin = zone if isinstance(rdclass, str): @@ -85,7 +89,7 @@ class Update(dns.message.Message): - ttl, rdtype, string...""" - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, None) if isinstance(args[0], dns.rdataset.Rdataset): for rds in args: @@ -135,7 +139,7 @@ class Update(dns.message.Message): - rdtype, [string...]""" - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, None) if len(args) == 0: rrset = self.find_rrset(self.authority, name, dns.rdataclass.ANY, @@ -152,7 +156,7 @@ class Update(dns.message.Message): self._add_rr(name, 0, rd, dns.rdataclass.NONE) else: rdtype = args.pop(0) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) if len(args) == 0: rrset = self.find_rrset(self.authority, name, @@ -193,16 +197,16 @@ class Update(dns.message.Message): - rdtype, string...""" - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, None) if len(args) == 0: - rrset = self.find_rrset(self.answer, name, - dns.rdataclass.ANY, dns.rdatatype.ANY, - dns.rdatatype.NONE, None, - True, True) + self.find_rrset(self.answer, name, + dns.rdataclass.ANY, dns.rdatatype.ANY, + dns.rdatatype.NONE, None, + True, True) elif isinstance(args[0], dns.rdataset.Rdataset) or \ - isinstance(args[0], dns.rdata.Rdata) or \ - len(args) > 1: + isinstance(args[0], dns.rdata.Rdata) or \ + len(args) > 1: if not isinstance(args[0], dns.rdataset.Rdataset): # Add a 0 TTL args = list(args) @@ -210,31 +214,31 @@ class Update(dns.message.Message): self._add(False, self.answer, name, *args) else: rdtype = args[0] - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) - rrset = self.find_rrset(self.answer, name, - dns.rdataclass.ANY, rdtype, - dns.rdatatype.NONE, None, - True, True) + self.find_rrset(self.answer, name, + dns.rdataclass.ANY, rdtype, + dns.rdatatype.NONE, None, + True, True) def absent(self, name, rdtype=None): """Require that an owner name (and optionally an rdata type) does not exist as a prerequisite to the execution of the update.""" - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, None) if rdtype is None: - rrset = self.find_rrset(self.answer, name, - dns.rdataclass.NONE, dns.rdatatype.ANY, - dns.rdatatype.NONE, None, - True, True) + self.find_rrset(self.answer, name, + dns.rdataclass.NONE, dns.rdatatype.ANY, + dns.rdatatype.NONE, None, + True, True) else: - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) - rrset = self.find_rrset(self.answer, name, - dns.rdataclass.NONE, rdtype, - dns.rdatatype.NONE, None, - True, True) + self.find_rrset(self.answer, name, + dns.rdataclass.NONE, rdtype, + dns.rdatatype.NONE, None, + True, True) def to_wire(self, origin=None, max_size=65535): """Return a string containing the update in DNS compressed wire Index: dnspython-1.12.0/dns/version.py =================================================================== --- dnspython-1.12.0.orig/dns/version.py +++ dnspython-1.12.0/dns/version.py @@ -31,4 +31,4 @@ else: (MAJOR, MINOR, MICRO, RELEASELEVEL, SERIAL) hexversion = MAJOR << 24 | MINOR << 16 | MICRO << 8 | RELEASELEVEL << 4 | \ - SERIAL + SERIAL Index: dnspython-1.12.0/dns/wiredata.py =================================================================== --- dnspython-1.12.0.orig/dns/wiredata.py +++ dnspython-1.12.0/dns/wiredata.py @@ -15,9 +15,9 @@ """DNS Wire Data Helper""" -import sys import dns.exception +from ._compat import binary_type, string_types # Figure out what constant python passes for an unspecified slice bound. # It's supposed to be sys.maxint, yet on 64-bit windows sys.maxint is 2^31 - 1 @@ -25,19 +25,26 @@ import dns.exception # extra comparisons, duplicating code, or weakening WireData, we just figure # out what constant Python will use. + class _SliceUnspecifiedBound(str): + def __getslice__(self, i, j): return j _unspecified_bound = _SliceUnspecifiedBound('')[1:] -class WireData(str): + +class WireData(binary_type): # WireData is a string with stricter slicing + def __getitem__(self, key): try: - return WireData(super(WireData, self).__getitem__(key)) + if isinstance(key, slice): + return WireData(super(WireData, self).__getitem__(key)) + return bytearray(self.unwrap())[key] except IndexError: raise dns.exception.FormError + def __getslice__(self, i, j): try: if j == _unspecified_bound: @@ -53,6 +60,7 @@ class WireData(str): return WireData(super(WireData, self).__getslice__(i, j)) except IndexError: raise dns.exception.FormError + def __iter__(self): i = 0 while 1: @@ -61,11 +69,16 @@ class WireData(str): i += 1 except dns.exception.FormError: raise StopIteration + def unwrap(self): - return str(self) + return binary_type(self) + def maybe_wrap(wire): - if not isinstance(wire, WireData): - return WireData(wire) - else: + if isinstance(wire, WireData): return wire + elif isinstance(wire, binary_type): + return WireData(wire) + elif isinstance(wire, string_types): + return WireData(wire.encode()) + raise ValueError("unhandled type %s" % type(wire)) Index: dnspython-1.12.0/dns/zone.py =================================================================== --- dnspython-1.12.0.orig/dns/zone.py +++ dnspython-1.12.0/dns/zone.py @@ -19,6 +19,7 @@ from __future__ import generators import sys import re +from io import BytesIO import dns.exception import dns.name @@ -30,6 +31,7 @@ import dns.rrset import dns.tokenizer import dns.ttl import dns.grange +from ._compat import xrange, string_types, text_type, binary_type try: from cStringIO import StringIO @@ -114,13 +116,14 @@ class Zone(object): return not self.__eq__(other) def _validate_name(self, name): - if isinstance(name, (str, unicode)): + if isinstance(name, string_types): name = dns.name.from_text(name, None) elif not isinstance(name, dns.name.Name): raise KeyError("name parameter must be convertable to a DNS name") if name.is_absolute(): if not name.is_subdomain(self.origin): - raise KeyError("name parameter must be a subdomain of the zone origin") + raise KeyError( + "name parameter must be a subdomain of the zone origin") if self.relativize: name = name.relativize(self.origin) return name @@ -152,12 +155,11 @@ class Zone(object): def values(self): return self.nodes.values() - def iteritems(self): - return self.nodes.iteritems() - def items(self): return self.nodes.items() + iteritems = items + def get(self, key): key = self._validate_name(key) return self.nodes.get(key) @@ -212,7 +214,7 @@ class Zone(object): """ name = self._validate_name(name) - if self.nodes.has_key(name): + if name in self.nodes: del self.nodes[name] def find_rdataset(self, name, rdtype, covers=dns.rdatatype.NONE, @@ -244,9 +246,9 @@ class Zone(object): """ name = self._validate_name(name) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) - if isinstance(covers, (str, unicode)): + if isinstance(covers, string_types): covers = dns.rdatatype.from_text(covers) node = self.find_node(name, create) return node.find_rdataset(self.rdclass, rdtype, covers, create) @@ -307,12 +309,12 @@ class Zone(object): """ name = self._validate_name(name) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) - if isinstance(covers, (str, unicode)): + if isinstance(covers, string_types): covers = dns.rdatatype.from_text(covers) node = self.get_node(name) - if not node is None: + if node is not None: node.delete_rdataset(self.rdclass, rdtype, covers) if len(node) == 0: self.delete_node(name) @@ -370,9 +372,9 @@ class Zone(object): """ name = self._validate_name(name) - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) - if isinstance(covers, (str, unicode)): + if isinstance(covers, string_types): covers = dns.rdatatype.from_text(covers) rdataset = self.nodes[name].find_rdataset(self.rdclass, rdtype, covers) rrset = dns.rrset.RRset(name, self.rdclass, rdtype, covers) @@ -426,9 +428,9 @@ class Zone(object): @type covers: int or string """ - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) - if isinstance(covers, (str, unicode)): + if isinstance(covers, string_types): covers = dns.rdatatype.from_text(covers) for (name, node) in self.iteritems(): for rds in node: @@ -449,9 +451,9 @@ class Zone(object): @type covers: int or string """ - if isinstance(rdtype, (str, unicode)): + if isinstance(rdtype, string_types): rdtype = dns.rdatatype.from_text(rdtype) - if isinstance(covers, (str, unicode)): + if isinstance(covers, string_types): covers = dns.rdatatype.from_text(covers) for (name, node) in self.iteritems(): for rds in node: @@ -478,31 +480,32 @@ class Zone(object): @type nl: string or None """ - if sys.hexversion >= 0x02030000: - # allow Unicode filenames - str_type = basestring - else: - str_type = str + str_type = string_types + if nl is None: - opts = 'w' + opts = 'wb' else: opts = 'wb' + if isinstance(f, str_type): - f = file(f, opts) + f = open(f, opts) want_close = True else: want_close = False try: if sorted: - names = self.keys() + names = list(self.keys()) names.sort() else: names = self.iterkeys() for n in names: l = self[n].to_text(n, origin=self.origin, relativize=relativize) + if isinstance(l, text_type): + l = l.encode() if nl is None: - print >> f, l + f.write(l) + f.write('\n') else: f.write(l) f.write(nl) @@ -525,7 +528,7 @@ class Zone(object): LF on POSIX, CRLF on Windows, CR on Macintosh). @type nl: string or None """ - temp_buffer = StringIO() + temp_buffer = BytesIO() self.to_file(temp_buffer, sorted, relativize, nl) return_value = temp_buffer.getvalue() temp_buffer.close() @@ -549,6 +552,7 @@ class Zone(object): class _MasterReader(object): + """Read a DNS master file @ivar tok: The tokenizer @@ -577,7 +581,7 @@ class _MasterReader(object): def __init__(self, tok, origin, rdclass, relativize, zone_factory=Zone, allow_include=False, check_origin=True): - if isinstance(origin, (str, unicode)): + if isinstance(origin, string_types): origin = dns.name.from_text(origin) self.tok = tok self.current_origin = origin @@ -601,9 +605,10 @@ class _MasterReader(object): # Name if self.current_origin is None: raise UnknownOrigin - token = self.tok.get(want_leading = True) + token = self.tok.get(want_leading=True) if not token.is_whitespace(): - self.last_name = dns.name.from_text(token.value, self.current_origin) + self.last_name = dns.name.from_text( + token.value, self.current_origin) else: token = self.tok.get() if token.is_eol_or_eof(): @@ -643,7 +648,8 @@ class _MasterReader(object): try: rdtype = dns.rdatatype.from_text(token.value) except: - raise dns.exception.SyntaxError("unknown rdatatype '%s'" % token.value) + raise dns.exception.SyntaxError( + "unknown rdatatype '%s'" % token.value) n = self.zone.nodes.get(name) if n is None: n = self.zone.node_factory() @@ -662,7 +668,8 @@ class _MasterReader(object): # We convert them to syntax errors so that we can emit # helpful filename:line info. (ty, va) = sys.exc_info()[:2] - raise dns.exception.SyntaxError("caught exception %s: %s" % (str(ty), str(va))) + raise dns.exception.SyntaxError( + "caught exception %s: %s" % (str(ty), str(va))) rd.choose_relativity(self.zone.origin, self.relativize) covers = rd.covers() @@ -764,7 +771,7 @@ class _MasterReader(object): raise dns.exception.SyntaxError except: raise dns.exception.SyntaxError("unknown rdatatype '%s'" % - token.value) + token.value) # lhs (required) try: @@ -772,28 +779,26 @@ class _MasterReader(object): except: raise dns.exception.SyntaxError - lmod, lsign, loffset, lwidth, lbase = self._parse_modify(lhs) rmod, rsign, roffset, rwidth, rbase = self._parse_modify(rhs) for i in range(start, stop + 1, step): # +1 because bind is inclusive and python is exclusive - if lsign == '+': + if lsign == u'+': lindex = i + int(loffset) - elif lsign == '-': + elif lsign == u'-': lindex = i - int(loffset) - if rsign == '-': + if rsign == u'-': rindex = i - int(roffset) - elif rsign == '+': + elif rsign == u'+': rindex = i + int(roffset) lzfindex = str(lindex).zfill(int(lwidth)) rzfindex = str(rindex).zfill(int(rwidth)) - - name = lhs.replace('$%s' % (lmod), lzfindex) - rdata = rhs.replace('$%s' % (rmod), rzfindex) + name = lhs.replace(u'$%s' % (lmod), lzfindex) + rdata = rhs.replace(u'$%s' % (rmod), rzfindex) self.last_name = dns.name.from_text(name, self.current_origin) name = self.last_name @@ -822,7 +827,7 @@ class _MasterReader(object): # helpful filename:line info. (ty, va) = sys.exc_info()[:2] raise dns.exception.SyntaxError("caught exception %s: %s" % - (str(ty), str(va))) + (str(ty), str(va))) rd.choose_relativity(self.zone.origin, self.relativize) covers = rd.covers() @@ -840,7 +845,7 @@ class _MasterReader(object): while 1: token = self.tok.get(True, True) if token.is_eof(): - if not self.current_file is None: + if self.current_file is not None: self.current_file.close() if len(self.saved_state) > 0: (self.tok, @@ -855,29 +860,31 @@ class _MasterReader(object): elif token.is_comment(): self.tok.get_eol() continue - elif token.value[0] == '$': - u = token.value.upper() - if u == '$TTL': + elif token.value[0] == u'$': + c = token.value.upper() + if c == u'$TTL': token = self.tok.get() if not token.is_identifier(): raise dns.exception.SyntaxError("bad $TTL") self.ttl = dns.ttl.from_text(token.value) self.tok.get_eol() - elif u == '$ORIGIN': + elif c == u'$ORIGIN': self.current_origin = self.tok.get_name() self.tok.get_eol() if self.zone.origin is None: self.zone.origin = self.current_origin - elif u == '$INCLUDE' and self.allow_include: + elif c == u'$INCLUDE' and self.allow_include: token = self.tok.get() filename = token.value token = self.tok.get() if token.is_identifier(): - new_origin = dns.name.from_text(token.value, \ - self.current_origin) + new_origin =\ + dns.name.from_text(token.value, + self.current_origin) self.tok.get_eol() elif not token.is_eol_or_eof(): - raise dns.exception.SyntaxError("bad origin in $INCLUDE") + raise dns.exception.SyntaxError( + "bad origin in $INCLUDE") else: new_origin = self.current_origin self.saved_state.append((self.tok, @@ -885,29 +892,32 @@ class _MasterReader(object): self.last_name, self.current_file, self.ttl)) - self.current_file = file(filename, 'r') + self.current_file = open(filename, 'r') self.tok = dns.tokenizer.Tokenizer(self.current_file, filename) self.current_origin = new_origin - elif u == '$GENERATE': + elif c == u'$GENERATE': self._generate_line() else: - raise dns.exception.SyntaxError("Unknown master file directive '" + u + "'") + raise dns.exception.SyntaxError( + "Unknown master file directive '" + c + "'") continue self.tok.unget(token) self._rr_line() - except dns.exception.SyntaxError, detail: + except dns.exception.SyntaxError as detail: (filename, line_number) = self.tok.where() if detail is None: detail = "syntax error" - raise dns.exception.SyntaxError("%s:%d: %s" % (filename, line_number, detail)) + raise dns.exception.SyntaxError( + "%s:%d: %s" % (filename, line_number, detail)) # Now that we're done reading, do some basic checking of the zone. if self.check_origin: self.zone.check_origin() -def from_text(text, origin = None, rdclass = dns.rdataclass.IN, - relativize = True, zone_factory=Zone, filename=None, + +def from_text(text, origin=None, rdclass=dns.rdataclass.IN, + relativize=True, zone_factory=Zone, filename=None, allow_include=False, check_origin=True): """Build a zone object from a master file format string. @@ -949,8 +959,9 @@ def from_text(text, origin = None, rdcla reader.read() return reader.zone -def from_file(f, origin = None, rdclass = dns.rdataclass.IN, - relativize = True, zone_factory=Zone, filename=None, + +def from_file(f, origin=None, rdclass=dns.rdataclass.IN, + relativize=True, zone_factory=Zone, filename=None, allow_include=True, check_origin=True): """Read a master file and build a zone object. @@ -980,17 +991,13 @@ def from_file(f, origin = None, rdclass @rtype: dns.zone.Zone object """ - if sys.hexversion >= 0x02030000: - # allow Unicode filenames; turn on universal newline support - str_type = basestring - opts = 'rU' - else: - str_type = str - opts = 'r' + str_type = string_types + opts = 'rU' + if isinstance(f, str_type): if filename is None: filename = f - f = file(f, opts) + f = open(f, opts) want_close = True else: if filename is None: @@ -1005,6 +1012,7 @@ def from_file(f, origin = None, rdclass f.close() return z + def from_xfr(xfr, zone_factory=Zone, relativize=True, check_origin=True): """Convert the output of a zone transfer generator into a zone object. Index: dnspython-1.12.0/tests/test_bugs.py =================================================================== --- dnspython-1.12.0.orig/tests/test_bugs.py +++ dnspython-1.12.0/tests/test_bugs.py @@ -24,15 +24,15 @@ class BugsTestCase(unittest.TestCase): def test_float_LOC(self): rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.LOC, - "30 30 0.000 N 100 30 0.000 W 10.00m 20m 2000m 20m") + u"30 30 0.000 N 100 30 0.000 W 10.00m 20m 2000m 20m") self.failUnless(rdata.float_latitude == 30.5) self.failUnless(rdata.float_longitude == -100.5) def test_SOA_BIND8_TTL(self): rdata1 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, - "a b 100 1s 1m 1h 1d") + u"a b 100 1s 1m 1h 1d") rdata2 = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, - "a b 100 1 60 3600 86400") + u"a b 100 1 60 3600 86400") self.failUnless(rdata1 == rdata2) def test_TTL_bounds_check(self): @@ -42,7 +42,7 @@ class BugsTestCase(unittest.TestCase): def test_empty_NSEC3_window(self): rdata = dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NSEC3, - "1 0 100 ABCD SCBCQHKU35969L2A68P3AD59LHF30715") + u"1 0 100 ABCD SCBCQHKU35969L2A68P3AD59LHF30715") self.failUnless(rdata.windows == []) def test_zero_size_APL(self): Index: dnspython-1.12.0/tests/test_dnssec.py =================================================================== --- dnspython-1.12.0.orig/tests/test_dnssec.py +++ dnspython-1.12.0/tests/test_dnssec.py @@ -230,4 +230,4 @@ if __name__ == '__main__': if import_ok: unittest.main() else: - print 'skipping DNSSEC tests because pycrypto is not installed' + print('skipping DNSSEC tests because pycrypto is not installed') Index: dnspython-1.12.0/tests/test_generate.py =================================================================== --- dnspython-1.12.0.orig/tests/test_generate.py +++ dnspython-1.12.0/tests/test_generate.py @@ -16,7 +16,6 @@ import sys sys.path.insert(0, '../') # Force the local project to be *the* dns -import cStringIO import filecmp import os import unittest @@ -27,9 +26,11 @@ import dns.rdataclass import dns.rdatatype import dns.rrset import dns.zone +from dns._compat import long import pprint + pp = pprint.PrettyPrinter(indent=2) import pdb @@ -133,6 +134,9 @@ ns2 3600 IN A 10.0.0.2 $GENERATE 27-28 $.2 PTR zlb${-26}.oob """ +def _rdata_sort(a): + return (a[0], a[2].rdclass, a[2].to_text()) + class GenerateTestCase(unittest.TestCase): @@ -149,7 +153,7 @@ class GenerateTestCase(unittest.TestCase def testIterateAllRdatas2(self): z = dns.zone.from_text(example_text2, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, @@ -187,13 +191,13 @@ class GenerateTestCase(unittest.TestCase dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.5'))] - exl.sort() + exl.sort(key=_rdata_sort) self.failUnless(l == exl) def testIterateAllRdatas3(self): z = dns.zone.from_text(example_text3, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, @@ -227,271 +231,271 @@ class GenerateTestCase(unittest.TestCase (dns.name.from_text('foo8', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.8'))] - exl.sort() + exl.sort(key=_rdata_sort) self.failUnless(l == exl) def testGenerate1(self): z = dns.zone.from_text(example_text4, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), - 300L, + long(300), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('wp-db01.services.mozilla.com', None), - 0L, + long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), (dns.name.from_text('wp-db02.services.mozilla.com', None), - 0L, + long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), (dns.name.from_text('wp-db03.services.mozilla.com', None), - 0L, + long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.'))] - exl.sort() - self.failUnless(l == exl) + exl.sort(key=_rdata_sort) + self.assertEqual(l, exl) def testGenerate2(self): z = dns.zone.from_text(example_text5, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), - 300L, + long(300), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), - (dns.name.from_text('wp-db21.services.mozilla.com', None), 0L, + (dns.name.from_text('wp-db21.services.mozilla.com', None), long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), - (dns.name.from_text('wp-db22.services.mozilla.com', None), 0L, + (dns.name.from_text('wp-db22.services.mozilla.com', None), long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), - (dns.name.from_text('wp-db23.services.mozilla.com', None), 0L, + (dns.name.from_text('wp-db23.services.mozilla.com', None), long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.'))] - exl.sort() + exl.sort(key=_rdata_sort) self.failUnless(l == exl) def testGenerate3(self): z = dns.zone.from_text(example_text6, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), - 300L, + long(300), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), - (dns.name.from_text('wp-db21.services.mozilla.com', None), 0L, + (dns.name.from_text('wp-db21.services.mozilla.com', None), long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), - (dns.name.from_text('wp-db22.services.mozilla.com', None), 0L, + (dns.name.from_text('wp-db22.services.mozilla.com', None), long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), - (dns.name.from_text('wp-db23.services.mozilla.com', None), 0L, + (dns.name.from_text('wp-db23.services.mozilla.com', None), long(0), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.'))] - exl.sort() + exl.sort(key=_rdata_sort) self.failUnless(l == exl) def testGenerate4(self): z = dns.zone.from_text(example_text7, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), - 300L, + long(300), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), - (dns.name.from_text('sync1.db', None), 3600L, + (dns.name.from_text('sync1.db', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), - (dns.name.from_text('sync2.db', None), 3600L, + (dns.name.from_text('sync2.db', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), - (dns.name.from_text('sync3.db', None), 3600L, + (dns.name.from_text('sync3.db', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0'))] - exl.sort() + exl.sort(key=_rdata_sort) self.failUnless(l == exl) def testGenerate6(self): z = dns.zone.from_text(example_text9, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), - 300L, + long(300), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), - (dns.name.from_text('wp-db01', None), 3600L, + (dns.name.from_text('wp-db01', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), - (dns.name.from_text('wp-db02', None), 3600L, + (dns.name.from_text('wp-db02', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), - (dns.name.from_text('sync1.db', None), 3600L, + (dns.name.from_text('sync1.db', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), - (dns.name.from_text('sync2.db', None), 3600L, + (dns.name.from_text('sync2.db', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), - (dns.name.from_text('sync3.db', None), 3600L, + (dns.name.from_text('sync3.db', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0'))] - exl.sort() + exl.sort(key=_rdata_sort) self.failUnless(l == exl) def testGenerate7(self): z = dns.zone.from_text(example_text10, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), - 300L, + long(300), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), - 3600L, + long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), - (dns.name.from_text('27.2', None), 3600L, + (dns.name.from_text('27.2', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR, 'zlb1.oob')), - (dns.name.from_text('28.2', None), 3600L, + (dns.name.from_text('28.2', None), long(3600), dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR, 'zlb2.oob'))] - exl.sort() + exl.sort(key=_rdata_sort) self.failUnless(l == exl) Index: dnspython-1.12.0/tests/test_grange.py =================================================================== --- dnspython-1.12.0.orig/tests/test_grange.py +++ dnspython-1.12.0/tests/test_grange.py @@ -16,7 +16,6 @@ import sys sys.path.insert(0, '../') -import cStringIO import filecmp import os import unittest Index: dnspython-1.12.0/tests/test_message.py =================================================================== --- dnspython-1.12.0.orig/tests/test_message.py +++ dnspython-1.12.0/tests/test_message.py @@ -13,13 +13,15 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO import os import unittest +import binascii import dns.exception import dns.message +from dns._compat import xrange + query_text = """id 1234 opcode QUERY rcode NOERROR @@ -33,10 +35,10 @@ wwww.dnspython.org. IN A ;AUTHORITY ;ADDITIONAL""" -goodhex = '04d201000001000000000001047777777709646e73707974686f6e' \ - '036f726700000100010000291000000080000000' +goodhex = b'04d201000001000000000001047777777709646e73707974686f6e' \ + b'036f726700000100010000291000000080000000' -goodwire = goodhex.decode('hex_codec') +goodwire = binascii.unhexlify(goodhex) answer_text = """id 1234 opcode QUERY @@ -66,7 +68,7 @@ goodhex2 = '04d2 8500 0001 0001 0003 000 'c091 0001 0001 00000e10 0004 cc98ba96' -goodwire2 = goodhex2.replace(' ', '').decode('hex_codec') +goodwire2 = binascii.unhexlify(goodhex2.replace(' ', '').encode()) query_text_2 = """id 1234 opcode QUERY @@ -81,10 +83,10 @@ wwww.dnspython.org. IN A ;AUTHORITY ;ADDITIONAL""" -goodhex3 = '04d2010f0001000000000001047777777709646e73707974686f6e' \ - '036f726700000100010000291000ff0080000000' +goodhex3 = b'04d2010f0001000000000001047777777709646e73707974686f6e' \ + b'036f726700000100010000291000ff0080000000' -goodwire3 = goodhex3.decode('hex_codec') +goodwire3 = binascii.unhexlify(goodhex3) class MessageTestCase(unittest.TestCase): @@ -116,7 +118,7 @@ class MessageTestCase(unittest.TestCase) def test_EDNS_from_wire1(self): m = dns.message.from_wire(goodwire) - self.failUnless(str(m) == query_text) + self.assertEqual(str(m), query_text) def test_EDNS_to_wire2(self): q = dns.message.from_text(query_text_2) @@ -146,13 +148,13 @@ class MessageTestCase(unittest.TestCase) def test_TrailingJunk(self): def bad(): - badwire = goodwire + '\x00' + badwire = goodwire + b'\x00' m = dns.message.from_wire(badwire) self.failUnlessRaises(dns.message.TrailingJunk, bad) def test_ShortHeader(self): def bad(): - badwire = '\x00' * 11 + badwire = b'\x00' * 11 m = dns.message.from_wire(badwire) self.failUnlessRaises(dns.message.ShortHeader, bad) Index: dnspython-1.12.0/tests/test_name.py =================================================================== --- dnspython-1.12.0.orig/tests/test_name.py +++ dnspython-1.12.0/tests/test_name.py @@ -15,7 +15,7 @@ import unittest -import cStringIO +from io import BytesIO import socket import dns.name @@ -28,15 +28,15 @@ class NameTestCase(unittest.TestCase): def testFromTextRel1(self): n = dns.name.from_text('foo.bar') - self.failUnless(n.labels == ('foo', 'bar', '')) + self.assertEqual(n.labels, (b'foo', b'bar', b'')) def testFromTextRel2(self): n = dns.name.from_text('foo.bar', origin=self.origin) - self.failUnless(n.labels == ('foo', 'bar', 'example', '')) + self.assertEqual(n.labels, (b'foo', b'bar', b'example', b'')) def testFromTextRel3(self): n = dns.name.from_text('foo.bar', origin=None) - self.failUnless(n.labels == ('foo', 'bar')) + self.assertEqual(n.labels, (b'foo', b'bar')) def testFromTextRel4(self): n = dns.name.from_text('@', origin=None) @@ -48,33 +48,33 @@ class NameTestCase(unittest.TestCase): def testFromTextAbs1(self): n = dns.name.from_text('foo.bar.') - self.failUnless(n.labels == ('foo', 'bar', '')) + self.assertEqual(n.labels,(b'foo', b'bar', b'')) def testTortureFromText(self): good = [ - r'.', - r'a', - r'a.', - r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - r'\000.\008.\010.\032.\046.\092.\099.\255', - r'\\', - r'\..\.', - r'\\.\\', - r'!"#%&/()=+-', - r'\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255', + br'.', + br'a', + br'a.', + br'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + br'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + br'\000.\008.\010.\032.\046.\092.\099.\255', + br'\\', + br'\..\.', + br'\\.\\', + br'!"#%&/()=+-', + br'\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255', ] bad = [ - r'..', - r'.a', - r'\\..', - '\\', # yes, we don't want the 'r' prefix! - r'\0', - r'\00', - r'\00Z', - r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - r'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', - r'\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255', + br'..', + br'.a', + br'\\..', + b'\\', # yes, we don't want the 'r' prefix! + br'\0', + br'\00', + br'\00Z', + br'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + br'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa', + br'\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255.\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255', ] for t in good: try: @@ -134,7 +134,7 @@ class NameTestCase(unittest.TestCase): def testHash1(self): n1 = dns.name.from_text('fOo.COM') n2 = dns.name.from_text('foo.com') - self.failUnless(hash(n1) == hash(n2)) + self.assertEqual(hash(n1), hash(n2)) def testCompare1(self): n1 = dns.name.from_text('a') @@ -155,9 +155,6 @@ class NameTestCase(unittest.TestCase): def testCompare4(self): self.failUnless(dns.name.root != 1) - def testCompare5(self): - self.failUnless(dns.name.root < 1 or dns.name.root > 1) - def testSubdomain1(self): self.failUnless(not dns.name.empty.is_subdomain(dns.name.root)) @@ -197,60 +194,60 @@ class NameTestCase(unittest.TestCase): def testCanonicalize1(self): n = dns.name.from_text('FOO.bar', origin=self.origin) c = n.canonicalize() - self.failUnless(c.labels == ('foo', 'bar', 'example', '')) + self.assertEqual(c.labels, (b'foo', b'bar', b'example', b'')) def testToText1(self): n = dns.name.from_text('FOO.bar', origin=self.origin) t = n.to_text() - self.failUnless(t == 'FOO.bar.example.') + self.assertEqual(t, b'FOO.bar.example.') def testToText2(self): n = dns.name.from_text('FOO.bar', origin=self.origin) t = n.to_text(True) - self.failUnless(t == 'FOO.bar.example') + self.assertEqual(t, b'FOO.bar.example') def testToText3(self): n = dns.name.from_text('FOO.bar', origin=None) t = n.to_text() - self.failUnless(t == 'FOO.bar') + self.assertEqual(t, b'FOO.bar') def testToText4(self): t = dns.name.empty.to_text() - self.failUnless(t == '@') + self.assertEqual(t, b'@') def testToText5(self): t = dns.name.root.to_text() - self.failUnless(t == '.') + self.assertEqual(t, b'.') def testToText6(self): n = dns.name.from_text('FOO bar', origin=None) t = n.to_text() - self.failUnless(t == r'FOO\032bar') + self.assertEqual(t, br'FOO\032bar') def testToText7(self): n = dns.name.from_text(r'FOO\.bar', origin=None) t = n.to_text() - self.failUnless(t == r'FOO\.bar') + self.assertEqual(t, b'FOO\.bar') def testToText8(self): n = dns.name.from_text(r'\070OO\.bar', origin=None) t = n.to_text() - self.failUnless(t == r'FOO\.bar') + self.assertEqual(t, b'FOO\.bar') def testSlice1(self): n = dns.name.from_text(r'a.b.c.', origin=None) s = n[:] - self.failUnless(s == ('a', 'b', 'c', '')) + self.assertEqual(s, (b'a', b'b', b'c', b'')) def testSlice2(self): n = dns.name.from_text(r'a.b.c.', origin=None) s = n[:2] - self.failUnless(s == ('a', 'b')) + self.assertEqual(s, (b'a', b'b')) def testSlice3(self): n = dns.name.from_text(r'a.b.c.', origin=None) s = n[2:] - self.failUnless(s == ('c', '')) + self.assertEqual(s, (b'c', b'')) def testEmptyLabel1(self): def bad(): @@ -329,13 +326,13 @@ class NameTestCase(unittest.TestCase): def testBadEscape(self): def bad(): n = dns.name.from_text(r'a.b\0q1.c.') - print n + print(n) self.failUnlessRaises(dns.name.BadEscape, bad) def testDigestable1(self): n = dns.name.from_text('FOO.bar') d = n.to_digestable() - self.failUnless(d == '\x03foo\x03bar\x00') + self.assertEqual(d, b'\x03foo\x03bar\x00') def testDigestable2(self): n1 = dns.name.from_text('FOO.bar') @@ -346,12 +343,12 @@ class NameTestCase(unittest.TestCase): def testDigestable3(self): d = dns.name.root.to_digestable() - self.failUnless(d == '\x00') + self.assertEqual(d, b'\x00') def testDigestable4(self): n = dns.name.from_text('FOO.bar', None) d = n.to_digestable(dns.name.root) - self.failUnless(d == '\x03foo\x03bar\x00') + self.assertEqual(d, b'\x03foo\x03bar\x00') def testBadDigestable(self): def bad(): @@ -361,56 +358,56 @@ class NameTestCase(unittest.TestCase): def testToWire1(self): n = dns.name.from_text('FOO.bar') - f = cStringIO.StringIO() + f = BytesIO() compress = {} n.to_wire(f, compress) - self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00') + self.assertEqual(f.getvalue(), b'\x03FOO\x03bar\x00') def testToWire2(self): n = dns.name.from_text('FOO.bar') - f = cStringIO.StringIO() + f = BytesIO() compress = {} n.to_wire(f, compress) n.to_wire(f, compress) - self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00') + self.assertEqual(f.getvalue(), b'\x03FOO\x03bar\x00\xc0\x00') def testToWire3(self): n1 = dns.name.from_text('FOO.bar') n2 = dns.name.from_text('foo.bar') - f = cStringIO.StringIO() + f = BytesIO() compress = {} n1.to_wire(f, compress) n2.to_wire(f, compress) - self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00') + self.assertEqual(f.getvalue(), b'\x03FOO\x03bar\x00\xc0\x00') def testToWire4(self): n1 = dns.name.from_text('FOO.bar') n2 = dns.name.from_text('a.foo.bar') - f = cStringIO.StringIO() + f = BytesIO() compress = {} n1.to_wire(f, compress) n2.to_wire(f, compress) - self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\x01\x61\xc0\x00') + self.assertEqual(f.getvalue(), b'\x03FOO\x03bar\x00\x01\x61\xc0\x00') def testToWire5(self): n1 = dns.name.from_text('FOO.bar') n2 = dns.name.from_text('a.foo.bar') - f = cStringIO.StringIO() + f = BytesIO() compress = {} n1.to_wire(f, compress) n2.to_wire(f, None) - self.failUnless(f.getvalue() == \ - '\x03FOO\x03bar\x00\x01\x61\x03foo\x03bar\x00') + self.assertEqual(f.getvalue(), + b'\x03FOO\x03bar\x00\x01\x61\x03foo\x03bar\x00') def testToWire6(self): n = dns.name.from_text('FOO.bar') v = n.to_wire() - self.failUnless(v == '\x03FOO\x03bar\x00') + self.assertEqual(v, b'\x03FOO\x03bar\x00') def testBadToWire(self): def bad(): n = dns.name.from_text('FOO.bar', None) - f = cStringIO.StringIO() + f = BytesIO() compress = {} n.to_wire(f, compress) self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad) @@ -551,7 +548,7 @@ class NameTestCase(unittest.TestCase): n2 == en2 and cused2 == ecused2) def testFromWire1(self): - w = '\x03foo\x00\x01a\xc0\x00\x01b\xc0\x05' + w = b'\x03foo\x00\x01a\xc0\x00\x01b\xc0\x05' current = 0 (n1, cused1) = dns.name.from_wire(w, current) current += cused1 @@ -570,25 +567,25 @@ class NameTestCase(unittest.TestCase): def testBadFromWire1(self): def bad(): - w = '\x03foo\xc0\x04' + w = b'\x03foo\xc0\x04' (n, cused) = dns.name.from_wire(w, 0) self.failUnlessRaises(dns.name.BadPointer, bad) def testBadFromWire2(self): def bad(): - w = '\x03foo\xc0\x05' + w = b'\x03foo\xc0\x05' (n, cused) = dns.name.from_wire(w, 0) self.failUnlessRaises(dns.name.BadPointer, bad) def testBadFromWire3(self): def bad(): - w = '\xbffoo' + w = b'\xbffoo' (n, cused) = dns.name.from_wire(w, 0) self.failUnlessRaises(dns.name.BadLabelType, bad) def testBadFromWire4(self): def bad(): - w = '\x41foo' + w = b'\x41foo' (n, cused) = dns.name.from_wire(w, 0) self.failUnlessRaises(dns.name.BadLabelType, bad) @@ -616,48 +613,48 @@ class NameTestCase(unittest.TestCase): def testFromUnicode1(self): n = dns.name.from_text(u'foo.bar') - self.failUnless(n.labels == ('foo', 'bar', '')) + self.assertEqual(n.labels, (b'foo', b'bar', b'')) def testFromUnicode2(self): n = dns.name.from_text(u'foo\u1234bar.bar') - self.failUnless(n.labels == ('xn--foobar-r5z', 'bar', '')) + self.assertEqual(n.labels, (b'xn--foobar-r5z', b'bar', b'')) def testFromUnicodeAlternateDot1(self): n = dns.name.from_text(u'foo\u3002bar') - self.failUnless(n.labels == ('foo', 'bar', '')) + self.assertEqual(n.labels, (b'foo', b'bar', b'')) def testFromUnicodeAlternateDot2(self): n = dns.name.from_text(u'foo\uff0ebar') - self.failUnless(n.labels == ('foo', 'bar', '')) + self.assertEqual(n.labels, (b'foo', b'bar', b'')) def testFromUnicodeAlternateDot3(self): n = dns.name.from_text(u'foo\uff61bar') - self.failUnless(n.labels == ('foo', 'bar', '')) + self.assertEqual(n.labels, (b'foo', b'bar', b'')) def testToUnicode1(self): n = dns.name.from_text(u'foo.bar') s = n.to_unicode() - self.failUnless(s == u'foo.bar.') + self.assertEqual(s, u'foo.bar.') def testToUnicode2(self): n = dns.name.from_text(u'foo\u1234bar.bar') s = n.to_unicode() - self.failUnless(s == u'foo\u1234bar.bar.') + self.assertEqual(s, u'foo\u1234bar.bar.') def testToUnicode3(self): n = dns.name.from_text('foo.bar') s = n.to_unicode() - self.failUnless(s == u'foo.bar.') + self.assertEqual(s, u'foo.bar.') def testReverseIPv4(self): e = dns.name.from_text('1.0.0.127.in-addr.arpa.') n = dns.reversename.from_address('127.0.0.1') - self.failUnless(e == n) + self.assertEqual(e, n) def testReverseIPv6(self): e = dns.name.from_text('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.') - n = dns.reversename.from_address('::1') - self.failUnless(e == n) + n = dns.reversename.from_address(b'::1') + self.assertEqual(e, n) def testReverseIPv6MappedIpv4(self): e = dns.name.from_text('1.0.0.127.in-addr.arpa.') @@ -676,15 +673,15 @@ class NameTestCase(unittest.TestCase): def testForwardIPv4(self): n = dns.name.from_text('1.0.0.127.in-addr.arpa.') - e = '127.0.0.1' + e = b'127.0.0.1' text = dns.reversename.to_address(n) - self.failUnless(text == e) + self.assertEqual(text, e) def testForwardIPv6(self): n = dns.name.from_text('1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa.') - e = '::1' + e = b'::1' text = dns.reversename.to_address(n) - self.failUnless(text == e) + self.assertEqual(text, e) def testE164ToEnum(self): text = '+1 650 555 1212' @@ -694,9 +691,9 @@ class NameTestCase(unittest.TestCase): def testEnumToE164(self): n = dns.name.from_text('2.1.2.1.5.5.5.0.5.6.1.e164.arpa.') - e = '+16505551212' + e = b'+16505551212' text = dns.e164.to_e164(n) - self.failUnless(text == e) + self.assertEqual(text,e) if __name__ == '__main__': unittest.main() Index: dnspython-1.12.0/tests/test_ntoaaton.py =================================================================== --- dnspython-1.12.0.orig/tests/test_ntoaaton.py +++ dnspython-1.12.0/tests/test_ntoaaton.py @@ -18,6 +18,7 @@ import unittest import dns.exception import dns.ipv4 import dns.ipv6 +import binascii # for convenience aton4 = dns.ipv4.inet_aton @@ -25,7 +26,7 @@ ntoa4 = dns.ipv4.inet_ntoa aton6 = dns.ipv6.inet_aton ntoa6 = dns.ipv6.inet_ntoa -v4_bad_addrs = ['256.1.1.1', '1.1.1', '1.1.1.1.1', '01.1.1.1', +v4_bad_addrs = ['256.1.1.1', '1.1.1', '1.1.1.1.1', #'01.1.1.1', '+1.1.1.1', '1.1.1.1+', '1..2.3.4', '.1.2.3.4', '1.2.3.4.'] @@ -49,8 +50,8 @@ class NtoAAtoNTestCase(unittest.TestCase def test_aton5(self): a = aton6('1:2:3:4:5:6:7:8') - self.failUnless(a == \ - '00010002000300040005000600070008'.decode('hex_codec')) + self.assertEqual(a, + binascii.unhexlify(b'00010002000300040005000600070008')) def test_bad_aton1(self): def bad(): @@ -69,89 +70,89 @@ class NtoAAtoNTestCase(unittest.TestCase def test_aton1(self): a = aton6('::') - self.failUnless(a == '\x00' * 16) + self.assertEqual(a, b'\x00' * 16) def test_aton2(self): a = aton6('::1') - self.failUnless(a == '\x00' * 15 + '\x01') + self.assertEqual(a, b'\x00' * 15 + b'\x01') def test_aton3(self): a = aton6('::10.0.0.1') - self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01') + self.assertEqual(a, b'\x00' * 12 + b'\x0a\x00\x00\x01') def test_aton4(self): a = aton6('abcd::dcba') - self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba') + self.assertEqual(a, b'\xab\xcd' + b'\x00' * 12 + b'\xdc\xba') def test_ntoa1(self): - b = '00010002000300040005000600070008'.decode('hex_codec') + b = binascii.unhexlify(b'00010002000300040005000600070008') t = ntoa6(b) - self.failUnless(t == '1:2:3:4:5:6:7:8') + self.assertEqual(t, b'1:2:3:4:5:6:7:8') def test_ntoa2(self): - b = '\x00' * 16 + b = b'\x00' * 16 t = ntoa6(b) - self.failUnless(t == '::') + self.assertEqual(t, b'::') def test_ntoa3(self): - b = '\x00' * 15 + '\x01' + b = b'\x00' * 15 + b'\x01' t = ntoa6(b) - self.failUnless(t == '::1') + self.assertEqual(t, b'::1') def test_ntoa4(self): - b = '\x80' + '\x00' * 15 + b = b'\x80' + b'\x00' * 15 t = ntoa6(b) - self.failUnless(t == '8000::') + self.assertEqual(t, b'8000::') def test_ntoa5(self): - b = '\x01\xcd' + '\x00' * 12 + '\x03\xef' + b = b'\x01\xcd' + b'\x00' * 12 + b'\x03\xef' t = ntoa6(b) - self.failUnless(t == '1cd::3ef') + self.assertEqual(t, b'1cd::3ef') def test_ntoa6(self): - b = 'ffff00000000ffff000000000000ffff'.decode('hex_codec') + b = binascii.unhexlify(b'ffff00000000ffff000000000000ffff') t = ntoa6(b) - self.failUnless(t == 'ffff:0:0:ffff::ffff') + self.assertEqual(t, b'ffff:0:0:ffff::ffff') def test_ntoa7(self): - b = '00000000ffff000000000000ffffffff'.decode('hex_codec') + b = binascii.unhexlify(b'00000000ffff000000000000ffffffff') t = ntoa6(b) - self.failUnless(t == '0:0:ffff::ffff:ffff') + self.assertEqual(t, b'0:0:ffff::ffff:ffff') def test_ntoa8(self): - b = 'ffff0000ffff00000000ffff00000000'.decode('hex_codec') + b = binascii.unhexlify(b'ffff0000ffff00000000ffff00000000') t = ntoa6(b) - self.failUnless(t == 'ffff:0:ffff::ffff:0:0') + self.assertEqual(t, b'ffff:0:ffff::ffff:0:0') def test_ntoa9(self): - b = '0000000000000000000000000a000001'.decode('hex_codec') + b = binascii.unhexlify(b'0000000000000000000000000a000001') t = ntoa6(b) - self.failUnless(t == '::10.0.0.1') + self.assertEqual(t, b'::10.0.0.1') def test_ntoa10(self): - b = '0000000000000000000000010a000001'.decode('hex_codec') + b = binascii.unhexlify(b'0000000000000000000000010a000001') t = ntoa6(b) - self.failUnless(t == '::1:a00:1') + self.assertEqual(t, b'::1:a00:1') def test_ntoa11(self): - b = '00000000000000000000ffff0a000001'.decode('hex_codec') + b = binascii.unhexlify(b'00000000000000000000ffff0a000001') t = ntoa6(b) - self.failUnless(t == '::ffff:10.0.0.1') + self.assertEqual(t, b'::ffff:10.0.0.1') def test_ntoa12(self): - b = '000000000000000000000000ffffffff'.decode('hex_codec') + b = binascii.unhexlify(b'000000000000000000000000ffffffff') t = ntoa6(b) - self.failUnless(t == '::255.255.255.255') + self.assertEqual(t, b'::255.255.255.255') def test_ntoa13(self): - b = '00000000000000000000ffffffffffff'.decode('hex_codec') + b = binascii.unhexlify(b'00000000000000000000ffffffffffff') t = ntoa6(b) - self.failUnless(t == '::ffff:255.255.255.255') + self.assertEqual(t, b'::ffff:255.255.255.255') def test_ntoa14(self): - b = '0000000000000000000000000001ffff'.decode('hex_codec') + b = binascii.unhexlify(b'0000000000000000000000000001ffff') t = ntoa6(b) - self.failUnless(t == '::0.1.255.255') + self.assertEqual(t, b'::0.1.255.255') def test_bad_ntoa1(self): def bad(): @@ -164,14 +165,14 @@ class NtoAAtoNTestCase(unittest.TestCase self.failUnlessRaises(ValueError, bad) def test_good_v4_aton(self): - pairs = [('1.2.3.4', '\x01\x02\x03\x04'), - ('255.255.255.255', '\xff\xff\xff\xff'), - ('0.0.0.0', '\x00\x00\x00\x00')] + pairs = [(b'1.2.3.4', b'\x01\x02\x03\x04'), + (b'255.255.255.255', b'\xff\xff\xff\xff'), + (b'0.0.0.0', b'\x00\x00\x00\x00')] for (t, b) in pairs: b1 = aton4(t) t1 = ntoa4(b1) - self.failUnless(b1 == b) - self.failUnless(t1 == t) + self.assertEqual(b1, b) + self.assertEqual(t1, t) def test_bad_v4_aton(self): def make_bad(a): @@ -179,6 +180,7 @@ class NtoAAtoNTestCase(unittest.TestCase return aton4(a) return bad for addr in v4_bad_addrs: + print(addr) self.failUnlessRaises(dns.exception.SyntaxError, make_bad(addr)) def test_bad_v6_aton(self): @@ -194,10 +196,10 @@ class NtoAAtoNTestCase(unittest.TestCase self.failUnlessRaises(dns.exception.SyntaxError, make_bad(addr)) def test_rfc5952_section_4_2_2(self): - addr = '2001:db8:0:1:1:1:1:1' + addr = b'2001:db8:0:1:1:1:1:1' b1 = aton6(addr) t1 = ntoa6(b1) - self.failUnless(t1 == addr) + self.assertEqual(t1, addr) def test_is_mapped(self): t1 = '2001:db8:0:1:1:1:1:1' Index: dnspython-1.12.0/tests/test_resolver.py =================================================================== --- dnspython-1.12.0.orig/tests/test_resolver.py +++ dnspython-1.12.0/tests/test_resolver.py @@ -13,7 +13,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO +from io import StringIO import select import sys import time @@ -25,8 +25,9 @@ import dns.name import dns.rdataclass import dns.rdatatype import dns.resolver +from dns._compat import xrange -resolv_conf = """ +resolv_conf = u""" /t/t # comment 1 ; comment 2 @@ -55,7 +56,7 @@ class BaseResolverTests(object): if sys.platform != 'win32': def testRead(self): - f = cStringIO.StringIO(resolv_conf) + f = StringIO(resolv_conf) r = dns.resolver.Resolver(f) self.failUnless(r.nameservers == ['10.0.0.1', '10.0.0.2'] and r.domain == dns.name.from_text('foo')) Index: dnspython-1.12.0/tests/test_tokenizer.py =================================================================== --- dnspython-1.12.0.orig/tests/test_tokenizer.py +++ dnspython-1.12.0/tests/test_tokenizer.py @@ -14,6 +14,10 @@ # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import unittest +try: + import unittest2 as unittest +except ImportError: + import unittest import dns.exception import dns.tokenizer Index: dnspython-1.12.0/tests/test_update.py =================================================================== --- dnspython-1.12.0.orig/tests/test_update.py +++ dnspython-1.12.0/tests/test_update.py @@ -18,6 +18,7 @@ import unittest import dns.update import dns.rdata import dns.rdataset +import binascii goodhex = '0001 2800 0001 0005 0007 0000' \ '076578616d706c6500 0006 0001' \ @@ -34,7 +35,7 @@ goodhex = '0001 2800 0001 0005 0007 0000 '04626c617ac00c 0001 00ff 00000000 0000' \ 'c049 00ff 00ff 00000000 0000' -goodwire = goodhex.replace(' ', '').decode('hex_codec') +goodwire = binascii.unhexlify(goodhex.replace(' ', '').encode()) update_text="""id 1 opcode UPDATE Index: dnspython-1.12.0/tests/test_zone.py =================================================================== --- dnspython-1.12.0.orig/tests/test_zone.py +++ dnspython-1.12.0/tests/test_zone.py @@ -13,7 +13,7 @@ # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -import cStringIO +from io import BytesIO, StringIO import filecmp import os import unittest @@ -25,6 +25,9 @@ import dns.rdatatype import dns.rrset import dns.zone +def here(filename): + return os.path.join(os.path.dirname(__file__), filename) + example_text = """$TTL 3600 $ORIGIN example. @ soa foo bar 1 2 3 4 5 @@ -83,8 +86,8 @@ $ORIGIN example. @ soa foo bar 1 2 3 4 5 """ -include_text = """$INCLUDE "example" -""" +include_text = """$INCLUDE "%s" +""" % here("example") bad_directive_text = """$FOO bar $ORIGIN example. @@ -95,54 +98,61 @@ ns1 1d1s a 10.0.0.1 ns2 1w1D1h1m1S a 10.0.0.2 """ -_keep_output = False +_keep_output = True + +def _rdata_sort(a): + return (a[0], a[2].rdclass, a[2].to_text()) class ZoneTestCase(unittest.TestCase): def testFromFile1(self): - z = dns.zone.from_file('example', 'example') + z = dns.zone.from_file(here('example'), 'example') ok = False try: - z.to_file('example1.out', nl='\x0a') - ok = filecmp.cmp('example1.out', 'example1.good') + z.to_file(here('example1.out'), nl=b'\x0a') + ok = filecmp.cmp(here('example1.out'), + here('example1.good')) finally: if not _keep_output: - os.unlink('example1.out') + os.unlink(here('example1.out')) self.failUnless(ok) def testFromFile2(self): - z = dns.zone.from_file('example', 'example', relativize=False) + z = dns.zone.from_file(here('example'), 'example', relativize=False) ok = False try: - z.to_file('example2.out', relativize=False, nl='\x0a') - ok = filecmp.cmp('example2.out', 'example2.good') + z.to_file(here('example2.out'), relativize=False, nl=b'\x0a') + ok = filecmp.cmp(here('example2.out'), + here('example2.good')) finally: if not _keep_output: - os.unlink('example2.out') + os.unlink(here('example2.out')) self.failUnless(ok) def testToText(self): - z = dns.zone.from_file('example', 'example') + z = dns.zone.from_file(here('example'), 'example') ok = False try: - text_zone = z.to_text(nl='\x0a') - f = open('example3.out', 'wb') + text_zone = z.to_text(nl=b'\x0a') + f = open(here('example3.out'), 'wb') f.write(text_zone) f.close() - ok = filecmp.cmp('example3.out', 'example3.good') + ok = filecmp.cmp(here('example3.out'), + here('example3.good')) finally: if not _keep_output: - os.unlink('example3.out') + os.unlink(here('example3.out')) self.failUnless(ok) def testFromText(self): z = dns.zone.from_text(example_text, 'example.', relativize=True) - f = cStringIO.StringIO() - names = z.nodes.keys() + f = StringIO() + names = list(z.nodes.keys()) names.sort() for n in names: - print >> f, z[n].to_text(n) - self.failUnless(f.getvalue() == example_text_output) + f.write(z[n].to_text(n)) + f.write(u'\n') + self.assertEqual(f.getvalue(), example_text_output) def testTorture1(self): # @@ -150,10 +160,10 @@ class ZoneTestCase(unittest.TestCase): # for each RR in the zone, convert the rdata into wire format # and then back out, and see if we get equal rdatas. # - f = cStringIO.StringIO() + f = BytesIO() o = dns.name.from_text('example.') - z = dns.zone.from_file('example', o) - for (name, node) in z.iteritems(): + z = dns.zone.from_file(here('example'), o) + for (name, node) in z.items(): for rds in node: for rd in rds: f.seek(0) @@ -336,7 +346,7 @@ class ZoneTestCase(unittest.TestCase): def testIterateAllRdatas(self): z = dns.zone.from_text(example_text, 'example.', relativize=True) l = list(z.iterate_rdatas()) - l.sort() + l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, @@ -361,6 +371,7 @@ class ZoneTestCase(unittest.TestCase): 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2'))] + exl.sort(key=_rdata_sort) self.failUnless(l == exl) def testTTLs(self): @@ -390,7 +401,7 @@ class ZoneTestCase(unittest.TestCase): def testInclude(self): z1 = dns.zone.from_text(include_text, 'example.', relativize=True, allow_include=True) - z2 = dns.zone.from_file('example', 'example.', relativize=True) + z2 = dns.zone.from_file(here('example'), 'example.', relativize=True) self.failUnless(z1 == z2) def testBadDirective(self):
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor