summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorxi <xi@18f92427-320e-0410-9341-c67f048884a3>2006-02-25 16:08:26 +0000
committerxi <xi@18f92427-320e-0410-9341-c67f048884a3>2006-02-25 16:08:26 +0000
commit5142aa8360bc5cb03c18d0a4ea86abcd087d1b6b (patch)
tree95ca5ba2fb800d979e145ef06ae85bc8588c0f4b
parenta3e1d53bbac8d5dc770802ab0cc9c85aeed65b3f (diff)
downloadpyyaml-5142aa8360bc5cb03c18d0a4ea86abcd087d1b6b.tar.gz
Ready for the initial release.
git-svn-id: http://svn.pyyaml.org/branches/pyyaml3000@58 18f92427-320e-0410-9341-c67f048884a3
-rw-r--r--LICENSE19
-rw-r--r--README11
-rw-r--r--lib/yaml/constructor.py95
-rw-r--r--tests/data/construct-binary.code7
-rw-r--r--tests/data/construct-binary.data12
-rw-r--r--tests/data/construct-bool.code6
-rw-r--r--tests/data/construct-bool.data4
-rw-r--r--tests/data/construct-custom.code9
-rw-r--r--tests/data/construct-custom.data23
-rw-r--r--tests/data/construct-float.code8
-rw-r--r--tests/data/construct-float.data6
-rw-r--r--tests/data/construct-int.code8
-rw-r--r--tests/data/construct-int.data6
-rw-r--r--tests/data/construct-map.code6
-rw-r--r--tests/data/construct-map.data6
-rw-r--r--tests/data/construct-merge.code10
-rw-r--r--tests/data/construct-merge.data27
-rw-r--r--tests/data/construct-null.code13
-rw-r--r--tests/data/construct-null.data18
-rw-r--r--tests/data/construct-omap.code8
-rw-r--r--tests/data/construct-omap.data8
-rw-r--r--tests/data/construct-pairs.code9
-rw-r--r--tests/data/construct-pairs.data7
-rw-r--r--tests/data/construct-seq.code4
-rw-r--r--tests/data/construct-seq.data15
-rw-r--r--tests/data/construct-set.code4
-rw-r--r--tests/data/construct-set.data7
-rw-r--r--tests/data/construct-str.code1
-rw-r--r--tests/data/construct-str.data1
-rw-r--r--tests/data/construct-timestamp.code7
-rw-r--r--tests/data/construct-timestamp.data5
-rw-r--r--tests/data/construct-value.code9
-rw-r--r--tests/data/construct-value.data10
-rw-r--r--tests/data/duplicate-key.error-message3
-rw-r--r--tests/data/duplicate-merge-key.error-message4
-rw-r--r--tests/data/duplicate-value-key.error-message4
-rw-r--r--tests/data/expected-mapping.error-message1
-rw-r--r--tests/data/expected-scalar.error-message1
-rw-r--r--tests/data/expected-sequence.error-message1
-rw-r--r--tests/data/invalid-base64-data.error-message2
-rw-r--r--tests/data/invalid-merge-1.error-message2
-rw-r--r--tests/data/invalid-merge-2.error-message2
-rw-r--r--tests/data/invalid-omap-1.error-message3
-rw-r--r--tests/data/invalid-omap-2.error-message3
-rw-r--r--tests/data/invalid-omap-3.error-message4
-rw-r--r--tests/data/invalid-pairs-1.error-message3
-rw-r--r--tests/data/invalid-pairs-2.error-message3
-rw-r--r--tests/data/invalid-pairs-3.error-message4
-rw-r--r--tests/data/unacceptable-key.error-message4
-rw-r--r--tests/data/undefined-constructor.error-message1
-rw-r--r--tests/test_constructor.py86
-rw-r--r--tests/test_errors.py22
-rw-r--r--tests/test_yaml.py1
53 files changed, 487 insertions, 56 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..050ced2
--- /dev/null
+++ b/LICENSE
@@ -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.
diff --git a/README b/README
new file mode 100644
index 0000000..4c8431d
--- /dev/null
+++ b/README
@@ -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.
diff --git a/lib/yaml/constructor.py b/lib/yaml/constructor.py
index 1e7fea0..0660f54 100644
--- a/lib/yaml/constructor.py
+++ b/lib/yaml/constructor.py
@@ -92,23 +92,23 @@ class BaseConstructor:
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)
+ 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,
@@ -211,7 +211,7 @@ class Constructor(BaseConstructor):
value = value.replace('_', '')
sign = +1
if value[0] == '-':
- value = -1
+ sign = -1
if value[0] in '+-':
value = value[1:]
if value.lower() == '.inf':
@@ -236,23 +236,23 @@ class Constructor(BaseConstructor):
return str(value).decode('base64')
except (binascii.Error, UnicodeEncodeError), exc:
raise ConstructorError(None, None,
- "failed to decode base64 data: %s" % exc, node.start_mark)
+ "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]+)
+ (?:(?:[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),
+ (?::(?P<tz_minute>[0-9][0-9])?)?))?)?$''', re.X)
def construct_yaml_timestamp(self, node):
value = self.construct_scalar(node)
- match = self.timestamp_expr.match(node.value)
+ match = self.timestamp_regexp.match(node.value)
values = match.groupdict()
for key in values:
if values[key]:
@@ -260,7 +260,7 @@ class Constructor(BaseConstructor):
else:
values[key] = 0
fraction = values['fraction']
- if micro:
+ if fraction:
while 10*fraction < 1000000:
fraction *= 10
values['fraction'] = fraction
@@ -281,34 +281,36 @@ class Constructor(BaseConstructor):
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))
+ 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)
- omap = []
+ 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])
- omap.append((key, value))
+ 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)
@@ -349,8 +351,13 @@ Constructor.add_constructor(
Constructor.construct_yaml_float)
Constructor.add_constructor(
- u'tag:yaml.org,2002:timestamp',
- Constructor.construct_yaml_timestamp)
+ 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',
@@ -384,13 +391,13 @@ 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_class.add_constructor(cls.yaml_tag, cls.from_yaml)
+ cls.yaml_constructor.add_constructor(cls.yaml_tag, cls.from_yaml)
class YAMLObject(object):
__metaclass__ = YAMLObjectMetaclass
- yaml_constructor_class = Constructor
+ yaml_constructor = Constructor
yaml_tag = None
diff --git a/tests/data/construct-binary.code b/tests/data/construct-binary.code
new file mode 100644
index 0000000..67ac0d5
--- /dev/null
+++ b/tests/data/construct-binary.code
@@ -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.",
+}
diff --git a/tests/data/construct-binary.data b/tests/data/construct-binary.data
new file mode 100644
index 0000000..dcdb16f
--- /dev/null
+++ b/tests/data/construct-binary.data
@@ -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.
diff --git a/tests/data/construct-bool.code b/tests/data/construct-bool.code
new file mode 100644
index 0000000..389d2c0
--- /dev/null
+++ b/tests/data/construct-bool.code
@@ -0,0 +1,6 @@
+{
+ "canonical": True,
+ "answer": False,
+ "logical": True,
+ "option": True,
+}
diff --git a/tests/data/construct-bool.data b/tests/data/construct-bool.data
new file mode 100644
index 0000000..2a8f2e6
--- /dev/null
+++ b/tests/data/construct-bool.data
@@ -0,0 +1,4 @@
+canonical: y
+answer: NO
+logical: True
+option: on
diff --git a/tests/data/construct-custom.code b/tests/data/construct-custom.code
new file mode 100644
index 0000000..bcc283f
--- /dev/null
+++ b/tests/data/construct-custom.code
@@ -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),
+]
diff --git a/tests/data/construct-custom.data b/tests/data/construct-custom.data
new file mode 100644
index 0000000..053d028
--- /dev/null
+++ b/tests/data/construct-custom.data
@@ -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
diff --git a/tests/data/construct-float.code b/tests/data/construct-float.code
new file mode 100644
index 0000000..8493bf2
--- /dev/null
+++ b/tests/data/construct-float.code
@@ -0,0 +1,8 @@
+{
+ "canonical": 685230.15,
+ "exponential": 685230.15,
+ "fixed": 685230.15,
+ "sexagesimal": 685230.15,
+ "negative infinity": -1e300000,
+ "not a number": 1e300000/1e300000,
+}
diff --git a/tests/data/construct-float.data b/tests/data/construct-float.data
new file mode 100644
index 0000000..b662c62
--- /dev/null
+++ b/tests/data/construct-float.data
@@ -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
diff --git a/tests/data/construct-int.code b/tests/data/construct-int.code
new file mode 100644
index 0000000..1058f7b
--- /dev/null
+++ b/tests/data/construct-int.code
@@ -0,0 +1,8 @@
+{
+ "canonical": 685230,
+ "decimal": 685230,
+ "octal": 685230,
+ "hexadecimal": 685230,
+ "binary": 685230,
+ "sexagesimal": 685230,
+}
diff --git a/tests/data/construct-int.data b/tests/data/construct-int.data
new file mode 100644
index 0000000..852c314
--- /dev/null
+++ b/tests/data/construct-int.data
@@ -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
diff --git a/tests/data/construct-map.code b/tests/data/construct-map.code
new file mode 100644
index 0000000..736ba48
--- /dev/null
+++ b/tests/data/construct-map.code
@@ -0,0 +1,6 @@
+{
+ "Block style":
+ { "Clark" : "Evans", "Brian" : "Ingerson", "Oren" : "Ben-Kiki" },
+ "Flow style":
+ { "Clark" : "Evans", "Brian" : "Ingerson", "Oren" : "Ben-Kiki" },
+}
diff --git a/tests/data/construct-map.data b/tests/data/construct-map.data
new file mode 100644
index 0000000..022446d
--- /dev/null
+++ b/tests/data/construct-map.data
@@ -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 }
diff --git a/tests/data/construct-merge.code b/tests/data/construct-merge.code
new file mode 100644
index 0000000..6cd419d
--- /dev/null
+++ b/tests/data/construct-merge.code
@@ -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" },
+]
diff --git a/tests/data/construct-merge.data b/tests/data/construct-merge.data
new file mode 100644
index 0000000..3fdb2e2
--- /dev/null
+++ b/tests/data/construct-merge.data
@@ -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
diff --git a/tests/data/construct-null.code b/tests/data/construct-null.code
new file mode 100644
index 0000000..a895eaa
--- /dev/null
+++ b/tests/data/construct-null.code
@@ -0,0 +1,13 @@
+[
+ None,
+ { "empty": None, "canonical": None, "english": None, None: "null key" },
+ {
+ "sparse": [
+ None,
+ "2nd entry",
+ None,
+ "4th entry",
+ None,
+ ],
+ },
+]
diff --git a/tests/data/construct-null.data b/tests/data/construct-null.data
new file mode 100644
index 0000000..9ad0344
--- /dev/null
+++ b/tests/data/construct-null.data
@@ -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
diff --git a/tests/data/construct-omap.code b/tests/data/construct-omap.code
new file mode 100644
index 0000000..f4cf1b8
--- /dev/null
+++ b/tests/data/construct-omap.code
@@ -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) ],
+}
diff --git a/tests/data/construct-omap.data b/tests/data/construct-omap.data
new file mode 100644
index 0000000..4fa0f45
--- /dev/null
+++ b/tests/data/construct-omap.data
@@ -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 ]
diff --git a/tests/data/construct-pairs.code b/tests/data/construct-pairs.code
new file mode 100644
index 0000000..64f86ee
--- /dev/null
+++ b/tests/data/construct-pairs.code
@@ -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") ],
+}
diff --git a/tests/data/construct-pairs.data b/tests/data/construct-pairs.data
new file mode 100644
index 0000000..05f55b9
--- /dev/null
+++ b/tests/data/construct-pairs.data
@@ -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 ]
diff --git a/tests/data/construct-seq.code b/tests/data/construct-seq.code
new file mode 100644
index 0000000..0c90c05
--- /dev/null
+++ b/tests/data/construct-seq.code
@@ -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"],
+}
diff --git a/tests/data/construct-seq.data b/tests/data/construct-seq.data
new file mode 100644
index 0000000..bb92fd1
--- /dev/null
+++ b/tests/data/construct-seq.data
@@ -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
+
diff --git a/tests/data/construct-set.code b/tests/data/construct-set.code
new file mode 100644
index 0000000..aa090e8
--- /dev/null
+++ b/tests/data/construct-set.code
@@ -0,0 +1,4 @@
+{
+ "baseball players": set(["Mark McGwire", "Sammy Sosa", "Ken Griffey"]),
+ "baseball teams": set(["Boston Red Sox", "Detroit Tigers", "New York Yankees"]),
+}
diff --git a/tests/data/construct-set.data b/tests/data/construct-set.data
new file mode 100644
index 0000000..e05dc88
--- /dev/null
+++ b/tests/data/construct-set.data
@@ -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 }
diff --git a/tests/data/construct-str.code b/tests/data/construct-str.code
new file mode 100644
index 0000000..8d57214
--- /dev/null
+++ b/tests/data/construct-str.code
@@ -0,0 +1 @@
+{ "string": "abcd" }
diff --git a/tests/data/construct-str.data b/tests/data/construct-str.data
new file mode 100644
index 0000000..606ac6b
--- /dev/null
+++ b/tests/data/construct-str.data
@@ -0,0 +1 @@
+string: abcd
diff --git a/tests/data/construct-timestamp.code b/tests/data/construct-timestamp.code
new file mode 100644
index 0000000..288022e
--- /dev/null
+++ b/tests/data/construct-timestamp.code
@@ -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),
+}
diff --git a/tests/data/construct-timestamp.data b/tests/data/construct-timestamp.data
new file mode 100644
index 0000000..c5f3840
--- /dev/null
+++ b/tests/data/construct-timestamp.data
@@ -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
diff --git a/tests/data/construct-value.code b/tests/data/construct-value.code
new file mode 100644
index 0000000..f1f015e
--- /dev/null
+++ b/tests/data/construct-value.code
@@ -0,0 +1,9 @@
+[
+ { "link with": [ "library1.dll", "library2.dll" ] },
+ {
+ "link with": [
+ { "=": "library1.dll", "version": 1.2 },
+ { "=": "library2.dll", "version": 2.3 },
+ ],
+ },
+]
diff --git a/tests/data/construct-value.data b/tests/data/construct-value.data
new file mode 100644
index 0000000..3eb7919
--- /dev/null
+++ b/tests/data/construct-value.data
@@ -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
diff --git a/tests/data/duplicate-key.error-message b/tests/data/duplicate-key.error-message
new file mode 100644
index 0000000..84deb8f
--- /dev/null
+++ b/tests/data/duplicate-key.error-message
@@ -0,0 +1,3 @@
+---
+foo: bar
+foo: baz
diff --git a/tests/data/duplicate-merge-key.error-message b/tests/data/duplicate-merge-key.error-message
new file mode 100644
index 0000000..cebc3a1
--- /dev/null
+++ b/tests/data/duplicate-merge-key.error-message
@@ -0,0 +1,4 @@
+---
+<<: {x: 1, y: 2}
+foo: bar
+<<: {z: 3, t: 4}
diff --git a/tests/data/duplicate-value-key.error-message b/tests/data/duplicate-value-key.error-message
new file mode 100644
index 0000000..b34a1d6
--- /dev/null
+++ b/tests/data/duplicate-value-key.error-message
@@ -0,0 +1,4 @@
+---
+=: 1
+foo: bar
+=: 2
diff --git a/tests/data/expected-mapping.error-message b/tests/data/expected-mapping.error-message
new file mode 100644
index 0000000..82aed98
--- /dev/null
+++ b/tests/data/expected-mapping.error-message
@@ -0,0 +1 @@
+--- !!map [not, a, map]
diff --git a/tests/data/expected-scalar.error-message b/tests/data/expected-scalar.error-message
new file mode 100644
index 0000000..7b3171e
--- /dev/null
+++ b/tests/data/expected-scalar.error-message
@@ -0,0 +1 @@
+--- !!str [not a scalar]
diff --git a/tests/data/expected-sequence.error-message b/tests/data/expected-sequence.error-message
new file mode 100644
index 0000000..08074ea
--- /dev/null
+++ b/tests/data/expected-sequence.error-message
@@ -0,0 +1 @@
+--- !!seq {foo, bar, baz}
diff --git a/tests/data/invalid-base64-data.error-message b/tests/data/invalid-base64-data.error-message
new file mode 100644
index 0000000..798abba
--- /dev/null
+++ b/tests/data/invalid-base64-data.error-message
@@ -0,0 +1,2 @@
+--- !!binary
+ binary data encoded in base64 should be here.
diff --git a/tests/data/invalid-merge-1.error-message b/tests/data/invalid-merge-1.error-message
new file mode 100644
index 0000000..fc3c284
--- /dev/null
+++ b/tests/data/invalid-merge-1.error-message
@@ -0,0 +1,2 @@
+foo: bar
+<<: baz
diff --git a/tests/data/invalid-merge-2.error-message b/tests/data/invalid-merge-2.error-message
new file mode 100644
index 0000000..8e88615
--- /dev/null
+++ b/tests/data/invalid-merge-2.error-message
@@ -0,0 +1,2 @@
+foo: bar
+<<: [x: 1, y: 2, z, t: 4]
diff --git a/tests/data/invalid-omap-1.error-message b/tests/data/invalid-omap-1.error-message
new file mode 100644
index 0000000..2863392
--- /dev/null
+++ b/tests/data/invalid-omap-1.error-message
@@ -0,0 +1,3 @@
+--- !!omap
+foo: bar
+baz: bat
diff --git a/tests/data/invalid-omap-2.error-message b/tests/data/invalid-omap-2.error-message
new file mode 100644
index 0000000..c377dfb
--- /dev/null
+++ b/tests/data/invalid-omap-2.error-message
@@ -0,0 +1,3 @@
+--- !!omap
+- foo: bar
+- baz
diff --git a/tests/data/invalid-omap-3.error-message b/tests/data/invalid-omap-3.error-message
new file mode 100644
index 0000000..2a4f50d
--- /dev/null
+++ b/tests/data/invalid-omap-3.error-message
@@ -0,0 +1,4 @@
+--- !!omap
+- foo: bar
+- baz: bar
+ bar: bar
diff --git a/tests/data/invalid-pairs-1.error-message b/tests/data/invalid-pairs-1.error-message
new file mode 100644
index 0000000..42d19ae
--- /dev/null
+++ b/tests/data/invalid-pairs-1.error-message
@@ -0,0 +1,3 @@
+--- !!pairs
+foo: bar
+baz: bat
diff --git a/tests/data/invalid-pairs-2.error-message b/tests/data/invalid-pairs-2.error-message
new file mode 100644
index 0000000..31389ea
--- /dev/null
+++ b/tests/data/invalid-pairs-2.error-message
@@ -0,0 +1,3 @@
+--- !!pairs
+- foo: bar
+- baz
diff --git a/tests/data/invalid-pairs-3.error-message b/tests/data/invalid-pairs-3.error-message
new file mode 100644
index 0000000..f8d7704
--- /dev/null
+++ b/tests/data/invalid-pairs-3.error-message
@@ -0,0 +1,4 @@
+--- !!pairs
+- foo: bar
+- baz: bar
+ bar: bar
diff --git a/tests/data/unacceptable-key.error-message b/tests/data/unacceptable-key.error-message
new file mode 100644
index 0000000..d748e37
--- /dev/null
+++ b/tests/data/unacceptable-key.error-message
@@ -0,0 +1,4 @@
+---
+? - foo
+ - bar
+: baz
diff --git a/tests/data/undefined-constructor.error-message b/tests/data/undefined-constructor.error-message
new file mode 100644
index 0000000..9a37ccc
--- /dev/null
+++ b/tests/data/undefined-constructor.error-message
@@ -0,0 +1 @@
+--- !foo bar
diff --git a/tests/test_constructor.py b/tests/test_constructor.py
new file mode 100644
index 0000000..e3895fa
--- /dev/null
+++ b/tests/test_constructor.py
@@ -0,0 +1,86 @@
+
+import test_appliance
+try:
+ import datetime
+except ImportError:
+ pass
+
+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')
+
diff --git a/tests/test_errors.py b/tests/test_errors.py
index 43834cb..74ba9f2 100644
--- a/tests/test_errors.py
+++ b/tests/test_errors.py
@@ -1,12 +1,7 @@
import test_appliance
-from yaml.error import YAMLError
-from yaml.reader import *
-from yaml.scanner import *
-from yaml.parser import *
-from yaml.composer import *
-from yaml.resolver import *
+from yaml import *
class TestErrors(test_appliance.TestAppliance):
@@ -25,7 +20,8 @@ class TestErrors(test_appliance.TestAppliance):
parser = Parser(scanner)
composer = Composer(parser)
resolver = Resolver(composer)
- return list(composer)
+ constructor = Constructor(resolver)
+ return list(constructor)
except YAMLError, exc:
#except ScannerError, exc:
#except ParserError, exc:
@@ -41,14 +37,16 @@ class TestErrors(test_appliance.TestAppliance):
parser = Parser(scanner)
composer = Composer(parser)
resolver = Resolver(composer)
- return list(composer)
- except YAMLError, exc:
+ constructor = Constructor(resolver)
+ return list(constructor)
+ #except YAMLError, exc:
#except ScannerError, exc:
#except ParserError, exc:
#except ComposerError, exc:
- #print '.'*70
- #print "%s:" % filename
- #print "%s:" % exc.__class__.__name__, exc
+ except ConstructorError, exc:
+ print '.'*70
+ print "%s:" % filename
+ print "%s:" % exc.__class__.__name__, exc
raise
TestErrors.add_tests('testErrors', '.error-message')
diff --git a/tests/test_yaml.py b/tests/test_yaml.py
index ccdd8d5..cfd4e79 100644
--- a/tests/test_yaml.py
+++ b/tests/test_yaml.py
@@ -8,6 +8,7 @@ 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__'):