]> git.ipfire.org Git - thirdparty/dnspython.git/commitdiff
Initial python 3 port (may have sharp edges still!)
authorBob Halley <halley@nominum.com>
Sun, 17 Jan 2010 03:15:13 +0000 (19:15 -0800)
committerBob Halley <halley@nominum.com>
Mon, 25 Jan 2010 16:20:25 +0000 (08:20 -0800)
73 files changed:
dns/__init__.py
dns/dnssec.py
dns/e164.py
dns/edns.py
dns/entropy.py
dns/flags.py
dns/ipv4.py
dns/ipv6.py
dns/message.py
dns/name.py
dns/namedict.py
dns/node.py
dns/opcode.py
dns/query.py
dns/rcode.py
dns/rdata.py
dns/rdataclass.py
dns/rdataset.py
dns/rdatatype.py
dns/rdtypes/ANY/CERT.py
dns/rdtypes/ANY/GPOS.py
dns/rdtypes/ANY/HINFO.py
dns/rdtypes/ANY/HIP.py
dns/rdtypes/ANY/ISDN.py
dns/rdtypes/ANY/LOC.py
dns/rdtypes/ANY/NSEC.py
dns/rdtypes/ANY/NSEC3.py
dns/rdtypes/ANY/NSEC3PARAM.py
dns/rdtypes/ANY/NXT.py
dns/rdtypes/ANY/RP.py
dns/rdtypes/ANY/SOA.py
dns/rdtypes/ANY/SSHFP.py
dns/rdtypes/ANY/X25.py
dns/rdtypes/IN/A.py
dns/rdtypes/IN/AAAA.py
dns/rdtypes/IN/APL.py
dns/rdtypes/IN/DHCID.py
dns/rdtypes/IN/IPSECKEY.py
dns/rdtypes/IN/NAPTR.py
dns/rdtypes/IN/NSAP.py
dns/rdtypes/IN/PX.py
dns/rdtypes/IN/SRV.py
dns/rdtypes/IN/WKS.py
dns/rdtypes/dsbase.py
dns/rdtypes/keybase.py
dns/rdtypes/mxbase.py
dns/rdtypes/nsbase.py
dns/rdtypes/sigbase.py
dns/rdtypes/txtbase.py
dns/renderer.py
dns/resolver.py
dns/reversename.py
dns/rrset.py
dns/set.py
dns/tokenizer.py
dns/tsig.py
dns/ttl.py
dns/update.py
dns/util.py [new file with mode: 0644]
dns/zone.py
examples/e164.py
examples/mx.py
examples/name.py
examples/reverse.py
examples/reverse_name.py
examples/xfr.py
tests/Makefile
tests/message.py
tests/name.py
tests/ntoaaton.py
tests/resolver.py
tests/update.py
tests/zone.py

index 5ad5737cfa24faf48678631674aad07a17dcda38..aef737e7e163a09205ac64201eac876319c9b137 100644 (file)
@@ -47,6 +47,7 @@ __all__ = [
     'ttl',
     'rdtypes',
     'update',
+    'util',
     'version',
     'zone',
 ]
index 54fd78d9c9b91491e5736627dd0662863d888297..5e3d49878a9231cfe7a0e3d2823630f8d781eecf 100644 (file)
@@ -47,7 +47,7 @@ _algorithm_by_text = {
 # 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()])
 
 class UnknownAlgorithm(Exception):
     """Raised if an algorithm is unknown."""
index d8f71ec7999513e76cc5ca9a5eea055b61fbbf91..104aae960f1b6d14e7c89eaa731dcc09e3311e50 100644 (file)
@@ -56,7 +56,7 @@ def to_e164(name, origin=public_enum_domain, want_plus_prefix=True):
     if len(dlabels) != len(name.labels):
         raise dns.exception.SyntaxError('non-digit labels in ENUM domain name')
     dlabels.reverse()
-    text = ''.join(dlabels)
+    text = ''.join([x.decode('ascii') for x in dlabels])
     if want_plus_prefix:
         text = '+' + text
     return text
index 1731cedde4f4b6d3e9d6a33d53ebdd043e3f849c..5f01a353790e7da7b128d0aa7ca5fbdfca4e7ae5 100644 (file)
@@ -33,6 +33,7 @@ class Option(object):
         """
         raise NotImplementedError
 
+    @classmethod
     def from_wire(cls, otype, wire, current, olen):
         """Build an EDNS option object from wire format
 
@@ -47,8 +48,6 @@ class Option(object):
         @rtype: dns.ends.Option instance"""
         raise NotImplementedError
 
-    from_wire = classmethod(from_wire)
-
     def _cmp(self, other):
         """Compare an ENDS option with another option of the same type.
         Return < 0 if self < other, 0 if self == other, and > 0 if self > other.
@@ -108,14 +107,13 @@ class GenericOption(Option):
     def to_wire(self, file):
         file.write(self.data)
 
+    def _cmp(self, other):
+        return cmp(self.data, other.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)
-
 _type_to_class = {
 }
 
index fd9d4f8cdf8ce5e1f5cc122e3dda67ef6cc2245b..9dd3fd8760a691d26eda7041d1eaf3b4b6ccbeda 100644 (file)
@@ -39,7 +39,7 @@ class EntropyPool(object):
                 import md5
                 self.hash = md5.new()
                 self.hash_len = 16
-        self.pool = '\0' * self.hash_len
+        self.pool = bytearray(self.hash_len)
         if not seed is None:
             self.stir(seed)
             self.seeded = True
@@ -50,14 +50,11 @@ 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
+                self.pool[self.pool_index] ^= c
                 self.pool_index += 1
-            self.pool = ''.join([chr(c) for c in bytes])
         finally:
             if not already_locked:
                 self.lock.release()
@@ -68,13 +65,13 @@ 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:
                         r.close()
                 except:
-                    seed = str(time.time())
+                    seed = str(time.time()).encode('utf-8')
             self.seeded = True
             self.stir(seed, True)
 
@@ -87,7 +84,7 @@ class EntropyPool(object):
                 self.digest = 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,18 +98,18 @@ class EntropyPool(object):
 
     def random_between(self, first, last):
         size = last - first + 1
-        if size > 4294967296L:
+        if size > 4294967296:
             raise ValueError('too big')
         if size > 65536:
             rand = self.random_32
-            max = 4294967295L
+            max = 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()
 
index 17afdbc2ec834dabdaff9cd76b36003b7ce678ac..1f906bf576d35e0bcfd9af14aee8efb09018d518 100644 (file)
@@ -48,15 +48,12 @@ _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.iteritems()])
+_edns_by_value = dict([(y, x) for x, y in _edns_by_text.items()])
 
 def _order_flags(table):
-    order = list(table.iteritems())
-    order.sort()
-    order.reverse()
-    return order
+    return sorted(table.items(), reverse=True)
 
 _flags_order = _order_flags(_by_value)
 
index 1569da54759ba397ac59211e2a38f6451b0282e0..d2eb0b8bcc2cfcd06b3fe60df8e0a11a2eb1d8ce 100644 (file)
 import socket
 import sys
 
-if sys.hexversion < 0x02030000 or sys.platform == 'win32':
+if sys.platform == 'win32':
     #
-    # Some versions of Python 2.2 have an inet_aton which rejects
-    # the valid IP address '255.255.255.255'.  It appears this
-    # problem is still present on the Win32 platform even in 2.3.
-    # We'll work around the problem.
+    # XXX  Does the Win32 python 3 inet_aton still reject 255.255.255.255?
+    # Until we know it doesn't, we'll keep our workaround in place.
     #
     def inet_aton(text):
         if text == '255.255.255.255':
-            return '\xff' * 4
+            return b'\xff' * 4
         else:
             return socket.inet_aton(text)
 else:
index 33c6713796d0ab2c43fb1425237ddebe62b73295..1dd96c2823ef5103a2c092578319786911d3c464 100644 (file)
 
 """IPv6 helper functions."""
 
+import base64
 import re
 
 import dns.exception
 import dns.ipv4
 
-_leading_zero = re.compile(r'0+([0-9a-f]+)')
-
 def inet_ntoa(address):
     """Convert a network format IPv6 address into text.
 
@@ -33,18 +32,14 @@ def inet_ntoa(address):
 
     if len(address) != 16:
         raise ValueError("IPv6 addresses are 16 bytes long")
-    hex = address.encode('hex_codec')
+    hex = str(base64.b16encode(address), encoding='utf_8').lower()
     chunks = []
     i = 0
     l = len(hex)
     while i < l:
-        chunk = hex[i : i + 4]
-        # strip leading zeros.  we do this with an re instead of
-        # with lstrip() because lstrip() didn't support chars until
-        # python 2.2.2
-        m = _leading_zero.match(chunk)
-        if not m is None:
-            chunk = m.group(1)
+        chunk = hex[i : i + 4].lstrip('0')
+        if chunk == '':
+            chunk = '0'
         chunks.append(chunk)
         i += 4
     #
@@ -54,7 +49,7 @@ def inet_ntoa(address):
     best_len = 0
     start = -1
     last_was_zero = False
-    for i in xrange(8):
+    for i in range(8):
         if chunks[i] != '0':
             if last_was_zero:
                 end = i
@@ -141,7 +136,7 @@ def inet_aton(text):
             if seen_empty:
                 raise dns.exception.SyntaxError
             seen_empty = True
-            for i in xrange(0, 8 - l + 1):
+            for i in range(0, 8 - l + 1):
                 canonical.append('0000')
         else:
             lc = len(c)
@@ -158,6 +153,6 @@ def inet_aton(text):
     # Finally we can go to binary.
     #
     try:
-        return text.decode('hex_codec')
+        return bytes.fromhex(text)
     except TypeError:
         raise dns.exception.SyntaxError
index ba0ebf65f14c7b8966fda39e35462b838f29c2be..54803e140c38f599f037d25a81d30f879d11e2a6 100644 (file)
@@ -15,7 +15,7 @@
 
 """DNS Messages"""
 
-import cStringIO
+import io
 import random
 import struct
 import sys
@@ -168,7 +168,7 @@ class Message(object):
         self.index = {}
 
     def __repr__(self):
-        return '<DNS message, ID ' + `self.id` + '>'
+        return '<DNS message, ID ' + str(self.id) + '>'
 
     def __str__(self):
         return self.to_text()
@@ -182,41 +182,42 @@ 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 = io.StringIO()
+        print('id %d' % self.id, file=s)
+        print('opcode %s' % \
+              dns.opcode.to_text(dns.opcode.from_flags(self.flags)),
+              file=s)
         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)
+        print('rcode %s' % dns.rcode.to_text(rc), file=s)
+        print('flags %s' % dns.flags.to_text(self.flags), file=s)
         if self.edns >= 0:
-            print >> s, 'edns %s' % self.edns
+            print('edns %s' % self.edns, file=s)
             if self.ednsflags != 0:
-                print >> s, 'eflags %s' % \
-                      dns.flags.edns_to_text(self.ednsflags)
-            print >> s, 'payload', self.payload
+                print('eflags %s' % \
+                      dns.flags.edns_to_text(self.ednsflags), file=s)
+            print('payload', self.payload, file=s)
         is_update = dns.opcode.is_update(self.flags)
         if is_update:
-            print >> s, ';ZONE'
+            print(';ZONE', file=s)
         else:
-            print >> s, ';QUESTION'
+            print(';QUESTION', file=s)
         for rrset in self.question:
-            print >> s, rrset.to_text(origin, relativize, **kw)
+            print(rrset.to_text(origin, relativize, **kw), file=s)
         if is_update:
-            print >> s, ';PREREQ'
+            print(';PREREQ', file=s)
         else:
-            print >> s, ';ANSWER'
+            print(';ANSWER', file=s)
         for rrset in self.answer:
-            print >> s, rrset.to_text(origin, relativize, **kw)
+            print(rrset.to_text(origin, relativize, **kw), file=s)
         if is_update:
-            print >> s, ';UPDATE'
+            print(';UPDATE', file=s)
         else:
-            print >> s, ';AUTHORITY'
+            print(';AUTHORITY', file=s)
         for rrset in self.authority:
-            print >> s, rrset.to_text(origin, relativize, **kw)
-        print >> s, ';ADDITIONAL'
+            print(rrset.to_text(origin, relativize, **kw), file=s)
+        print(';ADDITIONAL', file=s)
         for rrset in self.additional:
-            print >> s, rrset.to_text(origin, relativize, **kw)
+            print(rrset.to_text(origin, relativize, **kw), file=s)
         #
         # We strip off the final \n so the caller can print the result without
         # doing weird things to get around eccentricities in Python print
@@ -450,7 +451,7 @@ class Message(object):
         if keyname is None:
             self.keyname = self.keyring.keys()[0]
         else:
-            if isinstance(keyname, (str, unicode)):
+            if isinstance(keyname, str):
                 keyname = dns.name.from_text(keyname)
             self.keyname = keyname
         self.keyalgorithm = algorithm
@@ -494,7 +495,7 @@ class Message(object):
             options = []
         else:
             # make sure the EDNS version in ednsflags agrees with edns
-            ednsflags &= 0xFF00FFFFL
+            ednsflags &= 0xFF00FFFF
             ednsflags |= (edns << 16)
             if options is None:
                 options = []
@@ -532,7 +533,7 @@ class Message(object):
         (value, evalue) = dns.rcode.to_flags(rcode)
         self.flags &= 0xFFF0
         self.flags |= value
-        self.ednsflags &= 0x00FFFFFFL
+        self.ednsflags &= 0x00FFFFFF
         self.ednsflags |= evalue
         if self.ednsflags != 0 and self.edns < 0:
             self.edns = 0
@@ -590,7 +591,7 @@ class _WireReader(object):
         if self.updating and qcount > 1:
             raise dns.exception.FormError
 
-        for i in xrange(0, qcount):
+        for i in range(0, qcount):
             (qname, used) = dns.name.from_wire(self.wire, self.current)
             if not self.message.origin is None:
                 qname = qname.relativize(self.message.origin)
@@ -618,7 +619,7 @@ class _WireReader(object):
         else:
             force_unique = False
         seen_opt = False
-        for i in xrange(0, count):
+        for i in range(0, count):
             rr_start = self.current
             (name, used) = dns.name.from_wire(self.wire, self.current)
             absolute_name = name
@@ -989,15 +990,8 @@ 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'
-    if isinstance(f, str_type):
-        f = file(f, opts)
+    if isinstance(f, str):
+        f = open(f, 'rU')
         want_close = True
     else:
         want_close = False
@@ -1033,7 +1027,7 @@ def make_query(qname, rdtype, rdclass = dns.rdataclass.IN, use_edns=None,
     @type want_dnssec: bool
     @rtype: dns.message.Message object"""
 
-    if isinstance(qname, (str, unicode)):
+    if isinstance(qname, str):
         qname = dns.name.from_text(qname)
     if isinstance(rdtype, str):
         rdtype = dns.rdatatype.from_text(rdtype)
index f239c9b5de20eb9dccefeb7be01dea15e0431008..f58cfc99995078e2f15902bbc948f99def281fff 100644 (file)
 @type empty: dns.name.Name object
 """
 
-import cStringIO
+import encodings.idna
+import io
 import struct
 import sys
 
-if sys.hexversion >= 0x02030000:
-    import encodings.idna
-
 import dns.exception
+import dns.util
 
 NAMERELN_NONE = 0
 NAMERELN_SUPERDOMAIN = 1
@@ -75,16 +74,11 @@ class NoParent(dns.exception.DNSException):
     or the empty name."""
     pass
 
-_escaped = {
-    '"' : True,
-    '(' : True,
-    ')' : True,
-    '.' : True,
-    ';' : True,
-    '\\' : True,
-    '@' : True,
-    '$' : True
-    }
+class LabelMixesUnicodeAndASCII(dns.exception.SyntaxError):
+    """Raised if a label mixes Unicode characters and ASCII escapes."""
+    pass
+
+_escaped = frozenset([ord(c) for c in '"().;\\@$'])
 
 def _escapify(label):
     """Escape the characters in label which need it.
@@ -93,13 +87,21 @@ def _escapify(label):
     text = ''
     for c in label:
         if c in _escaped:
-            text += '\\' + c
-        elif ord(c) > 0x20 and ord(c) < 0x7F:
-            text += c
+            text += '\\' + chr(c)
+        elif c > 0x20 and c < 0x7F:
+            text += chr(c)
         else:
-            text += '\\%03d' % ord(c)
+            text += '\\%03d' % c
     return text
 
+def _bytesify(label):
+    if isinstance(label, str):
+        return label.encode('latin_1')
+    elif not isinstance(label, bytes):
+        raise ValueError('label is not a bytes or a string')
+    else:
+        return label
+
 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.
@@ -113,11 +115,13 @@ def _validate_labels(labels):
     i = -1
     j = 0
     for label in labels:
+        if not isinstance(label, bytes):
+            raise ValueError("label is not a bytes object or a string")
         ll = len(label)
         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:
@@ -139,11 +143,14 @@ class Name(object):
     def __init__(self, labels):
         """Initialize a domain name from a list of labels.
         @param labels: the labels
