summaryrefslogtreecommitdiff
path: root/numpy/lib
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/lib')
-rw-r--r--numpy/lib/__init__.py2
-rw-r--r--numpy/lib/_datasource.py112
-rw-r--r--numpy/lib/_iotools.py149
-rw-r--r--numpy/lib/_version.py8
-rw-r--r--numpy/lib/arraypad.py6
-rw-r--r--numpy/lib/arraysetops.py52
-rw-r--r--numpy/lib/arrayterator.py11
-rw-r--r--numpy/lib/financial.py148
-rw-r--r--numpy/lib/format.py72
-rw-r--r--numpy/lib/function_base.py226
-rw-r--r--numpy/lib/histograms.py41
-rw-r--r--numpy/lib/index_tricks.py16
-rw-r--r--numpy/lib/mixins.py10
-rw-r--r--numpy/lib/nanfunctions.py37
-rw-r--r--numpy/lib/npyio.py164
-rw-r--r--numpy/lib/polynomial.py12
-rw-r--r--numpy/lib/recfunctions.py38
-rw-r--r--numpy/lib/scimath.py2
-rw-r--r--numpy/lib/setup.py2
-rw-r--r--numpy/lib/shape_base.py73
-rw-r--r--numpy/lib/stride_tricks.py12
-rw-r--r--numpy/lib/tests/test__datasource.py48
-rw-r--r--numpy/lib/tests/test__iotools.py17
-rw-r--r--numpy/lib/tests/test__version.py2
-rw-r--r--numpy/lib/tests/test_arraypad.py59
-rw-r--r--numpy/lib/tests/test_arraysetops.py133
-rw-r--r--numpy/lib/tests/test_arrayterator.py2
-rw-r--r--numpy/lib/tests/test_financial.py40
-rw-r--r--numpy/lib/tests/test_format.py95
-rw-r--r--numpy/lib/tests/test_function_base.py231
-rw-r--r--numpy/lib/tests/test_histograms.py21
-rw-r--r--numpy/lib/tests/test_index_tricks.py18
-rw-r--r--numpy/lib/tests/test_io.py107
-rw-r--r--numpy/lib/tests/test_mixins.py20
-rw-r--r--numpy/lib/tests/test_nanfunctions.py45
-rw-r--r--numpy/lib/tests/test_packbits.py2
-rw-r--r--numpy/lib/tests/test_polynomial.py4
-rw-r--r--numpy/lib/tests/test_recfunctions.py19
-rw-r--r--numpy/lib/tests/test_regression.py13
-rw-r--r--numpy/lib/tests/test_shape_base.py59
-rw-r--r--numpy/lib/tests/test_stride_tricks.py11
-rw-r--r--numpy/lib/tests/test_twodim_base.py22
-rw-r--r--numpy/lib/tests/test_type_check.py40
-rw-r--r--numpy/lib/tests/test_ufunclike.py8
-rw-r--r--numpy/lib/tests/test_utils.py9
-rw-r--r--numpy/lib/twodim_base.py6
-rw-r--r--numpy/lib/type_check.py22
-rw-r--r--numpy/lib/ufunclike.py26
-rw-r--r--numpy/lib/user_array.py12
-rw-r--r--numpy/lib/utils.py46
50 files changed, 1138 insertions, 1192 deletions
diff --git a/numpy/lib/__init__.py b/numpy/lib/__init__.py
index 2db12d9a4..cb0de0d15 100644
--- a/numpy/lib/__init__.py
+++ b/numpy/lib/__init__.py
@@ -11,8 +11,6 @@ Most contains basic functions that are used by several submodules and are
useful to have in the main name-space.
"""
-from __future__ import division, absolute_import, print_function
-
import math
from numpy.version import version as __version__
diff --git a/numpy/lib/_datasource.py b/numpy/lib/_datasource.py
index 0d71375c2..f5d0cc217 100644
--- a/numpy/lib/_datasource.py
+++ b/numpy/lib/_datasource.py
@@ -34,11 +34,7 @@ Example::
>>> fp.close() # doctest: +SKIP
"""
-from __future__ import division, absolute_import, print_function
-
import os
-import sys
-import warnings
import shutil
import io
from contextlib import closing
@@ -72,76 +68,12 @@ def _check_mode(mode, encoding, newline):
raise ValueError("Argument 'newline' not supported in binary mode")
-def _python2_bz2open(fn, mode, encoding, newline):
- """Wrapper to open bz2 in text mode.
-
- Parameters
- ----------
- fn : str
- File name
- mode : {'r', 'w'}
- File mode. Note that bz2 Text files are not supported.
- encoding : str
- Ignored, text bz2 files not supported in Python2.
- newline : str
- Ignored, text bz2 files not supported in Python2.
- """
- import bz2
-
- _check_mode(mode, encoding, newline)
-
- if "t" in mode:
- # BZ2File is missing necessary functions for TextIOWrapper
- warnings.warn("Assuming latin1 encoding for bz2 text file in Python2",
- RuntimeWarning, stacklevel=5)
- mode = mode.replace("t", "")
- return bz2.BZ2File(fn, mode)
-
-def _python2_gzipopen(fn, mode, encoding, newline):
- """ Wrapper to open gzip in text mode.
-
- Parameters
- ----------
- fn : str, bytes, file
- File path or opened file.
- mode : str
- File mode. The actual files are opened as binary, but will decoded
- using the specified `encoding` and `newline`.
- encoding : str
- Encoding to be used when reading/writing as text.
- newline : str
- Newline to be used when reading/writing as text.
-
- """
- import gzip
- # gzip is lacking read1 needed for TextIOWrapper
- class GzipWrap(gzip.GzipFile):
- def read1(self, n):
- return self.read(n)
-
- _check_mode(mode, encoding, newline)
-
- gz_mode = mode.replace("t", "")
-
- if isinstance(fn, (str, bytes)):
- binary_file = GzipWrap(fn, gz_mode)
- elif hasattr(fn, "read") or hasattr(fn, "write"):
- binary_file = GzipWrap(None, gz_mode, fileobj=fn)
- else:
- raise TypeError("filename must be a str or bytes object, or a file")
-
- if "t" in mode:
- return io.TextIOWrapper(binary_file, encoding, newline=newline)
- else:
- return binary_file
-
-
# Using a class instead of a module-level dictionary
# to reduce the initial 'import numpy' overhead by
# deferring the import of lzma, bz2 and gzip until needed
# TODO: .zip support, .tar support?
-class _FileOpeners(object):
+class _FileOpeners:
"""
Container for different methods to open (un-)compressed files.
@@ -176,19 +108,13 @@ class _FileOpeners(object):
try:
import bz2
- if sys.version_info[0] >= 3:
- self._file_openers[".bz2"] = bz2.open
- else:
- self._file_openers[".bz2"] = _python2_bz2open
+ self._file_openers[".bz2"] = bz2.open
except ImportError:
pass
try:
import gzip
- if sys.version_info[0] >= 3:
- self._file_openers[".gz"] = gzip.open
- else:
- self._file_openers[".gz"] = _python2_gzipopen
+ self._file_openers[".gz"] = gzip.open
except ImportError:
pass
@@ -270,7 +196,7 @@ def open(path, mode='r', destpath=os.curdir, encoding=None, newline=None):
@set_module('numpy')
-class DataSource(object):
+class DataSource:
"""
DataSource(destpath='.')
@@ -377,10 +303,7 @@ class DataSource(object):
"""Test if path is a net location. Tests the scheme and netloc."""
# We do this here to reduce the 'import numpy' initial import time.
- if sys.version_info[0] >= 3:
- from urllib.parse import urlparse
- else:
- from urlparse import urlparse
+ from urllib.parse import urlparse
# BUG : URLs require a scheme string ('http://') to be used.
# www.google.com will fail.
@@ -397,14 +320,10 @@ class DataSource(object):
Creates a copy of the file in the datasource cache.
"""
- # We import these here because importing urllib2 is slow and
+ # We import these here because importing urllib is slow and
# a significant fraction of numpy's total import time.
- if sys.version_info[0] >= 3:
- from urllib.request import urlopen
- from urllib.error import URLError
- else:
- from urllib2 import urlopen
- from urllib2 import URLError
+ from urllib.request import urlopen
+ from urllib.error import URLError
upath = self.abspath(path)
@@ -479,10 +398,7 @@ class DataSource(object):
"""
# We do this here to reduce the 'import numpy' initial import time.
- if sys.version_info[0] >= 3:
- from urllib.parse import urlparse
- else:
- from urlparse import urlparse
+ from urllib.parse import urlparse
# TODO: This should be more robust. Handles case where path includes
# the destpath, but not other sub-paths. Failing case:
@@ -549,14 +465,10 @@ class DataSource(object):
if os.path.exists(path):
return True
- # We import this here because importing urllib2 is slow and
+ # We import this here because importing urllib is slow and
# a significant fraction of numpy's total import time.
- if sys.version_info[0] >= 3:
- from urllib.request import urlopen
- from urllib.error import URLError
- else:
- from urllib2 import urlopen
- from urllib2 import URLError
+ from urllib.request import urlopen
+ from urllib.error import URLError
# Test cached url
upath = self.abspath(path)
diff --git a/numpy/lib/_iotools.py b/numpy/lib/_iotools.py
index c392929fd..ff5b94342 100644
--- a/numpy/lib/_iotools.py
+++ b/numpy/lib/_iotools.py
@@ -1,20 +1,11 @@
"""A collection of functions designed to help I/O with ascii files.
"""
-from __future__ import division, absolute_import, print_function
-
__docformat__ = "restructuredtext en"
-import sys
import numpy as np
import numpy.core.numeric as nx
-from numpy.compat import asbytes, asunicode, bytes, basestring
-
-if sys.version_info[0] >= 3:
- from builtins import bool, int, float, complex, object, str
- unicode = str
-else:
- from __builtin__ import bool, int, float, complex, object, unicode, str
+from numpy.compat import asbytes, asunicode, bytes
def _decode_line(line, encoding=None):
@@ -65,40 +56,6 @@ def _is_bytes_like(obj):
return True
-def _to_filehandle(fname, flag='r', return_opened=False):
- """
- Returns the filehandle corresponding to a string or a file.
- If the string ends in '.gz', the file is automatically unzipped.
-
- Parameters
- ----------
- fname : string, filehandle
- Name of the file whose filehandle must be returned.
- flag : string, optional
- Flag indicating the status of the file ('r' for read, 'w' for write).
- return_opened : boolean, optional
- Whether to return the opening status of the file.
- """
- if _is_string_like(fname):
- if fname.endswith('.gz'):
- import gzip
- fhd = gzip.open(fname, flag)
- elif fname.endswith('.bz2'):
- import bz2
- fhd = bz2.BZ2File(fname)
- else:
- fhd = file(fname, flag)
- opened = True
- elif hasattr(fname, 'seek'):
- fhd = fname
- opened = False
- else:
- raise ValueError('fname must be a string or file handle')
- if return_opened:
- return fhd, opened
- return fhd
-
-
def has_nested_fields(ndtype):
"""
Returns whether one or several fields of a dtype are nested.
@@ -173,7 +130,7 @@ def flatten_dtype(ndtype, flatten_base=False):
return types
-class LineSplitter(object):
+class LineSplitter:
"""
Object to split a string at a given delimiter or at given places.
@@ -210,14 +167,15 @@ class LineSplitter(object):
return lambda input: [_.strip() for _ in method(input)]
#
- def __init__(self, delimiter=None, comments='#', autostrip=True, encoding=None):
+ def __init__(self, delimiter=None, comments='#', autostrip=True,
+ encoding=None):
delimiter = _decode_line(delimiter)
comments = _decode_line(comments)
self.comments = comments
# Delimiter is a character
- if (delimiter is None) or isinstance(delimiter, basestring):
+ if (delimiter is None) or isinstance(delimiter, str):
delimiter = delimiter or None
_handyman = self._delimited_splitter
# Delimiter is a list of field widths
@@ -273,7 +231,7 @@ class LineSplitter(object):
return self._handyman(_decode_line(line, self.encoding))
-class NameValidator(object):
+class NameValidator:
"""
Object to validate a list of strings to use as field names.
@@ -387,7 +345,7 @@ class NameValidator(object):
if (nbfields is None):
return None
names = []
- if isinstance(names, basestring):
+ if isinstance(names, str):
names = [names, ]
if nbfields is not None:
nbnames = len(names)
@@ -496,7 +454,7 @@ class ConversionWarning(UserWarning):
pass
-class StringConverter(object):
+class StringConverter:
"""
Factory class for function transforming a string into another object
(int, float).
@@ -546,18 +504,23 @@ class StringConverter(object):
"""
#
_mapper = [(nx.bool_, str2bool, False),
- (nx.integer, int, -1)]
+ (nx.int_, int, -1),]
# On 32-bit systems, we need to make sure that we explicitly include
- # nx.int64 since ns.integer is nx.int32.
- if nx.dtype(nx.integer).itemsize < nx.dtype(nx.int64).itemsize:
+ # nx.int64 since ns.int_ is nx.int32.
+ if nx.dtype(nx.int_).itemsize < nx.dtype(nx.int64).itemsize:
_mapper.append((nx.int64, int, -1))
- _mapper.extend([(nx.floating, float, nx.nan),
- (nx.complexfloating, complex, nx.nan + 0j),
+ _mapper.extend([(nx.float64, float, nx.nan),
+ (nx.complex128, complex, nx.nan + 0j),
(nx.longdouble, nx.longdouble, nx.nan),
(nx.unicode_, asunicode, '???'),
- (nx.string_, asbytes, '???')])
+ (nx.string_, asbytes, '???'),
+ # If a non-default dtype is passed, fall back to generic
+ # ones (should only be used for the converter)
+ (nx.integer, int, -1),
+ (nx.floating, float, nx.nan),
+ (nx.complexfloating, complex, nx.nan + 0j),])
(_defaulttype, _defaultfunc, _defaultfill) = zip(*_mapper)
@@ -701,7 +664,7 @@ class StringConverter(object):
if missing_values is None:
self.missing_values = {''}
else:
- if isinstance(missing_values, basestring):
+ if isinstance(missing_values, str):
missing_values = missing_values.split(",")
self.missing_values = set(list(missing_values) + [''])
#
@@ -748,6 +711,26 @@ class StringConverter(object):
return self._callingfunction(value)
#
+ def _do_upgrade(self):
+ # Raise an exception if we locked the converter...
+ if self._locked:
+ errmsg = "Converter is locked and cannot be upgraded"
+ raise ConverterLockError(errmsg)
+ _statusmax = len(self._mapper)
+ # Complains if we try to upgrade by the maximum
+ _status = self._status
+ if _status == _statusmax:
+ errmsg = "Could not find a valid conversion function"
+ raise ConverterError(errmsg)
+ elif _status < _statusmax - 1:
+ _status += 1
+ self.type, self.func, default = self._mapper[_status]
+ self._status = _status
+ if self._initial_default is not None:
+ self.default = self._initial_default
+ else:
+ self.default = default
+
def upgrade(self, value):
"""
Find the best converter for a given string, and return the result.
@@ -773,24 +756,7 @@ class StringConverter(object):
try:
return self._strict_call(value)
except ValueError:
- # Raise an exception if we locked the converter...
- if self._locked:
- errmsg = "Converter is locked and cannot be upgraded"
- raise ConverterLockError(errmsg)
- _statusmax = len(self._mapper)
- # Complains if we try to upgrade by the maximum
- _status = self._status
- if _status == _statusmax:
- errmsg = "Could not find a valid conversion function"
- raise ConverterError(errmsg)
- elif _status < _statusmax - 1:
- _status += 1
- (self.type, self.func, default) = self._mapper[_status]
- self._status = _status
- if self._initial_default is not None:
- self.default = self._initial_default
- else:
- self.default = default
+ self._do_upgrade()
return self.upgrade(value)
def iterupgrade(self, value):
@@ -802,25 +768,7 @@ class StringConverter(object):
for _m in value:
_strict_call(_m)
except ValueError:
- # Raise an exception if we locked the converter...
- if self._locked:
- errmsg = "Converter is locked and cannot be upgraded"
- raise ConverterLockError(errmsg)
- _statusmax = len(self._mapper)
- # Complains if we try to upgrade by the maximum
- _status = self._status
- if _status == _statusmax:
- raise ConverterError(
- "Could not find a valid conversion function"
- )
- elif _status < _statusmax - 1:
- _status += 1
- (self.type, self.func, default) = self._mapper[_status]
- if self._initial_default is not None:
- self.default = self._initial_default
- else:
- self.default = default
- self._status = _status
+ self._do_upgrade()
self.iterupgrade(value)
def update(self, func, default=None, testing_value=None,
@@ -876,7 +824,7 @@ class StringConverter(object):
else:
if not np.iterable(missing_values):
missing_values = [missing_values]
- if not all(isinstance(v, basestring) for v in missing_values):
+ if not all(isinstance(v, str) for v in missing_values):
raise TypeError("missing_values must be strings or unicode")
self.missing_values.update(missing_values)
@@ -926,7 +874,7 @@ def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs):
nbfields = len(ndtype)
if names is None:
names = [''] * len(ndtype)
- elif isinstance(names, basestring):
+ elif isinstance(names, str):
names = names.split(",")
names = validate(names, nbfields=nbfields, defaultfmt=defaultfmt)
ndtype = np.dtype(dict(formats=ndtype, names=names))
@@ -934,7 +882,7 @@ def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs):
# Explicit names
if names is not None:
validate = NameValidator(**validationargs)
- if isinstance(names, basestring):
+ if isinstance(names, str):
names = names.split(",")
# Simple dtype: repeat to match the nb of names
if ndtype.names is None:
@@ -949,9 +897,10 @@ def easy_dtype(ndtype, names=None, defaultfmt="f%i", **validationargs):
elif ndtype.names is not None:
validate = NameValidator(**validationargs)
# Default initial names : should we change the format ?
- if ((ndtype.names == tuple("f%i" % i for i in range(len(ndtype.names)))) and
- (defaultfmt != "f%i")):
- ndtype.names = validate([''] * len(ndtype.names), defaultfmt=defaultfmt)
+ numbered_names = tuple("f%i" % i for i in range(len(ndtype.names)))
+ if ((ndtype.names == numbered_names) and (defaultfmt != "f%i")):
+ ndtype.names = validate([''] * len(ndtype.names),
+ defaultfmt=defaultfmt)
# Explicit initial names : just validate
else:
ndtype.names = validate(ndtype.names, defaultfmt=defaultfmt)
diff --git a/numpy/lib/_version.py b/numpy/lib/_version.py
index 8aa999fc9..d4098acb5 100644
--- a/numpy/lib/_version.py
+++ b/numpy/lib/_version.py
@@ -5,12 +5,8 @@ The LooseVersion and StrictVersion classes that distutils provides don't
work; they don't recognize anything like alpha/beta/rc/dev versions.
"""
-from __future__ import division, absolute_import, print_function
-
import re
-from numpy.compat import basestring
-
__all__ = ['NumpyVersion']
@@ -116,10 +112,10 @@ class NumpyVersion():
return vercmp
def _compare(self, other):
- if not isinstance(other, (basestring, NumpyVersion)):
+ if not isinstance(other, (str, NumpyVersion)):
raise ValueError("Invalid object to compare with NumpyVersion.")
- if isinstance(other, basestring):
+ if isinstance(other, str):
other = NumpyVersion(other)
vercmp = self._compare_version(other)
diff --git a/numpy/lib/arraypad.py b/numpy/lib/arraypad.py
index 33e64708d..7569e7651 100644
--- a/numpy/lib/arraypad.py
+++ b/numpy/lib/arraypad.py
@@ -3,8 +3,6 @@ The arraypad module contains a group of functions to pad values onto the edges
of an n-dimensional array.
"""
-from __future__ import division, absolute_import, print_function
-
import numpy as np
from numpy.core.overrides import array_function_dispatch
from numpy.lib.index_tricks import ndindex
@@ -234,7 +232,7 @@ def _get_linear_ramps(padded, axis, width_pair, end_value_pair):
def _get_stats(padded, axis, width_pair, length_pair, stat_func):
"""
- Calculate statistic for the empty-padded array in given dimnsion.
+ Calculate statistic for the empty-padded array in given dimension.
Parameters
----------
@@ -273,7 +271,7 @@ def _get_stats(padded, axis, width_pair, length_pair, stat_func):
if (left_length == 0 or right_length == 0) \
and stat_func in {np.amax, np.amin}:
- # amax and amin can't operate on an emtpy array,
+ # amax and amin can't operate on an empty array,
# raise a more descriptive warning here instead of the default one
raise ValueError("stat_length of 0 yields no value for padding")
diff --git a/numpy/lib/arraysetops.py b/numpy/lib/arraysetops.py
index 2309f7e42..22687b941 100644
--- a/numpy/lib/arraysetops.py
+++ b/numpy/lib/arraysetops.py
@@ -25,8 +25,6 @@ To do: Optionally return indices analogously to unique for all functions.
:Author: Robert Cimrman
"""
-from __future__ import division, absolute_import, print_function
-
import functools
import numpy as np
@@ -94,8 +92,7 @@ def ediff1d(ary, to_end=None, to_begin=None):
# force a 1d array
ary = np.asanyarray(ary).ravel()
- # enforce propagation of the dtype of input
- # ary to returned result
+ # enforce that the dtype of `ary` is used for the output
dtype_req = ary.dtype
# fast track default case
@@ -105,22 +102,23 @@ def ediff1d(ary, to_end=None, to_begin=None):
if to_begin is None:
l_begin = 0
else:
- _to_begin = np.asanyarray(to_begin, dtype=dtype_req)
- if not np.all(_to_begin == to_begin):
- raise ValueError("cannot convert 'to_begin' to array with dtype "
- "'%r' as required for input ary" % dtype_req)
- to_begin = _to_begin.ravel()
+ to_begin = np.asanyarray(to_begin)
+ if not np.can_cast(to_begin, dtype_req, casting="same_kind"):
+ raise TypeError("dtype of `to_end` must be compatible "
+ "with input `ary` under the `same_kind` rule.")
+
+ to_begin = to_begin.ravel()
l_begin = len(to_begin)
if to_end is None:
l_end = 0
else:
- _to_end = np.asanyarray(to_end, dtype=dtype_req)
- # check that casting has not overflowed
- if not np.all(_to_end == to_end):
- raise ValueError("cannot convert 'to_end' to array with dtype "
- "'%r' as required for input ary" % dtype_req)
- to_end = _to_end.ravel()
+ to_end = np.asanyarray(to_end)
+ if not np.can_cast(to_end, dtype_req, casting="same_kind"):
+ raise TypeError("dtype of `to_end` must be compatible "
+ "with input `ary` under the `same_kind` rule.")
+
+ to_end = to_end.ravel()
l_end = len(to_end)
# do the calculation in place and copy to_begin and to_end
@@ -253,9 +251,9 @@ def unique(ar, return_index=False, return_inverse=False,
>>> u
array([1, 2, 3, 4, 6])
>>> indices
- array([0, 1, 4, ..., 1, 2, 1])
+ array([0, 1, 4, 3, 1, 2, 1])
>>> u[indices]
- array([1, 2, 6, ..., 2, 3, 2])
+ array([1, 2, 6, 4, 2, 3, 2])
"""
ar = np.asanyarray(ar)
@@ -272,20 +270,33 @@ def unique(ar, return_index=False, return_inverse=False,
# Must reshape to a contiguous 2D array for this to work...
orig_shape, orig_dtype = ar.shape, ar.dtype
- ar = ar.reshape(orig_shape[0], -1)
+ ar = ar.reshape(orig_shape[0], np.prod(orig_shape[1:], dtype=np.intp))
ar = np.ascontiguousarray(ar)
dtype = [('f{i}'.format(i=i), ar.dtype) for i in range(ar.shape[1])]
+ # At this point, `ar` has shape `(n, m)`, and `dtype` is a structured
+ # data type with `m` fields where each field has the data type of `ar`.
+ # In the following, we create the array `consolidated`, which has
+ # shape `(n,)` with data type `dtype`.
try:
- consolidated = ar.view(dtype)
+ if ar.shape[1] > 0:
+ consolidated = ar.view(dtype)
+ else:
+ # If ar.shape[1] == 0, then dtype will be `np.dtype([])`, which is
+ # a data type with itemsize 0, and the call `ar.view(dtype)` will
+ # fail. Instead, we'll use `np.empty` to explicitly create the
+ # array with shape `(len(ar),)`. Because `dtype` in this case has
+ # itemsize 0, the total size of the result is still 0 bytes.
+ consolidated = np.empty(len(ar), dtype=dtype)
except TypeError:
# There's no good way to do this for object arrays, etc...
msg = 'The axis argument to unique is not supported for dtype {dt}'
raise TypeError(msg.format(dt=ar.dtype))
def reshape_uniq(uniq):
+ n = len(uniq)
uniq = uniq.view(orig_dtype)
- uniq = uniq.reshape(-1, *orig_shape[1:])
+ uniq = uniq.reshape(n, *orig_shape[1:])
uniq = np.moveaxis(uniq, 0, axis)
return uniq
@@ -785,4 +796,3 @@ def setdiff1d(ar1, ar2, assume_unique=False):
ar1 = unique(ar1)
ar2 = unique(ar2)
return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]
-
diff --git a/numpy/lib/arrayterator.py b/numpy/lib/arrayterator.py
index c16668582..b9ea21f8e 100644
--- a/numpy/lib/arrayterator.py
+++ b/numpy/lib/arrayterator.py
@@ -7,17 +7,13 @@ an array object, and when iterated it will return sub-arrays with at most
a user-specified number of elements.
"""
-from __future__ import division, absolute_import, print_function
-
from operator import mul
from functools import reduce
-from numpy.compat import long
-
__all__ = ['Arrayterator']
-class Arrayterator(object):
+class Arrayterator:
"""
Buffered iterator for big arrays.
@@ -110,7 +106,7 @@ class Arrayterator(object):
if slice_ is Ellipsis:
fixed.extend([slice(None)] * (dims-length+1))
length = len(fixed)
- elif isinstance(slice_, (int, long)):
+ elif isinstance(slice_, int):
fixed.append(slice(slice_, slice_+1, 1))
else:
fixed.append(slice_)
@@ -163,8 +159,7 @@ class Arrayterator(object):
"""
for block in self:
- for value in block.flat:
- yield value
+ yield from block.flat
@property
def shape(self):
diff --git a/numpy/lib/financial.py b/numpy/lib/financial.py
index d72384e99..b055bb1ec 100644
--- a/numpy/lib/financial.py
+++ b/numpy/lib/financial.py
@@ -10,8 +10,7 @@ or arrays (or other sequences).
Functions support the :class:`decimal.Decimal` type unless
otherwise stated.
"""
-from __future__ import division, absolute_import, print_function
-
+import warnings
from decimal import Decimal
import functools
@@ -19,6 +18,10 @@ import numpy as np
from numpy.core import overrides
+_depmsg = ("numpy.{name} is deprecated and will be removed from NumPy 1.20. "
+ "Use numpy_financial.{name} instead "
+ "(https://pypi.org/project/numpy-financial/).")
+
array_function_dispatch = functools.partial(
overrides.array_function_dispatch, module='numpy')
@@ -45,6 +48,8 @@ def _convert_when(when):
def _fv_dispatcher(rate, nper, pmt, pv, when=None):
+ warnings.warn(_depmsg.format(name='fv'),
+ DeprecationWarning, stacklevel=3)
return (rate, nper, pmt, pv)
@@ -53,6 +58,12 @@ def fv(rate, nper, pmt, pv, when='end'):
"""
Compute the future value.
+ .. deprecated:: 1.18
+
+ `fv` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
Given:
* a present value, `pv`
* an interest `rate` compounded once per period, of which
@@ -100,7 +111,9 @@ def fv(rate, nper, pmt, pv, when='end'):
References
----------
- .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+ .. [2] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
Open Document Format for Office Applications (OpenDocument)v1.2,
Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
Pre-Draft 12. Organization for the Advancement of Structured Information
@@ -109,6 +122,7 @@ def fv(rate, nper, pmt, pv, when='end'):
http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
OpenDocument-formula-20090508.odt
+
Examples
--------
What is the future value after 10 years of saving $100 now, with
@@ -139,6 +153,8 @@ def fv(rate, nper, pmt, pv, when='end'):
def _pmt_dispatcher(rate, nper, pv, fv=None, when=None):
+ warnings.warn(_depmsg.format(name='pmt'),
+ DeprecationWarning, stacklevel=3)
return (rate, nper, pv, fv)
@@ -147,6 +163,12 @@ def pmt(rate, nper, pv, fv=0, when='end'):
"""
Compute the payment against loan principal plus interest.
+ .. deprecated:: 1.18
+
+ `pmt` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
Given:
* a present value, `pv` (e.g., an amount borrowed)
* a future value, `fv` (e.g., 0)
@@ -204,7 +226,9 @@ def pmt(rate, nper, pv, fv=0, when='end'):
References
----------
- .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+ .. [2] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
Open Document Format for Office Applications (OpenDocument)v1.2,
Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
Pre-Draft 12. Organization for the Advancement of Structured Information
@@ -237,6 +261,8 @@ def pmt(rate, nper, pv, fv=0, when='end'):
def _nper_dispatcher(rate, pmt, pv, fv=None, when=None):
+ warnings.warn(_depmsg.format(name='nper'),
+ DeprecationWarning, stacklevel=3)
return (rate, pmt, pv, fv)
@@ -245,6 +271,12 @@ def nper(rate, pmt, pv, fv=0, when='end'):
"""
Compute the number of periodic payments.
+ .. deprecated:: 1.18
+
+ `nper` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
:class:`decimal.Decimal` type is not supported.
Parameters
@@ -270,6 +302,11 @@ def nper(rate, pmt, pv, fv=0, when='end'):
fv + pv + pmt*nper = 0
+ References
+ ----------
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+
Examples
--------
If you only had $150/month to pay towards the loan, how long would it take
@@ -311,6 +348,8 @@ def nper(rate, pmt, pv, fv=0, when='end'):
def _ipmt_dispatcher(rate, per, nper, pv, fv=None, when=None):
+ warnings.warn(_depmsg.format(name='ipmt'),
+ DeprecationWarning, stacklevel=3)
return (rate, per, nper, pv, fv)
@@ -319,6 +358,12 @@ def ipmt(rate, per, nper, pv, fv=0, when='end'):
"""
Compute the interest portion of a payment.
+ .. deprecated:: 1.18
+
+ `ipmt` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
Parameters
----------
rate : scalar or array_like of shape(M, )
@@ -354,6 +399,11 @@ def ipmt(rate, per, nper, pv, fv=0, when='end'):
``pmt = ppmt + ipmt``
+ References
+ ----------
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+
Examples
--------
What is the amortization schedule for a 1 year loan of $2500 at
@@ -422,6 +472,8 @@ def _rbl(rate, per, pmt, pv, when):
def _ppmt_dispatcher(rate, per, nper, pv, fv=None, when=None):
+ warnings.warn(_depmsg.format(name='ppmt'),
+ DeprecationWarning, stacklevel=3)
return (rate, per, nper, pv, fv)
@@ -430,6 +482,12 @@ def ppmt(rate, per, nper, pv, fv=0, when='end'):
"""
Compute the payment against loan principal.
+ .. deprecated:: 1.18
+
+ `ppmt` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
Parameters
----------
rate : array_like
@@ -450,12 +508,19 @@ def ppmt(rate, per, nper, pv, fv=0, when='end'):
--------
pmt, pv, ipmt
+ References
+ ----------
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+
"""
total = pmt(rate, nper, pv, fv, when)
return total - ipmt(rate, per, nper, pv, fv, when)
def _pv_dispatcher(rate, nper, pmt, fv=None, when=None):
+ warnings.warn(_depmsg.format(name='pv'),
+ DeprecationWarning, stacklevel=3)
return (rate, nper, nper, pv, fv)
@@ -464,6 +529,12 @@ def pv(rate, nper, pmt, fv=0, when='end'):
"""
Compute the present value.
+ .. deprecated:: 1.18
+
+ `pv` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
Given:
* a future value, `fv`
* an interest `rate` compounded once per period, of which
@@ -510,7 +581,9 @@ def pv(rate, nper, pmt, fv=0, when='end'):
References
----------
- .. [WRW] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+ .. [2] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
Open Document Format for Office Applications (OpenDocument)v1.2,
Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
Pre-Draft 12. Organization for the Advancement of Structured Information
@@ -567,6 +640,8 @@ def _g_div_gp(r, n, p, x, y, w):
def _rate_dispatcher(nper, pmt, pv, fv, when=None, guess=None, tol=None,
maxiter=None):
+ warnings.warn(_depmsg.format(name='rate'),
+ DeprecationWarning, stacklevel=3)
return (nper, pmt, pv, fv)
@@ -582,6 +657,12 @@ def rate(nper, pmt, pv, fv, when='end', guess=None, tol=None, maxiter=100):
"""
Compute the rate of interest per period.
+ .. deprecated:: 1.18
+
+ `rate` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
Parameters
----------
nper : array_like
@@ -612,13 +693,16 @@ def rate(nper, pmt, pv, fv, when='end', guess=None, tol=None, maxiter=100):
References
----------
- Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May). Open Document
- Format for Office Applications (OpenDocument)v1.2, Part 2: Recalculated
- Formula (OpenFormula) Format - Annotated Version, Pre-Draft 12.
- Organization for the Advancement of Structured Information Standards
- (OASIS). Billerica, MA, USA. [ODT Document]. Available:
- http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
- OpenDocument-formula-20090508.odt
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+ .. [2] Wheeler, D. A., E. Rathke, and R. Weir (Eds.) (2009, May).
+ Open Document Format for Office Applications (OpenDocument)v1.2,
+ Part 2: Recalculated Formula (OpenFormula) Format - Annotated Version,
+ Pre-Draft 12. Organization for the Advancement of Structured Information
+ Standards (OASIS). Billerica, MA, USA. [ODT Document].
+ Available:
+ http://www.oasis-open.org/committees/documents.php?wg_abbrev=office-formula
+ OpenDocument-formula-20090508.odt
"""
when = _convert_when(when)
@@ -651,6 +735,8 @@ def rate(nper, pmt, pv, fv, when='end', guess=None, tol=None, maxiter=100):
def _irr_dispatcher(values):
+ warnings.warn(_depmsg.format(name='irr'),
+ DeprecationWarning, stacklevel=3)
return (values,)
@@ -659,6 +745,12 @@ def irr(values):
"""
Return the Internal Rate of Return (IRR).
+ .. deprecated:: 1.18
+
+ `irr` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
This is the "average" periodically compounded rate of return
that gives a net present value of 0.0; for a more complete explanation,
see Notes below.
@@ -693,13 +785,15 @@ def irr(values):
+ \\frac{55}{(1+r)^3} + \\frac{20}{(1+r)^4} = 0
In general, for `values` :math:`= [v_0, v_1, ... v_M]`,
- irr is the solution of the equation: [G]_
+ irr is the solution of the equation: [2]_
.. math:: \\sum_{t=0}^M{\\frac{v_t}{(1+irr)^{t}}} = 0
References
----------
- .. [G] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+ .. [2] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
Addison-Wesley, 2003, pg. 348.
Examples
@@ -734,6 +828,8 @@ def irr(values):
def _npv_dispatcher(rate, values):
+ warnings.warn(_depmsg.format(name='npv'),
+ DeprecationWarning, stacklevel=3)
return (values,)
@@ -742,6 +838,12 @@ def npv(rate, values):
"""
Returns the NPV (Net Present Value) of a cash flow series.
+ .. deprecated:: 1.18
+
+ `npv` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
Parameters
----------
rate : scalar
@@ -772,13 +874,15 @@ def npv(rate, values):
Notes
-----
- Returns the result of: [G]_
+ Returns the result of: [2]_
.. math :: \\sum_{t=0}^{M-1}{\\frac{values_t}{(1+rate)^{t}}}
References
----------
- .. [G] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
+ .. [2] L. J. Gitman, "Principles of Managerial Finance, Brief," 3rd ed.,
Addison-Wesley, 2003, pg. 346.
Examples
@@ -808,6 +912,8 @@ def npv(rate, values):
def _mirr_dispatcher(values, finance_rate, reinvest_rate):
+ warnings.warn(_depmsg.format(name='mirr'),
+ DeprecationWarning, stacklevel=3)
return (values,)
@@ -816,6 +922,12 @@ def mirr(values, finance_rate, reinvest_rate):
"""
Modified internal rate of return.
+ .. deprecated:: 1.18
+
+ `mirr` is deprecated; for details, see NEP 32 [1]_.
+ Use the corresponding function in the numpy-financial library,
+ https://pypi.org/project/numpy-financial.
+
Parameters
----------
values : array_like
@@ -832,6 +944,10 @@ def mirr(values, finance_rate, reinvest_rate):
out : float
Modified internal rate of return
+ References
+ ----------
+ .. [1] NumPy Enhancement Proposal (NEP) 32,
+ https://numpy.org/neps/nep-0032-remove-financial-functions.html
"""
values = np.asarray(values)
n = values.size
diff --git a/numpy/lib/format.py b/numpy/lib/format.py
index 1ecd72815..2afa4ac10 100644
--- a/numpy/lib/format.py
+++ b/numpy/lib/format.py
@@ -161,15 +161,12 @@ alternatives, is described in the `"npy-format" NEP
evolved with time and this document is more current.
"""
-from __future__ import division, absolute_import, print_function
-
import numpy
-import sys
import io
import warnings
from numpy.lib.utils import safe_eval
from numpy.compat import (
- isfileobj, long, os_fspath, pickle
+ isfileobj, os_fspath, pickle
)
@@ -215,10 +212,7 @@ def magic(major, minor):
raise ValueError("major version must be 0 <= major < 256")
if minor < 0 or minor > 255:
raise ValueError("minor version must be 0 <= minor < 256")
- if sys.version_info[0] < 3:
- return MAGIC_PREFIX + chr(major) + chr(minor)
- else:
- return MAGIC_PREFIX + bytes([major, minor])
+ return MAGIC_PREFIX + bytes([major, minor])
def read_magic(fp):
""" Read the magic string to get the version of the file format.
@@ -236,12 +230,19 @@ def read_magic(fp):
if magic_str[:-2] != MAGIC_PREFIX:
msg = "the magic string is not correct; expected %r, got %r"
raise ValueError(msg % (MAGIC_PREFIX, magic_str[:-2]))
- if sys.version_info[0] < 3:
- major, minor = map(ord, magic_str[-2:])
- else:
- major, minor = magic_str[-2:]
+ major, minor = magic_str[-2:]
return major, minor
+def _has_metadata(dt):
+ if dt.metadata is not None:
+ return True
+ elif dt.names is not None:
+ return any(_has_metadata(dt[k]) for k in dt.names)
+ elif dt.subdtype is not None:
+ return _has_metadata(dt.base)
+ else:
+ return False
+
def dtype_to_descr(dtype):
"""
Get a serializable descriptor from the dtype.
@@ -265,6 +266,10 @@ def dtype_to_descr(dtype):
replicate the input dtype.
"""
+ if _has_metadata(dtype):
+ warnings.warn("metadata on a dtype may be saved or ignored, but will "
+ "raise if saved when read. Use another form of storage.",
+ UserWarning, stacklevel=2)
if dtype.names is not None:
# This is a record array. The .descr is fine. XXX: parts of the
# record array with an empty name, like padding bytes, still get
@@ -290,7 +295,11 @@ def descr_to_dtype(descr):
# subtype, will always have a shape descr[1]
dt = descr_to_dtype(descr[0])
return numpy.dtype((dt, descr[1]))
- fields = []
+
+ titles = []
+ names = []
+ formats = []
+ offsets = []
offset = 0
for field in descr:
if len(field) == 2:
@@ -304,14 +313,13 @@ def descr_to_dtype(descr):
# Once support for blank names is removed, only "if name == ''" needed)
is_pad = (name == '' and dt.type is numpy.void and dt.names is None)
if not is_pad:
- fields.append((name, dt, offset))
-
+ title, name = name if isinstance(name, tuple) else (None, name)
+ titles.append(title)
+ names.append(name)
+ formats.append(dt)
+ offsets.append(offset)
offset += dt.itemsize
- names, formats, offsets = zip(*fields)
- # names may be (title, names) tuples
- nametups = (n if isinstance(n, tuple) else (None, n) for n in names)
- titles, names = zip(*nametups)
return numpy.dtype({'names': names, 'formats': formats, 'titles': titles,
'offsets': offsets, 'itemsize': offset})
@@ -530,16 +538,11 @@ def _filter_header(s):
"""
import tokenize
- if sys.version_info[0] >= 3:
- from io import StringIO
- else:
- from StringIO import StringIO
+ from io import StringIO
tokens = []
last_token_was_number = False
- # adding newline as python 2.7.5 workaround
- string = s + "\n"
- for token in tokenize.generate_tokens(StringIO(string).readline):
+ for token in tokenize.generate_tokens(StringIO(s).readline):
token_type = token[0]
token_string = token[1]
if (last_token_was_number and
@@ -549,8 +552,7 @@ def _filter_header(s):
else:
tokens.append(token)
last_token_was_number = (token_type == tokenize.NUMBER)
- # removing newline (see above) as python 2.7.5 workaround
- return tokenize.untokenize(tokens)[:-1]
+ return tokenize.untokenize(tokens)
def _read_array_header(fp, version):
@@ -592,7 +594,7 @@ def _read_array_header(fp, version):
# Sanity-check the values.
if (not isinstance(d['shape'], tuple) or
- not numpy.all([isinstance(x, (int, long)) for x in d['shape']])):
+ not numpy.all([isinstance(x, int) for x in d['shape']])):
msg = "shape is not valid: {!r}"
raise ValueError(msg.format(d['shape']))
if not isinstance(d['fortran_order'], bool):
@@ -600,7 +602,7 @@ def _read_array_header(fp, version):
raise ValueError(msg.format(d['fortran_order']))
try:
dtype = descr_to_dtype(d['descr'])
- except TypeError as e:
+ except TypeError:
msg = "descr is not a valid dtype descriptor: {!r}"
raise ValueError(msg.format(d['descr']))
@@ -729,12 +731,10 @@ def read_array(fp, allow_pickle=False, pickle_kwargs=None):
try:
array = pickle.load(fp, **pickle_kwargs)
except UnicodeError as err:
- if sys.version_info[0] >= 3:
- # Friendlier error message
- raise UnicodeError("Unpickling a python object failed: %r\n"
- "You may need to pass the encoding= option "
- "to numpy.load" % (err,))
- raise
+ # Friendlier error message
+ raise UnicodeError("Unpickling a python object failed: %r\n"
+ "You may need to pass the encoding= option "
+ "to numpy.load" % (err,))
else:
if isfileobj(fp):
# We can use the fast fromfile() function.
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index c39c2eea1..bfcf0d316 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -1,11 +1,4 @@
-from __future__ import division, absolute_import, print_function
-
-try:
- # Accessing collections abstract classes from collections
- # has been deprecated since Python 3.3
- import collections.abc as collections_abc
-except ImportError:
- import collections as collections_abc
+import collections.abc
import functools
import re
import sys
@@ -13,10 +6,10 @@ import warnings
import numpy as np
import numpy.core.numeric as _nx
-from numpy.core import atleast_1d, transpose
+from numpy.core import transpose
from numpy.core.numeric import (
ones, zeros, arange, concatenate, array, asarray, asanyarray, empty,
- empty_like, ndarray, around, floor, ceil, take, dot, where, intp,
+ ndarray, around, floor, ceil, take, dot, where, intp,
integer, isscalar, absolute
)
from numpy.core.umath import (
@@ -36,23 +29,17 @@ from numpy.core.multiarray import (
interp as compiled_interp, interp_complex as compiled_interp_complex
)
from numpy.core.umath import _add_newdoc_ufunc as add_newdoc_ufunc
-from numpy.compat import long
-if sys.version_info[0] < 3:
- # Force range to be a generator, for np.delete's usage.
- range = xrange
- import __builtin__ as builtins
-else:
- import builtins
+import builtins
+
+# needed in this module for compatibility
+from numpy.lib.histograms import histogram, histogramdd
array_function_dispatch = functools.partial(
overrides.array_function_dispatch, module='numpy')
-# needed in this module for compatibility
-from numpy.lib.histograms import histogram, histogramdd
-
__all__ = [
'select', 'piecewise', 'trim_zeros', 'copy', 'iterable', 'percentile',
'diff', 'gradient', 'angle', 'unwrap', 'sort_complex', 'disp', 'flip',
@@ -70,7 +57,7 @@ def _rot90_dispatcher(m, k=None, axes=None):
@array_function_dispatch(_rot90_dispatcher)
-def rot90(m, k=1, axes=(0,1)):
+def rot90(m, k=1, axes=(0, 1)):
"""
Rotate an array by 90 degrees in the plane specified by axes.
@@ -150,7 +137,7 @@ def rot90(m, k=1, axes=(0,1)):
axes_list[axes[0]])
if k == 1:
- return transpose(flip(m,axes[1]), axes_list)
+ return transpose(flip(m, axes[1]), axes_list)
else:
# k == 3
return flip(transpose(m, axes_list), axes[1])
@@ -504,8 +491,7 @@ def _piecewise_dispatcher(x, condlist, funclist, *args, **kw):
yield x
# support the undocumented behavior of allowing scalars
if np.iterable(condlist):
- for c in condlist:
- yield c
+ yield from condlist
@array_function_dispatch(_piecewise_dispatcher)
@@ -620,7 +606,7 @@ def piecewise(x, condlist, funclist, *args, **kw):
y = zeros(x.shape, x.dtype)
for k in range(n):
item = funclist[k]
- if not isinstance(item, collections_abc.Callable):
+ if not isinstance(item, collections.abc.Callable):
y[condlist[k]] = item
else:
vals = x[condlist[k]]
@@ -631,10 +617,8 @@ def piecewise(x, condlist, funclist, *args, **kw):
def _select_dispatcher(condlist, choicelist, default=None):
- for c in condlist:
- yield c
- for c in choicelist:
- yield c
+ yield from condlist
+ yield from choicelist
@array_function_dispatch(_select_dispatcher)
@@ -723,12 +707,12 @@ def select(condlist, choicelist, default=0):
return result
-def _copy_dispatcher(a, order=None):
+def _copy_dispatcher(a, order=None, subok=None):
return (a,)
@array_function_dispatch(_copy_dispatcher)
-def copy(a, order='K'):
+def copy(a, order='K', subok=False):
"""
Return an array copy of the given object.
@@ -743,12 +727,21 @@ def copy(a, order='K'):
as possible. (Note that this function and :meth:`ndarray.copy` are very
similar, but have different default values for their order=
arguments.)
+ subok : bool, optional
+ If True, then sub-classes will be passed-through, otherwise the
+ returned array will be forced to be a base-class array (defaults to False).
+
+ .. versionadded:: 1.19.0
Returns
-------
arr : ndarray
Array interpretation of `a`.
+ See Also
+ --------
+ ndarray.copy : Preferred method for creating an array copy
+
Notes
-----
This is equivalent to:
@@ -772,19 +765,18 @@ def copy(a, order='K'):
False
"""
- return array(a, order=order, copy=True)
+ return array(a, order=order, subok=subok, copy=True)
# Basic operations
-def _gradient_dispatcher(f, *varargs, **kwargs):
+def _gradient_dispatcher(f, *varargs, axis=None, edge_order=None):
yield f
- for v in varargs:
- yield v
+ yield from varargs
@array_function_dispatch(_gradient_dispatcher)
-def gradient(f, *varargs, **kwargs):
+def gradient(f, *varargs, axis=None, edge_order=1):
"""
Return the gradient of an N-dimensional array.
@@ -961,11 +953,10 @@ def gradient(f, *varargs, **kwargs):
f = np.asanyarray(f)
N = f.ndim # number of dimensions
- axes = kwargs.pop('axis', None)
- if axes is None:
+ if axis is None:
axes = tuple(range(N))
else:
- axes = _nx.normalize_axis_tuple(axes, N)
+ axes = _nx.normalize_axis_tuple(axis, N)
len_axes = len(axes)
n = len(varargs)
@@ -979,13 +970,18 @@ def gradient(f, *varargs, **kwargs):
# scalar or 1d array for each axis
dx = list(varargs)
for i, distances in enumerate(dx):
- if np.ndim(distances) == 0:
+ distances = np.asanyarray(distances)
+ if distances.ndim == 0:
continue
- elif np.ndim(distances) != 1:
+ elif distances.ndim != 1:
raise ValueError("distances must be either scalars or 1d")
if len(distances) != f.shape[axes[i]]:
raise ValueError("when 1d, distances must match "
"the length of the corresponding dimension")
+ if np.issubdtype(distances.dtype, np.integer):
+ # Convert numpy integer types to float64 to avoid modular
+ # arithmetic in np.diff(distances).
+ distances = distances.astype(np.float64)
diffx = np.diff(distances)
# if distances are constant reduce to the scalar case
# since it brings a consistent speedup
@@ -995,10 +991,6 @@ def gradient(f, *varargs, **kwargs):
else:
raise TypeError("invalid number of arguments")
- edge_order = kwargs.pop('edge_order', 1)
- if kwargs:
- raise TypeError('"{}" are not valid keyword arguments.'.format(
- '", "'.join(kwargs.keys())))
if edge_order > 2:
raise ValueError("'edge_order' greater than 2 not supported")
@@ -1024,8 +1016,12 @@ def gradient(f, *varargs, **kwargs):
elif np.issubdtype(otype, np.inexact):
pass
else:
- # all other types convert to floating point
- otype = np.double
+ # All other types convert to floating point.
+ # First check if f is a numpy integer type; if so, convert f to float64
+ # to avoid modular arithmetic when computing the changes in f.
+ if np.issubdtype(otype, np.integer):
+ f = f.astype(np.float64)
+ otype = np.float64
for axis, ax_dx in zip(axes, dx):
if f.shape[axis] < edge_order + 1:
@@ -1612,6 +1608,7 @@ def trim_zeros(filt, trim='fb'):
last = last - 1
return filt[first:last]
+
def _extract_dispatcher(condition, arr):
return (condition, arr)
@@ -1867,7 +1864,7 @@ def _create_arrays(broadcast_shape, dim_sizes, list_of_core_dims, dtypes):
@set_module('numpy')
-class vectorize(object):
+class vectorize:
"""
vectorize(pyfunc, otypes=None, doc=None, excluded=None, cache=False,
signature=None)
@@ -1893,7 +1890,7 @@ class vectorize(object):
typecode characters or a list of data type specifiers. There should
be one data type specifier for each output.
doc : str, optional
- The docstring for the function. If `None`, the docstring will be the
+ The docstring for the function. If None, the docstring will be the
``pyfunc.__doc__``.
excluded : set, optional
Set of strings or integers representing the positional or keyword
@@ -2305,7 +2302,7 @@ def cov(m, y=None, rowvar=True, bias=False, ddof=None, fweights=None,
>>> m = np.arange(10, dtype=np.float64)
>>> f = np.arange(10) * 2
>>> a = np.arange(10) ** 2.
- >>> ddof = 9 # N - 1
+ >>> ddof = 1
>>> w = f * a
>>> v1 = np.sum(w)
>>> v2 = np.sum(w * a)
@@ -2947,6 +2944,7 @@ def hamming(M):
n = arange(0, M)
return 0.54 - 0.46*cos(2.0*pi*n/(M-1))
+
## Code from cephes for i0
_i0A = [
@@ -3489,6 +3487,7 @@ def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
else:
return r
+
def _median(a, axis=None, out=None, overwrite_input=False):
# can't be reasonably be implemented in terms of percentile as we have to
# call mean to not break astropy
@@ -3707,7 +3706,7 @@ def quantile(a, q, axis=None, out=None,
overwrite_input=False, interpolation='linear', keepdims=False):
"""
Compute the q-th quantile of the data along the specified axis.
-
+
.. versionadded:: 1.15.0
Parameters
@@ -3878,8 +3877,8 @@ def _quantile_ureduce_func(a, q, axis=None, out=None, overwrite_input=False,
"interpolation can only be 'linear', 'lower' 'higher', "
"'midpoint', or 'nearest'")
- n = np.array(False, dtype=bool) # check for nan's flag
- if indices.dtype == intp: # take the points along axis
+ n = np.array(False, dtype=bool) # check for nan's flag
+ if np.issubdtype(indices.dtype, np.integer): # take the points along axis
# Check if the array contains any nan's
if np.issubdtype(a.dtype, np.inexact):
indices = concatenate((indices, [-1]))
@@ -3898,7 +3897,6 @@ def _quantile_ureduce_func(a, q, axis=None, out=None, overwrite_input=False,
indices = indices[0]
r = take(ap, indices, axis=axis, out=out)
-
else: # weight the points above and below the indices
indices_below = floor(indices).astype(intp)
indices_above = indices_below + 1
@@ -4059,13 +4057,13 @@ def trapz(y, x=None, dx=1.0, axis=-1):
return ret
-def _meshgrid_dispatcher(*xi, **kwargs):
+def _meshgrid_dispatcher(*xi, copy=None, sparse=None, indexing=None):
return xi
# Based on scitools meshgrid
@array_function_dispatch(_meshgrid_dispatcher)
-def meshgrid(*xi, **kwargs):
+def meshgrid(*xi, copy=True, sparse=False, indexing='xy'):
"""
Return coordinate matrices from coordinate vectors.
@@ -4171,14 +4169,6 @@ def meshgrid(*xi, **kwargs):
"""
ndim = len(xi)
- copy_ = kwargs.pop('copy', True)
- sparse = kwargs.pop('sparse', False)
- indexing = kwargs.pop('indexing', 'xy')
-
- if kwargs:
- raise TypeError("meshgrid() got an unexpected keyword argument '%s'"
- % (list(kwargs)[0],))
-
if indexing not in ['xy', 'ij']:
raise ValueError(
"Valid values for `indexing` are 'xy' and 'ij'.")
@@ -4196,7 +4186,7 @@ def meshgrid(*xi, **kwargs):
# Return the full N-D matrix (not only the 1-D vector)
output = np.broadcast_arrays(*output, subok=True)
- if copy_:
+ if copy:
output = [x.copy() for x in output]
return output
@@ -4216,12 +4206,17 @@ def delete(arr, obj, axis=None):
Parameters
----------
arr : array_like
- Input array.
+ Input array.
obj : slice, int or array of ints
- Indicate indices of sub-arrays to remove along the specified axis.
+ Indicate indices of sub-arrays to remove along the specified axis.
+
+ .. versionchanged:: 1.19.0
+ Boolean indices are now treated as a mask of elements to remove,
+ rather than being cast to the integers 0 and 1.
+
axis : int, optional
- The axis along which to delete the subarray defined by `obj`.
- If `axis` is None, `obj` is applied to the flattened array.
+ The axis along which to delete the subarray defined by `obj`.
+ If `axis` is None, `obj` is applied to the flattened array.
Returns
-------
@@ -4279,20 +4274,11 @@ def delete(arr, obj, axis=None):
if axis is None:
if ndim != 1:
arr = arr.ravel()
+ # needed for np.matrix, which is still not 1d after being ravelled
ndim = arr.ndim
- axis = -1
-
- if ndim == 0:
- # 2013-09-24, 1.9
- warnings.warn(
- "in the future the special handling of scalars will be removed "
- "from delete and raise an error", DeprecationWarning, stacklevel=3)
- if wrap:
- return wrap(arr)
- else:
- return arr.copy(order=arrorder)
-
- axis = normalize_axis_index(axis, ndim)
+ axis = ndim - 1
+ else:
+ axis = normalize_axis_index(axis, ndim)
slobj = [slice(None)]*ndim
N = arr.shape[axis]
@@ -4348,18 +4334,8 @@ def delete(arr, obj, axis=None):
else:
return new
- _obj = obj
- obj = np.asarray(obj)
- # After removing the special handling of booleans and out of
- # bounds values, the conversion to the array can be removed.
- if obj.dtype == bool:
- warnings.warn("in the future insert will treat boolean arrays and "
- "array-likes as boolean index instead of casting it "
- "to integer", FutureWarning, stacklevel=3)
- obj = obj.astype(intp)
- if isinstance(_obj, (int, long, integer)):
+ if isinstance(obj, (int, integer)) and not isinstance(obj, bool):
# optimization for a single value
- obj = obj.item()
if (obj < -N or obj >= N):
raise IndexError(
"index %i is out of bounds for axis %i with "
@@ -4375,35 +4351,23 @@ def delete(arr, obj, axis=None):
slobj2[axis] = slice(obj+1, None)
new[tuple(slobj)] = arr[tuple(slobj2)]
else:
+ _obj = obj
+ obj = np.asarray(obj)
if obj.size == 0 and not isinstance(_obj, np.ndarray):
obj = obj.astype(intp)
- if not np.can_cast(obj, intp, 'same_kind'):
- # obj.size = 1 special case always failed and would just
- # give superfluous warnings.
- # 2013-09-24, 1.9
- warnings.warn(
- "using a non-integer array as obj in delete will result in an "
- "error in the future", DeprecationWarning, stacklevel=3)
- obj = obj.astype(intp)
- keep = ones(N, dtype=bool)
- # Test if there are out of bound indices, this is deprecated
- inside_bounds = (obj < N) & (obj >= -N)
- if not inside_bounds.all():
- # 2013-09-24, 1.9
- warnings.warn(
- "in the future out of bounds indices will raise an error "
- "instead of being ignored by `numpy.delete`.",
- DeprecationWarning, stacklevel=3)
- obj = obj[inside_bounds]
- positive_indices = obj >= 0
- if not positive_indices.all():
- warnings.warn(
- "in the future negative indices will not be ignored by "
- "`numpy.delete`.", FutureWarning, stacklevel=3)
- obj = obj[positive_indices]
+ if obj.dtype == bool:
+ if obj.shape != (N,):
+ raise ValueError('boolean array argument obj to delete '
+ 'must be one dimensional and match the axis '
+ 'length of {}'.format(N))
+
+ # optimization, the other branch is slower
+ keep = ~obj
+ else:
+ keep = ones(N, dtype=bool)
+ keep[obj,] = False
- keep[obj, ] = False
slobj[axis] = keep
new = arr[tuple(slobj)]
@@ -4519,19 +4483,9 @@ def insert(arr, obj, values, axis=None):
if axis is None:
if ndim != 1:
arr = arr.ravel()
+ # needed for np.matrix, which is still not 1d after being ravelled
ndim = arr.ndim
axis = ndim - 1
- elif ndim == 0:
- # 2013-09-24, 1.9
- warnings.warn(
- "in the future the special handling of scalars will be removed "
- "from insert and raise an error", DeprecationWarning, stacklevel=3)
- arr = arr.copy(order=arrorder)
- arr[...] = values
- if wrap:
- return wrap(arr)
- else:
- return arr
else:
axis = normalize_axis_index(axis, ndim)
slobj = [slice(None)]*ndim
@@ -4540,12 +4494,13 @@ def insert(arr, obj, values, axis=None):
if isinstance(obj, slice):
# turn it into a range object
- indices = arange(*obj.indices(N), **{'dtype': intp})
+ indices = arange(*obj.indices(N), dtype=intp)
else:
# need to copy obj, because indices will be changed in-place
indices = np.array(obj)
if indices.dtype == bool:
# See also delete
+ # 2012-10-11, NumPy 1.8
warnings.warn(
"in the future insert will treat boolean arrays and "
"array-likes as a boolean index instead of casting it to "
@@ -4595,13 +4550,6 @@ def insert(arr, obj, values, axis=None):
# Can safely cast the empty list to intp
indices = indices.astype(intp)
- if not np.can_cast(indices, intp, 'same_kind'):
- # 2013-09-24, 1.9
- warnings.warn(
- "using a non-integer array as obj in insert will result in an "
- "error in the future", DeprecationWarning, stacklevel=3)
- indices = indices.astype(intp)
-
indices[indices < 0] += N
numnew = len(indices)
@@ -4672,7 +4620,9 @@ def append(arr, values, axis=None):
>>> np.append([[1, 2, 3], [4, 5, 6]], [7, 8, 9], axis=0)
Traceback (most recent call last):
...
- ValueError: all the input arrays must have same number of dimensions
+ ValueError: all the input arrays must have same number of dimensions, but
+ the array at index 0 has 2 dimension(s) and the array at index 1 has 1
+ dimension(s)
"""
arr = asanyarray(arr)
diff --git a/numpy/lib/histograms.py b/numpy/lib/histograms.py
index 8474bd5d3..ede8a26e4 100644
--- a/numpy/lib/histograms.py
+++ b/numpy/lib/histograms.py
@@ -1,15 +1,12 @@
"""
Histogram-related functions
"""
-from __future__ import division, absolute_import, print_function
-
import contextlib
import functools
import operator
import warnings
import numpy as np
-from numpy.compat.py3k import basestring
from numpy.core import overrides
__all__ = ['histogram', 'histogramdd', 'histogram_bin_edges']
@@ -22,6 +19,16 @@ array_function_dispatch = functools.partial(
_range = range
+def _ptp(x):
+ """Peak-to-peak value of x.
+
+ This implementation avoids the problem of signed integer arrays having a
+ peak-to-peak value that cannot be represented with the array's data type.
+ This function returns an unsigned value for signed integer arrays.
+ """
+ return _unsigned_subtract(x.max(), x.min())
+
+
def _hist_bin_sqrt(x, range):
"""
Square root histogram bin estimator.
@@ -40,7 +47,7 @@ def _hist_bin_sqrt(x, range):
h : An estimate of the optimal bin width for the given data.
"""
del range # unused
- return x.ptp() / np.sqrt(x.size)
+ return _ptp(x) / np.sqrt(x.size)
def _hist_bin_sturges(x, range):
@@ -63,7 +70,7 @@ def _hist_bin_sturges(x, range):
h : An estimate of the optimal bin width for the given data.
"""
del range # unused
- return x.ptp() / (np.log2(x.size) + 1.0)
+ return _ptp(x) / (np.log2(x.size) + 1.0)
def _hist_bin_rice(x, range):
@@ -87,7 +94,7 @@ def _hist_bin_rice(x, range):
h : An estimate of the optimal bin width for the given data.
"""
del range # unused
- return x.ptp() / (2.0 * x.size ** (1.0 / 3))
+ return _ptp(x) / (2.0 * x.size ** (1.0 / 3))
def _hist_bin_scott(x, range):
@@ -137,7 +144,7 @@ def _hist_bin_stone(x, range):
"""
n = x.size
- ptp_x = np.ptp(x)
+ ptp_x = _ptp(x)
if n <= 1 or ptp_x == 0:
return 0
@@ -184,7 +191,7 @@ def _hist_bin_doane(x, range):
np.true_divide(temp, sigma, temp)
np.power(temp, 3, temp)
g1 = np.mean(temp)
- return x.ptp() / (1.0 + np.log2(x.size) +
+ return _ptp(x) / (1.0 + np.log2(x.size) +
np.log2(1.0 + np.absolute(g1) / sg1))
return 0.0
@@ -200,7 +207,7 @@ def _hist_bin_fd(x, range):
than the standard deviation, so it is less accurate, especially for
long tailed distributions.
- If the IQR is 0, this function returns 1 for the number of bins.
+ If the IQR is 0, this function returns 0 for the bin width.
Binwidth is inversely proportional to the cube root of data size
(asymptotically optimal).
@@ -222,21 +229,21 @@ def _hist_bin_fd(x, range):
def _hist_bin_auto(x, range):
"""
Histogram bin estimator that uses the minimum width of the
- Freedman-Diaconis and Sturges estimators if the FD bandwidth is non zero
- and the Sturges estimator if the FD bandwidth is 0.
+ Freedman-Diaconis and Sturges estimators if the FD bin width is non-zero.
+ If the bin width from the FD estimator is 0, the Sturges estimator is used.
The FD estimator is usually the most robust method, but its width
estimate tends to be too large for small `x` and bad for data with limited
variance. The Sturges estimator is quite good for small (<1000) datasets
- and is the default in the R language. This method gives good off the shelf
+ and is the default in the R language. This method gives good off-the-shelf
behaviour.
.. versionchanged:: 1.15.0
If there is limited variance the IQR can be 0, which results in the
FD bin width being 0 too. This is not a valid bin width, so
``np.histogram_bin_edges`` chooses 1 bin instead, which may not be optimal.
- If the IQR is 0, it's unlikely any variance based estimators will be of
- use, so we revert to the sturges estimator, which only uses the size of the
+ If the IQR is 0, it's unlikely any variance-based estimators will be of
+ use, so we revert to the Sturges estimator, which only uses the size of the
dataset in its calculation.
Parameters
@@ -375,7 +382,7 @@ def _get_bin_edges(a, bins, range, weights):
n_equal_bins = None
bin_edges = None
- if isinstance(bins, basestring):
+ if isinstance(bins, str):
bin_name = bins
# if `bins` is a string for an automatic method,
# this will replace it with the number of bins calculated
@@ -946,9 +953,9 @@ def histogramdd(sample, bins=10, range=None, normed=None, weights=None,
Note the unusual interpretation of sample when an array_like:
* When an array, each row is a coordinate in a D-dimensional space -
- such as ``histogramgramdd(np.array([p1, p2, p3]))``.
+ such as ``histogramdd(np.array([p1, p2, p3]))``.
* When an array_like, each element is the list of values for single
- coordinate - such as ``histogramgramdd((X, Y, Z))``.
+ coordinate - such as ``histogramdd((X, Y, Z))``.
The first form should be preferred.
diff --git a/numpy/lib/index_tricks.py b/numpy/lib/index_tricks.py
index 04384854c..b4118814d 100644
--- a/numpy/lib/index_tricks.py
+++ b/numpy/lib/index_tricks.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import functools
import sys
import math
@@ -107,7 +105,7 @@ def ix_(*args):
out.append(new)
return tuple(out)
-class nd_grid(object):
+class nd_grid:
"""
Construct a multi-dimensional "meshgrid".
@@ -299,7 +297,7 @@ class OGridClass(nd_grid):
ogrid = OGridClass()
-class AxisConcatenator(object):
+class AxisConcatenator:
"""
Translates slice objects to concatenation along an axis.
@@ -552,7 +550,7 @@ c_ = CClass()
@set_module('numpy')
-class ndenumerate(object):
+class ndenumerate:
"""
Multidimensional index iterator.
@@ -599,11 +597,9 @@ class ndenumerate(object):
def __iter__(self):
return self
- next = __next__
-
@set_module('numpy')
-class ndindex(object):
+class ndindex:
"""
An N-dimensional iterator object to index arrays.
@@ -667,8 +663,6 @@ class ndindex(object):
next(self._it)
return self._it.multi_index
- next = __next__
-
# You can do all this with slice() plus a few special objects,
# but there's a lot to remember. This version is simpler because
@@ -681,7 +675,7 @@ class ndindex(object):
#
#
-class IndexExpression(object):
+class IndexExpression:
"""
A nicer way to build up index tuples for arrays.
diff --git a/numpy/lib/mixins.py b/numpy/lib/mixins.py
index f974a7724..50157069c 100644
--- a/numpy/lib/mixins.py
+++ b/numpy/lib/mixins.py
@@ -1,8 +1,4 @@
"""Mixin classes for custom array types that don't inherit from ndarray."""
-from __future__ import division, absolute_import, print_function
-
-import sys
-
from numpy.core import umath as um
@@ -60,7 +56,7 @@ def _unary_method(ufunc, name):
return func
-class NDArrayOperatorsMixin(object):
+class NDArrayOperatorsMixin:
"""Mixin defining all operator special methods using __array_ufunc__.
This class implements the special methods for almost all of Python's
@@ -154,9 +150,7 @@ class NDArrayOperatorsMixin(object):
__mul__, __rmul__, __imul__ = _numeric_methods(um.multiply, 'mul')
__matmul__, __rmatmul__, __imatmul__ = _numeric_methods(
um.matmul, 'matmul')
- if sys.version_info.major < 3:
- # Python 3 uses only __truediv__ and __floordiv__
- __div__, __rdiv__, __idiv__ = _numeric_methods(um.divide, 'div')
+ # Python 3 does not use __div__, __rdiv__, or __idiv__
__truediv__, __rtruediv__, __itruediv__ = _numeric_methods(
um.true_divide, 'truediv')
__floordiv__, __rfloordiv__, __ifloordiv__ = _numeric_methods(
diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py
index 6cffab6ac..003550432 100644
--- a/numpy/lib/nanfunctions.py
+++ b/numpy/lib/nanfunctions.py
@@ -20,8 +20,6 @@ Functions
- `nanpercentile` -- qth percentile of non-NaN values
"""
-from __future__ import division, absolute_import, print_function
-
import functools
import warnings
import numpy as np
@@ -95,17 +93,18 @@ def _replace_nan(a, val):
NaNs, otherwise return None.
"""
- a = np.array(a, subok=True, copy=True)
+ a = np.asanyarray(a)
if a.dtype == np.object_:
# object arrays do not support `isnan` (gh-9009), so make a guess
- mask = a != a
+ mask = np.not_equal(a, a, dtype=bool)
elif issubclass(a.dtype.type, np.inexact):
mask = np.isnan(a)
else:
mask = None
if mask is not None:
+ a = np.array(a, subok=True, copy=True)
np.copyto(a, val, where=mask)
return a, mask
@@ -244,8 +243,8 @@ def nanmin(a, axis=None, out=None, keepdims=np._NoValue):
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, but the type will be cast if necessary. See
- `doc.ufuncs` for details.
+ expected output, but the type will be cast if necessary. See
+ `ufuncs-output-type` for more details.
.. versionadded:: 1.8.0
keepdims : bool, optional
@@ -359,8 +358,8 @@ def nanmax(a, axis=None, out=None, keepdims=np._NoValue):
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, but the type will be cast if necessary. See
- `doc.ufuncs` for details.
+ expected output, but the type will be cast if necessary. See
+ `ufuncs-output-type` for more details.
.. versionadded:: 1.8.0
keepdims : bool, optional
@@ -585,8 +584,8 @@ def nansum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
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, but the type will be cast if necessary. See
- `doc.ufuncs` for details. The casting of NaN to integer can yield
- unexpected results.
+ `ufuncs-output-type` for more details. The casting of NaN to integer
+ can yield unexpected results.
.. versionadded:: 1.8.0
keepdims : bool, optional
@@ -681,9 +680,9 @@ def nanprod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
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, but the type will be cast if necessary. See
- `doc.ufuncs` for details. The casting of NaN to integer can yield
- unexpected results.
+ expected output, but the type will be cast if necessary. See
+ `ufuncs-output-type` for more details. The casting of NaN to integer
+ can yield unexpected results.
keepdims : bool, optional
If True, the axes which are reduced are left in the result as
dimensions with size one. With this option, the result will
@@ -750,8 +749,8 @@ def nancumsum(a, axis=None, dtype=None, out=None):
out : ndarray, optional
Alternative output array in which to place the result. It must
have the same shape and buffer length as the expected output
- but the type will be cast if necessary. See `doc.ufuncs`
- (Section "Output arguments") for more details.
+ but the type will be cast if necessary. See `ufuncs-output-type` for
+ more details.
Returns
-------
@@ -888,8 +887,8 @@ def nanmean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
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, but the type will be cast if necessary. See
- `doc.ufuncs` for details.
+ expected output, but the type will be cast if necessary. See
+ `ufuncs-output-type` for more details.
keepdims : bool, optional
If this is set to True, the axes which are reduced are left
in the result as dimensions with size one. With this option,
@@ -1473,7 +1472,7 @@ def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue):
mean : Average
var : Variance while not ignoring NaNs
nanstd, nanmean
- numpy.doc.ufuncs : Section "Output arguments"
+ ufuncs-output-type
Notes
-----
@@ -1625,7 +1624,7 @@ def nanstd(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue):
--------
var, mean, std
nanvar, nanmean
- numpy.doc.ufuncs : Section "Output arguments"
+ ufuncs-output-type
Notes
-----
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py
index e57a6dd47..0db2e6897 100644
--- a/numpy/lib/npyio.py
+++ b/numpy/lib/npyio.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import sys
import os
import re
@@ -9,6 +7,7 @@ import warnings
import weakref
import contextlib
from operator import itemgetter, index as opindex
+from collections.abc import Mapping
import numpy as np
from . import format
@@ -24,16 +23,10 @@ from ._iotools import (
)
from numpy.compat import (
- asbytes, asstr, asunicode, bytes, basestring, os_fspath, os_PathLike,
+ asbytes, asstr, asunicode, bytes, os_fspath, os_PathLike,
pickle, contextlib_nullcontext
)
-if sys.version_info[0] >= 3:
- from collections.abc import Mapping
-else:
- from future_builtins import map
- from collections import Mapping
-
@set_module('numpy')
def loads(*args, **kwargs):
@@ -55,7 +48,7 @@ array_function_dispatch = functools.partial(
overrides.array_function_dispatch, module='numpy')
-class BagObj(object):
+class BagObj:
"""
BagObj(obj)
@@ -69,7 +62,7 @@ class BagObj(object):
Examples
--------
>>> from numpy.lib.npyio import BagObj as BO
- >>> class BagDemo(object):
+ >>> class BagDemo:
... def __getitem__(self, key): # An instance of BagObj(BagDemo)
... # will call this method when any
... # attribute look-up is required
@@ -266,26 +259,25 @@ class NpzFile(Mapping):
raise KeyError("%s is not a file in the archive" % key)
- if sys.version_info.major == 3:
- # deprecate the python 2 dict apis that we supported by accident in
- # python 3. We forgot to implement itervalues() at all in earlier
- # versions of numpy, so no need to deprecated it here.
+ # deprecate the python 2 dict apis that we supported by accident in
+ # python 3. We forgot to implement itervalues() at all in earlier
+ # versions of numpy, so no need to deprecated it here.
- def iteritems(self):
- # Numpy 1.15, 2018-02-20
- warnings.warn(
- "NpzFile.iteritems is deprecated in python 3, to match the "
- "removal of dict.itertems. Use .items() instead.",
- DeprecationWarning, stacklevel=2)
- return self.items()
+ def iteritems(self):
+ # Numpy 1.15, 2018-02-20
+ warnings.warn(
+ "NpzFile.iteritems is deprecated in python 3, to match the "
+ "removal of dict.itertems. Use .items() instead.",
+ DeprecationWarning, stacklevel=2)
+ return self.items()
- def iterkeys(self):
- # Numpy 1.15, 2018-02-20
- warnings.warn(
- "NpzFile.iterkeys is deprecated in python 3, to match the "
- "removal of dict.iterkeys. Use .keys() instead.",
- DeprecationWarning, stacklevel=2)
- return self.keys()
+ def iterkeys(self):
+ # Numpy 1.15, 2018-02-20
+ warnings.warn(
+ "NpzFile.iterkeys is deprecated in python 3, to match the "
+ "removal of dict.iterkeys. Use .keys() instead.",
+ DeprecationWarning, stacklevel=2)
+ return self.keys()
@set_module('numpy')
@@ -414,21 +406,16 @@ def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,
# result can similarly silently corrupt numerical data.
raise ValueError("encoding must be 'ASCII', 'latin1', or 'bytes'")
- if sys.version_info[0] >= 3:
- pickle_kwargs = dict(encoding=encoding, fix_imports=fix_imports)
- else:
- # Nothing to do on Python 2
- pickle_kwargs = {}
+ pickle_kwargs = dict(encoding=encoding, fix_imports=fix_imports)
- # TODO: Use contextlib.ExitStack once we drop Python 2
- if hasattr(file, 'read'):
- fid = file
- own_fid = False
- else:
- fid = open(os_fspath(file), "rb")
- own_fid = True
+ with contextlib.ExitStack() as stack:
+ if hasattr(file, 'read'):
+ fid = file
+ own_fid = False
+ else:
+ fid = stack.enter_context(open(os_fspath(file), "rb"))
+ own_fid = True
- try:
# Code to distinguish from NumPy binary files and pickles.
_ZIP_PREFIX = b'PK\x03\x04'
_ZIP_SUFFIX = b'PK\x05\x06' # empty zip files start with this
@@ -439,10 +426,10 @@ def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,
fid.seek(-min(N, len(magic)), 1) # back-up
if magic.startswith(_ZIP_PREFIX) or magic.startswith(_ZIP_SUFFIX):
# zip-file (assume .npz)
- # Transfer file ownership to NpzFile
+ # Potentially transfer file ownership to NpzFile
+ stack.pop_all()
ret = NpzFile(fid, own_fid=own_fid, allow_pickle=allow_pickle,
pickle_kwargs=pickle_kwargs)
- own_fid = False
return ret
elif magic == format.MAGIC_PREFIX:
# .npy file
@@ -461,9 +448,6 @@ def load(file, mmap_mode=None, allow_pickle=False, fix_imports=True,
except Exception:
raise IOError(
"Failed to interpret file %s as a pickle" % repr(file))
- finally:
- if own_fid:
- fid.close()
def _save_dispatcher(file, arr, allow_pickle=None, fix_imports=None):
@@ -480,7 +464,7 @@ def save(file, arr, allow_pickle=True, fix_imports=True):
file : file, str, or pathlib.Path
File or filename to which the data is saved. If file is a file-object,
then the filename is unchanged. If file is a string or Path, a ``.npy``
- extension will be appended to the file name if it does not already
+ extension will be appended to the filename if it does not already
have one.
arr : array_like
Array data to be saved.
@@ -506,9 +490,9 @@ def save(file, arr, allow_pickle=True, fix_imports=True):
Notes
-----
For a description of the ``.npy`` format, see :py:mod:`numpy.lib.format`.
-
- Any data saved to the file is appended to the end of the file.
-
+
+ Any data saved to the file is appended to the end of the file.
+
Examples
--------
>>> from tempfile import TemporaryFile
@@ -524,49 +508,35 @@ def save(file, arr, allow_pickle=True, fix_imports=True):
>>> with open('test.npy', 'wb') as f:
... np.save(f, np.array([1, 2]))
- ... np.save(f, np.array([1, 3]))
+ ... np.save(f, np.array([1, 3]))
>>> with open('test.npy', 'rb') as f:
... a = np.load(f)
... b = np.load(f)
>>> print(a, b)
# [1 2] [1 3]
"""
- own_fid = False
if hasattr(file, 'write'):
- fid = file
+ file_ctx = contextlib_nullcontext(file)
else:
file = os_fspath(file)
if not file.endswith('.npy'):
file = file + '.npy'
- fid = open(file, "wb")
- own_fid = True
+ file_ctx = open(file, "wb")
- if sys.version_info[0] >= 3:
- pickle_kwargs = dict(fix_imports=fix_imports)
- else:
- # Nothing to do on Python 2
- pickle_kwargs = None
-
- try:
+ with file_ctx as fid:
arr = np.asanyarray(arr)
format.write_array(fid, arr, allow_pickle=allow_pickle,
- pickle_kwargs=pickle_kwargs)
- finally:
- if own_fid:
- fid.close()
+ pickle_kwargs=dict(fix_imports=fix_imports))
def _savez_dispatcher(file, *args, **kwds):
- for a in args:
- yield a
- for v in kwds.values():
- yield v
+ yield from args
+ yield from kwds.values()
@array_function_dispatch(_savez_dispatcher)
def savez(file, *args, **kwds):
- """
- Save several arrays into a single file in uncompressed ``.npz`` format.
+ """Save several arrays into a single file in uncompressed ``.npz`` format.
If arguments are passed in with no keywords, the corresponding variable
names, in the ``.npz`` file, are 'arr_0', 'arr_1', etc. If keyword
@@ -576,9 +546,9 @@ def savez(file, *args, **kwds):
Parameters
----------
file : str or file
- Either the file name (string) or an open file (file-like object)
+ Either the filename (string) or an open file (file-like object)
where the data will be saved. If file is a string or a Path, the
- ``.npz`` extension will be appended to the file name if it is not
+ ``.npz`` extension will be appended to the filename if it is not
already there.
args : Arguments, optional
Arrays to save to the file. Since it is not possible for Python to
@@ -611,6 +581,10 @@ def savez(file, *args, **kwds):
its list of arrays (with the ``.files`` attribute), and for the arrays
themselves.
+ When saving dictionaries, the dictionary keys become filenames
+ inside the ZIP archive. Therefore, keys should be valid filenames.
+ E.g., avoid keys that begin with ``/`` or contain ``.``.
+
Examples
--------
>>> from tempfile import TemporaryFile
@@ -638,16 +612,13 @@ def savez(file, *args, **kwds):
['x', 'y']
>>> npzfile['x']
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
-
"""
_savez(file, args, kwds, False)
def _savez_compressed_dispatcher(file, *args, **kwds):
- for a in args:
- yield a
- for v in kwds.values():
- yield v
+ yield from args
+ yield from kwds.values()
@array_function_dispatch(_savez_compressed_dispatcher)
@@ -656,15 +627,15 @@ def savez_compressed(file, *args, **kwds):
Save several arrays into a single file in compressed ``.npz`` format.
If keyword arguments are given, then filenames are taken from the keywords.
- If arguments are passed in with no keywords, then stored file names are
+ If arguments are passed in with no keywords, then stored filenames are
arr_0, arr_1, etc.
Parameters
----------
file : str or file
- Either the file name (string) or an open file (file-like object)
+ Either the filename (string) or an open file (file-like object)
where the data will be saved. If file is a string or a Path, the
- ``.npz`` extension will be appended to the file name if it is not
+ ``.npz`` extension will be appended to the filename if it is not
already there.
args : Arguments, optional
Arrays to save to the file. Since it is not possible for Python to
@@ -691,7 +662,7 @@ def savez_compressed(file, *args, **kwds):
The ``.npz`` file format is a zipped archive of files named after the
variables they contain. The archive is compressed with
``zipfile.ZIP_DEFLATED`` and each file in the archive contains one variable
- in ``.npy`` format. For a description of the ``.npy`` format, see
+ in ``.npy`` format. For a description of the ``.npy`` format, see
:py:mod:`numpy.lib.format`.
@@ -831,7 +802,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
fname : file, str, or pathlib.Path
File, filename, or generator to read. If the filename extension is
``.gz`` or ``.bz2``, the file is first decompressed. Note that
- generators should return byte strings for Python 3k.
+ generators should return byte strings.
dtype : data-type, optional
Data-type of the resulting array; default: float. If this is a
structured data-type, the resulting array will be 1-dimensional, and
@@ -934,7 +905,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
"""
# Type conversions for Py3 convenience
if comments is not None:
- if isinstance(comments, (basestring, bytes)):
+ if isinstance(comments, (str, bytes)):
comments = [comments]
comments = [_decode_line(x) for x in comments]
# Compile regex for comments beforehand
@@ -1334,8 +1305,8 @@ def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='',
fmt = asstr(fmt)
delimiter = asstr(delimiter)
- class WriteWrap(object):
- """Convert to unicode in py2 or to bytes on bytestream inputs.
+ class WriteWrap:
+ """Convert to bytes on bytestream inputs.
"""
def __init__(self, fh, encoding):
@@ -1375,9 +1346,6 @@ def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='',
open(fname, 'wt').close()
fh = np.lib._datasource.open(fname, 'wt', encoding=encoding)
own_fh = True
- # need to convert str to unicode for text io output
- if sys.version_info[0] == 2:
- fh = WriteWrap(fh, encoding or 'latin1')
elif hasattr(fname, 'write'):
# wrap to handle byte output streams
fh = WriteWrap(fname, encoding or 'latin1')
@@ -1410,7 +1378,7 @@ def savetxt(fname, X, fmt='%.18e', delimiter=' ', newline='\n', header='',
if len(fmt) != ncol:
raise AttributeError('fmt has wrong shape. %s' % str(fmt))
format = asstr(delimiter).join(map(asstr, fmt))
- elif isinstance(fmt, basestring):
+ elif isinstance(fmt, str):
n_fmt_chars = fmt.count('%')
error = ValueError('fmt has wrong number of %% formats: %s' % fmt)
if n_fmt_chars == 1:
@@ -1469,7 +1437,7 @@ def fromregex(file, regexp, dtype, encoding=None):
Parameters
----------
file : str or file
- File name or file object to read.
+ Filename or file object to read.
regexp : str or regexp
Regular expression used to parse the file.
Groups in the regular expression correspond to fields in the dtype.
@@ -1527,9 +1495,9 @@ def fromregex(file, regexp, dtype, encoding=None):
dtype = np.dtype(dtype)
content = file.read()
- if isinstance(content, bytes) and isinstance(regexp, np.unicode):
+ if isinstance(content, bytes) and isinstance(regexp, np.compat.unicode):
regexp = asbytes(regexp)
- elif isinstance(content, np.unicode) and isinstance(regexp, bytes):
+ elif isinstance(content, np.compat.unicode) and isinstance(regexp, bytes):
regexp = asstr(regexp)
if not hasattr(regexp, 'match'):
@@ -1576,7 +1544,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
fname : file, str, pathlib.Path, list of str, generator
File, filename, list, or generator to read. If the filename
extension is `.gz` or `.bz2`, the file is first decompressed. Note
- that generators must return byte strings in Python 3k. The strings
+ that generators must return byte strings. The strings
in a list or produced by a generator are treated as lines.
dtype : dtype, optional
Data type of the resulting array.
@@ -1766,7 +1734,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
try:
if isinstance(fname, os_PathLike):
fname = os_fspath(fname)
- if isinstance(fname, basestring):
+ if isinstance(fname, str):
fid = np.lib._datasource.open(fname, 'rt', encoding=encoding)
fid_ctx = contextlib.closing(fid)
else:
@@ -1908,7 +1876,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
if value not in entry:
entry.append(value)
# We have a string : apply it to all entries
- elif isinstance(user_missing_values, basestring):
+ elif isinstance(user_missing_values, str):
user_value = user_missing_values.split(",")
for entry in missing_values:
entry.extend(user_value)
diff --git a/numpy/lib/polynomial.py b/numpy/lib/polynomial.py
index 2c72f623c..5a0fa5431 100644
--- a/numpy/lib/polynomial.py
+++ b/numpy/lib/polynomial.py
@@ -2,8 +2,6 @@
Functions to operate on polynomials.
"""
-from __future__ import division, absolute_import, print_function
-
__all__ = ['poly', 'roots', 'polyint', 'polyder', 'polyadd',
'polysub', 'polymul', 'polydiv', 'polyval', 'poly1d',
'polyfit', 'RankWarning']
@@ -479,10 +477,10 @@ def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
coefficients for `k`-th data set are in ``p[:,k]``.
residuals, rank, singular_values, rcond
- Present only if `full` = True. Residuals of the least-squares fit,
- the effective rank of the scaled Vandermonde coefficient matrix,
- its singular values, and the specified value of `rcond`. For more
- details, see `linalg.lstsq`.
+ Present only if `full` = True. Residuals is sum of squared residuals
+ of the least-squares fit, the effective rank of the scaled Vandermonde
+ coefficient matrix, its singular values, and the specified value of
+ `rcond`. For more details, see `linalg.lstsq`.
V : ndarray, shape (M,M) or (M,M,K)
Present only if `full` = False and `cov`=True. The covariance
@@ -1007,7 +1005,7 @@ def _raise_power(astr, wrap=70):
@set_module('numpy')
-class poly1d(object):
+class poly1d:
"""
A one-dimensional polynomial class.
diff --git a/numpy/lib/recfunctions.py b/numpy/lib/recfunctions.py
index 927161ddb..a11d5f2c7 100644
--- a/numpy/lib/recfunctions.py
+++ b/numpy/lib/recfunctions.py
@@ -5,9 +5,6 @@ Most of these functions were initially implemented by John Hunter for
matplotlib. They have been rewritten and extended for convenience.
"""
-from __future__ import division, absolute_import, print_function
-
-import sys
import itertools
import numpy as np
import numpy.ma as ma
@@ -16,12 +13,8 @@ from numpy.ma import MaskedArray
from numpy.ma.mrecords import MaskedRecords
from numpy.core.overrides import array_function_dispatch
from numpy.lib._iotools import _is_string_like
-from numpy.compat import basestring
from numpy.testing import suppress_warnings
-if sys.version_info[0] < 3:
- from future_builtins import zip
-
_check_fill_value = np.ma.core._check_fill_value
@@ -292,8 +285,7 @@ def _izip_fields_flat(iterable):
"""
for element in iterable:
if isinstance(element, np.void):
- for f in _izip_fields_flat(tuple(element)):
- yield f
+ yield from _izip_fields_flat(tuple(element))
else:
yield element
@@ -305,12 +297,11 @@ def _izip_fields(iterable):
"""
for element in iterable:
if (hasattr(element, '__iter__') and
- not isinstance(element, basestring)):
- for f in _izip_fields(element):
- yield f
+ not isinstance(element, str)):
+ yield from _izip_fields(element)
elif isinstance(element, np.void) and len(tuple(element)) == 1:
- for f in _izip_fields(element):
- yield f
+ # this statement is the same from the previous expression
+ yield from _izip_fields(element)
else:
yield element
@@ -335,12 +326,7 @@ def _izip_records(seqarrays, fill_value=None, flatten=True):
else:
zipfunc = _izip_fields
- if sys.version_info[0] >= 3:
- zip_longest = itertools.zip_longest
- else:
- zip_longest = itertools.izip_longest
-
- for tup in zip_longest(*seqarrays, fillvalue=fill_value):
+ for tup in itertools.zip_longest(*seqarrays, fillvalue=fill_value):
yield tuple(zipfunc(tup))
@@ -438,7 +424,7 @@ def merge_arrays(seqarrays, fill_value=-1, flatten=False,
if seqdtype.names is None:
seqdtype = np.dtype([('', seqdtype)])
if not flatten or _zip_dtype((seqarrays,), flatten=True) == seqdtype:
- # Minimal processing needed: just make sure everythng's a-ok
+ # Minimal processing needed: just make sure everything's a-ok
seqarrays = seqarrays.ravel()
# Find what type of array we must return
if usemask:
@@ -669,8 +655,7 @@ def rename_fields(base, namemapper):
def _append_fields_dispatcher(base, names, data, dtypes=None,
fill_value=None, usemask=None, asrecarray=None):
yield base
- for d in data:
- yield d
+ yield from data
@array_function_dispatch(_append_fields_dispatcher)
@@ -709,7 +694,7 @@ def append_fields(base, names, data, dtypes=None,
if len(names) != len(data):
msg = "The number of arrays does not match the number of names"
raise ValueError(msg)
- elif isinstance(names, basestring):
+ elif isinstance(names, str):
names = [names, ]
data = [data, ]
#
@@ -746,8 +731,7 @@ def append_fields(base, names, data, dtypes=None,
def _rec_append_fields_dispatcher(base, names, data, dtypes=None):
yield base
- for d in data:
- yield d
+ yield from data
@array_function_dispatch(_rec_append_fields_dispatcher)
@@ -1466,7 +1450,7 @@ def join_by(key, r1, r2, jointype='inner', r1postfix='1', r2postfix='2',
"'outer' or 'leftouter' (got '%s' instead)" % jointype
)
# If we have a single key, put it in a tuple
- if isinstance(key, basestring):
+ if isinstance(key, str):
key = (key,)
# Check the keys
diff --git a/numpy/lib/scimath.py b/numpy/lib/scimath.py
index 5ac790ce9..555a3d5a8 100644
--- a/numpy/lib/scimath.py
+++ b/numpy/lib/scimath.py
@@ -15,8 +15,6 @@ Similarly, `sqrt`, other base logarithms, `power` and trig functions are
correctly handled. See their respective docstrings for specific examples.
"""
-from __future__ import division, absolute_import, print_function
-
import numpy.core.numeric as nx
import numpy.core.numerictypes as nt
from numpy.core.numeric import asarray, any
diff --git a/numpy/lib/setup.py b/numpy/lib/setup.py
index d342410b8..5d0341d86 100644
--- a/numpy/lib/setup.py
+++ b/numpy/lib/setup.py
@@ -1,5 +1,3 @@
-from __future__ import division, print_function
-
def configuration(parent_package='',top_path=None):
from numpy.distutils.misc_util import Configuration
diff --git a/numpy/lib/shape_base.py b/numpy/lib/shape_base.py
index 92d52109e..b7f1f16f2 100644
--- a/numpy/lib/shape_base.py
+++ b/numpy/lib/shape_base.py
@@ -1,7 +1,4 @@
-from __future__ import division, absolute_import, print_function
-
import functools
-import warnings
import numpy.core.numeric as _nx
from numpy.core.numeric import (
@@ -11,6 +8,7 @@ from numpy.core.fromnumeric import reshape, transpose
from numpy.core.multiarray import normalize_axis_index
from numpy.core import overrides
from numpy.core import vstack, atleast_3d
+from numpy.core.numeric import normalize_axis_tuple
from numpy.core.shape_base import _arrays_for_stack_dispatcher
from numpy.lib.index_tricks import ndindex
from numpy.matrixlib.defmatrix import matrix # this raises all the right alarm bells
@@ -29,7 +27,7 @@ array_function_dispatch = functools.partial(
def _make_along_axis_idx(arr_shape, indices, axis):
- # compute dimensions to iterate over
+ # compute dimensions to iterate over
if not _nx.issubdtype(indices.dtype, _nx.integer):
raise IndexError('`indices` must be an integer array')
if len(arr_shape) != indices.ndim:
@@ -271,8 +269,8 @@ def apply_along_axis(func1d, axis, arr, *args, **kwargs):
"""
Apply a function to 1-D slices along the given axis.
- Execute `func1d(a, *args)` where `func1d` operates on 1-D arrays and `a`
- is a 1-D slice of `arr` along `axis`.
+ Execute `func1d(a, *args, **kwargs)` where `func1d` operates on 1-D arrays
+ and `a` is a 1-D slice of `arr` along `axis`.
This is equivalent to (but faster than) the following use of `ndindex` and
`s_`, which sets each of ``ii``, ``jj``, and ``kk`` to a tuple of indices::
@@ -517,22 +515,26 @@ def expand_dims(a, axis):
Insert a new axis that will appear at the `axis` position in the expanded
array shape.
- .. note:: Previous to NumPy 1.13.0, neither ``axis < -a.ndim - 1`` nor
- ``axis > a.ndim`` raised errors or put the new axis where documented.
- Those axis values are now deprecated and will raise an AxisError in the
- future.
-
Parameters
----------
a : array_like
Input array.
- axis : int
- Position in the expanded axes where the new axis is placed.
+ axis : int or tuple of ints
+ Position in the expanded axes where the new axis (or axes) is placed.
+
+ .. deprecated:: 1.13.0
+ Passing an axis where ``axis > a.ndim`` will be treated as
+ ``axis == a.ndim``, and passing ``axis < -a.ndim - 1`` will
+ be treated as ``axis == 0``. This behavior is deprecated.
+
+ .. versionchanged:: 1.18.0
+ A tuple of axes is now supported. Out of range axes as
+ described above are now forbidden and raise an `AxisError`.
Returns
-------
- res : ndarray
- View of `a` with the number of dimensions increased by one.
+ result : ndarray
+ View of `a` with the number of dimensions increased.
See Also
--------
@@ -542,11 +544,11 @@ def expand_dims(a, axis):
Examples
--------
- >>> x = np.array([1,2])
+ >>> x = np.array([1, 2])
>>> x.shape
(2,)
- The following is equivalent to ``x[np.newaxis,:]`` or ``x[np.newaxis]``:
+ The following is equivalent to ``x[np.newaxis, :]`` or ``x[np.newaxis]``:
>>> y = np.expand_dims(x, axis=0)
>>> y
@@ -554,13 +556,26 @@ def expand_dims(a, axis):
>>> y.shape
(1, 2)
- >>> y = np.expand_dims(x, axis=1) # Equivalent to x[:,np.newaxis]
+ The following is equivalent to ``x[:, np.newaxis]``:
+
+ >>> y = np.expand_dims(x, axis=1)
>>> y
array([[1],
[2]])
>>> y.shape
(2, 1)
+ ``axis`` may also be a tuple:
+
+ >>> y = np.expand_dims(x, axis=(0, 1))
+ >>> y
+ array([[[1, 2]]])
+
+ >>> y = np.expand_dims(x, axis=(2, 0))
+ >>> y
+ array([[[1],
+ [2]]])
+
Note that some examples may use ``None`` instead of ``np.newaxis``. These
are the same objects:
@@ -573,18 +588,16 @@ def expand_dims(a, axis):
else:
a = asanyarray(a)
- shape = a.shape
- if axis > a.ndim or axis < -a.ndim - 1:
- # 2017-05-17, 1.13.0
- warnings.warn("Both axis > a.ndim and axis < -a.ndim - 1 are "
- "deprecated and will raise an AxisError in the future.",
- DeprecationWarning, stacklevel=3)
- # When the deprecation period expires, delete this if block,
- if axis < 0:
- axis = axis + a.ndim + 1
- # and uncomment the following line.
- # axis = normalize_axis_index(axis, a.ndim + 1)
- return a.reshape(shape[:axis] + (1,) + shape[axis:])
+ if type(axis) not in (tuple, list):
+ axis = (axis,)
+
+ out_ndim = len(axis) + a.ndim
+ axis = normalize_axis_tuple(axis, out_ndim)
+
+ shape_it = iter(a.shape)
+ shape = [1 if ax in axis else next(shape_it) for ax in range(out_ndim)]
+
+ return a.reshape(shape)
row_stack = vstack
diff --git a/numpy/lib/stride_tricks.py b/numpy/lib/stride_tricks.py
index 8aafd094b..502235bdf 100644
--- a/numpy/lib/stride_tricks.py
+++ b/numpy/lib/stride_tricks.py
@@ -5,15 +5,13 @@ An explanation of strides can be found in the "ndarray.rst" file in the
NumPy reference guide.
"""
-from __future__ import division, absolute_import, print_function
-
import numpy as np
from numpy.core.overrides import array_function_dispatch
__all__ = ['broadcast_to', 'broadcast_arrays']
-class DummyArray(object):
+class DummyArray:
"""Dummy object that just exists to hang __array_interface__ dictionaries
and possibly keep alive a reference to a base array.
"""
@@ -199,12 +197,12 @@ def _broadcast_shape(*args):
return b.shape
-def _broadcast_arrays_dispatcher(*args, **kwargs):
+def _broadcast_arrays_dispatcher(*args, subok=None):
return args
@array_function_dispatch(_broadcast_arrays_dispatcher, module='numpy')
-def broadcast_arrays(*args, **kwargs):
+def broadcast_arrays(*args, subok=False):
"""
Broadcast any number of arrays against each other.
@@ -255,10 +253,6 @@ def broadcast_arrays(*args, **kwargs):
# return np.nditer(args, flags=['multi_index', 'zerosize_ok'],
# order='C').itviews
- subok = kwargs.pop('subok', False)
- if kwargs:
- raise TypeError('broadcast_arrays() got an unexpected keyword '
- 'argument {!r}'.format(list(kwargs.keys())[0]))
args = [np.array(_m, copy=False, subok=subok) for _m in args]
shape = _broadcast_shape(*args)
diff --git a/numpy/lib/tests/test__datasource.py b/numpy/lib/tests/test__datasource.py
index 8eac16b58..1ed7815d9 100644
--- a/numpy/lib/tests/test__datasource.py
+++ b/numpy/lib/tests/test__datasource.py
@@ -1,24 +1,14 @@
-from __future__ import division, absolute_import, print_function
-
import os
-import sys
import pytest
from tempfile import mkdtemp, mkstemp, NamedTemporaryFile
from shutil import rmtree
import numpy.lib._datasource as datasource
-from numpy.testing import (
- assert_, assert_equal, assert_raises, assert_warns
- )
+from numpy.testing import assert_, assert_equal, assert_raises
-if sys.version_info[0] >= 3:
- import urllib.request as urllib_request
- from urllib.parse import urlparse
- from urllib.error import URLError
-else:
- import urllib2 as urllib_request
- from urlparse import urlparse
- from urllib2 import URLError
+import urllib.request as urllib_request
+from urllib.parse import urlparse
+from urllib.error import URLError
def urlopen_stub(url, data=None):
@@ -96,7 +86,7 @@ def invalid_httpfile():
return http_fakefile
-class TestDataSourceOpen(object):
+class TestDataSourceOpen:
def setup(self):
self.tmpdir = mkdtemp()
self.ds = datasource.DataSource(self.tmpdir)
@@ -164,26 +154,8 @@ class TestDataSourceOpen(object):
fp.close()
assert_equal(magic_line, result)
- @pytest.mark.skipif(sys.version_info[0] >= 3, reason="Python 2 only")
- def test_Bz2File_text_mode_warning(self):
- try:
- import bz2
- except ImportError:
- # We don't have the bz2 capabilities to test.
- pytest.skip()
- # Test datasource's internal file_opener for BZip2 files.
- filepath = os.path.join(self.tmpdir, 'foobar.txt.bz2')
- fp = bz2.BZ2File(filepath, 'w')
- fp.write(magic_line)
- fp.close()
- with assert_warns(RuntimeWarning):
- fp = self.ds.open(filepath, 'rt')
- result = fp.readline()
- fp.close()
- assert_equal(magic_line, result)
-
-class TestDataSourceExists(object):
+class TestDataSourceExists:
def setup(self):
self.tmpdir = mkdtemp()
self.ds = datasource.DataSource(self.tmpdir)
@@ -213,7 +185,7 @@ class TestDataSourceExists(object):
assert_equal(self.ds.exists(tmpfile), False)
-class TestDataSourceAbspath(object):
+class TestDataSourceAbspath:
def setup(self):
self.tmpdir = os.path.abspath(mkdtemp())
self.ds = datasource.DataSource(self.tmpdir)
@@ -278,7 +250,7 @@ class TestDataSourceAbspath(object):
os.sep = orig_os_sep
-class TestRepositoryAbspath(object):
+class TestRepositoryAbspath:
def setup(self):
self.tmpdir = os.path.abspath(mkdtemp())
self.repos = datasource.Repository(valid_baseurl(), self.tmpdir)
@@ -311,7 +283,7 @@ class TestRepositoryAbspath(object):
os.sep = orig_os_sep
-class TestRepositoryExists(object):
+class TestRepositoryExists:
def setup(self):
self.tmpdir = mkdtemp()
self.repos = datasource.Repository(valid_baseurl(), self.tmpdir)
@@ -344,7 +316,7 @@ class TestRepositoryExists(object):
assert_(self.repos.exists(tmpfile))
-class TestOpenFunc(object):
+class TestOpenFunc:
def setup(self):
self.tmpdir = mkdtemp()
diff --git a/numpy/lib/tests/test__iotools.py b/numpy/lib/tests/test__iotools.py
index 15cd3ad9d..6964c1128 100644
--- a/numpy/lib/tests/test__iotools.py
+++ b/numpy/lib/tests/test__iotools.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import time
from datetime import date
@@ -11,10 +9,9 @@ from numpy.lib._iotools import (
LineSplitter, NameValidator, StringConverter,
has_nested_fields, easy_dtype, flatten_dtype
)
-from numpy.compat import unicode
-class TestLineSplitter(object):
+class TestLineSplitter:
"Tests the LineSplitter class."
def test_no_delimiter(self):
@@ -83,7 +80,7 @@ class TestLineSplitter(object):
# -----------------------------------------------------------------------------
-class TestNameValidator(object):
+class TestNameValidator:
def test_case_sensitivity(self):
"Test case sensitivity"
@@ -141,7 +138,7 @@ def _bytes_to_date(s):
return date(*time.strptime(s, "%Y-%m-%d")[:3])
-class TestStringConverter(object):
+class TestStringConverter:
"Test StringConverter"
def test_creation(self):
@@ -181,10 +178,10 @@ class TestStringConverter(object):
# note that the longdouble type has been skipped, so the
# _status increases by 2. Everything should succeed with
# unicode conversion (5).
- for s in ['a', u'a', b'a']:
+ for s in ['a', b'a']:
res = converter.upgrade(s)
- assert_(type(res) is unicode)
- assert_equal(res, u'a')
+ assert_(type(res) is str)
+ assert_equal(res, 'a')
assert_equal(converter._status, 5 + status_offset)
def test_missing(self):
@@ -266,7 +263,7 @@ class TestStringConverter(object):
assert_(converter(val) == 9223372043271415339)
-class TestMiscFunctions(object):
+class TestMiscFunctions:
def test_has_nested_dtype(self):
"Test has_nested_dtype"
diff --git a/numpy/lib/tests/test__version.py b/numpy/lib/tests/test__version.py
index 8e66a0c03..182504631 100644
--- a/numpy/lib/tests/test__version.py
+++ b/numpy/lib/tests/test__version.py
@@ -1,8 +1,6 @@
"""Tests for the NumpyVersion class.
"""
-from __future__ import division, absolute_import, print_function
-
from numpy.testing import assert_, assert_raises
from numpy.lib import NumpyVersion
diff --git a/numpy/lib/tests/test_arraypad.py b/numpy/lib/tests/test_arraypad.py
index 65593dd29..75db5928b 100644
--- a/numpy/lib/tests/test_arraypad.py
+++ b/numpy/lib/tests/test_arraypad.py
@@ -1,8 +1,6 @@
"""Tests for the array padding functions.
"""
-from __future__ import division, absolute_import, print_function
-
import pytest
import numpy as np
@@ -31,7 +29,7 @@ _all_modes = {
}
-class TestAsPairs(object):
+class TestAsPairs:
def test_single_value(self):
"""Test casting for a single value."""
expected = np.array([[3, 3]] * 10)
@@ -114,7 +112,7 @@ class TestAsPairs(object):
_as_pairs(np.ones((2, 3)), 3)
-class TestConditionalShortcuts(object):
+class TestConditionalShortcuts:
@pytest.mark.parametrize("mode", _all_modes.keys())
def test_zero_padding_shortcuts(self, mode):
test = np.arange(120).reshape(4, 5, 6)
@@ -136,7 +134,7 @@ class TestConditionalShortcuts(object):
np.pad(test, pad_amt, mode=mode, stat_length=30))
-class TestStatistic(object):
+class TestStatistic:
def test_check_mean_stat_length(self):
a = np.arange(100).astype('f')
a = np.pad(a, ((25, 20), ), 'mean', stat_length=((2, 3), ))
@@ -498,7 +496,7 @@ class TestStatistic(object):
np.pad([1., 2.], 1, mode, stat_length=(1, 0))
-class TestConstant(object):
+class TestConstant:
def test_check_constant(self):
a = np.arange(100)
a = np.pad(a, (25, 20), 'constant', constant_values=(10, 20))
@@ -677,7 +675,7 @@ class TestConstant(object):
assert result.shape == (3, 4, 4)
-class TestLinearRamp(object):
+class TestLinearRamp:
def test_check_simple(self):
a = np.arange(100).astype('f')
a = np.pad(a, (25, 20), 'linear_ramp', end_values=(4, 5))
@@ -762,7 +760,7 @@ class TestLinearRamp(object):
assert_equal(result, expected)
-class TestReflect(object):
+class TestReflect:
def test_check_simple(self):
a = np.arange(100)
a = np.pad(a, (25, 20), 'reflect')
@@ -872,7 +870,7 @@ class TestReflect(object):
assert_array_equal(a, b)
-class TestEmptyArray(object):
+class TestEmptyArray:
"""Check how padding behaves on arrays with an empty dimension."""
@pytest.mark.parametrize(
@@ -896,7 +894,7 @@ class TestEmptyArray(object):
assert result.shape == (8, 0, 4)
-class TestSymmetric(object):
+class TestSymmetric:
def test_check_simple(self):
a = np.arange(100)
a = np.pad(a, (25, 20), 'symmetric')
@@ -1030,7 +1028,7 @@ class TestSymmetric(object):
assert_array_equal(a, b)
-class TestWrap(object):
+class TestWrap:
def test_check_simple(self):
a = np.arange(100)
a = np.pad(a, (25, 20), 'wrap')
@@ -1144,7 +1142,7 @@ class TestWrap(object):
assert_array_equal(np.r_[a, a, a, a][:-3], b)
-class TestEdge(object):
+class TestEdge:
def test_check_simple(self):
a = np.arange(12)
a = np.reshape(a, (4, 3))
@@ -1183,7 +1181,7 @@ class TestEdge(object):
assert_array_equal(padded, expected)
-class TestEmpty(object):
+class TestEmpty:
def test_simple(self):
arr = np.arange(24).reshape(4, 6)
result = np.pad(arr, [(2, 3), (3, 1)], mode="empty")
@@ -1231,7 +1229,7 @@ def test_object_input(mode):
assert_array_equal(np.pad(a, pad_amt, mode=mode), b)
-class TestPadWidth(object):
+class TestPadWidth:
@pytest.mark.parametrize("pad_width", [
(4, 5, 6, 7),
((1,), (2,), (3,)),
@@ -1262,24 +1260,29 @@ class TestPadWidth(object):
with pytest.raises(ValueError, match=match):
np.pad(arr, pad_width, mode)
- @pytest.mark.parametrize("pad_width", [
- "3",
- "word",
- None,
- object(),
- 3.4,
- ((2, 3, 4), (3, 2)), # dtype=object (tuple)
- complex(1, -1),
- ((-2.1, 3), (3, 2)),
+ @pytest.mark.parametrize("pad_width, dtype", [
+ ("3", None),
+ ("word", None),
+ (None, None),
+ (object(), None),
+ (3.4, None),
+ (((2, 3, 4), (3, 2)), object),
+ (complex(1, -1), None),
+ (((-2.1, 3), (3, 2)), None),
])
@pytest.mark.parametrize("mode", _all_modes.keys())
- def test_bad_type(self, pad_width, mode):
+ def test_bad_type(self, pad_width, dtype, mode):
arr = np.arange(30).reshape((6, 5))
match = "`pad_width` must be of integral type."
- with pytest.raises(TypeError, match=match):
- np.pad(arr, pad_width, mode)
- with pytest.raises(TypeError, match=match):
- np.pad(arr, np.array(pad_width), mode)
+ if dtype is not None:
+ # avoid DeprecationWarning when not specifying dtype
+ with pytest.raises(TypeError, match=match):
+ np.pad(arr, np.array(pad_width, dtype=dtype), mode)
+ else:
+ with pytest.raises(TypeError, match=match):
+ np.pad(arr, pad_width, mode)
+ with pytest.raises(TypeError, match=match):
+ np.pad(arr, np.array(pad_width), mode)
def test_pad_width_as_ndarray(self):
a = np.arange(12)
diff --git a/numpy/lib/tests/test_arraysetops.py b/numpy/lib/tests/test_arraysetops.py
index fd21a7f76..81ba789e3 100644
--- a/numpy/lib/tests/test_arraysetops.py
+++ b/numpy/lib/tests/test_arraysetops.py
@@ -1,8 +1,6 @@
"""Test functions for 1D array set operations.
"""
-from __future__ import division, absolute_import, print_function
-
import numpy as np
from numpy.testing import (assert_array_equal, assert_equal,
@@ -13,8 +11,7 @@ from numpy.lib.arraysetops import (
import pytest
-
-class TestSetOps(object):
+class TestSetOps:
def test_intersect1d(self):
# unique inputs
@@ -36,7 +33,7 @@ class TestSetOps(object):
def test_intersect1d_array_like(self):
# See gh-11772
- class Test(object):
+ class Test:
def __array__(self):
return np.arange(3)
@@ -120,12 +117,13 @@ class TestSetOps(object):
assert_array_equal([-1, 0], ediff1d(zero_elem, to_begin=-1, to_end=0))
assert_array_equal([], ediff1d(one_elem))
assert_array_equal([1], ediff1d(two_elem))
- assert_array_equal([7,1,9], ediff1d(two_elem, to_begin=7, to_end=9))
- assert_array_equal([5,6,1,7,8], ediff1d(two_elem, to_begin=[5,6], to_end=[7,8]))
- assert_array_equal([1,9], ediff1d(two_elem, to_end=9))
- assert_array_equal([1,7,8], ediff1d(two_elem, to_end=[7,8]))
- assert_array_equal([7,1], ediff1d(two_elem, to_begin=7))
- assert_array_equal([5,6,1], ediff1d(two_elem, to_begin=[5,6]))
+ assert_array_equal([7, 1, 9], ediff1d(two_elem, to_begin=7, to_end=9))
+ assert_array_equal([5, 6, 1, 7, 8],
+ ediff1d(two_elem, to_begin=[5, 6], to_end=[7, 8]))
+ assert_array_equal([1, 9], ediff1d(two_elem, to_end=9))
+ assert_array_equal([1, 7, 8], ediff1d(two_elem, to_end=[7, 8]))
+ assert_array_equal([7, 1], ediff1d(two_elem, to_begin=7))
+ assert_array_equal([5, 6, 1], ediff1d(two_elem, to_begin=[5, 6]))
@pytest.mark.parametrize("ary, prepend, append", [
# should fail because trying to cast
@@ -135,9 +133,9 @@ class TestSetOps(object):
None,
np.nan),
# should fail because attempting
- # to downcast to smaller int type:
- (np.array([1, 2, 3], dtype=np.int16),
- np.array([5, 1<<20, 2], dtype=np.int32),
+ # to downcast to int type:
+ (np.array([1, 2, 3], dtype=np.int64),
+ np.array([5, 7, 2], dtype=np.float32),
None),
# should fail because attempting to cast
# two special floating point values
@@ -152,29 +150,33 @@ class TestSetOps(object):
# specifically, raise an appropriate
# Exception when attempting to append or
# prepend with an incompatible type
- msg = 'cannot convert'
- with assert_raises_regex(ValueError, msg):
+ msg = 'must be compatible'
+ with assert_raises_regex(TypeError, msg):
ediff1d(ary=ary,
to_end=append,
to_begin=prepend)
- @pytest.mark.parametrize("ary,"
- "prepend,"
- "append,"
- "expected", [
- (np.array([1, 2, 3], dtype=np.int16),
- 0,
- None,
- np.array([0, 1, 1], dtype=np.int16)),
- (np.array([1, 2, 3], dtype=np.int32),
- 0,
- 0,
- np.array([0, 1, 1, 0], dtype=np.int32)),
- (np.array([1, 2, 3], dtype=np.int64),
- 3,
- -9,
- np.array([3, 1, 1, -9], dtype=np.int64)),
- ])
+ @pytest.mark.parametrize(
+ "ary,prepend,append,expected",
+ [
+ (np.array([1, 2, 3], dtype=np.int16),
+ 2**16, # will be cast to int16 under same kind rule.
+ 2**16 + 4,
+ np.array([0, 1, 1, 4], dtype=np.int16)),
+ (np.array([1, 2, 3], dtype=np.float32),
+ np.array([5], dtype=np.float64),
+ None,
+ np.array([5, 1, 1], dtype=np.float32)),
+ (np.array([1, 2, 3], dtype=np.int32),
+ 0,
+ 0,
+ np.array([0, 1, 1, 0], dtype=np.int32)),
+ (np.array([1, 2, 3], dtype=np.int64),
+ 3,
+ -9,
+ np.array([3, 1, 1, -9], dtype=np.int64)),
+ ]
+ )
def test_ediff1d_scalar_handling(self,
ary,
prepend,
@@ -187,7 +189,7 @@ class TestSetOps(object):
to_end=append,
to_begin=prepend)
assert_equal(actual, expected)
-
+ assert actual.dtype == expected.dtype
def test_isin(self):
# the tests for in1d cover most of isin's behavior
@@ -197,33 +199,34 @@ class TestSetOps(object):
b = np.asarray(b).flatten().tolist()
return a in b
isin_slow = np.vectorize(_isin_slow, otypes=[bool], excluded={1})
+
def assert_isin_equal(a, b):
x = isin(a, b)
y = isin_slow(a, b)
assert_array_equal(x, y)
- #multidimensional arrays in both arguments
+ # multidimensional arrays in both arguments
a = np.arange(24).reshape([2, 3, 4])
b = np.array([[10, 20, 30], [0, 1, 3], [11, 22, 33]])
assert_isin_equal(a, b)
- #array-likes as both arguments
+ # array-likes as both arguments
c = [(9, 8), (7, 6)]
d = (9, 7)
assert_isin_equal(c, d)
- #zero-d array:
+ # zero-d array:
f = np.array(3)
assert_isin_equal(f, b)
assert_isin_equal(a, f)
assert_isin_equal(f, f)
- #scalar:
+ # scalar:
assert_isin_equal(5, b)
assert_isin_equal(a, 6)
assert_isin_equal(5, 6)
- #empty array-like:
+ # empty array-like:
x = []
assert_isin_equal(x, b)
assert_isin_equal(a, x)
@@ -410,7 +413,7 @@ class TestSetOps(object):
assert_array_equal(c1, c2)
-class TestUnique(object):
+class TestUnique:
def test_unique_1d(self):
@@ -517,7 +520,8 @@ class TestUnique(object):
a = []
a1_idx = np.unique(a, return_index=True)[1]
a2_inv = np.unique(a, return_inverse=True)[1]
- a3_idx, a3_inv = np.unique(a, return_index=True, return_inverse=True)[1:]
+ a3_idx, a3_inv = np.unique(a, return_index=True,
+ return_inverse=True)[1:]
assert_equal(a1_idx.dtype, np.intp)
assert_equal(a2_inv.dtype, np.intp)
assert_equal(a3_idx.dtype, np.intp)
@@ -560,9 +564,52 @@ class TestUnique(object):
result = np.array([[-0.0, 0.0]])
assert_array_equal(unique(data, axis=0), result, msg)
+ @pytest.mark.parametrize("axis", [0, -1])
+ def test_unique_1d_with_axis(self, axis):
+ x = np.array([4, 3, 2, 3, 2, 1, 2, 2])
+ uniq = unique(x, axis=axis)
+ assert_array_equal(uniq, [1, 2, 3, 4])
+
+ def test_unique_axis_zeros(self):
+ # issue 15559
+ single_zero = np.empty(shape=(2, 0), dtype=np.int8)
+ uniq, idx, inv, cnt = unique(single_zero, axis=0, return_index=True,
+ return_inverse=True, return_counts=True)
+
+ # there's 1 element of shape (0,) along axis 0
+ assert_equal(uniq.dtype, single_zero.dtype)
+ assert_array_equal(uniq, np.empty(shape=(1, 0)))
+ assert_array_equal(idx, np.array([0]))
+ assert_array_equal(inv, np.array([0, 0]))
+ assert_array_equal(cnt, np.array([2]))
+
+ # there's 0 elements of shape (2,) along axis 1
+ uniq, idx, inv, cnt = unique(single_zero, axis=1, return_index=True,
+ return_inverse=True, return_counts=True)
+
+ assert_equal(uniq.dtype, single_zero.dtype)
+ assert_array_equal(uniq, np.empty(shape=(2, 0)))
+ assert_array_equal(idx, np.array([]))
+ assert_array_equal(inv, np.array([]))
+ assert_array_equal(cnt, np.array([]))
+
+ # test a "complicated" shape
+ shape = (0, 2, 0, 3, 0, 4, 0)
+ multiple_zeros = np.empty(shape=shape)
+ for axis in range(len(shape)):
+ expected_shape = list(shape)
+ if shape[axis] == 0:
+ expected_shape[axis] = 0
+ else:
+ expected_shape[axis] = 1
+
+ assert_array_equal(unique(multiple_zeros, axis=axis),
+ np.empty(shape=expected_shape))
+
def test_unique_masked(self):
# issue 8664
- x = np.array([64, 0, 1, 2, 3, 63, 63, 0, 0, 0, 1, 2, 0, 63, 0], dtype='uint8')
+ x = np.array([64, 0, 1, 2, 3, 63, 63, 0, 0, 0, 1, 2, 0, 63, 0],
+ dtype='uint8')
y = np.ma.masked_equal(x, 0)
v = np.unique(y)
@@ -577,7 +624,7 @@ class TestUnique(object):
# as unsigned byte strings. See gh-10495.
fmt = "sort order incorrect for integer type '%s'"
for dt in 'bhilq':
- a = np.array([[-1],[0]], dt)
+ a = np.array([[-1], [0]], dt)
b = np.unique(a, axis=0)
assert_array_equal(a, b, fmt % dt)
diff --git a/numpy/lib/tests/test_arrayterator.py b/numpy/lib/tests/test_arrayterator.py
index 2ce4456a5..c00ed13d7 100644
--- a/numpy/lib/tests/test_arrayterator.py
+++ b/numpy/lib/tests/test_arrayterator.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
from operator import mul
from functools import reduce
diff --git a/numpy/lib/tests/test_financial.py b/numpy/lib/tests/test_financial.py
index 21088765f..26e79bc06 100644
--- a/numpy/lib/tests/test_financial.py
+++ b/numpy/lib/tests/test_financial.py
@@ -1,5 +1,4 @@
-from __future__ import division, absolute_import, print_function
-
+import warnings
from decimal import Decimal
import numpy as np
@@ -8,22 +7,35 @@ from numpy.testing import (
)
-class TestFinancial(object):
+def filter_deprecation(func):
+ def newfunc(*args, **kwargs):
+ with warnings.catch_warnings(record=True) as ws:
+ warnings.filterwarnings('always', category=DeprecationWarning)
+ func(*args, **kwargs)
+ assert_(all(w.category is DeprecationWarning for w in ws))
+ return newfunc
+
+
+class TestFinancial:
+ @filter_deprecation
def test_npv_irr_congruence(self):
# IRR is defined as the rate required for the present value of a
# a series of cashflows to be zero i.e. NPV(IRR(x), x) = 0
cashflows = np.array([-40000, 5000, 8000, 12000, 30000])
assert_allclose(np.npv(np.irr(cashflows), cashflows), 0, atol=1e-10, rtol=0)
+ @filter_deprecation
def test_rate(self):
assert_almost_equal(
np.rate(10, 0, -3500, 10000),
0.1107, 4)
+ @filter_deprecation
def test_rate_decimal(self):
rate = np.rate(Decimal('10'), Decimal('0'), Decimal('-3500'), Decimal('10000'))
assert_equal(Decimal('0.1106908537142689284704528100'), rate)
+ @filter_deprecation
def test_irr(self):
v = [-150000, 15000, 25000, 35000, 45000, 60000]
assert_almost_equal(np.irr(v), 0.0524, 2)
@@ -43,20 +55,25 @@ class TestFinancial(object):
v = [-1, -2, -3]
assert_equal(np.irr(v), np.nan)
+ @filter_deprecation
def test_pv(self):
assert_almost_equal(np.pv(0.07, 20, 12000, 0), -127128.17, 2)
+ @filter_deprecation
def test_pv_decimal(self):
assert_equal(np.pv(Decimal('0.07'), Decimal('20'), Decimal('12000'), Decimal('0')),
Decimal('-127128.1709461939327295222005'))
+ @filter_deprecation
def test_fv(self):
assert_equal(np.fv(0.075, 20, -2000, 0, 0), 86609.362673042924)
+ @filter_deprecation
def test_fv_decimal(self):
assert_equal(np.fv(Decimal('0.075'), Decimal('20'), Decimal('-2000'), 0, 0),
Decimal('86609.36267304300040536731624'))
+ @filter_deprecation
def test_pmt(self):
res = np.pmt(0.08 / 12, 5 * 12, 15000)
tgt = -304.145914
@@ -71,6 +88,7 @@ class TestFinancial(object):
tgt = np.array([[-166.66667, -19311.258], [-626.90814, -19311.258]])
assert_allclose(res, tgt)
+ @filter_deprecation
def test_pmt_decimal(self):
res = np.pmt(Decimal('0.08') / Decimal('12'), 5 * 12, 15000)
tgt = Decimal('-304.1459143262052370338701494')
@@ -94,18 +112,22 @@ class TestFinancial(object):
assert_equal(res[1][0], tgt[1][0])
assert_equal(res[1][1], tgt[1][1])
+ @filter_deprecation
def test_ppmt(self):
assert_equal(np.round(np.ppmt(0.1 / 12, 1, 60, 55000), 2), -710.25)
+ @filter_deprecation
def test_ppmt_decimal(self):
assert_equal(np.ppmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('60'), Decimal('55000')),
Decimal('-710.2541257864217612489830917'))
# Two tests showing how Decimal is actually getting at a more exact result
# .23 / 12 does not come out nicely as a float but does as a decimal
+ @filter_deprecation
def test_ppmt_special_rate(self):
assert_equal(np.round(np.ppmt(0.23 / 12, 1, 60, 10000000000), 8), -90238044.232277036)
+ @filter_deprecation
def test_ppmt_special_rate_decimal(self):
# When rounded out to 8 decimal places like the float based test, this should not equal the same value
# as the float, substituted for the decimal
@@ -118,31 +140,38 @@ class TestFinancial(object):
assert_equal(np.ppmt(Decimal('0.23') / Decimal('12'), 1, 60, Decimal('10000000000')),
Decimal('-90238044.2322778884413969909'))
+ @filter_deprecation
def test_ipmt(self):
assert_almost_equal(np.round(np.ipmt(0.1 / 12, 1, 24, 2000), 2), -16.67)
+ @filter_deprecation
def test_ipmt_decimal(self):
result = np.ipmt(Decimal('0.1') / Decimal('12'), 1, 24, 2000)
assert_equal(result.flat[0], Decimal('-16.66666666666666666666666667'))
+ @filter_deprecation
def test_nper(self):
assert_almost_equal(np.nper(0.075, -2000, 0, 100000.),
21.54, 2)
+ @filter_deprecation
def test_nper2(self):
assert_almost_equal(np.nper(0.0, -2000, 0, 100000.),
50.0, 1)
+ @filter_deprecation
def test_npv(self):
assert_almost_equal(
np.npv(0.05, [-15000, 1500, 2500, 3500, 4500, 6000]),
122.89, 2)
+ @filter_deprecation
def test_npv_decimal(self):
assert_equal(
np.npv(Decimal('0.05'), [-15000, 1500, 2500, 3500, 4500, 6000]),
Decimal('122.894854950942692161628715'))
+ @filter_deprecation
def test_mirr(self):
val = [-4500, -800, 800, 800, 600, 600, 800, 800, 700, 3000]
assert_almost_equal(np.mirr(val, 0.08, 0.055), 0.0666, 4)
@@ -156,6 +185,7 @@ class TestFinancial(object):
val = [39000, 30000, 21000, 37000, 46000]
assert_(np.isnan(np.mirr(val, 0.10, 0.12)))
+ @filter_deprecation
def test_mirr_decimal(self):
val = [Decimal('-4500'), Decimal('-800'), Decimal('800'), Decimal('800'),
Decimal('600'), Decimal('600'), Decimal('800'), Decimal('800'),
@@ -174,6 +204,7 @@ class TestFinancial(object):
val = [Decimal('39000'), Decimal('30000'), Decimal('21000'), Decimal('37000'), Decimal('46000')]
assert_(np.isnan(np.mirr(val, Decimal('0.10'), Decimal('0.12'))))
+ @filter_deprecation
def test_when(self):
# begin
assert_equal(np.rate(10, 20, -3500, 10000, 1),
@@ -238,6 +269,7 @@ class TestFinancial(object):
assert_equal(np.nper(0.075, -2000, 0, 100000., 0),
np.nper(0.075, -2000, 0, 100000., 'end'))
+ @filter_deprecation
def test_decimal_with_when(self):
"""Test that decimals are still supported if the when argument is passed"""
# begin
@@ -312,6 +344,7 @@ class TestFinancial(object):
np.ipmt(Decimal('0.1') / Decimal('12'), Decimal('1'), Decimal('24'), Decimal('2000'),
Decimal('0'), 'end').flat[0])
+ @filter_deprecation
def test_broadcast(self):
assert_almost_equal(np.nper(0.075, -2000, 0, 100000., [0, 1]),
[21.5449442, 20.76156441], 4)
@@ -329,6 +362,7 @@ class TestFinancial(object):
[-74.998201, -75.62318601, -75.62318601,
-76.88882405, -76.88882405], 4)
+ @filter_deprecation
def test_broadcast_decimal(self):
# Use almost equal because precision is tested in the explicit tests, this test is to ensure
# broadcast with Decimal is not broken.
diff --git a/numpy/lib/tests/test_format.py b/numpy/lib/tests/test_format.py
index 062c21725..2dbaeb8cb 100644
--- a/numpy/lib/tests/test_format.py
+++ b/numpy/lib/tests/test_format.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
# doctest
r''' Test the .npy file format.
@@ -537,8 +535,10 @@ dt4 = np.dtype({'names': ['a', '', 'b'], 'formats': ['i4']*3})
# titles
dt5 = np.dtype({'names': ['a', 'b'], 'formats': ['i4', 'i4'],
'offsets': [1, 6], 'titles': ['aa', 'bb']})
+# empty
+dt6 = np.dtype({'names': [], 'formats': [], 'itemsize': 8})
-@pytest.mark.parametrize("dt", [dt1, dt2, dt3, dt4, dt5])
+@pytest.mark.parametrize("dt", [dt1, dt2, dt3, dt4, dt5, dt6])
def test_load_padded_dtype(dt):
arr = np.zeros(3, dt)
for i in range(3):
@@ -550,10 +550,7 @@ def test_load_padded_dtype(dt):
def test_python2_python3_interoperability():
- if sys.version_info[0] >= 3:
- fname = 'win64python2.npy'
- else:
- fname = 'python3.npy'
+ fname = 'win64python2.npy'
path = os.path.join(os.path.dirname(__file__), 'data', fname)
data = np.load(path)
assert_array_equal(data, np.ones(2))
@@ -563,13 +560,7 @@ def test_pickle_python2_python3():
# Python 2 and Python 3 and vice versa
data_dir = os.path.join(os.path.dirname(__file__), 'data')
- if sys.version_info[0] >= 3:
- xrange = range
- else:
- import __builtin__
- xrange = __builtin__.xrange
-
- expected = np.array([None, xrange, u'\u512a\u826f',
+ expected = np.array([None, range, u'\u512a\u826f',
b'\xe4\xb8\x8d\xe8\x89\xaf'],
dtype=object)
@@ -585,34 +576,30 @@ def test_pickle_python2_python3():
else:
data = data_f
- if sys.version_info[0] >= 3:
- if encoding == 'latin1' and fname.startswith('py2'):
- assert_(isinstance(data[3], str))
- assert_array_equal(data[:-1], expected[:-1])
- # mojibake occurs
- assert_array_equal(data[-1].encode(encoding), expected[-1])
- else:
- assert_(isinstance(data[3], bytes))
- assert_array_equal(data, expected)
+ if encoding == 'latin1' and fname.startswith('py2'):
+ assert_(isinstance(data[3], str))
+ assert_array_equal(data[:-1], expected[:-1])
+ # mojibake occurs
+ assert_array_equal(data[-1].encode(encoding), expected[-1])
else:
+ assert_(isinstance(data[3], bytes))
assert_array_equal(data, expected)
- if sys.version_info[0] >= 3:
- if fname.startswith('py2'):
- if fname.endswith('.npz'):
- data = np.load(path, allow_pickle=True)
- assert_raises(UnicodeError, data.__getitem__, 'x')
- data.close()
- data = np.load(path, allow_pickle=True, fix_imports=False,
- encoding='latin1')
- assert_raises(ImportError, data.__getitem__, 'x')
- data.close()
- else:
- assert_raises(UnicodeError, np.load, path,
- allow_pickle=True)
- assert_raises(ImportError, np.load, path,
- allow_pickle=True, fix_imports=False,
- encoding='latin1')
+ if fname.startswith('py2'):
+ if fname.endswith('.npz'):
+ data = np.load(path, allow_pickle=True)
+ assert_raises(UnicodeError, data.__getitem__, 'x')
+ data.close()
+ data = np.load(path, allow_pickle=True, fix_imports=False,
+ encoding='latin1')
+ assert_raises(ImportError, data.__getitem__, 'x')
+ data.close()
+ else:
+ assert_raises(UnicodeError, np.load, path,
+ allow_pickle=True)
+ assert_raises(ImportError, np.load, path,
+ allow_pickle=True, fix_imports=False,
+ encoding='latin1')
def test_pickle_disallow():
@@ -963,3 +950,33 @@ def test_unicode_field_names():
with open(fname, 'wb') as f:
with assert_warns(UserWarning):
format.write_array(f, arr, version=None)
+
+
+@pytest.mark.parametrize('dt, fail', [
+ (np.dtype({'names': ['a', 'b'], 'formats': [float, np.dtype('S3',
+ metadata={'some': 'stuff'})]}), True),
+ (np.dtype(int, metadata={'some': 'stuff'}), False),
+ (np.dtype([('subarray', (int, (2,)))], metadata={'some': 'stuff'}), False),
+ # recursive: metadata on the field of a dtype
+ (np.dtype({'names': ['a', 'b'], 'formats': [
+ float, np.dtype({'names': ['c'], 'formats': [np.dtype(int, metadata={})]})
+ ]}), False)
+ ])
+def test_metadata_dtype(dt, fail):
+ # gh-14142
+ arr = np.ones(10, dtype=dt)
+ buf = BytesIO()
+ with assert_warns(UserWarning):
+ np.save(buf, arr)
+ buf.seek(0)
+ if fail:
+ with assert_raises(ValueError):
+ np.load(buf)
+ else:
+ arr2 = np.load(buf)
+ # BUG: assert_array_equal does not check metadata
+ from numpy.lib.format import _has_metadata
+ assert_array_equal(arr, arr2)
+ assert _has_metadata(arr.dtype)
+ assert not _has_metadata(arr2.dtype)
+
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
index 1eae8ccfb..23bf3296d 100644
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -1,10 +1,7 @@
-from __future__ import division, absolute_import, print_function
-
import operator
import warnings
import sys
import decimal
-import types
from fractions import Fraction
import pytest
@@ -24,9 +21,6 @@ from numpy.lib import (
select, setxor1d, sinc, trapz, trim_zeros, unwrap, unique, vectorize
)
-from numpy.compat import long
-
-PY2 = sys.version_info[0] == 2
def get_mat(n):
data = np.arange(n)
@@ -45,7 +39,7 @@ def _make_complex(real, imag):
return ret
-class TestRot90(object):
+class TestRot90:
def test_basic(self):
assert_raises(ValueError, rot90, np.ones(4))
assert_raises(ValueError, rot90, np.ones((2,2,2)), axes=(0,1,2))
@@ -113,7 +107,7 @@ class TestRot90(object):
rot90(a_rot90_20, k=k-1, axes=(2, 0)))
-class TestFlip(object):
+class TestFlip:
def test_axes(self):
assert_raises(np.AxisError, np.flip, np.ones(4), axis=1)
@@ -216,7 +210,7 @@ class TestFlip(object):
assert_equal(np.flip(a, axis=(1, 2)), c)
-class TestAny(object):
+class TestAny:
def test_basic(self):
y1 = [0, 0, 1, 0]
@@ -233,7 +227,7 @@ class TestAny(object):
assert_array_equal(np.sometrue(y1, axis=1), [0, 1, 1])
-class TestAll(object):
+class TestAll:
def test_basic(self):
y1 = [0, 1, 1, 0]
@@ -251,7 +245,7 @@ class TestAll(object):
assert_array_equal(np.alltrue(y1, axis=1), [0, 0, 1])
-class TestCopy(object):
+class TestCopy:
def test_basic(self):
a = np.array([[1, 2], [3, 4]])
@@ -278,8 +272,15 @@ class TestCopy(object):
assert_(not a_fort_copy.flags.c_contiguous)
assert_(a_fort_copy.flags.f_contiguous)
+ def test_subok(self):
+ mx = ma.ones(5)
+ assert_(not ma.isMaskedArray(np.copy(mx, subok=False)))
+ assert_(ma.isMaskedArray(np.copy(mx, subok=True)))
+ # Default behavior
+ assert_(not ma.isMaskedArray(np.copy(mx)))
-class TestAverage(object):
+
+class TestAverage:
def test_basic(self):
y1 = np.array([1, 2, 3])
@@ -380,7 +381,7 @@ class TestAverage(object):
w /= w.sum()
assert_almost_equal(a.mean(0), average(a, weights=w))
-class TestSelect(object):
+class TestSelect:
choices = [np.array([1, 2, 3]),
np.array([4, 5, 6]),
np.array([7, 8, 9])]
@@ -442,7 +443,7 @@ class TestSelect(object):
select(conditions, choices)
-class TestInsert(object):
+class TestInsert:
def test_basic(self):
a = [1, 2, 3]
@@ -507,12 +508,11 @@ class TestInsert(object):
insert(a, 1, a[:, 2, :], axis=1))
def test_0d(self):
- # This is an error in the future
a = np.array(1)
- with warnings.catch_warnings(record=True) as w:
- warnings.filterwarnings('always', '', DeprecationWarning)
- assert_equal(insert(a, [], 2, axis=0), np.array(2))
- assert_(w[0].category is DeprecationWarning)
+ with pytest.raises(np.AxisError):
+ insert(a, [], 2, axis=0)
+ with pytest.raises(TypeError):
+ insert(a, [], 2, axis="nonsense")
def test_subclass(self):
class SubClass(np.ndarray):
@@ -542,8 +542,14 @@ class TestInsert(object):
b = np.insert(a, [0, 2], val)
assert_array_equal(b[[0, 3]], np.array(val, dtype=b.dtype))
+ def test_index_floats(self):
+ with pytest.raises(IndexError):
+ np.insert([0, 1, 2], np.array([1.0, 2.0]), [10, 20])
+ with pytest.raises(IndexError):
+ np.insert([0, 1, 2], np.array([], dtype=float), [])
-class TestAmax(object):
+
+class TestAmax:
def test_basic(self):
a = [3, 4, 5, 10, -3, -5, 6.0]
@@ -555,7 +561,7 @@ class TestAmax(object):
assert_equal(np.amax(b, axis=1), [9.0, 10.0, 8.0])
-class TestAmin(object):
+class TestAmin:
def test_basic(self):
a = [3, 4, 5, 10, -3, -5, 6.0]
@@ -567,7 +573,7 @@ class TestAmin(object):
assert_equal(np.amin(b, axis=1), [3.0, 4.0, 2.0])
-class TestPtp(object):
+class TestPtp:
def test_basic(self):
a = np.array([3, 4, 5, 10, -3, -5, 6.0])
@@ -582,7 +588,7 @@ class TestPtp(object):
assert_equal(b.ptp(axis=(0,1), keepdims=True), [[8.0]])
-class TestCumsum(object):
+class TestCumsum:
def test_basic(self):
ba = [1, 2, 10, 11, 6, 5, 4]
@@ -605,7 +611,7 @@ class TestCumsum(object):
assert_array_equal(np.cumsum(a2, axis=1), tgt)
-class TestProd(object):
+class TestProd:
def test_basic(self):
ba = [1, 2, 10, 11, 6, 5, 4]
@@ -625,7 +631,7 @@ class TestProd(object):
np.array([24, 1890, 600], ctype))
-class TestCumprod(object):
+class TestCumprod:
def test_basic(self):
ba = [1, 2, 10, 11, 6, 5, 4]
@@ -652,7 +658,7 @@ class TestCumprod(object):
[10, 30, 120, 600]], ctype))
-class TestDiff(object):
+class TestDiff:
def test_basic(self):
x = [1, 4, 6, 7, 12]
@@ -792,7 +798,7 @@ class TestDiff(object):
assert_raises(np.AxisError, diff, x, append=0, axis=3)
-class TestDelete(object):
+class TestDelete:
def setup(self):
self.a = np.arange(5)
@@ -802,10 +808,6 @@ class TestDelete(object):
a_del = delete(self.a, indices)
nd_a_del = delete(self.nd_a, indices, axis=1)
msg = 'Delete failed for obj: %r' % indices
- # NOTE: The cast should be removed after warning phase for bools
- if not isinstance(indices, (slice, int, long, np.integer)):
- indices = np.asarray(indices, dtype=np.intp)
- indices = indices[(indices >= 0) & (indices < 5)]
assert_array_equal(setxor1d(a_del, self.a[indices, ]), self.a,
err_msg=msg)
xor = setxor1d(nd_a_del[0,:, 0], self.nd_a[0, indices, 0])
@@ -821,19 +823,25 @@ class TestDelete(object):
self._check_inverse_of_slicing(s)
def test_fancy(self):
- # Deprecation/FutureWarning tests should be kept after change.
self._check_inverse_of_slicing(np.array([[0, 1], [2, 1]]))
- with warnings.catch_warnings():
- warnings.filterwarnings('error', category=DeprecationWarning)
- assert_raises(DeprecationWarning, delete, self.a, [100])
- assert_raises(DeprecationWarning, delete, self.a, [-100])
- with warnings.catch_warnings(record=True) as w:
- warnings.filterwarnings('always', category=FutureWarning)
- self._check_inverse_of_slicing([0, -1, 2, 2])
- obj = np.array([True, False, False], dtype=bool)
- self._check_inverse_of_slicing(obj)
- assert_(w[0].category is FutureWarning)
- assert_(w[1].category is FutureWarning)
+ with pytest.raises(IndexError):
+ delete(self.a, [100])
+ with pytest.raises(IndexError):
+ delete(self.a, [-100])
+
+ self._check_inverse_of_slicing([0, -1, 2, 2])
+
+ self._check_inverse_of_slicing([True, False, False, True, False])
+
+ # not legal, indexing with these would change the dimension
+ with pytest.raises(ValueError):
+ delete(self.a, True)
+ with pytest.raises(ValueError):
+ delete(self.a, False)
+
+ # not enough items
+ with pytest.raises(ValueError):
+ delete(self.a, [False]*4)
def test_single(self):
self._check_inverse_of_slicing(0)
@@ -841,10 +849,10 @@ class TestDelete(object):
def test_0d(self):
a = np.array(1)
- with warnings.catch_warnings(record=True) as w:
- warnings.filterwarnings('always', '', DeprecationWarning)
- assert_equal(delete(a, [], axis=0), a)
- assert_(w[0].category is DeprecationWarning)
+ with pytest.raises(np.AxisError):
+ delete(a, [], axis=0)
+ with pytest.raises(TypeError):
+ delete(a, [], axis="nonsense")
def test_subclass(self):
class SubClass(np.ndarray):
@@ -866,8 +874,14 @@ class TestDelete(object):
assert_equal(m.flags.c_contiguous, k.flags.c_contiguous)
assert_equal(m.flags.f_contiguous, k.flags.f_contiguous)
+ def test_index_floats(self):
+ with pytest.raises(IndexError):
+ np.delete([0, 1, 2], np.array([1.0, 2.0]))
+ with pytest.raises(IndexError):
+ np.delete([0, 1, 2], np.array([], dtype=float))
-class TestGradient(object):
+
+class TestGradient:
def test_basic(self):
v = [[1, 1], [3, 4]]
@@ -1084,8 +1098,42 @@ class TestGradient(object):
assert_raises(ValueError, gradient, np.arange(1), edge_order=2)
assert_raises(ValueError, gradient, np.arange(2), edge_order=2)
-
-class TestAngle(object):
+ @pytest.mark.parametrize('f_dtype', [np.uint8, np.uint16,
+ np.uint32, np.uint64])
+ def test_f_decreasing_unsigned_int(self, f_dtype):
+ f = np.array([5, 4, 3, 2, 1], dtype=f_dtype)
+ g = gradient(f)
+ assert_array_equal(g, [-1]*len(f))
+
+ @pytest.mark.parametrize('f_dtype', [np.int8, np.int16,
+ np.int32, np.int64])
+ def test_f_signed_int_big_jump(self, f_dtype):
+ maxint = np.iinfo(f_dtype).max
+ x = np.array([1, 3])
+ f = np.array([-1, maxint], dtype=f_dtype)
+ dfdx = gradient(f, x)
+ assert_array_equal(dfdx, [(maxint + 1) // 2]*2)
+
+ @pytest.mark.parametrize('x_dtype', [np.uint8, np.uint16,
+ np.uint32, np.uint64])
+ def test_x_decreasing_unsigned(self, x_dtype):
+ x = np.array([3, 2, 1], dtype=x_dtype)
+ f = np.array([0, 2, 4])
+ dfdx = gradient(f, x)
+ assert_array_equal(dfdx, [-2]*len(x))
+
+ @pytest.mark.parametrize('x_dtype', [np.int8, np.int16,
+ np.int32, np.int64])
+ def test_x_signed_int_big_jump(self, x_dtype):
+ minint = np.iinfo(x_dtype).min
+ maxint = np.iinfo(x_dtype).max
+ x = np.array([-1, maxint], dtype=x_dtype)
+ f = np.array([minint // 2, 0])
+ dfdx = gradient(f, x)
+ assert_array_equal(dfdx, [0.5, 0.5])
+
+
+class TestAngle:
def test_basic(self):
x = [1 + 3j, np.sqrt(2) / 2.0 + 1j * np.sqrt(2) / 2,
@@ -1111,7 +1159,7 @@ class TestAngle(object):
assert_equal(actual, expected)
-class TestTrimZeros(object):
+class TestTrimZeros:
"""
Only testing for integer splits.
@@ -1134,7 +1182,7 @@ class TestTrimZeros(object):
assert_array_equal(res, np.array([1, 0, 2, 3, 0, 4]))
-class TestExtins(object):
+class TestExtins:
def test_basic(self):
a = np.array([1, 3, 2, 1, 2, 3, 3])
@@ -1173,7 +1221,7 @@ class TestExtins(object):
assert_array_equal(a, ac)
-class TestVectorize(object):
+class TestVectorize:
def test_simple(self):
def addsubtract(a, b):
@@ -1505,8 +1553,8 @@ class TestVectorize(object):
f(x)
-class TestLeaks(object):
- class A(object):
+class TestLeaks:
+ class A:
iters = 20
def bound(self, *args):
@@ -1537,18 +1585,15 @@ class TestLeaks(object):
a.f = np.frompyfunc(getattr(a, name), 1, 1)
out = a.f(np.arange(10))
a = None
- if PY2:
- assert_equal(sys.getrefcount(A_func), refcount)
- else:
- # A.func is part of a reference cycle if incr is non-zero
- assert_equal(sys.getrefcount(A_func), refcount + incr)
+ # A.func is part of a reference cycle if incr is non-zero
+ assert_equal(sys.getrefcount(A_func), refcount + incr)
for i in range(5):
gc.collect()
assert_equal(sys.getrefcount(A_func), refcount)
finally:
gc.enable()
-class TestDigitize(object):
+class TestDigitize:
def test_forward(self):
x = np.arange(-6, 5)
@@ -1633,7 +1678,7 @@ class TestDigitize(object):
assert_equal(np.digitize(x, [x + 1, x - 1]), 1)
-class TestUnwrap(object):
+class TestUnwrap:
def test_simple(self):
# check that unwrap removes jumps greater that 2*pi
@@ -1642,7 +1687,7 @@ class TestUnwrap(object):
assert_(np.all(diff(unwrap(rand(10) * 100)) < np.pi))
-class TestFilterwindows(object):
+class TestFilterwindows:
def test_hanning(self):
# check symmetry
@@ -1673,7 +1718,7 @@ class TestFilterwindows(object):
assert_almost_equal(np.sum(w, axis=0), 3.7800, 4)
-class TestTrapz(object):
+class TestTrapz:
def test_simple(self):
x = np.arange(-10, 10, .1)
@@ -1735,7 +1780,7 @@ class TestTrapz(object):
assert_almost_equal(trapz(y, xm), r)
-class TestSinc(object):
+class TestSinc:
def test_simple(self):
assert_(sinc(0) == 1)
@@ -1752,7 +1797,7 @@ class TestSinc(object):
assert_array_equal(y1, y3)
-class TestUnique(object):
+class TestUnique:
def test_simple(self):
x = np.array([4, 3, 2, 1, 1, 2, 3, 4, 0])
@@ -1764,7 +1809,7 @@ class TestUnique(object):
assert_(np.all(unique(x) == [1 + 1j, 1 + 10j, 5 + 6j, 10]))
-class TestCheckFinite(object):
+class TestCheckFinite:
def test_simple(self):
a = [1, 2, 3]
@@ -1781,7 +1826,7 @@ class TestCheckFinite(object):
assert_(a.dtype == np.float64)
-class TestCorrCoef(object):
+class TestCorrCoef:
A = np.array(
[[0.15391142, 0.18045767, 0.14197213],
[0.70461506, 0.96474128, 0.27906989],
@@ -1866,14 +1911,14 @@ class TestCorrCoef(object):
assert_(np.all(np.abs(c) <= 1.0))
-class TestCov(object):
+class TestCov:
x1 = np.array([[0, 2], [1, 1], [2, 0]]).T
res1 = np.array([[1., -1.], [-1., 1.]])
x2 = np.array([0.0, 1.0, 2.0], ndmin=2)
frequencies = np.array([1, 4, 1])
x2_repeats = np.array([[0.0], [1.0], [1.0], [1.0], [1.0], [2.0]]).T
res2 = np.array([[0.4, -0.4], [-0.4, 0.4]])
- unit_frequencies = np.ones(3, dtype=np.integer)
+ unit_frequencies = np.ones(3, dtype=np.int_)
weights = np.array([1.0, 4.0, 1.0])
res3 = np.array([[2. / 3., -2. / 3.], [-2. / 3., 2. / 3.]])
unit_weights = np.ones(3)
@@ -1926,11 +1971,11 @@ class TestCov(object):
self.res1)
nonint = self.frequencies + 0.5
assert_raises(TypeError, cov, self.x1, fweights=nonint)
- f = np.ones((2, 3), dtype=np.integer)
+ f = np.ones((2, 3), dtype=np.int_)
assert_raises(RuntimeError, cov, self.x1, fweights=f)
- f = np.ones(2, dtype=np.integer)
+ f = np.ones(2, dtype=np.int_)
assert_raises(RuntimeError, cov, self.x1, fweights=f)
- f = -1 * np.ones(3, dtype=np.integer)
+ f = -1 * np.ones(3, dtype=np.int_)
assert_raises(ValueError, cov, self.x1, fweights=f)
def test_aweights(self):
@@ -1966,7 +2011,7 @@ class TestCov(object):
self.res1)
-class Test_I0(object):
+class Test_I0:
def test_simple(self):
assert_almost_equal(
@@ -2012,7 +2057,7 @@ class Test_I0(object):
assert_array_equal(exp, res)
-class TestKaiser(object):
+class TestKaiser:
def test_simple(self):
assert_(np.isfinite(kaiser(1, 1.0)))
@@ -2031,7 +2076,7 @@ class TestKaiser(object):
kaiser(3, 4)
-class TestMsort(object):
+class TestMsort:
def test_simple(self):
A = np.array([[0.44567325, 0.79115165, 0.54900530],
@@ -2044,7 +2089,7 @@ class TestMsort(object):
[0.64864341, 0.79115165, 0.96098397]]))
-class TestMeshgrid(object):
+class TestMeshgrid:
def test_simple(self):
[X, Y] = meshgrid([1, 2, 3], [4, 5, 6, 7])
@@ -2133,7 +2178,7 @@ class TestMeshgrid(object):
assert_equal(x[1, :], X)
-class TestPiecewise(object):
+class TestPiecewise:
def test_simple(self):
# Condition is single bool list
@@ -2225,7 +2270,7 @@ class TestPiecewise(object):
[3., 3., 1.]]))
-class TestBincount(object):
+class TestBincount:
def test_simple(self):
y = np.bincount(np.arange(4))
@@ -2312,7 +2357,7 @@ class TestBincount(object):
assert_equal(sys.getrefcount(np.dtype(np.double)), double_refcount)
-class TestInterp(object):
+class TestInterp:
def test_exceptions(self):
assert_raises(ValueError, interp, 0, [], [])
@@ -2511,7 +2556,7 @@ def compare_results(res, desired):
assert_array_equal(res[i], desired[i])
-class TestPercentile(object):
+class TestPercentile:
def test_basic(self):
x = np.arange(8) * 0.5
@@ -2523,7 +2568,7 @@ class TestPercentile(object):
assert_equal(np.percentile(x, 0, interpolation='nearest'), np.nan)
def test_fraction(self):
- x = [Fraction(i, 2) for i in np.arange(8)]
+ x = [Fraction(i, 2) for i in range(8)]
p = np.percentile(x, Fraction(0))
assert_equal(p, Fraction(0))
@@ -2932,7 +2977,7 @@ class TestPercentile(object):
a, [0.3, 0.6], (0, 2), interpolation='nearest'), b)
-class TestQuantile(object):
+class TestQuantile:
# most of this is already tested by TestPercentile
def test_basic(self):
@@ -2941,9 +2986,19 @@ class TestQuantile(object):
assert_equal(np.quantile(x, 1), 3.5)
assert_equal(np.quantile(x, 0.5), 1.75)
+ def test_correct_quantile_value(self):
+ a = np.array([True])
+ tf_quant = np.quantile(True, False)
+ assert_equal(tf_quant, a[0])
+ assert_equal(type(tf_quant), a.dtype)
+ a = np.array([False, True, True])
+ quant_res = np.quantile(a, a)
+ assert_array_equal(quant_res, a)
+ assert_equal(a.dtype, quant_res.dtype)
+
def test_fraction(self):
# fractional input, integral quantile
- x = [Fraction(i, 2) for i in np.arange(8)]
+ x = [Fraction(i, 2) for i in range(8)]
q = np.quantile(x, 0)
assert_equal(q, 0)
@@ -2974,7 +3029,7 @@ class TestQuantile(object):
assert_array_equal(p, p0)
-class TestMedian(object):
+class TestMedian:
def test_basic(self):
a0 = np.array(1)
@@ -3213,7 +3268,7 @@ class TestMedian(object):
(1, 1, 7, 1))
-class TestAdd_newdoc_ufunc(object):
+class TestAdd_newdoc_ufunc:
def test_ufunc_arg(self):
assert_raises(TypeError, add_newdoc_ufunc, 2, "blah")
@@ -3223,7 +3278,7 @@ class TestAdd_newdoc_ufunc(object):
assert_raises(TypeError, add_newdoc_ufunc, np.add, 3)
-class TestAdd_newdoc(object):
+class TestAdd_newdoc:
@pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO")
@pytest.mark.xfail(IS_PYPY, reason="PyPy does not modify tp_doc")
@@ -3234,7 +3289,7 @@ class TestAdd_newdoc(object):
assert_(len(np.core.ufunc.identity.__doc__) > 300)
assert_(len(np.lib.index_tricks.mgrid.__doc__) > 300)
-class TestSortComplex(object):
+class TestSortComplex:
@pytest.mark.parametrize("type_in, type_out", [
('l', 'D'),
diff --git a/numpy/lib/tests/test_histograms.py b/numpy/lib/tests/test_histograms.py
index 4895a722c..fc16b7396 100644
--- a/numpy/lib/tests/test_histograms.py
+++ b/numpy/lib/tests/test_histograms.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import numpy as np
from numpy.lib.histograms import histogram, histogramdd, histogram_bin_edges
@@ -8,9 +6,10 @@ from numpy.testing import (
assert_array_almost_equal, assert_raises, assert_allclose,
assert_array_max_ulp, assert_raises_regex, suppress_warnings,
)
+import pytest
-class TestHistogram(object):
+class TestHistogram:
def setup(self):
pass
@@ -82,7 +81,7 @@ class TestHistogram(object):
a, b = histogram(v, bins, density=False)
assert_array_equal(a, [1, 2, 3, 4])
- # Variale bin widths are especially useful to deal with
+ # Variable bin widths are especially useful to deal with
# infinities.
v = np.arange(10)
bins = [0, 1, 3, 6, np.inf]
@@ -423,7 +422,7 @@ class TestHistogram(object):
assert_array_equal(edges, e)
-class TestHistogramOptimBinNums(object):
+class TestHistogramOptimBinNums:
"""
Provide test coverage when using provided estimators for optimal number of
bins
@@ -591,6 +590,16 @@ class TestHistogramOptimBinNums(object):
msg += " with datasize of {0}".format(testlen)
assert_equal(len(a), numbins, err_msg=msg)
+ @pytest.mark.parametrize("bins", ['auto', 'fd', 'doane', 'scott',
+ 'stone', 'rice', 'sturges'])
+ def test_signed_integer_data(self, bins):
+ # Regression test for gh-14379.
+ a = np.array([-2, 0, 127], dtype=np.int8)
+ hist, edges = np.histogram(a, bins=bins)
+ hist32, edges32 = np.histogram(a.astype(np.int32), bins=bins)
+ assert_array_equal(hist, hist32)
+ assert_array_equal(edges, edges32)
+
def test_simple_weighted(self):
"""
Check that weighted data raises a TypeError
@@ -601,7 +610,7 @@ class TestHistogramOptimBinNums(object):
estimator, weights=[1, 2, 3])
-class TestHistogramdd(object):
+class TestHistogramdd:
def test_simple(self):
x = np.array([[-.5, .5, 1.5], [-.5, 1.5, 2.5], [-.5, 2.5, .5],
diff --git a/numpy/lib/tests/test_index_tricks.py b/numpy/lib/tests/test_index_tricks.py
index dbe445c2c..905165a99 100644
--- a/numpy/lib/tests/test_index_tricks.py
+++ b/numpy/lib/tests/test_index_tricks.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import pytest
import numpy as np
@@ -14,7 +12,7 @@ from numpy.lib.index_tricks import (
)
-class TestRavelUnravelIndex(object):
+class TestRavelUnravelIndex:
def test_basic(self):
assert_equal(np.unravel_index(2, (2, 2)), (1, 0))
@@ -194,7 +192,7 @@ class TestRavelUnravelIndex(object):
with assert_raises(ValueError):
np.unravel_index([1], (2, 1, 0))
-class TestGrid(object):
+class TestGrid:
def test_basic(self):
a = mgrid[-1:1:10j]
b = mgrid[-1:1:0.1]
@@ -252,7 +250,7 @@ class TestGrid(object):
assert_equal(grid_small.size, expected[1])
-class TestConcatenator(object):
+class TestConcatenator:
def test_1d(self):
assert_array_equal(r_[1, 2, 3, 4, 5, 6], np.array([1, 2, 3, 4, 5, 6]))
b = np.ones(5)
@@ -290,14 +288,14 @@ class TestConcatenator(object):
assert_equal(r_[np.array(0), [1, 2, 3]], [0, 1, 2, 3])
-class TestNdenumerate(object):
+class TestNdenumerate:
def test_basic(self):
a = np.array([[1, 2], [3, 4]])
assert_equal(list(ndenumerate(a)),
[((0, 0), 1), ((0, 1), 2), ((1, 0), 3), ((1, 1), 4)])
-class TestIndexExpression(object):
+class TestIndexExpression:
def test_regression_1(self):
# ticket #1196
a = np.arange(2)
@@ -311,7 +309,7 @@ class TestIndexExpression(object):
assert_equal(a[:, :3, [1, 2]], a[s_[:, :3, [1, 2]]])
-class TestIx_(object):
+class TestIx_:
def test_regression_1(self):
# Test empty untyped inputs create outputs of indexing type, gh-5804
a, = np.ix_(range(0))
@@ -358,7 +356,7 @@ def test_c_():
assert_equal(a, [[1, 2, 3, 0, 0, 4, 5, 6]])
-class TestFillDiagonal(object):
+class TestFillDiagonal:
def test_basic(self):
a = np.zeros((3, 3), int)
fill_diagonal(a, 5)
@@ -457,7 +455,7 @@ def test_diag_indices():
)
-class TestDiagIndicesFrom(object):
+class TestDiagIndicesFrom:
def test_diag_indices_from(self):
x = np.random.random((4, 4))
diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py
index 1181fe986..8ce20a116 100644
--- a/numpy/lib/tests/test_io.py
+++ b/numpy/lib/tests/test_io.py
@@ -1,6 +1,5 @@
-from __future__ import division, absolute_import, print_function
-
import sys
+import gc
import gzip
import os
import threading
@@ -9,21 +8,24 @@ import warnings
import io
import re
import pytest
+from pathlib import Path
from tempfile import NamedTemporaryFile
from io import BytesIO, StringIO
from datetime import datetime
import locale
+from multiprocessing import Process
import numpy as np
import numpy.ma as ma
from numpy.lib._iotools import ConverterError, ConversionWarning
-from numpy.compat import asbytes, bytes, Path
+from numpy.compat import asbytes, bytes
from numpy.ma.testutils import assert_equal
from numpy.testing import (
assert_warns, assert_, assert_raises_regex, assert_raises,
assert_allclose, assert_array_equal, temppath, tempdir, IS_PYPY,
HAS_REFCOUNT, suppress_warnings, assert_no_gc_cycles, assert_no_warnings
)
+from numpy.testing._private.utils import requires_memory
class TextIO(BytesIO):
@@ -45,7 +47,6 @@ class TextIO(BytesIO):
BytesIO.writelines(self, [asbytes(s) for s in lines])
-MAJVER, MINVER = sys.version_info[:2]
IS_64BIT = sys.maxsize > 2**32
try:
import bz2
@@ -70,7 +71,7 @@ def strptime(s, fmt=None):
return datetime(*time.strptime(s, fmt)[:3])
-class RoundtripTest(object):
+class RoundtripTest:
def roundtrip(self, save_func, *args, **kwargs):
"""
save_func : callable
@@ -277,8 +278,6 @@ class TestSavezLoad(RoundtripTest):
fp.seek(0)
assert_(not fp.closed)
- #FIXME: Is this still true?
- @pytest.mark.skipif(IS_PYPY, reason="Missing context manager on PyPy")
def test_closing_fid(self):
# Test that issue #1517 (too many opened files) remains closed
# It might be a "weak" test since failed to get triggered on
@@ -291,17 +290,18 @@ class TestSavezLoad(RoundtripTest):
# numpy npz file returned by np.load when their reference count
# goes to zero. Python 3 running in debug mode raises a
# ResourceWarning when file closing is left to the garbage
- # collector, so we catch the warnings. Because ResourceWarning
- # is unknown in Python < 3.x, we take the easy way out and
- # catch all warnings.
+ # collector, so we catch the warnings.
with suppress_warnings() as sup:
- sup.filter(Warning) # TODO: specify exact message
+ sup.filter(ResourceWarning) # TODO: specify exact message
for i in range(1, 1025):
try:
np.load(tmp)["data"]
except Exception as e:
msg = "Failed to load data from a file: %s" % e
raise AssertionError(msg)
+ finally:
+ if IS_PYPY:
+ gc.collect()
def test_closing_zipfile_after_load(self):
# Check that zipfile owns file and can close it. This needs to
@@ -317,7 +317,7 @@ class TestSavezLoad(RoundtripTest):
assert_(fp.closed)
-class TestSaveTxt(object):
+class TestSaveTxt:
def test_array(self):
a = np.array([[1, 2], [3, 4]], float)
fmt = "%.18e"
@@ -364,7 +364,6 @@ class TestSaveTxt(object):
c.seek(0)
assert_equal(c.readlines(), [b'1 3\n', b'4 6\n'])
- @pytest.mark.skipif(Path is None, reason="No pathlib.Path")
def test_multifield_view(self):
a = np.ones(1, dtype=[('x', 'i4'), ('y', 'i4'), ('z', 'f4')])
v = a[['x', 'z']]
@@ -518,7 +517,7 @@ class TestSaveTxt(object):
def test_unicode(self):
utf8 = b'\xcf\x96'.decode('UTF-8')
- a = np.array([utf8], dtype=np.unicode)
+ a = np.array([utf8], dtype=np.unicode_)
with tempdir() as tmpdir:
# set encoding as on windows it may not be unicode even on py3
np.savetxt(os.path.join(tmpdir, 'test.csv'), a, fmt=['%s'],
@@ -526,26 +525,24 @@ class TestSaveTxt(object):
def test_unicode_roundtrip(self):
utf8 = b'\xcf\x96'.decode('UTF-8')
- a = np.array([utf8], dtype=np.unicode)
+ a = np.array([utf8], dtype=np.unicode_)
# our gz wrapper support encoding
suffixes = ['', '.gz']
- # stdlib 2 versions do not support encoding
- if MAJVER > 2:
- if HAS_BZ2:
- suffixes.append('.bz2')
- if HAS_LZMA:
- suffixes.extend(['.xz', '.lzma'])
+ if HAS_BZ2:
+ suffixes.append('.bz2')
+ if HAS_LZMA:
+ suffixes.extend(['.xz', '.lzma'])
with tempdir() as tmpdir:
for suffix in suffixes:
np.savetxt(os.path.join(tmpdir, 'test.csv' + suffix), a,
fmt=['%s'], encoding='UTF-16-LE')
b = np.loadtxt(os.path.join(tmpdir, 'test.csv' + suffix),
- encoding='UTF-16-LE', dtype=np.unicode)
+ encoding='UTF-16-LE', dtype=np.unicode_)
assert_array_equal(a, b)
def test_unicode_bytestream(self):
utf8 = b'\xcf\x96'.decode('UTF-8')
- a = np.array([utf8], dtype=np.unicode)
+ a = np.array([utf8], dtype=np.unicode_)
s = BytesIO()
np.savetxt(s, a, fmt=['%s'], encoding='UTF-8')
s.seek(0)
@@ -553,7 +550,7 @@ class TestSaveTxt(object):
def test_unicode_stringstream(self):
utf8 = b'\xcf\x96'.decode('UTF-8')
- a = np.array([utf8], dtype=np.unicode)
+ a = np.array([utf8], dtype=np.unicode_)
s = StringIO()
np.savetxt(s, a, fmt=['%s'], encoding='UTF-8')
s.seek(0)
@@ -572,22 +569,23 @@ class TestSaveTxt(object):
else:
assert_equal(s.read(), b"%f\n" % 1.)
- @pytest.mark.skipif(sys.platform=='win32',
- reason="large files cause problems")
+ @pytest.mark.skipif(sys.platform=='win32', reason="files>4GB may not work")
@pytest.mark.slow
+ @requires_memory(free_bytes=7e9)
def test_large_zip(self):
- # The test takes at least 6GB of memory, writes a file larger than 4GB
- try:
- a = 'a' * 6 * 1024 * 1024 * 1024
- del a
- except (MemoryError, OverflowError):
- pytest.skip("Cannot allocate enough memory for test")
- test_data = np.asarray([np.random.rand(np.random.randint(50,100),4)
- for i in range(800000)])
- with tempdir() as tmpdir:
- np.savez(os.path.join(tmpdir, 'test.npz'), test_data=test_data)
-
-class LoadTxtBase(object):
+ def check_large_zip():
+ # The test takes at least 6GB of memory, writes a file larger than 4GB
+ test_data = np.asarray([np.random.rand(np.random.randint(50,100),4)
+ for i in range(800000)], dtype=object)
+ with tempdir() as tmpdir:
+ np.savez(os.path.join(tmpdir, 'test.npz'), test_data=test_data)
+ # run in a subprocess to ensure memory is released on PyPy, see gh-15775
+ p = Process(target=check_large_zip)
+ p.start()
+ p.join()
+ assert p.exitcode == 0
+
+class LoadTxtBase:
def check_compressed(self, fopen, suffixes):
# Test that we can load data from a compressed file
wanted = np.arange(6).reshape((2, 3))
@@ -604,18 +602,14 @@ class LoadTxtBase(object):
res = self.loadfunc(f)
assert_array_equal(res, wanted)
- # Python2 .open does not support encoding
- @pytest.mark.skipif(MAJVER == 2, reason="Needs Python version >= 3")
def test_compressed_gzip(self):
self.check_compressed(gzip.open, ('.gz',))
@pytest.mark.skipif(not HAS_BZ2, reason="Needs bz2")
- @pytest.mark.skipif(MAJVER == 2, reason="Needs Python version >= 3")
def test_compressed_bz2(self):
self.check_compressed(bz2.open, ('.bz2',))
@pytest.mark.skipif(not HAS_LZMA, reason="Needs lzma")
- @pytest.mark.skipif(MAJVER == 2, reason="Needs Python version >= 3")
def test_compressed_lzma(self):
self.check_compressed(lzma.open, ('.xz', '.lzma'))
@@ -632,12 +626,12 @@ class LoadTxtBase(object):
with temppath() as path:
with open(path, "wb") as f:
f.write(nonascii.encode("UTF-16"))
- x = self.loadfunc(path, encoding="UTF-16", dtype=np.unicode)
+ x = self.loadfunc(path, encoding="UTF-16", dtype=np.unicode_)
assert_array_equal(x, nonascii)
def test_binary_decode(self):
utf16 = b'\xff\xfeh\x04 \x00i\x04 \x00j\x04'
- v = self.loadfunc(BytesIO(utf16), dtype=np.unicode, encoding='UTF-16')
+ v = self.loadfunc(BytesIO(utf16), dtype=np.unicode_, encoding='UTF-16')
assert_array_equal(v, np.array(utf16.decode('UTF-16').split()))
def test_converters_decode(self):
@@ -645,7 +639,7 @@ class LoadTxtBase(object):
c = TextIO()
c.write(b'\xcf\x96')
c.seek(0)
- x = self.loadfunc(c, dtype=np.unicode,
+ x = self.loadfunc(c, dtype=np.unicode_,
converters={0: lambda x: x.decode('UTF-8')})
a = np.array([b'\xcf\x96'.decode('UTF-8')])
assert_array_equal(x, a)
@@ -656,7 +650,7 @@ class LoadTxtBase(object):
with temppath() as path:
with io.open(path, 'wt', encoding='UTF-8') as f:
f.write(utf8)
- x = self.loadfunc(path, dtype=np.unicode,
+ x = self.loadfunc(path, dtype=np.unicode_,
converters={0: lambda x: x + 't'},
encoding='UTF-8')
a = np.array([utf8 + 't'])
@@ -829,7 +823,7 @@ class TestLoadTxt(LoadTxtBase):
assert_array_equal(x, a[:, 1])
# Testing with some crazy custom integer type
- class CrazyInt(object):
+ class CrazyInt:
def __index__(self):
return 1
@@ -1104,7 +1098,7 @@ class TestLoadTxt(LoadTxtBase):
with open(path, "wb") as f:
f.write(butf8)
with open(path, "rb") as f:
- x = np.loadtxt(f, encoding="UTF-8", dtype=np.unicode)
+ x = np.loadtxt(f, encoding="UTF-8", dtype=np.unicode_)
assert_array_equal(x, sutf8)
# test broken latin1 conversion people now rely on
with open(path, "rb") as f:
@@ -1161,7 +1155,7 @@ class TestLoadTxt(LoadTxtBase):
a = np.array([[1, 2, 3, 5], [4, 5, 7, 8], [2, 1, 4, 5]], int)
assert_array_equal(x, a)
-class Testfromregex(object):
+class Testfromregex:
def test_record(self):
c = TextIO()
c.write('1.312 foo\n1.534 bar\n4.444 qux')
@@ -1587,7 +1581,7 @@ M 33 21.99
with open(path, 'wb') as f:
f.write(b'skip,skip,2001-01-01' + utf8 + b',1.0,skip')
test = np.genfromtxt(path, delimiter=",", names=None, dtype=float,
- usecols=(2, 3), converters={2: np.unicode},
+ usecols=(2, 3), converters={2: np.compat.unicode},
encoding='UTF-8')
control = np.array([('2001-01-01' + utf8.decode('UTF-8'), 1.)],
dtype=[('', '|U11'), ('', float)])
@@ -2126,7 +2120,7 @@ M 33 21.99
ctl = np.array([
["test1", "testNonethe" + utf8.decode("UTF-8"), "test3"],
["test1", "testNonethe" + utf8.decode("UTF-8"), "test3"]],
- dtype=np.unicode)
+ dtype=np.unicode_)
assert_array_equal(test, ctl)
# test a mixed dtype
@@ -2169,7 +2163,7 @@ M 33 21.99
["norm1", "norm2", "norm3"],
["norm1", latin1, "norm3"],
["test1", "testNonethe" + utf8, "test3"]],
- dtype=np.unicode)
+ dtype=np.unicode_)
assert_array_equal(test, ctl)
def test_recfromtxt(self):
@@ -2344,15 +2338,14 @@ M 33 21.99
assert_(test.dtype['f0'] == float)
assert_(test.dtype['f1'] == np.int64)
- assert_(test.dtype['f2'] == np.integer)
+ assert_(test.dtype['f2'] == np.int_)
assert_allclose(test['f0'], 73786976294838206464.)
assert_equal(test['f1'], 17179869184)
assert_equal(test['f2'], 1024)
-@pytest.mark.skipif(Path is None, reason="No pathlib.Path")
-class TestPathUsage(object):
+class TestPathUsage:
# Test that pathlib.Path can be used
def test_loadtxt(self):
with temppath(suffix='.txt') as path:
@@ -2485,7 +2478,7 @@ def test_gzip_load():
# These next two classes encode the minimal API needed to save()/load() arrays.
# The `test_ducktyping` ensures they work correctly
-class JustWriter(object):
+class JustWriter:
def __init__(self, base):
self.base = base
@@ -2495,7 +2488,7 @@ class JustWriter(object):
def flush(self):
return self.base.flush()
-class JustReader(object):
+class JustReader:
def __init__(self, base):
self.base = base
diff --git a/numpy/lib/tests/test_mixins.py b/numpy/lib/tests/test_mixins.py
index 3dd5346b6..632058763 100644
--- a/numpy/lib/tests/test_mixins.py
+++ b/numpy/lib/tests/test_mixins.py
@@ -1,16 +1,10 @@
-from __future__ import division, absolute_import, print_function
-
import numbers
import operator
-import sys
import numpy as np
from numpy.testing import assert_, assert_equal, assert_raises
-PY2 = sys.version_info.major < 3
-
-
# NOTE: This class should be kept as an exact copy of the example from the
# docstring for NDArrayOperatorsMixin.
@@ -86,7 +80,6 @@ _ALL_BINARY_OPERATORS = [
operator.mul,
operator.truediv,
operator.floordiv,
- # TODO: test div on Python 2, only
operator.mod,
divmod,
pow,
@@ -98,7 +91,7 @@ _ALL_BINARY_OPERATORS = [
]
-class TestNDArrayOperatorsMixin(object):
+class TestNDArrayOperatorsMixin:
def test_array_like_add(self):
@@ -128,7 +121,7 @@ class TestNDArrayOperatorsMixin(object):
def test_opt_out(self):
- class OptOut(object):
+ class OptOut:
"""Object that opts out of __array_ufunc__."""
__array_ufunc__ = None
@@ -204,11 +197,10 @@ class TestNDArrayOperatorsMixin(object):
array_like = ArrayLike(array)
expected = ArrayLike(np.float64(5))
_assert_equal_type_and_value(expected, np.matmul(array_like, array))
- if not PY2:
- _assert_equal_type_and_value(
- expected, operator.matmul(array_like, array))
- _assert_equal_type_and_value(
- expected, operator.matmul(array, array_like))
+ _assert_equal_type_and_value(
+ expected, operator.matmul(array_like, array))
+ _assert_equal_type_and_value(
+ expected, operator.matmul(array, array_like))
def test_ufunc_at(self):
array = ArrayLike(np.array([1, 2, 3, 4]))
diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py
index b7261c63f..db563e30c 100644
--- a/numpy/lib/tests/test_nanfunctions.py
+++ b/numpy/lib/tests/test_nanfunctions.py
@@ -1,10 +1,8 @@
-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.lib.nanfunctions import _nan_mask, _replace_nan
from numpy.testing import (
assert_, assert_equal, assert_almost_equal, assert_no_warnings,
assert_raises, assert_array_equal, suppress_warnings
@@ -37,7 +35,7 @@ _ndat_zeros = np.array([[0.6244, 0.0, 0.2692, 0.0116, 0.0, 0.1170],
[0.1610, 0.0, 0.0, 0.1859, 0.3146, 0.0]])
-class TestNanFunctions_MinMax(object):
+class TestNanFunctions_MinMax:
nanfuncs = [np.nanmin, np.nanmax]
stdfuncs = [np.min, np.max]
@@ -171,7 +169,7 @@ class TestNanFunctions_MinMax(object):
assert_(issubclass(w[0].category, RuntimeWarning))
-class TestNanFunctions_ArgminArgmax(object):
+class TestNanFunctions_ArgminArgmax:
nanfuncs = [np.nanargmin, np.nanargmax]
@@ -233,7 +231,7 @@ class TestNanFunctions_ArgminArgmax(object):
assert_(res.shape == ())
-class TestNanFunctions_IntTypes(object):
+class TestNanFunctions_IntTypes:
int_types = (np.int8, np.int16, np.int32, np.int64, np.uint8,
np.uint16, np.uint32, np.uint64)
@@ -308,7 +306,7 @@ class TestNanFunctions_IntTypes(object):
assert_equal(np.nanstd(mat, ddof=1), tgt)
-class SharedNanFunctionsTestsMixin(object):
+class SharedNanFunctionsTestsMixin:
def test_mutation(self):
# Check that passed array is not modified.
ndat = _ndat.copy()
@@ -590,7 +588,7 @@ class TestNanFunctions_MeanVarStd(SharedNanFunctionsTestsMixin):
assert_(len(w) == 0)
-class TestNanFunctions_Median(object):
+class TestNanFunctions_Median:
def test_mutation(self):
# Check that passed array is not modified.
@@ -754,7 +752,7 @@ class TestNanFunctions_Median(object):
([np.nan] * i) + [-inf] * j)
-class TestNanFunctions_Percentile(object):
+class TestNanFunctions_Percentile:
def test_mutation(self):
# Check that passed array is not modified.
@@ -893,7 +891,7 @@ class TestNanFunctions_Percentile(object):
assert_equal(np.nanpercentile(megamat, perc, axis=(1, 2)).shape, (2, 3, 6))
-class TestNanFunctions_Quantile(object):
+class TestNanFunctions_Quantile:
# most of this is already tested by TestPercentile
def test_regression(self):
@@ -953,3 +951,30 @@ def test__nan_mask(arr, expected):
# for types that can't possibly contain NaN
if type(expected) is not np.ndarray:
assert actual is True
+
+
+def test__replace_nan():
+ """ Test that _replace_nan returns the original array if there are no
+ NaNs, not a copy.
+ """
+ for dtype in [np.bool, np.int32, np.int64]:
+ arr = np.array([0, 1], dtype=dtype)
+ result, mask = _replace_nan(arr, 0)
+ assert mask is None
+ # do not make a copy if there are no nans
+ assert result is arr
+
+ for dtype in [np.float32, np.float64]:
+ arr = np.array([0, 1], dtype=dtype)
+ result, mask = _replace_nan(arr, 2)
+ assert (mask == False).all()
+ # mask is not None, so we make a copy
+ assert result is not arr
+ assert_equal(result, arr)
+
+ arr_nan = np.array([0, 1, np.nan], dtype=dtype)
+ result_nan, mask_nan = _replace_nan(arr_nan, 2)
+ assert_equal(mask_nan, np.array([False, False, True]))
+ assert result_nan is not arr_nan
+ assert_equal(result_nan, np.array([0, 1, 2]))
+ assert np.isnan(arr_nan[-1])
diff --git a/numpy/lib/tests/test_packbits.py b/numpy/lib/tests/test_packbits.py
index 95a465c36..5b07f41c6 100644
--- a/numpy/lib/tests/test_packbits.py
+++ b/numpy/lib/tests/test_packbits.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import numpy as np
from numpy.testing import assert_array_equal, assert_equal, assert_raises
import pytest
diff --git a/numpy/lib/tests/test_polynomial.py b/numpy/lib/tests/test_polynomial.py
index 89759bd83..cd0b90dc4 100644
--- a/numpy/lib/tests/test_polynomial.py
+++ b/numpy/lib/tests/test_polynomial.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import numpy as np
from numpy.testing import (
assert_, assert_equal, assert_array_equal, assert_almost_equal,
@@ -7,7 +5,7 @@ from numpy.testing import (
)
-class TestPolynomial(object):
+class TestPolynomial:
def test_poly1d_str_and_repr(self):
p = np.poly1d([1., 2, 3])
assert_equal(repr(p), 'poly1d([1., 2., 3.])')
diff --git a/numpy/lib/tests/test_recfunctions.py b/numpy/lib/tests/test_recfunctions.py
index fa5f4dec2..2f3c14df3 100644
--- a/numpy/lib/tests/test_recfunctions.py
+++ b/numpy/lib/tests/test_recfunctions.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import pytest
import numpy as np
@@ -19,7 +17,7 @@ zip_descr = np.lib.recfunctions._zip_descr
zip_dtype = np.lib.recfunctions._zip_dtype
-class TestRecFunctions(object):
+class TestRecFunctions:
# Misc tests
def setup(self):
@@ -348,7 +346,7 @@ class TestRecFunctions(object):
assert_equal(b[()], 3)
-class TestRecursiveFillFields(object):
+class TestRecursiveFillFields:
# Test recursive_fill_fields.
def test_simple_flexible(self):
# Test recursive_fill_fields on flexible-array
@@ -371,7 +369,7 @@ class TestRecursiveFillFields(object):
assert_equal(test, control)
-class TestMergeArrays(object):
+class TestMergeArrays:
# Test merge_arrays
def setup(self):
@@ -504,7 +502,7 @@ class TestMergeArrays(object):
assert_equal(test, control)
-class TestAppendFields(object):
+class TestAppendFields:
# Test append_fields
def setup(self):
@@ -558,7 +556,7 @@ class TestAppendFields(object):
assert_equal(test, control)
-class TestStackArrays(object):
+class TestStackArrays:
# Test stack_arrays
def setup(self):
x = np.array([1, 2, ])
@@ -729,7 +727,7 @@ class TestStackArrays(object):
assert_equal(res.mask, expected.mask)
-class TestJoinBy(object):
+class TestJoinBy:
def setup(self):
self.a = np.array(list(zip(np.arange(10), np.arange(50, 60),
np.arange(100, 110))),
@@ -772,7 +770,6 @@ class TestJoinBy(object):
def test_join_subdtype(self):
# tests the bug in https://stackoverflow.com/q/44769632/102441
- from numpy.lib import recfunctions as rfn
foo = np.array([(1,)],
dtype=[('key', int)])
bar = np.array([(1, np.array([1,2,3]))],
@@ -895,7 +892,7 @@ class TestJoinBy(object):
assert_equal(res.dtype, expected_dtype)
-class TestJoinBy2(object):
+class TestJoinBy2:
@classmethod
def setup(cls):
cls.a = np.array(list(zip(np.arange(10), np.arange(50, 60),
@@ -960,7 +957,7 @@ class TestJoinBy2(object):
assert_equal(test.dtype, control.dtype)
assert_equal(test, control)
-class TestAppendFieldsObj(object):
+class TestAppendFieldsObj:
"""
Test append_fields with arrays containing objects
"""
diff --git a/numpy/lib/tests/test_regression.py b/numpy/lib/tests/test_regression.py
index 4cd812f5d..55df2a675 100644
--- a/numpy/lib/tests/test_regression.py
+++ b/numpy/lib/tests/test_regression.py
@@ -1,17 +1,13 @@
-from __future__ import division, absolute_import, print_function
-
import os
-import sys
import numpy as np
from numpy.testing import (
assert_, assert_equal, assert_array_equal, assert_array_almost_equal,
assert_raises, _assert_valid_refcount,
)
-from numpy.compat import unicode
-class TestRegression(object):
+class TestRegression:
def test_poly1d(self):
# Ticket #28
assert_equal(np.poly1d([1]) - np.poly1d([1, 0]),
@@ -183,7 +179,7 @@ class TestRegression(object):
# related to ticket #1405.
include_dirs = [np.get_include()]
for path in include_dirs:
- assert_(isinstance(path, (str, unicode)))
+ assert_(isinstance(path, str))
assert_(path != '')
def test_polyder_return_type(self):
@@ -208,10 +204,7 @@ class TestRegression(object):
def test_loadtxt_fields_subarrays(self):
# For ticket #1936
- if sys.version_info[0] >= 3:
- from io import StringIO
- else:
- from StringIO import StringIO
+ from io import StringIO
dt = [("a", 'u1', 2), ("b", 'u1', 2)]
x = np.loadtxt(StringIO("0 1 2 3"), dtype=dt)
diff --git a/numpy/lib/tests/test_shape_base.py b/numpy/lib/tests/test_shape_base.py
index 01ea028bb..fb7ba7874 100644
--- a/numpy/lib/tests/test_shape_base.py
+++ b/numpy/lib/tests/test_shape_base.py
@@ -1,7 +1,4 @@
-from __future__ import division, absolute_import, print_function
-
import numpy as np
-import warnings
import functools
import sys
import pytest
@@ -30,7 +27,7 @@ def _add_keepdims(func):
return wrapped
-class TestTakeAlongAxis(object):
+class TestTakeAlongAxis:
def test_argequivalent(self):
""" Test it translates from arg<func> to <func> """
from numpy.random import rand
@@ -82,7 +79,7 @@ class TestTakeAlongAxis(object):
assert_equal(actual.shape, (3, 2, 5))
-class TestPutAlongAxis(object):
+class TestPutAlongAxis:
def test_replace_max(self):
a_base = np.array([[10, 30, 20], [60, 40, 50]])
@@ -107,7 +104,7 @@ class TestPutAlongAxis(object):
assert_equal(take_along_axis(a, ai, axis=1), 20)
-class TestApplyAlongAxis(object):
+class TestApplyAlongAxis:
def test_simple(self):
a = np.ones((20, 10), 'd')
assert_array_equal(
@@ -273,14 +270,14 @@ class TestApplyAlongAxis(object):
assert_equal(type(actual[i]), type(expected[i]))
-class TestApplyOverAxes(object):
+class TestApplyOverAxes:
def test_simple(self):
a = np.arange(24).reshape(2, 3, 4)
aoa_a = apply_over_axes(np.sum, a, [0, 2])
assert_array_equal(aoa_a, np.array([[[60], [92], [124]]]))
-class TestExpandDims(object):
+class TestExpandDims:
def test_functionality(self):
s = (2, 3, 4, 5)
a = np.empty(s)
@@ -289,14 +286,26 @@ class TestExpandDims(object):
assert_(b.shape[axis] == 1)
assert_(np.squeeze(b).shape == s)
- def test_deprecations(self):
- # 2017-05-17, 1.13.0
+ def test_axis_tuple(self):
+ a = np.empty((3, 3, 3))
+ assert np.expand_dims(a, axis=(0, 1, 2)).shape == (1, 1, 1, 3, 3, 3)
+ assert np.expand_dims(a, axis=(0, -1, -2)).shape == (1, 3, 3, 3, 1, 1)
+ assert np.expand_dims(a, axis=(0, 3, 5)).shape == (1, 3, 3, 1, 3, 1)
+ assert np.expand_dims(a, axis=(0, -3, -5)).shape == (1, 1, 3, 1, 3, 3)
+
+ def test_axis_out_of_range(self):
s = (2, 3, 4, 5)
a = np.empty(s)
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- assert_warns(DeprecationWarning, expand_dims, a, -6)
- assert_warns(DeprecationWarning, expand_dims, a, 5)
+ assert_raises(np.AxisError, expand_dims, a, -6)
+ assert_raises(np.AxisError, expand_dims, a, 5)
+
+ a = np.empty((3, 3, 3))
+ assert_raises(np.AxisError, expand_dims, a, (0, -6))
+ assert_raises(np.AxisError, expand_dims, a, (0, 5))
+
+ def test_repeated_axis(self):
+ a = np.empty((3, 3, 3))
+ assert_raises(ValueError, expand_dims, a, axis=(1, 1))
def test_subclasses(self):
a = np.arange(10).reshape((2, 5))
@@ -308,7 +317,7 @@ class TestExpandDims(object):
assert_equal(expanded.mask.shape, (2, 1, 5))
-class TestArraySplit(object):
+class TestArraySplit:
def test_integer_0_split(self):
a = np.arange(10)
assert_raises(ValueError, array_split, a, 0)
@@ -442,7 +451,7 @@ class TestArraySplit(object):
compare_results(res, desired)
-class TestSplit(object):
+class TestSplit:
# The split function is essentially the same as array_split,
# except that it test if splitting will result in an
# equal split. Only test for this case.
@@ -458,7 +467,7 @@ class TestSplit(object):
assert_raises(ValueError, split, a, 3)
-class TestColumnStack(object):
+class TestColumnStack:
def test_non_iterable(self):
assert_raises(TypeError, column_stack, 1)
@@ -487,7 +496,7 @@ class TestColumnStack(object):
column_stack((np.arange(3) for _ in range(2)))
-class TestDstack(object):
+class TestDstack:
def test_non_iterable(self):
assert_raises(TypeError, dstack, 1)
@@ -526,7 +535,7 @@ class TestDstack(object):
# array_split has more comprehensive test of splitting.
# only do simple test on hsplit, vsplit, and dsplit
-class TestHsplit(object):
+class TestHsplit:
"""Only testing for integer splits.
"""
@@ -555,7 +564,7 @@ class TestHsplit(object):
compare_results(res, desired)
-class TestVsplit(object):
+class TestVsplit:
"""Only testing for integer splits.
"""
@@ -582,7 +591,7 @@ class TestVsplit(object):
compare_results(res, desired)
-class TestDsplit(object):
+class TestDsplit:
# Only testing for integer splits.
def test_non_iterable(self):
assert_raises(ValueError, dsplit, 1, 1)
@@ -615,7 +624,7 @@ class TestDsplit(object):
compare_results(res, desired)
-class TestSqueeze(object):
+class TestSqueeze:
def test_basic(self):
from numpy.random import rand
@@ -634,7 +643,7 @@ class TestSqueeze(object):
assert_equal(type(res), np.ndarray)
-class TestKron(object):
+class TestKron:
def test_return_type(self):
class myarray(np.ndarray):
__array_priority__ = 0.0
@@ -647,7 +656,7 @@ class TestKron(object):
assert_equal(type(kron(ma, a)), myarray)
-class TestTile(object):
+class TestTile:
def test_basic(self):
a = np.array([0, 1, 2])
b = [[1, 2], [3, 4]]
@@ -687,7 +696,7 @@ class TestTile(object):
assert_equal(large, klarge)
-class TestMayShareMemory(object):
+class TestMayShareMemory:
def test_basic(self):
d = np.ones((50, 60))
d2 = np.ones((30, 60, 6))
diff --git a/numpy/lib/tests/test_stride_tricks.py b/numpy/lib/tests/test_stride_tricks.py
index 85fcceedc..9d95eb9d0 100644
--- a/numpy/lib/tests/test_stride_tricks.py
+++ b/numpy/lib/tests/test_stride_tricks.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import numpy as np
from numpy.core._rational_tests import rational
from numpy.testing import (
@@ -65,8 +63,7 @@ def test_broadcast_kwargs():
x = np.arange(10)
y = np.arange(10)
- with assert_raises_regex(TypeError,
- r'broadcast_arrays\(\) got an unexpected keyword*'):
+ with assert_raises_regex(TypeError, 'got an unexpected keyword'):
broadcast_arrays(x, y, dtype='float64')
@@ -356,14 +353,12 @@ def as_strided_writeable():
class VerySimpleSubClass(np.ndarray):
def __new__(cls, *args, **kwargs):
- kwargs['subok'] = True
- return np.array(*args, **kwargs).view(cls)
+ return np.array(*args, subok=True, **kwargs).view(cls)
class SimpleSubClass(VerySimpleSubClass):
def __new__(cls, *args, **kwargs):
- kwargs['subok'] = True
- self = np.array(*args, **kwargs).view(cls)
+ self = np.array(*args, subok=True, **kwargs).view(cls)
self.info = 'simple'
return self
diff --git a/numpy/lib/tests/test_twodim_base.py b/numpy/lib/tests/test_twodim_base.py
index bb844e4bd..cce683bfe 100644
--- a/numpy/lib/tests/test_twodim_base.py
+++ b/numpy/lib/tests/test_twodim_base.py
@@ -1,8 +1,6 @@
"""Test functions for matrix module
"""
-from __future__ import division, absolute_import, print_function
-
from numpy.testing import (
assert_equal, assert_array_equal, assert_array_max_ulp,
assert_array_almost_equal, assert_raises, assert_
@@ -26,7 +24,7 @@ def get_mat(n):
return data
-class TestEye(object):
+class TestEye:
def test_basic(self):
assert_equal(eye(4),
array([[1, 0, 0, 0],
@@ -108,7 +106,7 @@ class TestEye(object):
assert mat_f.flags.f_contiguous
-class TestDiag(object):
+class TestDiag:
def test_vector(self):
vals = (100 * arange(5)).astype('l')
b = zeros((5, 5))
@@ -155,7 +153,7 @@ class TestDiag(object):
assert_raises(ValueError, diag, [[[1]]])
-class TestFliplr(object):
+class TestFliplr:
def test_basic(self):
assert_raises(ValueError, fliplr, ones(4))
a = get_mat(4)
@@ -168,7 +166,7 @@ class TestFliplr(object):
assert_equal(fliplr(a), b)
-class TestFlipud(object):
+class TestFlipud:
def test_basic(self):
a = get_mat(4)
b = a[::-1, :]
@@ -180,7 +178,7 @@ class TestFlipud(object):
assert_equal(flipud(a), b)
-class TestHistogram2d(object):
+class TestHistogram2d:
def test_simple(self):
x = array(
[0.41702200, 0.72032449, 1.1437481e-4, 0.302332573, 0.146755891])
@@ -298,7 +296,7 @@ class TestHistogram2d(object):
assert_(r, ((ShouldDispatch,), (xy, xy), dict(weights=s_d)))
-class TestTri(object):
+class TestTri:
def test_dtype(self):
out = array([[1, 0, 0],
[1, 1, 0],
@@ -436,7 +434,7 @@ def test_tril_indices():
[-10, -10, -10, -10, -10]]))
-class TestTriuIndices(object):
+class TestTriuIndices:
def test_triu_indices(self):
iu1 = triu_indices(4)
iu2 = triu_indices(4, k=2)
@@ -486,21 +484,21 @@ class TestTriuIndices(object):
[16, 17, 18, -1, -1]]))
-class TestTrilIndicesFrom(object):
+class TestTrilIndicesFrom:
def test_exceptions(self):
assert_raises(ValueError, tril_indices_from, np.ones((2,)))
assert_raises(ValueError, tril_indices_from, np.ones((2, 2, 2)))
# assert_raises(ValueError, tril_indices_from, np.ones((2, 3)))
-class TestTriuIndicesFrom(object):
+class TestTriuIndicesFrom:
def test_exceptions(self):
assert_raises(ValueError, triu_indices_from, np.ones((2,)))
assert_raises(ValueError, triu_indices_from, np.ones((2, 2, 2)))
# assert_raises(ValueError, triu_indices_from, np.ones((2, 3)))
-class TestVander(object):
+class TestVander:
def test_basic(self):
c = np.array([0, 1, -2, 3])
v = vander(c)
diff --git a/numpy/lib/tests/test_type_check.py b/numpy/lib/tests/test_type_check.py
index b3f114b92..3f4ca6309 100644
--- a/numpy/lib/tests/test_type_check.py
+++ b/numpy/lib/tests/test_type_check.py
@@ -1,7 +1,4 @@
-from __future__ import division, absolute_import, print_function
-
import numpy as np
-from numpy.compat import long
from numpy.testing import (
assert_, assert_equal, assert_array_equal, assert_raises
)
@@ -15,7 +12,7 @@ def assert_all(x):
assert_(np.all(x), x)
-class TestCommonType(object):
+class TestCommonType:
def test_basic(self):
ai32 = np.array([[1, 2], [3, 4]], dtype=np.int32)
af16 = np.array([[1, 2], [3, 4]], dtype=np.float16)
@@ -31,7 +28,7 @@ class TestCommonType(object):
assert_(common_type(acd) == np.cdouble)
-class TestMintypecode(object):
+class TestMintypecode:
def test_default_1(self):
for itype in '1bcsuwil':
@@ -81,18 +78,17 @@ class TestMintypecode(object):
assert_equal(mintypecode('idD'), 'D')
-class TestIsscalar(object):
+class TestIsscalar:
def test_basic(self):
assert_(np.isscalar(3))
assert_(not np.isscalar([3]))
assert_(not np.isscalar((3,)))
assert_(np.isscalar(3j))
- assert_(np.isscalar(long(10)))
assert_(np.isscalar(4.0))
-class TestReal(object):
+class TestReal:
def test_real(self):
y = np.random.rand(10,)
@@ -123,7 +119,7 @@ class TestReal(object):
assert_(not isinstance(out, np.ndarray))
-class TestImag(object):
+class TestImag:
def test_real(self):
y = np.random.rand(10,)
@@ -154,7 +150,7 @@ class TestImag(object):
assert_(not isinstance(out, np.ndarray))
-class TestIscomplex(object):
+class TestIscomplex:
def test_fail(self):
z = np.array([-1, 0, 1])
@@ -167,7 +163,7 @@ class TestIscomplex(object):
assert_array_equal(res, [1, 0, 0])
-class TestIsreal(object):
+class TestIsreal:
def test_pass(self):
z = np.array([-1, 0, 1j])
@@ -180,7 +176,7 @@ class TestIsreal(object):
assert_array_equal(res, [0, 1, 1])
-class TestIscomplexobj(object):
+class TestIscomplexobj:
def test_basic(self):
z = np.array([-1, 0, 1])
@@ -209,7 +205,7 @@ class TestIscomplexobj(object):
# (pandas.core.dtypes)
class PdComplex(np.complex128):
pass
- class PdDtype(object):
+ class PdDtype:
name = 'category'
names = None
type = PdComplex
@@ -233,7 +229,7 @@ class TestIscomplexobj(object):
assert_(iscomplexobj(a))
-class TestIsrealobj(object):
+class TestIsrealobj:
def test_basic(self):
z = np.array([-1, 0, 1])
assert_(isrealobj(z))
@@ -241,7 +237,7 @@ class TestIsrealobj(object):
assert_(not isrealobj(z))
-class TestIsnan(object):
+class TestIsnan:
def test_goodvalues(self):
z = np.array((-1., 0., 1.))
@@ -271,7 +267,7 @@ class TestIsnan(object):
assert_all(np.isnan(np.array(0+0j)/0.) == 1)
-class TestIsfinite(object):
+class TestIsfinite:
# Fixme, wrong place, isfinite now ufunc
def test_goodvalues(self):
@@ -302,7 +298,7 @@ class TestIsfinite(object):
assert_all(np.isfinite(np.array(1+1j)/0.) == 0)
-class TestIsinf(object):
+class TestIsinf:
# Fixme, wrong place, isinf now ufunc
def test_goodvalues(self):
@@ -331,7 +327,7 @@ class TestIsinf(object):
assert_all(np.isinf(np.array((0.,))/0.) == 0)
-class TestIsposinf(object):
+class TestIsposinf:
def test_generic(self):
with np.errstate(divide='ignore', invalid='ignore'):
@@ -341,7 +337,7 @@ class TestIsposinf(object):
assert_(vals[2] == 1)
-class TestIsneginf(object):
+class TestIsneginf:
def test_generic(self):
with np.errstate(divide='ignore', invalid='ignore'):
@@ -351,7 +347,7 @@ class TestIsneginf(object):
assert_(vals[2] == 0)
-class TestNanToNum(object):
+class TestNanToNum:
def test_generic(self):
with np.errstate(divide='ignore', invalid='ignore'):
@@ -456,7 +452,7 @@ class TestNanToNum(object):
assert_equal(type(vals), np.ndarray)
-class TestRealIfClose(object):
+class TestRealIfClose:
def test_basic(self):
a = np.random.rand(10)
@@ -469,7 +465,7 @@ class TestRealIfClose(object):
assert_all(isrealobj(b))
-class TestArrayConversion(object):
+class TestArrayConversion:
def test_asfarray(self):
a = asfarray(np.array([1, 2, 3]))
diff --git a/numpy/lib/tests/test_ufunclike.py b/numpy/lib/tests/test_ufunclike.py
index 0f06876a1..c280b6969 100644
--- a/numpy/lib/tests/test_ufunclike.py
+++ b/numpy/lib/tests/test_ufunclike.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import numpy as np
import numpy.core as nx
import numpy.lib.ufunclike as ufl
@@ -8,7 +6,7 @@ from numpy.testing import (
)
-class TestUfunclike(object):
+class TestUfunclike:
def test_isposinf(self):
a = nx.array([nx.inf, -nx.inf, nx.nan, 0.0, 3.0, -3.0])
@@ -21,7 +19,7 @@ class TestUfunclike(object):
assert_equal(res, tgt)
assert_equal(out, tgt)
- a = a.astype(np.complex)
+ a = a.astype(np.complex_)
with assert_raises(TypeError):
ufl.isposinf(a)
@@ -36,7 +34,7 @@ class TestUfunclike(object):
assert_equal(res, tgt)
assert_equal(out, tgt)
- a = a.astype(np.complex)
+ a = a.astype(np.complex_)
with assert_raises(TypeError):
ufl.isneginf(a)
diff --git a/numpy/lib/tests/test_utils.py b/numpy/lib/tests/test_utils.py
index 9673a05fa..c96bf795a 100644
--- a/numpy/lib/tests/test_utils.py
+++ b/numpy/lib/tests/test_utils.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import inspect
import sys
import pytest
@@ -9,10 +7,7 @@ from numpy.testing import assert_, assert_equal, assert_raises_regex
from numpy.lib import deprecate
import numpy.lib.utils as utils
-if sys.version_info[0] >= 3:
- from io import StringIO
-else:
- from StringIO import StringIO
+from io import StringIO
@pytest.mark.skipif(sys.flags.optimize == 2, reason="Python running -OO")
@@ -102,7 +97,7 @@ def test_safe_eval_nameconstant():
utils.safe_eval('None')
-class TestByteBounds(object):
+class TestByteBounds:
def test_byte_bounds(self):
# pointer difference matches size * itemsize
diff --git a/numpy/lib/twodim_base.py b/numpy/lib/twodim_base.py
index f45392188..320a24856 100644
--- a/numpy/lib/twodim_base.py
+++ b/numpy/lib/twodim_base.py
@@ -1,18 +1,16 @@
""" Basic functions for manipulating 2d arrays
"""
-from __future__ import division, absolute_import, print_function
-
import functools
from numpy.core.numeric import (
- absolute, asanyarray, arange, zeros, greater_equal, multiply, ones,
+ asanyarray, arange, zeros, greater_equal, multiply, ones,
asarray, where, int8, int16, int32, int64, empty, promote_types, diagonal,
nonzero
)
from numpy.core.overrides import set_module
from numpy.core import overrides
-from numpy.core import iinfo, transpose
+from numpy.core import iinfo
__all__ = [
diff --git a/numpy/lib/type_check.py b/numpy/lib/type_check.py
index 586824743..2a2982ab3 100644
--- a/numpy/lib/type_check.py
+++ b/numpy/lib/type_check.py
@@ -1,7 +1,6 @@
"""Automatically adapted for numpy Sep 19, 2005 by convertcode.py
"""
-from __future__ import division, absolute_import, print_function
import functools
import warnings
@@ -68,16 +67,14 @@ def mintypecode(typechars, typeset='GDFgdf', default='d'):
'G'
"""
- typecodes = [(isinstance(t, str) and t) or asarray(t).dtype.char
- for t in typechars]
- intersection = [t for t in typecodes if t in typeset]
+ typecodes = ((isinstance(t, str) and t) or asarray(t).dtype.char
+ for t in typechars)
+ intersection = set(t for t in typecodes if t in typeset)
if not intersection:
return default
if 'F' in intersection and 'd' in intersection:
return 'D'
- l = [(_typecodes_by_elsize.index(t), t) for t in intersection]
- l.sort()
- return l[0][1]
+ return min(intersection, key=_typecodes_by_elsize.index)
def _asfarray_dispatcher(a, dtype=None):
@@ -495,7 +492,8 @@ def _real_if_close_dispatcher(a, tol=None):
@array_function_dispatch(_real_if_close_dispatcher)
def real_if_close(a, tol=100):
"""
- If complex input returns a real array if complex parts are close to zero.
+ If input is complex with all imaginary parts close to zero, return
+ real parts.
"Close to zero" is defined as `tol` * (machine epsilon of the type for
`a`).
@@ -530,10 +528,10 @@ def real_if_close(a, tol=100):
>>> np.finfo(float).eps
2.2204460492503131e-16 # may vary
- >>> np.real_if_close([2.1 + 4e-14j], tol=1000)
- array([2.1])
- >>> np.real_if_close([2.1 + 4e-13j], tol=1000)
- array([2.1+4.e-13j])
+ >>> np.real_if_close([2.1 + 4e-14j, 5.2 + 3e-15j], tol=1000)
+ array([2.1, 5.2])
+ >>> np.real_if_close([2.1 + 4e-13j, 5.2 + 3e-15j], tol=1000)
+ array([2.1+4.e-13j, 5.2 + 3e-15j])
"""
a = asanyarray(a)
diff --git a/numpy/lib/ufunclike.py b/numpy/lib/ufunclike.py
index 96fd5b319..8512669c2 100644
--- a/numpy/lib/ufunclike.py
+++ b/numpy/lib/ufunclike.py
@@ -3,8 +3,6 @@ Module of functions that are like ufuncs in acting on arrays and optionally
storing results in an output array.
"""
-from __future__ import division, absolute_import, print_function
-
__all__ = ['fix', 'isneginf', 'isposinf']
import numpy.core.numeric as nx
@@ -85,13 +83,20 @@ def fix(x, out=None):
----------
x : array_like
An array of floats to be rounded
- y : ndarray, optional
- Output array
+ out : ndarray, optional
+ A location into which the result is stored. If provided, it must have
+ a shape that the input broadcasts to. If not provided or None, a
+ freshly-allocated array is returned.
Returns
-------
out : ndarray of floats
- The array of rounded numbers
+ A float array with the same dimensions as the input.
+ If second argument is not supplied then a float array is returned
+ with the rounded values.
+
+ If a second argument is supplied the result is stored there.
+ The return value `out` is then a reference to that array.
See Also
--------
@@ -129,8 +134,10 @@ def isposinf(x, out=None):
----------
x : array_like
The input array.
- y : array_like, optional
- A boolean array with the same shape as `x` to store the result.
+ out : array_like, optional
+ A location into which the result is stored. If provided, it must have a
+ shape that the input broadcasts to. If not provided or None, a
+ freshly-allocated boolean array is returned.
Returns
-------
@@ -199,8 +206,9 @@ def isneginf(x, out=None):
x : array_like
The input array.
out : array_like, optional
- A boolean array with the same shape and type as `x` to store the
- result.
+ A location into which the result is stored. If provided, it must have a
+ shape that the input broadcasts to. If not provided or None, a
+ freshly-allocated boolean array is returned.
Returns
-------
diff --git a/numpy/lib/user_array.py b/numpy/lib/user_array.py
index f1510a7b1..0e96b477e 100644
--- a/numpy/lib/user_array.py
+++ b/numpy/lib/user_array.py
@@ -5,18 +5,15 @@ Try to inherit from the ndarray instead of using this class as this is not
complete.
"""
-from __future__ import division, absolute_import, print_function
-
from numpy.core import (
array, asarray, absolute, add, subtract, multiply, divide,
remainder, power, left_shift, right_shift, bitwise_and, bitwise_or,
bitwise_xor, invert, less, less_equal, not_equal, equal, greater,
greater_equal, shape, reshape, arange, sin, sqrt, transpose
)
-from numpy.compat import long
-class container(object):
+class container:
"""
container(data, dtype=None, copy=True)
@@ -198,9 +195,6 @@ class container(object):
def __int__(self):
return self._scalarfunc(int)
- def __long__(self):
- return self._scalarfunc(long)
-
def __hex__(self):
return self._scalarfunc(hex)
@@ -233,6 +227,10 @@ class container(object):
""
return self.array.tostring()
+ def tobytes(self):
+ ""
+ return self.array.tobytes()
+
def byteswap(self):
""
return self._rc(self.array.byteswap())
diff --git a/numpy/lib/utils.py b/numpy/lib/utils.py
index 3c71d2a7c..f233c7240 100644
--- a/numpy/lib/utils.py
+++ b/numpy/lib/utils.py
@@ -1,5 +1,3 @@
-from __future__ import division, absolute_import, print_function
-
import os
import sys
import types
@@ -55,7 +53,7 @@ def _set_function_name(func, name):
return func
-class _Deprecate(object):
+class _Deprecate:
"""
Decorator class to deprecate old functions.
@@ -607,41 +605,6 @@ def info(object=None, maxwidth=76, output=sys.stdout, toplevel='numpy'):
)
print(" %s -- %s" % (meth, methstr), file=output)
- elif (sys.version_info[0] < 3
- and isinstance(object, types.InstanceType)):
- # check for __call__ method
- # types.InstanceType is the type of the instances of oldstyle classes
- print("Instance of class: ", object.__class__.__name__, file=output)
- print(file=output)
- if hasattr(object, '__call__'):
- arguments = formatargspec(
- *getargspec(object.__call__.__func__)
- )
- arglist = arguments.split(', ')
- if len(arglist) > 1:
- arglist[1] = "("+arglist[1]
- arguments = ", ".join(arglist[1:])
- else:
- arguments = "()"
-
- if hasattr(object, 'name'):
- name = "%s" % object.name
- else:
- name = "<name>"
- if len(name+arguments) > maxwidth:
- argstr = _split_line(name, arguments, maxwidth)
- else:
- argstr = name + arguments
-
- print(" " + argstr + "\n", file=output)
- doc = inspect.getdoc(object.__call__)
- if doc is not None:
- print(inspect.getdoc(object.__call__), file=output)
- print(inspect.getdoc(object), file=output)
-
- else:
- print(inspect.getdoc(object), file=output)
-
elif inspect.ismethod(object):
name = object.__name__
arguments = formatargspec(
@@ -869,15 +832,10 @@ def _lookfor_generate_cache(module, import_modules, regenerate):
or newly generated.
"""
- global _lookfor_caches
# Local import to speed up numpy's import time.
import inspect
- if sys.version_info[0] >= 3:
- # In Python3 stderr, stdout are text files.
- from io import StringIO
- else:
- from StringIO import StringIO
+ from io import StringIO
if module is None:
module = "numpy"