crackerjack 0.18.10__tar.gz → 0.18.12__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.
Files changed (73) hide show
  1. {crackerjack-0.18.10 → crackerjack-0.18.12}/PKG-INFO +1 -1
  2. crackerjack-0.18.12/crackerjack/.ruff_cache/0.11.12/16869036553936192448 +0 -0
  3. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/__main__.py +8 -0
  4. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/crackerjack.py +4 -0
  5. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/pyproject.toml +2 -1
  6. {crackerjack-0.18.10 → crackerjack-0.18.12}/pyproject.toml +2 -1
  7. crackerjack-0.18.12/tests/conftest.py +64 -0
  8. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/test_crackerjack.py +23 -0
  9. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/test_crackerjack_runner.py +1 -0
  10. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/test_pytest_features.py +25 -0
  11. crackerjack-0.18.10/crackerjack/.ruff_cache/0.11.12/16869036553936192448 +0 -0
  12. crackerjack-0.18.10/tests/conftest.py +0 -28
  13. {crackerjack-0.18.10 → crackerjack-0.18.12}/LICENSE +0 -0
  14. {crackerjack-0.18.10 → crackerjack-0.18.12}/README.md +0 -0
  15. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.gitignore +0 -0
  16. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.libcst.codemod.yaml +0 -0
  17. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.pdm.toml +0 -0
  18. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.pre-commit-config.yaml +0 -0
  19. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.pytest_cache/.gitignore +0 -0
  20. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.pytest_cache/CACHEDIR.TAG +0 -0
  21. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.pytest_cache/README.md +0 -0
  22. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.pytest_cache/v/cache/nodeids +0 -0
  23. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.pytest_cache/v/cache/stepwise +0 -0
  24. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/.gitignore +0 -0
  25. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
  26. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
  27. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
  28. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
  29. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
  30. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
  31. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.11.11/18187162184424859798 +0 -0
  32. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
  33. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
  34. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
  35. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
  36. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
  37. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
  38. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
  39. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
  40. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
  41. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
  42. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
  43. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
  44. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
  45. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
  46. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
  47. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
  48. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
  49. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
  50. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
  51. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
  52. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
  53. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
  54. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
  55. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
  56. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
  57. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
  58. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
  59. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
  60. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
  61. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
  62. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
  63. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  64. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
  65. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
  66. {crackerjack-0.18.10 → crackerjack-0.18.12}/crackerjack/__init__.py +0 -0
  67. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/TESTING.md +0 -0
  68. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/__init__.py +0 -0
  69. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/data/comments_sample.txt +0 -0
  70. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/data/docstrings_sample.txt +0 -0
  71. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/data/expected_comments_sample.txt +0 -0
  72. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/data/init.py +0 -0
  73. {crackerjack-0.18.10 → crackerjack-0.18.12}/tests/test_main.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crackerjack
3
- Version: 0.18.10
3
+ Version: 0.18.12
4
4
  Summary: Default template for PDM package
5
5
  Keywords: black,ruff,mypy,creosote,refurb,pyright,bandit,pytest
6
6
  Author-Email: lesleslie <les@wedgwoodwebworks.com>
@@ -31,6 +31,7 @@ class Options(BaseModel):
31
31
  update_precommit: bool = False
32
32
  clean: bool = False
33
33
  test: bool = False
34
+ benchmark: bool = False
34
35
  all: BumpOption | None = None
35
36
  ai_agent: bool = False
36
37
  create_pr: bool = False
@@ -84,6 +85,11 @@ cli_options = {
84
85
  help="Remove docstrings, line comments, and unnecessary whitespace.",
85
86
  ),
86
87
  "test": typer.Option(False, "-t", "--test", help="Run tests."),
