From: "Jason R. Coombs" <jaraco@jaraco.com>
Date: Mon, 8 Mar 2021 21:51:42 -0500
Subject: Execute lib2to3 on src, examples. Ref #2.

python -m lib2to3 --no-diffs -nw src examples

Origin: https://github.com/jaraco/cssutils/commit/e1e07731fe7c6bd6f830149e6b980f693270314d
---
 examples/build.py                                  |    6 +-
 examples/codec.py                                  |    4 +-
 examples/cssencodings.py                           |   40 +-
 examples/customlog.py                              |    6 +-
 examples/imports.py                                |   22 +-
 examples/minify.py                                 |    8 +-
 examples/parse.py                                  |   16 +-
 examples/properties_with_same_name.py              |   44 +-
 examples/selectors_tolower.py                      |   20 +-
 examples/serialize.py                              |   50 +-
 examples/style.py                                  |   14 +-
 examples/styledeclaration.py                       |   34 +-
 examples/testutil.py                               |   36 +-
 src/cssutils/__init__.py                           |   56 +-
 src/cssutils/_codec2.py                            |   56 +-
 src/cssutils/_fetch.py                             |   26 +-
 src/cssutils/_fetchgae.py                          |   14 +-
 src/cssutils/codec.py                              |    8 +-
 src/cssutils/css/__init__.py                       |   40 +-
 src/cssutils/css/csscharsetrule.py                 |   34 +-
 src/cssutils/css/csscomment.py                     |   14 +-
 src/cssutils/css/cssfontfacerule.py                |   44 +-
 src/cssutils/css/cssimportrule.py                  |   70 +-
 src/cssutils/css/cssmediarule.py                   |   54 +-
 src/cssutils/css/cssnamespacerule.py               |   44 +-
 src/cssutils/css/csspagerule.py                    |   84 +-
 src/cssutils/css/cssrule.py                        |   72 +-
 src/cssutils/css/cssrulelist.py                    |    2 +-
 src/cssutils/css/cssstyledeclaration.py            |   76 +-
 src/cssutils/css/cssstylerule.py                   |   60 +-
 src/cssutils/css/cssstylesheet.py                  |   98 +-
 src/cssutils/css/cssunknownrule.py                 |   51 +-
 src/cssutils/css/cssvalue.py                       |  142 +--
 src/cssutils/css/cssvariablesdeclaration.py        |   64 +-
 src/cssutils/css/cssvariablesrule.py               |   46 +-
 src/cssutils/css/marginrule.py                     |   38 +-
 src/cssutils/css/property.py                       |   94 +-
 src/cssutils/css/selector.py                       |  146 +--
 src/cssutils/css/selectorlist.py                   |   30 +-
 src/cssutils/css/value.py                          |  252 ++---
 src/cssutils/cssproductions.py                     |   18 +-
 src/cssutils/errorhandler.py                       |    8 +-
 src/cssutils/helper.py                             |   26 +-
 src/cssutils/parse.py                              |    6 +-
 src/cssutils/prodparser.py                         |  100 +-
 src/cssutils/profiles.py                           |   60 +-
 src/cssutils/sac.py                                |  109 +-
 src/cssutils/script.py                             |   86 +-
 src/cssutils/scripts/__init__.py                   |    2 +-
 src/cssutils/scripts/csscapture.py                 |    6 +-
 src/cssutils/scripts/csscombine.py                 |    8 +-
 src/cssutils/scripts/cssparse.py                   |   10 +-
 src/cssutils/serialize.py                          |  256 ++---
 src/cssutils/settings.py                           |    4 +-
 src/cssutils/stylesheets/__init__.py               |    8 +-
 src/cssutils/stylesheets/medialist.py              |   24 +-
 src/cssutils/stylesheets/mediaquery.py             |   30 +-
 src/cssutils/stylesheets/stylesheet.py             |    4 +-
 src/cssutils/tests/basetest.py                     |   40 +-
 src/cssutils/tests/test_codec.py                   |  152 +--
 src/cssutils/tests/test_csscharsetrule.py          |   54 +-
 src/cssutils/tests/test_csscomment.py              |   40 +-
 src/cssutils/tests/test_cssfontfacerule.py         |  102 +-
 src/cssutils/tests/test_cssimportrule.py           |  272 ++---
 src/cssutils/tests/test_cssmediarule.py            |  250 ++---
 src/cssutils/tests/test_cssnamespacerule.py        |  180 ++--
 src/cssutils/tests/test_csspagerule.py             |  264 ++---
 src/cssutils/tests/test_cssproperties.py           |    4 +-
 src/cssutils/tests/test_cssrule.py                 |   42 +-
 src/cssutils/tests/test_cssrulelist.py             |    2 +-
 src/cssutils/tests/test_cssstyledeclaration.py     |  346 +++---
 src/cssutils/tests/test_cssstylerule.py            |  112 +-
 src/cssutils/tests/test_cssstylesheet.py           |  150 +--
 src/cssutils/tests/test_cssunknownrule.py          |  108 +-
 src/cssutils/tests/test_cssutils.py                |   94 +-
 src/cssutils/tests/test_cssvariablesdeclaration.py |   94 +-
 src/cssutils/tests/test_cssvariablesrule.py        |   74 +-
 src/cssutils/tests/test_encutils/__init__.py       |   70 +-
 src/cssutils/tests/test_errorhandler.py            |   32 +-
 src/cssutils/tests/test_helper.py                  |   56 +-
 src/cssutils/tests/test_marginrule.py              |   44 +-
 src/cssutils/tests/test_medialist.py               |  120 +--
 src/cssutils/tests/test_mediaquery.py              |   94 +-
 src/cssutils/tests/test_parse.py                   |  226 ++--
 src/cssutils/tests/test_prodparser.py              |   66 +-
 src/cssutils/tests/test_profiles.py                |   22 +-
 src/cssutils/tests/test_properties.py              |   16 +-
 src/cssutils/tests/test_property.py                |  160 +--
 src/cssutils/tests/test_scripts_csscombine.py      |    2 +-
 src/cssutils/tests/test_selector.py                |  552 +++++-----
 src/cssutils/tests/test_selectorlist.py            |   64 +-
 src/cssutils/tests/test_serialize.py               |  336 +++---
 src/cssutils/tests/test_settings.py                |    4 +-
 src/cssutils/tests/test_stylesheet.py              |    8 +-
 src/cssutils/tests/test_tokenize2.py               | 1129 ++++++++++----------
 src/cssutils/tests/test_util.py                    |  318 +++---
 src/cssutils/tests/test_value.py                   |  706 ++++++------
 src/cssutils/tests/test_x.py                       |    6 +-
 src/cssutils/tokenize2.py                          |   38 +-
 src/cssutils/util.py                               |  157 +--
 src/encutils/__init__.py                           |  100 +-
 101 files changed, 4742 insertions(+), 4744 deletions(-)

diff --git a/examples/build.py b/examples/build.py
index 29acc20..7e7bb27 100644
--- a/examples/build.py
+++ b/examples/build.py
@@ -18,7 +18,7 @@ atom|title {
     color: #000 !important
     }
 '''
-EXPERR = u'Property: Found valid "CSS Level 2.1" value: red [4:19: color]\nProperty: Found valid "CSS Level 2.1" value: #fff [4:30: background]\nProperty: Found valid "CSS Level 2.1" value: #000 [1:30: color]\nProperty: Found valid "CSS Level 2.1" value: url(images/example3.gif) [4:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(./images/example3.gif) [5:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(import/images2/example2.gif) [6:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(./import/images2/example2.gif) [7:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(import/images2/../../images/example3.gif) [8:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(images2/example2.gif) [4:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(http://example.com/images/example.gif) [5:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(//example.com/images/example.gif) [6:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(/images/example.gif) [7:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(images2/example.gif) [8:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(./images2/example.gif) [9:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(../images/example.gif) [10:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(./../images/example.gif) [11:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(images/example.gif) [4:2: background-image]\n'
+EXPERR = 'Property: Found valid "CSS Level 2.1" value: red [4:19: color]\nProperty: Found valid "CSS Level 2.1" value: #fff [4:30: background]\nProperty: Found valid "CSS Level 2.1" value: #000 [1:30: color]\nProperty: Found valid "CSS Level 2.1" value: url(images/example3.gif) [4:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(./images/example3.gif) [5:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(import/images2/example2.gif) [6:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(./import/images2/example2.gif) [7:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(import/images2/../../images/example3.gif) [8:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(images2/example2.gif) [4:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(http://example.com/images/example.gif) [5:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(//example.com/images/example.gif) [6:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(/images/example.gif) [7:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(images2/example.gif) [8:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(./images2/example.gif) [9:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(../images/example.gif) [10:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(./../images/example.gif) [11:2: background]\nProperty: Found valid "CSS Level 2.1" value: url(images/example.gif) [4:2: background-image]\n'
 
 def main():
     # -*- coding: utf-8 -*-
@@ -26,7 +26,7 @@ def main():
     import logging
     cssutils.log.setLevel(logging.DEBUG)
     
-    css = u'''/* a comment with umlaut ä */
+    css = '''/* a comment with umlaut ä */
          @namespace html "http://www.w3.org/1999/xhtml";
          @variables { BG: #fff }
          html|a { color:red; background: var(BG) }'''
@@ -50,7 +50,7 @@ def main():
     sheet.add('@import "sheets/import.css";')
     
     # cssutils.ser.prefs.resolveVariables = True # default since 0.9.7b2
-    print sheet.cssText
+    print(sheet.cssText)
 
 def _test():
     import doctest           # replace M with your module's name
diff --git a/examples/codec.py b/examples/codec.py
index 2af8d03..7ff7bf4 100644
--- a/examples/codec.py
+++ b/examples/codec.py
@@ -5,5 +5,5 @@ import cssutils
 
 cssText = codecs.open('../sheets/cases.css', encoding='css').read()
 sheet = cssutils.parseString(cssText)
-print sheet
-print sheet.cssText
\ No newline at end of file
+print(sheet)
+print(sheet.cssText)
diff --git a/examples/cssencodings.py b/examples/cssencodings.py
index 82c43ae..711e050 100644
--- a/examples/cssencodings.py
+++ b/examples/cssencodings.py
@@ -7,11 +7,11 @@ example css is in default UTF-8 encoding
 from cssutils import CSSParser
 
 EXPOUT = '''cssText in different encodings, depending on the console some\n     chars may look broken but are actually not\n\n@charset "ascii";\n/* some umlauts \\E4 \\F6 \\FC  and EURO sign \\20AC  */\na:before {\n    content: "\\E4 "\n    }\n\n@charset "iso-8859-1";\n/* some umlauts \xe4\xf6\xfc and EURO sign \\20AC  */\na:before {\n    content: "\xe4"\n    }\n\n@charset "iso-8859-15";\n/* some umlauts \xe4\xf6\xfc and EURO sign \xa4 */\na:before {\n    content: "\xe4"\n    }\n\n@charset "utf-8";\n/* some umlauts \xc3\xa4\xc3\xb6\xc3\xbc and EURO sign \xe2\x82\xac */\na:before {\n    content: "\xc3\xa4"\n    }\n\n/* some umlauts \xc3\xa4\xc3\xb6\xc3\xbc and EURO sign \xe2\x82\xac */\na:before {\n    content: "\xc3\xa4"\n    }\n'''
-EXPERR = u'Property: Found valid "CSS Level 2.1" value: "\xe4" [4:8: content]\n'
+EXPERR = 'Property: Found valid "CSS Level 2.1" value: "\xe4" [4:8: content]\n'
 
 
 def main():
-    css = u'''
+    css = '''
     /* some umlauts äöü and EURO sign € */
     a:before {
        content: "ä";
@@ -20,30 +20,30 @@ def main():
     p = CSSParser()
     sheet = p.parseString(css)
     
-    print """cssText in different encodings, depending on the console some
-     chars may look broken but are actually not"""
-    print 
-    
+    print("""cssText in different encodings, depending on the console some
+     chars may look broken but are actually not""")
+    print()
+
     sheet.encoding = 'ascii'
-    print sheet.cssText
-    print
-    
+    print(sheet.cssText)
+    print()
+
     sheet.encoding = 'iso-8859-1'
-    print sheet.cssText
-    print
-    
+    print(sheet.cssText)
+    print()
+
     sheet.encoding = 'iso-8859-15'
-    print sheet.cssText
-    print
-    
+    print(sheet.cssText)
+    print()
+
     sheet.encoding = 'utf-8'
-    print sheet.cssText
-    print
-    
+    print(sheet.cssText)
+    print()
+
     # results in default UTF-8 encoding without @charset rule
     sheet.encoding = None
-    print sheet.cssText
+    print(sheet.cssText)
 
 
 if __name__ == '__main__':
-    main()
\ No newline at end of file
+    main()
diff --git a/examples/customlog.py b/examples/customlog.py
index 123944d..da577c1 100644
--- a/examples/customlog.py
+++ b/examples/customlog.py
@@ -1,12 +1,12 @@
-import logging, StringIO
+import logging, io
 
 EXPOUT = ""
-EXPERR = u"Property: Unknown Property name. [1:5: x]\nHTTPError opening url=http://cthedot.de/x: 404 Not Found\nCSSImportRule: While processing imported style sheet href=http://cthedot.de/x: IOError('Cannot read Stylesheet.',)\nCSSStylesheet: CSSImportRule not allowed here. [1:13: @import]\n"
+EXPERR = "Property: Unknown Property name. [1:5: x]\nHTTPError opening url=http://cthedot.de/x: 404 Not Found\nCSSImportRule: While processing imported style sheet href=http://cthedot.de/x: IOError('Cannot read Stylesheet.',)\nCSSStylesheet: CSSImportRule not allowed here. [1:13: @import]\n"
 
 def main():
     import cssutils
 
-    mylog = StringIO.StringIO()
+    mylog = io.StringIO()
     h = logging.StreamHandler(mylog)
     h.setFormatter(logging.Formatter('%(levelname)s    %(message)s'))
     #cssutils.log.addHandler(h)
diff --git a/examples/imports.py b/examples/imports.py
index 4b8258a..ef045b2 100644
--- a/examples/imports.py
+++ b/examples/imports.py
@@ -3,7 +3,7 @@ import cssutils
 import os.path
 import xml.dom
 
-EXPOUT = u'''@charset "iso-8859-1";
+EXPOUT = '''@charset "iso-8859-1";
 @import "1inherit-iso.css";
 
 ##############################
@@ -22,7 +22,7 @@ EXPOUT = u'''@charset "iso-8859-1";
 
 
 '''
-EXPERR = u''
+EXPERR = ''
 
 
 def main():
@@ -30,19 +30,19 @@ def main():
     def p(s, l=0):
         c = '#=-'[l] * (30 - l*10)
         for r in s.cssRules.rulesOfType(cssutils.css.CSSRule.IMPORT_RULE):
-            print c
-            print r.href
-            print c
-            print r.styleSheet.cssText
-            print 
+            print(c)
+            print(r.href)
+            print(c)
+            print(r.styleSheet.cssText)
+            print()
             p(r.styleSheet, l=l+1)
-            print 
+            print()
             
     s = cssutils.parseFile(os.path.join('sheets', '1import.css'))        
-    print s.cssText
-    print
+    print(s.cssText)
+    print()
     
     p(s)
 
 if __name__ == '__main__':
-    main()
\ No newline at end of file
+    main()
diff --git a/examples/minify.py b/examples/minify.py
index fa7a069..62333ba 100644
--- a/examples/minify.py
+++ b/examples/minify.py
@@ -1,7 +1,7 @@
-import logging, StringIO
+import logging, io
 
 EXPOUT = "@variables{c:#0f0}a{color:var(c)}\na{color:#0f0}\n"
-EXPERR = u'Property: Found valid "CSS Level 2.1" value: #0f0 [6:9: color]\n'
+EXPERR = 'Property: Found valid "CSS Level 2.1" value: #0f0 [6:9: color]\n'
 
 def main():
     import cssutils
@@ -19,11 +19,11 @@ def main():
     
     cssutils.ser.prefs.useMinified()
     cssutils.ser.prefs.resolveVariables = False
-    print s.cssText
+    print(s.cssText)
 
     # reset
     cssutils.ser.prefs.resolveVariables = True
-    print s.cssText
+    print(s.cssText)
 
     
 if __name__ == '__main__':
diff --git a/examples/parse.py b/examples/parse.py
index e1525cf..f781659 100644
--- a/examples/parse.py
+++ b/examples/parse.py
@@ -3,7 +3,7 @@ import cssutils
 import xml.dom
 
 EXPOUT = '''\n--- source CSS ---\n/* This is a comment */\n    body {\n        background: white;\n        top: red;\n        x: 1;\n        }\n    a { y }\n            \n\n--- simple parsing ---\n/* This is a comment */\nbody {\n    background: white;\n    top: red;\n    x: 1\n    }\n\n--- CSSParser(raiseExceptions=True) ---\n:::RAISED::: Property: No ":" after name found: y  [7:10:  ]\n'''
-EXPERR = u'Property: Invalid value for "CSS Level 2.1" property: red [4:9: top]\nProperty: Unknown Property name. [5:9: x]\nProperty: No ":" after name found: y  [7:10:  ]\nProperty: No property value found: y  [7:10:  ]\nCSSStyleDeclaration: Syntax Error in Property: y \nProperty: Invalid value for "CSS Level 2.1" property: red [4:9: top]\nProperty: Unknown Property name. [5:9: x]\n'
+EXPERR = 'Property: Invalid value for "CSS Level 2.1" property: red [4:9: top]\nProperty: Unknown Property name. [5:9: x]\nProperty: No ":" after name found: y  [7:10:  ]\nProperty: No property value found: y  [7:10:  ]\nCSSStyleDeclaration: Syntax Error in Property: y \nProperty: Invalid value for "CSS Level 2.1" property: red [4:9: top]\nProperty: Unknown Property name. [5:9: x]\n'
 
 
 def main():
@@ -16,19 +16,19 @@ def main():
         }
     a { y }
             '''
-    print "\n--- source CSS ---"
-    print css
+    print("\n--- source CSS ---")
+    print(css)
 
-    print "\n--- simple parsing ---"
+    print("\n--- simple parsing ---")
     c1 = cssutils.parseString(css)
-    print c1.cssText
+    print(c1.cssText)
 
-    print "\n--- CSSParser(raiseExceptions=True) ---"
+    print("\n--- CSSParser(raiseExceptions=True) ---")
     p = cssutils.CSSParser(raiseExceptions=True)
     try:
         c2 = p.parseString(css)
-    except xml.dom.DOMException, e:
-        print ":::RAISED:::", e
+    except xml.dom.DOMException as e:
+        print(":::RAISED:::", e)
 
 if __name__ == '__main__':
     main()
\ No newline at end of file
diff --git a/examples/properties_with_same_name.py b/examples/properties_with_same_name.py
index 3418cf3..a2c87b4 100644
--- a/examples/properties_with_same_name.py
+++ b/examples/properties_with_same_name.py
@@ -2,39 +2,39 @@
 """
 import cssutils
 
-print "\n**SameNamePropertyList is replaced with style.getProperties() from 0.9.4**"
+print("\n**SameNamePropertyList is replaced with style.getProperties() from 0.9.4**")
 cssutils.ser.prefs.keepComments = False # remove for now
 
 cssText='''    background: white url(paper.png) scroll; /* for all UAs */
     background: white url(ledger.png) fixed; /* for UAs that do fixed backgrounds */
 '''
-print "\n>>> # cssText"
-print cssText
+print("\n>>> # cssText")
+print(cssText)
 
 
-print ">>> style = cssutils.css.CSSStyleDeclaration(cssText=cssText)"
+print(">>> style = cssutils.css.CSSStyleDeclaration(cssText=cssText)")
 style = cssutils.css.CSSStyleDeclaration(cssText=cssText)
-print '>>> print style.cssText'
-print style.cssText
+print('>>> print style.cssText')
+print(style.cssText)
 
-print "\n>>> cssutils.ser.prefs.keepAllProperties = True # output all values"
+print("\n>>> cssutils.ser.prefs.keepAllProperties = True # output all values")
 cssutils.ser.prefs.keepAllProperties = True # output all values
-print '>>> style.cssText # with keepAllProperties==True:'
-print style.cssText
-print
+print('>>> style.cssText # with keepAllProperties==True:')
+print(style.cssText)
+print()
 
-print ">>> # NEW METHOD getProperties"
-print ">>> proplist = style.getProperties('background', all=True)"
+print(">>> # NEW METHOD getProperties")
+print(">>> proplist = style.getProperties('background', all=True)")
 proplist = style.getProperties('background', all=True)
-print ">>> proplist\n", proplist
-print ">>> for prop in proplist: print '\\t', prop.value"
-for prop in proplist: print "\t", prop.value
-print
+print(">>> proplist\n", proplist)
+print(">>> for prop in proplist: print '\\t', prop.value")
+for prop in proplist: print("\t", prop.value)
+print()
 
-print ">>> # overwrite the current property, to overwrite all iterate over proplist"
-print ">>> style.setProperty('background', 'red')"
+print(">>> # overwrite the current property, to overwrite all iterate over proplist")
+print(">>> style.setProperty('background', 'red')")
 style.setProperty('background', 'red')
-print ">>> style.getPropertyValue('background')"
-print style.getPropertyValue('background')
-print ">>> style.cssText"
-print style.cssText
+print(">>> style.getPropertyValue('background')")
+print(style.getPropertyValue('background'))
+print(">>> style.cssText")
+print(style.cssText)
diff --git a/examples/selectors_tolower.py b/examples/selectors_tolower.py
index feef86e..8c18df3 100644
--- a/examples/selectors_tolower.py
+++ b/examples/selectors_tolower.py
@@ -1,11 +1,11 @@
 import cssutils
 from cssutils import css, stylesheets
 
-EXPOUT = u'''--- ORIGINAL ---\n@charset "ascii";\n        @namespace PREfix "uri";\n        SOME > WeIrD + selector ~ used here {color: green}\n        PREfix|name {color: green}\n    \n\n--- SELECTORS TO LOWER CASE (does not simply work for PREfix|name!) ---\n--- CHANGE PREFIX (prefix is not really part of selectorText, URI is! ---\n\n@charset "ascii";\n@namespace lower-case_prefix "uri";\nsome > weird + selector ~ used here {\n    color: green\n    }\nlower-case_prefix|name {\n    color: green\n    }\n'''
-EXPERR = u'Property: Found valid "CSS Level 2.1" value: green [3:46: color]\nProperty: Found valid "CSS Level 2.1" value: green [4:22: color]\n'
+EXPOUT = '''--- ORIGINAL ---\n@charset "ascii";\n        @namespace PREfix "uri";\n        SOME > WeIrD + selector ~ used here {color: green}\n        PREfix|name {color: green}\n    \n\n--- SELECTORS TO LOWER CASE (does not simply work for PREfix|name!) ---\n--- CHANGE PREFIX (prefix is not really part of selectorText, URI is! ---\n\n@charset "ascii";\n@namespace lower-case_prefix "uri";\nsome > weird + selector ~ used here {\n    color: green\n    }\nlower-case_prefix|name {\n    color: green\n    }\n'''
+EXPERR = 'Property: Found valid "CSS Level 2.1" value: green [3:46: color]\nProperty: Found valid "CSS Level 2.1" value: green [4:22: color]\n'
 
 def main():
-    examplecss = u"""@charset "ascii";
+    examplecss = """@charset "ascii";
         @namespace PREfix "uri";
         SOME > WeIrD + selector ~ used here {color: green}
         PREfix|name {color: green}
@@ -14,18 +14,18 @@ def main():
     import logging
     sheet = cssutils.CSSParser(loglevel=logging.DEBUG).parseString(examplecss)
     
-    print "--- ORIGINAL ---"
-    print examplecss
-    print
+    print("--- ORIGINAL ---")
+    print(examplecss)
+    print()
     
-    print "--- SELECTORS TO LOWER CASE (does not simply work for PREfix|name!) ---"
+    print("--- SELECTORS TO LOWER CASE (does not simply work for PREfix|name!) ---")
     sheet.cssRules[2].selectorText = sheet.cssRules[2].selectorText.lower() 
     
-    print "--- CHANGE PREFIX (prefix is not really part of selectorText, URI is! ---"
+    print("--- CHANGE PREFIX (prefix is not really part of selectorText, URI is! ---")
     sheet.cssRules[1].prefix = 'lower-case_prefix'
     
-    print
-    print sheet.cssText
+    print()
+    print(sheet.cssText)
 
 if __name__ == '__main__':
     main()
\ No newline at end of file
diff --git a/examples/serialize.py b/examples/serialize.py
index 713c374..1401d6e 100644
--- a/examples/serialize.py
+++ b/examples/serialize.py
@@ -12,49 +12,49 @@ a {
     }'''
 
 sheet = cssutils.parseString(css)
-print "\nORIGINAL CSS:"
-print css
-print "------------"
+print("\nORIGINAL CSS:")
+print(css)
+print("------------")
 
-print repr(cssutils.ser.prefs)
+print(repr(cssutils.ser.prefs))
 
-print "\nCSS Serialized"
-print sheet.cssText
+print("\nCSS Serialized")
+print(sheet.cssText)
 
-print "\nCSS Serialized with ``keepAllProperties`` = False" 
+print("\nCSS Serialized with ``keepAllProperties`` = False")
 cssutils.ser.prefs.keepAllProperties = False
-print sheet.cssText
+print(sheet.cssText)
 
-print "\nCSS Serialized with ``defaultPropertyName`` = True"
+print("\nCSS Serialized with ``defaultPropertyName`` = True")
 cssutils.ser.prefs.defaultPropertyName = True
-print sheet.cssText
+print(sheet.cssText)
 
-print "\nCSS Serialized with ``defaultPropertyName`` = False"
+print("\nCSS Serialized with ``defaultPropertyName`` = False")
 cssutils.ser.prefs.defaultPropertyName = False
-print sheet.cssText
+print(sheet.cssText)
 
 
-print '\nBUT: Reading value programmatic uses normalized property'
-print '     name and results in actual value only:'
-print '\t.getPropertyValue("color") ==',
-print sheet.cssRules[1].style.getPropertyValue('color')
-print '\t.getPropertyValue("c\\olor") ==',
-print sheet.cssRules[1].style.getPropertyValue('c\olor')
-print '\t.getPropertyValue("c\\o\\l\\o\\r") ==',
-print sheet.cssRules[1].style.getPropertyValue('c\\o\\l\\o\\r')
-print 
+print('\nBUT: Reading value programmatic uses normalized property')
+print('     name and results in actual value only:')
+print('\t.getPropertyValue("color") ==', end=' ')
+print(sheet.cssRules[1].style.getPropertyValue('color'))
+print('\t.getPropertyValue("c\\olor") ==', end=' ')
+print(sheet.cssRules[1].style.getPropertyValue('c\olor'))
+print('\t.getPropertyValue("c\\o\\l\\o\\r") ==', end=' ')
+print(sheet.cssRules[1].style.getPropertyValue('c\\o\\l\\o\\r'))
+print()
 
-print '\nCSS Serialized with indent = 2*" ", importHrefFormat="string", lineNumbers=True'
+print('\nCSS Serialized with indent = 2*" ", importHrefFormat="string", lineNumbers=True')
 cssutils.ser.prefs.indent = 2*' '
 # used to set indentation string, default is 4*' '
 cssutils.ser.prefs.importHrefFormat = 'string'
 # or 'uri', defaults to the format used in parsed stylesheet
 cssutils.ser.prefs.lineNumbers = True
-print sheet.cssText
+print(sheet.cssText)
 
-print '\nCSS Serialized with useMinified()'
+print('\nCSS Serialized with useMinified()')
 cssutils.ser.prefs.useMinified()
-print sheet.cssText
+print(sheet.cssText)
 
 # OUTPUTS
 #1: @import "example.css";
diff --git a/examples/style.py b/examples/style.py
index 9c64223..bb887cb 100644
--- a/examples/style.py
+++ b/examples/style.py
@@ -19,15 +19,15 @@ sys.path.append(os.path.join(os.path.dirname(__file__), 'lib'))
 try:
     import pkg_resources
     pkg_resources.require('lxml')
-except pkg_resources.DistributionNotFound, e:
+except pkg_resources.DistributionNotFound as e:
     pass
 
 try:
     from lxml import etree
     from lxml.builder import E
     from lxml.cssselect import CSSSelector
-except ImportError, e:
-    print 'You need lxml for this example:', e
+except ImportError as e:
+    print('You need lxml for this example:', e)
     sys.exit(1)
 
 
@@ -138,8 +138,8 @@ def render2style(document, view):
     - add style into @style attribute
     - add style into @title attribute (for debugging)
     """
-    for element, style in view.items():
-        v = style.getCssText(separator=u'')
+    for element, style in list(view.items()):
+        v = style.getCssText(separator='')
         element.set('style', v)
         element.set('title', v)
 
@@ -154,8 +154,8 @@ def render2content(document, view, css):
     e = etree.Element('style', {'type': 'text/css'})
     e.text = css
     document.find('head').append(e)
-    for element, style in view.items():
-        v = style.getCssText(separator=u'')
+    for element, style in list(view.items()):
+        v = style.getCssText(separator='')
         element.text = v
 
 def show(text, name, encoding='utf-8'):
diff --git a/examples/styledeclaration.py b/examples/styledeclaration.py
index 46d2918..86c9281 100644
--- a/examples/styledeclaration.py
+++ b/examples/styledeclaration.py
@@ -1,14 +1,14 @@
 import cssutils
 
 def show(style):
-    print "style.length ==", style.length
-    print "style.item(0) ==", style.item(0)
-    print "style.item(1) ==", style.item(1)
-    print "style.getProperties('color', all=True) == ["
+    print("style.length ==", style.length)
+    print("style.item(0) ==", style.item(0))
+    print("style.item(1) ==", style.item(1))
+    print("style.getProperties('color', all=True) == [")
     for x in style.getProperties('color', all=True):
-        print "\t", x.cssText
-    print "\t]"
-    print "style.getPropertyValue('color') ==", style.getPropertyValue('color'), '\n'
+        print("\t", x.cssText)
+    print("\t]")
+    print("style.getPropertyValue('color') ==", style.getPropertyValue('color'), '\n')
 
 
 styledeclaration = '''
@@ -19,34 +19,34 @@ c\olor: green !important;
 c\olor: blue;
 FONT-FAMILY: serif;
 '''
-print "\nGiven styledeclaration:"
-print styledeclaration
-print "------------"
+print("\nGiven styledeclaration:")
+print(styledeclaration)
+print("------------")
 
-print "setting cssText"
+print("setting cssText")
 style = cssutils.css.CSSStyleDeclaration(cssText=styledeclaration)
 show(style)
 
-print "------------"
+print("------------")
 
 # overwrite in any case
-print "style.setProperty('color', 'yellow','!important')"
+print("style.setProperty('color', 'yellow','!important')")
 style.setProperty('color', 'yellow','!important')
 show(style)
 
 # overwrite in any case, even !important
-print "style.setProperty('color', 'red')"
+print("style.setProperty('color', 'red')")
 style.setProperty('color', 'red')
 show(style)
 
-print "------------"
+print("------------")
 
 # overwrite in any case, even !important
-print "style.setProperty('color', 'green', '!important')"
+print("style.setProperty('color', 'green', '!important')")
 style.setProperty('color', 'green', '!important')
 show(style)
 
 # overwrite in any case, even !important
-print "style.setProperty('color', 'blue')"
+print("style.setProperty('color', 'blue')")
 style.setProperty('color', 'blue')
 show(style)
diff --git a/examples/testutil.py b/examples/testutil.py
index 284ab7f..256f4de 100644
--- a/examples/testutil.py
+++ b/examples/testutil.py
@@ -11,7 +11,7 @@ __all__ = ['TestUtil']
 
 import logging
 import os
-import StringIO
+import io
 import sys
 
 import cssutils
@@ -46,7 +46,7 @@ class TestUtil(object):
         self._out = OutReplacement()#StringIO()
         sys.stdout = self._out
         
-        self._err = StringIO.StringIO()
+        self._err = io.StringIO()
         hdlr = logging.StreamHandler(self._err)
         cssutils.log._log.addHandler(hdlr)
                 
@@ -59,11 +59,11 @@ class TestUtil(object):
 
         ok = (out == expo and err == expe)
         if not ok:
-            print
+            print()
             if out != expo:
-                print '### out:\n%r\n### != expout:\n%r\n' % (out, expo)
+                print('### out:\n%r\n### != expout:\n%r\n' % (out, expo))
             else:
-                print '### err:\n%r\n### != experr:\n%r\n' % (err, expe)
+                print('### err:\n%r\n### != experr:\n%r\n' % (err, expe))
         return ok
 
 modules = 0
@@ -77,20 +77,20 @@ def mod(module):
     ok = t.end(module.EXPOUT, module.EXPERR)
     if not ok:
         errors += 1
-    print '---', ok, ':', os.path.basename(module.__file__)
-    print 
-          
+    print('---', ok, ':', os.path.basename(module.__file__))
+    print()
+
 def main():
     if PY2x:
-        print "DOCTESTS:::::::::::::"
+        print("DOCTESTS:::::::::::::")
         # doctests
         import website
         import doctest
         doctest.testmod(website)
-        print 
-        print 80*'-' 
-        print 
-        print 
+        print()
+        print(80*'-')
+        print()
+        print()
 
     global modules, errors
     
@@ -111,13 +111,13 @@ def main():
     import minify
     mod(minify)
     
-    print 
-    print 80*'-' 
-    print 'Ran %i tests (%i errors).' % (modules, errors)
+    print()
+    print(80*'-')
+    print('Ran %i tests (%i errors).' % (modules, errors))
     if PY2x:
-        print '**Check doctest results above!**'
+        print('**Check doctest results above!**')
     else:
-        print 'doctests do not work in Python 3 (yet?)!'
+        print('doctests do not work in Python 3 (yet?)!')
           
     
 if __name__ == '__main__':
diff --git a/src/cssutils/__init__.py b/src/cssutils/__init__.py
index 4a2d773..b169d2c 100644
--- a/src/cssutils/__init__.py
+++ b/src/cssutils/__init__.py
@@ -101,25 +101,25 @@ import sys
 if sys.version_info < (2,6):
     bytes = str
 
-import codec
+from . import codec
 import os.path
-import urllib
-import urlparse
+import urllib.request, urllib.parse, urllib.error
+import urllib.parse
 import xml.dom
 
 # order of imports is important (partly circular)
 from . import util
-import errorhandler
+from . import errorhandler
 log = errorhandler.ErrorHandler()
 
-import css
-import stylesheets
-from parse import CSSParser
+from . import css
+from . import stylesheets
+from .parse import CSSParser
 
-from serialize import CSSSerializer
+from .serialize import CSSSerializer
 ser = CSSSerializer()
 
-from profiles import Profiles
+from .profiles import Profiles
 profile = Profiles(log=log)
 
 # used by Selector defining namespace prefix '*'
@@ -180,7 +180,7 @@ class DOMImplementationCSS(object):
         return minidom.DOMImplementation().createDocumentType(*args, **kwargs)
 
     def hasFeature(self, feature, version):
-        return (feature.lower(), unicode(version)) in self._features
+        return (feature.lower(), str(version)) in self._features
 
 xml.dom.registerDOMImplementation('cssutils', DOMImplementationCSS)
 
@@ -298,16 +298,16 @@ def resolveImports(sheet, target=None):
 
     def getReplacer(targetbase):
         "Return a replacer which uses base to return adjusted URLs"
-        basesch, baseloc, basepath, basequery, basefrag = urlparse.urlsplit(targetbase)
+        basesch, baseloc, basepath, basequery, basefrag = urllib.parse.urlsplit(targetbase)
         basepath, basepathfilename = os.path.split(basepath)
 
         def replacer(uri):
-            scheme, location, path, query, fragment = urlparse.urlsplit(uri)
-            if not scheme and not location and not path.startswith(u'/'):
+            scheme, location, path, query, fragment = urllib.parse.urlsplit(uri)
+            if not scheme and not location and not path.startswith('/'):
                 # relative
                 path, filename = os.path.split(path)
                 combined = os.path.normpath(os.path.join(basepath, path, filename))
-                return urllib.pathname2url(combined)
+                return urllib.request.pathname2url(combined)
             else:
                 # keep anything absolute
                 return uri
@@ -318,30 +318,30 @@ def resolveImports(sheet, target=None):
         if rule.type == rule.CHARSET_RULE:
             pass
         elif rule.type == rule.IMPORT_RULE:
-            log.info(u'Processing @import %r' % rule.href, neverraise=True)
+            log.info('Processing @import %r' % rule.href, neverraise=True)
 
             if rule.hrefFound:
                 # add all rules of @import to current sheet
-                target.add(css.CSSComment(cssText=u'/* START @import "%s" */'
+                target.add(css.CSSComment(cssText='/* START @import "%s" */'
                                           % rule.href))
 
                 try:
                     # nested imports
                     importedSheet = resolveImports(rule.styleSheet)
-                except xml.dom.HierarchyRequestErr, e:
-                    log.warn(u'@import: Cannot resolve target, keeping rule: %s'
+                except xml.dom.HierarchyRequestErr as e:
+                    log.warn('@import: Cannot resolve target, keeping rule: %s'
                              % e, neverraise=True)
                     target.add(rule)
                 else:
                     # adjust relative URI references
-                    log.info(u'@import: Adjusting paths for %r' % rule.href,
+                    log.info('@import: Adjusting paths for %r' % rule.href,
                              neverraise=True)
                     replaceUrls(importedSheet,
                                 getReplacer(rule.href),
                                 ignoreImportRules=True)
 
                     # might have to wrap rules in @media if media given
-                    if rule.media.mediaText == u'all':
+                    if rule.media.mediaText == 'all':
                         mediaproxy = None
                     else:
                         keepimport = False
@@ -354,18 +354,18 @@ def resolveImports(sheet, target=None):
                                 keepimport = True
                                 break
                         if keepimport:
-                            log.warn(u'Cannot combine imported sheet with'
-                                     u' given media as other rules then'
-                                     u' comments or stylerules found %r,'
-                                     u' keeping %r' % (r,
+                            log.warn('Cannot combine imported sheet with'
+                                     ' given media as other rules then'
+                                     ' comments or stylerules found %r,'
+                                     ' keeping %r' % (r,
                                                        rule.cssText),
                                      neverraise=True)
                             target.add(rule)
                             continue
 
                         # wrap in @media if media is not `all`
-                        log.info(u'@import: Wrapping some rules in @media '
-                                 u' to keep media: %s'
+                        log.info('@import: Wrapping some rules in @media '
+                                 ' to keep media: %s'
                                  % rule.media.mediaText, neverraise=True)
                         mediaproxy = css.CSSMediaRule(rule.media.mediaText)
 
@@ -381,7 +381,7 @@ def resolveImports(sheet, target=None):
 
             else:
                 # keep @import as it is
-                log.error(u'Cannot get referenced stylesheet %r, keeping rule'
+                log.error('Cannot get referenced stylesheet %r, keeping rule'
                           % rule.href, neverraise=True)
                 target.add(rule)
 
@@ -392,4 +392,4 @@ def resolveImports(sheet, target=None):
 
 
 if __name__ == '__main__':
-    print __doc__
+    print(__doc__)
diff --git a/src/cssutils/_codec2.py b/src/cssutils/_codec2.py
index d0ae617..3204736 100644
--- a/src/cssutils/_codec2.py
+++ b/src/cssutils/_codec2.py
@@ -154,9 +154,9 @@ def detectencoding_unicode(input, final=False):
     specifies whether more data will be available in later calls or not. If
     ``final`` is true, ``detectencoding_unicode()`` will never return ``None``.
     """
-    prefix = u'@charset "'
+    prefix = '@charset "'
     if input.startswith(prefix):
-        pos = input.find(u'"', len(prefix))
+        pos = input.find('"', len(prefix))
         if pos >= 0:
             return (input[len(prefix):pos], True)
     elif final or not prefix.startswith(input):
@@ -176,13 +176,13 @@ def _fixencoding(input, encoding, final=False):
     specifies whether more data will be available in later calls or not.
     If ``final`` is true, ``_fixencoding()`` will never return ``None``.
     """
-    prefix = u'@charset "'
+    prefix = '@charset "'
     if len(input) > len(prefix):
         if input.startswith(prefix):
-            pos = input.find(u'"', len(prefix))
+            pos = input.find('"', len(prefix))
             if pos >= 0:
                 if encoding.replace("_", "-").lower() == "utf-8-sig":
-                    encoding = u"utf-8"
+                    encoding = "utf-8"
                 return prefix + encoding + input[pos:]
             # we haven't seen the end of the encoding name yet => fall through
         else:
@@ -203,7 +203,7 @@ def decode(input, errors="strict", encoding=None, force=True):
         if (explicit and not force) or encoding is None: # Take the encoding from the input
             encoding = _encoding
     (input, consumed) = codecs.getdecoder(encoding)(input, errors)
-    return (_fixencoding(input, unicode(encoding), True), consumed)
+    return (_fixencoding(input, str(encoding), True), consumed)
 
 
 def encode(input, errors="strict", encoding=None):
@@ -211,9 +211,9 @@ def encode(input, errors="strict", encoding=None):
     if encoding is None:
         encoding = detectencoding_unicode(input, True)[0]
         if encoding.replace("_", "-").lower() == "utf-8-sig":
-            input = _fixencoding(input, u"utf-8", True)
+            input = _fixencoding(input, "utf-8", True)
     else:
-        input = _fixencoding(input, unicode(encoding), True)
+        input = _fixencoding(input, str(encoding), True)
     if encoding == "css":
         raise ValueError("css not allowed as encoding name")
     encoder = codecs.getencoder(encoding)
@@ -247,7 +247,7 @@ if hasattr(codecs, "IncrementalDecoder"):
             # Store ``errors`` somewhere else,
             # because we have to hide it in a property
             self._errors = errors
-            self.buffer = u"".encode()
+            self.buffer = "".encode()
             self.headerfixed = False
 
         def iterdecode(self, input):
@@ -272,7 +272,7 @@ if hasattr(codecs, "IncrementalDecoder"):
                     (encoding, explicit) = detectencoding_str(input, final)
                     if encoding is None: # no encoding determined yet
                         self.buffer = input # retry the complete input on the next call
-                        return u"" # no encoding determined yet, so no output
+                        return "" # no encoding determined yet, so no output
                     elif encoding == "css":
                         raise ValueError("css not allowed as encoding name")
                     if (explicit and not self.force) or self.encoding is None: # Take the encoding from the input
@@ -288,18 +288,18 @@ if hasattr(codecs, "IncrementalDecoder"):
             encoding = self.encoding
             if encoding.replace("_", "-").lower() == "utf-8-sig":
                 encoding = "utf-8"
-            newoutput = _fixencoding(output, unicode(encoding), final)
+            newoutput = _fixencoding(output, str(encoding), final)
             if newoutput is None:
                 # retry fixing the @charset rule (but keep the decoded stuff)
                 self.buffer = output
-                return u""
+                return ""
             self.headerfixed = True
             return newoutput
 
         def reset(self):
             codecs.IncrementalDecoder.reset(self)
             self.decoder = None
-            self.buffer = u"".encode()
+            self.buffer = "".encode()
             self.headerfixed = False
 
         def _geterrors(self):
@@ -340,14 +340,14 @@ if hasattr(codecs, "IncrementalEncoder"):
             # Store ``errors`` somewhere else,
             # because we have to hide it in a property
             self._errors = errors
-            self.buffer = u""
+            self.buffer = ""
 
         def iterencode(self, input):
             for part in input:
                 result = self.encode(part, False)
                 if result:
                     yield result
-            result = self.encode(u"", True)
+            result = self.encode("", True)
             if result:
                 yield result
 
@@ -359,7 +359,7 @@ if hasattr(codecs, "IncrementalEncoder"):
                     encoding = self.encoding
                     if encoding.replace("_", "-").lower() == "utf-8-sig":
                         encoding = "utf-8"
-                    newinput = _fixencoding(input, unicode(encoding), final)
+                    newinput = _fixencoding(input, str(encoding), final)
                     if newinput is None: # @charset rule incomplete => Retry next time
                         self.buffer = input
                         return ""
@@ -373,9 +373,9 @@ if hasattr(codecs, "IncrementalEncoder"):
                     info = codecs.lookup(self.encoding)
                     encoding = self.encoding
                     if self.encoding.replace("_", "-").lower() == "utf-8-sig":
-                        input = _fixencoding(input, u"utf-8", True)
+                        input = _fixencoding(input, "utf-8", True)
                     self.encoder = info.incrementalencoder(self._errors)
-                    self.buffer = u""
+                    self.buffer = ""
                 else:
                     self.buffer = input
                     return ""
@@ -384,7 +384,7 @@ if hasattr(codecs, "IncrementalEncoder"):
         def reset(self):
             codecs.IncrementalEncoder.reset(self)
             self.encoder = None
-            self.buffer = u""
+            self.buffer = ""
 
         def _geterrors(self):
             return self._errors
@@ -420,7 +420,7 @@ class StreamWriter(codecs.StreamWriter):
         self.streamwriter = None
         self.encoding = encoding
         self._errors = errors
-        self.buffer = u""
+        self.buffer = ""
 
     def encode(self, input, errors='strict'):
         li = len(input)
@@ -432,7 +432,7 @@ class StreamWriter(codecs.StreamWriter):
                 encoding = self.encoding
                 if encoding.replace("_", "-").lower() == "utf-8-sig":
                     encoding = "utf-8"
-                newinput = _fixencoding(input, unicode(encoding), False)
+                newinput = _fixencoding(input, str(encoding), False)
                 if newinput is None: # @charset rule incomplete => Retry next time
                     self.buffer = input
                     return ("", 0)
@@ -446,8 +446,8 @@ class StreamWriter(codecs.StreamWriter):
                 self.streamwriter = codecs.getwriter(self.encoding)(self.stream, self._errors)
                 encoding = self.encoding
                 if self.encoding.replace("_", "-").lower() == "utf-8-sig":
-                    input = _fixencoding(input, u"utf-8", True)
-                self.buffer = u""
+                    input = _fixencoding(input, "utf-8", True)
+                self.buffer = ""
             else:
                 self.buffer = input
                 return ("", 0)
@@ -478,7 +478,7 @@ class StreamReader(codecs.StreamReader):
             if self.encoding is None or not self.force:
                 (encoding, explicit) = detectencoding_str(input, False)
                 if encoding is None: # no encoding determined yet
-                    return (u"", 0) # no encoding determined yet, so no output
+                    return ("", 0) # no encoding determined yet, so no output
                 elif encoding == "css":
                     raise ValueError("css not allowed as encoding name")
                 if (explicit and not self.force) or self.encoding is None: # Take the encoding from the input
@@ -489,11 +489,11 @@ class StreamReader(codecs.StreamReader):
             encoding = self.encoding
             if encoding.replace("_", "-").lower() == "utf-8-sig":
                 encoding = "utf-8"
-            newoutput = _fixencoding(output, unicode(encoding), False)
+            newoutput = _fixencoding(output, str(encoding), False)
             if newoutput is not None:
                 self.streamreader = streamreader
                 return (newoutput, consumed)
-            return (u"", 0) # we will create a new streamreader on the next call
+            return ("", 0) # we will create a new streamreader on the next call
         return self.streamreader.decode(input, errors)
 
     def _geterrors(self):
@@ -558,7 +558,7 @@ else:
             if len(input) < 3 and codecs.BOM_UTF8.startswith(input):
                 # not enough data to decide if this is a BOM
                 # => try again on the next call
-                return (u"", 0)
+                return ("", 0)
             self.decode = codecs.utf_8_decode
             return utf8sig_decode(input, errors)
 
@@ -579,6 +579,6 @@ codecs.register(search_function)
 def cssescape(exc):
     if not isinstance(exc, UnicodeEncodeError):
         raise TypeError("don't know how to handle %r" % exc)
-    return (u"".join(u"\\%06x" % ord(c) for c in exc.object[exc.start:exc.end]), exc.end)
+    return ("".join("\\%06x" % ord(c) for c in exc.object[exc.start:exc.end]), exc.end)
 
 codecs.register_error("cssescape", cssescape)
diff --git a/src/cssutils/_fetch.py b/src/cssutils/_fetch.py
index e9096ee..822d987 100644
--- a/src/cssutils/_fetch.py
+++ b/src/cssutils/_fetch.py
@@ -6,8 +6,8 @@ __version__ = '$Id: tokenize2.py 1547 2008-12-10 20:42:26Z cthedot $'
 import cssutils
 from cssutils import VERSION
 import encutils
-import errorhandler
-import urllib2
+from . import errorhandler
+import urllib.request, urllib.error, urllib.parse
 
 log = errorhandler.ErrorHandler()
 
@@ -18,28 +18,28 @@ def _defaultFetcher(url):
     Returns ``(encoding, string)`` or ``None``
     """
     try:
-        request = urllib2.Request(url)
+        request = urllib.request.Request(url)
         request.add_header('User-agent',
                            'cssutils %s (http://www.cthedot.de/cssutils/)' % VERSION)
-        res = urllib2.urlopen(request)
-    except urllib2.HTTPError, e:
+        res = urllib.request.urlopen(request)
+    except urllib.error.HTTPError as e:
         # http error, e.g. 404, e can be raised
-        log.warn(u'HTTPError opening url=%s: %s %s' %
+        log.warn('HTTPError opening url=%s: %s %s' %
                           (url, e.code, e.msg), error=e)
-    except urllib2.URLError, e:
+    except urllib.error.URLError as e:
         # URLError like mailto: or other IO errors, e can be raised
-        log.warn(u'URLError, %s' % e.reason, error=e)
-    except OSError, e:
+        log.warn('URLError, %s' % e.reason, error=e)
+    except OSError as e:
         # e.g if file URL and not found
         log.warn(e, error=OSError)
-    except ValueError, e:
+    except ValueError as e:
         # invalid url, e.g. "1"
-        log.warn(u'ValueError, %s' % e.args[0], error=ValueError)
+        log.warn('ValueError, %s' % e.args[0], error=ValueError)
     else:
         if res:
             mimeType, encoding = encutils.getHTTPInfo(res)
-            if mimeType != u'text/css':
-                log.error(u'Expected "text/css" mime type for url=%r but found: %r' %
+            if mimeType != 'text/css':
+                log.error('Expected "text/css" mime type for url=%r but found: %r' %
                                   (url, mimeType), error=ValueError)
             content = res.read()
             if hasattr(res, 'close'):
diff --git a/src/cssutils/_fetchgae.py b/src/cssutils/_fetchgae.py
index 7760ac6..fb708e9 100644
--- a/src/cssutils/_fetchgae.py
+++ b/src/cssutils/_fetchgae.py
@@ -6,8 +6,8 @@ __version__ = '$Id: tokenize2.py 1547 2008-12-10 20:42:26Z cthedot $'
 # raises ImportError of not on GAE
 from google.appengine.api import urlfetch
 import cgi
-import errorhandler
-import util
+from . import errorhandler
+from . import util
 
 log = errorhandler.ErrorHandler()
 
@@ -46,8 +46,8 @@ def _defaultFetcher(url):
     #from google.appengine.api import urlfetch
     try:
         r = urlfetch.fetch(url, method=urlfetch.GET)
-    except urlfetch.Error, e:
-        log.warn(u'Error opening url=%r: %s' % (url, e),
+    except urlfetch.Error as e:
+        log.warn('Error opening url=%r: %s' % (url, e),
                           error=IOError)
     else:
         if r.status_code == 200:
@@ -58,11 +58,11 @@ def _defaultFetcher(url):
                 encoding = params['charset']
             except KeyError:
                 encoding = None
-            if mimetype != u'text/css':
-                log.error(u'Expected "text/css" mime type for url %r but found: %r' % 
+            if mimetype != 'text/css':
+                log.error('Expected "text/css" mime type for url %r but found: %r' %
                               (url, mimetype), error=ValueError)
             return encoding, r.content
         else:
             # TODO: 301 etc
-            log.warn(u'Error opening url=%r: HTTP status %s' % 
+            log.warn('Error opening url=%r: HTTP status %s' %
                               (url, r.status_code), error=IOError)
diff --git a/src/cssutils/codec.py b/src/cssutils/codec.py
index c694e1f..03ee076 100644
--- a/src/cssutils/codec.py
+++ b/src/cssutils/codec.py
@@ -7,10 +7,10 @@ __version__ = '$Id: util.py 1114 2008-03-05 13:22:59Z cthedot $'
 import sys
 
 if sys.version_info < (3,):
-    from _codec2 import *
+    from ._codec2 import *
     # for tests
-    from _codec2 import _fixencoding
+    from ._codec2 import _fixencoding
 else:
-    from _codec3 import *
+    from ._codec3 import *
     # for tests
-    from _codec3 import _fixencoding
+    from ._codec3 import _fixencoding
diff --git a/src/cssutils/css/__init__.py b/src/cssutils/css/__init__.py
index 4cc4a90..d70a630 100644
--- a/src/cssutils/css/__init__.py
+++ b/src/cssutils/css/__init__.py
@@ -57,24 +57,24 @@ __all__ = [
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from cssstylesheet import *
-from cssrulelist import *
-from cssrule import *
-from csscomment import *
-from csscharsetrule import *
-from cssfontfacerule import *
-from cssimportrule import *
-from cssmediarule import *
-from cssnamespacerule import *
-from csspagerule import *
-from marginrule import *
-from cssstylerule import *
-from cssvariablesrule import *
-from cssunknownrule import *
-from selector import *
-from selectorlist import *
-from cssstyledeclaration import *
-from cssvariablesdeclaration import *
-from property import *
+from .cssstylesheet import *
+from .cssrulelist import *
+from .cssrule import *
+from .csscomment import *
+from .csscharsetrule import *
+from .cssfontfacerule import *
+from .cssimportrule import *
+from .cssmediarule import *
+from .cssnamespacerule import *
+from .csspagerule import *
+from .marginrule import *
+from .cssstylerule import *
+from .cssvariablesrule import *
+from .cssunknownrule import *
+from .selector import *
+from .selectorlist import *
+from .cssstyledeclaration import *
+from .cssvariablesdeclaration import *
+from .property import *
 #from cssvalue import *
-from value import *
+from .value import *
diff --git a/src/cssutils/css/csscharsetrule.py b/src/cssutils/css/csscharsetrule.py
index fa6b7c4..1e0e9dc 100644
--- a/src/cssutils/css/csscharsetrule.py
+++ b/src/cssutils/css/csscharsetrule.py
@@ -4,7 +4,7 @@ __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
 import codecs
-import cssrule
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -57,14 +57,14 @@ class CSSCharsetRule(cssrule.CSSRule):
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(encoding=%r)" % (
-                self.__class__.__name__, 
+        return "cssutils.css.%s(encoding=%r)" % (
+                self.__class__.__name__,
                 self.encoding)
 
     def __str__(self):
-        return u"<cssutils.css.%s object encoding=%r at 0x%x>" % (
-                self.__class__.__name__, 
-                self.encoding, 
+        return "<cssutils.css.%s object encoding=%r at 0x%x>" % (
+                self.__class__.__name__,
+                self.encoding,
                 id(self))
 
     def _getCssText(self):
@@ -95,7 +95,7 @@ class CSSCharsetRule(cssrule.CSSRule):
         
         if self._type(self._nexttoken(tokenizer)) != self._prods.CHARSET_SYM: 
             wellformed = False
-            self._log.error(u'CSSCharsetRule must start with "@charset "',
+            self._log.error('CSSCharsetRule must start with "@charset "',
                             error=xml.dom.InvalidModificationErr)
         
         encodingtoken = self._nexttoken(tokenizer)
@@ -103,21 +103,21 @@ class CSSCharsetRule(cssrule.CSSRule):
         encoding = self._stringtokenvalue(encodingtoken)
         if self._prods.STRING != encodingtype or not encoding:
             wellformed = False
-            self._log.error(u'CSSCharsetRule: no encoding found; %r.' % 
+            self._log.error('CSSCharsetRule: no encoding found; %r.' %
                             self._valuestr(cssText))
             
         semicolon = self._tokenvalue(self._nexttoken(tokenizer))
         EOFtype = self._type(self._nexttoken(tokenizer))
-        if u';' != semicolon or EOFtype not in ('EOF', None):
+        if ';' != semicolon or EOFtype not in ('EOF', None):
             wellformed = False
-            self._log.error(u'CSSCharsetRule: Syntax Error: %r.' % 
+            self._log.error('CSSCharsetRule: Syntax Error: %r.' %
                             self._valuestr(cssText))
         
         if wellformed:
             self.encoding = encoding
             
     cssText = property(fget=_getCssText, fset=_setCssText,
-                       doc=u"(DOM) The parsable textual representation.")
+                       doc="(DOM) The parsable textual representation.")
 
     def _setEncoding(self, encoding):
         """
@@ -138,22 +138,22 @@ class CSSCharsetRule(cssrule.CSSRule):
 
         if not encodingtoken or unexpected or\
            self._prods.IDENT != self._type(encodingtoken):
-            self._log.error(u'CSSCharsetRule: Syntax Error in encoding value '
-                            u'%r.' % encoding)
+            self._log.error('CSSCharsetRule: Syntax Error in encoding value '
+                            '%r.' % encoding)
         else:
             try:
                 codecs.lookup(encoding)
             except LookupError:
-                self._log.error(u'CSSCharsetRule: Unknown (Python) encoding %r.'
+                self._log.error('CSSCharsetRule: Unknown (Python) encoding %r.'
                                 % encoding)
             else:
                 self._encoding = encoding.lower()
 
     encoding = property(lambda self: self._encoding, _setEncoding,
-        doc=u"(DOM)The encoding information used in this @charset rule.")
+        doc="(DOM)The encoding information used in this @charset rule.")
 
     type = property(lambda self: self.CHARSET_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
 
     wellformed = property(lambda self: bool(self.encoding))
diff --git a/src/cssutils/css/csscomment.py b/src/cssutils/css/csscomment.py
index 311df0f..0f706e9 100644
--- a/src/cssutils/css/csscomment.py
+++ b/src/cssutils/css/csscomment.py
@@ -7,7 +7,7 @@ __all__ = ['CSSComment']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-import cssrule
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -31,12 +31,12 @@ class CSSComment(cssrule.CSSRule):
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(cssText=%r)" % (
+        return "cssutils.css.%s(cssText=%r)" % (
                 self.__class__.__name__, 
                 self.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object cssText=%r at 0x%x>" % (
+        return "<cssutils.css.%s object cssText=%r at 0x%x>" % (
                 self.__class__.__name__, 
                 self.cssText, 
                 id(self))
@@ -70,18 +70,18 @@ class CSSComment(cssrule.CSSRule):
         if not commenttoken or\
            self._type(commenttoken) != self._prods.COMMENT or\
            unexpected:
-            self._log.error(u'CSSComment: Not a CSSComment: %r' %
+            self._log.error('CSSComment: Not a CSSComment: %r' %
                 self._valuestr(cssText),
                 error=xml.dom.InvalidModificationErr)
         else:
             self._cssText = self._tokenvalue(commenttoken)
 
     cssText = property(_getCssText, _setCssText,
-        doc=u"The parsable textual representation of this rule.")
+        doc="The parsable textual representation of this rule.")
 
     type = property(lambda self: self.COMMENT, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
     
     # constant but needed:
     wellformed = property(lambda self: True)
diff --git a/src/cssutils/css/cssfontfacerule.py b/src/cssutils/css/cssfontfacerule.py
index 621bcb8..dbc3142 100644
--- a/src/cssutils/css/cssfontfacerule.py
+++ b/src/cssutils/css/cssfontfacerule.py
@@ -7,8 +7,8 @@ __all__ = ['CSSFontFaceRule']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from cssstyledeclaration import CSSStyleDeclaration
-import cssrule
+from .cssstyledeclaration import CSSStyleDeclaration
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -41,7 +41,7 @@ class CSSFontFaceRule(cssrule.CSSRule):
         """
         super(CSSFontFaceRule, self).__init__(parentRule=parentRule, 
                                               parentStyleSheet=parentStyleSheet)
-        self._atkeyword = u'@font-face'
+        self._atkeyword = '@font-face'
             
         if style:
             self.style = style
@@ -51,12 +51,12 @@ class CSSFontFaceRule(cssrule.CSSRule):
         self._readonly = readonly
         
     def __repr__(self):
-        return u"cssutils.css.%s(style=%r)" % (
+        return "cssutils.css.%s(style=%r)" % (
                 self.__class__.__name__, 
                 self.style.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object style=%r valid=%r at 0x%x>" % (
+        return "<cssutils.css.%s object style=%r valid=%r at 0x%x>" % (
                 self.__class__.__name__, 
                 self.style.cssText, 
                 self.valid, 
@@ -86,7 +86,7 @@ class CSSFontFaceRule(cssrule.CSSRule):
         tokenizer = self._tokenize2(cssText)
         attoken = self._nexttoken(tokenizer, None)
         if self._type(attoken) != self._prods.FONT_FACE_SYM:
-            self._log.error(u'CSSFontFaceRule: No CSSFontFaceRule found: %s' %
+            self._log.error('CSSFontFaceRule: No CSSFontFaceRule found: %s' %
                 self._valuestr(cssText),
                 error=xml.dom.InvalidModificationErr)
         else:
@@ -96,10 +96,10 @@ class CSSFontFaceRule(cssrule.CSSRule):
             beforetokens, brace = self._tokensupto2(tokenizer, 
                                                     blockstartonly=True,
                                                     separateEnd=True)            
-            if self._tokenvalue(brace) != u'{':
+            if self._tokenvalue(brace) != '{':
                 ok = False
-                self._log.error(u'CSSFontFaceRule: No start { of style '
-                                u'declaration found: %r' 
+                self._log.error('CSSFontFaceRule: No start { of style '
+                                'declaration found: %r'
                                 % self._valuestr(cssText), brace)
             
             # parse stuff before { which should be comments and S only
@@ -117,16 +117,16 @@ class CSSFontFaceRule(cssrule.CSSRule):
 
             val, type_ = self._tokenvalue(braceorEOFtoken),\
                          self._type(braceorEOFtoken)
-            if val != u'}' and type_ != 'EOF':
+            if val != '}' and type_ != 'EOF':
                 ok = False
-                self._log.error(u'CSSFontFaceRule: No "}" after style '
-                                u'declaration found: %r'
+                self._log.error('CSSFontFaceRule: No "}" after style '
+                                'declaration found: %r'
                                 % self._valuestr(cssText))
                 
             nonetoken = self._nexttoken(tokenizer)
             if nonetoken:
                 ok = False
-                self._log.error(u'CSSFontFaceRule: Trailing content found.',
+                self._log.error('CSSFontFaceRule: Trailing content found.',
                                 token=nonetoken)
 
             if 'EOF' == type_:
@@ -142,8 +142,8 @@ class CSSFontFaceRule(cssrule.CSSRule):
                 self.style = newStyle                 
                 
     cssText = property(_getCssText, _setCssText,
-                       doc=u"(DOM) The parsable textual representation of this "
-                           u"rule.")
+                       doc="(DOM) The parsable textual representation of this "
+                           "rule.")
 
     def _setStyle(self, style):
         """
@@ -151,19 +151,19 @@ class CSSFontFaceRule(cssrule.CSSRule):
             a CSSStyleDeclaration or string
         """
         self._checkReadonly()
-        if isinstance(style, basestring):
+        if isinstance(style, str):
             self._style = CSSStyleDeclaration(cssText=style, parentRule=self)
         else:
             style._parentRule = self
             self._style = style
 
     style = property(lambda self: self._style, _setStyle,
-                     doc=u"(DOM) The declaration-block of this rule set, "
-                         u"a :class:`~cssutils.css.CSSStyleDeclaration`.")
+                     doc="(DOM) The declaration-block of this rule set, "
+                         "a :class:`~cssutils.css.CSSStyleDeclaration`.")
 
     type = property(lambda self: self.FONT_FACE_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
 
     def _getValid(self):
         needed = ['font-family', 'src']
@@ -177,8 +177,8 @@ class CSSFontFaceRule(cssrule.CSSRule):
         return not bool(needed)
 
     valid = property(_getValid, 
-                     doc=u"CSSFontFace is valid if properties `font-family` "
-                         u"and `src` are set and all properties are valid.")
+                     doc="CSSFontFace is valid if properties `font-family` "
+                         "and `src` are set and all properties are valid.")
     
     # constant but needed:
     wellformed = property(lambda self: True)
diff --git a/src/cssutils/css/cssimportrule.py b/src/cssutils/css/cssimportrule.py
index 59fe256..a83a561 100644
--- a/src/cssutils/css/cssimportrule.py
+++ b/src/cssutils/css/cssimportrule.py
@@ -4,10 +4,10 @@ __all__ = ['CSSImportRule']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-import cssrule
+from . import cssrule
 import cssutils
 import os
-import urlparse
+import urllib.parse
 import xml.dom
 
 class CSSImportRule(cssrule.CSSRule):
@@ -37,7 +37,7 @@ class CSSImportRule(cssrule.CSSRule):
         """
         super(CSSImportRule, self).__init__(parentRule=parentRule,
                                             parentStyleSheet=parentStyleSheet)
-        self._atkeyword = u'@import'
+        self._atkeyword = '@import'
         self._styleSheet = None
 
         # string or uri used for reserialization
@@ -55,7 +55,7 @@ class CSSImportRule(cssrule.CSSRule):
             self.media = mediaText
         else:
             # must be all for @import
-            self.media = cssutils.stylesheets.MediaList(mediaText=u'all')
+            self.media = cssutils.stylesheets.MediaList(mediaText='all')
         # 2. name
         self.name = name
         # 3. href and styleSheet
@@ -68,7 +68,7 @@ class CSSImportRule(cssrule.CSSRule):
             mediaText = self.media.mediaText
         else:
             mediaText = None
-        return u"cssutils.css.%s(href=%r, mediaText=%r, name=%r)" % (
+        return "cssutils.css.%s(href=%r, mediaText=%r, name=%r)" % (
                 self.__class__.__name__,
                 self.href, 
                 self.media.mediaText, 
@@ -79,14 +79,14 @@ class CSSImportRule(cssrule.CSSRule):
             mediaText = self.media.mediaText
         else:
             mediaText = None
-        return u"<cssutils.css.%s object href=%r mediaText=%r name=%r at 0x%x>"\
+        return "<cssutils.css.%s object href=%r mediaText=%r name=%r at 0x%x>"\
                % (self.__class__.__name__, 
                   self.href, 
                   mediaText, 
                   self.name, 
                   id(self))
 
-    _usemedia = property(lambda self: self.media.mediaText not in (u'', u'all'),
+    _usemedia = property(lambda self: self.media.mediaText not in ('', 'all'),
                          doc="if self.media is used (or simply empty)")
 
     def _getCssText(self):
@@ -112,7 +112,7 @@ class CSSImportRule(cssrule.CSSRule):
         tokenizer = self._tokenize2(cssText)
         attoken = self._nexttoken(tokenizer, None)
         if self._type(attoken) != self._prods.IMPORT_SYM:
-            self._log.error(u'CSSImportRule: No CSSImportRule found: %s' %
+            self._log.error('CSSImportRule: No CSSImportRule found: %s' %
                             self._valuestr(cssText),
                             error=xml.dom.InvalidModificationErr)
         else:
@@ -144,7 +144,7 @@ class CSSImportRule(cssrule.CSSRule):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'CSSImportRule: Unexpected string.', token)
+                        'CSSImportRule: Unexpected string.', token)
                     return expected
 
             def _uri(expected, seq, token, tokenizer=None):
@@ -158,7 +158,7 @@ class CSSImportRule(cssrule.CSSRule):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'CSSImportRule: Unexpected URI.', token)
+                        'CSSImportRule: Unexpected URI.', token)
                     return expected
 
             def _ident(expected, seq, token, tokenizer=None):
@@ -170,10 +170,10 @@ class CSSImportRule(cssrule.CSSRule):
 
                     last = mediatokens.pop() # retrieve ;
                     lastval, lasttyp = self._tokenvalue(last), self._type(last)
-                    if lastval != u';' and lasttyp not in ('EOF', 
+                    if lastval != ';' and lasttyp not in ('EOF',
                                                            self._prods.STRING):
                         new['wellformed'] = False
-                        self._log.error(u'CSSImportRule: No ";" found: %s' %
+                        self._log.error('CSSImportRule: No ";" found: %s' %
                                         self._valuestr(cssText), token=token)
 
                     newMedia = cssutils.stylesheets.MediaList(parentRule=self)
@@ -183,7 +183,7 @@ class CSSImportRule(cssrule.CSSRule):
                         seq.append(newMedia, 'media')
                     else:
                         new['wellformed'] = False
-                        self._log.error(u'CSSImportRule: Invalid MediaList: %s' %
+                        self._log.error('CSSImportRule: Invalid MediaList: %s' %
                                         self._valuestr(cssText), token=token)
 
                     if lasttyp == self._prods.STRING:
@@ -193,18 +193,18 @@ class CSSImportRule(cssrule.CSSRule):
                         return 'EOF' # ';' is token "last"
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'CSSImportRule: Unexpected ident.', token)
+                    self._log.error('CSSImportRule: Unexpected ident.', token)
                     return expected
 
             def _char(expected, seq, token, tokenizer=None):
                 # final ;
                 val = self._tokenvalue(token)
-                if expected.endswith(';') and u';' == val:
+                if expected.endswith(';') and ';' == val:
                     return 'EOF'
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'CSSImportRule: Unexpected char.', token)
+                        'CSSImportRule: Unexpected char.', token)
                     return expected
 
             # import : IMPORT_SYM S* [STRING|URI]
@@ -226,12 +226,12 @@ class CSSImportRule(cssrule.CSSRule):
             # post conditions
             if not new['href']:
                 ok = False
-                self._log.error(u'CSSImportRule: No href found: %s' %
+                self._log.error('CSSImportRule: No href found: %s' %
                     self._valuestr(cssText))
 
             if expected != 'EOF':
                 ok = False
-                self._log.error(u'CSSImportRule: No ";" found: %s' %
+                self._log.error('CSSImportRule: No ";" found: %s' %
                     self._valuestr(cssText))
 
             # set all
@@ -246,7 +246,7 @@ class CSSImportRule(cssrule.CSSRule):
                     self.media = new['media']
                 else:
                     # must be all for @import
-                    self.media = cssutils.stylesheets.MediaList(mediaText=u'all')
+                    self.media = cssutils.stylesheets.MediaList(mediaText='all')
 
                 # needs new self.media
                 self.href = new['href']
@@ -278,7 +278,7 @@ class CSSImportRule(cssrule.CSSRule):
                 # use cwd instead
                 parentHref = cssutils.helper.path2url(os.getcwd()) + '/'
                 
-            fullhref = urlparse.urljoin(parentHref, self.href)
+            fullhref = urllib.parse.urljoin(parentHref, self.href)
 
             # all possible exceptions are ignored
             try:
@@ -306,9 +306,9 @@ class CSSImportRule(cssrule.CSSRule):
                                             encodingOverride=encodingOverride,
                                             encoding=encoding)
 
-            except (OSError, IOError, ValueError), e:
-                self._log.warn(u'CSSImportRule: While processing imported '
-                               u'style sheet href=%s: %r'
+            except (OSError, IOError, ValueError) as e:
+                self._log.warn('CSSImportRule: While processing imported '
+                               'style sheet href=%s: %r'
                                % (self.href, e), neverraise=True)
                 
             else:
@@ -319,7 +319,7 @@ class CSSImportRule(cssrule.CSSRule):
 
     _href = None # needs to be set 
     href = property(lambda self: self._href, _setHref,
-                    doc=u"Location of the style sheet to be imported.")
+                    doc="Location of the style sheet to be imported.")
 
     def _setMedia(self, media):
         """
@@ -327,7 +327,7 @@ class CSSImportRule(cssrule.CSSRule):
             a :class:`~cssutils.stylesheets.MediaList` or string
         """
         self._checkReadonly()
-        if isinstance(media, basestring):
+        if isinstance(media, str):
             self._media = cssutils.stylesheets.MediaList(mediaText=media, 
                                                          parentRule=self)
         else:
@@ -348,12 +348,12 @@ class CSSImportRule(cssrule.CSSRule):
                             self._media, 'media', None, None)
         
     media = property(lambda self: self._media, _setMedia,
-                     doc=u"(DOM) A list of media types for this rule "
-                         u"of type :class:`~cssutils.stylesheets.MediaList`.")
+                     doc="(DOM) A list of media types for this rule "
+                         "of type :class:`~cssutils.stylesheets.MediaList`.")
 
-    def _setName(self, name=u''):
+    def _setName(self, name=''):
         """Raises xml.dom.SyntaxErr if name is not a string."""
-        if name is None or isinstance(name, basestring):
+        if name is None or isinstance(name, str):
             # "" or '' handled as None
             if not name:
                 name = None
@@ -373,18 +373,18 @@ class CSSImportRule(cssrule.CSSRule):
                 self.styleSheet.title = name
                 
         else:
-            self._log.error(u'CSSImportRule: Not a valid name: %s' % name)
+            self._log.error('CSSImportRule: Not a valid name: %s' % name)
 
     name = property(lambda self: self._name, _setName,
-                    doc=u"An optional name for the imported sheet.")
+                    doc="An optional name for the imported sheet.")
 
     styleSheet = property(lambda self: self._styleSheet,
-                          doc=u"(readonly) The style sheet referred to by this "
-                              u"rule.")
+                          doc="(readonly) The style sheet referred to by this "
+                              "rule.")
 
     type = property(lambda self: self.IMPORT_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
 
     def _getWellformed(self):
         "Depending on if media is used at all."
diff --git a/src/cssutils/css/cssmediarule.py b/src/cssutils/css/cssmediarule.py
index e58af09..74187c3 100644
--- a/src/cssutils/css/cssmediarule.py
+++ b/src/cssutils/css/cssmediarule.py
@@ -3,7 +3,7 @@ __all__ = ['CSSMediaRule']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-import cssrule
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -29,7 +29,7 @@ class CSSMediaRule(cssrule.CSSRuleRules):
         """constructor"""
         super(CSSMediaRule, self).__init__(parentRule=parentRule, 
                                            parentStyleSheet=parentStyleSheet)
-        self._atkeyword = u'@media'
+        self._atkeyword = '@media'
         
         # 1. media 
         if mediaText:
@@ -41,12 +41,12 @@ class CSSMediaRule(cssrule.CSSRuleRules):
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(mediaText=%r)" % (
+        return "cssutils.css.%s(mediaText=%r)" % (
                 self.__class__.__name__,
                 self.media.mediaText)
         
     def __str__(self):
-        return u"<cssutils.css.%s object mediaText=%r at 0x%x>" % (
+        return "<cssutils.css.%s object mediaText=%r at 0x%x>" % (
                 self.__class__.__name__,
                 self.media.mediaText,
                 id(self))
@@ -90,7 +90,7 @@ class CSSMediaRule(cssrule.CSSRuleRules):
         tokenizer = self._tokenize2(cssText)
         attoken = self._nexttoken(tokenizer, None)
         if self._type(attoken) != self._prods.MEDIA_SYM:
-            self._log.error(u'CSSMediaRule: No CSSMediaRule found: %s' %
+            self._log.error('CSSMediaRule: No CSSMediaRule found: %s' %
                 self._valuestr(cssText),
                 error=xml.dom.InvalidModificationErr)
         
@@ -106,7 +106,7 @@ class CSSMediaRule(cssrule.CSSRuleRules):
             mediatokens, end = self._tokensupto2(tokenizer, 
                                                  mediaqueryendonly=True,
                                                  separateEnd=True)        
-            if u'{' == self._tokenvalue(end)\
+            if '{' == self._tokenvalue(end)\
                or self._prods.STRING == self._type(end):
                 self.media = cssutils.stylesheets.MediaList(parentRule=self)
                 # TODO: remove special case
@@ -130,13 +130,13 @@ class CSSMediaRule(cssrule.CSSRuleRules):
                                                    {})
                 if not wellformed:
                     ok = False
-                    self._log.error(u'CSSMediaRule: Syntax Error: %s' % 
+                    self._log.error('CSSMediaRule: Syntax Error: %s' %
                                     self._valuestr(cssText))
                     
 
             # check for {
-            if u'{' != self._tokenvalue(end):
-                self._log.error(u'CSSMediaRule: No "{" found: %s' % 
+            if '{' != self._tokenvalue(end):
+                self._log.error('CSSMediaRule: No "{" found: %s' %
                                 self._valuestr(cssText))
                 return
             
@@ -150,14 +150,14 @@ class CSSMediaRule(cssrule.CSSRuleRules):
                 # TODO: Not complete, add EOF to rule and } to @media
                 cssrulestokens.append(braceOrEOF)
                 braceOrEOF = ('CHAR', '}', 0, 0)
-                self._log.debug(u'CSSMediaRule: Incomplete, adding "}".', 
+                self._log.debug('CSSMediaRule: Incomplete, adding "}".',
                                 token=braceOrEOF, neverraise=True)
 
-            if u'}' != self._tokenvalue(braceOrEOF):
-                self._log.error(u'CSSMediaRule: No "}" found.', 
+            if '}' != self._tokenvalue(braceOrEOF):
+                self._log.error('CSSMediaRule: No "}" found.',
                                 token=braceOrEOF)
             elif nonetoken:
-                self._log.error(u'CSSMediaRule: Trailing content found.',
+                self._log.error('CSSMediaRule: Trailing content found.',
                                 token=nonetoken)
             else:                
                 # for closures: must be a mutable
@@ -187,9 +187,9 @@ class CSSMediaRule(cssrule.CSSRuleRules):
                     }
                     if atval in ('@charset ', '@font-face', '@import', 
                                  '@namespace', '@variables'):
-                        self._log.error(u'CSSMediaRule: This rule is not '
-                                        u'allowed in CSSMediaRule - ignored: '
-                                        u'%s.' % self._valuestr(tokens),
+                        self._log.error('CSSMediaRule: This rule is not '
+                                        'allowed in CSSMediaRule - ignored: '
+                                        '%s.' % self._valuestr(tokens),
                                         token = token, 
                                         error=xml.dom.HierarchyRequestErr)
                     elif atval in factories:
@@ -238,21 +238,21 @@ class CSSMediaRule(cssrule.CSSRuleRules):
                 self._cssRules = oldCssRules
                                             
     cssText = property(_getCssText, _setCssText,
-                       doc=u"(DOM) The parsable textual representation of this "
-                           u"rule.")
+                       doc="(DOM) The parsable textual representation of this "
+                           "rule.")
 
     def _setName(self, name):
-        if isinstance(name, basestring) or name is None:
+        if isinstance(name, str) or name is None:
             # "" or ''
             if not name:
                 name = None
 
             self._name = name
         else:
-            self._log.error(u'CSSImportRule: Not a valid name: %s' % name)
+            self._log.error('CSSImportRule: Not a valid name: %s' % name)
 
     name = property(lambda self: self._name, _setName,
-                    doc=u"An optional name for this media rule.")
+                    doc="An optional name for this media rule.")
 
     def _setMedia(self, media):
         """
@@ -260,7 +260,7 @@ class CSSMediaRule(cssrule.CSSRuleRules):
             a :class:`~cssutils.stylesheets.MediaList` or string
         """
         self._checkReadonly()
-        if isinstance(media, basestring):
+        if isinstance(media, str):
             self._media = cssutils.stylesheets.MediaList(mediaText=media, 
                                                          parentRule=self)
         else:
@@ -279,8 +279,8 @@ class CSSMediaRule(cssrule.CSSRuleRules):
 #                             self._media, 'media', None, None)
             
     media = property(lambda self: self._media, _setMedia,
-                     doc=u"(DOM) A list of media types for this rule "
-                         u"of type :class:`~cssutils.stylesheets.MediaList`.")
+                     doc="(DOM) A list of media types for this rule "
+                         "of type :class:`~cssutils.stylesheets.MediaList`.")
     
             
     def insertRule(self, rule, index=None):
@@ -297,7 +297,7 @@ class CSSMediaRule(cssrule.CSSRuleRules):
            isinstance(rule, cssutils.css.CSSImportRule) or \
            isinstance(rule, cssutils.css.CSSNamespaceRule) or \
            isinstance(rule, cssutils.css.MarginRule):
-            self._log.error(u'%s: This type of rule is not allowed here: %s' 
+            self._log.error('%s: This type of rule is not allowed here: %s'
                             % (self.__class__.__name__, rule.cssText),
                             error=xml.dom.HierarchyRequestErr)
             return
@@ -305,7 +305,7 @@ class CSSMediaRule(cssrule.CSSRuleRules):
         return self._finishInsertRule(rule, index)
 
     type = property(lambda self: self.MEDIA_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
 
     wellformed = property(lambda self: self.media.wellformed)
diff --git a/src/cssutils/css/cssnamespacerule.py b/src/cssutils/css/cssnamespacerule.py
index a2610fc..5813713 100644
--- a/src/cssutils/css/cssnamespacerule.py
+++ b/src/cssutils/css/cssnamespacerule.py
@@ -4,7 +4,7 @@ __all__ = ['CSSNamespaceRule']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-import cssrule
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -62,8 +62,8 @@ class CSSNamespaceRule(cssrule.CSSRule):
         """
         super(CSSNamespaceRule, self).__init__(parentRule=parentRule, 
                                                parentStyleSheet=parentStyleSheet)
-        self._atkeyword = u'@namespace'
-        self._prefix = u''
+        self._atkeyword = '@namespace'
+        self._prefix = ''
         self._namespaceURI = None
         
         if namespaceURI:
@@ -83,13 +83,13 @@ class CSSNamespaceRule(cssrule.CSSRule):
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(namespaceURI=%r, prefix=%r)" % (
+        return "cssutils.css.%s(namespaceURI=%r, prefix=%r)" % (
                 self.__class__.__name__,
                 self.namespaceURI,
                 self.prefix)
 
     def __str__(self):
-        return u"<cssutils.css.%s object namespaceURI=%r prefix=%r at 0x%x>" % (
+        return "<cssutils.css.%s object namespaceURI=%r prefix=%r at 0x%x>" % (
                 self.__class__.__name__,
                 self.namespaceURI,
                 self.prefix,
@@ -119,13 +119,13 @@ class CSSNamespaceRule(cssrule.CSSRule):
         tokenizer = self._tokenize2(cssText)
         attoken = self._nexttoken(tokenizer, None)
         if self._type(attoken) != self._prods.NAMESPACE_SYM:
-            self._log.error(u'CSSNamespaceRule: No CSSNamespaceRule found: %s' %
+            self._log.error('CSSNamespaceRule: No CSSNamespaceRule found: %s' %
                             self._valuestr(cssText),
                             error=xml.dom.InvalidModificationErr)
         else:
             # for closures: must be a mutable
             new = {'keyword': self._tokenvalue(attoken),
-                   'prefix': u'',
+                   'prefix': '',
                    'uri': None,
                    'wellformed': True
                    }
@@ -139,7 +139,7 @@ class CSSNamespaceRule(cssrule.CSSRule):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'CSSNamespaceRule: Unexpected ident.', token)
+                        'CSSNamespaceRule: Unexpected ident.', token)
                     return expected
 
             def _string(expected, seq, token, tokenizer=None):
@@ -152,7 +152,7 @@ class CSSNamespaceRule(cssrule.CSSRule):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'CSSNamespaceRule: Unexpected string.', token)
+                        'CSSNamespaceRule: Unexpected string.', token)
                     return expected
 
             def _uri(expected, seq, token, tokenizer=None):
@@ -165,18 +165,18 @@ class CSSNamespaceRule(cssrule.CSSRule):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'CSSNamespaceRule: Unexpected URI.', token)
+                        'CSSNamespaceRule: Unexpected URI.', token)
                     return expected
 
             def _char(expected, seq, token, tokenizer=None):
                 # final ;
                 val = self._tokenvalue(token)
-                if ';' == expected and u';' == val:
+                if ';' == expected and ';' == val:
                     return 'EOF'
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'CSSNamespaceRule: Unexpected char.', token)
+                        'CSSNamespaceRule: Unexpected char.', token)
                     return expected
 
             # "NAMESPACE_SYM S* [namespace_prefix S*]? [STRING|URI] S* ';' S*"
@@ -195,12 +195,12 @@ class CSSNamespaceRule(cssrule.CSSRule):
             # post conditions
             if new['uri'] is None:
                 wellformed = False
-                self._log.error(u'CSSNamespaceRule: No namespace URI found: %s'
+                self._log.error('CSSNamespaceRule: No namespace URI found: %s'
                                 % self._valuestr(cssText))
 
             if expected != 'EOF':
                 wellformed = False
-                self._log.error(u'CSSNamespaceRule: No ";" found: %s' %
+                self._log.error('CSSNamespaceRule: No ";" found: %s' %
                                 self._valuestr(cssText))
 
             # set all
@@ -211,8 +211,8 @@ class CSSNamespaceRule(cssrule.CSSRule):
                 self._setSeq(newseq)
 
     cssText = property(fget=_getCssText, fset=_setCssText,
-                       doc=u"(DOM) The parsable textual representation of this "
-                           u"rule.")
+                       doc="(DOM) The parsable textual representation of this "
+                           "rule.")
 
     def _setNamespaceURI(self, namespaceURI):
         """
@@ -230,7 +230,7 @@ class CSSNamespaceRule(cssrule.CSSRule):
             tempseq.append(namespaceURI, 'namespaceURI')
             self._setSeq(tempseq) # makes seq readonly!
         elif self._namespaceURI != namespaceURI:
-            self._log.error(u'CSSNamespaceRule: namespaceURI is readonly.',
+            self._log.error('CSSNamespaceRule: namespaceURI is readonly.',
                             error=xml.dom.NoModificationAllowedErr)
 
     namespaceURI = property(lambda self: self._namespaceURI, _setNamespaceURI,
@@ -261,12 +261,12 @@ class CSSNamespaceRule(cssrule.CSSRule):
         """
         self._checkReadonly()
         if not prefix:
-            prefix = u''
+            prefix = ''
         else:        
             tokenizer = self._tokenize2(prefix)
             prefixtoken = self._nexttoken(tokenizer, None)
             if not prefixtoken or self._type(prefixtoken) != self._prods.IDENT:
-                self._log.error(u'CSSNamespaceRule: No valid prefix "%s".' %
+                self._log.error('CSSNamespaceRule: No valid prefix "%s".' %
                                 self._valuestr(prefix),
                                 error=xml.dom.SyntaxErr)
                 return
@@ -285,11 +285,11 @@ class CSSNamespaceRule(cssrule.CSSRule):
         self._prefix = prefix
 
     prefix = property(lambda self: self._prefix, _setPrefix,
-                      doc=u"Prefix used for the defined namespace.")
+                      doc="Prefix used for the defined namespace.")
 
     type = property(lambda self: self.NAMESPACE_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
     
     wellformed = property(lambda self: self.namespaceURI is not None)
     
\ No newline at end of file
diff --git a/src/cssutils/css/csspagerule.py b/src/cssutils/css/csspagerule.py
index cc2f451..9910678 100644
--- a/src/cssutils/css/csspagerule.py
+++ b/src/cssutils/css/csspagerule.py
@@ -4,9 +4,9 @@ __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
 from itertools import chain
-from cssstyledeclaration import CSSStyleDeclaration
-from marginrule import MarginRule
-import cssrule
+from .cssstyledeclaration import CSSStyleDeclaration
+from .marginrule import MarginRule
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -64,7 +64,7 @@ class CSSPageRule(cssrule.CSSRuleRules):
         """
         super(CSSPageRule, self).__init__(parentRule=parentRule, 
                                           parentStyleSheet=parentStyleSheet)
-        self._atkeyword = u'@page'
+        self._atkeyword = '@page'
         self._specificity = (0, 0, 0)
         
         tempseq = self._tempSeq()
@@ -86,14 +86,14 @@ class CSSPageRule(cssrule.CSSRuleRules):
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(selectorText=%r, style=%r)" % (
+        return "cssutils.css.%s(selectorText=%r, style=%r)" % (
                 self.__class__.__name__, 
                 self.selectorText, 
                 self.style.cssText)
 
     def __str__(self):
-        return (u"<cssutils.css.%s object selectorText=%r specificity=%r "+
-               u"style=%r cssRules=%r at 0x%x>") % (
+        return ("<cssutils.css.%s object selectorText=%r specificity=%r "+
+               "style=%r cssRules=%r at 0x%x>") % (
                 self.__class__.__name__,
                 self.selectorText, 
                 self.specificity,
@@ -103,7 +103,7 @@ class CSSPageRule(cssrule.CSSRuleRules):
 
     def __contains__(self, margin):
         """Check if margin is set in the rule."""
-        return margin in self.keys()
+        return margin in list(self.keys())
     
     def keys(self):
         "Return list of all set margins (MarginRule)."
@@ -152,24 +152,24 @@ class CSSPageRule(cssrule.CSSRuleRules):
             # pseudo_page, :left, :right or :first
             val = self._tokenvalue(token)
             if not new['last-S'] and expected in ['page', ': or EOF']\
-               and u':' == val:
+               and ':' == val:
                 try:
-                    identtoken = tokenizer.next()
+                    identtoken = next(tokenizer)
                 except StopIteration:
                     self._log.error(
-                        u'CSSPageRule selectorText: No IDENT found.', token)
+                        'CSSPageRule selectorText: No IDENT found.', token)
                 else:
                     ival, ityp = self._tokenvalue(identtoken),\
                                  self._type(identtoken)
                     if self._prods.IDENT != ityp:
-                        self._log.error(u'CSSPageRule selectorText: Expected '
-                                        u'IDENT but found: %r' % ival, token)
+                        self._log.error('CSSPageRule selectorText: Expected '
+                                        'IDENT but found: %r' % ival, token)
                     else:                        
-                        if not ival in (u'first', u'left', u'right'):
-                            self._log.warn(u'CSSPageRule: Unknown @page '
-                                           u'selector: %r' 
-                                           % (u':'+ival,), neverraise=True)
-                        if ival == u'first':
+                        if not ival in ('first', 'left', 'right'):
+                            self._log.warn('CSSPageRule: Unknown @page '
+                                           'selector: %r'
+                                           % (':'+ival,), neverraise=True)
+                        if ival == 'first':
                             new['first'] = 1
                         else:
                             new['lr'] = 1
@@ -178,7 +178,7 @@ class CSSPageRule(cssrule.CSSRuleRules):
                 return expected
             else:
                 new['wellformed'] = False
-                self._log.error(u'CSSPageRule selectorText: Unexpected CHAR: %r'
+                self._log.error('CSSPageRule selectorText: Unexpected CHAR: %r'
                                 % val, token)
                 return expected
 
@@ -193,8 +193,8 @@ class CSSPageRule(cssrule.CSSRuleRules):
             ""
             val = self._tokenvalue(token)
             if 'page' == expected:
-                if self._normalize(val) == u'auto':
-                    self._log.error(u'CSSPageRule selectorText: Invalid pagename.',
+                if self._normalize(val) == 'auto':
+                    self._log.error('CSSPageRule selectorText: Invalid pagename.',
                                     token)
                 else:
                     new['name'] = 1
@@ -203,8 +203,8 @@ class CSSPageRule(cssrule.CSSRuleRules):
                 return ': or EOF'
             else:
                 new['wellformed'] = False
-                self._log.error(u'CSSPageRule selectorText: Unexpected IDENT: '
-                                u'%r' % val, token)
+                self._log.error('CSSPageRule selectorText: Unexpected IDENT: '
+                                '%r' % val, token)
                 return expected
 
         def COMMENT(expected, seq, token, tokenizer=None):
@@ -225,7 +225,7 @@ class CSSPageRule(cssrule.CSSRuleRules):
         # post conditions
         if expected == 'ident':
             self._log.error(
-                u'CSSPageRule selectorText: No valid selector: %r' %
+                'CSSPageRule selectorText: No valid selector: %r' %
                     self._valuestr(selectorText))
         
         return wellformed, newseq, (new['name'], new['first'], new['lr'])
@@ -288,7 +288,7 @@ class CSSPageRule(cssrule.CSSRuleRules):
         
         tokenizer = self._tokenize2(cssText)
         if self._type(self._nexttoken(tokenizer)) != self._prods.PAGE_SYM:
-            self._log.error(u'CSSPageRule: No CSSPageRule found: %s' %
+            self._log.error('CSSPageRule: No CSSPageRule found: %s' %
                             self._valuestr(cssText), 
                             error=xml.dom.InvalidModificationErr)
         else:
@@ -302,14 +302,14 @@ class CSSPageRule(cssrule.CSSRuleRules):
                                                              blockendonly=True,
                                                              separateEnd=True)
             nonetoken = self._nexttoken(tokenizer)
-            if self._tokenvalue(startbrace) != u'{':
+            if self._tokenvalue(startbrace) != '{':
                 ok = False
-                self._log.error(u'CSSPageRule: No start { of style declaration ' 
-                                u'found: %r' % 
+                self._log.error('CSSPageRule: No start { of style declaration '
+                                'found: %r' %
                                 self._valuestr(cssText), startbrace)
             elif nonetoken:
                 ok = False
-                self._log.error(u'CSSPageRule: Trailing content found.', 
+                self._log.error('CSSPageRule: Trailing content found.',
                                 token=nonetoken)
                 
             selok, newselseq, specificity = self.__parseSelectorText(selectortokens)
@@ -318,10 +318,10 @@ class CSSPageRule(cssrule.CSSRuleRules):
             val, type_ = self._tokenvalue(braceorEOFtoken),\
                          self._type(braceorEOFtoken)
                          
-            if val != u'}' and type_ != 'EOF':
+            if val != '}' and type_ != 'EOF':
                 ok = False
                 self._log.error(
-                    u'CSSPageRule: No "}" after style declaration found: %r' %
+                    'CSSPageRule: No "}" after style declaration found: %r' %
                     self._valuestr(cssText))
             else:
                 if 'EOF' == type_:
@@ -343,7 +343,7 @@ class CSSPageRule(cssrule.CSSRuleRules):
                     self.cssRules.append(r)
                 
     cssText = property(_getCssText, _setCssText,
-        doc=u"(DOM) The parsable textual representation of this rule.")
+        doc="(DOM) The parsable textual representation of this rule.")
 
 
     def _getSelectorText(self):
@@ -377,8 +377,8 @@ class CSSPageRule(cssrule.CSSRuleRules):
             self._specificity = specificity
 
     selectorText = property(_getSelectorText, _setSelectorText,
-                            doc=u"(DOM) The parsable textual representation of "
-                                u"the page selector for the rule.")
+                            doc="(DOM) The parsable textual representation of "
+                                "the page selector for the rule.")
 
     def _setStyle(self, style):
         """
@@ -386,15 +386,15 @@ class CSSPageRule(cssrule.CSSRuleRules):
             a CSSStyleDeclaration or string
         """
         self._checkReadonly()
-        if isinstance(style, basestring):
+        if isinstance(style, str):
             self._style = CSSStyleDeclaration(cssText=style, parentRule=self)
         else:
             style._parentRule = self
             self._style = style
             
     style = property(lambda self: self._style, _setStyle,
-                     doc=u"(DOM) The declaration-block of this rule set, "
-                         u"a :class:`~cssutils.css.CSSStyleDeclaration`.")
+                     doc="(DOM) The declaration-block of this rule set, "
+                         "a :class:`~cssutils.css.CSSStyleDeclaration`.")
 
 
     def insertRule(self, rule, index=None):
@@ -412,7 +412,7 @@ class CSSPageRule(cssrule.CSSRuleRules):
            isinstance(rule, cssutils.css.CSSNamespaceRule) or \
            isinstance(rule, CSSPageRule) or \
            isinstance(rule, cssutils.css.CSSMediaRule):
-            self._log.error(u'%s: This type of rule is not allowed here: %s' 
+            self._log.error('%s: This type of rule is not allowed here: %s'
                             % (self.__class__.__name__, rule.cssText),
                             error=xml.dom.HierarchyRequestErr)
             return
@@ -420,7 +420,7 @@ class CSSPageRule(cssrule.CSSRuleRules):
         return self._finishInsertRule(rule, index)
 
     specificity = property(lambda self: self._specificity, 
-                           doc=u"""Specificity of this page rule (READONLY). 
+                           doc="""Specificity of this page rule (READONLY).
 Tuple of (f, g, h) where: 
 
  - if the page selector has a named page, f=1; else f=0
@@ -429,8 +429,8 @@ Tuple of (f, g, h) where:
 """)
 
     type = property(lambda self: self.PAGE_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
     
     # constant but needed:
-    wellformed = property(lambda self: True)
\ No newline at end of file
+    wellformed = property(lambda self: True)
diff --git a/src/cssutils/css/cssrule.py b/src/cssutils/css/cssrule.py
index 1d3ab6f..981f2b8 100644
--- a/src/cssutils/css/cssrule.py
+++ b/src/cssutils/css/cssrule.py
@@ -46,17 +46,17 @@ class CSSRule(cssutils.util.Base2):
     """:class:`cssutils.css.MarginRule` - experimental rule
     not in the offical spec"""
 
-    _typestrings = {UNKNOWN_RULE: u'UNKNOWN_RULE', 
-                    STYLE_RULE: u'STYLE_RULE',
-                    CHARSET_RULE: u'CHARSET_RULE', 
-                    IMPORT_RULE: u'IMPORT_RULE',
-                    MEDIA_RULE: u'MEDIA_RULE', 
-                    FONT_FACE_RULE: u'FONT_FACE_RULE', 
-                    PAGE_RULE: u'PAGE_RULE',                     
-                    NAMESPACE_RULE: u'NAMESPACE_RULE',
-                    COMMENT: u'COMMENT',
-                    VARIABLES_RULE: u'VARIABLES_RULE',
-                    MARGIN_RULE: u'MARGIN_RULE'
+    _typestrings = {UNKNOWN_RULE: 'UNKNOWN_RULE',
+                    STYLE_RULE: 'STYLE_RULE',
+                    CHARSET_RULE: 'CHARSET_RULE',
+                    IMPORT_RULE: 'IMPORT_RULE',
+                    MEDIA_RULE: 'MEDIA_RULE',
+                    FONT_FACE_RULE: 'FONT_FACE_RULE',
+                    PAGE_RULE: 'PAGE_RULE',
+                    NAMESPACE_RULE: 'NAMESPACE_RULE',
+                    COMMENT: 'COMMENT',
+                    VARIABLES_RULE: 'VARIABLES_RULE',
+                    MARGIN_RULE: 'MARGIN_RULE'
                     }
 
     def __init__(self, parentRule=None, parentStyleSheet=None, readonly=False):
@@ -77,12 +77,12 @@ class CSSRule(cssutils.util.Base2):
             self._atkeyword = atkeyword
             self._keyword = keyword
         else:
-            self._log.error(u'%s: Invalid atkeyword for this rule: %r' %
+            self._log.error('%s: Invalid atkeyword for this rule: %r' %
                             (self.atkeyword, keyword),
                             error=xml.dom.InvalidModificationErr)
 
     atkeyword = property(lambda self: self._atkeyword, _setAtkeyword,
-                         doc=u"Normalized  keyword of an @rule (e.g. ``@import``).")
+                         doc="Normalized  keyword of an @rule (e.g. ``@import``).")
 
     def _setCssText(self, cssText):
         """
@@ -103,19 +103,19 @@ class CSSRule(cssutils.util.Base2):
         """
         self._checkReadonly()
 
-    cssText = property(lambda self: u'', _setCssText,
-                       doc=u"(DOM) The parsable textual representation of the "
-                           u"rule. This reflects the current state of the rule "
-                           u"and not its initial value.")
+    cssText = property(lambda self: '', _setCssText,
+                       doc="(DOM) The parsable textual representation of the "
+                           "rule. This reflects the current state of the rule "
+                           "and not its initial value.")
 
     parent = property(lambda self: self._parent,
-                      doc=u"The Parent Node of this CSSRule or None.")
+                      doc="The Parent Node of this CSSRule or None.")
 
     parentRule = property(lambda self: self._parentRule,
-                          doc=u"If this rule is contained inside another rule "
-                          u"(e.g. a style rule inside an @media block), this "
-                          u"is the containing rule. If this rule is not nested "
-                          u"inside any other rules, this returns None.")
+                          doc="If this rule is contained inside another rule "
+                          "(e.g. a style rule inside an @media block), this "
+                          "is the containing rule. If this rule is not nested "
+                          "inside any other rules, this returns None.")
 
     def _getParentStyleSheet(self):
         # rules contained in other rules (@media) use that rules parent
@@ -125,17 +125,17 @@ class CSSRule(cssutils.util.Base2):
             return self._parentStyleSheet
 
     parentStyleSheet = property(_getParentStyleSheet,
-                                doc=u"The style sheet that contains this rule.")
+                                doc="The style sheet that contains this rule.")
 
     type = property(lambda self: self.UNKNOWN_RULE,
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
 
     typeString = property(lambda self: CSSRule._typestrings[self.type],
-                          doc=u"Descriptive name of this rule's type.")
+                          doc="Descriptive name of this rule's type.")
 
     wellformed = property(lambda self: False,
-                          doc=u"If the rule is wellformed.")
+                          doc="If the rule is wellformed.")
 
 
 
@@ -201,8 +201,8 @@ class CSSRuleRules(CSSRule):
                     index = i
                     break
             else:
-                raise xml.dom.IndexSizeErr(u"%s: Not a rule in "
-                                           u"this rule'a cssRules list: %s"
+                raise xml.dom.IndexSizeErr("%s: Not a rule in "
+                                           "this rule'a cssRules list: %s"
                                            % (self.__class__.__name__, index))
 
         try:
@@ -211,8 +211,8 @@ class CSSRuleRules(CSSRule):
             del self._cssRules[index]
             
         except IndexError:
-            raise xml.dom.IndexSizeErr(u'%s: %s is not a valid index '
-                                       u'in the rulelist of length %i' 
+            raise xml.dom.IndexSizeErr('%s: %s is not a valid index '
+                                       'in the rulelist of length %i'
                                        % (self.__class__.__name__, 
                                           index, self._cssRules.length))
 
@@ -225,18 +225,18 @@ class CSSRuleRules(CSSRule):
             index = len(self._cssRules)
             
         elif index < 0 or index > self._cssRules.length:
-            raise xml.dom.IndexSizeErr(u'%s: Invalid index %s for '
-                                       u'CSSRuleList with a length of %s.'
+            raise xml.dom.IndexSizeErr('%s: Invalid index %s for '
+                                       'CSSRuleList with a length of %s.'
                                        % (self.__class__.__name__,
                                           index, self._cssRules.length))
         
         # check and optionally parse rule
-        if isinstance(rule, basestring):
+        if isinstance(rule, str):
             tempsheet = cssutils.css.CSSStyleSheet()
             tempsheet.cssText = rule
             if len(tempsheet.cssRules) != 1 or (tempsheet.cssRules and
              not isinstance(tempsheet.cssRules[0], cssutils.css.CSSRule)):
-                self._log.error(u'%s: Invalid Rule: %s' % (self.__class__.__name__,
+                self._log.error('%s: Invalid Rule: %s' % (self.__class__.__name__,
                                                            rule))
                 return False, False
             rule = tempsheet.cssRules[0]
@@ -248,7 +248,7 @@ class CSSRuleRules(CSSRule):
             return True, True
             
         elif not isinstance(rule, cssutils.css.CSSRule):
-            self._log.error(u'%s: Not a CSSRule: %s' % (rule, 
+            self._log.error('%s: Not a CSSRule: %s' % (rule,
                                                         self.__class__.__name__))
             return False, False
         
diff --git a/src/cssutils/css/cssrulelist.py b/src/cssutils/css/cssrulelist.py
index f9daff4..c59788a 100644
--- a/src/cssutils/css/cssrulelist.py
+++ b/src/cssutils/css/cssrulelist.py
@@ -43,7 +43,7 @@ class CSSRuleList(list):
             return None
 
     length = property(lambda self: len(self),
-                      doc=u"(DOM) The number of CSSRules in the list.")
+                      doc="(DOM) The number of CSSRules in the list.")
 
     def rulesOfType(self, type):
         """Yield the rules which have the given `type` only, one of the 
diff --git a/src/cssutils/css/cssstyledeclaration.py b/src/cssutils/css/cssstyledeclaration.py
index 4dfc365..117a011 100644
--- a/src/cssutils/css/cssstyledeclaration.py
+++ b/src/cssutils/css/cssstyledeclaration.py
@@ -53,8 +53,8 @@ __all__ = ['CSSStyleDeclaration', 'Property']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from cssproperties import CSS2Properties
-from property import Property
+from .cssproperties import CSS2Properties
+from .property import Property
 import cssutils
 import xml.dom
 
@@ -94,7 +94,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
 
         [Property: Value Priority?;]* [Property: Value Priority?]?
     """
-    def __init__(self, cssText=u'', parentRule=None, readonly=False,
+    def __init__(self, cssText='', parentRule=None, readonly=False,
                  validating=None):
         """
         :param cssText:
@@ -182,17 +182,17 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
         if n in known:
             super(CSSStyleDeclaration, self).__setattr__(n, v)
         else:
-            raise AttributeError(u'Unknown CSS Property, '
-                                 u'``CSSStyleDeclaration.setProperty("%s", '
-                                 u'...)`` MUST be used.' % n)
+            raise AttributeError('Unknown CSS Property, '
+                                 '``CSSStyleDeclaration.setProperty("%s", '
+                                 '...)`` MUST be used.' % n)
 
     def __repr__(self):
-        return u"cssutils.css.%s(cssText=%r)" % (
+        return "cssutils.css.%s(cssText=%r)" % (
                 self.__class__.__name__,
-                self.getCssText(separator=u' '))
+                self.getCssText(separator=' '))
 
     def __str__(self):
-        return u"<cssutils.css.%s object length=%r (all: %r) at 0x%x>" % (
+        return "<cssutils.css.%s object length=%r (all: %r) at 0x%x>" % (
                 self.__class__.__name__,
                 self.length,
                 len(self.getProperties(all=True)),
@@ -293,15 +293,15 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
 
             tokens = self._tokensupto2(tokenizer, starttoken=token,
                                        semicolon=True)
-            if self._tokenvalue(tokens[-1]) == u';':
+            if self._tokenvalue(tokens[-1]) == ';':
                 tokens.pop()
             property = Property(parent=self)
             property.cssText = tokens
             if property.wellformed:
                 seq.append(property, 'Property')
             else:
-                self._log.error(u'CSSStyleDeclaration: Syntax Error in '
-                                u'Property: %s' % self._valuestr(tokens))
+                self._log.error('CSSStyleDeclaration: Syntax Error in '
+                                'Property: %s' % self._valuestr(tokens))
             # does not matter in this case
             return expected
 
@@ -310,16 +310,16 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
             ignored = self._tokenvalue(token) + self._valuestr(
                                 self._tokensupto2(tokenizer,
                                                   propertyvalueendonly=True))
-            self._log.error(u'CSSStyleDeclaration: Unexpected token, ignoring '
+            self._log.error('CSSStyleDeclaration: Unexpected token, ignoring '
                             'upto %r.' % ignored,token)
             # does not matter in this case
             return expected
 
         def char(expected, seq, token, tokenizer=None):
             # a standalone ; or error...
-            if self._tokenvalue(token) == u';':
-                self._log.info(u'CSSStyleDeclaration: Stripped standalone semicolon'
-                                u': %s' % self._valuestr([token]), neverraise=True)
+            if self._tokenvalue(token) == ';':
+                self._log.info('CSSStyleDeclaration: Stripped standalone semicolon'
+                                ': %s' % self._valuestr([token]), neverraise=True)
                 return expected
             else:
                 return unexpected(expected, seq, token, tokenizer)
@@ -339,9 +339,9 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
         self._setSeq(newseq)
 
     cssText = property(_getCssText, _setCssText,
-                       doc=u"(DOM) A parsable textual representation of the "
-                           u"declaration block excluding the surrounding curly "
-                           u"braces.")
+                       doc="(DOM) A parsable textual representation of the "
+                           "declaration block excluding the surrounding curly "
+                           "braces.")
 
     def getCssText(self, separator=None):
         """
@@ -460,8 +460,8 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
         """
         nname = self._normalize(name)
         if nname in self._SHORTHANDPROPERTIES:
-            self._log.info(u'CSSValue for shorthand property "%s" should be '
-                           u'None, this may be implemented later.' %
+            self._log.info('CSSValue for shorthand property "%s" should be '
+                           'None, this may be implemented later.' %
                            nname, neverraise=True)
 
         p = self.getProperty(name, normalize)
@@ -489,7 +489,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
         if p:
             return p.value
         else:
-            return u''
+            return ''
 
     def getPropertyPriority(self, name, normalize=True):
         """
@@ -510,7 +510,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
         if p:
             return p.priority
         else:
-            return u''
+            return ''
 
     def removeProperty(self, name, normalize=True):
         """
@@ -560,7 +560,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
         self._setSeq(newseq)
         return r
 
-    def setProperty(self, name, value=None, priority=u'',
+    def setProperty(self, name, value=None, priority='',
                     normalize=True, replace=True):
         """(DOM) Set a property value and priority within this declaration
         block.
@@ -636,7 +636,7 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
             self.seq._readonly = True
 
         else:
-            self._log.warn(u'Invalid Property: %s: %s %s'
+            self._log.warn('Invalid Property: %s: %s %s'
                            % (name, value, priority))
 
     def item(self, index):
@@ -665,15 +665,15 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
         try:
             return names[index]
         except IndexError:
-            return u''
+            return ''
 
     length = property(lambda self: len(list(self.__nnames())),
-                      doc=u"(DOM) The number of distinct properties that have "
-                          u"been explicitly in this declaration block. The "
-                          u"range of valid indices is 0 to length-1 inclusive. "
-                          u"These are properties with a different ``name`` "
-                          u"only. :meth:`item` and :attr:`length` work on the "
-                          u"same set here.")
+                      doc="(DOM) The number of distinct properties that have "
+                          "been explicitly in this declaration block. The "
+                          "range of valid indices is 0 to length-1 inclusive. "
+                          "These are properties with a different ``name`` "
+                          "only. :meth:`item` and :attr:`length` work on the "
+                          "same set here.")
 
     def _getValidating(self):
         try:
@@ -690,15 +690,15 @@ class CSSStyleDeclaration(CSS2Properties, cssutils.util.Base2):
         self._validating = validating
 
     validating = property(_getValidating, _setValidating,
-                          doc=u"If ``True`` this declaration validates "
-                          u"contained properties. The parent StyleSheet "
-                          u"validation setting does *always* win though so "
-                          u"even if validating is True it may not validate "
-                          u"if the StyleSheet defines else!")
+                          doc="If ``True`` this declaration validates "
+                          "contained properties. The parent StyleSheet "
+                          "validation setting does *always* win though so "
+                          "even if validating is True it may not validate "
+                          "if the StyleSheet defines else!")
 
     def _getValid(self):
         """Check each contained property for validity."""
         return all(prop.valid for prop in self.getProperties())
 
     valid = property(_getValid,
-                     doc=u'``True`` if each property is valid.')
+                     doc='``True`` if each property is valid.')
diff --git a/src/cssutils/css/cssstylerule.py b/src/cssutils/css/cssstylerule.py
index 329650d..c7a129c 100644
--- a/src/cssutils/css/cssstylerule.py
+++ b/src/cssutils/css/cssstylerule.py
@@ -3,9 +3,9 @@ __all__ = ['CSSStyleRule']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from cssstyledeclaration import CSSStyleDeclaration
-from selectorlist import SelectorList
-import cssrule
+from .cssstyledeclaration import CSSStyleDeclaration
+from .selectorlist import SelectorList
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -50,12 +50,12 @@ class CSSStyleRule(cssrule.CSSRule):
             st = (self.selectorText, self._namespaces)
         else:
             st = self.selectorText
-        return u"cssutils.css.%s(selectorText=%r, style=%r)" % (
+        return "cssutils.css.%s(selectorText=%r, style=%r)" % (
                 self.__class__.__name__, st, self.style.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object selectorText=%r style=%r _namespaces=%r "\
-               u"at 0x%x>" % (self.__class__.__name__,
+        return "<cssutils.css.%s object selectorText=%r style=%r _namespaces=%r "\
+               "at 0x%x>" % (self.__class__.__name__,
                               self.selectorText,
                               self.style.cssText,
                               self._namespaces,
@@ -100,13 +100,13 @@ class CSSStyleRule(cssrule.CSSRule):
         styletokens = self._tokensupto2(tokenizer, blockendonly=True)
         trail = self._nexttoken(tokenizer)
         if trail:
-            self._log.error(u'CSSStyleRule: Trailing content: %s' %
+            self._log.error('CSSStyleRule: Trailing content: %s' %
                             self._valuestr(cssText), token=trail)
         elif not selectortokens:
-            self._log.error(u'CSSStyleRule: No selector found: %r' %
+            self._log.error('CSSStyleRule: No selector found: %r' %
                             self._valuestr(cssText))
-        elif self._tokenvalue(selectortokens[0]).startswith(u'@'):
-            self._log.error(u'CSSStyleRule: No style rule: %r' %
+        elif self._tokenvalue(selectortokens[0]).startswith('@'):
+            self._log.error('CSSStyleRule: No style rule: %r' %
                             self._valuestr(cssText),
                             error=xml.dom.InvalidModificationErr)
         else:
@@ -115,14 +115,14 @@ class CSSStyleRule(cssrule.CSSRule):
             ok = True
 
             bracetoken = selectortokens.pop()
-            if self._tokenvalue(bracetoken) != u'{':
+            if self._tokenvalue(bracetoken) != '{':
                 ok = False
                 self._log.error(
-                    u'CSSStyleRule: No start { of style declaration found: %r' %
+                    'CSSStyleRule: No start { of style declaration found: %r' %
                     self._valuestr(cssText), bracetoken)
             elif not selectortokens:
                 ok = False
-                self._log.error(u'CSSStyleRule: No selector found: %r.' %
+                self._log.error('CSSStyleRule: No selector found: %r.' %
                             self._valuestr(cssText), bracetoken)
             # SET
             newSelectorList.selectorText = (selectortokens,
@@ -131,16 +131,16 @@ class CSSStyleRule(cssrule.CSSRule):
             if not styletokens:
                 ok = False
                 self._log.error(
-                    u'CSSStyleRule: No style declaration or "}" found: %r' %
+                    'CSSStyleRule: No style declaration or "}" found: %r' %
                     self._valuestr(cssText))
             else:
                 braceorEOFtoken = styletokens.pop()
                 val, typ = self._tokenvalue(braceorEOFtoken),\
                            self._type(braceorEOFtoken)
-                if val != u'}' and typ != 'EOF':
+                if val != '}' and typ != 'EOF':
                     ok = False
-                    self._log.error(u'CSSStyleRule: No "}" after style '
-                                    u'declaration found: %r'
+                    self._log.error('CSSStyleRule: No "}" after style '
+                                    'declaration found: %r'
                                     % self._valuestr(cssText))
                 else:
                     if 'EOF' == typ:
@@ -154,8 +154,8 @@ class CSSStyleRule(cssrule.CSSRule):
                 self.style = newStyle
 
     cssText = property(_getCssText, _setCssText,
-                       doc=u"(DOM) The parsable textual representation of this "
-                       u"rule.")
+                       doc="(DOM) The parsable textual representation of this "
+                       "rule.")
 
     def __getNamespaces(self):
         """Uses children namespaces if not attached to a sheet, else the sheet's
@@ -166,10 +166,10 @@ class CSSStyleRule(cssrule.CSSRule):
             return self.selectorList._namespaces
 
     _namespaces = property(__getNamespaces,
-                           doc=u"If this Rule is attached to a CSSStyleSheet "
-                               u"the namespaces of that sheet are mirrored "
-                               u"here. While the Rule is not attached the "
-                               u"namespaces of selectorList are used.""")
+                           doc="If this Rule is attached to a CSSStyleSheet "
+                               "the namespaces of that sheet are mirrored "
+                               "here. While the Rule is not attached the "
+                               "namespaces of selectorList are used.""")
 
     def _setSelectorList(self, selectorList):
         """
@@ -182,7 +182,7 @@ class CSSStyleRule(cssrule.CSSRule):
 
     _selectorList = None
     selectorList = property(lambda self: self._selectorList, _setSelectorList,
-                            doc=u"The SelectorList of this rule.")
+                            doc="The SelectorList of this rule.")
 
     def _setSelectorText(self, selectorText):
         """
@@ -209,8 +209,8 @@ class CSSStyleRule(cssrule.CSSRule):
 
     selectorText = property(lambda self: self._selectorList.selectorText,
                             _setSelectorText,
-                            doc=u"(DOM) The textual representation of the "
-                                u"selector for the rule set.")
+                            doc="(DOM) The textual representation of the "
+                                "selector for the rule set.")
 
     def _setStyle(self, style):
         """
@@ -218,17 +218,17 @@ class CSSStyleRule(cssrule.CSSRule):
             current style object.
         """
         self._checkReadonly()
-        if isinstance(style, basestring):
+        if isinstance(style, str):
             self._style = CSSStyleDeclaration(cssText=style, parentRule=self)
         else:
             style._parentRule = self
             self._style = style
 
     style = property(lambda self: self._style, _setStyle,
-                     doc=u"(DOM) The declaration-block of this rule set.")
+                     doc="(DOM) The declaration-block of this rule set.")
 
     type = property(lambda self: self.STYLE_RULE,
-                    doc=u"The type of this rule, as defined by a CSSRule "
+                    doc="The type of this rule, as defined by a CSSRule "
                         "type constant.")
 
     wellformed = property(lambda self: self.selectorList.wellformed)
@@ -238,4 +238,4 @@ class CSSStyleRule(cssrule.CSSRule):
         return self.style.valid
 
     valid = property(_getValid,
-                     doc=u'``True`` when the style declaration is true.')
+                     doc='``True`` when the style declaration is true.')
diff --git a/src/cssutils/css/cssstylesheet.py b/src/cssutils/css/cssstylesheet.py
index 2f74daf..d2204af 100644
--- a/src/cssutils/css/cssstylesheet.py
+++ b/src/cssutils/css/cssstylesheet.py
@@ -13,8 +13,8 @@ __version__ = '$Id$'
 
 from cssutils.helper import Deprecated
 from cssutils.util import _Namespaces, _SimpleNamespaces, _readUrl
-from cssrule import CSSRule
-from cssvariablesdeclaration import CSSVariablesDeclaration
+from .cssrule import CSSRule
+from .cssvariablesdeclaration import CSSVariablesDeclaration
 import cssutils.stylesheets
 import xml.dom
 
@@ -32,7 +32,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
     ``cssRules``
         All Rules in this style sheet, a :class:`~cssutils.css.CSSRuleList`.
     """
-    def __init__(self, href=None, media=None, title=u'', disabled=None,
+    def __init__(self, href=None, media=None, title='', disabled=None,
                  ownerNode=None, parentStyleSheet=None, readonly=False,
                  ownerRule=None,
                  validating=True):
@@ -82,7 +82,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
     def _cleanNamespaces(self):
         "Remove all namespace rules with same namespaceURI but last."
         rules = self.cssRules
-        namespaceitems = self.namespaces.items()
+        namespaceitems = list(self.namespaces.items())
         i = 0
         while i < len(rules):
             rule = rules[i]
@@ -116,8 +116,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
         self._cssRules = cssRules
 
     cssRules = property(lambda self: self._cssRules, _setCssRules,
-                        u"All Rules in this style sheet, a "
-                        u":class:`~cssutils.css.CSSRuleList`.")
+                        "All Rules in this style sheet, a "
+                        ":class:`~cssutils.css.CSSRuleList`.")
 
     def _getCssText(self):
         "Textual representation of the stylesheet (a byte string)."
@@ -160,8 +160,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             rule.cssText = self._tokensupto2(tokenizer, token)
 
             if expected > 0:
-                self._log.error(u'CSSStylesheet: CSSCharsetRule only allowed '
-                                u'at beginning of stylesheet.',
+                self._log.error('CSSStylesheet: CSSCharsetRule only allowed '
+                                'at beginning of stylesheet.',
                                 token, xml.dom.HierarchyRequestErr)
                 return expected
             elif rule.wellformed:
@@ -175,8 +175,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             rule.cssText = self._tokensupto2(tokenizer, token)
 
             if expected > 1:
-                self._log.error(u'CSSStylesheet: CSSImportRule not allowed '
-                                u'here.', token, xml.dom.HierarchyRequestErr)
+                self._log.error('CSSStylesheet: CSSImportRule not allowed '
+                                'here.', token, xml.dom.HierarchyRequestErr)
                 return expected
             elif rule.wellformed:
                 self.insertRule(rule)
@@ -190,8 +190,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                                                  parentStyleSheet=self)
 
             if expected > 2:
-                self._log.error(u'CSSStylesheet: CSSNamespaceRule not allowed '
-                                u'here.', token, xml.dom.HierarchyRequestErr)
+                self._log.error('CSSStylesheet: CSSNamespaceRule not allowed '
+                                'here.', token, xml.dom.HierarchyRequestErr)
                 return expected
             elif rule.wellformed:
                 if rule.prefix not in self.namespaces:
@@ -213,8 +213,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             rule.cssText = self._tokensupto2(tokenizer, token)
 
             if expected > 2:
-                self._log.error(u'CSSStylesheet: CSSVariablesRule not allowed '
-                                u'here.', token, xml.dom.HierarchyRequestErr)
+                self._log.error('CSSStylesheet: CSSVariablesRule not allowed '
+                                'here.', token, xml.dom.HierarchyRequestErr)
                 return expected
             elif rule.wellformed:
                 self.insertRule(rule)
@@ -249,12 +249,12 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
         def unknownrule(expected, seq, token, tokenizer):
             # parse and consume tokens in any case
             if token[1] in cssutils.css.MarginRule.margins:
-                self._log.error(u'CSSStylesheet: MarginRule out CSSPageRule.',
+                self._log.error('CSSStylesheet: MarginRule out CSSPageRule.',
                                 token, neverraise=True)
                 rule = cssutils.css.MarginRule(parentStyleSheet=self)
                 rule.cssText = self._tokensupto2(tokenizer, token)
             else:
-                self._log.warn(u'CSSStylesheet: Unknown @rule found.',
+                self._log.warn('CSSStylesheet: Unknown @rule found.',
                                token, neverraise=True)
                 rule = cssutils.css.CSSUnknownRule(parentStyleSheet=self)
                 rule.cssText = self._tokensupto2(tokenizer, token)
@@ -364,7 +364,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             self.encoding = encoding
             try:
                 del self.__newEncoding
-            except AttributeError, e:
+            except AttributeError as e:
                 pass
 
     def _setFetcher(self, fetcher=None):
@@ -422,10 +422,10 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                 self._variables.setVariable(var, vr.variables[var])
 
     variables = property(lambda self: self._variables,
-                         doc=u"A :class:`cssutils.css.CSSVariablesDeclaration` "
-                         u"containing all available variables in this "
-                         u"CSSStyleSheet including the ones defined in "
-                         u"imported sheets.")
+                         doc="A :class:`cssutils.css.CSSVariablesDeclaration` "
+                         "containing all available variables in this "
+                         "CSSStyleSheet including the ones defined in "
+                         "imported sheets.")
 
     def add(self, rule):
         """Add `rule` to style sheet at appropriate position.
@@ -462,7 +462,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                     index = i
                     break
             else:
-                raise xml.dom.IndexSizeErr(u"CSSStyleSheet: Not a rule in"
+                raise xml.dom.IndexSizeErr("CSSStyleSheet: Not a rule in"
                                            " this sheets'a cssRules list: %s"
                                            % index)
 
@@ -470,8 +470,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             rule = self._cssRules[index]
         except IndexError:
             raise xml.dom.IndexSizeErr(
-                u'CSSStyleSheet: %s is not a valid index in the rulelist of '
-                u'length %i' % (index, self._cssRules.length))
+                'CSSStyleSheet: %s is not a valid index in the rulelist of '
+                'length %i' % (index, self._cssRules.length))
         else:
             if rule.type == rule.NAMESPACE_RULE:
                 # check all namespacerules if used
@@ -481,8 +481,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                 if rule.namespaceURI in useduris and\
                    uris.count(rule.namespaceURI) == 1:
                     raise xml.dom.NoModificationAllowedErr(
-                        u'CSSStyleSheet: NamespaceURI defined in this rule is '
-                        u'used, cannot remove.')
+                        'CSSStyleSheet: NamespaceURI defined in this rule is '
+                        'used, cannot remove.')
                     return
 
             rule._parentStyleSheet = None # detach
@@ -529,11 +529,11 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             index = len(self._cssRules)
         elif index < 0 or index > self._cssRules.length:
             raise xml.dom.IndexSizeErr(
-                u'CSSStyleSheet: Invalid index %s for CSSRuleList with a '
-                u'length of %s.' % (index, self._cssRules.length))
+                'CSSStyleSheet: Invalid index %s for CSSRuleList with a '
+                'length of %s.' % (index, self._cssRules.length))
             return
 
-        if isinstance(rule, basestring):
+        if isinstance(rule, str):
             # init a temp sheet which has the same properties as self
             tempsheet = CSSStyleSheet(href=self.href,
                                       media=self.media,
@@ -545,7 +545,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             # prepend encoding if in this sheet to be able to use it in
             # @import rules encoding resolution
             # do not add if new rule startswith "@charset" (which is exact!)
-            if not rule.startswith(u'@charset') and (self._cssRules and
+            if not rule.startswith('@charset') and (self._cssRules and
                 self._cssRules[0].type == self._cssRules[0].CHARSET_RULE):
                 # rule 0 is @charset!
                 newrulescount, newruleindex = 2, 1
@@ -558,7 +558,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
 
             if len(tempsheet.cssRules) != newrulescount or (not isinstance(
                tempsheet.cssRules[newruleindex], cssutils.css.CSSRule)):
-                self._log.error(u'CSSStyleSheet: Not a CSSRule: %s' % rule)
+                self._log.error('CSSStyleSheet: Not a CSSRule: %s' % rule)
                 return
             rule = tempsheet.cssRules[newruleindex]
             rule._parentStyleSheet = None # done later?
@@ -574,7 +574,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             return index
 
         if not rule.wellformed:
-            self._log.error(u'CSSStyleSheet: Invalid rules cannot be added.')
+            self._log.error('CSSStyleSheet: Invalid rules cannot be added.')
             return
 
         # CHECK HIERARCHY
@@ -591,7 +591,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             elif index != 0 or (self._cssRules and
                               self._cssRules[0].type == rule.CHARSET_RULE):
                 self._log.error(
-                    u'CSSStylesheet: @charset only allowed once at the'
+                    'CSSStylesheet: @charset only allowed once at the'
                     ' beginning of a stylesheet.',
                     error=xml.dom.HierarchyRequestErr)
                 return
@@ -603,7 +603,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
             if index == 0 and self._cssRules and\
                self._cssRules[0].type == rule.CHARSET_RULE:
                 self._log.error(
-                    u'CSSStylesheet: @charset must be the first rule.',
+                    'CSSStylesheet: @charset must be the first rule.',
                     error=xml.dom.HierarchyRequestErr)
                 return
             else:
@@ -632,7 +632,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                 if index == 0 and self._cssRules and\
                    self._cssRules[0].type == rule.CHARSET_RULE:
                     self._log.error(
-                        u'CSSStylesheet: Found @charset at index 0.',
+                        'CSSStylesheet: Found @charset at index 0.',
                         error=xml.dom.HierarchyRequestErr)
                     return
                 # before @namespace @variables @page @font-face @media stylerule
@@ -644,7 +644,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                                   r.STYLE_RULE,
                                   r.FONT_FACE_RULE):
                         self._log.error(
-                            u'CSSStylesheet: Cannot insert @import here,'
+                            'CSSStylesheet: Cannot insert @import here,'
                              ' found @namespace, @variables, @media, @page or'
                              ' CSSStyleRule before index %s.' %
                             index,
@@ -676,7 +676,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                 for r in self._cssRules[index:]:
                     if r.type in (r.CHARSET_RULE, r.IMPORT_RULE):
                         self._log.error(
-                            u'CSSStylesheet: Cannot insert @namespace here,'
+                            'CSSStylesheet: Cannot insert @namespace here,'
                             ' found @charset or @import after index %s.' %
                             index,
                             error=xml.dom.HierarchyRequestErr)
@@ -689,7 +689,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                                   r.STYLE_RULE,
                                   r.FONT_FACE_RULE):
                         self._log.error(
-                            u'CSSStylesheet: Cannot insert @namespace here,'
+                            'CSSStylesheet: Cannot insert @namespace here,'
                             ' found @variables, @media, @page or CSSStyleRule'
                             ' before index %s.' %
                             index,
@@ -731,7 +731,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                                   r.IMPORT_RULE,
                                   r.NAMESPACE_RULE):
                         self._log.error(
-                            u'CSSStylesheet: Cannot insert @variables here,'
+                            'CSSStylesheet: Cannot insert @variables here,'
                             ' found @charset, @import or @namespace after'
                             ' index %s.' %
                             index,
@@ -744,7 +744,7 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                                   r.STYLE_RULE,
                                   r.FONT_FACE_RULE):
                         self._log.error(
-                            u'CSSStylesheet: Cannot insert @variables here,'
+                            'CSSStylesheet: Cannot insert @variables here,'
                             ' found @media, @page or CSSStyleRule'
                             ' before index %s.' %
                             index,
@@ -766,8 +766,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
                                   r.IMPORT_RULE,
                                   r.NAMESPACE_RULE):
                         self._log.error(
-                            u'CSSStylesheet: Cannot insert rule here, found '
-                            u'@charset, @import or @namespace before index %s.'
+                            'CSSStylesheet: Cannot insert rule here, found '
+                            '@charset, @import or @namespace before index %s.'
                             % index, error=xml.dom.HierarchyRequestErr)
                         return
                 self._cssRules.insert(index, rule)
@@ -782,8 +782,8 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
         return index
 
     ownerRule = property(lambda self: self._ownerRule,
-                         doc=u'A ref to an @import rule if it is imported, '
-                             u'else ``None``.')
+                         doc='A ref to an @import rule if it is imported, '
+                             'else ``None``.')
 
     def _getValid(self):
         """Check if each contained rule is valid."""
@@ -794,19 +794,19 @@ class CSSStyleSheet(cssutils.stylesheets.StyleSheet):
         return True
 
     valid = property(_getValid,
-                     doc=u'``True`` if all contained rules are valid')
+                     doc='``True`` if all contained rules are valid')
 
 
-    @Deprecated(u'Use ``cssutils.setSerializer(serializer)`` instead.')
+    @Deprecated('Use ``cssutils.setSerializer(serializer)`` instead.')
     def setSerializer(self, cssserializer):
         """Set the cssutils global Serializer used for all output."""
         if isinstance(cssserializer, cssutils.CSSSerializer):
             cssutils.ser = cssserializer
         else:
-            raise ValueError(u'Serializer must be an instance of '
-                             u'cssutils.CSSSerializer.')
+            raise ValueError('Serializer must be an instance of '
+                             'cssutils.CSSSerializer.')
 
-    @Deprecated(u'Set pref in ``cssutils.ser.prefs`` instead.')
+    @Deprecated('Set pref in ``cssutils.ser.prefs`` instead.')
     def setSerializerPref(self, pref, value):
         """Set a Preference of CSSSerializer used for output.
         See :class:`cssutils.serialize.Preferences` for possible
diff --git a/src/cssutils/css/cssunknownrule.py b/src/cssutils/css/cssunknownrule.py
index c9e4361..a474cd5 100644
--- a/src/cssutils/css/cssunknownrule.py
+++ b/src/cssutils/css/cssunknownrule.py
@@ -3,7 +3,7 @@ __all__ = ['CSSUnknownRule']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-import cssrule
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -16,7 +16,7 @@ class CSSUnknownRule(cssrule.CSSRule):
 
         @xxx until ';' or block {...}
     """
-    def __init__(self, cssText=u'', parentRule=None, 
+    def __init__(self, cssText='', parentRule=None,
                  parentStyleSheet=None, readonly=False):
         """
         :param cssText:
@@ -31,12 +31,12 @@ class CSSUnknownRule(cssrule.CSSRule):
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(cssText=%r)" % (
+        return "cssutils.css.%s(cssText=%r)" % (
                 self.__class__.__name__,
                 self.cssText)
         
     def __str__(self):
-        return u"<cssutils.css.%s object cssText=%r at 0x%x>" % (
+        return "<cssutils.css.%s object cssText=%r at 0x%x>" % (
                 self.__class__.__name__,
                 self.cssText,
                 id(self))
@@ -64,7 +64,7 @@ class CSSUnknownRule(cssrule.CSSRule):
         tokenizer = self._tokenize2(cssText)
         attoken = self._nexttoken(tokenizer, None)
         if not attoken or self._type(attoken) != self._prods.ATKEYWORD:
-            self._log.error(u'CSSUnknownRule: No CSSUnknownRule found: %s' %
+            self._log.error('CSSUnknownRule: No CSSUnknownRule found: %s' %
                 self._valuestr(cssText),
                 error=xml.dom.InvalidModificationErr)
         else:
@@ -76,10 +76,10 @@ class CSSUnknownRule(cssrule.CSSRule):
             def CHAR(expected, seq, token, tokenizer=None):
                 type_, val, line, col = token
                 if expected != 'EOF':
-                    if val in u'{[(':
+                    if val in '{[(':
                         new['nesting'].append(val)
-                    elif val in u'}])':
-                        opening = {u'}': u'{', u']': u'[', u')': u'('}[val]
+                    elif val in '}])':
+                        opening = {'}': '{', ']': '[', ')': '('}[val]
                         try:
                             if new['nesting'][-1] == opening:
                                 new['nesting'].pop()
@@ -87,17 +87,17 @@ class CSSUnknownRule(cssrule.CSSRule):
                                 raise IndexError()
                         except IndexError:
                             new['wellformed'] = False
-                            self._log.error(u'CSSUnknownRule: Wrong nesting of '
-                                            u'{, [ or (.', token=token)
+                            self._log.error('CSSUnknownRule: Wrong nesting of '
+                                            '{, [ or (.', token=token)
     
-                    if val in u'};' and not new['nesting']:
+                    if val in '};' and not new['nesting']:
                         expected = 'EOF' 
     
                     seq.append(val, type_, line=line, col=col)
                     return expected
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'CSSUnknownRule: Expected end of rule.',
+                    self._log.error('CSSUnknownRule: Expected end of rule.',
                                     token=token)
                     return expected
 
@@ -106,26 +106,26 @@ class CSSUnknownRule(cssrule.CSSRule):
                 type_, val, line, col = token
                 val = self._tokenvalue(token)
                 if expected != 'EOF':
-                    new['nesting'].append(u'(')
+                    new['nesting'].append('(')
                     seq.append(val, type_, line=line, col=col)
                     return expected
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'CSSUnknownRule: Expected end of rule.',
+                    self._log.error('CSSUnknownRule: Expected end of rule.',
                                     token=token)
                     return expected                
 
             def EOF(expected, seq, token, tokenizer=None):
                 "close all blocks and return 'EOF'"
                 for x in reversed(new['nesting']):
-                    closing = {u'{': u'}', u'[': u']', u'(': u')'}[x]
+                    closing = {'{': '}', '[': ']', '(': ')'}[x]
                     seq.append(closing, closing)
                 new['nesting'] = []
                 return 'EOF'
                 
             def INVALID(expected, seq, token, tokenizer=None):
                 # makes rule invalid
-                self._log.error(u'CSSUnknownRule: Bad syntax.',
+                self._log.error('CSSUnknownRule: Bad syntax.',
                                 token=token, error=xml.dom.SyntaxErr)
                 new['wellformed'] = False
                 return expected
@@ -138,7 +138,7 @@ class CSSUnknownRule(cssrule.CSSRule):
                     return expected
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'CSSUnknownRule: Expected end of rule.',
+                    self._log.error('CSSUnknownRule: Expected end of rule.',
                                     token=token)
                     return expected                
 
@@ -150,7 +150,7 @@ class CSSUnknownRule(cssrule.CSSRule):
                     return expected
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'CSSUnknownRule: Expected end of rule.',
+                    self._log.error('CSSUnknownRule: Expected end of rule.',
                                     token=token)
                     return expected                
 
@@ -161,7 +161,7 @@ class CSSUnknownRule(cssrule.CSSRule):
                     return expected
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'CSSUnknownRule: Expected end of rule.',
+                    self._log.error('CSSUnknownRule: Expected end of rule.',
                                     token=token)
                     return expected                
 
@@ -186,11 +186,11 @@ class CSSUnknownRule(cssrule.CSSRule):
             # post conditions
             if expected != 'EOF':
                 wellformed = False
-                self._log.error(u'CSSUnknownRule: No ending ";" or "}" found: '
-                                u'%r' % self._valuestr(cssText))
+                self._log.error('CSSUnknownRule: No ending ";" or "}" found: '
+                                '%r' % self._valuestr(cssText))
             elif new['nesting']:
                 wellformed = False
-                self._log.error(u'CSSUnknownRule: Unclosed "{", "[" or "(": %r'
+                self._log.error('CSSUnknownRule: Unclosed "{", "[" or "(": %r'
                                 % self._valuestr(cssText))
 
             # set all
@@ -199,11 +199,10 @@ class CSSUnknownRule(cssrule.CSSRule):
                 self._setSeq(newseq)
 
     cssText = property(fget=_getCssText, fset=_setCssText,
-                       doc=u"(DOM) The parsable textual representation.")
+                       doc="(DOM) The parsable textual representation.")
     
     type = property(lambda self: self.UNKNOWN_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
     
     wellformed = property(lambda self: bool(self.atkeyword))
-    
\ No newline at end of file
diff --git a/src/cssutils/css/cssvalue.py b/src/cssutils/css/cssvalue.py
index 2f64345..f819580 100644
--- a/src/cssutils/css/cssvalue.py
+++ b/src/cssutils/css/cssvalue.py
@@ -54,21 +54,21 @@ class CSSValue(cssutils.util._NewBase):
         self.parent = parent
         if cssText is not None: # may be 0
             if isinstance(cssText, int):
-                cssText = unicode(cssText) # if it is an integer
+                cssText = str(cssText) # if it is an integer
             elif isinstance(cssText, float):
-                cssText = u'%f' % cssText # if it is a floating point number
+                cssText = '%f' % cssText # if it is a floating point number
 
             self.cssText = cssText
 
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(%r)" % (self.__class__.__name__,
+        return "cssutils.css.%s(%r)" % (self.__class__.__name__,
                                          self.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object cssValueTypeString=%r cssText=%r at "\
-               u"0x%x>" % (self.__class__.__name__,
+        return "<cssutils.css.%s object cssValueTypeString=%r cssText=%r at "\
+               "0x%x>" % (self.__class__.__name__,
                            self.cssValueTypeString,
                            self.cssText,
                            id(self))
@@ -119,7 +119,7 @@ class CSSValue(cssutils.util._NewBase):
         self._checkReadonly()
 
         # used as operator is , / or S
-        nextSor = u',/'
+        nextSor = ',/'
 
         term = Choice(Sequence(PreDef.unary(),
                                Choice(PreDef.number(nextSor=nextSor),
@@ -133,21 +133,21 @@ class CSSValue(cssutils.util._NewBase):
                       # special case IE only expression
                       Prod(name='expression',
                            match=lambda t, v: t == self._prods.FUNCTION and (
-                              cssutils.helper.normalize(v) in (u'expression(',
-                                                               u'alpha(',
-                                                               u'blur(',
-                                                               u'chroma(',
-                                                               u'dropshadow(',
-                                                               u'fliph(',
-                                                               u'flipv(',
-                                                               u'glow(',
-                                                               u'gray(',
-                                                               u'invert(',
-                                                               u'mask(',
-                                                               u'shadow(',
-                                                               u'wave(',
-                                                               u'xray(') or
-                              v.startswith(u'progid:DXImageTransform.Microsoft.')
+                              cssutils.helper.normalize(v) in ('expression(',
+                                                               'alpha(',
+                                                               'blur(',
+                                                               'chroma(',
+                                                               'dropshadow(',
+                                                               'fliph(',
+                                                               'flipv(',
+                                                               'glow(',
+                                                               'gray(',
+                                                               'invert(',
+                                                               'mask(',
+                                                               'shadow(',
+                                                               'wave(',
+                                                               'xray(') or
+                              v.startswith('progid:DXImageTransform.Microsoft.')
                            ),
                            nextSor=nextSor,
                            toSeq=lambda t, tokens: (ExpressionValue._functionName,
@@ -216,7 +216,7 @@ class CSSValue(cssutils.util._NewBase):
                                        minmax=lambda: (0, None)))
         # parse
         wellformed, seq, store, notused = ProdParser().parse(cssText,
-                                                             u'CSSValue',
+                                                             'CSSValue',
                                                              valueprods,
                                                              keepS=True)
         if wellformed:
@@ -231,7 +231,7 @@ class CSSValue(cssutils.util._NewBase):
                 if item.type == self._prods.S:
                     pass
 
-                elif (item.value, item.type) == (u',', 'operator'):
+                elif (item.value, item.type) == (',', 'operator'):
                     # , separared counts as a single STRING for now
                     # URI or STRING value might be a single CHAR too!
                     newseq.appendItem(item)
@@ -241,11 +241,11 @@ class CSSValue(cssutils.util._NewBase):
                         if firstvalue[1] == self._prods.IDENT:
                             firstvalue = firstvalue[0], 'STRING'
 
-                elif item.value == u'/':
+                elif item.value == '/':
                     # / separated items count as one
                     newseq.appendItem(item)
 
-                elif item.value == u'-' or item.value == u'+':
+                elif item.value == '-' or item.value == '+':
                     # combine +- and following number or other
                     i += 1
                     try:
@@ -274,7 +274,7 @@ class CSSValue(cssutils.util._NewBase):
 
             if not firstvalue:
                 self._log.error(
-                        u'CSSValue: Unknown syntax or no value: %r.' %
+                        'CSSValue: Unknown syntax or no value: %r.' %
                         self._valuestr(cssText))
             else:
                 # ok and set
@@ -287,8 +287,8 @@ class CSSValue(cssutils.util._NewBase):
 
                 if count == 1:
                     # inherit, primitive or variable
-                    if isinstance(firstvalue[0], basestring) and\
-                       u'inherit' == cssutils.helper.normalize(firstvalue[0]):
+                    if isinstance(firstvalue[0], str) and\
+                       'inherit' == cssutils.helper.normalize(firstvalue[0]):
                         self.__class__ = CSSValue
                         self._cssValueType = CSSValue.CSS_INHERIT
                     elif 'CSSVariable' == firstvalue[1]:
@@ -328,7 +328,7 @@ class CSSValue(cssutils.util._NewBase):
                         """
                         if commalist:
                             newseq.replace(-1,
-                                           CSSPrimitiveValue(cssText=u''.join(
+                                           CSSPrimitiveValue(cssText=''.join(
                                                     commalist)),
                                            CSSPrimitiveValue,
                                            newseq[-1].line,
@@ -370,11 +370,11 @@ class CSSValue(cssutils.util._NewBase):
 
                             nexttocommalist = False
 
-                        elif u',' == item.value:
+                        elif ',' == item.value:
                             if not commalist:
                                 # save last item to commalist
                                 commalist.append(itemValue(self._seq[i - 1]))
-                            commalist.append(u',')
+                            commalist.append(',')
                             nexttocommalist = True
 
                         else:
@@ -518,7 +518,7 @@ class CSSPrimitiveValue(CSSValue):
                                                 readonly=readonly)
 
     def __str__(self):
-        return u"<cssutils.css.%s object primitiveType=%s cssText=%r at 0x%x>"\
+        return "<cssutils.css.%s object primitiveType=%s cssText=%r at 0x%x>"\
                % (self.__class__.__name__,
                   self.primitiveTypeString,
                   self.cssText,
@@ -541,7 +541,7 @@ class CSSPrimitiveValue(CSSValue):
                   'CSS_UNICODE_RANGE'
                   ]
 
-    _reNumDim = re.compile(ur'([+-]?\d*\.\d+|[+-]?\d+)(.*)$', re.I | re.U | re.X)
+    _reNumDim = re.compile(r'([+-]?\d*\.\d+|[+-]?\d+)(.*)$', re.I | re.U | re.X)
 
     def _unitDIMENSION(value):
         """Check val for dimension name."""
@@ -565,7 +565,7 @@ class CSSPrimitiveValue(CSSValue):
                  'rgb(': 'CSS_RGBCOLOR',
                  'rgba(': 'CSS_RGBACOLOR',
                  }
-        return units.get(re.findall(ur'^(.*?\()',
+        return units.get(re.findall(r'^(.*?\()',
                                     cssutils.helper.normalize(value.cssText),
                                     re.U)[0],
                          'CSS_UNKNOWN')
@@ -613,7 +613,7 @@ class CSSPrimitiveValue(CSSValue):
         try:
             return self._unitnames[type]
         except (IndexError, TypeError):
-            return u'%r (UNKNOWN TYPE)' % type
+            return '%r (UNKNOWN TYPE)' % type
 
     def _getNumDim(self, value=None):
         "Split self._value in numerical and dimension part."
@@ -623,14 +623,14 @@ class CSSPrimitiveValue(CSSValue):
         try:
             val, dim = CSSPrimitiveValue._reNumDim.findall(value)[0]
         except IndexError:
-            val, dim = value, u''
+            val, dim = value, ''
         try:
             val = float(val)
             if val == int(val):
                 val = int(val)
         except ValueError:
             raise xml.dom.InvalidAccessErr(
-                u'CSSPrimitiveValue: No float value %r' % self._value[0])
+                'CSSPrimitiveValue: No float value %r' % self._value[0])
 
         return val, dim
 
@@ -655,7 +655,7 @@ class CSSPrimitiveValue(CSSValue):
         """
         if unitType is not None and unitType not in self._floattypes:
             raise xml.dom.InvalidAccessErr(
-                u'unitType Parameter is not a float type')
+                'unitType Parameter is not a float type')
 
         val, dim = self._getNumDim()
 
@@ -665,7 +665,7 @@ class CSSPrimitiveValue(CSSValue):
                 val = self._converter[self.primitiveType, unitType](val)
             except KeyError:
                 raise xml.dom.InvalidAccessErr(
-                u'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r'
+                'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r'
                 % (self.primitiveTypeString,
                    self._getCSSPrimitiveTypeString(unitType)))
 
@@ -699,13 +699,13 @@ class CSSPrimitiveValue(CSSValue):
         self._checkReadonly()
         if unitType not in self._floattypes:
             raise xml.dom.InvalidAccessErr(
-               u'CSSPrimitiveValue: unitType %r is not a float type' %
+               'CSSPrimitiveValue: unitType %r is not a float type' %
                self._getCSSPrimitiveTypeString(unitType))
         try:
             val = float(floatValue)
-        except ValueError, e:
+        except ValueError as e:
             raise xml.dom.InvalidAccessErr(
-               u'CSSPrimitiveValue: floatValue %r is not a float' %
+               'CSSPrimitiveValue: floatValue %r is not a float' %
                floatValue)
 
         oldval, dim = self._getNumDim()
@@ -715,7 +715,7 @@ class CSSPrimitiveValue(CSSValue):
                 val = self._converter[unitType, self.primitiveType](val)
             except KeyError:
                 raise xml.dom.InvalidAccessErr(
-                u'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r'
+                'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r'
                 % (self.primitiveTypeString,
                    self._getCSSPrimitiveTypeString(unitType)))
 
@@ -736,7 +736,7 @@ class CSSPrimitiveValue(CSSValue):
         """
         if self.primitiveType not in self._stringtypes:
             raise xml.dom.InvalidAccessErr(
-                u'CSSPrimitiveValue %r is not a string type'
+                'CSSPrimitiveValue %r is not a string type'
                 % self.primitiveTypeString)
 
         if CSSPrimitiveValue.CSS_ATTR == self.primitiveType:
@@ -774,17 +774,17 @@ class CSSPrimitiveValue(CSSValue):
         # self not stringType
         if self.primitiveType not in self._stringtypes:
             raise xml.dom.InvalidAccessErr(
-                u'CSSPrimitiveValue %r is not a string type'
+                'CSSPrimitiveValue %r is not a string type'
                 % self.primitiveTypeString)
         # given stringType is no StringType
         if stringType not in self._stringtypes:
             raise xml.dom.InvalidAccessErr(
-                u'CSSPrimitiveValue: stringType %s is not a string type'
+                'CSSPrimitiveValue: stringType %s is not a string type'
                 % self._getCSSPrimitiveTypeString(stringType))
 
         if self._primitiveType != stringType:
             raise xml.dom.InvalidAccessErr(
-                u'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r'
+                'CSSPrimitiveValue: Cannot coerce primitiveType %r to %r'
                 % (self.primitiveTypeString,
                    self._getCSSPrimitiveTypeString(stringType)))
 
@@ -793,7 +793,7 @@ class CSSPrimitiveValue(CSSValue):
         elif CSSPrimitiveValue.CSS_URI == self._primitiveType:
             self.cssText = cssutils.helper.uri(stringValue)
         elif CSSPrimitiveValue.CSS_ATTR == self._primitiveType:
-            self.cssText = u'attr(%s)' % stringValue
+            self.cssText = 'attr(%s)' % stringValue
         else:
             self.cssText = stringValue
         self._primitiveType = stringType
@@ -807,7 +807,7 @@ class CSSPrimitiveValue(CSSValue):
         **Not implemented.**
         """
         if not self.CSS_COUNTER == self.primitiveType:
-            raise xml.dom.InvalidAccessErr(u'Value is not a counter type')
+            raise xml.dom.InvalidAccessErr('Value is not a counter type')
         # TODO: use Counter class
         raise NotImplementedError()
 
@@ -818,7 +818,7 @@ class CSSPrimitiveValue(CSSValue):
         can be achieved using the RGBColor interface.
         """
         if self.primitiveType not in self._rbgtypes:
-            raise xml.dom.InvalidAccessErr(u'Value is not a RGBColor value')
+            raise xml.dom.InvalidAccessErr('Value is not a RGBColor value')
         return RGBColor(self._value[0])
 
     def getRectValue(self):
@@ -830,7 +830,7 @@ class CSSPrimitiveValue(CSSValue):
         **Not implemented.**
         """
         if self.primitiveType not in self._recttypes:
-            raise xml.dom.InvalidAccessErr(u'value is not a Rect value')
+            raise xml.dom.InvalidAccessErr('value is not a Rect value')
         # TODO: use Rect class
         raise NotImplementedError()
 
@@ -872,8 +872,8 @@ class CSSValueList(CSSValue):
             yield item.value
 
     def __str__(self):
-        return u"<cssutils.css.%s object cssValueType=%r cssText=%r length=%r "\
-               u"at 0x%x>" % (self.__class__.__name__,
+        return "<cssutils.css.%s object cssValueType=%r cssText=%r length=%r "\
+               "at 0x%x>" % (self.__class__.__name__,
                               self.cssValueTypeString,
                               self.cssText,
                               self.length,
@@ -895,13 +895,13 @@ class CSSValueList(CSSValue):
             return None
 
     length = property(lambda self: len(self.__items()),
-                      doc=u"(DOM attribute) The number of CSSValues in the "
-                          u"list.")
+                      doc="(DOM attribute) The number of CSSValues in the "
+                          "list.")
 
 
 class CSSFunction(CSSPrimitiveValue):
     """A CSS function value like rect() etc."""
-    _functionName = u'CSSFunction'
+    _functionName = 'CSSFunction'
     primitiveType = CSSPrimitiveValue.CSS_UNKNOWN
 
     def __init__(self, cssText=None, parent=None, readonly=False):
@@ -976,7 +976,7 @@ class CSSFunction(CSSPrimitiveValue):
                 item = seq[i]
                 if item.type == self._prods.S:
                     pass
-                elif item.value == u'+' or item.value == u'-':
+                elif item.value == '+' or item.value == '-':
                     i += 1
                     next = seq[i]
                     newval = next.value
@@ -1007,7 +1007,7 @@ class CSSFunction(CSSPrimitiveValue):
 class RGBColor(CSSFunction):
     """A CSS color like RGB, RGBA or a simple value like `#000` or `red`."""
 
-    _functionName = u'Function rgb()'
+    _functionName = 'Function rgb()'
 
     def __init__(self, cssText=None, parent=None, readonly=False):
         """
@@ -1033,11 +1033,11 @@ class RGBColor(CSSFunction):
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(%r)" % (self.__class__.__name__,
+        return "cssutils.css.%s(%r)" % (self.__class__.__name__,
                                          self.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object colorType=%r cssText=%r at 0x%x>" % (
+        return "<cssutils.css.%s object colorType=%r cssText=%r at 0x%x>" % (
                 self.__class__.__name__,
                 self.colorType,
                 self.cssText,
@@ -1074,7 +1074,7 @@ class RGBColor(CSSFunction):
                             )
         # store: colorType, parts
         wellformed, seq, store, unusedtokens = ProdParser().parse(cssText,
-                                                            u'RGBColor',
+                                                            'RGBColor',
                                                             colorprods,
                                                             keepS=True,
                                                             store={'parts': []})
@@ -1099,7 +1099,7 @@ class RGBColor(CSSFunction):
 
 class CalcValue(CSSFunction):
     """Calc Function"""
-    _functionName = u'Function calc()'
+    _functionName = 'Function calc()'
 
     def _productiondefinition(self):
         """Return defintion used for parsing."""
@@ -1120,7 +1120,7 @@ class CalcValue(CSSFunction):
                                                                                                                  tokens)))
                                                   ),
                                              Prod(name='part',
-                                                  match=lambda t, v: v != u')',
+                                                  match=lambda t, v: v != ')',
                                                   toSeq=lambda t, tokens: (t[0], t[1])),
                                                   ),
                                       minmax=lambda: (0, None)),
@@ -1134,13 +1134,13 @@ class CalcValue(CSSFunction):
         return super(CalcValue, self)._setCssText(cssText)
 
     cssText = property(_getCssText, _setCssText,
-                       doc=u"A string representation of the current value.")
+                       doc="A string representation of the current value.")
 
 
 class ExpressionValue(CSSFunction):
     """Special IE only CSSFunction which may contain *anything*.
     Used for expressions and ``alpha(opacity=100)`` currently."""
-    _functionName = u'Expression (IE only)'
+    _functionName = 'Expression (IE only)'
 
     def _productiondefinition(self):
         """Return defintion used for parsing."""
@@ -1161,7 +1161,7 @@ class ExpressionValue(CSSFunction):
                                                                                                                  tokens)))
                                                   ),
                                              Prod(name='part',
-                                                  match=lambda t, v: v != u')',
+                                                  match=lambda t, v: v != ')',
                                                   toSeq=lambda t, tokens: (t[0], t[1])),
                                                   ),
                                       minmax=lambda: (0, None)),
@@ -1176,7 +1176,7 @@ class ExpressionValue(CSSFunction):
         return super(ExpressionValue, self)._setCssText(cssText)
 
     cssText = property(_getCssText, _setCssText,
-                       doc=u"A string representation of the current value.")
+                       doc="A string representation of the current value.")
 
 
 class CSSVariable(CSSValue):
@@ -1196,10 +1196,10 @@ class CSSVariable(CSSValue):
                                           readonly=readonly)
 
     def __repr__(self):
-        return u"cssutils.css.%s(%r)" % (self.__class__.__name__, self.cssText)
+        return "cssutils.css.%s(%r)" % (self.__class__.__name__, self.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object name=%r value=%r at 0x%x>" % (
+        return "<cssutils.css.%s object name=%r value=%r at 0x%x>" % (
                 self.__class__.__name__,
                 self.name,
                 self.value,
@@ -1219,7 +1219,7 @@ class CSSVariable(CSSValue):
         # store: name of variable
         store = {'ident': None}
         wellformed, seq, store, unusedtokens = ProdParser().parse(cssText,
-                                                                  u'CSSVariable',
+                                                                  'CSSVariable',
                                                                   funcProds,
                                                                   keepS=True)
         if wellformed:
@@ -1229,7 +1229,7 @@ class CSSVariable(CSSValue):
 
     cssText = property(lambda self: cssutils.ser.do_css_CSSVariable(self),
                        _setCssText,
-                       doc=u"A string representation of the current variable.")
+                       doc="A string representation of the current variable.")
 
     cssValueType = CSSValue.CSS_VARIABLE
 
diff --git a/src/cssutils/css/cssvariablesdeclaration.py b/src/cssutils/css/cssvariablesdeclaration.py
index 50b3b31..e2b0291 100644
--- a/src/cssutils/css/cssvariablesdeclaration.py
+++ b/src/cssutils/css/cssvariablesdeclaration.py
@@ -7,7 +7,7 @@ __version__ = '$Id: cssstyledeclaration.py 1819 2009-08-01 20:52:43Z cthedot $'
 
 from cssutils.prodparser import *
 from cssutils.helper import normalize
-from value import PropertyValue
+from .value import PropertyValue
 import cssutils
 import itertools
 import xml.dom
@@ -16,7 +16,7 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
     """The CSSVariablesDeclaration interface represents a single block of
     variable declarations. 
     """
-    def __init__(self, cssText=u'', parentRule=None, readonly=False):
+    def __init__(self, cssText='', parentRule=None, readonly=False):
         """
         :param cssText:
             Shortcut, sets CSSVariablesDeclaration.cssText
@@ -49,11 +49,11 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
         self._readonly = readonly
 
     def __repr__(self):
-        return u"cssutils.css.%s(cssText=%r)" % (self.__class__.__name__,
+        return "cssutils.css.%s(cssText=%r)" % (self.__class__.__name__,
                                                  self.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object length=%r at 0x%x>" % (
+        return "<cssutils.css.%s object length=%r at 0x%x>" % (
                 self.__class__.__name__,
                 self.length,
                 id(self))
@@ -64,7 +64,7 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
         :param variableName:
             a string
         """
-        return normalize(variableName) in self.keys()
+        return normalize(variableName) in list(self.keys())
     
     def __getitem__(self, variableName):
         """Retrieve the value of variable ``variableName`` from this 
@@ -80,13 +80,13 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
 
     def __iter__(self):
         """Iterator of names of set variables."""
-        for name in self.keys():
+        for name in list(self.keys()):
             yield name
 
     def keys(self):
         """Analoguous to standard dict returns variable names which are set in
         this declaration."""
-        return self._vars.keys()
+        return list(self._vars.keys())
     
     def _getCssText(self):
         """Return serialized property cssText."""
@@ -127,10 +127,10 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
 
         vardeclaration = Sequence(
             PreDef.ident(),
-            PreDef.char(u':', u':', toSeq=False, optional=True),
+            PreDef.char(':', ':', toSeq=False, optional=True),
             #PreDef.S(toSeq=False, optional=True),
-            Prod(name=u'term', match=lambda t, v: True,
-                 toSeq=lambda t, tokens: (u'value', 
+            Prod(name='term', match=lambda t, v: True,
+                 toSeq=lambda t, tokens: ('value',
                                           PropertyValue(itertools.chain([t], 
                                                                         tokens), 
                                           parent=self)
@@ -139,17 +139,17 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
         )
         prods = Sequence(vardeclaration,                         
                          Sequence(PreDef.S(optional=True),
-                                  PreDef.char(u';', u';', toSeq=False, optional=True),
+                                  PreDef.char(';', ';', toSeq=False, optional=True),
                                   PreDef.S(optional=True),
                                   vardeclaration,
                                   minmax=lambda: (0, None)),
                          PreDef.S(optional=True),
-                         PreDef.char(u';', u';', toSeq=False, optional=True)
+                         PreDef.char(';', ';', toSeq=False, optional=True)
                          )
         # parse
         wellformed, seq, store, notused = \
             ProdParser().parse(cssText, 
-                               u'CSSVariableDeclaration',
+                               'CSSVariableDeclaration',
                                prods,
                                emptyOk=True)
         if wellformed:
@@ -159,9 +159,9 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
             # seq contains only name: value pairs plus comments etc
             nameitem = None
             for item in seq:
-                if u'IDENT' == item.type:
+                if 'IDENT' == item.type:
                     nameitem = item
-                elif u'value' == item.type:
+                elif 'value' == item.type:
                     nname = normalize(nameitem.value)
                     if nname in newvars:
                         # replace var with same name
@@ -191,16 +191,16 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
             self.wellformed = True
 
     cssText = property(_getCssText, _setCssText,
-        doc=u"(DOM) A parsable textual representation of the declaration "
-            u"block excluding the surrounding curly braces.")
+        doc="(DOM) A parsable textual representation of the declaration "
+            "block excluding the surrounding curly braces.")
 
     def _setParentRule(self, parentRule):
         self._parentRule = parentRule
     
     parentRule = property(lambda self: self._parentRule, _setParentRule,
-                          doc=u"(DOM) The CSS rule that contains this"
-                              u" declaration block or None if this block"
-                              u" is not attached to a CSSRule.")
+                          doc="(DOM) The CSS rule that contains this"
+                              " declaration block or None if this block"
+                              " is not attached to a CSSRule.")
 
     def getVariableValue(self, variableName):
         """Used to retrieve the value of a variable if it has been explicitly
@@ -215,8 +215,8 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
         """
         try:
             return self._vars[normalize(variableName)].cssText
-        except KeyError, e:
-            return u''
+        except KeyError as e:
+            return ''
 
     def removeVariable(self, variableName):
         """Used to remove a variable if it has been explicitly set within this
@@ -236,8 +236,8 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
         normalname = variableName
         try:
             r = self._vars[normalname]
-        except KeyError, e:
-            return u''
+        except KeyError as e:
+            return ''
         else: 
             self.seq._readonly = False
             if normalname in self._vars:
@@ -270,10 +270,10 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
         # check name
         wellformed, seq, store, unused = \
             ProdParser().parse(normalize(variableName),
-                               u'variableName',
+                               'variableName',
                                Sequence(PreDef.ident()))
         if not wellformed:
-            self._log.error(u'Invalid variableName: %r: %r'
+            self._log.error('Invalid variableName: %r: %r'
                             % (variableName, value))
         else:
             # check value
@@ -283,7 +283,7 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
                 v = PropertyValue(cssText=value, parent=self)
                                 
             if not v.wellformed:
-                self._log.error(u'Invalid variable value: %r: %r'
+                self._log.error('Invalid variable value: %r: %r'
                                 % (variableName, value))
             else:
                 # update seq
@@ -321,11 +321,11 @@ class CSSVariablesDeclaration(cssutils.util._NewBase):
             string if no variable exists at this position.
         """
         try:
-            return self.keys()[index]
+            return list(self.keys())[index]
         except IndexError:
-            return u''
+            return ''
 
     length = property(lambda self: len(self._vars),
-        doc=u"The number of variables that have been explicitly set in this"
-            u" variable declaration block. The range of valid indices is 0"
-            u" to length-1 inclusive.")
+        doc="The number of variables that have been explicitly set in this"
+            " variable declaration block. The range of valid indices is 0"
+            " to length-1 inclusive.")
diff --git a/src/cssutils/css/cssvariablesrule.py b/src/cssutils/css/cssvariablesrule.py
index c7fbabf..5312dd7 100644
--- a/src/cssutils/css/cssvariablesrule.py
+++ b/src/cssutils/css/cssvariablesrule.py
@@ -5,8 +5,8 @@ __all__ = ['CSSVariablesRule']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id: cssfontfacerule.py 1818 2009-07-30 21:39:00Z cthedot $'
 
-from cssvariablesdeclaration import CSSVariablesDeclaration
-import cssrule
+from .cssvariablesdeclaration import CSSVariablesDeclaration
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -48,7 +48,7 @@ class CSSVariablesRule(cssrule.CSSRule):
         """
         super(CSSVariablesRule, self).__init__(parentRule=parentRule, 
                                               parentStyleSheet=parentStyleSheet)
-        self._atkeyword = u'@variables'
+        self._atkeyword = '@variables'
         
         # dummy
         self._media = cssutils.stylesheets.MediaList(mediaText, 
@@ -62,14 +62,14 @@ class CSSVariablesRule(cssrule.CSSRule):
         self._readonly = readonly
         
     def __repr__(self):
-        return u"cssutils.css.%s(mediaText=%r, variables=%r)" % (
+        return "cssutils.css.%s(mediaText=%r, variables=%r)" % (
                 self.__class__.__name__, 
                 self._media.mediaText,
                 self.variables.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object mediaText=%r variables=%r valid=%r " \
-               u"at 0x%x>" % (self.__class__.__name__,
+        return "<cssutils.css.%s object mediaText=%r variables=%r valid=%r " \
+               "at 0x%x>" % (self.__class__.__name__,
                               self._media.mediaText,
                               self.variables.cssText,
                               self.valid,
@@ -110,7 +110,7 @@ class CSSVariablesRule(cssrule.CSSRule):
         tokenizer = self._tokenize2(cssText)
         attoken = self._nexttoken(tokenizer, None)
         if self._type(attoken) != self._prods.VARIABLES_SYM:
-            self._log.error(u'CSSVariablesRule: No CSSVariablesRule found: %s' %
+            self._log.error('CSSVariablesRule: No CSSVariablesRule found: %s' %
                             self._valuestr(cssText),
                             error=xml.dom.InvalidModificationErr)
         else:
@@ -120,10 +120,10 @@ class CSSVariablesRule(cssrule.CSSRule):
             beforetokens, brace = self._tokensupto2(tokenizer, 
                                                     blockstartonly=True,
                                                     separateEnd=True)            
-            if self._tokenvalue(brace) != u'{':
+            if self._tokenvalue(brace) != '{':
                 ok = False
-                self._log.error(u'CSSVariablesRule: No start { of variable '
-                                u'declaration found: %r' 
+                self._log.error('CSSVariablesRule: No start { of variable '
+                                'declaration found: %r'
                                 % self._valuestr(cssText), brace)
             
             # parse stuff before { which should be comments and S only
@@ -141,16 +141,16 @@ class CSSVariablesRule(cssrule.CSSRule):
 
             val, type_ = self._tokenvalue(braceorEOFtoken), \
                          self._type(braceorEOFtoken)
-            if val != u'}' and type_ != 'EOF':
+            if val != '}' and type_ != 'EOF':
                 ok = False
-                self._log.error(u'CSSVariablesRule: No "}" after variables '
-                                u'declaration found: %r'
+                self._log.error('CSSVariablesRule: No "}" after variables '
+                                'declaration found: %r'
                                 % self._valuestr(cssText))
                 
             nonetoken = self._nexttoken(tokenizer)
             if nonetoken:
                 ok = False
-                self._log.error(u'CSSVariablesRule: Trailing content found.',
+                self._log.error('CSSVariablesRule: Trailing content found.',
                                 token=nonetoken)
 
             if 'EOF' == type_:
@@ -165,11 +165,11 @@ class CSSVariablesRule(cssrule.CSSRule):
                 self.variables = newVariables
 
     cssText = property(_getCssText, _setCssText,
-                       doc=u"(DOM) The parsable textual representation of this "
-                           u"rule.")
+                       doc="(DOM) The parsable textual representation of this "
+                           "rule.")
 
-    media = property(doc=u"NOT IMPLEMENTED! As cssutils resolves variables "\
-                         u"during serializing media information is lost.")
+    media = property(doc="NOT IMPLEMENTED! As cssutils resolves variables "\
+                         "during serializing media information is lost.")
 
     def _setVariables(self, variables):
         """
@@ -177,7 +177,7 @@ class CSSVariablesRule(cssrule.CSSRule):
             a CSSVariablesDeclaration or string
         """
         self._checkReadonly()
-        if isinstance(variables, basestring):
+        if isinstance(variables, str):
             self._variables = CSSVariablesDeclaration(cssText=variables, 
                                                       parentRule=self)
         else:
@@ -185,12 +185,12 @@ class CSSVariablesRule(cssrule.CSSRule):
             self._variables = variables
 
     variables = property(lambda self: self._variables, _setVariables,
-                         doc=u"(DOM) The variables of this rule set, a "
-                             u":class:`cssutils.css.CSSVariablesDeclaration`.")
+                         doc="(DOM) The variables of this rule set, a "
+                             ":class:`cssutils.css.CSSVariablesDeclaration`.")
 
     type = property(lambda self: self.VARIABLES_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
 
     valid = property(lambda self: True, doc='NOT IMPLEMTED REALLY (TODO)')
     
diff --git a/src/cssutils/css/marginrule.py b/src/cssutils/css/marginrule.py
index 0c789fa..f1301a3 100644
--- a/src/cssutils/css/marginrule.py
+++ b/src/cssutils/css/marginrule.py
@@ -4,8 +4,8 @@ __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
 from cssutils.prodparser import *
-from cssstyledeclaration import CSSStyleDeclaration
-import cssrule
+from .cssstyledeclaration import CSSStyleDeclaration
+from . import cssrule
 import cssutils
 import xml.dom
 
@@ -92,7 +92,7 @@ class MarginRule(cssrule.CSSRule):
         n = self._normalize(margin)
         
         if n not in MarginRule.margins:
-            self._log.error(u'Invalid margin @keyword for this %s rule: %r' %
+            self._log.error('Invalid margin @keyword for this %s rule: %r' %
                             (self.margin, margin),
                             error=xml.dom.InvalidModificationErr)
     
@@ -101,20 +101,20 @@ class MarginRule(cssrule.CSSRule):
             self._keyword = margin
 
     margin = property(lambda self: self._atkeyword, _setMargin,
-                      doc=u"Margin area of parent CSSPageRule. "
-                          u"`margin` and `atkeyword` are both normalized "
-                          u"@keyword of the @rule.")
+                      doc="Margin area of parent CSSPageRule. "
+                          "`margin` and `atkeyword` are both normalized "
+                          "@keyword of the @rule.")
 
     atkeyword = margin 
 
     def __repr__(self):
-        return u"cssutils.css.%s(margin=%r, style=%r)" % (self.__class__.__name__,
+        return "cssutils.css.%s(margin=%r, style=%r)" % (self.__class__.__name__,
                                                           self.margin, 
                                                           self.style.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object margin=%r style=%r "\
-               u"at 0x%x>" % (self.__class__.__name__,
+        return "<cssutils.css.%s object margin=%r style=%r "\
+               "at 0x%x>" % (self.__class__.__name__,
                               self.margin,
                               self.style.cssText,
                               id(self))
@@ -143,7 +143,7 @@ class MarginRule(cssrule.CSSRule):
         # TEMP: all style tokens are saved in store to fill styledeclaration
         # TODO: resolve when all generators
         styletokens = Prod(name='styletokens',
-                           match=lambda t, v: v != u'}',
+                           match=lambda t, v: v != '}',
                            #toSeq=False,
                            toStore='styletokens',
                            storeToken=True 
@@ -157,16 +157,16 @@ class MarginRule(cssrule.CSSRule):
                               # TODO?
                               #, exception=xml.dom.InvalidModificationErr 
                               ),
-                         PreDef.char('OPEN', u'{'),
+                         PreDef.char('OPEN', '{'),
                          Sequence(Choice(PreDef.unknownrule(toStore='@'), 
                                          styletokens),
                                   minmax=lambda: (0, None)
                          ),
-                         PreDef.char('CLOSE', u'}', stopAndKeep=True)
+                         PreDef.char('CLOSE', '}', stopAndKeep=True)
                 )
         # parse
         ok, seq, store, unused = ProdParser().parse(cssText,
-                                                    u'MarginRule',
+                                                    'MarginRule',
                                                     prods)
         
         if ok:
@@ -177,7 +177,7 @@ class MarginRule(cssrule.CSSRule):
                 # may raise:
                 self.margin = store['margin'].value
             else:
-                self._log.error(u'No margin @keyword for this %s rule' %
+                self._log.error('No margin @keyword for this %s rule' %
                                 self.margin,
                                 error=xml.dom.InvalidModificationErr)
             
@@ -190,7 +190,7 @@ class MarginRule(cssrule.CSSRule):
             
                 
     cssText = property(fget=_getCssText, fset=_setCssText,
-                       doc=u"(DOM) The parsable textual representation.")
+                       doc="(DOM) The parsable textual representation.")
     
     def _setStyle(self, style):
         """
@@ -198,18 +198,18 @@ class MarginRule(cssrule.CSSRule):
             current style object.
         """
         self._checkReadonly()
-        if isinstance(style, basestring):
+        if isinstance(style, str):
             self._style = CSSStyleDeclaration(cssText=style, parentRule=self)
         else:
             style._parentRule = self
             self._style = style
 
     style = property(lambda self: self._style, _setStyle,
-                     doc=u"(DOM) The declaration-block of this rule set.")
+                     doc="(DOM) The declaration-block of this rule set.")
     
     type = property(lambda self: self.MARGIN_RULE, 
-                    doc=u"The type of this rule, as defined by a CSSRule "
-                        u"type constant.")
+                    doc="The type of this rule, as defined by a CSSRule "
+                        "type constant.")
     
     wellformed = property(lambda self: bool(self.atkeyword))
     
\ No newline at end of file
diff --git a/src/cssutils/css/property.py b/src/cssutils/css/property.py
index fad240c..8490982 100644
--- a/src/cssutils/css/property.py
+++ b/src/cssutils/css/property.py
@@ -4,7 +4,7 @@ __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
 from cssutils.helper import Deprecated
-from value import PropertyValue
+from .value import PropertyValue
 import cssutils
 import xml.dom
 
@@ -43,7 +43,7 @@ class Property(cssutils.util.Base):
           ;
 
     """
-    def __init__(self, name=None, value=None, priority=u'',
+    def __init__(self, name=None, value=None, priority='',
                  _mediaQuery=False, parent=None):
         """
         :param name:
@@ -66,27 +66,27 @@ class Property(cssutils.util.Base):
         self.parent = parent
 
         self.__nametoken = None
-        self._name = u''
-        self._literalname = u''
+        self._name = ''
+        self._literalname = ''
         self.seqs[1] = PropertyValue(parent=self)
         if name:
             self.name = name
             self.propertyValue = value
 
-        self._priority = u''
-        self._literalpriority = u''
+        self._priority = ''
+        self._literalpriority = ''
         if priority:
             self.priority = priority
 
     def __repr__(self):
-        return u"cssutils.css.%s(name=%r, value=%r, priority=%r)" % (
+        return "cssutils.css.%s(name=%r, value=%r, priority=%r)" % (
                 self.__class__.__name__,
                 self.literalname,
                 self.propertyValue.cssText,
                 self.priority)
 
     def __str__(self):
-        return u"<%s.%s object name=%r value=%r priority=%r valid=%r at 0x%x>" \
+        return "<%s.%s object name=%r value=%r priority=%r valid=%r at 0x%x>" \
                % (self.__class__.__module__,
                   self.__class__.__name__,
                   self.name,
@@ -136,22 +136,22 @@ class Property(cssutils.util.Base):
 
             # remove colon from nametokens
             colontoken = nametokens.pop()
-            if self._tokenvalue(colontoken) != u':':
+            if self._tokenvalue(colontoken) != ':':
                 wellformed = False
-                self._log.error(u'Property: No ":" after name found: %s' %
+                self._log.error('Property: No ":" after name found: %s' %
                                 self._valuestr(cssText), colontoken)
             elif not nametokens:
                 wellformed = False
-                self._log.error(u'Property: No property name found: %s' %
+                self._log.error('Property: No property name found: %s' %
                             self._valuestr(cssText), colontoken)
 
             if valuetokens:
-                if self._tokenvalue(valuetokens[-1]) == u'!':
+                if self._tokenvalue(valuetokens[-1]) == '!':
                     # priority given, move "!" to prioritytokens
                     prioritytokens.insert(0, valuetokens.pop(-1))
             else:
                 wellformed = False
-                self._log.error(u'Property: No property value found: %s' %
+                self._log.error('Property: No property value found: %s' %
                                 self._valuestr(cssText), colontoken)
 
             if wellformed:
@@ -166,7 +166,7 @@ class Property(cssutils.util.Base):
                     self.validate()
 
         else:
-            self._log.error(u'Property: No property name found: %s' %
+            self._log.error('Property: No property name found: %s' %
                             self._valuestr(cssText))
 
     cssText = property(fget=_getCssText, fset=_setCssText,
@@ -191,7 +191,7 @@ class Property(cssutils.util.Base):
                 return 'EOF'
             else:
                 new['wellformed'] = False
-                self._log.error(u'Property: Unexpected ident.', token)
+                self._log.error('Property: Unexpected ident.', token)
                 return expected
 
         newseq = []
@@ -211,7 +211,7 @@ class Property(cssutils.util.Base):
 
         if not new['literalname']:
             wellformed = False
-            self._log.error(u'Property: No name found: %s' %
+            self._log.error('Property: No name found: %s' %
                 self._valuestr(name), token=token)
 
         if wellformed:
@@ -223,7 +223,7 @@ class Property(cssutils.util.Base):
             # validate
             if self._isValidating() and self._name not in cssutils.profile.knownNames:
                 # self.valid = False
-                self._log.warn(u'Property: Unknown Property name.',
+                self._log.warn('Property: Unknown Property name.',
                                token=token, neverraise=True)
             else:
                 pass
@@ -261,7 +261,7 @@ class Property(cssutils.util.Base):
 
     propertyValue = property(lambda self: self.seqs[1],
                              _setPropertyValue,
-                             doc=u"(cssutils) PropertyValue object of property")
+                             doc="(cssutils) PropertyValue object of property")
 
 
     def _getValue(self):
@@ -269,7 +269,7 @@ class Property(cssutils.util.Base):
             # value without comments
             return self.propertyValue.value
         else:
-            return u''
+            return ''
 
     def _setValue(self, value):
         self._setPropertyValue(value)
@@ -300,30 +300,30 @@ class Property(cssutils.util.Base):
               priority
         """
         if self._mediaQuery:
-            self._priority = u''
-            self._literalpriority = u''
+            self._priority = ''
+            self._literalpriority = ''
             if priority:
-                self._log.error(u'Property: No priority in a MediaQuery - '
-                                u'ignored.')
+                self._log.error('Property: No priority in a MediaQuery - '
+                                'ignored.')
             return
 
-        if isinstance(priority, basestring) and\
-           u'important' == self._normalize(priority):
-            priority = u'!%s' % priority
+        if isinstance(priority, str) and\
+           'important' == self._normalize(priority):
+            priority = '!%s' % priority
 
         # for closures: must be a mutable
-        new = {'literalpriority': u'',
+        new = {'literalpriority': '',
                'wellformed': True}
 
         def _char(expected, seq, token, tokenizer=None):
             # "!"
             val = self._tokenvalue(token)
-            if u'!' == expected == val:
+            if '!' == expected == val:
                 seq.append(val)
                 return 'important'
             else:
                 new['wellformed'] = False
-                self._log.error(u'Property: Unexpected char.', token)
+                self._log.error('Property: Unexpected char.', token)
                 return expected
 
         def _ident(expected, seq, token, tokenizer=None):
@@ -335,7 +335,7 @@ class Property(cssutils.util.Base):
                 return 'EOF'
             else:
                 new['wellformed'] = False
-                self._log.error(u'Property: Unexpected ident.', token)
+                self._log.error('Property: Unexpected ident.', token)
                 return expected
 
         newseq = []
@@ -349,7 +349,7 @@ class Property(cssutils.util.Base):
         # post conditions
         if priority and not new['literalpriority']:
             wellformed = False
-            self._log.info(u'Property: Invalid priority: %s' %
+            self._log.info('Property: Invalid priority: %s' %
                            self._valuestr(priority))
 
         if wellformed:
@@ -358,8 +358,8 @@ class Property(cssutils.util.Base):
             self._priority = self._normalize(self.literalpriority)
             self.seqs[2] = newseq
             # validate priority
-            if self._priority not in (u'', u'important'):
-                self._log.error(u'Property: No CSS priority value: %s' %
+            if self._priority not in ('', 'important'):
+                self._log.error('Property: No CSS priority value: %s' %
                                 self._priority)
 
     priority = property(lambda self: self._priority, _setPriority,
@@ -463,46 +463,46 @@ class Property(cssutils.util.Base):
                                                          profiles)
 
                 if not valid:
-                    self._log.error(u'Property: Invalid value for '
-                                    u'"%s" property: %s'
-                                    % (u'/'.join(validprofiles), self.value),
+                    self._log.error('Property: Invalid value for '
+                                    '"%s" property: %s'
+                                    % ('/'.join(validprofiles), self.value),
                                     token=self.__nametoken,
                                     neverraise=True)
 
                 # TODO: remove logic to profiles!
                 elif valid and not matching:#(profiles and profiles not in validprofiles):
                     if not profiles:
-                        notvalidprofiles = u'/'.join(cssutils.profile.defaultProfiles)
+                        notvalidprofiles = '/'.join(cssutils.profile.defaultProfiles)
                     else:
                         notvalidprofiles = profiles
-                    self._log.warn(u'Property: Not valid for profile "%s" '
-                                   u'but valid "%s" value: %s '
-                                   % (notvalidprofiles, u'/'.join(validprofiles),
+                    self._log.warn('Property: Not valid for profile "%s" '
+                                   'but valid "%s" value: %s '
+                                   % (notvalidprofiles, '/'.join(validprofiles),
                                       self.value),
                                    token = self.__nametoken,
                                    neverraise=True)
                     valid = False
 
                 elif valid:
-                    self._log.debug(u'Property: Found valid "%s" value: %s'
-                                   % (u'/'.join(validprofiles), self.value),
+                    self._log.debug('Property: Found valid "%s" value: %s'
+                                   % ('/'.join(validprofiles), self.value),
                                    token = self.__nametoken,
                                    neverraise=True)
 
-        if self._priority not in (u'', u'important'):
+        if self._priority not in ('', 'important'):
             valid = False
 
         return valid
 
-    valid = property(validate, doc=u"Check if value of this property is valid "
-                                   u"in the properties context.")
+    valid = property(validate, doc="Check if value of this property is valid "
+                                   "in the properties context.")
 
 
-    @Deprecated(u'Use ``property.propertyValue`` instead.')
+    @Deprecated('Use ``property.propertyValue`` instead.')
     def _getCSSValue(self):
         return self.propertyValue
 
-    @Deprecated(u'Use ``property.propertyValue`` instead.')
+    @Deprecated('Use ``property.propertyValue`` instead.')
     def _setCSSValue(self, cssText):
         self._setPropertyValue(cssText)
 
diff --git a/src/cssutils/css/selector.py b/src/cssutils/css/selector.py
index 87840a0..2c858c7 100644
--- a/src/cssutils/css/selector.py
+++ b/src/cssutils/css/selector.py
@@ -127,12 +127,12 @@ class Selector(cssutils.util.Base2):
             st = (self.selectorText, self._getUsedNamespaces())
         else:
             st = self.selectorText
-        return u"cssutils.css.%s(selectorText=%r)" % (self.__class__.__name__, 
+        return "cssutils.css.%s(selectorText=%r)" % (self.__class__.__name__,
                                                       st)
 
     def __str__(self):
-        return u"<cssutils.css.%s object selectorText=%r specificity=%r" \
-               u" _namespaces=%r at 0x%x>" % (self.__class__.__name__,
+        return "<cssutils.css.%s object selectorText=%r specificity=%r" \
+               " _namespaces=%r at 0x%x>" % (self.__class__.__name__,
                                               self.selectorText,
                                               self.specificity,
                                               self._getUsedNamespaces(),
@@ -143,8 +143,8 @@ class Selector(cssutils.util.Base2):
         uris = set()
         for item in self.seq:
             type_, val = item.type, item.value
-            if type_.endswith(u'-selector') or type_ == u'universal' and \
-               isinstance(val, tuple) and val[0] not in (None, u'*'):
+            if type_.endswith('-selector') or type_ == 'universal' and \
+               isinstance(val, tuple) and val[0] not in (None, '*'):
                 uris.add(val[0])
         return uris
 
@@ -152,7 +152,7 @@ class Selector(cssutils.util.Base2):
         "Return actually used namespaces only."
         useduris = self._getUsedUris()
         namespaces = _SimpleNamespaces(log=self._log)
-        for p, uri in self._namespaces.items():
+        for p, uri in list(self._namespaces.items()):
             if uri in useduris:
                 namespaces[p] = uri
         return namespaces
@@ -165,21 +165,21 @@ class Selector(cssutils.util.Base2):
             return self.__namespaces
 
     _namespaces = property(__getNamespaces, 
-                           doc=u"If this Selector is attached to a "
-                               u"CSSStyleSheet the namespaces of that sheet "
-                               u"are mirrored here. While the Selector (or "
-                               u"parent SelectorList or parentRule(s) of that "
-                               u"are not attached a own dict of {prefix: "
-                               u"namespaceURI} is used.")
+                           doc="If this Selector is attached to a "
+                               "CSSStyleSheet the namespaces of that sheet "
+                               "are mirrored here. While the Selector (or "
+                               "parent SelectorList or parentRule(s) of that "
+                               "are not attached a own dict of {prefix: "
+                               "namespaceURI} is used.")
 
     
     element = property(lambda self: self._element, 
-                       doc=u"Effective element target of this selector.")
+                       doc="Effective element target of this selector.")
 
     parent = property(lambda self: self._parent,
-                      doc=u"(DOM) The SelectorList that contains this Selector "
-                          u"or None if this Selector is not attached to a "
-                          u"SelectorList.")
+                      doc="(DOM) The SelectorList that contains this Selector "
+                          "or None if this Selector is not attached to a "
+                          "SelectorList.")
                 
     def _getSelectorText(self):
         """Return serialized format."""
@@ -215,7 +215,7 @@ class Selector(cssutils.util.Base2):
             pass
         tokenizer = self._tokenize2(selectorText)
         if not tokenizer:
-            self._log.error(u'Selector: No selectorText given.')
+            self._log.error('Selector: No selectorText given.')
         else:
             # prepare tokenlist:
             #     "*" -> type "universal"
@@ -228,54 +228,54 @@ class Selector(cssutils.util.Base2):
             tokens = []
             for t in tokenizer:
                 typ, val, lin, col = t
-                if val == u':' and tokens and\
+                if val == ':' and tokens and\
                    self._tokenvalue(tokens[-1]) == ':':
                     # combine ":" and ":"
-                    tokens[-1] = (typ, u'::', lin, col)
+                    tokens[-1] = (typ, '::', lin, col)
 
                 elif typ == 'IDENT' and tokens\
-                     and self._tokenvalue(tokens[-1]) == u'.':
+                     and self._tokenvalue(tokens[-1]) == '.':
                     # class: combine to .IDENT
-                    tokens[-1] = ('class', u'.'+val, lin, col)
+                    tokens[-1] = ('class', '.'+val, lin, col)
                 elif typ == 'IDENT' and tokens and \
-                     self._tokenvalue(tokens[-1]).startswith(u':') and\
-                     not self._tokenvalue(tokens[-1]).endswith(u'('):
+                     self._tokenvalue(tokens[-1]).startswith(':') and\
+                     not self._tokenvalue(tokens[-1]).endswith('('):
                     # pseudo-X: combine to :IDENT or ::IDENT but not ":a(" + "b"
-                    if self._tokenvalue(tokens[-1]).startswith(u'::'): 
+                    if self._tokenvalue(tokens[-1]).startswith('::'):
                         t = 'pseudo-element'
                     else: 
                         t = 'pseudo-class'
                     tokens[-1] = (t, self._tokenvalue(tokens[-1])+val, lin, col)
 
-                elif typ == 'FUNCTION' and val == u'not(' and tokens and \
-                     u':' == self._tokenvalue(tokens[-1]):
-                    tokens[-1] = ('negation', u':' + val, lin, tokens[-1][3])
+                elif typ == 'FUNCTION' and val == 'not(' and tokens and \
+                     ':' == self._tokenvalue(tokens[-1]):
+                    tokens[-1] = ('negation', ':' + val, lin, tokens[-1][3])
                 elif typ == 'FUNCTION' and tokens\
-                     and self._tokenvalue(tokens[-1]).startswith(u':'):
+                     and self._tokenvalue(tokens[-1]).startswith(':'):
                     # pseudo-X: combine to :FUNCTION( or ::FUNCTION(
-                    if self._tokenvalue(tokens[-1]).startswith(u'::'): 
+                    if self._tokenvalue(tokens[-1]).startswith('::'):
                         t = 'pseudo-element'
                     else: 
                         t = 'pseudo-class'
                     tokens[-1] = (t, self._tokenvalue(tokens[-1])+val, lin, col)
 
-                elif val == u'*' and tokens and\
+                elif val == '*' and tokens and\
                      self._type(tokens[-1]) == 'namespace_prefix' and\
-                     self._tokenvalue(tokens[-1]).endswith(u'|'):
+                     self._tokenvalue(tokens[-1]).endswith('|'):
                     # combine prefix|*
                     tokens[-1] = ('universal', self._tokenvalue(tokens[-1])+val, 
                                   lin, col)
-                elif val == u'*':
+                elif val == '*':
                     # universal: "*"
                     tokens.append(('universal', val, lin, col))
 
-                elif val == u'|' and tokens and\
+                elif val == '|' and tokens and\
                      self._type(tokens[-1]) in (self._prods.IDENT, 'universal')\
-                     and self._tokenvalue(tokens[-1]).find(u'|') == -1:
+                     and self._tokenvalue(tokens[-1]).find('|') == -1:
                     # namespace_prefix: "IDENT|" or "*|"
                     tokens[-1] = ('namespace_prefix', 
-                                  self._tokenvalue(tokens[-1])+u'|', lin, col)
-                elif val == u'|':
+                                  self._tokenvalue(tokens[-1])+'|', lin, col)
+                elif val == '|':
                     # namespace_prefix: "|"
                     tokens.append(('namespace_prefix', val, lin, col))
 
@@ -292,7 +292,7 @@ class Selector(cssutils.util.Base2):
                    'wellformed': True
                    }
             # used for equality checks and setting of a space combinator
-            S = u' '
+            S = ' '
 
             def append(seq, val, typ=None, token=None):
                 """
@@ -331,16 +331,16 @@ class Selector(cssutils.util.Base2):
                 if (typ.endswith('-selector') or typ == 'universal') and not (
                     'attribute-selector' == typ and not prefix):
                     # att **IS NOT** in default ns
-                    if prefix == u'*':
+                    if prefix == '*':
                         # *|name: in ANY_NS
                         namespaceURI = cssutils._ANYNS
                     elif prefix is None:
                         # e or *: default namespace with prefix u'' 
                         # or local-name()
-                        namespaceURI = namespaces.get(u'', None)
-                    elif prefix == u'':
+                        namespaceURI = namespaces.get('', None)
+                    elif prefix == '':
                         # |name or |*: in no (or the empty) namespace
-                        namespaceURI = u''
+                        namespaceURI = ''
                     else:
                         # explicit namespace prefix
                         # does not raise KeyError, see _SimpleNamespaces
@@ -348,8 +348,8 @@ class Selector(cssutils.util.Base2):
 
                         if namespaceURI is None:
                             new['wellformed'] = False
-                            self._log.error(u'Selector: No namespaceURI found '
-                                            u'for prefix %r' % prefix, 
+                            self._log.error('Selector: No namespaceURI found '
+                                            'for prefix %r' % prefix,
                                             token=token, 
                                             error=xml.dom.NamespaceErr)
                             return
@@ -403,7 +403,7 @@ class Selector(cssutils.util.Base2):
                 # S
                 context = new['context'][-1]
                 if context.startswith('pseudo-'):
-                    if seq and seq[-1].value not in u'+-':
+                    if seq and seq[-1].value not in '+-':
                         # e.g. x:func(a + b)
                         append(seq, S, 'S', token=token)
                     return expected
@@ -430,7 +430,7 @@ class Selector(cssutils.util.Base2):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Unexpected universal.', token=token)
+                        'Selector: Unexpected universal.', token=token)
                     return expected
 
             def _namespace_prefix(expected, seq, token, tokenizer=None):
@@ -449,7 +449,7 @@ class Selector(cssutils.util.Base2):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Unexpected namespace prefix.', token=token)
+                        'Selector: Unexpected namespace prefix.', token=token)
                     return expected
 
             def _pseudo(expected, seq, token, tokenizer=None):
@@ -474,7 +474,7 @@ class Selector(cssutils.util.Base2):
                         typ = 'pseudo-element'
                     append(seq, val, typ, token=token)
                     
-                    if val.endswith(u'('):
+                    if val.endswith('('):
                         # function
                         # "pseudo-" "class" or "element"
                         new['context'].append(typ) 
@@ -490,7 +490,7 @@ class Selector(cssutils.util.Base2):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Unexpected start of pseudo.', token=token)
+                        'Selector: Unexpected start of pseudo.', token=token)
                     return expected
 
             def _expression(expected, seq, token, tokenizer=None):
@@ -503,7 +503,7 @@ class Selector(cssutils.util.Base2):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Unexpected %s.' % typ, token=token)
+                        'Selector: Unexpected %s.' % typ, token=token)
                     return expected
 
             def _attcombinator(expected, seq, token, tokenizer=None):
@@ -519,7 +519,7 @@ class Selector(cssutils.util.Base2):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Unexpected %s.' % typ, token=token)
+                        'Selector: Unexpected %s.' % typ, token=token)
                     return expected
 
             def _string(expected, seq, token, tokenizer=None):
@@ -542,7 +542,7 @@ class Selector(cssutils.util.Base2):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Unexpected STRING.', token=token)
+                        'Selector: Unexpected STRING.', token=token)
                     return expected
 
             def _ident(expected, seq, token, tokenizer=None):
@@ -580,7 +580,7 @@ class Selector(cssutils.util.Base2):
 
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'Selector: Unexpected IDENT.', token=token)
+                    self._log.error('Selector: Unexpected IDENT.', token=token)
                     return expected
 
             def _class(expected, seq, token, tokenizer=None):
@@ -597,7 +597,7 @@ class Selector(cssutils.util.Base2):
 
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'Selector: Unexpected class.', token=token)
+                    self._log.error('Selector: Unexpected class.', token=token)
                     return expected
 
             def _hash(expected, seq, token, tokenizer=None):
@@ -614,7 +614,7 @@ class Selector(cssutils.util.Base2):
 
                 else:
                     new['wellformed'] = False
-                    self._log.error(u'Selector: Unexpected HASH.', token=token)
+                    self._log.error('Selector: Unexpected HASH.', token=token)
                     return expected
 
             def _char(expected, seq, token, tokenizer=None):
@@ -623,7 +623,7 @@ class Selector(cssutils.util.Base2):
                 val = self._tokenvalue(token)
                 
                 # context: attrib
-                if u']' == val and 'attrib' == context and ']' in expected:
+                if ']' == val and 'attrib' == context and ']' in expected:
                     # end of attrib
                     append(seq, val, 'attribute-end', token=token)
                     context = new['context'].pop() # attrib is done
@@ -633,14 +633,14 @@ class Selector(cssutils.util.Base2):
                     else:
                         return simple_selector_sequence2 + combinator
 
-                elif u'=' == val and 'attrib' == context\
+                elif '=' == val and 'attrib' == context\
                      and 'combinator' in expected:
                     # combinator in attrib
                     append(seq, val, 'equals', token=token)
                     return attvalue
 
                 # context: negation
-                elif u')' == val and 'negation' == context and u')' in expected:
+                elif ')' == val and 'negation' == context and ')' in expected:
                     # not(negation_arg)"
                     append(seq, val, 'negation-end', token=token)
                     new['context'].pop() # negation is done
@@ -648,17 +648,17 @@ class Selector(cssutils.util.Base2):
                     return simple_selector_sequence + combinator                
 
                 # context: pseudo (at least one expression)
-                elif val in u'+-' and context.startswith('pseudo-'):
+                elif val in '+-' and context.startswith('pseudo-'):
                     # :func(+ -)"
                     _names = {'+': 'plus', '-': 'minus'}
-                    if val == u'+' and seq and seq[-1].value == S:
+                    if val == '+' and seq and seq[-1].value == S:
                         seq.replace(-1, val, _names[val])
                     else:
                         append(seq, val, _names[val], 
                                token=token)
                     return expression                
 
-                elif u')' == val and context.startswith('pseudo-') and\
+                elif ')' == val and context.startswith('pseudo-') and\
                      expression == expected:
                     # :func(expression)"
                     append(seq, val, 'function-end', token=token)
@@ -669,13 +669,13 @@ class Selector(cssutils.util.Base2):
                         return simple_selector_sequence + combinator                
 
                 # context: ROOT                
-                elif u'[' == val and 'attrib' in expected:
+                elif '[' == val and 'attrib' in expected:
                     # start of [attrib]
                     append(seq, val, 'attribute-start', token=token)
                     new['context'].append('attrib')
                     return attname
 
-                elif val in u'+>~' and 'combinator' in expected:
+                elif val in '+>~' and 'combinator' in expected:
                     # no other combinator except S may be following
                     _names = {
                         '>': 'child',
@@ -687,11 +687,11 @@ class Selector(cssutils.util.Base2):
                         append(seq, val, _names[val], token=token)
                     return simple_selector_sequence
 
-                elif u',' == val:
+                elif ',' == val:
                     # not a selectorlist
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Single selector only.', 
+                        'Selector: Single selector only.',
                         error=xml.dom.InvalidModificationErr, 
                         token=token)
                     return expected
@@ -699,7 +699,7 @@ class Selector(cssutils.util.Base2):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Unexpected CHAR.', token=token)
+                        'Selector: Unexpected CHAR.', token=token)
                     return expected
 
             def _negation(expected, seq, token, tokenizer=None):
@@ -713,14 +713,14 @@ class Selector(cssutils.util.Base2):
                 else:
                     new['wellformed'] = False
                     self._log.error(
-                        u'Selector: Unexpected negation.', token=token)
+                        'Selector: Unexpected negation.', token=token)
                     return expected
 
             def _atkeyword(expected, seq, token, tokenizer=None):
                 "invalidates selector"
                 new['wellformed'] = False
                 self._log.error(
-                        u'Selector: Unexpected ATKEYWORD.', token=token)
+                        'Selector: Unexpected ATKEYWORD.', token=token)
                 return expected
 
 
@@ -758,21 +758,21 @@ class Selector(cssutils.util.Base2):
             # post condition         
             if len(new['context']) > 1 or not newseq:
                 wellformed = False
-                self._log.error(u'Selector: Invalid or incomplete selector: %s' 
+                self._log.error('Selector: Invalid or incomplete selector: %s'
                                 % self._valuestr(selectorText))
             
             if expected == 'element_name':
                 wellformed = False
-                self._log.error(u'Selector: No element name found: %s'
+                self._log.error('Selector: No element name found: %s'
                                 % self._valuestr(selectorText))
 
             if expected == simple_selector_sequence and newseq:
                 wellformed = False
-                self._log.error(u'Selector: Cannot end with combinator: %s'
+                self._log.error('Selector: Cannot end with combinator: %s'
                                 % self._valuestr(selectorText))
 
             if newseq and hasattr(newseq[-1].value, 'strip') \
-               and newseq[-1].value.strip() == u'':
+               and newseq[-1].value.strip() == '':
                 del newseq[-1]
 
             # set
@@ -785,8 +785,8 @@ class Selector(cssutils.util.Base2):
                 self.__namespaces = self._getUsedNamespaces()
 
     selectorText = property(_getSelectorText, _setSelectorText,
-                            doc=u"(DOM) The parsable textual representation of "
-                                u"the selector.")
+                            doc="(DOM) The parsable textual representation of "
+                                "the selector.")
 
     specificity = property(lambda self: self._specificity, 
          doc="""Specificity of this selector (READONLY). 
diff --git a/src/cssutils/css/selectorlist.py b/src/cssutils/css/selectorlist.py
index 2072cd5..184ca92 100644
--- a/src/cssutils/css/selectorlist.py
+++ b/src/cssutils/css/selectorlist.py
@@ -19,7 +19,7 @@ __all__ = ['SelectorList']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from selector import Selector
+from .selector import Selector
 import cssutils
 import xml.dom
 
@@ -49,12 +49,12 @@ class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
             st = (self.selectorText, self._namespaces)
         else:
             st = self.selectorText
-        return u"cssutils.css.%s(selectorText=%r)" % (self.__class__.__name__, 
+        return "cssutils.css.%s(selectorText=%r)" % (self.__class__.__name__,
                                                       st)
 
     def __str__(self):
-        return u"<cssutils.css.%s object selectorText=%r _namespaces=%r at " \
-               u"0x%x>" % (self.__class__.__name__,
+        return "<cssutils.css.%s object selectorText=%r _namespaces=%r at " \
+               "0x%x>" % (self.__class__.__name__,
                            self.selectorText,
                            self._namespaces,
                            id(self))
@@ -200,35 +200,35 @@ class SelectorList(cssutils.util.Base, cssutils.util.ListSeq):
                     newseq.append(selector)
                 else:
                     wellformed = False
-                    self._log.error(u'SelectorList: Invalid Selector: %s' %
+                    self._log.error('SelectorList: Invalid Selector: %s' %
                                     self._valuestr(selectortokens))
             else:
                 break
 
         # post condition
-        if u',' == expected:
+        if ',' == expected:
             wellformed = False
-            self._log.error(u'SelectorList: Cannot end with ",": %r' %
+            self._log.error('SelectorList: Cannot end with ",": %r' %
                             self._valuestr(selectorText))
         elif expected:
             wellformed = False
-            self._log.error(u'SelectorList: Unknown Syntax: %r' %
+            self._log.error('SelectorList: Unknown Syntax: %r' %
                             self._valuestr(selectorText))
         if wellformed:
             self.seq = newseq
 
     selectorText = property(_getSelectorText, _setSelectorText,
-                            doc=u"(cssutils) The textual representation of the "
-                                u"selector for a rule set.")
+                            doc="(cssutils) The textual representation of the "
+                                "selector for a rule set.")
 
     length = property(lambda self: len(self),
-                      doc=u"The number of :class:`~cssutils.css.Selector` "
-                          u"objects in the list.")
+                      doc="The number of :class:`~cssutils.css.Selector` "
+                          "objects in the list.")
 
     parentRule = property(lambda self: self._parentRule,
-                          doc=u"(DOM) The CSS rule that contains this "
-                              u"SelectorList or ``None`` if this SelectorList "
-                              u"is not attached to a CSSRule.")
+                          doc="(DOM) The CSS rule that contains this "
+                              "SelectorList or ``None`` if this SelectorList "
+                              "is not attached to a CSSRule.")
 
     wellformed = property(lambda self: bool(len(self.seq)))
 
diff --git a/src/cssutils/css/value.py b/src/cssutils/css/value.py
index 22d91ba..34c9a12 100644
--- a/src/cssutils/css/value.py
+++ b/src/cssutils/css/value.py
@@ -23,7 +23,7 @@ import colorsys
 import math
 import re
 import xml.dom
-import urlparse
+import urllib.parse
 
 class PropertyValue(cssutils.util._NewBase):
     """
@@ -53,7 +53,7 @@ class PropertyValue(cssutils.util._NewBase):
 
         if cssText is not None: # may be 0
             if isinstance(cssText, (int, float)):
-                cssText = unicode(cssText) # if it is a number
+                cssText = str(cssText) # if it is a number
             self.cssText = cssText
 
         self._readonly = readonly
@@ -73,12 +73,12 @@ class PropertyValue(cssutils.util._NewBase):
             yield item
 
     def __repr__(self):
-        return u"cssutils.css.%s(%r)" % (self.__class__.__name__,
+        return "cssutils.css.%s(%r)" % (self.__class__.__name__,
                                          self.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object length=%r cssText=%r at "\
-               u"0x%x>" % (self.__class__.__name__,
+        return "<cssutils.css.%s object length=%r cssText=%r at "\
+               "0x%x>" % (self.__class__.__name__,
                            self.length, self.cssText, id(self))
 
     def __items(self, seq=None):
@@ -89,7 +89,7 @@ class PropertyValue(cssutils.util._NewBase):
 
     def _setCssText(self, cssText):
         if isinstance(cssText, (int, float)):
-            cssText = unicode(cssText) # if it is a number
+            cssText = str(cssText) # if it is a number
         """
         Format::
 
@@ -135,7 +135,7 @@ class PropertyValue(cssutils.util._NewBase):
         self._checkReadonly()
 
         # used as operator is , / or S
-        nextSor = u',/'
+        nextSor = ',/'
         term = Choice(_ColorProd(self, nextSor),
                       _DimensionProd(self, nextSor),
                       _URIProd(self, nextSor),
@@ -169,7 +169,7 @@ class PropertyValue(cssutils.util._NewBase):
                                   minmax=lambda: (0, None)))
         # parse
         ok, seq, store, unused = ProdParser().parse(cssText,
-                                                    u'PropertyValue',
+                                                    'PropertyValue',
                                                     prods)
         # must be at least one value!
         ok = ok and len(list(self.__items(seq))) > 0
@@ -183,7 +183,7 @@ class PropertyValue(cssutils.util._NewBase):
         if ok:
             self._setSeq(seq)
         else:
-            self._log.error(u'PropertyValue: Unknown syntax or no value: %s' %
+            self._log.error('PropertyValue: Unknown syntax or no value: %s' %
                             self._valuestr(cssText))
 
     cssText = property(lambda self: cssutils.ser.do_css_PropertyValue(self),
@@ -204,12 +204,12 @@ class PropertyValue(cssutils.util._NewBase):
         return self[index]
 
     length = property(lambda self: len(self),
-                      doc=u"Number of values set.")
+                      doc="Number of values set.")
 
     value = property(lambda self: cssutils.ser.do_css_PropertyValue(self,
                                                                     valuesOnly=True),
-                       doc=u"A string representation of the current value "
-                           u"without any comments used for validation.")
+                       doc="A string representation of the current value "
+                           "without any comments used for validation.")
 
 
 class Value(cssutils.util._NewBase):
@@ -219,24 +219,24 @@ class Value(cssutils.util._NewBase):
     as Value objects. Other values like e.g. FUNCTIONs are represented by
     subclasses with an extended API.
     """
-    IDENT = u'IDENT'
-    STRING = u'STRING'
-    UNICODE_RANGE = u'UNICODE-RANGE'
-    URI = u'URI'
+    IDENT = 'IDENT'
+    STRING = 'STRING'
+    UNICODE_RANGE = 'UNICODE-RANGE'
+    URI = 'URI'
 
-    DIMENSION = u'DIMENSION'
-    NUMBER = u'NUMBER'
-    PERCENTAGE = u'PERCENTAGE'
+    DIMENSION = 'DIMENSION'
+    NUMBER = 'NUMBER'
+    PERCENTAGE = 'PERCENTAGE'
 
-    COLOR_VALUE = u'COLOR_VALUE'
-    HASH = u'HASH'
+    COLOR_VALUE = 'COLOR_VALUE'
+    HASH = 'HASH'
 
-    FUNCTION = u'FUNCTION'
-    CALC = u'CALC'
-    VARIABLE = u'VARIABLE'
+    FUNCTION = 'FUNCTION'
+    CALC = 'CALC'
+    VARIABLE = 'VARIABLE'
 
     _type = None
-    _value = u''
+    _value = ''
 
     def __init__(self, cssText=None, parent=None, readonly=False):
         super(Value, self).__init__()
@@ -248,11 +248,11 @@ class Value(cssutils.util._NewBase):
             self.cssText = cssText
 
     def __repr__(self):
-        return u"cssutils.css.%s(%r)" % (self.__class__.__name__,
+        return "cssutils.css.%s(%r)" % (self.__class__.__name__,
                                          self.cssText)
 
     def __str__(self):
-        return u"<cssutils.css.%s object type=%s value=%r cssText=%r at 0x%x>"\
+        return "<cssutils.css.%s object type=%s value=%r cssText=%r at 0x%x>"\
                % (self.__class__.__name__,
                   self.type, self.value, self.cssText,
                   id(self))
@@ -265,7 +265,7 @@ class Value(cssutils.util._NewBase):
                        PreDef.string(stop=True),
                        PreDef.unicode_range(stop=True),
                        )
-        ok, seq, store, unused = ProdParser().parse(cssText, u'Value', prods)
+        ok, seq, store, unused = ProdParser().parse(cssText, 'Value', prods)
         self.wellformed = ok
         if ok:
             # only 1 value anyway!
@@ -276,20 +276,20 @@ class Value(cssutils.util._NewBase):
 
     cssText = property(lambda self: cssutils.ser.do_css_Value(self),
                        _setCssText,
-                       doc=u'String value of this value.')
+                       doc='String value of this value.')
 
     type = property(lambda self: self._type, #_setType,
-                    doc=u"Type of this value, for now the production type "
-                        u"like e.g. `DIMENSION` or `STRING`. All types are "
-                        u"defined as constants in :class:`~cssutils.css.Value`.")
+                    doc="Type of this value, for now the production type "
+                        "like e.g. `DIMENSION` or `STRING`. All types are "
+                        "defined as constants in :class:`~cssutils.css.Value`.")
 
     def _setValue(self, value):
         # TODO: check!
         self._value = value
 
     value = property(lambda self: self._value, _setValue,
-                     doc=u"Actual value if possible: An int or float or else "
-                         u" a string")
+                     doc="Actual value if possible: An int or float or else "
+                         " a string")
 
 
 class ColorValue(Value):
@@ -298,7 +298,7 @@ class ColorValue(Value):
 
     TODO: Color Keywords
     """
-    from colors import COLORS
+    from .colors import COLORS
 
     type = Value.COLOR_VALUE
     # hexcolor, FUNCTION?
@@ -309,8 +309,8 @@ class ColorValue(Value):
     _alpha = 0
 
     def __str__(self):
-        return u"<cssutils.css.%s object type=%s value=%r colorType=%r "\
-               u"red=%s blue=%s green=%s alpha=%s at 0x%x>"\
+        return "<cssutils.css.%s object type=%s value=%r colorType=%r "\
+               "red=%s blue=%s green=%s alpha=%s at 0x%x>"\
                % (self.__class__.__name__,
                   self.type, self.value,
                   self.colorType, self.red, self.green, self.blue, self.alpha,
@@ -335,7 +335,7 @@ class ColorValue(Value):
                    )
         noalp = Sequence(Prod(name='FUNCTION',
                               match=lambda t, v: t == types.FUNCTION and
-                                                 v in (u'rgb(', u'hsl('),
+                                                 v in ('rgb(', 'hsl('),
                               toSeq=lambda t, tokens: (t[0], normalize(t[1]))),
                           component,
                           Sequence(PreDef.comma(optional=True),
@@ -346,7 +346,7 @@ class ColorValue(Value):
                           )
         witha = Sequence(Prod(name='FUNCTION',
                               match=lambda t, v: t == types.FUNCTION and
-                                                 v in (u'rgba(', u'hsla('),
+                                                 v in ('rgba(', 'hsla('),
                               toSeq=lambda t, tokens: (t[0],
                                  normalize(t[1]))
                               ),
@@ -359,7 +359,7 @@ class ColorValue(Value):
                           )
         namedcolor = Prod(name='Named Color',
                      match=lambda t, v: t == 'IDENT' and (
-                                        normalize(v) in self.COLORS.keys()
+                                        normalize(v) in list(self.COLORS.keys())
                                         ),
                      stop=True)
 
@@ -374,9 +374,9 @@ class ColorValue(Value):
         self.wellformed = ok
         if ok:
             t, v = seq[0].type, seq[0].value
-            if u'IDENT' == t:
+            if 'IDENT' == t:
                 rgba = self.COLORS[normalize(v)]
-            if u'HASH' == t:
+            if 'HASH' == t:
                 if len(v) == 4:
                     # HASH #rgb
                     rgba = (int(2*v[1], 16),
@@ -390,24 +390,24 @@ class ColorValue(Value):
                             int(v[5:7], 16),
                             1.0)
 
-            elif u'FUNCTION' == t:
-                functiontype, raw, check = None, [], u''
+            elif 'FUNCTION' == t:
+                functiontype, raw, check = None, [], ''
                 HSL = False
 
                 for item in seq:
                     try:
                         type_ = item.value.type
-                    except AttributeError, e:
+                    except AttributeError as e:
                         # type of function, e.g. rgb(
                         if item.type == 'FUNCTION':
                             functiontype = item.value
-                            HSL = functiontype in (u'hsl(', u'hsla(')
+                            HSL = functiontype in ('hsl(', 'hsla(')
                         continue
 
                     # save components
                     if type_ == Value.NUMBER:
                         raw.append(item.value.value)
-                        check += u'N'
+                        check += 'N'
                     elif type_ == Value.PERCENTAGE:
                         if HSL:
                             # save as percentage fraction
@@ -415,7 +415,7 @@ class ColorValue(Value):
                         else:
                             # save as real value of percentage of 255
                             raw.append(int(255 * item.value.value / 100))
-                        check += u'P'
+                        check += 'P'
 
                 if HSL:
                     # convert to rgb
@@ -439,14 +439,14 @@ class ColorValue(Value):
                     rgba.append(1.0)
 
                 # validate
-                checks = {u'rgb(': ('NNN', 'PPP'),
-                         u'rgba(': ('NNNN', 'PPPN'),
-                         u'hsl(': ('NPP',),
-                         u'hsla(': ('NPPN',)
+                checks = {'rgb(': ('NNN', 'PPP'),
+                         'rgba(': ('NNNN', 'PPPN'),
+                         'hsl(': ('NPP',),
+                         'hsla(': ('NPPN',)
                          }
                 if check not in checks[functiontype]:
-                    self._log.error(u'ColorValue has invalid %s) parameters: '
-                                    u'%s (N=Number, P=Percentage)' %
+                    self._log.error('ColorValue has invalid %s) parameters: '
+                                    '%s (N=Number, P=Percentage)' %
                                     (functiontype, check))
 
             self._colorType = t
@@ -455,34 +455,34 @@ class ColorValue(Value):
 
     cssText = property(lambda self: cssutils.ser.do_css_ColorValue(self),
                        _setCssText,
-                       doc=u"String value of this value.")
+                       doc="String value of this value.")
 
     value = property(lambda self: cssutils.ser.do_css_CSSFunction(self, True),
-                     doc=u'Same as cssText but without comments.')
+                     doc='Same as cssText but without comments.')
 
     type = property(lambda self: Value.COLOR_VALUE,
-                    doc=u"Type is fixed to Value.COLOR_VALUE.")
+                    doc="Type is fixed to Value.COLOR_VALUE.")
 
     def _getName(self):
-        for n, v in self.COLORS.items():
+        for n, v in list(self.COLORS.items()):
             if v == (self.red, self.green, self.blue, self.alpha):
                 return n
 
     colorType = property(lambda self: self._colorType,
-                    doc=u"IDENT (red), HASH (#f00) or FUNCTION (rgb(255, 0, 0).")
+                    doc="IDENT (red), HASH (#f00) or FUNCTION (rgb(255, 0, 0).")
 
     name = property(_getName,
-                    doc=u'Name of the color if known (in ColorValue.COLORS) '
-                        u'else None')
+                    doc='Name of the color if known (in ColorValue.COLORS) '
+                        'else None')
 
     red = property(lambda self: self._red,
-                   doc=u'red part as integer between 0 and 255')
+                   doc='red part as integer between 0 and 255')
     green = property(lambda self: self._green,
-                     doc=u'green part as integer between 0 and 255')
+                     doc='green part as integer between 0 and 255')
     blue = property(lambda self: self._blue,
-                    doc=u'blue part as integer between 0 and 255')
+                    doc='blue part as integer between 0 and 255')
     alpha = property(lambda self: self._alpha,
-                     doc=u'alpha part as float between 0.0 and 1.0')
+                     doc='alpha part as float between 0.0 and 1.0')
 
 class DimensionValue(Value):
     """
@@ -490,12 +490,12 @@ class DimensionValue(Value):
 
     Covers DIMENSION, PERCENTAGE or NUMBER values.
     """
-    __reUnNumDim = re.compile(ur'^([+-]?)(\d*\.\d+|\d+)(.*)$', re.I | re.U | re.X)
+    __reUnNumDim = re.compile(r'^([+-]?)(\d*\.\d+|\d+)(.*)$', re.I | re.U | re.X)
     _dimension = None
     _sign = None
 
     def __str__(self):
-        return u"<cssutils.css.%s object type=%s value=%r dimension=%r cssText=%r at 0x%x>"\
+        return "<cssutils.css.%s object type=%s value=%r dimension=%r cssText=%r at 0x%x>"\
                % (self.__class__.__name__,
                   self.type, self.value, self.dimension, self.cssText,
                   id(self))
@@ -510,7 +510,7 @@ class DimensionValue(Value):
                                 )
                          )
         ok, seq, store, unused = ProdParser().parse(cssText,
-                                                    u'DimensionValue',
+                                                    'DimensionValue',
                                                     prods)
         self.wellformed = ok
         if ok:
@@ -518,7 +518,7 @@ class DimensionValue(Value):
 
             sign, v, d = self.__reUnNumDim.findall(
                                 normalize(item.value))[0]
-            if u'.' in v:
+            if '.' in v:
                 val = float(sign + v)
             else:
                 val = int(sign + v)
@@ -536,11 +536,11 @@ class DimensionValue(Value):
 
     cssText = property(lambda self: cssutils.ser.do_css_Value(self),
                        _setCssText,
-                       doc=u"String value of this value including dimension.")
+                       doc="String value of this value including dimension.")
 
     dimension = property(lambda self: self._dimension, #_setValue,
-                         doc=u"Dimension if a DIMENSION or PERCENTAGE value, "
-                             u"else None")
+                         doc="Dimension if a DIMENSION or PERCENTAGE value, "
+                             "else None")
 class URIValue(Value):
     """
     An URI value like ``url(example.png)``.
@@ -549,7 +549,7 @@ class URIValue(Value):
     _uri = Value._value
 
     def __str__(self):
-        return u"<cssutils.css.%s object type=%s value=%r uri=%r cssText=%r at 0x%x>"\
+        return "<cssutils.css.%s object type=%s value=%r uri=%r cssText=%r at 0x%x>"\
                % (self.__class__.__name__,
                   self.type, self.value, self.uri, self.cssText,
                   id(self))
@@ -559,7 +559,7 @@ class URIValue(Value):
 
         prods = Sequence(PreDef.uri(stop=True))
 
-        ok, seq, store, unused = ProdParser().parse(cssText, u'URIValue', prods)
+        ok, seq, store, unused = ProdParser().parse(cssText, 'URIValue', prods)
         self.wellformed = ok
         if ok:
             # only 1 value only anyway
@@ -570,14 +570,14 @@ class URIValue(Value):
 
     cssText = property(lambda self: cssutils.ser.do_css_Value(self),
                        _setCssText,
-                       doc=u'String value of this value.')
+                       doc='String value of this value.')
 
     def _setUri(self, uri):
         # TODO: check?
         self._value = uri
 
     uri = property(lambda self: self._value, _setUri,
-                         doc=u"Actual URL without delimiters or the empty string")
+                         doc="Actual URL without delimiters or the empty string")
 
     def absoluteUri(self):
         """Actual URL, made absolute if possible, else same as `uri`."""
@@ -586,10 +586,10 @@ class URIValue(Value):
         try:
             # TODO: better way?
             styleSheet = self.parent.parent.parent.parentRule.parentStyleSheet
-        except AttributeError, e:
+        except AttributeError as e:
             return self.uri
         else:
-            return urlparse.urljoin(styleSheet.href, self.uri)
+            return urllib.parse.urljoin(styleSheet.href, self.uri)
 
     absoluteUri = property(absoluteUri, doc=absoluteUri.__doc__)
 
@@ -636,13 +636,13 @@ class CSSFunction(Value):
 
     cssText = property(lambda self: cssutils.ser.do_css_CSSFunction(self),
                        _setCssText,
-                       doc=u"String value of this value.")
+                       doc="String value of this value.")
 
     value = property(lambda self: cssutils.ser.do_css_CSSFunction(self, True),
-                     doc=u'Same as cssText but without comments.')
+                     doc='Same as cssText but without comments.')
 
     type = property(lambda self: Value.FUNCTION,
-                    doc=u"Type is fixed to Value.FUNCTION.")
+                    doc="Type is fixed to Value.FUNCTION.")
 
 class MSValue(CSSFunction):
     """An IE specific Microsoft only function value which is much looser
@@ -678,7 +678,7 @@ class MSValue(CSSFunction):
                                              func,
                                              #_CSSFunctionProd(self),
                                              Prod(name='MSValuePart',
-                                                  match=lambda t, v: v != u')',
+                                                  match=lambda t, v: v != ')',
                                                   toSeq=lambda t, tokens: (t[0], t[1])
                                                   )
                                              ),
@@ -693,7 +693,7 @@ class MSValue(CSSFunction):
 
     cssText = property(lambda self: cssutils.ser.do_css_MSValue(self),
                        _setCssText,
-                       doc=u"String value of this value.")
+                       doc="String value of this value.")
 
 
 class CSSCalc(CSSFunction):
@@ -705,7 +705,7 @@ class CSSCalc(CSSFunction):
     _functionName = 'CSSCalc'
 
     def __str__(self):
-        return u"<cssutils.css.%s object at 0x%x>" % (
+        return "<cssutils.css.%s object at 0x%x>" % (
                 self.__class__.__name__, id(self))
 
     def _setCssText(self, cssText):
@@ -714,7 +714,7 @@ class CSSCalc(CSSFunction):
         types = self._prods # rename!
 
         _operator = Choice(Prod(name='Operator */',
-                                match=lambda t, v: v in u'*/',
+                                match=lambda t, v: v in '*/',
                                 toSeq=lambda t, tokens: (t[0], t[1])
                            ),
                            Sequence(
@@ -722,14 +722,14 @@ class CSSCalc(CSSFunction):
                                Choice(
                                  Sequence(
                                     Prod(name='Operator */',
-                                        match=lambda t, v: v in u'*/',
+                                        match=lambda t, v: v in '*/',
                                         toSeq=lambda t, tokens: (t[0], t[1])
                                     ),
                                     PreDef.S(optional=True)
                                  ),
                                  Sequence(
                                     Prod(name='Operator +-',
-                                        match=lambda t, v: v in u'+-',
+                                        match=lambda t, v: v in '+-',
                                         toSeq=lambda t, tokens: (t[0], t[1])
                                     ),
                                     PreDef.S()
@@ -744,7 +744,7 @@ class CSSCalc(CSSFunction):
 
         prods = Sequence(Prod(name='CALC',
                                   match=lambda t, v: t == types.FUNCTION and
-                                        normalize(v) == u'calc('
+                                        normalize(v) == 'calc('
                          ),
                          PreDef.S(optional=True),
                          _operant(),
@@ -757,7 +757,7 @@ class CSSCalc(CSSFunction):
 
         # store: name of variable
         ok, seq, store, unused = ProdParser().parse(cssText,
-                                                    u'CSSCalc',
+                                                    'CSSCalc',
                                                     prods,
                                                     checkS=True)
         self.wellformed = ok
@@ -766,10 +766,10 @@ class CSSCalc(CSSFunction):
 
 
     cssText = property(lambda self: cssutils.ser.do_css_CSSCalc(self),
-                       _setCssText, doc=u"String representation of calc function.")
+                       _setCssText, doc="String representation of calc function.")
 
     type = property(lambda self: Value.CALC,
-                    doc=u"Type is fixed to Value.CALC.")
+                    doc="Type is fixed to Value.CALC.")
 
 
 
@@ -785,7 +785,7 @@ class CSSVariable(CSSFunction):
     _fallback = None
 
     def __str__(self):
-        return u"<cssutils.css.%s object name=%r value=%r at 0x%x>" % (
+        return "<cssutils.css.%s object name=%r value=%r at 0x%x>" % (
                 self.__class__.__name__, self.name, self.value, id(self))
 
     def _setCssText(self, cssText):
@@ -794,7 +794,7 @@ class CSSVariable(CSSFunction):
         types = self._prods # rename!
         prods = Sequence(Prod(name='var',
                                   match=lambda t, v: t == types.FUNCTION and
-                                        normalize(v) == u'var('
+                                        normalize(v) == 'var('
                              ),
                              PreDef.ident(toStore='ident'),
                              Sequence(PreDef.comma(),
@@ -813,7 +813,7 @@ class CSSVariable(CSSFunction):
         # store: name of variable
         store = {'ident': None, 'fallback': None}
         ok, seq, store, unused = ProdParser().parse(cssText,
-                                                    u'CSSVariable',
+                                                    'CSSVariable',
                                                     prods)
         self.wellformed = ok
 
@@ -827,19 +827,19 @@ class CSSVariable(CSSFunction):
             self._setSeq(seq)
 
     cssText = property(lambda self: cssutils.ser.do_css_CSSVariable(self),
-                       _setCssText, doc=u"String representation of variable.")
+                       _setCssText, doc="String representation of variable.")
 
     # TODO: writable? check if var (value) available?
     name = property(lambda self: self._name,
-                    doc=u"The name identifier of this variable referring to "
-                        u"a value in a "
-                        u":class:`cssutils.css.CSSVariablesDeclaration`.")
+                    doc="The name identifier of this variable referring to "
+                        "a value in a "
+                        ":class:`cssutils.css.CSSVariablesDeclaration`.")
 
     fallback = property(lambda self: self._fallback,
-                doc=u"The fallback Value of this variable")
+                doc="The fallback Value of this variable")
 
     type = property(lambda self: Value.VARIABLE,
-                    doc=u"Type is fixed to Value.VARIABLE.")
+                    doc="Type is fixed to Value.VARIABLE.")
 
     def _getValue(self):
         "Find contained sheet and @variables there"
@@ -861,7 +861,7 @@ class CSSVariable(CSSFunction):
                 return None
 
     value = property(_getValue,
-                     doc=u'The resolved actual value or None.')
+                     doc='The resolved actual value or None.')
 
 
 
@@ -879,12 +879,12 @@ def _ValueProd(parent, nextSor=False, toStore=None):
 
 def _DimensionProd(parent, nextSor=False, toStore=None):
     return Prod(name='Dimension',
-                match=lambda t, v: t in (u'DIMENSION',
-                                         u'NUMBER',
-                                         u'PERCENTAGE'),
+                match=lambda t, v: t in ('DIMENSION',
+                                         'NUMBER',
+                                         'PERCENTAGE'),
                 nextSor = nextSor,
                 toStore=toStore,
-                toSeq=lambda t, tokens: (u'DIMENSION', DimensionValue(
+                toSeq=lambda t, tokens: ('DIMENSION', DimensionValue(
                                             pushtoken(t,
                                                       tokens),
                                             parent=parent)
@@ -912,13 +912,13 @@ def _ColorProd(parent, nextSor=False, toStore=None):
                                     reHexcolor.match(v)
                                     ) or
                                    (t == 'FUNCTION' and
-                                    normalize(v) in (u'rgb(',
-                                                     u'rgba(',
-                                                     u'hsl(',
-                                                     u'hsla(')
+                                    normalize(v) in ('rgb(',
+                                                     'rgba(',
+                                                     'hsl(',
+                                                     'hsla(')
                                     ) or
                                    (t == 'IDENT' and
-                                    normalize(v) in ColorValue.COLORS.keys()
+                                    normalize(v) in list(ColorValue.COLORS.keys())
                                     ),
                 nextSor = nextSor,
                 toStore=toStore,
@@ -942,7 +942,7 @@ def _CSSFunctionProd(parent, nextSor=False, toStore=None):
 def _CalcValueProd(parent, nextSor=False, toStore=None):
     return Prod(name=CSSCalc._functionName,
                     match=lambda t, v: t == PreDef.types.FUNCTION and
-                        normalize(v) == u'calc(',
+                        normalize(v) == 'calc(',
                     toStore=toStore,
                     toSeq=lambda t, tokens: (CSSCalc._functionName,
                                                     CSSCalc(
@@ -964,21 +964,21 @@ def _CSSVariableProd(parent, nextSor=False, toStore=None):
 def _MSValueProd(parent, nextSor=False):
     return Prod(name=MSValue._functionName,
                 match=lambda t, v: (#t == self._prods.FUNCTION and (
-                    normalize(v) in (u'expression(',
-                                                     u'alpha(',
-                                                     u'blur(',
-                                                     u'chroma(',
-                                                     u'dropshadow(',
-                                                     u'fliph(',
-                                                     u'flipv(',
-                                                     u'glow(',
-                                                     u'gray(',
-                                                     u'invert(',
-                                                     u'mask(',
-                                                     u'shadow(',
-                                                     u'wave(',
-                                                     u'xray(') or
-                    v.startswith(u'progid:DXImageTransform.Microsoft.')
+                    normalize(v) in ('expression(',
+                                                     'alpha(',
+                                                     'blur(',
+                                                     'chroma(',
+                                                     'dropshadow(',
+                                                     'fliph(',
+                                                     'flipv(',
+                                                     'glow(',
+                                                     'gray(',
+                                                     'invert(',
+                                                     'mask(',
+                                                     'shadow(',
+                                                     'wave(',
+                                                     'xray(') or
+                    v.startswith('progid:DXImageTransform.Microsoft.')
                     ),
                 nextSor=nextSor,
                 toSeq=lambda t, tokens: (MSValue._functionName,
diff --git a/src/cssutils/cssproductions.py b/src/cssutils/cssproductions.py
index 84ba954..4fa4ed3 100644
--- a/src/cssutils/cssproductions.py
+++ b/src/cssutils/cssproductions.py
@@ -107,19 +107,19 @@ class CSSProductions(object):
     EOF = True
     # removed from productions as they simply are ATKEYWORD until
     # tokenizing
-    CHARSET_SYM = u'CHARSET_SYM'
-    FONT_FACE_SYM = u'FONT_FACE_SYM'
-    MEDIA_SYM = u'MEDIA_SYM'
-    IMPORT_SYM = u'IMPORT_SYM'
-    NAMESPACE_SYM = u'NAMESPACE_SYM'
-    PAGE_SYM = u'PAGE_SYM'
-    VARIABLES_SYM = u'VARIABLES_SYM'
+    CHARSET_SYM = 'CHARSET_SYM'
+    FONT_FACE_SYM = 'FONT_FACE_SYM'
+    MEDIA_SYM = 'MEDIA_SYM'
+    IMPORT_SYM = 'IMPORT_SYM'
+    NAMESPACE_SYM = 'NAMESPACE_SYM'
+    PAGE_SYM = 'PAGE_SYM'
+    VARIABLES_SYM = 'VARIABLES_SYM'
 
 for i, t in enumerate(PRODUCTIONS):
     setattr(CSSProductions, t[0].replace('-', '_'), t[0])
 
 
 # may be enabled by settings.set
-_DXImageTransform = (u'FUNCTION',
-                     ur'progid\:DXImageTransform\.Microsoft\..+\('
+_DXImageTransform = ('FUNCTION',
+                     r'progid\:DXImageTransform\.Microsoft\..+\('
                      )
diff --git a/src/cssutils/errorhandler.py b/src/cssutils/errorhandler.py
index 916adff..dc4b1e3 100644
--- a/src/cssutils/errorhandler.py
+++ b/src/cssutils/errorhandler.py
@@ -19,7 +19,7 @@ __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
 import logging
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 import xml.dom
 
 class _ErrorHandler(object):
@@ -70,7 +70,7 @@ class _ErrorHandler(object):
             raise AttributeError(
                 '(errorhandler) No Attribute %r found' % name)
 
-    def __handle(self, msg=u'', token=None, error=xml.dom.SyntaxErr,
+    def __handle(self, msg='', token=None, error=xml.dom.SyntaxErr,
                  neverraise=False, args=None):
         """
         handles all calls
@@ -86,11 +86,11 @@ class _ErrorHandler(object):
                     value, line, col = token[1], token[2], token[3]
                 else:
                     value, line, col = token.value, token.line, token.col
-                msg = u'%s [%s:%s: %s]' % (
+                msg = '%s [%s:%s: %s]' % (
                     msg, line, col, value)
     
             if error and self.raiseExceptions and not neverraise:
-                if isinstance(error, urllib2.HTTPError) or isinstance(error, urllib2.URLError):
+                if isinstance(error, urllib.error.HTTPError) or isinstance(error, urllib.error.URLError):
                     raise
                 elif issubclass(error, xml.dom.DOMException): 
                     error.line = line
diff --git a/src/cssutils/helper.py b/src/cssutils/helper.py
index 7eeb7a2..320074b 100644
--- a/src/cssutils/helper.py
+++ b/src/cssutils/helper.py
@@ -6,7 +6,7 @@ __version__ = '$Id: errorhandler.py 1234 2008-05-22 20:26:12Z cthedot $'
 import os
 import re
 import sys
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 class Deprecated(object):
     """This is a decorator which can be used to mark functions
@@ -33,7 +33,7 @@ class Deprecated(object):
         return newFunc
 
 # simple escapes, all non unicodes
-_simpleescapes = re.compile(ur'(\\[^0-9a-fA-F])').sub
+_simpleescapes = re.compile(r'(\\[^0-9a-fA-F])').sub
 def normalize(x):
     """
     normalizes x, namely:
@@ -53,7 +53,7 @@ def normalize(x):
 
 def path2url(path):
     """Return file URL of `path`"""
-    return u'file:' + urllib.pathname2url(os.path.abspath(path))
+    return 'file:' + urllib.request.pathname2url(os.path.abspath(path))
 
 def pushtoken(token, tokens):
     """Return new generator starting with token followed by all tokens in
@@ -70,15 +70,15 @@ def string(value):
         ``a \'string`` => ``'a \'string'``
     """
     # \n = 0xa, \r = 0xd, \f = 0xc
-    value = value.replace(u'\n', u'\\a ').replace(
-                          u'\r', u'\\d ').replace(
-                          u'\f', u'\\c ').replace(
-                          u'"', u'\\"')
+    value = value.replace('\n', '\\a ').replace(
+                          '\r', '\\d ').replace(
+                          '\f', '\\c ').replace(
+                          '"', '\\"')
 
-    if value.endswith(u'\\'):
-        value = value[:-1] + u'\\\\'
+    if value.endswith('\\'):
+        value = value[:-1] + '\\\\'
 
-    return u'"%s"' % value
+    return '"%s"' % value
 
 def stringvalue(string):
     """
@@ -87,9 +87,9 @@ def stringvalue(string):
 
         ``'a \'string'`` => ``a 'string``
     """
-    return string.replace(u'\\'+string[0], string[0])[1:-1]
+    return string.replace('\\'+string[0], string[0])[1:-1]
 
-_match_forbidden_in_uri = re.compile(ur'''.*?[\(\)\s\;,'"]''', re.U).match
+_match_forbidden_in_uri = re.compile(r'''.*?[\(\)\s\;,'"]''', re.U).match
 def uri(value):
     """
     Serialize value by adding ``url()`` and with quotes if needed e.g.::
@@ -98,7 +98,7 @@ def uri(value):
     """
     if _match_forbidden_in_uri(value):
         value = string(value)
-    return u'url(%s)' % value
+    return 'url(%s)' % value
 
 def urivalue(uri):
     """
diff --git a/src/cssutils/parse.py b/src/cssutils/parse.py
index 4b25e4e..1483690 100644
--- a/src/cssutils/parse.py
+++ b/src/cssutils/parse.py
@@ -4,13 +4,13 @@ __all__ = ['CSSParser']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from helper import path2url
+from .helper import path2url
 import codecs
 import cssutils
 import os
 import sys
-import tokenize2
-import urllib
+from . import tokenize2
+import urllib.request, urllib.parse, urllib.error
 
 from cssutils import css
 
diff --git a/src/cssutils/prodparser.py b/src/cssutils/prodparser.py
index 140fb81..877ce76 100644
--- a/src/cssutils/prodparser.py
+++ b/src/cssutils/prodparser.py
@@ -18,7 +18,7 @@ __all__ = ['ProdParser', 'Sequence', 'Choice', 'Prod', 'PreDef']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id: parse.py 1418 2008-08-09 19:27:50Z cthedot $'
 
-from helper import pushtoken
+from .helper import pushtoken
 import cssutils
 import itertools
 import re
@@ -62,7 +62,7 @@ class Choice(object):
 
         try:
             self.optional = options['optional']
-        except KeyError, e:
+        except KeyError as e:
             for p in self._prods:
                 if p.optional:
                     self.optional = True
@@ -107,17 +107,17 @@ class Choice(object):
             else:
                 if not optional:
                     # None matched but also None is optional
-                    raise NoMatch(u'No match for %s in %s' % (token, self))
+                    raise NoMatch('No match for %s in %s' % (token, self))
                     #raise ParseError(u'No match in %s for %s' % (self, token))
         elif token:
-            raise Exhausted(u'Extra token')
+            raise Exhausted('Extra token')
 
     def __repr__(self):
         return "<cssutils.prodsparser.%s object sequence=%r optional=%r at 0x%x>" % (
                 self.__class__.__name__, self.__str__(), self.optional, id(self))
 
     def __str__(self):
-        return u'Choice(%s)' % u', '.join([str(x) for x in self._prods])
+        return 'Choice(%s)' % ', '.join([str(x) for x in self._prods])
 
 
 class Sequence(object):
@@ -144,7 +144,7 @@ class Sequence(object):
                 self._max = sys.maxsize
             except AttributeError:
                 # py<2.6
-                self._max = sys.maxint
+                self._max = sys.maxsize
 
         self._prodcount = len(self._prods)
         self.reset()
@@ -212,26 +212,26 @@ class Sequence(object):
                 continue
 
             elif round < self._min or self._roundstarted: #or (round == 0 and self._min == 0):
-                raise Missing(u'Missing token for production %s' % p)
+                raise Missing('Missing token for production %s' % p)
 
             elif not token:
                 if self._roundstarted:
-                    raise Missing(u'Missing token for production %s' % p)
+                    raise Missing('Missing token for production %s' % p)
                 else:
                     raise Done()
 
             else:
-                raise NoMatch(u'No match for %s in %s' % (token, self))
+                raise NoMatch('No match for %s in %s' % (token, self))
 
         if token:
-            raise Exhausted(u'Extra token')
+            raise Exhausted('Extra token')
 
     def __repr__(self):
         return "<cssutils.prodsparser.%s object sequence=%r optional=%r at 0x%x>" % (
                 self.__class__.__name__, self.__str__(), self.optional, id(self))
 
     def __str__(self):
-        return u'Sequence(%s)' % u', '.join([str(x) for x in self._prods])
+        return 'Sequence(%s)' % ', '.join([str(x) for x in self._prods])
 
 
 
@@ -356,7 +356,7 @@ class ProdParser(object):
         """Build a generator which is the only thing that is parsed!
         old classes may use lists etc
         """
-        if isinstance(text, basestring):
+        if isinstance(text, str):
             # DEFAULT, to tokenize strip space
             return tokenizer.tokenize(text.strip())
 
@@ -387,7 +387,7 @@ class ProdParser(object):
         for token in tokens:
             if token[0] == self.types.S:
                 try:
-                    next_ = tokens.next()
+                    next_ = next(tokens)
                 except StopIteration:
                     yield token
                 else:
@@ -450,7 +450,7 @@ class ProdParser(object):
         tokens = self._texttotokens(text)
 
         if not tokens:
-            self._log.error(u'No content to parse.')
+            self._log.error('No content to parse.')
             return False, [], None, None
 
         seq = cssutils.util.Seq(readonly=False)
@@ -473,9 +473,9 @@ class ProdParser(object):
             try:
                 #print debug, "SAVED", savedTokens
                 token = savedTokens.pop()
-            except IndexError, e:
+            except IndexError as e:
                 try:
-                    token = tokens.next()
+                    token = next(tokens)
                 except StopIteration:
                     break
 
@@ -503,7 +503,7 @@ class ProdParser(object):
             elif type_ == self.types.INVALID:
                 # invalidate parse
                 wellformed = False
-                self._log.error(u'Invalid token: %r' % (token,))
+                self._log.error('Invalid token: %r' % (token,))
                 break
 
             elif type_ == 'EOF':
@@ -519,7 +519,7 @@ class ProdParser(object):
                         # find next matching production
                         try:
                             prod = prods[-1].nextProd(token)
-                        except (Exhausted, NoMatch), e:
+                        except (Exhausted, NoMatch) as e:
                             # try next
                             prod = None
 
@@ -536,7 +536,7 @@ class ProdParser(object):
                             else:
                                 raise NoMatch('No match')
 
-                except NoMatch, e:
+                except NoMatch as e:
                     if stopIfNoMoreMatch: # and token:
                         #print "\t1stopIfNoMoreMatch", e, token, prod, 'PUSHING'
                         #tokenizer.push(token)
@@ -546,10 +546,10 @@ class ProdParser(object):
 
                     else:
                         wellformed = False
-                        self._log.error(u'%s: %s: %r' % (name, e, token))
+                        self._log.error('%s: %s: %r' % (name, e, token))
                     break
 
-                except ParseError, e:
+                except ParseError as e:
                     # needed???
                     if stopIfNoMoreMatch: # and token:
                         #print "\t2stopIfNoMoreMatch", e, token, prod
@@ -559,7 +559,7 @@ class ProdParser(object):
 
                     else:
                         wellformed = False
-                        self._log.error(u'%s: %s: %r' % (name, e, token))
+                        self._log.error('%s: %s: %r' % (name, e, token))
                     break
 
                 else:
@@ -615,21 +615,21 @@ class ProdParser(object):
                 # all productions exhausted?
                 try:
                     prod = prods[-1].nextProd(token=None)
-                except Done, e:
+                except Done as e:
                     # ok
                     prod = None
 
-                except Missing, e:
+                except Missing as e:
                     prod = None
                     # last was a S operator which may End a Sequence, then ok
                     if hasattr(lastprod, 'mayEnd') and not lastprod.mayEnd:
                         wellformed = False
-                        self._log.error(u'%s: %s' % (name, e))
+                        self._log.error('%s: %s' % (name, e))
 
-                except ParseError, e:
+                except ParseError as e:
                     prod = None
                     wellformed = False
-                    self._log.error(u'%s: %s' % (name, e))
+                    self._log.error('%s: %s' % (name, e))
 
                 else:
                     if prods[-1].optional:
@@ -640,7 +640,7 @@ class ProdParser(object):
 
                 if prod and not prod.optional:
                     wellformed = False
-                    self._log.error(u'%s: Missing token for production %r'
+                    self._log.error('%s: Missing token for production %r'
                                     % (name, str(prod)))
                     break
                 elif len(prods) > 1:
@@ -650,7 +650,7 @@ class ProdParser(object):
                     break
 
             if not emptyOk and not len(seq):
-                self._log.error(u'No content to parse.')
+                self._log.error('No content to parse.')
                 return False, [], None, None
 
         # trim S from end
@@ -667,13 +667,13 @@ class PreDef(object):
 
     @staticmethod
     def calc(toSeq=None, nextSor=False):
-        return Prod(name=u'calcfunction',
-                    match=lambda t, v: u'calc(' == cssutils.helper.normalize(v),
+        return Prod(name='calcfunction',
+                    match=lambda t, v: 'calc(' == cssutils.helper.normalize(v),
                     toSeq=toSeq,
                     nextSor=nextSor)
 
     @staticmethod
-    def char(name='char', char=u',', toSeq=None,
+    def char(name='char', char=',', toSeq=None,
              stop=False, stopAndKeep=False, mayEnd=False, 
              stopIfNoMoreMatch=False,
              optional=False, # WAS: optional=True, 
@@ -687,11 +687,11 @@ class PreDef(object):
 
     @staticmethod
     def comma(optional=False, toSeq=None):
-        return PreDef.char(u'comma', u',', optional=optional, toSeq=toSeq)
+        return PreDef.char('comma', ',', optional=optional, toSeq=toSeq)
 
     @staticmethod
     def comment(parent=None):
-        return Prod(name=u'comment',
+        return Prod(name='comment',
                     match=lambda t, v: t == 'COMMENT',
                     toSeq=lambda t, tokens: (t[0], cssutils.css.CSSComment([1], 
                                                                            parentRule=parent)),
@@ -701,7 +701,7 @@ class PreDef(object):
 
     @staticmethod
     def dimension(nextSor=False, stop=False):
-        return Prod(name=u'dimension',
+        return Prod(name='dimension',
                     match=lambda t, v: t == PreDef.types.DIMENSION,
                     toSeq=lambda t, tokens: (t[0], cssutils.helper.normalize(t[1])),
                     stop=stop,
@@ -709,7 +709,7 @@ class PreDef(object):
 
     @staticmethod
     def function(toSeq=None, nextSor=False, toStore=None):
-        return Prod(name=u'function',
+        return Prod(name='function',
                     match=lambda t, v: t == PreDef.types.FUNCTION,
                     toStore=toStore,
                     toSeq=toSeq,
@@ -718,7 +718,7 @@ class PreDef(object):
     @staticmethod
     def funcEnd(stop=False, mayEnd=False):
         ")"
-        return PreDef.char(u'end FUNC ")"', u')', stop=stop, mayEnd=mayEnd)
+        return PreDef.char('end FUNC ")"', ')', stop=stop, mayEnd=mayEnd)
 
     @staticmethod
     def hexcolor(stop=False, nextSor=False):
@@ -733,7 +733,7 @@ class PreDef(object):
 
     @staticmethod
     def ident(stop=False, toStore=None, nextSor=False):
-        return Prod(name=u'ident',
+        return Prod(name='ident',
                     match=lambda t, v: t == PreDef.types.IDENT,
                     stop=stop,
                     toStore=toStore,
@@ -741,7 +741,7 @@ class PreDef(object):
 
     @staticmethod
     def number(stop=False, toSeq=None, nextSor=False):
-        return Prod(name=u'number',
+        return Prod(name='number',
                     match=lambda t, v: t == PreDef.types.NUMBER,
                     stop=stop,
                     toSeq=toSeq,
@@ -749,7 +749,7 @@ class PreDef(object):
 
     @staticmethod
     def percentage(stop=False, toSeq=None, nextSor=False):
-        return Prod(name=u'percentage',
+        return Prod(name='percentage',
                     match=lambda t, v: t == PreDef.types.PERCENTAGE,
                     stop=stop,
                     toSeq=toSeq,
@@ -758,14 +758,14 @@ class PreDef(object):
     @staticmethod
     def string(stop=False, nextSor=False):
         "string delimiters are removed by default"
-        return Prod(name=u'string',
+        return Prod(name='string',
                     match=lambda t, v: t == PreDef.types.STRING,
                     toSeq=lambda t, tokens: (t[0], cssutils.helper.stringvalue(t[1])),
                     stop=stop,
                     nextSor=nextSor)
 
     @staticmethod
-    def S(name=u'whitespace', toSeq=None, optional=False):
+    def S(name='whitespace', toSeq=None, optional=False):
         return Prod(name=name,
                     match=lambda t, v: t == PreDef.types.S,
                     toSeq=toSeq,
@@ -775,7 +775,7 @@ class PreDef(object):
     @staticmethod
     def unary(stop=False, toSeq=None, nextSor=False):
         "+ or -"
-        return Prod(name=u'unary +-', match=lambda t, v: v in (u'+', u'-'),
+        return Prod(name='unary +-', match=lambda t, v: v in ('+', '-'),
                     optional=True,
                     stop=stop,
                     toSeq=toSeq,
@@ -784,7 +784,7 @@ class PreDef(object):
     @staticmethod
     def uri(stop=False, nextSor=False):
         "'url(' and ')' are removed and URI is stripped"
-        return Prod(name=u'URI',
+        return Prod(name='URI',
                     match=lambda t, v: t == PreDef.types.URI,
                     toSeq=lambda t, tokens: (t[0], cssutils.helper.urivalue(t[1])),
                     stop=stop,
@@ -802,8 +802,8 @@ class PreDef(object):
 
     @staticmethod
     def variable(toSeq=None, stop=False, nextSor=False, toStore=None):
-        return Prod(name=u'variable',
-                    match=lambda t, v: u'var(' == cssutils.helper.normalize(v),
+        return Prod(name='variable',
+                    match=lambda t, v: 'var(' == cssutils.helper.normalize(v),
                     toSeq=toSeq,
                     toStore=toStore,
                     stop=stop,
@@ -811,7 +811,7 @@ class PreDef(object):
 
     # used for MarginRule for now:
     @staticmethod
-    def unknownrule(name=u'@', toStore=None):
+    def unknownrule(name='@', toStore=None):
         """@rule dummy (matches ATKEYWORD to remove unknown rule tokens from
         stream::
 
@@ -824,12 +824,12 @@ class PreDef(object):
             saved = []
             for t in tokens:
                 saved.append(t)
-                if (t[1] == u'}' or t[1] == u';'):
+                if (t[1] == '}' or t[1] == ';'):
                     return cssutils.css.CSSUnknownRule(saved)
 
         return Prod(name=name,
-                    match=lambda t, v: t == u'ATKEYWORD',
-                    toSeq=lambda t, tokens: (u'CSSUnknownRule',
+                    match=lambda t, v: t == 'ATKEYWORD',
+                    toSeq=lambda t, tokens: ('CSSUnknownRule',
                                              rule(pushtoken(t, tokens))
                                              ),
                     toStore=toStore
diff --git a/src/cssutils/profiles.py b/src/cssutils/profiles.py
index 71a9a30..873bf87 100644
--- a/src/cssutils/profiles.py
+++ b/src/cssutils/profiles.py
@@ -45,15 +45,15 @@ class Profiles(object):
     If you want to redefine any of these macros do this in your custom
     macros.
     """
-    CSS_LEVEL_2 = u'CSS Level 2.1'
-    CSS3_BACKGROUNDS_AND_BORDERS = u'CSS Backgrounds and Borders Module Level 3'
-    CSS3_BASIC_USER_INTERFACE = u'CSS3 Basic User Interface Module'
-    CSS3_BOX = CSS_BOX_LEVEL_3 = u'CSS Box Module Level 3'
-    CSS3_COLOR = CSS_COLOR_LEVEL_3 = u'CSS Color Module Level 3'
-    CSS3_FONTS = u'CSS Fonts Module Level 3'
-    CSS3_FONT_FACE = u'CSS Fonts Module Level 3 @font-face properties'
-    CSS3_PAGED_MEDIA = u'CSS3 Paged Media Module'
-    CSS3_TEXT = u'CSS Text Level 3'
+    CSS_LEVEL_2 = 'CSS Level 2.1'
+    CSS3_BACKGROUNDS_AND_BORDERS = 'CSS Backgrounds and Borders Module Level 3'
+    CSS3_BASIC_USER_INTERFACE = 'CSS3 Basic User Interface Module'
+    CSS3_BOX = CSS_BOX_LEVEL_3 = 'CSS Box Module Level 3'
+    CSS3_COLOR = CSS_COLOR_LEVEL_3 = 'CSS Color Module Level 3'
+    CSS3_FONTS = 'CSS Fonts Module Level 3'
+    CSS3_FONT_FACE = 'CSS Fonts Module Level 3 @font-face properties'
+    CSS3_PAGED_MEDIA = 'CSS3 Paged Media Module'
+    CSS3_TEXT = 'CSS Text Level 3'
 
     _TOKEN_MACROS = {
         'ident': r'[-]?{nmstart}{nmchar}*',
@@ -155,7 +155,7 @@ class Profiles(object):
         def macro_value(m):
             return '(?:%s)' % macros[m.groupdict()['macro']]
 
-        for key, value in dictionary.items():
+        for key, value in list(dictionary.items()):
             if not hasattr(value, '__call__'):
                 while re.search(r'{[a-z][a-z0-9-]*}', value):
                     value = re.sub(r'{(?P<macro>[a-z][a-z0-9-]*)}',
@@ -166,7 +166,7 @@ class Profiles(object):
 
     def _compile_regexes(self, dictionary):
         """Compile all regular expressions into callable objects"""
-        for key, value in dictionary.items():
+        for key, value in list(dictionary.items()):
             if not hasattr(value, '__call__'):
                 # Compiling them now will slow down the cssutils import time,
                 # even if cssutils is not needed. We lazily compile them the
@@ -179,8 +179,8 @@ class Profiles(object):
 
     def __update_knownNames(self):
         self._knownNames = []
-        for properties in self._profilesProperties.values():
-            self._knownNames.extend(properties.keys())
+        for properties in list(self._profilesProperties.values()):
+            self._knownNames.extend(list(properties.keys()))
 
     def _getDefaultProfiles(self):
         "If not explicitly set same as Profiles.profiles but in reverse order."
@@ -191,20 +191,20 @@ class Profiles(object):
 
     def _setDefaultProfiles(self, profiles):
         "profiles may be a single or a list of profile names"
-        if isinstance(profiles, basestring):
+        if isinstance(profiles, str):
             self._defaultProfiles = (profiles,)
         else:
             self._defaultProfiles = profiles
 
     defaultProfiles = property(_getDefaultProfiles,
                                _setDefaultProfiles,
-                               doc=u"Names of profiles to use for validation."
-                                   u"To use e.g. the CSS2 profile set "
-                                   u"``cssutils.profile.defaultProfiles = "
-                                   u"cssutils.profile.CSS_LEVEL_2``")
+                               doc="Names of profiles to use for validation."
+                                   "To use e.g. the CSS2 profile set "
+                                   "``cssutils.profile.defaultProfiles = "
+                                   "cssutils.profile.CSS_LEVEL_2``")
 
     profiles = property(lambda self: self._profileNames,
-                        doc=u'Names of all profiles in order as defined.')
+                        doc='Names of all profiles in order as defined.')
 
     knownNames = property(lambda self: self._knownNames,
                                doc="All known property names of all profiles.")
@@ -278,7 +278,7 @@ class Profiles(object):
         """
         if macros:
             # check if known macros would change and if yes reset properties
-            if len(set(macros.keys()).intersection(self._usedMacros.keys())):
+            if len(set(macros.keys()).intersection(list(self._usedMacros.keys()))):
                 self._resetProperties(newMacros=macros)
 
             else:
@@ -289,7 +289,7 @@ class Profiles(object):
             # might have been set by addProfiles before
             try:
                 macros = self._rawProfiles[profile]['macros']
-            except KeyError, e:
+            except KeyError as e:
                 macros = {}
 
         # save name and raw props/macros if macros change to completely reset
@@ -333,7 +333,7 @@ class Profiles(object):
                 del self._rawProfiles[profile]
                 del self._profileNames[self._profileNames.index(profile)]
             except KeyError:
-                raise NoSuchProfileException(u'No profile %r.' % profile)
+                raise NoSuchProfileException('No profile %r.' % profile)
 
             else:
                 if reset:
@@ -351,13 +351,13 @@ class Profiles(object):
         """
         if not profiles:
             profiles = self.profiles
-        elif isinstance(profiles, basestring):
+        elif isinstance(profiles, str):
             profiles = (profiles, )
         try:
             for profile in sorted(profiles):
                 for name in sorted(self._profilesProperties[profile].keys()):
                     yield name
-        except KeyError, e:
+        except KeyError as e:
             raise NoSuchProfileException(e)
 
     def validate(self, name, value):
@@ -377,7 +377,7 @@ class Profiles(object):
                 try:
                     # custom validation errors are caught
                     r = bool(self._profilesProperties[profile][name](value))
-                except Exception, e:
+                except Exception as e:
                     # TODO: more specific exception?
                     # Validate should not be fatal though!
                     self._log.error(e, error=Exception)
@@ -414,7 +414,7 @@ class Profiles(object):
         else:
             if not profiles:
                 profiles = self.defaultProfiles
-            elif isinstance(profiles, basestring):
+            elif isinstance(profiles, str):
                 profiles = (profiles, )
             for profilename in reversed(profiles):
                 # check given profiles
@@ -423,7 +423,7 @@ class Profiles(object):
                     try:
                         if validate(value):
                             return True, True, [profilename]
-                    except Exception, e:
+                    except Exception as e:
                         self._log.error(e, error=Exception)
 
             for profilename in (p for p in self._profileNames
@@ -434,13 +434,13 @@ class Profiles(object):
                     try:
                         if validate(value):
                             return True, False, [profilename]
-                    except Exception, e:
+                    except Exception as e:
                         self._log.error(e, error=Exception)
 
             names = []
-            for profilename, properties in self._profilesProperties.items():
+            for profilename, properties in list(self._profilesProperties.items()):
                 # return profile to which name belongs
-                if name in properties.keys():
+                if name in list(properties.keys()):
                     names.append(profilename)
             names.sort()
             return False, False, names
diff --git a/src/cssutils/sac.py b/src/cssutils/sac.py
index 4e4fe09..9880d73 100644
--- a/src/cssutils/sac.py
+++ b/src/cssutils/sac.py
@@ -4,12 +4,12 @@ __all__ = ['CSSParser']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id: parse.py 1754 2009-05-30 14:50:13Z cthedot $'
 
-import helper
+from . import helper
 import codecs
-import errorhandler
+from . import errorhandler
 import os
-import tokenize2
-import urllib
+from . import tokenize2
+import urllib.request, urllib.parse, urllib.error
 import sys
  
     
@@ -115,12 +115,12 @@ class EchoHandler(DocumentHandler):
         super(EchoHandler, self).__init__()
         self._out = []
         
-    out = property(lambda self: u''.join(self._out))
+    out = property(lambda self: ''.join(self._out))
 
     def startDocument(self, encoding):
         super(EchoHandler, self).startDocument(encoding)
-        if u'utf-8' != encoding:
-            self._out.append(u'@charset "%s";\n' % encoding)
+        if 'utf-8' != encoding:
+            self._out.append('@charset "%s";\n' % encoding)
     
 #    def comment(self, text, line=None, col=None):
 #        self._out.append(u'/*%s*/' % text)
@@ -129,30 +129,30 @@ class EchoHandler(DocumentHandler):
         "Receive notification of a import statement in the style sheet."
         # defaultNamespaceURI???
         super(EchoHandler, self).importStyle(uri, media, name, line, col)
-        self._out.append(u'@import %s%s%s;\n' % (helper.string(uri),
-                                               u'%s ' % media if media else u'',
-                                               u'%s ' % name if name else u'')
+        self._out.append('@import %s%s%s;\n' % (helper.string(uri),
+                                               '%s ' % media if media else '',
+                                               '%s ' % name if name else '')
         )
         
         
     def namespaceDeclaration(self, prefix, uri, line=None, col=None):
         super(EchoHandler, self).namespaceDeclaration(prefix, uri, line, col)
-        self._out.append(u'@namespace %s%s;\n' % (u'%s ' % prefix if prefix else u'', 
+        self._out.append('@namespace %s%s;\n' % ('%s ' % prefix if prefix else '',
                                                 helper.string(uri)))
 
     def startSelector(self, selectors=None, line=None, col=None):
         super(EchoHandler, self).startSelector(selectors, line, col)
         if selectors:
-            self._out.append(u', '.join(selectors))
-        self._out.append(u' {\n')
+            self._out.append(', '.join(selectors))
+        self._out.append(' {\n')
 
     def endSelector(self, selectors=None, line=None, col=None):
-        self._out.append(u'    }')
+        self._out.append('    }')
         
     def property(self, name, value, important=False, line=None, col=None):
         super(EchoHandler, self).property(name, value,  line, col)
-        self._out.append(u'    %s: %s%s;\n' % (name, value, 
-                                        u' !important' if important else u''))
+        self._out.append('    %s: %s%s;\n' % (name, value,
+                                        ' !important' if important else ''))
   
 
 class Parser(object):
@@ -219,24 +219,24 @@ class Parser(object):
                 return False
                         
         # START PARSING
-        t = tokens.next()
+        t = next(tokens)
         type_, val, line, col = t
         
         encoding = 'utf-8'                
         if 'CHARSET_SYM' == type_:
             # @charset "encoding";
             # S
-            encodingtoken = tokens.next()
-            semicolontoken = tokens.next()
+            encodingtoken = next(tokens)
+            semicolontoken = next(tokens)
             if 'STRING' == type_:
                 encoding = helper.stringvalue(val)
             # ;
             if 'STRING' == encodingtoken[0] and semicolontoken:
                 encoding = helper.stringvalue(encodingtoken[1])    
             else:
-                self._errorHandler.fatal(u'Invalid @charset')
+                self._errorHandler.fatal('Invalid @charset')
                 
-            t = tokens.next()
+            t = next(tokens)
             type_, val, line, col = t
             
         self._handler.startDocument(encoding)
@@ -253,44 +253,44 @@ class Parser(object):
                     while True:
                         # read till end ; 
                         # TODO: or {}
-                        t = tokens.next()
+                        t = next(tokens)
                         type_, val, line, col = t
                         atRule.append(val) 
-                        if u';' == val and not braces:
+                        if ';' == val and not braces:
                             break
-                        elif u'{' == val:
+                        elif '{' == val:
                             braces += 1
-                        elif u'}' == val:
+                        elif '}' == val:
                             braces -= 1
                             if braces == 0:
                                 break
                             
-                    self._handler.ignorableAtRule(u''.join(atRule), *start)
+                    self._handler.ignorableAtRule(''.join(atRule), *start)
 
                 elif 'IMPORT_SYM' == type_:
                     # import URI or STRING media? name?
                     uri, media, name = None, None, None
                     while True:
-                        t = tokens.next()
+                        t = next(tokens)
                         type_, val, line, col = t
                         if 'STRING' == type_:
                             uri = helper.stringvalue(val)
                         elif 'URI' == type_:
                             uri = helper.urivalue(val)
-                        elif u';' == val:
+                        elif ';' == val:
                             break
                     
                     if uri:    
                         self._handler.importStyle(uri, media, name)
                     else:
-                        self._errorHandler.error(u'Invalid @import'
-                                                 u' declaration at %r' 
+                        self._errorHandler.error('Invalid @import'
+                                                 ' declaration at %r'
                                                  % (start,))
                         
                 elif 'NAMESPACE_SYM' == type_:
                     prefix, uri = None, None
                     while True:
-                        t = tokens.next()
+                        t = next(tokens)
                         type_, val, line, col = t
                         if 'IDENT' == type_:
                             prefix = val
@@ -298,13 +298,13 @@ class Parser(object):
                             uri = helper.stringvalue(val)
                         elif 'URI' == type_:
                             uri = helper.urivalue(val)
-                        elif u';' == val:
+                        elif ';' == val:
                             break
                     if uri:
                         self._handler.namespaceDeclaration(prefix, uri, *start)
                     else:
-                        self._errorHandler.error(u'Invalid @namespace'
-                                                 u' declaration at %r' 
+                        self._errorHandler.error('Invalid @namespace'
+                                                 ' declaration at %r'
                                                  % (start,))
     
                 else:
@@ -314,20 +314,20 @@ class Parser(object):
                     while True:
                         # selectors[, selector]* {
                         if 'S' == type_:
-                            selector.append(u' ')
+                            selector.append(' ')
                         elif simple(t):
                             pass
-                        elif u',' == val:
-                            selectors.append(u''.join(selector).strip())
+                        elif ',' == val:
+                            selectors.append(''.join(selector).strip())
                             selector = []
-                        elif u'{' == val:
-                            selectors.append(u''.join(selector).strip())
+                        elif '{' == val:
+                            selectors.append(''.join(selector).strip())
                             self._handler.startSelector(selectors, *start)
                             break
                         else:
                             selector.append(val)
                             
-                        t = tokens.next()
+                        t = next(tokens)
                         type_, val, line, col = t
                                             
                     end = None
@@ -337,7 +337,7 @@ class Parser(object):
                         
                         while True:
                             # name:
-                            t = tokens.next()
+                            t = next(tokens)
                             type_, val, line, col = t
                             if 'S' == type_:
                                 pass
@@ -348,15 +348,15 @@ class Parser(object):
                                     self._errorHandler.error('more than one property name', t)
                                 else:
                                     name = val
-                            elif u':' == val:
+                            elif ':' == val:
                                 if not name:
                                     self._errorHandler.error('no property name', t)
                                 break
-                            elif u';' == val:
+                            elif ';' == val:
                                 self._errorHandler.error('premature end of property', t)
                                 end = val
                                 break
-                            elif u'}' == val:
+                            elif '}' == val:
                                 if name:
                                     self._errorHandler.error('premature end of property', t)
                                 end = val
@@ -364,16 +364,16 @@ class Parser(object):
                             else:
                                 self._errorHandler.error('unexpected property name token %r' % val, t)
 
-                        while not u';' == end and not u'}' == end:
+                        while not ';' == end and not '}' == end:
                             # value !;}
-                            t = tokens.next()
+                            t = next(tokens)
                             type_, val, line, col = t
                             
                             if 'S' == type_:
-                                value.append(u' ')
+                                value.append(' ')
                             elif simple(t):
                                 pass
-                            elif u'!' == val or u';' == val or u'}' == val:
+                            elif '!' == val or ';' == val or '}' == val:
                                 value = ''.join(value).strip()
                                 if not value:
                                     self._errorHandler.error('premature end of property (no value)', t)
@@ -382,16 +382,16 @@ class Parser(object):
                             else:
                                 value.append(val)
 
-                        while u'!' == end:
+                        while '!' == end:
                             # !important
-                            t = tokens.next()
+                            t = next(tokens)
                             type_, val, line, col = t
                             
                             if simple(t):
                                 pass
-                            elif u'IDENT' == type_ and not important:
+                            elif 'IDENT' == type_ and not important:
                                 important = True
-                            elif u';' == val or u'}' == val:
+                            elif ';' == val or '}' == val:
                                 end = val
                                 break
                             else:
@@ -400,7 +400,7 @@ class Parser(object):
                         if name and value:
                             self._handler.property(name, value, important)
                             
-                        if u'}' == end:
+                        if '}' == end:
                             self._handler.endSelector(selectors, line=line, col=col)
                             break
                         else:
@@ -410,7 +410,7 @@ class Parser(object):
                     else:
                         self._handler.endSelector(selectors, line=line, col=col)
 
-                t = tokens.next()
+                t = next(tokens)
                 type_, val, line, col = t
 
             except StopIteration:
@@ -425,4 +425,3 @@ class Parser(object):
     def setErrorHandler(self, handler):
         "TODO"
         self._errorHandler = handler
-        
\ No newline at end of file
diff --git a/src/cssutils/script.py b/src/cssutils/script.py
index 31fcae0..d1af89f 100644
--- a/src/cssutils/script.py
+++ b/src/cssutils/script.py
@@ -4,15 +4,15 @@ __all__ = ['CSSCapture', 'csscombine']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id: parse.py 1323 2008-07-06 18:13:57Z cthedot $'
 
-import HTMLParser
+import html.parser
 import codecs
 import cssutils
 import errno
 import logging
 import os
 import sys
-import urllib2
-import urlparse
+import urllib.request, urllib.error, urllib.parse
+import urllib.parse
 
 try:
     import cssutils.encutils as encutils
@@ -26,31 +26,31 @@ except ImportError:
 LINK = 0 # <link rel="stylesheet" type="text/css" href="..." [@title="..." @media="..."]/>
 STYLE = 1 # <style type="text/css" [@title="..."]>...</style>
 
-class CSSCaptureHTMLParser(HTMLParser.HTMLParser):
+class CSSCaptureHTMLParser(html.parser.HTMLParser):
     """CSSCapture helper: Parse given data for link and style elements"""
-    curtag = u''
+    curtag = ''
     sheets = [] # (type, [atts, cssText])
 
     def _loweratts(self, atts):
         return dict([(a.lower(), v.lower()) for a, v in atts])
 
     def handle_starttag(self, tag, atts):
-        if tag == u'link':
+        if tag == 'link':
             atts = self._loweratts(atts)
-            if u'text/css' == atts.get(u'type', u''):
+            if 'text/css' == atts.get('type', ''):
                 self.sheets.append((LINK, atts))
-        elif tag == u'style':
+        elif tag == 'style':
             # also get content of style
             atts = self._loweratts(atts)
-            if u'text/css' == atts.get(u'type', u''):
-                self.sheets.append((STYLE, [atts, u'']))
+            if 'text/css' == atts.get('type', ''):
+                self.sheets.append((STYLE, [atts, '']))
                 self.curtag = tag
         else:
             # close as only intersting <style> cannot contain any elements
-            self.curtag = u''
+            self.curtag = ''
 
     def handle_data(self, data):
-        if self.curtag == u'style':
+        if self.curtag == 'style':
             self.sheets[-1][1][1] = data # replace cssText
 
     def handle_comment(self, data):
@@ -59,7 +59,7 @@ class CSSCaptureHTMLParser(HTMLParser.HTMLParser):
 
     def handle_endtag(self, tag):
         # close as style cannot contain any elements
-        self.curtag = u''
+        self.curtag = ''
 
 
 class CSSCapture(object):
@@ -94,7 +94,7 @@ class CSSCapture(object):
             hdlr.setFormatter(formatter)
             self._log.addHandler(hdlr)
             self._log.setLevel(defaultloglevel)
-            self._log.debug(u'Using default log')
+            self._log.debug('Using default log')
 
         self._htmlparser = CSSCaptureHTMLParser()
         self._cssparser = cssutils.CSSParser(log = self._log)
@@ -105,16 +105,16 @@ class CSSCapture(object):
         Return (url, rawcontent)
             url might have been changed by server due to redirects etc
         """
-        self._log.debug(u'    CSSCapture._doRequest\n        * URL: %s' % url)
+        self._log.debug('    CSSCapture._doRequest\n        * URL: %s' % url)
 
-        req = urllib2.Request(url)
+        req = urllib.request.Request(url)
         if self._ua:
             req.add_header('User-agent', self._ua)
             self._log.info('        * Using User-Agent: %s', self._ua)
 
         try:
-            res = urllib2.urlopen(req)
-        except urllib2.HTTPError, e:
+            res = urllib.request.urlopen(req)
+        except urllib.error.HTTPError as e:
             self._log.critical('    %s\n%s %s\n%s' % (
                 e.geturl(), e.code, e.msg, e.headers))
             return None, None
@@ -129,7 +129,7 @@ class CSSCapture(object):
     def _createStyleSheet(self, href=None,
                           media=None,
                           parentStyleSheet=None,
-                          title=u'',
+                          title='',
                           cssText=None,
                           encoding=None):
         """
@@ -149,7 +149,7 @@ class CSSCapture(object):
             return None
 
         else:
-            self._log.info(u'    %s\n' % sheet)
+            self._log.info('    %s\n' % sheet)
             self._nonparsed[sheet] = cssText
             return sheet
 
@@ -170,25 +170,25 @@ class CSSCapture(object):
             sheet = None
 
             if LINK == typ:
-                self._log.info(u'+ PROCESSING <link> %r' % data)
+                self._log.info('+ PROCESSING <link> %r' % data)
 
                 atts = data
-                href = urlparse.urljoin(docurl, atts.get(u'href', None))
+                href = urllib.parse.urljoin(docurl, atts.get('href', None))
                 sheet = self._createStyleSheet(href=href,
-                                               media=atts.get(u'media', None),
-                                               title=atts.get(u'title', None))
+                                               media=atts.get('media', None),
+                                               title=atts.get('title', None))
             elif STYLE == typ:
-                self._log.info(u'+ PROCESSING <style> %r' % data)
+                self._log.info('+ PROCESSING <style> %r' % data)
 
                 atts, cssText = data
                 sheet = self._createStyleSheet(cssText=cssText,
                                                href = docurl,
-                                               media=atts.get(u'media', None),
-                                               title=atts.get(u'title', None),
+                                               media=atts.get('media', None),
+                                               title=atts.get('title', None),
                                                encoding=self.docencoding)
                 if sheet:
                     sheet._href = None # inline have no href!
-                print sheet.cssText
+                print(sheet.cssText)
 
             if sheet:
                 self.stylesheetlist.append(sheet)
@@ -204,12 +204,12 @@ class CSSCapture(object):
 
         for rule in parentStyleSheet.cssRules:
             if rule.type == rule.IMPORT_RULE:
-                self._log.info(u'+ PROCESSING @import:')
-                self._log.debug(u'    IN: %s\n' % parentStyleSheet.href)
+                self._log.info('+ PROCESSING @import:')
+                self._log.debug('    IN: %s\n' % parentStyleSheet.href)
                 sheet = rule.styleSheet
-                href = urlparse.urljoin(base, rule.href)
+                href = urllib.parse.urljoin(base, rule.href)
                 if sheet:
-                    self._log.info(u'    %s\n' % sheet)
+                    self._log.info('    %s\n' % sheet)
                     self.stylesheetlist.append(sheet)
                     self._doImports(sheet, base=href)
 
@@ -223,12 +223,12 @@ class CSSCapture(object):
 
         Returns ``cssutils.stylesheets.StyleSheetList``.
         """
-        self._log.info(u'\nCapturing CSS from URL:\n    %s\n', url)
+        self._log.info('\nCapturing CSS from URL:\n    %s\n', url)
         self._nonparsed = {}
         self.stylesheetlist = cssutils.stylesheets.StyleSheetList()
 
         # used to save inline styles
-        scheme, loc, path, query, fragment = urlparse.urlsplit(url)
+        scheme, loc, path, query, fragment = urllib.parse.urlsplit(url)
         self._filename = os.path.basename(path)
 
         # get url content
@@ -240,7 +240,7 @@ class CSSCapture(object):
 
         self.docencoding = encutils.getEncodingInfo(
             res, rawdoc, log=self._log).encoding
-        self._log.info(u'\nUsing Encoding: %s\n', self.docencoding)
+        self._log.info('\nUsing Encoding: %s\n', self.docencoding)
 
         doctext = rawdoc.decode(self.docencoding)
 
@@ -278,10 +278,10 @@ class CSSCapture(object):
             url = sheet.href
             if not url:
                 inlines += 1
-                url = u'%s_INLINE_%s.css' % (self._filename, inlines)
+                url = '%s_INLINE_%s.css' % (self._filename, inlines)
 
             # build savepath
-            scheme, loc, path, query, fragment = urlparse.urlsplit(url)
+            scheme, loc, path, query, fragment = urllib.parse.urlsplit(url)
             # no absolute path
             if path and path.startswith('/'):
                 path = path[1:]
@@ -291,12 +291,12 @@ class CSSCapture(object):
             savefn = os.path.join(savepath, fn)
             try:
                 os.makedirs(savepath)
-            except OSError, e:
+            except OSError as e:
                 if e.errno != errno.EEXIST:
                     raise e
-                self._log.debug(u'Path "%s" already exists.', savepath)
+                self._log.debug('Path "%s" already exists.', savepath)
 
-            self._log.info(u'SAVING %s, %s %r' % (i+1, msg, savefn))
+            self._log.info('SAVING %s, %s %r' % (i+1, msg, savefn))
 
             sf = open(savefn, 'wb')
             if saveraw:
@@ -330,10 +330,10 @@ def csscombine(path=None, url=None, cssText=None, href=None,
         `resolveVariables` = True
             defines if variables in combined sheet should be resolved
     """
-    cssutils.log.info(u'Combining files from %r' % url, 
+    cssutils.log.info('Combining files from %r' % url,
                       neverraise=True)
     if sourceencoding is not None:
-        cssutils.log.info(u'Using source encoding %r' % sourceencoding,
+        cssutils.log.info('Using source encoding %r' % sourceencoding,
                           neverraise=True)
         
     parser = cssutils.CSSParser(parseComments=not minify)
@@ -349,7 +349,7 @@ def csscombine(path=None, url=None, cssText=None, href=None,
 
     result = cssutils.resolveImports(src)
     result.encoding = targetencoding
-    cssutils.log.info(u'Using target encoding: %r' % targetencoding, neverraise=True)
+    cssutils.log.info('Using target encoding: %r' % targetencoding, neverraise=True)
 
     oldser = cssutils.ser
     cssutils.setSerializer(cssutils.serialize.CSSSerializer())
diff --git a/src/cssutils/scripts/__init__.py b/src/cssutils/scripts/__init__.py
index 87030eb..3fefceb 100644
--- a/src/cssutils/scripts/__init__.py
+++ b/src/cssutils/scripts/__init__.py
@@ -1,4 +1,4 @@
-from csscombine import csscombine
+from .csscombine import csscombine
 __all__ = ["csscapture", "csscombine", "cssparse"]
  
 
diff --git a/src/cssutils/scripts/csscapture.py b/src/cssutils/scripts/csscapture.py
index 5bcb181..2c9f874 100644
--- a/src/cssutils/scripts/csscapture.py
+++ b/src/cssutils/scripts/csscapture.py
@@ -55,14 +55,14 @@ def main(args=None):
         if options.saveto:
             saveto = options.saveto
         else:
-            saveto = u'_CSSCapture_SAVED'
+            saveto = '_CSSCapture_SAVED'
         c.saveto(saveto, saveraw=options.saveraw, minified=options.minified)
     else:
         for i, s in enumerate(stylesheetlist):
-            print u'''%s.
+            print('''%s.
     encoding: %r
     title: %r
-    href: %r''' % (i + 1, s.encoding, s.title, s.href)
+    href: %r''' % (i + 1, s.encoding, s.title, s.href))
 
 
 if __name__ == "__main__":
diff --git a/src/cssutils/scripts/csscombine.py b/src/cssutils/scripts/csscombine.py
index 91d7a41..0e7bbea 100644
--- a/src/cssutils/scripts/csscombine.py
+++ b/src/cssutils/scripts/csscombine.py
@@ -76,15 +76,15 @@ def main(args=None):
     options, path = parser.parse_args()
 
     if options.url:
-        print csscombine(url=options.url,
+        print(csscombine(url=options.url,
                          sourceencoding=options.sourceencoding, 
                          targetencoding=options.targetencoding,
-                         minify=options.minify)
+                         minify=options.minify))
     elif path:
-        print csscombine(path=path[0],
+        print(csscombine(path=path[0],
                          sourceencoding=options.sourceencoding, 
                          targetencoding=options.targetencoding,
-                         minify=options.minify)
+                         minify=options.minify))
     else:
         parser.error('no path or URL (-u) given')
 
diff --git a/src/cssutils/scripts/cssparse.py b/src/cssutils/scripts/cssparse.py
index 14baef2..d4a05cc 100644
--- a/src/cssutils/scripts/cssparse.py
+++ b/src/cssutils/scripts/cssparse.py
@@ -44,17 +44,17 @@ def main(args=None):
         cssutils.ser.prefs.useMinified()
 
     if options.string:
-        sheet = p.parseString(u''.join(params), encoding=options.encoding)
-        print sheet.cssText
+        sheet = p.parseString(''.join(params), encoding=options.encoding)
+        print(sheet.cssText)
     elif options.url:
         sheet = p.parseUrl(options.url, encoding=options.encoding)
-        print sheet.cssText
+        print(sheet.cssText)
     else:
         for filename in params:
             sys.stderr.write('=== CSS FILE: "%s" ===\n' % filename)
             sheet = p.parseFile(filename, encoding=options.encoding)
-            print sheet.cssText
-            print
+            print(sheet.cssText)
+            print()
             sys.stderr.write('\n')
 
 
diff --git a/src/cssutils/serialize.py b/src/cssutils/serialize.py
index 51162ec..fd41134 100644
--- a/src/cssutils/serialize.py
+++ b/src/cssutils/serialize.py
@@ -8,7 +8,7 @@ __version__ = '$Id$'
 from cssutils.helper import normalize
 import codecs
 import cssutils
-import helper
+from . import helper
 import re
 import xml.dom
 
@@ -20,7 +20,7 @@ def _escapecss(e):
     E.g. the german umlaut 'ä' is escaped as \E4
     """
     s = e.object[e.start:e.end]
-    return u''.join([ur'\%s ' % str(hex(ord(x)))[2:] # remove 0x from hex
+    return ''.join([r'\%s ' % str(hex(ord(x)))[2:] # remove 0x from hex
                      .upper() for x in s]), e.end
 
 codecs.register_error('escapecss', _escapecss)
@@ -109,18 +109,18 @@ class Preferences(object):
     def __init__(self, **initials):
         """Always use named instead of positional parameters."""
         self.useDefaults()
-        for key, value in initials.items():
+        for key, value in list(initials.items()):
             if value:
                 self.__setattr__(key, value)
 
     def __repr__(self):
-        return u"cssutils.css.%s(%s)" % (self.__class__.__name__,
-            u', '.join(['\n    %s=%r' % (p, self.__getattribute__(p)) for p in self.__dict__]
+        return "cssutils.css.%s(%s)" % (self.__class__.__name__,
+            ', '.join(['\n    %s=%r' % (p, self.__getattribute__(p)) for p in self.__dict__]
                 ))
 
     def __str__(self):
-        return u"<cssutils.css.%s object %s at 0x%x" % (self.__class__.__name__,
-            u' '.join(['%s=%r' % (p, self.__getattribute__(p)) for p in self.__dict__]
+        return "<cssutils.css.%s object %s at 0x%x" % (self.__class__.__name__,
+            ' '.join(['%s=%r' % (p, self.__getattribute__(p)) for p in self.__dict__]
                 ),
                 id(self))
 
@@ -130,7 +130,7 @@ class Preferences(object):
         self.defaultPropertyName = True
         self.defaultPropertyPriority = True
         self.importHrefFormat = None
-        self.indent = 4 * u' '
+        self.indent = 4 * ' '
         self.indentClosingBrace = True
         self.indentSpecificities = False
         self.keepAllProperties = True
@@ -139,17 +139,17 @@ class Preferences(object):
         self.keepUnknownAtRules = True
         self.keepUsedNamespaceRulesOnly = False
         self.lineNumbers = False
-        self.lineSeparator = u'\n'
-        self.listItemSpacer = u' '
+        self.lineSeparator = '\n'
+        self.listItemSpacer = ' '
         self.minimizeColorHash = True
         self.normalizedVarNames = True
         self.omitLastSemicolon = True
         self.omitLeadingZero = False
-        self.paranthesisSpacer = u' '
-        self.propertyNameSpacer = u' '
+        self.paranthesisSpacer = ' '
+        self.propertyNameSpacer = ' '
         self.resolveVariables = True
-        self.selectorCombinatorSpacer = u' '
-        self.spacer = u' '
+        self.selectorCombinatorSpacer = ' '
+        self.spacer = ' '
         self.validOnly = False # should not be changed currently!!!
 
     def useMinified(self):
@@ -159,21 +159,21 @@ class Preferences(object):
         and override specific settings you want adjusted afterwards.
         """
         self.importHrefFormat = 'string'
-        self.indent = u''
+        self.indent = ''
         self.keepComments = False
         self.keepEmptyRules = False
         self.keepUnknownAtRules = False
         self.keepUsedNamespaceRulesOnly = True
         self.lineNumbers = False
-        self.lineSeparator = u''
-        self.listItemSpacer = u''
+        self.lineSeparator = ''
+        self.listItemSpacer = ''
         self.minimizeColorHash = True
         self.omitLastSemicolon = True
         self.omitLeadingZero = True
-        self.paranthesisSpacer = u''
-        self.propertyNameSpacer = u''
-        self.selectorCombinatorSpacer = u''
-        self.spacer = u''
+        self.paranthesisSpacer = ''
+        self.propertyNameSpacer = ''
+        self.selectorCombinatorSpacer = ''
+        self.spacer = ''
         self.validOnly = False
 
 
@@ -223,7 +223,7 @@ class Out(object):
             elif 'S' == type_ and not keepS:
                 return
             elif 'S' == type_ and keepS:
-                val = u' '
+                val = ' '
             elif 'STRING' == type_:
                 # may be empty but MUST not be None
                 if val is None:
@@ -239,7 +239,7 @@ class Out(object):
                 val = val.cssText
             elif hasattr(val, 'mediaText'):
                 val = val.mediaText
-            elif val in u'+>~,:{;)]/=}' and not alwaysS:
+            elif val in '+>~,:{;)]/=}' and not alwaysS:
                 self._remove_last_if_S()
 #            elif type_ in ('Property', cssutils.css.CSSRule.UNKNOWN_RULE):
 #                val = val.cssText
@@ -251,38 +251,38 @@ class Out(object):
 
             # APPEND
 
-            if indent or (val == u'}' and self.ser.prefs.indentClosingBrace):
+            if indent or (val == '}' and self.ser.prefs.indentClosingBrace):
                 self.out.append(self.ser._indentblock(val, self.ser._level+1))
             else:
-                if val.endswith(u' '):
+                if val.endswith(' '):
                     self._remove_last_if_S()
                 self.out.append(val)
 
             # POST
-            if alwaysS and val in u'-+*/': # calc, */ not really but do anyway
-                self.out.append(u' ')
-            elif val in u'+>~': # enclose selector combinator
+            if alwaysS and val in '-+*/': # calc, */ not really but do anyway
+                self.out.append(' ')
+            elif val in '+>~': # enclose selector combinator
                 self.out.insert(-1, self.ser.prefs.selectorCombinatorSpacer)
                 self.out.append(self.ser.prefs.selectorCombinatorSpacer)
-            elif u')' == val and not keepS: # CHAR funcend
+            elif ')' == val and not keepS: # CHAR funcend
                 # TODO: pref?
-                self.out.append(u' ')
-            elif u',' == val: # list
+                self.out.append(' ')
+            elif ',' == val: # list
                 self.out.append(self.ser.prefs.listItemSpacer)
-            elif u':' == val: # prop
+            elif ':' == val: # prop
                 self.out.append(self.ser.prefs.propertyNameSpacer)
-            elif u'{' == val: # block start
+            elif '{' == val: # block start
                 self.out.insert(-1, self.ser.prefs.paranthesisSpacer)
                 self.out.append(self.ser.prefs.lineSeparator)
-            elif u';' == val or 'styletext' == type_: # end or prop or block
+            elif ';' == val or 'styletext' == type_: # end or prop or block
                 self.out.append(self.ser.prefs.lineSeparator)
-            elif val not in u'}[]()/=' and space and type_ != 'FUNCTION':
+            elif val not in '}[]()/=' and space and type_ != 'FUNCTION':
                 self.out.append(self.ser.prefs.spacer)
                 if type_ != 'STRING' and not self.ser.prefs.spacer and \
-                   self.out and not self.out[-1].endswith(u' '):
-                    self.out.append(u' ')
+                   self.out and not self.out[-1].endswith(' '):
+                    self.out.append(' ')
 
-    def value(self, delim=u'', end=None, keepS=False):
+    def value(self, delim='', end=None, keepS=False):
         "returns all items joined by delim"
         if not keepS:
             self._remove_last_if_S()
@@ -326,7 +326,7 @@ class CSSSerializer(object):
         if not self.prefs.lineSeparator:
             return text
         return self.prefs.lineSeparator.join(
-            [u'%s%s' % (level * self.prefs.indent, line)
+            ['%s%s' % (level * self.prefs.indent, line)
                 for line in text.split(self.prefs.lineSeparator)]
         )
 
@@ -346,7 +346,7 @@ class CSSSerializer(object):
             pad = len(str(text.count(self.prefs.lineSeparator)+1))
             out = []
             for i, line in enumerate(text.split(self.prefs.lineSeparator)):
-                out.append((u'%*i: %s') % (pad, i+1, line))
+                out.append(('%*i: %s') % (pad, i+1, line))
             text = self.prefs.lineSeparator.join(out)
         return text
 
@@ -359,7 +359,7 @@ class CSSSerializer(object):
             val[1] == val[2] and\
             val[3] == val[4] and\
             val[5] == val[6]:
-                return u'#%s%s%s' % (val[1], val[3], val[5])
+                return '#%s%s%s' % (val[1], val[3], val[5])
         return val
 
     def _valid(self, x):
@@ -387,10 +387,10 @@ class CSSSerializer(object):
         try:
             encoding = stylesheet.cssRules[0].encoding
         except (IndexError, AttributeError):
-            encoding = u'UTF-8'
+            encoding = 'UTF-8'
 
         # TODO: py3 return b str but tests use unicode?
-        return text.encode(encoding, u'escapecss')
+        return text.encode(encoding, 'escapecss')
 
     def do_CSSComment(self, rule):
         """
@@ -399,7 +399,7 @@ class CSSSerializer(object):
         if rule._cssText and self.prefs.keepComments:
             return rule._cssText
         else:
-            return u''
+            return ''
 
     def do_CSSCharsetRule(self, rule):
         """
@@ -410,9 +410,9 @@ class CSSSerializer(object):
         no comments or other things allowed!
         """
         if rule.wellformed:
-            return u'@charset %s;' % helper.string(rule.encoding)
+            return '@charset %s;' % helper.string(rule.encoding)
         else:
-            return u''
+            return ''
 
     def do_CSSVariablesRule(self, rule):
         """
@@ -433,12 +433,12 @@ class CSSSerializer(object):
             for item in rule.seq:
                 # assume comments {
                 out.append(item.value, item.type)
-            out.append(u'{')
-            out.append(u'%s%s}' % (variablesText, self.prefs.lineSeparator),
+            out.append('{')
+            out.append('%s%s}' % (variablesText, self.prefs.lineSeparator),
                        indent=1)
             return out.value()
         else:
-            return u''
+            return ''
 
     def do_CSSFontFaceRule(self, rule):
         """
@@ -457,12 +457,12 @@ class CSSSerializer(object):
             for item in rule.seq:
                 # assume comments {
                 out.append(item.value, item.type)
-            out.append(u'{')
-            out.append(u'%s%s}' % (styleText, self.prefs.lineSeparator),
+            out.append('{')
+            out.append('%s%s}' % (styleText, self.prefs.lineSeparator),
                        indent=1)
             return out.value()
         else:
-            return u''
+            return ''
 
     def do_CSSImportRule(self, rule):
         """
@@ -494,16 +494,16 @@ class CSSSerializer(object):
                 elif 'media' == type_:
                     # media
                     mediaText = self.do_stylesheets_medialist(val)
-                    if mediaText and mediaText != u'all':
+                    if mediaText and mediaText != 'all':
                         out.append(mediaText)
                 elif 'name' == type_:
                     out.append(val, 'STRING')
                 else:
                     out.append(val, type_)
 
-            return out.value(end=u';')
+            return out.value(end=';')
         else:
-            return u''
+            return ''
 
     def do_CSSNamespaceRule(self, rule):
         """
@@ -526,9 +526,9 @@ class CSSSerializer(object):
                 else:
                     out.append(val, type_)
 
-            return out.value(end=u';')
+            return out.value(end=';')
         else:
-            return u''
+            return ''
 
     def do_CSSMediaRule(self, rule):
         """
@@ -540,13 +540,13 @@ class CSSSerializer(object):
 
         # mediaquery
         if not rule.media.wellformed:
-            return u''
+            return ''
 
         # @media
         out = [self._atkeyword(rule)]
         if not len(self.prefs.spacer):
             # for now always with space as only webkit supports @mediaall?
-            out.append(u' ')
+            out.append(' ')
         else:
             out.append(self.prefs.spacer) # might be empty
 
@@ -563,7 +563,7 @@ class CSSSerializer(object):
 
         #  {
         out.append(self.prefs.paranthesisSpacer)
-        out.append(u'{')
+        out.append('{')
         out.append(self.prefs.lineSeparator)
 
         # rules
@@ -574,15 +574,15 @@ class CSSSerializer(object):
                 # indent each line of cssText
                 rulesout.append(self._indentblock(rtext, self._level + 1))
                 rulesout.append(self.prefs.lineSeparator)
-        if not self.prefs.keepEmptyRules and not u''.join(rulesout).strip():
-            return u''
+        if not self.prefs.keepEmptyRules and not ''.join(rulesout).strip():
+            return ''
         out.extend(rulesout)
 
         #     }
-        out.append(u'%s}' % ((self._level + int(self.prefs.indentClosingBrace))
+        out.append('%s}' % ((self._level + int(self.prefs.indentClosingBrace))
                              * self.prefs.indent))
 
-        return u''.join(out)
+        return ''.join(out)
 
     def do_CSSPageRule(self, rule):
         """
@@ -598,7 +598,7 @@ class CSSSerializer(object):
         + CSSComments
         """
         # rules
-        rules = u''
+        rules = ''
         rulesout = []
         for r in rule.cssRules:
             rtext = r.cssText
@@ -606,7 +606,7 @@ class CSSSerializer(object):
                 rulesout.append(rtext)
                 rulesout.append(self.prefs.lineSeparator)
 
-        rulesText = u''.join(rulesout)#.strip()
+        rulesText = ''.join(rulesout)#.strip()
 
         # omit semicolon only if no MarginRules
         styleText = self.do_css_CSSStyleDeclaration(rule.style,
@@ -616,11 +616,11 @@ class CSSSerializer(object):
             out = Out(self)
             out.append(self._atkeyword(rule))
             out.append(rule.selectorText)
-            out.append(u'{')
+            out.append('{')
 
             if styleText:
                 if not rulesText:
-                    out.append(u'%s%s' % (styleText,
+                    out.append('%s%s' % (styleText,
                                           self.prefs.lineSeparator
                                           ), indent=1)
                 else:
@@ -630,12 +630,12 @@ class CSSSerializer(object):
                 out.append(rulesText, indent=1)
             #?
             self._level -= 1
-            out.append(u'}')
+            out.append('}')
             self._level += 1
 
             return out.value()
         else:
-            return u''
+            return ''
 
     def do_CSSPageRuleSelector(self, seq):
         "Serialize selector of a CSSPageRule"
@@ -677,13 +677,13 @@ class CSSSerializer(object):
 
                 # ok for now:
                 out.append(self._atkeyword(rule), type_='ATKEYWORD')
-                out.append(u'{')
-                out.append(u'%s%s' % (self._indentblock(styleText, self._level+1),
+                out.append('{')
+                out.append('%s%s' % (self._indentblock(styleText, self._level+1),
                                        self.prefs.lineSeparator))
-                out.append(u'}')
+                out.append('}')
                 return out.value()
 
-        return u''
+        return ''
 
     def do_CSSUnknownRule(self, rule):
         """
@@ -699,7 +699,7 @@ class CSSSerializer(object):
             for item in rule.seq:
                 type_, val = item.type, item.value
                 # PRE
-                if u'}' == val:
+                if '}' == val:
                     # close last open item on stack
                     stackblock = stacks.pop().value()
                     if stackblock:
@@ -715,13 +715,13 @@ class CSSSerializer(object):
                     out.append(val, type_)
 
                 # POST
-                if u'{' == val:
+                if '{' == val:
                     # new stack level
                     stacks.append(Out(self))
 
             return out.value()
         else:
-            return u''
+            return ''
 
     def do_CSSStyleRule(self, rule):
         """
@@ -759,20 +759,20 @@ class CSSSerializer(object):
 
         selectorText = self.do_css_SelectorList(rule.selectorList)
         if not selectorText or not rule.wellformed:
-            return u''
+            return ''
         self._level += 1
-        styleText = u''
+        styleText = ''
         try:
             styleText = self.do_css_CSSStyleDeclaration(rule.style)
         finally:
             self._level -= 1
         if not styleText:
                 if self.prefs.keepEmptyRules:
-                    return u'%s%s{}' % (selectorText,
+                    return '%s%s{}' % (selectorText,
                                         self.prefs.paranthesisSpacer)
         else:
             return self._indentblock(
-                u'%s%s{%s%s%s%s}' % (
+                '%s%s{%s%s%s%s}' % (
                     selectorText,
                     self.prefs.paranthesisSpacer,
                     self.prefs.lineSeparator,
@@ -792,10 +792,10 @@ class CSSSerializer(object):
                     out.append(part.selectorText)
                 else:
                     out.append(part) # should not happen
-            sep = u',%s' % self.prefs.listItemSpacer
+            sep = ',%s' % self.prefs.listItemSpacer
             return sep.join(out)
         else:
-            return u''
+            return ''
 
     def do_css_Selector(self, selector):
         """
@@ -822,21 +822,21 @@ class CSSSerializer(object):
                         out.append(name, type_, space=False)
                     else:
                         if namespaceURI == cssutils._ANYNS:
-                            prefix = u'*'
+                            prefix = '*'
                         else:
                             try:
                                 prefix = selector._namespaces.prefixForNamespaceURI(
                                                     namespaceURI)
                             except IndexError:
-                                prefix = u''
+                                prefix = ''
 
-                        out.append(u'%s|%s' % (prefix, name), type_, space=False)
+                        out.append('%s|%s' % (prefix, name), type_, space=False)
                 else:
                     out.append(val, type_, space=False, keepS=True)
 
             return out.value()
         else:
-            return u''
+            return ''
 
     def do_css_CSSVariablesDeclaration(self, variables):
         """Variables of CSSVariableRule."""
@@ -846,15 +846,15 @@ class CSSSerializer(object):
             lastitem = len(variables.seq) - 1
             for i, item in enumerate(variables.seq):
                 type_, val = item.type, item.value
-                if u'var' == type_:
+                if 'var' == type_:
                     name, cssvalue = val
                     if self.prefs.normalizedVarNames:
                         name = normalize(name)
                     out.append(name)
-                    out.append(u':')
+                    out.append(':')
                     out.append(cssvalue.cssText)
                     if i < lastitem or not self.prefs.omitLastSemicolon:
-                        out.append(u';')
+                        out.append(';')
 
                 elif isinstance(val, cssutils.css.CSSComment):
                     # CSSComment
@@ -867,7 +867,7 @@ class CSSSerializer(object):
             return out.value().strip()
 
         else:
-            return u''
+            return ''
 
     def do_css_CSSStyleDeclaration(self, style, separator=None, omit=True):
         """
@@ -906,7 +906,7 @@ class CSSSerializer(object):
                     if val.cssText:
                         out.append(val.cssText)
                         if not (omitLastSemicolon and i==len(seq)-1):
-                            out.append(u';')
+                            out.append(';')
                         out.append(separator)
                 elif isinstance(val, cssutils.css.CSSUnknownRule):
                     # @rule
@@ -920,10 +920,10 @@ class CSSSerializer(object):
             if out and out[-1] == separator:
                 del out[-1]
 
-            return u''.join(out)
+            return ''.join(out)
 
         else:
-            return u''
+            return ''
 
     def do_Property(self, property):
         """
@@ -950,7 +950,7 @@ class CSSSerializer(object):
             if out and (not property._mediaQuery or
                         property._mediaQuery and value.cssText):
                 # MediaQuery may consist of name only
-                out.append(u':')
+                out.append(':')
                 out.append(self.prefs.propertyNameSpacer)
 
             # value
@@ -958,7 +958,7 @@ class CSSSerializer(object):
 
             # priority
             if out and priorityseq:
-                out.append(u' ')
+                out.append(' ')
                 for part in priorityseq:
                     if hasattr(part, 'cssText'): # comments
                         out.append(part.cssText)
@@ -969,7 +969,7 @@ class CSSSerializer(object):
                         else:
                             out.append(part)
 
-        return u''.join(out)
+        return ''.join(out)
 
     def do_Property_priority(self, priorityseq):
         """
@@ -979,17 +979,17 @@ class CSSSerializer(object):
         out = []
         for part in priorityseq:
             if hasattr(part, 'cssText'): # comments
-                out.append(u' ')
+                out.append(' ')
                 out.append(part.cssText)
-                out.append(u' ')
+                out.append(' ')
             else:
                 out.append(part)
-        return u''.join(out).strip()
+        return ''.join(out).strip()
 
     def do_css_PropertyValue(self, value, valuesOnly=False):
         """Serializes a PropertyValue"""
         if not value:
-            return u''
+            return ''
         else:
             out = Out(self)
             for item in value.seq:
@@ -1008,7 +1008,7 @@ class CSSSerializer(object):
             return out.value()
 
     def _strip_zeros(self, s):
-        i = s.index(u'.') + 2
+        i = s.index('.') + 2
         a, b = s[0:i], s[i:len(s)]
         b = b.rstrip('0')
         return a + b
@@ -1016,35 +1016,35 @@ class CSSSerializer(object):
     def do_css_Value(self, value, valuesOnly=None):
         """Serializes a Value, valuesOnly is ignored"""
         if not value:
-            return u''
+            return ''
         else:
             out = Out(self)
-            if value.type in (u'DIMENSION', u'NUMBER', u'PERCENTAGE'):
-                dim = value.dimension or u''
+            if value.type in ('DIMENSION', 'NUMBER', 'PERCENTAGE'):
+                dim = value.dimension or ''
                 if value.value == 0:
-                    val = u'0'
+                    val = '0'
                     if value.dimension in ('cm', 'mm', 'in', 'px', 'pc', 'pt',
                                            'em', 'ex'):
-                        dim = u''
+                        dim = ''
                 elif value.value == int(value.value):
                     # cut off after . which is zero anyway
-                    val = unicode(int(value.value))
+                    val = str(int(value.value))
                 elif self.prefs.omitLeadingZero and -1 < value.value < 1:
-                    v = self._strip_zeros(u'%f' % value.value) # issue #27
+                    v = self._strip_zeros('%f' % value.value) # issue #27
                     val = v
-                    if value._sign == u'-':
+                    if value._sign == '-':
                         val = v[0] + v[2:]
                     else:
                         val = v[1:]
                 else:
 
-                    val = self._strip_zeros(u'%f' % value.value) # issue #27
+                    val = self._strip_zeros('%f' % value.value) # issue #27
 
                 # keep '+' if given
-                if value.value != 0 and value._sign == u'+':
-                    sign = u'+'
+                if value.value != 0 and value._sign == '+':
+                    sign = '+'
                 else:
-                    sign = u''
+                    sign = ''
 
                 out.append(sign + val + dim, value.type)
 
@@ -1062,13 +1062,13 @@ class CSSSerializer(object):
                     'IDENT': self.do_css_Value
                     }[value.colorType](value,
                                        valuesOnly=valuesOnly)
-        except KeyError, e:
-            return u''
+        except KeyError as e:
+            return ''
 
     def do_css_CSSFunction(self, cssvalue, valuesOnly=False):
         """Serialize a CSS function value"""
         if not cssvalue:
-            return u''
+            return ''
         else:
             out = Out(self)
             for item in cssvalue.seq:
@@ -1081,7 +1081,7 @@ class CSSSerializer(object):
     def do_css_CSSCalc(self, cssvalue, valuesOnly=False):
         """Serialize a CSS calc value"""
         if not cssvalue:
-            return u''
+            return ''
         else:
             out = Out(self)
             for item in cssvalue.seq:
@@ -1092,7 +1092,7 @@ class CSSSerializer(object):
                 elif hasattr(val, 'cssText'):
                     # RGBColor or CSSValue if a CSSValueList
                     out.append(val.cssText, type_)
-                elif type_ == 'CHAR' and val in u'-+*/':
+                elif type_ == 'CHAR' and val in '-+*/':
                     out.append(val, type_, alwaysS=True)
                 else:
                     out.append(val, type_)
@@ -1103,7 +1103,7 @@ class CSSSerializer(object):
         """Serialize an ExpressionValue (IE only),
         should at least keep the original syntax"""
         if not cssvalue:
-            return u''
+            return ''
         else:
             out = Out(self)
             for item in cssvalue.seq:
@@ -1117,7 +1117,7 @@ class CSSSerializer(object):
     def do_css_CSSVariable(self, variable, IGNORED=False):
         """Serializes a CSSVariable"""
         if not variable or not variable.name:
-            return u''
+            return ''
         else:
             out = Out(self)
             v = variable.value
@@ -1127,12 +1127,12 @@ class CSSSerializer(object):
 
             else:
                 # keep var(NAME)
-                out.append(u'var(', 'FUNCTION')
+                out.append('var(', 'FUNCTION')
                 out.append(variable.name, 'IDENT')
                 if variable.fallback:
-                    out.append(u',', 'COMMA')
+                    out.append(',', 'COMMA')
                     out.append(variable.fallback.cssText)
-                out.append(u')')
+                out.append(')')
 
             return out.value()
 
@@ -1145,7 +1145,7 @@ class CSSSerializer(object):
         be stripped. This is because how Opera handles CSS for PDAs.
         """
         if len(medialist) == 0:
-            return u'all'
+            return 'all'
         else:
             seq = medialist.seq
             out = Out(self)
@@ -1156,7 +1156,7 @@ class CSSSerializer(object):
 
                 if type_ == 'MediaQuery':
                     if firstdone:
-                        out.append(u',', 'CHAR')
+                        out.append(',', 'CHAR')
                     else:
                         firstdone = True
                 
@@ -1169,7 +1169,7 @@ class CSSSerializer(object):
         a single media used in medialist
         """
         if not mediaquery.wellformed:
-            return u''
+            return ''
         else:
             withsemi = []
             nextmq = False
@@ -1177,7 +1177,7 @@ class CSSSerializer(object):
                 type_, val = item.type, item.value
 
                 if type_ == 'MediaQuery' and nextmq:
-                    withsemi.append(('CHAR', u','))
+                    withsemi.append(('CHAR', ','))
                     nextmq = False
                 else:
                     nextmq = True
diff --git a/src/cssutils/settings.py b/src/cssutils/settings.py
index a1c04a8..17c0647 100644
--- a/src/cssutils/settings.py
+++ b/src/cssutils/settings.py
@@ -9,7 +9,7 @@ def set(key, value):
     Clears the tokenizer cache which holds the compiled productions!
     """
     if key == 'DXImageTransform.Microsoft' and value == True:
-        import cssproductions
-        import tokenize2
+        from . import cssproductions
+        from . import tokenize2
         tokenize2._TOKENIZER_CACHE.clear()
         cssproductions.PRODUCTIONS.insert(1, cssproductions._DXImageTransform)
diff --git a/src/cssutils/stylesheets/__init__.py b/src/cssutils/stylesheets/__init__.py
index c82f1e4..8bfbe71 100644
--- a/src/cssutils/stylesheets/__init__.py
+++ b/src/cssutils/stylesheets/__init__.py
@@ -5,7 +5,7 @@ __all__ = ['MediaList', 'MediaQuery', 'StyleSheet', 'StyleSheetList']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from medialist import *
-from mediaquery import *
-from stylesheet import *
-from stylesheetlist import *
+from .medialist import *
+from .mediaquery import *
+from .stylesheet import *
+from .stylesheetlist import *
diff --git a/src/cssutils/stylesheets/medialist.py b/src/cssutils/stylesheets/medialist.py
index 65c8d91..7cc94dd 100644
--- a/src/cssutils/stylesheets/medialist.py
+++ b/src/cssutils/stylesheets/medialist.py
@@ -11,7 +11,7 @@ __version__ = '$Id$'
 from cssutils.prodparser import *
 from cssutils.helper import normalize, pushtoken
 from cssutils.css import csscomment
-from mediaquery import MediaQuery
+from .mediaquery import MediaQuery
 import cssutils
 import xml.dom
 
@@ -44,7 +44,7 @@ class MediaList(cssutils.util._NewListBase):
         self._wellformed = False
 
         if isinstance(mediaText, list):
-            mediaText = u','.join(mediaText)
+            mediaText = ','.join(mediaText)
 
         self._parentRule = parentRule
         
@@ -88,7 +88,7 @@ class MediaList(cssutils.util._NewListBase):
 
 
         mediaquery = lambda: Prod(name='MediaQueryStart',
-                                  match=lambda t, v: t == 'IDENT' or v == u'(',
+                                  match=lambda t, v: t == 'IDENT' or v == '(',
                                   toSeq=lambda t, tokens: ('MediaQuery', 
                                                            MediaQuery(pushtoken(t, tokens),
                                                                       _partof=True))
@@ -104,7 +104,7 @@ class MediaList(cssutils.util._NewListBase):
                          )
         # parse
         ok, seq, store, unused = ProdParser().parse(mediaText,
-                                                    u'MediaList',
+                                                    'MediaList',
                                                     prods, debug="ml")
 
         # each mq must be valid
@@ -123,7 +123,7 @@ class MediaList(cssutils.util._NewListBase):
         if not atleastone:
             ok = False
             self._wellformed = ok
-            self._log.error(u'MediaQuery: No content.',
+            self._log.error('MediaQuery: No content.',
                             error=xml.dom.SyntaxErr)
 
         self._wellformed = ok
@@ -137,7 +137,7 @@ class MediaList(cssutils.util._NewListBase):
                 if item.type == 'MediaQuery':
                     mediaType = item.value.mediaType
                     if mediaType:
-                        if mediaType == u'all':
+                        if mediaType == 'all':
                             # remove anthing else and keep all+comments(!) only
                             finalseq = commentseqonly
                             finalseq.append(item)
@@ -203,8 +203,8 @@ class MediaList(cssutils.util._NewListBase):
 
             self._seq._readonly = False
 
-            if u'all' in mts:
-                self._log.info(u'MediaList: Ignoring new medium %r as already specified "all" (set ``mediaText`` instead).' % newMedium, error=xml.dom.InvalidModificationErr)
+            if 'all' in mts:
+                self._log.info('MediaList: Ignoring new medium %r as already specified "all" (set ``mediaText`` instead).' % newMedium, error=xml.dom.InvalidModificationErr)
             
             elif newmt and newmt in mts:
                 # might be empty
@@ -212,7 +212,7 @@ class MediaList(cssutils.util._NewListBase):
                 self._seq.append(newMedium, 'MediaQuery')
 
             else:
-                if u'all' == newmt:
+                if 'all' == newmt:
                     self._clearSeq()
 
                 self._seq.append(newMedium, 'MediaQuery')
@@ -247,7 +247,7 @@ class MediaList(cssutils.util._NewListBase):
                 del self[i]
                 break
         else:
-            self._log.error(u'"%s" not in this MediaList' % oldMedium,
+            self._log.error('"%s" not in this MediaList' % oldMedium,
                             error=xml.dom.NotFoundErr)
 
     def item(self, index):
@@ -261,7 +261,7 @@ class MediaList(cssutils.util._NewListBase):
             return None
 
     parentRule = property(lambda self: self._parentRule,
-                          doc=u"The CSSRule (e.g. an @media or @import rule "
-                              u"this list is part of or None")
+                          doc="The CSSRule (e.g. an @media or @import rule "
+                              "this list is part of or None")
     
     wellformed = property(lambda self: self._wellformed)
diff --git a/src/cssutils/stylesheets/mediaquery.py b/src/cssutils/stylesheets/mediaquery.py
index 1c6b0b3..2832074 100644
--- a/src/cssutils/stylesheets/mediaquery.py
+++ b/src/cssutils/stylesheets/mediaquery.py
@@ -49,7 +49,7 @@ class MediaQuery(cssutils.util._NewBase):#cssutils.util.Base):
         super(MediaQuery, self).__init__()
 
         self._wellformed = False
-        self._mediaType = u''
+        self._mediaType = ''
         self._partof = _partof
         if mediaText:
             self.mediaText = mediaText # sets self._mediaType too
@@ -99,32 +99,32 @@ class MediaQuery(cssutils.util._NewBase):#cssutils.util.Base):
         """
         self._checkReadonly()
 
-        expression = lambda: Sequence(PreDef.char(name='expression', char=u'('),
-                                      Prod(name=u'media_feature',
+        expression = lambda: Sequence(PreDef.char(name='expression', char='('),
+                                      Prod(name='media_feature',
                                            match=lambda t, v: t == PreDef.types.IDENT
                                       ),
-                                      Sequence(PreDef.char(name='colon', char=u':'),
+                                      Sequence(PreDef.char(name='colon', char=':'),
                                                cssutils.css.value.MediaQueryValueProd(self),
                                                minmax=lambda: (0, 1) # optional
                                                ),
-                                      PreDef.char(name='expression END', char=u')',
+                                      PreDef.char(name='expression END', char=')',
                                                   stopIfNoMoreMatch=self._partof
                                                   )
                                       )
 
-        prods = Choice(Sequence(Prod(name=u'ONLY|NOT', # media_query
+        prods = Choice(Sequence(Prod(name='ONLY|NOT', # media_query
                                      match=lambda t, v: t == PreDef.types.IDENT and 
-                                                        normalize(v) in (u'only', u'not'),
+                                                        normalize(v) in ('only', 'not'),
                                      optional=True,
                                      toStore='not simple'
                                      ), 
-                                Prod(name=u'media_type',
+                                Prod(name='media_type',
                                      match=lambda t, v: t == PreDef.types.IDENT and 
                                                         normalize(v) in self.MEDIA_TYPES,
                                      stopIfNoMoreMatch=True,
                                      toStore='media_type'
                                      ),                   
-                                Sequence(Prod(name=u'AND',
+                                Sequence(Prod(name='AND',
                                               match=lambda t, v: t == PreDef.types.IDENT and 
                                                                  normalize(v) == 'and',
                                               toStore='not simple'
@@ -134,7 +134,7 @@ class MediaQuery(cssutils.util._NewBase):#cssutils.util.Base):
                                          )
                                 ),
                        Sequence(expression(),                   
-                                Sequence(Prod(name=u'AND',
+                                Sequence(Prod(name='AND',
                                               match=lambda t, v: t == PreDef.types.IDENT and 
                                                                  normalize(v) == 'and'
                                          ),                   
@@ -146,13 +146,13 @@ class MediaQuery(cssutils.util._NewBase):#cssutils.util.Base):
         
         # parse
         ok, seq, store, unused = ProdParser().parse(mediaText, 
-                                                    u'MediaQuery',
+                                                    'MediaQuery',
                                                     prods)
         self._wellformed = ok
         if ok:
             try:
                 media_type = store['media_type']
-            except KeyError, e:
+            except KeyError as e:
                 pass
             else:
                 if 'not simple' not in store:
@@ -183,7 +183,7 @@ class MediaQuery(cssutils.util._NewBase):#cssutils.util.Base):
 
         if nmediaType not in self.MEDIA_TYPES:
             self._log.error(
-                u'MediaQuery: Syntax Error in media type "%s".' % mediaType,
+                'MediaQuery: Syntax Error in media type "%s".' % mediaType,
                 error=xml.dom.SyntaxErr)
         else:
             # set
@@ -191,8 +191,8 @@ class MediaQuery(cssutils.util._NewBase):#cssutils.util.Base):
 
             # update seq
             for i, x in enumerate(self._seq):
-                if isinstance(x.value, basestring):
-                    if normalize(x.value) in (u'only', u'not'):
+                if isinstance(x.value, str):
+                    if normalize(x.value) in ('only', 'not'):
                         continue
                     else:
                         # TODO: simplify!
diff --git a/src/cssutils/stylesheets/stylesheet.py b/src/cssutils/stylesheets/stylesheet.py
index 10174ba..cc29a5a 100644
--- a/src/cssutils/stylesheets/stylesheet.py
+++ b/src/cssutils/stylesheets/stylesheet.py
@@ -4,7 +4,7 @@ __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
 import cssutils
-import urlparse
+import urllib.parse
 
 class StyleSheet(cssutils.util.Base2):
     """
@@ -23,7 +23,7 @@ class StyleSheet(cssutils.util.Base2):
     def __init__(self, type='text/css',
                  href=None,
                  media=None,
-                 title=u'',
+                 title='',
                  ownerNode=None,
                  parentStyleSheet=None,
                  alternate=False,
diff --git a/src/cssutils/tests/basetest.py b/src/cssutils/tests/basetest.py
index 081ecf9..3f97b42 100644
--- a/src/cssutils/tests/basetest.py
+++ b/src/cssutils/tests/basetest.py
@@ -4,9 +4,9 @@ import logging
 import os
 import re
 import sys
-import StringIO
+import io
 import unittest
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 from email import message_from_string, message_from_file
 
 # add src to PYTHONPATH
@@ -86,14 +86,14 @@ class BaseTestCase(unittest.TestCase):
             exc_pattern = None
 
         argv = [repr(a) for a in args]\
-               + ["%s=%r" % (k,v)  for k,v in kwargs.items()]
+               + ["%s=%r" % (k,v)  for k,v in list(kwargs.items())]
         callsig = "%s(%s)" % (callable.__name__, ", ".join(argv))
 
         try:
             callable(*args, **kwargs)
-        except exception, exc:
+        except exception as exc:
             if exc_args is not None:
-                self.failIf(exc.args != exc_args,
+                self.assertFalse(exc.args != exc_args,
                             "%s raised %s with unexpected args: "\
                             "expected=%r, actual=%r"\
                             % (callsig, exc.__class__, exc_args, exc.args))
@@ -105,7 +105,7 @@ class BaseTestCase(unittest.TestCase):
                                    str(exc)))
         except:
             exc_info = sys.exc_info()
-            print exc_info
+            print(exc_info)
             self.fail("%s raised an unexpected exception type: "\
                       "expected=%s, actual=%s"\
                       % (callsig, exception, exc_info[0]))
@@ -129,8 +129,8 @@ class BaseTestCase(unittest.TestCase):
         """
         try:
             callableObj(*args, **kwargs)
-        except excClass, exc:
-            excMsg = unicode(exc)
+        except excClass as exc:
+            excMsg = str(exc)
             if not msg:
                 # No message provided: any message is fine.
                 return
@@ -140,7 +140,7 @@ class BaseTestCase(unittest.TestCase):
             else:
                 # Message provided, and it didn't match: fail!
                 raise self.failureException(
-                    u"Right exception, wrong message: got '%s' instead of '%s'" %
+                    "Right exception, wrong message: got '%s' instead of '%s'" %
                     (excMsg, msg))
         else:
             if hasattr(excClass, '__name__'):
@@ -158,27 +158,27 @@ class BaseTestCase(unittest.TestCase):
         """
         p = cssutils.CSSParser(raiseExceptions=raising)
         # parses with self.p and checks att of result
-        for test, expected in tests.items():
+        for test, expected in list(tests.items()):
             if debug:
-                print '"%s"' % test
+                print('"%s"' % test)
             s = p.parseString(test)
             if expected is None:
                 expected = test
-            self.assertEqual(expected, unicode(s.__getattribute__(att), 'utf-8'))
+            self.assertEqual(expected, str(s.__getattribute__(att), 'utf-8'))
 
     def do_raise_p(self, tests, debug=False, raising=True):
         # parses with self.p and expects raise
         p = cssutils.CSSParser(raiseExceptions=raising)
-        for test, expected in tests.items():
+        for test, expected in list(tests.items()):
             if debug:
-                print '"%s"' % test
+                print('"%s"' % test)
             self.assertRaises(expected, p.parseString, test)
 
     def do_equal_r(self, tests, att='cssText', debug=False):
         # sets attribute att of self.r and asserts Equal
-        for test, expected in tests.items():
+        for test, expected in list(tests.items()):
             if debug:
-                print '"%s"' % test
+                print('"%s"' % test)
             self.r.__setattr__(att, test)
             if expected is None:
                 expected = test
@@ -186,16 +186,16 @@ class BaseTestCase(unittest.TestCase):
 
     def do_raise_r(self, tests, att='_setCssText', debug=False):
         # sets self.r and asserts raise
-        for test, expected in tests.items():
+        for test, expected in list(tests.items()):
             if debug:
-                print '"%s"' % test
+                print('"%s"' % test)
             self.assertRaises(expected, self.r.__getattribute__(att), test)
 
     def do_raise_r_list(self, tests, err, att='_setCssText', debug=False):
         # sets self.r and asserts raise
         for test in tests:
             if debug:
-                print '"%s"' % test
+                print('"%s"' % test)
             self.assertRaises(err, self.r.__getattribute__(att), test)
 
 
@@ -220,7 +220,7 @@ class GenerateTests(type):
     """
     def __new__(cls, name, bases, attrs):
         new_attrs = {}
-        for aname, aobj in attrs.items():
+        for aname, aobj in list(attrs.items()):
             if not aname.startswith("gen_test_"):
                 new_attrs[aname] = aobj
                 continue
diff --git a/src/cssutils/tests/test_codec.py b/src/cssutils/tests/test_codec.py
index 991d0d2..93dd5eb 100644
--- a/src/cssutils/tests/test_codec.py
+++ b/src/cssutils/tests/test_codec.py
@@ -6,8 +6,8 @@ import sys
 
 PY2x = sys.version_info < (3,0)
 if PY2x:
-    import StringIO
-    iostream = StringIO.StringIO
+    import io
+    iostream = io.StringIO
 else:
     import io
     iostream = io.BytesIO 
@@ -54,83 +54,83 @@ class CodecTestCase(unittest.TestCase):
 
     def test_detectencoding_str(self):
         "codec.detectencoding_str()"
-        self.assertEqual(codec.detectencoding_str(u''.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\xef'.encode('latin1')), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\xef\x33'.encode("utf-8")), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u'\xc3\xaf3'.encode("utf-8")), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u'\xef\xbb'.encode("latin1")), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\xef\xbb\x33'.encode("utf-8")), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u'\xef\xbb\xbf'.encode("utf-8-sig")), ("utf-8-sig", True))
-        self.assertEqual(codec.detectencoding_str(u'\xff'.encode("latin1")), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\xff\x33'.encode("utf-8")), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u'\xff\xfe'.encode("latin1")), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x33'.encode("utf-16")), ("utf-16", True))
-        self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00'.encode("latin1")), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00\x33'.encode("utf-16")), ("utf-16", True))
+        self.assertEqual(codec.detectencoding_str(''.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('\xef'.encode('latin1')), (None, False))
+        self.assertEqual(codec.detectencoding_str('\xef\x33'.encode("utf-8")), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str('\xc3\xaf3'.encode("utf-8")), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str('\xef\xbb'.encode("latin1")), (None, False))
+        self.assertEqual(codec.detectencoding_str('\xef\xbb\x33'.encode("utf-8")), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str('\xef\xbb\xbf'.encode("utf-8-sig")), ("utf-8-sig", True))
+        self.assertEqual(codec.detectencoding_str('\xff'.encode("latin1")), (None, False))
+        self.assertEqual(codec.detectencoding_str('\xff\x33'.encode("utf-8")), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str('\xff\xfe'.encode("latin1")), (None, False))
+        self.assertEqual(codec.detectencoding_str('\xff\xfe\x33'.encode("utf-16")), ("utf-16", True))
+        self.assertEqual(codec.detectencoding_str('\xff\xfe\x00'.encode("latin1")), (None, False))
+        self.assertEqual(codec.detectencoding_str('\xff\xfe\x00\x33'.encode("utf-16")), ("utf-16", True))
         if haveutf32:
-            self.assertEqual(codec.detectencoding_str(u'\xff\xfe\x00\x00'.encode("utf-32")), ("utf-32", True))
-        self.assertEqual(codec.detectencoding_str(u'\x00'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\x00\x33'.encode()), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u'\x00\x00'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\x00\x00\x33'.encode()), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u'\x00\x00\xfe'.encode('latin1')), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'\x00\x00\x00\x33'.encode()), ("utf-8", False))
+            self.assertEqual(codec.detectencoding_str('\xff\xfe\x00\x00'.encode("utf-32")), ("utf-32", True))
+        self.assertEqual(codec.detectencoding_str('\x00'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('\x00\x33'.encode()), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str('\x00\x00'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('\x00\x00\x33'.encode()), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str('\x00\x00\xfe'.encode('latin1')), (None, False))
+        self.assertEqual(codec.detectencoding_str('\x00\x00\x00\x33'.encode()), ("utf-8", False))
         if haveutf32:
-            self.assertEqual(codec.detectencoding_str(u'\x00\x00\x00@'.encode()), ("utf-32-be", False))
-            self.assertEqual(codec.detectencoding_str(u'\x00\x00\xfe\xff'.encode('utf-32')), ("utf-32", True))
-        self.assertEqual(codec.detectencoding_str(u'@'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@\x33'.encode()), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u'@\x00'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@\x00\x33'.encode()), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u'@\x00\x00'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@\x00\x00\x33'.encode()), ("utf-8", False))
+            self.assertEqual(codec.detectencoding_str('\x00\x00\x00@'.encode()), ("utf-32-be", False))
+            self.assertEqual(codec.detectencoding_str('\x00\x00\xfe\xff'.encode('utf-32')), ("utf-32", True))
+        self.assertEqual(codec.detectencoding_str('@'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@\x33'.encode()), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str('@\x00'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@\x00\x33'.encode()), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str('@\x00\x00'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@\x00\x00\x33'.encode()), ("utf-8", False))
         if haveutf32:
-            self.assertEqual(codec.detectencoding_str(u'@\x00\x00\x00'.encode()), ("utf-32-le", False))
-        self.assertEqual(codec.detectencoding_str(u'@c'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@ch'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@cha'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@char'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@chars'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@charse'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@charset'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@charset '.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@charset "'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@charset "x'.encode()), (None, False))
-        self.assertEqual(codec.detectencoding_str(u'@charset ""'.encode()), ("", True))
-        self.assertEqual(codec.detectencoding_str(u'@charset "x"'.encode()), ("x", True))
-        self.assertEqual(codec.detectencoding_str(u"@".encode(), False), (None, False))
-        self.assertEqual(codec.detectencoding_str(u"@".encode(), True), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_str(u"@c".encode(), False), (None, False))
-        self.assertEqual(codec.detectencoding_str(u"@c".encode(), True), ("utf-8", False))
+            self.assertEqual(codec.detectencoding_str('@\x00\x00\x00'.encode()), ("utf-32-le", False))
+        self.assertEqual(codec.detectencoding_str('@c'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@ch'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@cha'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@char'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@chars'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@charse'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@charset'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@charset '.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@charset "'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@charset "x'.encode()), (None, False))
+        self.assertEqual(codec.detectencoding_str('@charset ""'.encode()), ("", True))
+        self.assertEqual(codec.detectencoding_str('@charset "x"'.encode()), ("x", True))
+        self.assertEqual(codec.detectencoding_str("@".encode(), False), (None, False))
+        self.assertEqual(codec.detectencoding_str("@".encode(), True), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_str("@c".encode(), False), (None, False))
+        self.assertEqual(codec.detectencoding_str("@c".encode(), True), ("utf-8", False))
 
     def test_detectencoding_unicode(self):
         "codec.detectencoding_unicode()"
         # Unicode version (only parses the header)
-        self.assertEqual(codec.detectencoding_unicode(u'@charset "x'), (None, False))
-        self.assertEqual(codec.detectencoding_unicode(u'a {}'), ("utf-8", False))
-        self.assertEqual(codec.detectencoding_unicode(u'@charset "x', True), (None, False))
-        self.assertEqual(codec.detectencoding_unicode(u'@charset "x"'), ("x", True))
+        self.assertEqual(codec.detectencoding_unicode('@charset "x'), (None, False))
+        self.assertEqual(codec.detectencoding_unicode('a {}'), ("utf-8", False))
+        self.assertEqual(codec.detectencoding_unicode('@charset "x', True), (None, False))
+        self.assertEqual(codec.detectencoding_unicode('@charset "x"'), ("x", True))
 
     def test_fixencoding(self):
         "codec._fixencoding()"
-        s = u'@charset "'
-        self.assertTrue(codec._fixencoding(s, u"utf-8") is None)
+        s = '@charset "'
+        self.assertTrue(codec._fixencoding(s, "utf-8") is None)
 
-        s = u'@charset "x'
-        self.assertTrue(codec._fixencoding(s, u"utf-8") is None)
+        s = '@charset "x'
+        self.assertTrue(codec._fixencoding(s, "utf-8") is None)
 
-        s = u'@charset "x'
-        self.assertEqual(codec._fixencoding(s, u"utf-8", True), s)
+        s = '@charset "x'
+        self.assertEqual(codec._fixencoding(s, "utf-8", True), s)
 
-        s = u'@charset x'
-        self.assertEqual(codec._fixencoding(s, u"utf-8"), s)
+        s = '@charset x'
+        self.assertEqual(codec._fixencoding(s, "utf-8"), s)
 
-        s = u'@charset "x"'
-        self.assertEqual(codec._fixencoding(s, u"utf-8"), s.replace('"x"', '"utf-8"'))
+        s = '@charset "x"'
+        self.assertEqual(codec._fixencoding(s, "utf-8"), s.replace('"x"', '"utf-8"'))
 
     def test_decoder(self):
         "codecs.decoder"
-        def checkauto(encoding, input=u'@charset "x";g\xfcrk\u20ac{}'):
+        def checkauto(encoding, input='@charset "x";g\xfcrk\u20ac{}'):
             outputencoding = encoding
             if outputencoding == "utf-8-sig":
                 outputencoding = "utf-8"
@@ -179,7 +179,7 @@ class CodecTestCase(unittest.TestCase):
             checkauto("utf-32-le")
             checkauto("utf-32-be")
 
-        def checkdecl(encoding, input=u'@charset "%s";g\xfcrk{}'):
+        def checkdecl(encoding, input='@charset "%s";g\xfcrk{}'):
             # Check stateless decoder with encoding autodetection
             d = codecs.getdecoder("css")
             input = input % encoding
@@ -220,16 +220,16 @@ class CodecTestCase(unittest.TestCase):
 
         # Use correct declaration
         checkdecl("utf-8")
-        checkdecl("iso-8859-1", u'@charset "%s";g\xfcrk')
+        checkdecl("iso-8859-1", '@charset "%s";g\xfcrk')
         checkdecl("iso-8859-15")
         checkdecl("cp1252")
 
         # No recursion
-        self.assertRaises(ValueError, u'@charset "css";div{}'.encode().decode, "css")
+        self.assertRaises(ValueError, '@charset "css";div{}'.encode().decode, "css")
 
     def test_encoder(self):
         "codec.encoder"
-        def check(encoding, input=u'@charset "x";g\xfcrk\u20ac{}'):
+        def check(encoding, input='@charset "x";g\xfcrk\u20ac{}'):
             outputencoding = encoding
             if outputencoding == "utf-8-sig":
                 outputencoding = "utf-8"
@@ -276,12 +276,12 @@ class CodecTestCase(unittest.TestCase):
             check("utf-32-le")
             check("utf-32-be")
         check("utf-8")
-        check("iso-8859-1", u'@charset "x";g\xfcrk{}')
+        check("iso-8859-1", '@charset "x";g\xfcrk{}')
         check("iso-8859-15")
         check("cp1252")
 
         # No recursion
-        self.assertRaises(ValueError, u'@charset "css";div{}'.encode, "css")
+        self.assertRaises(ValueError, '@charset "css";div{}'.encode, "css")
 
     def test_decode_force(self):
         "codec.decode (force)"
@@ -317,23 +317,23 @@ class CodecTestCase(unittest.TestCase):
 #            output = u'@charset "utf-8"; \xff'
 #            self.assertEqual(d(input, encoding="iso-8859-1", force=False), output)
 
-            input = u'@charset "utf-8"; \xff'.encode('utf-8')
-            output = u'@charset "utf-8"; \xff'
+            input = '@charset "utf-8"; \xff'.encode('utf-8')
+            output = '@charset "utf-8"; \xff'
             self.assertEqual(d(input), output)
 
             #input = b'@charset "utf-8"; \xc3\xbf'
-            input = u'@charset "utf-8"; \xff'.encode('utf-8')
-            output = u'@charset "iso-8859-1"; \xc3\xbf'
+            input = '@charset "utf-8"; \xff'.encode('utf-8')
+            output = '@charset "iso-8859-1"; \xc3\xbf'
             self.assertEqual(d(input, encoding="iso-8859-1", force=True), output)
 
             #input = b'\xc3\xbf'
-            input = u'\xff'.encode('utf-8')
-            output = u'\xc3\xbf'
+            input = '\xff'.encode('utf-8')
+            output = '\xc3\xbf'
             self.assertEqual(d(input, encoding="iso-8859-1", force=True), output)
 
             #input = b'@charset "utf-8"; \xc3\xbf'
-            input = u'@charset "utf-8"; \xff'.encode('utf-8')
-            output = u'@charset "utf-8"; \xff'
+            input = '@charset "utf-8"; \xff'.encode('utf-8')
+            output = '@charset "utf-8"; \xff'
             self.assertEqual(d(input, encoding="iso-8859-1", force=False), output)
 
 
diff --git a/src/cssutils/tests/test_csscharsetrule.py b/src/cssutils/tests/test_csscharsetrule.py
index 67a907e..362db3f 100644
--- a/src/cssutils/tests/test_csscharsetrule.py
+++ b/src/cssutils/tests/test_csscharsetrule.py
@@ -2,7 +2,7 @@
 
 import re
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils.css
 
 class CSSCharsetRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -18,50 +18,50 @@ class CSSCharsetRuleTestCase(test_cssrule.CSSRuleTestCase):
         "CSSCharsetRule.__init__()"      
         super(CSSCharsetRuleTestCase, self).test_init()
         self.assertEqual(None, self.r.encoding)
-        self.assertEqual(u'', self.r.cssText)
+        self.assertEqual('', self.r.cssText)
         
-        self.assertRaises(xml.dom.InvalidModificationErr, self.r._setCssText, u'xxx')
+        self.assertRaises(xml.dom.InvalidModificationErr, self.r._setCssText, 'xxx')
 
     def test_InvalidModificationErr(self):
         "CSSCharsetRule InvalidModificationErr"
-        self._test_InvalidModificationErr(u'@charset')
+        self._test_InvalidModificationErr('@charset')
 
     def test_init_encoding(self):
         "CSSCharsetRule.__init__(encoding)"
-        for enc in (None, u'UTF-8', u'utf-8', u'iso-8859-1', u'ascii'):
+        for enc in (None, 'UTF-8', 'utf-8', 'iso-8859-1', 'ascii'):
             r = cssutils.css.CSSCharsetRule(enc)
             if enc is None:
                 self.assertEqual(None, r.encoding)
-                self.assertEqual(u'', r.cssText)
+                self.assertEqual('', r.cssText)
             else:
                 self.assertEqual(enc.lower(), r.encoding)
                 self.assertEqual(
-                    u'@charset "%s";' % enc.lower(), r.cssText)
+                    '@charset "%s";' % enc.lower(), r.cssText)
 
         for enc in (' ascii ', ' ascii', 'ascii '):
             self.assertRaisesEx(xml.dom.SyntaxErr,
                     cssutils.css.CSSCharsetRule, enc,
                     exc_pattern=re.compile("Syntax Error"))
 
-        for enc in (u'unknown', ):
+        for enc in ('unknown', ):
             self.assertRaisesEx(xml.dom.SyntaxErr,
                     cssutils.css.CSSCharsetRule, enc,
                     exc_pattern=re.compile("Unknown \(Python\) encoding"))
 
     def test_encoding(self):
         "CSSCharsetRule.encoding"
-        for enc in (u'UTF-8', u'utf-8', u'iso-8859-1', u'ascii'):
+        for enc in ('UTF-8', 'utf-8', 'iso-8859-1', 'ascii'):
             self.r.encoding = enc
             self.assertEqual(enc.lower(), self.r.encoding)
             self.assertEqual(
-                u'@charset "%s";' % enc.lower(), self.r.cssText)
+                '@charset "%s";' % enc.lower(), self.r.cssText)
 
         for enc in (None,' ascii ', ' ascii', 'ascii '):
             self.assertRaisesEx(xml.dom.SyntaxErr,
                     self.r.__setattr__, 'encoding', enc,
                     exc_pattern=re.compile("Syntax Error"))
 
-        for enc in (u'unknown', ):
+        for enc in ('unknown', ):
             self.assertRaisesEx(xml.dom.SyntaxErr,
                     self.r.__setattr__, 'encoding', enc,
                     exc_pattern=re.compile("Unknown \(Python\) encoding"))
@@ -73,31 +73,31 @@ class CSSCharsetRuleTestCase(test_cssrule.CSSRuleTestCase):
         using parse MUST use ``@charset "ENCODING";``
         """
         tests = {
-            u'@charset "utf-8";': None,
-            u"@charset 'utf-8';": u'@charset "utf-8";',
+            '@charset "utf-8";': None,
+            "@charset 'utf-8';": '@charset "utf-8";',
             }
         self.do_equal_r(tests)
         self.do_equal_p(tests) # also parse
 
         tests = {
             # token is "@charset " with space!
-            u'@charset;"': xml.dom.InvalidModificationErr,
-            u'@CHARSET "UTF-8";': xml.dom.InvalidModificationErr,
-            u'@charset "";': xml.dom.SyntaxErr,
-            u'''@charset /*1*/"utf-8"/*2*/;''': xml.dom.SyntaxErr,
-            u'''@charset /*1*/"utf-8";''': xml.dom.SyntaxErr,
-            u'''@charset "utf-8"/*2*/;''': xml.dom.SyntaxErr,
-            u'@charset { utf-8 }': xml.dom.SyntaxErr,
-            u'@charset "utf-8"': xml.dom.SyntaxErr,
-            u'@charset a;': xml.dom.SyntaxErr,
-            u'@charset /**/;': xml.dom.SyntaxErr,
+            '@charset;"': xml.dom.InvalidModificationErr,
+            '@CHARSET "UTF-8";': xml.dom.InvalidModificationErr,
+            '@charset "";': xml.dom.SyntaxErr,
+            '''@charset /*1*/"utf-8"/*2*/;''': xml.dom.SyntaxErr,
+            '''@charset /*1*/"utf-8";''': xml.dom.SyntaxErr,
+            '''@charset "utf-8"/*2*/;''': xml.dom.SyntaxErr,
+            '@charset { utf-8 }': xml.dom.SyntaxErr,
+            '@charset "utf-8"': xml.dom.SyntaxErr,
+            '@charset a;': xml.dom.SyntaxErr,
+            '@charset /**/;': xml.dom.SyntaxErr,
             # trailing content
-            u'@charset "utf-8";s': xml.dom.SyntaxErr,
-            u'@charset "utf-8";/**/': xml.dom.SyntaxErr,
-            u'@charset "utf-8"; ': xml.dom.SyntaxErr,
+            '@charset "utf-8";s': xml.dom.SyntaxErr,
+            '@charset "utf-8";/**/': xml.dom.SyntaxErr,
+            '@charset "utf-8"; ': xml.dom.SyntaxErr,
             
             # comments do not work in this rule!
-            u'@charset "utf-8"/*1*//*2*/;': xml.dom.SyntaxErr
+            '@charset "utf-8"/*1*//*2*/;': xml.dom.SyntaxErr
             }
         self.do_raise_r(tests)
 
diff --git a/src/cssutils/tests/test_csscomment.py b/src/cssutils/tests/test_csscomment.py
index abc2274..85480d6 100644
--- a/src/cssutils/tests/test_csscomment.py
+++ b/src/cssutils/tests/test_csscomment.py
@@ -2,7 +2,7 @@
 """Testcases for cssutils.css.CSSComment"""
 
 import xml
-import test_cssrule
+from . import test_cssrule
 import cssutils.css
 
 class CSSCommentTestCase(test_cssrule.CSSRuleTestCase):
@@ -21,32 +21,32 @@ class CSSCommentTestCase(test_cssrule.CSSRuleTestCase):
     def test_csstext(self):
         "CSSComment.cssText"
         tests = {
-            u'/*öäüß€ÖÄÜ*/': u'/*\xf6\xe4\xfc\xdf\u20ac\xd6\xc4\xdc*/',
-            u'/*x*/': None,
-            u'/* x */': None,
-            u'/*\t12\n*/': None,
-            u'/* /* */': None,
-            u'/* \\*/': None,
-            u'/*"*/': None,
-            u'''/*"
+            '/*öäüß€ÖÄÜ*/': '/*\xf6\xe4\xfc\xdf\u20ac\xd6\xc4\xdc*/',
+            '/*x*/': None,
+            '/* x */': None,
+            '/*\t12\n*/': None,
+            '/* /* */': None,
+            '/* \\*/': None,
+            '/*"*/': None,
+            '''/*"
             */''': None,
-            u'/** / ** //*/': None
+            '/** / ** //*/': None
             }
         self.do_equal_r(tests) # set cssText
         tests.update({
-            u'/*x': u'/*x*/',
-            u'\n /*': u'/**/',
+            '/*x': '/*x*/',
+            '\n /*': '/**/',
             })
         self.do_equal_p(tests) # parse
 
         tests = {
-            u'/* */ ': xml.dom.InvalidModificationErr,
-            u'/* *//**/': xml.dom.InvalidModificationErr,
-            u'/* */1': xml.dom.InvalidModificationErr,
-            u'/* */ */': xml.dom.InvalidModificationErr,
-            u'  */ /* ': xml.dom.InvalidModificationErr,
-            u'*/': xml.dom.InvalidModificationErr,
-            u'@x /* x */': xml.dom.InvalidModificationErr
+            '/* */ ': xml.dom.InvalidModificationErr,
+            '/* *//**/': xml.dom.InvalidModificationErr,
+            '/* */1': xml.dom.InvalidModificationErr,
+            '/* */ */': xml.dom.InvalidModificationErr,
+            '  */ /* ': xml.dom.InvalidModificationErr,
+            '*/': xml.dom.InvalidModificationErr,
+            '@x /* x */': xml.dom.InvalidModificationErr
             }
         self.do_raise_r(tests) # set cssText
         # no raising of error possible?
@@ -54,7 +54,7 @@ class CSSCommentTestCase(test_cssrule.CSSRuleTestCase):
 
     def test_InvalidModificationErr(self):
         "CSSComment.cssText InvalidModificationErr"
-        self._test_InvalidModificationErr(u'/* comment */')
+        self._test_InvalidModificationErr('/* comment */')
 
     def test_reprANDstr(self):
         "CSSComment.__repr__(), .__str__()"
diff --git a/src/cssutils/tests/test_cssfontfacerule.py b/src/cssutils/tests/test_cssfontfacerule.py
index a65924e..7161f0f 100644
--- a/src/cssutils/tests/test_cssfontfacerule.py
+++ b/src/cssutils/tests/test_cssfontfacerule.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.CSSFontFaceRule"""
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
 class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -22,7 +22,7 @@ class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertEqual(r, r.style.parentRule)
 
         # until any properties
-        self.assertEqual(u'', r.cssText)
+        self.assertEqual('', r.cssText)
 
         # only possible to set @... similar name
         self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x')
@@ -54,7 +54,7 @@ class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
     def test_cssText(self):
         "CSSFontFaceRule.cssText"
         tests = {
-            u'''@font-face {
+            '''@font-face {
     font-family: x;
     src: url(../fonts/LateefRegAAT.ttf) format("truetype-aat"), url(../fonts/LateefRegOT.ttf) format("opentype");
     font-style: italic;
@@ -62,30 +62,30 @@ class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
     font-stretch: condensed;
     unicode-range: u+1-ff, u+111
     }''': None,
-            u'@font-face{font-family: x;}': u'@font-face {\n    font-family: x\n    }',
-            u'@font-face  {  font-family: x;  }': u'@font-face {\n    font-family: x\n    }',
-            u'@f\\ont\\-face{font-family : x;}': u'@font-face {\n    font-family: x\n    }',
+            '@font-face{font-family: x;}': '@font-face {\n    font-family: x\n    }',
+            '@font-face  {  font-family: x;  }': '@font-face {\n    font-family: x\n    }',
+            '@f\\ont\\-face{font-family : x;}': '@font-face {\n    font-family: x\n    }',
             # comments
-            u'@font-face/*1*//*2*/{font-family: x;}':
-                u'@font-face /*1*/ /*2*/ {\n    font-family: x\n    }',
+            '@font-face/*1*//*2*/{font-family: x;}':
+                '@font-face /*1*/ /*2*/ {\n    font-family: x\n    }',
             # WS
-            u'@font-face\n\t\f {\n\t\f font-family:x;\n\t\f }': 
-                u'@font-face {\n    font-family: x\n    }',
+            '@font-face\n\t\f {\n\t\f font-family:x;\n\t\f }':
+                '@font-face {\n    font-family: x\n    }',
             }
         self.do_equal_r(tests)
         self.do_equal_p(tests)
 
         tests = {
-            u'@font-face;': xml.dom.SyntaxErr,
-            u'@font-face }': xml.dom.SyntaxErr,
+            '@font-face;': xml.dom.SyntaxErr,
+            '@font-face }': xml.dom.SyntaxErr,
             }
         self.do_raise_p(tests) # parse
         tests.update({
-            u'@font-face {': xml.dom.SyntaxErr, # no }
+            '@font-face {': xml.dom.SyntaxErr, # no }
             # trailing
-            u'@font-face {}1': xml.dom.SyntaxErr, 
-            u'@font-face {}/**/': xml.dom.SyntaxErr, 
-            u'@font-face {} ': xml.dom.SyntaxErr, 
+            '@font-face {}1': xml.dom.SyntaxErr,
+            '@font-face {}/**/': xml.dom.SyntaxErr,
+            '@font-face {} ': xml.dom.SyntaxErr,
             })
         self.do_raise_r(tests) # set cssText
 
@@ -94,68 +94,68 @@ class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
         r = cssutils.css.CSSFontFaceRule()
         s1 = r.style
         self.assertEqual(r, s1.parentRule)
-        self.assertEqual(u'', s1.cssText)
+        self.assertEqual('', s1.cssText)
         
         # set rule.cssText
         r.cssText = '@font-face { font-family: x1 }'
         self.assertNotEqual(r.style, s1)
         self.assertEqual(r, r.style.parentRule)
-        self.assertEqual(r.cssText, u'@font-face {\n    font-family: x1\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: x1')
-        self.assertEqual(s1.cssText, u'')
+        self.assertEqual(r.cssText, '@font-face {\n    font-family: x1\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: x1')
+        self.assertEqual(s1.cssText, '')
         s2 = r.style
         
         # set invalid rule.cssText
         try: 
             r.cssText = '@font-face { $ }'
-        except xml.dom.SyntaxErr, e:
+        except xml.dom.SyntaxErr as e:
             pass
         self.assertEqual(r.style, s2)
         self.assertEqual(r, s2.parentRule)
-        self.assertEqual(r.cssText, u'@font-face {\n    font-family: x1\n    }')
-        self.assertEqual(s2.cssText, u'font-family: x1')
-        self.assertEqual(r.style.cssText, u'font-family: x1')
+        self.assertEqual(r.cssText, '@font-face {\n    font-family: x1\n    }')
+        self.assertEqual(s2.cssText, 'font-family: x1')
+        self.assertEqual(r.style.cssText, 'font-family: x1')
 
         # set rule.style.cssText
         r.style.cssText = 'font-family: x2'
         self.assertEqual(r.style, s2)
         self.assertEqual(r, s2.parentRule)
-        self.assertEqual(r.cssText, u'@font-face {\n    font-family: x2\n    }')
-        self.assertEqual(s2.cssText, u'font-family: x2')
-        self.assertEqual(r.style.cssText, u'font-family: x2')
+        self.assertEqual(r.cssText, '@font-face {\n    font-family: x2\n    }')
+        self.assertEqual(s2.cssText, 'font-family: x2')
+        self.assertEqual(r.style.cssText, 'font-family: x2')
 
         # set new style object s2
         sn = cssutils.css.CSSStyleDeclaration('font-family: y1')
         r.style = sn
         self.assertEqual(r.style, sn)
         self.assertEqual(r, sn.parentRule)
-        self.assertEqual(r.cssText, u'@font-face {\n    font-family: y1\n    }')
-        self.assertEqual(sn.cssText, u'font-family: y1')
-        self.assertEqual(r.style.cssText, u'font-family: y1')
-        self.assertEqual(s2.cssText, u'font-family: x2') # old
+        self.assertEqual(r.cssText, '@font-face {\n    font-family: y1\n    }')
+        self.assertEqual(sn.cssText, 'font-family: y1')
+        self.assertEqual(r.style.cssText, 'font-family: y1')
+        self.assertEqual(s2.cssText, 'font-family: x2') # old
 
         # set s2.cssText
         sn.cssText = 'font-family: y2'
         self.assertEqual(r.style, sn)
-        self.assertEqual(r.cssText, u'@font-face {\n    font-family: y2\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: y2')
-        self.assertEqual(s2.cssText, u'font-family: x2') # old
+        self.assertEqual(r.cssText, '@font-face {\n    font-family: y2\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: y2')
+        self.assertEqual(s2.cssText, 'font-family: x2') # old
         
         # set invalid s2.cssText
         try: 
             sn.cssText = '$'
-        except xml.dom.SyntaxErr, e:
+        except xml.dom.SyntaxErr as e:
             pass
         self.assertEqual(r.style, sn)
-        self.assertEqual(r.style.cssText, u'font-family: y2')
-        self.assertEqual(r.cssText, u'@font-face {\n    font-family: y2\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: y2')
+        self.assertEqual(r.cssText, '@font-face {\n    font-family: y2\n    }')
         
         # set r.style with text
         r.style = 'font-family: z'
         self.assertNotEqual(r.style, sn)
-        self.assertEqual(r.cssText, u'@font-face {\n    font-family: z\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: z')
-        self.assertEqual(sn.cssText, u'font-family: y2')
+        self.assertEqual(r.cssText, '@font-face {\n    font-family: z\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: z')
+        self.assertEqual(sn.cssText, 'font-family: y2')
 
     def test_properties(self):
         "CSSFontFaceRule.style properties"
@@ -163,7 +163,7 @@ class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
         r.style.cssText = '''
         src: url(x)
         '''
-        exp = u'''@font-face {
+        exp = '''@font-face {
     src: url(x)
     }'''
         self.assertEqual(exp, r.cssText)
@@ -178,7 +178,7 @@ class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
 #                            ('"x", "y"', False)
                             ]
             }
-        for n, t in tests.items():
+        for n, t in list(tests.items()):
             for (v, valid) in t:
                 r = cssutils.css.CSSFontFaceRule()
                 r.style[n] = v
@@ -188,20 +188,20 @@ class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
     def test_incomplete(self):
         "CSSFontFaceRule (incomplete)"
         tests = {
-            u'@font-face{':
-                u'', # no } and no content
-            u'@font-face { ':
-                u'', # no } and no content
-            u'@font-face { font-family: x':
-                u'@font-face {\n    font-family: x\n    }', # no }
+            '@font-face{':
+                '', # no } and no content
+            '@font-face { ':
+                '', # no } and no content
+            '@font-face { font-family: x':
+                '@font-face {\n    font-family: x\n    }', # no }
         }
         self.do_equal_p(tests) # parse
 
     def test_InvalidModificationErr(self):
         "CSSFontFaceRule.cssText InvalidModificationErr"
-        self._test_InvalidModificationErr(u'@font-face')
+        self._test_InvalidModificationErr('@font-face')
         tests = {
-            u'@font-fac {}': xml.dom.InvalidModificationErr,
+            '@font-fac {}': xml.dom.InvalidModificationErr,
             }
         self.do_raise_r(tests)
 
@@ -219,7 +219,7 @@ class CSSFontFaceRuleTestCase(test_cssrule.CSSRuleTestCase):
                     N + 'font-style: inherit',
                     N + 'invalid: 1')
             }
-        for valid, testlist in tests.items():
+        for valid, testlist in list(tests.items()):
             for test in testlist:
                 r.style.cssText = test
                 self.assertEqual(valid, r.valid)
diff --git a/src/cssutils/tests/test_cssimportrule.py b/src/cssutils/tests/test_cssimportrule.py
index baa55d6..80677cd 100644
--- a/src/cssutils/tests/test_cssimportrule.py
+++ b/src/cssutils/tests/test_cssimportrule.py
@@ -1,10 +1,10 @@
 """Testcases for cssutils.css.CSSImportRule"""
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
-import basetest
+from . import basetest
 
 class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
 
@@ -23,20 +23,20 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertEqual(None, self.r.href)
         self.assertEqual(None, self.r.hreftype)
         self.assertEqual(False, self.r.hrefFound)
-        self.assertEqual(u'all', self.r.media.mediaText)
+        self.assertEqual('all', self.r.media.mediaText)
         self.assertEqual(
             cssutils.stylesheets.MediaList, type(self.r.media))
         self.assertEqual(None, self.r.name)
         self.assertEqual(cssutils.css.CSSStyleSheet, type(self.r.styleSheet))
         self.assertEqual(0, self.r.styleSheet.cssRules.length)
-        self.assertEqual(u'', self.r.cssText)
+        self.assertEqual('', self.r.cssText)
 
         # all
         r = cssutils.css.CSSImportRule(href='href', mediaText='tv', name='name')
-        self.assertEqual(u'@import url(href) tv "name";', r.cssText)
+        self.assertEqual('@import url(href) tv "name";', r.cssText)
         self.assertEqual("href", r.href)
         self.assertEqual(None, r.hreftype)
-        self.assertEqual(u'tv', r.media.mediaText)
+        self.assertEqual('tv', r.media.mediaText)
         self.assertEqual(
             cssutils.stylesheets.MediaList, type(r.media))
         self.assertEqual('name', r.name)
@@ -46,37 +46,37 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertEqual(0, self.r.styleSheet.cssRules.length)
         
         # href
-        r = cssutils.css.CSSImportRule(u'x')
-        self.assertEqual(u'@import url(x);', r.cssText)
+        r = cssutils.css.CSSImportRule('x')
+        self.assertEqual('@import url(x);', r.cssText)
         self.assertEqual('x', r.href)
         self.assertEqual(None, r.hreftype)
 
         # href + mediaText
-        r = cssutils.css.CSSImportRule(u'x', u'print')
-        self.assertEqual(u'@import url(x) print;', r.cssText)
+        r = cssutils.css.CSSImportRule('x', 'print')
+        self.assertEqual('@import url(x) print;', r.cssText)
         self.assertEqual('x', r.href)
         self.assertEqual('print', r.media.mediaText)
 
         # href + name
-        r = cssutils.css.CSSImportRule(u'x', name=u'n')
-        self.assertEqual(u'@import url(x) "n";', r.cssText)
+        r = cssutils.css.CSSImportRule('x', name='n')
+        self.assertEqual('@import url(x) "n";', r.cssText)
         self.assertEqual('x', r.href)
         self.assertEqual('n', r.name)
 
         # href + mediaText + name
-        r = cssutils.css.CSSImportRule(u'x', u'print', 'n')
-        self.assertEqual(u'@import url(x) print "n";', r.cssText)
+        r = cssutils.css.CSSImportRule('x', 'print', 'n')
+        self.assertEqual('@import url(x) print "n";', r.cssText)
         self.assertEqual('x', r.href)
         self.assertEqual('print', r.media.mediaText)
         self.assertEqual('n', r.name)
 
         # media +name only
-        self.r = cssutils.css.CSSImportRule(mediaText=u'print', name="n")
+        self.r = cssutils.css.CSSImportRule(mediaText='print', name="n")
         self.assertEqual(cssutils.stylesheets.MediaList,
                          type(self.r.media))
-        self.assertEqual(u'', self.r.cssText)
-        self.assertEqual(u'print', self.r.media.mediaText)
-        self.assertEqual(u'n', self.r.name)
+        self.assertEqual('', self.r.cssText)
+        self.assertEqual('print', self.r.media.mediaText)
+        self.assertEqual('n', self.r.name)
 
         # only possible to set @... similar name
         self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x')
@@ -85,100 +85,100 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
         "CSSImportRule.cssText"
         tests = {
             # href string
-            u'''@import "str";''': None,
-            u'''@import"str";''': u'''@import "str";''',
-            u'''@\\import "str";''': u'''@import "str";''',
-            u'''@IMPORT "str";''': u'''@import "str";''',
-            u'''@import 'str';''': u'''@import "str";''',
-            u'''@import 'str' ;''': u'''@import "str";''',
-            u'''@import "str";''': None,
-            u'''@import "str"  ;''': u'''@import "str";''',
-            ur'''@import "\""  ;''': ur'''@import "\"";''',
-            u'''@import '\\'';''': ur'''@import "'";''',
-            u'''@import '"';''': ur'''@import "\"";''',
+            '''@import "str";''': None,
+            '''@import"str";''': '''@import "str";''',
+            '''@\\import "str";''': '''@import "str";''',
+            '''@IMPORT "str";''': '''@import "str";''',
+            '''@import 'str';''': '''@import "str";''',
+            '''@import 'str' ;''': '''@import "str";''',
+            '''@import "str";''': None,
+            '''@import "str"  ;''': '''@import "str";''',
+            r'''@import "\""  ;''': r'''@import "\"";''',
+            '''@import '\\'';''': r'''@import "'";''',
+            '''@import '"';''': r'''@import "\"";''',
             # href url
-            u'''@import url(x.css);''': None,
+            '''@import url(x.css);''': None,
             # nospace
-            u'''@import url(")");''': u'''@import url(")");''',
-            u'''@import url("\\"");''': u'''@import url("\\"");''',
-            u'''@import url('\\'');''': u'''@import url("'");''',
+            '''@import url(")");''': '''@import url(")");''',
+            '''@import url("\\"");''': '''@import url("\\"");''',
+            '''@import url('\\'');''': '''@import url("'");''',
 
             # href + media
             # all is removed
-            u'''@import "str" all;''': u'''@import "str";''',
-            u'''@import "str" tv, print;''': None,
-            u'''@import"str"tv,print;''': u'''@import "str" tv, print;''',
-            u'''@import "str" tv, print, all;''': u'''@import "str";''',
-            u'''@import "str" handheld, all;''': u'''@import "str";''',
-            u'''@import "str" all, handheld;''': u'''@import "str";''',
-            u'''@import "str" not tv;''': None,
-            u'''@import "str" only tv;''': None,
-            u'''@import "str" only tv and (color: 2);''': None,
+            '''@import "str" all;''': '''@import "str";''',
+            '''@import "str" tv, print;''': None,
+            '''@import"str"tv,print;''': '''@import "str" tv, print;''',
+            '''@import "str" tv, print, all;''': '''@import "str";''',
+            '''@import "str" handheld, all;''': '''@import "str";''',
+            '''@import "str" all, handheld;''': '''@import "str";''',
+            '''@import "str" not tv;''': None,
+            '''@import "str" only tv;''': None,
+            '''@import "str" only tv and (color: 2);''': None,
 
             # href + name
-            u'''@import "str" "name";''': None,
-            u'''@import "str" 'name';''': u'''@import "str" "name";''',
-            u'''@import url(x) "name";''': None,
-            u'''@import "str" "\\"";''': None,
-            u'''@import "str" '\\'';''': u'''@import "str" "'";''',
+            '''@import "str" "name";''': None,
+            '''@import "str" 'name';''': '''@import "str" "name";''',
+            '''@import url(x) "name";''': None,
+            '''@import "str" "\\"";''': None,
+            '''@import "str" '\\'';''': '''@import "str" "'";''',
 
             # href + media + name
-            u'''@import"str"tv"name";''': u'''@import "str" tv "name";''',
-            u'''@import\t\r\f\n"str"\t\t\r\f\ntv\t\t\r\f\n"name"\t;''': 
-                u'''@import "str" tv "name";''',
+            '''@import"str"tv"name";''': '''@import "str" tv "name";''',
+            '''@import\t\r\f\n"str"\t\t\r\f\ntv\t\t\r\f\n"name"\t;''':
+                '''@import "str" tv "name";''',
 
             # comments
-            u'''@import /*1*/ "str" /*2*/;''': None,
-            u'@import/*1*//*2*/"str"/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': 
-                u'@import /*1*/ /*2*/ "str" /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;',
-            u'@import/*1*//*2*/url(u)/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': 
-                u'@import /*1*/ /*2*/ url(u) /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;',
-            u'@import/*1*//*2*/url("u")/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;': 
-                u'@import /*1*/ /*2*/ url(u) /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;',
+            '''@import /*1*/ "str" /*2*/;''': None,
+            '@import/*1*//*2*/"str"/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;':
+                '@import /*1*/ /*2*/ "str" /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;',
+            '@import/*1*//*2*/url(u)/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;':
+                '@import /*1*/ /*2*/ url(u) /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;',
+            '@import/*1*//*2*/url("u")/*3*//*4*/all/*5*//*6*/"name"/*7*//*8*/ ;':
+                '@import /*1*/ /*2*/ url(u) /*3*/ /*4*/ all /*5*/ /*6*/ "name" /*7*/ /*8*/;',
             # WS
-            u'@import\n\t\f "str"\n\t\f tv\n\t\f "name"\n\t\f ;': 
-                u'@import "str" tv "name";',
-            u'@import\n\t\f url(\n\t\f u\n\t\f )\n\t\f tv\n\t\f "name"\n\t\f ;': 
-                u'@import url(u) tv "name";',
-            u'@import\n\t\f url("u")\n\t\f tv\n\t\f "name"\n\t\f ;': 
-                u'@import url(u) tv "name";',
-            u'@import\n\t\f url(\n\t\f "u"\n\t\f )\n\t\f tv\n\t\f "name"\n\t\f ;': 
-                u'@import url(u) tv "name";',
+            '@import\n\t\f "str"\n\t\f tv\n\t\f "name"\n\t\f ;':
+                '@import "str" tv "name";',
+            '@import\n\t\f url(\n\t\f u\n\t\f )\n\t\f tv\n\t\f "name"\n\t\f ;':
+                '@import url(u) tv "name";',
+            '@import\n\t\f url("u")\n\t\f tv\n\t\f "name"\n\t\f ;':
+                '@import url(u) tv "name";',
+            '@import\n\t\f url(\n\t\f "u"\n\t\f )\n\t\f tv\n\t\f "name"\n\t\f ;':
+                '@import url(u) tv "name";',
             }
         self.do_equal_r(tests) # set cssText
         tests.update({
-            u'@import "x.css" tv': '@import "x.css" tv;',
-            u'@import "x.css"': '@import "x.css";', # no ;
-            u"@import 'x.css'": '@import "x.css";', # no ;
-            u'@import url(x.css)': '@import url(x.css);', # no ;
-            u'@import "x;': '@import "x;";', # no "!
+            '@import "x.css" tv': '@import "x.css" tv;',
+            '@import "x.css"': '@import "x.css";', # no ;
+            "@import 'x.css'": '@import "x.css";', # no ;
+            '@import url(x.css)': '@import url(x.css);', # no ;
+            '@import "x;': '@import "x;";', # no "!
             })
         self.do_equal_p(tests) # parse
 
         tests = {
-            u'''@import;''': xml.dom.SyntaxErr,
-            u'''@import all;''': xml.dom.SyntaxErr,
-            u'''@import all"name";''': xml.dom.SyntaxErr,
-            u'''@import;''': xml.dom.SyntaxErr,
-            u'''@import x";''': xml.dom.SyntaxErr,
-            u'''@import "str" ,all;''': xml.dom.SyntaxErr,
-            u'''@import "str" all,;''': xml.dom.SyntaxErr,
-            u'''@import "str" all tv;''': xml.dom.SyntaxErr,
-            u'''@import "str" "name" all;''': xml.dom.SyntaxErr,
+            '''@import;''': xml.dom.SyntaxErr,
+            '''@import all;''': xml.dom.SyntaxErr,
+            '''@import all"name";''': xml.dom.SyntaxErr,
+            '''@import;''': xml.dom.SyntaxErr,
+            '''@import x";''': xml.dom.SyntaxErr,
+            '''@import "str" ,all;''': xml.dom.SyntaxErr,
+            '''@import "str" all,;''': xml.dom.SyntaxErr,
+            '''@import "str" all tv;''': xml.dom.SyntaxErr,
+            '''@import "str" "name" all;''': xml.dom.SyntaxErr,
             }
         self.do_raise_p(tests) # parse
         tests.update({
-            u'@import "x.css"': xml.dom.SyntaxErr,
-            u"@import 'x.css'": xml.dom.SyntaxErr,
-            u'@import url(x.css)': xml.dom.SyntaxErr,
-            u'@import "x.css" tv': xml.dom.SyntaxErr,
-            u'@import "x;': xml.dom.SyntaxErr,
-            u'''@import url("x);''': xml.dom.SyntaxErr,
+            '@import "x.css"': xml.dom.SyntaxErr,
+            "@import 'x.css'": xml.dom.SyntaxErr,
+            '@import url(x.css)': xml.dom.SyntaxErr,
+            '@import "x.css" tv': xml.dom.SyntaxErr,
+            '@import "x;': xml.dom.SyntaxErr,
+            '''@import url("x);''': xml.dom.SyntaxErr,
             # trailing
-            u'''@import "x";"a"''': xml.dom.SyntaxErr,
+            '''@import "x";"a"''': xml.dom.SyntaxErr,
             # trailing S or COMMENT
-            u'''@import "x";/**/''': xml.dom.SyntaxErr,
-            u'''@import "x"; ''': xml.dom.SyntaxErr,
+            '''@import "x";/**/''': xml.dom.SyntaxErr,
+            '''@import "x"; ''': xml.dom.SyntaxErr,
             })
         self.do_raise_r(tests) # set cssText
 
@@ -187,53 +187,53 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
         # set
         self.r.href = 'x'
         self.assertEqual('x', self.r.href)
-        self.assertEqual(u'@import url(x);', self.r.cssText)
+        self.assertEqual('@import url(x);', self.r.cssText)
 
         # http
         self.r.href = 'http://www.example.com/x?css=z&v=1'
         self.assertEqual('http://www.example.com/x?css=z&v=1' , self.r.href)
-        self.assertEqual(u'@import url(http://www.example.com/x?css=z&v=1);',
+        self.assertEqual('@import url(http://www.example.com/x?css=z&v=1);',
                          self.r.cssText)
 
         # also if hreftype changed
         self.r.hreftype='string'
         self.assertEqual('http://www.example.com/x?css=z&v=1' , self.r.href)
-        self.assertEqual(u'@import "http://www.example.com/x?css=z&v=1";',
+        self.assertEqual('@import "http://www.example.com/x?css=z&v=1";',
                          self.r.cssText)
         
         # string escaping?
         self.r.href = '"'
-        self.assertEqual(u'@import "\\"";', self.r.cssText)
+        self.assertEqual('@import "\\"";', self.r.cssText)
         self.r.hreftype='url'
-        self.assertEqual(u'@import url("\\"");', self.r.cssText)
+        self.assertEqual('@import url("\\"");', self.r.cssText)
         
         # url escaping?
         self.r.href = ')'
-        self.assertEqual(u'@import url(")");', self.r.cssText)
+        self.assertEqual('@import url(")");', self.r.cssText)
 
         self.r.hreftype = 'NOT VALID' # using default
-        self.assertEqual(u'@import url(")");', self.r.cssText)
+        self.assertEqual('@import url(")");', self.r.cssText)
 
     def test_hrefFound(self):
         "CSSImportRule.hrefFound"
         def fetcher(url):
-            if url == u'http://example.com/yes': 
-                return None, u'/**/'
+            if url == 'http://example.com/yes':
+                return None, '/**/'
             else:
                 return None, None
             
         parser = cssutils.CSSParser(fetcher=fetcher)
-        sheet = parser.parseString(u'@import "http://example.com/yes" "name"')
+        sheet = parser.parseString('@import "http://example.com/yes" "name"')
         
         r = sheet.cssRules[0]
-        self.assertEqual(u'/**/'.encode(), r.styleSheet.cssText)
+        self.assertEqual('/**/'.encode(), r.styleSheet.cssText)
         self.assertEqual(True, r.hrefFound)
-        self.assertEqual(u'name', r.name)
+        self.assertEqual('name', r.name)
         
         r.cssText = '@import url(http://example.com/none) "name2";'
-        self.assertEqual(u''.encode(), r.styleSheet.cssText)
+        self.assertEqual(''.encode(), r.styleSheet.cssText)
         self.assertEqual(False, r.hrefFound)
-        self.assertEqual(u'name2', r.name)
+        self.assertEqual('name2', r.name)
 
         sheet.cssText = '@import url(http://example.com/none);'
         self.assertNotEqual(r, sheet.cssRules[0])
@@ -244,17 +244,17 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
 
         self.r.cssText = '@import /*1*/url(org) /*2*/;'
         self.assertEqual('uri', self.r.hreftype)
-        self.assertEqual(u'@import /*1*/ url(org) /*2*/;', self.r.cssText)
+        self.assertEqual('@import /*1*/ url(org) /*2*/;', self.r.cssText)
 
         self.r.cssText = '@import /*1*/"org" /*2*/;'
         self.assertEqual('string', self.r.hreftype)
-        self.assertEqual(u'@import /*1*/ "org" /*2*/;', self.r.cssText)
+        self.assertEqual('@import /*1*/ "org" /*2*/;', self.r.cssText)
 
         self.r.href = 'new'
-        self.assertEqual(u'@import /*1*/ "new" /*2*/;', self.r.cssText)
+        self.assertEqual('@import /*1*/ "new" /*2*/;', self.r.cssText)
 
         self.r.hreftype='uri'
-        self.assertEqual(u'@import /*1*/ url(new) /*2*/;', self.r.cssText)
+        self.assertEqual('@import /*1*/ url(new) /*2*/;', self.r.cssText)
 
     def test_media(self):
         "CSSImportRule.media"
@@ -265,24 +265,24 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
 
         # but not static
         self.r.media.mediaText = 'print'
-        self.assertEqual(u'@import url(x) print;', self.r.cssText)
+        self.assertEqual('@import url(x) print;', self.r.cssText)
         self.r.media.appendMedium('tv')
-        self.assertEqual(u'@import url(x) print, tv;', self.r.cssText)
+        self.assertEqual('@import url(x) print, tv;', self.r.cssText)
 
         # for generated rule
         r = cssutils.css.CSSImportRule(href='x')
         self.assertRaisesMsg(xml.dom.InvalidModificationErr, 
                              basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), 
                              r.media.appendMedium, 'tv')
-        self.assertEqual(u'@import url(x);', r.cssText)
+        self.assertEqual('@import url(x);', r.cssText)
         self.assertRaisesMsg(xml.dom.InvalidModificationErr, 
                              basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), 
                              r.media.appendMedium, 'tv')
-        self.assertEqual(u'@import url(x);', r.cssText)
+        self.assertEqual('@import url(x);', r.cssText)
         r.media.mediaText = 'tv' 
-        self.assertEqual(u'@import url(x) tv;', r.cssText)
+        self.assertEqual('@import url(x) tv;', r.cssText)
         r.media.appendMedium('print') # all + tv = all!
-        self.assertEqual(u'@import url(x) tv, print;', r.cssText)
+        self.assertEqual('@import url(x) tv, print;', r.cssText)
 
         # for parsed rule without initial media
         s = cssutils.parseString('@import url(x);')
@@ -291,41 +291,41 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertRaisesMsg(xml.dom.InvalidModificationErr, 
                              basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), 
                              r.media.appendMedium, 'tv')        
-        self.assertEqual(u'@import url(x);', r.cssText)
+        self.assertEqual('@import url(x);', r.cssText)
         self.assertRaisesMsg(xml.dom.InvalidModificationErr, 
                              basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), 
                              r.media.appendMedium, 'tv')
-        self.assertEqual(u'@import url(x);', r.cssText)
+        self.assertEqual('@import url(x);', r.cssText)
         r.media.mediaText = 'tv' 
-        self.assertEqual(u'@import url(x) tv;', r.cssText)
+        self.assertEqual('@import url(x) tv;', r.cssText)
         r.media.appendMedium('print') # all + tv = all!
-        self.assertEqual(u'@import url(x) tv, print;', r.cssText)
+        self.assertEqual('@import url(x) tv, print;', r.cssText)
 
     def test_name(self):
         "CSSImportRule.name"
         r = cssutils.css.CSSImportRule('x', name='a000000')
         self.assertEqual('a000000', r.name)
-        self.assertEqual(u'@import url(x) "a000000";', r.cssText)
+        self.assertEqual('@import url(x) "a000000";', r.cssText)
 
         r.name = "n"
         self.assertEqual('n', r.name)
-        self.assertEqual(u'@import url(x) "n";', r.cssText)
+        self.assertEqual('@import url(x) "n";', r.cssText)
         r.name = '"'
         self.assertEqual('"', r.name)
-        self.assertEqual(u'@import url(x) "\\"";', r.cssText)
+        self.assertEqual('@import url(x) "\\"";', r.cssText)
         
         r.hreftype = 'string'
-        self.assertEqual(u'@import "x" "\\"";', r.cssText)
+        self.assertEqual('@import "x" "\\"";', r.cssText)
         r.name = "123"
-        self.assertEqual(u'@import "x" "123";', r.cssText)
+        self.assertEqual('@import "x" "123";', r.cssText)
 
         r.name = None
         self.assertEqual(None, r.name)
-        self.assertEqual(u'@import "x";', r.cssText)
+        self.assertEqual('@import "x";', r.cssText)
 
         r.name = ""
         self.assertEqual(None, r.name)
-        self.assertEqual(u'@import "x";', r.cssText)
+        self.assertEqual('@import "x";', r.cssText)
         
         self.assertRaises(xml.dom.SyntaxErr, r._setName, 0)
         self.assertRaises(xml.dom.SyntaxErr, r._setName, 123)
@@ -376,9 +376,9 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
 
         def fetcher(url):
             if url.endswith('level1.css'): 
-                return None, u'@charset "ascii"; @import "level2.css";'.encode()
+                return None, '@charset "ascii"; @import "level2.css";'.encode()
             else:
-                return None, u'a { color: red }'.encode()
+                return None, 'a { color: red }'.encode()
             
         parser = cssutils.CSSParser(fetcher=fetcher)
         
@@ -394,24 +394,24 @@ class CSSImportRuleTestCase(test_cssrule.CSSRuleTestCase):
     def test_incomplete(self):
         "CSSImportRule (incomplete)"
         tests = {
-            u'@import "x.css': u'@import "x.css";',
-            u"@import 'x": u'@import "x";',
+            '@import "x.css': '@import "x.css";',
+            "@import 'x": '@import "x";',
             # TODO:
-            u"@import url(x": u'@import url(x);',
-            u"@import url('x": u'@import url(x);',
-            u'@import url("x;': u'@import url("x;");',
-            u'@import url( "x;': u'@import url("x;");',
-            u'@import url("x ': u'@import url("x ");',
-            u'@import url(x ': u'@import url(x);',
-            u'''@import "a
+            "@import url(x": '@import url(x);',
+            "@import url('x": '@import url(x);',
+            '@import url("x;': '@import url("x;");',
+            '@import url( "x;': '@import url("x;");',
+            '@import url("x ': '@import url("x ");',
+            '@import url(x ': '@import url(x);',
+            '''@import "a
                 @import "b";
-                @import "c";''': u'@import "c";'
+                @import "c";''': '@import "c";'
         }
         self.do_equal_p(tests, raising=False) # parse
         
     def test_InvalidModificationErr(self):
         "CSSImportRule.cssText InvalidModificationErr"
-        self._test_InvalidModificationErr(u'@import')
+        self._test_InvalidModificationErr('@import')
 
     def test_reprANDstr(self):
         "CSSImportRule.__repr__(), .__str__()"
diff --git a/src/cssutils/tests/test_cssmediarule.py b/src/cssutils/tests/test_cssmediarule.py
index 5d75821..db326b9 100644
--- a/src/cssutils/tests/test_cssmediarule.py
+++ b/src/cssutils/tests/test_cssmediarule.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.CSSMediaRule"""
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
 class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -14,7 +14,7 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.r_typeString = 'MEDIA_RULE'
         # for tests
         self.stylerule = cssutils.css.CSSStyleRule()
-        self.stylerule.cssText = u'a {}'
+        self.stylerule.cssText = 'a {}'
         
     def test_init(self):
         "CSSMediaRule.__init__()"
@@ -23,7 +23,7 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         r = cssutils.css.CSSMediaRule()
         self.assertEqual(cssutils.css.CSSRuleList, type(r.cssRules))
         self.assertEqual([], r.cssRules)
-        self.assertEqual(u'', r.cssText)
+        self.assertEqual('', r.cssText)
         self.assertEqual(cssutils.stylesheets.MediaList, type(r.media))
         self.assertEqual('all', r.media.mediaText)
         self.assertEqual(None, r.name)
@@ -31,7 +31,7 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         r = cssutils.css.CSSMediaRule(mediaText='print', name='name')
         self.assertEqual(cssutils.css.CSSRuleList, type(r.cssRules))
         self.assertEqual([], r.cssRules)
-        self.assertEqual(u'', r.cssText)
+        self.assertEqual('', r.cssText)
         self.assertEqual(cssutils.stylesheets.MediaList, type(r.media))
         self.assertEqual('print', r.media.mediaText)
         self.assertEqual('name', r.name)
@@ -93,7 +93,7 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertEqual(2, m.cssRules.length)
         m.cssRules.extend(cssutils.parseString('/*3*/x {y:2}').cssRules)
         self.assertEqual(4, m.cssRules.length)
-        self.assertEqual(u'@media all {\n    a {\n        x: 1\n        }\n    /*2*/\n    /*3*/\n    x {\n        y: 2\n        }\n    }', 
+        self.assertEqual('@media all {\n    a {\n        x: 1\n        }\n    /*2*/\n    /*3*/\n    x {\n        y: 2\n        }\n    }',
                          m.cssText)
         
         for rule in m.cssRules:
@@ -102,84 +102,84 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
 
     def test_cssText(self):
         "CSSMediaRule.cssText"
-        style = '''{
-    a {
-        color: red
-        }
+        style = '''{
+    a {
+        color: red
+        }
     }'''
 
         mls = {
-            u' (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx) ': None,
-            u' tv ': None,
-            u' only tv ': None,
-            u' not tv ': None,
-            u' only tv and (color) ': None,
-            u' only tv and(color)': u' only tv and (color) ',
-            u' only tv and (color: red) ': None,
-            u' only tv and (color: red) and (width: 100px) ': None,
-            u' only tv and (color: red) and (width: 100px), tv ': None,
-            u' only tv and (color: red) and (width: 100px), tv and (width: 20px) ': None,
-            u' only tv and(color :red)and(  width :100px  )  ,tv and(width: 20px) ': 
-                u' only tv and (color: red) and (width: 100px), tv and (width: 20px) ',
-            u' (color: red) and (width: 100px), (width: 20px) ': None,
-            u' /*1*/ only /*2*/ tv /*3*/ and /*4*/ (/*5*/ width) /*5*/ /*6*/, (color) and (height) ': None,
-            u'(color)and(width),(height)': u' (color) and (width), (height) '
+            ' (min-device-pixel-ratio: 1.3), (min-resolution: 1.3dppx) ': None,
+            ' tv ': None,
+            ' only tv ': None,
+            ' not tv ': None,
+            ' only tv and (color) ': None,
+            ' only tv and(color)': ' only tv and (color) ',
+            ' only tv and (color: red) ': None,
+            ' only tv and (color: red) and (width: 100px) ': None,
+            ' only tv and (color: red) and (width: 100px), tv ': None,
+            ' only tv and (color: red) and (width: 100px), tv and (width: 20px) ': None,
+            ' only tv and(color :red)and(  width :100px  )  ,tv and(width: 20px) ':
+                ' only tv and (color: red) and (width: 100px), tv and (width: 20px) ',
+            ' (color: red) and (width: 100px), (width: 20px) ': None,
+            ' /*1*/ only /*2*/ tv /*3*/ and /*4*/ (/*5*/ width) /*5*/ /*6*/, (color) and (height) ': None,
+            '(color)and(width),(height)': ' (color) and (width), (height) '
         }
         tests = {}
-        for b, a in mls.items(): 
+        for b, a in list(mls.items()):
             if a is None:
                 a = b
-            tests[u'@media%s%s' % (b, style)] = u'@media%s%s' % (a, style)
+            tests['@media%s%s' % (b, style)] = '@media%s%s' % (a, style)
 
         self.do_equal_p(tests)
         self.do_equal_r(tests)
 
         tests = {
-            u'@media only tv{}': u'',
-            u'@media not tv{}': u'',
-            u'@media only tv and (color){}': u'',
-            u'@media only tv and (color: red){}': u'',
-            u'@media only tv and (color: red) and (width: 100px){}': u'',
-            u'@media only tv and (color: red) and (width: 100px), tv{}': u'',
-            u'@media only tv and (color: red) and (width: 100px), tv and (width: 20px){}': u'',
-            u'@media (color: red) and (width: 100px), (width: 20px){}': u'',
-            u'@media (width){}': u'',
-            u'@media (width:10px){}': u'',
-            u'@media (width), (color){}': u'',
-            u'@media (width)  ,  (color),(height){}': u'',
-            u'@media (width)  ,  (color) and (height){}': u'',
-            u'@media (width) and (color){}': u'',
-            u'@media all and (width){}': u'',
-            u'@media all and (width:10px){}': u'',
-            u'@media all and (width), (color){}': u'',
-            u'@media all and (width)  ,  (color),(height){}': u'',
-            u'@media all and (width)  ,  (color) and (height){}': u'',
-            u'@media all and (width) and (color){}': u'',
-            u'@media only tv and (width){}': u'',
-            u'@media only tv and (width:10px){}': u'',
-            u'@media only tv and (width), (color){}': u'',
-            u'@media only tv and (width)  ,  (color),(height){}': u'',
-            u'@media only tv and (width)  ,  (color) and (height){}': u'',
-            u'@media only tv and (width) and (color){}': u'',
-
-            u'@media only tv and (width) "name" {}': u'',
-            u'@media only tv and (width:10px) "name" {}': u'',
-            u'@media only tv and (width), (color){}': u'',
-            u'@media only tv and (width)  ,  (color),(height){}': u'',
-            u'@media only tv and (width)  ,  (color) and (height){}': u'',
-            u'@media only tv and (width) and (color){}': u'',
+            '@media only tv{}': '',
+            '@media not tv{}': '',
+            '@media only tv and (color){}': '',
+            '@media only tv and (color: red){}': '',
+            '@media only tv and (color: red) and (width: 100px){}': '',
+            '@media only tv and (color: red) and (width: 100px), tv{}': '',
+            '@media only tv and (color: red) and (width: 100px), tv and (width: 20px){}': '',
+            '@media (color: red) and (width: 100px), (width: 20px){}': '',
+            '@media (width){}': '',
+            '@media (width:10px){}': '',
+            '@media (width), (color){}': '',
+            '@media (width)  ,  (color),(height){}': '',
+            '@media (width)  ,  (color) and (height){}': '',
+            '@media (width) and (color){}': '',
+            '@media all and (width){}': '',
+            '@media all and (width:10px){}': '',
+            '@media all and (width), (color){}': '',
+            '@media all and (width)  ,  (color),(height){}': '',
+            '@media all and (width)  ,  (color) and (height){}': '',
+            '@media all and (width) and (color){}': '',
+            '@media only tv and (width){}': '',
+            '@media only tv and (width:10px){}': '',
+            '@media only tv and (width), (color){}': '',
+            '@media only tv and (width)  ,  (color),(height){}': '',
+            '@media only tv and (width)  ,  (color) and (height){}': '',
+            '@media only tv and (width) and (color){}': '',
+
+            '@media only tv and (width) "name" {}': '',
+            '@media only tv and (width:10px) "name" {}': '',
+            '@media only tv and (width), (color){}': '',
+            '@media only tv and (width)  ,  (color),(height){}': '',
+            '@media only tv and (width)  ,  (color) and (height){}': '',
+            '@media only tv and (width) and (color){}': '',
 
             
 
-            u'@media all "name"{}': u'',
-            u'@media all {}': u'',
-            u'@media/*x*/all{}': u'',
-            u'@media all { a{ x: 1} }': u'@media all {\n    a {\n        x: 1\n        }\n    }',
-            u'@media all "name" { a{ x: 1} }': u'@media all "name" {\n    a {\n        x: 1\n        }\n    }',
-            u'@MEDIA all { a{x:1} }': u'@media all {\n    a {\n        x: 1\n        }\n    }',
-            u'@\\media all { a{x:1} }': u'@media all {\n    a {\n        x: 1\n        }\n    }',
-            u'@media all {@x some;a{color: red;}b{color: green;}}':
-                u'''@media all {
+            '@media all "name"{}': '',
+            '@media all {}': '',
+            '@media/*x*/all{}': '',
+            '@media all { a{ x: 1} }': '@media all {\n    a {\n        x: 1\n        }\n    }',
+            '@media all "name" { a{ x: 1} }': '@media all "name" {\n    a {\n        x: 1\n        }\n    }',
+            '@MEDIA all { a{x:1} }': '@media all {\n    a {\n        x: 1\n        }\n    }',
+            '@\\media all { a{x:1} }': '@media all {\n    a {\n        x: 1\n        }\n    }',
+            '@media all {@x some;a{color: red;}b{color: green;}}':
+                '''@media all {
     @x some;
     a {
         color: red
@@ -188,49 +188,49 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         color: green
         }
     }''',
-            u'@media all { @x{}}': u'@media all {\n    @x {\n        }\n    }',
-            u'@media all "n" /**/ { @x{}}': 
-                u'@media all "n" /**/ {\n    @x {\n        }\n    }',
+            '@media all { @x{}}': '@media all {\n    @x {\n        }\n    }',
+            '@media all "n" /**/ { @x{}}':
+                '@media all "n" /**/ {\n    @x {\n        }\n    }',
             # comments
-            u'@media/*1*//*2*/all/*3*//*4*/{/*5*/a{x:1}}': 
-                u'@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n    /*5*/\n    a {\n        x: 1\n        }\n    }',
-            u'@media  /*1*/  /*2*/  all  /*3*/  /*4*/  {  /*5*/  a{ x: 1} }': 
-                u'@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n    /*5*/\n    a {\n        x: 1\n        }\n    }',
+            '@media/*1*//*2*/all/*3*//*4*/{/*5*/a{x:1}}':
+                '@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n    /*5*/\n    a {\n        x: 1\n        }\n    }',
+            '@media  /*1*/  /*2*/  all  /*3*/  /*4*/  {  /*5*/  a{ x: 1} }':
+                '@media /*1*/ /*2*/ all /*3*/ /*4*/ {\n    /*5*/\n    a {\n        x: 1\n        }\n    }',
             # WS
-            u'@media\n\t\f all\n\t\f {\n\t\f a{ x: 1}\n\t\f }': 
-                u'@media all {\n    a {\n        x: 1\n        }\n    }',
+            '@media\n\t\f all\n\t\f {\n\t\f a{ x: 1}\n\t\f }':
+                '@media all {\n    a {\n        x: 1\n        }\n    }',
             # @page rule inside @media
-            u'@media all { @page { margin: 0; } }':
-                u'@media all {\n    @page {\n        margin: 0\n        }\n    }',
+            '@media all { @page { margin: 0; } }':
+                '@media all {\n    @page {\n        margin: 0\n        }\n    }',
             # nested media rules
-            u'@media all { @media all { p { color: red; } } }':
-                u'@media all {\n    @media all {\n        p {\n            '
+            '@media all { @media all { p { color: red; } } }':
+                '@media all {\n    @media all {\n        p {\n            '
                 'color: red\n            }\n        }\n    }',
             }
         self.do_equal_p(tests)
         self.do_equal_r(tests)
 
         tests = {
-            u'@media {}': xml.dom.SyntaxErr,
-            u'@media;': xml.dom.SyntaxErr,
-            u'@media/*only comment*/{}': xml.dom.SyntaxErr,
-            u'@media all;': xml.dom.SyntaxErr,
-            u'@media all "n";': xml.dom.SyntaxErr,
-            u'@media all; @x{}': xml.dom.SyntaxErr,
-            u'@media { a{ x: 1} }': xml.dom.SyntaxErr,
-            u'@media "name" { a{ x: 1} }': xml.dom.SyntaxErr,
-            u'@media "name" all { a{ x: 1} }': xml.dom.SyntaxErr,
-            u'@media all { @charset "x"; a{}}': xml.dom.HierarchyRequestErr,
-            u'@media all { @import "x"; a{}}': xml.dom.HierarchyRequestErr,
-            u'@media all { , }': xml.dom.SyntaxErr,
-            u'@media all {}EXTRA': xml.dom.SyntaxErr,
-            u'@media ({}': xml.dom.SyntaxErr,
-            u'@media (color{}': xml.dom.SyntaxErr,
-            u'@media (color:{}': xml.dom.SyntaxErr,
-            u'@media (color:red{}': xml.dom.SyntaxErr,
-            u'@media (:red){}': xml.dom.SyntaxErr,
-            u'@media (:){}': xml.dom.SyntaxErr,
-            u'@media color:red){}': xml.dom.SyntaxErr,
+            '@media {}': xml.dom.SyntaxErr,
+            '@media;': xml.dom.SyntaxErr,
+            '@media/*only comment*/{}': xml.dom.SyntaxErr,
+            '@media all;': xml.dom.SyntaxErr,
+            '@media all "n";': xml.dom.SyntaxErr,
+            '@media all; @x{}': xml.dom.SyntaxErr,
+            '@media { a{ x: 1} }': xml.dom.SyntaxErr,
+            '@media "name" { a{ x: 1} }': xml.dom.SyntaxErr,
+            '@media "name" all { a{ x: 1} }': xml.dom.SyntaxErr,
+            '@media all { @charset "x"; a{}}': xml.dom.HierarchyRequestErr,
+            '@media all { @import "x"; a{}}': xml.dom.HierarchyRequestErr,
+            '@media all { , }': xml.dom.SyntaxErr,
+            '@media all {}EXTRA': xml.dom.SyntaxErr,
+            '@media ({}': xml.dom.SyntaxErr,
+            '@media (color{}': xml.dom.SyntaxErr,
+            '@media (color:{}': xml.dom.SyntaxErr,
+            '@media (color:red{}': xml.dom.SyntaxErr,
+            '@media (:red){}': xml.dom.SyntaxErr,
+            '@media (:){}': xml.dom.SyntaxErr,
+            '@media color:red){}': xml.dom.SyntaxErr,
 
             }
         self.do_raise_p(tests)
@@ -243,7 +243,7 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.do_raise_r(tests)
 
         m = cssutils.css.CSSMediaRule()
-        m.cssText = u'''@media all {@x; /*1*/a{color: red;}}'''
+        m.cssText = '''@media all {@x; /*1*/a{color: red;}}'''
         for r in m.cssRules:
             self.assertEqual(m, r.parentRule)
             self.assertEqual(m.parentStyleSheet, r.parentStyleSheet)
@@ -263,9 +263,9 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         # set mediaText instead
         self.r.media.mediaText = 'print'
         self.r.insertRule(self.stylerule)
-        self.assertEqual(u'', self.r.cssText)
+        self.assertEqual('', self.r.cssText)
         cssutils.ser.prefs.keepEmptyRules = True
-        self.assertEqual(u'@media print {\n    a {}\n    }', self.r.cssText)
+        self.assertEqual('@media print {\n    a {}\n    }', self.r.cssText)
         cssutils.ser.prefs.useDefaults()
 
     def test_name(self):
@@ -276,21 +276,21 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertEqual('\\n"ame', r.name)
         r.name = "n"
         self.assertEqual('n', r.name)
-        self.assertEqual(u'@media all "n" {\n    a {\n        left: 0\n        }\n    }', 
+        self.assertEqual('@media all "n" {\n    a {\n        left: 0\n        }\n    }',
                          r.cssText)
         r.name = '"'
         self.assertEqual('"', r.name)
-        self.assertEqual(u'@media all "\\"" {\n    a {\n        left: 0\n        }\n    }',
+        self.assertEqual('@media all "\\"" {\n    a {\n        left: 0\n        }\n    }',
                          r.cssText)
 
         r.name = ''
         self.assertEqual(None, r.name)
-        self.assertEqual(u'@media all {\n    a {\n        left: 0\n        }\n    }',
+        self.assertEqual('@media all {\n    a {\n        left: 0\n        }\n    }',
                          r.cssText)
 
         r.name = None
         self.assertEqual(None, r.name)
-        self.assertEqual(u'@media all {\n    a {\n        left: 0\n        }\n    }',
+        self.assertEqual('@media all {\n    a {\n        left: 0\n        }\n    }',
                          r.cssText)
                 
         self.assertRaises(xml.dom.SyntaxErr, r._setName, 0)
@@ -300,7 +300,7 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         "CSSMediaRule.deleteRule(index)"
         # see CSSStyleSheet.deleteRule
         m = cssutils.css.CSSMediaRule()
-        m.cssText = u'''@media all {
+        m.cssText = '''@media all {
             @a;
             /* x */
             @b;
@@ -319,19 +319,19 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
 
         self.assertEqual(4, m.cssRules.length)
         self.assertEqual(
-            u'@media all {\n    @a;\n    /* x */\n    @b;\n    @c;\n    }', m.cssText)
+            '@media all {\n    @a;\n    /* x */\n    @b;\n    @c;\n    }', m.cssText)
         # beginning
         m.deleteRule(0)
         self.assertEqual(3, m.cssRules.length)
-        self.assertEqual(u'@media all {\n    /* x */\n    @b;\n    @c;\n    }', m.cssText)
+        self.assertEqual('@media all {\n    /* x */\n    @b;\n    @c;\n    }', m.cssText)
         # middle
         m.deleteRule(1)
         self.assertEqual(2, m.cssRules.length)
-        self.assertEqual(u'@media all {\n    /* x */\n    @c;\n    }', m.cssText)
+        self.assertEqual('@media all {\n    /* x */\n    @c;\n    }', m.cssText)
         # end
         m.deleteRule(1)
         self.assertEqual(1, m.cssRules.length)
-        self.assertEqual(u'@media all {\n    /* x */\n    }', m.cssText)
+        self.assertEqual('@media all {\n    /* x */\n    }', m.cssText)
 
     def test_deleteRule(self):
         "CSSMediaRule.deleteRule(rule)"
@@ -373,9 +373,9 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
         pagerule = cssutils.css.CSSPageRule()
         unknownrule = cssutils.css.CSSUnknownRule('@x;')
         stylerule = cssutils.css.CSSStyleRule('a')
-        stylerule.cssText = u'a { x: 1}'
-        comment1 = cssutils.css.CSSComment(u'/*1*/')
-        comment2 = cssutils.css.CSSComment(u'/*2*/')
+        stylerule.cssText = 'a { x: 1}'
+        comment1 = cssutils.css.CSSComment('/*1*/')
+        comment2 = cssutils.css.CSSComment('/*2*/')
 
         # hierarchy
         self.assertRaises(xml.dom.HierarchyRequestErr,
@@ -413,19 +413,19 @@ class CSSMediaRuleTestCase(test_cssrule.CSSRuleTestCase):
 
     def test_InvalidModificationErr(self):
         "CSSMediaRule.cssText InvalidModificationErr"
-        self._test_InvalidModificationErr(u'@media')
+        self._test_InvalidModificationErr('@media')
 
     def test_incomplete(self):
         "CSSMediaRule (incomplete)"
         tests = {
-            u'@media all { @unknown;': # no }
-                u'@media all {\n    @unknown;\n    }',
-            u'@media all { a {x:"1"}': # no }
-                u'@media all {\n    a {\n        x: "1"\n        }\n    }',
-            u'@media all { a {x:"1"': # no }}
-                u'@media all {\n    a {\n        x: "1"\n        }\n    }',
-            u'@media all { a {x:"1': # no "}}
-                u'@media all {\n    a {\n        x: "1"\n        }\n    }',
+            '@media all { @unknown;': # no }
+                '@media all {\n    @unknown;\n    }',
+            '@media all { a {x:"1"}': # no }
+                '@media all {\n    a {\n        x: "1"\n        }\n    }',
+            '@media all { a {x:"1"': # no }}
+                '@media all {\n    a {\n        x: "1"\n        }\n    }',
+            '@media all { a {x:"1': # no "}}
+                '@media all {\n    a {\n        x: "1"\n        }\n    }',
         }
         self.do_equal_p(tests) # parse
 
diff --git a/src/cssutils/tests/test_cssnamespacerule.py b/src/cssutils/tests/test_cssnamespacerule.py
index d41012d..12a3808 100644
--- a/src/cssutils/tests/test_cssnamespacerule.py
+++ b/src/cssutils/tests/test_cssnamespacerule.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.CSSImportRule"""
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
 class CSSNamespaceRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -21,31 +21,31 @@ class CSSNamespaceRuleTestCase(test_cssrule.CSSRuleTestCase):
         tests = [
                  (None, None),
                  ('', ''),
-                 (None, u''),
-                 (u'', None),
-                 (u'', u'no-uri'),
+                 (None, ''),
+                 ('', None),
+                 ('', 'no-uri'),
                  ]
         for uri, p in tests:            
             r = cssutils.css.CSSNamespaceRule(namespaceURI=uri, prefix=p)
             self.assertEqual(None, r.namespaceURI)
-            self.assertEqual(u'', r.prefix)
-            self.assertEqual(u'', r.cssText)
+            self.assertEqual('', r.prefix)
+            self.assertEqual('', r.cssText)
             self.assertEqual(None, r.parentStyleSheet)
             self.assertEqual(None, r.parentRule)
         
         r = cssutils.css.CSSNamespaceRule(namespaceURI='example')
         self.assertEqual('example', r.namespaceURI)
-        self.assertEqual(u'', r.prefix)
-        self.assertEqual(u'@namespace "example";', r.cssText)
+        self.assertEqual('', r.prefix)
+        self.assertEqual('@namespace "example";', r.cssText)
         self.sheet.add(r)
         self.assertEqual(self.sheet, r.parentStyleSheet)
 
         r = cssutils.css.CSSNamespaceRule(namespaceURI='example', prefix='p')
         self.assertEqual('example', r.namespaceURI)
-        self.assertEqual(u'p', r.prefix)
-        self.assertEqual(u'@namespace p "example";', r.cssText)
+        self.assertEqual('p', r.prefix)
+        self.assertEqual('@namespace p "example";', r.cssText)
         
-        css = u'@namespace p "u";'
+        css = '@namespace p "u";'
         r = cssutils.css.CSSNamespaceRule(cssText=css)
         self.assertEqual(r.cssText, css)       
 
@@ -56,129 +56,129 @@ class CSSNamespaceRuleTestCase(test_cssrule.CSSRuleTestCase):
         "CSSNamespaceRule.cssText"
         # cssText may only be set initalially
         r = cssutils.css.CSSNamespaceRule()
-        css = u'@namespace p "u";'
+        css = '@namespace p "u";'
         r.cssText = css
         self.assertEqual(r.cssText, css)
         self.assertRaises(xml.dom.NoModificationAllowedErr, r._setCssText, 
-                          u'@namespace p "OTHER";')
+                          '@namespace p "OTHER";')
         
         tests = {
-            u'@namespace "";': None,
-            u'@namespace "u";': None,
-            u'@namespace p "u";': None,
-            u'@namespace empty "";': None,
+            '@namespace "";': None,
+            '@namespace "u";': None,
+            '@namespace p "u";': None,
+            '@namespace empty "";': None,
             
-            u'@namespace p "p";': None,
-            u"@namespace p 'u';": u'@namespace p "u";',
+            '@namespace p "p";': None,
+            "@namespace p 'u';": '@namespace p "u";',
 
-            u'@\\namespace p "u";': u'@namespace p "u";',
-            u'@NAMESPACE p "u";': u'@namespace p "u";',
+            '@\\namespace p "u";': '@namespace p "u";',
+            '@NAMESPACE p "u";': '@namespace p "u";',
 
-            u'@namespace  p  "u"  ;': u'@namespace p "u";',
-            u'@namespace p"u";': u'@namespace p "u";',
-            u'@namespace p "u";': u'@namespace p "u";',
+            '@namespace  p  "u"  ;': '@namespace p "u";',
+            '@namespace p"u";': '@namespace p "u";',
+            '@namespace p "u";': '@namespace p "u";',
 
-            u'@namespace/*1*/"u"/*2*/;': u'@namespace /*1*/ "u" /*2*/;',
-            u'@namespace/*1*/p/*2*/"u"/*3*/;': u'@namespace /*1*/ p /*2*/ "u" /*3*/;',
+            '@namespace/*1*/"u"/*2*/;': '@namespace /*1*/ "u" /*2*/;',
+            '@namespace/*1*/p/*2*/"u"/*3*/;': '@namespace /*1*/ p /*2*/ "u" /*3*/;',
 
-            u'@namespace p url(u);': u'@namespace p "u";',
-            u'@namespace p url(\'u\');': u'@namespace p "u";',
-            u'@namespace p url(\"u\");': u'@namespace p "u";',
-            u'@namespace p url( \"u\" );': u'@namespace p "u";',
+            '@namespace p url(u);': '@namespace p "u";',
+            '@namespace p url(\'u\');': '@namespace p "u";',
+            '@namespace p url(\"u\");': '@namespace p "u";',
+            '@namespace p url( \"u\" );': '@namespace p "u";',
             
             # comments
-            u'@namespace/*1*//*2*/p/*3*//*4*/url(u)/*5*//*6*/;': 
-                u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;',
-            u'@namespace/*1*//*2*/p/*3*//*4*/"u"/*5*//*6*/;': 
-                u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;',
-            u'@namespace/*1*//*2*/p/*3*//*4*/url("u")/*5*//*6*/;': 
-                u'@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;',
-
-            u'@namespace/*1*//*2*/url(u)/*5*//*6*/;': 
-                u'@namespace /*1*/ /*2*/ "u" /*5*/ /*6*/;',
+            '@namespace/*1*//*2*/p/*3*//*4*/url(u)/*5*//*6*/;':
+                '@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;',
+            '@namespace/*1*//*2*/p/*3*//*4*/"u"/*5*//*6*/;':
+                '@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;',
+            '@namespace/*1*//*2*/p/*3*//*4*/url("u")/*5*//*6*/;':
+                '@namespace /*1*/ /*2*/ p /*3*/ /*4*/ "u" /*5*/ /*6*/;',
+
+            '@namespace/*1*//*2*/url(u)/*5*//*6*/;':
+                '@namespace /*1*/ /*2*/ "u" /*5*/ /*6*/;',
             
             # WS
-            u'@namespace\n\r\t\f p\n\r\t\f url(\n\r\t\f u\n\r\t\f )\n\r\t\f ;': 
-                u'@namespace p "u";',
-            u'@namespace\n\r\t\f p\n\r\t\f url(\n\r\t\f "u"\n\r\t\f )\n\r\t\f ;': 
-                u'@namespace p "u";',
-            u'@namespace\n\r\t\f p\n\r\t\f "str"\n\r\t\f ;': 
-                u'@namespace p "str";',
-            u'@namespace\n\r\t\f "str"\n\r\t\f ;': 
-                u'@namespace "str";'
+            '@namespace\n\r\t\f p\n\r\t\f url(\n\r\t\f u\n\r\t\f )\n\r\t\f ;':
+                '@namespace p "u";',
+            '@namespace\n\r\t\f p\n\r\t\f url(\n\r\t\f "u"\n\r\t\f )\n\r\t\f ;':
+                '@namespace p "u";',
+            '@namespace\n\r\t\f p\n\r\t\f "str"\n\r\t\f ;':
+                '@namespace p "str";',
+            '@namespace\n\r\t\f "str"\n\r\t\f ;':
+                '@namespace "str";'
             }
         self.do_equal_p(tests)
         #self.do_equal_r(tests) # cannot use here as always new r is needed
-        for test, expected in tests.items():
+        for test, expected in list(tests.items()):
             r = cssutils.css.CSSNamespaceRule(cssText=test)
             if expected is None:
                 expected = test
             self.assertEqual(expected, r.cssText)
 
         tests = {
-            u'@namespace;': xml.dom.SyntaxErr, # nothing
-            u'@namespace p;': xml.dom.SyntaxErr, # no namespaceURI
-            u'@namespace "u" p;': xml.dom.SyntaxErr, # order
-            u'@namespace "u";EXTRA': xml.dom.SyntaxErr,
-            u'@namespace p "u";EXTRA': xml.dom.SyntaxErr,
+            '@namespace;': xml.dom.SyntaxErr, # nothing
+            '@namespace p;': xml.dom.SyntaxErr, # no namespaceURI
+            '@namespace "u" p;': xml.dom.SyntaxErr, # order
+            '@namespace "u";EXTRA': xml.dom.SyntaxErr,
+            '@namespace p "u";EXTRA': xml.dom.SyntaxErr,
             }
         self.do_raise_p(tests) # parse
         tests.update({
-            u'@namespace p url(x)': xml.dom.SyntaxErr, # missing ;
-            u'@namespace p "u"': xml.dom.SyntaxErr, # missing ;
+            '@namespace p url(x)': xml.dom.SyntaxErr, # missing ;
+            '@namespace p "u"': xml.dom.SyntaxErr, # missing ;
             # trailing
-            u'@namespace "u"; ': xml.dom.SyntaxErr,
-            u'@namespace "u";/**/': xml.dom.SyntaxErr,
-            u'@namespace p "u"; ': xml.dom.SyntaxErr,
-            u'@namespace p "u";/**/': xml.dom.SyntaxErr,
+            '@namespace "u"; ': xml.dom.SyntaxErr,
+            '@namespace "u";/**/': xml.dom.SyntaxErr,
+            '@namespace p "u"; ': xml.dom.SyntaxErr,
+            '@namespace p "u";/**/': xml.dom.SyntaxErr,
             })
         def _do(test):
             r = cssutils.css.CSSNamespaceRule(cssText=test)
-        for test, expected in tests.items():
+        for test, expected in list(tests.items()):
             self.assertRaises(expected, _do, test)
 
     def test_namespaceURI(self):
         "CSSNamespaceRule.namespaceURI"
         # set only initially
         r = cssutils.css.CSSNamespaceRule(namespaceURI='x')
-        self.assertEqual(u'x' , r.namespaceURI)
-        self.assertEqual(u'@namespace "x";', r.cssText)
+        self.assertEqual('x' , r.namespaceURI)
+        self.assertEqual('@namespace "x";', r.cssText)
 
         r = cssutils.css.CSSNamespaceRule(namespaceURI='"')
-        self.assertEqual(u'@namespace "\\"";', r.cssText)
+        self.assertEqual('@namespace "\\"";', r.cssText)
         
         self.assertRaises(xml.dom.NoModificationAllowedErr, 
-                          r._setNamespaceURI, u'x')
+                          r._setNamespaceURI, 'x')
 
         self.assertRaises(xml.dom.NoModificationAllowedErr, 
-                          r._setCssText, u'@namespace "u";')
+                          r._setCssText, '@namespace "u";')
         
-        r._replaceNamespaceURI(u'http://example.com/new')
-        self.assertEqual(u'http://example.com/new' , r.namespaceURI)
+        r._replaceNamespaceURI('http://example.com/new')
+        self.assertEqual('http://example.com/new' , r.namespaceURI)
 
     def test_prefix(self):
         "CSSNamespaceRule.prefix"
         r = cssutils.css.CSSNamespaceRule(namespaceURI='u')
         r.prefix = 'p'
         self.assertEqual('p' , r.prefix)
-        self.assertEqual(u'@namespace p "u";', r.cssText)
+        self.assertEqual('@namespace p "u";', r.cssText)
 
         r = cssutils.css.CSSNamespaceRule(cssText='@namespace x "u";')
         r.prefix = 'p'
         self.assertEqual('p' , r.prefix)
-        self.assertEqual(u'@namespace p "u";', r.cssText)
+        self.assertEqual('@namespace p "u";', r.cssText)
 
-        valid = (None, u'')
+        valid = (None, '')
         for prefix in valid:
             r.prefix = prefix
-            self.assertEqual(r.prefix, u'')
-            self.assertEqual(u'@namespace "u";', r.cssText)
+            self.assertEqual(r.prefix, '')
+            self.assertEqual('@namespace "u";', r.cssText)
             
         valid = ('a', '_x', 'a1', 'a-1')
         for prefix in valid:
             r.prefix = prefix
             self.assertEqual(r.prefix, prefix)
-            self.assertEqual(u'@namespace %s "u";' % prefix, r.cssText)
+            self.assertEqual('@namespace %s "u";' % prefix, r.cssText)
                     
         invalid = ('1', ' x', ' ', ',')
         for prefix in invalid:
@@ -186,35 +186,35 @@ class CSSNamespaceRuleTestCase(test_cssrule.CSSRuleTestCase):
 
     def test_InvalidModificationErr(self):
         "CSSNamespaceRule.cssText InvalidModificationErr"
-        self._test_InvalidModificationErr(u'@namespace')        
+        self._test_InvalidModificationErr('@namespace')
 
     def test_incomplete(self):
         "CSSNamespaceRule (incomplete)"
         tests = {
-            u'@namespace "uri': u'@namespace "uri";',
-            u"@namespace url(x": u'@namespace "x";',
-            u"@namespace url('x": u'@namespace "x";',
-            u'@namespace url("x;': u'@namespace "x;";',
-            u'@namespace url( "x;': u'@namespace "x;";',
-            u'@namespace url("x ': u'@namespace "x ";',
-            u'@namespace url(x ': u'@namespace "x";',
+            '@namespace "uri': '@namespace "uri";',
+            "@namespace url(x": '@namespace "x";',
+            "@namespace url('x": '@namespace "x";',
+            '@namespace url("x;': '@namespace "x;";',
+            '@namespace url( "x;': '@namespace "x;";',
+            '@namespace url("x ': '@namespace "x ";',
+            '@namespace url(x ': '@namespace "x";',
         }
         self.do_equal_p(tests) # parse
         tests = {
-            u'@namespace "uri': xml.dom.SyntaxErr,
-            u"@namespace url(x": xml.dom.SyntaxErr,
-            u"@namespace url('x": xml.dom.SyntaxErr,
-            u'@namespace url("x;': xml.dom.SyntaxErr,
-            u'@namespace url( "x;': xml.dom.SyntaxErr,
-            u'@namespace url("x ': xml.dom.SyntaxErr,
-            u'@namespace url(x ': xml.dom.SyntaxErr           
+            '@namespace "uri': xml.dom.SyntaxErr,
+            "@namespace url(x": xml.dom.SyntaxErr,
+            "@namespace url('x": xml.dom.SyntaxErr,
+            '@namespace url("x;': xml.dom.SyntaxErr,
+            '@namespace url( "x;': xml.dom.SyntaxErr,
+            '@namespace url("x ': xml.dom.SyntaxErr,
+            '@namespace url(x ': xml.dom.SyntaxErr
             }
         self.do_raise_r(tests) # set cssText
 
     def test_reprANDstr(self):
         "CSSNamespaceRule.__repr__(), .__str__()"
-        namespaceURI=u'http://example.com'
-        prefix=u'prefix'
+        namespaceURI='http://example.com'
+        prefix='prefix'
 
         s = cssutils.css.CSSNamespaceRule(namespaceURI=namespaceURI, prefix=prefix)
 
diff --git a/src/cssutils/tests/test_csspagerule.py b/src/cssutils/tests/test_csspagerule.py
index 4aba2ae..f0fc778 100644
--- a/src/cssutils/tests/test_csspagerule.py
+++ b/src/cssutils/tests/test_csspagerule.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.CSSPageRule"""
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
 class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -23,12 +23,12 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
         super(CSSPageRuleTestCase, self).test_init()
 
         r = cssutils.css.CSSPageRule()
-        self.assertEqual(u'', r.selectorText)
+        self.assertEqual('', r.selectorText)
         self.assertEqual(cssutils.css.CSSStyleDeclaration, type(r.style))
         self.assertEqual(r, r.style.parentRule)
 
         # until any properties
-        self.assertEqual(u'', r.cssText)
+        self.assertEqual('', r.cssText)
 
         # only possible to set @... similar name
         self.assertRaises(xml.dom.InvalidModificationErr, self.r._setAtkeyword, 'x')
@@ -59,60 +59,60 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
 
     def test_InvalidModificationErr(self):
         "CSSPageRule.cssText InvalidModificationErr"
-        self._test_InvalidModificationErr(u'@page')
+        self._test_InvalidModificationErr('@page')
         tests = {
-            u'@pag {}': xml.dom.InvalidModificationErr,
+            '@pag {}': xml.dom.InvalidModificationErr,
             }
         self.do_raise_r(tests)
 
     def test_incomplete(self):
         "CSSPageRule (incomplete)"
         tests = {
-            u'@page :left { ':
-                u'', # no } and no content
-            u'@page :left { color: red':
-                u'@page :left {\n    color: red\n    }', # no }
+            '@page :left { ':
+                '', # no } and no content
+            '@page :left { color: red':
+                '@page :left {\n    color: red\n    }', # no }
         }
         self.do_equal_p(tests) # parse
 
     def test_cssText(self):
         "CSSPageRule.cssText"
-        EXP = u'@page %s {\n    margin: 0\n    }'
+        EXP = '@page %s {\n    margin: 0\n    }'
         tests = {
-            u'@page {}': u'',
-            u'@page:left{}': u'',
-            u'@page :right {}': u'',
-            u'@page {margin:0;}': u'@page {\n    margin: 0\n    }',
-
-            u'@page name { margin: 0 }': EXP % u'name',
-            u'@page name:left { margin: 0 }': EXP % u'name:left',
-            u'@page name:right { margin: 0 }': EXP % u'name:right',
-            u'@page name:first { margin: 0 }': EXP % u'name:first',
-            u'@page :left { margin: 0 }': EXP % u':left',
-            u'@page:left { margin: 0 }': EXP % u':left',
-            u'@page :right { margin: 0 }': EXP % u':right',
-            u'@page :first { margin: 0 }': EXP % u':first',
-            u'@page :UNKNOWNIDENT { margin: 0 }': EXP % u':UNKNOWNIDENT',
-
-            u'@PAGE:left{margin:0;}': u'@page :left {\n    margin: 0\n    }',
-            u'@\\page:left{margin:0;}': u'@page :left {\n    margin: 0\n    }',
+            '@page {}': '',
+            '@page:left{}': '',
+            '@page :right {}': '',
+            '@page {margin:0;}': '@page {\n    margin: 0\n    }',
+
+            '@page name { margin: 0 }': EXP % 'name',
+            '@page name:left { margin: 0 }': EXP % 'name:left',
+            '@page name:right { margin: 0 }': EXP % 'name:right',
+            '@page name:first { margin: 0 }': EXP % 'name:first',
+            '@page :left { margin: 0 }': EXP % ':left',
+            '@page:left { margin: 0 }': EXP % ':left',
+            '@page :right { margin: 0 }': EXP % ':right',
+            '@page :first { margin: 0 }': EXP % ':first',
+            '@page :UNKNOWNIDENT { margin: 0 }': EXP % ':UNKNOWNIDENT',
+
+            '@PAGE:left{margin:0;}': '@page :left {\n    margin: 0\n    }',
+            '@\\page:left{margin:0;}': '@page :left {\n    margin: 0\n    }',
 
             # comments
-            u'@page/*1*//*2*/:left/*3*//*4*/{margin:0;}':
-                u'@page /*1*/ /*2*/ :left /*3*/ /*4*/ {\n    margin: 0\n    }',
+            '@page/*1*//*2*/:left/*3*//*4*/{margin:0;}':
+                '@page /*1*/ /*2*/ :left /*3*/ /*4*/ {\n    margin: 0\n    }',
             # WS
-            u'@page:left{margin:0;}':
-                u'@page :left {\n    margin: 0\n    }',
-            u'@page\n\r\f\t :left\n\r\f\t {margin:0;}':
-                u'@page :left {\n    margin: 0\n    }',
+            '@page:left{margin:0;}':
+                '@page :left {\n    margin: 0\n    }',
+            '@page\n\r\f\t :left\n\r\f\t {margin:0;}':
+                '@page :left {\n    margin: 0\n    }',
                 
             # MarginRule
-            u'@page {    @top-right {        content: "2"        }    }':
-                u'@page {\n    @top-right {\n        content: "2"\n        }\n    }',
-            u'@page {padding: 1cm; margin: 1cm; @top-left {content: "1"}@top-right {content: "2";left: 1}}':
-                u'@page {\n    padding: 1cm;\n    margin: 1cm;\n    @top-left {\n        content: "1"\n        }\n    @top-right {\n        content: "2";\n        left: 1\n        }\n    }',
-            u'@page {@top-right { content: "1a"; content: "1b"; x: 1 }@top-right { content: "2"; y: 2 }}':
-                u'''@page {\n    @top-right {
+            '@page {    @top-right {        content: "2"        }    }':
+                '@page {\n    @top-right {\n        content: "2"\n        }\n    }',
+            '@page {padding: 1cm; margin: 1cm; @top-left {content: "1"}@top-right {content: "2";left: 1}}':
+                '@page {\n    padding: 1cm;\n    margin: 1cm;\n    @top-left {\n        content: "1"\n        }\n    @top-right {\n        content: "2";\n        left: 1\n        }\n    }',
+            '@page {@top-right { content: "1a"; content: "1b"; x: 1 }@top-right { content: "2"; y: 2 }}':
+                '''@page {\n    @top-right {
         content: "1a";
         content: "1b";
         x: 1;
@@ -126,39 +126,39 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
 
         tests = {
             # auto is not allowed
-            u'@page AUto {}': xml.dom.SyntaxErr,
-            u'@page AUto:left {}': xml.dom.SyntaxErr,
+            '@page AUto {}': xml.dom.SyntaxErr,
+            '@page AUto:left {}': xml.dom.SyntaxErr,
             
-            u'@page : {}': xml.dom.SyntaxErr,
-            u'@page :/*1*/left {}': xml.dom.SyntaxErr,
-            u'@page : left {}': xml.dom.SyntaxErr,
-            u'@page :left :right {}': xml.dom.SyntaxErr,
-            u'@page :left a {}': xml.dom.SyntaxErr,
+            '@page : {}': xml.dom.SyntaxErr,
+            '@page :/*1*/left {}': xml.dom.SyntaxErr,
+            '@page : left {}': xml.dom.SyntaxErr,
+            '@page :left :right {}': xml.dom.SyntaxErr,
+            '@page :left a {}': xml.dom.SyntaxErr,
             # no S between IDENT and PSEUDO
-            u'@page a :left  {}': xml.dom.SyntaxErr,
+            '@page a :left  {}': xml.dom.SyntaxErr,
 
-            u'@page :left;': xml.dom.SyntaxErr,
-            u'@page :left }': xml.dom.SyntaxErr,
+            '@page :left;': xml.dom.SyntaxErr,
+            '@page :left }': xml.dom.SyntaxErr,
             }
         self.do_raise_p(tests) # parse
         tests.update({
             # false selector
-            u'@page :right :left {}': xml.dom.SyntaxErr, # no }
-            u'@page :right X {}': xml.dom.SyntaxErr, # no }
-            u'@page X Y {}': xml.dom.SyntaxErr, # no }
+            '@page :right :left {}': xml.dom.SyntaxErr, # no }
+            '@page :right X {}': xml.dom.SyntaxErr, # no }
+            '@page X Y {}': xml.dom.SyntaxErr, # no }
             
-            u'@page :left {': xml.dom.SyntaxErr, # no }
+            '@page :left {': xml.dom.SyntaxErr, # no }
             # trailing
-            u'@page :left {}1': xml.dom.SyntaxErr, # no }
-            u'@page :left {}/**/': xml.dom.SyntaxErr, # no }
-            u'@page :left {} ': xml.dom.SyntaxErr, # no }
+            '@page :left {}1': xml.dom.SyntaxErr, # no }
+            '@page :left {}/**/': xml.dom.SyntaxErr, # no }
+            '@page :left {} ': xml.dom.SyntaxErr, # no }
             })
         self.do_raise_r(tests) # set cssText
 
     def test_cssText2(self):
         "CSSPageRule.cssText 2"
         r = cssutils.css.CSSPageRule()
-        s = u'a:left'
+        s = 'a:left'
         r.selectorText = s 
         self.assertEqual(r.selectorText, s)
 
@@ -188,33 +188,33 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
     def test_selectorText(self):
         "CSSPageRule.selectorText"
         r = cssutils.css.CSSPageRule()
-        r.selectorText = u'a:left'
-        self.assertEqual(r.selectorText, u'a:left')
+        r.selectorText = 'a:left'
+        self.assertEqual(r.selectorText, 'a:left')
         
         tests = {
-            u'': u'',
-            u'name': None,
-            u':left': None,
-            u':right': None,
-            u':first': None,
-            u':UNKNOWNIDENT': None,
-            u'name:left': None,
-            u' :left': u':left',
-            u':left': u':left',
-            u'/*1*/:left/*a*/': u'/*1*/ :left /*a*/',
-            u'/*1*/ :left /*a*/ /*b*/': None,
-            u':left/*a*/': u':left /*a*/',
-            u'/*1*/:left': u'/*1*/ :left',
+            '': '',
+            'name': None,
+            ':left': None,
+            ':right': None,
+            ':first': None,
+            ':UNKNOWNIDENT': None,
+            'name:left': None,
+            ' :left': ':left',
+            ':left': ':left',
+            '/*1*/:left/*a*/': '/*1*/ :left /*a*/',
+            '/*1*/ :left /*a*/ /*b*/': None,
+            ':left/*a*/': ':left /*a*/',
+            '/*1*/:left': '/*1*/ :left',
             }
         self.do_equal_r(tests, att='selectorText')
 
         tests = {
-            u':': xml.dom.SyntaxErr,
-            u':/*1*/left': xml.dom.SyntaxErr,
-            u': left': xml.dom.SyntaxErr,
-            u':left :right': xml.dom.SyntaxErr,
-            u':left a': xml.dom.SyntaxErr,
-            u'name :left': xml.dom.SyntaxErr,
+            ':': xml.dom.SyntaxErr,
+            ':/*1*/left': xml.dom.SyntaxErr,
+            ': left': xml.dom.SyntaxErr,
+            ':left :right': xml.dom.SyntaxErr,
+            ':left a': xml.dom.SyntaxErr,
+            'name :left': xml.dom.SyntaxErr,
             }
         self.do_raise_r(tests, att='_setSelectorText')
 
@@ -222,52 +222,52 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
         "CSSPageRule.specificity"
         r = cssutils.css.CSSPageRule()
         tests = {
-            u'': (0, 0, 0),
-            u'name': (1, 0, 0),
-            u':first': (0, 1, 0),
-            u':left': (0, 0, 1),
-            u':right': (0, 0, 1),
-            u':UNKNOWNIDENT': (0, 0, 1),
-            u'name:first': (1, 1, 0),
-            u'name:left': (1, 0, 1),
-            u'name:right': (1, 0, 1),
-            u'name:X': (1, 0, 1)
+            '': (0, 0, 0),
+            'name': (1, 0, 0),
+            ':first': (0, 1, 0),
+            ':left': (0, 0, 1),
+            ':right': (0, 0, 1),
+            ':UNKNOWNIDENT': (0, 0, 1),
+            'name:first': (1, 1, 0),
+            'name:left': (1, 0, 1),
+            'name:right': (1, 0, 1),
+            'name:X': (1, 0, 1)
         }
-        for sel, exp in tests.items():
+        for sel, exp in list(tests.items()):
             r.selectorText = sel
             self.assertEqual(r.specificity, exp)
             
             r = cssutils.css.CSSPageRule()
-            r.cssText = u'@page %s {}' % sel
+            r.cssText = '@page %s {}' % sel
             self.assertEqual(r.specificity, exp)
 
     def test_cssRules(self):
         "CSSPageRule.cssRules"
-        s = cssutils.parseString(u'@page {}')
+        s = cssutils.parseString('@page {}')
         p = s.cssRules[0]
         
         self.assertEqual(len(p.cssRules), 0)
         
         # add and insert
-        m1 = cssutils.css.MarginRule(u'@top-left', u'color: red')
+        m1 = cssutils.css.MarginRule('@top-left', 'color: red')
         i = p.add(m1)
         self.assertEqual(i, 0)
         self.assertEqual(len(p.cssRules), 1)
 
         m3 = cssutils.css.MarginRule()
-        m3.cssText = u'@top-right { color: blue }'
+        m3.cssText = '@top-right { color: blue }'
         i = p.insertRule(m3)
         self.assertEqual(i, 1)
         self.assertEqual(len(p.cssRules), 2)
 
         m2 = cssutils.css.MarginRule()
-        m2.margin = u'@top-center'
-        m2.style = u'color: green'
+        m2.margin = '@top-center'
+        m2.style = 'color: green'
         i = p.insertRule(m2, 1)
         self.assertEqual(i, 1)
         self.assertEqual(len(p.cssRules), 3)
 
-        self.assertEqual(p.cssText, u'''@page {
+        self.assertEqual(p.cssText, '''@page {
     @top-left {
         color: red
         }
@@ -280,22 +280,22 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
     }''')
         
         # keys and dict index
-        self.assertEqual(u'@top-left' in p, True)
-        self.assertEqual(u'@bottom-left' in p, False)
+        self.assertEqual('@top-left' in p, True)
+        self.assertEqual('@bottom-left' in p, False)
         
-        self.assertEqual(p.keys(), [u'@top-left', 
-                                    u'@top-center', 
-                                    u'@top-right'])
+        self.assertEqual(list(p.keys()), ['@top-left',
+                                    '@top-center',
+                                    '@top-right'])
         
-        self.assertEqual(p[u'@bottom-left'], None)
-        self.assertEqual(p[u'@top-left'].cssText, u'color: red')
-        p[u'@top-left'] = u'color: #f00'
-        self.assertEqual(p[u'@top-left'].cssText, u'color: #f00')
+        self.assertEqual(p['@bottom-left'], None)
+        self.assertEqual(p['@top-left'].cssText, 'color: red')
+        p['@top-left'] = 'color: #f00'
+        self.assertEqual(p['@top-left'].cssText, 'color: #f00')
         
         # delete
         p.deleteRule(m2)
         self.assertEqual(len(p.cssRules), 2)
-        self.assertEqual(p.cssText, u'''@page {
+        self.assertEqual(p.cssText, '''@page {
     @top-left {
         color: #f00
         }
@@ -307,7 +307,7 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
         p.deleteRule(0)
         self.assertEqual(len(p.cssRules), 1)        
         self.assertEqual(m3, p.cssRules[0])
-        self.assertEqual(p.cssText, u'''@page {
+        self.assertEqual(p.cssText, '''@page {
     @top-right {
         color: blue
         }
@@ -322,67 +322,67 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
         r = cssutils.css.CSSPageRule()
         s1 = r.style
         self.assertEqual(r, s1.parentRule)
-        self.assertEqual(u'', s1.cssText)
+        self.assertEqual('', s1.cssText)
         
         # set rule.cssText
         r.cssText = '@page { font-family: x1 }'
         self.assertNotEqual(r.style, s1)
         self.assertEqual(r, r.style.parentRule)
-        self.assertEqual(r.cssText, u'@page {\n    font-family: x1\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: x1')
-        self.assertEqual(s1.cssText, u'')
+        self.assertEqual(r.cssText, '@page {\n    font-family: x1\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: x1')
+        self.assertEqual(s1.cssText, '')
         s2 = r.style
         
         # set invalid rule.cssText
         try: 
             r.cssText = '@page { $ }'
-        except xml.dom.SyntaxErr, e:
+        except xml.dom.SyntaxErr as e:
             pass
         self.assertEqual(r.style, s2)
         self.assertEqual(r, r.style.parentRule)
-        self.assertEqual(r.cssText, u'@page {\n    font-family: x1\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: x1')
-        self.assertEqual(s2.cssText, u'font-family: x1')
+        self.assertEqual(r.cssText, '@page {\n    font-family: x1\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: x1')
+        self.assertEqual(s2.cssText, 'font-family: x1')
         s3 = r.style
 
         # set rule.style.cssText
         r.style.cssText = 'font-family: x2'
         self.assertEqual(r.style, s3)
         self.assertEqual(r, r.style.parentRule)
-        self.assertEqual(r.cssText, u'@page {\n    font-family: x2\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: x2')
+        self.assertEqual(r.cssText, '@page {\n    font-family: x2\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: x2')
 
         # set new style object s2
         s2 = cssutils.css.CSSStyleDeclaration('font-family: y1')
         r.style = s2
         self.assertEqual(r.style, s2)
         self.assertEqual(r, s2.parentRule)
-        self.assertEqual(r.cssText, u'@page {\n    font-family: y1\n    }')
-        self.assertEqual(s2.cssText, u'font-family: y1')
-        self.assertEqual(r.style.cssText, u'font-family: y1')
-        self.assertEqual(s3.cssText, u'font-family: x2') # old
+        self.assertEqual(r.cssText, '@page {\n    font-family: y1\n    }')
+        self.assertEqual(s2.cssText, 'font-family: y1')
+        self.assertEqual(r.style.cssText, 'font-family: y1')
+        self.assertEqual(s3.cssText, 'font-family: x2') # old
 
         # set s2.cssText
         s2.cssText = 'font-family: y2'
         self.assertEqual(r.style, s2)
-        self.assertEqual(r.cssText, u'@page {\n    font-family: y2\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: y2')
-        self.assertEqual(s3.cssText, u'font-family: x2') # old
+        self.assertEqual(r.cssText, '@page {\n    font-family: y2\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: y2')
+        self.assertEqual(s3.cssText, 'font-family: x2') # old
         # set invalid s2.cssText
         try: 
             s2.cssText = '$'
-        except xml.dom.SyntaxErr, e:
+        except xml.dom.SyntaxErr as e:
             pass
         self.assertEqual(r.style, s2)
-        self.assertEqual(r.cssText, u'@page {\n    font-family: y2\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: y2')
-        self.assertEqual(s3.cssText, u'font-family: x2') # old
+        self.assertEqual(r.cssText, '@page {\n    font-family: y2\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: y2')
+        self.assertEqual(s3.cssText, 'font-family: x2') # old
 
         # set r.style with text
         r.style = 'font-family: z'
         self.assertNotEqual(r.style, s2)
-        self.assertEqual(r.cssText, u'@page {\n    font-family: z\n    }')
-        self.assertEqual(r.style.cssText, u'font-family: z')
+        self.assertEqual(r.cssText, '@page {\n    font-family: z\n    }')
+        self.assertEqual(r.style.cssText, 'font-family: z')
 
     def test_properties(self):
         "CSSPageRule.style properties"
@@ -401,7 +401,7 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
         orphans: 3;
         widows: 3;
         '''
-        exp = u'''@page {
+        exp = '''@page {
     margin-top: 0;
     margin-right: 0;
     margin-bottom: 0;
@@ -417,7 +417,7 @@ class CSSPageRuleTestCase(test_cssrule.CSSRuleTestCase):
 
     def test_reprANDstr(self):
         "CSSPageRule.__repr__(), .__str__()"
-        sel=u':left'
+        sel=':left'
         
         s = cssutils.css.CSSPageRule(selectorText=sel)
         
diff --git a/src/cssutils/tests/test_cssproperties.py b/src/cssutils/tests/test_cssproperties.py
index ce6ec4d..bd270a2 100644
--- a/src/cssutils/tests/test_cssproperties.py
+++ b/src/cssutils/tests/test_cssproperties.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.cssproperties."""
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils.css
 import cssutils.profiles
 
@@ -46,7 +46,7 @@ class CSSPropertiesTestCase(basetest.BaseTestCase):
         "CSS2Properties"
         CSS2Properties = cssutils.css.cssproperties.CSS2Properties
         self.assertEqual(type(property()), type(CSS2Properties.color))
-        self.assertEqual(sum([len(x) for x in cssutils.profiles.properties.values()]),
+        self.assertEqual(sum([len(x) for x in list(cssutils.profiles.properties.values())]),
                           len(CSS2Properties._properties))
 
         c2 = CSS2Properties()
diff --git a/src/cssutils/tests/test_cssrule.py b/src/cssutils/tests/test_cssrule.py
index 8cfddc4..b777747 100644
--- a/src/cssutils/tests/test_cssrule.py
+++ b/src/cssutils/tests/test_cssrule.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.CSSRule"""
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils.css
 
 class CSSRuleTestCase(basetest.BaseTestCase):
@@ -39,7 +39,7 @@ class CSSRuleTestCase(basetest.BaseTestCase):
         "CSSRule.type and init"
         self.assertEqual(self.r_type, self.r.type)
         self.assertEqual(self.r_typeString, self.r.typeString)
-        self.assertEqual(u'', self.r.cssText)
+        self.assertEqual('', self.r.cssText)
         self.assertEqual(None, self.r.parentRule)
         self.assertEqual(None, self.r.parentStyleSheet)
 
@@ -79,7 +79,7 @@ class CSSRuleTestCase(basetest.BaseTestCase):
                 elif i == 2: # check namespaces
                     self.assertEqual('x', s.namespaces[''])
 
-        cssText = u''.join(r[0] for r in rules)
+        cssText = ''.join(r[0] for r in rules)
         # parsing               
         s = cssutils.parseString(cssText)
         test(s)
@@ -137,7 +137,7 @@ class CSSRuleTestCase(basetest.BaseTestCase):
                 self.assertEqual(rule.parentStyleSheet, mr.parentStyleSheet)
                 self.assertEqual(rule.type, rules[i][1])
 
-        cssText = '@media all { %s }' % u''.join(r[0] for r in rules)
+        cssText = '@media all { %s }' % ''.join(r[0] for r in rules)
         # parsing               
         s = cssutils.parseString(cssText)
         test(s)
@@ -184,10 +184,10 @@ class CSSRuleTestCase(basetest.BaseTestCase):
         self.rRO = cssutils.css.CSSRule()
         self.rRO._readonly = True
         self.assertEqual(True, self.rRO._readonly)
-        self.assertEqual(u'', self.rRO.cssText)
+        self.assertEqual('', self.rRO.cssText)
         self.assertRaises(xml.dom.NoModificationAllowedErr,
-                          self.rRO._setCssText, u'x')
-        self.assertEqual(u'', self.rRO.cssText)
+                          self.rRO._setCssText, 'x')
+        self.assertEqual('', self.rRO.cssText)
 
     def _test_InvalidModificationErr(self, startwithspace):
         """
@@ -201,27 +201,27 @@ class CSSRuleTestCase(basetest.BaseTestCase):
         e.g. " @page {}"
         exception is the style rule test
         """
-        tests = (u'',
-                 u'/* comment */',
-                 u'@charset "utf-8";',
-                 u'@font-face {}',
-                 u'@import url(x);',
-                 u'@media all {}',
-                 u'@namespace "x";'
-                 u'@page {}',
-                 u'@unknown;',
-                 u'@variables;',
+        tests = ('',
+                 '/* comment */',
+                 '@charset "utf-8";',
+                 '@font-face {}',
+                 '@import url(x);',
+                 '@media all {}',
+                 '@namespace "x";'
+                 '@page {}',
+                 '@unknown;',
+                 '@variables;',
                  # TODO:
                  #u'@top-left {}'
-                 u'a style rule {}'
+                 'a style rule {}'
                  )
         for test in tests:
-            if startwithspace in (u'a style rule', ) and test in (
-                u'/* comment */', u'a style rule {}'):
+            if startwithspace in ('a style rule', ) and test in (
+                '/* comment */', 'a style rule {}'):
                 continue
 
             if test.startswith(startwithspace):
-                test = u' %s' % test
+                test = ' %s' % test
 
             self.assertRaises(xml.dom.InvalidModificationErr,
                  self.r._setCssText, test)
diff --git a/src/cssutils/tests/test_cssrulelist.py b/src/cssutils/tests/test_cssrulelist.py
index 12a23a8..e8e0df7 100644
--- a/src/cssutils/tests/test_cssrulelist.py
+++ b/src/cssutils/tests/test_cssrulelist.py
@@ -1,6 +1,6 @@
 """Testcases for cssutils.css.CSSRuleList"""
 
-import basetest
+from . import basetest
 import cssutils
 
 class CSSRuleListTestCase(basetest.BaseTestCase):
diff --git a/src/cssutils/tests/test_cssstyledeclaration.py b/src/cssutils/tests/test_cssstyledeclaration.py
index 7e8bf6c..fb00f09 100644
--- a/src/cssutils/tests/test_cssstyledeclaration.py
+++ b/src/cssutils/tests/test_cssstyledeclaration.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.cssstyledelaration.CSSStyleDeclaration."""
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 
 class CSSStyleDeclarationTestCase(basetest.BaseTestCase):
@@ -12,12 +12,12 @@ class CSSStyleDeclarationTestCase(basetest.BaseTestCase):
     def test_init(self):
         "CSSStyleDeclaration.__init__()"
         s = cssutils.css.CSSStyleDeclaration()
-        self.assertEqual(u'', s.cssText)
+        self.assertEqual('', s.cssText)
         self.assertEqual(0, s.length)
         self.assertEqual(None, s.parentRule)
 
         s = cssutils.css.CSSStyleDeclaration(cssText='left: 0')
-        self.assertEqual(u'left: 0', s.cssText)
+        self.assertEqual('left: 0', s.cssText)
         self.assertEqual('0', s.getPropertyValue('left'))
 
         sheet = cssutils.css.CSSStyleRule()
@@ -26,7 +26,7 @@ class CSSStyleDeclarationTestCase(basetest.BaseTestCase):
 
         # should not be used but ordered parameter test
         s = cssutils.css.CSSStyleDeclaration('top: 0', sheet)
-        self.assertEqual(u'top: 0', s.cssText)
+        self.assertEqual('top: 0', s.cssText)
         self.assertEqual(sheet, s.parentRule)
 
     def test_items(self):
@@ -54,8 +54,8 @@ class CSSStyleDeclarationTestCase(basetest.BaseTestCase):
         self.assertEqual(priority, s.getProperty(name).priority)
 
         del s[name]
-        self.assertEqual(u'', s[name])
-        self.assertEqual(u'', s['never set'])
+        self.assertEqual('', s[name])
+        self.assertEqual('', s['never set'])
 
     def test__contains__(self):
         "CSSStyleDeclaration.__contains__(nameOrProperty)"
@@ -70,7 +70,7 @@ class CSSStyleDeclarationTestCase(basetest.BaseTestCase):
     def test__iter__item(self):
         "CSSStyleDeclaration.__iter__ and .item"
         s = cssutils.css.CSSStyleDeclaration()
-        s.cssText = ur'''
+        s.cssText = r'''
             color: red; c\olor: blue; CO\lor: green;
             left: 1px !important; left: 0;
             border: 0;
@@ -80,21 +80,21 @@ class CSSStyleDeclarationTestCase(basetest.BaseTestCase):
         for p in s:
             ps.append((p.literalname, p.value, p.priority))
         self.assertEqual(len(ps), 3)
-        self.assertEqual(ps[0], (ur'co\lor', 'green', ''))
-        self.assertEqual(ps[1], (ur'left', '1px', 'important'))
-        self.assertEqual(ps[2], (ur'border', '0', ''))
+        self.assertEqual(ps[0], (r'co\lor', 'green', ''))
+        self.assertEqual(ps[1], (r'left', '1px', 'important'))
+        self.assertEqual(ps[2], (r'border', '0', ''))
 
         # item
         self.assertEqual(s.length, 3)
-        self.assertEqual(s.item(0), u'color')
-        self.assertEqual(s.item(1), u'left')
-        self.assertEqual(s.item(2), u'border')
-        self.assertEqual(s.item(10), u'')
+        self.assertEqual(s.item(0), 'color')
+        self.assertEqual(s.item(1), 'left')
+        self.assertEqual(s.item(2), 'border')
+        self.assertEqual(s.item(10), '')
 
     def test_keys(self):
         "CSSStyleDeclaration.keys()"
         s = cssutils.parseStyle('x:1; x:2; y:1')
-        self.assertEqual(['x', 'y'], s.keys())
+        self.assertEqual(['x', 'y'], list(s.keys()))
         self.assertEqual(s['x'], '2')
         self.assertEqual(s['y'], '1')
 
@@ -103,53 +103,53 @@ class CSSStyleDeclarationTestCase(basetest.BaseTestCase):
         # error but parse
         tests = {
             # property names are caseinsensitive
-            u'TOP:0': u'top: 0',
-            u'top:0': u'top: 0',
+            'TOP:0': 'top: 0',
+            'top:0': 'top: 0',
             # simple escape
-            u'c\\olor: red; color:green': u'color: green',
-            u'color:g\\reen': u'color: g\\reen',
+            'c\\olor: red; color:green': 'color: green',
+            'color:g\\reen': 'color: g\\reen',
             # http://www.w3.org/TR/2009/CR-CSS2-20090423/syndata.html#illegalvalues
-            u'color:green': u'color: green',
-            u'color:green; color': u'color: green',
-            u'color:red;   color; color:green': u'color: green',
-            u'color:green; color:': u'color: green',
-            u'color:red;   color:; color:green': u'color: green',
-            u'color:green; color{;color:maroon}': u'color: green',
-            u'color:red; color{;color:maroon}; color:green': u'color: green',
+            'color:green': 'color: green',
+            'color:green; color': 'color: green',
+            'color:red;   color; color:green': 'color: green',
+            'color:green; color:': 'color: green',
+            'color:red;   color:; color:green': 'color: green',
+            'color:green; color{;color:maroon}': 'color: green',
+            'color:red; color{;color:maroon}; color:green': 'color: green',
             # tantek hack
-            ur'''color: red;
+            r'''color: red;
 voice-family: "\"}\"";
 voice-family:inherit;
 color: green;''': 'voice-family: inherit;\ncolor: green',
-            ur'''col\or: blue;
+            r'''col\or: blue;
                 font-family: 'Courier New Times
                 color: red;
-                color: green;''': u'color: green',
+                color: green;''': 'color: green',
 
             # special IE hacks are not preserved anymore (>=0.9.5b3)
-            u'/color: red; color: green': u'color: green',
-            u'/ color: red; color: green': u'color: green',
-            u'1px: red; color: green': u'color: green',
-            u'0: red; color: green': u'color: green',
-            u'1px:: red; color: green': u'color: green',
-            ur'$top: 0': u'',
-            ur'$: 0': u'', # really invalid!
+            '/color: red; color: green': 'color: green',
+            '/ color: red; color: green': 'color: green',
+            '1px: red; color: green': 'color: green',
+            '0: red; color: green': 'color: green',
+            '1px:: red; color: green': 'color: green',
+            r'$top: 0': '',
+            r'$: 0': '', # really invalid!
             # unknown rule but valid
-            u'@x;\ncolor: red': None,
-            u'@x {\n    }\ncolor: red': None,
-            u'/**/\ncolor: red': None,
-            u'/**/\ncolor: red;\n/**/': None,
+            '@x;\ncolor: red': None,
+            '@x {\n    }\ncolor: red': None,
+            '/**/\ncolor: red': None,
+            '/**/\ncolor: red;\n/**/': None,
             #issue #28
-            u';color: red': u'color: red',
-            u';;color: red;;': u'color: red'
+            ';color: red': 'color: red',
+            ';;color: red;;': 'color: red'
             }
         cssutils.ser.prefs.keepAllProperties = False
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             sh = cssutils.parseString('a { %s }' % test)
             if exp is None:
-                exp = u'%s' % test
-            elif exp != u'':
-                exp = u'%s' % exp
+                exp = '%s' % test
+            elif exp != '':
+                exp = '%s' % exp
             self.assertEqual(exp, sh.cssRules[0].style.cssText)
 
         cssutils.ser.prefs.useDefaults()
@@ -158,10 +158,10 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
         "CSSStyleDeclaration serialize"
         s = cssutils.css.CSSStyleDeclaration()
         tests = {
-            u'a:1 !important; a:2;b:1': (u'a: 1 !important;\nb: 1',
-                                         u'a: 1 !important;\na: 2;\nb: 1')
+            'a:1 !important; a:2;b:1': ('a: 1 !important;\nb: 1',
+                                         'a: 1 !important;\na: 2;\nb: 1')
         }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             s.cssText = test
             cssutils.ser.prefs.keepAllProperties = False
             self.assertEqual(exp[0], s.cssText)
@@ -172,7 +172,7 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
 
     def test_children(self):
         "CSSStyleDeclaration.children()"
-        style = u'/*1*/color: red; color: green; @x;'
+        style = '/*1*/color: red; color: green; @x;'
         types = [
             cssutils.css.CSSComment,
             cssutils.css.Property,
@@ -185,8 +185,8 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
                 self.assertEqual(x.parent, s)
 
         t(cssutils.parseStyle(style))
-        t(cssutils.parseString(u'a {'+style+'}').cssRules[0].style)
-        t(cssutils.parseString(u'@media all {a {'+style+'}}').cssRules[0].cssRules[0].style)
+        t(cssutils.parseString('a {'+style+'}').cssRules[0].style)
+        t(cssutils.parseString('@media all {a {'+style+'}}').cssRules[0].cssRules[0].style)
 
         s = cssutils.parseStyle(style)
         s['x'] = '0'
@@ -199,12 +199,12 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
         # empty
         s = cssutils.css.CSSStyleDeclaration()
         tests = {
-            u'': u'',
-            u' ': u'',
-            u' \t \n  ': u'',
-            u'/*x*/': u'/*x*/'
+            '': '',
+            ' ': '',
+            ' \t \n  ': '',
+            '/*x*/': '/*x*/'
             }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             s.cssText = 'left: 0;' # dummy to reset s
             s.cssText = test
             self.assertEqual(exp, s.cssText)
@@ -212,69 +212,69 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
         # normal
         s = cssutils.css.CSSStyleDeclaration()
         tests = {
-            u';': u'',
-            u'left: 0': u'left: 0',
-            u'left:0': u'left: 0',
-            u' left : 0 ': u'left: 0',
-            u'left: 0;': u'left: 0',
-            u'left: 0 !important ': u'left: 0 !important',
-            u'left:0!important': u'left: 0 !important',
-            u'left: 0; top: 1': u'left: 0;\ntop: 1',
+            ';': '',
+            'left: 0': 'left: 0',
+            'left:0': 'left: 0',
+            ' left : 0 ': 'left: 0',
+            'left: 0;': 'left: 0',
+            'left: 0 !important ': 'left: 0 !important',
+            'left:0!important': 'left: 0 !important',
+            'left: 0; top: 1': 'left: 0;\ntop: 1',
             # comments
             # TODO: spaces?
-            u'/*1*//*2*/left/*3*//*4*/:/*5*//*6*/0/*7*//*8*/!/*9*//*a*/important/*b*//*c*/;':
-                u'/*1*/\n/*2*/\nleft/*3*//*4*/: /*5*/ /*6*/ 0 /*7*/ /*8*/ !/*9*//*a*/important/*b*//*c*/',
-            u'/*1*/left: 0;/*2*/ top: 1/*3*/':
-                u'/*1*/\nleft: 0;\n/*2*/\ntop: 1 /*3*/',
-            u'left:0; top:1;': u'left: 0;\ntop: 1',
-            u'/*1*/left: 0;/*2*/ top: 1;/*3*/':
-                u'/*1*/\nleft: 0;\n/*2*/\ntop: 1;\n/*3*/',
+            '/*1*//*2*/left/*3*//*4*/:/*5*//*6*/0/*7*//*8*/!/*9*//*a*/important/*b*//*c*/;':
+                '/*1*/\n/*2*/\nleft/*3*//*4*/: /*5*/ /*6*/ 0 /*7*/ /*8*/ !/*9*//*a*/important/*b*//*c*/',
+            '/*1*/left: 0;/*2*/ top: 1/*3*/':
+                '/*1*/\nleft: 0;\n/*2*/\ntop: 1 /*3*/',
+            'left:0; top:1;': 'left: 0;\ntop: 1',
+            '/*1*/left: 0;/*2*/ top: 1;/*3*/':
+                '/*1*/\nleft: 0;\n/*2*/\ntop: 1;\n/*3*/',
             # WS
-            u'left:0!important;margin:1px 2px 3px 4px!important;': u'left: 0 !important;\nmargin: 1px 2px 3px 4px !important',
-            u'\n\r\f\t left\n\r\f\t :\n\r\f\t 0\n\r\f\t !\n\r\f\t important\n\r\f\t ;\n\r\f\t margin\n\r\f\t :\n\r\f\t 1px\n\r\f\t 2px\n\r\f\t 3px\n\r\f\t 4px;':
-            u'left: 0 !important;\nmargin: 1px 2px 3px 4px',
+            'left:0!important;margin:1px 2px 3px 4px!important;': 'left: 0 !important;\nmargin: 1px 2px 3px 4px !important',
+            '\n\r\f\t left\n\r\f\t :\n\r\f\t 0\n\r\f\t !\n\r\f\t important\n\r\f\t ;\n\r\f\t margin\n\r\f\t :\n\r\f\t 1px\n\r\f\t 2px\n\r\f\t 3px\n\r\f\t 4px;':
+            'left: 0 !important;\nmargin: 1px 2px 3px 4px',
             }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             s.cssText = test
             self.assertEqual(exp, s.cssText)
 
         # exception
         tests = {
-            u'color: #xyz': xml.dom.SyntaxErr,
-            u'top': xml.dom.SyntaxErr,
-            u'top:': xml.dom.SyntaxErr,
-            u'top : ': xml.dom.SyntaxErr,
-            u'top:!important': xml.dom.SyntaxErr,
-            u'top:!important;': xml.dom.SyntaxErr,
-            u'top:;': xml.dom.SyntaxErr,
-            u'top 0': xml.dom.SyntaxErr,
-            u'top 0;': xml.dom.SyntaxErr,
-
-            u':': xml.dom.SyntaxErr,
-            u':0': xml.dom.SyntaxErr,
-            u':0;': xml.dom.SyntaxErr,
-            u':0!important': xml.dom.SyntaxErr,
-            u':;': xml.dom.SyntaxErr,
-            u': ;': xml.dom.SyntaxErr,
-            u':!important;': xml.dom.SyntaxErr,
-            u': !important;': xml.dom.SyntaxErr,
-
-            u'0': xml.dom.SyntaxErr,
-            u'0!important': xml.dom.SyntaxErr,
-            u'0!important;': xml.dom.SyntaxErr,
-            u'0;': xml.dom.SyntaxErr,
-
-            u'!important': xml.dom.SyntaxErr,
-            u'!important;': xml.dom.SyntaxErr,
+            'color: #xyz': xml.dom.SyntaxErr,
+            'top': xml.dom.SyntaxErr,
+            'top:': xml.dom.SyntaxErr,
+            'top : ': xml.dom.SyntaxErr,
+            'top:!important': xml.dom.SyntaxErr,
+            'top:!important;': xml.dom.SyntaxErr,
+            'top:;': xml.dom.SyntaxErr,
+            'top 0': xml.dom.SyntaxErr,
+            'top 0;': xml.dom.SyntaxErr,
+
+            ':': xml.dom.SyntaxErr,
+            ':0': xml.dom.SyntaxErr,
+            ':0;': xml.dom.SyntaxErr,
+            ':0!important': xml.dom.SyntaxErr,
+            ':;': xml.dom.SyntaxErr,
+            ': ;': xml.dom.SyntaxErr,
+            ':!important;': xml.dom.SyntaxErr,
+            ': !important;': xml.dom.SyntaxErr,
+
+            '0': xml.dom.SyntaxErr,
+            '0!important': xml.dom.SyntaxErr,
+            '0!important;': xml.dom.SyntaxErr,
+            '0;': xml.dom.SyntaxErr,
+
+            '!important': xml.dom.SyntaxErr,
+            '!important;': xml.dom.SyntaxErr,
             }
         self.do_raise_r(tests)
 
     def test_getCssText(self):
         "CSSStyleDeclaration.getCssText(separator)"
-        s = cssutils.css.CSSStyleDeclaration(cssText=u'a:1;b:2')
-        self.assertEqual(u'a: 1;\nb: 2', s.getCssText())
-        self.assertEqual(u'a: 1;b: 2', s.getCssText(separator=u''))
-        self.assertEqual(u'a: 1;/*x*/b: 2', s.getCssText(separator=u'/*x*/'))
+        s = cssutils.css.CSSStyleDeclaration(cssText='a:1;b:2')
+        self.assertEqual('a: 1;\nb: 2', s.getCssText())
+        self.assertEqual('a: 1;b: 2', s.getCssText(separator=''))
+        self.assertEqual('a: 1;/*x*/b: 2', s.getCssText(separator='/*x*/'))
 
     def test_parentRule(self):
         "CSSStyleDeclaration.parentRule"
@@ -283,7 +283,7 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
         s.parentRule = sheet
         self.assertEqual(sheet, s.parentRule)
 
-        sheet = cssutils.parseString(u'a{x:1}')
+        sheet = cssutils.parseString('a{x:1}')
         s = sheet.cssRules[0]
         d = s.style
         self.assertEqual(s, d.parentRule)
@@ -306,35 +306,35 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
         "CSSStyleDeclaration.getProperty"
         s = cssutils.css.CSSStyleDeclaration()
         P = cssutils.css.Property
-        s.cssText = ur'''
+        s.cssText = r'''
             color: red; c\olor: blue; CO\lor: green;
             left: 1px !important; left: 0;
             border: 0;
         '''
-        self.assertEqual(s.getProperty('color').cssText, ur'co\lor: green')
-        self.assertEqual(s.getProperty(r'COLO\r').cssText, ur'co\lor: green')
-        self.assertEqual(s.getProperty('left').cssText, ur'left: 1px !important')
-        self.assertEqual(s.getProperty('border').cssText, ur'border: 0')
+        self.assertEqual(s.getProperty('color').cssText, r'co\lor: green')
+        self.assertEqual(s.getProperty(r'COLO\r').cssText, r'co\lor: green')
+        self.assertEqual(s.getProperty('left').cssText, r'left: 1px !important')
+        self.assertEqual(s.getProperty('border').cssText, r'border: 0')
 
     def test_getProperties(self):
         "CSSStyleDeclaration.getProperties()"
         s = cssutils.css.CSSStyleDeclaration(cssText=
-                                             u'/*1*/y:0;x:a !important;y:1; \\x:b;')
+                                             '/*1*/y:0;x:a !important;y:1; \\x:b;')
         tests = {
             # name, all
-            (None, False): [(u'y', u'1', u''),
-                            (u'x', u'a', u'important')],
-            (None, True): [(u'y', u'0', u''),
-                           (u'x', u'a', u'important'),
-                           (u'y', u'1', u''),
-                           (u'\\x', u'b', u'')
+            (None, False): [('y', '1', ''),
+                            ('x', 'a', 'important')],
+            (None, True): [('y', '0', ''),
+                           ('x', 'a', 'important'),
+                           ('y', '1', ''),
+                           ('\\x', 'b', '')
                            ],
-            ('x', False): [(u'x', u'a', u'important')],
-            ('\\x', False): [(u'x', u'a', u'important')],
-            ('x', True): [(u'x', u'a', u'important'),
-                           (u'\\x', u'b', u'')],
-            ('\\x', True): [(u'x', u'a', u'important'),
-                           (u'\\x', u'b', u'')],
+            ('x', False): [('x', 'a', 'important')],
+            ('\\x', False): [('x', 'a', 'important')],
+            ('x', True): [('x', 'a', 'important'),
+                           ('\\x', 'b', '')],
+            ('\\x', True): [('x', 'a', 'important'),
+                           ('\\x', 'b', '')],
             }
         for test in tests:
             name, all = test
@@ -347,16 +347,16 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
 
         # order is be effective properties set
         s = cssutils.css.CSSStyleDeclaration(cssText=
-                                             u'a:0;b:1;a:1')
-        self.assertEqual(u'ba', u''.join([p.name for p in s]))
+                                             'a:0;b:1;a:1')
+        self.assertEqual('ba', ''.join([p.name for p in s]))
 
     def test_getPropertyCSSValue(self):
         "CSSStyleDeclaration.getPropertyCSSValue()"
         s = cssutils.css.CSSStyleDeclaration(cssText='color: red;c\\olor: green')
-        self.assertEqual(u'green', s.getPropertyCSSValue('color').cssText)
-        self.assertEqual(u'green', s.getPropertyCSSValue('c\\olor').cssText)
-        self.assertEqual(u'red', s.getPropertyCSSValue('color', False).cssText)
-        self.assertEqual(u'green', s.getPropertyCSSValue('c\\olor', False).cssText)
+        self.assertEqual('green', s.getPropertyCSSValue('color').cssText)
+        self.assertEqual('green', s.getPropertyCSSValue('c\\olor').cssText)
+        self.assertEqual('red', s.getPropertyCSSValue('color', False).cssText)
+        self.assertEqual('green', s.getPropertyCSSValue('c\\olor', False).cssText)
 #        # shorthand CSSValue should be None
 #        SHORTHAND = [
 #            u'background',
@@ -378,26 +378,26 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
     def test_getPropertyValue(self):
         "CSSStyleDeclaration.getPropertyValue()"
         s = cssutils.css.CSSStyleDeclaration()
-        self.assertEqual(u'', s.getPropertyValue('unset'))
+        self.assertEqual('', s.getPropertyValue('unset'))
 
-        s.setProperty(u'left', '0')
-        self.assertEqual(u'0', s.getPropertyValue('left'))
+        s.setProperty('left', '0')
+        self.assertEqual('0', s.getPropertyValue('left'))
 
-        s.setProperty(u'border', '1px  solid  green')
-        self.assertEqual(u'1px solid green', s.getPropertyValue('border'))
+        s.setProperty('border', '1px  solid  green')
+        self.assertEqual('1px solid green', s.getPropertyValue('border'))
 
         s = cssutils.css.CSSStyleDeclaration(cssText='color: red;c\\olor: green')
-        self.assertEqual(u'green', s.getPropertyValue('color'))
-        self.assertEqual(u'green', s.getPropertyValue('c\\olor'))
-        self.assertEqual(u'red', s.getPropertyValue('color', False))
-        self.assertEqual(u'green', s.getPropertyValue('c\\olor', False))
+        self.assertEqual('green', s.getPropertyValue('color'))
+        self.assertEqual('green', s.getPropertyValue('c\\olor'))
+        self.assertEqual('red', s.getPropertyValue('color', False))
+        self.assertEqual('green', s.getPropertyValue('c\\olor', False))
 
         tests = {
-            ur'color: red; color: green': 'green',
-            ur'c\olor: red; c\olor: green': 'green',
-            ur'color: red; c\olor: green': 'green',
-            ur'color: red !important; color: green !important': 'green',
-            ur'color: green !important; color: red': 'green',
+            r'color: red; color: green': 'green',
+            r'c\olor: red; c\olor: green': 'green',
+            r'color: red; c\olor: green': 'green',
+            r'color: red !important; color: green !important': 'green',
+            r'color: green !important; color: red': 'green',
             }
         for test in tests:
             s = cssutils.css.CSSStyleDeclaration(cssText=test)
@@ -406,41 +406,41 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
     def test_getPropertyPriority(self):
         "CSSStyleDeclaration.getPropertyPriority()"
         s = cssutils.css.CSSStyleDeclaration()
-        self.assertEqual(u'', s.getPropertyPriority('unset'))
+        self.assertEqual('', s.getPropertyPriority('unset'))
 
-        s.setProperty(u'left', u'0', u'!important')
-        self.assertEqual(u'important', s.getPropertyPriority('left'))
+        s.setProperty('left', '0', '!important')
+        self.assertEqual('important', s.getPropertyPriority('left'))
 
         s = cssutils.css.CSSStyleDeclaration(cssText=
             'x: 1 !important;\\x: 2;x: 3 !important;\\x: 4')
-        self.assertEqual(u'important', s.getPropertyPriority('x'))
-        self.assertEqual(u'important', s.getPropertyPriority('\\x'))
-        self.assertEqual(u'important', s.getPropertyPriority('x', True))
-        self.assertEqual(u'', s.getPropertyPriority('\\x', False))
+        self.assertEqual('important', s.getPropertyPriority('x'))
+        self.assertEqual('important', s.getPropertyPriority('\\x'))
+        self.assertEqual('important', s.getPropertyPriority('x', True))
+        self.assertEqual('', s.getPropertyPriority('\\x', False))
 
     def test_removeProperty(self):
         "CSSStyleDeclaration.removeProperty()"
         cssutils.ser.prefs.useDefaults()
         s = cssutils.css.CSSStyleDeclaration()
-        css = ur'\x:0 !important; x:1; \x:2; x:3'
+        css = r'\x:0 !important; x:1; \x:2; x:3'
 
         # normalize=True DEFAULT
         s.cssText = css
-        self.assertEqual(u'0', s.removeProperty('x'))
-        self.assertEqual(u'', s.cssText)
+        self.assertEqual('0', s.removeProperty('x'))
+        self.assertEqual('', s.cssText)
 
         # normalize=False
         s.cssText = css
-        self.assertEqual(u'3', s.removeProperty('x', normalize=False))
-        self.assertEqual(ur'\x: 0 !important;\x: 2', s.getCssText(separator=u''))
-        self.assertEqual(u'0', s.removeProperty(r'\x', normalize=False))
-        self.assertEqual(u'', s.cssText)
+        self.assertEqual('3', s.removeProperty('x', normalize=False))
+        self.assertEqual(r'\x: 0 !important;\x: 2', s.getCssText(separator=''))
+        self.assertEqual('0', s.removeProperty(r'\x', normalize=False))
+        self.assertEqual('', s.cssText)
 
         s.cssText = css
-        self.assertEqual(u'0', s.removeProperty(r'\x', normalize=False))
-        self.assertEqual(ur'x: 1;x: 3', s.getCssText(separator=u''))
-        self.assertEqual(u'3', s.removeProperty('x', normalize=False))
-        self.assertEqual(u'', s.cssText)
+        self.assertEqual('0', s.removeProperty(r'\x', normalize=False))
+        self.assertEqual(r'x: 1;x: 3', s.getCssText(separator=''))
+        self.assertEqual('3', s.removeProperty('x', normalize=False))
+        self.assertEqual('', s.cssText)
 
     def test_setProperty(self):
         "CSSStyleDeclaration.setProperty()"
@@ -469,12 +469,12 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
         self.assertEqual('important', s.getPropertyPriority('top'))
 
         tests = {
-            (u'left', u'0', u''): u'left: 0',
-            (u'left', u'0', u'important'): u'left: 0 !important',
-            (u'LEFT', u'0', u'important'): u'left: 0 !important',
-            (u'left', u'0', u'important'): u'left: 0 !important',
+            ('left', '0', ''): 'left: 0',
+            ('left', '0', 'important'): 'left: 0 !important',
+            ('LEFT', '0', 'important'): 'left: 0 !important',
+            ('left', '0', 'important'): 'left: 0 !important',
             }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             s = cssutils.css.CSSStyleDeclaration()
             n, v, p = test
             s.setProperty(n, v, p)
@@ -511,10 +511,10 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
         s = cssutils.css.CSSStyleDeclaration()
 
         # cssText
-        s.cssText = u'left: 0'
+        s.cssText = 'left: 0'
         self.assertEqual(1, s.length)
         self.assertEqual(1, len(s.seq))
-        s.cssText = u'/*1*/left/*x*/:/*x*/0/*x*/;/*2*/ top: 1;/*3*/'
+        s.cssText = '/*1*/left/*x*/:/*x*/0/*x*/;/*2*/ top: 1;/*3*/'
         self.assertEqual(2, s.length)
         self.assertEqual(5, len(s.seq))
 
@@ -558,15 +558,15 @@ color: green;''': 'voice-family: inherit;\ncolor: green',
         self.assertEqual('green', s.getPropertyValue('color'))
         self.assertEqual('normal', s.getPropertyValue('font-style'))
         self.assertEqual(
-            u'''left: 1px;\ncolor: green;\nfont-style: normal''',
+            '''left: 1px;\ncolor: green;\nfont-style: normal''',
             s.cssText)
 
         del s.color
         self.assertEqual(
-            u'''left: 1px;\nfont-style: normal''',
+            '''left: 1px;\nfont-style: normal''',
             s.cssText)
         del s.fontStyle
-        self.assertEqual(u'left: 1px', s.cssText)
+        self.assertEqual('left: 1px', s.cssText)
 
         self.assertRaises(AttributeError, s.__setattr__, 'UNKNOWN', 'red')
         # unknown properties must be set with setProperty!
diff --git a/src/cssutils/tests/test_cssstylerule.py b/src/cssutils/tests/test_cssstylerule.py
index 2b2ac73..81815c3 100644
--- a/src/cssutils/tests/test_cssstylerule.py
+++ b/src/cssutils/tests/test_cssstylerule.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.CSSStyleRuleTestCase"""
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
 class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -16,10 +16,10 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
     def test_init(self):
         "CSSStyleRule.type and init"
         super(CSSStyleRuleTestCase, self).test_init()
-        self.assertEqual(u'', self.r.cssText)
+        self.assertEqual('', self.r.cssText)
         self.assertEqual(cssutils.css.selectorlist.SelectorList,
                          type(self.r.selectorList))
-        self.assertEqual(u'', self.r.selectorText)
+        self.assertEqual('', self.r.selectorText)
         self.assertEqual(cssutils.css.CSSStyleDeclaration,
                          type(self.r.style))
         self.assertEqual(self.r, self.r.style.parentRule)
@@ -47,15 +47,15 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
         for invalid in invalids:
             try:
                 s.cssText = invalid
-            except xml.dom.DOMException, e:
+            except xml.dom.DOMException as e:
                 pass
             self.assertEqual(sel, s.selectorList)
-            self.assertEqual(u'a', s.selectorList.selectorText)
+            self.assertEqual('a', s.selectorList.selectorText)
             self.assertEqual(style, s.style)
-            self.assertEqual(u'1', s.style.getPropertyValue('x'))
+            self.assertEqual('1', s.style.getPropertyValue('x'))
 
         # CHANGING
-        s = cssutils.parseString(u'a {s1: 1}')
+        s = cssutils.parseString('a {s1: 1}')
         r = s.cssRules[0]
         sel1 = r.selectorList
         st1 = r.style
@@ -90,7 +90,7 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertNotEqual(st1, r.style)
         self.assertEqual('s1: 2', r.style.cssText)
 
-        st2 = cssutils.parseStyle(u's2: 1')
+        st2 = cssutils.parseStyle('s2: 1')
         r.style = st2
         self.assertEqual(st2, r.style)
         self.assertEqual('s2: 1', r.style.cssText)
@@ -100,7 +100,7 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
         # fails
         try:
             r.cssText = '$ {content: "new"}'
-        except xml.dom.SyntaxErr, e:
+        except xml.dom.SyntaxErr as e:
             pass
         self.assertEqual(sl, r.selectorList)
         self.assertEqual(st, r.style)
@@ -112,8 +112,8 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
     def test_cssText(self):
         "CSSStyleRule.cssText"
         tests = {
-            u'* {}': u'',
-            u'a {}': u'',
+            '* {}': '',
+            'a {}': '',
             }
         self.do_equal_p(tests) # parse
         #self.do_equal_r(tests) # set cssText # TODO: WHY?
@@ -122,45 +122,45 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
         tests = {
             #u'''a{;display:block;float:left}''': 'a {\n    display:block;\n    float:left\n    }', # issue 28
 
-            u'''a\n{color: #000}''': 'a {\n    color: #000\n    }', # issue 4
-            u'''a\n{color: #000000}''': 'a {\n    color: #000\n    }', # issue 4
-            u'''a\n{color: #abc}''': 'a {\n    color: #abc\n    }', # issue 4
-            u'''a\n{color: #abcdef}''': 'a {\n    color: #abcdef\n    }', # issue 4
-            u'''a\n{color: #00a}''': 'a {\n    color: #00a\n    }', # issue 4
-            u'''a\n{color: #1a1a1a}''': 'a {\n    color: #1a1a1a\n    }', # issue 4
-            u'''#id\n{ color: red }''': '#id {\n    color: red\n    }', # issue 3
-            u'''* {}''': None,
-            u'a {}': None,
-            u'b { a: 1; }': u'b {\n    a: 1\n    }',
+            '''a\n{color: #000}''': 'a {\n    color: #000\n    }', # issue 4
+            '''a\n{color: #000000}''': 'a {\n    color: #000\n    }', # issue 4
+            '''a\n{color: #abc}''': 'a {\n    color: #abc\n    }', # issue 4
+            '''a\n{color: #abcdef}''': 'a {\n    color: #abcdef\n    }', # issue 4
+            '''a\n{color: #00a}''': 'a {\n    color: #00a\n    }', # issue 4
+            '''a\n{color: #1a1a1a}''': 'a {\n    color: #1a1a1a\n    }', # issue 4
+            '''#id\n{ color: red }''': '#id {\n    color: red\n    }', # issue 3
+            '''* {}''': None,
+            'a {}': None,
+            'b { a: 1; }': 'b {\n    a: 1\n    }',
             # mix of comments and properties
-            u'c1 {/*1*/a:1;}': u'c1 {\n    /*1*/\n    a: 1\n    }',
-            u'c2 {a:1;/*2*/}': u'c2 {\n    a: 1;\n    /*2*/\n    }',
-            u'd1 {/*0*/}': u'd1 {\n    /*0*/\n    }',
-            u'd2 {/*0*//*1*/}': u'd2 {\n    /*0*/\n    /*1*/\n    }',
+            'c1 {/*1*/a:1;}': 'c1 {\n    /*1*/\n    a: 1\n    }',
+            'c2 {a:1;/*2*/}': 'c2 {\n    a: 1;\n    /*2*/\n    }',
+            'd1 {/*0*/}': 'd1 {\n    /*0*/\n    }',
+            'd2 {/*0*//*1*/}': 'd2 {\n    /*0*/\n    /*1*/\n    }',
             # comments
             # TODO: spaces?
-            u'''a/*1*//*2*/,/*3*//*4*/b/*5*//*6*/{color: #000}''':
-                u'a/*1*//*2*/, /*3*//*4*/b/*5*//*6*/ {\n    color: #000\n    }',
+            '''a/*1*//*2*/,/*3*//*4*/b/*5*//*6*/{color: #000}''':
+                'a/*1*//*2*/, /*3*//*4*/b/*5*//*6*/ {\n    color: #000\n    }',
 
-            u'''a,b{color: #000}''': 'a, b {\n    color: #000\n    }', # issue 4
-            u'''a\n\r\t\f ,\n\r\t\f b\n\r\t\f {color: #000}''': 'a, b {\n    color: #000\n    }', # issue 4
+            '''a,b{color: #000}''': 'a, b {\n    color: #000\n    }', # issue 4
+            '''a\n\r\t\f ,\n\r\t\f b\n\r\t\f {color: #000}''': 'a, b {\n    color: #000\n    }', # issue 4
             }
         self.do_equal_p(tests) # parse
         self.do_equal_r(tests) # set cssText
 
         tests = {
-            u'''a;''': xml.dom.SyntaxErr,
-            u'''a {{}''': xml.dom.SyntaxErr,
-            u'''a }''': xml.dom.SyntaxErr,
+            '''a;''': xml.dom.SyntaxErr,
+            '''a {{}''': xml.dom.SyntaxErr,
+            '''a }''': xml.dom.SyntaxErr,
             }
         self.do_raise_p(tests) # parse
         tests.update({
-            u'''/*x*/''': xml.dom.SyntaxErr,
-            u'''a {''': xml.dom.SyntaxErr,
+            '''/*x*/''': xml.dom.SyntaxErr,
+            '''a {''': xml.dom.SyntaxErr,
             # trailing
-            u'''a {}x''': xml.dom.SyntaxErr,
-            u'''a {/**/''': xml.dom.SyntaxErr,
-            u'''a {} ''': xml.dom.SyntaxErr,
+            '''a {}x''': xml.dom.SyntaxErr,
+            '''a {/**/''': xml.dom.SyntaxErr,
+            '''a {} ''': xml.dom.SyntaxErr,
             })
         self.do_raise_r(tests) # set cssText
         cssutils.ser.prefs.useDefaults()
@@ -169,29 +169,29 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
         "CSSStyleRule.selectorList"
         r = cssutils.css.CSSStyleRule()
 
-        r.selectorList.appendSelector(u'a')
+        r.selectorList.appendSelector('a')
         self.assertEqual(1, r.selectorList.length)
-        self.assertEqual(u'a', r.selectorText)
+        self.assertEqual('a', r.selectorText)
 
-        r.selectorList.appendSelector(u' b  ')
+        r.selectorList.appendSelector(' b  ')
         # only simple selector!
         self.assertRaises(xml.dom.InvalidModificationErr,
-                          r.selectorList.appendSelector, u'  h1, x ')
+                          r.selectorList.appendSelector, '  h1, x ')
 
         self.assertEqual(2, r.selectorList.length)
-        self.assertEqual(u'a, b', r.selectorText)
+        self.assertEqual('a, b', r.selectorText)
 
     def test_selectorText(self):
         "CSSStyleRule.selectorText"
         r = cssutils.css.CSSStyleRule()
 
-        r.selectorText = u'a'
+        r.selectorText = 'a'
         self.assertEqual(1, r.selectorList.length)
-        self.assertEqual(u'a', r.selectorText)
+        self.assertEqual('a', r.selectorText)
 
-        r.selectorText = u' b, h1  '
+        r.selectorText = ' b, h1  '
         self.assertEqual(2, r.selectorList.length)
-        self.assertEqual(u'b, h1', r.selectorText)
+        self.assertEqual('b, h1', r.selectorText)
 
     def test_style(self):
         "CSSStyleRule.style"
@@ -206,24 +206,24 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
         "CSSStyleRule (incomplete)"
         cssutils.ser.prefs.keepEmptyRules = True
         tests = {
-            u'a {': u'a {}', # no }
-            u'a { font-family: "arial sans': # no "}
-                u'a {\n    font-family: "arial sans"\n    }',
-            u'a { font-family: "arial sans";': # no }
-                u'a {\n    font-family: "arial sans"\n    }',
-            u'''p {
+            'a {': 'a {}', # no }
+            'a { font-family: "arial sans': # no "}
+                'a {\n    font-family: "arial sans"\n    }',
+            'a { font-family: "arial sans";': # no }
+                'a {\n    font-family: "arial sans"\n    }',
+            '''p {
                 color: green;
                 font-family: 'Courier New Times
                 color: red;
                 color: green;
-                }''': u'''p {\n    color: green;\n    color: green\n    }''',
+                }''': '''p {\n    color: green;\n    color: green\n    }''',
             # no ;
-            u'''p {
+            '''p {
                 color: green;
                 font-family: 'Courier New Times'
                 color: red;
                 color: green;
-                ''': u'''p {\n    color: green;\n    color: green\n    }'''
+                ''': '''p {\n    color: green;\n    color: green\n    }'''
         }
         self.do_equal_p(tests, raising=False) # parse
         cssutils.ser.prefs.useDefaults()
@@ -234,7 +234,7 @@ class CSSStyleRuleTestCase(test_cssrule.CSSRuleTestCase):
 
     def test_reprANDstr(self):
         "CSSStyleRule.__repr__(), .__str__()"
-        sel=u'a > b + c'
+        sel='a > b + c'
 
         s = cssutils.css.CSSStyleRule(selectorText=sel)
 
diff --git a/src/cssutils/tests/test_cssstylesheet.py b/src/cssutils/tests/test_cssstylesheet.py
index b4a68f4..16dfc2d 100644
--- a/src/cssutils/tests/test_cssstylesheet.py
+++ b/src/cssutils/tests/test_cssstylesheet.py
@@ -2,7 +2,7 @@
 """Tests for css.CSSStyleSheet"""
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils.css
 
 class CSSStyleSheetTestCase(basetest.BaseTestCase):
@@ -26,7 +26,7 @@ class CSSStyleSheetTestCase(basetest.BaseTestCase):
         self.assertEqual(None, self.s.media)
         self.assertEqual(None, self.s.ownerNode)
         self.assertEqual(None, self.s.parentStyleSheet)
-        self.assertEqual(u'', self.s.title)
+        self.assertEqual('', self.s.title)
 
         # check that type is readonly
         self.assertRaises(AttributeError, self.r.__setattr__, 'href', 'x')
@@ -83,22 +83,22 @@ class CSSStyleSheetTestCase(basetest.BaseTestCase):
         # namespaces
         s = cssutils.parseString('@namespace "http://example.com/ns1"; a {}')
         namespaces = s.namespaces
-        self.assertEqual(s.namespaces.items(), [(u'', 'http://example.com/ns1')])
+        self.assertEqual(list(s.namespaces.items()), [('', 'http://example.com/ns1')])
         s.cssText = '@namespace x "http://example.com/ns2"; x|a {}'
         # not anymore!
         self.assertNotEqual(namespaces, s.namespaces)
-        self.assertEqual(s.namespaces.items(), [(u'x', 'http://example.com/ns2')])
+        self.assertEqual(list(s.namespaces.items()), [('x', 'http://example.com/ns2')])
 
         # variables
-        s = cssutils.parseString(u'@variables { a:1}')
+        s = cssutils.parseString('@variables { a:1}')
         vars1 = s.variables
-        self.assertEqual(vars1[u'a'], u'1')
+        self.assertEqual(vars1['a'], '1')
 
-        s = cssutils.parseString(u'@variables { a:2}')
+        s = cssutils.parseString('@variables { a:2}')
         vars2 = s.variables
         self.assertNotEqual(vars1, vars2)
-        self.assertEqual(vars1[u'a'], u'1')
-        self.assertEqual(vars2[u'a'], u'2')
+        self.assertEqual(vars1['a'], '1')
+        self.assertEqual(vars2['a'], '2')
 
     def test_cssRules(self):
         "CSSStyleSheet.cssRules"
@@ -110,7 +110,7 @@ class CSSStyleSheetTestCase(basetest.BaseTestCase):
         self.assertEqual(2, s.cssRules.length)
         s.cssRules.extend(cssutils.parseString('/*3*/x {y:2}').cssRules)
         self.assertEqual(4, s.cssRules.length)
-        self.assertEqual(u'a {\n    x: 1\n    }\n/*2*/\n/*3*/\nx {\n    y: 2\n    }'.encode(),
+        self.assertEqual('a {\n    x: 1\n    }\n/*2*/\n/*3*/\nx {\n    y: 2\n    }'.encode(),
                          s.cssText)
 
         for r in s.cssRules:
@@ -228,7 +228,7 @@ x|test {
         self.do_equal_p(tests)
 
         s = cssutils.css.CSSStyleSheet()
-        s.cssText = u'''@charset "ascii";@import "x";@namespace a "x";
+        s.cssText = '''@charset "ascii";@import "x";@namespace a "x";
         @media all {/*1*/}@page {margin: 0}a {\n    x: 1\n    }@unknown;/*comment*/'''
         for r in s.cssRules:
             self.assertEqual(s, r.parentStyleSheet)
@@ -237,24 +237,24 @@ x|test {
         "CSSStyleSheet.cssText HierarchyRequestErr"
         tests = {
             # @charset: only one and always 1st
-            u' @charset "utf-8";': xml.dom.HierarchyRequestErr,
-            u'@charset "ascii";@charset "ascii";': xml.dom.HierarchyRequestErr,            u'/*c*/@charset "ascii";': xml.dom.HierarchyRequestErr,
-            u'@import "x"; @charset "ascii";': xml.dom.HierarchyRequestErr,
-            u'@namespace a "x"; @charset "ascii";': xml.dom.HierarchyRequestErr,
-            u'@media all {} @charset "ascii";': xml.dom.HierarchyRequestErr,
-            u'@page {} @charset "ascii";': xml.dom.HierarchyRequestErr,
-            u'a {} @charset "ascii";': xml.dom.HierarchyRequestErr,
+            ' @charset "utf-8";': xml.dom.HierarchyRequestErr,
+            '@charset "ascii";@charset "ascii";': xml.dom.HierarchyRequestErr,            '/*c*/@charset "ascii";': xml.dom.HierarchyRequestErr,
+            '@import "x"; @charset "ascii";': xml.dom.HierarchyRequestErr,
+            '@namespace a "x"; @charset "ascii";': xml.dom.HierarchyRequestErr,
+            '@media all {} @charset "ascii";': xml.dom.HierarchyRequestErr,
+            '@page {} @charset "ascii";': xml.dom.HierarchyRequestErr,
+            'a {} @charset "ascii";': xml.dom.HierarchyRequestErr,
 
             # @import: before @namespace, @media, @page, sr
-            u'@namespace a "x"; @import "x";': xml.dom.HierarchyRequestErr,
-            u'@media all {} @import "x";': xml.dom.HierarchyRequestErr,
-            u'@page {} @import "x";': xml.dom.HierarchyRequestErr,
-            u'a {} @import "x";': xml.dom.HierarchyRequestErr,
+            '@namespace a "x"; @import "x";': xml.dom.HierarchyRequestErr,
+            '@media all {} @import "x";': xml.dom.HierarchyRequestErr,
+            '@page {} @import "x";': xml.dom.HierarchyRequestErr,
+            'a {} @import "x";': xml.dom.HierarchyRequestErr,
 
             # @namespace: before @media, @page, sr
-            u'@media all {} @namespace a "x";': xml.dom.HierarchyRequestErr,
-            u'@page {} @namespace a "x";': xml.dom.HierarchyRequestErr,
-            u'a {} @namespace a "x";': xml.dom.HierarchyRequestErr,
+            '@media all {} @namespace a "x";': xml.dom.HierarchyRequestErr,
+            '@page {} @namespace a "x";': xml.dom.HierarchyRequestErr,
+            'a {} @namespace a "x";': xml.dom.HierarchyRequestErr,
             }
         self.do_raise_r(tests)
         self.do_raise_p(tests)
@@ -265,12 +265,12 @@ x|test {
         for single {, } or ;
         """
         tests = {
-            u'{': xml.dom.SyntaxErr,
-            u'}': xml.dom.SyntaxErr,
-            u';': xml.dom.SyntaxErr,
-            u'@charset "ascii";{': xml.dom.SyntaxErr,
-            u'@charset "ascii";}': xml.dom.SyntaxErr,
-            u'@charset "ascii";;': xml.dom.SyntaxErr,
+            '{': xml.dom.SyntaxErr,
+            '}': xml.dom.SyntaxErr,
+            ';': xml.dom.SyntaxErr,
+            '@charset "ascii";{': xml.dom.SyntaxErr,
+            '@charset "ascii";}': xml.dom.SyntaxErr,
+            '@charset "ascii";;': xml.dom.SyntaxErr,
             }
         self.do_raise_r(tests)
         self.do_raise_p(tests)
@@ -304,11 +304,11 @@ x|test {
         s = cssutils.css.CSSStyleSheet()
         self.assertEqual(0, len(s.namespaces))
 
-        css = u'''@namespace "default";
+        css = '''@namespace "default";
 @namespace ex "example";
 @namespace ex2 "example";
 ex2|x { top: 0 }'''
-        expcss = u'''@namespace "default";
+        expcss = '''@namespace "default";
 @namespace ex2 "example";
 ex2|x {
     top: 0
@@ -316,7 +316,7 @@ ex2|x {
         s.cssText = css
         self.assertEqual(s.cssText, expcss.encode())
         self.assertEqual(s.namespaces.namespaces,
-                         { u'': u'default', u'ex2': u'example'})
+                         { '': 'default', 'ex2': 'example'})
 
         # __contains__
         self.assertTrue('' in s.namespaces)
@@ -341,10 +341,10 @@ ex2|x {
                           s.namespaces.__setitem__, 'ex2', 'NEWURI')
         s.namespaces['n1'] = 'new'
         self.assertEqual(s.namespaces.namespaces,
-                         { u'': u'default', u'ex2': u'example', u'n1': 'new'})
+                         { '': 'default', 'ex2': 'example', 'n1': 'new'})
         s.namespaces['n'] = 'new' # replaces prefix!
         self.assertEqual(s.namespaces.namespaces,
-                         { u'': u'default', u'ex2': u'example', u'n': 'new'})
+                         { '': 'default', 'ex2': 'example', 'n': 'new'})
         # prefixForNamespaceURI
         self.assertEqual('', s.namespaces.prefixForNamespaceURI('default'))
         self.assertEqual('ex2', s.namespaces.prefixForNamespaceURI('example'))
@@ -427,7 +427,7 @@ ex2|x {
         expcss = expcss.replace(oldsel, oldsel + ', ' + newsel)
         self.assertEqual(s.cssText, expcss.encode())
 
-        self.assertEqual(s.cssText, u'''@namespace n "new";
+        self.assertEqual(s.cssText, '''@namespace n "new";
 @namespace ex2 "example";
 @namespace DEFAULT "default";
 @media all {
@@ -443,7 +443,7 @@ ex2|SEL4, a, ex2|SELSR {
         "CSSStyleSheet.namespaces 3"
         # tests setting namespaces with new {}
         s = cssutils.css.CSSStyleSheet()
-        css = u'h|a { top: 0 }'
+        css = 'h|a { top: 0 }'
         self.assertRaises(xml.dom.NamespaceErr, s.add, css)
 
         s.add('@namespace x "html";')
@@ -460,22 +460,22 @@ ex2|SEL4, a, ex2|SELSR {
         s.namespaces['y'] = 'html'
         r.selectorList.append('y|b')
         self.assertEqual(s.cssText,
-            u'@namespace y "html";\ny|a, y|b {\n    top: 0\n    }'.encode())
+            '@namespace y "html";\ny|a, y|b {\n    top: 0\n    }'.encode())
 
         self.assertRaises(xml.dom.NoModificationAllowedErr,
                           s.namespaces.__delitem__, 'y')
         self.assertEqual(s.cssText,
-            u'@namespace y "html";\ny|a, y|b {\n    top: 0\n    }'.encode())
+            '@namespace y "html";\ny|a, y|b {\n    top: 0\n    }'.encode())
 
         s.cssRules[0].prefix = ''
         self.assertEqual(s.cssText,
-            u'@namespace "html";\na, b {\n    top: 0\n    }'.encode())
+            '@namespace "html";\na, b {\n    top: 0\n    }'.encode())
 
         # remove need of namespace
         s.cssRules[0].prefix = 'x'
         s.cssRules[1].selectorText = 'a, b'
         self.assertEqual(s.cssText,
-            u'@namespace x "html";\na, b {\n    top: 0\n    }'.encode())
+            '@namespace x "html";\na, b {\n    top: 0\n    }'.encode())
 
 
     def test_namespaces4(self):
@@ -488,13 +488,13 @@ ex2|SEL4, a, ex2|SELSR {
         self.assertEqual({}, s.namespaces.namespaces)
 
         s.namespaces[None] = 'default'
-        self.assertEqual({u'': 'default'}, s.namespaces.namespaces)
+        self.assertEqual({'': 'default'}, s.namespaces.namespaces)
 
         del s.namespaces['']
         self.assertEqual({}, s.namespaces.namespaces)
 
         s.namespaces[''] = 'default'
-        self.assertEqual({u'': 'default'}, s.namespaces.namespaces)
+        self.assertEqual({'': 'default'}, s.namespaces.namespaces)
 
         del s.namespaces[None]
         self.assertEqual({}, s.namespaces.namespaces)
@@ -502,9 +502,9 @@ ex2|SEL4, a, ex2|SELSR {
         s.namespaces['p'] = 'uri'
         # cannot use namespaces.namespaces
         del s.namespaces.namespaces['p']
-        self.assertEqual({u'p': 'uri'}, s.namespaces.namespaces)
+        self.assertEqual({'p': 'uri'}, s.namespaces.namespaces)
 
-        self.assertRaisesMsg(xml.dom.NamespaceErr, u"Prefix undefined not found.",
+        self.assertRaisesMsg(xml.dom.NamespaceErr, "Prefix undefined not found.",
                              s.namespaces.__delitem__, 'undefined')
 
     def test_namespaces5(self):
@@ -519,7 +519,7 @@ ex2|SEL4, a, ex2|SELSR {
 
     def test_deleteRuleIndex(self):
         "CSSStyleSheet.deleteRule(index)"
-        self.s.cssText = u'@charset "ascii"; @import "x"; @x; a {\n    x: 1\n    }@y;'
+        self.s.cssText = '@charset "ascii"; @import "x"; @x; a {\n    x: 1\n    }@y;'
         self.assertEqual(5, self.s.cssRules.length)
 
         self.assertRaises(xml.dom.IndexSizeErr, self.s.deleteRule, 5)
@@ -533,19 +533,19 @@ ex2|SEL4, a, ex2|SELSR {
 
         self.assertEqual(4, self.s.cssRules.length)
         self.assertEqual(
-            u'@charset "ascii";\n@import "x";\n@x;\na {\n    x: 1\n    }'.encode(), self.s.cssText)
+            '@charset "ascii";\n@import "x";\n@x;\na {\n    x: 1\n    }'.encode(), self.s.cssText)
         # beginning
         self.s.deleteRule(0)
         self.assertEqual(3, self.s.cssRules.length)
-        self.assertEqual(u'@import "x";\n@x;\na {\n    x: 1\n    }'.encode(), self.s.cssText)
+        self.assertEqual('@import "x";\n@x;\na {\n    x: 1\n    }'.encode(), self.s.cssText)
         # middle
         self.s.deleteRule(1)
         self.assertEqual(2, self.s.cssRules.length)
-        self.assertEqual(u'@import "x";\na {\n    x: 1\n    }'.encode(), self.s.cssText)
+        self.assertEqual('@import "x";\na {\n    x: 1\n    }'.encode(), self.s.cssText)
         # end
         self.s.deleteRule(1)
         self.assertEqual(1, self.s.cssRules.length)
-        self.assertEqual(u'@import "x";'.encode(), self.s.cssText)
+        self.assertEqual('@import "x";'.encode(), self.s.cssText)
 
     def test_deleteRule(self):
         "CSSStyleSheet.deleteRule(rule)"
@@ -574,14 +574,14 @@ ex2|SEL4, a, ex2|SELSR {
     def _gets(self):
         # complete
         self.cr = cssutils.css.CSSCharsetRule('ascii')
-        self.c = cssutils.css.CSSComment(u'/*c*/')
+        self.c = cssutils.css.CSSComment('/*c*/')
         self.ur = cssutils.css.CSSUnknownRule('@x;')
         self.ir = cssutils.css.CSSImportRule('x')
         self.nr = cssutils.css.CSSNamespaceRule('uri', 'p')
         self.mr = cssutils.css.CSSMediaRule()
-        self.mr.cssText = u'@media all { @m; }'
+        self.mr.cssText = '@media all { @m; }'
         self.pr = cssutils.css.CSSPageRule()
-        self.pr.style = u'margin: 0;'
+        self.pr.style = 'margin: 0;'
         self.sr = cssutils.css.CSSStyleRule()
         self.sr.cssText = 'a {\n    x: 1\n    }'
 
@@ -594,7 +594,7 @@ ex2|SEL4, a, ex2|SELSR {
         s.insertRule(self.mr) # 5
         s.insertRule(self.pr) # 6
         s.insertRule(self.sr) # 7
-        self.assertEqual(u'@charset "ascii";\n@import url(x);\n@namespace p "uri";\n@media all {\n    @m;\n    }\na {\n    x: 1\n    }\n@media all {\n    @m;\n    }\n@page {\n    margin: 0\n    }\na {\n    x: 1\n    }'.encode(), s.cssText)
+        self.assertEqual('@charset "ascii";\n@import url(x);\n@namespace p "uri";\n@media all {\n    @m;\n    }\na {\n    x: 1\n    }\n@media all {\n    @m;\n    }\n@page {\n    margin: 0\n    }\na {\n    x: 1\n    }'.encode(), s.cssText)
         return s, s.cssRules.length
 
     def test_add(self):
@@ -612,14 +612,14 @@ ex2|SEL4, a, ex2|SELSR {
                '@x;'
                ]
 
-        fullcss = u'\n'.join(css)
+        fullcss = '\n'.join(css)
         full.cssText = fullcss
         self.assertEqual(full.cssText, fullcss.encode())
         for i, line in enumerate(css):
             # sheet without same ruletype
             before = css[:i]
             after = css[i+1:]
-            sheet.cssText = u''.join(before + after)
+            sheet.cssText = ''.join(before + after)
 
             index = sheet.add(line)
             if i < 3:
@@ -631,7 +631,7 @@ ex2|SEL4, a, ex2|SELSR {
                 expected = before
                 expected.extend(after)
                 expected.append(line)
-                self.assertEqual(u'\n'.join(expected).encode(), sheet.cssText)
+                self.assertEqual('\n'.join(expected).encode(), sheet.cssText)
                 self.assertEqual(len(expected)-1, index) # no same rule present
 
             # sheet with the same ruletype
@@ -656,7 +656,7 @@ ex2|SEL4, a, ex2|SELSR {
                     expected.append(line)
                     expectedindex = len(expected) - 1
 
-                self.assertEqual(u'\n'.join(expected).encode(), full.cssText)
+                self.assertEqual('\n'.join(expected).encode(), full.cssText)
                 self.assertEqual(expectedindex, index) # no same rule present
 
     def test_addimport(self):
@@ -673,9 +673,9 @@ ex2|SEL4, a, ex2|SELSR {
             sheet.add(imp)
             added = sheet.cssRules[0]
             self.assertEqual(sheet, added.parentStyleSheet)
-            self.assertEqual(u'example.css', added.href)
-            self.assertEqual(u'utf-8', added.styleSheet.encoding)
-            self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText)
+            self.assertEqual('example.css', added.href)
+            self.assertEqual('utf-8', added.styleSheet.encoding)
+            self.assertEqual('/**/'.encode(), added.styleSheet.cssText)
 
         cssrulessheet = p.parseString('@import "example.css";')
         imports = (
@@ -689,12 +689,12 @@ ex2|SEL4, a, ex2|SELSR {
             sheet.add(imp)
             added = sheet.cssRules[1]
             self.assertEqual(sheet, added.parentStyleSheet)
-            self.assertEqual(u'example.css', added.href)
+            self.assertEqual('example.css', added.href)
             self.assertEqual(enc, added.styleSheet.encoding)
             if enc == 'ascii':
-                self.assertEqual(u'@charset "ascii";\n/**/'.encode(), added.styleSheet.cssText)
+                self.assertEqual('@charset "ascii";\n/**/'.encode(), added.styleSheet.cssText)
             else:
-                self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText)
+                self.assertEqual('/**/'.encode(), added.styleSheet.cssText)
 
         # if styleSheet is already there encoding is not set new
         impsheet = p.parseString('@import "example.css";')
@@ -703,9 +703,9 @@ ex2|SEL4, a, ex2|SELSR {
         sheet.add(imp)
         added = sheet.cssRules[1]
         self.assertEqual(sheet, added.parentStyleSheet)
-        self.assertEqual(u'example.css', added.href)
-        self.assertEqual(u'utf-8', added.styleSheet.encoding)
-        self.assertEqual(u'/**/'.encode(), added.styleSheet.cssText)
+        self.assertEqual('example.css', added.href)
+        self.assertEqual('utf-8', added.styleSheet.encoding)
+        self.assertEqual('/**/'.encode(), added.styleSheet.cssText)
 
     def test_insertRule(self):
         "CSSStyleSheet.insertRule()"
@@ -817,14 +817,14 @@ ex2|SEL4, a, ex2|SELSR {
 
     def test_HTMLComments(self):
         "CSSStyleSheet CDO CDC"
-        css = u'''body { color: red }
+        css = '''body { color: red }
 <!-- comment -->
 body { color: blue }
 body { color: pink }
 <!-- comment -->
 body { color: green }
 '''
-        exp = u'''body {
+        exp = '''body {
     color: red
     }
 body {
@@ -836,10 +836,10 @@ body {
     def test_incomplete(self):
         "CSSStyleRule (incomplete)"
         tests = {
-            u'@import "a': u'@import "a";', # no }
-            u'a { x: 1': u'a {\n    x: 1\n    }', # no }
-            u'a { font-family: "arial sans': # no "
-                u'a {\n    font-family: "arial sans"\n    }',
+            '@import "a': '@import "a";', # no }
+            'a { x: 1': 'a {\n    x: 1\n    }', # no }
+            'a { font-family: "arial sans': # no "
+                'a {\n    font-family: "arial sans"\n    }',
         }
         self.do_equal_p(tests) # parse
 
@@ -850,7 +850,7 @@ body {
         self.assertEqual(True, css._readonly) # internal...
 
         self.assertRaises(xml.dom.NoModificationAllowedErr,
-                          css._setCssText, u'@x;')
+                          css._setCssText, '@x;')
         self.assertRaises(xml.dom.NoModificationAllowedErr,
                           css.insertRule, self.rule)
         self.assertRaises(xml.dom.NoModificationAllowedErr,
diff --git a/src/cssutils/tests/test_cssunknownrule.py b/src/cssutils/tests/test_cssunknownrule.py
index 54c31aa..4343a4a 100644
--- a/src/cssutils/tests/test_cssunknownrule.py
+++ b/src/cssutils/tests/test_cssunknownrule.py
@@ -1,7 +1,7 @@
 """testcases for cssutils.css.CSSUnkownRule"""
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
 class CSSUnknownRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -23,65 +23,65 @@ class CSSUnknownRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertFalse(self.r.wellformed)
 
         # only name
-        r = cssutils.css.CSSUnknownRule(cssText=u'@init;')
-        self.assertEqual(u'@init', r.atkeyword)
-        self.assertEqual(u'@init;', r.cssText)
+        r = cssutils.css.CSSUnknownRule(cssText='@init;')
+        self.assertEqual('@init', r.atkeyword)
+        self.assertEqual('@init;', r.cssText)
         self.assertTrue(r.wellformed)
 
         # @-... not allowed?
-        r = cssutils.css.CSSUnknownRule(cssText=u'@-init;')
-        self.assertEqual(u'@-init;', r.cssText)
-        self.assertEqual(u'@-init', r.atkeyword)
+        r = cssutils.css.CSSUnknownRule(cssText='@-init;')
+        self.assertEqual('@-init;', r.cssText)
+        self.assertEqual('@-init', r.atkeyword)
         self.assertTrue(r.wellformed)
 
-        r = cssutils.css.CSSUnknownRule(cssText=u'@_w-h-a-012;')
-        self.assertEqual(u'@_w-h-a-012;', r.cssText)
-        self.assertEqual(u'@_w-h-a-012', r.atkeyword)
+        r = cssutils.css.CSSUnknownRule(cssText='@_w-h-a-012;')
+        self.assertEqual('@_w-h-a-012;', r.cssText)
+        self.assertEqual('@_w-h-a-012', r.atkeyword)
         self.assertTrue(r.wellformed)
 
         # name and content
-        r = cssutils.css.CSSUnknownRule(cssText=u'@init xxx;')
-        self.assertEqual(u'@init', r.atkeyword)
-        self.assertEqual(u'@init xxx;', r.cssText)
+        r = cssutils.css.CSSUnknownRule(cssText='@init xxx;')
+        self.assertEqual('@init', r.atkeyword)
+        self.assertEqual('@init xxx;', r.cssText)
         self.assertTrue(r.wellformed)
 
         # name and block
-        r = cssutils.css.CSSUnknownRule(cssText=u'@init { xxx }')
-        self.assertEqual(u'@init', r.atkeyword)
-        self.assertEqual(u'@init {\n    xxx\n    }', r.cssText)
+        r = cssutils.css.CSSUnknownRule(cssText='@init { xxx }')
+        self.assertEqual('@init', r.atkeyword)
+        self.assertEqual('@init {\n    xxx\n    }', r.cssText)
         self.assertTrue(r.wellformed)
 
         # name and content and block
-        r = cssutils.css.CSSUnknownRule(cssText=u'@init xxx { yyy }')
-        self.assertEqual(u'@init', r.atkeyword)
-        self.assertEqual(u'@init xxx {\n    yyy\n    }', r.cssText)
+        r = cssutils.css.CSSUnknownRule(cssText='@init xxx { yyy }')
+        self.assertEqual('@init', r.atkeyword)
+        self.assertEqual('@init xxx {\n    yyy\n    }', r.cssText)
         self.assertTrue(r.wellformed)
 
     def test_cssText(self):
         "CSSUnknownRule.cssText"
         tests = {
             # not normal rules!
-            u'@font-facex{}': u'@font-facex {\n    }',
-            u'@importurl(x.css);': u'@importurl (x . css);',
-            u'@mediaAll{}': u'@mediaall {\n    }',
-            u'@namespacep"x";': u'@namespacep "x";',
-            u'@pageX{}': u'@pagex {\n    }',
-            u'@xbottom { content: counter(page) }': u'@xbottom {\n    content: counter(page)\n    }', 
-            u'@xbottom { content: "x" counter(page) "y"}': u'@xbottom {\n    content: "x" counter(page) "y"\n    }' 
+            '@font-facex{}': '@font-facex {\n    }',
+            '@importurl(x.css);': '@importurl (x . css);',
+            '@mediaAll{}': '@mediaall {\n    }',
+            '@namespacep"x";': '@namespacep "x";',
+            '@pageX{}': '@pagex {\n    }',
+            '@xbottom { content: counter(page) }': '@xbottom {\n    content: counter(page)\n    }',
+            '@xbottom { content: "x" counter(page) "y"}': '@xbottom {\n    content: "x" counter(page) "y"\n    }'
             }
         self.do_equal_p(tests)
         
         # expects the same atkeyword for self.r so do a new one each test
         oldr = self.r
-        for t, e in tests.items():
+        for t, e in list(tests.items()):
             self.r = cssutils.css.CSSUnknownRule()
             self.do_equal_r({t:e})
         self.r = oldr
 
         tests = {
             '@x;': None,
-            '@x {}': u'@x {\n    }',
-            '@x{ \n \t \f\r}': u'@x {\n    }',
+            '@x {}': '@x {\n    }',
+            '@x{ \n \t \f\r}': '@x {\n    }',
             '@x {\n    [()]([ {\n        }]) {\n        }\n    }': None,
             '@x {\n    @b;\n    }': None,
             '''@x {
@@ -104,39 +104,39 @@ class CSSUnknownRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.do_equal_r(tests)
 
         tests = {
-                 u'@;': xml.dom.InvalidModificationErr,
-                 u'@{}': xml.dom.InvalidModificationErr,
-                 u'@ ;': xml.dom.InvalidModificationErr,
-                 u'@ {};': xml.dom.InvalidModificationErr,
+                 '@;': xml.dom.InvalidModificationErr,
+                 '@{}': xml.dom.InvalidModificationErr,
+                 '@ ;': xml.dom.InvalidModificationErr,
+                 '@ {};': xml.dom.InvalidModificationErr,
                  
-                 u'@x ;{}': xml.dom.SyntaxErr,
-                 u'@x ;;': xml.dom.SyntaxErr,
-                 u'@x }  ': xml.dom.SyntaxErr,
-                 u'@x }  ;': xml.dom.SyntaxErr,
-                 u'@x {  ': xml.dom.SyntaxErr,
-                 u'@x {  ;': xml.dom.SyntaxErr,
-                 u'@x ': xml.dom.SyntaxErr,
-                 u'@x (;': xml.dom.SyntaxErr,
-                 u'@x );': xml.dom.SyntaxErr,
-                 u'@x [;': xml.dom.SyntaxErr,
-                 u'@x ];': xml.dom.SyntaxErr,
-                 u'@x {[(]()}': xml.dom.SyntaxErr,
+                 '@x ;{}': xml.dom.SyntaxErr,
+                 '@x ;;': xml.dom.SyntaxErr,
+                 '@x }  ': xml.dom.SyntaxErr,
+                 '@x }  ;': xml.dom.SyntaxErr,
+                 '@x {  ': xml.dom.SyntaxErr,
+                 '@x {  ;': xml.dom.SyntaxErr,
+                 '@x ': xml.dom.SyntaxErr,
+                 '@x (;': xml.dom.SyntaxErr,
+                 '@x );': xml.dom.SyntaxErr,
+                 '@x [;': xml.dom.SyntaxErr,
+                 '@x ];': xml.dom.SyntaxErr,
+                 '@x {[(]()}': xml.dom.SyntaxErr,
                  # trailing
-                 u'@x{}{}': xml.dom.SyntaxErr,
-                 u'@x{};': xml.dom.SyntaxErr,
-                 u'@x{}1': xml.dom.SyntaxErr,
-                 u'@x{} ': xml.dom.SyntaxErr,
-                 u'@x{}/**/': xml.dom.SyntaxErr,
-                 u'@x;1': xml.dom.SyntaxErr,
-                 u'@x; ': xml.dom.SyntaxErr,
-                 u'@x;/**/': xml.dom.SyntaxErr,
+                 '@x{}{}': xml.dom.SyntaxErr,
+                 '@x{};': xml.dom.SyntaxErr,
+                 '@x{}1': xml.dom.SyntaxErr,
+                 '@x{} ': xml.dom.SyntaxErr,
+                 '@x{}/**/': xml.dom.SyntaxErr,
+                 '@x;1': xml.dom.SyntaxErr,
+                 '@x; ': xml.dom.SyntaxErr,
+                 '@x;/**/': xml.dom.SyntaxErr,
 
                  }
         self.do_raise_r(tests)
 
     def test_InvalidModificationErr(self):
         "CSSUnknownRule.cssText InvalidModificationErr"
-        self._test_InvalidModificationErr(u'@unknown')
+        self._test_InvalidModificationErr('@unknown')
 
     def test_reprANDstr(self):
         "CSSUnknownRule.__repr__(), .__str__()"        
diff --git a/src/cssutils/tests/test_cssutils.py b/src/cssutils/tests/test_cssutils.py
index 13c70d6..2c4f28f 100644
--- a/src/cssutils/tests/test_cssutils.py
+++ b/src/cssutils/tests/test_cssutils.py
@@ -1,8 +1,8 @@
 # -*- coding: utf-8 -*-
 """Testcases for cssutils.css.CSSCharsetRule"""
-from __future__ import with_statement
 
-import basetest
+
+from . import basetest
 import codecs
 import cssutils
 import os
@@ -14,7 +14,7 @@ try:
     import mock
 except ImportError:
     mock = None
-    print "install mock library to run all tests"
+    print("install mock library to run all tests")
 
 
 class CSSutilsTestCase(basetest.BaseTestCase):
@@ -25,7 +25,7 @@ class CSSutilsTestCase(basetest.BaseTestCase):
     def tearDown(self):
         cssutils.ser.prefs.useDefaults()
 
-    exp = u'''@import "import/import2.css";
+    exp = '''@import "import/import2.css";
 .import {
     /* ./import.css */
     background-image: url(images/example.gif)
@@ -42,9 +42,9 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         self.assertTrue(isinstance(s, cssutils.css.CSSStyleSheet))
         self.assertEqual(None, s.href)
         self.assertEqual(self.exp.encode(), s.cssText)
-        self.assertEqual(u'utf-8', s.encoding)
-        self.assertEqual(u'handheld, screen', s.media.mediaText)
-        self.assertEqual(u'from string', s.title)
+        self.assertEqual('utf-8', s.encoding)
+        self.assertEqual('handheld, screen', s.media.mediaText)
+        self.assertEqual('from string', s.title)
         self.assertEqual(self.exp.encode(), s.cssText)
 
         ir = s.cssRules[0]
@@ -65,8 +65,8 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n    /* sheets/import2.css */\n    background: url(http://example.com/images/example.gif);\n    background: url(//example.com/images/example.gif);\n    background: url(/images/example.gif);\n    background: url(images2/example.gif);\n    background: url(./images2/example.gif);\n    background: url(../images/example.gif);\n    background: url(./../images/example.gif)\n    }'.encode())
 
         tests = {
-                 'a {color: red}': u'a {\n    color: red\n    }',
-                 'a {color: rgb(1,2,3)}': u'a {\n    color: rgb(1, 2, 3)\n    }'
+                 'a {color: red}': 'a {\n    color: red\n    }',
+                 'a {color: rgb(1,2,3)}': 'a {\n    color: rgb(1, 2, 3)\n    }'
                  }
         self.do_equal_p(tests)
 
@@ -85,9 +85,9 @@ class CSSutilsTestCase(basetest.BaseTestCase):
             # normally file:/// on win and file:/ on unix
             self.assertTrue(s.href.startswith('file:/'))
         self.assertTrue(s.href.endswith('/sheets/import.css'))
-        self.assertEqual(u'utf-8', s.encoding)
-        self.assertEqual(u'screen', s.media.mediaText)
-        self.assertEqual(u'from file', s.title)
+        self.assertEqual('utf-8', s.encoding)
+        self.assertEqual('screen', s.media.mediaText)
+        self.assertEqual('from file', s.title)
         self.assertEqual(self.exp.encode(), s.cssText)
 
         ir = s.cssRules[0]
@@ -110,9 +110,9 @@ class CSSutilsTestCase(basetest.BaseTestCase):
             # normally file:/// on win and file:/ on unix
             self.assertTrue(s.href.startswith('file:/'))
         self.assertTrue(s.href.endswith('/sheets/import.css'))
-        self.assertEqual(u'utf-8', s.encoding)
-        self.assertEqual(u'screen', s.media.mediaText)
-        self.assertEqual(u'from file', s.title)
+        self.assertEqual('utf-8', s.encoding)
+        self.assertEqual('screen', s.media.mediaText)
+        self.assertEqual('from file', s.title)
         self.assertEqual(self.exp.encode(), s.cssText)
 
         ir = s.cssRules[0]
@@ -122,7 +122,7 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n    /* sheets/import2.css */\n    background: url(http://example.com/images/example.gif);\n    background: url(//example.com/images/example.gif);\n    background: url(/images/example.gif);\n    background: url(images2/example.gif);\n    background: url(./images2/example.gif);\n    background: url(../images/example.gif);\n    background: url(./../images/example.gif)\n    }'.encode())
 
         # next test
-        css = u'a:after { content: "羊蹄€\u2020" }'
+        css = 'a:after { content: "羊蹄€\u2020" }'
 
         fd, name = tempfile.mkstemp('_cssutilstest.css')
         t = os.fdopen(fd, 'wb')
@@ -140,7 +140,7 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         self.assertEqual(cssutils.css.CSSStyleSheet, type(s))
         self.assertEqual(s.cssRules[1].selectorText, 'a:after')
 
-        css = u'@charset "iso-8859-1"; a:after { content: "ä" }'
+        css = '@charset "iso-8859-1"; a:after { content: "ä" }'
         t = codecs.open(name, 'w', 'iso-8859-1')
         t.write(css)
         t.close()
@@ -158,7 +158,7 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         # clean up
         try:
             os.remove(name)
-        except OSError, e:
+        except OSError as e:
             pass
 
     def test_parseUrl(self):
@@ -173,8 +173,8 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         self.assertTrue(isinstance(s, cssutils.css.CSSStyleSheet))
         self.assertEqual(href, s.href)
         self.assertEqual(self.exp.encode(), s.cssText)
-        self.assertEqual(u'utf-8', s.encoding)
-        self.assertEqual(u'tv, print', s.media.mediaText)
+        self.assertEqual('utf-8', s.encoding)
+        self.assertEqual('tv, print', s.media.mediaText)
         self.assertEqual('from url', s.title)
 
         sr = s.cssRules[1]
@@ -182,12 +182,12 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         self.assertEqual(img, 'images/example.gif')
 
         ir = s.cssRules[0]
-        self.assertEqual(u'import/import2.css', ir.href)
+        self.assertEqual('import/import2.css', ir.href)
         irs = ir.styleSheet
         self.assertEqual(irs.cssText, '@import "../import3.css";\n@import "import-impossible.css" print;\n.import2 {\n    /* sheets/import2.css */\n    background: url(http://example.com/images/example.gif);\n    background: url(//example.com/images/example.gif);\n    background: url(/images/example.gif);\n    background: url(images2/example.gif);\n    background: url(./images2/example.gif);\n    background: url(../images/example.gif);\n    background: url(./../images/example.gif)\n    }'.encode())
 
         ir2 = irs.cssRules[0]
-        self.assertEqual(u'../import3.css', ir2.href)
+        self.assertEqual('../import3.css', ir2.href)
         irs2 = ir2.styleSheet
         self.assertEqual(irs2.cssText, '/* import3 */\n.import3 {\n    /* from ./import/../import3.css */\n    background: url(images/example3.gif);\n    background: url(./images/example3.gif);\n    background: url(import/images2/example2.gif);\n    background: url(./import/images2/example2.gif);\n    background: url(import/images2/../../images/example3.gif)\n    }'.encode())
 
@@ -212,22 +212,22 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         "cssutils.parseStyle()"
         s = cssutils.parseStyle('x:0; y:red')
         self.assertEqual(type(s), cssutils.css.CSSStyleDeclaration)
-        self.assertEqual(s.cssText,  u'x: 0;\ny: red')
+        self.assertEqual(s.cssText,  'x: 0;\ny: red')
 
         s = cssutils.parseStyle('@import "x";')
         self.assertEqual(type(s), cssutils.css.CSSStyleDeclaration)
-        self.assertEqual(s.cssText, u'')
+        self.assertEqual(s.cssText, '')
 
         tests = [
-            (u'content: "ä"', 'iso-8859-1'),
-            (u'content: "€"', 'utf-8')
+            ('content: "ä"', 'iso-8859-1'),
+            ('content: "€"', 'utf-8')
         ]
         for v, e in tests:
             s = cssutils.parseStyle(v.encode(e), encoding=e)
             self.assertEqual(s.cssText, v)
 
         self.assertRaises(UnicodeDecodeError, cssutils.parseStyle,
-                          u'content: "ä"'.encode('utf-8'), 'ascii')
+                          'content: "ä"'.encode('utf-8'), 'ascii')
 
 
     def test_getUrls(self):
@@ -253,7 +253,7 @@ class CSSutilsTestCase(basetest.BaseTestCase):
         urls = set(cssutils.getUrls(cssutils.parseString(css)))
         self.assertEqual(urls, set(["im1", "im2", "im3", "im4", "im5",
                                     "a", "b", "c",
-                                    u'f.woff', u'f.svg#f', u'f.otf']))
+                                    'f.woff', 'f.svg#f', 'f.otf']))
         cssutils.ser.prefs.keepAllProperties = False
 
     def test_replaceUrls(self):
@@ -270,21 +270,21 @@ class CSSutilsTestCase(basetest.BaseTestCase):
             }'''
         s = cssutils.parseString(css)
         cssutils.replaceUrls(s, lambda old: "NEW" + old)
-        self.assertEqual(u'@import "NEWim1";', s.cssRules[0].cssText)
-        self.assertEqual(u'NEWim2', s.cssRules[1].href)
-        self.assertEqual(u'''background-image: url(NEWc) !important;
+        self.assertEqual('@import "NEWim1";', s.cssRules[0].cssText)
+        self.assertEqual('NEWim2', s.cssRules[1].href)
+        self.assertEqual('''background-image: url(NEWc) !important;
 background-\\image: url(NEWb);
 background: url(NEWa) no-repeat !important''', s.cssRules[2].style.cssText)
 
         cssutils.ser.prefs.keepAllProperties = False
 
         # CSSStyleDeclaration
-        style = cssutils.parseStyle(u'''color: red;
+        style = cssutils.parseStyle('''color: red;
                                         background-image:
                                             url(1.png),
                                             url('2.png')''')
         cssutils.replaceUrls(style, lambda url: 'prefix/'+url)
-        self.assertEqual(style.cssText, u'''color: red;
+        self.assertEqual(style.cssText, '''color: red;
 background-image: url(prefix/1.png), url(prefix/2.png)''')
 
 
@@ -294,8 +294,8 @@ background-image: url(prefix/1.png), url(prefix/2.png)''')
             self._tempSer()
             cssutils.ser.prefs.useMinified()
 
-            a = u'@charset "iso-8859-1";@import"b.css";\xe4{color:green}'.encode('iso-8859-1')
-            b = u'@charset "ascii";\\E4 {color:red}'.encode('ascii')
+            a = '@charset "iso-8859-1";@import"b.css";\xe4{color:green}'.encode('iso-8859-1')
+            b = '@charset "ascii";\\E4 {color:red}'.encode('ascii')
 
             # normal
             m = mock.Mock()
@@ -310,11 +310,11 @@ background-image: url(prefix/1.png), url(prefix/2.png)''')
                 c = cssutils.resolveImports(s)
 
                 # py3 TODO
-                self.assertEqual(u'\xc3\xa4{color:red}\xc3\xa4{color:green}'.encode('iso-8859-1'),
+                self.assertEqual('\xc3\xa4{color:red}\xc3\xa4{color:green}'.encode('iso-8859-1'),
                                  c.cssText)
 
                 c.encoding = 'ascii'
-                self.assertEqual(ur'@charset "ascii";\E4 {color:red}\E4 {color:green}'.encode(),
+                self.assertEqual(r'@charset "ascii";\E4 {color:red}\E4 {color:green}'.encode(),
                                  c.cssText)
 
             # b cannot be found
@@ -329,12 +329,12 @@ background-image: url(prefix/1.png), url(prefix/2.png)''')
                                  type(s.cssRules[1].styleSheet))
                 c = cssutils.resolveImports(s)
                 # py3 TODO
-                self.assertEqual(u'@import"b.css";\xc3\xa4{color:green}'.encode('iso-8859-1'),
+                self.assertEqual('@import"b.css";\xc3\xa4{color:green}'.encode('iso-8859-1'),
                                  c.cssText)
 
             # @import with media
-            a = u'@import"b.css";@import"b.css" print, tv ;@import"b.css" all;'
-            b = u'a {color: red}'
+            a = '@import"b.css";@import"b.css" print, tv ;@import"b.css" all;'
+            b = 'a {color: red}'
             m = mock.Mock()
             with mock.patch('cssutils.util._defaultFetcher', m):
                 m.return_value = (None, b)
@@ -346,8 +346,8 @@ background-image: url(prefix/1.png), url(prefix/2.png)''')
                                  c.cssText)
 
             # cannot resolve with media => keep original
-            a = u'@import"b.css"print;'
-            b = u'@namespace "http://example.com";'
+            a = '@import"b.css"print;'
+            b = '@namespace "http://example.com";'
             m = mock.Mock()
             with mock.patch('cssutils.util._defaultFetcher', m):
                 m.return_value = (None, b)
@@ -362,7 +362,7 @@ background-image: url(prefix/1.png), url(prefix/2.png)''')
             # b/
             #     b.css
             #     subimg/subimg.gif
-            a = u'''
+            a = '''
                  @import"b/b.css";
                  a {
                      x: url(/img/abs.gif);
@@ -371,14 +371,14 @@ background-image: url(prefix/1.png), url(prefix/2.png)''')
                      }'''
             def fetcher(url):
                 c = {
-                     'b.css': u'''
+                     'b.css': '''
                          @import"../c.css";
                          b {
                              x: url(/img/abs.gif);
                              y: url(../img/img.gif);
                              z: url(subimg/subimg.gif);
                              }''',
-                     'c.css': u'''
+                     'c.css': '''
                          c {
                              x: url(/img/abs.gif);
                              y: url(./img/img.gif);
@@ -398,7 +398,7 @@ background-image: url(prefix/1.png), url(prefix/2.png)''')
 
             cssutils.ser.prefs.useDefaults()
             cssutils.ser.prefs.keepComments = False
-            self.assertEqual(u'''c {
+            self.assertEqual('''c {
     x: url(/img/abs.gif);
     y: url(img/img.gif);
     z: url(b/subimg/subimg.gif)
@@ -416,7 +416,7 @@ a {
 
             cssutils.ser.prefs.useDefaults()
         else:
-            self.assertEqual(False, u'Mock needed for this test')
+            self.assertEqual(False, 'Mock needed for this test')
 
 if __name__ == '__main__':
     import unittest
diff --git a/src/cssutils/tests/test_cssvariablesdeclaration.py b/src/cssutils/tests/test_cssvariablesdeclaration.py
index 4ac94e8..63d6afc 100644
--- a/src/cssutils/tests/test_cssvariablesdeclaration.py
+++ b/src/cssutils/tests/test_cssvariablesdeclaration.py
@@ -2,7 +2,7 @@
 __version__ = '$Id: test_cssstyledeclaration.py 1869 2009-10-17 19:37:40Z cthedot $'
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 
 class CSSVariablesDeclarationTestCase(basetest.BaseTestCase):
@@ -17,12 +17,12 @@ class CSSVariablesDeclarationTestCase(basetest.BaseTestCase):
     def test_init(self):
         "CSSVariablesDeclaration.__init__()"
         v = cssutils.css.CSSVariablesDeclaration()
-        self.assertEqual(u'', v.cssText)
+        self.assertEqual('', v.cssText)
         self.assertEqual(0, v.length)
         self.assertEqual(None, v.parentRule)
 
         v = cssutils.css.CSSVariablesDeclaration(cssText='x: 0')
-        self.assertEqual(u'x: 0', v.cssText)
+        self.assertEqual('x: 0', v.cssText)
         self.assertEqual('0', v.getVariableValue('x'))
 
         rule = cssutils.css.CSSVariablesRule()
@@ -50,8 +50,8 @@ class CSSVariablesDeclarationTestCase(basetest.BaseTestCase):
         self.assertEqual(value, v['x'])
         self.assertEqual(value, v.getVariableValue('x'))
 
-        self.assertEqual(u'', v['y'])
-        self.assertEqual(u'', v.getVariableValue('y'))
+        self.assertEqual('', v['y'])
+        self.assertEqual('', v.getVariableValue('y'))
 
         v['z'] = '1'
         self.assertEqual(2, v.length)
@@ -64,8 +64,8 @@ class CSSVariablesDeclarationTestCase(basetest.BaseTestCase):
         self.assertEqual(1, v.length)
         self.assertEqual(1, v.length)
 
-        self.assertEqual(u'0', v.removeVariable('x'))
-        self.assertEqual(u'', v.removeVariable('z'))
+        self.assertEqual('0', v.removeVariable('x'))
+        self.assertEqual('', v.removeVariable('z'))
         self.assertEqual(0, v.length)
 
         v.cssText = 'x:0; y:1'
@@ -73,7 +73,7 @@ class CSSVariablesDeclarationTestCase(basetest.BaseTestCase):
         # unsorted!
         for i in range(0, v.length):
             keys.append(v.item(i))
-        self.assertEqual(sorted(keys), [u'x', u'y'])
+        self.assertEqual(sorted(keys), ['x', 'y'])
 
     def test_keys(self):
         "CSSVariablesDeclaration.keys()"
@@ -84,33 +84,33 @@ class CSSVariablesDeclarationTestCase(basetest.BaseTestCase):
         "CSSVariablesDeclaration.cssText"
         # empty
         tests = {
-            u'': u'',
-            u' ': u'',
-            u' \t \n  ': u'',
-            u'x: 1': None,
-            u'x: "a"': None,
-            u'x: rgb(1, 2, 3)': None,
-            u'x: 1px 2px 3px': None,
+            '': '',
+            ' ': '',
+            ' \t \n  ': '',
+            'x: 1': None,
+            'x: "a"': None,
+            'x: rgb(1, 2, 3)': None,
+            'x: 1px 2px 3px': None,
 
-            u'x:1': u'x: 1',
-            u'x:1;': u'x: 1',
+            'x:1': 'x: 1',
+            'x:1;': 'x: 1',
 
-            u'x  :  1  ': u'x: 1',
-            u'x  :  1  ;  ': u'x: 1',
+            'x  :  1  ': 'x: 1',
+            'x  :  1  ;  ': 'x: 1',
             
-            u'x:1;y:2': u'x: 1;\ny: 2',
-            u'x:1;y:2;': u'x: 1;\ny: 2',
-            u'x  :  1  ;  y  :  2  ': u'x: 1;\ny: 2',
-            u'x  :  1  ;  y  :  2  ;  ': u'x: 1;\ny: 2',
+            'x:1;y:2': 'x: 1;\ny: 2',
+            'x:1;y:2;': 'x: 1;\ny: 2',
+            'x  :  1  ;  y  :  2  ': 'x: 1;\ny: 2',
+            'x  :  1  ;  y  :  2  ;  ': 'x: 1;\ny: 2',
             
-            u'/*x*/': u'/*x*/',
-            u'x555: 5': None,
-            u'xxx:1;yyy:2': u'xxx: 1;\nyyy: 2',
-            u'xxx : 1; yyy : 2': u'xxx: 1;\nyyy: 2',
-            u'x:1;x:2;X:2': u'x: 2',
-            u'same:1;SAME:2;': u'same: 2',
-            u'/**/x/**/:/**/1/**/;/**/y/**/:/**/2/**/': 
-                u'/**/ \n /**/ \n /**/ \n x: 1 /**/;\n/**/ \n /**/ \n /**/ \n y: 2 /**/'
+            '/*x*/': '/*x*/',
+            'x555: 5': None,
+            'xxx:1;yyy:2': 'xxx: 1;\nyyy: 2',
+            'xxx : 1; yyy : 2': 'xxx: 1;\nyyy: 2',
+            'x:1;x:2;X:2': 'x: 2',
+            'same:1;SAME:2;': 'same: 2',
+            '/**/x/**/:/**/1/**/;/**/y/**/:/**/2/**/':
+                '/**/ \n /**/ \n /**/ \n x: 1 /**/;\n/**/ \n /**/ \n /**/ \n y: 2 /**/'
             }
         self.do_equal_r(tests)
  
@@ -143,21 +143,21 @@ class CSSVariablesDeclarationTestCase(basetest.BaseTestCase):
         "CSSVariablesDeclaration.xVariable()"
         v = cssutils.css.CSSVariablesDeclaration()
         # unset
-        self.assertEqual(u'', v.getVariableValue('x'))
+        self.assertEqual('', v.getVariableValue('x'))
         # set
         v.setVariable('x', '0')
-        self.assertEqual(u'0', v.getVariableValue('x'))
-        self.assertEqual(u'0', v.getVariableValue('X'))
-        self.assertEqual(u'x: 0', v.cssText)
+        self.assertEqual('0', v.getVariableValue('x'))
+        self.assertEqual('0', v.getVariableValue('X'))
+        self.assertEqual('x: 0', v.cssText)
         v.setVariable('X', '0')
-        self.assertEqual(u'0', v.getVariableValue('x'))
-        self.assertEqual(u'0', v.getVariableValue('X'))
-        self.assertEqual(u'x: 0', v.cssText)
+        self.assertEqual('0', v.getVariableValue('x'))
+        self.assertEqual('0', v.getVariableValue('X'))
+        self.assertEqual('x: 0', v.cssText)
         # remove
-        self.assertEqual(u'0', v.removeVariable('x'))
-        self.assertEqual(u'', v.removeVariable('x'))
-        self.assertEqual(u'', v.getVariableValue('x'))
-        self.assertEqual(u'', v.cssText)
+        self.assertEqual('0', v.removeVariable('x'))
+        self.assertEqual('', v.removeVariable('x'))
+        self.assertEqual('', v.getVariableValue('x'))
+        self.assertEqual('', v.cssText)
 
 
     def test_imports(self):
@@ -245,10 +245,10 @@ class CSSVariablesDeclarationTestCase(basetest.BaseTestCase):
         self.assertEqual(s.cssRules[1].variables.length, 8)
         # but all vars in s available!
         self.assertEqual(s.variables.length, 15)
-        self.assertEqual([u'local0', u'local1', u'local2', u'local3', 
-                          u'over1-0', u'over2-0', u'over2-1', u'over2-1-0', 
-                          u'over3-0', u'over3-1', u'over3-1-0', u'over3-2', 
-                          u'over3-2-0', u'over3-2-1', u'over3-2-1-0'],
+        self.assertEqual(['local0', 'local1', 'local2', 'local3',
+                          'over1-0', 'over2-0', 'over2-1', 'over2-1-0',
+                          'over3-0', 'over3-1', 'over3-1-0', 'over3-2',
+                          'over3-2-0', 'over3-2-1', 'over3-2-1-0'],
                           sorted(s.variables.keys()))
         
         
@@ -326,7 +326,7 @@ a {
     
     def test_parentRule(self):
         "CSSVariablesDeclaration.parentRule"
-        s = cssutils.parseString(u'@variables { a:1}')
+        s = cssutils.parseString('@variables { a:1}')
         r = s.cssRules[0]
         d = r.variables 
         self.assertEqual(r, d.parentRule)
diff --git a/src/cssutils/tests/test_cssvariablesrule.py b/src/cssutils/tests/test_cssvariablesrule.py
index 5a966e0..f05795e 100644
--- a/src/cssutils/tests/test_cssvariablesrule.py
+++ b/src/cssutils/tests/test_cssvariablesrule.py
@@ -2,7 +2,7 @@
 __version__ = '$Id: test_csspagerule.py 1869 2009-10-17 19:37:40Z cthedot $'
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
 class CSSVariablesRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -26,7 +26,7 @@ class CSSVariablesRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertEqual(r, r.variables.parentRule)
 
         # until any variables
-        self.assertEqual(u'', r.cssText)
+        self.assertEqual('', r.cssText)
 
         # only possible to set @... similar name
         self.assertRaises(xml.dom.InvalidModificationErr, 
@@ -34,40 +34,40 @@ class CSSVariablesRuleTestCase(test_cssrule.CSSRuleTestCase):
 
     def test_InvalidModificationErr(self):
         "CSSVariablesRule.cssText InvalidModificationErr"
-        self._test_InvalidModificationErr(u'@variables')
+        self._test_InvalidModificationErr('@variables')
         tests = {
-            u'@var {}': xml.dom.InvalidModificationErr,
+            '@var {}': xml.dom.InvalidModificationErr,
             }
         self.do_raise_r(tests)
 
     def test_incomplete(self):
         "CSSVariablesRule (incomplete)"
         tests = {
-            u'@variables { ':
-                u'', # no } and no content
-            u'@variables { x: red':
-                u'@variables {\n    x: red\n    }', # no }
+            '@variables { ':
+                '', # no } and no content
+            '@variables { x: red':
+                '@variables {\n    x: red\n    }', # no }
         }
         self.do_equal_p(tests) # parse
 
     def test_cssText(self):
         "CSSVariablesRule"
-        EXP = u'@variables {\n    margin: 0\n    }'
+        EXP = '@variables {\n    margin: 0\n    }'
         tests = {
-             u'@variables {}': u'',
-             u'@variables     {margin:0;}': EXP,
-             u'@variables     {margin:0}': EXP,
-             u'@VaRIables {   margin    :   0   ;    }': EXP,
-            u'@\\VaRIables {    margin : 0    }': EXP,
+             '@variables {}': '',
+             '@variables     {margin:0;}': EXP,
+             '@variables     {margin:0}': EXP,
+             '@VaRIables {   margin    :   0   ;    }': EXP,
+            '@\\VaRIables {    margin : 0    }': EXP,
 
-            u'@variables {a:1;b:2}': 
-                u'@variables {\n    a: 1;\n    b: 2\n    }',
+            '@variables {a:1;b:2}':
+                '@variables {\n    a: 1;\n    b: 2\n    }',
 
             # comments
-            u'@variables   /*1*/   {margin:0;}': 
-                u'@variables /*1*/ {\n    margin: 0\n    }',
-            u'@variables/*1*/{margin:0;}': 
-                u'@variables /*1*/ {\n    margin: 0\n    }',
+            '@variables   /*1*/   {margin:0;}':
+                '@variables /*1*/ {\n    margin: 0\n    }',
+            '@variables/*1*/{margin:0;}':
+                '@variables /*1*/ {\n    margin: 0\n    }',
             }
         self.do_equal_r(tests)
         self.do_equal_p(tests)
@@ -86,30 +86,30 @@ class CSSVariablesRuleTestCase(test_cssrule.CSSRuleTestCase):
 
         # cssText
         r = cssutils.css.CSSVariablesRule()
-        r.cssText = u'@variables { x: 1 }'
+        r.cssText = '@variables { x: 1 }'
         vars1 = r.variables
         self.assertEqual(r, r.variables.parentRule)
         self.assertEqual(vars1, r.variables)
-        self.assertEqual(r.variables.cssText, u'x: 1')
-        self.assertEqual(r.cssText, u'@variables {\n    x: 1\n    }')
+        self.assertEqual(r.variables.cssText, 'x: 1')
+        self.assertEqual(r.cssText, '@variables {\n    x: 1\n    }')
         
-        r.cssText = u'@variables {y:2}'
+        r.cssText = '@variables {y:2}'
         self.assertEqual(r, r.variables.parentRule)
         self.assertNotEqual(vars1, r.variables)
-        self.assertEqual(r.variables.cssText, u'y: 2')
-        self.assertEqual(r.cssText, u'@variables {\n    y: 2\n    }')
+        self.assertEqual(r.variables.cssText, 'y: 2')
+        self.assertEqual(r.cssText, '@variables {\n    y: 2\n    }')
 
         vars2 = r.variables
         
         # fail
         try:
-            r.cssText = u'@variables {$:1}'
-        except xml.dom.DOMException, e:
+            r.cssText = '@variables {$:1}'
+        except xml.dom.DOMException as e:
             pass
 
         self.assertEqual(vars2, r.variables)
-        self.assertEqual(r.variables.cssText, u'y: 2')
-        self.assertEqual(r.cssText, u'@variables {\n    y: 2\n    }')
+        self.assertEqual(r.variables.cssText, 'y: 2')
+        self.assertEqual(r.cssText, '@variables {\n    y: 2\n    }')
 
         # var decl
         vars3 = cssutils.css.CSSVariablesDeclaration('z: 3')
@@ -117,26 +117,26 @@ class CSSVariablesRuleTestCase(test_cssrule.CSSRuleTestCase):
 
         self.assertEqual(r, r.variables.parentRule)
         self.assertEqual(vars3, r.variables)
-        self.assertEqual(r.variables.cssText, u'z: 3')
-        self.assertEqual(r.cssText, u'@variables {\n    z: 3\n    }')
+        self.assertEqual(r.variables.cssText, 'z: 3')
+        self.assertEqual(r.cssText, '@variables {\n    z: 3\n    }')
 
         # string
         r.variables = 'a: x'
         self.assertNotEqual(vars3, r.variables)
         self.assertEqual(r, r.variables.parentRule)
-        self.assertEqual(r.variables.cssText, u'a: x')
-        self.assertEqual(r.cssText, u'@variables {\n    a: x\n    }')
+        self.assertEqual(r.variables.cssText, 'a: x')
+        self.assertEqual(r.cssText, '@variables {\n    a: x\n    }')
         vars4 = r.variables
 
         # string fail
         try:
             r.variables = '$: x'
-        except xml.dom.DOMException, e:
+        except xml.dom.DOMException as e:
             pass
         self.assertEqual(vars4, r.variables)
         self.assertEqual(r, r.variables.parentRule)
-        self.assertEqual(r.variables.cssText, u'a: x')
-        self.assertEqual(r.cssText, u'@variables {\n    a: x\n    }')
+        self.assertEqual(r.variables.cssText, 'a: x')
+        self.assertEqual(r.cssText, '@variables {\n    a: x\n    }')
         
         
     def test_reprANDstr(self):
diff --git a/src/cssutils/tests/test_encutils/__init__.py b/src/cssutils/tests/test_encutils/__init__.py
index 4d0d7c9..01289d2 100644
--- a/src/cssutils/tests/test_encutils/__init__.py
+++ b/src/cssutils/tests/test_encutils/__init__.py
@@ -2,8 +2,8 @@
 """
 tests for encutils.py
 """
-import httplib
-from StringIO import StringIO
+import http.client
+from io import StringIO
 import sys
 import unittest
 
@@ -25,9 +25,9 @@ class AutoEncodingTestCase(unittest.TestCase):
             def __init__(self, content):
                 if PY2x:
                     fp = StringIO(content)
-                    self._info = httplib.HTTPMessage(fp)
+                    self._info = http.client.HTTPMessage(fp)
                 else:
-                    self._info = httplib.HTTPMessage()
+                    self._info = http.client.HTTPMessage()
                     # Adjust to testdata.
                     l = content.split(':')
                     if len(l) > 1:
@@ -60,28 +60,28 @@ class AutoEncodingTestCase(unittest.TestCase):
             'x/x': encutils._OTHER_TYPE,
             'ANYTHING': encutils._OTHER_TYPE
             }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             self.assertEqual(
                 exp, encutils._getTextTypeByMediaType(test, log=log))
 
     def test_getTextType(self):
         "encutils._getTextType"
         tests = {
-            u'\x00\x00\xFE\xFF<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
-            u'\xFF\xFE\x00\x00<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
-            u'\xFE\xFF<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
-            u'\xFF\xFE<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
-            u'\xef\xbb\xbf<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
-            u'<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
-            u'\x00\x00\xFE\xFFanything': encutils._OTHER_TYPE,
-            u'\xFF\xFE\x00\x00anything': encutils._OTHER_TYPE,
-            u'\xFE\xFFanything': encutils._OTHER_TYPE,
-            u'\xFF\xFEanything': encutils._OTHER_TYPE,
-            u'\xef\xbb\xbfanything': encutils._OTHER_TYPE,
-            u'x/x': encutils._OTHER_TYPE,
-            u'ANYTHING': encutils._OTHER_TYPE
+            '\x00\x00\xFE\xFF<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
+            '\xFF\xFE\x00\x00<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
+            '\xFE\xFF<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
+            '\xFF\xFE<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
+            '\xef\xbb\xbf<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
+            '<?xml version="1.0"': encutils._XML_APPLICATION_TYPE,
+            '\x00\x00\xFE\xFFanything': encutils._OTHER_TYPE,
+            '\xFF\xFE\x00\x00anything': encutils._OTHER_TYPE,
+            '\xFE\xFFanything': encutils._OTHER_TYPE,
+            '\xFF\xFEanything': encutils._OTHER_TYPE,
+            '\xef\xbb\xbfanything': encutils._OTHER_TYPE,
+            'x/x': encutils._OTHER_TYPE,
+            'ANYTHING': encutils._OTHER_TYPE
             }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             self.assertEqual(
                 exp, encutils._getTextType(test, log=log))
 
@@ -101,7 +101,7 @@ class AutoEncodingTestCase(unittest.TestCase):
             'text/plain': 'iso-8859-1',
             'ANYTHING': None
             }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             self.assertEqual(exp,
                              encutils.encodingByMediaType(test, log=log))
 
@@ -162,18 +162,18 @@ class AutoEncodingTestCase(unittest.TestCase):
                 <meta content="text/html;charset=ascii" http-equiv="cONTENT-type">""":
                 ('text/html', None)
             }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             self.assertEqual(exp, encutils.getMetaInfo(test, log=log))
 
     def test_detectXMLEncoding(self):
         "encutils.detectXMLEncoding"
         tests = {
             # BOM
-            ('utf_32_be'): u'\x00\x00\xFE\xFFanything',
-            ('utf_32_le'): u'\xFF\xFE\x00\x00anything',
-            ('utf_16_be'): u'\xFE\xFFanything',
-            ('utf_16_le'): u'\xFF\xFEanything',
-            ('utf-8'): u'\xef\xbb\xbfanything',
+            ('utf_32_be'): '\x00\x00\xFE\xFFanything',
+            ('utf_32_le'): '\xFF\xFE\x00\x00anything',
+            ('utf_16_be'): '\xFE\xFFanything',
+            ('utf_16_le'): '\xFF\xFEanything',
+            ('utf-8'): '\xef\xbb\xbfanything',
             # encoding=
             ('ascii'): '<?xml version="1.0" encoding="ascii" ?>',
             ('ascii'): "<?xml version='1.0' encoding='ascii' ?>",
@@ -182,7 +182,7 @@ class AutoEncodingTestCase(unittest.TestCase):
             ('utf-8'): '<?xml version="1.0" ?>',
             ('utf-8'): '<?xml version="1.0"?><x encoding="ascii"/>'
             }
-        for exp, test in tests.items():
+        for exp, test in list(tests.items()):
             self.assertEqual(exp, encutils.detectXMLEncoding(test, log=log))
 
     def test_tryEncodings(self):
@@ -190,17 +190,17 @@ class AutoEncodingTestCase(unittest.TestCase):
         try:
             import chardet
             tests = [
-                ('ascii', u'abc'.encode('ascii')),
-                ('Windows-1252', u'€'.encode('windows-1252')),
-                ('ascii', u'1'.encode('utf-8'))
+                ('ascii', 'abc'.encode('ascii')),
+                ('Windows-1252', '€'.encode('windows-1252')),
+                ('ascii', '1'.encode('utf-8'))
                 ]
         except ImportError:
             tests = [
-                ('ascii', u'abc'.encode('ascii')),
-                ('windows-1252', u'€'.encode('windows-1252')),
-                ('iso-8859-1', u'äöüß'.encode('iso-8859-1')),
-                ('iso-8859-1', u'äöüß'.encode('windows-1252')),
-                #('utf-8', u'\u1111'.encode('utf-8'))
+                ('ascii', 'abc'.encode('ascii')),
+                ('windows-1252', '€'.encode('windows-1252')),
+                ('iso-8859-1', 'äöüß'.encode('iso-8859-1')),
+                ('iso-8859-1', 'äöüß'.encode('windows-1252')),
+                #('utf-8', '\u1111'.encode('utf-8'))
                 ]
         for exp, test in tests:
             self.assertEqual(exp, encutils.tryEncodings(test))
diff --git a/src/cssutils/tests/test_errorhandler.py b/src/cssutils/tests/test_errorhandler.py
index a323e59..f2af724 100644
--- a/src/cssutils/tests/test_errorhandler.py
+++ b/src/cssutils/tests/test_errorhandler.py
@@ -2,10 +2,10 @@
 __version__ = '$Id: test_parse.py 1281 2008-06-04 21:12:29Z cthedot $'
 
 import logging
-import StringIO
+import io
 import sys
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 
 class ErrorHandlerTestCase(basetest.BaseTestCase):
@@ -27,7 +27,7 @@ class ErrorHandlerTestCase(basetest.BaseTestCase):
 
     def _setHandler(self):
         "sets new handler and returns StringIO instance to getvalue"
-        s = StringIO.StringIO()
+        s = io.StringIO()
         h = logging.StreamHandler(s)
         h.setFormatter(logging.Formatter('%(levelname)s    %(message)s'))
         # remove if present already
@@ -40,37 +40,37 @@ class ErrorHandlerTestCase(basetest.BaseTestCase):
         s = self._setHandler()
         cssutils.log.setLevel(logging.DEBUG)
         cssutils.log.debug('msg', neverraise=True)
-        self.assertEqual(s.getvalue(), u'DEBUG    msg\n')
+        self.assertEqual(s.getvalue(), 'DEBUG    msg\n')
 
         s = self._setHandler()
         cssutils.log.setLevel(logging.INFO)
         cssutils.log.info('msg', neverraise=True)
-        self.assertEqual(s.getvalue(), u'INFO    msg\n')
+        self.assertEqual(s.getvalue(), 'INFO    msg\n')
 
         s = self._setHandler()
         cssutils.log.setLevel(logging.WARNING)
         cssutils.log.warn('msg', neverraise=True)
-        self.assertEqual(s.getvalue(), u'WARNING    msg\n')
+        self.assertEqual(s.getvalue(), 'WARNING    msg\n')
 
         s = self._setHandler()
         cssutils.log.setLevel(logging.ERROR)
         cssutils.log.error('msg', neverraise=True)
-        self.assertEqual(s.getvalue(), u'ERROR    msg\n')
+        self.assertEqual(s.getvalue(), 'ERROR    msg\n')
 
         s = self._setHandler()
         cssutils.log.setLevel(logging.FATAL)
         cssutils.log.fatal('msg', neverraise=True)
-        self.assertEqual(s.getvalue(), u'CRITICAL    msg\n')
+        self.assertEqual(s.getvalue(), 'CRITICAL    msg\n')
 
         s = self._setHandler()
         cssutils.log.setLevel(logging.CRITICAL)
         cssutils.log.critical('msg', neverraise=True)
-        self.assertEqual(s.getvalue(), u'CRITICAL    msg\n')
+        self.assertEqual(s.getvalue(), 'CRITICAL    msg\n')
 
         s = self._setHandler()
         cssutils.log.setLevel(logging.CRITICAL)
         cssutils.log.error('msg', neverraise=True)
-        self.assertEqual(s.getvalue(), u'')
+        self.assertEqual(s.getvalue(), '')
 
     def test_linecol(self):
         "cssutils.log line col"
@@ -80,14 +80,14 @@ class ErrorHandlerTestCase(basetest.BaseTestCase):
         s = cssutils.css.CSSStyleSheet()
         try:
             s.cssText = '@import x;'
-        except xml.dom.DOMException, e:                
+        except xml.dom.DOMException as e:
             self.assertEqual(str(e), 'CSSImportRule: Unexpected ident. [1:9: x]')
             self.assertEqual(e.line, 1)
             self.assertEqual(e.col, 9)
             if sys.platform.startswith('java'):
-                self.assertEqual(e.msg, u'CSSImportRule: Unexpected ident. [1:9: x]')
+                self.assertEqual(e.msg, 'CSSImportRule: Unexpected ident. [1:9: x]')
             else:
-                self.assertEqual(e.args, (u'CSSImportRule: Unexpected ident. [1:9: x]',))
+                self.assertEqual(e.args, ('CSSImportRule: Unexpected ident. [1:9: x]',))
         
         cssutils.log.raiseExceptions = o
 
@@ -99,7 +99,7 @@ class ErrorHandlerTestCase(basetest.BaseTestCase):
         self.assertEqual(cssutils.log.getEffectiveLevel(), logging.FATAL)
 
         cssutils.parseString('a { color: 1 }')
-        self.assertEqual(s.getvalue(), u'')
+        self.assertEqual(s.getvalue(), '')
 
         cssutils.log.setLevel(logging.DEBUG)
         cssutils.parseString('a { color: 1 }')
@@ -107,14 +107,14 @@ class ErrorHandlerTestCase(basetest.BaseTestCase):
 #        self.assertEqual(s.getvalue(),
 #                         u'ERROR    Property: Invalid value for "CSS Color Module Level 3/CSS Level 2.1" property: 1 [1:5: color]\n')
         self.assertEqual(s.getvalue(),
-                         u'ERROR    Property: Invalid value for "CSS Level 2.1" property: 1 [1:5: color]\n')
+                         'ERROR    Property: Invalid value for "CSS Level 2.1" property: 1 [1:5: color]\n')
 
         s = self._setHandler()
 
         cssutils.log.setLevel(logging.ERROR)
         cssutils.parseUrl('http://example.com')
         self.assertEqual(s.getvalue()[:38],
-                         u'ERROR    Expected "text/css" mime type')
+                         'ERROR    Expected "text/css" mime type')
 
     def test_parsevalidation(self):
         style = 'color: 1'
diff --git a/src/cssutils/tests/test_helper.py b/src/cssutils/tests/test_helper.py
index 18eafaf..5f8e39c 100644
--- a/src/cssutils/tests/test_helper.py
+++ b/src/cssutils/tests/test_helper.py
@@ -2,21 +2,21 @@
 """Testcases for cssutils.helper"""
 __version__ = '$Id: test_util.py 1437 2008-08-18 20:30:38Z cthedot $'
 
-import basetest
+from . import basetest
 from cssutils.helper import * 
 
 class HelperTestCase(basetest.BaseTestCase):
 
     def test_normalize(self):
         "helper._normalize()"
-        tests = {u'abcdefg ABCDEFG äöüß€ AÖÜ': ur'abcdefg abcdefg äöüß€ aöü',
-                 ur'\ga\Ga\\\ ': ur'gaga\ ',
-                 ur'0123456789': ur'0123456789',
-                 ur'"\x"': ur'"x"',
+        tests = {'abcdefg ABCDEFG äöüß€ AÖÜ': r'abcdefg abcdefg äöüß€ aöü',
+                 r'\ga\Ga\\\ ': r'gaga\ ',
+                 r'0123456789': r'0123456789',
+                 r'"\x"': r'"x"',
                  # unicode escape seqs should have been done by
                  # the tokenizer...
                  }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             self.assertEqual(normalize(test), exp)
             # static too
             self.assertEqual(normalize(test), exp)
@@ -46,42 +46,42 @@ class HelperTestCase(basetest.BaseTestCase):
 
     def test_string(self):
         "helper.string()"
-        self.assertEqual(u'"x"', string(u'x'))
-        self.assertEqual(u'"1 2ä€"', string(u'1 2ä€'))
-        self.assertEqual(ur'''"'"''', string(u"'"))
-        self.assertEqual(ur'"\""', string(u'"'))
+        self.assertEqual('"x"', string('x'))
+        self.assertEqual('"1 2ä€"', string('1 2ä€'))
+        self.assertEqual(r'''"'"''', string("'"))
+        self.assertEqual(r'"\""', string('"'))
         # \n = 0xa, \r = 0xd, \f = 0xc
-        self.assertEqual(ur'"\a "', string('''
+        self.assertEqual(r'"\a "', string('''
 '''))
-        self.assertEqual(ur'"\c "', string('\f'))
-        self.assertEqual(ur'"\d "', string('\r'))
-        self.assertEqual(ur'"\d \a "', string('\r\n'))
+        self.assertEqual(r'"\c "', string('\f'))
+        self.assertEqual(r'"\d "', string('\r'))
+        self.assertEqual(r'"\d \a "', string('\r\n'))
 
     def test_stringvalue(self):
         "helper.stringvalue()"
-        self.assertEqual(u'x', stringvalue(u'"x"'))
-        self.assertEqual(u'"', stringvalue(u'"\\""'))
-        self.assertEqual(ur'x', stringvalue(ur"\x "))
+        self.assertEqual('x', stringvalue('"x"'))
+        self.assertEqual('"', stringvalue('"\\""'))
+        self.assertEqual(r'x', stringvalue(r"\x "))
         
         # escapes should have been done by tokenizer
         # so this shoule not happen at all:
-        self.assertEqual(ur'a', stringvalue(ur"\a "))
+        self.assertEqual(r'a', stringvalue(r"\a "))
 
     def test_uri(self):
         "helper.uri()"
-        self.assertEqual(u'url(x)', uri('x'))
-        self.assertEqual(u'url("(")', uri('('))
-        self.assertEqual(u'url(")")', uri(')'))
-        self.assertEqual(u'url(" ")', uri(' '))
-        self.assertEqual(u'url(";")', uri(';'))
-        self.assertEqual(u'url(",")', uri(','))
-        self.assertEqual(u'url("x)x")', uri('x)x'))
+        self.assertEqual('url(x)', uri('x'))
+        self.assertEqual('url("(")', uri('('))
+        self.assertEqual('url(")")', uri(')'))
+        self.assertEqual('url(" ")', uri(' '))
+        self.assertEqual('url(";")', uri(';'))
+        self.assertEqual('url(",")', uri(','))
+        self.assertEqual('url("x)x")', uri('x)x'))
 
     def test_urivalue(self):
         "helper.urivalue()"
-        self.assertEqual(u'x', urivalue('url(x)'))
-        self.assertEqual(u'x', urivalue('url("x")'))
-        self.assertEqual(u')', urivalue('url(")")'))
+        self.assertEqual('x', urivalue('url(x)'))
+        self.assertEqual('x', urivalue('url("x")'))
+        self.assertEqual(')', urivalue('url(")")'))
 
 
 if __name__ == '__main__':
diff --git a/src/cssutils/tests/test_marginrule.py b/src/cssutils/tests/test_marginrule.py
index 49f42b9..49446d0 100644
--- a/src/cssutils/tests/test_marginrule.py
+++ b/src/cssutils/tests/test_marginrule.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.CSSPageRule"""
 
 import xml.dom
-import test_cssrule
+from . import test_cssrule
 import cssutils
 
 class MarginRuleTestCase(test_cssrule.CSSRuleTestCase):
@@ -25,17 +25,17 @@ class MarginRuleTestCase(test_cssrule.CSSRuleTestCase):
         self.assertEqual(r.margin, None)
         self.assertEqual(r.atkeyword, None)
         self.assertEqual(r._keyword, None)
-        self.assertEqual(r.style.cssText, u'')
-        self.assertEqual(r.cssText, u'')
+        self.assertEqual(r.style.cssText, '')
+        self.assertEqual(r.cssText, '')
 
-        r = cssutils.css.MarginRule(margin=u'@TOP-left')
-        self.assertEqual(r.margin, u'@top-left')
-        self.assertEqual(r.atkeyword, u'@top-left')
-        self.assertEqual(r._keyword, u'@TOP-left')
-        self.assertEqual(r.style.cssText, u'')
-        self.assertEqual(r.cssText, u'')
+        r = cssutils.css.MarginRule(margin='@TOP-left')
+        self.assertEqual(r.margin, '@top-left')
+        self.assertEqual(r.atkeyword, '@top-left')
+        self.assertEqual(r._keyword, '@TOP-left')
+        self.assertEqual(r.style.cssText, '')
+        self.assertEqual(r.cssText, '')
         
-        self.assertRaises(xml.dom.InvalidModificationErr, cssutils.css.MarginRule, u'@x')
+        self.assertRaises(xml.dom.InvalidModificationErr, cssutils.css.MarginRule, '@x')
     
     def test_InvalidModificationErr(self):
         "MarginRule.cssText InvalidModificationErr"
@@ -50,21 +50,21 @@ class MarginRuleTestCase(test_cssrule.CSSRuleTestCase):
         "MarginRule (incomplete)"
         # must be inside @page as not valid outside
         tests = {
-            u'@page { @top-left { ': u'', # no } and no content
-            u'@page { @top-left { /*1*/ ': u'', # no } and no content
-            u'@page { @top-left { color: red':
-                u'@page {\n    @top-left {\n        color: red\n        }\n    }'
+            '@page { @top-left { ': '', # no } and no content
+            '@page { @top-left { /*1*/ ': '', # no } and no content
+            '@page { @top-left { color: red':
+                '@page {\n    @top-left {\n        color: red\n        }\n    }'
         }
         self.do_equal_p(tests) # parse
 
     def test_cssText(self):
         tests = {
-            u'@top-left {}': u'',
-            u'@top-left { /**/ }': u'',
-            u'@top-left { color: red }': u'@top-left {\n    color: red\n    }',
-            u'@top-left{color:red;}': u'@top-left {\n    color: red\n    }',
-            u'@top-left{color:red}': u'@top-left {\n    color: red\n    }',
-            u'@top-left { color: red; left: 0 }': u'@top-left {\n    color: red;\n    left: 0\n    }'
+            '@top-left {}': '',
+            '@top-left { /**/ }': '',
+            '@top-left { color: red }': '@top-left {\n    color: red\n    }',
+            '@top-left{color:red;}': '@top-left {\n    color: red\n    }',
+            '@top-left{color:red}': '@top-left {\n    color: red\n    }',
+            '@top-left { color: red; left: 0 }': '@top-left {\n    color: red;\n    left: 0\n    }'
         }
         self.do_equal_r(tests)
         
@@ -82,9 +82,9 @@ class MarginRuleTestCase(test_cssrule.CSSRuleTestCase):
         
     def test_reprANDstr(self):
         "MarginRule.__repr__(), .__str__()"
-        margin = u'@top-left'
+        margin = '@top-left'
         
-        s = cssutils.css.MarginRule(margin=margin, style=u'left: 0')
+        s = cssutils.css.MarginRule(margin=margin, style='left: 0')
         
         self.assertTrue(margin in str(s))
 
diff --git a/src/cssutils/tests/test_medialist.py b/src/cssutils/tests/test_medialist.py
index 65e934a..11ce8ff 100644
--- a/src/cssutils/tests/test_medialist.py
+++ b/src/cssutils/tests/test_medialist.py
@@ -2,7 +2,7 @@
 """Testcases for cssutils.stylesheets.MediaList"""
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils.stylesheets
 
 class MediaListTestCase(basetest.BaseTestCase):
@@ -16,11 +16,11 @@ class MediaListTestCase(basetest.BaseTestCase):
         ml = cssutils.stylesheets.MediaList()
 
         self.assertEqual(0, ml.length)
-        self.assertEqual(u'all', ml.mediaText)
+        self.assertEqual('all', ml.mediaText)
 
-        ml.mediaText = u' print   , screen '
+        ml.mediaText = ' print   , screen '
         self.assertEqual(2, ml.length)
-        self.assertEqual(u'print, screen', ml.mediaText)
+        self.assertEqual('print, screen', ml.mediaText)
         
         #self.assertRaisesMsg(xml.dom.InvalidModificationErr, 
         #                     basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), 
@@ -30,101 +30,101 @@ class MediaListTestCase(basetest.BaseTestCase):
         #self.assertEqual(1, ml.length)
 
         self.assertRaises(xml.dom.SyntaxErr,
-                          ml.appendMedium, u'test')
+                          ml.appendMedium, 'test')
 
     def test_appendMedium(self):
         "MediaList.appendMedium() 1"
         ml = cssutils.stylesheets.MediaList()
 
-        ml.appendMedium(u'print')
+        ml.appendMedium('print')
         self.assertEqual(1, ml.length)
-        self.assertEqual(u'print', ml.mediaText)
+        self.assertEqual('print', ml.mediaText)
 
-        ml.appendMedium(u'screen')
+        ml.appendMedium('screen')
         self.assertEqual(2, ml.length)
-        self.assertEqual(u'print, screen', ml.mediaText)
+        self.assertEqual('print, screen', ml.mediaText)
 
         # automatic del and append!
-        ml.appendMedium(u'print')
+        ml.appendMedium('print')
         self.assertEqual(2, ml.length)
-        self.assertEqual(u'screen, print', ml.mediaText)
+        self.assertEqual('screen, print', ml.mediaText)
 
         # automatic del and append!
-        ml.appendMedium(u'SCREEN')
+        ml.appendMedium('SCREEN')
         self.assertEqual(2, ml.length)
-        self.assertEqual(u'print, SCREEN', ml.mediaText)
+        self.assertEqual('print, SCREEN', ml.mediaText)
 
         # append invalid MediaQuery
         mq = cssutils.stylesheets.MediaQuery()
         ml.appendMedium(mq)
         self.assertEqual(2, ml.length)
-        self.assertEqual(u'print, SCREEN', ml.mediaText)
+        self.assertEqual('print, SCREEN', ml.mediaText)
         
         # append()
         mq = cssutils.stylesheets.MediaQuery('tv')
         ml.append(mq)
         self.assertEqual(3, ml.length)
-        self.assertEqual(u'print, SCREEN, tv', ml.mediaText)
+        self.assertEqual('print, SCREEN, tv', ml.mediaText)
 
         # __setitem__
         self.assertRaises(IndexError, ml.__setitem__, 10, 'all')
         ml[0] = 'handheld'
         self.assertEqual(3, ml.length)
-        self.assertEqual(u'handheld, SCREEN, tv', ml.mediaText)
+        self.assertEqual('handheld, SCREEN, tv', ml.mediaText)
 
     def test_appendAll(self):
         "MediaList.append() 2"
         ml = cssutils.stylesheets.MediaList()
-        ml.appendMedium(u'print')
-        ml.appendMedium(u'tv')
+        ml.appendMedium('print')
+        ml.appendMedium('tv')
         self.assertEqual(2, ml.length)
-        self.assertEqual(u'print, tv', ml.mediaText)
+        self.assertEqual('print, tv', ml.mediaText)
 
-        ml.appendMedium(u'all')
+        ml.appendMedium('all')
         self.assertEqual(1, ml.length)
-        self.assertEqual(u'all', ml.mediaText)
+        self.assertEqual('all', ml.mediaText)
 
         self.assertRaisesMsg(xml.dom.InvalidModificationErr, 
                              basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'tv') as already specified "all" (set ``mediaText`` instead).'''), 
                              ml.appendMedium, 'tv')
         self.assertEqual(1, ml.length)
-        self.assertEqual(u'all', ml.mediaText)
+        self.assertEqual('all', ml.mediaText)
 
-        self.assertRaises(xml.dom.SyntaxErr, ml.appendMedium, u'test')
+        self.assertRaises(xml.dom.SyntaxErr, ml.appendMedium, 'test')
 
     def test_append2All(self):
         "MediaList all"
         ml = cssutils.stylesheets.MediaList()
-        ml.appendMedium(u'all')
+        ml.appendMedium('all')
         self.assertRaisesMsg(xml.dom.InvalidModificationErr, 
                              basetest.msg3x('''MediaList: Ignoring new medium cssutils.stylesheets.MediaQuery(mediaText=u'print') as already specified "all" (set ``mediaText`` instead).'''), 
                              ml.appendMedium, 'print')
         
         sheet = cssutils.parseString('@media all, print { /**/ }')
-        self.assertEqual(u'@media all {\n    /**/\n    }'.encode(), sheet.cssText)
+        self.assertEqual('@media all {\n    /**/\n    }'.encode(), sheet.cssText)
 
     def test_delete(self):
         "MediaList.deleteMedium()"
         ml = cssutils.stylesheets.MediaList()
 
-        self.assertRaises(xml.dom.NotFoundErr, ml.deleteMedium, u'all')
-        self.assertRaises(xml.dom.NotFoundErr, ml.deleteMedium, u'test')
+        self.assertRaises(xml.dom.NotFoundErr, ml.deleteMedium, 'all')
+        self.assertRaises(xml.dom.NotFoundErr, ml.deleteMedium, 'test')
 
-        ml.appendMedium(u'print')
-        ml.deleteMedium(u'print')
-        ml.appendMedium(u'tV')
-        ml.deleteMedium(u'Tv')
+        ml.appendMedium('print')
+        ml.deleteMedium('print')
+        ml.appendMedium('tV')
+        ml.deleteMedium('Tv')
         self.assertEqual(0, ml.length)
-        self.assertEqual(u'all', ml.mediaText)
+        self.assertEqual('all', ml.mediaText)
 
     def test_item(self):
         "MediaList.item()"
         ml = cssutils.stylesheets.MediaList()
-        ml.appendMedium(u'print')
-        ml.appendMedium(u'screen')
+        ml.appendMedium('print')
+        ml.appendMedium('screen')
 
-        self.assertEqual(u'print', ml.item(0))
-        self.assertEqual(u'screen', ml.item(1))
+        self.assertEqual('print', ml.item(0))
+        self.assertEqual('screen', ml.item(1))
         self.assertEqual(None, ml.item(2))
 
     # REMOVED special case!
@@ -143,40 +143,40 @@ class MediaListTestCase(basetest.BaseTestCase):
     def test_mediaText(self):
         "MediaList.mediaText 2"
         tests = {
-            u'ALL': u'ALL',
-            u'Tv': u'Tv',
-            u'all': None,
-            u'all, handheld': u'all',
-            u'tv': None,
-            u'tv, handheld, print': None,
-            u'tv and (color), handheld and (width: 1px) and (color)': None,
+            'ALL': 'ALL',
+            'Tv': 'Tv',
+            'all': None,
+            'all, handheld': 'all',
+            'tv': None,
+            'tv, handheld, print': None,
+            'tv and (color), handheld and (width: 1px) and (color)': None,
             }
         self.do_equal_r(tests, att='mediaText')
 
         tests = {
-            u'': xml.dom.SyntaxErr,
-            u'UNKNOWN': xml.dom.SyntaxErr,
-            u'a,b': xml.dom.SyntaxErr,
-            u'a and (color)': xml.dom.SyntaxErr,
-            u'not': xml.dom.SyntaxErr, # known but need media
-            u'only': xml.dom.SyntaxErr, # known but need media
-            u'not tv,': xml.dom.SyntaxErr, # known but need media
-            u'all;': xml.dom.SyntaxErr,
-            u'all, and(color)': xml.dom.SyntaxErr,
-            u'all,': xml.dom.SyntaxErr,
-            u'all, ': xml.dom.SyntaxErr,
-            u'all ,': xml.dom.SyntaxErr,
-            u'all, /*1*/': xml.dom.SyntaxErr,
-            u'all and (color),': xml.dom.SyntaxErr,
-            u'all tv, print': xml.dom.SyntaxErr,
+            '': xml.dom.SyntaxErr,
+            'UNKNOWN': xml.dom.SyntaxErr,
+            'a,b': xml.dom.SyntaxErr,
+            'a and (color)': xml.dom.SyntaxErr,
+            'not': xml.dom.SyntaxErr, # known but need media
+            'only': xml.dom.SyntaxErr, # known but need media
+            'not tv,': xml.dom.SyntaxErr, # known but need media
+            'all;': xml.dom.SyntaxErr,
+            'all, and(color)': xml.dom.SyntaxErr,
+            'all,': xml.dom.SyntaxErr,
+            'all, ': xml.dom.SyntaxErr,
+            'all ,': xml.dom.SyntaxErr,
+            'all, /*1*/': xml.dom.SyntaxErr,
+            'all and (color),': xml.dom.SyntaxErr,
+            'all tv, print': xml.dom.SyntaxErr,
             }
         self.do_raise_r(tests, att='_setMediaText')
 
     def test_comments(self):
         "MediaList.mediaText comments"
         tests = {
-            u'/*1*/ tv /*2*/, /*3*/ handheld /*4*/, print': 
-            u'/*1*/ tv /*2*/ /*3*/, handheld /*4*/, print',
+            '/*1*/ tv /*2*/, /*3*/ handheld /*4*/, print':
+            '/*1*/ tv /*2*/ /*3*/, handheld /*4*/, print',
             }
         self.do_equal_r(tests, att='mediaText')
 
diff --git a/src/cssutils/tests/test_mediaquery.py b/src/cssutils/tests/test_mediaquery.py
index 25d6651..0399e7a 100644
--- a/src/cssutils/tests/test_mediaquery.py
+++ b/src/cssutils/tests/test_mediaquery.py
@@ -2,7 +2,7 @@
 """Testcases for cssutils.stylesheets.MediaQuery"""
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils.stylesheets
 
 class MediaQueryTestCase(basetest.BaseTestCase):
@@ -14,38 +14,38 @@ class MediaQueryTestCase(basetest.BaseTestCase):
     def test_mediaText(self):
         "MediaQuery.mediaText"
         tests = {
-            u'all': None,
-            u'braille': None,
-            u'embossed': None,
-            u'handheld': None,
-            u'print': None,
-            u'projection': None,
-            u'screen': None,
-            u'speech': None,
-            u'tty': None,
-            u'tv': None,
-            u'ALL': None,
-            u'a\\ll': None,
-            u'not tv': None,
-            u'n\\ot t\\v': None,
-            u'only tv': None,
-            u'\\only \\tv': None,
-            u'PRINT': None,
-            u'NOT PRINT': None,
-            u'ONLY PRINT': None,
-            u'tv and (color)': None,
-            u'not tv and (color)': None,
-            u'only tv and (color)': None,
-            u'print and(color)': u'print and (color)'
+            'all': None,
+            'braille': None,
+            'embossed': None,
+            'handheld': None,
+            'print': None,
+            'projection': None,
+            'screen': None,
+            'speech': None,
+            'tty': None,
+            'tv': None,
+            'ALL': None,
+            'a\\ll': None,
+            'not tv': None,
+            'n\\ot t\\v': None,
+            'only tv': None,
+            '\\only \\tv': None,
+            'PRINT': None,
+            'NOT PRINT': None,
+            'ONLY PRINT': None,
+            'tv and (color)': None,
+            'not tv and (color)': None,
+            'only tv and (color)': None,
+            'print and(color)': 'print and (color)'
             }
         self.do_equal_r(tests, att='mediaText')
 
         tests = {
-            u'': xml.dom.SyntaxErr,
-            u'two values': xml.dom.SyntaxErr,
-            u'or even three': xml.dom.SyntaxErr,
-            u'aural': xml.dom.SyntaxErr, # a dimension
-            u'3d': xml.dom.SyntaxErr, # a dimension
+            '': xml.dom.SyntaxErr,
+            'two values': xml.dom.SyntaxErr,
+            'or even three': xml.dom.SyntaxErr,
+            'aural': xml.dom.SyntaxErr, # a dimension
+            '3d': xml.dom.SyntaxErr, # a dimension
             }
         self.do_raise_r(tests, att='_setMediaText')        
 
@@ -53,7 +53,7 @@ class MediaQueryTestCase(basetest.BaseTestCase):
         "MediaQuery.mediaType"
         mq = cssutils.stylesheets.MediaQuery()
 
-        self.assertEqual(u'', mq.mediaText)
+        self.assertEqual('', mq.mediaText)
 
         for mt in cssutils.stylesheets.MediaQuery.MEDIA_TYPES:
             mq.mediaType = mt
@@ -61,7 +61,7 @@ class MediaQueryTestCase(basetest.BaseTestCase):
             mq.mediaType = mt.upper()
             self.assertEqual(mq.mediaType, mt.upper())
 
-        mt = u'3D-UNKOwn-MEDIAtype0123'
+        mt = '3D-UNKOwn-MEDIAtype0123'
         #mq.mediaType = mt
         self.assertRaises(xml.dom.SyntaxErr, mq._setMediaType, mt)
         #self.assertRaises(xml.dom.InvalidCharacterErr, mq._setMediaType, mt)
@@ -69,22 +69,22 @@ class MediaQueryTestCase(basetest.BaseTestCase):
     def test_comments(self):
         "MediaQuery.mediaText comments"
         tests = {
-            u'all': None,
-            u'print': None,
-            u'not print': None,
-            u'only print': None,
-            u'print and (color)': None,
-            u'print and (color) and (width)': None,
-            u'print and (color: 2)': None,
-            u'print and (min-width: 100px)': None,
-            u'print and (min-width: 100px) and (color: red)': None,
-            u'not print and (min-width: 100px)': None,
-            u'only print and (min-width: 100px)': None,
-            u'/*1*/ tv /*2*/': None,
-            u'/*0*/ only /*1*/ tv /*2*/': None,
-            u'/*0* /not /*1*/ tv /*2*/': None,
-            u'/*x*/ only /*x*/ print /*x*/ and /*x*/ (/*x*/ min-width /*x*/: /*x*/ 100px /*x*/)': None,
-            u'print and/*1*/(color)': u'print and /*1*/ (color)'
+            'all': None,
+            'print': None,
+            'not print': None,
+            'only print': None,
+            'print and (color)': None,
+            'print and (color) and (width)': None,
+            'print and (color: 2)': None,
+            'print and (min-width: 100px)': None,
+            'print and (min-width: 100px) and (color: red)': None,
+            'not print and (min-width: 100px)': None,
+            'only print and (min-width: 100px)': None,
+            '/*1*/ tv /*2*/': None,
+            '/*0*/ only /*1*/ tv /*2*/': None,
+            '/*0* /not /*1*/ tv /*2*/': None,
+            '/*x*/ only /*x*/ print /*x*/ and /*x*/ (/*x*/ min-width /*x*/: /*x*/ 100px /*x*/)': None,
+            'print and/*1*/(color)': 'print and /*1*/ (color)'
             }
         self.do_equal_r(tests, att='mediaText')
 
diff --git a/src/cssutils/tests/test_parse.py b/src/cssutils/tests/test_parse.py
index a0e708d..cf8ea38 100644
--- a/src/cssutils/tests/test_parse.py
+++ b/src/cssutils/tests/test_parse.py
@@ -1,19 +1,19 @@
 # -*- coding: utf-8 -*-
 """Tests for parsing which does not raise Exceptions normally"""
-from __future__ import with_statement
+
 
 
 import sys
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 
 try:
     import mock
 except ImportError:
     mock = None
-    print "install mock library to run all tests"
+    print("install mock library to run all tests")
 
 
 class CSSParserTestCase(basetest.BaseTestCase):
@@ -40,43 +40,43 @@ class CSSParserTestCase(basetest.BaseTestCase):
         # default non raising parser
         p = cssutils.CSSParser()
         s = p.parseString('$')
-        self.assertEqual(s.cssText, u''.encode())
+        self.assertEqual(s.cssText, ''.encode())
 
         # explicit raiseExceptions=False
         p = cssutils.CSSParser(raiseExceptions=False)
         s = p.parseString('$')
-        self.assertEqual(s.cssText, u''.encode())
+        self.assertEqual(s.cssText, ''.encode())
 
         # working with sheet does raise though!
-        self.assertRaises(xml.dom.DOMException, s.__setattr__, u'cssText', u'$')
+        self.assertRaises(xml.dom.DOMException, s.__setattr__, 'cssText', '$')
 
         # ----
 
         # raiseExceptions=True
         p = cssutils.CSSParser(raiseExceptions=True)
-        self.assertRaises(xml.dom.SyntaxErr, p.parseString, u'$')
+        self.assertRaises(xml.dom.SyntaxErr, p.parseString, '$')
 
         # working with a sheet does raise too
         s = cssutils.css.CSSStyleSheet()
-        self.assertRaises(xml.dom.DOMException, s.__setattr__, u'cssText', u'$')
+        self.assertRaises(xml.dom.DOMException, s.__setattr__, 'cssText', '$')
 
         # RESET cssutils.log.raiseExceptions
         cssutils.log.raiseExceptions = False
         s = cssutils.css.CSSStyleSheet()
         # does not raise!
-        s.__setattr__(u'cssText', u'$')
+        s.__setattr__('cssText', '$')
         self.assertEqual(s.cssText, ''.encode())
 
     def test_parseComments(self):
         "cssutils.CSSParser(parseComments=False)"
-        css = u'/*1*/ a { color: /*2*/ red; }'
+        css = '/*1*/ a { color: /*2*/ red; }'
 
         p = cssutils.CSSParser(parseComments=False)
         self.assertEqual(p.parseString(css).cssText,
-                         u'a {\n    color: red\n    }'.encode())
+                         'a {\n    color: red\n    }'.encode())
         p = cssutils.CSSParser(parseComments=True)
         self.assertEqual(p.parseString(css).cssText,
-                         u'/*1*/\na {\n    color: /*2*/ red\n    }'.encode())
+                         '/*1*/\na {\n    color: /*2*/ red\n    }'.encode())
 
 #    def test_parseFile(self):
 #        "CSSParser.parseFile()"
@@ -94,10 +94,10 @@ class CSSParserTestCase(basetest.BaseTestCase):
                                         media='tv,print',
                                         title='test')
                 
-            self.assertEqual(sheet.href, u'http://example.com')
-            self.assertEqual(sheet.encoding, u'utf-8')
-            self.assertEqual(sheet.media.mediaText, u'tv, print')
-            self.assertEqual(sheet.title, u'test')
+            self.assertEqual(sheet.href, 'http://example.com')
+            self.assertEqual(sheet.encoding, 'utf-8')
+            self.assertEqual(sheet.media.mediaText, 'tv, print')
+            self.assertEqual(sheet.title, 'test')
 
             # URL and content tests
             tests = {
@@ -106,20 +106,20 @@ class CSSParserTestCase(basetest.BaseTestCase):
                 ('1', None): (False, None, None),
                 ('mailto:a@bb.cd', None): (False, None, None),
                 ('http://cthedot.de/test.css', None): (False, None, None),
-                ('http://cthedot.de/test.css', ''): (True, u'utf-8', u''),
-                ('http://cthedot.de/test.css', 'a'): (True, u'utf-8', u''),
-                ('http://cthedot.de/test.css', 'a {color: red}'): (True, u'utf-8',
-                                                                 u'a {\n    color: red\n    }'),
-                ('http://cthedot.de/test.css', 'a {color: red}'): (True, u'utf-8',
-                                                                 u'a {\n    color: red\n    }'),
-                ('http://cthedot.de/test.css', '@charset "ascii";a {color: red}'): (True, u'ascii',
-                                                                 u'@charset "ascii";\na {\n    color: red\n    }'),
+                ('http://cthedot.de/test.css', ''): (True, 'utf-8', ''),
+                ('http://cthedot.de/test.css', 'a'): (True, 'utf-8', ''),
+                ('http://cthedot.de/test.css', 'a {color: red}'): (True, 'utf-8',
+                                                                 'a {\n    color: red\n    }'),
+                ('http://cthedot.de/test.css', 'a {color: red}'): (True, 'utf-8',
+                                                                 'a {\n    color: red\n    }'),
+                ('http://cthedot.de/test.css', '@charset "ascii";a {color: red}'): (True, 'ascii',
+                                                                 '@charset "ascii";\na {\n    color: red\n    }'),
             }
             override = 'iso-8859-1'
-            overrideprefix = u'@charset "iso-8859-1";'
+            overrideprefix = '@charset "iso-8859-1";'
             httpencoding = None
 
-            for (url, content), (isSheet, expencoding, cssText) in tests.items():
+            for (url, content), (isSheet, expencoding, cssText) in list(tests.items()):
                 parser.setFetcher(self._make_fetcher(httpencoding, content))
                 sheet1 = parser.parseUrl(url)
                 sheet2 = parser.parseUrl(url, encoding=override)
@@ -140,52 +140,52 @@ class CSSParserTestCase(basetest.BaseTestCase):
             parser.setFetcher(None)
 
             self.assertRaises(ValueError, parser.parseUrl, '../not-valid-in-urllib')
-            self.assertRaises(urllib2.HTTPError, parser.parseUrl, 'http://cthedot.de/not-present.css')
+            self.assertRaises(urllib.error.HTTPError, parser.parseUrl, 'http://cthedot.de/not-present.css')
 
         else:
-            self.assertEqual(False, u'Mock needed for this test')
+            self.assertEqual(False, 'Mock needed for this test')
 
     def test_parseString(self):
         "CSSParser.parseString()"
         tests = {
             # (byte) string, encoding: encoding, cssText
-            ('/*a*/', None): (u'utf-8', u'/*a*/'.encode('utf-8')),
-            ('/*a*/', 'ascii'): (u'ascii', u'@charset "ascii";\n/*a*/'.encode('ascii')),
+            ('/*a*/', None): ('utf-8', '/*a*/'.encode('utf-8')),
+            ('/*a*/', 'ascii'): ('ascii', '@charset "ascii";\n/*a*/'.encode('ascii')),
 
             # org
             #('/*\xc3\xa4*/', None): (u'utf-8', u'/*\xc3\xa4*/'.encode('utf-8')),
             #('/*\xc3\xa4*/', 'utf-8'): (u'utf-8', u'@charset "utf-8";\n/*\xc3\xa4*/'.encode('utf-8')),
             # new for 2.x and 3.x
-            (u'/*\xe4*/'.encode('utf-8'), None): (u'utf-8', u'/*\xe4*/'.encode('utf-8')),
-            (u'/*\xe4*/'.encode('utf-8'), 'utf-8'): (u'utf-8', u'@charset "utf-8";\n/*\xe4*/'.encode('utf-8')),
+            ('/*\xe4*/'.encode('utf-8'), None): ('utf-8', '/*\xe4*/'.encode('utf-8')),
+            ('/*\xe4*/'.encode('utf-8'), 'utf-8'): ('utf-8', '@charset "utf-8";\n/*\xe4*/'.encode('utf-8')),
 
-            ('@charset "ascii";/*a*/', None): (u'ascii', u'@charset "ascii";\n/*a*/'.encode('ascii')),
-            ('@charset "utf-8";/*a*/', None): (u'utf-8', u'@charset "utf-8";\n/*a*/'.encode('utf-8')),
-            ('@charset "iso-8859-1";/*a*/', None): (u'iso-8859-1', u'@charset "iso-8859-1";\n/*a*/'.encode('iso-8859-1')),
+            ('@charset "ascii";/*a*/', None): ('ascii', '@charset "ascii";\n/*a*/'.encode('ascii')),
+            ('@charset "utf-8";/*a*/', None): ('utf-8', '@charset "utf-8";\n/*a*/'.encode('utf-8')),
+            ('@charset "iso-8859-1";/*a*/', None): ('iso-8859-1', '@charset "iso-8859-1";\n/*a*/'.encode('iso-8859-1')),
 
             # unicode string, no encoding: encoding, cssText
-            (u'/*€*/', None): (
-               u'utf-8', u'/*€*/'.encode('utf-8')),
-            (u'@charset "iso-8859-1";/*ä*/', None): (
-               u'iso-8859-1', u'@charset "iso-8859-1";\n/*ä*/'.encode('iso-8859-1')),
-            (u'@charset "utf-8";/*€*/', None): (
-               u'utf-8', u'@charset "utf-8";\n/*€*/'.encode('utf-8')),
-            (u'@charset "utf-16";/**/', None): (
-               u'utf-16', u'@charset "utf-16";\n/**/'.encode('utf-16')),
+            ('/*€*/', None): (
+               'utf-8', '/*€*/'.encode('utf-8')),
+            ('@charset "iso-8859-1";/*ä*/', None): (
+               'iso-8859-1', '@charset "iso-8859-1";\n/*ä*/'.encode('iso-8859-1')),
+            ('@charset "utf-8";/*€*/', None): (
+               'utf-8', '@charset "utf-8";\n/*€*/'.encode('utf-8')),
+            ('@charset "utf-16";/**/', None): (
+               'utf-16', '@charset "utf-16";\n/**/'.encode('utf-16')),
             # unicode string, encoding utf-8: encoding, cssText
-            (u'/*€*/', 'utf-8'): ('utf-8',
-               u'@charset "utf-8";\n/*€*/'.encode('utf-8')),
-            (u'@charset "iso-8859-1";/*ä*/', 'utf-8'): (
-               u'utf-8', u'@charset "utf-8";\n/*ä*/'.encode('utf-8')),
-            (u'@charset "utf-8";/*€*/', 'utf-8'): (
-               u'utf-8', u'@charset "utf-8";\n/*€*/'.encode('utf-8')),
-            (u'@charset "utf-16";/**/', 'utf-8'): (
-               u'utf-8', u'@charset "utf-8";\n/**/'.encode('utf-8')),
+            ('/*€*/', 'utf-8'): ('utf-8',
+               '@charset "utf-8";\n/*€*/'.encode('utf-8')),
+            ('@charset "iso-8859-1";/*ä*/', 'utf-8'): (
+               'utf-8', '@charset "utf-8";\n/*ä*/'.encode('utf-8')),
+            ('@charset "utf-8";/*€*/', 'utf-8'): (
+               'utf-8', '@charset "utf-8";\n/*€*/'.encode('utf-8')),
+            ('@charset "utf-16";/**/', 'utf-8'): (
+               'utf-8', '@charset "utf-8";\n/**/'.encode('utf-8')),
             # probably not what is wanted but does not raise:
-            (u'/*€*/', 'ascii'): (
-               u'ascii', u'@charset "ascii";\n/*\\20AC */'.encode('utf-8')),
-            (u'/*€*/', 'iso-8859-1'): (
-               u'iso-8859-1', u'@charset "iso-8859-1";\n/*\\20AC */'.encode('utf-8')),
+            ('/*€*/', 'ascii'): (
+               'ascii', '@charset "ascii";\n/*\\20AC */'.encode('utf-8')),
+            ('/*€*/', 'iso-8859-1'): (
+               'iso-8859-1', '@charset "iso-8859-1";\n/*\\20AC */'.encode('utf-8')),
         }
         for test in tests:
             css, encoding = test
@@ -196,10 +196,10 @@ class CSSParserTestCase(basetest.BaseTestCase):
 
         tests = [
             # encoded css, overiding encoding
-            (u'/*€*/'.encode('utf-16'), 'utf-8'),
-            (u'/*ä*/'.encode('iso-8859-1'), 'ascii'),
-            (u'/*€*/'.encode('utf-8'), 'ascii'),
-            (u'a'.encode('ascii'), 'utf-16'),
+            ('/*€*/'.encode('utf-16'), 'utf-8'),
+            ('/*ä*/'.encode('iso-8859-1'), 'ascii'),
+            ('/*€*/'.encode('utf-8'), 'ascii'),
+            ('a'.encode('ascii'), 'utf-16'),
         ]
         for test in tests:
             #self.assertEqual(None, cssutils.parseString(css, encoding=encoding))
@@ -287,40 +287,40 @@ class CSSParserTestCase(basetest.BaseTestCase):
             #    encoding, importIndex, importEncoding, importText
 
             # 0/0 override/override => ASCII/ASCII
-            (u'@charset "utf-16"; @import "x";', 'ASCII', ('iso-8859-1',
-                                                          u'@charset "latin1";/*t*/')): (
-                 'ascii', 1, 'ascii', u'@charset "ascii";\n/*t*/'.encode()),
+            ('@charset "utf-16"; @import "x";', 'ASCII', ('iso-8859-1',
+                                                          '@charset "latin1";/*t*/')): (
+                 'ascii', 1, 'ascii', '@charset "ascii";\n/*t*/'.encode()),
             # 1/1 not tested her but same as next
             # 2/1 @charset/HTTP => UTF-16/ISO-8859-1
-            (u'@charset "UTF-16"; @import "x";', None, ('ISO-8859-1',
-                                                       u'@charset "latin1";/*t*/')): (
-                 'utf-16', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*t*/'.encode('iso-8859-1')),
+            ('@charset "UTF-16"; @import "x";', None, ('ISO-8859-1',
+                                                       '@charset "latin1";/*t*/')): (
+                 'utf-16', 1, 'iso-8859-1', '@charset "iso-8859-1";\n/*t*/'.encode('iso-8859-1')),
             # 2/2 @charset/@charset => UTF-16/ISO-8859-1
-            (u'@charset "UTF-16"; @import "x";', None, 
-                (None, u'@charset "ISO-8859-1";/*t*/')): (
-                 'utf-16', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*t*/'.encode('iso-8859-1')),
+            ('@charset "UTF-16"; @import "x";', None,
+                (None, '@charset "ISO-8859-1";/*t*/')): (
+                 'utf-16', 1, 'iso-8859-1', '@charset "iso-8859-1";\n/*t*/'.encode('iso-8859-1')),
             # 2/4 @charset/referrer => ASCII/ASCII
-            ('@charset "ASCII"; @import "x";', None, (None, u'/*t*/')): (
-                 'ascii', 1, 'ascii', u'@charset "ascii";\n/*t*/'.encode()),
+            ('@charset "ASCII"; @import "x";', None, (None, '/*t*/')): (
+                 'ascii', 1, 'ascii', '@charset "ascii";\n/*t*/'.encode()),
             # 5/5 default/default or referrer
-            ('@import "x";', None, (None, u'/*t*/')): (
-                 'utf-8', 0, 'utf-8', u'/*t*/'.encode()),
+            ('@import "x";', None, (None, '/*t*/')): (
+                 'utf-8', 0, 'utf-8', '/*t*/'.encode()),
             # 0/0 override/override+unicode
             ('@charset "utf-16"; @import "x";', 'ASCII', (
-                     None, u'@charset "latin1";/*\u0287*/')): (
-                 'ascii', 1, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()),
+                     None, '@charset "latin1";/*\u0287*/')): (
+                 'ascii', 1, 'ascii', '@charset "ascii";\n/*\\287 */'.encode()),
             # 2/1 @charset/HTTP+unicode
-            ('@charset "ascii"; @import "x";', None, ('iso-8859-1', u'/*\u0287*/')): (
-                 'ascii', 1, 'iso-8859-1', u'@charset "iso-8859-1";\n/*\\287 */'.encode()),
+            ('@charset "ascii"; @import "x";', None, ('iso-8859-1', '/*\u0287*/')): (
+                 'ascii', 1, 'iso-8859-1', '@charset "iso-8859-1";\n/*\\287 */'.encode()),
             # 2/4 @charset/referrer+unicode
-            ('@charset "ascii"; @import "x";', None, (None, u'/*\u0287*/')): (
-                 'ascii', 1, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()),
+            ('@charset "ascii"; @import "x";', None, (None, '/*\u0287*/')): (
+                 'ascii', 1, 'ascii', '@charset "ascii";\n/*\\287 */'.encode()),
             # 5/1 default/HTTP+unicode
-            ('@import "x";', None, ('ascii', u'/*\u0287*/')): (
-                 'utf-8', 0, 'ascii', u'@charset "ascii";\n/*\\287 */'.encode()),
+            ('@import "x";', None, ('ascii', '/*\u0287*/')): (
+                 'utf-8', 0, 'ascii', '@charset "ascii";\n/*\\287 */'.encode()),
             # 5/5 default+unicode/default+unicode
-            ('@import "x";', None, (None, u'/*\u0287*/')): (
-                 'utf-8', 0, 'utf-8', u'/*\u0287*/'.encode('utf-8'))
+            ('@import "x";', None, (None, '/*\u0287*/')): (
+                 'utf-8', 0, 'utf-8', '/*\u0287*/'.encode('utf-8'))
         }
         parser = cssutils.CSSParser()
         for test in tests:
@@ -350,29 +350,29 @@ class CSSParserTestCase(basetest.BaseTestCase):
 
     def test_roundtrip(self):
         "cssutils encodings"
-        css1 = ur'''@charset "utf-8";
+        css1 = r'''@charset "utf-8";
 /* ä */'''
         s = cssutils.parseString(css1)
-        css2 = unicode(s.cssText, 'utf-8')
+        css2 = str(s.cssText, 'utf-8')
         self.assertEqual(css1, css2)
 
         s = cssutils.parseString(css2)
         s.cssRules[0].encoding='ascii'
-        css3 = ur'''@charset "ascii";
+        css3 = r'''@charset "ascii";
 /* \E4  */'''
-        self.assertEqual(css3, unicode(s.cssText, 'utf-8'))
+        self.assertEqual(css3, str(s.cssText, 'utf-8'))
 
     def test_escapes(self):
         "cssutils escapes"
-        css = ur'\43\x { \43\x: \43\x !import\41nt }'
+        css = r'\43\x { \43\x: \43\x !import\41nt }'
         sheet = cssutils.parseString(css)
-        self.assertEqual(sheet.cssText, ur'''C\x {
+        self.assertEqual(sheet.cssText, r'''C\x {
     c\x: C\x !important
     }'''.encode())
 
-        css = ur'\ x{\ x :\ x ;y:1} '
+        css = r'\ x{\ x :\ x ;y:1} '
         sheet = cssutils.parseString(css)
-        self.assertEqual(sheet.cssText, ur'''\ x {
+        self.assertEqual(sheet.cssText, r'''\ x {
     \ x: \ x;
     y: 1
     }'''.encode())
@@ -381,43 +381,43 @@ class CSSParserTestCase(basetest.BaseTestCase):
         "cssutils.parseString(INVALID_STRING)"
         validfromhere = '@namespace "x";'
         csss = (
-            u'''@charset "ascii
+            '''@charset "ascii
                 ;''' + validfromhere,
-            u'''@charset 'ascii
+            '''@charset 'ascii
                 ;''' + validfromhere,
-            u'''@namespace "y
+            '''@namespace "y
                 ;''' + validfromhere,
-            u'''@import "y
+            '''@import "y
                 ;''' + validfromhere,
-            u'''@import url('a
+            '''@import url('a
                 );''' + validfromhere,
-            u'''@unknown "y
+            '''@unknown "y
                 ;''' + validfromhere)
         for css in csss:
             s = cssutils.parseString(css)
             self.assertEqual(validfromhere.encode(), s.cssText)
 
-        csss = (u'''a { font-family: "Courier
+        csss = ('''a { font-family: "Courier
                 ; }''',
-                ur'''a { content: "\"; }
+                r'''a { content: "\"; }
                 ''',
-                ur'''a { content: "\\\"; }
+                r'''a { content: "\\\"; }
                 '''
         )
         for css in csss:
-            self.assertEqual(u''.encode(), cssutils.parseString(css).cssText)
+            self.assertEqual(''.encode(), cssutils.parseString(css).cssText)
 
     def test_invalid(self):
         "cssutils.parseString(INVALID_CSS)"
         tests = {
-            u'a {color: blue}} a{color: red} a{color: green}':
-                u'''a {
+            'a {color: blue}} a{color: red} a{color: green}':
+                '''a {
     color: blue
     }
 a {
     color: green
     }''',
-            u'p @here {color: red} p {color: green}': u'p {\n    color: green\n    }'
+            'p @here {color: red} p {color: green}': 'p {\n    color: green\n    }'
             }
 
         for css in tests:
@@ -431,25 +431,25 @@ a {
         "cssutils.parseString nesting"
         # examples from csslist 27.11.2007
         tests = {
-            '@1; div{color:green}': u'div {\n    color: green\n    }',
-            '@1 []; div{color:green}': u'div {\n    color: green\n    }',
-            '@1 [{}]; div { color:green; }': u'div {\n    color: green\n    }',
+            '@1; div{color:green}': 'div {\n    color: green\n    }',
+            '@1 []; div{color:green}': 'div {\n    color: green\n    }',
+            '@1 [{}]; div { color:green; }': 'div {\n    color: green\n    }',
             '@media all { @ } div{color:green}':
-                u'div {\n    color: green\n    }',
+                'div {\n    color: green\n    }',
             # should this be u''?
-            '@1 { [ } div{color:green}': u'',
+            '@1 { [ } div{color:green}': '',
             # red was eaten:
-            '@1 { [ } ] div{color:red}div{color:green}': u'div {\n    color: green\n    }',
+            '@1 { [ } ] div{color:red}div{color:green}': 'div {\n    color: green\n    }',
              }
-        for css, exp in tests.items():
+        for css, exp in list(tests.items()):
             self.assertEqual(exp.encode(), cssutils.parseString(css).cssText)
 
     def test_specialcases(self):
         "cssutils.parseString(special_case)"
         tests = {
-            u'''
+            '''
     a[title="a not s\
-o very long title"] {/*...*/}''': u'''a[title="a not so very long title"] {
+o very long title"] {/*...*/}''': '''a[title="a not so very long title"] {
     /*...*/
     }'''
         }
diff --git a/src/cssutils/tests/test_prodparser.py b/src/cssutils/tests/test_prodparser.py
index d185f96..a73921c 100644
--- a/src/cssutils/tests/test_prodparser.py
+++ b/src/cssutils/tests/test_prodparser.py
@@ -3,7 +3,7 @@ __version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $'
 
 import sys
 import xml.dom
-import basetest
+from . import basetest
 from cssutils.prodparser import *
 from cssutils.prodparser import ParseError, Done, Exhausted, NoMatch # not in __all__
 
@@ -108,7 +108,7 @@ class SequenceTestCase(basetest.BaseTestCase):
             m = sys.maxsize
         except AttributeError:
             # py<1.6
-            m = sys.maxint
+            m = sys.maxsize
         self.assertEqual(m, s._max)
 
     def test_optional(self):
@@ -168,23 +168,23 @@ class SequenceTestCase(basetest.BaseTestCase):
             # seq: list of list of (token, prod or error msg)
             (p1, ): ([(t1, p1)],
                      [(t2, 'Extra token')], # as p1 optional
-                     [(t1, p1), (t1, u'Extra token')],
-                     [(t1, p1), (t2, u'Extra token')]
+                     [(t1, p1), (t1, 'Extra token')],
+                     [(t1, p1), (t2, 'Extra token')]
                     ),
             (p2, ): ([(t2, p2)],
-                     [(t2, p2), (t2, u'Extra token')],
-                     [(t2, p2), (t1, u'Extra token')],
+                     [(t2, p2), (t2, 'Extra token')],
+                     [(t2, p2), (t1, 'Extra token')],
                      [(t1, 'Missing token for production p2')]
                     ),
             (p1, p2): ([(t1, p1), (t2, p2)],
-                       [(t1, p1), (t1, u'Missing token for production p2')]
+                       [(t1, p1), (t1, 'Missing token for production p2')]
                        )
             }
-        for seqitems, results in tests.items():
+        for seqitems, results in list(tests.items()):
             for result in results: 
                 seq = Sequence(*seqitems)
                 for t, p in result:
-                    if isinstance(p, basestring):
+                    if isinstance(p, str):
                         self.assertRaisesMsg(ParseError, p, seq.nextProd, t)
                     else:
                         self.assertEqual(p, seq.nextProd(t))
@@ -197,29 +197,29 @@ class SequenceTestCase(basetest.BaseTestCase):
                        [(t1, p1), (t1, p1)],
                        [(t1, p1), (t1, p1), (t1, p1)],
                        [(t1, p1), (t1, p1), (t1, p1), (t1, p1)],
-                       [(t1, p1), (t1, p1), (t1, p1), (t1, p1), (t1, u'Extra token')],
+                       [(t1, p1), (t1, p1), (t1, p1), (t1, p1), (t1, 'Extra token')],
                      ),
             (p1, ): ([(t1, p1)],
                      [(t2, 'Extra token')], 
                      [(t1, p1), (t1, p1)],
                      [(t1, p1), (t2, 'Extra token')],
-                     [(t1, p1), (t1, p1), (t1, u'Extra token')],
-                     [(t1, p1), (t1, p1), (t2, u'Extra token')]
+                     [(t1, p1), (t1, p1), (t1, 'Extra token')],
+                     [(t1, p1), (t1, p1), (t2, 'Extra token')]
                     ),
             # as p2 NOT optional
             (p2, ): ([(t2, p2)],
                      [(t1, 'Missing token for production p2')],
                      [(t2, p2), (t2, p2)],
-                     [(t2, p2), (t1, u'No match for (1, 0, 0, 0) in Sequence(p2)')],
-                     [(t2, p2), (t2, p2), (t2, u'Extra token')],
-                     [(t2, p2), (t2, p2), (t1, u'Extra token')]
+                     [(t2, p2), (t1, 'No match for (1, 0, 0, 0) in Sequence(p2)')],
+                     [(t2, p2), (t2, p2), (t2, 'Extra token')],
+                     [(t2, p2), (t2, p2), (t1, 'Extra token')]
                     ),
-            (p1, p2): ([(t1, p1), (t1, u'Missing token for production p2')],
+            (p1, p2): ([(t1, p1), (t1, 'Missing token for production p2')],
                        [(t2, p2), (t2, p2)],
                        [(t2, p2), (t1, p1), (t2, p2)],
                        [(t1, p1), (t2, p2), (t2, p2)],
                        [(t1, p1), (t2, p2), (t1, p1), (t2, p2)],
-                       [(t2, p2), (t2, p2), (t2, u'Extra token')],
+                       [(t2, p2), (t2, p2), (t2, 'Extra token')],
                        [(t2, p2), (t1, p1), (t2, p2), (t1, 'Extra token')],
                        [(t2, p2), (t1, p1), (t2, p2), (t2, 'Extra token')],
                        [(t1, p1), (t2, p2), (t2, p2), (t1, 'Extra token')],
@@ -228,11 +228,11 @@ class SequenceTestCase(basetest.BaseTestCase):
                        [(t1, p1), (t2, p2), (t1, p1), (t2, p2), (t2, 'Extra token')],
                        )
             }
-        for seqitems, results in tests.items():
+        for seqitems, results in list(tests.items()):
             for result in results: 
                 seq = Sequence(minmax=lambda: (1,2), *seqitems)
                 for t, p in result:
-                    if isinstance(p, basestring):
+                    if isinstance(p, str):
                         self.assertRaisesMsg(ParseError, p, seq.nextProd, t)
                     else:
                         self.assertEqual(p, seq.nextProd(t))
@@ -249,22 +249,22 @@ class ChoiceTestCase(basetest.BaseTestCase):
         t2 = (2,0,0,0)
             
         ch = Choice(p1, p2)
-        self.assertRaisesMsg(ParseError, u'No match for (0, 0, 0, 0) in Choice(p1, p2)', ch.nextProd, t0)
+        self.assertRaisesMsg(ParseError, 'No match for (0, 0, 0, 0) in Choice(p1, p2)', ch.nextProd, t0)
         self.assertEqual(p1, ch.nextProd(t1))
-        self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1)
+        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
 
         ch = Choice(p1, p2)
         self.assertEqual(p2, ch.nextProd(t2))
-        self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t2)
+        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t2)
 
         ch = Choice(p2, p1)
         self.assertRaisesMsg(ParseError, 'No match for (0, 0, 0, 0) in Choice(p2, p1)', ch.nextProd, t0)
         self.assertEqual(p1, ch.nextProd(t1))
-        self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1)
+        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
 
         ch = Choice(p2, p1)
         self.assertEqual(p2, ch.nextProd(t2))
-        self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t2)
+        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t2)
 
     def test_matches(self):
         "Choice.matches()"
@@ -296,13 +296,13 @@ class ChoiceTestCase(basetest.BaseTestCase):
         t2 = (2,0,0,0)
 
         ch = Choice(s1, s2)
-        self.assertRaisesMsg(ParseError, u'No match for (0, 0, 0, 0) in Choice(Sequence(p1, p1), Sequence(p2, p2))', ch.nextProd, t0)
+        self.assertRaisesMsg(ParseError, 'No match for (0, 0, 0, 0) in Choice(Sequence(p1, p1), Sequence(p2, p2))', ch.nextProd, t0)
         self.assertEqual(s1, ch.nextProd(t1))
-        self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1)
+        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
             
         ch = Choice(s1, s2)
         self.assertEqual(s2, ch.nextProd(t2))
-        self.assertRaisesMsg(Exhausted, u'Extra token', ch.nextProd, t1)
+        self.assertRaisesMsg(Exhausted, 'Extra token', ch.nextProd, t1)
 
     def test_reset(self):    
         "Choice.reset()"
@@ -327,8 +327,8 @@ class ProdParserTestCase(basetest.BaseTestCase):
         p = ProdParser()
             
         # text, name, productions, store=None
-        prods = lambda: Sequence(PreDef.char(';', u';'),
-                                 PreDef.char(':', u':')
+        prods = lambda: Sequence(PreDef.char(';', ';'),
+                                 PreDef.char(':', ':')
                                  )       
         
         w, seq, store, unused = p.parse('; :', 'test', prods(), 
@@ -358,14 +358,14 @@ class ProdParserTestCase(basetest.BaseTestCase):
                  '3 x': "No match: ('IDENT', 'x', 1, 3)",
                  '3 3': "No match: ('NUMBER', '3', 1, 3)",
                  }
-        for text, exp in tests.items():
+        for text, exp in list(tests.items()):
             prods = Choice(Sequence(p1, p2, minmax=lambda: (1,2)),
                            p3)
             if exp is True:
                 wellformed, seq, store, unused = ProdParser().parse(text, 'T', prods)
                 self.assertEqual(wellformed, exp)
             else:
-                self.assertRaisesMsg(xml.dom.SyntaxErr, u'T: %s' % exp,
+                self.assertRaisesMsg(xml.dom.SyntaxErr, 'T: %s' % exp,
                                      ProdParser().parse, text, 'T', prods)
         
         tests = {'1 3': True,
@@ -379,7 +379,7 @@ class ProdParserTestCase(basetest.BaseTestCase):
                  '2': 'Missing token for production p3',
                  '3': "Missing token for production Choice(Sequence(p1), p2): ('NUMBER', '3', 1, 1)",
                  }
-        for text, exp in tests.items():
+        for text, exp in list(tests.items()):
             prods = Sequence(Choice(Sequence(p1, minmax=lambda: (1,2)),
                                     p2),
                              p3)
@@ -387,7 +387,7 @@ class ProdParserTestCase(basetest.BaseTestCase):
                 wellformed, seq, store, unused = ProdParser().parse(text, 'T', prods)
                 self.assertEqual(wellformed, exp)
             else:
-                self.assertRaisesMsg(xml.dom.SyntaxErr, u'T: %s' % exp,
+                self.assertRaisesMsg(xml.dom.SyntaxErr, 'T: %s' % exp,
                                      ProdParser().parse, text, 'T', prods)
                         
         
diff --git a/src/cssutils/tests/test_profiles.py b/src/cssutils/tests/test_profiles.py
index 301ebba..29a93c7 100644
--- a/src/cssutils/tests/test_profiles.py
+++ b/src/cssutils/tests/test_profiles.py
@@ -3,7 +3,7 @@ __version__ = '$Id: test_cssvalue.py 1443 2008-08-31 13:54:39Z cthedot $'
 
 import sys
 import platform
-import basetest
+from . import basetest
 import cssutils
 
 CSS2 = (cssutils.profile.CSS_LEVEL_2,)
@@ -27,7 +27,7 @@ class ProfilesTestCase(basetest.BaseTestCase):
         '-test-macro': '{ident}|{percentage}',
         '-test-custommacro': '{testvalue}',
         # custom validation function 
-        '-test-funcval': lambda(v): int(v) > 0 
+        '-test-funcval': lambda v: int(v) > 0
         }  
 
     def test_knownNames(self):
@@ -35,7 +35,7 @@ class ProfilesTestCase(basetest.BaseTestCase):
         p = cssutils.profiles.Profiles()
         p.removeProfile(all=True)
         p.addProfile('test', self.P1, self.M1)
-        self.assertEqual(p.knownNames, self.P1.keys())
+        self.assertEqual(p.knownNames, list(self.P1.keys()))
         p.removeProfile(all=True)
         self.assertEqual(p.knownNames, [])
         
@@ -91,7 +91,7 @@ class ProfilesTestCase(basetest.BaseTestCase):
         # new profile
         cssutils.profile.addProfile('test', self.P1, self.M1)
         
-        props = self.P1.keys()
+        props = list(self.P1.keys())
         props.sort()
         self.assertEqual(props, list(cssutils.profile.propertiesByProfile('test')))
         
@@ -110,7 +110,7 @@ class ProfilesTestCase(basetest.BaseTestCase):
             ('-test-funcval', '-1'): False,     
             ('-test-funcval', 'x'): False     
             }
-        for test, v in tests.items():
+        for test, v in list(tests.items()):
             self.assertEqual(v, cssutils.profile.validate(*test))
             
             self.assertEqual((v, v, ['test']), 
@@ -119,20 +119,20 @@ class ProfilesTestCase(basetest.BaseTestCase):
         cssutils.log.raiseExceptions = True
         
         # raises:
-        expmsg = u"invalid literal for int() with base 10: 'x'"        
+        expmsg = "invalid literal for int() with base 10: 'x'"
         # Python upto 2.4 and Jython have different msg format...
         if sys.version_info[0:2] == (2,4):
-            expmsg = u"invalid literal for int(): x" 
+            expmsg = "invalid literal for int(): x"
         elif sys.platform.startswith('java'):
-            expmsg = u"invalid literal for int() with base 10: x"
+            expmsg = "invalid literal for int() with base 10: x"
         # PyPy adds the u prefix, but only in versions lower than Python 3
         elif (platform.python_implementation() == "PyPy" and
               sys.version_info < (3, 0)):
-            expmsg = u"invalid literal for int() with base 10: u'x'"
+            expmsg = "invalid literal for int() with base 10: u'x'"
 
             
         self.assertRaisesMsg(Exception, expmsg, 
-                             cssutils.profile.validate, u'-test-funcval', u'x')
+                             cssutils.profile.validate, '-test-funcval', 'x')
 
     def test_removeProfile(self):
         "Profiles.removeProfile()"
@@ -505,7 +505,7 @@ class ProfilesTestCase(basetest.BaseTestCase):
         
         }
         # TODO!!!
-        for (name, values), (valid, matching, profile) in tests.items(): 
+        for (name, values), (valid, matching, profile) in list(tests.items()):
             for value in values:
                 self.assertEqual(valid, cssutils.profile.validate(name, value))
                 
diff --git a/src/cssutils/tests/test_properties.py b/src/cssutils/tests/test_properties.py
index 07dc8d7..b941395 100644
--- a/src/cssutils/tests/test_properties.py
+++ b/src/cssutils/tests/test_properties.py
@@ -3,7 +3,7 @@ __version__ = '$Id: test_property.py 1529 2008-11-30 15:12:01Z cthedot $'
 
 import copy
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 from cssutils.css.property import Property
 
@@ -54,7 +54,7 @@ class PropertiesTestCase(basetest.BaseTestCase):
         def expanded(*keys):
             r = []
             for k in keys:
-                if isinstance(V[k], basestring):
+                if isinstance(V[k], str):
                     r.append(V[k])
                 else:
                     r.extend(list(V[k]))
@@ -62,7 +62,7 @@ class PropertiesTestCase(basetest.BaseTestCase):
 
         # before adding combined
         self.V = V
-        self.ALL = list(self._valuesofkeys(V.keys())) 
+        self.ALL = list(self._valuesofkeys(list(V.keys())))
         
         # combined values, only keys of V may be used!
         self.V['LENGTHS'] = expanded('0', 'EM', 'EX', 'PX', 'CM', 'MM', 'IN', 'PT', 'PC')
@@ -83,7 +83,7 @@ class PropertiesTestCase(basetest.BaseTestCase):
                     yield v
             else:
                 v = self.V[key]
-                if isinstance(v, basestring):
+                if isinstance(v, str):
                     # single value
                     if v not in done: 
                         done.append(v)
@@ -103,13 +103,13 @@ class PropertiesTestCase(basetest.BaseTestCase):
 
         for value in self._valuesofkeys(keys):
             if name == debug:
-                print '+True?', Property(name, value).valid, value
+                print('+True?', Property(name, value).valid, value)
             self.assertEqual(True, Property(name, value).valid)
             if value in notvalid:
                 notvalid.remove(value)
         for value in notvalid:
             if name == debug:
-                print '-False?', Property(name, value).valid, value
+                print('-False?', Property(name, value).valid, value)
             self.assertEqual(False, Property(name, value).valid)
                 
     def test_properties(self):
@@ -170,7 +170,7 @@ class PropertiesTestCase(basetest.BaseTestCase):
             
             'widows': ('0', ['1', '99999', 'inherit'])
         }
-        for name, keys in tests.items():
+        for name, keys in list(tests.items()):
             # keep track of valid keys
             self._check(name, keys)
 
@@ -182,7 +182,7 @@ class PropertiesTestCase(basetest.BaseTestCase):
             'rgba(1,2,3,1)': (False, True, True, False, True),
             '1': (False, False, False, False, False)
         }
-        for v, rs in tests.items():
+        for v, rs in list(tests.items()):
             p = Property('color', v)
             
             # TODO: Fix
diff --git a/src/cssutils/tests/test_property.py b/src/cssutils/tests/test_property.py
index f2d700a..765634a 100644
--- a/src/cssutils/tests/test_property.py
+++ b/src/cssutils/tests/test_property.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.property._Property."""
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 
 class PropertyTestCase(basetest.BaseTestCase):
@@ -18,11 +18,11 @@ class PropertyTestCase(basetest.BaseTestCase):
         self.assertEqual('1px', p.value)
         #self.assertEqual('1px', p.cssValue.cssText)
         self.assertEqual('1px', p.propertyValue.cssText)
-        self.assertEqual(u'', p.priority)
+        self.assertEqual('', p.priority)
         self.assertEqual(True, p.valid)
         self.assertEqual(True, p.wellformed)
 
-        self.assertEqual([u'top'], p.seqs[0])
+        self.assertEqual(['top'], p.seqs[0])
         self.assertEqual(type(cssutils.css.PropertyValue(cssText="2px")), type(p.seqs[1]))
         self.assertEqual([], p.seqs[2])
 
@@ -36,7 +36,7 @@ class PropertyTestCase(basetest.BaseTestCase):
         self.assertEqual('', p.value)
         #self.assertEqual('', p.cssValue.cssText)
         self.assertEqual('', p.propertyValue.cssText)
-        self.assertEqual(u'', p.priority)
+        self.assertEqual('', p.priority)
         self.assertEqual(False, p.valid)
         #p.cssValue.cssText = '1px'
         p.propertyValue.cssText = '1px'
@@ -77,38 +77,38 @@ class PropertyTestCase(basetest.BaseTestCase):
         p = cssutils.css.property.Property()
 
         tests = {
-            u'a: 1': None,
-            u'a: 1px 2px': None,
-            u'a: 1 !important': None,
-            u'a: 1 !IMPORTANT': u'a: 1 !important',
-            u'a: 1 !impor\\tant': u'a: 1 !important',
+            'a: 1': None,
+            'a: 1px 2px': None,
+            'a: 1 !important': None,
+            'a: 1 !IMPORTANT': 'a: 1 !important',
+            'a: 1 !impor\\tant': 'a: 1 !important',
             # TODO: important with unicode escapes!
-            u'font: normal 1em/1.5 serif': None,
-            u'font: normal 1em/serif': None
+            'font: normal 1em/1.5 serif': None,
+            'font: normal 1em/serif': None
             }
         self.do_equal_r(tests)
 
         tests = {
-            u'': (xml.dom.SyntaxErr,
-                   u'Property: No property name found: '),
-            u':': (xml.dom.SyntaxErr,
-                   u'Property: No property name found: : [1:1: :]'),
-            u'a': (xml.dom.SyntaxErr,
-                   u'Property: No ":" after name found: a [1:1: a]'),
-            u'b !': (xml.dom.SyntaxErr,
-                     u'Property: No ":" after name found: b ! [1:3: !]'),
-            u'/**/x': (xml.dom.SyntaxErr,
-                       u'Property: No ":" after name found: /**/x [1:5: x]'),
-            u'c:': (xml.dom.SyntaxErr,
-                   u"Property: No property value found: c: [1:2: :]"),
-            u'd: ': (xml.dom.SyntaxErr,
-                   u"No content to parse."),
-            u'e:!important': (xml.dom.SyntaxErr,
-                   u"No content to parse."),
-            u'f: 1!': (xml.dom.SyntaxErr,
-                       u'Property: Invalid priority: !'),
-            u'g: 1!importantX': (xml.dom.SyntaxErr,
-                   u"Property: No CSS priority value: importantx"),
+            '': (xml.dom.SyntaxErr,
+                   'Property: No property name found: '),
+            ':': (xml.dom.SyntaxErr,
+                   'Property: No property name found: : [1:1: :]'),
+            'a': (xml.dom.SyntaxErr,
+                   'Property: No ":" after name found: a [1:1: a]'),
+            'b !': (xml.dom.SyntaxErr,
+                     'Property: No ":" after name found: b ! [1:3: !]'),
+            '/**/x': (xml.dom.SyntaxErr,
+                       'Property: No ":" after name found: /**/x [1:5: x]'),
+            'c:': (xml.dom.SyntaxErr,
+                   "Property: No property value found: c: [1:2: :]"),
+            'd: ': (xml.dom.SyntaxErr,
+                   "No content to parse."),
+            'e:!important': (xml.dom.SyntaxErr,
+                   "No content to parse."),
+            'f: 1!': (xml.dom.SyntaxErr,
+                       'Property: Invalid priority: !'),
+            'g: 1!importantX': (xml.dom.SyntaxErr,
+                   "Property: No CSS priority value: importantx"),
 
             # TODO?
             #u'a: 1;': (xml.dom.SyntaxErr,
@@ -125,29 +125,29 @@ class PropertyTestCase(basetest.BaseTestCase):
         self.assertEqual('left', p.name)
 
         tests = {
-            u'top': None,
-            u' top': u'top',
-            u'top ': u'top',
-            u' top ': u'top',
-            u'/*x*/ top ': u'top',
-            u' top /*x*/': u'top',
-            u'/*x*/top/*x*/': u'top',
-            u'\\x': u'x',
-            u'a\\010': u'a\x10',
-            u'a\\01': u'a\x01'
+            'top': None,
+            ' top': 'top',
+            'top ': 'top',
+            ' top ': 'top',
+            '/*x*/ top ': 'top',
+            ' top /*x*/': 'top',
+            '/*x*/top/*x*/': 'top',
+            '\\x': 'x',
+            'a\\010': 'a\x10',
+            'a\\01': 'a\x01'
             }
         self.do_equal_r(tests, att='name')
 
         tests = {
-            u'': xml.dom.SyntaxErr,
-            u' ': xml.dom.SyntaxErr,
-            u'"\n': xml.dom.SyntaxErr,
-            u'/*x*/': xml.dom.SyntaxErr,
-            u':': xml.dom.SyntaxErr,
-            u';': xml.dom.SyntaxErr,
-            u'top:': xml.dom.SyntaxErr,
-            u'top;': xml.dom.SyntaxErr,
-            u'color: #xyz': xml.dom.SyntaxErr,
+            '': xml.dom.SyntaxErr,
+            ' ': xml.dom.SyntaxErr,
+            '"\n': xml.dom.SyntaxErr,
+            '/*x*/': xml.dom.SyntaxErr,
+            ':': xml.dom.SyntaxErr,
+            ';': xml.dom.SyntaxErr,
+            'top:': xml.dom.SyntaxErr,
+            'top;': xml.dom.SyntaxErr,
+            'color: #xyz': xml.dom.SyntaxErr,
             }
         self.do_raise_r(tests, att='_setName')
 
@@ -186,65 +186,65 @@ class PropertyTestCase(basetest.BaseTestCase):
         "Property.priority"
         p = cssutils.css.property.Property('top', '1px', 'important')
 
-        for prio in (None, u''):
+        for prio in (None, ''):
             p.priority = prio
-            self.assertEqual(u'', p.priority)
-            self.assertEqual(u'', p.literalpriority)
-
-        for prio in (u'!important',
-                     u'! important',
-                     u'!/* x */ important',
-                     u'!/* x */ important /**/',
-                     u'important',
-                     u'IMPORTANT',
-                     ur'im\portant'
+            self.assertEqual('', p.priority)
+            self.assertEqual('', p.literalpriority)
+
+        for prio in ('!important',
+                     '! important',
+                     '!/* x */ important',
+                     '!/* x */ important /**/',
+                     'important',
+                     'IMPORTANT',
+                     r'im\portant'
                      ):
             p.priority = prio
-            self.assertEqual(u'important', p.priority)
+            self.assertEqual('important', p.priority)
             if prio.startswith('!'):
                 prio = prio[1:].strip()
-            if u'/*' in prio:
+            if '/*' in prio:
                 check = 'important'
             else:
                 check = prio
             self.assertEqual(check, p.literalpriority)
 
         tests = {
-            u' ': xml.dom.SyntaxErr,
-            u'"\n': xml.dom.SyntaxErr,
+            ' ': xml.dom.SyntaxErr,
+            '"\n': xml.dom.SyntaxErr,
             #u'important': xml.dom.SyntaxErr,
-            u';': xml.dom.SyntaxErr,
-            u'!important !important': xml.dom.SyntaxErr
+            ';': xml.dom.SyntaxErr,
+            '!important !important': xml.dom.SyntaxErr
             }
         self.do_raise_r(tests, att='_setPriority')
 
     def test_value(self):
         "Property.value"
-        p = cssutils.css.property.Property('top', u'1px')
+        p = cssutils.css.property.Property('top', '1px')
         self.assertEqual('1px', p.value)
         p.value = '2px'
         self.assertEqual('2px', p.value)
 
         tests = {
-            u'1px': None,
-            u' 2px': u'2px',
-            u'3px ': u'3px',
-            u' 4px ': u'4px',
-            u'5px 1px': u'5px 1px',
+            '1px': None,
+            ' 2px': '2px',
+            '3px ': '3px',
+            ' 4px ': '4px',
+            '5px 1px': '5px 1px',
             }
         self.do_equal_r(tests, att='value')
 
         tests = {
             # no value
             None: xml.dom.SyntaxErr,
-            u'': xml.dom.SyntaxErr,
-            u' ': xml.dom.SyntaxErr,
-            u'"\n': xml.dom.SyntaxErr,
-            u'/*x*/': xml.dom.SyntaxErr,
+            '': xml.dom.SyntaxErr,
+            ' ': xml.dom.SyntaxErr,
+            '"\n': xml.dom.SyntaxErr,
+            '/*x*/': xml.dom.SyntaxErr,
             # not allowed:
-            u':': xml.dom.SyntaxErr,
-            u';': xml.dom.SyntaxErr,
-            u'!important': xml.dom.SyntaxErr,
+            ':': xml.dom.SyntaxErr,
+            ';': xml.dom.SyntaxErr,
+            '!important': xml.dom.SyntaxErr,
             }
         self.do_raise_r(tests, att='_setValue')
 
diff --git a/src/cssutils/tests/test_scripts_csscombine.py b/src/cssutils/tests/test_scripts_csscombine.py
index 5c67a23..424e944 100644
--- a/src/cssutils/tests/test_scripts_csscombine.py
+++ b/src/cssutils/tests/test_scripts_csscombine.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.scripts.csscombine"""
 
 from cssutils.script import csscombine
-import basetest
+from . import basetest
 import cssutils
 import os
 
diff --git a/src/cssutils/tests/test_selector.py b/src/cssutils/tests/test_selector.py
index 667156f..7eec407 100644
--- a/src/cssutils/tests/test_selector.py
+++ b/src/cssutils/tests/test_selector.py
@@ -7,7 +7,7 @@ what should happen here?
 
 """
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 
 class SelectorTestCase(basetest.BaseTestCase):
@@ -41,9 +41,9 @@ class SelectorTestCase(basetest.BaseTestCase):
             '*': (None, '*'),
             'x': (None, 'x'),
             '\\x': (None, '\\x'),
-            '|x': (u'', 'x'),
+            '|x': ('', 'x'),
             '*|x': (cssutils._ANYNS, 'x'),
-            'ex|x': (u'example', 'x'),
+            'ex|x': ('example', 'x'),
             'a x': (None, 'x'),
             'a+x': (None, 'x'),
             'a>x': (None, 'x'),
@@ -61,7 +61,7 @@ class SelectorTestCase(basetest.BaseTestCase):
             'x#id': (None, 'x'),
             'x.c': (None, 'x')
         }
-        for test, ele in tests.items():
+        for test, ele in list(tests.items()):
             s = cssutils.css.Selector((test,{'ex': 'example'}))
             self.assertEqual(ele, s.element)
 
@@ -86,7 +86,7 @@ class SelectorTestCase(basetest.BaseTestCase):
                                    'x[a][a][*|a][p|a]',
                                    'x[a][a][*|a][a]')
         }
-        for sel, exp in tests.items():
+        for sel, exp in list(tests.items()):
             for i, result in enumerate(exp):
                 s = cssutils.css.Selector((sel, namespaces[i]))
                 self.assertEqual(result, s.selectorText)
@@ -97,14 +97,14 @@ class SelectorTestCase(basetest.BaseTestCase):
 
         r = sheet.cssRules[1]
 
-        self.assertEqual(r.selectorText, u'a')
+        self.assertEqual(r.selectorText, 'a')
 
         # add default namespace
         sheet.namespaces[''] = 'a';
-        self.assertEqual(r.selectorText, u'|a')
+        self.assertEqual(r.selectorText, '|a')
 
         del sheet.namespaces[''];
-        self.assertEqual(r.selectorText, u'a')
+        self.assertEqual(r.selectorText, 'a')
 
 #        r.selectorList.append('a')
 #        self.assertEqual(r.selectorText, u'|a, a')
@@ -119,11 +119,11 @@ class SelectorTestCase(basetest.BaseTestCase):
         sheet = cssutils.css.CSSStyleSheet()
         sheet.cssText = css
         self.assertEqual(sheet.cssText,
-                         u'@namespace "default";\na[att] {\n    color: green\n    }'.encode())
+                         '@namespace "default";\na[att] {\n    color: green\n    }'.encode())
         # use a prefix for default namespace, does not goes for atts!
         sheet.namespaces['p'] = 'default'
         self.assertEqual(sheet.cssText,
-                         u'@namespace p "default";\np|a[att] {\n    color: green\n    }'.encode())
+                         '@namespace p "default";\np|a[att] {\n    color: green\n    }'.encode())
 
     def test_parent(self):
         "Selector.parent"
@@ -143,261 +143,261 @@ class SelectorTestCase(basetest.BaseTestCase):
         "Selector.selectorText"
         tests = {
             # combinators
-            u'a+b>c~e f': u'a + b > c ~ e f',
-            u'a  +  b  >  c  ~  e   f': u'a + b > c ~ e f',
-            u'a+b': u'a + b',
-            u'a  +  b': 'a + b',
-            u'a\n  +\t  b': 'a + b',
-            u'a~b': u'a ~ b',
-            u'a b': None,
-            u'a   b': 'a b',
-            u'a\nb': 'a b',
-            u'a\tb': 'a b',
-            u'a   #b': 'a #b',
-            u'a   .b': 'a .b',
-            u'a * b': None,
+            'a+b>c~e f': 'a + b > c ~ e f',
+            'a  +  b  >  c  ~  e   f': 'a + b > c ~ e f',
+            'a+b': 'a + b',
+            'a  +  b': 'a + b',
+            'a\n  +\t  b': 'a + b',
+            'a~b': 'a ~ b',
+            'a b': None,
+            'a   b': 'a b',
+            'a\nb': 'a b',
+            'a\tb': 'a b',
+            'a   #b': 'a #b',
+            'a   .b': 'a .b',
+            'a * b': None,
             # >
-            u'a>b': u'a > b',
-            u'a> b': 'a > b',
-            u'a >b': 'a > b',
-            u'a > b': 'a > b',
+            'a>b': 'a > b',
+            'a> b': 'a > b',
+            'a >b': 'a > b',
+            'a > b': 'a > b',
             # +
-            u'a+b': u'a + b',
-            u'a+ b': 'a + b',
-            u'a +b': 'a + b',
-            u'a + b': 'a + b',
+            'a+b': 'a + b',
+            'a+ b': 'a + b',
+            'a +b': 'a + b',
+            'a + b': 'a + b',
             # ~
-            u'a~b': u'a ~ b',
-            u'a~ b': 'a ~ b',
-            u'a ~b': 'a ~ b',
-            u'a ~ b': 'a ~ b',
+            'a~b': 'a ~ b',
+            'a~ b': 'a ~ b',
+            'a ~b': 'a ~ b',
+            'a ~ b': 'a ~ b',
 
             # type selector
-            u'a': None,
-            u'h1-a_x__--': None,
-            u'a-a': None,
-            u'a_a': None,
-            u'-a': None,
-            u'_': None,
-            u'-_': None,
-            ur'-\72': u'-r',
+            'a': None,
+            'h1-a_x__--': None,
+            'a-a': None,
+            'a_a': None,
+            '-a': None,
+            '_': None,
+            '-_': None,
+            r'-\72': '-r',
             #ur'\25': u'%', # TODO: should be escaped!
-            u'.a a': None,
-            u'a1': None,
-            u'a1-1': None,
-            u'.a1-1': None,
+            '.a a': None,
+            'a1': None,
+            'a1-1': None,
+            '.a1-1': None,
 
             # universal
-            u'*': None,
-            u'*/*x*/': None,
-            u'* /*x*/': None,
-            u'*:hover': None,
-            u'* :hover': None,
-            u'*:lang(fr)': None,
-            u'* :lang(fr)': None,
-            u'*::first-line': None,
-            u'* ::first-line': None,
-            u'*[lang=fr]': None,
-            u'[lang=fr]': None,
+            '*': None,
+            '*/*x*/': None,
+            '* /*x*/': None,
+            '*:hover': None,
+            '* :hover': None,
+            '*:lang(fr)': None,
+            '* :lang(fr)': None,
+            '*::first-line': None,
+            '* ::first-line': None,
+            '*[lang=fr]': None,
+            '[lang=fr]': None,
 
             # HASH
-            u'''#a''': None,
-            u'''#a1''': None,
-            u'''#1a''': None, # valid to grammar but not for HTML
-            u'''#1''': None, # valid to grammar but not for HTML
-            u'''a#b''': None,
-            u'''a #b''': None,
-            u'''a#b.c''': None,
-            u'''a.c#b''': None,
-            u'''a #b.c''': None,
-            u'''a .c#b''': None,
+            '''#a''': None,
+            '''#a1''': None,
+            '''#1a''': None, # valid to grammar but not for HTML
+            '''#1''': None, # valid to grammar but not for HTML
+            '''a#b''': None,
+            '''a #b''': None,
+            '''a#b.c''': None,
+            '''a.c#b''': None,
+            '''a #b.c''': None,
+            '''a .c#b''': None,
 
             # class
-            u'ab': 'ab',
-            u'a.b': None,
-            u'a.b.c': None,
-            u'.a1._1': None,
+            'ab': 'ab',
+            'a.b': None,
+            'a.b.c': None,
+            '.a1._1': None,
 
             # attrib
-            u'''[x]''': None,
-            u'''*[x]''': None,
-            u'''a[x]''': None,
-            u'''a[ x]''': 'a[x]',
-            u'''a[x ]''': 'a[x]',
-            u'''a [x]''': 'a [x]',
-            u'''* [x]''': None, # is really * *[x]
-
-            u'''a[x="1"]''': None,
-            u'''a[x ="1"]''': 'a[x="1"]',
-            u'''a[x= "1"]''': 'a[x="1"]',
-            u'''a[x = "1"]''': 'a[x="1"]',
-            u'''a[ x = "1"]''': 'a[x="1"]',
-            u'''a[x = "1" ]''': 'a[x="1"]',
-            u'''a[ x = "1" ]''': 'a[x="1"]',
-            u'''a [ x = "1" ]''': 'a [x="1"]',
-
-            u'''a[x~=a1]''': None,
-            u'''a[x ~=a1]''': 'a[x~=a1]',
-            u'''a[x~= a1]''': 'a[x~=a1]',
-            u'''a[x ~= a1]''': 'a[x~=a1]',
-            u'''a[ x ~= a1]''': 'a[x~=a1]',
-            u'''a[x ~= a1 ]''': 'a[x~=a1]',
-            u'''a[ x ~= a1 ]''': 'a[x~=a1]',
-            u'''a [ x ~= a1 ]''': 'a [x~=a1]', # same as next!
-            u'''a *[ x ~= a1 ]''': 'a *[x~=a1]',
-
-            u'''a[x|=en]''': None,
-            u'''a[x|= en]''': 'a[x|=en]',
-            u'''a[x |=en]''': 'a[x|=en]',
-            u'''a[x |= en]''': 'a[x|=en]',
-            u'''a[ x |= en]''': 'a[x|=en]',
-            u'''a[x |= en ]''': 'a[x|=en]',
-            u'''a[ x |= en]''': 'a[x|=en]',
-            u'''a [ x |= en]''': 'a [x|=en]',
+            '''[x]''': None,
+            '''*[x]''': None,
+            '''a[x]''': None,
+            '''a[ x]''': 'a[x]',
+            '''a[x ]''': 'a[x]',
+            '''a [x]''': 'a [x]',
+            '''* [x]''': None, # is really * *[x]
+
+            '''a[x="1"]''': None,
+            '''a[x ="1"]''': 'a[x="1"]',
+            '''a[x= "1"]''': 'a[x="1"]',
+            '''a[x = "1"]''': 'a[x="1"]',
+            '''a[ x = "1"]''': 'a[x="1"]',
+            '''a[x = "1" ]''': 'a[x="1"]',
+            '''a[ x = "1" ]''': 'a[x="1"]',
+            '''a [ x = "1" ]''': 'a [x="1"]',
+
+            '''a[x~=a1]''': None,
+            '''a[x ~=a1]''': 'a[x~=a1]',
+            '''a[x~= a1]''': 'a[x~=a1]',
+            '''a[x ~= a1]''': 'a[x~=a1]',
+            '''a[ x ~= a1]''': 'a[x~=a1]',
+            '''a[x ~= a1 ]''': 'a[x~=a1]',
+            '''a[ x ~= a1 ]''': 'a[x~=a1]',
+            '''a [ x ~= a1 ]''': 'a [x~=a1]', # same as next!
+            '''a *[ x ~= a1 ]''': 'a *[x~=a1]',
+
+            '''a[x|=en]''': None,
+            '''a[x|= en]''': 'a[x|=en]',
+            '''a[x |=en]''': 'a[x|=en]',
+            '''a[x |= en]''': 'a[x|=en]',
+            '''a[ x |= en]''': 'a[x|=en]',
+            '''a[x |= en ]''': 'a[x|=en]',
+            '''a[ x |= en]''': 'a[x|=en]',
+            '''a [ x |= en]''': 'a [x|=en]',
             # CSS3
-            u'''a[x^=en]''': None,
-            u'''a[x$=en]''': None,
-            u'''a[x*=en]''': None,
+            '''a[x^=en]''': None,
+            '''a[x$=en]''': None,
+            '''a[x*=en]''': None,
 
-            u'''a[/*1*/x/*2*/]''': None,
-            u'''a[/*1*/x/*2*/=/*3*/a/*4*/]''': None,
-            u'''a[/*1*/x/*2*/~=/*3*/a/*4*/]''': None,
-            u'''a[/*1*/x/*2*/|=/*3*/a/*4*/]''': None,
+            '''a[/*1*/x/*2*/]''': None,
+            '''a[/*1*/x/*2*/=/*3*/a/*4*/]''': None,
+            '''a[/*1*/x/*2*/~=/*3*/a/*4*/]''': None,
+            '''a[/*1*/x/*2*/|=/*3*/a/*4*/]''': None,
 
             # pseudo-elements
-            u'a x:first-line': None,
-            u'a x:first-letter': None,
-            u'a x:before': None,
-            u'a x:after': None,
-            u'a x::selection': None,
-            u'a:hover+b:hover>c:hover~e:hover f:hover':
-                u'a:hover + b:hover > c:hover ~ e:hover f:hover',
-            u'a:hover  +  b:hover  >  c:hover  ~  e:hover   f:hover':
-                u'a:hover + b:hover > c:hover ~ e:hover f:hover',
-            u'a::selection+b::selection>c::selection~e::selection f::selection':
-                u'a::selection + b::selection > c::selection ~ e::selection f::selection',
-            u'a::selection  +  b::selection  >  c::selection  ~  e::selection   f::selection':
-                u'a::selection + b::selection > c::selection ~ e::selection f::selection',
-
-            u'x:lang(de) y': None,
-            u'x:nth-child(odd) y': None,
+            'a x:first-line': None,
+            'a x:first-letter': None,
+            'a x:before': None,
+            'a x:after': None,
+            'a x::selection': None,
+            'a:hover+b:hover>c:hover~e:hover f:hover':
+                'a:hover + b:hover > c:hover ~ e:hover f:hover',
+            'a:hover  +  b:hover  >  c:hover  ~  e:hover   f:hover':
+                'a:hover + b:hover > c:hover ~ e:hover f:hover',
+            'a::selection+b::selection>c::selection~e::selection f::selection':
+                'a::selection + b::selection > c::selection ~ e::selection f::selection',
+            'a::selection  +  b::selection  >  c::selection  ~  e::selection   f::selection':
+                'a::selection + b::selection > c::selection ~ e::selection f::selection',
+
+            'x:lang(de) y': None,
+            'x:nth-child(odd) y': None,
             # functional pseudo
-            u'x:func(a + b-2px22.3"s"i)': None,
-            u'x:func(1 + 1)': None,
-            u'x:func(1+1)': u'x:func(1+1)',
-            u'x:func(1   +   1)': u'x:func(1 + 1)',
-            u'x:func(1-1)': u'x:func(1-1)',
-            u'x:func(1  -  1)': u'x:func(1 -1)', # TODO: FIX!
-            u'x:func(a-1)': u'x:func(a-1)',
-            u'x:func(a -1px)': u'x:func(a -1px)',
-            u'x:func(1px)': None,
-            u'x:func(23.4)': None,
-            u'x:func("s")': None,
-            u'x:func(i)': None,
+            'x:func(a + b-2px22.3"s"i)': None,
+            'x:func(1 + 1)': None,
+            'x:func(1+1)': 'x:func(1+1)',
+            'x:func(1   +   1)': 'x:func(1 + 1)',
+            'x:func(1-1)': 'x:func(1-1)',
+            'x:func(1  -  1)': 'x:func(1 -1)', # TODO: FIX!
+            'x:func(a-1)': 'x:func(a-1)',
+            'x:func(a -1px)': 'x:func(a -1px)',
+            'x:func(1px)': None,
+            'x:func(23.4)': None,
+            'x:func("s")': None,
+            'x:func(i)': None,
 
             # negation
-            u':not(y)': None,
-            u':not(   y  \t\n)': u':not(y)',
-            u'*:not(y)': None,
-            u'x:not(y)': None,
-            u'.x:not(y)': None,
-            u':not(*)': None,
-            u':not(#a)': None,
-            u':not(.a)': None,
-            u':not([a])': None,
-            u':not(:first-letter)': None,
-            u':not(::first-letter)': None,
+            ':not(y)': None,
+            ':not(   y  \t\n)': ':not(y)',
+            '*:not(y)': None,
+            'x:not(y)': None,
+            '.x:not(y)': None,
+            ':not(*)': None,
+            ':not(#a)': None,
+            ':not(.a)': None,
+            ':not([a])': None,
+            ':not(:first-letter)': None,
+            ':not(::first-letter)': None,
 
             # escapes
-            ur'\74\72 td': 'trtd',
-            ur'\74\72  td': 'tr td',
-            ur'\74\000072 td': 'trtd',
-            ur'\74\000072  td': 'tr td',
+            r'\74\72 td': 'trtd',
+            r'\74\72  td': 'tr td',
+            r'\74\000072 td': 'trtd',
+            r'\74\000072  td': 'tr td',
 
             # comments
-            u'a/**/ b': None,
-            u'a /**/b': None,
-            u'a /**/ b': None,
-            u'a  /**/ b': u'a /**/ b',
-            u'a /**/  b': u'a /**/ b',
+            'a/**/ b': None,
+            'a /**/b': None,
+            'a /**/ b': None,
+            'a  /**/ b': 'a /**/ b',
+            'a /**/  b': 'a /**/ b',
 
             # namespaces
-            u'|e': None,
-            u'*|e': None,
-            u'*|*': None,
-            (u'p|*', (('p', 'uri'),)): u'p|*',
-            (u'p|e', (('p', 'uri'),)): u'p|e',
-            (u'-a_x12|e', (('-a_x12', 'uri'),)): u'-a_x12|e',
-            (u'*|b[p|a]', (('p', 'uri'),)): '*|b[p|a]',
+            '|e': None,
+            '*|e': None,
+            '*|*': None,
+            ('p|*', (('p', 'uri'),)): 'p|*',
+            ('p|e', (('p', 'uri'),)): 'p|e',
+            ('-a_x12|e', (('-a_x12', 'uri'),)): '-a_x12|e',
+            ('*|b[p|a]', (('p', 'uri'),)): '*|b[p|a]',
 
             # case
-            u'elemenT.clasS#iD[atT="valuE"]:noT(x)::firsT-linE':
-                u'elemenT.clasS#iD[atT="valuE"]:not(x)::first-line'
+            'elemenT.clasS#iD[atT="valuE"]:noT(x)::firsT-linE':
+                'elemenT.clasS#iD[atT="valuE"]:not(x)::first-line'
             }
         # do not parse as not complete
         self.do_equal_r(tests, att='selectorText')
 
         tests = {
-            u'x|a': xml.dom.NamespaceErr,
-            (u'p|*', (('x', 'uri'),)): xml.dom.NamespaceErr,
-
-            u'': xml.dom.SyntaxErr,
-            u'1': xml.dom.SyntaxErr,
-            u'-1': xml.dom.SyntaxErr,
-            u'a*b': xml.dom.SyntaxErr,
-            u'a *b': xml.dom.SyntaxErr,
-            u'a* b': xml.dom.SyntaxErr,
-            u'a/**/b': xml.dom.SyntaxErr,
-
-            u'#': xml.dom.SyntaxErr,
-            u'|': xml.dom.SyntaxErr,
-
-            u':': xml.dom.SyntaxErr,
-            u'::': xml.dom.SyntaxErr,
-            u': a': xml.dom.SyntaxErr,
-            u':: a': xml.dom.SyntaxErr,
-            u':a()': xml.dom.SyntaxErr, # no value
-            u'::a()': xml.dom.SyntaxErr, # no value
-            u':::a': xml.dom.SyntaxErr,
-            u':1': xml.dom.SyntaxErr,
-
-            u'#.x': xml.dom.SyntaxErr,
-            u'.': xml.dom.SyntaxErr,
-            u'.1': xml.dom.SyntaxErr,
-            u'.a.1': xml.dom.SyntaxErr,
-
-            u'[a': xml.dom.SyntaxErr,
-            u'a]': xml.dom.SyntaxErr,
-            u'[a b]': xml.dom.SyntaxErr,
-            u'[=b]': xml.dom.SyntaxErr,
-            u'[a=]': xml.dom.SyntaxErr,
-            u'[a|=]': xml.dom.SyntaxErr,
-            u'[a~=]': xml.dom.SyntaxErr,
-            u'[a=1]': xml.dom.SyntaxErr,
-
-            u'a +': xml.dom.SyntaxErr,
-            u'a >': xml.dom.SyntaxErr,
-            u'a ++ b': xml.dom.SyntaxErr,
-            u'a + > b': xml.dom.SyntaxErr,
+            'x|a': xml.dom.NamespaceErr,
+            ('p|*', (('x', 'uri'),)): xml.dom.NamespaceErr,
+
+            '': xml.dom.SyntaxErr,
+            '1': xml.dom.SyntaxErr,
+            '-1': xml.dom.SyntaxErr,
+            'a*b': xml.dom.SyntaxErr,
+            'a *b': xml.dom.SyntaxErr,
+            'a* b': xml.dom.SyntaxErr,
+            'a/**/b': xml.dom.SyntaxErr,
+
+            '#': xml.dom.SyntaxErr,
+            '|': xml.dom.SyntaxErr,
+
+            ':': xml.dom.SyntaxErr,
+            '::': xml.dom.SyntaxErr,
+            ': a': xml.dom.SyntaxErr,
+            ':: a': xml.dom.SyntaxErr,
+            ':a()': xml.dom.SyntaxErr, # no value
+            '::a()': xml.dom.SyntaxErr, # no value
+            ':::a': xml.dom.SyntaxErr,
+            ':1': xml.dom.SyntaxErr,
+
+            '#.x': xml.dom.SyntaxErr,
+            '.': xml.dom.SyntaxErr,
+            '.1': xml.dom.SyntaxErr,
+            '.a.1': xml.dom.SyntaxErr,
+
+            '[a': xml.dom.SyntaxErr,
+            'a]': xml.dom.SyntaxErr,
+            '[a b]': xml.dom.SyntaxErr,
+            '[=b]': xml.dom.SyntaxErr,
+            '[a=]': xml.dom.SyntaxErr,
+            '[a|=]': xml.dom.SyntaxErr,
+            '[a~=]': xml.dom.SyntaxErr,
+            '[a=1]': xml.dom.SyntaxErr,
+
+            'a +': xml.dom.SyntaxErr,
+            'a >': xml.dom.SyntaxErr,
+            'a ++ b': xml.dom.SyntaxErr,
+            'a + > b': xml.dom.SyntaxErr,
 
             # functional pseudo
-            u'*:lang(': xml.dom.SyntaxErr,
-            u'*:lang()': xml.dom.SyntaxErr, # no arg
+            '*:lang(': xml.dom.SyntaxErr,
+            '*:lang()': xml.dom.SyntaxErr, # no arg
 
             # negation
-            u'not(x)': xml.dom.SyntaxErr, # no valid function
-            u':not()': xml.dom.SyntaxErr, # no arg
-            u':not(x': xml.dom.SyntaxErr, # no )
-            u':not(-': xml.dom.SyntaxErr, # not allowed
-            u':not(+': xml.dom.SyntaxErr, # not allowed
+            'not(x)': xml.dom.SyntaxErr, # no valid function
+            ':not()': xml.dom.SyntaxErr, # no arg
+            ':not(x': xml.dom.SyntaxErr, # no )
+            ':not(-': xml.dom.SyntaxErr, # not allowed
+            ':not(+': xml.dom.SyntaxErr, # not allowed
 
             # only one selector!
-            u',': xml.dom.InvalidModificationErr,
-            u',a': xml.dom.InvalidModificationErr,
-            u'a,': xml.dom.InvalidModificationErr,
+            ',': xml.dom.InvalidModificationErr,
+            ',a': xml.dom.InvalidModificationErr,
+            'a,': xml.dom.InvalidModificationErr,
 
             # @
-            u'p @here': xml.dom.SyntaxErr, # not allowed
+            'p @here': xml.dom.SyntaxErr, # not allowed
 
             }
         # only set as not complete
@@ -412,66 +412,66 @@ class SelectorTestCase(basetest.BaseTestCase):
         self.assertRaisesMsg(AttributeError, "can't set attribute", _set)
 
         tests = {
-            u'*': (0,0,0,0),
-            u'li': (0,0,0,1),
-            u'li:first-line': (0,0,0,2),
-            u'ul li': (0,0,0,2),
-            u'ul ol+li': (0,0,0,3),
-            u'h1 + *[rel=up]': (0,0,1,1),
-            u'ul ol li.red': (0,0,1,3),
-            u'li.red.level': (0,0,2,1),
-            u'#x34y': (0,1,0,0),
-
-            u'UL OL LI.red': (0,0,1,3),
-            u'LI.red.level': (0,0,2,1),
-            u'#s12:not(FOO)': (0,1,0,1),
-            u'button:not([DISABLED])': (0,0,1,1), #?
-            u'*:not(FOO)': (0,0,0,1),
+            '*': (0,0,0,0),
+            'li': (0,0,0,1),
+            'li:first-line': (0,0,0,2),
+            'ul li': (0,0,0,2),
+            'ul ol+li': (0,0,0,3),
+            'h1 + *[rel=up]': (0,0,1,1),
+            'ul ol li.red': (0,0,1,3),
+            'li.red.level': (0,0,2,1),
+            '#x34y': (0,1,0,0),
+
+            'UL OL LI.red': (0,0,1,3),
+            'LI.red.level': (0,0,2,1),
+            '#s12:not(FOO)': (0,1,0,1),
+            'button:not([DISABLED])': (0,0,1,1), #?
+            '*:not(FOO)': (0,0,0,1),
 
             # elements
-            u'a+b': (0,0,0,2),
-            u'a>b': (0,0,0,2),
-            u'a b': (0,0,0,2),
-            u'* a': (0,0,0,1),
-            u'a *': (0,0,0,1),
-            u'a * b': (0,0,0,2),
+            'a+b': (0,0,0,2),
+            'a>b': (0,0,0,2),
+            'a b': (0,0,0,2),
+            '* a': (0,0,0,1),
+            'a *': (0,0,0,1),
+            'a * b': (0,0,0,2),
 
-            u'a:hover': (0,0,0,1),
+            'a:hover': (0,0,0,1),
 
-            u'a:first-line': (0,0,0,2),
-            u'a:first-letter': (0,0,0,2),
-            u'a:before': (0,0,0,2),
-            u'a:after': (0,0,0,2),
+            'a:first-line': (0,0,0,2),
+            'a:first-letter': (0,0,0,2),
+            'a:before': (0,0,0,2),
+            'a:after': (0,0,0,2),
 
             # classes and attributes
-            u'.a': (0,0,1,0),
-            u'*.a': (0,0,1,0),
-            u'a.a': (0,0,1,1),
-            u'.a.a': (0,0,2,0), # IE<7 False (0,0,1,0)
-            u'a.a.a': (0,0,2,1),
-            u'.a.b': (0,0,2,0),
-            u'a.a.b': (0,0,2,1),
-            u'.a .a': (0,0,2,0),
-            u'*[x]': (0,0,1,0),
-            u'*[x]': (0,0,1,0),
-            u'*[x]': (0,0,1,0),
-            u'*[x=a]': (0,0,1,0),
-            u'*[x~=a]': (0,0,1,0),
-            u'*[x|=a]': (0,0,1,0),
-            u'*[x^=a]': (0,0,1,0),
-            u'*[x*=a]': (0,0,1,0),
-            u'*[x$=a]': (0,0,1,0),
-            u'*[x][y]': (0,0,2,0),
+            '.a': (0,0,1,0),
+            '*.a': (0,0,1,0),
+            'a.a': (0,0,1,1),
+            '.a.a': (0,0,2,0), # IE<7 False (0,0,1,0)
+            'a.a.a': (0,0,2,1),
+            '.a.b': (0,0,2,0),
+            'a.a.b': (0,0,2,1),
+            '.a .a': (0,0,2,0),
+            '*[x]': (0,0,1,0),
+            '*[x]': (0,0,1,0),
+            '*[x]': (0,0,1,0),
+            '*[x=a]': (0,0,1,0),
+            '*[x~=a]': (0,0,1,0),
+            '*[x|=a]': (0,0,1,0),
+            '*[x^=a]': (0,0,1,0),
+            '*[x*=a]': (0,0,1,0),
+            '*[x$=a]': (0,0,1,0),
+            '*[x][y]': (0,0,2,0),
 
             # ids
-            u'#a': (0,1,0,0),
-            u'*#a': (0,1,0,0),
-            u'x#a': (0,1,0,1),
-            u'.x#a': (0,1,1,0),
-            u'a.x#a': (0,1,1,1),
-            u'#a#a': (0,2,0,0), # e.g. html:id + xml:id
-            u'#a#b': (0,2,0,0),
-            u'#a #b': (0,2,0,0),
+            '#a': (0,1,0,0),
+            '*#a': (0,1,0,0),
+            'x#a': (0,1,0,1),
+            '.x#a': (0,1,1,0),
+            'a.x#a': (0,1,1,1),
+            '#a#a': (0,2,0,0), # e.g. html:id + xml:id
+            '#a#b': (0,2,0,0),
+            '#a #b': (0,2,0,0),
             }
         for text in tests:
             selector.selectorText = text
@@ -479,7 +479,7 @@ class SelectorTestCase(basetest.BaseTestCase):
 
     def test_reprANDstr(self):
         "Selector.__repr__(), .__str__()"
-        sel=u'a + b'
+        sel='a + b'
 
         s = cssutils.css.Selector(selectorText=sel)
 
diff --git a/src/cssutils/tests/test_selectorlist.py b/src/cssutils/tests/test_selectorlist.py
index fc619d8..923cc48 100644
--- a/src/cssutils/tests/test_selectorlist.py
+++ b/src/cssutils/tests/test_selectorlist.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.css.selectorlist.SelectorList."""
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 from cssutils.css.selectorlist import SelectorList
 
@@ -17,19 +17,19 @@ class SelectorListTestCase(basetest.BaseTestCase):
 
         s = SelectorList('a, b')
         self.assertEqual(2, s.length)
-        self.assertEqual(u'a, b', s.selectorText)
+        self.assertEqual('a, b', s.selectorText)
 
         s = SelectorList(selectorText='a')
         self.assertEqual(1, s.length)
-        self.assertEqual(u'a', s.selectorText)
+        self.assertEqual('a', s.selectorText)
 
         s = SelectorList(selectorText=('p|a', {'p': 'uri'})) # n-dict
         self.assertEqual(1, s.length)
-        self.assertEqual(u'p|a', s.selectorText)
+        self.assertEqual('p|a', s.selectorText)
 
         s = SelectorList(selectorText=('p|a', (('p', 'uri'),))) # n-tuples
         self.assertEqual(1, s.length)
-        self.assertEqual(u'p|a', s.selectorText)
+        self.assertEqual('p|a', s.selectorText)
 
     def test_parentRule(self):
         "Selector.parentRule"
@@ -63,21 +63,21 @@ class SelectorListTestCase(basetest.BaseTestCase):
                           s.appendSelector, 'b,')
         self.assertEqual(1, s.length)
 
-        self.assertEqual(u'a', s.selectorText)
+        self.assertEqual('a', s.selectorText)
 
         s.append('b')
         self.assertEqual(2, s.length)
-        self.assertEqual(u'a, b', s.selectorText)
+        self.assertEqual('a, b', s.selectorText)
 
         s.append('a')
         self.assertEqual(2, s.length)
-        self.assertEqual(u'b, a', s.selectorText)
+        self.assertEqual('b, a', s.selectorText)
         
         # __setitem__    
         self.assertRaises(IndexError, s.__setitem__, 4, 'x')
         s[1] = 'c'
         self.assertEqual(2, s.length)
-        self.assertEqual(u'b, c', s.selectorText)
+        self.assertEqual('b, c', s.selectorText)
         # TODO: remove duplicates?
 #        s[0] = 'c'
 #        self.assertEqual(1, s.length)
@@ -85,53 +85,53 @@ class SelectorListTestCase(basetest.BaseTestCase):
 
         s = SelectorList()
         s.appendSelector(('p|a', {'p': 'uri', 'x': 'xxx'}))
-        self.assertEqual(u'p|a', s.selectorText)
+        self.assertEqual('p|a', s.selectorText)
         # x gets lost as not used
         self.assertRaises(xml.dom.NamespaceErr, s.append, 'x|a')
         # not set at all
         self.assertRaises(xml.dom.NamespaceErr, s.append, 'y|a')
         # but p is retained
         s.append('p|b')
-        self.assertEqual(u'p|a, p|b', s.selectorText)
+        self.assertEqual('p|a, p|b', s.selectorText)
 
     def test_selectorText(self):
         "SelectorList.selectorText"
         s = SelectorList()
-        s.selectorText = u'a, b'
-        self.assertEqual(u'a, b', s.selectorText)
-        self.assertRaises(xml.dom.SyntaxErr, s._setSelectorText, u',')
+        s.selectorText = 'a, b'
+        self.assertEqual('a, b', s.selectorText)
+        self.assertRaises(xml.dom.SyntaxErr, s._setSelectorText, ',')
         # not changed as invalid!
-        self.assertEqual(u'a, b', s.selectorText)
+        self.assertEqual('a, b', s.selectorText)
 
         tests = {
-            u'*': None,
-            u'/*1*/*': None,
-            u'/*1*/*, a': None,
-            u'a, b': None,
-            u'a ,b': u'a, b',
-            u'a , b': u'a, b',
-            u'a, b, c': u'a, b, c',
-            u'#a, x#a, .b, x.b': u'#a, x#a, .b, x.b',
-            (u'[p|a], p|*', (('p', 'uri'),)): u'[p|a], p|*',
+            '*': None,
+            '/*1*/*': None,
+            '/*1*/*, a': None,
+            'a, b': None,
+            'a ,b': 'a, b',
+            'a , b': 'a, b',
+            'a, b, c': 'a, b, c',
+            '#a, x#a, .b, x.b': '#a, x#a, .b, x.b',
+            ('[p|a], p|*', (('p', 'uri'),)): '[p|a], p|*',
             }
         # do not parse as not complete
         self.do_equal_r(tests, att='selectorText')
 
         tests = {
-            u'x|*': xml.dom.NamespaceErr,
-            u'': xml.dom.SyntaxErr,
-            u' ': xml.dom.SyntaxErr,
-            u',': xml.dom.SyntaxErr,
-            u'a,': xml.dom.SyntaxErr,
-            u',a': xml.dom.SyntaxErr,
-            u'/* 1 */,a': xml.dom.SyntaxErr,
+            'x|*': xml.dom.NamespaceErr,
+            '': xml.dom.SyntaxErr,
+            ' ': xml.dom.SyntaxErr,
+            ',': xml.dom.SyntaxErr,
+            'a,': xml.dom.SyntaxErr,
+            ',a': xml.dom.SyntaxErr,
+            '/* 1 */,a': xml.dom.SyntaxErr,
             }
         # only set as not complete
         self.do_raise_r(tests, att='_setSelectorText')
 
     def test_reprANDstr(self):
         "SelectorList.__repr__(), .__str__()"
-        sel=(u'a, p|b', { 'p': 'uri'})
+        sel=('a, p|b', { 'p': 'uri'})
         
         s = cssutils.css.SelectorList(selectorText=sel)
 
diff --git a/src/cssutils/tests/test_serialize.py b/src/cssutils/tests/test_serialize.py
index 29d6843..fde4853 100644
--- a/src/cssutils/tests/test_serialize.py
+++ b/src/cssutils/tests/test_serialize.py
@@ -1,7 +1,7 @@
 # -*- coding: utf-8 -*-
 """Testcases for cssutils.CSSSerializer"""
 
-import basetest
+from . import basetest
 import cssutils
 import sys
 
@@ -35,7 +35,7 @@ class PreferencesTestCase(basetest.BaseTestCase):
         
         cssutils.ser.prefs.resolveVariables = False
         
-        vars = u'''
+        vars = '''
             @variables {
                 c1: red;
                 c2: #0f0;
@@ -43,24 +43,24 @@ class PreferencesTestCase(basetest.BaseTestCase):
             }
         '''
         tests = {
-            u'''a {\n    color: var(c1)\n    }''':
-            u'''a {\n    color: red\n    }''',
-            u'''a {\n    color: var(c1)\n; color: var(  c2   )    }''':
-            u'''a {\n    color: red;\n    color: #0f0\n    }''',
-            u'''a {\n    margin: var(px)\n    }''':
-            u'''a {\n    margin: 1px 2px\n    }''',
-            u'''@media all {
+            '''a {\n    color: var(c1)\n    }''':
+            '''a {\n    color: red\n    }''',
+            '''a {\n    color: var(c1)\n; color: var(  c2   )    }''':
+            '''a {\n    color: red;\n    color: #0f0\n    }''',
+            '''a {\n    margin: var(px)\n    }''':
+            '''a {\n    margin: 1px 2px\n    }''',
+            '''@media all {
                 a {
                     margin: var(px) var(px);
                     color: var(c1);
                     left: var(unknown)
                     }
             }''': 
-            u'''@media all {\n    a {\n        margin: 1px 2px 1px 2px;\n        color: red;\n        left: var(unknown)\n        }\n    }''',
+            '''@media all {\n    a {\n        margin: 1px 2px 1px 2px;\n        color: red;\n        left: var(unknown)\n        }\n    }''',
         }
         cssutils.ser.prefs.resolveVariables = True
         
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             s = cssutils.parseString(vars + test)
             self.assertEqual(exp.encode(), s.cssText)
             
@@ -75,7 +75,7 @@ class PreferencesTestCase(basetest.BaseTestCase):
         self.assertEqual(cssutils.ser.prefs.defaultPropertyName, True)
         self.assertEqual(cssutils.ser.prefs.defaultPropertyPriority, True)
         self.assertEqual(cssutils.ser.prefs.importHrefFormat, None)
-        self.assertEqual(cssutils.ser.prefs.indent, 4 * u' ')
+        self.assertEqual(cssutils.ser.prefs.indent, 4 * ' ')
         self.assertEqual(cssutils.ser.prefs.indentClosingBrace, True)
         self.assertEqual(cssutils.ser.prefs.keepAllProperties, True)
         self.assertEqual(cssutils.ser.prefs.keepComments, True)
@@ -83,17 +83,17 @@ class PreferencesTestCase(basetest.BaseTestCase):
         self.assertEqual(cssutils.ser.prefs.keepUnknownAtRules, True)
         self.assertEqual(cssutils.ser.prefs.keepUsedNamespaceRulesOnly, False)
         self.assertEqual(cssutils.ser.prefs.lineNumbers, False)
-        self.assertEqual(cssutils.ser.prefs.lineSeparator, u'\n')
-        self.assertEqual(cssutils.ser.prefs.listItemSpacer, u' ')
+        self.assertEqual(cssutils.ser.prefs.lineSeparator, '\n')
+        self.assertEqual(cssutils.ser.prefs.listItemSpacer, ' ')
         self.assertEqual(cssutils.ser.prefs.minimizeColorHash, True)
         self.assertEqual(cssutils.ser.prefs.omitLastSemicolon, True)
         self.assertEqual(cssutils.ser.prefs.omitLeadingZero, False)
-        self.assertEqual(cssutils.ser.prefs.paranthesisSpacer, u' ')
-        self.assertEqual(cssutils.ser.prefs.propertyNameSpacer, u' ')
-        self.assertEqual(cssutils.ser.prefs.selectorCombinatorSpacer, u' ')
-        self.assertEqual(cssutils.ser.prefs.spacer, u' ')
+        self.assertEqual(cssutils.ser.prefs.paranthesisSpacer, ' ')
+        self.assertEqual(cssutils.ser.prefs.propertyNameSpacer, ' ')
+        self.assertEqual(cssutils.ser.prefs.selectorCombinatorSpacer, ' ')
+        self.assertEqual(cssutils.ser.prefs.spacer, ' ')
         self.assertEqual(cssutils.ser.prefs.validOnly, False)
-        css = u'''
+        css = '''
     /*1*/
     @import url(x) tv , print;
     @namespace prefix "uri";
@@ -111,7 +111,7 @@ class PreferencesTestCase(basetest.BaseTestCase):
         font-family : arial ,'some'
         }
     '''
-        parsedcss = u'''/*1*/
+        parsedcss = '''/*1*/
 @import url(x) tv, print;
 @namespace prefix "uri";
 @namespace unused "unused";
@@ -131,13 +131,13 @@ prefix|x, a + b > c ~ d, b {
         self.assertEqual(s.cssText, parsedcss.encode())
         
         tests = {
-            u'0.1 .1 0.1px .1px 0.1% .1% +0.1 +.1 +0.1px +.1px +0.1% +.1% -0.1 -.1 -0.1px -.1px -0.1% -.1%': 
-            u'0.1 0.1 0.1px 0.1px 0.1% 0.1% +0.1 +0.1 +0.1px +0.1px +0.1% +0.1% -0.1 -0.1 -0.1px -0.1px -0.1% -0.1%' 
+            '0.1 .1 0.1px .1px 0.1% .1% +0.1 +.1 +0.1px +.1px +0.1% +.1% -0.1 -.1 -0.1px -.1px -0.1% -.1%':
+            '0.1 0.1 0.1px 0.1px 0.1% 0.1% +0.1 +0.1 +0.1px +0.1px +0.1% +0.1% -0.1 -0.1 -0.1px -0.1px -0.1% -0.1%'
         }
         cssutils.ser.prefs.useDefaults()
-        for test, exp in tests.items():
-            s = cssutils.parseString(u'a{x:%s}' % test)
-            self.assertEqual((u'a {\n    x: %s\n    }' % exp).encode(), s.cssText)
+        for test, exp in list(tests.items()):
+            s = cssutils.parseString('a{x:%s}' % test)
+            self.assertEqual(('a {\n    x: %s\n    }' % exp).encode(), s.cssText)
 
 
     def test_useMinified(self):
@@ -147,24 +147,24 @@ prefix|x, a + b > c ~ d, b {
         self.assertEqual(cssutils.ser.prefs.defaultAtKeyword, True)
         self.assertEqual(cssutils.ser.prefs.defaultPropertyName, True)
         self.assertEqual(cssutils.ser.prefs.importHrefFormat, 'string')
-        self.assertEqual(cssutils.ser.prefs.indent, u'')
+        self.assertEqual(cssutils.ser.prefs.indent, '')
         self.assertEqual(cssutils.ser.prefs.keepAllProperties, True)
         self.assertEqual(cssutils.ser.prefs.keepComments, False)
         self.assertEqual(cssutils.ser.prefs.keepEmptyRules, False)
         self.assertEqual(cssutils.ser.prefs.keepUnknownAtRules, False)
         self.assertEqual(cssutils.ser.prefs.keepUsedNamespaceRulesOnly, True)
         self.assertEqual(cssutils.ser.prefs.lineNumbers, False)
-        self.assertEqual(cssutils.ser.prefs.lineSeparator, u'')
-        self.assertEqual(cssutils.ser.prefs.listItemSpacer, u'')
+        self.assertEqual(cssutils.ser.prefs.lineSeparator, '')
+        self.assertEqual(cssutils.ser.prefs.listItemSpacer, '')
         self.assertEqual(cssutils.ser.prefs.omitLastSemicolon, True)
         self.assertEqual(cssutils.ser.prefs.omitLeadingZero, True)
-        self.assertEqual(cssutils.ser.prefs.paranthesisSpacer, u'')
-        self.assertEqual(cssutils.ser.prefs.propertyNameSpacer, u'')
-        self.assertEqual(cssutils.ser.prefs.selectorCombinatorSpacer, u'')
-        self.assertEqual(cssutils.ser.prefs.spacer, u'')
+        self.assertEqual(cssutils.ser.prefs.paranthesisSpacer, '')
+        self.assertEqual(cssutils.ser.prefs.propertyNameSpacer, '')
+        self.assertEqual(cssutils.ser.prefs.selectorCombinatorSpacer, '')
+        self.assertEqual(cssutils.ser.prefs.spacer, '')
         self.assertEqual(cssutils.ser.prefs.validOnly, False)
         
-        css = u'''
+        css = '''
     /*1*/
     @import   url(x) tv , print;
     @namespace   prefix "uri";
@@ -188,47 +188,47 @@ prefix|x, a + b > c ~ d, b {
         s = cssutils.parseString(css)
         cssutils.ser.prefs.keepUnknownAtRules = True
         self.assertEqual(s.cssText,
-            u'''@import"x"tv,print;@namespace prefix"uri";@media all"name"{a{color:red}}@page :left{left:0}prefix|x,a+b>c~d,b{top:1px;font-family:arial,"some"}@x x;'''.encode() 
+            '''@import"x"tv,print;@namespace prefix"uri";@media all"name"{a{color:red}}@page :left{left:0}prefix|x,a+b>c~d,b{top:1px;font-family:arial,"some"}@x x;'''.encode()
             )
         cssutils.ser.prefs.keepUnknownAtRules = False
         self.assertEqual(s.cssText,
-            u'''@import"x"tv,print;@namespace prefix"uri";@media all"name"{a{color:red}}@page :left{left:0}prefix|x,a+b>c~d,b{top:1px;font-family:arial,"some"}'''.encode()
+            '''@import"x"tv,print;@namespace prefix"uri";@media all"name"{a{color:red}}@page :left{left:0}prefix|x,a+b>c~d,b{top:1px;font-family:arial,"some"}'''.encode()
             )
         # Values
         valuetests = {
-            u'  a  a1  a-1  a-1a  ': 'a a1 a-1 a-1a',
-            u'a b 1 c 1em d -1em e': u'a b 1 c 1em d -1em e',
-            u'  1em  /  5  ': u'1em/5',
-            u'1em/5': u'1em/5',
-            u'a 0 a .0 a 0.0 a -0 a -.0 a -0.0 a +0 a +.0 a +0.0':
-                u'a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0',
-            u'a  0px  a  .0px  a  0.0px  a  -0px  a  -.0px  a  -0.0px  a  +0px  a  +.0px  a  +0.0px ':
-                u'a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0',
-            u'a  1  a  .1  a  1.0  a  0.1  a  -1  a  -.1  a  -1.0  a  -0.1  a  +1  a  +.1  a  +1.0':
-                u'a 1 a .1 a 1 a .1 a -1 a -.1 a -1 a -.1 a +1 a +.1 a +1',
-            u'  url(x)  f()': 'url(x) f()',
-            u'#112233': '#123',
-            u'#112234': '#112234',
-            u'#123': '#123',
-            u'#123 url() f()': '#123 url() f()',
-            u'1 +2 +3 -4': u'1 +2 +3 -4', # ?
-            u'0.1 .1 0.1px .1px 0.1% .1% +0.1 +.1 +0.1px +.1px +0.1% +.1% -0.1 -.1 -0.1px -.1px -0.1% -.1%':
-            u'.1 .1 .1px .1px .1% .1% +.1 +.1 +.1px +.1px +.1% +.1% -.1 -.1 -.1px -.1px -.1% -.1%'
+            '  a  a1  a-1  a-1a  ': 'a a1 a-1 a-1a',
+            'a b 1 c 1em d -1em e': 'a b 1 c 1em d -1em e',
+            '  1em  /  5  ': '1em/5',
+            '1em/5': '1em/5',
+            'a 0 a .0 a 0.0 a -0 a -.0 a -0.0 a +0 a +.0 a +0.0':
+                'a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0',
+            'a  0px  a  .0px  a  0.0px  a  -0px  a  -.0px  a  -0.0px  a  +0px  a  +.0px  a  +0.0px ':
+                'a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0 a 0',
+            'a  1  a  .1  a  1.0  a  0.1  a  -1  a  -.1  a  -1.0  a  -0.1  a  +1  a  +.1  a  +1.0':
+                'a 1 a .1 a 1 a .1 a -1 a -.1 a -1 a -.1 a +1 a +.1 a +1',
+            '  url(x)  f()': 'url(x) f()',
+            '#112233': '#123',
+            '#112234': '#112234',
+            '#123': '#123',
+            '#123 url() f()': '#123 url() f()',
+            '1 +2 +3 -4': '1 +2 +3 -4', # ?
+            '0.1 .1 0.1px .1px 0.1% .1% +0.1 +.1 +0.1px +.1px +0.1% +.1% -0.1 -.1 -0.1px -.1px -0.1% -.1%':
+            '.1 .1 .1px .1px .1% .1% +.1 +.1 +.1px +.1px +.1% +.1% -.1 -.1 -.1px -.1px -.1% -.1%'
         }
-        for test, exp in valuetests.items():
-            s = cssutils.parseString(u'a{x:%s}' % test)
-            self.assertEqual((u'a{x:%s}' % exp).encode(), s.cssText)
+        for test, exp in list(valuetests.items()):
+            s = cssutils.parseString('a{x:%s}' % test)
+            self.assertEqual(('a{x:%s}' % exp).encode(), s.cssText)
 
         
             
     def test_defaultAtKeyword(self):
         "Preferences.defaultAtKeyword"
-        s = cssutils.parseString(u'@im\\port "x";')
-        self.assertEqual(u'@import "x";'.encode(), s.cssText)
+        s = cssutils.parseString('@im\\port "x";')
+        self.assertEqual('@import "x";'.encode(), s.cssText)
         cssutils.ser.prefs.defaultAtKeyword = True
-        self.assertEqual(u'@import "x";'.encode(), s.cssText)
+        self.assertEqual('@import "x";'.encode(), s.cssText)
         cssutils.ser.prefs.defaultAtKeyword = False
-        self.assertEqual(u'@im\\port "x";'.encode(), s.cssText)
+        self.assertEqual('@im\\port "x";'.encode(), s.cssText)
         
     def test_defaultPropertyName(self):
         "Preferences.defaultPropertyName"
@@ -237,56 +237,56 @@ prefix|x, a + b > c ~ d, b {
         # does not actually work as once the name is set it is used also
         # if used with a backslash in it later...
 
-        s = cssutils.parseString(ur'a { c\olor: green; }')
-        self.assertEqual(u'a {\n    color: green\n    }'.encode(), s.cssText)
+        s = cssutils.parseString(r'a { c\olor: green; }')
+        self.assertEqual('a {\n    color: green\n    }'.encode(), s.cssText)
         cssutils.ser.prefs.defaultPropertyName = True
-        self.assertEqual(u'a {\n    color: green\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    color: green\n    }'.encode(), s.cssText)
         cssutils.ser.prefs.defaultPropertyName = False
-        self.assertEqual(u'a {\n    c\\olor: green\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    c\\olor: green\n    }'.encode(), s.cssText)
 
-        s = cssutils.parseString(u'a { color: red; c\olor: green; }')
-        self.assertEqual(u'a {\n    c\\olor: green\n    }'.encode(), s.cssText)
+        s = cssutils.parseString('a { color: red; c\olor: green; }')
+        self.assertEqual('a {\n    c\\olor: green\n    }'.encode(), s.cssText)
         cssutils.ser.prefs.defaultPropertyName = False
-        self.assertEqual(u'a {\n    c\\olor: green\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    c\\olor: green\n    }'.encode(), s.cssText)
         cssutils.ser.prefs.defaultPropertyName = True
-        self.assertEqual(u'a {\n    color: green\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    color: green\n    }'.encode(), s.cssText)
         
     def test_defaultPropertyPriority(self):
         "Preferences.defaultPropertyPriority"
-        css = u'a {\n    color: green !IM\\portant\n    }'
+        css = 'a {\n    color: green !IM\\portant\n    }'
         s = cssutils.parseString(css)
-        self.assertEqual(s.cssText, u'a {\n    color: green !important\n    }'.encode())
+        self.assertEqual(s.cssText, 'a {\n    color: green !important\n    }'.encode())
         cssutils.ser.prefs.defaultPropertyPriority = False
         self.assertEqual(s.cssText, css.encode())
         
     def test_importHrefFormat(self):
         "Preferences.importHrefFormat"
         r0 = cssutils.css.CSSImportRule()
-        r0.cssText=u'@import url("not");'
+        r0.cssText='@import url("not");'
         r1 = cssutils.css.CSSImportRule()
-        r1.cssText=u'@import "str";'
-        self.assertEqual(u'@import url(not);', r0.cssText)
-        self.assertEqual(u'@import "str";', r1.cssText)
+        r1.cssText='@import "str";'
+        self.assertEqual('@import url(not);', r0.cssText)
+        self.assertEqual('@import "str";', r1.cssText)
 
         cssutils.ser.prefs.importHrefFormat = 'string'
-        self.assertEqual(u'@import "not";', r0.cssText)
-        self.assertEqual(u'@import "str";', r1.cssText)
+        self.assertEqual('@import "not";', r0.cssText)
+        self.assertEqual('@import "str";', r1.cssText)
 
         cssutils.ser.prefs.importHrefFormat = 'uri'
-        self.assertEqual(u'@import url(not);', r0.cssText)
-        self.assertEqual(u'@import url(str);', r1.cssText)
+        self.assertEqual('@import url(not);', r0.cssText)
+        self.assertEqual('@import url(str);', r1.cssText)
 
         cssutils.ser.prefs.importHrefFormat = 'not defined'
-        self.assertEqual(u'@import url(not);', r0.cssText)
-        self.assertEqual(u'@import "str";', r1.cssText)
+        self.assertEqual('@import url(not);', r0.cssText)
+        self.assertEqual('@import "str";', r1.cssText)
         
     def test_indent(self):
         "Preferences.ident"
-        s = cssutils.parseString(u'a { left: 0 }')
-        exp4 = u'''a {
+        s = cssutils.parseString('a { left: 0 }')
+        exp4 = '''a {
     left: 0
     }'''
-        exp1 = u'''a {
+        exp1 = '''a {
  left: 0
  }'''
         cssutils.ser.prefs.indent = ' '
@@ -296,8 +296,8 @@ prefix|x, a + b > c ~ d, b {
 
     def test_indentClosingBrace(self):
         "Preferences.indentClosingBrace"
-        s = cssutils.parseString(u'@media all {a {left: 0}} b { top: 0 }')
-        expT = u'''@media all {
+        s = cssutils.parseString('@media all {a {left: 0}} b { top: 0 }')
+        expT = '''@media all {
     a {
         left: 0
         }
@@ -305,7 +305,7 @@ prefix|x, a + b > c ~ d, b {
 b {
     top: 0
     }'''
-        expF = u'''@media all {
+        expF = '''@media all {
     a {
         left: 0
     }
@@ -329,10 +329,10 @@ b {
         s = cssutils.parseString(css)
         # keep only last
         cssutils.ser.prefs.keepAllProperties = False
-        self.assertEqual(u'a {\n    color: green\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    color: green\n    }'.encode(), s.cssText)
         # keep all
         cssutils.ser.prefs.keepAllProperties = True
-        self.assertEqual(u'a {\n    color: pink;\n    color: red;\n    c\olor: blue;\n    c\olor: green\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    color: pink;\n    color: red;\n    c\olor: blue;\n    c\olor: green\n    }'.encode(), s.cssText)
         
     def test_keepComments(self):
         "Preferences.keepComments"
@@ -345,7 +345,7 @@ b {
     def test_keepEmptyRules(self):
         "Preferences.keepEmptyRules"
         # CSSStyleRule
-        css = u'''a {}
+        css = '''a {}
 a {
     /*1*/
     }
@@ -357,13 +357,13 @@ a {
         cssutils.ser.prefs.keepEmptyRules = True
         self.assertEqual(css.encode(), s.cssText)
         cssutils.ser.prefs.keepEmptyRules = False
-        self.assertEqual(u'a {\n    /*1*/\n    }\na {\n    color: red\n    }'.encode(),
+        self.assertEqual('a {\n    /*1*/\n    }\na {\n    color: red\n    }'.encode(),
                          s.cssText)
         cssutils.ser.prefs.keepComments = False
-        self.assertEqual(u'a {\n    color: red\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    color: red\n    }'.encode(), s.cssText)
 
         # CSSMediaRule
-        css = u'''@media tv {
+        css = '''@media tv {
     }
 @media all {
     /*1*/
@@ -409,14 +409,14 @@ a {
     def test_keepUnknownAtRules(self):
         "Preferences.keepUnknownAtRules"
         tests = {
-            u'''@three-dee {
+            '''@three-dee {
               @background-lighting {
                 azimuth: 30deg;
                 elevation: 190deg;
               }
               h1 { color: red }
             }
-            h1 { color: blue }''': (u'''@three-dee {
+            h1 { color: blue }''': ('''@three-dee {
     @background-lighting {
         azimuth: 30deg;
         elevation: 190deg;
@@ -426,7 +426,7 @@ a {
     }
 h1 {
     color: blue
-    }''', u'''h1 {
+    }''', '''h1 {
     color: blue
     }''')
         }
@@ -496,10 +496,10 @@ h1 {
         s = cssutils.parseString('a { x:1;y:2}')
         self.assertEqual('a {\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
         # cannot be indented as no split possible
-        cssutils.ser.prefs.lineSeparator = u''
+        cssutils.ser.prefs.lineSeparator = ''
         self.assertEqual('a {x: 1;y: 2    }'.encode(), s.cssText)
         # no valid css but should work
-        cssutils.ser.prefs.lineSeparator = u'XXX'
+        cssutils.ser.prefs.lineSeparator = 'XXX'
         self.assertEqual('a {XXX    x: 1;XXX    y: 2XXX    }'.encode(), s.cssText)
 
     def test_listItemSpacer(self):
@@ -510,25 +510,25 @@ h1 {
         @import "x" print, tv;
 a, b {}'''
         s = cssutils.parseString(css)
-        self.assertEqual(u'@import "x" print, tv;\na, b {}'.encode(), s.cssText)
-        cssutils.ser.prefs.listItemSpacer = u''
-        self.assertEqual(u'@import "x" print,tv;\na,b {}'.encode(), s.cssText)
+        self.assertEqual('@import "x" print, tv;\na, b {}'.encode(), s.cssText)
+        cssutils.ser.prefs.listItemSpacer = ''
+        self.assertEqual('@import "x" print,tv;\na,b {}'.encode(), s.cssText)
 
     def test_minimizeColorHash(self):
         "Preferences.minimizeColorHash"
         css = 'a { color: #ffffff }'
         s = cssutils.parseString(css)
-        self.assertEqual(u'a {\n    color: #fff\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    color: #fff\n    }'.encode(), s.cssText)
         cssutils.ser.prefs.minimizeColorHash = False
-        self.assertEqual(u'a {\n    color: #ffffff\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    color: #ffffff\n    }'.encode(), s.cssText)
         
     def test_omitLastSemicolon(self):
         "Preferences.omitLastSemicolon"
         css = 'a { x: 1; y: 2 }'
         s = cssutils.parseString(css)
-        self.assertEqual(u'a {\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
         cssutils.ser.prefs.omitLastSemicolon = False
-        self.assertEqual(u'a {\n    x: 1;\n    y: 2;\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    x: 1;\n    y: 2;\n    }'.encode(), s.cssText)
         
     def test_normalizedVarNames(self):
         "Preferences.normalizedVarNames"
@@ -536,9 +536,9 @@ a, b {}'''
         
         css = '@variables { A: 1 }'
         s = cssutils.parseString(css)
-        self.assertEqual(u'@variables {\n    a: 1\n    }'.encode(), s.cssText)
+        self.assertEqual('@variables {\n    a: 1\n    }'.encode(), s.cssText)
         cssutils.ser.prefs.normalizedVarNames = False
-        self.assertEqual(u'@variables {\n    A: 1\n    }'.encode(), s.cssText)
+        self.assertEqual('@variables {\n    A: 1\n    }'.encode(), s.cssText)
 
         cssutils.ser.prefs.resolveVariables = True
 
@@ -546,38 +546,38 @@ a, b {}'''
         "Preferences.paranthesisSpacer"
         css = 'a { x: 1; y: 2 }'
         s = cssutils.parseString(css)
-        self.assertEqual(u'a {\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
-        cssutils.ser.prefs.paranthesisSpacer = u''
-        self.assertEqual(u'a{\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
+        cssutils.ser.prefs.paranthesisSpacer = ''
+        self.assertEqual('a{\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
         
     def test_propertyNameSpacer(self):
         "Preferences.propertyNameSpacer"
         css = 'a { x: 1; y: 2 }'
         s = cssutils.parseString(css)
-        self.assertEqual(u'a {\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
-        cssutils.ser.prefs.propertyNameSpacer = u''
-        self.assertEqual(u'a {\n    x:1;\n    y:2\n    }'.encode(), s.cssText)
+        self.assertEqual('a {\n    x: 1;\n    y: 2\n    }'.encode(), s.cssText)
+        cssutils.ser.prefs.propertyNameSpacer = ''
+        self.assertEqual('a {\n    x:1;\n    y:2\n    }'.encode(), s.cssText)
         
     def test_selectorCombinatorSpacer(self):
         "Preferences.selectorCombinatorSpacer"
         s = cssutils.css.Selector(selectorText='a+b>c~d  e')
-        self.assertEqual(u'a + b > c ~ d e', s.selectorText)
-        cssutils.ser.prefs.selectorCombinatorSpacer = u''
-        self.assertEqual(u'a+b>c~d e', s.selectorText)
+        self.assertEqual('a + b > c ~ d e', s.selectorText)
+        cssutils.ser.prefs.selectorCombinatorSpacer = ''
+        self.assertEqual('a+b>c~d e', s.selectorText)
         
     def test_spacer(self):
-        cssutils.ser.prefs.spacer = u''
+        cssutils.ser.prefs.spacer = ''
         tests = {
-            u'@font-face {a:1}': u'@font-face {\n    a: 1\n    }',
-            u'@import  url( a );': u'@import url(a);',
-            u'@media  all{a{color:red}}': u'@media all {\n    a {\n        color: red\n        }\n    }',
-            u'@namespace "a";': u'@namespace"a";',
-            u'@namespace a  "a";': u'@namespace a"a";',
-            u'@page  :left {   a  :1  }': u'@page :left {\n    a: 1\n    }',
-            u'@x  x;': u'@x x;',
-            u'@import"x"tv': u'@import"x"tv;' # ?
+            '@font-face {a:1}': '@font-face {\n    a: 1\n    }',
+            '@import  url( a );': '@import url(a);',
+            '@media  all{a{color:red}}': '@media all {\n    a {\n        color: red\n        }\n    }',
+            '@namespace "a";': '@namespace"a";',
+            '@namespace a  "a";': '@namespace a"a";',
+            '@page  :left {   a  :1  }': '@page :left {\n    a: 1\n    }',
+            '@x  x;': '@x x;',
+            '@import"x"tv': '@import"x"tv;' # ?
             }
-        for css, exp in tests.items():
+        for css, exp in list(tests.items()):
             self.assertEqual(exp.encode(), cssutils.parseString(css).cssText)
             
     def test_validOnly(self):
@@ -594,17 +594,17 @@ a, b {}'''
         # CSSStyleDeclaration has no actual property valid
         # but is empty if containing invalid Properties only
         s = cssutils.css.CSSStyleDeclaration()
-        s.cssText = u'left: x;top: x'
-        self.assertEqual(s.cssText, u'left: x;\ntop: x')
+        s.cssText = 'left: x;top: x'
+        self.assertEqual(s.cssText, 'left: x;\ntop: x')
         cssutils.ser.prefs.validOnly = True
-        self.assertEqual(s.cssText, u'')
+        self.assertEqual(s.cssText, '')
 
         cssutils.ser.prefs.useDefaults()
         cssutils.ser.prefs.keepComments = False
         cssutils.ser.prefs.validOnly = True
         tests = {
-            u'h1 { color: red; rotation: 70minutes }': 'h1 {\n    color: red;\n    }',
-            u'''img { float: left }       /* correct CSS 2.1 */
+            'h1 { color: red; rotation: 70minutes }': 'h1 {\n    color: red;\n    }',
+            '''img { float: left }       /* correct CSS 2.1 */
 img { float: left here }  /* "here" is not a value of 'float' */
 img { background: "red" } /* keywords cannot be quoted */
 img { border-width: 3 }   /* a unit must be specified for length values */''': 'img {\n    float: left\n    }'
@@ -625,58 +625,58 @@ class CSSSerializerTestCase(basetest.BaseTestCase):
 
     def test_canonical(self):
         tests = {
-            u'''1''': u'''1''',
+            '''1''': '''1''',
             # => remove +
-            u'''+1''': u'''+1''',
+            '''+1''': '''+1''',
             # 0 => remove unit
-            u'''0''': u'''0''',
-            u'''+0''': u'''0''',
-            u'''-0''': u'''0''',
-            u'''0.0''': u'''0''',
-            u'''00.0''': u'''0''',
-            u'''00.0px''': u'''0''',
-            u'''00.0pc''': u'''0''',
-            u'''00.0em''': u'''0''',
-            u'''00.0ex''': u'''0''',
-            u'''00.0cm''': u'''0''',
-            u'''00.0mm''': u'''0''',
-            u'''00.0in''': u'''0''',
+            '''0''': '''0''',
+            '''+0''': '''0''',
+            '''-0''': '''0''',
+            '''0.0''': '''0''',
+            '''00.0''': '''0''',
+            '''00.0px''': '''0''',
+            '''00.0pc''': '''0''',
+            '''00.0em''': '''0''',
+            '''00.0ex''': '''0''',
+            '''00.0cm''': '''0''',
+            '''00.0mm''': '''0''',
+            '''00.0in''': '''0''',
             # 0 => keep unit
-            u'''00.0%''': u'''0%''',
-            u'''00.0ms''': u'''0ms''',
-            u'''00.0s''': u'''0s''',
-            u'''00.0khz''': u'''0khz''',
-            u'''00.0hz''': u'''0hz''',
-            u'''00.0khz''': u'''0khz''',
-            u'''00.0deg''': u'''0deg''',
-            u'''00.0rad''': u'''0rad''',
-            u'''00.0grad''': u'''0grad''',
-            u'''00.0xx''': u'''0xx''',
+            '''00.0%''': '''0%''',
+            '''00.0ms''': '''0ms''',
+            '''00.0s''': '''0s''',
+            '''00.0khz''': '''0khz''',
+            '''00.0hz''': '''0hz''',
+            '''00.0khz''': '''0khz''',
+            '''00.0deg''': '''0deg''',
+            '''00.0rad''': '''0rad''',
+            '''00.0grad''': '''0grad''',
+            '''00.0xx''': '''0xx''',
             # 11. 
-            u'''a, 'b"', serif''': ur'''a, "b\"", serif''',
+            '''a, 'b"', serif''': r'''a, "b\"", serif''',
             # SHOULD: \[ => [ but keep!
-            ur"""url('h)i') '\[\]'""": ur'''url("h)i") "\[\]"''',
-            u'''rgb(18, 52, 86)''': u'''rgb(18, 52, 86)''',
-            u'''#123456''': u'''#123456''',
+            r"""url('h)i') '\[\]'""": r'''url("h)i") "\[\]"''',
+            '''rgb(18, 52, 86)''': '''rgb(18, 52, 86)''',
+            '''#123456''': '''#123456''',
             # SHOULD => #112233
-            u'''#112233''': u'''#123''',
+            '''#112233''': '''#123''',
             # SHOULD => #000000
 #            u'rgba(000001, 0, 0, 1)': u'#000'
             }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             v = cssutils.css.PropertyValue(test)
             self.assertEqual(exp, v.cssText)
 
 
     def test_CSSStyleSheet(self):
         "CSSSerializer.do_CSSStyleSheet"
-        css = u'/* κουρος */'
+        css = '/* κουρος */'
         sheet = cssutils.parseString(css)
-        self.assertEqual(css, unicode(sheet.cssText, 'utf-8'))
+        self.assertEqual(css, str(sheet.cssText, 'utf-8'))
         
-        css = u'@charset "utf-8";\n/* κουρος */'
+        css = '@charset "utf-8";\n/* κουρος */'
         sheet = cssutils.parseString(css)
-        self.assertEqual(css, unicode(sheet.cssText, 'utf-8'))
+        self.assertEqual(css, str(sheet.cssText, 'utf-8'))
         sheet.cssRules[0].encoding = 'ascii'
         self.assertEqual('@charset "ascii";\n/* \\3BA \\3BF \\3C5 \\3C1 \\3BF \\3C2  */'.encode(), 
                          sheet.cssText)
@@ -690,18 +690,18 @@ class CSSSerializerTestCase(basetest.BaseTestCase):
 
         s = cssutils.css.property.Property(
             name=name, value=value, priority=priority)
-        self.assertEqual(u'color: red !important',
+        self.assertEqual('color: red !important',
                     cssutils.ser.do_Property(s))
 
         s = cssutils.css.property.Property(
             name=name, value=value)
-        self.assertEqual(u'color: red',
+        self.assertEqual('color: red',
                     cssutils.ser.do_Property(s))
 
     def test_escapestring(self):
         "CSSSerializer._escapestring"
         #'"\a\22\27"'  
-        css = ur'''@import url("ABC\a");
+        css = r'''@import url("ABC\a");
 @import "ABC\a";
 @import 'ABC\a';
 a[href='"\a\22\27"'] {
@@ -727,7 +727,7 @@ a[href='"\a\22\27"'] {
 #    g: "2\\ 1\ 2\\";
 #    content: "\27"
 #    }'''
-        exp = ur'''@import url("ABC\a ");
+        exp = r'''@import url("ABC\a ");
 @import "ABC\a ";
 @import "ABC\a ";
 a[href="\"\a \"'\""] {
diff --git a/src/cssutils/tests/test_settings.py b/src/cssutils/tests/test_settings.py
index e4b25fd..cf38523 100644
--- a/src/cssutils/tests/test_settings.py
+++ b/src/cssutils/tests/test_settings.py
@@ -1,7 +1,7 @@
 """Testcases for cssutils.settings"""
 __version__ = '$Id: test_csscharsetrule.py 1356 2008-07-13 17:29:09Z cthedot $'
 
-import test_cssrule
+from . import test_cssrule
 import cssutils
 import cssutils.settings
 
@@ -10,7 +10,7 @@ class Settings(test_cssrule.CSSRuleTestCase):
     def test_set(self):
         "settings.set()"
         cssutils.ser.prefs.useMinified()
-        text = u'a {filter: progid:DXImageTransform.Microsoft.BasicImage( rotation = 90 )}'
+        text = 'a {filter: progid:DXImageTransform.Microsoft.BasicImage( rotation = 90 )}'
         
         self.assertEqual(cssutils.parseString(text).cssText, ''.encode())
         
diff --git a/src/cssutils/tests/test_stylesheet.py b/src/cssutils/tests/test_stylesheet.py
index 0ebef57..97cbf5d 100644
--- a/src/cssutils/tests/test_stylesheet.py
+++ b/src/cssutils/tests/test_stylesheet.py
@@ -2,7 +2,7 @@
 __version__ = '$Id: test_csspagerule.py 1869 2009-10-17 19:37:40Z cthedot $'
 
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 
 class StyleSheetTestCase(basetest.BaseTestCase):
@@ -14,7 +14,7 @@ class StyleSheetTestCase(basetest.BaseTestCase):
         self.assertEqual(s.type, 'text/css')
         self.assertEqual(s.href, None)
         self.assertEqual(s.media, None)
-        self.assertEqual(s.title, u'')
+        self.assertEqual(s.title, '')
         self.assertEqual(s.ownerNode, None)
         self.assertEqual(s.parentStyleSheet, None)
         self.assertEqual(s.alternate, False)
@@ -24,7 +24,7 @@ class StyleSheetTestCase(basetest.BaseTestCase):
         s = cssutils.stylesheets.StyleSheet(type='unknown',
                                             href='test.css',
                                             media=None,
-                                            title=u'title',
+                                            title='title',
                                             ownerNode=None,
                                             parentStyleSheet=None,
                                             alternate=True,
@@ -33,7 +33,7 @@ class StyleSheetTestCase(basetest.BaseTestCase):
         self.assertEqual(s.type, 'unknown')
         self.assertEqual(s.href, 'test.css')
         self.assertEqual(s.media, None)
-        self.assertEqual(s.title, u'title')
+        self.assertEqual(s.title, 'title')
         self.assertEqual(s.ownerNode, None)
         self.assertEqual(s.parentStyleSheet, None)
         self.assertEqual(s.alternate, True)
diff --git a/src/cssutils/tests/test_tokenize2.py b/src/cssutils/tests/test_tokenize2.py
index 3b4c76b..476398c 100644
--- a/src/cssutils/tests/test_tokenize2.py
+++ b/src/cssutils/tests/test_tokenize2.py
@@ -6,7 +6,7 @@ TODO: old tests as new ones are **not complete**!
 
 import sys
 import xml.dom
-import basetest
+from . import basetest
 import cssutils.tokenize2 as tokenize2
 from cssutils.tokenize2 import *
 
@@ -14,82 +14,82 @@ class TokenizerTestCase(basetest.BaseTestCase):
 
     testsall = {
         # IDENT
-        u'äöüß€': [('IDENT', u'äöüß€', 1, 1)],
-        u' a ': [('S', u' ', 1, 1),
-                 ('IDENT', u'a', 1, 2),
-                 ('S', u' ', 1, 3)],
-        u'_a': [('IDENT', u'_a', 1, 1)],
-        u'-a': [('IDENT', u'-a', 1, 1)],
-        u'aA-_\200\377': [('IDENT', u'aA-_\200\377', 1, 1)],
-        u'a1': [('IDENT', u'a1', 1, 1)],
+        'äöüß€': [('IDENT', 'äöüß€', 1, 1)],
+        ' a ': [('S', ' ', 1, 1),
+                 ('IDENT', 'a', 1, 2),
+                 ('S', ' ', 1, 3)],
+        '_a': [('IDENT', '_a', 1, 1)],
+        '-a': [('IDENT', '-a', 1, 1)],
+        'aA-_\200\377': [('IDENT', 'aA-_\200\377', 1, 1)],
+        'a1': [('IDENT', 'a1', 1, 1)],
         # escapes must end with S or max 6 digits:
-        u'\\44 b': [('IDENT', u'Db', 1, 1)],
-        u'\\44  b': [('IDENT', u'D', 1, 1),
-                     ('S', u' ', 1, 5),
-                     ('IDENT', u'b', 1, 6)],
-        u'\\44\nb': [('IDENT', u'Db', 1, 1)],
-        u'\\44\rb': [('IDENT', u'Db', 1, 1)],
-        u'\\44\fb': [('IDENT', u'Db', 1, 1)],
-        u'\\44\n*': [('IDENT', u'D', 1, 1),
-                    ('CHAR', u'*', 2, 1)],
-        u'\\44  a': [('IDENT', u'D', 1, 1),
-                    ('S', u' ', 1, 5),
-                    ('IDENT', u'a', 1, 6)],
+        '\\44 b': [('IDENT', 'Db', 1, 1)],
+        '\\44  b': [('IDENT', 'D', 1, 1),
+                     ('S', ' ', 1, 5),
+                     ('IDENT', 'b', 1, 6)],
+        '\\44\nb': [('IDENT', 'Db', 1, 1)],
+        '\\44\rb': [('IDENT', 'Db', 1, 1)],
+        '\\44\fb': [('IDENT', 'Db', 1, 1)],
+        '\\44\n*': [('IDENT', 'D', 1, 1),
+                    ('CHAR', '*', 2, 1)],
+        '\\44  a': [('IDENT', 'D', 1, 1),
+                    ('S', ' ', 1, 5),
+                    ('IDENT', 'a', 1, 6)],
         # TODO:
         # Note that this means that a "real" space after the escape sequence
         # must itself either be escaped or doubled:
-        u'\\44\ x': [('IDENT', u'D\\ x', 1, 1)],
-        u'\\44  ': [('IDENT', u'D', 1, 1),
-                     ('S', u' ', 1, 5)],
-
-        ur'\44': [('IDENT', u'D', 1, 1)],
-        ur'\\': [('IDENT', ur'\\', 1, 1)],
-        ur'\{': [('IDENT', ur'\{', 1, 1)],
-        ur'\"': [('IDENT', ur'\"', 1, 1)],
-        ur'\(': [('IDENT', ur'\(', 1, 1)],
-        ur'\1 \22 \333 \4444 \55555 \666666 \777777 7 \7777777':
+        '\\44\ x': [('IDENT', 'D\\ x', 1, 1)],
+        '\\44  ': [('IDENT', 'D', 1, 1),
+                     ('S', ' ', 1, 5)],
+
+        r'\44': [('IDENT', 'D', 1, 1)],
+        r'\\': [('IDENT', r'\\', 1, 1)],
+        r'\{': [('IDENT', r'\{', 1, 1)],
+        r'\"': [('IDENT', r'\"', 1, 1)],
+        r'\(': [('IDENT', r'\(', 1, 1)],
+        r'\1 \22 \333 \4444 \55555 \666666 \777777 7 \7777777':
             [(
-                ('IDENT', u'\x01"\u0333\u4444\U00055555\\666666 \\777777 7', 1, 1)
+                ('IDENT', '\x01"\u0333\u4444\U00055555\\666666 \\777777 7', 1, 1)
                 if sys.maxunicode > 0x10000 else
-                ('IDENT', u'\x01"\u0333\u4444\\55555 \\666666 \\777777 7', 1, 1)
+                ('IDENT', '\x01"\u0333\u4444\\55555 \\666666 \\777777 7', 1, 1)
             ),
             ('S', ' ', 1, 43),
             ('IDENT', '\\7777777', 1, 44)
         ],
         # Not a function, important for media queries
-        u'and(': [('IDENT', u'and', 1, 1), ('CHAR', u'(', 1, 4)],
+        'and(': [('IDENT', 'and', 1, 1), ('CHAR', '(', 1, 4)],
 
 
-        u'\\1 b': [('IDENT', u'\x01b', 1, 1)],
-        u'\\44 b': [('IDENT', u'Db', 1, 1)],
-        u'\\123 b': [('IDENT', u'\u0123b', 1, 1)],
-        u'\\1234 b': [('IDENT', u'\u1234b', 1, 1)],
-        u'\\12345 b':
+        '\\1 b': [('IDENT', '\x01b', 1, 1)],
+        '\\44 b': [('IDENT', 'Db', 1, 1)],
+        '\\123 b': [('IDENT', '\u0123b', 1, 1)],
+        '\\1234 b': [('IDENT', '\u1234b', 1, 1)],
+        '\\12345 b':
             [(
-                ('IDENT', u'\U00012345b', 1, 1)
+                ('IDENT', '\U00012345b', 1, 1)
                 if sys.maxunicode > 0x10000 else
-                ('IDENT', u'\\12345 b', 1, 1)
+                ('IDENT', '\\12345 b', 1, 1)
             )],
-        u'\\123456 b': [('IDENT', u'\\123456 b', 1, 1)],
-        u'\\1234567 b': [('IDENT', u'\\1234567', 1, 1),
-                         ('S', u' ', 1, 9),
-                         ('IDENT', u'b', 1, 10)],
-        u'\\{\\}\\(\\)\\[\\]\\#\\@\\.\\,':
-            [('IDENT', u'\\{\\}\\(\\)\\[\\]\\#\\@\\.\\,', 1, 1)],
+        '\\123456 b': [('IDENT', '\\123456 b', 1, 1)],
+        '\\1234567 b': [('IDENT', '\\1234567', 1, 1),
+                         ('S', ' ', 1, 9),
+                         ('IDENT', 'b', 1, 10)],
+        '\\{\\}\\(\\)\\[\\]\\#\\@\\.\\,':
+            [('IDENT', '\\{\\}\\(\\)\\[\\]\\#\\@\\.\\,', 1, 1)],
 
         # STRING
-        u' "" ': [('S', u' ', 1, 1),
-                 ('STRING', u'""', 1, 2),
-                 ('S', u' ', 1, 4)],
-        u' "\'" ': [('S', u' ', 1, 1),
-                 ('STRING', u'"\'"', 1, 2),
-                 ('S', u' ', 1, 5)],
-        u" '' ": [('S', u' ', 1, 1),
-                 ('STRING', u"''", 1, 2),
-                 ('S', u' ', 1, 4)],
-        u" '' ": [('S', u' ', 1, 1),
-                 ('STRING', u"''", 1, 2),
-                 ('S', u' ', 1, 4)],
+        ' "" ': [('S', ' ', 1, 1),
+                 ('STRING', '""', 1, 2),
+                 ('S', ' ', 1, 4)],
+        ' "\'" ': [('S', ' ', 1, 1),
+                 ('STRING', '"\'"', 1, 2),
+                 ('S', ' ', 1, 5)],
+        " '' ": [('S', ' ', 1, 1),
+                 ('STRING', "''", 1, 2),
+                 ('S', ' ', 1, 4)],
+        " '' ": [('S', ' ', 1, 1),
+                 ('STRING', "''", 1, 2),
+                 ('S', ' ', 1, 4)],
         # until 0.9.5.x
         #u"'\\\n'": [('STRING', u"'\\\n'", 1, 1)],
         #u"'\\\n\\\n\\\n'": [('STRING', u"'\\\n\\\n\\\n'", 1, 1)],
@@ -98,238 +98,238 @@ class TokenizerTestCase(basetest.BaseTestCase):
         #u"'\\\r\n'": [('STRING', u"'\\\r\n'", 1, 1)],
         #u"'1\\\n2'": [('STRING', u"'1\\\n2'", 1, 1)],
         # from 0.9.6a0 escaped nl is removed from string
-        u"'\\\n'": [('STRING', u"''", 1, 1)],
-        u"'\\\n\\\n\\\n'": [('STRING', u"''", 1, 1)],
-        u"'\\\f'": [('STRING', u"''", 1, 1)],
-        u"'\\\r'": [('STRING', u"''", 1, 1)],
-        u"'1\\\n2'": [('STRING', u"'12'", 1, 1)],
-        u"'1\\\r\n2'": [('STRING', u"'12'", 1, 1)],
+        "'\\\n'": [('STRING', "''", 1, 1)],
+        "'\\\n\\\n\\\n'": [('STRING', "''", 1, 1)],
+        "'\\\f'": [('STRING', "''", 1, 1)],
+        "'\\\r'": [('STRING', "''", 1, 1)],
+        "'1\\\n2'": [('STRING', "'12'", 1, 1)],
+        "'1\\\r\n2'": [('STRING', "'12'", 1, 1)],
         #ur'"\0020|\0020"': [('STRING', u'"\\0020|\\0020"', 1, 1)],
-        ur'"\61|\0061"': [('STRING', u'"a|a"', 1, 1)],
+        r'"\61|\0061"': [('STRING', '"a|a"', 1, 1)],
 
         # HASH
-        u' #a ': [('S', u' ', 1, 1),
-                 ('HASH', u'#a', 1, 2),
-                 ('S', u' ', 1, 4)],
+        ' #a ': [('S', ' ', 1, 1),
+                 ('HASH', '#a', 1, 2),
+                 ('S', ' ', 1, 4)],
 
-        u'#ccc': [('HASH', u'#ccc', 1, 1)],
-        u'#111': [('HASH', u'#111', 1, 1)],
-        u'#a1a1a1': [('HASH', u'#a1a1a1', 1, 1)],
-        u'#1a1a1a': [('HASH', u'#1a1a1a', 1, 1)],
+        '#ccc': [('HASH', '#ccc', 1, 1)],
+        '#111': [('HASH', '#111', 1, 1)],
+        '#a1a1a1': [('HASH', '#a1a1a1', 1, 1)],
+        '#1a1a1a': [('HASH', '#1a1a1a', 1, 1)],
 
         # NUMBER, for plus see CSS3
-        u' 0 ': [('S', u' ', 1, 1),
-                 ('NUMBER', u'0', 1, 2),
-                 ('S', u' ', 1, 3)],
-        u' 0.1 ': [('S', u' ', 1, 1),
-                 ('NUMBER', u'0.1', 1, 2),
-                 ('S', u' ', 1, 5)],
-        u' .0 ': [('S', u' ', 1, 1),
-                 ('NUMBER', u'.0', 1, 2),
-                 ('S', u' ', 1, 4)],
-
-        u' -0 ': [('S', u' ', 1, 1),
+        ' 0 ': [('S', ' ', 1, 1),
+                 ('NUMBER', '0', 1, 2),
+                 ('S', ' ', 1, 3)],
+        ' 0.1 ': [('S', ' ', 1, 1),
+                 ('NUMBER', '0.1', 1, 2),
+                 ('S', ' ', 1, 5)],
+        ' .0 ': [('S', ' ', 1, 1),
+                 ('NUMBER', '.0', 1, 2),
+                 ('S', ' ', 1, 4)],
+
+        ' -0 ': [('S', ' ', 1, 1),
                  #('CHAR', u'-', 1, 2),
                  #('NUMBER', u'0', 1, 3),
-                 ('NUMBER', u'-0', 1, 2),
-                 ('S', u' ', 1, 4)],
+                 ('NUMBER', '-0', 1, 2),
+                 ('S', ' ', 1, 4)],
 
         # PERCENTAGE
-        u' 0% ': [('S', u' ', 1, 1),
-                 ('PERCENTAGE', u'0%', 1, 2),
-                 ('S', u' ', 1, 4)],
-        u' .5% ': [('S', u' ', 1, 1),
-                 ('PERCENTAGE', u'.5%', 1, 2),
-                 ('S', u' ', 1, 5)],
+        ' 0% ': [('S', ' ', 1, 1),
+                 ('PERCENTAGE', '0%', 1, 2),
+                 ('S', ' ', 1, 4)],
+        ' .5% ': [('S', ' ', 1, 1),
+                 ('PERCENTAGE', '.5%', 1, 2),
+                 ('S', ' ', 1, 5)],
 
         # URI
-        u' url() ': [('S', u' ', 1, 1),
-                 ('URI', u'url()', 1, 2),
-                 ('S', u' ', 1, 7)],
-        u' url(a) ': [('S', u' ', 1, 1),
-                 ('URI', u'url(a)', 1, 2),
-                 ('S', u' ', 1, 8)],
-        u' url("a") ': [('S', u' ', 1, 1),
-                 ('URI', u'url("a")', 1, 2),
-                 ('S', u' ', 1, 10)],
-        u' url( a ) ': [('S', u' ', 1, 1),
-                 ('URI', u'url( a )', 1, 2),
-                 ('S', u' ', 1, 10)],
+        ' url() ': [('S', ' ', 1, 1),
+                 ('URI', 'url()', 1, 2),
+                 ('S', ' ', 1, 7)],
+        ' url(a) ': [('S', ' ', 1, 1),
+                 ('URI', 'url(a)', 1, 2),
+                 ('S', ' ', 1, 8)],
+        ' url("a") ': [('S', ' ', 1, 1),
+                 ('URI', 'url("a")', 1, 2),
+                 ('S', ' ', 1, 10)],
+        ' url( a ) ': [('S', ' ', 1, 1),
+                 ('URI', 'url( a )', 1, 2),
+                 ('S', ' ', 1, 10)],
 
         # UNICODE-RANGE
 
         # CDO
-        u' <!-- ': [('S', u' ', 1, 1),
-                   ('CDO', u'<!--', 1, 2),
-                   ('S', u' ', 1, 6)],
-        u'"<!--""-->"': [('STRING', u'"<!--"', 1, 1),
-                    ('STRING', u'"-->"', 1, 7)],
+        ' <!-- ': [('S', ' ', 1, 1),
+                   ('CDO', '<!--', 1, 2),
+                   ('S', ' ', 1, 6)],
+        '"<!--""-->"': [('STRING', '"<!--"', 1, 1),
+                    ('STRING', '"-->"', 1, 7)],
 
         # CDC
-        u' --> ': [('S', u' ', 1, 1),
-                  ('CDC', u'-->', 1, 2),
-                  ('S', u' ', 1, 5)],
+        ' --> ': [('S', ' ', 1, 1),
+                  ('CDC', '-->', 1, 2),
+                  ('S', ' ', 1, 5)],
 
         # S
-        u' ': [('S', u' ', 1, 1)],
-        u'  ': [('S', u'  ', 1, 1)],
-        u'\r': [('S', u'\r', 1, 1)],
-        u'\n': [('S', u'\n', 1, 1)],
-        u'\r\n': [('S', u'\r\n', 1, 1)],
-        u'\f': [('S', u'\f', 1, 1)],
-        u'\r': [('S', u'\r', 1, 1)],
-        u'\t': [('S', u'\t', 1, 1)],
-        u'\r\n\r\n\f\t ': [('S', u'\r\n\r\n\f\t ', 1, 1)],
+        ' ': [('S', ' ', 1, 1)],
+        '  ': [('S', '  ', 1, 1)],
+        '\r': [('S', '\r', 1, 1)],
+        '\n': [('S', '\n', 1, 1)],
+        '\r\n': [('S', '\r\n', 1, 1)],
+        '\f': [('S', '\f', 1, 1)],
+        '\r': [('S', '\r', 1, 1)],
+        '\t': [('S', '\t', 1, 1)],
+        '\r\n\r\n\f\t ': [('S', '\r\n\r\n\f\t ', 1, 1)],
 
         # COMMENT, for incomplete see later
-        u'/*x*/ ': [('COMMENT', u'/*x*/', 1, 1),
-                    ('S', u' ', 1, 6)],
+        '/*x*/ ': [('COMMENT', '/*x*/', 1, 1),
+                    ('S', ' ', 1, 6)],
 
         # FUNCTION
-        u' x( ': [('S', u' ', 1, 1),
-                  ('FUNCTION', u'x(', 1, 2),
-                  ('S', u' ', 1, 4)],
+        ' x( ': [('S', ' ', 1, 1),
+                  ('FUNCTION', 'x(', 1, 2),
+                  ('S', ' ', 1, 4)],
 
         # INCLUDES
-        u' ~= ': [('S', u' ', 1, 1),
-                  ('INCLUDES', u'~=', 1, 2),
-                  ('S', u' ', 1, 4)],
-        u'~==': [('INCLUDES', u'~=', 1, 1), ('CHAR', u'=', 1, 3)],
+        ' ~= ': [('S', ' ', 1, 1),
+                  ('INCLUDES', '~=', 1, 2),
+                  ('S', ' ', 1, 4)],
+        '~==': [('INCLUDES', '~=', 1, 1), ('CHAR', '=', 1, 3)],
 
         # DASHMATCH
-        u' |= ': [('S', u' ', 1, 1),
-                  ('DASHMATCH', u'|=', 1, 2),
-                  ('S', u' ', 1, 4)],
-        u'|==': [('DASHMATCH', u'|=', 1, 1), ('CHAR', u'=', 1, 3)],
+        ' |= ': [('S', ' ', 1, 1),
+                  ('DASHMATCH', '|=', 1, 2),
+                  ('S', ' ', 1, 4)],
+        '|==': [('DASHMATCH', '|=', 1, 1), ('CHAR', '=', 1, 3)],
 
         # CHAR
-        u' @ ': [('S', u' ', 1, 1),
-                  ('CHAR', u'@', 1, 2),
-                  ('S', u' ', 1, 3)],
+        ' @ ': [('S', ' ', 1, 1),
+                  ('CHAR', '@', 1, 2),
+                  ('S', ' ', 1, 3)],
 
         # --- overwritten for CSS 2.1 ---
         # LBRACE
-        u' { ': [('S', u' ', 1, 1),
-                 ('CHAR', u'{', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' { ': [('S', ' ', 1, 1),
+                 ('CHAR', '{', 1, 2),
+                 ('S', ' ', 1, 3)],
         # PLUS
-        u' + ': [('S', u' ', 1, 1),
-                 ('CHAR', u'+', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' + ': [('S', ' ', 1, 1),
+                 ('CHAR', '+', 1, 2),
+                 ('S', ' ', 1, 3)],
         # GREATER
-        u' > ': [('S', u' ', 1, 1),
-                 ('CHAR', u'>', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' > ': [('S', ' ', 1, 1),
+                 ('CHAR', '>', 1, 2),
+                 ('S', ' ', 1, 3)],
         # COMMA
-        u' , ': [('S', u' ', 1, 1),
-                 ('CHAR', u',', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' , ': [('S', ' ', 1, 1),
+                 ('CHAR', ',', 1, 2),
+                 ('S', ' ', 1, 3)],
         # class
-        u' . ': [('S', u' ', 1, 1),
-                  ('CHAR', u'.', 1, 2),
-                  ('S', u' ', 1, 3)],
+        ' . ': [('S', ' ', 1, 1),
+                  ('CHAR', '.', 1, 2),
+                  ('S', ' ', 1, 3)],
         }
 
     tests3 = {
         # UNICODE-RANGE
-        u' u+0 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+0', 1, 2),
-                  ('S', u' ', 1, 5)],
-        u' u+01 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+01', 1, 2),
-                  ('S', u' ', 1, 6)],
-        u' u+012 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+012', 1, 2),
-                  ('S', u' ', 1, 7)],
-        u' u+0123 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+0123', 1, 2),
-                  ('S', u' ', 1, 8)],
-        u' u+01234 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+01234', 1, 2),
-                  ('S', u' ', 1, 9)],
-        u' u+012345 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+012345', 1, 2),
-                  ('S', u' ', 1, 10)],
-        u' u+0123456 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+012345', 1, 2),
-                  ('NUMBER', u'6', 1, 10),
-                  ('S', u' ', 1, 11)],
-        u' U+123456 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'U+123456', 1, 2),
-                  ('S', u' ', 1, 10)],
-        u' \\55+abcdef ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'U+abcdef', 1, 2),
-                  ('S', u' ', 1, 12)],
-        u' \\75+abcdef ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+abcdef', 1, 2),
-                  ('S', u' ', 1, 12)],
-        u' u+0-1 ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+0-1', 1, 2),
-                  ('S', u' ', 1, 7)],
-        u' u+0-1, u+123456-abcdef ': [('S', u' ', 1, 1),
-                  ('UNICODE-RANGE', u'u+0-1', 1, 2),
-                  ('CHAR', u',', 1, 7),
-                  ('S', u' ', 1, 8),
-                  ('UNICODE-RANGE', u'u+123456-abcdef', 1, 9),
-                  ('S', u' ', 1, 24)],
+        ' u+0 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+0', 1, 2),
+                  ('S', ' ', 1, 5)],
+        ' u+01 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+01', 1, 2),
+                  ('S', ' ', 1, 6)],
+        ' u+012 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+012', 1, 2),
+                  ('S', ' ', 1, 7)],
+        ' u+0123 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+0123', 1, 2),
+                  ('S', ' ', 1, 8)],
+        ' u+01234 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+01234', 1, 2),
+                  ('S', ' ', 1, 9)],
+        ' u+012345 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+012345', 1, 2),
+                  ('S', ' ', 1, 10)],
+        ' u+0123456 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+012345', 1, 2),
+                  ('NUMBER', '6', 1, 10),
+                  ('S', ' ', 1, 11)],
+        ' U+123456 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'U+123456', 1, 2),
+                  ('S', ' ', 1, 10)],
+        ' \\55+abcdef ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'U+abcdef', 1, 2),
+                  ('S', ' ', 1, 12)],
+        ' \\75+abcdef ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+abcdef', 1, 2),
+                  ('S', ' ', 1, 12)],
+        ' u+0-1 ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+0-1', 1, 2),
+                  ('S', ' ', 1, 7)],
+        ' u+0-1, u+123456-abcdef ': [('S', ' ', 1, 1),
+                  ('UNICODE-RANGE', 'u+0-1', 1, 2),
+                  ('CHAR', ',', 1, 7),
+                  ('S', ' ', 1, 8),
+                  ('UNICODE-RANGE', 'u+123456-abcdef', 1, 9),
+                  ('S', ' ', 1, 24)],
 
         # specials
-        u'c\\olor': [('IDENT', u'c\\olor', 1, 1)],
+        'c\\olor': [('IDENT', 'c\\olor', 1, 1)],
         #u'-1': [('CHAR', u'-', 1, 1), ('NUMBER', u'1', 1, 2)],
         #u'-1px': [('CHAR', u'-', 1, 1), ('DIMENSION', u'1px', 1, 2)],
-        u'-1': [('NUMBER', u'-1', 1, 1)],
-        u'-1px': [('DIMENSION', u'-1px', 1, 1)],
+        '-1': [('NUMBER', '-1', 1, 1)],
+        '-1px': [('DIMENSION', '-1px', 1, 1)],
 
         # ATKEYWORD
-        u' @x ': [('S', u' ', 1, 1),
-                  ('ATKEYWORD', u'@x', 1, 2),
-                  ('S', u' ', 1, 4)],
-        u'@X': [('ATKEYWORD', u'@X', 1, 1)],
-        u'@\\x': [('ATKEYWORD', u'@\\x', 1, 1)],
+        ' @x ': [('S', ' ', 1, 1),
+                  ('ATKEYWORD', '@x', 1, 2),
+                  ('S', ' ', 1, 4)],
+        '@X': [('ATKEYWORD', '@X', 1, 1)],
+        '@\\x': [('ATKEYWORD', '@\\x', 1, 1)],
         # -
-        u'@1x': [('CHAR', u'@', 1, 1),
-                  ('DIMENSION', u'1x', 1, 2)],
+        '@1x': [('CHAR', '@', 1, 1),
+                  ('DIMENSION', '1x', 1, 2)],
 
         # DIMENSION
-        u' 0px ': [('S', u' ', 1, 1),
-                 ('DIMENSION', u'0px', 1, 2),
-                 ('S', u' ', 1, 5)],
-        u' 1s ': [('S', u' ', 1, 1),
-                 ('DIMENSION', u'1s', 1, 2),
-                 ('S', u' ', 1, 4)],
-        u'0.2EM': [('DIMENSION', u'0.2EM', 1, 1)],
-        u'1p\\x': [('DIMENSION', u'1p\\x', 1, 1)],
-        u'1PX': [('DIMENSION', u'1PX', 1, 1)],
+        ' 0px ': [('S', ' ', 1, 1),
+                 ('DIMENSION', '0px', 1, 2),
+                 ('S', ' ', 1, 5)],
+        ' 1s ': [('S', ' ', 1, 1),
+                 ('DIMENSION', '1s', 1, 2),
+                 ('S', ' ', 1, 4)],
+        '0.2EM': [('DIMENSION', '0.2EM', 1, 1)],
+        '1p\\x': [('DIMENSION', '1p\\x', 1, 1)],
+        '1PX': [('DIMENSION', '1PX', 1, 1)],
 
         # NUMBER
-        u' - 0 ': [('S', u' ', 1, 1),
-                 ('CHAR', u'-', 1, 2),
-                 ('S', u' ', 1, 3),
-                 ('NUMBER', u'0', 1, 4),
-                 ('S', u' ', 1, 5)],
-        u' + 0 ': [('S', u' ', 1, 1),
-                 ('CHAR', u'+', 1, 2),
-                 ('S', u' ', 1, 3),
-                 ('NUMBER', u'0', 1, 4),
-                 ('S', u' ', 1, 5)],
+        ' - 0 ': [('S', ' ', 1, 1),
+                 ('CHAR', '-', 1, 2),
+                 ('S', ' ', 1, 3),
+                 ('NUMBER', '0', 1, 4),
+                 ('S', ' ', 1, 5)],
+        ' + 0 ': [('S', ' ', 1, 1),
+                 ('CHAR', '+', 1, 2),
+                 ('S', ' ', 1, 3),
+                 ('NUMBER', '0', 1, 4),
+                 ('S', ' ', 1, 5)],
 
         # PREFIXMATCH
-        u' ^= ': [('S', u' ', 1, 1),
-                  ('PREFIXMATCH', u'^=', 1, 2),
-                  ('S', u' ', 1, 4)],
-        u'^==': [('PREFIXMATCH', u'^=', 1, 1), ('CHAR', u'=', 1, 3)],
+        ' ^= ': [('S', ' ', 1, 1),
+                  ('PREFIXMATCH', '^=', 1, 2),
+                  ('S', ' ', 1, 4)],
+        '^==': [('PREFIXMATCH', '^=', 1, 1), ('CHAR', '=', 1, 3)],
 
         # SUFFIXMATCH
-        u' $= ': [('S', u' ', 1, 1),
-                  ('SUFFIXMATCH', u'$=', 1, 2),
-                  ('S', u' ', 1, 4)],
-        u'$==': [('SUFFIXMATCH', u'$=', 1, 1), ('CHAR', u'=', 1, 3)],
+        ' $= ': [('S', ' ', 1, 1),
+                  ('SUFFIXMATCH', '$=', 1, 2),
+                  ('S', ' ', 1, 4)],
+        '$==': [('SUFFIXMATCH', '$=', 1, 1), ('CHAR', '=', 1, 3)],
 
         # SUBSTRINGMATCH
-        u' *= ': [('S', u' ', 1, 1),
-                  ('SUBSTRINGMATCH', u'*=', 1, 2),
-                  ('S', u' ', 1, 4)],
-        u'*==': [('SUBSTRINGMATCH', u'*=', 1, 1), ('CHAR', u'=', 1, 3)],
+        ' *= ': [('S', ' ', 1, 1),
+                  ('SUBSTRINGMATCH', '*=', 1, 2),
+                  ('S', ' ', 1, 4)],
+        '*==': [('SUBSTRINGMATCH', '*=', 1, 1), ('CHAR', '=', 1, 3)],
 
         # BOM only at start
 #        u'\xFEFF ': [('BOM', u'\xfeFF', 1, 1),
@@ -337,254 +337,254 @@ class TokenizerTestCase(basetest.BaseTestCase):
 #        u' \xFEFF ': [('S', u' ', 1, 1),
 #                  ('IDENT', u'\xfeFF', 1, 2),
 #                  ('S', u' ', 1, 5)],
-        u'\xfe\xff ': [('BOM', u'\xfe\xff', 1, 1),
-                  ('S', u' ', 1, 1)],
-        u' \xfe\xff ': [('S', u' ', 1, 1),
-                  ('IDENT', u'\xfe\xff', 1, 2),
-                  ('S', u' ', 1, 4)],
-        u'\xef\xbb\xbf ': [('BOM', u'\xef\xbb\xbf', 1, 1),
-                  ('S', u' ', 1, 1)],
-        u' \xef\xbb\xbf ': [('S', u' ', 1, 1),
-                  ('IDENT', u'\xef\xbb\xbf', 1, 2),
-                  ('S', u' ', 1, 5)],        }
+        '\xfe\xff ': [('BOM', '\xfe\xff', 1, 1),
+                  ('S', ' ', 1, 1)],
+        ' \xfe\xff ': [('S', ' ', 1, 1),
+                  ('IDENT', '\xfe\xff', 1, 2),
+                  ('S', ' ', 1, 4)],
+        '\xef\xbb\xbf ': [('BOM', '\xef\xbb\xbf', 1, 1),
+                  ('S', ' ', 1, 1)],
+        ' \xef\xbb\xbf ': [('S', ' ', 1, 1),
+                  ('IDENT', '\xef\xbb\xbf', 1, 2),
+                  ('S', ' ', 1, 5)],        }
 
     tests2 = {
         # escapes work not for a-f!
         # IMPORT_SYM
-        u' @import ': [('S', u' ', 1, 1),
-                 ('IMPORT_SYM', u'@import', 1, 2),
-                 ('S', u' ', 1, 9)],
-        u'@IMPORT': [('IMPORT_SYM', u'@IMPORT', 1, 1)],
-        u'@\\49\r\nMPORT': [('IMPORT_SYM', u'@\\49\r\nMPORT', 1, 1)],
-        ur'@\i\m\p\o\r\t': [('IMPORT_SYM', ur'@\i\m\p\o\r\t', 1, 1)],
-        ur'@\I\M\P\O\R\T': [('IMPORT_SYM', ur'@\I\M\P\O\R\T', 1, 1)],
-        ur'@\49 \04d\0050\0004f\000052\54': [('IMPORT_SYM',
-                                        ur'@\49 \04d\0050\0004f\000052\54',
+        ' @import ': [('S', ' ', 1, 1),
+                 ('IMPORT_SYM', '@import', 1, 2),
+                 ('S', ' ', 1, 9)],
+        '@IMPORT': [('IMPORT_SYM', '@IMPORT', 1, 1)],
+        '@\\49\r\nMPORT': [('IMPORT_SYM', '@\\49\r\nMPORT', 1, 1)],
+        r'@\i\m\p\o\r\t': [('IMPORT_SYM', r'@\i\m\p\o\r\t', 1, 1)],
+        r'@\I\M\P\O\R\T': [('IMPORT_SYM', r'@\I\M\P\O\R\T', 1, 1)],
+        r'@\49 \04d\0050\0004f\000052\54': [('IMPORT_SYM',
+                                        r'@\49 \04d\0050\0004f\000052\54',
                                         1, 1)],
-        ur'@\69 \06d\0070\0006f\000072\74': [('IMPORT_SYM',
-                                        ur'@\69 \06d\0070\0006f\000072\74',
+        r'@\69 \06d\0070\0006f\000072\74': [('IMPORT_SYM',
+                                        r'@\69 \06d\0070\0006f\000072\74',
                                         1, 1)],
 
         # PAGE_SYM
-        u' @page ': [('S', u' ', 1, 1),
-                 ('PAGE_SYM', u'@page', 1, 2),
-                 ('S', u' ', 1, 7)],
-        u'@PAGE': [('PAGE_SYM', u'@PAGE', 1, 1)],
-        ur'@\pa\ge': [('PAGE_SYM', ur'@\pa\ge', 1, 1)],
-        ur'@\PA\GE': [('PAGE_SYM', ur'@\PA\GE', 1, 1)],
-        ur'@\50\41\47\45': [('PAGE_SYM', ur'@\50\41\47\45', 1, 1)],
-        ur'@\70\61\67\65': [('PAGE_SYM', ur'@\70\61\67\65', 1, 1)],
+        ' @page ': [('S', ' ', 1, 1),
+                 ('PAGE_SYM', '@page', 1, 2),
+                 ('S', ' ', 1, 7)],
+        '@PAGE': [('PAGE_SYM', '@PAGE', 1, 1)],
+        r'@\pa\ge': [('PAGE_SYM', r'@\pa\ge', 1, 1)],
+        r'@\PA\GE': [('PAGE_SYM', r'@\PA\GE', 1, 1)],
+        r'@\50\41\47\45': [('PAGE_SYM', r'@\50\41\47\45', 1, 1)],
+        r'@\70\61\67\65': [('PAGE_SYM', r'@\70\61\67\65', 1, 1)],
 
         # MEDIA_SYM
-        u' @media ': [('S', u' ', 1, 1),
-                 ('MEDIA_SYM', u'@media', 1, 2),
-                 ('S', u' ', 1, 8)],
-        u'@MEDIA': [('MEDIA_SYM', u'@MEDIA', 1, 1)],
-        ur'@\med\ia': [('MEDIA_SYM', ur'@\med\ia', 1, 1)],
-        ur'@\MED\IA': [('MEDIA_SYM', ur'@\MED\IA', 1, 1)],
-        u'@\\4d\n\\45\r\\44\t\\49\r\nA': [('MEDIA_SYM', u'@\\4d\n\\45\r\\44\t\\49\r\nA', 1, 1)],
-        u'@\\4d\n\\45\r\\44\t\\49\r\\41\f': [('MEDIA_SYM',
-                                        u'@\\4d\n\\45\r\\44\t\\49\r\\41\f',
+        ' @media ': [('S', ' ', 1, 1),
+                 ('MEDIA_SYM', '@media', 1, 2),
+                 ('S', ' ', 1, 8)],
+        '@MEDIA': [('MEDIA_SYM', '@MEDIA', 1, 1)],
+        r'@\med\ia': [('MEDIA_SYM', r'@\med\ia', 1, 1)],
+        r'@\MED\IA': [('MEDIA_SYM', r'@\MED\IA', 1, 1)],
+        '@\\4d\n\\45\r\\44\t\\49\r\nA': [('MEDIA_SYM', '@\\4d\n\\45\r\\44\t\\49\r\nA', 1, 1)],
+        '@\\4d\n\\45\r\\44\t\\49\r\\41\f': [('MEDIA_SYM',
+                                        '@\\4d\n\\45\r\\44\t\\49\r\\41\f',
                                         1, 1)],
-        u'@\\6d\n\\65\r\\64\t\\69\r\\61\f': [('MEDIA_SYM',
-                                        u'@\\6d\n\\65\r\\64\t\\69\r\\61\f',
+        '@\\6d\n\\65\r\\64\t\\69\r\\61\f': [('MEDIA_SYM',
+                                        '@\\6d\n\\65\r\\64\t\\69\r\\61\f',
                                         1, 1)],
 
         # FONT_FACE_SYM
-        u' @font-face ': [('S', u' ', 1, 1),
-                 ('FONT_FACE_SYM', u'@font-face', 1, 2),
-                 ('S', u' ', 1, 12)],
-        u'@FONT-FACE': [('FONT_FACE_SYM', u'@FONT-FACE', 1, 1)],
-        ur'@f\o\n\t\-face': [('FONT_FACE_SYM', ur'@f\o\n\t\-face', 1, 1)],
-        ur'@F\O\N\T\-FACE': [('FONT_FACE_SYM', ur'@F\O\N\T\-FACE', 1, 1)],
+        ' @font-face ': [('S', ' ', 1, 1),
+                 ('FONT_FACE_SYM', '@font-face', 1, 2),
+                 ('S', ' ', 1, 12)],
+        '@FONT-FACE': [('FONT_FACE_SYM', '@FONT-FACE', 1, 1)],
+        r'@f\o\n\t\-face': [('FONT_FACE_SYM', r'@f\o\n\t\-face', 1, 1)],
+        r'@F\O\N\T\-FACE': [('FONT_FACE_SYM', r'@F\O\N\T\-FACE', 1, 1)],
         # TODO: "-" as hex!
-        ur'@\46\4f\4e\54\-\46\41\43\45': [('FONT_FACE_SYM',
-            ur'@\46\4f\4e\54\-\46\41\43\45', 1, 1)],
-        ur'@\66\6f\6e\74\-\66\61\63\65': [('FONT_FACE_SYM',
-            ur'@\66\6f\6e\74\-\66\61\63\65', 1, 1)],
+        r'@\46\4f\4e\54\-\46\41\43\45': [('FONT_FACE_SYM',
+            r'@\46\4f\4e\54\-\46\41\43\45', 1, 1)],
+        r'@\66\6f\6e\74\-\66\61\63\65': [('FONT_FACE_SYM',
+            r'@\66\6f\6e\74\-\66\61\63\65', 1, 1)],
 
         # CHARSET_SYM only if "@charset "!
-        u'@charset  ': [('CHARSET_SYM', u'@charset ', 1, 1),
-                        ('S', u' ', 1, 10)],
-        u' @charset  ': [('S', u' ', 1, 1),
-                 ('CHARSET_SYM', u'@charset ', 1, 2), # not at start
-                 ('S', u' ', 1, 11)],
-        u'@charset': [('ATKEYWORD', u'@charset', 1, 1)], # no ending S
-        u'@CHARSET ': [('ATKEYWORD', u'@CHARSET', 1, 1),# uppercase
-                       ('S', u' ', 1, 9)],
-        u'@cha\\rset ': [('ATKEYWORD', u'@cha\\rset', 1, 1), # not literal
-                         ('S', u' ', 1, 10)],
+        '@charset  ': [('CHARSET_SYM', '@charset ', 1, 1),
+                        ('S', ' ', 1, 10)],
+        ' @charset  ': [('S', ' ', 1, 1),
+                 ('CHARSET_SYM', '@charset ', 1, 2), # not at start
+                 ('S', ' ', 1, 11)],
+        '@charset': [('ATKEYWORD', '@charset', 1, 1)], # no ending S
+        '@CHARSET ': [('ATKEYWORD', '@CHARSET', 1, 1),# uppercase
+                       ('S', ' ', 1, 9)],
+        '@cha\\rset ': [('ATKEYWORD', '@cha\\rset', 1, 1), # not literal
+                         ('S', ' ', 1, 10)],
 
         # NAMESPACE_SYM
-        u' @namespace ': [('S', u' ', 1, 1),
-                 ('NAMESPACE_SYM', u'@namespace', 1, 2),
-                 ('S', u' ', 1, 12)],
-        ur'@NAMESPACE': [('NAMESPACE_SYM', ur'@NAMESPACE', 1, 1)],
-        ur'@\na\me\s\pace': [('NAMESPACE_SYM', ur'@\na\me\s\pace', 1, 1)],
-        ur'@\NA\ME\S\PACE': [('NAMESPACE_SYM', ur'@\NA\ME\S\PACE', 1, 1)],
-        ur'@\4e\41\4d\45\53\50\41\43\45': [('NAMESPACE_SYM',
-            ur'@\4e\41\4d\45\53\50\41\43\45', 1, 1)],
-        ur'@\6e\61\6d\65\73\70\61\63\65': [('NAMESPACE_SYM',
-            ur'@\6e\61\6d\65\73\70\61\63\65', 1, 1)],
+        ' @namespace ': [('S', ' ', 1, 1),
+                 ('NAMESPACE_SYM', '@namespace', 1, 2),
+                 ('S', ' ', 1, 12)],
+        r'@NAMESPACE': [('NAMESPACE_SYM', r'@NAMESPACE', 1, 1)],
+        r'@\na\me\s\pace': [('NAMESPACE_SYM', r'@\na\me\s\pace', 1, 1)],
+        r'@\NA\ME\S\PACE': [('NAMESPACE_SYM', r'@\NA\ME\S\PACE', 1, 1)],
+        r'@\4e\41\4d\45\53\50\41\43\45': [('NAMESPACE_SYM',
+            r'@\4e\41\4d\45\53\50\41\43\45', 1, 1)],
+        r'@\6e\61\6d\65\73\70\61\63\65': [('NAMESPACE_SYM',
+            r'@\6e\61\6d\65\73\70\61\63\65', 1, 1)],
 
         # ATKEYWORD
-        u' @unknown ': [('S', u' ', 1, 1),
-                 ('ATKEYWORD', u'@unknown', 1, 2),
-                 ('S', u' ', 1, 10)],
+        ' @unknown ': [('S', ' ', 1, 1),
+                 ('ATKEYWORD', '@unknown', 1, 2),
+                 ('S', ' ', 1, 10)],
 
         # STRING
         # strings with linebreak in it
-        u' "\\na"\na': [('S', u' ', 1, 1),
-                   ('STRING', u'"\\na"', 1, 2),
-                   ('S', u'\n', 1, 7),
-                   ('IDENT', u'a', 2, 1)],
-        u" '\\na'\na": [('S', u' ', 1, 1),
-                   ('STRING', u"'\\na'", 1, 2),
-                   ('S', u'\n', 1, 7),
-                   ('IDENT', u'a', 2, 1)],
-        u' "\\r\\n\\t\\n\\ra"a': [('S', u' ', 1, 1),
-                   ('STRING', u'"\\r\\n\\t\\n\\ra"', 1, 2),
-                   ('IDENT', u'a', 1, 15)],
+        ' "\\na"\na': [('S', ' ', 1, 1),
+                   ('STRING', '"\\na"', 1, 2),
+                   ('S', '\n', 1, 7),
+                   ('IDENT', 'a', 2, 1)],
+        " '\\na'\na": [('S', ' ', 1, 1),
+                   ('STRING', "'\\na'", 1, 2),
+                   ('S', '\n', 1, 7),
+                   ('IDENT', 'a', 2, 1)],
+        ' "\\r\\n\\t\\n\\ra"a': [('S', ' ', 1, 1),
+                   ('STRING', '"\\r\\n\\t\\n\\ra"', 1, 2),
+                   ('IDENT', 'a', 1, 15)],
 
         # IMPORTANT_SYM is not IDENT!!!
-        u' !important ': [('S', u' ', 1, 1),
-                ('CHAR', u'!', 1, 2),
-                 ('IDENT', u'important', 1, 3),
-                 ('S', u' ', 1, 12)],
-        u'! /*1*/ important ': [
-                ('CHAR', u'!', 1, 1),
-                ('S', u' ', 1, 2),
-                ('COMMENT', u'/*1*/', 1, 3),
-                ('S', u' ', 1, 8),
-                 ('IDENT', u'important', 1, 9),
-                 ('S', u' ', 1, 18)],
-        u'! important': [('CHAR', u'!', 1, 1),
-                         ('S', u' ', 1, 2),
-                         ('IDENT', u'important', 1, 3)],
-        u'!\n\timportant': [('CHAR', u'!', 1, 1),
-                            ('S', u'\n\t', 1, 2),
-                            ('IDENT', u'important', 2, 2)],
-        u'!IMPORTANT': [('CHAR', u'!', 1, 1),
-                        ('IDENT', u'IMPORTANT', 1, 2)],
-        ur'!\i\m\p\o\r\ta\n\t': [('CHAR', u'!', 1, 1),
+        ' !important ': [('S', ' ', 1, 1),
+                ('CHAR', '!', 1, 2),
+                 ('IDENT', 'important', 1, 3),
+                 ('S', ' ', 1, 12)],
+        '! /*1*/ important ': [
+                ('CHAR', '!', 1, 1),
+                ('S', ' ', 1, 2),
+                ('COMMENT', '/*1*/', 1, 3),
+                ('S', ' ', 1, 8),
+                 ('IDENT', 'important', 1, 9),
+                 ('S', ' ', 1, 18)],
+        '! important': [('CHAR', '!', 1, 1),
+                         ('S', ' ', 1, 2),
+                         ('IDENT', 'important', 1, 3)],
+        '!\n\timportant': [('CHAR', '!', 1, 1),
+                            ('S', '\n\t', 1, 2),
+                            ('IDENT', 'important', 2, 2)],
+        '!IMPORTANT': [('CHAR', '!', 1, 1),
+                        ('IDENT', 'IMPORTANT', 1, 2)],
+        r'!\i\m\p\o\r\ta\n\t': [('CHAR', '!', 1, 1),
                                  ('IDENT',
-                                  ur'\i\m\p\o\r\ta\n\t', 1, 2)],
-        ur'!\I\M\P\O\R\Ta\N\T': [('CHAR', u'!', 1, 1),
+                                  r'\i\m\p\o\r\ta\n\t', 1, 2)],
+        r'!\I\M\P\O\R\Ta\N\T': [('CHAR', '!', 1, 1),
                                  ('IDENT',
-                                  ur'\I\M\P\O\R\Ta\N\T', 1, 2)],
-        ur'!\49\4d\50\4f\52\54\41\4e\54': [('CHAR', u'!', 1, 1),
+                                  r'\I\M\P\O\R\Ta\N\T', 1, 2)],
+        r'!\49\4d\50\4f\52\54\41\4e\54': [('CHAR', '!', 1, 1),
                                            ('IDENT',
-                                            ur'IMPORTANT',
+                                            r'IMPORTANT',
                                             1, 2)],
-        ur'!\69\6d\70\6f\72\74\61\6e\74': [('CHAR', u'!', 1, 1),
+        r'!\69\6d\70\6f\72\74\61\6e\74': [('CHAR', '!', 1, 1),
                                            ('IDENT',
-                                            ur'important',
+                                            r'important',
                                             1, 2)],
         }
 
     # overwriting tests in testsall
     tests2only = {
         # LBRACE
-        u' { ': [('S', u' ', 1, 1),
-                 ('LBRACE', u'{', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' { ': [('S', ' ', 1, 1),
+                 ('LBRACE', '{', 1, 2),
+                 ('S', ' ', 1, 3)],
         # PLUS
-        u' + ': [('S', u' ', 1, 1),
-                 ('PLUS', u'+', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' + ': [('S', ' ', 1, 1),
+                 ('PLUS', '+', 1, 2),
+                 ('S', ' ', 1, 3)],
         # GREATER
-        u' > ': [('S', u' ', 1, 1),
-                 ('GREATER', u'>', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' > ': [('S', ' ', 1, 1),
+                 ('GREATER', '>', 1, 2),
+                 ('S', ' ', 1, 3)],
         # COMMA
-        u' , ': [('S', u' ', 1, 1),
-                 ('COMMA', u',', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' , ': [('S', ' ', 1, 1),
+                 ('COMMA', ',', 1, 2),
+                 ('S', ' ', 1, 3)],
         # class
-        u' . ': [('S', u' ', 1, 1),
-                 ('CLASS', u'.', 1, 2),
-                 ('S', u' ', 1, 3)],
+        ' . ': [('S', ' ', 1, 1),
+                 ('CLASS', '.', 1, 2),
+                 ('S', ' ', 1, 3)],
         }
 
     testsfullsheet = {
         # escape ends with explicit space but \r\n as single space
-        u'\\65\r\nb': [('IDENT', u'eb', 1, 1)],
+        '\\65\r\nb': [('IDENT', 'eb', 1, 1)],
 
         # STRING
-        ur'"\""': [('STRING', ur'"\""', 1, 1)],
-        ur'"\" "': [('STRING', ur'"\" "', 1, 1)],
-        u"""'\\''""": [('STRING', u"""'\\''""", 1, 1)],
-        u'''"\\""''': [('STRING', u'''"\\""''', 1, 1)],
-        u' "\na': [('S', u' ', 1, 1),
-                   ('INVALID', u'"', 1, 2),
-                   ('S', u'\n', 1, 3),
-                   ('IDENT', u'a', 2, 1)],
+        r'"\""': [('STRING', r'"\""', 1, 1)],
+        r'"\" "': [('STRING', r'"\" "', 1, 1)],
+        """'\\''""": [('STRING', """'\\''""", 1, 1)],
+        '''"\\""''': [('STRING', '''"\\""''', 1, 1)],
+        ' "\na': [('S', ' ', 1, 1),
+                   ('INVALID', '"', 1, 2),
+                   ('S', '\n', 1, 3),
+                   ('IDENT', 'a', 2, 1)],
 
         # strings with linebreak in it
-        u' "\\na\na': [('S', u' ', 1, 1),
-                   ('INVALID', u'"\\na', 1, 2),
-                   ('S', u'\n', 1, 6),
-                   ('IDENT', u'a', 2, 1)],
-        u' "\\r\\n\\t\\n\\ra\na': [('S', u' ', 1, 1),
-                   ('INVALID', u'"\\r\\n\\t\\n\\ra', 1, 2),
-                   ('S', u'\n', 1, 14),
-                   ('IDENT', u'a', 2, 1)],
+        ' "\\na\na': [('S', ' ', 1, 1),
+                   ('INVALID', '"\\na', 1, 2),
+                   ('S', '\n', 1, 6),
+                   ('IDENT', 'a', 2, 1)],
+        ' "\\r\\n\\t\\n\\ra\na': [('S', ' ', 1, 1),
+                   ('INVALID', '"\\r\\n\\t\\n\\ra', 1, 2),
+                   ('S', '\n', 1, 14),
+                   ('IDENT', 'a', 2, 1)],
         # URI
-        u'ur\\l(a)': [('URI', u'ur\\l(a)', 1, 1)],
-        u'url(a)': [('URI', u'url(a)', 1, 1)],
-        u'\\55r\\4c(a)': [('URI', u'UrL(a)', 1, 1)],
-        u'\\75r\\6c(a)': [('URI', u'url(a)', 1, 1)],
-        u' url())': [('S', u' ', 1, 1),
-                 ('URI', u'url()', 1, 2),
-                 ('CHAR', u')', 1, 7)],
-        u'url("x"))': [('URI', u'url("x")', 1, 1),
-                       ('CHAR', u')', 1, 9)],
-        u"url('x'))": [('URI', u"url('x')", 1, 1),
-                       ('CHAR', u')', 1, 9)],
+        'ur\\l(a)': [('URI', 'ur\\l(a)', 1, 1)],
+        'url(a)': [('URI', 'url(a)', 1, 1)],
+        '\\55r\\4c(a)': [('URI', 'UrL(a)', 1, 1)],
+        '\\75r\\6c(a)': [('URI', 'url(a)', 1, 1)],
+        ' url())': [('S', ' ', 1, 1),
+                 ('URI', 'url()', 1, 2),
+                 ('CHAR', ')', 1, 7)],
+        'url("x"))': [('URI', 'url("x")', 1, 1),
+                       ('CHAR', ')', 1, 9)],
+        "url('x'))": [('URI', "url('x')", 1, 1),
+                       ('CHAR', ')', 1, 9)],
         }
 
     # tests if fullsheet=False is set on tokenizer
     testsfullsheetfalse = {
         # COMMENT incomplete
-        u'/*': [('CHAR', u'/', 1, 1),
-                ('CHAR', u'*', 1, 2)],
+        '/*': [('CHAR', '/', 1, 1),
+                ('CHAR', '*', 1, 2)],
 
         # INVALID incomplete
-        u' " ': [('S', u' ', 1, 1),
-                 ('INVALID', u'" ', 1, 2)],
-        u" 'abc\"with quote\" in it": [('S', u' ', 1, 1),
-                 ('INVALID', u"'abc\"with quote\" in it", 1, 2)],
+        ' " ': [('S', ' ', 1, 1),
+                 ('INVALID', '" ', 1, 2)],
+        " 'abc\"with quote\" in it": [('S', ' ', 1, 1),
+                 ('INVALID', "'abc\"with quote\" in it", 1, 2)],
 
         # URI incomplete
-        u'url(a': [('FUNCTION', u'url(', 1, 1),
-                   ('IDENT', u'a', 1, 5)],
-        u'url("a': [('FUNCTION', u'url(', 1, 1),
-                   ('INVALID', u'"a', 1, 5)],
-        u"url('a": [('FUNCTION', u'url(', 1, 1),
-                   ('INVALID', u"'a", 1, 5)],
-        u"UR\\l('a": [('FUNCTION', u'UR\\l(', 1, 1),
-                   ('INVALID', u"'a", 1, 6)],
+        'url(a': [('FUNCTION', 'url(', 1, 1),
+                   ('IDENT', 'a', 1, 5)],
+        'url("a': [('FUNCTION', 'url(', 1, 1),
+                   ('INVALID', '"a', 1, 5)],
+        "url('a": [('FUNCTION', 'url(', 1, 1),
+                   ('INVALID', "'a", 1, 5)],
+        "UR\\l('a": [('FUNCTION', 'UR\\l(', 1, 1),
+                   ('INVALID', "'a", 1, 6)],
         }
 
     # tests if fullsheet=True is set on tokenizer
     testsfullsheettrue = {
         # COMMENT incomplete
-        u'/*': [('COMMENT', u'/**/', 1, 1)],
+        '/*': [('COMMENT', '/**/', 1, 1)],
 
 #        # INVALID incomplete => STRING
-        u' " ': [('S', u' ', 1, 1),
-                 ('STRING', u'" "', 1, 2)],
-        u" 'abc\"with quote\" in it": [('S', u' ', 1, 1),
-                 ('STRING', u"'abc\"with quote\" in it'", 1, 2)],
+        ' " ': [('S', ' ', 1, 1),
+                 ('STRING', '" "', 1, 2)],
+        " 'abc\"with quote\" in it": [('S', ' ', 1, 1),
+                 ('STRING', "'abc\"with quote\" in it'", 1, 2)],
 
         # URI incomplete FUNC => URI
-        u'url(a': [('URI', u'url(a)', 1, 1)],
-        u'url( a': [('URI', u'url( a)', 1, 1)],
-        u'url("a': [('URI', u'url("a")', 1, 1)],
-        u'url( "a ': [('URI', u'url( "a ")', 1, 1)],
-        u"url('a": [('URI', u"url('a')", 1, 1)],
-        u'url("a"': [('URI', u'url("a")', 1, 1)],
-        u"url('a'": [('URI', u"url('a')", 1, 1)],
+        'url(a': [('URI', 'url(a)', 1, 1)],
+        'url( a': [('URI', 'url( a)', 1, 1)],
+        'url("a': [('URI', 'url("a")', 1, 1)],
+        'url( "a ': [('URI', 'url( "a ")', 1, 1)],
+        "url('a": [('URI', "url('a')", 1, 1)],
+        'url("a"': [('URI', 'url("a")', 1, 1)],
+        "url('a'": [('URI', "url('a')", 1, 1)],
         }
 
     def setUp(self):
@@ -668,200 +668,199 @@ class TokenizerTestCase(basetest.BaseTestCase):
     def __old(self):
 
         testsOLD = {
-            u'x x1 -x .-x #_x -': [(1, 1, tt.IDENT, u'x'),
-               (1, 2, 'S', u' '),
-               (1, 3, tt.IDENT, u'x1'),
-               (1, 5, 'S', u' '),
-               (1, 6, tt.IDENT, u'-x'),
-               (1, 8, 'S', u' '),
-               (1, 9, tt.CLASS, u'.'),
-               (1, 10, tt.IDENT, u'-x'),
-               (1, 12, 'S', u' '),
-               (1, 13, tt.HASH, u'#_x'),
-               (1, 16, 'S', u' '),
-               (1, 17, 'DELIM', u'-')],
+            'x x1 -x .-x #_x -': [(1, 1, tt.IDENT, 'x'),
+               (1, 2, 'S', ' '),
+               (1, 3, tt.IDENT, 'x1'),
+               (1, 5, 'S', ' '),
+               (1, 6, tt.IDENT, '-x'),
+               (1, 8, 'S', ' '),
+               (1, 9, tt.CLASS, '.'),
+               (1, 10, tt.IDENT, '-x'),
+               (1, 12, 'S', ' '),
+               (1, 13, tt.HASH, '#_x'),
+               (1, 16, 'S', ' '),
+               (1, 17, 'DELIM', '-')],
 
             # num
-            u'1 1.1 -1 -1.1 .1 -.1 1.': [(1, 1, tt.NUMBER, u'1'),
-               (1, 2, 'S', u' '), (1, 3, tt.NUMBER, u'1.1'),
-               (1, 6, 'S', u' '), (1, 7, tt.NUMBER, u'-1'),
-               (1, 9, 'S', u' '), (1, 10, tt.NUMBER, u'-1.1'),
-               (1, 14, 'S', u' '), (1, 15, tt.NUMBER, u'0.1'),
-               (1, 17, 'S', u' '), (1, 18, tt.NUMBER, u'-0.1'),
-               (1, 21, 'S', u' '),
-               (1, 22, tt.NUMBER, u'1'), (1, 23, tt.CLASS, u'.')
+            '1 1.1 -1 -1.1 .1 -.1 1.': [(1, 1, tt.NUMBER, '1'),
+               (1, 2, 'S', ' '), (1, 3, tt.NUMBER, '1.1'),
+               (1, 6, 'S', ' '), (1, 7, tt.NUMBER, '-1'),
+               (1, 9, 'S', ' '), (1, 10, tt.NUMBER, '-1.1'),
+               (1, 14, 'S', ' '), (1, 15, tt.NUMBER, '0.1'),
+               (1, 17, 'S', ' '), (1, 18, tt.NUMBER, '-0.1'),
+               (1, 21, 'S', ' '),
+               (1, 22, tt.NUMBER, '1'), (1, 23, tt.CLASS, '.')
                                          ],
             # CSS3 pseudo
-            u'::': [(1, 1, tt.PSEUDO_ELEMENT, u'::')],
+            '::': [(1, 1, tt.PSEUDO_ELEMENT, '::')],
 
             # SPECIALS
-            u'*+>~{},': [(1, 1, tt.UNIVERSAL, u'*'),
-               (1, 2, tt.PLUS, u'+'),
-               (1, 3, tt.GREATER, u'>'),
-               (1, 4, tt.TILDE, u'~'),
-               (1, 5, tt.LBRACE, u'{'),
-               (1, 6, tt.RBRACE, u'}'),
-               (1, 7, tt.COMMA, u',')],
+            '*+>~{},': [(1, 1, tt.UNIVERSAL, '*'),
+               (1, 2, tt.PLUS, '+'),
+               (1, 3, tt.GREATER, '>'),
+               (1, 4, tt.TILDE, '~'),
+               (1, 5, tt.LBRACE, '{'),
+               (1, 6, tt.RBRACE, '}'),
+               (1, 7, tt.COMMA, ',')],
 
             # DELIM
-            u'!%:&$|': [(1, 1, 'DELIM', u'!'),
-               (1, 2, 'DELIM', u'%'),
-               (1, 3, 'DELIM', u':'),
-               (1, 4, 'DELIM', u'&'),
-               (1, 5, 'DELIM', u'$'),
-               (1, 6, 'DELIM', u'|')],
+            '!%:&$|': [(1, 1, 'DELIM', '!'),
+               (1, 2, 'DELIM', '%'),
+               (1, 3, 'DELIM', ':'),
+               (1, 4, 'DELIM', '&'),
+               (1, 5, 'DELIM', '$'),
+               (1, 6, 'DELIM', '|')],
 
 
             # DIMENSION
-            u'5em': [(1, 1, tt.DIMENSION, u'5em')],
-            u' 5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'5em')],
-            u'5em ': [(1, 1, tt.DIMENSION, u'5em'), (1, 4, 'S', u' ')],
-
-            u'-5em': [(1, 1, tt.DIMENSION, u'-5em')],
-            u' -5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'-5em')],
-            u'-5em ': [(1, 1, tt.DIMENSION, u'-5em'), (1, 5, 'S', u' ')],
-
-            u'.5em': [(1, 1, tt.DIMENSION, u'0.5em')],
-            u' .5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'0.5em')],
-            u'.5em ': [(1, 1, tt.DIMENSION, u'0.5em'), (1, 5, 'S', u' ')],
-
-            u'-.5em': [(1, 1, tt.DIMENSION, u'-0.5em')],
-            u' -.5em': [(1, 1, 'S', u' '), (1, 2, tt.DIMENSION, u'-0.5em')],
-            u'-.5em ': [(1, 1, tt.DIMENSION, u'-0.5em'), (1, 6, 'S', u' ')],
-
-            u'5em5_-': [(1, 1, tt.DIMENSION, u'5em5_-')],
-
-            u'a a5 a5a 5 5a 5a5': [(1, 1, tt.IDENT, u'a'),
-               (1, 2, 'S', u' '),
-               (1, 3, tt.IDENT, u'a5'),
-               (1, 5, 'S', u' '),
-               (1, 6, tt.IDENT, u'a5a'),
-               (1, 9, 'S', u' '),
-               (1, 10, tt.NUMBER, u'5'),
-               (1, 11, 'S', u' '),
-               (1, 12, tt.DIMENSION, u'5a'),
-               (1, 14, 'S', u' '),
-               (1, 15, tt.DIMENSION, u'5a5')],
+            '5em': [(1, 1, tt.DIMENSION, '5em')],
+            ' 5em': [(1, 1, 'S', ' '), (1, 2, tt.DIMENSION, '5em')],
+            '5em ': [(1, 1, tt.DIMENSION, '5em'), (1, 4, 'S', ' ')],
+
+            '-5em': [(1, 1, tt.DIMENSION, '-5em')],
+            ' -5em': [(1, 1, 'S', ' '), (1, 2, tt.DIMENSION, '-5em')],
+            '-5em ': [(1, 1, tt.DIMENSION, '-5em'), (1, 5, 'S', ' ')],
+
+            '.5em': [(1, 1, tt.DIMENSION, '0.5em')],
+            ' .5em': [(1, 1, 'S', ' '), (1, 2, tt.DIMENSION, '0.5em')],
+            '.5em ': [(1, 1, tt.DIMENSION, '0.5em'), (1, 5, 'S', ' ')],
+
+            '-.5em': [(1, 1, tt.DIMENSION, '-0.5em')],
+            ' -.5em': [(1, 1, 'S', ' '), (1, 2, tt.DIMENSION, '-0.5em')],
+            '-.5em ': [(1, 1, tt.DIMENSION, '-0.5em'), (1, 6, 'S', ' ')],
+
+            '5em5_-': [(1, 1, tt.DIMENSION, '5em5_-')],
+
+            'a a5 a5a 5 5a 5a5': [(1, 1, tt.IDENT, 'a'),
+               (1, 2, 'S', ' '),
+               (1, 3, tt.IDENT, 'a5'),
+               (1, 5, 'S', ' '),
+               (1, 6, tt.IDENT, 'a5a'),
+               (1, 9, 'S', ' '),
+               (1, 10, tt.NUMBER, '5'),
+               (1, 11, 'S', ' '),
+               (1, 12, tt.DIMENSION, '5a'),
+               (1, 14, 'S', ' '),
+               (1, 15, tt.DIMENSION, '5a5')],
 
             # URI
-            u'url()': [(1, 1, tt.URI, u'url()')],
-            u'url();': [(1, 1, tt.URI, u'url()'), (1, 6, tt.SEMICOLON, ';')],
-            u'url("x")': [(1, 1, tt.URI, u'url("x")')],
-            u'url( "x")': [(1, 1, tt.URI, u'url("x")')],
-            u'url("x" )': [(1, 1, tt.URI, u'url("x")')],
-            u'url( "x" )': [(1, 1, tt.URI, u'url("x")')],
-            u' url("x")': [
-                (1, 1, 'S', u' '),
-                (1, 2, tt.URI, u'url("x")')],
-            u'url("x") ': [
-                (1, 1, tt.URI, u'url("x")'),
-                (1, 9, 'S', u' '),
+            'url()': [(1, 1, tt.URI, 'url()')],
+            'url();': [(1, 1, tt.URI, 'url()'), (1, 6, tt.SEMICOLON, ';')],
+            'url("x")': [(1, 1, tt.URI, 'url("x")')],
+            'url( "x")': [(1, 1, tt.URI, 'url("x")')],
+            'url("x" )': [(1, 1, tt.URI, 'url("x")')],
+            'url( "x" )': [(1, 1, tt.URI, 'url("x")')],
+            ' url("x")': [
+                (1, 1, 'S', ' '),
+                (1, 2, tt.URI, 'url("x")')],
+            'url("x") ': [
+                (1, 1, tt.URI, 'url("x")'),
+                (1, 9, 'S', ' '),
                 ],
-            u'url(ab)': [(1, 1, tt.URI, u'url(ab)')],
-            u'url($#/ab)': [(1, 1, tt.URI, u'url($#/ab)')],
-            u'url(\1233/a/b)': [(1, 1, tt.URI, u'url(\1233/a/b)')],
+            'url(ab)': [(1, 1, tt.URI, 'url(ab)')],
+            'url($#/ab)': [(1, 1, tt.URI, 'url($#/ab)')],
+            'url(\1233/a/b)': [(1, 1, tt.URI, 'url(\1233/a/b)')],
             # not URI
-            u'url("1""2")': [
-                (1, 1, tt.FUNCTION, u'url('),
-                (1, 5, tt.STRING, u'"1"'),
-                (1, 8, tt.STRING, u'"2"'),
-                (1, 11, tt.RPARANTHESIS, u')'),
+            'url("1""2")': [
+                (1, 1, tt.FUNCTION, 'url('),
+                (1, 5, tt.STRING, '"1"'),
+                (1, 8, tt.STRING, '"2"'),
+                (1, 11, tt.RPARANTHESIS, ')'),
                 ],
-            u'url(a"2")': [
-                (1, 1, tt.FUNCTION, u'url('),
-                (1, 5, tt.IDENT, u'a'),
-                (1, 6, tt.STRING, u'"2"'),
-                (1, 9, tt.RPARANTHESIS, u')'),
+            'url(a"2")': [
+                (1, 1, tt.FUNCTION, 'url('),
+                (1, 5, tt.IDENT, 'a'),
+                (1, 6, tt.STRING, '"2"'),
+                (1, 9, tt.RPARANTHESIS, ')'),
                 ],
-            u'url(a b)': [
-                (1, 1, tt.FUNCTION, u'url('),
-                (1, 5, tt.IDENT, u'a'),
-                (1, 6, 'S', u' '),
-                (1, 7, tt.IDENT, u'b'),
-                (1, 8, tt.RPARANTHESIS, u')'),
+            'url(a b)': [
+                (1, 1, tt.FUNCTION, 'url('),
+                (1, 5, tt.IDENT, 'a'),
+                (1, 6, 'S', ' '),
+                (1, 7, tt.IDENT, 'b'),
+                (1, 8, tt.RPARANTHESIS, ')'),
                 ],
 
             # FUNCTION
-            u' counter("x")': [
-               (1,1, 'S', u' '),
-               (1, 2, tt.FUNCTION, u'counter('),
-               (1, 10, tt.STRING, u'"x"'),
-               (1, 13, tt.RPARANTHESIS, u')')],
+            ' counter("x")': [
+               (1,1, 'S', ' '),
+               (1, 2, tt.FUNCTION, 'counter('),
+               (1, 10, tt.STRING, '"x"'),
+               (1, 13, tt.RPARANTHESIS, ')')],
             # HASH
-            u'# #a #_a #-a #1': [
-                (1, 1, 'DELIM', u'#'),
-                (1, 2, 'S', u' '),
-                (1, 3, tt.HASH, u'#a'),
-                (1, 5, 'S', u' '),
-                (1, 6, tt.HASH, u'#_a'),
-                (1, 9, 'S', u' '),
-                (1, 10, tt.HASH, u'#-a'),
-                (1, 13, 'S', u' '),
-                (1, 14, tt.HASH, u'#1')
+            '# #a #_a #-a #1': [
+                (1, 1, 'DELIM', '#'),
+                (1, 2, 'S', ' '),
+                (1, 3, tt.HASH, '#a'),
+                (1, 5, 'S', ' '),
+                (1, 6, tt.HASH, '#_a'),
+                (1, 9, 'S', ' '),
+                (1, 10, tt.HASH, '#-a'),
+                (1, 13, 'S', ' '),
+                (1, 14, tt.HASH, '#1')
                 ],
-            u'#1a1 ': [
-                (1, 1, tt.HASH, u'#1a1'),
-                (1, 5, 'S', u' '),
+            '#1a1 ': [
+                (1, 1, tt.HASH, '#1a1'),
+                (1, 5, 'S', ' '),
                 ],
-            u'#1a1\n': [
-                (1, 1, tt.HASH, u'#1a1'),
-                (1, 5, 'S', u'\n'),
+            '#1a1\n': [
+                (1, 1, tt.HASH, '#1a1'),
+                (1, 5, 'S', '\n'),
                 ],
-            u'#1a1{': [
-                (1, 1, tt.HASH, u'#1a1'),
-                (1, 5, tt.LBRACE, u'{'),
+            '#1a1{': [
+                (1, 1, tt.HASH, '#1a1'),
+                (1, 5, tt.LBRACE, '{'),
                 ],
-            u'#1a1 {': [
-                (1, 1, tt.HASH, u'#1a1'),
-                (1, 5, 'S', u' '),
-                (1, 6, tt.LBRACE, u'{'),
+            '#1a1 {': [
+                (1, 1, tt.HASH, '#1a1'),
+                (1, 5, 'S', ' '),
+                (1, 6, tt.LBRACE, '{'),
                 ],
-            u'#1a1\n{': [
-                (1, 1, tt.HASH, u'#1a1'),
-                (1, 5, 'S', u'\n'),
-                (2, 1, tt.LBRACE, u'{'),
+            '#1a1\n{': [
+                (1, 1, tt.HASH, '#1a1'),
+                (1, 5, 'S', '\n'),
+                (2, 1, tt.LBRACE, '{'),
                 ],
-            u'#1a1\n {': [
-                (1, 1, tt.HASH, u'#1a1'),
-                (1, 5, 'S', u'\n '),
-                (2, 2, tt.LBRACE, u'{'),
+            '#1a1\n {': [
+                (1, 1, tt.HASH, '#1a1'),
+                (1, 5, 'S', '\n '),
+                (2, 2, tt.LBRACE, '{'),
                 ],
-            u'#1a1 \n{': [
-                (1, 1, tt.HASH, u'#1a1'),
-                (1, 5, 'S', u' \n'),
-                (2, 1, tt.LBRACE, u'{'),
+            '#1a1 \n{': [
+                (1, 1, tt.HASH, '#1a1'),
+                (1, 5, 'S', ' \n'),
+                (2, 1, tt.LBRACE, '{'),
                 ],
             # STRINGS with NL
-            u'"x\n': [(1,1, tt.INVALID, u'"x\n')],
-            u'"x\r': [(1,1, tt.INVALID, u'"x\r')],
-            u'"x\f': [(1,1, tt.INVALID, u'"x\f')],
-            u'"x\n ': [
-               (1,1, tt.INVALID, u'"x\n'),
-               (2,1, 'S', u' ')
+            '"x\n': [(1,1, tt.INVALID, '"x\n')],
+            '"x\r': [(1,1, tt.INVALID, '"x\r')],
+            '"x\f': [(1,1, tt.INVALID, '"x\f')],
+            '"x\n ': [
+               (1,1, tt.INVALID, '"x\n'),
+               (2,1, 'S', ' ')
                ]
 
             }
 
         tests = {
-            u'/*a': xml.dom.SyntaxErr,
-            u'"a': xml.dom.SyntaxErr,
-            u"'a": xml.dom.SyntaxErr,
-            u"\\0 a": xml.dom.SyntaxErr,
-            u"\\00": xml.dom.SyntaxErr,
-            u"\\000": xml.dom.SyntaxErr,
-            u"\\0000": xml.dom.SyntaxErr,
-            u"\\00000": xml.dom.SyntaxErr,
-            u"\\000000": xml.dom.SyntaxErr,
-            u"\\0000001": xml.dom.SyntaxErr
+            '/*a': xml.dom.SyntaxErr,
+            '"a': xml.dom.SyntaxErr,
+            "'a": xml.dom.SyntaxErr,
+            "\\0 a": xml.dom.SyntaxErr,
+            "\\00": xml.dom.SyntaxErr,
+            "\\000": xml.dom.SyntaxErr,
+            "\\0000": xml.dom.SyntaxErr,
+            "\\00000": xml.dom.SyntaxErr,
+            "\\000000": xml.dom.SyntaxErr,
+            "\\0000001": xml.dom.SyntaxErr
             }
 #        self.tokenizer.log.raiseExceptions = True #!!
 #        for css, exception in tests.items():
 #            self.assertRaises(exception, self.tokenizer.tokenize, css)
 
 
-class TokenizerUtilsTestCase(basetest.BaseTestCase):
+class TokenizerUtilsTestCase(basetest.BaseTestCase, metaclass=basetest.GenerateTests):
     """Tests for the util functions of tokenize"""
-    __metaclass__ = basetest.GenerateTests
 
     def gen_test_has_at(self, string, pos, text, expected):
         self.assertEqual(tokenize2.has_at(string, pos, text), expected)
diff --git a/src/cssutils/tests/test_util.py b/src/cssutils/tests/test_util.py
index 6d30eff..cf9d2a6 100644
--- a/src/cssutils/tests/test_util.py
+++ b/src/cssutils/tests/test_util.py
@@ -1,22 +1,22 @@
 # -*- coding: utf-8 -*-
 """Testcases for cssutils.util"""
-from __future__ import with_statement
+
 
 import cgi
 from email import message_from_string, message_from_file
-import StringIO
+import io
 import re
 import sys
-import urllib2
+import urllib.request, urllib.error, urllib.parse
 import xml.dom
 
 try:
     import mock
 except ImportError:
     mock = None
-    print "install mock library to run all tests"
+    print("install mock library to run all tests")
 
-import basetest
+from . import basetest
 import encutils
 
 from cssutils.util import Base, ListSeq, _readUrl, _defaultFetcher, LazyRegex
@@ -57,13 +57,13 @@ class BaseTestCase(basetest.BaseTestCase):
     def test_normalize(self):
         "Base._normalize()"
         b = Base()
-        tests = {u'abcdefg ABCDEFG äöüß€ AÖÜ': u'abcdefg abcdefg äöüß€ aöü',
-                 ur'\ga\Ga\\\ ': ur'gaga\ ',
-                 ur'0123456789': u'0123456789',
+        tests = {'abcdefg ABCDEFG äöüß€ AÖÜ': 'abcdefg abcdefg äöüß€ aöü',
+                 r'\ga\Ga\\\ ': r'gaga\ ',
+                 r'0123456789': '0123456789',
                  # unicode escape seqs should have been done by
                  # the tokenizer...
                  }
-        for test, exp in tests.items():
+        for test, exp in list(tests.items()):
             self.assertEqual(b._normalize(test), exp)
             # static too
             self.assertEqual(Base._normalize(test), exp)
@@ -75,26 +75,26 @@ class BaseTestCase(basetest.BaseTestCase):
         b = Base()
 
         tests = [
-            ('default', u'a[{1}]({2}) { } NOT', u'a[{1}]({2}) { }', False),
-            ('default', u'a[{1}]({2}) { } NOT', u'a[{1}]func({2}) { }', True),
-            ('blockstartonly', u'a[{1}]({2}) { NOT', u'a[{1}]({2}) {', False),
-            ('blockstartonly', u'a[{1}]({2}) { NOT', u'a[{1}]func({2}) {', True),
-            ('propertynameendonly', u'a[(2)1] { }2 : a;', u'a[(2)1] { }2 :', False),
-            ('propertynameendonly', u'a[(2)1] { }2 : a;', u'a[func(2)1] { }2 :', True),
-            ('propertyvalueendonly', u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT',
-                u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1;', False),
-            ('propertyvalueendonly', u'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT',
-                u'a{;{;}[;]func(;)}[;{;}[;]func(;)]func(;{;}[;]func(;)) 1;', True),
-            ('funcendonly', u'a{[1]}([3])[{[1]}[2]([3])]) NOT',
-                u'a{[1]}([3])[{[1]}[2]([3])])', False),
-            ('funcendonly', u'a{[1]}([3])[{[1]}[2]([3])]) NOT',
-                u'a{[1]}func([3])[{[1]}[2]func([3])])', True),
-            ('selectorattendonly', u'[a[()]{()}([()]{()}())] NOT',
-                u'[a[()]{()}([()]{()}())]', False),
-            ('selectorattendonly', u'[a[()]{()}([()]{()}())] NOT',
-                u'[a[func()]{func()}func([func()]{func()}func())]', True),
+            ('default', 'a[{1}]({2}) { } NOT', 'a[{1}]({2}) { }', False),
+            ('default', 'a[{1}]({2}) { } NOT', 'a[{1}]func({2}) { }', True),
+            ('blockstartonly', 'a[{1}]({2}) { NOT', 'a[{1}]({2}) {', False),
+            ('blockstartonly', 'a[{1}]({2}) { NOT', 'a[{1}]func({2}) {', True),
+            ('propertynameendonly', 'a[(2)1] { }2 : a;', 'a[(2)1] { }2 :', False),
+            ('propertynameendonly', 'a[(2)1] { }2 : a;', 'a[func(2)1] { }2 :', True),
+            ('propertyvalueendonly', 'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT',
+                'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1;', False),
+            ('propertyvalueendonly', 'a{;{;}[;](;)}[;{;}[;](;)](;{;}[;](;)) 1; NOT',
+                'a{;{;}[;]func(;)}[;{;}[;]func(;)]func(;{;}[;]func(;)) 1;', True),
+            ('funcendonly', 'a{[1]}([3])[{[1]}[2]([3])]) NOT',
+                'a{[1]}([3])[{[1]}[2]([3])])', False),
+            ('funcendonly', 'a{[1]}([3])[{[1]}[2]([3])]) NOT',
+                'a{[1]}func([3])[{[1]}[2]func([3])])', True),
+            ('selectorattendonly', '[a[()]{()}([()]{()}())] NOT',
+                '[a[()]{()}([()]{()}())]', False),
+            ('selectorattendonly', '[a[()]{()}([()]{()}())] NOT',
+                '[a[func()]{func()}func([func()]{func()}func())]', True),
             # issue 50
-            ('withstarttoken [', u'a];x', u'[a];', False)
+            ('withstarttoken [', 'a];x', '[a];', False)
             ]
 
         for typ, values, exp, paransasfunc in tests:
@@ -106,8 +106,8 @@ class BaseTestCase(basetest.BaseTestCase):
             tokens = maketokens(list(values))
             if paransasfunc:
                 for i, t in enumerate(tokens):
-                    if u'(' == t[1]:
-                        tokens[i] = ('FUNCTION', u'func(', t[2], t[3])
+                    if '(' == t[1]:
+                        tokens[i] = ('FUNCTION', 'func(', t[2], t[3])
 
             if 'default' == typ:
                 restokens = b._tokensupto2(tokens)
@@ -129,7 +129,7 @@ class BaseTestCase(basetest.BaseTestCase):
             elif 'withstarttoken [' == typ:
                 restokens = b._tokensupto2(tokens, ('CHAR', '[', 0, 0))
 
-            res = u''.join([t[1] for t in restokens])
+            res = ''.join([t[1] for t in restokens])
             self.assertEqual(exp, res)
 
 
@@ -150,14 +150,14 @@ class _readUrl_TestCase(basetest.BaseTestCase):
         tests = {
             # defaultFetcher returns: readUrl returns
             None: (None, None, None),
-            (None, ''): ('utf-8', 5, u''),
-            (None, u'€'.encode('utf-8')): ('utf-8', 5, u'€'),
-            ('utf-8', u'€'.encode('utf-8')): ('utf-8', 1, u'€'),
-            ('ISO-8859-1', u'ä'.encode('iso-8859-1')): ('ISO-8859-1', 1, u'ä'),
-            ('ASCII', u'a'.encode('ascii')): ('ASCII', 1, u'a')
+            (None, ''): ('utf-8', 5, ''),
+            (None, '€'.encode('utf-8')): ('utf-8', 5, '€'),
+            ('utf-8', '€'.encode('utf-8')): ('utf-8', 1, '€'),
+            ('ISO-8859-1', 'ä'.encode('iso-8859-1')): ('ISO-8859-1', 1, 'ä'),
+            ('ASCII', 'a'.encode('ascii')): ('ASCII', 1, 'a')
         }
 
-        for r, exp in tests.items():
+        for r, exp in list(tests.items()):
             self.assertEqual(_readUrl(url, fetcher=make_fetcher(r)), exp)
 
         tests = {
@@ -166,132 +166,132 @@ class _readUrl_TestCase(basetest.BaseTestCase):
 
             # ===== 0. OVERRIDE WINS =====
             # override + parent + http
-            ('latin1', 'ascii', ('utf-16', u''.encode())): ('latin1', 0, u''),
-            ('latin1', 'ascii', ('utf-16', u'123'.encode())): ('latin1', 0, u'123'),
-            ('latin1', 'ascii', ('utf-16', u'ä'.encode('iso-8859-1'))):
-                ('latin1', 0, u'ä'),
-            ('latin1', 'ascii', ('utf-16', u'a'.encode('ascii'))):
-                ('latin1',0,  u'a'),
+            ('latin1', 'ascii', ('utf-16', ''.encode())): ('latin1', 0, ''),
+            ('latin1', 'ascii', ('utf-16', '123'.encode())): ('latin1', 0, '123'),
+            ('latin1', 'ascii', ('utf-16', 'ä'.encode('iso-8859-1'))):
+                ('latin1', 0, 'ä'),
+            ('latin1', 'ascii', ('utf-16', 'a'.encode('ascii'))):
+                ('latin1',0,  'a'),
             # + @charset
-            ('latin1', 'ascii', ('utf-16', u'@charset "ascii";'.encode())):
-                ('latin1', 0, u'@charset "latin1";'),
-            ('latin1', 'ascii', ('utf-16', u'@charset "utf-8";ä'.encode('latin1'))):
-                ('latin1', 0, u'@charset "latin1";ä'),
-            ('latin1', 'ascii', ('utf-16', u'@charset "utf-8";ä'.encode('utf-8'))):
-                ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1!
+            ('latin1', 'ascii', ('utf-16', '@charset "ascii";'.encode())):
+                ('latin1', 0, '@charset "latin1";'),
+            ('latin1', 'ascii', ('utf-16', '@charset "utf-8";ä'.encode('latin1'))):
+                ('latin1', 0, '@charset "latin1";ä'),
+            ('latin1', 'ascii', ('utf-16', '@charset "utf-8";ä'.encode('utf-8'))):
+                ('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
 
             # override only
             ('latin1', None, None): (None, None, None),
-            ('latin1', None, (None, u''.encode())): ('latin1', 0, u''),
-            ('latin1', None, (None, u'123'.encode())): ('latin1', 0, u'123'),
-            ('latin1', None, (None, u'ä'.encode('iso-8859-1'))):
-                ('latin1', 0, u'ä'),
-            ('latin1', None, (None, u'a'.encode('ascii'))):
-                ('latin1', 0, u'a'),
+            ('latin1', None, (None, ''.encode())): ('latin1', 0, ''),
+            ('latin1', None, (None, '123'.encode())): ('latin1', 0, '123'),
+            ('latin1', None, (None, 'ä'.encode('iso-8859-1'))):
+                ('latin1', 0, 'ä'),
+            ('latin1', None, (None, 'a'.encode('ascii'))):
+                ('latin1', 0, 'a'),
             # + @charset
-            ('latin1', None, (None, u'@charset "ascii";'.encode())):
-                ('latin1', 0, u'@charset "latin1";'),
-            ('latin1', None, (None, u'@charset "utf-8";ä'.encode('latin1'))):
-                ('latin1', 0, u'@charset "latin1";ä'),
-            ('latin1', None, (None, u'@charset "utf-8";ä'.encode('utf-8'))):
-                ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1!
+            ('latin1', None, (None, '@charset "ascii";'.encode())):
+                ('latin1', 0, '@charset "latin1";'),
+            ('latin1', None, (None, '@charset "utf-8";ä'.encode('latin1'))):
+                ('latin1', 0, '@charset "latin1";ä'),
+            ('latin1', None, (None, '@charset "utf-8";ä'.encode('utf-8'))):
+                ('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
 
             # override + parent
             ('latin1', 'ascii', None): (None, None, None),
-            ('latin1', 'ascii', (None, u''.encode())): ('latin1', 0, u''),
-            ('latin1', 'ascii', (None, u'123'.encode())): ('latin1', 0, u'123'),
-            ('latin1', 'ascii', (None, u'ä'.encode('iso-8859-1'))):
-                ('latin1', 0, u'ä'),
-            ('latin1', 'ascii', (None, u'a'.encode('ascii'))):
-                ('latin1', 0, u'a'),
+            ('latin1', 'ascii', (None, ''.encode())): ('latin1', 0, ''),
+            ('latin1', 'ascii', (None, '123'.encode())): ('latin1', 0, '123'),
+            ('latin1', 'ascii', (None, 'ä'.encode('iso-8859-1'))):
+                ('latin1', 0, 'ä'),
+            ('latin1', 'ascii', (None, 'a'.encode('ascii'))):
+                ('latin1', 0, 'a'),
             # + @charset
-            ('latin1', 'ascii', (None, u'@charset "ascii";'.encode())):
-                ('latin1', 0, u'@charset "latin1";'),
-            ('latin1', 'ascii', (None, u'@charset "utf-8";ä'.encode('latin1'))):
-                ('latin1', 0, u'@charset "latin1";ä'),
-            ('latin1', 'ascii', (None, u'@charset "utf-8";ä'.encode('utf-8'))):
-                ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1!
+            ('latin1', 'ascii', (None, '@charset "ascii";'.encode())):
+                ('latin1', 0, '@charset "latin1";'),
+            ('latin1', 'ascii', (None, '@charset "utf-8";ä'.encode('latin1'))):
+                ('latin1', 0, '@charset "latin1";ä'),
+            ('latin1', 'ascii', (None, '@charset "utf-8";ä'.encode('utf-8'))):
+                ('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
 
             # override + http
-            ('latin1', None, ('utf-16', u''.encode())): ('latin1', 0, u''),
-            ('latin1', None, ('utf-16', u'123'.encode())): ('latin1', 0, u'123'),
-            ('latin1', None, ('utf-16', u'ä'.encode('iso-8859-1'))):
-                ('latin1', 0, u'ä'),
-            ('latin1', None, ('utf-16', u'a'.encode('ascii'))):
-                ('latin1', 0, u'a'),
+            ('latin1', None, ('utf-16', ''.encode())): ('latin1', 0, ''),
+            ('latin1', None, ('utf-16', '123'.encode())): ('latin1', 0, '123'),
+            ('latin1', None, ('utf-16', 'ä'.encode('iso-8859-1'))):
+                ('latin1', 0, 'ä'),
+            ('latin1', None, ('utf-16', 'a'.encode('ascii'))):
+                ('latin1', 0, 'a'),
             # + @charset
-            ('latin1', None, ('utf-16', u'@charset "ascii";'.encode())):
-                ('latin1', 0, u'@charset "latin1";'),
-            ('latin1', None, ('utf-16', u'@charset "utf-8";ä'.encode('latin1'))):
-                ('latin1', 0, u'@charset "latin1";ä'),
-            ('latin1', None, ('utf-16', u'@charset "utf-8";ä'.encode('utf-8'))):
-                ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1!
+            ('latin1', None, ('utf-16', '@charset "ascii";'.encode())):
+                ('latin1', 0, '@charset "latin1";'),
+            ('latin1', None, ('utf-16', '@charset "utf-8";ä'.encode('latin1'))):
+                ('latin1', 0, '@charset "latin1";ä'),
+            ('latin1', None, ('utf-16', '@charset "utf-8";ä'.encode('utf-8'))):
+                ('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
 
             # override ü @charset
-            ('latin1', None, (None, u'@charset "ascii";'.encode())):
-                ('latin1', 0, u'@charset "latin1";'),
-            ('latin1', None, (None, u'@charset "utf-8";ä'.encode('latin1'))):
-                ('latin1', 0, u'@charset "latin1";ä'),
-            ('latin1', None, (None, u'@charset "utf-8";ä'.encode('utf-8'))):
-                ('latin1', 0, u'@charset "latin1";\xc3\xa4'), # read as latin1!
+            ('latin1', None, (None, '@charset "ascii";'.encode())):
+                ('latin1', 0, '@charset "latin1";'),
+            ('latin1', None, (None, '@charset "utf-8";ä'.encode('latin1'))):
+                ('latin1', 0, '@charset "latin1";ä'),
+            ('latin1', None, (None, '@charset "utf-8";ä'.encode('utf-8'))):
+                ('latin1', 0, '@charset "latin1";\xc3\xa4'), # read as latin1!
 
 
             # ===== 1. HTTP WINS =====
-            (None, 'ascii', ('latin1', u''.encode())): ('latin1', 1, u''),
-            (None, 'ascii', ('latin1', u'123'.encode())): ('latin1', 1, u'123'),
-            (None, 'ascii', ('latin1', u'ä'.encode('iso-8859-1'))):
-                ('latin1', 1, u'ä'),
-            (None, 'ascii', ('latin1', u'a'.encode('ascii'))):
-                ('latin1', 1, u'a'),
+            (None, 'ascii', ('latin1', ''.encode())): ('latin1', 1, ''),
+            (None, 'ascii', ('latin1', '123'.encode())): ('latin1', 1, '123'),
+            (None, 'ascii', ('latin1', 'ä'.encode('iso-8859-1'))):
+                ('latin1', 1, 'ä'),
+            (None, 'ascii', ('latin1', 'a'.encode('ascii'))):
+                ('latin1', 1, 'a'),
             # + @charset
-            (None, 'ascii', ('latin1', u'@charset "ascii";'.encode())):
-                ('latin1', 1, u'@charset "latin1";'),
-            (None, 'ascii', ('latin1', u'@charset "utf-8";ä'.encode('latin1'))):
-                ('latin1', 1, u'@charset "latin1";ä'),
-            (None, 'ascii', ('latin1', u'@charset "utf-8";ä'.encode('utf-8'))):
-                ('latin1', 1, u'@charset "latin1";\xc3\xa4'), # read as latin1!
+            (None, 'ascii', ('latin1', '@charset "ascii";'.encode())):
+                ('latin1', 1, '@charset "latin1";'),
+            (None, 'ascii', ('latin1', '@charset "utf-8";ä'.encode('latin1'))):
+                ('latin1', 1, '@charset "latin1";ä'),
+            (None, 'ascii', ('latin1', '@charset "utf-8";ä'.encode('utf-8'))):
+                ('latin1', 1, '@charset "latin1";\xc3\xa4'), # read as latin1!
 
 
             # ===== 2. @charset WINS =====
-            (None, 'ascii', (None, u'@charset "latin1";'.encode())):
-                ('latin1', 2, u'@charset "latin1";'),
-            (None, 'ascii', (None, u'@charset "latin1";ä'.encode('latin1'))):
-                ('latin1', 2, u'@charset "latin1";ä'),
-            (None, 'ascii', (None, u'@charset "latin1";ä'.encode('utf-8'))):
-                ('latin1', 2, u'@charset "latin1";\xc3\xa4'), # read as latin1!
+            (None, 'ascii', (None, '@charset "latin1";'.encode())):
+                ('latin1', 2, '@charset "latin1";'),
+            (None, 'ascii', (None, '@charset "latin1";ä'.encode('latin1'))):
+                ('latin1', 2, '@charset "latin1";ä'),
+            (None, 'ascii', (None, '@charset "latin1";ä'.encode('utf-8'))):
+                ('latin1', 2, '@charset "latin1";\xc3\xa4'), # read as latin1!
 
             # ===== 2. BOM WINS =====
-            (None, 'ascii', (None, u'ä'.encode('utf-8-sig'))):
-                ('utf-8-sig', 2, u'\xe4'), # read as latin1!
-            (None, 'ascii', (None, u'@charset "utf-8";ä'.encode('utf-8-sig'))):
-                ('utf-8-sig', 2, u'@charset "utf-8";\xe4'), # read as latin1!
-            (None, 'ascii', (None, u'@charset "latin1";ä'.encode('utf-8-sig'))):
-                ('utf-8-sig', 2, u'@charset "utf-8";\xe4'), # read as latin1!
+            (None, 'ascii', (None, 'ä'.encode('utf-8-sig'))):
+                ('utf-8-sig', 2, '\xe4'), # read as latin1!
+            (None, 'ascii', (None, '@charset "utf-8";ä'.encode('utf-8-sig'))):
+                ('utf-8-sig', 2, '@charset "utf-8";\xe4'), # read as latin1!
+            (None, 'ascii', (None, '@charset "latin1";ä'.encode('utf-8-sig'))):
+                ('utf-8-sig', 2, '@charset "utf-8";\xe4'), # read as latin1!
 
 
             # ===== 4. parentEncoding WINS =====
-            (None, 'latin1', (None, u''.encode())): ('latin1', 4, u''),
-            (None, 'latin1', (None, u'123'.encode())): ('latin1', 4, u'123'),
-            (None, 'latin1', (None, u'ä'.encode('iso-8859-1'))):
-                ('latin1', 4, u'ä'),
-            (None, 'latin1', (None, u'a'.encode('ascii'))):
-                ('latin1', 4, u'a'),
-            (None, 'latin1', (None, u'ä'.encode('utf-8'))):
-                ('latin1', 4, u'\xc3\xa4'), # read as latin1!
+            (None, 'latin1', (None, ''.encode())): ('latin1', 4, ''),
+            (None, 'latin1', (None, '123'.encode())): ('latin1', 4, '123'),
+            (None, 'latin1', (None, 'ä'.encode('iso-8859-1'))):
+                ('latin1', 4, 'ä'),
+            (None, 'latin1', (None, 'a'.encode('ascii'))):
+                ('latin1', 4, 'a'),
+            (None, 'latin1', (None, 'ä'.encode('utf-8'))):
+                ('latin1', 4, '\xc3\xa4'), # read as latin1!
 
             # ===== 5. default WINS which in this case is None! =====
-            (None, None, (None, u''.encode())): ('utf-8', 5, u''),
-            (None, None, (None, u'123'.encode())): ('utf-8', 5, u'123'),
-            (None, None, (None, u'a'.encode('ascii'))):
-                ('utf-8', 5, u'a'),
-            (None, None, (None, u'ä'.encode('utf-8'))):
-                ('utf-8', 5, u'ä'), # read as utf-8
-            (None, None, (None, u'ä'.encode('iso-8859-1'))): # trigger UnicodeDecodeError!
+            (None, None, (None, ''.encode())): ('utf-8', 5, ''),
+            (None, None, (None, '123'.encode())): ('utf-8', 5, '123'),
+            (None, None, (None, 'a'.encode('ascii'))):
+                ('utf-8', 5, 'a'),
+            (None, None, (None, 'ä'.encode('utf-8'))):
+                ('utf-8', 5, 'ä'), # read as utf-8
+            (None, None, (None, 'ä'.encode('iso-8859-1'))): # trigger UnicodeDecodeError!
                 ('utf-8', 5, None),
 
 
         }
-        for (override, parent, r), exp in tests.items():
+        for (override, parent, r), exp in list(tests.items()):
             self.assertEqual(_readUrl(url,
                                        overrideEncoding=override,
                                        parentEncoding=parent,
@@ -362,15 +362,15 @@ class _readUrl_TestCase(basetest.BaseTestCase):
             # positive tests
             tests = {
                 # content-type, contentstr: encoding, contentstr
-                ('text/css', u'€'.encode('utf-8')):
-                        (None, u'€'.encode('utf-8')),
-                ('text/css;charset=utf-8', u'€'.encode('utf-8')):
-                        ('utf-8', u'€'.encode('utf-8')),
+                ('text/css', '€'.encode('utf-8')):
+                        (None, '€'.encode('utf-8')),
+                ('text/css;charset=utf-8', '€'.encode('utf-8')):
+                        ('utf-8', '€'.encode('utf-8')),
                 ('text/css;charset=ascii', 'a'):
                         ('ascii', 'a')
             }
             url = 'http://example.com/test.css'
-            for (contenttype, content), exp in tests.items():
+            for (contenttype, content), exp in list(tests.items()):
                 @mock.patch(urlopenpatch, new=urlopen(url, contenttype, content))
                 def do(url):
                     return _defaultFetcher(url)
@@ -390,11 +390,11 @@ class _readUrl_TestCase(basetest.BaseTestCase):
             tests = {
                 '1': (ValueError, ['invalid value for url']),
                 #_readUrl('mailto:a.css')
-                'mailto:e4': (urllib2.URLError, ['urlerror']),
+                'mailto:e4': (urllib.error.URLError, ['urlerror']),
                 # cannot resolve x, IOError
-                'http://x': (urllib2.URLError, ['ioerror']),
+                'http://x': (urllib.error.URLError, ['ioerror']),
             }
-            for url, (exception, args) in tests.items():
+            for url, (exception, args) in list(tests.items()):
                 @mock.patch(urlopenpatch, new=urlopen(url, exception=exception, args=args))
                 def do(url):
                     return _defaultFetcher(url)
@@ -405,10 +405,10 @@ class _readUrl_TestCase(basetest.BaseTestCase):
             urlrequestpatch = 'urllib2.urlopen' if basetest.PY2x else 'urllib.request.Request' 
             tests = {
                 #_readUrl('http://cthedot.de/__UNKNOWN__.css')
-                'e2': (urllib2.HTTPError, ['u', 500, 'server error', {}, None]),
-                'e3': (urllib2.HTTPError, ['u', 404, 'not found', {}, None]),
+                'e2': (urllib.error.HTTPError, ['u', 500, 'server error', {}, None]),
+                'e3': (urllib.error.HTTPError, ['u', 404, 'not found', {}, None]),
             }
-            for url, (exception, args) in tests.items():
+            for url, (exception, args) in list(tests.items()):
                 @mock.patch(urlrequestpatch, new=urlopen(url, exception=exception, args=args))
                 def do(url):
                     return _defaultFetcher(url)
@@ -416,7 +416,7 @@ class _readUrl_TestCase(basetest.BaseTestCase):
                 self.assertRaises(exception, do, url)
 
         else:
-            self.assertEqual(False, u'Mock needed for this test')
+            self.assertEqual(False, 'Mock needed for this test')
 
 
 class TestLazyRegex(basetest.BaseTestCase):
@@ -440,12 +440,12 @@ class TestLazyRegex(basetest.BaseTestCase):
     def test_calling(self):
         self.assertIsNone(self.lazyre('bar'))
         match = self.lazyre('foobar')
-        self.assertEquals(match.group(), 'foo')
+        self.assertEqual(match.group(), 'foo')
 
     def test_matching(self):
         self.assertIsNone(self.lazyre.match('bar'))
         match = self.lazyre.match('foobar')
-        self.assertEquals(match.group(), 'foo')
+        self.assertEqual(match.group(), 'foo')
 
     def test_matching_with_position_parameters(self):
         self.assertIsNone(self.lazyre.match('foo', 1))
@@ -454,56 +454,56 @@ class TestLazyRegex(basetest.BaseTestCase):
     def test_searching(self):
         self.assertIsNone(self.lazyre.search('rafuubar'))
         match = self.lazyre.search('rafoobar')
-        self.assertEquals(match.group(), 'foo')
+        self.assertEqual(match.group(), 'foo')
 
     def test_searching_with_position_parameters(self):
         self.assertIsNone(self.lazyre.search('rafoobar', 3))
         self.assertIsNone(self.lazyre.search('rafoobar', 0, 4))
         match = self.lazyre.search('rafoofuobar', 4)
-        self.assertEquals(match.group(), 'fuo')
+        self.assertEqual(match.group(), 'fuo')
 
     def test_split(self):
-        self.assertEquals(self.lazyre.split('rafoobarfoobaz'),
+        self.assertEqual(self.lazyre.split('rafoobarfoobaz'),
                           ['ra', 'bar', 'baz'])
-        self.assertEquals(self.lazyre.split('rafoobarfoobaz', 1),
+        self.assertEqual(self.lazyre.split('rafoobarfoobaz', 1),
                           ['ra', 'barfoobaz'])
 
     def test_findall(self):
-        self.assertEquals(self.lazyre.findall('rafoobarfuobaz'),
+        self.assertEqual(self.lazyre.findall('rafoobarfuobaz'),
                           ['foo', 'fuo'])
 
     def test_finditer(self):
         result = self.lazyre.finditer('rafoobarfuobaz')
-        self.assertEquals([m.group() for m in result], ['foo', 'fuo'])
+        self.assertEqual([m.group() for m in result], ['foo', 'fuo'])
 
     def test_sub(self):
-        self.assertEquals(self.lazyre.sub('bar', 'foofoo'), 'barbar')
-        self.assertEquals(self.lazyre.sub(lambda x: 'baz', 'foofoo'), 'bazbaz')
+        self.assertEqual(self.lazyre.sub('bar', 'foofoo'), 'barbar')
+        self.assertEqual(self.lazyre.sub(lambda x: 'baz', 'foofoo'), 'bazbaz')
 
     def test_subn(self):
         subbed = self.lazyre.subn('bar', 'foofoo')
-        self.assertEquals(subbed, ('barbar', 2))
+        self.assertEqual(subbed, ('barbar', 2))
         subbed = self.lazyre.subn(lambda x: 'baz', 'foofoo')
-        self.assertEquals(subbed, ('bazbaz', 2))
+        self.assertEqual(subbed, ('bazbaz', 2))
 
     def test_groups(self):
         lazyre = LazyRegex('(.)(.)')
         self.assertIsNone(lazyre.groups)
         lazyre.ensure()
-        self.assertEquals(lazyre.groups, 2)
+        self.assertEqual(lazyre.groups, 2)
 
     def test_groupindex(self):
         lazyre = LazyRegex('(?P<foo>.)')
         self.assertIsNone(lazyre.groupindex)
         lazyre.ensure()
-        self.assertEquals(lazyre.groupindex, {'foo': 1})
+        self.assertEqual(lazyre.groupindex, {'foo': 1})
 
     def test_flags(self):
         self.lazyre.ensure()
-        self.assertEquals(self.lazyre.flags, re.compile('.').flags)
+        self.assertEqual(self.lazyre.flags, re.compile('.').flags)
 
     def test_pattern(self):
-        self.assertEquals(self.lazyre.pattern, 'f.o')
+        self.assertEqual(self.lazyre.pattern, 'f.o')
 
 
 if __name__ == '__main__':
diff --git a/src/cssutils/tests/test_value.py b/src/cssutils/tests/test_value.py
index 7e13860..0fb4a51 100644
--- a/src/cssutils/tests/test_value.py
+++ b/src/cssutils/tests/test_value.py
@@ -2,7 +2,7 @@
 
 # from decimal import Decimal # maybe for later tests?
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 import types
 
@@ -15,12 +15,12 @@ class PropertyValueTestCase(basetest.BaseTestCase):
     def test_init(self):
         "PropertyValue.__init__() .item() .length"
         pv = cssutils.css.PropertyValue()
-        self.assertEqual(u'', pv.cssText)
+        self.assertEqual('', pv.cssText)
         self.assertEqual(0, pv.length)
-        self.assertEqual(u'', pv.value)
+        self.assertEqual('', pv.value)
 
-        cssText = u'0, 0/0 1px var(x) url(x)'
-        items = [u'0', u'0', u'0', u'1px', u'var(x)', 'url(x)']
+        cssText = '0, 0/0 1px var(x) url(x)'
+        items = ['0', '0', '0', '1px', 'var(x)', 'url(x)']
         pv = cssutils.css.PropertyValue(cssText)
         self.assertEqual(cssText, pv.cssText)
         self.assertEqual(6, len(pv))
@@ -38,60 +38,60 @@ class PropertyValueTestCase(basetest.BaseTestCase):
     def test_cssText(self):
         "PropertyValue.cssText"
         tests = {
-                 u'0': (None, 1, None),
-                 u'0 0': (None, 2, None),
-                 u'0, 0': (None, 2, None),
-                 u'0,0': (u'0, 0', 2, None),
-                 u'0  ,   0': (u'0, 0', 2, None),
-                 u'0/0': (None, 2, None),
-                 u'/**/ 0 /**/': (None, 1, u'0'),
-                 u'0 /**/ 0 /**/ 0': (None, 3, u'0 0 0'),
-                 u'0, /**/ 0, /**/ 0': (None, 3, u'0, 0, 0'),
-                 u'0//**/ 0//**/ 0': (None, 3, u'0/0/0'),
-                 u'/**/ red': (None, 1, u'red'),
-                 u'/**/red': (u'/**/ red', 1, u'red'),
-                 u'red /**/': (None, 1, u'red'),
-                 u'red/**/': (u'red /**/', 1, u'red'),
-
-                 u'a()1,-1,+1,1%,-1%,1px,-1px,"a",a,url(a),#aabb44': (
-                 u'a() 1, -1, +1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4',
-                    12, u'a() 1, -1, +1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4'),
+                 '0': (None, 1, None),
+                 '0 0': (None, 2, None),
+                 '0, 0': (None, 2, None),
+                 '0,0': ('0, 0', 2, None),
+                 '0  ,   0': ('0, 0', 2, None),
+                 '0/0': (None, 2, None),
+                 '/**/ 0 /**/': (None, 1, '0'),
+                 '0 /**/ 0 /**/ 0': (None, 3, '0 0 0'),
+                 '0, /**/ 0, /**/ 0': (None, 3, '0, 0, 0'),
+                 '0//**/ 0//**/ 0': (None, 3, '0/0/0'),
+                 '/**/ red': (None, 1, 'red'),
+                 '/**/red': ('/**/ red', 1, 'red'),
+                 'red /**/': (None, 1, 'red'),
+                 'red/**/': ('red /**/', 1, 'red'),
+
+                 'a()1,-1,+1,1%,-1%,1px,-1px,"a",a,url(a),#aabb44': (
+                 'a() 1, -1, +1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4',
+                    12, 'a() 1, -1, +1, 1%, -1%, 1px, -1px, "a", a, url(a), #ab4'),
 
                 # calc values
-                 u'calc(1)': (None, 1, u'calc(1)'),
-                 u'calc( 1)': (u'calc(1)', 1, u'calc(1)'),
-                 u'calc(1 )': (u'calc(1)', 1, u'calc(1)'),
-                 u'calc(1px)': (None, 1, u'calc(1px)'),
-                 u'calc(1p-x-)': (None, 1, u'calc(1p-x-)'),
-                 u'calc(1%)': (None, 1, u'calc(1%)'),
-                 u'calc(-1)': (None, 1, u'calc(-1)'),
-                 u'calc(+1)': (None, 1, u'calc(+1)'),
-                 u'calc(1  +   1px)': (u'calc(1 + 1px)', 1, u'calc(1 + 1px)'),
-                 u'calc(1 - 1px)': (None, 1, u'calc(1 - 1px)'),
-                 u'calc(1*1px)': (u'calc(1 * 1px)', 1, u'calc(1 * 1px)'),
-                 u'calc(1  /  1px)': (u'calc(1 / 1px)', 1, u'calc(1 / 1px)'),
-                 u'calc( 1*1px)': (u'calc(1 * 1px)', 1, u'calc(1 * 1px)'),
-                 u'calc( 1  /  1px)': (u'calc(1 / 1px)', 1, u'calc(1 / 1px)'),
-                 u'calc(1*1px )': (u'calc(1 * 1px)', 1, u'calc(1 * 1px)'),
-                 u'calc(1  /  1px )': (u'calc(1 / 1px)', 1, u'calc(1 / 1px)'),
-                 u'calc( 1*1px )': (u'calc(1 * 1px)', 1, u'calc(1 * 1px)'),
-                 u'calc( 1  /  1px )': (u'calc(1 / 1px)', 1, u'calc(1 / 1px)'),
-                 u'calc(var(X))': (None, 1, None),
-                 u'calc(2 * var(X))': (None, 1, None),
-                 u'calc(2px + var(X))': (None, 1, None),
+                 'calc(1)': (None, 1, 'calc(1)'),
+                 'calc( 1)': ('calc(1)', 1, 'calc(1)'),
+                 'calc(1 )': ('calc(1)', 1, 'calc(1)'),
+                 'calc(1px)': (None, 1, 'calc(1px)'),
+                 'calc(1p-x-)': (None, 1, 'calc(1p-x-)'),
+                 'calc(1%)': (None, 1, 'calc(1%)'),
+                 'calc(-1)': (None, 1, 'calc(-1)'),
+                 'calc(+1)': (None, 1, 'calc(+1)'),
+                 'calc(1  +   1px)': ('calc(1 + 1px)', 1, 'calc(1 + 1px)'),
+                 'calc(1 - 1px)': (None, 1, 'calc(1 - 1px)'),
+                 'calc(1*1px)': ('calc(1 * 1px)', 1, 'calc(1 * 1px)'),
+                 'calc(1  /  1px)': ('calc(1 / 1px)', 1, 'calc(1 / 1px)'),
+                 'calc( 1*1px)': ('calc(1 * 1px)', 1, 'calc(1 * 1px)'),
+                 'calc( 1  /  1px)': ('calc(1 / 1px)', 1, 'calc(1 / 1px)'),
+                 'calc(1*1px )': ('calc(1 * 1px)', 1, 'calc(1 * 1px)'),
+                 'calc(1  /  1px )': ('calc(1 / 1px)', 1, 'calc(1 / 1px)'),
+                 'calc( 1*1px )': ('calc(1 * 1px)', 1, 'calc(1 * 1px)'),
+                 'calc( 1  /  1px )': ('calc(1 / 1px)', 1, 'calc(1 / 1px)'),
+                 'calc(var(X))': (None, 1, None),
+                 'calc(2 * var(X))': (None, 1, None),
+                 'calc(2px + var(X))': (None, 1, None),
 
                  #issue #24
-                 u'rgb(0, 10, 255)': (None, 1, u'rgb(0, 10, 255)'),
-                 u'hsl(10, 10%, 25%)': (None, 1, u'hsl(10, 10%, 25%)'),
-                 u'rgba(0, 10, 255, 0.5)': (None, 1, u'rgba(0, 10, 255, 0.5)'),
-                 u'hsla(10, 10%, 25%, 0.5)': (None, 1, u'hsla(10, 10%, 25%, 0.5)'),
+                 'rgb(0, 10, 255)': (None, 1, 'rgb(0, 10, 255)'),
+                 'hsl(10, 10%, 25%)': (None, 1, 'hsl(10, 10%, 25%)'),
+                 'rgba(0, 10, 255, 0.5)': (None, 1, 'rgba(0, 10, 255, 0.5)'),
+                 'hsla(10, 10%, 25%, 0.5)': (None, 1, 'hsla(10, 10%, 25%, 0.5)'),
 
                 #issue #27
-                u'matrix(0.000092, 0.2500010, -0.250000, 0.000092, 0, 0)': (
-                    u'matrix(0.000092, 0.250001, -0.25, 0.000092, 0, 0)', 1,
-                    u'matrix(0.000092, 0.250001, -0.25, 0.000092, 0, 0)')
+                'matrix(0.000092, 0.2500010, -0.250000, 0.000092, 0, 0)': (
+                    'matrix(0.000092, 0.250001, -0.25, 0.000092, 0, 0)', 1,
+                    'matrix(0.000092, 0.250001, -0.25, 0.000092, 0, 0)')
                  }
-        for (cssText, (c, l, v)) in tests.items():
+        for (cssText, (c, l, v)) in list(tests.items()):
             if c is None:
                 c = cssText
             if v is None:
@@ -103,27 +103,27 @@ class PropertyValueTestCase(basetest.BaseTestCase):
             self.assertEqual(v, pv.value)
 
         tests = {
-                u'0 0px -0px +0px': (u'0 0 0 0', 4),
-                u'1 2 3 4': (None, 4),
-                u'-1 -2 -3 -4': (None, 4),
-                u'-1 2': (None, 2),
-                u'-1px red "x"': (None, 3),
-                u'a, b c': (None, 3),
-                u'1px1 2% 3': (u'1px1 2% 3', 3),
-                u'f(+1pX, -2, 5%) 1': (u'f(+1px, -2, 5%) 1', 2),
-                u'0 f()0': (u'0 f() 0', 3),
-                u'f()0': (u'f() 0', 2),
-                u'f()1%': (u'f() 1%', 2),
-                u'f()1px': (u'f() 1px', 2),
-                u'f()"str"': (u'f() "str"', 2),
-                u'f()ident': (u'f() ident', 2),
-                u'f()#123': (u'f() #123', 2),
-                u'f()url()': (u'f() url()', 2),
-                u'f()f()': (u'f() f()', 2),
-                u'url(x.gif)0 0': (u'url(x.gif) 0 0', 3),
-                u'url(x.gif)no-repeat': (u'url(x.gif) no-repeat', 2)
+                '0 0px -0px +0px': ('0 0 0 0', 4),
+                '1 2 3 4': (None, 4),
+                '-1 -2 -3 -4': (None, 4),
+                '-1 2': (None, 2),
+                '-1px red "x"': (None, 3),
+                'a, b c': (None, 3),
+                '1px1 2% 3': ('1px1 2% 3', 3),
+                'f(+1pX, -2, 5%) 1': ('f(+1px, -2, 5%) 1', 2),
+                '0 f()0': ('0 f() 0', 3),
+                'f()0': ('f() 0', 2),
+                'f()1%': ('f() 1%', 2),
+                'f()1px': ('f() 1px', 2),
+                'f()"str"': ('f() "str"', 2),
+                'f()ident': ('f() ident', 2),
+                'f()#123': ('f() #123', 2),
+                'f()url()': ('f() url()', 2),
+                'f()f()': ('f() f()', 2),
+                'url(x.gif)0 0': ('url(x.gif) 0 0', 3),
+                'url(x.gif)no-repeat': ('url(x.gif) no-repeat', 2)
                 }
-        for (cssText, (c, l)) in tests.items():
+        for (cssText, (c, l)) in list(tests.items()):
             if c is None:
                 c = cssText
             pv = cssutils.css.PropertyValue(cssText)
@@ -132,37 +132,37 @@ class PropertyValueTestCase(basetest.BaseTestCase):
 
         tests = {
             # hash and rgb/a
-            u'#112234': u'#112234',
-            u'#112233': u'#123',
-            u'rgb(1,2,3)': u'rgb(1, 2, 3)',
-            u'rgb(  1  ,  2  ,  3  )': u'rgb(1, 2, 3)',
-            u'rgba(1,2,3,4)': u'rgba(1, 2, 3, 4)',
-            u'rgba(  1  ,  2  ,  3  ,  4 )': u'rgba(1, 2, 3, 4)',
-            u'rgb(-1,+2,0)': u'rgb(-1, +2, 0)',
-            u'rgba(-1,+2,0, 0)': u'rgba(-1, +2, 0, 0)',
+            '#112234': '#112234',
+            '#112233': '#123',
+            'rgb(1,2,3)': 'rgb(1, 2, 3)',
+            'rgb(  1  ,  2  ,  3  )': 'rgb(1, 2, 3)',
+            'rgba(1,2,3,4)': 'rgba(1, 2, 3, 4)',
+            'rgba(  1  ,  2  ,  3  ,  4 )': 'rgba(1, 2, 3, 4)',
+            'rgb(-1,+2,0)': 'rgb(-1, +2, 0)',
+            'rgba(-1,+2,0, 0)': 'rgba(-1, +2, 0, 0)',
 
             # FUNCTION
-            u'f(1,2)': u'f(1, 2)',
-            u'f(  1  ,  2  )': u'f(1, 2)',
-            u'f(-1,+2)': u'f(-1, +2)',
-            u'f(  -1  ,  +2  )': u'f(-1, +2)',
-            u'fun(  -1  ,  +2  )': u'fun(-1, +2)',
-            u'local( x )': u'local(x)',
-            u'test(1px, #111, y, 1, 1%, "1", y(), var(x))':
-                u'test(1px, #111, y, 1, 1%, "1", y(), var(x))',
-            u'test(-1px, #111, y, -1, -1%, "1", -y())':
-                u'test(-1px, #111, y, -1, -1%, "1", -y())',
-            u'url(y)  format( "x" ,  "y" )': u'url(y) format("x", "y")',
-            u'f(1 2,3 4)': u'f(1 2, 3 4)',
+            'f(1,2)': 'f(1, 2)',
+            'f(  1  ,  2  )': 'f(1, 2)',
+            'f(-1,+2)': 'f(-1, +2)',
+            'f(  -1  ,  +2  )': 'f(-1, +2)',
+            'fun(  -1  ,  +2  )': 'fun(-1, +2)',
+            'local( x )': 'local(x)',
+            'test(1px, #111, y, 1, 1%, "1", y(), var(x))':
+                'test(1px, #111, y, 1, 1%, "1", y(), var(x))',
+            'test(-1px, #111, y, -1, -1%, "1", -y())':
+                'test(-1px, #111, y, -1, -1%, "1", -y())',
+            'url(y)  format( "x" ,  "y" )': 'url(y) format("x", "y")',
+            'f(1 2,3 4)': 'f(1 2, 3 4)',
 
             # IE expression
-            ur'Expression()': u'Expression()',
-            ur'expression(-1 < +2)': u'expression(-1<+2)',
-            ur'expression(document.width == "1")': u'expression(document.width=="1")',
-            u'alpha(opacity=80)': u'alpha(opacity=80)',
-            u'alpha( opacity = 80 , x=2  )': u'alpha(opacity=80, x=2)',
-            u'expression(eval(document.documentElement.scrollTop))':
-                u'expression(eval(document.documentElement.scrollTop))',
+            r'Expression()': 'Expression()',
+            r'expression(-1 < +2)': 'expression(-1<+2)',
+            r'expression(document.width == "1")': 'expression(document.width=="1")',
+            'alpha(opacity=80)': 'alpha(opacity=80)',
+            'alpha( opacity = 80 , x=2  )': 'alpha(opacity=80, x=2)',
+            'expression(eval(document.documentElement.scrollTop))':
+                'expression(eval(document.documentElement.scrollTop))',
             #TODO
 #            u'expression((function(ele){ele.style.behavior="none";})(this))':
 #                u'expression((function(ele){ele.style.behavior="none";})(this))',
@@ -222,82 +222,82 @@ class PropertyValueTestCase(basetest.BaseTestCase):
             'a b1,b2 b2,b3,b4': 'a b1, b2 b2, b3, b4',
             'a b1  ,   b2   b2  ,  b3  ,   b4': 'a b1, b2 b2, b3, b4',
             'u+1  ,   u+2-5': 'u+1, u+2-5',
-            u'local( x ),  url(y)  format( "x" ,  "y" )':
-                u'local(x), url(y) format("x", "y")',
+            'local( x ),  url(y)  format( "x" ,  "y" )':
+                'local(x), url(y) format("x", "y")',
             # FUNCTION
-            u'attr( href )': u'attr(href)',
+            'attr( href )': 'attr(href)',
             # PrinceXML extende FUNC syntax with nested FUNC
-            u'target-counter(attr(href),page)': u'target-counter(attr(href), page)'
+            'target-counter(attr(href),page)': 'target-counter(attr(href), page)'
                  }
         self.do_equal_r(tests)
 
         tests = [
-                    u'a+',
-                    u'-',
-                    u'+',
-                    u'-%',
-                    u'+a',
-                    u'--1px',
-                    u'++1px',
-                    u'#',
-                    u'#00',
-                    u'#12x',
-                    u'#xyz',
-                    u'#0000',
-                    u'#00000',
-                    u'#0000000',
-                    u'-#0',
+                    'a+',
+                    '-',
+                    '+',
+                    '-%',
+                    '+a',
+                    '--1px',
+                    '++1px',
+                    '#',
+                    '#00',
+                    '#12x',
+                    '#xyz',
+                    '#0000',
+                    '#00000',
+                    '#0000000',
+                    '-#0',
                     # operator
-                    u',',
-                    u'1,,2',
-                    u'1,/**/,2',
-                    u'1  ,  /**/  ,  2',
-                    u'1,',
-                    u'1, ',
-                    u'1 ,',
-                    u'1 , ',
-                    u'1  ,  ',
-                    u'1//2',
+                    ',',
+                    '1,,2',
+                    '1,/**/,2',
+                    '1  ,  /**/  ,  2',
+                    '1,',
+                    '1, ',
+                    '1 ,',
+                    '1 , ',
+                    '1  ,  ',
+                    '1//2',
                     # URL
-                    u'url(x))',
+                    'url(x))',
                     # string
-                    u'"',
-                    u"'",
+                    '"',
+                    "'",
                     # function
-                    u'f(-)',
-                    u'f(x))',
+                    'f(-)',
+                    'f(x))',
                     #calc
-                    u'calc(',
-                    u'calc(1',
-                    u'calc(1 + 1',
-                    u'calc(1+1)',
-                    u'calc(1-1)',
-                    u'calc(1 +1)',
-                    u'calc(1+ 1)',
-                    u'calc(1 -1)',
-                    u'calc(1- 1)',
-                    u'calc(+)',
-                    u'calc(+ 1)',
-                    u'calc(-)',
-                    u'calc(- 1)',
-                    u'calc(*)',
-                    u'calc(*1)',
-                    u'calc(* 2)',
-                    u'calc(/)',
-                    u'calc(/1)',
-                    u'calc(/ 2)',
-                    u'calc(1+)',
-                    u'calc(1 +)',
-                    u'calc(1 + )',
-                    u'calc(2px -)',
-                    u'calc(3px*)',
-                    u'calc(3px *)',
-                    u'calc(3px * )',
-                    u'calc(4em/)',
-                    u'calc(4em /)',
-                    u'calc(4em / )',
-                    u'calc(1 + + 1)',
-                    u'calc(1 ++ 1)'
+                    'calc(',
+                    'calc(1',
+                    'calc(1 + 1',
+                    'calc(1+1)',
+                    'calc(1-1)',
+                    'calc(1 +1)',
+                    'calc(1+ 1)',
+                    'calc(1 -1)',
+                    'calc(1- 1)',
+                    'calc(+)',
+                    'calc(+ 1)',
+                    'calc(-)',
+                    'calc(- 1)',
+                    'calc(*)',
+                    'calc(*1)',
+                    'calc(* 2)',
+                    'calc(/)',
+                    'calc(/1)',
+                    'calc(/ 2)',
+                    'calc(1+)',
+                    'calc(1 +)',
+                    'calc(1 + )',
+                    'calc(2px -)',
+                    'calc(3px*)',
+                    'calc(3px *)',
+                    'calc(3px * )',
+                    'calc(4em/)',
+                    'calc(4em /)',
+                    'calc(4em / )',
+                    'calc(1 + + 1)',
+                    'calc(1 ++ 1)'
                     ]
         self.do_raise_r_list(tests, xml.dom.SyntaxErr)
 
@@ -321,22 +321,22 @@ class PropertyValueTestCase(basetest.BaseTestCase):
     def test_comments(self):
         "PropertyValue with comment"
         # issue #45
-        for t in (u'green',
-                  u'green /* comment */',
-                  u'/* comment */green',
-                  u'/* comment */green/* comment */',
-                  u'/* comment */  green  /* comment */',
-                  u'/* comment *//**/  green  /* comment *//**/',
+        for t in ('green',
+                  'green /* comment */',
+                  '/* comment */green',
+                  '/* comment */green/* comment */',
+                  '/* comment */  green  /* comment */',
+                  '/* comment *//**/  green  /* comment *//**/',
                   ):
             sheet = cssutils.parseString('body {color: %s; }' % t)
             p = sheet.cssRules[0].style.getProperties()[0]
             self.assertEqual(p.valid, True)
-        for t in (u'gree',
-                  u'gree /* comment */',
-                  u'/* comment */gree',
-                  u'/* comment */gree/* comment */',
-                  u'/* comment */  gree  /* comment */',
-                  u'/* comment *//**/  gree  /* comment *//**/',
+        for t in ('gree',
+                  'gree /* comment */',
+                  '/* comment */gree',
+                  '/* comment */gree/* comment */',
+                  '/* comment */  gree  /* comment */',
+                  '/* comment *//**/  gree  /* comment *//**/',
                   ):
             sheet = cssutils.parseString('body {color: %s; }' % t)
             p = sheet.cssRules[0].style.getProperties()[0]
@@ -345,10 +345,10 @@ class PropertyValueTestCase(basetest.BaseTestCase):
     def test_incomplete(self):
         "PropertyValue (incomplete)"
         tests = {
-            u'url("a': u'url(a)',
-            u'url(a': u'url(a)'
+            'url("a': 'url(a)',
+            'url(a': 'url(a)'
         }
-        for v, exp in tests.items():
+        for v, exp in list(tests.items()):
             s = cssutils.parseString('a { background: %s' % v)
             v = s.cssRules[0].style.background
             self.assertEqual(v, exp)
@@ -360,9 +360,9 @@ class PropertyValueTestCase(basetest.BaseTestCase):
 
         v = cssutils.css.PropertyValue(cssText='inherit', readonly=True)
         self.assertTrue(True is v._readonly)
-        self.assertTrue(u'inherit', v.cssText)
-        self.assertRaises(xml.dom.NoModificationAllowedErr, v._setCssText, u'x')
-        self.assertTrue(u'inherit', v.cssText)
+        self.assertTrue('inherit', v.cssText)
+        self.assertRaises(xml.dom.NoModificationAllowedErr, v._setCssText, 'x')
+        self.assertTrue('inherit', v.cssText)
 
     def test_reprANDstr(self):
         "PropertyValue.__repr__(), .__str__()"
@@ -382,35 +382,35 @@ class ValueTestCase(basetest.BaseTestCase):
     def test_init(self):
         "Value.__init__()"
         v = cssutils.css.Value()
-        self.assertTrue(u'' == v.cssText)
-        self.assertTrue(u'' == v.value)
+        self.assertTrue('' == v.cssText)
+        self.assertTrue('' == v.value)
         self.assertTrue(None is  v.type)
 
     def test_cssText(self):
         "Value.cssText"
         # HASH IDENT STRING UNICODE-RANGE
         tests = {
-                 u'#123': (u'#123', u'#123', u'HASH'),
-                 u'#123456': (u'#123456', u'#123456', u'HASH'),
-                 u'#112233': (u'#123', u'#112233', u'HASH'),
-                 u'  #112233  ': (u'#123', u'#112233', u'HASH'),
-
-                 u'red': (u'red', u'red', u'IDENT'),
-                 u'  red  ': (u'red', u'red', u'IDENT'),
-                 u'red  ': (u'red', u'red', u'IDENT'),
-                 u'  red': (u'red', u'red', u'IDENT'),
-                 u'red-': (u'red-', u'red-', u'IDENT'),
-                 u'-red': (u'-red', u'-red', u'IDENT'),
-
-                 u'"red"': (u'"red"', u'red', u'STRING'),
-                 u"'red'": (u'"red"', u'red', u'STRING'),
-                 u'  "red"  ': (u'"red"', u'red', u'STRING'),
-                 ur'"red\""': (ur'"red\""', ur'red"', u'STRING'),
-                 ur"'x\"'": (ur'"x\\""', ur'x\"', 'STRING'), #???
-                 u'''"x\
-y"''': (u'"xy"', u'xy', u'STRING'),
+                 '#123': ('#123', '#123', 'HASH'),
+                 '#123456': ('#123456', '#123456', 'HASH'),
+                 '#112233': ('#123', '#112233', 'HASH'),
+                 '  #112233  ': ('#123', '#112233', 'HASH'),
+
+                 'red': ('red', 'red', 'IDENT'),
+                 '  red  ': ('red', 'red', 'IDENT'),
+                 'red  ': ('red', 'red', 'IDENT'),
+                 '  red': ('red', 'red', 'IDENT'),
+                 'red-': ('red-', 'red-', 'IDENT'),
+                 '-red': ('-red', '-red', 'IDENT'),
+
+                 '"red"': ('"red"', 'red', 'STRING'),
+                 "'red'": ('"red"', 'red', 'STRING'),
+                 '  "red"  ': ('"red"', 'red', 'STRING'),
+                 r'"red\""': (r'"red\""', r'red"', 'STRING'),
+                 r"'x\"'": (r'"x\\""', r'x\"', 'STRING'), #???
+                 '''"x\
+y"''': ('"xy"', 'xy', 'STRING'),
                  }
-        for (p, (r, n, t)) in tests.items():
+        for (p, (r, n, t)) in list(tests.items()):
             v = cssutils.css.Value(p)
             self.assertEqual(r, v.cssText)
             self.assertEqual(t, v.type)
@@ -423,30 +423,30 @@ class ColorValueTestCase(basetest.BaseTestCase):
         "ColorValue.__init__()"
         v = cssutils.css.ColorValue()
         self.assertEqual(v.COLOR_VALUE, v.type)
-        self.assertTrue(u'' == v.cssText)
-        self.assertTrue(u'' == v.value)
-        self.assertEqual(u'transparent', v.name)
+        self.assertTrue('' == v.cssText)
+        self.assertTrue('' == v.value)
+        self.assertEqual('transparent', v.name)
         self.assertEqual(None, v.colorType)
 
     def test_cssText(self):
         "ColorValue.cssText"
         tests = {
                  # HASH
-                 u'#123': (u'#123',),
-                 u'#112233': (u'#123',),
+                 '#123': ('#123',),
+                 '#112233': ('#123',),
                  # rgb
-                 u'rgb(1,2,3)': (u'rgb(1, 2, 3)',),
-                 u'rgb(1%,2%,3%)': (u'rgb(1%, 2%, 3%)',),
-                 u'rgb(-1,-1,-1)': (u'rgb(-1, -1, -1)',),
-                 u'rgb(-1%,-2%,-3%)': (u'rgb(-1%, -2%, -3%)',),
+                 'rgb(1,2,3)': ('rgb(1, 2, 3)',),
+                 'rgb(1%,2%,3%)': ('rgb(1%, 2%, 3%)',),
+                 'rgb(-1,-1,-1)': ('rgb(-1, -1, -1)',),
+                 'rgb(-1%,-2%,-3%)': ('rgb(-1%, -2%, -3%)',),
                  # rgba
-                 u'rgba(1,2,3, 0)': (u'rgba(1, 2, 3, 0)',),
+                 'rgba(1,2,3, 0)': ('rgba(1, 2, 3, 0)',),
                  # hsl
-                 u'hsl(1,2%,3%)': (u'hsl(1, 2%, 3%)',),
-                 u'hsla(1,2%,3%, 1.0)': (u'hsla(1, 2%, 3%, 1)',),
+                 'hsl(1,2%,3%)': ('hsl(1, 2%, 3%)',),
+                 'hsla(1,2%,3%, 1.0)': ('hsla(1, 2%, 3%, 1)',),
 
                  }
-        for (p, (r, )) in tests.items():
+        for (p, (r, )) in list(tests.items()):
             v = cssutils.css.ColorValue(p)
             self.assertEqual(v.COLOR_VALUE, v.type)
             self.assertEqual(r, v.cssText)
@@ -459,39 +459,39 @@ class ColorValueTestCase(basetest.BaseTestCase):
             self.assertEqual(r, v.value)
 
         tests = {
-             u'1': xml.dom.SyntaxErr,
-             u'a': xml.dom.SyntaxErr,
-
-             u'#12': xml.dom.SyntaxErr,
-             u'#1234': xml.dom.SyntaxErr,
-             u'#1234567': xml.dom.SyntaxErr,
-             u'#12345678': xml.dom.SyntaxErr,
-
-             u'rgb(1,1%,1%)': xml.dom.SyntaxErr,
-             u'rgb(1%,1,1)': xml.dom.SyntaxErr,
-             u'rgb(-1,-1%,-1%)': xml.dom.SyntaxErr,
-             u'rgb(-1%,-1,-1)': xml.dom.SyntaxErr,
-
-             u'rgb(1,1,1, 0)': xml.dom.SyntaxErr,
-             u'rgb(1%,1%,1%, 0)': xml.dom.SyntaxErr,
-             u'rgba(1,1,1)': xml.dom.SyntaxErr,
-             u'rgba(1%,1%,1%)': xml.dom.SyntaxErr,
-             u'rgba(1,1,1, 0%)': xml.dom.SyntaxErr,
-             u'rgba(1%,1%,1%, 0%)': xml.dom.SyntaxErr,
-
-             u'hsl(1,2%,3%, 1)': xml.dom.SyntaxErr,
-             u'hsla(1,2%,3%)': xml.dom.SyntaxErr,
-
-             u'hsl(1,2,3)': xml.dom.SyntaxErr,
-             u'hsl(1%,2,3)': xml.dom.SyntaxErr,
-             u'hsl(1%,2,3%)': xml.dom.SyntaxErr,
-             u'hsl(1%,2%,3)': xml.dom.SyntaxErr,
-
-             u'hsla(1,2%,3%, 0%)': xml.dom.SyntaxErr,
-             u'hsla(1,2,3, 0.0)': xml.dom.SyntaxErr,
-             u'hsla(1%,2,3, 0.0)': xml.dom.SyntaxErr,
-             u'hsla(1%,2,3%, 0.0)': xml.dom.SyntaxErr,
-             u'hsla(1%,2%,3, 0.0)': xml.dom.SyntaxErr,
+             '1': xml.dom.SyntaxErr,
+             'a': xml.dom.SyntaxErr,
+
+             '#12': xml.dom.SyntaxErr,
+             '#1234': xml.dom.SyntaxErr,
+             '#1234567': xml.dom.SyntaxErr,
+             '#12345678': xml.dom.SyntaxErr,
+
+             'rgb(1,1%,1%)': xml.dom.SyntaxErr,
+             'rgb(1%,1,1)': xml.dom.SyntaxErr,
+             'rgb(-1,-1%,-1%)': xml.dom.SyntaxErr,
+             'rgb(-1%,-1,-1)': xml.dom.SyntaxErr,
+
+             'rgb(1,1,1, 0)': xml.dom.SyntaxErr,
+             'rgb(1%,1%,1%, 0)': xml.dom.SyntaxErr,
+             'rgba(1,1,1)': xml.dom.SyntaxErr,
+             'rgba(1%,1%,1%)': xml.dom.SyntaxErr,
+             'rgba(1,1,1, 0%)': xml.dom.SyntaxErr,
+             'rgba(1%,1%,1%, 0%)': xml.dom.SyntaxErr,
+
+             'hsl(1,2%,3%, 1)': xml.dom.SyntaxErr,
+             'hsla(1,2%,3%)': xml.dom.SyntaxErr,
+
+             'hsl(1,2,3)': xml.dom.SyntaxErr,
+             'hsl(1%,2,3)': xml.dom.SyntaxErr,
+             'hsl(1%,2,3%)': xml.dom.SyntaxErr,
+             'hsl(1%,2%,3)': xml.dom.SyntaxErr,
+
+             'hsla(1,2%,3%, 0%)': xml.dom.SyntaxErr,
+             'hsla(1,2,3, 0.0)': xml.dom.SyntaxErr,
+             'hsla(1%,2,3, 0.0)': xml.dom.SyntaxErr,
+             'hsla(1%,2,3%, 0.0)': xml.dom.SyntaxErr,
+             'hsla(1%,2%,3, 0.0)': xml.dom.SyntaxErr,
         }
         self.r = cssutils.css.ColorValue()
         self.do_raise_r(tests)
@@ -499,22 +499,22 @@ class ColorValueTestCase(basetest.BaseTestCase):
     def test_rgb(self):
         "ColorValue.red .green .blue"
         tests = {
-            (u'#0A0AD2', 'rgb(10, 10, 210)' ): (10, 10, 210, 1.0),
+            ('#0A0AD2', 'rgb(10, 10, 210)' ): (10, 10, 210, 1.0),
             # TODO: Fix rounding?
-            (u'hsl(240, 91%, 43%)', ): (10, 10, 209, 1.0),
-            (u'#ff8800', u'#f80',
+            ('hsl(240, 91%, 43%)', ): (10, 10, 209, 1.0),
+            ('#ff8800', '#f80',
              'rgb(255, 136, 0)', 'rgba(255, 136, 0, 1.0)'): (255, 136, 0, 1.0),
-            (u'red', u'#ff0000', u'#f00',
-             u'hsl(0, 100%, 50%)', u'hsla(0, 100%, 50%, 1.0)'):
+            ('red', '#ff0000', '#f00',
+             'hsl(0, 100%, 50%)', 'hsla(0, 100%, 50%, 1.0)'):
                 (255, 0, 0, 1.0),
-            (u'lime', u'#00ff00', u'#0f0', u'hsl(120, 100%, 50%)'):
+            ('lime', '#00ff00', '#0f0', 'hsl(120, 100%, 50%)'):
                 (0, 255, 0, 1.0),
-            (u'rgba(255, 127, 0, .1)', u'rgba(100%, 50%, 0%, .1)'):
+            ('rgba(255, 127, 0, .1)', 'rgba(100%, 50%, 0%, .1)'):
                 (255, 127, 0, 0.1),
-            (u'transparent', u'rgba(0, 0, 0, 0)'): (0, 0, 0, 0),
-            (u'aqua',): (0, 255, 255, 1.0)
+            ('transparent', 'rgba(0, 0, 0, 0)'): (0, 0, 0, 0),
+            ('aqua',): (0, 255, 255, 1.0)
         }
-        for colors, rgba in tests.items():
+        for colors, rgba in list(tests.items()):
             for color in colors:
                 c = cssutils.css.ColorValue(color);
                 self.assertEqual(c.red, rgba[0])
@@ -528,46 +528,46 @@ class URIValueTestCase(basetest.BaseTestCase):
     def test_init(self):
         "URIValue.__init__()"
         v = cssutils.css.URIValue()
-        self.assertTrue(u'url()' == v.cssText)
-        self.assertTrue(u'' == v.value)
-        self.assertTrue(u'' == v.uri)
+        self.assertTrue('url()' == v.cssText)
+        self.assertTrue('' == v.value)
+        self.assertTrue('' == v.uri)
         self.assertTrue(v.URI is  v.type)
 
         v.uri = '1'
-        self.assertTrue(u'1' == v.value)
-        self.assertTrue(u'1' == v.uri)
-        self.assertEqual(u'url(1)', v.cssText)
+        self.assertTrue('1' == v.value)
+        self.assertTrue('1' == v.uri)
+        self.assertEqual('url(1)', v.cssText)
 
         v.value = '2'
-        self.assertTrue(u'2' == v.value)
-        self.assertTrue(u'2' == v.uri)
-        self.assertEqual(u'url(2)', v.cssText)
+        self.assertTrue('2' == v.value)
+        self.assertTrue('2' == v.uri)
+        self.assertEqual('url(2)', v.cssText)
 
     def test_absoluteUri(self):
         "URIValue.absoluteUri"
         s = cssutils.parseString('a { background-image: url(x.gif)}', href="/path/to/x.css")
         v = s.cssRules[0].style.getProperty('background-image').propertyValue[0]
-        self.assertEqual(u'x.gif', v.uri)
-        self.assertEqual(u'/path/to/x.gif', v.absoluteUri)
+        self.assertEqual('x.gif', v.uri)
+        self.assertEqual('/path/to/x.gif', v.absoluteUri)
 
-        v = cssutils.css.URIValue(u'url(x.gif)')
-        self.assertEqual(u'x.gif', v.uri)
-        self.assertEqual(u'x.gif', v.absoluteUri)
+        v = cssutils.css.URIValue('url(x.gif)')
+        self.assertEqual('x.gif', v.uri)
+        self.assertEqual('x.gif', v.absoluteUri)
 
     def test_cssText(self):
         "URIValue.cssText"
         tests = {
-                 u'url()': (u'url()', u'', u'URI'),
+                 'url()': ('url()', '', 'URI'),
                  # comments are part of the url!
-                 u'url(/**/)': (u'url(/**/)', u'/**/', u'URI'),
-                 u'url(/**/1)': (u'url(/**/1)', u'/**/1', u'URI'),
-                 u'url(1/**/)': (u'url(1/**/)', u'1/**/', u'URI'),
-                 u'url(/**/1/**/)': (u'url(/**/1/**/)', u'/**/1/**/', u'URI'),
-                 u'url(some.gif)': (u'url(some.gif)', u'some.gif', u'URI'),
-                 u'  url(some.gif)  ': (u'url(some.gif)', u'some.gif', u'URI'),
-                 u'url(   some.gif  )': (u'url(some.gif)', u'some.gif', u'URI'),
+                 'url(/**/)': ('url(/**/)', '/**/', 'URI'),
+                 'url(/**/1)': ('url(/**/1)', '/**/1', 'URI'),
+                 'url(1/**/)': ('url(1/**/)', '1/**/', 'URI'),
+                 'url(/**/1/**/)': ('url(/**/1/**/)', '/**/1/**/', 'URI'),
+                 'url(some.gif)': ('url(some.gif)', 'some.gif', 'URI'),
+                 '  url(some.gif)  ': ('url(some.gif)', 'some.gif', 'URI'),
+                 'url(   some.gif  )': ('url(some.gif)', 'some.gif', 'URI'),
                  }
-        for (p, (r, n, t)) in tests.items():
+        for (p, (r, n, t)) in list(tests.items()):
             v = cssutils.css.URIValue(p)
             self.assertEqual(r, v.cssText)
             self.assertEqual(t, v.type)
@@ -582,11 +582,11 @@ class URIValueTestCase(basetest.BaseTestCase):
             self.assertEqual(n, v.uri)
 
         tests = {
-             u'a()': xml.dom.SyntaxErr,
-             u'1': xml.dom.SyntaxErr,
-             u'url(': xml.dom.SyntaxErr,
-             u'url("': xml.dom.SyntaxErr,
-             u'url(\'': xml.dom.SyntaxErr,
+             'a()': xml.dom.SyntaxErr,
+             '1': xml.dom.SyntaxErr,
+             'url(': xml.dom.SyntaxErr,
+             'url("': xml.dom.SyntaxErr,
+             'url(\'': xml.dom.SyntaxErr,
              }
         self.r = cssutils.css.URIValue()
         self.do_raise_r(tests)
@@ -596,8 +596,8 @@ class DimensionValueTestCase(basetest.BaseTestCase):
     def test_init(self):
         "DimensionValue.__init__()"
         v = cssutils.css.DimensionValue()
-        self.assertTrue(u'' == v.cssText)
-        self.assertTrue(u'' == v.value)
+        self.assertTrue('' == v.cssText)
+        self.assertTrue('' == v.value)
         self.assertTrue(None is  v.type)
         self.assertTrue(None is  v.dimension)
 
@@ -606,47 +606,47 @@ class DimensionValueTestCase(basetest.BaseTestCase):
         # NUMBER DIMENSION PERCENTAGE
         tests = {
 
-                 u'0': (u'0', 0, None, u'NUMBER'),
-                 u'00': (u'0', 0, None, u'NUMBER'),
-                 u'.0': (u'0', 0, None, u'NUMBER'),
-                 u'0.0': (u'0', 0, None, u'NUMBER'),
-                 u'+0': (u'0', 0, None, u'NUMBER'),
-                 u'+00': (u'0', 0, None, u'NUMBER'),
-                 u'+.0': (u'0', 0, None, u'NUMBER'),
-                 u'+0.0': (u'0', 0, None, u'NUMBER'),
-                 u'-0': (u'0', 0, None, u'NUMBER'),
-                 u'-00': (u'0', 0, None, u'NUMBER'),
-                 u'-.0': (u'0', 0, None, u'NUMBER'),
-                 u'-0.0': (u'0', 0, None, u'NUMBER'),
-
-                 u'1': (u'1', 1, None, u'NUMBER'),
-                 u'1.0': (u'1', 1.0, None, u'NUMBER'),
-                 u'1.1': (u'1.1', 1.1, None, u'NUMBER'),
-                 u'+1': (u'+1', 1, None, u'NUMBER'),
-                 u'+1.0': (u'+1', 1.0, None, u'NUMBER'),
-                 u'+1.1': (u'+1.1', 1.1, None, u'NUMBER'),
-                 u'-1': (u'-1', -1, None, u'NUMBER'),
-                 u'-1.0': (u'-1', -1, None, u'NUMBER'),
-                 u'-1.1': (u'-1.1', -1.1, None, u'NUMBER'),
-
-                 u'0px': (u'0', 0, u'px', u'DIMENSION'),
-                 u'1px': (u'1px', 1, u'px', u'DIMENSION'),
-                 u'1.0px': (u'1px', 1.0, u'px', u'DIMENSION'),
-                 u'1.1px': (u'1.1px', 1.1, u'px', u'DIMENSION'),
-                 u'-1px': (u'-1px', -1, u'px', u'DIMENSION'),
-                 u'-1.1px': (u'-1.1px', -1.1, u'px', u'DIMENSION'),
-                 u'+1px': (u'+1px', 1, u'px', u'DIMENSION'),
-
-                 u'1px1': (u'1px1', 1, u'px1', u'DIMENSION'),
-
-                 u'0%': (u'0%', 0, u'%', u'PERCENTAGE'),
-                 u'1%': (u'1%', 1, u'%', u'PERCENTAGE'),
-                 u'1.1%': (u'1.1%', 1.1, u'%', u'PERCENTAGE'),
-                 u'-1%': (u'-1%', -1, u'%', u'PERCENTAGE'),
-                 u'-1.1%': (u'-1.1%', -1.1, u'%', u'PERCENTAGE'),
-                 u'+1%': (u'+1%', 1, u'%', u'PERCENTAGE'),
+                 '0': ('0', 0, None, 'NUMBER'),
+                 '00': ('0', 0, None, 'NUMBER'),
+                 '.0': ('0', 0, None, 'NUMBER'),
+                 '0.0': ('0', 0, None, 'NUMBER'),
+                 '+0': ('0', 0, None, 'NUMBER'),
+                 '+00': ('0', 0, None, 'NUMBER'),
+                 '+.0': ('0', 0, None, 'NUMBER'),
+                 '+0.0': ('0', 0, None, 'NUMBER'),
+                 '-0': ('0', 0, None, 'NUMBER'),
+                 '-00': ('0', 0, None, 'NUMBER'),
+                 '-.0': ('0', 0, None, 'NUMBER'),
+                 '-0.0': ('0', 0, None, 'NUMBER'),
+
+                 '1': ('1', 1, None, 'NUMBER'),
+                 '1.0': ('1', 1.0, None, 'NUMBER'),
+                 '1.1': ('1.1', 1.1, None, 'NUMBER'),
+                 '+1': ('+1', 1, None, 'NUMBER'),
+                 '+1.0': ('+1', 1.0, None, 'NUMBER'),
+                 '+1.1': ('+1.1', 1.1, None, 'NUMBER'),
+                 '-1': ('-1', -1, None, 'NUMBER'),
+                 '-1.0': ('-1', -1, None, 'NUMBER'),
+                 '-1.1': ('-1.1', -1.1, None, 'NUMBER'),
+
+                 '0px': ('0', 0, 'px', 'DIMENSION'),
+                 '1px': ('1px', 1, 'px', 'DIMENSION'),
+                 '1.0px': ('1px', 1.0, 'px', 'DIMENSION'),
+                 '1.1px': ('1.1px', 1.1, 'px', 'DIMENSION'),
+                 '-1px': ('-1px', -1, 'px', 'DIMENSION'),
+                 '-1.1px': ('-1.1px', -1.1, 'px', 'DIMENSION'),
+                 '+1px': ('+1px', 1, 'px', 'DIMENSION'),
+
+                 '1px1': ('1px1', 1, 'px1', 'DIMENSION'),
+
+                 '0%': ('0%', 0, '%', 'PERCENTAGE'),
+                 '1%': ('1%', 1, '%', 'PERCENTAGE'),
+                 '1.1%': ('1.1%', 1.1, '%', 'PERCENTAGE'),
+                 '-1%': ('-1%', -1, '%', 'PERCENTAGE'),
+                 '-1.1%': ('-1.1%', -1.1, '%', 'PERCENTAGE'),
+                 '+1%': ('+1%', 1, '%', 'PERCENTAGE'),
                  }
-        for (p, (r, n, d, t)) in tests.items():
+        for (p, (r, n, d, t)) in list(tests.items()):
             v = cssutils.css.DimensionValue(p)
             self.assertEqual(r, v.cssText)
             self.assertEqual(t, v.type)
@@ -659,23 +659,23 @@ class CSSFunctionTestCase(basetest.BaseTestCase):
     def test_init(self):
         "CSSFunction.__init__()"
         v = cssutils.css.CSSFunction()
-        self.assertEqual(u'', v.cssText)
-        self.assertEqual(u'FUNCTION', v.type)
-        self.assertEqual(v.value, u'')
+        self.assertEqual('', v.cssText)
+        self.assertEqual('FUNCTION', v.type)
+        self.assertEqual(v.value, '')
 
     def test_cssText(self):
         "CSSFunction.cssText"
         tests = {
-                 u'x(x)': (u'x(x)', None),
-                 u'X(  X  )': (u'x(X)', None),
-                 u'x(1,2)': (u'x(1, 2)', None),
-                 u'x(1/**/)': (u'x(1 /**/)', u'x(1)'),
-                 u'x(/**/1)': (u'x(/**/ 1)', u'x(1)'),
-                 u'x(/**/1/**/)': (u'x(/**/ 1 /**/)', u'x(1)'),
-                 u'x(/**/1,x/**/)': (u'x(/**/ 1, x /**/)', u'x(1, x)'),
-                 u'x(1,2)': (u'x(1, 2)', None),
+                 'x(x)': ('x(x)', None),
+                 'X(  X  )': ('x(X)', None),
+                 'x(1,2)': ('x(1, 2)', None),
+                 'x(1/**/)': ('x(1 /**/)', 'x(1)'),
+                 'x(/**/1)': ('x(/**/ 1)', 'x(1)'),
+                 'x(/**/1/**/)': ('x(/**/ 1 /**/)', 'x(1)'),
+                 'x(/**/1,x/**/)': ('x(/**/ 1, x /**/)', 'x(1, x)'),
+                 'x(1,2)': ('x(1, 2)', None),
                  }
-        for (f, (cssText, value)) in tests.items():
+        for (f, (cssText, value)) in list(tests.items()):
             if value is None:
                 value = cssText
             v = cssutils.css.CSSFunction(f)
@@ -689,24 +689,24 @@ class CSSVariableTestCase(basetest.BaseTestCase):
     def test_init(self):
         "CSSVariable.__init__()"
         v = cssutils.css.CSSVariable()
-        self.assertEqual(u'', v.cssText)
-        self.assertEqual(u'VARIABLE', v.type)
+        self.assertEqual('', v.cssText)
+        self.assertEqual('VARIABLE', v.type)
         self.assertTrue(None is v.name)
         self.assertTrue(None is v.value)
 
     def test_cssText(self):
         "CSSVariable.cssText"
         tests = {
-                 u'var(x)': (u'var(x)', u'x', None),
-                 u'VAR(  X  )': (u'var(X)', u'X', None),
-                 u'var(c1,rgb(14,14,14))': (u'var(c1, rgb(14, 14, 14))', u'c1', u'rgb(14, 14, 14)'),
-                 u'var( L, 1px )': (u'var(L, 1px)', u'L', u'1px'),
-                 u'var(L,1)': (u'var(L, 1)', u'L', u'1'),
-                 u'var(T, calc( 2 * 1px ))': (u'var(T, calc(2 * 1px))', u'T', 'calc(2 * 1px)'),
-                 u'var(U, url( example.png ) )': (u'var(U, url(example.png))', u'U', u'url(example.png)'),
-                 u'var(C, #f00 )': (u'var(C, #f00)', u'C', '#fff')
+                 'var(x)': ('var(x)', 'x', None),
+                 'VAR(  X  )': ('var(X)', 'X', None),
+                 'var(c1,rgb(14,14,14))': ('var(c1, rgb(14, 14, 14))', 'c1', 'rgb(14, 14, 14)'),
+                 'var( L, 1px )': ('var(L, 1px)', 'L', '1px'),
+                 'var(L,1)': ('var(L, 1)', 'L', '1'),
+                 'var(T, calc( 2 * 1px ))': ('var(T, calc(2 * 1px))', 'T', 'calc(2 * 1px)'),
+                 'var(U, url( example.png ) )': ('var(U, url(example.png))', 'U', 'url(example.png)'),
+                 'var(C, #f00 )': ('var(C, #f00)', 'C', '#fff')
                  }
-        for (var, (cssText, name, fallback)) in tests.items():
+        for (var, (cssText, name, fallback)) in list(tests.items()):
             v = cssutils.css.CSSVariable(var)
             self.assertEqual(cssText, v.cssText)
             self.assertEqual('VARIABLE', v.type)
diff --git a/src/cssutils/tests/test_x.py b/src/cssutils/tests/test_x.py
index eccbed5..d8227fa 100644
--- a/src/cssutils/tests/test_x.py
+++ b/src/cssutils/tests/test_x.py
@@ -3,7 +3,7 @@ __version__ = '$Id: test_cssvalue.py 1473 2008-09-15 21:15:54Z cthedot $'
 
 # from decimal import Decimal # maybe for later tests?
 import xml.dom
-import basetest
+from . import basetest
 import cssutils
 import types
 
@@ -17,8 +17,8 @@ class XTestCase(basetest.BaseTestCase):
         
     def test_prioriy(self):
         "Property.priority"
-        s = cssutils.parseString(u'a { color: red }')
-        self.assertEqual(s.cssText, u'a {\n    color: red\n    }'.encode())
+        s = cssutils.parseString('a { color: red }')
+        self.assertEqual(s.cssText, 'a {\n    color: red\n    }'.encode())
 #        self.assertEqual(u'', s.cssRules[0].style.getPropertyPriority('color'))
 #
 #        s = cssutils.parseString('a { color: red !important }')
diff --git a/src/cssutils/tokenize2.py b/src/cssutils/tokenize2.py
index 5941512..f9bc616 100644
--- a/src/cssutils/tokenize2.py
+++ b/src/cssutils/tokenize2.py
@@ -6,8 +6,8 @@ __all__ = ['Tokenizer', 'CSSProductions']
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from cssproductions import *
-from helper import normalize
+from .cssproductions import *
+from .helper import normalize
 import itertools
 import re
 import sys
@@ -20,14 +20,14 @@ class Tokenizer(object):
         (Tokenname, value, startline, startcolumn)
     """
     _atkeywords = {
-        u'@font-face': CSSProductions.FONT_FACE_SYM,
-        u'@import': CSSProductions.IMPORT_SYM,
-        u'@media': CSSProductions.MEDIA_SYM,
-        u'@namespace': CSSProductions.NAMESPACE_SYM,
-        u'@page': CSSProductions.PAGE_SYM,
-        u'@variables': CSSProductions.VARIABLES_SYM
+        '@font-face': CSSProductions.FONT_FACE_SYM,
+        '@import': CSSProductions.IMPORT_SYM,
+        '@media': CSSProductions.MEDIA_SYM,
+        '@namespace': CSSProductions.NAMESPACE_SYM,
+        '@page': CSSProductions.PAGE_SYM,
+        '@variables': CSSProductions.VARIABLES_SYM
         }
-    _linesep = u'\n'
+    _linesep = '\n'
     unicodesub = re.compile(r'\\[0-9a-fA-F]{1,6}(?:\r\n|[\t\r\n\f\x20])?').sub
     cleanstring = re.compile(r'\\((\r\n)|[\n\r\f])').sub
 
@@ -108,7 +108,7 @@ class Tokenizer(object):
             "used by unicodesub"
             num = int(m.group(0)[1:], 16)
             if num <= sys.maxunicode:
-                return unichr(num)
+                return chr(num)
             else:
                 return m.group(0)
 
@@ -146,7 +146,7 @@ class Tokenizer(object):
 
             # speed test for most used CHARs, sadly . not possible :(
             c = text[pos]
-            if c in u',:;{}>[]': # + but in num!
+            if c in ',:;{}>[]': # + but in num!
                 yield ('CHAR', c, line, col)
                 col += 1
                 pos += 1
@@ -157,9 +157,9 @@ class Tokenizer(object):
 
                     # TODO: USE bad comment?
                     if (fullsheet and name == 'CHAR' and
-                          has_at(text, pos, u'/*')):
+                          has_at(text, pos, '/*')):
                         # before CHAR production test for incomplete comment
-                        possiblecomment = u'%s*/' % text[pos:]
+                        possiblecomment = '%s*/' % text[pos:]
                         match = self.commentmatcher(possiblecomment)
                         if match and self._doComments:
                             yield ('COMMENT', possiblecomment, line, col)
@@ -190,10 +190,10 @@ class Tokenizer(object):
                                 name, found = 'STRING', '%s%s' % (found, found[0])
 
                             elif 'FUNCTION' == name and\
-                                 u'url(' == _normalize(found):
+                                 'url(' == _normalize(found):
                                 # url( is a FUNCTION if incomplete sheet
                                 # FUNCTION production MUST BE after URI production
-                                for end in (u"')", u'")', u')'):
+                                for end in ("')", '")', ')'):
                                     possibleuri = '%s%s' % (text[pos:], end)
                                     match = self.urimatcher(possibleuri)
                                     if match:
@@ -215,13 +215,13 @@ class Tokenizer(object):
                                 try:
                                     # get actual ATKEYWORD SYM
                                     name = self._atkeywords[_normalize(found)]
-                                except KeyError, e:
+                                except KeyError as e:
                                     # might also be misplace @charset...
                                     if ('@charset' == found and
-                                          has_at(text, pos + len(found), u' ')):
+                                          has_at(text, pos + len(found), ' ')):
                                         # @charset needs tailing S!
                                         name = CSSProductions.CHARSET_SYM
-                                        found += u' '
+                                        found += ' '
                                     else:
                                         name = 'ATKEYWORD'
 
@@ -244,7 +244,7 @@ class Tokenizer(object):
             assert text is _orig_text
 
         if fullsheet:
-            yield ('EOF', u'', line, col)
+            yield ('EOF', '', line, col)
 
 
 def has_at(text, pos, string):
diff --git a/src/cssutils/util.py b/src/cssutils/util.py
index 0d06d58..7c6f09d 100644
--- a/src/cssutils/util.py
+++ b/src/cssutils/util.py
@@ -4,21 +4,21 @@ __all__ = []
 __docformat__ = 'restructuredtext'
 __version__ = '$Id$'
 
-from helper import normalize
-from itertools import ifilter, chain
+from .helper import normalize
+from itertools import chain
 import cssutils
-import codec
+from . import codec
 import codecs
-import errorhandler
-import tokenize2
+from . import errorhandler
+from . import tokenize2
 import types
 import xml.dom
 import re
 
 try:
-    from _fetchgae import _defaultFetcher
-except ImportError, e:
-    from _fetch import _defaultFetcher
+    from ._fetchgae import _defaultFetcher
+except ImportError as e:
+    from ._fetch import _defaultFetcher
 
 log = errorhandler.ErrorHandler()
 
@@ -35,7 +35,7 @@ class _BaseClass(object):
         "Raise xml.dom.NoModificationAllowedErr if rule/... is readonly"
         if hasattr(self, '_readonly') and self._readonly:
             raise xml.dom.NoModificationAllowedErr(
-                u'%s is readonly.' % self.__class__)
+                '%s is readonly.' % self.__class__)
             return True
         return False
 
@@ -46,11 +46,11 @@ class _BaseClass(object):
         Mainly used to get a string value of t for error messages.
         """
         if not t:
-            return u''
-        elif isinstance(t, basestring):
+            return ''
+        elif isinstance(t, str):
             return t
         else:
-            return u''.join([x[1] for x in t])
+            return ''.join([x[1] for x in t])
 
 
 class _NewBase(_BaseClass):
@@ -144,23 +144,23 @@ class Base(_BaseClass):
     # http://www.dustindiaz.com/css-shorthand/
     # format: shorthand: [(propname, mandatorycheck?)*]
     _SHORTHANDPROPERTIES = {
-            u'background': [],
+            'background': [],
             #u'background-position': [], # list of 2 values!
-            u'border': [],
-            u'border-left': [],
-            u'border-right': [],
-            u'border-top': [],
-            u'border-bottom': [],
+            'border': [],
+            'border-left': [],
+            'border-right': [],
+            'border-top': [],
+            'border-bottom': [],
             #u'border-color': [], # list or single but same values
             #u'border-style': [], # list or single but same values
             #u'border-width': [], # list or single but same values
-            u'cue': [],
-            u'font': [],
-            u'list-style': [],
+            'cue': [],
+            'font': [],
+            'list-style': [],
             #u'margin': [], # list or single but same values
-            u'outline': [],
+            'outline': [],
             #u'padding': [], # list or single but same values
-            u'pause': []
+            'pause': []
             }
 
     @staticmethod
@@ -196,7 +196,7 @@ class Base(_BaseClass):
         """
         if not textortokens:
             return None
-        elif isinstance(textortokens, basestring):
+        elif isinstance(textortokens, str):
             # needs to be tokenized
             return self.__tokenizer2.tokenize(
                  textortokens)
@@ -210,7 +210,7 @@ class Base(_BaseClass):
     def _nexttoken(self, tokenizer, default=None):
         "returns next token in generator tokenizer or the default value"
         try:
-            return tokenizer.next()
+            return next(tokenizer)
         # TypeError for py3
         except (StopIteration, AttributeError, TypeError):
             return default
@@ -283,56 +283,56 @@ class Base(_BaseClass):
 
         default looks for ending "}" and ";"
         """
-        ends = u';}'
+        ends = ';}'
         endtypes = ()
         brace = bracket = parant = 0 # {}, [], ()
 
         if blockstartonly: # {
-            ends = u'{'
+            ends = '{'
             brace = - 1 # set to 0 with first {
         elif blockendonly: # }
-            ends = u'}'
+            ends = '}'
             brace = 1
         elif mediaendonly: # }
-            ends = u'}'
+            ends = '}'
             brace = 1 # rules } and mediarules }
         elif importmediaqueryendonly:
             # end of mediaquery which may be ; or STRING
-            ends = u';'
+            ends = ';'
             endtypes = ('STRING',)
         elif mediaqueryendonly:
             # end of mediaquery which may be { or STRING
             # special case, see below
-            ends = u'{'
+            ends = '{'
             brace = - 1 # set to 0 with first {
             endtypes = ('STRING',)
         elif semicolon:
-            ends = u';'
+            ends = ';'
         elif propertynameendonly: # : and ; in case of an error
-            ends = u':;'
+            ends = ':;'
         elif propertyvalueendonly: # ; or !important
-            ends = u';!'
+            ends = ';!'
         elif propertypriorityendonly: # ;
-            ends = u';'
+            ends = ';'
         elif selectorattendonly: # ]
-            ends = u']'
-            if starttoken and self._tokenvalue(starttoken) == u'[':
+            ends = ']'
+            if starttoken and self._tokenvalue(starttoken) == '[':
                 bracket = 1
         elif funcendonly: # )
-            ends = u')'
+            ends = ')'
             parant = 1
         elif listseponly: # ,
-            ends = u','
+            ends = ','
 
         resulttokens = []
         if starttoken:
             resulttokens.append(starttoken)
             val = starttoken[1]
-            if u'[' == val:
+            if '[' == val:
                 bracket += 1
-            elif u'{' == val:
+            elif '{' == val:
                 brace += 1
-            elif u'(' == val:
+            elif '(' == val:
                 parant += 1
 
         if tokenizer:
@@ -342,19 +342,19 @@ class Base(_BaseClass):
                     resulttokens.append(token)
                     break
 
-                if u'{' == val:
+                if '{' == val:
                     brace += 1
-                elif u'}' == val:
+                elif '}' == val:
                     brace -= 1
-                elif u'[' == val:
+                elif '[' == val:
                     bracket += 1
-                elif u']' == val:
+                elif ']' == val:
                     bracket -= 1
                 # function( or single (
-                elif u'(' == val or \
+                elif '(' == val or \
                      Base._prods.FUNCTION == typ:
                     parant += 1
-                elif u')' == val:
+                elif ')' == val:
                     parant -= 1
 
                 resulttokens.append(token)
@@ -396,7 +396,7 @@ class Base(_BaseClass):
                 return expected
             else:
                 new['wellformed'] = False
-                self._log.error(u'Expected EOF.', token=token)
+                self._log.error('Expected EOF.', token=token)
                 return expected
 
         def COMMENT(expected, seq, token, tokenizer=None):
@@ -465,7 +465,7 @@ class Base(_BaseClass):
                     expected = p(expected, seq, token, tokenizer)
                 else:
                     wellformed = False
-                    self._log.error(u'Unexpected token (%s, %s, %s, %s)' % token)
+                    self._log.error('Unexpected token (%s, %s, %s, %s)' % token)
         return wellformed, expected
 
 
@@ -500,14 +500,14 @@ class Base2(Base, _NewBase):
                 return expected
             else:
                 new['wellformed'] = False
-                self._log.error(u'Expected EOF.', token=token)
+                self._log.error('Expected EOF.', token=token)
                 return expected
 
         def COMMENT(expected, seq, token, tokenizer=None):
             "default impl, adds CSSCommentRule if not token == EOF"
             if expected == 'EOF':
                 new['wellformed'] = False
-                self._log.error(u'Expected EOF but found comment.', token=token)
+                self._log.error('Expected EOF but found comment.', token=token)
             seq.append(cssutils.css.CSSComment([token]), 'COMMENT')
             return expected
 
@@ -515,7 +515,7 @@ class Base2(Base, _NewBase):
             "default impl, does nothing if not token == EOF"
             if expected == 'EOF':
                 new['wellformed'] = False
-                self._log.error(u'Expected EOF but found whitespace.', token=token)
+                self._log.error('Expected EOF but found whitespace.', token=token)
             return expected
 
         def EOF(expected=None, seq=None, token=None, tokenizer=None):
@@ -549,15 +549,15 @@ class Seq(object):
 
     def __repr__(self):
         "returns a repr same as a list of tuples of (value, type)"
-        return u'cssutils.%s.%s([\n    %s], readonly=%r)' % (self.__module__,
+        return 'cssutils.%s.%s([\n    %s], readonly=%r)' % (self.__module__,
                                           self.__class__.__name__,
-            u',\n    '.join([u'%r' % item for item in self._seq]
+            ',\n    '.join(['%r' % item for item in self._seq]
             ), self._readonly)
 
     def __str__(self):
         vals = []
         for v in self:
-            if isinstance(v.value, basestring):
+            if isinstance(v.value, str):
                 vals.append(v.value)
             elif isinstance(v, tuple):
                 vals.append(v.value[1])
@@ -574,7 +574,8 @@ class Seq(object):
     def __getitem__(self, i):
         return self._seq[i]
 
-    def __setitem__(self, i, (val, typ, line, col)):
+    def __setitem__(self, i, xxx_todo_changeme):
+        (val, typ, line, col) = xxx_todo_changeme
         self._seq[i] = Item(val, typ, line, col)
 
     def __iter__(self):
@@ -745,9 +746,9 @@ class _Namespaces(object):
         prefix '' and None are handled the same
         """
         if not prefix:
-            prefix = u''
+            prefix = ''
         delrule = self.__findrule(prefix)
-        for i, rule in enumerate(ifilter(lambda r: r.type == r.NAMESPACE_RULE,
+        for i, rule in enumerate(filter(lambda r: r.type == r.NAMESPACE_RULE,
                             self.parentStyleSheet.cssRules)):
             if rule == delrule:
                 self.parentStyleSheet.deleteRule(i)
@@ -759,7 +760,7 @@ class _Namespaces(object):
     def __getitem__(self, prefix):
         try:
             return self.namespaces[prefix]
-        except KeyError, e:
+        except KeyError as e:
             self._log.error('Prefix %s not found.' % prefix,
                             error=xml.dom.NamespaceErr)
 
@@ -772,7 +773,7 @@ class _Namespaces(object):
     def __setitem__(self, prefix, namespaceURI):
         "replaces prefix or sets new rule, may raise NoModificationAllowedErr"
         if not prefix:
-            prefix = u'' # None or ''
+            prefix = '' # None or ''
         rule = self.__findrule(prefix)
         if not rule:
             self.parentStyleSheet.insertRule(cssutils.css.CSSNamespaceRule(
@@ -782,12 +783,12 @@ class _Namespaces(object):
         else:
             if prefix in self.namespaces:
                 rule.namespaceURI = namespaceURI # raises NoModificationAllowedErr
-            if namespaceURI in self.namespaces.values():
+            if namespaceURI in list(self.namespaces.values()):
                 rule.prefix = prefix
 
     def __findrule(self, prefix):
         # returns namespace rule where prefix == key
-        for rule in ifilter(lambda r: r.type == r.NAMESPACE_RULE,
+        for rule in filter(lambda r: r.type == r.NAMESPACE_RULE,
                             reversed(self.parentStyleSheet.cssRules)):
             if rule.prefix == prefix:
                 return rule
@@ -799,9 +800,9 @@ class _Namespaces(object):
         self.parentStyleSheets.
         """
         namespaces = {}
-        for rule in ifilter(lambda r: r.type == r.NAMESPACE_RULE,
+        for rule in filter(lambda r: r.type == r.NAMESPACE_RULE,
                             reversed(self.parentStyleSheet.cssRules)):
-            if rule.namespaceURI not in namespaces.values():
+            if rule.namespaceURI not in list(namespaces.values()):
                 namespaces[rule.prefix] = rule.namespaceURI
         return namespaces
 
@@ -809,25 +810,25 @@ class _Namespaces(object):
         return self.namespaces.get(prefix, default)
 
     def items(self):
-        return self.namespaces.items()
+        return list(self.namespaces.items())
 
     def keys(self):
-        return self.namespaces.keys()
+        return list(self.namespaces.keys())
 
     def values(self):
-        return self.namespaces.values()
+        return list(self.namespaces.values())
 
     def prefixForNamespaceURI(self, namespaceURI):
         """
         returns effective prefix for given namespaceURI or raises IndexError
         if this cannot be found"""
-        for prefix, uri in self.namespaces.items():
+        for prefix, uri in list(self.namespaces.items()):
             if uri == namespaceURI:
                 return prefix
-        raise IndexError(u'NamespaceURI %s not found.' % namespaceURI)
+        raise IndexError('NamespaceURI %s not found.' % namespaceURI)
 
     def __str__(self):
-        return u"<cssutils.util.%s object parentStyleSheet=%r at 0x%x>" % (
+        return "<cssutils.util.%s object parentStyleSheet=%r at 0x%x>" % (
                 self.__class__.__name__, str(self.parentStyleSheet), id(self))
 
 
@@ -845,14 +846,14 @@ class _SimpleNamespaces(_Namespaces):
         self.__namespaces[prefix] = namespaceURI
 
     namespaces = property(lambda self: self.__namespaces,
-                          doc=u'Dict Wrapper for self.sheets @namespace rules.')
+                          doc='Dict Wrapper for self.sheets @namespace rules.')
 
     def __str__(self):
-        return u"<cssutils.util.%s object namespaces=%r at 0x%x>" % (
+        return "<cssutils.util.%s object namespaces=%r at 0x%x>" % (
                 self.__class__.__name__, self.namespaces, id(self))
 
     def __repr__(self):
-        return u"cssutils.util.%s(%r)" % (self.__class__.__name__,
+        return "cssutils.util.%s(%r)" % (self.__class__.__name__,
             self.namespaces)
 
 
@@ -904,7 +905,7 @@ def _readUrl(url, fetcher=None, overrideEncoding=None, parentEncoding=None):
             encoding = httpEncoding
         else:
             # BOM or @charset
-            if isinstance(content, unicode):
+            if isinstance(content, str):
                 contentEncoding, explicit = codec.detectencoding_unicode(content)
             else:
                 contentEncoding, explicit = codec.detectencoding_str(content)
@@ -922,18 +923,18 @@ def _readUrl(url, fetcher=None, overrideEncoding=None, parentEncoding=None):
                 enctype = 5 # 5. assume UTF-8
                 encoding = 'utf-8'
 
-        if isinstance(content, unicode):
+        if isinstance(content, str):
             decodedCssText = content
         else:
             try:
                 # encoding may still be wrong if encoding *is lying*!
                 try:
                     decodedCssText = codecs.lookup("css")[1](content, encoding=encoding)[0]
-                except AttributeError, ae:
+                except AttributeError as ae:
                     # at least in GAE
                     decodedCssText = content.decode(encoding if encoding else 'utf-8')
                     
-            except UnicodeDecodeError, e:
+            except UnicodeDecodeError as e:
                 log.warn(e, neverraise=True)
                 decodedCssText = None
 
diff --git a/src/encutils/__init__.py b/src/encutils/__init__.py
index ece6a53..b417ce0 100644
--- a/src/encutils/__init__.py
+++ b/src/encutils/__init__.py
@@ -77,27 +77,27 @@ __docformat__ = 'restructuredtext'
 __author__ = 'Christof Hoeke, Robert Siemer, Fredrik Hedman'
 __version__ = '$Id$'
 
-import HTMLParser
-import StringIO
+import html.parser
+import io
 import cgi
-import httplib
+import http.client
 import re
 import sys
 import types
-import urllib
+import urllib.request, urllib.parse, urllib.error
 
 VERSION = '0.9.8'
 PY2x = sys.version_info < (3,0)
 
 
-class _MetaHTMLParser(HTMLParser.HTMLParser):
+class _MetaHTMLParser(html.parser.HTMLParser):
     """Parse given data for <meta http-equiv="content-type">."""
     content_type = None
 
     def handle_starttag(self, tag, attrs):
         if tag == 'meta' and not self.content_type:
             atts = dict([(a.lower(), v.lower()) for a, v in attrs])
-            if atts.get('http-equiv', u'').strip() == u'content-type':
+            if atts.get('http-equiv', '').strip() == 'content-type':
                 self.content_type = atts.get('content')
 
 
@@ -165,7 +165,7 @@ class EncodingInfo(object):
         if self.encoding:
             return self.encoding
         else:
-            return u''
+            return ''
 
     def __repr__(self):
         return "<%s.%s object encoding=%r mismatch=%s at 0x%x>" % (
@@ -214,14 +214,14 @@ def _getTextTypeByMediaType(media_type, log=None):
     if not media_type:
         return _OTHER_TYPE
     xml_application_types = [
-        ur'application/.*?\+xml',
-        u'application/xml',
-        u'application/xml-dtd',
-        u'application/xml-external-parsed-entity']
+        r'application/.*?\+xml',
+        'application/xml',
+        'application/xml-dtd',
+        'application/xml-external-parsed-entity']
     xml_text_types = [
-        ur'text\/.*?\+xml',
-        u'text/xml',
-        u'text/xml-external-parsed-entity']
+        r'text\/.*?\+xml',
+        'text/xml',
+        'text/xml-external-parsed-entity']
 
     media_type = media_type.strip().lower()
 
@@ -231,11 +231,11 @@ def _getTextTypeByMediaType(media_type, log=None):
     elif media_type in xml_text_types or\
             re.match(xml_text_types[0], media_type, re.I|re.S|re.X):
         return _XML_TEXT_TYPE
-    elif media_type == u'text/html':
+    elif media_type == 'text/html':
         return _HTML_TEXT_TYPE
-    elif media_type == u'text/css':
+    elif media_type == 'text/css':
         return _TEXT_UTF8
-    elif media_type.startswith(u'text/'):
+    elif media_type.startswith('text/'):
         return _TEXT_TYPE
     else:
         return _OTHER_TYPE
@@ -245,7 +245,7 @@ def _getTextType(text, log=None):
     """Check if given text is XML (**naive test!**)
     used if no content-type given
     """
-    if text[:30].find(u'<?xml version=') != -1:
+    if text[:30].find('<?xml version=') != -1:
         return _XML_APPLICATION_TYPE
     else:
         return _OTHER_TYPE
@@ -264,11 +264,11 @@ def encodingByMediaType(media_type, log=None):
         Refers to RFC 3023 and HTTP MIME specification.
     """
     defaultencodings = {
-        _XML_APPLICATION_TYPE: u'utf-8',
-        _XML_TEXT_TYPE: u'ascii',
-        _HTML_TEXT_TYPE: u'iso-8859-1', # should be None?
-        _TEXT_TYPE: u'iso-8859-1', # should be None?
-        _TEXT_UTF8: u'utf-8',
+        _XML_APPLICATION_TYPE: 'utf-8',
+        _XML_TEXT_TYPE: 'ascii',
+        _HTML_TEXT_TYPE: 'iso-8859-1', # should be None?
+        _TEXT_TYPE: 'iso-8859-1', # should be None?
+        _TEXT_UTF8: 'utf-8',
         _OTHER_TYPE: None}
 
     texttype = _getTextTypeByMediaType(media_type)
@@ -276,11 +276,11 @@ def encodingByMediaType(media_type, log=None):
 
     if log:
         if not encoding:
-            log.debug(u'"%s" Media-Type has no default encoding',
+            log.debug('"%s" Media-Type has no default encoding',
                 media_type)
         else:
             log.debug(
-                u'Default encoding for Media Type "%s": %s',
+                'Default encoding for Media Type "%s": %s',
                 media_type, encoding)
     return encoding
 
@@ -305,8 +305,8 @@ def getHTTPInfo(response, log=None):
         encoding = encoding.lower()
 
     if log:
-        log.info(u'HTTP media_type: %s', media_type)
-        log.info(u'HTTP encoding: %s', encoding)
+        log.info('HTTP media_type: %s', media_type)
+        log.info('HTTP encoding: %s', encoding)
 
     return media_type, encoding
 
@@ -328,7 +328,7 @@ def getMetaInfo(text, log=None):
 
     try:
         p.feed(text)
-    except HTMLParser.HTMLParseError, e:
+    except html.parser.HTMLParseError as e:
         pass
 
     if p.content_type:
@@ -337,8 +337,8 @@ def getMetaInfo(text, log=None):
         if encoding:
             encoding = encoding.lower()
         if log:
-            log.info(u'HTML META media_type: %s', media_type)
-            log.info(u'HTML META encoding: %s', encoding)
+            log.info('HTML META media_type: %s', media_type)
+            log.info('HTML META encoding: %s', encoding)
     else:
         media_type = encoding = None
 
@@ -367,10 +367,10 @@ def detectXMLEncoding(fp, log=None, includeDefault=True):
         - if BOM and xml declaration fail, utf-8 is returned according
           to XML 1.0.
     """
-    if PY2x and isinstance(fp, types.StringTypes):
-        fp = StringIO.StringIO(fp)
-    elif isinstance(fp, (str,)):
-        fp = StringIO.StringIO(fp)
+    if PY2x and isinstance(fp, (str,)):
+        fp = io.StringIO(fp)
+    elif isinstance(fp, str):
+        fp = io.StringIO(fp)
 
     ### detection using BOM
 
@@ -398,7 +398,7 @@ def detectXMLEncoding(fp, log=None, includeDefault=True):
     ## if BOM detected, we're done :-)
     if bomDetection:
         if log:
-            log.info(u'XML BOM encoding: %s' % bomDetection)
+            log.info('XML BOM encoding: %s' % bomDetection)
         fp.seek(oldFP)
         return bomDetection
 
@@ -433,13 +433,13 @@ def detectXMLEncoding(fp, log=None, includeDefault=True):
     if match:
         enc = match.group("encstr").lower()
         if log:
-            log.info(u'XML encoding="%s"' % enc)
+            log.info('XML encoding="%s"' % enc)
         return enc
     else:
         if includeDefault:
             if log:
-                log.info(u'XML encoding default utf-8')
-            return u'utf-8'
+                log.info('XML encoding default utf-8')
+            return 'utf-8'
         else:
             return None
 
@@ -471,7 +471,7 @@ def tryEncodings(text, log=None):
         if log:
             log.warn(msg)
         else:
-            print msg
+            print(msg)
 
         encodings = (
             'ascii',
@@ -488,7 +488,7 @@ def tryEncodings(text, log=None):
             else:
                 if 'iso-8859-1' == e:
                     try:
-                        if u'€' in text.decode('windows-1252'):
+                        if '€' in text.decode('windows-1252'):
                             return 'windows-1252'
                     except UnicodeDecodeError:
                         pass
@@ -498,7 +498,7 @@ def tryEncodings(text, log=None):
     return encoding
 
 
-def getEncodingInfo(response=None, text=u'', log=None, url=None):
+def getEncodingInfo(response=None, text='', log=None, url=None):
     """Find all encoding related information in given `text`.
 
     Information in headers of supplied HTTPResponse, possible XML
@@ -581,13 +581,13 @@ def getEncodingInfo(response=None, text=u'', log=None, url=None):
     """
     if url:
         # may cause IOError which is raised
-        response = urllib.urlopen(url)
+        response = urllib.request.urlopen(url)
 
     if text is None:
         # read text from response only if not explicitly given
         try:
             text = response.read()
-        except IOError, e:
+        except IOError as e:
             pass
 
     if text is None:
@@ -596,7 +596,7 @@ def getEncodingInfo(response=None, text=u'', log=None, url=None):
 
     encinfo = EncodingInfo()
 
-    logstream = StringIO.StringIO()
+    logstream = io.StringIO()
     if not log:
         log = buildlog(stream=logstream, format='%(message)s')
 
@@ -613,14 +613,14 @@ def getEncodingInfo(response=None, text=u'', log=None, url=None):
     if texttype == _XML_APPLICATION_TYPE:# or texttype == _XML_TEXT_TYPE:
         try:
             encinfo.xml_encoding = detectXMLEncoding(text, log)
-        except (AttributeError, ValueError), e:
+        except (AttributeError, ValueError) as e:
             encinfo.xml_encoding = None
 
     # XML (also XHTML served as text/html)
     if texttype == _HTML_TEXT_TYPE:
         try:
             encinfo.xml_encoding = detectXMLEncoding(text, log, includeDefault=False)
-        except (AttributeError, ValueError), e:
+        except (AttributeError, ValueError) as e:
             encinfo.xml_encoding = None
 
     # HTML
@@ -663,22 +663,22 @@ def getEncodingInfo(response=None, text=u'', log=None, url=None):
     if encinfo.http_encoding and encinfo.xml_encoding and\
        encinfo.http_encoding != encinfo.xml_encoding:
         encinfo.mismatch = True
-        log.warn(u'"%s" (HTTP) != "%s" (XML) encoding mismatch' %
+        log.warn('"%s" (HTTP) != "%s" (XML) encoding mismatch' %
                  (encinfo.http_encoding, encinfo.xml_encoding))
     # HTTP + Meta
     if encinfo.http_encoding and encinfo.meta_encoding and\
          encinfo.http_encoding != encinfo.meta_encoding:
         encinfo.mismatch = True
-        log.warning(u'"%s" (HTTP) != "%s" (HTML <meta>) encoding mismatch' %
+        log.warning('"%s" (HTTP) != "%s" (HTML <meta>) encoding mismatch' %
                  (encinfo.http_encoding, encinfo.meta_encoding))
     # XML + Meta
     if encinfo.xml_encoding and encinfo.meta_encoding and\
          encinfo.xml_encoding != encinfo.meta_encoding:
         encinfo.mismatch = True
-        log.warning(u'"%s" (XML) != "%s" (HTML <meta>) encoding mismatch' %
+        log.warning('"%s" (XML) != "%s" (HTML <meta>) encoding mismatch' %
                  (encinfo.xml_encoding, encinfo.meta_encoding))
 
-    log.info(u'Encoding (probably): %s (Mismatch: %s)',
+    log.info('Encoding (probably): %s (Mismatch: %s)',
              encinfo.encoding, encinfo.mismatch)
 
     encinfo.logtext = logstream.getvalue()
