json-repair 0.28.0__py3-none-any.whl → 0.28.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,7 @@ All supported use cases are in the unit tests
24
24
 
25
25
  import os
26
26
  import json
27
- from typing import Any, Dict, List, Optional, Union, TextIO, Tuple
27
+ from typing import Any, Dict, List, Optional, Union, TextIO, Tuple, overload, Literal
28
28
 
29
29
 
30
30
  class StringFileWrapper:
@@ -177,7 +177,7 @@ class JSONParser:
177
177
  # <member> starts with a <string>
178
178
  key = ""
179
179
  while self.get_char_at():
180
- key = self.parse_string()
180
+ key = str(self.parse_string())
181
181
 
182
182
  if key != "" or (key == "" and self.get_char_at() == ":"):
183
183
  # If the string is empty but there is a object divider, we are done here
@@ -255,7 +255,7 @@ class JSONParser:
255
255
  self.reset_context()
256
256
  return arr
257
257
 
258
- def parse_string(self) -> Union[str, JSONReturnType]:
258
+ def parse_string(self) -> Union[str, bool, None]:
259
259
  # <string> is a string of valid characters enclosed in quotes
260
260
  # i.e. { name: "John" }
261
261
  # Somehow all weird cases in an invalid JSON happen to be resolved in this function, so be careful here
@@ -382,7 +382,7 @@ class JSONParser:
382
382
  string_acc += char
383
383
  self.index += 1
384
384
  char = self.get_char_at()
385
- if len(string_acc) > 0 and string_acc[-1] == "\\":
385
+ if char and len(string_acc) > 0 and string_acc[-1] == "\\":
386
386
  # This is a special case, if people use real strings this might happen
387
387
  self.log("Found a stray escape sequence, normalizing it", "info")
388
388
  string_acc = string_acc[:-1]
@@ -473,7 +473,7 @@ class JSONParser:
473
473
  "While parsing a string, we a misplaced quote that would have closed the string but has a different meaning here since this is the last element of the object, ignoring it",
474
474
  "info",
475
475
  )
476
- string_acc += char
476
+ string_acc += str(char)
477
477
  self.index += 1
478
478
  char = self.get_char_at()
479
479
  elif next_c == rstring_delimiter:
@@ -503,7 +503,7 @@ class JSONParser:
503
503
  "While parsing a string, we a misplaced quote that would have closed the string but has a different meaning here, ignoring it",
504
504
  "info",
505
505
  )
506
- string_acc += char
506
+ string_acc += str(char)
507
507
  self.index += 1
508
508
  char = self.get_char_at()
509
509
 
@@ -521,7 +521,8 @@ class JSONParser:
521
521
  if self.get_char_at() not in [":", ","]:
522
522
  return ""
523
523
 
524
- # A fallout of the previous special case in the while loop, we need to update the index only if we had a closing quote
524
+ # A fallout of the previous special case in the while loop,
525
+ # we need to update the index only if we had a closing quote
525
526
  if char != rstring_delimiter:
526
527
  self.log(
527
528
  "While parsing a string, we missed the closing quote, ignoring",
@@ -563,6 +564,7 @@ class JSONParser:
563
564
  # <boolean> is one of the literal strings 'true', 'false', or 'null' (unquoted)
564
565
  starting_index = self.index
565
566
  char = (self.get_char_at() or "").lower()
567
+ value = None
566
568
  if char == "t":
567
569
  value = ("true", True)
568
570
  elif char == "f":
@@ -583,7 +585,7 @@ class JSONParser:
583
585
  self.index = starting_index
584
586
  return ""
585
587
 
586
- def get_char_at(self, count: int = 0) -> Union[str, bool]:
588
+ def get_char_at(self, count: int = 0) -> Union[str, Literal[False]]:
587
589
  # Why not use something simpler? Because try/except in python is a faster alternative to an "if" statement that is often True
588
590
  try:
589
591
  return self.json_str[self.index + count]
@@ -630,6 +632,50 @@ class JSONParser:
630
632
  )
