docsig 0.36.0__tar.gz → 0.37.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: docsig
3
- Version: 0.36.0
3
+ Version: 0.37.0
4
4
  Summary: Check signature params for proper documentation
5
5
  Home-page: https://pypi.org/project/docsig/
6
6
  License: MIT
@@ -2,19 +2,30 @@
2
2
  docsig._core
3
3
  ============
4
4
  """
5
- from __future__ import annotations
5
+ from __future__ import annotations as _
6
6
 
7
+ import sys as _sys
8
+ from os import environ as _e
7
9
  from pathlib import Path as _Path
8
10
 
9
11
  from ._display import Display as _Display
10
12
  from ._display import Failure as _Failure
11
13
  from ._display import Failures as _Failures
12
14
  from ._display import FuncStr as _FuncStr
15
+ from ._display import color as _color
13
16
  from ._module import Modules as _Modules
14
17
  from ._module import Parent as _Parent
15
18
  from ._report import generate_report as _generate_report
16
19
 
17
20
 
21
+ def pretty_print_error() -> None:
22
+ """Print user friendly commandline error if debug not enabled."""
23
+ if _e.get("DOCSIG_DEBUG", None) != "1":
24
+ _sys.excepthook = lambda x, y, _: print(
25
+ f"{_color.red.bold.get(x.__name__)}: {y}"
26
+ )
27
+
28
+
18
29
  def _run_check( # pylint: disable=too-many-arguments
19
30
  parent: _Parent,
20
31
  check_class: bool,
@@ -25,11 +36,9 @@ def _run_check( # pylint: disable=too-many-arguments
25
36
  ignore_no_params: bool,
26
37
  no_ansi: bool,
27
38
  targets: list[str],
28
- disable: list[str],
29
39
  ) -> _Failures:
30
40
  failures = _Failures()
31
41
  for func in parent:
32
- disable_func = list({*disable, *func.disabled})
33
42
  if not (func.isoverridden and not check_overridden) and (
34
43
  not (func.isprotected and not check_protected)
35
44
  and not (func.isinit and not check_class)
@@ -37,7 +46,7 @@ def _run_check( # pylint: disable=too-many-arguments
37
46
  and not (func.docstring.bare and ignore_no_params)
38
47
  ):
39
48
  report = _generate_report(
40
- func, targets, disable_func, check_property_returns
49
+ func, targets, func.disabled, check_property_returns
41
50
  )
42
51
  if report:
43
52
  failures.append(
@@ -91,6 +100,7 @@ def docsig( # pylint: disable=too-many-locals
91
100
  """
