Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BUG: ndarray.__pow__ does not check result of fast_scalar_power #9129

Merged

Conversation

mhvk
Copy link
Contributor

@mhvk mhvk commented May 17, 2017

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

mhvk added 2 commits May 17, 2017 09:59
If one raises an ndarray or subclass to particular powers,
fast_scalar_power is used in number.c -- this defers to another
function (e.g., sqrt for 0.5), but does not check whether an error
occurred. In consequece, if a subclass raises an error, and returns
NULL, that gets interpreted as meaning the fast operation is not
possible, and power is tried in turn, likely raising another
exception.  This commit fixes fast_scalar_power such that it
returns success any time an operation is attempted.
@charris charris added this to the 1.13.0 release milestone May 17, 2017
@charris charris changed the title Array ufunc fast scalar power backport BUG: ndarray.__pow__ does not check result of fast_scalar_power May 17, 2017
@charris charris merged commit 1b53503 into numpy:maintenance/1.13.x May 17, 2017
@charris
Copy link
Member

charris commented May 17, 2017

Thanks Marten.

@mhvk mhvk deleted the array_ufunc_fast_scalar_power_backport branch August 31, 2017 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants