diff --git lib/yaml/__init__.py lib/yaml/__init__.py
index e131795..2a568a3 100644
--- lib/yaml/__init__.py
+++ lib/yaml/__init__.py
@@ -1,15 +1,16 @@
+import io
 
-from error import *
+from yaml.error import *
 
-from tokens import *
-from events import *
-from nodes import *
+from yaml.tokens import *
+from yaml.events import *
+from yaml.nodes import *
 
-from loader import *
-from dumper import *
+from yaml.loader import *
+from yaml.dumper import *
 
 try:
-    from cyaml import *
+    from yaml.cyaml import *
 except ImportError:
     pass
 
@@ -88,11 +89,7 @@ def emit(events, stream=None, Dumper=Dumper,
     """
     getvalue = None
     if stream is None:
-        try:
-            from cStringIO import StringIO
-        except ImportError:
-            from StringIO import StringIO
-        stream = StringIO()
+        stream = io.StringIO()
         getvalue = stream.getvalue
     dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
             allow_unicode=allow_unicode, line_break=line_break)
@@ -112,11 +109,7 @@ def serialize_all(nodes, stream=None, Dumper=Dumper,
     """
     getvalue = None
     if stream is None:
-        try:
-            from cStringIO import StringIO
-        except ImportError:
-            from StringIO import StringIO
-        stream = StringIO()
+        stream = io.StringIO()
         getvalue = stream.getvalue
     dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
             allow_unicode=allow_unicode, line_break=line_break,
@@ -148,11 +141,7 @@ def dump_all(documents, stream=None, Dumper=Dumper,
     """
     getvalue = None
     if stream is None:
-        try:
-            from cStringIO import StringIO
-        except ImportError:
-            from StringIO import StringIO
-        stream = StringIO()
+        stream = io.StringIO()
         getvalue = stream.getvalue
     dumper = Dumper(stream, default_style=default_style,
             default_flow_style=default_flow_style,
@@ -256,13 +245,12 @@ class YAMLObjectMetaclass(type):
             cls.yaml_loader.add_constructor(cls.yaml_tag, cls.from_yaml)
             cls.yaml_dumper.add_representer(cls, cls.to_yaml)
 
-class YAMLObject(object):
+class YAMLObject(metaclass=YAMLObjectMetaclass):
     """
     An object that can dump itself to a YAML stream
     and load itself from a YAML stream.
     """
 
-    __metaclass__ = YAMLObjectMetaclass
     __slots__ = ()  # no direct instantiation, so allow immutable subclasses
 
     yaml_loader = Loader
diff --git lib/yaml/composer.py lib/yaml/composer.py
index 06e5ac7..f468cc5 100644
--- lib/yaml/composer.py
+++ lib/yaml/composer.py
@@ -1,14 +1,14 @@
 
 __all__ = ['Composer', 'ComposerError']
 
-from error import MarkedYAMLError
-from events import *
-from nodes import *
+from yaml.error import MarkedYAMLError
+from yaml.events import *
+from yaml.nodes import *
 
 class ComposerError(MarkedYAMLError):
     pass
 
-class Composer(object):
+class Composer:
 
     def __init__(self):
         self.anchors = {}
@@ -88,7 +88,7 @@ class Composer(object):
     def compose_scalar_node(self, anchor):
         event = self.get_event()
         tag = event.tag
-        if tag is None or tag == u'!':
+        if tag is None or tag == '!':
             tag = self.resolve(ScalarNode, event.value, event.implicit)
         node = ScalarNode(tag, event.value,
                 event.start_mark, event.end_mark, style=event.style)
@@ -99,7 +99,7 @@ class Composer(object):
     def compose_sequence_node(self, anchor):
         start_event = self.get_event()
         tag = start_event.tag
-        if tag is None or tag == u'!':
+        if tag is None or tag == '!':
             tag = self.resolve(SequenceNode, None, start_event.implicit)
         node = SequenceNode(tag, [],
                 start_event.start_mark, None,
@@ -117,7 +117,7 @@ class Composer(object):
     def compose_mapping_node(self, anchor):
         start_event = self.get_event()
         tag = start_event.tag
-        if tag is None or tag == u'!':
+        if tag is None or tag == '!':
             tag = self.resolve(MappingNode, None, start_event.implicit)
         node = MappingNode(tag, [],
                 start_event.start_mark, None,
diff --git lib/yaml/constructor.py lib/yaml/constructor.py
index 34cc226..cb51483 100644
--- lib/yaml/constructor.py
+++ lib/yaml/constructor.py
@@ -2,22 +2,17 @@
 __all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
     'ConstructorError']
 
-from error import *
-from nodes import *
+from yaml.error import *
+from yaml.nodes import *
 
 import datetime
 
-try:
-    set
-except NameError:
-    from sets import Set as set
-
-import binascii, re, sys, types
+import binascii, re, sys, types, base64
 
 class ConstructorError(MarkedYAMLError):
     pass
 
-class BaseConstructor(object):
+class BaseConstructor:
 
     yaml_constructors = {}
     yaml_multi_constructors = {}
@@ -96,7 +91,7 @@ class BaseConstructor(object):
             data = constructor(self, tag_suffix, node)
         if isinstance(data, types.GeneratorType):
             generator = data
-            data = generator.next()
+            data = next(generator)
             if self.deep_construct:
                 for dummy in generator:
                     pass
@@ -133,7 +128,7 @@ class BaseConstructor(object):
             key = self.construct_object(key_node, deep=deep)
             try:
                 hash(key)
-            except TypeError, exc:
+            except TypeError as exc:
                 raise ConstructorError("while constructing a mapping", node.start_mark,
                         "found unacceptable key (%s)" % exc, key_node.start_mark)
             value = self.construct_object(value_node, deep=deep)
@@ -169,7 +164,7 @@ class SafeConstructor(BaseConstructor):
     def construct_scalar(self, node):
         if isinstance(node, MappingNode):
             for key_node, value_node in node.value:
-                if key_node.tag == u'tag:yaml.org,2002:value':
+                if key_node.tag == 'tag:yaml.org,2002:value':
                     return self.construct_scalar(value_node)
         return BaseConstructor.construct_scalar(self, node)
 
@@ -178,7 +173,7 @@ class SafeConstructor(BaseConstructor):
         index = 0
         while index < len(node.value):
             key_node, value_node = node.value[index]
-            if key_node.tag == u'tag:yaml.org,2002:merge':
+            if key_node.tag == 'tag:yaml.org,2002:merge':
                 del node.value[index]
                 if isinstance(value_node, MappingNode):
                     self.flatten_mapping(value_node)
@@ -200,8 +195,8 @@ class SafeConstructor(BaseConstructor):
                     raise ConstructorError("while constructing a mapping", node.start_mark,
                             "expected a mapping or list of mappings for merging, but found %s"
                             % value_node.id, value_node.start_mark)
-            elif key_node.tag == u'tag:yaml.org,2002:value':
-                key_node.tag = u'tag:yaml.org,2002:str'
+            elif key_node.tag == 'tag:yaml.org,2002:value':
+                key_node.tag = 'tag:yaml.org,2002:str'
                 index += 1
             else:
                 index += 1
@@ -218,12 +213,12 @@ class SafeConstructor(BaseConstructor):
         return None
 
     bool_values = {
-        u'yes':     True,
-        u'no':      False,
-        u'true':    True,
-        u'false':   False,
-        u'on':      True,
-        u'off':     False,
+        'yes':     True,
+        'no':      False,
+        'true':    True,
+        'false':   False,
+        'on':      True,
+        'off':     False,
     }
 
     def construct_yaml_bool(self, node):
@@ -290,13 +285,13 @@ class SafeConstructor(BaseConstructor):
     def construct_yaml_binary(self, node):
         value = self.construct_scalar(node)
         try:
-            return str(value).decode('base64')
-        except (binascii.Error, UnicodeEncodeError), exc:
+            return base64.decodestring(value.encode('utf-8'))
+        except (binascii.Error, UnicodeEncodeError) as exc:
             raise ConstructorError(None, None,
                     "failed to decode base64 data: %s" % exc, node.start_mark) 
 
     timestamp_regexp = re.compile(
-            ur'''^(?P<year>[0-9][0-9][0-9][0-9])
+            r'''^(?P<year>[0-9][0-9][0-9][0-9])
                 -(?P<month>[0-9][0-9]?)
                 -(?P<day>[0-9][0-9]?)
                 (?:(?:[Tt]|[ \t]+)
@@ -387,11 +382,7 @@ class SafeConstructor(BaseConstructor):
         data.update(value)
 
     def construct_yaml_str(self, node):
-        value = self.construct_scalar(node)
-        try:
-            return value.encode('ascii')
-        except UnicodeEncodeError:
-            return value
+        return self.construct_scalar(node)
 
     def construct_yaml_seq(self, node):
         data = []
@@ -416,55 +407,55 @@ class SafeConstructor(BaseConstructor):
 
     def construct_undefined(self, node):
         raise ConstructorError(None, None,
-                "could not determine a constructor for the tag %r" % node.tag.encode('utf-8'),
+                "could not determine a constructor for the tag %r" % node.tag,
                 node.start_mark)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:null',
+        'tag:yaml.org,2002:null',
         SafeConstructor.construct_yaml_null)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:bool',
+        'tag:yaml.org,2002:bool',
         SafeConstructor.construct_yaml_bool)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:int',
+        'tag:yaml.org,2002:int',
         SafeConstructor.construct_yaml_int)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:float',
+        'tag:yaml.org,2002:float',
         SafeConstructor.construct_yaml_float)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:binary',
+        'tag:yaml.org,2002:binary',
         SafeConstructor.construct_yaml_binary)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:timestamp',
+        'tag:yaml.org,2002:timestamp',
         SafeConstructor.construct_yaml_timestamp)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:omap',
+        'tag:yaml.org,2002:omap',
         SafeConstructor.construct_yaml_omap)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:pairs',
+        'tag:yaml.org,2002:pairs',
         SafeConstructor.construct_yaml_pairs)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:set',
+        'tag:yaml.org,2002:set',
         SafeConstructor.construct_yaml_set)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:str',
+        'tag:yaml.org,2002:str',
         SafeConstructor.construct_yaml_str)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:seq',
+        'tag:yaml.org,2002:seq',
         SafeConstructor.construct_yaml_seq)
 
 SafeConstructor.add_constructor(
-        u'tag:yaml.org,2002:map',
+        'tag:yaml.org,2002:map',
         SafeConstructor.construct_yaml_map)
 
 SafeConstructor.add_constructor(None,
@@ -473,13 +464,16 @@ SafeConstructor.add_constructor(None,
 class Constructor(SafeConstructor):
 
     def construct_python_str(self, node):
-        return self.construct_scalar(node).encode('utf-8')
+        return self.construct_scalar(node)
 
     def construct_python_unicode(self, node):
         return self.construct_scalar(node)
 
+    def construct_python_bytes(self, node):
+        return self.construct_scalar(node).encode('utf-8')
+
     def construct_python_long(self, node):
-        return long(self.construct_yaml_int(node))
+        return self.construct_yaml_int(node)
 
     def construct_python_complex(self, node):
        return complex(self.construct_scalar(node))
@@ -493,33 +487,29 @@ class Constructor(SafeConstructor):
                     "expected non-empty name appended to the tag", mark)
         try:
             __import__(name)
-        except ImportError, exc:
+        except ImportError as exc:
             raise ConstructorError("while constructing a Python module", mark,
-                    "cannot find module %r (%s)" % (name.encode('utf-8'), exc), mark)
+                    "cannot find module %r (%s)" % (name, exc), mark)
         return sys.modules[name]
 
     def find_python_name(self, name, mark):
         if not name:
             raise ConstructorError("while constructing a Python object", mark,
                     "expected non-empty name appended to the tag", mark)
-        if u'.' in name:
-            # Python 2.4 only
-            #module_name, object_name = name.rsplit('.', 1)
-            items = name.split('.')
-            object_name = items.pop()
-            module_name = '.'.join(items)
+        if '.' in name:
+            module_name, object_name = name.rsplit('.', 1)
         else:
-            module_name = '__builtin__'
+            module_name = 'builtins'
             object_name = name
         try:
             __import__(module_name)
-        except ImportError, exc:
+        except ImportError as exc:
             raise ConstructorError("while constructing a Python object", mark,
-                    "cannot find module %r (%s)" % (module_name.encode('utf-8'), exc), mark)
+                    "cannot find module %r (%s)" % (module_name, exc), mark)
         module = sys.modules[module_name]
         if not hasattr(module, object_name):
             raise ConstructorError("while constructing a Python object", mark,
-                    "cannot find %r in the module %r" % (object_name.encode('utf-8'),
+                    "cannot find %r in the module %r" % (object_name,
                         module.__name__), mark)
         return getattr(module, object_name)
 
@@ -527,7 +517,7 @@ class Constructor(SafeConstructor):
         value = self.construct_scalar(node)
         if value:
             raise ConstructorError("while constructing a Python name", node.start_mark,
-                    "expected the empty value, but found %r" % value.encode('utf-8'),
+                    "expected the empty value, but found %r" % value,
                     node.start_mark)
         return self.find_python_name(suffix, node.start_mark)
 
@@ -535,12 +525,10 @@ class Constructor(SafeConstructor):
         value = self.construct_scalar(node)
         if value:
             raise ConstructorError("while constructing a Python module", node.start_mark,
-                    "expected the empty value, but found %r" % value.encode('utf-8'),
+                    "expected the empty value, but found %r" % value,
                     node.start_mark)
         return self.find_python_module(suffix, node.start_mark)
 
-    class classobj: pass
-
     def make_python_instance(self, suffix, node,
             args=None, kwds=None, newobj=False):
         if not args:
@@ -548,12 +536,7 @@ class Constructor(SafeConstructor):
         if not kwds:
             kwds = {}
         cls = self.find_python_name(suffix, node.start_mark)
-        if newobj and isinstance(cls, type(self.classobj))  \
-                and not args and not kwds:
-            instance = self.classobj()
-            instance.__class__ = cls
-            return instance
-        elif newobj and isinstance(cls, type):
+        if newobj and isinstance(cls, type):
             return cls.__new__(cls, *args, **kwds)
         else:
             return cls(*args, **kwds)
@@ -620,66 +603,70 @@ class Constructor(SafeConstructor):
         return self.construct_python_object_apply(suffix, node, newobj=True)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/none',
+    'tag:yaml.org,2002:python/none',
     Constructor.construct_yaml_null)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/bool',
+    'tag:yaml.org,2002:python/bool',
     Constructor.construct_yaml_bool)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/str',
+    'tag:yaml.org,2002:python/str',
     Constructor.construct_python_str)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/unicode',
+    'tag:yaml.org,2002:python/unicode',
     Constructor.construct_python_unicode)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/int',
+    'tag:yaml.org,2002:python/bytes',
+    Constructor.construct_python_bytes)
+
+Constructor.add_constructor(
+    'tag:yaml.org,2002:python/int',
     Constructor.construct_yaml_int)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/long',
+    'tag:yaml.org,2002:python/long',
     Constructor.construct_python_long)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/float',
+    'tag:yaml.org,2002:python/float',
     Constructor.construct_yaml_float)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/complex',
+    'tag:yaml.org,2002:python/complex',
     Constructor.construct_python_complex)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/list',
+    'tag:yaml.org,2002:python/list',
     Constructor.construct_yaml_seq)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/tuple',
+    'tag:yaml.org,2002:python/tuple',
     Constructor.construct_python_tuple)
 
 Constructor.add_constructor(
-    u'tag:yaml.org,2002:python/dict',
+    'tag:yaml.org,2002:python/dict',
     Constructor.construct_yaml_map)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/name:',
+    'tag:yaml.org,2002:python/name:',
     Constructor.construct_python_name)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/module:',
+    'tag:yaml.org,2002:python/module:',
     Constructor.construct_python_module)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/object:',
+    'tag:yaml.org,2002:python/object:',
     Constructor.construct_python_object)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/object/apply:',
+    'tag:yaml.org,2002:python/object/apply:',
     Constructor.construct_python_object_apply)
 
 Constructor.add_multi_constructor(
-    u'tag:yaml.org,2002:python/object/new:',
+    'tag:yaml.org,2002:python/object/new:',
     Constructor.construct_python_object_new)
 
diff --git lib/yaml/dumper.py lib/yaml/dumper.py
index 355c1e2..e06364c 100644
--- lib/yaml/dumper.py
+++ lib/yaml/dumper.py
@@ -1,10 +1,10 @@
 
 __all__ = ['BaseDumper', 'SafeDumper', 'Dumper']
 
-from emitter import *
-from serializer import *
-from representer import *
-from resolver import *
+from yaml.emitter import *
+from yaml.serializer import *
+from yaml.representer import *
+from yaml.resolver import *
 
 class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver):
 
diff --git lib/yaml/emitter.py lib/yaml/emitter.py
index d9d1bf8..17789e9 100644
--- lib/yaml/emitter.py
+++ lib/yaml/emitter.py
@@ -8,15 +8,15 @@
 
 __all__ = ['Emitter', 'EmitterError']
 
-from error import YAMLError
-from events import *
+from yaml.error import YAMLError
+from yaml.events import *
 
 import re
 
 class EmitterError(YAMLError):
     pass
 
-class ScalarAnalysis(object):
+class ScalarAnalysis:
     def __init__(self, scalar, empty, multiline,
             allow_flow_plain, allow_block_plain,
             allow_single_quoted, allow_double_quoted,
@@ -30,11 +30,11 @@ class ScalarAnalysis(object):
         self.allow_double_quoted = allow_double_quoted
         self.allow_block = allow_block
 
-class Emitter(object):
+class Emitter:
 
     DEFAULT_TAG_PREFIXES = {
-        u'!' : u'!',
-        u'tag:yaml.org,2002:' : u'!!',
+        '!' : '!',
+        'tag:yaml.org,2002:' : '!!',
     }
 
     def __init__(self, stream, canonical=None, indent=None, width=None,
@@ -87,8 +87,8 @@ class Emitter(object):
         self.best_width = 80
         if width and width > self.best_indent*2:
             self.best_width = width
-        self.best_line_break = u'\n'
-        if line_break in [u'\r', u'\n', u'\r\n']:
+        self.best_line_break = '\n'
+        if line_break in ['\r', '\n', '\r\n']:
             self.best_line_break = line_break
 
         # Tag prefixes.
@@ -176,8 +176,7 @@ class Emitter(object):
                 self.write_version_directive(version_text)
             self.tag_prefixes = self.DEFAULT_TAG_PREFIXES.copy()
             if self.event.tags:
-                handles = self.event.tags.keys()
-                handles.sort()
+                handles = sorted(self.event.tags.keys())
                 for handle in handles:
                     prefix = self.event.tags[handle]
                     self.tag_prefixes[prefix] = handle
@@ -189,7 +188,7 @@ class Emitter(object):
                     and not self.check_empty_document())
             if not implicit:
                 self.write_indent()
-                self.write_indicator(u'---', True)
+                self.write_indicator('---', True)
                 if self.canonical:
                     self.write_indent()
             self.state = self.expect_document_root
@@ -204,7 +203,7 @@ class Emitter(object):
         if isinstance(self.event, DocumentEndEvent):
             self.write_indent()
             if self.event.explicit:
-                self.write_indicator(u'...', True)
+                self.write_indicator('...', True)
                 self.write_indent()
             self.flush_stream()
             self.state = self.expect_document_start
@@ -227,7 +226,7 @@ class Emitter(object):
         if isinstance(self.event, AliasEvent):
             self.expect_alias()
         elif isinstance(self.event, (ScalarEvent, CollectionStartEvent)):
-            self.process_anchor(u'&')
+            self.process_anchor('&')
             self.process_tag()
             if isinstance(self.event, ScalarEvent):
                 self.expect_scalar()
@@ -249,7 +248,7 @@ class Emitter(object):
     def expect_alias(self):
         if self.event.anchor is None:
             raise EmitterError("anchor is not specified for alias")
-        self.process_anchor(u'*')
+        self.process_anchor('*')
         self.state = self.states.pop()
 
     def expect_scalar(self):
@@ -261,7 +260,7 @@ class Emitter(object):
     # Flow sequence handlers.
 
     def expect_flow_sequence(self):
-        self.write_indicator(u'[', True, whitespace=True)
+        self.write_indicator('[', True, whitespace=True)
         self.flow_level += 1
         self.increase_indent(flow=True)
         self.state = self.expect_first_flow_sequence_item
@@ -270,7 +269,7 @@ class Emitter(object):
         if isinstance(self.event, SequenceEndEvent):
             self.indent = self.indents.pop()
             self.flow_level -= 1
-            self.write_indicator(u']', False)
+            self.write_indicator(']', False)
             self.state = self.states.pop()
         else:
             if self.canonical or self.column > self.best_width:
@@ -283,12 +282,12 @@ class Emitter(object):
             self.indent = self.indents.pop()
             self.flow_level -= 1
             if self.canonical:
-                self.write_indicator(u',', False)
+                self.write_indicator(',', False)
                 self.write_indent()
-            self.write_indicator(u']', False)
+            self.write_indicator(']', False)
             self.state = self.states.pop()
         else:
-            self.write_indicator(u',', False)
+            self.write_indicator(',', False)
             if self.canonical or self.column > self.best_width:
                 self.write_indent()
             self.states.append(self.expect_flow_sequence_item)
@@ -297,7 +296,7 @@ class Emitter(object):
     # Flow mapping handlers.
 
     def expect_flow_mapping(self):
-        self.write_indicator(u'{', True, whitespace=True)
+        self.write_indicator('{', True, whitespace=True)
         self.flow_level += 1
         self.increase_indent(flow=True)
         self.state = self.expect_first_flow_mapping_key
@@ -306,7 +305,7 @@ class Emitter(object):
         if isinstance(self.event, MappingEndEvent):
             self.indent = self.indents.pop()
             self.flow_level -= 1
-            self.write_indicator(u'}', False)
+            self.write_indicator('}', False)
             self.state = self.states.pop()
         else:
             if self.canonical or self.column > self.best_width:
@@ -315,7 +314,7 @@ class Emitter(object):
                 self.states.append(self.expect_flow_mapping_simple_value)
                 self.expect_node(mapping=True, simple_key=True)
             else:
-                self.write_indicator(u'?', True)
+                self.write_indicator('?', True)
                 self.states.append(self.expect_flow_mapping_value)
                 self.expect_node(mapping=True)
 
@@ -324,31 +323,31 @@ class Emitter(object):
             self.indent = self.indents.pop()
             self.flow_level -= 1
             if self.canonical:
-                self.write_indicator(u',', False)
+                self.write_indicator(',', False)
                 self.write_indent()
-            self.write_indicator(u'}', False)
+            self.write_indicator('}', False)
             self.state = self.states.pop()
         else:
-            self.write_indicator(u',', False)
+            self.write_indicator(',', False)
             if self.canonical or self.column > self.best_width:
                 self.write_indent()
             if not self.canonical and self.check_simple_key():
                 self.states.append(self.expect_flow_mapping_simple_value)
                 self.expect_node(mapping=True, simple_key=True)
             else:
-                self.write_indicator(u'?', True)
+                self.write_indicator('?', True)
                 self.states.append(self.expect_flow_mapping_value)
                 self.expect_node(mapping=True)
 
     def expect_flow_mapping_simple_value(self):
-        self.write_indicator(u':', False)
+        self.write_indicator(':', False)
         self.states.append(self.expect_flow_mapping_key)
         self.expect_node(mapping=True)
 
     def expect_flow_mapping_value(self):
         if self.canonical or self.column > self.best_width:
             self.write_indent()
-        self.write_indicator(u':', True)
+        self.write_indicator(':', True)
         self.states.append(self.expect_flow_mapping_key)
         self.expect_node(mapping=True)
 
@@ -368,7 +367,7 @@ class Emitter(object):
             self.state = self.states.pop()
         else:
             self.write_indent()
-            self.write_indicator(u'-', True, indention=True)
+            self.write_indicator('-', True, indention=True)
             self.states.append(self.expect_block_sequence_item)
             self.expect_node(sequence=True)
 
@@ -391,18 +390,18 @@ class Emitter(object):
                 self.states.append(self.expect_block_mapping_simple_value)
                 self.expect_node(mapping=True, simple_key=True)
             else:
-                self.write_indicator(u'?', True, indention=True)
+                self.write_indicator('?', True, indention=True)
                 self.states.append(self.expect_block_mapping_value)
                 self.expect_node(mapping=True)
 
     def expect_block_mapping_simple_value(self):
-        self.write_indicator(u':', False)
+        self.write_indicator(':', False)
         self.states.append(self.expect_block_mapping_key)
         self.expect_node(mapping=True)
 
     def expect_block_mapping_value(self):
         self.write_indent()
-        self.write_indicator(u':', True, indention=True)
+        self.write_indicator(':', True, indention=True)
         self.states.append(self.expect_block_mapping_key)
         self.expect_node(mapping=True)
 
@@ -421,7 +420,7 @@ class Emitter(object):
             return False
         event = self.events[0]
         return (isinstance(event, ScalarEvent) and event.anchor is None
-                and event.tag is None and event.implicit and event.value == u'')
+                and event.tag is None and event.implicit and event.value == '')
 
     def check_simple_key(self):
         length = 0
@@ -466,7 +465,7 @@ class Emitter(object):
                 self.prepared_tag = None
                 return
             if self.event.implicit[0] and tag is None:
-                tag = u'!'
+                tag = '!'
                 self.prepared_tag = None
         else:
             if (not self.canonical or tag is None) and self.event.implicit:
@@ -529,17 +528,17 @@ class Emitter(object):
         major, minor = version
         if major != 1:
             raise EmitterError("unsupported YAML version: %d.%d" % (major, minor))
-        return u'%d.%d' % (major, minor)
+        return '%d.%d' % (major, minor)
 
     def prepare_tag_handle(self, handle):
         if not handle:
             raise EmitterError("tag handle must not be empty")
-        if handle[0] != u'!' or handle[-1] != u'!':
+        if handle[0] != '!' or handle[-1] != '!':
             raise EmitterError("tag handle must start and end with '!': %r"
                     % (handle.encode('utf-8')))
         for ch in handle[1:-1]:
-            if not (u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'    \
-                    or ch in u'-_'):
+            if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'    \
+                    or ch in '-_'):
                 raise EmitterError("invalid character %r in the tag handle: %r"
                         % (ch.encode('utf-8'), handle.encode('utf-8')))
         return handle
@@ -549,12 +548,12 @@ class Emitter(object):
             raise EmitterError("tag prefix must not be empty")
         chunks = []
         start = end = 0
-        if prefix[0] == u'!':
+        if prefix[0] == '!':
             end = 1
         while end < len(prefix):
             ch = prefix[end]
-            if u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'  \
-                    or ch in u'-;/?!:@&=+$,_.~*\'()[]':
+            if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'  \
+                    or ch in '-;/?!:@&=+$,_.~*\'()[]':
                 end += 1
             else:
                 if start < end:
@@ -562,30 +561,30 @@ class Emitter(object):
                 start = end = end+1
                 data = ch.encode('utf-8')
                 for ch in data:
-                    chunks.append(u'%%%02X' % ord(ch))
+                    chunks.append('%%%02X' % ord(ch))
         if start < end:
             chunks.append(prefix[start:end])
-        return u''.join(chunks)
+        return ''.join(chunks)
 
     def prepare_tag(self, tag):
         if not tag:
             raise EmitterError("tag must not be empty")
-        if tag == u'!':
+        if tag == '!':
             return tag
         handle = None
         suffix = tag
         for prefix in self.tag_prefixes:
             if tag.startswith(prefix)   \
-                    and (prefix == u'!' or len(prefix) < len(tag)):
+                    and (prefix == '!' or len(prefix) < len(tag)):
                 handle = self.tag_prefixes[prefix]
                 suffix = tag[len(prefix):]
         chunks = []
         start = end = 0
         while end < len(suffix):
             ch = suffix[end]
-            if u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'  \
-                    or ch in u'-;/?:@&=+$,_.~*\'()[]'   \
-                    or (ch == u'!' and handle != u'!'):
+            if '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'  \
+                    or ch in '-;/?:@&=+$,_.~*\'()[]'   \
+                    or (ch == '!' and handle != '!'):
                 end += 1
             else:
                 if start < end:
@@ -593,21 +592,21 @@ class Emitter(object):
                 start = end = end+1
                 data = ch.encode('utf-8')
                 for ch in data:
-                    chunks.append(u'%%%02X' % ord(ch))
+                    chunks.append('%%%02X' % ord(ch))
         if start < end:
             chunks.append(suffix[start:end])
-        suffix_text = u''.join(chunks)
+        suffix_text = ''.join(chunks)
         if handle:
-            return u'%s%s' % (handle, suffix_text)
+            return '%s%s' % (handle, suffix_text)
         else:
-            return u'!<%s>' % suffix_text
+            return '!<%s>' % suffix_text
 
     def prepare_anchor(self, anchor):
         if not anchor:
             raise EmitterError("anchor must not be empty")
         for ch in anchor:
-            if not (u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'    \
-                    or ch in u'-_'):
+            if not ('0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'    \
+                    or ch in '-_'):
                 raise EmitterError("invalid character %r in the anchor: %r"
                         % (ch.encode('utf-8'), anchor.encode('utf-8')))
         return anchor
@@ -638,7 +637,7 @@ class Emitter(object):
         mixed_breaks_spaces = False    # anything else
 
         # Check document indicators.
-        if scalar.startswith(u'---') or scalar.startswith(u'...'):
+        if scalar.startswith('---') or scalar.startswith('...'):
             block_indicators = True
             flow_indicators = True
 
@@ -647,7 +646,7 @@ class Emitter(object):
 
         # Last character or followed by a whitespace.
         followed_by_space = (len(scalar) == 1 or
-                scalar[1] in u'\0 \t\r\n\x85\u2028\u2029')
+                scalar[1] in '\0 \t\r\n\x85\u2028\u2029')
 
         # The current series of whitespaces contain plain spaces.
         spaces = False
@@ -671,35 +670,35 @@ class Emitter(object):
 
             if index == 0:
                 # Leading indicators are special characters.
-                if ch in u'#,[]{}&*!|>\'\"%@`': 
+                if ch in '#,[]{}&*!|>\'\"%@`': 
                     flow_indicators = True
                     block_indicators = True
-                if ch in u'?:':
+                if ch in '?:':
                     flow_indicators = True
                     if followed_by_space:
                         block_indicators = True
-                if ch == u'-' and followed_by_space:
+                if ch == '-' and followed_by_space:
                     flow_indicators = True
                     block_indicators = True
             else:
                 # Some indicators cannot appear within a scalar as well.
-                if ch in u',?[]{}':
+                if ch in ',?[]{}':
                     flow_indicators = True
-                if ch == u':':
+                if ch == ':':
                     flow_indicators = True
                     if followed_by_space:
                         block_indicators = True
-                if ch == u'#' and preceeded_by_space:
+                if ch == '#' and preceeded_by_space:
                     flow_indicators = True
                     block_indicators = True
 
             # Check for line breaks, special, and unicode characters.
 
-            if ch in u'\n\x85\u2028\u2029':
+            if ch in '\n\x85\u2028\u2029':
                 line_breaks = True
-            if not (ch == u'\n' or u'\x20' <= ch <= u'\x7E'):
-                if (ch == u'\x85' or u'\xA0' <= ch <= u'\uD7FF'
-                        or u'\uE000' <= ch <= u'\uFFFD') and ch != u'\uFEFF':
+            if not (ch == '\n' or '\x20' <= ch <= '\x7E'):
+                if (ch == '\x85' or '\xA0' <= ch <= '\uD7FF'
+                        or '\uE000' <= ch <= '\uFFFD') and ch != '\uFEFF':
                     unicode_characters = True
                     if not self.allow_unicode:
                         special_characters = True
@@ -709,20 +708,20 @@ class Emitter(object):
             # Spaces, line breaks, and how they are mixed. State machine.
 
             # Start or continue series of whitespaces.
-            if ch in u' \n\x85\u2028\u2029':
+            if ch in ' \n\x85\u2028\u2029':
                 if spaces and breaks:
-                    if ch != u' ':      # break+ (space+ break+)    => mixed
+                    if ch != ' ':      # break+ (space+ break+)    => mixed
                         mixed = True
                 elif spaces:
-                    if ch != u' ':      # (space+ break+)   => mixed
+                    if ch != ' ':      # (space+ break+)   => mixed
                         breaks = True
                         mixed = True
                 elif breaks:
-                    if ch == u' ':      # break+ space+
+                    if ch == ' ':      # break+ space+
                         spaces = True
                 else:
                     leading = (index == 0)
-                    if ch == u' ':      # space+
+                    if ch == ' ':      # space+
                         spaces = True
                     else:               # break+
                         breaks = True
@@ -763,9 +762,9 @@ class Emitter(object):
 
             # Prepare for the next character.
             index += 1
-            preceeded_by_space = (ch in u'\0 \t\r\n\x85\u2028\u2029')
+            preceeded_by_space = (ch in '\0 \t\r\n\x85\u2028\u2029')
             followed_by_space = (index+1 >= len(scalar) or
-                    scalar[index+1] in u'\0 \t\r\n\x85\u2028\u2029')
+                    scalar[index+1] in '\0 \t\r\n\x85\u2028\u2029')
 
         # Let's decide what styles are allowed.
         allow_flow_plain = True
@@ -824,7 +823,7 @@ class Emitter(object):
     def write_stream_start(self):
         # Write BOM if needed.
         if self.encoding and self.encoding.startswith('utf-16'):
-            self.stream.write(u'\xFF\xFE'.encode(self.encoding))
+            self.stream.write('\xFF\xFE'.encode(self.encoding))
 
     def write_stream_end(self):
         self.flush_stream()
@@ -834,12 +833,10 @@ class Emitter(object):
         if self.whitespace or not need_whitespace:
             data = indicator
         else:
-            data = u' '+indicator
+            data = ' '+indicator
         self.whitespace = whitespace
         self.indention = self.indention and indention
         self.column += len(data)
-        if self.encoding:
-            data = data.encode(self.encoding)
         self.stream.write(data)
 
     def write_indent(self):
@@ -849,10 +846,8 @@ class Emitter(object):
             self.write_line_break()
         if self.column < indent:
             self.whitespace = True
-            data = u' '*(indent-self.column)
+            data = ' '*(indent-self.column)
             self.column = indent
-            if self.encoding:
-                data = data.encode(self.encoding)
             self.stream.write(data)
 
     def write_line_break(self, data=None):
@@ -862,28 +857,22 @@ class Emitter(object):
         self.indention = True
         self.line += 1
         self.column = 0
-        if self.encoding:
-            data = data.encode(self.encoding)
         self.stream.write(data)
 
     def write_version_directive(self, version_text):
-        data = u'%%YAML %s' % version_text
-        if self.encoding:
-            data = data.encode(self.encoding)
+        data = '%%YAML %s' % version_text
         self.stream.write(data)
         self.write_line_break()
 
     def write_tag_directive(self, handle_text, prefix_text):
-        data = u'%%TAG %s %s' % (handle_text, prefix_text)
-        if self.encoding:
-            data = data.encode(self.encoding)
+        data = '%%TAG %s %s' % (handle_text, prefix_text)
         self.stream.write(data)
         self.write_line_break()
 
     # Scalar streams.
 
     def write_single_quoted(self, text, split=True):
-        self.write_indicator(u'\'', True)
+        self.write_indicator('\'', True)
         spaces = False
         breaks = False
         start = end = 0
@@ -892,137 +881,123 @@ class Emitter(object):
             if end < len(text):
                 ch = text[end]
             if spaces:
-                if ch is None or ch != u' ':
+                if ch is None or ch != ' ':
                     if start+1 == end and self.column > self.best_width and split   \
                             and start != 0 and end != len(text):
                         self.write_indent()
                     else:
                         data = text[start:end]
                         self.column += len(data)
-                        if self.encoding:
-                            data = data.encode(self.encoding)
                         self.stream.write(data)
                     start = end
             elif breaks:
-                if ch is None or ch not in u'\n\x85\u2028\u2029':
-                    if text[start] == u'\n':
+                if ch is None or ch not in '\n\x85\u2028\u2029':
+                    if text[start] == '\n':
                         self.write_line_break()
                     for br in text[start:end]:
-                        if br == u'\n':
+                        if br == '\n':
                             self.write_line_break()
                         else:
                             self.write_line_break(br)
                     self.write_indent()
                     start = end
             else:
-                if ch is None or ch in u' \n\x85\u2028\u2029' or ch == u'\'':
+                if ch is None or ch in ' \n\x85\u2028\u2029' or ch == '\'':
                     if start < end:
                         data = text[start:end]
                         self.column += len(data)
-                        if self.encoding:
-                            data = data.encode(self.encoding)
                         self.stream.write(data)
                         start = end
-            if ch == u'\'':
-                data = u'\'\''
+            if ch == '\'':
+                data = '\'\''
                 self.column += 2
-                if self.encoding:
-                    data = data.encode(self.encoding)
                 self.stream.write(data)
                 start = end + 1
             if ch is not None:
-                spaces = (ch == u' ')
-                breaks = (ch in u'\n\x85\u2028\u2029')
+                spaces = (ch == ' ')
+                breaks = (ch in '\n\x85\u2028\u2029')
             end += 1
-        self.write_indicator(u'\'', False)
+        self.write_indicator('\'', False)
 
     ESCAPE_REPLACEMENTS = {
-        u'\0':      u'0',
-        u'\x07':    u'a',
-        u'\x08':    u'b',
-        u'\x09':    u't',
-        u'\x0A':    u'n',
-        u'\x0B':    u'v',
-        u'\x0C':    u'f',
-        u'\x0D':    u'r',
-        u'\x1B':    u'e',
-        u'\"':      u'\"',
-        u'\\':      u'\\',
-        u'\x85':    u'N',
-        u'\xA0':    u'_',
-        u'\u2028':  u'L',
-        u'\u2029':  u'P',
+        '\0':      '0',
+        '\x07':    'a',
+        '\x08':    'b',
+        '\x09':    't',
+        '\x0A':    'n',
+        '\x0B':    'v',
+        '\x0C':    'f',
+        '\x0D':    'r',
+        '\x1B':    'e',
+        '\"':      '\"',
+        '\\':      '\\',
+        '\x85':    'N',
+        '\xA0':    '_',
+        '\u2028':  'L',
+        '\u2029':  'P',
     }
 
     def write_double_quoted(self, text, split=True):
-        self.write_indicator(u'"', True)
+        self.write_indicator('"', True)
         start = end = 0
         while end <= len(text):
             ch = None
             if end < len(text):
                 ch = text[end]
-            if ch is None or ch in u'"\\\x85\u2028\u2029\uFEFF' \
-                    or not (u'\x20' <= ch <= u'\x7E'
+            if ch is None or ch in '"\\\x85\u2028\u2029\uFEFF' \
+                    or not ('\x20' <= ch <= '\x7E'
                         or (self.allow_unicode
-                            and (u'\xA0' <= ch <= u'\uD7FF'
-                                or u'\uE000' <= ch <= u'\uFFFD'))):
+                            and ('\xA0' <= ch <= '\uD7FF'
+                                or '\uE000' <= ch <= '\uFFFD'))):
                 if start < end:
                     data = text[start:end]
                     self.column += len(data)
-                    if self.encoding:
-                        data = data.encode(self.encoding)
                     self.stream.write(data)
                     start = end
                 if ch is not None:
                     if ch in self.ESCAPE_REPLACEMENTS:
-                        data = u'\\'+self.ESCAPE_REPLACEMENTS[ch]
-                    elif ch <= u'\xFF':
-                        data = u'\\x%02X' % ord(ch)
-                    elif ch <= u'\uFFFF':
-                        data = u'\\u%04X' % ord(ch)
+                        data = '\\'+self.ESCAPE_REPLACEMENTS[ch]
+                    elif ch <= '\xFF':
+                        data = '\\x%02X' % ord(ch)
+                    elif ch <= '\uFFFF':
+                        data = '\\u%04X' % ord(ch)
                     else:
-                        data = u'\\U%08X' % ord(ch)
+                        data = '\\U%08X' % ord(ch)
                     self.column += len(data)
-                    if self.encoding:
-                        data = data.encode(self.encoding)
                     self.stream.write(data)
                     start = end+1
-            if 0 < end < len(text)-1 and (ch == u' ' or start >= end)   \
+            if 0 < end < len(text)-1 and (ch == ' ' or start >= end)   \
                     and self.column+(end-start) > self.best_width and split:
-                data = text[start:end]+u'\\'
+                data = text[start:end]+'\\'
                 if start < end:
                     start = end
                 self.column += len(data)
-                if self.encoding:
-                    data = data.encode(self.encoding)
                 self.stream.write(data)
                 self.write_indent()
                 self.whitespace = False
                 self.indention = False
-                if text[start] == u' ':
-                    data = u'\\'
+                if text[start] == ' ':
+                    data = '\\'
                     self.column += len(data)
-                    if self.encoding:
-                        data = data.encode(self.encoding)
                     self.stream.write(data)
             end += 1
-        self.write_indicator(u'"', False)
+        self.write_indicator('"', False)
 
     def determine_chomp(self, text):
         tail = text[-2:]
         while len(tail) < 2:
-            tail = u' '+tail
-        if tail[-1] in u'\n\x85\u2028\u2029':
-            if tail[-2] in u'\n\x85\u2028\u2029':
-                return u'+'
+            tail = ' '+tail
+        if tail[-1] in '\n\x85\u2028\u2029':
+            if tail[-2] in '\n\x85\u2028\u2029':
+                return '+'
             else:
-                return u''
+                return ''
         else:
-            return u'-'
+            return '-'
 
     def write_folded(self, text):
         chomp = self.determine_chomp(text)
-        self.write_indicator(u'>'+chomp, True)
+        self.write_indicator('>'+chomp, True)
         self.write_indent()
         leading_space = False
         spaces = False
@@ -1033,13 +1008,13 @@ class Emitter(object):
             if end < len(text):
                 ch = text[end]
             if breaks:
-                if ch is None or ch not in u'\n\x85\u2028\u2029':
-                    if not leading_space and ch is not None and ch != u' '  \
-                            and text[start] == u'\n':
+                if ch is None or ch not in '\n\x85\u2028\u2029':
+                    if not leading_space and ch is not None and ch != ' '  \
+                            and text[start] == '\n':
                         self.write_line_break()
-                    leading_space = (ch == u' ')
+                    leading_space = (ch == ' ')
                     for br in text[start:end]:
-                        if br == u'\n':
+                        if br == '\n':
                             self.write_line_break()
                         else:
                             self.write_line_break(br)
@@ -1047,33 +1022,29 @@ class Emitter(object):
                         self.write_indent()
                     start = end
             elif spaces:
-                if ch != u' ':
+                if ch != ' ':
                     if start+1 == end and self.column > self.best_width:
                         self.write_indent()
                     else:
                         data = text[start:end]
                         self.column += len(data)
-                        if self.encoding:
-                            data = data.encode(self.encoding)
                         self.stream.write(data)
                     start = end
             else:
-                if ch is None or ch in u' \n\x85\u2028\u2029':
+                if ch is None or ch in ' \n\x85\u2028\u2029':
                     data = text[start:end]
-                    if self.encoding:
-                        data = data.encode(self.encoding)
                     self.stream.write(data)
                     if ch is None:
                         self.write_line_break()
                     start = end
             if ch is not None:
-                breaks = (ch in u'\n\x85\u2028\u2029')
-                spaces = (ch == u' ')
+                breaks = (ch in '\n\x85\u2028\u2029')
+                spaces = (ch == ' ')
             end += 1
 
     def write_literal(self, text):
         chomp = self.determine_chomp(text)
-        self.write_indicator(u'|'+chomp, True)
+        self.write_indicator('|'+chomp, True)
         self.write_indent()
         breaks = False
         start = end = 0
@@ -1082,9 +1053,9 @@ class Emitter(object):
             if end < len(text):
                 ch = text[end]
             if breaks:
-                if ch is None or ch not in u'\n\x85\u2028\u2029':
+                if ch is None or ch not in '\n\x85\u2028\u2029':
                     for br in text[start:end]:
-                        if br == u'\n':
+                        if br == '\n':
                             self.write_line_break()
                         else:
                             self.write_line_break(br)
@@ -1092,26 +1063,22 @@ class Emitter(object):
                         self.write_indent()
                     start = end
             else:
-                if ch is None or ch in u'\n\x85\u2028\u2029':
+                if ch is None or ch in '\n\x85\u2028\u2029':
                     data = text[start:end]
-                    if self.encoding:
-                        data = data.encode(self.encoding)
                     self.stream.write(data)
                     if ch is None:
                         self.write_line_break()
                     start = end
             if ch is not None:
-                breaks = (ch in u'\n\x85\u2028\u2029')
+                breaks = (ch in '\n\x85\u2028\u2029')
             end += 1
 
     def write_plain(self, text, split=True):
         if not text:
             return
         if not self.whitespace:
-            data = u' '
+            data = ' '
             self.column += len(data)
-            if self.encoding:
-                data = data.encode(self.encoding)
             self.stream.write(data)
         self.writespace = False
         self.indention = False
@@ -1123,7 +1090,7 @@ class Emitter(object):
             if end < len(text):
                 ch = text[end]
             if spaces:
-                if ch != u' ':
+                if ch != ' ':
                     if start+1 == end and self.column > self.best_width and split:
                         self.write_indent()
                         self.writespace = False
@@ -1131,16 +1098,14 @@ class Emitter(object):
                     else:
                         data = text[start:end]
                         self.column += len(data)
-                        if self.encoding:
-                            data = data.encode(self.encoding)
                         self.stream.write(data)
                     start = end
             elif breaks:
-                if ch not in u'\n\x85\u2028\u2029':
-                    if text[start] == u'\n':
+                if ch not in '\n\x85\u2028\u2029':
+                    if text[start] == '\n':
                         self.write_line_break()
                     for br in text[start:end]:
-                        if br == u'\n':
+                        if br == '\n':
                             self.write_line_break()
                         else:
                             self.write_line_break(br)
@@ -1149,15 +1114,13 @@ class Emitter(object):
                     self.indention = False
                     start = end
             else:
-                if ch is None or ch in u' \n\x85\u2028\u2029':
+                if ch is None or ch in ' \n\x85\u2028\u2029':
                     data = text[start:end]
                     self.column += len(data)
-                    if self.encoding:
-                        data = data.encode(self.encoding)
                     self.stream.write(data)
                     start = end
             if ch is not None:
-                spaces = (ch == u' ')
-                breaks = (ch in u'\n\x85\u2028\u2029')
+                spaces = (ch == ' ')
+                breaks = (ch in '\n\x85\u2028\u2029')
             end += 1
 
diff --git lib/yaml/error.py lib/yaml/error.py
index 577686d..b796b4d 100644
--- lib/yaml/error.py
+++ lib/yaml/error.py
@@ -1,7 +1,7 @@
 
 __all__ = ['Mark', 'YAMLError', 'MarkedYAMLError']
 
-class Mark(object):
+class Mark:
 
     def __init__(self, name, index, line, column, buffer, pointer):
         self.name = name
@@ -16,7 +16,7 @@ class Mark(object):
             return None
         head = ''
         start = self.pointer
-        while start > 0 and self.buffer[start-1] not in u'\0\r\n\x85\u2028\u2029':
+        while start > 0 and self.buffer[start-1] not in '\0\r\n\x85\u2028\u2029':
             start -= 1
             if self.pointer-start > max_length/2-1:
                 head = ' ... '
@@ -24,13 +24,13 @@ class Mark(object):
                 break
         tail = ''
         end = self.pointer
-        while end < len(self.buffer) and self.buffer[end] not in u'\0\r\n\x85\u2028\u2029':
+        while end < len(self.buffer) and self.buffer[end] not in '\0\r\n\x85\u2028\u2029':
             end += 1
             if end-self.pointer > max_length/2-1:
                 tail = ' ... '
                 end -= 5
                 break
-        snippet = self.buffer[start:end].encode('utf-8')
+        snippet = self.buffer[start:end]
         return ' '*indent + head + snippet + tail + '\n'  \
                 + ' '*(indent+self.pointer-start+len(head)) + '^'
 
diff --git lib/yaml/events.py lib/yaml/events.py
index f79ad38..3f244fa 100644
--- lib/yaml/events.py
+++ lib/yaml/events.py
@@ -1,7 +1,7 @@
 
 # Abstract classes.
 
-class Event(object):
+class Event:
     def __init__(self, start_mark=None, end_mark=None):
         self.start_mark = start_mark
         self.end_mark = end_mark
diff --git lib/yaml/loader.py lib/yaml/loader.py
index 293ff46..efde149 100644
--- lib/yaml/loader.py
+++ lib/yaml/loader.py
@@ -1,12 +1,12 @@
 
 __all__ = ['BaseLoader', 'SafeLoader', 'Loader']
 
-from reader import *
-from scanner import *
-from parser import *
-from composer import *
-from constructor import *
-from resolver import *
+from yaml.reader import *
+from yaml.scanner import *
+from yaml.parser import *
+from yaml.composer import *
+from yaml.constructor import *
+from yaml.resolver import *
 
 class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, BaseResolver):
 
diff --git lib/yaml/nodes.py lib/yaml/nodes.py
index c4f070c..59cb70d 100644
--- lib/yaml/nodes.py
+++ lib/yaml/nodes.py
@@ -1,5 +1,5 @@
 
-class Node(object):
+class Node:
     def __init__(self, tag, value, start_mark, end_mark):
         self.tag = tag
         self.value = value
@@ -22,6 +22,14 @@ class Node(object):
         value = repr(value)
         return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value)
 
+    def __lt__(self, other):
+        if isinstance(other, Node):
+            return self.value < other.value
+        return super.__lt__(self, other)
+
+    def __hash__(self):
+        return id(self)
+
 class ScalarNode(Node):
     id = 'scalar'
     def __init__(self, tag, value,
diff --git lib/yaml/parser.py lib/yaml/parser.py
index a46bb9e..51c6dc8 100644
--- lib/yaml/parser.py
+++ lib/yaml/parser.py
@@ -61,23 +61,23 @@
 
 __all__ = ['Parser', 'ParserError']
 
-from error import MarkedYAMLError
-from tokens import *
-from events import *
-from scanner import *
+from yaml.error import MarkedYAMLError
+from yaml.tokens import *
+from yaml.events import *
+from yaml.scanner import *
 
 class ParserError(MarkedYAMLError):
     pass
 
-class Parser(object):
+class Parser:
     # Since writing a recursive-descendant parser is a straightforward task, we
     # do not give many comments here.
     # Note that we use Python generators. If you rewrite the parser in another
     # language, you may replace all 'yield'-s with event handler calls.
 
     DEFAULT_TAGS = {
-        u'!':   u'!',
-        u'!!':  u'tag:yaml.org,2002:',
+        '!':   '!',
+        '!!':  'tag:yaml.org,2002:',
     }
 
     def __init__(self):
@@ -216,7 +216,7 @@ class Parser(object):
         self.tag_handles = {}
         while self.check_token(DirectiveToken):
             token = self.get_token()
-            if token.name == u'YAML':
+            if token.name == 'YAML':
                 if self.yaml_version is not None:
                     raise ParserError(None, None,
                             "found duplicate YAML directive", token.start_mark)
@@ -226,7 +226,7 @@ class Parser(object):
                             "found incompatible YAML document (version 1.* is required)",
                             token.start_mark)
                 self.yaml_version = token.value
-            elif token.name == u'TAG':
+            elif token.name == 'TAG':
                 handle, prefix = token.value
                 if handle in self.tag_handles:
                     raise ParserError(None, None,
@@ -305,14 +305,14 @@ class Parser(object):
                     tag = self.tag_handles[handle]+suffix
                 else:
                     tag = suffix
-            #if tag == u'!':
+            #if tag == '!':
             #    raise ParserError("while parsing a node", start_mark,
             #            "found non-specific tag '!'", tag_mark,
             #            "Please check 'http://pyyaml.org/wiki/YAMLNonSpecificTag' and share your opinion.")
             if start_mark is None:
                 start_mark = end_mark = self.peek_token().start_mark
             event = None
-            implicit = (tag is None or tag == u'!')
+            implicit = (tag is None or tag == '!')
             if indentless_sequence and self.check_token(BlockEntryToken):
                 end_mark = self.peek_token().end_mark
                 event = SequenceStartEvent(anchor, tag, implicit,
@@ -322,7 +322,7 @@ class Parser(object):
                 if self.check_token(ScalarToken):
                     token = self.get_token()
                     end_mark = token.end_mark
-                    if (token.plain and tag is None) or tag == u'!':
+                    if (token.plain and tag is None) or tag == '!':
                         implicit = (True, False)
                     elif tag is None:
                         implicit = (False, True)
@@ -354,7 +354,7 @@ class Parser(object):
                 elif anchor is not None or tag is not None:
                     # Empty scalars are allowed even if a tag or an anchor is
                     # specified.
-                    event = ScalarEvent(anchor, tag, (implicit, False), u'',
+                    event = ScalarEvent(anchor, tag, (implicit, False), '',
                             start_mark, end_mark)
                     self.state = self.states.pop()
                 else:
@@ -582,5 +582,5 @@ class Parser(object):
         return self.process_empty_scalar(self.peek_token().start_mark)
 
     def process_empty_scalar(self, mark):
-        return ScalarEvent(None, None, (True, False), u'', mark, mark)
+        return ScalarEvent(None, None, (True, False), '', mark, mark)
 
diff --git lib/yaml/reader.py lib/yaml/reader.py
index 1d4667c..1998ce2 100644
--- lib/yaml/reader.py
+++ lib/yaml/reader.py
@@ -17,44 +17,9 @@
 
 __all__ = ['Reader', 'ReaderError']
 
-from error import YAMLError, Mark
-
-import codecs, re
-
-# Unfortunately, codec functions in Python 2.3 does not support the `finish`
-# arguments, so we have to write our own wrappers.
-
-try:
-    codecs.utf_8_decode('', 'strict', False)
-    from codecs import utf_8_decode, utf_16_le_decode, utf_16_be_decode
-
-except TypeError:
-
-    def utf_16_le_decode(data, errors, finish=False):
-        if not finish and len(data) % 2 == 1:
-            data = data[:-1]
-        return codecs.utf_16_le_decode(data, errors)
-
-    def utf_16_be_decode(data, errors, finish=False):
-        if not finish and len(data) % 2 == 1:
-            data = data[:-1]
-        return codecs.utf_16_be_decode(data, errors)
-
-    def utf_8_decode(data, errors, finish=False):
-        if not finish:
-            # We are trying to remove a possible incomplete multibyte character
-            # from the suffix of the data.
-            # The first byte of a multi-byte sequence is in the range 0xc0 to 0xfd.
-            # All further bytes are in the range 0x80 to 0xbf.
-            # UTF-8 encoded UCS characters may be up to six bytes long.
-            count = 0
-            while count < 5 and count < len(data)   \
-                    and '\x80' <= data[-count-1] <= '\xBF':
-                count -= 1
-            if count < 5 and count < len(data)  \
-                    and '\xC0' <= data[-count-1] <= '\xFD':
-                data = data[:-count-1]
-        return codecs.utf_8_decode(data, errors)
+from yaml.error import YAMLError, Mark
+
+import codecs, re, io
 
 class ReaderError(YAMLError):
 
@@ -66,18 +31,18 @@ class ReaderError(YAMLError):
         self.reason = reason
 
     def __str__(self):
-        if isinstance(self.character, str):
-            return "'%s' codec can't decode byte #x%02x: %s\n"  \
+        if isinstance(self.character, bytes):
+            return "'%s' codec can't decode #x%02x: %s\n"  \
                     "  in \"%s\", position %d"    \
                     % (self.encoding, ord(self.character), self.reason,
                             self.name, self.position)
         else:
-            return "unacceptable character #x%04x: %s\n"    \
+            return "unacceptable character %r: %s\n"    \
                     "  in \"%s\", position %d"    \
-                    % (ord(self.character), self.reason,
+                    % (self.character, self.reason,
                             self.name, self.position)
 
-class Reader(object):
+class Reader:
     # Reader:
     # - determines the data encoding and converts it to unicode,
     # - checks if characters are in allowed range,
@@ -96,7 +61,7 @@ class Reader(object):
         self.stream = None
         self.stream_pointer = 0
         self.eof = True
-        self.buffer = u''
+        self.buffer = ''
         self.pointer = 0
         self.raw_buffer = None
         self.raw_decode = None
@@ -104,11 +69,11 @@ class Reader(object):
         self.index = 0
         self.line = 0
         self.column = 0
-        if isinstance(stream, unicode):
+        if isinstance(stream, str):
             self.name = "<unicode string>"
             self.check_printable(stream)
-            self.buffer = stream+u'\0'
-        elif isinstance(stream, str):
+            self.buffer = stream+'\0'
+        elif isinstance(stream, bytes):
             self.name = "<string>"
             self.raw_buffer = stream
             self.determine_encoding()
@@ -116,7 +81,7 @@ class Reader(object):
             self.stream = stream
             self.name = getattr(stream, 'name', "<file>")
             self.eof = False
-            self.raw_buffer = ''
+            self.raw_buffer = None
             self.determine_encoding()
 
     def peek(self, index=0):
@@ -138,11 +103,11 @@ class Reader(object):
             ch = self.buffer[self.pointer]
             self.pointer += 1
             self.index += 1
-            if ch in u'\n\x85\u2028\u2029'  \
-                    or (ch == u'\r' and self.buffer[self.pointer] != u'\n'):
+            if ch in '\n\x85\u2028\u2029'  \
+                    or (ch == '\r' and self.buffer[self.pointer] != '\n'):
                 self.line += 1
                 self.column = 0
-            elif ch != u'\uFEFF':
+            elif ch != '\uFEFF':
                 self.column += 1
             length -= 1
 
@@ -155,21 +120,21 @@ class Reader(object):
                     None, None)
 
     def determine_encoding(self):
-        while not self.eof and len(self.raw_buffer) < 2:
+        while not self.eof and (self.raw_buffer is None or len(self.raw_buffer) < 2):
             self.update_raw()
-        if not isinstance(self.raw_buffer, unicode):
+        if not isinstance(self.raw_buffer, str):
             if self.raw_buffer.startswith(codecs.BOM_UTF16_LE):
-                self.raw_decode = utf_16_le_decode
+                self.raw_decode = codecs.utf_16_le_decode
                 self.encoding = 'utf-16-le'
             elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE):
-                self.raw_decode = utf_16_be_decode
+                self.raw_decode = codecs.utf_16_be_decode
                 self.encoding = 'utf-16-be'
             else:
-                self.raw_decode = utf_8_decode
+                self.raw_decode = codecs.utf_8_decode
                 self.encoding = 'utf-8'
         self.update(1)
 
-    NON_PRINTABLE = re.compile(u'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]')
+    NON_PRINTABLE = re.compile('[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]')
     def check_printable(self, data):
         match = self.NON_PRINTABLE.search(data)
         if match:
@@ -190,14 +155,14 @@ class Reader(object):
                 try:
                     data, converted = self.raw_decode(self.raw_buffer,
                             'strict', self.eof)
-                except UnicodeDecodeError, exc:
+                except UnicodeDecodeError as exc:
                     character = exc.object[exc.start]
                     if self.stream is not None:
                         position = self.stream_pointer-len(self.raw_buffer)+exc.start
                     else:
                         position = exc.start
                     raise ReaderError(self.name, position, character,
-                            exc.encoding, exc.reason)
+                            exc.encoding, exc.reason) from exc
             else:
                 data = self.raw_buffer
                 converted = len(data)
@@ -205,16 +170,21 @@ class Reader(object):
             self.buffer += data
             self.raw_buffer = self.raw_buffer[converted:]
             if self.eof:
-                self.buffer += u'\0'
+                self.buffer += '\0'
                 self.raw_buffer = None
                 break
 
     def update_raw(self, size=1024):
         data = self.stream.read(size)
         if data:
-            self.raw_buffer += data
-            self.stream_pointer += len(data)
+            if self.raw_buffer is None:
+                self.raw_buffer = data
+            else:
+                self.raw_buffer += data
+                self.stream_pointer += len(data)
         else:
+            if self.raw_buffer is None:
+                self.raw_buffer = b''
             self.eof = True
 
 #try:
diff --git lib/yaml/representer.py lib/yaml/representer.py
index 1f4fe59..5c9a76f 100644
--- lib/yaml/representer.py
+++ lib/yaml/representer.py
@@ -2,22 +2,17 @@
 __all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer',
     'RepresenterError']
 
-from error import *
-from nodes import *
+from yaml.error import *
+from yaml.nodes import *
 
-import datetime
+import datetime, base64
 
-try:
-    set
-except NameError:
-    from sets import Set as set
-
-import sys, copy_reg, types
+import sys, copyreg, types
 
 class RepresenterError(YAMLError):
     pass
 
-class BaseRepresenter(object):
+class BaseRepresenter:
 
     yaml_representers = {}
     yaml_multi_representers = {}
@@ -56,8 +51,6 @@ class BaseRepresenter(object):
             #self.represented_objects[alias_key] = None
             self.object_keeper.append(data)
         data_types = type(data).__mro__
-        if type(data) is types.InstanceType:
-            data_types = self.get_classobj_bases(data.__class__)+list(data_types)
         if data_types[0] in self.yaml_representers:
             node = self.yaml_representers[data_types[0]](self, data)
         else:
@@ -71,7 +64,7 @@ class BaseRepresenter(object):
                 elif None in self.yaml_representers:
                     node = self.yaml_representers[None](self, data)
                 else:
-                    node = ScalarNode(None, unicode(data))
+                    node = ScalarNode(None, str(data))
         #if alias_key is not None:
         #    self.represented_objects[alias_key] = node
         return node
@@ -121,8 +114,7 @@ class BaseRepresenter(object):
             self.represented_objects[self.alias_key] = node
         best_style = True
         if hasattr(mapping, 'items'):
-            mapping = mapping.items()
-            mapping.sort()
+            mapping = list(mapping.items())
         for item_key, item_value in mapping:
             node_key = self.represent_data(item_key)
             node_value = self.represent_data(item_value)
@@ -131,6 +123,7 @@ class BaseRepresenter(object):
             if not (isinstance(node_value, ScalarNode) and not node_value.style):
                 best_style = False
             value.append((node_key, node_value))
+        value.sort()
         if flow_style is None:
             if self.default_flow_style is not None:
                 node.flow_style = self.default_flow_style
@@ -146,44 +139,41 @@ class SafeRepresenter(BaseRepresenter):
     def ignore_aliases(self, data):
         if data in [None, ()]:
             return True
-        if isinstance(data, (str, unicode, bool, int, float)):
+        if isinstance(data, (str, bytes, bool, int, float)):
             return True
 
     def represent_none(self, data):
-        return self.represent_scalar(u'tag:yaml.org,2002:null',
-                u'null')
+        return self.represent_scalar('tag:yaml.org,2002:null',
+                'null')
 
-    def represent_str(self, data):
+    def represent_bytes(self, data):
         tag = None
         style = None
         try:
-            data = unicode(data, 'ascii')
-            tag = u'tag:yaml.org,2002:str'
+            data = data.decode('ascii')
+            tag = 'tag:yaml.org,2002:python/bytes'
         except UnicodeDecodeError:
             try:
-                data = unicode(data, 'utf-8')
-                tag = u'tag:yaml.org,2002:str'
+                data = data.decode('utf-8')
+                tag = 'tag:yaml.org,2002:python/bytes'
             except UnicodeDecodeError:
-                data = data.encode('base64')
-                tag = u'tag:yaml.org,2002:binary'
+                data = base64.b64encode(data).decode('ascii')
+                tag = 'tag:yaml.org,2002:binary'
                 style = '|'
         return self.represent_scalar(tag, data, style=style)
 
-    def represent_unicode(self, data):
-        return self.represent_scalar(u'tag:yaml.org,2002:str', data)
+    def represent_str(self, data):
+        return self.represent_scalar('tag:yaml.org,2002:str', data)
 
     def represent_bool(self, data):
         if data:
-            value = u'true'
+            value = 'true'
         else:
-            value = u'false'
-        return self.represent_scalar(u'tag:yaml.org,2002:bool', value)
+            value = 'false'
+        return self.represent_scalar('tag:yaml.org,2002:bool', value)
 
     def represent_int(self, data):
-        return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data))
-
-    def represent_long(self, data):
-        return self.represent_scalar(u'tag:yaml.org,2002:int', unicode(data))
+        return self.represent_scalar('tag:yaml.org,2002:int', str(data))
 
     inf_value = 1e300
     while repr(inf_value) != repr(inf_value*inf_value):
@@ -191,13 +181,13 @@ class SafeRepresenter(BaseRepresenter):
 
     def represent_float(self, data):
         if data != data or (data == 0.0 and data == 1.0):
-            value = u'.nan'
+            value = '.nan'
         elif data == self.inf_value:
-            value = u'.inf'
+            value = '.inf'
         elif data == -self.inf_value:
-            value = u'-.inf'
+            value = '-.inf'
         else:
-            value = unicode(repr(data)).lower()
+            value = str(repr(data)).lower()
             # Note that in some cases `repr(data)` represents a float number
             # without the decimal parts.  For instance:
             #   >>> repr(1e17)
@@ -205,9 +195,9 @@ class SafeRepresenter(BaseRepresenter):
             # Unfortunately, this is not a valid float representation according
             # to the definition of the `!!float` tag.  We fix this by adding
             # '.0' before the 'e' symbol.
-            if u'.' not in value and u'e' in value:
-                value = value.replace(u'e', u'.0e', 1)
-        return self.represent_scalar(u'tag:yaml.org,2002:float', value)
+            if '.' not in value and 'e' in value:
+                value = value.replace('e', '.0e', 1)
+        return self.represent_scalar('tag:yaml.org,2002:float', value)
 
     def represent_list(self, data):
         #pairs = (len(data) > 0 and isinstance(data, list))
@@ -217,29 +207,29 @@ class SafeRepresenter(BaseRepresenter):
         #            pairs = False
         #            break
         #if not pairs:
-            return self.represent_sequence(u'tag:yaml.org,2002:seq', data)
+            return self.represent_sequence('tag:yaml.org,2002:seq', data)
         #value = []
         #for item_key, item_value in data:
-        #    value.append(self.represent_mapping(u'tag:yaml.org,2002:map',
+        #    value.append(self.represent_mapping('tag:yaml.org,2002:map',
         #        [(item_key, item_value)]))
-        #return SequenceNode(u'tag:yaml.org,2002:pairs', value)
+        #return SequenceNode('tag:yaml.org,2002:pairs', value)
 
     def represent_dict(self, data):
-        return self.represent_mapping(u'tag:yaml.org,2002:map', data)
+        return self.represent_mapping('tag:yaml.org,2002:map', data)
 
     def represent_set(self, data):
         value = {}
         for key in data:
             value[key] = None
-        return self.represent_mapping(u'tag:yaml.org,2002:set', value)
+        return self.represent_mapping('tag:yaml.org,2002:set', value)
 
     def represent_date(self, data):
-        value = unicode(data.isoformat())
-        return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value)
+        value = str(data.isoformat())
+        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
 
     def represent_datetime(self, data):
-        value = unicode(data.isoformat(' '))
-        return self.represent_scalar(u'tag:yaml.org,2002:timestamp', value)
+        value = str(data.isoformat(' '))
+        return self.represent_scalar('tag:yaml.org,2002:timestamp', value)
 
     def represent_yaml_object(self, tag, data, cls, flow_style=None):
         if hasattr(data, '__getstate__'):
@@ -257,18 +247,12 @@ SafeRepresenter.add_representer(type(None),
 SafeRepresenter.add_representer(str,
         SafeRepresenter.represent_str)
 
-SafeRepresenter.add_representer(unicode,
-        SafeRepresenter.represent_unicode)
-
 SafeRepresenter.add_representer(bool,
         SafeRepresenter.represent_bool)
 
 SafeRepresenter.add_representer(int,
         SafeRepresenter.represent_int)
 
-SafeRepresenter.add_representer(long,
-        SafeRepresenter.represent_long)
-
 SafeRepresenter.add_representer(float,
         SafeRepresenter.represent_float)
 
@@ -294,99 +278,47 @@ SafeRepresenter.add_representer(None,
 
 class Representer(SafeRepresenter):
 
-    def represent_str(self, data):
+    def represent_bytes(self, data):
         tag = None
         style = None
         try:
-            data = unicode(data, 'ascii')
-            tag = u'tag:yaml.org,2002:str'
+            data = data.decode('ascii')
+            tag = 'tag:yaml.org,2002:python/bytes'
         except UnicodeDecodeError:
             try:
-                data = unicode(data, 'utf-8')
-                tag = u'tag:yaml.org,2002:python/str'
+                data = data.decode('utf-8')
+                tag = 'tag:yaml.org,2002:python/bytes'
             except UnicodeDecodeError:
-                data = data.encode('base64')
-                tag = u'tag:yaml.org,2002:binary'
+                data = base64.b64encode(data).decode('ascii')
+                tag = 'tag:yaml.org,2002:binary'
                 style = '|'
         return self.represent_scalar(tag, data, style=style)
 
-    def represent_unicode(self, data):
-        tag = None
-        try:
-            data.encode('ascii')
-            tag = u'tag:yaml.org,2002:python/unicode'
-        except UnicodeEncodeError:
-            tag = u'tag:yaml.org,2002:str'
+    def represent_str(self, data):
+        tag = 'tag:yaml.org,2002:str'
         return self.represent_scalar(tag, data)
 
-    def represent_long(self, data):
-        tag = u'tag:yaml.org,2002:int'
-        if int(data) is not data:
-            tag = u'tag:yaml.org,2002:python/long'
-        return self.represent_scalar(tag, unicode(data))
-
     def represent_complex(self, data):
         if data.imag == 0.0:
-            data = u'%r' % data.real
+            data = '%r' % data.real
         elif data.real == 0.0:
-            data = u'%rj' % data.imag
+            data = '%rj' % data.imag
         elif data.imag > 0:
-            data = u'%r+%rj' % (data.real, data.imag)
+            data = '%r+%rj' % (data.real, data.imag)
         else:
-            data = u'%r%rj' % (data.real, data.imag)
-        return self.represent_scalar(u'tag:yaml.org,2002:python/complex', data)
+            data = '%r%rj' % (data.real, data.imag)
+        return self.represent_scalar('tag:yaml.org,2002:python/complex', data)
 
     def represent_tuple(self, data):
-        return self.represent_sequence(u'tag:yaml.org,2002:python/tuple', data)
+        return self.represent_sequence('tag:yaml.org,2002:python/tuple', data)
 
     def represent_name(self, data):
-        name = u'%s.%s' % (data.__module__, data.__name__)
-        return self.represent_scalar(u'tag:yaml.org,2002:python/name:'+name, u'')
+        name = '%s.%s' % (data.__module__, data.__name__)
+        return self.represent_scalar('tag:yaml.org,2002:python/name:'+name, '')
 
     def represent_module(self, data):
         return self.represent_scalar(
-                u'tag:yaml.org,2002:python/module:'+data.__name__, u'')
-
-    def represent_instance(self, data):
-        # For instances of classic classes, we use __getinitargs__ and
-        # __getstate__ to serialize the data.
-
-        # If data.__getinitargs__ exists, the object must be reconstructed by
-        # calling cls(**args), where args is a tuple returned by
-        # __getinitargs__. Otherwise, the cls.__init__ method should never be
-        # called and the class instance is created by instantiating a trivial
-        # class and assigning to the instance's __class__ variable.
-
-        # If data.__getstate__ exists, it returns the state of the object.
-        # Otherwise, the state of the object is data.__dict__.
-
-        # We produce either a !!python/object or !!python/object/new node.
-        # If data.__getinitargs__ does not exist and state is a dictionary, we
-        # produce a !!python/object node . Otherwise we produce a
-        # !!python/object/new node.
-
-        cls = data.__class__
-        class_name = u'%s.%s' % (cls.__module__, cls.__name__)
-        args = None
-        state = None
-        if hasattr(data, '__getinitargs__'):
-            args = list(data.__getinitargs__())
-        if hasattr(data, '__getstate__'):
-            state = data.__getstate__()
-        else:
-            state = data.__dict__
-        if args is None and isinstance(state, dict):
-            return self.represent_mapping(
-                    u'tag:yaml.org,2002:python/object:'+class_name, state)
-        if isinstance(state, dict) and not state:
-            return self.represent_sequence(
-                    u'tag:yaml.org,2002:python/object/new:'+class_name, args)
-        value = {}
-        if args:
-            value['args'] = args
-        value['state'] = state
-        return self.represent_mapping(
-                u'tag:yaml.org,2002:python/object/new:'+class_name, value)
+                'tag:yaml.org,2002:python/module:'+data.__name__, '')
 
     def represent_object(self, data):
         # We use __reduce__ API to save the data. data.__reduce__ returns
@@ -406,8 +338,8 @@ class Representer(SafeRepresenter):
         # !!python/object/apply node.
 
         cls = type(data)
-        if cls in copy_reg.dispatch_table:
-            reduce = copy_reg.dispatch_table[cls](data)
+        if cls in copyreg.dispatch_table:
+            reduce = copyreg.dispatch_table[cls](data)
         elif hasattr(data, '__reduce_ex__'):
             reduce = data.__reduce_ex__(2)
         elif hasattr(data, '__reduce__'):
@@ -426,16 +358,16 @@ class Representer(SafeRepresenter):
         if function.__name__ == '__newobj__':
             function = args[0]
             args = args[1:]
-            tag = u'tag:yaml.org,2002:python/object/new:'
+            tag = 'tag:yaml.org,2002:python/object/new:'
             newobj = True
         else:
-            tag = u'tag:yaml.org,2002:python/object/apply:'
+            tag = 'tag:yaml.org,2002:python/object/apply:'
             newobj = False
-        function_name = u'%s.%s' % (function.__module__, function.__name__)
+        function_name = '%s.%s' % (function.__module__, function.__name__)
         if not args and not listitems and not dictitems \
                 and isinstance(state, dict) and newobj:
             return self.represent_mapping(
-                    u'tag:yaml.org,2002:python/object:'+function_name, state)
+                    'tag:yaml.org,2002:python/object:'+function_name, state)
         if not listitems and not dictitems  \
                 and isinstance(state, dict) and not state:
             return self.represent_sequence(tag+function_name, args)
@@ -453,11 +385,8 @@ class Representer(SafeRepresenter):
 Representer.add_representer(str,
         Representer.represent_str)
 
-Representer.add_representer(unicode,
-        Representer.represent_unicode)
-
-Representer.add_representer(long,
-        Representer.represent_long)
+Representer.add_representer(bytes,
+        Representer.represent_bytes)
 
 Representer.add_representer(complex,
         Representer.represent_complex)
@@ -468,9 +397,6 @@ Representer.add_representer(tuple,
 Representer.add_representer(type,
         Representer.represent_name)
 
-Representer.add_representer(types.ClassType,
-        Representer.represent_name)
-
 Representer.add_representer(types.FunctionType,
         Representer.represent_name)
 
@@ -480,9 +406,6 @@ Representer.add_representer(types.BuiltinFunctionType,
 Representer.add_representer(types.ModuleType,
         Representer.represent_module)
 
-Representer.add_multi_representer(types.InstanceType,
-        Representer.represent_instance)
-
 Representer.add_multi_representer(object,
         Representer.represent_object)
 
diff --git lib/yaml/resolver.py lib/yaml/resolver.py
index 60c43e3..08f121f 100644
--- lib/yaml/resolver.py
+++ lib/yaml/resolver.py
@@ -1,19 +1,19 @@
 
 __all__ = ['BaseResolver', 'Resolver']
 
-from error import *
-from nodes import *
+from yaml.error import *
+from yaml.nodes import *
 
 import re
 
 class ResolverError(YAMLError):
     pass
 
-class BaseResolver(object):
+class BaseResolver:
 
-    DEFAULT_SCALAR_TAG = u'tag:yaml.org,2002:str'
-    DEFAULT_SEQUENCE_TAG = u'tag:yaml.org,2002:seq'
-    DEFAULT_MAPPING_TAG = u'tag:yaml.org,2002:map'
+    DEFAULT_SCALAR_TAG = 'tag:yaml.org,2002:str'
+    DEFAULT_SEQUENCE_TAG = 'tag:yaml.org,2002:seq'
+    DEFAULT_MAPPING_TAG = 'tag:yaml.org,2002:map'
 
     yaml_implicit_resolvers = {}
     yaml_path_resolvers = {}
@@ -66,10 +66,10 @@ class BaseResolver(object):
             elif node_check is dict:
                 node_check = MappingNode
             elif node_check not in [ScalarNode, SequenceNode, MappingNode]  \
-                    and not isinstance(node_check, basestring)  \
+                    and not isinstance(node_check, str)  \
                     and node_check is not None:
                 raise ResolverError("Invalid node checker: %s" % node_check)
-            if not isinstance(index_check, (basestring, int))   \
+            if not isinstance(index_check, (str, int))   \
                     and index_check is not None:
                 raise ResolverError("Invalid index checker: %s" % index_check)
             new_path.append((node_check, index_check))
@@ -117,7 +117,7 @@ class BaseResolver(object):
     def check_resolver_prefix(self, depth, path, kind,
             current_node, current_index):
         node_check, index_check = path[depth-1]
-        if isinstance(node_check, basestring):
+        if isinstance(node_check, str):
             if current_node.tag != node_check:
                 return
         elif node_check is not None:
@@ -128,7 +128,7 @@ class BaseResolver(object):
         if (index_check is False or index_check is None)    \
                 and current_index is None:
             return
-        if isinstance(index_check, basestring):
+        if isinstance(index_check, str):
             if not (isinstance(current_index, ScalarNode)
                     and index_check == current_index.value):
                 return
@@ -139,8 +139,8 @@ class BaseResolver(object):
 
     def resolve(self, kind, value, implicit):
         if kind is ScalarNode and implicit[0]:
-            if value == u'':
-                resolvers = self.yaml_implicit_resolvers.get(u'', [])
+            if value == '':
+                resolvers = self.yaml_implicit_resolvers.get('', [])
             else:
                 resolvers = self.yaml_implicit_resolvers.get(value[0], [])
             resolvers += self.yaml_implicit_resolvers.get(None, [])
@@ -165,60 +165,60 @@ class Resolver(BaseResolver):
     pass
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:bool',
-        re.compile(ur'''^(?:yes|Yes|YES|no|No|NO
+        'tag:yaml.org,2002:bool',
+        re.compile(r'''^(?:yes|Yes|YES|no|No|NO
                     |true|True|TRUE|false|False|FALSE
                     |on|On|ON|off|Off|OFF)$''', re.X),
-        list(u'yYnNtTfFoO'))
+        list('yYnNtTfFoO'))
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:float',
-        re.compile(ur'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)?
+        'tag:yaml.org,2002:float',
+        re.compile(r'''^(?:[-+]?(?:[0-9][0-9_]*)\.[0-9_]*(?:[eE][-+][0-9]+)?
                     |\.[0-9_]+(?:[eE][-+][0-9]+)?
                     |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\.[0-9_]*
                     |[-+]?\.(?:inf|Inf|INF)
                     |\.(?:nan|NaN|NAN))$''', re.X),
-        list(u'-+0123456789.'))
+        list('-+0123456789.'))
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:int',
-        re.compile(ur'''^(?:[-+]?0b[0-1_]+
+        'tag:yaml.org,2002:int',
+        re.compile(r'''^(?:[-+]?0b[0-1_]+
                     |[-+]?0[0-7_]+
                     |[-+]?(?:0|[1-9][0-9_]*)
                     |[-+]?0x[0-9a-fA-F_]+
                     |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$''', re.X),
-        list(u'-+0123456789'))
+        list('-+0123456789'))
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:merge',
-        re.compile(ur'^(?:<<)$'),
+        'tag:yaml.org,2002:merge',
+        re.compile(r'^(?:<<)$'),
         ['<'])
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:null',
-        re.compile(ur'''^(?: ~
+        'tag:yaml.org,2002:null',
+        re.compile(r'''^(?: ~
                     |null|Null|NULL
                     | )$''', re.X),
-        [u'~', u'n', u'N', u''])
+        ['~', 'n', 'N', ''])
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:timestamp',
-        re.compile(ur'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
+        'tag:yaml.org,2002:timestamp',
+        re.compile(r'''^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]
                     |[0-9][0-9][0-9][0-9] -[0-9][0-9]? -[0-9][0-9]?
                      (?:[Tt]|[ \t]+)[0-9][0-9]?
                      :[0-9][0-9] :[0-9][0-9] (?:\.[0-9]*)?
                      (?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$''', re.X),
-        list(u'0123456789'))
+        list('0123456789'))
 
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:value',
-        re.compile(ur'^(?:=)$'),
+        'tag:yaml.org,2002:value',
+        re.compile(r'^(?:=)$'),
         ['='])
 
 # The following resolver is only for documentation purposes. It cannot work
 # because plain scalars cannot start with '!', '&', or '*'.
 Resolver.add_implicit_resolver(
-        u'tag:yaml.org,2002:yaml',
-        re.compile(ur'^(?:!|&|\*)$'),
-        list(u'!&*'))
+        'tag:yaml.org,2002:yaml',
+        re.compile(r'^(?:!|&|\*)$'),
+        list('!&*'))
 
diff --git lib/yaml/scanner.py lib/yaml/scanner.py
index a3ecdd0..2014e46 100644
--- lib/yaml/scanner.py
+++ lib/yaml/scanner.py
@@ -26,13 +26,13 @@
 
 __all__ = ['Scanner', 'ScannerError']
 
-from error import MarkedYAMLError
-from tokens import *
+from yaml.error import MarkedYAMLError
+from yaml.tokens import *
 
 class ScannerError(MarkedYAMLError):
     pass
 
-class SimpleKey(object):
+class SimpleKey:
     # See below simple keys treatment.
 
     def __init__(self, token_number, required, index, line, column, mark):
@@ -43,7 +43,7 @@ class SimpleKey(object):
         self.column = column
         self.mark = mark
 
-class Scanner(object):
+class Scanner:
 
     def __init__(self):
         """Initialize the scanner."""
@@ -166,85 +166,85 @@ class Scanner(object):
         ch = self.peek()
 
         # Is it the end of stream?
-        if ch == u'\0':
+        if ch == '\0':
             return self.fetch_stream_end()
 
         # Is it a directive?
-        if ch == u'%' and self.check_directive():
+        if ch == '%' and self.check_directive():
             return self.fetch_directive()
 
         # Is it the document start?
-        if ch == u'-' and self.check_document_start():
+        if ch == '-' and self.check_document_start():
             return self.fetch_document_start()
 
         # Is it the document end?
-        if ch == u'.' and self.check_document_end():
+        if ch == '.' and self.check_document_end():
             return self.fetch_document_end()
 
         # TODO: support for BOM within a stream.
-        #if ch == u'\uFEFF':
+        #if ch == '\uFEFF':
         #    return self.fetch_bom()    <-- issue BOMToken
 
         # Note: the order of the following checks is NOT significant.
 
         # Is it the flow sequence start indicator?
-        if ch == u'[':
+        if ch == '[':
             return self.fetch_flow_sequence_start()
 
         # Is it the flow mapping start indicator?
-        if ch == u'{':
+        if ch == '{':
             return self.fetch_flow_mapping_start()
 
         # Is it the flow sequence end indicator?
-        if ch == u']':
+        if ch == ']':
             return self.fetch_flow_sequence_end()
 
         # Is it the flow mapping end indicator?
-        if ch == u'}':
+        if ch == '}':
             return self.fetch_flow_mapping_end()
 
         # Is it the flow entry indicator?
-        if ch == u',':
+        if ch == ',':
             return self.fetch_flow_entry()
 
         # Is it the block entry indicator?
-        if ch == u'-' and self.check_block_entry():
+        if ch == '-' and self.check_block_entry():
             return self.fetch_block_entry()
 
         # Is it the key indicator?
-        if ch == u'?' and self.check_key():
+        if ch == '?' and self.check_key():
             return self.fetch_key()
 
         # Is it the value indicator?
-        if ch == u':' and self.check_value():
+        if ch == ':' and self.check_value():
             return self.fetch_value()
 
         # Is it an alias?
-        if ch == u'*':
+        if ch == '*':
             return self.fetch_alias()
 
         # Is it an anchor?
-        if ch == u'&':
+        if ch == '&':
             return self.fetch_anchor()
 
         # Is it a tag?
-        if ch == u'!':
+        if ch == '!':
             return self.fetch_tag()
 
         # Is it a literal scalar?
-        if ch == u'|' and not self.flow_level:
+        if ch == '|' and not self.flow_level:
             return self.fetch_literal()
 
         # Is it a folded scalar?
-        if ch == u'>' and not self.flow_level:
+        if ch == '>' and not self.flow_level:
             return self.fetch_folded()
 
         # Is it a single quoted scalar?
-        if ch == u'\'':
+        if ch == '\'':
             return self.fetch_single()
 
         # Is it a double quoted scalar?
-        if ch == u'\"':
+        if ch == '\"':
             return self.fetch_double()
 
         # It must be a plain scalar then.
@@ -280,7 +280,7 @@ class Scanner(object):
         # - should be no longer than 1024 characters.
         # Disabling this procedure will allow simple keys of any length and
         # height (may cause problems if indentation is broken though).
-        for level in self.possible_simple_keys.keys():
+        for level in list(self.possible_simple_keys.keys()):
             key = self.possible_simple_keys[level]
             if key.line != self.line  \
                     or self.index-key.index > 1024:
@@ -691,22 +691,22 @@ class Scanner(object):
 
         # DOCUMENT-START:   ^ '---' (' '|'\n')
         if self.column == 0:
-            if self.prefix(3) == u'---'  \
-                    and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+            if self.prefix(3) == '---'  \
+                    and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                 return True
 
     def check_document_end(self):
 
         # DOCUMENT-END:     ^ '...' (' '|'\n')
         if self.column == 0:
-            if self.prefix(3) == u'...'  \
-                    and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+            if self.prefix(3) == '...'  \
+                    and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                 return True
 
     def check_block_entry(self):
 
         # BLOCK-ENTRY:      '-' (' '|'\n')
-        return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+        return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029'
 
     def check_key(self):
 
@@ -716,7 +716,7 @@ class Scanner(object):
 
         # KEY(block context):   '?' (' '|'\n')
         else:
-            return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+            return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029'
 
     def check_value(self):
 
@@ -726,7 +726,7 @@ class Scanner(object):
 
         # VALUE(block context): ':' (' '|'\n')
         else:
-            return self.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+            return self.peek(1) in '\0 \t\r\n\x85\u2028\u2029'
 
     def check_plain(self):
 
@@ -743,9 +743,9 @@ class Scanner(object):
         # '-' character) because we want the flow context to be space
         # independent.
         ch = self.peek()
-        return ch not in u'\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`'  \
-                or (self.peek(1) not in u'\0 \t\r\n\x85\u2028\u2029'
-                        and (ch == u'-' or (not self.flow_level and ch in u'?:')))
+        return ch not in '\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`'  \
+                or (self.peek(1) not in '\0 \t\r\n\x85\u2028\u2029'
+                        and (ch == '-' or (not self.flow_level and ch in '?:')))
 
     # Scanners.
 
@@ -769,14 +769,14 @@ class Scanner(object):
         # `unwind_indent` before issuing BLOCK-END.
         # Scanners for block, flow, and plain scalars need to be modified.
 
-        if self.index == 0 and self.peek() == u'\uFEFF':
+        if self.index == 0 and self.peek() == '\uFEFF':
             self.forward()
         found = False
         while not found:
-            while self.peek() == u' ':
+            while self.peek() == ' ':
                 self.forward()
-            if self.peek() == u'#':
-                while self.peek() not in u'\0\r\n\x85\u2028\u2029':
+            if self.peek() == '#':
+                while self.peek() not in '\0\r\n\x85\u2028\u2029':
                     self.forward()
             if self.scan_line_break():
                 if not self.flow_level:
@@ -790,15 +790,15 @@ class Scanner(object):
         self.forward()
         name = self.scan_directive_name(start_mark)
         value = None
-        if name == u'YAML':
+        if name == 'YAML':
             value = self.scan_yaml_directive_value(start_mark)
             end_mark = self.get_mark()
-        elif name == u'TAG':
+        elif name == 'TAG':
             value = self.scan_tag_directive_value(start_mark)
             end_mark = self.get_mark()
         else:
             end_mark = self.get_mark()
-            while self.peek() not in u'\0\r\n\x85\u2028\u2029':
+            while self.peek() not in '\0\r\n\x85\u2028\u2029':
                 self.forward()
         self.scan_directive_ignored_line(start_mark)
         return DirectiveToken(name, value, start_mark, end_mark)
@@ -807,8 +807,8 @@ class Scanner(object):
         # See the specification for details.
         length = 0
         ch = self.peek(length)
-        while u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'  \
-                or ch in u'-_':
+        while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'  \
+                or ch in '-_':
             length += 1
             ch = self.peek(length)
         if not length:
@@ -818,7 +818,7 @@ class Scanner(object):
         value = self.prefix(length)
         self.forward(length)
         ch = self.peek()
-        if ch not in u'\0 \r\n\x85\u2028\u2029':
+        if ch not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected alphabetic or numeric character, but found %r"
                     % ch.encode('utf-8'), self.get_mark())
@@ -826,7 +826,7 @@ class Scanner(object):
 
     def scan_yaml_directive_value(self, start_mark):
         # See the specification for details.
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
         major = self.scan_yaml_directive_number(start_mark)
         if self.peek() != '.':
@@ -836,7 +836,7 @@ class Scanner(object):
                     self.get_mark())
         self.forward()
         minor = self.scan_yaml_directive_number(start_mark)
-        if self.peek() not in u'\0 \r\n\x85\u2028\u2029':
+        if self.peek() not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected a digit or ' ', but found %r"
                     % self.peek().encode('utf-8'),
@@ -846,12 +846,12 @@ class Scanner(object):
     def scan_yaml_directive_number(self, start_mark):
         # See the specification for details.
         ch = self.peek()
-        if not (u'0' <= ch <= '9'):
+        if not ('0' <= ch <= '9'):
             raise ScannerError("while scanning a directive", start_mark,
                     "expected a digit, but found %r" % ch.encode('utf-8'),
                     self.get_mark())
         length = 0
-        while u'0' <= self.peek(length) <= u'9':
+        while '0' <= self.peek(length) <= '9':
             length += 1
         value = int(self.prefix(length))
         self.forward(length)
@@ -859,10 +859,10 @@ class Scanner(object):
 
     def scan_tag_directive_value(self, start_mark):
         # See the specification for details.
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
         handle = self.scan_tag_directive_handle(start_mark)
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
         prefix = self.scan_tag_directive_prefix(start_mark)
         return (handle, prefix)
@@ -871,7 +871,7 @@ class Scanner(object):
         # See the specification for details.
         value = self.scan_tag_handle('directive', start_mark)
         ch = self.peek()
-        if ch != u' ':
+        if ch != ' ':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected ' ', but found %r" % ch.encode('utf-8'),
                     self.get_mark())
@@ -881,7 +881,7 @@ class Scanner(object):
         # See the specification for details.
         value = self.scan_tag_uri('directive', start_mark)
         ch = self.peek()
-        if ch not in u'\0 \r\n\x85\u2028\u2029':
+        if ch not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected ' ', but found %r" % ch.encode('utf-8'),
                     self.get_mark())
@@ -889,13 +889,13 @@ class Scanner(object):
 
     def scan_directive_ignored_line(self, start_mark):
         # See the specification for details.
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
-        if self.peek() == u'#':
-            while self.peek() not in u'\0\r\n\x85\u2028\u2029':
+        if self.peek() == '#':
+            while self.peek() not in '\0\r\n\x85\u2028\u2029':
                 self.forward()
         ch = self.peek()
-        if ch not in u'\0\r\n\x85\u2028\u2029':
+        if ch not in '\0\r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a directive", start_mark,
                     "expected a comment or a line break, but found %r"
                         % ch.encode('utf-8'), self.get_mark())
@@ -919,8 +919,8 @@ class Scanner(object):
         self.forward()
         length = 0
         ch = self.peek(length)
-        while u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'  \
-                or ch in u'-_':
+        while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'  \
+                or ch in '-_':
             length += 1
             ch = self.peek(length)
         if not length:
@@ -930,7 +930,7 @@ class Scanner(object):
         value = self.prefix(length)
         self.forward(length)
         ch = self.peek()
-        if ch not in u'\0 \t\r\n\x85\u2028\u2029?:,]}%@`':
+        if ch not in '\0 \t\r\n\x85\u2028\u2029?:,]}%@`':
             raise ScannerError("while scanning an %s" % name, start_mark,
                     "expected alphabetic or numeric character, but found %r"
                     % ch.encode('utf-8'), self.get_mark())
@@ -941,37 +941,37 @@ class Scanner(object):
         # See the specification for details.
         start_mark = self.get_mark()
         ch = self.peek(1)
-        if ch == u'<':
+        if ch == '<':
             handle = None
             self.forward(2)
             suffix = self.scan_tag_uri('tag', start_mark)
-            if self.peek() != u'>':
+            if self.peek() != '>':
                 raise ScannerError("while parsing a tag", start_mark,
                         "expected '>', but found %r" % self.peek().encode('utf-8'),
                         self.get_mark())
             self.forward()
-        elif ch in u'\0 \t\r\n\x85\u2028\u2029':
+        elif ch in '\0 \t\r\n\x85\u2028\u2029':
             handle = None
-            suffix = u'!'
+            suffix = '!'
             self.forward()
         else:
             length = 1
             use_handle = False
-            while ch not in u'\0 \r\n\x85\u2028\u2029':
-                if ch == u'!':
+            while ch not in '\0 \r\n\x85\u2028\u2029':
+                if ch == '!':
                     use_handle = True
                     break
                 length += 1
                 ch = self.peek(length)
-            handle = u'!'
+            handle = '!'
             if use_handle:
                 handle = self.scan_tag_handle('tag', start_mark)
             else:
-                handle = u'!'
+                handle = '!'
                 self.forward()
             suffix = self.scan_tag_uri('tag', start_mark)
         ch = self.peek()
-        if ch not in u'\0 \r\n\x85\u2028\u2029':
+        if ch not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a tag", start_mark,
                     "expected ' ', but found %r" % ch.encode('utf-8'),
                     self.get_mark())
@@ -1005,39 +1005,39 @@ class Scanner(object):
         else:
             indent = min_indent+increment-1
             breaks, end_mark = self.scan_block_scalar_breaks(indent)
-        line_break = u''
+        line_break = ''
 
         # Scan the inner part of the block scalar.
-        while self.column == indent and self.peek() != u'\0':
+        while self.column == indent and self.peek() != '\0':
             chunks.extend(breaks)
-            leading_non_space = self.peek() not in u' \t'
+            leading_non_space = self.peek() not in ' \t'
             length = 0
-            while self.peek(length) not in u'\0\r\n\x85\u2028\u2029':
+            while self.peek(length) not in '\0\r\n\x85\u2028\u2029':
                 length += 1
             chunks.append(self.prefix(length))
             self.forward(length)
             line_break = self.scan_line_break()
             breaks, end_mark = self.scan_block_scalar_breaks(indent)
-            if self.column == indent and self.peek() != u'\0':
+            if self.column == indent and self.peek() != '\0':
 
                 # Unfortunately, folding rules are ambiguous.
                 #
                 # This is the folding according to the specification:
                 
-                if folded and line_break == u'\n'   \
-                        and leading_non_space and self.peek() not in u' \t':
+                if folded and line_break == '\n'   \
+                        and leading_non_space and self.peek() not in ' \t':
                     if not breaks:
-                        chunks.append(u' ')
+                        chunks.append(' ')
                 else:
                     chunks.append(line_break)
                 
                 # This is Clark Evans's interpretation (also in the spec
                 # examples):
                 #
-                #if folded and line_break == u'\n':
+                #if folded and line_break == '\n':
                 #    if not breaks:
                 #        if self.peek() not in ' \t':
-                #            chunks.append(u' ')
+                #            chunks.append(' ')
                 #        else:
                 #            chunks.append(line_break)
                 #else:
@@ -1052,7 +1052,7 @@ class Scanner(object):
             chunks.extend(breaks)
 
         # We are done.
-        return ScalarToken(u''.join(chunks), False, start_mark, end_mark,
+        return ScalarToken(''.join(chunks), False, start_mark, end_mark,
                 style)
 
     def scan_block_scalar_indicators(self, start_mark):
@@ -1060,21 +1060,21 @@ class Scanner(object):
         chomping = None
         increment = None
         ch = self.peek()
-        if ch in u'+-':
+        if ch in '+-':
             if ch == '+':
                 chomping = True
             else:
                 chomping = False
             self.forward()
             ch = self.peek()
-            if ch in u'0123456789':
+            if ch in '0123456789':
                 increment = int(ch)
                 if increment == 0:
                     raise ScannerError("while scanning a block scalar", start_mark,
                             "expected indentation indicator in the range 1-9, but found 0",
                             self.get_mark())
                 self.forward()
-        elif ch in u'0123456789':
+        elif ch in '0123456789':
             increment = int(ch)
             if increment == 0:
                 raise ScannerError("while scanning a block scalar", start_mark,
@@ -1082,14 +1082,14 @@ class Scanner(object):
                         self.get_mark())
             self.forward()
             ch = self.peek()
-            if ch in u'+-':
+            if ch in '+-':
                 if ch == '+':
                     chomping = True
                 else:
                     chomping = False
                 self.forward()
         ch = self.peek()
-        if ch not in u'\0 \r\n\x85\u2028\u2029':
+        if ch not in '\0 \r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a block scalar", start_mark,
                     "expected chomping or indentation indicators, but found %r"
                         % ch.encode('utf-8'), self.get_mark())
@@ -1097,13 +1097,13 @@ class Scanner(object):
 
     def scan_block_scalar_ignored_line(self, start_mark):
         # See the specification for details.
-        while self.peek() == u' ':
+        while self.peek() == ' ':
             self.forward()
-        if self.peek() == u'#':
-            while self.peek() not in u'\0\r\n\x85\u2028\u2029':
+        if self.peek() == '#':
+            while self.peek() not in '\0\r\n\x85\u2028\u2029':
                 self.forward()
         ch = self.peek()
-        if ch not in u'\0\r\n\x85\u2028\u2029':
+        if ch not in '\0\r\n\x85\u2028\u2029':
             raise ScannerError("while scanning a block scalar", start_mark,
                     "expected a comment or a line break, but found %r"
                         % ch.encode('utf-8'), self.get_mark())
@@ -1114,8 +1114,8 @@ class Scanner(object):
         chunks = []
         max_indent = 0
         end_mark = self.get_mark()
-        while self.peek() in u' \r\n\x85\u2028\u2029':
-            if self.peek() != u' ':
+        while self.peek() in ' \r\n\x85\u2028\u2029':
+            if self.peek() != ' ':
                 chunks.append(self.scan_line_break())
                 end_mark = self.get_mark()
             else:
@@ -1128,12 +1128,12 @@ class Scanner(object):
         # See the specification for details.
         chunks = []
         end_mark = self.get_mark()
-        while self.column < indent and self.peek() == u' ':
+        while self.column < indent and self.peek() == ' ':
             self.forward()
-        while self.peek() in u'\r\n\x85\u2028\u2029':
+        while self.peek() in '\r\n\x85\u2028\u2029':
             chunks.append(self.scan_line_break())
             end_mark = self.get_mark()
-            while self.column < indent and self.peek() == u' ':
+            while self.column < indent and self.peek() == ' ':
                 self.forward()
         return chunks, end_mark
 
@@ -1158,33 +1158,33 @@ class Scanner(object):
             chunks.extend(self.scan_flow_scalar_non_spaces(double, start_mark))
         self.forward()
         end_mark = self.get_mark()
-        return ScalarToken(u''.join(chunks), False, start_mark, end_mark,
+        return ScalarToken(''.join(chunks), False, start_mark, end_mark,
                 style)
 
     ESCAPE_REPLACEMENTS = {
-        u'0':   u'\0',
-        u'a':   u'\x07',
-        u'b':   u'\x08',
-        u't':   u'\x09',
-        u'\t':  u'\x09',
-        u'n':   u'\x0A',
-        u'v':   u'\x0B',
-        u'f':   u'\x0C',
-        u'r':   u'\x0D',
-        u'e':   u'\x1B',
-        u' ':   u'\x20',
-        u'\"':  u'\"',
-        u'\\':  u'\\',
-        u'N':   u'\x85',
-        u'_':   u'\xA0',
-        u'L':   u'\u2028',
-        u'P':   u'\u2029',
+        '0':   '\0',
+        'a':   '\x07',
+        'b':   '\x08',
+        't':   '\x09',
+        '\t':  '\x09',
+        'n':   '\x0A',
+        'v':   '\x0B',
+        'f':   '\x0C',
+        'r':   '\x0D',
+        'e':   '\x1B',
+        ' ':   '\x20',
+        '\"':  '\"',
+        '\\':  '\\',
+        'N':   '\x85',
+        '_':   '\xA0',
+        'L':   '\u2028',
+        'P':   '\u2029',
     }
 
     ESCAPE_CODES = {
-        u'x':   2,
-        u'u':   4,
-        u'U':   8,
+        'x':   2,
+        'u':   4,
+        'U':   8,
     }
 
     def scan_flow_scalar_non_spaces(self, double, start_mark):
@@ -1192,19 +1192,19 @@ class Scanner(object):
         chunks = []
         while True:
             length = 0
-            while self.peek(length) not in u'\'\"\\\0 \t\r\n\x85\u2028\u2029':
+            while self.peek(length) not in '\'\"\\\0 \t\r\n\x85\u2028\u2029':
                 length += 1
             if length:
                 chunks.append(self.prefix(length))
                 self.forward(length)
             ch = self.peek()
-            if not double and ch == u'\'' and self.peek(1) == u'\'':
-                chunks.append(u'\'')
+            if not double and ch == '\'' and self.peek(1) == '\'':
+                chunks.append('\'')
                 self.forward(2)
-            elif (double and ch == u'\'') or (not double and ch in u'\"\\'):
+            elif (double and ch == '\'') or (not double and ch in '\"\\'):
                 chunks.append(ch)
                 self.forward()
-            elif double and ch == u'\\':
+            elif double and ch == '\\':
                 self.forward()
                 ch = self.peek()
                 if ch in self.ESCAPE_REPLACEMENTS:
@@ -1214,14 +1214,14 @@ class Scanner(object):
                     length = self.ESCAPE_CODES[ch]
                     self.forward()
                     for k in range(length):
-                        if self.peek(k) not in u'0123456789ABCDEFabcdef':
+                        if self.peek(k) not in '0123456789ABCDEFabcdef':
                             raise ScannerError("while scanning a double-quoted scalar", start_mark,
                                     "expected escape sequence of %d hexdecimal numbers, but found %r" %
                                         (length, self.peek(k).encode('utf-8')), self.get_mark())
                     code = int(self.prefix(length), 16)
-                    chunks.append(unichr(code))
+                    chunks.append(chr(code))
                     self.forward(length)
-                elif ch in u'\r\n\x85\u2028\u2029':
+                elif ch in '\r\n\x85\u2028\u2029':
                     self.scan_line_break()
                     chunks.extend(self.scan_flow_scalar_breaks(double, start_mark))
                 else:
@@ -1234,21 +1234,21 @@ class Scanner(object):
         # See the specification for details.
         chunks = []
         length = 0
-        while self.peek(length) in u' \t':
+        while self.peek(length) in ' \t':
             length += 1
         whitespaces = self.prefix(length)
         self.forward(length)
         ch = self.peek()
-        if ch == u'\0':
+        if ch == '\0':
             raise ScannerError("while scanning a quoted scalar", start_mark,
                     "found unexpected end of stream", self.get_mark())
-        elif ch in u'\r\n\x85\u2028\u2029':
+        elif ch in '\r\n\x85\u2028\u2029':
             line_break = self.scan_line_break()
             breaks = self.scan_flow_scalar_breaks(double, start_mark)
-            if line_break != u'\n':
+            if line_break != '\n':
                 chunks.append(line_break)
             elif not breaks:
-                chunks.append(u' ')
+                chunks.append(' ')
             chunks.extend(breaks)
         else:
             chunks.append(whitespaces)
@@ -1261,13 +1261,13 @@ class Scanner(object):
             # Instead of checking indentation, we check for document
             # separators.
             prefix = self.prefix(3)
-            if (prefix == u'---' or prefix == u'...')   \
-                    and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+            if (prefix == '---' or prefix == '...')   \
+                    and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                 raise ScannerError("while scanning a quoted scalar", start_mark,
                         "found unexpected document separator", self.get_mark())
-            while self.peek() in u' \t':
+            while self.peek() in ' \t':
                 self.forward()
-            if self.peek() in u'\r\n\x85\u2028\u2029':
+            if self.peek() in '\r\n\x85\u2028\u2029':
                 chunks.append(self.scan_line_break())
             else:
                 return chunks
@@ -1289,19 +1289,19 @@ class Scanner(object):
         spaces = []
         while True:
             length = 0
-            if self.peek() == u'#':
+            if self.peek() == '#':
                 break
             while True:
                 ch = self.peek(length)
-                if ch in u'\0 \t\r\n\x85\u2028\u2029'   \
-                        or (not self.flow_level and ch == u':' and
-                                self.peek(length+1) in u'\0 \t\r\n\x85\u2028\u2029') \
-                        or (self.flow_level and ch in u',:?[]{}'):
+                if ch in '\0 \t\r\n\x85\u2028\u2029'   \
+                        or (not self.flow_level and ch == ':' and
+                                self.peek(length+1) in '\0 \t\r\n\x85\u2028\u2029') \
+                        or (self.flow_level and ch in ',:?[]{}'):
                     break
                 length += 1
             # It's not clear what we should do with ':' in the flow context.
-            if (self.flow_level and ch == u':'
-                    and self.peek(length+1) not in u'\0 \t\r\n\x85\u2028\u2029,[]{}'):
+            if (self.flow_level and ch == ':'
+                    and self.peek(length+1) not in '\0 \t\r\n\x85\u2028\u2029,[]{}'):
                 self.forward(length)
                 raise ScannerError("while scanning a plain scalar", start_mark,
                     "found unexpected ':'", self.get_mark(),
@@ -1314,10 +1314,10 @@ class Scanner(object):
             self.forward(length)
             end_mark = self.get_mark()
             spaces = self.scan_plain_spaces(indent, start_mark)
-            if not spaces or self.peek() == u'#' \
+            if not spaces or self.peek() == '#' \
                     or (not self.flow_level and self.column < indent):
                 break
-        return ScalarToken(u''.join(chunks), True, start_mark, end_mark)
+        return ScalarToken(''.join(chunks), True, start_mark, end_mark)
 
     def scan_plain_spaces(self, indent, start_mark):
         # See the specification for details.
@@ -1325,32 +1325,32 @@ class Scanner(object):
         # We just forbid them completely. Do not use tabs in YAML!
         chunks = []
         length = 0
-        while self.peek(length) in u' ':
+        while self.peek(length) in ' ':
             length += 1
         whitespaces = self.prefix(length)
         self.forward(length)
         ch = self.peek()
-        if ch in u'\r\n\x85\u2028\u2029':
+        if ch in '\r\n\x85\u2028\u2029':
             line_break = self.scan_line_break()
             self.allow_simple_key = True
             prefix = self.prefix(3)
-            if (prefix == u'---' or prefix == u'...')   \
-                    and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+            if (prefix == '---' or prefix == '...')   \
+                    and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                 return
             breaks = []
-            while self.peek() in u' \r\n\x85\u2028\u2029':
+            while self.peek() in ' \r\n\x85\u2028\u2029':
                 if self.peek() == ' ':
                     self.forward()
                 else:
                     breaks.append(self.scan_line_break())
                     prefix = self.prefix(3)
-                    if (prefix == u'---' or prefix == u'...')   \
-                            and self.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+                    if (prefix == '---' or prefix == '...')   \
+                            and self.peek(3) in '\0 \t\r\n\x85\u2028\u2029':
                         return
-            if line_break != u'\n':
+            if line_break != '\n':
                 chunks.append(line_break)
             elif not breaks:
-                chunks.append(u' ')
+                chunks.append(' ')
             chunks.extend(breaks)
         elif whitespaces:
             chunks.append(whitespaces)
@@ -1361,18 +1361,18 @@ class Scanner(object):
         # For some strange reasons, the specification does not allow '_' in
         # tag handles. I have allowed it anyway.
         ch = self.peek()
-        if ch != u'!':
+        if ch != '!':
             raise ScannerError("while scanning a %s" % name, start_mark,
                     "expected '!', but found %r" % ch.encode('utf-8'),
                     self.get_mark())
         length = 1
         ch = self.peek(length)
-        if ch != u' ':
-            while u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'  \
-                    or ch in u'-_':
+        if ch != ' ':
+            while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'  \
+                    or ch in '-_':
                 length += 1
                 ch = self.peek(length)
-            if ch != u'!':
+            if ch != '!':
                 self.forward(length)
                 raise ScannerError("while scanning a %s" % name, start_mark,
                         "expected '!', but found %r" % ch.encode('utf-8'),
@@ -1388,9 +1388,9 @@ class Scanner(object):
         chunks = []
         length = 0
         ch = self.peek(length)
-        while u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'  \
-                or ch in u'-;/?:@&=+$,_.!~*\'()[]%':
-            if ch == u'%':
+        while '0' <= ch <= '9' or 'A' <= ch <= 'Z' or 'a' <= ch <= 'z'  \
+                or ch in '-;/?:@&=+$,_.!~*\'()[]%':
+            if ch == '%':
                 chunks.append(self.prefix(length))
                 self.forward(length)
                 length = 0
@@ -1406,24 +1406,24 @@ class Scanner(object):
             raise ScannerError("while parsing a %s" % name, start_mark,
                     "expected URI, but found %r" % ch.encode('utf-8'),
                     self.get_mark())
-        return u''.join(chunks)
+        return ''.join(chunks)
 
     def scan_uri_escapes(self, name, start_mark):
         # See the specification for details.
         bytes = []
         mark = self.get_mark()
-        while self.peek() == u'%':
+        while self.peek() == '%':
             self.forward()
             for k in range(2):
-                if self.peek(k) not in u'0123456789ABCDEFabcdef':
+                if self.peek(k) not in '0123456789ABCDEFabcdef':
                     raise ScannerError("while scanning a %s" % name, start_mark,
                             "expected URI escape sequence of 2 hexdecimal numbers, but found %r" %
                                 (self.peek(k).encode('utf-8')), self.get_mark())
             bytes.append(chr(int(self.prefix(2), 16)))
             self.forward(2)
         try:
-            value = unicode(''.join(bytes), 'utf-8')
-        except UnicodeDecodeError, exc:
+            value = str(''.join(bytes))
+        except UnicodeDecodeError as exc:
             raise ScannerError("while scanning a %s" % name, start_mark, str(exc), mark)
         return value
 
@@ -1437,16 +1437,16 @@ class Scanner(object):
         #   '\u2029     :   '\u2029'
         #   default     :   ''
         ch = self.peek()
-        if ch in u'\r\n\x85':
-            if self.prefix(2) == u'\r\n':
+        if ch in '\r\n\x85':
+            if self.prefix(2) == '\r\n':
                 self.forward(2)
             else:
                 self.forward()
-            return u'\n'
-        elif ch in u'\u2028\u2029':
+            return '\n'
+        elif ch in '\u2028\u2029':
             self.forward()
             return ch
-        return u''
+        return ''
 
 #try:
 #    import psyco
diff --git lib/yaml/serializer.py lib/yaml/serializer.py
index 2101f95..d193c41 100644
--- lib/yaml/serializer.py
+++ lib/yaml/serializer.py
@@ -1,16 +1,16 @@
 
 __all__ = ['Serializer', 'SerializerError']
 
-from error import YAMLError
-from events import *
-from nodes import *
+from yaml.error import YAMLError
+from yaml.events import *
+from yaml.nodes import *
 
 class SerializerError(YAMLError):
     pass
 
-class Serializer(object):
+class Serializer:
 
-    ANCHOR_TEMPLATE = u'id%03d'
+    ANCHOR_TEMPLATE = 'id%03d'
 
     def __init__(self, encoding=None,
             explicit_start=None, explicit_end=None, version=None, tags=None):
diff --git lib/yaml/tokens.py lib/yaml/tokens.py
index 4d0b48a..0cbd7e5 100644
--- lib/yaml/tokens.py
+++ lib/yaml/tokens.py
@@ -1,14 +1,13 @@
 
-class Token(object):
+class Token:
     def __init__(self, start_mark, end_mark):
         self.start_mark = start_mark
         self.end_mark = end_mark
     def __repr__(self):
-        attributes = [key for key in self.__dict__
-                if not key.endswith('_mark')]
-        attributes.sort()
-        arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
-                for key in attributes])
+        attributes = sorted(key for key in self.__dict__
+                if not key.endswith('_mark'))
+        arguments = ', '.join('%s=%r' % (key, getattr(self, key))
+                for key in attributes)
         return '%s(%s)' % (self.__class__.__name__, arguments)
 
 #class BOMToken(Token):
diff --git tests/data/construct-binary.code tests/data/construct-binary.code
index 67ac0d5..30bfc3f 100644
--- tests/data/construct-binary.code
+++ tests/data/construct-binary.code
@@ -1,7 +1,7 @@
 {
     "canonical":
-        "GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;",
+        b"GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;",
     "generic":
-        "GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;",
+        b"GIF89a\x0c\x00\x0c\x00\x84\x00\x00\xff\xff\xf7\xf5\xf5\xee\xe9\xe9\xe5fff\x00\x00\x00\xe7\xe7\xe7^^^\xf3\xf3\xed\x8e\x8e\x8e\xe0\xe0\xe0\x9f\x9f\x9f\x93\x93\x93\xa7\xa7\xa7\x9e\x9e\x9eiiiccc\xa3\xa3\xa3\x84\x84\x84\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9\xff\xfe\xf9!\xfe\x0eMade with GIMP\x00,\x00\x00\x00\x00\x0c\x00\x0c\x00\x00\x05,  \x8e\x810\x9e\xe3@\x14\xe8i\x10\xc4\xd1\x8a\x08\x1c\xcf\x80M$z\xef\xff0\x85p\xb8\xb01f\r\x1b\xce\x01\xc3\x01\x1e\x10' \x82\n\x01\x00;",
     "description": "The binary value above is a tiny arrow encoded as a gif image.",
 }
diff --git tests/data/construct-python-bytes-ascii.code tests/data/construct-python-bytes-ascii.code
new file mode 100644
index 0000000..aa9a80b
--- /dev/null
+++ tests/data/construct-python-bytes-ascii.code
@@ -0,0 +1 @@
+b"ascii string"
diff --git tests/data/construct-python-bytes-ascii.data tests/data/construct-python-bytes-ascii.data
new file mode 100644
index 0000000..dc53f06
--- /dev/null
+++ tests/data/construct-python-bytes-ascii.data
@@ -0,0 +1 @@
+--- !!python/bytes "ascii string"
diff --git tests/data/construct-python-bytes-utf8.code tests/data/construct-python-bytes-utf8.code
new file mode 100644
index 0000000..6ca7d8f
--- /dev/null
+++ tests/data/construct-python-bytes-utf8.code
@@ -0,0 +1 @@
+'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'.encode('utf-8')
diff --git tests/data/construct-python-bytes-utf8.data tests/data/construct-python-bytes-utf8.data
new file mode 100644
index 0000000..4e916c0
--- /dev/null
+++ tests/data/construct-python-bytes-utf8.data
@@ -0,0 +1 @@
+--- !!python/bytes "Это уникодная строка"
diff --git tests/data/construct-python-long-short.code tests/data/construct-python-long-short.code
index fafc3f1..190a180 100644
--- tests/data/construct-python-long-short.code
+++ tests/data/construct-python-long-short.code
@@ -1 +1 @@
-123L
+123
diff --git tests/data/construct-python-name-module.code tests/data/construct-python-name-module.code
index 335c7ca..4e6a519 100644
--- tests/data/construct-python-name-module.code
+++ tests/data/construct-python-name-module.code
@@ -1 +1 @@
-[file, Loader, dump, abs, yaml.tokens]
+[list, Loader, dump, abs, yaml.tokens]
diff --git tests/data/construct-python-name-module.data tests/data/construct-python-name-module.data
index c8f8036..7f1cc20 100644
--- tests/data/construct-python-name-module.data
+++ tests/data/construct-python-name-module.data
@@ -1,4 +1,4 @@
-- !!python/name:file
+- !!python/name:list
 - !!python/name:yaml.Loader
 - !!python/name:yaml.dump
 - !!python/name:abs
diff --git tests/data/construct-python-object.code tests/data/construct-python-object.code
index 7f1edf1..651a669 100644
--- tests/data/construct-python-object.code
+++ tests/data/construct-python-object.code
@@ -1,16 +1,11 @@
 [
 AnObject(1, 'two', [3,3,3]),
-AnInstance(1, 'two', [3,3,3]),
 
 AnObject(1, 'two', [3,3,3]),
-AnInstance(1, 'two', [3,3,3]),
 
 AState(1, 'two', [3,3,3]),
 ACustomState(1, 'two', [3,3,3]),
 
-InitArgs(1, 'two', [3,3,3]),
-InitArgsWithState(1, 'two', [3,3,3]),
-
 NewArgs(1, 'two', [3,3,3]),
 NewArgsWithState(1, 'two', [3,3,3]),
 
diff --git tests/data/construct-python-object.data tests/data/construct-python-object.data
index bce8b2e..2414f09 100644
--- tests/data/construct-python-object.data
+++ tests/data/construct-python-object.data
@@ -1,15 +1,10 @@
 - !!python/object:test_constructor.AnObject { foo: 1, bar: two, baz: [3,3,3] }
-- !!python/object:test_constructor.AnInstance { foo: 1, bar: two, baz: [3,3,3] }
 
 - !!python/object/new:test_constructor.AnObject { args: [1, two], kwds: {baz: [3,3,3]} }
-- !!python/object/apply:test_constructor.AnInstance { args: [1, two], kwds: {baz: [3,3,3]} }
 
 - !!python/object:test_constructor.AState { _foo: 1, _bar: two, _baz: [3,3,3] }
 - !!python/object/new:test_constructor.ACustomState { state: !!python/tuple [1, two, [3,3,3]] }
 
-- !!python/object/new:test_constructor.InitArgs [1, two, [3,3,3]]
-- !!python/object/new:test_constructor.InitArgsWithState { args: [1, two], state: [3,3,3] }
-
 - !!python/object/new:test_constructor.NewArgs [1, two, [3,3,3]]
 - !!python/object/new:test_constructor.NewArgsWithState { args: [1, two], state: [3,3,3] }
 
diff --git tests/data/construct-python-str-utf8.code tests/data/construct-python-str-utf8.code
index 47b28ab..9f66032 100644
--- tests/data/construct-python-str-utf8.code
+++ tests/data/construct-python-str-utf8.code
@@ -1 +1 @@
-u'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'.encode('utf-8')
+'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
diff --git tests/data/construct-python-unicode-ascii.code tests/data/construct-python-unicode-ascii.code
deleted file mode 100644
index d4cd82c..0000000
--- tests/data/construct-python-unicode-ascii.code
+++ /dev/null
@@ -1 +0,0 @@
-u"ascii string"
diff --git tests/data/construct-python-unicode-ascii.data tests/data/construct-python-unicode-ascii.data
deleted file mode 100644
index 3a0647b..0000000
--- tests/data/construct-python-unicode-ascii.data
+++ /dev/null
@@ -1 +0,0 @@
---- !!python/unicode "ascii string"
diff --git tests/data/construct-python-unicode-utf8.code tests/data/construct-python-unicode-utf8.code
deleted file mode 100644
index 2793ac7..0000000
--- tests/data/construct-python-unicode-utf8.code
+++ /dev/null
@@ -1 +0,0 @@
-u'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
diff --git tests/data/construct-python-unicode-utf8.data tests/data/construct-python-unicode-utf8.data
deleted file mode 100644
index 5a980ea..0000000
--- tests/data/construct-python-unicode-utf8.data
+++ /dev/null
@@ -1 +0,0 @@
---- !!python/unicode "Это уникодная строка"
diff --git tests/data/construct-str-utf8.code tests/data/construct-str-utf8.code
index 2793ac7..9f66032 100644
--- tests/data/construct-str-utf8.code
+++ tests/data/construct-str-utf8.code
@@ -1 +1 @@
-u'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
+'\u042d\u0442\u043e \u0443\u043d\u0438\u043a\u043e\u0434\u043d\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430'
diff --git tests/data/emitting-unacceptable-unicode-character-bug.code tests/data/emitting-unacceptable-unicode-character-bug.code
index 4b92854..2a5df00 100644
--- tests/data/emitting-unacceptable-unicode-character-bug.code
+++ tests/data/emitting-unacceptable-unicode-character-bug.code
@@ -1 +1 @@
-u"\udd00"
+"\udd00"
diff --git tests/data/recursive-set.recursive tests/data/recursive-set.recursive
index 457c50d..d1a7ca3 100644
--- tests/data/recursive-set.recursive
+++ tests/data/recursive-set.recursive
@@ -1,7 +1,3 @@
-try:
-    set
-except NameError:
-    from sets import Set as set
 value = set()
 value.add(AnInstance(foo=value, bar=value))
 value.add(AnInstance(foo=value, bar=value))
diff --git tests/data/serializer-is-already-opened.dumper-error tests/data/serializer-is-already-opened.dumper-error
index 0f66a46..c2be9bb 100644
--- tests/data/serializer-is-already-opened.dumper-error
+++ tests/data/serializer-is-already-opened.dumper-error
@@ -1,3 +1,3 @@
-dumper = Dumper(StringIO.StringIO())
+dumper = Dumper(io.StringIO())
 dumper.open()
 dumper.open()
diff --git tests/data/serializer-is-closed-1.dumper-error tests/data/serializer-is-closed-1.dumper-error
index 5d9ecfc..93dcd66 100644
--- tests/data/serializer-is-closed-1.dumper-error
+++ tests/data/serializer-is-closed-1.dumper-error
@@ -1,4 +1,4 @@
-dumper = Dumper(StringIO.StringIO())
+dumper = Dumper(io.StringIO())
 dumper.open()
 dumper.close()
 dumper.open()
diff --git tests/data/serializer-is-closed-2.dumper-error tests/data/serializer-is-closed-2.dumper-error
index 0762145..e15fb9d 100644
--- tests/data/serializer-is-closed-2.dumper-error
+++ tests/data/serializer-is-closed-2.dumper-error
@@ -1,4 +1,4 @@
-dumper = Dumper(StringIO.StringIO())
+dumper = Dumper(io.StringIO())
 dumper.open()
 dumper.close()
 dumper.serialize(ScalarNode(tag='!foo', value='bar'))
diff --git tests/data/serializer-is-not-opened-1.dumper-error tests/data/serializer-is-not-opened-1.dumper-error
index 1d21554..8f68baf 100644
--- tests/data/serializer-is-not-opened-1.dumper-error
+++ tests/data/serializer-is-not-opened-1.dumper-error
@@ -1,2 +1,2 @@
-dumper = Dumper(StringIO.StringIO())
+dumper = Dumper(io.StringIO())
 dumper.close()
diff --git tests/data/serializer-is-not-opened-2.dumper-error tests/data/serializer-is-not-opened-2.dumper-error
index d1d7f98..e818837 100644
--- tests/data/serializer-is-not-opened-2.dumper-error
+++ tests/data/serializer-is-not-opened-2.dumper-error
@@ -1,2 +1,2 @@
-dumper = Dumper(StringIO.StringIO())
+dumper = Dumper(io.StringIO())
 dumper.serialize(ScalarNode(tag='!foo', value='bar'))
diff --git tests/test_appliance.py tests/test_appliance.py
index d5e5d3e..5f3c23f 100644
--- tests/test_appliance.py
+++ tests/test_appliance.py
@@ -43,7 +43,7 @@ class Error(Exception):
 class CanonicalScanner:
 
     def __init__(self, data):
-        self.data = unicode(data, 'utf-8')+u'\0'
+        self.data = str(data, 'utf-8')+'\0'
         self.index = 0
         self.scan()
 
@@ -76,60 +76,60 @@ class CanonicalScanner:
         while True:
             self.find_token()
             ch = self.data[self.index]
-            if ch == u'\0':
+            if ch == '\0':
                 self.tokens.append(StreamEndToken(None, None))
                 break
-            elif ch == u'%':
+            elif ch == '%':
                 self.tokens.append(self.scan_directive())
-            elif ch == u'-' and self.data[self.index:self.index+3] == u'---':
+            elif ch == '-' and self.data[self.index:self.index+3] == '---':
                 self.index += 3
                 self.tokens.append(DocumentStartToken(None, None))
-            elif ch == u'[':
+            elif ch == '[':
                 self.index += 1
                 self.tokens.append(FlowSequenceStartToken(None, None))
-            elif ch == u'{':
+            elif ch == '{':
                 self.index += 1
                 self.tokens.append(FlowMappingStartToken(None, None))
-            elif ch == u']':
+            elif ch == ']':
                 self.index += 1
                 self.tokens.append(FlowSequenceEndToken(None, None))
-            elif ch == u'}':
+            elif ch == '}':
                 self.index += 1
                 self.tokens.append(FlowMappingEndToken(None, None))
-            elif ch == u'?':
+            elif ch == '?':
                 self.index += 1
                 self.tokens.append(KeyToken(None, None))
-            elif ch == u':':
+            elif ch == ':':
                 self.index += 1
                 self.tokens.append(ValueToken(None, None))
-            elif ch == u',':
+            elif ch == ',':
                 self.index += 1
                 self.tokens.append(FlowEntryToken(None, None))
-            elif ch == u'*' or ch == u'&':
+            elif ch == '*' or ch == '&':
                 self.tokens.append(self.scan_alias())
-            elif ch == u'!':
+            elif ch == '!':
                 self.tokens.append(self.scan_tag())
-            elif ch == u'"':
+            elif ch == '"':
                 self.tokens.append(self.scan_scalar())
             else:
                 raise Error("invalid token")
 
-    DIRECTIVE = u'%YAML 1.1'
+    DIRECTIVE = '%YAML 1.1'
 
     def scan_directive(self):
         if self.data[self.index:self.index+len(self.DIRECTIVE)] == self.DIRECTIVE and \
-                self.data[self.index+len(self.DIRECTIVE)] in u' \n\0':
+                self.data[self.index+len(self.DIRECTIVE)] in ' \n\0':
             self.index += len(self.DIRECTIVE)
             return DirectiveToken('YAML', (1, 1), None, None)
 
     def scan_alias(self):
-        if self.data[self.index] == u'*':
+        if self.data[self.index] == '*':
             TokenClass = AliasToken
         else:
             TokenClass = AnchorToken
         self.index += 1
         start = self.index
-        while self.data[self.index] not in u', \n\0':
+        while self.data[self.index] not in ', \n\0':
             self.index += 1
         value = self.data[start:self.index]
         return TokenClass(value, None, None)
@@ -137,15 +137,15 @@ class CanonicalScanner:
     def scan_tag(self):
         self.index += 1
         start = self.index
-        while self.data[self.index] not in u' \n\0':
+        while self.data[self.index] not in ' \n\0':
             self.index += 1
         value = self.data[start:self.index]
-        if value[0] == u'!':
+        if value[0] == '!':
             value = 'tag:yaml.org,2002:'+value[1:]
-        elif value[0] == u'<' and value[-1] == u'>':
+        elif value[0] == '<' and value[-1] == '>':
             value = value[1:-1]
         else:
-            value = u'!'+value
+            value = '!'+value
         return TagToken(value, None, None)
 
     QUOTE_CODES = {
@@ -155,22 +155,22 @@ class CanonicalScanner:
     }
 
     QUOTE_REPLACES = {
-        u'\\': u'\\',
-        u'\"': u'\"',
-        u' ': u' ',
-        u'a': u'\x07',
-        u'b': u'\x08',
-        u'e': u'\x1B',
-        u'f': u'\x0C',
-        u'n': u'\x0A',
-        u'r': u'\x0D',
-        u't': u'\x09',
-        u'v': u'\x0B',
-        u'N': u'\u0085',
-        u'L': u'\u2028',
-        u'P': u'\u2029',
-        u'_': u'_',
-        u'0': u'\x00',
+        '\\': '\\',
+        '\"': '\"',
+        ' ': ' ',
+        'a': '\x07',
+        'b': '\x08',
+        'e': '\x1B',
+        'f': '\x0C',
+        'n': '\x0A',
+        'r': '\x0D',
+        't': '\x09',
+        'v': '\x0B',
+        'N': '\u0085',
+        'L': '\u2028',
+        'P': '\u2029',
+        '_': '_',
+        '0': '\x00',
 
     }
 
@@ -179,30 +179,30 @@ class CanonicalScanner:
         chunks = []
         start = self.index
         ignore_spaces = False
-        while self.data[self.index] != u'"':
-            if self.data[self.index] == u'\\':
+        while self.data[self.index] != '"':
+            if self.data[self.index] == '\\':
                 ignore_spaces = False
                 chunks.append(self.data[start:self.index])
                 self.index += 1
                 ch = self.data[self.index]
                 self.index += 1
-                if ch == u'\n':
+                if ch == '\n':
                     ignore_spaces = True
                 elif ch in self.QUOTE_CODES:
                     length = self.QUOTE_CODES[ch]
                     code = int(self.data[self.index:self.index+length], 16)
-                    chunks.append(unichr(code))
+                    chunks.append(chr(code))
                     self.index += length
                 else:
                     chunks.append(self.QUOTE_REPLACES[ch])
                 start = self.index
-            elif self.data[self.index] == u'\n':
+            elif self.data[self.index] == '\n':
                 chunks.append(self.data[start:self.index])
-                chunks.append(u' ')
+                chunks.append(' ')
                 self.index += 1
                 start = self.index
                 ignore_spaces = True
-            elif ignore_spaces and self.data[self.index] == u' ':
+            elif ignore_spaces and self.data[self.index] == ' ':
                 self.index += 1
                 start = self.index
             else:
@@ -210,17 +210,17 @@ class CanonicalScanner:
                 self.index += 1
         chunks.append(self.data[start:self.index])
         self.index += 1
-        return ScalarToken(u''.join(chunks), False, None, None)
+        return ScalarToken(''.join(chunks), False, None, None)
 
     def find_token(self):
         found = False
         while not found:
-            while self.data[self.index] in u' \t':
+            while self.data[self.index] in ' \t':
                 self.index += 1
-            if self.data[self.index] == u'#':
-                while self.data[self.index] != u'\n':
+            if self.data[self.index] == '#':
+                while self.data[self.index] != '\n':
                     self.index += 1
-            if self.data[self.index] == u'\n':
+            if self.data[self.index] == '\n':
                 self.index += 1
             else:
                 found = True
diff --git tests/test_canonical.py tests/test_canonical.py
index 4416902..73804bc 100644
--- tests/test_canonical.py
+++ tests/test_canonical.py
@@ -4,16 +4,16 @@ import test_appliance
 class TestCanonicalAppliance(test_appliance.TestAppliance):
 
     def _testCanonicalScanner(self, test_name, canonical_filename):
-        data = file(canonical_filename, 'rb').read()
+        data = open(canonical_filename, 'rb').read()
         tokens = list(test_appliance.canonical_scan(data))
         #for token in tokens:
-        #    print token
+        #    print(token)
 
     def _testCanonicalParser(self, test_name, canonical_filename):
-        data = file(canonical_filename, 'rb').read()
+        data = open(canonical_filename, 'rb').read()
         event = list(test_appliance.canonical_parse(data))
         #for event in events:
-        #    print event
+        #    print(event)
 
 TestCanonicalAppliance.add_tests('testCanonicalScanner', '.canonical')
 TestCanonicalAppliance.add_tests('testCanonicalParser', '.canonical')
diff --git tests/test_constructor.py tests/test_constructor.py
index 04f54ef..3d72e5f 100644
--- tests/test_constructor.py
+++ tests/test_constructor.py
@@ -2,10 +2,6 @@
 import test_appliance
 
 import datetime
-try:
-    set
-except NameError:
-    from sets import Set as set
 
 from yaml import *
 
@@ -111,7 +107,7 @@ class YAMLObject2(YAMLObject):
         else:
             return False
 
-class AnObject(object):
+class AnObject:
 
     def __new__(cls, foo=None, bar=None, baz=None):
         self = object.__new__(cls)
@@ -128,22 +124,11 @@ class AnObject(object):
         return type(self) is type(other) and    \
                 (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
 
-class AnInstance:
+    def __repr__(self):
+        return '%s(foo=%r, bar=%r, baz=%r)' %    \
+                (self.__class__.__name__, self.foo, self.bar, self.baz)
 
-    def __init__(self, foo=None, bar=None, baz=None):
-        self.foo = foo
-        self.bar = bar
-        self.baz = baz
-
-    def __cmp__(self, other):
-        return cmp((type(self), self.foo, self.bar, self.baz),
-                (type(other), other.foo, other.bar, other.baz))
-
-    def __eq__(self, other):
-        return type(self) is type(other) and    \
-                (self.foo, self.bar, self.baz) == (other.foo, other.bar, other.baz)
-
-class AState(AnInstance):
+class AState(AnObject):
 
     def __getstate__(self):
         return {
@@ -157,7 +142,7 @@ class AState(AnInstance):
         self.bar = state['_bar']
         self.baz = state['_baz']
 
-class ACustomState(AnInstance):
+class ACustomState(AnObject):
 
     def __getstate__(self):
         return (self.foo, self.bar, self.baz)
@@ -165,25 +150,6 @@ class ACustomState(AnInstance):
     def __setstate__(self, state):
         self.foo, self.bar, self.baz = state
 
-class InitArgs(AnInstance):
-
-    def __getinitargs__(self):
-        return (self.foo, self.bar, self.baz)
-
-    def __getstate__(self):
-        return {}
-
-class InitArgsWithState(AnInstance):
-
-    def __getinitargs__(self):
-        return (self.foo, self.bar)
-
-    def __getstate__(self):
-        return self.baz
-
-    def __setstate__(self, state):
-        self.baz = state
-
 class NewArgs(AnObject):
 
     def __getnewargs__(self):
@@ -255,7 +221,7 @@ class FixedOffset(datetime.tzinfo):
 
 
 def execute(code):
-    exec code
+    exec(code)
     return value
 
 class TestConstructorTypes(test_appliance.TestAppliance):
@@ -264,10 +230,10 @@ class TestConstructorTypes(test_appliance.TestAppliance):
         data1 = None
         data2 = None
         try:
-            data1 = list(load_all(file(data_filename, 'rb'), Loader=MyLoader))
+            data1 = list(load_all(open(data_filename, 'rb'), Loader=MyLoader))
             if len(data1) == 1:
                 data1 = data1[0]
-            data2 = eval(file(code_filename, 'rb').read())
+            data2 = eval(open(code_filename, 'rb').read())
             self.failUnlessEqual(type(data1), type(data2))
             try:
                 self.failUnlessEqual(data1, data2)
@@ -300,13 +266,13 @@ class TestConstructorTypes(test_appliance.TestAppliance):
                 else:
                     raise
         except:
-            print
-            print "DATA:"
-            print file(data_filename, 'rb').read()
-            print "CODE:"
-            print file(code_filename, 'rb').read()
-            print "NATIVES1:", data1
-            print "NATIVES2:", data2
+            print()
+            print("DATA:")
+            print(open(data_filename, 'rb').read())
+            print("CODE:")
+            print(open(code_filename, 'rb').read())
+            print("NATIVES1:", repr(data1))
+            print("NATIVES2:", repr(data2))
             raise
 
 TestConstructorTypes.add_tests('testTypes', '.data', '.code')
diff --git tests/test_emitter.py tests/test_emitter.py
index d45cd8f..bf93dba 100644
--- tests/test_emitter.py
+++ tests/test_emitter.py
@@ -1,5 +1,5 @@
 
-import test_appliance, sys, StringIO
+import test_appliance, sys, io
 
 from yaml import *
 import yaml
@@ -16,9 +16,9 @@ class TestEmitter(test_appliance.TestAppliance):
         self._testEmitter(test_name, canonical_filename, True)
 
     def _testEmitter(self, test_name, filename, canonical=None):
-        events = list(parse(file(filename, 'rb')))
+        events = list(parse(open(filename, 'rb')))
         #self._dump(filename, events, canonical)
-        stream = StringIO.StringIO()
+        stream = io.StringIO()
         emit(events, stream, canonical=canonical)
         data = stream.getvalue()
         new_events = list(parse(data))
@@ -35,11 +35,11 @@ class TestEmitter(test_appliance.TestAppliance):
                 self.failUnlessEqual(event.value, new_event.value)
 
     def _dump(self, filename, events, canonical):
-        print "="*30
-        print "ORIGINAL DOCUMENT:"
-        print file(filename, 'rb').read()
-        print '-'*30
-        print "EMITTED DOCUMENT:"
+        print("="*30)
+        print("ORIGINAL DOCUMENT:")
+        print(open(filename, 'rb').read())
+        print('-'*30)
+        print("EMITTED DOCUMENT:")
         emit(events, sys.stdout, canonical=canonical)
         
 TestEmitter.add_tests('testEmitterOnData', '.canonical', '.data')
@@ -71,9 +71,9 @@ EventsLoader.add_constructor(None, EventsLoader.construct_event)
 class TestEmitterEvents(test_appliance.TestAppliance):
 
     def _testEmitterEvents(self, test_name, events_filename):
-        events = list(load(file(events_filename, 'rb'), Loader=EventsLoader))
+        events = list(load(open(events_filename, 'rb'), Loader=EventsLoader))
         #self._dump(events_filename, events)
-        stream = StringIO.StringIO()
+        stream = io.StringIO()
         emit(events, stream)
         data = stream.getvalue()
         new_events = list(parse(data))
@@ -90,11 +90,11 @@ class TestEmitterEvents(test_appliance.TestAppliance):
                 self.failUnlessEqual(event.value, new_event.value)
 
     def _dump(self, events_filename, events):
-        print "="*30
-        print "EVENTS:"
-        print file(events_filename, 'rb').read()
-        print '-'*30
-        print "OUTPUT:"
+        print("="*30)
+        print("EVENTS:")
+        print(open(events_filename, 'rb').read())
+        print('-'*30)
+        print("OUTPUT:")
         emit(events, sys.stdout)
         
 TestEmitterEvents.add_tests('testEmitterEvents', '.events')
diff --git tests/test_errors.py tests/test_errors.py
index 7d6e0d2..02df778 100644
--- tests/test_errors.py
+++ tests/test_errors.py
@@ -2,7 +2,7 @@
 import test_appliance
 import test_emitter
 
-import StringIO
+import io
 
 from yaml import *
 
@@ -21,66 +21,66 @@ class TestErrors(test_appliance.TestAppliance):
         self.failUnlessRaises(YAMLError, lambda: self._load_single(invalid_filename))
 
     def _testEmitterErrors(self, test_name, invalid_filename):
-        events = list(load(file(invalid_filename, 'rb').read(),
+        events = list(load(open(invalid_filename, 'rb').read(),
             Loader=test_emitter.EventsLoader))
         self.failUnlessRaises(YAMLError, lambda: self._emit(events))
 
     def _testDumperErrors(self, test_name, invalid_filename):
-        code = file(invalid_filename, 'rb').read()
+        code = open(invalid_filename, 'r').read()
         self.failUnlessRaises(YAMLError, lambda: self._dump(code))
 
     def _dump(self, code):
         try:
-            exec code
-        except YAMLError, exc:
-            #print '.'*70
-            #print "%s:" % exc.__class__.__name__, exc
+            exec(code)
+        except YAMLError as exc:
+            #print('.'*70)
+            #print("%s:" % exc.__class__.__name__, exc)
             raise
 
     def _emit(self, events):
         try:
             emit(events)
-        except YAMLError, exc:
-            #print '.'*70
-            #print "%s:" % exc.__class__.__name__, exc
+        except YAMLError as exc:
+            #print('.'*70)
+            #print("%s:" % exc.__class__.__name__, exc)
             raise
 
     def _load(self, filename):
         try:
-            return list(load_all(file(filename, 'rb')))
-        except YAMLError, exc:
+            return list(load_all(open(filename, 'rb')))
+        except YAMLError as exc:
         #except ScannerError, exc:
         #except ParserError, exc:
         #except ComposerError, exc:
         #except ConstructorError, exc:
-            #print '.'*70
-            #print "%s:" % exc.__class__.__name__, exc
+            #print('.'*70)
+            #print("%s:" % exc.__class__.__name__, exc)
             raise
 
     def _load_string(self, filename):
         try:
-            return list(load_all(file(filename, 'rb').read()))
-        except YAMLError, exc:
+            return list(load_all(open(filename, 'rb').read()))
+        except YAMLError as exc:
         #except ScannerError, exc:
         #except ParserError, exc:
         #except ComposerError, exc:
         #except ConstructorError, exc:
-            #print '.'*70
-            #print "%s:" % filename
-            #print "%s:" % exc.__class__.__name__, exc
+            #print('.'*70)
+            #print("%s:" % filename)
+            #print("%s:" % exc.__class__.__name__, exc)
             raise
 
     def _load_single(self, filename):
         try:
-            return load(file(filename, 'rb').read())
-        except YAMLError, exc:
+            return load(open(filename, 'rb').read())
+        except YAMLError as exc:
         #except ScannerError, exc:
         #except ParserError, exc:
         #except ComposerError, exc:
         #except ConstructorError, exc:
-            #print '.'*70
-            #print "%s:" % filename
-            #print "%s:" % exc.__class__.__name__, exc
+            #print('.'*70)
+            #print("%s:" % filename)
+            #print("%s:" % exc.__class__.__name__, exc)
             raise
 
 TestErrors.add_tests('testLoaderErrors', '.loader-error')
diff --git tests/test_mark.py tests/test_mark.py
index 4fa665e..12f73fa 100644
--- tests/test_mark.py
+++ tests/test_mark.py
@@ -6,7 +6,7 @@ from yaml.reader import Mark
 class TestMark(test_appliance.TestAppliance):
 
     def _testMarks(self, test_name, marks_filename):
-        inputs = file(marks_filename, 'rb').read().split('---\n')[1:]
+        inputs = open(marks_filename, 'r').read().split('---\n')[1:]
         for input in inputs:
             index = 0
             line = 0
@@ -18,12 +18,12 @@ class TestMark(test_appliance.TestAppliance):
                 else:
                     column += 1
                 index += 1
-            mark = Mark(test_name, index, line, column, unicode(input), index)
+            mark = Mark(test_name, index, line, column, input, index)
             snippet = mark.get_snippet(indent=2, max_length=79)
-            #print "INPUT:"
-            #print input
-            #print "SNIPPET:"
-            #print snippet
+            #print("INPUT:")
+            #print(input)
+            #print("SNIPPET:")
+            #print(snippet)
             self.failUnless(isinstance(snippet, str))
             self.failUnlessEqual(snippet.count('\n'), 1)
             data, pointer = snippet.split('\n')
diff --git tests/test_reader.py tests/test_reader.py
index 1bfae1a..bafae4e 100644
--- tests/test_reader.py
+++ tests/test_reader.py
@@ -9,7 +9,7 @@ class TestReaderErrors(test_appliance.TestAppliance):
     def _testReaderUnicodeErrors(self, test_name, stream_filename):
         for encoding in ['utf-8', 'utf-16-le', 'utf-16-be']:
             try:
-                data = unicode(file(stream_filename, 'rb').read(), encoding)
+                data = open(stream_filename, 'rb').read().decode(encoding)
                 break
             except:
                 pass
@@ -22,23 +22,23 @@ class TestReaderErrors(test_appliance.TestAppliance):
         self.failUnlessRaises(ReaderError,
                 lambda: self._load(codecs.open(stream_filename, encoding=encoding)))
 
-    def _testReaderStringErrors(self, test_name, stream_filename):
-        data = file(stream_filename, 'rb').read()
+    def _testReaderBytesErrors(self, test_name, stream_filename):
+        data = open(stream_filename, 'rb').read()
         #self._load(data)
         self.failUnlessRaises(ReaderError, lambda: self._load(data))
 
     def _testReaderFileErrors(self, test_name, stream_filename):
-        data = file(stream_filename, 'rb')
+        data = open(stream_filename, 'rb').read()
         #self._load(data)
         self.failUnlessRaises(ReaderError, lambda: self._load(data))
 
     def _load(self, data):
         stream = Reader(data)
-        while stream.peek() != u'\0':
+        while stream.peek() != '\0':
             stream.forward()
 
 TestReaderErrors.add_tests('testReaderUnicodeErrors', '.stream-error')
-TestReaderErrors.add_tests('testReaderStringErrors', '.stream-error')
+TestReaderErrors.add_tests('testReaderBytesErrors', '.stream-error')
 TestReaderErrors.add_tests('testReaderFileErrors', '.stream-error')
 
 
diff --git tests/test_recursive.py tests/test_recursive.py
index 3c09264..a9cac1f 100644
--- tests/test_recursive.py
+++ tests/test_recursive.py
@@ -27,25 +27,25 @@ class AnInstanceWithState(AnInstance):
 class TestRecursive(test_appliance.TestAppliance):
 
     def _testRecursive(self, test_name, recursive_filename):
-        exec file(recursive_filename, 'r').read()
-        value1 = value
+        exec(open(recursive_filename, 'r').read())
+        value1 = locals()['value']
         output1 = None
         value2 = None
         output2 = None
         try:
             output1 = dump(value1)
-            #print "OUTPUT %s:" % test_name
-            #print output1
+            #print("OUTPUT %s:" % test_name)
+            #print(output1)
             value2 = load(output1)
             output2 = dump(value2)
             self.failUnlessEqual(output1, output2)
         except:
-            print "VALUE1:", value1
-            print "VALUE2:", value2
-            print "OUTPUT1:"
-            print output1
-            print "OUTPUT2:"
-            print output2
+            print("VALUE1:", value1)
+            print("VALUE2:", value2)
+            print("OUTPUT1:")
+            print(output1)
+            print("OUTPUT2:")
+            print(output2)
             raise
 
 TestRecursive.add_tests('testRecursive', '.recursive')
diff --git tests/test_representer.py tests/test_representer.py
index 6746146..665def6 100644
--- tests/test_representer.py
+++ tests/test_representer.py
@@ -10,7 +10,7 @@ class TestRepresenterTypes(test_appliance.TestAppliance):
         return self._testTypes(test_name, data_filename, code_filename, allow_unicode=True)
 
     def _testTypes(self, test_name, data_filename, code_filename, allow_unicode=False):
-        data1 = eval(file(code_filename, 'rb').read())
+        data1 = eval(open(code_filename, 'rb').read())
         data2 = None
         output = None
         try:
@@ -48,11 +48,11 @@ class TestRepresenterTypes(test_appliance.TestAppliance):
                 else:
                     raise
         except:
-            print
-            print "OUTPUT:"
-            print output
-            print "NATIVES1:", data1
-            print "NATIVES2:", data2
+            print()
+            print("OUTPUT:")
+            print(output)
+            print("NATIVES1:", repr(data1))
+            print("NATIVES2:", repr(data2))
             raise
 
 TestRepresenterTypes.add_tests('testTypes', '.data', '.code')
diff --git tests/test_resolver.py tests/test_resolver.py
index a1845d8..b0693f2 100644
--- tests/test_resolver.py
+++ tests/test_resolver.py
@@ -9,19 +9,19 @@ class MyLoader(Loader):
 class MyDumper(Dumper):
     pass
 
-add_path_resolver(u'!root', [],
+add_path_resolver('!root', [],
         Loader=MyLoader, Dumper=MyDumper)
 
-add_path_resolver(u'!root/scalar', [], str,
+add_path_resolver('!root/scalar', [], str,
         Loader=MyLoader, Dumper=MyDumper)
 
-add_path_resolver(u'!root/key11/key12/*', ['key11', 'key12'],
+add_path_resolver('!root/key11/key12/*', ['key11', 'key12'],
         Loader=MyLoader, Dumper=MyDumper)
 
-add_path_resolver(u'!root/key21/1/*', ['key21', 1],
+add_path_resolver('!root/key21/1/*', ['key21', 1],
         Loader=MyLoader, Dumper=MyDumper)
 
-add_path_resolver(u'!root/key31/*/*/key14/map', ['key31', None, None, 'key14'], dict,
+add_path_resolver('!root/key31/*/*/key14/map', ['key31', None, None, 'key14'], dict,
         Loader=MyLoader, Dumper=MyDumper)
 
 class TestResolver(test_appliance.TestAppliance):
@@ -30,35 +30,35 @@ class TestResolver(test_appliance.TestAppliance):
         node = None
         correct_tag = None
         try:
-            correct_tag = file(detect_filename, 'rb').read().strip()
-            node = compose(file(data_filename, 'rb'))
+            correct_tag = open(detect_filename, 'r').read().strip()
+            node = compose(open(data_filename, 'rb'))
             self.failUnless(isinstance(node, SequenceNode))
             for scalar in node.value:
                 self.failUnless(isinstance(scalar, ScalarNode))
                 self.failUnlessEqual(scalar.tag, correct_tag)
         except:
-            print
-            print "DATA:"
-            print file(data_filename, 'rb').read()
-            print "CORRECT_TAG:"
-            print file(detect_filename, 'rb').read()
-            print "ROOT NODE:", node
-            print "SCALAR NODES:", node.value
+            print()
+            print("DATA:")
+            print(open(data_filename, 'rb').read())
+            print("CORRECT_TAG:")
+            print(open(detect_filename, 'rb').read())
+            print("ROOT NODE:", node)
+            print("SCALAR NODES:", node.value)
             raise
 
     def _testPathResolverLoader(self, test_name, data_filename, path_filename):
-        #print serialize_all(compose_all(file(data_filename, 'rb').read(), Loader=MyLoader))
-        nodes1 = compose_all(file(data_filename, 'rb').read(), Loader=MyLoader)
-        nodes2 = compose_all(file(path_filename, 'rb').read())
+        #print(serialize_all(compose_all(open(data_filename, 'rb').read(), Loader=MyLoader)))
+        nodes1 = compose_all(open(data_filename, 'rb').read(), Loader=MyLoader)
+        nodes2 = compose_all(open(path_filename, 'rb').read())
         for node1, node2 in zip(nodes1, nodes2):
             self.failUnlessEqual(self._convert(node1), self._convert(node2))
 
     def _testPathResolverDumper(self, test_name, data_filename, path_filename):
         for filename in [data_filename, path_filename]:
-            output = serialize_all(compose_all(file(filename, 'rb').read()), Dumper=MyDumper)
-            #print output
+            output = serialize_all(compose_all(open(filename, 'rb').read()), Dumper=MyDumper)
+            #print(output)
             nodes1 = compose_all(output)
-            nodes2 = compose_all(file(data_filename, 'rb').read())
+            nodes2 = compose_all(open(data_filename, 'rb').read())
             for node1, node2 in zip(nodes1, nodes2):
                 self.failUnlessEqual(self._convert(node1), self._convert(node2))
 
diff --git tests/test_structure.py tests/test_structure.py
index 0aef982..1919b47 100644
--- tests/test_structure.py
+++ tests/test_structure.py
@@ -7,9 +7,9 @@ class TestStructure(test_appliance.TestAppliance):
 
     def _testStructure(self, test_name, data_filename, structure_filename):
         node1 = None
-        node2 = eval(file(structure_filename, 'rb').read())
+        node2 = eval(open(structure_filename, 'rb').read())
         try:
-            loader = Loader(file(data_filename, 'rb'))
+            loader = Loader(open(data_filename, 'rb'))
             node1 = []
             while not loader.check_event(StreamEndEvent):
                 if not loader.check_event(StreamStartEvent, DocumentStartEvent, DocumentEndEvent):
@@ -21,11 +21,11 @@ class TestStructure(test_appliance.TestAppliance):
                 node1 = node1[0]
             self.failUnlessEqual(node1, node2)
         except:
-            print
-            print "DATA:"
-            print file(data_filename, 'rb').read()
-            print "NODE1:", node1
-            print "NODE2:", node2
+            print()
+            print("DATA:")
+            print(open(data_filename, 'rb').read())
+            print("NODE1:", node1)
+            print("NODE2:", node2)
             raise
 
     def _convert(self, loader):
@@ -66,17 +66,17 @@ class TestParser(test_appliance.TestAppliance):
         events1 = None
         events2 = None
         try:
-            events1 = list(parse(file(data_filename, 'rb')))
-            events2 = list(test_appliance.canonical_parse(file(canonical_filename, 'rb')))
+            events1 = list(parse(open(data_filename, 'rb')))
+            events2 = list(test_appliance.canonical_parse(open(canonical_filename, 'rb')))
             self._compare(events1, events2)
         except:
-            print
-            print "DATA1:"
-            print file(data_filename, 'rb').read()
-            print "DATA2:"
-            print file(canonical_filename, 'rb').read()
-            print "EVENTS1:", events1
-            print "EVENTS2:", events2
+            print()
+            print("DATA1:")
+            print(open(data_filename, 'rb').read())
+            print("DATA2:")
+            print(open(canonical_filename, 'rb').read())
+            print("EVENTS1:", events1)
+            print("EVENTS2:", events2)
             raise
 
     def _compare(self, events1, events2):
@@ -103,19 +103,19 @@ class TestResolver(test_appliance.TestAppliance):
         nodes1 = None
         nodes2 = None
         try:
-            nodes1 = list(compose_all(file(data_filename, 'rb')))
-            nodes2 = list(test_appliance.canonical_compose_all(file(canonical_filename, 'rb')))
+            nodes1 = list(compose_all(open(data_filename, 'rb')))
+            nodes2 = list(test_appliance.canonical_compose_all(open(canonical_filename, 'rb')))
             self.failUnlessEqual(len(nodes1), len(nodes2))
             for node1, node2 in zip(nodes1, nodes2):
                 self._compare(node1, node2)
         except:
-            print
-            print "DATA1:"
-            print file(data_filename, 'rb').read()
-            print "DATA2:"
-            print file(canonical_filename, 'rb').read()
-            print "NODES1:", nodes1
-            print "NODES2:", nodes2
+            print()
+            print("DATA1:")
+            print(open(data_filename, 'rb').read())
+            print("DATA2:")
+            print(open(canonical_filename, 'rb').read())
+            print("NODES1:", nodes1)
+            print("NODES2:", nodes2)
             raise
 
     def _compare(self, node1, node2):
@@ -129,12 +129,10 @@ class TestResolver(test_appliance.TestAppliance):
                 self._compare(item1, item2)
         elif isinstance(node1, MappingNode):
             self.failUnlessEqual(len(node1.value), len(node2.value))
-            items1 = node1.value.items()
-            items1.sort(lambda (k1,v1), (k2,v2): cmp((k1.tag,k1.value,v1.tag,v1.value),
-                                                    (k2.tag,k2.value,v2.tag,v2.value)))
-            items2 = node2.value.items()
-            items2.sort(lambda (k1,v1), (k2,v2): cmp((k1.tag,k1.value,v1.tag,v1.value),
-                                                    (k2.tag,k2.value,v2.tag,v2.value)))
+            items1 = list(node1.value.items())
+            items1.sort(key=lambda kv: (kv[0].tag, kv[0].value, kv[1].tag, kv[1].value))
+            items2 = list(node2.value.items())
+            items2.sort(key=lambda kv: (kv[0].tag, kv[0].value, kv[1].tag, kv[1].value))
             for (key1, value1), (key2, value2) in zip(items1, items2):
                 self._compare(key1, key2)
                 self._compare(value1, value2)
@@ -147,13 +145,12 @@ class MyLoader(Loader):
 
     def construct_mapping(self, node):
         pairs = self.construct_pairs(node)
-        pairs.sort()
         return pairs
 
     def construct_undefined(self, node):
         return self.construct_scalar(node)
 
-MyLoader.add_constructor(u'tag:yaml.org,2002:map', MyLoader.construct_mapping)
+MyLoader.add_constructor('tag:yaml.org,2002:map', MyLoader.construct_mapping)
 MyLoader.add_constructor(None, MyLoader.construct_undefined)
 
 class MyCanonicalLoader(test_appliance.CanonicalLoader):
@@ -163,13 +160,12 @@ class MyCanonicalLoader(test_appliance.CanonicalLoader):
 
     def construct_mapping(self, node):
         pairs = self.construct_pairs(node)
-        pairs.sort()
         return pairs
 
     def construct_undefined(self, node):
         return self.construct_scalar(node)
 
-MyCanonicalLoader.add_constructor(u'tag:yaml.org,2002:map', MyCanonicalLoader.construct_mapping)
+MyCanonicalLoader.add_constructor('tag:yaml.org,2002:map', MyCanonicalLoader.construct_mapping)
 MyCanonicalLoader.add_constructor(None, MyCanonicalLoader.construct_undefined)
 
 class TestConstructor(test_appliance.TestAppliance):
@@ -178,17 +174,17 @@ class TestConstructor(test_appliance.TestAppliance):
         data1 = None
         data2 = None
         try:
-            data1 = list(load_all(file(data_filename, 'rb'), Loader=MyLoader))
-            data2 = list(load_all(file(canonical_filename, 'rb'), Loader=MyCanonicalLoader))
+            data1 = list(load_all(open(data_filename, 'rb'), Loader=MyLoader))
+            data2 = list(load_all(open(canonical_filename, 'rb'), Loader=MyCanonicalLoader))
             self.failUnlessEqual(data1, data2)
         except:
-            print
-            print "DATA1:"
-            print file(data_filename, 'rb').read()
-            print "DATA2:"
-            print file(canonical_filename, 'rb').read()
-            print "NATIVES1:", data1
-            print "NATIVES2:", data2
+            print()
+            print("DATA1:")
+            print(open(data_filename, 'rb').read())
+            print("DATA2:")
+            print(open(canonical_filename, 'rb').read())
+            print("NATIVES1:", data1)
+            print("NATIVES2:", data2)
             raise
 
 TestConstructor.add_tests('testConstructor', '.data', '.canonical')
@@ -199,15 +195,15 @@ class TestParserOnCanonical(test_appliance.TestAppliance):
         events1 = None
         events2 = None
         try:
-            events1 = list(parse(file(canonical_filename, 'rb')))
-            events2 = list(test_appliance.canonical_parse(file(canonical_filename, 'rb')))
+            events1 = list(parse(open(canonical_filename, 'rb')))
+            events2 = list(test_appliance.canonical_parse(open(canonical_filename, 'rb')))
             self._compare(events1, events2)
         except:
-            print
-            print "DATA:"
-            print file(canonical_filename, 'rb').read()
-            print "EVENTS1:", events1
-            print "EVENTS2:", events2
+            print()
+            print("DATA:")
+            print(open(canonical_filename, 'rb').read())
+            print("EVENTS1:", events1)
+            print("EVENTS2:", events2)
             raise
 
     def _compare(self, events1, events2):
diff --git tests/test_syck.py tests/test_syck.py
index dd63056..95979c0 100644
--- tests/test_syck.py
+++ tests/test_syck.py
@@ -7,18 +7,18 @@ class TestSyck(test_appliance.TestAppliance):
         try:
             syck.parse(file(data_filename, 'rb'))
         except:
-            print
-            print "DATA:"
-            print file(data_filename, 'rb').read()
+            print()
+            print("DATA:")
+            print(file(data_filename, 'rb').read())
             raise
 
     def _testSyckOnCanonicalTests(self, test_name, data_filename, canonical_filename):
         try:
             syck.parse(file(data_filename, 'rb'))
         except:
-            print
-            print "DATA:"
-            print file(data_filename, 'rb').read()
+            print()
+            print("DATA:")
+            print(file(data_filename, 'rb').read())
             raise
 
 try:
diff --git tests/test_tokens.py tests/test_tokens.py
index 73d07b3..9af29c5 100644
--- tests/test_tokens.py
+++ tests/test_tokens.py
@@ -47,20 +47,20 @@ class TestTokens(test_appliance.TestAppliance):
 
     def _testTokens(self, test_name, data_filename, tokens_filename):
         tokens1 = None
-        tokens2 = file(tokens_filename, 'rb').read().split()
+        tokens2 = open(tokens_filename, 'r').read().split()
         try:
             tokens1 = []
-            for token in scan(file(data_filename, 'rb')):
+            for token in scan(open(data_filename, 'rb')):
                 if not isinstance(token, (StreamStartToken, StreamEndToken)):
                     tokens1.append(token)
             tokens1 = [self.replaces[t.__class__] for t in tokens1]
             self.failUnlessEqual(tokens1, tokens2)
         except:
-            print
-            print "DATA:"
-            print file(data_filename, 'rb').read()
-            print "TOKENS1:", tokens1
-            print "TOKENS2:", tokens2
+            print()
+            print("DATA:")
+            print(open(data_filename, 'rb').read())
+            print("TOKENS1:", tokens1)
+            print("TOKENS2:", tokens2)
             raise
 
 TestTokens.add_tests('testTokens', '.data', '.tokens')
@@ -72,14 +72,14 @@ class TestScanner(test_appliance.TestAppliance):
             tokens = None
             try:
                 tokens = []
-                for token in scan(file(filename, 'rb')):
+                for token in scan(open(filename, 'rb')):
                     if not isinstance(token, (StreamStartToken, StreamEndToken)):
                         tokens.append(token.__class__.__name__)
             except:
-                print
-                print "DATA:"
-                print file(data_filename, 'rb').read()
-                print "TOKENS:", tokens
+                print()
+                print("DATA:")
+                print(open(data_filename, 'rb').read())
+                print("TOKENS:", tokens)
                 raise
 
 TestScanner.add_tests('testScanner', '.data', '.canonical')
diff --git tests/test_yaml_ext.py tests/test_yaml_ext.py
index c5dd036..c987261 100644
--- tests/test_yaml_ext.py
+++ tests/test_yaml_ext.py
@@ -35,11 +35,11 @@ class TestCLoader(test_appliance.TestAppliance):
                 if hasattr(token, 'value'):
                     self.failUnlessEqual(token.value, ext_token.value)
         except:
-            print
-            print "DATA:"
-            print file(data_filename, 'rb').read()
-            print "TOKENS:", tokens
-            print "EXT_TOKENS:", ext_tokens
+            print()
+            print("DATA:")
+            print(file(data_filename, 'rb').read())
+            print("TOKENS:", tokens)
+            print("EXT_TOKENS:", ext_tokens)
             raise
 
     def _testCParser(self, test_name, data_filename, canonical_filename, Loader=yaml.Loader):
@@ -49,7 +49,7 @@ class TestCLoader(test_appliance.TestAppliance):
         try:
             for event in yaml.parse(data, Loader=yaml.CLoader):
                 ext_events.append(event)
-                #print "EVENT:", event
+                #print("EVENT:", event)
             self.failUnlessEqual(len(events), len(ext_events))
             for event, ext_event in zip(events, ext_events):
                 self.failUnlessEqual(event.__class__, ext_event.__class__)
@@ -68,11 +68,11 @@ class TestCLoader(test_appliance.TestAppliance):
                 if hasattr(event, 'tags'):
                     self.failUnlessEqual(event.tags, ext_event.tags)
         except:
-            print
-            print "DATA:"
-            print file(data_filename, 'rb').read()
-            print "EVENTS:", events
-            print "EXT_EVENTS:", ext_events
+            print()
+            print("DATA:")
+            print(file(data_filename, 'rb').read())
+            print("EVENTS:", events)
+            print("EXT_EVENTS:", ext_events)
             raise
 
 TestCLoader.add_tests('testCScanner', '.data', '.canonical')
@@ -108,13 +108,13 @@ class TestCEmitter(test_appliance.TestAppliance):
                 if hasattr(event, 'tags'):
                     self.failUnlessEqual(event.tags, ext_event.tags)
         except:
-            print
-            print "DATA1:"
-            print data1
-            print "DATA2:"
-            print data2
-            print "EVENTS:", events
-            print "EXT_EVENTS:", ext_events
+            print()
+            print("DATA1:")
+            print(data1)
+            print("DATA2:")
+            print(data2)
+            print("EVENTS:", events)
+            print("EXT_EVENTS:", ext_events)
             raise
 
 TestCEmitter.add_tests('testCEmitter', '.data', '.canonical')
