diff --git a/pyopencl/_cffi.py b/pyopencl/_cffi.py
index 52179af3915f3a95fe95226a36fc1f2c202b3928..6df057d61251c538b0463b1b7f737bbc1a4d9c96 100644
--- a/pyopencl/_cffi.py
+++ b/pyopencl/_cffi.py
@@ -1,3 +1,4 @@
+from __future__ import absolute_import
 from cffi import FFI
 
 _ffi = FFI()
diff --git a/pyopencl/_pvt_struct.py b/pyopencl/_pvt_struct.py
index b29f31efbb30d546764b0b440cb29600596e9757..f7461e5094f77b1ead29a0ad60f96511d7d41692 100644
--- a/pyopencl/_pvt_struct.py
+++ b/pyopencl/_pvt_struct.py
@@ -1,4 +1,5 @@
 from __future__ import division
+from __future__ import absolute_import
 
 __copyright__ = """
 Copyright (C) 2013 Marko Bencun
diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py
index f7b47b1766b5b0d34e73d605bbdc5469688f9831..1b16495997022e6bd8bb0b7437c3233a55fcd7ad 100644
--- a/pyopencl/cffi_cl.py
+++ b/pyopencl/cffi_cl.py
@@ -1,4 +1,8 @@
 from __future__ import division
+from __future__ import absolute_import
+from six.moves import map
+from six.moves import range
+from six.moves import zip
 
 __copyright__ = """
 Copyright (C) 2013 Marko Bencun
@@ -80,7 +84,7 @@ class _CArray(object):
         return self.ptr[0].__getitem__(key)
 
     def __iter__(self):
-        for i in xrange(self.size[0]):
+        for i in range(self.size[0]):
             yield self[i]
 
 # }}}
@@ -105,7 +109,7 @@ def _generic_info_to_python(info):
             }[info.opaque_class]
 
         if type_.endswith(']'):
-            ret = map(klass._create, value)
+            ret = list(map(klass._create, value))
             _lib.free_pointer(info.value)
             return ret
         else:
@@ -113,7 +117,7 @@ def _generic_info_to_python(info):
     if type_ == 'char*':
         ret = _ffi_pystr(value)
     elif type_.startswith('char*['):
-        ret = map(_ffi_pystr, value)
+        ret = list(map(_ffi_pystr, value))
         _lib.free_pointer_array(info.value, len(value))
     elif type_.endswith(']'):
         if type_.startswith('char['):
@@ -493,7 +497,7 @@ class Platform(_Common):
         _handle_error(_lib.platform__get_devices(
             self.ptr, devices.ptr, devices.size, device_type))
         return [Device._create(devices.ptr[0][i])
-                for i in xrange(devices.size[0])]
+                for i in range(devices.size[0])]
 
 
 def unload_platform_compiler(plat):
@@ -504,7 +508,7 @@ def get_platforms():
     platforms = _CArray(_ffi.new('clobj_t**'))
     _handle_error(_lib.get_platforms(platforms.ptr, platforms.size))
     return [Platform._create(platforms.ptr[0][i])
-            for i in xrange(platforms.size[0])]
+            for i in range(platforms.size[0])]
 
 # }}}
 
@@ -520,7 +524,7 @@ class Device(_Common):
         _handle_error(_lib.device__create_sub_devices(
             self.ptr, devices.ptr, devices.size, props))
         return [Device._create(devices.ptr[0][i])
-                for i in xrange(devices.size[0])]
+                for i in range(devices.size[0])]
 
     def create_sub_devices_ext(self, props):
         props = (tuple(props) +
@@ -529,7 +533,7 @@ class Device(_Common):
         _handle_error(_lib.device__create_sub_devices_ext(
             self.ptr, devices.ptr, devices.size, props))
         return [Device._create(devices.ptr[0][i])
-                for i in xrange(devices.size[0])]
+                for i in range(devices.size[0])]
 
 # }}}
 
@@ -919,8 +923,8 @@ class _Program(_Common):
 
     def compile(self, options="", devices=None, headers=[]):
         _devs, num_devs = _clobj_list(devices)
