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

Commit

Permalink
Select best imperative by longest prefix match
Browse files Browse the repository at this point in the history
  • Loading branch information
lordmauve authored and Nurdok committed Jul 20, 2019
1 parent ee4e264 commit d9c35a9
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 2 deletions.
8 changes: 6 additions & 2 deletions src/pydocstyle/checker.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from .parser import (Package, Module, Class, NestedClass, Definition, AllError,
Method, Function, NestedFunction, Parser, StringIO,
ParseError)
from .utils import log, is_blank, pairwise
from .utils import log, is_blank, pairwise, common_prefix_length
from .wordlists import IMPERATIVE_VERBS, IMPERATIVE_BLACKLIST, stem


Expand Down Expand Up @@ -448,8 +448,12 @@ def check_imperative_mood(self, function, docstring): # def context
return

if correct_forms and check_word not in correct_forms:
best = max(
correct_forms,
key=lambda f: common_prefix_length(check_word, f)
)
return violations.D401(
next(iter(correct_forms)).capitalize(),
best.capitalize(),
first_word
)

Expand Down
13 changes: 13 additions & 0 deletions src/pydocstyle/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,16 @@ def pairwise(
a, b = tee(iterable)
_ = next(b, default_value)
return zip_longest(a, b, fillvalue=default_value)


def common_prefix_length(a: str, b: str) -> int:
"""Return the length of the longest common prefix of a and b.
>>> common_prefix_length('abcd', 'abce')
3
"""
for common, (ca, cb) in enumerate(zip(a, b)):
if ca != cb:
return common
return common + 1
16 changes: 16 additions & 0 deletions src/tests/test_cases/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -387,6 +387,22 @@ def docstring_ignore_some_violations_but_catch_D401(): # noqa: E501,D400,D415
pass


@expect(
"D401: First line should be in imperative mood "
"('Initiate', not 'Initiates')"
)
def docstring_initiates():
"""Initiates the process."""


@expect(
"D401: First line should be in imperative mood "
"('Initialize', not 'Initializes')"
)
def docstring_initializes():
"""Initializes the process."""


@wraps(docstring_bad_ignore_one)
def bad_decorated_function():
"""Bad (E501) but decorated"""
Expand Down
23 changes: 23 additions & 0 deletions src/tests/test_utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Unit test for pydocstyle utils.
Use tox or py.test to run the test suite.
"""
from pydocstyle import utils


__all__ = ()


def test_common_prefix():
"""We can find the common prefix of two strings."""
assert utils.common_prefix_length('abcd', 'abce') == 3


def test_no_common_prefix():
"""If two strings have no common prefix, return the empty string."""
assert utils.common_prefix_length('abcd', 'cdef') == 0


def test_differ_length():
"""We can find a common prefix of two strings differing in length."""
assert utils.common_prefix_length('abcd', 'ab') == 2

0 comments on commit d9c35a9

Please sign in to comment.