Index: pyyaml/trunk/lib3/yaml/constructor.py
===================================================================
--- pyyaml/trunk/lib/yaml/constructor.py	(revision 303)
+++ pyyaml/trunk/lib3/yaml/constructor.py	(revision 328)
@@ -3,20 +3,13 @@
     'ConstructorError']
 
-from error import *
-from nodes import *
-
-import datetime
-
-try:
-    set
-except NameError:
-    from sets import Set as set
-
-import binascii, re, sys, types
+from .error import *
+from .nodes import *
+
+import collections, datetime, base64, binascii, re, sys, types
 
 class ConstructorError(MarkedYAMLError):
     pass
 
-class BaseConstructor(object):
+class BaseConstructor:
 
     yaml_constructors = {}
@@ -96,5 +89,5 @@
         if isinstance(data, types.GeneratorType):
             generator = data
-            data = generator.next()
+            data = next(generator)
             if self.deep_construct:
                 for dummy in generator:
@@ -131,9 +124,7 @@
         for key_node, value_node in node.value:
             key = self.construct_object(key_node, deep=deep)
-            try:
-                hash(key)
-            except TypeError, exc:
+            if not isinstance(key, collections.Hashable):
                 raise ConstructorError("while constructing a mapping", node.start_mark,
-                        "found unacceptable key (%s)" % exc, key_node.start_mark)
+                        "found unhashable key", key_node.start_mark)
             value = self.construct_object(value_node, deep=deep)
             mapping[key] = value
@@ -152,15 +143,15 @@
         return pairs
 
+    @classmethod
     def add_constructor(cls, tag, constructor):
         if not 'yaml_constructors' in cls.__dict__:
             cls.yaml_constructors = cls.yaml_constructors.copy()
         cls.yaml_constructors[tag] = constructor
-    add_constructor = classmethod(add_constructor)
-
+
+    @classmethod
     def add_multi_constructor(cls, tag_prefix, multi_constructor):
         if not 'yaml_multi_constructors' in cls.__dict__:
             cls.yaml_multi_constructors = cls.yaml_multi_constructors.copy()
         cls.yaml_multi_constructors[tag_prefix] = multi_constructor
-    add_multi_constructor = classmethod(add_multi_constructor)
 
 class SafeConstructor(BaseConstructor):
@@ -169,7 +160,7 @@
         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)
+        return super().construct_scalar(node)
 
     def flatten_mapping(self, node):
@@ -178,5 +169,5 @@
         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):
@@ -200,6 +191,6 @@
                             "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:
@@ -211,5 +202,5 @@
         if isinstance(node, MappingNode):
             self.flatten_mapping(node)
-        return BaseConstructor.construct_mapping(self, node, deep=deep)
+        return super().construct_mapping(node, deep=deep)
 
     def construct_yaml_null(self, node):
@@ -218,10 +209,10 @@
 
     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,
     }
 
@@ -231,5 +222,5 @@
 
     def construct_yaml_int(self, node):
-        value = str(self.construct_scalar(node))
+        value = self.construct_scalar(node)
         value = value.replace('_', '')
         sign = +1
@@ -264,5 +255,5 @@
 
     def construct_yaml_float(self, node):
-        value = str(self.construct_scalar(node))
+        value = self.construct_scalar(node)
         value = value.replace('_', '').lower()
         sign = +1
@@ -288,13 +279,18 @@
 
     def construct_yaml_binary(self, node):
-        value = self.construct_scalar(node)
         try:
-            return str(value).decode('base64')
-        except (binascii.Error, UnicodeEncodeError), exc:
-            raise ConstructorError(None, None,
-                    "failed to decode base64 data: %s" % exc, node.start_mark) 
+            value = self.construct_scalar(node).encode('ascii')
+        except UnicodeEncodeError as exc:
+            raise ConstructorError(None, None,
+                    "failed to convert base64 data into ascii: %s" % exc,
+                    node.start_mark)
+        try:
+            return base64.decodestring(value)
+        except binascii.Error 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]?)
@@ -387,9 +383,5 @@
 
     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):
@@ -416,53 +408,53 @@
     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)
 
@@ -473,11 +465,24 @@
 
     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):
+        try:
+            value = self.construct_scalar(node).encode('ascii')
+        except UnicodeEncodeError as exc:
+            raise ConstructorError(None, None,
+                    "failed to convert base64 data into ascii: %s" % exc,
+                    node.start_mark)
+        try:
+            return base64.decodestring(value)
+        except binascii.Error as exc:
+            raise ConstructorError(None, None,
+                    "failed to decode base64 data: %s" % exc, node.start_mark)
+
     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):
@@ -493,7 +498,7 @@
         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]
 
@@ -502,10 +507,6 @@
             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__'
@@ -513,12 +514,12 @@
         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'),
-                        module.__name__), mark)
+                    "cannot find %r in the module %r"
+                    % (object_name, module.__name__), mark)
         return getattr(module, object_name)
 
@@ -527,6 +528,5 @@
         if value:
             raise ConstructorError("while constructing a Python name", node.start_mark,
-                    "expected the empty value, but found %r" % value.encode('utf-8'),
-                    node.start_mark)
+                    "expected the empty value, but found %r" % value, node.start_mark)
         return self.find_python_name(suffix, node.start_mark)
 
@@ -535,9 +535,6 @@
         if value:
             raise ConstructorError("while constructing a Python module", node.start_mark,
-                    "expected the empty value, but found %r" % value.encode('utf-8'),
-                    node.start_mark)
+                    "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,
@@ -548,10 +545,5 @@
             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:
@@ -620,65 +612,69 @@
 
 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)
 
