crackerjack 0.18.12__tar.gz → 0.19.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.
- crackerjack-0.18.12/README.md → crackerjack-0.19.0/PKG-INFO +86 -0
- crackerjack-0.18.12/PKG-INFO → crackerjack-0.19.0/README.md +44 -41
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.pre-commit-config.yaml +19 -13
- crackerjack-0.19.0/crackerjack/.ruff_cache/0.11.12/4441409093023629623 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/__main__.py +18 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/crackerjack.py +44 -6
- crackerjack-0.19.0/crackerjack/pyproject.toml +233 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/pyproject.toml +151 -140
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/conftest.py +37 -1
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/test_crackerjack.py +51 -19
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/test_crackerjack_runner.py +4 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/test_main.py +56 -1
- crackerjack-0.18.12/crackerjack/pyproject.toml +0 -225
- {crackerjack-0.18.12 → crackerjack-0.19.0}/LICENSE +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.gitignore +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.libcst.codemod.yaml +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.pdm.toml +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.pytest_cache/.gitignore +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.pytest_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.pytest_cache/README.md +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.pytest_cache/v/cache/nodeids +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.pytest_cache/v/cache/stepwise +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/.gitignore +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.11/18187162184424859798 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.12/16869036553936192448 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/crackerjack/__init__.py +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/TESTING.md +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/__init__.py +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/data/comments_sample.txt +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/data/docstrings_sample.txt +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/data/expected_comments_sample.txt +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/data/init.py +0 -0
- {crackerjack-0.18.12 → crackerjack-0.19.0}/tests/test_pytest_features.py +0 -0
@@ -1,3 +1,45 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: crackerjack
|
3
|
+
Version: 0.19.0
|
4
|
+
Summary: Crackerjack: code quality toolkit
|
5
|
+
Keywords: bandit,black,creosote,mypy,pyright,pytest,refurb,ruff
|
6
|
+
Author-Email: lesleslie <les@wedgwoodwebworks.com>
|
7
|
+
Maintainer-Email: lesleslie <les@wedgwoodwebworks.com>
|
8
|
+
License: BSD-3-CLAUSE
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
10
|
+
Classifier: Environment :: Console
|
11
|
+
Classifier: License :: OSI Approved :: BSD License
|
12
|
+
Classifier: Operating System :: POSIX
|
13
|
+
Classifier: Programming Language :: Python
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
16
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
17
|
+
Classifier: Topic :: Software Development :: Quality Assurance
|
18
|
+
Classifier: Topic :: Software Development :: Testing
|
19
|
+
Classifier: Topic :: Utilities
|
20
|
+
Classifier: Typing :: Typed
|
21
|
+
Project-URL: documentation, https://github.com/lesleslie/crackerjack
|
22
|
+
Project-URL: homepage, https://github.com/lesleslie/crackerjack
|
23
|
+
Project-URL: repository, https://github.com/lesleslie/crackerjack
|
24
|
+
Requires-Python: >=3.13
|
25
|
+
Requires-Dist: autotyping>=24.9
|
26
|
+
Requires-Dist: pdm>=2.24.2
|
27
|
+
Requires-Dist: pdm-bump>=0.9.12
|
28
|
+
Requires-Dist: pre-commit>=4.2
|
29
|
+
Requires-Dist: pydantic>=2.11.5
|
30
|
+
Requires-Dist: pytest>=8.3.5
|
31
|
+
Requires-Dist: pytest-asyncio>=1
|
32
|
+
Requires-Dist: pytest-benchmark>=5.1
|
33
|
+
Requires-Dist: pytest-cov>=6.1.1
|
34
|
+
Requires-Dist: pytest-mock>=3.14.1
|
35
|
+
Requires-Dist: pytest-timeout>=2.4
|
36
|
+
Requires-Dist: pytest-xdist>=3.7
|
37
|
+
Requires-Dist: rich>=14
|
38
|
+
Requires-Dist: tomli-w>=1.2
|
39
|
+
Requires-Dist: typer>=0.16
|
40
|
+
Requires-Dist: uv>=0.7.9
|
41
|
+
Description-Content-Type: text/markdown
|
42
|
+
|
1
43
|
# Crackerjack: Elevate Your Python Development
|
2
44
|
|
3
45
|
[](https://github.com/lesleslie/crackerjack)
|
@@ -135,6 +177,44 @@ Crackerjack projects adhere to these guidelines:
|
|
135
177
|
- **Clear Code:** Avoid overly complex code.
|
136
178
|
- **Modular:** Functions should do one thing well.
|
137
179
|
|
180
|
+
## Testing Features
|
181
|
+
|
182
|
+
Crackerjack provides advanced testing capabilities powered by pytest:
|
183
|
+
|
184
|
+
### Standard Testing
|
185
|
+
|
186
|
+
- **Parallel Test Execution:** Tests run in parallel by default using pytest-xdist for faster execution
|
187
|
+
- **Timeout Protection:** All tests have a default 60-second timeout to prevent hanging tests
|
188
|
+
- **Coverage Reports:** Automatically generates test coverage reports with configurable thresholds
|
189
|
+
|
190
|
+
### Benchmark Testing
|
191
|
+
|
192
|
+
Crackerjack includes benchmark testing capabilities:
|
193
|
+
|
194
|
+
- **Performance Measurement:** Run tests with `--benchmark` to measure execution time and performance
|
195
|
+
- **Regression Testing:** Use `--benchmark-regression` to detect performance regressions
|
196
|
+
- **Configurable Thresholds:** Set custom regression thresholds with `--benchmark-regression-threshold`
|
197
|
+
- **Compatibility Management:** Automatically disables parallel execution when running benchmarks
|
198
|
+
- **CI Integration:** Track performance across commits with benchmark history
|
199
|
+
|
200
|
+
When benchmarks are run, Crackerjack:
|
201
|
+
1. Disables parallel test execution (as pytest-benchmark is incompatible with pytest-xdist)
|
202
|
+
2. Configures the pytest-benchmark plugin with optimized settings
|
203
|
+
3. Compares benchmark results against previous runs when regression testing is enabled
|
204
|
+
4. Fails tests if performance decreases beyond the specified threshold
|
205
|
+
|
206
|
+
Example benchmark usage:
|
207
|
+
```bash
|
208
|
+
# Run benchmarks
|
209
|
+
python -m crackerjack -t --benchmark
|
210
|
+
|
211
|
+
# Run benchmarks with regression testing (fail if >5% slower)
|
212
|
+
python -m crackerjack -t --benchmark-regression
|
213
|
+
|
214
|
+
# Run benchmarks with custom regression threshold (10%)
|
215
|
+
python -m crackerjack -t --benchmark-regression --benchmark-regression-threshold=10.0
|
216
|
+
```
|
217
|
+
|
138
218
|
## Installation
|
139
219
|
|
140
220
|
1. **Python:** Ensure you have Python 3.13 installed.
|
@@ -185,6 +265,9 @@ class MyOptions:
|
|
185
265
|
# Process options
|
186
266
|
self.clean = True # Clean code (remove docstrings, comments, etc.)
|
187
267
|
self.test = True # Run tests using pytest
|
268
|
+
self.benchmark = False # Run tests in benchmark mode
|
269
|
+
self.benchmark_regression = False # Fail tests if benchmarks regress beyond threshold
|
270
|
+
self.benchmark_regression_threshold = 5.0 # Threshold percentage for benchmark regression
|
188
271
|
self.skip_hooks = False # Skip running pre-commit hooks
|
189
272
|
|
190
273
|
# Version and publishing options
|
@@ -225,6 +308,9 @@ runner.process(MyOptions())
|
|
225
308
|
- `-s`, `--skip-hooks`: Skip running pre-commit hooks (useful with `-t`).
|
226
309
|
- `-x`, `--clean`: Clean code by removing docstrings, line comments, and extra whitespace.
|
227
310
|
- `-t`, `--test`: Run tests using `pytest`.
|
311
|
+
- `--benchmark`: Run tests in benchmark mode (disables parallel execution).
|
312
|
+
- `--benchmark-regression`: Fail tests if benchmarks regress beyond threshold.
|
313
|
+
- `--benchmark-regression-threshold`: Set threshold percentage for benchmark regression (default 5.0%).
|
228
314
|
- `-a`, `--all`: Run with `-x -t -p <micro|minor|major> -c` development options.
|
229
315
|
- `--ai-agent`: Enable AI agent mode with structured output (see [AI Agent Integration](#ai-agent-integration)).
|
230
316
|
- `--help`: Display help.
|
@@ -1,44 +1,3 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: crackerjack
|
3
|
-
Version: 0.18.12
|
4
|
-
Summary: Default template for PDM package
|
5
|
-
Keywords: black,ruff,mypy,creosote,refurb,pyright,bandit,pytest
|
6
|
-
Author-Email: lesleslie <les@wedgwoodwebworks.com>
|
7
|
-
Maintainer-Email: lesleslie <les@wedgwoodwebworks.com>
|
8
|
-
License: BSD-3-CLAUSE
|
9
|
-
Classifier: Environment :: Console
|
10
|
-
Classifier: Operating System :: POSIX
|
11
|
-
Classifier: Programming Language :: Python
|
12
|
-
Classifier: Programming Language :: Python :: 3.13
|
13
|
-
Classifier: Development Status :: 4 - Beta
|
14
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
15
|
-
Classifier: Topic :: Software Development :: Quality Assurance
|
16
|
-
Classifier: Topic :: Software Development :: Testing
|
17
|
-
Classifier: Topic :: Utilities
|
18
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
19
|
-
Classifier: License :: OSI Approved :: BSD License
|
20
|
-
Classifier: Typing :: Typed
|
21
|
-
Project-URL: homepage, https://github.com/lesleslie/crackerjack
|
22
|
-
Project-URL: documentation, https://github.com/lesleslie/crackerjack
|
23
|
-
Project-URL: repository, https://github.com/lesleslie/crackerjack
|
24
|
-
Requires-Python: >=3.13
|
25
|
-
Requires-Dist: autotyping>=24.9.0
|
26
|
-
Requires-Dist: pre-commit>=4.2.0
|
27
|
-
Requires-Dist: pytest>=8.3.5
|
28
|
-
Requires-Dist: pydantic>=2.11.5
|
29
|
-
Requires-Dist: pdm-bump>=0.9.12
|
30
|
-
Requires-Dist: pdm>=2.24.2
|
31
|
-
Requires-Dist: uv>=0.7.9
|
32
|
-
Requires-Dist: pytest-cov>=6.1.1
|
33
|
-
Requires-Dist: pytest-mock>=3.14.1
|
34
|
-
Requires-Dist: tomli-w>=1.2.0
|
35
|
-
Requires-Dist: pytest-asyncio>=1.0.0
|
36
|
-
Requires-Dist: rich>=14.0.0
|
37
|
-
Requires-Dist: typer>=0.16.0
|
38
|
-
Requires-Dist: pytest-timeout>=2.4.0
|
39
|
-
Requires-Dist: pytest-xdist>=3.7.0
|
40
|
-
Description-Content-Type: text/markdown
|
41
|
-
|
42
1
|
# Crackerjack: Elevate Your Python Development
|
43
2
|
|
44
3
|
[](https://github.com/lesleslie/crackerjack)
|
@@ -176,6 +135,44 @@ Crackerjack projects adhere to these guidelines:
|
|
176
135
|
- **Clear Code:** Avoid overly complex code.
|
177
136
|
- **Modular:** Functions should do one thing well.
|
178
137
|
|
138
|
+
## Testing Features
|
139
|
+
|
140
|
+
Crackerjack provides advanced testing capabilities powered by pytest:
|
141
|
+
|
142
|
+
### Standard Testing
|
143
|
+
|
144
|
+
- **Parallel Test Execution:** Tests run in parallel by default using pytest-xdist for faster execution
|
145
|
+
- **Timeout Protection:** All tests have a default 60-second timeout to prevent hanging tests
|
146
|
+
- **Coverage Reports:** Automatically generates test coverage reports with configurable thresholds
|
147
|
+
|
148
|
+
### Benchmark Testing
|
149
|
+
|
150
|
+
Crackerjack includes benchmark testing capabilities:
|
151
|
+
|
152
|
+
- **Performance Measurement:** Run tests with `--benchmark` to measure execution time and performance
|
153
|
+
- **Regression Testing:** Use `--benchmark-regression` to detect performance regressions
|
154
|
+
- **Configurable Thresholds:** Set custom regression thresholds with `--benchmark-regression-threshold`
|
155
|
+
- **Compatibility Management:** Automatically disables parallel execution when running benchmarks
|
156
|
+
- **CI Integration:** Track performance across commits with benchmark history
|
157
|
+
|
158
|
+
When benchmarks are run, Crackerjack:
|
159
|
+
1. Disables parallel test execution (as pytest-benchmark is incompatible with pytest-xdist)
|
160
|
+
2. Configures the pytest-benchmark plugin with optimized settings
|
161
|
+
3. Compares benchmark results against previous runs when regression testing is enabled
|
162
|
+
4. Fails tests if performance decreases beyond the specified threshold
|
163
|
+
|
164
|
+
Example benchmark usage:
|
165
|
+
```bash
|
166
|
+
# Run benchmarks
|
167
|
+
python -m crackerjack -t --benchmark
|
168
|
+
|
169
|
+
# Run benchmarks with regression testing (fail if >5% slower)
|
170
|
+
python -m crackerjack -t --benchmark-regression
|
171
|
+
|
172
|
+
# Run benchmarks with custom regression threshold (10%)
|
173
|
+
python -m crackerjack -t --benchmark-regression --benchmark-regression-threshold=10.0
|
174
|
+
```
|
175
|
+
|
179
176
|
## Installation
|
180
177
|
|
181
178
|
1. **Python:** Ensure you have Python 3.13 installed.
|
@@ -226,6 +223,9 @@ class MyOptions:
|
|
226
223
|
# Process options
|
227
224
|
self.clean = True # Clean code (remove docstrings, comments, etc.)
|
228
225
|
self.test = True # Run tests using pytest
|
226
|
+
self.benchmark = False # Run tests in benchmark mode
|
227
|
+
self.benchmark_regression = False # Fail tests if benchmarks regress beyond threshold
|
228
|
+
self.benchmark_regression_threshold = 5.0 # Threshold percentage for benchmark regression
|
229
229
|
self.skip_hooks = False # Skip running pre-commit hooks
|
230
230
|
|
231
231
|
# Version and publishing options
|
@@ -266,6 +266,9 @@ runner.process(MyOptions())
|
|
266
266
|
- `-s`, `--skip-hooks`: Skip running pre-commit hooks (useful with `-t`).
|
267
267
|
- `-x`, `--clean`: Clean code by removing docstrings, line comments, and extra whitespace.
|
268
268
|
- `-t`, `--test`: Run tests using `pytest`.
|
269
|
+
- `--benchmark`: Run tests in benchmark mode (disables parallel execution).
|
270
|
+
- `--benchmark-regression`: Fail tests if benchmarks regress beyond threshold.
|
271
|
+
- `--benchmark-regression-threshold`: Set threshold percentage for benchmark regression (default 5.0%).
|
269
272
|
- `-a`, `--all`: Run with `-x -t -p <micro|minor|major> -c` development options.
|
270
273
|
- `--ai-agent`: Enable AI agent mode with structured output (see [AI Agent Integration](#ai-agent-integration)).
|
271
274
|
- `--help`: Display help.
|
@@ -3,12 +3,14 @@ repos:
|
|
3
3
|
rev: 2.24.2 # a PDM release exposing the hook
|
4
4
|
hooks:
|
5
5
|
- id: pdm-lock-check
|
6
|
-
# - id: pdm-export
|
7
|
-
# args: [ '-o', 'requirements.txt', '--without-hashes' ]
|
8
|
-
# files: ^pdm.lock$
|
9
6
|
- id: pdm-sync
|
10
7
|
additional_dependencies:
|
11
8
|
- keyring
|
9
|
+
- repo: https://github.com/astral-sh/uv-pre-commit
|
10
|
+
rev: 0.7.9
|
11
|
+
hooks:
|
12
|
+
- id: uv-lock
|
13
|
+
files: ^pyproject\.toml$
|
12
14
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
13
15
|
rev: v5.0.0
|
14
16
|
hooks:
|
@@ -22,11 +24,24 @@ repos:
|
|
22
24
|
name: check-toml
|
23
25
|
- id: check-added-large-files
|
24
26
|
name: check-added-large-files
|
27
|
+
- repo: https://github.com/Yelp/detect-secrets
|
28
|
+
rev: v1.5.0
|
29
|
+
hooks:
|
30
|
+
- id: detect-secrets
|
31
|
+
exclude: "pdm.lock"
|
32
|
+
- repo: https://github.com/abravalheri/validate-pyproject
|
33
|
+
rev: v0.24.1
|
34
|
+
hooks:
|
35
|
+
- id: validate-pyproject
|
36
|
+
- repo: https://github.com/tox-dev/pyproject-fmt
|
37
|
+
rev: "v2.6.0"
|
38
|
+
hooks:
|
39
|
+
- id: pyproject-fmt
|
25
40
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
26
41
|
rev: v0.11.12
|
27
42
|
hooks:
|
28
|
-
- id: ruff-format
|
29
43
|
- id: ruff-check
|
44
|
+
- id: ruff-format
|
30
45
|
- repo: https://github.com/jendrikseipp/vulture
|
31
46
|
rev: 'v2.14'
|
32
47
|
hooks:
|
@@ -35,10 +50,6 @@ repos:
|
|
35
50
|
rev: v4.0.3
|
36
51
|
hooks:
|
37
52
|
- id: creosote
|
38
|
-
- repo: https://github.com/ikamensh/flynt/
|
39
|
-
rev: '1.0.1'
|
40
|
-
hooks:
|
41
|
-
- id: flynt
|
42
53
|
- repo: https://github.com/codespell-project/codespell
|
43
54
|
rev: v2.4.1
|
44
55
|
hooks:
|
@@ -74,11 +85,6 @@ repos:
|
|
74
85
|
rev: v1.1.401
|
75
86
|
hooks:
|
76
87
|
- id: pyright
|
77
|
-
- repo: https://github.com/astral-sh/ruff-pre-commit
|
78
|
-
rev: v0.11.12
|
79
|
-
hooks:
|
80
|
-
- id: ruff-check
|
81
|
-
- id: ruff-format
|
82
88
|
# - repo: https://github.com/pdoc3/pdoc
|
83
89
|
# rev: master
|
84
90
|
# hooks:
|
Binary file
|
@@ -32,6 +32,8 @@ class Options(BaseModel):
|
|
32
32
|
clean: bool = False
|
33
33
|
test: bool = False
|
34
34
|
benchmark: bool = False
|
35
|
+
benchmark_regression: bool = False
|
36
|
+
benchmark_regression_threshold: float = 5.0
|
35
37
|
all: BumpOption | None = None
|
36
38
|
ai_agent: bool = False
|
37
39
|
create_pr: bool = False
|
@@ -90,6 +92,16 @@ cli_options = {
|
|
90
92
|
"--benchmark",
|
91
93
|
help="Run tests in benchmark mode (disables parallel execution).",
|
92
94
|
),
|
95
|
+
"benchmark_regression": typer.Option(
|
96
|
+
False,
|
97
|
+
"--benchmark-regression",
|
98
|
+
help="Fail tests if benchmarks regress beyond threshold.",
|
99
|
+
),
|
100
|
+
"benchmark_regression_threshold": typer.Option(
|
101
|
+
5.0,
|
102
|
+
"--benchmark-regression-threshold",
|
103
|
+
help="Maximum allowed performance regression percentage (default: 5.0%).",
|
104
|
+
),
|
93
105
|
"skip_hooks": typer.Option(
|
94
106
|
False,
|
95
107
|
"-s",
|
@@ -132,6 +144,10 @@ def main(
|
|
132
144
|
clean: bool = cli_options["clean"],
|
133
145
|
test: bool = cli_options["test"],
|
134
146
|
benchmark: bool = cli_options["benchmark"],
|
147
|
+
benchmark_regression: bool = cli_options["benchmark_regression"],
|
148
|
+
benchmark_regression_threshold: float = cli_options[
|
149
|
+
"benchmark_regression_threshold"
|
150
|
+
],
|
135
151
|
skip_hooks: bool = cli_options["skip_hooks"],
|
136
152
|
create_pr: bool = cli_options["create_pr"],
|
137
153
|
ai_agent: bool = cli_options["ai_agent"],
|
@@ -148,6 +164,8 @@ def main(
|
|
148
164
|
clean=clean,
|
149
165
|
test=test,
|
150
166
|
benchmark=benchmark,
|
167
|
+
benchmark_regression=benchmark_regression,
|
168
|
+
benchmark_regression_threshold=benchmark_regression_threshold,
|
151
169
|
skip_hooks=skip_hooks,
|
152
170
|
all=all,
|
153
171
|
ai_agent=ai_agent,
|
@@ -39,7 +39,9 @@ class OptionsProtocol(t.Protocol):
|
|
39
39
|
update_precommit: bool
|
40
40
|
clean: bool
|
41
41
|
test: bool
|
42
|
-
benchmark: bool
|
42
|
+
benchmark: bool
|
43
|
+
benchmark_regression: bool
|
44
|
+
benchmark_regression_threshold: float
|
43
45
|
publish: t.Any | None
|
44
46
|
bump: t.Any | None
|
45
47
|
all: t.Any | None
|
@@ -295,10 +297,10 @@ class ConfigManager:
|
|
295
297
|
for k, v in {
|
296
298
|
x: self.swap_package_name(y)
|
297
299
|
for x, y in value.items()
|
298
|
-
if isinstance(y,
|
300
|
+
if isinstance(y, str | list) and "crackerjack" in str(y)
|
299
301
|
}.items():
|
300
302
|
settings[setting][k] = v
|
301
|
-
elif isinstance(value,
|
303
|
+
elif isinstance(value, str | list) and "crackerjack" in str(value):
|
302
304
|
value = self.swap_package_name(value)
|
303
305
|
settings[setting] = value
|
304
306
|
if setting in (
|
@@ -492,9 +494,27 @@ class Crackerjack:
|
|
492
494
|
self.code_cleaner.clean_files(tests_dir)
|
493
495
|
|
494
496
|
def _prepare_pytest_command(self, options: OptionsProtocol) -> list[str]:
|
497
|
+
"""Prepare pytest command with appropriate options.
|
498
|
+
|
499
|
+
Configures pytest command with:
|
500
|
+
- Standard options for formatting and output control
|
501
|
+
- Benchmark options when benchmark mode is enabled
|
502
|
+
- Benchmark regression options when regression testing is enabled
|
503
|
+
- Parallel execution via xdist for non-benchmark tests
|
504
|
+
|
505
|
+
Benchmark and parallel execution (xdist) are incompatible, so the command
|
506
|
+
automatically disables parallelism when benchmarks are enabled.
|
507
|
+
|
508
|
+
Args:
|
509
|
+
options: Command options with benchmark and test settings
|
510
|
+
|
511
|
+
Returns:
|
512
|
+
List of command-line arguments for pytest
|
513
|
+
"""
|
495
514
|
test = ["pytest"]
|
496
515
|
if options.verbose:
|
497
516
|
test.append("-v")
|
517
|
+
|
498
518
|
test.extend(
|
499
519
|
[
|
500
520
|
"--capture=fd", # Capture stdout/stderr at file descriptor level
|
@@ -505,9 +525,27 @@ class Crackerjack:
|
|
505
525
|
"--timeout=60", # 1-minute timeout for tests
|
506
526
|
]
|
507
527
|
)
|
508
|
-
|
509
|
-
|
510
|
-
|
528
|
+
|
529
|
+
# Benchmarks and parallel testing are incompatible
|
530
|
+
# Handle them mutually exclusively
|
531
|
+
if options.benchmark or options.benchmark_regression:
|
532
|
+
# When running benchmarks, avoid parallel execution
|
533
|
+
# and apply specific benchmark options
|
534
|
+
if options.benchmark:
|
535
|
+
test.append("--benchmark")
|
536
|
+
|
537
|
+
# Add benchmark regression testing options if enabled
|
538
|
+
if options.benchmark_regression:
|
539
|
+
test.extend(
|
540
|
+
[
|
541
|
+
"--benchmark-regression",
|
542
|
+
f"--benchmark-regression-threshold={options.benchmark_regression_threshold}",
|
543
|
+
]
|
544
|
+
)
|
545
|
+
else:
|
546
|
+
# No benchmarks - use parallel execution for speed
|
547
|
+
test.append("-xvs")
|
548
|
+
|
511
549
|
return test
|
512
550
|
|
513
551
|
def _setup_test_environment(self) -> None:
|
@@ -0,0 +1,233 @@
|
|
1
|
+
[build-system]
|
2
|
+
build-backend = "pdm.backend"
|
3
|
+
requires = [ "pdm-backend" ]
|
4
|
+
|
5
|
+
[project]
|
6
|
+
name = "crackerjack"
|
7
|
+
version = "0.18.12"
|
8
|
+
description = "Crackerjack: code quality toolkit"
|
9
|
+
readme = "README.md"
|
10
|
+
keywords = [
|
11
|
+
"bandit",
|
12
|
+
"black",
|
13
|
+
"creosote",
|
14
|
+
"mypy",
|
15
|
+
"pyright",
|
16
|
+
"pytest",
|
17
|
+
"refurb",
|
18
|
+
"ruff",
|
19
|
+
]
|
20
|
+
license.text = "BSD-3-CLAUSE"
|
21
|
+
maintainers = [
|
22
|
+
{ name = "lesleslie", email = "les@wedgwoodwebworks.com" },
|
23
|
+
]
|
24
|
+
|
25
|
+
authors = [
|
26
|
+
{ name = "lesleslie", email = "les@wedgwoodwebworks.com" },
|
27
|
+
]
|
28
|
+
requires-python = ">=3.13"
|
29
|
+
classifiers = [
|
30
|
+
"Development Status :: 4 - Beta",
|
31
|
+
"Environment :: Console",
|
32
|
+
"License :: OSI Approved :: BSD License",
|
33
|
+
"Operating System :: POSIX",
|
34
|
+
"Programming Language :: Python",
|
35
|
+
"Programming Language :: Python :: 3 :: Only",
|
36
|
+
"Programming Language :: Python :: 3.13",
|
37
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
38
|
+
"Topic :: Software Development :: Quality Assurance",
|
39
|
+
"Topic :: Software Development :: Testing",
|
40
|
+
"Topic :: Utilities",
|
41
|
+
"Typing :: Typed",
|
42
|
+
]
|
43
|
+
dependencies = [
|
44
|
+
"autotyping>=24.9",
|
45
|
+
"pdm>=2.24.2",
|
46
|
+
"pdm-bump>=0.9.12",
|
47
|
+
"pre-commit>=4.2",
|
48
|
+
"pydantic>=2.11.5",
|
49
|
+
"pytest>=8.3.5",
|
50
|
+
"pytest-asyncio>=1",
|
51
|
+
"pytest-benchmark>=5.1",
|
52
|
+
"pytest-cov>=6.1.1",
|
53
|
+
"pytest-mock>=3.14.1",
|
54
|
+
"pytest-timeout>=2.4",
|
55
|
+
"pytest-xdist>=3.7",
|
56
|
+
"rich>=14",
|
57
|
+
"tomli-w>=1.2",
|
58
|
+
"typer>=0.16",
|
59
|
+
"uv>=0.7.9",
|
60
|
+
]
|
61
|
+
urls.documentation = "https://github.com/lesleslie/crackerjack"
|
62
|
+
urls.homepage = "https://github.com/lesleslie/crackerjack"
|
63
|
+
urls.repository = "https://github.com/lesleslie/crackerjack"
|
64
|
+
|
65
|
+
[tool.ruff]
|
66
|
+
target-version = "py313"
|
67
|
+
line-length = 88
|
68
|
+
fix = true
|
69
|
+
unsafe-fixes = true
|
70
|
+
|
71
|
+
show-fixes = true
|
72
|
+
output-format = "full"
|
73
|
+
format.docstring-code-format = true
|
74
|
+
lint.extend-select = [
|
75
|
+
"C901",
|
76
|
+
"D",
|
77
|
+
"F", # pyflakes
|
78
|
+
"I",
|
79
|
+
"UP", # pyupgrade (includes F-string conversion)
|
80
|
+
]
|
81
|
+
lint.ignore = [
|
82
|
+
"D100",
|
83
|
+
"D101",
|
84
|
+
"D102",
|
85
|
+
"D103",
|
86
|
+
"D104",
|
87
|
+
"D105",
|
88
|
+
"D106",
|
89
|
+
"D107",
|
90
|
+
"F821",
|
91
|
+
]
|
92
|
+
lint.fixable = [ "ALL" ]
|
93
|
+
lint.unfixable = [ ]
|
94
|
+
lint.isort.no-lines-before = [
|
95
|
+
"first-party",
|
96
|
+
]
|
97
|
+
lint.mccabe.max-complexity = 13
|
98
|
+
lint.pydocstyle.convention = "google"
|
99
|
+
|
100
|
+
[tool.codespell]
|
101
|
+
skip = "*/data/*"
|
102
|
+
quiet-level = 3
|
103
|
+
ignore-words-list = "crate,uptodate,nd"
|
104
|
+
|
105
|
+
[tool.pytest.ini_options]
|
106
|
+
# Core pytest configuration
|
107
|
+
asyncio_mode = "auto"
|
108
|
+
asyncio_default_fixture_loop_scope = "function"
|
109
|
+
python_files = [ "test_*.py", "*_test.py" ]
|
110
|
+
testpaths = [ "tests", "crackerjack" ]
|
111
|
+
python_classes = [ "Test*" ]
|
112
|
+
python_functions = [ "test_*" ]
|
113
|
+
|
114
|
+
# Markers
|
115
|
+
markers = [
|
116
|
+
"unit: marks test as a unit test",
|
117
|
+
"benchmark: mark test as a benchmark (disables parallel execution)",
|
118
|
+
]
|
119
|
+
|
120
|
+
# Default timeout settings
|
121
|
+
timeout = 60
|
122
|
+
timeout_method = "thread"
|
123
|
+
|
124
|
+
# Test command options
|
125
|
+
addopts = "--cov=crackerjack --cov-report=term --cov-fail-under=80"
|
126
|
+
|
127
|
+
[tool.pytest.benchmark]
|
128
|
+
disable_gc = true
|
129
|
+
warmup = false
|
130
|
+
warmup_iterations = 0
|
131
|
+
|
132
|
+
[tool.coverage.run]
|
133
|
+
branch = false
|
134
|
+
source = [ "crackerjack" ]
|
135
|
+
data_file = ".coverage"
|
136
|
+
parallel = false
|
137
|
+
omit = [
|
138
|
+
"*/tests/*",
|
139
|
+
"*/site-packages/*",
|
140
|
+
"*/__pycache__/*",
|
141
|
+
"*/__init__.py",
|
142
|
+
"*/_version.py",
|
143
|
+
"*/conftest.py",
|
144
|
+
"*/test_*.py",
|
145
|
+
"*/_test.py",
|
146
|
+
]
|
147
|
+
|
148
|
+
[tool.coverage.report]
|
149
|
+
exclude_also = [
|
150
|
+
"pragma: no cover",
|
151
|
+
"def __repr__",
|
152
|
+
"raise NotImplementedError",
|
153
|
+
"if __name__ == .__main__.:",
|
154
|
+
"pass",
|
155
|
+
"raise ImportError",
|
156
|
+
"except ImportError",
|
157
|
+
"def __str__",
|
158
|
+
"@abstractmethod",
|
159
|
+
]
|
160
|
+
ignore_errors = false
|
161
|
+
|
162
|
+
[tool.pyright]
|
163
|
+
verboseOutput = true
|
164
|
+
include = [
|
165
|
+
"crackerjack",
|
166
|
+
]
|
167
|
+
exclude = [
|
168
|
+
"scratch",
|
169
|
+
]
|
170
|
+
extraPaths = [
|
171
|
+
".venv/lib/python3.13/site-packages/",
|
172
|
+
]
|
173
|
+
typeCheckingMode = "strict"
|
174
|
+
reportMissingTypeStubs = false
|
175
|
+
reportOptionalMemberAccess = false
|
176
|
+
reportOptionalCall = false
|
177
|
+
reportUnknownMemberType = false
|
178
|
+
reportUnknownVariableType = false
|
179
|
+
reportUnknownArgumentType = false
|
180
|
+
reportInvalidTypeForm = false
|
181
|
+
reportUnknownLambdaType = false
|
182
|
+
reportUnknownParameterType = "warning"
|
183
|
+
reportPrivateUsage = false
|
184
|
+
pythonVersion = "3.13"
|
185
|
+
pythonPlatform = "Darwin"
|
186
|
+
|
187
|
+
[tool.vulture]
|
188
|
+
min_confidence = 86
|
189
|
+
paths = [ "crackerjack" ]
|
190
|
+
ignore_names = [ "cls" ]
|
191
|
+
|
192
|
+
[tool.creosote]
|
193
|
+
paths = [
|
194
|
+
"crackerjack",
|
195
|
+
]
|
196
|
+
deps-file = "pyproject.toml"
|
197
|
+
exclude-deps = [
|
198
|
+
"pdm-bump",
|
199
|
+
"autotyping",
|
200
|
+
"pre-commit",
|
201
|
+
"pytest",
|
202
|
+
"pytest-asyncio",
|
203
|
+
"pytest-cov",
|
204
|
+
"pytest-mock",
|
205
|
+
"pytest-xdist",
|
206
|
+
"pytest-benchmark",
|
207
|
+
"pdm",
|
208
|
+
"pyfiglet",
|
209
|
+
"pyyaml",
|
210
|
+
"uv",
|
211
|
+
"tomli-w",
|
212
|
+
"google-crc32c",
|
213
|
+
"pytest-timeout",
|
214
|
+
]
|
215
|
+
|
216
|
+
[tool.refurb]
|
217
|
+
enable_all = true
|
218
|
+
|
219
|
+
[tool.bandit]
|
220
|
+
target = [
|
221
|
+
"crackerjack",
|
222
|
+
]
|
223
|
+
skips = [
|
224
|
+
"B101",
|
225
|
+
"B301",
|
226
|
+
"B311",
|
227
|
+
"B403",
|
228
|
+
"B404",
|
229
|
+
"B602",
|
230
|
+
"B603",
|
231
|
+
"B607",
|
232
|
+
"B704",
|
233
|
+
]
|