mirror of
https://github.com/sphinx-doc/sphinx.git
synced 2025-02-25 18:55:22 -06:00
Add `stable_str()
` (#12948)
Co-authored-by: Eric Larson <larson.eric.d@gmail.com>
This commit is contained in:
parent
e5df455087
commit
b6f818f600
@ -3,6 +3,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import json
|
||||
import types
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
@ -25,3 +26,28 @@ def stable_hash(obj: Any) -> str:
|
||||
# We use the fully qualified name instead.
|
||||
obj = f'{obj.__module__}.{obj.__qualname__}'
|
||||
return hashlib.md5(str(obj).encode(), usedforsecurity=False).hexdigest()
|
||||
|
||||
|
||||
def stable_str(obj: Any, *, indent: int | None = None) -> str:
|
||||
"""Return a stable string representation of a Python data structure.
|
||||
|
||||
We can't just use ``str(obj)`` as the order of collections may be random.
|
||||
"""
|
||||
return json.dumps(_stable_str_prep(obj), indent=indent)
|
||||
|
||||
|
||||
def _stable_str_prep(obj: Any) -> dict[str, Any] | list[Any] | str:
|
||||
if isinstance(obj, dict):
|
||||
# Convert to a sorted dict
|
||||
obj = [(_stable_str_prep(k), _stable_str_prep(v)) for k, v in obj.items()]
|
||||
obj.sort()
|
||||
return dict(obj)
|
||||
if isinstance(obj, list | tuple | set | frozenset):
|
||||
# Convert to a sorted list
|
||||
return sorted(map(_stable_str_prep, obj))
|
||||
if isinstance(obj, type | types.FunctionType):
|
||||
# The default repr() of functions includes the ID, which is not ideal.
|
||||
# We use the fully qualified name instead.
|
||||
return f'{obj.__module__}.{obj.__qualname__}'
|
||||
# We can't do any better, just use the string representation
|
||||
return str(obj)
|
||||
|
Loading…
Reference in New Issue
Block a user