Sets *elem to a NEW reference to an element in seq on success. REQUIRES: PySequence_Check(seq) && PySequence_Length(seq) > 0.
| 109 | // Sets *elem to a NEW reference to an element in seq on success. |
| 110 | // REQUIRES: PySequence_Check(seq) && PySequence_Length(seq) > 0. |
| 111 | Status SampleElementFromSequence(PyObject* seq, PyObject** elem) { |
| 112 | *elem = PySequence_GetItem(seq, 0); |
| 113 | if (*elem != nullptr) return Status::OK(); |
| 114 | // seq may implement the sequence protocol (i.e., implement __getitem__) |
| 115 | // but may legitimately not have a 0-th element (__getitem__(self, 0) |
| 116 | // raises a KeyError). For example: |
| 117 | // seq = pandas.Series([0, 1, 2], index=[2, 4, 6]) |
| 118 | // |
| 119 | // We don't actually care for the element at key 0, any element will do |
| 120 | // for inferring the element types. All elements are expected to |
| 121 | // have the same type, and this will be validated when converting |
| 122 | // to an EagerTensor. |
| 123 | PyErr_Clear(); |
| 124 | Safe_PyObjectPtr iter(PyObject_GetIter(seq)); |
| 125 | if (PyErr_Occurred()) { |
| 126 | return errors::InvalidArgument("Cannot infer dtype of a ", |
| 127 | Py_TYPE(seq)->tp_name, |
| 128 | " object: ", PyExceptionFetch()); |
| 129 | } |
| 130 | *elem = PyIter_Next(iter.get()); |
| 131 | if (PyErr_Occurred()) { |
| 132 | return errors::InvalidArgument( |
| 133 | "Cannot infer dtype of a ", Py_TYPE(seq)->tp_name, |
| 134 | " object, as iter(<object>).next() failed: ", PyExceptionFetch()); |
| 135 | } |
| 136 | if (*elem == nullptr) { |
| 137 | return errors::InvalidArgument("Cannot infer dtype of a ", |
| 138 | Py_TYPE(seq)->tp_name, |
| 139 | " object since it is an empty sequence"); |
| 140 | } |
| 141 | return Status::OK(); |
| 142 | } |
| 143 | |
| 144 | Status InferShapeAndType(PyObject* obj, TensorShape* shape, DataType* dtype) { |
| 145 | std::vector<Safe_PyObjectPtr> refs_to_clean; |
no test coverage detected