duty 1.6.0__py3-none-any.whl → 1.6.2__py3-none-any.whl
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.
- duty/__init__.py +49 -2
- duty/__main__.py +1 -1
- duty/_internal/__init__.py +0 -0
- duty/_internal/callables/__init__.py +34 -0
- duty/{callables → _internal/callables}/_io.py +2 -0
- duty/_internal/callables/autoflake.py +132 -0
- duty/_internal/callables/black.py +176 -0
- duty/_internal/callables/blacken_docs.py +92 -0
- duty/_internal/callables/build.py +76 -0
- duty/_internal/callables/coverage.py +716 -0
- duty/_internal/callables/flake8.py +222 -0
- duty/_internal/callables/git_changelog.py +178 -0
- duty/_internal/callables/griffe.py +227 -0
- duty/_internal/callables/interrogate.py +152 -0
- duty/_internal/callables/isort.py +573 -0
- duty/_internal/callables/mkdocs.py +256 -0
- duty/_internal/callables/mypy.py +496 -0
- duty/_internal/callables/pytest.py +475 -0
- duty/_internal/callables/ruff.py +399 -0
- duty/_internal/callables/safety.py +82 -0
- duty/_internal/callables/ssort.py +38 -0
- duty/_internal/callables/twine.py +284 -0
- duty/_internal/cli.py +322 -0
- duty/_internal/collection.py +246 -0
- duty/_internal/context.py +111 -0
- duty/{debug.py → _internal/debug.py} +13 -15
- duty/_internal/decorator.py +111 -0
- duty/_internal/exceptions.py +12 -0
- duty/_internal/tools/__init__.py +41 -0
- duty/{tools → _internal/tools}/_autoflake.py +8 -4
- duty/{tools → _internal/tools}/_base.py +15 -2
- duty/{tools → _internal/tools}/_black.py +5 -5
- duty/{tools → _internal/tools}/_blacken_docs.py +10 -5
- duty/{tools → _internal/tools}/_build.py +4 -4
- duty/{tools → _internal/tools}/_coverage.py +8 -4
- duty/{tools → _internal/tools}/_flake8.py +10 -12
- duty/{tools → _internal/tools}/_git_changelog.py +8 -4
- duty/{tools → _internal/tools}/_griffe.py +8 -4
- duty/{tools → _internal/tools}/_interrogate.py +4 -4
- duty/{tools → _internal/tools}/_isort.py +8 -6
- duty/{tools → _internal/tools}/_mkdocs.py +8 -4
- duty/{tools → _internal/tools}/_mypy.py +5 -5
- duty/{tools → _internal/tools}/_pytest.py +8 -4
- duty/{tools → _internal/tools}/_ruff.py +11 -5
- duty/{tools → _internal/tools}/_safety.py +13 -8
- duty/{tools → _internal/tools}/_ssort.py +10 -6
- duty/{tools → _internal/tools}/_twine.py +11 -5
- duty/_internal/tools/_yore.py +96 -0
- duty/_internal/validation.py +266 -0
- duty/callables/__init__.py +4 -4
- duty/callables/autoflake.py +11 -126
- duty/callables/black.py +12 -171
- duty/callables/blacken_docs.py +11 -86
- duty/callables/build.py +12 -71
- duty/callables/coverage.py +12 -711
- duty/callables/flake8.py +12 -217
- duty/callables/git_changelog.py +12 -173
- duty/callables/griffe.py +12 -222
- duty/callables/interrogate.py +12 -147
- duty/callables/isort.py +12 -568
- duty/callables/mkdocs.py +12 -251
- duty/callables/mypy.py +11 -490
- duty/callables/pytest.py +12 -470
- duty/callables/ruff.py +12 -394
- duty/callables/safety.py +11 -76
- duty/callables/ssort.py +12 -33
- duty/callables/twine.py +12 -279
- duty/cli.py +10 -316
- duty/collection.py +12 -228
- duty/context.py +12 -107
- duty/decorator.py +12 -108
- duty/exceptions.py +13 -10
- duty/tools.py +63 -0
- duty/validation.py +12 -262
- {duty-1.6.0.dist-info → duty-1.6.2.dist-info}/METADATA +5 -4
- duty-1.6.2.dist-info/RECORD +81 -0
- {duty-1.6.0.dist-info → duty-1.6.2.dist-info}/WHEEL +1 -1
- {duty-1.6.0.dist-info → duty-1.6.2.dist-info}/entry_points.txt +1 -1
- duty/tools/__init__.py +0 -50
- duty/tools/_yore.py +0 -54
- duty-1.6.0.dist-info/RECORD +0 -55
- {duty-1.6.0.dist-info → duty-1.6.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from duty._internal.tools._base import Tool
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class yore(Tool): # noqa: N801
|
|
7
|
+
"""Call [Yore](https://github.com/pawamoy/yore)."""
|
|
8
|
+
|
|
9
|
+
cli_name = "yore"
|
|
10
|
+
"""The name of the executable on PATH."""
|
|
11
|
+
|
|
12
|
+
@classmethod
|
|
13
|
+
def check(
|
|
14
|
+
cls,
|
|
15
|
+
*paths: str,
|
|
16
|
+
bump: str | None = None,
|
|
17
|
+
eol_within: str | None = None,
|
|
18
|
+
bol_within: str | None = None,
|
|
19
|
+
) -> yore:
|
|
20
|
+
"""Check Yore comments against Python EOL dates or the provided next version of your project.
|
|
21
|
+
|
|
22
|
+
Parameters:
|
|
23
|
+
paths: Path to files or directories to check.
|
|
24
|
+
bump: The next version of your project.
|
|
25
|
+
eol_within: The time delta to start checking before the End of Life of a Python version.
|
|
26
|
+
It is provided in a human-readable format, like `2 weeks` or `1 month`.
|
|
27
|
+
Spaces are optional, and the unit can be shortened to a single letter:
|
|
28
|
+
`d` for days, `w` for weeks, `m` for months, and `y` for years.
|
|
29
|
+
bol_within: The time delta to start checking before the Beginning of Life of a Python version.
|
|
30
|
+
It is provided in a human-readable format, like `2 weeks` or `1 month`.
|
|
31
|
+
Spaces are optional, and the unit can be shortened to a single letter:
|
|
32
|
+
`d` for days, `w` for weeks, `m` for months, and `y` for years.
|
|
33
|
+
"""
|
|
34
|
+
cli_args = ["check", *paths]
|
|
35
|
+
|
|
36
|
+
if bump:
|
|
37
|
+
cli_args.append("--bump")
|
|
38
|
+
cli_args.append(bump)
|
|
39
|
+
|
|
40
|
+
if eol_within:
|
|
41
|
+
cli_args.append("--eol-within")
|
|
42
|
+
cli_args.append(eol_within)
|
|
43
|
+
|
|
44
|
+
if bol_within:
|
|
45
|
+
cli_args.append("--bol-within")
|
|
46
|
+
cli_args.append(bol_within)
|
|
47
|
+
|
|
48
|
+
return cls(cli_args)
|
|
49
|
+
|
|
50
|
+
@classmethod
|
|
51
|
+
def fix(
|
|
52
|
+
cls,
|
|
53
|
+
*paths: str,
|
|
54
|
+
bump: str | None = None,
|
|
55
|
+
eol_within: str | None = None,
|
|
56
|
+
bol_within: str | None = None,
|
|
57
|
+
) -> yore:
|
|
58
|
+
"""Fix your code by transforming it according to the Yore comments.
|
|
59
|
+
|
|
60
|
+
Parameters:
|
|
61
|
+
paths: Path to files or directories to fix.
|
|
62
|
+
bump: The next version of your project.
|
|
63
|
+
eol_within: The time delta to start fixing before the End of Life of a Python version.
|
|
64
|
+
It is provided in a human-readable format, like `2 weeks` or `1 month`.
|
|
65
|
+
Spaces are optional, and the unit can be shortened to a single letter:
|
|
66
|
+
`d` for days, `w` for weeks, `m` for months, and `y` for years.
|
|
67
|
+
bol_within: The time delta to start fixing before the Beginning of Life of a Python version.
|
|
68
|
+
It is provided in a human-readable format, like `2 weeks` or `1 month`.
|
|
69
|
+
Spaces are optional, and the unit can be shortened to a single letter:
|
|
70
|
+
`d` for days, `w` for weeks, `m` for months, and `y` for years.
|
|
71
|
+
"""
|
|
72
|
+
cli_args = ["fix", *paths]
|
|
73
|
+
|
|
74
|
+
if bump:
|
|
75
|
+
cli_args.append("--bump")
|
|
76
|
+
cli_args.append(bump)
|
|
77
|
+
|
|
78
|
+
if eol_within:
|
|
79
|
+
cli_args.append("--eol-within")
|
|
80
|
+
cli_args.append(eol_within)
|
|
81
|
+
|
|
82
|
+
if bol_within:
|
|
83
|
+
cli_args.append("--bol-within")
|
|
84
|
+
cli_args.append(bol_within)
|
|
85
|
+
|
|
86
|
+
return cls(cli_args)
|
|
87
|
+
|
|
88
|
+
def __call__(self) -> int:
|
|
89
|
+
"""Run the command.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
The exit code of the command.
|
|
93
|
+
"""
|
|
94
|
+
from yore import main as run_yore # noqa: PLC0415
|
|
95
|
+
|
|
96
|
+
return run_yore(self.cli_args)
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# This module contains logic used to validate parameters passed to duties.
|
|
2
|
+
#
|
|
3
|
+
# We validate the parameters before running the duties,
|
|
4
|
+
# effectively checking all CLI arguments and failing early
|
|
5
|
+
# if they are incorrect.
|
|
6
|
+
|
|
7
|
+
from __future__ import annotations
|
|
8
|
+
|
|
9
|
+
import sys
|
|
10
|
+
import textwrap
|
|
11
|
+
from contextlib import suppress
|
|
12
|
+
from functools import cached_property, partial
|
|
13
|
+
from inspect import Parameter, Signature, signature
|
|
14
|
+
from typing import TYPE_CHECKING, Any, Callable, ForwardRef, Union, get_args, get_origin
|
|
15
|
+
|
|
16
|
+
if TYPE_CHECKING:
|
|
17
|
+
from collections.abc import Sequence
|
|
18
|
+
|
|
19
|
+
# YORE: EOL 3.9: Replace block with lines 6-13.
|
|
20
|
+
if sys.version_info < (3, 10):
|
|
21
|
+
from eval_type_backport import eval_type_backport as _eval_type
|
|
22
|
+
|
|
23
|
+
_union_types = (Union,)
|
|
24
|
+
else:
|
|
25
|
+
from types import UnionType
|
|
26
|
+
from typing import _eval_type # type: ignore[attr-defined]
|
|
27
|
+
|
|
28
|
+
if sys.version_info >= (3, 13):
|
|
29
|
+
_eval_type = partial(_eval_type, type_params=None)
|
|
30
|
+
_union_types = (Union, UnionType)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def to_bool(value: str) -> bool:
|
|
34
|
+
"""Convert a string to a boolean.
|
|
35
|
+
|
|
36
|
+
Parameters:
|
|
37
|
+
value: The string to convert.
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
True or False.
|
|
41
|
+
"""
|
|
42
|
+
return value.lower() not in {"", "0", "no", "n", "false", "off"}
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def cast_arg(arg: Any, annotation: Any) -> Any:
|
|
46
|
+
"""Cast an argument using a type annotation.
|
|
47
|
+
|
|
48
|
+
Parameters:
|
|
49
|
+
arg: The argument value.
|
|
50
|
+
annotation: A type annotation.
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
The cast value.
|
|
54
|
+
"""
|
|
55
|
+
if annotation is Parameter.empty:
|
|
56
|
+
return arg
|
|
57
|
+
if annotation is bool:
|
|
58
|
+
annotation = to_bool
|
|
59
|
+
if get_origin(annotation) in _union_types:
|
|
60
|
+
for sub_annotation in get_args(annotation):
|
|
61
|
+
if sub_annotation is type(None):
|
|
62
|
+
continue
|
|
63
|
+
with suppress(Exception):
|
|
64
|
+
return cast_arg(arg, sub_annotation)
|
|
65
|
+
try:
|
|
66
|
+
return annotation(arg)
|
|
67
|
+
except Exception: # noqa: BLE001
|
|
68
|
+
return arg
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class ParamsCaster:
|
|
72
|
+
"""A helper class to cast parameters based on a function's signature annotations."""
|
|
73
|
+
|
|
74
|
+
def __init__(self, signature: Signature) -> None:
|
|
75
|
+
"""Initialize the object.
|
|
76
|
+
|
|
77
|
+
Parameters:
|
|
78
|
+
signature: The signature to use to cast arguments.
|
|
79
|
+
"""
|
|
80
|
+
self.params_dict = signature.parameters
|
|
81
|
+
"""A dictionary of parameters, indexed by their name."""
|
|
82
|
+
self.params_list = list(self.params_dict.values())
|
|
83
|
+
"""A list of parameters, in the order they appear in the signature."""
|
|
84
|
+
|
|
85
|
+
@cached_property
|
|
86
|
+
def var_positional_position(self) -> int:
|
|
87
|
+
"""Give the position of the variable positional parameter in the signature.
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
The position of the variable positional parameter.
|
|
91
|
+
"""
|
|
92
|
+
for pos, param in enumerate(self.params_list):
|
|
93
|
+
if param.kind is Parameter.VAR_POSITIONAL:
|
|
94
|
+
return pos
|
|
95
|
+
return -1
|
|
96
|
+
|
|
97
|
+
@cached_property
|
|
98
|
+
def has_var_positional(self) -> bool:
|
|
99
|
+
"""Tell if there is a variable positional parameter.
|
|
100
|
+
|
|
101
|
+
Returns:
|
|
102
|
+
True or False.
|
|
103
|
+
"""
|
|
104
|
+
return self.var_positional_position >= 0
|
|
105
|
+
|
|
106
|
+
@cached_property
|
|
107
|
+
def var_positional_annotation(self) -> Any:
|
|
108
|
+
"""Give the variable positional parameter (`*args`) annotation if any.
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
The variable positional parameter annotation.
|
|
112
|
+
"""
|
|
113
|
+
return self.params_list[self.var_positional_position].annotation
|
|
114
|
+
|
|
115
|
+
@cached_property
|
|
116
|
+
def var_keyword_annotation(self) -> Any:
|
|
117
|
+
"""Give the variable keyword parameter (`**kwargs`) annotation if any.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
The variable keyword parameter annotation.
|
|
121
|
+
"""
|
|
122
|
+
for param in self.params_list:
|
|
123
|
+
if param.kind is Parameter.VAR_KEYWORD:
|
|
124
|
+
return param.annotation
|
|
125
|
+
return Parameter.empty
|
|
126
|
+
|
|
127
|
+
def annotation_at_pos(self, pos: int) -> Any:
|
|
128
|
+
"""Give the annotation for the parameter at the given position.
|
|
129
|
+
|
|
130
|
+
Parameters:
|
|
131
|
+
pos: The position of the parameter.
|
|
132
|
+
|
|
133
|
+
Returns:
|
|
134
|
+
The positional parameter annotation.
|
|
135
|
+
"""
|
|
136
|
+
return self.params_list[pos].annotation
|
|
137
|
+
|
|
138
|
+
def eaten_by_var_positional(self, pos: int) -> bool:
|
|
139
|
+
"""Tell if the parameter at this position is eaten by a variable positional parameter.
|
|
140
|
+
|
|
141
|
+
Parameters:
|
|
142
|
+
pos: The position of the parameter.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Whether the parameter is eaten.
|
|
146
|
+
"""
|
|
147
|
+
return self.has_var_positional and pos >= self.var_positional_position
|
|
148
|
+
|
|
149
|
+
def cast_posarg(self, pos: int, arg: Any) -> Any:
|
|
150
|
+
"""Cast a positional argument.
|
|
151
|
+
|
|
152
|
+
Parameters:
|
|
153
|
+
pos: The position of the argument in the signature.
|
|
154
|
+
arg: The argument value.
|
|
155
|
+
|
|
156
|
+
Returns:
|
|
157
|
+
The cast value.
|
|
158
|
+
"""
|
|
159
|
+
if self.eaten_by_var_positional(pos):
|
|
160
|
+
return cast_arg(arg, self.var_positional_annotation)
|
|
161
|
+
return cast_arg(arg, self.annotation_at_pos(pos))
|
|
162
|
+
|
|
163
|
+
def cast_kwarg(self, name: str, value: Any) -> Any:
|
|
164
|
+
"""Cast a keyword argument.
|
|
165
|
+
|
|
166
|
+
Parameters:
|
|
167
|
+
name: The name of the argument in the signature.
|
|
168
|
+
value: The argument value.
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
The cast value.
|
|
172
|
+
"""
|
|
173
|
+
if name in self.params_dict:
|
|
174
|
+
return cast_arg(value, self.params_dict[name].annotation)
|
|
175
|
+
return cast_arg(value, self.var_keyword_annotation)
|
|
176
|
+
|
|
177
|
+
def cast(self, *args: Any, **kwargs: Any) -> tuple[Sequence, dict[str, Any]]:
|
|
178
|
+
"""Cast all positional and keyword arguments.
|
|
179
|
+
|
|
180
|
+
Parameters:
|
|
181
|
+
*args: The positional arguments.
|
|
182
|
+
**kwargs: The keyword arguments.
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
The cast arguments.
|
|
186
|
+
"""
|
|
187
|
+
positional = tuple(self.cast_posarg(pos, arg) for pos, arg in enumerate(args))
|
|
188
|
+
keyword = {name: self.cast_kwarg(name, value) for name, value in kwargs.items()}
|
|
189
|
+
return positional, keyword
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
def _get_params_caster(func: Callable, *args: Any, **kwargs: Any) -> ParamsCaster:
|
|
193
|
+
duties_module = sys.modules[func.__module__]
|
|
194
|
+
exec_globals = dict(duties_module.__dict__)
|
|
195
|
+
eval_str = False
|
|
196
|
+
for name in list(exec_globals.keys()):
|
|
197
|
+
if exec_globals[name] is annotations:
|
|
198
|
+
eval_str = True
|
|
199
|
+
del exec_globals[name]
|
|
200
|
+
break
|
|
201
|
+
exec_globals["__context_above"] = {}
|
|
202
|
+
|
|
203
|
+
# Don't keep first parameter: context.
|
|
204
|
+
params = list(signature(func).parameters.values())[1:]
|
|
205
|
+
params_no_types = [Parameter(param.name, param.kind, default=param.default) for param in params]
|
|
206
|
+
code_sig = Signature(parameters=params_no_types)
|
|
207
|
+
if eval_str:
|
|
208
|
+
params_types = [
|
|
209
|
+
Parameter(
|
|
210
|
+
param.name,
|
|
211
|
+
param.kind,
|
|
212
|
+
default=param.default,
|
|
213
|
+
annotation=(
|
|
214
|
+
_eval_type(
|
|
215
|
+
ForwardRef(param.annotation) if isinstance(param.annotation, str) else param.annotation,
|
|
216
|
+
exec_globals,
|
|
217
|
+
{},
|
|
218
|
+
)
|
|
219
|
+
if param.annotation is not Parameter.empty
|
|
220
|
+
else type(param.default)
|
|
221
|
+
),
|
|
222
|
+
)
|
|
223
|
+
for param in params
|
|
224
|
+
]
|
|
225
|
+
else:
|
|
226
|
+
params_types = params
|
|
227
|
+
cast_sig = Signature(parameters=params_types)
|
|
228
|
+
|
|
229
|
+
code = f"""
|
|
230
|
+
import inspect
|
|
231
|
+
def {func.__name__}{code_sig}: ...
|
|
232
|
+
__context_above['func'] = {func.__name__}
|
|
233
|
+
"""
|
|
234
|
+
|
|
235
|
+
exec(textwrap.dedent(code), exec_globals) # noqa: S102
|
|
236
|
+
func = exec_globals["__context_above"]["func"]
|
|
237
|
+
|
|
238
|
+
# Trigger TypeError early.
|
|
239
|
+
func(*args, **kwargs)
|
|
240
|
+
|
|
241
|
+
return ParamsCaster(cast_sig)
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def validate(
|
|
245
|
+
func: Callable,
|
|
246
|
+
*args: Any,
|
|
247
|
+
**kwargs: Any,
|
|
248
|
+
) -> tuple[Sequence, dict[str, Any]]:
|
|
249
|
+
"""Validate positional and keyword arguments against a function.
|
|
250
|
+
|
|
251
|
+
First we clone the function, removing the first parameter (the context)
|
|
252
|
+
and the body, to fail early with a `TypeError` if the arguments
|
|
253
|
+
are incorrect: not enough, too much, in the wrong order, etc.
|
|
254
|
+
|
|
255
|
+
Then we cast all the arguments using the function's signature
|
|
256
|
+
and we return them.
|
|
257
|
+
|
|
258
|
+
Parameters:
|
|
259
|
+
func: The function to copy.
|
|
260
|
+
*args: The positional arguments.
|
|
261
|
+
**kwargs: The keyword arguments.
|
|
262
|
+
|
|
263
|
+
Returns:
|
|
264
|
+
The casted arguments.
|
|
265
|
+
"""
|
|
266
|
+
return _get_params_caster(func, *args, **kwargs).cast(*args, **kwargs)
|
duty/callables/__init__.py
CHANGED
|
@@ -3,13 +3,15 @@
|
|
|
3
3
|
These callables are **deprecated** in favor of our new [tools][duty.tools].
|
|
4
4
|
"""
|
|
5
5
|
|
|
6
|
+
# YORE: Bump 2: Remove file.
|
|
7
|
+
|
|
6
8
|
from __future__ import annotations
|
|
7
9
|
|
|
8
10
|
import warnings
|
|
9
11
|
|
|
10
|
-
from failprint
|
|
12
|
+
from failprint import lazy # noqa: F401
|
|
11
13
|
|
|
12
|
-
from duty.callables import (
|
|
14
|
+
from duty._internal.callables import (
|
|
13
15
|
autoflake, # noqa: F401
|
|
14
16
|
black, # noqa: F401
|
|
15
17
|
blacken_docs, # noqa: F401
|
|
@@ -29,8 +31,6 @@ from duty.callables import (
|
|
|
29
31
|
twine, # noqa: F401
|
|
30
32
|
)
|
|
31
33
|
|
|
32
|
-
__all__ = ["lazy"]
|
|
33
|
-
|
|
34
34
|
warnings.warn(
|
|
35
35
|
"Callables are deprecated in favor of our new `duty.tools`. "
|
|
36
36
|
"They are easier to use and provide more functionality "
|
duty/callables/autoflake.py
CHANGED
|
@@ -1,132 +1,17 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Deprecated. Use [`duty.tools.autoflake`][] instead."""
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
# YORE: Bump 2: Remove file.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import warnings
|
|
6
|
+
from typing import Any
|
|
6
7
|
|
|
7
|
-
from duty.callables import
|
|
8
|
+
from duty._internal.callables import autoflake as _autoflake
|
|
8
9
|
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
check_diff: bool | None = None,
|
|
16
|
-
imports: list[str] | None = None,
|
|
17
|
-
remove_all_unused_imports: bool | None = None,
|
|
18
|
-
recursive: bool | None = None,
|
|
19
|
-
jobs: int | None = None,
|
|
20
|
-
exclude: list[str] | None = None,
|
|
21
|
-
expand_star_imports: bool | None = None,
|
|
22
|
-
ignore_init_module_imports: bool | None = None,
|
|
23
|
-
remove_duplicate_keys: bool | None = None,
|
|
24
|
-
remove_unused_variables: bool | None = None,
|
|
25
|
-
remove_rhs_for_unused_variables: bool | None = None,
|
|
26
|
-
ignore_pass_statements: bool | None = None,
|
|
27
|
-
ignore_pass_after_docstring: bool | None = None,
|
|
28
|
-
quiet: bool | None = None,
|
|
29
|
-
verbose: bool | None = None,
|
|
30
|
-
stdin_display_name: str | None = None,
|
|
31
|
-
in_place: bool | None = None,
|
|
32
|
-
stdout: bool | None = None,
|
|
33
|
-
) -> int:
|
|
34
|
-
r"""Run `autoflake`.
|
|
35
|
-
|
|
36
|
-
Parameters:
|
|
37
|
-
*files: Files to format.
|
|
38
|
-
config: Explicitly set the config file instead of auto determining based on file location.
|
|
39
|
-
check: Return error code if changes are needed.
|
|
40
|
-
check_diff: Return error code if changes are needed, also display file diffs.
|
|
41
|
-
imports: By default, only unused standard library imports are removed; specify a comma-separated list of additional modules/packages.
|
|
42
|
-
remove_all_unused_imports: Remove all unused imports (not just those from the standard library).
|
|
43
|
-
recursive: Drill down directories recursively.
|
|
44
|
-
jobs: Number of parallel jobs; match CPU count if value is 0 (default: 0).
|
|
45
|
-
exclude: Exclude file/directory names that match these comma-separated globs.
|
|
46
|
-
expand_star_imports: Expand wildcard star imports with undefined names; this only triggers if there is only one star import in the file; this is skipped if there are any uses of `__all__` or `del` in the file.
|
|
47
|
-
ignore_init_module_imports: Exclude `__init__.py` when removing unused imports.
|
|
48
|
-
remove_duplicate_keys: Remove all duplicate keys in objects.
|
|
49
|
-
remove_unused_variables: Remove unused variables.
|
|
50
|
-
remove_rhs_for_unused_variables: Remove RHS of statements when removing unused variables (unsafe).
|
|
51
|
-
ignore_pass_statements: Ignore all pass statements.
|
|
52
|
-
ignore_pass_after_docstring: Ignore pass statements after a newline ending on `\"\"\"`.
|
|
53
|
-
quiet: Suppress output if there are no issues.
|
|
54
|
-
verbose: Print more verbose logs (you can repeat `-v` to make it more verbose).
|
|
55
|
-
stdin_display_name: The name used when processing input from stdin.
|
|
56
|
-
in_place: Make changes to files instead of printing diffs.
|
|
57
|
-
stdout: Print changed text to stdout. defaults to true when formatting stdin, or to false otherwise.
|
|
58
|
-
"""
|
|
59
|
-
from autoflake import _main as autoflake
|
|
60
|
-
|
|
61
|
-
cli_args = list(files)
|
|
62
|
-
|
|
63
|
-
if check:
|
|
64
|
-
cli_args.append("--check")
|
|
65
|
-
|
|
66
|
-
if check_diff:
|
|
67
|
-
cli_args.append("--check-diff")
|
|
68
|
-
|
|
69
|
-
if imports:
|
|
70
|
-
cli_args.append("--imports")
|
|
71
|
-
cli_args.append(",".join(imports))
|
|
72
|
-
|
|
73
|
-
if remove_all_unused_imports:
|
|
74
|
-
cli_args.append("--remove-all-unused-imports")
|
|
75
|
-
|
|
76
|
-
if recursive:
|
|
77
|
-
cli_args.append("--recursive")
|
|
78
|
-
|
|
79
|
-
if jobs:
|
|
80
|
-
cli_args.append("--jobs")
|
|
81
|
-
cli_args.append(str(jobs))
|
|
82
|
-
|
|
83
|
-
if exclude:
|
|
84
|
-
cli_args.append("--exclude")
|
|
85
|
-
cli_args.append(",".join(exclude))
|
|
86
|
-
|
|
87
|
-
if expand_star_imports:
|
|
88
|
-
cli_args.append("--expand-star-imports")
|
|
89
|
-
|
|
90
|
-
if ignore_init_module_imports:
|
|
91
|
-
cli_args.append("--ignore-init-module-imports")
|
|
92
|
-
|
|
93
|
-
if remove_duplicate_keys:
|
|
94
|
-
cli_args.append("--remove-duplicate-keys")
|
|
95
|
-
|
|
96
|
-
if remove_unused_variables:
|
|
97
|
-
cli_args.append("--remove-unused-variables")
|
|
98
|
-
|
|
99
|
-
if remove_rhs_for_unused_variables:
|
|
100
|
-
cli_args.append("remove-rhs-for-unused-variables")
|
|
101
|
-
|
|
102
|
-
if ignore_pass_statements:
|
|
103
|
-
cli_args.append("--ignore-pass-statements")
|
|
104
|
-
|
|
105
|
-
if ignore_pass_after_docstring:
|
|
106
|
-
cli_args.append("--ignore-pass-after-docstring")
|
|
107
|
-
|
|
108
|
-
if quiet:
|
|
109
|
-
cli_args.append("--quiet")
|
|
110
|
-
|
|
111
|
-
if verbose:
|
|
112
|
-
cli_args.append("--verbose")
|
|
113
|
-
|
|
114
|
-
if stdin_display_name:
|
|
115
|
-
cli_args.append("--stdin-display-name")
|
|
116
|
-
cli_args.append(stdin_display_name)
|
|
117
|
-
|
|
118
|
-
if config:
|
|
119
|
-
cli_args.append("--config")
|
|
120
|
-
cli_args.append(config)
|
|
121
|
-
|
|
122
|
-
if in_place:
|
|
123
|
-
cli_args.append("--in-place")
|
|
124
|
-
|
|
125
|
-
if stdout:
|
|
126
|
-
cli_args.append("--stdout")
|
|
127
|
-
|
|
128
|
-
return autoflake(
|
|
129
|
-
cli_args,
|
|
130
|
-
standard_out=_io._LazyStdout(),
|
|
131
|
-
standard_error=_io._LazyStderr(),
|
|
11
|
+
def __getattr__(name: str) -> Any:
|
|
12
|
+
warnings.warn(
|
|
13
|
+
"Callables are deprecated in favor of tools, use `duty.tools.autoflake` instead of `duty.callables.autoflake`.",
|
|
14
|
+
DeprecationWarning,
|
|
15
|
+
stacklevel=2,
|
|
132
16
|
)
|
|
17
|
+
return getattr(_autoflake, name)
|