Coverage for bioimageio/spec/pretty_validation_errors.py: 32%
40 statements
« prev ^ index » next coverage.py v7.6.10, created at 2025-02-05 13:53 +0000
« prev ^ index » next coverage.py v7.6.10, created at 2025-02-05 13:53 +0000
1from pprint import pformat
2from types import TracebackType
3from typing import Any, List, Type, Union
5from pydantic import ValidationError
7from .summary import format_loc
9try:
10 from IPython.core.getipython import get_ipython
11 from IPython.core.interactiveshell import InteractiveShell
13 class PrettyValidationError(ValueError):
14 """Wrap a pydantic.ValidationError to custumize formatting."""
16 def __init__(self, validation_error: ValidationError):
17 super().__init__()
18 self.error = validation_error
20 def __str__(self):
21 errors: List[str] = []
22 for e in self.error.errors(include_url=False):
23 ipt_lines = pformat(
24 e["input"], sort_dicts=False, depth=1, compact=True, width=30
25 ).split("\n")
26 if len(ipt_lines) > 2:
27 ipt_lines[1:-1] = ["..."]
29 ipt = " ".join([il.strip() for il in ipt_lines])
31 errors.append(
32 f"\n{format_loc(e['loc'], enclose_in='')}\n {e['msg']} [input={ipt}]"
33 )
35 return (
36 f"{self.error.error_count()} validation errors for"
37 f" {self.error.title}:{''.join(errors)}"
38 )
40 def _custom_exception_handler(
41 self: InteractiveShell,
42 etype: Type[ValidationError],
43 evalue: ValidationError,
44 tb: TracebackType,
45 tb_offset: Any = None,
46 ):
47 assert issubclass(etype, ValidationError), type(etype)
48 assert isinstance(evalue, ValidationError), type(etype)
50 stb: Union[Any, List[Union[str, Any]]]
51 stb = self.InteractiveTB.structured_traceback( # pyright: ignore[reportUnknownVariableType]
52 etype, PrettyValidationError(evalue), tb, tb_offset=tb_offset
53 )
55 if isinstance(stb, list):
56 stb_clean = []
57 for line in stb: # pyright: ignore[reportUnknownVariableType]
58 if (
59 isinstance(line, str)
60 and "pydantic" in line
61 and "__tracebackhide__" in line
62 ):
63 # ignore pydantic internal frame in traceback
64 continue
65 stb_clean.append(line)
67 stb = stb_clean
69 self._showtraceback(etype, PrettyValidationError(evalue), stb) # type: ignore
71 def enable_pretty_validation_errors_in_ipynb():
72 """A modestly hacky way to display prettified validaiton error messages and traceback
73 in interactive Python notebooks"""
74 ipy = get_ipython()
75 if ipy is not None:
76 ipy.set_custom_exc((ValidationError,), _custom_exception_handler)
78except ImportError:
80 def enable_pretty_validation_errors_in_ipynb():
81 return