-        @type labels: any iterable whose values are strings
+        @type labels: any iterable whose values are bytes objects or strings
+        containing only ISO Latin 1 characters (i.e. characters whose unicode
+        code points have values <= 255).
         """
 
-        super(Name, self).__setattr__('labels', tuple(labels))
-        _validate_labels(self.labels)
+        labels = tuple([_bytesify(l) for l in labels])
+        _validate_labels(labels)
+        super(Name, self).__setattr__('labels', labels)
 
     def __setattr__(self, name, value):
         raise TypeError("object doesn't support attribute assignment")
@@ -153,25 +160,26 @@ 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 = 0
         for label in self.labels:
+            label = label.lower()
             for c in label:
-                h += ( h << 3 ) + ord(c.lower())
-        return int(h % sys.maxint)
+                h += ( h << 3 ) + c
+        return int(h % 18446744073709551616)
 
     def fullcompare(self, other):
         """Compare two names, returning a 3-tuple (relation, order, nlabels).
@@ -317,7 +325,7 @@ class Name(object):
 
         if len(self.labels) == 0:
             return '@'
-        if len(self.labels) == 1 and self.labels[0] == '':
+        if len(self.labels) == 1 and self.labels[0] == b'':
             return '.'
         if omit_final_dot and self.is_absolute():
             l = self.labels[:-1]
@@ -337,14 +345,14 @@ class Name(object):
         """
 
         if len(self.labels) == 0:
-            return u'@'
-        if len(self.labels) == 1 and self.labels[0] == '':
-            return u'.'
+            return '@'
+        if len(self.labels) == 1 and self.labels[0] == b'':
+            return '.'
         if omit_final_dot and self.is_absolute():
             l = self.labels[:-1]
         else:
             l = self.labels
-        s = u'.'.join([encodings.idna.ToUnicode(_escapify(x)) for x in l])
+        s = '.'.join([encodings.idna.ToUnicode(_escapify(x)) for x in l])
         return s
 
     def to_digestable(self, origin=None):
@@ -358,7 +366,7 @@ class Name(object):
         @raises NeedAbsoluteNameOrOrigin: All names in wire format are
         absolute.  If self is a relative name, then an origin must be supplied;
         if it is missing, then this exception is raised
-        @rtype: string
+        @rtype: bytes
         """
 
         if not self.is_absolute():
@@ -368,16 +376,19 @@ 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)
+        ba = bytearray()
+        for label in labels:
+            ba.append(len(label))
+            ba.extend(label.lower())
+        return bytes(ba)
 
     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 io.BytesIO file).  If None, a string containing the wire name
         will be returned.
-        @type file: file or None
+        @type file: bytearray or None
         @param compress: The compression table.  If None (the default) names
         will not be compressed.
         @type compress: dict
@@ -390,7 +401,7 @@ class Name(object):
         """
 
         if file is None:
-            file = cStringIO.StringIO()
+            file = io.BytesIO()
             want_return = True
         else:
             want_return = False
@@ -412,8 +423,7 @@ class Name(object):
                 pos = None
             if not pos is None:
                 value = 0xc000 + pos
-                s = struct.pack('!H', value)
-                file.write(s)
+                dns.util.write_uint16(file, value)
                 break
             else:
                 if not compress is None and len(n) > 1:
@@ -421,7 +431,7 @@ class Name(object):
                     if pos < 0xc000:
                         compress[n] = pos
                 l = len(label)
-                file.write(chr(l))
+                dns.util.write_uint8(file, l)
                 if l > 0:
                     file.write(label)
         if want_return:
@@ -527,10 +537,10 @@ 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_text(text, origin = root):
     """Convert unicode text into a Name object.
 
     Lables are encoded in IDN ACE form.
@@ -538,82 +548,20 @@ def from_unicode(text, origin = root):
     @rtype: dns.name.Name object
     """
 
-    if not isinstance(text, unicode):
-        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")
-    labels = []
-    label = u''
-    escaping = False
-    edigits = 0
-    total = 0
-    if text == u'@':
-        text = u''
-    if text:
-        if text == u'.':
-            return Name([''])  # no Unicode "u" on this constant!
-        for c in text:
-            if escaping:
-                if edigits == 0:
-                    if c.isdigit():
-                        total = int(c)
-                        edigits += 1
-                    else:
-                        label += c
-                        escaping = False
-                else:
-                    if not c.isdigit():
-                        raise BadEscape
-                    total *= 10
-                    total += int(c)
-                    edigits += 1
-                    if edigits == 3:
-                        escaping = False
-                        label += chr(total)
-            elif c == u'.' or c == u'\u3002' or \
-                 c == u'\uff0e' or c == u'\uff61':
-                if len(label) == 0:
-                    raise EmptyLabel
-                labels.append(encodings.idna.ToASCII(label))
-                label = u''
-            elif c == u'\\':
-                escaping = True
-                edigits = 0
-                total = 0
-            else:
-                label += c
-        if escaping:
-            raise BadEscape
-        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.extend(list(origin.labels))
-    return Name(labels)
-
-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 not (origin is None or isinstance(origin, Name)):
         raise ValueError("origin must be a Name or None")
     labels = []
     label = ''
     escaping = False
+    seen_non_ascii = False
+    seen_non_ascii_escape = False
     edigits = 0
     total = 0
     if text == '@':
         text = ''
     if text:
         if text == '.':
-            return Name([''])
+            return Name([b''])
         for c in text:
             if escaping:
                 if edigits == 0:
@@ -623,6 +571,8 @@ def from_text(text, origin = root):
                     else:
                         label += c
                         escaping = False
+                        if ord(c) > 127:
+                            seen_non_ascii = True
                 else:
                     if not c.isdigit():
                         raise BadEscape
@@ -632,31 +582,48 @@ def from_text(text, origin = root):
                     if edigits == 3:
                         escaping = False
                         label += chr(total)
-            elif c == '.':
+                        if total > 127:
+                            seen_non_ascii_escape = True
+            elif c == '.' or c == '\u3002' or \
+                 c == '\uff0e' or c == '\uff61':
                 if len(label) == 0:
                     raise EmptyLabel
-                labels.append(label)
+                if seen_non_ascii:
+                    if seen_non_ascii_escape:
+                        raise LabelMixesUnicodeAndASCII
+                    labels.append(encodings.idna.ToASCII(label))
+                else:
+                    labels.append(label.encode('latin_1'))
                 label = ''
+                seen_non_ascii = False
+                seen_non_ascii_escape = False
             elif c == '\\':
                 escaping = True
                 edigits = 0
                 total = 0
             else:
                 label += c
+                if ord(c) > 127:
+                    seen_non_ascii = True
         if escaping:
             raise BadEscape
         if len(label) > 0:
-            labels.append(label)
+            if seen_non_ascii:
+                if seen_non_ascii_escape:
+                    raise LabelMixesUnicodeAndASCII
+                labels.append(encodings.idna.ToASCII(label))
+            else:
+                labels.append(label.encode('latin_1'))
         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 not origin is 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
-    @type message: string
+    @type message: bytes
     @param current: the offset of the beginning of the name from the start
     of the message
     @type current: int
@@ -668,12 +635,12 @@ def from_wire(message, current):
     @rtype: (dns.name.Name object, int) tuple
     """
 
-    if not isinstance(message, str):
+    if not isinstance(message, bytes):
         raise ValueError("input to from_wire() must be a byte string")
     labels = []
     biggest_pointer = current
     hops = 0
-    count = ord(message[current])
+    count = message[current]
     current += 1
     cused = 1
     while count != 0:
@@ -683,7 +650,7 @@ def from_wire(message, current):
             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:
@@ -692,9 +659,9 @@ def from_wire(message, current):
             hops += 1
         else:
             raise BadLabelType
-        count = ord(message[current])
+        count = message[current]
         current += 1
         if hops == 0:
             cused += 1
-    labels.append('')
+    labels.append(b'')
     return (Name(labels), cused)
index 54afb77188890e3defa64e127c8df9b28aaa135e..51993312bf78ebec814e6cc593c49c4c2adb7fb0 100644 (file)
@@ -51,9 +51,9 @@ class NameDict(dict):
         depth = len(name)
         if depth > self.max_depth:
             depth = self.max_depth
-        for i in xrange(-depth, 0):
+        for i in range(-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)
index 07fff9293c43ad066e1a4e6bb80acea46fe3d9cb..055f0b716ead2dd8833f957447057136d57d818e 100644 (file)
@@ -15,7 +15,7 @@
 
 """DNS nodes.  A node is a set of rdatasets."""
 
-import StringIO
+import io
 
 import dns.rdataset
 import dns.rdatatype
@@ -23,18 +23,18 @@ import dns.renderer
 
 class Node(object):
     """A DNS node.
-    
+
     A node is a set of rdatasets
 
     @ivar rdatasets: the node's rdatasets
     @type rdatasets: list of dns.rdataset.Rdataset objects"""
 
     __slots__ = ['rdatasets']
-    
+
     def __init__(self):
         """Initialize a DNS node.
         """
-        
+
         self.rdatasets = [];
 
     def to_text(self, name, **kw):
@@ -46,15 +46,15 @@ class Node(object):
         @type name: dns.name.Name object
         @rtype: string
         """
-        
-        s = StringIO.StringIO()
+
+        s = io.StringIO()
         for rds in self.rdatasets:
-            print >> s, rds.to_text(name, **kw)
+            print(rds.to_text(name, **kw), file=s)
         return s.getvalue()[:-1]
 
     def __repr__(self):
         return '<DNS node ' + str(id(self)) + '>'
-    
+
     def __eq__(self, other):
         """Two nodes are equal if they have the same rdatasets.
 
@@ -73,7 +73,7 @@ class Node(object):
 
     def __ne__(self, other):
         return not self.__eq__(other)
-        
+
     def __len__(self):
         return len(self.rdatasets)
 
@@ -159,7 +159,7 @@ class Node(object):
 
     def replace_rdataset(self, replacement):
         """Replace an rdataset.
-        
+
         It is not an error if there is no rdataset matching I{replacement}.
 
         Ownership of the I{replacement} object is transferred to the node;
index 705bd09a43d1fb887e63fcc0920ef7e317e1e2f7..b6b9f9a172dae653687e2a8c8ab849b097562e52 100644 (file)
@@ -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):
index c023b140aff67d1d0748c87718849ebc7076d7e5..cda2309e012f4a0e032be0cb429b440afc3c3f35 100644 (file)
@@ -59,7 +59,7 @@ def _wait_for(ir, iw, ix, expiration):
                 (r, w, x) = select.select(ir, iw, ix)
             else:
                 (r, w, x) = select.select(ir, iw, ix, timeout)
-        except select.error, e:
+        except select.error as e:
             if e.args[0] != errno.EINTR:
                 raise e
         done = True
index c055f2e7cd29c211d3c02a551b060e10e14c830d..41bbbad9c96f55b559a3af05c761fe15c6d2e335 100644 (file)
@@ -49,7 +49,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):
@@ -102,7 +102,7 @@ def to_flags(value):
     if value < 0 or value > 4095:
         raise ValueError('rcode must be >= 0 and <= 4095')
     v = value & 0xf
-    ev = long(value & 0xff0) << 20
+    ev = (value & 0xff0) << 20
     return (v, ev)
 
 def to_text(value):
index ce0268697b0aa5c7e03024c959d23b9257c77cd6..fe4547dfe35d12f83c7f3d5a15bd1d839d0f54a5 100644 (file)
@@ -25,12 +25,14 @@ default is 'dns.rdtypes'.  Changing this value will break the library.
 chunk of hexstring that _hexify() produces before whitespace occurs.
 @type _hex_chunk: int"""
 
-import cStringIO
+import base64
+import io
 
 import dns.exception
 import dns.rdataclass
 import dns.rdatatype
 import dns.tokenizer
+import dns.util
 
 _hex_chunksize = 32
 
@@ -46,7 +48,7 @@ def _hexify(data, chunksize=None):
 
     if chunksize is None:
         chunksize = _hex_chunksize
-    hex = data.encode('hex_codec')
+    hex = base64.b16encode(data).decode('ascii').lower()
     l = len(hex)
     if l > chunksize:
         chunks = []
@@ -72,8 +74,7 @@ def _base64ify(data, chunksize=None):
 
     if chunksize is None:
         chunksize = _base64_chunksize
-    b64 = data.encode('base64_codec')
-    b64 = b64.replace('\n', '')
+    b64 = base64.b64encode(data).decode('ascii')
     l = len(b64)
     if l > chunksize:
         chunks = []
@@ -84,10 +85,7 @@ def _base64ify(data, chunksize=None):
         b64 = ' '.join(chunks)
     return b64
 
-__escaped = {
-    '"' : True,
-    '\\' : True,
-    }
+_escaped = frozenset('"\\')
 
 def _escapify(qstring):
     """Escape the characters in a quoted string which need it.
@@ -98,9 +96,11 @@ def _escapify(qstring):
     @rtype: string
     """
 
+    if isinstance(qstring, bytes):
+        qstring = qstring.decode('latin_1')
     text = ''
     for c in qstring:
-        if c in __escaped:
+        if c in _escaped:
             text += '\\' + c
         elif ord(c) >= 0x20 and ord(c) < 0x7F:
             text += c
@@ -117,10 +117,10 @@ def _truncate_bitmap(what):
     @rtype: string
     """
 
-    for i in xrange(len(what) - 1, -1, -1):
-        if what[i] != '\x00':
+    for i in range(len(what) - 1, -1, -1):
+        if what[i] != 0:
             break
-    return ''.join(what[0 : i + 1])
+    return bytes(what[0 : i + 1])
 
 class Rdata(object):
     """Base class for all DNS rdata types.
@@ -175,7 +175,7 @@ class Rdata(object):
     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 = io.BytesIO()
         self.to_wire(f, None, origin)
         return f.getvalue()
 
@@ -225,33 +225,38 @@ class Rdata(object):
         return self._cmp(other) != 0
 
     def __lt__(self, other):
-        if not isinstance(other, Rdata) or \
-               self.rdclass != other.rdclass or \
-               self.rdtype != other.rdtype:
+        if not isinstance(other, Rdata):
             return NotImplemented
+        if self.rdclass != other.rdclass or \
+               self.rdtype != other.rdtype:
+            return dns.util.cmp((self.rdclass, self.rdtype), (other.rdclass, other.rdtype))
         return self._cmp(other) < 0
 
     def __le__(self, other):
-        if not isinstance(other, Rdata) or \
-               self.rdclass != other.rdclass or \
-               self.rdtype != other.rdtype:
+        if not isinstance(other, Rdata):
             return NotImplemented
+        if self.rdclass != other.rdclass or \
+               self.rdtype != other.rdtype:
+            return dns.util.cmp((self.rdclass, self.rdtype), (other.rdclass, other.rdtype))
         return self._cmp(other) <= 0
 
     def __ge__(self, other):
-        if not isinstance(other, Rdata) or \
-               self.rdclass != other.rdclass or \
-               self.rdtype != other.rdtype:
+        if not isinstance(other, Rdata):
             return NotImplemented
+        if self.rdclass != other.rdclass or \
+               self.rdtype != other.rdtype:
+            return dns.util.cmp((self.rdclass, self.rdtype), (other.rdclass, other.rdtype))
         return self._cmp(other) >= 0
 
     def __gt__(self, other):
-        if not isinstance(other, Rdata) or \
-               self.rdclass != other.rdclass or \
-               self.rdtype != other.rdtype:
+        if not isinstance(other, Rdata):
             return NotImplemented
