@@ -65,13 +65,55 @@ def get_tabulation() -> int:
6565 return 48
6666
6767
68+ def _is_pydantic_internal_loc (loc_part : typing .Any ) -> bool :
69+ """
70+ Check if a location part is a Pydantic v2 internal type descriptor.
71+ These are not human-readable and should be filtered out.
72+ Examples of internal descriptors:
73+ - 'constrained-str'
74+ - 'lax-or-strict[...]'
75+ - 'list[SomeModel]'
76+ - 'json-or-python[...]'
77+ - 'function-after[...]'
78+ - 'union[...]'
79+ """
80+ if not isinstance (loc_part , str ):
81+ return False
82+ # These patterns indicate internal Pydantic type descriptors
83+ internal_patterns = (
84+ "constrained-" ,
85+ "lax-or-strict[" ,
86+ "json-or-python[" ,
87+ "function-after[" ,
88+ "function-before[" ,
89+ "function-wrap[" ,
90+ "union[" ,
91+ "is-instance[" ,
92+ )
93+ if loc_part .startswith (internal_patterns ):
94+ return True
95+ # Also filter out patterns like 'list[Model]' or 'dict[str, Model]'
96+ # but keep simple field names
97+ if "[" in loc_part and "]" in loc_part :
98+ # Check if it looks like a type descriptor (e.g., 'list[Attachment]')
99+ # rather than a field name
100+ return True
101+ return False
102+
103+
68104def wrap_error (e : ValidationError ) -> str :
69105 tabulation = get_tabulation ()
70106 error_messages = defaultdict (list )
71107 for error in e .errors ():
72- errors_list = (
73- list (error ["loc" ])[:- 1 ] if len (error ["loc" ]) > 1 else list (error ["loc" ])
74- )
108+ error_loc = list (error ["loc" ])
109+ # Filter out Pydantic v2 internal type descriptors
110+ error_loc = [loc for loc in error_loc if not _is_pydantic_internal_loc (loc )]
111+ if len (error_loc ) == 0 :
112+ continue
113+ if len (error_loc ) == 1 and isinstance (error_loc [0 ], int ):
114+ errors_list = [f"argument at index { error_loc [0 ]} " ]
115+ else :
116+ errors_list = list (error_loc )
75117 if "__root__" in errors_list :
76118 errors_list .remove ("__root__" )
77119 errors_list [1 ::] = [
0 commit comments