1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 """Module for object related utils."""
31
32
33
34
35 _SEQUENCE_TYPES = (list, tuple, set, frozenset)
39 """Meta base class for __slots__ definitions.
40
41 """
42 - def __new__(mcs, name, bases, attrs):
43 """Called when a class should be created.
44
45 @param mcs: The meta class
46 @param name: Name of created class
47 @param bases: Base classes
48 @type attrs: dict
49 @param attrs: Class attributes
50
51 """
52 assert "__slots__" not in attrs, \
53 "Class '%s' defines __slots__ when it should not" % name
54
55 attrs["__slots__"] = mcs._GetSlots(attrs)
56
57 return type.__new__(mcs, name, bases, attrs)
58
59 @classmethod
61 """Used to get the list of defined slots.
62
63 @param attrs: The attributes of the class
64
65 """
66 raise NotImplementedError
67
70 """Sets and validates slots.
71
72 """
73 __slots__ = []
74
76 """Constructor for BaseOpCode.
77
78 The constructor takes only keyword arguments and will set
79 attributes on this object based on the passed arguments. As such,
80 it means that you should not pass arguments which are not in the
81 __slots__ attribute for this class.
82
83 """
84 slots = self.GetAllSlots()
85 for (key, value) in kwargs.items():
86 if key not in slots:
87 raise TypeError("Object %s doesn't support the parameter '%s'" %
88 (self.__class__.__name__, key))
89 setattr(self, key, value)
90
91 @classmethod
93 """Compute the list of all declared slots for a class.
94
95 """
96 slots = []
97 for parent in cls.__mro__:
98 slots.extend(getattr(parent, "__slots__", []))
99 return slots
100
102 """Validates the slots.
103
104 This method returns L{None} if the validation succeeds, or raises
105 an exception otherwise.
106
107 @rtype: NoneType
108 @return: L{None}, if the validation succeeds
109
110 @raise Exception: validation fails
111
112 This method must be implemented by the child classes.
113
114 """
115 raise NotImplementedError
116
119 """Convert the elements of a container to standard Python types.
120
121 This method converts a container with elements to standard Python types. If
122 the input container is of the type C{dict}, only its values are touched.
123 Those values, as well as all elements of input sequences, must support a
124 C{ToDict} method returning a serialized version.
125
126 @type container: dict or sequence (see L{_SEQUENCE_TYPES})
127
128 """
129 if isinstance(container, dict):
130 ret = dict([(k, v.ToDict()) for k, v in container.items()])
131 elif isinstance(container, _SEQUENCE_TYPES):
132 ret = [elem.ToDict() for elem in container]
133 else:
134 raise TypeError("Unknown container type '%s'" % type(container))
135
136 return ret
137
140 """Convert a container from standard python types.
141
142 This method converts a container with standard Python types to objects. If
143 the container is a dict, we don't touch the keys, only the values.
144
145 @type source: None, dict or sequence (see L{_SEQUENCE_TYPES})
146 @param source: Input data
147 @type c_type: type class
148 @param c_type: Desired type for returned container
149 @type e_type: element type class
150 @param e_type: Item type for elements in returned container (must have a
151 C{FromDict} class method)
152
153 """
154 if not isinstance(c_type, type):
155 raise TypeError("Container type '%s' is not a type" % type(c_type))
156
157 if source is None:
158 source = c_type()
159
160 if c_type is dict:
161 ret = dict([(k, e_type.FromDict(v)) for k, v in source.items()])
162 elif c_type in _SEQUENCE_TYPES:
163 ret = c_type(map(e_type.FromDict, source))
164 else:
165 raise TypeError("Unknown container type '%s'" % c_type)
166
167 return ret
168