diff --git a/pyproject.toml b/pyproject.toml index c7d9b05..ed7585e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ build-backend = "setuptools.build_meta" [tool.poetry] name = "mamushi" -version = "0.0.4-a2" +version = "0.0.4-a3" description = "Vyper Formatter" authors = ["benny "] diff --git a/setup.cfg b/setup.cfg index df520f8..85d99f3 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.0.4-a2 +current_version = 0.0.4-a3 commit = False tag = True parse = (?P\d+)\.(?P\d+)\.(?P\d+)(\-(?P[a-z]+)(?P\d+))? diff --git a/src/mamushi/__version__.py b/src/mamushi/__version__.py index f22196d..9beb433 100644 --- a/src/mamushi/__version__.py +++ b/src/mamushi/__version__.py @@ -1 +1 @@ -__version__ = "0.0.4-a2" +__version__ = "0.0.4-a3" diff --git a/src/mamushi/formatting/linegen.py b/src/mamushi/formatting/linegen.py index e517cc4..4fbbacb 100644 --- a/src/mamushi/formatting/linegen.py +++ b/src/mamushi/formatting/linegen.py @@ -21,6 +21,8 @@ wrap_in_parentheses, is_atom_with_invisible_parens, ensure_visible, + is_lpar_token, + is_rpar_token, ) from mamushi.formatting.strings import ( normalize_string_quotes, @@ -238,6 +240,7 @@ def visit_call(self, node: Node) -> Iterator[Line]: def visit_import(self, node: Node) -> Iterator[Line]: """Handles different import syntax""" + normalize_invisible_parens(node, parens_after={"import"}) for child in node.children: if child.type in IMPORTS_TYPE and child.prev_sibling is None: yield from self.line() @@ -262,6 +265,8 @@ def visit_simple_stmt(self, node: Node) -> Iterator[Line]: normalize_invisible_parens(node, parens_after={"assert", ","}) elif node.type == tokens.RETURN_STMT: normalize_invisible_parens(node, parens_after={"return"}) + elif node.type == tokens.EXPORT: + normalize_invisible_parens(node, parens_after={"export", ":"}) is_body_like = node.parent and ( # TODO: handle this more cleanly @@ -446,12 +451,34 @@ def normalize_invisible_parens( ): wrap_in_parentheses(child, first_child, visible=False) + elif node.type in {tokens.IMPORT, tokens.EXPORT}: + _normalize_import_from(node, child, index) + break + elif not (isinstance(child, Leaf)): wrap_in_parentheses(node, child, visible=False) check_lpar = isinstance(child, Leaf) and (child.value in parens_after) +def _normalize_import_from(parent: Node, child: LN, index: int) -> None: + # "import from" nodes store parentheses directly as part of + # the statement + if ( + is_lpar_token(child) + and isinstance(child, Leaf) + and isinstance(parent.children[-1], Leaf) + and is_rpar_token(parent.children[-1]) + ): + # make parentheses invisible + child.value = "" + parent.children[-1].value = "" + elif child.type != tokens.STAR: + # insert invisible parentheses + parent.insert_child(index, Leaf(tokens.LPAR, "")) + parent.append_child(Leaf(tokens.RPAR, "")) + + def maybe_make_parens_invisible_in_atom( node: LN, parent: LN, diff --git a/src/mamushi/formatting/nodes.py b/src/mamushi/formatting/nodes.py index b5bb08b..c39051d 100644 --- a/src/mamushi/formatting/nodes.py +++ b/src/mamushi/formatting/nodes.py @@ -56,6 +56,14 @@ def ensure_visible(leaf: Leaf) -> None: leaf.value = ")" +def is_lpar_token(nl: LN) -> bool: + return nl.type == tokens.LPAR + + +def is_rpar_token(nl: LN) -> bool: + return nl.type == tokens.RPAR + + def is_one_sequence_between( opening: Leaf, closing: Leaf, diff --git a/tests/data/imports/import_from_parens.vy b/tests/data/imports/import_from_parens.vy new file mode 100644 index 0000000..e607223 --- /dev/null +++ b/tests/data/imports/import_from_parens.vy @@ -0,0 +1,9 @@ +from a.c import (a) + +from a.b import ( +d +) +# output +from a.c import a + +from a.b import d diff --git a/tests/data/modules/exports_parens.vy b/tests/data/modules/exports_parens.vy new file mode 100644 index 0000000..976fbe8 --- /dev/null +++ b/tests/data/modules/exports_parens.vy @@ -0,0 +1,5 @@ +exports: ( + abc.xyz +) +# output +exports: abc.xyz