crackerjack 0.14.4__tar.gz → 0.14.6__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.
- {crackerjack-0.14.4 → crackerjack-0.14.6}/PKG-INFO +3 -3
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.pre-commit-config.yaml +3 -3
- crackerjack-0.14.6/crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/crackerjack.py +126 -60
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/pyproject.toml +7 -5
- {crackerjack-0.14.4 → crackerjack-0.14.6}/pyproject.toml +17 -5
- crackerjack-0.14.6/tests/data/docstrings_sample.txt +20 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/tests/test_crackerjack.py +26 -10
- crackerjack-0.14.4/tests/data/docstrings_sample.txt +0 -10
- {crackerjack-0.14.4 → crackerjack-0.14.6}/LICENSE +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/README.md +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.coverage +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.gitignore +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.libcst.codemod.yaml +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.pdm.toml +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.pytest_cache/.gitignore +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.pytest_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.pytest_cache/README.md +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.pytest_cache/v/cache/nodeids +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.pytest_cache/v/cache/stepwise +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/.gitignore +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/__init__.py +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/__main__.py +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/tests/__init__.py +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/tests/data/comments_sample.txt +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/tests/data/expected_comments_sample.txt +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/tests/data/init.py +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.6}/tests/test_main.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: crackerjack
|
3
|
-
Version: 0.14.
|
3
|
+
Version: 0.14.6
|
4
4
|
Summary: Default template for PDM package
|
5
5
|
Keywords: black,ruff,mypy,creosote,refurb
|
6
6
|
Author-Email: lesleslie <les@wedgwoodwebworks.com>
|
@@ -23,12 +23,12 @@ Project-URL: documentation, https://github.com/lesleslie/crackerjack
|
|
23
23
|
Project-URL: repository, https://github.com/lesleslie/crackerjack
|
24
24
|
Requires-Python: >=3.13
|
25
25
|
Requires-Dist: autotyping>=24.9.0
|
26
|
-
Requires-Dist: pre-commit>=4.
|
26
|
+
Requires-Dist: pre-commit>=4.2.0
|
27
27
|
Requires-Dist: pytest>=8.3.5
|
28
28
|
Requires-Dist: pydantic>=2.10.6
|
29
29
|
Requires-Dist: pdm-bump>=0.9.10
|
30
30
|
Requires-Dist: pdm>=2.22.4
|
31
|
-
Requires-Dist: uv>=0.6.
|
31
|
+
Requires-Dist: uv>=0.6.9
|
32
32
|
Requires-Dist: pytest-cov>=6.0.0
|
33
33
|
Requires-Dist: pytest-mock>=3.14.0
|
34
34
|
Requires-Dist: tomli-w>=1.2.0
|
@@ -17,7 +17,7 @@ repos:
|
|
17
17
|
- id: check-added-large-files
|
18
18
|
name: check-added-large-files
|
19
19
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
20
|
-
rev: v0.
|
20
|
+
rev: v0.11.2
|
21
21
|
hooks:
|
22
22
|
- id: ruff-format
|
23
23
|
- id: ruff
|
@@ -65,11 +65,11 @@ repos:
|
|
65
65
|
- id: bandit
|
66
66
|
args: ["-c", "pyproject.toml"]
|
67
67
|
- repo: https://github.com/RobertCraigie/pyright-python
|
68
|
-
rev: v1.1.
|
68
|
+
rev: v1.1.397
|
69
69
|
hooks:
|
70
70
|
- id: pyright
|
71
71
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
72
|
-
rev: v0.
|
72
|
+
rev: v0.11.2
|
73
73
|
hooks:
|
74
74
|
- id: ruff
|
75
75
|
- id: ruff-format
|
Binary file
|
@@ -5,13 +5,13 @@ import subprocess
|
|
5
5
|
import tokenize
|
6
6
|
import typing as t
|
7
7
|
from contextlib import suppress
|
8
|
+
from dataclasses import dataclass, field
|
8
9
|
from pathlib import Path
|
9
10
|
from subprocess import CompletedProcess
|
10
11
|
from subprocess import run as execute
|
11
12
|
from token import STRING
|
12
13
|
from tomllib import loads
|
13
14
|
|
14
|
-
from pydantic import BaseModel
|
15
15
|
from rich.console import Console
|
16
16
|
from tomli_w import dumps
|
17
17
|
|
@@ -20,7 +20,8 @@ interactive_hooks = ("refurb", "bandit", "pyright")
|
|
20
20
|
default_python_version = "3.13"
|
21
21
|
|
22
22
|
|
23
|
-
|
23
|
+
@dataclass
|
24
|
+
class CodeCleaner:
|
24
25
|
console: Console
|
25
26
|
|
26
27
|
def clean_files(self, pkg_dir: Path | None) -> None:
|
@@ -35,20 +36,20 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
|
|
35
36
|
def clean_file(self, file_path: Path) -> None:
|
36
37
|
try:
|
37
38
|
if file_path.resolve() == Path(__file__).resolve():
|
38
|
-
print(f"Skipping cleaning of {file_path} (self file).")
|
39
|
+
self.console.print(f"Skipping cleaning of {file_path} (self file).")
|
39
40
|
return
|
40
41
|
except Exception as e:
|
41
|
-
print(f"Error comparing file paths: {e}")
|
42
|
+
self.console.print(f"Error comparing file paths: {e}")
|
42
43
|
try:
|
43
44
|
code = file_path.read_text()
|
44
45
|
code = self.remove_docstrings(code)
|
45
46
|
code = self.remove_line_comments(code)
|
46
47
|
code = self.remove_extra_whitespace(code)
|
47
48
|
code = self.reformat_code(code)
|
48
|
-
file_path.write_text(code)
|
49
|
-
print(f"Cleaned: {file_path}")
|
49
|
+
file_path.write_text(code) # type: ignore
|
50
|
+
self.console.print(f"Cleaned: {file_path}")
|
50
51
|
except Exception as e:
|
51
|
-
print(f"Error cleaning {file_path}: {e}")
|
52
|
+
self.console.print(f"Error cleaning {file_path}: {e}")
|
52
53
|
|
53
54
|
def remove_line_comments(self, code: str) -> str:
|
54
55
|
new_lines = []
|
@@ -59,38 +60,98 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
|
|
59
60
|
idx = line.find("#")
|
60
61
|
code_part = line[:idx].rstrip()
|
61
62
|
comment_part = line[idx:]
|
62
|
-
if
|
63
|
+
if (
|
64
|
+
"type: ignore" in comment_part
|
65
|
+
or "noqa" in comment_part
|
66
|
+
or "nosec" in comment_part
|
67
|
+
):
|
63
68
|
new_lines.append(line)
|
64
69
|
else:
|
65
70
|
if code_part:
|
66
71
|
new_lines.append(code_part)
|
67
72
|
return "\n".join(new_lines)
|
68
73
|
|
74
|
+
def _is_triple_quoted(self, token_string: str) -> bool:
|
75
|
+
triple_quote_patterns = [
|
76
|
+
('"""', '"""'),
|
77
|
+
("'''", "'''"),
|
78
|
+
('r"""', '"""'),
|
79
|
+
("r'''", "'''"),
|
80
|
+
]
|
81
|
+
return any(
|
82
|
+
token_string.startswith(start) and token_string.endswith(end)
|
83
|
+
for start, end in triple_quote_patterns
|
84
|
+
)
|
85
|
+
|
86
|
+
def _is_module_docstring(
|
87
|
+
self, tokens: list[tokenize.TokenInfo], i: int, indent_level: int
|
88
|
+
) -> bool:
|
89
|
+
if i <= 0 or indent_level != 0:
|
90
|
+
return False
|
91
|
+
preceding_tokens = tokens[:i]
|
92
|
+
return not preceding_tokens
|
93
|
+
|
94
|
+
def _is_function_or_class_docstring(
|
95
|
+
self,
|
96
|
+
tokens: list[tokenize.TokenInfo],
|
97
|
+
i: int,
|
98
|
+
last_token_type: t.Any,
|
99
|
+
last_token_string: str,
|
100
|
+
) -> bool:
|
101
|
+
if last_token_type != tokenize.OP or last_token_string != ":": # nosec B105
|
102
|
+
return False
|
103
|
+
for prev_idx in range(i - 1, max(0, i - 20), -1):
|
104
|
+
prev_token = tokens[prev_idx]
|
105
|
+
if prev_token[1] in ("def", "class") and prev_token[0] == tokenize.NAME:
|
106
|
+
return True
|
107
|
+
elif prev_token[0] == tokenize.DEDENT:
|
108
|
+
break
|
109
|
+
return False
|
110
|
+
|
111
|
+
def _is_variable_docstring(
|
112
|
+
self, tokens: list[tokenize.TokenInfo], i: int, indent_level: int
|
113
|
+
) -> bool:
|
114
|
+
if indent_level <= 0:
|
115
|
+
return False
|
116
|
+
for prev_idx in range(i - 1, max(0, i - 10), -1):
|
117
|
+
if tokens[prev_idx][0]:
|
118
|
+
return True
|
119
|
+
return False
|
120
|
+
|
69
121
|
def remove_docstrings(self, source: str) -> str:
|
70
122
|
try:
|
71
123
|
io_obj = io.StringIO(source)
|
72
|
-
output_tokens = []
|
73
|
-
first_token_stack = [True]
|
74
124
|
tokens = list(tokenize.generate_tokens(io_obj.readline))
|
75
|
-
|
76
|
-
|
125
|
+
result_tokens = []
|
126
|
+
indent_level = 0
|
127
|
+
last_non_ws_token_type = None
|
128
|
+
last_non_ws_token_string = "" # nosec B105
|
129
|
+
for i, token in enumerate(tokens):
|
130
|
+
token_type, token_string, _, _, _ = token
|
77
131
|
if token_type == tokenize.INDENT:
|
78
|
-
|
132
|
+
indent_level += 1
|
79
133
|
elif token_type == tokenize.DEDENT:
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
134
|
+
indent_level -= 1
|
135
|
+
if token_type == STRING and self._is_triple_quoted(token_string):
|
136
|
+
is_docstring = (
|
137
|
+
self._is_module_docstring(tokens, i, indent_level)
|
138
|
+
or self._is_function_or_class_docstring(
|
139
|
+
tokens, i, last_non_ws_token_type, last_non_ws_token_string
|
140
|
+
)
|
141
|
+
or self._is_variable_docstring(tokens, i, indent_level)
|
142
|
+
)
|
143
|
+
if is_docstring:
|
144
|
+
continue
|
145
|
+
if token_type not in (
|
146
|
+
tokenize.NL,
|
147
|
+
tokenize.NEWLINE,
|
148
|
+
tokenize.INDENT,
|
149
|
+
tokenize.DEDENT,
|
150
|
+
):
|
151
|
+
last_non_ws_token_type = token_type
|
152
|
+
last_non_ws_token_string = token_string
|
153
|
+
result_tokens.append(token)
|
154
|
+
return tokenize.untokenize(result_tokens)
|
94
155
|
except Exception as e:
|
95
156
|
self.console.print(f"Error removing docstrings: {e}")
|
96
157
|
return source
|
@@ -105,7 +166,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
|
|
105
166
|
cleaned_lines.append(line)
|
106
167
|
return "\n".join(cleaned_lines)
|
107
168
|
|
108
|
-
def reformat_code(self, code: str) -> str:
|
169
|
+
def reformat_code(self, code: str) -> str | None:
|
109
170
|
try:
|
110
171
|
import tempfile
|
111
172
|
|
@@ -124,21 +185,22 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
|
|
124
185
|
if result.returncode == 0:
|
125
186
|
formatted_code = temp_path.read_text()
|
126
187
|
else:
|
127
|
-
print(f"Ruff formatting failed: {result.stderr}")
|
188
|
+
self.console.print(f"Ruff formatting failed: {result.stderr}")
|
128
189
|
formatted_code = code
|
129
190
|
except Exception as e:
|
130
|
-
print(f"Error running Ruff: {e}")
|
191
|
+
self.console.print(f"Error running Ruff: {e}")
|
131
192
|
formatted_code = code
|
132
193
|
finally:
|
133
194
|
with suppress(FileNotFoundError):
|
134
195
|
temp_path.unlink()
|
135
196
|
return formatted_code
|
136
197
|
except Exception as e:
|
137
|
-
print(f"Error during reformatting: {e}")
|
198
|
+
self.console.print(f"Error during reformatting: {e}")
|
138
199
|
return code
|
139
200
|
|
140
201
|
|
141
|
-
|
202
|
+
@dataclass
|
203
|
+
class ConfigManager:
|
142
204
|
our_path: Path
|
143
205
|
pkg_path: Path
|
144
206
|
pkg_name: str
|
@@ -262,14 +324,15 @@ class ConfigManager(BaseModel, arbitrary_types_allowed=True):
|
|
262
324
|
return execute(cmd, **kwargs)
|
263
325
|
|
264
326
|
|
265
|
-
|
327
|
+
@dataclass
|
328
|
+
class ProjectManager:
|
266
329
|
our_path: Path
|
267
330
|
pkg_path: Path
|
268
|
-
pkg_dir: Path | None = None
|
269
|
-
pkg_name: str = "crackerjack"
|
270
331
|
console: Console
|
271
332
|
code_cleaner: CodeCleaner
|
272
333
|
config_manager: ConfigManager
|
334
|
+
pkg_dir: Path | None = None
|
335
|
+
pkg_name: str = "crackerjack"
|
273
336
|
dry_run: bool = False
|
274
337
|
|
275
338
|
def run_interactive(self, hook: str) -> None:
|
@@ -321,39 +384,42 @@ class ProjectManager(BaseModel, arbitrary_types_allowed=True):
|
|
321
384
|
return execute(cmd, **kwargs)
|
322
385
|
|
323
386
|
|
324
|
-
|
325
|
-
|
326
|
-
|
387
|
+
@dataclass
|
388
|
+
class Crackerjack:
|
389
|
+
our_path: Path = field(default_factory=lambda: Path(__file__).parent)
|
390
|
+
pkg_path: Path = field(default_factory=lambda: Path(Path.cwd()))
|
327
391
|
pkg_dir: Path | None = None
|
328
392
|
pkg_name: str = "crackerjack"
|
329
393
|
python_version: str = default_python_version
|
330
|
-
console: Console = Console(force_terminal=True)
|
394
|
+
console: Console = field(default_factory=lambda: Console(force_terminal=True))
|
331
395
|
dry_run: bool = False
|
332
396
|
code_cleaner: CodeCleaner | None = None
|
333
397
|
config_manager: ConfigManager | None = None
|
334
398
|
project_manager: ProjectManager | None = None
|
335
399
|
|
336
|
-
def
|
337
|
-
|
338
|
-
|
339
|
-
self.config_manager
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
400
|
+
def __post_init__(self) -> None:
|
401
|
+
if self.code_cleaner is None:
|
402
|
+
self.code_cleaner = CodeCleaner(console=self.console)
|
403
|
+
if self.config_manager is None:
|
404
|
+
self.config_manager = ConfigManager(
|
405
|
+
our_path=self.our_path,
|
406
|
+
pkg_path=self.pkg_path,
|
407
|
+
pkg_name=self.pkg_name,
|
408
|
+
console=self.console,
|
409
|
+
python_version=self.python_version,
|
410
|
+
dry_run=self.dry_run,
|
411
|
+
)
|
412
|
+
if self.project_manager is None:
|
413
|
+
self.project_manager = ProjectManager(
|
414
|
+
our_path=self.our_path,
|
415
|
+
pkg_path=self.pkg_path,
|
416
|
+
pkg_dir=self.pkg_dir,
|
417
|
+
pkg_name=self.pkg_name,
|
418
|
+
console=self.console,
|
419
|
+
code_cleaner=self.code_cleaner,
|
420
|
+
config_manager=self.config_manager,
|
421
|
+
dry_run=self.dry_run,
|
422
|
+
)
|
357
423
|
|
358
424
|
def _setup_package(self) -> None:
|
359
425
|
self.pkg_name = self.pkg_path.stem.lower().replace("-", "_")
|
@@ -2,9 +2,10 @@
|
|
2
2
|
addopts = "--cov=crackerjack"
|
3
3
|
asyncio_default_fixture_loop_scope = "function"
|
4
4
|
python_files = ["test_*.py", "*_test.py"]
|
5
|
-
python_classes = "Test*"
|
6
|
-
python_functions = "test_*"
|
7
5
|
asyncio_mode = "auto"
|
6
|
+
testpaths = ["tests", "crackerjack"]
|
7
|
+
python_classes = ["Test*"]
|
8
|
+
python_functions = ["test_*"]
|
8
9
|
|
9
10
|
[tool.coverage.run]
|
10
11
|
branch = true
|
@@ -14,6 +15,7 @@ omit = [
|
|
14
15
|
"*/site-packages/*",
|
15
16
|
"*/__pycache__/*",
|
16
17
|
"*/__init__.py",
|
18
|
+
"*/_version.py", "*/conftest.py", "*/test_*.py", "*/_test.py"
|
17
19
|
]
|
18
20
|
|
19
21
|
[tool.coverage.report]
|
@@ -147,7 +149,7 @@ pythonPlatform = "Darwin"
|
|
147
149
|
|
148
150
|
[project]
|
149
151
|
name = "crackerjack"
|
150
|
-
version = "0.14.
|
152
|
+
version = "0.14.5"
|
151
153
|
description = "Default template for PDM package"
|
152
154
|
requires-python = ">=3.13"
|
153
155
|
readme = "README.md"
|
@@ -174,12 +176,12 @@ classifiers = [
|
|
174
176
|
]
|
175
177
|
dependencies = [
|
176
178
|
"autotyping>=24.9.0",
|
177
|
-
"pre-commit>=4.
|
179
|
+
"pre-commit>=4.2.0",
|
178
180
|
"pytest>=8.3.5",
|
179
181
|
"pydantic>=2.10.6",
|
180
182
|
"pdm-bump>=0.9.10",
|
181
183
|
"pdm>=2.22.4",
|
182
|
-
"uv>=0.6.
|
184
|
+
"uv>=0.6.9",
|
183
185
|
"pytest-cov>=6.0.0",
|
184
186
|
"pytest-mock>=3.14.0",
|
185
187
|
"tomli-w>=1.2.0",
|
@@ -5,9 +5,17 @@ python_files = [
|
|
5
5
|
"test_*.py",
|
6
6
|
"*_test.py",
|
7
7
|
]
|
8
|
-
python_classes = "Test*"
|
9
|
-
python_functions = "test_*"
|
10
8
|
asyncio_mode = "auto"
|
9
|
+
testpaths = [
|
10
|
+
"tests",
|
11
|
+
"crackerjack",
|
12
|
+
]
|
13
|
+
python_classes = [
|
14
|
+
"Test*",
|
15
|
+
]
|
16
|
+
python_functions = [
|
17
|
+
"test_*",
|
18
|
+
]
|
11
19
|
|
12
20
|
[tool.coverage.run]
|
13
21
|
branch = true
|
@@ -19,6 +27,10 @@ omit = [
|
|
19
27
|
"*/site-packages/*",
|
20
28
|
"*/__pycache__/*",
|
21
29
|
"*/__init__.py",
|
30
|
+
"*/_version.py",
|
31
|
+
"*/conftest.py",
|
32
|
+
"*/test_*.py",
|
33
|
+
"*/_test.py",
|
22
34
|
]
|
23
35
|
|
24
36
|
[tool.coverage.report]
|
@@ -156,7 +168,7 @@ pythonPlatform = "Darwin"
|
|
156
168
|
|
157
169
|
[project]
|
158
170
|
name = "crackerjack"
|
159
|
-
version = "0.14.
|
171
|
+
version = "0.14.6"
|
160
172
|
description = "Default template for PDM package"
|
161
173
|
requires-python = ">=3.13"
|
162
174
|
readme = "README.md"
|
@@ -183,12 +195,12 @@ classifiers = [
|
|
183
195
|
]
|
184
196
|
dependencies = [
|
185
197
|
"autotyping>=24.9.0",
|
186
|
-
"pre-commit>=4.
|
198
|
+
"pre-commit>=4.2.0",
|
187
199
|
"pytest>=8.3.5",
|
188
200
|
"pydantic>=2.10.6",
|
189
201
|
"pdm-bump>=0.9.10",
|
190
202
|
"pdm>=2.22.4",
|
191
|
-
"uv>=0.6.
|
203
|
+
"uv>=0.6.9",
|
192
204
|
"pytest-cov>=6.0.0",
|
193
205
|
"pytest-mock>=3.14.0",
|
194
206
|
"tomli-w>=1.2.0",
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
def test_func():
|
3
|
+
"""This is a docstring."""
|
4
|
+
return True
|
5
|
+
|
6
|
+
class TestClass:
|
7
|
+
"""Class docstring."""
|
8
|
+
|
9
|
+
def method1(self):
|
10
|
+
'''Method docstring.'''
|
11
|
+
pass
|
12
|
+
|
13
|
+
def method2(self):
|
14
|
+
"""
|
15
|
+
Method docstring.
|
16
|
+
|
17
|
+
This is a multi-line docstring.
|
18
|
+
|
19
|
+
"""
|
20
|
+
pass
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import os
|
2
2
|
import typing as t
|
3
3
|
from contextlib import suppress
|
4
|
+
from dataclasses import dataclass
|
4
5
|
from enum import Enum
|
5
6
|
from pathlib import Path
|
6
7
|
from unittest.mock import MagicMock, patch
|
7
8
|
|
8
9
|
import pytest
|
9
|
-
from pydantic import BaseModel
|
10
10
|
from rich.console import Console
|
11
11
|
from crackerjack.crackerjack import (
|
12
12
|
CodeCleaner,
|
@@ -25,18 +25,19 @@ class BumpOption(str, Enum):
|
|
25
25
|
return self.value
|
26
26
|
|
27
27
|
|
28
|
-
|
28
|
+
@dataclass
|
29
|
+
class OptionsForTesting:
|
29
30
|
commit: bool = False
|
30
31
|
interactive: bool = False
|
31
32
|
doc: bool = False
|
32
33
|
no_config_updates: bool = False
|
33
|
-
publish:
|
34
|
-
bump:
|
34
|
+
publish: BumpOption | None = None
|
35
|
+
bump: BumpOption | None = None
|
35
36
|
verbose: bool = False
|
36
37
|
update_precommit: bool = False
|
37
38
|
clean: bool = False
|
38
39
|
test: bool = False
|
39
|
-
all:
|
40
|
+
all: BumpOption | None = None
|
40
41
|
|
41
42
|
|
42
43
|
@pytest.fixture
|
@@ -98,6 +99,8 @@ class TestCrackerjackProcess:
|
|
98
99
|
kwargs["publish"] = BumpOption(kwargs["publish"])
|
99
100
|
if "bump" in kwargs and isinstance(kwargs["bump"], str):
|
100
101
|
kwargs["bump"] = BumpOption(kwargs["bump"])
|
102
|
+
if "all" in kwargs and isinstance(kwargs["all"], str):
|
103
|
+
kwargs["all"] = BumpOption(kwargs["all"])
|
101
104
|
return OptionsForTesting(**kwargs)
|
102
105
|
|
103
106
|
return _create_options
|
@@ -901,11 +904,15 @@ class TestCrackerjackProcess:
|
|
901
904
|
Path(__file__).parent / "data" / "docstrings_sample.txt"
|
902
905
|
).read_text()
|
903
906
|
cleaned_code = code_cleaner.remove_docstrings(code_with_docstrings)
|
907
|
+
print(cleaned_code)
|
904
908
|
assert '"""This is a docstring."""' not in cleaned_code, (
|
905
909
|
f"Got: {cleaned_code!r}"
|
906
910
|
)
|
907
911
|
assert '"""Class docstring."""' not in cleaned_code, f"Got: {cleaned_code!r}"
|
908
|
-
assert '
|
912
|
+
assert "'''Method docstring.'''" not in cleaned_code, f"Got: {cleaned_code!r}"
|
913
|
+
assert "This is a multi-line docstring." not in cleaned_code, (
|
914
|
+
f"Got: {cleaned_code!r}"
|
915
|
+
)
|
909
916
|
|
910
917
|
def test_code_cleaner_remove_line_comments(self) -> None:
|
911
918
|
from pathlib import Path
|
@@ -961,16 +968,25 @@ class TestCrackerjackProcess:
|
|
961
968
|
def test_code_cleaner_reformat_code_failure(
|
962
969
|
self, mock_execute: MagicMock, mock_console_print: MagicMock, tmp_path: Path
|
963
970
|
) -> None:
|
964
|
-
|
971
|
+
from rich.console import Console
|
972
|
+
|
973
|
+
console = Console()
|
974
|
+
|
975
|
+
code_cleaner = CodeCleaner(console=console)
|
965
976
|
code_to_format = "def test_func():\n return True\n"
|
977
|
+
|
966
978
|
with patch("subprocess.run") as mock_run:
|
967
979
|
mock_run.return_value = MagicMock(returncode=1, stderr="Formatting error")
|
968
|
-
|
969
|
-
|
980
|
+
|
981
|
+
with patch("pathlib.Path.write_text"):
|
982
|
+
with patch.object(console, "print") as mock_console_print_method:
|
970
983
|
formatted_code = code_cleaner.reformat_code(code_to_format)
|
984
|
+
|
971
985
|
assert formatted_code == code_to_format
|
986
|
+
|
972
987
|
mock_run.assert_called_once()
|
973
|
-
|
988
|
+
|
989
|
+
mock_console_print_method.assert_any_call(
|
974
990
|
"Ruff formatting failed: Formatting error"
|
975
991
|
)
|
976
992
|
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.11/3256171999636029978
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.4/10355199064880463147
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.6/15140459877605758699
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.1.9/17041001205004563469
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.2.0/10047773857155985907
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.2.2/18053836298936336950
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.3.0/12548816621480535786
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.3.3/11081883392474770722
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.3.5/16311176246009842383
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.0/11982804814124138945
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.6.0/12055761203849489982
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.7.3/16061516852537040135
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.8.4/16354268377385700367
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.9.10/12813592349865671909
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.9.3/13948373885254993391
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.6}/crackerjack/.ruff_cache/0.9.9/12813592349865671909
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|