json-repair 0.28.0__tar.gz → 0.28.2__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: json_repair
3
- Version: 0.28.0
3
+ Version: 0.28.2
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
@@ -3,7 +3,7 @@ requires = ["setuptools>=61.0"]
3
3
  build-backend = "setuptools.build_meta"
4
4
  [project]
5
5
  name = "json_repair"
6
- version = "0.28.0"
6
+ version = "0.28.2"
7
7
  license = {file = "LICENSE"}
8
8
  authors = [
9
9
  { name="Stefano Baccianella", email="4247706+mangiucugna@users.noreply.github.com" },
@@ -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, Literal
28
28
 
29
29
 
30
30
  class StringFileWrapper:
@@ -33,7 +33,7 @@ class StringFileWrapper:
33
33
  self.fd = fd
34
34
  self.length: int = 0
35
35
 
36
- def __getitem__(self, index: int) -> str:
36
+ def __getitem__(self, index: int | slice) -> str:
37
37
  if isinstance(index, slice):
38
38
  self.fd.seek(index.start)
39
39
  value = self.fd.read(index.stop - index.start)
@@ -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: Optional[Tuple[str, Optional[bool]]]
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]
@@ -632,18 +634,18 @@ class JSONParser:
632
634
 
633
635
  def repair_json(
634
636
  json_str: str = "",
635
- return_objects: Optional[bool] = False,
636
- skip_json_loads: Optional[bool] = False,
637
- logging: Optional[bool] = False,
637
+ return_objects: bool = False,
638
+ skip_json_loads: bool = False,
639
+ logging: bool = False,
638
640
  json_fd: Optional[TextIO] = None,
639
- ensure_ascii: Optional[bool] = True,
641
+ ensure_ascii: bool = True,
640
642
  ) -> Union[JSONReturnType, Tuple[JSONReturnType, List[Dict[str, str]]]]:
641
643
  """
642
644
  Given a json formatted string, it will try to decode it and, if it fails, it will try to fix it.
643
645
  It will return the fixed string by default.
644
646
  When `return_objects=True` is passed, it will return the decoded data structure instead.
645
647
  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
648
+ When `logging=True` is passed, it will return a tuple with the repaired json and a log of all repair actions
647
649
  """
648
650
  parser = JSONParser(json_str, json_fd, logging)
649
651
  if skip_json_loads:
@@ -656,7 +658,8 @@ def repair_json(
656
658
  parsed_json = json.loads(json_str)
657
659
  except json.JSONDecodeError:
658
660
  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
661
+ # It's useful to return the actual object instead of the json string,
662
+ # it allows this lib to be a replacement of the json library
660
663
  if return_objects or logging:
661
664
  return parsed_json
662
665
  return json.dumps(parsed_json, ensure_ascii=ensure_ascii)
@@ -664,8 +667,8 @@ def repair_json(
664
667
 
665
668
  def loads(
666
669
  json_str: str,
667
- skip_json_loads: Optional[bool] = False,
668
- logging: Optional[bool] = False,
670
+ skip_json_loads: bool = False,
671
+ logging: bool = False,
669
672
  ) -> Union[JSONReturnType, Tuple[JSONReturnType, List[Dict[str, str]]]]:
670
673
  """
671
674
  This function works like `json.loads()` except that it will fix your JSON in the process.
@@ -680,7 +683,7 @@ def loads(
680
683
 
681
684
 
682
685
  def load(
683
- fd: TextIO, skip_json_loads: Optional[bool] = False, logging: Optional[bool] = False
686
+ fd: TextIO, skip_json_loads: bool = False, logging: bool = False
684
687
  ) -> Union[JSONReturnType, Tuple[JSONReturnType, List[Dict[str, str]]]]:
685
688
  """
686
689
  This function works like `json.load()` except that it will fix your JSON in the process.
@@ -696,8 +699,8 @@ def load(
696
699
 
697
700
  def from_file(
698
701
  filename: str,
699
- skip_json_loads: Optional[bool] = False,
700
- logging: Optional[bool] = False,
702
+ skip_json_loads: bool = False,
703
+ logging: bool = False,
701
704
  ) -> Union[JSONReturnType, Tuple[JSONReturnType, List[Dict[str, str]]]]:
702
705
  """
703
706
  This function is a wrapper around `load()` so you can pass the filename as string
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: json_repair
3
- Version: 0.28.0
3
+ Version: 0.28.2
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
File without changes
File without changes
File without changes