Repository: numba/numba

Issue:
np.arange with kwargs not supported when parallel=True
<!--

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).

-->

## Reporting a bug

<!--

Before submitting a bug report please ensure that you can check off these boxes:

-->

- [x] I have tried using the latest released version of Numba (most recent is
 visible in the change log (https://github.com/numba/numba/blob/main/CHANGE_LOG).
- [x] I have included a self contained code sample to reproduce the problem.
  i.e. it's possible to run as 'python bug.py'.

<!--

Please include details of the bug here, including, if applicable, what you
expected to happen!

-->

`parallel=True` with `np.arange` doesn't seem to support passing any arguments with keywords. Based on the code I believe this exists for all functions that are replaced, but here is a reproducer for `np.arange`.

```python3
import numpy as np
import numba

@numba.njit
def f():
    return np.arange(1, 100, dtype=np.float32)

@numba.njit(parallel=True)
def g():
    return np.arange(1, 100, dtype=np.float32)

print(f())
print(g())
```



Discussion:
@njriasan thank you for reporting this. I can reproduce and received the following stack-trace:

```
 💣 zsh» python issue_8225.py
[ 1.  2.  3.  4.  5.  6.  7.  8.  9. 10. 11. 12. 13. 14. 15. 16. 17. 18.
 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36.
 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54.
 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72.
 73. 74. 75. 76. 77. 78. 79. 80. 81. 82. 83. 84. 85. 86. 87. 88. 89. 90.
 91. 92. 93. 94. 95. 96. 97. 98. 99.]
Traceback (most recent call last):
  File "/Users/esc/git/numba/issue_8225.py", line 16, in <module>
    print(g())
  File "/Users/esc/git/numba/numba/core/dispatcher.py", line 487, in _compile_for_args
    raise e
  File "/Users/esc/git/numba/numba/core/dispatcher.py", line 420, in _compile_for_args
    return_val = self.compile(tuple(argtypes))
  File "/Users/esc/git/numba/numba/core/dispatcher.py", line 965, in compile
    cres = self._compiler.compile(args, return_type)
  File "/Users/esc/git/numba/numba/core/dispatcher.py", line 125, in compile
    status, retval = self._compile_cached(args, return_type)
  File "/Users/esc/git/numba/numba/core/dispatcher.py", line 139, in _compile_cached
    retval = self._compile_core(args, return_type)
  File "/Users/esc/git/numba/numba/core/dispatcher.py", line 152, in _compile_core
    cres = compiler.compile_extra(self.targetdescr.typing_context,
  File "/Users/esc/git/numba/numba/core/compiler.py", line 716, in compile_extra
    return pipeline.compile_extra(func)
  File "/Users/esc/git/numba/numba/core/compiler.py", line 452, in compile_extra
    return self._compile_bytecode()
  File "/Users/esc/git/numba/numba/core/compiler.py", line 520, in _compile_bytecode
    return self._compile_core()
  File "/Users/esc/git/numba/numba/core/compiler.py", line 499, in _compile_core
    raise e
  File "/Users/esc/git/numba/numba/core/compiler.py", line 486, in _compile_core
    pm.run(self.state)
  File "/Users/esc/git/numba/numba/core/compiler_machinery.py", line 368, in run
    raise patched_exception
  File "/Users/esc/git/numba/numba/core/compiler_machinery.py", line 356, in run
    self._runPass(idx, pass_inst, state)
  File "/Users/esc/git/numba/numba/core/compiler_lock.py", line 35, in _acquire_compile_lock
    return func(*args, **kwargs)
  File "/Users/esc/git/numba/numba/core/compiler_machinery.py", line 311, in _runPass
    mutated |= check(pss.run_pass, internal_state)
  File "/Users/esc/git/numba/numba/core/compiler_machinery.py", line 273, in check
    mangled = func(compiler_state)
  File "/Users/esc/git/numba/numba/core/typed_passes.py", line 269, in run_pass
    preparfor_pass.run()
  File "/Users/esc/git/numba/numba/parfors/parfor.py", line 1443, in run
    self._replace_parallel_functions(self.func_ir.blocks)
  File "/Users/esc/git/numba/numba/parfors/parfor.py", line 1509, in _replace_parallel_functions
    if guard(replace_func):
  File "/Users/esc/git/numba/numba/core/ir_utils.py", line 1527, in guard
    return func(*args, **kwargs)
  File "/Users/esc/git/numba/numba/parfors/parfor.py", line 1497, in replace_func
    new_blocks, _ = inline_closure_call(self.func_ir, g,
  File "/Users/esc/git/numba/numba/core/inline_closurecall.py", line 634, in inline_closure_call
    args = _get_callee_args(call_expr, callee, block.body[i].loc, func_ir)
  File "/Users/esc/git/numba/numba/core/inline_closurecall.py", line 749, in _get_callee_args
    return numba.core.typing.fold_arguments(
  File "/Users/esc/git/numba/numba/core/typing/templates.py", line 221, in fold_arguments
    ba = pysig.bind(*bind_args, **bind_kws)
  File "/Users/esc/miniconda3/envs/numba_3.10/lib/python3.10/inspect.py", line 3179, in bind
    return self._bind(args, kwargs)
  File "/Users/esc/miniconda3/envs/numba_3.10/lib/python3.10/inspect.py", line 3168, in _bind
    raise TypeError(
TypeError: Failed in nopython mode pipeline (step: Preprocessing for parfors)
got an unexpected keyword argument 'dtype'
```

Resolving patch:
diff --git a/numba/parfors/parfor.py b/numba/parfors/parfor.py
--- a/numba/parfors/parfor.py
+++ b/numba/parfors/parfor.py
@@ -1478,6 +1478,10 @@ def replace_func():
 
                             require(repl_func is not None)
                             typs = tuple(self.typemap[x.name] for x in expr.args)
+                            # The dtype keyword argument is handled by typing and can
+                            # be removed here during the implementation replacement so
+                            # that subsequent typing and argument handling won't fail.
+                            expr.kws = list(filter(lambda x: x[0] != "dtype", expr.kws))
                             try:
                                 new_func =  repl_func(lhs_typ, *typs)
                             except:


Test patch:
diff --git a/numba/tests/test_parfors.py b/numba/tests/test_parfors.py
--- a/numba/tests/test_parfors.py
+++ b/numba/tests/test_parfors.py
@@ -908,7 +908,7 @@ def test_impl1(n):
             return np.arange(n)
         # start and stop
         def test_impl2(s, n):
-            return np.arange(n)
+            return np.arange(s, n)
         # start, step, stop
         def test_impl3(s, n, t):
             return np.arange(s, n, t)
@@ -918,6 +918,22 @@ def test_impl3(s, n, t):
             self.check(test_impl2, 2, arg)
             self.check(test_impl3, 2, arg, 2)
 
+    def test_arange_dtype(self):
+        # test with stop only
+        def test_impl1(n):
+            return np.arange(n, dtype=np.float32)
+        # start and stop
+        def test_impl2(s, n):
+            return np.arange(s, n, dtype=np.float32)
+        # start, step, stop
+        def test_impl3(s, n, t):
+            return np.arange(s, n, t, dtype=np.float32)
+
+        for arg in [11, 128, 30.0]:
+            self.check(test_impl1, arg)
+            self.check(test_impl2, 2, arg)
+            self.check(test_impl3, 2, arg, 2)
+
     def test_linspace(self):
         # without num
         def test_impl1(start, stop):