-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
HH-205308 fix recursion in json encoder #680
Conversation
FrontikJsonDecodeError = orjson.JSONDecodeError | ||
|
||
|
||
def _encode_value(value: Any) -> Any: | ||
def _deep_encode_value(value: Any) -> Any: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
бывший рекурсивный _encode_value
переименовал в _deep_encode_value
и в паре мест добавил ещё рекурсии (т.к. странно, что некоторые вложенные объекты преобразовывались, а некоторые нет, так что сделал все), см. комменты ниже
return None | ||
|
||
elif isinstance(value, BaseModel): | ||
return _deep_encode_value(value.model_dump()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
тут добавил рекурсивный вызов
return _deep_encode_value(value.model_dump()) | ||
|
||
elif hasattr(value, 'to_dict'): | ||
return _deep_encode_value(value.to_dict()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
и тут добавил рекурсивный вызов
return value | ||
|
||
|
||
def _encode_value(value: Any) -> Any: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
этот метод теперь без рекурсии. также убрал обработку dict
, list
, tuple
, т.к. json-сериализатор сам их умеет
@@ -76,7 +91,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()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
вот это одно место, где нужно преобразовывать в т.ч. вложенные объекты
SonarQube Quality Gate |
https://jira.hh.ru/browse/HH-205308
Пофиксил контракт default-метода
_encode_value
: если он не преобразует значение, то кидает ошибку (иначе получается бесконечная рекурсия), и он не преобразует вложенные объекты, сериализатор json сам вызовет его, если нужно.Но в одном месте оказалось нужно преобразование вместе с вложенными объектами, для этого сделал рекурсивный метод
_deep_encode_value
.