Skip to content

Commit ee728c5

Browse files
committed
Refactor transforms
1 parent 2482455 commit ee728c5

File tree

12 files changed

+198
-210
lines changed

12 files changed

+198
-210
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77
## [2.2.1] - Unreleased
88

99
### Fixed
10-
- Unnecessary spaces after ';' in minified output have been removed.
10+
- Unnecessary spaces after ';' in minified output have been removed
11+
- Fixed PendingDeprecationWarnings
1112

1213
## [2.2.0] - 2019-10-27
1314
### Added

src/python_minifier/expression_printer.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,11 +98,7 @@ def visit_Unknown(self, node):
9898
def visit_Constant(self, node):
9999
if node.value in [None, True, False]:
100100
return self.visit_NameConstant(node)
101-
elif isinstance(node.value, int):
102-
return self.visit_Num(node)
103-
elif isinstance(node.value, float):
104-
return self.visit_Num(node)
105-
elif isinstance(node.value, complex):
101+
elif isinstance(node.value, (int, float, complex)):
106102
return self.visit_Num(node)
107103
elif isinstance(node.value, str):
108104
return self.visit_Str(node)

src/python_minifier/f_string.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from python_minifier.ast_compare import compare_ast
1515
from python_minifier.expression_printer import ExpressionPrinter
1616
from python_minifier.ministring import MiniString
17-
17+
from python_minifier.rename.util import is_str
1818

1919
class FString(object):
2020
"""
@@ -43,7 +43,7 @@ def candidates(self):
4343
nested_allowed = copy.copy(self.allowed_quotes)
4444
nested_allowed.remove(quote)
4545
for v in self.node.values:
46-
if isinstance(v, ast.Str):
46+
if is_str(v):
4747
try:
4848
candidates = [x + self.str_for(v.s, quote) for x in candidates]
4949
except:
@@ -288,7 +288,7 @@ def candidates(self):
288288

289289
candidates = ['']
290290
for v in self.node.values:
291-
if isinstance(v, ast.Str):
291+
if is_str(v):
292292
candidates = [x + self.str_for(v.s) for x in candidates]
293293
elif isinstance(v, ast.FormattedValue):
294294
candidates = [

src/python_minifier/rename/bind_names.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
from python_minifier.rename.binding import NameBinding
44
from python_minifier.rename.util import arg_rename_in_place, get_global_namespace, get_nonlocal_namespace, builtins
5+
from python_minifier.transforms.suite_transformer import NodeVisitor
56

67

7-
class NameBinder(ast.NodeVisitor):
8+
class NameBinder(NodeVisitor):
89
"""
910
Create a NameBinding for each name that is bound
1011

src/python_minifier/rename/rename_literals.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import ast
22

33
from python_minifier.rename.binding import Binding
4-
from python_minifier.rename.util import insert
4+
from python_minifier.rename.util import insert, is_str
5+
from python_minifier.transforms.suite_transformer import NodeVisitor
6+
57

68
def replace(old_node, new_node):
79
parent = old_node.parent
@@ -39,7 +41,7 @@ def set_local_namespace(self, node):
3941

4042
@property
4143
def value(self):
42-
if isinstance(self._value_node, ast.Str) or (hasattr(ast, 'Bytes') and isinstance(self._value_node, ast.Bytes)):
44+
if is_str(self._value_node) or (hasattr(ast, 'Bytes') and isinstance(self._value_node, ast.Bytes)):
4345
return self._value_node.s
4446
else:
4547
return self._value_node.value
@@ -89,7 +91,7 @@ def __ne__(self, other):
8991
return not self == other
9092

9193

92-
class HoistLiterals(ast.NodeVisitor):
94+
class HoistLiterals(NodeVisitor):
9395
"""
9496
Hoist literal strings to module level variables
9597
"""
@@ -195,7 +197,7 @@ def visit_Bytes(self, node):
195197

196198
def visit_JoinedStr(self, node):
197199
for v in node.values:
198-
if isinstance(v, ast.Str):
200+
if is_str(v):
199201
# Can't hoist this!
200202
continue
201203
else:

src/python_minifier/rename/util.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ def insert(suite, new_node):
110110

