diff options
Diffstat (limited to 'numpy')
| -rw-r--r-- | numpy/core/numeric.py | 10 | ||||
| -rw-r--r-- | numpy/core/records.py | 5 | ||||
| -rw-r--r-- | numpy/core/tests/test_errstate.py | 8 | ||||
| -rw-r--r-- | numpy/lib/_datasource.py | 9 | ||||
| -rw-r--r-- | numpy/lib/function_base.py | 2 | ||||
| -rw-r--r-- | numpy/lib/nanfunctions.py | 27 | ||||
| -rw-r--r-- | numpy/lib/tests/test_nanfunctions.py | 28 |
7 files changed, 81 insertions, 8 deletions
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index 8a8efddf3..1b8f36c3e 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -12,6 +12,7 @@ import operator import sys import warnings import numbers +import contextlib import numpy as np from . import multiarray @@ -2990,7 +2991,7 @@ _Unspecified = _unspecified() @set_module('numpy') -class errstate(object): +class errstate(contextlib.ContextDecorator): """ errstate(**kwargs) @@ -3000,7 +3001,12 @@ class errstate(object): that context to execute with a known error handling behavior. Upon entering the context the error handling is set with `seterr` and `seterrcall`, and upon exiting it is reset to what it was before. - + + .. versionchanged:: 1.17.0 + `errstate` is also usable as a function decorator, saving + a level of indentation if an entire function is wrapped. + See :py:class:`contextlib.ContextDecorator` for more information. + Parameters ---------- kwargs : {divide, over, under, invalid} diff --git a/numpy/core/records.py b/numpy/core/records.py index 4ea83accc..42aca5b60 100644 --- a/numpy/core/records.py +++ b/numpy/core/records.py @@ -721,7 +721,7 @@ def fromstring(datastring, dtype=None, shape=None, offset=0, formats=None, a string""" if dtype is None and formats is None: - raise ValueError("Must have dtype= or formats=") + raise TypeError("fromstring() needs a 'dtype' or 'formats' argument") if dtype is not None: descr = sb.dtype(dtype) @@ -768,6 +768,9 @@ def fromfile(fd, dtype=None, shape=None, offset=0, formats=None, >>> r.shape (10,) """ + + if dtype is None and formats is None: + raise TypeError("fromfile() needs a 'dtype' or 'formats' argument") if (shape is None or shape == 0): shape = (-1,) diff --git a/numpy/core/tests/test_errstate.py b/numpy/core/tests/test_errstate.py index 670d485c1..0008c4cc8 100644 --- a/numpy/core/tests/test_errstate.py +++ b/numpy/core/tests/test_errstate.py @@ -39,3 +39,11 @@ class TestErrstate(object): with np.errstate(call=None): assert_(np.geterrcall() is None, 'call is not None') assert_(np.geterrcall() is olderrcall, 'call is not olderrcall') + + def test_errstate_decorator(self): + @np.errstate(all='ignore') + def foo(): + a = -np.arange(3) + a // 0 + + foo() diff --git a/numpy/lib/_datasource.py b/numpy/lib/_datasource.py index 3a0e67f60..816f7624e 100644 --- a/numpy/lib/_datasource.py +++ b/numpy/lib/_datasource.py @@ -547,6 +547,11 @@ class DataSource(object): is accessible if it exists in either location. """ + + # First test for local path + if os.path.exists(path): + return True + # We import this here because importing urllib2 is slow and # a significant fraction of numpy's total import time. if sys.version_info[0] >= 3: @@ -556,10 +561,6 @@ class DataSource(object): from urllib2 import urlopen from urllib2 import URLError - # Test local path - if os.path.exists(path): - return True - # Test cached url upath = self.abspath(path) if os.path.exists(upath): diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py index fa1f42252..b61a64b8e 100644 --- a/numpy/lib/function_base.py +++ b/numpy/lib/function_base.py @@ -1150,7 +1150,7 @@ def diff(a, n=1, axis=-1, prepend=np._NoValue, append=np._NoValue): """ Calculate the n-th discrete difference along the given axis. - The first difference is given by ``out[n] = a[n+1] - a[n]`` along + The first difference is given by ``out[i] = a[i+1] - a[i]`` along the given axis, higher differences are calculated by using `diff` recursively. diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py index b3bf1880b..77c851fcf 100644 --- a/numpy/lib/nanfunctions.py +++ b/numpy/lib/nanfunctions.py @@ -40,6 +40,33 @@ __all__ = [ ] +def _nan_mask(a, out=None): + """ + Parameters + ---------- + a : array-like + Input array with at least 1 dimension. + out : ndarray, optional + Alternate output array in which to place the result. The default + is ``None``; if provided, it must have the same shape as the + expected output and will prevent the allocation of a new array. + + Returns + ------- + y : bool ndarray or True + A bool array where ``np.nan`` positions are marked with ``False`` + and other positions are marked with ``True``. If the type of ``a`` + is such that it can't possibly contain ``np.nan``, returns ``True``. + """ + # we assume that a is an array for this private function + + if a.dtype.kind not in 'fc': + return True + + y = np.isnan(a, out=out) + y = np.invert(y, out=y) + return y + def _replace_nan(a, val): """ If `a` is of inexact type, make a copy of `a`, replace NaNs with diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py index 504372faf..b7261c63f 100644 --- a/numpy/lib/tests/test_nanfunctions.py +++ b/numpy/lib/tests/test_nanfunctions.py @@ -1,8 +1,10 @@ from __future__ import division, absolute_import, print_function import warnings +import pytest import numpy as np +from numpy.lib.nanfunctions import _nan_mask from numpy.testing import ( assert_, assert_equal, assert_almost_equal, assert_no_warnings, assert_raises, assert_array_equal, suppress_warnings @@ -925,3 +927,29 @@ class TestNanFunctions_Quantile(object): p = p.tolist() np.nanquantile(np.arange(100.), p, interpolation="midpoint") assert_array_equal(p, p0) + +@pytest.mark.parametrize("arr, expected", [ + # array of floats with some nans + (np.array([np.nan, 5.0, np.nan, np.inf]), + np.array([False, True, False, True])), + # int64 array that can't possibly have nans + (np.array([1, 5, 7, 9], dtype=np.int64), + True), + # bool array that can't possibly have nans + (np.array([False, True, False, True]), + True), + # 2-D complex array with nans + (np.array([[np.nan, 5.0], + [np.nan, np.inf]], dtype=np.complex64), + np.array([[False, True], + [False, True]])), + ]) +def test__nan_mask(arr, expected): + for out in [None, np.empty(arr.shape, dtype=np.bool_)]: + actual = _nan_mask(arr, out=out) + assert_equal(actual, expected) + # the above won't distinguish between True proper + # and an array of True values; we want True proper + # for types that can't possibly contain NaN + if type(expected) is not np.ndarray: + assert actual is True |
