diff options
author | Anthon van der Neut <anthon@mnt.org> | 2018-08-05 23:20:17 +0200 |
---|---|---|
committer | Anthon van der Neut <anthon@mnt.org> | 2018-08-05 23:20:17 +0200 |
commit | bfd63d6184e3a43cb63e0831467819bc44513d50 (patch) | |
tree | 9426b3c93cb1fd7849ea678424b6bbd900ff2d68 | |
parent | 893db272efb6d7041e09aa09f04da2010ec92072 (diff) | |
download | ruamel.yaml-bfd63d6184e3a43cb63e0831467819bc44513d50.tar.gz |
added context manager, mypy cleanup (w. Optional) added tests0.15.50
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | README.rst | 8 | ||||
-rw-r--r-- | __init__.py | 4 | ||||
-rw-r--r-- | _doc/_static/pypi.svg | 2 | ||||
-rw-r--r-- | _doc/api.ryd | 56 | ||||
-rw-r--r-- | _doc/basicuse.ryd | 2 | ||||
-rw-r--r-- | _test/test_contextmanager.py | 12 | ||||
-rw-r--r-- | comments.py | 4 | ||||
-rw-r--r-- | compat.py | 4 | ||||
-rw-r--r-- | constructor.py | 4 | ||||
-rw-r--r-- | cyaml.py | 14 | ||||
-rw-r--r-- | dumper.py | 10 | ||||
-rw-r--r-- | emitter.py | 12 | ||||
-rw-r--r-- | loader.py | 10 | ||||
-rw-r--r-- | main.py | 103 | ||||
-rw-r--r-- | reader.py | 12 | ||||
-rw-r--r-- | representer.py | 4 | ||||
-rw-r--r-- | resolver.py | 6 | ||||
-rw-r--r-- | serializer.py | 6 |
19 files changed, 196 insertions, 83 deletions
@@ -1,3 +1,9 @@ +[0, 15, 50]: 2018-08-05 + - Allow ``YAML()`` as a context manager for output, thereby making it much easier + to generate multi-documents in a stream. + - Fix issue with incorrect type information for `load()` and `dump()` (reported + by `Jimbo Jim <https://bitbucket.org/jimbo1qaz/>`__) + [0, 15, 49]: 2018-08-05 - fix preservation of leading newlines in root level literal style scalar, and preserve comment after literal style indicator (``| # some comment``) @@ -4,7 +4,7 @@ ruamel.yaml ``ruamel.yaml`` is a YAML 1.2 loader/dumper package for Python. -:version: 0.15.49 +:version: 0.15.50 :updated: 2018-08-05 :documentation: http://yaml.readthedocs.io :repository: https://bitbucket.org/ruamel/ @@ -54,6 +54,12 @@ ChangeLog .. should insert NEXT: at the beginning of line for next key (with empty line) +0.15.50 (2018-08-05): + - Allow ``YAML()`` as a context manager for output, thereby making it much easier + to generate multi-documents in a stream. + - Fix issue with incorrect type information for `load()` and `dump()` (reported + by `Jimbo Jim <https://bitbucket.org/jimbo1qaz/>`__) + 0.15.49 (2018-08-05): - fix preservation of leading newlines in root level literal style scalar, and preserve comment after literal style indicator (``| # some comment``) diff --git a/__init__.py b/__init__.py index ece2b5b..1e3bf42 100644 --- a/__init__.py +++ b/__init__.py @@ -7,8 +7,8 @@ if False: # MYPY _package_data = dict( full_package_name='ruamel.yaml', - version_info=(0, 15, 50, 'dev'), - __version__='0.15.50.dev', + version_info=(0, 15, 50), + __version__='0.15.50', author='Anthon van der Neut', author_email='a.van.der.neut@ruamel.eu', description='ruamel.yaml is a YAML parser/emitter that supports roundtrip preservation of comments, seq/map flow style, and map key order', # NOQA diff --git a/_doc/_static/pypi.svg b/_doc/_static/pypi.svg index 67703ce..a145534 100644 --- a/_doc/_static/pypi.svg +++ b/_doc/_static/pypi.svg @@ -1 +1 @@ -<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#007ec6" d="M33 0h53v20H33z"/><path fill="url(#b)" d="M0 0h86v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">pypi</text><text x="175" y="140" transform="scale(.1)" textLength="230">pypi</text><text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">0.15.49</text><text x="585" y="140" transform="scale(.1)" textLength="430">0.15.49</text></g> </svg> +<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="86" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><clipPath id="a"><rect width="86" height="20" rx="3" fill="#fff"/></clipPath><g clip-path="url(#a)"><path fill="#555" d="M0 0h33v20H0z"/><path fill="#007ec6" d="M33 0h53v20H33z"/><path fill="url(#b)" d="M0 0h86v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="110"> <text x="175" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="230">pypi</text><text x="175" y="140" transform="scale(.1)" textLength="230">pypi</text><text x="585" y="150" fill="#010101" fill-opacity=".3" transform="scale(.1)" textLength="430">0.15.50</text><text x="585" y="140" transform="scale(.1)" textLength="430">0.15.50</text></g> </svg> diff --git a/_doc/api.ryd b/_doc/api.ryd index a6c5afd..9e89b00 100644 --- a/_doc/api.ryd +++ b/_doc/api.ryd @@ -116,6 +116,62 @@ yaml.load(stream) In the old API this is a warning starting with 0.15.2 and an error in 0.16.0. +Dumping a multi-documents YAML stream ++++++++++++++++++++++++++++++++++++++ + +The "normal" ``dump_all`` expected as first element a list of documents, or +something else the internals of the method can iterate over. To read +and write a multi-document you would either make a ``list``:: + +--- !code | + yaml = YAML() + data = list(yaml.load_all(in_path)) + # do something on data[0], data[1], etc. + yaml.dump_all(data, out_path) +--- | + +or create some function/object that would yield the ``data`` values. + +What you now can do is create ``YAML()`` as an context manager. This +works for output (dumping) only, requires you to specify the output +(file, buffer, ``Path``) at creation time, and doesn't support +``transform`` (yet). + +:: + +--- !code | + with YAML(output=sys.stdout) as yaml: + yaml.explicit_start = True + for data in yaml.load_all(Path(multi_document_filename)): + # do something on data + yaml.dump(data) +--- | + +Within the context manager, you cannot use the ``dump()`` with a +second (stream) argument, nor can you use ``dump_all()``. The +``dump()`` within the context of the ``YAML()`` automatically creates + multi-document if called more than once. + +To combine multiple YAML documents from multiple files: + +:: + +--- !code | + list_of_filenames = ['x.yaml', 'y.yaml', ] + with YAML(output=sys.stdout) as yaml: + yaml.explicit_start = True + for path in list_of_filename: + with open(path) as fp: + yaml.dump(yaml.load(fp)) +--- | + +The output will be a valid, uniformly indented YAML file. Doing +``cat {x,y}.yaml`` might result in a single document if there is not +document start marker at the beginning of ``y.yaml`` + + + + Dumping +++++++ diff --git a/_doc/basicuse.ryd b/_doc/basicuse.ryd index c4a744d..9d2512d 100644 --- a/_doc/basicuse.ryd +++ b/_doc/basicuse.ryd @@ -38,7 +38,7 @@ enforce using the pure Python implementation (faster C libraries will be used when possible/available) Dumping works in the same way:: ---- !python | +--- !code | from ruamel.yaml import YAML yaml=YAML() diff --git a/_test/test_contextmanager.py b/_test/test_contextmanager.py index 85adf75..76d24aa 100644 --- a/_test/test_contextmanager.py +++ b/_test/test_contextmanager.py @@ -98,3 +98,15 @@ class TestContextManager: # with YAML(input=multi_doc) as yaml: # for idx, data in enumerate(yaml.load()): # assert data == multi_doc_data[0] + + def test_roundtrip(self, capsys): + from ruamel.yaml import YAML + + with YAML(output=sys.stdout) as yaml: + yaml.explicit_start = True + for data in yaml.load_all(multi_doc): + yaml.dump(data) + + out, err = capsys.readouterr() + print(err) + assert out == multi_doc diff --git a/comments.py b/comments.py index 32ce8ce..84fecbc 100644 --- a/comments.py +++ b/comments.py @@ -21,7 +21,7 @@ else: from collections.abc import MutableSet, Sized, Set if False: # MYPY - from typing import Any, Dict, Optional, List, Union # NOQA + from typing import Any, Dict, Optional, List, Union, Optional # NOQA # fmt: off __all__ = ["CommentedSeq", "CommentedKeySeq", @@ -127,7 +127,7 @@ class LineCol(object): # type: () -> None self.line = None self.col = None - self.data = None # type: Union[None, Dict[Any, Any]] + self.data = None # type: Optional[Dict[Any, Any]] def add_kv_line_col(self, key, data): # type: (Any, Any) -> None @@ -9,7 +9,7 @@ import os import types if False: # MYPY - from typing import Any, Dict, Optional, List, Union, BinaryIO, IO, Text, Tuple # NOQA + from typing import Any, Dict, Optional, List, Union, BinaryIO, IO, Text, Tuple, Optional # NOQA _DEFAULT_YAML_VERSION = (1, 2) @@ -136,7 +136,7 @@ DBG_EVENT = 2 DBG_NODE = 4 -_debug = None # type: Union[None, int] +_debug = None # type: Optional[int] if 'RUAMELDEBUG' in os.environ: _debugx = os.environ.get('RUAMELDEBUG') if _debugx is None: diff --git a/constructor.py b/constructor.py index c36f01d..6de5181 100644 --- a/constructor.py +++ b/constructor.py @@ -29,7 +29,7 @@ from ruamel.yaml.timestamp import TimeStamp from ruamel.yaml.util import RegExp if False: # MYPY - from typing import Any, Dict, List, Set, Generator, Union # NOQA + from typing import Any, Dict, List, Set, Generator, Union, Optional # NOQA __all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor', @@ -55,7 +55,7 @@ class BaseConstructor(object): yaml_multi_constructors = {} # type: Dict[Any, Any] def __init__(self, preserve_quotes=None, loader=None): - # type: (Union[None, bool], Any) -> None + # type: (Optional[bool], Any) -> None self.loader = loader if self.loader is not None and getattr(self.loader, '_constructor', None) is None: self.loader._constructor = self @@ -9,7 +9,7 @@ from ruamel.yaml.representer import Representer, SafeRepresenter, BaseRepresente from ruamel.yaml.resolver import Resolver, BaseResolver if False: # MYPY - from typing import Any, Union # NOQA + from typing import Any, Union, Optional # NOQA from ruamel.yaml.compat import StreamTextType, StreamType, VersionType # NOQA __all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader', 'CBaseDumper', 'CSafeDumper', 'CDumper'] @@ -21,7 +21,7 @@ __all__ = ['CBaseLoader', 'CSafeLoader', 'CLoader', 'CBaseDumper', 'CSafeDumper' class CBaseLoader(CParser, BaseConstructor, BaseResolver): # type: ignore def __init__(self, stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> None + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> None CParser.__init__(self, stream) self._parser = self._composer = self BaseConstructor.__init__(self, loader=self) @@ -33,7 +33,7 @@ class CBaseLoader(CParser, BaseConstructor, BaseResolver): # type: ignore class CSafeLoader(CParser, SafeConstructor, Resolver): # type: ignore def __init__(self, stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> None + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> None CParser.__init__(self, stream) self._parser = self._composer = self SafeConstructor.__init__(self, loader=self) @@ -45,7 +45,7 @@ class CSafeLoader(CParser, SafeConstructor, Resolver): # type: ignore class CLoader(CParser, Constructor, Resolver): # type: ignore def __init__(self, stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> None + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> None CParser.__init__(self, stream) self._parser = self._composer = self Constructor.__init__(self, loader=self) @@ -75,7 +75,7 @@ class CBaseDumper(CEmitter, BaseRepresenter, BaseResolver): # type: ignore top_level_colon_align=None, prefix_colon=None, ): - # type: (StreamType, Any, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> None # NOQA + # type: (StreamType, Any, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> None # NOQA CEmitter.__init__( self, stream, @@ -120,7 +120,7 @@ class CSafeDumper(CEmitter, SafeRepresenter, Resolver): # type: ignore top_level_colon_align=None, prefix_colon=None, ): - # type: (StreamType, Any, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> None # NOQA + # type: (StreamType, Any, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> None # NOQA self._emitter = self._serializer = self._representer = self CEmitter.__init__( self, @@ -163,7 +163,7 @@ class CDumper(CEmitter, Representer, Resolver): # type: ignore top_level_colon_align=None, prefix_colon=None, ): - # type: (StreamType, Any, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> None # NOQA + # type: (StreamType, Any, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> None # NOQA CEmitter.__init__( self, stream, @@ -13,7 +13,7 @@ from ruamel.yaml.representer import ( from ruamel.yaml.resolver import Resolver, BaseResolver, VersionedResolver if False: # MYPY - from typing import Any, Dict, List, Union # NOQA + from typing import Any, Dict, List, Union, Optional # NOQA from ruamel.yaml.compat import StreamType, VersionType # NOQA __all__ = ['BaseDumper', 'SafeDumper', 'Dumper', 'RoundTripDumper'] @@ -39,7 +39,7 @@ class BaseDumper(Emitter, Serializer, BaseRepresenter, BaseResolver): top_level_colon_align=None, prefix_colon=None, ): - # type: (Any, StreamType, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> None # NOQA + # type: (Any, StreamType, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> None # NOQA Emitter.__init__( self, stream, @@ -89,7 +89,7 @@ class SafeDumper(Emitter, Serializer, SafeRepresenter, Resolver): top_level_colon_align=None, prefix_colon=None, ): - # type: (StreamType, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> None # NOQA + # type: (StreamType, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> None # NOQA Emitter.__init__( self, stream, @@ -139,7 +139,7 @@ class Dumper(Emitter, Serializer, Representer, Resolver): top_level_colon_align=None, prefix_colon=None, ): - # type: (StreamType, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> None # NOQA + # type: (StreamType, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> None # NOQA Emitter.__init__( self, stream, @@ -189,7 +189,7 @@ class RoundTripDumper(Emitter, Serializer, RoundTripRepresenter, VersionedResolv top_level_colon_align=None, prefix_colon=None, ): - # type: (StreamType, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> None # NOQA + # type: (StreamType, Any, Optional[bool], Optional[int], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> None # NOQA Emitter.__init__( self, stream, @@ -20,7 +20,7 @@ from ruamel.yaml.compat import utf8, text_type, PY2, nprint, dbg, DBG_EVENT, \ # fmt: on if False: # MYPY - from typing import Any, Dict, List, Union, Text, Tuple # NOQA + from typing import Any, Dict, List, Union, Text, Tuple, Optional # NOQA from ruamel.yaml.compat import StreamType # NOQA __all__ = ['Emitter', 'EmitterError'] @@ -113,14 +113,14 @@ class Emitter(object): prefix_colon=None, dumper=None, ): - # type: (StreamType, Any, Union[None, int], Union[None, int], Union[None, bool], Any, Union[None, int], Union[None, bool], Any, Any) -> None # NOQA + # type: (StreamType, Any, Optional[int], Optional[int], Optional[bool], Any, Optional[int], Optional[bool], Any, Any) -> None # NOQA self.dumper = dumper if self.dumper is not None and getattr(self.dumper, '_emitter', None) is None: self.dumper._emitter = self self.stream = stream # Encoding can be overriden by STREAM-START. - self.encoding = None # type: Union[None, Text] + self.encoding = None # type: Optional[Text] self.allow_space_break = None # Emitter is a state machine with a stack of states to handle nested @@ -134,7 +134,7 @@ class Emitter(object): # The current indentation level and the stack of previous indents. self.indents = Indents() - self.indent = None # type: Union[None, int] + self.indent = None # type: Optional[int] # Flow level. self.flow_level = 0 @@ -154,7 +154,7 @@ class Emitter(object): self.column = 0 self.whitespace = True self.indention = True - self.no_newline = None # type: Union[None, bool] # set if directly after `- ` + self.no_newline = None # type: Optional[bool] # set if directly after `- ` # Whether the document requires an explicit document indicator self.open_ended = False @@ -269,7 +269,7 @@ class Emitter(object): return len(self.events) < count + 1 def increase_indent(self, flow=False, sequence=None, indentless=False): - # type: (bool, Union[None, bool], bool) -> None + # type: (bool, Optional[bool], bool) -> None self.indents.append(self.indent, sequence) if self.indent is None: # top level if flow: @@ -16,7 +16,7 @@ from ruamel.yaml.constructor import ( from ruamel.yaml.resolver import VersionedResolver if False: # MYPY - from typing import Any, Dict, List, Union # NOQA + from typing import Any, Dict, List, Union, Optional # NOQA from ruamel.yaml.compat import StreamTextType, VersionType # NOQA __all__ = ['BaseLoader', 'SafeLoader', 'Loader', 'RoundTripLoader'] @@ -24,7 +24,7 @@ __all__ = ['BaseLoader', 'SafeLoader', 'Loader', 'RoundTripLoader'] class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, VersionedResolver): def __init__(self, stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> None + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> None Reader.__init__(self, stream, loader=self) Scanner.__init__(self, loader=self) Parser.__init__(self, loader=self) @@ -35,7 +35,7 @@ class BaseLoader(Reader, Scanner, Parser, Composer, BaseConstructor, VersionedRe class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, VersionedResolver): def __init__(self, stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> None + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> None Reader.__init__(self, stream, loader=self) Scanner.__init__(self, loader=self) Parser.__init__(self, loader=self) @@ -46,7 +46,7 @@ class SafeLoader(Reader, Scanner, Parser, Composer, SafeConstructor, VersionedRe class Loader(Reader, Scanner, Parser, Composer, Constructor, VersionedResolver): def __init__(self, stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> None + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> None Reader.__init__(self, stream, loader=self) Scanner.__init__(self, loader=self) Parser.__init__(self, loader=self) @@ -64,7 +64,7 @@ class RoundTripLoader( VersionedResolver, ): def __init__(self, stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> None + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> None # self.reader = Reader.__init__(self, stream) Reader.__init__(self, stream, loader=self) RoundTripScanner.__init__(self, loader=self) @@ -35,7 +35,7 @@ from ruamel.yaml.constructor import ( from ruamel.yaml.loader import Loader as UnsafeLoader if False: # MYPY - from typing import List, Set, Dict, Union, Any # NOQA + from typing import List, Set, Dict, Union, Any, Callable # NOQA from ruamel.yaml.compat import StreamType, StreamTextType, VersionType # NOQA if PY3: @@ -61,7 +61,7 @@ class YAML(object): def __init__( self, _kw=enforce, typ=None, pure=False, output=None, plug_ins=None # input=None, ): - # type: (Any, Any, Any, Any) -> None + # type: (Any, Optional[Text], Any, Any, Any) -> None """ _kw: not used, forces keyword arguments in 2.7 (in 3 you can do (*, safe_load=..) typ: 'rt'/None -> RoundTripLoader/RoundTripDumper, (default) @@ -83,7 +83,7 @@ class YAML(object): # self._input = input self._output = output - self._context_manager = False + self._context_manager = None # type: Any self.plug_ins = [] # type: List[Any] for pu in ([] if plug_ins is None else plug_ins) + self.official_plug_ins(): @@ -394,7 +394,7 @@ class YAML(object): class XLoader(self.Parser, self.Constructor, rslvr): # type: ignore def __init__(selfx, stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> None # NOQA + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> None # NOQA CParser.__init__(selfx, stream) selfx._parser = selfx._composer = selfx self.Constructor.__init__(selfx, loader=selfx) @@ -411,7 +411,17 @@ class YAML(object): if self._context_manager: if not self._output: raise TypeError('Missing output stream while dumping from context manager') - self._context_manager.dump(data, transform=transform) + if _kw is not enforce: + raise TypeError( + '{}.dump() takes one positional argument but at least ' + 'two were given ({!r})'.format(self.__class__.__name__, _kw) + ) + if transform is not None: + raise TypeError( + '{}.dump() in the context manager cannot have transform keyword ' + ''.format(self.__class__.__name__) + ) + self._context_manager.dump(data) else: # old style if stream is None: raise TypeError('Need a stream argument when not dumping from context manager') @@ -419,6 +429,23 @@ class YAML(object): def dump_all(self, documents, stream, _kw=enforce, transform=None): # type: (Any, Union[Path, StreamType], Any, Any) -> Any + if self._context_manager: + raise NotImplementedError + if _kw is not enforce: + raise TypeError( + '{}.dump(_all) takes two positional argument but at least ' + 'three were given ({!r})'.format(self.__class__.__name__, _kw) + ) + self._output = stream + self._context_manager = YAMLContextManager(self, transform=transform) + for data in documents: + self._context_manager.dump(data) + self._context_manager.teardown_output() + self._output = None + self._context_manager = None + + def Xdump_all(self, documents, stream, _kw=enforce, transform=None): + # type: (Any, Union[Path, StreamType], Any, Any) -> Any """ Serialize a sequence of Python objects into a YAML stream. """ @@ -515,7 +542,7 @@ class YAML(object): top_level_colon_align=None, prefix_colon=None, ): - # type: (StreamType, Any, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> None # NOQA + # type: (StreamType, Any, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> None # NOQA CEmitter.__init__( selfx, stream, @@ -615,10 +642,12 @@ class YAML(object): # ### context manager def __enter__(self): + # type: () -> Any self._context_manager = YAMLContextManager(self) return self def __exit__(self, typ, value, traceback): + # type: (Any, Any, Any) -> None if typ: print('typ', typ) self._context_manager.teardown_output() @@ -657,12 +686,13 @@ class YAML(object): class YAMLContextManager(object): - def __init__(self, yaml): + def __init__(self, yaml, transform=None): + # type: (Any, Optional[Callable]) -> None self._yaml = yaml self._output_inited = False self._output_path = None self._output = self._yaml._output - self._transform = False + self._transform = transform # self._input_inited = False # self._input = input @@ -673,7 +703,7 @@ class YAMLContextManager(object): if not hasattr(self._output, 'write') and hasattr(self._output, 'open'): # pathlib.Path() instance, open with the same mode self._output_path = self._output - self._output = self._output_path.open('r') + self._output = self._output_path.open('w') # if not hasattr(self._stream, 'write') and hasattr(stream, 'open'): # if not hasattr(self._input, 'read') and hasattr(self._input, 'open'): @@ -681,14 +711,15 @@ class YAMLContextManager(object): # self._input_path = self._input # self._input = self._input_path.open('r') - # if self._transform is not None: - # self._fstream = self._stream - # if self._yaml.encoding is None: - # self._stream = StringIO() - # else: - # self._stream = BytesIO() + if self._transform is not None: + self._fstream = self._output + if self._yaml.encoding is None: + self._output = StringIO() + else: + self._output = BytesIO() def teardown_output(self): + # type: () -> None if self._output_inited: self._yaml.serializer.close() else: @@ -702,21 +733,22 @@ class YAMLContextManager(object): delattr(self._yaml, '_serializer') delattr(self._yaml, '_emitter') except AttributeError: - if not typ: - raise + raise if self._transform: - val = self._stream.getvalue() # type: ignore + val = self._output.getvalue() if self._yaml.encoding: val = val.decode(self._yaml.encoding) if self._fstream is None: self._transform(val) else: self._fstream.write(self._transform(val)) - self._fstream.close() + self._fstream.flush() + self._output = self._fstream # maybe not necessary if self._output_path is not None: self._output.close() - def init_output(self, data): + def init_output(self, first_data): + # type: (Any) -> None if self._yaml.top_level_colon_align is True: tlca = max([len(str(x)) for x in first_data]) # type: Any else: @@ -725,7 +757,8 @@ class YAMLContextManager(object): self._yaml.serializer.open() self._output_inited = True - def dump(self, data, transform=None): + def dump(self, data): + # type: (Any) -> None if not self._output_inited: self.init_output(data) try: @@ -853,7 +886,7 @@ def compose_all(stream, Loader=Loader): def load(stream, Loader=None, version=None, preserve_quotes=None): - # type: (StreamTextType, Any, Union[None, VersionType], Any) -> Any + # type: (StreamTextType, Any, Optional[VersionType], Any) -> Any """ Parse the first YAML document in a stream and produce the corresponding Python object. @@ -869,7 +902,7 @@ def load(stream, Loader=None, version=None, preserve_quotes=None): def load_all(stream, Loader=None, version=None, preserve_quotes=None): - # type: (Union[None, StreamTextType], Any, Union[None, VersionType], Union[None, bool]) -> Any # NOQA + # type: (Optional[StreamTextType], Any, Optional[VersionType], Optional[bool]) -> Any # NOQA """ Parse all YAML documents in a stream and produce corresponding Python objects. @@ -886,7 +919,7 @@ def load_all(stream, Loader=None, version=None, preserve_quotes=None): def safe_load(stream, version=None): - # type: (StreamTextType, Union[None, VersionType]) -> Any + # type: (StreamTextType, Optional[VersionType]) -> Any """ Parse the first YAML document in a stream and produce the corresponding Python object. @@ -896,7 +929,7 @@ def safe_load(stream, version=None): def safe_load_all(stream, version=None): - # type: (StreamTextType, Union[None, VersionType]) -> Any + # type: (StreamTextType, Optional[VersionType]) -> Any """ Parse all YAML documents in a stream and produce corresponding Python objects. @@ -906,7 +939,7 @@ def safe_load_all(stream, version=None): def round_trip_load(stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> Any + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> Any """ Parse the first YAML document in a stream and produce the corresponding Python object. @@ -916,7 +949,7 @@ def round_trip_load(stream, version=None, preserve_quotes=None): def round_trip_load_all(stream, version=None, preserve_quotes=None): - # type: (StreamTextType, Union[None, VersionType], Union[None, bool]) -> Any + # type: (StreamTextType, Optional[VersionType], Optional[bool]) -> Any """ Parse all YAML documents in a stream and produce corresponding Python objects. @@ -935,7 +968,7 @@ def emit( allow_unicode=None, line_break=None, ): - # type: (Any, Union[None, StreamType], Any, Union[None, bool], Union[int, None], Union[None, int], Union[None, bool], Any) -> Any # NOQA + # type: (Any, Optional[StreamType], Any, Optional[bool], Union[int, None], Optional[int], Optional[bool], Any) -> Any # NOQA """ Emit YAML parsing events into a stream. If stream is None, return the produced string instead. @@ -983,7 +1016,7 @@ def serialize_all( version=None, tags=None, ): - # type: (Any, Union[None, StreamType], Any, Any, Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Union[None, VersionType], Any) -> Any # NOQA + # type: (Any, Optional[StreamType], Any, Any, Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Optional[VersionType], Any) -> Any # NOQA """ Serialize a sequence of representation trees into a YAML stream. If stream is None, return the produced string instead. @@ -1024,7 +1057,7 @@ def serialize_all( def serialize(node, stream=None, Dumper=Dumper, **kwds): - # type: (Any, Union[None, StreamType], Any, Any) -> Any + # type: (Any, Optional[StreamType], Any, Any) -> Any """ Serialize a representation tree into a YAML stream. If stream is None, return the produced string instead. @@ -1052,7 +1085,7 @@ def dump_all( top_level_colon_align=None, prefix_colon=None, ): - # type: (Any, Union[None, StreamType], Any, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Any, Any, Any, Any, Any) -> Union[None, str] # NOQA + # type: (Any, Optional[StreamType], Any, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Any, Any, Any, Any, Any) -> Optional[str] # NOQA """ Serialize a sequence of Python objects into a YAML stream. If stream is None, return the produced string instead. @@ -1122,7 +1155,7 @@ def dump( tags=None, block_seq_indent=None, ): - # type: (Any, Union[None, StreamType], Any, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Union[None, VersionType], Any, Any) -> Union[None, str] # NOQA + # type: (Any, Optional[StreamType], Any, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Optional[VersionType], Any, Any) -> Optional[str] # NOQA """ Serialize a Python object into a YAML stream. If stream is None, return the produced string instead. @@ -1151,7 +1184,7 @@ def dump( def safe_dump_all(documents, stream=None, **kwds): - # type: (Any, Union[None, StreamType], Any) -> Union[None, str] + # type: (Any, Optional[StreamType], Any) -> Optional[str] """ Serialize a sequence of Python objects into a YAML stream. Produce only basic YAML tags. @@ -1161,7 +1194,7 @@ def safe_dump_all(documents, stream=None, **kwds): def safe_dump(data, stream=None, **kwds): - # type: (Any, Union[None, StreamType], Any) -> Union[None, str] + # type: (Any, Optional[StreamType], Any) -> Optional[str] """ Serialize a Python object into a YAML stream. Produce only basic YAML tags. @@ -1190,7 +1223,7 @@ def round_trip_dump( top_level_colon_align=None, prefix_colon=None, ): - # type: (Any, Union[None, StreamType], Any, Any, Any, Union[None, bool], Union[None, int], Union[None, int], Union[None, bool], Any, Any, Union[None, bool], Union[None, bool], Union[None, VersionType], Any, Any, Any, Any) -> Union[None, str] # NOQA + # type: (Any, Optional[StreamType], Any, Any, Any, Optional[bool], Optional[int], Optional[int], Optional[bool], Any, Any, Optional[bool], Optional[bool], Optional[VersionType], Any, Any, Any, Any) -> Optional[str] # NOQA allow_unicode = True if allow_unicode is None else allow_unicode return dump_all( [data], @@ -28,7 +28,7 @@ from ruamel.yaml.compat import text_type, binary_type, PY3, UNICODE_SIZE from ruamel.yaml.util import RegExp if False: # MYPY - from typing import Any, Dict, Optional, List, Union, Text, Tuple # NOQA + from typing import Any, Dict, Optional, List, Union, Text, Tuple, Optional # NOQA from ruamel.yaml.compat import StreamTextType # NOQA __all__ = ['Reader', 'ReaderError'] @@ -93,7 +93,7 @@ class Reader(object): self.pointer = 0 self.raw_buffer = None # type: Any self.raw_decode = None - self.encoding = None # type: Union[None, Text] + self.encoding = None # type: Optional[Text] self.index = 0 self.line = 0 self.column = 0 @@ -202,7 +202,7 @@ class Reader(object): @classmethod def _get_non_printable_ascii(cls, data): # type: ignore - # type: (Text, bytes) -> Union[None, Tuple[int, Text]] + # type: (Text, bytes) -> Optional[Tuple[int, Text]] ascii_bytes = data.encode('ascii') non_printables = ascii_bytes.translate(None, cls._printable_ascii) # type: ignore if not non_printables: @@ -212,7 +212,7 @@ class Reader(object): @classmethod def _get_non_printable_regex(cls, data): - # type: (Text) -> Union[None, Tuple[int, Text]] + # type: (Text) -> Optional[Tuple[int, Text]] match = cls.NON_PRINTABLE.search(data) if not bool(match): return None @@ -220,7 +220,7 @@ class Reader(object): @classmethod def _get_non_printable(cls, data): - # type: (Text) -> Union[None, Tuple[int, Text]] + # type: (Text) -> Optional[Tuple[int, Text]] try: return cls._get_non_printable_ascii(data) # type: ignore except UnicodeEncodeError: @@ -276,7 +276,7 @@ class Reader(object): break def update_raw(self, size=None): - # type: (Union[None, int]) -> None + # type: (Optional[int]) -> None if size is None: size = 4096 if PY3 else 1024 data = self.stream.read(size) diff --git a/representer.py b/representer.py index 07b2535..a659977 100644 --- a/representer.py +++ b/representer.py @@ -26,7 +26,7 @@ else: import copy_reg as copyreg # type: ignore if False: # MYPY - from typing import Dict, List, Any, Union, Text # NOQA + from typing import Dict, List, Any, Union, Text, Optional # NOQA # fmt: off __all__ = ['BaseRepresenter', 'SafeRepresenter', 'Representer', @@ -62,7 +62,7 @@ class BaseRepresenter(object): self.default_flow_style = default_flow_style self.represented_objects = {} # type: Dict[Any, Any] self.object_keeper = [] # type: List[Any] - self.alias_key = None # type: Union[None, int] + self.alias_key = None # type: Optional[int] @property def serializer(self): diff --git a/resolver.py b/resolver.py index 6b8c56e..34e3d1e 100644 --- a/resolver.py +++ b/resolver.py @@ -5,7 +5,7 @@ from __future__ import absolute_import import re if False: # MYPY - from typing import Any, Dict, List, Union, Text # NOQA + from typing import Any, Dict, List, Union, Text, Optional # NOQA from ruamel.yaml.compat import VersionType # NOQA from ruamel.yaml.compat import string_types, _DEFAULT_YAML_VERSION # NOQA @@ -377,7 +377,7 @@ class VersionedResolver(BaseResolver): """ def __init__(self, version=None, loader=None): - # type: (Union[None, VersionType], Any) -> None + # type: (Optional[VersionType], Any) -> None BaseResolver.__init__(self, loader) self._loader_version = self.get_loader_version(version) self._version_implicit_resolver = {} # type: Dict[Any, Any] @@ -391,7 +391,7 @@ class VersionedResolver(BaseResolver): impl_resolver.setdefault(ch, []).append((tag, regexp)) def get_loader_version(self, version): - # type: (Union[VersionType, None]) -> Any + # type: (Optional[VersionType]) -> Any if version is None or isinstance(version, tuple): return version if isinstance(version, list): diff --git a/serializer.py b/serializer.py index b2b26bf..fa4ae62 100644 --- a/serializer.py +++ b/serializer.py @@ -21,7 +21,7 @@ from ruamel.yaml.events import ( from ruamel.yaml.nodes import MappingNode, ScalarNode, SequenceNode if False: # MYPY - from typing import Any, Dict, Union, Text # NOQA + from typing import Any, Dict, Union, Text, Optional # NOQA from ruamel.yaml.compat import VersionType # NOQA __all__ = ['Serializer', 'SerializerError'] @@ -46,7 +46,7 @@ class Serializer(object): tags=None, dumper=None, ): - # type: (Any, Union[None, bool], Union[None, bool], Union[None, VersionType], Any, Any) -> None # NOQA + # type: (Any, Optional[bool], Optional[bool], Optional[VersionType], Any, Any) -> None # NOQA self.dumper = dumper if self.dumper is not None: self.dumper._serializer = self @@ -61,7 +61,7 @@ class Serializer(object): self.serialized_nodes = {} # type: Dict[Any, Any] self.anchors = {} # type: Dict[Any, Any] self.last_anchor_id = 0 - self.closed = None # type: Union[None, bool] + self.closed = None # type: Optional[bool] self._templated_id = None @property |