crackerjack 0.20.12__tar.gz → 0.20.13__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 (86) hide show
  1. {crackerjack-0.20.12 → crackerjack-0.20.13}/PKG-INFO +1 -1
  2. crackerjack-0.20.13/crackerjack/.ruff_cache/0.11.13/1867267426380906393 +0 -0
  3. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/crackerjack.py +50 -3
  4. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/pyproject.toml +1 -1
  5. {crackerjack-0.20.12 → crackerjack-0.20.13}/pyproject.toml +1 -1
  6. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/data/comments_sample.txt +1 -0
  7. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/data/expected_comments_sample.txt +1 -0
  8. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_crackerjack.py +13 -2
  9. crackerjack-0.20.12/crackerjack/.ruff_cache/0.11.13/1867267426380906393 +0 -0
  10. {crackerjack-0.20.12 → crackerjack-0.20.13}/LICENSE +0 -0
  11. {crackerjack-0.20.12 → crackerjack-0.20.13}/README.md +0 -0
  12. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.gitignore +0 -0
  13. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.libcst.codemod.yaml +0 -0
  14. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.pdm.toml +0 -0
  15. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.pre-commit-config.yaml +0 -0
  16. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.pytest_cache/.gitignore +0 -0
  17. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.pytest_cache/CACHEDIR.TAG +0 -0
  18. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.pytest_cache/README.md +0 -0
  19. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.pytest_cache/v/cache/nodeids +0 -0
  20. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.pytest_cache/v/cache/stepwise +0 -0
  21. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/.gitignore +0 -0
  22. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.1.11/3256171999636029978 +0 -0
  23. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.1.14/602324811142551221 +0 -0
  24. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.1.4/10355199064880463147 +0 -0
  25. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.1.6/15140459877605758699 +0 -0
  26. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.1.7/1790508110482614856 +0 -0
  27. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.1.9/17041001205004563469 +0 -0
  28. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.11/18187162184424859798 +0 -0
  29. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.12/16869036553936192448 +0 -0
  30. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.12/1867267426380906393 +0 -0
  31. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.12/4240757255861806333 +0 -0
  32. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.12/4441409093023629623 +0 -0
  33. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.13/4240757255861806333 +0 -0
  34. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.2/4070660268492669020 +0 -0
  35. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.3/9818742842212983150 +0 -0
  36. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.4/9818742842212983150 +0 -0
  37. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.6/3557596832929915217 +0 -0
  38. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.7/10386934055395314831 +0 -0
  39. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.7/3557596832929915217 +0 -0
  40. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.11.8/530407680854991027 +0 -0
  41. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.2.0/10047773857155985907 +0 -0
  42. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.2.1/8522267973936635051 +0 -0
  43. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.2.2/18053836298936336950 +0 -0
  44. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.3.0/12548816621480535786 +0 -0
  45. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.3.3/11081883392474770722 +0 -0
  46. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.3.4/676973378459347183 +0 -0
  47. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.3.5/16311176246009842383 +0 -0
  48. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.5.7/1493622539551733492 +0 -0
  49. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.5.7/6231957614044513175 +0 -0
  50. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.5.7/9932762556785938009 +0 -0
  51. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.6.0/11982804814124138945 +0 -0
  52. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.6.0/12055761203849489982 +0 -0
  53. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.6.2/1206147804896221174 +0 -0
  54. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.6.4/1206147804896221174 +0 -0
  55. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.6.5/1206147804896221174 +0 -0
  56. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.6.7/3657366982708166874 +0 -0
  57. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.6.9/285614542852677309 +0 -0
  58. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.7.1/1024065805990144819 +0 -0
  59. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.7.1/285614542852677309 +0 -0
  60. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.7.3/16061516852537040135 +0 -0
  61. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.8.4/16354268377385700367 +0 -0
  62. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.9.10/12813592349865671909 +0 -0
  63. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.9.10/923908772239632759 +0 -0
  64. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.9.3/13948373885254993391 +0 -0
  65. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.9.9/12813592349865671909 +0 -0
  66. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/0.9.9/8843823720003377982 +0 -0
  67. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/.ruff_cache/CACHEDIR.TAG +0 -0
  68. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/__init__.py +0 -0
  69. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/__main__.py +0 -0
  70. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/errors.py +0 -0
  71. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/interactive.py +0 -0
  72. {crackerjack-0.20.12 → crackerjack-0.20.13}/crackerjack/py313.py +0 -0
  73. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/TESTING.md +0 -0
  74. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/__init__.py +0 -0
  75. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/conftest.py +0 -0
  76. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/data/docstrings_sample.txt +0 -0
  77. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/data/init.py +0 -0
  78. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_crackerjack_runner.py +0 -0
  79. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_errors.py +0 -0
  80. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_interactive.py +0 -0
  81. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_interactive_run.py +0 -0
  82. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_main.py +0 -0
  83. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_py313_advanced.py +0 -0
  84. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_py313_features.py +0 -0
  85. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_pytest_features.py +0 -0
  86. {crackerjack-0.20.12 → crackerjack-0.20.13}/tests/test_structured_errors.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crackerjack
3
- Version: 0.20.12
3
+ Version: 0.20.13
4
4
  Summary: Crackerjack: code quality toolkit
5
5
  Keywords: bandit,black,creosote,mypy,pyright,pytest,refurb,ruff
6
6
  Author-Email: lesleslie <les@wedgwoodwebworks.com>
@@ -118,7 +118,10 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
118
118
  i += 1
119
119
  elif char == "#" and in_string is None:
120
120
  comment = line[i:].strip()
