Skip to content

Commit df9d2f2

Browse files
committed
Use NPY_OBJECT for empty temporal arrays to avoid unitless datetime64
The NPY_TYPE<DateTime/TimeDelta> specializations would cause empty_array() to create unitless datetime64/timedelta64 arrays via PyArray_SimpleNew, which newer pandas rejects. Use NPY_OBJECT for the empty (0-length) case to match prior behavior. Signed-off-by: Arham Chopra <arham.chopra@cubistsystematic.com>
1 parent 65d2a59 commit df9d2f2

2 files changed

Lines changed: 6 additions & 4 deletions

File tree

cpp/csp/python/NumpyConversions.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ inline PyObject * as_nparray( const csp::TimeSeriesProvider * ts, const TickBuff
9696
{
9797
int32_t len = startIndex - endIndex + 1;
9898
if( len <= 0 || !ts -> valid() || ( !tickBuffer && endIndex != 0 ) )
99-
return empty_array( NPY_TYPE<DateTime>::value );
99+
return empty_array( NPY_OBJECT );
100100

101101
DateTime * values = getValues( tickBuffer, lastValue, startIndex, endIndex, &len, tailPadding );
102102
npy_intp dims[]{ ( npy_intp ) len };
@@ -107,6 +107,7 @@ inline PyObject * as_nparray( const csp::TimeSeriesProvider * ts, const TickBuff
107107
auto date_type = PyPtr<PyObject>::own( PyUnicode_FromString( "<M8[ns]" ) );
108108
PyArray_DescrConverter( date_type.get(), &datetime_descr );
109109
}
110+
110111
// PyArray_NewFromDescr steals a reference
111112
Py_INCREF( datetime_descr );
112113
auto * array = PyArray_NewFromDescr( &PyArray_Type, datetime_descr, 1, dims, nullptr, values, 0, nullptr );
@@ -119,7 +120,7 @@ inline PyObject * as_nparray( const csp::TimeSeriesProvider * ts, const TickBuff
119120
{
120121
int32_t len = startIndex - endIndex + 1;
121122
if( len <= 0 || !ts -> valid()|| ( !tickBuffer && endIndex != 0 ) )
122-
return empty_array( NPY_TYPE<TimeDelta>::value );
123+
return empty_array( NPY_OBJECT );
123124

124125
TimeDelta * values = getValues( tickBuffer, lastValue, startIndex, endIndex, &len, tailPadding );
125126
npy_intp dims[]{ ( npy_intp ) len };
@@ -130,6 +131,7 @@ inline PyObject * as_nparray( const csp::TimeSeriesProvider * ts, const TickBuff
130131
auto timedelta_type = PyPtr<PyObject>::own( PyUnicode_FromString( "<m8[ns]" ) );
131132
PyArray_DescrConverter( timedelta_type.get(), &timedelta_descr );
132133
}
134+
133135
Py_INCREF( timedelta_descr );
134136
auto * array = PyArray_NewFromDescr( &PyArray_Type, timedelta_descr, 1, dims, nullptr, values, 0, nullptr );
135137
PyArray_ENABLEFLAGS( ( PyArrayObject * ) array, NPY_ARRAY_OWNDATA);

cpp/csp/python/adapters/ArrowNumpyListWriter.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,8 @@ class NumpyNDArrayWriter final : public csp::adapters::arrow::FieldWriter
393393
// These write all elements of a numpy array into an arrow value builder
394394
// (list start/end is handled by the caller, e.g. ListColumnArrayBuilder).
395395

396-
template<typename T> struct ArrowArrayType { using type = T; };
397-
template<> struct ArrowArrayType<bool> { using type = uint8_t; };
396+
template<typename T> struct ArrowArrayType { using type = T; };
397+
template<> struct ArrowArrayType<bool> { using type = uint8_t; };
398398

399399
template<typename CspT, typename ArrowBuilderT>
400400
inline csp::adapters::arrow::ListItemsWriter makeNativeListItemsWriter(

0 commit comments

Comments
 (0)