+        if self.rdclass != other.rdclass or \
+               self.rdtype != other.rdtype:
+            return dns.util.cmp((self.rdclass, self.rdtype), (other.rdclass, other.rdtype))
         return self._cmp(other) > 0
 
+    @classmethod
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         """Build an rdata object from text format.
 
@@ -270,8 +275,7 @@ class Rdata(object):
 
         raise NotImplementedError
 
-    from_text = classmethod(from_text)
-
+    @classmethod
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         """Build an rdata object from wire format
 
@@ -292,8 +296,6 @@ class Rdata(object):
 
         raise NotImplementedError
 
-    from_wire = classmethod(from_wire)
-
     def choose_relativity(self, origin = None, relativize = True):
         """Convert any domain names in the rdata to the specified
         relativization.
@@ -318,9 +320,11 @@ 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 != '\#':
+            print('XXX %u %u' % (rdclass, rdtype))
             raise dns.exception.SyntaxError(r'generic rdata does not start with \#')
         length = tok.get_int()
         chunks = []
@@ -329,24 +333,20 @@ class GenericRdata(Rdata):
             if token.is_eol_or_eof():
                 break
             chunks.append(token.value)
-        hex = ''.join(chunks)
-        data = hex.decode('hex_codec')
+        data = bytes.fromhex(''.join(chunks))
         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 dns.util.cmp(self.data, other.data)
 
 _rdata_modules = {}
 _module_prefix = 'dns.rdtypes'
index 887fd1ad6b91462c91e98048c35eaf17b6d89c53..2709b4e002031e9e6217947071270d1c4ff26b51 100644 (file)
@@ -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.
@@ -58,10 +58,7 @@ _by_text.update({
     'HESIOD' : HS
     })
 
-_metaclasses = {
-    NONE : True,
-    ANY : True
-    }
+_metaclasses = frozenset([NONE, ANY])
 
 _unknown_class_pattern = re.compile('CLASS([0-9]+)$', re.I);
 
@@ -100,7 +97,7 @@ 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' + str(value)
     return text
 
 def is_metaclass(rdclass):
@@ -109,6 +106,6 @@ def is_metaclass(rdclass):
     @type rdclass: int
     @rtype: bool"""
 
-    if _metaclasses.has_key(rdclass):
+    if rdclass in _metaclasses:
         return True
     return False
index 0af018bab5c0e715cede89f7fc7ab794e7faea9c..bfc817b80a32f7618e1669191de2620fe7ec4ae3 100644 (file)
@@ -15,8 +15,8 @@
 
 """DNS rdatasets (an rdataset is a set of rdatas of a given type and class)"""
 
+import io
 import random
-import StringIO
 import struct
 
 import dns.exception
@@ -192,7 +192,7 @@ class Rdataset(dns.set.Set):
         else:
             ntext = ''
             pad = ''
-        s = StringIO.StringIO()
+        s = io.StringIO()
         if not override_rdclass is None:
             rdclass = override_rdclass
         else:
@@ -203,15 +203,17 @@ 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))
+            print('%s%s%s %s' % (ntext, pad,
+                                 dns.rdataclass.to_text(rdclass),
+                                 dns.rdatatype.to_text(self.rdtype)),
+                  file=s)
         else:
             for rd in self:
-                print >> s, '%s%s%d %s %s %s' % \
+                print('%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))
+                       rd.to_text(origin=origin, relativize=relativize, **kw)),
+                      file=s)
         #
         # We strip off the final \n for the caller's convenience in printing
         #
index 1a02b7d3cd9598b4b8dece53545e53909957d3be..57b7ab12e549a6ff432998cb1240f92dfaf2ade5 100644 (file)
@@ -158,20 +158,12 @@ _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 = frozenset([OPT])
 
-_metatypes = {
-    OPT : True
-    }
-
-_singletons = {
-    SOA : True,
-    NXT : True,
-    DNAME : True,
-    NSEC : True,
-    # CNAME is technically a singleton, but we allow multiple CNAMEs.
-    }
+# CNAME is technically a singleton, but we allow multiple CNAMEs.
+_singletons = frozenset([SOA, NXT, DNAME, NSEC, NSEC3, NSEC3PARAM])
 
 _unknown_type_pattern = re.compile('TYPE([0-9]+)$', re.I);
 
@@ -208,7 +200,7 @@ 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' + str(value)
     return text
 
 def is_metatype(rdtype):
@@ -217,7 +209,7 @@ def is_metatype(rdtype):
     @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
 
@@ -227,6 +219,6 @@ def is_singleton(rdtype):
     @type rdtype: int
     @rtype: bool"""
 
-    if _singletons.has_key(rdtype):
+    if rdtype in _singletons:
         return True
     return False
index d2703519d5f842325f02e02f57a4963e1920b715..675f2f128c20b370c03871139093a8a4047a378b 100644 (file)
 # 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 base64
+import io
 import struct
 
 import dns.exception
 import dns.dnssec
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 _ctype_by_value = {
     1 : 'PKIX',
@@ -93,7 +95,7 @@ class CERT(dns.rdata.Rdata):
                 raise dns.exception.SyntaxError
             chunks.append(t.value)
         b64 = ''.join(chunks)
-        certificate = b64.decode('base64_codec')
+        certificate = base64.b64decode(b64.encode('ascii'))
         return cls(rdclass, rdtype, certificate_type, key_tag,
                    algorithm, certificate)
 
@@ -119,7 +121,7 @@ class CERT(dns.rdata.Rdata):
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        f = cStringIO.StringIO()
+        f = io.BytesIO()
         self.to_wire(f)
         wire1 = f.getvalue()
         f.seek(0)
@@ -128,4 +130,4 @@ class CERT(dns.rdata.Rdata):
         wire2 = f.getvalue()
         f.close()
 
-        return cmp(wire1, wire2)
+        return dns.util.cmp(wire1, wire2)
index 6f63cc05f63c549cecb28a9b42ce6d4bb5d144aa..1d45fe609e64b01ec96dc343d3d4e9c0439db35d 100644 (file)
@@ -16,6 +16,7 @@
 import dns.exception
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 def _validate_float_string(what):
     if what[0] == '-' or what[0] == '+':
@@ -29,7 +30,7 @@ def _validate_float_string(what):
         raise dns.exception.FormError
     if not right == '' and not right.isdigit():
         raise dns.exception.FormError
-    
+
 class GPOS(dns.rdata.Rdata):
     """GPOS record
 
@@ -42,20 +43,17 @@ class GPOS(dns.rdata.Rdata):
     @see: RFC 1712"""
 
     __slots__ = ['latitude', 'longitude', 'altitude']
-    
+
     def __init__(self, rdclass, rdtype, latitude, longitude, altitude):
         super(GPOS, self).__init__(rdclass, rdtype)
         if isinstance(latitude, float) or \
-           isinstance(latitude, int) or \
-           isinstance(latitude, long):
+           isinstance(latitude, int):
             latitude = str(latitude)
         if isinstance(longitude, float) or \
-           isinstance(longitude, int) or \
-           isinstance(longitude, long):
+           isinstance(longitude, int):
             longitude = str(longitude)
         if isinstance(altitude, float) or \
-           isinstance(altitude, int) or \
-           isinstance(altitude, long):
+           isinstance(altitude, int):
             altitude = str(altitude)
         _validate_float_string(latitude)
         _validate_float_string(longitude)
@@ -66,66 +64,63 @@ class GPOS(dns.rdata.Rdata):
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '%s %s %s' % (self.latitude, self.longitude, self.altitude)
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         latitude = tok.get_string()
         longitude = tok.get_string()
         altitude = tok.get_string()
         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(self.latitude)
+        dns.util.write_uint8(file, l)
+        file.write(self.latitude.encode('latin_1'))
         l = len(self.longitude)
         assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.longitude)
+        dns.util.write_uint8(file, l)
+        file.write(self.longitude.encode('latin_1'))
         l = len(self.altitude)
         assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.altitude)
-        
+        dns.util.write_uint8(file, l)
+        file.write(self.altitude.encode('latin_1'))
+
     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:
             raise dns.exception.FormError
-        latitude = wire[current : current + l]
+        latitude = wire[current : current + l].decode('latin_1')
         current += l
         rdlen -= l
-        l = ord(wire[current])
+        l = wire[current]
         current += 1
         rdlen -= 1
         if l > rdlen:
             raise dns.exception.FormError
-        longitude = wire[current : current + l]
+        longitude = wire[current : current + l].decode('latin_1')
         current += l
         rdlen -= l
-        l = ord(wire[current])
+        l = wire[current]
         current += 1
         rdlen -= 1
         if l != rdlen:
             raise dns.exception.FormError
-        altitude = wire[current : current + l]
+        altitude = wire[current : current + l].decode('latin_1')
         return cls(rdclass, rdtype, latitude, longitude, altitude)
 
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        v = cmp(self.latitude, other.latitude)
+        v = dns.util.cmp(self.latitude, other.latitude)
         if v == 0:
-            v = cmp(self.longitude, other.longitude)
+            v = dns.util.cmp(self.longitude, other.longitude)
             if v == 0:
-                v = cmp(self.altitude, other.altitude)
+                v = dns.util.cmp(self.altitude, other.altitude)
         return v
 
     def _get_float_latitude(self):
index e592ad39a7d86b5a30e5d2b223a09be83d612d34..3bb0eac6fec7890077777eab45bfba86c28833ec 100644 (file)
@@ -16,6 +16,7 @@
 import dns.exception
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 class HINFO(dns.rdata.Rdata):
     """HINFO record
@@ -27,7 +28,7 @@ class HINFO(dns.rdata.Rdata):
     @see: RFC 1035"""
 
     __slots__ = ['cpu', 'os']
-    
+
     def __init__(self, rdclass, rdtype, cpu, os):
         super(HINFO, self).__init__(rdclass, rdtype)
         self.cpu = cpu
@@ -36,48 +37,46 @@ class HINFO(dns.rdata.Rdata):
     def to_text(self, origin=None, relativize=True, **kw):
         return '"%s" "%s"' % (dns.rdata._escapify(self.cpu),
                               dns.rdata._escapify(self.os))
-        
+
     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(self.cpu)
+        dns.util.write_uint8(file, l)
+        file.write(self.cpu.encode('latin_1'))
         l = len(self.os)
         assert l < 256
-        byte = chr(l)
-        file.write(byte)
-        file.write(self.os)
-        
+        dns.util.write_uint8(file, l)
+        file.write(self.os.encode('latin_1'))
+
     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:
             raise dns.exception.FormError
-        cpu = wire[current : current + l]
+        cpu = wire[current : current + l].decode('latin_1')
         current += l
         rdlen -= l
-        l = ord(wire[current])
+        l = wire[current]
         current += 1
         rdlen -= 1
         if l != rdlen:
             raise dns.exception.FormError
-        os = wire[current : current + l]
+        os = wire[current : current + l].decode('latin_1')
         return cls(rdclass, rdtype, cpu, os)
 
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        v = cmp(self.cpu, other.cpu)
+        v = dns.util.cmp(self.cpu, other.cpu)
         if v == 0:
-            v = cmp(self.os, other.os)
+            v = dns.util.cmp(self.os, other.os)
         return v
index 8f96ae93d640cc8dbd4a699a494fa94c8c6b902d..2618ab10ac3e2d7b6e01b421ca9cd385dc6b7b4b 100644 (file)
 # 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 base64
+import io
 import string
 import struct
 
 import dns.exception
 import dns.rdata
 import dns.rdatatype
+import dns.util
 
 class HIP(dns.rdata.Rdata):
     """HIP record
@@ -44,8 +46,8 @@ 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', '')
+        hit = base64.b16encode(self.hit).decode('ascii').lower()
+        key = base64.b64encode(self.key).decode('ascii')
         text = ''
         servers = []
         for server in self.servers:
@@ -56,10 +58,10 @@ class HIP(dns.rdata.Rdata):
 
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         algorithm = tok.get_uint8()
-        hit = tok.get_string().decode('hex-codec')
+        hit = bytes.fromhex(tok.get_string())
         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('ascii'))
         servers = []
         while 1:
             token = tok.get()
@@ -113,19 +115,19 @@ class HIP(dns.rdata.Rdata):
         self.servers = servers
 
     def _cmp(self, other):
