crackerjack 0.13.2__py3-none-any.whl → 0.14.0__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/__init__.py CHANGED
@@ -1,4 +1,5 @@
1
1
  from typing import Sequence
2
+
2
3
  from .crackerjack import Crackerjack, crackerjack_it
3
4
 
4
5
  __all__: Sequence[str] = ["crackerjack_it", "Crackerjack"]
crackerjack/__main__.py CHANGED
@@ -1,5 +1,6 @@
1
1
  import typing as t
2
2
  from enum import Enum
3
+
3
4
  import typer
4
5
  from pydantic import BaseModel, field_validator
5
6
  from rich.console import Console
@@ -1,13 +1,16 @@
1
- import ast
1
+ import io
2
2
  import platform
3
3
  import re
4
4
  import subprocess
5
+ import tokenize
5
6
  import typing as t
6
7
  from contextlib import suppress
7
8
  from pathlib import Path
8
9
  from subprocess import CompletedProcess
9
10
  from subprocess import run as execute
11
+ from token import STRING
10
12
  from tomllib import loads
13
+
11
14
  from pydantic import BaseModel
12
15
  from rich.console import Console
13
16
  from tomli_w import dumps
@@ -30,6 +33,12 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
30
33
  pkg_dir.parent.joinpath("__pycache__").rmdir()
31
34
 
32
35
  def clean_file(self, file_path: Path) -> None:
36
+ try:
37
+ if file_path.resolve() == Path(__file__).resolve():
38
+ print(f"Skipping cleaning of {file_path} (self file).")
39
+ return
40
+ except Exception as e:
41
+ print(f"Error comparing file paths: {e}")
33
42
  try:
34
43
  code = file_path.read_text()
35
44
  code = self.remove_docstrings(code)
@@ -41,36 +50,50 @@ class CodeCleaner(BaseModel, arbitrary_types_allowed=True):
41
50
  except Exception as e:
42
51
  print(f"Error cleaning {file_path}: {e}")
43
52
 
44
- def remove_docstrings(self, code: str) -> str:
45
- tree = ast.parse(code)
46
- for node in ast.walk(tree):
47
- if isinstance(
48
- node, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef, ast.Module)
49
- ):
50
- if ast.get_docstring(node):
51
- node.body = (
52
- node.body[1:]
53
- if isinstance(node.body[0], ast.Expr)
54
- else node.body
55
- )
56
- return ast.unparse(tree)
57
-
58
53
  def remove_line_comments(self, code: str) -> str:
59
- lines = code.split("\n")
60
- cleaned_lines = []
61
- for line in lines:
62
- comment_match = re.search("(?<!\\S)#(.*)", line)
63
- if comment_match is None:
64
- cleaned_lines.append(line)
54
+ new_lines = []
55
+ for line in code.splitlines():
56
+ if "#" not in line:
57
+ new_lines.append(line)
65
58
  continue
66
- comment_start = comment_match.start()
67
- code_part = line[:comment_start].rstrip()
68
- comment = line[comment_start:].strip()
69
- if re.match("^#\\s*(?:type: ignore|noqa)(?:\\[[^\\]]*\\])?", comment):
70
- cleaned_lines.append(line)
71
- elif code_part:
72
- cleaned_lines.append(code_part)
73
- return "\n".join(cleaned_lines)
59
+ idx = line.find("#")
60
+ code_part = line[:idx].rstrip()
61
+ comment_part = line[idx:]
62
+ if "type: ignore" in comment_part or "noqa" in comment_part:
63
+ new_lines.append(line)
64
+ else:
65
+ if code_part:
66
+ new_lines.append(code_part)
67
+ return "\n".join(new_lines)
68
+
69
+ def remove_docstrings(self, source: str) -> str:
70
+ try:
71
+ io_obj = io.StringIO(source)
72
+ output_tokens = []
73
+ first_token_stack = [True]
74
+ tokens = list(tokenize.generate_tokens(io_obj.readline))
75
+ for tok in tokens:
76
+ token_type = tok.type
77
+ if token_type == tokenize.INDENT:
78
+ first_token_stack.append(True)
79
+ elif token_type == tokenize.DEDENT:
80
+ if len(first_token_stack) > 1:
81
+ first_token_stack.pop()
82
+ if token_type == STRING and first_token_stack[-1]:
83
+ first_token_stack[-1] = False
84
+ continue
85
+ else:
86
+ if token_type not in (
87
+ tokenize.NEWLINE,
88
+ tokenize.NL,
89
+ tokenize.COMMENT,
90
+ ):
91
+ first_token_stack[-1] = False
92
+ output_tokens.append(tok)
93
+ return tokenize.untokenize(output_tokens)
94
+ except Exception as e:
95
+ self.console.print(f"Error removing docstrings: {e}")
96
+ return source
74
97
 
