|
32 | 32 |
|
33 | 33 |
|
34 | 34 | import datetime |
| 35 | +import itertools |
35 | 36 | import uuid |
36 | 37 | from decimal import Decimal |
37 | 38 |
|
@@ -178,15 +179,41 @@ def to_string(value): |
178 | 179 | return to_unicode(value).encode("utf-8") |
179 | 180 |
|
180 | 181 |
|
181 | | -def shorten(var, list_length=50, string_length=200): |
| 182 | +def shorten(var, list_length=50, string_length=200, dict_length=50): |
| 183 | + """ |
| 184 | + Shorten a given variable based on configurable maximum lengths, leaving |
| 185 | + breadcrumbs in the object to show that it was shortened. |
| 186 | +
|
| 187 | + For strings, truncate the string to the max length, and append "..." so |
| 188 | + the user knows data was lost. |
| 189 | +
|
| 190 | + For lists, truncate the list to the max length, and append two new strings |
| 191 | + to the list: "..." and "(<x> more elements)" where <x> is the number of |
| 192 | + elements removed. |
| 193 | +
|
| 194 | + For dicts, truncate the dict to the max length (based on number of key/value |
| 195 | + pairs) and add a new (key, value) pair to the dict: |
| 196 | + ("...", "(<x> more elements)") where <x> is the number of key/value pairs |
| 197 | + removed. |
| 198 | +
|
| 199 | + :param var: Variable to be shortened |
| 200 | + :param list_length: Max length (in items) of lists |
| 201 | + :param string_length: Max length (in characters) of strings |
| 202 | + :param dict_length: Max length (in key/value pairs) of dicts |
| 203 | + :return: Shortened variable |
| 204 | + """ |
182 | 205 | var = transform(var) |
183 | 206 | if isinstance(var, compat.string_types) and len(var) > string_length: |
184 | 207 | var = var[: string_length - 3] + "..." |
185 | 208 | elif isinstance(var, (list, tuple, set, frozenset)) and len(var) > list_length: |
186 | 209 | # TODO: we should write a real API for storing some metadata with vars when |
187 | 210 | # we get around to doing ref storage |
188 | | - # TODO: when we finish the above, we should also implement this for dicts |
189 | 211 | var = list(var)[:list_length] + ["...", "(%d more elements)" % (len(var) - list_length,)] |
| 212 | + elif isinstance(var, dict) and len(var) > dict_length: |
| 213 | + trimmed_tuples = [(k, v) for (k, v) in itertools.islice(compat.iteritems(var), dict_length)] |
| 214 | + if "<truncated>" not in var: |
| 215 | + trimmed_tuples += [("<truncated>", "(%d more elements)" % (len(var) - dict_length))] |
| 216 | + var = dict(trimmed_tuples) |
190 | 217 | return var |
191 | 218 |
|
192 | 219 |
|
|
0 commit comments