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
24 changes: 22 additions & 2 deletions personal_python_ast_optimizer/parser/minifier.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def _update_text_to_write(self, text: str) -> str:

return text

def visit_node(self, node: ast.AST, is_last_node_in_body: bool = False):
def visit_node(self, node: ast.AST, is_last_node_in_body: bool = False) -> None:
method = "visit_" + node.__class__.__name__
visitor = getattr(self, method, self.generic_visit)

Expand All @@ -94,13 +94,33 @@ def visit_Pass(self, _: ast.Pass | None = None) -> None:
same_line: bool = self._can_write_same_line()
self.fill("pass", same_line=same_line)

def visit_Continue(self, _: ast.Continue | None = None) -> None:
same_line: bool = self._can_write_same_line()
self.fill("continue", same_line=same_line)

def visit_Return(self, node: ast.Return) -> None:
same_line: bool = self._can_write_same_line()
self.fill("return", same_line=same_line)
if node.value and not is_return_none(node):
self.write(" ")
self.traverse(node.value)

def visit_Raise(self, node: ast.Raise) -> None:
same_line: bool = self._can_write_same_line()
self.fill("raise", same_line=same_line)

if not node.exc:
if node.cause:
raise ValueError("Node can't use cause without an exception.")
return

self.write(" ")
self.traverse(node.exc)

if node.cause:
self.write(" from ")
self.traverse(node.cause)

def visit_ImportFrom(self, node: ast.ImportFrom) -> None:
"""Skip unnecessary futures imports"""
if node.module == "__future__" and self.target_python_version is not None:
Expand Down Expand Up @@ -327,7 +347,7 @@ def _use_version_optimization(self, python_version: tuple[int, int]) -> bool:

return self.target_python_version >= python_version

def _can_write_same_line(self):
def _can_write_same_line(self) -> bool:
return (
len(self._source) > 0
and self._source[-1] == ":"
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ authors = [
{name = "James Demetris"},
]
name = "personal-python-ast-optimizer"
version = "1.1.1"
version = "1.1.2"
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
Expand Down
27 changes: 1 addition & 26 deletions tests/parser/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import pytest

from tests.utils import BeforeAndAfter, BeforeAndAfterBasedOnVersion
from tests.utils import BeforeAndAfter


@pytest.fixture
Expand Down Expand Up @@ -102,17 +102,6 @@ class SomeTuple:
)


@pytest.fixture
def ignorable_bases_class() -> BeforeAndAfterBasedOnVersion:
return BeforeAndAfterBasedOnVersion(
"""
class Foo(object):
pass
""",
{"3.0": "class Foo:pass", None: "class Foo(object):pass"},
)


@pytest.fixture
def annotations_script() -> BeforeAndAfter:
return BeforeAndAfter("a: int;b: int = 2;b -= 1", "b=2\nb-=1")
Expand All @@ -132,20 +121,6 @@ def one_line_if_script() -> BeforeAndAfter:
)


@pytest.fixture
def futures_imports() -> BeforeAndAfterBasedOnVersion:
many_futures_imports: str = """
from __future__ import annotations
from __future__ import generator_stop
from __future__ import unicode_literals
from __future__ import with_statement
"""
return BeforeAndAfterBasedOnVersion(
many_futures_imports,
{"3.7": "", None: many_futures_imports.strip()},
)


@pytest.fixture
def name_equals_main_excludes() -> BeforeAndAfter:
return BeforeAndAfter(
Expand Down
37 changes: 18 additions & 19 deletions tests/parser/test_assign.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,29 @@

from tests.utils import BeforeAndAfter, run_minifiyer_and_assert_correct


@pytest.mark.parametrize(
"before_and_after",
[
(
BeforeAndAfter(
"""
_assign_cases = [
(
BeforeAndAfter(
"""
if a > 6:
b = 3
c = 4
""",
"if a>6:\n\tb=3\n\tc=4",
)
),
(
BeforeAndAfter(
"""
"if a>6:\n\tb=3\n\tc=4",
)
),
(
BeforeAndAfter(
"""
if a > 6:
b = 3
""",
"if a>6:b=3",
)
),
],
)
def test_exclude_name_equals_main(before_and_after: BeforeAndAfter):
"if a>6:b=3",
)
),
]


@pytest.mark.parametrize("before_and_after", _assign_cases)
def test_assign(before_and_after: BeforeAndAfter):
run_minifiyer_and_assert_correct(before_and_after)
123 changes: 61 additions & 62 deletions tests/parser/test_constant_folding.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,90 +4,89 @@

