--- a/setup.py
+++ b/setup.py
@@ -7,10 +7,6 @@ README = os.path.join(os.path.dirname(__
 long_description = open(README).read().strip() + "\n\n"
 
 extra = {}
-if sys.version_info >= (3, 0):
-    extra.update(
-        use_2to3=True,
-    )
 
 
 setup(name='slimmer',
--- a/slimmer/__init__.py
+++ b/slimmer/__init__.py
@@ -1 +1 @@
-from slimmer import * # slimmer.py has an __all__ variable
\ No newline at end of file
+from .slimmer import * # slimmer.py has an __all__ variable
\ No newline at end of file
--- a/slimmer/js_function_slimmer.py
+++ b/slimmer/js_function_slimmer.py
@@ -91,7 +91,7 @@ def slim_params(code):
         old_functions[old_function] = new_function
         
     # killer regex
-    regex = '|'.join([re.escape(x) for x in old_functions.keys()])
+    regex = '|'.join([re.escape(x) for x in list(old_functions.keys())])
     def replacer(match):
         return old_functions.get(match.group())
     return re.sub(regex, replacer, new_code)
@@ -102,7 +102,7 @@ class NamesGenerator:
         self.i = 0
         self.pool = list('ABCDEFGHIJKLMNOPQRSTUVWXYZ')
         
-    def next(self):
+    def __next__(self):
         try:
             e = self.pool[self.i]
             self.i = self.i + 1
@@ -117,7 +117,7 @@ class NamesGenerator:
             except IndexError:
                 self.i += 1
                 self.j = 0
-                return self.next()
+                return next(self)
         
         return '_%s' % e
 
@@ -130,7 +130,7 @@ def slim_func_names(js):
         if len(func_name) > 2 and count > 1:
             #print func_name, count, 
             #len(re.findall(r'\b%s\b'% re.escape(func_name), js))
-            new_name = new_names_generator.next()
+            new_name = next(new_names_generator)
             if re.findall(r'\b%s\b' % re.escape(new_name), js):
                 #print  "new_name:%r\n\n%s" % (new_name, js)
                 continue
@@ -156,14 +156,14 @@ def test(inputbuffer):
     js1 = inputbuffer.read()
     res = slim(js1)
     t1 = time()
-    print t1-t0
+    print(t1-t0)
     return res
     
 if __name__=='__main__':
     import sys
     argv = sys.argv[1:]
     if argv:
-        print test(open(argv[0]))
+        print(test(open(argv[0])))
     else:
         test(sys.stdin)
 
--- a/slimmer/slimit.py
+++ b/slimmer/slimit.py
@@ -4,8 +4,8 @@
 A command line program wrapper to slimmer
 """
 
-from slimmer import *
-from slimmer import run
+from .slimmer import *
+from .slimmer import run
 import CommandLineApp
 
 class slimit(CommandLineApp.CommandLineApp):
@@ -32,7 +32,7 @@ To save to a particular file other than
     
     def optionHandler_version(self):
         """Prints version and exits"""
-        print __version__
+        print(__version__)
         
         
     speedtest = 0
@@ -60,10 +60,10 @@ To save to a particular file other than
         Run the slimmer
         """
         if syntax is None:
-            print "guess for", repr(filename),
+            print("guess for", repr(filename), end=' ')
             syntax = guessSyntax(filename)
-            print repr(syntax)
-        print syntax
+            print(repr(syntax))
+        print(syntax)
         run(filename, syntax, self.speedtest, self.outputfile, hardcore=self.hardcore)
         
         
--- a/slimmer/slimmer.py
+++ b/slimmer/slimmer.py
@@ -107,9 +107,9 @@ __all__=['acceptableSyntax','guessSyntax
          '__version__']
 
 import re, os, sys, getopt
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 try:
-    from js_function_slimmer import slim as js_function_slimmer
+    from .js_function_slimmer import slim as js_function_slimmer
 except ImportError:
     js_function_slimmer = None
 
@@ -185,7 +185,7 @@ def slimmer(code, syntax=XHTML, hardcore
 try:
     import itertools
     def anyTrue(pred, seq):
-        return True in itertools.imap(pred,seq)
+        return True in map(pred,seq)
 except ImportError:
     def anyTrue(pred, seq):
         for e in seq:
@@ -430,7 +430,7 @@ def uniqify(all):
     u = {}
     for each in all:
         u[each]=1
-    return u.keys()
+    return list(u.keys())
 
 def simplifyHexColours(text):
     """ Replace all colour declarations where pairs repeat.
@@ -442,17 +442,17 @@ def simplifyHexColours(text):
     for e in uniqify(all_hex_encodings):
         if e[1]==e[2] and e[3]==e[4] and e[5]==e[6]:
             colour_replacements[e] = '#'+e[1]+e[3]+e[5]
-    for k, v in colour_replacements.items():
+    for k, v in list(colour_replacements.items()):
         text = text.replace(k, v)
     return text
 
 
 def __grr():
-    print "Usage: python slimmer.py /path/to/input.html [xhtml|html|css|js] /path/to/output.html"
+    print("Usage: python slimmer.py /path/to/input.html [xhtml|html|css|js] /path/to/output.html")
 
 def _pingable(url):
     try:
-        urllib2.urlopen(url)
+        urllib.request.urlopen(url)
         return 1
     except:
         return 0
@@ -476,7 +476,7 @@ def __guess_syntax(filepath):
         if os.path.isfile(filepath):
             f=open(filepath)
         else:
-            f=urllib2.urlopen(filepath)
+            f=urllib.request.urlopen(filepath)
             
         line = f.readline()
         c = 0 
@@ -534,10 +534,10 @@ Options:
                                             
     
 def __showversion():
-    print __version__
+    print(__version__)
     
 def __usage():
-    print usage
+    print(usage)
 
 class Usage(Exception):
     def __init__(self, msg):
@@ -550,12 +550,12 @@ def main(argv=None):
         try:
             opts, args = getopt.getopt(argv[1:], "ho:vt", 
                            ["help", "output=", "version", "test", "hardcore"])
-        except getopt.error, msg:
+        except getopt.error as msg:
             raise Usage(msg)
         # more code, unchanged
-    except Usage, err:
-        print >>sys.stderr, err.msg
-        print >>sys.stderr, "for help use --help"
+    except Usage as err:
+        print(err.msg, file=sys.stderr)
+        print("for help use --help", file=sys.stderr)
         return 2
     
     outputfile = None
@@ -599,18 +599,18 @@ def main(argv=None):
         syntax = __guess_syntax(inputfile)
     
     if inputfile is None:
-        print >>sys.stderr, "No input file"
-        print >>sys.stderr, "for help use --help"
+        print("No input file", file=sys.stderr)
+        print("for help use --help", file=sys.stderr)
         return 2        
         
     if not acceptableSyntax(syntax):
-        print >>sys.stderr, "Unrecognized syntax"
-        print >>sys.stderr, "for help use --help"
+        print("Unrecognized syntax", file=sys.stderr)
+        print("for help use --help", file=sys.stderr)
         return 2
     
     if otherargs:
-        print >>sys.stderr, "Unrecognized arguments %r"%otherargs
-        print >>sys.stderr, "for help use --help"
+        print("Unrecognized arguments %r"%otherargs, file=sys.stderr)
+        print("for help use --help", file=sys.stderr)
         return 2
 
     
@@ -623,8 +623,8 @@ def main(argv=None):
 from time import time
 
 def _gzipText(content):
-    import cStringIO,gzip
-    zbuf = cStringIO.StringIO()
+    import io,gzip
+    zbuf = io.StringIO()
     zfile = gzip.GzipFile(None, 'wb', 9, zbuf)
     zfile.write(content)
     zfile.close()
@@ -634,7 +634,7 @@ def run(inputfile, syntax, speedtest, ou
     if os.path.isfile(inputfile):
         contents = open(inputfile).read()
     else:
-        contents = urllib2.urlopen(inputfile).read()
+        contents = urllib.request.urlopen(inputfile).read()
     t0=time()
     slimmed = slimmer(contents, syntax, hardcore=hardcore)
     t=time()-t0
@@ -655,19 +655,19 @@ def run(inputfile, syntax, speedtest, ou
         size_difference = before-after
         if size_difference > 10000:
             size_difference = "%s (%sK)"%(size_difference, size_difference/1024)
-        print "Took %s seconds"%round(t, 3)
-        print "Bytes before: %s"%size_before
-        print "Bytes after:  %s"%size_after
-        print "Bytes after zlib: %s"%after_zlibbed
-        print "Bytes after gzip: %s"%after_gzip
-        print "Bytes saved:  %s "%size_difference,
-        print "(%s%% of original size)"%(100*round(after/float(before), 2))
+        print("Took %s seconds"%round(t, 3))
+        print("Bytes before: %s"%size_before)
+        print("Bytes after:  %s"%size_after)
+        print("Bytes after zlib: %s"%after_zlibbed)
+        print("Bytes after gzip: %s"%after_gzip)
+        print("Bytes saved:  %s "%size_difference, end=' ')
+        print("(%s%% of original size)"%(100*round(after/float(before), 2)))
         
     elif outputfile:
         open(outputfile, 'w').write(slimmed)
         
     else:
-        print >>sys.stdout, slimmed
+        print(slimmed, file=sys.stdout)
     
     
 if __name__=='__main__':
--- a/slimmer/tests/codechunks.py
+++ b/slimmer/tests/codechunks.py
@@ -51,13 +51,13 @@ expect_CSS_3 = r'''
 '''
 #----------------------------------------------------------------------------
 
-CSS_3b = unicode(CSS_3)
+CSS_3b = str(CSS_3)
 
-expect_CSS_3b = unicode(expect_CSS_3)
+expect_CSS_3b = str(expect_CSS_3)
 
 
 #----------------------------------------------------------------------------
-CSS_3c = u'''
+CSS_3c = '''
 body {
     color:#000000;
     color:#ccFF99;
@@ -65,7 +65,7 @@ body {
     }
 '''    
 
-expect_CSS_3c = u'''
+expect_CSS_3c = '''
 body{color:#000;color:#cF9;\xa3}'''
 
 #----------------------------------------------------------------------------
@@ -271,7 +271,7 @@ expect_HTML_7='''
 
 #----------------------------------------------------------------------------
 
-HTML_8=u'''
+HTML_8='''
 <html>
   <style>
   * { color:#000000; background-color:#ffcc99 ; }
@@ -282,14 +282,14 @@ HTML_8=u'''
 </html>
 '''
 
-expect_HTML_8=u'''
+expect_HTML_8='''
 <html><style> *{color:#000;background-color:#fc9}</style><body><div style="color:#CCCCCC; background-color: #ee99cc">Pay with \xa3</div></body></html>
 '''
 
 
 #----------------------------------------------------------------------------
 
-HTML_9=u'''
+HTML_9='''
 <html>
   <style>
   * { color:#000000; 
@@ -302,7 +302,7 @@ HTML_9=u'''
 </html>
 '''
 
-expect_HTML_9=u'''
+expect_HTML_9='''
 <html><style> *{color:#000;background-color:#fc9}</style><body><div style="color:#CCCCCC; background-color: #ee99cc">Pay with \xa3</div></body></html>
 '''
 
--- a/slimmer/tests/testSlimmer.py
+++ b/slimmer/tests/testSlimmer.py
@@ -9,25 +9,25 @@ import slimmer
 
 VERBOSE = False
 
-from codechunks import *
+from .codechunks import *
 
 class SlimmerTestCase(unittest.TestCase):
     
     def _assert(self, str1, str2, name=''):
         """ special kind of assertEqual that strips """
         if not str1.strip() == str2.strip():
-            print '\n'+"-"*70
-            print "DIFFERENCES %s"%name
-            print "----Result|"+"-"*50
+            print('\n'+"-"*70)
+            print("DIFFERENCES %s"%name)
+            print("----Result|"+"-"*50)
             #print repr(str1.strip())
-            print str1.strip()
-            print "----Expect|"+"-"*50
+            print(str1.strip())
+            print("----Expect|"+"-"*50)
             #print repr(str2.strip())
-            print str2.strip()
-            print "-"*70
+            print(str2.strip())
+            print("-"*70)
             x = str1.strip()
             y = str2.strip()
-            print x
+            print(x)
             arrow = ''
             for i, e in enumerate(list(x)):
                 if e==y[i]:
@@ -35,7 +35,7 @@ class SlimmerTestCase(unittest.TestCase)
                 else:
                     arrow += "^"
                     break
-            print arrow            
+            print(arrow)            
         self.assertEqual(str1.strip(), str2.strip())
         #assert str1.strip() == str2.strip()
         #return self.assertEqual(str1.strip(), str2.strip())
@@ -55,14 +55,14 @@ class SlimmerTestCase(unittest.TestCase)
         for record in self.timed_records:
 
             if VERBOSE:
-                print "-- %s --:"%record['name']
-                print "%s seconds"%round(record['time'], 6)
-                print "Was: %s\tNow: %s"%(record['size1'], record['size2'])
+                print("-- %s --:"%record['name'])
+                print("%s seconds"%round(record['time'], 6))
+                print("Was: %s\tNow: %s"%(record['size1'], record['size2']))
                 percent = round(100*record['size2']/float(record['size1']), 5)
                 percent = "%s%%"%percent
                 difference = record['size1'] - record['size2']
-                print "Difference: %s (%s)"%(difference, percent)
-                print 
+                print("Difference: %s (%s)"%(difference, percent))
+                print() 
             
 
     def atest(self, str1, str2, name, func, printresult=VERBOSE, *args, **kw):
@@ -72,9 +72,9 @@ class SlimmerTestCase(unittest.TestCase)
         
         t0=time()
         args = [before]+list(args)
-        result = apply(func, args, kw)
+        result = func(*args, **kw)
         if printresult:
-            print result
+            print(result)
         T = time()-t0
         
         self.timer(name,time()-t0, len(before), len(result))
@@ -86,7 +86,7 @@ class SlimmerTestCase(unittest.TestCase)
     #--- Start the madness! ----------------------------------------------
     
     def testGuessSyntax(self):
-        for var, value in globals().items():
+        for var, value in list(globals().items()):
             syntax = None
             if var.find('CSS')> -1:
                 syntax = slimmer.guessSyntax(value)
@@ -303,18 +303,18 @@ class SlimmerTestCase(unittest.TestCase)
         here = os.path.dirname(__file__)
         before = codecs.open(os.path.join(here, 'euc-jp.html'),
                              'r','euc-jp').read()
-        assert isinstance(before, unicode)
+        assert isinstance(before, str)
         after = slimmer.html_slimmer(before)
-        assert isinstance(after, unicode)
+        assert isinstance(after, str)
         
     def testUnicodeHTML2(self):
         here = os.path.dirname(__file__)
         before = codecs.open(os.path.join(here, 'utf-8.html'),
                              'r','utf-8').read()
-        assert isinstance(before, unicode)
+        assert isinstance(before, str)
         after = slimmer.html_slimmer(before)
-        assert isinstance(after, unicode)
-        expect = u'<html><p>\u0e2a\u0e27\u0e31\u0e2a\u0e14\u0e35\u0e04\u0e23\u0e31\u0e1a</p></html>'
+        assert isinstance(after, str)
+        expect = '<html><p>\u0e2a\u0e27\u0e31\u0e2a\u0e14\u0e35\u0e04\u0e23\u0e31\u0e1a</p></html>'
         assert after == expect
         
 
