@@ -229,6 +229,9 @@ def setup(app):
229229
230230 # hook to run apidoc before building
231231 app .connect ('builder-inited' , run_apidoc )
232+ # hooks to test docstring coverage
233+ app .connect ('autodoc-process-docstring' , doc_coverage )
234+ app .connect ('build-finished' , doc_report )
232235
233236
234237def run_apidoc (_ ):
@@ -248,3 +251,39 @@ def run_apidoc(_):
248251 main (['-TMf' , '-s' , 'inc' ,
249252 '-t' , templates_path ,
250253 '-o' , out_path , daq_models_path ])
254+
255+
256+ members_to_watch = ['module' , 'class' , 'function' , 'exception' , 'method' , 'attribute' ]
257+ doc_count = 0
258+ undoc_count = 0
259+ undoc_objects = []
260+ undoc_print_objects = False
261+
262+
263+ def doc_coverage (app , what , name , obj , options , lines ):
264+ global doc_count
265+ global undoc_count
266+ global undoc_objects
267+
268+ if (what in members_to_watch and len (lines ) == 0 ):
269+ # blank docstring detected
270+ undoc_count += 1
271+ undoc_objects .append (name )
272+ else :
273+ doc_count += 1
274+
275+
276+ def doc_report (app , exception ):
277+ global doc_count
278+ global undoc_count
279+ global undoc_objects
280+ # print out report of documentation coverage
281+ total_docs = undoc_count + doc_count
282+ if total_docs != 0 :
283+ print (f'\n API Doc coverage of { doc_count / total_docs :.1%} ' )
284+ if undoc_print_objects or os .environ .get ('READTHEDOCS' ):
285+ print ('\n Items lacking documentation' )
286+ print ('===========================' )
287+ print (* undoc_objects , sep = '\n ' )
288+ else :
289+ print ('No docs counted, run \' make clean\' then rebuild to get the count.' )
0 commit comments