92
101
  modules = _Modules(
93
102
  *path,
103
+ disable=disable or [],
94
104
  string=string,
95
105
  ignore_args=ignore_args,
96
106
  ignore_kwargs=ignore_kwargs,
@@ -109,7 +119,6 @@ def docsig( # pylint: disable=too-many-locals
109
119
  ignore_no_params,
110
120
  no_ansi,
111
121
  targets or [],
112
- disable or [],
113
122
  )
114
123
  if failures:
115
124
  display[top_level.path].append(failures)
@@ -2,31 +2,33 @@
2
2
  docsig._disable
3
3
  ===============
4
4
  """
5
- from __future__ import annotations
5
+ from __future__ import annotations as _
6
6
 
7
7
  import tokenize as _tokenize
8
- import typing as t
8
+ import typing as _t
9
9
  from io import StringIO as _StringIO
10
10
 
11
11
  from ._report import ERRORS as _ERRORS
12
12
 
13
13
 
14
- class Disabled(t.Dict[int, t.List[str]]):
14
+ class Disabled(_t.Dict[int, _t.List[str]]):
15
15
  """Data for lines which are excluded from checks.
16
16
 
17
17
  :param text: Python code.
18
+ :param disable: List of checks to disable.
18
19
  """
19
20
 
20
- def __init__(self, text: str) -> None:
21
+ def __init__(self, text: str, disable: list[str]) -> None:
21
22
  super().__init__()
22
23
  fin = _StringIO(text)
23
24
  module_is_disabled = False
24
25
  for line in _tokenize.generate_tokens(fin.readline):
25
26
  lineno = line.start[0]
26
27
  col = line.start[1]
28
+ self[lineno] = list(disable)
27
29
  if line.type == _tokenize.COMMENT:
28
- if line.string.startswith(f"# {__package__}:"):
29
- string = line.string.split(": ")[1]
30
+ if line.string[1:].strip().startswith(f"{__package__}:"):
31
+ string = line.string.split(":")[1].strip()
30
32
 
31
33
  # module level comments
32
34
  if col == 0:
@@ -37,11 +39,11 @@ class Disabled(t.Dict[int, t.List[str]]):
37
39
 
38
40
  # otherwise, inline comments
39
41
  elif string == "disable":
40
- self[lineno] = list(_ERRORS)
42
+ self[lineno].extend(_ERRORS)
41
43
 
42
44
  # keep appending disabled lines as long as this is true
43
45
  if module_is_disabled:
44
- self[lineno] = list(_ERRORS)
46
+ self[lineno].extend(_ERRORS)
45
47
 
46
48
  def __setitem__(self, key: int, value: list[str]) -> None:
47
49
  if key not in self:
@@ -2,7 +2,7 @@
2
2
  docsig._display
3
3
  ===============
4
4
  """
5
- from __future__ import annotations
5
+ from __future__ import annotations as _
6
6
 
7
7
  import typing as _t
8
8
  from collections import UserString as _UserString
@@ -20,7 +20,6 @@ from ._function import ARG as _ARG
20
20
  from ._function import KEY as _KEY
21
21
  from ._function import Function as _Function
22
22
  from ._function import Param as _Param
23
- from ._objects import MutableSequence as _MutableSequence
24
23
  from ._report import Report as _Report
25
24
 
26
25
  color = _Color()
@@ -205,7 +204,7 @@ class Failure(_t.NamedTuple):
205
204
  report: _Report
206
205
 
207
206
 
208
- class Failures(_MutableSequence[Failure]):
207
+ class Failures(_t.List[Failure]):
209
208
  """Sequence of failed functions."""
210
209
 
211
210
 
@@ -2,7 +2,7 @@
2
2
  docsig._function
3
3
  ================
4
4
  """
5
- from __future__ import annotations
5
+ from __future__ import annotations as _
6
6
 
7
7
  import re as _re
8
8
  import textwrap as _textwrap
@@ -75,7 +75,7 @@ class Param(_t.NamedTuple):
75
75
  return str(self.name).startswith("_")
76
76
 
77
77
 
78
- class _Matches(_MutableSequence[Param]):
78
+ class _Matches(_t.List[Param]):
79
79
  _pattern = _re.compile(":(.*?):")
80
80
  _normalize = {KEYWORD: KEY}
81
81
 
@@ -6,6 +6,7 @@ Contains package entry point.
6
6
  """
7
7
  from ._config import Parser as _Parser
8
8
  from ._core import docsig as _docsig
9
+ from ._core import pretty_print_error as _pretty_print_error
9
10
 
10
11
 
11
12
  def main() -> int:
@@ -16,6 +17,7 @@ def main() -> int:
16
17
  :return: Exit status for whether test failed or not.
17
18
  """
18
19
  parser = _Parser()
20
+ _pretty_print_error()
19
21
  return _docsig(
20
22
  *parser.args.path,
21
23
  string=parser.args.string,
@@ -2,21 +2,19 @@
2
2
  docsig._module
3
3
  ==============
4
4
  """
5
- from __future__ import annotations
5
+ from __future__ import annotations as _
6
6
 
7
+ import typing as _t
7
8
  from pathlib import Path as _Path
8
9
 
9
10
  import astroid as _ast
10
11
 
11
12
  from ._disable import Disabled as _Disabled
12
13
  from ._function import Function as _Function
13
- from ._objects import MutableSequence as _MutableSequence
14
14
  from ._utils import isprotected as _isprotected
15
15
 
16
16
 
17
- class Parent( # pylint: disable=too-many-arguments
18
- _MutableSequence[_Function]
19
- ):
17
+ class Parent(_t.List[_Function]):
20
18
  """Represents an object that contains functions or methods.
21
19
 
22
20
  :param node: Parent's abstract syntax tree.
@@ -26,7 +24,7 @@ class Parent( # pylint: disable=too-many-arguments
26
24
  :param ignore_kwargs: Ignore kwargs prefixed with two asterisks.
27
25
  """
28
26
 
29
- def __init__(
27
+ def __init__( # pylint: disable=too-many-arguments
30
28
  self,
31
29
  node: _ast.Module | _ast.ClassDef,
32
30
  disabled: _Disabled,
@@ -37,7 +35,6 @@ class Parent( # pylint: disable=too-many-arguments
37
35
  super().__init__()
38
36
  self._name = node.name
39
37
  self._path = f"{path}:" if path is not None else ""
40
- self._directives = disabled
41
38
  overloads = []
42
39
  returns = None
43
40
  for subnode in node.body:
@@ -54,11 +51,15 @@ class Parent( # pylint: disable=too-many-arguments
54
51
  else:
55
52
  if func.name in overloads:
56
53
  subnode.returns = returns
57
- func = _Function(
58
- subnode,
59
- disabled.get(subnode.lineno, []),
60
- ignore_args,
61
- ignore_kwargs,
54
+ # noinspection PyProtectedMember
55
+ func._signature._rettype = (
56
+ returns
57
+ if isinstance(returns, str)
58
+ else func._signature._get_rettype(returns)
59
+ )
60
+ # noinspection PyProtectedMember
61
+ func._signature._returns = (
62
+ str(func._signature._rettype) != "None"
62
63
  )
63
64
 
64
65
  self.append(func)
@@ -74,17 +75,18 @@ class Parent( # pylint: disable=too-many-arguments
74
75
  return _isprotected(self._name)
75
76
 
76
77
 
77
- class _Module(_MutableSequence[Parent]):
78
- def __init__(
78
+ class _Module(_t.List[Parent]):
79
+ def __init__( # pylint: disable=too-many-arguments
79
80
  self,
80
81
  string: str,
82
+ disable: list[str],
81
83
  path: _Path | None = None,
82
84
  ignore_args: bool = False,
83
85
  ignore_kwargs: bool = False,
84
86
  ) -> None:
85
87
  super().__init__()
86
88
  ast = _ast.parse(string)
87
- disabled = _Disabled(string)
89
+ disabled = _Disabled(string, disable)
88
90
  self.append(Parent(ast, disabled, path, ignore_args, ignore_kwargs))
89
91
  for subnode in ast.body:
90
92
  if isinstance(subnode, _ast.ClassDef):
@@ -93,7 +95,7 @@ class _Module(_MutableSequence[Parent]):
93
95
  )
94
96
 
95
97
 
96
- class Modules(_MutableSequence[_Module]):
98
+ class Modules(_t.List[_Module]):
97
99
  """Sequence of ``Module`` objects parsed from Python modules or str.
98
100
 
99
101
  Recursively collect Python files from within all dirs that exist
@@ -102,6 +104,7 @@ class Modules(_MutableSequence[_Module]):
102
104
  If string is provided, ignore paths.
103
105
 
104
106
  :param paths: Path(s) to parse ``Module``(s) from.
107
+ :param disable: List of checks to disable.
105
108
  :param string: String to parse if provided.
106
109
  :param ignore_args: Ignore args prefixed with an asterisk.
107
110
  :param ignore_kwargs: Ignore kwargs prefixed with two asterisks.
@@ -110,17 +113,20 @@ class Modules(_MutableSequence[_Module]):
110
113
  def __init__(
111
114
  self,
112
115
  *paths: _Path,
116
+ disable: list[str],
113
117
  string: str | None = None,
114
118
  ignore_args: bool = False,
115
119
  ignore_kwargs: bool = False,
116
120
  ) -> None:
117
121
  super().__init__()
122
+ self._disable = disable
118
123
  self._ignore_args = ignore_args
119
124
  self._ignore_kwargs = ignore_kwargs
120
125
  if string is not None:
121
126
  self.append(
122
127
  _Module(
123
128
  string,
129
+ disable,
124
130
  ignore_args=ignore_args,
125
131
  ignore_kwargs=ignore_kwargs,
126
132
  )
@@ -130,10 +136,14 @@ class Modules(_MutableSequence[_Module]):
130
136
  self._populate(path)
131
137
 
132
138
  def _populate(self, root: _Path) -> None:
139
+ if not root.exists():
140
+ raise FileNotFoundError(root)
141
+
133
142
  if root.is_file() and root.name.endswith(".py"):
134
143
  self.append(
135
144
  _Module(
136
145
  root.read_text(),
146
+ self._disable,
137
147
  root,
138
148
  self._ignore_args,
139
149
  self._ignore_kwargs,
@@ -2,7 +2,7 @@
2
2
  docsig._objects
3
3
  ===============
4
4
  """
5
- from __future__ import annotations
5
+ from __future__ import annotations as _
6
6
 
7
7
  import typing as _t
8
8
 
@@ -2,7 +2,7 @@
2
2
  docsig._report
3
3
  ==============
4
4
  """
5
- from __future__ import annotations
5
+ from __future__ import annotations as _
6
6
 
7
7
  from . import messages as _messages
8
8
  from ._function import RETURN as _RETURN
@@ -2,7 +2,7 @@
2
2
  docsig._utils
3
3
  =============
4
4
  """
5
- from __future__ import annotations
5
+ from __future__ import annotations as _
6
6
 
7
7
  from difflib import SequenceMatcher as _SequenceMatcher
8
8
 
@@ -7,4 +7,4 @@ Contains the version of this package.
7
7
  Allows for access to the version internally without cyclic imports
8
8
  caused by accessing it through __init__.
9
9
  """
10
- __version__ = "0.36.0"
10
+ __version__ = "0.37.0"
@@ -70,7 +70,7 @@ maintainers = [
70
70
  name = "docsig"
71
71
  readme = "README.rst"
72
72
  repository = "https://github.com/jshwi/docsig"
73
- version = "0.36.0"
73
+ version = "0.37.0"
74
74
 
75
75
  [tool.poetry.dependencies]
76
76
  Pygments = "^2.13.0"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes