Repository: numba/numba

Issue:
int * list isn't supported
---

<!--

Thanks for opening an issue! To help the Numba team handle your information
efficiently, please first ensure that there is no other issue present that
already describes the issue you have
(search at https://github.com/numba/numba/issues?&q=is%3Aissue).

-->

## Feature request

operator.mul(int, list) doesn't work inside JIT code. Seems like an easy fix.

```python3
import numba

@numba.njit
def f():
    return 5 * [1]

print(f())
```

Output:
```python3
No implementation of function Function(<built-in function mul>) found for signature:
 
 >>> mul(Literal[int](5), list(int64)<iv=[1]>)
 
There are 12 candidate implementations:
  - Of which 10 did not match due to:
  Overload of function 'mul': File: <numerous>: Line N/A.
    With argument(s): '(int64, list(int64)<iv=None>)':
   No match.
  - Of which 2 did not match due to:
  Operator Overload in function 'mul': File: unknown: Line unknown.
    With argument(s): '(int64, list(int64)<iv=None>)':
   No match for registered cases:
    * (int64, int64) -> int64
    * (int64, uint64) -> int64
    * (uint64, int64) -> int64
    * (uint64, uint64) -> uint64
    * (float32, float32) -> float32
    * (float64, float64) -> float64
    * (complex64, complex64) -> complex64
    * (complex128, complex128) -> complex128
       

During: typing of intrinsic-call at test.py (5)

File "test.py", line 5:
def f():
    return 5 * [1]


<!--

Please include details of the feature you would like to see, why you would
like to see it/the use case.
```

-->



Discussion:

Resolving patch:
diff --git a/numba/core/typing/listdecl.py b/numba/core/typing/listdecl.py
--- a/numba/core/typing/listdecl.py
+++ b/numba/core/typing/listdecl.py
@@ -153,6 +153,8 @@ def generic(self, args, kws):
         a, b = args
         if isinstance(a, types.List) and isinstance(b, types.Integer):
             return signature(a, a, types.intp)
+        elif isinstance(a, types.Integer) and isinstance(b, types.List):
+            return signature(b, types.intp, b)
 
 
 @infer_global(operator.imul)
diff --git a/numba/cpython/listobj.py b/numba/cpython/listobj.py
--- a/numba/cpython/listobj.py
+++ b/numba/cpython/listobj.py
@@ -714,11 +714,16 @@ def list_add_inplace(context, builder, sig, args):
 
 
 @lower_builtin(operator.mul, types.List, types.Integer)
+@lower_builtin(operator.mul, types.Integer, types.List)
 def list_mul(context, builder, sig, args):
-    src = ListInstance(context, builder, sig.args[0], args[0])
+    if isinstance(sig.args[0], types.List):
+        list_idx, int_idx = 0, 1
+    else:
+        list_idx, int_idx = 1, 0
+    src = ListInstance(context, builder, sig.args[list_idx], args[list_idx])
     src_size = src.size
 
-    mult = args[1]
+    mult = args[int_idx]
     zero = ir.Constant(mult.type, 0)
     mult = builder.select(cgutils.is_neg_int(builder, mult), zero, mult)
     nitems = builder.mul(mult, src_size)


Test patch:
diff --git a/numba/tests/test_lists.py b/numba/tests/test_lists.py
--- a/numba/tests/test_lists.py
+++ b/numba/tests/test_lists.py
@@ -312,6 +312,10 @@ def list_mul(n, v):
     a = list(range(n))
     return a * v
 
+def list_mul2(n, v):
+    a = list(range(n))
+    return v * a
+
 def list_mul_inplace(n, v):
     a = list(range(n))
     a *= v
@@ -656,6 +660,9 @@ def check_mul(self, pyfunc):
     def test_mul(self):
         self.check_mul(list_mul)
 
+    def test_mul2(self):
+        self.check_mul(list_mul2)
+
     def test_mul_inplace(self):
         self.check_mul(list_mul_inplace)