Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions src/python_minifier/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,18 @@ def minify(
rename_globals = False
rename_locals = False

if preserve_locals is None:
preserve_locals = []
elif isinstance(preserve_locals, str):
preserve_locals = [preserve_locals]
if preserve_globals is None:
preserve_globals = []
elif isinstance(preserve_globals, str):
preserve_globals = [preserve_globals]

preserve_locals.extend(module.preserved)
preserve_globals.extend(module.preserved)

allow_rename_locals(module, rename_locals, preserve_locals)
allow_rename_globals(module, rename_globals, preserve_globals)

Expand Down
19 changes: 19 additions & 0 deletions src/python_minifier/rename/bind_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class NameBinder(NodeVisitor):
def __call__(self, module):
assert isinstance(module, ast.Module)
module.tainted = False
module.preserved = set()
return self.visit(module)

def get_binding(self, name, namespace):
Expand Down Expand Up @@ -161,6 +162,24 @@ def visit_MatchMapping(self, node):

self.generic_visit(node)

def visit_TypeVar(self, node):
if node.name not in node.namespace.nonlocal_names:
self.get_binding(node.name, node.namespace).add_reference(node)

get_global_namespace(node.namespace).preserved.add(node.name)

def visit_TypeVarTuple(self, node):
if node.name not in node.namespace.nonlocal_names:
self.get_binding(node.name, node.namespace).add_reference(node)

get_global_namespace(node.namespace).preserved.add(node.name)

def visit_ParamSpec(self, node):
if node.name not in node.namespace.nonlocal_names:
self.get_binding(node.name, node.namespace).add_reference(node)

get_global_namespace(node.namespace).preserved.add(node.name)

def bind_names(module):
"""
Bind names to their local namespace
Expand Down
24 changes: 24 additions & 0 deletions src/python_minifier/rename/binding.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ def additional_byte_cost(self):
pass
elif is_ast_node(node, 'MatchMapping'):
pass
elif is_ast_node(node, 'TypeVar'):
pass
elif is_ast_node(node, 'TypeVarTuple'):
pass
elif is_ast_node(node, 'ParamSpec'):
pass

else:
raise AssertionError('Unknown reference node')
Expand Down Expand Up @@ -177,6 +183,12 @@ def old_mention_count(self):
pass
elif is_ast_node(node, 'MatchMapping'):
pass
elif is_ast_node(node, 'TypeVar'):
pass
elif is_ast_node(node, 'TypeVarTuple'):
pass
elif is_ast_node(node, 'ParamSpec'):
pass

else:
raise AssertionError('Unknown reference node')
Expand Down Expand Up @@ -220,6 +232,12 @@ def new_mention_count(self):
mentions += 1
elif is_ast_node(node, 'MatchMapping'):
mentions += 1
elif is_ast_node(node, 'TypeVar'):
mentions += 1
elif is_ast_node(node, 'TypeVarTuple'):
mentions += 1
elif is_ast_node(node, 'ParamSpec'):
mentions += 1

else:
raise AssertionError('Unknown reference node')
Expand Down Expand Up @@ -386,6 +404,12 @@ def rename(self, new_name):
node.name = new_name
elif is_ast_node(node, 'MatchMapping'):
node.rest = new_name
elif is_ast_node(node, 'TypeVar'):
node.name = new_name
elif is_ast_node(node, 'TypeVarTuple'):
node.name = new_name
elif is_ast_node(node, 'ParamSpec'):
node.name = new_name

if func_namespace_binding is not None:
func_namespace_binding.body = list(
Expand Down
12 changes: 8 additions & 4 deletions xtest/manifests/python3.10_test_manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -865,17 +865,21 @@
rename_globals: true
/usr/local/lib/python3.10/test/test_contextlib_async.py:
- options:
preserve_locals: baz
preserve_locals:
- baz
- options:
rename_globals: true
preserve_locals: baz
preserve_locals:
- baz
- options:
remove_literal_statements: true
preserve_locals: baz
preserve_locals:
- baz
- options:
remove_literal_statements: true
rename_globals: true
preserve_locals: baz
preserve_locals:
- baz
/usr/local/lib/python3.10/test/test_copy.py:
- options: {}
- options:
Expand Down
24 changes: 16 additions & 8 deletions xtest/manifests/python3.11_test_manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -188,17 +188,21 @@
/usr/local/lib/python3.11/test/test_asyncio/test_futures.py: []
/usr/local/lib/python3.11/test/test_asyncio/test_futures2.py:
- options:
preserve_locals: future
preserve_locals:
- future
- options:
rename_globals: true
preserve_locals: future
preserve_locals:
- future
- options:
remove_literal_statements: true
preserve_locals: future
preserve_locals:
- future
- options:
remove_literal_statements: true
rename_globals: true
preserve_locals: future
preserve_locals:
- future
/usr/local/lib/python3.11/test/test_asyncio/test_locks.py:
- options: {}
- options:
Expand Down Expand Up @@ -2904,17 +2908,21 @@
rename_globals: true
/usr/local/lib/python3.11/test/test_opcache.py:
- options:
preserve_locals: Class
preserve_locals:
- Class
- options:
rename_globals: true
preserve_locals: Class
preserve_locals:
- Class
- options:
remove_literal_statements: true
preserve_locals: Class
preserve_locals:
- Class
- options:
remove_literal_statements: true
rename_globals: true
preserve_locals: Class
preserve_locals:
- Class
/usr/local/lib/python3.11/test/test_opcodes.py:
- options: {}
- options:
Expand Down
12 changes: 8 additions & 4 deletions xtest/manifests/python3.12_test_manifest.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4740,20 +4740,24 @@
status: passing
/usr/local/lib/python3.12/test/test_opcache.py:
- options:
preserve_locals: Class
preserve_locals:
- Class
remove_literal_statements: true
rename_globals: true
status: passing
- options:
preserve_locals: Class
preserve_locals:
- Class
rename_globals: true
status: passing
- options:
preserve_locals: Class
preserve_locals:
- Class
remove_literal_statements: true
status: passing
- options:
preserve_locals: Class
preserve_locals:
- Class
status: passing
/usr/local/lib/python3.12/test/test_opcodes.py:
- options:
Expand Down