-        b1 = cStringIO.StringIO()
+        b1 = io.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 = io.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 = dns.util.cmp(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 = dns.util.cmp(self.servers[i], other.servers[i])
             if v != 0:
                 return v
             i += 1
index 424d3a9a3c9f95194e91a0d26efe797a3af08248..032350573104a6561c41e6101e422a58407870c2 100644 (file)
@@ -16,6 +16,7 @@
 import dns.exception
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 class ISDN(dns.rdata.Rdata):
     """ISDN record
@@ -41,14 +42,14 @@ class ISDN(dns.rdata.Rdata):
             return '"%s"' % dns.rdata._escapify(self.address)
 
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
-        address = tok.get_string()
+        address = tok.get_string().encode('ascii')
         t = tok.get()
         if not t.is_eol_or_eof():
             tok.unget(t)
-            subaddress = tok.get_string()
+            subaddress = tok.get_string().encode('ascii')
         else:
             tok.unget(t)
-            subaddress = ''
+            subaddress = b''
         tok.get_eol()
         return cls(rdclass, rdtype, address, subaddress)
 
@@ -57,18 +58,16 @@ class ISDN(dns.rdata.Rdata):
     def to_wire(self, file, compress = None, origin = None):
         l = len(self.address)
         assert l < 256
-        byte = chr(l)
-        file.write(byte)
+        dns.util.write_uint8(file, l)
         file.write(self.address)
         l = len(self.subaddress)
         if l > 0:
             assert l < 256
-            byte = chr(l)
-            file.write(byte)
+            dns.util.write_uint8(file, l)
             file.write(self.subaddress)
 
     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,20 +76,20 @@ 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:
                 raise dns.exception.FormError
             subaddress = wire[current : current + l]
         else:
-            subaddress = ''
+            subaddress = b''
         return cls(rdclass, rdtype, address, subaddress)
 
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        v = cmp(self.address, other.address)
+        v = dns.util.cmp(self.address, other.address)
         if v == 0:
-            v = cmp(self.subaddress, other.subaddress)
+            v = dns.util.cmp(self.subaddress, other.subaddress)
         return v
index 518dd6010f7c6d7a3084fd2e2c65022af918b2c0..7bfd351458a0d3e19ee54ad10c7a52be32be6115 100644 (file)
 # 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 io
 import struct
 
 import dns.exception
 import dns.rdata
+import dns.util
 
-_pows = (1L, 10L, 100L, 1000L, 10000L, 100000L, 1000000L, 10000000L,
-         100000000L, 1000000000L, 10000000000L)
+_pows = (1, 10, 100, 1000, 10000, 100000, 1000000, 10000000,
+         100000000, 1000000000, 10000000000)
 
 def _exponent_of(what, desc):
     exp = None
-    for i in xrange(len(_pows)):
-        if what // _pows[i] == 0L:
+    for i in range(len(_pows)):
+        if what // _pows[i] == 0:
             exp = i - 1
             break
     if exp is None or exp < 0:
@@ -38,14 +39,13 @@ def _float_to_tuple(what):
         what *= -1
     else:
         sign = 1
-    what = long(round(what * 3600000))
-    degrees = int(what // 3600000)
+    what = int(round(what * 3600000))
+    degrees = what // 3600000
     what -= degrees * 3600000
-    minutes = int(what // 60000)
+    minutes = what // 60000
     what -= minutes * 60000
-    seconds = int(what // 1000)
-    what -= int(seconds * 1000)
-    what = int(what)
+    seconds = what // 1000
+    what -= seconds * 1000
     return (degrees * sign, minutes, seconds, what)
 
 def _tuple_to_float(what):
@@ -61,7 +61,7 @@ def _tuple_to_float(what):
     return sign * value
 
 def _encode_size(what, desc):
-    what = long(what);
+    what = int(what);
     exponent = _exponent_of(what, desc) & 0xF
     base = what // pow(10, exponent) & 0xF
     return base * 16 + exponent
@@ -73,7 +73,7 @@ def _decode_size(what, desc):
     base = (what & 0xF0) >> 4
     if base > 9:
         raise dns.exception.SyntaxError("bad %s base" % desc)
-    return long(base) * pow(10, exponent)
+    return int(base) * pow(10, exponent)
 
 class LOC(dns.rdata.Rdata):
     """LOC record
@@ -107,12 +107,12 @@ class LOC(dns.rdata.Rdata):
         degrees.  The other parameters are floats."""
 
         super(LOC, self).__init__(rdclass, rdtype)
-        if isinstance(latitude, int) or isinstance(latitude, long):
+        if isinstance(latitude, int):
             latitude = float(latitude)
         if isinstance(latitude, float):
             latitude = _float_to_tuple(latitude)
         self.latitude = latitude
-        if isinstance(longitude, int) or isinstance(longitude, long):
+        if isinstance(longitude, int):
             longitude = float(longitude)
         if isinstance(longitude, float):
             longitude = _float_to_tuple(longitude)
@@ -251,27 +251,27 @@ class LOC(dns.rdata.Rdata):
     def to_wire(self, file, compress = None, origin = None):
         if self.latitude[0] < 0:
             sign = -1
-            degrees = long(-1 * self.latitude[0])
+            degrees = -1 * self.latitude[0]
         else:
             sign = 1
-            degrees = long(self.latitude[0])
+            degrees = self.latitude[0]
         milliseconds = (degrees * 3600000 +
                         self.latitude[1] * 60000 +
                         self.latitude[2] * 1000 +
                         self.latitude[3]) * sign
-        latitude = 0x80000000L + milliseconds
+        latitude = 0x80000000 + milliseconds
         if self.longitude[0] < 0:
             sign = -1
-            degrees = long(-1 * self.longitude[0])
+            degrees = -1 * self.longitude[0]
         else:
             sign = 1
-            degrees = long(self.longitude[0])
+            degrees = self.longitude[0]
         milliseconds = (degrees * 3600000 +
                         self.longitude[1] * 60000 +
                         self.longitude[2] * 1000 +
                         self.longitude[3]) * sign
-        longitude = 0x80000000L + milliseconds
-        altitude = long(self.altitude) + 10000000L
+        longitude = 0x80000000 + milliseconds
+        altitude = int(self.altitude) + 10000000
         size = _encode_size(self.size, "size")
         hprec = _encode_size(self.horizontal_precision, "horizontal precision")
         vprec = _encode_size(self.vertical_precision, "vertical precision")
@@ -282,16 +282,16 @@ class LOC(dns.rdata.Rdata):
     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
+        if latitude > 0x80000000:
+            latitude = float(latitude - 0x80000000) / 3600000
         else:
-            latitude = -1 * float(0x80000000L - latitude) / 3600000
+            latitude = -1 * float(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 > 0x80000000:
+            longitude = float(longitude - 0x80000000) / 3600000
         else:
-            longitude = -1 * float(0x80000000L - longitude) / 3600000
+            longitude = -1 * float(0x80000000 - longitude) / 3600000
         if longitude < -180.0 or longitude > 180.0:
             raise dns.exception.FormError("bad longitude")
         altitude = float(altitude) - 10000000.0
@@ -304,7 +304,7 @@ class LOC(dns.rdata.Rdata):
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        f = cStringIO.StringIO()
+        f = io.BytesIO()
         self.to_wire(f)
         wire1 = f.getvalue()
         f.seek(0)
@@ -313,7 +313,7 @@ class LOC(dns.rdata.Rdata):
         wire2 = f.getvalue()
         f.close()
 
-        return cmp(wire1, wire2)
+        return dns.util.cmp(wire1, wire2)
 
     def _get_float_latitude(self):
         return _tuple_to_float(self.latitude)
index 72859ce108a883a0bcbcc4fd8ae185d7aea433f3..0a373d1521347bd5752bffd4acbd8be5fe1d43f9 100644 (file)
 # 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 io
 
 import dns.exception
 import dns.rdata
 import dns.rdatatype
 import dns.name
+import dns.util
 
 class NSEC(dns.rdata.Rdata):
     """NSEC record
@@ -40,9 +41,9 @@ class NSEC(dns.rdata.Rdata):
         text = ''
         for (window, bitmap) in self.windows:
             bits = []
-            for i in xrange(0, len(bitmap)):
-                byte = ord(bitmap[i])
-                for j in xrange(0, 8):
+            for i in range(0, len(bitmap)):
+                byte = bitmap[i]
+                for j in range(0, 8):
                     if byte & (0x80 >> j):
                         bits.append(dns.rdatatype.to_text(window * 256 + \
                                                           i * 8 + j))
@@ -67,7 +68,7 @@ class NSEC(dns.rdata.Rdata):
         window = 0
         octets = 0
         prior_rdtype = 0
-        bitmap = ['\0'] * 32
+        bitmap = bytearray(32)
         windows = []
         for nrdtype in rdtypes:
             if nrdtype == prior_rdtype:
@@ -75,15 +76,15 @@ 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, bytes(bitmap[0:octets])))
+                bitmap = bytearray(32)
                 window = new_window
             offset = nrdtype % 256
-            byte = offset / 8
+            byte = offset // 8
             bit = offset % 8
             octets = byte + 1
-            bitmap[byte] = chr(ord(bitmap[byte]) | (0x80 >> bit))
-        windows.append((window, ''.join(bitmap[0:octets])))
+            bitmap[byte] = bitmap[byte] | (0x80 >> bit)
+        windows.append((window, bytes(bitmap[0:octets])))
         return cls(rdclass, rdtype, next, windows)
 
     from_text = classmethod(from_text)
@@ -91,8 +92,8 @@ class NSEC(dns.rdata.Rdata):
     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)))
+            dns.util.write_uint8(file, window)
+            dns.util.write_uint8(file, len(bitmap))
             file.write(bitmap)
 
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
@@ -103,8 +104,8 @@ 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
@@ -125,17 +126,17 @@ class NSEC(dns.rdata.Rdata):
         self.next = self.next.choose_relativity(origin, relativize)
 
     def _cmp(self, other):
-        v = cmp(self.next, other.next)
+        v = dns.util.cmp(self.next, other.next)
         if v == 0:
-            b1 = cStringIO.StringIO()
+            b1 = io.BytesIO()
             for (window, bitmap) in self.windows:
-                b1.write(chr(window))
-                b1.write(chr(len(bitmap)))
+                dns.util.write_uint8(b1, window)
+                dns.util.write_uint8(b1, len(bitmap))
                 b1.write(bitmap)
-            b2 = cStringIO.StringIO()
+            b2 = io.BytesIO()
             for (window, bitmap) in other.windows:
-                b2.write(chr(window))
-                b2.write(chr(len(bitmap)))
+                dns.util.write_uint8(b2, window)
+                dns.util.write_uint8(b2, len(bitmap))
                 b2.write(bitmap)
-            v = cmp(b1.getvalue(), b2.getvalue())
+            v = dns.util.cmp(b1.getvalue(), b2.getvalue())
         return v
index 932d7b40327553a83e5f8c971f6558a4b94d8a11..c00f8cc603f376c7dbd362cd0800d6c6ecb52a2e 100644 (file)
 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 import base64
-import cStringIO
+import io
 import string
 import struct
 
 import dns.exception
 import dns.rdata
 import dns.rdatatype
+import dns.util
 
-b32_hex_to_normal = string.maketrans('0123456789ABCDEFGHIJKLMNOPQRSTUV',
-                                     'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567')
-b32_normal_to_hex = string.maketrans('ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
-                                     '0123456789ABCDEFGHIJKLMNOPQRSTUV')
+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
@@ -63,16 +64,17 @@ class NSEC3(dns.rdata.Rdata):
 
     def to_text(self, origin=None, relativize=True, **kw):
         next = base64.b32encode(self.next).translate(b32_normal_to_hex).lower()
-        if self.salt == '':
+        next = next.decode('ascii')
+        if self.salt == b'':
             salt = '-'
         else:
-            salt = self.salt.encode('hex-codec')
+            salt = base64.b16encode(self.salt).decode('ascii').lower()
         text = ''
         for (window, bitmap) in self.windows:
             bits = []
-            for i in xrange(0, len(bitmap)):
-                byte = ord(bitmap[i])
-                for j in xrange(0, 8):
+            for i in range(0, len(bitmap)):
+                byte = bitmap[i]
+                for j in range(0, 8):
                     if byte & (0x80 >> j):
                         bits.append(dns.rdatatype.to_text(window * 256 + \
                                                           i * 8 + j))
@@ -86,10 +88,11 @@ class NSEC3(dns.rdata.Rdata):
         iterations = tok.get_uint16()
         salt = tok.get_string()
         if salt == '-':
-            salt = ''
+            salt = b''
         else:
-            salt = salt.decode('hex-codec')
-        next = tok.get_string().upper().translate(b32_hex_to_normal)
+            salt = bytes.fromhex(salt)
+        next = tok.get_string().upper().encode('ascii')
+        next = next.translate(b32_hex_to_normal)
         next = base64.b32decode(next)
         rdtypes = []
         while 1:
@@ -106,7 +109,7 @@ class NSEC3(dns.rdata.Rdata):
         window = 0
         octets = 0
         prior_rdtype = 0
-        bitmap = ['\0'] * 32
+        bitmap = bytearray(32)
         windows = []
         for nrdtype in rdtypes:
             if nrdtype == prior_rdtype:
@@ -114,15 +117,15 @@ class NSEC3(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, bytes(bitmap[0:octets])))
+                bitmap = bytearray(32)
                 window = new_window
             offset = nrdtype % 256
-            byte = offset / 8
+            byte = offset // 8
             bit = offset % 8
             octets = byte + 1
-            bitmap[byte] = chr(ord(bitmap[byte]) | (0x80 >> bit))
-        windows.append((window, ''.join(bitmap[0:octets])))
+            bitmap[byte] = bitmap[byte] | (0x80 >> bit)
+        windows.append((window, bytes(bitmap[0:octets])))
         return cls(rdclass, rdtype, algorithm, flags, iterations, salt, next, windows)
 
     from_text = classmethod(from_text)
@@ -136,8 +139,8 @@ 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)))
+            dns.util.write_uint8(file, window)
+            dns.util.write_uint8(file, len(bitmap))
             file.write(bitmap)
 
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
@@ -148,7 +151,7 @@ class NSEC3(dns.rdata.Rdata):
         salt = wire[current : current + slen]
         current += slen
         rdlen -= slen
-        (nlen, ) = struct.unpack('!B', wire[current])
+        nlen = wire[current]
         current += 1
         rdlen -= 1
         next = wire[current : current + nlen]
@@ -158,8 +161,8 @@ 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
@@ -175,8 +178,8 @@ class NSEC3(dns.rdata.Rdata):
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        b1 = cStringIO.StringIO()
+        b1 = io.BytesIO()
         self.to_wire(b1)
-        b2 = cStringIO.StringIO()
+        b2 = io.BytesIO()
         other.to_wire(b2)
-        return cmp(b1.getvalue(), b2.getvalue())
+        return dns.util.cmp(b1.getvalue(), b2.getvalue())
index ec91e5e85c3a76544f5529f9ab09487439277bb9..03bc1890aca859b272b6192c8f03853bf07601e0 100644 (file)
 # 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 base64
+import io
 import struct
 
 import dns.exception
 import dns.rdata
+import dns.util
 
 class NSEC3PARAM(dns.rdata.Rdata):
     """NSEC3PARAM record
@@ -41,10 +43,10 @@ class NSEC3PARAM(dns.rdata.Rdata):
         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')
+            salt = base64.b16encode(self.salt).decode('ascii').lower()
         return '%u %u %u %s' % (self.algorithm, self.flags, self.iterations, salt)
 
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
@@ -53,9 +55,9 @@ class NSEC3PARAM(dns.rdata.Rdata):
         iterations = tok.get_uint16()
         salt = tok.get_string()
         if salt == '-':
-            salt = ''
+            salt = b''
         else:
-            salt = salt.decode('hex-codec')
+            salt = bytes.fromhex(salt)
         return cls(rdclass, rdtype, algorithm, flags, iterations, salt)
 
     from_text = classmethod(from_text)
@@ -81,8 +83,8 @@ class NSEC3PARAM(dns.rdata.Rdata):
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        b1 = cStringIO.StringIO()
+        b1 = io.BytesIO()
         self.to_wire(b1)
-        b2 = cStringIO.StringIO()
+        b2 = io.BytesIO()
         other.to_wire(b2)
-        return cmp(b1.getvalue(), b2.getvalue())
+        return dns.util.cmp(b1.getvalue(), b2.getvalue())
index 99ae9b9dff6eca36bcaaa60de38cf91087654260..9721cb602a92e1a785b56b7f9b0c3c0cae2500ac 100644 (file)
@@ -17,6 +17,7 @@ import dns.exception
 import dns.rdata
 import dns.rdatatype
 import dns.name
+import dns.util
 
 class NXT(dns.rdata.Rdata):
     """NXT record
@@ -37,9 +38,9 @@ class NXT(dns.rdata.Rdata):
     def to_text(self, origin=None, relativize=True, **kw):
         next = self.next.choose_relativity(origin, relativize)
         bits = []
-        for i in xrange(0, len(self.bitmap)):
-            byte = ord(self.bitmap[i])
-            for j in xrange(0, 8):
+        for i in range(0, len(self.bitmap)):
+            byte = self.bitmap[i]
+            for j in range(0, 8):
                 if byte & (0x80 >> j):
                     bits.append(dns.rdatatype.to_text(i * 8 + j))
         text = ' '.join(bits)
@@ -48,10 +49,7 @@ class NXT(dns.rdata.Rdata):
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         next = tok.get_name()
         next = next.choose_relativity(origin, relativize)
-        bitmap = ['\x00', '\x00', '\x00', '\x00',
-                  '\x00', '\x00', '\x00', '\x00',
-                  '\x00', '\x00', '\x00', '\x00',
-                  '\x00', '\x00', '\x00', '\x00' ]
+        bitmap = bytearray(32)
         while 1:
             token = tok.get().unescape()
             if token.is_eol_or_eof():
@@ -65,7 +63,7 @@ class NXT(dns.rdata.Rdata):
             if nrdtype > 127:
                 raise dns.exception.SyntaxError("NXT with bit > 127")
             i = nrdtype // 8
-            bitmap[i] = chr(ord(bitmap[i]) | (0x80 >> (nrdtype % 8)))
+            bitmap[i] = bitmap[i] | (0x80 >> (nrdtype % 8))
         bitmap = dns.rdata._truncate_bitmap(bitmap)
         return cls(rdclass, rdtype, next, bitmap)
 
@@ -93,7 +91,7 @@ class NXT(dns.rdata.Rdata):
         self.next = self.next.choose_relativity(origin, relativize)
 
     def _cmp(self, other):
-        v = cmp(self.next, other.next)
+        v = dns.util.cmp(self.next, other.next)
         if v == 0:
-            v = cmp(self.bitmap, other.bitmap)
+            v = dns.util.cmp(self.bitmap, other.bitmap)
         return v
index 421ce8e207ece7e782f15ecfff2d94a8cbc3cfde..50ff3ffab1bce94b5860c8baf44ce5c419bfd451 100644 (file)
@@ -16,6 +16,7 @@
 import dns.exception
 import dns.rdata
 import dns.name
+import dns.util
 
 class RP(dns.rdata.Rdata):
     """RP record
@@ -80,7 +81,7 @@ class RP(dns.rdata.Rdata):
         self.txt = self.txt.choose_relativity(origin, relativize)
 
     def _cmp(self, other):
-        v = cmp(self.mbox, other.mbox)
+        v = dns.util.cmp(self.mbox, other.mbox)
         if v == 0:
-            v = cmp(self.txt, other.txt)
+            v = dns.util.cmp(self.txt, other.txt)
         return v
index a25a35e29b0bf4bb1a9eb42ea4d2d4003dcd620a..94d81a1f9dd1ac4c73d1d9a311aa6832bbbc9b4b 100644 (file)
@@ -18,6 +18,7 @@ import struct
 import dns.exception
 import dns.rdata
 import dns.name
+import dns.util
 
 class SOA(dns.rdata.Rdata):
     """SOA record
@@ -41,7 +42,7 @@ class SOA(dns.rdata.Rdata):
 
     __slots__ = ['mname', 'rname', 'serial', 'refresh', 'retry', 'expire',
                  'minimum']
-    
+
     def __init__(self, rdclass, rdtype, mname, rname, serial, refresh, retry,
                  expire, minimum):
         super(SOA, self).__init__(rdclass, rdtype)
