Skip to content

Commit

Permalink
Fix prepended escape char handling (#94)
Browse files Browse the repository at this point in the history
  • Loading branch information
jsh9 authored Oct 20, 2023

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
1 parent d2b1d21 commit 71cdf37
Showing 7 changed files with 74 additions and 15 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Change Log

## [0.3.8] - 2023-10-20

- Fixed

- A bug in handling prepended escape characters in docstrings

- Full diff
- https://github.com/jsh9/pydoclint/compare/0.3.7...0.3.8

## [0.3.7] - 2023-10-19

- Changed
20 changes: 7 additions & 13 deletions pydoclint/utils/arg.py
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@ def __init__(self, name: str, typeHint: str) -> None:
if len(name) == 0:
raise ValueError('`name` cannot be an empty string')

self.name: str = name
self.name: str = self._removeEscapeChar(name)
self.typeHint: str = typeHint

def __repr__(self) -> str:
@@ -32,7 +32,7 @@ def __eq__(self, other: 'Arg') -> bool:
if not isinstance(other, Arg):
return False

argNamesEqual: bool = self._argNamesEq(self.name, other.name)
argNamesEqual: bool = self.name == other.name
typeHintsEqual: bool = self._typeHintsEq(self.typeHint, other.typeHint)
return argNamesEqual and typeHintsEqual

@@ -110,20 +110,14 @@ def _typeHintsEq(cls, hint1: str, hint2: str) -> bool:

return hint1_ == hint2_

@classmethod
def _argNamesEq(cls, name1: str, name2: str) -> bool:
return cls._removeEscapeChar(name1) == cls._removeEscapeChar(name2)

@classmethod
def _removeEscapeChar(cls, string: str) -> str:
# We need to remove `\` from the arg names before comparing them,
# because when there are 1 or 2 trailing underscores in an argument,
# people need to use `\_` or `\_\_`, otherwise Sphinx will somehow
# not render the underscores (and for some reason, 3 or more trailing
# underscores are fine).
#
# We need to remove `\` from the arg names for proper comparison.
# This is because it is often necessary to add `\` in docstrings in
# order for Sphinx to correctly render them.
# For example:
# arg1\_\_ (int): The first argument
# arg1\_\_
# \\**kwargs
return string.replace('\\', '')


2 changes: 1 addition & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = pydoclint
version = 0.3.7
version = 0.3.8
description = A Python docstring linter that checks arguments, returns, yields, and raises sections
long_description = file: README.md
long_description_content_type = text/markdown
9 changes: 9 additions & 0 deletions tests/data/edge_cases/05_escape_char/google.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# From these issues:
# https://github.com/jsh9/pydoclint/issues/73
# https://github.com/jsh9/pydoclint/issues/92


def myFunc(
arg1_: int,
arg2__: int,
@@ -8,6 +13,8 @@ def myFunc(
some_thing_3___: int,
some_thing_4____: int,
some_thing_5_____: str,
*args: Any,
**kwargs: Any,
) -> None:
r"""
Do something.
@@ -22,6 +29,8 @@ def myFunc(
some_thing_3\_\_\_ (int): Arg
some_thing_4\_\_\_\_ (int): Arg
some_thing_5_____ (str): Arg
*args (Any): Args
**kwargs (Any): Keyword args
Returns:
None: Return value
11 changes: 11 additions & 0 deletions tests/data/edge_cases/05_escape_char/numpy.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# From these issues:
# https://github.com/jsh9/pydoclint/issues/73
# https://github.com/jsh9/pydoclint/issues/92


def myFunc(
arg1_: int,
arg2__: int,
@@ -8,6 +13,8 @@ def myFunc(
some_thing_3___: int,
some_thing_4____: int,
some_thing_5_____: str,
*args: Any,
**kwargs: Any,
) -> None:
r"""
Do something.
@@ -32,6 +39,10 @@ def myFunc(
Arg
some_thing_5_____ : str
Arg
*args : Any
Args
**kwargs : Any
Keyword args
Returns
-------
11 changes: 11 additions & 0 deletions tests/data/edge_cases/05_escape_char/sphinx.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# From these issues:
# https://github.com/jsh9/pydoclint/issues/73
# https://github.com/jsh9/pydoclint/issues/92


def myFunc(
arg1_: int,
arg2__: int,
@@ -8,6 +13,8 @@ def myFunc(
some_thing_3___: int,
some_thing_4____: int,
some_thing_5_____: str,
*args: Any,
**kwargs: Any,
) -> None:
r"""
Do something.
@@ -30,6 +37,10 @@ def myFunc(
:type some_thing_4\_\_\_\_: int
:param some_thing_5_____: Arg
:type some_thing_5_____: str
:param \\*args: Args
:type \\*args: Any
:param \\**kwargs: Args
:type \\**kwargs: Any
:return: Return value
:rtype: None
"""
27 changes: 26 additions & 1 deletion tests/utils/test_arg.py
Original file line number Diff line number Diff line change
@@ -16,6 +16,9 @@ def testArg_initializationCheck():
(Arg(name='1', typeHint='2'), '1: 2'),
(Arg(name='arg1', typeHint='str'), 'arg1: str'),
(Arg(name='obj', typeHint='int | float'), 'obj: int | float'),
(Arg(name='arg1\_\_', typeHint='Any'), 'arg1__: Any'), # noqa: W605
(Arg(name='**kwargs', typeHint='Any'), '**kwargs: Any'),
(Arg(name='\\**kwargs', typeHint='Any'), '**kwargs: Any'),
],
)
def testArg_str(arg: Arg, string_repr: str) -> None:
@@ -28,6 +31,10 @@ def testArg_str(arg: Arg, string_repr: str) -> None:
(Arg(name='1', typeHint='2'), Arg(name='1', typeHint='2')),
(Arg(name='abc', typeHint='12345'), Arg(name='abc', typeHint='12345')),
(Arg(name='aa', typeHint=''), Arg(name='aa', typeHint='')),
(Arg(name='\\**kw', typeHint=''), Arg(name='**kw', typeHint='')),
(Arg(name='**kw', typeHint=''), Arg(name='\\**kw', typeHint='')),
(Arg(name='\\*args', typeHint=''), Arg(name='*args', typeHint='')),
(Arg(name='*args', typeHint=''), Arg(name='\\*args', typeHint='')),
],
)
def testArg_equal(arg1: Arg, arg2: Arg) -> None:
@@ -137,7 +144,7 @@ def testArg_sorting(original: Set[Arg], after: List[Arg]) -> None:
('Literal["abc", "def"]', "Literal[\n 'abc',\n 'def',\n]", True),
],
)
def testArg_eq(str1: str, str2: str, expected: bool) -> None:
def testArg_typeHintsEq(str1: str, str2: str, expected: bool) -> None:
assert Arg._typeHintsEq(str1, str2) == expected


