[core] add test for json parser (#15297)

this should fail, but isnt

---------

Co-authored-by: Nuno Campos <nuno@langchain.dev>
pull/15110/head^2
Harrison Chase 6 months ago committed by GitHub
parent ec090745a6
commit c3b3b77a11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -10,6 +10,7 @@ import jsonpatch # type: ignore[import]
from langchain_core.exceptions import OutputParserException
from langchain_core.output_parsers.format_instructions import JSON_FORMAT_INSTRUCTIONS
from langchain_core.output_parsers.transform import BaseCumulativeTransformOutputParser
from langchain_core.outputs import Generation
from langchain_core.pydantic_v1 import BaseModel
@ -106,11 +107,7 @@ def parse_partial_json(s: str, *, strict: bool = False) -> Any:
new_s += closing_char
# Attempt to parse the modified string as JSON.
try:
return json.loads(new_s, strict=strict)
except json.JSONDecodeError:
# If we still can't parse the string as JSON, return None to indicate failure.
return None
return json.loads(new_s, strict=strict)
def parse_json_markdown(
@ -187,12 +184,22 @@ class JsonOutputParser(BaseCumulativeTransformOutputParser[Any]):
def _diff(self, prev: Optional[Any], next: Any) -> Any:
return jsonpatch.make_patch(prev, next).patch
def parse(self, text: str) -> Any:
def parse_result(self, result: List[Generation], *, partial: bool = False) -> Any:
text = result[0].text
text = text.strip()
try:
return parse_json_markdown(text.strip())
except JSONDecodeError as e:
raise OutputParserException(f"Invalid json output: {text}") from e
if partial:
try:
return parse_json_markdown(text)
except JSONDecodeError:
return None
else:
try:
return parse_json_markdown(text)
except JSONDecodeError as e:
raise OutputParserException(f"Invalid json output: {text}") from e
def parse(self, text: str) -> Any:
return self.parse_result([Generation(text=text)])
def get_format_instructions(self) -> str:
if self.pydantic_object is None:

@ -487,3 +487,9 @@ async def test_partial_text_json_output_parser_diff_async() -> None:
chain = input_iter | SimpleJsonOutputParser(diff=True)
assert [p async for p in chain.astream(None)] == EXPECTED_STREAMED_JSON_DIFF
def test_raises_error() -> None:
parser = SimpleJsonOutputParser()
with pytest.raises(Exception):
parser.invoke("hi")

@ -78,17 +78,20 @@ class JsonOutputFunctionsParser(BaseCumulativeTransformOutputParser[Any]):
raise OutputParserException(f"Could not parse function call: {exc}")
try:
if partial:
if self.args_only:
return parse_partial_json(
function_call["arguments"], strict=self.strict
)
else:
return {
**function_call,
"arguments": parse_partial_json(
try:
if self.args_only:
return parse_partial_json(
function_call["arguments"], strict=self.strict
),
}
)
else:
return {
**function_call,
"arguments": parse_partial_json(
function_call["arguments"], strict=self.strict
),
}
except json.JSONDecodeError:
return None
else:
if self.args_only:
try:

Loading…
Cancel
Save