@@ -59,7 +60,7 @@ class SOA(dns.rdata.Rdata):
         return '%s %s %d %d %d %d %d' % (
             mname, rname, self.serial, self.refresh, self.retry,
             self.expire, self.minimum )
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         mname = tok.get_name()
         rname = tok.get_name()
@@ -73,7 +74,7 @@ class SOA(dns.rdata.Rdata):
         tok.get_eol()
         return cls(rdclass, rdtype, mname, rname, serial, refresh, retry,
                    expire, minimum )
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
@@ -114,14 +115,14 @@ class SOA(dns.rdata.Rdata):
         self.rname = self.rname.choose_relativity(origin, relativize)
 
     def _cmp(self, other):
-        v = cmp(self.mname, other.mname)
+        v = dns.util.cmp(self.mname, other.mname)
         if v == 0:
-            v = cmp(self.rname, other.rname)
+            v = dns.util.cmp(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 = dns.util.cmp(self_ints, other_ints)
         return v
index 162dda5c4887ae501634370bf0c5fe7abd96b436..6505b2c9b782fd8e44ddcfaa61afdd1c0348208e 100644 (file)
@@ -17,6 +17,7 @@ import struct
 
 import dns.rdata
 import dns.rdatatype
+import dns.util
 
 class SSHFP(dns.rdata.Rdata):
     """SSHFP record
@@ -30,7 +31,7 @@ class SSHFP(dns.rdata.Rdata):
     @see: draft-ietf-secsh-dns-05.txt"""
 
     __slots__ = ['algorithm', 'fp_type', 'fingerprint']
-    
+
     def __init__(self, rdclass, rdtype, algorithm, fp_type,
                  fingerprint):
         super(SSHFP, self).__init__(rdclass, rdtype)
@@ -43,22 +44,21 @@ class SSHFP(dns.rdata.Rdata):
                              self.fp_type,
                              dns.rdata._hexify(self.fingerprint,
                                                chunksize=128))
-        
+
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         algorithm = tok.get_uint8()
         fp_type = tok.get_uint8()
-        fingerprint = tok.get_string()
-        fingerprint = fingerprint.decode('hex_codec')
+        fingerprint = bytes.fromhex(tok.get_string())
         tok.get_eol()
         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)
-        
+
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         header = struct.unpack("!BB", wire[current : current + 2])
         current += 2
@@ -71,7 +71,7 @@ class SSHFP(dns.rdata.Rdata):
     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 = dns.util.cmp(hs, ho)
         if v == 0:
-            v = cmp(self.fingerprint, other.fingerprint)
+            v = dns.util.cmp(self.fingerprint, other.fingerprint)
         return v
index c3632f7fc406b088c08dd834f3a0fc8e9be101a0..190ef5ed06f7cc791d523f152440ee8f0ac73c11 100644 (file)
@@ -16,6 +16,7 @@
 import dns.exception
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 class X25(dns.rdata.Rdata):
     """X25 record
@@ -25,38 +26,37 @@ class X25(dns.rdata.Rdata):
     @see: RFC 1183"""
 
     __slots__ = ['address']
-    
+
     def __init__(self, rdclass, rdtype, address):
         super(X25, self).__init__(rdclass, rdtype)
         self.address = address
 
     def to_text(self, origin=None, relativize=True, **kw):
         return '"%s"' % dns.rdata._escapify(self.address)
-        
+
     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(self.address)
-        
+        dns.util.write_uint8(file, l)
+        file.write(self.address.encode('latin_1'))
+
     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:
             raise dns.exception.FormError
-        address = wire[current : current + l]
+        address = wire[current : current + l].decode('latin_1')
         return cls(rdclass, rdtype, address)
 
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        return cmp(self.address, other.address)
+        return dns.util.cmp(self.address, other.address)
index e05f204a2fd59014188fbad8f3eba2c0f00f850b..81415211df569bf69c46e342dec1a39ea66affeb 100644 (file)
@@ -17,6 +17,7 @@ import dns.exception
 import dns.ipv4
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 class A(dns.rdata.Rdata):
     """A record.
@@ -54,4 +55,4 @@ class A(dns.rdata.Rdata):
     def _cmp(self, other):
         sa = dns.ipv4.inet_aton(self.address)
         oa = dns.ipv4.inet_aton(other.address)
-        return cmp(sa, oa)
+        return dns.util.cmp(sa, oa)
index 2d812d39eb95cc5b8c378e52d9600af4bc4ba728..c7eb366fcdf91e0b512a29c7db04bd134d0b4a18 100644 (file)
@@ -17,6 +17,7 @@ import dns.exception
 import dns.inet
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 class AAAA(dns.rdata.Rdata):
     """AAAA record.
@@ -55,4 +56,4 @@ class AAAA(dns.rdata.Rdata):
     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 dns.util.cmp(sa, oa)
index 7412c02d304196d9570e1b55c46553201356bdce..5bb7b28e8534541648b0c779fecc0342aaf246a2 100644 (file)
 # 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 io
 import struct
 
 import dns.exception
 import dns.inet
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 class APLItem(object):
     """An APL list item.
@@ -59,7 +60,7 @@ class APLItem(object):
         # Truncate least significant zero bytes.
         #
         last = 0
-        for i in xrange(len(address) - 1, -1, -1):
+        for i in range(len(address) - 1, -1, -1):
             if address[i] != chr(0):
                 last = i + 1
                 break
@@ -135,18 +136,18 @@ class APL(dns.rdata.Rdata):
             l = len(address)
             if header[0] == 1:
                 if l < 4:
-                    address += '\x00' * (4 - l)
+                    address += b'\x00' * (4 - l)
                 address = dns.inet.inet_ntop(dns.inet.AF_INET, address)
             elif header[0] == 2:
                 if l < 16:
-                    address += '\x00' * (16 - l)
+                    address += b'\x00' * (16 - l)
                 address = dns.inet.inet_ntop(dns.inet.AF_INET6, address)
             else:
                 #
                 # This isn't really right according to the RFC, but it
                 # seems better than throwing an exception
                 #
-                address = address.encode('hex_codec')
+                address = dns.rdata._hexify(address)
             current += afdlen
             rdlen -= afdlen
             item = APLItem(header[0], negation, address, header[1])
@@ -158,7 +159,7 @@ class APL(dns.rdata.Rdata):
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        f = cStringIO.StringIO()
+        f = io.BytesIO()
         self.to_wire(f)
         wire1 = f.getvalue()
         f.seek(0)
@@ -167,4 +168,4 @@ class APL(dns.rdata.Rdata):
         wire2 = f.getvalue()
         f.close()
 
-        return cmp(wire1, wire2)
+        return dns.util.cmp(wire1, wire2)
index 2d35234bf04ca025638438698c4097ae078e8ec0..ef4654ad752192ac7255a0634df79eaf1cbb3626 100644 (file)
 # 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
+import dns.util
 
 class DHCID(dns.rdata.Rdata):
     """DHCID record
@@ -42,7 +45,7 @@ class DHCID(dns.rdata.Rdata):
                 raise dns.exception.SyntaxError
             chunks.append(t.value)
         b64 = ''.join(chunks)
-        data = b64.decode('base64_codec')
+        data = base64.b64decode(b64.encode('ascii'))
         return cls(rdclass, rdtype, data)
 
     from_text = classmethod(from_text)
@@ -57,4 +60,4 @@ class DHCID(dns.rdata.Rdata):
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        return cmp(self.data, other.data)
+        return dns.util.cmp(self.data, other.data)
index 9ab08d881c552877090315192d30629210a9d759..3a7810a3c8a3df56bd2c9c0d9dd013928ec842b5 100644 (file)
 # 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 base64
+import io
 import struct
 
 import dns.exception
 import dns.inet
 import dns.name
+import dns.util
 
 class IPSECKEY(dns.rdata.Rdata):
     """IPSECKEY record
@@ -92,7 +94,7 @@ class IPSECKEY(dns.rdata.Rdata):
                 raise dns.exception.SyntaxError
             chunks.append(t.value)
         b64 = ''.join(chunks)
-        key = b64.decode('base64_codec')
+        key = base64.b64decode(b64.encode('ascii'))
         return cls(rdclass, rdtype, precedence, gateway_type, algorithm,
                    gateway, key)
 
@@ -147,7 +149,7 @@ class IPSECKEY(dns.rdata.Rdata):
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        f = cStringIO.StringIO()
+        f = io.BytesIO()
         self.to_wire(f)
         wire1 = f.getvalue()
         f.seek(0)
@@ -156,4 +158,4 @@ class IPSECKEY(dns.rdata.Rdata):
         wire2 = f.getvalue()
         f.close()
 
-        return cmp(wire1, wire2)
+        return dns.util.cmp(wire1, wire2)
index a3cca55e1ce6fe581377f4ab891d8fafa061c1c9..951dec0342af3f3fc55e10d987455826963918c9 100644 (file)
@@ -18,13 +18,13 @@ import struct
 import dns.exception
 import dns.name
 import dns.rdata
+import dns.util
 
 def _write_string(file, s):
     l = len(s)
     assert l < 256
-    byte = chr(l)
-    file.write(byte)
-    file.write(s)
+    dns.util.write_uint8(file, l)
+    file.write(s.encode('ascii'))
 
 class NAPTR(dns.rdata.Rdata):
     """NAPTR record
@@ -45,7 +45,7 @@ class NAPTR(dns.rdata.Rdata):
 
     __slots__ = ['order', 'preference', 'flags', 'service', 'regexp',
                  'replacement']
-    
+
     def __init__(self, rdclass, rdtype, order, preference, flags, service,
                  regexp, replacement):
         super(NAPTR, self).__init__(rdclass, rdtype)
@@ -76,7 +76,7 @@ class NAPTR(dns.rdata.Rdata):
         tok.get_eol()
         return cls(rdclass, rdtype, order, preference, flags, service,
                    regexp, replacement)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
@@ -86,19 +86,19 @@ class NAPTR(dns.rdata.Rdata):
         _write_string(file, self.service)
         _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])
         current += 4
         rdlen -= 4
         strings = []
-        for i in xrange(3):
-            l = ord(wire[current])
+        for i in range(3):
+            l = wire[current]
             current += 1
             rdlen -= 1
             if l > rdlen or rdlen < 0:
                 raise dns.exception.FormError
-            s = wire[current : current + l]
+            s = wire[current : current + l].decode('latin_1')
             current += l
             rdlen -= l
             strings.append(s)
@@ -116,17 +116,17 @@ class NAPTR(dns.rdata.Rdata):
     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 = dns.util.cmp(sp, op)
         if v == 0:
-            v = cmp(self.flags, other.flags)
+            v = dns.util.cmp(self.flags, other.flags)
             if v == 0:
-                v = cmp(self.service, other.service)
+                v = dns.util.cmp(self.service, other.service)
                 if v == 0:
-                    v = cmp(self.regexp, other.regexp)
+                    v = dns.util.cmp(self.regexp, other.regexp)
                     if v == 0:
-                        v = cmp(self.replacement, other.replacement)
+                        v = dns.util.cmp(self.replacement, other.replacement)
         return v
index 22b9131ccf3fe0c751801f542cf3131f54d4b453..1d66114ccc25790abdf45571276d1a4500b7ba30 100644 (file)
@@ -16,6 +16,7 @@
 import dns.exception
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 class NSAP(dns.rdata.Rdata):
     """NSAP record.
@@ -31,7 +32,7 @@ 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" % dns.rdata._hexify(self.address, 256)
 
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         address = tok.get_string()
@@ -41,7 +42,7 @@ 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 = bytes.fromhex(address)
         return cls(rdclass, rdtype, address)
 
     from_text = classmethod(from_text)
@@ -56,4 +57,4 @@ class NSAP(dns.rdata.Rdata):
     from_wire = classmethod(from_wire)
 
     def _cmp(self, other):
-        return cmp(self.address, other.address)
+        return dns.util.cmp(self.address, other.address)
index 0f112907240696c0cb74acbed5855c8a1c2df3e9..52eae542ec45456067cfbd450a47e041c7f6050f 100644 (file)
@@ -18,6 +18,7 @@ import struct
 import dns.exception
 import dns.rdata
 import dns.name
+import dns.util
 
 class PX(dns.rdata.Rdata):
     """PX record.
@@ -31,7 +32,7 @@ class PX(dns.rdata.Rdata):
     @see: RFC 2163"""
 
     __slots__ = ['preference', 'map822', 'mapx400']
-        
+
     def __init__(self, rdclass, rdtype, preference, map822, mapx400):
         super(PX, self).__init__(rdclass, rdtype)
         self.preference = preference
@@ -42,7 +43,7 @@ class PX(dns.rdata.Rdata):
         map822 = self.map822.choose_relativity(origin, relativize)
         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):
         preference = tok.get_uint16()
         map822 = tok.get_name()
@@ -51,7 +52,7 @@ class PX(dns.rdata.Rdata):
         mapx400 = mapx400.choose_relativity(origin, relativize)
         tok.get_eol()
         return cls(rdclass, rdtype, preference, map822, mapx400)
-    
+
     from_text = classmethod(from_text)
 
     def to_wire(self, file, compress = None, origin = None):
@@ -59,7 +60,7 @@ class PX(dns.rdata.Rdata):
         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])
         current += 2
@@ -89,9 +90,9 @@ class PX(dns.rdata.Rdata):
     def _cmp(self, other):
         sp = struct.pack("!H", self.preference)
         op = struct.pack("!H", other.preference)
-        v = cmp(sp, op)
+        v = dns.util.cmp(sp, op)
         if v == 0:
-            v = cmp(self.map822, other.map822)
+            v = dns.util.cmp(self.map822, other.map822)
             if v == 0:
-                v = cmp(self.mapx400, other.mapx400)
+                v = dns.util.cmp(self.mapx400, other.mapx400)
         return v
index c9c5823381fe159594664564f23981f5f2030971..d5c5017ddd5ce16848f20089282e401848433866 100644 (file)
@@ -18,6 +18,7 @@ import struct
 import dns.exception
 import dns.rdata
 import dns.name
+import dns.util
 
 class SRV(dns.rdata.Rdata):
     """SRV record
@@ -83,7 +84,7 @@ class SRV(dns.rdata.Rdata):
     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 = dns.util.cmp(sp, op)
         if v == 0:
-            v = cmp(self.target, other.target)
+            v = dns.util.cmp(self.target, other.target)
         return v
index 85aafb3d231d546cf3d68c5ed89cf0b9318fd87c..f0b169e0b5cdc74fb75fdbe11e5a487ac77b94fa 100644 (file)
@@ -18,6 +18,7 @@ import struct
 
 import dns.ipv4
 import dns.rdata
+import dns.util
 
 _proto_tcp = socket.getprotobyname('tcp')
 _proto_udp = socket.getprotobyname('udp')
@@ -43,9 +44,9 @@ class WKS(dns.rdata.Rdata):
 
     def to_text(self, origin=None, relativize=True, **kw):
         bits = []
-        for i in xrange(0, len(self.bitmap)):
-            byte = ord(self.bitmap[i])
-            for j in xrange(0, 8):
+        for i in range(0, len(self.bitmap)):
+            byte = self.bitmap[i]
+            for j in range(0, 8):
                 if byte & (0x80 >> j):
                     bits.append(str(i * 8 + j))
         text = ' '.join(bits)
@@ -58,7 +59,7 @@ class WKS(dns.rdata.Rdata):
             protocol = int(protocol)
         else:
             protocol = socket.getprotobyname(protocol)
-        bitmap = []
+        bitmap = bytearray(32 * 256)
         while 1:
             token = tok.get().unescape()
             if token.is_eol_or_eof():
@@ -74,11 +75,7 @@ class WKS(dns.rdata.Rdata):
                     protocol_text = "tcp"
                 serv = socket.getservbyname(token.value, protocol_text)
             i = serv // 8
-            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[i] = bitmap[i] | (0x80 >> (serv % 8))
         bitmap = dns.rdata._truncate_bitmap(bitmap)
         return cls(rdclass, rdtype, address, protocol, bitmap)
 
@@ -103,11 +100,11 @@ class WKS(dns.rdata.Rdata):
     def _cmp(self, other):
         sa = dns.ipv4.inet_aton(self.address)
         oa = dns.ipv4.inet_aton(other.address)
