crackerjack 0.18.12__py3-none-any.whl → 0.19.1__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.
- crackerjack/.pre-commit-config.yaml +19 -13
- crackerjack/.ruff_cache/0.11.12/4441409093023629623 +0 -0
- crackerjack/__main__.py +18 -0
- crackerjack/crackerjack.py +44 -6
- crackerjack/pyproject.toml +187 -179
- {crackerjack-0.18.12.dist-info → crackerjack-0.19.1.dist-info}/METADATA +64 -19
- {crackerjack-0.18.12.dist-info → crackerjack-0.19.1.dist-info}/RECORD +10 -9
- {crackerjack-0.18.12.dist-info → crackerjack-0.19.1.dist-info}/WHEEL +0 -0
- {crackerjack-0.18.12.dist-info → crackerjack-0.19.1.dist-info}/entry_points.txt +0 -0
- {crackerjack-0.18.12.dist-info → crackerjack-0.19.1.dist-info}/licenses/LICENSE +0 -0
@@ -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
|
crackerjack/__main__.py
CHANGED
@@ -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,
|
crackerjack/crackerjack.py
CHANGED
@@ -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:
|
crackerjack/pyproject.toml
CHANGED
@@ -1,147 +1,174 @@
|
|
1
|
-
[
|
2
|
-
|
3
|
-
|
4
|
-
python_files = ["test_*.py", "*_test.py"]
|
5
|
-
asyncio_mode = "auto"
|
6
|
-
testpaths = ["tests", "crackerjack"]
|
7
|
-
python_classes = ["Test*"]
|
8
|
-
python_functions = ["test_*"]
|
9
|
-
markers = [
|
10
|
-
"unit: marks test as a unit test",
|
11
|
-
"benchmark: mark test as a benchmark (disables parallel execution)",
|
12
|
-
]
|
13
|
-
|
14
|
-
[tool.coverage.run]
|
15
|
-
branch = false
|
16
|
-
source = ["crackerjack"]
|
17
|
-
data_file = ".coverage"
|
18
|
-
parallel = false
|
19
|
-
omit = [
|
20
|
-
"*/tests/*",
|
21
|
-
"*/site-packages/*",
|
22
|
-
"*/__pycache__/*",
|
23
|
-
"*/__init__.py",
|
24
|
-
"*/_version.py", "*/conftest.py", "*/test_*.py", "*/_test.py"
|
25
|
-
]
|
1
|
+
[build-system]
|
2
|
+
build-backend = "pdm.backend"
|
3
|
+
requires = [ "pdm-backend" ]
|
26
4
|
|
27
|
-
[
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
5
|
+
[project]
|
6
|
+
name = "crackerjack"
|
7
|
+
version = "0.19.0"
|
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
|
+
]
|
40
24
|
|
41
|
-
[
|
42
|
-
|
43
|
-
|
44
|
-
|
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"
|
45
64
|
|
46
65
|
[tool.ruff]
|
47
|
-
line-length = 88
|
48
66
|
target-version = "py313"
|
67
|
+
line-length = 88
|
49
68
|
fix = true
|
69
|
+
unsafe-fixes = true
|
70
|
+
|
50
71
|
show-fixes = true
|
51
72
|
output-format = "full"
|
52
|
-
|
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"
|
53
99
|
|
54
|
-
[tool.
|
55
|
-
|
100
|
+
[tool.codespell]
|
101
|
+
skip = "*/data/*"
|
102
|
+
quiet-level = 3
|
103
|
+
ignore-words-list = "crate,uptodate,nd"
|
56
104
|
|
57
|
-
[tool.
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
"D105",
|
66
|
-
"D106",
|
67
|
-
"D107",
|
68
|
-
]
|
69
|
-
extend-select = [
|
70
|
-
"I",
|
71
|
-
"C901",
|
72
|
-
"D",
|
73
|
-
]
|
74
|
-
fixable = ["ALL"]
|
75
|
-
unfixable = []
|
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_*" ]
|
76
113
|
|
77
|
-
|
78
|
-
|
79
|
-
|
114
|
+
# Markers
|
115
|
+
markers = [
|
116
|
+
"unit: marks test as a unit test",
|
117
|
+
"benchmark: mark test as a benchmark (disables parallel execution)",
|
80
118
|
]
|
81
119
|
|
82
|
-
|
83
|
-
|
120
|
+
# Default timeout settings
|
121
|
+
timeout = 60
|
122
|
+
timeout_method = "thread"
|
84
123
|
|
85
|
-
|
86
|
-
|
124
|
+
# Test command options
|
125
|
+
addopts = "--cov=crackerjack --cov-report=term --cov-fail-under=80"
|
87
126
|
|
88
|
-
[tool.
|
89
|
-
|
90
|
-
|
91
|
-
|
127
|
+
[tool.pytest.benchmark]
|
128
|
+
disable_gc = true
|
129
|
+
warmup = false
|
130
|
+
warmup_iterations = 0
|
92
131
|
|
93
|
-
[tool.
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
"pdm",
|
108
|
-
"pyfiglet",
|
109
|
-
"pyyaml",
|
110
|
-
"uv",
|
111
|
-
"tomli-w",
|
112
|
-
"google-crc32c",
|
113
|
-
"pytest-timeout",
|
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",
|
114
146
|
]
|
115
147
|
|
116
|
-
[tool.
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
"B403",
|
128
|
-
"B404",
|
129
|
-
"B602",
|
130
|
-
"B603",
|
131
|
-
"B607",
|
132
|
-
"B704",
|
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",
|
133
159
|
]
|
160
|
+
ignore_errors = false
|
134
161
|
|
135
162
|
[tool.pyright]
|
136
163
|
verboseOutput = true
|
137
164
|
include = [
|
138
|
-
|
165
|
+
"crackerjack",
|
139
166
|
]
|
140
167
|
exclude = [
|
141
|
-
|
168
|
+
"scratch",
|
142
169
|
]
|
143
170
|
extraPaths = [
|
144
|
-
|
171
|
+
".venv/lib/python3.13/site-packages/",
|
145
172
|
]
|
146
173
|
typeCheckingMode = "strict"
|
147
174
|
reportMissingTypeStubs = false
|
@@ -157,69 +184,50 @@ reportPrivateUsage = false
|
|
157
184
|
pythonVersion = "3.13"
|
158
185
|
pythonPlatform = "Darwin"
|
159
186
|
|
160
|
-
[
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
"ruff",
|
169
|
-
"mypy",
|
170
|
-
"creosote",
|
171
|
-
"refurb",
|
172
|
-
"pyright",
|
173
|
-
"bandit",
|
174
|
-
"pytest",
|
175
|
-
]
|
176
|
-
classifiers = [
|
177
|
-
"Environment :: Console",
|
178
|
-
"Operating System :: POSIX",
|
179
|
-
"Programming Language :: Python",
|
180
|
-
"Programming Language :: Python :: 3.13",
|
181
|
-
"Development Status :: 4 - Beta",
|
182
|
-
"Topic :: Software Development :: Libraries :: Python Modules",
|
183
|
-
"Topic :: Software Development :: Quality Assurance",
|
184
|
-
"Topic :: Software Development :: Testing",
|
185
|
-
"Topic :: Utilities",
|
186
|
-
"Topic :: Software Development :: Libraries :: Python Modules",
|
187
|
-
"License :: OSI Approved :: BSD License",
|
188
|
-
"Typing :: Typed",
|
189
|
-
]
|
190
|
-
dependencies = [
|
191
|
-
"autotyping>=24.9.0",
|
192
|
-
"pre-commit>=4.2.0",
|
193
|
-
"pytest>=8.3.5",
|
194
|
-
"pydantic>=2.11.5",
|
195
|
-
"pdm-bump>=0.9.12",
|
196
|
-
"pdm>=2.24.2",
|
197
|
-
"uv>=0.7.9",
|
198
|
-
"pytest-cov>=6.1.1",
|
199
|
-
"pytest-mock>=3.14.1",
|
200
|
-
"tomli-w>=1.2.0",
|
201
|
-
"pytest-asyncio>=1.0.0",
|
202
|
-
"rich>=14.0.0",
|
203
|
-
"typer>=0.16.0",
|
204
|
-
"pytest-timeout>=2.4.0",
|
205
|
-
"pytest-xdist>=3.7.0",
|
206
|
-
]
|
207
|
-
authors = [
|
208
|
-
{ name = "lesleslie", email = "les@wedgwoodwebworks.com" },
|
187
|
+
[tool.vulture]
|
188
|
+
min_confidence = 86
|
189
|
+
paths = [ "crackerjack" ]
|
190
|
+
ignore_names = [ "cls" ]
|
191
|
+
|
192
|
+
[tool.creosote]
|
193
|
+
paths = [
|
194
|
+
"crackerjack",
|
209
195
|
]
|
210
|
-
|
211
|
-
|
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",
|
212
214
|
]
|
213
215
|
|
214
|
-
[
|
215
|
-
|
216
|
-
|
217
|
-
[project.urls]
|
218
|
-
homepage = "https://github.com/lesleslie/crackerjack"
|
219
|
-
documentation = "https://github.com/lesleslie/crackerjack"
|
220
|
-
repository = "https://github.com/lesleslie/crackerjack"
|
221
|
-
|
216
|
+
[tool.refurb]
|
217
|
+
enable_all = true
|
222
218
|
|
223
|
-
[
|
224
|
-
|
225
|
-
|
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
|
+
]
|
@@ -1,42 +1,43 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: crackerjack
|
3
|
-
Version: 0.
|
4
|
-
Summary:
|
5
|
-
Keywords: black,
|
3
|
+
Version: 0.19.1
|
4
|
+
Summary: Crackerjack: code quality toolkit
|
5
|
+
Keywords: bandit,black,creosote,mypy,pyright,pytest,refurb,ruff
|
6
6
|
Author-Email: lesleslie <les@wedgwoodwebworks.com>
|
7
7
|
Maintainer-Email: lesleslie <les@wedgwoodwebworks.com>
|
8
8
|
License: BSD-3-CLAUSE
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
9
10
|
Classifier: Environment :: Console
|
11
|
+
Classifier: License :: OSI Approved :: BSD License
|
10
12
|
Classifier: Operating System :: POSIX
|
11
13
|
Classifier: Programming Language :: Python
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
12
15
|
Classifier: Programming Language :: Python :: 3.13
|
13
|
-
Classifier: Development Status :: 4 - Beta
|
14
16
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
15
17
|
Classifier: Topic :: Software Development :: Quality Assurance
|
16
18
|
Classifier: Topic :: Software Development :: Testing
|
17
19
|
Classifier: Topic :: Utilities
|
18
|
-
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
19
|
-
Classifier: License :: OSI Approved :: BSD License
|
20
20
|
Classifier: Typing :: Typed
|
21
|
-
Project-URL: homepage, https://github.com/lesleslie/crackerjack
|
22
21
|
Project-URL: documentation, https://github.com/lesleslie/crackerjack
|
22
|
+
Project-URL: homepage, https://github.com/lesleslie/crackerjack
|
23
23
|
Project-URL: repository, https://github.com/lesleslie/crackerjack
|
24
24
|
Requires-Python: >=3.13
|
25
|
-
Requires-Dist: autotyping>=24.9
|
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
|
25
|
+
Requires-Dist: autotyping>=24.9
|
30
26
|
Requires-Dist: pdm>=2.24.2
|
31
|
-
Requires-Dist:
|
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
|
32
33
|
Requires-Dist: pytest-cov>=6.1.1
|
33
34
|
Requires-Dist: pytest-mock>=3.14.1
|
34
|
-
Requires-Dist:
|
35
|
-
Requires-Dist: pytest-
|
36
|
-
Requires-Dist: rich>=14
|
37
|
-
Requires-Dist:
|
38
|
-
Requires-Dist:
|
39
|
-
Requires-Dist:
|
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
|
40
41
|
Description-Content-Type: text/markdown
|
41
42
|
|
42
43
|
# Crackerjack: Elevate Your Python Development
|
@@ -176,6 +177,44 @@ Crackerjack projects adhere to these guidelines:
|
|
176
177
|
- **Clear Code:** Avoid overly complex code.
|
177
178
|
- **Modular:** Functions should do one thing well.
|
178
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
|
+
|
179
218
|
## Installation
|
180
219
|
|
181
220
|
1. **Python:** Ensure you have Python 3.13 installed.
|
@@ -226,6 +265,9 @@ class MyOptions:
|
|
226
265
|
# Process options
|
227
266
|
self.clean = True # Clean code (remove docstrings, comments, etc.)
|
228
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
|
229
271
|
self.skip_hooks = False # Skip running pre-commit hooks
|
230
272
|
|
231
273
|
# Version and publishing options
|
@@ -266,6 +308,9 @@ runner.process(MyOptions())
|
|
266
308
|
- `-s`, `--skip-hooks`: Skip running pre-commit hooks (useful with `-t`).
|
267
309
|
- `-x`, `--clean`: Clean code by removing docstrings, line comments, and extra whitespace.
|
268
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%).
|
269
314
|
- `-a`, `--all`: Run with `-x -t -p <micro|minor|major> -c` development options.
|
270
315
|
- `--ai-agent`: Enable AI agent mode with structured output (see [AI Agent Integration](#ai-agent-integration)).
|
271
316
|
- `--help`: Display help.
|
@@ -1,11 +1,11 @@
|
|
1
|
-
crackerjack-0.
|
2
|
-
crackerjack-0.
|
3
|
-
crackerjack-0.
|
4
|
-
crackerjack-0.
|
1
|
+
crackerjack-0.19.1.dist-info/METADATA,sha256=euP5RNzd6Ww8Rhi9bvlOKXVLNhe2RHUgEsjgTLMSyYI,20079
|
2
|
+
crackerjack-0.19.1.dist-info/WHEEL,sha256=tSfRZzRHthuv7vxpI4aehrdN9scLjk-dCJkPLzkHxGg,90
|
3
|
+
crackerjack-0.19.1.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
|
4
|
+
crackerjack-0.19.1.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
|
5
5
|
crackerjack/.gitignore,sha256=oho3dNx7a7y36_y9AsalCkssU4in0MMsNAANWdc-h1c,153
|
6
6
|
crackerjack/.libcst.codemod.yaml,sha256=a8DlErRAIPV1nE6QlyXPAzTOgkB24_spl2E9hphuf5s,772
|
7
7
|
crackerjack/.pdm.toml,sha256=dZe44HRcuxxCFESGG8SZIjmc-cGzSoyK3Hs6t4NYA8w,23
|
8
|
-
crackerjack/.pre-commit-config.yaml,sha256=
|
8
|
+
crackerjack/.pre-commit-config.yaml,sha256=QSc25WQTksQ199Ww21Y3IwlxDFhJR52RD0KNldSQoGs,2621
|
9
9
|
crackerjack/.pytest_cache/.gitignore,sha256=Ptcxtl0GFQwTji2tsL4Gl1UIiKa0frjEXsya26i46b0,37
|
10
10
|
crackerjack/.pytest_cache/CACHEDIR.TAG,sha256=N9yI75oKvt2-gQU6bdj9-xOvthMEXqHrSlyBWnSjveQ,191
|
11
11
|
crackerjack/.pytest_cache/README.md,sha256=c_1vzN2ALEGaay2YPWwxc7fal1WKxLWJ7ewt_kQ9ua0,302
|
@@ -20,6 +20,7 @@ crackerjack/.ruff_cache/0.1.7/1790508110482614856,sha256=De7Puq32XF0925xrGehWSKX
|
|
20
20
|
crackerjack/.ruff_cache/0.1.9/17041001205004563469,sha256=tKP_k8HaHhQJyrHbDfJ93kM7vahjrU8cKQ1f_-OUzZY,248
|
21
21
|
crackerjack/.ruff_cache/0.11.11/18187162184424859798,sha256=rx6CoDveth9JeurkrEgbDB4U0esMrGQ7pwIi5VnKEdo,153
|
22
22
|
crackerjack/.ruff_cache/0.11.12/16869036553936192448,sha256=pYYUCDrYh7fPq8xkFLxvmz9gA55kTuRbMAmbVU4-Eco,153
|
23
|
+
crackerjack/.ruff_cache/0.11.12/4441409093023629623,sha256=k2RDJ6AR_Loq31innfQ83BOjGivQWIXKd9UqD1kuJIM,153
|
23
24
|
crackerjack/.ruff_cache/0.11.2/4070660268492669020,sha256=FTRTUmvj6nZw_QQBp_WHI-h3_iqRejzL39api-9wTvs,224
|
24
25
|
crackerjack/.ruff_cache/0.11.3/9818742842212983150,sha256=U-4mT__a-OljovvAJvv5M6X7TCMa3dReLXx3kTNGgwU,224
|
25
26
|
crackerjack/.ruff_cache/0.11.4/9818742842212983150,sha256=QF9j6-3MH_d0pDNotdbF2hlqCL66SxN8OLVKR3PZyZU,224
|
@@ -55,7 +56,7 @@ crackerjack/.ruff_cache/0.9.9/12813592349865671909,sha256=tmr8_vhRD2OxsVuMfbJPdT
|
|
55
56
|
crackerjack/.ruff_cache/0.9.9/8843823720003377982,sha256=e4ymkXfQsUg5e_mtO34xTsaTvs1uA3_fI216Qq9qCAM,136
|
56
57
|
crackerjack/.ruff_cache/CACHEDIR.TAG,sha256=WVMVbX4MVkpCclExbq8m-IcOZIOuIZf5FrYw5Pk-Ma4,43
|
57
58
|
crackerjack/__init__.py,sha256=r9SuEjHUrW99hFWifRk4ofmYPSgf9rblcnzqhdV5bP0,157
|
58
|
-
crackerjack/__main__.py,sha256=
|
59
|
-
crackerjack/crackerjack.py,sha256=
|
60
|
-
crackerjack/pyproject.toml,sha256=
|
61
|
-
crackerjack-0.
|
59
|
+
crackerjack/__main__.py,sha256=MTVu9nxSIkMgUBIlieq561PX-ts1HaNMsFaTWdLUqz0,5561
|
60
|
+
crackerjack/crackerjack.py,sha256=8sHtYljfHJy5mpC6gHAwKw5686yG8050CFzk3Ohprd4,35167
|
61
|
+
crackerjack/pyproject.toml,sha256=nxyAt3zqH-E7SRijBxKhkh0ZUdjx0yJN3MIDgcjzOCg,4534
|
62
|
+
crackerjack-0.19.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|