diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2019-03-11 23:49:54 -0700 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2019-03-16 10:04:58 -0700 |
commit | 0764929543c85decde9d664367dbf7d8f137fe1f (patch) | |
tree | 54901a64ac4fec1a52ab48808767309fc7ce4cab /numpy/polynomial/polyutils.py | |
parent | 5646b46341240ddecc1692d21610e49125b4b16e (diff) | |
download | numpy-0764929543c85decde9d664367dbf7d8f137fe1f.tar.gz |
DEP: polynomial: Be stricter about integral arguments
This changes the behavior for:
* The `deg` and `axis` arguments of `<type>der`
* The `deg` and `axis` arguments of `<type>int`
* The `deg` argument of `<type>gauss`
* The `deg` argument of `<type>vander2d`
* The `deg` argument of `<type>vander3d`
The old behavior was:
* Raise `ValueError` if the argument is a float, but not an integral one
* Allow a float like `1.0` to mean `1`.
This is inconsistent with most other integer-accepting APIs in numpy, which require these to be actual integers, and raise TypeError when they are not.
The new behavior is:
* Raise `TypeError` if the argument is a float, but not an integral one
* Emit a `DeprecationWarning` if a float like `1.0` is passed, continuing to allow it its old meaning.
Diffstat (limited to 'numpy/polynomial/polyutils.py')
-rw-r--r-- | numpy/polynomial/polyutils.py | 58 |
1 files changed, 48 insertions, 10 deletions
diff --git a/numpy/polynomial/polyutils.py b/numpy/polynomial/polyutils.py index fb3ebe44a..1a73f47d8 100644 --- a/numpy/polynomial/polyutils.py +++ b/numpy/polynomial/polyutils.py @@ -45,6 +45,8 @@ Functions """ from __future__ import division, absolute_import, print_function +import operator + import numpy as np __all__ = [ @@ -423,11 +425,10 @@ def _vander2d(vander_f, x, y, deg): x, y, deg : See the ``<type>vander2d`` functions for more detail """ - ideg = [int(d) for d in deg] - is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)] - if is_valid != [1, 1]: - raise ValueError("degrees must be non-negative integers") - degx, degy = ideg + degx, degy = [ + _deprecate_as_int(d, "degrees") + for d in deg + ] x, y = np.array((x, y), copy=0) + 0.0 vx = vander_f(x, degx) @@ -447,11 +448,10 @@ def _vander3d(vander_f, x, y, z, deg): x, y, z, deg : See the ``<type>vander3d`` functions for more detail """ - ideg = [int(d) for d in deg] - is_valid = [id == d and id >= 0 for id, d in zip(ideg, deg)] - if is_valid != [1, 1, 1]: - raise ValueError("degrees must be non-negative integers") - degx, degy, degz = ideg + degx, degy, degz = [ + _deprecate_as_int(d, "degrees") + for d in deg + ] x, y, z = np.array((x, y, z), copy=0) + 0.0 vx = vander_f(x, degx) @@ -688,3 +688,41 @@ def _fit(vander_f, x, y, deg, rcond=None, full=False, w=None): return c, [resids, rank, s, rcond] else: return c + + +def _deprecate_as_int(x, desc): + """ + Like `operator.index`, but emits a deprecation warning when passed a float + + Parameters + ---------- + x : int-like, or float with integral value + Value to interpret as an integer + desc : str + description to include in any error message + + Raises + ------ + TypeError : if x is a non-integral float or non-numeric + DeprecationWarning : if x is an integral float + """ + try: + return operator.index(x) + except TypeError: + # Numpy 1.17.0, 2019-03-11 + try: + ix = int(x) + except TypeError: + pass + else: + if ix == x: + warnings.warn( + "In future, this will raise TypeError, as {} will need to " + "be an integer not just an integral float." + .format(desc), + DeprecationWarning, + stacklevel=3 + ) + return ix + + raise TypeError("{} must be an integer".format(desc)) |