-        _prgs, names = zip(*((prg.ptr, _to_cstring(name))
-                             for (name, prg) in headers))
+        _prgs, names = list(zip(*((prg.ptr, _to_cstring(name))
+                             for (name, prg) in headers)))
         _handle_error(_lib.program__compile(
             self.ptr, _to_cstring(options), _devs, num_devs,
             _prgs, names, len(names)))
@@ -947,7 +951,7 @@ class _Program(_Common):
         knls = _CArray(_ffi.new('clobj_t**'))
         _handle_error(_lib.platform__get_devices(
             self.ptr, knls.ptr, knls.size))
-        return [Kernel._create(knls.ptr[0][i]) for i in xrange(knls.size[0])]
+        return [Kernel._create(knls.ptr[0][i]) for i in range(knls.size[0])]
 
 # }}}
 
@@ -1078,7 +1082,7 @@ def enqueue_nd_range_kernel(queue, kernel, global_work_size, local_work_size,
         if g_times_l:
             if not global_size_copied:
                 global_work_size = list(global_work_size)
-            for i in xrange(work_dim):
+            for i in range(work_dim):
                 global_work_size[i] *= local_work_size[i]
 
     if global_work_offset is not None:
diff --git a/pyopencl/mempool.py b/pyopencl/mempool.py
index 8ca837d0a8a87009879797d9c9f9025b2451826c..6ee12257655f273fe22415e517244eeecbdc769b 100644
--- a/pyopencl/mempool.py
+++ b/pyopencl/mempool.py
@@ -1,4 +1,6 @@
 from __future__ import division
+from __future__ import absolute_import
+import six
 
 __copyright__ = """
 Copyright (C) 2014 Andreas Kloeckner
@@ -39,7 +41,7 @@ class AllocatorBase(object):
         while try_count < 2:
             try:
                 return self.allocate(nbytes)
-            except cl.Error, e:
+            except cl.Error as e:
                 if not e.is_out_of_memory():
                     raise
                 try_count += 1
@@ -158,7 +160,7 @@ class MemoryPool(object):
         self.free_held()
 
     def free_held(self):
-        for bin_nr, bin_list in self.bin_nr_to_bin.iteritems():
+        for bin_nr, bin_list in six.iteritems(self.bin_nr_to_bin):
             while bin_list:
                 self.allocator.free(bin_list.pop())
 
@@ -166,7 +168,7 @@ class MemoryPool(object):
     def held_blocks(self):
         return sum(
                 len(bin_list)
-                for bin_list in self.bin_nr_to_bin.itervalues())
+                for bin_list in six.itervalues(self.bin_nr_to_bin))
 
     def allocate(self, size):
         bin_nr = self.bin_number(size)
@@ -238,7 +240,7 @@ class MemoryPool(object):
             self.allocator.free(buf)
 
     def _try_to_free_memory(self):
-        for bin_nr, bin_list in self.bin_nr_to_bin.iteritems():
+        for bin_nr, bin_list in six.iteritems(self.bin_nr_to_bin):
             while bin_list:
                 self.allocator.free(bin_list.pop())
                 self.held_blocks -= 1
diff --git a/setup.py b/setup.py
index 6ce373dde5e08286b3cdee8604a6479a99fd94e2..8aa0f244e9aedff7c185130d88c56fdaa31b8871 100644
--- a/setup.py
+++ b/setup.py
@@ -123,11 +123,6 @@ def main():
     exec(compile(version_file_contents, "pyopencl/version.py", 'exec'), ver_dic)
 
     SEPARATOR = "-"*75
-    try:
-        from distutils.command.build_py import build_py_2to3 as build_py
-    except ImportError:
-        # 2.x
-        from distutils.command.build_py import build_py
 
     try:
         import mako  # noqa
@@ -275,8 +270,6 @@ def main():
                              if conf["CL_ENABLE_GL"] else [])
                     },
 
-            # 2to3 invocation
-            cmdclass={'build_py': build_py},
             zip_safe=False)