Coverage for pysource_minimize/_minimize.py: 94%
38 statements
« prev ^ index » next coverage.py v6.5.0, created at 2024-03-25 08:14 +0100
« prev ^ index » next coverage.py v6.5.0, created at 2024-03-25 08:14 +0100
1import ast
2import warnings
4from ._minimize_base import equal_ast
5from ._minimize_structure import MinimizeStructure
6from ._minimize_value import MinimizeValue
7from ._utils import parse
8from ._utils import unparse
11def minimize_ast( 11 ↛ exitline 11 didn't jump to the function exit
12 original_ast: ast.AST,
13 checker,
14 *,
15 progress_callback=lambda current, total: None,
16 retries=1,
17) -> ast.AST:
18 """
19 minimzes the AST
21 Args:
22 ast: the ast to minimize
23 checker: a function which gets the ast and returns `True` when the criteria is fullfilled.
24 progress_callback: function which is called everytime the ast gets a bit smaller.
25 retries: the number of retries which sould be performed when the ast could be minimized (useful for non deterministic issues)
27 returns the minimized ast
28 """
30 last_success = 0
32 current_ast = original_ast
33 while last_success <= retries:
34 new_ast = current_ast
36 for Minimizer in (MinimizeStructure, MinimizeValue):
37 minimizer = Minimizer(new_ast, checker, progress_callback)
38 new_ast = minimizer.get_current_tree({})
39 if minimizer.stop:
40 break
42 minimized_something = not equal_ast(new_ast, current_ast)
44 current_ast = new_ast
46 if minimized_something:
47 last_success = 0
48 else:
49 last_success += 1
51 return current_ast
54def minimize(
55 source: str, checker, *, progress_callback=lambda current, total: None, retries=1
56) -> str:
57 """
58 minimzes the source code
60 Args:
61 source: the source code to minimize
62 checker: a function which gets the source and returns `True` when the criteria is fullfilled.
63 progress_callback: function which is called everytime the source gets a bit smaller.
64 retries: the number of retries which sould be performed when the ast could be minimized (useful for non deterministic issues)
66 returns the minimized source
67 """
69 original_ast = parse(source)
71 def source_checker(new_ast):
72 try:
73 with warnings.catch_warnings():
74 source = unparse(new_ast)
75 warnings.simplefilter("ignore", SyntaxWarning)
76 compile(source, "<string>", "exec")
77 except:
78 return False
80 return checker(source)
82 if not source_checker(original_ast): 82 ↛ 83line 82 didn't jump to line 83, because the condition on line 82 was never true
83 raise ValueError("ast.unparse removes the error minimize can not help here")
85 minimized_ast = minimize_ast(
86 original_ast,
87 source_checker,
88 progress_callback=progress_callback,
89 retries=retries,
90 )
92 return unparse(minimized_ast)