Skip to content

Commit 678a761

Browse files
authored
Merge pull request #104 from dflook/python312-typeparam-rename
Add type parameter renaming support
2 parents 333acfe + 03ec99a commit 678a761

File tree

6 files changed

+87
-16
lines changed

6 files changed

+87
-16
lines changed

src/python_minifier/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,18 @@ def minify(
166166
rename_globals = False
167167
rename_locals = False
168168

169+
if preserve_locals is None:
170+
preserve_locals = []
171+
elif isinstance(preserve_locals, str):
172+
preserve_locals = [preserve_locals]
173+
if preserve_globals is None:
174+
preserve_globals = []
175+
elif isinstance(preserve_globals, str):
176+
preserve_globals = [preserve_globals]
177+
178+
preserve_locals.extend(module.preserved)
179+
preserve_globals.extend(module.preserved)
180+
169181
allow_rename_locals(module, rename_locals, preserve_locals)
170182
allow_rename_globals(module, rename_globals, preserve_globals)
171183

src/python_minifier/rename/bind_names.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class NameBinder(NodeVisitor):
1515
def __call__(self, module):
1616
assert isinstance(module, ast.Module)
1717
module.tainted = False
18+
module.preserved = set()
1819
return self.visit(module)
1920

2021
def get_binding(self, name, namespace):
@@ -161,6 +162,24 @@ def visit_MatchMapping(self, node):
161162

162163
self.generic_visit(node)
163164

165+
def visit_TypeVar(self, node):
166+
if node.name not in node.namespace.nonlocal_names:
167+
self.get_binding(node.name, node.namespace).add_reference(node)
168+
169+
get_global_namespace(node.namespace).preserved.add(node.name)
170+
171+
def visit_TypeVarTuple(self, node):
172+
if node.name not in node.namespace.nonlocal_names:
173+
self.get_binding(node.name, node.namespace).add_reference(node)
174+
175+
get_global_namespace(node.namespace).preserved.add(node.name)
176+
177+
def visit_ParamSpec(self, node):
178+
if node.name not in node.namespace.nonlocal_names:
179+
self.get_binding(node.name, node.namespace).add_reference(node)
180+
181+
get_global_namespace(node.namespace).preserved.add(node.name)
182+
164183
def bind_names(module):
165184
"""
166185
Bind names to their local namespace

src/python_minifier/rename/binding.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ def additional_byte_cost(self):
130130
pass
131131
elif is_ast_node(node, 'MatchMapping'):
132132
pass
133+
elif is_ast_node(node, 'TypeVar'):
134+
pass
135+
elif is_ast_node(node, 'TypeVarTuple'):
136+
pass
137+
elif is_ast_node(node, 'ParamSpec'):
138+
pass
133139

134140
else:
135141
raise AssertionError('Unknown reference node')
@@ -177,6 +183,12 @@ def old_mention_count(self):
177183
pass
178184
elif is_ast_node(node, 'MatchMapping'):
179185
pass
186+
elif is_ast_node(node, 'TypeVar'):
187+
pass
188+
elif is_ast_node(node, 'TypeVarTuple'):
189+
pass
190+
elif is_ast_node(node, 'ParamSpec'):
191+
pass
180192

181193
else:
182194
raise AssertionError('Unknown reference node')
@@ -220,6 +232,12 @@ def new_mention_count(self):
220232
mentions += 1
221233
elif is_ast_node(node, 'MatchMapping'):
222234
mentions += 1
235+
elif is_ast_node(node, 'TypeVar'):
236+
mentions += 1
237+
elif is_ast_node(node, 'TypeVarTuple'):
238+
mentions += 1
239+
elif is_ast_node(node, 'ParamSpec'):
240+
mentions += 1
223241

224242
else:
225243
raise AssertionError('Unknown reference node')
@@ -386,6 +404,12 @@ def rename(self, new_name):
386404
node.name = new_name
387405
elif is_ast_node(node, 'MatchMapping'):
388406
node.rest = new_name
407+
elif is_ast_node(node, 'TypeVar'):
408+
node.name = new_name
409+
elif is_ast_node(node, 'TypeVarTuple'):
410+
node.name = new_name
411+
elif is_ast_node(node, 'ParamSpec'):
412+
node.name = new_name
389413

390414
if func_namespace_binding is not None:
391415
func_namespace_binding.body = list(

xtest/manifests/python3.10_test_manifest.yaml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -865,17 +865,21 @@
865865
rename_globals: true
866866
/usr/local/lib/python3.10/test/test_contextlib_async.py:
867867
- options:
868-
preserve_locals: baz
868+
preserve_locals:
869+
- baz
869870
- options:
870871
rename_globals: true
871-
preserve_locals: baz
872+
preserve_locals:
873+
- baz
872874
- options:
873875
remove_literal_statements: true
874-
preserve_locals: baz
876+
preserve_locals:
877+
- baz
875878
- options:
876879
remove_literal_statements: true
877880
rename_globals: true
878-
preserve_locals: baz
881+
preserve_locals:
882+
- baz
879883
/usr/local/lib/python3.10/test/test_copy.py:
880884
- options: {}
881885
- options:

xtest/manifests/python3.11_test_manifest.yaml

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -188,17 +188,21 @@
188188
/usr/local/lib/python3.11/test/test_asyncio/test_futures.py: []
189189
/usr/local/lib/python3.11/test/test_asyncio/test_futures2.py:
190190
- options:
191-
preserve_locals: future
191+
preserve_locals:
192+
- future
192193
- options:
193194
rename_globals: true
194-
preserve_locals: future
195+
preserve_locals:
196+
- future
195197
- options:
196198
remove_literal_statements: true
197-
preserve_locals: future
199+
preserve_locals:
200+
- future
198201
- options:
199202
remove_literal_statements: true
200203
rename_globals: true
201-
preserve_locals: future
204+
preserve_locals:
205+
- future
202206
/usr/local/lib/python3.11/test/test_asyncio/test_locks.py:
203207
- options: {}
204208
- options:
@@ -2904,17 +2908,21 @@
29042908
rename_globals: true
29052909
/usr/local/lib/python3.11/test/test_opcache.py:
29062910
- options:
2907-
preserve_locals: Class
2911+
preserve_locals:
2912+
- Class
29082913
- options:
29092914
rename_globals: true
2910-
preserve_locals: Class
2915+
preserve_locals:
2916+
- Class
29112917
- options:
29122918
remove_literal_statements: true
2913-
preserve_locals: Class
2919+
preserve_locals:
2920+
- Class
29142921
- options:
29152922
remove_literal_statements: true
29162923
rename_globals: true
2917-
preserve_locals: Class
2924+
preserve_locals:
2925+
- Class
29182926
/usr/local/lib/python3.11/test/test_opcodes.py:
29192927
- options: {}
29202928
- options:

xtest/manifests/python3.12_test_manifest.yaml

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4740,20 +4740,24 @@
47404740
status: passing
47414741
/usr/local/lib/python3.12/test/test_opcache.py:
47424742
- options:
4743-
preserve_locals: Class
4743+
preserve_locals:
4744+
- Class
47444745
remove_literal_statements: true
47454746
rename_globals: true
47464747
status: passing
47474748
- options:
4748-
preserve_locals: Class
4749+
preserve_locals:
4750+
- Class
47494751
rename_globals: true
47504752
status: passing
47514753
- options:
4752-
preserve_locals: Class
4754+
preserve_locals:
4755+
- Class
47534756
remove_literal_statements: true
47544757
status: passing
47554758
- options:
4756-
preserve_locals: Class
4759+
preserve_locals:
4760+
- Class
47574761
status: passing
47584762
/usr/local/lib/python3.12/test/test_opcodes.py:
47594763
- options:

0 commit comments

Comments
 (0)