88
+ "benchmark": typer.Option(
89
+ False,
90
+ "--benchmark",
91
+ help="Run tests in benchmark mode (disables parallel execution).",
92
+ ),
87
93
  "skip_hooks": typer.Option(
88
94
  False,
89
95
  "-s",
@@ -125,6 +131,7 @@ def main(
125
131
  bump: BumpOption | None = cli_options["bump"],
126
132
  clean: bool = cli_options["clean"],
127
133
  test: bool = cli_options["test"],
134
+ benchmark: bool = cli_options["benchmark"],
128
135
  skip_hooks: bool = cli_options["skip_hooks"],
129
136
  create_pr: bool = cli_options["create_pr"],
130
137
  ai_agent: bool = cli_options["ai_agent"],
@@ -140,6 +147,7 @@ def main(
140
147
  bump=bump,
141
148
  clean=clean,
142
149
  test=test,
150
+ benchmark=benchmark,
143
151
  skip_hooks=skip_hooks,
144
152
  all=all,
145
153
  ai_agent=ai_agent,
@@ -39,6 +39,7 @@ class OptionsProtocol(t.Protocol):
39
39
  update_precommit: bool
40
40
  clean: bool
41
41
  test: bool
42
+ benchmark: bool = False
42
43
  publish: t.Any | None
43
44
  bump: t.Any | None
44
45
  all: t.Any | None
@@ -504,6 +505,9 @@ class Crackerjack:
504
505
  "--timeout=60", # 1-minute timeout for tests
505
506
  ]
506
507
  )
508
+ # Add benchmark flag if enabled (disables parallel execution)
509
+ if options.benchmark:
510
+ test.append("--benchmark")
507
511
  return test
508
512
 
509
513
  def _setup_test_environment(self) -> None:
@@ -8,6 +8,7 @@ python_classes = ["Test*"]
8
8
  python_functions = ["test_*"]
9
9
  markers = [
10
10
  "unit: marks test as a unit test",
11
+ "benchmark: mark test as a benchmark (disables parallel execution)",
11
12
  ]
12
13
 
13
14
  [tool.coverage.run]
@@ -158,7 +159,7 @@ pythonPlatform = "Darwin"
158
159
 
159
160
  [project]
160
161
  name = "crackerjack"
161
- version = "0.18.9"
162
+ version = "0.18.11"
162
163
  description = "Default template for PDM package"
163
164
  requires-python = ">=3.13"
164
165
  readme = "README.md"
@@ -18,6 +18,7 @@ python_functions = [
18
18
  ]
19
19
  markers = [
20
20
  "unit: marks test as a unit test",
21
+ "benchmark: mark test as a benchmark (disables parallel execution)",
21
22
  ]
22
23
 
23
24
  [tool.coverage.run]
@@ -179,7 +180,7 @@ pythonPlatform = "Darwin"
179
180
 
180
181
  [project]
181
182
  name = "crackerjack"
182
- version = "0.18.10"
183
+ version = "0.18.12"
183
184
  description = "Default template for PDM package"
184
185
  requires-python = ">=3.13"
185
186
  readme = "README.md"
@@ -0,0 +1,64 @@
1
+ """Pytest configuration file with hooks for detecting slow and hanging tests."""
2
+
3
+ import time
4
+ import typing as t
5
+ from pathlib import Path
6
+
7
+ import pytest
8
+ from pytest import Config, Item, Parser
9
+
10
+
11
+ def pytest_configure(config: Config) -> None:
12
+ config.addinivalue_line(
13
+ "markers", "benchmark: mark test as a benchmark (disables parallel execution)"
14
+ )
15
+
16
+
17
+ def pytest_addoption(parser: Parser) -> None:
18
+ parser.addoption(
19
+ "--benchmark",
20
+ action="store_true",
21
+ default=False,
22
+ help="Run benchmark tests and disable parallelism",
23
+ )
24
+
25
+
26
+ def pytest_collection_modifyitems(config: Config, items: list[Item]) -> None:
27
+ benchmark_mode = t.cast(bool, config.getoption("--benchmark"))
28
+ has_benchmark_tests = any(item.get_closest_marker("benchmark") for item in items)
29
+
30
+ if benchmark_mode or has_benchmark_tests:
31
+ has_worker = hasattr(config, "workerinput")
32
+
33
+ try:
34
+ num_processes = t.cast(int, config.getoption("numprocesses"))
35
+ has_multi_processes = num_processes > 0
36
+ except Exception:
37
+ has_multi_processes = False
38
+
39
+ if has_worker or has_multi_processes:
40
+ config.option.numprocesses = 0
41
+ print(
42
+ "Benchmark tests detected: Disabling parallel execution for accurate timing"
43
+ )
44
+
45
+
46
+ @pytest.hookimpl(trylast=True)
47
+ def pytest_runtest_setup(item: t.Any) -> None:
48
+ item._start_time = time.time()
49
+ print(f"Starting test: {item.name}")
50
+
51
+
52
+ @pytest.hookimpl(trylast=True)
53
+ def pytest_runtest_teardown(item: t.Any) -> None:
54
+ if hasattr(item, "_start_time"):
55
+ duration = time.time() - item._start_time
56
+ if duration > 10:
57
+ print(f"SLOW TEST: {item.name} took {duration:.2f}s")
58
+ else:
59
+ print(f"Test completed: {item.name} in {duration:.2f}s")
60
+
61
+
62
+ @pytest.hookimpl(trylast=True)
63
+ def pytest_runtest_protocol(item: t.Any) -> None:
64
+ Path(".current_test").write_text(f"Current test: {item.name}")
@@ -37,6 +37,7 @@ class OptionsForTesting:
37
37
  update_precommit: bool = False
38
38
  clean: bool = False
39
39
  test: bool = False
40
+ benchmark: bool = False
40
41
  all: BumpOption | None = None
41
42
  ai_agent: bool = False
42
43
  create_pr: bool = False
@@ -1148,3 +1149,25 @@ class TestCrackerjackProcess:
1148
1149
  assert "crackerjack" not in (pkg_path / config).read_text()
1149
1150
  assert "test_package" in (pkg_path / config).read_text()
1150
1151
  mock_cm_execute.assert_any_call(["git", "add", config])
1152
+
1153
+ def test_prepare_pytest_command_with_benchmark(
1154
+ self,
1155
+ mock_execute: MagicMock,
1156
+ mock_console_print: MagicMock,
1157
+ tmp_path: Path,
1158
+ tmp_path_package: Path,
1159
+ create_package_dir: None,
1160
+ options_factory: t.Callable[..., OptionsForTesting],
1161
+ ) -> None:
1162
+ crackerjack = Crackerjack(
1163
+ pkg_path=tmp_path_package,
1164
+ console=Console(force_terminal=True),
1165
+ )
1166
+
1167
+ options = options_factory(test=True, benchmark=False)
1168
+ test_command = crackerjack._prepare_pytest_command(options)
1169
+ assert "--benchmark" not in test_command
1170
+
1171
+ options = options_factory(test=True, benchmark=True)
1172
+ test_command = crackerjack._prepare_pytest_command(options)
1173
+ assert "--benchmark" in test_command
@@ -25,6 +25,7 @@ class MockOptions:
25
25
  self.ai_agent = kwargs.get("ai_agent", False)
26
26
  self.create_pr = kwargs.get("create_pr", False)
27
27
  self.skip_hooks = kwargs.get("skip_hooks", False)
28
+ self.benchmark = kwargs.get("benchmark", False)
28
29
 
29
30
 
30
31
  def test_create_crackerjack_runner() -> None:
@@ -39,3 +39,28 @@ def test_slow_but_not_hanging() -> None:
39
39
  def test_hanging() -> None:
40
40
  while True:
41
41
  time.sleep(1)
42
+
43
+
44
+ @pytest.mark.benchmark
45
+ def test_benchmark_marker() -> None:
46
+ start_time = time.time()
47
+ time.sleep(0.1)
48
+ end_time = time.time()
49
+ duration = end_time - start_time
50
+ assert duration >= 0.1
51
+
52
+
53
+ @pytest.mark.benchmark
54
+ class TestBenchmarkClass:
55
+ def test_benchmark_in_class(self) -> None:
56
+ assert True
57
+
58
+ def test_benchmark_with_timing(self) -> None:
59
+ results: list[float] = []
60
+ for _ in range(5):
61
+ start = time.time()
62
+ sum(range(10000))
63
+ end = time.time()
64
+ results.append(end - start)
65
+
66
+ assert max(results) - min(results) < 0.1
@@ -1,28 +0,0 @@
1
- """Pytest configuration file with hooks for detecting slow and hanging tests."""
2
-
3
- import time
4
- from pathlib import Path
5
- from typing import Any
6
-
7
- import pytest
8
-
9
-
10
- @pytest.hookimpl(trylast=True)
11
- def pytest_runtest_setup(item: Any) -> None:
12
- item._start_time = time.time()
13
- print(f"Starting test: {item.name}")
14
-
15
-
16
- @pytest.hookimpl(trylast=True)
17
- def pytest_runtest_teardown(item: Any) -> None:
18
- if hasattr(item, "_start_time"):
19
- duration = time.time() - item._start_time
20
- if duration > 10:
21
- print(f"SLOW TEST: {item.name} took {duration:.2f}s")
22
- else:
23
- print(f"Test completed: {item.name} in {duration:.2f}s")
24
-
25
-
26
- @pytest.hookimpl(trylast=True)
27
- def pytest_runtest_protocol(item: Any) -> None:
28
- Path(".current_test").write_text(f"Current test: {item.name}")
File without changes
File without changes