Skip to content

Commit

Permalink
add: Adds disable option
Browse files Browse the repository at this point in the history
  • Loading branch information
jshwi committed Jun 28, 2022
1 parent 0d9406d commit ecb5057
Show file tree
Hide file tree
Showing 12 changed files with 300 additions and 79 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
[Unreleased](https://github.com/jshwi/docsig/compare/v0.11.0...HEAD)
------------------------------------------------------------------------
### Added
- Adds disable option
- Adds error for missing return type
- Adds error for documented property returns

Expand Down
20 changes: 16 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,25 @@ Commandline

.. code-block:: console
usage: docsig [-h] [-v] [path [path ...]]
usage: docsig [-h] [-v] [-d LIST] [path [path ...]]
Check docstring matches signature
positional arguments:
path directories or files to check
path directories or files to check
optional arguments:
-h, --help show this help message and exit
-v, --version show version and exit
-h, --help show this help message and exit
-v, --version show version and exit
-d LIST, --disable LIST comma separated list of rules to disable
Options can also be configured with the pyproject.toml file

.. code-block:: toml
[tool.docsig]
disable = [
"E101",
"E102",
"E103",
]
43 changes: 42 additions & 1 deletion docsig/_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,56 @@
docsig._cli
===========
"""
import re as _re
import sys as _sys
import typing as _t
from argparse import ArgumentParser as _ArgumentParser
from argparse import HelpFormatter as _HelpFormatter
from pathlib import Path as _Path

import tomli as _tomli

from ._utils import color as _color
from ._utils import find_pyproject_toml as _find_pyproject_toml
from ._version import __version__

NAME = __name__.split(".", maxsplit=1)[0]

ConfigType = _t.Dict[str, _t.Any]


# split str by comma, but allow for escaping
def _split_comma(value: str) -> _t.List[str]:
return [i.replace("\\,", ",") for i in _re.split(r"(?<!\\),", value)]


def get_config() -> ConfigType:
"""Get config dict object from package's tool section in toml file.
:return: Dict object; containing config if there is one, else return
empty.
"""
pyproject_file = _find_pyproject_toml()
if pyproject_file is None:
return {}

return (
_tomli.loads(pyproject_file.read_text()).get("tool", {}).get(NAME, {})
)


class Parser(_ArgumentParser):
"""Parse commandline arguments."""

def __init__(self) -> None:
def __init__(self, kwargs: ConfigType) -> None:
super().__init__(
prog=_color.cyan.get(NAME),
formatter_class=lambda prog: _HelpFormatter(
prog, max_help_position=45
),
description="Check docstring matches signature",
)
self._kwargs = kwargs
self._add_arguments()
self._version_request()
self.args = self.parse_args()
Expand All @@ -38,6 +70,15 @@ def _add_arguments(self) -> None:
action="store_true",
help="show version and exit",
)
self.add_argument(
"-d",
"--disable",
action="store",
metavar="LIST",
type=_split_comma,
default=self._kwargs.get("disable", []),
help="comma separated list of rules to disable",
)

@staticmethod
def _version_request() -> None:
Expand Down
7 changes: 5 additions & 2 deletions docsig/_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,16 +112,19 @@ def print_failures(failures: FailedDocData) -> None:
print(f"{func}\n{summary.get_report()}")


def populate(name: str, parent: _Parent, failures: FailedDocData) -> None:
def populate(
name: str, parent: _Parent, failures: FailedDocData, disable: _t.List[str]
) -> None:
"""Populate function issues.
:param name: Name of function parent.
:param parent: Functions ``Parent`` object.
:param failures: Dictionary of failure objects.
:param disable: List of rules to disable.
"""
module_data = []
for func in parent.funcs:
report = _Report(func)
report = _Report(func, disable)
report.exists()
report.missing()
report.duplicates()
Expand Down
8 changes: 5 additions & 3 deletions docsig/_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from pathlib import Path as _Path

from ._cli import Parser as _Parser
from ._cli import get_config as _get_config
from ._core import FailedDocData as _FailedDocData
from ._core import get_files as _get_files
from ._core import get_members as _get_members
Expand All @@ -22,16 +23,17 @@ def main() -> int:
"""
paths: _t.List[_Path] = []
failures: _FailedDocData = {}
parser = _Parser()
config = _get_config()
parser = _Parser(config)
for path in parser.args.path:
_get_files(path, paths)

members = _get_members(paths)
for module in members:
_populate(module.name, module, failures)
_populate(module.name, module, failures, parser.args.disable)
for klass in module.classes:
name = f"{module.name}::{klass.name}"
_populate(name, klass, failures)
_populate(name, klass, failures, parser.args.disable)

_print_failures(failures)

Expand Down
4 changes: 2 additions & 2 deletions docsig/_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ class Report(_MessageSequence):
:param func: Function object.
"""

def __init__(self, func: _Function) -> None:
super().__init__()
def __init__(self, func: _Function, disable: _t.List[str]) -> None:
super().__init__(disable)
self._func = func

def order(self, arg: str | None, doc: str | None) -> None:
Expand Down
20 changes: 20 additions & 0 deletions docsig/_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from __future__ import annotations

import typing as _t
from pathlib import Path as _Path

from object_colors import Color as _Color

Expand Down Expand Up @@ -39,3 +40,22 @@ def lstrip_quant(string: str, quant: int) -> str:
string = string[4:]

return string


def find_pyproject_toml(path: _Path | None = None) -> _Path | None:
"""Attempt to locate a pyproject.toml file if one exists in parents.
:param path: Path to start search, if None start with CWD.
:return: Path to pyproject.toml if it exists, else None.
"""
if not path:
path = _Path.cwd()

pyproject_toml = path / "pyproject.toml"
if pyproject_toml.is_file():
return pyproject_toml

if path == _Path("/"):
return None

return find_pyproject_toml(path.parent)
14 changes: 13 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ version = "0.11.0"
astroid = "^2.11.6"
object-colors = "^2.1.0"
python = "^3.8"
tomli = "^2.0.1"

[tool.poetry.dev-dependencies]
bump2version = "^1.0.1"
Expand All @@ -71,6 +72,7 @@ pytest-sugar = "^0.9.4"
restview = "^3.0.0"
sphinx-toolbox = "^3.1.1"
templatest = "^0.5.0"
tomli-w = "^1.0.0"

[tool.poetry.scripts]
docsig = "docsig.__main__:main"
Expand Down
29 changes: 19 additions & 10 deletions tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,17 @@
MULTI = "multi"
E101 = "E101"
E102 = "E102"
E103 = "E103"
E104 = "E104"
E105 = "E105"
E106 = "E106"
E107 = "E107"
E108 = "E108"
H101 = "H101"
H102 = "H102"
NAME = "name"
TEMPLATE = "template"
ERR_GROUP = "fail-e-1-0"


@_templates.register
Expand Down Expand Up @@ -252,7 +261,7 @@ def function({CHECK}param1, {CHECK}param2, {CHECK}param3) -> {CROSS}int:


@_templates.register
class _FailNoRetNoType(_BaseTemplate):
class _FailE109NoRetNoType(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand Down Expand Up @@ -352,7 +361,7 @@ def function({CHECK}param1) -> {CROSS}Optional[str]:


@_templates.register
class _FailOutOfOrder1Sum(_BaseTemplate):
class _FailE101OutOfOrder1Sum(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand Down Expand Up @@ -397,7 +406,7 @@ def function({CHECK}param1, {CROSS}None) -> {CHECK}None:


@_templates.register
class _FailParamDocs1Sum(_BaseTemplate):
class _FailE102ParamDocs1Sum(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand All @@ -416,7 +425,7 @@ def expected(self) -> str:


@_templates.register
class _FailParamSig1Sum(_BaseTemplate):
class _FailE103ParamSig1Sum(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand All @@ -434,7 +443,7 @@ def expected(self) -> str:


@_templates.register
class _FailRetTypeDocs1Sum(_BaseTemplate):
class _FailE104RetTypeDocs1Sum(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand All @@ -454,7 +463,7 @@ def expected(self) -> str:


@_templates.register
class _FailRetTypeSig1Sum(_BaseTemplate):
class _FailE105RetTypeSig1Sum(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand Down Expand Up @@ -840,7 +849,7 @@ def expected(self) -> str:


@_templates.register
class _FailPoorIndent(_BaseTemplate):
class _FailMsgPoorIndent(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand All @@ -866,7 +875,7 @@ def expected(self) -> str:


@_templates.register
class _FailNoSpace(_BaseTemplate):
class _FailE103NoSpace(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand Down Expand Up @@ -1087,7 +1096,7 @@ def expected(self) -> str:


@_templates.register
class _FailWRetQuestion(_BaseTemplate):
class _FailE109WRetQuestion(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand All @@ -1104,7 +1113,7 @@ def expected(self) -> str:


@_templates.register
class _FailWORetQuestion(_BaseTemplate):
class _FailE109WORetQuestion(_BaseTemplate):
@property
def template(self) -> str:
return """
Expand Down
Loading

0 comments on commit ecb5057

Please sign in to comment.