diff --git a/tensorflow/python/framework/ops.py b/tensorflow/python/framework/ops.py index f93ab6190f7..d0884de2a6e 100644 --- a/tensorflow/python/framework/ops.py +++ b/tensorflow/python/framework/ops.py @@ -780,12 +780,6 @@ class _EagerTensorBase(Tensor): return maybe_arr.__index__() return int(maybe_arr) # Must be a NumPy scalar. - def __array__(self, dtype=None): - # This is only called if the buffer interface conversion failed. - # Remove once numpy/numpy#13507 is merged and released or py_function - # creates EagerTensors with a non-nullptr context. - return np.asarray(self.numpy(), dtype=dtype) - def __format__(self, format_spec): return self._numpy().__format__(format_spec) diff --git a/tensorflow/python/framework/tensor_util.py b/tensorflow/python/framework/tensor_util.py index d6d103815f8..e9bda38652a 100644 --- a/tensorflow/python/framework/tensor_util.py +++ b/tensorflow/python/framework/tensor_util.py @@ -369,6 +369,21 @@ def _AssertCompatible(values, dtype): (dtype.name, repr(mismatch), type(mismatch).__name__)) +def _is_array_like(obj): # pylint: disable=invalid-name + """Check if a given object is array-like.""" + # TODO(slebedev): an object could also implement C-level array interface. + if (callable(getattr(obj, "__array__", None)) or + isinstance(getattr(obj, "__array_interface__", None), dict)): + return True + + try: + memoryview(obj) + except TypeError: + return False + else: + return not isinstance(obj, bytes) + + # pylint: disable=invalid-name @tf_export("make_tensor_proto") def make_tensor_proto(values, dtype=None, shape=None, verify_shape=False, @@ -441,21 +456,15 @@ def make_tensor_proto(values, dtype=None, shape=None, verify_shape=False, dtypes.qint32 ]) + if _is_array_like(values): + values = np.asarray(values) + # We first convert value to a numpy array or scalar. if isinstance(values, (np.ndarray, np.generic)): - if dtype: + if dtype and dtype.is_numpy_compatible: nparray = values.astype(dtype.as_numpy_dtype) else: nparray = values - elif callable(getattr(values, "__array__", None)) or isinstance( - getattr(values, "__array_interface__", None), dict): - # If a class has the __array__ method, or __array_interface__ dict, then it - # is possible to convert to numpy array. - nparray = np.asarray(values, dtype=dtype) - - # This is the preferred way to create an array from the object, so replace - # the `values` with the array so that _FlattenToStrings is not run. - values = nparray else: if values is None: raise ValueError("None values not supported.")