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

Commit 286d933

Browse files
authored
Merge pull request #235 from lordmauve/imperative-mood-heuristic-2
Improve imperative mood check using stemmer/wordlist
2 parents 07ada6a + 490edfa commit 286d933

File tree

14 files changed

+440
-25
lines changed

14 files changed

+440
-25
lines changed

docs/conf.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,12 @@
103103

104104
# The theme to use for HTML and HTML Help pages. See the documentation for
105105
# a list of builtin themes.
106-
html_theme = 'default'
106+
try:
107+
import sphinx_rtd_theme
108+
except ImportError:
109+
html_theme = 'default'
110+
else:
111+
html_theme = 'sphinx_rtd_theme'
107112

108113
# Theme options are theme-specific and customize the look and feel of a theme
109114
# further. For a list of options available for each theme, see the

requirements/docs.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
sphinxcontrib-issuetracker
1+
sphinxcontrib-issuetracker
2+
sphinx_rtd_theme

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',
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, pairwise
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: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
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+
a
17+
an
18+
the
19+
action
20+
always
21+
api
22+
base
23+
basic
24+
business
25+
calculation
26+
callback
27+
collection
28+
common
29+
constructor
30+
convenience
31+
convenient
32+
current
33+
currently
34+
custom
35+
data
36+
data
37+
default
38+
deprecated
39+
description
40+
dict
41+
dictionary
42+
does
43+
dummy
44+
example
45+
factory
46+
false
47+
final
48+
formula
49+
function
50+
generic
51+
handler
52+
handler
53+
helper
54+
here
55+
hook
56+
implementation
57+
importantly
58+
internal
59+
it
60+
main
61+
method
62+
module
63+
new
64+
number
65+
optional
66+
package
67+
placeholder
68+
reference
69+
result
70+
same
71+
schema
72+
setup
73+
should
74+
simple
75+
some
76+
special
77+
sql
78+
standard
79+
static
80+
string
81+
subclasses
82+
that
83+
these
84+
this
85+
true
86+
unique
87+
unit
88+
utility
89+
what
90+
wrapper
91+
92+
93+
# These are nouns, but often used in the context of functions that act as
94+
# objects; thus we do not blacklist these.
95+
#
96+
# context # as in context manager
97+
# decorator
98+
# class # as in class decorator
99+
# property
100+
# generator

0 commit comments

Comments
 (0)