-        v = cmp(sa, oa)
+        v = dns.util.cmp(sa, oa)
         if v == 0:
             sp = struct.pack('!B', self.protocol)
             op = struct.pack('!B', other.protocol)
-            v = cmp(sp, op)
+            v = dns.util.cmp(sp, op)
             if v == 0:
-                v = cmp(self.bitmap, other.bitmap)
+                v = dns.util.cmp(self.bitmap, other.bitmap)
         return v
index aa46403a5f181ac69583cf00eda077a63b8e314c..139c249a24f655c32e4115dc555d03b634a95453 100644 (file)
@@ -17,6 +17,7 @@ import struct
 
 import dns.rdata
 import dns.rdatatype
+import dns.util
 
 class DSBase(dns.rdata.Rdata):
     """Base class for rdata that is like a DS record
@@ -47,6 +48,7 @@ class DSBase(dns.rdata.Rdata):
                                 dns.rdata._hexify(self.digest,
                                                   chunksize=128))
 
+    @classmethod
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         key_tag = tok.get_uint16()
         algorithm = tok.get_uint8()
@@ -59,19 +61,17 @@ class DSBase(dns.rdata.Rdata):
             if not t.is_identifier():
                 raise dns.exception.SyntaxError
             chunks.append(t.value)
-        digest = ''.join(chunks)
-        digest = digest.decode('hex_codec')
+        digest = bytes.fromhex(''.join(chunks))
         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 +79,12 @@ class DSBase(dns.rdata.Rdata):
         digest = wire[current : current + rdlen]
         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 = dns.util.cmp(hs, ho)
         if v == 0:
-            v = cmp(self.digest, other.digest)
+            v = dns.util.cmp(self.digest, other.digest)
         return v
index 75c9272670bff9c3e002f0bf8b7f881c9e2b6084..3b18690282006f25b2f07b9fbbafbfdfd495bce8 100644 (file)
 # 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 struct
 
 import dns.exception
 import dns.dnssec
 import dns.rdata
+import dns.util
 
 _flags_from_text = {
     'NOCONF': (0x4000, 0xC000),
@@ -87,6 +89,7 @@ class KEYBase(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_string()
         if flags.isdigit():
@@ -118,16 +121,15 @@ class KEYBase(dns.rdata.Rdata):
                 raise dns.exception.SyntaxError
             chunks.append(t.value)
         b64 = ''.join(chunks)
-        key = b64.decode('base64_codec')
+        key = base64.b64decode(b64.encode('ascii'))
         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
@@ -138,12 +140,10 @@ class KEYBase(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 = dns.util.cmp(hs, ho)
         if v == 0:
-            v = cmp(self.key, other.key)
+            v = dns.util.cmp(self.key, other.key)
         return v
index 5e3515bec4bcc6cb1bcea5c5d34d743e61ecb41e..c7991a6a2ed48eb55d1eeb4c4e6064c6a1324a0a 100644 (file)
 
 """MX-like base classes."""
 
-import cStringIO
 import struct
 
 import dns.exception
 import dns.rdata
 import dns.name
+import dns.util
 
 class MXBase(dns.rdata.Rdata):
     """Base class for rdata that is like an MX record.
@@ -41,6 +41,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 +49,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 +58,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
@@ -71,17 +71,15 @@ class MXBase(dns.rdata.Rdata):
             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 = dns.util.cmp(sp, op)
         if v == 0:
-            v = cmp(self.exchange, other.exchange)
+            v = dns.util.cmp(self.exchange, other.exchange)
         return v
 
 class UncompressedMX(MXBase):
@@ -93,9 +91,7 @@ class UncompressedMX(MXBase):
         super(UncompressedMX, self).to_wire(file, None, origin)
 
     def to_digestable(self, origin = None):
-        f = cStringIO.StringIO()
-        self.to_wire(f, None, origin)
-        return f.getvalue()
+        return self.to_wire(f, None, origin)
 
 class UncompressedDowncasingMX(MXBase):
     """Base class for rdata that is like an MX record, but whose name
index 7cdb2a0289a2b1c3c224011fadd23701d8bdfc85..2a9e1e6cd98ed3f4c02afa7ceb916d46b581d55d 100644 (file)
 
 """NS-like base classes."""
 
-import cStringIO
+import io
 
 import dns.exception
 import dns.rdata
 import dns.name
+import dns.util
 
 class NSBase(dns.rdata.Rdata):
     """Base class for rdata that is like an NS record.
@@ -37,20 +38,20 @@ 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)
@@ -60,13 +61,11 @@ class NSBase(dns.rdata.Rdata):
             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 dns.util.cmp(self.target, other.target)
 
 class UncompressedNS(NSBase):
     """Base class for rdata that is like an NS record, but whose name
@@ -77,6 +76,4 @@ class UncompressedNS(NSBase):
         super(UncompressedNS, self).to_wire(file, None, origin)
 
     def to_digestable(self, origin = None):
-        f = cStringIO.StringIO()
-        self.to_wire(f, None, origin)
-        return f.getvalue()
+        return self.to_wire(None, None, origin)
index ccb6dd69ae78f26c1bd80c366a1f13e4b3525387..1df1f31de0484bae75ec2fa75bee604f3241058a 100644 (file)
@@ -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
@@ -21,6 +22,7 @@ import dns.dnssec
 import dns.exception
 import dns.rdata
 import dns.rdatatype
+import dns.util
 
 class BadSigTime(dns.exception.DNSException):
     """Raised when a SIG or RRSIG RR's time cannot be parsed."""
@@ -97,6 +99,7 @@ class SIGBase(dns.rdata.Rdata):
             dns.rdata._base64ify(self.signature)
             )
 
+    @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())
@@ -116,13 +119,11 @@ class SIGBase(dns.rdata.Rdata):
                 raise dns.exception.SyntaxError
             chunks.append(t.value)
         b64 = ''.join(chunks)
-        signature = b64.decode('base64_codec')
+        signature = base64.b64decode(b64.encode('ascii'))
         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):
         header = struct.pack('!HBBIIIH', self.type_covered,
                              self.algorithm, self.labels,
@@ -132,6 +133,7 @@ class SIGBase(dns.rdata.Rdata):
         self.signer.to_wire(file, None, origin)
         file.write(self.signature)
 
+    @classmethod
     def from_wire(cls, rdclass, rdtype, wire, current, rdlen, origin = None):
         header = struct.unpack('!HBBIIIH', wire[current : current + 18])
         current += 18
@@ -146,8 +148,6 @@ class SIGBase(dns.rdata.Rdata):
                    header[3], header[4], header[5], header[6], signer,
                    signature)
 
-    from_wire = classmethod(from_wire)
-
     def choose_relativity(self, origin = None, relativize = True):
         self.signer = self.signer.choose_relativity(origin, relativize)
 
@@ -160,9 +160,9 @@ class SIGBase(dns.rdata.Rdata):
                          other.algorithm, other.labels,
                          other.original_ttl, other.expiration,
                          other.inception, other.key_tag)
-        v = cmp(hs, ho)
+        v = dns.util.cmp(hs, ho)
         if v == 0:
-            v = cmp(self.signer, other.signer)
+            v = dns.util.cmp(self.signer, other.signer)
             if v == 0:
-                v = cmp(self.signature, other.signature)
+                v = dns.util.cmp(self.signature, other.signature)
         return v
index 43db2a48c0791c407acc403a33d2c12833aee412..fc25024028e09e94c8f9964663ea73fd4f164c9d 100644 (file)
@@ -18,6 +18,7 @@
 import dns.exception
 import dns.rdata
 import dns.tokenizer
+import dns.util
 
 class TXTBase(dns.rdata.Rdata):
     """Base class for rdata that is like a TXT record
@@ -42,6 +43,7 @@ class TXTBase(dns.rdata.Rdata):
             prefix = ' '
         return txt
 
+    @classmethod
     def from_text(cls, rdclass, rdtype, tok, origin = None, relativize = True):
         strings = []
         while 1:
@@ -57,31 +59,27 @@ class TXTBase(dns.rdata.Rdata):
             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(s)
+            dns.util.write_uint8(file, l)
+            file.write(s.encode('latin_1'))
 
+    @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:
                 raise dns.exception.FormError
-            s = wire[current : current + l]
+            s = wire[current : current + l].decode('latin_1')
             current += l
             rdlen -= l
             strings.append(s)
         return cls(rdclass, rdtype, strings)
 
-    from_wire = classmethod(from_wire)
-
     def _cmp(self, other):
-        return cmp(self.strings, other.strings)
+        return dns.util.cmp(self.strings, other.strings)
index bb0218ac301d81ec0b993fff56d2c9a3e2b44812..b0a081d9410c3da392b041626b40120dfaec59d2 100644 (file)
@@ -15,7 +15,7 @@
 
 """Help for building DNS wire format messages"""
 
-import cStringIO
+import io
 import struct
 import random
 import time
@@ -51,7 +51,7 @@ class Renderer(object):
         wire = r.get_wire()
 
     @ivar output: where rendering is written
-    @type output: cStringIO.StringIO object
+    @type output: io.BytesIO object
     @ivar id: the message id
     @type id: int
     @ivar flags: the message flags
@@ -86,7 +86,7 @@ class Renderer(object):
         @type origin: dns.name.Namem or None.
         """
 
-        self.output = cStringIO.StringIO()
+        self.output = io.BytesIO()
         if id is None:
             self.id = random.randint(0, 65535)
         else:
@@ -97,7 +97,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 +112,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,7 +218,7 @@ class Renderer(object):
         """
 
         # make sure the EDNS version in ednsflags agrees with edns
-        ednsflags &= 0xFF00FFFFL
+        ednsflags &= 0xFF00FFFF
         ednsflags |= (edns << 16)
         self._set_section(ADDITIONAL)
         before = self.output.tell()
index 372d7d83615b9474e0a1e4594e6eae375d99d4f6..f898c80892c7ec855391de57e4fbc248c8bc8ae2 100644 (file)
@@ -97,7 +97,7 @@ class Answer(object):
         self.response = response
         min_ttl = -1
         rrset = None
-        for count in xrange(0, 15):
+        for count in range(0, 15):
             try:
                 rrset = response.find_rrset(response.answer, qname,
                                             rdclass, rdtype)
@@ -188,7 +188,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:
@@ -234,7 +234,7 @@ class Cache(object):
         """
 
         if not key is None:
-            if self.data.has_key(key):
+            if key in self.data:
                 del self.data[key]
         else:
             self.data = {}
@@ -320,7 +320,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, str):
             try:
                 f = open(f, 'r')
             except IOError:
@@ -368,8 +368,6 @@ class Resolver(object):
 
     def _config_win32_nameservers(self, nameservers):
         """Configure a NameServer registry entry."""
-        # we call str() on nameservers to convert it from unicode to ascii
-        nameservers = str(nameservers)
         split_char = self._determine_split_char(nameservers)
         ns_list = nameservers.split(split_char)
         for ns in ns_list:
@@ -378,13 +376,10 @@ class Resolver(object):
 
     def _config_win32_domain(self, domain):
         """Configure a Domain registry entry."""
-        # we call str() on domain to convert it from unicode to ascii
-        self.domain = dns.name.from_text(str(domain))
+        self.domain = dns.name.from_text(domain)
 
     def _config_win32_search(self, search):
         """Configure a Search registry entry."""
-        # we call str() on search to convert it from unicode to ascii
-        search = str(search)
         split_char = self._determine_split_char(search)
         search_list = search.split(split_char)
         for s in search_list:
@@ -567,7 +562,7 @@ class Resolver(object):
         @raises NoNameservers: no non-broken nameservers are available to
         answer the question."""
 
-        if isinstance(qname, (str, unicode)):
+        if isinstance(qname, str):
             qname = dns.name.from_text(qname, None)
         if isinstance(rdtype, str):
             rdtype = dns.rdatatype.from_text(rdtype)
@@ -744,7 +739,7 @@ def zone_for_name(name, rdclass=dns.rdataclass.IN, tcp=False, resolver=None):
     @type resolver: dns.resolver.Resolver object or None
     @rtype: dns.name.Name"""
 
-    if isinstance(name, (str, unicode)):
+    if isinstance(name, str):
         name = dns.name.from_text(name, dns.name.root)
     if resolver is None:
         resolver = get_default_resolver()
index 0a61b827b0c6fe8680ae98e37749e7b9775a2577..6badf4849d20faa2b74b69e9bb21ef0c81270e69 100644 (file)
@@ -21,6 +21,8 @@
 @type ipv6_reverse_domain: dns.name.Name object
 """
 
+import base64
+
 import dns.name
 import dns.ipv6
 import dns.ipv4
@@ -37,13 +39,13 @@ def from_address(text):
     @rtype: dns.name.Name object
     """
     try:
-        parts = list(dns.ipv6.inet_aton(text).encode('hex_codec'))
+        parts = ['%x.%x' % (byte, byte >> 4) for byte in dns.ipv6.inet_aton(text)]
         origin = ipv6_reverse_domain
     except:
-        parts = ['%d' % ord(byte) for byte in dns.ipv4.inet_aton(text)]
+        parts = ['%d' % byte for byte in dns.ipv4.inet_aton(text)]
         origin = ipv4_reverse_domain
     parts.reverse()
-    return dns.name.from_text('.'.join(parts), origin=origin)
+    return dns.name.from_text('.'.join(parts).lower(), origin=origin)
 
 def to_address(name):
     """Convert a reverse map domain name into textual address form.
@@ -55,7 +57,7 @@ def to_address(name):
         name = name.relativize(ipv4_reverse_domain)
         labels = list(name.labels)
         labels.reverse()
-        text = '.'.join(labels)
+        text = '.'.join([x.decode('ascii') for x in 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):
@@ -66,7 +68,7 @@ def to_address(name):
         i = 0
         l = len(labels)
         while i < l:
-            parts.append(''.join(labels[i:i+4]))
+            parts.append(''.join([x.decode('ascii') for x in labels[i:i+4]]))
             i += 4
         text = ':'.join(parts)
         # run through inet_aton() to check syntax and make pretty.
index 7f6c4afed4a0a2f60328e7720df21d0676f345a3..317119248fd350c2836151005d0acd0b78f77a12 100644 (file)
@@ -122,7 +122,7 @@ def from_text_list(name, ttl, rdclass, rdtype, text_rdatas):
     @rtype: dns.rrset.RRset object
     """
 
-    if isinstance(name, (str, unicode)):
+    if isinstance(name, str):
         name = dns.name.from_text(name, None)
     if isinstance(rdclass, str):
         rdclass = dns.rdataclass.from_text(rdclass)
index 91f9fb876693d3cd5fb9945bfff2f3c6f3b7d052..033b7c22d02d22e974f0972222917b03d2ffc081 100644 (file)
@@ -18,9 +18,8 @@
 class Set(object):
     """A simple set class.
 
-    Sets are not in Python until 2.3, and rdata are not immutable so
-    we cannot use sets.Set anyway.  This class implements subset of
-    the 2.3 Set interface using a list as the container.
+    This class implements a mutable set using a list as the container.
+    We don't use Python's set class because it's not indexable.
 
     @ivar items: A list of the items which are in the set
     @type items: list"""
index 4f68a2a4952c467567518b478a998a79b38735dc..f9a59590e67477ce2eac1eaeff5faa4f92526c65 100644 (file)
 
 """Tokenize DNS master file format"""
 
-import cStringIO
+import io
 import sys
 
 import dns.exception
 import dns.name
 import dns.ttl
 
-_DELIMITERS = {
-    ' ' : True,
-    '\t' : True,
-    '\n' : True,
-    ';' : True,
-    '(' : True,
-    ')' : True,
-    '"' : True }
-
-_QUOTING_DELIMITERS = { '"' : True }
+_DELIMITERS = frozenset(' \t\n;()"')
+_QUOTING_DELIMITERS = frozenset('"')
 
 EOF = 0
 EOL = 1
