Coverage for /opt/hostedtoolcache/Python/3.10.18/x64/lib/python3.10/site-packages/bioimageio/spec/pretty_validation_errors.py: 41%
46 statements
« prev ^ index » next coverage.py v7.10.7, created at 2025-09-22 09:21 +0000
« prev ^ index » next coverage.py v7.10.7, created at 2025-09-22 09:21 +0000
1import warnings
2from pprint import pformat
3from types import TracebackType
4from typing import Any, List, Type, Union
6from pydantic import ValidationError
8from .summary import format_loc
10try:
11 from IPython.core.getipython import get_ipython
12 from IPython.core.interactiveshell import InteractiveShell
14 class PrettyValidationError(ValueError):
15 """Wrap a pydantic.ValidationError to custumize formatting."""
17 def __init__(self, validation_error: ValidationError):
18 super().__init__()
19 self.error = validation_error
21 def __str__(self):
22 errors: List[str] = []
23 for e in self.error.errors(include_url=False):
24 ipt_lines = pformat(
25 e["input"], sort_dicts=False, depth=1, compact=True, width=30
26 ).split("\n")
27 if len(ipt_lines) > 2:
28 ipt_lines[1:-1] = ["..."]
30 ipt = " ".join([il.strip() for il in ipt_lines])
32 errors.append(
33 f"\n{format_loc(e['loc'], 'plain')}\n {e['msg']} [input={ipt}]"
34 )
36 return (
37 f"{self.error.error_count()} validation errors for"
38 f" {self.error.title}:{''.join(errors)}"
39 )
41 def _custom_exception_handler(
42 self: InteractiveShell,
43 etype: Type[ValidationError],
44 evalue: ValidationError,
45 tb: TracebackType,
46 tb_offset: Any = None,
47 ):
48 assert issubclass(etype, ValidationError), type(etype)
49 assert isinstance(evalue, ValidationError), type(etype)
51 stb: Union[Any, List[Union[str, Any]]]
52 stb = self.InteractiveTB.structured_traceback(
53 etype, PrettyValidationError(evalue), tb, tb_offset=tb_offset
54 )
56 if isinstance(stb, list):
57 stb_clean = []
58 for line in stb: # pyright: ignore[reportUnknownVariableType]
59 if (
60 isinstance(line, str)
61 and "pydantic" in line
62 and "__tracebackhide__" in line
63 ):
64 # ignore pydantic internal frame in traceback
65 continue
66 stb_clean.append(line)
68 stb = stb_clean
70 self._showtraceback(etype, PrettyValidationError(evalue), stb) # type: ignore
72 def _enable_pretty_validation_errors_in_ipynb():
73 """A modestly hacky way to display prettified validaiton error messages and traceback
74 in interactive Python notebooks"""
75 ipy = get_ipython()
76 if ipy is not None:
77 ipy.set_custom_exc((ValidationError,), _custom_exception_handler)
79except ImportError:
80 pass
81else:
82 try:
83 _enable_pretty_validation_errors_in_ipynb()
84 except Exception as e:
85 warnings.warn(
86 "Failed to enable pretty validation errors in ipython: " + str(e),
87 stacklevel=2,
88 )
91def enable_pretty_validation_errors_in_ipynb():
92 """DEPRECATED; this is enabled by default at import time."""
93 warnings.warn(
94 "deprecated, this is enabled by default at import time.",
95 DeprecationWarning,
96 stacklevel=2,
97 )