Skip to content
This repository was archived by the owner on Nov 3, 2023. It is now read-only.

Commit da8a3ce

Browse files
committed
Improve imperative mood check using stemmer/wordlist
1 parent 69bb3b8 commit da8a3ce

File tree

12 files changed

+438
-20
lines changed

12 files changed

+438
-20
lines changed

requirements/runtime.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
snowballstemmer==1.2.1

setup.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
keywords='pydocstyle, PEP 257, pep257, PEP 8, pep8, docstrings',
3232
packages=('pydocstyle',),
3333
package_dir={'': 'src'},
34+
package_data={'pydocstyle': ['data/*.txt']},
35+
install_requires=[
36+
'snowballstemmer==1.2.1',
37+
],
3438
entry_points={
3539
'console_scripts': [
3640
'pydocstyle = pydocstyle.cli:main',

src/pydocstyle/checker.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
from .parser import (Package, Module, Class, NestedClass, Definition, AllError,
1414
Method, Function, NestedFunction, Parser, StringIO)
1515
from .utils import log, is_blank
16+
from .wordlists import IMPERATIVE_VERBS, IMPERATIVE_BLACKLIST, stem
1617

1718

1819
__all__ = ('check', )
@@ -361,12 +362,21 @@ def check_imperative_mood(self, function, docstring): # def context
361362
"Returns the pathname ...".
362363
363364
"""
364-
if docstring:
365+
if docstring and not function.is_test:
365366
stripped = ast.literal_eval(docstring).strip()
366367
if stripped:
367368
first_word = stripped.split()[0]
368-
if first_word.endswith('s') and not first_word.endswith('ss'):
369-
return violations.D401(first_word[:-1], first_word)
369+
check_word = first_word.lower()
370+
371+
if check_word in IMPERATIVE_BLACKLIST:
372+
return violations.D401b(first_word)
373+
374+
correct_form = IMPERATIVE_VERBS.get(stem(check_word))
375+
if correct_form and correct_form != check_word:
376+
return violations.D401(
377+
correct_form.capitalize(),
378+
first_word
379+
)
370380

371381
@check_for(Function)
372382
def check_no_signature(self, function, docstring): # def context

src/pydocstyle/data/imperatives.txt

Lines changed: 232 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,232 @@
1+
# Imperative forms of verbs
2+
#
3+
# This file contains the imperative form of frequently encountered
4+
# docstring verbs. Some of these may be more commonly encountered as
5+
# nouns, but blacklisting them for this may cause false positives.
6+
accept
7+
access
8+
add
9+
adjust
10+
aggregate
11+
allow
12+
append
13+
apply
14+
archive
15+
assert
16+
assign
17+
attempt
18+
authenticate
19+
authorize
20+
break
21+
build
22+
cache
23+
calculate
24+
call
25+
cancel
26+
capture
27+
change
28+
check
29+
clean
30+
clear
31+
close
32+
collect
33+
combine
34+
commit
35+
compare
36+
compute
37+
configure
38+
confirm
39+
connect
40+
construct
41+
control
42+
convert
43+
copy
44+
count
45+
create
46+
customize
47+
declare
48+
decode
49+
decorate
50+
define
51+
delegate
52+
delete
53+
deprecate
54+
derive
55+
describe
56+
detect
57+
determine
58+
display
59+
download
60+
drop
61+
dump
62+
emit
63+
empty
64+
enable
65+
encapsulate
66+
encode
67+
end
68+
ensure
69+
enumerate
70+
establish
71+
evaluate
72+
examine
73+
execute
74+
exit
75+
expand
76+
expect
77+
export
78+
extend
79+
extract
80+
feed
81+
fetch
82+
fill
83+
filter
84+
finalize
85+
find
86+
fire
87+
fix
88+
flag
89+
force
90+
format
91+
forward
92+
generate
93+
get
94+
give
95+
go
96+
group
97+
handle
98+
help
99+
hold
100+
identify
101+
implement
102+
import
103+
indicate
104+
init
105+
initalise
106+
initialise
107+
initialize
108+
input
109+
insert
110+
instantiate
111+
intercept
112+
invoke
113+
iterate
114+
join
115+
keep
116+
launch
117+
list
118+
listen
119+
load
120+
log
121+
look
122+
make
123+
manage
124+
manipulate
125+
map
126+
mark
127+
match
128+
merge
129+
mock
130+
modify
131+
monitor
132+
move
133+
normalize
134+
note
135+
obtain
136+
open
137+
output
138+
override
139+
overwrite
140+
pad
141+
parse
142+
partial
143+
pass
144+
perform
145+
persist
146+
pick
147+
plot
148+
poll
149+
populate
150+
post
151+
prepare
152+
print
153+
process
154+
produce
155+
provide
156+
publish
157+
pull
158+
put
159+
query
160+
raise
161+
read
162+
record
163+
refer
164+
refresh
165+
register
166+
reload
167+
remove
168+
rename
169+
render
170+
replace
171+
reply
172+
report
173+
represent
174+
request
175+
require
176+
reset
177+
resolve
178+
retrieve
179+
return
180+
roll
181+
rollback
182+
round
183+
run
184+
sample
185+
save
186+
scan
187+
search
188+
select
189+
send
190+
serialise
191+
serialize
192+
serve
193+
set
194+
show
195+
simulate
196+
source
197+
specify
198+
split
199+
start
200+
step
201+
stop
202+
store
203+
strip
204+
submit
205+
subscribe
206+
sum
207+
swap
208+
sync
209+
synchronise
210+
synchronize
211+
take
212+
tear
213+
test
214+
time
215+
transform
216+
translate
217+
transmit
218+
truncate
219+
try
220+
turn
221+
tweak
222+
update
223+
upload
224+
use
225+
validate
226+
verify
227+
view
228+
wait
229+
walk
230+
wrap
231+
write
232+
yield
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Blacklisted imperative words
2+
#
3+
# These are words that, if they begin a docstring, are a good indicator that
4+
# the docstring is not written in an imperative voice.
5+
#
6+
# The words included in this list fall into a number of categories:
7+
#
8+
# - Starting with a noun/pronoun indicates that the docstring is a noun phrase
9+
# or a sentence but not in the imperative mood
10+
# - Adjectives are always followed by a noun, so same
11+
# - Particles are also followed by a noun
12+
# - Some adverbs don't really indicate an imperative sentence, for example
13+
# "importantly" or "currently".
14+
# - Some irregular verb forms that don't stem to the same string as the
15+
# imperative does (eg. 'does')
16+
:param
17+
:return
18+
:return:
19+
:returns
20+
:returns:
21+
:rtype
22+
a
23+
an
24+
the
25+
action
26+
always
27+
api
28+
base
29+
basic
30+
business
31+
calculation
32+
callback
33+
collection
34+
common
35+
constructor
36+
convenience
37+
convenient
38+
current
39+
currently
40+
custom
41+
data
42+
data
43+
default
44+
deprecated
45+
description
46+
description:
47+
dict
48+
dictionary
49+
does
50+
dummy
51+
example
52+
factory
53+
false
54+
final
55+
formula
56+
function
57+
generic
58+
handler
59+
handler
60+
helper
61+
here
62+
hook
63+
implementation
64+
importantly
65+
internal
66+
it
67+
main
68+
method
69+
module
70+
new
71+
number
72+
optional
73+
package
74+
parameters:
75+
placeholder
76+
reference
77+
result
78+
returns:
79+
same
80+
schema
81+
setup
82+
should
83+
simple
84+
some
85+
special
86+
sql
87+
standard
88+
static
89+
string
90+
subclasses
91+
that
92+
these
93+
this
94+
true
95+
unique
96+
unit
97+
utility
98+
what
99+
wrapper
100+
101+
102+
# These are nouns, but often used in the context of functions that act as
103+
# objects; thus we do not blacklist these.
104+
#
105+
# context # as in context manager
106+
# decorator
107+
# class # as in class decorator
108+
# property
109+
# generator

0 commit comments

Comments
 (0)