Status InferShapeAndType(PyObject* obj, ConverterState* state) {
  std::vector<Safe_PyObjectPtr> refs_to_clean;
  while (true) {
    // Convert any zero dimensional numpy arrays to scalars first of all.
    // We also have to make sure a reference to the safe_obj is kept.
    obj = ZeroDimArrayToScalar(obj, state);
    refs_to_clean.push_back(make_safe(obj));
    // We test strings first, in case a string is considered a sequence.
    if (IsPyString(obj)) {
      state->inferred_dtype = DT_STRING;
    } else if (PySequence_Check(obj)) {
      auto length = PySequence_Length(obj);
      if (length > 0) {
        state->inferred_shape.AddDim(length);
        PyObject* elem = nullptr;
        TF_RETURN_IF_ERROR(SampleElementFromSequence(obj, &elem));
        obj = elem;
        refs_to_clean.push_back(make_safe(obj));
        continue;
      } else if (length == 0) {
        state->inferred_shape.AddDim(length);
        state->inferred_dtype = DT_INVALID;  // Invalid dtype for empty tensors.
      } else {
        // The sequence does not have a valid length (PySequence_Length < 0).
        if (PyErr_Occurred()) {
          // PySequence_Length failed and set an exception. Fetch the message
          // and convert it to a failed status.
          return errors::InvalidArgument(PyExceptionFetch());
        } else {
          // This is almost certainly dead code: PySequence_Length failed but
          // did not set an exception.
          return errors::InvalidArgument(
              "Attempted to convert an invalid sequence to a Tensor.");
        }
      }
    } else if (IsPyDouble(obj)) {
      state->inferred_dtype = DT_DOUBLE;
    } else if (IsNumpyHalf(obj)) {
      state->inferred_dtype = DT_HALF;
    } else if (IsPyFloat(obj)) {
      state->inferred_dtype = DT_FLOAT;
    } else if (PyBool_Check(obj) || PyIsInstance(obj, &PyBoolArrType_Type)) {
      // Have to test for bool before int, since IsInt(True/False) == true.
      state->inferred_dtype = DT_BOOL;
    } else if (IsPyInt(obj)) {
      state->inferred_dtype = DT_INT64;
    } else if (IsPyDimension(obj)) {
      state->inferred_dtype = DT_INT64;
    } else if (PyComplex_Check(obj) ||
               PyIsInstance(obj, &PyComplexFloatingArrType_Type)) {  // NumPy
      state->inferred_dtype = DT_COMPLEX128;
    } else {
      return errors::InvalidArgument("Attempt to convert a value (",
                                     PyRepr(obj),
                                     ") with an unsupported type (",
                                     PyRepr(PyType(obj)), ") to a Tensor.");
    }
    return Status::OK();
  }
}
Status InferShapeAndType(PyObject* obj, ConverterState* state) {
  std::vector<Safe_PyObjectPtr> refs_to_clean;
  while (true) {
     
     
    obj = ZeroDimArrayToScalar(obj, state);
    refs_to_clean.push_back(make_safe(obj));
     
    if (IsPyString(obj)) {
      state->inferred_dtype = DT_STRING;
    } else if (PySequence_Check(obj)) {
      auto length = PySequence_Length(obj);
      if (length > 0) {
        state->inferred_shape.AddDim(length);
        PyObject* elem = nullptr;
        TF_RETURN_IF_ERROR(SampleElementFromSequence(obj, &elem));
        obj = elem;
        refs_to_clean.push_back(make_safe(obj));
        continue;
      } else if (length == 0) {
        state->inferred_shape.AddDim(length);
        state->inferred_dtype = DT_INVALID;   
      } else {
         
        if (PyErr_Occurred()) {
           
           
          return errors::InvalidArgument(PyExceptionFetch());
        } else {
           
           
          return errors::InvalidArgument(
              "Attempted to convert an invalid sequence to a Tensor.");
        }
      }
    } else if (IsPyDouble(obj)) {
      state->inferred_dtype = DT_DOUBLE;
    } else if (IsNumpyHalf(obj)) {
      state->inferred_dtype = DT_HALF;
    } else if (IsPyFloat(obj)) {
      state->inferred_dtype = DT_FLOAT;
    } else if (PyBool_Check(obj) || PyIsInstance(obj, &PyBoolArrType_Type)) {
       
      state->inferred_dtype = DT_BOOL;
    } else if (IsPyInt(obj)) {
      state->inferred_dtype = DT_INT64;
    } else if (IsPyDimension(obj)) {
      state->inferred_dtype = DT_INT64;
    } else if (PyComplex_Check(obj) ||
               PyIsInstance(obj, &PyComplexFloatingArrType_Type)) {   
      state->inferred_dtype = DT_COMPLEX128;
    } else {
      return errors::InvalidArgument("Attempt to convert a value (",
                                     PyRepr(obj),
                                     ") with an unsupported type (",
                                     PyRepr(PyType(obj)), ") to a Tensor.");
    }
    return Status::OK();
  }
}