Index: /pyyaml/trunk/ext/_yaml.pyx
===================================================================
--- /pyyaml/trunk/ext/_yaml.pyx	(revision 257)
+++ /pyyaml/trunk/ext/_yaml.pyx	(revision 258)
@@ -663,4 +663,22 @@
         if self.parsed_event.type != YAML_STREAM_END_EVENT:
             return self._compose_document()
+
+    def get_single_node(self):
+        self._parse_next_event()
+        yaml_event_delete(&self.parsed_event)
+        self._parse_next_event()
+        document = None
+        if self.parsed_event.type != YAML_STREAM_END_EVENT:
+            document = self._compose_document()
+        self._parse_next_event()
+        if self.parsed_event.type != YAML_STREAM_END_EVENT:
+            mark = Mark(self.stream_name,
+                    self.parsed_event.start_mark.index,
+                    self.parsed_event.start_mark.line,
+                    self.parsed_event.start_mark.column,
+                    None, None)
+            raise ComposerError("expected a single document in the stream",
+                    document.start_mark, "but found another document", mark)
+        return document
 
     cdef object _compose_document(self):
Index: /pyyaml/trunk/tests/test_errors.py
===================================================================
--- /pyyaml/trunk/tests/test_errors.py	(revision 146)
+++ /pyyaml/trunk/tests/test_errors.py	(revision 258)
@@ -16,4 +16,8 @@
         #self._load_string(invalid_filename)
         self.failUnlessRaises(YAMLError, lambda: self._load_string(invalid_filename))
+
+    def _testLoaderSingleErrors(self, test_name, invalid_filename):
+        self._load_single(invalid_filename)
+        self.failUnlessRaises(YAMLError, lambda: self._load_single(invalid_filename))
 
     def _testEmitterErrors(self, test_name, invalid_filename):
@@ -67,6 +71,20 @@
             raise
 
+    def _load_single(self, filename):
+        try:
+            return load(file(filename, 'rb').read())
+        except YAMLError, exc:
+        #except ScannerError, exc:
+        #except ParserError, exc:
+        #except ComposerError, exc:
+        #except ConstructorError, exc:
+            #print '.'*70
+            #print "%s:" % filename
+            #print "%s:" % exc.__class__.__name__, exc
+            raise
+
 TestErrors.add_tests('testLoaderErrors', '.loader-error')
 TestErrors.add_tests('testLoaderStringErrors', '.loader-error')
+TestErrors.add_tests('testLoaderSingleErrors', '.single-loader-error')
 TestErrors.add_tests('testEmitterErrors', '.emitter-error')
 TestErrors.add_tests('testDumperErrors', '.dumper-error')
Index: /pyyaml/trunk/tests/data/implicit-document.single-loader-error
===================================================================
--- /pyyaml/trunk/tests/data/implicit-document.single-loader-error	(revision 258)
+++ /pyyaml/trunk/tests/data/implicit-document.single-loader-error	(revision 258)
@@ -0,0 +1,3 @@
+foo: bar
+---
+foo: bar
Index: /pyyaml/trunk/tests/data/explicit-document.single-loader-error
===================================================================
--- /pyyaml/trunk/tests/data/explicit-document.single-loader-error	(revision 258)
+++ /pyyaml/trunk/tests/data/explicit-document.single-loader-error	(revision 258)
@@ -0,0 +1,4 @@
+---
+foo: bar
+---
+foo: bar
Index: /pyyaml/trunk/tests/data/empty-documents.single-loader-error
===================================================================
--- /pyyaml/trunk/tests/data/empty-documents.single-loader-error	(revision 258)
+++ /pyyaml/trunk/tests/data/empty-documents.single-loader-error	(revision 258)
@@ -0,0 +1,2 @@
+--- # first document
+--- # second document
Index: /pyyaml/trunk/lib/yaml/constructor.py
===================================================================
--- /pyyaml/trunk/lib/yaml/constructor.py	(revision 251)
+++ /pyyaml/trunk/lib/yaml/constructor.py	(revision 258)
@@ -37,4 +37,11 @@
         if self.check_node():
             return self.construct_document(self.get_node())
+
+    def get_single_data(self):
+        # Ensure that the stream contains a single document and construct it.
+        node = self.get_single_node()
+        if node is not None:
+            return self.construct_document(node)
+        return None
 
     def construct_document(self, node):
Index: /pyyaml/trunk/lib/yaml/composer.py
===================================================================
--- /pyyaml/trunk/lib/yaml/composer.py	(revision 233)
+++ /pyyaml/trunk/lib/yaml/composer.py	(revision 258)
@@ -26,4 +26,25 @@
         if not self.check_event(StreamEndEvent):
             return self.compose_document()
+
+    def get_single_node(self):
+        # Drop the STREAM-START event.
+        self.get_event()
+
+        # Compose a document if the stream is not empty.
+        document = None
+        if not self.check_event(StreamEndEvent):
+            document = self.compose_document()
+
+        # Ensure that the stream contains no more documents.
+        if not self.check_event(StreamEndEvent):
+            event = self.get_event()
+            raise ComposerError("expected a single document in the stream",
+                    document.start_mark, "but found another document",
+                    event.start_mark)
+
+        # Drop the STREAM-END event.
+        self.get_event()
+
+        return document
 
     def compose_document(self):
Index: /pyyaml/trunk/lib/yaml/__init__.py
===================================================================
--- /pyyaml/trunk/lib/yaml/__init__.py	(revision 252)
+++ /pyyaml/trunk/lib/yaml/__init__.py	(revision 258)
@@ -36,6 +36,5 @@
     """
     loader = Loader(stream)
-    if loader.check_node():
-        return loader.get_node()
+    return loader.get_single_node()
 
 def compose_all(stream, Loader=Loader):
@@ -48,4 +47,12 @@
         yield loader.get_node()
 
+def load(stream, Loader=Loader):
+    """
+    Parse the first YAML document in a stream
+    and produce the corresponding Python object.
+    """
+    loader = Loader(stream)
+    return loader.get_single_data()
+
 def load_all(stream, Loader=Loader):
     """
@@ -57,12 +64,11 @@
         yield loader.get_data()
 
-def load(stream, Loader=Loader):
+def safe_load(stream):
     """
     Parse the first YAML document in a stream
     and produce the corresponding Python object.
-    """
-    loader = Loader(stream)
-    if loader.check_data():
-        return loader.get_data()
+    Resolve only basic YAML tags.
+    """
+    return load(stream, SafeLoader)
 
 def safe_load_all(stream):
@@ -73,12 +79,4 @@
     """
     return load_all(stream, SafeLoader)
-
-def safe_load(stream):
-    """
-    Parse the first YAML document in a stream
-    and produce the corresponding Python object.
-    Resolve only basic YAML tags.
-    """
-    return load(stream, SafeLoader)
 
 def emit(events, stream=None, Dumper=Dumper,
