2626
2727class ToonDecodeError (Exception ):
2828 """TOON decoding error."""
29+
2930 pass
3031
3132
@@ -57,18 +58,16 @@ def compute_depth(line: str, indent_size: int, strict: bool) -> int:
5758 return 0
5859
5960 # Count leading spaces
60- leading_spaces = len (line ) - len (line .lstrip (' ' ))
61+ leading_spaces = len (line ) - len (line .lstrip (" " ))
6162
6263 # Check for tabs in indentation (always error in strict mode)
63- if strict and ' \t ' in line [:leading_spaces ]:
64+ if strict and " \t " in line [:leading_spaces ]:
6465 raise ToonDecodeError ("Tabs are not allowed in indentation" )
6566
6667 # In strict mode, leading spaces must be exact multiple of indent_size
6768 if strict :
6869 if leading_spaces % indent_size != 0 :
69- raise ToonDecodeError (
70- f"Indentation must be an exact multiple of { indent_size } spaces"
71- )
70+ raise ToonDecodeError (f"Indentation must be an exact multiple of { indent_size } spaces" )
7271 return leading_spaces // indent_size
7372 else :
7473 # Non-strict mode: use floor division
@@ -98,19 +97,19 @@ def unescape_string(value: str) -> str:
9897 result .append (BACKSLASH )
9998 elif next_char == DOUBLE_QUOTE :
10099 result .append (DOUBLE_QUOTE )
101- elif next_char == 'n' :
100+ elif next_char == "n" :
102101 result .append (NEWLINE )
103- elif next_char == 'r' :
102+ elif next_char == "r" :
104103 result .append (CARRIAGE_RETURN )
105- elif next_char == 't' :
104+ elif next_char == "t" :
106105 result .append (TAB )
107106 else :
108107 raise ToonDecodeError (f"Invalid escape sequence: \\ { next_char } " )
109108 i += 2
110109 else :
111110 result .append (value [i ])
112111 i += 1
113- return '' .join (result )
112+ return "" .join (result )
114113
115114
116115def parse_primitive (token : str ) -> JsonValue :
@@ -146,13 +145,13 @@ def parse_primitive(token: str) -> JsonValue:
146145 # Must reject leading zeros like "05", "0001"
147146 if token :
148147 # Check for forbidden leading zeros
149- if re .match (r' ^0\d+$' , token ):
148+ if re .match (r" ^0\d+$" , token ):
150149 # Leading zero like "05" -> string
151150 return token
152151
153152 try :
154153 # Try int first
155- if '.' not in token and 'e' not in token .lower ():
154+ if "." not in token and "e" not in token .lower ():
156155 return int (token )
157156 # Then float
158157 return float (token )
@@ -191,7 +190,7 @@ def parse_delimited_values(line: str, delimiter: str) -> List[str]:
191190 i += 1
192191 elif char == delimiter and not in_quotes :
193192 # Split on unquoted delimiter
194- tokens .append ('' .join (current ))
193+ tokens .append ("" .join (current ))
195194 current = []
196195 i += 1
197196 continue
@@ -202,7 +201,7 @@ def parse_delimited_values(line: str, delimiter: str) -> List[str]:
202201
203202 # Add final token
204203 if current or tokens : # Include empty final token if there was a delimiter
205- tokens .append ('' .join (current ))
204+ tokens .append ("" .join (current ))
206205
207206 return tokens
208207
@@ -238,10 +237,10 @@ def parse_header(line: str) -> Optional[Tuple[Optional[str], int, str, Optional[
238237 return None
239238
240239 # Parse bracket content: [#?N<delim?>]
241- bracket_content = line [bracket_start + 1 : bracket_end ]
240+ bracket_content = line [bracket_start + 1 : bracket_end ]
242241
243242 # Remove optional # marker
244- if bracket_content .startswith ('#' ):
243+ if bracket_content .startswith ("#" ):
245244 bracket_content = bracket_content [1 :]
246245
247246 # Determine delimiter from bracket content
@@ -267,7 +266,7 @@ def parse_header(line: str) -> Optional[Tuple[Optional[str], int, str, Optional[
267266
268267 # Check for fields segment
269268 fields = None
270- after_bracket = line [bracket_end + 1 :].strip ()
269+ after_bracket = line [bracket_end + 1 :].strip ()
271270
272271 if after_bracket .startswith (OPEN_BRACE ):
273272 brace_end = after_bracket .find (CLOSE_BRACE )
@@ -279,7 +278,7 @@ def parse_header(line: str) -> Optional[Tuple[Optional[str], int, str, Optional[
279278 field_tokens = parse_delimited_values (fields_content , delimiter )
280279 fields = [parse_key (f .strip ()) for f in field_tokens ]
281280
282- after_bracket = after_bracket [brace_end + 1 :].strip ()
281+ after_bracket = after_bracket [brace_end + 1 :].strip ()
283282
284283 # Must end with colon
285284 if not after_bracket .startswith (COLON ):
@@ -334,7 +333,7 @@ def split_key_value(line: str) -> Tuple[str, str]:
334333 i += 1 # Skip next char
335334 elif char == COLON and not in_quotes :
336335 key = line [:i ].strip ()
337- value = line [i + 1 :].strip ()
336+ value = line [i + 1 :].strip ()
338337 return (key , value )
339338
340339 i += 1
@@ -362,7 +361,7 @@ def decode(input_str: str, options: Optional[DecodeOptions] = None) -> JsonValue
362361 strict = options .strict
363362
364363 # Split into lines
365- raw_lines = input_str .split (' \n ' )
364+ raw_lines = input_str .split (" \n " )
366365
367366 # Process lines: compute depth and filter blanks outside arrays
368367 lines : List [Line ] = []
@@ -415,10 +414,7 @@ def decode(input_str: str, options: Optional[DecodeOptions] = None) -> JsonValue
415414
416415
417416def decode_object (
418- lines : List [Line ],
419- start_idx : int ,
420- parent_depth : int ,
421- strict : bool
417+ lines : List [Line ], start_idx : int , parent_depth : int , strict : bool
422418) -> Dict [str , Any ]:
423419 """Decode an object starting at given line index.
424420
@@ -500,7 +496,7 @@ def decode_array_from_header(
500496 header_idx : int ,
501497 header_depth : int ,
502498 header_info : Tuple [Optional [str ], int , str , Optional [List [str ]]],
503- strict : bool
499+ strict : bool ,
504500) -> Tuple [List [Any ], int ]:
505501 """Decode array starting from a header line.
506502
@@ -519,7 +515,7 @@ def decode_array_from_header(
519515
520516 # Check if there's inline content after the colon
521517 colon_idx = header_line .rfind (COLON )
522- inline_content = header_line [colon_idx + 1 :].strip ()
518+ inline_content = header_line [colon_idx + 1 :].strip ()
523519
524520 if inline_content :
525521 # Inline primitive array
@@ -541,7 +537,7 @@ def decode_array(
541537 start_idx : int ,
542538 parent_depth : int ,
543539 header_info : Tuple [Optional [str ], int , str , Optional [List [str ]]],
544- strict : bool
540+ strict : bool ,
545541) -> List [Any ]:
546542 """Decode array (convenience wrapper).
547543
@@ -560,10 +556,7 @@ def decode_array(
560556
561557
562558def decode_inline_array (
563- content : str ,
564- delimiter : str ,
565- expected_length : int ,
566- strict : bool
559+ content : str , delimiter : str , expected_length : int , strict : bool
567560) -> List [Any ]:
568561 """Decode an inline primitive array.
569562
@@ -586,9 +579,7 @@ def decode_inline_array(
586579 values = [parse_primitive (token ) for token in tokens ]
587580
588581 if strict and len (values ) != expected_length :
589- raise ToonDecodeError (
590- f"Expected { expected_length } values, but got { len (values )} "
591- )
582+ raise ToonDecodeError (f"Expected { expected_length } values, but got { len (values )} " )
592583
593584 return values
594585
@@ -600,7 +591,7 @@ def decode_tabular_array(
600591 fields : List [str ],
601592 delimiter : str ,
602593 expected_length : int ,
603- strict : bool
594+ strict : bool ,
604595) -> Tuple [List [Dict [str , Any ]], int ]:
605596 """Decode a tabular array.
606597
@@ -662,9 +653,7 @@ def decode_tabular_array(
662653 break
663654
664655 if strict and len (result ) != expected_length :
665- raise ToonDecodeError (
666- f"Expected { expected_length } rows, but got { len (result )} "
667- )
656+ raise ToonDecodeError (f"Expected { expected_length } rows, but got { len (result )} " )
668657
669658 return result , i
670659
@@ -718,7 +707,7 @@ def decode_list_array(
718707 header_depth : int ,
719708 delimiter : str ,
720709 expected_length : int ,
721- strict : bool
710+ strict : bool ,
722711) -> Tuple [List [Any ], int ]:
723712 """Decode a list-format array (mixed/non-uniform).
724713
@@ -761,7 +750,7 @@ def decode_list_array(
761750 break
762751
763752 # Remove "- " prefix
764- item_content = content [len (LIST_ITEM_MARKER ):].strip ()
753+ item_content = content [len (LIST_ITEM_MARKER ) :].strip ()
765754
766755 # Check what kind of item this is
767756 item_header = parse_header (item_content )
@@ -773,7 +762,7 @@ def decode_list_array(
773762 # - [N]: inline array
774763 colon_idx = item_content .find (COLON )
775764 if colon_idx != - 1 :
776- inline_part = item_content [colon_idx + 1 :].strip ()
765+ inline_part = item_content [colon_idx + 1 :].strip ()
777766 if inline_part :
778767 # Inline primitive array
779768 item_val = decode_inline_array (inline_part , item_delim , length , strict )
@@ -895,8 +884,6 @@ def decode_list_array(
895884 i += 1
896885
897886 if strict and len (result ) != expected_length :
898- raise ToonDecodeError (
899- f"Expected { expected_length } items, but got { len (result )} "
900- )
887+ raise ToonDecodeError (f"Expected { expected_length } items, but got { len (result )} " )
901888
902889 return result , i
0 commit comments