111111
if not inserted:
112112
if (isinstance(node, ast.ImportFrom) and node.module == '__future__') or (
113-
isinstance(node, ast.Expr) and isinstance(node.value, ast.Str)
113+
isinstance(node, ast.Expr) and is_str(node.value)
114114
):
115115
pass
116116
else:
@@ -162,7 +162,7 @@ def is_assign_all_node(node):
162162
continue
163163

164164
for el in node.value.elts:
165-
if isinstance(el, ast.Str):
165+
if is_str(el):
166166
names.append(el.s)
167167

168168
return names
@@ -178,6 +178,16 @@ def allow_rename_globals(module, rename_globals=False, preserve_globals=None):
178178
if rename_globals is False or binding.name in preserve_globals:
179179
binding.disallow_rename()
180180

181+
def is_str(node):
182+
if isinstance(node, ast.Str):
183+
return True
184+
185+
if hasattr(ast, 'Constant') and isinstance(node, ast.Constant):
186+
if isinstance(node.value, str):
187+
return True
188+
189+
return False
190+
181191
try:
182192
import builtins
183193
except ImportError:

src/python_minifier/transforms/combine_imports.py

Lines changed: 4 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,16 @@
11
import ast
22

3+
from python_minifier.transforms.suite_transformer import SuiteTransformer
34

4-
class CombineImports(ast.NodeTransformer):
5+
6+
class CombineImports(SuiteTransformer):
57
"""
68
Combine multiple import statements where possible
79
810
This doesn't change the order of imports
911
1012
"""
1113

12-
def __call__(self, node):
13-
return self.visit(node)
14-
15-
def visit_ClassDef(self, node):
16-
node.body = self.suite(node.body)
17-
return node
18-
19-
def visit_FunctionDef(self, node):
20-
node.body = self.suite(node.body)
21-
return node
22-
23-
def visit_AsyncFunctionDef(self, node):
24-
node.body = self.suite(node.body)
25-
return node
26-
27-
def visit_For(self, node):
28-
node.body = self.suite(node.body)
29-
30-
if node.orelse:
31-
node.orelse = self.suite(node.orelse)
32-
33-
return node
34-
35-
def visit_AsyncFor(self, node):
36-
return self.visit_For(node)
37-
38-
def visit_If(self, node):
39-
node.body = self.suite(node.body)
40-
if node.orelse:
41-
node.orelse = self.suite(node.orelse)
42-
43-
return node
44-
45-
def visit_Try(self, node):
46-
node.body = self.suite(node.body)
47-
48-
if node.orelse:
49-
node.orelse = self.suite(node.orelse)
50-
51-
if node.finalbody:
52-
node.finalbody = self.suite(node.finalbody)
53-
54-
return node
55-
56-
def visit_While(self, node):
57-
node.body = self.suite(node.body)
58-
59-
if node.orelse:
60-
node.orelse = self.suite(node.orelse)
61-
62-
return node
63-
64-
def visit_With(self, node):
65-
node.body = self.suite(node.body)
66-
return node
67-
68-
def visit_AsyncWith(self, node):
69-
node.body = self.suite(node.body)
70-
return node
71-
72-
def visit_Module(self, node):
73-
node.body = self.suite(node.body)
74-
return node
75-
7614
def _combine_import(self, node_list):
7715

7816
alias = []
@@ -124,7 +62,7 @@ def combine(statement):
12462
if alias:
12563
yield ast.ImportFrom(module=prev_import.module, names=alias, level=prev_import.level)
12664

127-
def suite(self, node_list):
65+
def suite(self, node_list, parent):
12866
a = list(self._combine_import(node_list))
12967
b = list(self._combine_import_from(a))
13068

src/python_minifier/transforms/remove_annotations.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
import ast
22
import sys
33

4+
from python_minifier.rename.mapper import add_parent
5+
from python_minifier.transforms.suite_transformer import SuiteTransformer
46

5-
class RemoveAnnotations(ast.NodeTransformer):
7+
8+
class RemoveAnnotations(SuiteTransformer):
69
"""
710
Remove type annotations from source
811
"""
@@ -73,11 +76,15 @@ def is_dataclass_field(node):
7376
if is_dataclass_field(node):
7477
return node
7578
elif node.value:
76-
return ast.Assign([node.target], node.value)
79+
assign = ast.Assign([node.target], node.value)
80+
assign.parent = node.parent
81+
assign.namespace = node.namespace
82+
return assign
7783
else:
7884
# Valueless annotations cause the interpreter to treat the variable as a local.
7985
# I don't know of another way to do that without assigning to it, so
8086
# keep it as an AnnAssign, but replace the annotation with '0'
8187

