-
Notifications
You must be signed in to change notification settings - Fork 43.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2032 from bingoko/master
refactoring all json utilities
- Loading branch information
Showing
16 changed files
with
229 additions
and
248 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
This file was deleted.
Oops, something went wrong.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
"""This module contains functions to fix JSON strings using general programmatic approaches, suitable for addressing | ||
common JSON formatting issues.""" | ||
from __future__ import annotations | ||
|
||
import contextlib | ||
import json | ||
import re | ||
from typing import Optional | ||
|
||
from autogpt.config import Config | ||
from autogpt.json_utils.utilities import extract_char_position | ||
|
||
CFG = Config() | ||
|
||
|
||
def fix_invalid_escape(json_to_load: str, error_message: str) -> str: | ||
"""Fix invalid escape sequences in JSON strings. | ||
Args: | ||
json_to_load (str): The JSON string. | ||
error_message (str): The error message from the JSONDecodeError | ||
exception. | ||
Returns: | ||
str: The JSON string with invalid escape sequences fixed. | ||
""" | ||
while error_message.startswith("Invalid \\escape"): | ||
bad_escape_location = extract_char_position(error_message) | ||
json_to_load = ( | ||
json_to_load[:bad_escape_location] + json_to_load[bad_escape_location + 1 :] | ||
) | ||
try: | ||
json.loads(json_to_load) | ||
return json_to_load | ||
except json.JSONDecodeError as e: | ||
if CFG.debug_mode: | ||
print("json loads error - fix invalid escape", e) | ||
error_message = str(e) | ||
return json_to_load | ||
|
||
|
||
def balance_braces(json_string: str) -> Optional[str]: | ||
""" | ||
Balance the braces in a JSON string. | ||
Args: | ||
json_string (str): The JSON string. | ||
Returns: | ||
str: The JSON string with braces balanced. | ||
""" | ||
|
||
open_braces_count = json_string.count("{") | ||
close_braces_count = json_string.count("}") | ||
|
||
while open_braces_count > close_braces_count: | ||
json_string += "}" | ||
close_braces_count += 1 | ||
|
||
while close_braces_count > open_braces_count: | ||
json_string = json_string.rstrip("}") | ||
close_braces_count -= 1 | ||
|
||
with contextlib.suppress(json.JSONDecodeError): | ||
json.loads(json_string) | ||
return json_string | ||
|
||
|
||
def add_quotes_to_property_names(json_string: str) -> str: | ||
""" | ||
Add quotes to property names in a JSON string. | ||
Args: | ||
json_string (str): The JSON string. | ||
Returns: | ||
str: The JSON string with quotes added to property names. | ||
""" | ||
|
||
def replace_func(match: re.Match) -> str: | ||
return f'"{match[1]}":' | ||
|
||
property_name_pattern = re.compile(r"(\w+):") | ||
corrected_json_string = property_name_pattern.sub(replace_func, json_string) | ||
|
||
try: | ||
json.loads(corrected_json_string) | ||
return corrected_json_string | ||
except json.JSONDecodeError as e: | ||
raise e | ||
|
||
|
||
def correct_json(json_to_load: str) -> str: | ||
""" | ||
Correct common JSON errors. | ||
Args: | ||
json_to_load (str): The JSON string. | ||
""" | ||
|
||
try: | ||
if CFG.debug_mode: | ||
print("json", json_to_load) | ||
json.loads(json_to_load) | ||
return json_to_load | ||
except json.JSONDecodeError as e: | ||
if CFG.debug_mode: | ||
print("json loads error", e) | ||
error_message = str(e) | ||
if error_message.startswith("Invalid \\escape"): | ||
json_to_load = fix_invalid_escape(json_to_load, error_message) | ||
if error_message.startswith( | ||
"Expecting property name enclosed in double quotes" | ||
): | ||
json_to_load = add_quotes_to_property_names(json_to_load) | ||
try: | ||
json.loads(json_to_load) | ||
return json_to_load | ||
except json.JSONDecodeError as e: | ||
if CFG.debug_mode: | ||
print("json loads error - add quotes", e) | ||
error_message = str(e) | ||
if balanced_str := balance_braces(json_to_load): | ||
return balanced_str | ||
return json_to_load |
Oops, something went wrong.