crackerjack 0.14.4__tar.gz → 0.14.5__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.5}/PKG-INFO +3 -3
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.pre-commit-config.yaml +3 -3
- crackerjack-0.14.5/crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/crackerjack.py +121 -59
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/pyproject.toml +3 -3
- {crackerjack-0.14.4 → crackerjack-0.14.5}/pyproject.toml +3 -3
- crackerjack-0.14.5/tests/data/docstrings_sample.txt +20 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/tests/test_crackerjack.py +26 -10
- crackerjack-0.14.4/tests/data/docstrings_sample.txt +0 -10
- {crackerjack-0.14.4 → crackerjack-0.14.5}/LICENSE +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/README.md +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.coverage +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.gitignore +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.libcst.codemod.yaml +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.pdm.toml +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.pytest_cache/.gitignore +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.pytest_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.pytest_cache/README.md +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.pytest_cache/v/cache/nodeids +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.pytest_cache/v/cache/stepwise +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/.gitignore +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/__init__.py +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/__main__.py +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/tests/__init__.py +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/tests/data/comments_sample.txt +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/tests/data/expected_comments_sample.txt +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/tests/data/init.py +0 -0
- {crackerjack-0.14.4 → crackerjack-0.14.5}/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.5
|
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 = []
|
@@ -66,31 +67,87 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
|
|
66
67
|
new_lines.append(code_part)
|
67
68
|
return "\n".join(new_lines)
|
68
69
|
|
70
|
+
def _is_triple_quoted(self, token_string: str) -> bool:
|
71
|
+
triple_quote_patterns = [
|
72
|
+
('"""', '"""'),
|
73
|
+
("'''", "'''"),
|
74
|
+
('r"""', '"""'),
|
75
|
+
("r'''", "'''"),
|
76
|
+
]
|
77
|
+
return any(
|
78
|
+
token_string.startswith(start) and token_string.endswith(end)
|
79
|
+
for start, end in triple_quote_patterns
|
80
|
+
)
|
81
|
+
|
82
|
+
def _is_module_docstring(
|
83
|
+
self, tokens: list[tokenize.TokenInfo], i: int, indent_level: int
|
84
|
+
) -> bool:
|
85
|
+
if i <= 0 or indent_level != 0:
|
86
|
+
return False
|
87
|
+
preceding_tokens = tokens[:i]
|
88
|
+
return not preceding_tokens
|
89
|
+
|
90
|
+
def _is_function_or_class_docstring(
|
91
|
+
self,
|
92
|
+
tokens: list[tokenize.TokenInfo],
|
93
|
+
i: int,
|
94
|
+
last_token_type: t.Any,
|
95
|
+
last_token_string: str,
|
96
|
+
) -> bool:
|
97
|
+
if last_token_type != tokenize.OP or last_token_string != ":": # nosec B105
|
98
|
+
return False
|
99
|
+
for prev_idx in range(i - 1, max(0, i - 20), -1):
|
100
|
+
prev_token = tokens[prev_idx]
|
101
|
+
if prev_token[1] in ("def", "class") and prev_token[0] == tokenize.NAME:
|
102
|
+
return True
|
103
|
+
elif prev_token[0] == tokenize.DEDENT:
|
104
|
+
break
|
105
|
+
return False
|
106
|
+
|
107
|
+
def _is_variable_docstring(
|
108
|
+
self, tokens: list[tokenize.TokenInfo], i: int, indent_level: int
|
109
|
+
) -> bool:
|
110
|
+
if indent_level <= 0:
|
111
|
+
return False
|
112
|
+
for prev_idx in range(i - 1, max(0, i - 10), -1):
|
113
|
+
if tokens[prev_idx][0]:
|
114
|
+
return True
|
115
|
+
return False
|
116
|
+
|
69
117
|
def remove_docstrings(self, source: str) -> str:
|
70
118
|
try:
|
71
119
|
io_obj = io.StringIO(source)
|
72
|
-
output_tokens = []
|
73
|
-
first_token_stack = [True]
|
74
120
|
tokens = list(tokenize.generate_tokens(io_obj.readline))
|
75
|
-
|
76
|
-
|
121
|
+
result_tokens = []
|
122
|
+
indent_level = 0
|
123
|
+
last_non_ws_token_type = None
|
124
|
+
last_non_ws_token_string = "" # nosec B105
|
125
|
+
for i, token in enumerate(tokens):
|
126
|
+
token_type, token_string, _, _, _ = token
|
77
127
|
if token_type == tokenize.INDENT:
|
78
|
-
|
128
|
+
indent_level += 1
|
79
129
|
elif token_type == tokenize.DEDENT:
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
130
|
+
indent_level -= 1
|
131
|
+
if token_type == STRING and self._is_triple_quoted(token_string):
|
132
|
+
is_docstring = (
|
133
|
+
self._is_module_docstring(tokens, i, indent_level)
|
134
|
+
or self._is_function_or_class_docstring(
|
135
|
+
tokens, i, last_non_ws_token_type, last_non_ws_token_string
|
136
|
+
)
|
137
|
+
or self._is_variable_docstring(tokens, i, indent_level)
|
138
|
+
)
|
139
|
+
if is_docstring:
|
140
|
+
continue
|
141
|
+
if token_type not in (
|
142
|
+
tokenize.NL,
|
143
|
+
tokenize.NEWLINE,
|
144
|
+
tokenize.INDENT,
|
145
|
+
tokenize.DEDENT,
|
146
|
+
):
|
147
|
+
last_non_ws_token_type = token_type
|
148
|
+
last_non_ws_token_string = token_string
|
149
|
+
result_tokens.append(token)
|
150
|
+
return tokenize.untokenize(result_tokens)
|
94
151
|
except Exception as e:
|
95
152
|
self.console.print(f"Error removing docstrings: {e}")
|
96
153
|
return source
|
@@ -105,7 +162,7 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
|
|
105
162
|
cleaned_lines.append(line)
|
106
163
|
return "\n".join(cleaned_lines)
|
107
164
|
|
108
|
-
def reformat_code(self, code: str) -> str:
|
165
|
+
def reformat_code(self, code: str) -> str | None:
|
109
166
|
try:
|
110
167
|
import tempfile
|
111
168
|
|
@@ -124,21 +181,22 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
|
|
124
181
|
if result.returncode == 0:
|
125
182
|
formatted_code = temp_path.read_text()
|
126
183
|
else:
|
127
|
-
print(f"Ruff formatting failed: {result.stderr}")
|
184
|
+
self.console.print(f"Ruff formatting failed: {result.stderr}")
|
128
185
|
formatted_code = code
|
129
186
|
except Exception as e:
|
130
|
-
print(f"Error running Ruff: {e}")
|
187
|
+
self.console.print(f"Error running Ruff: {e}")
|
131
188
|
formatted_code = code
|
132
189
|
finally:
|
133
190
|
with suppress(FileNotFoundError):
|
134
191
|
temp_path.unlink()
|
135
192
|
return formatted_code
|
136
193
|
except Exception as e:
|
137
|
-
print(f"Error during reformatting: {e}")
|
194
|
+
self.console.print(f"Error during reformatting: {e}")
|
138
195
|
return code
|
139
196
|
|
140
197
|
|
141
|
-
|
198
|
+
@dataclass
|
199
|
+
class ConfigManager:
|
142
200
|
our_path: Path
|
143
201
|
pkg_path: Path
|
144
202
|
pkg_name: str
|
@@ -262,14 +320,15 @@ class ConfigManager(BaseModel, arbitrary_types_allowed=True):
|
|
262
320
|
return execute(cmd, **kwargs)
|
263
321
|
|
264
322
|
|
265
|
-
|
323
|
+
@dataclass
|
324
|
+
class ProjectManager:
|
266
325
|
our_path: Path
|
267
326
|
pkg_path: Path
|
268
|
-
pkg_dir: Path | None = None
|
269
|
-
pkg_name: str = "crackerjack"
|
270
327
|
console: Console
|
271
328
|
code_cleaner: CodeCleaner
|
272
329
|
config_manager: ConfigManager
|
330
|
+
pkg_dir: Path | None = None
|
331
|
+
pkg_name: str = "crackerjack"
|
273
332
|
dry_run: bool = False
|
274
333
|
|
275
334
|
def run_interactive(self, hook: str) -> None:
|
@@ -321,39 +380,42 @@ class ProjectManager(BaseModel, arbitrary_types_allowed=True):
|
|
321
380
|
return execute(cmd, **kwargs)
|
322
381
|
|
323
382
|
|
324
|
-
|
325
|
-
|
326
|
-
|
383
|
+
@dataclass
|
384
|
+
class Crackerjack:
|
385
|
+
our_path: Path = field(default_factory=lambda: Path(__file__).parent)
|
386
|
+
pkg_path: Path = field(default_factory=lambda: Path(Path.cwd()))
|
327
387
|
pkg_dir: Path | None = None
|
328
388
|
pkg_name: str = "crackerjack"
|
329
389
|
python_version: str = default_python_version
|
330
|
-
console: Console = Console(force_terminal=True)
|
390
|
+
console: Console = field(default_factory=lambda: Console(force_terminal=True))
|
331
391
|
dry_run: bool = False
|
332
392
|
code_cleaner: CodeCleaner | None = None
|
333
393
|
config_manager: ConfigManager | None = None
|
334
394
|
project_manager: ProjectManager | None = None
|
335
395
|
|
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
|
-
|
396
|
+
def __post_init__(self) -> None:
|
397
|
+
if self.code_cleaner is None:
|
398
|
+
self.code_cleaner = CodeCleaner(console=self.console)
|
399
|
+
if self.config_manager is None:
|
400
|
+
self.config_manager = ConfigManager(
|
401
|
+
our_path=self.our_path,
|
402
|
+
pkg_path=self.pkg_path,
|
403
|
+
pkg_name=self.pkg_name,
|
404
|
+
console=self.console,
|
405
|
+
python_version=self.python_version,
|
406
|
+
dry_run=self.dry_run,
|
407
|
+
)
|
408
|
+
if self.project_manager is None:
|
409
|
+
self.project_manager = ProjectManager(
|
410
|
+
our_path=self.our_path,
|
411
|
+
pkg_path=self.pkg_path,
|
412
|
+
pkg_dir=self.pkg_dir,
|
413
|
+
pkg_name=self.pkg_name,
|
414
|
+
console=self.console,
|
415
|
+
code_cleaner=self.code_cleaner,
|
416
|
+
config_manager=self.config_manager,
|
417
|
+
dry_run=self.dry_run,
|
418
|
+
)
|
357
419
|
|
358
420
|
def _setup_package(self) -> None:
|
359
421
|
self.pkg_name = self.pkg_path.stem.lower().replace("-", "_")
|
@@ -147,7 +147,7 @@ pythonPlatform = "Darwin"
|
|
147
147
|
|
148
148
|
[project]
|
149
149
|
name = "crackerjack"
|
150
|
-
version = "0.14.
|
150
|
+
version = "0.14.4"
|
151
151
|
description = "Default template for PDM package"
|
152
152
|
requires-python = ">=3.13"
|
153
153
|
readme = "README.md"
|
@@ -174,12 +174,12 @@ classifiers = [
|
|
174
174
|
]
|
175
175
|
dependencies = [
|
176
176
|
"autotyping>=24.9.0",
|
177
|
-
"pre-commit>=4.
|
177
|
+
"pre-commit>=4.2.0",
|
178
178
|
"pytest>=8.3.5",
|
179
179
|
"pydantic>=2.10.6",
|
180
180
|
"pdm-bump>=0.9.10",
|
181
181
|
"pdm>=2.22.4",
|
182
|
-
"uv>=0.6.
|
182
|
+
"uv>=0.6.9",
|
183
183
|
"pytest-cov>=6.0.0",
|
184
184
|
"pytest-mock>=3.14.0",
|
185
185
|
"tomli-w>=1.2.0",
|
@@ -156,7 +156,7 @@ pythonPlatform = "Darwin"
|
|
156
156
|
|
157
157
|
[project]
|
158
158
|
name = "crackerjack"
|
159
|
-
version = "0.14.
|
159
|
+
version = "0.14.5"
|
160
160
|
description = "Default template for PDM package"
|
161
161
|
requires-python = ">=3.13"
|
162
162
|
readme = "README.md"
|
@@ -183,12 +183,12 @@ classifiers = [
|
|
183
183
|
]
|
184
184
|
dependencies = [
|
185
185
|
"autotyping>=24.9.0",
|
186
|
-
"pre-commit>=4.
|
186
|
+
"pre-commit>=4.2.0",
|
187
187
|
"pytest>=8.3.5",
|
188
188
|
"pydantic>=2.10.6",
|
189
189
|
"pdm-bump>=0.9.10",
|
190
190
|
"pdm>=2.22.4",
|
191
|
-
"uv>=0.6.
|
191
|
+
"uv>=0.6.9",
|
192
192
|
"pytest-cov>=6.0.0",
|
193
193
|
"pytest-mock>=3.14.0",
|
194
194
|
"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.5}/crackerjack/.ruff_cache/0.1.11/3256171999636029978
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.4/10355199064880463147
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.6/15140459877605758699
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.1.9/17041001205004563469
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.2.0/10047773857155985907
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.2.2/18053836298936336950
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.3.0/12548816621480535786
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.3.3/11081883392474770722
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/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.5}/crackerjack/.ruff_cache/0.6.0/11982804814124138945
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/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.5}/crackerjack/.ruff_cache/0.7.3/16061516852537040135
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.8.4/16354268377385700367
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.9.10/12813592349865671909
RENAMED
File without changes
|
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/crackerjack/.ruff_cache/0.9.3/13948373885254993391
RENAMED
File without changes
|
{crackerjack-0.14.4 → crackerjack-0.14.5}/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
|