8
8
from griffe .loader import GriffeLoader
9
9
from griffe .collections import ModulesCollection , LinesCollection
10
10
from griffe .docstrings .parsers import Parser
11
+ from griffe .exceptions import AliasResolutionError
11
12
from functools import partial
12
13
from textwrap import indent
13
14
@@ -120,6 +121,26 @@ def _non_default_entries(el: Auto):
120
121
return {k : getattr (el , k ) for k in el ._fields_specified }
121
122
122
123
124
+ def _resolve_alias (obj : dc .Alias | dc .Object , get_object ):
125
+ if not isinstance (obj , dc .Alias ):
126
+ return obj
127
+
128
+ # attempt to resolve alias, loading external modules when needed ----
129
+ max_tries = 100
130
+
131
+ new_obj = obj
132
+ for ii in range (max_tries ):
133
+ if not new_obj .is_alias :
134
+ break
135
+
136
+ try :
137
+ new_obj = new_obj .target
138
+ except AliasResolutionError as e :
139
+ new_obj = get_object (e .alias .target_path )
140
+
141
+ return new_obj
142
+
143
+
123
144
class BlueprintTransformer (PydanticTransformer ):
124
145
def __init__ (self , get_object = None , parser = "numpy" ):
125
146
if get_object is None :
@@ -296,8 +317,9 @@ def enter(self, el: Auto):
296
317
297
318
# do no document submodules
298
319
if (
299
- _is_external_alias (doc .obj , obj .package )
300
- or doc .obj .kind .value == "module"
320
+ # _is_external_alias(doc.obj, obj.package)
321
+ doc .obj .kind .value
322
+ == "module"
301
323
):
302
324
continue
303
325
@@ -332,13 +354,19 @@ def enter(self, el: Auto):
332
354
signature_name = el .signature_name ,
333
355
)
334
356
335
- @staticmethod
336
- def _fetch_members (el : Auto , obj : dc .Object | dc .Alias ):
357
+ def _fetch_members (self , el : Auto , obj : dc .Object | dc .Alias ):
358
+ # Note that this could be a static method, if we passed in the griffe loader
359
+
337
360
if el .members is not None :
338
361
return el .members
339
362
340
363
options = obj .all_members if el .include_inherited else obj .members
341
364
365
+ # use the __all__ attribute of modules to filter members
366
+ # otherwise, all members are included in the initial options
367
+ if obj .is_module and obj .exports is not None :
368
+ options = {k : v for k , v in options .items () if v .is_exported }
369
+
342
370
if el .include :
343
371
raise NotImplementedError ("include argument currently unsupported." )
344
372
@@ -348,9 +376,14 @@ def _fetch_members(el: Auto, obj: dc.Object | dc.Alias):
348
376
if not el .include_private :
349
377
options = {k : v for k , v in options .items () if not k .startswith ("_" )}
350
378
351
- if not el .include_imports and not el .include_inherited :
379
+ if not ( el .include_imports or el .include_inherited ) :
352
380
options = {k : v for k , v in options .items () if not v .is_alias }
353
381
382
+ # resolve any remaining aliases ----
383
+ # the reamining filters require attributes on the target object.
384
+ for obj in options .values ():
385
+ _resolve_alias (obj , self .get_object )
386
+
354
387
if not el .include_empty :
355
388
options = {k : v for k , v in options .items () if v .docstring is not None }
356
389
@@ -363,12 +396,6 @@ def _fetch_members(el: Auto, obj: dc.Object | dc.Alias):
363
396
if not el .include_functions :
364
397
options = {k : v for k , v in options .items () if not v .is_function }
365
398
366
- # for modules, remove any Alias objects, since they were imported from
367
- # other places. Sphinx has a flag for this behavior, so may be good
368
- # to do something similar.
369
- # if obj.is_module:
370
- # options = {k: v for k, v in options.items() if not v.is_alias}
371
-
372
399
return sorted (options )
373
400
374
401
0 commit comments