From a23c4d4cbfefc615862a46460d0a8b7eaabfe305 Mon Sep 17 00:00:00 2001 From: jbjd Date: Sun, 18 Jan 2026 12:38:57 -0600 Subject: [PATCH 1/4] Improvement: Option to remove typing cast --- .../parser/config.py | 6 +++- .../parser/skipper.py | 8 +++++ tests/parser/test_functions.py | 35 ++++++++++++++++++- .../{test_excludes.py => test_skips.py} | 7 ++++ .../parser/{test_skipper.py => test_warn.py} | 0 version.txt | 2 +- 6 files changed, 55 insertions(+), 3 deletions(-) rename tests/parser/{test_excludes.py => test_skips.py} (98%) rename tests/parser/{test_skipper.py => test_warn.py} (100%) diff --git a/personal_python_ast_optimizer/parser/config.py b/personal_python_ast_optimizer/parser/config.py index e99a01b..5ce59aa 100644 --- a/personal_python_ast_optimizer/parser/config.py +++ b/personal_python_ast_optimizer/parser/config.py @@ -137,6 +137,7 @@ class OptimizationsConfig(_Config): "vars_to_fold", "enums_to_fold", "functions_safe_to_exclude_in_test_expr", + "remove_typing_cast", "remove_unused_imports", "fold_constants", "assume_this_machine", @@ -144,14 +145,16 @@ class OptimizationsConfig(_Config): def __init__( # noqa: PLR0913 self, + *, vars_to_fold: dict[ str, str | bytes | bool | int | float | complex | None | EllipsisType ] | None = None, enums_to_fold: Iterable[EnumType] | None = None, functions_safe_to_exclude_in_test_expr: set[str] | None = None, - fold_constants: bool = True, remove_unused_imports: bool = True, + remove_typing_cast: bool = True, + fold_constants: bool = False, assume_this_machine: bool = False, ) -> None: self.vars_to_fold: dict[ @@ -167,6 +170,7 @@ def __init__( # noqa: PLR0913 or default_functions_safe_to_exclude_in_test_expr ) self.remove_unused_imports: bool = remove_unused_imports + self.remove_typing_cast: bool = remove_typing_cast self.assume_this_machine: bool = assume_this_machine self.fold_constants: bool = fold_constants diff --git a/personal_python_ast_optimizer/parser/skipper.py b/personal_python_ast_optimizer/parser/skipper.py index 4179fe3..993bf62 100644 --- a/personal_python_ast_optimizer/parser/skipper.py +++ b/personal_python_ast_optimizer/parser/skipper.py @@ -587,6 +587,14 @@ def visit_Call(self, node: ast.Call) -> ast.AST | None: if function_call_key in machine_dependent_functions: return ast.Constant(machine_dependent_functions[function_call_key]) + if ( + self.optimizations_config.remove_typing_cast + and isinstance(node.func, ast.Name) + and node.func.id == "cast" + and len(node.args) == 2 # noqa: PLR2004 + ): + return node.args[1] + return self.generic_visit(node) def visit_Constant(self, node: ast.Constant) -> ast.Constant: diff --git a/tests/parser/test_functions.py b/tests/parser/test_functions.py index 870ee0f..eaefe30 100644 --- a/tests/parser/test_functions.py +++ b/tests/parser/test_functions.py @@ -1,4 +1,7 @@ -from personal_python_ast_optimizer.parser.config import TokenTypesConfig +from personal_python_ast_optimizer.parser.config import ( + OptimizationsConfig, + TokenTypesConfig, +) from tests.utils import BeforeAndAfter, run_minifier_and_assert_correct @@ -76,3 +79,33 @@ def test_overload(a: float) -> int: do_something() before_and_after, token_types_config=TokenTypesConfig(skip_overload_functions=True), ) + + +def test_typing_cast_remove(): + before_and_after = BeforeAndAfter( + """ +from typing import cast + +a = cast(str, 1) +""", + "a=1", + ) + run_minifier_and_assert_correct( + before_and_after, + optimizations_config=OptimizationsConfig(remove_typing_cast=True), + ) + + +def test_typing_cast(): + before_and_after = BeforeAndAfter( + """ +from typing import cast + +a = cast(str, 1) +""", + "from typing import cast\na=cast(str,1)", + ) + run_minifier_and_assert_correct( + before_and_after, + optimizations_config=OptimizationsConfig(remove_typing_cast=False), + ) diff --git a/tests/parser/test_excludes.py b/tests/parser/test_skips.py similarity index 98% rename from tests/parser/test_excludes.py rename to tests/parser/test_skips.py index 7b16f4f..5445b09 100644 --- a/tests/parser/test_excludes.py +++ b/tests/parser/test_skips.py @@ -74,6 +74,13 @@ def bar(): """, "def bar():test=1", ), + BeforeAndAfter( + """ +foo = something +foo.do() +""", + "", + ), ] diff --git a/tests/parser/test_skipper.py b/tests/parser/test_warn.py similarity index 100% rename from tests/parser/test_skipper.py rename to tests/parser/test_warn.py diff --git a/version.txt b/version.txt index 88d06f1..6abaeb2 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -6.1.3 +6.2.0 From 01ffb113a38184af460585580ecb6d722169504c Mon Sep 17 00:00:00 2001 From: jbjd Date: Sun, 18 Jan 2026 12:42:31 -0600 Subject: [PATCH 2/4] Still visit arg of cast --- personal_python_ast_optimizer/parser/skipper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/personal_python_ast_optimizer/parser/skipper.py b/personal_python_ast_optimizer/parser/skipper.py index 993bf62..4e64781 100644 --- a/personal_python_ast_optimizer/parser/skipper.py +++ b/personal_python_ast_optimizer/parser/skipper.py @@ -593,7 +593,7 @@ def visit_Call(self, node: ast.Call) -> ast.AST | None: and node.func.id == "cast" and len(node.args) == 2 # noqa: PLR2004 ): - return node.args[1] + return self.generic_visit(node.args[1]) return self.generic_visit(node) From 31e12ec469490ed412be4fd8d487339341d7c639 Mon Sep 17 00:00:00 2001 From: jbjd Date: Sun, 18 Jan 2026 12:44:15 -0600 Subject: [PATCH 3/4] Didn't mean to commit this --- tests/parser/test_skips.py | 7 ------- 1 file changed, 7 deletions(-) diff --git a/tests/parser/test_skips.py b/tests/parser/test_skips.py index 5445b09..7b16f4f 100644 --- a/tests/parser/test_skips.py +++ b/tests/parser/test_skips.py @@ -74,13 +74,6 @@ def bar(): """, "def bar():test=1", ), - BeforeAndAfter( - """ -foo = something -foo.do() -""", - "", - ), ] From cd2d5726acce0263fb35322dd1af807c296a3e95 Mon Sep 17 00:00:00 2001 From: jbjd Date: Sun, 18 Jan 2026 12:48:03 -0600 Subject: [PATCH 4/4] Fix test config --- tests/parser/test_constant_folding.py | 5 ++++- version.txt | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/parser/test_constant_folding.py b/tests/parser/test_constant_folding.py index 584c3c1..b0ee165 100644 --- a/tests/parser/test_constant_folding.py +++ b/tests/parser/test_constant_folding.py @@ -1,5 +1,6 @@ import pytest +from personal_python_ast_optimizer.parser.config import OptimizationsConfig from tests.utils import BeforeAndAfter, run_minifier_and_assert_correct _binary_op_folding_cases = [ @@ -15,7 +16,9 @@ @pytest.mark.parametrize("before_and_after", _binary_op_folding_cases) def test_binary_op_folding(before_and_after: BeforeAndAfter): - run_minifier_and_assert_correct(before_and_after) + run_minifier_and_assert_correct( + before_and_after, optimizations_config=OptimizationsConfig(fold_constants=True) + ) def test_string_folding(): diff --git a/version.txt b/version.txt index 6abaeb2..66ce77b 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -6.2.0 +7.0.0