From 4f072ee5c29faf7d6d636f37216e92e09011409c Mon Sep 17 00:00:00 2001 From: Takeshi KOMIYA Date: Wed, 24 Feb 2021 01:32:05 +0900 Subject: [PATCH] Fix #8917: autodoc: Raises a warning if function has wrong __globals__ value `sphinx.util.inspect:signature()` crashes with AttributeError when subject has wrong `__globals__` value. This ignores the error on building. --- CHANGES | 1 + sphinx/util/inspect.py | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index e4b06ae411f..9ddab2294aa 100644 --- a/CHANGES +++ b/CHANGES @@ -69,6 +69,7 @@ Features added Bugs fixed ---------- +* #8917: autodoc: Raises a warning if function has wrong __globals__ value * #8380: html search: Paragraphs in search results are not identified as ``

`` * #8915: html theme: The translation of sphinx_rtd_theme does not work * #8342: Emit a warning if a unknown domain is given for directive or role (ex. diff --git a/sphinx/util/inspect.py b/sphinx/util/inspect.py index 3cf1c6824a3..dbeb547b131 100644 --- a/sphinx/util/inspect.py +++ b/sphinx/util/inspect.py @@ -166,6 +166,15 @@ def getannotations(obj: Any) -> Mapping[str, Any]: return {} +def getglobals(obj: Any) -> Mapping[str, Any]: + """Get __globals__ from given *obj* safely.""" + __globals__ = safe_getattr(obj, '__globals__', None) + if isinstance(__globals__, Mapping): + return __globals__ + else: + return {} + + def getmro(obj: Any) -> Tuple["Type", ...]: """Get __mro__ from given *obj* safely.""" __mro__ = safe_getattr(obj, '__mro__', None) @@ -484,9 +493,9 @@ def __repr__(self) -> str: def _should_unwrap(subject: Callable) -> bool: """Check the function should be unwrapped on getting signature.""" - if (safe_getattr(subject, '__globals__', None) and - subject.__globals__.get('__name__') == 'contextlib' and # type: ignore - subject.__globals__.get('__file__') == contextlib.__file__): # type: ignore + __globals__ = getglobals(subject) + if (__globals__.get('__name__') == 'contextlib' and + __globals__.get('__file__') == contextlib.__file__): # contextmanger should be unwrapped return True