json-repair 0.29.0__py3-none-any.whl → 0.29.2__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- json_repair/json_repair.py +55 -36
- {json_repair-0.29.0.dist-info → json_repair-0.29.2.dist-info}/METADATA +10 -10
- json_repair-0.29.2.dist-info/RECORD +10 -0
- {json_repair-0.29.0.dist-info → json_repair-0.29.2.dist-info}/WHEEL +1 -1
- json_repair-0.29.0.dist-info/RECORD +0 -10
- {json_repair-0.29.0.dist-info → json_repair-0.29.2.dist-info}/LICENSE +0 -0
- {json_repair-0.29.0.dist-info → json_repair-0.29.2.dist-info}/entry_points.txt +0 -0
- {json_repair-0.29.0.dist-info → json_repair-0.29.2.dist-info}/top_level.txt +0 -0
json_repair/json_repair.py
CHANGED
@@ -384,38 +384,39 @@ class JSONParser:
|
|
384
384
|
# * If we are fixing missing quotes in an object, when it finds the special terminators
|
385
385
|
char = self.get_char_at()
|
386
386
|
while char and char != rstring_delimiter:
|
387
|
-
if
|
388
|
-
|
389
|
-
|
390
|
-
)
|
387
|
+
if (
|
388
|
+
missing_quotes
|
389
|
+
and self.get_context() == "object_key"
|
390
|
+
and (char == ":" or char.isspace())
|
391
|
+
):
|
392
|
+
self.log(
|
393
|
+
"While parsing a string missing the left delimiter in object key context, we found a :, stopping here",
|
394
|
+
"info",
|
395
|
+
)
|
396
|
+
break
|
397
|
+
if self.get_context() == "object_value" and char in [",", "}"]:
|
398
|
+
rstring_delimiter_missing = True
|
399
|
+
# check if this is a case in which the closing comma is NOT missing instead
|
400
|
+
i = 1
|
401
|
+
next_c = self.get_char_at(i)
|
402
|
+
while next_c and next_c != rstring_delimiter:
|
403
|
+
i += 1
|
404
|
+
next_c = self.get_char_at(i)
|
405
|
+
if next_c:
|
406
|
+
i += 1
|
407
|
+
next_c = self.get_char_at(i)
|
408
|
+
# found a delimiter, now we need to check that is followed strictly by a comma or brace
|
409
|
+
while next_c and next_c.isspace():
|
410
|
+
i += 1
|
411
|
+
next_c = self.get_char_at(i)
|
412
|
+
if next_c and next_c in [",", "}"]:
|
413
|
+
rstring_delimiter_missing = False
|
414
|
+
if rstring_delimiter_missing:
|
391
415
|
self.log(
|
392
|
-
"While parsing a string missing the left delimiter in object
|
416
|
+
"While parsing a string missing the left delimiter in object value context, we found a , or } and we couldn't determine that a right delimiter was present. Stopping here",
|
393
417
|
"info",
|
394
418
|
)
|
395
419
|
break
|
396
|
-
elif self.get_context() == "object_value" and char in [",", "}"]:
|
397
|
-
rstring_delimiter_missing = True
|
398
|
-
# check if this is a case in which the closing comma is NOT missing instead
|
399
|
-
i = 1
|
400
|
-
next_c = self.get_char_at(i)
|
401
|
-
while next_c and next_c != rstring_delimiter:
|
402
|
-
i += 1
|
403
|
-
next_c = self.get_char_at(i)
|
404
|
-
if next_c:
|
405
|
-
i += 1
|
406
|
-
next_c = self.get_char_at(i)
|
407
|
-
# found a delimiter, now we need to check that is followed strictly by a comma or brace
|
408
|
-
while next_c and next_c.isspace():
|
409
|
-
i += 1
|
410
|
-
next_c = self.get_char_at(i)
|
411
|
-
if next_c and next_c in [",", "}"]:
|
412
|
-
rstring_delimiter_missing = False
|
413
|
-
if rstring_delimiter_missing:
|
414
|
-
self.log(
|
415
|
-
"While parsing a string missing the left delimiter in object value context, we found a , or } and we couldn't determine that a right delimiter was present. Stopping here",
|
416
|
-
"info",
|
417
|
-
)
|
418
|
-
break
|
419
420
|
string_acc += char
|
420
421
|
self.index += 1
|
421
422
|
char = self.get_char_at()
|
@@ -507,7 +508,7 @@ class JSONParser:
|
|
507
508
|
if next_c == "}":
|
508
509
|
# OK this is valid then
|
509
510
|
self.log(
|
510
|
-
"While parsing a string, we a
|
511
|
+
"While parsing a string, we misplaced a quote that would have closed the string but has a different meaning here since this is the last element of the object, ignoring it",
|
511
512
|
"info",
|
512
513
|
)
|
513
514
|
string_acc += str(char)
|
@@ -760,7 +761,7 @@ def from_file(
|
|
760
761
|
return jsonobj
|
761
762
|
|
762
763
|
|
763
|
-
def cli(
|
764
|
+
def cli(inline_args: Optional[List[str]] = None) -> int:
|
764
765
|
parser = argparse.ArgumentParser(description="Repair and parse JSON files.")
|
765
766
|
parser.add_argument("filename", help="The JSON file to repair")
|
766
767
|
parser.add_argument(
|
@@ -769,10 +770,16 @@ def cli(): # pragma: no cover
|
|
769
770
|
action="store_true",
|
770
771
|
help="Replace the file inline instead of returning the output to stdout",
|
771
772
|
)
|
773
|
+
parser.add_argument(
|
774
|
+
"-o",
|
775
|
+
"--output",
|
776
|
+
metavar="TARGET",
|
777
|
+
help="If specified, the output will be written to TARGET filename instead of stdout",
|
778
|
+
)
|
772
779
|
parser.add_argument(
|
773
780
|
"--ensure_ascii",
|
774
781
|
action="store_true",
|
775
|
-
help="Pass
|
782
|
+
help="Pass ensure_ascii=True to json.dumps()",
|
776
783
|
)
|
777
784
|
parser.add_argument(
|
778
785
|
"--indent",
|
@@ -781,24 +788,36 @@ def cli(): # pragma: no cover
|
|
781
788
|
help="Number of spaces for indentation (Default 2)",
|
782
789
|
)
|
783
790
|
|
784
|
-
|
791
|
+
if inline_args is None: # pragma: no cover
|
792
|
+
args = parser.parse_args()
|
793
|
+
else:
|
794
|
+
args = parser.parse_args(
|
795
|
+
inline_args
|
796
|
+
) # This is needed so this function is testable
|
797
|
+
|
798
|
+
if args.inline and args.output: # pragma: no cover
|
799
|
+
print("Error: You cannot pass both --inline and --output", file=sys.stderr)
|
800
|
+
sys.exit(1)
|
785
801
|
|
786
802
|
ensure_ascii = False
|
787
803
|
if args.ensure_ascii:
|
788
804
|
ensure_ascii = True
|
805
|
+
|
789
806
|
try:
|
790
807
|
result = from_file(args.filename)
|
791
808
|
|
792
|
-
if args.inline:
|
793
|
-
fd = open(args.filename, mode="w")
|
809
|
+
if args.inline or args.output:
|
810
|
+
fd = open(args.output or args.filename, mode="w")
|
794
811
|
json.dump(result, fd, indent=args.indent, ensure_ascii=ensure_ascii)
|
795
812
|
fd.close()
|
796
813
|
else:
|
797
814
|
print(json.dumps(result, indent=args.indent, ensure_ascii=ensure_ascii))
|
798
|
-
except Exception as e:
|
815
|
+
except Exception as e: # pragma: no cover
|
799
816
|
print(f"Error: {str(e)}", file=sys.stderr)
|
800
817
|
sys.exit(1)
|
801
818
|
|
819
|
+
return 0 # Success
|
820
|
+
|
802
821
|
|
803
822
|
if __name__ == "__main__": # pragma: no cover
|
804
|
-
cli()
|
823
|
+
sys.exit(cli())
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: json_repair
|
3
|
-
Version: 0.29.
|
3
|
+
Version: 0.29.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
|
@@ -156,24 +156,24 @@ Install the library for command-line with:
|
|
156
156
|
```
|
157
157
|
pipx install json-repair
|
158
158
|
```
|
159
|
-
|
159
|
+
to know all options available:
|
160
160
|
```
|
161
161
|
$ json_repair -h
|
162
|
-
|
163
|
-
usage: json_repair [-h] [-i] [--ensure_ascii] [--indent INDENT] filename
|
162
|
+
usage: json_repair [-h] [-i] [-o TARGET] [--ensure_ascii] [--indent INDENT] filename
|
164
163
|
|
165
164
|
Repair and parse JSON files.
|
166
165
|
|
167
166
|
positional arguments:
|
168
|
-
filename
|
167
|
+
filename The JSON file to repair
|
169
168
|
|
170
169
|
options:
|
171
|
-
-h, --help
|
172
|
-
-i, --inline
|
173
|
-
|
174
|
-
|
170
|
+
-h, --help show this help message and exit
|
171
|
+
-i, --inline Replace the file inline instead of returning the output to stdout
|
172
|
+
-o TARGET, --output TARGET
|
173
|
+
If specified, the output will be written to TARGET filename instead of stdout
|
174
|
+
--ensure_ascii Pass ensure_ascii=True to json.dumps()
|
175
|
+
--indent INDENT Number of spaces for indentation (Default 2)
|
175
176
|
```
|
176
|
-
to learn how to use it
|
177
177
|
|
178
178
|
## Adding to requirements
|
179
179
|
**Please pin this library only on the major version!**
|
@@ -0,0 +1,10 @@
|
|
1
|
+
json_repair/__init__.py,sha256=IIzSm1DsCRrr8seF3UeMZXwxcq-tE3j-8d1WBxvEJvE,178
|
2
|
+
json_repair/__main__.py,sha256=EsJb-y89uZEvGQQg1GdIDWzfDwfOMvVekKEtdguQXCM,67
|
3
|
+
json_repair/json_repair.py,sha256=anGQI5RxauBnZUO9QKoPU7JgN_sUaIddyiR4ecpMmm8,34060
|
4
|
+
json_repair/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
+
json_repair-0.29.2.dist-info/LICENSE,sha256=wrjQo8MhNrNCicXtMe3MHmS-fx8AmQk1ue8AQwiiFV8,1076
|
6
|
+
json_repair-0.29.2.dist-info/METADATA,sha256=Jtwl047L79Xj0CmA363Xc2EemzttgMWqYW0abi4a7fA,9787
|
7
|
+
json_repair-0.29.2.dist-info/WHEEL,sha256=cVxcB9AmuTcXqmwrtPhNK88dr7IR_b6qagTj0UvIEbY,91
|
8
|
+
json_repair-0.29.2.dist-info/entry_points.txt,sha256=SNfge3zPSP-ASqriYU9r3NAPaXdseYr7ciPMKdV2uSw,57
|
9
|
+
json_repair-0.29.2.dist-info/top_level.txt,sha256=7-VZwZN2CgB_n0NlSLk-rEUFh8ug21lESbsblOYuZqw,12
|
10
|
+
json_repair-0.29.2.dist-info/RECORD,,
|
@@ -1,10 +0,0 @@
|
|
1
|
-
json_repair/__init__.py,sha256=IIzSm1DsCRrr8seF3UeMZXwxcq-tE3j-8d1WBxvEJvE,178
|
2
|
-
json_repair/__main__.py,sha256=EsJb-y89uZEvGQQg1GdIDWzfDwfOMvVekKEtdguQXCM,67
|
3
|
-
json_repair/json_repair.py,sha256=hltJ3Qa4qFbUD3mVKkYvFWksnCcIZqx8zamKfBpjeNs,33538
|
4
|
-
json_repair/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
5
|
-
json_repair-0.29.0.dist-info/LICENSE,sha256=wrjQo8MhNrNCicXtMe3MHmS-fx8AmQk1ue8AQwiiFV8,1076
|
6
|
-
json_repair-0.29.0.dist-info/METADATA,sha256=yh0EJo-I1u0R6X-Gq9ETz0WbgmuGIhzR7Icw9W4Kee0,9630
|
7
|
-
json_repair-0.29.0.dist-info/WHEEL,sha256=uCRv0ZEik_232NlR4YDw4Pv3Ajt5bKvMH13NUU7hFuI,91
|
8
|
-
json_repair-0.29.0.dist-info/entry_points.txt,sha256=SNfge3zPSP-ASqriYU9r3NAPaXdseYr7ciPMKdV2uSw,57
|
9
|
-
json_repair-0.29.0.dist-info/top_level.txt,sha256=7-VZwZN2CgB_n0NlSLk-rEUFh8ug21lESbsblOYuZqw,12
|
10
|
-
json_repair-0.29.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|