Index: /pyyaml/trunk/LICENSE
===================================================================
--- /pyyaml/trunk/LICENSE	(revision 58)
+++ /pyyaml/trunk/LICENSE	(revision 58)
@@ -0,0 +1,19 @@
+Copyright (c) 2006 Kirill Simonov
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
Index: /pyyaml/trunk/tests/test_reader.py
===================================================================
--- /pyyaml/trunk/tests/test_reader.py	(revision 46)
+++ /pyyaml/trunk/tests/test_reader.py	(revision 46)
@@ -0,0 +1,44 @@
+
+import test_appliance
+from yaml.reader import Reader, ReaderError
+
+import codecs
+
+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)
+                break
+            except:
+                pass
+        else:
+            return
+        #self._load(data)
+        self.failUnlessRaises(ReaderError,
+                lambda: self._load(data))
+        #self._load(codecs.open(stream_filename, encoding=encoding))
+        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()
+        #self._load(data)
+        self.failUnlessRaises(ReaderError, lambda: self._load(data))
+
+    def _testReaderFileErrors(self, test_name, stream_filename):
+        data = file(stream_filename, 'rb')
+        #self._load(data)
+        self.failUnlessRaises(ReaderError, lambda: self._load(data))
+
+    def _load(self, data):
+        stream = Reader(data)
+        while stream.peek() != u'\0':
+            stream.forward()
+
+TestReaderErrors.add_tests('testReaderUnicodeErrors', '.stream-error')
+TestReaderErrors.add_tests('testReaderStringErrors', '.stream-error')
+TestReaderErrors.add_tests('testReaderFileErrors', '.stream-error')
+
+
Index: /pyyaml/trunk/tests/test_yaml.py
===================================================================
--- /pyyaml/trunk/tests/test_yaml.py	(revision 58)
+++ /pyyaml/trunk/tests/test_yaml.py	(revision 58)
@@ -0,0 +1,19 @@
+
+import unittest
+
+from test_marker import *
+from test_reader import *
+from test_canonical import *
+from test_tokens import *
+from test_structure import *
+from test_errors import *
+from test_detector import *
+from test_constructor import *
+from test_syck import *
+
+def main(module='__main__'):
+    unittest.main(module)
+
+if __name__ == '__main__':
+    main()
+
Index: /pyyaml/trunk/tests/data/duplicate-tag-directive.error-message
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-tag-directive.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/duplicate-tag-directive.error-message	(revision 52)
@@ -0,0 +1,3 @@
+%TAG    !foo!   bar
+%TAG    !foo!   baz
+--- foo
Index: /pyyaml/trunk/tests/data/spec-09-13.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-13.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-13.data	(revision 38)
@@ -0,0 +1,6 @@
+simple key : {
+  also simple : value,
+  ? not a
+  simple key : any
+  value
+}
Index: /pyyaml/trunk/tests/data/spec-07-07a.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-07a.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-07a.data	(revision 38)
@@ -0,0 +1,2 @@
+# Private application:
+!foo "bar"
Index: /pyyaml/trunk/tests/data/spec-09-25.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-25.data	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-09-25.data	(revision 48)
@@ -0,0 +1,3 @@
+| # Simple block scalar
+ literal
+ 	text
Index: /pyyaml/trunk/tests/data/spec-08-09.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-09.data	(revision 57)
+++ /pyyaml/trunk/tests/data/spec-08-09.data	(revision 57)
@@ -0,0 +1,11 @@
+---
+scalars:
+  plain: !!str some text
+  quoted:
+    single: 'some text'
+    double: "some text"
+collections:
+  sequence: !!seq [ !!str entry,
+    # Mapping entry:
+      key: value ]
+  mapping: { key: value }
Index: /pyyaml/trunk/tests/data/invalid-tag-directive-prefix.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-tag-directive-prefix.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-tag-directive-prefix.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%TAG    !   tag:zz.com/foo#bar  # '#' is not allowed in URLs
+---
Index: /pyyaml/trunk/tests/data/spec-07-01.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-01.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-01.canonical	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+--- !!str
+"foo"
Index: /pyyaml/trunk/tests/data/spec-05-10.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-10.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-10.error	(revision 38)
@@ -0,0 +1,3 @@
+ERROR:
+ Reserved indicators can't
+ start a plain scalar.
Index: /pyyaml/trunk/tests/data/invalid-starting-character.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-starting-character.error-message	(revision 48)
+++ /pyyaml/trunk/tests/data/invalid-starting-character.error-message	(revision 48)
@@ -0,0 +1,1 @@
+@@@@@@@@@@@@@@@@@@@
Index: /pyyaml/trunk/tests/data/spec-02-02.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-02.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-02.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/spec-08-15.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-15.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-08-15.canonical	(revision 44)
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!seq [
+  !!null "",
+  !!map {
+    ? !!str "foo"
+    : !!null "",
+    ? !!null ""
+    : !!str "bar",
+  }
+]
Index: /pyyaml/trunk/tests/data/spec-02-01.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-01.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-01.tokens	(revision 39)
@@ -0,0 +1,1 @@
+[[ , _ , _ , _ ]}
Index: /pyyaml/trunk/tests/data/spec-06-02.empty
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-02.empty	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-02.empty	(revision 38)
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
Index: /pyyaml/trunk/tests/data/spec-07-09.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-09.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-09.canonical	(revision 38)
@@ -0,0 +1,9 @@
+%YAML 1.1
+---
+!!str "foo"
+%YAML 1.1
+---
+!!str "bar"
+%YAML 1.1
+---
+!!str "baz"
Index: /pyyaml/trunk/tests/data/spec-02-23.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-23.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-23.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/spec-09-08.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-08.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-08.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!str "as space \
+  trimmed\n\
+  specific\L\n\
+  none"
Index: /pyyaml/trunk/tests/data/spec-02-21.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-21.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-21.tokens	(revision 41)
@@ -0,0 +1,6 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/spec-09-29.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-29.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-09-29.canonical	(revision 44)
@@ -0,0 +1,4 @@
+%YAML 1.1
+---
+!!str "folded text\n\
+      \tlines\n"
Index: /pyyaml/trunk/tests/data/spec-10-01.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-01.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-01.data	(revision 38)
@@ -0,0 +1,2 @@
+- [ inner, inner, ]
+- [inner,last]
Index: /pyyaml/trunk/tests/data/invalid-yaml-directive-version-3.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-yaml-directive-version-3.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-yaml-directive-version-3.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%YAML 1.
+---
Index: /pyyaml/trunk/tests/data/spec-10-13.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-13.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-13.data	(revision 38)
@@ -0,0 +1,5 @@
+? explicit key # implicit value
+? |
+  block key
+: - one # explicit in-line
+  - two # block value
Index: /pyyaml/trunk/tests/data/spec-02-19.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-19.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-19.tokens	(revision 41)
@@ -0,0 +1,7 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/spec-05-10.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-10.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-10.data	(revision 38)
@@ -0,0 +1,2 @@
+commercial-at: @text
+grave-accent: `text
Index: /pyyaml/trunk/tests/data/spec-02-06.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-06.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-06.data	(revision 38)
@@ -0,0 +1,5 @@
+Mark McGwire: {hr: 65, avg: 0.278}
+Sammy Sosa: {
+    hr: 63,
+    avg: 0.288
+  }
Index: /pyyaml/trunk/tests/data/spec-07-10.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-10.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-10.data	(revision 38)
@@ -0,0 +1,11 @@
+"Root flow
+ scalar"
+--- !!str >
+ Root block
+ scalar
+---
+# Root collection:
+foo : bar
+... # Is optional.
+---
+# Explicit document may be empty.
Index: /pyyaml/trunk/tests/data/construct-null.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-null.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-null.code	(revision 58)
@@ -0,0 +1,13 @@
+[
+    None,
+    { "empty": None, "canonical": None, "english": None, None: "null key" },
+    {
+        "sparse": [
+            None,
+            "2nd entry",
+            None,
+            "4th entry",
+            None,
+        ],
+    },
+]
Index: /pyyaml/trunk/tests/data/spec-09-10.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-10.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-10.data	(revision 38)
@@ -0,0 +1,3 @@
+ 'first
+ 	inner	
+ last'
Index: /pyyaml/trunk/tests/data/duplicate-merge-key.error-message
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-merge-key.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/duplicate-merge-key.error-message	(revision 58)
@@ -0,0 +1,4 @@
+---
+<<: {x: 1, y: 2}
+foo: bar
+<<: {z: 3, t: 4}
Index: /pyyaml/trunk/tests/data/spec-02-18.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-18.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-18.data	(revision 38)
@@ -0,0 +1,6 @@
+plain:
+  This unquoted scalar
+  spans many lines.
+
+quoted: "So does this
+  quoted scalar.\n"
Index: /pyyaml/trunk/tests/data/spec-06-06.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-06.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-06.data	(revision 38)
@@ -0,0 +1,7 @@
+plain: text
+  lines
+quoted: "text
+  	lines"
+block: |
+  text
+   	lines
Index: /pyyaml/trunk/tests/data/spec-09-22.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-22.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-22.data	(revision 38)
@@ -0,0 +1,5 @@
+strip: |-
+  textâ©clip: |
+  textÂ
+keep: |+
+  textâš
Index: /pyyaml/trunk/tests/data/spec-08-06.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-06.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-06.data	(revision 38)
@@ -0,0 +1,5 @@
+%TAG !o! tag:ben-kiki.org,2000:
+---
+- !$a!b foo
+- !o! bar
+- !h!type baz
Index: /pyyaml/trunk/tests/data/timestamp.data
===================================================================
--- /pyyaml/trunk/tests/data/timestamp.data	(revision 55)
+++ /pyyaml/trunk/tests/data/timestamp.data	(revision 55)
@@ -0,0 +1,5 @@
+- 2001-12-15T02:59:43.1Z
+- 2001-12-14t21:59:43.10-05:00
+- 2001-12-14 21:59:43.10 -5
+- 2001-12-15 2:59:43.10
+- 2002-12-14
Index: /pyyaml/trunk/tests/data/invalid-tag-directive-handle.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-tag-directive-handle.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-tag-directive-handle.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%TAG !!! !!!
+---
Index: /pyyaml/trunk/tests/data/spec-10-04.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-04.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-04.canonical	(revision 38)
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "block"
+  : !!seq [
+    !!str "one",
+    !!seq [
+      !!str "two"
+    ]
+  ]
+}
Index: /pyyaml/trunk/tests/data/spec-05-11.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-11.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-11.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+--- !!str
+"Generic line break (no glyph)\n\
+ Generic line break (glyphed)\n\
+ Line separator\u2028\
+ Paragraph separator\u2029"
Index: /pyyaml/trunk/tests/data/spec-07-10.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-10.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-07-10.canonical	(revision 48)
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+!!str "Root flow scalar"
+%YAML 1.1
+---
+!!str "Root block scalar\n"
+%YAML 1.1
+---
+!!map {
+  ? !!str "foo"
+  : !!str "bar"
+}
+---
+#!!str ""
+!!null ""
Index: /pyyaml/trunk/tests/data/spec-06-04.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-04.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-04.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "key"
+  : !!str "value"
+}
Index: /pyyaml/trunk/tests/data/spec-08-03.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-03.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-03.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!map {
+  ? !<tag:yaml.org,2002:str> "foo"
+  : !<!bar> "baz"
+}
Index: /pyyaml/trunk/tests/data/spec-09-30.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-30.canonical	(revision 51)
+++ /pyyaml/trunk/tests/data/spec-09-30.canonical	(revision 51)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "folded line\n\
+      next line\n\n\
+      \  * bullet\n\
+      \  * list\n\n\
+      last line\n"
Index: /pyyaml/trunk/tests/data/spec-02-11.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-11.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-11.structure	(revision 44)
@@ -0,0 +1,4 @@
+[
+([True, True], [True]),
+([True, True], [True, True, True]),
+]
Index: /pyyaml/trunk/tests/data/spec-09-21.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-21.error	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-09-21.error	(revision 42)
@@ -0,0 +1,7 @@
+ERROR:
+- A leading all-space line must
+  not have too many spaces.
+- A following text line must
+  not be less indented.
+- The text is less indented
+  than the indicated level.
Index: /pyyaml/trunk/tests/data/spec-02-10.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-10.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-10.tokens	(revision 39)
@@ -0,0 +1,5 @@
+---
+{{
+? _ : [[ , _ , & _ ]}
+? _ : [[ , * , _ ]}
+]}
Index: /pyyaml/trunk/tests/data/spec-09-17.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-17.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-17.canonical	(revision 38)
@@ -0,0 +1,4 @@
+%YAML 1.1
+---
+!!str "first line\n\
+      more line"
Index: /pyyaml/trunk/tests/data/spec-10-10.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-10.data	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-10-10.data	(revision 48)
@@ -0,0 +1,8 @@
+{
+? explicit key1 : explicit value,
+? explicit key2 : , # Explicit empty
+? explicit key3,     # Empty value
+simple key1 : explicit value,
+simple key2 : ,     # Explicit empty
+simple key3,         # Empty value
+}
Index: /pyyaml/trunk/tests/data/spec-02-19.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-19.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-19.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True), (True, True), (True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/spec-02-08.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-08.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-08.tokens	(revision 39)
@@ -0,0 +1,15 @@
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
+...
+
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
+...
Index: /pyyaml/trunk/tests/data/spec-02-03.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-03.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-03.data	(revision 38)
@@ -0,0 +1,8 @@
+american:
+  - Boston Red Sox
+  - Detroit Tigers
+  - New York Yankees
+national:
+  - New York Mets
+  - Chicago Cubs
+  - Atlanta Braves
Index: /pyyaml/trunk/tests/data/spec-02-28.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-28.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-28.tokens	(revision 41)
@@ -0,0 +1,23 @@
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
+---
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ :
+    [[
+        , {{ ? _ : _ ? _ : _ ? _ : _ ]}
+        , {{ ? _ : _ ? _ : _ ? _ : _ ]}
+    ]}
+]}
Index: /pyyaml/trunk/tests/data/spec-02-15.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-15.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-15.data	(revision 38)
@@ -0,0 +1,8 @@
+>
+ Sammy Sosa completed another
+ fine season with great stats.
+
+   63 Home Runs
+   0.288 Batting Average
+
+ What a year!
Index: /pyyaml/trunk/tests/data/spec-06-03.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-03.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-03.data	(revision 38)
@@ -0,0 +1,2 @@
+key:    # Comment
+  value
Index: /pyyaml/trunk/tests/data/invalid-anchor-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-anchor-2.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-anchor-2.error-message	(revision 52)
@@ -0,0 +1,8 @@
+---
+- [
+    &correct foo,
+    *correct,
+    *correct]   # still correct
+- *correct: still correct
+- &correct-or-not[foo, bar]
+
Index: /pyyaml/trunk/tests/data/spec-02-27.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-27.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-27.data	(revision 38)
@@ -0,0 +1,29 @@
+--- !<tag:clarkevans.com,2002:invoice>
+invoice: 34843
+date   : 2001-01-23
+bill-to: &id001
+    given  : Chris
+    family : Dumars
+    address:
+        lines: |
+            458 Walkman Dr.
+            Suite #292
+        city    : Royal Oak
+        state   : MI
+        postal  : 48046
+ship-to: *id001
+product:
+    - sku         : BL394D
+      quantity    : 4
+      description : Basketball
+      price       : 450.00
+    - sku         : BL4438H
+      quantity    : 1
+      description : Super Hoop
+      price       : 2392.00
+tax  : 251.42
+total: 4443.52
+comments:
+    Late afternoon is best.
+    Backup contact is Nancy
+    Billsmer @ 338-4338.
Index: /pyyaml/trunk/tests/data/spec-08-03.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-03.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-03.data	(revision 38)
@@ -0,0 +1,2 @@
+!<tag:yaml.org,2002:str> foo :
+  !<!bar> baz
Index: /pyyaml/trunk/tests/data/spec-09-31.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-31.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-31.data	(revision 38)
@@ -0,0 +1,14 @@
+>
+ folded
+ line
+
+ next
+ line
+
+   * bullet
+   * list
+
+ last
+ line
+
+# Comment
Index: /pyyaml/trunk/tests/data/spec-08-15.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-15.data	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-08-15.data	(revision 44)
@@ -0,0 +1,5 @@
+- # Empty plain scalar
+- ? foo
+  :
+  ?
+  : bar
Index: /pyyaml/trunk/tests/data/spec-05-01-utf8.empty
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-01-utf8.empty	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-01-utf8.empty	(revision 38)
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
Index: /pyyaml/trunk/tests/data/spec-10-13.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-13.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-10-13.canonical	(revision 44)
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "explicit key"
+  : !!null "",
+  ? !!str "block key\n"
+  : !!seq [
+    !!str "one",
+    !!str "two",
+  ]
+}
Index: /pyyaml/trunk/tests/data/invalid-indentation-indicator-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-indentation-indicator-2.error-message	(revision 48)
+++ /pyyaml/trunk/tests/data/invalid-indentation-indicator-2.error-message	(revision 48)
@@ -0,0 +1,2 @@
+--- >-0
+data
Index: /pyyaml/trunk/tests/data/spec-08-12.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-12.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-12.canonical	(revision 38)
@@ -0,0 +1,9 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "Without properties",
+  &A !!str "Anchored",
+  !!str "Tagged",
+  *A,
+  !!str "",
+]
Index: /pyyaml/trunk/tests/data/spec-07-12b.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-12b.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-12b.canonical	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "Text content\n"
Index: /pyyaml/trunk/tests/data/spec-05-07.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-07.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-07.canonical	(revision 38)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "literal"
+  : !!str "text\n",
+  ? !!str "folded"
+  : !!str "text\n",
+}
Index: /pyyaml/trunk/tests/data/spec-02-20.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-20.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-20.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True), (True, True), (True, True), (True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/spec-07-06.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-06.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-06.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!seq [
+  !<!foobar> "baz",
+  !<tag:yaml.org,2002:str> "string"
+]
Index: /pyyaml/trunk/tests/data/construct-omap.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-omap.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-omap.code	(revision 58)
@@ -0,0 +1,8 @@
+{
+    "Bestiary": [
+        ("aardvark", "African pig-like ant eater. Ugly."),
+        ("anteater", "South-American ant eater. Two species."),
+        ("anaconda", "South-American constrictor snake. Scaly."),
+    ],
+    "Numbers": [ ("one", 1), ("two", 2), ("three", 3) ],
+}
Index: /pyyaml/trunk/tests/data/spec-09-05.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-05.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-05.canonical	(revision 38)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "first ",
+  !!str "first\nlast",
+  !!str "first inner  \tlast",
+]
Index: /pyyaml/trunk/tests/data/spec-09-26.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-26.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-09-26.canonical	(revision 48)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "\n\nliteral\n\ntext\n"
Index: /pyyaml/trunk/tests/data/invalid-utf8-byte.stream-error
===================================================================
--- /pyyaml/trunk/tests/data/invalid-utf8-byte.stream-error	(revision 45)
+++ /pyyaml/trunk/tests/data/invalid-utf8-byte.stream-error	(revision 45)
@@ -0,0 +1,18 @@
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+Invalid byte ('\xFF'): ÿ <--
+-------------------------------------------------------------------------------------------------------------------------------
Index: /pyyaml/trunk/tests/data/spec-02-07.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-07.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-07.structure	(revision 44)
@@ -0,0 +1,4 @@
+[
+[True, True, True],
+[True, True],
+]
Index: /pyyaml/trunk/tests/data/no-document-start.error-message
===================================================================
--- /pyyaml/trunk/tests/data/no-document-start.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/no-document-start.error-message	(revision 52)
@@ -0,0 +1,3 @@
+%YAML   1.1
+# no ---
+foo: bar
Index: /pyyaml/trunk/tests/data/invalid-yaml-directive-version-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-yaml-directive-version-2.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-yaml-directive-version-2.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%YAML   1e-5
+---
Index: /pyyaml/trunk/tests/data/spec-02-28.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-28.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-28.structure	(revision 44)
@@ -0,0 +1,10 @@
+[
+[(True, True), (True, True), (True, True)],
+[(True, True), (True, True), (True, True)],
+[(True, True), (True, True), (True, True),
+(True, [
+    [(True, True), (True, True), (True, True)],
+    [(True, True), (True, True), (True, True)],
+    ]),
+]
+]
Index: /pyyaml/trunk/tests/data/spec-02-17.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-17.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-17.tokens	(revision 41)
@@ -0,0 +1,8 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/spec-02-12.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-12.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-12.data	(revision 38)
@@ -0,0 +1,8 @@
+---
+# products purchased
+- item    : Super Hoop
+  quantity: 1
+- item    : Basketball
+  quantity: 4
+- item    : Big Shoes
+  quantity: 1
Index: /pyyaml/trunk/tests/data/bool.detect
===================================================================
--- /pyyaml/trunk/tests/data/bool.detect	(revision 55)
+++ /pyyaml/trunk/tests/data/bool.detect	(revision 55)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:bool
Index: /pyyaml/trunk/tests/data/duplicate-mapping-key.error-message
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-mapping-key.error-message	(revision 55)
+++ /pyyaml/trunk/tests/data/duplicate-mapping-key.error-message	(revision 55)
@@ -0,0 +1,6 @@
+---
+&anchor foo:
+    foo: bar
+    *anchor: duplicate key
+    baz: bat
+    *anchor: duplicate key
Index: /pyyaml/trunk/tests/data/spec-02-24.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-24.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-24.data	(revision 38)
@@ -0,0 +1,14 @@
+%TAG ! tag:clarkevans.com,2002:
+--- !shape
+  # Use the ! handle for presenting
+  # tag:clarkevans.com,2002:circle
+- !circle
+  center: &ORIGIN {x: 73, y: 129}
+  radius: 7
+- !line
+  start: *ORIGIN
+  finish: { x: 89, y: 102 }
+- !label
+  start: *ORIGIN
+  color: 0xFFEEBB
+  text: Pretty vector drawing.
Index: /pyyaml/trunk/tests/data/spec-08-12.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-12.data	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-08-12.data	(revision 44)
@@ -0,0 +1,8 @@
+[
+  Without properties,
+  &anchor "Anchored",
+  !!str 'Tagged',
+  *anchor, # Alias node
+#  !!str,   # Empty plain scalar
+  '',   # Empty plain scalar
+]
Index: /pyyaml/trunk/tests/data/spec-05-08.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-08.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-08.data	(revision 38)
@@ -0,0 +1,2 @@
+single: 'text'
+double: "text"
Index: /pyyaml/trunk/tests/data/spec-07-08.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-08.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-08.data	(revision 38)
@@ -0,0 +1,9 @@
+# Explicitly specify default settings:
+%TAG !     !
+%TAG !!    tag:yaml.org,2002:
+# Named handles have no default:
+%TAG !o! tag:ben-kiki.org,2000:
+---
+- !foo "bar"
+- !!str "string"
+- !o!type "baz"
Index: /pyyaml/trunk/tests/data/no-block-mapping-end.error-message
===================================================================
--- /pyyaml/trunk/tests/data/no-block-mapping-end.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/no-block-mapping-end.error-message	(revision 52)
@@ -0,0 +1,1 @@
+foo: "bar" "baz"
Index: /pyyaml/trunk/tests/data/spec-10-01.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-01.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-01.canonical	(revision 38)
@@ -0,0 +1,12 @@
+%YAML 1.1
+---
+!!seq [
+  !!seq [
+    !!str "inner",
+    !!str "inner",
+  ],
+  !!seq [
+    !!str "inner",
+    !!str "last",
+  ],
+]
Index: /pyyaml/trunk/tests/data/spec-09-08.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-08.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-08.data	(revision 38)
@@ -0,0 +1,5 @@
+ 'as space	Â
+ trimmed Â
+Â
+ specificâšÂ
+ none'
Index: /pyyaml/trunk/tests/data/spec-06-01.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-01.canonical	(revision 51)
+++ /pyyaml/trunk/tests/data/spec-06-01.canonical	(revision 51)
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "Not indented"
+  : !!map {
+      ? !!str "By one space"
+      : !!str "By four\n  spaces\n",
+      ? !!str "Flow style"
+      : !!seq [
+          !!str "By two",
+          !!str "Also by two",
+          !!str "Still by two",
+        ]
+    }
+}
Index: /pyyaml/trunk/tests/data/null.data
===================================================================
--- /pyyaml/trunk/tests/data/null.data	(revision 55)
+++ /pyyaml/trunk/tests/data/null.data	(revision 55)
@@ -0,0 +1,3 @@
+-
+- ~
+- null
Index: /pyyaml/trunk/tests/data/spec-10-09.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-09.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-10-09.canonical	(revision 44)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "key"
+  : !!str "value",
+  ? !!str "empty"
+  : !!null "",
+}
Index: /pyyaml/trunk/tests/data/spec-07-07a.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-07a.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-07a.canonical	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!<!foo> "bar"
Index: /pyyaml/trunk/tests/data/construct-merge.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-merge.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-merge.code	(revision 58)
@@ -0,0 +1,10 @@
+[
+    { "x": 1, "y": 2 },
+    { "x": 0, "y": 2 },
+    { "r": 10 },
+    { "r": 1 },
+    { "x": 1, "y": 2, "r": 10, "label": "center/big" },
+    { "x": 1, "y": 2, "r": 10, "label": "center/big" },
+    { "x": 1, "y": 2, "r": 10, "label": "center/big" },
+    { "x": 1, "y": 2, "r": 10, "label": "center/big" },
+]
Index: /pyyaml/trunk/tests/data/spec-08-08.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-08.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-08-08.canonical	(revision 48)
@@ -0,0 +1,15 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "foo"
+  : !!str "bar baz"
+}
+%YAML 1.1
+---
+!!str "foo bar"
+%YAML 1.1
+---
+!!str "foo bar"
+%YAML 1.1
+---
+!!str "foo\n"
Index: /pyyaml/trunk/tests/data/spec-02-16.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-16.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-16.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/spec-02-06.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-06.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-06.tokens	(revision 39)
@@ -0,0 +1,4 @@
+{{
+? _ : { ? _ : _ , ? _ : _ }
+? _ : { ? _ : _ , ? _ : _ }
+]}
Index: /pyyaml/trunk/tests/data/spec-02-26.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-26.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-26.tokens	(revision 41)
@@ -0,0 +1,6 @@
+--- !
+[[
+, {{ ? _ : _ ]}
+, {{ ? _ : _ ]}
+, {{ ? _ : _ ]}
+]}
Index: /pyyaml/trunk/tests/data/spec-02-21.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-21.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-21.data	(revision 38)
@@ -0,0 +1,4 @@
+null: ~
+true: y
+false: n
+string: '12345'
Index: /pyyaml/trunk/tests/data/construct-custom.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-custom.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-custom.data	(revision 58)
@@ -0,0 +1,23 @@
+---
+- !tag1
+  x: 1
+- !tag1
+  x: 1
+  'y': 2
+  z: 3
+- !tag2
+  10
+- !tag2
+  =: 10
+  'y': 20
+  z: 30
+- !tag3
+  x: 1
+- !tag3
+  x: 1
+  'y': 2
+  z: 3
+- !tag3
+  =: 1
+  'y': 2
+  z: 3
Index: /pyyaml/trunk/tests/data/spec-10-08.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-08.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-08.data	(revision 38)
@@ -0,0 +1,5 @@
+{
+multi-line
+ simple key : value,
+very long ...................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................(>1KB)................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... key: value
+}
Index: /pyyaml/trunk/tests/data/invalid-anchor-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-anchor-1.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-anchor-1.error-message	(revision 52)
@@ -0,0 +1,1 @@
+--- &?  foo # we allow only ascii and numeric characters in anchor names.
Index: /pyyaml/trunk/tests/data/spec-05-05.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-05.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-05.data	(revision 38)
@@ -0,0 +1,1 @@
+# Comment only.
Index: /pyyaml/trunk/tests/data/merge.detect
===================================================================
--- /pyyaml/trunk/tests/data/merge.detect	(revision 55)
+++ /pyyaml/trunk/tests/data/merge.detect	(revision 55)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:merge
Index: /pyyaml/trunk/tests/data/merge.data
===================================================================
--- /pyyaml/trunk/tests/data/merge.data	(revision 55)
+++ /pyyaml/trunk/tests/data/merge.data	(revision 55)
@@ -0,0 +1,1 @@
+- <<
Index: /pyyaml/trunk/tests/data/spec-07-05.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-05.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-05.data	(revision 38)
@@ -0,0 +1,3 @@
+%TAG ! !foo
+%TAG ! !foo
+bar
Index: /pyyaml/trunk/tests/data/spec-09-05.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-05.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-05.data	(revision 38)
@@ -0,0 +1,8 @@
+- "first
+  	"
+- "first
+
+  	last"
+- "first
+ inner
+ \ 	last"
Index: /pyyaml/trunk/tests/data/invalid-pairs-3.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-pairs-3.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-pairs-3.error-message	(revision 58)
@@ -0,0 +1,4 @@
+--- !!pairs
+- foo: bar
+- baz: bar
+  bar: bar
Index: /pyyaml/trunk/tests/data/spec-10-10.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-10.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-10-10.canonical	(revision 44)
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "explicit key1"
+  : !!str "explicit value",
+  ? !!str "explicit key2"
+  : !!null "",
+  ? !!str "explicit key3"
+  : !!null "",
+  ? !!str "simple key1"
+  : !!str "explicit value",
+  ? !!str "simple key2"
+  : !!null "",
+  ? !!str "simple key3"
+  : !!null "",
+}
Index: /pyyaml/trunk/tests/data/spec-09-17.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-17.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-17.data	(revision 38)
@@ -0,0 +1,3 @@
+ first line 
+   
+  more line
Index: /pyyaml/trunk/tests/data/spec-09-29.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-29.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-29.data	(revision 38)
@@ -0,0 +1,4 @@
+> # Simple folded scalar
+ folded
+ text
+ 	lines
Index: /pyyaml/trunk/tests/data/invalid-indentation-indicator-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-indentation-indicator-1.error-message	(revision 48)
+++ /pyyaml/trunk/tests/data/invalid-indentation-indicator-1.error-message	(revision 48)
@@ -0,0 +1,2 @@
+--- >0  # not valid
+data
Index: /pyyaml/trunk/tests/data/spec-05-04.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-04.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-04.canonical	(revision 38)
@@ -0,0 +1,13 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "sequence"
+  : !!seq [
+    !!str "one", !!str "two"
+  ],
+  ? !!str "mapping"
+  : !!map {
+    ? !!str "sky" : !!str "blue",
+    ? !!str "sea" : !!str "green",
+  }
+}
Index: /pyyaml/trunk/tests/data/spec-09-02.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-02.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-09-02.canonical	(revision 48)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "as space \
+  trimmed\n\
+  specific\L\n\
+  escaped\t\n\
+  none"
Index: /pyyaml/trunk/tests/data/construct-int.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-int.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-int.code	(revision 58)
@@ -0,0 +1,8 @@
+{
+    "canonical": 685230,
+    "decimal": 685230,
+    "octal": 685230,
+    "hexadecimal": 685230,
+    "binary": 685230,
+    "sexagesimal": 685230,
+}
Index: /pyyaml/trunk/tests/data/construct-set.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-set.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-set.code	(revision 58)
@@ -0,0 +1,4 @@
+{
+    "baseball players": set(["Mark McGwire", "Sammy Sosa", "Ken Griffey"]),
+    "baseball teams": set(["Boston Red Sox", "Detroit Tigers", "New York Yankees"]),
+}
Index: /pyyaml/trunk/tests/data/invalid-escape-character.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-escape-character.error-message	(revision 48)
+++ /pyyaml/trunk/tests/data/invalid-escape-character.error-message	(revision 48)
@@ -0,0 +1,1 @@
+"some escape characters are \ncorrect, but this one \?\nis not\n"
Index: /pyyaml/trunk/tests/data/spec-09-23.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-23.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-09-23.canonical	(revision 42)
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "strip"
+  : !!str "# text",
+  ? !!str "clip"
+  : !!str "# text\n",
+  ? !!str "keep"
+  : !!str "# text\L\n",
+}
Index: /pyyaml/trunk/tests/data/invalid-base64-data.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-base64-data.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-base64-data.error-message	(revision 58)
@@ -0,0 +1,2 @@
+--- !!binary
+    binary data encoded in base64 should be here.
Index: /pyyaml/trunk/tests/data/spec-02-04.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-04.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-04.structure	(revision 44)
@@ -0,0 +1,4 @@
+[
+    [(True, True), (True, True), (True, True)],
+    [(True, True), (True, True), (True, True)],
+]
Index: /pyyaml/trunk/tests/data/spec-02-25.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-25.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-25.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, None), (True, None), (True, None)]
Index: /pyyaml/trunk/tests/data/spec-05-02-utf16be.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-02-utf16be.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-02-utf16be.error	(revision 38)
@@ -0,0 +1,3 @@
+ERROR:
+ A BOM must not appear
+ inside a document.
Index: /pyyaml/trunk/tests/data/invalid-yaml-directive-version-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-yaml-directive-version-1.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-yaml-directive-version-1.error-message	(revision 52)
@@ -0,0 +1,3 @@
+# No version at all.
+%YAML
+---
Index: /pyyaml/trunk/tests/data/spec-02-15.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-15.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-15.tokens	(revision 41)
@@ -0,0 +1,1 @@
+_
Index: /pyyaml/trunk/tests/data/invalid-directive-line.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-directive-line.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-directive-line.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%YAML   1.1 ?   # extra symbol
+---
Index: /pyyaml/trunk/tests/data/spec-10-05.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-05.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-05.data	(revision 38)
@@ -0,0 +1,7 @@
+- # Empty
+- |
+ block node
+- - one # in-line
+  - two # sequence
+- one: two # in-line
+           # mapping
Index: /pyyaml/trunk/tests/data/construct-str.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-str.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-str.code	(revision 58)
@@ -0,0 +1,1 @@
+{ "string": "abcd" }
Index: /pyyaml/trunk/tests/data/spec-07-02.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-02.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-02.data	(revision 38)
@@ -0,0 +1,4 @@
+%YAML 1.2 # Attempt parsing
+           # with a warning
+---
+"foo"
Index: /pyyaml/trunk/tests/data/spec-05-14.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-14.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-14.data	(revision 38)
@@ -0,0 +1,3 @@
+"Fun with \\
+ \" \a \b \e \f \Â
+ \n \r \t \v \0 \âš \  \_ \N \L \P \â© \x41 \u0041 \U00000041"
Index: /pyyaml/trunk/tests/data/spec-09-02.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-02.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-02.data	(revision 38)
@@ -0,0 +1,6 @@
+ "as space	
+ trimmed 
+
+ specificâš
+ escaped	\â© 
+ none"
Index: /pyyaml/trunk/tests/data/construct-map.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-map.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-map.data	(revision 58)
@@ -0,0 +1,6 @@
+# Unordered set of key: value pairs.
+Block style: !!map
+  Clark : Evans
+  Brian : Ingerson
+  Oren  : Ben-Kiki
+Flow style: !!map { Clark: Evans, Brian: Ingerson, Oren: Ben-Kiki }
Index: /pyyaml/trunk/tests/data/yaml.data
===================================================================
--- /pyyaml/trunk/tests/data/yaml.data	(revision 56)
+++ /pyyaml/trunk/tests/data/yaml.data	(revision 56)
@@ -0,0 +1,3 @@
+- !!yaml '!'
+- !!yaml '&'
+- !!yaml '*'
Index: /pyyaml/trunk/tests/data/spec-09-14.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-14.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-14.data	(revision 38)
@@ -0,0 +1,14 @@
+---
+--- ||| : foo
+... >>>: bar
+---
+[
+---
+,
+... ,
+{
+--- :
+... # Nested
+}
+]
+...
Index: /pyyaml/trunk/tests/data/spec-07-07b.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-07b.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-07b.data	(revision 38)
@@ -0,0 +1,4 @@
+# Migrated to global:
+%TAG ! tag:ben-kiki.org,2000:app/
+---
+!foo "bar"
Index: /pyyaml/trunk/tests/data/undefined-tag-handle.error-message
===================================================================
--- /pyyaml/trunk/tests/data/undefined-tag-handle.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/undefined-tag-handle.error-message	(revision 52)
@@ -0,0 +1,1 @@
+--- !foo!bar    baz
Index: /pyyaml/trunk/tests/data/spec-09-26.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-26.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-26.data	(revision 38)
@@ -0,0 +1,8 @@
+|
+ 
+  
+  literal
+ 
+  text
+
+ # Comment
Index: /pyyaml/trunk/tests/data/forbidden-value.error-message
===================================================================
--- /pyyaml/trunk/tests/data/forbidden-value.error-message	(revision 47)
+++ /pyyaml/trunk/tests/data/forbidden-value.error-message	(revision 47)
@@ -0,0 +1,1 @@
+test: key: value
Index: /pyyaml/trunk/tests/data/spec-10-06.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-06.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-06.canonical	(revision 38)
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+!!seq [
+  !!map {
+    ? !!str "inner"
+    : !!str "entry",
+    ? !!str "also"
+    : !!str "inner"
+  },
+  !!map {
+    ? !!str "inner"
+    : !!str "entry",
+    ? !!str "last"
+    : !!str "entry"
+  }
+]
Index: /pyyaml/trunk/tests/data/construct-seq.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-seq.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-seq.code	(revision 58)
@@ -0,0 +1,4 @@
+{
+    "Block style": ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"],
+    "Flow style": ["Mercury", "Venus", "Earth", "Mars", "Jupiter", "Saturn", "Uranus", "Neptune", "Pluto"],
+}
Index: /pyyaml/trunk/tests/data/spec-05-13.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-13.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-13.canonical	(revision 38)
@@ -0,0 +1,5 @@
+%YAML 1.1
+--- !!str
+"Text containing \
+ both space and \
+ tab	characters"
Index: /pyyaml/trunk/tests/data/test_marker.markers
===================================================================
--- /pyyaml/trunk/tests/data/test_marker.markers	(revision 39)
+++ /pyyaml/trunk/tests/data/test_marker.markers	(revision 39)
@@ -0,0 +1,38 @@
+---
+*The first line.
+The last line.
+---
+The first*line.
+The last line.
+---
+The first line.*
+The last line.
+---
+The first line.
+*The last line.
+---
+The first line.
+The last*line.
+---
+The first line.
+The last line.*
+---
+The first line.
+*The selected line.
+The last line.
+---
+The first line.
+The selected*line.
+The last line.
+---
+The first line.
+The selected line.*
+The last line.
+---
+*The only line.
+---
+The only*line.
+---
+The only line.*
+---
+Loooooooooooooooooooooooooooooooooooooooooooooong*Liiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiine
Index: /pyyaml/trunk/tests/data/duplicate-value-key.error-message
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-value-key.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/duplicate-value-key.error-message	(revision 58)
@@ -0,0 +1,4 @@
+---
+=: 1
+foo: bar
+=: 2
Index: /pyyaml/trunk/tests/data/spec-09-11.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-11.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-11.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "first ",
+  !!str "first\nlast",
+]
Index: /pyyaml/trunk/tests/data/spec-06-06.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-06.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-06-06.canonical	(revision 48)
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "plain"
+  : !!str "text lines",
+  ? !!str "quoted"
+  : !!str "text lines",
+  ? !!str "block"
+  : !!str "text\n 	lines\n"
+}
Index: /pyyaml/trunk/tests/data/spec-08-05.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-05.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-05.canonical	(revision 38)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !<!local> "foo",
+  !<tag:yaml.org,2002:str> "bar",
+  !<tag:ben-kiki.org,2000:type> "baz",
+]
Index: /pyyaml/trunk/tests/data/spec-09-32.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-32.canonical	(revision 51)
+++ /pyyaml/trunk/tests/data/spec-09-32.canonical	(revision 51)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "folded line\n\
+      next line\n\n\
+      \  * bullet\n\
+      \  * list\n\n\
+      last line\n"
Index: /pyyaml/trunk/tests/data/spec-02-13.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-13.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-13.structure	(revision 44)
@@ -0,0 +1,1 @@
+True
Index: /pyyaml/trunk/tests/data/spec-02-04.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-04.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-04.tokens	(revision 39)
@@ -0,0 +1,4 @@
+[[
+, {{ ? _ : _ ? _ : _ ? _ : _ ]}
+, {{ ? _ : _ ? _ : _ ? _ : _ ]}
+]}
Index: /pyyaml/trunk/tests/data/spec-09-19.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-19.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-19.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "literal\n",
+  !!str "folded\n",
+]
Index: /pyyaml/trunk/tests/data/spec-02-24.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-24.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-24.tokens	(revision 41)
@@ -0,0 +1,20 @@
+%
+--- !
+[[
+, !
+    {{
+    ? _ : & { ? _ : _ , ? _ : _ }
+    ? _ : _
+    ]}
+, !
+    {{
+    ? _ : *
+    ? _ : { ? _ : _ , ? _ : _ }
+    ]}
+, !
+    {{
+    ? _ : *
+    ? _ : _
+    ? _ : _
+    ]}
+]}
Index: /pyyaml/trunk/tests/data/spec-10-02.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-02.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-02.data	(revision 38)
@@ -0,0 +1,8 @@
+[
+"double
+ quoted", 'single
+           quoted',
+plain
+ text, [ nested ],
+single: pair ,
+]
Index: /pyyaml/trunk/tests/data/construct-float.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-float.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-float.data	(revision 58)
@@ -0,0 +1,6 @@
+canonical: 6.8523015e+5
+exponential: 685.230_15e+03
+fixed: 685_230.15
+sexagesimal: 190:20:30.15
+negative infinity: -.inf
+not a number: .NaN
Index: /pyyaml/trunk/tests/data/spec-10-14.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-14.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-14.data	(revision 38)
@@ -0,0 +1,4 @@
+plain key: # empty value
+"quoted key":
+- one # explicit next-line
+- two # block value
Index: /pyyaml/trunk/tests/data/spec-05-11.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-11.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-11.data	(revision 38)
@@ -0,0 +1,4 @@
+|
+  Generic line break (no glyph)
+  Generic line break (glyphed)Â
+  Line separatorâš  Paragraph separatorâ©
Index: /pyyaml/trunk/tests/data/spec-02-07.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-07.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-07.data	(revision 38)
@@ -0,0 +1,10 @@
+# Ranking of 1998 home runs
+---
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
+
+# Team ranking
+---
+- Chicago Cubs
+- St Louis Cardinals
Index: /pyyaml/trunk/tests/data/spec-07-11.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-11.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-11.data	(revision 38)
@@ -0,0 +1,2 @@
+﻿# A stream may contain
+# no documents.
Index: /pyyaml/trunk/tests/data/construct-value.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-value.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-value.data	(revision 58)
@@ -0,0 +1,10 @@
+---     # Old schema
+link with:
+  - library1.dll
+  - library2.dll
+---     # New schema
+link with:
+  - = : library1.dll
+    version: 1.2
+  - = : library2.dll
+    version: 2.3
Index: /pyyaml/trunk/tests/data/spec-09-11.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-11.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-11.data	(revision 38)
@@ -0,0 +1,5 @@
+- 'first
+  	'
+- 'first
+
+  	last'
Index: /pyyaml/trunk/tests/data/spec-02-19.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-19.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-19.data	(revision 38)
@@ -0,0 +1,5 @@
+canonical: 12345
+decimal: +12,345
+sexagesimal: 3:25:45
+octal: 014
+hexadecimal: 0xC
Index: /pyyaml/trunk/tests/data/spec-06-07.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-07.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-07.data	(revision 38)
@@ -0,0 +1,8 @@
+- foo
+ 
+  bar
+- |-
+  foo
+ 
+  bar
+  
Index: /pyyaml/trunk/tests/data/spec-09-23.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-23.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-23.data	(revision 38)
@@ -0,0 +1,15 @@
+ # Strip
+  # Comments:
+strip: |-
+  # textâ©  âš # Clip
+  # comments:
+Â
+clip: |
+  # textÂ
+ â© # Keep
+  # comments:
+Â
+keep: |+
+  # textâšÂ
+ # Trail
+  # comments.
Index: /pyyaml/trunk/tests/data/invalid-pairs-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-pairs-2.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-pairs-2.error-message	(revision 58)
@@ -0,0 +1,3 @@
+--- !!pairs
+- foo: bar
+- baz
Index: /pyyaml/trunk/tests/data/spec-08-07.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-07.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-07.data	(revision 38)
@@ -0,0 +1,4 @@
+# Assuming conventional resolution:
+- "12"
+- 12
+- ! 12
Index: /pyyaml/trunk/tests/data/no-block-collection-end.error-message
===================================================================
--- /pyyaml/trunk/tests/data/no-block-collection-end.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/no-block-collection-end.error-message	(revision 52)
@@ -0,0 +1,3 @@
+- foo
+- bar
+baz: bar
Index: /pyyaml/trunk/tests/data/expected-scalar.error-message
===================================================================
--- /pyyaml/trunk/tests/data/expected-scalar.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/expected-scalar.error-message	(revision 58)
@@ -0,0 +1,1 @@
+--- !!str [not a scalar]
Index: /pyyaml/trunk/tests/data/expected-sequence.error-message
===================================================================
--- /pyyaml/trunk/tests/data/expected-sequence.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/expected-sequence.error-message	(revision 58)
@@ -0,0 +1,1 @@
+--- !!seq {foo, bar, baz}
Index: /pyyaml/trunk/tests/data/spec-10-15.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-15.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-10-15.canonical	(revision 42)
@@ -0,0 +1,18 @@
+%YAML 1.1
+---
+!!seq [
+  !!map {
+    ? !!str "sun"
+    : !!str "yellow"
+  },
+  !!map {
+    ? !!map {
+      ? !!str "earth"
+      : !!str "blue"
+    }
+    : !!map {
+      ? !!str "moon"
+      : !!str "white"
+    }
+  }
+]
Index: /pyyaml/trunk/tests/data/undefined-anchor.error-message
===================================================================
--- /pyyaml/trunk/tests/data/undefined-anchor.error-message	(revision 53)
+++ /pyyaml/trunk/tests/data/undefined-anchor.error-message	(revision 53)
@@ -0,0 +1,3 @@
+- foo
+- &bar baz
+- *bat
Index: /pyyaml/trunk/tests/data/spec-10-08.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-08.error	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-10-08.error	(revision 42)
@@ -0,0 +1,5 @@
+ERROR:
+- A simple key is restricted
+  to only one line.
+- A simple key must not be
+  longer than 1024 characters.
Index: /pyyaml/trunk/tests/data/spec-09-20.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-20.canonical	(revision 51)
+++ /pyyaml/trunk/tests/data/spec-09-20.canonical	(revision 51)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "detected\n",
+  !!str "\n\n# detected\n",
+  !!str " explicit\n",
+  !!str "\t\ndetected\n",
+]
Index: /pyyaml/trunk/tests/data/spec-02-01.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-01.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-01.structure	(revision 44)
@@ -0,0 +1,1 @@
+[True, True, True]
Index: /pyyaml/trunk/tests/data/spec-05-02-utf8.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-02-utf8.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-02-utf8.data	(revision 38)
@@ -0,0 +1,3 @@
+# Invalid use of BOM
+ï»¿# inside a
+# document.
Index: /pyyaml/trunk/tests/data/spec-08-14.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-14.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-14.canonical	(revision 38)
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "flow in block",
+  !!str "Block scalar\n",
+  !!map {
+    ? !!str "foo"
+    : !!str "bar"
+  }
+]
Index: /pyyaml/trunk/tests/data/spec-05-09.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-09.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-09.canonical	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "text"
Index: /pyyaml/trunk/tests/data/spec-02-22.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-22.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-22.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True), (True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/spec-07-08.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-08.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-07-08.canonical	(revision 42)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !<!foo> "bar",
+  !<tag:yaml.org,2002:str> "string",
+  !<tag:ben-kiki.org,2000:type> "baz"
+]
Index: /pyyaml/trunk/tests/data/invalid-omap-3.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-omap-3.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-omap-3.error-message	(revision 58)
@@ -0,0 +1,4 @@
+--- !!omap
+- foo: bar
+- baz: bar
+  bar: bar
Index: /pyyaml/trunk/tests/data/spec-09-07.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-07.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-07.canonical	(revision 38)
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "simple key"
+  : !!map {
+    ? !!str "also simple"
+    : !!str "value",
+    ? !!str "not a simple key"
+    : !!str "any value"
+  }
+}
Index: /pyyaml/trunk/tests/data/spec-02-13.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-13.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-13.tokens	(revision 41)
@@ -0,0 +1,1 @@
+--- _
Index: /pyyaml/trunk/tests/data/invalid-uri.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-uri.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-uri.error-message	(revision 52)
@@ -0,0 +1,1 @@
+--- !foo!   bar
Index: /pyyaml/trunk/tests/data/spec-09-28.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-28.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-09-28.canonical	(revision 48)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "\n\nliteral\n\ntext\n"
Index: /pyyaml/trunk/tests/data/spec-02-09.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-09.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-09.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, [True, True]), (True, [True, True])]
Index: /pyyaml/trunk/tests/data/spec-10-11.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-11.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-11.data	(revision 38)
@@ -0,0 +1,7 @@
+[
+? explicit key1 : explicit value,
+? explicit key2 : , # Explicit empty
+? explicit key3,     # Implicit empty
+simple key1 : explicit value,
+simple key2 : ,     # Explicit empty
+]
Index: /pyyaml/trunk/tests/data/spec-02-04.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-04.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-04.data	(revision 38)
@@ -0,0 +1,8 @@
+-
+  name: Mark McGwire
+  hr:   65
+  avg:  0.278
+-
+  name: Sammy Sosa
+  hr:   63
+  avg:  0.288
Index: /pyyaml/trunk/tests/data/spec-02-16.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-16.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-16.data	(revision 38)
@@ -0,0 +1,7 @@
+name: Mark McGwire
+accomplishment: >
+  Mark set a major league
+  home run record in 1998.
+stats: |
+  65 Home Runs
+  0.278 Batting Average
Index: /pyyaml/trunk/tests/data/spec-06-04.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-04.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-04.data	(revision 38)
@@ -0,0 +1,4 @@
+key:    # Comment
+        # lines
+  value
+
Index: /pyyaml/trunk/tests/data/spec-09-20.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-20.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-20.data	(revision 38)
@@ -0,0 +1,11 @@
+- |
+ detected
+- >
+ 
+  
+  # detected
+- |1
+  explicit
+- >
+ 	
+ detected
Index: /pyyaml/trunk/tests/data/spec-02-28.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-28.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-28.data	(revision 38)
@@ -0,0 +1,26 @@
+---
+Time: 2001-11-23 15:01:42 -5
+User: ed
+Warning:
+  This is an error message
+  for the log file
+---
+Time: 2001-11-23 15:02:31 -5
+User: ed
+Warning:
+  A slightly different error
+  message.
+---
+Date: 2001-11-23 15:03:17 -5
+User: ed
+Fatal:
+  Unknown variable "bar"
+Stack:
+  - file: TopClass.py
+    line: 23
+    code: |
+      x = MoreObject("345\n")
+  - file: MoreClass.py
+    line: 58
+    code: |-
+      foo = bar
Index: /pyyaml/trunk/tests/data/spec-08-04.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-04.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-04.data	(revision 38)
@@ -0,0 +1,2 @@
+- !<!> foo
+- !<$:?> bar
Index: /pyyaml/trunk/tests/data/spec-09-32.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-32.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-32.data	(revision 38)
@@ -0,0 +1,14 @@
+>
+ folded
+ line
+
+ next
+ line
+
+   * bullet
+   * list
+
+ last
+ line
+
+# Comment
Index: /pyyaml/trunk/tests/data/spec-10-03.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-03.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-03.canonical	(revision 38)
@@ -0,0 +1,12 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "block"
+  : !!seq [
+    !!str "one",
+    !!map {
+      ? !!str "two"
+      : !!str "three"
+    }
+  ]
+}
Index: /pyyaml/trunk/tests/data/construct-binary.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-binary.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-binary.code	(revision 58)
@@ -0,0 +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;",
+    "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;",
+    "description": "The binary value above is a tiny arrow encoded as a gif image.",
+}
Index: /pyyaml/trunk/tests/data/spec-06-03.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-03.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-03.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "key"
+  : !!str "value"
+}
Index: /pyyaml/trunk/tests/data/spec-08-02.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-02.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-02.canonical	(revision 38)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "First occurrence"
+  : &A !!str "Value",
+  ? !!str "Second occurrence"
+  : *A
+}
Index: /pyyaml/trunk/tests/data/spec-02-10.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-10.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-10.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, [True, True]), (True, ['*', True])]
Index: /pyyaml/trunk/tests/data/spec-09-16.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-16.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-16.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!str "as space \
+  trimmed\n\
+  specific\L\n\
+  none"
Index: /pyyaml/trunk/tests/data/spec-02-02.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-02.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-02.tokens	(revision 39)
@@ -0,0 +1,5 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/forbidden-key.error-message
===================================================================
--- /pyyaml/trunk/tests/data/forbidden-key.error-message	(revision 47)
+++ /pyyaml/trunk/tests/data/forbidden-key.error-message	(revision 47)
@@ -0,0 +1,2 @@
+test: ? foo
+      : bar
Index: /pyyaml/trunk/tests/data/spec-02-22.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-22.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-22.tokens	(revision 41)
@@ -0,0 +1,6 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/spec-02-18.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-18.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-18.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/spec-02-01.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-01.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-01.data	(revision 38)
@@ -0,0 +1,3 @@
+- Mark McGwire
+- Sammy Sosa
+- Ken Griffey
Index: /pyyaml/trunk/tests/data/spec-02-13.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-13.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-13.data	(revision 38)
@@ -0,0 +1,4 @@
+# ASCII Art
+--- |
+  \//||\/||
+  // ||  ||__
Index: /pyyaml/trunk/tests/data/spec-06-01.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-01.data	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-06-01.data	(revision 48)
@@ -0,0 +1,14 @@
+  # Leading comment line spaces are
+   # neither content nor indentation.
+    
+Not indented:
+ By one space: |
+    By four
+      spaces
+ Flow style: [    # Leading spaces
+   By two,        # in flow style
+  Also by two,    # are neither
+# Tabs are not allowed:
+#  	Still by two   # content nor
+    Still by two   # content nor
+    ]             # indentation.
Index: /pyyaml/trunk/tests/data/construct-null.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-null.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-null.data	(revision 58)
@@ -0,0 +1,18 @@
+# A document may be null.
+---
+---
+# This mapping has four keys,
+# one has a value.
+empty:
+canonical: ~
+english: null
+~: null key
+---
+# This sequence has five
+# entries, two have values.
+sparse:
+  - ~
+  - 2nd entry
+  -
+  - 4th entry
+  - Null
Index: /pyyaml/trunk/tests/data/spec-08-01.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-01.data	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-08-01.data	(revision 44)
@@ -0,0 +1,2 @@
+!!str &a1 "foo" : !!str bar
+&a2 baz : *a1
Index: /pyyaml/trunk/tests/data/spec-02-25.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-25.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-25.data	(revision 38)
@@ -0,0 +1,7 @@
+# sets are represented as a
+# mapping where each key is
+# associated with the empty string
+--- !!set
+? Mark McGwire
+? Sammy Sosa
+? Ken Griff
Index: /pyyaml/trunk/tests/data/no-flow-sequence-end.error-message
===================================================================
--- /pyyaml/trunk/tests/data/no-flow-sequence-end.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/no-flow-sequence-end.error-message	(revision 52)
@@ -0,0 +1,1 @@
+[foo, bar}
Index: /pyyaml/trunk/tests/data/invalid-escape-numbers.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-escape-numbers.error-message	(revision 48)
+++ /pyyaml/trunk/tests/data/invalid-escape-numbers.error-message	(revision 48)
@@ -0,0 +1,1 @@
+"hm.... \u123?"
Index: /pyyaml/trunk/tests/data/spec-08-13.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-13.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-13.data	(revision 38)
@@ -0,0 +1,4 @@
+{
+  ? foo :,
+  ? : bar,
+}
Index: /pyyaml/trunk/tests/data/construct-pairs.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-pairs.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-pairs.code	(revision 58)
@@ -0,0 +1,9 @@
+{
+    "Block tasks": [
+        ("meeting", "with team."),
+        ("meeting", "with boss."),
+        ("break", "lunch."),
+        ("meeting", "with client."),
+    ],
+    "Flow tasks": [ ("meeting", "with team"), ("meeting", "with boss") ],
+}
Index: /pyyaml/trunk/tests/data/invalid-pairs-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-pairs-1.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-pairs-1.error-message	(revision 58)
@@ -0,0 +1,3 @@
+--- !!pairs
+foo: bar
+baz: bat
Index: /pyyaml/trunk/tests/data/spec-05-09.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-09.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-09.data	(revision 38)
@@ -0,0 +1,2 @@
+%YAML 1.1
+--- text
Index: /pyyaml/trunk/tests/data/spec-07-09.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-09.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-09.data	(revision 38)
@@ -0,0 +1,11 @@
+---
+foo
+...
+# Repeated end marker.
+...
+---
+bar
+# No end marker.
+---
+baz
+...
Index: /pyyaml/trunk/tests/data/spec-09-09.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-09.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-09.data	(revision 38)
@@ -0,0 +1,6 @@
+- '
+  last'
+- ' 	
+  last'
+- ' 	first
+  last'
Index: /pyyaml/trunk/tests/data/spec-10-12.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-12.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-10-12.canonical	(revision 42)
@@ -0,0 +1,9 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "block"
+  : !!map {
+    ? !!str "key"
+    : !!str "value"
+  }
+}
Index: /pyyaml/trunk/tests/data/spec-08-11.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-11.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-11.canonical	(revision 38)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "First occurrence"
+  : &A !!str "Value",
+  ? !!str "Second occurrence"
+  : *A
+}
Index: /pyyaml/trunk/tests/data/spec-07-12a.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-12a.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-12a.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "foo"
+  : !!str "bar"
+}
Index: /pyyaml/trunk/tests/data/spec-05-06.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-06.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-05-06.canonical	(revision 42)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "anchored"
+  : &A1 !local "value",
+  ? !!str "alias"
+  : *A1,
+}
Index: /pyyaml/trunk/tests/data/unacceptable-key.error-message
===================================================================
--- /pyyaml/trunk/tests/data/unacceptable-key.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/unacceptable-key.error-message	(revision 58)
@@ -0,0 +1,4 @@
+---
+? - foo
+  - bar
+: baz
Index: /pyyaml/trunk/tests/data/construct-bool.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-bool.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-bool.code	(revision 58)
@@ -0,0 +1,6 @@
+{
+    "canonical": True,
+    "answer": False,
+    "logical": True,
+    "option": True,
+}
Index: /pyyaml/trunk/tests/data/spec-09-04.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-04.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-04.canonical	(revision 38)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!str "first \
+  inner 1  \
+  inner 2 \
+  last"
Index: /pyyaml/trunk/tests/data/invalid-omap-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-omap-2.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-omap-2.error-message	(revision 58)
@@ -0,0 +1,3 @@
+--- !!omap
+- foo: bar
+- baz
Index: /pyyaml/trunk/tests/data/spec-08-06.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-06.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-06.error	(revision 38)
@@ -0,0 +1,4 @@
+ERROR:
+- The !$a! looks like a handle.
+- The !o! handle has no suffix.
+- The !h! handle wasn't declared.
Index: /pyyaml/trunk/tests/data/spec-09-25.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-25.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-09-25.canonical	(revision 44)
@@ -0,0 +1,4 @@
+%YAML 1.1
+---
+!!str "literal\n\
+      \ttext\n"
Index: /pyyaml/trunk/tests/data/spec-02-11.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-11.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-11.tokens	(revision 41)
@@ -0,0 +1,6 @@
+{{
+? [[ , _ , _ ]}
+: [[ , _ ]}
+? [ _ , _ ]
+: [ _ , _ , _ ]
+]}
Index: /pyyaml/trunk/tests/data/spec-02-06.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-06.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-06.structure	(revision 44)
@@ -0,0 +1,4 @@
+[
+    (True, [(True, True), (True, True)]),
+    (True, [(True, True), (True, True)]),
+]
Index: /pyyaml/trunk/tests/data/spec-02-27.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-27.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-27.structure	(revision 44)
@@ -0,0 +1,17 @@
+[
+(True, True),
+(True, True),
+(True, [
+    (True, True),
+    (True, True),
+    (True, [(True, True), (True, True), (True, True), (True, True)]),
+    ]),
+(True, '*'),
+(True, [
+        [(True, True), (True, True), (True, True), (True, True)],
+        [(True, True), (True, True), (True, True), (True, True)],
+    ]),
+(True, True),
+(True, True),
+(True, True),
+]
Index: /pyyaml/trunk/tests/data/construct-timestamp.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-timestamp.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-timestamp.code	(revision 58)
@@ -0,0 +1,7 @@
+{
+    "canonical": datetime.datetime(2001, 12, 15, 2, 59, 43, 100000),
+    "valid iso8601": datetime.datetime(2001, 12, 15, 2, 59, 43, 100000),
+    "space separated": datetime.datetime(2001, 12, 15, 2, 59, 43, 100000),
+    "no time zone (Z)": datetime.datetime(2001, 12, 15, 2, 59, 43, 100000),
+    "date (00:00:00Z)": datetime.datetime(2002, 12, 14),
+}
Index: /pyyaml/trunk/tests/data/spec-02-10.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-10.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-10.data	(revision 38)
@@ -0,0 +1,8 @@
+---
+hr:
+  - Mark McGwire
+  # Following node labeled SS
+  - &SS Sammy Sosa
+rbi:
+  - *SS # Subsequent occurrence
+  - Ken Griffey
Index: /pyyaml/trunk/tests/data/invalid-tag-handle-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-tag-handle-2.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-tag-handle-2.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%TAG    !foo    bar
+---
Index: /pyyaml/trunk/tests/data/spec-02-09.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-09.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-09.tokens	(revision 39)
@@ -0,0 +1,5 @@
+---
+{{
+? _ : [[ , _ , _ ]}
+? _ : [[ , _ , _ ]}
+]}
Index: /pyyaml/trunk/tests/data/spec-05-01-utf16be.empty
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-01-utf16be.empty	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-01-utf16be.empty	(revision 38)
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
Index: /pyyaml/trunk/tests/data/spec-02-22.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-22.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-22.data	(revision 38)
@@ -0,0 +1,4 @@
+canonical: 2001-12-15T02:59:43.1Z
+iso8601: 2001-12-14t21:59:43.10-05:00
+spaced: 2001-12-14 21:59:43.10 -5
+date: 2002-12-14
Index: /pyyaml/trunk/tests/data/int.data
===================================================================
--- /pyyaml/trunk/tests/data/int.data	(revision 55)
+++ /pyyaml/trunk/tests/data/int.data	(revision 55)
@@ -0,0 +1,6 @@
+- 685230
+- +685_230
+- 02472256
+- 0x_0A_74_AE
+- 0b1010_0111_0100_1010_1110
+- 190:20:30
Index: /pyyaml/trunk/tests/data/spec-08-10.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-10.data	(revision 56)
+++ /pyyaml/trunk/tests/data/spec-08-10.data	(revision 56)
@@ -0,0 +1,15 @@
+block styles:
+  scalars:
+    literal: !!str |
+      #!/usr/bin/perl
+      print "Hello, world!\n";
+    folded: >
+      This sentence
+      is false.
+  collections: !!map
+    sequence: !!seq # Entry:
+      - entry # Plain
+      # Mapping entry:
+      - key: value
+    mapping: 
+      key: value
Index: /pyyaml/trunk/tests/data/spec-10-09.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-09.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-09.data	(revision 38)
@@ -0,0 +1,4 @@
+{
+key : value,
+empty: # empty valueâ
+}
Index: /pyyaml/trunk/tests/data/spec-05-06.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-06.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-06.data	(revision 38)
@@ -0,0 +1,2 @@
+anchored: !local &anchor value
+alias: *anchor
Index: /pyyaml/trunk/tests/data/spec-07-12a.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-12a.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-12a.data	(revision 38)
@@ -0,0 +1,3 @@
+# Implicit document. Root
+# collection (mapping) node.
+foo : bar
Index: /pyyaml/trunk/tests/data/spec-07-06.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-06.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-06.data	(revision 38)
@@ -0,0 +1,5 @@
+%TAG !      !foo
+%TAG !yaml! tag:yaml.org,2002:
+---
+- !bar "baz"
+- !yaml!str "string"
Index: /pyyaml/trunk/tests/data/timestamp.detect
===================================================================
--- /pyyaml/trunk/tests/data/timestamp.detect	(revision 55)
+++ /pyyaml/trunk/tests/data/timestamp.detect	(revision 55)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:timestamp
Index: /pyyaml/trunk/tests/data/spec-09-06.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-06.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-06.data	(revision 38)
@@ -0,0 +1,1 @@
+ 'here''s to "quotes"'
Index: /pyyaml/trunk/tests/data/spec-09-18.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-18.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-18.data	(revision 38)
@@ -0,0 +1,9 @@
+- | # Just the style
+ literal
+- >1 # Indentation indicator
+  folded
+- |+ # Chomping indicator
+ keep
+
+- >-1 # Both indicators
+  strip
Index: /pyyaml/trunk/tests/data/invalid-uri-escapes-3.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-uri-escapes-3.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-uri-escapes-3.error-message	(revision 52)
@@ -0,0 +1,1 @@
+--- !<foo%d0%af%d0%af%d0bar> baz
Index: /pyyaml/trunk/tests/data/str.data
===================================================================
--- /pyyaml/trunk/tests/data/str.data	(revision 55)
+++ /pyyaml/trunk/tests/data/str.data	(revision 55)
@@ -0,0 +1,1 @@
+- abcd
Index: /pyyaml/trunk/tests/data/null.detect
===================================================================
--- /pyyaml/trunk/tests/data/null.detect	(revision 55)
+++ /pyyaml/trunk/tests/data/null.detect	(revision 55)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:null
Index: /pyyaml/trunk/tests/data/value.detect
===================================================================
--- /pyyaml/trunk/tests/data/value.detect	(revision 55)
+++ /pyyaml/trunk/tests/data/value.detect	(revision 55)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:value
Index: /pyyaml/trunk/tests/data/construct-omap.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-omap.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-omap.data	(revision 58)
@@ -0,0 +1,8 @@
+# Explicitly typed ordered map (dictionary).
+Bestiary: !!omap
+  - aardvark: African pig-like ant eater. Ugly.
+  - anteater: South-American ant eater. Two species.
+  - anaconda: South-American constrictor snake. Scaly.
+  # Etc.
+# Flow style
+Numbers: !!omap [ one: 1, two: 2, three : 3 ]
Index: /pyyaml/trunk/tests/data/spec-09-13.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-13.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-13.canonical	(revision 38)
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "simple key"
+  : !!map {
+    ? !!str "also simple"
+    : !!str "value",
+    ? !!str "not a simple key"
+    : !!str "any value"
+  }
+}
Index: /pyyaml/trunk/tests/data/spec-07-05.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-05.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-05.error	(revision 38)
@@ -0,0 +1,4 @@
+ERROR:
+The TAG directive must only
+be given at most once per
+handle in the same document.
Index: /pyyaml/trunk/tests/data/spec-06-08.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-08.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-08.canonical	(revision 38)
@@ -0,0 +1,5 @@
+%YAML 1.1
+--- !!str
+"specific\L\
+ trimmed\n\n\n\
+ as space"
Index: /pyyaml/trunk/tests/data/spec-08-07.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-07.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-07.canonical	(revision 38)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !<tag:yaml.org,2002:str> "12",
+  !<tag:yaml.org,2002:int> "12",
+  !<tag:yaml.org,2002:str> "12",
+]
Index: /pyyaml/trunk/tests/data/invalid-directive-name-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-directive-name-2.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-directive-name-2.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%invalid-characters:in-directive name
+---
Index: /pyyaml/trunk/tests/data/spec-02-20.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-20.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-20.tokens	(revision 41)
@@ -0,0 +1,8 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/spec-05-05.empty
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-05.empty	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-05.empty	(revision 38)
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
Index: /pyyaml/trunk/tests/data/spec-02-15.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-15.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-15.structure	(revision 44)
@@ -0,0 +1,1 @@
+True
Index: /pyyaml/trunk/tests/data/spec-02-18.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-18.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-18.tokens	(revision 41)
@@ -0,0 +1,4 @@
+{{
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/spec-10-06.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-06.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-06.data	(revision 38)
@@ -0,0 +1,2 @@
+- { inner : entry , also: inner , }
+- {inner: entry,last : entry}
Index: /pyyaml/trunk/tests/data/spec-05-03.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-03.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-03.data	(revision 38)
@@ -0,0 +1,7 @@
+sequence:
+- one
+- two
+mapping:
+  ? sky
+  : blue
+  ? sea : green
Index: /pyyaml/trunk/tests/data/spec-07-03.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-03.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-03.data	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+%YAML 1.1
+foo
Index: /pyyaml/trunk/tests/data/spec-05-15.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-15.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-15.data	(revision 38)
@@ -0,0 +1,3 @@
+Bad escapes:
+  "\c
+  \xq-"
Index: /pyyaml/trunk/tests/data/spec-09-03.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-03.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-03.data	(revision 38)
@@ -0,0 +1,6 @@
+- "
+  last"
+- " 	
+  last"
+- " 	first
+  last"
Index: /pyyaml/trunk/tests/data/duplicate-key.error-message
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-key.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/duplicate-key.error-message	(revision 58)
@@ -0,0 +1,3 @@
+---
+foo: bar
+foo: baz
Index: /pyyaml/trunk/tests/data/spec-09-15.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-15.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-15.data	(revision 38)
@@ -0,0 +1,13 @@
+---
+"---" : foo
+...: bar
+---
+[
+---,
+...,
+{
+? ---
+: ...
+}
+]
+...
Index: /pyyaml/trunk/tests/data/spec-09-27.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-27.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-27.data	(revision 38)
@@ -0,0 +1,8 @@
+|
+ 
+  
+  literal
+ 
+  text
+
+ # Comment
Index: /pyyaml/trunk/tests/data/scan-line-break-bug.data
===================================================================
--- /pyyaml/trunk/tests/data/scan-line-break-bug.data	(revision 60)
+++ /pyyaml/trunk/tests/data/scan-line-break-bug.data	(revision 60)
@@ -0,0 +1,3 @@
+foo:
+    bar
+    baz
Index: /pyyaml/trunk/tests/data/spec-05-03.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-03.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-05-03.canonical	(revision 44)
@@ -0,0 +1,14 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "sequence"
+  : !!seq [
+    !!str "one", !!str "two"
+  ],
+  ? !!str "mapping"
+  : !!map {
+    ? !!str "sky" : !!str "blue",
+#    ? !!str "sea" : !!str "green",
+    ? !!map { ? !!str "sea" : !!str "green" } : !!null "",
+  }
+}
Index: /pyyaml/trunk/tests/data/invalid-yaml-version.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-yaml-version.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-yaml-version.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%YAML   2.0
+--- foo
Index: /pyyaml/trunk/tests/data/spec-07-02.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-02.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-02.canonical	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "foo"
Index: /pyyaml/trunk/tests/data/spec-09-01.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-01.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-01.canonical	(revision 38)
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "simple key"
+  : !!map {
+    ? !!str "also simple"
+    : !!str "value",
+    ? !!str "not a simple key"
+    : !!str "any value"
+  }
+}
Index: /pyyaml/trunk/tests/data/spec-09-22.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-22.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-22.canonical	(revision 38)
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "strip"
+  : !!str "text",
+  ? !!str "clip"
+  : !!str "text\n",
+  ? !!str "keep"
+  : !!str "text\L",
+}
Index: /pyyaml/trunk/tests/data/spec-02-03.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-03.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-03.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, [True, True, True]), (True, [True, True, True])]
Index: /pyyaml/trunk/tests/data/invalid-omap-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-omap-1.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-omap-1.error-message	(revision 58)
@@ -0,0 +1,3 @@
+--- !!omap
+foo: bar
+baz: bat
Index: /pyyaml/trunk/tests/data/construct-merge.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-merge.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-merge.data	(revision 58)
@@ -0,0 +1,27 @@
+---
+- &CENTER { x: 1, 'y': 2 }
+- &LEFT { x: 0, 'y': 2 }
+- &BIG { r: 10 }
+- &SMALL { r: 1 }
+
+# All the following maps are equal:
+
+- # Explicit keys
+  x: 1
+  'y': 2
+  r: 10
+  label: center/big
+
+- # Merge one map
+  << : *CENTER
+  r: 10
+  label: center/big
+
+- # Merge multiple maps
+  << : [ *CENTER, *BIG ]
+  label: center/big
+
+- # Override
+  << : [ *BIG, *LEFT, *SMALL ]
+  x: 1
+  label: center/big
Index: /pyyaml/trunk/tests/data/spec-07-11.empty
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-11.empty	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-11.empty	(revision 38)
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
Index: /pyyaml/trunk/tests/data/spec-02-24.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-24.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-24.structure	(revision 44)
@@ -0,0 +1,5 @@
+[
+[(True, [(True, True), (True, True)]), (True, True)],
+[(True, '*'), (True, [(True, True), (True, True)])],
+[(True, '*'), (True, True), (True, True)],
+]
Index: /pyyaml/trunk/tests/data/spec-09-09.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-09.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-09.canonical	(revision 38)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !!str " last",
+  !!str " last",
+  !!str " \tfirst last",
+]
Index: /pyyaml/trunk/tests/data/spec-02-07.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-07.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-07.tokens	(revision 39)
@@ -0,0 +1,12 @@
+---
+[[
+, _
+, _
+, _
+]}
+
+---
+[[
+, _
+, _
+]}
Index: /pyyaml/trunk/tests/data/spec-10-03.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-03.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-03.data	(revision 38)
@@ -0,0 +1,4 @@
+block: # Block
+       # sequence
+- one
+- two : three
Index: /pyyaml/trunk/tests/data/invalid-tag-handle-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-tag-handle-1.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-tag-handle-1.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%TAG    foo bar
+---
Index: /pyyaml/trunk/tests/data/invalid-indentation-for-quoted-scalar.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-indentation-for-quoted-scalar.error-message	(revision 48)
+++ /pyyaml/trunk/tests/data/invalid-indentation-for-quoted-scalar.error-message	(revision 48)
@@ -0,0 +1,2 @@
+test: "foo
+bar"
Index: /pyyaml/trunk/tests/data/spec-02-27.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-27.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-27.tokens	(revision 41)
@@ -0,0 +1,20 @@
+--- !
+{{
+? _ : _
+? _ : _
+? _ : &
+    {{
+    ? _ : _
+    ? _ : _
+    ? _ : {{ ? _ : _ ? _ : _ ? _ : _ ? _ : _ ]}
+    ]}
+? _ : *
+? _ :
+    [[
+    , {{ ? _ : _ ? _ : _ ? _ : _ ? _ : _ ]}
+    , {{ ? _ : _ ? _ : _ ? _ : _ ? _ : _ ]}
+    ]}
+? _ : _
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/invalid-yaml-directive-version-6.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-yaml-directive-version-6.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-yaml-directive-version-6.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%YAML 123.C
+---
Index: /pyyaml/trunk/tests/data/spec-10-15.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-15.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-15.data	(revision 38)
@@ -0,0 +1,3 @@
+- sun: yellow
+- ? earth: blue
+  : moon: white
Index: /pyyaml/trunk/tests/data/bool.data
===================================================================
--- /pyyaml/trunk/tests/data/bool.data	(revision 59)
+++ /pyyaml/trunk/tests/data/bool.data	(revision 59)
@@ -0,0 +1,4 @@
+- yes
+- NO
+- True
+- on
Index: /pyyaml/trunk/tests/data/spec-05-12.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-12.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-12.data	(revision 38)
@@ -0,0 +1,9 @@
+# Tabs do's and don'ts:
+# comment: 	
+quoted: "Quoted		"
+block: |
+  void main() {
+  	printf("Hello, world!\n");
+  }
+elsewhere:	# separation
+	indentation, in	plain scalar
Index: /pyyaml/trunk/tests/data/invalid-block-scalar-indicator.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-block-scalar-indicator.error-message	(revision 48)
+++ /pyyaml/trunk/tests/data/invalid-block-scalar-indicator.error-message	(revision 48)
@@ -0,0 +1,2 @@
+--- > what is this?  # a comment
+data
Index: /pyyaml/trunk/tests/data/spec-02-08.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-08.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-08.data	(revision 38)
@@ -0,0 +1,10 @@
+---
+time: 20:03:20
+player: Sammy Sosa
+action: strike (miss)
+...
+---
+time: 20:03:47
+player: Sammy Sosa
+action: grand slam
+...
Index: /pyyaml/trunk/tests/data/spec-05-02-utf8.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-02-utf8.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-02-utf8.error	(revision 38)
@@ -0,0 +1,3 @@
+ERROR:
+ A BOM must not appear
+ inside a document.
Index: /pyyaml/trunk/tests/data/spec-05-02-utf16le.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-02-utf16le.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-02-utf16le.error	(revision 38)
@@ -0,0 +1,3 @@
+ERROR:
+ A BOM must not appear
+ inside a document.
Index: /pyyaml/trunk/tests/data/spec-09-12.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-12.data	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-09-12.data	(revision 48)
@@ -0,0 +1,8 @@
+# Outside flow collection:
+- ::std::vector
+- Up, up, and away!
+- -123
+# Inside flow collection:
+- [ '::std::vector',
+  "Up, up, and away!",
+  -123 ]
Index: /pyyaml/trunk/tests/data/invalid-tag-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-tag-2.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-tag-2.error-message	(revision 52)
@@ -0,0 +1,1 @@
+- !prefix!foo#bar baz
Index: /pyyaml/trunk/tests/data/yaml.detect
===================================================================
--- /pyyaml/trunk/tests/data/yaml.detect	(revision 56)
+++ /pyyaml/trunk/tests/data/yaml.detect	(revision 56)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:yaml
Index: /pyyaml/trunk/tests/data/spec-06-08.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-08.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-08.data	(revision 38)
@@ -0,0 +1,7 @@
+>-
+  specificâš  trimmedÂ
+  Â
+ Â
+Â
+  asÂ
+  space
Index: /pyyaml/trunk/tests/data/spec-09-24.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-24.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-24.data	(revision 38)
@@ -0,0 +1,6 @@
+strip: >-
+
+clip: >
+
+keep: |+
+
Index: /pyyaml/trunk/tests/data/spec-08-08.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-08.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-08.data	(revision 38)
@@ -0,0 +1,13 @@
+---
+foo:
+ "bar
+ baz"
+---
+"foo
+ bar"
+---
+foo
+ bar
+--- |
+ foo
+...
Index: /pyyaml/trunk/tests/data/float.detect
===================================================================
--- /pyyaml/trunk/tests/data/float.detect	(revision 55)
+++ /pyyaml/trunk/tests/data/float.detect	(revision 55)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:float
Index: /pyyaml/trunk/tests/data/invalid-uri-escapes-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-uri-escapes-2.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-uri-escapes-2.error-message	(revision 52)
@@ -0,0 +1,1 @@
+--- !<%FF> foo
Index: /pyyaml/trunk/tests/data/str.detect
===================================================================
--- /pyyaml/trunk/tests/data/str.detect	(revision 55)
+++ /pyyaml/trunk/tests/data/str.detect	(revision 55)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:str
Index: /pyyaml/trunk/tests/data/spec-10-05.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-05.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-10-05.canonical	(revision 44)
@@ -0,0 +1,14 @@
+%YAML 1.1
+---
+!!seq [
+  !!null "",
+  !!str "block node\n",
+  !!seq [
+    !!str "one",
+    !!str "two",
+  ],
+  !!map {
+    ? !!str "one"
+    : !!str "two",
+  }
+]
Index: /pyyaml/trunk/tests/data/construct-int.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-int.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-int.data	(revision 58)
@@ -0,0 +1,6 @@
+canonical: 685230
+decimal: +685_230
+octal: 02472256
+hexadecimal: 0x_0A_74_AE
+binary: 0b1010_0111_0100_1010_1110
+sexagesimal: 190:20:30
Index: /pyyaml/trunk/tests/data/spec-09-10.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-10.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-10.canonical	(revision 38)
@@ -0,0 +1,5 @@
+%YAML 1.1
+---
+!!str "first \
+  inner \
+  last"
Index: /pyyaml/trunk/tests/data/construct-set.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-set.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-set.data	(revision 58)
@@ -0,0 +1,7 @@
+# Explicitly typed set.
+baseball players: !!set
+  ? Mark McGwire
+  ? Sammy Sosa
+  ? Ken Griffey
+# Flow style
+baseball teams: !!set { Boston Red Sox, Detroit Tigers, New York Yankees }
Index: /pyyaml/trunk/tests/data/spec-06-05.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-05.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-05.canonical	(revision 38)
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+!!map {
+  ? !!map {
+    ? !!str "first"
+    : !!str "Sammy",
+    ? !!str "last"
+    : !!str "Sosa"
+  }
+  : !!map {
+    ? !!str "hr"
+    : !!int "65",
+    ? !!str "avg"
+    : !!float "0.278"
+  }
+}
Index: /pyyaml/trunk/tests/data/spec-09-31.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-31.canonical	(revision 51)
+++ /pyyaml/trunk/tests/data/spec-09-31.canonical	(revision 51)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "folded line\n\
+      next line\n\n\
+      \  * bullet\n\
+      \  * list\n\n\
+      last line\n"
Index: /pyyaml/trunk/tests/data/invalid-directive-name-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-directive-name-1.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-directive-name-1.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%   # no name at all
+---
Index: /pyyaml/trunk/tests/data/spec-02-12.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-12.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-12.structure	(revision 44)
@@ -0,0 +1,5 @@
+[
+[(True, True), (True, True)],
+[(True, True), (True, True)],
+[(True, True), (True, True)],
+]
Index: /pyyaml/trunk/tests/data/spec-09-18.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-18.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-18.canonical	(revision 38)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "literal\n",
+  !!str " folded\n",
+  !!str "keep\n\n",
+  !!str " strip",
+]
Index: /pyyaml/trunk/tests/data/undefined-constructor.error-message
===================================================================
--- /pyyaml/trunk/tests/data/undefined-constructor.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/undefined-constructor.error-message	(revision 58)
@@ -0,0 +1,1 @@
+--- !foo bar
Index: /pyyaml/trunk/tests/data/spec-02-16.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-16.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-16.tokens	(revision 41)
@@ -0,0 +1,5 @@
+{{
+? _ : _
+? _ : _
+? _ : _
+]}
Index: /pyyaml/trunk/tests/data/spec-10-12.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-12.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-12.data	(revision 38)
@@ -0,0 +1,3 @@
+block: # Block
+    # mapping
+ key: value
Index: /pyyaml/trunk/tests/data/duplicate-yaml-directive.error-message
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-yaml-directive.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/duplicate-yaml-directive.error-message	(revision 52)
@@ -0,0 +1,3 @@
+%YAML   1.1
+%YAML   1.1
+--- foo
Index: /pyyaml/trunk/tests/data/construct-str.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-str.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-str.data	(revision 58)
@@ -0,0 +1,1 @@
+string: abcd
Index: /pyyaml/trunk/tests/data/spec-02-05.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-05.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-05.data	(revision 38)
@@ -0,0 +1,3 @@
+- [name        , hr, avg  ]
+- [Mark McGwire, 65, 0.278]
+- [Sammy Sosa  , 63, 0.288]
Index: /pyyaml/trunk/tests/data/forbidden-entry.error-message
===================================================================
--- /pyyaml/trunk/tests/data/forbidden-entry.error-message	(revision 47)
+++ /pyyaml/trunk/tests/data/forbidden-entry.error-message	(revision 47)
@@ -0,0 +1,2 @@
+test: - foo
+      - bar
Index: /pyyaml/trunk/tests/data/spec-02-17.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-17.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-17.data	(revision 38)
@@ -0,0 +1,7 @@
+unicode: "Sosa did fine.\u263A"
+control: "\b1998\t1999\t2000\n"
+hexesc:  "\x13\x10 is \r\n"
+
+single: '"Howdy!" he cried.'
+quoted: ' # not a ''comment''.'
+tie-fighter: '|\-*-/|'
Index: /pyyaml/trunk/tests/data/spec-06-05.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-05.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-05.data	(revision 38)
@@ -0,0 +1,6 @@
+{ first: Sammy, last: Sosa }:
+# Statistics:
+  hr:  # Home runs
+    65
+  avg: # Average
+    0.278
Index: /pyyaml/trunk/tests/data/spec-09-21.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-21.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-21.data	(revision 38)
@@ -0,0 +1,8 @@
+- |
+  
+ text
+- >
+  text
+ text
+- |1
+ text
Index: /pyyaml/trunk/tests/data/spec-08-05.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-05.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-05.data	(revision 38)
@@ -0,0 +1,5 @@
+%TAG !o! tag:ben-kiki.org,2000:
+---
+- !local foo
+- !!str bar
+- !o!type baz
Index: /pyyaml/trunk/tests/data/spec-09-33.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-33.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-33.data	(revision 38)
@@ -0,0 +1,14 @@
+>
+ folded
+ line
+
+ next
+ line
+
+   * bullet
+   * list
+
+ last
+ line
+
+# Comment
Index: /pyyaml/trunk/tests/data/spec-10-14.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-14.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-10-14.canonical	(revision 48)
@@ -0,0 +1,11 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "plain key"
+  : !!null "",
+  ? !!str "quoted key"
+  : !!seq [
+    !!str "one",
+    !!str "two",
+  ]
+}
Index: /pyyaml/trunk/tests/data/construct-seq.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-seq.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-seq.data	(revision 58)
@@ -0,0 +1,15 @@
+# Ordered sequence of nodes
+Block style: !!seq
+- Mercury   # Rotates - no light/dark sides.
+- Venus     # Deadliest. Aptly named.
+- Earth     # Mostly dirt.
+- Mars      # Seems empty.
+- Jupiter   # The king.
+- Saturn    # Pretty.
+- Uranus    # Where the sun hardly shines.
+- Neptune   # Boring. No rings.
+- Pluto     # You call this a planet?
+Flow style: !!seq [ Mercury, Venus, Earth, Mars,      # Rocks
+                    Jupiter, Saturn, Uranus, Neptune, # Gas
+                    Pluto ]                           # Overrated
+
Index: /pyyaml/trunk/tests/data/spec-05-12.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-12.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-12.error	(revision 38)
@@ -0,0 +1,8 @@
+ERROR:
+ Tabs may appear inside
+ comments and quoted or
+ block scalar content.
+ Tabs must not appear
+ elsewhere, such as
+ in indentation and
+ separation spaces.
Index: /pyyaml/trunk/tests/data/spec-08-13.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-13.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-08-13.canonical	(revision 44)
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "foo"
+#  : !!str "",
+#  ? !!str ""
+  : !!null "",
+  ? !!null ""
+  : !!str "bar",
+}
Index: /pyyaml/trunk/tests/data/spec-05-01-utf8.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-01-utf8.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-01-utf8.data	(revision 38)
@@ -0,0 +1,1 @@
+﻿# Comment only.
Index: /pyyaml/trunk/tests/data/spec-05-08.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-08.canonical	(revision 51)
+++ /pyyaml/trunk/tests/data/spec-05-08.canonical	(revision 51)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "single"
+  : !!str "text",
+  ? !!str "double"
+  : !!str "text",
+}
Index: /pyyaml/trunk/tests/data/spec-08-04.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-04.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-04.error	(revision 38)
@@ -0,0 +1,6 @@
+ERROR:
+- Verbatim tags aren't resolved,
+  so ! is invalid.
+- The $:? tag is neither a global
+  URI tag nor a local tag starting
+  with â!â.
Index: /pyyaml/trunk/tests/data/unclosed-quoted-scalar.error-message
===================================================================
--- /pyyaml/trunk/tests/data/unclosed-quoted-scalar.error-message	(revision 48)
+++ /pyyaml/trunk/tests/data/unclosed-quoted-scalar.error-message	(revision 48)
@@ -0,0 +1,2 @@
+'foo
+ bar
Index: /pyyaml/trunk/tests/data/spec-02-21.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-21.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-21.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True), (True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/spec-09-06.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-06.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-06.canonical	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "here's to \"quotes\""
Index: /pyyaml/trunk/tests/data/spec-09-14.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-14.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-14.error	(revision 38)
@@ -0,0 +1,6 @@
+ERROR:
+ The --- and ... document
+ start and end markers must
+ not be specified as the
+ first content line of a
+ non-indented plain scalar.
Index: /pyyaml/trunk/tests/data/duplicate-anchor-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-anchor-2.error-message	(revision 53)
+++ /pyyaml/trunk/tests/data/duplicate-anchor-2.error-message	(revision 53)
@@ -0,0 +1,1 @@
+&foo [1, 2, 3, &foo 4]
Index: /pyyaml/trunk/tests/data/spec-09-27.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-27.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-09-27.canonical	(revision 48)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "\n\nliteral\n\ntext\n"
Index: /pyyaml/trunk/tests/data/invalid-merge-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-merge-2.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-merge-2.error-message	(revision 58)
@@ -0,0 +1,2 @@
+foo: bar
+<<: [x: 1, y: 2, z, t: 4]
Index: /pyyaml/trunk/tests/data/scan-line-break-bug.canonical
===================================================================
--- /pyyaml/trunk/tests/data/scan-line-break-bug.canonical	(revision 60)
+++ /pyyaml/trunk/tests/data/scan-line-break-bug.canonical	(revision 60)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!map { ? !!str "foo" : !!str "bar baz" }
Index: /pyyaml/trunk/tests/data/spec-02-05.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-05.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-05.tokens	(revision 39)
@@ -0,0 +1,5 @@
+[[
+, [ _ , _ , _ ]
+, [ _ , _ , _ ]
+, [ _ , _ , _ ]
+]}
Index: /pyyaml/trunk/tests/data/spec-02-08.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-08.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-08.structure	(revision 44)
@@ -0,0 +1,4 @@
+[
+[(True, True), (True, True), (True, True)],
+[(True, True), (True, True), (True, True)],
+]
Index: /pyyaml/trunk/tests/data/spec-02-25.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-25.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-25.tokens	(revision 41)
@@ -0,0 +1,6 @@
+--- !
+{{
+? _
+? _
+? _
+]}
Index: /pyyaml/trunk/tests/data/spec-02-02.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-02.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-02.data	(revision 38)
@@ -0,0 +1,3 @@
+hr:  65    # Home runs
+avg: 0.278 # Batting average
+rbi: 147   # Runs Batted In
Index: /pyyaml/trunk/tests/data/invalid-yaml-directive-version-5.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-yaml-directive-version-5.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-yaml-directive-version-5.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%YAML A.0
+---
Index: /pyyaml/trunk/tests/data/spec-02-14.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-14.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-14.data	(revision 38)
@@ -0,0 +1,4 @@
+---
+  Mark McGwire's
+  year was crippled
+  by a knee injury.
Index: /pyyaml/trunk/tests/data/spec-06-02.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-02.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-06-02.data	(revision 38)
@@ -0,0 +1,3 @@
+  # Comment
+   
+
Index: /pyyaml/trunk/tests/data/construct-custom.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-custom.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-custom.code	(revision 58)
@@ -0,0 +1,9 @@
+[
+    MyTestClass1(x=1),
+    MyTestClass1(x=1, y=2, z=3),
+    MyTestClass2(x=10),
+    MyTestClass2(x=10, y=20, z=30),
+    MyTestClass3(x=1),
+    MyTestClass3(x=1, y=2, z=3),
+    MyTestClass3(x=1, y=2, z=3),
+]
Index: /pyyaml/trunk/tests/data/spec-02-26.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-26.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-26.data	(revision 38)
@@ -0,0 +1,7 @@
+# ordered maps are represented as
+# a sequence of mappings, with
+# each mapping having one key
+--- !!omap
+- Mark McGwire: 65
+- Sammy Sosa: 63
+- Ken Griffy: 58
Index: /pyyaml/trunk/tests/data/spec-08-02.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-02.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-02.data	(revision 38)
@@ -0,0 +1,2 @@
+First occurrence: &anchor Value
+Second occurrence: *anchor
Index: /pyyaml/trunk/tests/data/invalid-tag-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-tag-1.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-tag-1.error-message	(revision 52)
@@ -0,0 +1,1 @@
+- !<foo#bar> baz
Index: /pyyaml/trunk/tests/data/no-node-2.error-message
===================================================================
--- /pyyaml/trunk/tests/data/no-node-2.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/no-node-2.error-message	(revision 52)
@@ -0,0 +1,1 @@
+- [ !foo } ]
Index: /pyyaml/trunk/tests/data/spec-09-30.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-30.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-30.data	(revision 38)
@@ -0,0 +1,14 @@
+>
+ folded
+ line
+
+ next
+ line
+
+   * bullet
+   * list
+
+ last
+ line
+
+# Comment
Index: /pyyaml/trunk/tests/data/spec-08-14.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-14.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-14.data	(revision 38)
@@ -0,0 +1,5 @@
+- "flow in block"
+- >
+ Block scalar
+- !!map # Block collection
+  foo : bar
Index: /pyyaml/trunk/tests/data/invalid-uri-escapes-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-uri-escapes-1.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-uri-escapes-1.error-message	(revision 52)
@@ -0,0 +1,1 @@
+--- !<tag:%x?y> foo
Index: /pyyaml/trunk/tests/data/invalid-simple-key.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-simple-key.error-message	(revision 47)
+++ /pyyaml/trunk/tests/data/invalid-simple-key.error-message	(revision 47)
@@ -0,0 +1,3 @@
+key: value
+invalid simple key
+next key: next value
Index: /pyyaml/trunk/tests/data/spec-10-02.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-02.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-02.canonical	(revision 38)
@@ -0,0 +1,14 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "double quoted",
+  !!str "single quoted",
+  !!str "plain text",
+  !!seq [
+    !!str "nested",
+  ],
+  !!map {
+    ? !!str "single"
+    : !!str "pair"
+  }
+]
Index: /pyyaml/trunk/tests/data/spec-08-01.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-01.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-08-01.canonical	(revision 42)
@@ -0,0 +1,8 @@
+%YAML 1.1
+---
+!!map {
+  ? &A1 !!str "foo"
+  : !!str "bar",
+  ? &A2 !!str "baz"
+  : *A1
+}
Index: /pyyaml/trunk/tests/data/invalid-utf8-byte.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-utf8-byte.error-message	(revision 47)
+++ /pyyaml/trunk/tests/data/invalid-utf8-byte.error-message	(revision 47)
@@ -0,0 +1,18 @@
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+Invalid byte ('\xFF'): ÿ <--
+-------------------------------------------------------------------------------------------------------------------------------
Index: /pyyaml/trunk/tests/data/spec-07-03.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-03.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-03.error	(revision 38)
@@ -0,0 +1,3 @@
+ERROR:
+The YAML directive must only be
+given at most once per document.
Index: /pyyaml/trunk/tests/data/no-flow-mapping-end.error-message
===================================================================
--- /pyyaml/trunk/tests/data/no-flow-mapping-end.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/no-flow-mapping-end.error-message	(revision 52)
@@ -0,0 +1,1 @@
+{ foo: bar ]
Index: /pyyaml/trunk/tests/data/spec-09-15.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-15.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-09-15.canonical	(revision 42)
@@ -0,0 +1,18 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "---"
+  : !!str "foo",
+  ? !!str "..."
+  : !!str "bar"
+}
+%YAML 1.1
+---
+!!seq [
+  !!str "---",
+  !!str "...",
+  !!map {
+    ? !!str "---"
+    : !!str "..."
+  }
+]
Index: /pyyaml/trunk/tests/data/recursive-anchor.error-message
===================================================================
--- /pyyaml/trunk/tests/data/recursive-anchor.error-message	(revision 53)
+++ /pyyaml/trunk/tests/data/recursive-anchor.error-message	(revision 53)
@@ -0,0 +1,4 @@
+- &foo [1
+    2,
+    3,
+    *foo]
Index: /pyyaml/trunk/tests/data/spec-07-07b.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-07b.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-07b.canonical	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!<tag:ben-kiki.org,2000:app/foo> "bar"
Index: /pyyaml/trunk/tests/data/spec-08-09.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-09.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-08-09.canonical	(revision 42)
@@ -0,0 +1,21 @@
+%YAML 1.1
+--- !!map {
+  ? !!str "scalars" : !!map {
+      ? !!str "plain"
+      : !!str "some text",
+      ? !!str "quoted"
+      : !!map {
+        ? !!str "single"
+        : !!str "some text",
+        ? !!str "double"
+        : !!str "some text"
+  } },
+  ? !!str "collections" : !!map {
+    ? !!str "sequence" : !!seq [
+      !!str "entry",
+      !!map {
+        ? !!str "key" : !!str "value"
+    } ],
+    ? !!str "mapping" : !!map {
+      ? !!str "key" : !!str "value"
+} } }
Index: /pyyaml/trunk/tests/data/spec-02-14.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-14.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-14.tokens	(revision 41)
@@ -0,0 +1,1 @@
+--- _
Index: /pyyaml/trunk/tests/data/spec-02-17.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-17.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-17.structure	(revision 44)
@@ -0,0 +1,1 @@
+[(True, True), (True, True), (True, True), (True, True), (True, True), (True, True)]
Index: /pyyaml/trunk/tests/data/unclosed-bracket.error-message
===================================================================
--- /pyyaml/trunk/tests/data/unclosed-bracket.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/unclosed-bracket.error-message	(revision 52)
@@ -0,0 +1,6 @@
+test:
+    - [ foo: bar
+# comment the rest of the stream to let the scanner detect the problem.
+#    - baz
+#"we could have detected the unclosed bracket on the above line, but this would forbid such syntax as": {
+#}
Index: /pyyaml/trunk/tests/data/spec-02-11.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-11.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-11.data	(revision 38)
@@ -0,0 +1,9 @@
+? - Detroit Tigers
+  - Chicago cubs
+:
+  - 2001-07-23
+
+? [ New York Yankees,
+    Atlanta Braves ]
+: [ 2001-07-02, 2001-08-12,
+    2001-08-14 ]
Index: /pyyaml/trunk/tests/data/spec-02-23.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-23.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-23.data	(revision 38)
@@ -0,0 +1,13 @@
+---
+not-date: !!str 2002-04-28
+
+picture: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X
+ 17unp5WZmZgAAAOfn515eXv
+ Pz7Y6OjuDg4J+fn5OTk6enp
+ 56enmleECcgggoBADs=
+
+application specific tag: !something |
+ The semantics of the tag
+ above may be different for
+ different documents.
Index: /pyyaml/trunk/tests/data/spec-08-11.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-11.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-08-11.data	(revision 38)
@@ -0,0 +1,2 @@
+First occurrence: &anchor Value
+Second occurrence: *anchor
Index: /pyyaml/trunk/tests/data/construct-map.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-map.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-map.code	(revision 58)
@@ -0,0 +1,6 @@
+{
+    "Block style":
+        { "Clark" : "Evans", "Brian" : "Ingerson", "Oren" : "Ben-Kiki" },
+    "Flow style":
+        { "Clark" : "Evans", "Brian" : "Ingerson", "Oren" : "Ben-Kiki" },
+}
Index: /pyyaml/trunk/tests/data/spec-07-12b.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-12b.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-12b.data	(revision 38)
@@ -0,0 +1,4 @@
+# Explicit document. Root
+# scalar (literal) node.
+--- |
+ Text content
Index: /pyyaml/trunk/tests/data/spec-05-07.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-07.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-07.data	(revision 38)
@@ -0,0 +1,4 @@
+literal: |
+  text
+folded: >
+  text
Index: /pyyaml/trunk/tests/data/spec-09-07.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-07.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-07.data	(revision 38)
@@ -0,0 +1,6 @@
+'simple key' : {
+  'also simple' : value,
+  ? 'not a
+  simple key' : 'any
+  value'
+}
Index: /pyyaml/trunk/tests/data/spec-10-11.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-11.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-10-11.canonical	(revision 44)
@@ -0,0 +1,24 @@
+%YAML 1.1
+---
+!!seq [
+  !!map {
+    ? !!str "explicit key1"
+    : !!str "explicit value",
+  },
+  !!map {
+    ? !!str "explicit key2"
+    : !!null "",
+  },
+  !!map {
+    ? !!str "explicit key3"
+    : !!null "",
+  },
+  !!map {
+    ? !!str "simple key1"
+    : !!str "explicit value",
+  },
+  !!map {
+    ? !!str "simple key2"
+    : !!null "",
+  },
+]
Index: /pyyaml/trunk/tests/data/construct-binary.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-binary.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-binary.data	(revision 58)
@@ -0,0 +1,12 @@
+canonical: !!binary "\
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5\
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+\
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC\
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs="
+generic: !!binary |
+ R0lGODlhDAAMAIQAAP//9/X17unp5WZmZgAAAOfn515eXvPz7Y6OjuDg4J+fn5
+ OTk6enp56enmlpaWNjY6Ojo4SEhP/++f/++f/++f/++f/++f/++f/++f/++f/+
+ +f/++f/++f/++f/++f/++SH+Dk1hZGUgd2l0aCBHSU1QACwAAAAADAAMAAAFLC
+ AgjoEwnuNAFOhpEMTRiggcz4BNJHrv/zCFcLiwMWYNG84BwwEeECcgggoBADs=
+description:
+ The binary value above is a tiny arrow encoded as a gif image.
Index: /pyyaml/trunk/tests/data/spec-09-19.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-19.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-19.data	(revision 38)
@@ -0,0 +1,4 @@
+- |
+ literal
+- >
+ folded
Index: /pyyaml/trunk/tests/data/spec-08-10.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-08-10.canonical	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-08-10.canonical	(revision 48)
@@ -0,0 +1,23 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "block styles" : !!map {
+    ? !!str "scalars" : !!map {
+      ? !!str "literal"
+      : !!str "#!/usr/bin/perl\n\
+          print \"Hello,
+          world!\\n\";\n",
+      ? !!str "folded"
+      : !!str "This sentence
+          is false.\n"
+    },
+    ? !!str "collections" : !!map {
+      ? !!str "sequence" : !!seq [
+        !!str "entry",
+        !!map {
+          ? !!str "key" : !!str "value"
+        }
+      ],
+      ? !!str "mapping" : !!map {
+        ? !!str "key" : !!str "value"
+} } } }
Index: /pyyaml/trunk/tests/data/spec-07-04.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-04.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-04.canonical	(revision 38)
@@ -0,0 +1,3 @@
+%YAML 1.1
+---
+!!str "foo"
Index: /pyyaml/trunk/tests/data/spec-09-03.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-03.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-03.canonical	(revision 38)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!seq [
+  !!str " last",
+  !!str " last",
+  !!str " \tfirst last",
+]
Index: /pyyaml/trunk/tests/data/spec-05-15.error
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-15.error	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-15.error	(revision 38)
@@ -0,0 +1,3 @@
+ERROR:
+- c is an invalid escaped character.
+- q and - are invalid hex digits.
Index: /pyyaml/trunk/tests/data/spec-09-24.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-24.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-09-24.canonical	(revision 42)
@@ -0,0 +1,10 @@
+%YAML 1.1
+---
+!!map {
+  ? !!str "strip"
+  : !!str "",
+  ? !!str "clip"
+  : !!str "",
+  ? !!str "keep"
+  : !!str "\n",
+}
Index: /pyyaml/trunk/tests/data/spec-02-05.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-05.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-05.structure	(revision 44)
@@ -0,0 +1,5 @@
+[
+    [True, True, True],
+    [True, True, True],
+    [True, True, True],
+]
Index: /pyyaml/trunk/tests/data/duplicate-anchor-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/duplicate-anchor-1.error-message	(revision 53)
+++ /pyyaml/trunk/tests/data/duplicate-anchor-1.error-message	(revision 53)
@@ -0,0 +1,3 @@
+- &foo bar
+- &bar bar
+- &foo bar
Index: /pyyaml/trunk/tests/data/spec-02-03.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-03.tokens	(revision 39)
+++ /pyyaml/trunk/tests/data/spec-02-03.tokens	(revision 39)
@@ -0,0 +1,4 @@
+{{
+? _ : [[ , _ , _ , _ ]}
+? _ : [[ , _ , _ , _ ]}
+]}
Index: /pyyaml/trunk/tests/data/invalid-merge-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-merge-1.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/invalid-merge-1.error-message	(revision 58)
@@ -0,0 +1,2 @@
+foo: bar
+<<: baz
Index: /pyyaml/trunk/tests/data/spec-02-26.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-26.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-26.structure	(revision 44)
@@ -0,0 +1,5 @@
+[
+[(True, True)],
+[(True, True)],
+[(True, True)],
+]
Index: /pyyaml/trunk/tests/data/spec-02-23.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-23.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-23.tokens	(revision 41)
@@ -0,0 +1,6 @@
+---
+{{
+? _ : ! _
+? _ : ! _
+? _ : ! _
+]}
Index: /pyyaml/trunk/tests/data/construct-float.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-float.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-float.code	(revision 58)
@@ -0,0 +1,8 @@
+{
+    "canonical": 685230.15,
+    "exponential": 685230.15,
+    "fixed": 685230.15,
+    "sexagesimal": 685230.15,
+    "negative infinity": -1e300000,
+    "not a number": 1e300000/1e300000,
+}
Index: /pyyaml/trunk/tests/data/spec-02-20.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-20.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-20.data	(revision 38)
@@ -0,0 +1,6 @@
+canonical: 1.23015e+3
+exponential: 12.3015e+02
+sexagesimal: 20:30.15
+fixed: 1,230.15
+negative infinity: -.inf
+not a number: .NaN
Index: /pyyaml/trunk/tests/data/invalid-yaml-directive-version-4.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-yaml-directive-version-4.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/invalid-yaml-directive-version-4.error-message	(revision 52)
@@ -0,0 +1,2 @@
+%YAML 1.132.435
+---
Index: /pyyaml/trunk/tests/data/int.detect
===================================================================
--- /pyyaml/trunk/tests/data/int.detect	(revision 55)
+++ /pyyaml/trunk/tests/data/int.detect	(revision 55)
@@ -0,0 +1,1 @@
+tag:yaml.org,2002:int
Index: /pyyaml/trunk/tests/data/spec-10-07.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-07.data	(revision 47)
+++ /pyyaml/trunk/tests/data/spec-10-07.data	(revision 47)
@@ -0,0 +1,7 @@
+{
+? : value, # Empty key
+? explicit
+ key: value,
+simple key : value,
+[ collection, simple, key ]: value
+}
Index: /pyyaml/trunk/tests/data/spec-05-04.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-04.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-04.data	(revision 38)
@@ -0,0 +1,2 @@
+sequence: [ one, two, ]
+mapping: { sky: blue, sea: green }
Index: /pyyaml/trunk/tests/data/construct-value.code
===================================================================
--- /pyyaml/trunk/tests/data/construct-value.code	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-value.code	(revision 58)
@@ -0,0 +1,9 @@
+[
+    { "link with": [ "library1.dll", "library2.dll" ] },
+    {
+        "link with": [
+            { "=": "library1.dll", "version": 1.2 },
+            { "=": "library2.dll", "version": 2.3 },
+        ],
+    },
+]
Index: /pyyaml/trunk/tests/data/no-node-1.error-message
===================================================================
--- /pyyaml/trunk/tests/data/no-node-1.error-message	(revision 52)
+++ /pyyaml/trunk/tests/data/no-node-1.error-message	(revision 52)
@@ -0,0 +1,1 @@
+- !foo ]
Index: /pyyaml/trunk/tests/data/spec-07-04.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-04.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-04.data	(revision 38)
@@ -0,0 +1,3 @@
+%TAG !yaml! tag:yaml.org,2002:
+---
+!yaml!str "foo"
Index: /pyyaml/trunk/tests/data/construct-pairs.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-pairs.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-pairs.data	(revision 58)
@@ -0,0 +1,7 @@
+# Explicitly typed pairs.
+Block tasks: !!pairs
+  - meeting: with team.
+  - meeting: with boss.
+  - break: lunch.
+  - meeting: with client.
+Flow tasks: !!pairs [ meeting: with team, meeting: with boss ]
Index: /pyyaml/trunk/tests/data/spec-09-04.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-04.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-04.data	(revision 38)
@@ -0,0 +1,4 @@
+ "first
+ 	inner 1	
+ \ inner 2 \
+ last"
Index: /pyyaml/trunk/tests/data/spec-05-01-utf16le.empty
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-01-utf16le.empty	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-01-utf16le.empty	(revision 38)
@@ -0,0 +1,2 @@
+# This stream contains no
+# documents, only comments.
Index: /pyyaml/trunk/tests/data/spec-09-16.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-16.data	(revision 48)
+++ /pyyaml/trunk/tests/data/spec-09-16.data	(revision 48)
@@ -0,0 +1,7 @@
+# Tabs are confusing:
+# as space/trimmed/specific/none
+ as space Â
+ trimmed Â
+Â
+ specificâšÂ
+ none
Index: /pyyaml/trunk/tests/data/float.data
===================================================================
--- /pyyaml/trunk/tests/data/float.data	(revision 55)
+++ /pyyaml/trunk/tests/data/float.data	(revision 55)
@@ -0,0 +1,6 @@
+- 6.8523015e+5
+- 685.230_15e+03
+- 685_230.15
+- 190:20:30.15
+- -.inf
+- .NaN
Index: /pyyaml/trunk/tests/data/spec-09-28.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-28.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-28.data	(revision 38)
@@ -0,0 +1,8 @@
+|
+ 
+  
+  literal
+ 
+  text
+
+ # Comment
Index: /pyyaml/trunk/tests/data/spec-10-07.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-07.canonical	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-10-07.canonical	(revision 44)
@@ -0,0 +1,16 @@
+%YAML 1.1
+---
+!!map {
+  ? !!null ""
+  : !!str "value",
+  ? !!str "explicit key"
+  : !!str "value",
+  ? !!str "simple key"
+  : !!str "value",
+  ? !!seq [
+    !!str "collection",
+    !!str "simple",
+    !!str "key"
+  ]
+  : !!str "value"
+}
Index: /pyyaml/trunk/tests/data/spec-05-14.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-14.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-05-14.canonical	(revision 42)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+"Fun with \x5C
+ \x22 \x07 \x08 \x1B \x0C
+ \x0A \x0D \x09 \x0B \x00
+ \x20 \xA0 \x85 \u2028 \u2029
+ A A A"
Index: /pyyaml/trunk/tests/data/value.data
===================================================================
--- /pyyaml/trunk/tests/data/value.data	(revision 55)
+++ /pyyaml/trunk/tests/data/value.data	(revision 55)
@@ -0,0 +1,1 @@
+- =
Index: /pyyaml/trunk/tests/data/construct-bool.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-bool.data	(revision 59)
+++ /pyyaml/trunk/tests/data/construct-bool.data	(revision 59)
@@ -0,0 +1,4 @@
+canonical: yes
+answer: NO
+logical: True
+option: on
Index: /pyyaml/trunk/tests/data/spec-07-13.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-13.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-13.canonical	(revision 38)
@@ -0,0 +1,9 @@
+%YAML 1.1
+---
+!!str "First document"
+---
+!<!foo> "No directives"
+---
+!<!foobar> "With directives"
+---
+!<!baz> "Reset settings"
Index: /pyyaml/trunk/tests/data/spec-09-12.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-12.canonical	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-12.canonical	(revision 38)
@@ -0,0 +1,12 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "::std::vector",
+  !!str "Up, up, and away!",
+  !!int "-123",
+  !!seq [
+    !!str "::std::vector",
+    !!str "Up, up, and away!",
+    !!int "-123",
+  ]
+]
Index: /pyyaml/trunk/tests/data/spec-06-07.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-06-07.canonical	(revision 42)
+++ /pyyaml/trunk/tests/data/spec-06-07.canonical	(revision 42)
@@ -0,0 +1,6 @@
+%YAML 1.1
+---
+!!seq [
+  !!str "foo\nbar",
+  !!str "foo\n\nbar"
+]
Index: /pyyaml/trunk/tests/data/spec-09-33.canonical
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-33.canonical	(revision 51)
+++ /pyyaml/trunk/tests/data/spec-09-33.canonical	(revision 51)
@@ -0,0 +1,7 @@
+%YAML 1.1
+---
+!!str "folded line\n\
+      next line\n\n\
+      \  * bullet\n\
+      \  * list\n\n\
+      last line\n"
Index: /pyyaml/trunk/tests/data/spec-02-14.structure
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-14.structure	(revision 44)
+++ /pyyaml/trunk/tests/data/spec-02-14.structure	(revision 44)
@@ -0,0 +1,1 @@
+True
Index: /pyyaml/trunk/tests/data/invalid-character.error-message
===================================================================
--- /pyyaml/trunk/tests/data/invalid-character.error-message	(revision 47)
+++ /pyyaml/trunk/tests/data/invalid-character.error-message	(revision 47)
@@ -0,0 +1,18 @@
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+Control character ('\x0'):   <--
+-------------------------------------------------------------------------------------------------------------------------------
Index: /pyyaml/trunk/tests/data/spec-02-12.tokens
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-12.tokens	(revision 41)
+++ /pyyaml/trunk/tests/data/spec-02-12.tokens	(revision 41)
@@ -0,0 +1,6 @@
+---
+[[
+, {{ ? _ : _ ? _ : _ ]}
+, {{ ? _ : _ ? _ : _ ]}
+, {{ ? _ : _ ? _ : _ ]}
+]}
Index: /pyyaml/trunk/tests/data/construct-timestamp.data
===================================================================
--- /pyyaml/trunk/tests/data/construct-timestamp.data	(revision 58)
+++ /pyyaml/trunk/tests/data/construct-timestamp.data	(revision 58)
@@ -0,0 +1,5 @@
+canonical:        2001-12-15T02:59:43.1Z
+valid iso8601:    2001-12-14t21:59:43.10-05:00
+space separated:  2001-12-14 21:59:43.10 -5
+no time zone (Z): 2001-12-15 2:59:43.10
+date (00:00:00Z): 2002-12-14
Index: /pyyaml/trunk/tests/data/spec-10-04.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-10-04.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-10-04.data	(revision 38)
@@ -0,0 +1,4 @@
+block:
+- one
+-
+ - two
Index: /pyyaml/trunk/tests/data/invalid-character.stream-error
===================================================================
--- /pyyaml/trunk/tests/data/invalid-character.stream-error	(revision 45)
+++ /pyyaml/trunk/tests/data/invalid-character.stream-error	(revision 45)
@@ -0,0 +1,18 @@
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+-------------------------------------------------------------------------------------------------------------------------------
+Control character ('\x0'):   <--
+-------------------------------------------------------------------------------------------------------------------------------
Index: /pyyaml/trunk/tests/data/spec-07-01.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-01.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-01.data	(revision 38)
@@ -0,0 +1,3 @@
+%FOO  bar baz # Should be ignored
+               # with a warning.
+--- "foo"
Index: /pyyaml/trunk/tests/data/expected-mapping.error-message
===================================================================
--- /pyyaml/trunk/tests/data/expected-mapping.error-message	(revision 58)
+++ /pyyaml/trunk/tests/data/expected-mapping.error-message	(revision 58)
@@ -0,0 +1,1 @@
+--- !!map [not, a, map]
Index: /pyyaml/trunk/tests/data/spec-05-13.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-05-13.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-05-13.data	(revision 38)
@@ -0,0 +1,3 @@
+  "Text containing   
+  both space and	
+  	tab	characters"
Index: /pyyaml/trunk/tests/data/spec-09-01.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-09-01.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-09-01.data	(revision 38)
@@ -0,0 +1,6 @@
+"simple key" : {
+  "also simple" : value,
+  ? "not a
+  simple key" : "any
+  value"
+}
Index: /pyyaml/trunk/tests/data/spec-02-09.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-02-09.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-02-09.data	(revision 38)
@@ -0,0 +1,8 @@
+---
+hr: # 1998 hr ranking
+  - Mark McGwire
+  - Sammy Sosa
+rbi:
+  # 1998 rbi ranking
+  - Sammy Sosa
+  - Ken Griffey
Index: /pyyaml/trunk/tests/data/spec-07-13.data
===================================================================
--- /pyyaml/trunk/tests/data/spec-07-13.data	(revision 38)
+++ /pyyaml/trunk/tests/data/spec-07-13.data	(revision 38)
@@ -0,0 +1,9 @@
+! "First document"
+---
+!foo "No directives"
+%TAG ! !foo
+---
+!bar "With directives"
+%YAML 1.1
+---
+!baz "Reset settings"
Index: /pyyaml/trunk/tests/test_tokens.py
===================================================================
--- /pyyaml/trunk/tests/test_tokens.py	(revision 51)
+++ /pyyaml/trunk/tests/test_tokens.py	(revision 51)
@@ -0,0 +1,90 @@
+
+import test_appliance
+
+from yaml.reader import *
+from yaml.tokens import *
+from yaml.scanner import *
+
+class TestTokens(test_appliance.TestAppliance):
+
+    # Tokens mnemonic:
+    # directive:            %
+    # document_start:       ---
+    # document_end:         ...
+    # alias:                *
+    # anchor:               &
+    # tag:                  !
+    # scalar                _
+    # block_sequence_start: [[
+    # block_mapping_start:  {{
+    # block_end:            ]}
+    # flow_sequence_start:  [
+    # flow_sequence_end:    ]
+    # flow_mapping_start:   {
+    # flow_mapping_end:     }
+    # entry:                ,
+    # key:                  ?
+    # value:                :
+
+    replaces = {
+        DirectiveToken: '%',
+        DocumentStartToken: '---',
+        DocumentEndToken: '...',
+        AliasToken: '*',
+        AnchorToken: '&',
+        TagToken: '!',
+        ScalarToken: '_',
+        BlockSequenceStartToken: '[[',
+        BlockMappingStartToken: '{{',
+        BlockEndToken: ']}',
+        FlowSequenceStartToken: '[',
+        FlowSequenceEndToken: ']',
+        FlowMappingStartToken: '{',
+        FlowMappingEndToken: '}',
+        BlockEntryToken: ',',
+        FlowEntryToken: ',',
+        KeyToken: '?',
+        ValueToken: ':',
+    }
+
+    def _testTokens(self, test_name, data_filename, tokens_filename):
+        tokens1 = None
+        tokens2 = file(tokens_filename, 'rb').read().split()
+        try:
+            scanner = Scanner(Reader(file(data_filename, 'rb')))
+            tokens1 = []
+            for token in scanner:
+                if not isinstance(token, 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
+            raise
+
+TestTokens.add_tests('testTokens', '.data', '.tokens')
+
+class TestScanner(test_appliance.TestAppliance):
+
+    def _testScanner(self, test_name, data_filename, canonical_filename):
+        for filename in [canonical_filename, data_filename]:
+            tokens = None
+            try:
+                scanner = Scanner(Reader(file(filename, 'rb')))
+                tokens = []
+                for token in scanner:
+                    if not isinstance(token, StreamEndToken):
+                        tokens.append(token.__class__.__name__)
+            except:
+                print
+                print "DATA:"
+                print file(data_filename, 'rb').read()
+                print "TOKENS:", tokens
+                raise
+
+TestScanner.add_tests('testScanner', '.data', '.canonical')
+
Index: /pyyaml/trunk/tests/test_constructor.py
===================================================================
--- /pyyaml/trunk/tests/test_constructor.py	(revision 59)
+++ /pyyaml/trunk/tests/test_constructor.py	(revision 59)
@@ -0,0 +1,90 @@
+
+import test_appliance
+try:
+    import datetime
+except ImportError:
+    pass
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+from yaml import *
+
+class MyConstructor(Constructor):
+    pass
+
+class MyTestClass1:
+
+    def __init__(self, x, y=0, z=0):
+        self.x = x
+        self.y = y
+        self.z = z
+
+    def __eq__(self, other):
+        return self.__class__, self.__dict__ == other.__class__, other.__dict__
+
+def construct1(constructor, node):
+    mapping = constructor.construct_mapping(node)
+    return MyTestClass1(**mapping)
+
+MyConstructor.add_constructor("!tag1", construct1)
+
+class MyTestClass2(MyTestClass1, YAMLObject):
+
+    yaml_constructor = MyConstructor
+    yaml_tag = "!tag2"
+
+    def from_yaml(cls, constructor, node):
+        x = constructor.construct_yaml_int(node)
+        return cls(x=x)
+    from_yaml = classmethod(from_yaml)
+
+class MyTestClass3(MyTestClass2):
+
+    yaml_tag = "!tag3"
+
+    def from_yaml(cls, constructor, node):
+        mapping = constructor.construct_mapping(node)
+        if '=' in mapping:
+            x = mapping['=']
+            del mapping['=']
+            mapping['x'] = x
+        return cls(**mapping)
+    from_yaml = classmethod(from_yaml)
+
+class TestTypes(test_appliance.TestAppliance):
+
+    def _testTypes(self, test_name, data_filename, code_filename):
+        natives1 = None
+        natives2 = None
+        try:
+            constructor1 = MyConstructor(Resolver(Composer(Parser(Scanner(Reader(file(data_filename, 'rb')))))))
+            natives1 = list(iter(constructor1))
+            if len(natives1) == 1:
+                natives1 = natives1[0]
+            natives2 = eval(file(code_filename, 'rb').read())
+            try:
+                self.failUnlessEqual(natives1, natives2)
+            except AssertionError:
+                if isinstance(natives1, dict):
+                    natives1 = natives1.items()
+                    natives1.sort()
+                    natives1 = repr(natives1)
+                    natives2 = natives2.items()
+                    natives2.sort()
+                    natives2 = repr(natives2)
+                if natives1 != natives2:
+                    raise
+        except:
+            print
+            print "DATA:"
+            print file(data_filename, 'rb').read()
+            print "CODE:"
+            print file(code_filename, 'rb').read()
+            print "NATIVES1:", natives1
+            print "NATIVES2:", natives2
+            raise
+
+TestTypes.add_tests('testTypes', '.data', '.code')
+
Index: /pyyaml/trunk/tests/test_canonical.py
===================================================================
--- /pyyaml/trunk/tests/test_canonical.py	(revision 51)
+++ /pyyaml/trunk/tests/test_canonical.py	(revision 51)
@@ -0,0 +1,22 @@
+
+import test_appliance
+
+class TestCanonicalAppliance(test_appliance.TestAppliance):
+
+    def _testCanonicalScanner(self, test_name, canonical_filename):
+        data = file(canonical_filename, 'rb').read()
+        scanner = test_appliance.CanonicalScanner(data)
+        tokens = scanner.scan()
+        #for token in tokens:
+        #    print token
+
+    def _testCanonicalParser(self, test_name, canonical_filename):
+        data = file(canonical_filename, 'rb').read()
+        parser = test_appliance.CanonicalParser(data)
+        events = parser.parse()
+        #for event in events:
+        #    print event
+
+TestCanonicalAppliance.add_tests('testCanonicalScanner', '.canonical')
+TestCanonicalAppliance.add_tests('testCanonicalParser', '.canonical')
+
Index: /pyyaml/trunk/tests/test_detector.py
===================================================================
--- /pyyaml/trunk/tests/test_detector.py	(revision 55)
+++ /pyyaml/trunk/tests/test_detector.py	(revision 55)
@@ -0,0 +1,36 @@
+
+import test_appliance
+
+from yaml.reader import Reader
+from yaml.scanner import Scanner
+from yaml.parser import *
+from yaml.composer import *
+from yaml.resolver import *
+from yaml.nodes import *
+
+class TestDetector(test_appliance.TestAppliance):
+
+    def _testDetector(self, test_name, data_filename, detect_filename):
+        node = None
+        correct_tag = None
+        try:
+            correct_tag = file(detect_filename, 'rb').read().strip()
+            resolver = Resolver(Composer(Parser(Scanner(Reader(file(data_filename, 'rb'))))))
+            node = list(iter(resolver))[0]
+            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
+            raise
+
+TestDetector.add_tests('testDetector', '.data', '.detect')
+
+
Index: /pyyaml/trunk/tests/test_syck.py
===================================================================
--- /pyyaml/trunk/tests/test_syck.py	(revision 52)
+++ /pyyaml/trunk/tests/test_syck.py	(revision 52)
@@ -0,0 +1,30 @@
+
+import test_appliance
+
+class TestSyck(test_appliance.TestAppliance):
+
+    def _testSyckOnTokenTests(self, test_name, data_filename, tokens_filename):
+        try:
+            syck.parse(file(data_filename, 'rb'))
+        except:
+            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()
+            raise
+
+try:
+    import syck
+    #TestSyck.add_tests('testSyckOnTokenTests', '.data', '.tokens')
+    #TestSyck.add_tests('testSyckOnCanonicalTests', '.data', '.canonical')
+except ImportError:
+    pass
+
Index: /pyyaml/trunk/tests/test_appliance.py
===================================================================
--- /pyyaml/trunk/tests/test_appliance.py	(revision 54)
+++ /pyyaml/trunk/tests/test_appliance.py	(revision 54)
@@ -0,0 +1,312 @@
+
+import unittest, os
+
+from yaml.tokens import *
+from yaml.events import *
+
+class TestAppliance(unittest.TestCase):
+
+    DATA = 'tests/data'
+
+    all_tests = {}
+    for filename in os.listdir(DATA):
+        if os.path.isfile(os.path.join(DATA, filename)):
+            root, ext = os.path.splitext(filename)
+            all_tests.setdefault(root, []).append(ext)
+
+    def add_tests(cls, method_name, *extensions):
+        for test in cls.all_tests:
+            available_extensions = cls.all_tests[test]
+            for ext in extensions:
+                if ext not in available_extensions:
+                    break
+            else:
+                filenames = [os.path.join(cls.DATA, test+ext) for ext in extensions]
+                def test_method(self, test=test, filenames=filenames):
+                    getattr(self, '_'+method_name)(test, *filenames)
+                test = test.replace('-', '_')
+                try:
+                    test_method.__name__ = '%s_%s' % (method_name, test)
+                except TypeError:
+                    import new
+                    test_method = new.function(test_method.func_code, test_method.func_globals,
+                            '%s_%s' % (method_name, test), test_method.func_defaults,
+                            test_method.func_closure)
+                setattr(cls, test_method.__name__, test_method)
+    add_tests = classmethod(add_tests)
+
+class Error(Exception):
+    pass
+
+class CanonicalScanner:
+
+    def __init__(self, data):
+        self.data = unicode(data, 'utf-8')+u'\0'
+        self.index = 0
+
+    def scan(self):
+        #print self.data[self.index:]
+        tokens = []
+        while True:
+            self.find_token()
+            ch = self.data[self.index]
+            if ch == u'\0':
+                tokens.append(StreamEndToken(None, None))
+                break
+            elif ch == u'%':
+                tokens.append(self.scan_directive())
+            elif ch == u'-' and self.data[self.index:self.index+3] == u'---':
+                self.index += 3
+                tokens.append(DocumentStartToken(None, None))
+            elif ch == u'[':
+                self.index += 1
+                tokens.append(FlowSequenceStartToken(None, None))
+            elif ch == u'{':
+                self.index += 1
+                tokens.append(FlowMappingStartToken(None, None))
+            elif ch == u']':
+                self.index += 1
+                tokens.append(FlowSequenceEndToken(None, None))
+            elif ch == u'}':
+                self.index += 1
+                tokens.append(FlowMappingEndToken(None, None))
+            elif ch == u'?':
+                self.index += 1
+                tokens.append(KeyToken(None, None))
+            elif ch == u':':
+                self.index += 1
+                tokens.append(ValueToken(None, None))
+            elif ch == u',':
+                self.index += 1
+                tokens.append(FlowEntryToken(None, None))
+            elif ch == u'*' or ch == u'&':
+                tokens.append(self.scan_alias())
+            elif ch == u'!':
+                tokens.append(self.scan_tag())
+            elif ch == u'"':
+                tokens.append(self.scan_scalar())
+            else:
+                raise Error("invalid token")
+        return tokens
+
+    DIRECTIVE = u'%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.index += len(self.DIRECTIVE)
+            return DirectiveToken('YAML', (1, 1), None, None)
+
+    def scan_alias(self):
+        if self.data[self.index] == u'*':
+            TokenClass = AliasToken
+        else:
+            TokenClass = AnchorToken
+        self.index += 1
+        start = self.index
+        while self.data[self.index] not in u', \n\0':
+            self.index += 1
+        value = self.data[start:self.index]
+        return TokenClass(value, None, None)
+
+    def scan_tag(self):
+        self.index += 1
+        start = self.index
+        while self.data[self.index] not in u' \n\0':
+            self.index += 1
+        value = self.data[start:self.index]
+        if value[0] == u'!':
+            value = 'tag:yaml.org,2002:'+value[1:]
+        elif value[0] == u'<' and value[-1] == u'>':
+            value = value[1:-1]
+        else:
+            value = u'!'+value
+        return TagToken(value, None, None)
+
+    QUOTE_CODES = {
+        'x': 2,
+        'u': 4,
+        'U': 8,
+    }
+
+    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',
+
+    }
+
+    def scan_scalar(self):
+        self.index += 1
+        chunks = []
+        start = self.index
+        ignore_spaces = False
+        while self.data[self.index] != u'"':
+            if self.data[self.index] == u'\\':
+                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':
+                    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))
+                    self.index += length
+                else:
+                    chunks.append(self.QUOTE_REPLACES[ch])
+                start = self.index
+            elif self.data[self.index] == u'\n':
+                chunks.append(self.data[start:self.index])
+                chunks.append(u' ')
+                self.index += 1
+                start = self.index
+                ignore_spaces = True
+            elif ignore_spaces and self.data[self.index] == u' ':
+                self.index += 1
+                start = self.index
+            else:
+                ignore_spaces = False
+                self.index += 1
+        chunks.append(self.data[start:self.index])
+        self.index += 1
+        return ScalarToken(u''.join(chunks), False, None, None)
+
+    def find_token(self):
+        found = False
+        while not found:
+            while self.data[self.index] in u' \t':
+                self.index += 1
+            if self.data[self.index] == u'#':
+                while self.data[self.index] != u'\n':
+                    self.index += 1
+            if self.data[self.index] == u'\n':
+                self.index += 1
+            else:
+                found = True
+
+class CanonicalParser:
+
+    def __init__(self, data):
+        self.scanner = CanonicalScanner(data)
+        self.events = []
+
+    # stream: document* END
+    def parse_stream(self):
+        while not self.test_token(StreamEndToken):
+            if self.test_token(DirectiveToken, DocumentStartToken):
+                self.parse_document()
+            else:
+                raise Error("document is expected, got "+repr(self.tokens[self.index]))
+        self.events.append(StreamEndEvent(None, None))
+
+    # document: DIRECTIVE? DOCUMENT-START node
+    def parse_document(self):
+        node = None
+        if self.test_token(DirectiveToken):
+            self.consume_token(DirectiveToken)
+        self.consume_token(DocumentStartToken)
+        self.parse_node()
+
+    # node: ALIAS | ANCHOR? TAG? (SCALAR|sequence|mapping)
+    def parse_node(self):
+        if self.test_token(AliasToken):
+            self.events.append(AliasEvent(self.get_value(), None, None))
+        else:
+            anchor = None
+            if self.test_token(AnchorToken):
+                anchor = self.get_value()
+            tag = u'!'
+            if self.test_token(TagToken):
+                tag = self.get_value()
+            if self.test_token(ScalarToken):
+                self.events.append(ScalarEvent(anchor, tag, self.get_value(), None, None))
+            elif self.test_token(FlowSequenceStartToken):
+                self.events.append(SequenceEvent(anchor, tag, None, None))
+                self.parse_sequence()
+            elif self.test_token(FlowMappingStartToken):
+                self.events.append(MappingEvent(anchor, tag, None, None))
+                self.parse_mapping()
+            else:
+                raise Error("SCALAR, '[', or '{' is expected, got "+repr(self.tokens[self.index]))
+
+    # sequence: SEQUENCE-START (node (ENTRY node)*)? ENTRY? SEQUENCE-END
+    def parse_sequence(self):
+        self.consume_token(FlowSequenceStartToken)
+        if not self.test_token(FlowSequenceEndToken):
+            self.parse_node()
+            while not self.test_token(FlowSequenceEndToken):
+                self.consume_token(FlowEntryToken)
+                if not self.test_token(FlowSequenceEndToken):
+                    self.parse_node()
+        self.consume_token(FlowSequenceEndToken)
+        self.events.append(CollectionEndEvent(None, None))
+
+    # mapping: MAPPING-START (map_entry (ENTRY map_entry)*)? ENTRY? MAPPING-END
+    def parse_mapping(self):
+        self.consume_token(FlowMappingStartToken)
+        if not self.test_token(FlowMappingEndToken):
+            self.parse_map_entry()
+            while not self.test_token(FlowMappingEndToken):
+                self.consume_token(FlowEntryToken)
+                if not self.test_token(FlowMappingEndToken):
+                    self.parse_map_entry()
+        self.consume_token(FlowMappingEndToken)
+        self.events.append(CollectionEndEvent(None, None))
+
+    # map_entry: KEY node VALUE node
+    def parse_map_entry(self):
+        self.consume_token(KeyToken)
+        self.parse_node()
+        self.consume_token(ValueToken)
+        self.parse_node()
+
+    def test_token(self, *choices):
+        for choice in choices:
+            if isinstance(self.tokens[self.index], choice):
+                return True
+        return False
+
+    def consume_token(self, cls):
+        if not isinstance(self.tokens[self.index], cls):
+            raise Error("unexpected token "+repr(self.tokens[self.index]))
+        self.index += 1
+
+    def get_value(self):
+        value = self.tokens[self.index].value
+        self.index += 1
+        return value
+
+    def parse(self):
+        self.tokens = self.scanner.scan()
+        self.index = 0
+        self.parse_stream()
+        return self.events
+
+    def get(self):
+        return self.events.pop(0)
+
+    def check(self, *choices):
+        for choice in choices:
+            if isinstance(self.events[0], choice):
+                return True
+        return False
+
+    def peek(self):
+        return self.events[0]
+
Index: /pyyaml/trunk/tests/test_errors.py
===================================================================
--- /pyyaml/trunk/tests/test_errors.py	(revision 59)
+++ /pyyaml/trunk/tests/test_errors.py	(revision 59)
@@ -0,0 +1,55 @@
+
+import test_appliance
+
+from yaml import *
+
+class TestErrors(test_appliance.TestAppliance):
+
+    def _testErrors(self, test_name, invalid_filename):
+        #self._load(invalid_filename)
+        self.failUnlessRaises(YAMLError, lambda: self._load(invalid_filename))
+
+    def _testStringErrors(self, test_name, invalid_filename):
+        #self._load_string(invalid_filename)
+        self.failUnlessRaises(YAMLError, lambda: self._load_string(invalid_filename))
+
+    def _load(self, filename):
+        try:
+            reader = Reader(file(filename, 'rb'))
+            scanner = Scanner(reader)
+            parser = Parser(scanner)
+            composer = Composer(parser)
+            resolver = Resolver(composer)
+            constructor = Constructor(resolver)
+            return list(constructor)
+        except YAMLError, exc:
+        #except ScannerError, exc:
+        #except ParserError, exc:
+        #except ComposerError, exc:
+        #except ConstructorError, exc:
+            #print '.'*70
+            #print "%s:" % exc.__class__.__name__, exc
+            raise
+
+    def _load_string(self, filename):
+        try:
+            reader = Reader(file(filename, 'rb').read())
+            scanner = Scanner(reader)
+            parser = Parser(scanner)
+            composer = Composer(parser)
+            resolver = Resolver(composer)
+            constructor = Constructor(resolver)
+            return list(constructor)
+        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('testErrors', '.error-message')
+TestErrors.add_tests('testStringErrors', '.error-message')
+
Index: /pyyaml/trunk/tests/test_build.py
===================================================================
--- /pyyaml/trunk/tests/test_build.py	(revision 39)
+++ /pyyaml/trunk/tests/test_build.py	(revision 39)
@@ -0,0 +1,12 @@
+
+def main():
+    import sys, os, distutils.util
+    #build_lib = os.path.join('build', 'lib.%s-%s' % (distutils.util.get_platform(), sys.version[0:3]))
+    build_lib = 'build/lib'
+    sys.path.insert(0, build_lib)
+    import test_yaml
+    test_yaml.main('test_yaml')
+
+if __name__ == '__main__':
+    main()
+
Index: /pyyaml/trunk/tests/test_structure.py
===================================================================
--- /pyyaml/trunk/tests/test_structure.py	(revision 57)
+++ /pyyaml/trunk/tests/test_structure.py	(revision 57)
@@ -0,0 +1,218 @@
+
+import test_appliance
+
+from yaml import *
+
+class TestStructure(test_appliance.TestAppliance):
+
+    def _testStructure(self, test_name, data_filename, structure_filename):
+        node1 = None
+        node2 = eval(file(structure_filename, 'rb').read())
+        try:
+            parser = Parser(Scanner(Reader(file(data_filename, 'rb'))))
+            node1 = []
+            while not parser.check(StreamEndEvent):
+                node1.append(self._convert(parser))
+            parser.get()
+            if len(node1) == 1:
+                node1 = node1[0]
+            self.failUnlessEqual(node1, node2)
+        except:
+            print
+            print "DATA:"
+            print file(data_filename, 'rb').read()
+            print "NODE1:", node1
+            print "NODE2:", node2
+            raise
+
+    def _convert(self, parser):
+        if parser.check(ScalarEvent):
+            event = parser.get()
+            if event.tag or event.anchor or event.value:
+                return True
+            else:
+                return None
+        elif parser.check(SequenceEvent):
+            parser.get()
+            sequence = []
+            while not parser.check(CollectionEndEvent):
+                sequence.append(self._convert(parser))
+            parser.get()
+            return sequence
+        elif parser.check(MappingEvent):
+            parser.get()
+            mapping = []
+            while not parser.check(CollectionEndEvent):
+                key = self._convert(parser)
+                value = self._convert(parser)
+                mapping.append((key, value))
+            parser.get()
+            return mapping
+        elif parser.check(AliasEvent):
+            parser.get()
+            return '*'
+        else:
+            parser.get()
+            return '?'
+
+TestStructure.add_tests('testStructure', '.data', '.structure')
+
+class TestParser(test_appliance.TestAppliance):
+
+    def _testParser(self, test_name, data_filename, canonical_filename):
+        events1 = None
+        events2 = None
+        try:
+            parser = Parser(Scanner(Reader(file(data_filename, 'rb'))))
+            events1 = list(iter(parser))
+            canonical = test_appliance.CanonicalParser(file(canonical_filename, 'rb').read())
+            events2 = canonical.parse()
+            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
+            raise
+
+    def _compare(self, events1, events2):
+        self.failUnlessEqual(len(events1), len(events2))
+        for event1, event2 in zip(events1, events2):
+            self.failUnlessEqual(event1.__class__, event2.__class__)
+            if isinstance(event1, AliasEvent):
+                #self.failUnlessEqual(event1.name, event2.name)
+                pass
+            elif isinstance(event1, ScalarEvent):
+                #self.failUnlessEqual(event1.anchor, event2.anchor)
+                #self.failUnlessEqual(event1.tag, event2.tag)
+                self.failUnlessEqual(event1.value, event2.value)
+            if isinstance(event1, CollectionEvent):
+                #self.failUnlessEqual(event1.anchor, event2.anchor)
+                #self.failUnlessEqual(event1.tag, event2.tag)
+                pass
+
+TestParser.add_tests('testParser', '.data', '.canonical')
+
+class TestResolver(test_appliance.TestAppliance):
+
+    def _testResolver(self, test_name, data_filename, canonical_filename):
+        nodes1 = None
+        nodes2 = None
+        try:
+            resolver1 = Resolver(Composer(Parser(Scanner(Reader(file(data_filename, 'rb'))))))
+            nodes1 = list(iter(resolver1))
+            canonical = test_appliance.CanonicalParser(file(canonical_filename, 'rb').read())
+            canonical.parse()
+            resolver2 = Resolver(Composer(canonical))
+            nodes2 = list(iter(resolver2))
+            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
+            raise
+
+    def _compare(self, node1, node2):
+        self.failUnlessEqual(node1.__class__, node2.__class__)
+        if isinstance(node1, ScalarNode):
+            #self.failUnlessEqual(node1.tag, node2.tag)
+            self.failUnlessEqual(node1.value, node2.value)
+        elif isinstance(node1, SequenceNode):
+            self.failUnlessEqual(len(node1.value), len(node2.value))
+            for item1, item2 in zip(node1.value, node2.value):
+                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)))
+            for (key1, value1), (key2, value2) in zip(items1, items2):
+                self._compare(key1, key2)
+                self._compare(value1, value2)
+
+TestResolver.add_tests('testResolver', '.data', '.canonical')
+
+class MyConstructor(Constructor):
+
+    def construct_sequence(self, node):
+        return tuple(Constructor.construct_sequence(self, node))
+
+    def construct_mapping(self, node):
+        pairs = self.construct_pairs(node)
+        pairs.sort()
+        return pairs
+
+MyConstructor.add_constructor(None, MyConstructor.construct_scalar)
+
+class TestConstructor(test_appliance.TestAppliance):
+
+    def _testConstructor(self, test_name, data_filename, canonical_filename):
+        natives1 = None
+        natives2 = None
+        try:
+            constructor1 = MyConstructor(Resolver(Composer(Parser(Scanner(Reader(file(data_filename, 'rb')))))))
+            natives1 = list(iter(constructor1))
+            canonical = test_appliance.CanonicalParser(file(canonical_filename, 'rb').read())
+            canonical.parse()
+            constructor2 = MyConstructor(Resolver(Composer(canonical)))
+            natives2 = list(iter(constructor2))
+            self.failUnlessEqual(natives1, natives2)
+        except:
+            print
+            print "DATA1:"
+            print file(data_filename, 'rb').read()
+            print "DATA2:"
+            print file(canonical_filename, 'rb').read()
+            print "NATIVES1:", natives1
+            print "NATIVES2:", natives2
+            raise
+
+TestConstructor.add_tests('testConstructor', '.data', '.canonical')
+
+class TestParserOnCanonical(test_appliance.TestAppliance):
+
+    def _testParserOnCanonical(self, test_name, canonical_filename):
+        events1 = None
+        events2 = None
+        try:
+            parser = Parser(Scanner(Reader(file(canonical_filename, 'rb'))))
+            events1 = list(iter(parser))
+            canonical = test_appliance.CanonicalParser(file(canonical_filename, 'rb').read())
+            events2 = canonical.parse()
+            self._compare(events1, events2)
+        except:
+            print
+            print "DATA:"
+            print file(canonical_filename, 'rb').read()
+            print "EVENTS1:", events1
+            print "EVENTS2:", events2
+            raise
+
+    def _compare(self, events1, events2):
+        self.failUnlessEqual(len(events1), len(events2))
+        for event1, event2 in zip(events1, events2):
+            self.failUnlessEqual(event1.__class__, event2.__class__)
+            if isinstance(event1, AliasEvent):
+                self.failUnlessEqual(event1.anchor, event2.anchor)
+            elif isinstance(event1, ScalarEvent):
+                self.failUnlessEqual(event1.anchor, event2.anchor)
+                self.failUnlessEqual(event1.tag, event2.tag)
+                self.failUnlessEqual(event1.value, event2.value)
+            if isinstance(event1, CollectionEvent):
+                self.failUnlessEqual(event1.anchor, event2.anchor)
+                self.failUnlessEqual(event1.tag, event2.tag)
+
+TestParserOnCanonical.add_tests('testParserOnCanonical', '.canonical')
+
Index: /pyyaml/trunk/tests/test_marker.py
===================================================================
--- /pyyaml/trunk/tests/test_marker.py	(revision 47)
+++ /pyyaml/trunk/tests/test_marker.py	(revision 47)
@@ -0,0 +1,34 @@
+
+import test_appliance
+
+from yaml.reader import Marker
+
+class TestMarker(test_appliance.TestAppliance):
+
+    def _testMarkers(self, test_name, markers_filename):
+        inputs = file(markers_filename, 'rb').read().split('---\n')[1:]
+        for input in inputs:
+            index = 0
+            line = 0
+            column = 0
+            while input[index] != '*':
+                if input[index] == '\n':
+                    line += 1
+                    column = 0
+                else:
+                    column += 1
+                index += 1
+            marker = Marker(test_name, line, column, unicode(input), index)
+            snippet = marker.get_snippet(indent=2, max_length=79)
+            #print "INPUT:"
+            #print input
+            #print "SNIPPET:"
+            #print snippet
+            self.failUnless(isinstance(snippet, str))
+            self.failUnlessEqual(snippet.count('\n'), 1)
+            data, pointer = snippet.split('\n')
+            self.failUnless(len(data) < 82)
+            self.failUnlessEqual(data[len(pointer)-1], '*')
+
+TestMarker.add_tests('testMarkers', '.markers')
+
Index: /pyyaml/trunk/lib/yaml/nodes.py
===================================================================
--- /pyyaml/trunk/lib/yaml/nodes.py	(revision 55)
+++ /pyyaml/trunk/lib/yaml/nodes.py	(revision 55)
@@ -0,0 +1,35 @@
+
+class Node:
+    def __init__(self, tag, value, start_marker, end_marker):
+        self.tag = tag
+        self.value = value
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+    def __repr__(self):
+        value = self.value
+        if isinstance(value, list):
+            if len(value) == 0:
+                value = '<empty>'
+            elif len(value) == 1:
+                value = '<1 item>'
+            else:
+                value = '<%d items>' % len(value)
+        else:
+            if len(value) > 75:
+                value = repr(value[:70]+u' ... ')
+            else:
+                value = repr(value)
+        return '%s(tag=%r, value=%s)' % (self.__class__.__name__, self.tag, value)
+
+class ScalarNode(Node):
+    id = 'scalar'
+
+class CollectionNode(Node):
+    pass
+
+class SequenceNode(CollectionNode):
+    id = 'sequence'
+
+class MappingNode(CollectionNode):
+    id = 'mapping'
+
Index: /pyyaml/trunk/lib/yaml/error.py
===================================================================
--- /pyyaml/trunk/lib/yaml/error.py	(revision 53)
+++ /pyyaml/trunk/lib/yaml/error.py	(revision 53)
@@ -0,0 +1,79 @@
+
+__all__ = ['Marker', 'YAMLError', 'MarkedYAMLError']
+
+class Marker:
+
+    def __init__(self, name, line, column, buffer, pointer):
+        self.name = name
+        self.line = line
+        self.column = column
+        self.buffer = buffer
+        self.pointer = pointer
+
+    def get_snippet(self, indent=4, max_length=75):
+        if self.buffer is None:
+            return None
+        head = ''
+        start = self.pointer
+        while start > 0 and self.buffer[start-1] not in u'\0\r\n\x85\u2028\u2029':
+            start -= 1
+            if self.pointer-start > max_length/2-1:
+                head = ' ... '
+                start += 5
+                break
+        tail = ''
+        end = self.pointer
+        while end < len(self.buffer) and self.buffer[end] not in u'\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')
+        return ' '*indent + head + snippet + tail + '\n'  \
+                + ' '*(indent+self.pointer-start+len(head)) + '^'
+
+    def __str__(self):
+        snippet = self.get_snippet()
+        where = "  in \"%s\", line %d, column %d"   \
+                % (self.name, self.line+1, self.column+1)
+        if snippet is not None:
+            where += ":\n"+snippet
+        return where
+
+class YAMLError(Exception):
+    pass
+
+class MarkedYAMLError(YAMLError):
+
+    def __init__(self, context=None, context_marker=None,
+            problem=None, problem_marker=None):
+        self.context = context
+        self.context_marker = context_marker
+        self.problem = problem
+        self.problem_marker = problem_marker
+
+    def __str__(self):
+        lines = []
+        #for (place, marker) in [(self.context, self.context_marker),
+        #                        (self.problem, self.problem_marker)]:
+        #    if place is not None:
+        #        lines.append(place)
+        #        if marker is not None:
+        #            lines.append(str(marker))
+        if self.context is not None:
+            lines.append(self.context)
+        if self.context_marker is not None  \
+            and (self.problem is None or self.problem_marker is None
+                    or self.context_marker.name != self.problem_marker.name
+                    or self.context_marker.line != self.problem_marker.line
+                    or self.context_marker.column != self.problem_marker.column):
+            lines.append(str(self.context_marker))
+        if self.problem is not None:
+            lines.append(self.problem)
+        if self.problem_marker is not None:
+            lines.append(str(self.problem_marker))
+        return '\n'.join(lines)
+
+
+
Index: /pyyaml/trunk/lib/yaml/scanner.py
===================================================================
--- /pyyaml/trunk/lib/yaml/scanner.py	(revision 60)
+++ /pyyaml/trunk/lib/yaml/scanner.py	(revision 60)
@@ -0,0 +1,1415 @@
+
+# Scanner produces tokens of the following types:
+# DIRECTIVE(name, value)
+# DOCUMENT-START
+# DOCUMENT-END
+# STREAM-END
+# BLOCK-SEQUENCE-START
+# BLOCK-MAPPING-START
+# BLOCK-END
+# FLOW-SEQUENCE-START
+# FLOW-MAPPING-START
+# FLOW-SEQUENCE-END
+# FLOW-MAPPING-END
+# BLOCK-ENTRY
+# FLOW-ENTRY
+# KEY
+# VALUE
+# ALIAS(value)
+# ANCHOR(value)
+# TAG(value)
+# SCALAR(value, plain)
+#
+# Read comments in the Scanner code for more details.
+#
+
+__all__ = ['Scanner', 'ScannerError']
+
+from error import MarkedYAMLError
+from tokens import *
+
+class ScannerError(MarkedYAMLError):
+    pass
+
+class SimpleKey:
+    # See below simple keys treatment.
+
+    def __init__(self, token_number, required, index, line, column, marker):
+        self.token_number = token_number
+        self.required = required
+        self.index = index
+        self.line = line
+        self.column = column
+        self.marker = marker
+
+class Scanner:
+
+
+    def __init__(self, reader):
+        """Initialize the scanner."""
+        # The input stream. The Reader class do the dirty work of checking for
+        # BOM and converting the input data to Unicode. It also adds NUL to
+        # the end.
+        #
+        # Reader supports the following methods
+        #   self.reader.peek(i=0)       # peek the next i-th character
+        #   self.reader.prefix(l=1)     # peek the next l characters
+        #   self.reader.forward(l=1)    # read the next l characters
+                                        # and move the pointer
+        self.reader = reader
+
+        # Had we reached the end of the stream?
+        self.done = False
+
+        # The number of unclosed '{' and '['. `flow_level == 0` means block
+        # context.
+        self.flow_level = 0
+
+        # List of processed tokens that are not yet emitted.
+        self.tokens = []
+
+        # Number of tokens that were emitted through the `get_token` method.
+        self.tokens_taken = 0
+
+        # The current indentation level.
+        self.indent = -1
+
+        # Past indentation levels.
+        self.indents = []
+
+        # Variables related to simple keys treatment.
+
+        # A simple key is a key that is not denoted by the '?' indicator.
+        # Example of simple keys:
+        #   ---
+        #   block simple key: value
+        #   ? not a simple key:
+        #   : { flow simple key: value }
+        # We emit the KEY token before all keys, so when we find a potential
+        # simple key, we try to locate the corresponding ':' indicator.
+        # Simple keys should be limited to a single line and 1024 characters.
+
+        # Can a simple key start at the current position? A simple key may
+        # start:
+        # - at the beginning of the line, not counting indentation spaces
+        #       (in block context),
+        # - after '{', '[', ',' (in the flow context),
+        # - after '?', ':', '-' (in the block context).
+        # In the block context, this flag also signifies if a block collection
+        # may start at the current position.
+        self.allow_simple_key = True
+
+        # Keep track of possible simple keys. This is a dictionary. The key
+        # is `flow_level`; there can be no more that one possible simple key
+        # for each level. The value is a SimpleKey record:
+        #   (token_number, required, index, line, column, marker)
+        # A simple key may start with ALIAS, ANCHOR, TAG, SCALAR(flow),
+        # '[', or '{' tokens.
+        self.possible_simple_keys = {}
+
+    # Public methods.
+
+    def check(self, *choices):
+        # Check if the next token is one of the given types.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        if self.tokens:
+            for choice in choices:
+                if isinstance(self.tokens[0], choice):
+                    return True
+        return False
+
+    def peek(self):
+        # Return the next token, but do not delete if from the queue.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        if self.tokens:
+            return self.tokens[0]
+
+    def get(self):
+        # Return the next token.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        if self.tokens:
+            self.tokens_taken += 1
+            return self.tokens.pop(0)
+
+    def __iter__(self):
+        # Iterator protocol.
+        while self.need_more_tokens():
+            self.fetch_more_tokens()
+        while self.tokens:
+            self.tokens_taken += 1
+            yield self.tokens.pop(0)
+            while self.need_more_tokens():
+                self.fetch_more_tokens()
+
+    # Private methods.
+
+    def need_more_tokens(self):
+        if self.done:
+            return False
+        if not self.tokens:
+            return True
+        # The current token may be a potential simple key, so we
+        # need to look further.
+        self.stale_possible_simple_keys()
+        if self.next_possible_simple_key() == self.tokens_taken:
+            return True
+
+    def fetch_more_tokens(self):
+
+        # Eat whitespaces and comments until we reach the next token.
+        self.scan_to_next_token()
+
+        # Remove obsolete possible simple keys.
+        self.stale_possible_simple_keys()
+
+        # Compare the current indentation and column. It may add some tokens
+        # and decrease the current indentation level.
+        self.unwind_indent(self.reader.column)
+
+        # Peek the next character.
+        ch = self.reader.peek()
+
+        # Is it the end of stream?
+        if ch == u'\0':
+            return self.fetch_stream_end()
+
+        # Is it a directive?
+        if ch == u'%' and self.check_directive():
+            return self.fetch_directive()
+
+        # Is it the document start?
+        if ch == u'-' and self.check_document_start():
+            return self.fetch_document_start()
+
+        # Is it the document end?
+        if ch == u'.' and self.check_document_end():
+            return self.fetch_document_end()
+
+        # TODO: support for BOM within a stream.
+        #if ch == u'\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'[':
+            return self.fetch_flow_sequence_start()
+
+        # Is it the flow mapping start indicator?
+        if ch == u'{':
+            return self.fetch_flow_mapping_start()
+
+        # Is it the flow sequence end indicator?
+        if ch == u']':
+            return self.fetch_flow_sequence_end()
+
+        # Is it the flow mapping end indicator?
+        if ch == u'}':
+            return self.fetch_flow_mapping_end()
+
+        # Is it the flow entry indicator?
+        if ch in u',':
+            return self.fetch_flow_entry()
+
+        # Is it the block entry indicator?
+        if ch in u'-' and self.check_block_entry():
+            return self.fetch_block_entry()
+
+        # Is it the key indicator?
+        if ch == u'?' and self.check_key():
+            return self.fetch_key()
+
+        # Is it the value indicator?
+        if ch == u':' and self.check_value():
+            return self.fetch_value()
+
+        # Is it an alias?
+        if ch == u'*':
+            return self.fetch_alias()
+
+        # Is it an anchor?
+        if ch == u'&':
+            return self.fetch_anchor()
+
+        # Is it a tag?
+        if ch == u'!':
+            return self.fetch_tag()
+
+        # Is it a literal scalar?
+        if ch == u'|' and not self.flow_level:
+            return self.fetch_literal()
+
+        # Is it a folded scalar?
+        if ch == u'>' and not self.flow_level:
+            return self.fetch_folded()
+
+        # Is it a single quoted scalar?
+        if ch == u'\'':
+            return self.fetch_single()
+
+        # Is it a double quoted scalar?
+        if ch == u'\"':
+            return self.fetch_double()
+
+        # It must be a plain scalar then.
+        if self.check_plain():
+            return self.fetch_plain()
+
+        # No? It's an error. Let's produce a nice error message.
+        raise ScannerError("while scanning for the next token", None,
+                "found character %r that cannot start any token"
+                % ch.encode('utf-8'), self.reader.get_marker())
+
+    # Simple keys treatment.
+
+    def next_possible_simple_key(self):
+        # Return the number of the nearest possible simple key. Actually we
+        # don't need to loop through the whole dictionary. We may replace it
+        # with the following code:
+        #   if not self.possible_simple_keys:
+        #       return None
+        #   return self.possible_simple_keys[
+        #           min(self.possible_simple_keys.keys())].token_number
+        min_token_number = None
+        for level in self.possible_simple_keys:
+            key = self.possible_simple_keys[level]
+            if min_token_number is None or key.token_number < min_token_number:
+                min_token_number = key.token_number
+        return min_token_number
+
+    def stale_possible_simple_keys(self):
+        # Remove entries that are no longer possible simple keys. According to
+        # the YAML specification, simple keys
+        # - should be limited to a single line,
+        # - 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():
+            key = self.possible_simple_keys[level]
+            if key.line != self.reader.line  \
+                    or self.reader.index-key.index > 1024:
+                if key.required:
+                    raise ScannerError("while scanning a simple key", key.marker,
+                            "could not found expected ':'", self.reader.get_marker())
+                del self.possible_simple_keys[level]
+
+    def save_possible_simple_key(self):
+        # The next token may start a simple key. We check if it's possible
+        # and save its position. This function is called for
+        #   ALIAS, ANCHOR, TAG, SCALAR(flow), '[', and '{'.
+
+        # Check if a simple key is required at the current position.
+        required = not self.flow_level and self.indent == self.reader.column
+
+        # A simple key is required only if it is the first token in the current
+        # line. Therefore it is always allowed.
+        assert self.allow_simple_key or not required
+
+        # The next token might be a simple key. Let's save it's number and
+        # position.
+        if self.allow_simple_key:
+            self.remove_possible_simple_key()
+            token_number = self.tokens_taken+len(self.tokens)
+            index = self.reader.index
+            line = self.reader.line
+            column = self.reader.column
+            marker = self.reader.get_marker()
+            key = SimpleKey(token_number, required,
+                    index, line, column, marker)
+            self.possible_simple_keys[self.flow_level] = key
+
+    def remove_possible_simple_key(self):
+        # Remove the saved possible key position at the current flow level.
+        if self.flow_level in self.possible_simple_keys:
+            key = self.possible_simple_keys[self.flow_level]
+            
+            # I don't think it's possible, but I could be wrong.
+            assert not key.required
+            #if key.required:
+            #    raise ScannerError("while scanning a simple key", key.marker,
+            #            "could not found expected ':'", self.reader.get_marker())
+
+    # Indentation functions.
+
+    def unwind_indent(self, column):
+
+        # In flow context, tokens should respect indentation.
+        # Actually the condition should be `self.indent >= column` according to
+        # the spec. But this condition will prohibit intuitively correct
+        # constructions such as
+        # key : {
+        # }
+        if self.flow_level and self.indent > column:
+            raise ScannerError(None, None,
+                    "invalid intendation or unclosed '[' or '{'",
+                    self.reader.get_marker())
+
+        # In block context, we may need to issue the BLOCK-END tokens.
+        while self.indent > column:
+            marker = self.reader.get_marker()
+            self.indent = self.indents.pop()
+            self.tokens.append(BlockEndToken(marker, marker))
+
+    def add_indent(self, column):
+        # Check if we need to increase indentation.
+        if self.indent < column:
+            self.indents.append(self.indent)
+            self.indent = column
+            return True
+        return False
+
+    # Fetchers.
+
+    def fetch_stream_end(self):
+
+        # Set the current intendation to -1.
+        self.unwind_indent(-1)
+
+        # Reset everything (not really needed).
+        self.allow_simple_key = False
+        self.possible_simple_keys = {}
+
+        # Read the token.
+        marker = self.reader.get_marker()
+        
+        # Add END.
+        self.tokens.append(StreamEndToken(marker, marker))
+
+        # The reader is ended.
+        self.done = True
+
+    def fetch_directive(self):
+        
+        # Set the current intendation to -1.
+        self.unwind_indent(-1)
+
+        # Reset simple keys.
+        self.remove_possible_simple_key()
+        self.allow_simple_key = False
+
+        # Scan and add DIRECTIVE.
+        self.tokens.append(self.scan_directive())
+
+    def fetch_document_start(self):
+        self.fetch_document_indicator(DocumentStartToken)
+
+    def fetch_document_end(self):
+        self.fetch_document_indicator(DocumentEndToken)
+
+    def fetch_document_indicator(self, TokenClass):
+
+        # Set the current intendation to -1.
+        self.unwind_indent(-1)
+
+        # Reset simple keys. Note that there could not be a block collection
+        # after '---'.
+        self.remove_possible_simple_key()
+        self.allow_simple_key = False
+
+        # Add DOCUMENT-START or DOCUMENT-END.
+        start_marker = self.reader.get_marker()
+        self.reader.forward(3)
+        end_marker = self.reader.get_marker()
+        self.tokens.append(TokenClass(start_marker, end_marker))
+
+    def fetch_flow_sequence_start(self):
+        self.fetch_flow_collection_start(FlowSequenceStartToken)
+
+    def fetch_flow_mapping_start(self):
+        self.fetch_flow_collection_start(FlowMappingStartToken)
+
+    def fetch_flow_collection_start(self, TokenClass):
+
+        # '[' and '{' may start a simple key.
+        self.save_possible_simple_key()
+
+        # Increase the flow level.
+        self.flow_level += 1
+
+        # Simple keys are allowed after '[' and '{'.
+        self.allow_simple_key = True
+
+        # Add FLOW-SEQUENCE-START or FLOW-MAPPING-START.
+        start_marker = self.reader.get_marker()
+        self.reader.forward()
+        end_marker = self.reader.get_marker()
+        self.tokens.append(TokenClass(start_marker, end_marker))
+
+    def fetch_flow_sequence_end(self):
+        self.fetch_flow_collection_end(FlowSequenceEndToken)
+
+    def fetch_flow_mapping_end(self):
+        self.fetch_flow_collection_end(FlowMappingEndToken)
+
+    def fetch_flow_collection_end(self, TokenClass):
+
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+
+        # Decrease the flow level.
+        self.flow_level -= 1
+
+        # No simple keys after ']' or '}'.
+        self.allow_simple_key = False
+
+        # Add FLOW-SEQUENCE-END or FLOW-MAPPING-END.
+        start_marker = self.reader.get_marker()
+        self.reader.forward()
+        end_marker = self.reader.get_marker()
+        self.tokens.append(TokenClass(start_marker, end_marker))
+
+    def fetch_flow_entry(self):
+
+        # Simple keys are allowed after ','.
+        self.allow_simple_key = True
+
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+
+        # Add FLOW-ENTRY.
+        start_marker = self.reader.get_marker()
+        self.reader.forward()
+        end_marker = self.reader.get_marker()
+        self.tokens.append(FlowEntryToken(start_marker, end_marker))
+
+    def fetch_block_entry(self):
+
+        # Block context needs additional checks.
+        if not self.flow_level:
+
+            # Are we allowed to start a new entry?
+            if not self.allow_simple_key:
+                raise ScannerError(None, None,
+                        "sequence entries are not allowed here",
+                        self.reader.get_marker())
+
+            # We may need to add BLOCK-SEQUENCE-START.
+            if self.add_indent(self.reader.column):
+                marker = self.reader.get_marker()
+                self.tokens.append(BlockSequenceStartToken(marker, marker))
+
+        # It's an error for the block entry to occur in the flow context,
+        # but we let the parser detect this.
+        else:
+            pass
+
+        # Simple keys are allowed after '-'.
+        self.allow_simple_key = True
+
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+
+        # Add BLOCK-ENTRY.
+        start_marker = self.reader.get_marker()
+        self.reader.forward()
+        end_marker = self.reader.get_marker()
+        self.tokens.append(BlockEntryToken(start_marker, end_marker))
+
+    def fetch_key(self):
+        
+        # Block context needs additional checks.
+        if not self.flow_level:
+
+            # Are we allowed to start a key (not nessesary a simple)?
+            if not self.allow_simple_key:
+                raise ScannerError(None, None,
+                        "mapping keys are not allowed here",
+                        self.reader.get_marker())
+
+            # We may need to add BLOCK-MAPPING-START.
+            if self.add_indent(self.reader.column):
+                marker = self.reader.get_marker()
+                self.tokens.append(BlockMappingStartToken(marker, marker))
+
+        # Simple keys are allowed after '?' in the block context.
+        self.allow_simple_key = not self.flow_level
+
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+
+        # Add KEY.
+        start_marker = self.reader.get_marker()
+        self.reader.forward()
+        end_marker = self.reader.get_marker()
+        self.tokens.append(KeyToken(start_marker, end_marker))
+
+    def fetch_value(self):
+
+        # Do we determine a simple key?
+        if self.flow_level in self.possible_simple_keys:
+
+            # Add KEY.
+            key = self.possible_simple_keys[self.flow_level]
+            del self.possible_simple_keys[self.flow_level]
+            self.tokens.insert(key.token_number-self.tokens_taken,
+                    KeyToken(key.marker, key.marker))
+
+            # If this key starts a new block mapping, we need to add
+            # BLOCK-MAPPING-START.
+            if not self.flow_level:
+                if self.add_indent(key.column):
+                    self.tokens.insert(key.token_number-self.tokens_taken,
+                            BlockMappingStartToken(key.marker, key.marker))
+
+            # There cannot be two simple keys one after another.
+            self.allow_simple_key = False
+
+        # It must be a part of a complex key.
+        else:
+            
+            # Block context needs additional checks.
+            # (Do we really need them? They will be catched by the parser
+            # anyway.)
+            if not self.flow_level:
+
+                # We are allowed to start a complex value if and only if
+                # we can start a simple key.
+                if not self.allow_simple_key:
+                    raise ScannerError(None, None,
+                            "mapping values are not allowed here",
+                            self.reader.get_marker())
+
+            # Simple keys are allowed after ':' in the block context.
+            self.allow_simple_key = not self.flow_level
+
+            # Reset possible simple key on the current level.
+            self.remove_possible_simple_key()
+
+        # Add VALUE.
+        start_marker = self.reader.get_marker()
+        self.reader.forward()
+        end_marker = self.reader.get_marker()
+        self.tokens.append(ValueToken(start_marker, end_marker))
+
+    def fetch_alias(self):
+
+        # ALIAS could be a simple key.
+        self.save_possible_simple_key()
+
+        # No simple keys after ALIAS.
+        self.allow_simple_key = False
+
+        # Scan and add ALIAS.
+        self.tokens.append(self.scan_anchor(AliasToken))
+
+    def fetch_anchor(self):
+
+        # ANCHOR could start a simple key.
+        self.save_possible_simple_key()
+
+        # No simple keys after ANCHOR.
+        self.allow_simple_key = False
+
+        # Scan and add ANCHOR.
+        self.tokens.append(self.scan_anchor(AnchorToken))
+
+    def fetch_tag(self):
+
+        # TAG could start a simple key.
+        self.save_possible_simple_key()
+
+        # No simple keys after TAG.
+        self.allow_simple_key = False
+
+        # Scan and add TAG.
+        self.tokens.append(self.scan_tag())
+
+    def fetch_literal(self):
+        self.fetch_block_scalar(folded=False)
+
+    def fetch_folded(self):
+        self.fetch_block_scalar(folded=True)
+
+    def fetch_block_scalar(self, folded):
+
+        # A simple key may follow a block scalar.
+        self.allow_simple_key = True
+
+        # Reset possible simple key on the current level.
+        self.remove_possible_simple_key()
+
+        # Scan and add SCALAR.
+        self.tokens.append(self.scan_block_scalar(folded))
+
+    def fetch_single(self):
+        self.fetch_flow_scalar(double=False)
+
+    def fetch_double(self):
+        self.fetch_flow_scalar(double=True)
+
+    def fetch_flow_scalar(self, double):
+
+        # A flow scalar could be a simple key.
+        self.save_possible_simple_key()
+
+        # No simple keys after flow scalars.
+        self.allow_simple_key = False
+
+        # Scan and add SCALAR.
+        self.tokens.append(self.scan_flow_scalar(double))
+
+    def fetch_plain(self):
+
+        # A plain scalar could be a simple key.
+        self.save_possible_simple_key()
+
+        # No simple keys after plain scalars. But note that `scan_plain` will
+        # change this flag if the scan is finished at the beginning of the
+        # line.
+        self.allow_simple_key = False
+
+        # Scan and add SCALAR. May change `allow_simple_key`.
+        self.tokens.append(self.scan_plain())
+
+    # Checkers.
+
+    def check_directive(self):
+
+        # DIRECTIVE:        ^ '%' ...
+        # The '%' indicator is already checked.
+        if self.reader.column == 0:
+            return True
+
+    def check_document_start(self):
+
+        # DOCUMENT-START:   ^ '---' (' '|'\n')
+        if self.reader.column == 0:
+            if self.reader.prefix(3) == u'---'  \
+                    and self.reader.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+                return True
+
+    def check_document_end(self):
+
+        # DOCUMENT-END:     ^ '...' (' '|'\n')
+        if self.reader.column == 0:
+            prefix = self.reader.peek(4)
+            if self.reader.prefix(3) == u'...'  \
+                    and self.reader.peek(3) in u'\0 \t\r\n\x85\u2028\u2029':
+                return True
+
+    def check_block_entry(self):
+
+        # BLOCK-ENTRY:      '-' (' '|'\n')
+        return self.reader.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+
+    def check_key(self):
+
+        # KEY(flow context):    '?'
+        if self.flow_level:
+            return True
+
+        # KEY(block context):   '?' (' '|'\n')
+        else:
+            return self.reader.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+
+    def check_value(self):
+
+        # VALUE(flow context):  ':'
+        if self.flow_level:
+            return True
+
+        # VALUE(block context): ':' (' '|'\n')
+        else:
+            return self.reader.peek(1) in u'\0 \t\r\n\x85\u2028\u2029'
+
+    def check_plain(self):
+
+        # A plain scalar may start with any non-space character except:
+        #   '-', '?', ':', ',', '[', ']', '{', '}',
+        #   '#', '&', '*', '!', '|', '>', '\'', '\"',
+        #   '%', '@', '`'.
+        #
+        # It may also start with
+        #   '-', '?', ':'
+        # if it is followed by a non-space character.
+        #
+        # Note that we limit the last rule to the block context (except the
+        # '-' character) because we want the flow context to be space
+        # independent.
+        ch = self.reader.peek()
+        return ch not in u'\0 \t\r\n\x85\u2028\u2029-?:,[]{}#&*!|>\'\"%@`'  \
+                or (self.reader.peek(1) not in u'\0 \t\r\n\x85\u2028\u2029'
+                        and (ch == '-' or (not self.flow_level and ch in u'?:')))
+
+    # Scanners.
+
+    def scan_to_next_token(self):
+        # We ignore spaces, line breaks and comments.
+        # If we find a line break in the block context, we set the flag
+        # `allow_simple_key` on.
+        # The byte order mark is stripped if it's the first character in the
+        # stream. We do not yet support BOM inside the stream as the
+        # specification requires. Any such mark will be considered as a part
+        # of the document.
+        #
+        # TODO: We need to make tab handling rules more sane. A good rule is
+        #   Tabs cannot precede tokens
+        #   BLOCK-SEQUENCE-START, BLOCK-MAPPING-START, BLOCK-END,
+        #   KEY(block), VALUE(block), BLOCK-ENTRY
+        # So the checking code is
+        #   if <TAB>:
+        #       self.allow_simple_keys = False
+        # We also need to add the check for `allow_simple_keys == True` to
+        # `unwind_indent` before issuing BLOCK-END.
+        # Scanners for block, flow, and plain scalars need to be modified.
+
+        if self.reader.index == 0 and self.reader.peek() == u'\uFEFF':
+            self.reader.forward()
+        found = False
+        while not found:
+            while self.reader.peek() == u' ':
+                self.reader.forward()
+            if self.reader.peek() == u'#':
+                while self.reader.peek() not in u'\0\r\n\x85\u2028\u2029':
+                    self.reader.forward()
+            if self.scan_line_break():
+                if not self.flow_level:
+                    self.allow_simple_key = True
+            else:
+                found = True
+
+    def scan_directive(self):
+        # See the specification for details.
+        start_marker = self.reader.get_marker()
+        self.reader.forward()
+        name = self.scan_directive_name(start_marker)
+        value = None
+        if name == u'YAML':
+            value = self.scan_yaml_directive_value(start_marker)
+            end_marker = self.reader.get_marker()
+        elif name == u'TAG':
+            value = self.scan_tag_directive_value(start_marker)
+            end_marker = self.reader.get_marker()
+        else:
+            end_marker = self.reader.get_marker()
+            while self.reader.peek() not in u'\0\r\n\x85\u2028\u2029':
+                self.reader.forward()
+        self.scan_directive_ignored_line(start_marker)
+        return DirectiveToken(name, value, start_marker, end_marker)
+
+    def scan_directive_name(self, start_marker):
+        # See the specification for details.
+        length = 0
+        ch = self.reader.peek(length)
+        while u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'  \
+                or ch in u'-_':
+            length += 1
+            ch = self.reader.peek(length)
+        if not length:
+            raise ScannerError("while scanning a directive", start_marker,
+                    "expected alphabetic or numeric character, but found %r"
+                    % ch.encode('utf-8'), self.reader.get_marker())
+        value = self.reader.prefix(length)
+        self.reader.forward(length)
+        ch = self.reader.peek()
+        if ch not in u'\0 \r\n\x85\u2028\u2029':
+            raise ScannerError("while scanning a directive", start_marker,
+                    "expected alphabetic or numeric character, but found %r"
+                    % ch.encode('utf-8'), self.reader.get_marker())
+        return value
+
+    def scan_yaml_directive_value(self, start_marker):
+        # See the specification for details.
+        while self.reader.peek() == u' ':
+            self.reader.forward()
+        major = self.scan_yaml_directive_number(start_marker)
+        if self.reader.peek() != '.':
+            raise ScannerError("while scanning a directive", start_marker,
+                    "expected a digit or '.', but found %r"
+                    % self.reader.peek().encode('utf-8'),
+                    self.reader.get_marker())
+        self.reader.forward()
+        minor = self.scan_yaml_directive_number(start_marker)
+        if self.reader.peek() not in u'\0 \r\n\x85\u2028\u2029':
+            raise ScannerError("while scanning a directive", start_marker,
+                    "expected a digit or ' ', but found %r"
+                    % self.reader.peek().encode('utf-8'),
+                    self.reader.get_marker())
+        return (major, minor)
+
+    def scan_yaml_directive_number(self, start_marker):
+        # See the specification for details.
+        ch = self.reader.peek()
+        if not (u'0' <= ch <= '9'):
+            raise ScannerError("while scanning a directive", start_marker,
+                    "expected a digit, but found %r" % ch.encode('utf-8'),
+                    self.reader.get_marker())
+        length = 0
+        while u'0' <= self.reader.peek(length) <= u'9':
+            length += 1
+        value = int(self.reader.prefix(length))
+        self.reader.forward(length)
+        return value
+
+    def scan_tag_directive_value(self, start_marker):
+        # See the specification for details.
+        while self.reader.peek() == u' ':
+            self.reader.forward()
+        handle = self.scan_tag_directive_handle(start_marker)
+        while self.reader.peek() == u' ':
+            self.reader.forward()
+        prefix = self.scan_tag_directive_prefix(start_marker)
+        return (handle, prefix)
+
+    def scan_tag_directive_handle(self, start_marker):
+        # See the specification for details.
+        value = self.scan_tag_handle('directive', start_marker)
+        ch = self.reader.peek()
+        if ch != u' ':
+            raise ScannerError("while scanning a directive", start_marker,
+                    "expected ' ', but found %r" % ch.encode('utf-8'),
+                    self.reader.get_marker())
+        return value
+
+    def scan_tag_directive_prefix(self, start_marker):
+        # See the specification for details.
+        value = self.scan_tag_uri('directive', start_marker)
+        ch = self.reader.peek()
+        if ch not in u'\0 \r\n\x85\u2028\u2029':
+            raise ScannerError("while scanning a directive", start_marker,
+                    "expected ' ', but found %r" % ch.encode('utf-8'),
+                    self.reader.get_marker())
+        return value
+
+    def scan_directive_ignored_line(self, start_marker):
+        # See the specification for details.
+        while self.reader.peek() == u' ':
+            self.reader.forward()
+        if self.reader.peek() == u'#':
+            while self.reader.peek() not in u'\0\r\n\x85\u2028\u2029':
+                self.reader.forward()
+        ch = self.reader.peek()
+        if ch not in u'\0\r\n\x85\u2028\u2029':
+            raise ScannerError("while scanning a directive", start_marker,
+                    "expected a comment or a line break, but found %r"
+                        % ch.encode('utf-8'), self.reader.get_marker())
+        self.scan_line_break()
+
+    def scan_anchor(self, TokenClass):
+        # The specification does not restrict characters for anchors and
+        # aliases. This may lead to problems, for instance, the document:
+        #   [ *alias, value ]
+        # can be interpteted in two ways, as
+        #   [ "value" ]
+        # and
+        #   [ *alias , "value" ]
+        # Therefore we restrict aliases to numbers and ASCII letters.
+        start_marker = self.reader.get_marker()
+        indicator = self.reader.peek()
+        if indicator == '*':
+            name = 'alias'
+        else:
+            name = 'anchor'
+        self.reader.forward()
+        length = 0
+        ch = self.reader.peek(length)
+        while u'0' <= ch <= u'9' or u'A' <= ch <= 'Z' or u'a' <= ch <= 'z'  \
+                or ch in u'-_':
+            length += 1
+            ch = self.reader.peek(length)
+        if not length:
+            raise ScannerError("while scanning an %s" % name, start_marker,
+                    "expected alphabetic or numeric character, but found %r"
+                    % ch.encode('utf-8'), self.reader.get_marker())
+        value = self.reader.prefix(length)
+        self.reader.forward(length)
+        ch = self.reader.peek()
+        if ch not in u'\0 \t\r\n\x85\u2028\u2029?:,]}%@`':
+            raise ScannerError("while scanning an %s" % name, start_marker,
+                    "expected alphabetic or numeric character, but found %r"
+                    % ch.encode('utf-8'), self.reader.get_marker())
+        end_marker = self.reader.get_marker()
+        return TokenClass(value, start_marker, end_marker)
+
+    def scan_tag(self):
+        # See the specification for details.
+        start_marker = self.reader.get_marker()
+        ch = self.reader.peek(1)
+        if ch == u'<':
+            handle = None
+            self.reader.forward(2)
+            suffix = self.scan_tag_uri('tag', start_marker)
+            if self.reader.peek() != u'>':
+                raise ScannerError("while parsing a tag", start_marker,
+                        "expected '>', but found %r" % self.reader.peek().encode('utf-8'),
+                        self.reader.get_marker())
+            self.reader.forward()
+        elif ch in u'\0 \t\r\n\x85\u2028\u2029':
+            handle = None
+            suffix = u'!'
+            self.reader.forward()
+        else:
+            length = 1
+            use_handle = False
+            while ch not in u'\0 \r\n\x85\u2028\u2029':
+                if ch == u'!':
+                    use_handle = True
+                    break
+                length += 1
+                ch = self.reader.peek(length)
+            handle = u'!'
+            if use_handle:
+                handle = self.scan_tag_handle('tag', start_marker)
+            else:
+                handle = u'!'
+                self.reader.forward()
+            suffix = self.scan_tag_uri('tag', start_marker)
+        ch = self.reader.peek()
+        if ch not in u'\0 \r\n\x85\u2028\u2029':
+            raise ScannerError("while scanning a tag", start_marker,
+                    "expected ' ', but found %r" % ch.encode('utf-8'),
+                    self.reader.get_marker())
+        value = (handle, suffix)
+        end_marker = self.reader.get_marker()
+        return TagToken(value, start_marker, end_marker)
+
+    def scan_block_scalar(self, folded):
+        # See the specification for details.
+
+        chunks = []
+        start_marker = self.reader.get_marker()
+
+        # Scan the header.
+        self.reader.forward()
+        chomping, increment = self.scan_block_scalar_indicators(start_marker)
+        self.scan_block_scalar_ignored_line(start_marker)
+
+        # Determine the indentation level and go to the first non-empty line.
+        min_indent = self.indent+1
+        if min_indent < 1:
+            min_indent = 1
+        if increment is None:
+            breaks, max_indent, end_marker = self.scan_block_scalar_indentation()
+            indent = max(min_indent, max_indent)
+        else:
+            indent = min_indent+increment-1
+            breaks, end_marker = self.scan_block_scalar_breaks(indent)
+        line_break = u''
+
+        # Scan the inner part of the block scalar.
+        while self.reader.column == indent and self.reader.peek() != u'\0':
+            chunks.extend(breaks)
+            leading_non_space = self.reader.peek() not in u' \t'
+            length = 0
+            while self.reader.peek(length) not in u'\0\r\n\x85\u2028\u2029':
+                length += 1
+            chunks.append(self.reader.prefix(length))
+            self.reader.forward(length)
+            line_break = self.scan_line_break()
+            breaks, end_marker = self.scan_block_scalar_breaks(indent)
+            if self.reader.column == indent and self.reader.peek() != u'\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.reader.peek() not in u' \t':
+                    if not breaks:
+                        chunks.append(u' ')
+                else:
+                    chunks.append(line_break)
+                
+                # This is Clark Evans's interpretation (also in the spec
+                # examples):
+                #
+                #if folded and line_break == u'\n':
+                #    if not breaks:
+                #        if self.reader.peek() not in ' \t':
+                #            chunks.append(u' ')
+                #        else:
+                #            chunks.append(line_break)
+                #else:
+                #    chunks.append(line_break)
+            else:
+                break
+
+        # Chomp the tail.
+        if chomping is not False:
+            chunks.append(line_break)
+        if chomping is True:
+            chunks.extend(breaks)
+
+        # We are done.
+        return ScalarToken(u''.join(chunks), False, start_marker, end_marker)
+
+    def scan_block_scalar_indicators(self, start_marker):
+        # See the specification for details.
+        chomping = None
+        increment = None
+        ch = self.reader.peek()
+        if ch in u'+-':
+            if ch == '+':
+                chomping = True
+            else:
+                chomping = False
+            self.reader.forward()
+            ch = self.reader.peek()
+            if ch in u'0123456789':
+                increment = int(ch)
+                if increment == 0:
+                    raise ScannerError("while scanning a block scalar", start_marker,
+                            "expected indentation indicator in the range 1-9, but found 0",
+                            self.reader.get_marker())
+                self.reader.forward()
+        elif ch in u'0123456789':
+            increment = int(ch)
+            if increment == 0:
+                raise ScannerError("while scanning a block scalar", start_marker,
+                        "expected indentation indicator in the range 1-9, but found 0",
+                        self.reader.get_marker())
+            self.reader.forward()
+            ch = self.reader.peek()
+            if ch in u'+-':
+                if ch == '+':
+                    chomping = True
+                else:
+                    chomping = False
+                self.reader.forward()
+        ch = self.reader.peek()
+        if ch not in u'\0 \r\n\x85\u2028\u2029':
+            raise ScannerError("while scanning a block scalar", start_marker,
+                    "expected chomping or indentation indicators, but found %r"
+                        % ch.encode('utf-8'), self.reader.get_marker())
+        return chomping, increment
+
+    def scan_block_scalar_ignored_line(self, start_marker):
+        # See the specification for details.
+        while self.reader.peek() == u' ':
+            self.reader.forward()
+        if self.reader.peek() == u'#':
+            while self.reader.peek() not in u'\0\r\n\x85\u2028\u2029':
+                self.reader.forward()
+        ch = self.reader.peek()
+        if ch not in u'\0\r\n\x85\u2028\u2029':
+            raise ScannerError("while scanning a block scalar", start_marker,
+                    "expected a comment or a line break, but found %r"
+                        % ch.encode('utf-8'), self.reader.get_marker())
+        self.scan_line_break()
+
+    def scan_block_scalar_indentation(self):
+        # See the specification for details.
+        chunks = []
+        max_indent = 0
+        end_marker = self.reader.get_marker()
+        while self.reader.peek() in u' \r\n\x85\u2028\u2029':
+            if self.reader.peek() != u' ':
+                chunks.append(self.scan_line_break())
+                end_marker = self.reader.get_marker()
+            else:
+                self.reader.forward()
+                if self.reader.column > max_indent:
+                    max_indent = self.reader.column
+        return chunks, max_indent, end_marker
+
+    def scan_block_scalar_breaks(self, indent):
+        # See the specification for details.
+        chunks = []
+        end_marker = self.reader.get_marker()
+        while self.reader.column < indent and self.reader.peek() == u' ':
+            self.reader.forward()
+        while self.reader.peek() in u'\r\n\x85\u2028\u2029':
+            chunks.append(self.scan_line_break())
+            end_marker = self.reader.get_marker()
+            while self.reader.column < indent and self.reader.peek() == u' ':
+                self.reader.forward()
+        return chunks, end_marker
+
+    def scan_flow_scalar(self, double):
+        # See the specification for details.
+        chunks = []
+        start_marker = self.reader.get_marker()
+        indent = self.indent+1
+        if indent == 0:
+            indent = 1
+        quote = self.reader.peek()
+        self.reader.forward()
+        chunks.extend(self.scan_flow_scalar_non_spaces(double, indent, start_marker))
+        while self.reader.peek() != quote:
+            chunks.extend(self.scan_flow_scalar_spaces(double, indent, start_marker))
+            chunks.extend(self.scan_flow_scalar_non_spaces(double, indent, start_marker))
+        self.reader.forward()
+        end_marker = self.reader.get_marker()
+        return ScalarToken(u''.join(chunks), False, start_marker, end_marker)
+
+    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',
+    }
+
+    ESCAPE_CODES = {
+        u'x':   2,
+        u'u':   4,
+        u'U':   8,
+    }
+
+    def scan_flow_scalar_non_spaces(self, double, indent, start_marker):
+        # See the specification for details.
+        chunks = []
+        while True:
+            length = 0
+            while self.reader.peek(length) not in u'\'\"\\\0 \t\r\n\x85\u2028\u2029':
+                length += 1
+            if length:
+                chunks.append(self.reader.prefix(length))
+                self.reader.forward(length)
+            ch = self.reader.peek()
+            if not double and ch == u'\'' and self.reader.peek(1) == u'\'':
+                chunks.append(u'\'')
+                self.reader.forward(2)
+            elif (double and ch == u'\'') or (not double and ch in u'\"\\'):
+                chunks.append(ch)
+                self.reader.forward()
+            elif double and ch == u'\\':
+                self.reader.forward()
+                ch = self.reader.peek()
+                if ch in self.ESCAPE_REPLACEMENTS:
+                    chunks.append(self.ESCAPE_REPLACEMENTS[ch])
+                    self.reader.forward()
+                elif ch in self.ESCAPE_CODES:
+                    length = self.ESCAPE_CODES[ch]
+                    self.reader.forward()
+                    for k in range(length):
+                        if self.reader.peek(k) not in u'0123456789ABCDEFabcdef':
+                            raise ScannerError("while scanning a double-quoted scalar", start_marker,
+                                    "expected escape sequence of %d hexdecimal numbers, but found %r" %
+                                        (length, self.reader.peek(k).encode('utf-8')), self.reader.get_marker())
+                    code = int(self.reader.prefix(length), 16)
+                    chunks.append(unichr(code))
+                    self.reader.forward(length)
+                elif ch in u'\r\n\x85\u2028\u2029':
+                    self.scan_line_break()
+                    chunks.extend(self.scan_flow_scalar_breaks(double, indent, start_marker))
+                else:
+                    raise ScannerError("while scanning a double-quoted scalar", start_marker,
+                            "found unknown escape character %r" % ch.encode('utf-8'), self.reader.get_marker())
+            else:
+                return chunks
+
+    def scan_flow_scalar_spaces(self, double, indent, start_marker):
+        # See the specification for details.
+        chunks = []
+        length = 0
+        while self.reader.peek(length) in u' \t':
+            length += 1
+        whitespaces = self.reader.prefix(length)
+        self.reader.forward(length)
+        ch = self.reader.peek()
+        if ch == u'\0':
+            raise ScannerError("while scanning a quoted scalar", start_marker,
+                    "found unexpected end of stream", self.reader.get_marker())
+        elif ch in u'\r\n\x85\u2028\u2029':
+            line_break = self.scan_line_break()
+            breaks = self.scan_flow_scalar_breaks(double, indent, start_marker)
+            if line_break != u'\n':
+                chunks.append(line_break)
+            elif not breaks:
+                chunks.append(u' ')
+            chunks.extend(breaks)
+        else:
+            chunks.append(whitespaces)
+        return chunks
+
+    def scan_flow_scalar_breaks(self, double, indent, start_marker):
+        # See the specification for details.
+        chunks = []
+        while True:
+            while self.reader.column < indent and self.reader.peek() == u' ':
+                self.reader.forward()
+            if self.reader.column < indent  \
+                    and self.reader.peek() not in u'\0\r\n\x85\u2028\u2029':
+                s = 's'
+                if indent == 1:
+                    s = ''
+                raise ScannerError("while scanning a quoted scalar", start_marker,
+                        "expected %d space%s indentation, but found %r"
+                        % (indent, s, self.reader.peek().encode('utf-8')),
+                        self.reader.get_marker())
+            while self.reader.peek() in u' \t':
+                self.reader.forward()
+            if self.reader.peek() in u'\r\n\x85\u2028\u2029':
+                chunks.append(self.scan_line_break())
+            else:
+                return chunks
+
+    def scan_plain(self):
+        # See the specification for details.
+        # We add an additional restriction for the flow context:
+        #   plain scalars in the flow context cannot contain ':' and '?'.
+        # We also keep track of the `allow_simple_key` flag here.
+        chunks = []
+        start_marker = self.reader.get_marker()
+        end_marker = start_marker
+        indent = self.indent+1
+        if indent == 0:
+            indent = 1
+        spaces = []
+        while True:
+            length = 0
+            if self.reader.peek() == u'#':
+                break
+            while True:
+                ch = self.reader.peek(length)
+                if ch in u'\0 \t\r\n\x85\u2028\u2029'   \
+                        or (not self.flow_level and ch == u':' and
+                                self.reader.peek(length+1) in u'\0 \t\r\n\x28\u2028\u2029') \
+                        or (self.flow_level and ch in u',:?[]{}'):
+                    break
+                length += 1
+            if length == 0:
+                break
+            self.allow_simple_key = False
+            chunks.extend(spaces)
+            chunks.append(self.reader.prefix(length))
+            self.reader.forward(length)
+            end_marker = self.reader.get_marker()
+            spaces = self.scan_plain_spaces(indent)
+            if not spaces or self.reader.peek() == u'#' \
+                    or self.reader.column < indent:
+                break
+        return ScalarToken(u''.join(chunks), True, start_marker, end_marker)
+
+    def scan_plain_spaces(self, indent):
+        # See the specification for details.
+        # The specification is really confusing about tabs in plain scalars.
+        # We just forbid them completely. Do not use tabs in YAML!
+        chunks = []
+        length = 0
+        while self.reader.peek(length) in u' ':
+            length += 1
+        whitespaces = self.reader.prefix(length)
+        self.reader.forward(length)
+        ch = self.reader.peek()
+        if ch in u'\r\n\x85\u2028\u2029':
+            line_break = self.scan_line_break()
+            self.allow_simple_key = True
+            breaks = []
+            while self.reader.peek() in u' \r\n\x85\u2028\u2029':
+                if self.reader.peek() == ' ':
+                    self.reader.forward()
+                else:
+                    breaks.append(self.scan_line_break())
+            if line_break != u'\n':
+                chunks.append(line_break)
+            elif not breaks:
+                chunks.append(u' ')
+            chunks.extend(breaks)
+        elif whitespaces:
+            chunks.append(whitespaces)
+        return chunks
+
+    def scan_tag_handle(self, name, start_marker):
+        # See the specification for details.
+        # For some strange reasons, the specification does not allow '_' in
+        # tag handles. I have allowed it anyway.
+        ch = self.reader.peek()
+        if ch != u'!':
+            raise ScannerError("while scanning a %s" % name, start_marker,
+                    "expected '!', but found %r" % ch.encode('utf-8'),
+                    self.reader.get_marker())
+        length = 1
+        ch = self.reader.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'-_':
+                length += 1
+                ch = self.reader.peek(length)
+            if ch != u'!':
+                self.reader.forward(length)
+                raise ScannerError("while scanning a %s" % name, start_marker,
+                        "expected '!', but found %r" % ch.encode('utf-8'),
+                        self.reader.get_marker())
+            length += 1
+        value = self.reader.prefix(length)
+        self.reader.forward(length)
+        return value
+
+    def scan_tag_uri(self, name, start_marker):
+        # See the specification for details.
+        # Note: we do not check if URI is well-formed.
+        chunks = []
+        length = 0
+        ch = self.reader.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'%':
+                chunks.append(self.reader.prefix(length))
+                self.reader.forward(length)
+                length = 0
+                chunks.append(self.scan_uri_escapes(name, start_marker))
+            else:
+                length += 1
+            ch = self.reader.peek(length)
+        if length:
+            chunks.append(self.reader.prefix(length))
+            self.reader.forward(length)
+            length = 0
+        if not chunks:
+            raise ScannerError("while parsing a %s" % name, start_marker,
+                    "expected URI, but found %r" % ch.encode('utf-8'),
+                    self.reader.get_marker())
+        return u''.join(chunks)
+
+    def scan_uri_escapes(self, name, start_marker):
+        # See the specification for details.
+        bytes = []
+        marker = self.reader.get_marker()
+        while self.reader.peek() == u'%':
+            self.reader.forward()
+            for k in range(2):
+                if self.reader.peek(k) not in u'0123456789ABCDEFabcdef':
+                    raise ScannerError("while scanning a %s" % name, start_marker,
+                            "expected URI escape sequence of 2 hexdecimal numbers, but found %r" %
+                                (self.reader.peek(k).encode('utf-8')), self.reader.get_marker())
+            bytes.append(chr(int(self.reader.prefix(2), 16)))
+            self.reader.forward(2)
+        try:
+            value = unicode(''.join(bytes), 'utf-8')
+        except UnicodeDecodeError, exc:
+            raise ScannerError("while scanning a %s" % name, start_marker, str(exc), marker)
+        return value
+
+    def scan_line_break(self):
+        # Transforms:
+        #   '\r\n'      :   '\n'
+        #   '\r'        :   '\n'
+        #   '\n'        :   '\n'
+        #   '\x85'      :   '\n'
+        #   '\u2028'    :   '\u2028'
+        #   '\u2029     :   '\u2029'
+        #   default     :   ''
+        ch = self.reader.peek()
+        if ch in u'\r\n\x85':
+            if self.reader.prefix(2) == u'\r\n':
+                self.reader.forward(2)
+            else:
+                self.reader.forward()
+            return u'\n'
+        elif ch in u'\u2028\u2029':
+            self.reader.forward()
+            return ch
+        return u''
+
+#try:
+#    import psyco
+#    psyco.bind(Scanner)
+#except ImportError:
+#    pass
+
Index: /pyyaml/trunk/lib/yaml/parser.py
===================================================================
--- /pyyaml/trunk/lib/yaml/parser.py	(revision 57)
+++ /pyyaml/trunk/lib/yaml/parser.py	(revision 57)
@@ -0,0 +1,443 @@
+
+# YAML can be parsed by an LL(1) parser!
+#
+# We use the following production rules:
+# stream            ::= implicit_document? explicit_document* STREAM-END
+# explicit_document ::= DIRECTIVE* DOCUMENT-START block_node? DOCUMENT-END?
+# implicit_document ::= block_node DOCUMENT-END?
+# block_node    ::= ALIAS | properties? block_content
+# flow_node     ::= ALIAS | properties? flow_content
+# properties    ::= TAG ANCHOR? | ANCHOR TAG?
+# block_content     ::= block_collection | flow_collection | SCALAR
+# flow_content      ::= flow_collection | SCALAR
+# block_collection  ::= block_sequence | block_mapping
+# block_sequence    ::= BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+# block_mapping     ::= BLOCK-MAPPING_START ((KEY block_node_or_indentless_sequence?)? (VALUE block_node_or_indentless_sequence?)?)* BLOCK-END
+# block_node_or_indentless_sequence ::= ALIAS | properties? (block_content | indentless_block_sequence)
+# indentless_block_sequence         ::= (BLOCK-ENTRY block_node?)+
+# flow_collection   ::= flow_sequence | flow_mapping
+# flow_sequence     ::= FLOW-SEQUENCE-START (flow_sequence_entry FLOW-ENTRY)* flow_sequence_entry? FLOW-SEQUENCE-END
+# flow_mapping      ::= FLOW-MAPPING-START (flow_mapping_entry FLOW-ENTRY)* flow_mapping_entry? FLOW-MAPPING-END
+# flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+# flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+
+# TODO: support for BOM within a stream.
+# stream ::= (BOM? implicit_document)? (BOM? explicit_document)* STREAM-END
+
+# Note that there is a slight deviation from the specification. We require a
+# non-empty node content if ANCHOR or TAG is specified. This disallow such
+# documents as
+#
+#   key:    !!str   # empty value
+#
+# This is done to prevent ambiguity in parsing tags and aliases:
+#
+#   {   !!perl/YAML::Parser:    value }
+#
+# What is it? Should it be interpreted as
+#   {   ? !<tag:yaml.org,2002:perl/YAML::Parser> '' : value }
+# or
+#   {   ? !<tag:yaml.org,2002:perl/YAML::Parser:> value : '' }
+# Since we disallow non-empty node content, tags are always followed by spaces
+# or line breaks.
+
+# FIRST sets:
+# stream: FIRST(block_node) + { DIRECTIVE DOCUMENT-START }
+# explicit_document: { DIRECTIVE DOCUMENT-START }
+# implicit_document: FIRST(block_node)
+# block_node: { ALIAS TAG ANCHOR SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START }
+# flow_node: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START }
+# block_content: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
+# flow_content: { FLOW-SEQUENCE-START FLOW-MAPPING-START SCALAR }
+# block_collection: { BLOCK-SEQUENCE-START BLOCK-MAPPING-START }
+# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
+# block_sequence: { BLOCK-SEQUENCE-START }
+# block_mapping: { BLOCK-MAPPING-START }
+# block_node_or_indentless_sequence: { ALIAS ANCHOR TAG SCALAR BLOCK-SEQUENCE-START BLOCK-MAPPING-START FLOW-SEQUENCE-START FLOW-MAPPING-START BLOCK-ENTRY }
+# indentless_sequence: { ENTRY }
+# flow_collection: { FLOW-SEQUENCE-START FLOW-MAPPING-START }
+# flow_sequence: { FLOW-SEQUENCE-START }
+# flow_mapping: { FLOW-MAPPING-START }
+# flow_sequence_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }
+# flow_mapping_entry: { ALIAS ANCHOR TAG SCALAR FLOW-SEQUENCE-START FLOW-MAPPING-START KEY }
+
+__all__ = ['Parser', 'ParserError']
+
+from error import MarkedYAMLError
+from tokens import *
+from events import *
+
+class ParserError(MarkedYAMLError):
+    pass
+
+class Parser:
+    # Since writing an LL(1) 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:',
+    }
+
+    def __init__(self, scanner):
+        self.scanner = scanner
+        self.current_event = None
+        self.yaml_version = None
+        self.tag_handles = {}
+        self.event_generator = self.parse_stream()
+
+    def check(self, *choices):
+        # Check the type of the next event.
+        if self.current_event is None:
+            try:
+                self.current_event = self.event_generator.next()
+            except StopIteration:
+                pass
+        if self.current_event is not None:
+            for choice in choices:
+                if isinstance(self.current_event, choice):
+                    return True
+        return False
+
+    def peek(self):
+        # Get the next event.
+        if self.current_event is None:
+            try:
+                self.current_event = self.event_generator.next()
+            except StopIteration:
+                pass
+        return self.current_event
+
+    def get(self):
+        # Get the next event.
+        if self.current_event is None:
+            try:
+                self.current_event = self.event_generator.next()
+            except StopIteration:
+                pass
+        value = self.current_event
+        self.current_event = None
+        return value
+
+    def __iter__(self):
+        # Iterator protocol.
+        return self.event_generator
+
+    def parse_stream(self):
+        # implicit_document? explicit_document* STREAM-END
+
+        # Parse implicit document.
+        if not self.scanner.check(DirectiveToken, DocumentStartToken,
+                StreamEndToken):
+            self.tag_handles = self.DEFAULT_TAGS
+            for event in self.parse_block_node():
+                yield event
+
+        # Parse explicit documents.
+        while not self.scanner.check(StreamEndToken):
+            self.process_directives()
+            if not self.scanner.check(DocumentStartToken):
+                raise ParserError(None, None,
+                        "expected '<document start>', but found %r"
+                        % self.scanner.peek().id,
+                        self.scanner.peek().start_marker)
+            token = self.scanner.get()
+            if self.scanner.check(DirectiveToken,
+                    DocumentStartToken, DocumentEndToken, StreamEndToken):
+                yield self.process_empty_scalar(token.end_marker)
+            else:
+                for event in self.parse_block_node():
+                    yield event
+            while self.scanner.check(DocumentEndToken):
+                self.scanner.get()
+
+        # Parse end of stream.
+        token = self.scanner.get()
+        yield StreamEndEvent(token.start_marker, token.end_marker)
+
+    def process_directives(self):
+        # DIRECTIVE*
+        self.yaml_version = None
+        self.tag_handles = {}
+        while self.scanner.check(DirectiveToken):
+            token = self.scanner.get()
+            if token.name == u'YAML':
+                if self.yaml_version is not None:
+                    raise ParserError(None, None,
+                            "found duplicate YAML directive", token.start_marker)
+                major, minor = token.value
+                if major != 1:
+                    raise ParserError(None, None,
+                            "found incompatible YAML document (version 1.* is required)",
+                            token.start_marker)
+                self.yaml_version = token.value
+            elif token.name == u'TAG':
+                handle, prefix = token.value
+                if handle in self.tag_handles:
+                    raise ParserError(None, None,
+                            "duplicate tag handle %r" % handle.encode('utf-8'),
+                            token.start_marker)
+                self.tag_handles[handle] = prefix
+        for key in self.DEFAULT_TAGS:
+            if key not in self.tag_handles:
+                self.tag_handles[key] = self.DEFAULT_TAGS[key]
+
+    def parse_block_node(self):
+        return self.parse_node(block=True)
+
+    def parse_flow_node(self):
+        return self.parse_node()
+
+    def parse_block_node_or_indentless_sequence(self):
+        return self.parse_node(block=True, indentless_sequence=True)
+
+    def parse_node(self, block=False, indentless_sequence=False):
+        # block_node    ::= ALIAS | properties? block_content
+        # flow_node     ::= ALIAS | properties? flow_content
+        # properties    ::= TAG ANCHOR? | ANCHOR TAG?
+        # block_content     ::= block_collection | flow_collection | SCALAR
+        # flow_content      ::= flow_collection | SCALAR
+        # block_collection  ::= block_sequence | block_mapping
+        # block_node_or_indentless_sequence ::= ALIAS | properties?
+        #                                       (block_content | indentless_block_sequence)
+        if self.scanner.check(AliasToken):
+            token = self.scanner.get()
+            yield AliasEvent(token.value, token.start_marker, token.end_marker)
+        else:
+            anchor = None
+            tag = None
+            start_marker = end_marker = tag_marker = None
+            if self.scanner.check(AnchorToken):
+                token = self.scanner.get()
+                start_marker = end_marker = token.start_marker
+                anchor = token.value
+                if self.scanner.check(TagToken):
+                    token = self.scanner.get()
+                    end_marker = tag_marker = token.start_marker
+                    tag = token.value
+            elif self.scanner.check(TagToken):
+                token = self.scanner.get()
+                start_marker = end_marker = tag_marker = token.start_marker
+                tag = token.value
+                if self.scanner.check(AnchorToken):
+                    token = self.scanner.get()
+                    end_marker = token.start_marker
+                    anchor = token.value
+            if tag is not None:
+                handle, suffix = tag
+                if handle is not None:
+                    if handle not in self.tag_handles:
+                        raise ParserError("while parsing a node", start_marker,
+                                "found undefined tag handle %r" % handle.encode('utf-8'),
+                                tag_marker)
+                    tag = self.tag_handles[handle]+suffix
+                else:
+                    tag = suffix
+            if tag is None:
+                if not (self.scanner.check(ScalarToken) and
+                        self.scanner.peek().plain):
+                    tag = u'!'
+            if start_marker is None:
+                start_marker = self.scanner.peek().start_marker
+            event = None
+            collection_events = None
+            if indentless_sequence and self.scanner.check(BlockEntryToken):
+                end_marker = self.scanner.peek().end_marker
+                event = SequenceEvent(anchor, tag, start_marker, end_marker)
+                collection_events = self.parse_indentless_sequence()
+            else:
+                if self.scanner.check(ScalarToken):
+                    token = self.scanner.get()
+                    end_marker = token.end_marker
+                    event = ScalarEvent(anchor, tag, token.value,
+                            start_marker, end_marker)
+                elif self.scanner.check(FlowSequenceStartToken):
+                    end_marker = self.scanner.peek().end_marker
+                    event = SequenceEvent(anchor, tag, start_marker, end_marker)
+                    collection_events = self.parse_flow_sequence()
+                elif self.scanner.check(FlowMappingStartToken):
+                    end_marker = self.scanner.peek().end_marker
+                    event = MappingEvent(anchor, tag, start_marker, end_marker)
+                    collection_events = self.parse_flow_mapping()
+                elif block and self.scanner.check(BlockSequenceStartToken):
+                    end_marker = self.scanner.peek().start_marker
+                    event = SequenceEvent(anchor, tag, start_marker, end_marker)
+                    collection_events = self.parse_block_sequence()
+                elif block and self.scanner.check(BlockMappingStartToken):
+                    end_marker = self.scanner.peek().start_marker
+                    event = MappingEvent(anchor, tag, start_marker, end_marker)
+                    collection_events = self.parse_block_mapping()
+                else:
+                    if block:
+                        node = 'block'
+                    else:
+                        node = 'flow'
+                    token = self.scanner.peek()
+                    raise ParserError("while scanning a %s node" % node, start_marker,
+                            "expected the node content, but found %r" % token.id,
+                            token.start_marker)
+            yield event
+            if collection_events is not None:
+                for event in collection_events:
+                    yield event
+
+    def parse_block_sequence(self):
+        # BLOCK-SEQUENCE-START (BLOCK-ENTRY block_node?)* BLOCK-END
+        token = self.scanner.get()
+        start_marker = token.start_marker
+        while self.scanner.check(BlockEntryToken):
+            token = self.scanner.get()
+            if not self.scanner.check(BlockEntryToken, BlockEndToken):
+                for event in self.parse_block_node():
+                    yield event
+            else:
+                yield self.process_empty_scalar(token.end_marker)
+        if not self.scanner.check(BlockEndToken):
+            token = self.scanner.peek()
+            raise ParserError("while scanning a block collection", start_marker,
+                    "expected <block end>, but found %r" % token.id, token.start_marker)
+        token = self.scanner.get()
+        yield CollectionEndEvent(token.start_marker, token.end_marker)
+
+    def parse_indentless_sequence(self):
+        # (BLOCK-ENTRY block_node?)+
+        while self.scanner.check(BlockEntryToken):
+            token = self.scanner.get()
+            if not self.scanner.check(BlockEntryToken,
+                    KeyToken, ValueToken, BlockEndToken):
+                for event in self.parse_block_node():
+                    yield event
+            else:
+                yield self.process_empty_scalar(token.end_marker)
+        token = self.scanner.peek()
+        yield CollectionEndEvent(token.start_marker, token.start_marker)
+
+    def parse_block_mapping(self):
+        # BLOCK-MAPPING_START
+        #   ((KEY block_node_or_indentless_sequence?)?
+        #   (VALUE block_node_or_indentless_sequence?)?)*
+        # BLOCK-END
+        token = self.scanner.get()
+        start_marker = token.start_marker
+        while self.scanner.check(KeyToken, ValueToken):
+            if self.scanner.check(KeyToken):
+                token = self.scanner.get()
+                if not self.scanner.check(KeyToken, ValueToken, BlockEndToken):
+                    for event in self.parse_block_node_or_indentless_sequence():
+                        yield event
+                else:
+                    yield self.process_empty_scalar(token.end_marker)
+            if self.scanner.check(ValueToken):
+                token = self.scanner.get()
+                if not self.scanner.check(KeyToken, ValueToken, BlockEndToken):
+                    for event in self.parse_block_node_or_indentless_sequence():
+                        yield event
+                else:
+                    yield self.process_empty_scalar(token.end_marker)
+            else:
+                token = self.scanner.peek()
+                yield self.process_empty_scalar(token.start_marker)
+        if not self.scanner.check(BlockEndToken):
+            token = self.scanner.peek()
+            raise ParserError("while scanning a block mapping", start_marker,
+                    "expected <block end>, but found %r" % token.id, token.start_marker)
+        token = self.scanner.get()
+        yield CollectionEndEvent(token.start_marker, token.end_marker)
+
+    def parse_flow_sequence(self):
+        # flow_sequence     ::= FLOW-SEQUENCE-START
+        #                       (flow_sequence_entry FLOW-ENTRY)*
+        #                       flow_sequence_entry?
+        #                       FLOW-SEQUENCE-END
+        # flow_sequence_entry   ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+        #
+        # Note that while production rules for both flow_sequence_entry and
+        # flow_mapping_entry are equal, their interpretations are different.
+        # For `flow_sequence_entry`, the part `KEY flow_node? (VALUE flow_node?)?`
+        # generate an inline mapping (set syntax).
+        token = self.scanner.get()
+        start_marker = token.start_marker
+        while not self.scanner.check(FlowSequenceEndToken):
+            if self.scanner.check(KeyToken):
+                token = self.scanner.get()
+                yield MappingEvent(None, u'!',
+                        token.start_marker, token.end_marker)
+                if not self.scanner.check(ValueToken,
+                        FlowEntryToken, FlowSequenceEndToken):
+                    for event in self.parse_flow_node():
+                        yield event
+                else:
+                    yield self.process_empty_scalar(token.end_marker)
+                if self.scanner.check(ValueToken):
+                    token = self.scanner.get()
+                    if not self.scanner.check(FlowEntryToken, FlowSequenceEndToken):
+                        for event in self.parse_flow_node():
+                            yield event
+                    else:
+                        yield self.process_empty_scalar(token.end_marker)
+                else:
+                    token = self.scanner.peek()
+                    yield self.process_empty_scalar(token.start_marker)
+                token = self.scanner.peek()
+                yield CollectionEndEvent(token.start_marker, token.start_marker)
+            else:
+                for event in self.parse_flow_node():
+                    yield event
+            if not self.scanner.check(FlowEntryToken, FlowSequenceEndToken):
+                token = self.scanner.peek()
+                raise ParserError("while scanning a flow sequence", start_marker,
+                        "expected ',' or ']', but got %r" % token.id, token.start_marker)
+            if self.scanner.check(FlowEntryToken):
+                self.scanner.get()
+        token = self.scanner.get()
+        yield CollectionEndEvent(token.start_marker, token.end_marker)
+
+    def parse_flow_mapping(self):
+        # flow_mapping      ::= FLOW-MAPPING-START
+        #                       (flow_mapping_entry FLOW-ENTRY)*
+        #                       flow_mapping_entry?
+        #                       FLOW-MAPPING-END
+        # flow_mapping_entry    ::= flow_node | KEY flow_node? (VALUE flow_node?)?
+        token = self.scanner.get()
+        start_marker = token.start_marker
+        while not self.scanner.check(FlowMappingEndToken):
+            if self.scanner.check(KeyToken):
+                token = self.scanner.get()
+                if not self.scanner.check(ValueToken,
+                        FlowEntryToken, FlowMappingEndToken):
+                    for event in self.parse_flow_node():
+                        yield event
+                else:
+                    yield self.process_empty_scalar(token.end_marker)
+                if self.scanner.check(ValueToken):
+                    token = self.scanner.get()
+                    if not self.scanner.check(FlowEntryToken, FlowMappingEndToken):
+                        for event in self.parse_flow_node():
+                            yield event
+                    else:
+                        yield self.process_empty_scalar(token.end_marker)
+                else:
+                    token = self.scanner.peek()
+                    yield self.process_empty_scalar(token.start_marker)
+            else:
+                for event in self.parse_flow_node():
+                    yield event
+                yield self.process_empty_scalar(self.scanner.peek().start_marker)
+            if not self.scanner.check(FlowEntryToken, FlowMappingEndToken):
+                token = self.scanner.peek()
+                raise ParserError("while scanning a flow mapping", start_marker,
+                        "expected ',' or '}', but got %r" % token.id, token.start_marker)
+            if self.scanner.check(FlowEntryToken):
+                self.scanner.get()
+        if not self.scanner.check(FlowMappingEndToken):
+            token = self.scanner.peek()
+            raise ParserError("while scanning a flow mapping", start_marker,
+                    "expected '}', but found %r" % token.id, token.start_marker)
+        token = self.scanner.get()
+        yield CollectionEndEvent(token.start_marker, token.end_marker)
+
+    def process_empty_scalar(self, marker):
+        return ScalarEvent(None, None, u'', marker, marker)
+
Index: /pyyaml/trunk/lib/yaml/__init__.py
===================================================================
--- /pyyaml/trunk/lib/yaml/__init__.py	(revision 57)
+++ /pyyaml/trunk/lib/yaml/__init__.py	(revision 57)
@@ -0,0 +1,33 @@
+
+from error import *
+from reader import *
+from scanner import *
+from parser import *
+from composer import *
+from resolver import *
+from constructor import *
+
+from tokens import *
+from events import *
+from nodes import *
+
+def parse(data, Reader=Reader, Scanner=Scanner, Parser=Parser):
+    reader = Reader(data)
+    scanner = Scanner(reader)
+    parser = Parser(scanner)
+    return parser
+
+def load(data, Reader=Reader, Scanner=Scanner, Parser=Parser,
+        Composer=Composer, Resolver=Resolver, Constructor=Constructor):
+    reader = Reader(data)
+    scanner = Scanner(reader)
+    parser = Parser(scanner)
+    composer = Composer(parser)
+    resolver = Resolver(composer)
+    constructor = Constructor(resolver)
+    return constructor
+
+def load_document(*args, **kwds):
+    for document in load(*args, **kwds):
+        return document
+
Index: /pyyaml/trunk/lib/yaml/resolver.py
===================================================================
--- /pyyaml/trunk/lib/yaml/resolver.py	(revision 59)
+++ /pyyaml/trunk/lib/yaml/resolver.py	(revision 59)
@@ -0,0 +1,150 @@
+
+__all__ = ['BaseResolver', 'Resolver', 'ResolverError']
+
+from error import MarkedYAMLError
+from nodes import *
+
+import re
+
+# Not really used.
+class ResolverError(MarkedYAMLError):
+    pass
+
+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'
+
+    def __init__(self, composer):
+        self.composer = composer
+        self.resolved_nodes = {}
+
+    def check(self):
+        # If there are more documents available?
+        return self.composer.check()
+
+    def get(self):
+        # Resolve and return the root node of the next document.
+        if self.composer.check():
+            return self.resolve_document(self.composer.get())
+
+    def __iter__(self):
+        # Iterator protocol.
+        while self.composer.check():
+            yield self.resolve_document(self.composer.get())
+
+    def resolve_document(self, node):
+        self.resolve_node([], node)
+        return node
+        self.resolved_nodes = {}
+
+    def resolve_node(self, path, node):
+        if node in self.resolved_nodes:
+            return
+        self.resolved_nodes[node] = None
+        if isinstance(node, ScalarNode):
+            self.resolve_scalar(path, node)
+        elif isinstance(node, SequenceNode):
+            self.resolve_sequence(path, node)
+            for index in range(len(node.value)):
+                self.resolve_node(path+[(node, index)], node.value[index])
+        elif isinstance(node, MappingNode):
+            self.resolve_mapping(path, node)
+            for key in node.value:
+                self.resolve_node(path+[node, None], key)
+                self.resolve_node(path+[node, key], node.value[key])
+
+    def resolve_scalar(self, path, node):
+        if node.tag is None:
+            node.tag = self.detect_scalar(node.value)
+        if node.tag is None or node.tag == u'!':
+            node.tag = self.DEFAULT_SCALAR_TAG
+
+    def resolve_sequence(self, path, node):
+        if node.tag is None or node.tag == u'!':
+            node.tag = self.DEFAULT_SEQUENCE_TAG
+
+    def resolve_mapping(self, path, node):
+        if node.tag is None or node.tag == u'!':
+            node.tag = self.DEFAULT_MAPPING_TAG
+
+    def detect_scalar(self, value):
+        if value == u'':
+            detectors = self.yaml_detectors.get(u'', [])
+        else:
+            detectors = self.yaml_detectors.get(value[0], [])
+        detectors += self.yaml_detectors.get(None, [])
+        for tag, regexp in detectors:
+            if regexp.match(value):
+                return tag
+
+    def add_detector(cls, tag, regexp, first):
+        if not 'yaml_detectors' in cls.__dict__:
+            cls.yaml_detectors = cls.yaml_detectors.copy()
+        for ch in first:
+            cls.yaml_detectors.setdefault(ch, []).append((tag, regexp))
+    add_detector = classmethod(add_detector)
+
+    yaml_detectors = {}
+
+class Resolver(BaseResolver):
+    pass
+
+Resolver.add_detector(
+        u'tag:yaml.org,2002:bool',
+        re.compile(ur'''^(?:yes|Yes|YES|n|N|no|No|NO
+                    |true|True|TRUE|false|False|FALSE
+                    |on|On|ON|off|Off|OFF)$''', re.X),
+        list(u'yYnNtTfFoO'))
+
+Resolver.add_detector(
+        u'tag:yaml.org,2002:float',
+        re.compile(ur'''^(?:[-+]?(?:[0-9][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.'))
+
+Resolver.add_detector(
+        u'tag:yaml.org,2002:int',
+        re.compile(ur'''^(?:[-+]?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'))
+
+Resolver.add_detector(
+        u'tag:yaml.org,2002:merge',
+        re.compile(ur'^(?:<<)$'),
+        ['<'])
+
+Resolver.add_detector(
+        u'tag:yaml.org,2002:null',
+        re.compile(ur'''^(?: ~
+                    |null|Null|NULL
+                    | )$''', re.X),
+        [u'~', u'n', u'N', u''])
+
+Resolver.add_detector(
+        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]
+                    |[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'))
+
+Resolver.add_detector(
+        u'tag:yaml.org,2002:value',
+        re.compile(ur'^(?:=)$'),
+        ['='])
+
+# The following detector is only for documentation purposes. It cannot work
+# because plain scalars cannot start with '!', '&', or '*'.
+Resolver.add_detector(
+        u'tag:yaml.org,2002:yaml',
+        re.compile(ur'^(?:!|&|\*)$'),
+        list(u'!&*'))
+
Index: /pyyaml/trunk/lib/yaml/reader.py
===================================================================
--- /pyyaml/trunk/lib/yaml/reader.py	(revision 52)
+++ /pyyaml/trunk/lib/yaml/reader.py	(revision 52)
@@ -0,0 +1,217 @@
+# This module contains abstractions for the input stream. You don't have to
+# looks further, there are no pretty code.
+#
+# We define two classes here.
+#
+#   Marker(source, line, column)
+# It's just a record and its only use is producing nice error messages.
+# Parser does not use it for any other purposes.
+#
+#   Reader(source, data)
+# Reader determines the encoding of `data` and converts it to unicode.
+# Reader provides the following methods and attributes:
+#   reader.peek(length=1) - return the next `length` characters
+#   reader.forward(length=1) - move the current position to `length` characters.
+#   reader.index - the number of the current character.
+#   reader.line, stream.column - the line and the column of the current character.
+
+__all__ = ['Reader', 'ReaderError']
+
+from error import YAMLError, Marker
+
+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)
+
+class ReaderError(YAMLError):
+
+    def __init__(self, name, position, character, encoding, reason):
+        self.name = name
+        self.character = character
+        self.position = position
+        self.encoding = encoding
+        self.reason = reason
+
+    def __str__(self):
+        if isinstance(self.character, str):
+            return "'%s' codec can't decode byte #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"    \
+                    "  in \"%s\", position %d"    \
+                    % (ord(self.character), self.reason,
+                            self.name, self.position)
+
+class Reader:
+    # Reader:
+    # - determines the data encoding and converts it to unicode,
+    # - checks if characters are in allowed range,
+    # - adds '\0' to the end.
+
+    # Reader accepts
+    #  - a `str` object,
+    #  - a `unicode` object,
+    #  - a file-like object with its `read` method returning `str`,
+    #  - a file-like object with its `read` method returning `unicode`.
+
+    # Yeah, it's ugly and slow.
+
+    def __init__(self, data):
+        self.name = None
+        self.stream = None
+        self.stream_pointer = 0
+        self.eof = True
+        self.buffer = u''
+        self.pointer = 0
+        self.raw_buffer = None
+        self.raw_decode = None
+        self.index = 0
+        self.line = 0
+        self.column = 0
+        if isinstance(data, unicode):
+            self.name = "<unicode string>"
+            self.check_printable(data)
+            self.buffer = data+u'\0'
+        elif isinstance(data, str):
+            self.name = "<string>"
+            self.raw_buffer = data
+            self.determine_encoding()
+        else:
+            self.stream = data
+            self.name = getattr(data, 'name', "<file>")
+            self.eof = False
+            self.raw_buffer = ''
+            self.determine_encoding()
+
+    def peek(self, index=0):
+        if self.pointer+index+1 >= len(self.buffer):
+            self.update(index+1)
+        return self.buffer[self.pointer+index]
+
+    def prefix(self, length=1):
+        if self.pointer+length >= len(self.buffer):
+            self.update(length)
+        return self.buffer[self.pointer:self.pointer+length]
+
+    def forward(self, length=1):
+        if self.pointer+length+1 >= len(self.buffer):
+            self.update(length+1)
+        for k in range(length):
+            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+1] != u'\n'):
+                self.line += 1
+                self.column = 0
+            elif ch != u'\uFEFF':
+                self.column += 1
+
+    def get_marker(self):
+        if self.stream is None:
+            return Marker(self.name, self.line, self.column,
+                    self.buffer, self.pointer)
+        else:
+            return Marker(self.name, self.line, self.column, None, None)
+
+    def determine_encoding(self):
+        while not self.eof and len(self.raw_buffer) < 2:
+            self.update_raw()
+        if not isinstance(self.raw_buffer, unicode):
+            if self.raw_buffer.startswith(codecs.BOM_UTF16_LE):
+                self.raw_decode = utf_16_le_decode
+            elif self.raw_buffer.startswith(codecs.BOM_UTF16_BE):
+                self.raw_decode = utf_16_be_decode
+            else:
+                self.raw_decode = utf_8_decode
+        self.update(1)
+
+    NON_PRINTABLE = re.compile(u'[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\uD7FF\uE000-\uFFFD]')
+    def check_printable(self, data):
+        match = self.NON_PRINTABLE.search(data)
+        if match:
+            character = match.group()
+            position = self.index+(len(self.buffer)-self.pointer)+match.start()
+            raise ReaderError(self.name, position, character,
+                    'unicode', "special characters are not allowed")
+
+    def update(self, length):
+        if self.raw_buffer is None:
+            return
+        self.buffer = self.buffer[self.pointer:]
+        self.pointer = 0
+        while len(self.buffer) < length:
+            if not self.eof:
+                self.update_raw()
+            if self.raw_decode is not None:
+                try:
+                    data, converted = self.raw_decode(self.raw_buffer,
+                            'strict', self.eof)
+                except UnicodeDecodeError, 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)
+            else:
+                data = self.raw_buffer
+                converted = len(data)
+            self.check_printable(data)
+            self.buffer += data
+            self.raw_buffer = self.raw_buffer[converted:]
+            if self.eof:
+                self.buffer += u'\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)
+        else:
+            self.eof = True
+
+#try:
+#    import psyco
+#    psyco.bind(Reader)
+#except ImportError:
+#    pass
+
Index: /pyyaml/trunk/lib/yaml/tokens.py
===================================================================
--- /pyyaml/trunk/lib/yaml/tokens.py	(revision 52)
+++ /pyyaml/trunk/lib/yaml/tokens.py	(revision 52)
@@ -0,0 +1,95 @@
+
+class Token:
+    def __init__(self, start_marker, end_marker):
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+    def __repr__(self):
+        attributes = [key for key in self.__dict__
+                if not key.endswith('_marker')]
+        attributes.sort()
+        arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
+                for key in attributes])
+        return '%s(%s)' % (self.__class__.__name__, arguments)
+
+#class BOMToken(Token):
+#    id = '<byte order mark>'
+
+class DirectiveToken(Token):
+    id = '<directive>'
+    def __init__(self, name, value, start_marker, end_marker):
+        self.name = name
+        self.value = value
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+
+class DocumentStartToken(Token):
+    id = '<document start>'
+
+class DocumentEndToken(Token):
+    id = '<document end>'
+
+class StreamEndToken(Token):
+    id = '<stream end>'
+
+class BlockSequenceStartToken(Token):
+    id = '<block sequence start>'
+
+class BlockMappingStartToken(Token):
+    id = '<block mapping start>'
+
+class BlockEndToken(Token):
+    id = '<block end>'
+
+class FlowSequenceStartToken(Token):
+    id = '['
+
+class FlowMappingStartToken(Token):
+    id = '{'
+
+class FlowSequenceEndToken(Token):
+    id = ']'
+
+class FlowMappingEndToken(Token):
+    id = '}'
+
+class KeyToken(Token):
+    id = '?'
+
+class ValueToken(Token):
+    id = ':'
+
+class BlockEntryToken(Token):
+    id = '-'
+
+class FlowEntryToken(Token):
+    id = ','
+
+class AliasToken(Token):
+    id = '<alias>'
+    def __init__(self, value, start_marker, end_marker):
+        self.value = value
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+
+class AnchorToken(Token):
+    id = '<anchor>'
+    def __init__(self, value, start_marker, end_marker):
+        self.value = value
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+
+class TagToken(Token):
+    id = '<tag>'
+    def __init__(self, value, start_marker, end_marker):
+        self.value = value
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+
+class ScalarToken(Token):
+    id = '<scalar>'
+    def __init__(self, value, plain, start_marker, end_marker):
+        self.value = value
+        self.plain = plain
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+
Index: /pyyaml/trunk/lib/yaml/events.py
===================================================================
--- /pyyaml/trunk/lib/yaml/events.py	(revision 53)
+++ /pyyaml/trunk/lib/yaml/events.py	(revision 53)
@@ -0,0 +1,49 @@
+
+class Event:
+    def __init__(self, start_marker, end_marker):
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+    def __repr__(self):
+        attributes = [key for key in self.__dict__
+                if not key.endswith('_marker')]
+        attributes.sort()
+        arguments = ', '.join(['%s=%r' % (key, getattr(self, key))
+                for key in attributes])
+        return '%s(%s)' % (self.__class__.__name__, arguments)
+
+class NodeEvent(Event):
+    def __init__(self, anchor, start_marker, end_marker):
+        self.anchor = anchor
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+
+class AliasEvent(NodeEvent):
+    pass
+
+class ScalarEvent(NodeEvent):
+    def __init__(self, anchor, tag, value, start_marker, end_marker):
+        self.anchor = anchor
+        self.tag = tag
+        self.value = value
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+
+class CollectionEvent(NodeEvent):
+    def __init__(self, anchor, tag, start_marker, end_marker):
+        self.anchor = anchor
+        self.tag = tag
+        self.start_marker = start_marker
+        self.end_marker = end_marker
+
+class SequenceEvent(CollectionEvent):
+    pass
+
+class MappingEvent(CollectionEvent):
+    pass
+
+class CollectionEndEvent(Event):
+    pass
+
+class StreamEndEvent(Event):
+    pass
+
Index: /pyyaml/trunk/lib/yaml/constructor.py
===================================================================
--- /pyyaml/trunk/lib/yaml/constructor.py	(revision 59)
+++ /pyyaml/trunk/lib/yaml/constructor.py	(revision 59)
@@ -0,0 +1,410 @@
+
+__all__ = ['BaseConstructor', 'Constructor', 'ConstructorError',
+    'YAMLObject', 'YAMLObjectMetaclass']
+
+from error import *
+from nodes import *
+
+try:
+    import datetime
+    datetime_available = True
+except ImportError:
+    datetime_available = False
+
+try:
+    set
+except NameError:
+    from sets import Set as set
+
+import binascii, re
+
+class ConstructorError(MarkedYAMLError):
+    pass
+
+class BaseConstructor:
+
+    def __init__(self, resolver):
+        self.resolver = resolver
+        self.constructed_objects = {}
+
+    def check(self):
+        # If there are more documents available?
+        return self.resolver.check()
+
+    def get(self):
+        # Construct and return the next document.
+        if self.resolver.check():
+            return self.construct_document(self.resolver.get())
+
+    def __iter__(self):
+        # Iterator protocol.
+        while self.resolver.check():
+            yield self.construct_document(self.resolver.get())
+
+    def construct_document(self, node):
+        native = self.construct_object(node)
+        self.constructed_objects = {}
+        return native
+
+    def construct_object(self, node):
+        if node in self.constructed_objects:
+            return self.constructed_objects[node]
+        if node.tag in self.yaml_constructors:
+            native = self.yaml_constructors[node.tag](self, node)
+        elif None in self.yaml_constructors:
+            native = self.yaml_constructors[None](self, node)
+        elif isinstance(node, ScalarNode):
+            native = self.construct_scalar(node)
+        elif isinstance(node, SequenceNode):
+            native = self.construct_sequence(node)
+        elif isinstance(node, MappingNode):
+            native = self.construct_mapping(node)
+        self.constructed_objects[node] = native
+        return native
+
+    def construct_scalar(self, node):
+        if not isinstance(node, ScalarNode):
+            if isinstance(node, MappingNode):
+                for key_node in node.value:
+                    if key_node.tag == u'tag:yaml.org,2002:value':
+                        return self.construct_scalar(node.value[key_node])
+            raise ConstructorError(None, None,
+                    "expected a scalar node, but found %s" % node.id,
+                    node.start_marker)
+        return node.value
+
+    def construct_sequence(self, node):
+        if not isinstance(node, SequenceNode):
+            raise ConstructorError(None, None,
+                    "expected a sequence node, but found %s" % node.id,
+                    node.start_marker)
+        return [self.construct_object(child) for child in node.value]
+
+    def construct_mapping(self, node):
+        if not isinstance(node, MappingNode):
+            raise ConstructorError(None, None,
+                    "expected a mapping node, but found %s" % node.id,
+                    node.start_marker)
+        mapping = {}
+        merge = None
+        for key_node in node.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
+
+    def construct_pairs(self, node):
+        if not isinstance(node, MappingNode):
+            raise ConstructorError(None, None,
+                    "expected a mapping node, but found %s" % node.id,
+                    node.start_marker)
+        pairs = []
+        for key_node in node.value:
+            key = self.construct_object(key_node)
+            value = self.construct_object(node.value[key_node])
+            pairs.append((key, value))
+        return pairs
+
+    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)
+
+    yaml_constructors = {}
+
+class Constructor(BaseConstructor):
+
+    def construct_yaml_null(self, node):
+        self.construct_scalar(node)
+        return None
+
+    bool_values = {
+        u'yes':     True,
+        u'no':      False,
+        u'true':    True,
+        u'false':   False,
+        u'on':      True,
+        u'off':     False,
+    }
+
+    def construct_yaml_bool(self, node):
+        value = self.construct_scalar(node)
+        return self.bool_values[value.lower()]
+
+    def construct_yaml_int(self, node):
+        value = str(self.construct_scalar(node))
+        value = value.replace('_', '')
+        sign = +1
+        if value[0] == '-':
+            sign = -1
+        if value[0] in '+-':
+            value = value[1:]
+        if value == '0':
+            return 0
+        elif value.startswith('0b'):
+            return sign*int(value[2:], 2)
+        elif value.startswith('0x'):
+            return sign*int(value[2:], 16)
+        elif value[0] == '0':
+            return sign*int(value, 8)
+        elif ':' in value:
+            digits = [int(part) for part in value.split(':')]
+            digits.reverse()
+            base = 1
+            value = 0
+            for digit in digits:
+                value += digit*base
+                base *= 60
+            return sign*value
+        else:
+            return sign*int(value)
+
+    inf_value = 1e300000
+    nan_value = inf_value/inf_value
+
+    def construct_yaml_float(self, node):
+        value = str(self.construct_scalar(node))
+        value = value.replace('_', '')
+        sign = +1
+        if value[0] == '-':
+            sign = -1
+        if value[0] in '+-':
+            value = value[1:]
+        if value.lower() == '.inf':
+            return sign*self.inf_value
+        elif value.lower() == '.nan':
+            return self.nan_value
+        elif ':' in value:
+            digits = [float(part) for part in value.split(':')]
+            digits.reverse()
+            base = 1
+            value = 0.0
+            for digit in digits:
+                value += digit*base
+                base *= 60
+            return sign*value
+        else:
+            return float(value)
+
+    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_marker) 
+
+    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_regexp.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 fraction:
+            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))
+        return omap
+
+    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)
+        pairs = []
+        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])
+            pairs.append((key, value))
+        return pairs
+
+    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)
+        try:
+            return str(value)
+        except UnicodeEncodeError:
+            return value
+
+    def construct_yaml_seq(self, node):
+        return self.construct_sequence(node)
+
+    def construct_yaml_map(self, node):
+        return self.construct_mapping(node)
+
+    def construct_undefined(self, node):
+        raise ConstructorError(None, None,
+                "could not determine a constructor for the tag %r" % node.tag.encode('utf-8'),
+                node.start_marker)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:null',
+        Constructor.construct_yaml_null)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:bool',
+        Constructor.construct_yaml_bool)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:int',
+        Constructor.construct_yaml_int)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:float',
+        Constructor.construct_yaml_float)
+
+Constructor.add_constructor(
+        u'tag:yaml.org,2002:binary',
+        Constructor.construct_yaml_binary)
+
+if datetime_available:
+    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)
+
+Constructor.add_constructor(None,
+        Constructor.construct_undefined)
+
+class YAMLObjectMetaclass(type):
+
+    def __init__(cls, name, bases, kwds):
+        super(YAMLObjectMetaclass, cls).__init__(name, bases, kwds)
+        if 'yaml_tag' in kwds and kwds['yaml_tag'] is not None:
+            cls.yaml_constructor.add_constructor(cls.yaml_tag, cls.from_yaml)
+
+class YAMLObject(object):
+
+    __metaclass__ = YAMLObjectMetaclass
+
+    yaml_constructor = Constructor
+
+    yaml_tag = None
+
+    def from_yaml(cls, constructor, node):
+        raise ConstructorError(None, None,
+                "found undefined constructor for the tag %r"
+                % node.tag.encode('utf-8'), node.start_marker)
+    from_yaml = classmethod(from_yaml)
+
+    def to_yaml(self):
+        assert False    # needs dumper
+
Index: /pyyaml/trunk/lib/yaml/composer.py
===================================================================
--- /pyyaml/trunk/lib/yaml/composer.py	(revision 57)
+++ /pyyaml/trunk/lib/yaml/composer.py	(revision 57)
@@ -0,0 +1,98 @@
+
+__all__ = ['Composer', 'ComposerError']
+
+from error import MarkedYAMLError
+from events import *
+from nodes import *
+
+class ComposerError(MarkedYAMLError):
+    pass
+
+class Composer:
+
+    def __init__(self, parser):
+        self.parser = parser
+        self.all_anchors = {}
+        self.complete_anchors = {}
+
+    def check(self):
+        # If there are more documents available?
+        return not self.parser.check(StreamEndEvent)
+
+    def get(self):
+        # Get the root node of the next document.
+        if not self.parser.check(StreamEndEvent):
+            return self.compose_document()
+
+    def __iter__(self):
+        # Iterator protocol.
+        while not self.parser.check(StreamEndEvent):
+            yield self.compose_document()
+
+    def compose_document(self):
+        node = self.compose_node()
+        self.all_anchors = {}
+        self.complete_anchors = {}
+        return node
+
+    def compose_node(self):
+        if self.parser.check(AliasEvent):
+            event = self.parser.get()
+            anchor = event.anchor
+            if anchor not in self.all_anchors:
+                raise ComposerError(None, None, "found undefined alias %r"
+                        % anchor.encode('utf-8'), event.start_marker)
+            if anchor not in self.complete_anchors:
+                collection_event = self.all_anchors[anchor]
+                raise ComposerError("while composing a collection",
+                        collection_event.start_marker,
+                        "found recursive anchor %r" % anchor.encode('utf-8'),
+                        event.start_marker)
+            return self.complete_anchors[anchor]
+        event = self.parser.peek()
+        anchor = event.anchor
+        if anchor is not None:
+            if anchor in self.all_anchors:
+                raise ComposerError("found duplicate anchor %r; first occurence"
+                        % anchor.encode('utf-8'), self.all_anchors[anchor].start_marker,
+                        "second occurence", event.start_marker)
+            self.all_anchors[anchor] = event
+        if self.parser.check(ScalarEvent):
+            node = self.compose_scalar_node()
+        elif self.parser.check(SequenceEvent):
+            node = self.compose_sequence_node()
+        elif self.parser.check(MappingEvent):
+            node = self.compose_mapping_node()
+        if anchor is not None:
+            self.complete_anchors[anchor] = node
+        return node
+
+    def compose_scalar_node(self):
+        event = self.parser.get()
+        return ScalarNode(event.tag, event.value,
+                event.start_marker, event.end_marker)
+
+    def compose_sequence_node(self):
+        start_event = self.parser.get()
+        value = []
+        while not self.parser.check(CollectionEndEvent):
+            value.append(self.compose_node())
+        end_event = self.parser.get()
+        return SequenceNode(start_event.tag, value,
+                start_event.start_marker, end_event.end_marker)
+
+    def compose_mapping_node(self):
+        start_event = self.parser.get()
+        value = {}
+        while not self.parser.check(CollectionEndEvent):
+            key_event = self.parser.peek()
+            item_key = self.compose_node()
+            item_value = self.compose_node()
+            if item_key in value:
+                raise ComposerError("while composing a mapping", start_event.start_marker,
+                        "found duplicate key", key_event.start_marker)
+            value[item_key] = item_value
+        end_event = self.parser.get()
+        return MappingNode(start_event.tag, value,
+                start_event.start_marker, end_event.end_marker)
+
Index: /pyyaml/trunk/setup.py
===================================================================
--- /pyyaml/trunk/setup.py	(revision 59)
+++ /pyyaml/trunk/setup.py	(revision 59)
@@ -0,0 +1,22 @@
+
+NAME = 'PyYAML3000'
+VERSION = '0.1'
+DESCRIPTION = "The next generation YAML parser for Python"
+AUTHOR = "Kirill Simonov"
+AUTHOR_EMAIL = 'xi@resolvent.net'
+LICENSE = "MIT"
+
+from distutils.core import setup
+
+setup(
+    name=NAME,
+    version=VERSION,
+    description=DESCRIPTION,
+    author=AUTHOR,
+    author_email=AUTHOR_EMAIL,
+    license=LICENSE,
+
+    package_dir={'': 'lib'},
+    packages=['yaml'],
+)
+
Index: /pyyaml/trunk/MANIFEST.in
===================================================================
--- /pyyaml/trunk/MANIFEST.in	(revision 59)
+++ /pyyaml/trunk/MANIFEST.in	(revision 59)
@@ -0,0 +1,1 @@
+include README LICENSE
Index: /pyyaml/trunk/Makefile
===================================================================
--- /pyyaml/trunk/Makefile	(revision 59)
+++ /pyyaml/trunk/Makefile	(revision 59)
@@ -0,0 +1,25 @@
+
+.PHONY: default build force install test dist-src clean
+
+PYTHON=/usr/bin/python
+TEST=
+PARAMETERS=
+
+build:
+	${PYTHON} setup.py build ${PARAMETERS}
+
+force:
+	${PYTHON} setup.py build -f ${PARAMETERS}
+
+install: build
+	${PYTHON} setup.py install ${PARAMETERS}
+
+test: build
+	${PYTHON} tests/test_build.py ${TEST}
+
+dist-src:
+	${PYTHON} setup.py sdist --formats=zip,gztar
+
+clean:
+	${PYTHON} setup.py clean -a
+
Index: /pyyaml/trunk/README
===================================================================
--- /pyyaml/trunk/README	(revision 58)
+++ /pyyaml/trunk/README	(revision 58)
@@ -0,0 +1,11 @@
+PyYAML3000 - The next generation YAML parser for Python.
+
+To install, type 'python setup.py install'.
+
+For more information, check 'http://trac.xitology.org/pysyck/wiki/PyYAML3000'.
+
+Post your questions and opinions to the YAML-Core mailing list:
+'http://lists.sourceforge.net/lists/listinfo/yaml-core'.
+
+PyYAML3000 is written by Kirill Simonov <xi@resolvent.net>. It is released
+under the MIT license. See the file LICENSE for more details.
