| 106 | /// Visit sequence with null mask |
| 107 | template <class VisitorFunc> |
| 108 | inline Status VisitSequenceMasked(PyObject* obj, PyObject* mo, int64_t offset, |
| 109 | VisitorFunc&& func) { |
| 110 | if (has_numpy() && PyArray_Check(mo)) { |
| 111 | PyArrayObject* mask = reinterpret_cast<PyArrayObject*>(mo); |
| 112 | if (PyArray_NDIM(mask) != 1) { |
| 113 | return Status::Invalid("Mask must be 1D array"); |
| 114 | } |
| 115 | if (PyArray_SIZE(mask) != static_cast<int64_t>(PySequence_Size(obj))) { |
| 116 | return Status::Invalid("Mask was a different length from sequence being converted"); |
| 117 | } |
| 118 | |
| 119 | const int dtype = fix_numpy_type_num(PyArray_DESCR(mask)->type_num); |
| 120 | if (dtype == NPY_BOOL) { |
| 121 | Ndarray1DIndexer<uint8_t> mask_values(mask); |
| 122 | |
| 123 | return VisitSequenceGeneric( |
| 124 | obj, offset, |
| 125 | [&func, &mask_values](PyObject* value, int64_t i, bool* keep_going) { |
| 126 | return func(value, mask_values[i], keep_going); |
| 127 | }); |
| 128 | } else { |
| 129 | return Status::TypeError("Mask must be boolean dtype"); |
| 130 | } |
| 131 | } else if (py::is_array(mo)) { |
| 132 | auto unwrap_mask_result = unwrap_array(mo); |
| 133 | ARROW_RETURN_NOT_OK(unwrap_mask_result); |
| 134 | std::shared_ptr<Array> mask_ = unwrap_mask_result.ValueOrDie(); |
| 135 | if (mask_->type_id() != Type::type::BOOL) { |
| 136 | return Status::TypeError("Mask must be an array of booleans"); |
| 137 | } |
| 138 | |
| 139 | if (mask_->length() != PySequence_Size(obj)) { |
| 140 | return Status::Invalid("Mask was a different length from sequence being converted"); |
| 141 | } |
| 142 | |
| 143 | if (mask_->null_count() != 0) { |
| 144 | return Status::TypeError("Mask must be an array of booleans"); |
| 145 | } |
| 146 | |
| 147 | BooleanArray* boolmask = checked_cast<BooleanArray*>(mask_.get()); |
| 148 | return VisitSequenceGeneric( |
| 149 | obj, offset, [&func, &boolmask](PyObject* value, int64_t i, bool* keep_going) { |
| 150 | return func(value, boolmask->Value(i), keep_going); |
| 151 | }); |
| 152 | } else if (PySequence_Check(mo)) { |
| 153 | if (PySequence_Size(mo) != PySequence_Size(obj)) { |
| 154 | return Status::Invalid("Mask was a different length from sequence being converted"); |
| 155 | } |
| 156 | RETURN_IF_PYERROR(); |
| 157 | |
| 158 | return VisitSequenceGeneric( |
| 159 | obj, offset, [&func, &mo](PyObject* value, int64_t i, bool* keep_going) { |
| 160 | OwnedRef value_ref(PySequence_ITEM(mo, i)); |
| 161 | if (!PyBool_Check(value_ref.obj())) |
| 162 | return Status::TypeError("Mask must be a sequence of booleans"); |
| 163 | return func(value, value_ref.obj() == Py_True, keep_going); |
| 164 | }); |
| 165 | } else { |
no test coverage detected