8288
node.annotation = ast.Num(0)
89+
add_parent(node, parent=node.parent, namespace=node.namespace)
8390
return node
Lines changed: 12 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import ast
22

3+
from python_minifier.rename.mapper import add_parent
4+
from python_minifier.transforms.suite_transformer import SuiteTransformer
5+
36

47
def find_doc(node):
58

@@ -18,7 +21,7 @@ def _doc_in_module(module):
1821
except:
1922
return True
2023

21-
class RemoveLiteralStatements(ast.NodeTransformer):
24+
class RemoveLiteralStatements(SuiteTransformer):
2225
"""
2326
Remove literal expressions from the code
2427
@@ -30,90 +33,37 @@ def __call__(self, node):
3033
return node
3134
return self.visit(node)
3235

33-
def visit_ClassDef(self, node):
34-
node.body = self.suite(node.body)
35-
return node
36-
37-
def visit_FunctionDef(self, node):
38-
node.body = self.suite(node.body)
39-
return node
40-
41-
def visit_AsyncFunctionDef(self, node):
42-
return self.visit_FunctionDef(node)
43-
44-
def visit_For(self, node):
45-
node.body = self.suite(node.body)
46-
47-
if node.orelse:
48-
node.orelse = self.suite(node.orelse)
49-
50-
return node
51-
52-
def visit_AsyncFor(self, node):
53-
return self.visit_For(node)
54-
55-
def visit_If(self, node):
56-
node.body = self.suite(node.body)
57-
if node.orelse:
58-
node.orelse = self.suite(node.orelse)
59-
60-
return node
61-
62-
def visit_Try(self, node):
63-
node.body = self.suite(node.body)
64-
65-
if node.orelse:
66-
node.orelse = self.suite(node.orelse)
67-
68-
if node.finalbody:
69-
node.finalbody = self.suite(node.finalbody)
70-
71-
return node
72-
73-
def visit_While(self, node):
74-
node.body = self.suite(node.body)
75-
76-
if node.orelse:
77-
node.orelse = self.suite(node.orelse)
78-
79-
return node
80-
81-
def visit_With(self, node):
82-
node.body = self.suite(node.body)
83-
return node
84-
85-
def visit_AsyncWith(self, node):
86-
return self.visit_With(node)
87-
8836
def visit_Module(self, node):
8937
for binding in node.bindings:
9038
if binding.name == '__doc__':
9139
node.body = [self.visit(a) for a in node.body]
9240
return node
9341

94-
node.body = self.suite(node.body, module=True)
42+
node.body = self.suite(node.body, parent=node)
9543
return node
9644

9745
def is_literal_statement(self, node):
9846
if not isinstance(node, ast.Expr):
9947
return False
10048

10149
if (
102-
isinstance(node.value, ast.Num)
103-
or isinstance(node.value, ast.Str)
50+
isinstance(node.value, (ast.Num, ast.Str, ast.NameConstant))
51+
or node.value.__class__.__name__ == 'Constant'
10452
or node.value.__class__.__name__ == 'Bytes'
10553
):
10654
return True
10755

10856
return False
10957

110-
def suite(self, node_list, module=False):
58+
def suite(self, node_list, parent):
11159
without_literals = [self.visit(a) for a in filter(lambda n: not self.is_literal_statement(n), node_list)]
11260

11361
if len(without_literals) == 0:
114-
if module:
62+
if isinstance(parent, ast.Module):
11563
return []
11664
else:
117-
return [ast.Expr(value=ast.Num(0))]
65+
expr = ast.Expr(value=ast.Num(0))
66+
add_parent(expr, parent=parent, namespace=parent.namespace)
67+
return [expr]
11868

11969
return without_literals

src/python_minifier/transforms/remove_object_base.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import ast
22
import sys
33

4-
class RemoveObject(ast.NodeTransformer):
4+
from python_minifier.transforms.suite_transformer import SuiteTransformer
5+
6+
7+
class RemoveObject(SuiteTransformer):
58
def __call__(self, node):
69
if sys.version_info < (3, 0):
710
return node

0 commit comments

Comments
 (0)