Repository: numba/numba

Issue:
ndarray.sum() method silently ignores axis argument
On `numba==0.33.0`, `my_2d_array.sum(0)` is silently interpreted as `my_2d_array.sum()`.


Discussion:
Thanks for the report. I believe this is documented behaviour http://numba.pydata.org/numba-doc/latest/reference/numpysupported.html#calculation ? `The following methods of Numpy arrays are supported in their basic form (without any optional arguments): * sum()`
I think "silently ignores" is the problem here.  Numba should raise an error.  The axis argument changes the behavior too much.


Resolving patch:
diff --git a/numba/typing/arraydecl.py b/numba/typing/arraydecl.py
--- a/numba/typing/arraydecl.py
+++ b/numba/typing/arraydecl.py
@@ -528,9 +528,13 @@ def generic_homog(self, args, kws):
     return signature(self.this.dtype, recvr=self.this)
 
 def generic_expand(self, args, kws):
+    assert not args
+    assert not kws
     return signature(_expand_integer(self.this.dtype), recvr=self.this)
 
 def generic_expand_cumulative(self, args, kws):
+    assert not args
+    assert not kws
     assert isinstance(self.this, types.Array)
     return_type = types.Array(dtype=_expand_integer(self.this.dtype),
                               ndim=1, layout='C')


Test patch:
diff --git a/numba/tests/test_array_methods.py b/numba/tests/test_array_methods.py
--- a/numba/tests/test_array_methods.py
+++ b/numba/tests/test_array_methods.py
@@ -8,6 +8,7 @@
 from numba import unittest_support as unittest
 from numba import jit, typeof, types
 from numba.compiler import compile_isolated
+from numba.errors import TypingError
 from numba.numpy_support import (as_dtype, strict_ufunc_typing,
                                  version as numpy_version)
 from .support import TestCase, CompilationCache, MemoryLeak, MemoryLeakMixin, tag
@@ -131,6 +132,18 @@ def array_item(a):
 def array_itemset(a, v):
     a.itemset(v)
 
+def array_sum(a, *args):
+    return a.sum(*args)
+
+def array_sum_kws(a, axis):
+    return a.sum(axis=axis)
+
+def array_cumsum(a, *args):
+    return a.cumsum(*args)
+
+def array_cumsum_kws(a, axis):
+    return a.cumsum(axis=axis)
+
 
 class TestArrayMethods(MemoryLeakMixin, TestCase):
     """
@@ -602,6 +615,36 @@ def check_err(a):
         check_err(np.array([1, 2]))
         check_err(np.array([]))
 
+    def test_sum(self):
+        pyfunc = array_sum
+        cfunc = jit(nopython=True)(pyfunc)
+        # OK
+        a = np.ones((2, 3))
+        self.assertPreciseEqual(pyfunc(a), cfunc(a))
+        # BAD: with axis
+        with self.assertRaises(TypingError):
+            cfunc(a, 1)
+        # BAD: with kw axis
+        pyfunc = array_sum_kws
+        cfunc = jit(nopython=True)(pyfunc)
+        with self.assertRaises(TypingError):
+            cfunc(a, axis=1)
+
+    def test_cumsum(self):
+        pyfunc = array_cumsum
+        cfunc = jit(nopython=True)(pyfunc)
+        # OK
+        a = np.ones((2, 3))
+        self.assertPreciseEqual(pyfunc(a), cfunc(a))
+        # BAD: with axis
+        with self.assertRaises(TypingError):
+            cfunc(a, 1)
+        # BAD: with kw axis
+        pyfunc = array_cumsum_kws
+        cfunc = jit(nopython=True)(pyfunc)
+        with self.assertRaises(TypingError):
+            cfunc(a, axis=1)
+
 
 class TestArrayComparisons(TestCase):