json-repair 0.4.5__tar.gz → 0.5.0__tar.gz
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.
- {json_repair-0.4.5 → json_repair-0.5.0}/PKG-INFO +1 -1
- {json_repair-0.4.5 → json_repair-0.5.0}/pyproject.toml +1 -1
- {json_repair-0.4.5 → json_repair-0.5.0}/src/json_repair/json_repair.py +14 -8
- {json_repair-0.4.5 → json_repair-0.5.0}/src/json_repair.egg-info/PKG-INFO +2 -2
- {json_repair-0.4.5 → json_repair-0.5.0}/tests/test_json_repair.py +6 -0
- {json_repair-0.4.5 → json_repair-0.5.0}/LICENSE +0 -0
- {json_repair-0.4.5 → json_repair-0.5.0}/README.md +0 -0
- {json_repair-0.4.5 → json_repair-0.5.0}/setup.cfg +0 -0
- {json_repair-0.4.5 → json_repair-0.5.0}/src/json_repair/__init__.py +0 -0
- {json_repair-0.4.5 → json_repair-0.5.0}/src/json_repair.egg-info/SOURCES.txt +0 -0
- {json_repair-0.4.5 → json_repair-0.5.0}/src/json_repair.egg-info/dependency_links.txt +0 -0
- {json_repair-0.4.5 → json_repair-0.5.0}/src/json_repair.egg-info/top_level.txt +0 -0
- {json_repair-0.4.5 → json_repair-0.5.0}/tests/test_performance.py +0 -0
@@ -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.
|
6
|
+
version = "0.5.0"
|
7
7
|
license = {file = "LICENSE"}
|
8
8
|
authors = [
|
9
9
|
{ name="Stefano Baccianella", email="4247706+mangiucugna@users.noreply.github.com" },
|
@@ -61,6 +61,8 @@ class JSONParser:
|
|
61
61
|
# <string> starts with '"'
|
62
62
|
elif char == '"':
|
63
63
|
return self.parse_string()
|
64
|
+
elif char == "'":
|
65
|
+
return self.parse_string(use_single_quotes=True)
|
64
66
|
# <number> starts with [0-9] or minus
|
65
67
|
elif char.isdigit() or char == "-":
|
66
68
|
return self.parse_number()
|
@@ -105,7 +107,9 @@ class JSONParser:
|
|
105
107
|
# <member> starts with a <string>
|
106
108
|
key = ""
|
107
109
|
while key == "" and self.get_char_at():
|
108
|
-
key = self.parse_string(
|
110
|
+
key = self.parse_string(
|
111
|
+
use_single_quotes=(self.json_str[self.index] == "'")
|
112
|
+
)
|
109
113
|
|
110
114
|
# We reached the end here
|
111
115
|
if key == "}":
|
@@ -166,17 +170,19 @@ class JSONParser:
|
|
166
170
|
self.index += 1
|
167
171
|
return arr
|
168
172
|
|
169
|
-
def parse_string(self) -> str:
|
173
|
+
def parse_string(self, use_single_quotes=False) -> str:
|
170
174
|
# <string> is a string of valid characters enclosed in quotes
|
171
175
|
# i.e. { name: "John" }
|
172
176
|
# Somehow all weird cases in an invalid JSON happen to be resolved in this function, so be careful here
|
173
177
|
|
174
178
|
# Flag to manage corner cases related to missing starting quote
|
175
179
|
fixed_quotes = False
|
176
|
-
|
180
|
+
string_terminator = '"'
|
181
|
+
if use_single_quotes:
|
182
|
+
string_terminator = "'"
|
177
183
|
char = self.get_char_at()
|
178
|
-
if char !=
|
179
|
-
self.insert_char_at(
|
184
|
+
if char != string_terminator:
|
185
|
+
self.insert_char_at(string_terminator)
|
180
186
|
fixed_quotes = True
|
181
187
|
else:
|
182
188
|
self.index += 1
|
@@ -191,7 +197,7 @@ class JSONParser:
|
|
191
197
|
# * It iterated over the entire sequence
|
192
198
|
# * If we are fixing missing quotes in an object, when it finds the special terminators
|
193
199
|
char = self.get_char_at()
|
194
|
-
while char and char !=
|
200
|
+
while char and char != string_terminator:
|
195
201
|
if fixed_quotes:
|
196
202
|
if self.context == "object_key" and (char == ":" or char.isspace()):
|
197
203
|
break
|
@@ -208,8 +214,8 @@ class JSONParser:
|
|
208
214
|
end = self.index
|
209
215
|
|
210
216
|
# A fallout of the previous special case in the while loop, we need to update the index only if we had a closing quote
|
211
|
-
if char !=
|
212
|
-
self.insert_char_at(
|
217
|
+
if char != string_terminator:
|
218
|
+
self.insert_char_at(string_terminator)
|
213
219
|
else:
|
214
220
|
self.index += 1
|
215
221
|
|
@@ -8,6 +8,7 @@ def test_repair_json():
|
|
8
8
|
assert repair_json("\"") == '""'
|
9
9
|
assert repair_json("\n") == '""'
|
10
10
|
assert repair_json('{"key": true, "key2": false, "key3": null}') == '{"key": true, "key2": false, "key3": null}'
|
11
|
+
assert repair_json("{'key': 'string', 'key2': false, \"key3\": null, \"key4\": unquoted}") == '{"key": "string", "key2": false, "key3": null, "key4": "unquoted"}'
|
11
12
|
assert (
|
12
13
|
repair_json('{"name": "John", "age": 30, "city": "New York"}')
|
13
14
|
== '{"name": "John", "age": 30, "city": "New York"}'
|
@@ -66,6 +67,10 @@ def test_repair_json():
|
|
66
67
|
repair_json('{"text": "The quick brown fox,"}')
|
67
68
|
== '{"text": "The quick brown fox,"}'
|
68
69
|
)
|
70
|
+
assert (
|
71
|
+
repair_json('{"text": "The quick brown fox won\'t jump"}')
|
72
|
+
== '{"text": "The quick brown fox won\'t jump"}'
|
73
|
+
)
|
69
74
|
assert {
|
70
75
|
repair_json('{"value_1": "value_2": "data"}') == '{"value_1": "value_2", "data": ""}'
|
71
76
|
}
|
@@ -119,6 +124,7 @@ def test_repair_json_with_objects():
|
|
119
124
|
assert repair_json("[", True) == []
|
120
125
|
assert repair_json("{", True) == {}
|
121
126
|
assert repair_json('{"key": "value:value"}', True) == {"key": "value:value"}
|
127
|
+
assert repair_json("{'key': 'string', 'key2': false, \"key3\": null, \"key4\": unquoted}", True) == {"key": "string", "key2": False, "key3": None, "key4": "unquoted"}
|
122
128
|
assert repair_json('{"name": "John", "age": 30, "city": "New', True) == {
|
123
129
|
"name": "John",
|
124
130
|
"age": 30,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|