@@ -198,7 +190,7 @@ class Tokenizer(object):
         """
 
         if isinstance(f, str):
-            f = cStringIO.StringIO(f)
+            f = io.StringIO(f)
             if filename is None:
                 filename = '<string>'
         else:
@@ -419,7 +411,7 @@ class Tokenizer(object):
             raise UngetBufferFull
         self.ungotten_token = token
 
-    def next(self):
+    def __next__(self):
         """Return the next item in an iteration.
         @rtype: (int, string)
         """
@@ -487,8 +479,8 @@ class Tokenizer(object):
             raise dns.exception.SyntaxError('expecting an identifier')
         if not token.value.isdigit():
             raise dns.exception.SyntaxError('expecting an integer')
-        value = long(token.value)
-        if value < 0 or value > 4294967296L:
+        value = int(token.value)
+        if value < 0 or value > 4294967296:
             raise dns.exception.SyntaxError('%d is not an unsigned 32-bit integer' % value)
         return value
 
index b4deeca859dcaac594acd4733326c17b64f5a4c7..2479d09b9cc1bdaff0da75511f3b89d105348acd 100644 (file)
@@ -15,6 +15,7 @@
 
 """DNS TSIG support."""
 
+import hashlib
 import hmac
 import struct
 
@@ -82,9 +83,8 @@ def sign(wire, keyname, secret, time, fudge, original_id, error,
         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
+    upper_time = (time >> 32) & 0xffff
+    lower_time = time & 0xffffffff
     time_mac = struct.pack('!HIH', upper_time, lower_time, fudge)
     pre_mac = algorithm_name + time_mac
     ol = len(other_data)
@@ -134,7 +134,7 @@ def validate(wire, keyname, secret, now, request_mac, tsig_start, tsig_rdata,
     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)
+    time = ((upper_time + 0) << 32) + lower_time
     current += 10
     mac = wire[current:current + mac_size]
     current += mac_size
@@ -176,35 +176,12 @@ def get_algorithm(algorithm):
     """
 
     hashes = {}
-    try:
-        import hashlib
-        hashes[dns.name.from_text('hmac-sha224')] = hashlib.sha224
-        hashes[dns.name.from_text('hmac-sha256')] = hashlib.sha256
-        hashes[dns.name.from_text('hmac-sha384')] = hashlib.sha384
-        hashes[dns.name.from_text('hmac-sha512')] = hashlib.sha512
-        hashes[dns.name.from_text('hmac-sha1')] = hashlib.sha1
-        hashes[dns.name.from_text('HMAC-MD5.SIG-ALG.REG.INT')] = hashlib.md5
-
-        import sys
-        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[dns.name.from_text('HMAC-MD5.SIG-ALG.REG.INT')] =  md5.md5
-        hashes[dns.name.from_text('hmac-sha1')] = sha.sha
+    hashes[dns.name.from_text('hmac-sha224')] = hashlib.sha224
+    hashes[dns.name.from_text('hmac-sha256')] = hashlib.sha256
+    hashes[dns.name.from_text('hmac-sha384')] = hashlib.sha384
+    hashes[dns.name.from_text('hmac-sha512')] = hashlib.sha512
+    hashes[dns.name.from_text('hmac-sha1')] = hashlib.sha1
+    hashes[dns.name.from_text('HMAC-MD5.SIG-ALG.REG.INT')] = hashlib.md5
 
     if isinstance(algorithm, (str, unicode)):
         algorithm = dns.name.from_text(algorithm)
index f295300517755cb7cc89d29b950bc7d1d74fead8..3bb1e700a34f504422a8ce52c9ebadcf6b14f129 100644 (file)
@@ -32,26 +32,26 @@ def from_text(text):
     """
 
     if text.isdigit():
-        total = long(text)
+        total = int(text)
     else:
         if not text[0].isdigit():
             raise BadTTL
-        total = 0L
-        current = 0L
+        total = 0
+        current = 0
         for c in text:
             if c.isdigit():
                 current *= 10
-                current += long(c)
+                current += int(c)
             else:
                 c = c.lower()
                 if c == 'w':
-                    total += current * 604800L
+                    total += current * 604800
                 elif c == 'd':
-                    total += current * 86400L
+                    total += current * 86400
                 elif c == 'h':
-                    total += current * 3600L
+                    total += current * 3600
                 elif c == 'm':
-                    total += current * 60L
+                    total += current * 60
                 elif c == 's':
                     total += current
                 else:
@@ -59,6 +59,6 @@ def from_text(text):
                 current = 0
         if not current == 0:
             raise BadTTL("trailing integer")
-    if total < 0L or total > 2147483647L:
+    if total < 0 or total > 2147483647:
         raise BadTTL("TTL should be between 0 and 2^31 - 1 (inclusive)")
     return total
index 7d4263689170574fdde5df4cfed2bf0b20556df8..33e0a956e12c68f6cc4bb00578350a240d48aab0 100644 (file)
@@ -47,7 +47,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, str):
             zone = dns.name.from_text(zone)
         self.origin = zone
         if isinstance(rdclass, str):
@@ -81,7 +81,7 @@ class Update(dns.message.Message):
 
                 - ttl, rdtype, string..."""
 
-        if isinstance(name, (str, unicode)):
+        if isinstance(name, str):
             name = dns.name.from_text(name, None)
         if isinstance(args[0], dns.rdataset.Rdataset):
             for rds in args:
@@ -131,7 +131,7 @@ class Update(dns.message.Message):
 
                 - rdtype, [string...]"""
 
-        if isinstance(name, (str, unicode)):
+        if isinstance(name, str):
             name = dns.name.from_text(name, None)
         if len(args) == 0:
             rrset = self.find_rrset(self.authority, name, dns.rdataclass.ANY,
@@ -189,7 +189,7 @@ class Update(dns.message.Message):
 
                 - rdtype, string..."""
 
-        if isinstance(name, (str, unicode)):
+        if isinstance(name, str):
             name = dns.name.from_text(name, None)
         if len(args) == 0:
             rrset = self.find_rrset(self.answer, name,
@@ -217,7 +217,7 @@ class Update(dns.message.Message):
         """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, str):
             name = dns.name.from_text(name, None)
         if rdtype is None:
             rrset = self.find_rrset(self.answer, name,
diff --git a/dns/util.py b/dns/util.py
new file mode 100644 (file)
index 0000000..876f930
--- /dev/null
@@ -0,0 +1,52 @@
+# Copyright (C) 2010 Nominum, Inc.
+#
+# Permission to use, copy, modify, and distribute this software and its
+# documentation for any purpose with or without fee is hereby granted,
+# provided that the above copyright notice and this permission notice
+# appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+# OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+"""Miscellaneous Implementation Helpers"""
+
+import struct
+
+def cmp(x, y):
+    if x > y:
+        return 1
+    elif x < y:
+        return -1
+    else:
+        return 0
+
+def write_uint8(bfile, value):
+    """Write an unsigned 8-bit integer to an io.BytesIO file
+    """
+
+    bfile.write(struct.pack('B', value))
+
+
+def write_uint16(bfile, value):
+    """Write an unsigned 16-bit integer to an io.BytesIO file
+    """
+
+    bfile.write(struct.pack('!H', value))
+
+def write_uint32(bfile, value):
+    """Write an unsigned 32-bit integer to an io.BytesIO file
+    """
+
+    bfile.write(struct.pack('!L', value))
+
+
+def write_uint64(bfile, value):
+    """Write an unsigned 64-bit integer to an io.BytesIO file
+    """
+
+    bfile.write(struct.pack('!Q', value))
index 93c157d8f01d22f5f94eba6a5e9d503465a8554d..5479f5aa5752ad9ec9731117ee22c0bfe40ad229 100644 (file)
@@ -107,7 +107,7 @@ class Zone(object):
         return not self.__eq__(other)
 
     def _validate_name(self, name):
-        if isinstance(name, (str, unicode)):
+        if isinstance(name, str):
             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")
@@ -205,7 +205,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,
@@ -423,7 +423,7 @@ class Zone(object):
             rdtype = dns.rdatatype.from_text(rdtype)
         if isinstance(covers, str):
             covers = dns.rdatatype.from_text(covers)
-        for (name, node) in self.iteritems():
+        for (name, node) in self.items():
             for rds in node:
                 if rdtype == dns.rdatatype.ANY or \
                    (rds.rdtype == rdtype and rds.covers == covers):
@@ -446,7 +446,7 @@ class Zone(object):
             rdtype = dns.rdatatype.from_text(rdtype)
         if isinstance(covers, str):
             covers = dns.rdatatype.from_text(covers)
-        for (name, node) in self.iteritems():
+        for (name, node) in self.items():
             for rds in node:
                 if rdtype == dns.rdatatype.ANY or \
                    (rds.rdtype == rdtype and rds.covers == covers):
@@ -471,23 +471,18 @@ class Zone(object):
         @type nl: string or None
         """
 
-        if sys.hexversion >= 0x02030000:
-            # allow Unicode filenames
-            str_type = basestring
-        else:
-            str_type = str
         if nl is None:
             opts = 'w'
         else:
             opts = 'wb'
-        if isinstance(f, str_type):
-            f = file(f, opts)
+        if isinstance(f, str):
+            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()
@@ -495,10 +490,10 @@ class Zone(object):
                 l = self[n].to_text(n, origin=self.origin,
                                     relativize=relativize)
                 if nl is None:
-                    print >> f, l
+                    print(l, file=f)
                 else:
-                    f.write(l)
-                    f.write(nl)
+                    f.write(l.encode('ascii'))
+                    f.write(nl.encode('ascii'))
         finally:
             if want_close:
                 f.close()
@@ -549,7 +544,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, str):
             origin = dns.name.from_text(origin)
         self.tok = tok
         self.current_origin = origin
@@ -699,7 +694,7 @@ 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
@@ -708,7 +703,7 @@ class _MasterReader(object):
                     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"
@@ -792,17 +787,10 @@ def from_file(f, origin = None, rdclass = dns.rdataclass.IN,
     @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'
-    if isinstance(f, str_type):
+    if isinstance(f, str):
         if filename is None:
             filename = f
-        f = file(f, opts)
+        f = open(f, 'rU')
         want_close = True
     else:
         if filename is None:
index ad40ccf84b5c439256b1b15406b3ebc92c14202d..497fd680e43023c21e894f4738a00aea2b1d2b2b 100755 (executable)
@@ -2,5 +2,5 @@
 
 import dns.e164
 n = dns.e164.from_e164("+1 555 1212")
-print n
-print dns.e164.to_e164(n)
+print(n)
+print(dns.e164.to_e164(n))
index 3036e70ddf3ead96df677600e8c199232573b83a..4fe34df10ca1c93e26e261ab89321e3950e7e150 100755 (executable)
@@ -4,4 +4,5 @@ import dns.resolver
 
 answers = dns.resolver.query('nominum.com', 'MX')
 for rdata in answers:
-    print 'Host', rdata.exchange, 'has preference', rdata.preference
+    print('Host', rdata.exchange, 'has preference', rdata.preference)
+
index b099c49d16675abdbb27e9fe635cc8cab6b422d9..a52d0e40a724decb384a466f7949bc0141f5f30c 100755 (executable)
@@ -4,10 +4,10 @@ import dns.name
 
 n = dns.name.from_text('www.dnspython.org')
 o = dns.name.from_text('dnspython.org')
-print n.is_subdomain(o)         # True
-print n.is_superdomain(o)       # False
-print n > o                     # True
-rel = n.relativize(o)           # rel is the relative name www
+print(n.is_subdomain(o))         # True
+print(n.is_superdomain(o))       # False
+print(n > o)                     # True
+rel = n.relativize(o)            # rel is the relative name www
 n2 = rel + o
-print n2 == n                   # True
-print n.labels                  # ['www', 'dnspython', 'org', '']
+print(n2 == n)                   # True
+print(n.labels)                  # (b'www', b'dnspython', b'org', b'')
index 8657baed440735dea4fe69f08b3a109e9f06066c..b8491ca4d26e61ed23119486f90a2cc6ec9d5037 100755 (executable)
@@ -28,13 +28,11 @@ for filename in sys.argv[1:]:
                               relativize=False)
     for (name, ttl, rdata) in zone.iterate_rdatas('A'):
         try:
-           reverse_map[rdata.address].append(name.to_text())
-       except KeyError:
-           reverse_map[rdata.address] = [name.to_text()]
+            reverse_map[rdata.address].append(name.to_text())
+        except KeyError:
+            reverse_map[rdata.address] = [name.to_text()]
 
-keys = reverse_map.keys()
-keys.sort(lambda a1, a2: cmp(dns.ipv4.inet_aton(a1), dns.ipv4.inet_aton(a2)))
+keys = sorted(reverse_map.keys(), key=dns.ipv4.inet_aton)
 for k in keys:
-    v = reverse_map[k]
-    v.sort()
-    print k, v
+    v = sorted(reverse_map[k])
+    print(k, v)
index 351896b01563dd8abd5e834a5d55f01e2c0b7e90..a87fe344883a90d469c25f55bab5bb0deb066477 100755 (executable)
@@ -2,5 +2,5 @@
 
 import dns.reversename
 n = dns.reversename.from_address("127.0.0.1")
-print n
-print dns.reversename.to_address(n)
+print(n)
+print(dns.reversename.to_address(n))
index 5cd6f55c06c7cb08f6f553b633bf759d6eaa5cf0..24e1c45e54bf16330664d7845a919d252ebd4aae 100755 (executable)
@@ -7,4 +7,4 @@ z = dns.zone.from_xfr(dns.query.xfr('204.152.189.147', 'dnspython.org'))
 names = z.nodes.keys()
 names.sort()
 for n in names:
-        print z[n].to_text(n)
+        print(z[n].to_text(n))
index 584f6a7da70a70516e8752f238df1f881ba33ea4..e375d9151ae4dc06c1e45c9a5e8cbc39a2e0a0d7 100644 (file)
@@ -15,7 +15,7 @@
 
 # $Id: Makefile,v 1.5 2004/03/19 00:17:27 halley Exp $
 
-PYTHON=python
+PYTHON=python3.1
 
 check: test
 
index 7134661d3ae7fc9e37e9b715a097202d9e2e6bac..e4b0858780cf46916d3ef78e37d88740563b9118 100644 (file)
@@ -13,7 +13,6 @@
 # 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
 
@@ -36,7 +35,7 @@ wwww.dnspython.org. IN A
 goodhex = '04d201000001000000000001047777777709646e73707974686f6e' \
           '036f726700000100010000291000000080000000'
 
-goodwire = goodhex.decode('hex_codec')
+goodwire = bytes.fromhex(goodhex)
 
 answer_text = """id 1234
 opcode QUERY
@@ -66,7 +65,7 @@ goodhex2 = '04d2 8500 0001 0001 0003 0001' \
            'c091 0001 0001 00000e10 0004 cc98ba96'
 
 
-goodwire2 = goodhex2.replace(' ', '').decode('hex_codec')
+goodwire2 = bytes.fromhex(goodhex2.replace(' ', ''))
 
 query_text_2 = """id 1234
 opcode QUERY
@@ -84,7 +83,7 @@ wwww.dnspython.org. IN A
 goodhex3 = '04d2010f0001000000000001047777777709646e73707974686f6e' \
           '036f726700000100010000291000ff0080000000'
 
-goodwire3 = goodhex3.decode('hex_codec')
+goodwire3 = bytes.fromhex(goodhex3)
 
 class MessageTestCase(unittest.TestCase):
 
@@ -130,7 +129,7 @@ class MessageTestCase(unittest.TestCase):
     def test_TooBig(self):
         def bad():
             q = dns.message.from_text(query_text)
