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.
- python_minifier/__init__.py +12 -8
- python_minifier/__init__.pyi +6 -1
- python_minifier/__main__.py +10 -7
- python_minifier/ast_annotation/__init__.py +82 -0
- python_minifier/ast_compare.py +1 -3
- python_minifier/ast_compat.py +38 -0
- python_minifier/ast_printer.py +8 -5
- python_minifier/expression_printer.py +14 -13
- python_minifier/f_string.py +13 -14
- python_minifier/ministring.py +3 -3
- python_minifier/module_printer.py +13 -14
- python_minifier/rename/__init__.py +1 -1
- python_minifier/rename/bind_names.py +2 -1
- python_minifier/rename/binding.py +39 -40
- python_minifier/rename/mapper.py +66 -50
- python_minifier/rename/rename_literals.py +17 -15
- python_minifier/rename/renamer.py +26 -28
- python_minifier/rename/resolve_names.py +8 -7
- python_minifier/rename/util.py +7 -5
- python_minifier/token_printer.py +3 -0
- python_minifier/transforms/combine_imports.py +0 -1
- python_minifier/transforms/constant_folding.py +16 -10
- python_minifier/transforms/remove_annotations.py +18 -16
- python_minifier/transforms/remove_annotations_options.py +3 -1
- python_minifier/transforms/remove_annotations_options.pyi +8 -7
- python_minifier/transforms/remove_asserts.py +1 -2
- python_minifier/transforms/remove_debug.py +4 -3
- python_minifier/transforms/remove_exception_brackets.py +12 -7
- python_minifier/transforms/remove_explicit_return_none.py +5 -4
- python_minifier/transforms/remove_literal_statements.py +5 -6
- python_minifier/transforms/remove_object_base.py +2 -1
- python_minifier/transforms/remove_pass.py +1 -2
- python_minifier/transforms/remove_posargs.py +3 -4
- python_minifier/transforms/suite_transformer.py +6 -5
- python_minifier/util.py +12 -18
- {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/METADATA +1 -1
- python_minifier-2.11.3.dist-info/RECORD +45 -0
- python_minifier-2.11.2.dist-info/RECORD +0 -44
- {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/LICENSE +0 -0
- {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/WHEEL +0 -0
- {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/entry_points.txt +0 -0
- {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/top_level.txt +0 -0
- {python_minifier-2.11.2.dist-info → python_minifier-2.11.3.dist-info}/zip-safe +0 -0
|
@@ -1,9 +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 .expression_printer import ExpressionPrinter
|
|
5
6
|
from .token_printer import Delimiter
|
|
6
|
-
from .util import is_ast_node
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class ModulePrinter(ExpressionPrinter):
|
|
@@ -55,7 +55,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
55
55
|
def visit_Expr(self, node):
|
|
56
56
|
assert isinstance(node, ast.Expr)
|
|
57
57
|
|
|
58
|
-
if
|
|
58
|
+
if isinstance(node.value, (ast.Yield, ast.YieldFrom)):
|
|
59
59
|
self._yield_expr(node.value)
|
|
60
60
|
else:
|
|
61
61
|
self._testlist(node.value)
|
|
@@ -82,7 +82,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
82
82
|
self.printer.delimiter('=')
|
|
83
83
|
|
|
84
84
|
# Yield nodes that are the sole node on the right hand side of an assignment do not need parens
|
|
85
|
-
if
|
|
85
|
+
if isinstance(node.value, (ast.Yield, ast.YieldFrom)):
|
|
86
86
|
self._yield_expr(node.value)
|
|
87
87
|
else:
|
|
88
88
|
self._testlist(node.value)
|
|
@@ -97,7 +97,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
97
97
|
self.printer.delimiter('=')
|
|
98
98
|
|
|
99
99
|
# Yield nodes that are the sole node on the right hand side of an assignment do not need parens
|
|
100
|
-
if
|
|
100
|
+
if isinstance(node.value, (ast.Yield, ast.YieldFrom)):
|
|
101
101
|
self._yield_expr(node.value)
|
|
102
102
|
else:
|
|
103
103
|
self._testlist(node.value)
|
|
@@ -143,7 +143,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
143
143
|
|
|
144
144
|
self.printer.keyword('return')
|
|
145
145
|
if isinstance(node.value, ast.Tuple):
|
|
146
|
-
if sys.version_info < (3, 8) and [n for n in node.value.elts if
|
|
146
|
+
if sys.version_info < (3, 8) and [n for n in node.value.elts if isinstance(n, ast.Starred)]:
|
|
147
147
|
self.printer.delimiter('(')
|
|
148
148
|
self._testlist(node.value)
|
|
149
149
|
self.printer.delimiter(')')
|
|
@@ -243,7 +243,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
243
243
|
assert isinstance(node, ast.ImportFrom)
|
|
244
244
|
|
|
245
245
|
self.printer.keyword('from')
|
|
246
|
-
for
|
|
246
|
+
for _i in range(node.level):
|
|
247
247
|
self.printer.delimiter('.')
|
|
248
248
|
if node.module is not None:
|
|
249
249
|
self.printer.identifier(node.module)
|
|
@@ -326,7 +326,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
326
326
|
self._suite(node.orelse)
|
|
327
327
|
|
|
328
328
|
def visit_For(self, node, is_async=False):
|
|
329
|
-
assert isinstance(node, ast.For
|
|
329
|
+
assert isinstance(node, (ast.For, ast.AsyncFor))
|
|
330
330
|
|
|
331
331
|
self.printer.newline()
|
|
332
332
|
|
|
@@ -362,7 +362,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
362
362
|
self._suite(node.orelse)
|
|
363
363
|
|
|
364
364
|
def visit_Try(self, node, star=False):
|
|
365
|
-
assert
|
|
365
|
+
assert isinstance(node, (ast.Try, ast.TryStar))
|
|
366
366
|
|
|
367
367
|
self.printer.newline()
|
|
368
368
|
self.printer.keyword('try')
|
|
@@ -440,7 +440,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
440
440
|
self._suite(node.body)
|
|
441
441
|
|
|
442
442
|
def visit_With(self, node, is_async=False):
|
|
443
|
-
assert
|
|
443
|
+
assert isinstance(node, (ast.With, ast.AsyncWith))
|
|
444
444
|
|
|
445
445
|
self.printer.newline()
|
|
446
446
|
|
|
@@ -469,7 +469,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
469
469
|
self._suite(node.body)
|
|
470
470
|
|
|
471
471
|
def visit_withitem(self, node):
|
|
472
|
-
assert
|
|
472
|
+
assert isinstance(node, (ast.withitem, ast.With))
|
|
473
473
|
|
|
474
474
|
self._expression(node.context_expr)
|
|
475
475
|
|
|
@@ -478,7 +478,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
478
478
|
self._expression(node.optional_vars)
|
|
479
479
|
|
|
480
480
|
def visit_FunctionDef(self, node, is_async=False):
|
|
481
|
-
assert
|
|
481
|
+
assert isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef))
|
|
482
482
|
|
|
483
483
|
self.printer.newline()
|
|
484
484
|
|
|
@@ -670,7 +670,7 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
670
670
|
for kwd, pattern in zip(node.kwd_attrs, node.kwd_patterns):
|
|
671
671
|
delimiter.new_item()
|
|
672
672
|
|
|
673
|
-
self.printer.identifier(kwd)
|
|
673
|
+
self.printer.identifier(kwd)
|
|
674
674
|
self.printer.delimiter('=')
|
|
675
675
|
|
|
676
676
|
self.pattern(pattern)
|
|
@@ -859,4 +859,3 @@ class ModulePrinter(ExpressionPrinter):
|
|
|
859
859
|
|
|
860
860
|
for node in node_list:
|
|
861
861
|
statements[node.__class__.__name__](node)
|
|
862
|
-
|
|
@@ -3,4 +3,4 @@ from python_minifier.rename.mapper import add_namespace
|
|
|
3
3
|
from python_minifier.rename.rename_literals import rename_literals
|
|
4
4
|
from python_minifier.rename.renamer import rename
|
|
5
5
|
from python_minifier.rename.resolve_names import resolve_names
|
|
6
|
-
from python_minifier.rename.util import
|
|
6
|
+
from python_minifier.rename.util import allow_rename_globals, allow_rename_locals
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import python_minifier.ast_compat as ast
|
|
2
2
|
|
|
3
3
|
from python_minifier.rename.binding import NameBinding
|
|
4
|
-
from python_minifier.rename.util import arg_rename_in_place,
|
|
4
|
+
from python_minifier.rename.util import arg_rename_in_place, builtins, get_global_namespace
|
|
5
5
|
from python_minifier.transforms.suite_transformer import NodeVisitor
|
|
6
6
|
|
|
7
7
|
|
|
@@ -180,6 +180,7 @@ class NameBinder(NodeVisitor):
|
|
|
180
180
|
|
|
181
181
|
get_global_namespace(node.namespace).preserved.add(node.name)
|
|
182
182
|
|
|
183
|
+
|
|
183
184
|
def bind_names(module):
|
|
184
185
|
"""
|
|
185
186
|
Bind names to their local namespace
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import python_minifier.ast_compat as ast
|
|
2
2
|
|
|
3
3
|
from python_minifier.rename.util import arg_rename_in_place, insert
|
|
4
|
-
from python_minifier.util import is_ast_node
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
class Binding(object):
|
|
@@ -105,11 +104,11 @@ class Binding(object):
|
|
|
105
104
|
# Python 2 Param context
|
|
106
105
|
if not arg_rename_in_place(node):
|
|
107
106
|
arg_rename = True
|
|
108
|
-
elif
|
|
107
|
+
elif isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
109
108
|
pass
|
|
110
109
|
elif isinstance(node, ast.ExceptHandler):
|
|
111
110
|
pass
|
|
112
|
-
elif
|
|
111
|
+
elif isinstance(node, (ast.Global, ast.Nonlocal)):
|
|
113
112
|
pass
|
|
114
113
|
elif isinstance(node, ast.alias):
|
|
115
114
|
if node.asname is None:
|
|
@@ -119,22 +118,22 @@ class Binding(object):
|
|
|
119
118
|
pass
|
|
120
119
|
if node.kwarg == self._name:
|
|
121
120
|
pass
|
|
122
|
-
elif
|
|
121
|
+
elif isinstance(node, ast.arg):
|
|
123
122
|
if not arg_rename_in_place(node):
|
|
124
123
|
arg_rename = True
|
|
125
124
|
|
|
126
|
-
elif
|
|
125
|
+
elif isinstance(node, ast.MatchAs):
|
|
127
126
|
if node.name is None:
|
|
128
127
|
additional_bytes += 4 # ' as '
|
|
129
|
-
elif
|
|
128
|
+
elif isinstance(node, ast.MatchStar):
|
|
130
129
|
pass
|
|
131
|
-
elif
|
|
130
|
+
elif isinstance(node, ast.MatchMapping):
|
|
132
131
|
pass
|
|
133
|
-
elif
|
|
132
|
+
elif isinstance(node, ast.TypeVar):
|
|
134
133
|
pass
|
|
135
|
-
elif
|
|
134
|
+
elif isinstance(node, ast.TypeVarTuple):
|
|
136
135
|
pass
|
|
137
|
-
elif
|
|
136
|
+
elif isinstance(node, ast.ParamSpec):
|
|
138
137
|
pass
|
|
139
138
|
|
|
140
139
|
else:
|
|
@@ -160,11 +159,11 @@ class Binding(object):
|
|
|
160
159
|
mentions += 1
|
|
161
160
|
arg_rename = True
|
|
162
161
|
|
|
163
|
-
elif
|
|
162
|
+
elif isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
164
163
|
pass
|
|
165
164
|
elif isinstance(node, ast.ExceptHandler):
|
|
166
165
|
pass
|
|
167
|
-
elif
|
|
166
|
+
elif isinstance(node, (ast.Global, ast.Nonlocal)):
|
|
168
167
|
pass
|
|
169
168
|
elif isinstance(node, ast.alias):
|
|
170
169
|
if node.asname is None:
|
|
@@ -172,22 +171,22 @@ class Binding(object):
|
|
|
172
171
|
mentions += 1
|
|
173
172
|
elif isinstance(node, ast.arguments):
|
|
174
173
|
pass
|
|
175
|
-
elif
|
|
174
|
+
elif isinstance(node, ast.arg):
|
|
176
175
|
if not arg_rename_in_place(node):
|
|
177
176
|
mentions += 1
|
|
178
177
|
arg_rename = True
|
|
179
178
|
|
|
180
|
-
elif
|
|
179
|
+
elif isinstance(node, ast.MatchAs):
|
|
181
180
|
pass
|
|
182
|
-
elif
|
|
181
|
+
elif isinstance(node, ast.MatchStar):
|
|
183
182
|
pass
|
|
184
|
-
elif
|
|
183
|
+
elif isinstance(node, ast.MatchMapping):
|
|
185
184
|
pass
|
|
186
|
-
elif
|
|
185
|
+
elif isinstance(node, ast.TypeVar):
|
|
187
186
|
pass
|
|
188
|
-
elif
|
|
187
|
+
elif isinstance(node, ast.TypeVarTuple):
|
|
189
188
|
pass
|
|
190
|
-
elif
|
|
189
|
+
elif isinstance(node, ast.ParamSpec):
|
|
191
190
|
pass
|
|
192
191
|
|
|
193
192
|
else:
|
|
@@ -210,11 +209,11 @@ class Binding(object):
|
|
|
210
209
|
else:
|
|
211
210
|
# Python 2 Param context
|
|
212
211
|
arg_rename = True
|
|
213
|
-
elif
|
|
212
|
+
elif isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
214
213
|
mentions += 1
|
|
215
214
|
elif isinstance(node, ast.ExceptHandler):
|
|
216
215
|
mentions += 1
|
|
217
|
-
elif
|
|
216
|
+
elif isinstance(node, (ast.Global, ast.Nonlocal)):
|
|
218
217
|
mentions += len([n for n in node.names if n == self._name])
|
|
219
218
|
elif isinstance(node, ast.alias):
|
|
220
219
|
mentions += 1
|
|
@@ -223,20 +222,20 @@ class Binding(object):
|
|
|
223
222
|
mentions += 1
|
|
224
223
|
if node.kwarg == self._name:
|
|
225
224
|
mentions += 1
|
|
226
|
-
elif
|
|
225
|
+
elif isinstance(node, ast.arg):
|
|
227
226
|
arg_rename = True
|
|
228
227
|
|
|
229
|
-
elif
|
|
228
|
+
elif isinstance(node, ast.MatchAs):
|
|
230
229
|
mentions += 1
|
|
231
|
-
elif
|
|
230
|
+
elif isinstance(node, ast.MatchStar):
|
|
232
231
|
mentions += 1
|
|
233
|
-
elif
|
|
232
|
+
elif isinstance(node, ast.MatchMapping):
|
|
234
233
|
mentions += 1
|
|
235
|
-
elif
|
|
234
|
+
elif isinstance(node, ast.TypeVar):
|
|
236
235
|
mentions += 1
|
|
237
|
-
elif
|
|
236
|
+
elif isinstance(node, ast.TypeVarTuple):
|
|
238
237
|
mentions += 1
|
|
239
|
-
elif
|
|
238
|
+
elif isinstance(node, ast.ParamSpec):
|
|
240
239
|
mentions += 1
|
|
241
240
|
|
|
242
241
|
else:
|
|
@@ -273,7 +272,7 @@ class Binding(object):
|
|
|
273
272
|
|
|
274
273
|
"""
|
|
275
274
|
|
|
276
|
-
raise NotImplementedError
|
|
275
|
+
raise NotImplementedError
|
|
277
276
|
|
|
278
277
|
def rename(self, new_name):
|
|
279
278
|
"""
|
|
@@ -283,7 +282,7 @@ class Binding(object):
|
|
|
283
282
|
|
|
284
283
|
"""
|
|
285
284
|
|
|
286
|
-
raise NotImplementedError
|
|
285
|
+
raise NotImplementedError
|
|
287
286
|
|
|
288
287
|
|
|
289
288
|
class NameBinding(Binding):
|
|
@@ -362,7 +361,7 @@ class NameBinding(Binding):
|
|
|
362
361
|
else:
|
|
363
362
|
assert func_namespace_binding is node.namespace
|
|
364
363
|
|
|
365
|
-
elif
|
|
364
|
+
elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
366
365
|
node.name = new_name
|
|
367
366
|
elif isinstance(node, ast.ClassDef):
|
|
368
367
|
node.name = new_name
|
|
@@ -371,7 +370,7 @@ class NameBinding(Binding):
|
|
|
371
370
|
node.asname = None
|
|
372
371
|
else:
|
|
373
372
|
node.asname = new_name
|
|
374
|
-
elif
|
|
373
|
+
elif isinstance(node, ast.arg):
|
|
375
374
|
|
|
376
375
|
if arg_rename_in_place(node):
|
|
377
376
|
node.arg = new_name
|
|
@@ -384,7 +383,7 @@ class NameBinding(Binding):
|
|
|
384
383
|
|
|
385
384
|
elif isinstance(node, ast.ExceptHandler):
|
|
386
385
|
node.name = new_name
|
|
387
|
-
elif
|
|
386
|
+
elif isinstance(node, (ast.Global, ast.Nonlocal)):
|
|
388
387
|
node.names = [new_name if n == self._name else n for n in node.names]
|
|
389
388
|
elif isinstance(node, ast.arguments):
|
|
390
389
|
|
|
@@ -398,17 +397,17 @@ class NameBinding(Binding):
|
|
|
398
397
|
node.kwarg = new_name
|
|
399
398
|
node.kwarg_renamed = True
|
|
400
399
|
|
|
401
|
-
elif
|
|
400
|
+
elif isinstance(node, ast.MatchAs):
|
|
402
401
|
node.name = new_name
|
|
403
|
-
elif
|
|
402
|
+
elif isinstance(node, ast.MatchStar):
|
|
404
403
|
node.name = new_name
|
|
405
|
-
elif
|
|
404
|
+
elif isinstance(node, ast.MatchMapping):
|
|
406
405
|
node.rest = new_name
|
|
407
|
-
elif
|
|
406
|
+
elif isinstance(node, ast.TypeVar):
|
|
408
407
|
node.name = new_name
|
|
409
|
-
elif
|
|
408
|
+
elif isinstance(node, ast.TypeVarTuple):
|
|
410
409
|
node.name = new_name
|
|
411
|
-
elif
|
|
410
|
+
elif isinstance(node, ast.ParamSpec):
|
|
412
411
|
node.name = new_name
|
|
413
412
|
|
|
414
413
|
if func_namespace_binding is not None:
|
|
@@ -492,4 +491,4 @@ class BuiltinBinding(NameBinding):
|
|
|
492
491
|
if not isinstance(node.ctx, ast.Load):
|
|
493
492
|
return True
|
|
494
493
|
|
|
495
|
-
return False
|
|
494
|
+
return False
|
python_minifier/rename/mapper.py
CHANGED
|
@@ -3,48 +3,47 @@ For each node in an AST set the namespace to use for name binding and resolution
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import python_minifier.ast_compat as ast
|
|
6
|
+
from python_minifier.ast_annotation import get_parent
|
|
6
7
|
|
|
7
8
|
from python_minifier.rename.util import is_namespace
|
|
8
|
-
from python_minifier.util import is_ast_node
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def add_parent_to_arguments(arguments, func):
|
|
12
|
-
arguments.parent = func
|
|
13
12
|
arguments.namespace = func
|
|
14
13
|
|
|
15
14
|
for arg in getattr(arguments, 'posonlyargs', []) + arguments.args:
|
|
16
|
-
add_parent(arg,
|
|
15
|
+
add_parent(arg, func)
|
|
17
16
|
if hasattr(arg, 'annotation') and arg.annotation is not None:
|
|
18
|
-
add_parent(arg.annotation,
|
|
17
|
+
add_parent(arg.annotation, func.namespace)
|
|
19
18
|
|
|
20
19
|
if hasattr(arguments, 'kwonlyargs'):
|
|
21
20
|
for arg in arguments.kwonlyargs:
|
|
22
|
-
add_parent(arg,
|
|
21
|
+
add_parent(arg, func)
|
|
23
22
|
if arg.annotation is not None:
|
|
24
|
-
add_parent(arg.annotation,
|
|
23
|
+
add_parent(arg.annotation, func.namespace)
|
|
25
24
|
|
|
26
25
|
for node in arguments.kw_defaults:
|
|
27
26
|
if node is not None:
|
|
28
|
-
add_parent(node,
|
|
27
|
+
add_parent(node, func.namespace)
|
|
29
28
|
|
|
30
29
|
for node in arguments.defaults:
|
|
31
|
-
add_parent(node,
|
|
30
|
+
add_parent(node, func.namespace)
|
|
32
31
|
|
|
33
32
|
if arguments.vararg:
|
|
34
33
|
if hasattr(arguments, 'varargannotation') and arguments.varargannotation is not None:
|
|
35
|
-
add_parent(arguments.varargannotation,
|
|
34
|
+
add_parent(arguments.varargannotation, func.namespace)
|
|
36
35
|
elif isinstance(arguments.vararg, str):
|
|
37
36
|
pass
|
|
38
37
|
else:
|
|
39
|
-
add_parent(arguments.vararg,
|
|
38
|
+
add_parent(arguments.vararg, func)
|
|
40
39
|
|
|
41
40
|
if arguments.kwarg:
|
|
42
41
|
if hasattr(arguments, 'kwargannotation') and arguments.kwargannotation is not None:
|
|
43
|
-
add_parent(arguments.kwargannotation,
|
|
42
|
+
add_parent(arguments.kwargannotation, func.namespace)
|
|
44
43
|
elif isinstance(arguments.kwarg, str):
|
|
45
44
|
pass
|
|
46
45
|
else:
|
|
47
|
-
add_parent(arguments.kwarg,
|
|
46
|
+
add_parent(arguments.kwarg, func)
|
|
48
47
|
|
|
49
48
|
|
|
50
49
|
def add_parent_to_functiondef(functiondef):
|
|
@@ -56,17 +55,17 @@ def add_parent_to_functiondef(functiondef):
|
|
|
56
55
|
add_parent_to_arguments(functiondef.args, func=functiondef)
|
|
57
56
|
|
|
58
57
|
for node in functiondef.body:
|
|
59
|
-
add_parent(node,
|
|
58
|
+
add_parent(node, namespace=functiondef)
|
|
60
59
|
|
|
61
60
|
for node in functiondef.decorator_list:
|
|
62
|
-
add_parent(node,
|
|
61
|
+
add_parent(node, namespace=functiondef.namespace)
|
|
63
62
|
|
|
64
63
|
if hasattr(functiondef, 'type_params') and functiondef.type_params is not None:
|
|
65
64
|
for node in functiondef.type_params:
|
|
66
|
-
add_parent(node,
|
|
65
|
+
add_parent(node, namespace=functiondef.namespace)
|
|
67
66
|
|
|
68
67
|
if hasattr(functiondef, 'returns') and functiondef.returns is not None:
|
|
69
|
-
add_parent(functiondef.returns,
|
|
68
|
+
add_parent(functiondef.returns, namespace=functiondef.namespace)
|
|
70
69
|
|
|
71
70
|
|
|
72
71
|
def add_parent_to_classdef(classdef):
|
|
@@ -75,64 +74,77 @@ def add_parent_to_classdef(classdef):
|
|
|
75
74
|
"""
|
|
76
75
|
|
|
77
76
|
for node in classdef.bases:
|
|
78
|
-
add_parent(node,
|
|
77
|
+
add_parent(node, namespace=classdef.namespace)
|
|
79
78
|
|
|
80
79
|
if hasattr(classdef, 'keywords'):
|
|
81
80
|
for node in classdef.keywords:
|
|
82
|
-
add_parent(node,
|
|
81
|
+
add_parent(node, namespace=classdef.namespace)
|
|
83
82
|
|
|
84
83
|
if hasattr(classdef, 'starargs') and classdef.starargs is not None:
|
|
85
|
-
add_parent(classdef.starargs,
|
|
84
|
+
add_parent(classdef.starargs, namespace=classdef.namespace)
|
|
86
85
|
|
|
87
86
|
if hasattr(classdef, 'kwargs') and classdef.kwargs is not None:
|
|
88
|
-
add_parent(classdef.kwargs,
|
|
87
|
+
add_parent(classdef.kwargs, namespace=classdef.namespace)
|
|
89
88
|
|
|
90
89
|
for node in classdef.body:
|
|
91
|
-
add_parent(node,
|
|
90
|
+
add_parent(node, namespace=classdef)
|
|
92
91
|
|
|
93
92
|
for node in classdef.decorator_list:
|
|
94
|
-
add_parent(node,
|
|
93
|
+
add_parent(node, namespace=classdef.namespace)
|
|
95
94
|
|
|
96
95
|
if hasattr(classdef, 'type_params') and classdef.type_params is not None:
|
|
97
96
|
for node in classdef.type_params:
|
|
98
|
-
add_parent(node,
|
|
97
|
+
add_parent(node, namespace=classdef.namespace)
|
|
98
|
+
|
|
99
99
|
|
|
100
100
|
def add_parent_to_comprehension(node, namespace):
|
|
101
|
-
assert
|
|
101
|
+
assert isinstance(node, (ast.GeneratorExp, ast.SetComp, ast.DictComp, ast.ListComp))
|
|
102
102
|
|
|
103
103
|
if hasattr(node, 'elt'):
|
|
104
|
-
add_parent(node.elt,
|
|
104
|
+
add_parent(node.elt, namespace=node)
|
|
105
105
|
elif hasattr(node, 'key'):
|
|
106
|
-
add_parent(node.key,
|
|
107
|
-
add_parent(node.value,
|
|
106
|
+
add_parent(node.key, namespace=node)
|
|
107
|
+
add_parent(node.value, namespace=node)
|
|
108
108
|
|
|
109
109
|
iter_namespace = namespace
|
|
110
110
|
for generator in node.generators:
|
|
111
|
-
generator.parent = node
|
|
112
111
|
generator.namespace = node
|
|
113
112
|
|
|
114
|
-
add_parent(generator.target,
|
|
115
|
-
add_parent(generator.iter,
|
|
116
|
-
|
|
113
|
+
add_parent(generator.target, namespace=node)
|
|
114
|
+
add_parent(generator.iter, namespace=iter_namespace)
|
|
115
|
+
|
|
117
116
|
for if_ in generator.ifs:
|
|
118
|
-
add_parent(if_,
|
|
117
|
+
add_parent(if_, namespace=node)
|
|
119
118
|
|
|
119
|
+
iter_namespace = node
|
|
120
120
|
|
|
121
|
-
def
|
|
121
|
+
def namedexpr_namespace(node):
|
|
122
|
+
"""
|
|
123
|
+
Get the namespace for a NamedExpr target
|
|
124
|
+
"""
|
|
125
|
+
|
|
126
|
+
if not isinstance(node, (ast.ListComp, ast.DictComp, ast.SetComp, ast.GeneratorExp)):
|
|
127
|
+
return node
|
|
128
|
+
|
|
129
|
+
return namedexpr_namespace(node.namespace)
|
|
130
|
+
|
|
131
|
+
def add_parent_to_namedexpr(node):
|
|
132
|
+
assert isinstance(node, ast.NamedExpr)
|
|
133
|
+
|
|
134
|
+
add_parent(node.target, namespace=namedexpr_namespace(node.namespace))
|
|
135
|
+
add_parent(node.value, namespace=node.namespace)
|
|
136
|
+
|
|
137
|
+
def add_parent(node, namespace=None):
|
|
122
138
|
"""
|
|
123
|
-
Add a parent attribute to child nodes
|
|
124
139
|
Add a namespace attribute to child nodes
|
|
125
140
|
|
|
126
|
-
:param node: The tree to add
|
|
141
|
+
:param node: The tree to add namespace properties to
|
|
127
142
|
:type node: :class:`ast.AST`
|
|
128
|
-
:param parent: The parent node of this node
|
|
129
|
-
:type parent: :class:`ast.AST`
|
|
130
143
|
:param namespace: The namespace Node that this node is in
|
|
131
144
|
:type namespace: ast.Lambda or ast.Module or ast.FunctionDef or ast.AsyncFunctionDef or ast.ClassDef or ast.DictComp or ast.SetComp or ast.ListComp or ast.Generator
|
|
132
145
|
|
|
133
146
|
"""
|
|
134
147
|
|
|
135
|
-
node.parent = parent if parent is not None else node
|
|
136
148
|
node.namespace = namespace if namespace is not None else node
|
|
137
149
|
|
|
138
150
|
if is_namespace(node):
|
|
@@ -140,35 +152,39 @@ def add_parent(node, parent=None, namespace=None):
|
|
|
140
152
|
node.global_names = set()
|
|
141
153
|
node.nonlocal_names = set()
|
|
142
154
|
|
|
143
|
-
if
|
|
155
|
+
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
|
|
144
156
|
add_parent_to_functiondef(node)
|
|
145
|
-
elif
|
|
157
|
+
elif isinstance(node, (ast.GeneratorExp, ast.SetComp, ast.DictComp, ast.ListComp)):
|
|
146
158
|
add_parent_to_comprehension(node, namespace=namespace)
|
|
147
159
|
elif isinstance(node, ast.Lambda):
|
|
148
160
|
add_parent_to_arguments(node.args, func=node)
|
|
149
|
-
add_parent(node.body,
|
|
161
|
+
add_parent(node.body, namespace=node)
|
|
150
162
|
elif isinstance(node, ast.ClassDef):
|
|
151
163
|
add_parent_to_classdef(node)
|
|
152
164
|
else:
|
|
153
165
|
for child in ast.iter_child_nodes(node):
|
|
154
|
-
add_parent(child,
|
|
166
|
+
add_parent(child, namespace=node)
|
|
155
167
|
|
|
156
168
|
return
|
|
157
169
|
|
|
158
170
|
if isinstance(node, ast.Global):
|
|
159
171
|
namespace.global_names.update(node.names)
|
|
160
|
-
if
|
|
172
|
+
if isinstance(node, ast.Nonlocal):
|
|
161
173
|
namespace.nonlocal_names.update(node.names)
|
|
162
174
|
|
|
163
|
-
if isinstance(node, ast.Name):
|
|
164
|
-
if isinstance(
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
175
|
+
if isinstance(node, ast.Name) and isinstance(namespace, ast.ClassDef):
|
|
176
|
+
if isinstance(node.ctx, ast.Load):
|
|
177
|
+
namespace.nonlocal_names.add(node.id)
|
|
178
|
+
elif isinstance(node.ctx, ast.Store) and isinstance(get_parent(node), ast.AugAssign):
|
|
179
|
+
namespace.nonlocal_names.add(node.id)
|
|
180
|
+
|
|
181
|
+
if isinstance(node, ast.NamedExpr):
|
|
182
|
+
# NamedExpr is 'special'
|
|
183
|
+
add_parent_to_namedexpr(node)
|
|
184
|
+
return
|
|
169
185
|
|
|
170
186
|
for child in ast.iter_child_nodes(node):
|
|
171
|
-
add_parent(child,
|
|
187
|
+
add_parent(child, namespace=namespace)
|
|
172
188
|
|
|
173
189
|
|
|
174
190
|
def add_namespace(module):
|