1- from abc import ABC
1+ from abc import ABCMeta
22from collections import OrderedDict
3- from io import TextIOBase , StringIO
4- from typing import Union , TypeVar , Dict , Any
5- from warnings import warn
63
74try :
8- from typing import Type
5+ # Python 2 only:
6+ from StringIO import StringIO
7+
8+ # create a variant that can serve as a context manager
9+ class StringIO (StringIO ):
10+ def __enter__ (self ):
11+ return self
12+ def __exit__ (self , exception_type , exception_value , traceback ):
13+ self .close ()
14+
915except ImportError :
10- pass # normal for old versions of typing
16+ # (IOBase is only used in type hints)
17+ from io import IOBase , StringIO
18+
19+ from warnings import warn
1120
21+ import six
1222
13- Y = TypeVar ('Y' , bound = 'AbstractYamlObject' )
23+ try : # python 3.5+
24+ from typing import Union , TypeVar , Dict , Any
25+
26+ Y = TypeVar ('Y' , bound = 'AbstractYamlObject' )
27+
28+ except ImportError :
29+ pass
30+
31+ try : # python 3.5.4+
32+ from typing import Type
33+ except ImportError :
34+ pass # normal for old versions of typing
1435
1536
16- class AbstractYamlObject (ABC ):
37+ class AbstractYamlObject (six . with_metaclass ( ABCMeta , object ) ):
1738 """
1839 Adds convenient methods load(s)_yaml/dump(s)_yaml to any object, to call pyyaml features directly on the object or
1940 on the object class.
@@ -22,24 +43,30 @@ class AbstractYamlObject(ABC):
2243 Default implementation uses vars(self) and cls(**dct), but subclasses can override.
2344 """
2445
25- def __to_yaml_dict__ (self ) -> Dict [str , Any ]:
46+ def __to_yaml_dict__ (self ):
47+ # type: (...) -> Dict[str, Any]
2648 """
2749 Implementors should transform the object into a dictionary containing all information necessary to decode the
2850 object in the future. That dictionary will be serialized as a YAML mapping.
2951
3052 Default implementation returns vars(self). TODO maybe some day we'll need to rather make a copy...?
3153 :return:
3254 """
33- # Legacy compliance TODO remove in future version
55+ # Legacy compliance with old 'not dunder' method name TODO remove in future version
3456 if 'to_yaml_dict' in dir (self ):
3557 warn (type (self ).__name__ + " still uses the legacy method name 'to_yaml_dict'. This name will not be "
3658 "supported in future version, please use '__to_yaml_dict__' instead" )
3759 return self .to_yaml_dict ()
3860
61+ # Default: return vars
3962 return vars (self )
4063
4164 @classmethod
42- def __from_yaml_dict__ (cls : 'Type[Y]' , dct : Dict [Any , Any ], yaml_tag : str ) -> Y :
65+ def __from_yaml_dict__ (cls , # type: Type[Y]
66+ dct , # type: Dict[str, Any]
67+ yaml_tag # type: str
68+ ):
69+ # type: (...) -> Y
4370 """
4471 Implementors should transform the given dictionary (read from yaml by the pyYaml stack) into an object instance.
4572 The yaml tag associated to this object, read in the yaml document, is provided in parameter.
@@ -54,15 +81,21 @@ def __from_yaml_dict__(cls: 'Type[Y]', dct: Dict[Any, Any], yaml_tag: str) -> Y:
5481 against is_json_schema_id_supported)
5582 :return:
5683 """
57- # Legacy compliance TODO remove in future version
84+ # Legacy compliance with old 'not dunder' method name TODO remove in future version
5885 if 'from_yaml_dict' in dir (cls ):
5986 warn (cls .__name__ + " still uses the legacy method name 'from_yaml_dict'. This name will not be "
6087 "supported in future version, please use '__from_yaml_dict__' instead" )
6188 return cls .from_yaml_dict (dct , yaml_tag )
6289
90+ # Default: call constructor with all keyword arguments
6391 return cls (** dct )
6492
65- def dump_yaml (self , file_path_or_stream : Union [str , TextIOBase ], safe : bool = True , ** pyyaml_kwargs ):
93+ def dump_yaml (self ,
94+ file_path_or_stream , # type: Union[str, IOBase, StrinIO]
95+ safe = True , # type: bool
96+ ** pyyaml_kwargs # type: Dict[str, Any]
97+ ):
98+ # type: (...) -> None
6699 """
67100 Dumps this object to a yaml file or stream using pyYaml.
68101
@@ -85,7 +118,11 @@ def dump_yaml(self, file_path_or_stream: Union[str, TextIOBase], safe: bool = Tr
85118 else :
86119 dump (self , f , ** pyyaml_kwargs )
87120
88- def dumps_yaml (self , safe : bool = True , ** pyyaml_kwargs ):
121+ def dumps_yaml (self ,
122+ safe = True , # type: bool
123+ ** pyyaml_kwargs # type: Dict[str, Any]
124+ ):
125+ # type: (...) -> str
89126 """
90127 Dumps this object to a yaml string and returns it.
91128
@@ -100,7 +137,11 @@ def dumps_yaml(self, safe: bool = True, **pyyaml_kwargs):
100137 return dump (self , ** pyyaml_kwargs )
101138
102139 @classmethod
103- def loads_yaml (cls : 'Type[Y]' , yaml_str : str , safe : bool = True ) -> Y :
140+ def loads_yaml (cls , # type: Type[Y]
141+ yaml_str , # type: str
142+ safe = True # type: bool
143+ ):
144+ # type: (...) -> Y
104145 """
105146 Utility method to load an instance of this class from the provided yaml string. This methods only returns
106147 successfully if the result is an instance of `cls`.
@@ -112,7 +153,11 @@ def loads_yaml(cls: 'Type[Y]', yaml_str: str, safe: bool=True) -> Y:
112153 return cls .load_yaml (StringIO (yaml_str ), safe = safe )
113154
114155 @classmethod
115- def load_yaml (cls : 'Type[Y]' , file_path_or_stream : Union [str , TextIOBase ], safe : bool = True ) -> Y :
156+ def load_yaml (cls , # type: Type[Y]
157+ file_path_or_stream , # type: Union[str, IOBase, StringIO]
158+ safe = True # type: bool
159+ ):
160+ # type: (...) -> Y
116161 """
117162 Parses the given file path or stream as a yaml document. This methods only returns successfully if the result
118163 is an instance of `cls`.
0 commit comments