Skip to content

Commit

Permalink
Allow parens allow first element of a tuple
Browse files Browse the repository at this point in the history
A tuple doesn't always have parens, so it is difficult to distinguish a tuple with parens from a tuple without parens but with parens around the first element. This commit adds backtracking to deal with this.
  • Loading branch information
knutwannheden committed Oct 11, 2024
1 parent d84fdb8 commit fea7697
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
41 changes: 28 additions & 13 deletions rewrite/rewrite/python/_parser_visitor.py
Original file line number Diff line number Diff line change
Expand Up @@ -1572,20 +1572,35 @@ def visit_Subscript(self, node):
def visit_Tuple(self, node):
prefix = self.__whitespace()

omit_parens = True
if self._source[self._cursor] == '(':
self._cursor += 1
omit_parens = False
if self._source[self._cursor] == '(' and node.elts:
save_cursor = self._cursor
elements = JContainer(
Space.EMPTY,
[self.__pad_list_element(self.__convert(e), last=i == len(node.elts) - 1) for i, e in enumerate(node.elts)],
Markers.EMPTY
)
if self._cursor < len(self._source) and self._source[self._cursor] == ')':
# we need to backtrack as the parentheses belonged to a nested element
elements = None
self._cursor = save_cursor
else:
elements = elements.with_markers(Markers(random_id(), [OmitParentheses(random_id())]))
else:
elements = None

elements = JContainer(
Space.EMPTY,
[self.__pad_list_element(self.__convert(e), last=i == len(node.elts) - 1,
end_delim=None if omit_parens else ')') for i, e in
enumerate(node.elts)] if node.elts else
[self.__pad_right(j.Empty(random_id(), self.__whitespace() if omit_parens else self.__source_before(')'),
Markers.EMPTY), Space.EMPTY)],
Markers(random_id(), [OmitParentheses(random_id())]) if omit_parens else Markers.EMPTY
)
if elements is None:
omit_parens = self._source[self._cursor] != '('
if not omit_parens:
self._cursor += 1
elements = JContainer(
Space.EMPTY,
[self.__pad_list_element(self.__convert(e), last=i == len(node.elts) - 1,
end_delim=None if omit_parens else ')') for i, e in
enumerate(node.elts)] if node.elts else
[self.__pad_right(j.Empty(random_id(), self.__whitespace() if omit_parens else self.__source_before(')'),
Markers.EMPTY), Space.EMPTY)],
Markers(random_id(), [OmitParentheses(random_id())]) if omit_parens else Markers.EMPTY
)
return py.CollectionLiteral(
random_id(),
prefix,
Expand Down
5 changes: 5 additions & 0 deletions rewrite/tests/python/all/collection_literal_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ def test_single_element_tuple_with_trailing_comma():
rewrite_run(python("t = (1 , )"))


def test_tuple_with_first_element_in_parens():
# language=python
rewrite_run(python("x = (1) // 2, 0"))


# note: `{}` is always a dict
def test_empty_set():
# language=python
Expand Down

0 comments on commit fea7697

Please sign in to comment.