Skip to content

Commit

Permalink
HH-205308 fix recursion in json encoder
Browse files Browse the repository at this point in the history
  • Loading branch information
Powerrr committed Feb 1, 2024
1 parent 6705f8d commit 089b1ad
Showing 1 changed file with 33 additions and 11 deletions.
44 changes: 33 additions & 11 deletions frontik/json_builder.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,53 @@
from __future__ import annotations

import logging
from typing import TYPE_CHECKING, Callable, Optional, Union
from typing import Any, Callable, Optional, Union

import orjson
from pydantic import BaseModel
from tornado.concurrent import Future

if TYPE_CHECKING:
from typing import Any

handler_logger = logging.getLogger('handler')


FrontikJsonDecodeError = orjson.JSONDecodeError


def _encode_value(value: Any) -> Any:
def _deep_encode_value(value: Any) -> Any:
"""
This method partially duplicates ``_encode_value()``.
It is only used by ``JsonBuilder.to_dict()``
which is only used by ``JsonProducer.get_jinja_context()``.
"""

if isinstance(value, dict):
return {k: _encode_value(v) for k, v in value.items()}
return {k: _deep_encode_value(v) for k, v in value.items()}

elif isinstance(value, (set, frozenset, list, tuple)):
return [_encode_value(v1) for v1 in value]
return [_deep_encode_value(v1) for v1 in value]

elif isinstance(value, Future):
if value.done() and value.exception() is None:
return _deep_encode_value(value.result())

return None

elif isinstance(value, BaseModel):
return _deep_encode_value(value.model_dump())

elif hasattr(value, 'to_dict'):
return _deep_encode_value(value.to_dict())

return value


def _encode_value(value: Any) -> Any:
if isinstance(value, (set, frozenset)):
return list(value)

elif isinstance(value, Future):
if value.done() and value.exception() is None:
return _encode_value(value.result())
return value.result()

return None

Expand All @@ -35,7 +57,7 @@ def _encode_value(value: Any) -> Any:
elif hasattr(value, 'to_dict'):
return value.to_dict()

return value
raise TypeError


def json_encode(obj: Any, default: Callable = _encode_value) -> str:
Expand Down Expand Up @@ -76,7 +98,7 @@ def replace(self, *args: Any, **kwargs: Any) -> None:

def to_dict(self) -> dict:
"""Return plain dict from all data appended to JsonBuilder"""
return _encode_value(self._concat_chunks())
return _deep_encode_value(self._concat_chunks())

def _concat_chunks(self) -> dict:
result = {}
Expand Down

0 comments on commit 089b1ad

Please sign in to comment.