diff --git a/CHANGES.rst b/CHANGES.rst
index 768d8dc..b9a92f7 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,6 +1,8 @@
 Changelog
 =========
 
+* Drop support of Python 2.x
+
 * Add salt decryption of encrypted attributes
 
 * Fix create CoA packet in client_async
diff --git a/README.rst b/README.rst
index 06a7480..c4460a9 100644
--- a/README.rst
+++ b/README.rst
@@ -24,7 +24,6 @@ them and decoding responses.
 
 Here is an example of doing a authentication request::
 
-    from __future__ import print_function
     from pyrad.client import Client
     from pyrad.dictionary import Dictionary
     import pyrad.packet
diff --git a/docs/source/index.rst b/docs/source/index.rst
index 7b61cb1..a3da64a 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -15,7 +15,6 @@ them and decoding responses.
 
 Here is an example of doing a authentication request::
 
-    from __future__ import print_function
     from pyrad.client import Client
     from pyrad.dictionary import Dictionary
     import pyrad.packet
diff --git a/example/acct.py b/example/acct.py
index c5a09fe..55a7663 100755
--- a/example/acct.py
+++ b/example/acct.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-from __future__ import print_function
 from pyrad.client import Client
 from pyrad.dictionary import Dictionary
 import random
diff --git a/example/auth.py b/example/auth.py
index 367f283..c5487aa 100755
--- a/example/auth.py
+++ b/example/auth.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-from __future__ import print_function
 from pyrad.client import Client
 from pyrad.dictionary import Dictionary
 import socket
diff --git a/example/client-coa.py b/example/client-coa.py
index 30e30b9..27c8306 100755
--- a/example/client-coa.py
+++ b/example/client-coa.py
@@ -3,7 +3,6 @@
 # Copyright 6WIND, 2017
 #
 
-from __future__ import print_function
 from pyrad import dictionary, packet, server
 import sys
 import prctl
diff --git a/example/coa.py b/example/coa.py
index 0d462bf..c3b9909 100755
--- a/example/coa.py
+++ b/example/coa.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-from __future__ import print_function
 from pyrad.client import Client
 from pyrad import dictionary
 from pyrad import packet
diff --git a/example/server.py b/example/server.py
index 748ad36..ad9902d 100755
--- a/example/server.py
+++ b/example/server.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-from __future__ import print_function
 from pyrad import dictionary, packet, server
 import logging
 
diff --git a/example/status.py b/example/status.py
index 62173f0..3683494 100644
--- a/example/status.py
+++ b/example/status.py
@@ -1,5 +1,4 @@
 #!/usr/bin/python
-from __future__ import print_function
 from pyrad.client import Client
 from pyrad.dictionary import Dictionary
 import socket
diff --git a/pyproject.toml b/pyproject.toml
index 3505042..ec0dc47 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -17,10 +17,13 @@ classifiers = [
     "Development Status :: 6 - Mature",
     "Intended Audience :: Developers",
     "License :: OSI Approved :: BSD License",
-    "Programming Language :: Python :: 2.7",
     "Programming Language :: Python :: 3.6",
     "Programming Language :: Python :: 3.7",
     "Programming Language :: Python :: 3.8",
+    "Programming Language :: Python :: 3.9",
+    "Programming Language :: Python :: 3.10",
+    "Programming Language :: Python :: 3.11",
+    "Programming Language :: Python :: 3.12",
     "Topic :: Software Development :: Libraries :: Python Modules",
     "Topic :: System :: Systems Administration :: Authentication/Directory",
 ]
