Skip to content

Commit 7121e99

Browse files
authored
Use ModuleSpec.origin (#13973)
1 parent b5870e6 commit 7121e99

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

sphinx/ext/autodoc/_documenters.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import sys
34
from typing import TYPE_CHECKING, NewType, TypeVar
45

56
from docutils.statemachine import StringList
@@ -27,7 +28,6 @@
2728

2829
if TYPE_CHECKING:
2930
from collections.abc import Callable, Iterator, Sequence
30-
from types import ModuleType
3131
from typing import Any, ClassVar, Final, Literal, NoReturn
3232

3333
from sphinx.config import Config
@@ -97,7 +97,6 @@ def __init__(
9797
self.get_attr = directive.get_attr
9898
self.name = name
9999
self.indent: Final = indent
100-
self.module: ModuleType | None = None
101100
# the parent/owner of the object to document
102101
self.parent: Any = None
103102
# the module analyzer to get at attribute docs, or None
@@ -144,10 +143,9 @@ def _load_object_by_name(self) -> Literal[True] | None:
144143
)
145144
if ret is None:
146145
return None
147-
props, module, parent = ret
146+
props, parent = ret
148147

149148
self.props = props
150-
self.module = module
151149
self.parent = parent
152150
self._load_object_has_been_called = True
153151
return True
@@ -407,9 +405,19 @@ def _generate(
407405
logger.debug('[autodoc] module analyzer failed: %s', exc)
408406
# no source file -- e.g. for builtin and C modules
409407
self.analyzer = None
410-
# at least add the module.__file__ as a dependency
411-
if module___file__ := getattr(self.module, '__file__', ''):
412-
self.directive.record_dependencies.add(module___file__)
408+
# at least add the module source file as a dependency
409+
if self.props.module_name:
410+
try:
411+
module_spec = sys.modules[self.props.module_name].__spec__
412+
except (AttributeError, KeyError):
413+
pass
414+
else:
415+
if (
416+
module_spec is not None
417+
and module_spec.has_location
418+
and module_spec.origin
419+
):
420+
self.directive.record_dependencies.add(module_spec.origin)
413421
else:
414422
self.directive.record_dependencies.add(self.analyzer.srcname)
415423

sphinx/ext/autodoc/importer.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ def _load_object_by_name(
495495
events: EventManager,
496496
get_attr: _AttrGetter,
497497
options: _AutoDocumenterOptions,
498-
) -> tuple[_ItemProperties, ModuleType | None, Any] | None:
498+
) -> tuple[_ItemProperties, Any] | None:
499499
"""Import and load the object given by *name*."""
500500
parsed = _parse_name(
501501
name=name,
@@ -542,13 +542,18 @@ def _load_object_by_name(
542542

543543
# Assemble object properties from the imported object.
544544
props: _ItemProperties
545-
module = im.module
546545
parent = im.parent
547546
object_name = im.object_name
548547
obj = im.obj
549548
obj_properties: set[_AutodocFuncProperty] = set()
550549
if objtype == 'module':
551-
file_path = getattr(module, '__file__', None)
550+
try:
551+
mod_origin = im.module.__spec__.origin # type: ignore[union-attr]
552+
except AttributeError:
553+
file_path = None
554+
else:
555+
file_path = Path(mod_origin) if mod_origin is not None else None
556+
552557
mod_all = safe_getattr(obj, '__all__', None)
553558
if isinstance(mod_all, (list, tuple)) and all(
554559
isinstance(e, str) for e in mod_all
@@ -564,7 +569,7 @@ def _load_object_by_name(
564569
obj_type=objtype,
565570
module_name=module_name,
566571
docstring_lines=(),
567-
file_path=Path(file_path) if file_path is not None else None,
572+
file_path=file_path,
568573
all=mod_all,
569574
_obj=obj,
570575
_obj___module__=obj.__name__,
@@ -911,7 +916,7 @@ def _load_object_by_name(
911916
f'{args} -> {retann}' if retann else str(args) for args, retann in signatures
912917
)
913918

914-
return props, module, parent
919+
return props, parent
915920

916921

917922
def _parse_name(

0 commit comments

Comments
 (0)