-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Expand file tree
/
Copy pathcheck_docstrings.py
More file actions
138 lines (120 loc) · 4.41 KB
/
check_docstrings.py
File metadata and controls
138 lines (120 loc) · 4.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
"""This library contains functions that checks the docstrings
Authors
* Mirco Ravanelli 2022
"""
import re
from speechbrain.utils.data_utils import get_all_files
def extractName(s, search_class=False):
"""Extracts the names of the function or classes in the input string.
Arguments
---------
s: str
Input string where to search for function or class names.
search_class: bool
If True, searches for class names.
Returns
-------
string: str
Name of the function or class detected.
"""
string = ""
if search_class:
regexp = re.compile(r"(class)\s(.*)\:")
else:
regexp = re.compile(r"(def)\s(.*)\(.*\)\:")
for m in regexp.finditer(s):
string += m.group(2)
return string
def check_docstrings(
base_folder=".", check_folders=["speechbrain", "tools", "templates"]
):
"""Checks if all the functions or classes have a docstring.
Arguments
---------
base_folder: path
The main folder of speechbrain.
check_folders: list
List of subfolders to check.
Returns
-------
check: bool
True if all the functions/classes have a docstring, False otherwise.
"""
# Search all python libraries in the folder of interest
lib_lst = get_all_files(
base_folder,
match_and=[".py"],
match_or=check_folders,
exclude_or=[".pyc"],
)
check = True
# Loop over the detected libraries
for libpath in lib_lst:
if "__" in libpath:
continue
print("Checking %s..." % (libpath))
# Support variable initialization
fun_name = libpath
class_name = libpath
check_line = True
is_class = False
first_line = True
with open(libpath, encoding="utf-8") as f:
for line in f:
# Remove spaces or tabs
line = line.strip()
# Avoid processing lines with the following patterns
if ">>>" in line:
continue
if "..." in line:
continue
if len(line) == 0:
continue
if line[0] == "#":
continue
# Check if the docstring is written after the class/funct declaration
if check_line:
if line[0] != '"' and not is_class:
if line[0:2] == 'r"':
check_line = False
continue
check = False
if first_line:
print(
"\tERROR: The library %s must start with a docstring. "
% (libpath)
+ "Please write it. For more info, see tests/consistency/DOCSTRINGS.md"
)
else:
print(
"\tERROR: The function %s in %s has no docstring. "
% (fun_name, libpath)
+ "Please write it. For more info, see tests/consistency/DOCSTRINGS.md"
)
if line[0] != '"' and is_class:
if line[0:2] == 'r"':
check_line = False
continue
check = False
print(
"\tERROR: The class %s in %s has no docstring. "
% (class_name, libpath)
+ "Please write it. For more info, see tests/consistency/DOCSTRINGS.md"
)
# Update support variables
check_line = False
is_class = False
first_line = False
continue
# Extract function name (if any)
fun_name = extractName(line)
if len(fun_name) > 0 and line[0:3] == "def":
if fun_name[0] == "_":
continue
check_line = True
# Extract class name (if any)
class_name = extractName(line, search_class=True)
if len(class_name) > 0 and line[0:5] == "class":
check_line = True
is_class = True
return check