Skip to content

Commit

Permalink
add: option for checking nested functions and classes (#293)
Browse files Browse the repository at this point in the history
Signed-off-by: Stephen Whitlock <stephen@jshwisolutions.com>
  • Loading branch information
jshwi committed Apr 14, 2024
1 parent 15be6fc commit fb330fb
Show file tree
Hide file tree
Showing 7 changed files with 186 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

[Unreleased](https://github.com/jshwi/docsig/compare/v0.46.0...HEAD)
------------------------------------------------------------------------
### Added
- option for checking nested functions and classes

### Fixed
- check indented functions and classes

Expand Down
5 changes: 3 additions & 2 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,8 @@ Commandline

.. code-block:: console
usage: docsig [-h] [-V] [-l] [-c | -C] [-D] [-m] [-o] [-p] [-P] [-i] [-a] [-k]
[-n] [-S] [-v] [-s STR] [-d LIST] [-t LIST] [-e EXCLUDE]
usage: docsig [-h] [-V] [-l] [-c | -C] [-D] [-m] [-N] [-o] [-p] [-P] [-i] [-a]
[-k] [-n] [-S] [-v] [-s STR] [-d LIST] [-t LIST] [-e EXCLUDE]
[path [path ...]]
Check signature params for proper documentation
Expand All @@ -96,6 +96,7 @@ Commandline
-D, --check-dunders check dunder methods
-m, --check-protected-class-methods check public methods belonging to protected
classes
-N, --check-nested check nested functions and classes
-o, --check-overridden check overridden methods
-p, --check-protected check protected functions and classes
-P, --check-property-returns check property return values
Expand Down
6 changes: 6 additions & 0 deletions docsig/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ def _add_arguments(self) -> None:
action="store_true",
help="check public methods belonging to protected classes",
)
self.add_argument(
"-N",
"--check-nested",
action="store_true",
help="check nested functions and classes",
)
self.add_argument(
"-o",
"--check-overridden",
Expand Down
23 changes: 23 additions & 0 deletions docsig/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ def _run_check( # pylint: disable=too-many-arguments
check_class: bool,
check_class_constructor: bool,
check_dunders: bool,
check_nested: bool,
check_overridden: bool,
check_protected: bool,
check_property_returns: bool,
Expand Down Expand Up @@ -79,6 +80,24 @@ def _run_check( # pylint: disable=too-many-arguments
failures.append(
_Failure(child, _FuncStr(child, no_ansi), report)
)

if check_nested:
for func in child:
_run_check(
func,
child,
check_class,
check_class_constructor,
check_dunders,
check_nested,
check_overridden,
check_protected,
check_property_returns,
ignore_no_params,
no_ansi,
targets,
failures,
)
else:
for func in child:
_run_check(
Expand All @@ -87,6 +106,7 @@ def _run_check( # pylint: disable=too-many-arguments
check_class,
check_class_constructor,
check_dunders,
check_nested,
check_overridden,
check_protected,
check_property_returns,
Expand All @@ -107,6 +127,7 @@ def docsig( # pylint: disable=too-many-locals,too-many-arguments
check_class_constructor: bool = False,
check_dunders: bool = False,
check_protected_class_methods: bool = False,
check_nested: bool = False,
check_overridden: bool = False,
check_protected: bool = False,
check_property_returns: bool = False,
Expand Down Expand Up @@ -138,6 +159,7 @@ def docsig( # pylint: disable=too-many-locals,too-many-arguments
:param check_dunders: Check dunder methods
:param check_protected_class_methods: Check public methods belonging
to protected classes.
:param check_nested: Check nested functions and classes.
:param check_overridden: Check overridden methods
:param check_protected: Check protected functions and classes.
:param check_property_returns: Run return checks on properties.
Expand Down Expand Up @@ -186,6 +208,7 @@ def docsig( # pylint: disable=too-many-locals,too-many-arguments
check_class,
check_class_constructor,
check_dunders,
check_nested,
check_overridden,
check_protected,
check_property_returns,
Expand Down
1 change: 1 addition & 0 deletions docsig/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ def main() -> str | int:
check_protected_class_methods=(
parser.args.check_protected_class_methods
),
check_nested=parser.args.check_nested,
check_overridden=parser.args.check_overridden,
check_protected=parser.args.check_protected,
check_property_returns=parser.args.check_property_returns,
Expand Down
147 changes: 147 additions & 0 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ def __call__(self, content: str, path: Path = ..., /) -> Path:
long.check_dunders,
long.check_property_returns,
long.check_protected_class_methods,
long.check_nested,
)
FAIL_CHECK_ARGS = tuple(f"f-{i[8:]}" for i in CHECK_ARGS)
ENABLE = "enable"
Expand Down Expand Up @@ -8777,3 +8778,149 @@ def my_external_function(✖argument) -> ✖int:
E113: function is missing a docstring (function-doc-missing)
"""


@_templates.register
class _FNestedFuncN(_BaseTemplate):
@property
def template(self) -> str:
return '''
def my_function(argument: int = 42) -> int:
"""
Function that prints a message and returns the argument + 1
Parameters
----------
argument : int, optional
The input argument, by default 42
Returns
-------
int
The input argument + 1
"""
print("Hello from a function")
print(argument)
def my_external_function(argument: int = 42) -> int:
print("Hello from an external function")
print(argument)
return argument + 42
return argument + 1
'''

@property
def expected(self) -> str:
return """\
def my_external_function(✖argument) -> ✖int:
...
E113: function is missing a docstring (function-doc-missing)
"""


# starts with `M` for multi instead of `F` so we don't run
# `test_single_flag` with this as it needs `-N/--check-nested` and
# `-c/--check-class` to fail
@_templates.register
class _MNestedKlassNotMethodOkN(_BaseTemplate):
@property
def template(self) -> str:
return '''
def my_function(argument: int = 42) -> int:
"""
Function that prints a message and returns the argument + 1
Parameters
----------
argument : int, optional
The input argument, by default 42
Returns
-------
int
The input argument + 1
"""
print("Hello from a function")
print(argument)
class Klass:
def __init__(self, this) -> None:
self.this = this
def my_external_function(self, argument: int = 42) -> int:
"""This is a method.
:param argument: An int.
:return: An int.
"""
print("Hello from an external function")
print(argument)
return argument + 42
return argument + 1
'''

@property
def expected(self) -> str:
return """\
module/file.py:19 in Klass
--------------------------
class Klass:
...
def __init__(✖this) -> ✓None:
E114: class is missing a docstring (class-doc-missing)
"""


@_templates.register
class _MNestedKlassNotMethodNotN(_BaseTemplate):
@property
def template(self) -> str:
return '''
def my_function(argument: int = 42) -> int:
"""
Function that prints a message and returns the argument + 1
Parameters
----------
argument : int, optional
The input argument, by default 42
Returns
-------
int
The input argument + 1
"""
print("Hello from a function")
print(argument)
class Klass:
def __init__(self, this) -> None:
self.this = this
def my_external_function(self, argument: int = 42) -> int:
print("Hello from an external function")
print(argument)
return argument + 42
return argument + 1
'''

@property
def expected(self) -> str:
return """\
module/file.py:19 in Klass
--------------------------
class Klass:
...
def __init__(✖this) -> ✓None:
E114: class is missing a docstring (class-doc-missing)
module/file.py:21 in Klass
--------------------------
def my_external_function(✖argument) -> ✖int:
...
E113: function is missing a docstring (function-doc-missing)
"""
3 changes: 3 additions & 0 deletions whitelist.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
_FMethodWKwargsS # unused class (tests/__init__.py)
_FMsgPoorIndentS # unused class (tests/__init__.py)
_FMsgPoorIndentSRs # unused class (tests/__init__.py)
_FNestedFuncN # unused class (tests/__init__.py)
_FNoDocClassS # unused class (tests/__init__.py)
_FNoDocNoRetN # unused class (tests/__init__.py)
_FNoDocNoRetS # unused class (tests/__init__.py)
Expand Down Expand Up @@ -200,6 +201,8 @@
_MInvalidDirectiveOptions # unused class (tests/__init__.py)
_MInvalidSingleDirectiveOptions # unused class (tests/__init__.py)
_MInvalidSingleModuleDirectiveOptions # unused class (tests/__init__.py)
_MNestedKlassNotMethodNotN # unused class (tests/__init__.py)
_MNestedKlassNotMethodOkN # unused class (tests/__init__.py)
_MPassBadInlineDirective # unused class (tests/__init__.py)
_MPassBadModuleDirective # unused class (tests/__init__.py)
_MPassCommentDisableModuleFirstS # unused class (tests/__init__.py)
Expand Down

0 comments on commit fb330fb

Please sign in to comment.