16
16
import importlib
17
17
import inspect
18
18
import sys
19
- from typing import Dict , List
19
+ import typing
20
20
21
21
import bigframes
22
22
import bigframes .pandas as bpd
50
50
"remote" ,
51
51
]
52
52
53
+ COVERAGE_GENERATORS = {
54
+ "documentation" : lambda docstr : docstr ,
55
+ "code samples" : lambda docstr : docstr and "**Examples:**" in docstr ,
56
+ }
57
+
53
58
for module_name in ML_MODULE_NAMES :
54
59
module = importlib .import_module (f"bigframes.ml.{ module_name } " )
55
60
classes_ = [
58
63
CLASSES .extend (classes_ )
59
64
60
65
61
- def get_code_samples_summary () -> Dict [str , Dict [str , List [str ]]]:
66
+ def get_coverage_summary (
67
+ func : typing .Callable ,
68
+ ) -> typing .Dict [str , typing .Dict [str , typing .List [str ]]]:
62
69
"""Get Summary of the code samples coverage in BigFrames APIs.
63
70
71
+ Args:
72
+ func (callable):
73
+ Function to accept documentation and return whether it satisfies
74
+ coverage.
64
75
Returns:
65
76
Summary: A dictionary of the format
66
77
{
@@ -73,7 +84,7 @@ def get_code_samples_summary() -> Dict[str, Dict[str, List[str]]]:
73
84
}
74
85
}
75
86
"""
76
- summary : Dict [str , Dict [str , List [str ]]] = dict ()
87
+ summary : typing . Dict [str , typing . Dict [str , typing . List [str ]]] = dict ()
77
88
78
89
for class_ in CLASSES :
79
90
class_key = f"{ class_ .__module__ } .{ class_ .__name__ } "
@@ -104,29 +115,39 @@ def predicate(impl):
104
115
impl = getattr (class_ , name )
105
116
106
117
docstr = inspect .getdoc (impl )
107
- code_samples_present = docstr and "**Examples:**" in docstr
108
- key = PRESENT if code_samples_present else NOT_PRESENT
118
+ coverage_present = func ( docstr )
119
+ key = PRESENT if coverage_present else NOT_PRESENT
109
120
summary [class_key ][key ].append (name )
110
121
111
122
return summary
112
123
113
124
114
125
if __name__ == "__main__" :
115
126
parser = argparse .ArgumentParser (
116
- description = "Get a summary of code samples coverage in BigFrames APIs."
127
+ description = "Get a summary of documentation coverage in BigFrames APIs."
128
+ )
129
+ parser .add_argument (
130
+ "-c" ,
131
+ "--code-samples" ,
132
+ type = bool ,
133
+ action = argparse .BooleanOptionalAction ,
134
+ default = False ,
135
+ help = "Whether to calculate code samples coverage. By default the tool"
136
+ " calculates the documentation (docstring) coverage." ,
117
137
)
118
138
parser .add_argument (
119
139
"-d" ,
120
140
"--details" ,
121
141
type = bool ,
122
142
action = argparse .BooleanOptionalAction ,
123
143
default = False ,
124
- help = "Whether to print APIs with and without code samples ." ,
144
+ help = "Whether to print APIs with and without the coverage ." ,
125
145
)
126
146
127
147
args = parser .parse_args (sys .argv [1 :])
128
148
129
- summary = get_code_samples_summary ()
149
+ scenario = "code samples" if args .code_samples else "documentation"
150
+ summary = get_coverage_summary (COVERAGE_GENERATORS [scenario ])
130
151
131
152
total_with_code_samples = 0
132
153
total = 0
@@ -140,8 +161,8 @@ def predicate(impl):
140
161
coverage = 100 * apis_with_code_samples / apis_total
141
162
print (f"{ class_ } : { coverage :.1f} % ({ apis_with_code_samples } /{ apis_total } )" )
142
163
if args .details :
143
- print (f"===> APIs WITH code samples : { class_summary [PRESENT ]} " )
144
- print (f"===> APIs WITHOUT code samples : { class_summary [NOT_PRESENT ]} " )
164
+ print (f"===> APIs WITH { scenario } : { class_summary [PRESENT ]} " )
165
+ print (f"===> APIs WITHOUT { scenario } : { class_summary [NOT_PRESENT ]} " )
145
166
146
167
coverage = 100 * total_with_code_samples / total
147
168
print (f"Total: { coverage :.1f} % ({ total_with_code_samples } /{ total } )" )
0 commit comments