75
98
  def remove_extra_whitespace(self, code: str) -> str:
76
99
  lines = code.split("\n")
@@ -375,7 +398,10 @@ class Crackerjack(BaseModel, arbitrary_types_allowed=True):
375
398
  def _run_tests(self, options: t.Any) -> None:
376
399
  if options.test:
377
400
  self.console.print("\n\nRunning tests...\n")
378
- result = self.execute_command(["pytest"], capture_output=True, text=True)
401
+ test = ["pytest"]
402
+ if options.verbose:
403
+ test.append("-v")
404
+ result = self.execute_command(test, capture_output=True, text=True)
379
405
  if result.stdout:
380
406
  self.console.print(result.stdout)
381
407
  if result.returncode > 0:
@@ -120,7 +120,7 @@ pythonPlatform = "Darwin"
120
120
 
121
121
  [project]
122
122
  name = "crackerjack"
123
- version = "0.13.1"
123
+ version = "0.13.2"
124
124
  description = "Default template for PDM package"
125
125
  requires-python = ">=3.13"
126
126
  readme = "README.md"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: crackerjack
3
- Version: 0.13.2
3
+ Version: 0.14.0
4
4
  Summary: Default template for PDM package
5
5
  Keywords: black,ruff,mypy,creosote,refurb
6
6
  Author-Email: lesleslie <les@wedgwoodwebworks.com>
@@ -167,7 +167,7 @@ Run Crackerjack from the root of your Python project using:
167
167
  - `-n`, `--no-config-updates`: Skip updating configuration files (e.g., `pyproject.toml`).
168
168
  - `-u`, `--update-precommit`: Update pre-commit hooks to the latest versions.
169
169
  - `-d`, `--doc`: Generate documentation. (not yet implemented)
170
- - `-v`, `--verbose`: Enable verbose output. (not yet implemented)
170
+ - `-v`, `--verbose`: Enable verbose output.
171
171
  - `-p`, `--publish <micro|minor|major>`: Bump the project version and publish to PyPI using PDM.
172
172
  - `-b`, `--bump <micro|minor|major>`: Bump the project version without publishing.
173
173
  - `-x`, `--clean`: Clean code by removing docstrings, line comments, and extra whitespace.
@@ -1,7 +1,7 @@
1
- crackerjack-0.13.2.dist-info/METADATA,sha256=wEBnFSqrBfeQmQmSASdtlVbgP-jg7Xim7wNvGK5v0iA,11055
2
- crackerjack-0.13.2.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
- crackerjack-0.13.2.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
- crackerjack-0.13.2.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
1
+ crackerjack-0.14.0.dist-info/METADATA,sha256=TUmJc-8CeMFVjOztSWpLiRuGDCHtWGAjLuOxsdzw3Dw,11033
2
+ crackerjack-0.14.0.dist-info/WHEEL,sha256=thaaA2w1JzcGC48WYufAs8nrYZjJm8LqNfnXFOFyCC4,90
3
+ crackerjack-0.14.0.dist-info/entry_points.txt,sha256=6OYgBcLyFCUgeqLgnvMyOJxPCWzgy7se4rLPKtNonMs,34
4
+ crackerjack-0.14.0.dist-info/licenses/LICENSE,sha256=fDt371P6_6sCu7RyqiZH_AhT1LdN3sN1zjBtqEhDYCk,1531
5
5
  crackerjack/.coverage,sha256=dLzPzp72qZEXohNfxnOAlRwvM9dqF06-HoFqfvXZd1U,53248
