Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(174)

Side by Side Diff: appengine/findit/libs/meta_dict_serializer.py

Issue 2641583002: [Cuprit-finder] Add MetaDict class. (Closed)
Patch Set: Address comment. Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | appengine/findit/libs/meta_object.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright 2017 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 from collections import OrderedDict
6
7 from libs.meta_object import Element
8 from libs.meta_object import MetaDict
9
10
11 class ElementSerializer(Element):
Martin Barbella 2017/01/23 22:21:16 To leave some more specific feedback building on m
Martin Barbella 2017/01/23 23:30:11 Discussed offline. It's fine to land this CL prett
Sharu Jiang 2017/01/24 00:55:29 Added some documents.
12
13 def ToList(self, element, default=None):
14 """Serializes an ``Element`` to a list of this single element.
15
16 Args:
17 element (Element or None): The element to be serialized. If the element
18 is None, return a list of one default value.
19 default (Element or None) The default value to set when None element is
20 provided.
21
22 Returns:
23 A list of single element.
24
25 Raises:
26 Exception: An error occurs when the passed-in meta object is not an
27 ``Element`` object.
28 """
29 if element is None:
30 return [default]
31
32 assert element.is_element, Exception(
33 '%s can only serialize Element object.' % self.__class__.__name__)
34 return [element]
35
36 def FromList(self, element_list, constructor=None):
37 """De-serializes from element_list to an ``Element``.
38
39 Args:
40 element_list (list of Element): A list of ``Element`` object.
41 constructor (callable): contructor of ``Element`` class.
42
43 Returns:
44 The ``Element`` object in the element_list.
45
46 Raises:
47 Exception: An error occurs when the element_list is not 1.
48 """
49 assert len(element_list) == len(self), Exception(
Martin Barbella 2017/01/23 22:21:16 It'd be nice to see a less generic exception class
Sharu Jiang 2017/01/24 00:55:29 This is the practice throughout the code, I filed
50 'The element list should have the same length as serializer')
51
52 constructor = constructor or (lambda x: x)
53 return constructor(element_list[0])
54
55 def __len__(self):
56 return 1
57
58
59 class MetaDictSerializer(MetaDict):
60 """Class that serialize a ``MetaDict`` to a list of ``Element``s.
61
62 This class itself is a ``MetaDict``, it has the same structure as the
63 meta_dict it wants to serialize or de-serialize, and it is using a
64 ``OrderedDict`` to keep track of the serializing order.
65 """
66
67 def __init__(self, value):
68 super(MetaDictSerializer, self).__init__(value)
69 self._length = None
70
71 def ToList(self, meta_dict, default=None):
72 """Serializes a ``MetaDict`` to a list of ``Element``s.
73
74 Args:
75 meta_dict (MetaDict or None): The element to be serialized. If meta_dict
76 is None, return a list of default values.
77 default (Element or None) The default value to set when None meta_dict is
78 provided.
79
80 Returns:
81 A list of ``Element``s.
82 """
83 element_list = []
84 for key, serializer in self.iteritems():
85 sub_meta_dict = meta_dict.get(key) if meta_dict else None
86 element_list.extend(serializer.ToList(sub_meta_dict, default=default))
87
88 return element_list
89
90 def FromList(self, element_list,
91 meta_constructor=None, element_constructor=None):
92 """De-serializes from element_list to an ``MetaDict``.
93
94 Args:
95 element_list (list of Element): A list of ``Element`` object.
96 element_constructor (callable): The constructor of ``Element`` object that
97 takes one value in element_list as input.
98 meta_constructor (callable): The contructor of ``MetaDict`` object that
99 only take one dict of MetaObjects as input.
100
101 Returns:
102 The ``MetaDict`` object contructed from element_list.
103
104 Raises:
105 Exception: An error occurs when the length of element_list is not equal
106 to the serializer length.
107 """
108 assert len(self) == len(element_list), Exception(
109 'The element list should have the same length as serializer')
110
111 meta_constructor = meta_constructor or (lambda x: x)
112 meta_objs = {}
113 index = 0
114 for key, serializer in self.iteritems():
115 # Truncate the segment in the element list to construct
116 # the ``MetaObject`` corresponding to ``key``.
117 segment = element_list[index : (index + len(serializer))]
118 if serializer.is_element:
119 meta_objs[key] = serializer.FromList(segment, element_constructor)
120 else:
121 meta_objs[key] = serializer.FromList(segment, meta_constructor,
122 element_constructor)
123
124 index += len(serializer)
125
126 return meta_constructor(meta_objs)
127
128 def _Length(self):
129 """Methods to get the length of the serializer recusively.
130
131 Note, the length of a serializer is the number of elements, which is also
132 the number of "real values" in a ``MetaDict`` structure.
133 """
134 if self._length is not None:
135 return self._length
136
137 self._length = 0
138 for value in self.itervalues():
139 self._length += len(value)
140
141 return self._length
142
143 def __len__(self):
144 return self._Length()
145
146
147 def GetSerializer(meta_object, key=None):
148 """Factory to get a serializer corresponding to a ``MetaObject``.
149
150 Args:
151 meta_object (MetaObject): ``Element`` or ``MetaDict`` objects.
152 key (callable or None): Key function to sort ``MetaDict`` object.
153 """
154 if meta_object.is_element:
155 return ElementSerializer()
156
157 sorted_meta = sorted(meta_object.iteritems(), key=key)
158 ordered_dict = OrderedDict((key, GetSerializer(sub_meta))
159 for key, sub_meta in sorted_meta)
160
161 return MetaDictSerializer(ordered_dict)
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/libs/meta_object.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698