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

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

Issue 2641583002: [Cuprit-finder] Add MetaDict class. (Closed)
Patch Set: . 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
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):
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.IsElement(), 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(
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, meta_constructor, element_constructor=None):
91 """De-serializes from element_list to an ``MetaDict``.
92
93 Args:
94 element_list (list of Element): A list of ``Element`` object.
95 element_constructor (callable): The constructor of ``Element`` object that
96 takes one value in element_list as input.
97 meta_constructor (callable): The contructor of ``MetaDict`` object that
98 only take one dict of MetaObjects as input.
99
100 Returns:
101 The ``MetaDict`` object contructed from element_list.
102
103 Raises:
104 Exception: An error occurs when the length of element_list is not equal
105 to the serializer length.
106 """
107 assert len(self) == len(element_list), Exception(
108 'The element list should have the same length as serializer')
109
110 meta_objs = {}
111 index = 0
112 for key, serializer in self.iteritems():
113 # Trucate the segment in the element list to construct
chanli 2017/01/18 22:14:23 Nit:Truncate?
chanli 2017/01/18 22:14:23 Nit: 2 spaces between 'the' and 'segment'
Sharu Jiang 2017/01/19 00:00:52 Done.
Sharu Jiang 2017/01/19 00:00:52 Done.
114 # the ``MetaObject`` corresponding to ``key``.
115 segment = element_list[index : (index + len(serializer))]
116 if serializer.IsElement():
117 meta_objs[key] = serializer.FromList(segment, element_constructor)
chanli 2017/01/18 22:14:23 This means all elements in the dict must use the s
Sharu Jiang 2017/01/19 00:00:52 Yes.
chanli 2017/01/19 02:10:58 So I assume this is expected behavior.
118 else:
119 meta_objs[key] = serializer.FromList(segment, meta_constructor,
120 element_constructor)
121
122 index += len(serializer)
123
124 return meta_constructor(meta_objs)
125
126 def _Length(self):
127 """Methods to get the length of the serializer recusively.
128
129 Note, the length of a serializer is the number of elements, which is also
130 the number of "real values" in a ``MetaDict`` structure.
131 """
132 if self._length is not None:
133 return self._length
134
135 self._length = 0
136 for value in self.itervalues():
137 self._length += len(value)
138
139 return self._length
140
141 def __len__(self):
142 return self._Length()
143
144
145 def GetSerializer(meta_object, key=None):
146 """Factory to get a serializer corresponding to a ``MetaObject``.
147
148 Args:
149 meta_object (MetaObject): ``Element`` or ``MetaDict`` objects.
150 constructor (callable or None): Callable with dict as input and returns a
chanli 2017/01/18 22:14:23 constructor is not in argument list?
Sharu Jiang 2017/01/19 00:00:52 Oops, forgot to delete it.
151 serializer(either ``ElementSerializer`` or ``MetaDictSerializer``). If
152 None, the init function of meta_object is used.
153 key (callable or None): Key function to sort ``MetaDict`` object.
154 """
155 if meta_object.IsElement():
156 return ElementSerializer()
157
158 sorted_meta = sorted(meta_object.iteritems(), key=key)
159 ordered_dict = OrderedDict((key, GetSerializer(sub_meta))
160 for key, sub_meta in sorted_meta)
161
162 return MetaDictSerializer(ordered_dict)
OLDNEW
« no previous file with comments | « no previous file | appengine/findit/libs/meta_object.py » ('j') | appengine/findit/libs/meta_object.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698