6
6
  crackerjack/.gitignore,sha256=l8ErBAypC3rI6N9lhc7ZMdOw87t0Tz69ZW5C6uj15Wg,214
7
7
  crackerjack/.libcst.codemod.yaml,sha256=a8DlErRAIPV1nE6QlyXPAzTOgkB24_spl2E9hphuf5s,772
@@ -40,13 +40,13 @@ crackerjack/.ruff_cache/0.7.1/1024065805990144819,sha256=3Sww592NB0PWBNHU_UIqvqg
40
40
  crackerjack/.ruff_cache/0.7.1/285614542852677309,sha256=mOHKRzKoSvW-1sHtqI_LHWRt-mBinJ4rQRtp9Yqzv5I,224
41
41
  crackerjack/.ruff_cache/0.7.3/16061516852537040135,sha256=AWJR9gmaO7-wpv8mY1homuwI8CrMPI3VrnbXH-wRPlg,224
42
42
  crackerjack/.ruff_cache/0.8.4/16354268377385700367,sha256=Ksz4X8N6Z1i83N0vV1PxmBRlqgjrtzmDCOg7VBF4baQ,224
43
- crackerjack/.ruff_cache/0.9.10/12813592349865671909,sha256=wd08QGUlhZnKU3yNc5PIkPWnlUq0x4qi5AAXJJTi010,224
43
+ crackerjack/.ruff_cache/0.9.10/12813592349865671909,sha256=6yRYi5XvzLtzUymRBm6-DozDE48eJtLmaLGSghgY3Wo,224
44
44
  crackerjack/.ruff_cache/0.9.3/13948373885254993391,sha256=kGhtIkzPUtKAgvlKs3D8j4QM4qG8RhsHrmQJI69Sv3o,224
45
45
  crackerjack/.ruff_cache/0.9.9/12813592349865671909,sha256=tmr8_vhRD2OxsVuMfbJPdT9fDFX-d5tfC5U9jgziyho,224
46
46
  crackerjack/.ruff_cache/0.9.9/8843823720003377982,sha256=e4ymkXfQsUg5e_mtO34xTsaTvs1uA3_fI216Qq9qCAM,136
47
47
  crackerjack/.ruff_cache/CACHEDIR.TAG,sha256=WVMVbX4MVkpCclExbq8m-IcOZIOuIZf5FrYw5Pk-Ma4,43
48
- crackerjack/__init__.py,sha256=EOKnIXfBAvxS55uPkpk5DbcNqVS29wja_IcCPaGwyus,141
49
- crackerjack/__main__.py,sha256=11gg9itMrUY7-7vPFGc1MrNOuOFIzdm0vheW_PMS_Gk,3783
50
- crackerjack/crackerjack.py,sha256=xz0akxI2uDw3kt3W_UbvxRW4o4_6Y4fjZjLmpw03DoE,17985
51
- crackerjack/pyproject.toml,sha256=1vI6Ud1wHi7VVs3xfhtNzN3MvxLeJfOj-rpXS409Yv0,3438
52
- crackerjack-0.13.2.dist-info/RECORD,,
48
+ crackerjack/__init__.py,sha256=XTWW_XQkWR6dSydFSLg-T--eY3TPKUp4jUwZP11kgwY,142
49
+ crackerjack/__main__.py,sha256=7SHrcRFYhMaSV0S-EG8q2w8udURwdvIsS7vi9AW4naU,3784
50
+ crackerjack/crackerjack.py,sha256=bOZWuZ3nRbpXCz7ML2fL_WOcaUwLoyWlHh86QiWiAdY,18914
51
+ crackerjack/pyproject.toml,sha256=7WKCAe445X4JLfYvksdVAXXd8zg5TYWRJPxmf5o4968,3438
52
+ crackerjack-0.14.0.dist-info/RECORD,,