Index: branches/pyyaml3000/lib/yaml/constructor.py
===================================================================
--- branches/pyyaml3000/lib/yaml/constructor.py	(revision 55)
+++ branches/pyyaml3000/lib/yaml/constructor.py	(revision 56)
@@ -14,5 +14,5 @@
     from sets import Set as set
 
-import binascii
+import binascii, re
 
 class ConstructorError(MarkedYAMLError):
@@ -84,16 +84,50 @@
                     node.start_marker)
         mapping = {}
+        merge = None
         for key_node in node.value:
-            key = self.construct_object(key_node)
-            try:
-                duplicate_key = key in mapping
-            except TypeError, exc:
-                raise ConstructorError("while constructing a mapping", node.start_marker,
-                        "found unacceptable key (%s)" % exc, key_node.start_marker)
-            if duplicate_key:
-                raise ConstructorError("while constructing a mapping", node.start_marker,
-                        "found duplicate key", key_node.start_marker)
-            value = self.construct_object(node.value[key_node])
-            mapping[key] = value
+            if key_node.tag == u'tag:yaml.org,2002:merge':
+                if merge is not None:
+                    raise ConstructorError("while constructing a mapping", node.start_marker,
+                            "found duplicate merge key", key_node.start_marker)
+                    value_node = node.value[key_node]
+                    if isinstance(value_node, MappingNode):
+                        merge = [self.construct_mapping(value_node)]
+                    elif isinstance(value_node, SequenceNode):
+                        merge = []
+                        for subnode in value_node.value:
+                            if not isinstance(subnode, MappingNode):
+                                raise ConstructorError("while constructing a mapping",
+                                        node.start_marker,
+                                        "expected a mapping for merging, but found %s"
+                                        % subnode.id, subnode.start_marker)
+                            merge.append(self.construct_mapping(subnode))
+                        merge.reverse()
+                    else:
+                        raise ConstructorError("while constructing a mapping", node.start_marker,
+                                "expected a mapping or list of mappings for merging, but found %s"
+                                % value_node.id, value_node.start_marker)
+            elif key_node.tag == u'tag:yaml.org,2002:value':
+                if '=' in mapping:
+                    raise ConstructorError("while construction a mapping", node.start_marker,
+                            "found duplicate value key", key_node.start_marker)
+                value = self.construct_object(node.value[key_node])
+                mapping['='] = value
+            else:
+                key = self.construct_object(key_node)
+                try:
+                    duplicate_key = key in mapping
+                except TypeError, exc:
+                    raise ConstructorError("while constructing a mapping", node.start_marker,
+                            "found unacceptable key (%s)" % exc, key_node.start_marker)
+                if duplicate_key:
+                    raise ConstructorError("while constructing a mapping", node.start_marker,
+                            "found duplicate key", key_node.start_marker)
+                value = self.construct_object(node.value[key_node])
+                mapping[key] = value
+        if merge is not None:
+            merge.append(mapping)
+            mapping = {}
+            for submapping in merge:
+                mapping.update(submapping)
         return mapping
 
@@ -202,4 +236,80 @@
                     "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])
+                -(?P<month>[0-9][0-9]?)
+                -(?P<day>[0-9][0-9]?)
+                (?:[Tt]|[ \t]+)
+                (?P<hour>[0-9][0-9]?)
+                :(?P<minute>[0-9][0-9])
+                :(?P<second>[0-9][0-9])
+                (?:\.(?P<fraction>[0-9]*))?
+                (?:[ \t]*(?:Z|(?P<tz_hour>[-+][0-9][0-9]?)
+                (?::(?P<tz_minute>[0-9][0-9])?)))?$''', re.X),
+
+    def construct_yaml_timestamp(self, node):
+        value = self.construct_scalar(node)
+        match = self.timestamp_expr.match(node.value)
+        values = match.groupdict()
+        for key in values:
+            if values[key]:
+                values[key] = int(values[key])
+            else:
+                values[key] = 0
+        fraction = values['fraction']
+        if micro:
+            while 10*fraction < 1000000:
+                fraction *= 10
+            values['fraction'] = fraction
+        stamp = datetime.datetime(values['year'], values['month'], values['day'],
+                values['hour'], values['minute'], values['second'], values['fraction'])
+        diff = datetime.timedelta(hours=values['tz_hour'], minutes=values['tz_minute'])
+        return stamp-diff
+
+    def construct_yaml_omap(self, node):
+        # Note: we do not check for duplicate keys, because it's too
+        # CPU-expensive.
+        if not isinstance(node, SequenceNode):
+            raise ConstructorError("while constructing an ordered map", node.start_marker,
+                    "expected a sequence, but found %s" % node.id, node.start_marker)
+        omap = []
+        for subnode in node.value:
+            if not isinstance(subnode, MappingNode):
+                raise ConstructorError("while constructing an ordered map", node.start_marker,
+                        "expected a mapping of length 1, but found %s" % subnode.id,
+                        subnode.start_marker)
+                if len(subnode.value) != 1:
+                    raise ConstructorError("while constructing an ordered map", node.start_marker,
+                            "expected a single mapping item, but found %d items" % len(subnode.value),
+                            subnode.start_marker)
+                key_node = subnode.value.keys()[0]
+                key = self.construct_object(key_node)
+                value = self.construct_object(subnode.value[key_node])
+                omap.append((key, value))
+
+    def construct_yaml_pairs(self, node):
+        # Note: the same code as `construct_yaml_omap`.
+        if not isinstance(node, SequenceNode):
+            raise ConstructorError("while constructing pairs", node.start_marker,
+                    "expected a sequence, but found %s" % node.id, node.start_marker)
+        omap = []
+        for subnode in node.value:
+            if not isinstance(subnode, MappingNode):
+                raise ConstructorError("while constructing pairs", node.start_marker,
+                        "expected a mapping of length 1, but found %s" % subnode.id,
+                        subnode.start_marker)
+                if len(subnode.value) != 1:
+                    raise ConstructorError("while constructing pairs", node.start_marker,
+                            "expected a single mapping item, but found %d items" % len(subnode.value),
+                            subnode.start_marker)
+                key_node = subnode.value.keys()[0]
+                key = self.construct_object(key_node)
+                value = self.construct_object(subnode.value[key_node])
+                omap.append((key, value))
+
+    def construct_yaml_set(self, node):
+        value = self.construct_mapping(node)
+        return set(value)
+
     def construct_yaml_str(self, node):
         value = self.construct_scalar(node)
@@ -209,4 +319,10 @@
             return value
 
+    def construct_yaml_seq(self, node):
+        return self.construct_sequence(node)
+
+    def construct_yaml_map(self, node):
+        return self.construct_mapping(node)
+
 Constructor.add_constructor(
         u'tag:yaml.org,2002:null',
@@ -226,6 +342,30 @@
 
 Constructor.add_constructor(
+        u'tag:yaml.org,2002:timestamp',
+        Constructor.construct_yaml_timestamp)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:omap',
+        Constructor.construct_yaml_omap)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:pairs',
+        Constructor.construct_yaml_pairs)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:set',
+        Constructor.construct_yaml_set)
+
+Constructor.add_constructor(
         u'tag:yaml.org,2002:str',
         Constructor.construct_yaml_str)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:seq',
+        Constructor.construct_yaml_seq)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:map',
+        Constructor.construct_yaml_map)
 
 class YAMLObjectMetaclass(type):
