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

Select best imperative by longest prefix match #379

Merged
merged 1 commit into from
Jul 20, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -385,6 +385,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