From 81704368e3368c4f7b6d6ea6b16b163608579d65 Mon Sep 17 00:00:00 2001 From: jsh9 <25124332+jsh9@users.noreply.github.com> Date: Sun, 29 Sep 2024 18:30:50 -0400 Subject: [PATCH] Improve handling of long type annotations (#173) --- CHANGELOG.md | 9 +++++ pydoclint/utils/generic.py | 6 ++- setup.cfg | 2 +- .../15_very_long_annotations/google.py | 32 ++++++++++++++++ .../15_very_long_annotations/numpy.py | 37 +++++++++++++++++++ .../15_very_long_annotations/sphinx.py | 36 ++++++++++++++++++ tests/test_main.py | 3 ++ 7 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 tests/data/edge_cases/15_very_long_annotations/google.py create mode 100644 tests/data/edge_cases/15_very_long_annotations/numpy.py create mode 100644 tests/data/edge_cases/15_very_long_annotations/sphinx.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c5fb61e..f4a4e3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,14 @@ # Change Log +## [0.5.9] - 2024-09-29 + +- Fixed + + - Fixed an edge case where type annotations are very long + +- Full diff + - https://github.com/jsh9/pydoclint/compare/0.5.8...0.5.9 + ## [0.5.8] - 2024-09-23 - Fixed diff --git a/pydoclint/utils/generic.py b/pydoclint/utils/generic.py index 9f3bde4..2d7ea72 100644 --- a/pydoclint/utils/generic.py +++ b/pydoclint/utils/generic.py @@ -214,11 +214,15 @@ def appendArgsToCheckToV105( def specialEqual(str1: str, str2: str) -> bool: """ Check string equality but treat any single quotes as the same as - double quotes. + double quotes, and also ignore line breaks in either strings. """ if str1 == str2: return True # using shortcuts to speed up evaluation + if '\n' in str1 or '\n' in str2: + str1 = str1.replace(' ', '').replace('\n', '') + str2 = str2.replace(' ', '').replace('\n', '') + if len(str1) != len(str2): return False # using shortcuts to speed up evaluation diff --git a/setup.cfg b/setup.cfg index 9ec6c76..9a1e34c 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,6 +1,6 @@ [metadata] name = pydoclint -version = 0.5.8 +version = 0.5.9 description = A Python docstring linter that checks arguments, returns, yields, and raises sections long_description = file: README.md long_description_content_type = text/markdown diff --git a/tests/data/edge_cases/15_very_long_annotations/google.py b/tests/data/edge_cases/15_very_long_annotations/google.py new file mode 100644 index 0000000..56f4658 --- /dev/null +++ b/tests/data/edge_cases/15_very_long_annotations/google.py @@ -0,0 +1,32 @@ +# This edge case was reported in https://github.com/jsh9/pydoclint/issues/164 + +# fmt: off +import numpy as np + + +def func( + arg1: tuple[ + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + ], +) -> tuple[ + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray]: + """ + The docstring parser for the Google style does not support line breaking + in type hints. Therefore, in order to pass pydoclint's checks, we can only + put long type hints in one line. + + Args: + arg1 (tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]): A parameter + + Returns: + tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]: The return value + """ + return ( + np.array([]), np.array([]), np.array([]), np.array([]), np.array([]), + np.array([]), np.array([]), np.array([]), np.array([]), + ) + +# fmt: on diff --git a/tests/data/edge_cases/15_very_long_annotations/numpy.py b/tests/data/edge_cases/15_very_long_annotations/numpy.py new file mode 100644 index 0000000..ba33007 --- /dev/null +++ b/tests/data/edge_cases/15_very_long_annotations/numpy.py @@ -0,0 +1,37 @@ +# This edge case was reported in https://github.com/jsh9/pydoclint/issues/164 + +# fmt: off + +import numpy as np + + +def func( + arg1: tuple[ + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + ], +) -> tuple[ + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray]: + """ + The docstring parser for the numpy style does not support line breaking + in type hints. Therefore, in order to pass pydoclint's checks, we can only + put long type hints in one line. + + Parameters + ---------- + arg1 : tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray] + A parameter + + Returns + ------- + tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray] + The return value + """ + return ( + np.array([]), np.array([]), np.array([]), np.array([]), np.array([]), + np.array([]), np.array([]), np.array([]), np.array([]), + ) + +# fmt: on diff --git a/tests/data/edge_cases/15_very_long_annotations/sphinx.py b/tests/data/edge_cases/15_very_long_annotations/sphinx.py new file mode 100644 index 0000000..d3bf3e0 --- /dev/null +++ b/tests/data/edge_cases/15_very_long_annotations/sphinx.py @@ -0,0 +1,36 @@ +# This edge case was reported in https://github.com/jsh9/pydoclint/issues/164 + +# fmt: off + +import numpy as np + + +def func( + arg1: tuple[ + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + ], +) -> tuple[ + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray]: + """Something + + :param arg1: A parameter + :type arg1: tuple[ + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + ] + + :returns: Numpy arrays + :rtype: tuple[ + np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, + np.ndarray, np.ndarray, np.ndarray] + """ + return ( + np.array([]), np.array([]), np.array([]), np.array([]), np.array([]), + np.array([]), np.array([]), np.array([]), np.array([]), + ) + +# fmt: on diff --git a/tests/test_main.py b/tests/test_main.py index 71f2485..0a68f60 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1456,6 +1456,9 @@ def testNonAscii() -> None: 'args do not match: arg1' ], ), + ('15_very_long_annotations/sphinx.py', {'style': 'sphinx'}, []), + ('15_very_long_annotations/google.py', {'style': 'google'}, []), + ('15_very_long_annotations/numpy.py', {'style': 'numpy'}, []), ], ) def testEdgeCases(