From 5ae9421616a8c34725773454438221fc63652071 Mon Sep 17 00:00:00 2001 From: jbjd Date: Tue, 13 Jan 2026 18:22:20 -0600 Subject: [PATCH 1/3] Improvement: Skip useless try node --- .../parser/skipper.py | 16 ++++++++++++++++ tests/parser/test_exception.py | 19 +++++++++++++++++-- version.txt | 2 +- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/personal_python_ast_optimizer/parser/skipper.py b/personal_python_ast_optimizer/parser/skipper.py index 134628e..f37d7c0 100644 --- a/personal_python_ast_optimizer/parser/skipper.py +++ b/personal_python_ast_optimizer/parser/skipper.py @@ -214,6 +214,22 @@ def _should_skip_function( and is_overload_function(node) ) + def visit_Try(self, node: ast.Try) -> ast.AST | None: + parsed_node = self.generic_visit(node) + return None if self._is_useless_try_node(parsed_node) else parsed_node + + def visit_TryStar(self, node: ast.TryStar) -> ast.AST | None: + parsed_node = self.generic_visit(node) + return None if self._is_useless_try_node(parsed_node) else parsed_node + + @staticmethod + def _is_useless_try_node(node: ast.AST) -> bool: + return ( + isinstance(node, (ast.Try, ast.TryStar)) + and len(node.body) == 1 + and isinstance(node.body[0], ast.Pass) + ) + def visit_Attribute(self, node: ast.Attribute) -> ast.AST | None: if isinstance(node.value, ast.Name): if node.attr in self.optimizations_config.enums_to_fold.get( diff --git a/tests/parser/test_exception.py b/tests/parser/test_exception.py index 57551de..008f118 100644 --- a/tests/parser/test_exception.py +++ b/tests/parser/test_exception.py @@ -1,15 +1,30 @@ from tests.utils import BeforeAndAfter, run_minifier_and_assert_correct -def test_raise_same_line(): +def test_useless_try(): before_and_after = BeforeAndAfter( """ try: pass + pass +except Exception as e: + pass +""", + "", + ) + + run_minifier_and_assert_correct(before_and_after) + + +def test_raise_same_line(): + before_and_after = BeforeAndAfter( + """ +try: + a += 1 except (Exception, ValueError) as e: raise ValueError('a') from e """, - "try:pass\nexcept(Exception,ValueError)as e:raise ValueError('a')from e", + "try:a+=1\nexcept(Exception,ValueError)as e:raise ValueError('a')from e", ) run_minifier_and_assert_correct(before_and_after) diff --git a/version.txt b/version.txt index c7cb131..84197c8 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -5.3.1 +5.3.2 From aa188aaca8500bcf181b7434b52e739debcededa Mon Sep 17 00:00:00 2001 From: jbjd Date: Tue, 13 Jan 2026 18:29:47 -0600 Subject: [PATCH 2/3] Handle edge case --- .../parser/skipper.py | 24 ++++++++++++------- tests/parser/test_exception.py | 20 +++++++++++++++- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/personal_python_ast_optimizer/parser/skipper.py b/personal_python_ast_optimizer/parser/skipper.py index f37d7c0..6557c18 100644 --- a/personal_python_ast_optimizer/parser/skipper.py +++ b/personal_python_ast_optimizer/parser/skipper.py @@ -216,19 +216,27 @@ def _should_skip_function( def visit_Try(self, node: ast.Try) -> ast.AST | None: parsed_node = self.generic_visit(node) - return None if self._is_useless_try_node(parsed_node) else parsed_node + + if isinstance( + parsed_node, (ast.Try, ast.TryStar) + ) and self._is_useless_try_node(parsed_node): + return parsed_node.finalbody or None + + return parsed_node def visit_TryStar(self, node: ast.TryStar) -> ast.AST | None: parsed_node = self.generic_visit(node) - return None if self._is_useless_try_node(parsed_node) else parsed_node + + if isinstance( + parsed_node, (ast.Try, ast.TryStar) + ) and self._is_useless_try_node(parsed_node): + return parsed_node.finalbody or None + + return parsed_node @staticmethod - def _is_useless_try_node(node: ast.AST) -> bool: - return ( - isinstance(node, (ast.Try, ast.TryStar)) - and len(node.body) == 1 - and isinstance(node.body[0], ast.Pass) - ) + def _is_useless_try_node(node: ast.Try | ast.TryStar) -> bool: + return all(isinstance(n, ast.Pass) for n in node.body) def visit_Attribute(self, node: ast.Attribute) -> ast.AST | None: if isinstance(node.value, ast.Name): diff --git a/tests/parser/test_exception.py b/tests/parser/test_exception.py index 008f118..8bcce4e 100644 --- a/tests/parser/test_exception.py +++ b/tests/parser/test_exception.py @@ -1,14 +1,32 @@ from tests.utils import BeforeAndAfter, run_minifier_and_assert_correct -def test_useless_try(): +def test_almost_useful_try(): before_and_after = BeforeAndAfter( """ try: pass pass +except: + pass +finally: + print(1) +""", + "print(1)", + ) + + run_minifier_and_assert_correct(before_and_after) + + +def test_useless_try(): + before_and_after = BeforeAndAfter( + """ +try: + pass except Exception as e: pass +finally: + pass """, "", ) From 77ebff9364a7ec8222e5966096da3c786f89a48b Mon Sep 17 00:00:00 2001 From: jbjd Date: Tue, 13 Jan 2026 18:31:25 -0600 Subject: [PATCH 3/3] mypy --- personal_python_ast_optimizer/parser/skipper.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/personal_python_ast_optimizer/parser/skipper.py b/personal_python_ast_optimizer/parser/skipper.py index 6557c18..5eb0bc6 100644 --- a/personal_python_ast_optimizer/parser/skipper.py +++ b/personal_python_ast_optimizer/parser/skipper.py @@ -214,7 +214,7 @@ def _should_skip_function( and is_overload_function(node) ) - def visit_Try(self, node: ast.Try) -> ast.AST | None: + def visit_Try(self, node: ast.Try) -> ast.AST | list[ast.stmt] | None: parsed_node = self.generic_visit(node) if isinstance( @@ -224,7 +224,7 @@ def visit_Try(self, node: ast.Try) -> ast.AST | None: return parsed_node - def visit_TryStar(self, node: ast.TryStar) -> ast.AST | None: + def visit_TryStar(self, node: ast.TryStar) -> ast.AST | list[ast.stmt] | None: parsed_node = self.generic_visit(node) if isinstance(