10 # |
10 # |
11 # This code was inspired by pydevd. |
11 # This code was inspired by pydevd. |
12 # |
12 # |
13 |
13 |
14 MaxItemsToHandle = 300 |
14 MaxItemsToHandle = 300 |
15 TooLargeMessage = ("Too large to show contents. Max items to show: " + |
15 TooLargeMessage = ("Too large to show contents. Max items to show: " + |
16 str(MaxItemsToHandle)) |
16 str(MaxItemsToHandle)) |
17 TooLargeAttribute = "Too large to be handled." |
17 TooLargeAttribute = "Too large to be handled." |
18 |
18 |
19 ############################################################ |
19 ############################################################ |
20 ## Classes implementing resolvers for various compund types |
20 ## Classes implementing resolvers for various compund types |
21 ############################################################ |
21 ############################################################ |
22 |
22 |
|
23 |
23 class BaseResolver(object): |
24 class BaseResolver(object): |
24 """ |
25 """ |
25 Base class of the resolver class tree. |
26 Base class of the resolver class tree. |
26 """ |
27 """ |
27 def resolve(self, var, attribute): |
28 def resolve(self, var, attribute): |
32 @type any |
33 @type any |
33 @param attribute name of the attribute to extract |
34 @param attribute name of the attribute to extract |
34 @type str |
35 @type str |
35 @return value of the attribute |
36 @return value of the attribute |
36 @rtype any |
37 @rtype any |
37 """ |
38 @exception NotImplementedError raised to indicate a missing |
|
39 implementation |
|
40 """ # __IGNORE_WARNING_D235__ |
38 raise NotImplementedError |
41 raise NotImplementedError |
39 |
42 |
40 def getDictionary(self, var): |
43 def getDictionary(self, var): |
41 """ |
44 """ |
42 Public method to get the attributes of a variable as a dictionary. |
45 Public method to get the attributes of a variable as a dictionary. |
43 |
46 |
44 @param var variable to be converted |
47 @param var variable to be converted |
45 @type any |
48 @type any |
46 @return dictionary containing the variable attributes |
49 @return dictionary containing the variable attributes |
47 @rtype dict |
50 @rtype dict |
48 """ |
51 @exception NotImplementedError raised to indicate a missing |
|
52 implementation |
|
53 """ # __IGNORE_WARNING_D235__ |
49 raise NotImplementedError |
54 raise NotImplementedError |
50 |
55 |
51 |
56 |
52 class DefaultResolver(BaseResolver): |
57 class DefaultResolver(BaseResolver): |
53 """ |
58 """ |
103 @param attribute name of the attribute to extract |
108 @param attribute name of the attribute to extract |
104 @type str |
109 @type str |
105 @return value of the attribute |
110 @return value of the attribute |
106 @rtype any |
111 @rtype any |
107 """ |
112 """ |
108 if attribute in ('__len__', TooLargeAttribute): |
113 if attribute in ('___len___', TooLargeAttribute): |
109 return None |
114 return None |
110 |
115 |
111 if "(" not in attribute: |
116 if "(ID:" not in attribute: |
112 try: |
117 try: |
113 ## if attribute[0] == "'" and attribute[-1] == "'": |
|
114 ## attribute = attribute[1:-1] |
|
115 return var[attribute] |
118 return var[attribute] |
116 except Exception: |
119 except Exception: |
117 return getattr(var, attribute) |
120 return getattr(var, attribute) |
118 |
121 |
119 expectedID = int(attribute.split("(")[-1][:-1]) |
122 expectedID = int(attribute.split("(ID:")[-1][:-1]) |
120 for key, value in var.items(): |
123 for key, value in var.items(): |
121 if id(key) == expectedID: |
124 if id(key) == expectedID: |
122 return value |
125 return value |
123 |
126 |
124 return None |
127 return None |
125 |
128 |
126 def __keyToStr(self, key): |
129 def __keyToStr(self, key): |
|
130 """ |
|
131 Private method to get a string representation for a key. |
|
132 |
|
133 @param key key to be converted |
|
134 @type any |
|
135 @return string representation of the given key |
|
136 @rtype str |
|
137 """ |
127 if isinstance(key, str): |
138 if isinstance(key, str): |
128 return repr(key) |
139 return repr(key) |
129 else: |
140 else: |
130 return key |
141 return key |
131 |
142 |
140 """ |
151 """ |
141 d = {} |
152 d = {} |
142 count = 0 |
153 count = 0 |
143 for key, value in var.items(): |
154 for key, value in var.items(): |
144 count += 1 |
155 count += 1 |
145 key = "{0} ({1})".format(self.__keyToStr(key), id(key)) |
156 key = "{0} (ID:{1})".format(self.__keyToStr(key), id(key)) |
146 d[key] = value |
157 d[key] = value |
147 if count > MaxItemsToHandle: |
158 if count > MaxItemsToHandle: |
148 d[TooLargeAttribute] = TooLargeMessage |
159 d[TooLargeAttribute] = TooLargeMessage |
149 break |
160 break |
150 |
161 |
151 d["__len__"] = len(var) |
162 d["___len___"] = len(var) |
152 |
163 |
153 # in case it has additional fields |
164 # in case it has additional fields |
154 additionals = defaultResolver.getDictionary(var) |
165 additionals = defaultResolver.getDictionary(var) |
155 d.update(additionals) |
166 d.update(additionals) |
156 |
167 |
187 @param var variable to be converted |
198 @param var variable to be converted |
188 @type any |
199 @type any |
189 @return dictionary containing the variable attributes |
200 @return dictionary containing the variable attributes |
190 @rtype dict |
201 @rtype dict |
191 """ |
202 """ |
192 length = len(var) |
|
193 d = {} |
203 d = {} |
194 formatStr = "{0:0" + str(len(str(length))) + "d}" |
|
195 count = 0 |
204 count = 0 |
196 for value in var: |
205 for value in var: |
197 d[formatStr.format(count)] = value |
206 d[str(count)] = value |
198 count += 1 |
207 count += 1 |
199 if count > MaxItemsToHandle: |
208 if count > MaxItemsToHandle: |
200 d[TooLargeAttribute] = TooLargeMessage |
209 d[TooLargeAttribute] = TooLargeMessage |
201 break |
210 break |
202 |
211 |
203 d["__len__"] = length |
212 d["___len___"] = len(var) |
204 |
213 |
205 # in case it has additional fields |
214 # in case it has additional fields |
206 additionals = defaultResolver.getDictionary(var) |
215 additionals = defaultResolver.getDictionary(var) |
207 d.update(additionals) |
216 d.update(additionals) |
208 |
217 |
209 return d |
218 return d |
210 |
219 |
211 |
220 |
|
221 class SetResolver(BaseResolver): |
|
222 """ |
|
223 Class used to resolve from a set or frozenset. |
|
224 """ |
|
225 def resolve(self, var, attribute): |
|
226 """ |
|
227 Public method to get an attribute from a variable. |
|
228 |
|
229 @param var variable to extract an attribute or value from |
|
230 @type tuple or list |
|
231 @param attribute id of the value to extract |
|
232 @type str |
|
233 @return value of the attribute |
|
234 @rtype any |
|
235 """ |
|
236 if attribute in ('___len___', TooLargeAttribute): |
|
237 return None |
|
238 |
|
239 if attribute.startswith("ID:"): |
|
240 attribute = attribute.split(None, 1)[1] |
|
241 try: |
|
242 attribute = int(attribute) |
|
243 except Exception: |
|
244 return getattr(var, attribute) |
|
245 |
|
246 for v in var: |
|
247 if id(v) == attribute: |
|
248 return v |
|
249 |
|
250 return None |
|
251 |
|
252 def getDictionary(self, var): |
|
253 """ |
|
254 Public method to get the attributes of a variable as a dictionary. |
|
255 |
|
256 @param var variable to be converted |
|
257 @type any |
|
258 @return dictionary containing the variable attributes |
|
259 @rtype dict |
|
260 """ |
|
261 d = {} |
|
262 count = 0 |
|
263 for value in var: |
|
264 count += 1 |
|
265 d["ID: " + str(id(value))] = value |
|
266 if count > MaxItemsToHandle: |
|
267 d[TooLargeAttribute] = TooLargeMessage |
|
268 break |
|
269 |
|
270 d["___len___"] = len(var) |
|
271 |
|
272 # in case it has additional fields |
|
273 additionals = defaultResolver.getDictionary(var) |
|
274 d.update(additionals) |
|
275 |
|
276 return d |
|
277 |
|
278 |
212 defaultResolver = DefaultResolver() |
279 defaultResolver = DefaultResolver() |
213 dictResolver = DictResolver() |
280 dictResolver = DictResolver() |
214 listResolver = ListResolver() |
281 listResolver = ListResolver() |
215 |
282 setResolver = SetResolver() |
216 # TODO: add resolver for set and frozenset |
283 |
217 # TODO: add resolver for numpy arrays |
284 # TODO: add resolver for numpy arrays |
218 # TODO: add resolver for Django MultiValueDict |
285 # TODO: add resolver for Django MultiValueDict |
219 # TODO: add resolver for collections.deque |
286 # TODO: add resolver for collections.deque |
220 |
287 |
221 ############################################################ |
288 ############################################################ |