Skip to content
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

Merged
merged 1 commit into from
Feb 1, 2024
Merged

HH-205308 fix recursion in json encoder #680

merged 1 commit into from
Feb 1, 2024

Conversation

Powerrr
Copy link
Member

@Powerrr Powerrr commented Feb 1, 2024

https://jira.hh.ru/browse/HH-205308

Пофиксил контракт default-метода _encode_value: если он не преобразует значение, то кидает ошибку (иначе получается бесконечная рекурсия), и он не преобразует вложенные объекты, сериализатор json сам вызовет его, если нужно.
Но в одном месте оказалось нужно преобразование вместе с вложенными объектами, для этого сделал рекурсивный метод _deep_encode_value.

FrontikJsonDecodeError = orjson.JSONDecodeError


def _encode_value(value: Any) -> Any:
def _deep_encode_value(value: Any) -> Any:
Copy link
Member Author

@Powerrr Powerrr Feb 1, 2024

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())
Copy link
Member Author

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())
Copy link
Member Author

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:
Copy link
Member Author

@Powerrr Powerrr Feb 1, 2024

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())
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

вот это одно место, где нужно преобразовывать в т.ч. вложенные объекты

@Powerrr Powerrr marked this pull request as ready for review February 1, 2024 05:51
@Powerrr Powerrr requested a review from a team as a code owner February 1, 2024 05:51
Copy link

hh-sonar bot commented Feb 1, 2024

SonarQube Quality Gate

Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@hhrelease hhrelease merged commit 19b4e28 into master Feb 1, 2024
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants