Skip to content

Commit 141f3ec

Browse files
committed
Elaborate a little more in the warning message for config.cache
1 parent af27188 commit 141f3ec

File tree

2 files changed

+15
-16
lines changed

2 files changed

+15
-16
lines changed

Diff for: sphinx/config.py

+14-15
Original file line numberDiff line numberDiff line change
@@ -51,30 +51,28 @@ class ConfigValue(NamedTuple):
5151
rebuild: _ConfigRebuild
5252

5353

54-
def is_serializable(obj: object, *, _recursive_guard: frozenset[int] = frozenset()) -> bool:
55-
"""Check if object is serializable or not."""
54+
def is_serializable(obj: object, *, _seen: frozenset[int] = frozenset()) -> bool:
55+
"""Check if an object is serializable or not."""
5656
if isinstance(obj, UNSERIALIZABLE_TYPES):
5757
return False
5858

5959
# use id() to handle un-hashable objects
60-
if id(obj) in _recursive_guard:
60+
if id(obj) in _seen:
6161
return True
6262

6363
if isinstance(obj, dict):
64-
guard = _recursive_guard | {id(obj)}
65-
for key, value in obj.items():
66-
if (
67-
not is_serializable(key, _recursive_guard=guard)
68-
or not is_serializable(value, _recursive_guard=guard)
69-
):
70-
return False
64+
seen = _seen | {id(obj)}
65+
return all(
66+
is_serializable(key, _seen=seen) and is_serializable(value, _seen=seen)
67+
for key, value in obj.items()
68+
)
7169
elif isinstance(obj, (list, tuple, set, frozenset)):
72-
guard = _recursive_guard | {id(obj)}
73-
return all(is_serializable(item, _recursive_guard=guard) for item in obj)
70+
seen = _seen | {id(obj)}
71+
return all(is_serializable(item, _seen=seen) for item in obj)
7472

7573
# if an issue occurs for a non-serializable type, pickle will complain
76-
# since the object is likely coming from a third-party extension (we
77-
# natively expect 'simple' types and not weird ones)
74+
# since the object is likely coming from a third-party extension
75+
# (we natively expect 'simple' types and not weird ones)
7876
return True
7977

8078

@@ -473,7 +471,8 @@ def __getstate__(self) -> dict:
473471
# will always mark the config value as changed,
474472
# and thus always invalidate the cache and perform a rebuild.
475473
logger.warning(
476-
__('cannot cache unpickable configuration value: %r'),
474+
__('cannot cache unpickable configuration value: %r '
475+
'(because it contains a function, class, or module object)'),
477476
name,
478477
type='config',
479478
subtype='cache',

Diff for: tests/test_config/test_config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ def union(self, *args: Iterable[object]) -> UselessGuard:
4646

4747
# check that without recursive guards, a recursion error occurs
4848
with pytest.raises(RecursionError):
49-
assert is_serializable(subject, _recursive_guard=UselessGuard())
49+
assert is_serializable(subject, _seen=UselessGuard())
5050

5151

5252
def test_is_serializable() -> None:

0 commit comments

Comments
 (0)