631
633
 
632
634
 
635
+ @overload
636
+ def repair_json(
637
+ json_str: str = "",
638
+ return_objects: Optional[Literal[False]] = False,
639
+ skip_json_loads: Optional[bool] = False,
640
+ logging: Optional[Literal[False]] = False, # None is treated as False
641
+ json_fd: Optional[TextIO] = None,
642
+ ensure_ascii: Optional[bool] = True,
643
+ ) -> str: ...
644
+
645
+
646
+ @overload
647
+ def repair_json(
648
+ json_str: str = "",
649
+ return_objects: Literal[True] = True,
650
+ skip_json_loads: Optional[bool] = False,
651
+ logging: Optional[Literal[False]] = False, # None is treated as False
652
+ json_fd: Optional[TextIO] = None,
653
+ ensure_ascii: Optional[bool] = True,
654
+ ) -> JSONReturnType: ...
655
+
656
+
657
+ @overload
658
+ def repair_json(
659
+ json_str: str = "",
660
+ return_objects: Optional[Literal[False]] = False, # None is treated as False
661
+ skip_json_loads: Optional[bool] = False,
662
+ logging: Literal[True] = True,
663
+ json_fd: Optional[TextIO] = None,
664
+ ensure_ascii: Optional[bool] = True,
665
+ ) -> Tuple[str, List[Dict[str, str]]]: ...
666
+
667
+
668
+ @overload
669
+ def repair_json(
670
+ json_str: str = "",
671
+ return_objects: Literal[True] = True,
672
+ skip_json_loads: Optional[bool] = False,
673
+ logging: Literal[True] = True,
674
+ json_fd: Optional[TextIO] = None,
675
+ ensure_ascii: Optional[bool] = True,
676
+ ) -> Tuple[JSONReturnType, List[Dict[str, str]]]: ...
677
+
678
+
633
679
  def repair_json(
634
680
  json_str: str = "",
635
681
  return_objects: Optional[bool] = False,
@@ -643,7 +689,7 @@ def repair_json(
643
689
  It will return the fixed string by default.
644
690
  When `return_objects=True` is passed, it will return the decoded data structure instead.
645
691
  When `skip_json_loads=True` is passed, it will not call the built-in json.loads() function
646
- When `logging=True` is passed, it will return an tuple with the repaired json and a log of all repair actions
692
+ When `logging=True` is passed, it will return a tuple with the repaired json and a log of all repair actions
647
693
  """
648
694
  parser = JSONParser(json_str, json_fd, logging)
649
695
  if skip_json_loads:
@@ -656,12 +702,29 @@ def repair_json(
656
702
  parsed_json = json.loads(json_str)
657
703
  except json.JSONDecodeError:
658
704
  parsed_json = parser.parse()
659
- # It's useful to return the actual object instead of the json string, it allows this lib to be a replacement of the json library
705
+ # It's useful to return the actual object instead of the json string,
706
+ # it allows this lib to be a replacement of the json library
660
707
  if return_objects or logging:
661
708
  return parsed_json
662
709
  return json.dumps(parsed_json, ensure_ascii=ensure_ascii)
663
710
 
664
711
 
712
+ @overload
713
+ def loads(
714
+ json_str: str,
715
+ skip_json_loads: Optional[bool] = False,
716
+ logging: Optional[Literal[False]] = False, # None is treated as False
717
+ ) -> JSONReturnType: ...
718
+
719
+
720
+ @overload
721
+ def loads(
722
+ json_str: str,
723
+ skip_json_loads: Optional[bool] = False,
724
+ logging: Literal[True] = True,
725
+ ) -> Tuple[JSONReturnType, List[Dict[str, str]]]: ...
726
+
727
+
665
728
  def loads(
666
729
  json_str: str,
667
730
  skip_json_loads: Optional[bool] = False,
@@ -679,6 +742,20 @@ def loads(
679
742
  )
680
743
 
681
744
 
745
+ @overload
746
+ def load(
747
+ fd: TextIO,
748
+ skip_json_loads: Optional[bool] = False,
749
+ logging: Optional[Literal[False]] = False,
750
+ ) -> JSONReturnType: ...
751
+
752
+
753
+ @overload
754
+ def load(
755
+ fd: TextIO, skip_json_loads: Optional[bool] = False, logging: Literal[True] = True
756
+ ) -> Tuple[JSONReturnType, List[Dict[str, str]]]: ...
757
+
758
+
682
759
  def load(
683
760
  fd: TextIO, skip_json_loads: Optional[bool] = False, logging: Optional[bool] = False
684
761
  ) -> Union[JSONReturnType, Tuple[JSONReturnType, List[Dict[str, str]]]]:
@@ -694,6 +771,22 @@ def load(
694
771
  )
695
772
 
696
773
 
774
+ @overload
775
+ def from_file(
776
+ filename: str,
777
+ skip_json_loads: Optional[bool] = False,
778
+ logging: Optional[Literal[False]] = False,
779
+ ) -> JSONReturnType: ...
780
+
781
+
782
+ @overload
783
+ def from_file(
784
+ filename: str,
785
+ skip_json_loads: Optional[bool] = False,
786
+ logging: Literal[True] = True,
787
+ ) -> Tuple[JSONReturnType, List[Dict[str, str]]]: ...
788
+
789
+
697
790
  def from_file(
698
791
  filename: str,
699
792
  skip_json_loads: Optional[bool] = False,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: json_repair
3
- Version: 0.28.0
3
+ Version: 0.28.1
4
4
  Summary: A package to repair broken json strings
5
5
  Author-email: Stefano Baccianella <4247706+mangiucugna@users.noreply.github.com>
6
6
  License: MIT License
@@ -0,0 +1,8 @@
1
+ json_repair/__init__.py,sha256=IIzSm1DsCRrr8seF3UeMZXwxcq-tE3j-8d1WBxvEJvE,178
2
+ json_repair/json_repair.py,sha256=_NBAaY6iqIp1cB1W-lnQ3uS6nc5DjZZyf_HeklYmDyY,32502
3
+ json_repair/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ json_repair-0.28.1.dist-info/LICENSE,sha256=wrjQo8MhNrNCicXtMe3MHmS-fx8AmQk1ue8AQwiiFV8,1076
5
+ json_repair-0.28.1.dist-info/METADATA,sha256=i9SaIoWFc7YjuQLLN1Rd8GsmVAy0rWJ9-fNwsVDR_KA,8043
6
+ json_repair-0.28.1.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
7
+ json_repair-0.28.1.dist-info/top_level.txt,sha256=7-VZwZN2CgB_n0NlSLk-rEUFh8ug21lESbsblOYuZqw,12
8
+ json_repair-0.28.1.dist-info/RECORD,,
@@ -1,8 +0,0 @@
1
- json_repair/__init__.py,sha256=IIzSm1DsCRrr8seF3UeMZXwxcq-tE3j-8d1WBxvEJvE,178
2
- json_repair/json_repair.py,sha256=5WjVoNO7Grdq9wfnbSjggiVlDv2XVcvWbCIQVmREP38,30109
3
- json_repair/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
- json_repair-0.28.0.dist-info/LICENSE,sha256=wrjQo8MhNrNCicXtMe3MHmS-fx8AmQk1ue8AQwiiFV8,1076
5
- json_repair-0.28.0.dist-info/METADATA,sha256=rPrWno-My7ZQt7EJIR0BodmpLQ84fr0vjJwBM4XYmYU,8043
6
- json_repair-0.28.0.dist-info/WHEEL,sha256=HiCZjzuy6Dw0hdX5R3LCFPDmFS4BWl8H-8W39XfmgX4,91
7
- json_repair-0.28.0.dist-info/top_level.txt,sha256=7-VZwZN2CgB_n0NlSLk-rEUFh8ug21lESbsblOYuZqw,12
8
- json_repair-0.28.0.dist-info/RECORD,,