summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--numpy/core/src/multiarray/number.c8
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src8
-rw-r--r--numpy/core/src/umath/scalarmath.c.src37
-rw-r--r--numpy/core/tests/test_scalarmath.py11
4 files changed, 52 insertions, 12 deletions
diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c
index c4e675430..62e8e3884 100644
--- a/numpy/core/src/multiarray/number.c
+++ b/numpy/core/src/multiarray/number.c
@@ -614,10 +614,14 @@ fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace)
}
static PyObject *
-array_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo))
+array_power(PyArrayObject *a1, PyObject *o2, PyObject *modulo)
{
- /* modulo is ignored! */
PyObject *value;
+ if (modulo != Py_None) {
+ /* modular exponentiation is not implemented (gh-8804) */
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
GIVE_UP_IF_HAS_RIGHT_BINOP(a1, o2, "__pow__", "__rpow__", 0, nb_power);
value = fast_scalar_power(a1, o2, 0);
if (!value) {
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index f85e3b828..bad61e3f0 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -149,11 +149,17 @@ gentype_free(PyObject *v)
static PyObject *
-gentype_power(PyObject *m1, PyObject *m2, PyObject *NPY_UNUSED(m3))
+gentype_power(PyObject *m1, PyObject *m2, PyObject *modulo)
{
PyObject *arr, *ret, *arg2;
char *msg="unsupported operand type(s) for ** or pow()";
+ if (modulo != Py_None) {
+ /* modular exponentiation is not implemented (gh-8804) */
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
if (!PyArray_IsScalar(m1, Generic)) {
if (PyArray_Check(m1)) {
ret = Py_TYPE(m1)->tp_as_number->nb_power(m1,m2, Py_None);
diff --git a/numpy/core/src/umath/scalarmath.c.src b/numpy/core/src/umath/scalarmath.c.src
index ed6553f69..723ee998a 100644
--- a/numpy/core/src/umath/scalarmath.c.src
+++ b/numpy/core/src/umath/scalarmath.c.src
@@ -956,7 +956,7 @@ static PyObject *
#if @cmplx@
static PyObject *
-@name@_power(PyObject *a, PyObject *b, PyObject *NPY_UNUSED(c))
+@name@_power(PyObject *a, PyObject *b, PyObject *modulo)
{
PyObject *ret;
@type@ arg1, arg2;
@@ -969,13 +969,13 @@ static PyObject *
break;
case -1:
/* can't cast both safely mixed-types? */
- return PyArray_Type.tp_as_number->nb_power(a,b,NULL);
+ return PyArray_Type.tp_as_number->nb_power(a,b,modulo);
case -2:
/* use default handling */
if (PyErr_Occurred()) {
return NULL;
}
- return PyGenericArrType_Type.tp_as_number->nb_power(a,b,NULL);
+ return PyGenericArrType_Type.tp_as_number->nb_power(a,b,modulo);
case -3:
default:
/*
@@ -986,6 +986,12 @@ static PyObject *
return Py_NotImplemented;
}
+ if (modulo != Py_None) {
+ /* modular exponentiation is not implemented (gh-8804) */
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
PyUFunc_clearfperr();
/*
@@ -1030,7 +1036,7 @@ static PyObject *
#elif @isint@
static PyObject *
-@name@_power(PyObject *a, PyObject *b, PyObject *NPY_UNUSED(c))
+@name@_power(PyObject *a, PyObject *b, PyObject *modulo)
{
PyObject *ret;
@type@ arg1, arg2, out;
@@ -1040,13 +1046,13 @@ static PyObject *
break;
case -1:
/* can't cast both safely mixed-types? */
- return PyArray_Type.tp_as_number->nb_power(a,b,NULL);
+ return PyArray_Type.tp_as_number->nb_power(a,b,modulo);
case -2:
/* use default handling */
if (PyErr_Occurred()) {
return NULL;
}
- return PyGenericArrType_Type.tp_as_number->nb_power(a,b,NULL);
+ return PyGenericArrType_Type.tp_as_number->nb_power(a,b,modulo);
case -3:
default:
/*
@@ -1056,6 +1062,13 @@ static PyObject *
Py_INCREF(Py_NotImplemented);
return Py_NotImplemented;
}
+
+ if (modulo != Py_None) {
+ /* modular exponentiation is not implemented (gh-8804) */
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
PyUFunc_clearfperr();
/*
@@ -1081,7 +1094,7 @@ static PyObject *
#else
static PyObject *
-@name@_power(PyObject *a, PyObject *b, PyObject *NPY_UNUSED(c))
+@name@_power(PyObject *a, PyObject *b, PyObject *modulo)
{
PyObject *ret;
@type@ arg1, arg2;
@@ -1094,13 +1107,13 @@ static PyObject *
break;
case -1:
/* can't cast both safely mixed-types? */
- return PyArray_Type.tp_as_number->nb_power(a,b,NULL);
+ return PyArray_Type.tp_as_number->nb_power(a,b,modulo);
case -2:
/* use default handling */
if (PyErr_Occurred()) {
return NULL;
}
- return PyGenericArrType_Type.tp_as_number->nb_power(a,b,NULL);
+ return PyGenericArrType_Type.tp_as_number->nb_power(a,b,modulo);
case -3:
default:
/*
@@ -1111,6 +1124,12 @@ static PyObject *
return Py_NotImplemented;
}
+ if (modulo != Py_None) {
+ /* modular exponentiation is not implemented (gh-8804) */
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
PyUFunc_clearfperr();
/*
diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py
index e43a0b2e0..1cafde5a0 100644
--- a/numpy/core/tests/test_scalarmath.py
+++ b/numpy/core/tests/test_scalarmath.py
@@ -177,6 +177,17 @@ class TestPower(TestCase):
else:
assert_almost_equal(result, 9, err_msg=msg)
+ def test_modular_power(self):
+ # modular power is not implemented, so ensure it errors
+ a = 5
+ b = 4
+ c = 10
+ expected = pow(a, b, c)
+ for t in (np.int32, np.float32, np.complex64):
+ # note that 3-operand power only dispatches on the first argument
+ assert_raises(TypeError, operator.pow, t(a), b, c)
+ assert_raises(TypeError, operator.pow, np.array(t(a)), b, c)
+
class TestModulus(TestCase):