1+ import re
12from typing import Any , List , Optional , Tuple
23
34from pydantic import BaseModel
67 "ModelFormatter" ,
78]
89
10+ _ANSI_RE = re .compile (r'\033\[[0-9;]*m' )
11+
12+
13+ def _strip_ansi (s : str ) -> str :
14+ return _ANSI_RE .sub ('' , s )
15+
916
1017class ModelFormatter :
1118 def __init__ (self , line_width : int = 80 , indent : int = 4 , connector : str = ": " , separator : str = ", " ):
@@ -33,7 +40,7 @@ def current_remaining_width(self):
3340 return self .current_max_width () - self .current_width
3441
3542 def get_width (self , key : Optional [str ], value : Any ) -> int :
36- cache_key = id (value )
43+ cache_key = ( key , id (value ) )
3744 if cache_key in self .width_cache :
3845 return self .width_cache [cache_key ]
3946
@@ -98,6 +105,7 @@ def add_entry(self, key: Optional[str], value: Any):
98105
99106 def _process (_elements : List [Tuple [Optional [str ], Any ]], _prefix : str , _suffix : str ):
100107 self .current_line .append (_prefix )
108+ self .current_width += len (_strip_ansi (_prefix ))
101109 if width > self .current_max_width ():
102110 self .new_line ()
103111 self .current_level += 1
@@ -106,6 +114,7 @@ def _process(_elements: List[Tuple[Optional[str], Any]], _prefix: str, _suffix:
106114 self .new_line ()
107115 self .current_level -= 1
108116 self .current_line .append (_suffix )
117+ self .current_width += len (_strip_ansi (_suffix ))
109118
110119 if isinstance (value , tuple ):
111120 _process ([(None , item ) for item in value ], prefix + "(" , ")" )
0 commit comments