-            for i in xrange(0, 25):
+            for i in range(0, 25):
                 rrset = dns.rrset.from_text('foo%d.' % i, 3600,
                                             dns.rdataclass.IN,
                                             dns.rdatatype.A,
@@ -146,13 +145,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 1ab4f52814b90c88277840d804ecf5873e9432cd..bf05a91b20aa1c83d53a24f42ebb2a409a5b0bf0 100644 (file)
@@ -15,8 +15,9 @@
 
 import unittest
 
-import cStringIO
+import io
 import socket
+import sys
 
 import dns.name
 import dns.reversename
@@ -25,18 +26,18 @@ import dns.e164
 class NameTestCase(unittest.TestCase):
     def setUp(self):
         self.origin = dns.name.from_text('example.')
-        
+
     def testFromTextRel1(self):
         n = dns.name.from_text('foo.bar')
-        self.failUnless(n.labels == ('foo', 'bar', ''))
+        self.failUnless(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.failUnless(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.failUnless(n.labels == (b'foo', b'bar'))
 
     def testFromTextRel4(self):
         n = dns.name.from_text('@', origin=None)
@@ -48,7 +49,7 @@ class NameTestCase(unittest.TestCase):
 
     def testFromTextAbs1(self):
         n = dns.name.from_text('foo.bar.')
-        self.failUnless(n.labels == ('foo', 'bar', ''))
+        self.failUnless(n.labels == (b'foo', b'bar', b''))
 
     def testTortureFromText(self):
         good = [
@@ -80,6 +81,9 @@ class NameTestCase(unittest.TestCase):
             try:
                 n = dns.name.from_text(t)
             except:
+                info = sys.exc_info()
+                print(info[0])
+                print(info[2])
                 self.fail("good test '%s' raised an exception" % t)
         for t in bad:
             caught = False
@@ -97,7 +101,7 @@ class NameTestCase(unittest.TestCase):
 
     def testImmutable2(self):
         def bad():
-            self.origin.labels[0] = 'foo'
+            self.origin.labels[0] = b'foo'
         self.failUnlessRaises(TypeError, bad)
 
     def testAbs1(self):
@@ -155,9 +159,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,7 +198,7 @@ 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.failUnless(c.labels == (b'foo', b'bar', b'example', b''))
 
     def testToText1(self):
         n = dns.name.from_text('FOO.bar', origin=self.origin)
@@ -240,17 +241,17 @@ class NameTestCase(unittest.TestCase):
     def testSlice1(self):
         n = dns.name.from_text(r'a.b.c.', origin=None)
         s = n[:]
-        self.failUnless(s == ('a', 'b', 'c', ''))
+        self.failUnless(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.failUnless(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.failUnless(s == (b'c', b''))
 
     def testEmptyLabel1(self):
         def bad():
@@ -329,13 +330,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.failUnless(d == b'\x03foo\x03bar\x00')
 
     def testDigestable2(self):
         n1 = dns.name.from_text('FOO.bar')
@@ -346,13 +347,13 @@ class NameTestCase(unittest.TestCase):
 
     def testDigestable3(self):
         d = dns.name.root.to_digestable()
-        self.failUnless(d == '\x00')
+        self.failUnless(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.failUnless(d == b'\x03foo\x03bar\x00')
+
     def testBadDigestable(self):
         def bad():
             n = dns.name.from_text('FOO.bar', None)
@@ -361,56 +362,56 @@ class NameTestCase(unittest.TestCase):
 
     def testToWire1(self):
         n = dns.name.from_text('FOO.bar')
-        f = cStringIO.StringIO()
+        f = io.BytesIO()
         compress = {}
         n.to_wire(f, compress)
-        self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00')
+        self.failUnless(f.getvalue() == b'\x03FOO\x03bar\x00')
 
     def testToWire2(self):
         n = dns.name.from_text('FOO.bar')
-        f = cStringIO.StringIO()
+        f = io.BytesIO()
         compress = {}
         n.to_wire(f, compress)
         n.to_wire(f, compress)
-        self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00')
+        self.failUnless(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 = io.BytesIO()
         compress = {}
         n1.to_wire(f, compress)
         n2.to_wire(f, compress)
-        self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\xc0\x00')
+        self.failUnless(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 = io.BytesIO()
         compress = {}
         n1.to_wire(f, compress)
         n2.to_wire(f, compress)
-        self.failUnless(f.getvalue() == '\x03FOO\x03bar\x00\x01\x61\xc0\x00')
+        self.failUnless(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 = io.BytesIO()
         compress = {}
         n1.to_wire(f, compress)
         n2.to_wire(f, None)
         self.failUnless(f.getvalue() == \
-                        '\x03FOO\x03bar\x00\x01\x61\x03foo\x03bar\x00')
+                        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.failUnless(v == b'\x03FOO\x03bar\x00')
 
     def testBadToWire(self):
         def bad():
             n = dns.name.from_text('FOO.bar', None)
-            f = cStringIO.StringIO()
+            f = io.BytesIO()
             compress = {}
             n.to_wire(f, compress)
         self.failUnlessRaises(dns.name.NeedAbsoluteNameOrOrigin, bad)
@@ -540,7 +541,7 @@ class NameTestCase(unittest.TestCase):
         self.failUnless(n.choose_relativity(o, False) == e)
 
     def testFromWire1(self):
-        w = '\x03foo\x00\xc0\x00'
+        w = b'\x03foo\x00\xc0\x00'
         (n1, cused1) = dns.name.from_wire(w, 0)
         (n2, cused2) = dns.name.from_wire(w, cused1)
         en1 = dns.name.from_text('foo.')
@@ -550,8 +551,8 @@ class NameTestCase(unittest.TestCase):
         self.failUnless(n1 == en1 and cused1 == ecused1 and \
                         n2 == en2 and cused2 == ecused2)
 
-    def testFromWire1(self):
-        w = '\x03foo\x00\x01a\xc0\x00\x01b\xc0\x05'
+    def testFromWire2(self):
+        w = b'\x03foo\x00\x01a\xc0\x00\x01b\xc0\x05'
         current = 0
         (n1, cused1) = dns.name.from_wire(w, current)
         current += cused1
@@ -570,25 +571,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)
 
@@ -615,39 +616,39 @@ class NameTestCase(unittest.TestCase):
         self.failUnlessRaises(dns.name.NoParent, bad)
 
     def testFromUnicode1(self):
-        n = dns.name.from_text(u'foo.bar')
-        self.failUnless(n.labels == ('foo', 'bar', ''))
+        n = dns.name.from_text('foo.bar')
+        self.failUnless(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', ''))
+        n = dns.name.from_text('foo\u1234bar.bar')
+        self.failUnless(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', ''))
+        n = dns.name.from_text('foo\u3002bar')
+        self.failUnless(n.labels == (b'foo', b'bar', b''))
 
     def testFromUnicodeAlternateDot2(self):
-        n = dns.name.from_text(u'foo\uff0ebar')
-        self.failUnless(n.labels == ('foo', 'bar', ''))
+        n = dns.name.from_text('foo\uff0ebar')
+        self.failUnless(n.labels == (b'foo', b'bar', b''))
 
     def testFromUnicodeAlternateDot3(self):
-        n = dns.name.from_text(u'foo\uff61bar')
-        self.failUnless(n.labels == ('foo', 'bar', ''))
+        n = dns.name.from_text('foo\uff61bar')
+        self.failUnless(n.labels == (b'foo', b'bar', b''))
 
     def testToUnicode1(self):
-        n = dns.name.from_text(u'foo.bar')
+        n = dns.name.from_text('foo.bar')
         s = n.to_unicode()
-        self.failUnless(s == u'foo.bar.')
+        self.failUnless(s == 'foo.bar.')
 
     def testToUnicode2(self):
-        n = dns.name.from_text(u'foo\u1234bar.bar')
+        n = dns.name.from_text('foo\u1234bar.bar')
         s = n.to_unicode()
-        self.failUnless(s == u'foo\u1234bar.bar.')
+        self.failUnless(s == 'foo\u1234bar.bar.')
 
     def testToUnicode3(self):
         n = dns.name.from_text('foo.bar')
         s = n.to_unicode()
-        self.failUnless(s == u'foo.bar.')
+        self.failUnless(s == 'foo.bar.')
 
     def testReverseIPv4(self):
         e = dns.name.from_text('1.0.0.127.in-addr.arpa.')
index 77befd26e3a8c1a84eea0cc5d9800fa5fafc052f..022cac17ae4b60d93dbd8a3178b50e917d1f220f 100644 (file)
@@ -22,24 +22,24 @@ class NtoAAtoNTestCase(unittest.TestCase):
 
     def test_aton1(self):
         a = dns.ipv6.inet_aton('::')
-        self.failUnless(a == '\x00' * 16)
+        self.failUnless(a == b'\x00' * 16)
 
     def test_aton2(self):
         a = dns.ipv6.inet_aton('::1')
-        self.failUnless(a == '\x00' * 15 + '\x01')
+        self.failUnless(a == b'\x00' * 15 + b'\x01')
 
     def test_aton3(self):
         a = dns.ipv6.inet_aton('::10.0.0.1')
-        self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01')
+        self.failUnless(a == b'\x00' * 12 + b'\x0a\x00\x00\x01')
 
     def test_aton4(self):
         a = dns.ipv6.inet_aton('abcd::dcba')
-        self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba')
+        self.failUnless(a == b'\xab\xcd' + b'\x00' * 12 + b'\xdc\xba')
 
     def test_aton5(self):
         a = dns.ipv6.inet_aton('1:2:3:4:5:6:7:8')
         self.failUnless(a == \
-                        '00010002000300040005000600070008'.decode('hex_codec'))
+                        bytes.fromhex('00010002000300040005000600070008'))
 
     def test_bad_aton1(self):
         def bad():
@@ -58,87 +58,87 @@ class NtoAAtoNTestCase(unittest.TestCase):
 
     def test_aton1(self):
         a = dns.ipv6.inet_aton('::')
-        self.failUnless(a == '\x00' * 16)
+        self.failUnless(a == b'\x00' * 16)
 
     def test_aton2(self):
         a = dns.ipv6.inet_aton('::1')
-        self.failUnless(a == '\x00' * 15 + '\x01')
+        self.failUnless(a == b'\x00' * 15 + b'\x01')
 
     def test_aton3(self):
         a = dns.ipv6.inet_aton('::10.0.0.1')
-        self.failUnless(a == '\x00' * 12 + '\x0a\x00\x00\x01')
+        self.failUnless(a == b'\x00' * 12 + b'\x0a\x00\x00\x01')
 
     def test_aton4(self):
         a = dns.ipv6.inet_aton('abcd::dcba')
-        self.failUnless(a == '\xab\xcd' + '\x00' * 12 + '\xdc\xba')
+        self.failUnless(a == b'\xab\xcd' + b'\x00' * 12 + b'\xdc\xba')
 
     def test_ntoa1(self):
-        b = '00010002000300040005000600070008'.decode('hex_codec')
+        b = bytes.fromhex('00010002000300040005000600070008')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '1:2:3:4:5:6:7:8')
 
     def test_ntoa2(self):
-        b = '\x00' * 16
+        b = b'\x00' * 16
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '::')
 
     def test_ntoa3(self):
-        b = '\x00' * 15 + '\x01'
+        b = b'\x00' * 15 + b'\x01'
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '::1')
 
     def test_ntoa4(self):
-        b = '\x80' + '\x00' * 15
+        b = b'\x80' + b'\x00' * 15
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '8000::')
 
     def test_ntoa5(self):
-        b = '\x01\xcd' + '\x00' * 12 + '\x03\xef'
+        b = b'\x01\xcd' + b'\x00' * 12 + b'\x03\xef'
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '1cd::3ef')
 
     def test_ntoa6(self):
-        b = 'ffff00000000ffff000000000000ffff'.decode('hex_codec')
+        b = bytes.fromhex('ffff00000000ffff000000000000ffff')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == 'ffff:0:0:ffff::ffff')
 
     def test_ntoa7(self):
-        b = '00000000ffff000000000000ffffffff'.decode('hex_codec')
+        b = bytes.fromhex('00000000ffff000000000000ffffffff')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '0:0:ffff::ffff:ffff')
 
     def test_ntoa8(self):
-        b = 'ffff0000ffff00000000ffff00000000'.decode('hex_codec')
+        b = bytes.fromhex('ffff0000ffff00000000ffff00000000')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == 'ffff:0:ffff::ffff:0:0')
 
     def test_ntoa9(self):
-        b = '0000000000000000000000000a000001'.decode('hex_codec')
+        b = bytes.fromhex('0000000000000000000000000a000001')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '::10.0.0.1')
 
     def test_ntoa10(self):
-        b = '0000000000000000000000010a000001'.decode('hex_codec')
+        b = bytes.fromhex('0000000000000000000000010a000001')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '::1:a00:1')
 
     def test_ntoa11(self):
-        b = '00000000000000000000ffff0a000001'.decode('hex_codec')
+        b = bytes.fromhex('00000000000000000000ffff0a000001')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '::ffff:10.0.0.1')
 
     def test_ntoa12(self):
-        b = '000000000000000000000000ffffffff'.decode('hex_codec')
+        b = bytes.fromhex('000000000000000000000000ffffffff')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '::255.255.255.255')
 
     def test_ntoa13(self):
-        b = '00000000000000000000ffffffffffff'.decode('hex_codec')
+        b = bytes.fromhex('00000000000000000000ffffffffffff')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '::ffff:255.255.255.255')
 
     def test_ntoa14(self):
-        b = '0000000000000000000000000001ffff'.decode('hex_codec')
+        b = bytes.fromhex('0000000000000000000000000001ffff')
         t = dns.ipv6.inet_ntoa(b)
         self.failUnless(t == '::0.1.255.255')
 
@@ -149,7 +149,7 @@ class NtoAAtoNTestCase(unittest.TestCase):
 
     def test_bad_ntoa2(self):
         def bad():
-            a = dns.ipv6.inet_ntoa('\x00' * 17)
+            a = dns.ipv6.inet_ntoa(b'\x00' * 17)
         self.failUnlessRaises(ValueError, bad)
 
 if __name__ == '__main__':
index 4cacbdc79d95e747448dcb08def95bca3edf54d1..f29fa28c81b0ebbebc881279073fdb7de0dbe2c2 100644 (file)
@@ -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
+import io
 import sys
 import time
 import unittest
@@ -50,7 +50,7 @@ class ResolverTestCase(unittest.TestCase):
 
     if sys.platform != 'win32':
         def testRead(self):
-            f = cStringIO.StringIO(resolv_conf)
+            f = io.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 5f7b31f23fa581e9028f5347483e459be0c9c170..e7254547202534461a3c9cbb07c7adf327d27eb9 100644 (file)
@@ -34,7 +34,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 = bytes.fromhex(goodhex.replace(' ', ''))
 
 update_text="""id 1
 opcode UPDATE
index 075be0a48a35d3ba5c9c28cb1ac230028c39dbe4..c34164aa7cc1c160bb5edc948a559ecdfcaf99e9 100644 (file)
@@ -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
+import io
 import filecmp
 import os
 import unittest
@@ -123,23 +123,22 @@ class ZoneTestCase(unittest.TestCase):
 
     def testFromText(self):
         z = dns.zone.from_text(example_text, 'example.', relativize=True)
-        f = cStringIO.StringIO()
-        names = z.nodes.keys()
-        names.sort()
+        f = io.StringIO()
+        names = sorted(z.nodes.keys())
         for n in names:
-            print >> f, z[n].to_text(n)
+            print(z[n].to_text(n), file=f)
         self.failUnless(f.getvalue() == example_text_output)
-            
+
     def testTorture1(self):
         #
         # Read a zone containing all our supported RR types, and
         # 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 = io.BytesIO()
         o = dns.name.from_text('example.')
         z = dns.zone.from_file('example', o)
-        for (name, node) in z.iteritems():
+        for (name, node) in z.items():
             for rds in node:
                 for rd in rds:
                     f.seek(0)
@@ -290,15 +289,13 @@ class ZoneTestCase(unittest.TestCase):
 
     def testIterateRdatasets(self):
         z = dns.zone.from_text(example_text, 'example.', relativize=True)
-        ns = [n for n, r in z.iterate_rdatasets('A')]
-        ns.sort()
+        ns = sorted([n for n, r in z.iterate_rdatasets('A')])
         self.failUnless(ns == [dns.name.from_text('ns1', None),
                                dns.name.from_text('ns2', None)])
 
     def testIterateAllRdatasets(self):
         z = dns.zone.from_text(example_text, 'example.', relativize=True)
-        ns = [n for n, r in z.iterate_rdatasets()]
-        ns.sort()
+        ns = sorted([n for n, r in z.iterate_rdatasets()])
         self.failUnless(ns == [dns.name.from_text('@', None),
                                dns.name.from_text('@', None),
                                dns.name.from_text('bar.foo', None),
@@ -307,8 +304,7 @@ class ZoneTestCase(unittest.TestCase):
 
     def testIterateRdatas(self):
         z = dns.zone.from_text(example_text, 'example.', relativize=True)
-        l = list(z.iterate_rdatas('A'))
-        l.sort()
+        l = sorted(z.iterate_rdatas('A'))
         exl = [(dns.name.from_text('ns1', None),
                 3600,
                 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A,
@@ -321,8 +317,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 = sorted(z.iterate_rdatas())
         exl = [(dns.name.from_text('@', None),
                 3600,
                 dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS,