18
18
import inspect
19
19
import os
20
20
import pathlib
21
+ import textwrap
22
+ import types
21
23
import typing
22
- from typing import Any , Callable , List , Sequence , Tuple
24
+ from typing import Any , Callable , List , Sequence , Tuple , Union
25
+
23
26
24
27
from tensorflow_docs .api_generator import doc_controls
25
28
from tensorflow_docs .api_generator import doc_generator_visitor
@@ -167,7 +170,7 @@ def util_2
167
170
return filtered_children
168
171
169
172
170
- def _get_imported_symbols (obj ):
173
+ def _get_imported_symbols (obj : Union [ str , types . ModuleType ] ):
171
174
"""Returns a list of symbol names imported by the given `obj`."""
172
175
173
176
class ImportNodeVisitor (ast .NodeVisitor ):
@@ -177,15 +180,24 @@ def __init__(self):
177
180
self .imported_symbols = []
178
181
179
182
def _add_imported_symbol (self , node ):
180
- self .imported_symbols .extend ([alias .name for alias in node .names ])
183
+ for alias in node .names :
184
+ name = alias .asname or alias .name
185
+ if name == '*' :
186
+ continue
187
+ if '.' in name :
188
+ continue
189
+ self .imported_symbols .append (name )
181
190
182
191
def visit_Import (self , node ): # pylint: disable=invalid-name
183
192
self ._add_imported_symbol (node )
184
193
185
194
def visit_ImportFrom (self , node ): # pylint: disable=invalid-name
186
195
self ._add_imported_symbol (node )
187
196
188
- source = get_source .get_source (obj )
197
+ if isinstance (obj , str ):
198
+ source = textwrap .dedent (obj )
199
+ else :
200
+ source = get_source .get_source (obj )
189
201
if source is None :
190
202
return []
191
203
@@ -197,21 +209,57 @@ def visit_ImportFrom(self, node): # pylint: disable=invalid-name
197
209
198
210
def explicit_package_contents_filter (path : Sequence [str ], parent : Any ,
199
211
children : Children ) -> Children :
200
- """Filter modules to only include explicit contents.
201
-
202
- This function returns the children explicitly included by this module, meaning
203
- that it will exclude:
212
+ """Filter submodules, only keep what's explicitly included.
204
213
205
- * Modules in a package not explicitly imported by the package (submodules
206
- are implicitly injected into their parent's namespace).
207
- * Modules imported by a module that is not a package.
214
+ This filter only affects the visibility of **modules**. Other objects are not
215
+ affected.
208
216
209
217
This filter is useful if you explicitly define your API in the packages of
210
- your library, but do not expliticly define that API in the `__all__` variable
211
- of each module. The purpose is to make it easier to maintain that API.
218
+ your library (the __init__.py files), but do not expliticly define that API
219
+ in the `__all__` variable of each module. The purpose is to make it easier to
220
+ maintain that API.
221
+
222
+ **This filter makes it so that modules are only documented where they are
223
+ explicitly imported in an __init__.py**
224
+
225
+ ### Packages
226
+
227
+ Lots of imports **indirectly** inject modules into package namespaces, this
228
+ filter helps you ignore those. Anywhere you `import pkg.sub1` it will inject
229
+ `sub1` into the `pkg` namsspace.
230
+
231
+ When filtering a package it only keeps modules that are **directly**
232
+ impotrted in the package. This code, injects `[sub0, sub1, sub2, sub3, sub4,
233
+ sub_sub1, *]` into the pkg namespace:
234
+
235
+ pkg/__init__.py
236
+
237
+ ```
238
+ import sub0
239
+ import pkg.sub1
240
+ from pkg import sub2
241
+ from pkg.sub3 import sub_sub1
242
+ from pkg.sub4 import *
243
+ ```
244
+
245
+ But this filter will only keep the modules `[sub0, sub2, sub_sub1]` in the
246
+ docs for `pkg`.
247
+
248
+ ### Regular modules
249
+
250
+ For regular modules all modules in the namespace are assumed to be
251
+ implementation details and/or documented in their source location. For example
252
+ in this package:
253
+
254
+ ```
255
+ pkg/
256
+ __init__.py
257
+ sub1.py
258
+ sub2.py
259
+ ```
212
260
213
- Note: This filter does work with wildcard imports, however it is generally not
214
- recommended to use wildcard imports.
261
+ If you `import sub2` in `__init__.py` `sub2` will documented in `pkg`
262
+ But if you `import sub2` in `sub1.py` `sub2` will not be documented in `sub1`
215
263
216
264
Args:
217
265
path: A tuple of names forming the path to the object.
0 commit comments