MCPcopy Create free account
hub / github.com/apache/arrow / VisitSequenceGeneric

Function VisitSequenceGeneric

python/pyarrow/src/arrow/python/iterators.h:44–198  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

42// If keep_going is set to false, the iteration terminates
43template <class VisitorFunc>
44inline Status VisitSequenceGeneric(PyObject* obj, int64_t offset, VisitorFunc&& func) {
45 // VisitorFunc may set to false to terminate iteration
46 bool keep_going = true;
47
48 if (has_numpy() && PyArray_Check(obj)) {
49 PyArrayObject* arr_obj = reinterpret_cast<PyArrayObject*>(obj);
50 if (PyArray_NDIM(arr_obj) != 1) {
51 return Status::Invalid("Only 1D arrays accepted");
52 }
53
54 if (PyArray_DESCR(arr_obj)->type_num == NPY_OBJECT) {
55 // It's an array object, we can fetch object pointers directly
56 const Ndarray1DIndexer<PyObject*> objects(arr_obj);
57 for (int64_t i = offset; keep_going && i < objects.size(); ++i) {
58 RETURN_NOT_OK(func(objects[i], i, &keep_going));
59 }
60 return Status::OK();
61 }
62 // It's a non-object array, fall back on regular sequence access.
63 // (note PyArray_GETITEM() is slightly different: it returns standard
64 // Python types, not Numpy scalar types)
65 // This code path is inefficient: callers should implement dedicated
66 // logic for non-object arrays.
67 }
68
69 if (PySequence_Check(obj)) {
70#ifdef Py_GIL_DISABLED
71 if (PyTuple_Check(obj)) {
72#else
73 if (PyList_Check(obj) || PyTuple_Check(obj)) {
74#endif
75 // Use fast item access
76 const Py_ssize_t size = PySequence_Fast_GET_SIZE(obj);
77 for (Py_ssize_t i = offset; keep_going && i < size; ++i) {
78 PyObject* value = PySequence_Fast_GET_ITEM(obj, i);
79 RETURN_NOT_OK(func(value, static_cast<int64_t>(i), &keep_going));
80 }
81 } else {
82 // Regular sequence: avoid making a potentially large copy
83 const Py_ssize_t size = PySequence_Size(obj);
84 RETURN_IF_PYERROR();
85 for (Py_ssize_t i = offset; keep_going && i < size; ++i) {
86 OwnedRef value_ref(PySequence_ITEM(obj, i));
87 RETURN_IF_PYERROR();
88 RETURN_NOT_OK(func(value_ref.obj(), static_cast<int64_t>(i), &keep_going));
89 }
90 }
91 } else {
92 return Status::TypeError("Object is not a sequence");
93 }
94 return Status::OK();
95}
96
97// Visit sequence with no null mask
98template <class VisitorFunc>
99inline Status VisitSequence(PyObject* obj, int64_t offset, VisitorFunc&& func) {
100 return VisitSequenceGeneric(
101 obj, offset, [&func](PyObject* value, int64_t i /* unused */, bool* keep_going) {

Callers 2

VisitSequenceFunction · 0.85
VisitSequenceMaskedFunction · 0.85

Calls 6

has_numpyFunction · 0.85
InvalidFunction · 0.50
funcFunction · 0.50
OKFunction · 0.50
TypeErrorFunction · 0.50
sizeMethod · 0.45

Tested by

no test coverage detected