@@ -32,9 +35,7 @@ include = [
 repository = "https://github.com/pyradius/pyrad"
 
 [tool.poetry.dependencies]
-python = "^2.7 || ^3.6"
-six = "^1.15.0"
-netaddr = "^0.8"
+python = "^3.6"
 
 [tool.poetry.dev-dependencies]
 nose = "^0.10.0b1"
diff --git a/pyrad/client.py b/pyrad/client.py
index 6964963..6fde96b 100644
--- a/pyrad/client.py
+++ b/pyrad/client.py
@@ -8,7 +8,6 @@
 import select
 import socket
 import time
-import six
 import struct
 from pyrad import host
 from pyrad import packet
@@ -34,7 +33,7 @@ class Client(host.Host):
     :type timeout: float
     """
     def __init__(self, server, authport=1812, acctport=1813,
-            coaport=3799, secret=six.b(''), dict=None, retries=3, timeout=5):
+            coaport=3799, secret=b'', dict=None, retries=3, timeout=5):
 
         """Constructor.
 
diff --git a/pyrad/client_async.py b/pyrad/client_async.py
index e9d5df3..2eec5a5 100644
--- a/pyrad/client_async.py
+++ b/pyrad/client_async.py
@@ -6,7 +6,6 @@
 
 from datetime import datetime
 import asyncio
-import six
 import logging
 import random
 
@@ -175,7 +174,7 @@ class ClientAsync:
     """
     # noinspection PyShadowingBuiltins
     def __init__(self, server, auth_port=1812, acct_port=1813,
-                 coa_port=3799, secret=six.b(''), dict=None,
+                 coa_port=3799, secret=b'', dict=None,
                  loop=None, retries=3, timeout=30,
                  logger_name='pyrad'):
 
diff --git a/pyrad/dictfile.py b/pyrad/dictfile.py
index 3a0a67e..11dee7c 100644
--- a/pyrad/dictfile.py
+++ b/pyrad/dictfile.py
@@ -9,7 +9,6 @@
 """
 
 import os
-import six
 
 
 class _Node(object):
@@ -54,10 +53,8 @@ def __init__(self, fil):
         self.__ReadNode(fil)
 
     def __ReadNode(self, fil):
-        node = None
         parentdir = self.__CurDir()
-        if isinstance(fil, six.string_types):
-            fname = None
+        if isinstance(fil, str):
             if os.path.isabs(fil):
                 fname = fil
             else:
diff --git a/pyrad/packet.py b/pyrad/packet.py
index 821c02d..f4c1e3e 100644
--- a/pyrad/packet.py
+++ b/pyrad/packet.py
@@ -27,7 +27,6 @@
     # BBB for python 2.4
     import md5
     md5_constructor = md5.new
-import six
 from pyrad import tools
 
 # Packet codes
@@ -70,7 +69,7 @@ class Packet(OrderedDict):
     :obj:`AuthPacket` or :obj:`AcctPacket` classes.
     """
 
-    def __init__(self, code=0, id=None, secret=six.b(''), authenticator=None,
+    def __init__(self, code=0, id=None, secret=b'', authenticator=None,
                  **attributes):
         """Constructor
 
@@ -91,11 +90,11 @@ def __init__(self, code=0, id=None, secret=six.b(''), authenticator=None,
             self.id = id
         else:
             self.id = CreateID()
-        if not isinstance(secret, six.binary_type):
+        if not isinstance(secret, bytes):
             raise TypeError('secret must be a binary string')
         self.secret = secret
         if authenticator is not None and \
-                not isinstance(authenticator, six.binary_type):
+                not isinstance(authenticator, bytes):
             raise TypeError('authenticator must be a binary string')
         self.authenticator = authenticator
         self.message_authenticator = None
@@ -124,7 +123,7 @@ def add_message_authenticator(self):
 
         self.message_authenticator = True
         # Maintain a zero octets content for md5 and hmac calculation.
-        self['Message-Authenticator'] = 16 * six.b('\00')
+        self['Message-Authenticator'] = 16 * b'\00'
 
         if self.id is None:
             self.id = self.CreateID()
@@ -141,7 +140,7 @@ def _refresh_message_authenticator(self):
         hmac_constructor = hmac_new(self.secret)
 
         # Maintain a zero octets content for md5 and hmac calculation.
-        self['Message-Authenticator'] = 16 * six.b('\00')
+        self['Message-Authenticator'] = 16 * b'\00'
         attr = self._PktEncodeAttributes()
 
         header = struct.pack('!BBH', self.code, self.id,
@@ -150,7 +149,7 @@ def _refresh_message_authenticator(self):
         hmac_constructor.update(header[0:4])
         if self.code in (AccountingRequest, DisconnectRequest,
                          CoARequest, AccountingResponse):
-            hmac_constructor.update(16 * six.b('\00'))
+            hmac_constructor.update(16 * b'\00')
         else:
             # NOTE: self.authenticator on reply packet is initialized
             #       with request authenticator by design.
@@ -197,9 +196,9 @@ def verify_message_authenticator(self, secret=None,
         # attributes exactly as sent.
         if self.raw_packet:
             attr = self.raw_packet[20:]
-            attr = attr.replace(prev_ma[0], 16 * six.b('\00'))
+            attr = attr.replace(prev_ma[0], 16 * b'\00')
         else:
-            self['Message-Authenticator'] = 16 * six.b('\00')
+            self['Message-Authenticator'] = 16 * b'\00'
             attr = self._PktEncodeAttributes()
 
         header = struct.pack('!BBH', self.code, self.id,
@@ -211,7 +210,7 @@ def verify_message_authenticator(self, secret=None,
                          CoARequest, AccountingResponse):
             if original_code is None or original_code != StatusServer:
                 # TODO: Handle Status-Server response correctly.
-                hmac_constructor.update(16 * six.b('\00'))
+                hmac_constructor.update(16 * b'\00')
         elif self.code in (AccessAccept, AccessChallenge,
                            AccessReject):
             if original_authenticator is None:
@@ -329,7 +328,7 @@ def get(self, key, failobj=None):
         return res
 
     def __getitem__(self, key):
-        if not isinstance(key, six.string_types):
+        if not isinstance(key, str):
             return OrderedDict.__getitem__(self, key)
 
         values = OrderedDict.__getitem__(self, self._EncodeKey(key))
@@ -360,7 +359,7 @@ def __delitem__(self, key):
         OrderedDict.__delitem__(self, self._EncodeKey(key))
 
     def __setitem__(self, key, item):
-        if isinstance(key, six.string_types):
+        if isinstance(key, str):
             (key, item) = self._EncodeKeyValues(key, item)
             OrderedDict.__setitem__(self, key, item)
         else:
@@ -379,14 +378,10 @@ def CreateAuthenticator():
         :return: valid packet authenticator
         :rtype: binary string
         """
-
-        data = []
-        for _ in range(16):
-            data.append(random_generator.randrange(0, 256))
-        if six.PY3:
-            return bytes(data)
-        else:
-            return ''.join(chr(b) for b in data)
+        return bytes(
+            random_generator.randrange(0, 256)
+            for _ in range(16)
+        )
 
     def CreateID(self):
         """Create a packet ID.  All RADIUS requests have a ID which is used to
@@ -455,11 +450,11 @@ def _PktEncodeAttribute(self, key, value):
 
     def _PktEncodeTlv(self, tlv_key, tlv_value):
         tlv_attr = self.dict.attributes[self._DecodeKey(tlv_key)]
-        curr_avp = six.b('')
+        curr_avp = b''
         avps = []
         max_sub_attribute_len = max(map(lambda item: len(item[1]), tlv_value.items()))
         for i in range(max_sub_attribute_len):
-            sub_attr_encoding = six.b('')
+            sub_attr_encoding = b''
             for (code, datalst) in tlv_value.items():
                 if i < len(datalst):
                     sub_attr_encoding += self._PktEncodeAttribute(code, datalst[i])
@@ -475,7 +470,7 @@ def _PktEncodeTlv(self, tlv_key, tlv_value):
             value = struct.pack('!BB', tlv_attr.code, (len(avp) + 2)) + avp
             tlv_avps.append(value)
         if tlv_attr.vendor:
-            vendor_avps = six.b('')
+            vendor_avps = b''
             for avp in tlv_avps:
                 vendor_avps += struct.pack(
                     '!BBL', 26, (len(avp) + 6),
@@ -486,7 +481,7 @@ def _PktEncodeTlv(self, tlv_key, tlv_value):
             return b''.join(tlv_avps)
 
     def _PktEncodeAttributes(self):
-        result = six.b('')
+        result = b''
         for (code, datalst) in self.items():
             attribute = self.dict.attributes.get(self._DecodeKey(code))
             if attribute and attribute.type == 'tlv':
@@ -585,12 +580,8 @@ def _salt_en_decrypt(self, data, salt):
         last = self.authenticator + salt
         while data:
             hash = md5_constructor(self.secret + last).digest()
-            if six.PY3:
-                for i in range(16):
-                    result += bytes((hash[i] ^ data[i],))
-            else:
-                for i in range(16):
-                    result += chr(ord(hash[i]) ^ ord(data[i]))
+            for i in range(16):
+                result += bytes((hash[i] ^ data[i],))
 
             last = result[-16:]
             data = data[16:]
@@ -606,21 +597,16 @@ def SaltCrypt(self, value):
         :rtype:          binary string
         """
 
-        if isinstance(value, six.text_type):
+        if isinstance(value, str):
             value = value.encode('utf-8')
 
         if self.authenticator is None:
             # self.authenticator = self.CreateAuthenticator()
-            self.authenticator = 16 * six.b('\x00')
+            self.authenticator = 16 * b'\x00'
 
         #create salt
         random_value = 32768 + random_generator.randrange(0, 32767)
-        if six.PY3:
-            salt_raw = struct.pack('!H', random_value )
-            salt = chr(salt_raw[0]) + chr(salt_raw[1])
-        else:
-            salt = struct.pack('!H', random_value )
-            salt = chr(ord(salt[0]) | 1 << 7)+salt[1]
+        salt_raw = struct.pack('!H', random_value)
 
         #length prefixing
         length = struct.pack("B", len(value))
@@ -628,9 +614,9 @@ def SaltCrypt(self, value):
 
         #zero padding
         if len(value) % 16 != 0:
-            value += six.b('\x00') * (16 - (len(value) % 16))
+            value += b'\x00' * (16 - (len(value) % 16))
 
-        return six.b(salt) + self._salt_en_decrypt(value, six.b(salt))
+        return salt_raw + self._salt_en_decrypt(value, salt_raw)
 
     def SaltDecrypt(self, value):
         """ SaltDecrypt
@@ -654,7 +640,7 @@ def SaltDecrypt(self, value):
 
 
 class AuthPacket(Packet):
-    def __init__(self, code=AccessRequest, id=None, secret=six.b(''),
+    def __init__(self, code=AccessRequest, id=None, secret=b'',
             authenticator=None, auth_type='pap', **attributes):
         """Constructor
 
@@ -734,21 +720,16 @@ def PwDecrypt(self, password):
         :rtype:          unicode string
         """
         buf = password
-        pw = six.b('')
+        pw = b''
 
         last = self.authenticator
         while buf:
             hash = md5_constructor(self.secret + last).digest()
-            if six.PY3:
-                for i in range(16):
-                    pw += bytes((hash[i] ^ buf[i],))
-            else:
-                for i in range(16):
-                    pw += chr(ord(hash[i]) ^ ord(buf[i]))
-
+            for i in range(16):
+                pw += bytes((hash[i] ^ buf[i],))
             (last, buf) = (buf[:16], buf[16:])
 
-        while pw.endswith(six.b('\x00')):
+        while pw.endswith(b'\x00'):
             pw = pw[:-1]
 
         return pw.decode('utf-8')
@@ -770,25 +751,20 @@ def PwCrypt(self, password):
         if self.authenticator is None:
             self.authenticator = self.CreateAuthenticator()
 
-        if isinstance(password, six.text_type):
+        if isinstance(password, str):
             password = password.encode('utf-8')
 
         buf = password
         if len(password) % 16 != 0:
-            buf += six.b('\x00') * (16 - (len(password) % 16))
+            buf += b'\x00' * (16 - (len(password) % 16))
 
-        result = six.b('')
+        result = b''
 
         last = self.authenticator
         while buf:
             hash = md5_constructor(self.secret + last).digest()
-            if six.PY3:
-                for i in range(16):
-                    result += bytes((hash[i] ^ buf[i],))
-            else:
-                for i in range(16):
-                    result += chr(ord(hash[i]) ^ ord(buf[i]))
-
+            for i in range(16):
+                result += bytes((hash[i] ^ buf[i],))
             last = result[-16:]
             buf = buf[16:]
 
@@ -806,16 +782,14 @@ def VerifyChapPasswd(self, userpwd):
         if not self.authenticator:
             self.authenticator = self.CreateAuthenticator()
 
-        if isinstance(userpwd, six.text_type):
+        if isinstance(userpwd, str):
             userpwd = userpwd.strip().encode('utf-8')
 
         chap_password = tools.DecodeOctets(self.get(3)[0])
         if len(chap_password) != 17:
             return False
 
-        chapid = chap_password[0]
-        if six.PY3:
-            chapid = chr(chapid).encode('utf-8')
+        chapid = chap_password[:1]
         password = chap_password[1:]
 
         challenge = self.authenticator
@@ -829,8 +803,8 @@ def VerifyAuthRequest(self):
         :return: True if verification passed else False
         :rtype: boolean
         """
-        assert(self.raw_packet)
-        hash = md5_constructor(self.raw_packet[0:4] + 16 * six.b('\x00') +
+        assert (self.raw_packet)
+        hash = md5_constructor(self.raw_packet[0:4] + 16 * b'\x00' +
                                self.raw_packet[20:] + self.secret).digest()
         return hash == self.authenticator
 
@@ -840,7 +814,7 @@ class AcctPacket(Packet):
     of the generic :obj:`Packet` class for accounting packets.
     """
 
-    def __init__(self, code=AccountingRequest, id=None, secret=six.b(''),
+    def __init__(self, code=AccountingRequest, id=None, secret=b'',
                  authenticator=None, **attributes):
         """Constructor
 
@@ -874,7 +848,7 @@ def VerifyAcctRequest(self):
         """
         assert(self.raw_packet)
 
-        hash = md5_constructor(self.raw_packet[0:4] + 16 * six.b('\x00') +
+        hash = md5_constructor(self.raw_packet[0:4] + 16 * b'\x00' +
                                self.raw_packet[20:] + self.secret).digest()
 
         return hash == self.authenticator
@@ -896,7 +870,7 @@ def RequestPacket(self):
 
         attr = self._PktEncodeAttributes()
         header = struct.pack('!BBH', self.code, self.id, (20 + len(attr)))
-        self.authenticator = md5_constructor(header[0:4] + 16 * six.b('\x00') +
+        self.authenticator = md5_constructor(header[0:4] + 16 * b'\x00' +
                                              attr + self.secret).digest()
 
         ans = header + self.authenticator + attr
@@ -909,7 +883,7 @@ class CoAPacket(Packet):
     of the generic :obj:`Packet` class for CoA packets.
     """
 
-    def __init__(self, code=CoARequest, id=None, secret=six.b(''),
+    def __init__(self, code=CoARequest, id=None, secret=b'',
             authenticator=None, **attributes):
         """Constructor
 
@@ -942,7 +916,7 @@ def VerifyCoARequest(self):
         :rtype: boolean
         """
         assert(self.raw_packet)
-        hash = md5_constructor(self.raw_packet[0:4] + 16 * six.b('\x00') +
+        hash = md5_constructor(self.raw_packet[0:4] + 16 * b'\x00' +
                                self.raw_packet[20:] + self.secret).digest()
         return hash == self.authenticator
 
@@ -961,13 +935,13 @@ def RequestPacket(self):
             self.id = self.CreateID()
 
         header = struct.pack('!BBH', self.code, self.id, (20 + len(attr)))
-        self.authenticator = md5_constructor(header[0:4] + 16 * six.b('\x00') +
+        self.authenticator = md5_constructor(header[0:4] + 16 * b'\x00' +
                                              attr + self.secret).digest()
 
         if self.message_authenticator:
             self._refresh_message_authenticator()
             attr = self._PktEncodeAttributes()
-            self.authenticator = md5_constructor(header[0:4] + 16 * six.b('\x00') +
+            self.authenticator = md5_constructor(header[0:4] + 16 * b'\x00' +
                                                  attr + self.secret).digest()
 
         return header + self.authenticator + attr
diff --git a/pyrad/tools.py b/pyrad/tools.py
index 2bb22c1..0ad3cb9 100644
--- a/pyrad/tools.py
+++ b/pyrad/tools.py
@@ -4,17 +4,16 @@
 from ipaddress import IPv4Address, IPv6Address
 from ipaddress import IPv4Network, IPv6Network
 import struct
-import six
 import binascii
 
 
-def EncodeString(str):
-    if len(str) > 253:
+def EncodeString(origstr):
+    if len(origstr) > 253:
         raise ValueError('Can only encode strings of <= 253 characters')
-    if isinstance(str, six.text_type):
-        return str.encode('utf-8')
+    if isinstance(origstr, str):
+        return origstr.encode('utf-8')
     else:
-        return str
+        return origstr
 
 
 def EncodeOctets(octetstring):
@@ -41,25 +40,25 @@ def EncodeOctets(octetstring):
 
 
 def EncodeAddress(addr):
-    if not isinstance(addr, six.string_types):
+    if not isinstance(addr, str):
         raise TypeError('Address has to be a string')
     return IPv4Address(addr).packed
 
 
 def EncodeIPv6Prefix(addr):
-    if not isinstance(addr, six.string_types):
+    if not isinstance(addr, str):
         raise TypeError('IPv6 Prefix has to be a string')
     ip = IPv6Network(addr)
     return struct.pack('2B', *[0, ip.prefixlen]) + ip.ip.packed
 
 
 def EncodeIPv6Address(addr):
-    if not isinstance(addr, six.string_types):
+    if not isinstance(addr, str):
         raise TypeError('IPv6 Address has to be a string')
     return IPv6Address(addr).packed
 
 
-def EncodeAscendBinary(str):
+def EncodeAscendBinary(orig_str):
     """
     Format: List of type=value pairs separated by spaces.
 
@@ -103,7 +102,7 @@ def EncodeAscendBinary(str):
     }
 
     family = 'ipv4'
-    for t in str.split(' '):
+    for t in orig_str.split(' '):
         key, value = t.split('=')
         if key == 'family' and value == 'ipv6':
             family = 'ipv6'
@@ -158,15 +157,12 @@ def EncodeDate(num):
     return struct.pack('!I', num)
 
 
-def DecodeString(str):
-    try:
-        return str.decode('utf-8')
-    except:
-        return str
+def DecodeString(orig_str):
+    return orig_str.decode('utf-8')
 
 
-def DecodeOctets(str):
-    return str
+def DecodeOctets(orig_bytes):
+    return orig_bytes
 
 
 def DecodeAddress(addr):
@@ -185,8 +181,8 @@ def DecodeIPv6Address(addr):
     return str(IPv6Address(prefix))
 
 
-def DecodeAscendBinary(str):
-    return str
+def DecodeAscendBinary(orig_bytes):
+    return orig_bytes
 
 
 def DecodeInteger(num, format='!I'):
diff --git a/requirements.txt b/requirements.txt
index fddfdeb..e69de29 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,2 +0,0 @@
-six
-netaddr
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 3af8807..d03f3de 100644
--- a/setup.py
+++ b/setup.py
@@ -22,6 +22,8 @@
           'Programming Language :: Python :: 3.8',
           'Programming Language :: Python :: 3.9',
           'Programming Language :: Python :: 3.10',
+          'Programming Language :: Python :: 3.11',
+          'Programming Language :: Python :: 3.12',
           'Topic :: Software Development :: Libraries :: Python Modules',
           'Topic :: System :: Systems Administration :: Authentication/Directory',
       ],
@@ -29,7 +31,6 @@
       keywords=['radius', 'authentication'],
       zip_safe=True,
       include_package_data=True,
-      install_requires=['six'],
       tests_require='nose>=0.10.0b1',
       test_suite='nose.collector',
       )
diff --git a/tests/testClient.py b/tests/testClient.py
index 0effe08..0e07c3a 100644
--- a/tests/testClient.py
+++ b/tests/testClient.py
@@ -1,7 +1,6 @@
 import select
 import socket
 import unittest
-import six
 from .mock import MockPacket
 from .mock import MockPoll
 from .mock import MockSocket
@@ -25,7 +24,7 @@ def testSimpleConstruction(self):
         self.assertTrue(client.server is self.server)
         self.assertEqual(client.authport, 1812)
         self.assertEqual(client.acctport, 1813)
-        self.assertEqual(client.secret, six.b(''))
+        self.assertEqual(client.secret, b'')
         self.assertEqual(client.retries, 3)
         self.assertEqual(client.timeout, 5)
         self.assertTrue(client.dict is None)
@@ -142,14 +141,14 @@ def testDoubleAccountDelay(self):
     def testIgnorePacketError(self):
         self.client.retries = 1
         self.client.timeout = 1
-        self.client._socket = MockSocket(1, 2, six.b("valid reply"))
+        self.client._socket = MockSocket(1, 2, b'valid reply')
         packet = MockPacket(AccountingRequest, verify=True, error=True)
         self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
 
     def testValidReply(self):
         self.client.retries = 1
         self.client.timeout = 1
-        self.client._socket = MockSocket(1, 2, six.b("valid reply"))
+        self.client._socket = MockSocket(1, 2, b'valid reply')
         self.client._poll = MockPoll()
         MockPoll.results = [(1, select.POLLIN)]
         packet = MockPacket(AccountingRequest, verify=True)
@@ -159,7 +158,7 @@ def testValidReply(self):
     def testInvalidReply(self):
         self.client.retries = 1
         self.client.timeout = 1
-        self.client._socket = MockSocket(1, 2, six.b("invalid reply"))
+        self.client._socket = MockSocket(1, 2, b'invalid reply')
         MockPoll.results = [(1, select.POLLIN)]
         packet = MockPacket(AccountingRequest, verify=False)
         self.assertRaises(Timeout, self.client._SendPacket, packet, 432)
@@ -168,18 +167,18 @@ def testInvalidReply(self):
 class OtherTests(unittest.TestCase):
     def setUp(self):
         self.server = object()
-        self.client = Client(self.server, secret=six.b('zeer geheim'))
+        self.client = Client(self.server, secret=b'zeer geheim')
 
     def testCreateAuthPacket(self):
         packet = self.client.CreateAuthPacket(id=15)
         self.assertTrue(isinstance(packet, AuthPacket))
         self.assertTrue(packet.dict is self.client.dict)
         self.assertEqual(packet.id, 15)
-        self.assertEqual(packet.secret, six.b('zeer geheim'))
+        self.assertEqual(packet.secret, b'zeer geheim')
 
     def testCreateAcctPacket(self):
         packet = self.client.CreateAcctPacket(id=15)
         self.assertTrue(isinstance(packet, AcctPacket))
         self.assertTrue(packet.dict is self.client.dict)
         self.assertEqual(packet.id, 15)
-        self.assertEqual(packet.secret, six.b('zeer geheim'))
+        self.assertEqual(packet.secret, b'zeer geheim')
diff --git a/tests/testDictionary.py b/tests/testDictionary.py
index 5b8c39f..0d1fb99 100644
--- a/tests/testDictionary.py
+++ b/tests/testDictionary.py
@@ -1,7 +1,8 @@
 import unittest
 import operator
 import os
-from six import StringIO
+from io import StringIO
+
 from . import home
 from pyrad.dictionary import Attribute
 from pyrad.dictionary import Dictionary
@@ -54,7 +55,6 @@ def testContainment(self):
         self.assertEqual(dict.has_key('test'), True)
 
     def testReadonlyContainer(self):
-        import six
         dict = Dictionary()
         self.assertRaises(TypeError,
                 operator.setitem, dict, 'test', 'dummy')
diff --git a/tests/testPacket.py b/tests/testPacket.py
index cef7583..f7649a0 100644
--- a/tests/testPacket.py
+++ b/tests/testPacket.py
@@ -2,7 +2,6 @@
 import os
 import struct
 import unittest
-import six
 
 from . import home
 
@@ -38,16 +37,16 @@ def testBasicConstructor(self):
         pkt = self.klass()
         self.assertTrue(isinstance(pkt.code, int))
         self.assertTrue(isinstance(pkt.id, int))
-        self.assertTrue(isinstance(pkt.secret, six.binary_type))
+        self.assertTrue(isinstance(pkt.secret, bytes))
 
     def testNamedConstructor(self):
-        pkt = self.klass(code=26, id=38, secret=six.b('secret'),
-                         authenticator=six.b('authenticator'),
+        pkt = self.klass(code=26, id=38, secret=b'secret',
+                         authenticator=b'authenticator',
                          dict='fakedict')
         self.assertEqual(pkt.code, 26)
         self.assertEqual(pkt.id, 38)
-        self.assertEqual(pkt.secret, six.b('secret'))
-        self.assertEqual(pkt.authenticator, six.b('authenticator'))
+        self.assertEqual(pkt.secret, b'secret')
+        self.assertEqual(pkt.authenticator, b'authenticator')
         self.assertEqual(pkt.dict, 'fakedict')
 
     def testConstructWithDictionary(self):
@@ -60,7 +59,7 @@ def testConstructorIgnoredParameters(self):
         self.assertFalse(getattr(pkt, 'fd', None) is marker)
 
     def testSecretMustBeBytestring(self):
-        self.assertRaises(TypeError, self.klass, secret=six.u('secret'))
+        self.assertRaises(TypeError, self.klass, secret='secret')
 
     def testConstructorWithAttributes(self):
         pkt = self.klass(**{'Test-String' :'this works', 'dict' : self.dict})
@@ -83,8 +82,8 @@ def setUp(self):
         self.path = os.path.join(home, 'data')
         self.dict = Dictionary(os.path.join(self.path, 'full'))
         self.packet = packet.Packet(
-            id=0, secret=six.b('secret'),
-            authenticator=six.b('01234567890ABCDEF'), dict=self.dict)
+            id=0, secret=b'secret',
+            authenticator=b'01234567890ABCDEF', dict=self.dict)
 
     def _create_reply_with_duplicate_attributes(self, request):
         """
@@ -101,7 +100,7 @@ def _create_reply_with_duplicate_attributes(self, request):
         attributes += self._get_attribute_bytes('Test-Integer', 1)
         attributes += self._get_attribute_bytes('Test-String', 'test')
         attributes += self._get_attribute_bytes('Message-Authenticator',
-                                                16 * six.b('\00'))
+                                                16 * b'\00')
 
         header = struct.pack('!BBH', packet.AccessAccept,
                              request.id, (20 + len(attributes)))
@@ -110,7 +109,7 @@ def _create_reply_with_duplicate_attributes(self, request):
         hmac_constructor = hmac.new(request.secret, None, md5_constructor)
         hmac_constructor.update(header + request.authenticator + attributes)
         updated_message_authenticator = hmac_constructor.digest()
-        attributes = attributes.replace(six.b('\x00') * 16,
+        attributes = attributes.replace(b'\x00' * 16,
                                         updated_message_authenticator)
 
         # Calculate the response authenticator
@@ -139,28 +138,28 @@ def testCreateReply(self):
     def testAttributeAccess(self):
         self.packet['Test-Integer'] = 10
         self.assertEqual(self.packet['Test-Integer'], [10])
-        self.assertEqual(self.packet[3], [six.b('\x00\x00\x00\x0a')])
+        self.assertEqual(self.packet[3], [b'\x00\x00\x00\x0a'])
 
         self.packet['Test-String'] = 'dummy'
         self.assertEqual(self.packet['Test-String'], ['dummy'])
-        self.assertEqual(self.packet[1], [six.b('dummy')])
+        self.assertEqual(self.packet[1], [b'dummy'])
 
     def testAttributeValueAccess(self):
         self.packet['Test-Integer'] = 'Three'
         self.assertEqual(self.packet['Test-Integer'], ['Three'])
-        self.assertEqual(self.packet[3], [six.b('\x00\x00\x00\x03')])
+        self.assertEqual(self.packet[3], [b'\x00\x00\x00\x03'])
 
     def testVendorAttributeAccess(self):
         self.packet['Simplon-Number'] = 10
         self.assertEqual(self.packet['Simplon-Number'], [10])
-        self.assertEqual(self.packet[(16, 1)], [six.b('\x00\x00\x00\x0a')])
+        self.assertEqual(self.packet[(16, 1)], [b'\x00\x00\x00\x0a'])
 
         self.packet['Simplon-Number'] = 'Four'
         self.assertEqual(self.packet['Simplon-Number'], ['Four'])
-        self.assertEqual(self.packet[(16, 1)], [six.b('\x00\x00\x00\x04')])
+        self.assertEqual(self.packet[(16, 1)], [b'\x00\x00\x00\x04'])
 
     def testRawAttributeAccess(self):
-        marker = [six.b('')]
+        marker = [b'']
         self.packet[1] = marker
         self.assertTrue(self.packet[1] is marker)
         self.packet[(16, 1)] = marker
@@ -205,7 +204,7 @@ def testKeys(self):
 
     def testCreateAuthenticator(self):
         a = packet.Packet.CreateAuthenticator()
-        self.assertTrue(isinstance(a, six.binary_type))
+        self.assertTrue(isinstance(a, bytes))
         self.assertEqual(len(a), 16)
 
         b = packet.Packet.CreateAuthenticator()
@@ -220,8 +219,8 @@ def testGenerateID(self):
     def testReplyPacket(self):
         reply = self.packet.ReplyPacket()
         self.assertEqual(reply,
-                six.b('\x00\x00\x00\x14\xb0\x5e\x4b\xfb\xcc\x1c'
-                      '\x8c\x8e\xc4\x72\xac\xea\x87\x45\x63\xa7'))
+                (b'\x00\x00\x00\x14\xb0\x5e\x4b\xfb\xcc\x1c'
+                 b'\x8c\x8e\xc4\x72\xac\xea\x87\x45\x63\xa7'))
 
     def testVerifyReply(self):
         reply = self.packet.CreateReply()
@@ -231,11 +230,11 @@ def testVerifyReply(self):
         self.assertEqual(self.packet.VerifyReply(reply), False)
         reply.id = self.packet.id
 
-        reply.secret = six.b('different')
+        reply.secret = b'different'
         self.assertEqual(self.packet.VerifyReply(reply), False)
         reply.secret = self.packet.secret
 
-        reply.authenticator = six.b('X') * 16
+        reply.authenticator = b'X' * 16
         self.assertEqual(self.packet.VerifyReply(reply), False)
         reply.authenticator = self.packet.authenticator
 
@@ -254,24 +253,24 @@ def testVerifyMessageAuthenticator(self):
         reply.add_message_authenticator()
         reply._refresh_message_authenticator()
         self.assertTrue(reply.verify_message_authenticator(
-            secret=six.b('secret'),
+            secret=b'secret',
             original_authenticator=self.packet.authenticator,
             original_code=self.packet.code))
 
         self.assertFalse(reply.verify_message_authenticator(
-            secret=six.b('bad_secret'),
+            secret=b'bad_secret',
             original_authenticator=self.packet.authenticator,
             original_code=self.packet.code))
 
         self.assertFalse(reply.verify_message_authenticator(
-            secret=six.b('secret'),
-            original_authenticator=six.b('bad_authenticator'),
+            secret=b'secret',
+            original_authenticator=b'bad_authenticator',
             original_code=self.packet.code))
 
     def testVerifyMessageAuthenticatorDuplicateAttributes(self):
         reply = self._create_reply_with_duplicate_attributes(self.packet)
         self.assertTrue(reply.verify_message_authenticator(
-            secret=six.b('secret'),
+            secret=b'secret',
             original_authenticator=self.packet.authenticator,
             original_code=packet.AccessRequest))
 
@@ -280,105 +279,105 @@ def testPktEncodeAttribute(self):
 
         # Encode a normal attribute
         self.assertEqual(
-                encode(1, six.b('value')),
-                six.b('\x01\x07value'))
+                encode(1, b'value'),
+                b'\x01\x07value')
         # Encode a vendor attribute
         self.assertEqual(
-                encode((1, 2), six.b('value')),
-                six.b('\x1a\x0d\x00\x00\x00\x01\x02\x07value'))
+                encode((1, 2), b'value'),
+                b'\x1a\x0d\x00\x00\x00\x01\x02\x07value')
 
     def testPktEncodeTlvAttribute(self):
         encode = self.packet._PktEncodeTlv
 
         # Encode a normal tlv attribute
         self.assertEqual(
-                encode(4, {1:[six.b('value')], 2:[six.b('\x00\x00\x00\x02')]}),
-                six.b('\x04\x0f\x01\x07value\x02\x06\x00\x00\x00\x02'))
+                encode(4, {1:[b'value'], 2:[b'\x00\x00\x00\x02']}),
+                b'\x04\x0f\x01\x07value\x02\x06\x00\x00\x00\x02')
 
         # Encode a normal tlv attribute with several sub attribute instances
         self.assertEqual(
-                encode(4, {1:[six.b('value'), six.b('other')], 2:[six.b('\x00\x00\x00\x02')]}),
-                six.b('\x04\x16\x01\x07value\x02\x06\x00\x00\x00\x02\x01\x07other'))
+                encode(4, {1:[b'value', b'other'], 2:[b'\x00\x00\x00\x02']}),
+                b'\x04\x16\x01\x07value\x02\x06\x00\x00\x00\x02\x01\x07other')
         # Encode a vendor tlv attribute
         self.assertEqual(
-                encode((16, 3), {1:[six.b('value')], 2:[six.b('\x00\x00\x00\x02')]}),
-                six.b('\x1a\x15\x00\x00\x00\x10\x03\x0f\x01\x07value\x02\x06\x00\x00\x00\x02'))
+                encode((16, 3), {1:[b'value'], 2:[b'\x00\x00\x00\x02']}),
+                b'\x1a\x15\x00\x00\x00\x10\x03\x0f\x01\x07value\x02\x06\x00\x00\x00\x02')
 
     def testPktEncodeLongTlvAttribute(self):
         encode = self.packet._PktEncodeTlv
 
-        long_str = 'a' * 245
+        long_str = b'a' * 245
         # Encode a long tlv attribute - check it is split between AVPs
         self.assertEqual(
-                encode(4, {1:[six.b('value'), six.b(long_str)], 2:[six.b('\x00\x00\x00\x02')]}),
-                six.b('\x04\x0f\x01\x07value\x02\x06\x00\x00\x00\x02\x04\xf9\x01\xf7' + long_str))
+                encode(4, {1:[b'value', long_str], 2:[b'\x00\x00\x00\x02']}),
+                b'\x04\x0f\x01\x07value\x02\x06\x00\x00\x00\x02\x04\xf9\x01\xf7' + long_str)
 
         # Encode a long vendor tlv attribute
-        first_avp = '\x1a\x15\x00\x00\x00\x10\x03\x0f\x01\x07value\x02\x06\x00\x00\x00\x02'
-        second_avp = '\x1a\xff\x00\x00\x00\x10\x03\xf9\x01\xf7' + long_str
+        first_avp = b'\x1a\x15\x00\x00\x00\x10\x03\x0f\x01\x07value\x02\x06\x00\x00\x00\x02'
+        second_avp = b'\x1a\xff\x00\x00\x00\x10\x03\xf9\x01\xf7' + long_str
         self.assertEqual(
-                encode((16, 3), {1:[six.b('value'), six.b(long_str)], 2:[six.b('\x00\x00\x00\x02')]}),
-                six.b(first_avp + second_avp))
+                encode((16, 3), {1:[b'value', long_str], 2:[b'\x00\x00\x00\x02']}),
+                first_avp + second_avp)
 
     def testPktEncodeAttributes(self):
-        self.packet[1] = [six.b('value')]
+        self.packet[1] = [b'value']
         self.assertEqual(self.packet._PktEncodeAttributes(),
-                six.b('\x01\x07value'))
+                b'\x01\x07value')
 
         self.packet.clear()
-        self.packet[(16, 2)] = [six.b('value')]
+        self.packet[(16, 2)] = [b'value']
         self.assertEqual(self.packet._PktEncodeAttributes(),
-                six.b('\x1a\x0d\x00\x00\x00\x10\x02\x07value'))
+                b'\x1a\x0d\x00\x00\x00\x10\x02\x07value')
 
         self.packet.clear()
-        self.packet[1] = [six.b('one'), six.b('two'), six.b('three')]
+        self.packet[1] = [b'one', b'two', b'three']
         self.assertEqual(self.packet._PktEncodeAttributes(),
-                six.b('\x01\x05one\x01\x05two\x01\x07three'))
+                b'\x01\x05one\x01\x05two\x01\x07three')
 
         self.packet.clear()
-        self.packet[1] = [six.b('value')]
-        self.packet[(16, 2)] = [six.b('value')]
+        self.packet[1] = [b'value']
+        self.packet[(16, 2)] = [b'value']
         self.assertEqual(
                 self.packet._PktEncodeAttributes(),
-                six.b('\x01\x07value\x1a\x0d\x00\x00\x00\x10\x02\x07value'))
+                b'\x01\x07value\x1a\x0d\x00\x00\x00\x10\x02\x07value')
 
     def testPktDecodeVendorAttribute(self):
         decode = self.packet._PktDecodeVendorAttribute
 
         # Non-RFC2865 recommended form
-        self.assertEqual(decode(six.b('')), [(26, six.b(''))])
-        self.assertEqual(decode(six.b('12345')), [(26, six.b('12345'))])
+        self.assertEqual(decode(b''), [(26, b'')])
+        self.assertEqual(decode(b'12345'), [(26, b'12345')])
 
         # Almost RFC2865 recommended form: bad length value
         self.assertEqual(
-                decode(six.b('\x00\x00\x00\x01\x02\x06value')),
-                [(26, six.b('\x00\x00\x00\x01\x02\x06value'))])
+                decode(b'\x00\x00\x00\x01\x02\x06value'),
+                [(26, b'\x00\x00\x00\x01\x02\x06value')])
 
         # Proper RFC2865 recommended form
         self.assertEqual(
-                decode(six.b('\x00\x00\x00\x10\x02\x07value')),
-                [((16, 2), six.b('value'))])
+                decode(b'\x00\x00\x00\x10\x02\x07value'),
+                [((16, 2), b'value')])
 
     def testPktDecodeTlvAttribute(self):
         decode = self.packet._PktDecodeTlvAttribute
 
-        decode(4,six.b('\x01\x07value'))
-        self.assertEqual(self.packet[4], {1: [six.b('value')]})
+        decode(4,b'\x01\x07value')
+        self.assertEqual(self.packet[4], {1: [b'value']})
 
         #add another instance of the same sub attribute
-        decode(4,six.b('\x01\x07other'))
-        self.assertEqual(self.packet[4], {1: [six.b('value'), six.b('other')]})
+        decode(4,b'\x01\x07other')
+        self.assertEqual(self.packet[4], {1: [b'value', b'other']})
 
         #add a different sub attribute
-        decode(4,six.b('\x02\x07\x00\x00\x00\x01'))
+        decode(4,b'\x02\x07\x00\x00\x00\x01')
         self.assertEqual(self.packet[4], {
-            1: [six.b('value'), six.b('other')],
-            2: [six.b('\x00\x00\x00\x01')]
+            1: [b'value', b'other'],
+            2: [b'\x00\x00\x00\x01']
         })
 
     def testDecodePacketWithEmptyPacket(self):
         try:
-            self.packet.DecodePacket(six.b(''))
+            self.packet.DecodePacket(b'')
         except packet.PacketError as e:
             self.assertTrue('header is corrupt' in str(e))
         else:
@@ -386,7 +385,7 @@ def testDecodePacketWithEmptyPacket(self):
 
     def testDecodePacketWithInvalidLength(self):
         try:
-            self.packet.DecodePacket(six.b('\x00\x00\x00\x001234567890123456'))
+            self.packet.DecodePacket(b'\x00\x00\x00\x001234567890123456')
         except packet.PacketError as e:
             self.assertTrue('invalid length' in str(e))
         else:
@@ -394,7 +393,7 @@ def testDecodePacketWithInvalidLength(self):
 
     def testDecodePacketWithTooBigPacket(self):
         try:
-            self.packet.DecodePacket(six.b('\x00\x00\x24\x00') + (0x2400 - 4) * six.b('X'))
+            self.packet.DecodePacket(b'\x00\x00\x24\x00' + (0x2400 - 4) * b'X')
         except packet.PacketError as e:
             self.assertTrue('too long' in str(e))
         else:
@@ -403,23 +402,23 @@ def testDecodePacketWithTooBigPacket(self):
     def testDecodePacketWithPartialAttributes(self):
         try:
             self.packet.DecodePacket(
-                    six.b('\x01\x02\x00\x151234567890123456\x00'))
+                    b'\x01\x02\x00\x151234567890123456\x00')
         except packet.PacketError as e:
             self.assertTrue('header is corrupt' in str(e))
         else:
             self.fail()
 
     def testDecodePacketWithoutAttributes(self):
-        self.packet.DecodePacket(six.b('\x01\x02\x00\x141234567890123456'))
+        self.packet.DecodePacket(b'\x01\x02\x00\x141234567890123456')
         self.assertEqual(self.packet.code, 1)
         self.assertEqual(self.packet.id, 2)
-        self.assertEqual(self.packet.authenticator, six.b('1234567890123456'))
+        self.assertEqual(self.packet.authenticator, b'1234567890123456')
         self.assertEqual(self.packet.keys(), [])
 
     def testDecodePacketWithBadAttribute(self):
         try:
             self.packet.DecodePacket(
-                    six.b('\x01\x02\x00\x161234567890123456\x00\x01'))
+                    b'\x01\x02\x00\x161234567890123456\x00\x01')
         except packet.PacketError as e:
             self.assertTrue('too small' in str(e))
         else:
@@ -427,48 +426,48 @@ def testDecodePacketWithBadAttribute(self):
 
     def testDecodePacketWithEmptyAttribute(self):
         self.packet.DecodePacket(
-                six.b('\x01\x02\x00\x161234567890123456\x01\x02'))
-        self.assertEqual(self.packet[1], [six.b('')])
+                b'\x01\x02\x00\x161234567890123456\x01\x02')
+        self.assertEqual(self.packet[1], [b''])
 
     def testDecodePacketWithAttribute(self):
         self.packet.DecodePacket(
-            six.b('\x01\x02\x00\x1b1234567890123456\x01\x07value'))
-        self.assertEqual(self.packet[1], [six.b('value')])
+            b'\x01\x02\x00\x1b1234567890123456\x01\x07value')
+        self.assertEqual(self.packet[1], [b'value'])
 
     def testDecodePacketWithTlvAttribute(self):
         self.packet.DecodePacket(
-            six.b('\x01\x02\x00\x1d1234567890123456\x04\x09\x01\x07value'))
-        self.assertEqual(self.packet[4], {1:[six.b('value')]})
+            b'\x01\x02\x00\x1d1234567890123456\x04\x09\x01\x07value')
+        self.assertEqual(self.packet[4], {1:[b'value']})
 
     def testDecodePacketWithVendorTlvAttribute(self):
         self.packet.DecodePacket(
-            six.b('\x01\x02\x00\x231234567890123456\x1a\x0f\x00\x00\x00\x10\x03\x09\x01\x07value'))
-        self.assertEqual(self.packet[(16,3)], {1:[six.b('value')]})
+            b'\x01\x02\x00\x231234567890123456\x1a\x0f\x00\x00\x00\x10\x03\x09\x01\x07value')
+        self.assertEqual(self.packet[(16,3)], {1:[b'value']})
 
     def testDecodePacketWithTlvAttributeWith2SubAttributes(self):
         self.packet.DecodePacket(
-            six.b('\x01\x02\x00\x231234567890123456\x04\x0f\x01\x07value\x02\x06\x00\x00\x00\x09'))
-        self.assertEqual(self.packet[4], {1:[six.b('value')], 2:[six.b('\x00\x00\x00\x09')]})
+            b'\x01\x02\x00\x231234567890123456\x04\x0f\x01\x07value\x02\x06\x00\x00\x00\x09')
+        self.assertEqual(self.packet[4], {1:[b'value'], 2:[b'\x00\x00\x00\x09']})
 
     def testDecodePacketWithSplitTlvAttribute(self):
         self.packet.DecodePacket(
-            six.b('\x01\x02\x00\x251234567890123456\x04\x09\x01\x07value\x04\x09\x02\x06\x00\x00\x00\x09'))
-        self.assertEqual(self.packet[4], {1:[six.b('value')], 2:[six.b('\x00\x00\x00\x09')]})
+            b'\x01\x02\x00\x251234567890123456\x04\x09\x01\x07value\x04\x09\x02\x06\x00\x00\x00\x09')
+        self.assertEqual(self.packet[4], {1:[b'value'], 2:[b'\x00\x00\x00\x09']})
 
     def testDecodePacketWithMultiValuedAttribute(self):
         self.packet.DecodePacket(
-            six.b('\x01\x02\x00\x1e1234567890123456\x01\x05one\x01\x05two'))
-        self.assertEqual(self.packet[1], [six.b('one'), six.b('two')])
+            b'\x01\x02\x00\x1e1234567890123456\x01\x05one\x01\x05two')
+        self.assertEqual(self.packet[1], [b'one', b'two'])
 
     def testDecodePacketWithTwoAttributes(self):
         self.packet.DecodePacket(
-            six.b('\x01\x02\x00\x1e1234567890123456\x01\x05one\x01\x05two'))
-        self.assertEqual(self.packet[1], [six.b('one'), six.b('two')])
+            b'\x01\x02\x00\x1e1234567890123456\x01\x05one\x01\x05two')
+        self.assertEqual(self.packet[1], [b'one', b'two'])
 
     def testDecodePacketWithVendorAttribute(self):
         self.packet.DecodePacket(
-                six.b('\x01\x02\x00\x1b1234567890123456\x1a\x07value'))
-        self.assertEqual(self.packet[26], [six.b('value')])
+                b'\x01\x02\x00\x1b1234567890123456\x1a\x07value')
+        self.assertEqual(self.packet[26], [b'value'])
 
     def testEncodeKeyValues(self):
         self.assertEqual(self.packet._EncodeKeyValues(1, '1234'), (1, '1234'))
@@ -496,8 +495,8 @@ class AuthPacketTests(unittest.TestCase):
     def setUp(self):
         self.path = os.path.join(home, 'data')
         self.dict = Dictionary(os.path.join(self.path, 'full'))
-        self.packet = packet.AuthPacket(id=0, secret=six.b('secret'),
-                authenticator=six.b('01234567890ABCDEF'), dict=self.dict)
+        self.packet = packet.AuthPacket(id=0, secret=b'secret',
+                authenticator=b'01234567890ABCDEF', dict=self.dict)
 
     def testCreateReply(self):
         reply = self.packet.CreateReply(**{'Test-Integer' : 10})
@@ -509,7 +508,7 @@ def testCreateReply(self):
 
     def testRequestPacket(self):
         self.assertEqual(self.packet.RequestPacket(),
-                six.b('\x01\x00\x00\x1401234567890ABCDE'))
+                b'\x01\x00\x00\x1401234567890ABCDE')
 
     def testRequestPacketCreatesAuthenticator(self):
         self.packet.authenticator = None
@@ -522,33 +521,33 @@ def testRequestPacketCreatesID(self):
         self.assertTrue(self.packet.id is not None)
 
     def testPwCryptEmptyPassword(self):
-        self.assertEqual(self.packet.PwCrypt(''), six.b(''))
+        self.assertEqual(self.packet.PwCrypt(''), b'')
 
     def testPwCryptPassword(self):
         self.assertEqual(self.packet.PwCrypt('Simplon'),
-                six.b('\xd3U;\xb23\r\x11\xba\x07\xe3\xa8*\xa8x\x14\x01'))
+                b'\xd3U;\xb23\r\x11\xba\x07\xe3\xa8*\xa8x\x14\x01')
 
     def testPwCryptSetsAuthenticator(self):
         self.packet.authenticator = None
-        self.packet.PwCrypt(six.u(''))
+        self.packet.PwCrypt('')
         self.assertTrue(self.packet.authenticator is not None)
 
     def testPwDecryptEmptyPassword(self):
-        self.assertEqual(self.packet.PwDecrypt(six.b('')), six.u(''))
+        self.assertEqual(self.packet.PwDecrypt(b''), '')
 
     def testPwDecryptPassword(self):
         self.assertEqual(self.packet.PwDecrypt(
-                six.b('\xd3U;\xb23\r\x11\xba\x07\xe3\xa8*\xa8x\x14\x01')),
-                six.u('Simplon'))
+                b'\xd3U;\xb23\r\x11\xba\x07\xe3\xa8*\xa8x\x14\x01'),
+                'Simplon')
 
 
 class AuthPacketChapTests(unittest.TestCase):
     def setUp(self):
         self.path = os.path.join(home, 'data')
         self.dict = Dictionary(os.path.join(self.path, 'chap'))
-        # self.packet = packet.Packet(id=0, secret=six.b('secret'),
+        # self.packet = packet.Packet(id=0, secret=b'secret',
         #                             dict=self.dict)
-        self.client = Client(server='localhost', secret=six.b('secret'),
+        self.client = Client(server='localhost', secret=b'secret',
                              dict=self.dict)
 
     def testVerifyChapPasswd(self):
@@ -576,8 +575,8 @@ def testConstructorDefaults(self):
         self.assertEqual(pkt.code, packet.AccountingRequest)
 
     def testConstructorRawPacket(self):
-        raw = six.b('\x00\x00\x00\x14\xb0\x5e\x4b\xfb\xcc\x1c' \
-                    '\x8c\x8e\xc4\x72\xac\xea\x87\x45\x63\xa7')
+        raw = (b'\x00\x00\x00\x14\xb0\x5e\x4b\xfb\xcc\x1c'
+               b'\x8c\x8e\xc4\x72\xac\xea\x87\x45\x63\xa7')
         pkt = self.klass(packet=raw)
         self.assertEqual(pkt.raw_packet, raw)
 
@@ -586,8 +585,8 @@ class AcctPacketTests(unittest.TestCase):
     def setUp(self):
         self.path = os.path.join(home, 'data')
         self.dict = Dictionary(os.path.join(self.path, 'full'))
-        self.packet = packet.AcctPacket(id=0, secret=six.b('secret'),
-                authenticator=six.b('01234567890ABCDEF'), dict=self.dict)
+        self.packet = packet.AcctPacket(id=0, secret=b'secret',
+                authenticator=b'01234567890ABCDEF', dict=self.dict)
 
     def testCreateReply(self):
         reply = self.packet.CreateReply(**{'Test-Integer' : 10})
@@ -599,19 +598,19 @@ def testCreateReply(self):
 
     def testVerifyAcctRequest(self):
         rawpacket = self.packet.RequestPacket()
-        pkt = packet.AcctPacket(secret=six.b('secret'), packet=rawpacket)
+        pkt = packet.AcctPacket(secret=b'secret', packet=rawpacket)
         self.assertEqual(pkt.VerifyAcctRequest(), True)
 
-        pkt.secret = six.b('different')
+        pkt.secret = b'different'
         self.assertEqual(pkt.VerifyAcctRequest(), False)
-        pkt.secret = six.b('secret')
+        pkt.secret = b'secret'
 
-        pkt.raw_packet = six.b('X') + pkt.raw_packet[1:]
+        pkt.raw_packet = b'X' + pkt.raw_packet[1:]
         self.assertEqual(pkt.VerifyAcctRequest(), False)
 
     def testRequestPacket(self):
         self.assertEqual(self.packet.RequestPacket(),
-            six.b('\x04\x00\x00\x14\x95\xdf\x90\xccbn\xfb\x15G!\x13\xea\xfa>6\x0f'))
+            b'\x04\x00\x00\x14\x95\xdf\x90\xccbn\xfb\x15G!\x13\xea\xfa>6\x0f')
 
     def testRequestPacketSetsId(self):
         self.packet.id = None
diff --git a/tests/testTools.py b/tests/testTools.py
index 14c3891..f220e7b 100644
--- a/tests/testTools.py
+++ b/tests/testTools.py
@@ -1,9 +1,6 @@
 from ipaddress import AddressValueError
 from pyrad import tools
 import unittest
-import six
-import sys
-
 
 
 class EncodingTests(unittest.TestCase):
@@ -11,7 +8,7 @@ def testStringEncoding(self):
         self.assertRaises(ValueError, tools.EncodeString, 'x' * 254)
         self.assertEqual(
                 tools.EncodeString('1234567890'),
-                six.b('1234567890'))
+                b'1234567890')
 
     def testInvalidStringEncodingRaisesTypeError(self):
         self.assertRaises(TypeError, tools.EncodeString, 1)
@@ -20,27 +17,27 @@ def testAddressEncoding(self):
         self.assertRaises(AddressValueError, tools.EncodeAddress, 'TEST123')
         self.assertEqual(
                 tools.EncodeAddress('192.168.0.255'),
-                six.b('\xc0\xa8\x00\xff'))
+                b'\xc0\xa8\x00\xff')
 
     def testInvalidAddressEncodingRaisesTypeError(self):
         self.assertRaises(TypeError, tools.EncodeAddress, 1)
 
     def testIntegerEncoding(self):
-        self.assertEqual(tools.EncodeInteger(0x01020304), six.b('\x01\x02\x03\x04'))
+        self.assertEqual(tools.EncodeInteger(0x01020304), b'\x01\x02\x03\x04')
 
     def testInteger64Encoding(self):
         self.assertEqual(
-            tools.EncodeInteger64(0xFFFFFFFFFFFFFFFF), six.b('\xff' * 8)
+            tools.EncodeInteger64(0xFFFFFFFFFFFFFFFF), b'\xff' * 8
         )
 
     def testUnsignedIntegerEncoding(self):
-        self.assertEqual(tools.EncodeInteger(0xFFFFFFFF), six.b('\xff\xff\xff\xff'))
+        self.assertEqual(tools.EncodeInteger(0xFFFFFFFF), b'\xff\xff\xff\xff')
 
     def testInvalidIntegerEncodingRaisesTypeError(self):
         self.assertRaises(TypeError, tools.EncodeInteger, 'ONE')
 
     def testDateEncoding(self):
-        self.assertEqual(tools.EncodeDate(0x01020304), six.b('\x01\x02\x03\x04'))
+        self.assertEqual(tools.EncodeDate(0x01020304), b'\x01\x02\x03\x04')
 
     def testInvalidDataEncodingRaisesTypeError(self):
         self.assertRaises(TypeError, tools.EncodeDate, '1')
@@ -48,37 +45,37 @@ def testInvalidDataEncodingRaisesTypeError(self):
     def testEncodeAscendBinary(self):
         self.assertEqual(
             tools.EncodeAscendBinary('family=ipv4 action=discard direction=in dst=10.10.255.254/32'),
-            six.b('\x01\x00\x01\x00\x00\x00\x00\x00\n\n\xff\xfe\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'))
+            b'\x01\x00\x01\x00\x00\x00\x00\x00\n\n\xff\xfe\x00 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 
     def testStringDecoding(self):
         self.assertEqual(
-                tools.DecodeString(six.b('1234567890')),
+                tools.DecodeString(b'1234567890'),
                 '1234567890')
 
     def testAddressDecoding(self):
         self.assertEqual(
-                tools.DecodeAddress(six.b('\xc0\xa8\x00\xff')),
+                tools.DecodeAddress(b'\xc0\xa8\x00\xff'),
                 '192.168.0.255')
 
     def testIntegerDecoding(self):
         self.assertEqual(
-                tools.DecodeInteger(six.b('\x01\x02\x03\x04')),
+                tools.DecodeInteger(b'\x01\x02\x03\x04'),
                 0x01020304)
 
     def testInteger64Decoding(self):
         self.assertEqual(
-            tools.DecodeInteger64(six.b('\xff' * 8)), 0xFFFFFFFFFFFFFFFF
+            tools.DecodeInteger64(b'\xff' * 8), 0xFFFFFFFFFFFFFFFF
         )
 
     def testDateDecoding(self):
         self.assertEqual(
-                tools.DecodeDate(six.b('\x01\x02\x03\x04')),
+                tools.DecodeDate(b'\x01\x02\x03\x04'),
                 0x01020304)
 
     def testOctetsEncoding(self):
-        self.assertEqual(tools.EncodeOctets('0x01020304'), six.b('\x01\x02\x03\x04'))
-        self.assertEqual(tools.EncodeOctets(b'0x01020304'), six.b('\x01\x02\x03\x04'))
-        self.assertEqual(tools.EncodeOctets('16909060'), six.b('\x01\x02\x03\x04'))
+        self.assertEqual(tools.EncodeOctets('0x01020304'), b'\x01\x02\x03\x04')
+        self.assertEqual(tools.EncodeOctets(b'0x01020304'), b'\x01\x02\x03\x04')
+        self.assertEqual(tools.EncodeOctets('16909060'), b'\x01\x02\x03\x04')
         # encodes to 253 bytes
         self.assertEqual(tools.EncodeOctets('0x0102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D'), b'\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r')
         self.assertRaisesRegex(ValueError, 'Can only encode strings of <= 253 characters', tools.EncodeOctets, '0x0102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E0F100102030405060708090A0B0C0D0E')
@@ -91,40 +88,40 @@ def testUnknownTypeDecoding(self):
 
     def testEncodeFunction(self):
         self.assertEqual(
-                tools.EncodeAttr('string', six.u('string')),
-                six.b('string'))
+                tools.EncodeAttr('string', 'string'),
+                b'string')
         self.assertEqual(
-                tools.EncodeAttr('octets', six.b('string')),
-                six.b('string'))
+                tools.EncodeAttr('octets', b'string'),
+                b'string')
         self.assertEqual(
                 tools.EncodeAttr('ipaddr', '192.168.0.255'),
-                six.b('\xc0\xa8\x00\xff'))
+                b'\xc0\xa8\x00\xff')
         self.assertEqual(
                 tools.EncodeAttr('integer', 0x01020304),
-                six.b('\x01\x02\x03\x04'))
+                b'\x01\x02\x03\x04')
         self.assertEqual(
                 tools.EncodeAttr('date', 0x01020304),
-                six.b('\x01\x02\x03\x04'))
+                b'\x01\x02\x03\x04')
         self.assertEqual(
                 tools.EncodeAttr('integer64', 0xFFFFFFFFFFFFFFFF),
-                six.b('\xff'*8))
+                b'\xff'*8)
 
     def testDecodeFunction(self):
         self.assertEqual(
-                tools.DecodeAttr('string', six.b('string')),
-                six.u('string'))
+                tools.DecodeAttr('string', b'string'),
+                'string')
         self.assertEqual(
-                tools.EncodeAttr('octets', six.b('string')),
-                six.b('string'))
+                tools.EncodeAttr('octets', b'string'),
+                b'string')
         self.assertEqual(
-                tools.DecodeAttr('ipaddr', six.b('\xc0\xa8\x00\xff')),
+                tools.DecodeAttr('ipaddr', b'\xc0\xa8\x00\xff'),
                 '192.168.0.255')
         self.assertEqual(
-                tools.DecodeAttr('integer', six.b('\x01\x02\x03\x04')),
+                tools.DecodeAttr('integer', b'\x01\x02\x03\x04'),
                 0x01020304)
         self.assertEqual(
-                tools.DecodeAttr('integer64', six.b('\xff'*8)),
+                tools.DecodeAttr('integer64', b'\xff'*8),
                 0xFFFFFFFFFFFFFFFF)
         self.assertEqual(
-                tools.DecodeAttr('date', six.b('\x01\x02\x03\x04')),
+                tools.DecodeAttr('date', b'\x01\x02\x03\x04'),
                 0x01020304)