auto-walrus 0.3.3__py3-none-any.whl → 0.4.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.

Potentially problematic release.


This version of auto-walrus might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: auto-walrus
3
- Version: 0.3.3
3
+ Version: 0.4.0
4
4
  Summary: Automatically apply the awesome walrus operator
5
5
  Project-URL: Homepage, https://github.com/MarcoGorelli/auto-walrus
6
6
  Project-URL: Bug Tracker, https://github.com/MarcoGorelli/auto-walrus
@@ -10,6 +10,7 @@ Classifier: License :: OSI Approved :: MIT License
10
10
  Classifier: Operating System :: OS Independent
11
11
  Classifier: Programming Language :: Python :: 3
12
12
  Requires-Python: >=3.8
13
+ Requires-Dist: tomli; python_version < '3.11'
13
14
  Description-Content-Type: text/markdown
14
15
 
15
16
  <h1 align="center">
@@ -44,7 +45,7 @@ Sample `.pre-commit-config.yaml`:
44
45
 
45
46
  ```yaml
46
47
  - repo: https://github.com/MarcoGorelli/auto-walrus
47
- rev: v0.2.2
48
+ rev: 0.4.0
48
49
  hooks:
49
50
  - id: auto-walrus
50
51
  ```
@@ -0,0 +1,6 @@
1
+ auto_walrus.py,sha256=oI_1v09aD6tuvgXz7_BHi6lUt4xWgjjxSeSzFz_dWYM,12958
2
+ auto_walrus-0.4.0.dist-info/METADATA,sha256=vPWs4IE0XtXq_f2hZ98irkRjw0mM_QLRd9n6J-Pvi5c,2981
3
+ auto_walrus-0.4.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
4
+ auto_walrus-0.4.0.dist-info/entry_points.txt,sha256=E-31QDdV5kzcjR9avgfwLt-i2Pc6c_zUa-knm__GCHo,49
5
+ auto_walrus-0.4.0.dist-info/licenses/LICENSE,sha256=YhJBcZzQmTfUwcrA-3FDZB3hiSIawDPD-VJSugAZXLY,1071
6
+ auto_walrus-0.4.0.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.22.5
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
auto_walrus.py CHANGED
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import argparse
4
4
  import ast
5
+ import dataclasses
5
6
  import os
6
7
  import pathlib
7
8
  import re
@@ -30,6 +31,12 @@ EXCLUDES = (
30
31
  )
31
32
 
32
33
 
34
+ @dataclasses.dataclass
35
+ class Config:
36
+ line_length: int
37
+ unsafe: bool = False
38
+
39
+
33
40
  def name_lineno_coloffset_iterable(
34
41
  tokens: Iterable[Token],
35
42
  ) -> list[tuple[str, int, int]]:
