Coverage for python/lsst/daf/butler/formatters/yamlFormatter.py : 26%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# This file is part of daf_butler.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22__all__ = ("YamlFormatter", )
24import builtins
25import yaml
27from lsst.daf.butler.formatters.fileFormatter import FileFormatter
30class YamlFormatter(FileFormatter):
31 """Interface for reading and writing Python objects to and from YAML files.
32 """
33 extension = ".yaml"
35 unsupportedParameters = None
36 """This formatter does not support any parameters"""
38 def _readFile(self, path, pytype=None):
39 """Read a file from the path in YAML format.
41 Parameters
42 ----------
43 path : `str`
44 Path to use to open YAML format file.
45 pytype : `class`, optional
46 Not used by this implementation.
48 Returns
49 -------
50 data : `object`
51 Either data as Python object read from YAML file, or None
52 if the file could not be opened.
54 Notes
55 -----
56 The `~yaml.UnsafeLoader` is used when parsing the YAML file.
57 """
58 try:
59 with open(path, "rb") as fd:
60 data = self._fromBytes(fd.read(), pytype)
61 except FileNotFoundError:
62 data = None
64 return data
66 def _fromBytes(self, serializedDataset, pytype=None):
67 """Read the bytes object as a python object.
69 Parameters
70 ----------
71 serializedDataset : `bytes`
72 Bytes object to unserialize.
73 pytype : `class`, optional
74 Not used by this implementation.
76 Returns
77 -------
78 inMemoryDataset : `object`
79 The requested data as an object, or None if the string could
80 not be read.
81 """
82 try:
83 data = yaml.load(serializedDataset, Loader=yaml.UnsafeLoader)
84 except yaml.YAMLError:
85 data = None
86 try:
87 data = data.exportAsDict()
88 except AttributeError:
89 pass
90 return data
92 def _writeFile(self, inMemoryDataset):
93 """Write the in memory dataset to file on disk.
95 Will look for `_asdict()` method to aid YAML serialization, following
96 the approach of the simplejson module.
98 Parameters
99 ----------
100 inMemoryDataset : `object`
101 Object to serialize.
103 Raises
104 ------
105 Exception
106 The file could not be written.
107 """
108 with open(self.fileDescriptor.location.path, "wb") as fd:
109 if hasattr(inMemoryDataset, "_asdict"):
110 inMemoryDataset = inMemoryDataset._asdict()
111 fd.write(self._toBytes(inMemoryDataset))
113 def _toBytes(self, inMemoryDataset):
114 """Write the in memory dataset to a bytestring.
116 Parameters
117 ----------
118 inMemoryDataset : `object`
119 Object to serialize
121 Returns
122 -------
123 serializedDataset : `bytes`
124 YAML string encoded to bytes.
126 Raises
127 ------
128 Exception
129 The object could not be serialized.
130 """
131 return yaml.dump(inMemoryDataset).encode()
133 def _coerceType(self, inMemoryDataset, storageClass, pytype=None):
134 """Coerce the supplied inMemoryDataset to type `pytype`.
136 Parameters
137 ----------
138 inMemoryDataset : `object`
139 Object to coerce to expected type.
140 storageClass : `StorageClass`
141 StorageClass associated with `inMemoryDataset`.
142 pytype : `type`, optional
143 Override type to use for conversion.
145 Returns
146 -------
147 inMemoryDataset : `object`
148 Object of expected type `pytype`.
149 """
150 if not hasattr(builtins, pytype.__name__):
151 if storageClass.isComposite():
152 inMemoryDataset = storageClass.assembler().assemble(inMemoryDataset, pytype=pytype)
153 elif not isinstance(inMemoryDataset, pytype):
154 # Hope that we can pass the arguments in directly
155 inMemoryDataset = pytype(inMemoryDataset)
156 return inMemoryDataset