Repository: cython/cython

Issue:
[BUG] Multiple starred expressions in a list
<!--
**PLEASE READ THIS FIRST:**
- Do not use the bug and feature tracker for support requests. Use the `cython-users` mailing list instead.
- Did you search for similar issues already? Please do, it helps to save us precious time that we otherwise could not invest into development.
- Did you try the latest master branch or pre-release? It might already have what you want to report. Also see the [Changelog](https://github.com/cython/cython/blob/master/CHANGES.rst) regarding recent changes.
-->
Hi !
I think Cython is not able to compile when I unpack multiple expressions separated by commas, in one list.

**Describe the bug**
When I want to compile my python file containing a condition like 
```python
if arr['name'] not in [*foo.bar.keys(), *foo.bar2.keys()]:
```

I get two error messages
```
Error compiling Cython file:
------------------------------------------------------------

if arr['name'] not in [*foo.bar.keys(), *foo.bar2.keys()]:
                            ^
------------------------------------------------------------

src/package/foo/bar.py:964:83: starred expression is not allowed here

Error compiling Cython file:
------------------------------------------------------------

if arr['name'] not in [*foo.bar.keys(), *foo.bar2.keys()]:
                                             ^
------------------------------------------------------------

src/package/foo/bar.py:964:83: starred expression is not allowed here
````

I know it is a very particular method and I could do 
```python
if arr['name'] not in [*foo.bar.keys()] + [*foo.bar2.keys()]:
```
But maybe it's possible to add this feature to Cython ?

I found this [issue](https://github.com/cython/cython/issues/2939) which looks like my problem, but setting different language_level doesn't change anything.

**To Reproduce**
To reproduce behaviour, try to compile 
```python
if arr['name'] not in [*foo.bar.keys(), *foo.bar2.keys()]:
```

**Expected behavior**
Errors should appear

**Environment (please complete the following information):**
 - OS: Linux & Windows
 - Python version 3.7.9
 - All Cython versions tested, even master branch

**Additional context**



Discussion:
Probably an issue with the optimised `in` tests. If there is a starred expression in the `in` list, then it should not get optimised.

See the `FlattenInListTransform` in `Optimize.py`. 
Test should go into `tests/run/pep448_extended_unpacking.py`
Suitable for a backport to 0.29.x.
@scoder I'd like to give this a shot
Could not reproduce the issue when I test with
```
a = {1: 'a', 2: 'b'}
b = {3: 'c', 4: 'd'}
print(2 in [*a.keys(), *b.keys()])
-----
O/P: 
python3 test.py
True
-----
python3 -VV
Python 3.8.10 (default, Sep 28 2021, 16:10:42) 
[GCC 9.3.0]
```


Still looks broken to me - it doesn't look like you tried to compile it with Cython.
Sorry, my bad. Can replicate the issue. I'll give it a shot.
```
cython3 --embed -o test.c test.py
/usr/lib/python3/dist-packages/Cython/Compiler/Main.py:369: FutureWarning: Cython directive 'language_level' not set, using 2 for now (Py2). This will change in a later release! File: /home/arvind/test.py
  tree = Parsing.p_module(s, pxd, full_module_name)

Error compiling Cython file:
------------------------------------------------------------
...
a = {1: 'a', 2: 'b'}
b = {3: 'c', 4: 'd'}
print(2 in [*a.keys()])
           ^
------------------------------------------------------------

test.py:3:12: starred expression is not allowed here

```

Resolving patch:
diff --git a/Cython/Compiler/Optimize.py b/Cython/Compiler/Optimize.py
--- a/Cython/Compiler/Optimize.py
+++ b/Cython/Compiler/Optimize.py
@@ -1440,6 +1440,10 @@ def visit_PrimaryCmpNode(self, node):
             # note: lhs may have side effects
             return node
 
+        if any([arg.is_starred for arg in args]):
+            # Starred arguments do not directly translate to comparisons or "in" tests.
+            return node
+
         lhs = UtilNodes.ResultRefNode(node.operand1)
 
         conds = []


Test patch:
diff --git a/tests/run/pep448_extended_unpacking.pyx b/tests/run/pep448_extended_unpacking.pyx
--- a/tests/run/pep448_extended_unpacking.pyx
+++ b/tests/run/pep448_extended_unpacking.pyx
@@ -272,6 +272,24 @@ def unpack_list_keep_originals(a, b, c):
     return [*a, *b, 2, *c]
 
 
+def unpack_starred_arg_for_in_operator(x, l, m):
+    """
+    >>> l = [1,2,3]
+    >>> m = [4,5,6]
+    >>> x = 1
+    >>> unpack_starred_arg_for_in_operator(x, l, m)
+    True
+    >>> x = 10
+    >>> unpack_starred_arg_for_in_operator(x, l, m)
+    False
+    >>> unpack_starred_arg_for_in_operator(x, l, [])
+    False
+    >>> unpack_starred_arg_for_in_operator(x, [], [])
+    False
+    """
+    return x in [*l, *m]
+
+
 ###### sets