summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2014-11-23 11:31:53 +0100
committerAnthon van der Neut <anthon@mnt.org>2014-11-23 11:31:53 +0100
commitd709fb8be80a54e793f7eb5a148cd1fa5103933c (patch)
treee50bc28652738b8d7940b85eb90d2fd828dde932
parent259d7c875079984ed502912fe77868f5b435e36b (diff)
downloadruamel.yaml-d709fb8be80a54e793f7eb5a148cd1fa5103933c.tar.gz
- change install so that you can include ruamel.yaml instead of ruamel.yaml.py
- add "yaml" utility with initial subcommands (test rt, from json)
-rw-r--r--README.rst16
-rw-r--r--__init__.py373
-rw-r--r--py/__init__.py371
-rw-r--r--py/representer.py1
-rw-r--r--py/yaml.py145
-rw-r--r--setup.py20
-rw-r--r--test/lib/canonical.py8
-rw-r--r--test/lib/test_appliance.py2
-rw-r--r--test/lib/test_constructor.py4
-rw-r--r--test/lib/test_input_output.py2
-rw-r--r--test/lib/test_mark.py2
-rw-r--r--test/lib/test_reader.py4
-rw-r--r--test/lib/test_resolver.py2
-rw-r--r--test/lib/test_structure.py2
-rw-r--r--test/lib/test_tokens.py2
-rw-r--r--test/roundtrip.py6
-rw-r--r--test/test_z_data.py5
-rw-r--r--yaml.py68
18 files changed, 559 insertions, 474 deletions
diff --git a/README.rst b/README.rst
index fcfa9a0..267647e 100644
--- a/README.rst
+++ b/README.rst
@@ -4,7 +4,7 @@ ruamel.yaml
``ruamel.yaml`` is a YAML package for Python. It is a derivative
of Kirill Simonov's `PyYAML 3.11 <https://bitbucket.org/xi/pyyaml>`_
-which is a YAML1.1
+which supports YAML1.1
Major differences with PyYAML 3.11:
@@ -38,7 +38,7 @@ comments, there are no libraries that support round trip updating of
such commented files.
INI files support comments, and the excellent `ConfigObj
-<http://www.voidspace.org.uk/python/configobj.html>` library by Foord
+<http://www.voidspace.org.uk/python/configobj.html>`_ library by Foord
and Larosa even supports round trip editing with comment preservation,
nesting of sections and limited lists (within a value). Retrieval of
particular value format is explicit (and extensible).
@@ -53,3 +53,15 @@ format. By extending the Python YAML parser to support round trip
preservation of comments, it makes YAML a very good choice for
configuration files that are human readable and editable while at
the same time interpretable and modifiable by a program.
+
+yaml utlity
+===========
+
+A utility name ``yaml`` is included and allows for basic operations on files:
+
+- ``yaml round-trip <file_name>`` for basic roundtrip testing of YAML
+ files
+- ``yaml json <file_name>`` for conversion of JSON file(s) to a single
+ YAML block style document
+
+See ``yaml --help`` for more information on the availble commands
diff --git a/__init__.py b/__init__.py
deleted file mode 100644
index 5170c03..0000000
--- a/__init__.py
+++ /dev/null
@@ -1,373 +0,0 @@
-# coding: utf-8
-
-from __future__ import absolute_import
-
-
-def _convert_version(tup):
- """create a PEP 386 pseudo-format conformant string from tuple tup"""
- ret_val = str(tup[0]) # first is always digit
- next_sep = "." # separator for next extension, can be "" or "."
- for x in tup[1:]:
- if isinstance(x, int):
- ret_val += next_sep + str(x)
- next_sep = '.'
- continue
- first_letter = x[0].lower()
- next_sep = ''
- if first_letter in 'abcr':
- ret_val += 'rc' if first_letter == 'r' else first_letter
- elif first_letter in 'pd':
- ret_val += '.post' if first_letter == 'p' else '.dev'
- return ret_val
-
-
-version_info = (0, 1)
-__version__ = _convert_version(version_info)
-
-del _convert_version
-
-
-
-from ruamel.yaml.py.error import *
-
-from ruamel.yaml.py.tokens import *
-from ruamel.yaml.py.events import *
-from ruamel.yaml.py.nodes import *
-
-from ruamel.yaml.py.loader import *
-from ruamel.yaml.py.dumper import *
-from ruamel.yaml.py.compat import StringIO, BytesIO, with_metaclass, PY3
-
-try:
- from .cyaml import *
- __with_libyaml__ = True
-except ImportError:
- __with_libyaml__ = False
-
-import io
-
-
-def scan(stream, Loader=Loader):
- """
- Scan a YAML stream and produce scanning tokens.
- """
- loader = Loader(stream)
- try:
- while loader.check_token():
- yield loader.get_token()
- finally:
- loader.dispose()
-
-
-def parse(stream, Loader=Loader):
- """
- Parse a YAML stream and produce parsing events.
- """
- loader = Loader(stream)
- try:
- while loader.check_event():
- yield loader.get_event()
- finally:
- loader.dispose()
-
-
-def compose(stream, Loader=Loader):
- """
- Parse the first YAML document in a stream
- and produce the corresponding representation tree.
- """
- loader = Loader(stream)
- try:
- return loader.get_single_node()
- finally:
- loader.dispose()
-
-
-def compose_all(stream, Loader=Loader):
- """
- Parse all YAML documents in a stream
- and produce corresponding representation trees.
- """
- loader = Loader(stream)
- try:
- while loader.check_node():
- yield loader.get_node()
- finally:
- loader.dispose()
-
-
-def load(stream, Loader=Loader):
- """
- Parse the first YAML document in a stream
- and produce the corresponding Python object.
- """
- loader = Loader(stream)
- try:
- return loader.get_single_data()
- finally:
- loader.dispose()
-
-
-def load_all(stream, Loader=Loader):
- """
- Parse all YAML documents in a stream
- and produce corresponding Python objects.
- """
- loader = Loader(stream)
- try:
- while loader.check_data():
- yield loader.get_data()
- finally:
- loader.dispose()
-
-
-def safe_load(stream):
- """
- Parse the first YAML document in a stream
- and produce the corresponding Python object.
- Resolve only basic YAML tags.
- """
- return load(stream, SafeLoader)
-
-
-def safe_load_all(stream):
- """
- Parse all YAML documents in a stream
- and produce corresponding Python objects.
- Resolve only basic YAML tags.
- """
- return load_all(stream, SafeLoader)
-
-
-def emit(events, stream=None, Dumper=Dumper,
- canonical=None, indent=None, width=None,
- allow_unicode=None, line_break=None):
- """
- Emit YAML parsing events into a stream.
- If stream is None, return the produced string instead.
- """
- getvalue = None
- if stream is None:
- stream = StringIO()
- getvalue = stream.getvalue
- dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
- allow_unicode=allow_unicode, line_break=line_break)
- try:
- for event in events:
- dumper.emit(event)
- finally:
- dumper.dispose()
- if getvalue:
- return getvalue()
-
-enc = None if PY3 else 'utf-8'
-
-
-def serialize_all(nodes, stream=None, Dumper=Dumper,
- canonical=None, indent=None, width=None,
- allow_unicode=None, line_break=None,
- encoding=enc, explicit_start=None, explicit_end=None,
- version=None, tags=None):
- """
- Serialize a sequence of representation trees into a YAML stream.
- If stream is None, return the produced string instead.
- """
- getvalue = None
- if stream is None:
- if encoding is None:
- stream = StringIO()
- else:
- stream = BytesIO()
- getvalue = stream.getvalue
- dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
- allow_unicode=allow_unicode, line_break=line_break,
- encoding=encoding, version=version, tags=tags,
- explicit_start=explicit_start, explicit_end=explicit_end)
- try:
- dumper.open()
- for node in nodes:
- dumper.serialize(node)
- dumper.close()
- finally:
- dumper.dispose()
- if getvalue:
- return getvalue()
-
-
-def serialize(node, stream=None, Dumper=Dumper, **kwds):
- """
- Serialize a representation tree into a YAML stream.
- If stream is None, return the produced string instead.
- """
- return serialize_all([node], stream, Dumper=Dumper, **kwds)
-
-
-def dump_all(documents, stream=None, Dumper=Dumper,
- default_style=None, default_flow_style=None,
- canonical=None, indent=None, width=None,
- allow_unicode=None, line_break=None,
- encoding=enc, explicit_start=None, explicit_end=None,
- version=None, tags=None):
- """
- Serialize a sequence of Python objects into a YAML stream.
- If stream is None, return the produced string instead.
- """
- getvalue = None
- if stream is None:
- if encoding is None:
- stream = StringIO()
- else:
- stream = BytesIO()
- getvalue = stream.getvalue
- dumper = Dumper(stream, default_style=default_style,
- default_flow_style=default_flow_style,
- canonical=canonical, indent=indent, width=width,
- allow_unicode=allow_unicode, line_break=line_break,
- encoding=encoding, version=version, tags=tags,
- explicit_start=explicit_start, explicit_end=explicit_end)
- try:
- dumper.open()
- for data in documents:
- dumper.represent(data)
- dumper.close()
- finally:
- dumper.dispose()
- if getvalue:
- return getvalue()
-
-
-def dump(data, stream=None, Dumper=Dumper, **kwds):
- """
- Serialize a Python object into a YAML stream.
- If stream is None, return the produced string instead.
- """
- return dump_all([data], stream, Dumper=Dumper, **kwds)
-
-
-def safe_dump_all(documents, stream=None, **kwds):
- """
- Serialize a sequence of Python objects into a YAML stream.
- Produce only basic YAML tags.
- If stream is None, return the produced string instead.
- """
- return dump_all(documents, stream, Dumper=SafeDumper, **kwds)
-
-
-def safe_dump(data, stream=None, **kwds):
- """
- Serialize a Python object into a YAML stream.
- Produce only basic YAML tags.
- If stream is None, return the produced string instead.
- """
- return dump_all([data], stream, Dumper=SafeDumper, **kwds)
-
-
-def add_implicit_resolver(tag, regexp, first=None,
- Loader=Loader, Dumper=Dumper):
- """
- Add an implicit scalar detector.
- If an implicit scalar value matches the given regexp,
- the corresponding tag is assigned to the scalar.
- first is a sequence of possible initial characters or None.
- """
- Loader.add_implicit_resolver(tag, regexp, first)
- Dumper.add_implicit_resolver(tag, regexp, first)
-
-
-def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper):
- """
- Add a path based resolver for the given tag.
- A path is a list of keys that forms a path
- to a node in the representation tree.
- Keys can be string values, integers, or None.
- """
- Loader.add_path_resolver(tag, path, kind)
- Dumper.add_path_resolver(tag, path, kind)
-
-
-def add_constructor(tag, constructor, Loader=Loader):
- """
- Add a constructor for the given tag.
- Constructor is a function that accepts a Loader instance
- and a node object and produces the corresponding Python object.
- """
- Loader.add_constructor(tag, constructor)
-
-
-def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader):
- """
- Add a multi-constructor for the given tag prefix.
- Multi-constructor is called for a node if its tag starts with tag_prefix.
- Multi-constructor accepts a Loader instance, a tag suffix,
- and a node object and produces the corresponding Python object.
- """
- Loader.add_multi_constructor(tag_prefix, multi_constructor)
-
-
-def add_representer(data_type, representer, Dumper=Dumper):
- """
- Add a representer for the given type.
- Representer is a function accepting a Dumper instance
- and an instance of the given data type
- and producing the corresponding representation node.
- """
- Dumper.add_representer(data_type, representer)
-
-
-def add_multi_representer(data_type, multi_representer, Dumper=Dumper):
- """
- Add a representer for the given type.
- Multi-representer is a function accepting a Dumper instance
- and an instance of the given data type or subtype
- and producing the corresponding representation node.
- """
- Dumper.add_multi_representer(data_type, multi_representer)
-
-
-class YAMLObjectMetaclass(type):
- """
- The metaclass for YAMLObject.
- """
- 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_loader.add_constructor(cls.yaml_tag, cls.from_yaml)
- cls.yaml_dumper.add_representer(cls, cls.to_yaml)
-
-
-class YAMLObject(with_metaclass(YAMLObjectMetaclass)):
- """
- An object that can dump itself to a YAML stream
- and load itself from a YAML stream.
- """
- __slots__ = () # no direct instantiation, so allow immutable subclasses
-
- yaml_loader = Loader
- yaml_dumper = Dumper
-
- yaml_tag = None
- yaml_flow_style = None
-
- @classmethod
- def from_yaml(cls, loader, node):
- """
- Convert a representation node to a Python object.
- """
- return loader.construct_yaml_object(node, cls)
-
- @classmethod
- def to_yaml(cls, dumper, data):
- """
- Convert a Python object to a representation node.
- """
- return dumper.represent_yaml_object(cls.yaml_tag, data, cls,
- flow_style=cls.yaml_flow_style)
-
-
-
-def main():
- # No direct import of yaml in order not to pollute namespace.
- # If other utility 'bodies' exist in this directory a module level
- # import here, would get you all of its initialisations/imports as well
- from yaml import main as util_main
- util_main()
diff --git a/py/__init__.py b/py/__init__.py
index e69de29..23137d3 100644
--- a/py/__init__.py
+++ b/py/__init__.py
@@ -0,0 +1,371 @@
+# coding: utf-8
+
+from __future__ import absolute_import
+
+
+def _convert_version(tup):
+ """create a PEP 386 pseudo-format conformant string from tuple tup"""
+ ret_val = str(tup[0]) # first is always digit
+ next_sep = "." # separator for next extension, can be "" or "."
+ for x in tup[1:]:
+ if isinstance(x, int):
+ ret_val += next_sep + str(x)
+ next_sep = '.'
+ continue
+ first_letter = x[0].lower()
+ next_sep = ''
+ if first_letter in 'abcr':
+ ret_val += 'rc' if first_letter == 'r' else first_letter
+ elif first_letter in 'pd':
+ ret_val += '.post' if first_letter == 'p' else '.dev'
+ return ret_val
+
+
+version_info = (0, 2)
+__version__ = _convert_version(version_info)
+
+del _convert_version
+
+
+from ruamel.yaml.error import *
+
+from ruamel.yaml.tokens import *
+from ruamel.yaml.events import *
+from ruamel.yaml.nodes import *
+
+from ruamel.yaml.loader import *
+from ruamel.yaml.dumper import *
+from ruamel.yaml.compat import StringIO, BytesIO, with_metaclass, PY3
+
+try:
+ from .cyaml import *
+ __with_libyaml__ = True
+except ImportError:
+ __with_libyaml__ = False
+
+import io
+
+
+def scan(stream, Loader=Loader):
+ """
+ Scan a YAML stream and produce scanning tokens.
+ """
+ loader = Loader(stream)
+ try:
+ while loader.check_token():
+ yield loader.get_token()
+ finally:
+ loader.dispose()
+
+
+def parse(stream, Loader=Loader):
+ """
+ Parse a YAML stream and produce parsing events.
+ """
+ loader = Loader(stream)
+ try:
+ while loader.check_event():
+ yield loader.get_event()
+ finally:
+ loader.dispose()
+
+
+def compose(stream, Loader=Loader):
+ """
+ Parse the first YAML document in a stream
+ and produce the corresponding representation tree.
+ """
+ loader = Loader(stream)
+ try:
+ return loader.get_single_node()
+ finally:
+ loader.dispose()
+
+
+def compose_all(stream, Loader=Loader):
+ """
+ Parse all YAML documents in a stream
+ and produce corresponding representation trees.
+ """
+ loader = Loader(stream)
+ try:
+ while loader.check_node():
+ yield loader.get_node()
+ finally:
+ loader.dispose()
+
+
+def load(stream, Loader=Loader):
+ """
+ Parse the first YAML document in a stream
+ and produce the corresponding Python object.
+ """
+ loader = Loader(stream)
+ try:
+ return loader.get_single_data()
+ finally:
+ loader.dispose()
+
+
+def load_all(stream, Loader=Loader):
+ """
+ Parse all YAML documents in a stream
+ and produce corresponding Python objects.
+ """
+ loader = Loader(stream)
+ try:
+ while loader.check_data():
+ yield loader.get_data()
+ finally:
+ loader.dispose()
+
+
+def safe_load(stream):
+ """
+ Parse the first YAML document in a stream
+ and produce the corresponding Python object.
+ Resolve only basic YAML tags.
+ """
+ return load(stream, SafeLoader)
+
+
+def safe_load_all(stream):
+ """
+ Parse all YAML documents in a stream
+ and produce corresponding Python objects.
+ Resolve only basic YAML tags.
+ """
+ return load_all(stream, SafeLoader)
+
+
+def emit(events, stream=None, Dumper=Dumper,
+ canonical=None, indent=None, width=None,
+ allow_unicode=None, line_break=None):
+ """
+ Emit YAML parsing events into a stream.
+ If stream is None, return the produced string instead.
+ """
+ getvalue = None
+ if stream is None:
+ stream = StringIO()
+ getvalue = stream.getvalue
+ dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
+ allow_unicode=allow_unicode, line_break=line_break)
+ try:
+ for event in events:
+ dumper.emit(event)
+ finally:
+ dumper.dispose()
+ if getvalue:
+ return getvalue()
+
+enc = None if PY3 else 'utf-8'
+
+
+def serialize_all(nodes, stream=None, Dumper=Dumper,
+ canonical=None, indent=None, width=None,
+ allow_unicode=None, line_break=None,
+ encoding=enc, explicit_start=None, explicit_end=None,
+ version=None, tags=None):
+ """
+ Serialize a sequence of representation trees into a YAML stream.
+ If stream is None, return the produced string instead.
+ """
+ getvalue = None
+ if stream is None:
+ if encoding is None:
+ stream = StringIO()
+ else:
+ stream = BytesIO()
+ getvalue = stream.getvalue
+ dumper = Dumper(stream, canonical=canonical, indent=indent, width=width,
+ allow_unicode=allow_unicode, line_break=line_break,
+ encoding=encoding, version=version, tags=tags,
+ explicit_start=explicit_start, explicit_end=explicit_end)
+ try:
+ dumper.open()
+ for node in nodes:
+ dumper.serialize(node)
+ dumper.close()
+ finally:
+ dumper.dispose()
+ if getvalue:
+ return getvalue()
+
+
+def serialize(node, stream=None, Dumper=Dumper, **kwds):
+ """
+ Serialize a representation tree into a YAML stream.
+ If stream is None, return the produced string instead.
+ """
+ return serialize_all([node], stream, Dumper=Dumper, **kwds)
+
+
+def dump_all(documents, stream=None, Dumper=Dumper,
+ default_style=None, default_flow_style=None,
+ canonical=None, indent=None, width=None,
+ allow_unicode=None, line_break=None,
+ encoding=enc, explicit_start=None, explicit_end=None,
+ version=None, tags=None):
+ """
+ Serialize a sequence of Python objects into a YAML stream.
+ If stream is None, return the produced string instead.
+ """
+ getvalue = None
+ if stream is None:
+ if encoding is None:
+ stream = StringIO()
+ else:
+ stream = BytesIO()
+ getvalue = stream.getvalue
+ dumper = Dumper(stream, default_style=default_style,
+ default_flow_style=default_flow_style,
+ canonical=canonical, indent=indent, width=width,
+ allow_unicode=allow_unicode, line_break=line_break,
+ encoding=encoding, version=version, tags=tags,
+ explicit_start=explicit_start, explicit_end=explicit_end)
+ try:
+ dumper.open()
+ for data in documents:
+ dumper.represent(data)
+ dumper.close()
+ finally:
+ dumper.dispose()
+ if getvalue:
+ return getvalue()
+
+
+def dump(data, stream=None, Dumper=Dumper, **kwds):
+ """
+ Serialize a Python object into a YAML stream.
+ If stream is None, return the produced string instead.
+ """
+ return dump_all([data], stream, Dumper=Dumper, **kwds)
+
+
+def safe_dump_all(documents, stream=None, **kwds):
+ """
+ Serialize a sequence of Python objects into a YAML stream.
+ Produce only basic YAML tags.
+ If stream is None, return the produced string instead.
+ """
+ return dump_all(documents, stream, Dumper=SafeDumper, **kwds)
+
+
+def safe_dump(data, stream=None, **kwds):
+ """
+ Serialize a Python object into a YAML stream.
+ Produce only basic YAML tags.
+ If stream is None, return the produced string instead.
+ """
+ return dump_all([data], stream, Dumper=SafeDumper, **kwds)
+
+
+def add_implicit_resolver(tag, regexp, first=None,
+ Loader=Loader, Dumper=Dumper):
+ """
+ Add an implicit scalar detector.
+ If an implicit scalar value matches the given regexp,
+ the corresponding tag is assigned to the scalar.
+ first is a sequence of possible initial characters or None.
+ """
+ Loader.add_implicit_resolver(tag, regexp, first)
+ Dumper.add_implicit_resolver(tag, regexp, first)
+
+
+def add_path_resolver(tag, path, kind=None, Loader=Loader, Dumper=Dumper):
+ """
+ Add a path based resolver for the given tag.
+ A path is a list of keys that forms a path
+ to a node in the representation tree.
+ Keys can be string values, integers, or None.
+ """
+ Loader.add_path_resolver(tag, path, kind)
+ Dumper.add_path_resolver(tag, path, kind)
+
+
+def add_constructor(tag, constructor, Loader=Loader):
+ """
+ Add a constructor for the given tag.
+ Constructor is a function that accepts a Loader instance
+ and a node object and produces the corresponding Python object.
+ """
+ Loader.add_constructor(tag, constructor)
+
+
+def add_multi_constructor(tag_prefix, multi_constructor, Loader=Loader):
+ """
+ Add a multi-constructor for the given tag prefix.
+ Multi-constructor is called for a node if its tag starts with tag_prefix.
+ Multi-constructor accepts a Loader instance, a tag suffix,
+ and a node object and produces the corresponding Python object.
+ """
+ Loader.add_multi_constructor(tag_prefix, multi_constructor)
+
+
+def add_representer(data_type, representer, Dumper=Dumper):
+ """
+ Add a representer for the given type.
+ Representer is a function accepting a Dumper instance
+ and an instance of the given data type
+ and producing the corresponding representation node.
+ """
+ Dumper.add_representer(data_type, representer)
+
+
+def add_multi_representer(data_type, multi_representer, Dumper=Dumper):
+ """
+ Add a representer for the given type.
+ Multi-representer is a function accepting a Dumper instance
+ and an instance of the given data type or subtype
+ and producing the corresponding representation node.
+ """
+ Dumper.add_multi_representer(data_type, multi_representer)
+
+
+class YAMLObjectMetaclass(type):
+ """
+ The metaclass for YAMLObject.
+ """
+ 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_loader.add_constructor(cls.yaml_tag, cls.from_yaml)
+ cls.yaml_dumper.add_representer(cls, cls.to_yaml)
+
+
+class YAMLObject(with_metaclass(YAMLObjectMetaclass)):
+ """
+ An object that can dump itself to a YAML stream
+ and load itself from a YAML stream.
+ """
+ __slots__ = () # no direct instantiation, so allow immutable subclasses
+
+ yaml_loader = Loader
+ yaml_dumper = Dumper
+
+ yaml_tag = None
+ yaml_flow_style = None
+
+ @classmethod
+ def from_yaml(cls, loader, node):
+ """
+ Convert a representation node to a Python object.
+ """
+ return loader.construct_yaml_object(node, cls)
+
+ @classmethod
+ def to_yaml(cls, dumper, data):
+ """
+ Convert a Python object to a representation node.
+ """
+ return dumper.represent_yaml_object(cls.yaml_tag, data, cls,
+ flow_style=cls.yaml_flow_style)
+
+
+def main():
+ # No direct import of yaml in order not to pollute namespace.
+ # If other utility 'bodies' exist in this directory a module level
+ # import here, would get you all of its initialisations/imports as well
+ from ruamel.yaml.yaml import main as util_main
+ util_main()
diff --git a/py/representer.py b/py/representer.py
index a36256d..a30c540 100644
--- a/py/representer.py
+++ b/py/representer.py
@@ -733,4 +733,3 @@ RoundTripRepresenter.add_representer(CommentedMap,
RoundTripRepresenter.add_representer(set,
RoundTripRepresenter.represent_set)
-
diff --git a/py/yaml.py b/py/yaml.py
new file mode 100644
index 0000000..71178c2
--- /dev/null
+++ b/py/yaml.py
@@ -0,0 +1,145 @@
+# coding: utf-8
+
+"""
+this is the source for the yaml utility
+"""
+
+from __future__ import print_function
+
+import sys
+import os
+import io
+
+from ruamel.std.argparse import ProgramBase, option, sub_parser, version, \
+ CountAction, SmartFormatter
+# from ruamel.appconfig import AppConfig
+from . import __version__
+
+import ruamel.yaml
+
+
+class YAML:
+ def __init__(self, args, config):
+ self._args = args
+ self._config = config
+
+ def from_json(self):
+ # use roundtrip to preserver order
+ errors = 0
+ docs = []
+ for file_name in self._args.file:
+ inp = open(file_name).read()
+ loader = ruamel.yaml.RoundTripLoader
+ docs.append(ruamel.yaml.load(inp, loader))
+ stream = io.StringIO()
+ dumper = ruamel.yaml.RoundTripDumper
+ print(ruamel.yaml.dump_all(docs, Dumper=dumper))
+ return 1 if errors else 0
+
+ def round_trip(self):
+ errors = 0
+ warnings = 0
+ for file_name in self._args.file:
+ inp = open(file_name).read()
+ outp = self.round_trip_single(inp)
+ if inp == outp:
+ if self._args.verbose > 0:
+ print(u"{0}: ok".format(file_name))
+ continue
+ warnings += 1
+ stabelize = []
+ if inp.split() != outp.split():
+ errors += 1
+ stabelize.append(u"drops info on round trip")
+ else:
+ if self.round_trip_single(outp) == outp:
+ stabelize.append(u"stabelizes on second round trip")
+ else:
+ errors += 1
+ ncoutp = self.round_trip_single(inp, drop_comment=True)
+ if self.round_trip_single(ncoutp, drop_comment=True) == ncoutp:
+ stabelize.append(u"ok without comments")
+ print("{0}:\n {1}".format(file_name, u', '.join(stabelize)))
+ self.diff(inp, outp, file_name)
+ return 2 if errors > 0 else 1 if warnings > 0 else 0
+
+ def round_trip_single(self, inp, drop_comment=False):
+ loader = ruamel.yaml.SafeLoader if drop_comment else \
+ ruamel.yaml.RoundTripLoader
+ code = ruamel.yaml.load(inp, loader)
+ stream = io.StringIO()
+ dumper = ruamel.yaml.SafeDumper if drop_comment else \
+ ruamel.yaml.RoundTripDumper
+ return ruamel.yaml.dump(code, Dumper=dumper)
+
+ def diff(self, inp, outp, file_name):
+ import difflib
+ inl = inp.splitlines(True) # True for keepends
+ outl = outp.splitlines(True)
+ diff = difflib.unified_diff(inl, outl, file_name, 'round trip YAML')
+ sys.stdout.writelines(diff)
+
+
+def to_stdout(*args):
+ sys.stdout.write(' '.join(args))
+
+
+class YAML_Cmd(ProgramBase):
+ def __init__(self):
+ super(YAML_Cmd, self).__init__(
+ formatter_class=SmartFormatter,
+ aliases=True,
+ )
+ self._config = None
+
+ # you can put these on __init__, but subclassing YAML_Cmd
+ # will cause that to break
+ @option('--verbose', '-v',
+ help='increase verbosity level', action=CountAction,
+ const=1, nargs=0, default=0, global_option=True)
+ @version('version: ' + __version__)
+ def _pb_init(self):
+ # special name for which attribs are included in help
+ pass
+
+ def run(self):
+ yaml = YAML(self._args, self._config)
+ if self._args.func:
+ return self._args.func(yaml)
+
+ def parse_args(self):
+ # self._config = AppConfig(
+ # 'yaml',
+ # filename=AppConfig.check,
+ # parser=self._parser, # sets --config option
+ # warning=to_stdout,
+ # add_save=False, # add a --save-defaults (to config) option
+ # )
+ # self._config._file_name can be handed to objects that need
+ # to get other information from the configuration directory
+ # self._config.set_defaults()
+ self._parse_args()
+
+ @sub_parser(
+ aliases=['round-trip'],
+ help='test round trip on YAML data',
+ description='test round trip on YAML data',
+ )
+ @option('file', nargs='+')
+ def rt(self, yaml):
+ return yaml.round_trip()
+
+ @sub_parser(
+ aliases=['from-json'],
+ help='convert json to block YAML',
+ description='convert json to block YAML',
+ )
+ @option('file', nargs='+')
+ def json(self, yaml):
+ return yaml.from_json()
+
+
+def main():
+ n = YAML_Cmd()
+ n.parse_args()
+ sys.exit(n.run())
diff --git a/setup.py b/setup.py
index 493b5b6..174b452 100644
--- a/setup.py
+++ b/setup.py
@@ -18,7 +18,7 @@ exclude_files = [
def get_version():
v_i = 'version_info = '
- for line in open('__init__.py'):
+ for line in open('py/__init__.py'):
if not line.startswith(v_i):
continue
s_e = line[len(v_i):].strip()[1:-1].split(', ')
@@ -109,14 +109,16 @@ class MyInstallLib(install_lib.install_lib):
def main():
install_requires = [
+ "ruamel.std.argparse",
]
# use fast ordereddict for !!omap
- install_requires = ['ruamel.ordereddict'] \
- if sys.version_info[0] == 2 else []
+ if sys.version_info[0] == 2:
+ install_requires.extend(['ruamel.ordereddict'])
# if sys.version_info < (3, 4):
# install_requires.append("")
- packages = [full_package_name] + [(full_package_name + '.' + x) for x
- in find_packages(exclude=['tests'])]
+ packages = [full_package_name] + [
+ (full_package_name + '.' + x)
+ for x in find_packages('py', exclude=['tests'])]
setup(
name=full_package_name,
version=version_str,
@@ -128,7 +130,7 @@ def main():
author='Anthon van der Neut',
author_email='a.van.der.neut@ruamel.eu',
license="MIT license",
- package_dir={full_package_name: '.'},
+ package_dir={full_package_name: 'py'},
namespace_packages=[name_space],
packages=packages,
entry_points=mk_entry_points(full_package_name),
@@ -143,10 +145,10 @@ def main():
)
-def mk_entry_points(package_name):
- script_name = package_name.replace('.', '_')
+def mk_entry_points(full_package_name):
+ script_name = full_package_name.rsplit('.', 1)[-1]
return {'console_scripts': [
- '{0} = {1}:main'.format(script_name, package_name),
+ '{0} = {1}:main'.format(script_name, full_package_name),
]}
if __name__ == '__main__':
diff --git a/test/lib/canonical.py b/test/lib/canonical.py
index 9932d45..c273e01 100644
--- a/test/lib/canonical.py
+++ b/test/lib/canonical.py
@@ -1,9 +1,9 @@
import ruamel.yaml
-from ruamel.yaml.py.composer import Composer
-from ruamel.yaml.py.constructor import Constructor
-from ruamel.yaml.py.resolver import Resolver
-from ruamel.yaml.py.compat import unichr, PY3
+from ruamel.yaml.composer import Composer
+from ruamel.yaml.constructor import Constructor
+from ruamel.yaml.resolver import Resolver
+from ruamel.yaml.compat import unichr, PY3
class CanonicalError(ruamel.yaml.YAMLError):
pass
diff --git a/test/lib/test_appliance.py b/test/lib/test_appliance.py
index b6896f7..03ee6d7 100644
--- a/test/lib/test_appliance.py
+++ b/test/lib/test_appliance.py
@@ -7,7 +7,7 @@ import types
import traceback
import pprint
import argparse
-from ruamel.yaml.py.compat import PY3
+from ruamel.yaml.compat import PY3
# DATA = 'tests/data'
# determine the position of data dynamically relative to program
diff --git a/test/lib/test_constructor.py b/test/lib/test_constructor.py
index 593805b..544a80e 100644
--- a/test/lib/test_constructor.py
+++ b/test/lib/test_constructor.py
@@ -3,14 +3,14 @@ from __future__ import print_function
import ruamel.yaml
import pprint
-from ruamel.yaml.py.compat import PY2, PY3
+from ruamel.yaml.compat import PY2, PY3
import datetime
try:
set
except NameError:
from sets import Set as set
-import ruamel.yaml.py.tokens
+import ruamel.yaml.tokens
def execute(code):
global value
diff --git a/test/lib/test_input_output.py b/test/lib/test_input_output.py
index cbe57d5..7d103dc 100644
--- a/test/lib/test_input_output.py
+++ b/test/lib/test_input_output.py
@@ -3,7 +3,7 @@ from __future__ import print_function
import ruamel.yaml as yaml
import codecs, tempfile, os, os.path
-from ruamel.yaml.py.compat import PY2, PY3, StringIO, BytesIO
+from ruamel.yaml.compat import PY2, PY3, StringIO, BytesIO
if PY2:
def _unicode_open(file, encoding, errors='strict'):
diff --git a/test/lib/test_mark.py b/test/lib/test_mark.py
index 7935965..0574f20 100644
--- a/test/lib/test_mark.py
+++ b/test/lib/test_mark.py
@@ -2,7 +2,7 @@ from __future__ import absolute_import
from __future__ import print_function
import ruamel.yaml as yaml
-from ruamel.yaml.py.compat import text_type, PY3
+from ruamel.yaml.compat import text_type, PY3
def test_marks(marks_filename, verbose=False):
inputs = open(marks_filename, 'r' if PY3 else 'rb').read(
diff --git a/test/lib/test_reader.py b/test/lib/test_reader.py
index 484a7ce..157c652 100644
--- a/test/lib/test_reader.py
+++ b/test/lib/test_reader.py
@@ -4,8 +4,8 @@ from __future__ import print_function
import codecs
import io
-from ruamel.yaml.py.compat import PY2
-import ruamel.yaml.py.reader
+from ruamel.yaml.compat import PY2
+import ruamel.yaml.reader
def _run_reader(data, verbose):
try:
diff --git a/test/lib/test_resolver.py b/test/lib/test_resolver.py
index 371f1b8..bc3928f 100644
--- a/test/lib/test_resolver.py
+++ b/test/lib/test_resolver.py
@@ -3,7 +3,7 @@ from __future__ import print_function
import ruamel.yaml as yaml
import pprint
-from ruamel.yaml.py.compat import PY3
+from ruamel.yaml.compat import PY3
def test_implicit_resolver(data_filename, detect_filename, verbose=False):
correct_tag = None
diff --git a/test/lib/test_structure.py b/test/lib/test_structure.py
index f6a29aa..353d432 100644
--- a/test/lib/test_structure.py
+++ b/test/lib/test_structure.py
@@ -4,7 +4,7 @@ from __future__ import print_function
import ruamel.yaml as yaml
import canonical
import pprint
-from ruamel.yaml.py.compat import text_type, PY3
+from ruamel.yaml.compat import text_type, PY3
def _convert_structure(loader):
if loader.check_event(yaml.ScalarEvent):
diff --git a/test/lib/test_tokens.py b/test/lib/test_tokens.py
index 6ba3a86..23c9380 100644
--- a/test/lib/test_tokens.py
+++ b/test/lib/test_tokens.py
@@ -3,7 +3,7 @@ from __future__ import print_function
import ruamel.yaml as yaml
import pprint
-from ruamel.yaml.py.compat import PY3
+from ruamel.yaml.compat import PY3
# Tokens mnemonic:
# directive: %
diff --git a/test/roundtrip.py b/test/roundtrip.py
index b5dadda..374bff3 100644
--- a/test/roundtrip.py
+++ b/test/roundtrip.py
@@ -10,8 +10,6 @@ except ImportError:
from io import StringIO
import ruamel.yaml
-from ruamel.yaml import RoundTripLoader
-from ruamel.yaml import RoundTripDumper
def dedent(data):
@@ -28,12 +26,12 @@ def dedent(data):
def round_trip_load(dinp):
- return ruamel.yaml.load(dinp, RoundTripLoader)
+ return ruamel.yaml.load(dinp, ruamel.yaml.RoundTripLoader)
def round_trip_dump(data):
stream = StringIO()
- dumper = RoundTripDumper
+ dumper = ruamel.yaml.RoundTripDumper
return ruamel.yaml.dump(data, default_flow_style=False, Dumper=dumper)
diff --git a/test/test_z_data.py b/test/test_z_data.py
index c221c76..19d454c 100644
--- a/test/test_z_data.py
+++ b/test/test_z_data.py
@@ -20,12 +20,11 @@ def test_data():
test_appliance.run(collections, args)
-@pytest.mark.skipif(not ruamel.yaml.__with_libyaml__,
- reason="no libyaml")
+@pytest.mark.skipif(not ruamel.yaml.__with_libyaml__,
+ reason="no libyaml")
def test_data_ext():
collections = []
if ruamel.yaml.__with_libyaml__:
import test_yaml_ext
collections.append(test_yaml_ext)
test_appliance.run(collections, args)
-
diff --git a/yaml.py b/yaml.py
deleted file mode 100644
index b4b36a6..0000000
--- a/yaml.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# coding: utf-8
-
-from __future__ import print_function
-
-import sys
-import os
-
-from ruamel.std.argparse import ProgramBase, option, sub_parser, version, \
- CountAction, SmartFormatter
-from ruamel.appconfig import AppConfig
-from . import __version__
-
-
-class YAML:
- def __init__(self, args, config):
- self._args = args
- self._config = config
-
-
-def to_stdout(*args):
- sys.stdout.write(' '.join(args))
-
-
-class YAML_Cmd(ProgramBase):
- def __init__(self):
- super(YAML_Cmd, self).__init__(
- formatter_class=SmartFormatter
- )
-
- # you can put these on __init__, but subclassing YAML_Cmd
- # will cause that to break
- @option('--verbose', '-v',
- help='increase verbosity level', action=CountAction,
- const=1, nargs=0, default=0, global_option=True)
- @version('version: ' + __version__)
- def _pb_init(self):
- # special name for which attribs are included in help
- pass
-
- def run(self):
- yaml = YAML(self._args, self._config)
- # if self._args.func:
- # return self._args.func()
-
- def parse_args(self):
- #self._config = AppConfig(
- # 'yaml',
- # filename=AppConfig.check,
- # parser=self._parser, # sets --config option
- # warning=to_stdout,
- # add_save=False, # add a --save-defaults (to config) option
- #)
- # self._config._file_name can be handed to objects that need
- # to get other information from the configuration directory
- #self._config.set_defaults()
- self._parse_args()
-
- # @sub_parser(help='some command specific help for tmux')
- # @option('--session-name', default='abc')
- # def tmux(self):
- # from plumbum.cmd import tmux
- # from plumbum.commands.processes import ProcessExecutionError
-
-
-def main():
- n = YAML_Cmd()
- n.parse_args()
- n.run()