@@ -129,6 +129,13 @@ def status_disclaimer(status: str) -> str:
129129 return admonition ('warning' , 'This API is not documented yet.' )
130130 return ''
131131
132+ def multi_class_disclaimer (classes : list [str ]) -> str :
133+ """Return tip informing about all classes documented on the page"""
134+ content = f'This page contains documentation for the `{ classes [0 ]} ` class and its subclasses: \n '
135+ for i , class_name in enumerate (classes [1 :], start = 1 ):
136+ content += list_item (link (class_name , f'#{ class_name .lower ()} ' ))
137+ return admonition ('tip' , content )
138+
132139def dedup_newlines (text : str ) -> str :
133140 return re .sub (r'\n{2}' , ' \n ' , text )
134141
@@ -225,9 +232,9 @@ def check_concatenation(api_name: str) -> str:
225232
226233 return api_name
227234
228- def parse_class_apis (class_name : str , file_content : str ) -> str :
235+ def parse_class_apis (class_name : str , file_content : str , file_path : str ) -> str :
229236 matches = re .findall (CLASS_API_NAME_PATTERN , file_content )
230- section = header ('h3' , class_name )
237+ section = header ('h3' , link ( class_name , f'./apis/classes/ { file_path . replace ( ".py" , "" ) } ' ) )
231238 for api_name in matches :
232239 api_name = check_concatenation (api_name )
233240
@@ -243,12 +250,19 @@ def parse_method_api(method_name: str, file_content: str) -> str:
243250 section = header ('h4' , 'Internal API' )
244251 section += div (text (api_name , ['code' ]), 'padding' , 'left' , 'md' )
245252 else :
246- warnings .warn (f'Failed to parse API name for { method_name } ' , UserWarning )
253+ warnings .warn (f'Method { method_name } seems to not be directly calling any internal API, this is expected for utility methods that use other calls in the class. ' , UserWarning )
247254 return section + NEWLINE
248255
249- def gen_header (class_name : str , docstring : str ) -> str :
250- content , docs_status = metadata (class_name )
251- content += header ('h1' , class_name )
256+ def gen_header (class_name : str , docstring : str , classes : list [str ]) -> str :
257+ content = ''
258+ docs_status = ''
259+
260+ if class_name == classes [0 ]:
261+ content , docs_status = metadata (class_name )
262+ if len (classes ) > 1 :
263+ content += multi_class_disclaimer (classes )
264+
265+ content += header ('h1' , class_name ) if class_name == classes [0 ] else header ('h2' , class_name )
252266 content += status_disclaimer (docs_status )
253267 content += header ('h2' , 'Overview' )
254268
@@ -333,16 +347,18 @@ def main():
333347 warnings .warn (f'Failed to parse { file_name } ' , UserWarning )
334348 continue
335349
336- for class_type in docstrings ["content" ]:
337- if is_private (class_type ['name' ]):
338- continue
339-
340- supported_apis += parse_class_apis (class_type ['name' ], file_content )
341- doc_content += gen_header (class_type ['name' ], class_type ['docstring_text' ])
342-
343- for method in class_type ['content' ]:
344- if is_private (method ['name' ]):
345- continue
350+ classes = [c for c in docstrings ["content" ] if not is_private (c ['name' ])]
351+ classes_names = [c ['name' ] for c in classes ]
352+ for i , class_item in enumerate (classes ):
353+ supported_apis += parse_class_apis (class_item ['name' ], file_content , file_name )
354+ doc_content += gen_header (
355+ class_item ['name' ],
356+ class_item ['docstring_text' ],
357+ classes = classes_names
358+ )
359+
360+ methods = [m for m in class_item ['content' ] if not is_private (m ['name' ])]
361+ for method in methods :
346362 doc_content += gen_method (method , file_content )
347363
348364 # Write to md files if the args were set
0 commit comments