@@ -193,6 +200,14 @@ def testArgList_length(input_: ArgList, expected: int) -> None:
ArgList([Arg('1', '2'), Arg('2', '3'), Arg('3', '4')]),
ArgList([Arg('1', '2'), Arg('2', '3'), Arg('3', '4')]),
),
(
ArgList([Arg('*args', '1'), Arg('\\**kwargs', '2')]),
ArgList([Arg('\\*args', '1'), Arg('**kwargs', '2')]),
),
(
ArgList([Arg('arg1\_', '1'), Arg('arg2__', '2')]), # noqa: W605
ArgList([Arg('arg1_', '1'), Arg('arg2\_\_', '2')]), # noqa: W605
),
],
)
def testArgList_equality(list1: ArgList, list2: ArgList) -> None:
@@ -298,6 +313,16 @@ def testArgList_contains(
ArgList([]),
{Arg('a', '1'), Arg('b', '2'), Arg('c', '3')},
),
(
ArgList([Arg('*args', '1'), Arg('\\**kwargs', '2')]),
ArgList([Arg('\\*args', '1')]),
{Arg('**kwargs', '2')},
),
(
ArgList([Arg('arg1\_', '1'), Arg('arg2__', '2')]), # noqa: W605
ArgList([Arg('arg2\_\_', '2')]), # noqa: W605
{Arg('arg1_', '1')},
),
],
)
def testArgList_subtract(

0 comments on commit 71cdf37

Please sign in to comment.