summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthon van der Neut <anthon@mnt.org>2017-03-16 08:50:30 +0100
committerAnthon van der Neut <anthon@mnt.org>2017-03-16 08:50:30 +0100
commitf75754aa90ea4d53f87aba5fce692185a25514c3 (patch)
tree678c37afebe1efd786d513e222a053a3cfe76a07
parent65537ac45d2fe35a98322aea5e6056baa1aefd8a (diff)
downloadruamel.yaml-f75754aa90ea4d53f87aba5fce692185a25514c3.tar.gz
some changes for mypy --strict
-rw-r--r--.hgignore1
-rw-r--r--Makefile6
-rw-r--r--__init__.py8
-rw-r--r--comments.py152
-rw-r--r--compat.py28
-rw-r--r--composer.py14
-rw-r--r--constructor.py145
-rw-r--r--emitter.py2
-rw-r--r--error.py5
-rw-r--r--main.py1
-rw-r--r--tokens.py1
-rw-r--r--util.py9
12 files changed, 300 insertions, 72 deletions
diff --git a/.hgignore b/.hgignore
index 303c646..da8328e 100644
--- a/.hgignore
+++ b/.hgignore
@@ -26,3 +26,4 @@ cmd
TODO.rst
_doc/_build
.dcw_alt.yml
+tags_for_scalarstrings
diff --git a/Makefile b/Makefile
index cebdacf..770f63e 100644
--- a/Makefile
+++ b/Makefile
@@ -24,6 +24,12 @@ ext/_yaml.c: ext/_yaml.pyx
ls-l:
ls -l dist/*$(VERSION)*
+mypy:
+ cd ..; mypy --strict --no-warn-unused-ignores yaml/*.py
+
+mypy2:
+ cd ..; mypy --py2 --strict --no-strict-boolean --no-warn-unused-ignores yaml/*.py
+
#tstvenv: testvenv testsetup testtest
#
#testvenv:
diff --git a/__init__.py b/__init__.py
index 78f694e..64b2f5e 100644
--- a/__init__.py
+++ b/__init__.py
@@ -6,10 +6,12 @@ from __future__ import print_function, absolute_import, division, unicode_litera
# ruamel.base installed __init__.py, and thus a new version should
# be installed at some point
+from typing import Dict, Any # NOQA
+
_package_data = dict(
full_package_name='ruamel.yaml',
- version_info=(0, 13, 14),
- __version__='0.13.14',
+ version_info=(0, 13, 15),
+ __version__='0.13.15',
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
@@ -49,7 +51,7 @@ _package_data = dict(
read_the_docs='yaml',
many_linux='libyaml-devel',
supported=[(2, 7), (3, 3)], # minimum
-)
+) # type: Dict[Any, Any]
version_info = _package_data['version_info']
diff --git a/comments.py b/comments.py
index e549a33..d77d72a 100644
--- a/comments.py
+++ b/comments.py
@@ -8,7 +8,9 @@ these are not really related, formatting could be factored out as
a separate base
"""
+from typing import Any, Dict, Optional, List, Union # NOQA
import copy
+
from collections import MutableSet, Sized, Set # type: ignore
from ruamel.yaml.compat import ordereddict, PY2
@@ -32,15 +34,17 @@ class Comment(object):
attrib = comment_attrib
def __init__(self):
+ # type: () -> None
self.comment = None # [post, [pre]]
# map key (mapping/omap/dict) or index (sequence/list) to a list of
# dict: post_key, pre_key, post_value, pre_value
# list: pre item, post item
- self._items = {}
+ self._items = {} # type: Dict[Any, Any]
# self._start = [] # should not put these on first item
- self._end = [] # end of document comments
+ self._end = [] # type: List[Any] # end of document comments
def __str__(self):
+ # type: () -> str
if self._end:
end = ',\n end=' + str(self._end)
else:
@@ -50,27 +54,33 @@ class Comment(object):
@property
def items(self):
+ # type: () -> Any
return self._items
@property
def end(self):
+ # type: () -> Any
return self._end
@end.setter
def end(self, value):
+ # type: (Any) -> None
self._end = value
@property
def start(self):
+ # type: () -> Any
return self._start
@start.setter
def start(self, value):
+ # type: (Any) -> None
self._start = value
# to distinguish key from None
def NoComment():
+ # type: () -> None
pass
@@ -79,15 +89,19 @@ class Format(object):
attrib = format_attrib
def __init__(self):
- self._flow_style = None
+ # type: () -> None
+ self._flow_style = None # type: Any
def set_flow_style(self):
+ # type: () -> None
self._flow_style = True
def set_block_style(self):
+ # type: () -> None
self._flow_style = False
def flow_style(self, default=None):
+ # type: (Optional[Any]) -> Any
"""if default (the flow_style) is None, the flow style tacked on to
the object explicitly will be taken. If that is None as well the
default flow style rules the format down the line, or the type
@@ -101,35 +115,42 @@ class LineCol(object):
attrib = line_col_attrib
def __init__(self):
+ # type: () -> None
self.line = None
self.col = None
- self.data = None
+ self.data = None # type: Union[None, Dict[Any, Any]]
def add_kv_line_col(self, key, data):
+ # type: (Any, Any) -> None
if self.data is None:
self.data = {}
self.data[key] = data
def key(self, k):
+ # type: (Any) -> Any
return self._kv(k, 0, 1)
def value(self, k):
+ # type: (Any) -> Any
return self._kv(k, 2, 3)
def _kv(self, k, x0, x1):
+ # type: (Any, Any, Any) -> Any
if self.data is None:
return None
data = self.data[k]
return data[x0], data[x1]
def item(self, idx):
+ # type: (Any) -> Any
if self.data is None:
return None
return self.data[idx][0], self.data[idx][1]
def add_idx_line_col(self, key, data):
+ # type: (Any, Any) -> None
if self.data is None:
- self.data = {}
+ self.data = {} # type: Dict[Any, Any]
self.data[key] = data
@@ -138,6 +159,7 @@ class Anchor(object):
attrib = anchor_attrib
def __init__(self):
+ # type: () -> None
self.value = None
self.always_dump = False
@@ -148,17 +170,20 @@ class Tag(object):
attrib = tag_attrib
def __init__(self):
+ # type: () -> None
self.value = None
class CommentedBase(object):
@property
def ca(self):
+ # type: () -> Any
if not hasattr(self, Comment.attrib):
setattr(self, Comment.attrib, Comment())
return getattr(self, Comment.attrib)
def yaml_end_comment_extend(self, comment, clear=False):
+ # type: (Any, bool) -> None
if comment is None:
return
if clear or self.ca.end is None:
@@ -166,6 +191,7 @@ class CommentedBase(object):
self.ca.end.extend(comment)
def yaml_key_comment_extend(self, key, comment, clear=False):
+ # type: (Any, Any, bool) -> None
l = self.ca._items.setdefault(key, [None, None, None, None])
if clear or l[1] is None:
if comment[1] is not None:
@@ -176,6 +202,7 @@ class CommentedBase(object):
l[0] = comment[0]
def yaml_value_comment_extend(self, key, comment, clear=False):
+ # type: (Any, Any, bool) -> None
l = self.ca._items.setdefault(key, [None, None, None, None])
if clear or l[3] is None:
if comment[1] is not None:
@@ -186,6 +213,7 @@ class CommentedBase(object):
l[2] = comment[0]
def yaml_set_start_comment(self, comment, indent=0):
+ # type: (Any, Any) -> None
"""overwrites any preceding comment lines on an object
expects comment to be without `#` and possible have multiple lines
"""
@@ -200,6 +228,7 @@ class CommentedBase(object):
def yaml_set_comment_before_after_key(self, key, before=None, indent=0,
after=None, after_indent=None):
+ # type: (Any, Any, Any, Any, Any) -> None
"""
expects comment (before/after) to be without `#` and possible have multiple lines
"""
@@ -207,6 +236,7 @@ class CommentedBase(object):
from ruamel.yaml.tokens import CommentToken
def comment_token(s, mark):
+ # type: (Any) -> Any
# handle empty lines as having no comment
return CommentToken(('# ' if s else '') + s + '\n', mark, None)
@@ -230,6 +260,7 @@ class CommentedBase(object):
@property
def fa(self):
+ # type: () -> Any
"""format attribute
set_flow_style()/set_block_style()"""
@@ -238,6 +269,7 @@ class CommentedBase(object):
return getattr(self, Format.attrib)
def yaml_add_eol_comment(self, comment, key=NoComment, column=None):
+ # type: (Any, Optional[Any], Optional[Any]) -> None
"""
there is a problem as eol comments should start with ' #'
(but at the beginning of the line the space doesn't have to be before
@@ -259,45 +291,55 @@ class CommentedBase(object):
@property
def lc(self):
+ # type: () -> Any
if not hasattr(self, LineCol.attrib):
setattr(self, LineCol.attrib, LineCol())
return getattr(self, LineCol.attrib)
def _yaml_set_line_col(self, line, col):
+ # type: (Any, Any) -> None
self.lc.line = line
self.lc.col = col
def _yaml_set_kv_line_col(self, key, data):
+ # type: (Any, Any) -> None
self.lc.add_kv_line_col(key, data)
def _yaml_set_idx_line_col(self, key, data):
+ # type: (Any, Any) -> None
self.lc.add_idx_line_col(key, data)
@property
def anchor(self):
+ # type: () -> Any
if not hasattr(self, Anchor.attrib):
setattr(self, Anchor.attrib, Anchor())
return getattr(self, Anchor.attrib)
def yaml_anchor(self):
+ # type: () -> Any
if not hasattr(self, Anchor.attrib):
return None
return self.anchor
def yaml_set_anchor(self, value, always_dump=False):
+ # type: (Any, bool) -> None
self.anchor.value = value
self.anchor.always_dump = always_dump
@property
def tag(self):
+ # type: () -> Any
if not hasattr(self, Tag.attrib):
setattr(self, Tag.attrib, Tag())
return getattr(self, Tag.attrib)
def yaml_set_tag(self, value):
+ # type: (Any) -> None
self.tag.value = value
def copy_attributes(self, t, deep=False):
+ # type: (Any, bool) -> None
for a in [Comment.attrib, Format.attrib, LineCol.attrib, Anchor.attrib,
Tag.attrib, merge_attrib]:
if hasattr(self, a):
@@ -306,23 +348,35 @@ class CommentedBase(object):
else:
setattr(t, a, getattr(self, a))
+ def _yaml_add_eol_comment(self, comment, key):
+ # type: (Any, Any) -> None
+ raise NotImplementedError
+
+ def _yaml_get_pre_comment(self):
+ # type: () -> Any
+ raise NotImplementedError
+
class CommentedSeq(list, CommentedBase):
__slots__ = Comment.attrib,
def _yaml_add_comment(self, comment, key=NoComment):
+ # type: (Any, Optional[Any]) -> None
if key is not NoComment:
self.yaml_key_comment_extend(key, comment)
else:
self.ca.comment = comment
def _yaml_add_eol_comment(self, comment, key):
+ # type: (Any, Any) -> None
self._yaml_add_comment(comment, key=key)
def _yaml_get_columnX(self, key):
+ # type: (Any) -> Any
return self.ca.items[key][0].start_mark.column
def insert(self, idx, val):
+ # type: (Any, Any) -> None
"""the comments after the insertion have to move forward"""
list.insert(self, idx, val)
for list_index in sorted(self.ca.items, reverse=True):
@@ -330,7 +384,8 @@ class CommentedSeq(list, CommentedBase):
break
self.ca.items[list_index+1] = self.ca.items.pop(list_index)
- def pop(self, idx):
+ def pop(self, idx=None):
+ # type: (Any) -> Any
res = list.pop(self, idx)
self.ca.items.pop(idx, None) # might not be there -> default value
for list_index in sorted(self.ca.items):
@@ -340,6 +395,7 @@ class CommentedSeq(list, CommentedBase):
return res
def _yaml_get_column(self, key):
+ # type: (Any) -> Any
column = None
sel_idx = None
pre, post = key-1, key+1
@@ -360,14 +416,16 @@ class CommentedSeq(list, CommentedBase):
return column
def _yaml_get_pre_comment(self):
+ # type: () -> Any
+ pre_comments = [] # type: List[Any]
if self.ca.comment is None:
- pre_comments = []
self.ca.comment = [None, pre_comments]
else:
- pre_comments = self.ca.comment[1] = []
+ self.ca.comment[1] = pre_comments
return pre_comments
def __deepcopy__(self, memo):
+ # type: (Any) -> Any
res = CommentedSeq()
memo[id(self)] = res
for k in self:
@@ -379,18 +437,22 @@ class CommentedSeq(list, CommentedBase):
class CommentedKeySeq(tuple, CommentedBase):
"""This primarily exists to be able to roundtrip keys that are sequences"""
def _yaml_add_comment(self, comment, key=NoComment):
+ # type: (Any, Optional[Any]) -> None
if key is not NoComment:
self.yaml_key_comment_extend(key, comment)
else:
self.ca.comment = comment
def _yaml_add_eol_comment(self, comment, key):
+ # type: (Any, Any) -> None
self._yaml_add_comment(comment, key=key)
def _yaml_get_columnX(self, key):
+ # type: (Any) -> Any
return self.ca.items[key][0].start_mark.column
def _yaml_get_column(self, key):
+ # type: (Any) -> Any
column = None
sel_idx = None
pre, post = key-1, key+1
@@ -411,11 +473,12 @@ class CommentedKeySeq(tuple, CommentedBase):
return column
def _yaml_get_pre_comment(self):
+ # type: () -> Any
+ pre_comments = [] # type: List[Any]
if self.ca.comment is None:
- pre_comments = []
self.ca.comment = [None, pre_comments]
else:
- pre_comments = self.ca.comment[1] = []
+ self.ca.comment[1] = pre_comments
return pre_comments
@@ -423,11 +486,13 @@ class CommentedMapView(Sized):
__slots__ = '_mapping',
def __init__(self, mapping):
+ # type: (Any) -> None
self._mapping = mapping
def __len__(self):
+ # type: () -> int
count = len(self._mapping)
- done = [] # list of processed merge items, kept for masking
+ done = [] # type: List[Any] # list of processed merge items, kept for masking
for merged in getattr(self._mapping, merge_attrib, []):
for x in merged[1]:
if self._mapping._unmerged_contains(x):
@@ -441,6 +506,7 @@ class CommentedMapView(Sized):
return count
def __repr__(self):
+ # type: () -> str
return '{0.__class__.__name__}({0._mapping!r})'.format(self)
@@ -449,13 +515,15 @@ class CommentedMapKeysView(CommentedMapView, Set):
@classmethod
def _from_iterable(self, it):
+ # type: (Any) -> Any
return set(it)
def __contains__(self, key):
+ # type: (Any) -> Any
return key in self._mapping
def __iter__(self):
- # yield from self._mapping # not in py27, pypy
+ # type: () -> Any # yield from self._mapping # not in py27, pypy
for x in self._mapping:
yield x
@@ -465,9 +533,11 @@ class CommentedMapItemsView(CommentedMapView, Set):
@classmethod
def _from_iterable(self, it):
+ # type: (Any) -> Any
return set(it)
def __contains__(self, item):
+ # type: (Any) -> Any
key, value = item
try:
v = self._mapping[key]
@@ -477,6 +547,7 @@ class CommentedMapItemsView(CommentedMapView, Set):
return v == value
def __iter__(self):
+ # type: () -> Any
for key in self._mapping._keys():
yield (key, self._mapping[key])
@@ -485,12 +556,14 @@ class CommentedMapValuesView(CommentedMapView):
__slots__ = ()
def __contains__(self, value):
+ # type: (Any) -> Any
for key in self._mapping:
if value == self._mapping[key]:
return True
return False
def __iter__(self):
+ # type: () -> Any
for key in self._mapping:
yield self._mapping[key]
@@ -499,6 +572,7 @@ class CommentedMap(ordereddict, CommentedBase):
__slots__ = Comment.attrib,
def _yaml_add_comment(self, comment, key=NoComment, value=NoComment):
+ # type: (Any, Optional[Any], Optional[Any]) -> None
"""values is set to key to indicate a value attachment of comment"""
if key is not NoComment:
self.yaml_key_comment_extend(key, comment)
@@ -509,13 +583,16 @@ class CommentedMap(ordereddict, CommentedBase):
self.ca.comment = comment
def _yaml_add_eol_comment(self, comment, key):
+ # type: (Any, Any) -> None
"""add on the value line, with value specified by the key"""
self._yaml_add_comment(comment, value=key)
def _yaml_get_columnX(self, key):
+ # type: (Any) -> Any
return self.ca.items[key][2].start_mark.column
def _yaml_get_column(self, key):
+ # type: (Any) -> Any
column = None
sel_idx = None
pre, post, last = None, None, None
@@ -543,14 +620,16 @@ class CommentedMap(ordereddict, CommentedBase):
return column
def _yaml_get_pre_comment(self):
+ # type: () -> Any
+ pre_comments = [] # type: List[Any]
if self.ca.comment is None:
- pre_comments = []
self.ca.comment = [None, pre_comments]
else:
- pre_comments = self.ca.comment[1] = []
+ self.ca.comment[1] = pre_comments
return pre_comments
def update(self, vals):
+ # type: (Any) -> None
try:
ordereddict.update(self, vals)
except TypeError:
@@ -559,6 +638,7 @@ class CommentedMap(ordereddict, CommentedBase):
self[x] = vals[x]
def insert(self, pos, key, value, comment=None):
+ # type: (Any, Any, Any, Optional[Any]) -> None
"""insert key value into given position
attach comment if provided
"""
@@ -567,12 +647,14 @@ class CommentedMap(ordereddict, CommentedBase):
self.yaml_add_eol_comment(comment, key=key)
def mlget(self, key, default=None, list_ok=False):
+ # type: (Any, Any, Any) -> Any
"""multi-level get that expects dicts within dicts"""
if not isinstance(key, list):
return self.get(key, default)
# assume that the key is a list of recursively accessible dicts
def get_one_level(key_list, level, d):
+ # type: (Any, Any, Any) -> Any
if not list_ok:
assert isinstance(d, dict)
if level >= len(key_list):
@@ -591,6 +673,7 @@ class CommentedMap(ordereddict, CommentedBase):
return default
def __getitem__(self, key):
+ # type: (Any) -> Any
try:
return ordereddict.__getitem__(self, key)
except KeyError:
@@ -600,10 +683,13 @@ class CommentedMap(ordereddict, CommentedBase):
raise
def _unmerged_contains(self, key):
+ # type: (Any) -> Any
if ordereddict.__contains__(self, key):
return True
+ return None
def __contains__(self, key):
+ # type: (Any) -> bool
if ordereddict.__contains__(self, key):
return True
# this will only work once the mapping/dict is built to completion
@@ -613,21 +699,25 @@ class CommentedMap(ordereddict, CommentedBase):
return False
def get(self, key, default=None):
+ # type: (Any, Any) -> Any
try:
return self.__getitem__(key)
except:
return default
def __repr__(self):
+ # type: () -> Any
if not hasattr(self, merge_attrib):
return ordereddict.__repr__(self)
return 'ordereddict(' + repr(list(self._items())) + ')'
def non_merged_items(self):
+ # type: () -> Any
for x in ordereddict.__iter__(self):
yield x, ordereddict.__getitem__(self, x)
def __delitem__(self, key):
+ # type: (Any) -> None
found = True
for merged in getattr(self, merge_attrib, []):
try:
@@ -642,9 +732,10 @@ class CommentedMap(ordereddict, CommentedBase):
raise
def __iter__(self):
+ # type: () -> Any
for x in ordereddict.__iter__(self):
yield x
- done = [] # list of processed merge items, kept for masking
+ done = [] # type: List[Any] # list of processed merge items, kept for masking
for merged in getattr(self, merge_attrib, []):
for x in merged[1]:
if ordereddict.__contains__(self, x):
@@ -657,9 +748,10 @@ class CommentedMap(ordereddict, CommentedBase):
done.append(merged[1])
def _keys(self):
+ # type: () -> Any
for x in ordereddict.__iter__(self):
yield x
- done = [] # list of processed merge items, kept for masking
+ done = [] # type: List[Any] # list of processed merge items, kept for masking
for merged in getattr(self, merge_attrib, []):
for x in merged[1]:
if ordereddict.__contains__(self, x):
@@ -673,21 +765,26 @@ class CommentedMap(ordereddict, CommentedBase):
if PY2:
def keys(self):
+ # type: () -> Any
return list(self._keys())
def iterkeys(self):
+ # type: () -> Any
return self._keys()
def viewkeys(self):
+ # type: () -> Any
return CommentedMapKeysView(self)
else:
def keys(self):
+ # type: () -> Any
return CommentedMapKeysView(self)
def _values(self):
+ # type: () -> Any
for x in ordereddict.__iter__(self):
yield ordereddict.__getitem__(self, x)
- done = [] # list of processed merge items, kept for masking
+ done = [] # type: List[Any] # list of processed merge items, kept for masking
for merged in getattr(self, merge_attrib, []):
for x in merged[1]:
if ordereddict.__contains__(self, x):
@@ -701,21 +798,26 @@ class CommentedMap(ordereddict, CommentedBase):
if PY2:
def values(self):
+ # type: () -> Any
return list(self._values())
def itervalues(self):
+ # type: () -> Any
return self._values()
def viewvalues(self):
+ # type: () -> Any
return CommentedMapValuesView(self)
else:
def values(self):
+ # type: () -> Any
return CommentedMapValuesView(self)
def _items(self):
+ # type: () -> Any
for x in ordereddict.__iter__(self):
yield x, ordereddict.__getitem__(self, x)
- done = [] # list of processed merge items, kept for masking
+ done = [] # type: List[Any] # list of processed merge items, kept for masking
for merged in getattr(self, merge_attrib, []):
for x in merged[1]:
if ordereddict.__contains__(self, x):
@@ -729,27 +831,34 @@ class CommentedMap(ordereddict, CommentedBase):
if PY2:
def items(self):
+ # type: () -> Any
return list(self._items())
def iteritems(self):
+ # type: () -> Any
return self._items()
def viewitems(self):
+ # type: () -> Any
return CommentedMapItemsView(self)
else:
def items(self):
+ # type: () -> Any
return CommentedMapItemsView(self)
@property
def merge(self):
+ # type: () -> Any
if not hasattr(self, merge_attrib):
setattr(self, merge_attrib, [])
return getattr(self, merge_attrib)
def add_yaml_merge(self, value):
+ # type: (Any) -> None
self.merge.extend(value)
def __deepcopy__(self, memo):
+ # type: (Any) -> Any
res = CommentedMap()
memo[id(self)] = res
for k in self:
@@ -766,28 +875,35 @@ class CommentedSet(MutableSet, CommentedMap):
__slots__ = Comment.attrib, 'odict',
def __init__(self, values=None):
+ # type: (Optional[Any]) -> None
self.odict = ordereddict()
MutableSet.__init__(self)
if values is not None:
self |= values
def add(self, value):
+ # type: (Any) -> None
"""Add an element."""
self.odict[value] = None
def discard(self, value):
+ # type: (Any) -> None
"""Remove an element. Do not raise an exception if absent."""
del self.odict[value]
def __contains__(self, x):
+ # type: (Any) -> Any
return x in self.odict
def __iter__(self):
+ # type: () -> Any
for x in self.odict:
yield x
def __len__(self):
+ # type: () -> int
return len(self.odict)
def __repr__(self):
+ # type: () -> str
return 'set({0!r})'.format(self.odict.keys())
diff --git a/compat.py b/compat.py
index 4a3f07c..d9fc76c 100644
--- a/compat.py
+++ b/compat.py
@@ -8,6 +8,9 @@ import sys
import os
import types
+from typing import Any, Dict, Optional, List, Union # NOQA
+
+
try:
from ruamel.ordereddict import ordereddict # type: ignore
except:
@@ -20,6 +23,7 @@ except:
class ordereddict(OrderedDict): # type: ignore
if not hasattr(OrderedDict, 'insert'):
def insert(self, pos, key, value):
+ # type: (int, Any, Any) -> None
if pos >= len(self):
self[key] = value
return
@@ -39,22 +43,28 @@ PY3 = sys.version_info[0] == 3
if PY3:
def utf8(s):
+ # type: (str) -> str
return s
def to_str(s):
+ # type: (str) -> str
return s
def to_unicode(s):
+ # type: (str) -> str
return s
else:
def utf8(s):
+ # type: (unicode) -> str
return s.encode('utf-8')
def to_str(s):
+ # type: (str) -> str
return str(s)
def to_unicode(s):
+ # type: (str) -> unicode
return unicode(s)
if PY3:
@@ -91,6 +101,7 @@ else:
def with_metaclass(meta, *bases):
+ # type: (Any, Any) -> Any
"""Create a base class with a metaclass."""
return meta("NewBase", bases, {})
@@ -99,17 +110,20 @@ DBG_EVENT = 2
DBG_NODE = 4
-_debug = None
+_debug = None # type: Union[None, int]
if _debug:
class ObjectCounter(object):
def __init__(self):
- self.map = {}
+ # type: () -> None
+ self.map = {} # type: Dict[Any, Any]
def __call__(self, k):
+ # type: (Any) -> None
self.map[k] = self.map.get(k, 0) + 1
def dump(self):
+ # type: () -> None
for k in sorted(self.map):
print(k, '->', self.map[k])
@@ -118,20 +132,22 @@ if _debug:
# used from yaml util when testing
def dbg(val=None):
+ # type: (Any) -> Any
global _debug
if _debug is None:
# set to true or false
- _debug = os.environ.get('YAMLDEBUG')
- if _debug is None:
+ _debugx = os.environ.get('YAMLDEBUG')
+ if _debugx is None:
_debug = 0
else:
- _debug = int(_debug)
+ _debug = int(_debugx)
if val is None:
return _debug
return _debug & val
def nprint(*args, **kw):
+ # type: (Any, Any) -> None
if dbg:
print(*args, **kw)
@@ -139,6 +155,7 @@ def nprint(*args, **kw):
def check_namespace_char(ch):
+ # type: (Any) -> bool
if u'\x21' <= ch <= u'\x7E': # ! to ~
return True
if u'\xA0' <= ch <= u'\xD7FF':
@@ -151,6 +168,7 @@ def check_namespace_char(ch):
def check_anchorname_char(ch):
+ # type: (Any) -> bool
if ch in u',[]{}':
return False
return check_namespace_char(ch)
diff --git a/composer.py b/composer.py
index 791bf50..bbaa62f 100644
--- a/composer.py
+++ b/composer.py
@@ -5,6 +5,8 @@ from __future__ import print_function
import warnings
+from typing import Any, Dict, Optional, List # NOQA
+
from ruamel.yaml.error import MarkedYAMLError, ReusedAnchorWarning
from ruamel.yaml.compat import utf8
@@ -25,9 +27,11 @@ class ComposerError(MarkedYAMLError):
class Composer(object):
def __init__(self):
- self.anchors = {}
+ # type: () -> None
+ self.anchors = {} # type: Dict[Any, Any]
def check_node(self):
+ # type: () -> Any
# Drop the STREAM-START event.
if self.check_event(StreamStartEvent):
self.get_event()
@@ -36,11 +40,13 @@ class Composer(object):
return not self.check_event(StreamEndEvent)
def get_node(self):
+ # type: () -> Any
# Get the root node of the next document.
if not self.check_event(StreamEndEvent):
return self.compose_document()
def get_single_node(self):
+ # type: () -> Any
# Drop the STREAM-START event.
self.get_event()
@@ -63,6 +69,7 @@ class Composer(object):
return document
def compose_document(self):
+ # type: (Any) -> Any
# Drop the DOCUMENT-START event.
self.get_event()
@@ -76,6 +83,7 @@ class Composer(object):
return node
def compose_node(self, parent, index):
+ # type: (Any, Any) -> Any
if self.check_event(AliasEvent):
event = self.get_event()
alias = event.anchor
@@ -107,6 +115,7 @@ class Composer(object):
return node
def compose_scalar_node(self, anchor):
+ # type: (Any) -> Any
event = self.get_event()
tag = event.tag
if tag is None or tag == u'!':
@@ -119,6 +128,7 @@ class Composer(object):
return node
def compose_sequence_node(self, anchor):
+ # type: (Any) -> Any
start_event = self.get_event()
tag = start_event.tag
if tag is None or tag == u'!':
@@ -144,6 +154,7 @@ class Composer(object):
return node
def compose_mapping_node(self, anchor):
+ # type: (Any) -> Any
start_event = self.get_event()
tag = start_event.tag
if tag is None or tag == u'!':
@@ -172,6 +183,7 @@ class Composer(object):
return node
def check_end_doc_comment(self, end_event, node):
+ # type: (Any, Any) -> None
if end_event.comment and end_event.comment[1]:
# pre comments on an end_event, no following to move to
if node.comment is None:
diff --git a/constructor.py b/constructor.py
index 4d3962d..d425bae 100644
--- a/constructor.py
+++ b/constructor.py
@@ -14,10 +14,15 @@ from typing import Any, Dict # NOQA
from ruamel.yaml.error import * # NOQA
from ruamel.yaml.nodes import * # NOQA
-from ruamel.yaml.compat import (utf8, builtins_module, to_str, PY2, PY3,
- ordereddict, text_type)
+from ruamel.yaml.nodes import (SequenceNode, MappingNode, ScalarNode)
+from ruamel.yaml.compat import (utf8, builtins_module, to_str, PY2, PY3, # NOQA
+ ordereddict, text_type, nprint)
from ruamel.yaml.comments import * # NOQA
+from ruamel.yaml.comments import (CommentedMap, CommentedOrderedMap, CommentedSet,
+ CommentedKeySeq, CommentedSeq)
from ruamel.yaml.scalarstring import * # NOQA
+from ruamel.yaml.scalarstring import (PreservedScalarString, SingleQuotedScalarString,
+ DoubleQuotedScalarString, ScalarString)
from ruamel.yaml.timestamp import TimeStamp
__all__ = ['BaseConstructor', 'SafeConstructor', 'Constructor',
@@ -34,6 +39,7 @@ class BaseConstructor(object):
yaml_multi_constructors = {} # type: Dict[Any, Any]
def __init__(self, preserve_quotes=None):
+ # type: (Any) -> None
self.constructed_objects = {}
self.recursive_objects = {}
self.state_generators = []
@@ -41,15 +47,18 @@ class BaseConstructor(object):
self._preserve_quotes = preserve_quotes
def check_data(self):
+ # type: () -> Any
# If there are more documents available?
return self.check_node()
def get_data(self):
+ # type: () -> Any
# Construct and return the next document.
if self.check_node():
return self.construct_document(self.get_node())
def get_single_data(self):
+ # type: () -> Any
# Ensure that the stream contains a single document and construct it.
node = self.get_single_node()
if node is not None:
@@ -57,6 +66,7 @@ class BaseConstructor(object):
return None
def construct_document(self, node):
+ # type: (Any) -> Any
data = self.construct_object(node)
while self.state_generators:
state_generators = self.state_generators
@@ -70,6 +80,7 @@ class BaseConstructor(object):
return data
def construct_object(self, node, deep=False):
+ # type: (Any, bool) -> Any
"""deep is True when creating an object/mapping recursively,
in that case want the underlying elements available during construction
"""
@@ -124,6 +135,7 @@ class BaseConstructor(object):
return data
def construct_scalar(self, node):
+ # type: (Any) -> Any
if not isinstance(node, ScalarNode):
raise ConstructorError(
None, None,
@@ -132,6 +144,7 @@ class BaseConstructor(object):
return node.value
def construct_sequence(self, node, deep=False):
+ # type: (Any, bool) -> Any
"""deep is True when creating an object/mapping recursively,
in that case want the underlying elements available during construction
"""
@@ -144,6 +157,7 @@ class BaseConstructor(object):
for child in node.value]
def construct_mapping(self, node, deep=False):
+ # type: (Any, bool) -> Any
"""deep is True when creating an object/mapping recursively,
in that case want the underlying elements available during construction
"""
@@ -179,6 +193,7 @@ class BaseConstructor(object):
return mapping
def construct_pairs(self, node, deep=False):
+ # type: (Any, bool) -> Any
if not isinstance(node, MappingNode):
raise ConstructorError(
None, None,
@@ -208,6 +223,7 @@ class BaseConstructor(object):
class SafeConstructor(BaseConstructor):
def construct_scalar(self, node):
+ # type: (Any) -> Any
if isinstance(node, MappingNode):
for key_node, value_node in node.value:
if key_node.tag == u'tag:yaml.org,2002:value':
@@ -215,6 +231,7 @@ class SafeConstructor(BaseConstructor):
return BaseConstructor.construct_scalar(self, node)
def flatten_mapping(self, node):
+ # type: (Any) -> Any
"""
This implements the merge key feature http://yaml.org/type/merge.html
by inserting keys from the merge dict/list of dicts if not yet
@@ -258,6 +275,7 @@ class SafeConstructor(BaseConstructor):
node.value = merge + node.value
def construct_mapping(self, node, deep=False):
+ # type: (Any, bool) -> Any
"""deep is True when creating an object/mapping recursively,
in that case want the underlying elements available during construction
"""
@@ -266,6 +284,7 @@ class SafeConstructor(BaseConstructor):
return BaseConstructor.construct_mapping(self, node, deep=deep)
def construct_yaml_null(self, node):
+ # type: (Any) -> Any
self.construct_scalar(node)
return None
@@ -280,29 +299,31 @@ class SafeConstructor(BaseConstructor):
}
def construct_yaml_bool(self, node):
+ # type: (Any) -> bool
value = self.construct_scalar(node)
return self.bool_values[value.lower()]
def construct_yaml_int(self, node):
- value = to_str(self.construct_scalar(node))
- value = value.replace('_', '')
+ # type: (Any) -> int
+ value_s = to_str(self.construct_scalar(node))
+ value_s = value_s.replace('_', '')
sign = +1
- if value[0] == '-':
+ if value_s[0] == '-':
sign = -1
- if value[0] in '+-':
- value = value[1:]
- if value == '0':
+ if value_s[0] in '+-':
+ value_s = value_s[1:]
+ if value_s == '0':
return 0
- elif value.startswith('0b'):
- return sign*int(value[2:], 2)
- elif value.startswith('0x'):
- return sign*int(value[2:], 16)
- elif value.startswith('0o'):
- return sign*int(value[2:], 8)
- elif self.processing_version != (1, 2) and value[0] == '0':
- return sign*int(value, 8)
- elif self.processing_version != (1, 2) and ':' in value:
- digits = [int(part) for part in value.split(':')]
+ elif value_s.startswith('0b'):
+ return sign*int(value_s[2:], 2)
+ elif value_s.startswith('0x'):
+ return sign*int(value_s[2:], 16)
+ elif value_s.startswith('0o'):
+ return sign*int(value_s[2:], 8)
+ elif self.processing_version != (1, 2) and value_s[0] == '0':
+ return sign*int(value_s, 8)
+ elif self.processing_version != (1, 2) and ':' in value_s:
+ digits = [int(part) for part in value_s.split(':')]
digits.reverse()
base = 1
value = 0
@@ -311,7 +332,7 @@ class SafeConstructor(BaseConstructor):
base *= 60
return sign*value
else:
- return sign*int(value)
+ return sign*int(value_s)
inf_value = 1e300
while inf_value != inf_value*inf_value:
@@ -319,19 +340,20 @@ class SafeConstructor(BaseConstructor):
nan_value = -inf_value/inf_value # Trying to make a quiet NaN (like C99).
def construct_yaml_float(self, node):
- value = to_str(self.construct_scalar(node))
- value = value.replace('_', '').lower()
+ # type: (Any) -> float
+ value_s = to_str(self.construct_scalar(node))
+ value_s = value_s.replace('_', '').lower()
sign = +1
- if value[0] == '-':
+ if value_s[0] == '-':
sign = -1
- if value[0] in '+-':
- value = value[1:]
- if value == '.inf':
+ if value_s[0] in '+-':
+ value_s = value_s[1:]
+ if value_s == '.inf':
return sign*self.inf_value
- elif value == '.nan':
+ elif value_s == '.nan':
return self.nan_value
- elif ':' in value:
- digits = [float(part) for part in value.split(':')]
+ elif ':' in value_s:
+ digits = [float(part) for part in value_s.split(':')]
digits.reverse()
base = 1
value = 0.0
@@ -340,10 +362,11 @@ class SafeConstructor(BaseConstructor):
base *= 60
return sign*value
else:
- return sign*float(value)
+ return sign*float(value_s)
if PY3:
def construct_yaml_binary(self, node):
+ # type: (Any) -> Any
try:
value = self.construct_scalar(node).encode('ascii')
except UnicodeEncodeError as exc:
@@ -362,6 +385,7 @@ class SafeConstructor(BaseConstructor):
"failed to decode base64 data: %s" % exc, node.start_mark)
else:
def construct_yaml_binary(self, node):
+ # type: (Any) -> Any
value = self.construct_scalar(node)
try:
return to_str(value).decode('base64')
@@ -383,6 +407,7 @@ class SafeConstructor(BaseConstructor):
(?::(?P<tz_minute>[0-9][0-9]))?))?)?$''', re.X)
def construct_yaml_timestamp(self, node, values=None):
+ # type: (Any, Any) -> Any
if values is None:
match = self.timestamp_regexp.match(node.value)
values = match.groupdict()
@@ -396,10 +421,10 @@ class SafeConstructor(BaseConstructor):
second = int(values['second'])
fraction = 0
if values['fraction']:
- fraction = values['fraction'][:6]
- while len(fraction) < 6:
- fraction += '0'
- fraction = int(fraction)
+ fraction_s = values['fraction'][:6]
+ while len(fraction_s) < 6:
+ fraction_s += '0'
+ fraction = int(fraction_s)
if len(values['fraction']) > 6 and int(values['fraction'][6]) > 4:
fraction += 1
delta = None
@@ -416,6 +441,7 @@ class SafeConstructor(BaseConstructor):
return data
def construct_yaml_omap(self, node):
+ # type: (Any) -> Any
# Note: we do now check for duplicate keys
omap = ordereddict()
yield omap
@@ -443,6 +469,7 @@ class SafeConstructor(BaseConstructor):
omap[key] = value
def construct_yaml_pairs(self, node):
+ # type: (Any) -> Any
# Note: the same code as `construct_yaml_omap`.
pairs = []
yield pairs
@@ -469,12 +496,14 @@ class SafeConstructor(BaseConstructor):
pairs.append((key, value))
def construct_yaml_set(self, node):
+ # type: (Any) -> Any
data = set()
yield data
value = self.construct_mapping(node)
data.update(value)
def construct_yaml_str(self, node):
+ # type: (Any) -> Any
value = self.construct_scalar(node)
if PY3:
return value
@@ -484,17 +513,20 @@ class SafeConstructor(BaseConstructor):
return value
def construct_yaml_seq(self, node):
+ # type: (Any) -> Any
data = []
yield data
data.extend(self.construct_sequence(node))
def construct_yaml_map(self, node):
+ # type: (Any) -> Any
data = {}
yield data
value = self.construct_mapping(node)
data.update(value)
def construct_yaml_object(self, node, cls):
+ # type: (Any, Any) -> Any
data = cls.__new__(cls)
yield data
if hasattr(data, '__setstate__'):
@@ -505,6 +537,7 @@ class SafeConstructor(BaseConstructor):
data.__dict__.update(state)
def construct_undefined(self, node):
+ # type: (Any) -> None
raise ConstructorError(
None, None,
"could not determine a constructor for the tag %r" %
@@ -566,13 +599,16 @@ SafeConstructor.add_constructor(
class Constructor(SafeConstructor):
def construct_python_str(self, node):
+ # type: (Any) -> Any
return utf8(self.construct_scalar(node))
def construct_python_unicode(self, node):
+ # type: (Any) -> Any
return self.construct_scalar(node)
if PY3:
def construct_python_bytes(self, node):
+ # type: (Any) -> Any
try:
value = self.construct_scalar(node).encode('ascii')
except UnicodeEncodeError as exc:
@@ -591,18 +627,22 @@ class Constructor(SafeConstructor):
"failed to decode base64 data: %s" % exc, node.start_mark)
def construct_python_long(self, node):
+ # type: (Any) -> int
val = self.construct_yaml_int(node)
if PY3:
return val
return int(val)
def construct_python_complex(self, node):
+ # type: (Any) -> Any
return complex(self.construct_scalar(node))
def construct_python_tuple(self, node):
+ # type: (Any) -> Any
return tuple(self.construct_sequence(node))
def find_python_module(self, name, mark):
+ # type: (Any, Any) -> Any
if not name:
raise ConstructorError(
"while constructing a Python module", mark,
@@ -616,6 +656,7 @@ class Constructor(SafeConstructor):
return sys.modules[name]
def find_python_name(self, name, mark):
+ # type: (Any, Any) -> Any
if not name:
raise ConstructorError(
"while constructing a Python object", mark,
@@ -640,6 +681,7 @@ class Constructor(SafeConstructor):
return getattr(module, object_name)
def construct_python_name(self, suffix, node):
+ # type: (Any, Any) -> Any
value = self.construct_scalar(node)
if value:
raise ConstructorError(
@@ -649,6 +691,7 @@ class Constructor(SafeConstructor):
return self.find_python_name(suffix, node.start_mark)
def construct_python_module(self, suffix, node):
+ # type: (Any, Any) -> Any
value = self.construct_scalar(node)
if value:
raise ConstructorError(
@@ -663,6 +706,7 @@ class Constructor(SafeConstructor):
def make_python_instance(self, suffix, node,
args=None, kwds=None, newobj=False):
+ # type: (Any, Any, Any, Any, bool) -> Any
if not args:
args = []
if not kwds:
@@ -685,10 +729,11 @@ class Constructor(SafeConstructor):
return cls(*args, **kwds)
def set_python_instance_state(self, instance, state):
+ # type: (Any, Any) -> None
if hasattr(instance, '__setstate__'):
instance.__setstate__(state)
else:
- slotstate = {}
+ slotstate = {} # type: Dict[Any, Any]
if isinstance(state, tuple) and len(state) == 2:
state, slotstate = state
if hasattr(instance, '__dict__'):
@@ -699,6 +744,7 @@ class Constructor(SafeConstructor):
setattr(object, key, value)
def construct_python_object(self, suffix, node):
+ # type: (Any, Any) -> Any
# Format:
# !!python/object:module.name { ... state ... }
instance = self.make_python_instance(suffix, node, newobj=True)
@@ -708,6 +754,7 @@ class Constructor(SafeConstructor):
self.set_python_instance_state(instance, state)
def construct_python_object_apply(self, suffix, node, newobj=False):
+ # type: (Any, Any, bool) -> Any
# Format:
# !!python/object/apply # (or !!python/object/new)
# args: [ ... arguments ... ]
@@ -721,10 +768,10 @@ class Constructor(SafeConstructor):
# is how an object is created, check make_python_instance for details.
if isinstance(node, SequenceNode):
args = self.construct_sequence(node, deep=True)
- kwds = {}
- state = {}
- listitems = []
- dictitems = {}
+ kwds = {} # type: Dict[Any, Any]
+ state = {} # type: Dict[Any, Any]
+ listitems = [] # List[Any]
+ dictitems = {} # type: Dict[Any, Any]
else:
value = self.construct_mapping(node, deep=True)
args = value.get('args', [])
@@ -743,6 +790,7 @@ class Constructor(SafeConstructor):
return instance
def construct_python_object_new(self, suffix, node):
+ # type: (Any, Any) -> Any
return self.construct_python_object_apply(suffix, node, newobj=True)
Constructor.add_constructor(
@@ -821,6 +869,7 @@ class RoundTripConstructor(SafeConstructor):
"""
def construct_scalar(self, node):
+ # type: (Any) -> Any
if not isinstance(node, ScalarNode):
raise ConstructorError(
None, None,
@@ -837,6 +886,7 @@ class RoundTripConstructor(SafeConstructor):
return node.value
def construct_yaml_str(self, node):
+ # type: (Any) -> Any
value = self.construct_scalar(node)
if isinstance(value, ScalarString):
return value
@@ -851,6 +901,7 @@ class RoundTripConstructor(SafeConstructor):
return value
def construct_sequence(self, node, seqtyp, deep=False):
+ # type: (Any, Any, bool) -> Any
if not isinstance(node, SequenceNode):
raise ConstructorError(
None, None,
@@ -874,6 +925,7 @@ class RoundTripConstructor(SafeConstructor):
return ret_val
def flatten_mapping(self, node):
+ # type: (Any) -> Any
"""
This implements the merge key feature http://yaml.org/type/merge.html
by inserting keys from the merge dict/list of dicts if not yet
@@ -935,9 +987,11 @@ class RoundTripConstructor(SafeConstructor):
# node.value = merge + node.value
def _sentinel(self):
+ # type: () -> None
pass
def construct_mapping(self, node, maptyp, deep=False):
+ # type: (Any, Any, bool) -> Any
if not isinstance(node, MappingNode):
raise ConstructorError(
None, None,
@@ -1004,6 +1058,7 @@ class RoundTripConstructor(SafeConstructor):
maptyp.add_yaml_merge(merge_map)
def construct_setting(self, node, typ, deep=False):
+ # type: (Any, Any, bool) -> Any
if not isinstance(node, MappingNode):
raise ConstructorError(
None, None,
@@ -1045,6 +1100,7 @@ class RoundTripConstructor(SafeConstructor):
typ.add(key)
def construct_yaml_seq(self, node):
+ # type: (Any) -> Any
data = CommentedSeq()
data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
if node.flow_style is True:
@@ -1057,6 +1113,7 @@ class RoundTripConstructor(SafeConstructor):
data.extend(self.construct_sequence(node, data))
def construct_yaml_map(self, node):
+ # type: (Any) -> Any
data = CommentedMap()
data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
if node.flow_style is True:
@@ -1067,6 +1124,7 @@ class RoundTripConstructor(SafeConstructor):
self.construct_mapping(node, data)
def construct_yaml_omap(self, node):
+ # type: (Any) -> Any
# Note: we do now check for duplicate keys
omap = CommentedOrderedMap()
omap._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
@@ -1109,12 +1167,14 @@ class RoundTripConstructor(SafeConstructor):
omap[key] = value
def construct_yaml_set(self, node):
+ # type: (Any) -> Any
data = CommentedSet()
data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
yield data
self.construct_setting(node, data)
def construct_undefined(self, node):
+ # type: (Any) -> Any
try:
data = CommentedMap()
data._yaml_set_line_col(node.start_mark.line, node.start_mark.column)
@@ -1133,6 +1193,7 @@ class RoundTripConstructor(SafeConstructor):
node.start_mark)
def construct_yaml_timestamp(self, node):
+ # type: (Any) -> Any
match = self.timestamp_regexp.match(node.value)
values = match.groupdict()
if not values['hour']:
@@ -1150,10 +1211,10 @@ class RoundTripConstructor(SafeConstructor):
second = int(values['second'])
fraction = 0
if values['fraction']:
- fraction = values['fraction'][:6]
- while len(fraction) < 6:
- fraction += '0'
- fraction = int(fraction)
+ fraction_s = values['fraction'][:6]
+ while len(fraction_s) < 6:
+ fraction_s += '0'
+ fraction = int(fraction_s)
if len(values['fraction']) > 6 and int(values['fraction'][6]) > 4:
fraction += 1
delta = None
diff --git a/emitter.py b/emitter.py
index a1cdf54..4feb6b2 100644
--- a/emitter.py
+++ b/emitter.py
@@ -1229,7 +1229,7 @@ class Emitter(object):
def write_comment(self, comment):
value = comment.value
- # print('{:02d} {:02d} {}'.format(self.column, comment.start_mark.column, value))
+ # print('{:02d} {:02d} {!r}'.format(self.column, comment.start_mark.column, value))
if value[-1] == '\n':
value = value[:-1]
try:
diff --git a/error.py b/error.py
index 9055746..e140c5f 100644
--- a/error.py
+++ b/error.py
@@ -4,6 +4,8 @@ from __future__ import absolute_import
import warnings
+from typing import Any, Dict, Optional, List # NOQA
+
from ruamel.yaml.compat import utf8
__all__ = ['FileMark', 'StringMark', 'CommentMark',
@@ -78,6 +80,7 @@ class CommentMark(object):
__slots__ = 'column',
def __init__(self, column):
+ # type: (Any) -> None
self.column = column
@@ -88,6 +91,7 @@ class YAMLError(Exception):
class MarkedYAMLError(YAMLError):
def __init__(self, context=None, context_mark=None,
problem=None, problem_mark=None, note=None):
+ # type: (Any, Any, Any, Any, Any) -> None
self.context = context
self.context_mark = context_mark
self.problem = problem
@@ -95,6 +99,7 @@ class MarkedYAMLError(YAMLError):
self.note = note
def __str__(self):
+ # type: () -> str
lines = []
if self.context is not None:
lines.append(self.context)
diff --git a/main.py b/main.py
index 0792d71..0946899 100644
--- a/main.py
+++ b/main.py
@@ -125,6 +125,7 @@ def safe_load_all(stream, version=None):
def round_trip_load(stream, version=None, preserve_quotes=None):
+ # type: (Any, Any, bool) -> Any
"""
Parse the first YAML document in a stream
and produce the corresponding Python object.
diff --git a/tokens.py b/tokens.py
index a4646bd..9001216 100644
--- a/tokens.py
+++ b/tokens.py
@@ -216,6 +216,7 @@ class CommentToken(Token):
id = '<comment>'
def __init__(self, value, start_mark, end_mark):
+ # type: (Any, Any, Any) -> None
Token.__init__(self, start_mark, end_mark)
self.value = value
diff --git a/util.py b/util.py
index 25c64e4..40aed9e 100644
--- a/util.py
+++ b/util.py
@@ -4,8 +4,9 @@
some helper functions that might be generally useful
"""
-from __future__ import print_function
-from __future__ import absolute_import
+from __future__ import absolute_import, print_function
+
+from typing import Any, Dict, Optional, List # NOQA
from .compat import text_type, binary_type
@@ -16,6 +17,7 @@ from .compat import text_type, binary_type
# that check this routines output against a known piece of your YAML
# before upgrades to this code break your round-tripped YAML
def load_yaml_guess_indent(stream, **kw):
+ # type: (Any, Any) -> Any
"""guess the indent and block sequence indent of yaml stream/string
returns round_trip_loaded stream, indent level, block sequence indent
@@ -27,6 +29,7 @@ def load_yaml_guess_indent(stream, **kw):
# load a yaml file guess the indentation, if you use TABs ...
def leading_spaces(l):
+ # type: (Any) -> int
idx = 0
while idx < len(l) and l[idx] == ' ':
idx += 1
@@ -76,6 +79,7 @@ def load_yaml_guess_indent(stream, **kw):
def configobj_walker(cfg):
+ # type: (Any) -> Any
"""
walks over a ConfigObj (INI file with comments) generating
corresponding YAML output (including comments
@@ -94,6 +98,7 @@ def configobj_walker(cfg):
def _walk_section(s, level=0):
+ # type: (Any, int) -> Any
from configobj import Section
assert isinstance(s, Section)
indent = u' ' * level