Repository: Instagram/LibCST (language: python)

Issue:
Unpacked tuples inside f-strings are not allowed on the native parser
Short reproducer;
```py
f'{1, 2}'
```

```
Traceback (most recent call last):
  File "/usr/lib/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/isidentical/projects/LibCST/libcst/tool.py", line 839, in <module>
    main(os.environ.get("LIBCST_TOOL_COMMAND_NAME", "libcst.tool"), sys.argv[1:])
  File "/home/isidentical/projects/LibCST/libcst/tool.py", line 834, in main
    return lookup.get(args.action or None, _invalid_command)(proc_name, command_args)
  File "/home/isidentical/projects/LibCST/libcst/tool.py", line 278, in _print_tree_impl
    tree = parse_module(
  File "/home/isidentical/projects/LibCST/libcst/_parser/entrypoints.py", line 109, in parse_module
    result = _parse(
  File "/home/isidentical/projects/LibCST/libcst/_parser/entrypoints.py", line 55, in _parse
    return parse(source_str)
libcst._exceptions.ParserSyntaxError: Syntax Error @ 1:7.
parser error: error at 1:6: expected one of !, !=, %, &, (, *, **, +, -, ., /, //, :, <, <<, <=, =, ==, >, >=, >>, @, ASYNC, [, ^, and, for, if, in, is, not, or, |, }

f'{1, 2}'
      ^
```


Discussion / hints:

Fix patch:
diff --git a/native/libcst/src/parser/grammar.rs b/native/libcst/src/parser/grammar.rs
index 70d2f968e..fcd351a93 100644
--- a/native/libcst/src/parser/grammar.rs
+++ b/native/libcst/src/parser/grammar.rs
@@ -1396,7 +1396,7 @@ parser! {
 
         rule _f_expr() -> Expression<'a>
             = (g:_bare_genexp() {Expression::GeneratorExp(g)})
-            / _conditional_expression()
+            / star_expressions()
             / yield_expr()
 
         rule _f_conversion() -> &'a str


Test patch:
diff --git a/libcst/_nodes/tests/test_atom.py b/libcst/_nodes/tests/test_atom.py
index c2e316088..82f7ab998 100644
--- a/libcst/_nodes/tests/test_atom.py
+++ b/libcst/_nodes/tests/test_atom.py
@@ -740,6 +740,69 @@ class AtomTest(CSTNodeTest):
                 "parser": parse_expression,
                 "expected_position": None,
             },
+            # Unpacked tuple
+            {
+                "node": cst.FormattedString(
+                    parts=[
+                        cst.FormattedStringExpression(
+                            expression=cst.Tuple(
+                                elements=[
+                                    cst.Element(
+                                        value=cst.Name(
+                                            value="a",
+                                        ),
+                                        comma=cst.Comma(
+                                            whitespace_before=cst.SimpleWhitespace(
+                                                value="",
+                                            ),
+                                            whitespace_after=cst.SimpleWhitespace(
+                                                value=" ",
+                                            ),
+                                        ),
+                                    ),
+                                    cst.Element(
+                                        value=cst.Name(
+                                            value="b",
+                                        ),
+                                    ),
+                                ],
+                                lpar=[],
+                                rpar=[],
+                            ),
+                        ),
+                    ],
+                    start="f'",
+                    end="'",
+                ),
+                "code": "f'{a, b}'",
+                "parser": parse_expression,
+                "expected_position": None,
+            },
+            # Conditional expression
+            {
+                "node": cst.FormattedString(
+                    parts=[
+                        cst.FormattedStringExpression(
+                            expression=cst.IfExp(
+                                test=cst.Name(
+                                    value="b",
+                                ),
+                                body=cst.Name(
+                                    value="a",
+                                ),
+                                orelse=cst.Name(
+                                    value="c",
+                                ),
+                            ),
+                        ),
+                    ],
+                    start="f'",
+                    end="'",
+                ),
+                "code": "f'{a if b else c}'",
+                "parser": parse_expression,
+                "expected_position": None,
+            },
             # Concatenated strings
             {
                 "node": cst.ConcatenatedString(