from tests.utils import BeforeAndAfter, run_minifiyer_and_assert_correct


@pytest.mark.parametrize(
"before_and_after",
[
(
BeforeAndAfter(
"""
_exclude_name_equals_main_cases = [
(
BeforeAndAfter(
"""
from foo import FAVORITE_NUMBER

a = FAVORITE_NUMBER
""",
"a=6",
)
),
(
BeforeAndAfter(
"""
"a=6",
)
),
(
BeforeAndAfter(
"""
FAVORITE_NUMBER = 6

a = FAVORITE_NUMBER
""",
"a=6",
)
),
(
BeforeAndAfter(
"""
"a=6",
)
),
(
BeforeAndAfter(
"""
FAVORITE_NUMBER: int = 6

a = FAVORITE_NUMBER
""",
"a=6",
)
),
(
BeforeAndAfter(
"""
"a=6",
)
),
(
BeforeAndAfter(
"""
FAVORITE_NUMBER=a=6
""",
"a=6",
)
),
(
BeforeAndAfter(
"""
"a=6",
)
),
(
BeforeAndAfter(
"""
FAVORITE_NUMBER,a=4,5
""",
"a=5",
)
),
(
BeforeAndAfter(
"""
"a=5",
)
),
(
BeforeAndAfter(
"""
FAVORITE_NUMBER,a,*_=4,5,6,7,8
""",
(
"a,*_=(5,6,7,8)"
if sys.version_info[:2] > (3, 10)
else "(a,*_)=(5,6,7,8)"
),
)
),
(
BeforeAndAfter(
"""
(
"a,*_=(5,6,7,8)"
if sys.version_info[:2] > (3, 10)
else "(a,*_)=(5,6,7,8)"
),
)
),
(
BeforeAndAfter(
"""
*_,FAVORITE_NUMBER,a=4,5,6,7,8
""",
(
"*_,a=(4,6,7,8)"
if sys.version_info[:2] > (3, 10)
else "(*_,a)=(4,6,7,8)"
),
)
),
(
BeforeAndAfter(
"""
(
"*_,a=(4,6,7,8)"
if sys.version_info[:2] > (3, 10)
else "(*_,a)=(4,6,7,8)"
),
)
),
(
BeforeAndAfter(
"""
FAVORITE_NUMBER,TEST=4,5
""",
"",
)
),
],
)
"",
)
),
]


@pytest.mark.parametrize("before_and_after", _exclude_name_equals_main_cases)
def test_exclude_name_equals_main(before_and_after: BeforeAndAfter):
run_minifiyer_and_assert_correct(
before_and_after,
Expand Down
13 changes: 13 additions & 0 deletions tests/parser/test_continue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from tests.utils import BeforeAndAfter, run_minifiyer_and_assert_correct


def test_continue_same_line():
before_and_after = BeforeAndAfter(
"""
if a > 6:
continue
""",
"if a>6:continue",
)

run_minifiyer_and_assert_correct(before_and_after)
13 changes: 13 additions & 0 deletions tests/parser/test_exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from tests.utils import BeforeAndAfter, run_minifiyer_and_assert_correct


def test_continue_same_line():
before_and_after = BeforeAndAfter(
"""
if a > 6:
raise Exception()
""",
"if a>6:raise Exception()",
)

run_minifiyer_and_assert_correct(before_and_after)
19 changes: 15 additions & 4 deletions tests/parser/test_imports.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@
)


def test_futures_imports(
futures_imports: BeforeAndAfterBasedOnVersion,
):
run_minifiyer_and_assert_correct_multiple_versions(futures_imports)
def test_futures_imports():

many_futures_imports: str = """
from __future__ import annotations
from __future__ import generator_stop
from __future__ import unicode_literals
from __future__ import with_statement
"""

before_and_after = BeforeAndAfterBasedOnVersion(
many_futures_imports,
{"3.7": "", None: many_futures_imports.strip()},
)

run_minifiyer_and_assert_correct_multiple_versions(before_and_after)
12 changes: 10 additions & 2 deletions tests/parser/test_versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,13 @@
)


def test_class_ignorable_bases(ignorable_bases_class: BeforeAndAfterBasedOnVersion):
run_minifiyer_and_assert_correct_multiple_versions(ignorable_bases_class)
def test_class_ignorable_bases():
before_and_after = BeforeAndAfterBasedOnVersion(
"""
class Foo(object):
pass
""",
{"3.0": "class Foo:pass", None: "class Foo(object):pass"},
)

run_minifiyer_and_assert_correct_multiple_versions(before_and_after)