From 5142aa8360bc5cb03c18d0a4ea86abcd087d1b6b Mon Sep 17 00:00:00 2001 From: xi Date: Sat, 25 Feb 2006 16:08:26 +0000 Subject: Ready for the initial release. git-svn-id: http://svn.pyyaml.org/branches/pyyaml3000@58 18f92427-320e-0410-9341-c67f048884a3 --- LICENSE | 19 ++++++ README | 11 +++ lib/yaml/constructor.py | 95 ++++++++++++++------------ tests/data/construct-binary.code | 7 ++ tests/data/construct-binary.data | 12 ++++ tests/data/construct-bool.code | 6 ++ tests/data/construct-bool.data | 4 ++ tests/data/construct-custom.code | 9 +++ tests/data/construct-custom.data | 23 +++++++ tests/data/construct-float.code | 8 +++ tests/data/construct-float.data | 6 ++ tests/data/construct-int.code | 8 +++ tests/data/construct-int.data | 6 ++ tests/data/construct-map.code | 6 ++ tests/data/construct-map.data | 6 ++ tests/data/construct-merge.code | 10 +++ tests/data/construct-merge.data | 27 ++++++++ tests/data/construct-null.code | 13 ++++ tests/data/construct-null.data | 18 +++++ tests/data/construct-omap.code | 8 +++ tests/data/construct-omap.data | 8 +++ tests/data/construct-pairs.code | 9 +++ tests/data/construct-pairs.data | 7 ++ tests/data/construct-seq.code | 4 ++ tests/data/construct-seq.data | 15 ++++ tests/data/construct-set.code | 4 ++ tests/data/construct-set.data | 7 ++ tests/data/construct-str.code | 1 + tests/data/construct-str.data | 1 + tests/data/construct-timestamp.code | 7 ++ tests/data/construct-timestamp.data | 5 ++ tests/data/construct-value.code | 9 +++ tests/data/construct-value.data | 10 +++ tests/data/duplicate-key.error-message | 3 + tests/data/duplicate-merge-key.error-message | 4 ++ tests/data/duplicate-value-key.error-message | 4 ++ tests/data/expected-mapping.error-message | 1 + tests/data/expected-scalar.error-message | 1 + tests/data/expected-sequence.error-message | 1 + tests/data/invalid-base64-data.error-message | 2 + tests/data/invalid-merge-1.error-message | 2 + tests/data/invalid-merge-2.error-message | 2 + tests/data/invalid-omap-1.error-message | 3 + tests/data/invalid-omap-2.error-message | 3 + tests/data/invalid-omap-3.error-message | 4 ++ tests/data/invalid-pairs-1.error-message | 3 + tests/data/invalid-pairs-2.error-message | 3 + tests/data/invalid-pairs-3.error-message | 4 ++ tests/data/unacceptable-key.error-message | 4 ++ tests/data/undefined-constructor.error-message | 1 + tests/test_constructor.py | 86 +++++++++++++++++++++++ tests/test_errors.py | 22 +++--- tests/test_yaml.py | 1 + 53 files changed, 487 insertions(+), 56 deletions(-) create mode 100644 LICENSE create mode 100644 README create mode 100644 tests/data/construct-binary.code create mode 100644 tests/data/construct-binary.data create mode 100644 tests/data/construct-bool.code create mode 100644 tests/data/construct-bool.data create mode 100644 tests/data/construct-custom.code create mode 100644 tests/data/construct-custom.data create mode 100644 tests/data/construct-float.code create mode 100644 tests/data/construct-float.data create mode 100644 tests/data/construct-int.code create mode 100644 tests/data/construct-int.data create mode 100644 tests/data/construct-map.code create mode 100644 tests/data/construct-map.data create mode 100644 tests/data/construct-merge.code create mode 100644 tests/data/construct-merge.data create mode 100644 tests/data/construct-null.code create mode 100644 tests/data/construct-null.data create mode 100644 tests/data/construct-omap.code create mode 100644 tests/data/construct-omap.data create mode 100644 tests/data/construct-pairs.code create mode 100644 tests/data/construct-pairs.data create mode 100644 tests/data/construct-seq.code create mode 100644 tests/data/construct-seq.data create mode 100644 tests/data/construct-set.code create mode 100644 tests/data/construct-set.data create mode 100644 tests/data/construct-str.code create mode 100644 tests/data/construct-str.data create mode 100644 tests/data/construct-timestamp.code create mode 100644 tests/data/construct-timestamp.data create mode 100644 tests/data/construct-value.code create mode 100644 tests/data/construct-value.data create mode 100644 tests/data/duplicate-key.error-message create mode 100644 tests/data/duplicate-merge-key.error-message create mode 100644 tests/data/duplicate-value-key.error-message create mode 100644 tests/data/expected-mapping.error-message create mode 100644 tests/data/expected-scalar.error-message create mode 100644 tests/data/expected-sequence.error-message create mode 100644 tests/data/invalid-base64-data.error-message create mode 100644 tests/data/invalid-merge-1.error-message create mode 100644 tests/data/invalid-merge-2.error-message create mode 100644 tests/data/invalid-omap-1.error-message create mode 100644 tests/data/invalid-omap-2.error-message create mode 100644 tests/data/invalid-omap-3.error-message create mode 100644 tests/data/invalid-pairs-1.error-message create mode 100644 tests/data/invalid-pairs-2.error-message create mode 100644 tests/data/invalid-pairs-3.error-message create mode 100644 tests/data/unacceptable-key.error-message create mode 100644 tests/data/undefined-constructor.error-message create mode 100644 tests/test_constructor.py 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 . 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[0-9][0-9][0-9][0-9]) -(?P[0-9][0-9]?) -(?P[0-9][0-9]?) - (?:[Tt]|[ \t]+) + (?:(?:[Tt]|[ \t]+) (?P[0-9][0-9]?) :(?P[0-9][0-9]) :(?P[0-9][0-9]) (?:\.(?P[0-9]*))? (?:[ \t]*(?:Z|(?P[-+][0-9][0-9]?) - (?::(?P[0-9][0-9])?)))?$''', re.X), + (?::(?P[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__'): -- cgit v1.2.1