@@ -193,6 +200,7 @@ def related_vars_are_unused(
193
200
 
194
201
  def visit_function_def(
195
202
  node: ast.FunctionDef,
203
+ config: Config,
196
204
  ) -> list[tuple[Token, Token]]:
197
205
  names = set()
198
206
  assignments: set[Token] = set()
@@ -204,7 +212,7 @@ def visit_function_def(
204
212
  related_vars: dict[str, list[Token]] = {}
205
213
  in_body_vars: dict[Token, set[Token]] = {}
206
214
 
207
- for _node in node.body:
215
+ for _node in ast.walk(node) if config.unsafe else node.body:
208
216
  if isinstance(_node, ast.Assign):
209
217
  process_assign(_node, assignments, related_vars)
210
218
  elif isinstance(_node, ast.If):
@@ -255,7 +263,7 @@ def visit_function_def(
255
263
 
256
264
  def auto_walrus(
257
265
  content: str,
258
- line_length: int,
266
+ config: Config,
259
267
  ) -> str | None:
260
268
  lines = content.splitlines()
261
269
  try:
@@ -266,7 +274,7 @@ def auto_walrus(
266
274
  walruses = []
267
275
  for node in ast.walk(tree):
268
276
  if isinstance(node, ast.FunctionDef):
269
- walruses.extend(visit_function_def(node))
277
+ walruses.extend(visit_function_def(node, config))
270
278
  lines_to_remove = []
271
279
  walruses = sorted(walruses, key=lambda x: (-x[1][1], -x[1][2]))
272
280
 
@@ -290,13 +298,13 @@ def auto_walrus(
290
298
  line_with_walrus = left_bit + replace + right_bit
291
299
  else:
292
300
  line_with_walrus = left_bit + "(" + replace + ")" + right_bit
293
- if len(line_with_walrus) > line_length:
301
+ if len(line_with_walrus) > config.line_length:
294
302
  # don't rewrite if it would split over multiple lines
295
303
  continue
296
304
  # replace assignment
297
305
  line_without_assignment = (
298
- f"{lines[_assignment[1]-1][:_assignment[2]]}"
299
- f"{lines[_assignment[1]-1][_assignment[4]:]}"
306
+ f"{lines[_assignment[1] - 1][: _assignment[2]]}"
307
+ f"{lines[_assignment[1] - 1][_assignment[4] :]}"
300
308
  )
301
309
  if (ENDS_WITH_COMMENT.search(lines[_assignment[1] - 1]) is not None) or (
302
310
  ENDS_WITH_COMMENT.search(lines[_if_statement[1] - 1]) is not None
@@ -348,7 +356,7 @@ def _get_config(paths: list[pathlib.Path]) -> dict[str, Any]:
348
356
 
349
357
  def main(argv: Sequence[str] | None = None) -> int: # pragma: no cover
350
358
  parser = argparse.ArgumentParser()
351
- parser.add_argument("paths", nargs="*")
359
+ parser.add_argument("paths", nargs="+", metavar="path")
352
360
  parser.add_argument(
353
361
  "--files",
354
362
  help="Regex pattern with which to match files to include",
@@ -361,18 +369,24 @@ def main(argv: Sequence[str] | None = None) -> int: # pragma: no cover
361
369
  required=False,
362
370
  default=r"^$",
363
371
  )
372
+ parser.add_argument(
373
+ "--unsafe",
374
+ action="store_true",
375
+ help="Also process if statements inside other blocks (like for loops)",
376
+ )
364
377
  # black formatter's default
365
378
  parser.add_argument("--line-length", type=int, default=88)
366
379
  args = parser.parse_args(argv)
367
380
  paths = [pathlib.Path(path).resolve() for path in args.paths]
368
381
 
369
382
  # Update defaults from pyproject.toml if present
370
- config = {k.replace("-", "_"): v for k, v in _get_config(paths).items()}
371
- parser.set_defaults(**config)
383
+ defaults = {k.replace("-", "_"): v for k, v in _get_config(paths).items()}
384
+ parser.set_defaults(**defaults)
372
385
  args = parser.parse_args(argv)
373
386
 
374
387
  ret = 0
375
388
 
389
+ config = Config(line_length=args.line_length, unsafe=args.unsafe)
376
390
  for path in paths:
377
391
  if path.is_file():
378
392
  filepaths = iter((path,))
@@ -382,7 +396,7 @@ def main(argv: Sequence[str] | None = None) -> int: # pragma: no cover
382
396
  for p in path.rglob("*")
383
397
  if re.search(args.files, p.as_posix(), re.VERBOSE)
384
398
  and not re.search(args.exclude, p.as_posix(), re.VERBOSE)
385
- and not re.search(EXCLUDES, p.as_posix())
399
+ and not re.search(EXCLUDES, p.relative_to(path).as_posix())
386
400
  and p.suffix == ".py"
387
401
  )
388
402
 
@@ -392,10 +406,7 @@ def main(argv: Sequence[str] | None = None) -> int: # pragma: no cover
392
406
  content = fd.read()
393
407
  except UnicodeDecodeError:
394
408
  continue
395
- new_content = auto_walrus(
396
- content,
397
- line_length=args.line_length,
398
- )
409
+ new_content = auto_walrus(content, config)
399
410
  if new_content is not None and content != new_content:
400
411
  sys.stdout.write(f"Rewriting {filepath}\n")
401
412
  with open(filepath, "w", encoding="utf-8") as fd:
@@ -1,6 +0,0 @@
1
- auto_walrus.py,sha256=VI_WBQuwOu7OUY6fkul4wqRKedOWF9tt8U8GV8ZJiwk,12579
2
- auto_walrus-0.3.3.dist-info/METADATA,sha256=3ArSFbOHe9SGGq8Z_LtsQih34fjCM23Z0posm0Lqf_M,2936
3
- auto_walrus-0.3.3.dist-info/WHEEL,sha256=as-1oFTWSeWBgyzh0O_qF439xqBe6AbBgt4MfYe5zwY,87
4
- auto_walrus-0.3.3.dist-info/entry_points.txt,sha256=E-31QDdV5kzcjR9avgfwLt-i2Pc6c_zUa-knm__GCHo,49
5
- auto_walrus-0.3.3.dist-info/licenses/LICENSE,sha256=YhJBcZzQmTfUwcrA-3FDZB3hiSIawDPD-VJSugAZXLY,1071
6
- auto_walrus-0.3.3.dist-info/RECORD,,