|
2 | 2 | import re
|
3 | 3 | from textwrap import dedent
|
4 | 4 | from keyword import iskeyword
|
| 5 | +from typing import Any |
| 6 | +from typing_extensions import Final |
| 7 | + |
5 | 8 | import flask
|
6 | 9 |
|
7 | 10 | from ._grouping import grouping_len, map_grouping
|
|
15 | 18 | clean_property_name,
|
16 | 19 | )
|
17 | 20 |
|
| 21 | +TRUNCATE_AT: Final[int] = 100 |
| 22 | + |
18 | 23 |
|
19 | 24 | def validate_callback(outputs, inputs, state, extra_args, types):
|
20 | 25 | Input, Output, State = types
|
@@ -209,11 +214,23 @@ def validate_multi_return(output_lists, output_values, callback_id):
|
209 | 214 | )
|
210 | 215 |
|
211 | 216 |
|
| 217 | +def truncate_object(obj: Any, at: int) -> str: |
| 218 | + """Return a truncated string representation of an object.""" |
| 219 | + obj_stringified = str(obj) |
| 220 | + size = len(obj_stringified) |
| 221 | + |
| 222 | + if size <= at: |
| 223 | + return obj_stringified |
| 224 | + |
| 225 | + return obj_stringified[:at] + f"... (truncated - {size} characters total)" |
| 226 | + |
| 227 | + |
212 | 228 | def fail_callback_output(output_value, output):
|
213 | 229 | valid_children = (str, int, float, type(None), Component)
|
214 | 230 | valid_props = (str, int, float, type(None), tuple, MutableSequence)
|
215 | 231 |
|
216 | 232 | def _raise_invalid(bad_val, outer_val, path, index=None, toplevel=False):
|
| 233 | + bad_val_stringified = truncate_object(bad_val, TRUNCATE_AT) |
217 | 234 | bad_type = type(bad_val).__name__
|
218 | 235 | outer_id = f"(id={outer_val.id:s})" if getattr(outer_val, "id", False) else ""
|
219 | 236 | outer_type = type(outer_val).__name__
|
@@ -244,7 +261,7 @@ def _raise_invalid(bad_val, outer_val, path, index=None, toplevel=False):
|
244 | 261 |
|
245 | 262 | {location}
|
246 | 263 | and has string representation
|
247 |
| - `{bad_val}` |
| 264 | + `{bad_val_stringified}` |
248 | 265 |
|
249 | 266 | In general, Dash properties can only be
|
250 | 267 | dash components, strings, dictionaries, numbers, None,
|
|
0 commit comments