python-minifier 2.11.2__py2-none-any.whl → 2.11.3__py2-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.
Files changed (43) hide show
  1. python_minifier/__init__.py +12 -8
  2. python_minifier/__init__.pyi +6 -1
  3. python_minifier/__main__.py +10 -7
  4. python_minifier/ast_annotation/__init__.py +82 -0
  5. python_minifier/ast_compare.py +1 -3
  6. python_minifier/ast_compat.py +38 -0
  7. python_minifier/ast_printer.py +8 -5
  8. python_minifier/expression_printer.py +14 -13
  9. python_minifier/f_string.py +13 -14
  10. python_minifier/ministring.py +3 -3
  11. python_minifier/module_printer.py +13 -14
  12. python_minifier/rename/__init__.py +1 -1
  13. python_minifier/rename/bind_names.py +2 -1
  14. python_minifier/rename/binding.py +39 -40
  15. python_minifier/rename/mapper.py +66 -50
  16. python_minifier/rename/rename_literals.py +17 -15
  17. python_minifier/rename/renamer.py +26 -28
  18. python_minifier/rename/resolve_names.py +8 -7
  19. python_minifier/rename/util.py +7 -5
  20. python_minifier/token_printer.py +3 -0
  21. python_minifier/transforms/combine_imports.py +0 -1
  22. python_minifier/transforms/constant_folding.py +16 -10
  23. python_minifier/transforms/remove_annotations.py +18 -16
  24. python_minifier/transforms/remove_annotations_options.py +3 -1
  25. python_minifier/transforms/remove_annotations_options.pyi +8 -7
  26. python_minifier/transforms/remove_asserts.py +1 -2
  27. python_minifier/transforms/remove_debug.py +4 -3
  28. python_minifier/transforms/remove_exception_brackets.py +12 -7
  29. python_minifier/transforms/remove_explicit_return_none.py +5 -4
  30. python_minifier/transforms/remove_literal_statements.py +5 -6
  31. python_minifier/transforms/remove_object_base.py +2 -1
  32. python_minifier/transforms/remove_pass.py +1 -2
  33. python_minifier/transforms/remove_posargs.py +3 -4
  34. python_minifier/transforms/suite_transformer.py +6 -5
  35. python_minifier/util.py +12 -18
  36. {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/METADATA +1 -1
  37. python_minifier-2.11.3.dist-info/RECORD +45 -0
  38. python_minifier-2.11.2.dist-info/RECORD +0 -44
  39. {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/LICENSE +0 -0
  40. {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/WHEEL +0 -0
  41. {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/entry_points.txt +0 -0
  42. {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/top_level.txt +0 -0
  43. {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/zip-safe +0 -0
@@ -1,14 +1,15 @@
1
1
  import python_minifier.ast_compat as ast
2
+ from python_minifier.ast_annotation import get_parent, set_parent
2
3
 
3
4
  from python_minifier.rename.binding import Binding
4
5
  from python_minifier.rename.util import insert
5
6
  from python_minifier.transforms.suite_transformer import NodeVisitor
6
- from python_minifier.util import is_ast_node
7
+ from python_minifier.util import is_constant_node
7
8
 
8
9
 
9
10
  def replace(old_node, new_node):
10
- parent = old_node.parent
11
- new_node.parent = parent
11
+ parent = get_parent(old_node)
12
+ set_parent(new_node, parent)
12
13
  new_node.namespace = old_node.namespace
13
14
 
14
15
  for field, old_value in ast.iter_fields(parent):
@@ -43,7 +44,7 @@ class HoistedBinding(Binding):
43
44
 
44
45
  @property
45
46
  def value(self):
46
- if is_ast_node(self._value_node, (ast.Str, 'Bytes')):
47
+ if is_constant_node(self._value_node, (ast.Str, ast.Bytes)):
47
48
  return self._value_node.s
48
49
  else:
49
50
  return self._value_node.value
@@ -84,6 +85,7 @@ class HoistedBinding(Binding):
84
85
 
85
86
  return rename_cost <= current_cost
86
87
 
88
+
87
89
  class HoistedValue(object):
88
90
  """
89
91
  HoistedValue comparator object
@@ -132,7 +134,7 @@ class HoistLiterals(NodeVisitor):
132
134
 
133
135
  """
134
136
 
135
- if is_ast_node(node.namespace, (ast.FunctionDef, ast.Module, 'AsyncFunctionDef')):
137
+ if isinstance(node.namespace, (ast.FunctionDef, ast.Module, ast.AsyncFunctionDef)):
136
138
  return node.namespace
137
139
  return self.nearest_function_namespace(node.namespace)
138
140
 
@@ -154,18 +156,18 @@ class HoistLiterals(NodeVisitor):
154
156
 
155
157
  """
156
158
 
157
- l = []
159
+ path = []
158
160
 
159
161
  while True:
160
162
  namespace = self.nearest_function_namespace(node)
161
- l.insert(0, namespace)
163
+ path.insert(0, namespace)
162
164
 
163
165
  if isinstance(namespace, ast.Module):
164
166
  break
165
167
 
166
168
  node = namespace
167
169
 
168
- return l
170
+ return path
169
171
 
170
172
  def common_path(self, n1_path, n2_path):
171
173
 
@@ -201,7 +203,7 @@ class HoistLiterals(NodeVisitor):
201
203
 
202
204
  def visit_Str(self, node):
203
205
 
204
- if isinstance(node.parent, ast.Expr):
206
+ if isinstance(get_parent(node), ast.Expr):
205
207
  # This is literal statement
206
208
  # The RemoveLiteralStatements transformer must have left it here, so ignore it.
207
209
  return
@@ -213,11 +215,10 @@ class HoistLiterals(NodeVisitor):
213
215
 
214
216
  def visit_JoinedStr(self, node):
215
217
  for v in node.values:
216
- if is_ast_node(v, ast.Str):
218
+ if is_constant_node(v, ast.Str):
217
219
  # Can't hoist this!
218
220
  continue
219
- else:
220
- self.visit(v)
221
+ self.visit(v)
221
222
 
222
223
  def visit_NameConstant(self, node):
223
224
  self.get_binding(node.value, node).add_reference(node)
@@ -235,15 +236,16 @@ class HoistLiterals(NodeVisitor):
235
236
  if not self._ignore_slots:
236
237
  return self.generic_visit(node)
237
238
 
238
- if not is_ast_node(node.namespace, ast.ClassDef):
239
+ if not isinstance(node.namespace, ast.ClassDef):
239
240
  return self.generic_visit(node)
240
241
 
241
242
  for target in node.targets:
242
- if is_ast_node(target, ast.Name) and target.id == '__slots__':
243
+ if isinstance(target, ast.Name) and target.id == '__slots__':
243
244
  # This is a __slots__ assignment, don't hoist the literals
244
- return
245
+ return None
245
246
 
246
247
  return self.generic_visit(node)
247
248
 
249
+
248
250
  def rename_literals(module):
249
251
  HoistLiterals()(module)
@@ -55,7 +55,7 @@ def reservation_scope(namespace, binding):
55
55
 
56
56
  """
57
57
 
58
- namespaces = set([namespace])
58
+ namespaces = {namespace}
59
59
 
60
60
  for node in binding.references:
61
61
  while node is not namespace:
@@ -112,7 +112,7 @@ class UniqueNameAssigner(object):
112
112
  def __call__(self, module):
113
113
  assert isinstance(module, ast.Module)
114
114
 
115
- for namespace, binding in sorted_bindings(module):
115
+ for _namespace, binding in sorted_bindings(module):
116
116
  if binding.allow_rename:
117
117
  binding.new_name = self.available_name()
118
118
 
@@ -154,6 +154,8 @@ class NameAssigner(object):
154
154
  if self.is_available(prefix + name, reservation_scope):
155
155
  return prefix + name
156
156
 
157
+ return None
158
+
157
159
  def is_available(self, name, reservation_scope):
158
160
  """
159
161
  Is a name unreserved in a reservation scope
@@ -165,11 +167,7 @@ class NameAssigner(object):
165
167
 
166
168
  """
167
169
 
168
- for namespace in reservation_scope:
169
- if name in namespace.assigned_names:
170
- return False
171
-
172
- return True
170
+ return all(name not in namespace.assigned_names for namespace in reservation_scope)
173
171
 
174
172
  def __call__(self, module, prefix_globals, reserved_globals=None):
175
173
  assert isinstance(module, ast.Module)
@@ -184,6 +182,26 @@ class NameAssigner(object):
184
182
  for name in reserved_globals:
185
183
  module.assigned_names.add(name)
186
184
 
185
+ def should_rename(binding, name, scope):
186
+ if binding.should_rename(name):
187
+ return True
188
+
189
+ # It's no longer efficient to do this rename
190
+
191
+ if isinstance(binding, NameBinding):
192
+ # Check that the original name is still available
193
+
194
+ if binding.reserved == binding.name:
195
+ # We already reserved it (this is probably an arg)
196
+ return False
197
+
198
+ if not self.is_available(binding.name, scope):
199
+ # The original name has already been assigned to another binding,
200
+ # so we need to rename this anyway.
201
+ return True
202
+
203
+ return False
204
+
187
205
  for namespace, binding in sorted_bindings(module):
188
206
  scope = reservation_scope(namespace, binding)
189
207
 
@@ -194,27 +212,7 @@ class NameAssigner(object):
194
212
  else:
195
213
  name = self.available_name(scope)
196
214
 
197
- def should_rename():
198
- if binding.should_rename(name):
199
- return True
200
-
201
- # It's no longer efficient to do this rename
202
-
203
- if isinstance(binding, NameBinding):
204
- # Check that the original name is still available
205
-
206
- if binding.reserved == binding.name:
207
- # We already reserved it (this is probably an arg)
208
- return False
209
-
210
- if not self.is_available(binding.name, scope):
211
- # The original name has already been assigned to another binding,
212
- # so we need to rename this anyway.
213
- return True
214
-
215
- return False
216
-
217
- if should_rename():
215
+ if should_rename(binding, name, scope):
218
216
  binding.rename(name)
219
217
  else:
220
218
  # Any existing name will become reserved
@@ -1,8 +1,7 @@
1
1
  import python_minifier.ast_compat as ast
2
2
 
3
3
  from python_minifier.rename.binding import BuiltinBinding, NameBinding
4
- from python_minifier.rename.util import get_global_namespace, get_nonlocal_namespace, builtins
5
- from python_minifier.util import is_ast_node
4
+ from python_minifier.rename.util import builtins, get_global_namespace, get_nonlocal_namespace
6
5
 
7
6
 
8
7
  def get_binding(name, namespace):
@@ -34,6 +33,7 @@ def get_binding(name, namespace):
34
33
  namespace.bindings.append(binding)
35
34
  return binding
36
35
 
36
+
37
37
  def get_binding_disallow_class_namespace_rename(name, namespace):
38
38
  binding = get_binding(name, namespace)
39
39
 
@@ -43,6 +43,7 @@ def get_binding_disallow_class_namespace_rename(name, namespace):
43
43
 
44
44
  return binding
45
45
 
46
+
46
47
  def resolve_names(node):
47
48
  """
48
49
  Resolve unbound names to a NameBinding
@@ -65,7 +66,7 @@ def resolve_names(node):
65
66
  binding = get_binding_disallow_class_namespace_rename(node.name, node.namespace)
66
67
  binding.add_reference(node)
67
68
 
68
- elif is_ast_node(node, (ast.FunctionDef, 'AsyncFunctionDef')) and node.name in node.namespace.nonlocal_names:
69
+ elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) and node.name in node.namespace.nonlocal_names:
69
70
  binding = get_binding_disallow_class_namespace_rename(node.name, node.namespace)
70
71
  binding.add_reference(node)
71
72
 
@@ -91,15 +92,15 @@ def resolve_names(node):
91
92
  if isinstance(node.name, str) and node.name in node.namespace.nonlocal_names:
92
93
  get_binding_disallow_class_namespace_rename(node.name, node.namespace).add_reference(node)
93
94
 
94
- elif is_ast_node(node, 'Nonlocal'):
95
+ elif isinstance(node, ast.Nonlocal):
95
96
  for name in node.names:
96
97
  get_binding_disallow_class_namespace_rename(name, node.namespace).add_reference(node)
97
- elif is_ast_node(node, ('MatchAs', 'MatchStar')) and node.name in node.namespace.nonlocal_names:
98
+ elif isinstance(node, (ast.MatchAs, ast.MatchStar)) and node.name in node.namespace.nonlocal_names:
98
99
  get_binding_disallow_class_namespace_rename(node.name, node.namespace).add_reference(node)
99
- elif is_ast_node(node, 'MatchMapping') and node.rest in node.namespace.nonlocal_names:
100
+ elif isinstance(node, ast.MatchMapping) and node.rest in node.namespace.nonlocal_names:
100
101
  get_binding_disallow_class_namespace_rename(node.rest, node.namespace).add_reference(node)
101
102
 
102
- elif is_ast_node(node, 'Exec'):
103
+ elif isinstance(node, ast.Exec):
103
104
  get_global_namespace(node).tainted = True
104
105
 
105
106
  for child in ast.iter_child_nodes(node):
@@ -1,7 +1,8 @@
1
- import python_minifier.ast_compat as ast
2
1
  import sys
3
2
 
4
- from python_minifier.util import is_ast_node
3
+ import python_minifier.ast_compat as ast
4
+
5
+ from python_minifier.util import is_constant_node
5
6
 
6
7
 
7
8
  def create_is_namespace():
@@ -32,6 +33,7 @@ def iter_child_namespaces(node):
32
33
  for c in iter_child_namespaces(child):
33
34
  yield c
34
35
 
36
+
35
37
  def get_global_namespace(node):
36
38
  """
37
39
  Return the global namespace for a node
@@ -125,7 +127,7 @@ def insert(suite, new_node):
125
127
 
126
128
  if not inserted:
127
129
  if (isinstance(node, ast.ImportFrom) and node.module == '__future__') or (
128
- isinstance(node, ast.Expr) and is_ast_node(node.value, ast.Str)
130
+ isinstance(node, ast.Expr) and is_constant_node(node.value, ast.Str)
129
131
  ):
130
132
  pass
131
133
  else:
@@ -164,7 +166,7 @@ def find__all__(module):
164
166
  if isinstance(name, ast.Name) and name.id == '__all__':
165
167
  return True
166
168
 
167
- elif is_ast_node(node, (ast.AugAssign, 'AnnAssign')):
169
+ elif isinstance(node, (ast.AugAssign, ast.AnnAssign)):
168
170
  if isinstance(node.target, ast.Name) and node.target.id == '__all__':
169
171
  return True
170
172
 
@@ -178,7 +180,7 @@ def find__all__(module):
178
180
  continue
179
181
 
180
182
  for el in node.value.elts:
181
- if is_ast_node(el, ast.Str):
183
+ if is_constant_node(el, ast.Str):
182
184
  names.append(el.s)
183
185
 
184
186
  return names
@@ -3,6 +3,7 @@
3
3
  import re
4
4
  import sys
5
5
 
6
+
6
7
  class TokenTypes(object):
7
8
  NoToken = 0
8
9
  Identifier = 1
@@ -15,6 +16,7 @@ class TokenTypes(object):
15
16
  NewLine = 8
16
17
  EndStatement = 9
17
18
 
19
+
18
20
  class Delimiter(object):
19
21
  def __init__(self, terminal_printer, delimiter=',', add_parens=False):
20
22
  """
@@ -74,6 +76,7 @@ class Delimiter(object):
74
76
  else:
75
77
  self._terminal_printer.delimiter(self._delimiter)
76
78
 
79
+
77
80
  class TokenPrinter(object):
78
81
  """
79
82
  Concatenates terminal symbols of the python grammar
@@ -30,7 +30,6 @@ class CombineImports(SuiteTransformer):
30
30
  if alias:
31
31
  yield self.add_child(ast.Import(names=alias), parent=parent, namespace=namespace)
32
32
 
33
-
34
33
  def _combine_import_from(self, node_list, parent):
35
34
 
36
35
  prev_import = None
@@ -1,11 +1,14 @@
1
- import python_minifier.ast_compat as ast
2
1
  import math
3
2
  import sys
4
3
 
4
+ import python_minifier.ast_compat as ast
5
+ from python_minifier.ast_annotation import get_parent
6
+
5
7
  from python_minifier.ast_compare import compare_ast
6
8
  from python_minifier.expression_printer import ExpressionPrinter
7
9
  from python_minifier.transforms.suite_transformer import SuiteTransformer
8
- from python_minifier.util import is_ast_node
10
+ from python_minifier.util import is_constant_node
11
+
9
12
 
10
13
  class FoldConstants(SuiteTransformer):
11
14
  """
@@ -22,9 +25,9 @@ class FoldConstants(SuiteTransformer):
22
25
 
23
26
  # Check this is a constant expression that could be folded
24
27
  # We don't try to fold strings or bytes, since they have probably been arranged this way to make the source shorter and we are unlikely to beat that
25
- if not is_ast_node(node.left, (ast.Num, 'NameConstant')):
28
+ if not is_constant_node(node.left, (ast.Num, ast.NameConstant)):
26
29
  return node
27
- if not is_ast_node(node.right, (ast.Num, 'NameConstant')):
30
+ if not is_constant_node(node.right, (ast.Num, ast.NameConstant)):
28
31
  return node
29
32
 
30
33
  if isinstance(node.op, ast.Div):
@@ -68,7 +71,7 @@ class FoldConstants(SuiteTransformer):
68
71
  try:
69
72
  folded_expression = unparse_expression(new_node)
70
73
  folded_value = safe_eval(folded_expression)
71
- except Exception as e:
74
+ except Exception:
72
75
  # This can happen if the value is too large to be represented as a literal
73
76
  # or if the value is unparsed as nan, inf or -inf - which are not valid python literals
74
77
  return node
@@ -91,7 +94,8 @@ class FoldConstants(SuiteTransformer):
91
94
  return node
92
95
 
93
96
  # New representation is shorter and has the same value, so use it
94
- return self.add_child(new_node, node.parent, node.namespace)
97
+ return self.add_child(new_node, get_parent(node), node.namespace)
98
+
95
99
 
96
100
  def equal_value_and_type(a, b):
97
101
  if type(a) != type(b):
@@ -102,13 +106,15 @@ def equal_value_and_type(a, b):
102
106
 
103
107
  return a == b
104
108
 
109
+
105
110
  def safe_eval(expression):
106
- globals = {}
107
- locals = {}
111
+ empty_globals = {}
112
+ empty_locals = {}
108
113
 
109
114
  # This will return the value, or could raise an exception
110
- return eval(expression, globals, locals)
115
+ return eval(expression, empty_globals, empty_locals)
116
+
111
117
 
112
118
  def unparse_expression(node):
113
119
  expression_printer = ExpressionPrinter()
114
- return expression_printer(node)
120
+ return expression_printer(node)
@@ -1,6 +1,8 @@
1
- import python_minifier.ast_compat as ast
2
1
  import sys
3
2
 
3
+ import python_minifier.ast_compat as ast
4
+ from python_minifier.ast_annotation import get_parent
5
+
4
6
  from python_minifier.transforms.remove_annotations_options import RemoveAnnotationsOptions
5
7
  from python_minifier.transforms.suite_transformer import SuiteTransformer
6
8
 
@@ -71,20 +73,20 @@ class RemoveAnnotations(SuiteTransformer):
71
73
  if sys.version_info < (3, 7):
72
74
  return False
73
75
 
74
- if not isinstance(node.parent, ast.ClassDef):
76
+ if not isinstance(get_parent(node), ast.ClassDef):
75
77
  return False
76
78
 
77
- if len(node.parent.decorator_list) == 0:
79
+ if len(get_parent(node).decorator_list) == 0:
78
80
  return False
79
81
 
80
- for node in node.parent.decorator_list:
81
- if isinstance(node, ast.Name) and node.id == 'dataclass':
82
+ for decorator_node in get_parent(node).decorator_list:
83
+ if isinstance(decorator_node, ast.Name) and decorator_node.id == 'dataclass':
82
84
  return True
83
- elif isinstance(node, ast.Attribute) and node.attr == 'dataclass':
85
+ elif isinstance(decorator_node, ast.Attribute) and decorator_node.attr == 'dataclass':
84
86
  return True
85
- elif isinstance(node, ast.Call) and isinstance(node.func, ast.Name) and node.func.id == 'dataclass':
87
+ elif isinstance(decorator_node, ast.Call) and isinstance(decorator_node.func, ast.Name) and decorator_node.func.id == 'dataclass':
86
88
  return True
87
- elif isinstance(node, ast.Call) and isinstance(node.func, ast.Attribute) and node.func.attr == 'dataclass':
89
+ elif isinstance(decorator_node, ast.Call) and isinstance(decorator_node.func, ast.Attribute) and decorator_node.func.attr == 'dataclass':
88
90
  return True
89
91
 
90
92
  return False
@@ -93,24 +95,24 @@ class RemoveAnnotations(SuiteTransformer):
93
95
  if sys.version_info < (3, 5):
94
96
  return False
95
97
 
96
- if not isinstance(node.parent, ast.ClassDef):
98
+ if not isinstance(get_parent(node), ast.ClassDef):
97
99
  return False
98
100
 
99
- if len(node.parent.bases) == 0:
101
+ if len(get_parent(node).bases) == 0:
100
102
  return False
101
103
 
102
104
  tricky_types = ['NamedTuple', 'TypedDict']
103
105
 
104
- for node in node.parent.bases:
105
- if isinstance(node, ast.Name) and node.id in tricky_types:
106
+ for base_node in get_parent(node).bases:
107
+ if isinstance(base_node, ast.Name) and base_node.id in tricky_types:
106
108
  return True
107
- elif isinstance(node, ast. Attribute) and node.attr in tricky_types:
109
+ elif isinstance(base_node, ast.Attribute) and base_node.attr in tricky_types:
108
110
  return True
109
111
 
110
112
  return False
111
113
 
112
114
  # is this a class attribute or a variable?
113
- if isinstance(node.parent, ast.ClassDef):
115
+ if isinstance(get_parent(node), ast.ClassDef):
114
116
  if not self._options.remove_class_attribute_annotations:
115
117
  return node
116
118
  else:
@@ -120,11 +122,11 @@ class RemoveAnnotations(SuiteTransformer):
120
122
  if is_dataclass_field(node) or is_typing_sensitive(node):
121
123
  return node
122
124
  elif node.value:
123
- return self.add_child(ast.Assign([node.target], node.value), parent=node.parent, namespace=node.namespace)
125
+ return self.add_child(ast.Assign([node.target], node.value), parent=get_parent(node), namespace=node.namespace)
124
126
  else:
125
127
  # Valueless annotations cause the interpreter to treat the variable as a local.
126
128
  # I don't know of another way to do that without assigning to it, so
127
129
  # keep it as an AnnAssign, but replace the annotation with '0'
128
130
 
129
- node.annotation = self.add_child(ast.Num(0), parent=node.parent, namespace=node.namespace)
131
+ node.annotation = self.add_child(ast.Num(0), parent=get_parent(node), namespace=node.namespace)
130
132
  return node
@@ -26,7 +26,9 @@ class RemoveAnnotationsOptions(object):
26
26
  self.remove_class_attribute_annotations = remove_class_attribute_annotations
27
27
 
28
28
  def __repr__(self):
29
- return 'RemoveAnnotationsOptions(remove_variable_annotations=%r, remove_return_annotations=%r, remove_argument_annotations=%r, remove_class_attribute_annotations=%r)' % (self.remove_variable_annotations, self.remove_return_annotations, self.remove_argument_annotations, self.remove_class_attribute_annotations)
29
+ return 'RemoveAnnotationsOptions(remove_variable_annotations=%r, remove_return_annotations=%r, remove_argument_annotations=%r, remove_class_attribute_annotations=%r)' % (
30
+ self.remove_variable_annotations, self.remove_return_annotations, self.remove_argument_annotations, self.remove_class_attribute_annotations
31
+ )
30
32
 
31
33
  def __nonzero__(self):
32
34
  return any((self.remove_variable_annotations, self.remove_return_annotations, self.remove_argument_annotations, self.remove_class_attribute_annotations))
@@ -1,17 +1,18 @@
1
1
  class RemoveAnnotationsOptions:
2
-
3
2
  remove_variable_annotations: bool
4
3
  remove_return_annotations: bool
5
4
  remove_argument_annotations: bool
6
5
  remove_class_attribute_annotations: bool
7
6
 
8
- def __init__(self,
9
- remove_variable_annotations: bool = ...,
10
- remove_return_annotations: bool = ...,
11
- remove_argument_annotations: bool = ...,
12
- remove_class_attribute_annotations: bool = ...):
7
+ def __init__(
8
+ self,
9
+ remove_variable_annotations: bool = ...,
10
+ remove_return_annotations: bool = ...,
11
+ remove_argument_annotations: bool = ...,
12
+ remove_class_attribute_annotations: bool = ...
13
+ ):
13
14
  ...
14
15
 
15
- def __repr__(self) -> str: ...
16
16
  def __nonzero__(self) -> bool: ...
17
+
17
18
  def __bool__(self) -> bool: ...
@@ -1,7 +1,6 @@
1
1
  import python_minifier.ast_compat as ast
2
2
 
3
3
  from python_minifier.transforms.suite_transformer import SuiteTransformer
4
- from python_minifier.util import is_ast_node
5
4
 
6
5
 
7
6
  class RemoveAsserts(SuiteTransformer):
@@ -15,7 +14,7 @@ class RemoveAsserts(SuiteTransformer):
15
14
  return self.visit(node)
16
15
 
17
16
  def suite(self, node_list, parent):
18
- without_assert = [self.visit(a) for a in filter(lambda n: not is_ast_node(n, ast.Assert), node_list)]
17
+ without_assert = [self.visit(a) for a in filter(lambda n: not isinstance(n, ast.Assert), node_list)]
19
18
 
20
19
  if len(without_assert) == 0:
21
20
  if isinstance(parent, ast.Module):
@@ -1,8 +1,9 @@
1
- import python_minifier.ast_compat as ast
2
1
  import sys
3
2
 
3
+ import python_minifier.ast_compat as ast
4
+
4
5
  from python_minifier.transforms.suite_transformer import SuiteTransformer
5
- from python_minifier.util import is_ast_node
6
+ from python_minifier.util import is_constant_node
6
7
 
7
8
 
8
9
  class RemoveDebug(SuiteTransformer):
@@ -18,7 +19,7 @@ class RemoveDebug(SuiteTransformer):
18
19
  def constant_value(self, node):
19
20
  if sys.version_info < (3, 4):
20
21
  return node.id == 'True'
21
- elif is_ast_node(node, 'NameConstant'):
22
+ elif is_constant_node(node, ast.NameConstant):
22
23
  return node.value
23
24
  return None
24
25
 
@@ -8,11 +8,14 @@ When printed, this essentially removes the brackets from the exception name.
8
8
  We can't generally know if a name refers to an exception, so we only do this for builtin exceptions
9
9
  """
10
10
 
11
- import python_minifier.ast_compat as ast
12
11
  import sys
13
12
 
13
+ import python_minifier.ast_compat as ast
14
+ from python_minifier.ast_annotation import get_parent, set_parent
15
+
14
16
  from python_minifier.rename.binding import BuiltinBinding
15
17
 
18
+
16
19
  # These are always exceptions, in every version of python
17
20
  builtin_exceptions = [
18
21
  'SyntaxError', 'Exception', 'ValueError', 'BaseException', 'MemoryError', 'RuntimeError', 'DeprecationWarning', 'UnicodeEncodeError', 'KeyError', 'LookupError', 'TypeError', 'BufferError',
@@ -73,22 +76,24 @@ builtin_exceptions_3_11 = [
73
76
  'BaseExceptionGroup',
74
77
  ]
75
78
 
79
+
76
80
  def _remove_empty_call(binding):
77
81
  assert isinstance(binding, BuiltinBinding)
78
82
 
79
83
  for name_node in binding.references:
80
84
  # For this to be a builtin, all references must be name nodes as it is not defined anywhere
81
- assert isinstance(name_node, ast.Name) and isinstance(name_node.ctx, ast.Load)
85
+ assert isinstance(name_node, ast.Name)
86
+ assert isinstance(name_node.ctx, ast.Load)
82
87
 
83
- if not isinstance(name_node.parent, ast.Call):
88
+ if not isinstance(get_parent(name_node), ast.Call):
84
89
  # This is not a call
85
90
  continue
86
- call_node = name_node.parent
91
+ call_node = get_parent(name_node)
87
92
 
88
- if not isinstance(call_node.parent, ast.Raise):
93
+ if not isinstance(get_parent(call_node), ast.Raise):
89
94
  # This is not a raise statement
90
95
  continue
91
- raise_node = call_node.parent
96
+ raise_node = get_parent(call_node)
92
97
 
93
98
  if len(call_node.args) > 0 or len(call_node.keywords) > 0:
94
99
  # This is a call with arguments
@@ -101,7 +106,7 @@ def _remove_empty_call(binding):
101
106
  raise_node.exc = name_node
102
107
  elif raise_node.cause is call_node:
103
108
  raise_node.cause = name_node
104
- name_node.parent = raise_node
109
+ set_parent(name_node, raise_node)
105
110
 
106
111
 
107
112
  def remove_no_arg_exception_call(module):
@@ -1,8 +1,9 @@
1
- import python_minifier.ast_compat as ast
2
1
  import sys
3
2
 
3
+ import python_minifier.ast_compat as ast
4
+
4
5
  from python_minifier.transforms.suite_transformer import SuiteTransformer
5
- from python_minifier.util import is_ast_node
6
+ from python_minifier.util import is_constant_node
6
7
 
7
8
 
8
9
  class RemoveExplicitReturnNone(SuiteTransformer):
@@ -17,13 +18,13 @@ class RemoveExplicitReturnNone(SuiteTransformer):
17
18
  if sys.version_info < (3, 4) and isinstance(node.value, ast.Name) and node.value.id == 'None':
18
19
  node.value = None
19
20
 
20
- elif sys.version_info >= (3, 4) and is_ast_node(node.value, 'NameConstant') and node.value.value is None:
21
+ elif sys.version_info >= (3, 4) and is_constant_node(node.value, ast.NameConstant) and node.value.value is None:
21
22
  node.value = None
22
23
 
23
24
  return node
24
25
 
25
26
  def visit_FunctionDef(self, node):
26
- assert is_ast_node(node, (ast.FunctionDef, 'AsyncFunctionDef'))
27
+ assert isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))
27
28
 
28
29
  node.body = [self.visit(a) for a in node.body]
29
30