8
8
9
9
.. code:: python
10
10
11
- import sys
12
- from pathlib import Path
13
-
14
- HERE = Path(__file__).parent
15
- # make sure modules are import from the right place
16
- sys.path.insert(0, HERE.parent / "src")
17
-
18
11
extensions = [
19
12
"scanpydoc",
20
13
"sphinx.ext.linkcode",
67
60
68
61
import inspect
69
62
import sys
63
+ from importlib import import_module
70
64
from pathlib import Path , PurePosixPath
71
65
from types import ModuleType
72
66
from typing import Any
@@ -108,14 +102,18 @@ def _get_obj_module(qualname: str) -> tuple[Any, ModuleType]:
108
102
# retrieve object and find original module name
109
103
mod = sys .modules [modname ]
110
104
obj = None
105
+ del modname
111
106
for attr_name in attr_path :
112
107
try :
113
108
thing = getattr (mod if obj is None else obj , attr_name )
114
- except AttributeError :
109
+ except AttributeError as e :
115
110
if is_dataclass (obj ):
116
111
thing = next (f for f in fields (obj ) if f .name == attr_name )
117
112
else :
118
- raise
113
+ try :
114
+ thing = import_module (f"{ mod .__name__ } .{ attr_name } " )
115
+ except ImportError :
116
+ raise e from None
119
117
if isinstance (thing , ModuleType ):
120
118
mod = thing
121
119
else :
@@ -137,12 +135,15 @@ def _get_linenos(obj):
137
135
return start , start + len (lines ) - 1
138
136
139
137
140
- def _module_path (module : ModuleType ) -> PurePosixPath :
141
- stem = PurePosixPath (* module .__name__ .split ("." ))
142
- if Path (module .__file__ ).name == "__init__.py" :
143
- return stem / "__init__.py"
144
- else :
145
- return stem .with_suffix (".py" )
138
+ def _module_path (obj : Any , module : ModuleType ) -> PurePosixPath :
139
+ """Relative module path to parent directory of toplevel module."""
140
+ try :
141
+ file = Path (inspect .getabsfile (obj ))
142
+ except TypeError :
143
+ file = Path (module .__file__ )
144
+ offset = - 1 if file .name == "__init__.py" else 0
145
+ parts = module .__name__ .split ("." )
146
+ return PurePosixPath (* file .parts [offset - len (parts ) :])
146
147
147
148
148
149
def github_url (qualname : str ) -> str :
@@ -159,7 +160,7 @@ def github_url(qualname: str) -> str:
159
160
except Exception :
160
161
print (f"Error in github_url({ qualname !r} ):" , file = sys .stderr )
161
162
raise
162
- path = rtd_links_prefix / _module_path (module )
163
+ path = rtd_links_prefix / _module_path (obj , module )
163
164
start , end = _get_linenos (obj )
164
165
fragment = f"#L{ start } -L{ end } " if start and end else ""
165
166
return f"{ github_base_url } /{ path } { fragment } "
0 commit comments