121
- if re.match("^#\\s*(?:type:\\s*ignore|noqa)\\b", comment):
121
+ if re.match(
122
+ "^#\\s*(?:type:\\s*ignore|noqa|nosec|pragma:\\s*no\\s*cover|pylint:\\s*disable|mypy:\\s*ignore)",
123
+ comment,
124
+ ):
122
125
  result.append(line[i:])
123
126
  break
124
127
  break
@@ -133,11 +136,55 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
133
136
  def remove_extra_whitespace(self, code: str) -> str:
134
137
  lines = code.split("\n")
135
138
  cleaned_lines = []
139
+ in_function = False
140
+ function_indent = 0
136
141
  for i, line in enumerate(lines):
137
142
  line = line.rstrip()
138
- if i > 0 and (not line) and (not cleaned_lines[-1]):
139
- continue
143
+ stripped_line = line.lstrip()
144
+ if stripped_line.startswith(("def ", "async def ")):
145
+ in_function = True
146
+ function_indent = len(line) - len(stripped_line)
147
+ elif (
148
+ in_function
149
+ and line
150
+ and (len(line) - len(stripped_line) <= function_indent)
151
+ and (not stripped_line.startswith(("@", "#")))
152
+ ):
153
+ in_function = False
154
+ function_indent = 0
155
+ if not line:
156
+ if i > 0 and cleaned_lines and (not cleaned_lines[-1]):
157
+ continue
158
+ if in_function:
159
+ next_line_idx = i + 1
160
+ if next_line_idx < len(lines):
161
+ next_line = lines[next_line_idx].strip()
162
+ if not (
163
+ next_line.startswith(
164
+ ("return", "class ", "def ", "async def ", "@")
165
+ )
166
+ or next_line in ("pass", "break", "continue", "raise")
167
+ or (
168
+ next_line.startswith("#")
169
+ and any(
170
+ (
171
+ pattern in next_line
172
+ for pattern in (
173
+ "type:",
174
+ "noqa",
175
+ "nosec",
176
+ "pragma:",
177
+ "pylint:",
178
+ "mypy:",
179
+ )
180
+ )
181
+ )
182
+ )
183
+ ):
184
+ continue
140
185
  cleaned_lines.append(line)
186
+ while cleaned_lines and (not cleaned_lines[-1]):
187
+ cleaned_lines.pop()
141
188
  return "\n".join(cleaned_lines)
142
189
 
143
190
  def reformat_code(self, code: str) -> str:
@@ -4,7 +4,7 @@ requires = [ "pdm-backend" ]
4
4
 
5
5
  [project]
6
6
  name = "crackerjack"
7
- version = "0.20.11"
7
+ version = "0.20.12"
8
8
  description = "Crackerjack: code quality toolkit"
9
9
  readme = "README.md"
10
10
  keywords = [
@@ -6,7 +6,7 @@ requires = [
6
6
 
7
7
  [project]
8
8
  name = "crackerjack"
9
- version = "0.20.12"
9
+ version = "0.20.13"
10
10
  description = "Crackerjack: code quality toolkit"
11
11
  readme = "README.md"
12
12
  keywords = [
@@ -4,6 +4,7 @@ def test_func():
4
4
  # Full line comment
5
5
  x = 1 # type: ignore
6
6
  y = 2 # noqa
7
+ z = subprocess.run(["rm", "-rf", user_input]) # nosec
7
8
 
8
9
 
9
10
  class AsyncRedisBytecodeCache(AsyncBytecodeCache):
@@ -3,6 +3,7 @@ def test_func():
3
3
 
4
4
  x = 1 # type: ignore
5
5
  y = 2 # noqa
6
+ z = subprocess.run(["rm", "-rf", user_input]) # nosec
6
7
 
7
8
 
8
9
  class AsyncRedisBytecodeCache(AsyncBytecodeCache):
@@ -1068,12 +1068,23 @@ class TestCrackerjackProcess:
1068
1068
 
1069
1069
  code_cleaner = CodeCleaner(console=Console())
1070
1070
  code_with_whitespace = (
1071
- "def test_func():\n return True\n \n \n x = 1\n "
1071
+ "def test_func():\n x = 1\n\n\n y = 2\n\n return x + y\n\n\n"
1072
1072
  )
1073
1073
  cleaned_code = code_cleaner.remove_extra_whitespace(code_with_whitespace)
1074
1074
  assert "def test_func():" in cleaned_code, f"Got: {cleaned_code!r}"
1075
- assert "return True" in cleaned_code, f"Got: {cleaned_code!r}"
1076
1075
  assert "x = 1" in cleaned_code, f"Got: {cleaned_code!r}"
1076
+ assert "y = 2" in cleaned_code, f"Got: {cleaned_code!r}"
1077
+ assert "\n\n\n" not in cleaned_code, (
1078
+ f"Triple newlines should be removed: {cleaned_code!r}"
1079
+ )
1080
+ assert "y = 2\n\n return x + y" in cleaned_code, (
1081
+ f"Should keep blank before return: {cleaned_code!r}"
1082
+ )
1083
+ code_with_classes = "class TestClass:\n\n\n def method1(self):\n pass\n\n\n def method2(self):\n return True\n\n"
1084
+ cleaned_class_code = code_cleaner.remove_extra_whitespace(code_with_classes)
1085
+ assert "class TestClass:" in cleaned_class_code
1086
+ assert "def method1(self):" in cleaned_class_code
1087
+ assert "def method2(self):" in cleaned_class_code
1077
1088
 
1078
1089
  def test_code_cleaner_reformat_code_success(
1079
1090
  self, mock_execute: MagicMock, mock_console_print: MagicMock, tmp_path: Path
File without changes
File without changes