# These test cases specifically tests out parsing a list of with items that start with a
# left parenthesis. This makes parsing ambiguous as to whether the left parenthesis is to
# parenthesize the with items or part of a parenthesized expression. It's not to test the
# with statement itself.

# The following sections basically separates between which node does the
# start parenthesis belongs to.

# Parenthesized with items
# ------------------------
#
# - The opening parenthesis belongs to the with statement.
# - The range of the first with item shouldn't include the parenthesis.
with (item): ...
with (item,): ...  # with a trailing comma
with (((item))): ...
with (item1, item2): ...
with (item1, item2,): ...  # with a trailing comma
with ((item1), (item2), item3 as f, (item4)): ...
with ((item1, item2), item3): ...
with ((x, y) as f): ...
with (item1 as f1, item2 as f2): ...
with (item1 as f1, item2 as f2,): ...  # with a trailing comma
with (item == 10,): ...
with ((item := 10)): ...
with ((item := 10,)): ...
with ((*item,)): ...
with ((item1 := 10), item2): ...
with (item1 as f, (item2 := 10)): ...
with (foo()): ...
with (foo(),): ...
with (foo() as f): ...
with (f"{item := 42}"): ...
with (f"{(item := 42)}"): ...
with ((x for x in range(10)), item): ...
with (item, (x for x in range(10))): ...
with (item, (x for x in range(10)), item): ...
with (data[1:2]): ...
with (data[1:2] as f): ...
with ((x for x in iter) as y): ...

# Parenthesized expression
# ------------------------
#
# - The opening parenthesis belongs to the context expression of the first with item.
# - The range of the first with item should include the parenthesis.
with (item) as f: ...
with (item := 10): ...
with (item := 10) as f: ...
with (  item := 1   ): ...
with (item1 := 42), item2: ...
with (root + filename).read(): ...  # Postfix expression
with (root + filename).read() as f: ...  # Postfix expression
with (foo)(): ...  # Postfix expression
with (foo)() as f: ...  # Postfix expression
with (foo()) as f: ...
with (data[1:2]) as f: ...
with (1, 2, 3)[0]: ...  # Postfix expression
with (1, 2, 3)[0] as f: ...  # Postfix expression
with (item1), (item2): ...
with (open('a.py')), (open('b.py')): ...
with (yield x): ...
with ((yield x)): ...
with (yield from x): ...
with ((yield from x)): ...
with (yield x) as f: ...
with (yield x,) as f: ...


# Tuple expression
# ----------------
#
# - This is a sub-case of the parenthesized expression and requires transforming the list of
#   with items from the speculative parsing to a single with item containing a tuple expression.
# - The opening parenthesis belongs to the tuple expression of the first with item.
# - The range of the first with item should include the parenthesis.
with (): ...
with () as f: ...
with (item := 42,): ...
with (1, item := 2): ...
with (item1 := 10, item2): ...
with (item1, item2 := 2, item3) as f: ...
with (item,) as f: ...
with (*item,): ...
with (*item,) as f: ...
with (item1, item2) as f: ...
with (item1, item2,) as f: ...
with (item1, item2), item3: ...
with ((item1, item2), item3) as f: ...
with (item1,), item2, (item3, item4) as f: ...
with (item1, item2) as f1, item3 as f2: ...
with (item1, *item2): ...
with (item1, *item2) as f: ...
with (item1 := 10, *item2): ...
with ((item1 := 10), *item2): ...


# Parenthesized generator expression
# ----------------------------------
#
# - The opening parenthesis belongs to the generator expression
# - The range of the with item should include the parenthesis
with (x for x in range(10)): ...
with (x async for x in range(10)): ...
with (x for x in range(10)), item: ...