From a073198864e18dab7fc78653a69175fa6c76e345 Mon Sep 17 00:00:00 2001 From: Antony Lee Date: Thu, 21 Jan 2016 17:17:38 -0800 Subject: [PATCH] MAINT: np.full defaults to the filler's dtype. --- doc/release/1.12.0-notes.rst | 2 + numpy/core/numeric.py | 13 +++---- numpy/core/tests/test_deprecations.py | 11 ------ numpy/core/tests/test_numeric.py | 55 +++++++++++++-------------- 4 files changed, 34 insertions(+), 47 deletions(-) diff --git a/doc/release/1.12.0-notes.rst b/doc/release/1.12.0-notes.rst index f555731561bd..ce01e89c1f8b 100644 --- a/doc/release/1.12.0-notes.rst +++ b/doc/release/1.12.0-notes.rst @@ -84,6 +84,8 @@ more explanation. FutureWarning to changed behavior ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +* ``np.full`` now returns an array of the fill-value's dtype if no dtype is + given, instead of defaulting to float. C API ~~~~~ diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py index 551d63a01685..7f12068553a3 100644 --- a/numpy/core/numeric.py +++ b/numpy/core/numeric.py @@ -262,9 +262,8 @@ def full(shape, fill_value, dtype=None, order='C'): fill_value : scalar Fill value. dtype : data-type, optional - The desired data-type for the array, e.g., `np.int8`. Default - is `float`, but will change to `np.array(fill_value).dtype` in a - future release. + The desired data-type for the array The default, `None`, means + `np.array(fill_value).dtype`. order : {'C', 'F'}, optional Whether to store multidimensional data in C- or Fortran-contiguous (row- or column-wise) order in memory. @@ -289,16 +288,14 @@ def full(shape, fill_value, dtype=None, order='C'): >>> np.full((2, 2), np.inf) array([[ inf, inf], [ inf, inf]]) - >>> np.full((2, 2), 10, dtype=np.int) + >>> np.full((2, 2), 10) array([[10, 10], [10, 10]]) """ + if dtype is None: + dtype = array(fill_value).dtype a = empty(shape, dtype, order) - if dtype is None and array(fill_value).dtype != a.dtype: - warnings.warn( - "in the future, full({0}, {1!r}) will return an array of {2!r}". - format(shape, fill_value, array(fill_value).dtype), FutureWarning) multiarray.copyto(a, fill_value, casting='unsafe') return a diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py index 7d12ed4665f3..e6d3cd261b8a 100644 --- a/numpy/core/tests/test_deprecations.py +++ b/numpy/core/tests/test_deprecations.py @@ -485,17 +485,6 @@ def test_simple(self): arr.__getitem__, (slice(None), index)) -class TestFullDefaultDtype(object): - """np.full defaults to float when dtype is not set. In the future, it will - use the fill value's dtype. - """ - - def test_full_default_dtype(self): - assert_warns(FutureWarning, np.full, 1, 1) - assert_warns(FutureWarning, np.full, 1, None) - assert_no_warnings(np.full, 1, 1, float) - - class TestDatetime64Timezone(_DeprecationTestCase): """Parsing of datetime64 with timezones deprecated in 1.11.0, because datetime64 is now timezone naive rather than UTC only. diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index a43ad96b7729..0040f3a25428 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -1847,49 +1847,48 @@ def test_scalars(self): class TestCreationFuncs(TestCase): - # Test ones, zeros, empty and filled + # Test ones, zeros, empty and full. def setUp(self): - self.dtypes = ('b', 'i', 'u', 'f', 'c', 'S', 'a', 'U', 'V') + dtypes = {np.dtype(tp) for tp in itertools.chain(*np.sctypes.values())} + # void, bytes, str + variable_sized = {tp for tp in dtypes if tp.str.endswith('0')} + self.dtypes = sorted(dtypes - variable_sized | + {np.dtype(tp.str.replace("0", str(i))) + for tp in variable_sized for i in range(1, 10)}, + key=lambda dtype: dtype.str) self.orders = {'C': 'c_contiguous', 'F': 'f_contiguous'} self.ndims = 10 def check_function(self, func, fill_value=None): - par = ( - (0, 1, 2), - range(self.ndims), - self.orders, - self.dtypes, - 2**np.arange(9) - ) + par = ((0, 1, 2), + range(self.ndims), + self.orders, + self.dtypes) fill_kwarg = {} if fill_value is not None: fill_kwarg = {'fill_value': fill_value} with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) - for size, ndims, order, type, bytes in itertools.product(*par): + for size, ndims, order, dtype in itertools.product(*par): shape = ndims * [size] - try: - dtype = np.dtype('{0}{1}'.format(type, bytes)) - except TypeError: # dtype combination does not exist + + # do not fill void type + if fill_kwarg and dtype.str.startswith('|V'): continue - else: - # do not fill void type - if fill_value is not None and type in 'V': - continue - arr = func(shape, order=order, dtype=dtype, - **fill_kwarg) + arr = func(shape, order=order, dtype=dtype, + **fill_kwarg) - assert_(arr.dtype == dtype) - assert_(getattr(arr.flags, self.orders[order])) + assert_equal(arr.dtype, dtype) + assert_(getattr(arr.flags, self.orders[order])) - if fill_value is not None: - if dtype.str.startswith('|S'): - val = str(fill_value) - else: - val = fill_value - assert_equal(arr, dtype.type(val)) + if fill_value is not None: + if dtype.str.startswith('|S'): + val = str(fill_value) + else: + val = fill_value + assert_equal(arr, dtype.type(val)) def test_zeros(self): self.check_function(np.zeros) @@ -1900,7 +1899,7 @@ def test_ones(self): def test_empty(self): self.check_function(np.empty) - def test_filled(self): + def test_full(self): self.check_function(np.full, 0) self.check_function(np.full, 1)