BUG: ndarray.__pow__ does not check result of fast_scalar_power #9129
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Backport of #9112.
While testing astropy with array_ufunc, I found the puzzling behaviour that logarithmic quantities, which cannot be raised usefully to any power, gave SystemError when raising to 0.5. After looking into this, the reason is that if one raises an ndarray or subclass to particular powers, fast_scalar_power is used in number.c -- this defers to another function (sqrt in this case), but does not check whether an error occurred. Now if a subclass raises an error, and returns NULL, that gets interpreted as meaning the fast operation is not possible, and power is tried. E.g.,
class A(np.ndarray):
def array_ufunc(self, ufunc, method, *inputs, **kwargs):
print(ufunc)
raise ValueError
a = np.ones(1).view(A)
a ** 0.5
yields
<ufunc 'sqrt'>
<ufunc 'power'>---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
in array_ufunc(self, ufunc, method, *inputs, **kwargs)
3 print(ufunc)
----> 4 raise ValueError
5
ValueError:
During handling of the above exception, another exception occurred:
SystemError Traceback (most recent call last)
in ()
6
7 a = np.ones(1).view(A)
----> 8 a ** 0.5
in array_ufunc(self, ufunc, method, *inputs, **kwargs)
1 class A(np.ndarray):
2 def array_ufunc(self, ufunc, method, *inputs, **kwargs):
----> 3 print(ufunc)
4 raise ValueError
5
SystemError: <built-in method write of _io.TextIOWrapper object at 0x7f1307c7b630> returned a result with an error set