From 4f8e93a3b26f15bb96d86ee05d672b51cda1e935 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Tue, 10 Nov 2015 14:25:34 +1300 Subject: [PATCH 1/3] Let linspace accept input that has an array_interface but is not otherwise a numpy or python type. --- numpy/core/function_base.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/numpy/core/function_base.py b/numpy/core/function_base.py index 05fea557a5ea..5070608b7446 100644 --- a/numpy/core/function_base.py +++ b/numpy/core/function_base.py @@ -87,8 +87,10 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None): div = (num - 1) if endpoint else num # Convert float/complex array scalars to float, gh-3504 - start = start * 1. - stop = stop * 1. + # Make sure one can use variables that have an __array_interface__, gh-6634 + from numpy import asarray + start = asarray(start) * 1. + stop = asarray(stop) * 1. dt = result_type(start, stop, float(num)) if dtype is None: From 072e8a5572f0104c4b28828cb1404bed8682e951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bissey?= Date: Wed, 11 Nov 2015 21:02:08 +1300 Subject: [PATCH 2/3] Use asanyarray instead of asarray --- numpy/core/function_base.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/numpy/core/function_base.py b/numpy/core/function_base.py index 5070608b7446..0e2bdc693bfd 100644 --- a/numpy/core/function_base.py +++ b/numpy/core/function_base.py @@ -3,7 +3,7 @@ __all__ = ['logspace', 'linspace', 'may_share_memory'] from . import numeric as _nx -from .numeric import result_type, NaN, shares_memory, MAY_SHARE_BOUNDS, TooHardError +from .numeric import result_type, NaN, shares_memory, MAY_SHARE_BOUNDS, TooHardError, asanyarray def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None): @@ -88,9 +88,8 @@ def linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None): # Convert float/complex array scalars to float, gh-3504 # Make sure one can use variables that have an __array_interface__, gh-6634 - from numpy import asarray - start = asarray(start) * 1. - stop = asarray(stop) * 1. + start = asanyarray(start) * 1. + stop = asanyarray(stop) * 1. dt = result_type(start, stop, float(num)) if dtype is None: From 12ea33a6fe73f6597cc301ebcb23cb44644addd5 Mon Sep 17 00:00:00 2001 From: "Erik M. Bray" Date: Mon, 29 Aug 2016 19:06:38 +0200 Subject: [PATCH 3/3] Adds a regression test that demonstrates the issue. --- numpy/core/tests/test_function_base.py | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/numpy/core/tests/test_function_base.py b/numpy/core/tests/test_function_base.py index 0fabb25886e8..8b4f5b4ac6d3 100644 --- a/numpy/core/tests/test_function_base.py +++ b/numpy/core/tests/test_function_base.py @@ -260,6 +260,42 @@ def test_subclass(self): assert type(ls) is PhysicalQuantity2 assert_equal(ls, linspace(0.0, 1.0, 1)) + def test_array_interface(self): + # Regression test for https://github.com/numpy/numpy/pull/6659 + # Ensure that start/stop can be objects that implement + # __array_interface__ and are convertible to numeric scalars + + class Arrayish(object): + """ + A generic object that supports the __array_interface__ and hence + can in principle be converted to a numeric scalar, but is not + otherwise recognized as numeric, but also happens to support + multiplication by floats. + + Data should be an object that implements the buffer interface, + and contains at least 4 bytes. + """ + + def __init__(self, data): + self._data = data + + @property + def __array_interface__(self): + # Ideally should be `'shape': ()` but the current interface + # does not allow that + return {'shape': (1,), 'typestr': '